diff --git a/cranelift/filetests/isa/intel/allones_funcaddrs32.cton b/cranelift/filetests/isa/intel/allones_funcaddrs32.cton new file mode 100644 index 0000000000..0c769d45ec --- /dev/null +++ b/cranelift/filetests/isa/intel/allones_funcaddrs32.cton @@ -0,0 +1,25 @@ +; binary emission of 32-bit code. +test binemit +set is_compressed +set allones_funcaddrs +isa intel haswell + +; The binary encodings can be verified with the command: +; +; sed -ne 's/^ *; asm: *//p' filetests/isa/intel/allones_funcaddrs32.cton | llvm-mc -show-encoding -triple=i386 +; + +; Tests from binary32.cton affected by allones_funcaddrs. +function %I32() { + fn0 = function %foo() + sig0 = () + +ebb0: + + ; asm: movl $-1, %ecx + [-,%rcx] v400 = func_addr.i32 fn0 ; bin: b9 Abs4(fn0) ffffffff + ; asm: movl $-1, %esi + [-,%rsi] v401 = func_addr.i32 fn0 ; bin: be Abs4(fn0) ffffffff + + return ; bin: c3 +} diff --git a/cranelift/filetests/isa/intel/allones_funcaddrs64.cton b/cranelift/filetests/isa/intel/allones_funcaddrs64.cton new file mode 100644 index 0000000000..5670c6ee2e --- /dev/null +++ b/cranelift/filetests/isa/intel/allones_funcaddrs64.cton @@ -0,0 +1,28 @@ +; binary emission of 64-bit code. +test binemit +set is_64bit +set is_compressed +set allones_funcaddrs +isa intel haswell + +; The binary encodings can be verified with the command: +; +; sed -ne 's/^ *; asm: *//p' filetests/isa/intel/allones_funcaddrs64.cton | llvm-mc -show-encoding -triple=x86_64 +; + +; Tests from binary64.cton affected by allones_funcaddrs. +function %I64() { + fn0 = function %foo() + sig0 = () + +ebb0: + + ; asm: movabsq $-1, %rcx + [-,%rcx] v400 = func_addr.i64 fn0 ; bin: 48 b9 Abs8(fn0) ffffffffffffffff + ; asm: movabsq $-1, %rsi + [-,%rsi] v401 = func_addr.i64 fn0 ; bin: 48 be Abs8(fn0) ffffffffffffffff + ; asm: movabsq $-1, %r10 + [-,%r10] v402 = func_addr.i64 fn0 ; bin: 49 ba Abs8(fn0) ffffffffffffffff + + return ; bin: c3 +} diff --git a/cranelift/filetests/isa/intel/binary32.cton b/cranelift/filetests/isa/intel/binary32.cton index 51e739483f..ab0f060488 100644 --- a/cranelift/filetests/isa/intel/binary32.cton +++ b/cranelift/filetests/isa/intel/binary32.cton @@ -343,9 +343,9 @@ ebb0: call fn0() ; bin: e8 PCRel4(fn0) 00000000 ; asm: movl $-1, %ecx - [-,%rcx] v400 = func_addr.i32 fn0 ; bin: b9 Abs4(fn0) ffffffff + [-,%rcx] v400 = func_addr.i32 fn0 ; bin: b9 Abs4(fn0) 00000000 ; asm: movl $-1, %esi - [-,%rsi] v401 = func_addr.i32 fn0 ; bin: be Abs4(fn0) ffffffff + [-,%rsi] v401 = func_addr.i32 fn0 ; bin: be Abs4(fn0) 00000000 ; asm: call *%ecx call_indirect sig0, v400() ; bin: ff d1 diff --git a/cranelift/filetests/isa/intel/binary64.cton b/cranelift/filetests/isa/intel/binary64.cton index 6d062c29b6..a770416e30 100644 --- a/cranelift/filetests/isa/intel/binary64.cton +++ b/cranelift/filetests/isa/intel/binary64.cton @@ -430,11 +430,11 @@ ebb0: call fn0() ; bin: e8 PCRel4(fn0) 00000000 ; asm: movabsq $-1, %rcx - [-,%rcx] v400 = func_addr.i64 fn0 ; bin: 48 b9 Abs8(fn0) ffffffffffffffff + [-,%rcx] v400 = func_addr.i64 fn0 ; bin: 48 b9 Abs8(fn0) 0000000000000000 ; asm: movabsq $-1, %rsi - [-,%rsi] v401 = func_addr.i64 fn0 ; bin: 48 be Abs8(fn0) ffffffffffffffff + [-,%rsi] v401 = func_addr.i64 fn0 ; bin: 48 be Abs8(fn0) 0000000000000000 ; asm: movabsq $-1, %r10 - [-,%r10] v402 = func_addr.i64 fn0 ; bin: 49 ba Abs8(fn0) ffffffffffffffff + [-,%r10] v402 = func_addr.i64 fn0 ; bin: 49 ba Abs8(fn0) 0000000000000000 ; asm: call *%rcx call_indirect sig0, v400() ; bin: ff d1 diff --git a/lib/cretonne/meta/base/settings.py b/lib/cretonne/meta/base/settings.py index 434bd28a52..11f0728e11 100644 --- a/lib/cretonne/meta/base/settings.py +++ b/lib/cretonne/meta/base/settings.py @@ -69,5 +69,13 @@ spiderwasm_prologue_words = NumSetting( pushed return address on Intel ISAs. """) +# +# BaldrMonkey requires that not-yet-relocated function addresses be encoded +# as all-ones bitpatterns. +# +allones_funcaddrs = BoolSetting( + """ + Emit not-yet-relocated function addresses as all-ones bit patterns. + """) group.close(globals()) diff --git a/lib/cretonne/meta/isa/intel/encodings.py b/lib/cretonne/meta/isa/intel/encodings.py index bdbb61fc05..9ae4601a57 100644 --- a/lib/cretonne/meta/isa/intel/encodings.py +++ b/lib/cretonne/meta/isa/intel/encodings.py @@ -2,7 +2,7 @@ Intel Encodings. """ from __future__ import absolute_import -from cdsl.predicates import IsUnsignedInt +from cdsl.predicates import IsUnsignedInt, Not from base import instructions as base from base.formats import UnaryImm from .defs import I32, I64 @@ -11,6 +11,7 @@ from . import settings as cfg from . import instructions as x86 from .legalize import intel_expand from base.legalize import narrow, expand +from base.settings import allones_funcaddrs from .settings import use_sse41 try: @@ -260,8 +261,15 @@ enc_both(base.regspill.f64, r.frsp32, 0x66, 0x0f, 0xd6) # Function addresses. # -I32.enc(base.func_addr.i32, *r.fnaddr4(0xb8)) -I64.enc(base.func_addr.i64, *r.fnaddr8.rex(0xb8, w=1)) +I32.enc(base.func_addr.i32, *r.fnaddr4(0xb8), + isap=Not(allones_funcaddrs)) +I64.enc(base.func_addr.i64, *r.fnaddr8.rex(0xb8, w=1), + isap=Not(allones_funcaddrs)) + +I32.enc(base.func_addr.i32, *r.allones_fnaddr4(0xb8), + isap=allones_funcaddrs) +I64.enc(base.func_addr.i64, *r.allones_fnaddr8.rex(0xb8, w=1), + isap=allones_funcaddrs) # # Call/return diff --git a/lib/cretonne/meta/isa/intel/recipes.py b/lib/cretonne/meta/isa/intel/recipes.py index 0aa3f0acd9..89f0e00ac0 100644 --- a/lib/cretonne/meta/isa/intel/recipes.py +++ b/lib/cretonne/meta/isa/intel/recipes.py @@ -478,8 +478,7 @@ fnaddr4 = TailRecipe( emit=''' PUT_OP(bits | (out_reg0 & 7), rex1(out_reg0), sink); sink.reloc_func(RelocKind::Abs4.into(), func_ref); - // Write the immediate as `!0` for the benefit of BaldrMonkey. - sink.put4(!0); + sink.put4(0); ''') # XX+rd iq with Abs8 function relocation. @@ -488,6 +487,25 @@ fnaddr8 = TailRecipe( emit=''' PUT_OP(bits | (out_reg0 & 7), rex1(out_reg0), sink); sink.reloc_func(RelocKind::Abs8.into(), func_ref); + sink.put8(0); + ''') + +# Similar to fnaddr4, but writes !0 (this is used by BaldrMonkey). +allones_fnaddr4 = TailRecipe( + 'allones_fnaddr4', FuncAddr, size=4, ins=(), outs=GPR, + emit=''' + PUT_OP(bits | (out_reg0 & 7), rex1(out_reg0), sink); + sink.reloc_func(RelocKind::Abs4.into(), func_ref); + // Write the immediate as `!0` for the benefit of BaldrMonkey. + sink.put4(!0); + ''') + +# Similar to fnaddr8, but writes !0 (this is used by BaldrMonkey). +allones_fnaddr8 = TailRecipe( + 'allones_fnaddr8', FuncAddr, size=8, ins=(), outs=GPR, + emit=''' + PUT_OP(bits | (out_reg0 & 7), rex1(out_reg0), sink); + sink.reloc_func(RelocKind::Abs8.into(), func_ref); // Write the immediate as `!0` for the benefit of BaldrMonkey. sink.put8(!0); ''') diff --git a/lib/cretonne/src/settings.rs b/lib/cretonne/src/settings.rs index 67ee68a214..d04dd4991f 100644 --- a/lib/cretonne/src/settings.rs +++ b/lib/cretonne/src/settings.rs @@ -352,7 +352,8 @@ mod tests { enable_float = true\n\ enable_simd = true\n\ enable_atomics = true\n\ - spiderwasm_prologue_words = 0\n" + spiderwasm_prologue_words = 0\n\ + allones_funcaddrs = false\n" ); assert_eq!(f.opt_level(), super::OptLevel::Default); assert_eq!(f.enable_simd(), true);