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

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: Clean up code. 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
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)
John 2015/10/09 12:12:24 two argument ctor -- explicit is no longer needed.
Karl 2015/10/09 19:08:18 Leaving as is, since C++ 11 will otherwise try imp
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 enum {
John 2015/10/09 12:12:24 this trick for introducing class-level constants i
Karl 2015/10/09 19:08:18 Done.
104 H = 1 << 5, // halfword (or byte)
105 L = 1 << 20, // load (or store)
106 S = 1 << 20, // set condition code (or leave unchanged)
107 W = 1 << 21, // writeback base register (or leave unchanged)
108 A = 1 << 21, // accumulate in multiply instruction (or not)
109 B = 1 << 22, // unsigned byte (or word)
110 D = 1 << 22, // high/lo bit of start of s/d register range
111 N = 1 << 22, // long (or short)
112 U = 1 << 23, // positive (or negative) offset/index
113 P = 1 << 24, // offset/pre-indexed addressing (or post-indexed addressing)
114 I = 1 << 25, // immediate shifter operand (or not)
115
116 B0 = 1,
117 B1 = 1 << 1,
118 B2 = 1 << 2,
119 B3 = 1 << 3,
120 B4 = 1 << 4,
121 B5 = 1 << 5,
122 B6 = 1 << 6,
123 B7 = 1 << 7,
124 B8 = 1 << 8,
125 B9 = 1 << 9,
126 B10 = 1 << 10,
127 B11 = 1 << 11,
128 B12 = 1 << 12,
129 B16 = 1 << 16,
130 B17 = 1 << 17,
131 B18 = 1 << 18,
132 B19 = 1 << 19,
133 B20 = 1 << 20,
134 B21 = 1 << 21,
135 B22 = 1 << 22,
136 B23 = 1 << 23,
137 B24 = 1 << 24,
138 B25 = 1 << 25,
139 B26 = 1 << 26,
140 B27 = 1 << 27,
141 };
142
143 // Constants used for the decoding or encoding of the individual fields of
144 // instructions. Based on the "Figure 3-1 ARM instruction set summary".
Jim Stichnoth 2015/10/08 23:50:41 Figure 3-1 of what document?
Karl 2015/10/09 19:08:18 I agree that this comment is useless (I copied it
145 enum InstructionFields {
146 kConditionShift = 28,
John 2015/10/09 12:12:24 This is also just introducing class-level constant
Karl 2015/10/09 19:08:18 Done.
147 kConditionBits = 4,
148 kTypeShift = 25,
149 kTypeBits = 3,
150 kLinkShift = 24,
151 kLinkBits = 1,
152 kUShift = 23,
153 kUBits = 1,
154 kOpcodeShift = 21,
155 kOpcodeBits = 4,
156 kSShift = 20,
157 kSBits = 1,
158 kRnShift = 16,
159 kRnBits = 4,
160 kRdShift = 12,
161 kRdBits = 4,
162 kRsShift = 8,
163 kRsBits = 4,
164 kRmShift = 0,
165 kRmBits = 4,
166
167 // Immediate instruction fields encoding.
168 kRotateShift = 8,
169 kRotateBits = 4,
170 kImmed8Shift = 0,
171 kImmed8Bits = 8,
172
173 // Shift instruction register fields encodings.
174 kShiftImmShift = 7,
175 kShiftRegisterShift = 8,
176 kShiftImmBits = 5,
177 kShiftShift = 5,
178 kShiftBits = 2,
179
180 // Load/store instruction offset field encoding.
181 kOffset12Shift = 0,
182 kOffset12Bits = 12,
183 kOffset12Mask = 0x00000fff,
184
185 // Mul instruction register field encodings.
186 kMulRdShift = 16,
187 kMulRdBits = 4,
188 kMulRnShift = 12,
189 kMulRnBits = 4,
190
191 // Div instruction register field encodings.
192 kDivRdShift = 16,
193 kDivRdBits = 4,
194 kDivRmShift = 8,
195 kDivRmBints = 4,
196 kDivRnShift = 0,
197 kDivRnBits = 4,
198
199 // ldrex/strex register field encodings.
200 kLdExRnShift = 16,
201 kLdExRtShift = 12,
202 kStrExRnShift = 16,
203 kStrExRdShift = 12,
204 kStrExRtShift = 0,
205
206 // MRC instruction offset field encoding.
207 kCRmShift = 0,
208 kCRmBits = 4,
209 kOpc2Shift = 5,
210 kOpc2Bits = 3,
211 kCoprocShift = 8,
212 kCoprocBits = 4,
213 kCRnShift = 16,
214 kCRnBits = 4,
215 kOpc1Shift = 21,
216 kOpc1Bits = 3,
217
218 kBranchOffsetMask = 0x00ffffff
219 };
220
221 // A vector of pool-allocated x86 labels for CFG nodes.
222 using LabelVector = std::vector<Label *>;
223 LabelVector CfgNodeLabels;
224
225 Label *getOrCreateLabel(SizeT Number, LabelVector &Labels);
226 Label *getOrCreateCfgNodeLabel(SizeT NodeNumber) {
227 return getOrCreateLabel(NodeNumber, CfgNodeLabels);
228 }
229
230 void emitInt32(int32_t Value) { Buffer.emit<int32_t>(Value); }
231
232 static int32_t BkptEncoding(uint16_t imm16) {
233 // bkpt requires that the cond field is AL.
234 // cccc00010010iiiiiiiiiiii0111iiii where cccc=AL and i in imm16
235 return (CondARM32::AL << kConditionShift) | B24 | B21 |
236 ((imm16 >> 4) << 8) | B6 | B5 | B4 | (imm16 & 0xf);
237 }
82 }; 238 };
83 239
84 } // end of namespace ARM32 240 } // end of namespace ARM32
85 } // end of namespace Ice 241 } // end of namespace Ice
86 242
87 #endif // SUBZERO_SRC_ICEASSEMBLERARM32_H 243 #endif // SUBZERO_SRC_ICEASSEMBLERARM32_H
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698