diff --git a/filetests/wasm/i32-arith.cton b/filetests/wasm/i32-arith.cton index b345847eb9..fe9cf19883 100644 --- a/filetests/wasm/i32-arith.cton +++ b/filetests/wasm/i32-arith.cton @@ -55,9 +55,29 @@ ebb0(v0: i32, v1: i32): return v2 } -; function %i32_div(i32, i32) -> i32 -; function %i32_rem_s(i32, i32) -> i32 -; function %i32_rem_u(i32, i32) -> i32 +function %i32_div_s(i32, i32) -> i32 { +ebb0(v0: i32, v1: i32): + v2 = sdiv v0, v1 + return v2 +} + +function %i32_div_u(i32, i32) -> i32 { +ebb0(v0: i32, v1: i32): + v2 = udiv v0, v1 + return v2 +} + +function %i32_rem_s(i32, i32) -> i32 { +ebb0(v0: i32, v1: i32): + v2 = srem v0, v1 + return v2 +} + +function %i32_rem_u(i32, i32) -> i32 { +ebb0(v0: i32, v1: i32): + v2 = urem v0, v1 + return v2 +} function %i32_and(i32, i32) -> i32 { ebb0(v0: i32, v1: i32): diff --git a/filetests/wasm/i64-arith.cton b/filetests/wasm/i64-arith.cton index a7cce18d3c..4e8cdc06df 100644 --- a/filetests/wasm/i64-arith.cton +++ b/filetests/wasm/i64-arith.cton @@ -52,9 +52,29 @@ ebb0(v0: i64, v1: i64): return v2 } -; function %i64_div(i64, i64) -> i64 -; function %i64_rem_s(i64, i64) -> i64 -; function %i64_rem_u(i64, i64) -> i64 +function %i32_div_s(i32, i32) -> i32 { +ebb0(v0: i32, v1: i32): + v2 = sdiv v0, v1 + return v2 +} + +function %i32_div_u(i32, i32) -> i32 { +ebb0(v0: i32, v1: i32): + v2 = udiv v0, v1 + return v2 +} + +function %i32_rem_s(i32, i32) -> i32 { +ebb0(v0: i32, v1: i32): + v2 = srem v0, v1 + return v2 +} + +function %i32_rem_u(i32, i32) -> i32 { +ebb0(v0: i32, v1: i32): + v2 = urem v0, v1 + return v2 +} function %i64_and(i64, i64) -> i64 { ebb0(v0: i64, v1: i64): diff --git a/lib/cretonne/meta/base/legalize.py b/lib/cretonne/meta/base/legalize.py index 1afefcda89..c250d53ce2 100644 --- a/lib/cretonne/meta/base/legalize.py +++ b/lib/cretonne/meta/base/legalize.py @@ -14,6 +14,8 @@ from .instructions import band, bor, bxor, isplit, iconcat from .instructions import bnot, band_not, bor_not, bxor_not from .instructions import icmp, icmp_imm from .instructions import iconst, bint +from .instructions import ishl, ishl_imm, sshr, sshr_imm, ushr, ushr_imm +from .instructions import rotl, rotl_imm, rotr, rotr_imm from cdsl.ast import Var from cdsl.xform import Rtl, XFormGroup @@ -153,6 +155,20 @@ expand.legalize( a << iadd(x, a1) )) +# Rotates and shifts. +for inst_imm, inst in [ + (rotl_imm, rotl), + (rotr_imm, rotr), + (ishl_imm, ishl), + (sshr_imm, sshr), + (ushr_imm, ushr)]: + expand.legalize( + a << inst_imm(x, y), + Rtl( + a1 << iconst.i32(y), + a << inst(x, a1) + )) + expand.legalize( a << icmp_imm(cc, x, y), Rtl( diff --git a/lib/cretonne/meta/isa/intel/encodings.py b/lib/cretonne/meta/isa/intel/encodings.py index 44f8c16677..448252f43a 100644 --- a/lib/cretonne/meta/isa/intel/encodings.py +++ b/lib/cretonne/meta/isa/intel/encodings.py @@ -9,6 +9,7 @@ from .defs import I32, I64 from . import recipes as r from . import settings as cfg from . import instructions as x86 +from .legalize import intel_expand from base.legalize import narrow, expand try: @@ -21,14 +22,14 @@ except ImportError: I32.legalize_type( default=narrow, - i32=expand, + i32=intel_expand, f32=expand, f64=expand) I64.legalize_type( default=narrow, - i32=expand, - i64=expand, + i32=intel_expand, + i64=intel_expand, f32=expand, f64=expand) diff --git a/lib/cretonne/meta/isa/intel/instructions.py b/lib/cretonne/meta/isa/intel/instructions.py index c9d87c43f3..7921b2f431 100644 --- a/lib/cretonne/meta/isa/intel/instructions.py +++ b/lib/cretonne/meta/isa/intel/instructions.py @@ -6,17 +6,19 @@ target ISA. """ from cdsl.operands import Operand +from cdsl.typevar import TypeVar from cdsl.instructions import Instruction, InstructionGroup -from base.instructions import iB GROUP = InstructionGroup("x86", "Intel-specific instruction set") -nlo = Operand('nlo', iB, doc='Low part of numerator') -nhi = Operand('nhi', iB, doc='High part of numerator') -d = Operand('d', iB, doc='Denominator') -q = Operand('q', iB, doc='Quotient') -r = Operand('r', iB, doc='Remainder') +iWord = TypeVar('iWord', 'A scalar integer machine word', ints=(32, 64)) + +nlo = Operand('nlo', iWord, doc='Low part of numerator') +nhi = Operand('nhi', iWord, doc='High part of numerator') +d = Operand('d', iWord, doc='Denominator') +q = Operand('q', iWord, doc='Quotient') +r = Operand('r', iWord, doc='Remainder') udivmodx = Instruction( 'x86_udivmodx', r""" diff --git a/lib/cretonne/meta/isa/intel/legalize.py b/lib/cretonne/meta/isa/intel/legalize.py new file mode 100644 index 0000000000..cc46846d81 --- /dev/null +++ b/lib/cretonne/meta/isa/intel/legalize.py @@ -0,0 +1,58 @@ +""" +Custom legalization patterns for Intel. +""" +from __future__ import absolute_import +from cdsl.ast import Var +from cdsl.xform import Rtl, XFormGroup +from base.immediates import imm64 +from base.types import i32, i64 +from base import legalize as shared +from base import instructions as insts +from . import instructions as x86 +from .defs import ISA + +intel_expand = XFormGroup( + 'intel_expand', + """ + Legalize instructions by expansion. + + Use Intel-specific instructions if needed. + """, + isa=ISA, chain=shared.expand) + +a = Var('a') +dead = Var('dead') +x = Var('x') +xhi = Var('xhi') +y = Var('y') + +# +# Division and remainder. +# +intel_expand.legalize( + a << insts.udiv(x, y), + Rtl( + xhi << insts.iconst(imm64(0)), + (a, dead) << x86.udivmodx(x, xhi, y) + )) + +intel_expand.legalize( + a << insts.urem(x, y), + Rtl( + xhi << insts.iconst(imm64(0)), + (dead, a) << x86.udivmodx(x, xhi, y) + )) + +for ty in [i32, i64]: + intel_expand.legalize( + a << insts.sdiv.bind(ty)(x, y), + Rtl( + xhi << insts.sshr_imm(x, imm64(ty.lane_bits() - 1)), + (a, dead) << x86.sdivmodx(x, xhi, y) + )) + intel_expand.legalize( + a << insts.srem.bind(ty)(x, y), + Rtl( + xhi << insts.sshr_imm(x, imm64(ty.lane_bits() - 1)), + (dead, a) << x86.sdivmodx(x, xhi, y) + )) diff --git a/lib/cretonne/src/isa/intel/enc_tables.rs b/lib/cretonne/src/isa/intel/enc_tables.rs index ad66cb1f7f..35ca9a9d76 100644 --- a/lib/cretonne/src/isa/intel/enc_tables.rs +++ b/lib/cretonne/src/isa/intel/enc_tables.rs @@ -1,10 +1,11 @@ //! Encoding tables for Intel ISAs. +use bitset::BitSet; use ir; -use isa; use isa::constraints::*; use isa::enc_tables::*; use isa::encoding::RecipeSizing; +use isa; use predicates; use super::registers::*;