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 B24 = 1 << 24; | 42 static constexpr IValueT B24 = 1 << 24; |
42 | 43 |
43 // Constants used for the decoding or encoding of the individual fields of | 44 // Constants used for the decoding or encoding of the individual fields of |
44 // instructions. Based on ARM section A5.1. | 45 // instructions. Based on ARM section A5.1. |
45 static constexpr IValueT L = 1 << 20; // load (or store) | 46 static constexpr IValueT L = 1 << 20; // load (or store) |
46 static constexpr IValueT W = 1 << 21; // writeback base register | 47 static constexpr IValueT W = 1 << 21; // writeback base register |
47 // (or leave unchanged) | 48 // (or leave unchanged) |
48 static constexpr IValueT B = 1 << 22; // unsigned byte (or word) | 49 static constexpr IValueT B = 1 << 22; // unsigned byte (or word) |
49 static constexpr IValueT U = 1 << 23; // positive (or negative) | 50 static constexpr IValueT U = 1 << 23; // positive (or negative) |
50 // offset/index | 51 // offset/index |
51 static constexpr IValueT P = 1 << 24; // offset/pre-indexed | 52 static constexpr IValueT P = 1 << 24; // offset/pre-indexed |
52 // addressing (or | 53 // addressing (or |
53 // post-indexed addressing) | 54 // post-indexed addressing) |
54 | 55 |
55 static constexpr IValueT kConditionShift = 28; | 56 static constexpr IValueT kConditionShift = 28; |
56 static constexpr IValueT kLinkShift = 24; | 57 static constexpr IValueT kLinkShift = 24; |
57 static constexpr IValueT kOpcodeShift = 21; | 58 static constexpr IValueT kOpcodeShift = 21; |
58 static constexpr IValueT kRdShift = 12; | 59 static constexpr IValueT kRdShift = 12; |
59 static constexpr IValueT kRmShift = 0; | 60 static constexpr IValueT kRmShift = 0; |
60 static constexpr IValueT kRnShift = 16; | 61 static constexpr IValueT kRnShift = 16; |
62 static constexpr IValueT kRsShift = 8; | |
61 static constexpr IValueT kSShift = 20; | 63 static constexpr IValueT kSShift = 20; |
62 static constexpr IValueT kTypeShift = 25; | 64 static constexpr IValueT kTypeShift = 25; |
63 | 65 |
64 // Immediate instruction fields encoding. | 66 // Immediate instruction fields encoding. |
65 static constexpr IValueT kImmed8Bits = 8; | 67 static constexpr IValueT kImmed8Bits = 8; |
66 static constexpr IValueT kImmed8Shift = 0; | 68 static constexpr IValueT kImmed8Shift = 0; |
67 static constexpr IValueT kRotateBits = 4; | 69 static constexpr IValueT kRotateBits = 4; |
68 static constexpr IValueT kRotateShift = 8; | 70 static constexpr IValueT kRotateShift = 8; |
69 | 71 |
70 // Shift instruction register fields encodings. | 72 // Shift instruction register fields encodings. |
(...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
341 IValueT Address) { | 343 IValueT Address) { |
342 if (!isGPRRegisterDefined(Rt) || !isConditionDefined(Cond)) | 344 if (!isGPRRegisterDefined(Rt) || !isConditionDefined(Cond)) |
343 return setNeedsTextFixup(); | 345 return setNeedsTextFixup(); |
344 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 346 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
345 const IValueT Encoding = (encodeCondition(Cond) << kConditionShift) | | 347 const IValueT Encoding = (encodeCondition(Cond) << kConditionShift) | |
346 (InstType << kTypeShift) | (IsLoad ? L : 0) | | 348 (InstType << kTypeShift) | (IsLoad ? L : 0) | |
347 (IsByte ? B : 0) | (Rt << kRdShift) | Address; | 349 (IsByte ? B : 0) | (Rt << kRdShift) | Address; |
348 emitInst(Encoding); | 350 emitInst(Encoding); |
349 } | 351 } |
350 | 352 |
353 void AssemblerARM32::emitMulOp(CondARM32::Cond Cond, IValueT Opcode, IValueT Rd, | |
354 IValueT Rn, IValueT Rm, IValueT Rs, bool SetCc) { | |
355 if (!isGPRRegisterDefined(Rd) || !isGPRRegisterDefined(Rn) || | |
356 !isGPRRegisterDefined(Rm) || !isGPRRegisterDefined(Rs) || | |
357 !isConditionDefined(Cond)) | |
358 return setNeedsTextFixup(); | |
359 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | |
360 IValueT Encoding = Opcode | (encodeCondition(Cond) << kConditionShift) | | |
361 (encodeBool(SetCc) << kSShift) | (Rn << kRnShift) | | |
362 (Rd << kRdShift) | (Rs << kRsShift) | B7 | B4 | | |
363 (Rm << kRmShift); | |
364 emitInst(Encoding); | |
365 } | |
366 | |
351 void AssemblerARM32::adc(const Operand *OpRd, const Operand *OpRn, | 367 void AssemblerARM32::adc(const Operand *OpRd, const Operand *OpRn, |
352 const Operand *OpSrc1, bool SetFlags, | 368 const Operand *OpSrc1, bool SetFlags, |
353 CondARM32::Cond Cond) { | 369 CondARM32::Cond Cond) { |
354 IValueT Rd; | 370 IValueT Rd; |
355 if (decodeOperand(OpRd, Rd) != DecodedAsRegister) | 371 if (decodeOperand(OpRd, Rd) != DecodedAsRegister) |
356 return setNeedsTextFixup(); | 372 return setNeedsTextFixup(); |
357 IValueT Rn; | 373 IValueT Rn; |
358 if (decodeOperand(OpRn, Rn) != DecodedAsRegister) | 374 if (decodeOperand(OpRn, Rn) != DecodedAsRegister) |
359 return setNeedsTextFixup(); | 375 return setNeedsTextFixup(); |
360 constexpr IValueT Adc = B2 | B0; // 0101 | 376 constexpr IValueT Adc = B2 | B0; // 0101 |
(...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
602 return setNeedsTextFixup(); | 618 return setNeedsTextFixup(); |
603 if (!isBitSet(P, Address) && isBitSet(W, Address)) | 619 if (!isBitSet(P, Address) && isBitSet(W, Address)) |
604 return setNeedsTextFixup(); | 620 return setNeedsTextFixup(); |
605 if (!IsByte && (getGPRReg(kRnShift, Address) == RegARM32::Encoded_Reg_sp) && | 621 if (!IsByte && (getGPRReg(kRnShift, Address) == RegARM32::Encoded_Reg_sp) && |
606 isBitSet(P, Address) && !isBitSet(U, Address) && isBitSet(W, Address) && | 622 isBitSet(P, Address) && !isBitSet(U, Address) && isBitSet(W, Address) && |
607 (mask(Address, kImm12Shift, kImmed12Bits) == 0x8 /* 000000000100 */)) | 623 (mask(Address, kImm12Shift, kImmed12Bits) == 0x8 /* 000000000100 */)) |
608 return setNeedsTextFixup(); | 624 return setNeedsTextFixup(); |
609 emitMemOp(Cond, kInstTypeMemImmediate, IsLoad, IsByte, Rt, Address); | 625 emitMemOp(Cond, kInstTypeMemImmediate, IsLoad, IsByte, Rt, Address); |
610 } | 626 } |
611 | 627 |
628 void AssemblerARM32::mul(const Operand *OpRd, const Operand *OpRn, | |
629 const Operand *OpSrc1, bool SetFlags, | |
630 CondARM32::Cond Cond) { | |
631 IValueT Rd; | |
632 if (decodeOperand(OpRd, Rd) != DecodedAsRegister) | |
633 return setNeedsTextFixup(); | |
634 IValueT Rn; | |
635 if (decodeOperand(OpRn, Rn) != DecodedAsRegister) | |
636 return setNeedsTextFixup(); | |
637 IValueT Rm; | |
638 if (decodeOperand(OpSrc1, Rm) != DecodedAsRegister) | |
639 return setNeedsTextFixup(); | |
640 // MUL - ARM section A8.8.114, encoding A1. | |
641 // mul{s}<c> <Rd>, <Rn>, <Rm> | |
642 // | |
643 // cccc0000000sdddd0000mmmm1001nnnn where cccc=Cond, dddd=Rd, nnnn=Rn, | |
644 // mmmm=Rm, and s=SetFlags. | |
645 if (Rd == RegARM32::Encoded_Reg_pc || Rn == RegARM32::Encoded_Reg_pc || | |
646 Rm == RegARM32::Encoded_Reg_pc) | |
647 llvm::report_fatal_error("Mul instruction unpredictable on pc"); | |
648 // Assembler registers rd, rn, rm are encoded as rn, rm, rs. | |
649 IValueT MulOpcode = 0; | |
Jim Stichnoth
2015/10/29 22:17:58
constexpr?
Karl
2015/10/30 14:25:56
Done.
| |
650 emitMulOp(Cond, MulOpcode, RegARM32::Encoded_Reg_r0, Rd, Rn, Rm, SetFlags); | |
651 } | |
652 | |
612 void AssemblerARM32::sub(const Operand *OpRd, const Operand *OpRn, | 653 void AssemblerARM32::sub(const Operand *OpRd, const Operand *OpRn, |
613 const Operand *OpSrc1, bool SetFlags, | 654 const Operand *OpSrc1, bool SetFlags, |
614 CondARM32::Cond Cond) { | 655 CondARM32::Cond Cond) { |
615 IValueT Rd; | 656 IValueT Rd; |
616 if (decodeOperand(OpRd, Rd) != DecodedAsRegister) | 657 if (decodeOperand(OpRd, Rd) != DecodedAsRegister) |
617 return setNeedsTextFixup(); | 658 return setNeedsTextFixup(); |
618 IValueT Rn; | 659 IValueT Rn; |
619 if (decodeOperand(OpRn, Rn) != DecodedAsRegister) | 660 if (decodeOperand(OpRn, Rn) != DecodedAsRegister) |
620 return setNeedsTextFixup(); | 661 return setNeedsTextFixup(); |
621 constexpr IValueT Sub = B1; // 0010 | 662 constexpr IValueT Sub = B1; // 0010 |
(...skipping 29 matching lines...) Expand all Loading... | |
651 // Conditions of rule violated. | 692 // Conditions of rule violated. |
652 return setNeedsTextFixup(); | 693 return setNeedsTextFixup(); |
653 emitType01(Cond, kInstTypeDataImmediate, Sub, SetFlags, Rn, Rd, Src1Value); | 694 emitType01(Cond, kInstTypeDataImmediate, Sub, SetFlags, Rn, Rd, Src1Value); |
654 return; | 695 return; |
655 } | 696 } |
656 } | 697 } |
657 } | 698 } |
658 | 699 |
659 } // end of namespace ARM32 | 700 } // end of namespace ARM32 |
660 } // end of namespace Ice | 701 } // end of namespace Ice |
OLD | NEW |