Index: src/IceTargetLoweringARM32.h |
diff --git a/src/IceTargetLoweringARM32.h b/src/IceTargetLoweringARM32.h |
index 6085eed48b016b3459e4dd343a5413eeee002077..a1f37a639e913437252ddafcc8b6d65b531b36a5 100644 |
--- a/src/IceTargetLoweringARM32.h |
+++ b/src/IceTargetLoweringARM32.h |
@@ -189,7 +189,6 @@ protected: |
// The following are helpers that insert lowered ARM32 instructions with |
// minimal syntactic overhead, so that the lowering code can look as close to |
// assembly as practical. |
- |
void _add(Variable *Dest, Variable *Src0, Operand *Src1, |
CondARM32::Cond Pred = CondARM32::AL) { |
Context.insert(InstARM32Add::create(Func, Dest, Src0, Src1, Pred)); |
@@ -246,6 +245,10 @@ protected: |
CondARM32::Cond Pred = CondARM32::AL) { |
Context.insert(InstARM32Eor::create(Func, Dest, Src0, Src1, Pred)); |
} |
+ /// _ldr, for all your memory to Variable data moves. It handles all types |
+ /// (integer, floating point, and vectors.) Addr needs to be valid for Dest's |
+ /// type (e.g., no immediates for vector loads, and no index registers for fp |
+ /// loads.) |
void _ldr(Variable *Dest, OperandARM32Mem *Addr, |
CondARM32::Cond Pred = CondARM32::AL) { |
Context.insert(InstARM32Ldr::create(Func, Dest, Addr, Pred)); |
@@ -266,14 +269,17 @@ protected: |
CondARM32::Cond Pred = CondARM32::AL) { |
Context.insert(InstARM32Mls::create(Func, Dest, Src0, Src1, Acc, Pred)); |
} |
- /// If Dest=nullptr is passed in, then a new variable is created, marked as |
- /// infinite register allocation weight, and returned through the in/out Dest |
- /// argument. |
- void _mov(Variable *&Dest, Operand *Src0, |
- CondARM32::Cond Pred = CondARM32::AL, |
- int32_t RegNum = Variable::NoRegister) { |
- if (Dest == nullptr) |
- Dest = makeReg(Src0->getType(), RegNum); |
+ /// _mov, for all your Variable to Variable data movement needs. It handles |
+ /// all types (integer, floating point, and vectors), as well as moves between |
+ /// Core and VFP registers. This is not a panacea: you must obey the (weird, |
+ /// confusing, non-uniform) rules for data moves in ARM. |
+ void _mov(Variable *Dest, Operand *Src0, |
+ CondARM32::Cond Pred = CondARM32::AL) { |
+ // _mov used to be unique in the sense that it would create a temporary |
+ // automagically if Dest was nullptr. It won't do that anymore, so we keep |
+ // an assert around just in case there is some untested code path where Dest |
+ // is nullptr. |
+ assert(Dest != nullptr); |
Context.insert(InstARM32Mov::create(Func, Dest, Src0, Pred)); |
} |
void _mov_nonkillable(Variable *Dest, Operand *Src0, |
@@ -348,6 +354,8 @@ protected: |
CondARM32::Cond Pred = CondARM32::AL) { |
Context.insert(InstARM32Sdiv::create(Func, Dest, Src0, Src1, Pred)); |
} |
+ /// _str, for all your Variable to memory transfers. Addr has the same |
+ /// restrictions that it does in _ldr. |
void _str(Variable *Value, OperandARM32Mem *Addr, |
CondARM32::Cond Pred = CondARM32::AL) { |
Context.insert(InstARM32Str::create(Func, Value, Addr, Pred)); |
@@ -387,6 +395,10 @@ protected: |
CondARM32::Cond Pred = CondARM32::AL) { |
Context.insert(InstARM32Uxt::create(Func, Dest, Src0, Pred)); |
} |
+ void _vabs(Variable *Dest, Variable *Src, |
+ CondARM32::Cond Pred = CondARM32::AL) { |
+ Context.insert(InstARM32Vabs::create(Func, Dest, Src, Pred)); |
+ } |
void _vadd(Variable *Dest, Variable *Src0, Variable *Src1) { |
Context.insert(InstARM32Vadd::create(Func, Dest, Src0, Src1)); |
} |
@@ -397,10 +409,6 @@ protected: |
void _vdiv(Variable *Dest, Variable *Src0, Variable *Src1) { |
Context.insert(InstARM32Vdiv::create(Func, Dest, Src0, Src1)); |
} |
- void _vldr(Variable *Dest, OperandARM32Mem *Src, |
- CondARM32::Cond Pred = CondARM32::AL) { |
- Context.insert(InstARM32Vldr::create(Func, Dest, Src, Pred)); |
- } |
void _vcmp(Variable *Src0, Variable *Src1, |
CondARM32::Cond Pred = CondARM32::AL) { |
Context.insert(InstARM32Vcmp::create(Func, Src0, Src1, Pred)); |
@@ -408,33 +416,6 @@ protected: |
void _vmrs(CondARM32::Cond Pred = CondARM32::AL) { |
Context.insert(InstARM32Vmrs::create(Func, Pred)); |
} |
- // There are a whole bunch of vmov variants, to transfer within S/D/Q |
- // registers, between core integer registers and S/D, and from small |
- // immediates into S/D. For integer -> S/D/Q there is a variant which takes |
- // two integer register to fill a D, or to fill two consecutive S registers. |
- // Vmov can also be used to insert-element. E.g., |
- // "vmov.8 d0[1], r0" |
- // but insert-element is a "two-address" operation where only part of the |
- // register is modified. This cannot model that. |
- // |
- // This represents the simple single source, single dest variants only. |
- void _vmov(Variable *Dest, Operand *Src0, |
- CondARM32::Cond Pred = CondARM32::AL) { |
- Context.insert(InstARM32Vmov::create(Func, Dest, Src0, Pred)); |
- } |
- // This represents the single source, multi dest variant. |
- void _vmov(InstARM32Vmov::RegisterPair Dests, Variable *Src0) { |
- constexpr CondARM32::Cond Pred = CondARM32::AL; |
- Context.insert(InstARM32Vmov::create(Func, Dests, Src0, Pred)); |
- // The Vmov instruction created above does not define Dests._1. Therefore |
- // we add a Dest._1 = FakeDef pseudo instruction. |
- Context.insert(InstFakeDef::create(Func, Dests._1)); |
- } |
- // This represents the multi source, single dest variant. |
- void _vmov(Variable *Dest, InstARM32Vmov::RegisterPair Srcs) { |
- constexpr CondARM32::Cond Pred = CondARM32::AL; |
- Context.insert(InstARM32Vmov::create(Func, Dest, Srcs, Pred)); |
- } |
void _vmul(Variable *Dest, Variable *Src0, Variable *Src1) { |
Context.insert(InstARM32Vmul::create(Func, Dest, Src0, Src1)); |
} |
@@ -451,10 +432,11 @@ protected: |
/// offset, such that the addressing mode offset bits are now legal. |
void legalizeStackSlots(); |
/// Returns true if the given Offset can be represented in a stack ldr/str. |
- bool isLegalVariableStackOffset(int32_t Offset) const; |
+ bool isLegalVariableStackOffset(Type Ty, int32_t Offset) const; |
/// Assuming Var needs its offset legalized, define a new base register |
- /// centered on the given Var's offset and use it. |
- StackVariable *legalizeVariableSlot(Variable *Var, Variable *OrigBaseReg); |
+ /// centered on the given Var's offset plus StackAdjust, and use it. |
+ StackVariable *legalizeVariableSlot(Variable *Var, int32_t StackAdjust, |
+ Variable *OrigBaseReg); |
TargetARM32Features CPUFeatures; |
bool UsesFramePointer = false; |