forked from OSchip/llvm-project
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:
parent
970aed92c0
commit
7bbf3fd0d6
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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,
|
||||||
|
|
Loading…
Reference in New Issue