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

Side by Side Diff: src/IceAssemblerARM32.cpp

Issue 1418523002: Add hybrid assembler concept to 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
« no previous file with comments | « src/IceAssemblerARM32.h ('k') | src/IceAssemblerX86Base.h » ('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 //
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
63 static constexpr uint32_t kRotateShift = 8; 63 static constexpr uint32_t kRotateShift = 8;
64 64
65 // Shift instruction register fields encodings. 65 // Shift instruction register fields encodings.
66 static constexpr uint32_t kShiftImmShift = 7; 66 static constexpr uint32_t kShiftImmShift = 7;
67 static constexpr uint32_t kShiftImmBits = 5; 67 static constexpr uint32_t kShiftImmBits = 5;
68 static constexpr uint32_t kShiftShift = 5; 68 static constexpr uint32_t kShiftShift = 5;
69 69
70 static constexpr uint32_t kImmed12Bits = 12; 70 static constexpr uint32_t kImmed12Bits = 12;
71 static constexpr uint32_t kImm12Shift = 0; 71 static constexpr uint32_t kImm12Shift = 0;
72 72
73 // Type of instruction encoding (bits 25-27). See ARM section A5.1
74 static constexpr uint32_t kInstTypeDataRegister = 0; // i.e. 000
75 static constexpr uint32_t kInstTypeDataImmediate = 1; // i.e. 001
76 static constexpr uint32_t kInstTypeMemImmediate = 2; // i.e. 010
77
73 inline uint32_t encodeBool(bool b) { return b ? 1 : 0; } 78 inline uint32_t encodeBool(bool b) { return b ? 1 : 0; }
74 79
75 inline uint32_t encodeGPRRegister(RegARM32::GPRRegister Rn) { 80 inline uint32_t encodeGPRRegister(RegARM32::GPRRegister Rn) {
76 return static_cast<uint32_t>(Rn); 81 return static_cast<uint32_t>(Rn);
77 } 82 }
78 83
79 inline bool isGPRRegisterDefined(RegARM32::GPRRegister R) { 84 inline bool isGPRRegisterDefined(RegARM32::GPRRegister R) {
80 return R != RegARM32::Encoded_Not_GPR; 85 return R != RegARM32::Encoded_Not_GPR;
81 } 86 }
82 87
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
224 while (label->isLinked()) { 229 while (label->isLinked()) {
225 intptr_t position = label->getLinkPosition(); 230 intptr_t position = label->getLinkPosition();
226 intptr_t next = Buffer.load<int32_t>(position); 231 intptr_t next = Buffer.load<int32_t>(position);
227 Buffer.store<int32_t>(position, bound - (position + 4)); 232 Buffer.store<int32_t>(position, bound - (position + 4));
228 label->setPosition(next); 233 label->setPosition(next);
229 } 234 }
230 // TODO(kschimpf) Decide if we have near jumps. 235 // TODO(kschimpf) Decide if we have near jumps.
231 label->bindTo(bound); 236 label->bindTo(bound);
232 } 237 }
233 238
239 void ARM32::AssemblerARM32::emitTextInst(const std::string &Text) {
240 static constexpr uint32_t Placeholder = 0;
241 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
242 AssemblerFixup *F = createTextFixup(Text, sizeof(Placeholder));
243 emitFixup(F);
244 emitInst(Placeholder);
245 }
246
234 void ARM32::AssemblerARM32::emitType01(CondARM32::Cond Cond, uint32_t Type, 247 void ARM32::AssemblerARM32::emitType01(CondARM32::Cond Cond, uint32_t Type,
235 uint32_t Opcode, bool SetCc, uint32_t Rn, 248 uint32_t Opcode, bool SetCc, uint32_t Rn,
236 uint32_t Rd, uint32_t Imm12) { 249 uint32_t Rd, uint32_t Imm12) {
237 assert(isGPRRegisterDefined(Rd)); 250 assert(isGPRRegisterDefined(Rd));
238 // TODO(kschimpf): Remove void cast when MINIMAL build allows. 251 // TODO(kschimpf): Remove void cast when MINIMAL build allows.
239 (void)isGPRRegisterDefined(Rd); 252 (void)isGPRRegisterDefined(Rd);
240 assert(Cond != CondARM32::kNone); 253 assert(Cond != CondARM32::kNone);
241 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 254 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
242 const uint32_t Encoding = (encodeCondition(Cond) << kConditionShift) | 255 const uint32_t Encoding = (encodeCondition(Cond) << kConditionShift) |
243 (Type << kTypeShift) | (Opcode << kOpcodeShift) | 256 (Type << kTypeShift) | (Opcode << kOpcodeShift) |
(...skipping 10 matching lines...) Expand all
254 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 267 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
255 const uint32_t Encoding = (encodeCondition(Cond) << kConditionShift) | 268 const uint32_t Encoding = (encodeCondition(Cond) << kConditionShift) |
256 (InstType << kTypeShift) | (IsLoad ? L : 0) | 269 (InstType << kTypeShift) | (IsLoad ? L : 0) |
257 (IsByte ? B : 0) | (Rt << kRdShift) | Address; 270 (IsByte ? B : 0) | (Rt << kRdShift) | Address;
258 emitInst(Encoding); 271 emitInst(Encoding);
259 } 272 }
260 273
261 void ARM32::AssemblerARM32::add(const Operand *OpRd, const Operand *OpRn, 274 void ARM32::AssemblerARM32::add(const Operand *OpRd, const Operand *OpRn,
262 const Operand *OpSrc1, bool SetFlags, 275 const Operand *OpSrc1, bool SetFlags,
263 CondARM32::Cond Cond) { 276 CondARM32::Cond Cond) {
264 // Note: Loop is used so that we can short circuit using break; 277 uint32_t Rd;
265 do { 278 if (decodeOperand(OpRd, Rd) != DecodedAsRegister)
266 uint32_t Rd; 279 return setNeedsTextFixup();
267 if (decodeOperand(OpRd, Rd) != DecodedAsRegister) 280 uint32_t Rn;
268 break; 281 if (decodeOperand(OpRn, Rn) != DecodedAsRegister)
269 uint32_t Rn; 282 return setNeedsTextFixup();
270 if (decodeOperand(OpRn, Rn) != DecodedAsRegister) 283 constexpr uint32_t Add = B2; // 0100
271 break; 284 uint32_t Src1Value;
272 constexpr uint32_t Add = B2; // 0100 285 // TODO(kschimpf) Other possible decodings of add.
273 uint32_t Src1Value; 286 switch (decodeOperand(OpSrc1, Src1Value)) {
274 // TODO(kschimpf) Other possible decodings of add. 287 default:
275 switch (decodeOperand(OpSrc1, Src1Value)) { 288 return setNeedsTextFixup();
276 default: 289 case DecodedAsRegister: {
277 break; 290 // ADD (register) - ARM section A8.8.7, encoding A1:
278 case DecodedAsRegister: { 291 // add{s}<c> <Rd>, <Rn>, <Rm>{, <shiff>}
279 // ADD (register) - ARM section A8.8.7, encoding A1: 292 // ADD (Sp plus register) - ARM section A8.8.11, encoding A1:
280 // add{s}<c> <Rd>, <Rn>, <Rm>{, <shiff>} 293 // add{s}<c> sp, <Rn>, <Rm>{, <shiff>}
281 // ADD (Sp plus register) - ARM section A8.8.11, encoding A1: 294 //
282 // add{s}<c> sp, <Rn>, <Rm>{, <shiff>} 295 // cccc0000100snnnnddddiiiiitt0mmmm where cccc=Cond, dddd=Rd, nnnn=Rn,
283 // 296 // mmmm=Rm, iiiii=Shift, tt=ShiftKind, and s=SetFlags
284 // cccc0000100snnnnddddiiiiitt0mmmm where cccc=Cond, dddd=Rd, nnnn=Rn, 297 Src1Value = encodeShiftRotateImm5(Src1Value, OperandARM32::kNoShift, 0);
285 // mmmm=Rm, iiiii=Shift, tt=ShiftKind, and s=SetFlags 298 if (((Rd == RegARM32::Encoded_Reg_pc) && SetFlags))
286 Src1Value = encodeShiftRotateImm5(Src1Value, OperandARM32::kNoShift, 0); 299 // Conditions of rule violated.
287 if (((Rd == RegARM32::Encoded_Reg_pc) && SetFlags)) 300 return setNeedsTextFixup();
288 // Conditions of rule violated. 301 emitType01(Cond, kInstTypeDataRegister, Add, SetFlags, Rn, Rd, Src1Value);
289 break; 302 return;
290 constexpr uint32_t InstTypeRegister = 0; 303 }
291 emitType01(Cond, InstTypeRegister, Add, SetFlags, Rn, Rd, Src1Value); 304 case DecodedAsRotatedImm8: {
292 return; 305 // ADD (Immediate) - ARM section A8.8.5, encoding A1:
293 } 306 // add{s}<c> <Rd>, <Rn>, #<RotatedImm8>
294 case DecodedAsRotatedImm8: { 307 // ADD (SP plus immediate) - ARM section A8.8.9, encoding A1.
295 // ADD (Immediate) - ARM section A8.8.5, encoding A1: 308 // add{s}<c> <Rd>, sp, #<RotatedImm8>
296 // add{s}<c> <Rd>, <Rn>, #<RotatedImm8> 309 //
297 // ADD (SP plus immediate) - ARM section A8.8.9, encoding A1. 310 // cccc0010100snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn,
298 // add{s}<c> <Rd>, sp, #<RotatedImm8> 311 // s=SetFlags and iiiiiiiiiiii=Src1Value=RotatedImm8.
299 // 312 if ((Rd == RegARM32::Encoded_Reg_pc && SetFlags))
300 // cccc0010100snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn, 313 // Conditions of rule violated.
301 // s=SetFlags and iiiiiiiiiiii=Src1Value=RotatedImm8. 314 return setNeedsTextFixup();
302 if ((Rd == RegARM32::Encoded_Reg_pc && SetFlags)) 315 emitType01(Cond, kInstTypeDataImmediate, Add, SetFlags, Rn, Rd, Src1Value);
303 // Conditions of rule violated. 316 return;
304 break; 317 }
305 constexpr uint32_t InstTypeImmediate = 1; 318 };
306 emitType01(Cond, InstTypeImmediate, Add, SetFlags, Rn, Rd, Src1Value);
307 return;
308 }
309 }
310 } while (0);
311 UnimplementedError(Ctx->getFlags());
312 } 319 }
313 320
314 void ARM32::AssemblerARM32::bkpt(uint16_t Imm16) { 321 void ARM32::AssemblerARM32::bkpt(uint16_t Imm16) {
315 // BKPT - ARM section A*.8.24 - encoding A1: 322 // BKPT - ARM section A*.8.24 - encoding A1:
316 // bkpt #<Imm16> 323 // bkpt #<Imm16>
317 // 324 //
318 // cccc00010010iiiiiiiiiiii0111iiii where cccc=AL and iiiiiiiiiiiiiiii=Imm16 325 // cccc00010010iiiiiiiiiiii0111iiii where cccc=AL and iiiiiiiiiiiiiiii=Imm16
319 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 326 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
320 const uint32_t Encoding = (CondARM32::AL << kConditionShift) | B24 | B21 | 327 const uint32_t Encoding = (CondARM32::AL << kConditionShift) | B24 | B21 |
321 ((Imm16 >> 4) << 8) | B6 | B5 | B4 | (Imm16 & 0xf); 328 ((Imm16 >> 4) << 8) | B6 | B5 | B4 | (Imm16 & 0xf);
322 emitInst(Encoding); 329 emitInst(Encoding);
323 } 330 }
324 331
325 void ARM32::AssemblerARM32::bx(RegARM32::GPRRegister Rm, CondARM32::Cond Cond) { 332 void ARM32::AssemblerARM32::bx(RegARM32::GPRRegister Rm, CondARM32::Cond Cond) {
326 // BX - ARM section A8.8.27, encoding A1: 333 // BX - ARM section A8.8.27, encoding A1:
327 // bx<c> <Rm> 334 // bx<c> <Rm>
328 // 335 //
329 // cccc000100101111111111110001mmmm where mmmm=rm and cccc=Cond. 336 // cccc000100101111111111110001mmmm where mmmm=rm and cccc=Cond.
330 assert(isGPRRegisterDefined(Rm)); 337 if (!(isGPRRegisterDefined(Rm) && isConditionDefined(Cond)))
331 // TODO(kschimpf): Remove void cast when MINIMAL build allows. 338 return setNeedsTextFixup();
332 (void)isGPRRegisterDefined(Rm);
333 assert(isConditionDefined(Cond));
334 (void)isConditionDefined(Cond);
335 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 339 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
336 const uint32_t Encoding = (encodeCondition(Cond) << kConditionShift) | B24 | 340 const uint32_t Encoding = (encodeCondition(Cond) << kConditionShift) | B24 |
337 B21 | (0xfff << 8) | B4 | 341 B21 | (0xfff << 8) | B4 |
338 (encodeGPRRegister(Rm) << kRmShift); 342 (encodeGPRRegister(Rm) << kRmShift);
339 emitInst(Encoding); 343 emitInst(Encoding);
340 } 344 }
341 345
342 void ARM32::AssemblerARM32::ldr(const Operand *OpRt, const Operand *OpAddress, 346 void ARM32::AssemblerARM32::ldr(const Operand *OpRt, const Operand *OpAddress,
343 CondARM32::Cond Cond) { 347 CondARM32::Cond Cond) {
344 // Note: Loop is used so that we can short ciruit using break; 348 uint32_t Rt;
345 do { 349 if (decodeOperand(OpRt, Rt) != DecodedAsRegister)
346 uint32_t Rt; 350 return setNeedsTextFixup();
347 if (decodeOperand(OpRt, Rt) != DecodedAsRegister) 351 uint32_t Address;
348 break; 352 if (decodeAddress(OpAddress, Address) != DecodedAsImmRegOffset)
349 uint32_t Address; 353 return setNeedsTextFixup();
350 if (decodeAddress(OpAddress, Address) != DecodedAsImmRegOffset) 354 // LDR (immediate) - ARM section A8.8.63, encoding A1:
351 break; 355 // ldr<c> <Rt>, [<Rn>{, #+/-<imm12>}] ; p=1, w=0
352 // LDR (immediate) - ARM section A8.8.63, encoding A1: 356 // ldr<c> <Rt>, [<Rn>], #+/-<imm12> ; p=1, w=1
353 // ldr<c> <Rt>, [<Rn>{, #+/-<imm12>}] ; p=1, w=0 357 // ldr<c> <Rt>, [<Rn>, #+/-<imm12>]! ; p=0, w=1
354 // ldr<c> <Rt>, [<Rn>], #+/-<imm12> ; p=1, w=1 358 // LDRB (immediate) - ARM section A8.8.68, encoding A1:
355 // ldr<c> <Rt>, [<Rn>, #+/-<imm12>]! ; p=0, w=1 359 // ldrb<c> <Rt>, [<Rn>{, #+/-<imm12>}] ; p=1, w=0
356 // LDRB (immediate) - ARM section A8.8.68, encoding A1: 360 // ldrb<c> <Rt>, [<Rn>], #+/-<imm12> ; p=1, w=1
357 // ldrb<c> <Rt>, [<Rn>{, #+/-<imm12>}] ; p=1, w=0 361 // ldrb<c> <Rt>, [<Rn>, #+/-<imm12>]! ; p=0, w=1
358 // ldrb<c> <Rt>, [<Rn>], #+/-<imm12> ; p=1, w=1 362 //
359 // ldrb<c> <Rt>, [<Rn>, #+/-<imm12>]! ; p=0, w=1 363 // cccc010pubw1nnnnttttiiiiiiiiiiii where cccc=Cond, tttt=Rt, nnnn=Rn,
360 // 364 // iiiiiiiiiiii=imm12, b=1 if STRB, u=1 if +.
361 // cccc010pubw1nnnnttttiiiiiiiiiiii where cccc=Cond, tttt=Rt, nnnn=Rn, 365 constexpr bool IsLoad = true;
362 // iiiiiiiiiiii=imm12, b=1 if STRB, u=1 if +. 366 const Type Ty = OpRt->getType();
363 constexpr uint32_t InstType = B1; // 010 367 if (!(Ty == IceType_i32 || Ty == IceType_i8)) // TODO(kschimpf) Expand?
364 constexpr bool IsLoad = true; 368 return setNeedsTextFixup();
365 const Type Ty = OpRt->getType(); 369 const bool IsByte = typeWidthInBytes(Ty) == 1;
366 if (!(Ty == IceType_i32 || Ty == IceType_i8)) // TODO(kschimpf) Expand? 370 // Check conditions of rules violated.
367 break; 371 if (getGPRReg(kRnShift, Address) == RegARM32::Encoded_Reg_pc)
368 const bool IsByte = typeWidthInBytes(Ty) == 1; 372 return setNeedsTextFixup();
369 if ((getGPRReg(kRnShift, Address) == RegARM32::Encoded_Reg_pc) || 373 if (!isBitSet(P, Address) && isBitSet(W, Address))
370 (!isBitSet(P, Address) && isBitSet(W, Address)) || 374 return setNeedsTextFixup();
371 (!IsByte && 375 if (!IsByte && (getGPRReg(kRnShift, Address) == RegARM32::Encoded_Reg_sp) &&
372 (getGPRReg(kRnShift, Address) == RegARM32::Encoded_Reg_sp) && 376 !isBitSet(P, Address) && isBitSet(U, Address) & !isBitSet(W, Address) &&
373 !isBitSet(P, Address) && 377 (mask(Address, kImm12Shift, kImmed12Bits) == 0x8 /* 000000000100 */))
374 isBitSet(U, Address) & !isBitSet(W, Address) && 378 return setNeedsTextFixup();
375 (mask(Address, kImm12Shift, kImmed12Bits) == 0x8 /* 000000000100 */))) 379 emitMemOp(Cond, kInstTypeMemImmediate, IsLoad, IsByte, Rt, Address);
376 break;
377 emitMemOp(Cond, InstType, IsLoad, IsByte, Rt, Address);
378 return;
379 } while (0);
380 UnimplementedError(Ctx->getFlags());
381 } 380 }
382 381
383 void ARM32::AssemblerARM32::mov(const Operand *OpRd, const Operand *OpSrc, 382 void ARM32::AssemblerARM32::mov(const Operand *OpRd, const Operand *OpSrc,
384 CondARM32::Cond Cond) { 383 CondARM32::Cond Cond) {
385 // Note: Loop is used so that we can short ciruit using break; 384 uint32_t Rd;
386 do { 385 if (decodeOperand(OpRd, Rd) != DecodedAsRegister)
387 uint32_t Rd; 386 return setNeedsTextFixup();
388 if (decodeOperand(OpRd, Rd) != DecodedAsRegister) 387 uint32_t Src;
389 break; 388 // TODO(kschimpf) Handle other forms of mov.
390 uint32_t Src; 389 if (decodeOperand(OpSrc, Src) != DecodedAsRotatedImm8)
391 // TODO(kschimpf) Handle other forms of mov. 390 return setNeedsTextFixup();
392 if (decodeOperand(OpSrc, Src) == DecodedAsRotatedImm8) { 391 // MOV (immediate) - ARM section A8.8.102, encoding A1:
393 // MOV (immediate) - ARM section A8.8.102, encoding A1: 392 // mov{S}<c> <Rd>, #<RotatedImm8>
394 // mov{S}<c> <Rd>, #<RotatedImm8> 393 //
395 // 394 // cccc0011101s0000ddddiiiiiiiiiiii where cccc=Cond, s=SetFlags, dddd=Rd,
396 // cccc0011101s0000ddddiiiiiiiiiiii where cccc=Cond, s=SetFlags, dddd=Rd, 395 // and iiiiiiiiiiii=RotatedImm8=Src. Note: We don't use movs in this
397 // and iiiiiiiiiiii=RotatedImm8=Src. Note: We don't use movs in this 396 // assembler.
398 // assembler. 397 constexpr bool SetFlags = false;
399 constexpr bool SetFlags = false; 398 if ((Rd == RegARM32::Encoded_Reg_pc && SetFlags))
400 if ((Rd == RegARM32::Encoded_Reg_pc && SetFlags)) 399 // Conditions of rule violated.
401 // Conditions of rule violated. 400 return setNeedsTextFixup();
402 break; 401 constexpr uint32_t Rn = 0;
403 constexpr uint32_t Rn = 0; 402 constexpr uint32_t Mov = B3 | B2 | B0; // 1101.
404 constexpr uint32_t Mov = B3 | B2 | B0; // 1101. 403 emitType01(Cond, kInstTypeDataImmediate, Mov, SetFlags, Rn, Rd, Src);
405 constexpr uint32_t InstType = 1;
406 emitType01(Cond, InstType, Mov, SetFlags, Rn, Rd, Src);
407 return;
408 }
409 } while (0);
410 UnimplementedError(Ctx->getFlags());
411 } 404 }
412 405
413 void ARM32::AssemblerARM32::str(const Operand *OpRt, const Operand *OpAddress, 406 void ARM32::AssemblerARM32::str(const Operand *OpRt, const Operand *OpAddress,
414 CondARM32::Cond Cond) { 407 CondARM32::Cond Cond) {
415 // Note: Loop is used so that we can short ciruit using break; 408 uint32_t Rt;
416 do { 409 if (decodeOperand(OpRt, Rt) != DecodedAsRegister)
417 uint32_t Rt; 410 return setNeedsTextFixup();
418 if (decodeOperand(OpRt, Rt) != DecodedAsRegister) 411 uint32_t Address;
419 break; 412 if (decodeAddress(OpAddress, Address) != DecodedAsImmRegOffset)
420 uint32_t Address; 413 return setNeedsTextFixup();
421 if (decodeAddress(OpAddress, Address) != DecodedAsImmRegOffset) 414 // STR (immediate) - ARM section A8.8.204, encoding A1:
422 break; 415 // str<c> <Rt>, [<Rn>{, #+/-<imm12>}] ; p=1, w=0
423 // STR (immediate) - ARM section A8.8.204, encoding A1: 416 // str<c> <Rt>, [<Rn>], #+/-<imm12> ; p=1, w=1
424 // str<c> <Rt>, [<Rn>{, #+/-<imm12>}] ; p=1, w=0 417 // str<c> <Rt>, [<Rn>, #+/-<imm12>]! ; p=0, w=1
425 // str<c> <Rt>, [<Rn>], #+/-<imm12> ; p=1, w=1 418 // STRB (immediate) - ARM section A8.8.207, encoding A1:
426 // str<c> <Rt>, [<Rn>, #+/-<imm12>]! ; p=0, w=1 419 // strb<c> <Rt>, [<Rn>{, #+/-<imm12>}] ; p=1, w=0
427 // STRB (immediate) - ARM section A8.8.207, encoding A1: 420 // strb<c> <Rt>, [<Rn>], #+/-<imm12> ; p=1, w=1
428 // strb<c> <Rt>, [<Rn>{, #+/-<imm12>}] ; p=1, w=0 421 // strb<c> <Rt>, [<Rn>, #+/-<imm12>]! ; p=0, w=1
429 // strb<c> <Rt>, [<Rn>], #+/-<imm12> ; p=1, w=1 422 //
430 // strb<c> <Rt>, [<Rn>, #+/-<imm12>]! ; p=0, w=1 423 // cccc010pubw0nnnnttttiiiiiiiiiiii where cccc=Cond, tttt=Rt, nnnn=Rn,
431 // 424 // iiiiiiiiiiii=imm12, b=1 if STRB, u=1 if +.
432 // cccc010pubw0nnnnttttiiiiiiiiiiii where cccc=Cond, tttt=Rt, nnnn=Rn, 425 constexpr bool IsLoad = false;
433 // iiiiiiiiiiii=imm12, b=1 if STRB, u=1 if +. 426 const Type Ty = OpRt->getType();
434 constexpr uint32_t InstType = B1; // 010 427 if (!(Ty == IceType_i32 || Ty == IceType_i8)) // TODO(kschimpf) Expand?
435 constexpr bool IsLoad = false; 428 return setNeedsTextFixup();
436 const Type Ty = OpRt->getType(); 429 const bool IsByte = typeWidthInBytes(Ty) == 1;
437 if (!(Ty == IceType_i32 || Ty == IceType_i8)) // TODO(kschimpf) Expand? 430 // Check for rule violations.
438 break; 431 if ((getGPRReg(kRnShift, Address) == RegARM32::Encoded_Reg_pc))
439 const bool IsByte = typeWidthInBytes(Ty) == 1; 432 return setNeedsTextFixup();
440 // Check for rule violations. 433 if (!isBitSet(P, Address) && isBitSet(W, Address))
441 if ((getGPRReg(kRnShift, Address) == RegARM32::Encoded_Reg_pc) || 434 return setNeedsTextFixup();
442 (!isBitSet(P, Address) && isBitSet(W, Address)) || 435 if (!IsByte && (getGPRReg(kRnShift, Address) == RegARM32::Encoded_Reg_sp) &&
443 (!IsByte && 436 isBitSet(P, Address) && !isBitSet(U, Address) && isBitSet(W, Address) &&
444 (getGPRReg(kRnShift, Address) == RegARM32::Encoded_Reg_sp) && 437 (mask(Address, kImm12Shift, kImmed12Bits) == 0x8 /* 000000000100 */))
445 isBitSet(P, Address) && !isBitSet(U, Address) && 438 return setNeedsTextFixup();
446 isBitSet(W, Address) && 439 emitMemOp(Cond, kInstTypeMemImmediate, IsLoad, IsByte, Rt, Address);
447 (mask(Address, kImm12Shift, kImmed12Bits) == 0x8 /* 000000000100 */)))
448 // Conditions of rule violated.
449 break;
450 emitMemOp(Cond, InstType, IsLoad, IsByte, Rt, Address);
451 return;
452 } while (0);
453 UnimplementedError(Ctx->getFlags());
454 } 440 }
455 441
456 void ARM32::AssemblerARM32::sub(const Operand *OpRd, const Operand *OpRn, 442 void ARM32::AssemblerARM32::sub(const Operand *OpRd, const Operand *OpRn,
457 const Operand *OpSrc1, bool SetFlags, 443 const Operand *OpSrc1, bool SetFlags,
458 CondARM32::Cond Cond) { 444 CondARM32::Cond Cond) {
459 // Note: Loop is used so that we can short circuit using break; 445 uint32_t Rd;
460 do { 446 if (decodeOperand(OpRd, Rd) != DecodedAsRegister)
461 uint32_t Rd; 447 return setNeedsTextFixup();
462 if (decodeOperand(OpRd, Rd) != DecodedAsRegister) 448 uint32_t Rn;
463 break; 449 if (decodeOperand(OpRn, Rn) != DecodedAsRegister)
464 uint32_t Rn; 450 return setNeedsTextFixup();
465 if (decodeOperand(OpRn, Rn) != DecodedAsRegister) 451 constexpr uint32_t Sub = B1; // 0010
466 break; 452 uint32_t Src1Value;
467 constexpr uint32_t Sub = B1; // 0010 453 // TODO(kschimpf) Other possible decodings of sub.
468 uint32_t Src1Value; 454 switch (decodeOperand(OpSrc1, Src1Value)) {
469 // TODO(kschimpf) Other possible decodings of sub. 455 default:
470 switch (decodeOperand(OpSrc1, Src1Value)) { 456 return setNeedsTextFixup();
471 default: 457 case DecodedAsRegister: {
472 break; 458 // SUB (register) - ARM section A8.8.223, encoding A1:
473 case DecodedAsRegister: { 459 // sub{s}<c> <Rd>, <Rn>, <Rm>{, <shift>}
474 // SUB (register) - ARM section A8.8.223, encoding A1: 460 // SUB (SP minus register): See ARM section 8.8.226, encoding A1:
475 // sub{s}<c> <Rd>, <Rn>, <Rm>{, <shift>} 461 // sub{s}<c> <Rd>, sp, <Rm>{, <Shift>}
476 // SUB (SP minus register): See ARM section 8.8.226, encoding A1: 462 //
477 // sub{s}<c> <Rd>, sp, <Rm>{, <Shift>} 463 // cccc0000010snnnnddddiiiiitt0mmmm where cccc=Cond, dddd=Rd, nnnn=Rn,
478 // 464 // mmmm=Rm, iiiiii=shift, tt=ShiftKind, and s=SetFlags.
479 // cccc0000010snnnnddddiiiiitt0mmmm where cccc=Cond, dddd=Rd, nnnn=Rn, 465 Src1Value = encodeShiftRotateImm5(Src1Value, OperandARM32::kNoShift, 0);
480 // mmmm=Rm, iiiiii=shift, tt=ShiftKind, and s=SetFlags. 466 if (((Rd == RegARM32::Encoded_Reg_pc) && SetFlags))
481 Src1Value = encodeShiftRotateImm5(Src1Value, OperandARM32::kNoShift, 0); 467 // Conditions of rule violated.
482 constexpr uint32_t InstType = 0; // i.e. register 468 return setNeedsTextFixup();
483 if (((Rd == RegARM32::Encoded_Reg_pc) && SetFlags)) 469 emitType01(Cond, kInstTypeDataRegister, Sub, SetFlags, Rn, Rd, Src1Value);
484 // Conditions of rule violated. 470 return;
485 break; 471 }
486 emitType01(Cond, InstType, Sub, SetFlags, Rn, Rd, Src1Value); 472 case DecodedAsRotatedImm8: {
487 return; 473 // Sub (Immediate) - ARM section A8.8.222, encoding A1:
488 } 474 // sub{s}<c> <Rd>, <Rn>, #<RotatedImm8>
489 case DecodedAsRotatedImm8: { 475 // Sub (Sp minus immediate) - ARM section A8.*.225, encoding A1:
490 // Sub (Immediate) - ARM section A8.8.222, encoding A1: 476 // sub{s}<c> sp, <Rn>, #<RotatedImm8>
491 // sub{s}<c> <Rd>, <Rn>, #<RotatedImm8> 477 //
492 // Sub (Sp minus immediate) - ARM section A8.*.225, encoding A1: 478 // cccc0010010snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn,
493 // sub{s}<c> sp, <Rn>, #<RotatedImm8> 479 // s=SetFlags and iiiiiiiiiiii=Src1Value=RotatedImm8
494 // 480 if (Rd == RegARM32::Encoded_Reg_pc)
495 // cccc0010010snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn, 481 // Conditions of rule violated.
496 // s=SetFlags and iiiiiiiiiiii=Src1Value=RotatedImm8 482 return setNeedsTextFixup();
497 if (Rd == RegARM32::Encoded_Reg_pc) 483 emitType01(Cond, kInstTypeDataImmediate, Sub, SetFlags, Rn, Rd, Src1Value);
498 // Conditions of rule violated. 484 return;
499 break; 485 }
500 constexpr uint32_t InstType = 1; 486 }
501 emitType01(Cond, InstType, Sub, SetFlags, Rn, Rd, Src1Value);
502 return;
503 }
504 }
505 } while (0);
506 UnimplementedError(Ctx->getFlags());
507 } 487 }
508 488
509 } // end of namespace Ice 489 } // end of namespace Ice
OLDNEW
« no previous file with comments | « src/IceAssemblerARM32.h ('k') | src/IceAssemblerX86Base.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698