The ARM AsmMatcher needs to know that the CCOut operand is a register value,
authorJim Grosbach <grosbach@apple.com>
Mon, 6 Dec 2010 18:21:12 +0000 (18:21 +0000)
committerJim Grosbach <grosbach@apple.com>
Mon, 6 Dec 2010 18:21:12 +0000 (18:21 +0000)
not an immediate. It stores either ARM::CPSR or reg0.

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

lib/Target/ARM/ARMInstrFormats.td
lib/Target/ARM/AsmParser/ARMAsmParser.cpp

index 7948786f406d0dcf58e09f1b7527561e41465e00..c84f1cee2a599b2be0d4772823e4d0612ad2c425 100644 (file)
@@ -143,6 +143,11 @@ def CondCodeOperand : AsmOperandClass {
   let SuperClasses = [];
 }
 
+def CCOutOperand : AsmOperandClass {
+  let Name = "CCOut";
+  let SuperClasses = [];
+}
+
 // ARM Predicate operand. Default to 14 = always (AL). Second part is CC
 // register whose default is 0 (no register).
 def pred : PredicateOperand<OtherVT, (ops i32imm, CCR),
@@ -155,12 +160,14 @@ def pred : PredicateOperand<OtherVT, (ops i32imm, CCR),
 def cc_out : OptionalDefOperand<OtherVT, (ops CCR), (ops (i32 zero_reg))> {
   let EncoderMethod = "getCCOutOpValue";
   let PrintMethod = "printSBitModifierOperand";
+  let ParserMatchClass = CCOutOperand;
 }
 
 // Same as cc_out except it defaults to setting CPSR.
 def s_cc_out : OptionalDefOperand<OtherVT, (ops CCR), (ops (i32 CPSR))> {
   let EncoderMethod = "getCCOutOpValue";
   let PrintMethod = "printSBitModifierOperand";
+  let ParserMatchClass = CCOutOperand;
 }
 
 // ARM special operands for disassembly only.
index 12d892a9fbefcf271e51d84b50872cad2b7c9c0e..c0d282086f3924a0d48fe8feb6f4d27431d2a8c1 100644 (file)
@@ -103,6 +103,7 @@ namespace {
 class ARMOperand : public MCParsedAsmOperand {
   enum KindTy {
     CondCode,
+    CCOut,
     Immediate,
     Memory,
     Register,
@@ -162,6 +163,7 @@ public:
     case Token:
       Tok = o.Tok;
       break;
+    case CCOut:
     case Register:
       Reg = o.Reg;
       break;
@@ -195,7 +197,7 @@ public:
   }
 
   unsigned getReg() const {
-    assert(Kind == Register && "Invalid access!");
+    assert(Kind == Register || Kind == CCOut && "Invalid access!");
     return Reg.RegNum;
   }
 
@@ -211,6 +213,7 @@ public:
   }
 
   bool isCondCode() const { return Kind == CondCode; }
+  bool isCCOut() const { return Kind == CCOut; }
   bool isImm() const { return Kind == Immediate; }
   bool isReg() const { return Kind == Register; }
   bool isRegList() const { return Kind == RegisterList; }
@@ -264,6 +267,11 @@ public:
     Inst.addOperand(MCOperand::CreateReg(0));
   }
 
+  void addCCOutOperands(MCInst &Inst, unsigned N) const {
+    assert(N == 1 && "Invalid number of operands!");
+    Inst.addOperand(MCOperand::CreateReg(getReg()));
+  }
+
   void addRegOperands(MCInst &Inst, unsigned N) const {
     assert(N == 1 && "Invalid number of operands!");
     Inst.addOperand(MCOperand::CreateReg(getReg()));
@@ -341,6 +349,14 @@ public:
     return Op;
   }
 
+  static ARMOperand *CreateCCOut(unsigned RegNum, SMLoc S) {
+    ARMOperand *Op = new ARMOperand(CCOut);
+    Op->Reg.RegNum = RegNum;
+    Op->StartLoc = S;
+    Op->EndLoc = S;
+    return Op;
+  }
+
   static ARMOperand *CreateToken(StringRef Str, SMLoc S) {
     ARMOperand *Op = new ARMOperand(Token);
     Op->Tok.Data = Str.data();
@@ -418,6 +434,9 @@ void ARMOperand::dump(raw_ostream &OS) const {
   case CondCode:
     OS << ARMCondCodeToString(getCondCode());
     break;
+  case CCOut:
+    OS << "<ccout " << getReg() << ">";
+    break;
   case Immediate:
     getImm()->print(OS);
     break;