Index: src/IceTargetLoweringARM32.cpp |
diff --git a/src/IceTargetLoweringARM32.cpp b/src/IceTargetLoweringARM32.cpp |
index 72ba954e5a1f127952489fc635234ede22d0c013..4f08e5f1815edee0eced24c5b344cedfc8c56ff0 100644 |
--- a/src/IceTargetLoweringARM32.cpp |
+++ b/src/IceTargetLoweringARM32.cpp |
@@ -297,6 +297,7 @@ void TargetARM32::staticInit(GlobalContext *Ctx) { |
llvm::SmallBitVector Float32Registers(RegARM32::Reg_NUM); |
llvm::SmallBitVector Float64Registers(RegARM32::Reg_NUM); |
llvm::SmallBitVector VectorRegisters(RegARM32::Reg_NUM); |
+ llvm::SmallBitVector QtoSRegisters(RegARM32::Reg_NUM); |
llvm::SmallBitVector InvalidRegisters(RegARM32::Reg_NUM); |
for (int i = 0; i < RegARM32::Reg_NUM; ++i) { |
const auto &Entry = RegARM32::RegTable[i]; |
@@ -306,6 +307,7 @@ void TargetARM32::staticInit(GlobalContext *Ctx) { |
Float64Registers[i] = Entry.IsFP64; |
VectorRegisters[i] = Entry.IsVec128; |
RegisterAliases[i].resize(RegARM32::Reg_NUM); |
+ QtoSRegisters[i] = Entry.IsVec128 && i < RegARM32::Reg_q8; |
for (int j = 0; j < Entry.NumAliases; ++j) { |
assert(i == j || !RegisterAliases[i][Entry.Aliases[j]]); |
RegisterAliases[i].set(Entry.Aliases[j]); |
@@ -341,6 +343,7 @@ void TargetARM32::staticInit(GlobalContext *Ctx) { |
TypeToRegisterSet[IceType_v8i16] = VectorRegisters; |
TypeToRegisterSet[IceType_v4i32] = VectorRegisters; |
TypeToRegisterSet[IceType_v4f32] = VectorRegisters; |
+ TypeToRegisterSet[RegARM32::RCARM32_QtoS] = QtoSRegisters; |
for (size_t i = 0; i < llvm::array_lengthof(TypeToRegisterSet); ++i) |
TypeToRegisterSetUnfiltered[i] = TypeToRegisterSet[i]; |
@@ -3830,8 +3833,35 @@ void TargetARM32::lowerCast(const InstCast *Inst) { |
} |
} |
-void TargetARM32::lowerExtractElement(const InstExtractElement *Inst) { |
- UnimplementedLoweringError(this, Inst); |
+void TargetARM32::lowerExtractElement(const InstExtractElement *Instr) { |
+ Variable *Dest = Instr->getDest(); |
+ auto DestTy = Dest->getType(); |
+ |
+ if (Dest->isRematerializable()) { |
+ Context.insert<InstFakeDef>(Dest); |
+ return; |
+ } |
+ |
+ Variable *Src0 = legalizeToReg(Instr->getSrc(0)); |
+ Operand *Src1 = Instr->getSrc(1); |
+ |
+ if (const auto *Imm = llvm::dyn_cast<ConstantInteger32>(Src1)) { |
+ const uint32_t Index = Imm->getValue(); |
+ Variable *T = makeReg(DestTy); |
+ Variable *TSrc0 = makeReg(Src0->getType()); |
Jim Stichnoth
2016/02/03 22:32:21
Bikeshed: the name "TSrc0" strikes me as unlike an
|
+ |
+ if (isFloatingType(DestTy)) { |
+ // We need to make sure the source is in a suitable register. |
+ TSrc0->setRegClass(RegARM32::RCARM32_QtoS); |
Jim Stichnoth
2016/02/03 22:32:21
Another possibility is to move more stuff into thi
John
2016/02/04 15:23:57
+1
|
+ } |
+ |
+ _mov(TSrc0, Src0); |
+ _extractelement(T, TSrc0, Index); |
+ _mov(Dest, T); |
+ return; |
+ } else { |
+ assert(false && "extractelement requires a constant index"); |
+ } |
} |
namespace { |
@@ -4225,8 +4255,34 @@ void TargetARM32::lowerIcmp(const InstIcmp *Inst) { |
return; |
} |
-void TargetARM32::lowerInsertElement(const InstInsertElement *Inst) { |
- UnimplementedLoweringError(this, Inst); |
+void TargetARM32::lowerInsertElement(const InstInsertElement *Instr) { |
+ Variable *Dest = Instr->getDest(); |
+ auto DestTy = Dest->getType(); |
+ |
+ if (Dest->isRematerializable()) { |
+ Context.insert<InstFakeDef>(Dest); |
+ return; |
+ } |
+ |
+ Variable *Src0 = legalizeToReg(Instr->getSrc(0)); |
+ Variable *Src1 = legalizeToReg(Instr->getSrc(1)); |
+ Operand *Src2 = Instr->getSrc(2); |
+ |
+ if (const auto *Imm = llvm::dyn_cast<ConstantInteger32>(Src2)) { |
+ auto Index = Imm->getValue(); |
+ Variable *T = makeReg(DestTy); |
+ |
+ if (isFloatingType(DestTy)) { |
+ T->setRegClass(RegARM32::RCARM32_QtoS); |
+ } |
+ |
+ _mov(T, Src0); |
+ _insertelement(T, Src1, Index); |
+ _set_dest_redefined(); |
+ _mov(Dest, T); |
+ return; |
+ } |
+ assert(false && "insertelement requires a constant index"); |
} |
namespace { |