| 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 // This file implements the InstARM32 and OperandARM32 classes, | 10 // This file implements the InstARM32 and OperandARM32 classes, |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 90 if (SrcTy != DestTy) | 90 if (SrcTy != DestTy) |
| 91 Str << getWidthString(SrcTy); | 91 Str << getWidthString(SrcTy); |
| 92 Str << "\t"; | 92 Str << "\t"; |
| 93 Inst->getDest()->emit(Func); | 93 Inst->getDest()->emit(Func); |
| 94 Str << ", "; | 94 Str << ", "; |
| 95 Inst->getSrc(0)->emit(Func); | 95 Inst->getSrc(0)->emit(Func); |
| 96 } | 96 } |
| 97 | 97 |
| 98 void InstARM32Pred::emitTwoAddr(const char *Opcode, const InstARM32Pred *Inst, | 98 void InstARM32Pred::emitTwoAddr(const char *Opcode, const InstARM32Pred *Inst, |
| 99 const Cfg *Func) { | 99 const Cfg *Func) { |
| 100 if (!ALLOW_DUMP) | 100 if (!buildAllowsDump()) |
| 101 return; | 101 return; |
| 102 Ostream &Str = Func->getContext()->getStrEmit(); | 102 Ostream &Str = Func->getContext()->getStrEmit(); |
| 103 assert(Inst->getSrcSize() == 2); | 103 assert(Inst->getSrcSize() == 2); |
| 104 Variable *Dest = Inst->getDest(); | 104 Variable *Dest = Inst->getDest(); |
| 105 assert(Dest == Inst->getSrc(0)); | 105 assert(Dest == Inst->getSrc(0)); |
| 106 Str << "\t" << Opcode << Inst->getPredicate() << "\t"; | 106 Str << "\t" << Opcode << Inst->getPredicate() << "\t"; |
| 107 Dest->emit(Func); | 107 Dest->emit(Func); |
| 108 Str << ", "; | 108 Str << ", "; |
| 109 Inst->getSrc(1)->emit(Func); | 109 Inst->getSrc(1)->emit(Func); |
| 110 } | 110 } |
| 111 | 111 |
| 112 void InstARM32Pred::emitThreeAddr(const char *Opcode, const InstARM32Pred *Inst, | 112 void InstARM32Pred::emitThreeAddr(const char *Opcode, const InstARM32Pred *Inst, |
| 113 const Cfg *Func, bool SetFlags) { | 113 const Cfg *Func, bool SetFlags) { |
| 114 if (!ALLOW_DUMP) | 114 if (!buildAllowsDump()) |
| 115 return; | 115 return; |
| 116 Ostream &Str = Func->getContext()->getStrEmit(); | 116 Ostream &Str = Func->getContext()->getStrEmit(); |
| 117 assert(Inst->getSrcSize() == 2); | 117 assert(Inst->getSrcSize() == 2); |
| 118 Str << "\t" << Opcode << (SetFlags ? "s" : "") << Inst->getPredicate() | 118 Str << "\t" << Opcode << (SetFlags ? "s" : "") << Inst->getPredicate() |
| 119 << "\t"; | 119 << "\t"; |
| 120 Inst->getDest()->emit(Func); | 120 Inst->getDest()->emit(Func); |
| 121 Str << ", "; | 121 Str << ", "; |
| 122 Inst->getSrc(0)->emit(Func); | 122 Inst->getSrc(0)->emit(Func); |
| 123 Str << ", "; | 123 Str << ", "; |
| 124 Inst->getSrc(1)->emit(Func); | 124 Inst->getSrc(1)->emit(Func); |
| (...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 343 template <> const char *InstARM32Eor::Opcode = "eor"; | 343 template <> const char *InstARM32Eor::Opcode = "eor"; |
| 344 template <> const char *InstARM32Lsl::Opcode = "lsl"; | 344 template <> const char *InstARM32Lsl::Opcode = "lsl"; |
| 345 template <> const char *InstARM32Lsr::Opcode = "lsr"; | 345 template <> const char *InstARM32Lsr::Opcode = "lsr"; |
| 346 template <> const char *InstARM32Mul::Opcode = "mul"; | 346 template <> const char *InstARM32Mul::Opcode = "mul"; |
| 347 template <> const char *InstARM32Orr::Opcode = "orr"; | 347 template <> const char *InstARM32Orr::Opcode = "orr"; |
| 348 template <> const char *InstARM32Rsb::Opcode = "rsb"; | 348 template <> const char *InstARM32Rsb::Opcode = "rsb"; |
| 349 template <> const char *InstARM32Sbc::Opcode = "sbc"; | 349 template <> const char *InstARM32Sbc::Opcode = "sbc"; |
| 350 template <> const char *InstARM32Sub::Opcode = "sub"; | 350 template <> const char *InstARM32Sub::Opcode = "sub"; |
| 351 | 351 |
| 352 void InstARM32::dump(const Cfg *Func) const { | 352 void InstARM32::dump(const Cfg *Func) const { |
| 353 if (!ALLOW_DUMP) | 353 if (!buildAllowsDump()) |
| 354 return; | 354 return; |
| 355 Ostream &Str = Func->getContext()->getStrDump(); | 355 Ostream &Str = Func->getContext()->getStrDump(); |
| 356 Str << "[ARM32] "; | 356 Str << "[ARM32] "; |
| 357 Inst::dump(Func); | 357 Inst::dump(Func); |
| 358 } | 358 } |
| 359 | 359 |
| 360 template <> void InstARM32Mov::emit(const Cfg *Func) const { | 360 template <> void InstARM32Mov::emit(const Cfg *Func) const { |
| 361 if (!ALLOW_DUMP) | 361 if (!buildAllowsDump()) |
| 362 return; | 362 return; |
| 363 Ostream &Str = Func->getContext()->getStrEmit(); | 363 Ostream &Str = Func->getContext()->getStrEmit(); |
| 364 assert(getSrcSize() == 1); | 364 assert(getSrcSize() == 1); |
| 365 Variable *Dest = getDest(); | 365 Variable *Dest = getDest(); |
| 366 if (Dest->hasReg()) { | 366 if (Dest->hasReg()) { |
| 367 IceString Opcode = "mov"; | 367 IceString Opcode = "mov"; |
| 368 Operand *Src0 = getSrc(0); | 368 Operand *Src0 = getSrc(0); |
| 369 if (const auto *Src0V = llvm::dyn_cast<Variable>(Src0)) { | 369 if (const auto *Src0V = llvm::dyn_cast<Variable>(Src0)) { |
| 370 if (!Src0V->hasReg()) { | 370 if (!Src0V->hasReg()) { |
| 371 Opcode = IceString("ldr"); // Always use the whole stack slot. | 371 Opcode = IceString("ldr"); // Always use the whole stack slot. |
| (...skipping 17 matching lines...) Expand all Loading... |
| 389 } | 389 } |
| 390 } | 390 } |
| 391 | 391 |
| 392 template <> void InstARM32Mov::emitIAS(const Cfg *Func) const { | 392 template <> void InstARM32Mov::emitIAS(const Cfg *Func) const { |
| 393 assert(getSrcSize() == 1); | 393 assert(getSrcSize() == 1); |
| 394 (void)Func; | 394 (void)Func; |
| 395 llvm_unreachable("Not yet implemented"); | 395 llvm_unreachable("Not yet implemented"); |
| 396 } | 396 } |
| 397 | 397 |
| 398 void InstARM32Br::emit(const Cfg *Func) const { | 398 void InstARM32Br::emit(const Cfg *Func) const { |
| 399 if (!ALLOW_DUMP) | 399 if (!buildAllowsDump()) |
| 400 return; | 400 return; |
| 401 Ostream &Str = Func->getContext()->getStrEmit(); | 401 Ostream &Str = Func->getContext()->getStrEmit(); |
| 402 Str << "\t" | 402 Str << "\t" |
| 403 << "b" << getPredicate() << "\t"; | 403 << "b" << getPredicate() << "\t"; |
| 404 if (isUnconditionalBranch()) { | 404 if (isUnconditionalBranch()) { |
| 405 Str << getTargetFalse()->getAsmName(); | 405 Str << getTargetFalse()->getAsmName(); |
| 406 } else { | 406 } else { |
| 407 Str << getTargetTrue()->getAsmName(); | 407 Str << getTargetTrue()->getAsmName(); |
| 408 if (getTargetFalse()) { | 408 if (getTargetFalse()) { |
| 409 Str << "\n\t" | 409 Str << "\n\t" |
| 410 << "b" | 410 << "b" |
| 411 << "\t" << getTargetFalse()->getAsmName(); | 411 << "\t" << getTargetFalse()->getAsmName(); |
| 412 } | 412 } |
| 413 } | 413 } |
| 414 } | 414 } |
| 415 | 415 |
| 416 void InstARM32Br::emitIAS(const Cfg *Func) const { | 416 void InstARM32Br::emitIAS(const Cfg *Func) const { |
| 417 (void)Func; | 417 (void)Func; |
| 418 llvm_unreachable("Not yet implemented"); | 418 llvm_unreachable("Not yet implemented"); |
| 419 } | 419 } |
| 420 | 420 |
| 421 void InstARM32Br::dump(const Cfg *Func) const { | 421 void InstARM32Br::dump(const Cfg *Func) const { |
| 422 if (!ALLOW_DUMP) | 422 if (!buildAllowsDump()) |
| 423 return; | 423 return; |
| 424 Ostream &Str = Func->getContext()->getStrDump(); | 424 Ostream &Str = Func->getContext()->getStrDump(); |
| 425 Str << "br "; | 425 Str << "br "; |
| 426 | 426 |
| 427 if (getPredicate() == CondARM32::AL) { | 427 if (getPredicate() == CondARM32::AL) { |
| 428 Str << "label %" << getTargetFalse()->getName(); | 428 Str << "label %" << getTargetFalse()->getName(); |
| 429 return; | 429 return; |
| 430 } | 430 } |
| 431 | 431 |
| 432 Str << getPredicate() << ", label %" << getTargetTrue()->getName(); | 432 Str << getPredicate() << ", label %" << getTargetTrue()->getName(); |
| 433 if (getTargetFalse()) { | 433 if (getTargetFalse()) { |
| 434 Str << ", label %" << getTargetFalse()->getName(); | 434 Str << ", label %" << getTargetFalse()->getName(); |
| 435 } | 435 } |
| 436 } | 436 } |
| 437 | 437 |
| 438 void InstARM32Call::emit(const Cfg *Func) const { | 438 void InstARM32Call::emit(const Cfg *Func) const { |
| 439 if (!ALLOW_DUMP) | 439 if (!buildAllowsDump()) |
| 440 return; | 440 return; |
| 441 Ostream &Str = Func->getContext()->getStrEmit(); | 441 Ostream &Str = Func->getContext()->getStrEmit(); |
| 442 assert(getSrcSize() == 1); | 442 assert(getSrcSize() == 1); |
| 443 if (llvm::isa<ConstantInteger32>(getCallTarget())) { | 443 if (llvm::isa<ConstantInteger32>(getCallTarget())) { |
| 444 // This shouldn't happen (typically have to copy the full 32-bits | 444 // This shouldn't happen (typically have to copy the full 32-bits |
| 445 // to a register and do an indirect jump). | 445 // to a register and do an indirect jump). |
| 446 llvm::report_fatal_error("ARM32Call to ConstantInteger32"); | 446 llvm::report_fatal_error("ARM32Call to ConstantInteger32"); |
| 447 } else if (const auto CallTarget = | 447 } else if (const auto CallTarget = |
| 448 llvm::dyn_cast<ConstantRelocatable>(getCallTarget())) { | 448 llvm::dyn_cast<ConstantRelocatable>(getCallTarget())) { |
| 449 // Calls only have 24-bits, but the linker should insert veneers to | 449 // Calls only have 24-bits, but the linker should insert veneers to |
| (...skipping 10 matching lines...) Expand all Loading... |
| 460 } | 460 } |
| 461 Func->getTarget()->resetStackAdjustment(); | 461 Func->getTarget()->resetStackAdjustment(); |
| 462 } | 462 } |
| 463 | 463 |
| 464 void InstARM32Call::emitIAS(const Cfg *Func) const { | 464 void InstARM32Call::emitIAS(const Cfg *Func) const { |
| 465 (void)Func; | 465 (void)Func; |
| 466 llvm_unreachable("Not yet implemented"); | 466 llvm_unreachable("Not yet implemented"); |
| 467 } | 467 } |
| 468 | 468 |
| 469 void InstARM32Call::dump(const Cfg *Func) const { | 469 void InstARM32Call::dump(const Cfg *Func) const { |
| 470 if (!ALLOW_DUMP) | 470 if (!buildAllowsDump()) |
| 471 return; | 471 return; |
| 472 Ostream &Str = Func->getContext()->getStrDump(); | 472 Ostream &Str = Func->getContext()->getStrDump(); |
| 473 if (getDest()) { | 473 if (getDest()) { |
| 474 dumpDest(Func); | 474 dumpDest(Func); |
| 475 Str << " = "; | 475 Str << " = "; |
| 476 } | 476 } |
| 477 Str << "call "; | 477 Str << "call "; |
| 478 getCallTarget()->dump(Func); | 478 getCallTarget()->dump(Func); |
| 479 } | 479 } |
| 480 | 480 |
| 481 void InstARM32Cmp::emit(const Cfg *Func) const { | 481 void InstARM32Cmp::emit(const Cfg *Func) const { |
| 482 if (!ALLOW_DUMP) | 482 if (!buildAllowsDump()) |
| 483 return; | 483 return; |
| 484 Ostream &Str = Func->getContext()->getStrEmit(); | 484 Ostream &Str = Func->getContext()->getStrEmit(); |
| 485 assert(getSrcSize() == 2); | 485 assert(getSrcSize() == 2); |
| 486 Str << "\t" | 486 Str << "\t" |
| 487 << "cmp" << getPredicate() << "\t"; | 487 << "cmp" << getPredicate() << "\t"; |
| 488 getSrc(0)->emit(Func); | 488 getSrc(0)->emit(Func); |
| 489 Str << ", "; | 489 Str << ", "; |
| 490 getSrc(1)->emit(Func); | 490 getSrc(1)->emit(Func); |
| 491 } | 491 } |
| 492 | 492 |
| 493 void InstARM32Cmp::emitIAS(const Cfg *Func) const { | 493 void InstARM32Cmp::emitIAS(const Cfg *Func) const { |
| 494 assert(getSrcSize() == 2); | 494 assert(getSrcSize() == 2); |
| 495 (void)Func; | 495 (void)Func; |
| 496 llvm_unreachable("Not yet implemented"); | 496 llvm_unreachable("Not yet implemented"); |
| 497 } | 497 } |
| 498 | 498 |
| 499 void InstARM32Cmp::dump(const Cfg *Func) const { | 499 void InstARM32Cmp::dump(const Cfg *Func) const { |
| 500 if (!ALLOW_DUMP) | 500 if (!buildAllowsDump()) |
| 501 return; | 501 return; |
| 502 Ostream &Str = Func->getContext()->getStrDump(); | 502 Ostream &Str = Func->getContext()->getStrDump(); |
| 503 dumpOpcodePred(Str, "cmp", getSrc(0)->getType()); | 503 dumpOpcodePred(Str, "cmp", getSrc(0)->getType()); |
| 504 dumpSources(Func); | 504 dumpSources(Func); |
| 505 } | 505 } |
| 506 | 506 |
| 507 void InstARM32Ldr::emit(const Cfg *Func) const { | 507 void InstARM32Ldr::emit(const Cfg *Func) const { |
| 508 if (!ALLOW_DUMP) | 508 if (!buildAllowsDump()) |
| 509 return; | 509 return; |
| 510 Ostream &Str = Func->getContext()->getStrEmit(); | 510 Ostream &Str = Func->getContext()->getStrEmit(); |
| 511 assert(getSrcSize() == 1); | 511 assert(getSrcSize() == 1); |
| 512 assert(getDest()->hasReg()); | 512 assert(getDest()->hasReg()); |
| 513 Type Ty = getSrc(0)->getType(); | 513 Type Ty = getSrc(0)->getType(); |
| 514 Str << "\t" | 514 Str << "\t" |
| 515 << "ldr" << getWidthString(Ty) << getPredicate() << "\t"; | 515 << "ldr" << getWidthString(Ty) << getPredicate() << "\t"; |
| 516 getDest()->emit(Func); | 516 getDest()->emit(Func); |
| 517 Str << ", "; | 517 Str << ", "; |
| 518 getSrc(0)->emit(Func); | 518 getSrc(0)->emit(Func); |
| 519 } | 519 } |
| 520 | 520 |
| 521 void InstARM32Ldr::emitIAS(const Cfg *Func) const { | 521 void InstARM32Ldr::emitIAS(const Cfg *Func) const { |
| 522 assert(getSrcSize() == 1); | 522 assert(getSrcSize() == 1); |
| 523 (void)Func; | 523 (void)Func; |
| 524 llvm_unreachable("Not yet implemented"); | 524 llvm_unreachable("Not yet implemented"); |
| 525 } | 525 } |
| 526 | 526 |
| 527 void InstARM32Ldr::dump(const Cfg *Func) const { | 527 void InstARM32Ldr::dump(const Cfg *Func) const { |
| 528 if (!ALLOW_DUMP) | 528 if (!buildAllowsDump()) |
| 529 return; | 529 return; |
| 530 Ostream &Str = Func->getContext()->getStrDump(); | 530 Ostream &Str = Func->getContext()->getStrDump(); |
| 531 dumpDest(Func); | 531 dumpDest(Func); |
| 532 Str << " = "; | 532 Str << " = "; |
| 533 dumpOpcodePred(Str, "ldr", getDest()->getType()); | 533 dumpOpcodePred(Str, "ldr", getDest()->getType()); |
| 534 Str << " "; | 534 Str << " "; |
| 535 dumpSources(Func); | 535 dumpSources(Func); |
| 536 } | 536 } |
| 537 | 537 |
| 538 void InstARM32Mla::emit(const Cfg *Func) const { | 538 void InstARM32Mla::emit(const Cfg *Func) const { |
| 539 if (!ALLOW_DUMP) | 539 if (!buildAllowsDump()) |
| 540 return; | 540 return; |
| 541 Ostream &Str = Func->getContext()->getStrEmit(); | 541 Ostream &Str = Func->getContext()->getStrEmit(); |
| 542 assert(getSrcSize() == 3); | 542 assert(getSrcSize() == 3); |
| 543 assert(getDest()->hasReg()); | 543 assert(getDest()->hasReg()); |
| 544 Str << "\t" | 544 Str << "\t" |
| 545 << "mla" << getPredicate() << "\t"; | 545 << "mla" << getPredicate() << "\t"; |
| 546 getDest()->emit(Func); | 546 getDest()->emit(Func); |
| 547 Str << ", "; | 547 Str << ", "; |
| 548 getSrc(0)->emit(Func); | 548 getSrc(0)->emit(Func); |
| 549 Str << ", "; | 549 Str << ", "; |
| 550 getSrc(1)->emit(Func); | 550 getSrc(1)->emit(Func); |
| 551 Str << ", "; | 551 Str << ", "; |
| 552 getSrc(2)->emit(Func); | 552 getSrc(2)->emit(Func); |
| 553 } | 553 } |
| 554 | 554 |
| 555 void InstARM32Mla::emitIAS(const Cfg *Func) const { | 555 void InstARM32Mla::emitIAS(const Cfg *Func) const { |
| 556 assert(getSrcSize() == 3); | 556 assert(getSrcSize() == 3); |
| 557 (void)Func; | 557 (void)Func; |
| 558 llvm_unreachable("Not yet implemented"); | 558 llvm_unreachable("Not yet implemented"); |
| 559 } | 559 } |
| 560 | 560 |
| 561 void InstARM32Mla::dump(const Cfg *Func) const { | 561 void InstARM32Mla::dump(const Cfg *Func) const { |
| 562 if (!ALLOW_DUMP) | 562 if (!buildAllowsDump()) |
| 563 return; | 563 return; |
| 564 Ostream &Str = Func->getContext()->getStrDump(); | 564 Ostream &Str = Func->getContext()->getStrDump(); |
| 565 dumpDest(Func); | 565 dumpDest(Func); |
| 566 Str << " = "; | 566 Str << " = "; |
| 567 dumpOpcodePred(Str, "mla", getDest()->getType()); | 567 dumpOpcodePred(Str, "mla", getDest()->getType()); |
| 568 Str << " "; | 568 Str << " "; |
| 569 dumpSources(Func); | 569 dumpSources(Func); |
| 570 } | 570 } |
| 571 | 571 |
| 572 template <> void InstARM32Movw::emit(const Cfg *Func) const { | 572 template <> void InstARM32Movw::emit(const Cfg *Func) const { |
| 573 if (!ALLOW_DUMP) | 573 if (!buildAllowsDump()) |
| 574 return; | 574 return; |
| 575 Ostream &Str = Func->getContext()->getStrEmit(); | 575 Ostream &Str = Func->getContext()->getStrEmit(); |
| 576 assert(getSrcSize() == 1); | 576 assert(getSrcSize() == 1); |
| 577 Str << "\t" << Opcode << getPredicate() << "\t"; | 577 Str << "\t" << Opcode << getPredicate() << "\t"; |
| 578 getDest()->emit(Func); | 578 getDest()->emit(Func); |
| 579 Str << ", "; | 579 Str << ", "; |
| 580 Constant *Src0 = llvm::cast<Constant>(getSrc(0)); | 580 Constant *Src0 = llvm::cast<Constant>(getSrc(0)); |
| 581 if (auto CR = llvm::dyn_cast<ConstantRelocatable>(Src0)) { | 581 if (auto CR = llvm::dyn_cast<ConstantRelocatable>(Src0)) { |
| 582 Str << "#:lower16:"; | 582 Str << "#:lower16:"; |
| 583 CR->emitWithoutPrefix(Func->getTarget()); | 583 CR->emitWithoutPrefix(Func->getTarget()); |
| 584 } else { | 584 } else { |
| 585 Src0->emit(Func); | 585 Src0->emit(Func); |
| 586 } | 586 } |
| 587 } | 587 } |
| 588 | 588 |
| 589 template <> void InstARM32Movt::emit(const Cfg *Func) const { | 589 template <> void InstARM32Movt::emit(const Cfg *Func) const { |
| 590 if (!ALLOW_DUMP) | 590 if (!buildAllowsDump()) |
| 591 return; | 591 return; |
| 592 Ostream &Str = Func->getContext()->getStrEmit(); | 592 Ostream &Str = Func->getContext()->getStrEmit(); |
| 593 assert(getSrcSize() == 2); | 593 assert(getSrcSize() == 2); |
| 594 Variable *Dest = getDest(); | 594 Variable *Dest = getDest(); |
| 595 Constant *Src1 = llvm::cast<Constant>(getSrc(1)); | 595 Constant *Src1 = llvm::cast<Constant>(getSrc(1)); |
| 596 Str << "\t" << Opcode << getPredicate() << "\t"; | 596 Str << "\t" << Opcode << getPredicate() << "\t"; |
| 597 Dest->emit(Func); | 597 Dest->emit(Func); |
| 598 Str << ", "; | 598 Str << ", "; |
| 599 if (auto CR = llvm::dyn_cast<ConstantRelocatable>(Src1)) { | 599 if (auto CR = llvm::dyn_cast<ConstantRelocatable>(Src1)) { |
| 600 Str << "#:upper16:"; | 600 Str << "#:upper16:"; |
| 601 CR->emitWithoutPrefix(Func->getTarget()); | 601 CR->emitWithoutPrefix(Func->getTarget()); |
| 602 } else { | 602 } else { |
| 603 Src1->emit(Func); | 603 Src1->emit(Func); |
| 604 } | 604 } |
| 605 } | 605 } |
| 606 | 606 |
| 607 void InstARM32Pop::emit(const Cfg *Func) const { | 607 void InstARM32Pop::emit(const Cfg *Func) const { |
| 608 if (!ALLOW_DUMP) | 608 if (!buildAllowsDump()) |
| 609 return; | 609 return; |
| 610 assert(Dests.size() > 0); | 610 assert(Dests.size() > 0); |
| 611 Ostream &Str = Func->getContext()->getStrEmit(); | 611 Ostream &Str = Func->getContext()->getStrEmit(); |
| 612 Str << "\t" | 612 Str << "\t" |
| 613 << "pop" | 613 << "pop" |
| 614 << "\t{"; | 614 << "\t{"; |
| 615 for (SizeT I = 0; I < Dests.size(); ++I) { | 615 for (SizeT I = 0; I < Dests.size(); ++I) { |
| 616 if (I > 0) | 616 if (I > 0) |
| 617 Str << ", "; | 617 Str << ", "; |
| 618 Dests[I]->emit(Func); | 618 Dests[I]->emit(Func); |
| 619 } | 619 } |
| 620 Str << "}"; | 620 Str << "}"; |
| 621 } | 621 } |
| 622 | 622 |
| 623 void InstARM32Pop::emitIAS(const Cfg *Func) const { | 623 void InstARM32Pop::emitIAS(const Cfg *Func) const { |
| 624 (void)Func; | 624 (void)Func; |
| 625 llvm_unreachable("Not yet implemented"); | 625 llvm_unreachable("Not yet implemented"); |
| 626 } | 626 } |
| 627 | 627 |
| 628 void InstARM32Pop::dump(const Cfg *Func) const { | 628 void InstARM32Pop::dump(const Cfg *Func) const { |
| 629 if (!ALLOW_DUMP) | 629 if (!buildAllowsDump()) |
| 630 return; | 630 return; |
| 631 Ostream &Str = Func->getContext()->getStrDump(); | 631 Ostream &Str = Func->getContext()->getStrDump(); |
| 632 Str << "pop" | 632 Str << "pop" |
| 633 << " "; | 633 << " "; |
| 634 for (SizeT I = 0; I < Dests.size(); ++I) { | 634 for (SizeT I = 0; I < Dests.size(); ++I) { |
| 635 if (I > 0) | 635 if (I > 0) |
| 636 Str << ", "; | 636 Str << ", "; |
| 637 Dests[I]->dump(Func); | 637 Dests[I]->dump(Func); |
| 638 } | 638 } |
| 639 } | 639 } |
| 640 | 640 |
| 641 void InstARM32AdjustStack::emit(const Cfg *Func) const { | 641 void InstARM32AdjustStack::emit(const Cfg *Func) const { |
| 642 if (!ALLOW_DUMP) | 642 if (!buildAllowsDump()) |
| 643 return; | 643 return; |
| 644 Ostream &Str = Func->getContext()->getStrEmit(); | 644 Ostream &Str = Func->getContext()->getStrEmit(); |
| 645 assert(getSrcSize() == 2); | 645 assert(getSrcSize() == 2); |
| 646 Str << "\t" | 646 Str << "\t" |
| 647 << "sub" | 647 << "sub" |
| 648 << "\t"; | 648 << "\t"; |
| 649 getDest()->emit(Func); | 649 getDest()->emit(Func); |
| 650 Str << ", "; | 650 Str << ", "; |
| 651 getSrc(0)->emit(Func); | 651 getSrc(0)->emit(Func); |
| 652 Str << ", "; | 652 Str << ", "; |
| 653 getSrc(1)->emit(Func); | 653 getSrc(1)->emit(Func); |
| 654 Func->getTarget()->updateStackAdjustment(Amount); | 654 Func->getTarget()->updateStackAdjustment(Amount); |
| 655 } | 655 } |
| 656 | 656 |
| 657 void InstARM32AdjustStack::emitIAS(const Cfg *Func) const { | 657 void InstARM32AdjustStack::emitIAS(const Cfg *Func) const { |
| 658 (void)Func; | 658 (void)Func; |
| 659 llvm_unreachable("Not yet implemented"); | 659 llvm_unreachable("Not yet implemented"); |
| 660 Func->getTarget()->updateStackAdjustment(Amount); | 660 Func->getTarget()->updateStackAdjustment(Amount); |
| 661 } | 661 } |
| 662 | 662 |
| 663 void InstARM32AdjustStack::dump(const Cfg *Func) const { | 663 void InstARM32AdjustStack::dump(const Cfg *Func) const { |
| 664 if (!ALLOW_DUMP) | 664 if (!buildAllowsDump()) |
| 665 return; | 665 return; |
| 666 Ostream &Str = Func->getContext()->getStrDump(); | 666 Ostream &Str = Func->getContext()->getStrDump(); |
| 667 getDest()->dump(Func); | 667 getDest()->dump(Func); |
| 668 Str << " = sub.i32 "; | 668 Str << " = sub.i32 "; |
| 669 getSrc(0)->dump(Func); | 669 getSrc(0)->dump(Func); |
| 670 Str << ", " << Amount << " ; "; | 670 Str << ", " << Amount << " ; "; |
| 671 getSrc(1)->dump(Func); | 671 getSrc(1)->dump(Func); |
| 672 } | 672 } |
| 673 | 673 |
| 674 void InstARM32Push::emit(const Cfg *Func) const { | 674 void InstARM32Push::emit(const Cfg *Func) const { |
| 675 if (!ALLOW_DUMP) | 675 if (!buildAllowsDump()) |
| 676 return; | 676 return; |
| 677 assert(getSrcSize() > 0); | 677 assert(getSrcSize() > 0); |
| 678 Ostream &Str = Func->getContext()->getStrEmit(); | 678 Ostream &Str = Func->getContext()->getStrEmit(); |
| 679 Str << "\t" | 679 Str << "\t" |
| 680 << "push" | 680 << "push" |
| 681 << "\t{"; | 681 << "\t{"; |
| 682 emitSources(Func); | 682 emitSources(Func); |
| 683 Str << "}"; | 683 Str << "}"; |
| 684 } | 684 } |
| 685 | 685 |
| 686 void InstARM32Push::emitIAS(const Cfg *Func) const { | 686 void InstARM32Push::emitIAS(const Cfg *Func) const { |
| 687 (void)Func; | 687 (void)Func; |
| 688 llvm_unreachable("Not yet implemented"); | 688 llvm_unreachable("Not yet implemented"); |
| 689 } | 689 } |
| 690 | 690 |
| 691 void InstARM32Push::dump(const Cfg *Func) const { | 691 void InstARM32Push::dump(const Cfg *Func) const { |
| 692 if (!ALLOW_DUMP) | 692 if (!buildAllowsDump()) |
| 693 return; | 693 return; |
| 694 Ostream &Str = Func->getContext()->getStrDump(); | 694 Ostream &Str = Func->getContext()->getStrDump(); |
| 695 Str << "push" | 695 Str << "push" |
| 696 << " "; | 696 << " "; |
| 697 dumpSources(Func); | 697 dumpSources(Func); |
| 698 } | 698 } |
| 699 | 699 |
| 700 void InstARM32Ret::emit(const Cfg *Func) const { | 700 void InstARM32Ret::emit(const Cfg *Func) const { |
| 701 if (!ALLOW_DUMP) | 701 if (!buildAllowsDump()) |
| 702 return; | 702 return; |
| 703 assert(getSrcSize() > 0); | 703 assert(getSrcSize() > 0); |
| 704 Variable *LR = llvm::cast<Variable>(getSrc(0)); | 704 Variable *LR = llvm::cast<Variable>(getSrc(0)); |
| 705 assert(LR->hasReg()); | 705 assert(LR->hasReg()); |
| 706 assert(LR->getRegNum() == RegARM32::Reg_lr); | 706 assert(LR->getRegNum() == RegARM32::Reg_lr); |
| 707 Ostream &Str = Func->getContext()->getStrEmit(); | 707 Ostream &Str = Func->getContext()->getStrEmit(); |
| 708 Str << "\t" | 708 Str << "\t" |
| 709 << "bx" | 709 << "bx" |
| 710 << "\t"; | 710 << "\t"; |
| 711 LR->emit(Func); | 711 LR->emit(Func); |
| 712 } | 712 } |
| 713 | 713 |
| 714 void InstARM32Ret::emitIAS(const Cfg *Func) const { | 714 void InstARM32Ret::emitIAS(const Cfg *Func) const { |
| 715 (void)Func; | 715 (void)Func; |
| 716 llvm_unreachable("Not yet implemented"); | 716 llvm_unreachable("Not yet implemented"); |
| 717 } | 717 } |
| 718 | 718 |
| 719 void InstARM32Ret::dump(const Cfg *Func) const { | 719 void InstARM32Ret::dump(const Cfg *Func) const { |
| 720 if (!ALLOW_DUMP) | 720 if (!buildAllowsDump()) |
| 721 return; | 721 return; |
| 722 Ostream &Str = Func->getContext()->getStrDump(); | 722 Ostream &Str = Func->getContext()->getStrDump(); |
| 723 Type Ty = (getSrcSize() == 1 ? IceType_void : getSrc(0)->getType()); | 723 Type Ty = (getSrcSize() == 1 ? IceType_void : getSrc(0)->getType()); |
| 724 Str << "ret." << Ty << " "; | 724 Str << "ret." << Ty << " "; |
| 725 dumpSources(Func); | 725 dumpSources(Func); |
| 726 } | 726 } |
| 727 | 727 |
| 728 void InstARM32Str::emit(const Cfg *Func) const { | 728 void InstARM32Str::emit(const Cfg *Func) const { |
| 729 if (!ALLOW_DUMP) | 729 if (!buildAllowsDump()) |
| 730 return; | 730 return; |
| 731 Ostream &Str = Func->getContext()->getStrEmit(); | 731 Ostream &Str = Func->getContext()->getStrEmit(); |
| 732 assert(getSrcSize() == 2); | 732 assert(getSrcSize() == 2); |
| 733 Type Ty = getSrc(0)->getType(); | 733 Type Ty = getSrc(0)->getType(); |
| 734 Str << "\t" | 734 Str << "\t" |
| 735 << "str" << getWidthString(Ty) << getPredicate() << "\t"; | 735 << "str" << getWidthString(Ty) << getPredicate() << "\t"; |
| 736 getSrc(0)->emit(Func); | 736 getSrc(0)->emit(Func); |
| 737 Str << ", "; | 737 Str << ", "; |
| 738 getSrc(1)->emit(Func); | 738 getSrc(1)->emit(Func); |
| 739 } | 739 } |
| 740 | 740 |
| 741 void InstARM32Str::emitIAS(const Cfg *Func) const { | 741 void InstARM32Str::emitIAS(const Cfg *Func) const { |
| 742 assert(getSrcSize() == 2); | 742 assert(getSrcSize() == 2); |
| 743 (void)Func; | 743 (void)Func; |
| 744 llvm_unreachable("Not yet implemented"); | 744 llvm_unreachable("Not yet implemented"); |
| 745 } | 745 } |
| 746 | 746 |
| 747 void InstARM32Str::dump(const Cfg *Func) const { | 747 void InstARM32Str::dump(const Cfg *Func) const { |
| 748 if (!ALLOW_DUMP) | 748 if (!buildAllowsDump()) |
| 749 return; | 749 return; |
| 750 Ostream &Str = Func->getContext()->getStrDump(); | 750 Ostream &Str = Func->getContext()->getStrDump(); |
| 751 Type Ty = getSrc(0)->getType(); | 751 Type Ty = getSrc(0)->getType(); |
| 752 dumpOpcodePred(Str, "str", Ty); | 752 dumpOpcodePred(Str, "str", Ty); |
| 753 Str << " "; | 753 Str << " "; |
| 754 getSrc(1)->dump(Func); | 754 getSrc(1)->dump(Func); |
| 755 Str << ", "; | 755 Str << ", "; |
| 756 getSrc(0)->dump(Func); | 756 getSrc(0)->dump(Func); |
| 757 } | 757 } |
| 758 | 758 |
| 759 void InstARM32Umull::emit(const Cfg *Func) const { | 759 void InstARM32Umull::emit(const Cfg *Func) const { |
| 760 if (!ALLOW_DUMP) | 760 if (!buildAllowsDump()) |
| 761 return; | 761 return; |
| 762 Ostream &Str = Func->getContext()->getStrEmit(); | 762 Ostream &Str = Func->getContext()->getStrEmit(); |
| 763 assert(getSrcSize() == 2); | 763 assert(getSrcSize() == 2); |
| 764 assert(getDest()->hasReg()); | 764 assert(getDest()->hasReg()); |
| 765 Str << "\t" | 765 Str << "\t" |
| 766 << "umull" << getPredicate() << "\t"; | 766 << "umull" << getPredicate() << "\t"; |
| 767 getDest()->emit(Func); | 767 getDest()->emit(Func); |
| 768 Str << ", "; | 768 Str << ", "; |
| 769 DestHi->emit(Func); | 769 DestHi->emit(Func); |
| 770 Str << ", "; | 770 Str << ", "; |
| 771 getSrc(0)->emit(Func); | 771 getSrc(0)->emit(Func); |
| 772 Str << ", "; | 772 Str << ", "; |
| 773 getSrc(1)->emit(Func); | 773 getSrc(1)->emit(Func); |
| 774 } | 774 } |
| 775 | 775 |
| 776 void InstARM32Umull::emitIAS(const Cfg *Func) const { | 776 void InstARM32Umull::emitIAS(const Cfg *Func) const { |
| 777 assert(getSrcSize() == 2); | 777 assert(getSrcSize() == 2); |
| 778 (void)Func; | 778 (void)Func; |
| 779 llvm_unreachable("Not yet implemented"); | 779 llvm_unreachable("Not yet implemented"); |
| 780 } | 780 } |
| 781 | 781 |
| 782 void InstARM32Umull::dump(const Cfg *Func) const { | 782 void InstARM32Umull::dump(const Cfg *Func) const { |
| 783 if (!ALLOW_DUMP) | 783 if (!buildAllowsDump()) |
| 784 return; | 784 return; |
| 785 Ostream &Str = Func->getContext()->getStrDump(); | 785 Ostream &Str = Func->getContext()->getStrDump(); |
| 786 dumpDest(Func); | 786 dumpDest(Func); |
| 787 Str << " = "; | 787 Str << " = "; |
| 788 dumpOpcodePred(Str, "umull", getDest()->getType()); | 788 dumpOpcodePred(Str, "umull", getDest()->getType()); |
| 789 Str << " "; | 789 Str << " "; |
| 790 dumpSources(Func); | 790 dumpSources(Func); |
| 791 } | 791 } |
| 792 | 792 |
| 793 void OperandARM32Mem::emit(const Cfg *Func) const { | 793 void OperandARM32Mem::emit(const Cfg *Func) const { |
| 794 if (!ALLOW_DUMP) | 794 if (!buildAllowsDump()) |
| 795 return; | 795 return; |
| 796 Ostream &Str = Func->getContext()->getStrEmit(); | 796 Ostream &Str = Func->getContext()->getStrEmit(); |
| 797 Str << "["; | 797 Str << "["; |
| 798 getBase()->emit(Func); | 798 getBase()->emit(Func); |
| 799 switch (getAddrMode()) { | 799 switch (getAddrMode()) { |
| 800 case PostIndex: | 800 case PostIndex: |
| 801 case NegPostIndex: | 801 case NegPostIndex: |
| 802 Str << "], "; | 802 Str << "], "; |
| 803 break; | 803 break; |
| 804 default: | 804 default: |
| (...skipping 22 matching lines...) Expand all Loading... |
| 827 Str << "]!"; | 827 Str << "]!"; |
| 828 break; | 828 break; |
| 829 case PostIndex: | 829 case PostIndex: |
| 830 case NegPostIndex: | 830 case NegPostIndex: |
| 831 // Brace is already closed off. | 831 // Brace is already closed off. |
| 832 break; | 832 break; |
| 833 } | 833 } |
| 834 } | 834 } |
| 835 | 835 |
| 836 void OperandARM32Mem::dump(const Cfg *Func, Ostream &Str) const { | 836 void OperandARM32Mem::dump(const Cfg *Func, Ostream &Str) const { |
| 837 if (!ALLOW_DUMP) | 837 if (!buildAllowsDump()) |
| 838 return; | 838 return; |
| 839 Str << "["; | 839 Str << "["; |
| 840 if (Func) | 840 if (Func) |
| 841 getBase()->dump(Func); | 841 getBase()->dump(Func); |
| 842 else | 842 else |
| 843 getBase()->dump(Str); | 843 getBase()->dump(Str); |
| 844 Str << ", "; | 844 Str << ", "; |
| 845 if (isRegReg()) { | 845 if (isRegReg()) { |
| 846 if (isNegAddrMode()) { | 846 if (isNegAddrMode()) { |
| 847 Str << "-"; | 847 Str << "-"; |
| 848 } | 848 } |
| 849 if (Func) | 849 if (Func) |
| 850 getIndex()->dump(Func); | 850 getIndex()->dump(Func); |
| 851 else | 851 else |
| 852 getIndex()->dump(Str); | 852 getIndex()->dump(Str); |
| 853 if (getShiftOp() != kNoShift) { | 853 if (getShiftOp() != kNoShift) { |
| 854 Str << ", " << InstARM32ShiftAttributes[getShiftOp()].EmitString << " #" | 854 Str << ", " << InstARM32ShiftAttributes[getShiftOp()].EmitString << " #" |
| 855 << getShiftAmt(); | 855 << getShiftAmt(); |
| 856 } | 856 } |
| 857 } else { | 857 } else { |
| 858 getOffset()->dump(Func, Str); | 858 getOffset()->dump(Func, Str); |
| 859 } | 859 } |
| 860 Str << "] AddrMode==" << getAddrMode(); | 860 Str << "] AddrMode==" << getAddrMode(); |
| 861 } | 861 } |
| 862 | 862 |
| 863 void OperandARM32FlexImm::emit(const Cfg *Func) const { | 863 void OperandARM32FlexImm::emit(const Cfg *Func) const { |
| 864 if (!ALLOW_DUMP) | 864 if (!buildAllowsDump()) |
| 865 return; | 865 return; |
| 866 Ostream &Str = Func->getContext()->getStrEmit(); | 866 Ostream &Str = Func->getContext()->getStrEmit(); |
| 867 uint32_t Imm = getImm(); | 867 uint32_t Imm = getImm(); |
| 868 uint32_t RotateAmt = getRotateAmt(); | 868 uint32_t RotateAmt = getRotateAmt(); |
| 869 Str << "#" << Utils::rotateRight32(Imm, 2 * RotateAmt); | 869 Str << "#" << Utils::rotateRight32(Imm, 2 * RotateAmt); |
| 870 } | 870 } |
| 871 | 871 |
| 872 void OperandARM32FlexImm::dump(const Cfg * /* Func */, Ostream &Str) const { | 872 void OperandARM32FlexImm::dump(const Cfg * /* Func */, Ostream &Str) const { |
| 873 if (!ALLOW_DUMP) | 873 if (!buildAllowsDump()) |
| 874 return; | 874 return; |
| 875 uint32_t Imm = getImm(); | 875 uint32_t Imm = getImm(); |
| 876 uint32_t RotateAmt = getRotateAmt(); | 876 uint32_t RotateAmt = getRotateAmt(); |
| 877 Str << "#(" << Imm << " ror 2*" << RotateAmt << ")"; | 877 Str << "#(" << Imm << " ror 2*" << RotateAmt << ")"; |
| 878 } | 878 } |
| 879 | 879 |
| 880 void OperandARM32FlexReg::emit(const Cfg *Func) const { | 880 void OperandARM32FlexReg::emit(const Cfg *Func) const { |
| 881 if (!ALLOW_DUMP) | 881 if (!buildAllowsDump()) |
| 882 return; | 882 return; |
| 883 Ostream &Str = Func->getContext()->getStrEmit(); | 883 Ostream &Str = Func->getContext()->getStrEmit(); |
| 884 getReg()->emit(Func); | 884 getReg()->emit(Func); |
| 885 if (getShiftOp() != kNoShift) { | 885 if (getShiftOp() != kNoShift) { |
| 886 Str << ", " << InstARM32ShiftAttributes[getShiftOp()].EmitString << " "; | 886 Str << ", " << InstARM32ShiftAttributes[getShiftOp()].EmitString << " "; |
| 887 getShiftAmt()->emit(Func); | 887 getShiftAmt()->emit(Func); |
| 888 } | 888 } |
| 889 } | 889 } |
| 890 | 890 |
| 891 void OperandARM32FlexReg::dump(const Cfg *Func, Ostream &Str) const { | 891 void OperandARM32FlexReg::dump(const Cfg *Func, Ostream &Str) const { |
| 892 if (!ALLOW_DUMP) | 892 if (!buildAllowsDump()) |
| 893 return; | 893 return; |
| 894 Variable *Reg = getReg(); | 894 Variable *Reg = getReg(); |
| 895 if (Func) | 895 if (Func) |
| 896 Reg->dump(Func); | 896 Reg->dump(Func); |
| 897 else | 897 else |
| 898 Reg->dump(Str); | 898 Reg->dump(Str); |
| 899 if (getShiftOp() != kNoShift) { | 899 if (getShiftOp() != kNoShift) { |
| 900 Str << ", " << InstARM32ShiftAttributes[getShiftOp()].EmitString << " "; | 900 Str << ", " << InstARM32ShiftAttributes[getShiftOp()].EmitString << " "; |
| 901 if (Func) | 901 if (Func) |
| 902 getShiftAmt()->dump(Func); | 902 getShiftAmt()->dump(Func); |
| 903 else | 903 else |
| 904 getShiftAmt()->dump(Str); | 904 getShiftAmt()->dump(Str); |
| 905 } | 905 } |
| 906 } | 906 } |
| 907 | 907 |
| 908 } // end of namespace Ice | 908 } // end of namespace Ice |
| OLD | NEW |