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

Side by Side Diff: src/IceAssemblerARM32.cpp

Issue 1411873002: emit add/sub registers instructions in integrated ARM 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
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 //
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
55 static constexpr uint32_t kRnShift = 16; 55 static constexpr uint32_t kRnShift = 16;
56 static constexpr uint32_t kSShift = 20; 56 static constexpr uint32_t kSShift = 20;
57 static constexpr uint32_t kTypeShift = 25; 57 static constexpr uint32_t kTypeShift = 25;
58 58
59 // Immediate instruction fields encoding. 59 // Immediate instruction fields encoding.
60 static constexpr uint32_t kImmed8Bits = 8; 60 static constexpr uint32_t kImmed8Bits = 8;
61 static constexpr uint32_t kImmed8Shift = 0; 61 static constexpr uint32_t kImmed8Shift = 0;
62 static constexpr uint32_t kRotateBits = 4; 62 static constexpr uint32_t kRotateBits = 4;
63 static constexpr uint32_t kRotateShift = 8; 63 static constexpr uint32_t kRotateShift = 8;
64 64
65 // Shift instruction register fields encodings.
66 static constexpr uint32_t kShiftImmShift = 7;
67 static constexpr uint32_t kShiftImmBits = 5;
68 static constexpr uint32_t kShiftShift = 5;
69
65 static constexpr uint32_t kImmed12Bits = 12; 70 static constexpr uint32_t kImmed12Bits = 12;
66 static constexpr uint32_t kImm12Shift = 0; 71 static constexpr uint32_t kImm12Shift = 0;
67 72
68 inline uint32_t encodeBool(bool b) { return b ? 1 : 0; } 73 inline uint32_t encodeBool(bool b) { return b ? 1 : 0; }
69 74
70 inline uint32_t encodeGPRRegister(RegARM32::GPRRegister Rn) { 75 inline uint32_t encodeGPRRegister(RegARM32::GPRRegister Rn) {
71 return static_cast<uint32_t>(Rn); 76 return static_cast<uint32_t>(Rn);
72 } 77 }
73 78
74 inline bool isGPRRegisterDefined(RegARM32::GPRRegister R) { 79 inline bool isGPRRegisterDefined(RegARM32::GPRRegister R) {
75 return R != RegARM32::Encoded_Not_GPR; 80 return R != RegARM32::Encoded_Not_GPR;
76 } 81 }
77 82
78 inline bool isGPRRegisterDefined(uint32_t R) { 83 inline bool isGPRRegisterDefined(uint32_t R) {
79 return R != encodeGPRRegister(RegARM32::Encoded_Not_GPR); 84 return R != encodeGPRRegister(RegARM32::Encoded_Not_GPR);
80 } 85 }
81 86
82 inline bool isConditionDefined(CondARM32::Cond Cond) { 87 inline bool isConditionDefined(CondARM32::Cond Cond) {
83 return Cond != CondARM32::kNone; 88 return Cond != CondARM32::kNone;
84 } 89 }
85 90
86 inline uint32_t encodeCondition(CondARM32::Cond Cond) { 91 inline uint32_t encodeCondition(CondARM32::Cond Cond) {
87 return static_cast<uint32_t>(Cond); 92 return static_cast<uint32_t>(Cond);
88 } 93 }
89 94
95 uint32_t encodeShift(OperandARM32::ShiftKind Shift) {
96 // Follows encoding in ARM section A8.4.1 "Constant shifts".
97 switch (Shift) {
98 case OperandARM32::kNoShift:
99 case OperandARM32::LSL:
100 return 0; // 0b00
101 case OperandARM32::LSR:
102 return 1; // 0b01
103 case OperandARM32::ASR:
104 return 2; // 0b10
105 case OperandARM32::ROR:
106 case OperandARM32::RRX:
107 return 3; // 0b11
108 }
109 }
110
90 // Returns the bits in the corresponding masked value. 111 // Returns the bits in the corresponding masked value.
91 inline uint32_t mask(uint32_t Value, uint32_t Shift, uint32_t Bits) { 112 inline uint32_t mask(uint32_t Value, uint32_t Shift, uint32_t Bits) {
92 return (Value >> Shift) & ((1 << Bits) - 1); 113 return (Value >> Shift) & ((1 << Bits) - 1);
93 } 114 }
94 115
95 // Extract out a Bit in Value. 116 // Extract out a Bit in Value.
96 inline bool isBitSet(uint32_t Bit, uint32_t Value) { 117 inline bool isBitSet(uint32_t Bit, uint32_t Value) {
97 return (Value & Bit) == Bit; 118 return (Value & Bit) == Bit;
98 } 119 }
99 120
(...skipping 11 matching lines...) Expand all
111 DecodedAsRegister, 132 DecodedAsRegister,
112 // Value=rrrriiiiiiii where rrrr is the rotation, and iiiiiiii is the imm8 133 // Value=rrrriiiiiiii where rrrr is the rotation, and iiiiiiii is the imm8
113 // value. 134 // value.
114 DecodedAsRotatedImm8, 135 DecodedAsRotatedImm8,
115 // i.e. 0000000pu0w0nnnn0000iiiiiiiiiiii where nnnn is the base register Rn, 136 // 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 137 // 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. 138 // Rn should be used, and iiiiiiiiiiii is the offset.
118 DecodedAsImmRegOffset 139 DecodedAsImmRegOffset
119 }; 140 };
120 141
142 // Encodes iiiiitt0mmmm for data-processing (2nd) operands where iiiii=Imm5,
143 // tt=Shift, and mmmm=Rm.
144 uint32_t encodeShiftRotateImm5(uint32_t Rm, OperandARM32::ShiftKind Shift,
145 uint32_t imm5) {
146 assert(imm5 < (1 << kShiftImmBits));
147 return (imm5 << kShiftImmShift) | (encodeShift(Shift) << kShiftShift) | Rm;
148 }
149
121 DecodedResult decodeOperand(const Operand *Opnd, uint32_t &Value) { 150 DecodedResult decodeOperand(const Operand *Opnd, uint32_t &Value) {
122 if (const auto *Var = llvm::dyn_cast<Variable>(Opnd)) { 151 if (const auto *Var = llvm::dyn_cast<Variable>(Opnd)) {
123 if (Var->hasReg()) { 152 if (Var->hasReg()) {
124 Value = Var->getRegNum(); 153 Value = Var->getRegNum();
125 return DecodedAsRegister; 154 return DecodedAsRegister;
126 } 155 }
127 } else if (const auto *FlexImm = llvm::dyn_cast<OperandARM32FlexImm>(Opnd)) { 156 } else if (const auto *FlexImm = llvm::dyn_cast<OperandARM32FlexImm>(Opnd)) {
128 const uint32_t Immed8 = FlexImm->getImm(); 157 const uint32_t Immed8 = FlexImm->getImm();
129 const uint32_t Rotate = FlexImm->getRotateAmt(); 158 const uint32_t Rotate = FlexImm->getRotateAmt();
130 assert((Rotate < (1 << kRotateBits)) && (Immed8 < (1 << kImmed8Bits))); 159 assert((Rotate < (1 << kRotateBits)) && (Immed8 < (1 << kImmed8Bits)));
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
227 const Operand *OpSrc1, bool SetFlags, 256 const Operand *OpSrc1, bool SetFlags,
228 CondARM32::Cond Cond) { 257 CondARM32::Cond Cond) {
229 // Note: Loop is used so that we can short circuit using break; 258 // Note: Loop is used so that we can short circuit using break;
230 do { 259 do {
231 uint32_t Rd; 260 uint32_t Rd;
232 if (decodeOperand(OpRd, Rd) != DecodedAsRegister) 261 if (decodeOperand(OpRd, Rd) != DecodedAsRegister)
233 break; 262 break;
234 uint32_t Rn; 263 uint32_t Rn;
235 if (decodeOperand(OpRn, Rn) != DecodedAsRegister) 264 if (decodeOperand(OpRn, Rn) != DecodedAsRegister)
236 break; 265 break;
266 constexpr uint32_t Add = B2; // 0100
237 uint32_t Src1Value; 267 uint32_t Src1Value;
238 // TODO(kschimpf) Other possible decodings of add. 268 // TODO(kschimpf) Other possible decodings of add.
239 if (decodeOperand(OpSrc1, Src1Value) == DecodedAsRotatedImm8) { 269 switch (decodeOperand(OpSrc1, Src1Value)) {
240 // ADD (Immediate): See ARM section A8.8.5, rule A1. 270 default:
241 // cccc0010100snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn, 271 break;
242 // s=SetFlags and iiiiiiiiiiii=Src1Value 272 case DecodedAsRegister: {
243 if (!isConditionDefined(Cond) || (Rd == RegARM32::Reg_pc && SetFlags) || 273 // ADD (register) - ARM section A8.8.7, encoding A1:
244 (Rn == RegARM32::Reg_lr) || (Rn == RegARM32::Reg_pc && SetFlags)) 274 // add{s}<c> <Rd>, <Rn>, <Rm>{, <shiff>}
275 // ADD (Sp plus register) - ARM section A8.8.11, encoding A1:
276 // add{s}<c> sp, <Rn>, <Rm>{, <shiff>}
277 //
278 // cccc0000100snnnnddddiiiiitt0mmmm where cccc=Cond, dddd=Rd, nnnn=Rn,
279 // mmmm=Rm, iiiii=Shift, tt=ShiftKind, and s=SetFlags
280 Src1Value = encodeShiftRotateImm5(Src1Value, OperandARM32::kNoShift, 0);
281 if (((Rd == RegARM32::Encoded_Reg_pc) && SetFlags))
245 // Conditions of rule violated. 282 // Conditions of rule violated.
246 break; 283 break;
247 constexpr uint32_t Add = B2; // 0100 284 constexpr uint32_t InstType = 0; // i.e. register
Jim Stichnoth 2015/10/16 21:30:09 Might be clearer to name this InstTypeReg. (and In
Karl 2015/10/17 20:00:41 Done.
248 constexpr uint32_t InstType = 1;
249 emitType01(Cond, InstType, Add, SetFlags, Rn, Rd, Src1Value); 285 emitType01(Cond, InstType, Add, SetFlags, Rn, Rd, Src1Value);
250 return; 286 return;
251 } 287 }
288 case DecodedAsRotatedImm8: {
289 // ADD (Immediate) - ARM section A8.8.5, encoding A1:
290 // add{s}<c> <Rd>, <Rn>, #<RotatedImm8>
291 // ADD (SP plus immediate) - ARM section A8.8.9, encoding A1.
292 // add{s}<c> <Rd>, sp, #<RotatedImm8>
293 //
294 // cccc0010100snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn,
295 // s=SetFlags and iiiiiiiiiiii=Src1Value=RotatedImm8.
296 if ((Rd == RegARM32::Encoded_Reg_pc && SetFlags))
297 // Conditions of rule violated.
298 break;
299 constexpr uint32_t InstType = 1; // i.e. immediate.
300 emitType01(Cond, InstType, Add, SetFlags, Rn, Rd, Src1Value);
301 return;
302 }
303 }
252 } while (0); 304 } while (0);
253 UnimplementedError(Ctx->getFlags()); 305 UnimplementedError(Ctx->getFlags());
254 } 306 }
255 307
256 void ARM32::AssemblerARM32::bkpt(uint16_t imm16) { 308 void ARM32::AssemblerARM32::bkpt(uint16_t Imm16) {
309 // BKPT - ARM section A*.8.24 - encoding A1:
310 // bkpt #<Imm16>
311 //
312 // cccc00010010iiiiiiiiiiii0111iiii where cccc=AL and iiiiiiiiiiiiiiii=Imm16
257 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 313 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
258 const uint32_t Encoding = (CondARM32::AL << kConditionShift) | B24 | B21 | 314 const uint32_t Encoding = (CondARM32::AL << kConditionShift) | B24 | B21 |
259 ((imm16 >> 4) << 8) | B6 | B5 | B4 | (imm16 & 0xf); 315 ((Imm16 >> 4) << 8) | B6 | B5 | B4 | (Imm16 & 0xf);
260 emitInst(Encoding); 316 emitInst(Encoding);
261 } 317 }
262 318
263 void ARM32::AssemblerARM32::bx(RegARM32::GPRRegister Rm, CondARM32::Cond Cond) { 319 void ARM32::AssemblerARM32::bx(RegARM32::GPRRegister Rm, CondARM32::Cond Cond) {
320 // BX - ARM section A8.8.27, encoding A1:
321 // bx<c> <Rm>
322 //
264 // cccc000100101111111111110001mmmm where mmmm=rm and cccc=Cond. 323 // cccc000100101111111111110001mmmm where mmmm=rm and cccc=Cond.
265 // (ARM section A8.8.27, encoding A1).
266 assert(isGPRRegisterDefined(Rm)); 324 assert(isGPRRegisterDefined(Rm));
267 assert(isConditionDefined(Cond)); 325 assert(isConditionDefined(Cond));
268 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 326 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
269 const uint32_t Encoding = (encodeCondition(Cond) << kConditionShift) | B24 | 327 const uint32_t Encoding = (encodeCondition(Cond) << kConditionShift) | B24 |
270 B21 | (0xfff << 8) | B4 | 328 B21 | (0xfff << 8) | B4 |
271 (encodeGPRRegister(Rm) << kRmShift); 329 (encodeGPRRegister(Rm) << kRmShift);
272 emitInst(Encoding); 330 emitInst(Encoding);
273 } 331 }
274 332
275 void ARM32::AssemblerARM32::ldr(const Operand *OpRt, const Operand *OpAddress, 333 void ARM32::AssemblerARM32::ldr(const Operand *OpRt, const Operand *OpAddress,
276 CondARM32::Cond Cond) { 334 CondARM32::Cond Cond) {
277 // Note: Loop is used so that we can short ciruit using break; 335 // Note: Loop is used so that we can short ciruit using break;
278 do { 336 do {
279 uint32_t Rt; 337 uint32_t Rt;
280 if (decodeOperand(OpRt, Rt) != DecodedAsRegister) 338 if (decodeOperand(OpRt, Rt) != DecodedAsRegister)
281 break; 339 break;
282 uint32_t Address; 340 uint32_t Address;
283 if (decodeAddress(OpAddress, Address) != DecodedAsImmRegOffset) 341 if (decodeAddress(OpAddress, Address) != DecodedAsImmRegOffset)
284 break; 342 break;
285 // cccc010pu0w1nnnnttttiiiiiiiiiiii (ARM section A8.8.63, encoding A1; and 343 // LDR (immediate) - ARM section A8.8.63, encoding A1:
286 // section A8.6.68, encoding A1). 344 // ldr<c> <Rt>, [<Rn>{, #+/-<imm12>}] ; p=1, w=0
345 // ldr<c> <Rt>, [<Rn>], #+/-<imm12> ; p=1, w=1
346 // ldr<c> <Rt>, [<Rn>, #+/-<imm12>]! ; p=0, w=1
347 // LDRB (immediate) - ARM section A8.8.68, encoding A1:
348 // ldrb<c> <Rt>, [<Rn>{, #+/-<imm12>}] ; p=1, w=0
349 // ldrb<c> <Rt>, [<Rn>], #+/-<imm12> ; p=1, w=1
350 // ldrb<c> <Rt>, [<Rn>, #+/-<imm12>]! ; p=0, w=1
351 //
352 // cccc010pubw1nnnnttttiiiiiiiiiiii where cccc=Cond, tttt=Rt, nnnn=Rn,
353 // iiiiiiiiiiii=imm12, b=1 if STRB, u=1 if +.
287 constexpr uint32_t InstType = B1; // 010 354 constexpr uint32_t InstType = B1; // 010
288 constexpr bool IsLoad = true; 355 constexpr bool IsLoad = true;
289 const Type Ty = OpRt->getType(); 356 const Type Ty = OpRt->getType();
290 if (!(Ty == IceType_i32 || Ty == IceType_i8)) // TODO(kschimpf) Expand? 357 if (!(Ty == IceType_i32 || Ty == IceType_i8)) // TODO(kschimpf) Expand?
291 break; 358 break;
292 const bool IsByte = typeWidthInBytes(Ty) == 1; 359 const bool IsByte = typeWidthInBytes(Ty) == 1;
293 if ((getGPRReg(kRnShift, Address) == RegARM32::Encoded_Reg_pc) || 360 if ((getGPRReg(kRnShift, Address) == RegARM32::Encoded_Reg_pc) ||
294 (!IsByte && !isBitSet(P, Address) && isBitSet(W, Address)) || 361 (!isBitSet(P, Address) && isBitSet(W, Address)) ||
295 ((getGPRReg(kRnShift, Address) == RegARM32::Encoded_Reg_sp) && 362 (!IsByte &&
363 (getGPRReg(kRnShift, Address) == RegARM32::Encoded_Reg_sp) &&
296 !isBitSet(P, Address) && 364 !isBitSet(P, Address) &&
297 isBitSet(U, Address) & !isBitSet(W, Address) && 365 isBitSet(U, Address) & !isBitSet(W, Address) &&
298 (mask(Address, kImm12Shift, kImmed12Bits) == 0x8 /* 000000000100 */))) 366 (mask(Address, kImm12Shift, kImmed12Bits) == 0x8 /* 000000000100 */)))
299 break; 367 break;
300 emitMemOp(Cond, InstType, IsLoad, IsByte, Rt, Address); 368 emitMemOp(Cond, InstType, IsLoad, IsByte, Rt, Address);
301 return; 369 return;
302 } while (0); 370 } while (0);
303 UnimplementedError(Ctx->getFlags()); 371 UnimplementedError(Ctx->getFlags());
304 } 372 }
305 373
306 void ARM32::AssemblerARM32::mov(const Operand *OpRd, const Operand *OpSrc, 374 void ARM32::AssemblerARM32::mov(const Operand *OpRd, const Operand *OpSrc,
307 CondARM32::Cond Cond) { 375 CondARM32::Cond Cond) {
308 // Note: Loop is used so that we can short ciruit using break; 376 // Note: Loop is used so that we can short ciruit using break;
309 do { 377 do {
310 uint32_t Rd; 378 uint32_t Rd;
311 if (decodeOperand(OpRd, Rd) != DecodedAsRegister) 379 if (decodeOperand(OpRd, Rd) != DecodedAsRegister)
312 break; 380 break;
313 uint32_t Src; 381 uint32_t Src;
314 // TODO(kschimpf) Handle other forms of mov. 382 // TODO(kschimpf) Handle other forms of mov.
315 if (decodeOperand(OpSrc, Src) == DecodedAsRotatedImm8) { 383 if (decodeOperand(OpSrc, Src) == DecodedAsRotatedImm8) {
316 // cccc0011101s0000ddddiiiiiiiiiiii (ARM section A8.8.102, encoding A1) 384 // MOV (immediate) - ARM section A8.8.102, encoding A1:
317 // Note: We don't use movs in this assembler. 385 // mov{S}<c> <Rd>, #<RotatedImm8>
386 //
387 // cccc0011101s0000ddddiiiiiiiiiiii where cccc=Cond, s=SetFlags, dddd=Rd,
388 // and iiiiiiiiiiii=RotatedImm8=Src. Note: We don't use movs in this
389 // assembler.
318 constexpr bool SetFlags = false; 390 constexpr bool SetFlags = false;
319 if (!isConditionDefined(Cond) || (Rd == RegARM32::Reg_pc && SetFlags)) 391 if ((Rd == RegARM32::Encoded_Reg_pc && SetFlags))
320 // Conditions of rule violated. 392 // Conditions of rule violated.
321 break; 393 break;
322 constexpr uint32_t Rn = 0; 394 constexpr uint32_t Rn = 0;
323 constexpr uint32_t Mov = B3 | B2 | B0; // 1101. 395 constexpr uint32_t Mov = B3 | B2 | B0; // 1101.
324 constexpr uint32_t InstType = 1; 396 constexpr uint32_t InstType = 1;
325 emitType01(Cond, InstType, Mov, SetFlags, Rn, Rd, Src); 397 emitType01(Cond, InstType, Mov, SetFlags, Rn, Rd, Src);
326 return; 398 return;
327 } 399 }
328 } while (0); 400 } while (0);
329 UnimplementedError(Ctx->getFlags()); 401 UnimplementedError(Ctx->getFlags());
330 } 402 }
331 403
332 void ARM32::AssemblerARM32::str(const Operand *OpRt, const Operand *OpAddress, 404 void ARM32::AssemblerARM32::str(const Operand *OpRt, const Operand *OpAddress,
333 CondARM32::Cond Cond) { 405 CondARM32::Cond Cond) {
334 // Note: Loop is used so that we can short ciruit using break; 406 // Note: Loop is used so that we can short ciruit using break;
335 do { 407 do {
336 uint32_t Rt; 408 uint32_t Rt;
337 if (decodeOperand(OpRt, Rt) != DecodedAsRegister) 409 if (decodeOperand(OpRt, Rt) != DecodedAsRegister)
338 break; 410 break;
339 uint32_t Address; 411 uint32_t Address;
340 if (decodeAddress(OpAddress, Address) != DecodedAsImmRegOffset) 412 if (decodeAddress(OpAddress, Address) != DecodedAsImmRegOffset)
341 break; 413 break;
342 // cccc010pub0nnnnttttiiiiiiiiiiii (ARM section A8.8.204, encoding A1; and 414 // STR (immediate) - ARM section A8.8.204, encoding A1:
343 // section 18.8.207, encoding A1). 415 // str<c> <Rt>, [<Rn>{, #+/-<imm12>}] ; p=1, w=0
416 // str<c> <Rt>, [<Rn>], #+/-<imm12> ; p=1, w=1
417 // str<c> <Rt>, [<Rn>, #+/-<imm12>]! ; p=0, w=1
418 // STRB (immediate) - ARM section A8.8.207, encoding A1:
419 // strb<c> <Rt>, [<Rn>{, #+/-<imm12>}] ; p=1, w=0
420 // strb<c> <Rt>, [<Rn>], #+/-<imm12> ; p=1, w=1
421 // strb<c> <Rt>, [<Rn>, #+/-<imm12>]! ; p=0, w=1
422 //
423 // cccc010pubw0nnnnttttiiiiiiiiiiii where cccc=Cond, tttt=Rt, nnnn=Rn,
424 // iiiiiiiiiiii=imm12, b=1 if STRB, u=1 if +.
344 constexpr uint32_t InstType = B1; // 010 425 constexpr uint32_t InstType = B1; // 010
345 constexpr bool IsLoad = false; 426 constexpr bool IsLoad = false;
346 const Type Ty = OpRt->getType(); 427 const Type Ty = OpRt->getType();
347 if (!(Ty == IceType_i32 || Ty == IceType_i8)) // TODO(kschimpf) Expand? 428 if (!(Ty == IceType_i32 || Ty == IceType_i8)) // TODO(kschimpf) Expand?
348 break; 429 break;
349 const bool IsByte = typeWidthInBytes(Ty) == 1; 430 const bool IsByte = typeWidthInBytes(Ty) == 1;
350 // Check for rule violations. 431 // Check for rule violations.
351 if ((getGPRReg(kRnShift, Address) == RegARM32::Encoded_Reg_pc) || 432 if ((getGPRReg(kRnShift, Address) == RegARM32::Encoded_Reg_pc) ||
352 (!isBitSet(P, Address) && isBitSet(W, Address)) || 433 (!isBitSet(P, Address) && isBitSet(W, Address)) ||
353 (!IsByte && 434 (!IsByte &&
354 (getGPRReg(kRnShift, Address) == RegARM32::Encoded_Reg_sp) && 435 (getGPRReg(kRnShift, Address) == RegARM32::Encoded_Reg_sp) &&
355 isBitSet(P, Address) && !isBitSet(U, Address) && 436 isBitSet(P, Address) && !isBitSet(U, Address) &&
356 isBitSet(W, Address) && 437 isBitSet(W, Address) &&
357 (mask(Address, kImm12Shift, kImmed12Bits) == 0x8 /* 000000000100 */))) 438 (mask(Address, kImm12Shift, kImmed12Bits) == 0x8 /* 000000000100 */)))
439 // Conditions of rule violated.
358 break; 440 break;
359 emitMemOp(Cond, InstType, IsLoad, IsByte, Rt, Address); 441 emitMemOp(Cond, InstType, IsLoad, IsByte, Rt, Address);
360 return; 442 return;
361 } while (0); 443 } while (0);
362 UnimplementedError(Ctx->getFlags()); 444 UnimplementedError(Ctx->getFlags());
363 } 445 }
364 446
365 void ARM32::AssemblerARM32::sub(const Operand *OpRd, const Operand *OpRn, 447 void ARM32::AssemblerARM32::sub(const Operand *OpRd, const Operand *OpRn,
366 const Operand *OpSrc1, bool SetFlags, 448 const Operand *OpSrc1, bool SetFlags,
367 CondARM32::Cond Cond) { 449 CondARM32::Cond Cond) {
368 // Note: Loop is used so that we can short circuit using break; 450 // Note: Loop is used so that we can short circuit using break;
369 do { 451 do {
370 uint32_t Rd; 452 uint32_t Rd;
371 if (decodeOperand(OpRd, Rd) != DecodedAsRegister) 453 if (decodeOperand(OpRd, Rd) != DecodedAsRegister)
372 break; 454 break;
373 uint32_t Rn; 455 uint32_t Rn;
374 if (decodeOperand(OpRn, Rn) != DecodedAsRegister) 456 if (decodeOperand(OpRn, Rn) != DecodedAsRegister)
375 break; 457 break;
458 constexpr uint32_t Sub = B1; // 0010
376 uint32_t Src1Value; 459 uint32_t Src1Value;
377 // TODO(kschimpf) Other possible decodings of add. 460 // TODO(kschimpf) Other possible decodings of sub.
378 if (decodeOperand(OpSrc1, Src1Value) == DecodedAsRotatedImm8) { 461 switch (decodeOperand(OpSrc1, Src1Value)) {
379 // Sub (Immediate): See ARM section A8.8.222, rule A1. 462 default:
380 // cccc0010010snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn, 463 break;
381 // s=SetFlags and iiiiiiiiiiii=Src1Value 464 case DecodedAsRegister: {
382 if (!isConditionDefined(Cond) || (Rd == RegARM32::Reg_pc && SetFlags) || 465 // SUB (register) - ARM section A8.8.223, encoding A1:
383 (Rn == RegARM32::Reg_lr) || (Rn == RegARM32::Reg_pc && SetFlags)) 466 // sub{s}<c> <Rd>, <Rn>, <Rm>{, <shift>}
467 // SUB (SP minus register): See ARM section 8.8.226, encoding A1:
468 // sub{s}<c> <Rd>, sp, <Rm>{, <Shift>}
469 //
470 // cccc0000010snnnnddddiiiiitt0mmmm where cccc=Cond, dddd=Rd, nnnn=Rn,
471 // mmmm=Rm, iiiiii=shift, tt=ShiftKind, and s=SetFlags.
472 Src1Value = encodeShiftRotateImm5(Src1Value, OperandARM32::kNoShift, 0);
473 constexpr uint32_t InstType = 0; // i.e. register
474 if (((Rd == RegARM32::Encoded_Reg_pc) && SetFlags))
384 // Conditions of rule violated. 475 // Conditions of rule violated.
385 break; 476 break;
386 constexpr uint32_t Add = B1; // 0010 477 emitType01(Cond, InstType, Sub, SetFlags, Rn, Rd, Src1Value);
478 return;
479 }
480 case DecodedAsRotatedImm8: {
481 // Sub (Immediate) - ARM section A8.8.222, encoding A1:
482 // sub{s}<c> <Rd>, <Rn>, #<RotatedImm8>
483 // Sub (Sp minus immediate) - ARM section A8.*.225, encoding A1:
484 // sub{s}<c> sp, <Rn>, #<RotatedImm8>
485 //
486 // cccc0010010snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn,
487 // s=SetFlags and iiiiiiiiiiii=Src1Value=RotatedImm8
488 if (Rd == RegARM32::Encoded_Reg_pc)
489 // Conditions of rule violated.
490 break;
387 constexpr uint32_t InstType = 1; 491 constexpr uint32_t InstType = 1;
388 emitType01(Cond, InstType, Add, SetFlags, Rn, Rd, Src1Value); 492 emitType01(Cond, InstType, Sub, SetFlags, Rn, Rd, Src1Value);
389 return; 493 return;
390 } 494 }
495 }
391 } while (0); 496 } while (0);
392 UnimplementedError(Ctx->getFlags()); 497 UnimplementedError(Ctx->getFlags());
393 } 498 }
394 499
395 } // end of namespace Ice 500 } // end of namespace Ice
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698