-
Notifications
You must be signed in to change notification settings - Fork 12.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Refactor
powerpc64
call ABI handling
- Loading branch information
Showing
2 changed files
with
144 additions
and
55 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,132 @@ | ||
//@ revisions: elfv1-be elfv2-be elfv2-le | ||
//@ assembly-output: emit-asm | ||
//@ compile-flags: -O | ||
//@[elfv1-be] compile-flags: --target powerpc64-unknown-linux-gnu | ||
//@[elfv1-be] needs-llvm-components: powerpc | ||
//@[elfv2-be] compile-flags: --target powerpc64-unknown-linux-musl | ||
//@[elfv2-be] needs-llvm-components: powerpc | ||
//@[elfv2-le] compile-flags: --target powerpc64le-unknown-linux-gnu | ||
//@[elfv2-le] needs-llvm-components: powerpc | ||
//@[elfv1-be] filecheck-flags: --check-prefix be | ||
//@[elfv2-be] filecheck-flags: --check-prefix be | ||
|
||
#![feature(no_core, lang_items)] | ||
#![no_std] | ||
#![no_core] | ||
#![crate_type = "lib"] | ||
|
||
#[lang = "sized"] | ||
trait Sized {} | ||
|
||
#[lang = "copy"] | ||
trait Copy {} | ||
|
||
#[lang = "freeze"] | ||
trait Freeze {} | ||
|
||
#[lang = "unpin"] | ||
trait Unpin {} | ||
|
||
impl Copy for u8 {} | ||
impl Copy for u16 {} | ||
impl Copy for u32 {} | ||
impl Copy for FiveU32s {} | ||
impl Copy for FiveU16s {} | ||
impl Copy for ThreeU8s {} | ||
|
||
#[repr(C)] | ||
struct FiveU32s(u32, u32, u32, u32, u32); | ||
|
||
#[repr(C)] | ||
struct FiveU16s(u16, u16, u16, u16, u16); | ||
|
||
#[repr(C)] | ||
struct ThreeU8s(u8, u8, u8); | ||
|
||
// CHECK-LABEL: read_large | ||
// be: lwz [[REG1:.*]], 16(4) | ||
// be-NEXT: stw [[REG1]], 16(3) | ||
// be-NEXT: ld [[REG2:.*]], 8(4) | ||
// be-NEXT: ld [[REG3:.*]], 0(4) | ||
// be-NEXT: std [[REG2]], 8(3) | ||
// be-NEXT: std [[REG3]], 0(3) | ||
// elfv2-le: lxvd2x [[REG1:.*]], 0, 4 | ||
// elfv2-le-NEXT: lwz [[REG2:.*]], 16(4) | ||
// elfv2-le-NEXT: stw [[REG2]], 16(3) | ||
// elfv2-le-NEXT: stxvd2x [[REG1]], 0, 3 | ||
// CHECK-NEXT: blr | ||
#[no_mangle] | ||
extern "C" fn read_large(x: &FiveU32s) -> FiveU32s { | ||
*x | ||
} | ||
|
||
// CHECK-LABEL: read_medium | ||
// elfv1-be: lhz [[REG1:.*]], 8(4) | ||
// elfv1-be-NEXT: ld [[REG2:.*]], 0(4) | ||
// elfv1-be-NEXT: sth [[REG1]], 8(3) | ||
// elfv1-be-NEXT: std [[REG2]], 0(3) | ||
// elfv2-be: lhz [[REG1:.*]], 8(3) | ||
// elfv2-be-NEXT: ld 3, 0(3) | ||
// elfv2-be-NEXT: sldi 4, [[REG1]], 48 | ||
// elfv2-le: ld [[REG1:.*]], 0(3) | ||
// elfv2-le-NEXT: lhz 4, 8(3) | ||
// elfv2-le-NEXT: mr 3, [[REG1]] | ||
// CHECK-NEXT: blr | ||
#[no_mangle] | ||
extern "C" fn read_medium(x: &FiveU16s) -> FiveU16s { | ||
*x | ||
} | ||
|
||
// CHECK-LABEL: read_small | ||
// elfv1-be: lbz [[REG1:.*]], 2(4) | ||
// elfv1-be-NEXT: lhz [[REG2:.*]], 0(4) | ||
// elfv1-be-NEXT: stb [[REG1]], 2(3) | ||
// elfv1-be-NEXT: sth [[REG2]], 0(3) | ||
// elfv2-be: lhz [[REG1:.*]], 0(3) | ||
// elfv2-be-NEXT: lbz 3, 2(3) | ||
// elfv2-be-NEXT: rldimi 3, [[REG1]], 8, 0 | ||
// elfv2-le: lbz [[REG1:.*]], 2(3) | ||
// elfv2-le-NEXT: lhz 3, 0(3) | ||
// elfv2-le-NEXT: rldimi 3, [[REG1]], 16, 0 | ||
// CHECK-NEXT: blr | ||
#[no_mangle] | ||
extern "C" fn read_small(x: &ThreeU8s) -> ThreeU8s { | ||
*x | ||
} | ||
|
||
// CHECK-LABEL: write_large | ||
// CHECK: std 3, 0(6) | ||
// be-NEXT: rldicl [[REG1:.*]], 5, 32, 32 | ||
// CHECK-NEXT: std 4, 8(6) | ||
// be-NEXT: stw [[REG1]], 16(6) | ||
// elfv2-le-NEXT: stw 5, 16(6) | ||
// CHECK-NEXT: blr | ||
#[no_mangle] | ||
extern "C" fn write_large(x: FiveU32s, dest: &mut FiveU32s) { | ||
*dest = x; | ||
} | ||
|
||
// CHECK-LABEL: write_medium | ||
// CHECK: std 3, 0(5) | ||
// be-NEXT: rldicl [[REG1:.*]], 4, 16, 48 | ||
// be-NEXT: sth [[REG1]], 8(5) | ||
// elfv2-le-NEXT: sth 4, 8(5) | ||
// CHECK-NEXT: blr | ||
#[no_mangle] | ||
extern "C" fn write_medium(x: FiveU16s, dest: &mut FiveU16s) { | ||
*dest = x; | ||
} | ||
|
||
// CHECK-LABEL: write_small | ||
// be: stb 3, 2(4) | ||
// be-NEXT: srwi [[REG1:.*]], 3, 8 | ||
// be-NEXT: sth [[REG1]], 0(4) | ||
// The order these instructions are emitted in changed in LLVM 18. | ||
// elfv2-le-DAG: sth 3, 0(4) | ||
// elfv2-le-DAG: srwi [[REG1:.*]], 3, 16 | ||
// elfv2-le-NEXT: stb [[REG1]], 2(4) | ||
// CHECK-NEXT: blr | ||
#[no_mangle] | ||
extern "C" fn write_small(x: ThreeU8s, dest: &mut ThreeU8s) { | ||
*dest = x; | ||
} |