Use the target-lexicon crate.

This switches from a custom list of architectures to use the
target-lexicon crate.

 - "set is_64bit=1; isa x86" is replaced with "target x86_64", and
   similar for other architectures, and the `is_64bit` flag is removed
   entirely.

 - The `is_compressed` flag is removed too; it's no longer being used to
   control REX prefixes on x86-64, ARM and Thumb are separate
   architectures in target-lexicon, and we can figure out how to
   select RISC-V compressed encodings when we're ready.
This commit is contained in:
Dan Gohman
2018-05-25 11:41:14 -07:00
parent 2f3008aa40
commit 4e67e08efd
131 changed files with 487 additions and 499 deletions

View File

@@ -31,6 +31,7 @@ serde_derive = "1.0.8"
term = "0.5.1" term = "0.5.1"
capstone = "0.3.1" capstone = "0.3.1"
wabt = { version = "0.3", optional = true } wabt = { version = "0.3", optional = true }
target-lexicon = "0.0.0"
[features] [features]
default = ["wasm"] default = ["wasm"]

View File

@@ -125,15 +125,15 @@ The ``set`` lines apply settings cumulatively::
test legalizer test legalizer
set opt_level=best set opt_level=best
set is_64bit=1 set is_pic=1
isa riscv isa riscv64
set is_64bit=0 set is_pic=0
isa riscv supports_m=false isa riscv32 supports_m=false
function %foo() {} function %foo() {}
This example will run the legalizer test twice. Both runs will have This example will run the legalizer test twice. Both runs will have
``opt_level=best``, but they will have different ``is_64bit`` settings. The 32-bit ``opt_level=best``, but they will have different ``is_pic`` settings. The 32-bit
run will also have the RISC-V specific flag ``supports_m`` disabled. run will also have the RISC-V specific flag ``supports_m`` disabled.
The filetests are run automatically as part of `cargo test`, and they can The filetests are run automatically as part of `cargo test`, and they can

View File

@@ -1,6 +1,6 @@
; Test the legalization of function signatures for RV32E. ; Test the legalization of function signatures for RV32E.
test legalizer test legalizer
isa riscv enable_e target riscv32 enable_e
; regex: V=v\d+ ; regex: V=v\d+

View File

@@ -1,6 +1,6 @@
; Test the legalization of function signatures. ; Test the legalization of function signatures.
test legalizer test legalizer
isa riscv target riscv32
; regex: V=v\d+ ; regex: V=v\d+

View File

@@ -1,6 +1,6 @@
; Binary emission of 32-bit code. ; Binary emission of 32-bit code.
test binemit test binemit
isa riscv target riscv32
function %RV32I(i32 link [%x1]) -> i32 link [%x1] { function %RV32I(i32 link [%x1]) -> i32 link [%x1] {
sig0 = () sig0 = ()

View File

@@ -1,5 +1,5 @@
test legalizer test legalizer
isa riscv supports_m=1 target riscv32 supports_m=1
function %int32(i32, i32) { function %int32(i32, i32) {
ebb0(v1: i32, v2: i32): ebb0(v1: i32, v2: i32):

View File

@@ -1,11 +1,9 @@
; Test the legalization of i32 instructions that don't have RISC-V versions. ; Test the legalization of i32 instructions that don't have RISC-V versions.
test legalizer test legalizer
set is_64bit=0 target riscv32 supports_m=1
isa riscv supports_m=1
set is_64bit=1 target riscv64 supports_m=1
isa riscv supports_m=1
; regex: V=v\d+ ; regex: V=v\d+

View File

@@ -1,6 +1,6 @@
; Test legalizer's handling of ABI boundaries. ; Test legalizer's handling of ABI boundaries.
test legalizer test legalizer
isa riscv target riscv32
; regex: V=v\d+ ; regex: V=v\d+
; regex: SS=ss\d+ ; regex: SS=ss\d+

View File

@@ -1,6 +1,6 @@
; Test the legalization of i64 arithmetic instructions. ; Test the legalization of i64 arithmetic instructions.
test legalizer test legalizer
isa riscv supports_m=1 target riscv32 supports_m=1
; regex: V=v\d+ ; regex: V=v\d+

View File

@@ -1,6 +1,6 @@
; Test the parser's support for encoding annotations. ; Test the parser's support for encoding annotations.
test legalizer test legalizer
isa riscv target riscv32
function %parse_encoding(i32 [%x5]) -> i32 [%x10] { function %parse_encoding(i32 [%x5]) -> i32 [%x10] {
; check: function %parse_encoding(i32 [%x5], i32 link [%x1]) -> i32 [%x10], i32 link [%x1] fast { ; check: function %parse_encoding(i32 [%x5], i32 link [%x1]) -> i32 [%x10], i32 link [%x1] fast {

View File

@@ -1,6 +1,6 @@
; Test tracking of register moves. ; Test tracking of register moves.
test binemit test binemit
isa riscv target riscv32
function %regmoves(i32 link [%x1]) -> i32 link [%x1] { function %regmoves(i32 link [%x1]) -> i32 link [%x1] {
ebb0(v9999: i32): ebb0(v9999: i32):

View File

@@ -1,6 +1,6 @@
; Test the legalization of EBB arguments that are split. ; Test the legalization of EBB arguments that are split.
test legalizer test legalizer
isa riscv target riscv32
; regex: V=v\d+ ; regex: V=v\d+

View File

@@ -1,5 +1,5 @@
test verifier test verifier
isa riscv target riscv32
function %RV32I(i32 link [%x1]) -> i32 link [%x1] { function %RV32I(i32 link [%x1]) -> i32 link [%x1] {
fn0 = %foo() fn0 = %foo()

View File

@@ -1,5 +1,5 @@
test regalloc test regalloc
isa x86 target i686
; %rdi can't be used in a movsbl instruction, so test that the register ; %rdi can't be used in a movsbl instruction, so test that the register
; allocator can move it to a register that can be. ; allocator can move it to a register that can be.

View File

@@ -1,6 +1,5 @@
test compile test compile
set is_64bit=1 target x86_64 haswell
isa x86 haswell
function %foo(i64, i64, i64, i32) -> b1 system_v { function %foo(i64, i64, i64, i32) -> b1 system_v {
ebb3(v0: i64, v1: i64, v2: i64, v3: i32): ebb3(v0: i64, v1: i64, v2: i64, v3: i32):

View File

@@ -1,6 +1,6 @@
; Test the legalization of function signatures. ; Test the legalization of function signatures.
test legalizer test legalizer
isa x86 target i686
; regex: V=v\d+ ; regex: V=v\d+

View File

@@ -1,7 +1,6 @@
; Test the legalization of function signatures. ; Test the legalization of function signatures.
test legalizer test legalizer
set is_64bit target x86_64
isa x86
; regex: V=v\d+ ; regex: V=v\d+

View File

@@ -2,7 +2,7 @@
test binemit test binemit
set opt_level=best set opt_level=best
set allones_funcaddrs set allones_funcaddrs
isa x86 haswell target i686 haswell
; The binary encodings can be verified with the command: ; The binary encodings can be verified with the command:
; ;

View File

@@ -1,9 +1,8 @@
; binary emission of 64-bit code. ; binary emission of 64-bit code.
test binemit test binemit
set is_64bit
set opt_level=best set opt_level=best
set allones_funcaddrs set allones_funcaddrs
isa x86 haswell target x86_64 haswell
; The binary encodings can be verified with the command: ; The binary encodings can be verified with the command:
; ;

View File

@@ -1,7 +1,5 @@
test compile test compile
set is_64bit target x86_64 baseline
isa x86 baseline
; clz/ctz on 64 bit operands ; clz/ctz on 64 bit operands

View File

@@ -1,7 +1,6 @@
test binemit test binemit
set is_64bit
set opt_level=best set opt_level=best
isa x86 baseline target x86_64 baseline
; The binary encodings can be verified with the command: ; The binary encodings can be verified with the command:
; ;

View File

@@ -1,6 +1,6 @@
; Binary emission of 32-bit floating point code. ; Binary emission of 32-bit floating point code.
test binemit test binemit
isa x86 haswell target i686 haswell
; The binary encodings can be verified with the command: ; The binary encodings can be verified with the command:
; ;

View File

@@ -1,7 +1,7 @@
; binary emission of x86-32 code. ; binary emission of x86-32 code.
test binemit test binemit
set opt_level=best set opt_level=best
isa x86 haswell target i686 haswell
; The binary encodings can be verified with the command: ; The binary encodings can be verified with the command:
; ;

View File

@@ -1,8 +1,7 @@
; Binary emission of 64-bit floating point code. ; Binary emission of 64-bit floating point code.
test binemit test binemit
set is_64bit
set opt_level=best set opt_level=best
isa x86 haswell target x86_64 haswell
; The binary encodings can be verified with the command: ; The binary encodings can be verified with the command:
; ;

View File

@@ -1,9 +1,8 @@
; binary emission of 64-bit code. ; binary emission of 64-bit code.
test binemit test binemit
set is_64bit
set opt_level=best set opt_level=best
set is_pic set is_pic
isa x86 haswell target x86_64 haswell
; The binary encodings can be verified with the command: ; The binary encodings can be verified with the command:
; ;

View File

@@ -1,8 +1,7 @@
; binary emission of x86-64 code. ; binary emission of x86-64 code.
test binemit test binemit
set is_64bit
set opt_level=best set opt_level=best
isa x86 haswell target x86_64 haswell
; The binary encodings can be verified with the command: ; The binary encodings can be verified with the command:
; ;

View File

@@ -1,8 +1,7 @@
; Test legalization of a non-colocated call in 64-bit non-PIC mode. ; Test legalization of a non-colocated call in 64-bit non-PIC mode.
test legalizer test legalizer
set is_64bit
set opt_level=best set opt_level=best
isa x86 haswell target x86_64 haswell
function %call() { function %call() {
fn0 = %foo() fn0 = %foo()

View File

@@ -1,8 +1,7 @@
; Test the custom legalizations. ; Test the custom legalizations.
test legalizer test legalizer
isa x86 target i686
set is_64bit target x86_64
isa x86
; regex: V=v\d+ ; regex: V=v\d+
; regex: EBB=ebb\d+ ; regex: EBB=ebb\d+

View File

@@ -1,9 +1,8 @@
; Test the division legalizations. ; Test the division legalizations.
test legalizer test legalizer
set is_64bit
; See also legalize-div.cton. ; See also legalize-div.cton.
set avoid_div_traps=1 set avoid_div_traps=1
isa x86 target x86_64
; regex: V=v\d+ ; regex: V=v\d+
; regex: EBB=ebb\d+ ; regex: EBB=ebb\d+

View File

@@ -1,9 +1,8 @@
; Test the division legalizations. ; Test the division legalizations.
test legalizer test legalizer
set is_64bit
; See also legalize-div-traps.cton. ; See also legalize-div-traps.cton.
set avoid_div_traps=0 set avoid_div_traps=0
isa x86 target x86_64
; regex: V=v\d+ ; regex: V=v\d+
; regex: EBB=ebb\d+ ; regex: EBB=ebb\d+

View File

@@ -1,10 +1,9 @@
test legalizer test legalizer
; Pre-SSE 4.1, we need to use runtime library calls for floating point rounding operations. ; Pre-SSE 4.1, we need to use runtime library calls for floating point rounding operations.
set is_64bit
set is_pic set is_pic
set call_conv=system_v set call_conv=system_v
isa x86 target x86_64
function %floor(f32) -> f32 { function %floor(f32) -> f32 {
ebb0(v0: f32): ebb0(v0: f32):

View File

@@ -1,7 +1,6 @@
; Test the legalization of memory objects. ; Test the legalization of memory objects.
test legalizer test legalizer
set is_64bit target x86_64
isa x86
; regex: V=v\d+ ; regex: V=v\d+
; regex: EBB=ebb\d+ ; regex: EBB=ebb\d+

View File

@@ -1,7 +1,5 @@
test compile test compile
set is_64bit target x86_64 baseline
isa x86 baseline
; umulhi/smulhi on 64 bit operands ; umulhi/smulhi on 64 bit operands

View File

@@ -1,7 +1,6 @@
; Check that floating-point constants equal to zero are optimized correctly. ; Check that floating-point constants equal to zero are optimized correctly.
test binemit test binemit
set is_64bit=0 target i686
isa x86
function %foo() -> f32 fast { function %foo() -> f32 fast {
ebb0: ebb0:

View File

@@ -1,7 +1,6 @@
; Check that floating-point constants equal to zero are optimized correctly. ; Check that floating-point constants equal to zero are optimized correctly.
test binemit test binemit
set is_64bit=1 target x86_64
isa x86
function %zero_const_32bit_no_rex() -> f32 fast { function %zero_const_32bit_no_rex() -> f32 fast {
ebb0: ebb0:

View File

@@ -1,8 +1,7 @@
test compile test compile
set is_64bit=1
set colocated_libcalls=1 set colocated_libcalls=1
set probestack_func_adjusts_sp=1 set probestack_func_adjusts_sp=1
isa x86 target x86_64
; Like %big in probestack.cton, but with the probestack function adjusting ; Like %big in probestack.cton, but with the probestack function adjusting
; the stack pointer itself. ; the stack pointer itself.

View File

@@ -1,8 +1,7 @@
test compile test compile
set is_64bit=1
set colocated_libcalls=1 set colocated_libcalls=1
set probestack_enabled=0 set probestack_enabled=0
isa x86 target x86_64
; Like %big in probestack.cton, but with probes disabled. ; Like %big in probestack.cton, but with probes disabled.

View File

@@ -1,6 +1,5 @@
test compile test compile
set is_64bit=1 target x86_64
isa x86
; Like %big in probestack.cton, but without a colocated libcall. ; Like %big in probestack.cton, but without a colocated libcall.

View File

@@ -1,8 +1,7 @@
test compile test compile
set is_64bit=1
set colocated_libcalls=1 set colocated_libcalls=1
set probestack_size_log2=13 set probestack_size_log2=13
isa x86 target x86_64
; Like %big in probestack.cton, but now the probestack size is bigger ; Like %big in probestack.cton, but now the probestack size is bigger
; and it no longer needs a probe. ; and it no longer needs a probe.

View File

@@ -1,7 +1,6 @@
test compile test compile
set is_64bit=1
set colocated_libcalls=1 set colocated_libcalls=1
isa x86 target x86_64
; A function with a big stack frame. This should have a stack probe. ; A function with a big stack frame. This should have a stack probe.

View File

@@ -1,8 +1,7 @@
test compile test compile
set is_64bit
set opt_level=best set opt_level=best
set is_pic set is_pic
isa x86 haswell target x86_64 haswell
; An empty function. ; An empty function.

View File

@@ -1,7 +1,6 @@
test binemit test binemit
set is_64bit=1
set opt_level=best set opt_level=best
isa x86 target x86_64
; Test that instruction shrinking eliminates REX prefixes when possible. ; Test that instruction shrinking eliminates REX prefixes when possible.

View File

@@ -1,8 +1,7 @@
test compile test compile
set is_64bit
set opt_level=best set opt_level=best
set is_pic set is_pic
isa x86 haswell target x86_64 haswell
; check if for one arg we use the right register ; check if for one arg we use the right register
function %one_arg(i64) windows_fastcall { function %one_arg(i64) windows_fastcall {

View File

@@ -1,6 +1,6 @@
test cat test cat
isa riscv target riscv32
; regex: WS=[ \t]* ; regex: WS=[ \t]*

View File

@@ -1,5 +1,5 @@
test postopt test postopt
isa x86 target i686
; Test that compare+branch sequences are folded effectively on x86. ; Test that compare+branch sequences are folded effectively on x86.

View File

@@ -1,6 +1,5 @@
test postopt test postopt
set is_64bit target x86_64
isa x86
function %dual_loads(i64, i64) -> i64 { function %dual_loads(i64, i64) -> i64 {
ebb0(v0: i64, v1: i64): ebb0(v0: i64, v1: i64):

View File

@@ -1,6 +1,5 @@
test preopt test preopt
isa x86 baseline target i686 baseline
; Cases where the denominator is created by an iconst ; Cases where the denominator is created by an iconst

View File

@@ -1,6 +1,5 @@
test preopt test preopt
isa x86 baseline target i686 baseline
; -------- U32 -------- ; -------- U32 --------

View File

@@ -1,6 +1,5 @@
test preopt test preopt
isa x86 baseline target i686 baseline
; -------- U32 -------- ; -------- U32 --------

View File

@@ -1,6 +1,5 @@
test preopt test preopt
isa x86 baseline target i686 baseline
; -------- U32 -------- ; -------- U32 --------

View File

@@ -1,6 +1,5 @@
test preopt test preopt
isa x86 baseline target i686 baseline
; -------- U32 -------- ; -------- U32 --------

View File

@@ -1,5 +1,5 @@
test preopt test preopt
isa x86 target i686
function %iadd_imm(i32) -> i32 { function %iadd_imm(i32) -> i32 {
ebb0(v0: i32): ebb0(v0: i32):

View File

@@ -1,6 +1,5 @@
test regalloc test regalloc
set is_64bit target x86_64 haswell
isa x86 haswell
function %value_aliases(i32, f32, i64 vmctx) baldrdash { function %value_aliases(i32, f32, i64 vmctx) baldrdash {
gv0 = vmctx gv0 = vmctx

View File

@@ -1,7 +1,7 @@
test regalloc test regalloc
; We can add more ISAs once they have defined encodings. ; We can add more ISAs once they have defined encodings.
isa riscv target riscv32
; regex: RX=%x\d+ ; regex: RX=%x\d+

View File

@@ -1,5 +1,5 @@
test regalloc test regalloc
isa riscv target riscv32
; Test the coalescer. ; Test the coalescer.
; regex: V=v\d+ ; regex: V=v\d+

View File

@@ -1,6 +1,5 @@
test regalloc test regalloc
set is_64bit target x86_64 haswell
isa x86 haswell
; Reported as https://github.com/cretonne/cretonne/issues/207 ; Reported as https://github.com/cretonne/cretonne/issues/207
; ;

View File

@@ -1,6 +1,5 @@
test regalloc test regalloc
set is_64bit target x86_64 haswell
isa x86 haswell
; Reported as https://github.com/cretonne/cretonne/issues/216 from the Binaryen fuzzer. ; Reported as https://github.com/cretonne/cretonne/issues/216 from the Binaryen fuzzer.
; ;

View File

@@ -1,6 +1,5 @@
test regalloc test regalloc
set is_64bit target x86_64 haswell
isa x86 haswell
function %pr227(i32 [%rdi], i32 [%rsi], i32 [%rdx], i32 [%rcx], i64 vmctx [%r8]) system_v { function %pr227(i32 [%rdi], i32 [%rsi], i32 [%rdx], i32 [%rcx], i64 vmctx [%r8]) system_v {
gv0 = vmctx gv0 = vmctx

View File

@@ -1,5 +1,5 @@
test regalloc test regalloc
isa x86 target i686
; regex: V=v\d+ ; regex: V=v\d+
; regex: REG=%r([abcd]x|[sd]i) ; regex: REG=%r([abcd]x|[sd]i)

View File

@@ -1,6 +1,5 @@
test regalloc test regalloc
set is_64bit target x86_64 haswell
isa x86 haswell
; This test case would create an EBB parameter that was a ghost value. ; This test case would create an EBB parameter that was a ghost value.
; The coalescer would insert a copy of the ghost value, leading to verifier errors. ; The coalescer would insert a copy of the ghost value, leading to verifier errors.

View File

@@ -1,5 +1,5 @@
test regalloc test regalloc
isa x86 target i686
; This test covers the troubles when values with global live ranges are defined ; This test covers the troubles when values with global live ranges are defined
; by instructions with constrained register classes. ; by instructions with constrained register classes.

View File

@@ -1,6 +1,5 @@
test regalloc test regalloc
set is_64bit=1 target x86_64 haswell
isa x86 haswell
function %foo() system_v { function %foo() system_v {
ebb4: ebb4:

View File

@@ -1,5 +1,5 @@
test regalloc test regalloc
isa riscv target riscv32
; Here, the coalescer initially builds vreg0 = [v1, v2, v3] ; Here, the coalescer initially builds vreg0 = [v1, v2, v3]
; ;

View File

@@ -1,6 +1,5 @@
test regalloc test regalloc
set is_64bit target x86_64 haswell
isa x86 haswell
function u0:9(i64 [%rdi], f32 [%xmm0], f64 [%xmm1], i32 [%rsi], i32 [%rdx], i64 vmctx [%r14]) -> i64 [%rax] baldrdash { function u0:9(i64 [%rdi], f32 [%xmm0], f64 [%xmm1], i32 [%rsi], i32 [%rdx], i64 vmctx [%r14]) -> i64 [%rax] baldrdash {
ebb0(v0: i64, v1: f32, v2: f64, v3: i32, v4: i32, v5: i64): ebb0(v0: i64, v1: f32, v2: f64, v3: i32, v4: i32, v5: i64):

View File

@@ -1,6 +1,5 @@
test regalloc test regalloc
set is_64bit target x86_64 haswell
isa x86 haswell
; Test combinations of constraints. ; Test combinations of constraints.
; ;

View File

@@ -1,6 +1,5 @@
test regalloc test regalloc
set is_64bit=1 target x86_64 haswell
isa x86 haswell
function %test(i64) -> i64 system_v { function %test(i64) -> i64 system_v {
ebb0(v0: i64): ebb0(v0: i64):

View File

@@ -1,6 +1,5 @@
test regalloc test regalloc
set is_64bit target x86_64 haswell
isa x86 haswell
; regex: V=v\d+ ; regex: V=v\d+

View File

@@ -1,5 +1,5 @@
test regalloc test regalloc
isa riscv enable_e target riscv32 enable_e
; regex: V=v\d+ ; regex: V=v\d+

View File

@@ -1,5 +1,5 @@
test regalloc test regalloc
isa x86 haswell target i686 haswell
function %pr165() system_v { function %pr165() system_v {
ebb0: ebb0:

View File

@@ -1,6 +1,5 @@
test regalloc test regalloc
set is_64bit target x86_64
isa x86
; Test case found by the Binaryen fuzzer. ; Test case found by the Binaryen fuzzer.
; ;

View File

@@ -12,7 +12,7 @@ test regalloc
; regex: V=v\d+ ; regex: V=v\d+
; regex: WS=\s+ ; regex: WS=\s+
isa riscv enable_e target riscv32 enable_e
; In straight-line code, the first value defined is spilled. ; In straight-line code, the first value defined is spilled.
; That is in order: ; That is in order:

View File

@@ -1,9 +1,8 @@
; Use "test compile" here otherwise the dead blocks won't be eliminated. ; Use "test compile" here otherwise the dead blocks won't be eliminated.
test compile test compile
set is_64bit
set probestack_enabled=0 set probestack_enabled=0
isa x86 haswell target x86_64 haswell
; This function contains unreachable blocks which trip up the register ; This function contains unreachable blocks which trip up the register
; allocator if they don't get cleared out. ; allocator if they don't get cleared out.

View File

@@ -1,6 +1,6 @@
test regalloc test regalloc
isa x86 target i686
; regex: V=v\d+ ; regex: V=v\d+

View File

@@ -1,5 +1,5 @@
test verifier test verifier
isa x86 target i686
; Simple, correct use of CPU flags. ; Simple, correct use of CPU flags.
function %simple(i32) -> i32 { function %simple(i32) -> i32 {

View File

@@ -1,11 +1,9 @@
; Test basic code generation for control flow WebAssembly instructions. ; Test basic code generation for control flow WebAssembly instructions.
test compile test compile
set is_64bit=0 target i686 haswell
isa x86 haswell
set is_64bit=1 target x86_64 haswell
isa x86 haswell
function %br_if(i32) -> i32 { function %br_if(i32) -> i32 {
ebb0(v0: i32): ebb0(v0: i32):

View File

@@ -1,8 +1,7 @@
; Test code generation for WebAssembly type conversion operators. ; Test code generation for WebAssembly type conversion operators.
test compile test compile
set is_64bit=1 target x86_64 haswell
isa x86 haswell
function %i32_wrap_i64(i64) -> i32 { function %i32_wrap_i64(i64) -> i32 {
ebb0(v0: i64): ebb0(v0: i64):

View File

@@ -1,17 +1,10 @@
; Test basic code generation for f32 arithmetic WebAssembly instructions. ; Test basic code generation for f32 arithmetic WebAssembly instructions.
test compile test compile
set is_64bit=0 target i686 haswell
isa x86 haswell target i686 baseline
target x86_64 haswell
set is_64bit=0 target x86_64 baseline
isa x86 baseline
set is_64bit=1
isa x86 haswell
set is_64bit=1
isa x86 baseline
; Constants. ; Constants.

View File

@@ -1,11 +1,9 @@
; Test code generation for WebAssembly f32 comparison operators. ; Test code generation for WebAssembly f32 comparison operators.
test compile test compile
set is_64bit=0 target i686 haswell
isa x86 haswell
set is_64bit=1 target x86_64 haswell
isa x86 haswell
function %f32_eq(f32, f32) -> i32 { function %f32_eq(f32, f32) -> i32 {
ebb0(v0: f32, v1: f32): ebb0(v0: f32, v1: f32):

View File

@@ -3,8 +3,7 @@ test compile
; We only test on 64-bit since the heap_addr instructions and vmctx parameters ; We only test on 64-bit since the heap_addr instructions and vmctx parameters
; explicitly mention the pointer width. ; explicitly mention the pointer width.
set is_64bit=1 target x86_64 haswell
isa x86 haswell
function %f32_load(i32, i64 vmctx) -> f32 { function %f32_load(i32, i64 vmctx) -> f32 {
gv0 = vmctx gv0 = vmctx

View File

@@ -1,11 +1,8 @@
; Test basic code generation for f64 arithmetic WebAssembly instructions. ; Test basic code generation for f64 arithmetic WebAssembly instructions.
test compile test compile
set is_64bit=1 target x86_64 haswell
isa x86 haswell target x86_64 baseline
set is_64bit=1
isa x86 baseline
; Constants. ; Constants.

View File

@@ -1,11 +1,9 @@
; Test code generation for WebAssembly f64 comparison operators. ; Test code generation for WebAssembly f64 comparison operators.
test compile test compile
set is_64bit=0 target i686 haswell
isa x86 haswell
set is_64bit=1 target x86_64 haswell
isa x86 haswell
function %f64_eq(f64, f64) -> i32 { function %f64_eq(f64, f64) -> i32 {
ebb0(v0: f64, v1: f64): ebb0(v0: f64, v1: f64):

View File

@@ -3,8 +3,7 @@ test compile
; We only test on 64-bit since the heap_addr instructions and vmctx parameters ; We only test on 64-bit since the heap_addr instructions and vmctx parameters
; explicitly mention the pointer width. ; explicitly mention the pointer width.
set is_64bit=1 target x86_64 haswell
isa x86 haswell
function %f64_load(i32, i64 vmctx) -> f64 { function %f64_load(i32, i64 vmctx) -> f64 {
gv0 = vmctx gv0 = vmctx

View File

@@ -1,17 +1,10 @@
; Test basic code generation for i32 arithmetic WebAssembly instructions. ; Test basic code generation for i32 arithmetic WebAssembly instructions.
test compile test compile
set is_64bit=0 target i686 haswell
isa x86 haswell target i686 baseline
target x86_64 haswell
set is_64bit=0 target x86_64 baseline
isa x86 baseline
set is_64bit=1
isa x86 haswell
set is_64bit=1
isa x86 baseline
; Constants. ; Constants.

View File

@@ -1,11 +1,9 @@
; Test code generation for WebAssembly i32 comparison operators. ; Test code generation for WebAssembly i32 comparison operators.
test compile test compile
set is_64bit=0 target i686 haswell
isa x86 haswell
set is_64bit=1 target x86_64 haswell
isa x86 haswell
function %i32_eqz(i32) -> i32 { function %i32_eqz(i32) -> i32 {
ebb0(v0: i32): ebb0(v0: i32):

View File

@@ -3,8 +3,7 @@ test compile
; We only test on 64-bit since the heap_addr instructions and vmctx parameters ; We only test on 64-bit since the heap_addr instructions and vmctx parameters
; explicitly mention the pointer width. ; explicitly mention the pointer width.
set is_64bit=1 target x86_64 haswell
isa x86 haswell
function %i32_load(i32, i64 vmctx) -> i32 { function %i32_load(i32, i64 vmctx) -> i32 {
gv0 = vmctx gv0 = vmctx

View File

@@ -1,11 +1,8 @@
; Test basic code generation for i64 arithmetic WebAssembly instructions. ; Test basic code generation for i64 arithmetic WebAssembly instructions.
test compile test compile
set is_64bit=1 target x86_64 haswell
isa x86 haswell target x86_64 baseline
set is_64bit=1
isa x86 baseline
; Constants. ; Constants.

View File

@@ -1,8 +1,7 @@
; Test code generation for WebAssembly i64 comparison operators. ; Test code generation for WebAssembly i64 comparison operators.
test compile test compile
set is_64bit=1 target x86_64 haswell
isa x86 haswell
function %i64_eqz(i64) -> i32 { function %i64_eqz(i64) -> i32 {
ebb0(v0: i64): ebb0(v0: i64):

View File

@@ -3,8 +3,7 @@ test compile
; We only test on 64-bit since the heap_addr instructions and vmctx parameters ; We only test on 64-bit since the heap_addr instructions and vmctx parameters
; explicitly mention the pointer width. ; explicitly mention the pointer width.
set is_64bit=1 target x86_64 haswell
isa x86 haswell
function %i64_load(i32, i64 vmctx) -> i64 { function %i64_load(i32, i64 vmctx) -> i64 {
gv0 = vmctx gv0 = vmctx

View File

@@ -1,11 +1,9 @@
; Test basic code generation for the select WebAssembly instruction. ; Test basic code generation for the select WebAssembly instruction.
test compile test compile
set is_64bit=0 target i686 haswell
isa x86 haswell
set is_64bit=1 target x86_64 haswell
isa x86 haswell
function %select_i32(i32, i32, i32) -> i32 { function %select_i32(i32, i32, i32) -> i32 {
ebb0(v0: i32, v1: i32, v2: i32): ebb0(v0: i32, v1: i32, v2: i32):

View File

@@ -20,6 +20,9 @@ git = "https://github.com/rust-fuzz/libfuzzer-sys.git"
[dependencies.cretonne-wasm] [dependencies.cretonne-wasm]
path = "../lib/wasm" path = "../lib/wasm"
[dependencies.target-lexicon]
version = "0.0.0"
# Prevent this from interfering with workspaces # Prevent this from interfering with workspaces
[workspace] [workspace]
members = ["."] members = ["."]

View File

@@ -3,13 +3,16 @@
extern crate libfuzzer_sys; extern crate libfuzzer_sys;
extern crate binaryen; extern crate binaryen;
extern crate cretonne_wasm; extern crate cretonne_wasm;
#[macro_use]
extern crate target_lexicon;
use cretonne_wasm::{translate_module, DummyEnvironment}; use cretonne_wasm::{translate_module, DummyEnvironment};
use std::str::FromStr;
fuzz_target!(|data: &[u8]| { fuzz_target!(|data: &[u8]| {
let binaryen_module = binaryen::tools::translate_to_fuzz_mvp(data); let binaryen_module = binaryen::tools::translate_to_fuzz_mvp(data);
let wasm = binaryen_module.write(); let wasm = binaryen_module.write();
let mut dummy_environ = DummyEnvironment::default(); let mut dummy_environ = DummyEnvironment::with_triple(triple!("x86_64"));
translate_module(&wasm, &mut dummy_environ).unwrap(); translate_module(&wasm, &mut dummy_environ).unwrap();
}); });

View File

@@ -9,7 +9,8 @@ use cretonne_codegen::{binemit, ir};
use cretonne_reader::parse_test; use cretonne_reader::parse_test;
use std::path::Path; use std::path::Path;
use std::path::PathBuf; use std::path::PathBuf;
use utils::{parse_sets_and_isa, read_to_string}; use target_lexicon::Architecture;
use utils::{parse_sets_and_triple, read_to_string};
struct PrintRelocs { struct PrintRelocs {
flag_print: bool, flag_print: bool,
@@ -64,7 +65,7 @@ pub fn run(
flag_set: &[String], flag_set: &[String],
flag_isa: &str, flag_isa: &str,
) -> Result<(), String> { ) -> Result<(), String> {
let parsed = parse_sets_and_isa(flag_set, flag_isa)?; let parsed = parse_sets_and_triple(flag_set, flag_isa)?;
for filename in files { for filename in files {
let path = Path::new(&filename); let path = Path::new(&filename);
@@ -136,23 +137,28 @@ fn handle_module(
} }
fn get_disassembler(isa: &TargetIsa) -> Result<Capstone, String> { fn get_disassembler(isa: &TargetIsa) -> Result<Capstone, String> {
let cs = match isa.name() { let cs = match isa.triple().architecture {
"riscv" => return Err(String::from("No disassembler for RiscV")), Architecture::Riscv32 | Architecture::Riscv64 => {
"x86" => { return Err(String::from("No disassembler for RiscV"))
if isa.flags().is_64bit() { }
Capstone::new() Architecture::I386 | Architecture::I586 | Architecture::I686 => Capstone::new()
.x86()
.mode(arch::x86::ArchMode::Mode64)
.build()
} else {
Capstone::new()
.x86() .x86()
.mode(arch::x86::ArchMode::Mode32) .mode(arch::x86::ArchMode::Mode32)
.build() .build(),
} Architecture::X86_64 => Capstone::new()
} .x86()
"arm32" => Capstone::new().arm().mode(arch::arm::ArchMode::Arm).build(), .mode(arch::x86::ArchMode::Mode64)
"arm64" => Capstone::new() .build(),
Architecture::Arm
| Architecture::Armv4t
| Architecture::Armv5te
| Architecture::Armv7
| Architecture::Armv7s => Capstone::new().arm().mode(arch::arm::ArchMode::Arm).build(),
Architecture::Thumbv6m | Architecture::Thumbv7em | Architecture::Thumbv7m => Capstone::new(
).arm()
.mode(arch::arm::ArchMode::Thumb)
.build(),
Architecture::Aarch64 => Capstone::new()
.arm64() .arm64()
.mode(arch::arm64::ArchMode::Arm) .mode(arch::arm64::ArchMode::Arm)
.build(), .build(),

View File

@@ -27,6 +27,7 @@ cfg_if! {
mod wasm; mod wasm;
} }
} }
extern crate target_lexicon;
use cretonne_codegen::{timing, VERSION}; use cretonne_codegen::{timing, VERSION};
use docopt::Docopt; use docopt::Docopt;
@@ -47,8 +48,8 @@ Usage:
cton-util cat <file>... cton-util cat <file>...
cton-util filecheck [-v] <file> cton-util filecheck [-v] <file>
cton-util print-cfg <file>... cton-util print-cfg <file>...
cton-util compile [-vpT] [--set <set>]... [--isa <isa>] <file>... cton-util compile [-vpT] [--set <set>]... [--target <triple>] <file>...
cton-util wasm [-ctvpTs] [--set <set>]... [--isa <isa>] <file>... cton-util wasm [-ctvpTs] [--set <set>]... [--target <triple>] <file>...
cton-util --help | --version cton-util --help | --version
Options: Options:
@@ -64,7 +65,8 @@ Options:
-p, --print print the resulting Cretonne IR -p, --print print the resulting Cretonne IR
-h, --help print this help message -h, --help print this help message
--set=<set> configure Cretonne settings --set=<set> configure Cretonne settings
--isa=<isa> specify the Cretonne ISA --target=<triple>
specify the Cretonne target
--version print the Cretonne version --version print the Cretonne version
"; ";
@@ -83,7 +85,7 @@ struct Args {
flag_print: bool, flag_print: bool,
flag_verbose: bool, flag_verbose: bool,
flag_set: Vec<String>, flag_set: Vec<String>,
flag_isa: String, flag_target: String,
flag_time_passes: bool, flag_time_passes: bool,
flag_print_size: bool, flag_print_size: bool,
} }
@@ -116,7 +118,7 @@ fn cton_util() -> CommandResult {
args.arg_file, args.arg_file,
args.flag_print, args.flag_print,
&args.flag_set, &args.flag_set,
&args.flag_isa, &args.flag_target,
) )
} else if args.cmd_wasm { } else if args.cmd_wasm {
#[cfg(feature = "wasm")] #[cfg(feature = "wasm")]
@@ -127,7 +129,7 @@ fn cton_util() -> CommandResult {
args.flag_check_translation, args.flag_check_translation,
args.flag_print, args.flag_print,
&args.flag_set, &args.flag_set,
&args.flag_isa, &args.flag_target,
args.flag_print_size, args.flag_print_size,
); );

View File

@@ -7,6 +7,8 @@ use cretonne_reader::{parse_options, Location};
use std::fs::File; use std::fs::File;
use std::io::{self, Read}; use std::io::{self, Read};
use std::path::Path; use std::path::Path;
use std::str::FromStr;
use target_lexicon::Triple;
/// Read an entire file into a string. /// Read an entire file into a string.
pub fn read_to_string<P: AsRef<Path>>(path: P) -> io::Result<String> { pub fn read_to_string<P: AsRef<Path>>(path: P) -> io::Result<String> {
@@ -40,8 +42,11 @@ impl OwnedFlagsOrIsa {
} }
} }
/// Parse "set" and "isa" commands. /// Parse "set" and "triple" commands.
pub fn parse_sets_and_isa(flag_set: &[String], flag_isa: &str) -> Result<OwnedFlagsOrIsa, String> { pub fn parse_sets_and_triple(
flag_set: &[String],
flag_triple: &str,
) -> Result<OwnedFlagsOrIsa, String> {
let mut flag_builder = settings::builder(); let mut flag_builder = settings::builder();
parse_options( parse_options(
flag_set.iter().map(|x| x.as_str()), flag_set.iter().map(|x| x.as_str()),
@@ -49,12 +54,21 @@ pub fn parse_sets_and_isa(flag_set: &[String], flag_isa: &str) -> Result<OwnedFl
&Location { line_number: 0 }, &Location { line_number: 0 },
).map_err(|err| err.to_string())?; ).map_err(|err| err.to_string())?;
let mut words = flag_isa.trim().split_whitespace(); let mut words = flag_triple.trim().split_whitespace();
// Look for `isa foo`. // Look for `target foo`.
if let Some(isa_name) = words.next() { if let Some(triple_name) = words.next() {
let mut isa_builder = isa::lookup(isa_name).map_err(|err| match err { let triple = match Triple::from_str(triple_name) {
isa::LookupError::Unknown => format!("unknown ISA '{}'", isa_name), Ok(triple) => triple,
isa::LookupError::Unsupported => format!("support for ISA '{}' not enabled", isa_name), Err(parse_error) => return Err(format!("{}", parse_error)),
};
let mut isa_builder = isa::lookup(triple).map_err(|err| match err {
isa::LookupError::SupportDisabled => {
format!("support for triple '{}' is disabled", triple_name)
}
isa::LookupError::Unsupported => format!(
"support for triple '{}' is not implemented yet",
triple_name
),
})?; })?;
// Apply the ISA-specific settings to `isa_builder`. // Apply the ISA-specific settings to `isa_builder`.
parse_options(words, &mut isa_builder, &Location { line_number: 0 }) parse_options(words, &mut isa_builder, &Location { line_number: 0 })

View File

@@ -12,7 +12,7 @@ use std::error::Error;
use std::path::Path; use std::path::Path;
use std::path::PathBuf; use std::path::PathBuf;
use term; use term;
use utils::{parse_sets_and_isa, read_to_end}; use utils::{parse_sets_and_triple, read_to_end};
use wabt::wat2wasm; use wabt::wat2wasm;
macro_rules! vprintln { macro_rules! vprintln {
@@ -38,10 +38,10 @@ pub fn run(
flag_check_translation: bool, flag_check_translation: bool,
flag_print: bool, flag_print: bool,
flag_set: &[String], flag_set: &[String],
flag_isa: &str, flag_triple: &str,
flag_print_size: bool, flag_print_size: bool,
) -> Result<(), String> { ) -> Result<(), String> {
let parsed = parse_sets_and_isa(flag_set, flag_isa)?; let parsed = parse_sets_and_triple(flag_set, flag_triple)?;
for filename in files { for filename in files {
let path = Path::new(&filename); let path = Path::new(&filename);
@@ -79,9 +79,7 @@ fn handle_module(
vprint!(flag_verbose, "Translating... "); vprint!(flag_verbose, "Translating... ");
terminal.reset().unwrap(); terminal.reset().unwrap();
let mut data = read_to_end(path.clone()).map_err(|err| { let mut data = read_to_end(path.clone()).map_err(|err| String::from(err.description()))?;
String::from(err.description())
})?;
if !data.starts_with(&[b'\0', b'a', b's', b'm']) { if !data.starts_with(&[b'\0', b'a', b's', b'm']) {
data = match wat2wasm(&data) { data = match wat2wasm(&data) {
@@ -90,10 +88,9 @@ fn handle_module(
}; };
} }
let mut dummy_environ = DummyEnvironment::with_flags(fisa.flags.clone()); let mut dummy_environ =
translate_module(&data, &mut dummy_environ).map_err( DummyEnvironment::with_triple_flags(fisa.isa.unwrap().triple().clone(), fisa.flags.clone());
|e| e.to_string(), translate_module(&data, &mut dummy_environ).map_err(|e| e.to_string())?;
)?;
terminal.fg(term::color::GREEN).unwrap(); terminal.fg(term::color::GREEN).unwrap();
vprintln!(flag_verbose, "ok"); vprintln!(flag_verbose, "ok");
@@ -142,24 +139,22 @@ fn handle_module(
let mut context = Context::new(); let mut context = Context::new();
context.func = func.clone(); context.func = func.clone();
if flag_check_translation { if flag_check_translation {
context.verify(fisa).map_err(|err| { context
pretty_verifier_error(&context.func, fisa.isa, &err) .verify(fisa)
})?; .map_err(|err| pretty_verifier_error(&context.func, fisa.isa, &err))?;
} else if let Some(isa) = fisa.isa { } else if let Some(isa) = fisa.isa {
let compiled_size = context.compile(isa).map_err(|err| { let compiled_size = context
pretty_error(&context.func, fisa.isa, err) .compile(isa)
})?; .map_err(|err| pretty_error(&context.func, fisa.isa, err))?;
if flag_print_size { if flag_print_size {
println!( println!(
"Function #{} code size: {} bytes", "Function #{} code size: {} bytes",
func_index, func_index, compiled_size
compiled_size
); );
total_module_code_size += compiled_size; total_module_code_size += compiled_size;
println!( println!(
"Function #{} bytecode size: {} bytes", "Function #{} bytecode size: {} bytes",
func_index, func_index, dummy_environ.func_bytecode_sizes[def_index]
dummy_environ.func_bytecode_sizes[def_index]
); );
} }
} else { } else {

View File

@@ -15,6 +15,7 @@ cretonne-entity = { path = "../entity", version = "0.8.0", default-features = fa
failure = { version = "0.1.1", default-features = false, features = ["derive"] } failure = { version = "0.1.1", default-features = false, features = ["derive"] }
failure_derive = { version = "0.1.1", default-features = false } failure_derive = { version = "0.1.1", default-features = false }
hashmap_core = { version = "0.1.4", optional = true } hashmap_core = { version = "0.1.4", optional = true }
target-lexicon = { version = "0.0.0", default-features = false }
# It is a goal of the cretonne-codegen crate to have minimal external dependencies. # It is a goal of the cretonne-codegen crate to have minimal external dependencies.
# Please don't add any unless they are essential to the task of creating binary # Please don't add any unless they are essential to the task of creating binary
# machine code. Integration tests that need external dependencies can be # machine code. Integration tests that need external dependencies can be

View File

@@ -27,8 +27,6 @@ enable_verifier = BoolSetting(
""", """,
default=True) default=True)
is_64bit = BoolSetting("Enable 64-bit code generation")
call_conv = EnumSetting( call_conv = EnumSetting(
""" """
Default calling convention: Default calling convention:
@@ -89,8 +87,6 @@ avoid_div_traps = BoolSetting(
this setting has no effect - explicit checks are always inserted. this setting has no effect - explicit checks are always inserted.
""") """)
is_compressed = BoolSetting("Enable compressed instructions")
enable_float = BoolSetting( enable_float = BoolSetting(
""" """
Enable the use of floating-point instructions Enable the use of floating-point instructions

View File

@@ -15,32 +15,43 @@ use isa::{EncInfo, RegClass, RegInfo, TargetIsa};
use regalloc; use regalloc;
use std::boxed::Box; use std::boxed::Box;
use std::fmt; use std::fmt;
use target_lexicon::{Architecture, Triple};
#[allow(dead_code)] #[allow(dead_code)]
struct Isa { struct Isa {
triple: Triple,
shared_flags: shared_settings::Flags, shared_flags: shared_settings::Flags,
isa_flags: settings::Flags, isa_flags: settings::Flags,
cpumode: &'static [shared_enc_tables::Level1Entry<u16>], cpumode: &'static [shared_enc_tables::Level1Entry<u16>],
} }
/// Get an ISA builder for creating ARM32 targets. /// Get an ISA builder for creating ARM32 targets.
pub fn isa_builder() -> IsaBuilder { pub fn isa_builder(triple: Triple) -> IsaBuilder {
IsaBuilder { IsaBuilder {
triple,
setup: settings::builder(), setup: settings::builder(),
constructor: isa_constructor, constructor: isa_constructor,
} }
} }
fn isa_constructor( fn isa_constructor(
triple: Triple,
shared_flags: shared_settings::Flags, shared_flags: shared_settings::Flags,
builder: shared_settings::Builder, builder: shared_settings::Builder,
) -> Box<TargetIsa> { ) -> Box<TargetIsa> {
let level1 = if shared_flags.is_compressed() { let level1 = match triple.architecture {
Architecture::Thumbv6m | Architecture::Thumbv7em | Architecture::Thumbv7m => {
&enc_tables::LEVEL1_T32[..] &enc_tables::LEVEL1_T32[..]
} else { }
&enc_tables::LEVEL1_A32[..] Architecture::Arm
| Architecture::Armv4t
| Architecture::Armv5te
| Architecture::Armv7
| Architecture::Armv7s => &enc_tables::LEVEL1_A32[..],
_ => panic!(),
}; };
Box::new(Isa { Box::new(Isa {
triple,
isa_flags: settings::Flags::new(&shared_flags, builder), isa_flags: settings::Flags::new(&shared_flags, builder),
shared_flags, shared_flags,
cpumode: level1, cpumode: level1,
@@ -52,6 +63,10 @@ impl TargetIsa for Isa {
"arm32" "arm32"
} }
fn triple(&self) -> &Triple {
&self.triple
}
fn flags(&self) -> &shared_settings::Flags { fn flags(&self) -> &shared_settings::Flags {
&self.shared_flags &self.shared_flags
} }

View File

@@ -15,26 +15,31 @@ use isa::{EncInfo, RegClass, RegInfo, TargetIsa};
use regalloc; use regalloc;
use std::boxed::Box; use std::boxed::Box;
use std::fmt; use std::fmt;
use target_lexicon::Triple;
#[allow(dead_code)] #[allow(dead_code)]
struct Isa { struct Isa {
triple: Triple,
shared_flags: shared_settings::Flags, shared_flags: shared_settings::Flags,
isa_flags: settings::Flags, isa_flags: settings::Flags,
} }
/// Get an ISA builder for creating ARM64 targets. /// Get an ISA builder for creating ARM64 targets.
pub fn isa_builder() -> IsaBuilder { pub fn isa_builder(triple: Triple) -> IsaBuilder {
IsaBuilder { IsaBuilder {
triple,
setup: settings::builder(), setup: settings::builder(),
constructor: isa_constructor, constructor: isa_constructor,
} }
} }
fn isa_constructor( fn isa_constructor(
triple: Triple,
shared_flags: shared_settings::Flags, shared_flags: shared_settings::Flags,
builder: shared_settings::Builder, builder: shared_settings::Builder,
) -> Box<TargetIsa> { ) -> Box<TargetIsa> {
Box::new(Isa { Box::new(Isa {
triple,
isa_flags: settings::Flags::new(&shared_flags, builder), isa_flags: settings::Flags::new(&shared_flags, builder),
shared_flags, shared_flags,
}) })
@@ -45,6 +50,10 @@ impl TargetIsa for Isa {
"arm64" "arm64"
} }
fn triple(&self) -> &Triple {
&self.triple
}
fn flags(&self) -> &shared_settings::Flags { fn flags(&self) -> &shared_settings::Flags {
&self.shared_flags &self.shared_flags
} }

View File

@@ -20,13 +20,18 @@
//! appropriate for the requested ISA: //! appropriate for the requested ISA:
//! //!
//! ``` //! ```
//! # extern crate cretonne_codegen;
//! # #[macro_use] extern crate target_lexicon;
//! # fn main() {
//! use cretonne_codegen::settings::{self, Configurable}; //! use cretonne_codegen::settings::{self, Configurable};
//! use cretonne_codegen::isa; //! use cretonne_codegen::isa;
//! use std::str::FromStr;
//! use target_lexicon::Triple;
//! //!
//! let shared_builder = settings::builder(); //! let shared_builder = settings::builder();
//! let shared_flags = settings::Flags::new(shared_builder); //! let shared_flags = settings::Flags::new(shared_builder);
//! //!
//! match isa::lookup("riscv") { //! match isa::lookup(triple!("riscv32")) {
//! Err(_) => { //! Err(_) => {
//! // The RISC-V target ISA is not available. //! // The RISC-V target ISA is not available.
//! } //! }
@@ -35,6 +40,7 @@
//! let isa = isa_builder.finish(shared_flags); //! let isa = isa_builder.finish(shared_flags);
//! } //! }
//! } //! }
//! # }
//! ``` //! ```
//! //!
//! The configured target ISA trait object is a `Box<TargetIsa>` which can be used for multiple //! The configured target ISA trait object is a `Box<TargetIsa>` which can be used for multiple
@@ -55,6 +61,7 @@ use settings;
use settings::CallConv; use settings::CallConv;
use std::boxed::Box; use std::boxed::Box;
use std::fmt; use std::fmt;
use target_lexicon::{Architecture, Triple};
use timing; use timing;
#[cfg(build_riscv)] #[cfg(build_riscv)]
@@ -80,51 +87,61 @@ mod stack;
macro_rules! isa_builder { macro_rules! isa_builder {
($module:ident, $name:ident) => {{ ($module:ident, $name:ident) => {{
#[cfg($name)] #[cfg($name)]
fn $name() -> Result<Builder, LookupError> { fn $name(triple: Triple) -> Result<Builder, LookupError> {
Ok($module::isa_builder()) Ok($module::isa_builder(triple))
}; };
#[cfg(not($name))] #[cfg(not($name))]
fn $name() -> Result<Builder, LookupError> { fn $name(_triple: Triple) -> Result<Builder, LookupError> {
Err(LookupError::Unsupported) Err(LookupError::Unsupported)
} }
$name() $name
}}; }};
} }
/// Look for a supported ISA with the given `name`. /// Look for a supported ISA with the given `name`.
/// Return a builder that can create a corresponding `TargetIsa`. /// Return a builder that can create a corresponding `TargetIsa`.
pub fn lookup(name: &str) -> Result<Builder, LookupError> { pub fn lookup(triple: Triple) -> Result<Builder, LookupError> {
match name { match triple.architecture {
"riscv" => isa_builder!(riscv, build_riscv), Architecture::Riscv32 | Architecture::Riscv64 => isa_builder!(riscv, build_riscv)(triple),
"x86" => isa_builder!(x86, build_x86), Architecture::I386 | Architecture::I586 | Architecture::I686 | Architecture::X86_64 => {
"arm32" => isa_builder!(arm32, build_arm32), isa_builder!(x86, build_x86)(triple)
"arm64" => isa_builder!(arm64, build_arm64), }
_ => Err(LookupError::Unknown), Architecture::Thumbv6m
| Architecture::Thumbv7em
| Architecture::Thumbv7m
| Architecture::Arm
| Architecture::Armv4t
| Architecture::Armv5te
| Architecture::Armv7
| Architecture::Armv7s => isa_builder!(arm32, build_arm32)(triple),
Architecture::Aarch64 => isa_builder!(arm64, build_arm64)(triple),
_ => Err(LookupError::Unsupported),
} }
} }
/// Describes reason for target lookup failure /// Describes reason for target lookup failure
#[derive(PartialEq, Eq, Copy, Clone, Debug)] #[derive(PartialEq, Eq, Copy, Clone, Debug)]
pub enum LookupError { pub enum LookupError {
/// Unknown Target /// Support for this target was disabled in the current build.
Unknown, SupportDisabled,
/// Target known but not built and thus not supported /// Support for this target has not yet been implemented.
Unsupported, Unsupported,
} }
/// Builder for a `TargetIsa`. /// Builder for a `TargetIsa`.
/// Modify the ISA-specific settings before creating the `TargetIsa` trait object with `finish`. /// Modify the ISA-specific settings before creating the `TargetIsa` trait object with `finish`.
pub struct Builder { pub struct Builder {
triple: Triple,
setup: settings::Builder, setup: settings::Builder,
constructor: fn(settings::Flags, settings::Builder) -> Box<TargetIsa>, constructor: fn(Triple, settings::Flags, settings::Builder) -> Box<TargetIsa>,
} }
impl Builder { impl Builder {
/// Combine the ISA-specific settings with the provided ISA-independent settings and allocate a /// Combine the ISA-specific settings with the provided ISA-independent settings and allocate a
/// fully configured `TargetIsa` trait object. /// fully configured `TargetIsa` trait object.
pub fn finish(self, shared_flags: settings::Flags) -> Box<TargetIsa> { pub fn finish(self, shared_flags: settings::Flags) -> Box<TargetIsa> {
(self.constructor)(shared_flags, self.setup) (self.constructor)(self.triple, shared_flags, self.setup)
} }
} }
@@ -151,9 +168,17 @@ pub trait TargetIsa: fmt::Display {
/// Get the name of this ISA. /// Get the name of this ISA.
fn name(&self) -> &'static str; fn name(&self) -> &'static str;
/// Get the target triple that was used to make this trait object.
fn triple(&self) -> &Triple;
/// Get the ISA-independent flags that were used to make this trait object. /// Get the ISA-independent flags that were used to make this trait object.
fn flags(&self) -> &settings::Flags; fn flags(&self) -> &settings::Flags;
/// Get the pointer type of this ISA.
fn pointer_type(&self) -> ir::Type {
ir::Type::int(u16::from(self.triple().pointer_width().unwrap().bits())).unwrap()
}
/// Does the CPU implement scalar comparisons using a CPU flags register? /// Does the CPU implement scalar comparisons using a CPU flags register?
fn uses_cpu_flags(&self) -> bool { fn uses_cpu_flags(&self) -> bool {
false false
@@ -252,7 +277,7 @@ pub trait TargetIsa: fmt::Display {
use ir::stackslot::{StackOffset, StackSize}; use ir::stackslot::{StackOffset, StackSize};
use stack_layout::layout_stack; use stack_layout::layout_stack;
let word_size = if self.flags().is_64bit() { 8 } else { 4 }; let word_size = StackSize::from(self.triple().pointer_width().unwrap().bytes());
// Account for the SpiderMonkey standard prologue pushes. // Account for the SpiderMonkey standard prologue pushes.
if func.signature.call_conv == CallConv::Baldrdash { if func.signature.call_conv == CallConv::Baldrdash {

Some files were not shown because too many files have changed in this diff Show More