Chromium Code Reviews| 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 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 54 CondARM32::Cond Opposite; | 54 CondARM32::Cond Opposite; |
| 55 const char *EmitString; | 55 const char *EmitString; |
| 56 } InstARM32CondAttributes[] = { | 56 } InstARM32CondAttributes[] = { |
| 57 #define X(tag, encode, opp, emit) \ | 57 #define X(tag, encode, opp, emit) \ |
| 58 { CondARM32::opp, emit } \ | 58 { CondARM32::opp, emit } \ |
| 59 , | 59 , |
| 60 ICEINSTARM32COND_TABLE | 60 ICEINSTARM32COND_TABLE |
| 61 #undef X | 61 #undef X |
| 62 }; | 62 }; |
| 63 | 63 |
| 64 // Holds the list of ARM assembler instructions that are safe (i.e. spec2k works | |
| 65 // when these instructions are translated into bytes. | |
| 66 static InstARM32::InstKindARM32 SafeIASMInsts[] = { | |
|
Jim Stichnoth
2015/11/03 00:21:42
I think a blacklist of unsafe instructions would b
Karl
2015/11/03 18:56:11
Done.
| |
| 67 // TODO(kschimpf): Figure out why commented out instructions are not | |
| 68 // (always) | |
| 69 // translated correctly. | |
| 70 InstARM32::Adc, InstARM32::Add, InstARM32::And, | |
| 71 // InstARM32::Br, | |
| 72 InstARM32::Cmp, InstARM32::Eor, InstARM32::Ldr, | |
| 73 // InstARM32::Mov, | |
| 74 // InstARM32::Movw, | |
| 75 // InstARM32::Movt, | |
| 76 InstARM32::Mul, InstARM32::Orr, InstARM32::Sbc, | |
| 77 InstARM32::Sdiv, InstARM32::Str, InstARM32::Sub, | |
| 78 InstARM32::Udiv, InstARM32::Ret, InstARM32::Label}; | |
| 79 | |
| 64 } // end of anonymous namespace | 80 } // end of anonymous namespace |
| 65 | 81 |
| 82 bool InstARM32::isIasSafeImpl(InstKind Kind) const { | |
| 83 for (unsigned i = 0; i < llvm::array_lengthof(SafeIASMInsts); ++i) { | |
|
Jim Stichnoth
2015/11/03 00:21:42
I realize it's only temporary, but this linear sea
Karl
2015/11/03 18:56:11
Actually, reducing the footprint by moving this to
| |
| 84 if (static_cast<InstKind>(SafeIASMInsts[i]) == Kind) | |
| 85 return true; | |
| 86 } | |
| 87 return false; | |
| 88 } | |
| 89 | |
| 66 const char *InstARM32::getWidthString(Type Ty) { | 90 const char *InstARM32::getWidthString(Type Ty) { |
| 67 return TypeARM32Attributes[Ty].WidthString; | 91 return TypeARM32Attributes[Ty].WidthString; |
| 68 } | 92 } |
| 69 | 93 |
| 70 const char *InstARM32::getVecWidthString(Type Ty) { | 94 const char *InstARM32::getVecWidthString(Type Ty) { |
| 71 return TypeARM32Attributes[Ty].VecWidthString; | 95 return TypeARM32Attributes[Ty].VecWidthString; |
| 72 } | 96 } |
| 73 | 97 |
| 74 const char *InstARM32Pred::predString(CondARM32::Cond Pred) { | 98 const char *InstARM32Pred::predString(CondARM32::Cond Pred) { |
| 75 return InstARM32CondAttributes[Pred].EmitString; | 99 return InstARM32CondAttributes[Pred].EmitString; |
| (...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 338 } | 362 } |
| 339 return Found; | 363 return Found; |
| 340 } | 364 } |
| 341 | 365 |
| 342 template <InstARM32::InstKindARM32 K> | 366 template <InstARM32::InstKindARM32 K> |
| 343 void InstARM32ThreeAddrGPR<K>::emitIAS(const Cfg *Func) const { | 367 void InstARM32ThreeAddrGPR<K>::emitIAS(const Cfg *Func) const { |
| 344 emitUsingTextFixup(Func); | 368 emitUsingTextFixup(Func); |
| 345 } | 369 } |
| 346 | 370 |
| 347 template <> void InstARM32Adc::emitIAS(const Cfg *Func) const { | 371 template <> void InstARM32Adc::emitIAS(const Cfg *Func) const { |
| 372 if (!isIasSafe(getKind())) | |
| 373 return emitUsingTextFixup(Func); | |
| 348 ARM32::AssemblerARM32 *Asm = Func->getAssembler<ARM32::AssemblerARM32>(); | 374 ARM32::AssemblerARM32 *Asm = Func->getAssembler<ARM32::AssemblerARM32>(); |
| 349 Asm->adc(getDest(), getSrc(0), getSrc(1), SetFlags, getPredicate()); | 375 Asm->adc(getDest(), getSrc(0), getSrc(1), SetFlags, getPredicate()); |
| 350 if (Asm->needsTextFixup()) | 376 if (Asm->needsTextFixup()) |
| 351 emitUsingTextFixup(Func); | 377 emitUsingTextFixup(Func); |
| 352 } | 378 } |
| 353 | 379 |
| 354 template <> void InstARM32Add::emitIAS(const Cfg *Func) const { | 380 template <> void InstARM32Add::emitIAS(const Cfg *Func) const { |
| 381 if (!isIasSafe(getKind())) | |
| 382 return emitUsingTextFixup(Func); | |
| 355 ARM32::AssemblerARM32 *Asm = Func->getAssembler<ARM32::AssemblerARM32>(); | 383 ARM32::AssemblerARM32 *Asm = Func->getAssembler<ARM32::AssemblerARM32>(); |
| 356 Asm->add(getDest(), getSrc(0), getSrc(1), SetFlags, getPredicate()); | 384 Asm->add(getDest(), getSrc(0), getSrc(1), SetFlags, getPredicate()); |
| 357 if (Asm->needsTextFixup()) | 385 if (Asm->needsTextFixup()) |
| 358 emitUsingTextFixup(Func); | 386 emitUsingTextFixup(Func); |
| 359 } | 387 } |
| 360 | 388 |
| 361 template <> void InstARM32And::emitIAS(const Cfg *Func) const { | 389 template <> void InstARM32And::emitIAS(const Cfg *Func) const { |
| 390 if (!isIasSafe(getKind())) | |
| 391 return emitUsingTextFixup(Func); | |
| 362 ARM32::AssemblerARM32 *Asm = Func->getAssembler<ARM32::AssemblerARM32>(); | 392 ARM32::AssemblerARM32 *Asm = Func->getAssembler<ARM32::AssemblerARM32>(); |
| 363 Asm->and_(getDest(), getSrc(0), getSrc(1), SetFlags, getPredicate()); | 393 Asm->and_(getDest(), getSrc(0), getSrc(1), SetFlags, getPredicate()); |
| 364 if (Asm->needsTextFixup()) | 394 if (Asm->needsTextFixup()) |
| 365 emitUsingTextFixup(Func); | 395 emitUsingTextFixup(Func); |
| 366 } | 396 } |
| 367 | 397 |
| 368 template <> void InstARM32Eor::emitIAS(const Cfg *Func) const { | 398 template <> void InstARM32Eor::emitIAS(const Cfg *Func) const { |
| 399 if (!isIasSafe(getKind())) | |
| 400 return emitUsingTextFixup(Func); | |
| 369 ARM32::AssemblerARM32 *Asm = Func->getAssembler<ARM32::AssemblerARM32>(); | 401 ARM32::AssemblerARM32 *Asm = Func->getAssembler<ARM32::AssemblerARM32>(); |
| 370 Asm->eor(getDest(), getSrc(0), getSrc(1), SetFlags, getPredicate()); | 402 Asm->eor(getDest(), getSrc(0), getSrc(1), SetFlags, getPredicate()); |
| 371 if (Asm->needsTextFixup()) | 403 if (Asm->needsTextFixup()) |
| 372 emitUsingTextFixup(Func); | 404 emitUsingTextFixup(Func); |
| 373 } | 405 } |
| 374 | 406 |
| 375 template <> void InstARM32Orr::emitIAS(const Cfg *Func) const { | 407 template <> void InstARM32Orr::emitIAS(const Cfg *Func) const { |
| 408 if (!isIasSafe(getKind())) | |
| 409 return emitUsingTextFixup(Func); | |
| 376 ARM32::AssemblerARM32 *Asm = Func->getAssembler<ARM32::AssemblerARM32>(); | 410 ARM32::AssemblerARM32 *Asm = Func->getAssembler<ARM32::AssemblerARM32>(); |
| 377 Asm->orr(getDest(), getSrc(0), getSrc(1), SetFlags, getPredicate()); | 411 Asm->orr(getDest(), getSrc(0), getSrc(1), SetFlags, getPredicate()); |
| 378 if (Asm->needsTextFixup()) | 412 if (Asm->needsTextFixup()) |
| 379 emitUsingTextFixup(Func); | 413 emitUsingTextFixup(Func); |
| 380 } | 414 } |
| 381 | 415 |
| 382 template <> void InstARM32Mul::emitIAS(const Cfg *Func) const { | 416 template <> void InstARM32Mul::emitIAS(const Cfg *Func) const { |
| 417 if (!isIasSafe(getKind())) | |
| 418 return emitUsingTextFixup(Func); | |
| 383 ARM32::AssemblerARM32 *Asm = Func->getAssembler<ARM32::AssemblerARM32>(); | 419 ARM32::AssemblerARM32 *Asm = Func->getAssembler<ARM32::AssemblerARM32>(); |
| 384 Asm->mul(getDest(), getSrc(0), getSrc(1), SetFlags, getPredicate()); | 420 Asm->mul(getDest(), getSrc(0), getSrc(1), SetFlags, getPredicate()); |
| 385 if (Asm->needsTextFixup()) | 421 if (Asm->needsTextFixup()) |
| 386 emitUsingTextFixup(Func); | 422 emitUsingTextFixup(Func); |
| 387 } | 423 } |
| 388 | 424 |
| 389 template <> void InstARM32Sbc::emitIAS(const Cfg *Func) const { | 425 template <> void InstARM32Sbc::emitIAS(const Cfg *Func) const { |
| 426 if (!isIasSafe(getKind())) | |
| 427 return emitUsingTextFixup(Func); | |
| 390 ARM32::AssemblerARM32 *Asm = Func->getAssembler<ARM32::AssemblerARM32>(); | 428 ARM32::AssemblerARM32 *Asm = Func->getAssembler<ARM32::AssemblerARM32>(); |
| 391 Asm->sbc(getDest(), getSrc(0), getSrc(1), SetFlags, getPredicate()); | 429 Asm->sbc(getDest(), getSrc(0), getSrc(1), SetFlags, getPredicate()); |
| 392 if (Asm->needsTextFixup()) | 430 if (Asm->needsTextFixup()) |
| 393 emitUsingTextFixup(Func); | 431 emitUsingTextFixup(Func); |
| 394 } | 432 } |
| 395 | 433 |
| 396 template <> void InstARM32Sdiv::emitIAS(const Cfg *Func) const { | 434 template <> void InstARM32Sdiv::emitIAS(const Cfg *Func) const { |
| 435 if (!isIasSafe(getKind())) | |
| 436 return emitUsingTextFixup(Func); | |
| 397 assert(!SetFlags); | 437 assert(!SetFlags); |
| 398 ARM32::AssemblerARM32 *Asm = Func->getAssembler<ARM32::AssemblerARM32>(); | 438 ARM32::AssemblerARM32 *Asm = Func->getAssembler<ARM32::AssemblerARM32>(); |
| 399 Asm->sdiv(getDest(), getSrc(0), getSrc(1), getPredicate()); | 439 Asm->sdiv(getDest(), getSrc(0), getSrc(1), getPredicate()); |
| 400 if (Asm->needsTextFixup()) | 440 if (Asm->needsTextFixup()) |
| 401 emitUsingTextFixup(Func); | 441 emitUsingTextFixup(Func); |
| 402 } | 442 } |
| 403 | 443 |
| 404 template <> void InstARM32Sub::emitIAS(const Cfg *Func) const { | 444 template <> void InstARM32Sub::emitIAS(const Cfg *Func) const { |
| 445 if (!isIasSafe(getKind())) | |
| 446 return emitUsingTextFixup(Func); | |
| 405 ARM32::AssemblerARM32 *Asm = Func->getAssembler<ARM32::AssemblerARM32>(); | 447 ARM32::AssemblerARM32 *Asm = Func->getAssembler<ARM32::AssemblerARM32>(); |
| 406 Asm->sub(getDest(), getSrc(0), getSrc(1), SetFlags, getPredicate()); | 448 Asm->sub(getDest(), getSrc(0), getSrc(1), SetFlags, getPredicate()); |
| 407 if (Asm->needsTextFixup()) | 449 if (Asm->needsTextFixup()) |
| 408 emitUsingTextFixup(Func); | 450 emitUsingTextFixup(Func); |
| 409 } | 451 } |
| 410 | 452 |
| 411 template <> void InstARM32Udiv::emitIAS(const Cfg *Func) const { | 453 template <> void InstARM32Udiv::emitIAS(const Cfg *Func) const { |
| 454 if (!isIasSafe(getKind())) | |
| 455 return emitUsingTextFixup(Func); | |
| 412 assert(!SetFlags); | 456 assert(!SetFlags); |
| 413 ARM32::AssemblerARM32 *Asm = Func->getAssembler<ARM32::AssemblerARM32>(); | 457 ARM32::AssemblerARM32 *Asm = Func->getAssembler<ARM32::AssemblerARM32>(); |
| 414 Asm->udiv(getDest(), getSrc(0), getSrc(1), getPredicate()); | 458 Asm->udiv(getDest(), getSrc(0), getSrc(1), getPredicate()); |
| 415 if (Asm->needsTextFixup()) | 459 if (Asm->needsTextFixup()) |
| 416 emitUsingTextFixup(Func); | 460 emitUsingTextFixup(Func); |
| 417 } | 461 } |
| 418 | 462 |
| 419 InstARM32Call::InstARM32Call(Cfg *Func, Variable *Dest, Operand *CallTarget) | 463 InstARM32Call::InstARM32Call(Cfg *Func, Variable *Dest, Operand *CallTarget) |
| 420 : InstARM32(Func, InstARM32::Call, 1, Dest) { | 464 : InstARM32(Func, InstARM32::Call, 1, Dest) { |
| 421 HasSideEffects = true; | 465 HasSideEffects = true; |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 506 addSource(Src64->getHi()); | 550 addSource(Src64->getHi()); |
| 507 } | 551 } |
| 508 } | 552 } |
| 509 | 553 |
| 510 template <InstARM32::InstKindARM32 K> | 554 template <InstARM32::InstKindARM32 K> |
| 511 void InstARM32CmpLike<K>::emitIAS(const Cfg *Func) const { | 555 void InstARM32CmpLike<K>::emitIAS(const Cfg *Func) const { |
| 512 emitUsingTextFixup(Func); | 556 emitUsingTextFixup(Func); |
| 513 } | 557 } |
| 514 | 558 |
| 515 template <> void InstARM32Cmp::emitIAS(const Cfg *Func) const { | 559 template <> void InstARM32Cmp::emitIAS(const Cfg *Func) const { |
| 560 if (!isIasSafe(getKind())) | |
| 561 return emitUsingTextFixup(Func); | |
| 516 assert(getSrcSize() == 2); | 562 assert(getSrcSize() == 2); |
| 517 ARM32::AssemblerARM32 *Asm = Func->getAssembler<ARM32::AssemblerARM32>(); | 563 ARM32::AssemblerARM32 *Asm = Func->getAssembler<ARM32::AssemblerARM32>(); |
| 518 Asm->cmp(getSrc(0), getSrc(1), getPredicate()); | 564 Asm->cmp(getSrc(0), getSrc(1), getPredicate()); |
| 519 if (Asm->needsTextFixup()) | 565 if (Asm->needsTextFixup()) |
| 520 emitUsingTextFixup(Func); | 566 emitUsingTextFixup(Func); |
| 521 } | 567 } |
| 522 | 568 |
| 523 InstARM32Vcmp::InstARM32Vcmp(Cfg *Func, Variable *Src0, Variable *Src1, | 569 InstARM32Vcmp::InstARM32Vcmp(Cfg *Func, Variable *Src0, Variable *Src1, |
| 524 CondARM32::Cond Predicate) | 570 CondARM32::Cond Predicate) |
| 525 : InstARM32Pred(Func, InstARM32::Vcmp, 2, nullptr, Predicate) { | 571 : InstARM32Pred(Func, InstARM32::Vcmp, 2, nullptr, Predicate) { |
| (...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 743 | 789 |
| 744 if (isMultiSource()) { | 790 if (isMultiSource()) { |
| 745 emitSingleDestMultiSource(Func); | 791 emitSingleDestMultiSource(Func); |
| 746 return; | 792 return; |
| 747 } | 793 } |
| 748 | 794 |
| 749 emitSingleDestSingleSource(Func); | 795 emitSingleDestSingleSource(Func); |
| 750 } | 796 } |
| 751 | 797 |
| 752 void InstARM32Mov::emitIAS(const Cfg *Func) const { | 798 void InstARM32Mov::emitIAS(const Cfg *Func) const { |
| 753 (void)Func; | 799 if (!isIasSafe(getKind())) |
| 800 return emitUsingTextFixup(Func); | |
| 754 assert(!(isMultiDest() && isMultiSource()) && "Invalid vmov type."); | 801 assert(!(isMultiDest() && isMultiSource()) && "Invalid vmov type."); |
| 755 ARM32::AssemblerARM32 *Asm = Func->getAssembler<ARM32::AssemblerARM32>(); | 802 ARM32::AssemblerARM32 *Asm = Func->getAssembler<ARM32::AssemblerARM32>(); |
| 756 if (!(isMultiDest() || isMultiSource())) { | 803 if (!(isMultiDest() || isMultiSource())) { |
| 757 // Must be single source/dest. | 804 // Must be single source/dest. |
| 758 emitIASSingleDestSingleSource(Func); | 805 emitIASSingleDestSingleSource(Func); |
| 759 } | 806 } |
| 760 if (Asm->needsTextFixup()) | 807 if (Asm->needsTextFixup()) |
| 761 emitUsingTextFixup(Func); | 808 emitUsingTextFixup(Func); |
| 762 } | 809 } |
| 763 | 810 |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 796 if (getTargetFalse()) { | 843 if (getTargetFalse()) { |
| 797 Str << "\n\t" | 844 Str << "\n\t" |
| 798 << "b" | 845 << "b" |
| 799 << "\t" << getTargetFalse()->getAsmName(); | 846 << "\t" << getTargetFalse()->getAsmName(); |
| 800 } | 847 } |
| 801 } | 848 } |
| 802 } | 849 } |
| 803 } | 850 } |
| 804 | 851 |
| 805 void InstARM32Br::emitIAS(const Cfg *Func) const { | 852 void InstARM32Br::emitIAS(const Cfg *Func) const { |
| 853 if (!isIasSafe(getKind())) | |
| 854 return emitUsingTextFixup(Func); | |
| 806 ARM32::AssemblerARM32 *Asm = Func->getAssembler<ARM32::AssemblerARM32>(); | 855 ARM32::AssemblerARM32 *Asm = Func->getAssembler<ARM32::AssemblerARM32>(); |
| 807 if (Label) { | 856 if (Label) { |
| 808 Asm->b(Asm->getOrCreateLocalLabel(Label->getNumber()), getPredicate()); | 857 Asm->b(Asm->getOrCreateLocalLabel(Label->getNumber()), getPredicate()); |
| 809 } else if (isUnconditionalBranch()) { | 858 } else if (isUnconditionalBranch()) { |
| 810 Asm->b(Asm->getOrCreateCfgNodeLabel(getTargetFalse()->getIndex()), | 859 Asm->b(Asm->getOrCreateCfgNodeLabel(getTargetFalse()->getIndex()), |
| 811 getPredicate()); | 860 getPredicate()); |
| 812 } else { | 861 } else { |
| 813 Asm->b(Asm->getOrCreateCfgNodeLabel(getTargetTrue()->getIndex()), | 862 Asm->b(Asm->getOrCreateCfgNodeLabel(getTargetTrue()->getIndex()), |
| 814 getPredicate()); | 863 getPredicate()); |
| 815 if (const CfgNode *False = getTargetFalse()) | 864 if (const CfgNode *False = getTargetFalse()) |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 880 } | 929 } |
| 881 | 930 |
| 882 void InstARM32Label::emit(const Cfg *Func) const { | 931 void InstARM32Label::emit(const Cfg *Func) const { |
| 883 if (!BuildDefs::dump()) | 932 if (!BuildDefs::dump()) |
| 884 return; | 933 return; |
| 885 Ostream &Str = Func->getContext()->getStrEmit(); | 934 Ostream &Str = Func->getContext()->getStrEmit(); |
| 886 Str << getName(Func) << ":"; | 935 Str << getName(Func) << ":"; |
| 887 } | 936 } |
| 888 | 937 |
| 889 void InstARM32Label::emitIAS(const Cfg *Func) const { | 938 void InstARM32Label::emitIAS(const Cfg *Func) const { |
| 939 if (!isIasSafe(getKind())) | |
| 940 return emitUsingTextFixup(Func); | |
| 890 ARM32::AssemblerARM32 *Asm = Func->getAssembler<ARM32::AssemblerARM32>(); | 941 ARM32::AssemblerARM32 *Asm = Func->getAssembler<ARM32::AssemblerARM32>(); |
| 891 Asm->bindLocalLabel(Number); | 942 Asm->bindLocalLabel(Func, this, Number); |
| 892 if (Asm->needsTextFixup()) | 943 if (Asm->needsTextFixup()) |
| 893 emitUsingTextFixup(Func); | 944 emitUsingTextFixup(Func); |
| 894 } | 945 } |
| 895 | 946 |
| 896 void InstARM32Label::dump(const Cfg *Func) const { | 947 void InstARM32Label::dump(const Cfg *Func) const { |
| 897 if (!BuildDefs::dump()) | 948 if (!BuildDefs::dump()) |
| 898 return; | 949 return; |
| 899 Ostream &Str = Func->getContext()->getStrDump(); | 950 Ostream &Str = Func->getContext()->getStrDump(); |
| 900 Str << getName(Func) << ":"; | 951 Str << getName(Func) << ":"; |
| 901 } | 952 } |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 920 const char *VectorMarker = DestIsVector ? ".64" : ""; | 971 const char *VectorMarker = DestIsVector ? ".64" : ""; |
| 921 const char *WidthString = DestIsVector ? "" : getWidthString(DestTy); | 972 const char *WidthString = DestIsVector ? "" : getWidthString(DestTy); |
| 922 Str << "\t" << ActualOpcode << WidthString << getPredicate() << VectorMarker | 973 Str << "\t" << ActualOpcode << WidthString << getPredicate() << VectorMarker |
| 923 << "\t"; | 974 << "\t"; |
| 924 getDest()->emit(Func); | 975 getDest()->emit(Func); |
| 925 Str << ", "; | 976 Str << ", "; |
| 926 getSrc(0)->emit(Func); | 977 getSrc(0)->emit(Func); |
| 927 } | 978 } |
| 928 | 979 |
| 929 template <> void InstARM32Ldr::emitIAS(const Cfg *Func) const { | 980 template <> void InstARM32Ldr::emitIAS(const Cfg *Func) const { |
| 981 if (!isIasSafe(getKind())) | |
| 982 return emitUsingTextFixup(Func); | |
| 930 assert(getSrcSize() == 1); | 983 assert(getSrcSize() == 1); |
| 931 Variable *Dest = getDest(); | 984 Variable *Dest = getDest(); |
| 932 Type DestTy = Dest->getType(); | 985 Type DestTy = Dest->getType(); |
| 933 ARM32::AssemblerARM32 *Asm = Func->getAssembler<ARM32::AssemblerARM32>(); | 986 ARM32::AssemblerARM32 *Asm = Func->getAssembler<ARM32::AssemblerARM32>(); |
| 934 if (isVectorType(DestTy) || isScalarFloatingType(DestTy)) | 987 if (isVectorType(DestTy) || isScalarFloatingType(DestTy)) |
| 935 // TODO(kschimpf) Handle case. | 988 // TODO(kschimpf) Handle case. |
| 936 Asm->setNeedsTextFixup(); | 989 Asm->setNeedsTextFixup(); |
| 937 else | 990 else |
| 938 Asm->ldr(Dest, getSrc(0), getPredicate()); | 991 Asm->ldr(Dest, getSrc(0), getPredicate()); |
| 939 if (Asm->needsTextFixup()) | 992 if (Asm->needsTextFixup()) |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 977 Constant *Src0 = llvm::cast<Constant>(getSrc(0)); | 1030 Constant *Src0 = llvm::cast<Constant>(getSrc(0)); |
| 978 if (auto *CR = llvm::dyn_cast<ConstantRelocatable>(Src0)) { | 1031 if (auto *CR = llvm::dyn_cast<ConstantRelocatable>(Src0)) { |
| 979 Str << "#:lower16:"; | 1032 Str << "#:lower16:"; |
| 980 CR->emitWithoutPrefix(Func->getTarget()); | 1033 CR->emitWithoutPrefix(Func->getTarget()); |
| 981 } else { | 1034 } else { |
| 982 Src0->emit(Func); | 1035 Src0->emit(Func); |
| 983 } | 1036 } |
| 984 } | 1037 } |
| 985 | 1038 |
| 986 template <> void InstARM32Movw::emitIAS(const Cfg *Func) const { | 1039 template <> void InstARM32Movw::emitIAS(const Cfg *Func) const { |
| 1040 if (!isIasSafe(getKind())) | |
| 1041 return emitUsingTextFixup(Func); | |
| 987 assert(getSrcSize() == 1); | 1042 assert(getSrcSize() == 1); |
| 988 ARM32::AssemblerARM32 *Asm = Func->getAssembler<ARM32::AssemblerARM32>(); | 1043 ARM32::AssemblerARM32 *Asm = Func->getAssembler<ARM32::AssemblerARM32>(); |
| 989 Asm->movw(getDest(), getSrc(0), getPredicate()); | 1044 Asm->movw(getDest(), getSrc(0), getPredicate()); |
| 990 if (Asm->needsTextFixup()) | 1045 if (Asm->needsTextFixup()) |
| 991 emitUsingTextFixup(Func); | 1046 emitUsingTextFixup(Func); |
| 992 } | 1047 } |
| 993 | 1048 |
| 994 template <> void InstARM32Movt::emit(const Cfg *Func) const { | 1049 template <> void InstARM32Movt::emit(const Cfg *Func) const { |
| 995 if (!BuildDefs::dump()) | 1050 if (!BuildDefs::dump()) |
| 996 return; | 1051 return; |
| 997 Ostream &Str = Func->getContext()->getStrEmit(); | 1052 Ostream &Str = Func->getContext()->getStrEmit(); |
| 998 assert(getSrcSize() == 2); | 1053 assert(getSrcSize() == 2); |
| 999 Variable *Dest = getDest(); | 1054 Variable *Dest = getDest(); |
| 1000 Constant *Src1 = llvm::cast<Constant>(getSrc(1)); | 1055 Constant *Src1 = llvm::cast<Constant>(getSrc(1)); |
| 1001 Str << "\t" << Opcode << getPredicate() << "\t"; | 1056 Str << "\t" << Opcode << getPredicate() << "\t"; |
| 1002 Dest->emit(Func); | 1057 Dest->emit(Func); |
| 1003 Str << ", "; | 1058 Str << ", "; |
| 1004 if (auto *CR = llvm::dyn_cast<ConstantRelocatable>(Src1)) { | 1059 if (auto *CR = llvm::dyn_cast<ConstantRelocatable>(Src1)) { |
| 1005 Str << "#:upper16:"; | 1060 Str << "#:upper16:"; |
| 1006 CR->emitWithoutPrefix(Func->getTarget()); | 1061 CR->emitWithoutPrefix(Func->getTarget()); |
| 1007 } else { | 1062 } else { |
| 1008 Src1->emit(Func); | 1063 Src1->emit(Func); |
| 1009 } | 1064 } |
| 1010 } | 1065 } |
| 1011 | 1066 |
| 1012 template <> void InstARM32Movt::emitIAS(const Cfg *Func) const { | 1067 template <> void InstARM32Movt::emitIAS(const Cfg *Func) const { |
| 1068 if (!isIasSafe(getKind())) | |
| 1069 return emitUsingTextFixup(Func); | |
| 1013 assert(getSrcSize() == 2); | 1070 assert(getSrcSize() == 2); |
| 1014 ARM32::AssemblerARM32 *Asm = Func->getAssembler<ARM32::AssemblerARM32>(); | 1071 ARM32::AssemblerARM32 *Asm = Func->getAssembler<ARM32::AssemblerARM32>(); |
| 1015 Asm->movt(getDest(), getSrc(1), getPredicate()); | 1072 Asm->movt(getDest(), getSrc(1), getPredicate()); |
| 1016 if (Asm->needsTextFixup()) | 1073 if (Asm->needsTextFixup()) |
| 1017 emitUsingTextFixup(Func); | 1074 emitUsingTextFixup(Func); |
| 1018 } | 1075 } |
| 1019 | 1076 |
| 1020 void InstARM32Pop::emit(const Cfg *Func) const { | 1077 void InstARM32Pop::emit(const Cfg *Func) const { |
| 1021 // TODO(jpp): Improve FP register save/restore. | 1078 // TODO(jpp): Improve FP register save/restore. |
| 1022 if (!BuildDefs::dump()) | 1079 if (!BuildDefs::dump()) |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1151 assert(LR->hasReg()); | 1208 assert(LR->hasReg()); |
| 1152 assert(LR->getRegNum() == RegARM32::Reg_lr); | 1209 assert(LR->getRegNum() == RegARM32::Reg_lr); |
| 1153 Ostream &Str = Func->getContext()->getStrEmit(); | 1210 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1154 Str << "\t" | 1211 Str << "\t" |
| 1155 << "bx" | 1212 << "bx" |
| 1156 << "\t"; | 1213 << "\t"; |
| 1157 LR->emit(Func); | 1214 LR->emit(Func); |
| 1158 } | 1215 } |
| 1159 | 1216 |
| 1160 void InstARM32Ret::emitIAS(const Cfg *Func) const { | 1217 void InstARM32Ret::emitIAS(const Cfg *Func) const { |
| 1218 if (!isIasSafe(getKind())) | |
| 1219 return emitUsingTextFixup(Func); | |
| 1161 ARM32::AssemblerARM32 *Asm = Func->getAssembler<ARM32::AssemblerARM32>(); | 1220 ARM32::AssemblerARM32 *Asm = Func->getAssembler<ARM32::AssemblerARM32>(); |
| 1162 Asm->bx(RegARM32::Encoded_Reg_lr); | 1221 Asm->bx(RegARM32::Encoded_Reg_lr); |
| 1163 if (Asm->needsTextFixup()) | 1222 if (Asm->needsTextFixup()) |
| 1164 emitUsingTextFixup(Func); | 1223 emitUsingTextFixup(Func); |
| 1165 } | 1224 } |
| 1166 | 1225 |
| 1167 void InstARM32Ret::dump(const Cfg *Func) const { | 1226 void InstARM32Ret::dump(const Cfg *Func) const { |
| 1168 if (!BuildDefs::dump()) | 1227 if (!BuildDefs::dump()) |
| 1169 return; | 1228 return; |
| 1170 Ostream &Str = Func->getContext()->getStrDump(); | 1229 Ostream &Str = Func->getContext()->getStrDump(); |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 1184 IsVectorStore ? "vst1" : (isScalarFloatingType(Ty) ? "vstr" : "str"); | 1243 IsVectorStore ? "vst1" : (isScalarFloatingType(Ty) ? "vstr" : "str"); |
| 1185 const char *VecEltWidthString = IsVectorStore ? ".64" : ""; | 1244 const char *VecEltWidthString = IsVectorStore ? ".64" : ""; |
| 1186 Str << "\t" << Opcode << getWidthString(Ty) << getPredicate() | 1245 Str << "\t" << Opcode << getWidthString(Ty) << getPredicate() |
| 1187 << VecEltWidthString << "\t"; | 1246 << VecEltWidthString << "\t"; |
| 1188 getSrc(0)->emit(Func); | 1247 getSrc(0)->emit(Func); |
| 1189 Str << ", "; | 1248 Str << ", "; |
| 1190 getSrc(1)->emit(Func); | 1249 getSrc(1)->emit(Func); |
| 1191 } | 1250 } |
| 1192 | 1251 |
| 1193 void InstARM32Str::emitIAS(const Cfg *Func) const { | 1252 void InstARM32Str::emitIAS(const Cfg *Func) const { |
| 1253 if (!isIasSafe(getKind())) | |
| 1254 return emitUsingTextFixup(Func); | |
| 1194 assert(getSrcSize() == 2); | 1255 assert(getSrcSize() == 2); |
| 1195 Type Ty = getSrc(0)->getType(); | 1256 Type Ty = getSrc(0)->getType(); |
| 1196 ARM32::AssemblerARM32 *Asm = Func->getAssembler<ARM32::AssemblerARM32>(); | 1257 ARM32::AssemblerARM32 *Asm = Func->getAssembler<ARM32::AssemblerARM32>(); |
| 1197 if (isVectorType(Ty) || isScalarFloatingType(Ty)) | 1258 if (isVectorType(Ty) || isScalarFloatingType(Ty)) |
| 1198 // TODO(kschimpf) Handle case. | 1259 // TODO(kschimpf) Handle case. |
| 1199 Asm->setNeedsTextFixup(); | 1260 Asm->setNeedsTextFixup(); |
| 1200 else | 1261 else |
| 1201 Asm->str(getSrc(0), getSrc(1), getPredicate()); | 1262 Asm->str(getSrc(0), getSrc(1), getPredicate()); |
| 1202 if (Asm->needsTextFixup()) | 1263 if (Asm->needsTextFixup()) |
| 1203 emitUsingTextFixup(Func); | 1264 emitUsingTextFixup(Func); |
| (...skipping 373 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1577 template class InstARM32UnaryopGPR<InstARM32::Rbit, false>; | 1638 template class InstARM32UnaryopGPR<InstARM32::Rbit, false>; |
| 1578 template class InstARM32UnaryopGPR<InstARM32::Rev, false>; | 1639 template class InstARM32UnaryopGPR<InstARM32::Rev, false>; |
| 1579 template class InstARM32UnaryopGPR<InstARM32::Sxt, true>; | 1640 template class InstARM32UnaryopGPR<InstARM32::Sxt, true>; |
| 1580 template class InstARM32UnaryopGPR<InstARM32::Uxt, true>; | 1641 template class InstARM32UnaryopGPR<InstARM32::Uxt, true>; |
| 1581 template class InstARM32UnaryopFP<InstARM32::Vsqrt>; | 1642 template class InstARM32UnaryopFP<InstARM32::Vsqrt>; |
| 1582 | 1643 |
| 1583 template class InstARM32CmpLike<InstARM32::Cmp>; | 1644 template class InstARM32CmpLike<InstARM32::Cmp>; |
| 1584 template class InstARM32CmpLike<InstARM32::Tst>; | 1645 template class InstARM32CmpLike<InstARM32::Tst>; |
| 1585 | 1646 |
| 1586 } // end of namespace Ice | 1647 } // end of namespace Ice |
| OLD | NEW |