mirror of
https://github.com/RPCS3/llvm.git
synced 2024-12-19 09:57:42 +00:00
[WebAssembly] Add AsmString strings for most instructions.
Mangling type information into MachineInstr opcode names was a temporary measure, and it's starting to get hairy. At the same time, the MC instruction printer wants to use AsmString strings for printing. This patch takes the first step, starting the process of adding AsmStrings for instructions. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@252203 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
ae31b98bc3
commit
651ccf4012
@ -27,10 +27,12 @@
|
||||
|
||||
let isBranch = 1, isTerminator = 1, hasCtrlDep = 1 in {
|
||||
def BR_IF_ : I<(outs), (ins bb_op:$dst, I32:$a),
|
||||
[(brcond I32:$a, bb:$dst)]>;
|
||||
[(brcond I32:$a, bb:$dst)],
|
||||
"br_if $dst, $a">;
|
||||
let isBarrier = 1 in {
|
||||
def BR : I<(outs), (ins bb_op:$dst),
|
||||
[(br bb:$dst)]>;
|
||||
[(br bb:$dst)],
|
||||
"br $dst">;
|
||||
} // isBarrier = 1
|
||||
} // isBranch = 1, isTerminator = 1, hasCtrlDep = 1
|
||||
|
||||
@ -45,16 +47,17 @@ def SWITCH_I64 : I<(outs), (ins I64:$index, variable_ops),
|
||||
} // isTerminator = 1, hasCtrlDep = 1, isBarrier = 1
|
||||
|
||||
// Placemarkers to indicate the start of a block or loop scope.
|
||||
def BLOCK : I<(outs), (ins bb_op:$dst), []>;
|
||||
def LOOP : I<(outs), (ins bb_op:$dst), []>;
|
||||
def BLOCK : I<(outs), (ins bb_op:$dst), [], "block $dst">;
|
||||
def LOOP : I<(outs), (ins bb_op:$dst), [], "loop $dst">;
|
||||
|
||||
multiclass RETURN<WebAssemblyRegClass vt> {
|
||||
def RETURN_#vt : I<(outs), (ins vt:$val), [(WebAssemblyreturn vt:$val)]>;
|
||||
def RETURN_#vt : I<(outs), (ins vt:$val), [(WebAssemblyreturn vt:$val)],
|
||||
"return $val">;
|
||||
}
|
||||
let isReturn = 1, isTerminator = 1, hasCtrlDep = 1, isBarrier = 1 in {
|
||||
defm : RETURN<I32>;
|
||||
defm : RETURN<I64>;
|
||||
defm : RETURN<F32>;
|
||||
defm : RETURN<F64>;
|
||||
def RETURN_VOID : I<(outs), (ins), [(WebAssemblyreturn)]>;
|
||||
def RETURN_VOID : I<(outs), (ins), [(WebAssemblyreturn)], "return">;
|
||||
} // isReturn = 1, isTerminator = 1, hasCtrlDep = 1, isBarrier = 1
|
||||
|
@ -13,58 +13,83 @@
|
||||
///
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
def I64__WRAP_I32 : I<(outs I32:$dst), (ins I64:$src),
|
||||
[(set I32:$dst, (trunc I64:$src))]>;
|
||||
def i64__WRAP_i32 : I<(outs I32:$dst), (ins I64:$src),
|
||||
[(set I32:$dst, (trunc I64:$src))],
|
||||
"i32.wrap/i64 $dst, $src">;
|
||||
|
||||
def I32__EXTEND_S_I64 : I<(outs I64:$dst), (ins I32:$src),
|
||||
[(set I64:$dst, (sext I32:$src))]>;
|
||||
[(set I64:$dst, (sext I32:$src))],
|
||||
"i64.extend_s/i32 $dst, $src">;
|
||||
def I32__EXTEND_U_I64 : I<(outs I64:$dst), (ins I32:$src),
|
||||
[(set I64:$dst, (zext I32:$src))]>;
|
||||
[(set I64:$dst, (zext I32:$src))],
|
||||
"i64.extend_u/i32 $dst, $src">;
|
||||
|
||||
def F32__TRUNC_S_I32 : I<(outs I32:$dst), (ins F32:$src),
|
||||
[(set I32:$dst, (fp_to_sint F32:$src))]>;
|
||||
[(set I32:$dst, (fp_to_sint F32:$src))],
|
||||
"i32.trunc_s/f32 $dst, $src">;
|
||||
def F32__TRUNC_U_I32 : I<(outs I32:$dst), (ins F32:$src),
|
||||
[(set I32:$dst, (fp_to_uint F32:$src))]>;
|
||||
[(set I32:$dst, (fp_to_uint F32:$src))],
|
||||
"i32.trunc_u/f32 $dst, $src">;
|
||||
def F32__TRUNC_S_I64 : I<(outs I64:$dst), (ins F32:$src),
|
||||
[(set I64:$dst, (fp_to_sint F32:$src))]>;
|
||||
[(set I64:$dst, (fp_to_sint F32:$src))],
|
||||
"i64.trunc_s/f32 $dst, $src">;
|
||||
def F32__TRUNC_U_I64 : I<(outs I64:$dst), (ins F32:$src),
|
||||
[(set I64:$dst, (fp_to_uint F32:$src))]>;
|
||||
[(set I64:$dst, (fp_to_uint F32:$src))],
|
||||
"i64.trunc_u/f32 $dst, $src">;
|
||||
def F64__TRUNC_S_I32 : I<(outs I32:$dst), (ins F64:$src),
|
||||
[(set I32:$dst, (fp_to_sint F64:$src))]>;
|
||||
[(set I32:$dst, (fp_to_sint F64:$src))],
|
||||
"i32.trunc_s/f64 $dst, $src">;
|
||||
def F64__TRUNC_U_I32 : I<(outs I32:$dst), (ins F64:$src),
|
||||
[(set I32:$dst, (fp_to_uint F64:$src))]>;
|
||||
[(set I32:$dst, (fp_to_uint F64:$src))],
|
||||
"i32.trunc_u/f64 $dst, $src">;
|
||||
def F64__TRUNC_S_I64 : I<(outs I64:$dst), (ins F64:$src),
|
||||
[(set I64:$dst, (fp_to_sint F64:$src))]>;
|
||||
[(set I64:$dst, (fp_to_sint F64:$src))],
|
||||
"i64.trunc_s/f64 $dst, $src">;
|
||||
def F64__TRUNC_U_I64 : I<(outs I64:$dst), (ins F64:$src),
|
||||
[(set I64:$dst, (fp_to_uint F64:$src))]>;
|
||||
[(set I64:$dst, (fp_to_uint F64:$src))],
|
||||
"i64.trunc_u/f64 $dst, $src">;
|
||||
|
||||
def I32__CONVERT_S_F32 : I<(outs F32:$dst), (ins I32:$src),
|
||||
[(set F32:$dst, (sint_to_fp I32:$src))]>;
|
||||
[(set F32:$dst, (sint_to_fp I32:$src))],
|
||||
"f32.convert_s/i32 $dst, $src">;
|
||||
def I32__CONVERT_U_F32 : I<(outs F32:$dst), (ins I32:$src),
|
||||
[(set F32:$dst, (uint_to_fp I32:$src))]>;
|
||||
[(set F32:$dst, (uint_to_fp I32:$src))],
|
||||
"f32.convert_u/i32 $dst, $src">;
|
||||
def I32__CONVERT_S_F64 : I<(outs F64:$dst), (ins I32:$src),
|
||||
[(set F64:$dst, (sint_to_fp I32:$src))]>;
|
||||
[(set F64:$dst, (sint_to_fp I32:$src))],
|
||||
"f64.convert_s/i32 $dst, $src">;
|
||||
def I32__CONVERT_U_F64 : I<(outs F64:$dst), (ins I32:$src),
|
||||
[(set F64:$dst, (uint_to_fp I32:$src))]>;
|
||||
[(set F64:$dst, (uint_to_fp I32:$src))],
|
||||
"f64.convert_u/i32 $dst, $src">;
|
||||
def I64__CONVERT_S_F32 : I<(outs F32:$dst), (ins I64:$src),
|
||||
[(set F32:$dst, (sint_to_fp I64:$src))]>;
|
||||
[(set F32:$dst, (sint_to_fp I64:$src))],
|
||||
"f32.convert_s/i64 $dst, $src">;
|
||||
def I64__CONVERT_U_F32 : I<(outs F32:$dst), (ins I64:$src),
|
||||
[(set F32:$dst, (uint_to_fp I64:$src))]>;
|
||||
[(set F32:$dst, (uint_to_fp I64:$src))],
|
||||
"f32.convert_u/i64 $dst, $src">;
|
||||
def I64__CONVERT_S_F64 : I<(outs F64:$dst), (ins I64:$src),
|
||||
[(set F64:$dst, (sint_to_fp I64:$src))]>;
|
||||
[(set F64:$dst, (sint_to_fp I64:$src))],
|
||||
"f64.convert_s/i64 $dst, $src">;
|
||||
def I64__CONVERT_U_F64 : I<(outs F64:$dst), (ins I64:$src),
|
||||
[(set F64:$dst, (uint_to_fp I64:$src))]>;
|
||||
[(set F64:$dst, (uint_to_fp I64:$src))],
|
||||
"f64.convert_u/i64 $dst, $src">;
|
||||
|
||||
def F32__PROMOTE_F64 : I<(outs F64:$dst), (ins F32:$src),
|
||||
[(set F64:$dst, (fextend F32:$src))]>;
|
||||
[(set F64:$dst, (fextend F32:$src))],
|
||||
"f64.promote/f32 $dst, $src">;
|
||||
def F64__DEMOTE_F32 : I<(outs F32:$dst), (ins F64:$src),
|
||||
[(set F32:$dst, (fround F64:$src))]>;
|
||||
[(set F32:$dst, (fround F64:$src))],
|
||||
"f32.demote/f64 $dst, $src">;
|
||||
|
||||
def F32__REINTERPRET_I32 : I<(outs I32:$dst), (ins F32:$src),
|
||||
[(set I32:$dst, (bitconvert F32:$src))]>;
|
||||
[(set I32:$dst, (bitconvert F32:$src))],
|
||||
"i32.reinterpret/f32 $dst, $src">;
|
||||
def I32__REINTERPRET_F32 : I<(outs F32:$dst), (ins I32:$src),
|
||||
[(set F32:$dst, (bitconvert I32:$src))]>;
|
||||
[(set F32:$dst, (bitconvert I32:$src))],
|
||||
"f32.reinterpret/i32 $dst, $src">;
|
||||
def F64__REINTERPRET_I64 : I<(outs I64:$dst), (ins F64:$src),
|
||||
[(set I64:$dst, (bitconvert F64:$src))]>;
|
||||
[(set I64:$dst, (bitconvert F64:$src))],
|
||||
"i64.reinterpret/f64 $dst, $src">;
|
||||
def I64__REINTERPRET_F64 : I<(outs F64:$dst), (ins I64:$src),
|
||||
[(set F64:$dst, (bitconvert I64:$src))]>;
|
||||
[(set F64:$dst, (bitconvert I64:$src))],
|
||||
"f64.reinterpret/i64 $dst, $src">;
|
||||
|
@ -12,31 +12,31 @@
|
||||
///
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
defm ADD : BinaryFP<fadd>;
|
||||
defm SUB : BinaryFP<fsub>;
|
||||
defm MUL : BinaryFP<fmul>;
|
||||
defm DIV : BinaryFP<fdiv>;
|
||||
defm SQRT : UnaryFP<fsqrt>;
|
||||
defm ADD : BinaryFP<fadd, "add">;
|
||||
defm SUB : BinaryFP<fsub, "sub">;
|
||||
defm MUL : BinaryFP<fmul, "mul">;
|
||||
defm DIV : BinaryFP<fdiv, "div">;
|
||||
defm SQRT : UnaryFP<fsqrt, "sqrt">;
|
||||
|
||||
defm ABS : UnaryFP<fabs>;
|
||||
defm NEG : UnaryFP<fneg>;
|
||||
defm COPYSIGN : BinaryFP<fcopysign>;
|
||||
defm ABS : UnaryFP<fabs, "abs">;
|
||||
defm NEG : UnaryFP<fneg, "neg">;
|
||||
defm COPYSIGN : BinaryFP<fcopysign, "copysign">;
|
||||
|
||||
defm CEIL : UnaryFP<fceil>;
|
||||
defm FLOOR : UnaryFP<ffloor>;
|
||||
defm TRUNC : UnaryFP<ftrunc>;
|
||||
defm NEAREST : UnaryFP<fnearbyint>;
|
||||
defm CEIL : UnaryFP<fceil, "ceil">;
|
||||
defm FLOOR : UnaryFP<ffloor, "floor">;
|
||||
defm TRUNC : UnaryFP<ftrunc, "trunc">;
|
||||
defm NEAREST : UnaryFP<fnearbyint, "nearest">;
|
||||
|
||||
// WebAssembly doesn't expose inexact exceptions, so map frint to fnearbyint.
|
||||
def : Pat<(frint f32:$src), (NEAREST_F32 f32:$src)>;
|
||||
def : Pat<(frint f64:$src), (NEAREST_F64 f64:$src)>;
|
||||
|
||||
defm EQ : ComparisonFP<SETOEQ>;
|
||||
defm NE : ComparisonFP<SETUNE>;
|
||||
defm LT : ComparisonFP<SETOLT>;
|
||||
defm LE : ComparisonFP<SETOLE>;
|
||||
defm GT : ComparisonFP<SETOGT>;
|
||||
defm GE : ComparisonFP<SETOGE>;
|
||||
defm EQ : ComparisonFP<SETOEQ, "eq">;
|
||||
defm NE : ComparisonFP<SETUNE, "ne">;
|
||||
defm LT : ComparisonFP<SETOLT, "lt">;
|
||||
defm LE : ComparisonFP<SETOLE, "le">;
|
||||
defm GT : ComparisonFP<SETOGT, "gt">;
|
||||
defm GE : ComparisonFP<SETOGE, "ge">;
|
||||
|
||||
// Don't care floating-point comparisons, supported via other comparisons.
|
||||
def : Pat<(seteq f32:$lhs, f32:$rhs), (EQ_F32 f32:$lhs, f32:$rhs)>;
|
||||
@ -60,6 +60,8 @@ def : Pat<(setge f64:$lhs, f64:$rhs), (GE_F64 f64:$lhs, f64:$rhs)>;
|
||||
*/
|
||||
|
||||
def SELECT_F32 : I<(outs F32:$dst), (ins I32:$cond, F32:$lhs, F32:$rhs),
|
||||
[(set F32:$dst, (select I32:$cond, F32:$lhs, F32:$rhs))]>;
|
||||
[(set F32:$dst, (select I32:$cond, F32:$lhs, F32:$rhs))],
|
||||
"f32.select $dst, $cond, $lhs, $rhs">;
|
||||
def SELECT_F64 : I<(outs F64:$dst), (ins I32:$cond, F64:$lhs, F64:$rhs),
|
||||
[(set F64:$dst, (select I32:$cond, F64:$lhs, F64:$rhs))]>;
|
||||
[(set F64:$dst, (select I32:$cond, F64:$lhs, F64:$rhs))],
|
||||
"f64.select $dst, $cond, $lhs, $rhs">;
|
||||
|
@ -13,55 +13,67 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// WebAssembly Instruction Format.
|
||||
class WebAssemblyInst<string cstr> : Instruction {
|
||||
class WebAssemblyInst<string asmstr> : Instruction {
|
||||
field bits<0> Inst; // Instruction encoding.
|
||||
let Namespace = "WebAssembly";
|
||||
let Pattern = [];
|
||||
let Constraints = cstr;
|
||||
let AsmString = asmstr;
|
||||
}
|
||||
|
||||
// Normal instructions.
|
||||
class I<dag oops, dag iops, list<dag> pattern, string cstr = "">
|
||||
: WebAssemblyInst<cstr> {
|
||||
class I<dag oops, dag iops, list<dag> pattern, string asmstr = "">
|
||||
: WebAssemblyInst<asmstr> {
|
||||
dag OutOperandList = oops;
|
||||
dag InOperandList = iops;
|
||||
let Pattern = pattern;
|
||||
}
|
||||
|
||||
// Unary and binary instructions, for the local types that WebAssembly supports.
|
||||
multiclass UnaryInt<SDNode node> {
|
||||
multiclass UnaryInt<SDNode node, string name> {
|
||||
def _I32 : I<(outs I32:$dst), (ins I32:$src),
|
||||
[(set I32:$dst, (node I32:$src))]>;
|
||||
[(set I32:$dst, (node I32:$src))],
|
||||
!strconcat("i32.", !strconcat(name, " $dst, $src"))>;
|
||||
def _I64 : I<(outs I64:$dst), (ins I64:$src),
|
||||
[(set I64:$dst, (node I64:$src))]>;
|
||||
[(set I64:$dst, (node I64:$src))],
|
||||
!strconcat("i64.", !strconcat(name, " $dst, $src"))>;
|
||||
}
|
||||
multiclass BinaryInt<SDNode node> {
|
||||
multiclass BinaryInt<SDNode node, string name> {
|
||||
def _I32 : I<(outs I32:$dst), (ins I32:$lhs, I32:$rhs),
|
||||
[(set I32:$dst, (node I32:$lhs, I32:$rhs))]>;
|
||||
[(set I32:$dst, (node I32:$lhs, I32:$rhs))],
|
||||
!strconcat("i32.", !strconcat(name, " $dst, $lhs, $rhs"))>;
|
||||
def _I64 : I<(outs I64:$dst), (ins I64:$lhs, I64:$rhs),
|
||||
[(set I64:$dst, (node I64:$lhs, I64:$rhs))]>;
|
||||
[(set I64:$dst, (node I64:$lhs, I64:$rhs))],
|
||||
!strconcat("i64.", !strconcat(name, " $dst, $lhs, $rhs"))>;
|
||||
}
|
||||
multiclass UnaryFP<SDNode node> {
|
||||
multiclass UnaryFP<SDNode node, string name> {
|
||||
def _F32 : I<(outs F32:$dst), (ins F32:$src),
|
||||
[(set F32:$dst, (node F32:$src))]>;
|
||||
[(set F32:$dst, (node F32:$src))],
|
||||
!strconcat("f32.", !strconcat(name, " $dst, $src"))>;
|
||||
def _F64 : I<(outs F64:$dst), (ins F64:$src),
|
||||
[(set F64:$dst, (node F64:$src))]>;
|
||||
[(set F64:$dst, (node F64:$src))],
|
||||
!strconcat("f64.", !strconcat(name, " $dst, $src"))>;
|
||||
}
|
||||
multiclass BinaryFP<SDNode node> {
|
||||
multiclass BinaryFP<SDNode node, string name> {
|
||||
def _F32 : I<(outs F32:$dst), (ins F32:$lhs, F32:$rhs),
|
||||
[(set F32:$dst, (node F32:$lhs, F32:$rhs))]>;
|
||||
[(set F32:$dst, (node F32:$lhs, F32:$rhs))],
|
||||
!strconcat("f32.", !strconcat(name, " $dst, $lhs, $rhs"))>;
|
||||
def _F64 : I<(outs F64:$dst), (ins F64:$lhs, F64:$rhs),
|
||||
[(set F64:$dst, (node F64:$lhs, F64:$rhs))]>;
|
||||
[(set F64:$dst, (node F64:$lhs, F64:$rhs))],
|
||||
!strconcat("f64.", !strconcat(name, " $dst, $lhs, $rhs"))>;
|
||||
}
|
||||
multiclass ComparisonInt<CondCode cond> {
|
||||
multiclass ComparisonInt<CondCode cond, string name> {
|
||||
def _I32 : I<(outs I32:$dst), (ins I32:$lhs, I32:$rhs),
|
||||
[(set I32:$dst, (setcc I32:$lhs, I32:$rhs, cond))]>;
|
||||
[(set I32:$dst, (setcc I32:$lhs, I32:$rhs, cond))],
|
||||
!strconcat("i32.", !strconcat(name, " $dst, $lhs, $rhs"))>;
|
||||
def _I64 : I<(outs I32:$dst), (ins I64:$lhs, I64:$rhs),
|
||||
[(set I32:$dst, (setcc I64:$lhs, I64:$rhs, cond))]>;
|
||||
[(set I32:$dst, (setcc I64:$lhs, I64:$rhs, cond))],
|
||||
!strconcat("i64.", !strconcat(name, " $dst, $lhs, $rhs"))>;
|
||||
}
|
||||
multiclass ComparisonFP<CondCode cond> {
|
||||
multiclass ComparisonFP<CondCode cond, string name> {
|
||||
def _F32 : I<(outs I32:$dst), (ins F32:$lhs, F32:$rhs),
|
||||
[(set I32:$dst, (setcc F32:$lhs, F32:$rhs, cond))]>;
|
||||
[(set I32:$dst, (setcc F32:$lhs, F32:$rhs, cond))],
|
||||
!strconcat("f32.", !strconcat(name, " $dst, $lhs, $rhs"))>;
|
||||
def _F64 : I<(outs I32:$dst), (ins F64:$lhs, F64:$rhs),
|
||||
[(set I32:$dst, (setcc F64:$lhs, F64:$rhs, cond))]>;
|
||||
[(set I32:$dst, (setcc F64:$lhs, F64:$rhs, cond))],
|
||||
!strconcat("f64.", !strconcat(name, " $dst, $lhs, $rhs"))>;
|
||||
}
|
||||
|
@ -94,19 +94,25 @@ defm : ARGUMENT<F64>;
|
||||
|
||||
|
||||
def Immediate_I32 : I<(outs I32:$res), (ins i32imm:$imm),
|
||||
[(set I32:$res, imm:$imm)]>;
|
||||
[(set I32:$res, imm:$imm)],
|
||||
"i32.const $res, $imm">;
|
||||
def Immediate_I64 : I<(outs I64:$res), (ins i64imm:$imm),
|
||||
[(set I64:$res, imm:$imm)]>;
|
||||
[(set I64:$res, imm:$imm)],
|
||||
"i64.const $res, $imm">;
|
||||
def Immediate_F32 : I<(outs F32:$res), (ins f32imm:$imm),
|
||||
[(set F32:$res, fpimm:$imm)]>;
|
||||
[(set F32:$res, fpimm:$imm)],
|
||||
"f32.const $res, $imm">;
|
||||
def Immediate_F64 : I<(outs F64:$res), (ins f64imm:$imm),
|
||||
[(set F64:$res, fpimm:$imm)]>;
|
||||
[(set F64:$res, fpimm:$imm)],
|
||||
"f64.const $res, $imm">;
|
||||
|
||||
// Special types of immediates. FIXME: Hard-coded as 32-bit for now.
|
||||
def GLOBAL : I<(outs I32:$dst), (ins global:$addr),
|
||||
[(set I32:$dst, (WebAssemblywrapper tglobaladdr:$addr))]>;
|
||||
[(set I32:$dst, (WebAssemblywrapper tglobaladdr:$addr))],
|
||||
"global $dst, $addr">;
|
||||
def JUMP_TABLE : I<(outs I32:$dst), (ins tjumptable_op:$addr),
|
||||
[(set I32:$dst, (WebAssemblywrapper tjumptable:$addr))]>;
|
||||
[(set I32:$dst, (WebAssemblywrapper tjumptable:$addr))],
|
||||
"jump_table $dst, $addr">;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Additional sets of instructions.
|
||||
|
@ -12,34 +12,34 @@
|
||||
///
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
defm ADD : BinaryInt<add>;
|
||||
defm SUB : BinaryInt<sub>;
|
||||
defm MUL : BinaryInt<mul>;
|
||||
defm DIV_S : BinaryInt<sdiv>;
|
||||
defm DIV_U : BinaryInt<udiv>;
|
||||
defm REM_S : BinaryInt<srem>;
|
||||
defm REM_U : BinaryInt<urem>;
|
||||
defm AND : BinaryInt<and>;
|
||||
defm OR : BinaryInt<or>;
|
||||
defm XOR : BinaryInt<xor>;
|
||||
defm SHL : BinaryInt<shl>;
|
||||
defm SHR_U : BinaryInt<srl>;
|
||||
defm SHR_S : BinaryInt<sra>;
|
||||
defm ADD : BinaryInt<add, "add">;
|
||||
defm SUB : BinaryInt<sub, "sub">;
|
||||
defm MUL : BinaryInt<mul, "mul">;
|
||||
defm DIV_S : BinaryInt<sdiv, "div_s">;
|
||||
defm DIV_U : BinaryInt<udiv, "div_u">;
|
||||
defm REM_S : BinaryInt<srem, "rem_s">;
|
||||
defm REM_U : BinaryInt<urem, "rem_u">;
|
||||
defm AND : BinaryInt<and, "and">;
|
||||
defm OR : BinaryInt<or, "or">;
|
||||
defm XOR : BinaryInt<xor, "xor">;
|
||||
defm SHL : BinaryInt<shl, "shl">;
|
||||
defm SHR_U : BinaryInt<srl, "shr_u">;
|
||||
defm SHR_S : BinaryInt<sra, "shr_s">;
|
||||
|
||||
defm EQ : ComparisonInt<SETEQ>;
|
||||
defm NE : ComparisonInt<SETNE>;
|
||||
defm LT_S : ComparisonInt<SETLT>;
|
||||
defm LE_S : ComparisonInt<SETLE>;
|
||||
defm LT_U : ComparisonInt<SETULT>;
|
||||
defm LE_U : ComparisonInt<SETULE>;
|
||||
defm GT_S : ComparisonInt<SETGT>;
|
||||
defm GE_S : ComparisonInt<SETGE>;
|
||||
defm GT_U : ComparisonInt<SETUGT>;
|
||||
defm GE_U : ComparisonInt<SETUGE>;
|
||||
defm EQ : ComparisonInt<SETEQ, "eq">;
|
||||
defm NE : ComparisonInt<SETNE, "ne">;
|
||||
defm LT_S : ComparisonInt<SETLT, "lt_s">;
|
||||
defm LE_S : ComparisonInt<SETLE, "le_s">;
|
||||
defm LT_U : ComparisonInt<SETULT, "lt_u">;
|
||||
defm LE_U : ComparisonInt<SETULE, "le_u">;
|
||||
defm GT_S : ComparisonInt<SETGT, "gt_s">;
|
||||
defm GE_S : ComparisonInt<SETGE, "ge_s">;
|
||||
defm GT_U : ComparisonInt<SETUGT, "gt_u">;
|
||||
defm GE_U : ComparisonInt<SETUGE, "ge_u">;
|
||||
|
||||
defm CLZ : UnaryInt<ctlz>;
|
||||
defm CTZ : UnaryInt<cttz>;
|
||||
defm POPCNT : UnaryInt<ctpop>;
|
||||
defm CLZ : UnaryInt<ctlz, "clz">;
|
||||
defm CTZ : UnaryInt<cttz, "ctz">;
|
||||
defm POPCNT : UnaryInt<ctpop, "popcnt">;
|
||||
|
||||
// Expand the "don't care" operations to supported operations.
|
||||
def : Pat<(ctlz_zero_undef I32:$src), (CLZ_I32 I32:$src)>;
|
||||
@ -48,6 +48,8 @@ def : Pat<(cttz_zero_undef I32:$src), (CTZ_I32 I32:$src)>;
|
||||
def : Pat<(cttz_zero_undef I64:$src), (CTZ_I64 I64:$src)>;
|
||||
|
||||
def SELECT_I32 : I<(outs I32:$dst), (ins I32:$cond, I32:$lhs, I32:$rhs),
|
||||
[(set I32:$dst, (select I32:$cond, I32:$lhs, I32:$rhs))]>;
|
||||
[(set I32:$dst, (select I32:$cond, I32:$lhs, I32:$rhs))],
|
||||
"i32.select $dst, $cond, $lhs, $rhs">;
|
||||
def SELECT_I64 : I<(outs I64:$dst), (ins I32:$cond, I64:$lhs, I64:$rhs),
|
||||
[(set I64:$dst, (select I32:$cond, I64:$lhs, I64:$rhs))]>;
|
||||
[(set I64:$dst, (select I32:$cond, I64:$lhs, I64:$rhs))],
|
||||
"i32.select $dst, $cond, $lhs, $rhs">;
|
||||
|
@ -24,35 +24,49 @@
|
||||
|
||||
// Basic load.
|
||||
def LOAD_I32 : I<(outs I32:$dst), (ins I32:$addr),
|
||||
[(set I32:$dst, (load I32:$addr))]>;
|
||||
[(set I32:$dst, (load I32:$addr))],
|
||||
"i32.load $dst, $addr">;
|
||||
def LOAD_I64 : I<(outs I64:$dst), (ins I32:$addr),
|
||||
[(set I64:$dst, (load I32:$addr))]>;
|
||||
[(set I64:$dst, (load I32:$addr))],
|
||||
"i64.load $dst, $addr">;
|
||||
def LOAD_F32 : I<(outs F32:$dst), (ins I32:$addr),
|
||||
[(set F32:$dst, (load I32:$addr))]>;
|
||||
[(set F32:$dst, (load I32:$addr))],
|
||||
"f32.load $dst, $addr">;
|
||||
def LOAD_F64 : I<(outs F64:$dst), (ins I32:$addr),
|
||||
[(set F64:$dst, (load I32:$addr))]>;
|
||||
[(set F64:$dst, (load I32:$addr))],
|
||||
"f64.load $dst, $addr">;
|
||||
|
||||
// Extending load.
|
||||
def LOAD8_S_I32 : I<(outs I32:$dst), (ins I32:$addr),
|
||||
[(set I32:$dst, (sextloadi8 I32:$addr))]>;
|
||||
[(set I32:$dst, (sextloadi8 I32:$addr))],
|
||||
"i32.load8_s $dst, $addr">;
|
||||
def LOAD8_U_I32 : I<(outs I32:$dst), (ins I32:$addr),
|
||||
[(set I32:$dst, (zextloadi8 I32:$addr))]>;
|
||||
[(set I32:$dst, (zextloadi8 I32:$addr))],
|
||||
"i32.load8_u $dst, $addr">;
|
||||
def LOAD16_S_I32 : I<(outs I32:$dst), (ins I32:$addr),
|
||||
[(set I32:$dst, (sextloadi16 I32:$addr))]>;
|
||||
[(set I32:$dst, (sextloadi16 I32:$addr))],
|
||||
"i32.load16_s $dst, $addr">;
|
||||
def LOAD16_U_I32 : I<(outs I32:$dst), (ins I32:$addr),
|
||||
[(set I32:$dst, (zextloadi16 I32:$addr))]>;
|
||||
[(set I32:$dst, (zextloadi16 I32:$addr))],
|
||||
"i32.load16_u $dst, $addr">;
|
||||
def LOAD8_S_I64 : I<(outs I64:$dst), (ins I32:$addr),
|
||||
[(set I64:$dst, (sextloadi8 I32:$addr))]>;
|
||||
[(set I64:$dst, (sextloadi8 I32:$addr))],
|
||||
"i64.load8_s $dst, $addr">;
|
||||
def LOAD8_U_I64 : I<(outs I64:$dst), (ins I32:$addr),
|
||||
[(set I64:$dst, (zextloadi8 I32:$addr))]>;
|
||||
[(set I64:$dst, (zextloadi8 I32:$addr))],
|
||||
"i64.load8_u $dst, $addr">;
|
||||
def LOAD16_S_I64 : I<(outs I64:$dst), (ins I32:$addr),
|
||||
[(set I64:$dst, (sextloadi16 I32:$addr))]>;
|
||||
[(set I64:$dst, (sextloadi16 I32:$addr))],
|
||||
"i64.load16_s $dst, $addr">;
|
||||
def LOAD16_U_I64 : I<(outs I64:$dst), (ins I32:$addr),
|
||||
[(set I64:$dst, (zextloadi16 I32:$addr))]>;
|
||||
[(set I64:$dst, (zextloadi16 I32:$addr))],
|
||||
"i64.load16_u $dst, $addr">;
|
||||
def LOAD32_S_I64 : I<(outs I64:$dst), (ins I32:$addr),
|
||||
[(set I64:$dst, (sextloadi32 I32:$addr))]>;
|
||||
[(set I64:$dst, (sextloadi32 I32:$addr))],
|
||||
"i64.load32_s $dst, $addr">;
|
||||
def LOAD32_U_I64 : I<(outs I64:$dst), (ins I32:$addr),
|
||||
[(set I64:$dst, (zextloadi32 I32:$addr))]>;
|
||||
[(set I64:$dst, (zextloadi32 I32:$addr))],
|
||||
"i64.load32_u $dst, $addr">;
|
||||
|
||||
// "Don't care" extending load become zero-extending load.
|
||||
def : Pat<(i32 (extloadi8 I32:$addr)), (LOAD8_U_I32 $addr)>;
|
||||
@ -64,38 +78,51 @@ def : Pat<(i64 (extloadi32 I32:$addr)), (LOAD32_U_I64 $addr)>;
|
||||
// Basic store.
|
||||
// Note: WebAssembly inverts SelectionDAG's usual operand order.
|
||||
def STORE_I32 : I<(outs), (ins I32:$addr, I32:$val),
|
||||
[(store i32:$val, I32:$addr)]>;
|
||||
[(store i32:$val, I32:$addr)],
|
||||
"i32.store $addr, $val">;
|
||||
def STORE_I64 : I<(outs), (ins I32:$addr, I64:$val),
|
||||
[(store i64:$val, I32:$addr)]>;
|
||||
[(store i64:$val, I32:$addr)],
|
||||
"i64.store $addr, $val">;
|
||||
def STORE_F32 : I<(outs), (ins I32:$addr, F32:$val),
|
||||
[(store f32:$val, I32:$addr)]>;
|
||||
[(store f32:$val, I32:$addr)],
|
||||
"i64.store $addr, $val">;
|
||||
def STORE_F64 : I<(outs), (ins I32:$addr, F64:$val),
|
||||
[(store f64:$val, I32:$addr)]>;
|
||||
[(store f64:$val, I32:$addr)],
|
||||
"i64.store $addr, $val">;
|
||||
|
||||
// Truncating store.
|
||||
def STORE8_I32 : I<(outs), (ins I32:$addr, I32:$val),
|
||||
[(truncstorei8 I32:$val, I32:$addr)]>;
|
||||
[(truncstorei8 I32:$val, I32:$addr)],
|
||||
"i32.store8 $addr, $val">;
|
||||
def STORE16_I32 : I<(outs), (ins I32:$addr, I32:$val),
|
||||
[(truncstorei16 I32:$val, I32:$addr)]>;
|
||||
[(truncstorei16 I32:$val, I32:$addr)],
|
||||
"i32.store16 $addr, $val">;
|
||||
def STORE8_I64 : I<(outs), (ins I32:$addr, I64:$val),
|
||||
[(truncstorei8 I64:$val, I32:$addr)]>;
|
||||
[(truncstorei8 I64:$val, I32:$addr)],
|
||||
"i64.store8 $addr, $val">;
|
||||
def STORE16_I64 : I<(outs), (ins I32:$addr, I64:$val),
|
||||
[(truncstorei16 I64:$val, I32:$addr)]>;
|
||||
[(truncstorei16 I64:$val, I32:$addr)],
|
||||
"i64.store16 $addr, $val">;
|
||||
def STORE32_I64 : I<(outs), (ins I32:$addr, I64:$val),
|
||||
[(truncstorei32 I64:$val, I32:$addr)]>;
|
||||
[(truncstorei32 I64:$val, I32:$addr)],
|
||||
"i64.store32 $addr, $val">;
|
||||
|
||||
// Memory size.
|
||||
def memory_size_I32 : I<(outs I32:$dst), (ins),
|
||||
[(set I32:$dst, (int_wasm_memory_size))]>,
|
||||
[(set I32:$dst, (int_wasm_memory_size))],
|
||||
"i32.memory_size $dst">,
|
||||
Requires<[HasAddr32]>;
|
||||
def memory_size_I64 : I<(outs I64:$dst), (ins),
|
||||
[(set I64:$dst, (int_wasm_memory_size))]>,
|
||||
[(set I64:$dst, (int_wasm_memory_size))],
|
||||
"i64.memory_size $dst">,
|
||||
Requires<[HasAddr64]>;
|
||||
|
||||
// Grow memory.
|
||||
def grow_memory_I32 : I<(outs), (ins I32:$delta),
|
||||
[(int_wasm_grow_memory I32:$delta)]>,
|
||||
[(int_wasm_grow_memory I32:$delta)],
|
||||
"i32.grow_memory $delta">,
|
||||
Requires<[HasAddr32]>;
|
||||
def grow_memory_I64 : I<(outs), (ins I64:$delta),
|
||||
[(int_wasm_grow_memory I64:$delta)]>,
|
||||
[(int_wasm_grow_memory I64:$delta)],
|
||||
"i64.grow_memory $delta">,
|
||||
Requires<[HasAddr64]>;
|
||||
|
Loading…
Reference in New Issue
Block a user