[WebAssembly][NFC] Remove repetition of Defs = [ARGUMENTS] (fixed)
llvm-svn: 344287
This commit is contained in:
parent
000dbbca39
commit
f04bed8e79
|
@ -24,10 +24,8 @@ multiclass ATOMIC_I<dag oops_r, dag iops_r, dag oops_s, dag iops_s,
|
|||
Requires<[HasAtomics]>;
|
||||
}
|
||||
|
||||
let Defs = [ARGUMENTS] in {
|
||||
defm ATOMIC_LOAD_I32 : WebAssemblyLoad<I32, "i32.atomic.load", 0xfe10>;
|
||||
defm ATOMIC_LOAD_I64 : WebAssemblyLoad<I64, "i64.atomic.load", 0xfe11>;
|
||||
} // Defs = [ARGUMENTS]
|
||||
|
||||
// Select loads with no constant offset.
|
||||
let Predicates = [HasAtomics] in {
|
||||
|
@ -62,13 +60,11 @@ def : LoadPatExternSymOffOnly<i64, atomic_load_64, ATOMIC_LOAD_I64>;
|
|||
|
||||
// Extending loads. Note that there are only zero-extending atomic loads, no
|
||||
// sign-extending loads.
|
||||
let Defs = [ARGUMENTS] in {
|
||||
defm ATOMIC_LOAD8_U_I32 : WebAssemblyLoad<I32, "i32.atomic.load8_u", 0xfe12>;
|
||||
defm ATOMIC_LOAD16_U_I32 : WebAssemblyLoad<I32, "i32.atomic.load16_u", 0xfe13>;
|
||||
defm ATOMIC_LOAD8_U_I64 : WebAssemblyLoad<I64, "i64.atomic.load8_u", 0xfe14>;
|
||||
defm ATOMIC_LOAD16_U_I64 : WebAssemblyLoad<I64, "i64.atomic.load16_u", 0xfe15>;
|
||||
defm ATOMIC_LOAD32_U_I64 : WebAssemblyLoad<I64, "i64.atomic.load32_u", 0xfe16>;
|
||||
} // Defs = [ARGUMENTS]
|
||||
|
||||
// Fragments for extending loads. These are different from regular loads because
|
||||
// the SDNodes are derived from AtomicSDNode rather than LoadSDNode and
|
||||
|
@ -200,10 +196,8 @@ def : LoadPatExternSymOffOnly<i64, sext_aload_16_64, ATOMIC_LOAD16_U_I64>;
|
|||
// Atomic stores
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
let Defs = [ARGUMENTS] in {
|
||||
defm ATOMIC_STORE_I32 : WebAssemblyStore<I32, "i32.atomic.store", 0xfe17>;
|
||||
defm ATOMIC_STORE_I64 : WebAssemblyStore<I64, "i64.atomic.store", 0xfe18>;
|
||||
} // Defs = [ARGUMENTS]
|
||||
|
||||
// We need an 'atomic' version of store patterns because store and atomic_store
|
||||
// nodes have different operand orders:
|
||||
|
@ -263,13 +257,11 @@ def : AStorePatExternSymOffOnly<i64, atomic_store_64, ATOMIC_STORE_I64>;
|
|||
} // Predicates = [HasAtomics]
|
||||
|
||||
// Truncating stores.
|
||||
let Defs = [ARGUMENTS] in {
|
||||
defm ATOMIC_STORE8_I32 : WebAssemblyStore<I32, "i32.atomic.store8", 0xfe19>;
|
||||
defm ATOMIC_STORE16_I32 : WebAssemblyStore<I32, "i32.atomic.store16", 0xfe1a>;
|
||||
defm ATOMIC_STORE8_I64 : WebAssemblyStore<I64, "i64.atomic.store8", 0xfe1b>;
|
||||
defm ATOMIC_STORE16_I64 : WebAssemblyStore<I64, "i64.atomic.store16", 0xfe1c>;
|
||||
defm ATOMIC_STORE32_I64 : WebAssemblyStore<I64, "i64.atomic.store32", 0xfe1d>;
|
||||
} // Defs = [ARGUMENTS]
|
||||
|
||||
// Fragments for truncating stores.
|
||||
|
||||
|
@ -341,8 +333,6 @@ def : AStorePatExternSymOffOnly<i64, trunc_astore_32_64, ATOMIC_STORE32_I64>;
|
|||
// Atomic binary read-modify-writes
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
let Defs = [ARGUMENTS] in {
|
||||
|
||||
multiclass WebAssemblyBinRMW<WebAssemblyRegClass rc, string Name, int Opcode> {
|
||||
defm "" : I<(outs rc:$dst),
|
||||
(ins P2Align:$p2align, offset32_op:$off, I32:$addr, rc:$val),
|
||||
|
@ -430,7 +420,6 @@ defm ATOMIC_RMW16_U_XCHG_I64 :
|
|||
WebAssemblyBinRMW<I64, "i64.atomic.rmw16_u.xchg", 0xfe46>;
|
||||
defm ATOMIC_RMW32_U_XCHG_I64 :
|
||||
WebAssemblyBinRMW<I64, "i64.atomic.rmw32_u.xchg", 0xfe47>;
|
||||
}
|
||||
|
||||
// Select binary RMWs with no constant offset.
|
||||
class BinRMWPatNoOffset<ValueType ty, PatFrag kind, NI inst> :
|
||||
|
@ -674,8 +663,6 @@ defm : BinRMWTruncExtPattern<
|
|||
// Consider adding a pass after instruction selection that optimizes this case
|
||||
// if it is frequent.
|
||||
|
||||
let Defs = [ARGUMENTS] in {
|
||||
|
||||
multiclass WebAssemblyTerRMW<WebAssemblyRegClass rc, string Name, int Opcode> {
|
||||
defm "" : I<(outs rc:$dst),
|
||||
(ins P2Align:$p2align, offset32_op:$off, I32:$addr, rc:$exp,
|
||||
|
@ -699,7 +686,6 @@ defm ATOMIC_RMW16_U_CMPXCHG_I64 :
|
|||
WebAssemblyTerRMW<I64, "i64.atomic.rmw16_u.cmpxchg", 0xfe4d>;
|
||||
defm ATOMIC_RMW32_U_CMPXCHG_I64 :
|
||||
WebAssemblyTerRMW<I64, "i64.atomic.rmw32_u.cmpxchg", 0xfe4e>;
|
||||
}
|
||||
|
||||
// Select ternary RMWs with no constant offset.
|
||||
class TerRMWPatNoOffset<ValueType ty, PatFrag kind, NI inst> :
|
||||
|
@ -912,7 +898,6 @@ defm : TerRMWTruncExtPattern<
|
|||
// Atomic wait / notify
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
let Defs = [ARGUMENTS] in {
|
||||
let hasSideEffects = 1 in {
|
||||
defm ATOMIC_NOTIFY :
|
||||
I<(outs I32:$dst),
|
||||
|
@ -935,7 +920,6 @@ defm ATOMIC_WAIT_I64 :
|
|||
"i64.atomic.wait \t${off}, ${p2align}", 0xfe02>;
|
||||
} // mayLoad = 1
|
||||
} // hasSideEffects = 1
|
||||
} // Defs = [ARGUMENTS]
|
||||
|
||||
let Predicates = [HasAtomics] in {
|
||||
// Select notifys with no constant offset.
|
||||
|
|
|
@ -15,8 +15,6 @@
|
|||
// TODO: addr64: These currently assume the callee address is 32-bit.
|
||||
// FIXME: add $type to first call_indirect asmstr (and maybe $flags)
|
||||
|
||||
let Defs = [ARGUMENTS] in {
|
||||
|
||||
// Call sequence markers. These have an immediate which represents the amount of
|
||||
// stack space to allocate or free, which is used for varargs lowering.
|
||||
let Uses = [SP32, SP64], Defs = [SP32, SP64], isCodeGenOnly = 1 in {
|
||||
|
@ -118,8 +116,6 @@ let Uses = [SP32, SP64], isCall = 1 in {
|
|||
0x11>;
|
||||
} // Uses = [SP32,SP64], isCall = 1
|
||||
|
||||
} // Defs = [ARGUMENTS]
|
||||
|
||||
// Patterns for matching a direct call to a global address.
|
||||
def : Pat<(i32 (WebAssemblycall1 (WebAssemblywrapper tglobaladdr:$callee))),
|
||||
(CALL_I32 tglobaladdr:$callee)>;
|
||||
|
|
|
@ -12,8 +12,6 @@
|
|||
///
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
let Defs = [ARGUMENTS] in {
|
||||
|
||||
let isBranch = 1, isTerminator = 1, hasCtrlDep = 1 in {
|
||||
// The condition operand is a boolean value which WebAssembly represents as i32.
|
||||
defm BR_IF : I<(outs), (ins bb_op:$dst, I32:$cond),
|
||||
|
@ -30,15 +28,11 @@ defm BR : NRI<(outs), (ins bb_op:$dst),
|
|||
} // isBarrier = 1
|
||||
} // isBranch = 1, isTerminator = 1, hasCtrlDep = 1
|
||||
|
||||
} // Defs = [ARGUMENTS]
|
||||
|
||||
def : Pat<(brcond (i32 (setne I32:$cond, 0)), bb:$dst),
|
||||
(BR_IF bb_op:$dst, I32:$cond)>;
|
||||
def : Pat<(brcond (i32 (seteq I32:$cond, 0)), bb:$dst),
|
||||
(BR_UNLESS bb_op:$dst, I32:$cond)>;
|
||||
|
||||
let Defs = [ARGUMENTS] in {
|
||||
|
||||
// TODO: SelectionDAG's lowering insists on using a pointer as the index for
|
||||
// jump tables, so in practice we don't ever use BR_TABLE_I64 in wasm32 mode
|
||||
// currently.
|
||||
|
@ -194,5 +188,3 @@ let isTerminator = 1, hasSideEffects = 1, isBarrier = 1, hasCtrlDep = 1,
|
|||
[(catchret bb:$dst, bb:$from)], "", 0>;
|
||||
}
|
||||
}
|
||||
|
||||
} // Defs = [ARGUMENTS]
|
||||
|
|
|
@ -13,8 +13,6 @@
|
|||
///
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
let Defs = [ARGUMENTS] in {
|
||||
|
||||
defm I32_WRAP_I64 : I<(outs I32:$dst), (ins I64:$src), (outs), (ins),
|
||||
[(set I32:$dst, (trunc I64:$src))],
|
||||
"i32.wrap/i64\t$dst, $src", "i32.wrap/i64", 0xa7>;
|
||||
|
@ -51,15 +49,11 @@ defm I64_EXTEND32_S_I64 : I<(outs I64:$dst), (ins I64:$src), (outs), (ins),
|
|||
0xc4>;
|
||||
} // Predicates = [HasSignExt]
|
||||
|
||||
} // defs = [ARGUMENTS]
|
||||
|
||||
// Expand a "don't care" extend into zero-extend (chosen over sign-extend
|
||||
// somewhat arbitrarily, although it favors popular hardware architectures
|
||||
// and is conceptually a simpler operation).
|
||||
def : Pat<(i64 (anyext I32:$src)), (I64_EXTEND_U_I32 I32:$src)>;
|
||||
|
||||
let Defs = [ARGUMENTS] in {
|
||||
|
||||
// Conversion from floating point to integer instructions which don't trap on
|
||||
// overflow or invalid.
|
||||
defm I32_TRUNC_S_SAT_F32 : I<(outs I32:$dst), (ins F32:$src), (outs), (ins),
|
||||
|
@ -103,8 +97,6 @@ defm I64_TRUNC_U_SAT_F64 : I<(outs I64:$dst), (ins F64:$src), (outs), (ins),
|
|||
"i64.trunc_u:sat/f64", 0xfc07>,
|
||||
Requires<[HasNontrappingFPToInt]>;
|
||||
|
||||
} // Defs = [Arguments]
|
||||
|
||||
// Lower llvm.wasm.trunc.saturate.* to saturating instructions
|
||||
def : Pat<(int_wasm_trunc_saturate_signed F32:$src),
|
||||
(I32_TRUNC_S_SAT_F32 F32:$src)>;
|
||||
|
@ -123,8 +115,6 @@ def : Pat<(int_wasm_trunc_saturate_signed F64:$src),
|
|||
def : Pat<(int_wasm_trunc_saturate_unsigned F64:$src),
|
||||
(I64_TRUNC_U_SAT_F64 F64:$src)>;
|
||||
|
||||
let Defs = [ARGUMENTS] in {
|
||||
|
||||
// Conversion from floating point to integer pseudo-instructions which don't
|
||||
// trap on overflow or invalid.
|
||||
let usesCustomInserter = 1, isCodeGenOnly = 1 in {
|
||||
|
@ -240,5 +230,3 @@ defm F64_REINTERPRET_I64 : I<(outs F64:$dst), (ins I64:$src), (outs), (ins),
|
|||
[(set F64:$dst, (bitconvert I64:$src))],
|
||||
"f64.reinterpret/i64\t$dst, $src",
|
||||
"f64.reinterpret/i64", 0xbf>;
|
||||
|
||||
} // Defs = [ARGUMENTS]
|
||||
|
|
|
@ -12,8 +12,6 @@
|
|||
///
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
let Defs = [ARGUMENTS] in {
|
||||
|
||||
defm SELECT_EXCEPT_REF : I<(outs EXCEPT_REF:$dst),
|
||||
(ins EXCEPT_REF:$lhs, EXCEPT_REF:$rhs, I32:$cond),
|
||||
(outs), (ins),
|
||||
|
@ -23,8 +21,6 @@ defm SELECT_EXCEPT_REF : I<(outs EXCEPT_REF:$dst),
|
|||
"except_ref.select\t$dst, $lhs, $rhs, $cond",
|
||||
"except_ref.select", 0x1b>;
|
||||
|
||||
} // Defs = [ARGUMENTS]
|
||||
|
||||
def : Pat<(select (i32 (setne I32:$cond, 0)), EXCEPT_REF:$lhs, EXCEPT_REF:$rhs),
|
||||
(SELECT_EXCEPT_REF EXCEPT_REF:$lhs, EXCEPT_REF:$rhs, I32:$cond)>;
|
||||
def : Pat<(select (i32 (seteq I32:$cond, 0)), EXCEPT_REF:$lhs, EXCEPT_REF:$rhs),
|
||||
|
|
|
@ -45,8 +45,6 @@ multiclass ComparisonFP<CondCode cond, string name, bits<32> f32Inst, bits<32> f
|
|||
!strconcat("f64.", name), f64Inst>;
|
||||
}
|
||||
|
||||
let Defs = [ARGUMENTS] in {
|
||||
|
||||
let isCommutable = 1 in
|
||||
defm ADD : BinaryFP<fadd, "add ", 0x92, 0xa0>;
|
||||
defm SUB : BinaryFP<fsub, "sub ", 0x93, 0xa1>;
|
||||
|
@ -69,8 +67,6 @@ defm FLOOR : UnaryFP<ffloor, "floor", 0x8e, 0x9c>;
|
|||
defm TRUNC : UnaryFP<ftrunc, "trunc", 0x8f, 0x9d>;
|
||||
defm NEAREST : UnaryFP<fnearbyint, "nearest", 0x90, 0x9e>;
|
||||
|
||||
} // Defs = [ARGUMENTS]
|
||||
|
||||
// DAGCombine oddly folds casts into the rhs of copysign. Unfold them.
|
||||
def : Pat<(fcopysign F64:$lhs, F32:$rhs),
|
||||
(COPYSIGN_F64 F64:$lhs, (F64_PROMOTE_F32 F32:$rhs))>;
|
||||
|
@ -81,8 +77,6 @@ def : Pat<(fcopysign F32:$lhs, F64:$rhs),
|
|||
def : Pat<(frint f32:$src), (NEAREST_F32 f32:$src)>;
|
||||
def : Pat<(frint f64:$src), (NEAREST_F64 f64:$src)>;
|
||||
|
||||
let Defs = [ARGUMENTS] in {
|
||||
|
||||
let isCommutable = 1 in {
|
||||
defm EQ : ComparisonFP<SETOEQ, "eq ", 0x5b, 0x61>;
|
||||
defm NE : ComparisonFP<SETUNE, "ne ", 0x5c, 0x62>;
|
||||
|
@ -92,8 +86,6 @@ defm LE : ComparisonFP<SETOLE, "le ", 0x5f, 0x65>;
|
|||
defm GT : ComparisonFP<SETOGT, "gt ", 0x5e, 0x64>;
|
||||
defm GE : ComparisonFP<SETOGE, "ge ", 0x60, 0x66>;
|
||||
|
||||
} // Defs = [ARGUMENTS]
|
||||
|
||||
// Don't care floating-point comparisons, supported via other comparisons.
|
||||
def : Pat<(seteq f32:$lhs, f32:$rhs), (EQ_F32 f32:$lhs, f32:$rhs)>;
|
||||
def : Pat<(setne f32:$lhs, f32:$rhs), (NE_F32 f32:$lhs, f32:$rhs)>;
|
||||
|
@ -108,8 +100,6 @@ def : Pat<(setle f64:$lhs, f64:$rhs), (LE_F64 f64:$lhs, f64:$rhs)>;
|
|||
def : Pat<(setgt f64:$lhs, f64:$rhs), (GT_F64 f64:$lhs, f64:$rhs)>;
|
||||
def : Pat<(setge f64:$lhs, f64:$rhs), (GE_F64 f64:$lhs, f64:$rhs)>;
|
||||
|
||||
let Defs = [ARGUMENTS] in {
|
||||
|
||||
defm SELECT_F32 : I<(outs F32:$dst), (ins F32:$lhs, F32:$rhs, I32:$cond),
|
||||
(outs), (ins),
|
||||
[(set F32:$dst, (select I32:$cond, F32:$lhs, F32:$rhs))],
|
||||
|
@ -119,8 +109,6 @@ defm SELECT_F64 : I<(outs F64:$dst), (ins F64:$lhs, F64:$rhs, I32:$cond),
|
|||
[(set F64:$dst, (select I32:$cond, F64:$lhs, F64:$rhs))],
|
||||
"f64.select\t$dst, $lhs, $rhs, $cond", "f64.select", 0x1b>;
|
||||
|
||||
} // Defs = [ARGUMENTS]
|
||||
|
||||
// ISD::SELECT requires its operand to conform to getBooleanContents, but
|
||||
// WebAssembly's select interprets any non-zero value as true, so we can fold
|
||||
// a setne with 0 into a select.
|
||||
|
|
|
@ -30,6 +30,7 @@ class NI<dag oops, dag iops, list<dag> pattern, bit stack, string asmstr = "",
|
|||
dag OutOperandList = oops;
|
||||
dag InOperandList = iops;
|
||||
let Pattern = pattern;
|
||||
let Defs = [ARGUMENTS];
|
||||
}
|
||||
|
||||
// Generates both register and stack based versions of one actual instruction.
|
||||
|
|
|
@ -164,7 +164,8 @@ include "WebAssemblyInstrFormats.td"
|
|||
//===----------------------------------------------------------------------===//
|
||||
|
||||
multiclass ARGUMENT<WebAssemblyRegClass vt> {
|
||||
let hasSideEffects = 1, Uses = [ARGUMENTS], isCodeGenOnly = 1 in
|
||||
let hasSideEffects = 1, isCodeGenOnly = 1,
|
||||
Defs = []<Register>, Uses = [ARGUMENTS] in
|
||||
defm ARGUMENT_#vt : I<(outs vt:$res), (ins i32imm:$argno),
|
||||
(outs), (ins i32imm:$argno),
|
||||
[(set vt:$res, (WebAssemblyargument timm:$argno))]>;
|
||||
|
@ -175,8 +176,6 @@ defm "": ARGUMENT<F32>;
|
|||
defm "": ARGUMENT<F64>;
|
||||
defm "": ARGUMENT<EXCEPT_REF>;
|
||||
|
||||
let Defs = [ARGUMENTS] in {
|
||||
|
||||
// get_local and set_local are not generated by instruction selection; they
|
||||
// are implied by virtual register uses and defs.
|
||||
multiclass LOCAL<WebAssemblyRegClass vt> {
|
||||
|
@ -266,8 +265,6 @@ defm CONST_F64 : I<(outs F64:$res), (ins f64imm_op:$imm),
|
|||
"f64.const\t$res, $imm", "f64.const\t$imm", 0x44>;
|
||||
} // isMoveImm = 1, isAsCheapAsAMove = 1, isReMaterializable = 1
|
||||
|
||||
} // Defs = [ARGUMENTS]
|
||||
|
||||
def : Pat<(i32 (WebAssemblywrapper tglobaladdr:$addr)),
|
||||
(CONST_I32 tglobaladdr:$addr)>;
|
||||
def : Pat<(i32 (WebAssemblywrapper texternalsym:$addr)),
|
||||
|
|
|
@ -45,9 +45,6 @@ multiclass ComparisonInt<CondCode cond, string name, bits<32> i32Inst, bits<32>
|
|||
!strconcat("i64.", name), i64Inst>;
|
||||
}
|
||||
|
||||
|
||||
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
|
||||
|
@ -97,16 +94,12 @@ defm EQZ_I64 : I<(outs I32:$dst), (ins I64:$src), (outs), (ins),
|
|||
[(set I32:$dst, (setcc I64:$src, 0, SETEQ))],
|
||||
"i64.eqz \t$dst, $src", "i64.eqz", 0x50>;
|
||||
|
||||
} // Defs = [ARGUMENTS]
|
||||
|
||||
// Optimize away an explicit mask on a rotate count.
|
||||
def : Pat<(rotl I32:$lhs, (and I32:$rhs, 31)), (ROTL_I32 I32:$lhs, I32:$rhs)>;
|
||||
def : Pat<(rotr I32:$lhs, (and I32:$rhs, 31)), (ROTR_I32 I32:$lhs, I32:$rhs)>;
|
||||
def : Pat<(rotl I64:$lhs, (and I64:$rhs, 63)), (ROTL_I64 I64:$lhs, I64:$rhs)>;
|
||||
def : Pat<(rotr I64:$lhs, (and I64:$rhs, 63)), (ROTR_I64 I64:$lhs, I64:$rhs)>;
|
||||
|
||||
let Defs = [ARGUMENTS] in {
|
||||
|
||||
defm SELECT_I32 : I<(outs I32:$dst), (ins I32:$lhs, I32:$rhs, I32:$cond),
|
||||
(outs), (ins),
|
||||
[(set I32:$dst, (select I32:$cond, I32:$lhs, I32:$rhs))],
|
||||
|
@ -116,8 +109,6 @@ defm SELECT_I64 : I<(outs I64:$dst), (ins I64:$lhs, I64:$rhs, I32:$cond),
|
|||
[(set I64:$dst, (select I32:$cond, I64:$lhs, I64:$rhs))],
|
||||
"i64.select\t$dst, $lhs, $rhs, $cond", "i64.select", 0x1b>;
|
||||
|
||||
} // Defs = [ARGUMENTS]
|
||||
|
||||
// ISD::SELECT requires its operand to conform to getBooleanContents, but
|
||||
// WebAssembly's select interprets any non-zero value as true, so we can fold
|
||||
// a setne with 0 into a select.
|
||||
|
|
|
@ -53,8 +53,6 @@ def regPlusGA : PatFrag<(ops node:$addr, node:$off),
|
|||
// We don't need a regPlusES because external symbols never have constant
|
||||
// offsets folded into them, so we can just use add.
|
||||
|
||||
let Defs = [ARGUMENTS] in {
|
||||
|
||||
// Defines atomic and non-atomic loads, regular and extending.
|
||||
multiclass WebAssemblyLoad<WebAssemblyRegClass rc, string Name, int Opcode> {
|
||||
let mayLoad = 1 in
|
||||
|
@ -73,8 +71,6 @@ defm LOAD_I64 : WebAssemblyLoad<I64, "i64.load", 0x29>;
|
|||
defm LOAD_F32 : WebAssemblyLoad<F32, "f32.load", 0x2a>;
|
||||
defm LOAD_F64 : WebAssemblyLoad<F64, "f64.load", 0x2b>;
|
||||
|
||||
} // Defs = [ARGUMENTS]
|
||||
|
||||
// Select loads with no constant offset.
|
||||
class LoadPatNoOffset<ValueType ty, PatFrag kind, NI inst> :
|
||||
Pat<(ty (kind I32:$addr)), (inst 0, 0, I32:$addr)>;
|
||||
|
@ -144,8 +140,6 @@ def : LoadPatExternSymOffOnly<i64, load, LOAD_I64>;
|
|||
def : LoadPatExternSymOffOnly<f32, load, LOAD_F32>;
|
||||
def : LoadPatExternSymOffOnly<f64, load, LOAD_F64>;
|
||||
|
||||
let Defs = [ARGUMENTS] in {
|
||||
|
||||
// Extending load.
|
||||
defm LOAD8_S_I32 : WebAssemblyLoad<I32, "i32.load8_s", 0x2c>;
|
||||
defm LOAD8_U_I32 : WebAssemblyLoad<I32, "i32.load8_u", 0x2d>;
|
||||
|
@ -158,8 +152,6 @@ defm LOAD16_U_I64 : WebAssemblyLoad<I64, "i64.load16_u", 0x33>;
|
|||
defm LOAD32_S_I64 : WebAssemblyLoad<I64, "i64.load32_s", 0x34>;
|
||||
defm LOAD32_U_I64 : WebAssemblyLoad<I64, "i64.load32_u", 0x35>;
|
||||
|
||||
} // Defs = [ARGUMENTS]
|
||||
|
||||
// Select extending loads with no constant offset.
|
||||
def : LoadPatNoOffset<i32, sextloadi8, LOAD8_S_I32>;
|
||||
def : LoadPatNoOffset<i32, zextloadi8, LOAD8_U_I32>;
|
||||
|
@ -303,9 +295,6 @@ def : LoadPatExternSymOffOnly<i64, extloadi8, LOAD8_U_I64>;
|
|||
def : LoadPatExternSymOffOnly<i64, extloadi16, LOAD16_U_I64>;
|
||||
def : LoadPatExternSymOffOnly<i64, extloadi32, LOAD32_U_I64>;
|
||||
|
||||
|
||||
let Defs = [ARGUMENTS] in {
|
||||
|
||||
// Defines atomic and non-atomic stores, regular and truncating
|
||||
multiclass WebAssemblyStore<WebAssemblyRegClass rc, string Name, int Opcode> {
|
||||
let mayStore = 1 in
|
||||
|
@ -323,8 +312,6 @@ defm STORE_I64 : WebAssemblyStore<I64, "i64.store", 0x37>;
|
|||
defm STORE_F32 : WebAssemblyStore<F32, "f32.store", 0x38>;
|
||||
defm STORE_F64 : WebAssemblyStore<F64, "f64.store", 0x39>;
|
||||
|
||||
} // Defs = [ARGUMENTS]
|
||||
|
||||
// Select stores with no constant offset.
|
||||
class StorePatNoOffset<ValueType ty, PatFrag node, NI inst> :
|
||||
Pat<(node ty:$val, I32:$addr), (inst 0, 0, I32:$addr, ty:$val)>;
|
||||
|
@ -389,9 +376,6 @@ def : StorePatExternSymOffOnly<i64, store, STORE_I64>;
|
|||
def : StorePatExternSymOffOnly<f32, store, STORE_F32>;
|
||||
def : StorePatExternSymOffOnly<f64, store, STORE_F64>;
|
||||
|
||||
|
||||
let Defs = [ARGUMENTS] in {
|
||||
|
||||
// Truncating store.
|
||||
defm STORE8_I32 : WebAssemblyStore<I32, "i32.store8", 0x3a>;
|
||||
defm STORE16_I32 : WebAssemblyStore<I32, "i32.store16", 0x3b>;
|
||||
|
@ -399,8 +383,6 @@ defm STORE8_I64 : WebAssemblyStore<I64, "i64.store8", 0x3c>;
|
|||
defm STORE16_I64 : WebAssemblyStore<I64, "i64.store16", 0x3d>;
|
||||
defm STORE32_I64 : WebAssemblyStore<I64, "i64.store32", 0x3e>;
|
||||
|
||||
} // Defs = [ARGUMENTS]
|
||||
|
||||
// Select truncating stores with no constant offset.
|
||||
def : StorePatNoOffset<i32, truncstorei8, STORE8_I32>;
|
||||
def : StorePatNoOffset<i32, truncstorei16, STORE16_I32>;
|
||||
|
@ -448,8 +430,6 @@ def : StorePatExternSymOffOnly<i64, truncstorei8, STORE8_I64>;
|
|||
def : StorePatExternSymOffOnly<i64, truncstorei16, STORE16_I64>;
|
||||
def : StorePatExternSymOffOnly<i64, truncstorei32, STORE32_I64>;
|
||||
|
||||
let Defs = [ARGUMENTS] in {
|
||||
|
||||
// Current memory size.
|
||||
defm MEMORY_SIZE_I32 : I<(outs I32:$dst), (ins i32imm:$flags),
|
||||
(outs), (ins i32imm:$flags),
|
||||
|
@ -493,8 +473,6 @@ defm GROW_MEMORY_I32 : I<(outs I32:$dst), (ins i32imm:$flags, I32:$delta),
|
|||
0x40>,
|
||||
Requires<[HasAddr32]>;
|
||||
|
||||
} // Defs = [ARGUMENTS]
|
||||
|
||||
def : Pat<(int_wasm_current_memory),
|
||||
(CURRENT_MEMORY_I32 0)>;
|
||||
def : Pat<(int_wasm_grow_memory I32:$delta),
|
||||
|
|
|
@ -22,7 +22,8 @@ multiclass SIMD_I<dag oops_r, dag iops_r, dag oops_s, dag iops_s,
|
|||
}
|
||||
|
||||
multiclass SIMD_ARGUMENT<ValueType vt> {
|
||||
let hasSideEffects = 1, Uses = [ARGUMENTS], isCodeGenOnly = 1 in
|
||||
let hasSideEffects = 1, isCodeGenOnly = 1,
|
||||
Defs = []<Register>, Uses = [ARGUMENTS] in
|
||||
defm ARGUMENT_#vt : SIMD_I<(outs V128:$res), (ins i32imm:$argno),
|
||||
(outs), (ins i32imm:$argno),
|
||||
[(set (vt V128:$res),
|
||||
|
@ -55,7 +56,6 @@ multiclass ConstVec<ValueType vec_t, dag ops, dag pat, string args> {
|
|||
"v128.const\t"#args, 0>;
|
||||
}
|
||||
|
||||
let Defs = [ARGUMENTS] in {
|
||||
defm "" : ConstVec<v16i8,
|
||||
(ins vec_i8imm_op:$i0, vec_i8imm_op:$i1,
|
||||
vec_i8imm_op:$i2, vec_i8imm_op:$i3,
|
||||
|
@ -100,7 +100,6 @@ defm "" : ConstVec<v2f64,
|
|||
(ins f64imm_op:$i0, f64imm_op:$i1),
|
||||
(build_vector (f64 fpimm:$i0), (f64 fpimm:$i1)),
|
||||
"$i0, $i1">;
|
||||
} // Defs = [ARGUMENTS]
|
||||
|
||||
// Create vector with identical lanes: splat
|
||||
def splat2 : PatFrag<(ops node:$x), (build_vector node:$x, node:$x)>;
|
||||
|
|
Loading…
Reference in New Issue