| 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 |