mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 11:13:28 +01:00
[WebAssembly] Add binary-encoding opcode values to instruction descriptions.
llvm-svn: 283389
This commit is contained in:
parent
7388fcda39
commit
cfaebd7741
@ -44,6 +44,10 @@ namespace WebAssembly {
|
||||
enum OperandType {
|
||||
/// Basic block label in a branch construct.
|
||||
OPERAND_BASIC_BLOCK = MCOI::OPERAND_FIRST_TARGET,
|
||||
/// 32-bit integer immediates.
|
||||
OPERAND_I32IMM,
|
||||
/// 64-bit integer immediates.
|
||||
OPERAND_I64IMM,
|
||||
/// 32-bit floating-point immediates.
|
||||
OPERAND_F32IMM,
|
||||
/// 64-bit floating-point immediates.
|
||||
|
@ -18,14 +18,13 @@ let isBranch = 1, isTerminator = 1, hasCtrlDep = 1 in {
|
||||
// The condition operand is a boolean value which WebAssembly represents as i32.
|
||||
def BR_IF : I<(outs), (ins bb_op:$dst, I32:$cond),
|
||||
[(brcond I32:$cond, bb:$dst)],
|
||||
"br_if \t$dst, $cond">;
|
||||
"br_if \t$dst, $cond", 0x07>;
|
||||
let isCodeGenOnly = 1 in
|
||||
def BR_UNLESS : I<(outs), (ins bb_op:$dst, I32:$cond), [],
|
||||
"br_unless\t$dst, $cond">;
|
||||
def BR_UNLESS : I<(outs), (ins bb_op:$dst, I32:$cond), []>;
|
||||
let isBarrier = 1 in {
|
||||
def BR : I<(outs), (ins bb_op:$dst),
|
||||
[(br bb:$dst)],
|
||||
"br \t$dst">;
|
||||
"br \t$dst", 0x06>;
|
||||
} // isBarrier = 1
|
||||
} // isBranch = 1, isTerminator = 1, hasCtrlDep = 1
|
||||
|
||||
@ -46,7 +45,7 @@ let Defs = [ARGUMENTS] in {
|
||||
let isTerminator = 1, hasCtrlDep = 1, isBarrier = 1 in {
|
||||
def BR_TABLE_I32 : I<(outs), (ins I32:$index, variable_ops),
|
||||
[(WebAssemblybr_table I32:$index)],
|
||||
"br_table \t$index"> {
|
||||
"br_table \t$index", 0x08> {
|
||||
let TSFlags{0} = 1;
|
||||
let TSFlags{1} = 1;
|
||||
}
|
||||
@ -62,8 +61,8 @@ def BR_TABLE_I64 : I<(outs), (ins I64:$index, variable_ops),
|
||||
// use/clobber VALUE_STACK to prevent them from being moved into the middle of
|
||||
// an expression tree.
|
||||
let Uses = [VALUE_STACK], Defs = [VALUE_STACK] in {
|
||||
def BLOCK : I<(outs), (ins), [], "block">;
|
||||
def LOOP : I<(outs), (ins), [], "loop">;
|
||||
def BLOCK : I<(outs), (ins), [], "block", 0x01>;
|
||||
def LOOP : I<(outs), (ins), [], "loop", 0x02>;
|
||||
def END_BLOCK : I<(outs), (ins), [], "end_block">;
|
||||
def END_LOOP : I<(outs), (ins), [], "end_loop">;
|
||||
} // Uses = [VALUE_STACK], Defs = [VALUE_STACK]
|
||||
|
@ -17,14 +17,14 @@ let Defs = [ARGUMENTS] in {
|
||||
|
||||
def I32_WRAP_I64 : I<(outs I32:$dst), (ins I64:$src),
|
||||
[(set I32:$dst, (trunc I64:$src))],
|
||||
"i32.wrap/i64\t$dst, $src">;
|
||||
"i32.wrap/i64\t$dst, $src", 0xa1>;
|
||||
|
||||
def I64_EXTEND_S_I32 : I<(outs I64:$dst), (ins I32:$src),
|
||||
[(set I64:$dst, (sext I32:$src))],
|
||||
"i64.extend_s/i32\t$dst, $src">;
|
||||
"i64.extend_s/i32\t$dst, $src", 0xa6>;
|
||||
def I64_EXTEND_U_I32 : I<(outs I64:$dst), (ins I32:$src),
|
||||
[(set I64:$dst, (zext I32:$src))],
|
||||
"i64.extend_u/i32\t$dst, $src">;
|
||||
"i64.extend_u/i32\t$dst, $src", 0xa7>;
|
||||
|
||||
} // defs = [ARGUMENTS]
|
||||
|
||||
@ -39,73 +39,73 @@ let Defs = [ARGUMENTS] in {
|
||||
let hasSideEffects = 1 in {
|
||||
def I32_TRUNC_S_F32 : I<(outs I32:$dst), (ins F32:$src),
|
||||
[(set I32:$dst, (fp_to_sint F32:$src))],
|
||||
"i32.trunc_s/f32\t$dst, $src">;
|
||||
"i32.trunc_s/f32\t$dst, $src", 0x9d>;
|
||||
def I32_TRUNC_U_F32 : I<(outs I32:$dst), (ins F32:$src),
|
||||
[(set I32:$dst, (fp_to_uint F32:$src))],
|
||||
"i32.trunc_u/f32\t$dst, $src">;
|
||||
"i32.trunc_u/f32\t$dst, $src", 0x9f>;
|
||||
def I64_TRUNC_S_F32 : I<(outs I64:$dst), (ins F32:$src),
|
||||
[(set I64:$dst, (fp_to_sint F32:$src))],
|
||||
"i64.trunc_s/f32\t$dst, $src">;
|
||||
"i64.trunc_s/f32\t$dst, $src", 0xa2>;
|
||||
def I64_TRUNC_U_F32 : I<(outs I64:$dst), (ins F32:$src),
|
||||
[(set I64:$dst, (fp_to_uint F32:$src))],
|
||||
"i64.trunc_u/f32\t$dst, $src">;
|
||||
"i64.trunc_u/f32\t$dst, $src", 0xa4>;
|
||||
def I32_TRUNC_S_F64 : I<(outs I32:$dst), (ins F64:$src),
|
||||
[(set I32:$dst, (fp_to_sint F64:$src))],
|
||||
"i32.trunc_s/f64\t$dst, $src">;
|
||||
"i32.trunc_s/f64\t$dst, $src", 0x9e>;
|
||||
def I32_TRUNC_U_F64 : I<(outs I32:$dst), (ins F64:$src),
|
||||
[(set I32:$dst, (fp_to_uint F64:$src))],
|
||||
"i32.trunc_u/f64\t$dst, $src">;
|
||||
"i32.trunc_u/f64\t$dst, $src", 0xa0>;
|
||||
def I64_TRUNC_S_F64 : I<(outs I64:$dst), (ins F64:$src),
|
||||
[(set I64:$dst, (fp_to_sint F64:$src))],
|
||||
"i64.trunc_s/f64\t$dst, $src">;
|
||||
"i64.trunc_s/f64\t$dst, $src", 0xa3>;
|
||||
def I64_TRUNC_U_F64 : I<(outs I64:$dst), (ins F64:$src),
|
||||
[(set I64:$dst, (fp_to_uint F64:$src))],
|
||||
"i64.trunc_u/f64\t$dst, $src">;
|
||||
"i64.trunc_u/f64\t$dst, $src", 0xa5>;
|
||||
} // hasSideEffects = 1
|
||||
|
||||
def F32_CONVERT_S_I32 : I<(outs F32:$dst), (ins I32:$src),
|
||||
[(set F32:$dst, (sint_to_fp I32:$src))],
|
||||
"f32.convert_s/i32\t$dst, $src">;
|
||||
"f32.convert_s/i32\t$dst, $src", 0xa8>;
|
||||
def F32_CONVERT_U_I32 : I<(outs F32:$dst), (ins I32:$src),
|
||||
[(set F32:$dst, (uint_to_fp I32:$src))],
|
||||
"f32.convert_u/i32\t$dst, $src">;
|
||||
"f32.convert_u/i32\t$dst, $src", 0xa9>;
|
||||
def F64_CONVERT_S_I32 : I<(outs F64:$dst), (ins I32:$src),
|
||||
[(set F64:$dst, (sint_to_fp I32:$src))],
|
||||
"f64.convert_s/i32\t$dst, $src">;
|
||||
"f64.convert_s/i32\t$dst, $src", 0xae>;
|
||||
def F64_CONVERT_U_I32 : I<(outs F64:$dst), (ins I32:$src),
|
||||
[(set F64:$dst, (uint_to_fp I32:$src))],
|
||||
"f64.convert_u/i32\t$dst, $src">;
|
||||
"f64.convert_u/i32\t$dst, $src", 0xaf>;
|
||||
def F32_CONVERT_S_I64 : I<(outs F32:$dst), (ins I64:$src),
|
||||
[(set F32:$dst, (sint_to_fp I64:$src))],
|
||||
"f32.convert_s/i64\t$dst, $src">;
|
||||
"f32.convert_s/i64\t$dst, $src", 0xaa>;
|
||||
def F32_CONVERT_U_I64 : I<(outs F32:$dst), (ins I64:$src),
|
||||
[(set F32:$dst, (uint_to_fp I64:$src))],
|
||||
"f32.convert_u/i64\t$dst, $src">;
|
||||
"f32.convert_u/i64\t$dst, $src", 0xab>;
|
||||
def F64_CONVERT_S_I64 : I<(outs F64:$dst), (ins I64:$src),
|
||||
[(set F64:$dst, (sint_to_fp I64:$src))],
|
||||
"f64.convert_s/i64\t$dst, $src">;
|
||||
"f64.convert_s/i64\t$dst, $src", 0xb0>;
|
||||
def F64_CONVERT_U_I64 : I<(outs F64:$dst), (ins I64:$src),
|
||||
[(set F64:$dst, (uint_to_fp I64:$src))],
|
||||
"f64.convert_u/i64\t$dst, $src">;
|
||||
"f64.convert_u/i64\t$dst, $src", 0xb1>;
|
||||
|
||||
def F64_PROMOTE_F32 : I<(outs F64:$dst), (ins F32:$src),
|
||||
[(set F64:$dst, (fpextend F32:$src))],
|
||||
"f64.promote/f32\t$dst, $src">;
|
||||
"f64.promote/f32\t$dst, $src", 0xb2>;
|
||||
def F32_DEMOTE_F64 : I<(outs F32:$dst), (ins F64:$src),
|
||||
[(set F32:$dst, (fpround F64:$src))],
|
||||
"f32.demote/f64\t$dst, $src">;
|
||||
"f32.demote/f64\t$dst, $src", 0xac>;
|
||||
|
||||
def I32_REINTERPRET_F32 : I<(outs I32:$dst), (ins F32:$src),
|
||||
[(set I32:$dst, (bitconvert F32:$src))],
|
||||
"i32.reinterpret/f32\t$dst, $src">;
|
||||
"i32.reinterpret/f32\t$dst, $src", 0xb4>;
|
||||
def F32_REINTERPRET_I32 : I<(outs F32:$dst), (ins I32:$src),
|
||||
[(set F32:$dst, (bitconvert I32:$src))],
|
||||
"f32.reinterpret/i32\t$dst, $src">;
|
||||
"f32.reinterpret/i32\t$dst, $src", 0xad>;
|
||||
def I64_REINTERPRET_F64 : I<(outs I64:$dst), (ins F64:$src),
|
||||
[(set I64:$dst, (bitconvert F64:$src))],
|
||||
"i64.reinterpret/f64\t$dst, $src">;
|
||||
"i64.reinterpret/f64\t$dst, $src", 0xb5>;
|
||||
def F64_REINTERPRET_I64 : I<(outs F64:$dst), (ins I64:$src),
|
||||
[(set F64:$dst, (bitconvert I64:$src))],
|
||||
"f64.reinterpret/i64\t$dst, $src">;
|
||||
"f64.reinterpret/i64\t$dst, $src", 0xb3>;
|
||||
|
||||
} // Defs = [ARGUMENTS]
|
||||
|
@ -15,26 +15,26 @@
|
||||
let Defs = [ARGUMENTS] in {
|
||||
|
||||
let isCommutable = 1 in
|
||||
defm ADD : BinaryFP<fadd, "add ">;
|
||||
defm SUB : BinaryFP<fsub, "sub ">;
|
||||
defm ADD : BinaryFP<fadd, "add ", 0x75, 0x89>;
|
||||
defm SUB : BinaryFP<fsub, "sub ", 0x76, 0x8a>;
|
||||
let isCommutable = 1 in
|
||||
defm MUL : BinaryFP<fmul, "mul ">;
|
||||
defm DIV : BinaryFP<fdiv, "div ">;
|
||||
defm SQRT : UnaryFP<fsqrt, "sqrt">;
|
||||
defm MUL : BinaryFP<fmul, "mul ", 0x77, 0x8b>;
|
||||
defm DIV : BinaryFP<fdiv, "div ", 0x78, 0x8c>;
|
||||
defm SQRT : UnaryFP<fsqrt, "sqrt", 0x82, 0x96>;
|
||||
|
||||
defm ABS : UnaryFP<fabs, "abs ">;
|
||||
defm NEG : UnaryFP<fneg, "neg ">;
|
||||
defm COPYSIGN : BinaryFP<fcopysign, "copysign">;
|
||||
defm ABS : UnaryFP<fabs, "abs ", 0x7b, 0x8f>;
|
||||
defm NEG : UnaryFP<fneg, "neg ", 0x7c, 0x90>;
|
||||
defm COPYSIGN : BinaryFP<fcopysign, "copysign", 0x7d, 0x91>;
|
||||
|
||||
let isCommutable = 1 in {
|
||||
defm MIN : BinaryFP<fminnan, "min ">;
|
||||
defm MAX : BinaryFP<fmaxnan, "max ">;
|
||||
defm MIN : BinaryFP<fminnan, "min ", 0x79, 0x8d>;
|
||||
defm MAX : BinaryFP<fmaxnan, "max ", 0x7a, 0x8e>;
|
||||
} // isCommutable = 1
|
||||
|
||||
defm CEIL : UnaryFP<fceil, "ceil">;
|
||||
defm FLOOR : UnaryFP<ffloor, "floor">;
|
||||
defm TRUNC : UnaryFP<ftrunc, "trunc">;
|
||||
defm NEAREST : UnaryFP<fnearbyint, "nearest">;
|
||||
defm CEIL : UnaryFP<fceil, "ceil", 0x7e, 0x92>;
|
||||
defm FLOOR : UnaryFP<ffloor, "floor", 0x7f, 0x93>;
|
||||
defm TRUNC : UnaryFP<ftrunc, "trunc", 0x80, 0x94>;
|
||||
defm NEAREST : UnaryFP<fnearbyint, "nearest", 0x81, 0x95>;
|
||||
|
||||
} // Defs = [ARGUMENTS]
|
||||
|
||||
@ -51,13 +51,13 @@ def : Pat<(frint f64:$src), (NEAREST_F64 f64:$src)>;
|
||||
let Defs = [ARGUMENTS] in {
|
||||
|
||||
let isCommutable = 1 in {
|
||||
defm EQ : ComparisonFP<SETOEQ, "eq ">;
|
||||
defm NE : ComparisonFP<SETUNE, "ne ">;
|
||||
defm EQ : ComparisonFP<SETOEQ, "eq ", 0x83, 0x97>;
|
||||
defm NE : ComparisonFP<SETUNE, "ne ", 0x84, 0x98>;
|
||||
} // isCommutable = 1
|
||||
defm LT : ComparisonFP<SETOLT, "lt ">;
|
||||
defm LE : ComparisonFP<SETOLE, "le ">;
|
||||
defm GT : ComparisonFP<SETOGT, "gt ">;
|
||||
defm GE : ComparisonFP<SETOGE, "ge ">;
|
||||
defm LT : ComparisonFP<SETOLT, "lt ", 0x85, 0x99>;
|
||||
defm LE : ComparisonFP<SETOLE, "le ", 0x86, 0x9a>;
|
||||
defm GT : ComparisonFP<SETOGT, "gt ", 0x87, 0x9b>;
|
||||
defm GE : ComparisonFP<SETOGE, "ge ", 0x88, 0x9c>;
|
||||
|
||||
} // Defs = [ARGUMENTS]
|
||||
|
||||
|
@ -13,56 +13,57 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// WebAssembly Instruction Format.
|
||||
class WebAssemblyInst<string asmstr> : Instruction {
|
||||
field bits<0> Inst; // Instruction encoding.
|
||||
class WebAssemblyInst<bits<32> inst, string asmstr> : Instruction {
|
||||
field bits<32> Inst = inst; // Instruction encoding.
|
||||
let Namespace = "WebAssembly";
|
||||
let Pattern = [];
|
||||
let AsmString = asmstr;
|
||||
}
|
||||
|
||||
// Normal instructions.
|
||||
class I<dag oops, dag iops, list<dag> pattern, string asmstr = "">
|
||||
: WebAssemblyInst<asmstr> {
|
||||
class I<dag oops, dag iops, list<dag> pattern, string asmstr = "", bits<32> inst = -1>
|
||||
: WebAssemblyInst<inst, asmstr> {
|
||||
dag OutOperandList = oops;
|
||||
dag InOperandList = iops;
|
||||
let Pattern = pattern;
|
||||
}
|
||||
|
||||
class SIMD_I<dag oops, dag iops, list<dag> pattern, string asmstr = "">
|
||||
: I<oops, iops, pattern, asmstr>, Requires<[HasSIMD128]>;
|
||||
class SIMD_I<dag oops, dag iops, list<dag> pattern,
|
||||
string asmstr = "", bits<32> inst = -1>
|
||||
: I<oops, iops, pattern, asmstr, inst>, Requires<[HasSIMD128]>;
|
||||
|
||||
// Unary and binary instructions, for the local types that WebAssembly supports.
|
||||
multiclass UnaryInt<SDNode node, string name> {
|
||||
multiclass UnaryInt<SDNode node, string name, bits<32> i32Inst, bits<32> i64Inst> {
|
||||
def _I32 : I<(outs I32:$dst), (ins I32:$src),
|
||||
[(set I32:$dst, (node I32:$src))],
|
||||
!strconcat("i32.", !strconcat(name, "\t$dst, $src"))>;
|
||||
!strconcat("i32.", !strconcat(name, "\t$dst, $src")), i32Inst>;
|
||||
def _I64 : I<(outs I64:$dst), (ins I64:$src),
|
||||
[(set I64:$dst, (node I64:$src))],
|
||||
!strconcat("i64.", !strconcat(name, "\t$dst, $src"))>;
|
||||
!strconcat("i64.", !strconcat(name, "\t$dst, $src")), i64Inst>;
|
||||
}
|
||||
multiclass BinaryInt<SDNode node, string name> {
|
||||
multiclass BinaryInt<SDNode node, string name, bits<32> i32Inst, bits<32> i64Inst> {
|
||||
def _I32 : I<(outs I32:$dst), (ins I32:$lhs, I32:$rhs),
|
||||
[(set I32:$dst, (node I32:$lhs, I32:$rhs))],
|
||||
!strconcat("i32.", !strconcat(name, "\t$dst, $lhs, $rhs"))>;
|
||||
!strconcat("i32.", !strconcat(name, "\t$dst, $lhs, $rhs")), i32Inst>;
|
||||
def _I64 : I<(outs I64:$dst), (ins I64:$lhs, I64:$rhs),
|
||||
[(set I64:$dst, (node I64:$lhs, I64:$rhs))],
|
||||
!strconcat("i64.", !strconcat(name, "\t$dst, $lhs, $rhs"))>;
|
||||
!strconcat("i64.", !strconcat(name, "\t$dst, $lhs, $rhs")), i64Inst>;
|
||||
}
|
||||
multiclass UnaryFP<SDNode node, string name> {
|
||||
multiclass UnaryFP<SDNode node, string name, bits<32> f32Inst, bits<32> f64Inst> {
|
||||
def _F32 : I<(outs F32:$dst), (ins F32:$src),
|
||||
[(set F32:$dst, (node F32:$src))],
|
||||
!strconcat("f32.", !strconcat(name, "\t$dst, $src"))>;
|
||||
!strconcat("f32.", !strconcat(name, "\t$dst, $src")), f32Inst>;
|
||||
def _F64 : I<(outs F64:$dst), (ins F64:$src),
|
||||
[(set F64:$dst, (node F64:$src))],
|
||||
!strconcat("f64.", !strconcat(name, "\t$dst, $src"))>;
|
||||
!strconcat("f64.", !strconcat(name, "\t$dst, $src")), f64Inst>;
|
||||
}
|
||||
multiclass BinaryFP<SDNode node, string name> {
|
||||
multiclass BinaryFP<SDNode node, string name, bits<32> f32Inst, bits<32> f64Inst> {
|
||||
def _F32 : I<(outs F32:$dst), (ins F32:$lhs, F32:$rhs),
|
||||
[(set F32:$dst, (node F32:$lhs, F32:$rhs))],
|
||||
!strconcat("f32.", !strconcat(name, "\t$dst, $lhs, $rhs"))>;
|
||||
!strconcat("f32.", !strconcat(name, "\t$dst, $lhs, $rhs")), f32Inst>;
|
||||
def _F64 : I<(outs F64:$dst), (ins F64:$lhs, F64:$rhs),
|
||||
[(set F64:$dst, (node F64:$lhs, F64:$rhs))],
|
||||
!strconcat("f64.", !strconcat(name, "\t$dst, $lhs, $rhs"))>;
|
||||
!strconcat("f64.", !strconcat(name, "\t$dst, $lhs, $rhs")), f64Inst>;
|
||||
}
|
||||
multiclass SIMDBinary<SDNode node, SDNode fnode, string name> {
|
||||
def _I8x16 : SIMD_I<(outs V128:$dst), (ins V128:$lhs, V128:$rhs),
|
||||
@ -79,19 +80,23 @@ multiclass SIMDBinary<SDNode node, SDNode fnode, string name> {
|
||||
!strconcat("f32x4.", !strconcat(name, "\t$dst, $lhs, $rhs"))>;
|
||||
|
||||
}
|
||||
multiclass ComparisonInt<CondCode cond, string name> {
|
||||
multiclass ComparisonInt<CondCode cond, string name, bits<32> i32Inst, bits<32> i64Inst> {
|
||||
def _I32 : I<(outs I32:$dst), (ins I32:$lhs, I32:$rhs),
|
||||
[(set I32:$dst, (setcc I32:$lhs, I32:$rhs, cond))],
|
||||
!strconcat("i32.", !strconcat(name, "\t$dst, $lhs, $rhs"))>;
|
||||
!strconcat("i32.", !strconcat(name, "\t$dst, $lhs, $rhs")),
|
||||
i32Inst>;
|
||||
def _I64 : I<(outs I32:$dst), (ins I64:$lhs, I64:$rhs),
|
||||
[(set I32:$dst, (setcc I64:$lhs, I64:$rhs, cond))],
|
||||
!strconcat("i64.", !strconcat(name, "\t$dst, $lhs, $rhs"))>;
|
||||
!strconcat("i64.", !strconcat(name, "\t$dst, $lhs, $rhs")),
|
||||
i64Inst>;
|
||||
}
|
||||
multiclass ComparisonFP<CondCode cond, string name> {
|
||||
multiclass ComparisonFP<CondCode cond, string name, bits<32> f32Inst, bits<32> f64Inst> {
|
||||
def _F32 : I<(outs I32:$dst), (ins F32:$lhs, F32:$rhs),
|
||||
[(set I32:$dst, (setcc F32:$lhs, F32:$rhs, cond))],
|
||||
!strconcat("f32.", !strconcat(name, "\t$dst, $lhs, $rhs"))>;
|
||||
!strconcat("f32.", !strconcat(name, "\t$dst, $lhs, $rhs")),
|
||||
f32Inst>;
|
||||
def _F64 : I<(outs I32:$dst), (ins F64:$lhs, F64:$rhs),
|
||||
[(set I32:$dst, (setcc F64:$lhs, F64:$rhs, cond))],
|
||||
!strconcat("f64.", !strconcat(name, "\t$dst, $lhs, $rhs"))>;
|
||||
!strconcat("f64.", !strconcat(name, "\t$dst, $lhs, $rhs")),
|
||||
f64Inst>;
|
||||
}
|
||||
|
@ -71,6 +71,12 @@ let OperandNamespace = "WebAssembly" in {
|
||||
let OperandType = "OPERAND_BASIC_BLOCK" in
|
||||
def bb_op : Operand<OtherVT>;
|
||||
|
||||
let OperandType = "OPERAND_I32IMM" in
|
||||
def i32imm_op : Operand<i32>;
|
||||
|
||||
let OperandType = "OPERAND_I64IMM" in
|
||||
def i64imm_op : Operand<i64>;
|
||||
|
||||
let OperandType = "OPERAND_F32IMM" in
|
||||
def f32imm_op : Operand<f32>;
|
||||
|
||||
@ -144,10 +150,10 @@ defm : LOCAL<F64>;
|
||||
defm : LOCAL<V128>, Requires<[HasSIMD128]>;
|
||||
|
||||
let isMoveImm = 1, isAsCheapAsAMove = 1, isReMaterializable = 1 in {
|
||||
def CONST_I32 : I<(outs I32:$res), (ins i32imm:$imm),
|
||||
def CONST_I32 : I<(outs I32:$res), (ins i32imm_op:$imm),
|
||||
[(set I32:$res, imm:$imm)],
|
||||
"i32.const\t$res, $imm">;
|
||||
def CONST_I64 : I<(outs I64:$res), (ins i64imm:$imm),
|
||||
def CONST_I64 : I<(outs I64:$res), (ins i64imm_op:$imm),
|
||||
[(set I64:$res, imm:$imm)],
|
||||
"i64.const\t$res, $imm">;
|
||||
def CONST_F32 : I<(outs F32:$res), (ins f32imm_op:$imm),
|
||||
|
@ -17,51 +17,51 @@ let Defs = [ARGUMENTS] in {
|
||||
// The spaces after the names are for aesthetic purposes only, to make
|
||||
// operands line up vertically after tab expansion.
|
||||
let isCommutable = 1 in
|
||||
defm ADD : BinaryInt<add, "add ">;
|
||||
defm SUB : BinaryInt<sub, "sub ">;
|
||||
defm ADD : BinaryInt<add, "add ", 0x40, 0x5b>;
|
||||
defm SUB : BinaryInt<sub, "sub ", 0x41, 0x5c>;
|
||||
let isCommutable = 1 in
|
||||
defm MUL : BinaryInt<mul, "mul ">;
|
||||
defm MUL : BinaryInt<mul, "mul ", 0x42, 0x5d>;
|
||||
// Divide and remainder trap on a zero denominator.
|
||||
let hasSideEffects = 1 in {
|
||||
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 DIV_S : BinaryInt<sdiv, "div_s", 0x43, 0x5e>;
|
||||
defm DIV_U : BinaryInt<udiv, "div_u", 0x44, 0x5f>;
|
||||
defm REM_S : BinaryInt<srem, "rem_s", 0x45, 0x60>;
|
||||
defm REM_U : BinaryInt<urem, "rem_u", 0x46, 0x61>;
|
||||
} // hasSideEffects = 1
|
||||
let isCommutable = 1 in {
|
||||
defm AND : BinaryInt<and, "and ">;
|
||||
defm OR : BinaryInt<or, "or ">;
|
||||
defm XOR : BinaryInt<xor, "xor ">;
|
||||
defm AND : BinaryInt<and, "and ", 0x47, 0x62>;
|
||||
defm OR : BinaryInt<or, "or ", 0x48, 0x63>;
|
||||
defm XOR : BinaryInt<xor, "xor ", 0x49, 0x64>;
|
||||
} // isCommutable = 1
|
||||
defm SHL : BinaryInt<shl, "shl ">;
|
||||
defm SHR_U : BinaryInt<srl, "shr_u">;
|
||||
defm SHR_S : BinaryInt<sra, "shr_s">;
|
||||
defm ROTL : BinaryInt<rotl, "rotl">;
|
||||
defm ROTR : BinaryInt<rotr, "rotr">;
|
||||
defm SHL : BinaryInt<shl, "shl ", 0x4a, 0x65>;
|
||||
defm SHR_U : BinaryInt<srl, "shr_u", 0x4b, 0x66>;
|
||||
defm SHR_S : BinaryInt<sra, "shr_s", 0x4c, 0x67>;
|
||||
defm ROTL : BinaryInt<rotl, "rotl", 0xb7, 0xb9>;
|
||||
defm ROTR : BinaryInt<rotr, "rotr", 0xb6, 0xb8>;
|
||||
|
||||
let isCommutable = 1 in {
|
||||
defm EQ : ComparisonInt<SETEQ, "eq ">;
|
||||
defm NE : ComparisonInt<SETNE, "ne ">;
|
||||
defm EQ : ComparisonInt<SETEQ, "eq ", 0x4d, 0x68>;
|
||||
defm NE : ComparisonInt<SETNE, "ne ", 0x4e, 0x69>;
|
||||
} // isCommutable = 1
|
||||
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 LT_S : ComparisonInt<SETLT, "lt_s", 0x4f, 0x6a>;
|
||||
defm LE_S : ComparisonInt<SETLE, "le_s", 0x50, 0x6b>;
|
||||
defm LT_U : ComparisonInt<SETULT, "lt_u", 0x51, 0x6c>;
|
||||
defm LE_U : ComparisonInt<SETULE, "le_u", 0x52, 0x6d>;
|
||||
defm GT_S : ComparisonInt<SETGT, "gt_s", 0x53, 0x6e>;
|
||||
defm GE_S : ComparisonInt<SETGE, "ge_s", 0x54, 0x6f>;
|
||||
defm GT_U : ComparisonInt<SETUGT, "gt_u", 0x55, 0x70>;
|
||||
defm GE_U : ComparisonInt<SETUGE, "ge_u", 0x56, 0x71>;
|
||||
|
||||
defm CLZ : UnaryInt<ctlz, "clz ">;
|
||||
defm CTZ : UnaryInt<cttz, "ctz ">;
|
||||
defm POPCNT : UnaryInt<ctpop, "popcnt">;
|
||||
defm CLZ : UnaryInt<ctlz, "clz ", 0x57, 0x72>;
|
||||
defm CTZ : UnaryInt<cttz, "ctz ", 0x58, 0x73>;
|
||||
defm POPCNT : UnaryInt<ctpop, "popcnt", 0x59, 0x74>;
|
||||
|
||||
def EQZ_I32 : I<(outs I32:$dst), (ins I32:$src),
|
||||
[(set I32:$dst, (setcc I32:$src, 0, SETEQ))],
|
||||
"i32.eqz \t$dst, $src">;
|
||||
"i32.eqz \t$dst, $src", 0x5a>;
|
||||
def EQZ_I64 : I<(outs I32:$dst), (ins I64:$src),
|
||||
[(set I32:$dst, (setcc I64:$src, 0, SETEQ))],
|
||||
"i64.eqz \t$dst, $src">;
|
||||
"i64.eqz \t$dst, $src", 0xba>;
|
||||
|
||||
} // Defs = [ARGUMENTS]
|
||||
|
||||
|
@ -58,16 +58,16 @@ let Defs = [ARGUMENTS] in {
|
||||
// Basic load.
|
||||
def LOAD_I32 : I<(outs I32:$dst), (ins i32imm:$off, I32:$addr,
|
||||
P2Align:$p2align), [],
|
||||
"i32.load\t$dst, ${off}(${addr})${p2align}">;
|
||||
"i32.load\t$dst, ${off}(${addr})${p2align}", 0x2a>;
|
||||
def LOAD_I64 : I<(outs I64:$dst), (ins i32imm:$off, I32:$addr,
|
||||
P2Align:$p2align), [],
|
||||
"i64.load\t$dst, ${off}(${addr})${p2align}">;
|
||||
"i64.load\t$dst, ${off}(${addr})${p2align}", 0x2b>;
|
||||
def LOAD_F32 : I<(outs F32:$dst), (ins i32imm:$off, I32:$addr,
|
||||
P2Align:$p2align), [],
|
||||
"f32.load\t$dst, ${off}(${addr})${p2align}">;
|
||||
"f32.load\t$dst, ${off}(${addr})${p2align}", 0x2c>;
|
||||
def LOAD_F64 : I<(outs F64:$dst), (ins i32imm:$off, I32:$addr,
|
||||
P2Align:$p2align), [],
|
||||
"f64.load\t$dst, ${off}(${addr})${p2align}">;
|
||||
"f64.load\t$dst, ${off}(${addr})${p2align}", 0x2d>;
|
||||
|
||||
} // Defs = [ARGUMENTS]
|
||||
|
||||
@ -142,34 +142,34 @@ let Defs = [ARGUMENTS] in {
|
||||
// Extending load.
|
||||
def LOAD8_S_I32 : I<(outs I32:$dst), (ins i32imm:$off, I32:$addr,
|
||||
P2Align:$p2align), [],
|
||||
"i32.load8_s\t$dst, ${off}(${addr})${p2align}">;
|
||||
"i32.load8_s\t$dst, ${off}(${addr})${p2align}", 0x20>;
|
||||
def LOAD8_U_I32 : I<(outs I32:$dst), (ins i32imm:$off, I32:$addr,
|
||||
P2Align:$p2align), [],
|
||||
"i32.load8_u\t$dst, ${off}(${addr})${p2align}">;
|
||||
"i32.load8_u\t$dst, ${off}(${addr})${p2align}", 0x21>;
|
||||
def LOAD16_S_I32 : I<(outs I32:$dst), (ins i32imm:$off, I32:$addr,
|
||||
P2Align:$p2align), [],
|
||||
"i32.load16_s\t$dst, ${off}(${addr})${p2align}">;
|
||||
"i32.load16_s\t$dst, ${off}(${addr})${p2align}", 0x22>;
|
||||
def LOAD16_U_I32 : I<(outs I32:$dst), (ins i32imm:$off, I32:$addr,
|
||||
P2Align:$p2align), [],
|
||||
"i32.load16_u\t$dst, ${off}(${addr})${p2align}">;
|
||||
"i32.load16_u\t$dst, ${off}(${addr})${p2align}", 0x23>;
|
||||
def LOAD8_S_I64 : I<(outs I64:$dst), (ins i32imm:$off, I32:$addr,
|
||||
P2Align:$p2align), [],
|
||||
"i64.load8_s\t$dst, ${off}(${addr})${p2align}">;
|
||||
"i64.load8_s\t$dst, ${off}(${addr})${p2align}", 0x24>;
|
||||
def LOAD8_U_I64 : I<(outs I64:$dst), (ins i32imm:$off, I32:$addr,
|
||||
P2Align:$p2align), [],
|
||||
"i64.load8_u\t$dst, ${off}(${addr})${p2align}">;
|
||||
"i64.load8_u\t$dst, ${off}(${addr})${p2align}", 0x25>;
|
||||
def LOAD16_S_I64 : I<(outs I64:$dst), (ins i32imm:$off, I32:$addr,
|
||||
P2Align:$p2align), [],
|
||||
"i64.load16_s\t$dst, ${off}(${addr})${p2align}">;
|
||||
"i64.load16_s\t$dst, ${off}(${addr})${p2align}", 0x26>;
|
||||
def LOAD16_U_I64 : I<(outs I64:$dst), (ins i32imm:$off, I32:$addr,
|
||||
P2Align:$p2align), [],
|
||||
"i64.load16_u\t$dst, ${off}(${addr})${p2align}">;
|
||||
"i64.load16_u\t$dst, ${off}(${addr})${p2align}", 0x27>;
|
||||
def LOAD32_S_I64 : I<(outs I64:$dst), (ins i32imm:$off, I32:$addr,
|
||||
P2Align:$p2align), [],
|
||||
"i64.load32_s\t$dst, ${off}(${addr})${p2align}">;
|
||||
"i64.load32_s\t$dst, ${off}(${addr})${p2align}", 0x28>;
|
||||
def LOAD32_U_I64 : I<(outs I64:$dst), (ins i32imm:$off, I32:$addr,
|
||||
P2Align:$p2align), [],
|
||||
"i64.load32_u\t$dst, ${off}(${addr})${p2align}">;
|
||||
"i64.load32_u\t$dst, ${off}(${addr})${p2align}", 0x29>;
|
||||
|
||||
} // Defs = [ARGUMENTS]
|
||||
|
||||
@ -453,16 +453,16 @@ let Defs = [ARGUMENTS] in {
|
||||
// Note: WebAssembly inverts SelectionDAG's usual operand order.
|
||||
def STORE_I32 : I<(outs I32:$dst), (ins i32imm:$off, I32:$addr,
|
||||
P2Align:$p2align, I32:$val), [],
|
||||
"i32.store\t$dst, ${off}(${addr})${p2align}, $val">;
|
||||
"i32.store\t$dst, ${off}(${addr})${p2align}, $val", 0x33>;
|
||||
def STORE_I64 : I<(outs I64:$dst), (ins i32imm:$off, I32:$addr,
|
||||
P2Align:$p2align, I64:$val), [],
|
||||
"i64.store\t$dst, ${off}(${addr})${p2align}, $val">;
|
||||
"i64.store\t$dst, ${off}(${addr})${p2align}, $val", 0x34>;
|
||||
def STORE_F32 : I<(outs F32:$dst), (ins i32imm:$off, I32:$addr,
|
||||
P2Align:$p2align, F32:$val), [],
|
||||
"f32.store\t$dst, ${off}(${addr})${p2align}, $val">;
|
||||
"f32.store\t$dst, ${off}(${addr})${p2align}, $val", 0x35>;
|
||||
def STORE_F64 : I<(outs F64:$dst), (ins i32imm:$off, I32:$addr,
|
||||
P2Align:$p2align, F64:$val), [],
|
||||
"f64.store\t$dst, ${off}(${addr})${p2align}, $val">;
|
||||
"f64.store\t$dst, ${off}(${addr})${p2align}, $val", 0x36>;
|
||||
|
||||
} // Defs = [ARGUMENTS]
|
||||
|
||||
@ -545,19 +545,19 @@ let Defs = [ARGUMENTS] in {
|
||||
// Truncating store.
|
||||
def STORE8_I32 : I<(outs I32:$dst), (ins i32imm:$off, I32:$addr,
|
||||
P2Align:$p2align, I32:$val), [],
|
||||
"i32.store8\t$dst, ${off}(${addr})${p2align}, $val">;
|
||||
"i32.store8\t$dst, ${off}(${addr})${p2align}, $val", 0x2e>;
|
||||
def STORE16_I32 : I<(outs I32:$dst), (ins i32imm:$off, I32:$addr,
|
||||
P2Align:$p2align, I32:$val), [],
|
||||
"i32.store16\t$dst, ${off}(${addr})${p2align}, $val">;
|
||||
"i32.store16\t$dst, ${off}(${addr})${p2align}, $val", 0x2f>;
|
||||
def STORE8_I64 : I<(outs I64:$dst), (ins i32imm:$off, I32:$addr,
|
||||
P2Align:$p2align, I64:$val), [],
|
||||
"i64.store8\t$dst, ${off}(${addr})${p2align}, $val">;
|
||||
"i64.store8\t$dst, ${off}(${addr})${p2align}, $val", 0x30>;
|
||||
def STORE16_I64 : I<(outs I64:$dst), (ins i32imm:$off, I32:$addr,
|
||||
P2Align:$p2align, I64:$val), [],
|
||||
"i64.store16\t$dst, ${off}(${addr})${p2align}, $val">;
|
||||
"i64.store16\t$dst, ${off}(${addr})${p2align}, $val", 0x31>;
|
||||
def STORE32_I64 : I<(outs I64:$dst), (ins i32imm:$off, I32:$addr,
|
||||
P2Align:$p2align, I64:$val), [],
|
||||
"i64.store32\t$dst, ${off}(${addr})${p2align}, $val">;
|
||||
"i64.store32\t$dst, ${off}(${addr})${p2align}, $val", 0x32>;
|
||||
|
||||
} // Defs = [ARGUMENTS]
|
||||
|
||||
@ -671,7 +671,7 @@ let Defs = [ARGUMENTS] in {
|
||||
// Current memory size.
|
||||
def CURRENT_MEMORY_I32 : I<(outs I32:$dst), (ins),
|
||||
[(set I32:$dst, (int_wasm_current_memory))],
|
||||
"current_memory\t$dst">,
|
||||
"current_memory\t$dst", 0x3b>,
|
||||
Requires<[HasAddr32]>;
|
||||
def CURRENT_MEMORY_I64 : I<(outs I64:$dst), (ins),
|
||||
[(set I64:$dst, (int_wasm_current_memory))],
|
||||
@ -681,7 +681,7 @@ def CURRENT_MEMORY_I64 : I<(outs I64:$dst), (ins),
|
||||
// Grow memory.
|
||||
def GROW_MEMORY_I32 : I<(outs), (ins I32:$delta),
|
||||
[(int_wasm_grow_memory I32:$delta)],
|
||||
"grow_memory\t$delta">,
|
||||
"grow_memory\t$delta", 0x39>,
|
||||
Requires<[HasAddr32]>;
|
||||
def GROW_MEMORY_I64 : I<(outs), (ins I64:$delta),
|
||||
[(int_wasm_grow_memory I64:$delta)],
|
||||
|
Loading…
Reference in New Issue
Block a user