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 11 matching lines...) Expand all Loading... |
22 | 22 |
23 #include "IceAssemblerARM32.h" | 23 #include "IceAssemblerARM32.h" |
24 #include "IceCfgNode.h" | 24 #include "IceCfgNode.h" |
25 #include "IceUtils.h" | 25 #include "IceUtils.h" |
26 | 26 |
27 namespace { | 27 namespace { |
28 | 28 |
29 using namespace Ice; | 29 using namespace Ice; |
30 using namespace Ice::ARM32; | 30 using namespace Ice::ARM32; |
31 | 31 |
| 32 using WordType = uint32_t; |
| 33 static constexpr IValueT kWordSize = sizeof(WordType); |
| 34 |
32 // The following define individual bits. | 35 // The following define individual bits. |
33 static constexpr IValueT B0 = 1; | 36 static constexpr IValueT B0 = 1; |
34 static constexpr IValueT B1 = 1 << 1; | 37 static constexpr IValueT B1 = 1 << 1; |
35 static constexpr IValueT B2 = 1 << 2; | 38 static constexpr IValueT B2 = 1 << 2; |
36 static constexpr IValueT B3 = 1 << 3; | 39 static constexpr IValueT B3 = 1 << 3; |
37 static constexpr IValueT B4 = 1 << 4; | 40 static constexpr IValueT B4 = 1 << 4; |
38 static constexpr IValueT B5 = 1 << 5; | 41 static constexpr IValueT B5 = 1 << 5; |
39 static constexpr IValueT B6 = 1 << 6; | 42 static constexpr IValueT B6 = 1 << 6; |
40 static constexpr IValueT B7 = 1 << 7; | 43 static constexpr IValueT B7 = 1 << 7; |
41 static constexpr IValueT B12 = 1 << 12; | 44 static constexpr IValueT B12 = 1 << 12; |
42 static constexpr IValueT B13 = 1 << 13; | 45 static constexpr IValueT B13 = 1 << 13; |
43 static constexpr IValueT B14 = 1 << 14; | 46 static constexpr IValueT B14 = 1 << 14; |
44 static constexpr IValueT B15 = 1 << 15; | 47 static constexpr IValueT B15 = 1 << 15; |
45 static constexpr IValueT B20 = 1 << 20; | 48 static constexpr IValueT B20 = 1 << 20; |
46 static constexpr IValueT B21 = 1 << 21; | 49 static constexpr IValueT B21 = 1 << 21; |
47 static constexpr IValueT B22 = 1 << 22; | 50 static constexpr IValueT B22 = 1 << 22; |
48 static constexpr IValueT B24 = 1 << 24; | 51 static constexpr IValueT B24 = 1 << 24; |
49 static constexpr IValueT B25 = 1 << 25; | 52 static constexpr IValueT B25 = 1 << 25; |
50 static constexpr IValueT B26 = 1 << 26; | 53 static constexpr IValueT B26 = 1 << 26; |
| 54 static constexpr IValueT B27 = 1 << 27; |
51 | 55 |
52 // Constants used for the decoding or encoding of the individual fields of | 56 // Constants used for the decoding or encoding of the individual fields of |
53 // instructions. Based on ARM section A5.1. | 57 // instructions. Based on ARM section A5.1. |
54 static constexpr IValueT L = 1 << 20; // load (or store) | 58 static constexpr IValueT L = 1 << 20; // load (or store) |
55 static constexpr IValueT W = 1 << 21; // writeback base register | 59 static constexpr IValueT W = 1 << 21; // writeback base register |
56 // (or leave unchanged) | 60 // (or leave unchanged) |
57 static constexpr IValueT B = 1 << 22; // unsigned byte (or word) | 61 static constexpr IValueT B = 1 << 22; // unsigned byte (or word) |
58 static constexpr IValueT U = 1 << 23; // positive (or negative) | 62 static constexpr IValueT U = 1 << 23; // positive (or negative) |
59 // offset/index | 63 // offset/index |
60 static constexpr IValueT P = 1 << 24; // offset/pre-indexed | 64 static constexpr IValueT P = 1 << 24; // offset/pre-indexed |
(...skipping 467 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
528 !isConditionDefined(Cond)) | 532 !isConditionDefined(Cond)) |
529 return setNeedsTextFixup(); | 533 return setNeedsTextFixup(); |
530 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 534 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
531 IValueT Encoding = Opcode | (encodeCondition(Cond) << kConditionShift) | | 535 IValueT Encoding = Opcode | (encodeCondition(Cond) << kConditionShift) | |
532 (encodeBool(SetCc) << kSShift) | (Rn << kRnShift) | | 536 (encodeBool(SetCc) << kSShift) | (Rn << kRnShift) | |
533 (Rd << kRdShift) | (Rs << kRsShift) | B7 | B4 | | 537 (Rd << kRdShift) | (Rs << kRsShift) | B7 | B4 | |
534 (Rm << kRmShift); | 538 (Rm << kRmShift); |
535 emitInst(Encoding); | 539 emitInst(Encoding); |
536 } | 540 } |
537 | 541 |
| 542 void AssemblerARM32::emitMultiMemOp(CondARM32::Cond Cond, |
| 543 BlockAddressMode AddressMode, bool IsLoad, |
| 544 IValueT BaseReg, IValueT Registers) { |
| 545 constexpr IValueT NumGPRegisters = 16; |
| 546 if (!isConditionDefined(Cond) || !isGPRRegisterDefined(BaseReg) || |
| 547 Registers >= (1 << NumGPRegisters)) |
| 548 return setNeedsTextFixup(); |
| 549 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 550 IValueT Encoding = (encodeCondition(Cond) << kConditionShift) | B27 | |
| 551 AddressMode | (IsLoad ? L : 0) | (BaseReg << kRnShift) | |
| 552 Registers; |
| 553 emitInst(Encoding); |
| 554 } |
| 555 |
538 void AssemblerARM32::adc(const Operand *OpRd, const Operand *OpRn, | 556 void AssemblerARM32::adc(const Operand *OpRd, const Operand *OpRn, |
539 const Operand *OpSrc1, bool SetFlags, | 557 const Operand *OpSrc1, bool SetFlags, |
540 CondARM32::Cond Cond) { | 558 CondARM32::Cond Cond) { |
541 // ADC (register) - ARM section 18.8.2, encoding A1: | 559 // ADC (register) - ARM section 18.8.2, encoding A1: |
542 // adc{s}<c> <Rd>, <Rn>, <Rm>{, <shift>} | 560 // adc{s}<c> <Rd>, <Rn>, <Rm>{, <shift>} |
543 // | 561 // |
544 // cccc0000101snnnnddddiiiiitt0mmmm where cccc=Cond, dddd=Rd, nnnn=Rn, | 562 // cccc0000101snnnnddddiiiiitt0mmmm where cccc=Cond, dddd=Rd, nnnn=Rn, |
545 // mmmm=Rm, iiiii=Shift, tt=ShiftKind, and s=SetFlags. | 563 // mmmm=Rm, iiiii=Shift, tt=ShiftKind, and s=SetFlags. |
546 // | 564 // |
547 // ADC (Immediate) - ARM section A8.8.1, encoding A1: | 565 // ADC (Immediate) - ARM section A8.8.1, encoding A1: |
(...skipping 331 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
879 // | 897 // |
880 // ORR (register) - ARM Section A8.8.123, encoding A1: | 898 // ORR (register) - ARM Section A8.8.123, encoding A1: |
881 // orr{s}<c> <Rd>, <Rn>, #<RotatedImm8> | 899 // orr{s}<c> <Rd>, <Rn>, #<RotatedImm8> |
882 // | 900 // |
883 // cccc0001100snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn, | 901 // cccc0001100snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn, |
884 // s=SetFlags and iiiiiiiiiiii=Src1Value defining RotatedImm8. | 902 // s=SetFlags and iiiiiiiiiiii=Src1Value defining RotatedImm8. |
885 constexpr IValueT Orr = B3 | B2; // i.e. 1100 | 903 constexpr IValueT Orr = B3 | B2; // i.e. 1100 |
886 emitType01(Orr, OpRd, OpRn, OpSrc1, SetFlags, Cond); | 904 emitType01(Orr, OpRd, OpRn, OpSrc1, SetFlags, Cond); |
887 } | 905 } |
888 | 906 |
| 907 void AssemblerARM32::push(const Operand *OpRt, CondARM32::Cond Cond) { |
| 908 // PUSH - ARM section A8.8.133, encoding A2: |
| 909 // push<c> {Rt} |
| 910 // |
| 911 // cccc010100101101dddd000000000100 where dddd=Rd and cccc=Cond. |
| 912 IValueT Rt; |
| 913 if (decodeOperand(OpRt, Rt) != DecodedAsRegister) |
| 914 return setNeedsTextFixup(); |
| 915 assert(Rt != RegARM32::Encoded_Reg_sp); |
| 916 // Same as store instruction. |
| 917 constexpr bool isLoad = false; |
| 918 constexpr bool isByte = false; |
| 919 IValueT Address = decodeImmRegOffset(RegARM32::Encoded_Reg_sp, -kWordSize, |
| 920 OperandARM32Mem::PreIndex); |
| 921 emitMemOp(Cond, kInstTypeMemImmediate, isLoad, isByte, Rt, Address); |
| 922 } |
| 923 |
| 924 void AssemblerARM32::pushList(const IValueT Registers, CondARM32::Cond Cond) { |
| 925 // PUSH - ARM section A8.8.133, encoding A1: |
| 926 // push<c> <Registers> |
| 927 // |
| 928 // cccc100100101101rrrrrrrrrrrrrrrr where cccc=Cond and |
| 929 // rrrrrrrrrrrrrrrr=Registers (one bit for each GP register). |
| 930 constexpr bool IsLoad = false; |
| 931 emitMultiMemOp(Cond, DB_W, IsLoad, RegARM32::Encoded_Reg_sp, Registers); |
| 932 } |
| 933 |
889 void AssemblerARM32::mla(const Operand *OpRd, const Operand *OpRn, | 934 void AssemblerARM32::mla(const Operand *OpRd, const Operand *OpRn, |
890 const Operand *OpRm, const Operand *OpRa, | 935 const Operand *OpRm, const Operand *OpRa, |
891 CondARM32::Cond Cond) { | 936 CondARM32::Cond Cond) { |
892 IValueT Rd; | 937 IValueT Rd; |
893 if (decodeOperand(OpRd, Rd) != DecodedAsRegister) | 938 if (decodeOperand(OpRd, Rd) != DecodedAsRegister) |
894 return setNeedsTextFixup(); | 939 return setNeedsTextFixup(); |
895 IValueT Rn; | 940 IValueT Rn; |
896 if (decodeOperand(OpRn, Rn) != DecodedAsRegister) | 941 if (decodeOperand(OpRn, Rn) != DecodedAsRegister) |
897 return setNeedsTextFixup(); | 942 return setNeedsTextFixup(); |
898 IValueT Rm; | 943 IValueT Rm; |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
998 // tst<c> <Rn>, #<RotatedImm8> | 1043 // tst<c> <Rn>, #<RotatedImm8> |
999 // | 1044 // |
1000 // cccc00110001nnnn0000iiiiiiiiiiii where cccc=Cond, nnnn=Rn, and | 1045 // cccc00110001nnnn0000iiiiiiiiiiii where cccc=Cond, nnnn=Rn, and |
1001 // iiiiiiiiiiii defines RotatedImm8. | 1046 // iiiiiiiiiiii defines RotatedImm8. |
1002 constexpr IValueT Opcode = B3; // ie. 1000 | 1047 constexpr IValueT Opcode = B3; // ie. 1000 |
1003 emitCompareOp(Opcode, OpRn, OpSrc1, Cond); | 1048 emitCompareOp(Opcode, OpRn, OpSrc1, Cond); |
1004 } | 1049 } |
1005 | 1050 |
1006 } // end of namespace ARM32 | 1051 } // end of namespace ARM32 |
1007 } // end of namespace Ice | 1052 } // end of namespace Ice |
OLD | NEW |