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

Side by Side Diff: src/IceAssemblerARM32.cpp

Issue 1402403002: Handle stack spills in ARM integrated assembler. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Fix nits. 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/IceAssemblerARM32.h ('k') | src/IceInstARM32.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.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 //
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 #include "IceAssemblerARM32.h" 23 #include "IceAssemblerARM32.h"
24 #include "IceUtils.h"
24 25
25 namespace { 26 namespace {
26 27
27 using namespace Ice; 28 using namespace Ice;
28 29
29 // The following define individual bits. 30 // The following define individual bits.
30 static constexpr uint32_t B0 = 1; 31 static constexpr uint32_t B0 = 1;
31 static constexpr uint32_t B1 = 1 << 1; 32 static constexpr uint32_t B1 = 1 << 1;
32 static constexpr uint32_t B2 = 1 << 2; 33 static constexpr uint32_t B2 = 1 << 2;
33 static constexpr uint32_t B3 = 1 << 3; 34 static constexpr uint32_t B3 = 1 << 3;
34 static constexpr uint32_t B4 = 1 << 4; 35 static constexpr uint32_t B4 = 1 << 4;
35 static constexpr uint32_t B5 = 1 << 5; 36 static constexpr uint32_t B5 = 1 << 5;
36 static constexpr uint32_t B6 = 1 << 6; 37 static constexpr uint32_t B6 = 1 << 6;
37 static constexpr uint32_t B21 = 1 << 21; 38 static constexpr uint32_t B21 = 1 << 21;
38 static constexpr uint32_t B24 = 1 << 24; 39 static constexpr uint32_t B24 = 1 << 24;
39 40
40 // Constants used for the decoding or encoding of the individual fields of 41 // Constants used for the decoding or encoding of the individual fields of
41 // instructions. Based on ARM section A5.1. 42 // instructions. Based on ARM section A5.1.
43 static constexpr uint32_t L = 1 << 20; // load (or store)
44 static constexpr uint32_t W = 1 << 21; // writeback base register (or leave
45 // unchanged)
46 static constexpr uint32_t B = 1 << 22; // unsigned byte (or word)
47 static constexpr uint32_t U = 1 << 23; // positive (or negative) offset/index
48 static constexpr uint32_t P = 1 << 24; // offset/pre-indexed addressing (or
49 // post-indexed addressing)
50
42 static constexpr uint32_t kConditionShift = 28; 51 static constexpr uint32_t kConditionShift = 28;
43 static constexpr uint32_t kOpcodeShift = 21; 52 static constexpr uint32_t kOpcodeShift = 21;
44 static constexpr uint32_t kRdShift = 12; 53 static constexpr uint32_t kRdShift = 12;
45 static constexpr uint32_t kRmShift = 0; 54 static constexpr uint32_t kRmShift = 0;
46 static constexpr uint32_t kRnShift = 16; 55 static constexpr uint32_t kRnShift = 16;
47 static constexpr uint32_t kSShift = 20; 56 static constexpr uint32_t kSShift = 20;
48 static constexpr uint32_t kTypeShift = 25; 57 static constexpr uint32_t kTypeShift = 25;
49 58
50 // Immediate instruction fields encoding. 59 // Immediate instruction fields encoding.
51 static constexpr uint32_t kImmed8Bits = 8; 60 static constexpr uint32_t kImmed8Bits = 8;
52 static constexpr uint32_t kImmed8Shift = 0; 61 static constexpr uint32_t kImmed8Shift = 0;
53 static constexpr uint32_t kRotateBits = 4; 62 static constexpr uint32_t kRotateBits = 4;
54 static constexpr uint32_t kRotateShift = 8; 63 static constexpr uint32_t kRotateShift = 8;
55 64
65 static constexpr uint32_t kImmed12Bits = 12;
66 static constexpr uint32_t kImm12Shift = 0;
67
56 inline uint32_t encodeBool(bool b) { return b ? 1 : 0; } 68 inline uint32_t encodeBool(bool b) { return b ? 1 : 0; }
57 69
58 inline uint32_t encodeGPRRegister(RegARM32::GPRRegister Rn) { 70 inline uint32_t encodeGPRRegister(RegARM32::GPRRegister Rn) {
59 return static_cast<uint32_t>(Rn); 71 return static_cast<uint32_t>(Rn);
60 } 72 }
61 73
62 inline bool isGPRRegisterDefined(RegARM32::GPRRegister R) { 74 inline bool isGPRRegisterDefined(RegARM32::GPRRegister R) {
63 return R != RegARM32::Encoded_Not_GPR; 75 return R != RegARM32::Encoded_Not_GPR;
64 } 76 }
65 77
66 inline bool isGPRRegisterDefined(uint32_t R) { 78 inline bool isGPRRegisterDefined(uint32_t R) {
67 return R != encodeGPRRegister(RegARM32::Encoded_Not_GPR); 79 return R != encodeGPRRegister(RegARM32::Encoded_Not_GPR);
68 } 80 }
69 81
70 inline bool isConditionDefined(CondARM32::Cond Cond) { 82 inline bool isConditionDefined(CondARM32::Cond Cond) {
71 return Cond != CondARM32::kNone; 83 return Cond != CondARM32::kNone;
72 } 84 }
73 85
74 inline uint32_t encodeCondition(CondARM32::Cond Cond) { 86 inline uint32_t encodeCondition(CondARM32::Cond Cond) {
75 return static_cast<uint32_t>(Cond); 87 return static_cast<uint32_t>(Cond);
76 } 88 }
77 89
78 // The way an operand was decoded in function decode below. 90 // Returns the bits in the corresponding masked value.
91 inline uint32_t mask(uint32_t Value, uint32_t Shift, uint32_t Bits) {
92 return (Value >> Shift) & ((1 << Bits) - 1);
93 }
94
95 // Extract out a Bit in Value.
96 inline bool isBitSet(uint32_t Bit, uint32_t Value) {
97 return (Value & Bit) == Bit;
98 }
99
100 // Returns the GPR register at given Shift in Value.
101 inline RegARM32::GPRRegister getGPRReg(uint32_t Shift, uint32_t Value) {
102 return static_cast<RegARM32::GPRRegister>((Value >> Shift) & 0xF);
103 }
104
105 // The way an operand was decoded in functions decodeOperand and decodeAddress
106 // below.
79 enum DecodedResult { 107 enum DecodedResult {
80 CantDecode = 0, // I.e. will fail in test. 108 // Unable to decode, value left undefined.
109 CantDecode = 0,
110 // Value is register found.
81 DecodedAsRegister, 111 DecodedAsRegister,
82 DecodedAsRotatedImm8 112 // Value=rrrriiiiiiii where rrrr is the rotation, and iiiiiiii is the imm8
113 // value.
114 DecodedAsRotatedImm8,
115 // i.e. 0000000pu0w0nnnn0000iiiiiiiiiiii where nnnn is the base register Rn,
116 // p=1 if pre-indexed addressing, u=1 if offset positive, w=1 if writeback to
117 // Rn should be used, and iiiiiiiiiiii is the offset.
118 DecodedAsImmRegOffset
83 }; 119 };
84 120
85 DecodedResult decode(const Operand *Opnd, uint32_t &Value) { 121 DecodedResult decodeOperand(const Operand *Opnd, uint32_t &Value) {
86 if (const auto *Var = llvm::dyn_cast<Variable>(Opnd)) { 122 if (const auto *Var = llvm::dyn_cast<Variable>(Opnd)) {
87 if (Var->hasReg()) { 123 if (Var->hasReg()) {
88 Value = Var->getRegNum(); 124 Value = Var->getRegNum();
89 return DecodedAsRegister; 125 return DecodedAsRegister;
90 } 126 }
91 } else if (const auto *FlexImm = llvm::dyn_cast<OperandARM32FlexImm>(Opnd)) { 127 } else if (const auto *FlexImm = llvm::dyn_cast<OperandARM32FlexImm>(Opnd)) {
92 uint32_t Immed8 = FlexImm->getImm(); 128 const uint32_t Immed8 = FlexImm->getImm();
93 uint32_t Rotate = FlexImm->getRotateAmt(); 129 const uint32_t Rotate = FlexImm->getRotateAmt();
94 assert((Rotate < (1 << kRotateBits)) && (Immed8 < (1 << kImmed8Bits))); 130 assert((Rotate < (1 << kRotateBits)) && (Immed8 < (1 << kImmed8Bits)));
95 Value = (Rotate << kRotateShift) | (Immed8 << kImmed8Shift); 131 Value = (Rotate << kRotateShift) | (Immed8 << kImmed8Shift);
96 return DecodedAsRotatedImm8; 132 return DecodedAsRotatedImm8;
97 } 133 }
98 return CantDecode; 134 return CantDecode;
99 } 135 }
100 136
137 uint32_t decodeImmRegOffset(RegARM32::GPRRegister Reg, int32_t Offset,
138 OperandARM32Mem::AddrMode Mode) {
139 uint32_t Value = Mode | (encodeGPRRegister(Reg) << kRnShift);
140 if (Offset < 0) {
141 Value = (Value ^ U) | -Offset; // Flip U to adjust sign.
142 } else {
143 Value |= Offset;
144 }
145 return Value;
146 }
147
148 // Decodes memory address Opnd, and encodes that information into Value,
149 // based on how ARM represents the address. Returns how the value was encoded.
150 DecodedResult decodeAddress(const Operand *Opnd, uint32_t &Value) {
151 if (const auto *Var = llvm::dyn_cast<Variable>(Opnd)) {
152 // Should be a stack variable, with an offset.
153 if (Var->hasReg())
154 return CantDecode;
155 const int32_t Offset = Var->getStackOffset();
156 if (!Utils::IsAbsoluteUint(12, Offset))
157 return CantDecode;
158 Value = decodeImmRegOffset(RegARM32::Encoded_Reg_sp, Offset,
159 OperandARM32Mem::Offset);
160 return DecodedAsImmRegOffset;
161 }
162 return CantDecode;
163 }
164
101 } // end of anonymous namespace 165 } // end of anonymous namespace
102 166
103 namespace Ice { 167 namespace Ice {
104 168
105 Label *ARM32::AssemblerARM32::getOrCreateLabel(SizeT Number, 169 Label *ARM32::AssemblerARM32::getOrCreateLabel(SizeT Number,
106 LabelVector &Labels) { 170 LabelVector &Labels) {
107 Label *L = nullptr; 171 Label *L = nullptr;
108 if (Number == Labels.size()) { 172 if (Number == Labels.size()) {
109 L = new (this->allocate<Label>()) Label(); 173 L = new (this->allocate<Label>()) Label();
110 Labels.push_back(L); 174 Labels.push_back(L);
(...skipping 22 matching lines...) Expand all
133 // TODO(kschimpf) Decide if we have near jumps. 197 // TODO(kschimpf) Decide if we have near jumps.
134 label->bindTo(bound); 198 label->bindTo(bound);
135 } 199 }
136 200
137 void ARM32::AssemblerARM32::emitType01(CondARM32::Cond Cond, uint32_t Type, 201 void ARM32::AssemblerARM32::emitType01(CondARM32::Cond Cond, uint32_t Type,
138 uint32_t Opcode, bool SetCc, uint32_t Rn, 202 uint32_t Opcode, bool SetCc, uint32_t Rn,
139 uint32_t Rd, uint32_t Imm12) { 203 uint32_t Rd, uint32_t Imm12) {
140 assert(isGPRRegisterDefined(Rd)); 204 assert(isGPRRegisterDefined(Rd));
141 assert(Cond != CondARM32::kNone); 205 assert(Cond != CondARM32::kNone);
142 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 206 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
143 uint32_t Encoding = encodeCondition(Cond) << kConditionShift | 207 const uint32_t Encoding = (encodeCondition(Cond) << kConditionShift) |
144 (Type << kTypeShift) | (Opcode << kOpcodeShift) | 208 (Type << kTypeShift) | (Opcode << kOpcodeShift) |
145 (encodeBool(SetCc) << kSShift) | (Rn << kRnShift) | 209 (encodeBool(SetCc) << kSShift) | (Rn << kRnShift) |
146 (Rd << kRdShift) | Imm12; 210 (Rd << kRdShift) | Imm12;
147 emitInst(Encoding); 211 emitInst(Encoding);
148 } 212 }
149 213
214 void ARM32::AssemblerARM32::emitMemOp(CondARM32::Cond Cond, uint32_t InstType,
215 bool IsLoad, bool IsByte, uint32_t Rt,
216 uint32_t Address) {
217 assert(isGPRRegisterDefined(Rt));
218 assert(Cond != CondARM32::kNone);
219 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
220 const uint32_t Encoding = (encodeCondition(Cond) << kConditionShift) |
221 (InstType << kTypeShift) | (IsLoad ? L : 0) |
222 (IsByte ? B : 0) | (Rt << kRdShift) | Address;
223 emitInst(Encoding);
224 }
225
150 void ARM32::AssemblerARM32::add(const Operand *OpRd, const Operand *OpRn, 226 void ARM32::AssemblerARM32::add(const Operand *OpRd, const Operand *OpRn,
151 const Operand *OpSrc1, bool SetFlags, 227 const Operand *OpSrc1, bool SetFlags,
152 CondARM32::Cond Cond) { 228 CondARM32::Cond Cond) {
153 // Note: Loop is used so that we can short circuit using break; 229 // Note: Loop is used so that we can short circuit using break;
154 do { 230 do {
155 uint32_t Rd; 231 uint32_t Rd;
156 if (decode(OpRd, Rd) != DecodedAsRegister) 232 if (decodeOperand(OpRd, Rd) != DecodedAsRegister)
157 break; 233 break;
158 uint32_t Rn; 234 uint32_t Rn;
159 if (decode(OpRn, Rn) != DecodedAsRegister) 235 if (decodeOperand(OpRn, Rn) != DecodedAsRegister)
160 break; 236 break;
161 uint32_t Src1Value; 237 uint32_t Src1Value;
162 // TODO(kschimpf) Other possible decodings of add. 238 // TODO(kschimpf) Other possible decodings of add.
163 if (decode(OpSrc1, Src1Value) == DecodedAsRotatedImm8) { 239 if (decodeOperand(OpSrc1, Src1Value) == DecodedAsRotatedImm8) {
164 // ADD (Immediate): See ARM section A8.8.5, rule A1. 240 // ADD (Immediate): See ARM section A8.8.5, rule A1.
165 // cccc0010100snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn, 241 // cccc0010100snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn,
166 // s=SetFlags and iiiiiiiiiiii=Src1Value 242 // s=SetFlags and iiiiiiiiiiii=Src1Value
167 if (!isConditionDefined(Cond) || (Rd == RegARM32::Reg_pc && SetFlags) || 243 if (!isConditionDefined(Cond) || (Rd == RegARM32::Reg_pc && SetFlags) ||
168 (Rn == RegARM32::Reg_lr) || (Rn == RegARM32::Reg_pc && SetFlags)) 244 (Rn == RegARM32::Reg_lr) || (Rn == RegARM32::Reg_pc && SetFlags))
169 // Conditions of rule violated. 245 // Conditions of rule violated.
170 break; 246 break;
171 uint32_t Add = B2; // 0100 247 constexpr uint32_t Add = B2; // 0100
172 uint32_t InstType = 1; 248 constexpr uint32_t InstType = 1;
173 emitType01(Cond, InstType, Add, SetFlags, Rn, Rd, Src1Value); 249 emitType01(Cond, InstType, Add, SetFlags, Rn, Rd, Src1Value);
174 return; 250 return;
175 } 251 }
176 } while (0); 252 } while (0);
177 UnimplementedError(Ctx->getFlags()); 253 UnimplementedError(Ctx->getFlags());
178 } 254 }
179 255
180 void ARM32::AssemblerARM32::bkpt(uint16_t imm16) { 256 void ARM32::AssemblerARM32::bkpt(uint16_t imm16) {
181 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 257 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
182 uint32_t Encoding = (CondARM32::AL << kConditionShift) | B24 | B21 | 258 const uint32_t Encoding = (CondARM32::AL << kConditionShift) | B24 | B21 |
183 ((imm16 >> 4) << 8) | B6 | B5 | B4 | (imm16 & 0xf); 259 ((imm16 >> 4) << 8) | B6 | B5 | B4 | (imm16 & 0xf);
184 emitInst(Encoding); 260 emitInst(Encoding);
185 } 261 }
186 262
187 void ARM32::AssemblerARM32::bx(RegARM32::GPRRegister Rm, CondARM32::Cond Cond) { 263 void ARM32::AssemblerARM32::bx(RegARM32::GPRRegister Rm, CondARM32::Cond Cond) {
188 // cccc000100101111111111110001mmmm where mmmm=rm and cccc=Cond. 264 // cccc000100101111111111110001mmmm where mmmm=rm and cccc=Cond.
189 // (ARM section A8.8.27, encoding A1). 265 // (ARM section A8.8.27, encoding A1).
190 assert(isGPRRegisterDefined(Rm)); 266 assert(isGPRRegisterDefined(Rm));
191 assert(isConditionDefined(Cond)); 267 assert(isConditionDefined(Cond));
192 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 268 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
193 uint32_t Encoding = (encodeCondition(Cond) << kConditionShift) | B24 | B21 | 269 const uint32_t Encoding = (encodeCondition(Cond) << kConditionShift) | B24 |
194 (0xfff << 8) | B4 | (encodeGPRRegister(Rm) << kRmShift); 270 B21 | (0xfff << 8) | B4 |
271 (encodeGPRRegister(Rm) << kRmShift);
195 emitInst(Encoding); 272 emitInst(Encoding);
196 } 273 }
197 274
275 void ARM32::AssemblerARM32::ldr(const Operand *OpRt, const Operand *OpAddress,
276 CondARM32::Cond Cond) {
277 // Note: Loop is used so that we can short ciruit using break;
278 do {
279 uint32_t Rt;
280 if (decodeOperand(OpRt, Rt) != DecodedAsRegister)
281 break;
282 uint32_t Address;
283 if (decodeAddress(OpAddress, Address) != DecodedAsImmRegOffset)
284 break;
285 // cccc010pu0w1nnnnttttiiiiiiiiiiii (ARM section A8.8.63, encoding A1; and
286 // section A8.6.68, encoding A1).
287 constexpr uint32_t InstType = B1; // 010
288 constexpr bool IsLoad = true;
289 const Type Ty = OpRt->getType();
290 if (!(Ty == IceType_i32 || Ty == IceType_i8)) // TODO(kschimpf) Expand?
291 break;
292 const bool IsByte = typeWidthInBytes(Ty) == 1;
293 if ((getGPRReg(kRnShift, Address) == RegARM32::Encoded_Reg_pc) ||
294 (!IsByte && !isBitSet(P, Address) && isBitSet(W, Address)) ||
295 ((getGPRReg(kRnShift, Address) == RegARM32::Encoded_Reg_sp) &&
296 !isBitSet(P, Address) &&
297 isBitSet(U, Address) & !isBitSet(W, Address) &&
298 (mask(Address, kImm12Shift, kImmed12Bits) == 0x8 /* 000000000100 */)))
299 break;
300 emitMemOp(Cond, InstType, IsLoad, IsByte, Rt, Address);
301 return;
302 } while (0);
303 UnimplementedError(Ctx->getFlags());
304 }
305
198 void ARM32::AssemblerARM32::mov(const Operand *OpRd, const Operand *OpSrc, 306 void ARM32::AssemblerARM32::mov(const Operand *OpRd, const Operand *OpSrc,
199 CondARM32::Cond Cond) { 307 CondARM32::Cond Cond) {
200 // Note: Loop is used so that we can short ciruit using break; 308 // Note: Loop is used so that we can short ciruit using break;
201 do { 309 do {
202 uint32_t Rd; 310 uint32_t Rd;
203 if (decode(OpRd, Rd) != DecodedAsRegister) 311 if (decodeOperand(OpRd, Rd) != DecodedAsRegister)
204 break; 312 break;
205 uint32_t Src; 313 uint32_t Src;
206 // TODO(kschimpf) Handle other forms of mov. 314 // TODO(kschimpf) Handle other forms of mov.
207 if (decode(OpSrc, Src) == DecodedAsRotatedImm8) { 315 if (decodeOperand(OpSrc, Src) == DecodedAsRotatedImm8) {
208 // cccc0011101s0000ddddiiiiiiiiiiii (ARM section A8.8.102, encoding A1) 316 // cccc0011101s0000ddddiiiiiiiiiiii (ARM section A8.8.102, encoding A1)
209 // Note: We don't use movs in this assembler. 317 // Note: We don't use movs in this assembler.
210 constexpr bool SetFlags = false; 318 constexpr bool SetFlags = false;
211 if (!isConditionDefined(Cond) || (Rd == RegARM32::Reg_pc && SetFlags)) 319 if (!isConditionDefined(Cond) || (Rd == RegARM32::Reg_pc && SetFlags))
212 // Conditions of rule violated. 320 // Conditions of rule violated.
213 break; 321 break;
214 uint32_t Rn = 0; 322 constexpr uint32_t Rn = 0;
215 uint32_t Mov = B3 | B2 | B0; // 1101. 323 constexpr uint32_t Mov = B3 | B2 | B0; // 1101.
216 uint32_t InstType = 1; 324 constexpr uint32_t InstType = 1;
217 emitType01(Cond, InstType, Mov, SetFlags, Rn, Rd, Src); 325 emitType01(Cond, InstType, Mov, SetFlags, Rn, Rd, Src);
218 return; 326 return;
219 } 327 }
220 } while (0); 328 } while (0);
221 UnimplementedError(Ctx->getFlags()); 329 UnimplementedError(Ctx->getFlags());
222 } 330 }
223 331
332 void ARM32::AssemblerARM32::str(const Operand *OpRt, const Operand *OpAddress,
333 CondARM32::Cond Cond) {
334 // Note: Loop is used so that we can short ciruit using break;
335 do {
336 uint32_t Rt;
337 if (decodeOperand(OpRt, Rt) != DecodedAsRegister)
338 break;
339 uint32_t Address;
340 if (decodeAddress(OpAddress, Address) != DecodedAsImmRegOffset)
341 break;
342 // cccc010pub0nnnnttttiiiiiiiiiiii (ARM section A8.8.204, encoding A1; and
343 // section 18.8.207, encoding A1).
344 constexpr uint32_t InstType = B1; // 010
345 constexpr bool IsLoad = false;
346 const Type Ty = OpRt->getType();
347 if (!(Ty == IceType_i32 || Ty == IceType_i8)) // TODO(kschimpf) Expand?
348 break;
349 const bool IsByte = typeWidthInBytes(Ty) == 1;
350 // Check for rule violations.
351 if ((getGPRReg(kRnShift, Address) == RegARM32::Encoded_Reg_pc) ||
352 (!isBitSet(P, Address) && isBitSet(W, Address)) ||
353 (!IsByte &&
354 (getGPRReg(kRnShift, Address) == RegARM32::Encoded_Reg_sp) &&
355 isBitSet(P, Address) && !isBitSet(U, Address) &&
356 isBitSet(W, Address) &&
357 (mask(Address, kImm12Shift, kImmed12Bits) == 0x8 /* 000000000100 */)))
358 break;
359 emitMemOp(Cond, InstType, IsLoad, IsByte, Rt, Address);
360 return;
361 } while (0);
362 UnimplementedError(Ctx->getFlags());
363 }
364
224 void ARM32::AssemblerARM32::sub(const Operand *OpRd, const Operand *OpRn, 365 void ARM32::AssemblerARM32::sub(const Operand *OpRd, const Operand *OpRn,
225 const Operand *OpSrc1, bool SetFlags, 366 const Operand *OpSrc1, bool SetFlags,
226 CondARM32::Cond Cond) { 367 CondARM32::Cond Cond) {
227 // Note: Loop is used so that we can short circuit using break; 368 // Note: Loop is used so that we can short circuit using break;
228 do { 369 do {
229 uint32_t Rd; 370 uint32_t Rd;
230 if (decode(OpRd, Rd) != DecodedAsRegister) 371 if (decodeOperand(OpRd, Rd) != DecodedAsRegister)
231 break; 372 break;
232 uint32_t Rn; 373 uint32_t Rn;
233 if (decode(OpRn, Rn) != DecodedAsRegister) 374 if (decodeOperand(OpRn, Rn) != DecodedAsRegister)
234 break; 375 break;
235 uint32_t Src1Value; 376 uint32_t Src1Value;
236 // TODO(kschimpf) Other possible decodings of add. 377 // TODO(kschimpf) Other possible decodings of add.
237 if (decode(OpSrc1, Src1Value) == DecodedAsRotatedImm8) { 378 if (decodeOperand(OpSrc1, Src1Value) == DecodedAsRotatedImm8) {
238 // Sub (Immediate): See ARM section A8.8.222, rule A1. 379 // Sub (Immediate): See ARM section A8.8.222, rule A1.
239 // cccc0010010snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn, 380 // cccc0010010snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn,
240 // s=SetFlags and iiiiiiiiiiii=Src1Value 381 // s=SetFlags and iiiiiiiiiiii=Src1Value
241 if (!isConditionDefined(Cond) || (Rd == RegARM32::Reg_pc && SetFlags) || 382 if (!isConditionDefined(Cond) || (Rd == RegARM32::Reg_pc && SetFlags) ||
242 (Rn == RegARM32::Reg_lr) || (Rn == RegARM32::Reg_pc && SetFlags)) 383 (Rn == RegARM32::Reg_lr) || (Rn == RegARM32::Reg_pc && SetFlags))
243 // Conditions of rule violated. 384 // Conditions of rule violated.
244 break; 385 break;
245 uint32_t Add = B1; // 0010 386 constexpr uint32_t Add = B1; // 0010
246 uint32_t InstType = 1; 387 constexpr uint32_t InstType = 1;
247 emitType01(Cond, InstType, Add, SetFlags, Rn, Rd, Src1Value); 388 emitType01(Cond, InstType, Add, SetFlags, Rn, Rd, Src1Value);
248 return; 389 return;
249 } 390 }
250 } while (0); 391 } while (0);
251 UnimplementedError(Ctx->getFlags()); 392 UnimplementedError(Ctx->getFlags());
252 } 393 }
253 394
254 } // end of namespace Ice 395 } // end of namespace Ice
OLDNEW
« no previous file with comments | « src/IceAssemblerARM32.h ('k') | src/IceInstARM32.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698