Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(146)

Side by Side Diff: src/IceAssemblerARM32.h

Issue 1397933002: Start incorporating the ARM integrated assembler. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Fix nit and add URL. Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/IceAssembler.cpp ('k') | src/IceAssemblerARM32.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 //===- subzero/src/IceAssemblerARM32.h - Assembler for ARM32 ----*- C++ -*-===// 1 //===- subzero/src/IceAssemblerARM32.h - 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 //
11 // The Subzero Code Generator 11 // The Subzero Code Generator
12 // 12 //
13 // This file is distributed under the University of Illinois Open Source 13 // This file is distributed under the University of Illinois Open Source
14 // License. See LICENSE.TXT for details. 14 // License. See LICENSE.TXT for details.
15 // 15 //
16 //===----------------------------------------------------------------------===// 16 //===----------------------------------------------------------------------===//
17 /// 17 ///
18 /// \file 18 /// \file
19 /// This file implements the Assembler class for ARM32. 19 /// This file implements the Assembler class for ARM32.
20 /// 20 ///
21 //===----------------------------------------------------------------------===// 21 //===----------------------------------------------------------------------===//
22 22
23 #ifndef SUBZERO_SRC_ICEASSEMBLERARM32_H 23 #ifndef SUBZERO_SRC_ICEASSEMBLERARM32_H
24 #define SUBZERO_SRC_ICEASSEMBLERARM32_H 24 #define SUBZERO_SRC_ICEASSEMBLERARM32_H
25 25
26 #include "IceAssembler.h" 26 #include "IceAssembler.h"
27 #include "IceConditionCodesARM32.h"
27 #include "IceDefs.h" 28 #include "IceDefs.h"
28 #include "IceFixups.h" 29 #include "IceFixups.h"
30 #include "IceRegistersARM32.h"
31 #include "IceTargetLowering.h"
29 32
30 namespace Ice { 33 namespace Ice {
31 namespace ARM32 { 34 namespace ARM32 {
32 35
33 class AssemblerARM32 : public Assembler { 36 class AssemblerARM32 : public Assembler {
34 AssemblerARM32(const AssemblerARM32 &) = delete; 37 AssemblerARM32(const AssemblerARM32 &) = delete;
35 AssemblerARM32 &operator=(const AssemblerARM32 &) = delete; 38 AssemblerARM32 &operator=(const AssemblerARM32 &) = delete;
36 39
37 public: 40 public:
38 explicit AssemblerARM32(bool use_far_branches = false) 41 explicit AssemblerARM32(GlobalContext *Ctx, bool use_far_branches = false)
39 : Assembler(Asm_ARM32) { 42 : Assembler(Asm_ARM32, Ctx) {
40 // This mode is only needed and implemented for MIPS and ARM. 43 // TODO(kschimpf): Add mode if needed when branches are handled.
41 assert(!use_far_branches);
42 (void)use_far_branches; 44 (void)use_far_branches;
43 } 45 }
44 ~AssemblerARM32() override = default; 46 ~AssemblerARM32() override = default;
45 47
46 void alignFunction() override { llvm_unreachable("Not yet implemented."); } 48 void alignFunction() override {
49 const SizeT Align = 1 << getBundleAlignLog2Bytes();
50 SizeT BytesNeeded = Utils::OffsetToAlignment(Buffer.getPosition(), Align);
51 constexpr SizeT InstSize = sizeof(int32_t);
52 assert(BytesNeeded % InstSize == 0);
53 while (BytesNeeded > 0) {
54 // TODO(kschimpf) Should this be NOP or some other instruction?
55 bkpt(0);
56 BytesNeeded -= InstSize;
57 }
58 }
47 59
48 SizeT getBundleAlignLog2Bytes() const override { return 4; } 60 SizeT getBundleAlignLog2Bytes() const override { return 4; }
49 61
50 const char *getAlignDirective() const override { return ".p2alignl"; } 62 const char *getAlignDirective() const override { return ".p2alignl"; }
51 63
52 llvm::ArrayRef<uint8_t> getNonExecBundlePadding() const override { 64 llvm::ArrayRef<uint8_t> getNonExecBundlePadding() const override {
53 // Use a particular UDF encoding -- TRAPNaCl in LLVM: 0xE7FEDEF0 65 // Use a particular UDF encoding -- TRAPNaCl in LLVM: 0xE7FEDEF0
54 // http://llvm.org/viewvc/llvm-project?view=revision&revision=173943 66 // http://llvm.org/viewvc/llvm-project?view=revision&revision=173943
55 static const uint8_t Padding[] = {0xE7, 0xFE, 0xDE, 0xF0}; 67 static const uint8_t Padding[] = {0xE7, 0xFE, 0xDE, 0xF0};
56 return llvm::ArrayRef<uint8_t>(Padding, 4); 68 return llvm::ArrayRef<uint8_t>(Padding, 4);
57 } 69 }
58 70
59 void padWithNop(intptr_t Padding) override { 71 void padWithNop(intptr_t Padding) override {
60 (void)Padding; 72 (void)Padding;
61 llvm_unreachable("Not yet implemented."); 73 llvm_unreachable("Not yet implemented.");
62 } 74 }
63 75
64 Ice::Label *getCfgNodeLabel(SizeT NodeNumber) override { 76 Ice::Label *getCfgNodeLabel(SizeT NodeNumber) override {
65 (void)NodeNumber; 77 (void)NodeNumber;
66 llvm_unreachable("Not yet implemented."); 78 llvm_unreachable("Not yet implemented.");
67 } 79 }
68 80
69 void bindCfgNodeLabel(SizeT NodeNumber) override { 81 void bindCfgNodeLabel(SizeT NodeNumber) override {
70 (void)NodeNumber; 82 assert(!getPreliminary());
71 llvm_unreachable("Not yet implemented."); 83 Label *L = getOrCreateCfgNodeLabel(NodeNumber);
84 this->bind(L);
72 } 85 }
73 86
74 bool fixupIsPCRel(FixupKind Kind) const override { 87 bool fixupIsPCRel(FixupKind Kind) const override {
75 (void)Kind; 88 (void)Kind;
76 llvm_unreachable("Not yet implemented."); 89 llvm_unreachable("Not yet implemented.");
77 } 90 }
91 void bind(Label *label);
92
93 void bkpt(uint16_t imm16);
94
95 void bx(RegARM32::GPRRegister rm, CondARM32::Cond cond = CondARM32::AL);
78 96
79 static bool classof(const Assembler *Asm) { 97 static bool classof(const Assembler *Asm) {
80 return Asm->getKind() == Asm_ARM32; 98 return Asm->getKind() == Asm_ARM32;
81 } 99 }
100
101 private:
102 // Instruction encoding bits.
103
104 // halfword (or byte)
105 static constexpr uint32_t H = 1 << 5;
106 // load (or store)
107 static constexpr uint32_t L = 1 << 20;
108 // set condition code (or leave unchanged)
109 static constexpr uint32_t S = 1 << 20;
110 // writeback base register (or leave unchanged)
111 static constexpr uint32_t W = 1 << 21;
112 // accumulate in multiply instruction (or not)
113 static constexpr uint32_t A = 1 << 21;
114 // unsigned byte (or word)
115 static constexpr uint32_t B = 1 << 22;
116 // high/lo bit of start of s/d register range
117 static constexpr uint32_t D = 1 << 22;
118 // long (or short)
119 static constexpr uint32_t N = 1 << 22;
120 // positive (or negative) offset/index
121 static constexpr uint32_t U = 1 << 23;
122 // offset/pre-indexed addressing (or post-indexed addressing)
123 static constexpr uint32_t P = 1 << 24;
124 // immediate shifter operand (or not)
125 static constexpr uint32_t I = 1 << 25;
126
127 // The following define individual bits.
128 static constexpr uint32_t B0 = 1;
129 static constexpr uint32_t B1 = 1 << 1;
130 static constexpr uint32_t B2 = 1 << 2;
131 static constexpr uint32_t B3 = 1 << 3;
132 static constexpr uint32_t B4 = 1 << 4;
133 static constexpr uint32_t B5 = 1 << 5;
134 static constexpr uint32_t B6 = 1 << 6;
135 static constexpr uint32_t B7 = 1 << 7;
136 static constexpr uint32_t B8 = 1 << 8;
137 static constexpr uint32_t B9 = 1 << 9;
138 static constexpr uint32_t B10 = 1 << 10;
139 static constexpr uint32_t B11 = 1 << 11;
140 static constexpr uint32_t B12 = 1 << 12;
141 static constexpr uint32_t B16 = 1 << 16;
142 static constexpr uint32_t B17 = 1 << 17;
143 static constexpr uint32_t B18 = 1 << 18;
144 static constexpr uint32_t B19 = 1 << 19;
145 static constexpr uint32_t B20 = 1 << 20;
146 static constexpr uint32_t B21 = 1 << 21;
147 static constexpr uint32_t B22 = 1 << 22;
148 static constexpr uint32_t B23 = 1 << 23;
149 static constexpr uint32_t B24 = 1 << 24;
150 static constexpr uint32_t B25 = 1 << 25;
151 static constexpr uint32_t B26 = 1 << 26;
152 static constexpr uint32_t B27 = 1 << 27;
153
154 // Constants used for the decoding or encoding of the individual fields of
155 // instructions. Based on section A5.1 from the "ARM Architecture Reference
156 // Manual, ARMv7-A and ARMv7-R edition". See:
157 // http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0406c
158 static constexpr uint32_t kConditionShift = 28;
159 static constexpr uint32_t kConditionBits = 4;
160 static constexpr uint32_t kTypeShift = 25;
161 static constexpr uint32_t kTypeBits = 3;
162 static constexpr uint32_t kLinkShift = 24;
163 static constexpr uint32_t kLinkBits = 1;
164 static constexpr uint32_t kUShift = 23;
165 static constexpr uint32_t kUBits = 1;
166 static constexpr uint32_t kOpcodeShift = 21;
167 static constexpr uint32_t kOpcodeBits = 4;
168 static constexpr uint32_t kSShift = 20;
169 static constexpr uint32_t kSBits = 1;
170 static constexpr uint32_t kRnShift = 16;
171 static constexpr uint32_t kRnBits = 4;
172 static constexpr uint32_t kRdShift = 12;
173 static constexpr uint32_t kRdBits = 4;
174 static constexpr uint32_t kRsShift = 8;
175 static constexpr uint32_t kRsBits = 4;
176 static constexpr uint32_t kRmShift = 0;
177 static constexpr uint32_t kRmBits = 4;
178
179 // Immediate instruction fields encoding.
180 static constexpr uint32_t kRotateShift = 8;
181 static constexpr uint32_t kRotateBits = 4;
182 static constexpr uint32_t kImmed8Shift = 0;
183 static constexpr uint32_t kImmed8Bits = 8;
184
185 // Shift instruction register fields encodings.
186 static constexpr uint32_t kShiftImmShift = 7;
187 static constexpr uint32_t kShiftRegisterShift = 8;
188 static constexpr uint32_t kShiftImmBits = 5;
189 static constexpr uint32_t kShiftShift = 5;
190 static constexpr uint32_t kShiftBits = 2;
191
192 // Load/store instruction offset field encoding.
193 static constexpr uint32_t kOffset12Shift = 0;
194 static constexpr uint32_t kOffset12Bits = 12;
195 static constexpr uint32_t kOffset12Mask = 0x00000fff;
196
197 // Mul instruction register field encodings.
198 static constexpr uint32_t kMulRdShift = 16;
199 static constexpr uint32_t kMulRdBits = 4;
200 static constexpr uint32_t kMulRnShift = 12;
201 static constexpr uint32_t kMulRnBits = 4;
202
203 // Div instruction register field encodings.
204 static constexpr uint32_t kDivRdShift = 16;
205 static constexpr uint32_t kDivRdBits = 4;
206 static constexpr uint32_t kDivRmShift = 8;
207 static constexpr uint32_t kDivRmBints = 4;
208 static constexpr uint32_t kDivRnShift = 0;
209 static constexpr uint32_t kDivRnBits = 4;
210
211 // ldrex/strex register field encodings.
212 static constexpr uint32_t kLdExRnShift = 16;
213 static constexpr uint32_t kLdExRtShift = 12;
214 static constexpr uint32_t kStrExRnShift = 16;
215 static constexpr uint32_t kStrExRdShift = 12;
216 static constexpr uint32_t kStrExRtShift = 0;
217
218 // MRC instruction offset field encoding.
219 static constexpr uint32_t kCRmShift = 0;
220 static constexpr uint32_t kCRmBits = 4;
221 static constexpr uint32_t kOpc2Shift = 5;
222 static constexpr uint32_t kOpc2Bits = 3;
223 static constexpr uint32_t kCoprocShift = 8;
224 static constexpr uint32_t kCoprocBits = 4;
225 static constexpr uint32_t kCRnShift = 16;
226 static constexpr uint32_t kCRnBits = 4;
227 static constexpr uint32_t kOpc1Shift = 21;
228 static constexpr uint32_t kOpc1Bits = 3;
229
230 static constexpr uint32_t kBranchOffsetMask = 0x00ffffff;
231
232 // A vector of pool-allocated x86 labels for CFG nodes.
233 using LabelVector = std::vector<Label *>;
234 LabelVector CfgNodeLabels;
235
236 Label *getOrCreateLabel(SizeT Number, LabelVector &Labels);
237 Label *getOrCreateCfgNodeLabel(SizeT NodeNumber) {
238 return getOrCreateLabel(NodeNumber, CfgNodeLabels);
239 }
240
241 void emitInt32(int32_t Value) { Buffer.emit<int32_t>(Value); }
242
243 static int32_t BkptEncoding(uint16_t imm16) {
244 // bkpt requires that the cond field is AL.
245 // cccc00010010iiiiiiiiiiii0111iiii where cccc=AL and i in imm16
246 return (CondARM32::AL << kConditionShift) | B24 | B21 |
247 ((imm16 >> 4) << 8) | B6 | B5 | B4 | (imm16 & 0xf);
248 }
82 }; 249 };
83 250
84 } // end of namespace ARM32 251 } // end of namespace ARM32
85 } // end of namespace Ice 252 } // end of namespace Ice
86 253
87 #endif // SUBZERO_SRC_ICEASSEMBLERARM32_H 254 #endif // SUBZERO_SRC_ICEASSEMBLERARM32_H
OLDNEW
« no previous file with comments | « src/IceAssembler.cpp ('k') | src/IceAssemblerARM32.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698