diff --git a/filetests/isa/intel/binary32-float.cton b/filetests/isa/intel/binary32-float.cton new file mode 100644 index 0000000000..c59bf10217 --- /dev/null +++ b/filetests/isa/intel/binary32-float.cton @@ -0,0 +1,34 @@ +; Binary emission of 32-bit floating point code. +test binemit +isa intel has_sse2 + +; The binary encodings can be verified with the command: +; +; sed -ne 's/^ *; asm: *//p' filetests/isa/intel/binary32-float.cton | llvm-mc -show-encoding -triple=i386 +; + +function %F32() { +ebb0: + [-,%rcx] v0 = iconst.i32 1 + [-,%rsi] v1 = iconst.i32 2 + + ; asm: cvtsi2ss %ecx, %xmm5 + [-,%xmm5] v10 = fcvt_from_sint.f32 v0 ; bin: f3 0f 2a e9 + ; asm: cvtsi2ss %esi, %xmm2 + [-,%xmm2] v11 = fcvt_from_sint.f32 v1 ; bin: f3 0f 2a d6 + + return +} + +function %F64() { +ebb0: + [-,%rcx] v0 = iconst.i32 1 + [-,%rsi] v1 = iconst.i32 2 + + ; asm: cvtsi2sd %ecx, %xmm5 + [-,%xmm5] v10 = fcvt_from_sint.f64 v0 ; bin: f2 0f 2a e9 + ; asm: cvtsi2sd %esi, %xmm2 + [-,%xmm2] v11 = fcvt_from_sint.f64 v1 ; bin: f2 0f 2a d6 + + return +} diff --git a/filetests/isa/intel/binary64-float.cton b/filetests/isa/intel/binary64-float.cton new file mode 100644 index 0000000000..cf523b0e5b --- /dev/null +++ b/filetests/isa/intel/binary64-float.cton @@ -0,0 +1,49 @@ +; Binary emission of 64-bit floating point code. +test binemit +set is_64bit +isa intel has_sse2 + +; The binary encodings can be verified with the command: +; +; sed -ne 's/^ *; asm: *//p' filetests/isa/intel/binary64-float.cton | llvm-mc -show-encoding -triple=x86_64 +; + +function %F32() { +ebb0: + [-,%r11] v0 = iconst.i32 1 + [-,%rsi] v1 = iconst.i32 2 + [-,%rax] v2 = iconst.i64 11 + [-,%r14] v3 = iconst.i64 12 + + ; asm: cvtsi2ssl %r11d, %xmm5 + [-,%xmm5] v10 = fcvt_from_sint.f32 v0 ; bin: f3 41 0f 2a eb + ; asm: cvtsi2ssl %esi, %xmm10 + [-,%xmm10] v11 = fcvt_from_sint.f32 v1 ; bin: f3 44 0f 2a d6 + + ; asm: cvtsi2ssq %rax, %xmm5 + [-,%xmm5] v12 = fcvt_from_sint.f32 v2 ; TODO: f3 48 0f 2a e8 + ; asm: cvtsi2ssq %r14, %xmm10 + [-,%xmm10] v13 = fcvt_from_sint.f32 v3 ; TODO: f3 4d 0f 2a d6 + + return +} + +function %F64() { +ebb0: + [-,%r11] v0 = iconst.i32 1 + [-,%rsi] v1 = iconst.i32 2 + [-,%rax] v2 = iconst.i64 11 + [-,%r14] v3 = iconst.i64 12 + + ; asm: cvtsi2sdl %r11d, %xmm5 + [-,%xmm5] v10 = fcvt_from_sint.f64 v0 ; bin: f2 41 0f 2a eb + ; asm: cvtsi2sdl %esi, %xmm10 + [-,%xmm10] v11 = fcvt_from_sint.f64 v1 ; bin: f2 44 0f 2a d6 + + ; asm: cvtsi2sdq %rax, %xmm5 + [-,%xmm5] v12 = fcvt_from_sint.f64 v2 ; TODO: f2 48 0f 2a e8 + ; asm: cvtsi2sdq %r14, %xmm10 + [-,%xmm10] v13 = fcvt_from_sint.f64 v3 ; TODO: f2 4d 0f 2a d6 + + return +} diff --git a/filetests/wasm/conversions.cton b/filetests/wasm/conversions.cton index a30cf97226..6f2354d624 100644 --- a/filetests/wasm/conversions.cton +++ b/filetests/wasm/conversions.cton @@ -21,3 +21,29 @@ ebb0(v0: i32): v1 = uextend.i64 v0 return v1 } + +function %f32_convert_s_i32(i32) -> f32 { +ebb0(v0: i32): + v1 = fcvt_from_sint.f32 v0 + return v1 +} + +function %f64_convert_s_i32(i32) -> f64 { +ebb0(v0: i32): + v1 = fcvt_from_sint.f64 v0 + return v1 +} + +function %f32_convert_s_i64(i64) -> f32 { +ebb0(v0: i64): + v1 = fcvt_from_sint.f32 v0 + return v1 +} + +function %f64_convert_s_i64(i64) -> f64 { +ebb0(v0: i64): + v1 = fcvt_from_sint.f64 v0 + return v1 +} + +; TODO: f*_convert_u_i* (Don't exist on Intel). diff --git a/lib/cretonne/meta/isa/intel/encodings.py b/lib/cretonne/meta/isa/intel/encodings.py index fcf114ef3e..264c07000e 100644 --- a/lib/cretonne/meta/isa/intel/encodings.py +++ b/lib/cretonne/meta/isa/intel/encodings.py @@ -208,3 +208,17 @@ I64.enc(base.sextend.i64.i32, *r.urm.rex(0x63, w=1)) # A 32-bit register copy clears the high 32 bits. I64.enc(base.uextend.i64.i32, *r.umr.rex(0x89)) I64.enc(base.uextend.i64.i32, *r.umr(0x89)) + +# +# Floating point +# + +# cvtsi2ss +I32.enc(base.fcvt_from_sint.f32.i32, *r.furm(0xf3, 0x0f, 0x2A)) +I64.enc(base.fcvt_from_sint.f32.i32, *r.furm.rex(0xf3, 0x0f, 0x2A)) +I64.enc(base.fcvt_from_sint.f32.i32, *r.furm(0xf3, 0x0f, 0x2A)) + +# cvtsi2sd +I32.enc(base.fcvt_from_sint.f64.i32, *r.furm(0xf2, 0x0f, 0x2A)) +I64.enc(base.fcvt_from_sint.f64.i32, *r.furm.rex(0xf2, 0x0f, 0x2A)) +I64.enc(base.fcvt_from_sint.f64.i32, *r.furm(0xf2, 0x0f, 0x2A)) diff --git a/lib/cretonne/meta/isa/intel/recipes.py b/lib/cretonne/meta/isa/intel/recipes.py index efffc47319..642e335f6a 100644 --- a/lib/cretonne/meta/isa/intel/recipes.py +++ b/lib/cretonne/meta/isa/intel/recipes.py @@ -8,7 +8,7 @@ from base.formats import Unary, UnaryImm, Binary, BinaryImm, MultiAry from base.formats import Nullary, Call, IndirectCall, Store, Load from base.formats import IntCompare from base.formats import RegMove, Ternary, Jump, Branch -from .registers import GPR, ABCD +from .registers import GPR, ABCD, FPR try: from typing import Tuple, Dict # noqa @@ -241,6 +241,14 @@ urm_abcd = TailRecipe( modrm_rr(in_reg0, out_reg0, sink); ''') +# XX /r, RM form, GPR -> FPR. +furm = TailRecipe( + 'furm', Unary, size=1, ins=GPR, outs=FPR, + emit=''' + PUT_OP(bits, rex2(in_reg0, out_reg0), sink); + modrm_rr(in_reg0, out_reg0, sink); + ''') + # XX /r, for regmove instructions. rmov = TailRecipe( 'ur', RegMove, size=1, ins=GPR, outs=(),