From b01fad6d19ac83f9c97eee16af438507383f36d8 Mon Sep 17 00:00:00 2001 From: Evan Cheng Date: Mon, 12 Mar 2007 23:30:29 +0000 Subject: [PATCH] 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 --- lib/Target/ARM/ARMISelLowering.cpp | 81 ++++++++++++++++++++++++++++-- lib/Target/ARM/ARMISelLowering.h | 15 ++++-- 2 files changed, 88 insertions(+), 8 deletions(-) diff --git a/lib/Target/ARM/ARMISelLowering.cpp b/lib/Target/ARM/ARMISelLowering.cpp index 55f5c976ce7..2038a3e3aef 100644 --- a/lib/Target/ARM/ARMISelLowering.cpp +++ b/lib/Target/ARM/ARMISelLowering.cpp @@ -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, diff --git a/lib/Target/ARM/ARMISelLowering.h b/lib/Target/ARM/ARMISelLowering.h index 0dbc3d6b32a..7feb2c3ef7b 100644 --- a/lib/Target/ARM/ARMISelLowering.h +++ b/lib/Target/ARM/ARMISelLowering.h @@ -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.