Add support for floating point immediates to MC instruction printing. ARM

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...

llvm-svn: 113996
This commit is contained in:
Jim Grosbach 2010-09-15 18:47:08 +00:00
parent 970aed92c0
commit 7bbf3fd0d6
3 changed files with 29 additions and 3 deletions

View File

@ -16,6 +16,7 @@
#ifndef LLVM_MC_MCINST_H #ifndef LLVM_MC_MCINST_H
#define LLVM_MC_MCINST_H #define LLVM_MC_MCINST_H
#include "llvm/ADT/APFloat.h"
#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringRef.h"
#include "llvm/System/DataTypes.h" #include "llvm/System/DataTypes.h"
@ -33,6 +34,7 @@ class MCOperand {
kInvalid, ///< Uninitialized. kInvalid, ///< Uninitialized.
kRegister, ///< Register operand. kRegister, ///< Register operand.
kImmediate, ///< Immediate operand. kImmediate, ///< Immediate operand.
kFPImmediate, ///< Floating-point immediate operand.
kExpr ///< Relocatable immediate operand. kExpr ///< Relocatable immediate operand.
}; };
unsigned char Kind; unsigned char Kind;
@ -42,13 +44,17 @@ class MCOperand {
int64_t ImmVal; int64_t ImmVal;
const MCExpr *ExprVal; 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: public:
MCOperand() : Kind(kInvalid) {} MCOperand() : Kind(kInvalid), FPImmVal(0.0) {}
bool isValid() const { return Kind != kInvalid; } bool isValid() const { return Kind != kInvalid; }
bool isReg() const { return Kind == kRegister; } bool isReg() const { return Kind == kRegister; }
bool isImm() const { return Kind == kImmediate; } bool isImm() const { return Kind == kImmediate; }
bool isFPImm() const { return Kind == kFPImmediate; }
bool isExpr() const { return Kind == kExpr; } bool isExpr() const { return Kind == kExpr; }
/// getReg - Returns the register number. /// getReg - Returns the register number.
@ -72,6 +78,16 @@ public:
ImmVal = Val; 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 { const MCExpr *getExpr() const {
assert(isExpr() && "This is not an expression"); assert(isExpr() && "This is not an expression");
return ExprVal; return ExprVal;
@ -93,6 +109,12 @@ public:
Op.ImmVal = Val; Op.ImmVal = Val;
return Op; return Op;
} }
static MCOperand CreateFPImm(const APFloat &Val) {
MCOperand Op;
Op.Kind = kFPImmediate;
Op.FPImmVal = Val;
return Op;
}
static MCOperand CreateExpr(const MCExpr *Val) { static MCOperand CreateExpr(const MCExpr *Val) {
MCOperand Op; MCOperand Op;
Op.Kind = kExpr; Op.Kind = kExpr;

View File

@ -16,6 +16,7 @@
#include "ARMMCInstLower.h" #include "ARMMCInstLower.h"
//#include "llvm/CodeGen/MachineModuleInfoImpls.h" //#include "llvm/CodeGen/MachineModuleInfoImpls.h"
#include "llvm/CodeGen/AsmPrinter.h" #include "llvm/CodeGen/AsmPrinter.h"
#include "llvm/Constants.h"
#include "llvm/CodeGen/MachineBasicBlock.h" #include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCContext.h" #include "llvm/MC/MCContext.h"
@ -155,6 +156,9 @@ void ARMMCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) const {
MCOp = LowerSymbolOperand(MO, Printer.GetBlockAddressSymbol( MCOp = LowerSymbolOperand(MO, Printer.GetBlockAddressSymbol(
MO.getBlockAddress())); MO.getBlockAddress()));
break; break;
case MachineOperand::MO_FPImmediate:
MCOp = MCOperand::CreateFPImm(MO.getFPImm()->getValueAPF());
break;
} }
OutMI.addOperand(MCOp); OutMI.addOperand(MCOp);

View File

@ -729,12 +729,12 @@ void ARMInstPrinter::printT2AddrModeSoRegOperand(const MCInst *MI,
void ARMInstPrinter::printVFPf32ImmOperand(const MCInst *MI, unsigned OpNum, void ARMInstPrinter::printVFPf32ImmOperand(const MCInst *MI, unsigned OpNum,
raw_ostream &O) { raw_ostream &O) {
O << '#' << MI->getOperand(OpNum).getImm(); O << '#' << MI->getOperand(OpNum).getFPImm().convertToFloat();
} }
void ARMInstPrinter::printVFPf64ImmOperand(const MCInst *MI, unsigned OpNum, void ARMInstPrinter::printVFPf64ImmOperand(const MCInst *MI, unsigned OpNum,
raw_ostream &O) { raw_ostream &O) {
O << '#' << MI->getOperand(OpNum).getImm(); O << '#' << MI->getOperand(OpNum).getFPImm().convertToDouble();
} }
void ARMInstPrinter::printNEONModImmOperand(const MCInst *MI, unsigned OpNum, void ARMInstPrinter::printNEONModImmOperand(const MCInst *MI, unsigned OpNum,