Index: src/IceTargetLoweringARM32.cpp |
diff --git a/src/IceTargetLoweringARM32.cpp b/src/IceTargetLoweringARM32.cpp |
index e160a3c61c1df9005e4f3caae84700234e7ad578..37f5e19ed65dee937cd8b01f31877211192f4541 100644 |
--- a/src/IceTargetLoweringARM32.cpp |
+++ b/src/IceTargetLoweringARM32.cpp |
@@ -1628,9 +1628,18 @@ void TargetARM32::lowerIntrinsicCall(const InstIntrinsicCall *Instr) { |
return; |
} |
-void TargetARM32::lowerLoad(const InstLoad *Inst) { |
- (void)Inst; |
- UnimplementedError(Func->getContext()->getFlags()); |
+void TargetARM32::lowerLoad(const InstLoad *Load) { |
+ // A Load instruction can be treated the same as an Assign |
+ // instruction, after the source operand is transformed into an |
+ // OperandARM32Mem operand. |
+ Type Ty = Load->getDest()->getType(); |
+ Operand *Src0 = formMemoryOperand(Load->getSourceAddress(), Ty); |
+ Variable *DestLoad = Load->getDest(); |
+ |
+ // TODO(jvoung): handled folding opportunities. Sign and zero extension |
+ // can be folded into a load. |
+ InstAssign *Assign = InstAssign::create(Func, DestLoad, Src0); |
+ lowerAssign(Assign); |
} |
void TargetARM32::doAddressOptLoad() { |
@@ -1687,8 +1696,22 @@ void TargetARM32::lowerSelect(const InstSelect *Inst) { |
} |
void TargetARM32::lowerStore(const InstStore *Inst) { |
- (void)Inst; |
- UnimplementedError(Func->getContext()->getFlags()); |
+ Operand *Value = Inst->getData(); |
+ Operand *Addr = Inst->getAddr(); |
+ OperandARM32Mem *NewAddr = formMemoryOperand(Addr, Value->getType()); |
+ Type Ty = NewAddr->getType(); |
+ |
+ if (Ty == IceType_i64) { |
+ Variable *ValueHi = legalizeToVar(hiOperand(Value)); |
+ Variable *ValueLo = legalizeToVar(loOperand(Value)); |
+ _str(ValueHi, llvm::cast<OperandARM32Mem>(hiOperand(NewAddr))); |
+ _str(ValueLo, llvm::cast<OperandARM32Mem>(loOperand(NewAddr))); |
+ } else if (isVectorType(Ty)) { |
+ UnimplementedError(Func->getContext()->getFlags()); |
+ } else { |
+ Variable *ValueR = legalizeToVar(Value); |
+ _str(ValueR, NewAddr); |
+ } |
} |
void TargetARM32::doAddressOptStore() { |
@@ -1891,6 +1914,23 @@ Variable *TargetARM32::legalizeToVar(Operand *From, int32_t RegNum) { |
return llvm::cast<Variable>(legalize(From, Legal_Reg, RegNum)); |
} |
+OperandARM32Mem *TargetARM32::formMemoryOperand(Operand *Operand, Type Ty) { |
+ OperandARM32Mem *Mem = llvm::dyn_cast<OperandARM32Mem>(Operand); |
+ // It may be the case that address mode optimization already creates |
+ // an OperandARM32Mem, so in that case it wouldn't need another level |
+ // of transformation. |
+ if (Mem) { |
+ return llvm::cast<OperandARM32Mem>(legalize(Mem)); |
+ } |
+ // If we didn't do address mode optimization, then we only |
+ // have a base/offset to work with. ARM always requires a base |
+ // register, so just use that to hold the operand. |
+ Variable *Base = legalizeToVar(Operand); |
+ return OperandARM32Mem::create( |
+ Func, Ty, Base, |
+ llvm::cast<ConstantInteger32>(Ctx->getConstantZero(IceType_i32))); |
+} |
+ |
Variable *TargetARM32::makeReg(Type Type, int32_t RegNum) { |
// There aren't any 64-bit integer registers for ARM32. |
assert(Type != IceType_i64); |