]> granicus.if.org Git - llvm/commitdiff
[WebAssembly] tablegen: distinguish float/int immediate operands.
authorWouter van Oortmerssen <aardappel@gmail.com>
Mon, 8 Jul 2019 16:58:37 +0000 (16:58 +0000)
committerWouter van Oortmerssen <aardappel@gmail.com>
Mon, 8 Jul 2019 16:58:37 +0000 (16:58 +0000)
Summary:
Before, they were one category of operands which could cause
crashes in non-sensical combinations, e.g. "f32.const symbol".
Now these are forced to be an error.

Reviewers: dschuff

Subscribers: sbc100, jgravelle-google, aheejin, sunfish, llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D64039

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@365351 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp
lib/Target/WebAssembly/WebAssemblyInstrInfo.td
test/MC/WebAssembly/basic-assembly-errors.s

index e22ed8e4764be1d8c8983d46d29b5893c1ed5120..c7a88906019fde962a515b9f8e5baed6d6b398b1 100644 (file)
@@ -89,9 +89,8 @@ struct WebAssemblyOperand : public MCParsedAsmOperand {
   }
 
   bool isToken() const override { return Kind == Token; }
-  bool isImm() const override {
-    return Kind == Integer || Kind == Float || Kind == Symbol;
-  }
+  bool isImm() const override { return Kind == Integer || Kind == Symbol; }
+  bool isFPImm() const { return Kind == Float; }
   bool isMem() const override { return false; }
   bool isReg() const override { return false; }
   bool isBrList() const { return Kind == BrList; }
@@ -118,12 +117,18 @@ struct WebAssemblyOperand : public MCParsedAsmOperand {
     assert(N == 1 && "Invalid number of operands!");
     if (Kind == Integer)
       Inst.addOperand(MCOperand::createImm(Int.Val));
-    else if (Kind == Float)
-      Inst.addOperand(MCOperand::createFPImm(Flt.Val));
     else if (Kind == Symbol)
       Inst.addOperand(MCOperand::createExpr(Sym.Exp));
     else
-      llvm_unreachable("Should be immediate or symbol!");
+      llvm_unreachable("Should be integer immediate or symbol!");
+  }
+
+  void addFPImmOperands(MCInst &Inst, unsigned N) const {
+    assert(N == 1 && "Invalid number of operands!");
+    if (Kind == Float)
+      Inst.addOperand(MCOperand::createFPImm(Flt.Val));
+    else
+      llvm_unreachable("Should be float immediate!");
   }
 
   void addBrListOperands(MCInst &Inst, unsigned N) const {
index c42118e82c878c933a4775934bc6bf75a501057d..859cb9bcdfd970d51b83fccdc94a0a727dbeeab1 100644 (file)
@@ -118,6 +118,17 @@ def WebAssemblythrow : SDNode<"WebAssemblyISD::THROW", SDT_WebAssemblyThrow,
 // WebAssembly-specific Operands.
 //===----------------------------------------------------------------------===//
 
+// Default Operand has AsmOperandClass "Imm" which is for integers (and
+// symbols), so specialize one for floats:
+def FPImmAsmOperand : AsmOperandClass {
+  let Name = "FPImm";
+  let PredicateMethod = "isFPImm";
+}
+
+class FPOperand<ValueType ty> : Operand<ty> {
+  AsmOperandClass ParserMatchClass = FPImmAsmOperand;
+}
+
 let OperandNamespace = "WebAssembly" in {
 
 let OperandType = "OPERAND_BASIC_BLOCK" in
@@ -136,10 +147,10 @@ let OperandType = "OPERAND_I64IMM" in
 def i64imm_op : Operand<i64>;
 
 let OperandType = "OPERAND_F32IMM" in
-def f32imm_op : Operand<f32>;
+def f32imm_op : FPOperand<f32>;
 
 let OperandType = "OPERAND_F64IMM" in
-def f64imm_op : Operand<f64>;
+def f64imm_op : FPOperand<f64>;
 
 let OperandType = "OPERAND_VEC_I8IMM" in
 def vec_i8imm_op : Operand<i32>;
index eead082e93f7a222834e96b2a2f3959400a95d48..ba990f14e11a3bc00160f6a2daf4f2f4b1771955 100644 (file)
@@ -1,5 +1,9 @@
 # RUN: not llvm-mc -triple=wasm32-unknown-unknown -mattr=+simd128,+nontrapping-fptoint,+exception-handling < %s 2>&1 | FileCheck %s
 
+# CHECK: invalid operand for instruction
+# (must be 0.0 or similar)
+    f32.const 0
+
 # CHECK: End of block construct with no start: end_try
     end_try
 test0: