OLD | NEW |
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 10 matching lines...) Expand all Loading... |
21 #include "IceInst.h" | 21 #include "IceInst.h" |
22 #include "IceOperand.h" | 22 #include "IceOperand.h" |
23 #include "IceRegistersARM32.h" | 23 #include "IceRegistersARM32.h" |
24 #include "IceTargetLoweringARM32.h" | 24 #include "IceTargetLoweringARM32.h" |
25 | 25 |
26 namespace Ice { | 26 namespace Ice { |
27 | 27 |
28 namespace { | 28 namespace { |
29 | 29 |
30 const struct TypeARM32Attributes_ { | 30 const struct TypeARM32Attributes_ { |
31 const char *WidthString; // b, h, <blank>, or d | 31 const char *WidthString; // b, h, <blank>, or d |
| 32 const char *VecWidthString; // i8, i16, i32, f32, f64 |
32 int8_t SExtAddrOffsetBits; | 33 int8_t SExtAddrOffsetBits; |
33 int8_t ZExtAddrOffsetBits; | 34 int8_t ZExtAddrOffsetBits; |
34 } TypeARM32Attributes[] = { | 35 } TypeARM32Attributes[] = { |
35 #define X(tag, elementty, width, sbits, ubits) \ | 36 #define X(tag, elementty, int_width, vec_width, sbits, ubits) \ |
36 { width, sbits, ubits } \ | 37 { int_width, vec_width, sbits, ubits } \ |
37 , | 38 , |
38 ICETYPEARM32_TABLE | 39 ICETYPEARM32_TABLE |
39 #undef X | 40 #undef X |
40 }; | 41 }; |
41 | 42 |
42 const struct InstARM32ShiftAttributes_ { | 43 const struct InstARM32ShiftAttributes_ { |
43 const char *EmitString; | 44 const char *EmitString; |
44 } InstARM32ShiftAttributes[] = { | 45 } InstARM32ShiftAttributes[] = { |
45 #define X(tag, emit) \ | 46 #define X(tag, emit) \ |
46 { emit } \ | 47 { emit } \ |
(...skipping 12 matching lines...) Expand all Loading... |
59 ICEINSTARM32COND_TABLE | 60 ICEINSTARM32COND_TABLE |
60 #undef X | 61 #undef X |
61 }; | 62 }; |
62 | 63 |
63 } // end of anonymous namespace | 64 } // end of anonymous namespace |
64 | 65 |
65 const char *InstARM32::getWidthString(Type Ty) { | 66 const char *InstARM32::getWidthString(Type Ty) { |
66 return TypeARM32Attributes[Ty].WidthString; | 67 return TypeARM32Attributes[Ty].WidthString; |
67 } | 68 } |
68 | 69 |
| 70 const char *InstARM32::getVecWidthString(Type Ty) { |
| 71 return TypeARM32Attributes[Ty].VecWidthString; |
| 72 } |
| 73 |
69 const char *InstARM32Pred::predString(CondARM32::Cond Pred) { | 74 const char *InstARM32Pred::predString(CondARM32::Cond Pred) { |
70 return InstARM32CondAttributes[Pred].EmitString; | 75 return InstARM32CondAttributes[Pred].EmitString; |
71 } | 76 } |
72 | 77 |
73 void InstARM32Pred::dumpOpcodePred(Ostream &Str, const char *Opcode, | 78 void InstARM32Pred::dumpOpcodePred(Ostream &Str, const char *Opcode, |
74 Type Ty) const { | 79 Type Ty) const { |
75 Str << Opcode << getPredicate() << "." << Ty; | 80 Str << Opcode << getPredicate() << "." << Ty; |
76 } | 81 } |
77 | 82 |
78 CondARM32::Cond InstARM32::getOppositeCondition(CondARM32::Cond Cond) { | 83 CondARM32::Cond InstARM32::getOppositeCondition(CondARM32::Cond Cond) { |
79 return InstARM32CondAttributes[Cond].Opposite; | 84 return InstARM32CondAttributes[Cond].Opposite; |
80 } | 85 } |
81 | 86 |
82 void InstARM32Pred::emitUnaryopGPR(const char *Opcode, | 87 void InstARM32Pred::emitUnaryopGPR(const char *Opcode, |
83 const InstARM32Pred *Inst, const Cfg *Func, | 88 const InstARM32Pred *Inst, const Cfg *Func, |
84 bool NeedsWidthSuffix) { | 89 bool NeedsWidthSuffix) { |
85 Ostream &Str = Func->getContext()->getStrEmit(); | 90 Ostream &Str = Func->getContext()->getStrEmit(); |
86 assert(Inst->getSrcSize() == 1); | 91 assert(Inst->getSrcSize() == 1); |
87 Type SrcTy = Inst->getSrc(0)->getType(); | 92 Type SrcTy = Inst->getSrc(0)->getType(); |
88 Str << "\t" << Opcode; | 93 Str << "\t" << Opcode; |
89 if (NeedsWidthSuffix) | 94 if (NeedsWidthSuffix) |
90 Str << getWidthString(SrcTy); | 95 Str << getWidthString(SrcTy); |
91 Str << Inst->getPredicate() << "\t"; | 96 Str << Inst->getPredicate() << "\t"; |
92 Inst->getDest()->emit(Func); | 97 Inst->getDest()->emit(Func); |
93 Str << ", "; | 98 Str << ", "; |
94 Inst->getSrc(0)->emit(Func); | 99 Inst->getSrc(0)->emit(Func); |
95 } | 100 } |
96 | 101 |
| 102 void InstARM32Pred::emitUnaryopFP(const char *Opcode, const InstARM32Pred *Inst, |
| 103 const Cfg *Func) { |
| 104 Ostream &Str = Func->getContext()->getStrEmit(); |
| 105 assert(Inst->getSrcSize() == 1); |
| 106 Type SrcTy = Inst->getSrc(0)->getType(); |
| 107 Str << "\t" << Opcode << Inst->getPredicate() << getVecWidthString(SrcTy) |
| 108 << "\t"; |
| 109 Inst->getDest()->emit(Func); |
| 110 Str << ", "; |
| 111 Inst->getSrc(0)->emit(Func); |
| 112 } |
| 113 |
97 void InstARM32Pred::emitTwoAddr(const char *Opcode, const InstARM32Pred *Inst, | 114 void InstARM32Pred::emitTwoAddr(const char *Opcode, const InstARM32Pred *Inst, |
98 const Cfg *Func) { | 115 const Cfg *Func) { |
99 if (!BuildDefs::dump()) | 116 if (!BuildDefs::dump()) |
100 return; | 117 return; |
101 Ostream &Str = Func->getContext()->getStrEmit(); | 118 Ostream &Str = Func->getContext()->getStrEmit(); |
102 assert(Inst->getSrcSize() == 2); | 119 assert(Inst->getSrcSize() == 2); |
103 Variable *Dest = Inst->getDest(); | 120 Variable *Dest = Inst->getDest(); |
104 assert(Dest == Inst->getSrc(0)); | 121 assert(Dest == Inst->getSrc(0)); |
105 Str << "\t" << Opcode << Inst->getPredicate() << "\t"; | 122 Str << "\t" << Opcode << Inst->getPredicate() << "\t"; |
106 Dest->emit(Func); | 123 Dest->emit(Func); |
107 Str << ", "; | 124 Str << ", "; |
108 Inst->getSrc(1)->emit(Func); | 125 Inst->getSrc(1)->emit(Func); |
109 } | 126 } |
110 | 127 |
111 void InstARM32Pred::emitThreeAddr(const char *Opcode, const InstARM32Pred *Inst, | 128 void InstARM32Pred::emitThreeAddr(const char *Opcode, const InstARM32Pred *Inst, |
112 const Cfg *Func, bool SetFlags) { | 129 const Cfg *Func, bool SetFlags) { |
113 if (!BuildDefs::dump()) | 130 if (!BuildDefs::dump()) |
114 return; | 131 return; |
115 Ostream &Str = Func->getContext()->getStrEmit(); | 132 Ostream &Str = Func->getContext()->getStrEmit(); |
116 assert(Inst->getSrcSize() == 2); | 133 assert(Inst->getSrcSize() == 2); |
117 Str << "\t" << Opcode << (SetFlags ? "s" : "") << Inst->getPredicate() | 134 Str << "\t" << Opcode << (SetFlags ? "s" : "") << Inst->getPredicate() |
118 << "\t"; | 135 << "\t"; |
119 Inst->getDest()->emit(Func); | 136 Inst->getDest()->emit(Func); |
120 Str << ", "; | 137 Str << ", "; |
121 Inst->getSrc(0)->emit(Func); | 138 Inst->getSrc(0)->emit(Func); |
122 Str << ", "; | 139 Str << ", "; |
123 Inst->getSrc(1)->emit(Func); | 140 Inst->getSrc(1)->emit(Func); |
124 } | 141 } |
125 | 142 |
| 143 void InstARM32::emitThreeAddrFP(const char *Opcode, const InstARM32 *Inst, |
| 144 const Cfg *Func) { |
| 145 if (!BuildDefs::dump()) |
| 146 return; |
| 147 Ostream &Str = Func->getContext()->getStrEmit(); |
| 148 assert(Inst->getSrcSize() == 2); |
| 149 Str << "\t" << Opcode << getVecWidthString(Inst->getDest()->getType()) |
| 150 << "\t"; |
| 151 Inst->getDest()->emit(Func); |
| 152 Str << ", "; |
| 153 Inst->getSrc(0)->emit(Func); |
| 154 Str << ", "; |
| 155 Inst->getSrc(1)->emit(Func); |
| 156 } |
| 157 |
126 void InstARM32Pred::emitFourAddr(const char *Opcode, const InstARM32Pred *Inst, | 158 void InstARM32Pred::emitFourAddr(const char *Opcode, const InstARM32Pred *Inst, |
127 const Cfg *Func) { | 159 const Cfg *Func) { |
128 if (!BuildDefs::dump()) | 160 if (!BuildDefs::dump()) |
129 return; | 161 return; |
130 Ostream &Str = Func->getContext()->getStrEmit(); | 162 Ostream &Str = Func->getContext()->getStrEmit(); |
131 assert(Inst->getSrcSize() == 3); | 163 assert(Inst->getSrcSize() == 3); |
132 Str << "\t" << Opcode << Inst->getPredicate() << "\t"; | 164 Str << "\t" << Opcode << Inst->getPredicate() << "\t"; |
133 Inst->getDest()->emit(Func); | 165 Inst->getDest()->emit(Func); |
134 Str << ", "; | 166 Str << ", "; |
135 Inst->getSrc(0)->emit(Func); | 167 Inst->getSrc(0)->emit(Func); |
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
297 } | 329 } |
298 | 330 |
299 InstARM32Label::InstARM32Label(Cfg *Func, TargetARM32 *Target) | 331 InstARM32Label::InstARM32Label(Cfg *Func, TargetARM32 *Target) |
300 : InstARM32(Func, InstARM32::Label, 0, nullptr), | 332 : InstARM32(Func, InstARM32::Label, 0, nullptr), |
301 Number(Target->makeNextLabelNumber()) {} | 333 Number(Target->makeNextLabelNumber()) {} |
302 | 334 |
303 IceString InstARM32Label::getName(const Cfg *Func) const { | 335 IceString InstARM32Label::getName(const Cfg *Func) const { |
304 return ".L" + Func->getFunctionName() + "$local$__" + std::to_string(Number); | 336 return ".L" + Func->getFunctionName() + "$local$__" + std::to_string(Number); |
305 } | 337 } |
306 | 338 |
307 InstARM32Ldr::InstARM32Ldr(Cfg *Func, Variable *Dest, OperandARM32Mem *Mem, | |
308 CondARM32::Cond Predicate) | |
309 : InstARM32Pred(Func, InstARM32::Ldr, 1, Dest, Predicate) { | |
310 addSource(Mem); | |
311 } | |
312 | |
313 InstARM32Pop::InstARM32Pop(Cfg *Func, const VarList &Dests) | 339 InstARM32Pop::InstARM32Pop(Cfg *Func, const VarList &Dests) |
314 : InstARM32(Func, InstARM32::Pop, 0, nullptr), Dests(Dests) { | 340 : InstARM32(Func, InstARM32::Pop, 0, nullptr), Dests(Dests) { |
315 // Track modifications to Dests separately via FakeDefs. | 341 // Track modifications to Dests separately via FakeDefs. |
316 // Also, a pop instruction affects the stack pointer and so it should not | 342 // Also, a pop instruction affects the stack pointer and so it should not |
317 // be allowed to be automatically dead-code eliminated. This is automatic | 343 // be allowed to be automatically dead-code eliminated. This is automatic |
318 // since we leave the Dest as nullptr. | 344 // since we leave the Dest as nullptr. |
319 } | 345 } |
320 | 346 |
321 InstARM32Push::InstARM32Push(Cfg *Func, const VarList &Srcs) | 347 InstARM32Push::InstARM32Push(Cfg *Func, const VarList &Srcs) |
322 : InstARM32(Func, InstARM32::Push, Srcs.size(), nullptr) { | 348 : InstARM32(Func, InstARM32::Push, Srcs.size(), nullptr) { |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
356 // Two-addr ops | 382 // Two-addr ops |
357 template <> const char *InstARM32Movt::Opcode = "movt"; | 383 template <> const char *InstARM32Movt::Opcode = "movt"; |
358 // Unary ops | 384 // Unary ops |
359 template <> const char *InstARM32Movw::Opcode = "movw"; | 385 template <> const char *InstARM32Movw::Opcode = "movw"; |
360 template <> const char *InstARM32Clz::Opcode = "clz"; | 386 template <> const char *InstARM32Clz::Opcode = "clz"; |
361 template <> const char *InstARM32Mvn::Opcode = "mvn"; | 387 template <> const char *InstARM32Mvn::Opcode = "mvn"; |
362 template <> const char *InstARM32Rbit::Opcode = "rbit"; | 388 template <> const char *InstARM32Rbit::Opcode = "rbit"; |
363 template <> const char *InstARM32Rev::Opcode = "rev"; | 389 template <> const char *InstARM32Rev::Opcode = "rev"; |
364 template <> const char *InstARM32Sxt::Opcode = "sxt"; // still requires b/h | 390 template <> const char *InstARM32Sxt::Opcode = "sxt"; // still requires b/h |
365 template <> const char *InstARM32Uxt::Opcode = "uxt"; // still requires b/h | 391 template <> const char *InstARM32Uxt::Opcode = "uxt"; // still requires b/h |
| 392 // FP |
| 393 template <> const char *InstARM32Vsqrt::Opcode = "vsqrt"; |
366 // Mov-like ops | 394 // Mov-like ops |
| 395 template <> const char *InstARM32Ldr::Opcode = "ldr"; |
367 template <> const char *InstARM32Mov::Opcode = "mov"; | 396 template <> const char *InstARM32Mov::Opcode = "mov"; |
| 397 // FP |
| 398 template <> const char *InstARM32Vldr::Opcode = "vldr"; |
| 399 template <> const char *InstARM32Vmov::Opcode = "vmov"; |
368 // Three-addr ops | 400 // Three-addr ops |
369 template <> const char *InstARM32Adc::Opcode = "adc"; | 401 template <> const char *InstARM32Adc::Opcode = "adc"; |
370 template <> const char *InstARM32Add::Opcode = "add"; | 402 template <> const char *InstARM32Add::Opcode = "add"; |
371 template <> const char *InstARM32And::Opcode = "and"; | 403 template <> const char *InstARM32And::Opcode = "and"; |
372 template <> const char *InstARM32Asr::Opcode = "asr"; | 404 template <> const char *InstARM32Asr::Opcode = "asr"; |
373 template <> const char *InstARM32Bic::Opcode = "bic"; | 405 template <> const char *InstARM32Bic::Opcode = "bic"; |
374 template <> const char *InstARM32Eor::Opcode = "eor"; | 406 template <> const char *InstARM32Eor::Opcode = "eor"; |
375 template <> const char *InstARM32Lsl::Opcode = "lsl"; | 407 template <> const char *InstARM32Lsl::Opcode = "lsl"; |
376 template <> const char *InstARM32Lsr::Opcode = "lsr"; | 408 template <> const char *InstARM32Lsr::Opcode = "lsr"; |
377 template <> const char *InstARM32Mul::Opcode = "mul"; | 409 template <> const char *InstARM32Mul::Opcode = "mul"; |
378 template <> const char *InstARM32Orr::Opcode = "orr"; | 410 template <> const char *InstARM32Orr::Opcode = "orr"; |
379 template <> const char *InstARM32Rsb::Opcode = "rsb"; | 411 template <> const char *InstARM32Rsb::Opcode = "rsb"; |
380 template <> const char *InstARM32Sbc::Opcode = "sbc"; | 412 template <> const char *InstARM32Sbc::Opcode = "sbc"; |
381 template <> const char *InstARM32Sdiv::Opcode = "sdiv"; | 413 template <> const char *InstARM32Sdiv::Opcode = "sdiv"; |
382 template <> const char *InstARM32Sub::Opcode = "sub"; | 414 template <> const char *InstARM32Sub::Opcode = "sub"; |
383 template <> const char *InstARM32Udiv::Opcode = "udiv"; | 415 template <> const char *InstARM32Udiv::Opcode = "udiv"; |
| 416 // FP |
| 417 template <> const char *InstARM32Vadd::Opcode = "vadd"; |
| 418 template <> const char *InstARM32Vdiv::Opcode = "vdiv"; |
| 419 template <> const char *InstARM32Vmul::Opcode = "vmul"; |
| 420 template <> const char *InstARM32Vsub::Opcode = "vsub"; |
384 // Four-addr ops | 421 // Four-addr ops |
385 template <> const char *InstARM32Mla::Opcode = "mla"; | 422 template <> const char *InstARM32Mla::Opcode = "mla"; |
386 template <> const char *InstARM32Mls::Opcode = "mls"; | 423 template <> const char *InstARM32Mls::Opcode = "mls"; |
387 // Cmp-like ops | 424 // Cmp-like ops |
388 template <> const char *InstARM32Cmp::Opcode = "cmp"; | 425 template <> const char *InstARM32Cmp::Opcode = "cmp"; |
389 template <> const char *InstARM32Tst::Opcode = "tst"; | 426 template <> const char *InstARM32Tst::Opcode = "tst"; |
390 | 427 |
391 void InstARM32::dump(const Cfg *Func) const { | 428 void InstARM32::dump(const Cfg *Func) const { |
392 if (!BuildDefs::dump()) | 429 if (!BuildDefs::dump()) |
393 return; | 430 return; |
394 Ostream &Str = Func->getContext()->getStrDump(); | 431 Ostream &Str = Func->getContext()->getStrDump(); |
395 Str << "[ARM32] "; | 432 Str << "[ARM32] "; |
396 Inst::dump(Func); | 433 Inst::dump(Func); |
397 } | 434 } |
398 | 435 |
399 template <> void InstARM32Mov::emit(const Cfg *Func) const { | 436 template <> void InstARM32Mov::emit(const Cfg *Func) const { |
400 if (!BuildDefs::dump()) | 437 if (!BuildDefs::dump()) |
401 return; | 438 return; |
402 Ostream &Str = Func->getContext()->getStrEmit(); | 439 Ostream &Str = Func->getContext()->getStrEmit(); |
403 assert(getSrcSize() == 1); | 440 assert(getSrcSize() == 1); |
404 Variable *Dest = getDest(); | 441 Variable *Dest = getDest(); |
405 if (Dest->hasReg()) { | 442 if (Dest->hasReg()) { |
406 IceString Opcode = "mov"; | 443 IceString ActualOpcode = Opcode; |
407 Operand *Src0 = getSrc(0); | 444 Operand *Src0 = getSrc(0); |
408 if (const auto *Src0V = llvm::dyn_cast<Variable>(Src0)) { | 445 if (const auto *Src0V = llvm::dyn_cast<Variable>(Src0)) { |
409 if (!Src0V->hasReg()) { | 446 if (!Src0V->hasReg()) { |
410 // Always use the whole stack slot. A 32-bit load has a larger range | 447 // Always use the whole stack slot. A 32-bit load has a larger range |
411 // of offsets than 16-bit, etc. | 448 // of offsets than 16-bit, etc. |
412 Opcode = IceString("ldr"); | 449 ActualOpcode = IceString("ldr"); |
413 } | 450 } |
414 } else { | 451 } else { |
415 if (llvm::isa<OperandARM32Mem>(Src0)) | 452 if (llvm::isa<OperandARM32Mem>(Src0)) |
416 Opcode = IceString("ldr") + getWidthString(Dest->getType()); | 453 ActualOpcode = IceString("ldr") + getWidthString(Dest->getType()); |
417 } | 454 } |
418 Str << "\t" << Opcode << getPredicate() << "\t"; | 455 Str << "\t" << ActualOpcode << getPredicate() << "\t"; |
419 getDest()->emit(Func); | 456 getDest()->emit(Func); |
420 Str << ", "; | 457 Str << ", "; |
421 getSrc(0)->emit(Func); | 458 getSrc(0)->emit(Func); |
422 } else { | 459 } else { |
423 Variable *Src0 = llvm::cast<Variable>(getSrc(0)); | 460 Variable *Src0 = llvm::cast<Variable>(getSrc(0)); |
424 assert(Src0->hasReg()); | 461 assert(Src0->hasReg()); |
425 Str << "\t" | 462 Str << "\t" |
426 << "str" << getPredicate() << "\t"; | 463 << "str" << getPredicate() << "\t"; |
427 Src0->emit(Func); | 464 Src0->emit(Func); |
428 Str << ", "; | 465 Str << ", "; |
429 Dest->emit(Func); | 466 Dest->emit(Func); |
430 } | 467 } |
431 } | 468 } |
432 | 469 |
433 template <> void InstARM32Mov::emitIAS(const Cfg *Func) const { | 470 template <> void InstARM32Mov::emitIAS(const Cfg *Func) const { |
434 assert(getSrcSize() == 1); | 471 assert(getSrcSize() == 1); |
435 (void)Func; | 472 (void)Func; |
436 llvm_unreachable("Not yet implemented"); | 473 llvm_unreachable("Not yet implemented"); |
437 } | 474 } |
438 | 475 |
| 476 template <> void InstARM32Vldr::emit(const Cfg *Func) const { |
| 477 if (!BuildDefs::dump()) |
| 478 return; |
| 479 Ostream &Str = Func->getContext()->getStrEmit(); |
| 480 assert(getSrcSize() == 1); |
| 481 assert(getDest()->hasReg()); |
| 482 Str << "\t"<< Opcode << getPredicate() << "\t"; |
| 483 getDest()->emit(Func); |
| 484 Str << ", "; |
| 485 getSrc(0)->emit(Func); |
| 486 } |
| 487 |
| 488 template <> void InstARM32Vldr::emitIAS(const Cfg *Func) const { |
| 489 assert(getSrcSize() == 1); |
| 490 (void)Func; |
| 491 llvm_unreachable("Not yet implemented"); |
| 492 } |
| 493 |
| 494 template <> void InstARM32Vmov::emit(const Cfg *Func) const { |
| 495 if (!BuildDefs::dump()) |
| 496 return; |
| 497 assert(CondARM32::AL == getPredicate()); |
| 498 Ostream &Str = Func->getContext()->getStrEmit(); |
| 499 assert(getSrcSize() == 1); |
| 500 Variable *Dest = getDest(); |
| 501 if (Dest->hasReg()) { |
| 502 IceString ActualOpcode = Opcode; |
| 503 Operand *Src0 = getSrc(0); |
| 504 if (const auto *Src0V = llvm::dyn_cast<Variable>(Src0)) { |
| 505 if (!Src0V->hasReg()) { |
| 506 ActualOpcode = IceString("vldr"); |
| 507 } |
| 508 } else { |
| 509 if (llvm::isa<OperandARM32Mem>(Src0)) |
| 510 ActualOpcode = IceString("vldr"); |
| 511 } |
| 512 Str << "\t" << ActualOpcode << "\t"; |
| 513 getDest()->emit(Func); |
| 514 Str << ", "; |
| 515 getSrc(0)->emit(Func); |
| 516 } else { |
| 517 Variable *Src0 = llvm::cast<Variable>(getSrc(0)); |
| 518 assert(Src0->hasReg()); |
| 519 Str << "\t" |
| 520 "vstr" |
| 521 "\t"; |
| 522 Src0->emit(Func); |
| 523 Str << ", "; |
| 524 Dest->emit(Func); |
| 525 } |
| 526 } |
| 527 |
| 528 template <> void InstARM32Vmov::emitIAS(const Cfg *Func) const { |
| 529 assert(getSrcSize() == 1); |
| 530 (void)Func; |
| 531 llvm_unreachable("Not yet implemented"); |
| 532 } |
| 533 |
439 void InstARM32Br::emit(const Cfg *Func) const { | 534 void InstARM32Br::emit(const Cfg *Func) const { |
440 if (!BuildDefs::dump()) | 535 if (!BuildDefs::dump()) |
441 return; | 536 return; |
442 Ostream &Str = Func->getContext()->getStrEmit(); | 537 Ostream &Str = Func->getContext()->getStrEmit(); |
443 Str << "\t" | 538 Str << "\t" |
444 << "b" << getPredicate() << "\t"; | 539 << "b" << getPredicate() << "\t"; |
445 if (Label) { | 540 if (Label) { |
446 Str << Label->getName(Func); | 541 Str << Label->getName(Func); |
447 } else { | 542 } else { |
448 if (isUnconditionalBranch()) { | 543 if (isUnconditionalBranch()) { |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
540 llvm_unreachable("Not yet implemented"); | 635 llvm_unreachable("Not yet implemented"); |
541 } | 636 } |
542 | 637 |
543 void InstARM32Label::dump(const Cfg *Func) const { | 638 void InstARM32Label::dump(const Cfg *Func) const { |
544 if (!BuildDefs::dump()) | 639 if (!BuildDefs::dump()) |
545 return; | 640 return; |
546 Ostream &Str = Func->getContext()->getStrDump(); | 641 Ostream &Str = Func->getContext()->getStrDump(); |
547 Str << getName(Func) << ":"; | 642 Str << getName(Func) << ":"; |
548 } | 643 } |
549 | 644 |
550 void InstARM32Ldr::emit(const Cfg *Func) const { | 645 template <> void InstARM32Ldr::emit(const Cfg *Func) const { |
551 if (!BuildDefs::dump()) | 646 if (!BuildDefs::dump()) |
552 return; | 647 return; |
553 Ostream &Str = Func->getContext()->getStrEmit(); | 648 Ostream &Str = Func->getContext()->getStrEmit(); |
554 assert(getSrcSize() == 1); | 649 assert(getSrcSize() == 1); |
555 assert(getDest()->hasReg()); | 650 assert(getDest()->hasReg()); |
556 Type Ty = getSrc(0)->getType(); | 651 Type Ty = getSrc(0)->getType(); |
557 Str << "\t" | 652 Str << "\t"<< Opcode << getWidthString(Ty) << getPredicate() << "\t"; |
558 << "ldr" << getWidthString(Ty) << getPredicate() << "\t"; | |
559 getDest()->emit(Func); | 653 getDest()->emit(Func); |
560 Str << ", "; | 654 Str << ", "; |
561 getSrc(0)->emit(Func); | 655 getSrc(0)->emit(Func); |
562 } | 656 } |
563 | 657 |
564 void InstARM32Ldr::emitIAS(const Cfg *Func) const { | 658 template <> void InstARM32Ldr::emitIAS(const Cfg *Func) const { |
565 assert(getSrcSize() == 1); | 659 assert(getSrcSize() == 1); |
566 (void)Func; | 660 (void)Func; |
567 llvm_unreachable("Not yet implemented"); | 661 llvm_unreachable("Not yet implemented"); |
568 } | 662 } |
569 | 663 |
570 void InstARM32Ldr::dump(const Cfg *Func) const { | |
571 if (!BuildDefs::dump()) | |
572 return; | |
573 Ostream &Str = Func->getContext()->getStrDump(); | |
574 dumpDest(Func); | |
575 Str << " = "; | |
576 dumpOpcodePred(Str, "ldr", getDest()->getType()); | |
577 Str << " "; | |
578 dumpSources(Func); | |
579 } | |
580 | |
581 template <> void InstARM32Movw::emit(const Cfg *Func) const { | 664 template <> void InstARM32Movw::emit(const Cfg *Func) const { |
582 if (!BuildDefs::dump()) | 665 if (!BuildDefs::dump()) |
583 return; | 666 return; |
584 Ostream &Str = Func->getContext()->getStrEmit(); | 667 Ostream &Str = Func->getContext()->getStrEmit(); |
585 assert(getSrcSize() == 1); | 668 assert(getSrcSize() == 1); |
586 Str << "\t" << Opcode << getPredicate() << "\t"; | 669 Str << "\t" << Opcode << getPredicate() << "\t"; |
587 getDest()->emit(Func); | 670 getDest()->emit(Func); |
588 Str << ", "; | 671 Str << ", "; |
589 Constant *Src0 = llvm::cast<Constant>(getSrc(0)); | 672 Constant *Src0 = llvm::cast<Constant>(getSrc(0)); |
590 if (auto CR = llvm::dyn_cast<ConstantRelocatable>(Src0)) { | 673 if (auto CR = llvm::dyn_cast<ConstantRelocatable>(Src0)) { |
(...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
935 if (getShiftOp() != kNoShift) { | 1018 if (getShiftOp() != kNoShift) { |
936 Str << ", " << InstARM32ShiftAttributes[getShiftOp()].EmitString << " "; | 1019 Str << ", " << InstARM32ShiftAttributes[getShiftOp()].EmitString << " "; |
937 if (Func) | 1020 if (Func) |
938 getShiftAmt()->dump(Func); | 1021 getShiftAmt()->dump(Func); |
939 else | 1022 else |
940 getShiftAmt()->dump(Str); | 1023 getShiftAmt()->dump(Str); |
941 } | 1024 } |
942 } | 1025 } |
943 | 1026 |
944 } // end of namespace Ice | 1027 } // end of namespace Ice |
OLD | NEW |