llvm-mc/X86: Sketch match functions for immediates and memory operands.
authorDaniel Dunbar <daniel@zuster.org>
Fri, 31 Jul 2009 20:53:16 +0000 (20:53 +0000)
committerDaniel Dunbar <daniel@zuster.org>
Fri, 31 Jul 2009 20:53:16 +0000 (20:53 +0000)
Also, change scale value to always be 1 when unspecified to machine MachineInst
encoding.

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

lib/Target/X86/AsmParser/X86AsmParser.cpp
test/MC/AsmParser/x86_instructions.s

index 1f00f16d6933c9405aa4c1e62026a242abfe5450..1c55c3fc7b28a78889ea41766c718b281599ba6e 100644 (file)
@@ -95,6 +95,32 @@ struct X86Operand {
     return Reg.RegNo;
   }
 
+  const MCValue &getImm() const {
+    assert(Kind == Immediate && "Invalid access!");
+    return Imm.Val;
+  }
+
+  const MCValue &getMemDisp() const {
+    assert(Kind == Memory && "Invalid access!");
+    return Mem.Disp;
+  }
+  unsigned getMemSegReg() const {
+    assert(Kind == Memory && "Invalid access!");
+    return Mem.SegReg;
+  }
+  unsigned getMemBaseReg() const {
+    assert(Kind == Memory && "Invalid access!");
+    return Mem.BaseReg;
+  }
+  unsigned getMemIndexReg() const {
+    assert(Kind == Memory && "Invalid access!");
+    return Mem.IndexReg;
+  }
+  unsigned getMemScale() const {
+    assert(Kind == Memory && "Invalid access!");
+    return Mem.Scale;
+  }
+
   static X86Operand CreateReg(unsigned RegNo) {
     X86Operand Res;
     Res.Kind = Register;
@@ -109,11 +135,8 @@ struct X86Operand {
   }
   static X86Operand CreateMem(unsigned SegReg, MCValue Disp, unsigned BaseReg,
                               unsigned IndexReg, unsigned Scale) {
-    // If there is no index register, we should never have a scale, and we
-    // should always have a scale (in {1,2,4,8}) if we do.
-    assert(((Scale == 0 && !IndexReg) ||
-            (IndexReg && (Scale == 1 || Scale == 2 ||
-                          Scale == 4 || Scale == 8))) &&
+    // The scale should always be one of {1,2,4,8}.
+    assert(((Scale == 1 || Scale == 2 || Scale == 4 || Scale == 8)) &&
            "Invalid scale!");
     X86Operand Res;
     Res.Kind = Memory;
@@ -193,7 +216,7 @@ bool X86ATTAsmParser::ParseMemOperand(X86Operand &Op) {
     // After parsing the base expression we could either have a parenthesized
     // memory address or not.  If not, return now.  If so, eat the (.
     if (getLexer().isNot(AsmToken::LParen)) {
-      Op = X86Operand::CreateMem(SegReg, Disp, 0, 0, 0);
+      Op = X86Operand::CreateMem(SegReg, Disp, 0, 0, 1);
       return false;
     }
     
@@ -215,7 +238,7 @@ bool X86ATTAsmParser::ParseMemOperand(X86Operand &Op) {
       // After parsing the base expression we could either have a parenthesized
       // memory address or not.  If not, return now.  If so, eat the (.
       if (getLexer().isNot(AsmToken::LParen)) {
-        Op = X86Operand::CreateMem(SegReg, Disp, 0, 0, 0);
+        Op = X86Operand::CreateMem(SegReg, Disp, 0, 0, 1);
         return false;
       }
       
@@ -226,7 +249,7 @@ bool X86ATTAsmParser::ParseMemOperand(X86Operand &Op) {
   
   // If we reached here, then we just ate the ( of the memory operand.  Process
   // the rest of the memory operand.
-  unsigned BaseReg = 0, IndexReg = 0, Scale = 0;
+  unsigned BaseReg = 0, IndexReg = 0, Scale = 1;
   
   if (getLexer().is(AsmToken::Register)) {
     if (ParseRegister(Op))
@@ -247,7 +270,6 @@ bool X86ATTAsmParser::ParseMemOperand(X86Operand &Op) {
       if (ParseRegister(Op))
         return true;
       IndexReg = Op.getReg();
-      Scale = 1;      // If not specified, the scale defaults to 1.
     
       if (getLexer().isNot(AsmToken::RParen)) {
         // Parse the scale amount:
@@ -329,11 +351,10 @@ extern "C" void LLVMInitializeX86AsmParser() {
   RegisterAsmParser<X86ATTAsmParser> Y(TheX86_64Target);
 }
 
-// FIXME: These should come from tblgen.
+// FIXME: These should come from tblgen?
 
-// Match_X86_Op_GR8
 static bool 
-Match_X86_Op_GR8(const X86Operand &Op, MCOperand *MCOps, unsigned NumOps) {
+Match_X86_Op_REG(const X86Operand &Op, MCOperand *MCOps, unsigned NumOps) {
   assert(NumOps == 1 && "Invalid number of ops!");
 
   // FIXME: Match correct registers.
@@ -344,6 +365,85 @@ Match_X86_Op_GR8(const X86Operand &Op, MCOperand *MCOps, unsigned NumOps) {
   return false;
 }
 
+static bool 
+Match_X86_Op_IMM(const X86Operand &Op, MCOperand *MCOps, unsigned NumOps) {
+  assert(NumOps == 1 && "Invalid number of ops!");
+
+  // FIXME: We need to check widths.
+  if (Op.Kind != X86Operand::Immediate)
+    return true;
+
+  MCOps[0].MakeMCValue(Op.getImm());
+  return false;
+}
+
+static bool Match_X86_Op_MEM(const X86Operand &Op,
+                             MCOperand *MCOps,
+                             unsigned NumMCOps) {
+  assert(NumMCOps == 5 && "Invalid number of ops!");
+
+  if (Op.Kind != X86Operand::Memory)
+    return true;
+
+  MCOps[0].MakeReg(Op.getMemBaseReg());
+  MCOps[1].MakeImm(Op.getMemScale());
+  MCOps[2].MakeReg(Op.getMemIndexReg());
+  MCOps[3].MakeMCValue(Op.getMemDisp());
+  MCOps[4].MakeReg(Op.getMemSegReg());
+
+  return false;  
+}
+
+#define REG(name) \
+  static bool Match_X86_Op_##name(const X86Operand &Op, \
+                                  MCOperand *MCOps,     \
+                                  unsigned NumMCOps) {  \
+    return Match_X86_Op_REG(Op, MCOps, NumMCOps);       \
+  }
+
+REG(GR64)
+REG(GR32)
+REG(GR16)
+REG(GR8)
+
+#define IMM(name) \
+  static bool Match_X86_Op_##name(const X86Operand &Op, \
+                                  MCOperand *MCOps,     \
+                                  unsigned NumMCOps) {  \
+    return Match_X86_Op_IMM(Op, MCOps, NumMCOps);       \
+  }
+
+IMM(i16i8imm)
+IMM(i16imm)
+IMM(i32i8imm)
+IMM(i32imm)
+IMM(i64i32imm)
+IMM(i64i8imm)
+IMM(i64imm)
+IMM(i8imm)
+
+#define MEM(name) \
+  static bool Match_X86_Op_##name(const X86Operand &Op, \
+                                  MCOperand *MCOps,     \
+                                  unsigned NumMCOps) {  \
+    return Match_X86_Op_MEM(Op, MCOps, NumMCOps);       \
+  }
+
+MEM(f128mem)
+MEM(f32mem)
+MEM(f64mem)
+MEM(f80mem)
+MEM(i128mem)
+MEM(i16mem)
+MEM(i32mem)
+MEM(i64mem)
+MEM(i8mem)
+MEM(lea32mem)
+MEM(lea64_32mem)
+MEM(lea64mem)
+MEM(sdmem)
+MEM(ssmem)
+
 #define DUMMY(name) \
   static bool Match_X86_Op_##name(const X86Operand &Op, \
                                   MCOperand *MCOps,     \
@@ -353,40 +453,15 @@ Match_X86_Op_GR8(const X86Operand &Op, MCOperand *MCOps, unsigned NumOps) {
 
 DUMMY(FR32)
 DUMMY(FR64)
-DUMMY(GR16)
-DUMMY(GR32)
 DUMMY(GR32_NOREX)
-DUMMY(GR64)
 DUMMY(GR8_NOREX)
 DUMMY(RST)
 DUMMY(VR128)
 DUMMY(VR64)
 DUMMY(brtarget)
 DUMMY(brtarget8)
-DUMMY(f128mem)
-DUMMY(f32mem)
-DUMMY(f64mem)
-DUMMY(f80mem)
-DUMMY(i128mem)
-DUMMY(i16i8imm)
-DUMMY(i16imm)
-DUMMY(i16mem)
-DUMMY(i32i8imm)
 DUMMY(i32imm_pcrel)
-DUMMY(i32imm)
-DUMMY(i32mem)
 DUMMY(i64i32imm_pcrel)
-DUMMY(i64i32imm)
-DUMMY(i64i8imm)
-DUMMY(i64imm)
-DUMMY(i64mem)
-DUMMY(i8imm)
 DUMMY(i8mem_NOREX)
-DUMMY(i8mem)
-DUMMY(lea32mem)
-DUMMY(lea64_32mem)
-DUMMY(lea64mem)
-DUMMY(sdmem)
-DUMMY(ssmem)
 
 #include "X86GenAsmMatcher.inc"
index acffd570de8b2146814eb12d1ca0495151b5bfec..7dbe93950c118c52040cbe35cf0f39853acd4291 100644 (file)
@@ -2,6 +2,18 @@
 
 // RUN: llvm-mc -triple i386-unknown-unknown %s > %t
 
-# Simple instructions
-        subb %al, %al
 // RUN: grep {MCInst(opcode=.*, operands=.reg:2, reg:0, reg:2.)} %t
+        subb %al, %al
+
+// RUN: grep {MCInst(opcode=.*, operands=.reg:19, reg:0, val:24.)} %t
+        addl $24, %eax
+
+// RUN: grep {MCInst(opcode=.*, operands=.reg:20, imm:1, reg:0, val:10, reg:0, reg:19.)} %t
+        movl %eax, 10(%ebp)
+// RUN: grep {MCInst(opcode=.*, operands=.reg:20, imm:1, reg:21, val:10, reg:0, reg:19.)} %t
+        movl %eax, 10(%ebp, %ebx)
+// RUN: grep {MCInst(opcode=.*, operands=.reg:20, imm:4, reg:21, val:10, reg:0, reg:19.)} %t
+        movl %eax, 10(%ebp, %ebx, 4)
+// RUN: grep {MCInst(opcode=.*, operands=.reg:0, imm:4, reg:21, val:10, reg:0, reg:19.)} %t
+        movl %eax, 10(, %ebx, 4)
+        
\ No newline at end of file