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 |