Chromium Code Reviews| Index: src/IceTargetLoweringARM32.cpp |
| diff --git a/src/IceTargetLoweringARM32.cpp b/src/IceTargetLoweringARM32.cpp |
| index 72ba954e5a1f127952489fc635234ede22d0c013..6c95e4f1f7a2acfe2439c2edd7af5047a6eff43e 100644 |
| --- a/src/IceTargetLoweringARM32.cpp |
| +++ b/src/IceTargetLoweringARM32.cpp |
| @@ -298,6 +298,7 @@ void TargetARM32::staticInit(GlobalContext *Ctx) { |
| llvm::SmallBitVector Float64Registers(RegARM32::Reg_NUM); |
| llvm::SmallBitVector VectorRegisters(RegARM32::Reg_NUM); |
| llvm::SmallBitVector InvalidRegisters(RegARM32::Reg_NUM); |
| + llvm::SmallBitVector QtoSRegisters(RegARM32::Reg_NUM); |
|
Jim Stichnoth
2016/02/03 15:28:37
I would list this before InvalidRegisters.
Eric Holk
2016/02/03 21:02:22
Done.
|
| for (int i = 0; i < RegARM32::Reg_NUM; ++i) { |
| const auto &Entry = RegARM32::RegTable[i]; |
| IntegerRegisters[i] = Entry.IsInt; |
| @@ -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,33 @@ 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); |
|
Jim Stichnoth
2016/02/03 15:28:37
Maybe I haven't thought this through well enough,
John
2016/02/03 16:06:51
Yup, this is wrong. you have to handle these (whic
|
| + return; |
| + } |
| + |
| + Variable *Src0 = legalizeToReg(Instr->getSrc(0)); |
|
Jim Stichnoth
2016/02/03 15:28:38
Optional: It would be nice if InstExtractElement h
|
| + Operand *Src1 = Instr->getSrc(1); |
| + |
| + if (const auto *Imm = llvm::dyn_cast<ConstantInteger32>(Src1)) { |
| + auto Index = Imm->getValue(); |
| + Variable *T = makeReg(DestTy); |
| + |
| + if (isFloatingType(DestTy)) { |
| + // We need to make sure the source is in a suitable register. |
| + Src0->setRegClass(RegARM32::RCARM32_QtoS); |
|
Jim Stichnoth
2016/02/03 15:28:38
It's possible (though unlikely) that legalizeToReg
Eric Holk
2016/02/03 21:02:22
Done.
|
| + } |
| + |
| + _extract(T, Src0, Index); |
| + _mov(Dest, T); |
| + return; |
| + } else { |
| + assert(false && "extract requires a constant index"); |
|
Jim Stichnoth
2016/02/03 15:28:38
s/extract/extractelement
would make a more instant
Eric Holk
2016/02/03 21:02:21
Done.
|
| + } |
| } |
| namespace { |
| @@ -4225,8 +4253,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); |
| + _insert(T, Src1, Index); |
| + _set_dest_redefined(); |
| + _mov(Dest, T); |
| + return; |
| + } |
| + assert(false && "insert requires a constant index"); |
| } |
| namespace { |