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

Side by Side Diff: src/IceAssemblerARM32.cpp

Issue 1456783003: Add LSL (register, immediate) to ARM integrated assembler. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Fix more nits. Created 5 years, 1 month 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 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
93 // Rotation instructions (uxtb etc.). 93 // Rotation instructions (uxtb etc.).
94 static constexpr IValueT kRotationShift = 10; 94 static constexpr IValueT kRotationShift = 10;
95 95
96 // Div instruction register field encodings. 96 // Div instruction register field encodings.
97 static constexpr IValueT kDivRdShift = 16; 97 static constexpr IValueT kDivRdShift = 16;
98 static constexpr IValueT kDivRmShift = 8; 98 static constexpr IValueT kDivRmShift = 8;
99 static constexpr IValueT kDivRnShift = 0; 99 static constexpr IValueT kDivRnShift = 0;
100 100
101 // Type of instruction encoding (bits 25-27). See ARM section A5.1 101 // Type of instruction encoding (bits 25-27). See ARM section A5.1
102 static constexpr IValueT kInstTypeDataRegister = 0; // i.e. 000 102 static constexpr IValueT kInstTypeDataRegister = 0; // i.e. 000
103 static constexpr IValueT kInstTypeDataRegShift = 0; // i.e. 000
103 static constexpr IValueT kInstTypeDataImmediate = 1; // i.e. 001 104 static constexpr IValueT kInstTypeDataImmediate = 1; // i.e. 001
104 static constexpr IValueT kInstTypeMemImmediate = 2; // i.e. 010 105 static constexpr IValueT kInstTypeMemImmediate = 2; // i.e. 010
105 static constexpr IValueT kInstTypeRegisterShift = 3; // i.e. 011 106 static constexpr IValueT kInstTypeRegisterShift = 3; // i.e. 011
106 107
107 // Offset modifier to current PC for next instruction. The offset is off by 8 108 // Offset modifier to current PC for next instruction. The offset is off by 8
108 // due to the way the ARM CPUs read PC. 109 // due to the way the ARM CPUs read PC.
109 static constexpr IOffsetT kPCReadOffset = 8; 110 static constexpr IOffsetT kPCReadOffset = 8;
110 111
111 // Mask to pull out PC offset from branch (b) instruction. 112 // Mask to pull out PC offset from branch (b) instruction.
112 static constexpr int kBranchOffsetBits = 24; 113 static constexpr int kBranchOffsetBits = 24;
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
188 DecodedAsRotatedImm8, 189 DecodedAsRotatedImm8,
189 // i.e. 0000000pu0w0nnnn0000iiiiiiiiiiii where nnnn is the base register Rn, 190 // i.e. 0000000pu0w0nnnn0000iiiiiiiiiiii where nnnn is the base register Rn,
190 // p=1 if pre-indexed addressing, u=1 if offset positive, w=1 if writeback to 191 // p=1 if pre-indexed addressing, u=1 if offset positive, w=1 if writeback to
191 // Rn should be used, and iiiiiiiiiiii defines the rotated Imm8 value. 192 // Rn should be used, and iiiiiiiiiiii defines the rotated Imm8 value.
192 DecodedAsImmRegOffset, 193 DecodedAsImmRegOffset,
193 // i.e. 0000000pu0w00nnnnttttiiiiiss0mmmm where nnnn is the base register Rn, 194 // i.e. 0000000pu0w00nnnnttttiiiiiss0mmmm where nnnn is the base register Rn,
194 // mmmm is the index register Rm, iiiii is the shift amount, ss is the shift 195 // mmmm is the index register Rm, iiiii is the shift amount, ss is the shift
195 // kind, p=1 if pre-indexed addressing, u=1 if offset positive, and w=1 if 196 // kind, p=1 if pre-indexed addressing, u=1 if offset positive, and w=1 if
196 // writeback to Rn. 197 // writeback to Rn.
197 DecodedAsShiftRotateImm5, 198 DecodedAsShiftRotateImm5,
199 // i.e. 000000000000000000000iiiii0000000 iiii defines Imm5 value to shift.
200 DecodedAsShiftImm5,
198 // Value is 32bit integer constant. 201 // Value is 32bit integer constant.
199 DecodedAsConstI32 202 DecodedAsConstI32
200 }; 203 };
201 204
202 // Sets Encoding to a rotated Imm8 encoding of Value, if possible. 205 // Sets Encoding to a rotated Imm8 encoding of Value, if possible.
203 inline IValueT encodeRotatedImm8(IValueT RotateAmt, IValueT Immed8) { 206 inline IValueT encodeRotatedImm8(IValueT RotateAmt, IValueT Immed8) {
204 assert(RotateAmt < (1 << kRotateBits)); 207 assert(RotateAmt < (1 << kRotateBits));
205 assert(Immed8 < (1 << kImmed8Bits)); 208 assert(Immed8 < (1 << kImmed8Bits));
206 return (RotateAmt << kRotateShift) | (Immed8 << kImmed8Shift); 209 return (RotateAmt << kRotateShift) | (Immed8 << kImmed8Shift);
207 } 210 }
208 211
209 // Encodes iiiiitt0mmmm for data-processing (2nd) operands where iiiii=Imm5, 212 // Encodes iiiiitt0mmmm for data-processing (2nd) operands where iiiii=Imm5,
210 // tt=Shift, and mmmm=Rm. 213 // tt=Shift, and mmmm=Rm.
211 IValueT encodeShiftRotateImm5(IValueT Rm, OperandARM32::ShiftKind Shift, 214 IValueT encodeShiftRotateImm5(IValueT Rm, OperandARM32::ShiftKind Shift,
212 IOffsetT imm5) { 215 IOffsetT imm5) {
213 (void)kShiftImmBits; 216 (void)kShiftImmBits;
214 assert(imm5 < (1 << kShiftImmBits)); 217 assert(imm5 < (1 << kShiftImmBits));
215 return (imm5 << kShiftImmShift) | (encodeShift(Shift) << kShiftShift) | Rm; 218 return (imm5 << kShiftImmShift) | (encodeShift(Shift) << kShiftShift) | Rm;
216 } 219 }
217 220
221 // Encodes mmmmtt01ssss for data-processing (2nd) operands where mmmm=Rm,
222 // ssss=Rs, and tt=Shift.
223 IValueT encodeShiftRotateReg(IValueT Rm, OperandARM32::ShiftKind Shift,
224 IValueT Rs) {
225 return (Rs << kRsShift) | (encodeShift(Shift) << kShiftShift) | B4 |
226 (Rm << kRmShift);
227 }
228
218 DecodedResult decodeOperand(const Operand *Opnd, IValueT &Value) { 229 DecodedResult decodeOperand(const Operand *Opnd, IValueT &Value) {
219 if (const auto *Var = llvm::dyn_cast<Variable>(Opnd)) { 230 if (const auto *Var = llvm::dyn_cast<Variable>(Opnd)) {
220 if (Var->hasReg()) { 231 if (Var->hasReg()) {
221 Value = Var->getRegNum(); 232 Value = Var->getRegNum();
222 return DecodedAsRegister; 233 return DecodedAsRegister;
223 } 234 }
224 } else if (const auto *FlexImm = llvm::dyn_cast<OperandARM32FlexImm>(Opnd)) { 235 return CantDecode;
236 }
237 if (const auto *FlexImm = llvm::dyn_cast<OperandARM32FlexImm>(Opnd)) {
225 const IValueT Immed8 = FlexImm->getImm(); 238 const IValueT Immed8 = FlexImm->getImm();
226 const IValueT Rotate = FlexImm->getRotateAmt(); 239 const IValueT Rotate = FlexImm->getRotateAmt();
227 if (!((Rotate < (1 << kRotateBits)) && (Immed8 < (1 << kImmed8Bits)))) 240 if (!((Rotate < (1 << kRotateBits)) && (Immed8 < (1 << kImmed8Bits))))
228 return CantDecode; 241 return CantDecode;
229 Value = (Rotate << kRotateShift) | (Immed8 << kImmed8Shift); 242 Value = (Rotate << kRotateShift) | (Immed8 << kImmed8Shift);
230 return DecodedAsRotatedImm8; 243 return DecodedAsRotatedImm8;
231 } 244 }
232 if (const auto *Const = llvm::dyn_cast<ConstantInteger32>(Opnd)) { 245 if (const auto *Const = llvm::dyn_cast<ConstantInteger32>(Opnd)) {
233 Value = Const->getValue(); 246 Value = Const->getValue();
234 return DecodedAsConstI32; 247 return DecodedAsConstI32;
235 } 248 }
249 if (const auto *ShImm = llvm::dyn_cast<OperandARM32ShAmtImm>(Opnd)) {
250 const IValueT Immed5 = ShImm->getShAmtImm();
251 assert(Immed5 < (1 << kShiftImmBits));
252 Value = (Immed5 << kShiftImmShift);
253 return DecodedAsShiftImm5;
254 }
236 return CantDecode; 255 return CantDecode;
237 } 256 }
238 257
239 IValueT decodeImmRegOffset(RegARM32::GPRRegister Reg, IOffsetT Offset, 258 IValueT decodeImmRegOffset(RegARM32::GPRRegister Reg, IOffsetT Offset,
240 OperandARM32Mem::AddrMode Mode) { 259 OperandARM32Mem::AddrMode Mode) {
241 IValueT Value = Mode | (encodeGPRRegister(Reg) << kRnShift); 260 IValueT Value = Mode | (encodeGPRRegister(Reg) << kRnShift);
242 if (Offset < 0) { 261 if (Offset < 0) {
243 Value = (Value ^ U) | -Offset; // Flip U to adjust sign. 262 Value = (Value ^ U) | -Offset; // Flip U to adjust sign.
244 } else { 263 } else {
245 Value |= Offset; 264 Value |= Offset;
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after
416 void AssemblerARM32::emitTextInst(const std::string &Text, SizeT InstSize) { 435 void AssemblerARM32::emitTextInst(const std::string &Text, SizeT InstSize) {
417 AssemblerFixup *F = createTextFixup(Text, InstSize); 436 AssemblerFixup *F = createTextFixup(Text, InstSize);
418 emitFixup(F); 437 emitFixup(F);
419 for (SizeT I = 0; I < InstSize; ++I) { 438 for (SizeT I = 0; I < InstSize; ++I) {
420 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 439 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
421 Buffer.emit<char>(0); 440 Buffer.emit<char>(0);
422 } 441 }
423 } 442 }
424 443
425 void AssemblerARM32::emitType01(CondARM32::Cond Cond, IValueT Type, 444 void AssemblerARM32::emitType01(CondARM32::Cond Cond, IValueT Type,
426 IValueT Opcode, bool SetCc, IValueT Rn, 445 IValueT Opcode, bool SetFlags, IValueT Rn,
427 IValueT Rd, IValueT Imm12) { 446 IValueT Rd, IValueT Imm12,
447 EmitChecks RuleChecks) {
448 switch (RuleChecks) {
449 case NoChecks:
450 break;
451 case RdIsPcAndSetFlags:
452 if (((Rd == RegARM32::Encoded_Reg_pc) && SetFlags))
Jim Stichnoth 2015/11/22 03:58:47 Maybe strip one level of parens?
Karl 2015/11/30 16:53:52 Done.
453 // Conditions of rule violated.
454 return setNeedsTextFixup();
455 break;
456 }
457
428 if (!isGPRRegisterDefined(Rd) || !isConditionDefined(Cond)) 458 if (!isGPRRegisterDefined(Rd) || !isConditionDefined(Cond))
429 return setNeedsTextFixup(); 459 return setNeedsTextFixup();
430 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 460 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
431 const IValueT Encoding = (encodeCondition(Cond) << kConditionShift) | 461 const IValueT Encoding = (encodeCondition(Cond) << kConditionShift) |
432 (Type << kTypeShift) | (Opcode << kOpcodeShift) | 462 (Type << kTypeShift) | (Opcode << kOpcodeShift) |
433 (encodeBool(SetCc) << kSShift) | (Rn << kRnShift) | 463 (encodeBool(SetFlags) << kSShift) |
434 (Rd << kRdShift) | Imm12; 464 (Rn << kRnShift) | (Rd << kRdShift) | Imm12;
435 emitInst(Encoding); 465 emitInst(Encoding);
436 } 466 }
437 467
438 void AssemblerARM32::emitType01(IValueT Opcode, const Operand *OpRd, 468 void AssemblerARM32::emitType01(IValueT Opcode, const Operand *OpRd,
439 const Operand *OpRn, const Operand *OpSrc1, 469 const Operand *OpRn, const Operand *OpSrc1,
440 bool SetFlags, CondARM32::Cond Cond, 470 bool SetFlags, CondARM32::Cond Cond,
441 Type01Checks RuleChecks) { 471 EmitChecks RuleChecks) {
442 IValueT Rd; 472 IValueT Rd;
443 if (decodeOperand(OpRd, Rd) != DecodedAsRegister) 473 if (decodeOperand(OpRd, Rd) != DecodedAsRegister)
444 return setNeedsTextFixup(); 474 return setNeedsTextFixup();
445 IValueT Rn; 475 IValueT Rn;
446 if (decodeOperand(OpRn, Rn) != DecodedAsRegister) 476 if (decodeOperand(OpRn, Rn) != DecodedAsRegister)
447 return setNeedsTextFixup(); 477 return setNeedsTextFixup();
448 emitType01(Opcode, Rd, Rn, OpSrc1, SetFlags, Cond, RuleChecks); 478 emitType01(Opcode, Rd, Rn, OpSrc1, SetFlags, Cond, RuleChecks);
449 } 479 }
450 480
451 void AssemblerARM32::emitType01(IValueT Opcode, IValueT Rd, IValueT Rn, 481 void AssemblerARM32::emitType01(IValueT Opcode, IValueT Rd, IValueT Rn,
452 const Operand *OpSrc1, bool SetFlags, 482 const Operand *OpSrc1, bool SetFlags,
453 CondARM32::Cond Cond, Type01Checks RuleChecks) { 483 CondARM32::Cond Cond, EmitChecks RuleChecks) {
454 switch (RuleChecks) { 484 switch (RuleChecks) {
455 case NoChecks: 485 case NoChecks:
456 break; 486 break;
457 case RdIsPcAndSetFlags: 487 case RdIsPcAndSetFlags:
458 if (((Rd == RegARM32::Encoded_Reg_pc) && SetFlags)) 488 if (((Rd == RegARM32::Encoded_Reg_pc) && SetFlags))
459 // Conditions of rule violated. 489 // Conditions of rule violated.
460 return setNeedsTextFixup(); 490 return setNeedsTextFixup();
461 break; 491 break;
462 } 492 }
463 493
464 IValueT Src1Value; 494 IValueT Src1Value;
465 // TODO(kschimpf) Other possible decodings of data operations. 495 // TODO(kschimpf) Other possible decodings of data operations.
466 switch (decodeOperand(OpSrc1, Src1Value)) { 496 switch (decodeOperand(OpSrc1, Src1Value)) {
467 default: 497 default:
468 return setNeedsTextFixup(); 498 return setNeedsTextFixup();
469 case DecodedAsRegister: { 499 case DecodedAsRegister: {
470 // XXX (register) 500 // XXX (register)
471 // xxx{s}<c> <Rd>, <Rn>, <Rm>{, <shiff>} 501 // xxx{s}<c> <Rd>, <Rn>, <Rm>{, <shiff>}
472 // 502 //
473 // cccc0000100snnnnddddiiiiitt0mmmm where cccc=Cond, dddd=Rd, nnnn=Rn, 503 // cccc0000100snnnnddddiiiiitt0mmmm where cccc=Cond, dddd=Rd, nnnn=Rn,
474 // mmmm=Rm, iiiii=Shift, tt=ShiftKind, and s=SetFlags. 504 // mmmm=Rm, iiiii=Shift, tt=ShiftKind, and s=SetFlags.
475 constexpr IValueT Imm5 = 0; 505 constexpr IValueT Imm5 = 0;
476 Src1Value = encodeShiftRotateImm5(Src1Value, OperandARM32::kNoShift, Imm5); 506 Src1Value = encodeShiftRotateImm5(Src1Value, OperandARM32::kNoShift, Imm5);
477 emitType01(Cond, kInstTypeDataRegister, Opcode, SetFlags, Rn, Rd, 507 emitType01(Cond, kInstTypeDataRegister, Opcode, SetFlags, Rn, Rd, Src1Value,
478 Src1Value); 508 RuleChecks);
479 return; 509 return;
480 } 510 }
481 case DecodedAsConstI32: { 511 case DecodedAsConstI32: {
482 // See if we can convert this to an XXX (immediate). 512 // See if we can convert this to an XXX (immediate).
483 IValueT RotateAmt; 513 IValueT RotateAmt;
484 IValueT Imm8; 514 IValueT Imm8;
485 if (!OperandARM32FlexImm::canHoldImm(Src1Value, &RotateAmt, &Imm8)) 515 if (!OperandARM32FlexImm::canHoldImm(Src1Value, &RotateAmt, &Imm8))
486 return setNeedsTextFixup(); 516 return setNeedsTextFixup();
487 Src1Value = encodeRotatedImm8(RotateAmt, Imm8); 517 Src1Value = encodeRotatedImm8(RotateAmt, Imm8);
488 // Intentionally fall to next case! 518 // Intentionally fall to next case!
489 } 519 }
490 case DecodedAsRotatedImm8: { 520 case DecodedAsRotatedImm8: {
491 // XXX (Immediate) 521 // XXX (Immediate)
492 // xxx{s}<c> <Rd>, <Rn>, #<RotatedImm8> 522 // xxx{s}<c> <Rd>, <Rn>, #<RotatedImm8>
493 // 523 //
494 // cccc0010100snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn, 524 // cccc0010100snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn,
495 // s=SetFlags and iiiiiiiiiiii=Src1Value defining RotatedImm8. 525 // s=SetFlags and iiiiiiiiiiii=Src1Value defining RotatedImm8.
496 emitType01(Cond, kInstTypeDataImmediate, Opcode, SetFlags, Rn, Rd, 526 emitType01(Cond, kInstTypeDataImmediate, Opcode, SetFlags, Rn, Rd,
497 Src1Value); 527 Src1Value, RuleChecks);
498 return; 528 return;
499 } 529 }
500 } 530 }
501 } 531 }
502 532
503 void AssemblerARM32::emitType05(CondARM32::Cond Cond, IOffsetT Offset, 533 void AssemblerARM32::emitType05(CondARM32::Cond Cond, IOffsetT Offset,
504 bool Link) { 534 bool Link) {
505 // cccc101liiiiiiiiiiiiiiiiiiiiiiii where cccc=Cond, l=Link, and 535 // cccc101liiiiiiiiiiiiiiiiiiiiiiii where cccc=Cond, l=Link, and
506 // iiiiiiiiiiiiiiiiiiiiiiii= 536 // iiiiiiiiiiiiiiiiiiiiiiii=
507 // EncodedBranchOffset(cccc101l000000000000000000000000, Offset); 537 // EncodedBranchOffset(cccc101l000000000000000000000000, Offset);
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
570 return setNeedsTextFixup(); 600 return setNeedsTextFixup();
571 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 601 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
572 const IValueT Encoding = Opcode | (encodeCondition(Cond) << kConditionShift) | 602 const IValueT Encoding = Opcode | (encodeCondition(Cond) << kConditionShift) |
573 (Rn << kDivRnShift) | (Rd << kDivRdShift) | B26 | 603 (Rn << kDivRnShift) | (Rd << kDivRdShift) | B26 |
574 B25 | B24 | B20 | B15 | B14 | B13 | B12 | B4 | 604 B25 | B24 | B20 | B15 | B14 | B13 | B12 | B4 |
575 (Rm << kDivRmShift); 605 (Rm << kDivRmShift);
576 emitInst(Encoding); 606 emitInst(Encoding);
577 } 607 }
578 608
579 void AssemblerARM32::emitMulOp(CondARM32::Cond Cond, IValueT Opcode, IValueT Rd, 609 void AssemblerARM32::emitMulOp(CondARM32::Cond Cond, IValueT Opcode, IValueT Rd,
580 IValueT Rn, IValueT Rm, IValueT Rs, bool SetCc) { 610 IValueT Rn, IValueT Rm, IValueT Rs,
611 bool SetFlags) {
581 if (!isGPRRegisterDefined(Rd) || !isGPRRegisterDefined(Rn) || 612 if (!isGPRRegisterDefined(Rd) || !isGPRRegisterDefined(Rn) ||
582 !isGPRRegisterDefined(Rm) || !isGPRRegisterDefined(Rs) || 613 !isGPRRegisterDefined(Rm) || !isGPRRegisterDefined(Rs) ||
583 !isConditionDefined(Cond)) 614 !isConditionDefined(Cond))
584 return setNeedsTextFixup(); 615 return setNeedsTextFixup();
585 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 616 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
586 IValueT Encoding = Opcode | (encodeCondition(Cond) << kConditionShift) | 617 IValueT Encoding = Opcode | (encodeCondition(Cond) << kConditionShift) |
587 (encodeBool(SetCc) << kSShift) | (Rn << kRnShift) | 618 (encodeBool(SetFlags) << kSShift) | (Rn << kRnShift) |
588 (Rd << kRdShift) | (Rs << kRsShift) | B7 | B4 | 619 (Rd << kRdShift) | (Rs << kRsShift) | B7 | B4 |
589 (Rm << kRmShift); 620 (Rm << kRmShift);
590 emitInst(Encoding); 621 emitInst(Encoding);
591 } 622 }
592 623
593 void AssemblerARM32::emitUxt(CondARM32::Cond Cond, IValueT Opcode, IValueT Rd, 624 void AssemblerARM32::emitUxt(CondARM32::Cond Cond, IValueT Opcode, IValueT Rd,
594 IValueT Rn, IValueT Rm, RotationValue Rotation) { 625 IValueT Rn, IValueT Rm, RotationValue Rotation) {
595 IValueT Rot = encodeRotation(Rotation); 626 IValueT Rot = encodeRotation(Rotation);
596 if (!isConditionDefined(Cond) || !Utils::IsUint(2, Rot)) 627 if (!isConditionDefined(Cond) || !Utils::IsUint(2, Rot))
597 return setNeedsTextFixup(); 628 return setNeedsTextFixup();
(...skipping 26 matching lines...) Expand all
624 // 655 //
625 // cccc0000101snnnnddddiiiiitt0mmmm where cccc=Cond, dddd=Rd, nnnn=Rn, 656 // cccc0000101snnnnddddiiiiitt0mmmm where cccc=Cond, dddd=Rd, nnnn=Rn,
626 // mmmm=Rm, iiiii=Shift, tt=ShiftKind, and s=SetFlags. 657 // mmmm=Rm, iiiii=Shift, tt=ShiftKind, and s=SetFlags.
627 // 658 //
628 // ADC (Immediate) - ARM section A8.8.1, encoding A1: 659 // ADC (Immediate) - ARM section A8.8.1, encoding A1:
629 // adc{s}<c> <Rd>, <Rn>, #<RotatedImm8> 660 // adc{s}<c> <Rd>, <Rn>, #<RotatedImm8>
630 // 661 //
631 // cccc0010101snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn, 662 // cccc0010101snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn,
632 // s=SetFlags and iiiiiiiiiiii=Src1Value defining RotatedImm8. 663 // s=SetFlags and iiiiiiiiiiii=Src1Value defining RotatedImm8.
633 constexpr IValueT Adc = B2 | B0; // 0101 664 constexpr IValueT Adc = B2 | B0; // 0101
634 emitType01(Adc, OpRd, OpRn, OpSrc1, SetFlags, Cond); 665 emitType01(Adc, OpRd, OpRn, OpSrc1, SetFlags, Cond, RdIsPcAndSetFlags);
635 } 666 }
636 667
637 void AssemblerARM32::add(const Operand *OpRd, const Operand *OpRn, 668 void AssemblerARM32::add(const Operand *OpRd, const Operand *OpRn,
638 const Operand *OpSrc1, bool SetFlags, 669 const Operand *OpSrc1, bool SetFlags,
639 CondARM32::Cond Cond) { 670 CondARM32::Cond Cond) {
640 // ADD (register) - ARM section A8.8.7, encoding A1: 671 // ADD (register) - ARM section A8.8.7, encoding A1:
641 // add{s}<c> <Rd>, <Rn>, <Rm>{, <shiff>} 672 // add{s}<c> <Rd>, <Rn>, <Rm>{, <shiff>}
642 // ADD (Sp plus register) - ARM section A8.8.11, encoding A1: 673 // ADD (Sp plus register) - ARM section A8.8.11, encoding A1:
643 // add{s}<c> sp, <Rn>, <Rm>{, <shiff>} 674 // add{s}<c> sp, <Rn>, <Rm>{, <shiff>}
644 // 675 //
645 // cccc0000100snnnnddddiiiiitt0mmmm where cccc=Cond, dddd=Rd, nnnn=Rn, 676 // cccc0000100snnnnddddiiiiitt0mmmm where cccc=Cond, dddd=Rd, nnnn=Rn,
646 // mmmm=Rm, iiiii=Shift, tt=ShiftKind, and s=SetFlags. 677 // mmmm=Rm, iiiii=Shift, tt=ShiftKind, and s=SetFlags.
647 // 678 //
648 // ADD (Immediate) - ARM section A8.8.5, encoding A1: 679 // ADD (Immediate) - ARM section A8.8.5, encoding A1:
649 // add{s}<c> <Rd>, <Rn>, #<RotatedImm8> 680 // add{s}<c> <Rd>, <Rn>, #<RotatedImm8>
650 // ADD (SP plus immediate) - ARM section A8.8.9, encoding A1. 681 // ADD (SP plus immediate) - ARM section A8.8.9, encoding A1.
651 // add{s}<c> <Rd>, sp, #<RotatedImm8> 682 // add{s}<c> <Rd>, sp, #<RotatedImm8>
652 // 683 //
653 // cccc0010100snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn, 684 // cccc0010100snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn,
654 // s=SetFlags and iiiiiiiiiiii=Src1Value defining RotatedImm8. 685 // s=SetFlags and iiiiiiiiiiii=Src1Value defining RotatedImm8.
655 constexpr IValueT Add = B2; // 0100 686 constexpr IValueT Add = B2; // 0100
656 emitType01(Add, OpRd, OpRn, OpSrc1, SetFlags, Cond); 687 emitType01(Add, OpRd, OpRn, OpSrc1, SetFlags, Cond, RdIsPcAndSetFlags);
657 } 688 }
658 689
659 void AssemblerARM32::and_(const Operand *OpRd, const Operand *OpRn, 690 void AssemblerARM32::and_(const Operand *OpRd, const Operand *OpRn,
660 const Operand *OpSrc1, bool SetFlags, 691 const Operand *OpSrc1, bool SetFlags,
661 CondARM32::Cond Cond) { 692 CondARM32::Cond Cond) {
662 // AND (register) - ARM section A8.8.14, encoding A1: 693 // AND (register) - ARM section A8.8.14, encoding A1:
663 // and{s}<c> <Rd>, <Rn>{, <shift>} 694 // and{s}<c> <Rd>, <Rn>{, <shift>}
664 // 695 //
665 // cccc0000000snnnnddddiiiiitt0mmmm where cccc=Cond, dddd=Rd, nnnn=Rn, 696 // cccc0000000snnnnddddiiiiitt0mmmm where cccc=Cond, dddd=Rd, nnnn=Rn,
666 // mmmm=Rm, iiiii=Shift, tt=ShiftKind, and s=SetFlags. 697 // mmmm=Rm, iiiii=Shift, tt=ShiftKind, and s=SetFlags.
667 // 698 //
668 // AND (Immediate) - ARM section A8.8.13, encoding A1: 699 // AND (Immediate) - ARM section A8.8.13, encoding A1:
669 // and{s}<c> <Rd>, <Rn>, #<RotatedImm8> 700 // and{s}<c> <Rd>, <Rn>, #<RotatedImm8>
670 // 701 //
671 // cccc0010100snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn, 702 // cccc0010100snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn,
672 // s=SetFlags and iiiiiiiiiiii=Src1Value defining RotatedImm8. 703 // s=SetFlags and iiiiiiiiiiii=Src1Value defining RotatedImm8.
673 constexpr IValueT And = 0; // 0000 704 constexpr IValueT And = 0; // 0000
674 emitType01(And, OpRd, OpRn, OpSrc1, SetFlags, Cond); 705 emitType01(And, OpRd, OpRn, OpSrc1, SetFlags, Cond, RdIsPcAndSetFlags);
675 } 706 }
676 707
677 void AssemblerARM32::b(Label *L, CondARM32::Cond Cond) { 708 void AssemblerARM32::b(Label *L, CondARM32::Cond Cond) {
678 emitBranch(L, Cond, false); 709 emitBranch(L, Cond, false);
679 } 710 }
680 711
681 void AssemblerARM32::bkpt(uint16_t Imm16) { 712 void AssemblerARM32::bkpt(uint16_t Imm16) {
682 // BKPT - ARM section A*.8.24 - encoding A1: 713 // BKPT - ARM section A*.8.24 - encoding A1:
683 // bkpt #<Imm16> 714 // bkpt #<Imm16>
684 // 715 //
(...skipping 12 matching lines...) Expand all
697 // 728 //
698 // cccc0001110snnnnddddiiiiitt0mmmm where cccc=Cond, dddd=Rd, nnnn=Rn, 729 // cccc0001110snnnnddddiiiiitt0mmmm where cccc=Cond, dddd=Rd, nnnn=Rn,
699 // mmmm=Rm, iiiii=Shift, tt=ShiftKind, and s=SetFlags. 730 // mmmm=Rm, iiiii=Shift, tt=ShiftKind, and s=SetFlags.
700 // 731 //
701 // BIC (immediate) - ARM section A8.8.21, encoding A1: 732 // BIC (immediate) - ARM section A8.8.21, encoding A1:
702 // bic{s}<c> <Rd>, <Rn>, #<RotatedImm8> 733 // bic{s}<c> <Rd>, <Rn>, #<RotatedImm8>
703 // 734 //
704 // cccc0011110snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rn, nnnn=Rn, 735 // cccc0011110snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rn, nnnn=Rn,
705 // s=SetFlags, and iiiiiiiiiiii=Src1Value defining RotatedImm8. 736 // s=SetFlags, and iiiiiiiiiiii=Src1Value defining RotatedImm8.
706 IValueT Opcode = B3 | B2 | B1; // i.e. 1110 737 IValueT Opcode = B3 | B2 | B1; // i.e. 1110
707 emitType01(Opcode, OpRd, OpRn, OpSrc1, SetFlags, Cond); 738 emitType01(Opcode, OpRd, OpRn, OpSrc1, SetFlags, Cond, RdIsPcAndSetFlags);
708 } 739 }
709 740
710 void AssemblerARM32::bl(const ConstantRelocatable *Target) { 741 void AssemblerARM32::bl(const ConstantRelocatable *Target) {
711 // BL (immediate) - ARM section A8.8.25, encoding A1: 742 // BL (immediate) - ARM section A8.8.25, encoding A1:
712 // bl<c> <label> 743 // bl<c> <label>
713 // 744 //
714 // cccc1011iiiiiiiiiiiiiiiiiiiiiiii where cccc=Cond (not currently allowed) 745 // cccc1011iiiiiiiiiiiiiiiiiiiiiiii where cccc=Cond (not currently allowed)
715 // and iiiiiiiiiiiiiiiiiiiiiiii is the (encoded) Target to branch to. 746 // and iiiiiiiiiiiiiiiiiiiiiiii is the (encoded) Target to branch to.
716 emitFixup(createBlFixup(Target)); 747 emitFixup(createBlFixup(Target));
717 constexpr CondARM32::Cond Cond = CondARM32::AL; 748 constexpr CondARM32::Cond Cond = CondARM32::AL;
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
778 // 809 //
779 // cccc0000001snnnnddddiiiiitt0mmmm where cccc=Cond, dddd=Rd, nnnn=Rn, 810 // cccc0000001snnnnddddiiiiitt0mmmm where cccc=Cond, dddd=Rd, nnnn=Rn,
780 // mmmm=Rm, iiiii=Shift, tt=ShiftKind, and s=SetFlags. 811 // mmmm=Rm, iiiii=Shift, tt=ShiftKind, and s=SetFlags.
781 // 812 //
782 // EOR (Immediate) - ARM section A8.*.46, encoding A1: 813 // EOR (Immediate) - ARM section A8.*.46, encoding A1:
783 // eor{s}<c> <Rd>, <Rn>, #RotatedImm8 814 // eor{s}<c> <Rd>, <Rn>, #RotatedImm8
784 // 815 //
785 // cccc0010001snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn, 816 // cccc0010001snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn,
786 // s=SetFlags and iiiiiiiiiiii=Src1Value defining RotatedImm8. 817 // s=SetFlags and iiiiiiiiiiii=Src1Value defining RotatedImm8.
787 constexpr IValueT Eor = B0; // 0001 818 constexpr IValueT Eor = B0; // 0001
788 emitType01(Eor, OpRd, OpRn, OpSrc1, SetFlags, Cond); 819 emitType01(Eor, OpRd, OpRn, OpSrc1, SetFlags, Cond, RdIsPcAndSetFlags);
789 } 820 }
790 821
791 void AssemblerARM32::ldr(const Operand *OpRt, const Operand *OpAddress, 822 void AssemblerARM32::ldr(const Operand *OpRt, const Operand *OpAddress,
792 CondARM32::Cond Cond, const TargetInfo &TInfo) { 823 CondARM32::Cond Cond, const TargetInfo &TInfo) {
793 constexpr bool IsLoad = true; 824 constexpr bool IsLoad = true;
794 IValueT Rt; 825 IValueT Rt;
795 if (decodeOperand(OpRt, Rt) != DecodedAsRegister) 826 if (decodeOperand(OpRt, Rt) != DecodedAsRegister)
796 return setNeedsTextFixup(); 827 return setNeedsTextFixup();
797 const Type Ty = OpRt->getType(); 828 const Type Ty = OpRt->getType();
798 if (!(Ty == IceType_i32 || Ty == IceType_i8)) // TODO(kschimpf) Expand? 829 if (!(Ty == IceType_i32 || Ty == IceType_i8)) // TODO(kschimpf) Expand?
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
861 if (isBitSet(W, Address) && 892 if (isBitSet(W, Address) &&
862 ((Rn == RegARM32::Encoded_Reg_pc) || encodeGPRRegister(Rn) == Rt)) 893 ((Rn == RegARM32::Encoded_Reg_pc) || encodeGPRRegister(Rn) == Rt))
863 // Unpredictable 894 // Unpredictable
864 return setNeedsTextFixup(); 895 return setNeedsTextFixup();
865 896
866 return emitMemOp(Cond, kInstTypeRegisterShift, IsLoad, IsByte, Rt, Address); 897 return emitMemOp(Cond, kInstTypeRegisterShift, IsLoad, IsByte, Rt, Address);
867 } 898 }
868 } 899 }
869 } 900 }
870 901
902 void AssemblerARM32::lsl(const Operand *OpRd, const Operand *OpRm,
903 const Operand *OpSrc1, bool SetFlags,
904 CondARM32::Cond Cond) {
905 constexpr IValueT Lsl = B3 | B2 | B0; // 1101
906 constexpr IValueT Rn = 0; // Rn field is not used.
907 IValueT Rd;
908 if (decodeOperand(OpRd, Rd) != DecodedAsRegister)
909 return setNeedsTextFixup();
910 IValueT Rm;
911 if (decodeOperand(OpRm, Rm) != DecodedAsRegister)
912 return setNeedsTextFixup();
913 IValueT Value;
914 switch (decodeOperand(OpSrc1, Value)) {
915 default:
916 return setNeedsTextFixup();
917 case DecodedAsShiftImm5: {
918 // LSL (immediate) - ARM section A8.8.94, encoding A1:
919 // lsl{s}<c> <Rd>, <Rm>, #imm5
920 //
921 // cccc0001101s0000ddddiiiii000mmmm where cccc=Cond, s=SetFlags, dddd=Rd,
922 // iiiii=imm5, and mmmm=Rm.
923 Value = Value | (Rm << kRmShift);
924 emitType01(Cond, kInstTypeDataRegShift, Lsl, SetFlags, Rn, Rd, Value,
925 RdIsPcAndSetFlags);
926 return;
927 }
928 case DecodedAsRegister: {
929 // LSL (register) - ARM section A8.8.95, encoding A1:
930 // lsl{S}<c> <Rd>, <Rm>, <Rs>
931 //
932 // cccc0001101s0000ddddssss0001mmmm where cccc=Cond, s=SetFlags, dddd=Rd,
933 // mmmm=Rm, and ssss=Rs.
934 IValueT Rs;
935 if (decodeOperand(OpSrc1, Rs) != DecodedAsRegister)
936 return setNeedsTextFixup();
937 if ((Rd == RegARM32::Encoded_Reg_pc) || (Rm == RegARM32::Encoded_Reg_pc) ||
938 (Rs == RegARM32::Encoded_Reg_pc))
939 setNeedsTextFixup();
940 emitType01(Cond, kInstTypeDataRegShift, Lsl, SetFlags, Rn, Rd,
941 encodeShiftRotateReg(Rm, OperandARM32::kNoShift, Rs), NoChecks);
942 return;
943 }
944 }
945 }
946
871 void AssemblerARM32::mov(const Operand *OpRd, const Operand *OpSrc, 947 void AssemblerARM32::mov(const Operand *OpRd, const Operand *OpSrc,
872 CondARM32::Cond Cond) { 948 CondARM32::Cond Cond) {
873 // MOV (register) - ARM section A8.8.104, encoding A1: 949 // MOV (register) - ARM section A8.8.104, encoding A1:
874 // mov{S}<c> <Rd>, <Rn> 950 // mov{S}<c> <Rd>, <Rn>
875 // 951 //
876 // cccc0001101s0000dddd00000000mmmm where cccc=Cond, s=SetFlags, dddd=Rd, 952 // cccc0001101s0000dddd00000000mmmm where cccc=Cond, s=SetFlags, dddd=Rd,
877 // and nnnn=Rn. 953 // and nnnn=Rn.
878 // 954 //
879 // MOV (immediate) - ARM section A8.8.102, encoding A1: 955 // MOV (immediate) - ARM section A8.8.102, encoding A1:
880 // mov{S}<c> <Rd>, #<RotatedImm8> 956 // mov{S}<c> <Rd>, #<RotatedImm8>
881 // 957 //
882 // cccc0011101s0000ddddiiiiiiiiiiii where cccc=Cond, s=SetFlags, dddd=Rd, 958 // cccc0011101s0000ddddiiiiiiiiiiii where cccc=Cond, s=SetFlags, dddd=Rd,
883 // and iiiiiiiiiiii=RotatedImm8=Src. Note: We don't use movs in this 959 // and iiiiiiiiiiii=RotatedImm8=Src. Note: We don't use movs in this
884 // assembler. 960 // assembler.
885 IValueT Rd; 961 IValueT Rd;
886 if (decodeOperand(OpRd, Rd) != DecodedAsRegister) 962 if (decodeOperand(OpRd, Rd) != DecodedAsRegister)
887 return setNeedsTextFixup(); 963 return setNeedsTextFixup();
888 constexpr bool SetFlags = false; 964 constexpr bool SetFlags = false;
889 constexpr IValueT Rn = 0; 965 constexpr IValueT Rn = 0;
890 constexpr IValueT Mov = B3 | B2 | B0; // 1101. 966 constexpr IValueT Mov = B3 | B2 | B0; // 1101.
891 emitType01(Mov, Rd, Rn, OpSrc, SetFlags, Cond); 967 emitType01(Mov, Rd, Rn, OpSrc, SetFlags, Cond, RdIsPcAndSetFlags);
892 } 968 }
893 969
894 void AssemblerARM32::emitMovw(IValueT Opcode, IValueT Rd, IValueT Imm16, 970 void AssemblerARM32::emitMovw(IValueT Opcode, IValueT Rd, IValueT Imm16,
895 bool SetFlags, CondARM32::Cond Cond) { 971 bool SetFlags, CondARM32::Cond Cond) {
896 if (!isConditionDefined(Cond) || !Utils::IsAbsoluteUint(16, Imm16)) 972 if (!isConditionDefined(Cond) || !Utils::IsAbsoluteUint(16, Imm16))
897 return setNeedsTextFixup(); 973 return setNeedsTextFixup();
898 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 974 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
899 const IValueT Encoding = encodeCondition(Cond) << kConditionShift | Opcode | 975 const IValueT Encoding = encodeCondition(Cond) << kConditionShift | Opcode |
900 (encodeBool(SetFlags) << kSShift) | 976 (encodeBool(SetFlags) << kSShift) |
901 ((Imm16 >> 12) << 16) | Rd << kRdShift | 977 ((Imm16 >> 12) << 16) | Rd << kRdShift |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
979 // 1055 //
980 // cccc0000110snnnnddddiiiiitt0mmmm where cccc=Cond, dddd=Rd, nnnn=Rn, 1056 // cccc0000110snnnnddddiiiiitt0mmmm where cccc=Cond, dddd=Rd, nnnn=Rn,
981 // mmmm=Rm, iiiii=Shift, tt=ShiftKind, and s=SetFlags. 1057 // mmmm=Rm, iiiii=Shift, tt=ShiftKind, and s=SetFlags.
982 // 1058 //
983 // SBC (Immediate) - ARM section A8.8.161, encoding A1: 1059 // SBC (Immediate) - ARM section A8.8.161, encoding A1:
984 // sbc{s}<c> <Rd>, <Rn>, #<RotatedImm8> 1060 // sbc{s}<c> <Rd>, <Rn>, #<RotatedImm8>
985 // 1061 //
986 // cccc0010110snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn, 1062 // cccc0010110snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn,
987 // s=SetFlags and iiiiiiiiiiii=Src1Value defining RotatedImm8. 1063 // s=SetFlags and iiiiiiiiiiii=Src1Value defining RotatedImm8.
988 constexpr IValueT Sbc = B2 | B1; // 0110 1064 constexpr IValueT Sbc = B2 | B1; // 0110
989 emitType01(Sbc, OpRd, OpRn, OpSrc1, SetFlags, Cond); 1065 emitType01(Sbc, OpRd, OpRn, OpSrc1, SetFlags, Cond, RdIsPcAndSetFlags);
990 } 1066 }
991 1067
992 void AssemblerARM32::sdiv(const Operand *OpRd, const Operand *OpRn, 1068 void AssemblerARM32::sdiv(const Operand *OpRd, const Operand *OpRn,
993 const Operand *OpSrc1, CondARM32::Cond Cond) { 1069 const Operand *OpSrc1, CondARM32::Cond Cond) {
994 // SDIV - ARM section A8.8.165, encoding A1. 1070 // SDIV - ARM section A8.8.165, encoding A1.
995 // sdiv<c> <Rd>, <Rn>, <Rm> 1071 // sdiv<c> <Rd>, <Rn>, <Rm>
996 // 1072 //
997 // cccc01110001dddd1111mmmm0001nnnn where cccc=Cond, dddd=Rd, nnnn=Rn, and 1073 // cccc01110001dddd1111mmmm0001nnnn where cccc=Cond, dddd=Rd, nnnn=Rn, and
998 // mmmm=Rm. 1074 // mmmm=Rm.
999 IValueT Rd; 1075 IValueT Rd;
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
1057 // 1133 //
1058 // cccc0001100snnnnddddiiiiitt0mmmm where cccc=Cond, dddd=Rd, nnnn=Rn, 1134 // cccc0001100snnnnddddiiiiitt0mmmm where cccc=Cond, dddd=Rd, nnnn=Rn,
1059 // mmmm=Rm, iiiii=shift, tt=ShiftKind,, and s=SetFlags. 1135 // mmmm=Rm, iiiii=shift, tt=ShiftKind,, and s=SetFlags.
1060 // 1136 //
1061 // ORR (register) - ARM Section A8.8.123, encoding A1: 1137 // ORR (register) - ARM Section A8.8.123, encoding A1:
1062 // orr{s}<c> <Rd>, <Rn>, #<RotatedImm8> 1138 // orr{s}<c> <Rd>, <Rn>, #<RotatedImm8>
1063 // 1139 //
1064 // cccc0001100snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn, 1140 // cccc0001100snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn,
1065 // s=SetFlags and iiiiiiiiiiii=Src1Value defining RotatedImm8. 1141 // s=SetFlags and iiiiiiiiiiii=Src1Value defining RotatedImm8.
1066 constexpr IValueT Orr = B3 | B2; // i.e. 1100 1142 constexpr IValueT Orr = B3 | B2; // i.e. 1100
1067 emitType01(Orr, OpRd, OpRn, OpSrc1, SetFlags, Cond); 1143 emitType01(Orr, OpRd, OpRn, OpSrc1, SetFlags, Cond, RdIsPcAndSetFlags);
1068 } 1144 }
1069 1145
1070 void AssemblerARM32::pop(const Operand *OpRt, CondARM32::Cond Cond) { 1146 void AssemblerARM32::pop(const Operand *OpRt, CondARM32::Cond Cond) {
1071 // POP - ARM section A8.8.132, encoding A2: 1147 // POP - ARM section A8.8.132, encoding A2:
1072 // pop<c> {Rt} 1148 // pop<c> {Rt}
1073 // 1149 //
1074 // cccc010010011101dddd000000000100 where dddd=Rt and cccc=Cond. 1150 // cccc010010011101dddd000000000100 where dddd=Rt and cccc=Cond.
1075 IValueT Rt; 1151 IValueT Rt;
1076 if (decodeOperand(OpRt, Rt) != DecodedAsRegister) 1152 if (decodeOperand(OpRt, Rt) != DecodedAsRegister)
1077 return setNeedsTextFixup(); 1153 return setNeedsTextFixup();
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
1211 // mmmm=Rm, iiiiii=shift, tt=ShiftKind, and s=SetFlags. 1287 // mmmm=Rm, iiiiii=shift, tt=ShiftKind, and s=SetFlags.
1212 // 1288 //
1213 // Sub (Immediate) - ARM section A8.8.222, encoding A1: 1289 // Sub (Immediate) - ARM section A8.8.222, encoding A1:
1214 // sub{s}<c> <Rd>, <Rn>, #<RotatedImm8> 1290 // sub{s}<c> <Rd>, <Rn>, #<RotatedImm8>
1215 // Sub (Sp minus immediate) - ARM section A8.*.225, encoding A1: 1291 // Sub (Sp minus immediate) - ARM section A8.*.225, encoding A1:
1216 // sub{s}<c> sp, <Rn>, #<RotatedImm8> 1292 // sub{s}<c> sp, <Rn>, #<RotatedImm8>
1217 // 1293 //
1218 // cccc0010010snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn, 1294 // cccc0010010snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn,
1219 // s=SetFlags and iiiiiiiiiiii=Src1Value defining RotatedImm8 1295 // s=SetFlags and iiiiiiiiiiii=Src1Value defining RotatedImm8
1220 constexpr IValueT Sub = B1; // 0010 1296 constexpr IValueT Sub = B1; // 0010
1221 emitType01(Sub, OpRd, OpRn, OpSrc1, SetFlags, Cond); 1297 emitType01(Sub, OpRd, OpRn, OpSrc1, SetFlags, Cond, RdIsPcAndSetFlags);
1222 } 1298 }
1223 1299
1224 void AssemblerARM32::tst(const Operand *OpRn, const Operand *OpSrc1, 1300 void AssemblerARM32::tst(const Operand *OpRn, const Operand *OpSrc1,
1225 CondARM32::Cond Cond) { 1301 CondARM32::Cond Cond) {
1226 // TST (register) - ARM section A8.8.241, encoding A1: 1302 // TST (register) - ARM section A8.8.241, encoding A1:
1227 // tst<c> <Rn>, <Rm>(, <shift>} 1303 // tst<c> <Rn>, <Rm>(, <shift>}
1228 // 1304 //
1229 // cccc00010001nnnn0000iiiiitt0mmmm where cccc=Cond, nnnn=Rn, mmmm=Rm, 1305 // cccc00010001nnnn0000iiiiitt0mmmm where cccc=Cond, nnnn=Rn, mmmm=Rm,
1230 // iiiii=Shift, and tt=ShiftKind. 1306 // iiiii=Shift, and tt=ShiftKind.
1231 // 1307 //
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
1295 // rr defined (RotationValue) rotate. 1371 // rr defined (RotationValue) rotate.
1296 constexpr IValueT Opcode = B26 | B25 | B23 | B22 | B21 | B20; 1372 constexpr IValueT Opcode = B26 | B25 | B23 | B22 | B21 | B20;
1297 emitUxt(Cond, Opcode, Rd, Rn, Rm, Rotation); 1373 emitUxt(Cond, Opcode, Rd, Rn, Rm, Rotation);
1298 return; 1374 return;
1299 } 1375 }
1300 } 1376 }
1301 } 1377 }
1302 1378
1303 } // end of namespace ARM32 1379 } // end of namespace ARM32
1304 } // end of namespace Ice 1380 } // end of namespace Ice
OLDNEW
« no previous file with comments | « src/IceAssemblerARM32.h ('k') | src/IceInstARM32.cpp » ('j') | tests_lit/assembler/arm32/lsl.ll » ('J')

Powered by Google App Engine
This is Rietveld 408576698