forked from OSchip/llvm-project
Updated TargetLowering LSR addressing mode hooks for ARM and Thumb.
llvm-svn: 35075
This commit is contained in:
parent
b9dce9db85
commit
2150b9286f
|
@ -30,6 +30,7 @@
|
|||
#include "llvm/CodeGen/SSARegMap.h"
|
||||
#include "llvm/Target/TargetOptions.h"
|
||||
#include "llvm/ADT/VectorExtras.h"
|
||||
#include "llvm/Support/MathExtras.h"
|
||||
using namespace llvm;
|
||||
|
||||
ARMTargetLowering::ARMTargetLowering(TargetMachine &TM)
|
||||
|
@ -1268,17 +1269,87 @@ ARMTargetLowering::InsertAtEndOfBasicBlock(MachineInstr *MI,
|
|||
// ARM Optimization Hooks
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
/// isLegalAddressImmediate - Return true if the integer value or
|
||||
/// GlobalValue can be used as the offset of the target addressing mode.
|
||||
bool ARMTargetLowering::isLegalAddressImmediate(int64_t V) const {
|
||||
// ARM allows a 12-bit immediate field.
|
||||
return V == V & ((1LL << 12) - 1);
|
||||
/// isLegalAddressImmediate - Return true if the integer value can be used
|
||||
/// as the offset of the target addressing mode for load / store of the
|
||||
/// given type.
|
||||
bool ARMTargetLowering::isLegalAddressImmediate(int64_t V,const Type *Ty) const{
|
||||
MVT::ValueType VT = getValueType(Ty);
|
||||
if (Subtarget->isThumb()) {
|
||||
if (V < 0)
|
||||
return false;
|
||||
|
||||
unsigned Scale = 1;
|
||||
switch (VT) {
|
||||
default: return false;
|
||||
case MVT::i1:
|
||||
case MVT::i8:
|
||||
// Scale == 1;
|
||||
break;
|
||||
case MVT::i16:
|
||||
// Scale == 2;
|
||||
Scale = 2;
|
||||
break;
|
||||
case MVT::i32:
|
||||
// Scale == 4;
|
||||
Scale = 4;
|
||||
break;
|
||||
}
|
||||
|
||||
if ((V & (Scale - 1)) != 0)
|
||||
return false;
|
||||
V /= Scale;
|
||||
return V == V & ((1LL << 5) - 1);
|
||||
}
|
||||
|
||||
if (V < 0)
|
||||
V = - V;
|
||||
switch (VT) {
|
||||
default: return false;
|
||||
case MVT::i1:
|
||||
case MVT::i8:
|
||||
case MVT::i32:
|
||||
// +- imm12
|
||||
return V == V & ((1LL << 12) - 1);
|
||||
case MVT::i16:
|
||||
// +- imm8
|
||||
return V == V & ((1LL << 8) - 1);
|
||||
case MVT::f32:
|
||||
case MVT::f64:
|
||||
if (!Subtarget->hasVFP2())
|
||||
return false;
|
||||
if ((V % 3) != 0)
|
||||
return false;
|
||||
V >>= 2;
|
||||
return V == V & ((1LL << 8) - 1);
|
||||
}
|
||||
}
|
||||
|
||||
bool ARMTargetLowering::isLegalAddressImmediate(GlobalValue *GV) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
/// isLegalAddressScale - Return true if the integer value can be used as
|
||||
/// the scale of the target addressing mode for load / store of the given
|
||||
/// type.
|
||||
bool ARMTargetLowering::isLegalAddressScale(int64_t S, const Type *Ty) const {
|
||||
if (Subtarget->isThumb())
|
||||
return false;
|
||||
|
||||
MVT::ValueType VT = getValueType(Ty);
|
||||
switch (VT) {
|
||||
default: return false;
|
||||
case MVT::i1:
|
||||
case MVT::i8:
|
||||
case MVT::i32:
|
||||
// r + r
|
||||
if (S == 2)
|
||||
return true;
|
||||
// r + r << imm
|
||||
S &= ~1;
|
||||
return isPowerOf2_32(S);
|
||||
}
|
||||
}
|
||||
|
||||
static bool getIndexedAddressParts(SDNode *Ptr, MVT::ValueType VT,
|
||||
bool isSEXTLoad, SDOperand &Base,
|
||||
SDOperand &Offset, bool &isInc,
|
||||
|
|
|
@ -80,11 +80,20 @@ namespace llvm {
|
|||
virtual MachineBasicBlock *InsertAtEndOfBasicBlock(MachineInstr *MI,
|
||||
MachineBasicBlock *MBB);
|
||||
|
||||
/// isLegalAddressImmediate - Return true if the integer value or
|
||||
/// GlobalValue can be used as the offset of the target addressing mode.
|
||||
virtual bool isLegalAddressImmediate(int64_t V) const;
|
||||
/// isLegalAddressImmediate - Return true if the integer value can be used
|
||||
/// as the offset of the target addressing mode for load / store of the
|
||||
/// given type.
|
||||
virtual bool isLegalAddressImmediate(int64_t V, const Type *Ty) const;
|
||||
|
||||
/// isLegalAddressImmediate - Return true if the GlobalValue can be used as
|
||||
/// the offset of the target addressing mode.
|
||||
virtual bool isLegalAddressImmediate(GlobalValue *GV) const;
|
||||
|
||||
/// isLegalAddressScale - Return true if the integer value can be used as
|
||||
/// the scale of the target addressing mode for load / store of the given
|
||||
/// type.
|
||||
virtual bool isLegalAddressScale(int64_t S, const Type *Ty) const;
|
||||
|
||||
/// getPreIndexedAddressParts - returns true by value, base pointer and
|
||||
/// offset pointer and addressing mode by reference if the node's address
|
||||
/// can be legally represented as pre-indexed load / store address.
|
||||
|
|
Loading…
Reference in New Issue