aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Christopher <echristo@apple.com>2010-09-09 00:19:41 +0000
committerEric Christopher <echristo@apple.com>2010-09-09 00:19:41 +0000
commit9ed58dff86f09699946641ba87f6c4f04a3773c8 (patch)
treea620808e819357635624a5d846fc02bd21cc8952
parent63569c99ec944210d0edc687d7411b5c687e97a7 (diff)
Rewrite TargetMaterializeConstant splitting it out into two functions
for integer and fp constants. Implement todo to use vfp3 instructions to materialize easy constants if we can. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@113453 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Target/ARM/ARMFastISel.cpp66
1 files changed, 45 insertions, 21 deletions
diff --git a/lib/Target/ARM/ARMFastISel.cpp b/lib/Target/ARM/ARMFastISel.cpp
index dabfe9c9f2..ca42079eb8 100644
--- a/lib/Target/ARM/ARMFastISel.cpp
+++ b/lib/Target/ARM/ARMFastISel.cpp
@@ -124,6 +124,8 @@ class ARMFastISel : public FastISel {
bool ARMLoadAlloca(const Instruction *I, EVT VT);
bool ARMStoreAlloca(const Instruction *I, unsigned SrcReg, EVT VT);
bool ARMComputeRegOffset(const Value *Obj, unsigned &Reg, int &Offset);
+ unsigned ARMMaterializeFP(const ConstantFP *CFP, EVT VT);
+ unsigned ARMMaterializeInt(const Constant *C);
bool DefinesOptionalPredicate(MachineInstr *MI, bool *CPSR);
const MachineInstrBuilder &AddOptionalDefs(const MachineInstrBuilder &MIB);
@@ -323,18 +325,40 @@ unsigned ARMFastISel::FastEmitInst_extractsubreg(MVT RetVT,
return ResultReg;
}
-unsigned ARMFastISel::TargetMaterializeConstant(const Constant *C) {
- EVT VT = TLI.getValueType(C->getType(), true);
-
- // Only handle simple types.
- if (!VT.isSimple()) return 0;
-
- // Handle double width floating point?
- if (VT.getSimpleVT().SimpleTy == MVT::f64) return 0;
+// For double width floating point we need to materialize two constants
+// (the high and the low) into integer registers then use a move to get
+// the combined constant into an FP reg.
+unsigned ARMFastISel::ARMMaterializeFP(const ConstantFP *CFP, EVT VT) {
+ const APFloat Val = CFP->getValueAPF();
+ bool is64bit = VT.getSimpleVT().SimpleTy == MVT::f64;
- // TODO: Theoretically we could materialize fp constants directly with
- // instructions from VFP3.
+ // This checks to see if we can use VFP3 instructions to materialize
+ // a constant, otherwise we have to go through the constant pool.
+ if (TLI.isFPImmLegal(Val, VT)) {
+ unsigned Opc = is64bit ? ARM::FCONSTD : ARM::FCONSTS;
+ unsigned DestReg = createResultReg(TLI.getRegClassFor(VT));
+ AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(Opc),
+ DestReg)
+ .addFPImm(CFP));
+ return DestReg;
+ }
+
+ // No 64-bit at the moment.
+ if (is64bit) return 0;
+
+ // Load this from the constant pool.
+ unsigned DestReg = ARMMaterializeInt(cast<Constant>(CFP));
+
+ // If we have a floating point constant we expect it in a floating point
+ // register.
+ unsigned MoveReg = createResultReg(TLI.getRegClassFor(VT));
+ AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
+ TII.get(ARM::VMOVRS), MoveReg)
+ .addReg(DestReg));
+ return MoveReg;
+}
+unsigned ARMFastISel::ARMMaterializeInt(const Constant *C) {
// MachineConstantPool wants an explicit alignment.
unsigned Align = TD.getPrefTypeAlignment(C->getType());
if (Align == 0) {
@@ -353,21 +377,21 @@ unsigned ARMFastISel::TargetMaterializeConstant(const Constant *C) {
TII.get(ARM::LDRcp))
.addReg(DestReg).addConstantPoolIndex(Idx)
.addReg(0).addImm(0));
-
- // If we have a floating point constant we expect it in a floating point
- // register.
- // TODO: Make this use ARMBaseInstrInfo::copyPhysReg.
- if (C->getType()->isFloatTy()) {
- unsigned MoveReg = createResultReg(TLI.getRegClassFor(VT));
- AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
- TII.get(ARM::VMOVRS), MoveReg)
- .addReg(DestReg));
- return MoveReg;
- }
return DestReg;
}
+unsigned ARMFastISel::TargetMaterializeConstant(const Constant *C) {
+ EVT VT = TLI.getValueType(C->getType(), true);
+
+ // Only handle simple types.
+ if (!VT.isSimple()) return 0;
+
+ if (const ConstantFP *CFP = dyn_cast<ConstantFP>(C))
+ return ARMMaterializeFP(CFP, VT);
+ return ARMMaterializeInt(C);
+}
+
bool ARMFastISel::isTypeLegal(const Type *Ty, EVT &VT) {
VT = TLI.getValueType(Ty, true);