[llvm] r334985 - [WebAssembly] Modified tablegen defs to have 2 parallel instuction sets.
Wouter van Oortmerssen via llvm-commits
llvm-commits at lists.llvm.org
Mon Jun 18 14:22:44 PDT 2018
Author: aardappel
Date: Mon Jun 18 14:22:44 2018
New Revision: 334985
URL: http://llvm.org/viewvc/llvm-project?rev=334985&view=rev
Log:
[WebAssembly] Modified tablegen defs to have 2 parallel instuction sets.
Summary:
One for register based, much like the existing definitions,
and one for stack based (suffix _S).
This allows us to use registers in most of LLVM (which works better),
and stack based in MC (which results in a simpler and more readable
assembler / disassembler).
Tried to keep this change as small as possible while passing tests,
follow-up commit will:
- Add reg->stack conversion in MI.
- Fix asm/disasm in MC to be stack based.
- Fix emitter to be stack based.
tests passing:
llvm-lit -v `find test -name WebAssembly`
test/CodeGen/WebAssembly
test/MC/WebAssembly
test/MC/Disassembler/WebAssembly
test/DebugInfo/WebAssembly
test/CodeGen/MIR/WebAssembly
test/tools/llvm-objdump/WebAssembly
Reviewers: dschuff, sbc100, jgravelle-google, sunfish
Subscribers: aheejin, JDevlieghere, llvm-commits
Differential Revision: https://reviews.llvm.org/D48183
Modified:
llvm/trunk/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h
llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrAtomics.td
llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrCall.td
llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrControl.td
llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrConv.td
llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrExceptRef.td
llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrFloat.td
llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrFormats.td
llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrInfo.td
llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrInteger.td
llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrMemory.td
llvm/trunk/test/MC/Disassembler/WebAssembly/wasm.txt
Modified: llvm/trunk/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h?rev=334985&r1=334984&r2=334985&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h (original)
+++ llvm/trunk/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h Mon Jun 18 14:22:44 2018
@@ -109,38 +109,68 @@ namespace WebAssembly {
inline unsigned GetDefaultP2Align(unsigned Opcode) {
switch (Opcode) {
case WebAssembly::LOAD8_S_I32:
+ case WebAssembly::LOAD8_S_I32_S:
case WebAssembly::LOAD8_U_I32:
+ case WebAssembly::LOAD8_U_I32_S:
case WebAssembly::LOAD8_S_I64:
+ case WebAssembly::LOAD8_S_I64_S:
case WebAssembly::LOAD8_U_I64:
+ case WebAssembly::LOAD8_U_I64_S:
case WebAssembly::ATOMIC_LOAD8_U_I32:
+ case WebAssembly::ATOMIC_LOAD8_U_I32_S:
case WebAssembly::ATOMIC_LOAD8_U_I64:
+ case WebAssembly::ATOMIC_LOAD8_U_I64_S:
case WebAssembly::STORE8_I32:
+ case WebAssembly::STORE8_I32_S:
case WebAssembly::STORE8_I64:
+ case WebAssembly::STORE8_I64_S:
return 0;
case WebAssembly::LOAD16_S_I32:
+ case WebAssembly::LOAD16_S_I32_S:
case WebAssembly::LOAD16_U_I32:
+ case WebAssembly::LOAD16_U_I32_S:
case WebAssembly::LOAD16_S_I64:
+ case WebAssembly::LOAD16_S_I64_S:
case WebAssembly::LOAD16_U_I64:
+ case WebAssembly::LOAD16_U_I64_S:
case WebAssembly::ATOMIC_LOAD16_U_I32:
+ case WebAssembly::ATOMIC_LOAD16_U_I32_S:
case WebAssembly::ATOMIC_LOAD16_U_I64:
+ case WebAssembly::ATOMIC_LOAD16_U_I64_S:
case WebAssembly::STORE16_I32:
+ case WebAssembly::STORE16_I32_S:
case WebAssembly::STORE16_I64:
+ case WebAssembly::STORE16_I64_S:
return 1;
case WebAssembly::LOAD_I32:
+ case WebAssembly::LOAD_I32_S:
case WebAssembly::LOAD_F32:
+ case WebAssembly::LOAD_F32_S:
case WebAssembly::STORE_I32:
+ case WebAssembly::STORE_I32_S:
case WebAssembly::STORE_F32:
+ case WebAssembly::STORE_F32_S:
case WebAssembly::LOAD32_S_I64:
+ case WebAssembly::LOAD32_S_I64_S:
case WebAssembly::LOAD32_U_I64:
+ case WebAssembly::LOAD32_U_I64_S:
case WebAssembly::STORE32_I64:
+ case WebAssembly::STORE32_I64_S:
case WebAssembly::ATOMIC_LOAD_I32:
+ case WebAssembly::ATOMIC_LOAD_I32_S:
case WebAssembly::ATOMIC_LOAD32_U_I64:
+ case WebAssembly::ATOMIC_LOAD32_U_I64_S:
return 2;
case WebAssembly::LOAD_I64:
+ case WebAssembly::LOAD_I64_S:
case WebAssembly::LOAD_F64:
+ case WebAssembly::LOAD_F64_S:
case WebAssembly::STORE_I64:
+ case WebAssembly::STORE_I64_S:
case WebAssembly::STORE_F64:
+ case WebAssembly::STORE_F64_S:
case WebAssembly::ATOMIC_LOAD_I64:
+ case WebAssembly::ATOMIC_LOAD_I64_S:
return 3;
default:
llvm_unreachable("Only loads and stores have p2align values");
Modified: llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrAtomics.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrAtomics.td?rev=334985&r1=334984&r2=334985&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrAtomics.td (original)
+++ llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrAtomics.td Mon Jun 18 14:22:44 2018
@@ -17,8 +17,8 @@
//===----------------------------------------------------------------------===//
let Defs = [ARGUMENTS] in {
-def ATOMIC_LOAD_I32 : WebAssemblyLoad<I32, "i32.atomic.load", 0xfe10>;
-def ATOMIC_LOAD_I64 : WebAssemblyLoad<I64, "i64.atomic.load", 0xfe11>;
+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.
@@ -56,11 +56,11 @@ def : LoadPatExternSymOffOnly<i64, atomi
// Extending loads. Note that there are only zero-extending atomic loads, no
// sign-extending loads.
let Defs = [ARGUMENTS] in {
-def ATOMIC_LOAD8_U_I32 : WebAssemblyLoad<I32, "i32.atomic.load8_u", 0xfe12>;
-def ATOMIC_LOAD16_U_I32 : WebAssemblyLoad<I32, "i32.atomic.load16_u", 0xfe13>;
-def ATOMIC_LOAD8_U_I64 : WebAssemblyLoad<I64, "i64.atomic.load8_u", 0xfe14>;
-def ATOMIC_LOAD16_U_I64 : WebAssemblyLoad<I64, "i64.atomic.load16_u", 0xfe15>;
-def ATOMIC_LOAD32_U_I64 : WebAssemblyLoad<I64, "i64.atomic.load32_u", 0xfe16>;
+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 exending loads. These are different from regular loads because
Modified: llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrCall.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrCall.td?rev=334985&r1=334984&r2=334985&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrCall.td (original)
+++ llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrCall.td Mon Jun 18 14:22:44 2018
@@ -13,57 +13,72 @@
//===----------------------------------------------------------------------===//
// 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 {
-def ADJCALLSTACKDOWN : I<(outs), (ins i32imm:$amt, i32imm:$amt2),
- [(WebAssemblycallseq_start timm:$amt, timm:$amt2)]>;
-def ADJCALLSTACKUP : I<(outs), (ins i32imm:$amt, i32imm:$amt2),
- [(WebAssemblycallseq_end timm:$amt, timm:$amt2)]>;
+defm ADJCALLSTACKDOWN : NRI<(outs), (ins i32imm:$amt, i32imm:$amt2),
+ [(WebAssemblycallseq_start timm:$amt, timm:$amt2)]>;
+defm ADJCALLSTACKUP : NRI<(outs), (ins i32imm:$amt, i32imm:$amt2),
+ [(WebAssemblycallseq_end timm:$amt, timm:$amt2)]>;
} // isCodeGenOnly = 1
multiclass CALL<WebAssemblyRegClass vt, string prefix> {
- def CALL_#vt : I<(outs vt:$dst), (ins function32_op:$callee, variable_ops),
- [(set vt:$dst, (WebAssemblycall1 (i32 imm:$callee)))],
- !strconcat(prefix, "call\t$dst, $callee"),
- 0x10>;
+ defm CALL_#vt : I<(outs vt:$dst), (ins function32_op:$callee, variable_ops),
+ (outs), (ins function32_op:$callee),
+ [(set vt:$dst, (WebAssemblycall1 (i32 imm:$callee)))],
+ !strconcat(prefix, "call\t$dst, $callee"),
+ !strconcat(prefix, "call\t$callee"),
+ 0x10>;
let isCodeGenOnly = 1 in {
- def PCALL_INDIRECT_#vt : I<(outs vt:$dst), (ins I32:$callee, variable_ops),
- [(set vt:$dst, (WebAssemblycall1 I32:$callee))],
- "PSEUDO CALL INDIRECT\t$callee">;
+ defm PCALL_INDIRECT_#vt : I<(outs vt:$dst), (ins I32:$callee, variable_ops),
+ (outs), (ins I32:$callee),
+ [(set vt:$dst, (WebAssemblycall1 I32:$callee))],
+ "PSEUDO CALL INDIRECT\t$callee",
+ "PSEUDO CALL INDIRECT\t$callee">;
} // isCodeGenOnly = 1
- def CALL_INDIRECT_#vt : I<(outs vt:$dst),
- (ins TypeIndex:$type, i32imm:$flags, variable_ops),
- [],
- !strconcat(prefix, "call_indirect\t$dst"),
- 0x11>;
+ defm CALL_INDIRECT_#vt : I<(outs vt:$dst),
+ (ins TypeIndex:$type, i32imm:$flags, variable_ops),
+ (outs), (ins TypeIndex:$type, i32imm:$flags),
+ [],
+ !strconcat(prefix, "call_indirect\t$dst"),
+ !strconcat(prefix, "call_indirect\t$type"),
+ 0x11>;
}
multiclass SIMD_CALL<ValueType vt, string prefix> {
- def CALL_#vt : SIMD_I<(outs V128:$dst), (ins function32_op:$callee, variable_ops),
+ defm CALL_#vt : SIMD_I<(outs V128:$dst), (ins function32_op:$callee,
+ variable_ops),
+ (outs), (ins function32_op:$callee),
[(set (vt V128:$dst),
- (WebAssemblycall1 (i32 imm:$callee)))],
+ (WebAssemblycall1 (i32 imm:$callee)))],
!strconcat(prefix, "call\t$dst, $callee"),
+ !strconcat(prefix, "call\t$callee"),
0x10>;
let isCodeGenOnly = 1 in {
- def PCALL_INDIRECT_#vt : SIMD_I<(outs V128:$dst),
- (ins I32:$callee, variable_ops),
- [(set (vt V128:$dst),
- (WebAssemblycall1 I32:$callee))],
- "PSEUDO CALL INDIRECT\t$callee">;
+ defm PCALL_INDIRECT_#vt : SIMD_I<(outs V128:$dst),
+ (ins I32:$callee, variable_ops),
+ (outs), (ins I32:$callee),
+ [(set (vt V128:$dst),
+ (WebAssemblycall1 I32:$callee))],
+ "PSEUDO CALL INDIRECT\t$callee",
+ "PSEUDO CALL INDIRECT\t$callee">;
} // isCodeGenOnly = 1
- def CALL_INDIRECT_#vt : SIMD_I<(outs V128:$dst),
+ defm CALL_INDIRECT_#vt : SIMD_I<(outs V128:$dst),
(ins TypeIndex:$type, i32imm:$flags,
- variable_ops),
+ variable_ops),
+ (outs), (ins TypeIndex:$type, i32imm:$flags),
[],
- !strconcat(prefix, "call_indirect\t$dst"),
+ !strconcat(prefix,
+ "call_indirect\t$dst"),
+ !strconcat(prefix, "call_indirect\t$type"),
0x11>;
}
@@ -78,20 +93,26 @@ let Uses = [SP32, SP64], isCall = 1 in {
defm "" : SIMD_CALL<v4i32, "i32x4.">;
defm "" : SIMD_CALL<v4f32, "f32x4.">;
- def CALL_VOID : I<(outs), (ins function32_op:$callee, variable_ops),
- [(WebAssemblycall0 (i32 imm:$callee))],
- "call \t$callee", 0x10>;
+ defm CALL_VOID : I<(outs), (ins function32_op:$callee, variable_ops),
+ (outs), (ins function32_op:$callee),
+ [(WebAssemblycall0 (i32 imm:$callee))],
+ "call \t$callee", "call\t$callee", 0x10>;
let isCodeGenOnly = 1 in {
- def PCALL_INDIRECT_VOID : I<(outs), (ins I32:$callee, variable_ops),
- [(WebAssemblycall0 I32:$callee)],
- "PSEUDO CALL INDIRECT\t$callee">;
+ defm PCALL_INDIRECT_VOID : I<(outs), (ins I32:$callee, variable_ops),
+ (outs), (ins I32:$callee),
+ [(WebAssemblycall0 I32:$callee)],
+ "PSEUDO CALL INDIRECT\t$callee",
+ "PSEUDO CALL INDIRECT\t$callee">;
} // isCodeGenOnly = 1
- def CALL_INDIRECT_VOID : I<(outs),
- (ins TypeIndex:$type, i32imm:$flags, variable_ops),
- [],
- "call_indirect\t", 0x11>;
+ defm CALL_INDIRECT_VOID : I<(outs),
+ (ins TypeIndex:$type, i32imm:$flags,
+ variable_ops),
+ (outs), (ins TypeIndex:$type, i32imm:$flags),
+ [],
+ "call_indirect\t", "call_indirect\t$type",
+ 0x11>;
} // Uses = [SP32,SP64], isCall = 1
} // Defs = [ARGUMENTS]
Modified: llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrControl.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrControl.td?rev=334985&r1=334984&r2=334985&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrControl.td (original)
+++ llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrControl.td Mon Jun 18 14:22:44 2018
@@ -16,15 +16,17 @@ let Defs = [ARGUMENTS] in {
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", 0x0d>;
+defm BR_IF : I<(outs), (ins bb_op:$dst, I32:$cond),
+ (outs), (ins bb_op:$dst),
+ [(brcond I32:$cond, bb:$dst)],
+ "br_if \t$dst, $cond", "br_if \t$dst", 0x0d>;
let isCodeGenOnly = 1 in
-def BR_UNLESS : I<(outs), (ins bb_op:$dst, I32:$cond), []>;
+defm BR_UNLESS : I<(outs), (ins bb_op:$dst, I32:$cond),
+ (outs), (ins bb_op:$dst), []>;
let isBarrier = 1 in {
-def BR : I<(outs), (ins bb_op:$dst),
- [(br bb:$dst)],
- "br \t$dst", 0x0c>;
+defm BR : NRI<(outs), (ins bb_op:$dst),
+ [(br bb:$dst)],
+ "br \t$dst", 0x0c>;
} // isBarrier = 1
} // isBranch = 1, isTerminator = 1, hasCtrlDep = 1
@@ -42,16 +44,30 @@ let Defs = [ARGUMENTS] in {
// currently.
// Set TSFlags{0} to 1 to indicate that the variable_ops are immediates.
// Set TSFlags{1} to 1 to indicate that the immediates represent labels.
+// FIXME: this can't inherit from I<> since there is no way to inherit from a
+// multiclass and still have the let statements.
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", 0x0e> {
+def BR_TABLE_I32 : NI<(outs), (ins I32:$index, variable_ops),
+ [(WebAssemblybr_table I32:$index)], 0,
+ "br_table \t$index", 0x0e> {
let TSFlags{0} = 1;
let TSFlags{1} = 1;
}
-def BR_TABLE_I64 : I<(outs), (ins I64:$index, variable_ops),
- [(WebAssemblybr_table I64:$index)],
- "br_table \t$index"> {
+def BR_TABLE_I32_S : NI<(outs), (ins I32:$index),
+ [], 1,
+ "br_table \t$index", 0x0e> {
+ let TSFlags{0} = 1;
+ let TSFlags{1} = 1;
+}
+def BR_TABLE_I64 : NI<(outs), (ins I64:$index, variable_ops),
+ [(WebAssemblybr_table I64:$index)], 0,
+ "br_table \t$index"> {
+ let TSFlags{0} = 1;
+ let TSFlags{1} = 1;
+}
+def BR_TABLE_I64_S : NI<(outs), (ins I64:$index),
+ [], 1,
+ "br_table \t$index"> {
let TSFlags{0} = 1;
let TSFlags{1} = 1;
}
@@ -59,40 +75,42 @@ def BR_TABLE_I64 : I<(outs), (ins I64:$i
// This is technically a control-flow instruction, since all it affects is the
// IP.
-def NOP : I<(outs), (ins), [], "nop", 0x01>;
+defm NOP : NRI<(outs), (ins), [], "nop", 0x01>;
// Placemarkers to indicate the start or end of a block or loop scope.
// These 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 Signature:$sig), [], "block \t$sig", 0x02>;
-def LOOP : I<(outs), (ins Signature:$sig), [], "loop \t$sig", 0x03>;
+defm BLOCK : NRI<(outs), (ins Signature:$sig), [], "block \t$sig", 0x02>;
+defm LOOP : NRI<(outs), (ins Signature:$sig), [], "loop \t$sig", 0x03>;
// END_BLOCK, END_LOOP, and END_FUNCTION are represented with the same opcode in
// wasm.
-def END_BLOCK : I<(outs), (ins), [], "end_block", 0x0b>;
-def END_LOOP : I<(outs), (ins), [], "end_loop", 0x0b>;
+defm END_BLOCK : NRI<(outs), (ins), [], "end_block", 0x0b>;
+defm END_LOOP : NRI<(outs), (ins), [], "end_loop", 0x0b>;
let isTerminator = 1, isBarrier = 1 in
-def END_FUNCTION : I<(outs), (ins), [], "end_function", 0x0b>;
+defm END_FUNCTION : NRI<(outs), (ins), [], "end_function", 0x0b>;
} // Uses = [VALUE_STACK], Defs = [VALUE_STACK]
multiclass RETURN<WebAssemblyRegClass vt> {
- def RETURN_#vt : I<(outs), (ins vt:$val), [(WebAssemblyreturn vt:$val)],
- "return \t$val", 0x0f>;
+ defm RETURN_#vt : I<(outs), (ins vt:$val), (outs), (ins),
+ [(WebAssemblyreturn vt:$val)],
+ "return \t$val", "return", 0x0f>;
// Equivalent to RETURN_#vt, for use at the end of a function when wasm
// semantics return by falling off the end of the block.
let isCodeGenOnly = 1 in
- def FALLTHROUGH_RETURN_#vt : I<(outs), (ins vt:$val), []>;
+ defm FALLTHROUGH_RETURN_#vt : I<(outs), (ins vt:$val), (outs), (ins), []>;
}
multiclass SIMD_RETURN<ValueType vt> {
- def RETURN_#vt : SIMD_I<(outs), (ins V128:$val),
- [(WebAssemblyreturn (vt V128:$val))],
- "return \t$val", 0x0f>;
+ defm RETURN_#vt : SIMD_I<(outs), (ins V128:$val), (outs), (ins),
+ [(WebAssemblyreturn (vt V128:$val))],
+ "return \t$val", "return", 0x0f>;
// Equivalent to RETURN_#vt, for use at the end of a function when wasm
// semantics return by falling off the end of the block.
let isCodeGenOnly = 1 in
- def FALLTHROUGH_RETURN_#vt : SIMD_I<(outs), (ins V128:$val), []>;
+ defm FALLTHROUGH_RETURN_#vt : SIMD_I<(outs), (ins V128:$val), (outs), (ins),
+ []>;
}
let isTerminator = 1, hasCtrlDep = 1, isBarrier = 1 in {
@@ -108,14 +126,14 @@ let isReturn = 1 in {
defm "": SIMD_RETURN<v4i32>;
defm "": SIMD_RETURN<v4f32>;
- def RETURN_VOID : I<(outs), (ins), [(WebAssemblyreturn)], "return", 0x0f>;
+ defm RETURN_VOID : NRI<(outs), (ins), [(WebAssemblyreturn)], "return", 0x0f>;
// This is to RETURN_VOID what FALLTHROUGH_RETURN_#vt is to RETURN_#vt.
let isCodeGenOnly = 1 in
- def FALLTHROUGH_RETURN_VOID : I<(outs), (ins), []>;
+ defm FALLTHROUGH_RETURN_VOID : NRI<(outs), (ins), []>;
} // isReturn = 1
-def UNREACHABLE : I<(outs), (ins), [(trap)], "unreachable", 0x00>;
+defm UNREACHABLE : NRI<(outs), (ins), [(trap)], "unreachable", 0x00>;
} // isTerminator = 1, hasCtrlDep = 1, isBarrier = 1
//===----------------------------------------------------------------------===//
@@ -124,31 +142,37 @@ def UNREACHABLE : I<(outs), (ins), [(tra
// Throwing an exception: throw / rethrow
let isTerminator = 1, hasCtrlDep = 1, isBarrier = 1 in {
-def THROW_I32 : I<(outs), (ins i32imm:$tag, I32:$val),
- [(int_wasm_throw imm:$tag, I32:$val)], "throw \t$tag, $val",
- 0x08>;
-def THROW_I64 : I<(outs), (ins i32imm:$tag, I64:$val),
- [(int_wasm_throw imm:$tag, I64:$val)], "throw \t$tag, $val",
- 0x08>;
-def RETHROW : I<(outs), (ins i32imm:$rel_depth), [], "rethrow \t$rel_depth",
- 0x09>;
+defm THROW_I32 : I<(outs), (ins i32imm:$tag, I32:$val),
+ (outs), (ins i32imm:$tag),
+ [(int_wasm_throw imm:$tag, I32:$val)],
+ "throw \t$tag, $val", "throw \t$tag",
+ 0x08>;
+defm THROW_I64 : I<(outs), (ins i32imm:$tag, I64:$val),
+ (outs), (ins i32imm:$tag),
+ [(int_wasm_throw imm:$tag, I64:$val)],
+ "throw \t$tag, $val", "throw \t$tag",
+ 0x08>;
+defm RETHROW : NRI<(outs), (ins i32imm:$rel_depth), [], "rethrow \t$rel_depth",
+ 0x09>;
} // isTerminator = 1, hasCtrlDep = 1, isBarrier = 1
// Region within which an exception is caught: try / end_try
let Uses = [VALUE_STACK], Defs = [VALUE_STACK] in {
-def TRY : I<(outs), (ins Signature:$sig), [], "try \t$sig", 0x06>;
-def END_TRY : I<(outs), (ins), [], "end_try", 0x0b>;
+defm TRY : NRI<(outs), (ins Signature:$sig), [], "try \t$sig", 0x06>;
+defm END_TRY : NRI<(outs), (ins), [], "end_try", 0x0b>;
} // Uses = [VALUE_STACK], Defs = [VALUE_STACK]
// Catching an exception: catch / catch_all
let hasCtrlDep = 1 in {
-def CATCH_I32 : I<(outs I32:$dst), (ins i32imm:$tag),
- [(set I32:$dst, (int_wasm_catch imm:$tag))],
- "i32.catch \t$dst, $tag", 0x07>;
-def CATCH_I64 : I<(outs I64:$dst), (ins i32imm:$tag),
- [(set I64:$dst, (int_wasm_catch imm:$tag))],
- "i64.catch \t$dst, $tag", 0x07>;
-def CATCH_ALL : I<(outs), (ins), [], "catch_all", 0x05>;
+defm CATCH_I32 : I<(outs I32:$dst), (ins i32imm:$tag),
+ (outs), (ins i32imm:$tag),
+ [(set I32:$dst, (int_wasm_catch imm:$tag))],
+ "i32.catch \t$dst, $tag", "i32.catch \t$tag", 0x07>;
+defm CATCH_I64 : I<(outs I64:$dst), (ins i32imm:$tag),
+ (outs), (ins i32imm:$tag),
+ [(set I64:$dst, (int_wasm_catch imm:$tag))],
+ "i64.catch \t$dst, $tag", "i64.catch \t$tag", 0x07>;
+defm CATCH_ALL : NRI<(outs), (ins), [], "catch_all", 0x05>;
}
// Pseudo instructions: cleanupret / catchret
@@ -156,8 +180,8 @@ def CATCH_ALL : I<(outs), (ins), [], "ca
// in X86 is necessary for computing EH scope membership.
let isTerminator = 1, hasSideEffects = 1, isBarrier = 1, hasCtrlDep = 1,
isCodeGenOnly = 1, isReturn = 1 in {
- def CLEANUPRET : I<(outs), (ins), [(cleanupret)], "", 0>;
- def CATCHRET : I<(outs), (ins bb_op:$dst, bb_op:$from),
+ defm CLEANUPRET : NRI<(outs), (ins), [(cleanupret)], "", 0>;
+ defm CATCHRET : NRI<(outs), (ins bb_op:$dst, bb_op:$from),
[(catchret bb:$dst, bb:$from)], "", 0>;
}
Modified: llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrConv.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrConv.td?rev=334985&r1=334984&r2=334985&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrConv.td (original)
+++ llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrConv.td Mon Jun 18 14:22:44 2018
@@ -15,33 +15,40 @@
let Defs = [ARGUMENTS] in {
-def I32_WRAP_I64 : I<(outs I32:$dst), (ins I64:$src),
+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", 0xa7>;
+ "i32.wrap/i64\t$dst, $src", "i32.wrap/i64", 0xa7>;
-def I64_EXTEND_S_I32 : I<(outs I64:$dst), (ins I32:$src),
+defm I64_EXTEND_S_I32 : I<(outs I64:$dst), (ins I32:$src), (outs), (ins),
[(set I64:$dst, (sext I32:$src))],
- "i64.extend_s/i32\t$dst, $src", 0xac>;
-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", 0xad>;
+ "i64.extend_s/i32\t$dst, $src", "i64.extend_s/i32",
+ 0xac>;
+defm I64_EXTEND_U_I32 : I<(outs I64:$dst), (ins I32:$src), (outs), (ins),
+ [(set I64:$dst, (zext I32:$src))],
+ "i64.extend_u/i32\t$dst, $src", "i64.extend_u/i32",
+ 0xad>;
let Predicates = [HasSignExt] in {
-def I32_EXTEND8_S_I32 : I<(outs I32:$dst), (ins I32:$src),
- [(set I32:$dst, (sext_inreg I32:$src, i8))],
- "i32.extend8_s\t$dst, $src", 0xc0>;
-def I32_EXTEND16_S_I32 : I<(outs I32:$dst), (ins I32:$src),
- [(set I32:$dst, (sext_inreg I32:$src, i16))],
- "i32.extend16_s\t$dst, $src", 0xc1>;
-def I64_EXTEND8_S_I64 : I<(outs I64:$dst), (ins I64:$src),
- [(set I64:$dst, (sext_inreg I64:$src, i8))],
- "i64.extend8_s\t$dst, $src", 0xc2>;
-def I64_EXTEND16_S_I64 : I<(outs I64:$dst), (ins I64:$src),
- [(set I64:$dst, (sext_inreg I64:$src, i16))],
- "i64.extend16_s\t$dst, $src", 0xc3>;
-def I64_EXTEND32_S_I64 : I<(outs I64:$dst), (ins I64:$src),
- [(set I64:$dst, (sext_inreg I64:$src, i32))],
- "i64.extend32_s\t$dst, $src", 0xc4>;
+defm I32_EXTEND8_S_I32 : I<(outs I32:$dst), (ins I32:$src), (outs), (ins),
+ [(set I32:$dst, (sext_inreg I32:$src, i8))],
+ "i32.extend8_s\t$dst, $src", "i32.extend8_s",
+ 0xc0>;
+defm I32_EXTEND16_S_I32 : I<(outs I32:$dst), (ins I32:$src), (outs), (ins),
+ [(set I32:$dst, (sext_inreg I32:$src, i16))],
+ "i32.extend16_s\t$dst, $src", "i32.extend16_s",
+ 0xc1>;
+defm I64_EXTEND8_S_I64 : I<(outs I64:$dst), (ins I64:$src), (outs), (ins),
+ [(set I64:$dst, (sext_inreg I64:$src, i8))],
+ "i64.extend8_s\t$dst, $src", "i64.extend8_s",
+ 0xc2>;
+defm I64_EXTEND16_S_I64 : I<(outs I64:$dst), (ins I64:$src), (outs), (ins),
+ [(set I64:$dst, (sext_inreg I64:$src, i16))],
+ "i64.extend16_s\t$dst, $src", "i64.extend16_s",
+ 0xc3>;
+defm I64_EXTEND32_S_I64 : I<(outs I64:$dst), (ins I64:$src), (outs), (ins),
+ [(set I64:$dst, (sext_inreg I64:$src, i32))],
+ "i64.extend32_s\t$dst, $src", "i64.extend32_s",
+ 0xc4>;
} // Predicates = [HasSignExt]
} // defs = [ARGUMENTS]
@@ -55,131 +62,161 @@ let Defs = [ARGUMENTS] in {
// Conversion from floating point to integer instructions which don't trap on
// overflow or invalid.
-def I32_TRUNC_S_SAT_F32 : I<(outs I32:$dst), (ins F32:$src),
- [(set I32:$dst, (fp_to_sint F32:$src))],
- "i32.trunc_s:sat/f32\t$dst, $src", 0xfc00>,
- Requires<[HasNontrappingFPToInt]>;
-def I32_TRUNC_U_SAT_F32 : I<(outs I32:$dst), (ins F32:$src),
- [(set I32:$dst, (fp_to_uint F32:$src))],
- "i32.trunc_u:sat/f32\t$dst, $src", 0xfc01>,
- Requires<[HasNontrappingFPToInt]>;
-def I64_TRUNC_S_SAT_F32 : I<(outs I64:$dst), (ins F32:$src),
- [(set I64:$dst, (fp_to_sint F32:$src))],
- "i64.trunc_s:sat/f32\t$dst, $src", 0xfc04>,
- Requires<[HasNontrappingFPToInt]>;
-def I64_TRUNC_U_SAT_F32 : I<(outs I64:$dst), (ins F32:$src),
- [(set I64:$dst, (fp_to_uint F32:$src))],
- "i64.trunc_u:sat/f32\t$dst, $src", 0xfc05>,
- Requires<[HasNontrappingFPToInt]>;
-def I32_TRUNC_S_SAT_F64 : I<(outs I32:$dst), (ins F64:$src),
- [(set I32:$dst, (fp_to_sint F64:$src))],
- "i32.trunc_s:sat/f64\t$dst, $src", 0xfc02>,
- Requires<[HasNontrappingFPToInt]>;
-def I32_TRUNC_U_SAT_F64 : I<(outs I32:$dst), (ins F64:$src),
- [(set I32:$dst, (fp_to_uint F64:$src))],
- "i32.trunc_u:sat/f64\t$dst, $src", 0xfc03>,
- Requires<[HasNontrappingFPToInt]>;
-def I64_TRUNC_S_SAT_F64 : I<(outs I64:$dst), (ins F64:$src),
- [(set I64:$dst, (fp_to_sint F64:$src))],
- "i64.trunc_s:sat/f64\t$dst, $src", 0xfc06>,
- Requires<[HasNontrappingFPToInt]>;
-def I64_TRUNC_U_SAT_F64 : I<(outs I64:$dst), (ins F64:$src),
- [(set I64:$dst, (fp_to_uint F64:$src))],
- "i64.trunc_u:sat/f64\t$dst, $src", 0xfc07>,
- Requires<[HasNontrappingFPToInt]>;
+defm I32_TRUNC_S_SAT_F32 : I<(outs I32:$dst), (ins F32:$src), (outs), (ins),
+ [(set I32:$dst, (fp_to_sint F32:$src))],
+ "i32.trunc_s:sat/f32\t$dst, $src",
+ "i32.trunc_s:sat/f32", 0xfc00>,
+ Requires<[HasNontrappingFPToInt]>;
+defm I32_TRUNC_U_SAT_F32 : I<(outs I32:$dst), (ins F32:$src), (outs), (ins),
+ [(set I32:$dst, (fp_to_uint F32:$src))],
+ "i32.trunc_u:sat/f32\t$dst, $src",
+ "i32.trunc_u:sat/f32", 0xfc01>,
+ Requires<[HasNontrappingFPToInt]>;
+defm I64_TRUNC_S_SAT_F32 : I<(outs I64:$dst), (ins F32:$src), (outs), (ins),
+ [(set I64:$dst, (fp_to_sint F32:$src))],
+ "i64.trunc_s:sat/f32\t$dst, $src",
+ "i64.trunc_s:sat/f32", 0xfc04>,
+ Requires<[HasNontrappingFPToInt]>;
+defm I64_TRUNC_U_SAT_F32 : I<(outs I64:$dst), (ins F32:$src), (outs), (ins),
+ [(set I64:$dst, (fp_to_uint F32:$src))],
+ "i64.trunc_u:sat/f32\t$dst, $src",
+ "i64.trunc_u:sat/f32", 0xfc05>,
+ Requires<[HasNontrappingFPToInt]>;
+defm I32_TRUNC_S_SAT_F64 : I<(outs I32:$dst), (ins F64:$src), (outs), (ins),
+ [(set I32:$dst, (fp_to_sint F64:$src))],
+ "i32.trunc_s:sat/f64\t$dst, $src",
+ "i32.trunc_s:sat/f64", 0xfc02>,
+ Requires<[HasNontrappingFPToInt]>;
+defm I32_TRUNC_U_SAT_F64 : I<(outs I32:$dst), (ins F64:$src), (outs), (ins),
+ [(set I32:$dst, (fp_to_uint F64:$src))],
+ "i32.trunc_u:sat/f64\t$dst, $src",
+ "i32.trunc_u:sat/f64", 0xfc03>,
+ Requires<[HasNontrappingFPToInt]>;
+defm I64_TRUNC_S_SAT_F64 : I<(outs I64:$dst), (ins F64:$src), (outs), (ins),
+ [(set I64:$dst, (fp_to_sint F64:$src))],
+ "i64.trunc_s:sat/f64\t$dst, $src",
+ "i64.trunc_s:sat/f64", 0xfc06>,
+ Requires<[HasNontrappingFPToInt]>;
+defm I64_TRUNC_U_SAT_F64 : I<(outs I64:$dst), (ins F64:$src), (outs), (ins),
+ [(set I64:$dst, (fp_to_uint F64:$src))],
+ "i64.trunc_u:sat/f64\t$dst, $src",
+ "i64.trunc_u:sat/f64", 0xfc07>,
+ Requires<[HasNontrappingFPToInt]>;
// Conversion from floating point to integer pseudo-instructions which don't
// trap on overflow or invalid.
let usesCustomInserter = 1, isCodeGenOnly = 1 in {
-def FP_TO_SINT_I32_F32 : I<(outs I32:$dst), (ins F32:$src),
- [(set I32:$dst, (fp_to_sint F32:$src))], "", 0>,
- Requires<[NotHasNontrappingFPToInt]>;
-def FP_TO_UINT_I32_F32 : I<(outs I32:$dst), (ins F32:$src),
- [(set I32:$dst, (fp_to_uint F32:$src))], "", 0>,
- Requires<[NotHasNontrappingFPToInt]>;
-def FP_TO_SINT_I64_F32 : I<(outs I64:$dst), (ins F32:$src),
- [(set I64:$dst, (fp_to_sint F32:$src))], "", 0>,
- Requires<[NotHasNontrappingFPToInt]>;
-def FP_TO_UINT_I64_F32 : I<(outs I64:$dst), (ins F32:$src),
- [(set I64:$dst, (fp_to_uint F32:$src))], "", 0>,
- Requires<[NotHasNontrappingFPToInt]>;
-def FP_TO_SINT_I32_F64 : I<(outs I32:$dst), (ins F64:$src),
- [(set I32:$dst, (fp_to_sint F64:$src))], "", 0>,
- Requires<[NotHasNontrappingFPToInt]>;
-def FP_TO_UINT_I32_F64 : I<(outs I32:$dst), (ins F64:$src),
- [(set I32:$dst, (fp_to_uint F64:$src))], "", 0>,
- Requires<[NotHasNontrappingFPToInt]>;
-def FP_TO_SINT_I64_F64 : I<(outs I64:$dst), (ins F64:$src),
- [(set I64:$dst, (fp_to_sint F64:$src))], "", 0>,
- Requires<[NotHasNontrappingFPToInt]>;
-def FP_TO_UINT_I64_F64 : I<(outs I64:$dst), (ins F64:$src),
- [(set I64:$dst, (fp_to_uint F64:$src))], "", 0>,
- Requires<[NotHasNontrappingFPToInt]>;
+defm FP_TO_SINT_I32_F32 : I<(outs I32:$dst), (ins F32:$src), (outs), (ins),
+ [(set I32:$dst, (fp_to_sint F32:$src))], "", "", 0>,
+ Requires<[NotHasNontrappingFPToInt]>;
+defm FP_TO_UINT_I32_F32 : I<(outs I32:$dst), (ins F32:$src), (outs), (ins),
+ [(set I32:$dst, (fp_to_uint F32:$src))], "", "", 0>,
+ Requires<[NotHasNontrappingFPToInt]>;
+defm FP_TO_SINT_I64_F32 : I<(outs I64:$dst), (ins F32:$src), (outs), (ins),
+ [(set I64:$dst, (fp_to_sint F32:$src))], "", "", 0>,
+ Requires<[NotHasNontrappingFPToInt]>;
+defm FP_TO_UINT_I64_F32 : I<(outs I64:$dst), (ins F32:$src), (outs), (ins),
+ [(set I64:$dst, (fp_to_uint F32:$src))], "", "", 0>,
+ Requires<[NotHasNontrappingFPToInt]>;
+defm FP_TO_SINT_I32_F64 : I<(outs I32:$dst), (ins F64:$src), (outs), (ins),
+ [(set I32:$dst, (fp_to_sint F64:$src))], "", "", 0>,
+ Requires<[NotHasNontrappingFPToInt]>;
+defm FP_TO_UINT_I32_F64 : I<(outs I32:$dst), (ins F64:$src), (outs), (ins),
+ [(set I32:$dst, (fp_to_uint F64:$src))], "", "", 0>,
+ Requires<[NotHasNontrappingFPToInt]>;
+defm FP_TO_SINT_I64_F64 : I<(outs I64:$dst), (ins F64:$src), (outs), (ins),
+ [(set I64:$dst, (fp_to_sint F64:$src))], "", "", 0>,
+ Requires<[NotHasNontrappingFPToInt]>;
+defm FP_TO_UINT_I64_F64 : I<(outs I64:$dst), (ins F64:$src), (outs), (ins),
+ [(set I64:$dst, (fp_to_uint F64:$src))], "", "", 0>,
+ Requires<[NotHasNontrappingFPToInt]>;
} // usesCustomInserter, isCodeGenOnly = 1
// Conversion from floating point to integer traps on overflow and invalid.
let hasSideEffects = 1 in {
-def I32_TRUNC_S_F32 : I<(outs I32:$dst), (ins F32:$src),
- [], "i32.trunc_s/f32\t$dst, $src", 0xa8>;
-def I32_TRUNC_U_F32 : I<(outs I32:$dst), (ins F32:$src),
- [], "i32.trunc_u/f32\t$dst, $src", 0xa9>;
-def I64_TRUNC_S_F32 : I<(outs I64:$dst), (ins F32:$src),
- [], "i64.trunc_s/f32\t$dst, $src", 0xae>;
-def I64_TRUNC_U_F32 : I<(outs I64:$dst), (ins F32:$src),
- [], "i64.trunc_u/f32\t$dst, $src", 0xaf>;
-def I32_TRUNC_S_F64 : I<(outs I32:$dst), (ins F64:$src),
- [], "i32.trunc_s/f64\t$dst, $src", 0xaa>;
-def I32_TRUNC_U_F64 : I<(outs I32:$dst), (ins F64:$src),
- [], "i32.trunc_u/f64\t$dst, $src", 0xab>;
-def I64_TRUNC_S_F64 : I<(outs I64:$dst), (ins F64:$src),
- [], "i64.trunc_s/f64\t$dst, $src", 0xb0>;
-def I64_TRUNC_U_F64 : I<(outs I64:$dst), (ins F64:$src),
- [], "i64.trunc_u/f64\t$dst, $src", 0xb1>;
+defm I32_TRUNC_S_F32 : I<(outs I32:$dst), (ins F32:$src), (outs), (ins),
+ [], "i32.trunc_s/f32\t$dst, $src", "i32.trunc_s/f32",
+ 0xa8>;
+defm I32_TRUNC_U_F32 : I<(outs I32:$dst), (ins F32:$src), (outs), (ins),
+ [], "i32.trunc_u/f32\t$dst, $src", "i32.trunc_u/f32",
+ 0xa9>;
+defm I64_TRUNC_S_F32 : I<(outs I64:$dst), (ins F32:$src), (outs), (ins),
+ [], "i64.trunc_s/f32\t$dst, $src", "i64.trunc_s/f32",
+ 0xae>;
+defm I64_TRUNC_U_F32 : I<(outs I64:$dst), (ins F32:$src), (outs), (ins),
+ [], "i64.trunc_u/f32\t$dst, $src", "i64.trunc_u/f32",
+ 0xaf>;
+defm I32_TRUNC_S_F64 : I<(outs I32:$dst), (ins F64:$src), (outs), (ins),
+ [], "i32.trunc_s/f64\t$dst, $src", "i32.trunc_s/f64",
+ 0xaa>;
+defm I32_TRUNC_U_F64 : I<(outs I32:$dst), (ins F64:$src), (outs), (ins),
+ [], "i32.trunc_u/f64\t$dst, $src", "i32.trunc_u/f64",
+ 0xab>;
+defm I64_TRUNC_S_F64 : I<(outs I64:$dst), (ins F64:$src), (outs), (ins),
+ [], "i64.trunc_s/f64\t$dst, $src", "i64.trunc_s/f64",
+ 0xb0>;
+defm I64_TRUNC_U_F64 : I<(outs I64:$dst), (ins F64:$src), (outs), (ins),
+ [], "i64.trunc_u/f64\t$dst, $src", "i64.trunc_u/f64",
+ 0xb1>;
} // 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", 0xb2>;
-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", 0xb3>;
-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", 0xb7>;
-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", 0xb8>;
-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", 0xb4>;
-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", 0xb5>;
-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", 0xb9>;
-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", 0xba>;
-
-def F64_PROMOTE_F32 : I<(outs F64:$dst), (ins F32:$src),
- [(set F64:$dst, (fpextend F32:$src))],
- "f64.promote/f32\t$dst, $src", 0xbb>;
-def F32_DEMOTE_F64 : I<(outs F32:$dst), (ins F64:$src),
- [(set F32:$dst, (fpround F64:$src))],
- "f32.demote/f64\t$dst, $src", 0xb6>;
-
-def I32_REINTERPRET_F32 : I<(outs I32:$dst), (ins F32:$src),
- [(set I32:$dst, (bitconvert F32:$src))],
- "i32.reinterpret/f32\t$dst, $src", 0xbc>;
-def F32_REINTERPRET_I32 : I<(outs F32:$dst), (ins I32:$src),
- [(set F32:$dst, (bitconvert I32:$src))],
- "f32.reinterpret/i32\t$dst, $src", 0xbe>;
-def I64_REINTERPRET_F64 : I<(outs I64:$dst), (ins F64:$src),
- [(set I64:$dst, (bitconvert F64:$src))],
- "i64.reinterpret/f64\t$dst, $src", 0xbd>;
-def F64_REINTERPRET_I64 : I<(outs F64:$dst), (ins I64:$src),
- [(set F64:$dst, (bitconvert I64:$src))],
- "f64.reinterpret/i64\t$dst, $src", 0xbf>;
+defm F32_CONVERT_S_I32 : I<(outs F32:$dst), (ins I32:$src), (outs), (ins),
+ [(set F32:$dst, (sint_to_fp I32:$src))],
+ "f32.convert_s/i32\t$dst, $src", "f32.convert_s/i32",
+ 0xb2>;
+defm F32_CONVERT_U_I32 : I<(outs F32:$dst), (ins I32:$src), (outs), (ins),
+ [(set F32:$dst, (uint_to_fp I32:$src))],
+ "f32.convert_u/i32\t$dst, $src", "f32.convert_u/i32",
+ 0xb3>;
+defm F64_CONVERT_S_I32 : I<(outs F64:$dst), (ins I32:$src), (outs), (ins),
+ [(set F64:$dst, (sint_to_fp I32:$src))],
+ "f64.convert_s/i32\t$dst, $src", "f64.convert_s/i32",
+ 0xb7>;
+defm F64_CONVERT_U_I32 : I<(outs F64:$dst), (ins I32:$src), (outs), (ins),
+ [(set F64:$dst, (uint_to_fp I32:$src))],
+ "f64.convert_u/i32\t$dst, $src", "f64.convert_u/i32",
+ 0xb8>;
+defm F32_CONVERT_S_I64 : I<(outs F32:$dst), (ins I64:$src), (outs), (ins),
+ [(set F32:$dst, (sint_to_fp I64:$src))],
+ "f32.convert_s/i64\t$dst, $src", "f32.convert_s/i64",
+ 0xb4>;
+defm F32_CONVERT_U_I64 : I<(outs F32:$dst), (ins I64:$src), (outs), (ins),
+ [(set F32:$dst, (uint_to_fp I64:$src))],
+ "f32.convert_u/i64\t$dst, $src", "f32.convert_u/i64",
+ 0xb5>;
+defm F64_CONVERT_S_I64 : I<(outs F64:$dst), (ins I64:$src), (outs), (ins),
+ [(set F64:$dst, (sint_to_fp I64:$src))],
+ "f64.convert_s/i64\t$dst, $src", "f64.convert_s/i64",
+ 0xb9>;
+defm F64_CONVERT_U_I64 : I<(outs F64:$dst), (ins I64:$src), (outs), (ins),
+ [(set F64:$dst, (uint_to_fp I64:$src))],
+ "f64.convert_u/i64\t$dst, $src", "f64.convert_u/i64",
+ 0xba>;
+
+defm F64_PROMOTE_F32 : I<(outs F64:$dst), (ins F32:$src), (outs), (ins),
+ [(set F64:$dst, (fpextend F32:$src))],
+ "f64.promote/f32\t$dst, $src", "f64.promote/f32",
+ 0xbb>;
+defm F32_DEMOTE_F64 : I<(outs F32:$dst), (ins F64:$src), (outs), (ins),
+ [(set F32:$dst, (fpround F64:$src))],
+ "f32.demote/f64\t$dst, $src", "f32.demote/f64",
+ 0xb6>;
+
+defm I32_REINTERPRET_F32 : I<(outs I32:$dst), (ins F32:$src), (outs), (ins),
+ [(set I32:$dst, (bitconvert F32:$src))],
+ "i32.reinterpret/f32\t$dst, $src",
+ "i32.reinterpret/f32", 0xbc>;
+defm F32_REINTERPRET_I32 : I<(outs F32:$dst), (ins I32:$src), (outs), (ins),
+ [(set F32:$dst, (bitconvert I32:$src))],
+ "f32.reinterpret/i32\t$dst, $src",
+ "f32.reinterpret/i32", 0xbe>;
+defm I64_REINTERPRET_F64 : I<(outs I64:$dst), (ins F64:$src), (outs), (ins),
+ [(set I64:$dst, (bitconvert F64:$src))],
+ "i64.reinterpret/f64\t$dst, $src",
+ "i64.reinterpret/f64", 0xbd>;
+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]
Modified: llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrExceptRef.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrExceptRef.td?rev=334985&r1=334984&r2=334985&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrExceptRef.td (original)
+++ llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrExceptRef.td Mon Jun 18 14:22:44 2018
@@ -14,12 +14,14 @@
let Defs = [ARGUMENTS] in {
-def SELECT_EXCEPT_REF : I<(outs EXCEPT_REF:$dst),
- (ins EXCEPT_REF:$lhs, EXCEPT_REF:$rhs, I32:$cond),
- [(set EXCEPT_REF:$dst,
- (select I32:$cond, EXCEPT_REF:$lhs,
- EXCEPT_REF:$rhs))],
- "except_ref.select\t$dst, $lhs, $rhs, $cond", 0x1b>;
+defm SELECT_EXCEPT_REF : I<(outs EXCEPT_REF:$dst),
+ (ins EXCEPT_REF:$lhs, EXCEPT_REF:$rhs, I32:$cond),
+ (outs), (ins),
+ [(set EXCEPT_REF:$dst,
+ (select I32:$cond, EXCEPT_REF:$lhs,
+ EXCEPT_REF:$rhs))],
+ "except_ref.select\t$dst, $lhs, $rhs, $cond",
+ "except_ref.select", 0x1b>;
} // Defs = [ARGUMENTS]
Modified: llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrFloat.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrFloat.td?rev=334985&r1=334984&r2=334985&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrFloat.td (original)
+++ llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrFloat.td Mon Jun 18 14:22:44 2018
@@ -77,12 +77,14 @@ def : Pat<(setge f64:$lhs, f64:$rhs), (G
let Defs = [ARGUMENTS] in {
-def SELECT_F32 : I<(outs F32:$dst), (ins F32:$lhs, F32:$rhs, I32:$cond),
- [(set F32:$dst, (select I32:$cond, F32:$lhs, F32:$rhs))],
- "f32.select\t$dst, $lhs, $rhs, $cond", 0x1b>;
-def 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", 0x1b>;
+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))],
+ "f32.select\t$dst, $lhs, $rhs, $cond", "f32.select", 0x1b>;
+defm SELECT_F64 : I<(outs F64:$dst), (ins F64:$lhs, F64:$rhs, I32:$cond),
+ (outs), (ins),
+ [(set F64:$dst, (select I32:$cond, F64:$lhs, F64:$rhs))],
+ "f64.select\t$dst, $lhs, $rhs, $cond", "f64.select", 0x1b>;
} // Defs = [ARGUMENTS]
Modified: llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrFormats.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrFormats.td?rev=334985&r1=334984&r2=334985&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrFormats.td (original)
+++ llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrFormats.td Mon Jun 18 14:22:44 2018
@@ -13,94 +13,155 @@
//===----------------------------------------------------------------------===//
// WebAssembly Instruction Format.
-class WebAssemblyInst<bits<32> inst, string asmstr> : Instruction {
+// We instantiate 2 of these for every actual instruction (register based
+// and stack based), see below.
+class WebAssemblyInst<bits<32> inst, string asmstr, bit stack> : Instruction {
field bits<32> Inst = inst; // Instruction encoding.
+ field bit StackBased = stack;
let Namespace = "WebAssembly";
let Pattern = [];
let AsmString = asmstr;
}
-// Normal instructions.
-class I<dag oops, dag iops, list<dag> pattern, string asmstr = "", bits<32> inst = -1>
- : WebAssemblyInst<inst, asmstr> {
+// Normal instructions. Default instantiation of a WebAssemblyInst.
+class NI<dag oops, dag iops, list<dag> pattern, bit stack, string asmstr = "",
+ bits<32> inst = -1>
+ : WebAssemblyInst<inst, asmstr, stack> {
dag OutOperandList = oops;
dag InOperandList = iops;
let Pattern = pattern;
}
-class SIMD_I<dag oops, dag iops, list<dag> pattern,
- string asmstr = "", bits<32> inst = -1>
- : I<oops, iops, pattern, asmstr, inst>, Requires<[HasSIMD128]>;
-
-class ATOMIC_I<dag oops, dag iops, list<dag> pattern,
- string asmstr = "", bits<32> inst = -1>
- : I<oops, iops, pattern, asmstr, inst>, Requires<[HasAtomics]>;
+// Generates both register and stack based versions of one actual instruction.
+// We have 2 sets of operands (oops & iops) for the register and stack
+// based version of this instruction, as well as the corresponding asmstr.
+// The register versions have virtual-register operands which correspond to wasm
+// locals or stack locations. Each use and def of the register corresponds to an
+// implicit get_local / set_local or access of stack operands in wasm. These
+// instructions are used for ISel and all MI passes. The stack versions of the
+// instructions do not have register operands (they implicitly operate on the
+// stack), and get_locals and set_locals are explicit. The register instructions
+// are converted to their corresponding stack instructions before lowering to
+// MC.
+// Every instruction should want to be based on this multi-class to guarantee
+// there is always an equivalent pair of instructions.
+multiclass I<dag oops_r, dag iops_r, dag oops_s, dag iops_s,
+ list<dag> pattern_r, string asmstr_r = "", string asmstr_s = "",
+ bits<32> inst = -1> {
+ def "" : NI<oops_r, iops_r, pattern_r, 0, asmstr_r, inst>;
+ def _S : NI<oops_s, iops_s, [], 1, asmstr_s, inst>;
+}
+
+// For instructions that have no register ops, so both sets are the same.
+multiclass NRI<dag oops, dag iops, list<dag> pattern, string asmstr = "",
+ bits<32> inst = -1> {
+ defm "": I<oops, iops, oops, iops, pattern, asmstr, asmstr, inst>;
+}
+
+multiclass SIMD_I<dag oops_r, dag iops_r, dag oops_s, dag iops_s,
+ list<dag> pattern_r, string asmstr_r = "",
+ string asmstr_s = "", bits<32> inst = -1> {
+ defm "" : I<oops_r, iops_r, oops_s, iops_s, pattern_r, asmstr_r, asmstr_s,
+ inst>,
+ Requires<[HasSIMD128]>;
+}
+
+multiclass ATOMIC_I<dag oops_r, dag iops_r, dag oops_s, dag iops_s,
+ list<dag> pattern_r, string asmstr_r = "",
+ string asmstr_s = "", bits<32> inst = -1> {
+ defm "" : I<oops_r, iops_r, oops_s, iops_s, pattern_r, asmstr_r, asmstr_s,
+ inst>,
+ Requires<[HasAtomics]>;
+}
// Unary and binary instructions, for the local types that WebAssembly supports.
-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")), i32Inst>;
- def _I64 : I<(outs I64:$dst), (ins I64:$src),
- [(set I64:$dst, (node I64:$src))],
- !strconcat("i64.", !strconcat(name, "\t$dst, $src")), i64Inst>;
-}
-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")), 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")), i64Inst>;
-}
-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")), f32Inst>;
- def _F64 : I<(outs F64:$dst), (ins F64:$src),
- [(set F64:$dst, (node F64:$src))],
- !strconcat("f64.", !strconcat(name, "\t$dst, $src")), f64Inst>;
-}
-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")), 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")), f64Inst>;
+multiclass UnaryInt<SDNode node, string name, bits<32> i32Inst,
+ bits<32> i64Inst> {
+ defm _I32 : I<(outs I32:$dst), (ins I32:$src), (outs), (ins),
+ [(set I32:$dst, (node I32:$src))],
+ !strconcat("i32.", !strconcat(name, "\t$dst, $src")),
+ !strconcat("i32.", name), i32Inst>;
+ defm _I64 : I<(outs I64:$dst), (ins I64:$src), (outs), (ins),
+ [(set I64:$dst, (node I64:$src))],
+ !strconcat("i64.", !strconcat(name, "\t$dst, $src")),
+ !strconcat("i64.", name), i64Inst>;
+}
+multiclass BinaryInt<SDNode node, string name, bits<32> i32Inst,
+ bits<32> i64Inst> {
+ defm _I32 : I<(outs I32:$dst), (ins I32:$lhs, I32:$rhs), (outs), (ins),
+ [(set I32:$dst, (node I32:$lhs, I32:$rhs))],
+ !strconcat("i32.", !strconcat(name, "\t$dst, $lhs, $rhs")),
+ !strconcat("i32.", name), i32Inst>;
+ defm _I64 : I<(outs I64:$dst), (ins I64:$lhs, I64:$rhs), (outs), (ins),
+ [(set I64:$dst, (node I64:$lhs, I64:$rhs))],
+ !strconcat("i64.", !strconcat(name, "\t$dst, $lhs, $rhs")),
+ !strconcat("i64.", name), i64Inst>;
+}
+multiclass UnaryFP<SDNode node, string name, bits<32> f32Inst,
+ bits<32> f64Inst> {
+ defm _F32 : I<(outs F32:$dst), (ins F32:$src), (outs), (ins),
+ [(set F32:$dst, (node F32:$src))],
+ !strconcat("f32.", !strconcat(name, "\t$dst, $src")),
+ !strconcat("f32.", name), f32Inst>;
+ defm _F64 : I<(outs F64:$dst), (ins F64:$src), (outs), (ins),
+ [(set F64:$dst, (node F64:$src))],
+ !strconcat("f64.", !strconcat(name, "\t$dst, $src")),
+ !strconcat("f64.", name), f64Inst>;
+}
+multiclass BinaryFP<SDNode node, string name, bits<32> f32Inst,
+ bits<32> f64Inst> {
+ defm _F32 : I<(outs F32:$dst), (ins F32:$lhs, F32:$rhs), (outs), (ins),
+ [(set F32:$dst, (node F32:$lhs, F32:$rhs))],
+ !strconcat("f32.", !strconcat(name, "\t$dst, $lhs, $rhs")),
+ !strconcat("f32.", name), f32Inst>;
+ defm _F64 : I<(outs F64:$dst), (ins F64:$lhs, F64:$rhs), (outs), (ins),
+ [(set F64:$dst, (node F64:$lhs, F64:$rhs))],
+ !strconcat("f64.", !strconcat(name, "\t$dst, $lhs, $rhs")),
+ !strconcat("f64.", name), f64Inst>;
}
multiclass SIMDBinary<SDNode node, SDNode fnode, string name> {
- def _I8x16 : SIMD_I<(outs V128:$dst), (ins V128:$lhs, V128:$rhs),
- [(set (v16i8 V128:$dst), (node V128:$lhs, V128:$rhs))],
- !strconcat("i8x16.", !strconcat(name, "\t$dst, $lhs, $rhs"))>;
- def _I16x8 : SIMD_I<(outs V128:$dst), (ins V128:$lhs, V128:$rhs),
- [(set (v8i16 V128:$dst), (node V128:$lhs, V128:$rhs))],
- !strconcat("i16x8.", !strconcat(name, "\t$dst, $lhs, $rhs"))>;
- def _I32x4 : SIMD_I<(outs V128:$dst), (ins V128:$lhs, V128:$rhs),
- [(set (v4i32 V128:$dst), (node V128:$lhs, V128:$rhs))],
- !strconcat("i32x4.", !strconcat(name, "\t$dst, $lhs, $rhs"))>;
- def _F32x4 : SIMD_I<(outs V128:$dst), (ins V128:$lhs, V128:$rhs),
- [(set (v4f32 V128:$dst), (fnode V128:$lhs, V128:$rhs))],
- !strconcat("f32x4.", !strconcat(name, "\t$dst, $lhs, $rhs"))>;
-
+ defm _I8x16 : SIMD_I<(outs V128:$dst), (ins V128:$lhs, V128:$rhs),
+ (outs), (ins),
+ [(set (v16i8 V128:$dst), (node V128:$lhs, V128:$rhs))],
+ !strconcat("i8x16.",
+ !strconcat(name, "\t$dst, $lhs, $rhs")),
+ !strconcat("i8x16.", name)>;
+ defm _I16x8 : SIMD_I<(outs V128:$dst), (ins V128:$lhs, V128:$rhs),
+ (outs), (ins),
+ [(set (v8i16 V128:$dst), (node V128:$lhs, V128:$rhs))],
+ !strconcat("i16x8.",
+ !strconcat(name, "\t$dst, $lhs, $rhs")),
+ !strconcat("i16x8.", name)>;
+ defm _I32x4 : SIMD_I<(outs V128:$dst), (ins V128:$lhs, V128:$rhs),
+ (outs), (ins),
+ [(set (v4i32 V128:$dst), (node V128:$lhs, V128:$rhs))],
+ !strconcat("i32x4.",
+ !strconcat(name, "\t$dst, $lhs, $rhs")),
+ !strconcat("i32x4.", name)>;
+ defm _F32x4 : SIMD_I<(outs V128:$dst), (ins V128:$lhs, V128:$rhs),
+ (outs), (ins),
+ [(set (v4f32 V128:$dst), (fnode V128:$lhs, V128:$rhs))],
+ !strconcat("f32x4.",
+ !strconcat(name, "\t$dst, $lhs, $rhs")),
+ !strconcat("f32x4.", 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")),
- 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")),
- i64Inst>;
+ defm _I32 : I<(outs I32:$dst), (ins I32:$lhs, I32:$rhs), (outs), (ins),
+ [(set I32:$dst, (setcc I32:$lhs, I32:$rhs, cond))],
+ !strconcat("i32.", !strconcat(name, "\t$dst, $lhs, $rhs")),
+ !strconcat("i32.", name), i32Inst>;
+ defm _I64 : I<(outs I32:$dst), (ins I64:$lhs, I64:$rhs), (outs), (ins),
+ [(set I32:$dst, (setcc I64:$lhs, I64:$rhs, cond))],
+ !strconcat("i64.", !strconcat(name, "\t$dst, $lhs, $rhs")),
+ !strconcat("i64.", name), i64Inst>;
}
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")),
- 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")),
- f64Inst>;
+ defm _F32 : I<(outs I32:$dst), (ins F32:$lhs, F32:$rhs), (outs), (ins),
+ [(set I32:$dst, (setcc F32:$lhs, F32:$rhs, cond))],
+ !strconcat("f32.", !strconcat(name, "\t$dst, $lhs, $rhs")),
+ !strconcat("f32.", name), f32Inst>;
+ defm _F64 : I<(outs I32:$dst), (ins F64:$lhs, F64:$rhs), (outs), (ins),
+ [(set I32:$dst, (setcc F64:$lhs, F64:$rhs, cond))],
+ !strconcat("f64.", !strconcat(name, "\t$dst, $lhs, $rhs")),
+ !strconcat("f64.", name), f64Inst>;
}
Modified: llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrInfo.td?rev=334985&r1=334984&r2=334985&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrInfo.td (original)
+++ llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrInfo.td Mon Jun 18 14:22:44 2018
@@ -153,13 +153,15 @@ include "WebAssemblyInstrFormats.td"
multiclass ARGUMENT<WebAssemblyRegClass vt> {
let hasSideEffects = 1, Uses = [ARGUMENTS], isCodeGenOnly = 1 in
- def ARGUMENT_#vt : I<(outs vt:$res), (ins i32imm:$argno),
- [(set vt:$res, (WebAssemblyargument timm:$argno))]>;
+ defm ARGUMENT_#vt : I<(outs vt:$res), (ins i32imm:$argno),
+ (outs), (ins i32imm:$argno),
+ [(set vt:$res, (WebAssemblyargument timm:$argno))]>;
}
multiclass SIMD_ARGUMENT<ValueType vt> {
let hasSideEffects = 1, Uses = [ARGUMENTS], isCodeGenOnly = 1 in
- def ARGUMENT_#vt : SIMD_I<(outs V128:$res), (ins i32imm:$argno),
- [(set (vt V128:$res),
+ defm ARGUMENT_#vt : SIMD_I<(outs V128:$res), (ins i32imm:$argno),
+ (outs), (ins i32imm:$argno),
+ [(set (vt V128:$res),
(WebAssemblyargument timm:$argno))]>;
}
defm "": ARGUMENT<I32>;
@@ -184,47 +186,56 @@ let hasSideEffects = 0 in {
// and set_local. COPYs are eliminated (and replaced with
// get_local/set_local) in the ExplicitLocals pass.
let isAsCheapAsAMove = 1, isCodeGenOnly = 1 in
- def COPY_#vt : I<(outs vt:$res), (ins vt:$src), [], "copy_local\t$res, $src">;
+ defm COPY_#vt : I<(outs vt:$res), (ins vt:$src), (outs), (ins), [],
+ "copy_local\t$res, $src", "copy_local">;
// TEE is similar to COPY, but writes two copies of its result. Typically
// this would be used to stackify one result and write the other result to a
// local.
let isAsCheapAsAMove = 1, isCodeGenOnly = 1 in
- def TEE_#vt : I<(outs vt:$res, vt:$also), (ins vt:$src), [],
- "tee_local\t$res, $also, $src">;
+ defm TEE_#vt : I<(outs vt:$res, vt:$also), (ins vt:$src), (outs), (ins), [],
+ "tee_local\t$res, $also, $src", "tee_local">;
// This is the actual get_local instruction in wasm. These are made explicit
// by the ExplicitLocals pass. It has mayLoad because it reads from a wasm
// local, which is a side effect not otherwise modeled in LLVM.
let mayLoad = 1, isAsCheapAsAMove = 1 in
- def GET_LOCAL_#vt : I<(outs vt:$res), (ins local_op:$local), [],
- "get_local\t$res, $local", 0x20>;
+ defm GET_LOCAL_#vt : I<(outs vt:$res), (ins local_op:$local),
+ (outs), (ins local_op:$local), [],
+ "get_local\t$res, $local", "get_local\t$local", 0x20>;
// This is the actual set_local instruction in wasm. These are made explicit
// by the ExplicitLocals pass. It has mayStore because it writes to a wasm
// local, which is a side effect not otherwise modeled in LLVM.
let mayStore = 1, isAsCheapAsAMove = 1 in
- def SET_LOCAL_#vt : I<(outs), (ins local_op:$local, vt:$src), [],
- "set_local\t$local, $src", 0x21>;
+ defm SET_LOCAL_#vt : I<(outs), (ins local_op:$local, vt:$src),
+ (outs), (ins local_op:$local), [],
+ "set_local\t$local, $src", "set_local\t$local", 0x21>;
// This is the actual tee_local instruction in wasm. TEEs are turned into
// TEE_LOCALs by the ExplicitLocals pass. It has mayStore for the same reason
// as SET_LOCAL.
let mayStore = 1, isAsCheapAsAMove = 1 in
- def TEE_LOCAL_#vt : I<(outs vt:$res), (ins local_op:$local, vt:$src), [],
- "tee_local\t$res, $local, $src", 0x22>;
+ defm TEE_LOCAL_#vt : I<(outs vt:$res), (ins local_op:$local, vt:$src),
+ (outs), (ins local_op:$local), [],
+ "tee_local\t$res, $local, $src", "tee_local\t$local",
+ 0x22>;
// Unused values must be dropped in some contexts.
- def DROP_#vt : I<(outs), (ins vt:$src), [],
- "drop\t$src", 0x1a>;
+ defm DROP_#vt : I<(outs), (ins vt:$src), (outs), (ins), [],
+ "drop\t$src", "drop", 0x1a>;
let mayLoad = 1 in
- def GET_GLOBAL_#vt : I<(outs vt:$res), (ins global_op:$local), [],
- "get_global\t$res, $local", 0x23>;
+ defm GET_GLOBAL_#vt : I<(outs vt:$res), (ins global_op:$local),
+ (outs), (ins global_op:$local), [],
+ "get_global\t$res, $local", "get_global\t$local",
+ 0x23>;
let mayStore = 1 in
- def SET_GLOBAL_#vt : I<(outs), (ins global_op:$local, vt:$src), [],
- "set_global\t$local, $src", 0x24>;
+ defm SET_GLOBAL_#vt : I<(outs), (ins global_op:$local, vt:$src),
+ (outs), (ins global_op:$local), [],
+ "set_global\t$local, $src", "set_global\t$local",
+ 0x24>;
} // hasSideEffects = 0
}
@@ -236,18 +247,22 @@ defm "" : LOCAL<V128>, Requires<[HasSIMD
defm "" : LOCAL<EXCEPT_REF>, Requires<[HasExceptionHandling]>;
let isMoveImm = 1, isAsCheapAsAMove = 1, isReMaterializable = 1 in {
-def CONST_I32 : I<(outs I32:$res), (ins i32imm_op:$imm),
- [(set I32:$res, imm:$imm)],
- "i32.const\t$res, $imm", 0x41>;
-def CONST_I64 : I<(outs I64:$res), (ins i64imm_op:$imm),
- [(set I64:$res, imm:$imm)],
- "i64.const\t$res, $imm", 0x42>;
-def CONST_F32 : I<(outs F32:$res), (ins f32imm_op:$imm),
- [(set F32:$res, fpimm:$imm)],
- "f32.const\t$res, $imm", 0x43>;
-def CONST_F64 : I<(outs F64:$res), (ins f64imm_op:$imm),
- [(set F64:$res, fpimm:$imm)],
- "f64.const\t$res, $imm", 0x44>;
+defm CONST_I32 : I<(outs I32:$res), (ins i32imm_op:$imm),
+ (outs), (ins i32imm_op:$imm),
+ [(set I32:$res, imm:$imm)],
+ "i32.const\t$res, $imm", "i32.const\t$imm", 0x41>;
+defm CONST_I64 : I<(outs I64:$res), (ins i64imm_op:$imm),
+ (outs), (ins i64imm_op:$imm),
+ [(set I64:$res, imm:$imm)],
+ "i64.const\t$res, $imm", "i64.const\t$imm", 0x42>;
+defm CONST_F32 : I<(outs F32:$res), (ins f32imm_op:$imm),
+ (outs), (ins f32imm_op:$imm),
+ [(set F32:$res, fpimm:$imm)],
+ "f32.const\t$res, $imm", "f32.const\t$imm", 0x43>;
+defm CONST_F64 : I<(outs F64:$res), (ins f64imm_op:$imm),
+ (outs), (ins f64imm_op:$imm),
+ [(set F64:$res, fpimm:$imm)],
+ "f64.const\t$res, $imm", "f64.const\t$imm", 0x44>;
} // isMoveImm = 1, isAsCheapAsAMove = 1, isReMaterializable = 1
} // Defs = [ARGUMENTS]
Modified: llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrInteger.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrInteger.td?rev=334985&r1=334984&r2=334985&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrInteger.td (original)
+++ llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrInteger.td Mon Jun 18 14:22:44 2018
@@ -56,12 +56,12 @@ defm CLZ : UnaryInt<ctlz, "clz ", 0x67,
defm CTZ : UnaryInt<cttz, "ctz ", 0x68, 0x7a>;
defm POPCNT : UnaryInt<ctpop, "popcnt", 0x69, 0x7b>;
-def EQZ_I32 : I<(outs I32:$dst), (ins I32:$src),
- [(set I32:$dst, (setcc I32:$src, 0, SETEQ))],
- "i32.eqz \t$dst, $src", 0x45>;
-def EQZ_I64 : I<(outs I32:$dst), (ins I64:$src),
- [(set I32:$dst, (setcc I64:$src, 0, SETEQ))],
- "i64.eqz \t$dst, $src", 0x50>;
+defm EQZ_I32 : I<(outs I32:$dst), (ins I32:$src), (outs), (ins),
+ [(set I32:$dst, (setcc I32:$src, 0, SETEQ))],
+ "i32.eqz \t$dst, $src", "i32.eqz", 0x45>;
+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]
@@ -73,12 +73,14 @@ def : Pat<(rotr I64:$lhs, (and I64:$rhs,
let Defs = [ARGUMENTS] in {
-def SELECT_I32 : I<(outs I32:$dst), (ins I32:$lhs, I32:$rhs, I32:$cond),
- [(set I32:$dst, (select I32:$cond, I32:$lhs, I32:$rhs))],
- "i32.select\t$dst, $lhs, $rhs, $cond", 0x1b>;
-def 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", 0x1b>;
+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))],
+ "i32.select\t$dst, $lhs, $rhs, $cond", "i32.select", 0x1b>;
+defm SELECT_I64 : I<(outs I64:$dst), (ins I64:$lhs, I64:$rhs, I32:$cond),
+ (outs), (ins),
+ [(set I64:$dst, (select I32:$cond, I64:$lhs, I64:$rhs))],
+ "i64.select\t$dst, $lhs, $rhs, $cond", "i64.select", 0x1b>;
} // Defs = [ARGUMENTS]
Modified: llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrMemory.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrMemory.td?rev=334985&r1=334984&r2=334985&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrMemory.td (original)
+++ llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrMemory.td Mon Jun 18 14:22:44 2018
@@ -56,23 +56,26 @@ def regPlusGA : PatFrag<(ops node:$addr,
let Defs = [ARGUMENTS] in {
// Defines atomic and non-atomic loads, regular and extending.
-class WebAssemblyLoad<WebAssemblyRegClass rc, string Name, int Opcode> :
- I<(outs rc:$dst),
- (ins P2Align:$p2align, offset32_op:$off, I32:$addr),
- [], !strconcat(Name, "\t$dst, ${off}(${addr})${p2align}"), Opcode>;
+multiclass WebAssemblyLoad<WebAssemblyRegClass rc, string Name, int Opcode> {
+ defm "": I<(outs rc:$dst),
+ (ins P2Align:$p2align, offset32_op:$off, I32:$addr),
+ (outs), (ins P2Align:$p2align, offset32_op:$off),
+ [], !strconcat(Name, "\t$dst, ${off}(${addr})${p2align}"),
+ !strconcat(Name, "\t${off}, ${p2align}"), Opcode>;
+}
// Basic load.
// FIXME: When we can break syntax compatibility, reorder the fields in the
// asmstrings to match the binary encoding.
-def LOAD_I32 : WebAssemblyLoad<I32, "i32.load", 0x28>;
-def LOAD_I64 : WebAssemblyLoad<I64, "i64.load", 0x29>;
-def LOAD_F32 : WebAssemblyLoad<F32, "f32.load", 0x2a>;
-def LOAD_F64 : WebAssemblyLoad<F64, "f64.load", 0x2b>;
+defm LOAD_I32 : WebAssemblyLoad<I32, "i32.load", 0x28>;
+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 node, I inst> :
+class LoadPatNoOffset<ValueType ty, PatFrag node, NI inst> :
Pat<(ty (node I32:$addr)), (inst 0, 0, $addr)>;
def : LoadPatNoOffset<i32, load, LOAD_I32>;
@@ -84,7 +87,7 @@ def : LoadPatNoOffset<f64, load, LOAD_F6
// Select loads with a constant offset.
// Pattern with address + immediate offset
-class LoadPatImmOff<ValueType ty, PatFrag loadkind, PatFrag operand, I inst> :
+class LoadPatImmOff<ValueType ty, PatFrag loadkind, PatFrag operand, NI inst> :
Pat<(ty (loadkind (operand I32:$addr, imm:$off))),
(inst 0, imm:$off, $addr)>;
@@ -97,7 +100,7 @@ def : LoadPatImmOff<i64, load, or_is_add
def : LoadPatImmOff<f32, load, or_is_add, LOAD_F32>;
def : LoadPatImmOff<f64, load, or_is_add, LOAD_F64>;
-class LoadPatGlobalAddr<ValueType ty, PatFrag loadkind, I inst> :
+class LoadPatGlobalAddr<ValueType ty, PatFrag loadkind, NI inst> :
Pat<(ty (loadkind (regPlusGA I32:$addr, (WebAssemblywrapper tglobaladdr:$off)))),
(inst 0, tglobaladdr:$off, $addr)>;
@@ -106,7 +109,7 @@ def : LoadPatGlobalAddr<i64, load, LOAD_
def : LoadPatGlobalAddr<f32, load, LOAD_F32>;
def : LoadPatGlobalAddr<f64, load, LOAD_F64>;
-class LoadPatExternalSym<ValueType ty, PatFrag loadkind, I inst> :
+class LoadPatExternalSym<ValueType ty, PatFrag loadkind, NI inst> :
Pat<(ty (loadkind (add I32:$addr, (WebAssemblywrapper texternalsym:$off)))),
(inst 0, texternalsym:$off, $addr)>;
def : LoadPatExternalSym<i32, load, LOAD_I32>;
@@ -116,7 +119,7 @@ def : LoadPatExternalSym<f64, load, LOAD
// Select loads with just a constant offset.
-class LoadPatOffsetOnly<ValueType ty, PatFrag loadkind, I inst> :
+class LoadPatOffsetOnly<ValueType ty, PatFrag loadkind, NI inst> :
Pat<(ty (loadkind imm:$off)), (inst 0, imm:$off, (CONST_I32 0))>;
def : LoadPatOffsetOnly<i32, load, LOAD_I32>;
@@ -124,7 +127,7 @@ def : LoadPatOffsetOnly<i64, load, LOAD_
def : LoadPatOffsetOnly<f32, load, LOAD_F32>;
def : LoadPatOffsetOnly<f64, load, LOAD_F64>;
-class LoadPatGlobalAddrOffOnly<ValueType ty, PatFrag loadkind, I inst> :
+class LoadPatGlobalAddrOffOnly<ValueType ty, PatFrag loadkind, NI inst> :
Pat<(ty (loadkind (WebAssemblywrapper tglobaladdr:$off))),
(inst 0, tglobaladdr:$off, (CONST_I32 0))>;
@@ -133,7 +136,7 @@ def : LoadPatGlobalAddrOffOnly<i64, load
def : LoadPatGlobalAddrOffOnly<f32, load, LOAD_F32>;
def : LoadPatGlobalAddrOffOnly<f64, load, LOAD_F64>;
-class LoadPatExternSymOffOnly<ValueType ty, PatFrag loadkind, I inst> :
+class LoadPatExternSymOffOnly<ValueType ty, PatFrag loadkind, NI inst> :
Pat<(ty (loadkind (WebAssemblywrapper texternalsym:$off))),
(inst 0, texternalsym:$off, (CONST_I32 0))>;
def : LoadPatExternSymOffOnly<i32, load, LOAD_I32>;
@@ -144,16 +147,16 @@ def : LoadPatExternSymOffOnly<f64, load,
let Defs = [ARGUMENTS] in {
// Extending load.
-def LOAD8_S_I32 : WebAssemblyLoad<I32, "i32.load8_s", 0x2c>;
-def LOAD8_U_I32 : WebAssemblyLoad<I32, "i32.load8_u", 0x2d>;
-def LOAD16_S_I32 : WebAssemblyLoad<I32, "i32.load16_s", 0x2e>;
-def LOAD16_U_I32 : WebAssemblyLoad<I32, "i32.load16_u", 0x2f>;
-def LOAD8_S_I64 : WebAssemblyLoad<I64, "i64.load8_s", 0x30>;
-def LOAD8_U_I64 : WebAssemblyLoad<I64, "i64.load8_u", 0x31>;
-def LOAD16_S_I64 : WebAssemblyLoad<I64, "i64.load16_s", 0x32>;
-def LOAD16_U_I64 : WebAssemblyLoad<I64, "i64.load16_u", 0x33>;
-def LOAD32_S_I64 : WebAssemblyLoad<I64, "i64.load32_s", 0x34>;
-def LOAD32_U_I64 : WebAssemblyLoad<I64, "i64.load32_u", 0x35>;
+defm LOAD8_S_I32 : WebAssemblyLoad<I32, "i32.load8_s", 0x2c>;
+defm LOAD8_U_I32 : WebAssemblyLoad<I32, "i32.load8_u", 0x2d>;
+defm LOAD16_S_I32 : WebAssemblyLoad<I32, "i32.load16_s", 0x2e>;
+defm LOAD16_U_I32 : WebAssemblyLoad<I32, "i32.load16_u", 0x2f>;
+defm LOAD8_S_I64 : WebAssemblyLoad<I64, "i64.load8_s", 0x30>;
+defm LOAD8_U_I64 : WebAssemblyLoad<I64, "i64.load8_u", 0x31>;
+defm LOAD16_S_I64 : WebAssemblyLoad<I64, "i64.load16_s", 0x32>;
+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]
@@ -304,20 +307,25 @@ def : LoadPatExternSymOffOnly<i64, extlo
let Defs = [ARGUMENTS] in {
// Defines atomic and non-atomic stores, regular and truncating
-class WebAssemblyStore<WebAssemblyRegClass rc, string Name, int Opcode> :
- I<(outs), (ins P2Align:$p2align, offset32_op:$off, I32:$addr, rc:$val), [],
- !strconcat(Name, "\t${off}(${addr})${p2align}, $val"), Opcode>;
+multiclass WebAssemblyStore<WebAssemblyRegClass rc, string Name, int Opcode> {
+ defm "" : I<(outs),
+ (ins P2Align:$p2align, offset32_op:$off, I32:$addr, rc:$val),
+ (outs),
+ (ins P2Align:$p2align, offset32_op:$off), [],
+ !strconcat(Name, "\t${off}(${addr})${p2align}, $val"),
+ !strconcat(Name, "\t${off}, ${p2align}"), Opcode>;
+}
// Basic store.
// Note: WebAssembly inverts SelectionDAG's usual operand order.
-def STORE_I32 : WebAssemblyStore<I32, "i32.store", 0x36>;
-def STORE_I64 : WebAssemblyStore<I64, "i64.store", 0x37>;
-def STORE_F32 : WebAssemblyStore<F32, "f32.store", 0x38>;
-def STORE_F64 : WebAssemblyStore<F64, "f64.store", 0x39>;
+defm STORE_I32 : WebAssemblyStore<I32, "i32.store", 0x36>;
+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, I inst> :
+class StorePatNoOffset<ValueType ty, PatFrag node, NI inst> :
Pat<(node ty:$val, I32:$addr), (inst 0, 0, $addr, $val)>;
def : StorePatNoOffset<i32, store, STORE_I32>;
@@ -326,7 +334,7 @@ def : StorePatNoOffset<f32, store, STORE
def : StorePatNoOffset<f64, store, STORE_F64>;
// Select stores with a constant offset.
-class StorePatImmOff<ValueType ty, PatFrag storekind, PatFrag operand, I inst> :
+class StorePatImmOff<ValueType ty, PatFrag storekind, PatFrag operand, NI inst> :
Pat<(storekind ty:$val, (operand I32:$addr, imm:$off)),
(inst 0, imm:$off, $addr, ty:$val)>;
@@ -339,7 +347,7 @@ def : StorePatImmOff<i64, store, or_is_a
def : StorePatImmOff<f32, store, or_is_add, STORE_F32>;
def : StorePatImmOff<f64, store, or_is_add, STORE_F64>;
-class StorePatGlobalAddr<ValueType ty, PatFrag storekind, I inst> :
+class StorePatGlobalAddr<ValueType ty, PatFrag storekind, NI inst> :
Pat<(storekind ty:$val, (regPlusGA I32:$addr,
(WebAssemblywrapper tglobaladdr:$off))),
(inst 0, tglobaladdr:$off, I32:$addr, ty:$val)>;
@@ -348,7 +356,7 @@ def : StorePatGlobalAddr<i64, store, STO
def : StorePatGlobalAddr<f32, store, STORE_F32>;
def : StorePatGlobalAddr<f64, store, STORE_F64>;
-class StorePatExternalSym<ValueType ty, PatFrag storekind, I inst> :
+class StorePatExternalSym<ValueType ty, PatFrag storekind, NI inst> :
Pat<(storekind ty:$val, (add I32:$addr,
(WebAssemblywrapper texternalsym:$off))),
(inst 0, texternalsym:$off, I32:$addr, ty:$val)>;
@@ -358,7 +366,7 @@ def : StorePatExternalSym<f32, store, ST
def : StorePatExternalSym<f64, store, STORE_F64>;
// Select stores with just a constant offset.
-class StorePatOffsetOnly<ValueType ty, PatFrag storekind, I inst> :
+class StorePatOffsetOnly<ValueType ty, PatFrag storekind, NI inst> :
Pat<(storekind ty:$val, imm:$off),
(inst 0, imm:$off, (CONST_I32 0), ty:$val)>;
def : StorePatOffsetOnly<i32, store, STORE_I32>;
@@ -366,7 +374,7 @@ def : StorePatOffsetOnly<i64, store, STO
def : StorePatOffsetOnly<f32, store, STORE_F32>;
def : StorePatOffsetOnly<f64, store, STORE_F64>;
-class StorePatGlobalAddrOffOnly<ValueType ty, PatFrag storekind, I inst> :
+class StorePatGlobalAddrOffOnly<ValueType ty, PatFrag storekind, NI inst> :
Pat<(storekind ty:$val, (WebAssemblywrapper tglobaladdr:$off)),
(inst 0, tglobaladdr:$off, (CONST_I32 0), ty:$val)>;
def : StorePatGlobalAddrOffOnly<i32, store, STORE_I32>;
@@ -374,7 +382,7 @@ def : StorePatGlobalAddrOffOnly<i64, sto
def : StorePatGlobalAddrOffOnly<f32, store, STORE_F32>;
def : StorePatGlobalAddrOffOnly<f64, store, STORE_F64>;
-class StorePatExternSymOffOnly<ValueType ty, PatFrag storekind, I inst> :
+class StorePatExternSymOffOnly<ValueType ty, PatFrag storekind, NI inst> :
Pat<(storekind ty:$val, (WebAssemblywrapper texternalsym:$off)),
(inst 0, texternalsym:$off, (CONST_I32 0), ty:$val)>;
def : StorePatExternSymOffOnly<i32, store, STORE_I32>;
@@ -386,11 +394,11 @@ def : StorePatExternSymOffOnly<f64, stor
let Defs = [ARGUMENTS] in {
// Truncating store.
-def STORE8_I32 : WebAssemblyStore<I32, "i32.store8", 0x3a>;
-def STORE16_I32 : WebAssemblyStore<I32, "i32.store16", 0x3b>;
-def STORE8_I64 : WebAssemblyStore<I64, "i64.store8", 0x3c>;
-def STORE16_I64 : WebAssemblyStore<I64, "i64.store16", 0x3d>;
-def STORE32_I64 : WebAssemblyStore<I64, "i64.store32", 0x3e>;
+defm STORE8_I32 : WebAssemblyStore<I32, "i32.store8", 0x3a>;
+defm STORE16_I32 : WebAssemblyStore<I32, "i32.store16", 0x3b>;
+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]
@@ -444,34 +452,47 @@ def : StorePatExternSymOffOnly<i64, trun
let Defs = [ARGUMENTS] in {
// Current memory size.
-def MEMORY_SIZE_I32 : I<(outs I32:$dst), (ins i32imm:$flags),
- [(set I32:$dst, (int_wasm_memory_size (i32 imm:$flags)))],
- "memory.size\t$dst, $flags", 0x3f>,
- Requires<[HasAddr32]>;
-def MEM_SIZE_I32 : I<(outs I32:$dst), (ins i32imm:$flags),
- [(set I32:$dst, (int_wasm_mem_size (i32 imm:$flags)))],
- "mem.size\t$dst, $flags", 0x3f>,
- Requires<[HasAddr32]>;
-def CURRENT_MEMORY_I32 : I<(outs I32:$dst), (ins i32imm:$flags),
- [],
- "current_memory\t$dst", 0x3f>,
- Requires<[HasAddr32]>;
+defm MEMORY_SIZE_I32 : I<(outs I32:$dst), (ins i32imm:$flags),
+ (outs), (ins i32imm:$flags),
+ [(set I32:$dst,
+ (int_wasm_memory_size (i32 imm:$flags)))],
+ "memory.size\t$dst, $flags", "memory.size\t$flags",
+ 0x3f>,
+ Requires<[HasAddr32]>;
+defm MEM_SIZE_I32 : I<(outs I32:$dst), (ins i32imm:$flags),
+ (outs), (ins i32imm:$flags),
+ [(set I32:$dst, (int_wasm_mem_size (i32 imm:$flags)))],
+ "mem.size\t$dst, $flags", "mem.size\t$flags", 0x3f>,
+ Requires<[HasAddr32]>;
+defm CURRENT_MEMORY_I32 : I<(outs I32:$dst), (ins i32imm:$flags),
+ (outs), (ins i32imm:$flags),
+ [],
+ "current_memory\t$dst",
+ "current_memory\t$flags", 0x3f>,
+ Requires<[HasAddr32]>;
// Grow memory.
-def MEMORY_GROW_I32 : I<(outs I32:$dst), (ins i32imm:$flags, I32:$delta),
- [(set I32:$dst,
- (int_wasm_memory_grow (i32 imm:$flags), I32:$delta))],
- "memory.grow\t$dst, $flags, $delta", 0x3f>,
- Requires<[HasAddr32]>;
-def MEM_GROW_I32 : I<(outs I32:$dst), (ins i32imm:$flags, I32:$delta),
- [(set I32:$dst,
- (int_wasm_mem_grow (i32 imm:$flags), I32:$delta))],
- "mem.grow\t$dst, $flags, $delta", 0x3f>,
- Requires<[HasAddr32]>;
-def GROW_MEMORY_I32 : I<(outs I32:$dst), (ins i32imm:$flags, I32:$delta),
- [],
- "grow_memory\t$dst, $delta", 0x40>,
- Requires<[HasAddr32]>;
+defm MEMORY_GROW_I32 : I<(outs I32:$dst), (ins i32imm:$flags, I32:$delta),
+ (outs), (ins i32imm:$flags, I32:$delta),
+ [(set I32:$dst,
+ (int_wasm_memory_grow (i32 imm:$flags),
+ I32:$delta))],
+ "memory.grow\t$dst, $flags, $delta",
+ "memory.grow\t$flags, $delta", 0x3f>,
+ Requires<[HasAddr32]>;
+defm MEM_GROW_I32 : I<(outs I32:$dst), (ins i32imm:$flags, I32:$delta),
+ (outs), (ins i32imm:$flags),
+ [(set I32:$dst,
+ (int_wasm_mem_grow (i32 imm:$flags), I32:$delta))],
+ "mem.grow\t$dst, $flags, $delta", "mem.grow\t$flags",
+ 0x3f>,
+ Requires<[HasAddr32]>;
+defm GROW_MEMORY_I32 : I<(outs I32:$dst), (ins i32imm:$flags, I32:$delta),
+ (outs), (ins i32imm:$flags),
+ [],
+ "grow_memory\t$dst, $delta", "grow_memory\t$flags",
+ 0x40>,
+ Requires<[HasAddr32]>;
} // Defs = [ARGUMENTS]
Modified: llvm/trunk/test/MC/Disassembler/WebAssembly/wasm.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/WebAssembly/wasm.txt?rev=334985&r1=334984&r2=334985&view=diff
==============================================================================
--- llvm/trunk/test/MC/Disassembler/WebAssembly/wasm.txt (original)
+++ llvm/trunk/test/MC/Disassembler/WebAssembly/wasm.txt Mon Jun 18 14:22:44 2018
@@ -5,14 +5,14 @@
# CHECK: nop
0x01
-# CHECK: i32.add $0=, $0, $0
-# NOTE: registers are meaningless, as there is no context for what they are.
+# CHECK: i32.add
0x6a
-# CHECK: i64.const $0=, -1
+# CHECK: i64.const -1
0x42 0x7F
-# CHECK: i64.load32_u $0=, 16($0):p2align=1
+# CHECK: i64.load32_u 16, :p2align=1
+# FIXME: fix p2align output in WebAssemblyInstPrinter
0x35 0x01 0x10
# CHECK: block
@@ -25,9 +25,9 @@
# FIXME: WebAssemblyInstPrinter does not print immediates.
0x11 0x80 0x01 0x00
-# CHECK: get_local $0=, 128
+# CHECK: get_local 128
0x20 0x80 0x01
# Prefix byte example:
-# CHECK: i64.trunc_u:sat/f64 $0=, $0
+# CHECK: i64.trunc_u:sat/f64
0xFC 0x07
More information about the llvm-commits
mailing list