OSDN Git Service

Add support for floating point immediates to MC instruction printing. ARM
authorJim Grosbach <grosbach@apple.com>
Wed, 15 Sep 2010 18:47:08 +0000 (18:47 +0000)
committerJim Grosbach <grosbach@apple.com>
Wed, 15 Sep 2010 18:47:08 +0000 (18:47 +0000)
VFP instructions use it for loading some constants, so implement that
handling.

Not thrilled with adding a member to MCOperand, but not sure there's much of
a better option that's not pretty fragile (like putting a double in the
union instead and just assuming that's good enough). Suggestions welcome...

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

include/llvm/MC/MCInst.h
lib/Target/ARM/ARMMCInstLower.cpp
lib/Target/ARM/AsmPrinter/ARMInstPrinter.cpp

index bd1b58a..f008b20 100644 (file)
@@ -16,6 +16,7 @@
 #ifndef LLVM_MC_MCINST_H
 #define LLVM_MC_MCINST_H
 
+#include "llvm/ADT/APFloat.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/System/DataTypes.h"
@@ -33,6 +34,7 @@ class MCOperand {
     kInvalid,                 ///< Uninitialized.
     kRegister,                ///< Register operand.
     kImmediate,               ///< Immediate operand.
+    kFPImmediate,             ///< Floating-point immediate operand.
     kExpr                     ///< Relocatable immediate operand.
   };
   unsigned char Kind;
@@ -42,13 +44,17 @@ class MCOperand {
     int64_t ImmVal;
     const MCExpr *ExprVal;
   };
+  // This can't go in the union due to the non-trivial copy constructor
+  // of APFloat. It's still only valid for Kind == kFPImmediate, though.
+  APFloat FPImmVal;
 public:
 
-  MCOperand() : Kind(kInvalid) {}
+  MCOperand() : Kind(kInvalid), FPImmVal(0.0) {}
 
   bool isValid() const { return Kind != kInvalid; }
   bool isReg() const { return Kind == kRegister; }
   bool isImm() const { return Kind == kImmediate; }
+  bool isFPImm() const { return Kind == kFPImmediate; }
   bool isExpr() const { return Kind == kExpr; }
 
   /// getReg - Returns the register number.
@@ -72,6 +78,16 @@ public:
     ImmVal = Val;
   }
 
+  const APFloat &getFPImm() const {
+    assert(isFPImm() && "This is not an FP immediate");
+    return FPImmVal;
+  }
+
+  void setFPImm(const APFloat &Val) {
+    assert(isFPImm() && "This is not an FP immediate");
+    FPImmVal = Val;
+  }
+
   const MCExpr *getExpr() const {
     assert(isExpr() && "This is not an expression");
     return ExprVal;
@@ -93,6 +109,12 @@ public:
     Op.ImmVal = Val;
     return Op;
   }
+  static MCOperand CreateFPImm(const APFloat &Val) {
+    MCOperand Op;
+    Op.Kind = kFPImmediate;
+    Op.FPImmVal = Val;
+    return Op;
+  }
   static MCOperand CreateExpr(const MCExpr *Val) {
     MCOperand Op;
     Op.Kind = kExpr;
index 41af088..b26d327 100644 (file)
@@ -16,6 +16,7 @@
 #include "ARMMCInstLower.h"
 //#include "llvm/CodeGen/MachineModuleInfoImpls.h"
 #include "llvm/CodeGen/AsmPrinter.h"
+#include "llvm/Constants.h"
 #include "llvm/CodeGen/MachineBasicBlock.h"
 #include "llvm/MC/MCAsmInfo.h"
 #include "llvm/MC/MCContext.h"
@@ -155,6 +156,9 @@ void ARMMCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) const {
       MCOp = LowerSymbolOperand(MO, Printer.GetBlockAddressSymbol(
                                               MO.getBlockAddress()));
       break;
+    case MachineOperand::MO_FPImmediate:
+      MCOp = MCOperand::CreateFPImm(MO.getFPImm()->getValueAPF());
+      break;
     }
 
     OutMI.addOperand(MCOp);
index 000108a..344273f 100644 (file)
@@ -729,12 +729,12 @@ void ARMInstPrinter::printT2AddrModeSoRegOperand(const MCInst *MI,
 
 void ARMInstPrinter::printVFPf32ImmOperand(const MCInst *MI, unsigned OpNum,
                                            raw_ostream &O) {
-  O << '#' << MI->getOperand(OpNum).getImm();
+  O << '#' << MI->getOperand(OpNum).getFPImm().convertToFloat();
 }
 
 void ARMInstPrinter::printVFPf64ImmOperand(const MCInst *MI, unsigned OpNum,
                                            raw_ostream &O) {
-  O << '#' << MI->getOperand(OpNum).getImm();
+  O << '#' << MI->getOperand(OpNum).getFPImm().convertToDouble();
 }
 
 void ARMInstPrinter::printNEONModImmOperand(const MCInst *MI, unsigned OpNum,