Index: src/IceInstARM32.cpp |
diff --git a/src/IceInstARM32.cpp b/src/IceInstARM32.cpp |
index 93bbb2769b2db2e1e7027c614765415e557e2856..3b6de8095d1c3067ee2735ace75b5dbad9c5dd65 100644 |
--- a/src/IceInstARM32.cpp |
+++ b/src/IceInstARM32.cpp |
@@ -20,7 +20,6 @@ |
#include "IceCfgNode.h" |
#include "IceInst.h" |
#include "IceOperand.h" |
-#include "IceRegistersARM32.h" |
#include "IceTargetLoweringARM32.h" |
namespace Ice { |
@@ -981,6 +980,134 @@ InstARM32Mov::InstARM32Mov(Cfg *Func, Variable *Dest, Operand *Src, |
} |
} |
+RegARM32::AllRegisters |
+InstARM32ExtractInsert::getDRegister(const Variable *Src) const { |
+ assert(Src->hasReg()); |
+ RegARM32::AllRegisters SrcReg = (RegARM32::AllRegisters)Src->getRegNum(); |
+ |
+ const RegARM32::RegTableType &SrcEntry = RegARM32::RegTable[SrcReg]; |
+ assert(SrcEntry.IsVec128); |
+ |
+ const uint32_t NumElements = typeNumElements(Src->getType()); |
+ |
+ // This code assumes the Aliases list goes Q_n, S_2n, S_2n+1. The asserts in |
+ // the next two branches help to check that this is still true. |
+ if (Index < NumElements / 2) { |
+ // TODO(jpp): find a way to do this that doesn't rely on ordering of the |
+ // alias list. |
+ SrcReg = (RegARM32::AllRegisters)SrcEntry.Aliases[1]; |
+ // We have a Q register that's made up of two D registers. This assert is |
+ // to help ensure that we picked the right D register. |
+ assert(RegARM32::RegTable[SrcEntry.Aliases[1]].Encoding + 1 == |
+ RegARM32::RegTable[SrcEntry.Aliases[2]].Encoding); |
+ } else { |
+ // TODO(jpp): find a way to do this that doesn't rely on ordering of the |
+ // alias list. |
+ SrcReg = (RegARM32::AllRegisters)SrcEntry.Aliases[2]; |
+ // We have a Q register that's made up of two D registers. This assert is |
+ // to help ensure that we picked the right D register. |
+ assert(RegARM32::RegTable[SrcEntry.Aliases[2]].Encoding - 1 == |
+ RegARM32::RegTable[SrcEntry.Aliases[1]].Encoding); |
+ } |
+ return SrcReg; |
+} |
+ |
+uint32_t InstARM32ExtractInsert::getDIndex(uint32_t NumElements) const { |
+ if (Index < NumElements / 2) { |
+ return Index; |
+ } else { |
+ return Index - (NumElements / 2); |
+ } |
+} |
+ |
+RegARM32::AllRegisters |
+InstARM32ExtractInsert::getSRegister(const Variable *Src) const { |
+ assert(Src->hasReg()); |
+ auto SrcReg = Src->getRegNum(); |
+ |
+ // For floating point values, we need to be allocated to Q0 - Q7, so we can |
+ // directly access the value we want as one of the S registers. |
+ assert(Src->getType() == IceType_v4f32 && SrcReg < RegARM32::Reg_q8); |
+ |
+ // This part assumes the register alias list is goes q0, d0, d1, s0, s1, s2, |
+ // s3. |
+ assert(Index < 4); |
+ |
+ // TODO(jpp): find a way to do this that doesn't rely on ordering of the alias |
+ // list. |
+ return (RegARM32::AllRegisters)RegARM32::RegTable[SrcReg].Aliases[Index + 3]; |
+} |
+ |
+void InstARM32Extract::emit(const Cfg *Func) const { |
+ auto &Str = Func->getContext()->getStrEmit(); |
Jim Stichnoth
2016/02/03 22:32:21
Ostream &Str
|
+ auto DestTy = getDest()->getType(); |
Jim Stichnoth
2016/02/03 22:32:21
const Type DestTy
|
+ |
+ auto Src = llvm::dyn_cast<Variable>(getSrc(0)); |
Jim Stichnoth
2016/02/03 22:32:21
auto *
|
+ |
+ if (isIntegerType(DestTy)) { |
+ Str << "\t" |
+ << "vmov" << getPredicate(); |
+ auto BitSize = typeWidthInBytes(DestTy) * CHAR_BIT; |
+ if (BitSize < 32) { |
+ Str << ".s" << BitSize; |
+ } else { |
+ Str << "." << BitSize; |
+ } |
+ Str << "\t"; |
+ getDest()->emit(Func); |
+ Str << ", "; |
+ |
+ auto VectorSize = typeNumElements(Src->getType()); |
+ |
+ auto SrcReg = getDRegister(Src); |
+ |
+ Str << RegARM32::RegTable[SrcReg].Name; |
+ Str << "[" << getDIndex(VectorSize) << "]"; |
+ } else if (isFloatingType(DestTy)) { |
+ auto SrcReg = getSRegister(Src); |
+ |
+ Str << "\t" |
+ << "vmov" << getPredicate() << ".f32" |
+ << "\t"; |
+ getDest()->emit(Func); |
+ Str << ", " << RegARM32::RegTable[SrcReg].Name; |
+ } else { |
+ assert(false && "Invalid extract type"); |
+ } |
+} |
+ |
+void InstARM32Insert::emit(const Cfg *Func) const { |
+ Ostream &Str = Func->getContext()->getStrEmit(); |
+ const Variable *Dest = getDest(); |
+ const Type DestTy = getDest()->getType(); |
+ |
+ assert(llvm::isa<Variable>(getSrc(0))); |
+ auto Src = llvm::dyn_cast<Variable>(getSrc(0)); |
+ |
+ if (isIntegerType(DestTy)) { |
+ Str << "\t" |
+ << "vmov" << getPredicate(); |
+ auto BitSize = typeWidthInBytes(typeElementType(DestTy)) * CHAR_BIT; |
+ Str << "." << BitSize << "\t"; |
+ |
+ auto VectorSize = typeNumElements(DestTy); |
+ auto DestReg = getDRegister(Dest); |
+ auto Index = getDIndex(VectorSize); |
+ Str << RegARM32::RegTable[DestReg].Name; |
+ Str << "[" << Index << "], "; |
+ Src->emit(Func); |
+ } else if (isFloatingType(DestTy)) { |
+ Str << "\t" |
+ << "vmov" << getPredicate() << ".f32" |
+ << "\t"; |
+ auto DestReg = getSRegister(Dest); |
+ Str << RegARM32::RegTable[DestReg].Name << ", "; |
+ Src->emit(Func); |
+ } else { |
+ assert(false && "Invalid insert type"); |
+ } |
+} |
+ |
template <InstARM32::InstKindARM32 K> |
void InstARM32CmpLike<K>::emitIAS(const Cfg *Func) const { |
emitUsingTextFixup(Func); |