Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(936)

Side by Side Diff: src/IceInstARM32.cpp

Issue 1655313002: Subzero: ARM32: lowering of vector insert and extract. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Incorporating review feedback" Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 //===- subzero/src/IceInstARM32.cpp - ARM32 instruction implementation ----===// 1 //===- subzero/src/IceInstARM32.cpp - ARM32 instruction implementation ----===//
2 // 2 //
3 // The Subzero Code Generator 3 // The Subzero Code Generator
4 // 4 //
5 // This file is distributed under the University of Illinois Open Source 5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details. 6 // License. See LICENSE.TXT for details.
7 // 7 //
8 //===----------------------------------------------------------------------===// 8 //===----------------------------------------------------------------------===//
9 /// 9 ///
10 /// \file 10 /// \file
11 /// \brief Implements the InstARM32 and OperandARM32 classes, primarily the 11 /// \brief Implements the InstARM32 and OperandARM32 classes, primarily the
12 /// constructors and the dump()/emit() methods. 12 /// constructors and the dump()/emit() methods.
13 /// 13 ///
14 //===----------------------------------------------------------------------===// 14 //===----------------------------------------------------------------------===//
15 15
16 #include "IceInstARM32.h" 16 #include "IceInstARM32.h"
17 17
18 #include "IceAssemblerARM32.h" 18 #include "IceAssemblerARM32.h"
19 #include "IceCfg.h" 19 #include "IceCfg.h"
20 #include "IceCfgNode.h" 20 #include "IceCfgNode.h"
21 #include "IceInst.h" 21 #include "IceInst.h"
22 #include "IceOperand.h" 22 #include "IceOperand.h"
23 #include "IceRegistersARM32.h"
24 #include "IceTargetLoweringARM32.h" 23 #include "IceTargetLoweringARM32.h"
25 24
26 namespace Ice { 25 namespace Ice {
27 namespace ARM32 { 26 namespace ARM32 {
28 27
29 namespace { 28 namespace {
30 29
31 // maximum number of registers allowed in vpush/vpop. 30 // maximum number of registers allowed in vpush/vpop.
32 static constexpr SizeT VpushVpopMaxConsecRegs = 16; 31 static constexpr SizeT VpushVpopMaxConsecRegs = 16;
33 32
(...skipping 940 matching lines...) Expand 10 before | Expand all | Expand 10 after
974 } 973 }
975 974
976 if (Src64 == nullptr) { 975 if (Src64 == nullptr) {
977 addSource(Src); 976 addSource(Src);
978 } else { 977 } else {
979 addSource(Src64->getLo()); 978 addSource(Src64->getLo());
980 addSource(Src64->getHi()); 979 addSource(Src64->getHi());
981 } 980 }
982 } 981 }
983 982
983 RegARM32::AllRegisters
984 InstARM32ExtractInsert::getDRegister(const Variable *Src) const {
985 assert(Src->hasReg());
986 RegARM32::AllRegisters SrcReg = (RegARM32::AllRegisters)Src->getRegNum();
987
988 const RegARM32::RegTableType &SrcEntry = RegARM32::RegTable[SrcReg];
989 assert(SrcEntry.IsVec128);
990
991 const uint32_t NumElements = typeNumElements(Src->getType());
992
993 // This code assumes the Aliases list goes Q_n, S_2n, S_2n+1. The asserts in
994 // the next two branches help to check that this is still true.
995 if (Index < NumElements / 2) {
996 // TODO(jpp): find a way to do this that doesn't rely on ordering of the
997 // alias list.
998 SrcReg = (RegARM32::AllRegisters)SrcEntry.Aliases[1];
999 // We have a Q register that's made up of two D registers. This assert is
1000 // to help ensure that we picked the right D register.
1001 assert(RegARM32::RegTable[SrcEntry.Aliases[1]].Encoding + 1 ==
1002 RegARM32::RegTable[SrcEntry.Aliases[2]].Encoding);
1003 } else {
1004 // TODO(jpp): find a way to do this that doesn't rely on ordering of the
1005 // alias list.
1006 SrcReg = (RegARM32::AllRegisters)SrcEntry.Aliases[2];
1007 // We have a Q register that's made up of two D registers. This assert is
1008 // to help ensure that we picked the right D register.
1009 assert(RegARM32::RegTable[SrcEntry.Aliases[2]].Encoding - 1 ==
1010 RegARM32::RegTable[SrcEntry.Aliases[1]].Encoding);
1011 }
1012 return SrcReg;
1013 }
1014
1015 uint32_t InstARM32ExtractInsert::getDIndex(uint32_t NumElements) const {
1016 if (Index < NumElements / 2) {
1017 return Index;
1018 } else {
1019 return Index - (NumElements / 2);
1020 }
1021 }
1022
1023 RegARM32::AllRegisters
1024 InstARM32ExtractInsert::getSRegister(const Variable *Src) const {
1025 assert(Src->hasReg());
1026 auto SrcReg = Src->getRegNum();
1027
1028 // For floating point values, we need to be allocated to Q0 - Q7, so we can
1029 // directly access the value we want as one of the S registers.
1030 assert(Src->getType() == IceType_v4f32 && SrcReg < RegARM32::Reg_q8);
1031
1032 // This part assumes the register alias list is goes q0, d0, d1, s0, s1, s2,
1033 // s3.
1034 assert(Index < 4);
1035
1036 // TODO(jpp): find a way to do this that doesn't rely on ordering of the alias
1037 // list.
1038 return (RegARM32::AllRegisters)RegARM32::RegTable[SrcReg].Aliases[Index + 3];
1039 }
1040
1041 void InstARM32Extract::emit(const Cfg *Func) const {
1042 auto &Str = Func->getContext()->getStrEmit();
Jim Stichnoth 2016/02/03 22:32:21 Ostream &Str
1043 auto DestTy = getDest()->getType();
Jim Stichnoth 2016/02/03 22:32:21 const Type DestTy
1044
1045 auto Src = llvm::dyn_cast<Variable>(getSrc(0));
Jim Stichnoth 2016/02/03 22:32:21 auto *
1046
1047 if (isIntegerType(DestTy)) {
1048 Str << "\t"
1049 << "vmov" << getPredicate();
1050 auto BitSize = typeWidthInBytes(DestTy) * CHAR_BIT;
1051 if (BitSize < 32) {
1052 Str << ".s" << BitSize;
1053 } else {
1054 Str << "." << BitSize;
1055 }
1056 Str << "\t";
1057 getDest()->emit(Func);
1058 Str << ", ";
1059
1060 auto VectorSize = typeNumElements(Src->getType());
1061
1062 auto SrcReg = getDRegister(Src);
1063
1064 Str << RegARM32::RegTable[SrcReg].Name;
1065 Str << "[" << getDIndex(VectorSize) << "]";
1066 } else if (isFloatingType(DestTy)) {
1067 auto SrcReg = getSRegister(Src);
1068
1069 Str << "\t"
1070 << "vmov" << getPredicate() << ".f32"
1071 << "\t";
1072 getDest()->emit(Func);
1073 Str << ", " << RegARM32::RegTable[SrcReg].Name;
1074 } else {
1075 assert(false && "Invalid extract type");
1076 }
1077 }
1078
1079 void InstARM32Insert::emit(const Cfg *Func) const {
1080 Ostream &Str = Func->getContext()->getStrEmit();
1081 const Variable *Dest = getDest();
1082 const Type DestTy = getDest()->getType();
1083
1084 assert(llvm::isa<Variable>(getSrc(0)));
1085 auto Src = llvm::dyn_cast<Variable>(getSrc(0));
1086
1087 if (isIntegerType(DestTy)) {
1088 Str << "\t"
1089 << "vmov" << getPredicate();
1090 auto BitSize = typeWidthInBytes(typeElementType(DestTy)) * CHAR_BIT;
1091 Str << "." << BitSize << "\t";
1092
1093 auto VectorSize = typeNumElements(DestTy);
1094 auto DestReg = getDRegister(Dest);
1095 auto Index = getDIndex(VectorSize);
1096 Str << RegARM32::RegTable[DestReg].Name;
1097 Str << "[" << Index << "], ";
1098 Src->emit(Func);
1099 } else if (isFloatingType(DestTy)) {
1100 Str << "\t"
1101 << "vmov" << getPredicate() << ".f32"
1102 << "\t";
1103 auto DestReg = getSRegister(Dest);
1104 Str << RegARM32::RegTable[DestReg].Name << ", ";
1105 Src->emit(Func);
1106 } else {
1107 assert(false && "Invalid insert type");
1108 }
1109 }
1110
984 template <InstARM32::InstKindARM32 K> 1111 template <InstARM32::InstKindARM32 K>
985 void InstARM32CmpLike<K>::emitIAS(const Cfg *Func) const { 1112 void InstARM32CmpLike<K>::emitIAS(const Cfg *Func) const {
986 emitUsingTextFixup(Func); 1113 emitUsingTextFixup(Func);
987 } 1114 }
988 1115
989 template <> void InstARM32Cmn::emitIAS(const Cfg *Func) const { 1116 template <> void InstARM32Cmn::emitIAS(const Cfg *Func) const {
990 assert(getSrcSize() == 2); 1117 assert(getSrcSize() == 2);
991 auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>(); 1118 auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
992 Asm->cmn(getSrc(0), getSrc(1), getPredicate()); 1119 Asm->cmn(getSrc(0), getSrc(1), getPredicate());
993 if (Asm->needsTextFixup()) 1120 if (Asm->needsTextFixup())
(...skipping 1456 matching lines...) Expand 10 before | Expand all | Expand 10 after
2450 2577
2451 template class InstARM32FourAddrGPR<InstARM32::Mla>; 2578 template class InstARM32FourAddrGPR<InstARM32::Mla>;
2452 template class InstARM32FourAddrGPR<InstARM32::Mls>; 2579 template class InstARM32FourAddrGPR<InstARM32::Mls>;
2453 2580
2454 template class InstARM32CmpLike<InstARM32::Cmn>; 2581 template class InstARM32CmpLike<InstARM32::Cmn>;
2455 template class InstARM32CmpLike<InstARM32::Cmp>; 2582 template class InstARM32CmpLike<InstARM32::Cmp>;
2456 template class InstARM32CmpLike<InstARM32::Tst>; 2583 template class InstARM32CmpLike<InstARM32::Tst>;
2457 2584
2458 } // end of namespace ARM32 2585 } // end of namespace ARM32
2459 } // end of namespace Ice 2586 } // end of namespace Ice
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698