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

Side by Side Diff: src/IceInstARM32.cpp

Issue 1881623002: Subzero. ARM32. Vector shifts. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Pre-review pass. Created 4 years, 8 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
(...skipping 15 matching lines...) Expand all
26 namespace ARM32 { 26 namespace ARM32 {
27 27
28 namespace { 28 namespace {
29 29
30 using Register = RegARM32::AllRegisters; 30 using Register = RegARM32::AllRegisters;
31 31
32 // maximum number of registers allowed in vpush/vpop. 32 // maximum number of registers allowed in vpush/vpop.
33 static constexpr SizeT VpushVpopMaxConsecRegs = 16; 33 static constexpr SizeT VpushVpopMaxConsecRegs = 16;
34 34
35 const struct TypeARM32Attributes_ { 35 const struct TypeARM32Attributes_ {
36 const char *WidthString; // b, h, <blank>, or d 36 const char *WidthString; // b, h, <blank>, or d
37 const char *VecWidthString; // i8, i16, i32, f32, f64 37 const char *FpWidthString; // i8, i16, i32, f32, f64
38 const char *SVecWidthString; // s8, s16, s32, f32
39 const char *UVecWidthString; // u8, u16, u32, f32
38 int8_t SExtAddrOffsetBits; 40 int8_t SExtAddrOffsetBits;
39 int8_t ZExtAddrOffsetBits; 41 int8_t ZExtAddrOffsetBits;
40 } TypeARM32Attributes[] = { 42 } TypeARM32Attributes[] = {
41 #define X(tag, elementty, int_width, vec_width, sbits, ubits, rraddr, shaddr) \ 43 #define X(tag, elementty, int_width, fp_width, uvec_width, svec_width, sbits, \
42 { int_width, vec_width, sbits, ubits } \ 44 ubits, rraddr, shaddr) \
45 { int_width, fp_width, svec_width, uvec_width, sbits, ubits } \
43 , 46 ,
44 ICETYPEARM32_TABLE 47 ICETYPEARM32_TABLE
45 #undef X 48 #undef X
46 }; 49 };
47 50
48 const struct InstARM32ShiftAttributes_ { 51 const struct InstARM32ShiftAttributes_ {
49 const char *EmitString; 52 const char *EmitString;
50 } InstARM32ShiftAttributes[] = { 53 } InstARM32ShiftAttributes[] = {
51 #define X(tag, emit) \ 54 #define X(tag, emit) \
52 { emit } \ 55 { emit } \
(...skipping 10 matching lines...) Expand all
63 { CondARM32::opp, emit } \ 66 { CondARM32::opp, emit } \
64 , 67 ,
65 ICEINSTARM32COND_TABLE 68 ICEINSTARM32COND_TABLE
66 #undef X 69 #undef X
67 }; 70 };
68 71
69 size_t getVecElmtBitsize(Type Ty) { 72 size_t getVecElmtBitsize(Type Ty) {
70 return typeWidthInBytes(typeElementType(Ty)) * CHAR_BIT; 73 return typeWidthInBytes(typeElementType(Ty)) * CHAR_BIT;
71 } 74 }
72 75
73 } // end of anonymous namespace 76 const char *getWidthString(Type Ty) {
74
75 const char *InstARM32::getWidthString(Type Ty) {
76 return TypeARM32Attributes[Ty].WidthString; 77 return TypeARM32Attributes[Ty].WidthString;
77 } 78 }
78 79
79 const char *InstARM32::getVecWidthString(Type Ty) { 80 const char *getFpWidthString(Type Ty) {
80 return TypeARM32Attributes[Ty].VecWidthString; 81 return TypeARM32Attributes[Ty].FpWidthString;
81 } 82 }
82 83
84 const char *getSVecWidthString(Type Ty) {
85 return TypeARM32Attributes[Ty].SVecWidthString;
86 }
87
88 const char *getUVecWidthString(Type Ty) {
89 return TypeARM32Attributes[Ty].UVecWidthString;
90 }
91 } // end of anonymous namespace
92
83 const char *InstARM32Pred::predString(CondARM32::Cond Pred) { 93 const char *InstARM32Pred::predString(CondARM32::Cond Pred) {
84 return InstARM32CondAttributes[Pred].EmitString; 94 return InstARM32CondAttributes[Pred].EmitString;
85 } 95 }
86 96
87 void InstARM32Pred::dumpOpcodePred(Ostream &Str, const char *Opcode, 97 void InstARM32Pred::dumpOpcodePred(Ostream &Str, const char *Opcode,
88 Type Ty) const { 98 Type Ty) const {
89 Str << Opcode << getPredicate() << "." << Ty; 99 Str << Opcode << getPredicate() << "." << Ty;
90 } 100 }
91 101
92 CondARM32::Cond InstARM32::getOppositeCondition(CondARM32::Cond Cond) { 102 CondARM32::Cond InstARM32::getOppositeCondition(CondARM32::Cond Cond) {
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
143 Type SrcTy = Instr->getSrc(0)->getType(); 153 Type SrcTy = Instr->getSrc(0)->getType();
144 Str << "\t" << Opcode; 154 Str << "\t" << Opcode;
145 if (NeedsWidthSuffix) 155 if (NeedsWidthSuffix)
146 Str << getWidthString(SrcTy); 156 Str << getWidthString(SrcTy);
147 Str << Instr->getPredicate() << "\t"; 157 Str << Instr->getPredicate() << "\t";
148 Instr->getDest()->emit(Func); 158 Instr->getDest()->emit(Func);
149 Str << ", "; 159 Str << ", ";
150 Instr->getSrc(0)->emit(Func); 160 Instr->getSrc(0)->emit(Func);
151 } 161 }
152 162
153 void InstARM32Pred::emitUnaryopFP(const char *Opcode, 163 void InstARM32Pred::emitUnaryopFP(const char *Opcode, FPSign Sign,
154 const InstARM32Pred *Instr, const Cfg *Func) { 164 const InstARM32Pred *Instr, const Cfg *Func) {
155 Ostream &Str = Func->getContext()->getStrEmit(); 165 Ostream &Str = Func->getContext()->getStrEmit();
156 assert(Instr->getSrcSize() == 1); 166 assert(Instr->getSrcSize() == 1);
157 Type SrcTy = Instr->getSrc(0)->getType(); 167 Type SrcTy = Instr->getSrc(0)->getType();
158 Str << "\t" << Opcode << Instr->getPredicate() << getVecWidthString(SrcTy) 168 Str << "\t" << Opcode << Instr->getPredicate();
159 << "\t"; 169 switch (Sign) {
170 case FS_None:
171 Str << getFpWidthString(SrcTy);
172 break;
173 case FS_Signed:
174 Str << getSVecWidthString(SrcTy);
175 break;
176 case FS_Unsigned:
177 Str << getUVecWidthString(SrcTy);
178 break;
179 }
180 Str << "\t";
160 Instr->getDest()->emit(Func); 181 Instr->getDest()->emit(Func);
161 Str << ", "; 182 Str << ", ";
162 Instr->getSrc(0)->emit(Func); 183 Instr->getSrc(0)->emit(Func);
163 } 184 }
164 185
165 void InstARM32Pred::emitTwoAddr(const char *Opcode, const InstARM32Pred *Instr, 186 void InstARM32Pred::emitTwoAddr(const char *Opcode, const InstARM32Pred *Instr,
166 const Cfg *Func) { 187 const Cfg *Func) {
167 if (!BuildDefs::dump()) 188 if (!BuildDefs::dump())
168 return; 189 return;
169 Ostream &Str = Func->getContext()->getStrEmit(); 190 Ostream &Str = Func->getContext()->getStrEmit();
(...skipping 15 matching lines...) Expand all
185 assert(Instr->getSrcSize() == 2); 206 assert(Instr->getSrcSize() == 2);
186 Str << "\t" << Opcode << (SetFlags ? "s" : "") << Instr->getPredicate() 207 Str << "\t" << Opcode << (SetFlags ? "s" : "") << Instr->getPredicate()
187 << "\t"; 208 << "\t";
188 Instr->getDest()->emit(Func); 209 Instr->getDest()->emit(Func);
189 Str << ", "; 210 Str << ", ";
190 Instr->getSrc(0)->emit(Func); 211 Instr->getSrc(0)->emit(Func);
191 Str << ", "; 212 Str << ", ";
192 Instr->getSrc(1)->emit(Func); 213 Instr->getSrc(1)->emit(Func);
193 } 214 }
194 215
195 void InstARM32::emitThreeAddrFP(const char *Opcode, const InstARM32 *Instr, 216 void InstARM32::emitThreeAddrFP(const char *Opcode, FPSign SignType,
196 const Cfg *Func) { 217 const InstARM32 *Instr, const Cfg *Func) {
197 if (!BuildDefs::dump()) 218 if (!BuildDefs::dump())
198 return; 219 return;
199 Ostream &Str = Func->getContext()->getStrEmit(); 220 Ostream &Str = Func->getContext()->getStrEmit();
200 assert(Instr->getSrcSize() == 2); 221 assert(Instr->getSrcSize() == 2);
201 Str << "\t" << Opcode << getVecWidthString(Instr->getDest()->getType()) 222 Str << "\t" << Opcode;
202 << "\t"; 223 switch (SignType) {
Karl 2016/04/13 16:17:36 This switch appears in multiple places. Consider f
John 2016/04/15 13:20:56 Done.
224 case FS_None:
225 Str << getFpWidthString(Instr->getDest()->getType());
226 break;
227 case FS_Signed:
228 Str << getSVecWidthString(Instr->getDest()->getType());
229 break;
230 case FS_Unsigned:
231 Str << getUVecWidthString(Instr->getDest()->getType());
232 break;
233 }
234 Str << "\t";
203 Instr->getDest()->emit(Func); 235 Instr->getDest()->emit(Func);
204 Str << ", "; 236 Str << ", ";
205 Instr->getSrc(0)->emit(Func); 237 Instr->getSrc(0)->emit(Func);
206 Str << ", "; 238 Str << ", ";
207 Instr->getSrc(1)->emit(Func); 239 Instr->getSrc(1)->emit(Func);
208 } 240 }
209 241
210 void InstARM32::emitFourAddrFP(const char *Opcode, const InstARM32 *Instr, 242 void InstARM32::emitFourAddrFP(const char *Opcode, FPSign SignType,
211 const Cfg *Func) { 243 const InstARM32 *Instr, const Cfg *Func) {
212 if (!BuildDefs::dump()) 244 if (!BuildDefs::dump())
213 return; 245 return;
214 Ostream &Str = Func->getContext()->getStrEmit(); 246 Ostream &Str = Func->getContext()->getStrEmit();
215 assert(Instr->getSrcSize() == 3); 247 assert(Instr->getSrcSize() == 3);
216 assert(Instr->getSrc(0) == Instr->getDest()); 248 assert(Instr->getSrc(0) == Instr->getDest());
217 Str << "\t" << Opcode << getVecWidthString(Instr->getDest()->getType()) 249 Str << "\t" << Opcode;
218 << "\t"; 250 switch (SignType) {
251 case FS_None:
252 Str << getFpWidthString(Instr->getDest()->getType());
253 break;
254 case FS_Signed:
255 Str << getSVecWidthString(Instr->getDest()->getType());
256 break;
257 case FS_Unsigned:
258 Str << getUVecWidthString(Instr->getDest()->getType());
259 break;
260 }
261 Str << "\t";
219 Instr->getDest()->emit(Func); 262 Instr->getDest()->emit(Func);
220 Str << ", "; 263 Str << ", ";
221 Instr->getSrc(1)->emit(Func); 264 Instr->getSrc(1)->emit(Func);
222 Str << ", "; 265 Str << ", ";
223 Instr->getSrc(2)->emit(Func); 266 Instr->getSrc(2)->emit(Func);
224 } 267 }
225 268
226 void InstARM32Pred::emitFourAddr(const char *Opcode, const InstARM32Pred *Instr, 269 void InstARM32Pred::emitFourAddr(const char *Opcode, const InstARM32Pred *Instr,
227 const Cfg *Func) { 270 const Cfg *Func) {
228 if (!BuildDefs::dump()) 271 if (!BuildDefs::dump())
(...skipping 18 matching lines...) Expand all
247 template <InstARM32::InstKindARM32 K> 290 template <InstARM32::InstKindARM32 K>
248 void InstARM32FourAddrFP<K>::emitIAS(const Cfg *Func) const { 291 void InstARM32FourAddrFP<K>::emitIAS(const Cfg *Func) const {
249 emitUsingTextFixup(Func); 292 emitUsingTextFixup(Func);
250 } 293 }
251 294
252 template <InstARM32::InstKindARM32 K> 295 template <InstARM32::InstKindARM32 K>
253 void InstARM32ThreeAddrFP<K>::emitIAS(const Cfg *Func) const { 296 void InstARM32ThreeAddrFP<K>::emitIAS(const Cfg *Func) const {
254 emitUsingTextFixup(Func); 297 emitUsingTextFixup(Func);
255 } 298 }
256 299
300 template <InstARM32::InstKindARM32 K>
301 void InstARM32ThreeAddrSignAwareFP<K>::emitIAS(const Cfg *Func) const {
302 InstARM32::emitUsingTextFixup(Func);
303 }
304
257 template <> void InstARM32Mla::emitIAS(const Cfg *Func) const { 305 template <> void InstARM32Mla::emitIAS(const Cfg *Func) const {
258 assert(getSrcSize() == 3); 306 assert(getSrcSize() == 3);
259 auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>(); 307 auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
260 Asm->mla(getDest(), getSrc(0), getSrc(1), getSrc(2), getPredicate()); 308 Asm->mla(getDest(), getSrc(0), getSrc(1), getSrc(2), getPredicate());
261 if (Asm->needsTextFixup()) 309 if (Asm->needsTextFixup())
262 emitUsingTextFixup(Func); 310 emitUsingTextFixup(Func);
263 } 311 }
264 312
265 template <> void InstARM32Mls::emitIAS(const Cfg *Func) const { 313 template <> void InstARM32Mls::emitIAS(const Cfg *Func) const {
266 assert(getSrcSize() == 3); 314 assert(getSrcSize() == 3);
(...skipping 463 matching lines...) Expand 10 before | Expand all | Expand 10 after
730 Asm->vmlss(getDest(), getSrc(1), getSrc(2), CondARM32::AL); 778 Asm->vmlss(getDest(), getSrc(1), getSrc(2), CondARM32::AL);
731 assert(!Asm->needsTextFixup()); 779 assert(!Asm->needsTextFixup());
732 return; 780 return;
733 case IceType_f64: 781 case IceType_f64:
734 Asm->vmlsd(getDest(), getSrc(1), getSrc(2), CondARM32::AL); 782 Asm->vmlsd(getDest(), getSrc(1), getSrc(2), CondARM32::AL);
735 assert(!Asm->needsTextFixup()); 783 assert(!Asm->needsTextFixup());
736 return; 784 return;
737 } 785 }
738 } 786 }
739 787
788 template <> void InstARM32Vneg::emitIAS(const Cfg *Func) const {
789 auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
790 const Variable *Dest = getDest();
791 const Type DestTy = Dest->getType();
792 switch (Dest->getType()) {
793 default:
794 llvm::report_fatal_error("Vneg not defined on type " +
795 typeStdString(Dest->getType()));
796 case IceType_v4i1:
797 case IceType_v8i1:
798 case IceType_v16i1:
799 case IceType_v16i8:
800 case IceType_v8i16:
801 case IceType_v4i32:
802 case IceType_v4f32: {
803 const Type ElmtTy = typeElementType(DestTy);
804 Asm->vnegqs(ElmtTy, Dest, getSrc(0));
Karl 2016/04/13 16:17:36 Is it necessary to factor out ElmtTy here and pass
John 2016/04/15 13:20:56 No, it is not, but there is precedent in this file
805 } break;
806 }
807 }
808
740 template <> void InstARM32Vorr::emitIAS(const Cfg *Func) const { 809 template <> void InstARM32Vorr::emitIAS(const Cfg *Func) const {
741 auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>(); 810 auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
742 const Variable *Dest = getDest(); 811 const Variable *Dest = getDest();
743 switch (Dest->getType()) { 812 switch (Dest->getType()) {
744 default: 813 default:
745 llvm::report_fatal_error("Vorr not defined on type " + 814 llvm::report_fatal_error("Vorr not defined on type " +
746 typeStdString(Dest->getType())); 815 typeStdString(Dest->getType()));
747 case IceType_v4i1: 816 case IceType_v4i1:
748 case IceType_v8i1: 817 case IceType_v8i1:
749 case IceType_v16i1: 818 case IceType_v16i1:
750 case IceType_v16i8: 819 case IceType_v16i8:
751 case IceType_v8i16: 820 case IceType_v8i16:
752 case IceType_v4i32: 821 case IceType_v4i32:
753 Asm->vorrq(Dest, getSrc(0), getSrc(1)); 822 Asm->vorrq(Dest, getSrc(0), getSrc(1));
754 } 823 }
755 assert(!Asm->needsTextFixup()); 824 assert(!Asm->needsTextFixup());
756 } 825 }
757 826
827 template <> void InstARM32Vshl::emitIAS(const Cfg *Func) const {
828 auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
829 const Variable *Dest = getDest();
830 const Type DestTy = Dest->getType();
831 switch (DestTy) {
832 default:
833 llvm::report_fatal_error("Vshl not defined on type " +
834 typeStdString(Dest->getType()));
835 case IceType_v4i1:
836 case IceType_v8i1:
837 case IceType_v16i1:
838 case IceType_v16i8:
839 case IceType_v8i16:
840 case IceType_v4i32: {
841 const Type ElmtTy = typeElementType(DestTy);
842 assert(Sign != InstARM32::FS_None);
843 switch (Sign) {
844 case InstARM32::FS_None: // defaults to unsigned.
845 case InstARM32::FS_Unsigned:
846 Asm->vshlqu(ElmtTy, Dest, getSrc(0), getSrc(1));
Karl 2016/04/13 16:17:36 Similar question here. Should we be forcing the pa
John 2016/04/15 13:20:56 Acknowledged.
847 break;
848 case InstARM32::FS_Signed:
849 Asm->vshlqi(ElmtTy, Dest, getSrc(0), getSrc(1));
850 break;
851 }
852 } break;
853 }
854 }
855
758 template <> void InstARM32Vsub::emitIAS(const Cfg *Func) const { 856 template <> void InstARM32Vsub::emitIAS(const Cfg *Func) const {
759 auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>(); 857 auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
760 const Variable *Dest = getDest(); 858 const Variable *Dest = getDest();
761 Type DestTy = Dest->getType(); 859 Type DestTy = Dest->getType();
762 switch (DestTy) { 860 switch (DestTy) {
763 default: 861 default:
764 llvm::report_fatal_error("Vsub not defined on type " + 862 llvm::report_fatal_error("Vsub not defined on type " +
765 typeStdString(DestTy)); 863 typeStdString(DestTy));
766 case IceType_v16i8: 864 case IceType_v16i8:
767 case IceType_v8i16: 865 case IceType_v8i16:
(...skipping 599 matching lines...) Expand 10 before | Expand all | Expand 10 after
1367 template <> const char *InstARM32Udiv::Opcode = "udiv"; 1465 template <> const char *InstARM32Udiv::Opcode = "udiv";
1368 // FP 1466 // FP
1369 template <> const char *InstARM32Vadd::Opcode = "vadd"; 1467 template <> const char *InstARM32Vadd::Opcode = "vadd";
1370 template <> const char *InstARM32Vand::Opcode = "vand"; 1468 template <> const char *InstARM32Vand::Opcode = "vand";
1371 template <> const char *InstARM32Vdiv::Opcode = "vdiv"; 1469 template <> const char *InstARM32Vdiv::Opcode = "vdiv";
1372 template <> const char *InstARM32Veor::Opcode = "veor"; 1470 template <> const char *InstARM32Veor::Opcode = "veor";
1373 template <> const char *InstARM32Vmla::Opcode = "vmla"; 1471 template <> const char *InstARM32Vmla::Opcode = "vmla";
1374 template <> const char *InstARM32Vmls::Opcode = "vmls"; 1472 template <> const char *InstARM32Vmls::Opcode = "vmls";
1375 template <> const char *InstARM32Vmul::Opcode = "vmul"; 1473 template <> const char *InstARM32Vmul::Opcode = "vmul";
1376 template <> const char *InstARM32Vorr::Opcode = "vorr"; 1474 template <> const char *InstARM32Vorr::Opcode = "vorr";
1475 template <> const char *InstARM32UnaryopFP<InstARM32::Vneg>::Opcode = "vneg";
1476 template <> const char *InstARM32ThreeAddrFP<InstARM32::Vshl>::Opcode = "vshl";
1377 template <> const char *InstARM32Vsub::Opcode = "vsub"; 1477 template <> const char *InstARM32Vsub::Opcode = "vsub";
1378 // Four-addr ops 1478 // Four-addr ops
1379 template <> const char *InstARM32Mla::Opcode = "mla"; 1479 template <> const char *InstARM32Mla::Opcode = "mla";
1380 template <> const char *InstARM32Mls::Opcode = "mls"; 1480 template <> const char *InstARM32Mls::Opcode = "mls";
1381 // Cmp-like ops 1481 // Cmp-like ops
1382 template <> const char *InstARM32Cmn::Opcode = "cmn"; 1482 template <> const char *InstARM32Cmn::Opcode = "cmn";
1383 template <> const char *InstARM32Cmp::Opcode = "cmp"; 1483 template <> const char *InstARM32Cmp::Opcode = "cmp";
1384 template <> const char *InstARM32Tst::Opcode = "tst"; 1484 template <> const char *InstARM32Tst::Opcode = "tst";
1385 1485
1386 void InstARM32::dump(const Cfg *Func) const { 1486 void InstARM32::dump(const Cfg *Func) const {
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
1472 1572
1473 Type Ty = Dest->getType(); 1573 Type Ty = Dest->getType();
1474 const bool IsVector = isVectorType(Ty); 1574 const bool IsVector = isVectorType(Ty);
1475 const bool IsScalarFP = isScalarFloatingType(Ty); 1575 const bool IsScalarFP = isScalarFloatingType(Ty);
1476 const bool CoreVFPMove = isMoveBetweenCoreAndVFPRegisters(Dest, Src0); 1576 const bool CoreVFPMove = isMoveBetweenCoreAndVFPRegisters(Dest, Src0);
1477 const bool IsVMove = (IsVector || IsScalarFP || CoreVFPMove); 1577 const bool IsVMove = (IsVector || IsScalarFP || CoreVFPMove);
1478 const char *Opcode = IsVMove ? "vmov" : "mov"; 1578 const char *Opcode = IsVMove ? "vmov" : "mov";
1479 // when vmov{c}'ing, we need to emit a width string. Otherwise, the 1579 // when vmov{c}'ing, we need to emit a width string. Otherwise, the
1480 // assembler might be tempted to assume we want a vector vmov{c}, and that 1580 // assembler might be tempted to assume we want a vector vmov{c}, and that
1481 // is disallowed because ARM. 1581 // is disallowed because ARM.
1482 const char *WidthString = !CoreVFPMove ? getVecWidthString(Ty) : ""; 1582 const char *WidthString = !CoreVFPMove ? getFpWidthString(Ty) : "";
1483 CondARM32::Cond Cond = getPredicate(); 1583 CondARM32::Cond Cond = getPredicate();
1484 if (IsVector) 1584 if (IsVector)
1485 assert(CondARM32::isUnconditional(Cond) && 1585 assert(CondARM32::isUnconditional(Cond) &&
1486 "Moves on vectors must be unconditional!"); 1586 "Moves on vectors must be unconditional!");
1487 Str << "\t" << Opcode; 1587 Str << "\t" << Opcode;
1488 if (IsVMove) { 1588 if (IsVMove) {
1489 Str << Cond << WidthString; 1589 Str << Cond << WidthString;
1490 } else { 1590 } else {
1491 Str << WidthString << Cond; 1591 Str << WidthString << Cond;
1492 } 1592 }
(...skipping 509 matching lines...) Expand 10 before | Expand all | Expand 10 after
2002 Asm->uxt(getDest(), getSrc(0), getPredicate()); 2102 Asm->uxt(getDest(), getSrc(0), getPredicate());
2003 if (Asm->needsTextFixup()) 2103 if (Asm->needsTextFixup())
2004 emitUsingTextFixup(Func); 2104 emitUsingTextFixup(Func);
2005 } 2105 }
2006 2106
2007 template <InstARM32::InstKindARM32 K> 2107 template <InstARM32::InstKindARM32 K>
2008 void InstARM32UnaryopFP<K>::emitIAS(const Cfg *Func) const { 2108 void InstARM32UnaryopFP<K>::emitIAS(const Cfg *Func) const {
2009 emitUsingTextFixup(Func); 2109 emitUsingTextFixup(Func);
2010 } 2110 }
2011 2111
2112 template <InstARM32::InstKindARM32 K>
2113 void InstARM32UnaryopSignAwareFP<K>::emitIAS(const Cfg *Func) const {
2114 InstARM32::emitUsingTextFixup(Func);
2115 }
2116
2012 template <> void InstARM32Vsqrt::emitIAS(const Cfg *Func) const { 2117 template <> void InstARM32Vsqrt::emitIAS(const Cfg *Func) const {
2013 assert(getSrcSize() == 1); 2118 assert(getSrcSize() == 1);
2014 auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>(); 2119 auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
2015 const Operand *Dest = getDest(); 2120 const Operand *Dest = getDest();
2016 switch (Dest->getType()) { 2121 switch (Dest->getType()) {
2017 case IceType_f32: 2122 case IceType_f32:
2018 Asm->vsqrts(Dest, getSrc(0), getPredicate()); 2123 Asm->vsqrts(Dest, getSrc(0), getPredicate());
2019 break; 2124 break;
2020 case IceType_f64: 2125 case IceType_f64:
2021 Asm->vsqrtd(Dest, getSrc(0), getPredicate()); 2126 Asm->vsqrtd(Dest, getSrc(0), getPredicate());
(...skipping 391 matching lines...) Expand 10 before | Expand all | Expand 10 after
2413 << "vcvt" << getPredicate() << vcvtVariantSuffix(Variant) << " "; 2518 << "vcvt" << getPredicate() << vcvtVariantSuffix(Variant) << " ";
2414 dumpSources(Func); 2519 dumpSources(Func);
2415 } 2520 }
2416 2521
2417 void InstARM32Vcmp::emit(const Cfg *Func) const { 2522 void InstARM32Vcmp::emit(const Cfg *Func) const {
2418 if (!BuildDefs::dump()) 2523 if (!BuildDefs::dump())
2419 return; 2524 return;
2420 Ostream &Str = Func->getContext()->getStrEmit(); 2525 Ostream &Str = Func->getContext()->getStrEmit();
2421 assert(getSrcSize() == 2); 2526 assert(getSrcSize() == 2);
2422 Str << "\t" 2527 Str << "\t"
2423 "vcmp" << getPredicate() << getVecWidthString(getSrc(0)->getType()) 2528 "vcmp" << getPredicate() << getFpWidthString(getSrc(0)->getType())
2424 << "\t"; 2529 << "\t";
2425 getSrc(0)->emit(Func); 2530 getSrc(0)->emit(Func);
2426 Str << ", "; 2531 Str << ", ";
2427 getSrc(1)->emit(Func); 2532 getSrc(1)->emit(Func);
2428 } 2533 }
2429 2534
2430 void InstARM32Vcmp::emitIAS(const Cfg *Func) const { 2535 void InstARM32Vcmp::emitIAS(const Cfg *Func) const {
2431 assert(getSrcSize() == 2); 2536 assert(getSrcSize() == 2);
2432 const Operand *Src0 = getSrc(0); 2537 const Operand *Src0 = getSrc(0);
2433 const Type Ty = Src0->getType(); 2538 const Type Ty = Src0->getType();
(...skipping 23 matching lines...) Expand all
2457 llvm::report_fatal_error("Vcvt on non floating value"); 2562 llvm::report_fatal_error("Vcvt on non floating value");
2458 } 2563 }
2459 } 2564 }
2460 assert(!Asm->needsTextFixup()); 2565 assert(!Asm->needsTextFixup());
2461 } 2566 }
2462 2567
2463 void InstARM32Vcmp::dump(const Cfg *Func) const { 2568 void InstARM32Vcmp::dump(const Cfg *Func) const {
2464 if (!BuildDefs::dump()) 2569 if (!BuildDefs::dump())
2465 return; 2570 return;
2466 Ostream &Str = Func->getContext()->getStrDump(); 2571 Ostream &Str = Func->getContext()->getStrDump();
2467 Str << "vcmp" << getPredicate() << getVecWidthString(getSrc(0)->getType()); 2572 Str << "vcmp" << getPredicate() << getFpWidthString(getSrc(0)->getType());
2468 dumpSources(Func); 2573 dumpSources(Func);
2469 } 2574 }
2470 2575
2471 void InstARM32Vmrs::emit(const Cfg *Func) const { 2576 void InstARM32Vmrs::emit(const Cfg *Func) const {
2472 if (!BuildDefs::dump()) 2577 if (!BuildDefs::dump())
2473 return; 2578 return;
2474 Ostream &Str = Func->getContext()->getStrEmit(); 2579 Ostream &Str = Func->getContext()->getStrEmit();
2475 assert(getSrcSize() == 0); 2580 assert(getSrcSize() == 0);
2476 Str << "\t" 2581 Str << "\t"
2477 "vmrs" << getPredicate() << "\t" 2582 "vmrs" << getPredicate() << "\t"
(...skipping 15 matching lines...) Expand all
2493 Str << "APSR{n,z,v,c} = vmrs" << getPredicate() << "\t" 2598 Str << "APSR{n,z,v,c} = vmrs" << getPredicate() << "\t"
2494 "FPSCR{n,z,c,v}"; 2599 "FPSCR{n,z,c,v}";
2495 } 2600 }
2496 2601
2497 void InstARM32Vabs::emit(const Cfg *Func) const { 2602 void InstARM32Vabs::emit(const Cfg *Func) const {
2498 if (!BuildDefs::dump()) 2603 if (!BuildDefs::dump())
2499 return; 2604 return;
2500 Ostream &Str = Func->getContext()->getStrEmit(); 2605 Ostream &Str = Func->getContext()->getStrEmit();
2501 assert(getSrcSize() == 1); 2606 assert(getSrcSize() == 1);
2502 Str << "\t" 2607 Str << "\t"
2503 "vabs" << getPredicate() << getVecWidthString(getSrc(0)->getType()) 2608 "vabs" << getPredicate() << getFpWidthString(getSrc(0)->getType())
2504 << "\t"; 2609 << "\t";
2505 getDest()->emit(Func); 2610 getDest()->emit(Func);
2506 Str << ", "; 2611 Str << ", ";
2507 getSrc(0)->emit(Func); 2612 getSrc(0)->emit(Func);
2508 } 2613 }
2509 2614
2510 void InstARM32Vabs::emitIAS(const Cfg *Func) const { 2615 void InstARM32Vabs::emitIAS(const Cfg *Func) const {
2511 assert(getSrcSize() == 1); 2616 assert(getSrcSize() == 1);
2512 auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>(); 2617 auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
2513 const Variable *Dest = getDest(); 2618 const Variable *Dest = getDest();
(...skipping 13 matching lines...) Expand all
2527 Asm->vabsq(Dest, getSrc(0)); 2632 Asm->vabsq(Dest, getSrc(0));
2528 } 2633 }
2529 assert(!Asm->needsTextFixup()); 2634 assert(!Asm->needsTextFixup());
2530 } 2635 }
2531 2636
2532 void InstARM32Vabs::dump(const Cfg *Func) const { 2637 void InstARM32Vabs::dump(const Cfg *Func) const {
2533 if (!BuildDefs::dump()) 2638 if (!BuildDefs::dump())
2534 return; 2639 return;
2535 Ostream &Str = Func->getContext()->getStrDump(); 2640 Ostream &Str = Func->getContext()->getStrDump();
2536 dumpDest(Func); 2641 dumpDest(Func);
2537 Str << " = vabs" << getPredicate() << getVecWidthString(getSrc(0)->getType()); 2642 Str << " = vabs" << getPredicate() << getFpWidthString(getSrc(0)->getType());
2538 } 2643 }
2539 2644
2540 void InstARM32Dmb::emit(const Cfg *Func) const { 2645 void InstARM32Dmb::emit(const Cfg *Func) const {
2541 if (!BuildDefs::dump()) 2646 if (!BuildDefs::dump())
2542 return; 2647 return;
2543 Ostream &Str = Func->getContext()->getStrEmit(); 2648 Ostream &Str = Func->getContext()->getStrEmit();
2544 assert(getSrcSize() == 0); 2649 assert(getSrcSize() == 0);
2545 Str << "\t" 2650 Str << "\t"
2546 "dmb" 2651 "dmb"
2547 "\t" 2652 "\t"
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after
2727 case IceType_f32: 2832 case IceType_f32:
2728 Str << "#" << materializeFloatImmediate(ModifiedImm) 2833 Str << "#" << materializeFloatImmediate(ModifiedImm)
2729 << " @ Modified: " << ModifiedImm; 2834 << " @ Modified: " << ModifiedImm;
2730 break; 2835 break;
2731 } 2836 }
2732 } 2837 }
2733 2838
2734 void OperandARM32FlexFpImm::dump(const Cfg * /*Func*/, Ostream &Str) const { 2839 void OperandARM32FlexFpImm::dump(const Cfg * /*Func*/, Ostream &Str) const {
2735 if (!BuildDefs::dump()) 2840 if (!BuildDefs::dump())
2736 return; 2841 return;
2737 Str << "#" << materializeFloatImmediate(ModifiedImm) 2842 Str << "#" << materializeFloatImmediate(ModifiedImm) << getFpWidthString(Ty);
2738 << InstARM32::getVecWidthString(Ty);
2739 } 2843 }
2740 2844
2741 void OperandARM32FlexFpZero::emit(const Cfg *Func) const { 2845 void OperandARM32FlexFpZero::emit(const Cfg *Func) const {
2742 if (!BuildDefs::dump()) 2846 if (!BuildDefs::dump())
2743 return; 2847 return;
2744 Ostream &Str = Func->getContext()->getStrEmit(); 2848 Ostream &Str = Func->getContext()->getStrEmit();
2745 switch (Ty) { 2849 switch (Ty) {
2746 default: 2850 default:
2747 llvm::report_fatal_error("Invalid flex fp imm type."); 2851 llvm::report_fatal_error("Invalid flex fp imm type.");
2748 case IceType_f64: 2852 case IceType_f64:
2749 case IceType_f32: 2853 case IceType_f32:
2750 Str << "#0.0"; 2854 Str << "#0.0";
2751 } 2855 }
2752 } 2856 }
2753 2857
2754 void OperandARM32FlexFpZero::dump(const Cfg * /*Func*/, Ostream &Str) const { 2858 void OperandARM32FlexFpZero::dump(const Cfg * /*Func*/, Ostream &Str) const {
2755 if (!BuildDefs::dump()) 2859 if (!BuildDefs::dump())
2756 return; 2860 return;
2757 Str << "#0.0" << InstARM32::getVecWidthString(Ty); 2861 Str << "#0.0" << getFpWidthString(Ty);
2758 } 2862 }
2759 2863
2760 void OperandARM32FlexReg::emit(const Cfg *Func) const { 2864 void OperandARM32FlexReg::emit(const Cfg *Func) const {
2761 if (!BuildDefs::dump()) 2865 if (!BuildDefs::dump())
2762 return; 2866 return;
2763 Ostream &Str = Func->getContext()->getStrEmit(); 2867 Ostream &Str = Func->getContext()->getStrEmit();
2764 getReg()->emit(Func); 2868 getReg()->emit(Func);
2765 if (getShiftOp() != kNoShift) { 2869 if (getShiftOp() != kNoShift) {
2766 Str << ", " << InstARM32ShiftAttributes[getShiftOp()].EmitString << " "; 2870 Str << ", " << InstARM32ShiftAttributes[getShiftOp()].EmitString << " ";
2767 getShiftAmt()->emit(Func); 2871 getShiftAmt()->emit(Func);
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
2802 template class InstARM32ThreeAddrGPR<InstARM32::Sdiv>; 2906 template class InstARM32ThreeAddrGPR<InstARM32::Sdiv>;
2803 template class InstARM32ThreeAddrGPR<InstARM32::Sub>; 2907 template class InstARM32ThreeAddrGPR<InstARM32::Sub>;
2804 template class InstARM32ThreeAddrGPR<InstARM32::Udiv>; 2908 template class InstARM32ThreeAddrGPR<InstARM32::Udiv>;
2805 2909
2806 template class InstARM32ThreeAddrFP<InstARM32::Vadd>; 2910 template class InstARM32ThreeAddrFP<InstARM32::Vadd>;
2807 template class InstARM32ThreeAddrFP<InstARM32::Vdiv>; 2911 template class InstARM32ThreeAddrFP<InstARM32::Vdiv>;
2808 template class InstARM32ThreeAddrFP<InstARM32::Veor>; 2912 template class InstARM32ThreeAddrFP<InstARM32::Veor>;
2809 template class InstARM32FourAddrFP<InstARM32::Vmla>; 2913 template class InstARM32FourAddrFP<InstARM32::Vmla>;
2810 template class InstARM32FourAddrFP<InstARM32::Vmls>; 2914 template class InstARM32FourAddrFP<InstARM32::Vmls>;
2811 template class InstARM32ThreeAddrFP<InstARM32::Vmul>; 2915 template class InstARM32ThreeAddrFP<InstARM32::Vmul>;
2916 template class InstARM32UnaryopSignAwareFP<InstARM32::Vneg>;
2917 template class InstARM32ThreeAddrSignAwareFP<InstARM32::Vshl>;
2812 template class InstARM32ThreeAddrFP<InstARM32::Vsub>; 2918 template class InstARM32ThreeAddrFP<InstARM32::Vsub>;
2813 2919
2814 template class InstARM32LoadBase<InstARM32::Ldr>; 2920 template class InstARM32LoadBase<InstARM32::Ldr>;
2815 template class InstARM32LoadBase<InstARM32::Ldrex>; 2921 template class InstARM32LoadBase<InstARM32::Ldrex>;
2816 2922
2817 template class InstARM32TwoAddrGPR<InstARM32::Movt>; 2923 template class InstARM32TwoAddrGPR<InstARM32::Movt>;
2818 2924
2819 template class InstARM32UnaryopGPR<InstARM32::Movw, false>; 2925 template class InstARM32UnaryopGPR<InstARM32::Movw, false>;
2820 template class InstARM32UnaryopGPR<InstARM32::Clz, false>; 2926 template class InstARM32UnaryopGPR<InstARM32::Clz, false>;
2821 template class InstARM32UnaryopGPR<InstARM32::Mvn, false>; 2927 template class InstARM32UnaryopGPR<InstARM32::Mvn, false>;
2822 template class InstARM32UnaryopGPR<InstARM32::Rbit, false>; 2928 template class InstARM32UnaryopGPR<InstARM32::Rbit, false>;
2823 template class InstARM32UnaryopGPR<InstARM32::Rev, false>; 2929 template class InstARM32UnaryopGPR<InstARM32::Rev, false>;
2824 template class InstARM32UnaryopGPR<InstARM32::Sxt, true>; 2930 template class InstARM32UnaryopGPR<InstARM32::Sxt, true>;
2825 template class InstARM32UnaryopGPR<InstARM32::Uxt, true>; 2931 template class InstARM32UnaryopGPR<InstARM32::Uxt, true>;
2826 template class InstARM32UnaryopFP<InstARM32::Vsqrt>; 2932 template class InstARM32UnaryopFP<InstARM32::Vsqrt>;
2827 2933
2828 template class InstARM32FourAddrGPR<InstARM32::Mla>; 2934 template class InstARM32FourAddrGPR<InstARM32::Mla>;
2829 template class InstARM32FourAddrGPR<InstARM32::Mls>; 2935 template class InstARM32FourAddrGPR<InstARM32::Mls>;
2830 2936
2831 template class InstARM32CmpLike<InstARM32::Cmn>; 2937 template class InstARM32CmpLike<InstARM32::Cmn>;
2832 template class InstARM32CmpLike<InstARM32::Cmp>; 2938 template class InstARM32CmpLike<InstARM32::Cmp>;
2833 template class InstARM32CmpLike<InstARM32::Tst>; 2939 template class InstARM32CmpLike<InstARM32::Tst>;
2834 2940
2835 } // end of namespace ARM32 2941 } // end of namespace ARM32
2836 } // end of namespace Ice 2942 } // end of namespace Ice
OLDNEW
« no previous file with comments | « src/IceInstARM32.h ('k') | src/IceInstARM32.def » ('j') | src/IceInstARM32.def » ('J')

Powered by Google App Engine
This is Rietveld 408576698