Updated TargetLowering LSR addressing mode hooks for ARM and Thumb.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@35075 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Evan Cheng 2007-03-12 23:30:29 +00:00
parent 861939152d
commit b01fad6d19
2 changed files with 88 additions and 8 deletions

View File

@ -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,

View File

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