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/CodeGen/SSARegMap.h"
|
||||||
#include "llvm/Target/TargetOptions.h"
|
#include "llvm/Target/TargetOptions.h"
|
||||||
#include "llvm/ADT/VectorExtras.h"
|
#include "llvm/ADT/VectorExtras.h"
|
||||||
|
#include "llvm/Support/MathExtras.h"
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
|
||||||
ARMTargetLowering::ARMTargetLowering(TargetMachine &TM)
|
ARMTargetLowering::ARMTargetLowering(TargetMachine &TM)
|
||||||
|
@ -1268,17 +1269,87 @@ ARMTargetLowering::InsertAtEndOfBasicBlock(MachineInstr *MI,
|
||||||
// ARM Optimization Hooks
|
// ARM Optimization Hooks
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
/// isLegalAddressImmediate - Return true if the integer value or
|
/// isLegalAddressImmediate - Return true if the integer value can be used
|
||||||
/// GlobalValue can be used as the offset of the target addressing mode.
|
/// as the offset of the target addressing mode for load / store of the
|
||||||
bool ARMTargetLowering::isLegalAddressImmediate(int64_t V) const {
|
/// given type.
|
||||||
// ARM allows a 12-bit immediate field.
|
bool ARMTargetLowering::isLegalAddressImmediate(int64_t V,const Type *Ty) const{
|
||||||
return V == V & ((1LL << 12) - 1);
|
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 {
|
bool ARMTargetLowering::isLegalAddressImmediate(GlobalValue *GV) const {
|
||||||
return false;
|
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,
|
static bool getIndexedAddressParts(SDNode *Ptr, MVT::ValueType VT,
|
||||||
bool isSEXTLoad, SDOperand &Base,
|
bool isSEXTLoad, SDOperand &Base,
|
||||||
SDOperand &Offset, bool &isInc,
|
SDOperand &Offset, bool &isInc,
|
||||||
|
|
|
@ -80,11 +80,20 @@ namespace llvm {
|
||||||
virtual MachineBasicBlock *InsertAtEndOfBasicBlock(MachineInstr *MI,
|
virtual MachineBasicBlock *InsertAtEndOfBasicBlock(MachineInstr *MI,
|
||||||
MachineBasicBlock *MBB);
|
MachineBasicBlock *MBB);
|
||||||
|
|
||||||
/// isLegalAddressImmediate - Return true if the integer value or
|
/// isLegalAddressImmediate - Return true if the integer value can be used
|
||||||
/// GlobalValue can be used as the offset of the target addressing mode.
|
/// as the offset of the target addressing mode for load / store of the
|
||||||
virtual bool isLegalAddressImmediate(int64_t V) const;
|
/// 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;
|
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
|
/// getPreIndexedAddressParts - returns true by value, base pointer and
|
||||||
/// offset pointer and addressing mode by reference if the node's address
|
/// offset pointer and addressing mode by reference if the node's address
|
||||||
/// can be legally represented as pre-indexed load / store address.
|
/// can be legally represented as pre-indexed load / store address.
|
||||||
|
|
Loading…
Reference in New Issue