Chromium Code Reviews| 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 if (!isConditionDefined(Cond) || !isGPRRegisterDefined(BaseReg) || | |
| 546 Registers >= (1 << 16)) | |
|
Jim Stichnoth
2015/11/06 00:59:09
What is this magic 16? Can you document it in a c
Karl
2015/11/06 17:14:29
Done.
| |
| 547 return setNeedsTextFixup(); | |
| 548 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | |
| 549 IValueT Encoding = (encodeCondition(Cond) << kConditionShift) | B27 | | |
| 550 AddressMode | (IsLoad ? L : 0) | (BaseReg << kRnShift) | | |
| 551 Registers; | |
| 552 emitInst(Encoding); | |
| 553 } | |
| 554 | |
| 538 void AssemblerARM32::adc(const Operand *OpRd, const Operand *OpRn, | 555 void AssemblerARM32::adc(const Operand *OpRd, const Operand *OpRn, |
| 539 const Operand *OpSrc1, bool SetFlags, | 556 const Operand *OpSrc1, bool SetFlags, |
| 540 CondARM32::Cond Cond) { | 557 CondARM32::Cond Cond) { |
| 541 // ADC (register) - ARM section 18.8.2, encoding A1: | 558 // ADC (register) - ARM section 18.8.2, encoding A1: |
| 542 // adc{s}<c> <Rd>, <Rn>, <Rm>{, <shift>} | 559 // adc{s}<c> <Rd>, <Rn>, <Rm>{, <shift>} |
| 543 // | 560 // |
| 544 // cccc0000101snnnnddddiiiiitt0mmmm where cccc=Cond, dddd=Rd, nnnn=Rn, | 561 // cccc0000101snnnnddddiiiiitt0mmmm where cccc=Cond, dddd=Rd, nnnn=Rn, |
| 545 // mmmm=Rm, iiiii=Shift, tt=ShiftKind, and s=SetFlags. | 562 // mmmm=Rm, iiiii=Shift, tt=ShiftKind, and s=SetFlags. |
| 546 // | 563 // |
| 547 // ADC (Immediate) - ARM section A8.8.1, encoding A1: | 564 // ADC (Immediate) - ARM section A8.8.1, encoding A1: |
| (...skipping 331 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 879 // | 896 // |
| 880 // ORR (register) - ARM Section A8.8.123, encoding A1: | 897 // ORR (register) - ARM Section A8.8.123, encoding A1: |
| 881 // orr{s}<c> <Rd>, <Rn>, #<RotatedImm8> | 898 // orr{s}<c> <Rd>, <Rn>, #<RotatedImm8> |
| 882 // | 899 // |
| 883 // cccc0001100snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn, | 900 // cccc0001100snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn, |
| 884 // s=SetFlags and iiiiiiiiiiii=Src1Value defining RotatedImm8. | 901 // s=SetFlags and iiiiiiiiiiii=Src1Value defining RotatedImm8. |
| 885 constexpr IValueT Orr = B3 | B2; // i.e. 1100 | 902 constexpr IValueT Orr = B3 | B2; // i.e. 1100 |
| 886 emitType01(Orr, OpRd, OpRn, OpSrc1, SetFlags, Cond); | 903 emitType01(Orr, OpRd, OpRn, OpSrc1, SetFlags, Cond); |
| 887 } | 904 } |
| 888 | 905 |
| 906 void AssemblerARM32::push(const Operand *OpRt, CondARM32::Cond Cond) { | |
| 907 // PUSH - ARM section A8.8.133, encoding A2: | |
| 908 // push<c> {Rt} | |
| 909 // | |
| 910 // cccc010100101101dddd000000000100 where dddd=Rd and cccc=Cond. | |
| 911 IValueT Rt; | |
| 912 if (decodeOperand(OpRt, Rt) != DecodedAsRegister) | |
| 913 return setNeedsTextFixup(); | |
| 914 assert(Rt != RegARM32::Encoded_Reg_sp); | |
| 915 // Same as store instruction. | |
| 916 constexpr bool isLoad = false; | |
| 917 constexpr bool isByte = false; | |
| 918 IValueT Address = decodeImmRegOffset(RegARM32::Encoded_Reg_sp, -kWordSize, | |
| 919 OperandARM32Mem::PreIndex); | |
| 920 emitMemOp(Cond, kInstTypeMemImmediate, isLoad, isByte, Rt, Address); | |
| 921 } | |
| 922 | |
| 923 void AssemblerARM32::pushList(const IValueT Registers, CondARM32::Cond Cond) { | |
| 924 // PUSH - ARM section A8.8.133, encoding A1: | |
| 925 // push<c> <Registers> | |
| 926 // | |
| 927 // cccc100100101101rrrrrrrrrrrrrrrr where cccc=Cond and | |
| 928 // rrrrrrrrrrrrrrrr=Registers (one bit for each GP register). | |
| 929 constexpr bool IsLoad = false; | |
| 930 emitMultiMemOp(Cond, DB_W, IsLoad, RegARM32::Encoded_Reg_sp, Registers); | |
| 931 } | |
| 932 | |
| 889 void AssemblerARM32::mla(const Operand *OpRd, const Operand *OpRn, | 933 void AssemblerARM32::mla(const Operand *OpRd, const Operand *OpRn, |
| 890 const Operand *OpRm, const Operand *OpRa, | 934 const Operand *OpRm, const Operand *OpRa, |
| 891 CondARM32::Cond Cond) { | 935 CondARM32::Cond Cond) { |
| 892 IValueT Rd; | 936 IValueT Rd; |
| 893 if (decodeOperand(OpRd, Rd) != DecodedAsRegister) | 937 if (decodeOperand(OpRd, Rd) != DecodedAsRegister) |
| 894 return setNeedsTextFixup(); | 938 return setNeedsTextFixup(); |
| 895 IValueT Rn; | 939 IValueT Rn; |
| 896 if (decodeOperand(OpRn, Rn) != DecodedAsRegister) | 940 if (decodeOperand(OpRn, Rn) != DecodedAsRegister) |
| 897 return setNeedsTextFixup(); | 941 return setNeedsTextFixup(); |
| 898 IValueT Rm; | 942 IValueT Rm; |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 998 // tst<c> <Rn>, #<RotatedImm8> | 1042 // tst<c> <Rn>, #<RotatedImm8> |
| 999 // | 1043 // |
| 1000 // cccc00110001nnnn0000iiiiiiiiiiii where cccc=Cond, nnnn=Rn, and | 1044 // cccc00110001nnnn0000iiiiiiiiiiii where cccc=Cond, nnnn=Rn, and |
| 1001 // iiiiiiiiiiii defines RotatedImm8. | 1045 // iiiiiiiiiiii defines RotatedImm8. |
| 1002 constexpr IValueT Opcode = B3; // ie. 1000 | 1046 constexpr IValueT Opcode = B3; // ie. 1000 |
| 1003 emitCompareOp(Opcode, OpRn, OpSrc1, Cond); | 1047 emitCompareOp(Opcode, OpRn, OpSrc1, Cond); |
| 1004 } | 1048 } |
| 1005 | 1049 |
| 1006 } // end of namespace ARM32 | 1050 } // end of namespace ARM32 |
| 1007 } // end of namespace Ice | 1051 } // end of namespace Ice |
| OLD | NEW |