| OLD | NEW |
| 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 19 matching lines...) Expand all Loading... |
| 30 using namespace Ice::ARM32; | 30 using namespace Ice::ARM32; |
| 31 | 31 |
| 32 // The following define individual bits. | 32 // The following define individual bits. |
| 33 static constexpr IValueT B0 = 1; | 33 static constexpr IValueT B0 = 1; |
| 34 static constexpr IValueT B1 = 1 << 1; | 34 static constexpr IValueT B1 = 1 << 1; |
| 35 static constexpr IValueT B2 = 1 << 2; | 35 static constexpr IValueT B2 = 1 << 2; |
| 36 static constexpr IValueT B3 = 1 << 3; | 36 static constexpr IValueT B3 = 1 << 3; |
| 37 static constexpr IValueT B4 = 1 << 4; | 37 static constexpr IValueT B4 = 1 << 4; |
| 38 static constexpr IValueT B5 = 1 << 5; | 38 static constexpr IValueT B5 = 1 << 5; |
| 39 static constexpr IValueT B6 = 1 << 6; | 39 static constexpr IValueT B6 = 1 << 6; |
| 40 static constexpr IValueT B7 = 1 << 7; |
| 40 static constexpr IValueT B21 = 1 << 21; | 41 static constexpr IValueT B21 = 1 << 21; |
| 41 static constexpr IValueT B22 = 1 << 22; | 42 static constexpr IValueT B22 = 1 << 22; |
| 42 static constexpr IValueT B24 = 1 << 24; | 43 static constexpr IValueT B24 = 1 << 24; |
| 43 static constexpr IValueT B25 = 1 << 25; | 44 static constexpr IValueT B25 = 1 << 25; |
| 44 | 45 |
| 45 // Constants used for the decoding or encoding of the individual fields of | 46 // Constants used for the decoding or encoding of the individual fields of |
| 46 // instructions. Based on ARM section A5.1. | 47 // instructions. Based on ARM section A5.1. |
| 47 static constexpr IValueT L = 1 << 20; // load (or store) | 48 static constexpr IValueT L = 1 << 20; // load (or store) |
| 48 static constexpr IValueT W = 1 << 21; // writeback base register | 49 static constexpr IValueT W = 1 << 21; // writeback base register |
| 49 // (or leave unchanged) | 50 // (or leave unchanged) |
| 50 static constexpr IValueT B = 1 << 22; // unsigned byte (or word) | 51 static constexpr IValueT B = 1 << 22; // unsigned byte (or word) |
| 51 static constexpr IValueT U = 1 << 23; // positive (or negative) | 52 static constexpr IValueT U = 1 << 23; // positive (or negative) |
| 52 // offset/index | 53 // offset/index |
| 53 static constexpr IValueT P = 1 << 24; // offset/pre-indexed | 54 static constexpr IValueT P = 1 << 24; // offset/pre-indexed |
| 54 // addressing (or | 55 // addressing (or |
| 55 // post-indexed addressing) | 56 // post-indexed addressing) |
| 56 | 57 |
| 57 static constexpr IValueT kConditionShift = 28; | 58 static constexpr IValueT kConditionShift = 28; |
| 58 static constexpr IValueT kLinkShift = 24; | 59 static constexpr IValueT kLinkShift = 24; |
| 59 static constexpr IValueT kOpcodeShift = 21; | 60 static constexpr IValueT kOpcodeShift = 21; |
| 60 static constexpr IValueT kRdShift = 12; | 61 static constexpr IValueT kRdShift = 12; |
| 61 static constexpr IValueT kRmShift = 0; | 62 static constexpr IValueT kRmShift = 0; |
| 62 static constexpr IValueT kRnShift = 16; | 63 static constexpr IValueT kRnShift = 16; |
| 64 static constexpr IValueT kRsShift = 8; |
| 63 static constexpr IValueT kSShift = 20; | 65 static constexpr IValueT kSShift = 20; |
| 64 static constexpr IValueT kTypeShift = 25; | 66 static constexpr IValueT kTypeShift = 25; |
| 65 | 67 |
| 66 // Immediate instruction fields encoding. | 68 // Immediate instruction fields encoding. |
| 67 static constexpr IValueT kImmed8Bits = 8; | 69 static constexpr IValueT kImmed8Bits = 8; |
| 68 static constexpr IValueT kImmed8Shift = 0; | 70 static constexpr IValueT kImmed8Shift = 0; |
| 69 static constexpr IValueT kRotateBits = 4; | 71 static constexpr IValueT kRotateBits = 4; |
| 70 static constexpr IValueT kRotateShift = 8; | 72 static constexpr IValueT kRotateShift = 8; |
| 71 | 73 |
| 72 // Shift instruction register fields encodings. | 74 // Shift instruction register fields encodings. |
| (...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 369 IValueT Address) { | 371 IValueT Address) { |
| 370 if (!isGPRRegisterDefined(Rt) || !isConditionDefined(Cond)) | 372 if (!isGPRRegisterDefined(Rt) || !isConditionDefined(Cond)) |
| 371 return setNeedsTextFixup(); | 373 return setNeedsTextFixup(); |
| 372 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 374 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 373 const IValueT Encoding = (encodeCondition(Cond) << kConditionShift) | | 375 const IValueT Encoding = (encodeCondition(Cond) << kConditionShift) | |
| 374 (InstType << kTypeShift) | (IsLoad ? L : 0) | | 376 (InstType << kTypeShift) | (IsLoad ? L : 0) | |
| 375 (IsByte ? B : 0) | (Rt << kRdShift) | Address; | 377 (IsByte ? B : 0) | (Rt << kRdShift) | Address; |
| 376 emitInst(Encoding); | 378 emitInst(Encoding); |
| 377 } | 379 } |
| 378 | 380 |
| 381 void AssemblerARM32::emitMulOp(CondARM32::Cond Cond, IValueT Opcode, IValueT Rd, |
| 382 IValueT Rn, IValueT Rm, IValueT Rs, bool SetCc) { |
| 383 if (!isGPRRegisterDefined(Rd) || !isGPRRegisterDefined(Rn) || |
| 384 !isGPRRegisterDefined(Rm) || !isGPRRegisterDefined(Rs) || |
| 385 !isConditionDefined(Cond)) |
| 386 return setNeedsTextFixup(); |
| 387 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 388 IValueT Encoding = Opcode | (encodeCondition(Cond) << kConditionShift) | |
| 389 (encodeBool(SetCc) << kSShift) | (Rn << kRnShift) | |
| 390 (Rd << kRdShift) | (Rs << kRsShift) | B7 | B4 | |
| 391 (Rm << kRmShift); |
| 392 emitInst(Encoding); |
| 393 } |
| 394 |
| 379 void AssemblerARM32::adc(const Operand *OpRd, const Operand *OpRn, | 395 void AssemblerARM32::adc(const Operand *OpRd, const Operand *OpRn, |
| 380 const Operand *OpSrc1, bool SetFlags, | 396 const Operand *OpSrc1, bool SetFlags, |
| 381 CondARM32::Cond Cond) { | 397 CondARM32::Cond Cond) { |
| 382 IValueT Rd; | 398 IValueT Rd; |
| 383 if (decodeOperand(OpRd, Rd) != DecodedAsRegister) | 399 if (decodeOperand(OpRd, Rd) != DecodedAsRegister) |
| 384 return setNeedsTextFixup(); | 400 return setNeedsTextFixup(); |
| 385 IValueT Rn; | 401 IValueT Rn; |
| 386 if (decodeOperand(OpRn, Rn) != DecodedAsRegister) | 402 if (decodeOperand(OpRn, Rn) != DecodedAsRegister) |
| 387 return setNeedsTextFixup(); | 403 return setNeedsTextFixup(); |
| 388 constexpr IValueT Adc = B2 | B0; // 0101 | 404 constexpr IValueT Adc = B2 | B0; // 0101 |
| (...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 729 return setNeedsTextFixup(); | 745 return setNeedsTextFixup(); |
| 730 if (!isBitSet(P, Address) && isBitSet(W, Address)) | 746 if (!isBitSet(P, Address) && isBitSet(W, Address)) |
| 731 return setNeedsTextFixup(); | 747 return setNeedsTextFixup(); |
| 732 if (!IsByte && (getGPRReg(kRnShift, Address) == RegARM32::Encoded_Reg_sp) && | 748 if (!IsByte && (getGPRReg(kRnShift, Address) == RegARM32::Encoded_Reg_sp) && |
| 733 isBitSet(P, Address) && !isBitSet(U, Address) && isBitSet(W, Address) && | 749 isBitSet(P, Address) && !isBitSet(U, Address) && isBitSet(W, Address) && |
| 734 (mask(Address, kImm12Shift, kImmed12Bits) == 0x8 /* 000000000100 */)) | 750 (mask(Address, kImm12Shift, kImmed12Bits) == 0x8 /* 000000000100 */)) |
| 735 return setNeedsTextFixup(); | 751 return setNeedsTextFixup(); |
| 736 emitMemOp(Cond, kInstTypeMemImmediate, IsLoad, IsByte, Rt, Address); | 752 emitMemOp(Cond, kInstTypeMemImmediate, IsLoad, IsByte, Rt, Address); |
| 737 } | 753 } |
| 738 | 754 |
| 755 void AssemblerARM32::mul(const Operand *OpRd, const Operand *OpRn, |
| 756 const Operand *OpSrc1, bool SetFlags, |
| 757 CondARM32::Cond Cond) { |
| 758 IValueT Rd; |
| 759 if (decodeOperand(OpRd, Rd) != DecodedAsRegister) |
| 760 return setNeedsTextFixup(); |
| 761 IValueT Rn; |
| 762 if (decodeOperand(OpRn, Rn) != DecodedAsRegister) |
| 763 return setNeedsTextFixup(); |
| 764 IValueT Rm; |
| 765 if (decodeOperand(OpSrc1, Rm) != DecodedAsRegister) |
| 766 return setNeedsTextFixup(); |
| 767 // MUL - ARM section A8.8.114, encoding A1. |
| 768 // mul{s}<c> <Rd>, <Rn>, <Rm> |
| 769 // |
| 770 // cccc0000000sdddd0000mmmm1001nnnn where cccc=Cond, dddd=Rd, nnnn=Rn, |
| 771 // mmmm=Rm, and s=SetFlags. |
| 772 if (Rd == RegARM32::Encoded_Reg_pc || Rn == RegARM32::Encoded_Reg_pc || |
| 773 Rm == RegARM32::Encoded_Reg_pc) |
| 774 llvm::report_fatal_error("Mul instruction unpredictable on pc"); |
| 775 // Assembler registers rd, rn, rm are encoded as rn, rm, rs. |
| 776 constexpr IValueT MulOpcode = 0; |
| 777 emitMulOp(Cond, MulOpcode, RegARM32::Encoded_Reg_r0, Rd, Rn, Rm, SetFlags); |
| 778 } |
| 779 |
| 739 void AssemblerARM32::sub(const Operand *OpRd, const Operand *OpRn, | 780 void AssemblerARM32::sub(const Operand *OpRd, const Operand *OpRn, |
| 740 const Operand *OpSrc1, bool SetFlags, | 781 const Operand *OpSrc1, bool SetFlags, |
| 741 CondARM32::Cond Cond) { | 782 CondARM32::Cond Cond) { |
| 742 IValueT Rd; | 783 IValueT Rd; |
| 743 if (decodeOperand(OpRd, Rd) != DecodedAsRegister) | 784 if (decodeOperand(OpRd, Rd) != DecodedAsRegister) |
| 744 return setNeedsTextFixup(); | 785 return setNeedsTextFixup(); |
| 745 IValueT Rn; | 786 IValueT Rn; |
| 746 if (decodeOperand(OpRn, Rn) != DecodedAsRegister) | 787 if (decodeOperand(OpRn, Rn) != DecodedAsRegister) |
| 747 return setNeedsTextFixup(); | 788 return setNeedsTextFixup(); |
| 748 constexpr IValueT Sub = B1; // 0010 | 789 constexpr IValueT Sub = B1; // 0010 |
| (...skipping 29 matching lines...) Expand all Loading... |
| 778 // Conditions of rule violated. | 819 // Conditions of rule violated. |
| 779 return setNeedsTextFixup(); | 820 return setNeedsTextFixup(); |
| 780 emitType01(Cond, kInstTypeDataImmediate, Sub, SetFlags, Rn, Rd, Src1Value); | 821 emitType01(Cond, kInstTypeDataImmediate, Sub, SetFlags, Rn, Rd, Src1Value); |
| 781 return; | 822 return; |
| 782 } | 823 } |
| 783 } | 824 } |
| 784 } | 825 } |
| 785 | 826 |
| 786 } // end of namespace ARM32 | 827 } // end of namespace ARM32 |
| 787 } // end of namespace Ice | 828 } // end of namespace Ice |
| OLD | NEW |