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

Side by Side Diff: src/IceAssemblerARM32.cpp

Issue 1511653002: Fix problems with sandboxing and the ARM integrated assembler. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Lift pass information into linkTo() and nearLinkTo(). Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 //===- subzero/src/IceAssemblerARM32.cpp - Assembler for ARM32 --*- C++ -*-===// 1 //===- subzero/src/IceAssemblerARM32.cpp - Assembler for ARM32 --*- C++ -*-===//
2 // 2 //
3 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 3 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
4 // for details. All rights reserved. Use of this source code is governed by a 4 // for details. All rights reserved. Use of this source code is governed by a
5 // BSD-style license that can be found in the LICENSE file. 5 // BSD-style license that can be found in the LICENSE file.
6 // 6 //
7 // Modified by the Subzero authors. 7 // Modified by the Subzero authors.
8 // 8 //
9 //===----------------------------------------------------------------------===// 9 //===----------------------------------------------------------------------===//
10 // 10 //
(...skipping 442 matching lines...) Expand 10 before | Expand all | Expand 10 after
453 if (!BuildDefs::dump()) 453 if (!BuildDefs::dump())
454 return InstARM32::InstSize; 454 return InstARM32::InstSize;
455 Ostream &Str = Ctx->getStrEmit(); 455 Ostream &Str = Ctx->getStrEmit();
456 IValueT Inst = Asm.load<IValueT>(position()); 456 IValueT Inst = Asm.load<IValueT>(position());
457 Str << "\t" 457 Str << "\t"
458 << "bl\t" << symbol(Ctx) << "\t@ .word " 458 << "bl\t" << symbol(Ctx) << "\t@ .word "
459 << llvm::format_hex_no_prefix(Inst, 8) << "\n"; 459 << llvm::format_hex_no_prefix(Inst, 8) << "\n";
460 return InstARM32::InstSize; 460 return InstARM32::InstSize;
461 } 461 }
462 462
463 void AssemblerARM32::padWithNop(intptr_t Padding) {
464 constexpr intptr_t InstWidth = sizeof(IValueT);
465 assert(Padding % InstWidth == 0 &&
466 "Padding not multiple of instruction size");
467 for (intptr_t i = 0; i < Padding; i += InstWidth)
468 nop();
469 }
470
463 BlRelocatableFixup * 471 BlRelocatableFixup *
464 AssemblerARM32::createBlFixup(const ConstantRelocatable *BlTarget) { 472 AssemblerARM32::createBlFixup(const ConstantRelocatable *BlTarget) {
465 BlRelocatableFixup *F = 473 BlRelocatableFixup *F =
466 new (allocate<BlRelocatableFixup>()) BlRelocatableFixup(); 474 new (allocate<BlRelocatableFixup>()) BlRelocatableFixup();
467 F->set_kind(llvm::ELF::R_ARM_CALL); 475 F->set_kind(llvm::ELF::R_ARM_CALL);
468 F->set_value(BlTarget); 476 F->set_value(BlTarget);
469 Buffer.installFixup(F); 477 Buffer.installFixup(F);
470 return F; 478 return F;
471 } 479 }
472 480
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
644 // TODO(kschimpf): Handle far jumps. 652 // TODO(kschimpf): Handle far jumps.
645 constexpr const char *BranchName = "b"; 653 constexpr const char *BranchName = "b";
646 if (L->isBound()) { 654 if (L->isBound()) {
647 const int32_t Dest = L->getPosition() - Buffer.size(); 655 const int32_t Dest = L->getPosition() - Buffer.size();
648 emitType05(Cond, Dest, Link, BranchName); 656 emitType05(Cond, Dest, Link, BranchName);
649 return; 657 return;
650 } 658 }
651 const IOffsetT Position = Buffer.size(); 659 const IOffsetT Position = Buffer.size();
652 // Use the offset field of the branch instruction for linking the sites. 660 // Use the offset field of the branch instruction for linking the sites.
653 emitType05(Cond, L->getEncodedPosition(), Link, BranchName); 661 emitType05(Cond, L->getEncodedPosition(), Link, BranchName);
654 if (!needsTextFixup()) 662 L->linkTo(*this, Position);
655 L->linkTo(Position);
656 } 663 }
657 664
658 void AssemblerARM32::emitCompareOp(CondARM32::Cond Cond, IValueT Opcode, 665 void AssemblerARM32::emitCompareOp(CondARM32::Cond Cond, IValueT Opcode,
659 const Operand *OpRn, const Operand *OpSrc1, 666 const Operand *OpRn, const Operand *OpSrc1,
660 const char *InstName) { 667 const char *InstName) {
661 // XXX (register) 668 // XXX (register)
662 // XXX<c> <Rn>, <Rm>{, <shift>} 669 // XXX<c> <Rn>, <Rm>{, <shift>}
663 // 670 //
664 // ccccyyyxxxx1nnnn0000iiiiitt0mmmm where cccc=Cond, nnnn=Rn, mmmm=Rm, iiiii 671 // ccccyyyxxxx1nnnn0000iiiiitt0mmmm where cccc=Cond, nnnn=Rn, mmmm=Rm, iiiii
665 // defines shift constant, tt=ShiftKind, yyy=kInstTypeDataRegister, and 672 // defines shift constant, tt=ShiftKind, yyy=kInstTypeDataRegister, and
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
710 717
711 // Check if conditions of rules violated. 718 // Check if conditions of rules violated.
712 verifyRegNotPc(Rn, "Rn", InstName); 719 verifyRegNotPc(Rn, "Rn", InstName);
713 verifyPOrNotW(Address, InstName); 720 verifyPOrNotW(Address, InstName);
714 if (!IsByte && (Rn == RegARM32::Encoded_Reg_sp) && !isBitSet(P, Address) && 721 if (!IsByte && (Rn == RegARM32::Encoded_Reg_sp) && !isBitSet(P, Address) &&
715 isBitSet(U, Address) && !isBitSet(W, Address) && 722 isBitSet(U, Address) && !isBitSet(W, Address) &&
716 (mask(Address, kImm12Shift, kImmed12Bits) == 0x8 /* 000000000100 */)) 723 (mask(Address, kImm12Shift, kImmed12Bits) == 0x8 /* 000000000100 */))
717 llvm::report_fatal_error(std::string(InstName) + 724 llvm::report_fatal_error(std::string(InstName) +
718 ": Use push/pop instead"); 725 ": Use push/pop instead");
719 726
720 return emitMemOp(Cond, kInstTypeMemImmediate, IsLoad, IsByte, Rt, Address, 727 emitMemOp(Cond, kInstTypeMemImmediate, IsLoad, IsByte, Rt, Address,
721 InstName); 728 InstName);
729 return;
722 } 730 }
723 case EncodedAsShiftRotateImm5: { 731 case EncodedAsShiftRotateImm5: {
724 // XXX{B} (register) 732 // XXX{B} (register)
725 // xxx{b}<c> <Rt>, [<Rn>, +/-<Rm>{, <shift>}]{!} 733 // xxx{b}<c> <Rt>, [<Rn>, +/-<Rm>{, <shift>}]{!}
726 // xxx{b}<c> <Rt>, [<Rn>], +/-<Rm>{, <shift>} 734 // xxx{b}<c> <Rt>, [<Rn>], +/-<Rm>{, <shift>}
727 // 735 //
728 // cccc011pubwlnnnnttttiiiiiss0mmmm where cccc=Cond, tttt=Rt, 736 // cccc011pubwlnnnnttttiiiiiss0mmmm where cccc=Cond, tttt=Rt,
729 // b=IsByte, U=1 if +, pu0b is a BlockAddr, l=IsLoad, and 737 // b=IsByte, U=1 if +, pu0b is a BlockAddr, l=IsLoad, and
730 // pu0w0nnnn0000iiiiiss0mmmm=Address. 738 // pu0w0nnnn0000iiiiiss0mmmm=Address.
731 RegARM32::GPRRegister Rn = getGPRReg(kRnShift, Address); 739 RegARM32::GPRRegister Rn = getGPRReg(kRnShift, Address);
732 RegARM32::GPRRegister Rm = getGPRReg(kRmShift, Address); 740 RegARM32::GPRRegister Rm = getGPRReg(kRmShift, Address);
733 741
734 // Check if conditions of rules violated. 742 // Check if conditions of rules violated.
735 verifyPOrNotW(Address, InstName); 743 verifyPOrNotW(Address, InstName);
736 verifyRegNotPc(Rm, "Rm", InstName); 744 verifyRegNotPc(Rm, "Rm", InstName);
737 if (IsByte) 745 if (IsByte)
738 verifyRegNotPc(Rt, "Rt", InstName); 746 verifyRegNotPc(Rt, "Rt", InstName);
739 if (isBitSet(W, Address)) { 747 if (isBitSet(W, Address)) {
740 verifyRegNotPc(Rn, "Rn", InstName); 748 verifyRegNotPc(Rn, "Rn", InstName);
741 verifyRegsNotEq(Rn, "Rn", Rt, "Rt", InstName); 749 verifyRegsNotEq(Rn, "Rn", Rt, "Rt", InstName);
742 } 750 }
743 return emitMemOp(Cond, kInstTypeRegisterShift, IsLoad, IsByte, Rt, Address, 751 emitMemOp(Cond, kInstTypeRegisterShift, IsLoad, IsByte, Rt, Address,
744 InstName); 752 InstName);
753 return;
745 } 754 }
746 } 755 }
747 } 756 }
748 757
749 void AssemblerARM32::emitMemOpEnc3(CondARM32::Cond Cond, IValueT Opcode, 758 void AssemblerARM32::emitMemOpEnc3(CondARM32::Cond Cond, IValueT Opcode,
750 IValueT Rt, const Operand *OpAddress, 759 IValueT Rt, const Operand *OpAddress,
751 const TargetInfo &TInfo, 760 const TargetInfo &TInfo,
752 const char *InstName) { 761 const char *InstName) {
753 IValueT Address; 762 IValueT Address;
754 switch (encodeAddress(OpAddress, Address, TInfo, OpEncoding3)) { 763 switch (encodeAddress(OpAddress, Address, TInfo, OpEncoding3)) {
(...skipping 11 matching lines...) Expand all
766 // and pu0w0nnnn0000iiii0000jjjj=Address. 775 // and pu0w0nnnn0000iiii0000jjjj=Address.
767 verifyRegDefined(Rt, "Rt", InstName); 776 verifyRegDefined(Rt, "Rt", InstName);
768 verifyCondDefined(Cond, InstName); 777 verifyCondDefined(Cond, InstName);
769 verifyPOrNotW(Address, InstName); 778 verifyPOrNotW(Address, InstName);
770 verifyRegNotPc(Rt, "Rt", InstName); 779 verifyRegNotPc(Rt, "Rt", InstName);
771 if (isBitSet(W, Address)) 780 if (isBitSet(W, Address))
772 verifyRegsNotEq(getGPRReg(kRnShift, Address), "Rn", Rt, "Rt", InstName); 781 verifyRegsNotEq(getGPRReg(kRnShift, Address), "Rn", Rt, "Rt", InstName);
773 const IValueT Encoding = (encodeCondition(Cond) << kConditionShift) | 782 const IValueT Encoding = (encodeCondition(Cond) << kConditionShift) |
774 Opcode | (Rt << kRdShift) | Address; 783 Opcode | (Rt << kRdShift) | Address;
775 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 784 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
776 return emitInst(Encoding); 785 emitInst(Encoding);
786 return;
777 } 787 }
778 case EncodedAsShiftRotateImm5: { 788 case EncodedAsShiftRotateImm5: {
779 // XXXH (register) 789 // XXXH (register)
780 // xxxh<c> <Rt>, [<Rn>, +/-<Rm>]{!} 790 // xxxh<c> <Rt>, [<Rn>, +/-<Rm>]{!}
781 // xxxh<c> <Rt>, [<Rn>], +/-<Rm> 791 // xxxh<c> <Rt>, [<Rn>], +/-<Rm>
782 // 792 //
783 // cccc000pu0wxnnnntttt00001011mmmm where cccc=Cond, tttt=Rt, nnnn=Rn, 793 // cccc000pu0wxnnnntttt00001011mmmm where cccc=Cond, tttt=Rt, nnnn=Rn,
784 // mmmm=Rm, pu0w<<21 is a BlockAddr, x000000000000yyyy0000=Opcode, and 794 // mmmm=Rm, pu0w<<21 is a BlockAddr, x000000000000yyyy0000=Opcode, and
785 // pu0w0nnnn000000000000mmmm=Address. 795 // pu0w0nnnn000000000000mmmm=Address.
786 verifyRegDefined(Rt, "Rt", InstName); 796 verifyRegDefined(Rt, "Rt", InstName);
787 verifyCondDefined(Cond, InstName); 797 verifyCondDefined(Cond, InstName);
788 verifyPOrNotW(Address, InstName); 798 verifyPOrNotW(Address, InstName);
789 verifyRegNotPc(Rt, "Rt", InstName); 799 verifyRegNotPc(Rt, "Rt", InstName);
790 verifyAddrRegNotPc(kRmShift, Address, "Rm", InstName); 800 verifyAddrRegNotPc(kRmShift, Address, "Rm", InstName);
791 const RegARM32::GPRRegister Rn = getGPRReg(kRnShift, Address); 801 const RegARM32::GPRRegister Rn = getGPRReg(kRnShift, Address);
792 if (isBitSet(W, Address)) { 802 if (isBitSet(W, Address)) {
793 verifyRegNotPc(Rn, "Rn", InstName); 803 verifyRegNotPc(Rn, "Rn", InstName);
794 verifyRegsNotEq(Rn, "Rn", Rt, "Rt", InstName); 804 verifyRegsNotEq(Rn, "Rn", Rt, "Rt", InstName);
795 } 805 }
796 if (mask(Address, kShiftImmShift, 5) != 0) 806 if (mask(Address, kShiftImmShift, 5) != 0)
797 // For encoding 3, no shift is allowed. 807 // For encoding 3, no shift is allowed.
798 llvm::report_fatal_error(std::string(InstName) + 808 llvm::report_fatal_error(std::string(InstName) +
799 ": Shift constant not allowed"); 809 ": Shift constant not allowed");
800 const IValueT Encoding = (encodeCondition(Cond) << kConditionShift) | 810 const IValueT Encoding = (encodeCondition(Cond) << kConditionShift) |
801 Opcode | (Rt << kRdShift) | Address; 811 Opcode | (Rt << kRdShift) | Address;
802 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 812 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
803 return emitInst(Encoding); 813 emitInst(Encoding);
814 return;
804 } 815 }
805 } 816 }
806 } 817 }
807 818
808 void AssemblerARM32::emitDivOp(CondARM32::Cond Cond, IValueT Opcode, IValueT Rd, 819 void AssemblerARM32::emitDivOp(CondARM32::Cond Cond, IValueT Opcode, IValueT Rd,
809 IValueT Rn, IValueT Rm, const char *InstName) { 820 IValueT Rn, IValueT Rm, const char *InstName) {
810 verifyRegDefined(Rd, "Rd", InstName); 821 verifyRegDefined(Rd, "Rd", InstName);
811 verifyRegDefined(Rn, "Rn", InstName); 822 verifyRegDefined(Rn, "Rn", InstName);
812 verifyRegDefined(Rm, "Rm", InstName); 823 verifyRegDefined(Rm, "Rm", InstName);
813 verifyCondDefined(Cond, InstName); 824 verifyCondDefined(Cond, InstName);
(...skipping 291 matching lines...) Expand 10 before | Expand all | Expand 10 after
1105 // iiiiiiiiiiii=imm12, u=1 if +, pu0w is a BlockAddr, and 1116 // iiiiiiiiiiii=imm12, u=1 if +, pu0w is a BlockAddr, and
1106 // pu0w0nnnn0000iiiiiiiiiiii=Address. 1117 // pu0w0nnnn0000iiiiiiiiiiii=Address.
1107 // 1118 //
1108 // LDRB (register) - ARM section A8.8.66, encoding A1: 1119 // LDRB (register) - ARM section A8.8.66, encoding A1:
1109 // ldrb<c> <Rt>, [<Rn>, +/-<Rm>{, <shift>}]{!} 1120 // ldrb<c> <Rt>, [<Rn>, +/-<Rm>{, <shift>}]{!}
1110 // ldrb<c> <Rt>, [<Rn>], +/-<Rm>{, <shift>} 1121 // ldrb<c> <Rt>, [<Rn>], +/-<Rm>{, <shift>}
1111 // 1122 //
1112 // cccc011pu1w1nnnnttttiiiiiss0mmmm where cccc=Cond, tttt=Rt, U=1 if +, pu0b 1123 // cccc011pu1w1nnnnttttiiiiiss0mmmm where cccc=Cond, tttt=Rt, U=1 if +, pu0b
1113 // is a BlockAddr, and pu0w0nnnn0000iiiiiss0mmmm=Address. 1124 // is a BlockAddr, and pu0w0nnnn0000iiiiiss0mmmm=Address.
1114 constexpr bool IsByte = true; 1125 constexpr bool IsByte = true;
1115 return emitMemOp(Cond, IsLoad, IsByte, Rt, OpAddress, TInfo, LdrName); 1126 emitMemOp(Cond, IsLoad, IsByte, Rt, OpAddress, TInfo, LdrName);
1127 return;
1116 } 1128 }
1117 case 1: { 1129 case 1: {
1118 // Handles i16 loads. 1130 // Handles i16 loads.
1119 // 1131 //
1120 // LDRH (immediate) - ARM section A8.8.80, encoding A1: 1132 // LDRH (immediate) - ARM section A8.8.80, encoding A1:
1121 // ldrh<c> <Rt>, [<Rn>{, #+/-<Imm8>}] 1133 // ldrh<c> <Rt>, [<Rn>{, #+/-<Imm8>}]
1122 // ldrh<c> <Rt>, [<Rn>], #+/-<Imm8> 1134 // ldrh<c> <Rt>, [<Rn>], #+/-<Imm8>
1123 // ldrh<c> <Rt>, [<Rn>, #+/-<Imm8>]! 1135 // ldrh<c> <Rt>, [<Rn>, #+/-<Imm8>]!
1124 // 1136 //
1125 // cccc000pu1w1nnnnttttiiii1011iiii where cccc=Cond, tttt=Rt, nnnn=Rn, 1137 // cccc000pu1w1nnnnttttiiii1011iiii where cccc=Cond, tttt=Rt, nnnn=Rn,
1126 // iiiiiiii=Imm8, u=1 if +, pu0w is a BlockAddr, and 1138 // iiiiiiii=Imm8, u=1 if +, pu0w is a BlockAddr, and
1127 // pu0w0nnnn0000iiiiiiiiiiii=Address. 1139 // pu0w0nnnn0000iiiiiiiiiiii=Address.
1128 constexpr const char *Ldrh = "ldrh"; 1140 constexpr const char *Ldrh = "ldrh";
1129 return emitMemOpEnc3(Cond, L | B7 | B5 | B4, Rt, OpAddress, TInfo, Ldrh); 1141 emitMemOpEnc3(Cond, L | B7 | B5 | B4, Rt, OpAddress, TInfo, Ldrh);
1142 return;
1130 } 1143 }
1131 case 2: { 1144 case 2: {
1132 // Note: Handles i32 and float loads. Target lowering handles i64 and 1145 // Note: Handles i32 and float loads. Target lowering handles i64 and
1133 // double by using two (32 bit) load instructions. 1146 // double by using two (32 bit) load instructions.
1134 // 1147 //
1135 // LDR (immediate) - ARM section A8.8.63, encoding A1: 1148 // LDR (immediate) - ARM section A8.8.63, encoding A1:
1136 // ldr<c> <Rt>, [<Rn>{, #+/-<imm12>}] ; p=1, w=0 1149 // ldr<c> <Rt>, [<Rn>{, #+/-<imm12>}] ; p=1, w=0
1137 // ldr<c> <Rt>, [<Rn>], #+/-<imm12> ; p=1, w=1 1150 // ldr<c> <Rt>, [<Rn>], #+/-<imm12> ; p=1, w=1
1138 // ldr<c> <Rt>, [<Rn>, #+/-<imm12>]! ; p=0, w=1 1151 // ldr<c> <Rt>, [<Rn>, #+/-<imm12>]! ; p=0, w=1
1139 // 1152 //
1140 // cccc010pu0w1nnnnttttiiiiiiiiiiii where cccc=Cond, tttt=Rt, nnnn=Rn, 1153 // cccc010pu0w1nnnnttttiiiiiiiiiiii where cccc=Cond, tttt=Rt, nnnn=Rn,
1141 // iiiiiiiiiiii=imm12, u=1 if +, pu0w is a BlockAddr, and 1154 // iiiiiiiiiiii=imm12, u=1 if +, pu0w is a BlockAddr, and
1142 // 1155 //
1143 // LDR (register) - ARM section A8.8.70, encoding A1: 1156 // LDR (register) - ARM section A8.8.70, encoding A1:
1144 // ldrb<c> <Rt>, [<Rn>, +/-<Rm>{, <shift>}]{!} 1157 // ldrb<c> <Rt>, [<Rn>, +/-<Rm>{, <shift>}]{!}
1145 // ldrb<c> <Rt>, [<Rn>], +-<Rm>{, <shift>} 1158 // ldrb<c> <Rt>, [<Rn>], +-<Rm>{, <shift>}
1146 // 1159 //
1147 // cccc011pu0w1nnnnttttiiiiiss0mmmm where cccc=Cond, tttt=Rt, U=1 if +, pu0b 1160 // cccc011pu0w1nnnnttttiiiiiss0mmmm where cccc=Cond, tttt=Rt, U=1 if +, pu0b
1148 // is a BlockAddr, and pu0w0nnnn0000iiiiiss0mmmm=Address. 1161 // is a BlockAddr, and pu0w0nnnn0000iiiiiss0mmmm=Address.
1149 constexpr bool IsByte = false; 1162 constexpr bool IsByte = false;
1150 return emitMemOp(Cond, IsLoad, IsByte, Rt, OpAddress, TInfo, LdrName); 1163 emitMemOp(Cond, IsLoad, IsByte, Rt, OpAddress, TInfo, LdrName);
1164 return;
1151 } 1165 }
1152 } 1166 }
1153 } 1167 }
1154 1168
1155 void AssemblerARM32::emitShift(const CondARM32::Cond Cond, 1169 void AssemblerARM32::emitShift(const CondARM32::Cond Cond,
1156 const OperandARM32::ShiftKind Shift, 1170 const OperandARM32::ShiftKind Shift,
1157 const Operand *OpRd, const Operand *OpRm, 1171 const Operand *OpRd, const Operand *OpRm,
1158 const Operand *OpSrc1, const bool SetFlags, 1172 const Operand *OpSrc1, const bool SetFlags,
1159 const char *InstName) { 1173 const char *InstName) {
1160 constexpr IValueT ShiftOpcode = B3 | B2 | B0; // 1101 1174 constexpr IValueT ShiftOpcode = B3 | B2 | B0; // 1101
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
1295 // mmmm=Rm, iiii defines shift constant, and tt=ShiftKind. 1309 // mmmm=Rm, iiii defines shift constant, and tt=ShiftKind.
1296 constexpr const char *MvnName = "mvn"; 1310 constexpr const char *MvnName = "mvn";
1297 IValueT Rd = encodeRegister(OpRd, "Rd", MvnName); 1311 IValueT Rd = encodeRegister(OpRd, "Rd", MvnName);
1298 constexpr IValueT MvnOpcode = B3 | B2 | B1 | B0; // i.e. 1111 1312 constexpr IValueT MvnOpcode = B3 | B2 | B1 | B0; // i.e. 1111
1299 constexpr IValueT Rn = 0; 1313 constexpr IValueT Rn = 0;
1300 constexpr bool SetFlags = false; 1314 constexpr bool SetFlags = false;
1301 emitType01(Cond, MvnOpcode, Rd, Rn, OpSrc, SetFlags, RdIsPcAndSetFlags, 1315 emitType01(Cond, MvnOpcode, Rd, Rn, OpSrc, SetFlags, RdIsPcAndSetFlags,
1302 MvnName); 1316 MvnName);
1303 } 1317 }
1304 1318
1319 void AssemblerARM32::nop() {
1320 // NOP - Section A8.8.119, encoding A1:
1321 // nop<c>
1322 //
1323 // cccc0011001000001111000000000000 where cccc=Cond.
1324 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1325 constexpr CondARM32::Cond Cond = CondARM32::AL;
1326 const IValueT Encoding = (encodeCondition(Cond) << kConditionShift) | B25 |
1327 B24 | B21 | B15 | B14 | B13 | B12;
1328 emitInst(Encoding);
1329 }
1330
1305 void AssemblerARM32::sbc(const Operand *OpRd, const Operand *OpRn, 1331 void AssemblerARM32::sbc(const Operand *OpRd, const Operand *OpRn,
1306 const Operand *OpSrc1, bool SetFlags, 1332 const Operand *OpSrc1, bool SetFlags,
1307 CondARM32::Cond Cond) { 1333 CondARM32::Cond Cond) {
1308 // SBC (register) - ARM section 18.8.162, encoding A1: 1334 // SBC (register) - ARM section 18.8.162, encoding A1:
1309 // sbc{s}<c> <Rd>, <Rn>, <Rm>{, <shift>} 1335 // sbc{s}<c> <Rd>, <Rn>, <Rm>{, <shift>}
1310 // 1336 //
1311 // cccc0000110snnnnddddiiiiitt0mmmm where cccc=Cond, dddd=Rd, nnnn=Rn, 1337 // cccc0000110snnnnddddiiiiitt0mmmm where cccc=Cond, dddd=Rd, nnnn=Rn,
1312 // mmmm=Rm, iiiii=Shift, tt=ShiftKind, and s=SetFlags. 1338 // mmmm=Rm, iiiii=Shift, tt=ShiftKind, and s=SetFlags.
1313 // 1339 //
1314 // SBC (Immediate) - ARM section A8.8.161, encoding A1: 1340 // SBC (Immediate) - ARM section A8.8.161, encoding A1:
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
1359 // Handles i1 and i8 stores. 1385 // Handles i1 and i8 stores.
1360 // 1386 //
1361 // STRB (immediate) - ARM section A8.8.207, encoding A1: 1387 // STRB (immediate) - ARM section A8.8.207, encoding A1:
1362 // strb<c> <Rt>, [<Rn>{, #+/-<imm12>}] ; p=1, w=0 1388 // strb<c> <Rt>, [<Rn>{, #+/-<imm12>}] ; p=1, w=0
1363 // strb<c> <Rt>, [<Rn>], #+/-<imm12> ; p=1, w=1 1389 // strb<c> <Rt>, [<Rn>], #+/-<imm12> ; p=1, w=1
1364 // strb<c> <Rt>, [<Rn>, #+/-<imm12>]! ; p=0, w=1 1390 // strb<c> <Rt>, [<Rn>, #+/-<imm12>]! ; p=0, w=1
1365 // 1391 //
1366 // cccc010pu1w0nnnnttttiiiiiiiiiiii where cccc=Cond, tttt=Rt, nnnn=Rn, 1392 // cccc010pu1w0nnnnttttiiiiiiiiiiii where cccc=Cond, tttt=Rt, nnnn=Rn,
1367 // iiiiiiiiiiii=imm12, u=1 if +. 1393 // iiiiiiiiiiii=imm12, u=1 if +.
1368 constexpr bool IsByte = true; 1394 constexpr bool IsByte = true;
1369 return emitMemOp(Cond, IsLoad, IsByte, Rt, OpAddress, TInfo, StrName); 1395 emitMemOp(Cond, IsLoad, IsByte, Rt, OpAddress, TInfo, StrName);
1396 return;
1370 } 1397 }
1371 case 1: { 1398 case 1: {
1372 // Handles i16 stores. 1399 // Handles i16 stores.
1373 // 1400 //
1374 // STRH (immediate) - ARM section A8.*.217, encoding A1: 1401 // STRH (immediate) - ARM section A8.*.217, encoding A1:
1375 // strh<c> <Rt>, [<Rn>{, #+/-<Imm8>}] 1402 // strh<c> <Rt>, [<Rn>{, #+/-<Imm8>}]
1376 // strh<c> <Rt>, [<Rn>], #+/-<Imm8> 1403 // strh<c> <Rt>, [<Rn>], #+/-<Imm8>
1377 // strh<c> <Rt>, [<Rn>, #+/-<Imm8>]! 1404 // strh<c> <Rt>, [<Rn>, #+/-<Imm8>]!
1378 // 1405 //
1379 // cccc000pu1w0nnnnttttiiii1011iiii where cccc=Cond, tttt=Rt, nnnn=Rn, 1406 // cccc000pu1w0nnnnttttiiii1011iiii where cccc=Cond, tttt=Rt, nnnn=Rn,
1380 // iiiiiiii=Imm8, u=1 if +, pu0w is a BlockAddr, and 1407 // iiiiiiii=Imm8, u=1 if +, pu0w is a BlockAddr, and
1381 // pu0w0nnnn0000iiiiiiiiiiii=Address. 1408 // pu0w0nnnn0000iiiiiiiiiiii=Address.
1382 constexpr const char *Strh = "strh"; 1409 constexpr const char *Strh = "strh";
1383 return emitMemOpEnc3(Cond, B7 | B5 | B4, Rt, OpAddress, TInfo, Strh); 1410 emitMemOpEnc3(Cond, B7 | B5 | B4, Rt, OpAddress, TInfo, Strh);
1411 return;
1384 } 1412 }
1385 case 2: { 1413 case 2: {
1386 // Note: Handles i32 and float stores. Target lowering handles i64 and 1414 // Note: Handles i32 and float stores. Target lowering handles i64 and
1387 // double by using two (32 bit) store instructions. 1415 // double by using two (32 bit) store instructions.
1388 // 1416 //
1389 // STR (immediate) - ARM section A8.8.207, encoding A1: 1417 // STR (immediate) - ARM section A8.8.207, encoding A1:
1390 // str<c> <Rt>, [<Rn>{, #+/-<imm12>}] ; p=1, w=0 1418 // str<c> <Rt>, [<Rn>{, #+/-<imm12>}] ; p=1, w=0
1391 // str<c> <Rt>, [<Rn>], #+/-<imm12> ; p=1, w=1 1419 // str<c> <Rt>, [<Rn>], #+/-<imm12> ; p=1, w=1
1392 // str<c> <Rt>, [<Rn>, #+/-<imm12>]! ; p=0, w=1 1420 // str<c> <Rt>, [<Rn>, #+/-<imm12>]! ; p=0, w=1
1393 // 1421 //
1394 // cccc010pu1w0nnnnttttiiiiiiiiiiii where cccc=Cond, tttt=Rt, nnnn=Rn, 1422 // cccc010pu1w0nnnnttttiiiiiiiiiiii where cccc=Cond, tttt=Rt, nnnn=Rn,
1395 // iiiiiiiiiiii=imm12, u=1 if +. 1423 // iiiiiiiiiiii=imm12, u=1 if +.
1396 constexpr bool IsByte = false; 1424 constexpr bool IsByte = false;
1397 return emitMemOp(Cond, IsLoad, IsByte, Rt, OpAddress, TInfo, StrName); 1425 emitMemOp(Cond, IsLoad, IsByte, Rt, OpAddress, TInfo, StrName);
1398 return setNeedsTextFixup(); 1426 return;
1399 } 1427 }
1400 } 1428 }
1401 } 1429 }
1402 1430
1403 void AssemblerARM32::orr(const Operand *OpRd, const Operand *OpRn, 1431 void AssemblerARM32::orr(const Operand *OpRd, const Operand *OpRn,
1404 const Operand *OpSrc1, bool SetFlags, 1432 const Operand *OpSrc1, bool SetFlags,
1405 CondARM32::Cond Cond) { 1433 CondARM32::Cond Cond) {
1406 // ORR (register) - ARM Section A8.8.123, encoding A1: 1434 // ORR (register) - ARM Section A8.8.123, encoding A1:
1407 // orr{s}<c> <Rd>, <Rn>, <Rm> 1435 // orr{s}<c> <Rd>, <Rn>, <Rm>
1408 // 1436 //
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after
1633 1661
1634 void AssemblerARM32::uxt(const Operand *OpRd, const Operand *OpSrc0, 1662 void AssemblerARM32::uxt(const Operand *OpRd, const Operand *OpSrc0,
1635 CondARM32::Cond Cond) { 1663 CondARM32::Cond Cond) {
1636 constexpr const char *UxtName = "uxt"; 1664 constexpr const char *UxtName = "uxt";
1637 constexpr IValueT UxtOpcode = B26 | B25 | B23 | B22 | B21; 1665 constexpr IValueT UxtOpcode = B26 | B25 | B23 | B22 | B21;
1638 emitSignExtend(Cond, UxtOpcode, OpRd, OpSrc0, UxtName); 1666 emitSignExtend(Cond, UxtOpcode, OpRd, OpSrc0, UxtName);
1639 } 1667 }
1640 1668
1641 } // end of namespace ARM32 1669 } // end of namespace ARM32
1642 } // end of namespace Ice 1670 } // end of namespace Ice
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698