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

Side by Side Diff: src/IceAssemblerARM32.cpp

Issue 1495093002: Improve error handling in the ARM integrated assembler. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Fix nits. Created 5 years 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') | no next file » | 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 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
79 // Immediate instruction fields encoding. 79 // Immediate instruction fields encoding.
80 static constexpr IValueT kImmed8Bits = 8; 80 static constexpr IValueT kImmed8Bits = 8;
81 static constexpr IValueT kImmed8Shift = 0; 81 static constexpr IValueT kImmed8Shift = 0;
82 static constexpr IValueT kRotateBits = 4; 82 static constexpr IValueT kRotateBits = 4;
83 static constexpr IValueT kRotateShift = 8; 83 static constexpr IValueT kRotateShift = 8;
84 84
85 // Shift instruction register fields encodings. 85 // Shift instruction register fields encodings.
86 static constexpr IValueT kShiftImmShift = 7; 86 static constexpr IValueT kShiftImmShift = 7;
87 static constexpr IValueT kShiftImmBits = 5; 87 static constexpr IValueT kShiftImmBits = 5;
88 static constexpr IValueT kShiftShift = 5; 88 static constexpr IValueT kShiftShift = 5;
89
90 static constexpr IValueT kImmed12Bits = 12; 89 static constexpr IValueT kImmed12Bits = 12;
91 static constexpr IValueT kImm12Shift = 0; 90 static constexpr IValueT kImm12Shift = 0;
92 91
93 // Rotation instructions (uxtb etc.). 92 // Rotation instructions (uxtb etc.).
94 static constexpr IValueT kRotationShift = 10; 93 static constexpr IValueT kRotationShift = 10;
95 94
96 // Div instruction register field encodings. 95 // Div instruction register field encodings.
97 static constexpr IValueT kDivRdShift = 16; 96 static constexpr IValueT kDivRdShift = 16;
98 static constexpr IValueT kDivRmShift = 8; 97 static constexpr IValueT kDivRmShift = 8;
99 static constexpr IValueT kDivRnShift = 0; 98 static constexpr IValueT kDivRnShift = 0;
(...skipping 20 matching lines...) Expand all
120 } 119 }
121 120
122 inline IValueT encodeGPRRegister(RegARM32::GPRRegister Rn) { 121 inline IValueT encodeGPRRegister(RegARM32::GPRRegister Rn) {
123 return static_cast<IValueT>(Rn); 122 return static_cast<IValueT>(Rn);
124 } 123 }
125 124
126 inline RegARM32::GPRRegister decodeGPRRegister(IValueT R) { 125 inline RegARM32::GPRRegister decodeGPRRegister(IValueT R) {
127 return static_cast<RegARM32::GPRRegister>(R); 126 return static_cast<RegARM32::GPRRegister>(R);
128 } 127 }
129 128
130 inline bool isGPRRegisterDefined(RegARM32::GPRRegister R) {
131 return R != RegARM32::Encoded_Not_GPR;
132 }
133
134 inline bool isGPRRegisterDefined(IValueT R) { 129 inline bool isGPRRegisterDefined(IValueT R) {
135 return R != encodeGPRRegister(RegARM32::Encoded_Not_GPR); 130 return R != encodeGPRRegister(RegARM32::Encoded_Not_GPR);
136 } 131 }
137 132
138 inline bool isConditionDefined(CondARM32::Cond Cond) { 133 inline bool isConditionDefined(CondARM32::Cond Cond) {
139 return Cond != CondARM32::kNone; 134 return Cond != CondARM32::kNone;
140 } 135 }
141 136
142 inline IValueT encodeCondition(CondARM32::Cond Cond) { 137 inline IValueT encodeCondition(CondARM32::Cond Cond) {
143 return static_cast<IValueT>(Cond); 138 return static_cast<IValueT>(Cond);
144 } 139 }
145 140
146 IValueT encodeShift(OperandARM32::ShiftKind Shift) { 141 IValueT encodeShift(OperandARM32::ShiftKind Shift) {
147 // Follows encoding in ARM section A8.4.1 "Constant shifts". 142 // Follows encoding in ARM section A8.4.1 "Constant shifts".
148 switch (Shift) { 143 switch (Shift) {
149 case OperandARM32::kNoShift: 144 case OperandARM32::kNoShift:
150 case OperandARM32::LSL: 145 case OperandARM32::LSL:
151 return 0; // 0b00 146 return 0; // 0b00
152 case OperandARM32::LSR: 147 case OperandARM32::LSR:
153 return 1; // 0b01 148 return 1; // 0b01
154 case OperandARM32::ASR: 149 case OperandARM32::ASR:
155 return 2; // 0b10 150 return 2; // 0b10
156 case OperandARM32::ROR: 151 case OperandARM32::ROR:
157 case OperandARM32::RRX: 152 case OperandARM32::RRX:
158 return 3; // 0b11 153 return 3; // 0b11
159 } 154 }
160
161 llvm::report_fatal_error("Unknown Shift value"); 155 llvm::report_fatal_error("Unknown Shift value");
162 return 0; 156 return 0;
163 } 157 }
164 158
165 // Returns the bits in the corresponding masked value. 159 // Returns the bits in the corresponding masked value.
166 inline IValueT mask(IValueT Value, IValueT Shift, IValueT Bits) { 160 inline IValueT mask(IValueT Value, IValueT Shift, IValueT Bits) {
167 return (Value >> Shift) & ((1 << Bits) - 1); 161 return (Value >> Shift) & ((1 << Bits) - 1);
168 } 162 }
169 163
170 // Extract out a Bit in Value. 164 // Extract out a Bit in Value.
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after
356 } 350 }
357 return CantEncode; 351 return CantEncode;
358 } 352 }
359 353
360 // Checks that Offset can fit in imm24 constant of branch (b) instruction. 354 // Checks that Offset can fit in imm24 constant of branch (b) instruction.
361 bool canEncodeBranchOffset(IOffsetT Offset) { 355 bool canEncodeBranchOffset(IOffsetT Offset) {
362 return Utils::IsAligned(Offset, 4) && 356 return Utils::IsAligned(Offset, 4) &&
363 Utils::IsInt(kBranchOffsetBits, Offset >> 2); 357 Utils::IsInt(kBranchOffsetBits, Offset >> 2);
364 } 358 }
365 359
360 inline IValueT encodeRegister(const Operand *OpReg, const char *RegName,
Jim Stichnoth 2015/12/03 21:19:49 I don't think all the "inline" specifications are
Karl 2015/12/03 23:52:59 Removed inlines.
361 const char *InstName) {
362 IValueT Reg = 0;
363 if (encodeOperand(OpReg, Reg) != EncodedAsRegister)
364 llvm::report_fatal_error(std::string(InstName) + ": Can't find register " +
365 RegName);
366 return Reg;
367 }
368
369 inline void verifyRegDefined(IValueT Reg, const char *RegName,
370 const char *InstName) {
371 if (!isGPRRegisterDefined(Reg))
Jim Stichnoth 2015/12/03 21:19:49 What do you think about using BuildDefs to disable
Karl 2015/12/03 23:52:59 I guess it is ok. Changing.
372 llvm::report_fatal_error(std::string(InstName) + ": Can't find " + RegName);
373 }
374
375 inline void verifyCondDefined(CondARM32::Cond Cond, const char *InstName) {
376 if (!isConditionDefined(Cond))
377 llvm::report_fatal_error(std::string(InstName) + ": Condition not defined");
378 }
379
380 inline void verifyNot_NotPAndW(IValueT Address, const char *InstName) {
Jim Stichnoth 2015/12/03 21:19:49 The "Not_Not" substring, including the use of unde
Karl 2015/12/03 23:52:59 Renamed to verifyPOrNotW().
381 if (!isBitSet(P, Address) && isBitSet(W, Address))
382 llvm::report_fatal_error(std::string(InstName) +
383 ": P=0 when W=1 not allowed");
384 }
385
386 inline void verifyRegsNotEq(IValueT Reg1, const char *Reg1Name, IValueT Reg2,
387 const char *Reg2Name, const char *InstName) {
388 if (Reg1 == Reg2)
389 llvm::report_fatal_error(std::string(InstName) + ": " + Reg1Name + "=" +
390 Reg2Name + " not allowed");
391 }
392
393 inline void verifyRegNotPc(IValueT Reg, const char *RegName,
394 const char *InstName) {
395 verifyRegsNotEq(Reg, RegName, RegARM32::Encoded_Reg_pc, "pc", InstName);
396 }
397
398 inline void verifyAddrRegNotPc(IValueT RegShift, IValueT Address,
399 const char *RegName, const char *InstName) {
400 if (getGPRReg(RegShift, Address) == RegARM32::Encoded_Reg_pc)
401 llvm::report_fatal_error(std::string(InstName) + ": " + RegName +
402 "=pc not allowed");
403 }
404
405 inline void verifyRegNotPcWhenSetFlags(IValueT Reg, bool SetFlags,
406 const char *InstName) {
407 if (SetFlags && (Reg == RegARM32::Encoded_Reg_pc))
408 llvm::report_fatal_error(std::string(InstName) + ": " +
409 RegARM32::RegNames[Reg] +
410 "=pc not allowed when CC=1");
411 }
412
366 } // end of anonymous namespace 413 } // end of anonymous namespace
367 414
368 namespace Ice { 415 namespace Ice {
369 namespace ARM32 { 416 namespace ARM32 {
370 417
371 size_t MoveRelocatableFixup::emit(GlobalContext *Ctx, 418 size_t MoveRelocatableFixup::emit(GlobalContext *Ctx,
372 const Assembler &Asm) const { 419 const Assembler &Asm) const {
373 if (!BuildDefs::dump()) 420 if (!BuildDefs::dump())
374 return InstARM32::InstSize; 421 return InstARM32::InstSize;
375 Ostream &Str = Ctx->getStrEmit(); 422 Ostream &Str = Ctx->getStrEmit();
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
483 530
484 void AssemblerARM32::emitTextInst(const std::string &Text, SizeT InstSize) { 531 void AssemblerARM32::emitTextInst(const std::string &Text, SizeT InstSize) {
485 AssemblerFixup *F = createTextFixup(Text, InstSize); 532 AssemblerFixup *F = createTextFixup(Text, InstSize);
486 emitFixup(F); 533 emitFixup(F);
487 for (SizeT I = 0; I < InstSize; ++I) { 534 for (SizeT I = 0; I < InstSize; ++I) {
488 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 535 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
489 Buffer.emit<char>(0); 536 Buffer.emit<char>(0);
490 } 537 }
491 } 538 }
492 539
493 void AssemblerARM32::emitType01(CondARM32::Cond Cond, IValueT Type, 540 void AssemblerARM32::emitType01(CondARM32::Cond Cond, IValueT InstType,
494 IValueT Opcode, bool SetFlags, IValueT Rn, 541 IValueT Opcode, bool SetFlags, IValueT Rn,
495 IValueT Rd, IValueT Imm12, 542 IValueT Rd, IValueT Imm12,
496 EmitChecks RuleChecks) { 543 EmitChecks RuleChecks, const char *InstName) {
497 switch (RuleChecks) { 544 switch (RuleChecks) {
498 case NoChecks: 545 case NoChecks:
499 break; 546 break;
500 case RdIsPcAndSetFlags: 547 case RdIsPcAndSetFlags:
501 if ((Rd == RegARM32::Encoded_Reg_pc) && SetFlags) 548 verifyRegNotPcWhenSetFlags(Rd, SetFlags, InstName);
502 // Conditions of rule violated.
503 return setNeedsTextFixup();
504 break; 549 break;
505 } 550 }
506 551 verifyRegDefined(Rd, "Rd", InstName);
507 if (!isGPRRegisterDefined(Rd) || !isConditionDefined(Cond)) 552 verifyCondDefined(Cond, InstName);
508 return setNeedsTextFixup();
509 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 553 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
510 const IValueT Encoding = (encodeCondition(Cond) << kConditionShift) | 554 const IValueT Encoding = (encodeCondition(Cond) << kConditionShift) |
511 (Type << kTypeShift) | (Opcode << kOpcodeShift) | 555 (InstType << kTypeShift) | (Opcode << kOpcodeShift) |
512 (encodeBool(SetFlags) << kSShift) | 556 (encodeBool(SetFlags) << kSShift) |
513 (Rn << kRnShift) | (Rd << kRdShift) | Imm12; 557 (Rn << kRnShift) | (Rd << kRdShift) | Imm12;
514 emitInst(Encoding); 558 emitInst(Encoding);
515 } 559 }
516 560
517 void AssemblerARM32::emitType01(IValueT Opcode, const Operand *OpRd, 561 void AssemblerARM32::emitType01(CondARM32::Cond Cond, IValueT Opcode,
518 const Operand *OpRn, const Operand *OpSrc1, 562 const Operand *OpRd, const Operand *OpRn,
519 bool SetFlags, CondARM32::Cond Cond, 563 const Operand *OpSrc1, bool SetFlags,
520 EmitChecks RuleChecks) { 564 EmitChecks RuleChecks, const char *InstName) {
521 IValueT Rd; 565 IValueT Rd = encodeRegister(OpRd, "Rd", InstName);
522 if (encodeOperand(OpRd, Rd) != EncodedAsRegister) 566 IValueT Rn = encodeRegister(OpRn, "Rn", InstName);
523 return setNeedsTextFixup(); 567 emitType01(Cond, Opcode, Rd, Rn, OpSrc1, SetFlags, RuleChecks, InstName);
524 IValueT Rn;
525 if (encodeOperand(OpRn, Rn) != EncodedAsRegister)
526 return setNeedsTextFixup();
527 emitType01(Opcode, Rd, Rn, OpSrc1, SetFlags, Cond, RuleChecks);
528 } 568 }
529 569
530 void AssemblerARM32::emitType01(IValueT Opcode, IValueT Rd, IValueT Rn, 570 void AssemblerARM32::emitType01(CondARM32::Cond Cond, IValueT Opcode,
531 const Operand *OpSrc1, bool SetFlags, 571 IValueT Rd, IValueT Rn, const Operand *OpSrc1,
532 CondARM32::Cond Cond, EmitChecks RuleChecks) { 572 bool SetFlags, EmitChecks RuleChecks,
573 const char *InstName) {
533 574
534 IValueT Src1Value; 575 IValueT Src1Value;
535 // TODO(kschimpf) Other possible decodings of data operations. 576 // TODO(kschimpf) Other possible decodings of data operations.
536 switch (encodeOperand(OpSrc1, Src1Value)) { 577 switch (encodeOperand(OpSrc1, Src1Value)) {
537 default: 578 default:
579 // TODO(kschimpf): Figure out what additional cases need to be handled.
538 return setNeedsTextFixup(); 580 return setNeedsTextFixup();
539 case EncodedAsRegister: { 581 case EncodedAsRegister: {
540 // XXX (register) 582 // XXX (register)
541 // xxx{s}<c> <Rd>, <Rn>, <Rm>{, <shiff>} 583 // xxx{s}<c> <Rd>, <Rn>, <Rm>{, <shiff>}
542 // 584 //
543 // cccc0000100snnnnddddiiiiitt0mmmm where cccc=Cond, dddd=Rd, nnnn=Rn, 585 // cccc0000100snnnnddddiiiiitt0mmmm where cccc=Cond, dddd=Rd, nnnn=Rn,
544 // mmmm=Rm, iiiii=Shift, tt=ShiftKind, and s=SetFlags. 586 // mmmm=Rm, iiiii=Shift, tt=ShiftKind, and s=SetFlags.
545 constexpr IValueT Imm5 = 0; 587 constexpr IValueT Imm5 = 0;
546 Src1Value = encodeShiftRotateImm5(Src1Value, OperandARM32::kNoShift, Imm5); 588 Src1Value = encodeShiftRotateImm5(Src1Value, OperandARM32::kNoShift, Imm5);
547 emitType01(Cond, kInstTypeDataRegister, Opcode, SetFlags, Rn, Rd, Src1Value, 589 emitType01(Cond, kInstTypeDataRegister, Opcode, SetFlags, Rn, Rd, Src1Value,
548 RuleChecks); 590 RuleChecks, InstName);
549 return; 591 return;
550 } 592 }
551 case EncodedAsShiftedRegister: { 593 case EncodedAsShiftedRegister: {
552 // Form is defined in case EncodedAsRegister. (i.e. XXX (register)). 594 // Form is defined in case EncodedAsRegister. (i.e. XXX (register)).
553 emitType01(Cond, kInstTypeDataRegister, Opcode, SetFlags, Rn, Rd, Src1Value, 595 emitType01(Cond, kInstTypeDataRegister, Opcode, SetFlags, Rn, Rd, Src1Value,
554 RuleChecks); 596 RuleChecks, InstName);
555 return; 597 return;
556 } 598 }
557 case EncodedAsConstI32: { 599 case EncodedAsConstI32: {
558 // See if we can convert this to an XXX (immediate). 600 // See if we can convert this to an XXX (immediate).
559 IValueT RotateAmt; 601 IValueT RotateAmt;
560 IValueT Imm8; 602 IValueT Imm8;
561 if (!OperandARM32FlexImm::canHoldImm(Src1Value, &RotateAmt, &Imm8)) 603 if (!OperandARM32FlexImm::canHoldImm(Src1Value, &RotateAmt, &Imm8))
562 return setNeedsTextFixup(); 604 llvm::report_fatal_error(std::string(InstName) +
605 ": Immediate rotated constant not valid");
563 Src1Value = encodeRotatedImm8(RotateAmt, Imm8); 606 Src1Value = encodeRotatedImm8(RotateAmt, Imm8);
564 // Intentionally fall to next case! 607 // Intentionally fall to next case!
565 } 608 }
566 case EncodedAsRotatedImm8: { 609 case EncodedAsRotatedImm8: {
567 // XXX (Immediate) 610 // XXX (Immediate)
568 // xxx{s}<c> <Rd>, <Rn>, #<RotatedImm8> 611 // xxx{s}<c> <Rd>, <Rn>, #<RotatedImm8>
569 // 612 //
570 // cccc0010100snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn, 613 // cccc0010100snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn,
571 // s=SetFlags and iiiiiiiiiiii=Src1Value defining RotatedImm8. 614 // s=SetFlags and iiiiiiiiiiii=Src1Value defining RotatedImm8.
572 emitType01(Cond, kInstTypeDataImmediate, Opcode, SetFlags, Rn, Rd, 615 emitType01(Cond, kInstTypeDataImmediate, Opcode, SetFlags, Rn, Rd,
573 Src1Value, RuleChecks); 616 Src1Value, RuleChecks, InstName);
574 return; 617 return;
575 } 618 }
576 } 619 }
577 } 620 }
578 621
579 void AssemblerARM32::emitType05(CondARM32::Cond Cond, IOffsetT Offset, 622 void AssemblerARM32::emitType05(CondARM32::Cond Cond, IOffsetT Offset,
580 bool Link) { 623 bool Link, const char *InstName) {
581 // cccc101liiiiiiiiiiiiiiiiiiiiiiii where cccc=Cond, l=Link, and 624 // cccc101liiiiiiiiiiiiiiiiiiiiiiii where cccc=Cond, l=Link, and
582 // iiiiiiiiiiiiiiiiiiiiiiii= 625 // iiiiiiiiiiiiiiiiiiiiiiii=
583 // EncodedBranchOffset(cccc101l000000000000000000000000, Offset); 626 // EncodedBranchOffset(cccc101l000000000000000000000000, Offset);
584 if (!isConditionDefined(Cond)) 627 verifyCondDefined(Cond, InstName);
585 return setNeedsTextFixup();
586 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 628 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
587 IValueT Encoding = static_cast<int32_t>(Cond) << kConditionShift | 629 IValueT Encoding = static_cast<int32_t>(Cond) << kConditionShift |
588 5 << kTypeShift | (Link ? 1 : 0) << kLinkShift; 630 5 << kTypeShift | (Link ? 1 : 0) << kLinkShift;
589 Encoding = encodeBranchOffset(Offset, Encoding); 631 Encoding = encodeBranchOffset(Offset, Encoding);
590 emitInst(Encoding); 632 emitInst(Encoding);
591 } 633 }
592 634
593 void AssemblerARM32::emitBranch(Label *L, CondARM32::Cond Cond, bool Link) { 635 void AssemblerARM32::emitBranch(Label *L, CondARM32::Cond Cond, bool Link) {
594 // TODO(kschimpf): Handle far jumps. 636 // TODO(kschimpf): Handle far jumps.
637 constexpr const char *BranchName = "b";
595 if (L->isBound()) { 638 if (L->isBound()) {
596 const int32_t Dest = L->getPosition() - Buffer.size(); 639 const int32_t Dest = L->getPosition() - Buffer.size();
597 emitType05(Cond, Dest, Link); 640 emitType05(Cond, Dest, Link, BranchName);
598 return; 641 return;
599 } 642 }
600 const IOffsetT Position = Buffer.size(); 643 const IOffsetT Position = Buffer.size();
601 // Use the offset field of the branch instruction for linking the sites. 644 // Use the offset field of the branch instruction for linking the sites.
602 emitType05(Cond, L->getEncodedPosition(), Link); 645 emitType05(Cond, L->getEncodedPosition(), Link, BranchName);
603 if (!needsTextFixup()) 646 if (!needsTextFixup())
604 L->linkTo(Position); 647 L->linkTo(Position);
605 } 648 }
606 649
607 void AssemblerARM32::emitCompareOp(IValueT Opcode, const Operand *OpRn, 650 void AssemblerARM32::emitCompareOp(CondARM32::Cond Cond, IValueT Opcode,
608 const Operand *OpSrc1, 651 const Operand *OpRn, const Operand *OpSrc1,
609 CondARM32::Cond Cond) { 652 const char *InstName) {
610 // XXX (register) 653 // XXX (register)
611 // XXX<c> <Rn>, <Rm>{, <shift>} 654 // XXX<c> <Rn>, <Rm>{, <shift>}
612 // 655 //
613 // ccccyyyxxxx1nnnn0000iiiiitt0mmmm where cccc=Cond, nnnn=Rn, mmmm=Rm, iiiii 656 // ccccyyyxxxx1nnnn0000iiiiitt0mmmm where cccc=Cond, nnnn=Rn, mmmm=Rm, iiiii
614 // defines shift constant, tt=ShiftKind, yyy=kInstTypeDataRegister, and 657 // defines shift constant, tt=ShiftKind, yyy=kInstTypeDataRegister, and
615 // xxxx=Opcode. 658 // xxxx=Opcode.
616 // 659 //
617 // XXX (immediate) 660 // XXX (immediate)
618 // XXX<c> <Rn>, #<RotatedImm8> 661 // XXX<c> <Rn>, #<RotatedImm8>
619 // 662 //
620 // ccccyyyxxxx1nnnn0000iiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn, 663 // ccccyyyxxxx1nnnn0000iiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn,
621 // yyy=kInstTypeDataImmdiate, xxxx=Opcode, and iiiiiiiiiiii=Src1Value 664 // yyy=kInstTypeDataImmdiate, xxxx=Opcode, and iiiiiiiiiiii=Src1Value
622 // defining RotatedImm8. 665 // defining RotatedImm8.
623 constexpr bool SetFlags = true; 666 constexpr bool SetFlags = true;
624 constexpr IValueT Rd = RegARM32::Encoded_Reg_r0; 667 constexpr IValueT Rd = RegARM32::Encoded_Reg_r0;
625 IValueT Rn; 668 IValueT Rn = encodeRegister(OpRn, "Rn", InstName);
626 if (encodeOperand(OpRn, Rn) != EncodedAsRegister) 669 emitType01(Cond, Opcode, Rd, Rn, OpSrc1, SetFlags, NoChecks, InstName);
627 return setNeedsTextFixup();
628 emitType01(Opcode, Rd, Rn, OpSrc1, SetFlags, Cond, NoChecks);
629 } 670 }
630 671
631 void AssemblerARM32::emitMemOp(CondARM32::Cond Cond, IValueT InstType, 672 void AssemblerARM32::emitMemOp(CondARM32::Cond Cond, IValueT InstType,
632 bool IsLoad, bool IsByte, IValueT Rt, 673 bool IsLoad, bool IsByte, IValueT Rt,
633 IValueT Address) { 674 IValueT Address, const char *InstName) {
634 if (!isGPRRegisterDefined(Rt) || !isConditionDefined(Cond)) 675 verifyRegDefined(Rt, "Rt", InstName);
635 return setNeedsTextFixup(); 676 verifyCondDefined(Cond, InstName);
636 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 677 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
637 const IValueT Encoding = (encodeCondition(Cond) << kConditionShift) | 678 const IValueT Encoding = (encodeCondition(Cond) << kConditionShift) |
638 (InstType << kTypeShift) | (IsLoad ? L : 0) | 679 (InstType << kTypeShift) | (IsLoad ? L : 0) |
639 (IsByte ? B : 0) | (Rt << kRdShift) | Address; 680 (IsByte ? B : 0) | (Rt << kRdShift) | Address;
640 emitInst(Encoding); 681 emitInst(Encoding);
641 } 682 }
642 683
643 void AssemblerARM32::emitMemOp(CondARM32::Cond Cond, bool IsLoad, bool IsByte, 684 void AssemblerARM32::emitMemOp(CondARM32::Cond Cond, bool IsLoad, bool IsByte,
644 IValueT Rt, const Operand *OpAddress, 685 IValueT Rt, const Operand *OpAddress,
645 const TargetInfo &TInfo) { 686 const TargetInfo &TInfo, const char *InstName) {
646 IValueT Address; 687 IValueT Address;
647 switch (encodeAddress(OpAddress, Address, TInfo)) { 688 switch (encodeAddress(OpAddress, Address, TInfo)) {
648 default: 689 default:
649 return setNeedsTextFixup(); 690 llvm::report_fatal_error(std::string(InstName) +
691 ": Memory address not understood");
650 case EncodedAsImmRegOffset: { 692 case EncodedAsImmRegOffset: {
651 // XXX{B} (immediate): 693 // XXX{B} (immediate):
652 // xxx{b}<c> <Rt>, [<Rn>{, #+/-<imm12>}] ; p=1, w=0 694 // xxx{b}<c> <Rt>, [<Rn>{, #+/-<imm12>}] ; p=1, w=0
653 // xxx{b}<c> <Rt>, [<Rn>], #+/-<imm12> ; p=1, w=1 695 // xxx{b}<c> <Rt>, [<Rn>], #+/-<imm12> ; p=1, w=1
654 // xxx{b}<c> <Rt>, [<Rn>, #+/-<imm12>]! ; p=0, w=1 696 // xxx{b}<c> <Rt>, [<Rn>, #+/-<imm12>]! ; p=0, w=1
655 // 697 //
656 // cccc010pubwlnnnnttttiiiiiiiiiiii where cccc=Cond, tttt=Rt, nnnn=Rn, 698 // cccc010pubwlnnnnttttiiiiiiiiiiii where cccc=Cond, tttt=Rt, nnnn=Rn,
657 // iiiiiiiiiiii=imm12, b=IsByte, pu0w<<21 is a BlockAddr, l=IsLoad, and 699 // iiiiiiiiiiii=imm12, b=IsByte, pu0w<<21 is a BlockAddr, l=IsLoad, and
658 // pu0w0nnnn0000iiiiiiiiiiii=Address. 700 // pu0w0nnnn0000iiiiiiiiiiii=Address.
659 RegARM32::GPRRegister Rn = getGPRReg(kRnShift, Address); 701 RegARM32::GPRRegister Rn = getGPRReg(kRnShift, Address);
660 702
661 // Check if conditions of rules violated. 703 // Check if conditions of rules violated.
662 if (Rn == RegARM32::Encoded_Reg_pc) 704 verifyRegNotPc(Rn, "Rn", InstName);
663 return setNeedsTextFixup(); 705 verifyNot_NotPAndW(Address, InstName);
664 if (!isBitSet(P, Address) && isBitSet(W, Address))
665 return setNeedsTextFixup();
666 if (!IsByte && (Rn == RegARM32::Encoded_Reg_sp) && !isBitSet(P, Address) && 706 if (!IsByte && (Rn == RegARM32::Encoded_Reg_sp) && !isBitSet(P, Address) &&
667 isBitSet(U, Address) & !isBitSet(W, Address) && 707 isBitSet(U, Address) && !isBitSet(W, Address) &&
668 (mask(Address, kImm12Shift, kImmed12Bits) == 0x8 /* 000000000100 */)) 708 (mask(Address, kImm12Shift, kImmed12Bits) == 0x8 /* 000000000100 */))
669 return setNeedsTextFixup(); 709 llvm::report_fatal_error(std::string(InstName) +
710 ": Use push/pop instead");
670 711
671 return emitMemOp(Cond, kInstTypeMemImmediate, IsLoad, IsByte, Rt, Address); 712 return emitMemOp(Cond, kInstTypeMemImmediate, IsLoad, IsByte, Rt, Address,
713 InstName);
672 } 714 }
673 case EncodedAsShiftRotateImm5: { 715 case EncodedAsShiftRotateImm5: {
674 // XXX{B} (register) 716 // XXX{B} (register)
675 // xxx{b}<c> <Rt>, [<Rn>, +/-<Rm>{, <shift>}]{!} 717 // xxx{b}<c> <Rt>, [<Rn>, +/-<Rm>{, <shift>}]{!}
676 // xxx{b}<c> <Rt>, [<Rn>], +/-<Rm>{, <shift>} 718 // xxx{b}<c> <Rt>, [<Rn>], +/-<Rm>{, <shift>}
677 // 719 //
678 // cccc011pubwlnnnnttttiiiiiss0mmmm where cccc=Cond, tttt=Rt, 720 // cccc011pubwlnnnnttttiiiiiss0mmmm where cccc=Cond, tttt=Rt,
679 // b=IsByte, U=1 if +, pu0b is a BlockAddr, l=IsLoad, and 721 // b=IsByte, U=1 if +, pu0b is a BlockAddr, l=IsLoad, and
680 // pu0w0nnnn0000iiiiiss0mmmm=Address. 722 // pu0w0nnnn0000iiiiiss0mmmm=Address.
681 RegARM32::GPRRegister Rn = getGPRReg(kRnShift, Address); 723 RegARM32::GPRRegister Rn = getGPRReg(kRnShift, Address);
682 RegARM32::GPRRegister Rm = getGPRReg(kRmShift, Address); 724 RegARM32::GPRRegister Rm = getGPRReg(kRmShift, Address);
683 725
684 // Check if conditions of rules violated. 726 // Check if conditions of rules violated.
685 if (isBitSet(P, Address) && isBitSet(W, Address)) 727 verifyNot_NotPAndW(Address, InstName);
686 // Instruction XXXBT! 728 verifyRegNotPc(Rm, "Rm", InstName);
687 return setNeedsTextFixup(); 729 if (IsByte)
688 if (IsByte && 730 verifyRegNotPc(Rt, "Rt", InstName);
689 ((Rt == RegARM32::Encoded_Reg_pc) || (Rm == RegARM32::Encoded_Reg_pc))) 731 if (isBitSet(W, Address)) {
690 // Unpredictable. 732 verifyRegNotPc(Rn, "Rn", InstName);
691 return setNeedsTextFixup(); 733 verifyRegsNotEq(Rn, "Rn", Rt, "Rt", InstName);
692 if (!IsByte && Rm == RegARM32::Encoded_Reg_pc) 734 }
693 // Unpredictable. 735 return emitMemOp(Cond, kInstTypeRegisterShift, IsLoad, IsByte, Rt, Address,
694 return setNeedsTextFixup(); 736 InstName);
695 if (isBitSet(W, Address) &&
696 ((Rn == RegARM32::Encoded_Reg_pc) || encodeGPRRegister(Rn) == Rt))
697 // Unpredictable
698 return setNeedsTextFixup();
699
700 return emitMemOp(Cond, kInstTypeRegisterShift, IsLoad, IsByte, Rt, Address);
701 } 737 }
702 } 738 }
703 } 739 }
704 740
705 void AssemblerARM32::emitMemOpEnc3(CondARM32::Cond Cond, IValueT Opcode, 741 void AssemblerARM32::emitMemOpEnc3(CondARM32::Cond Cond, IValueT Opcode,
706 IValueT Rt, const Operand *OpAddress, 742 IValueT Rt, const Operand *OpAddress,
707 const TargetInfo &TInfo) { 743 const TargetInfo &TInfo,
744 const char *InstName) {
708 IValueT Address; 745 IValueT Address;
709 switch (encodeAddress(OpAddress, Address, TInfo, OpEncoding3)) { 746 switch (encodeAddress(OpAddress, Address, TInfo, OpEncoding3)) {
710 default: 747 default:
711 return setNeedsTextFixup(); 748 llvm::report_fatal_error(std::string(InstName) +
749 ": Memory address not understood");
712 case EncodedAsImmRegOffsetEnc3: { 750 case EncodedAsImmRegOffsetEnc3: {
713 // XXXH (immediate) 751 // XXXH (immediate)
714 // xxxh<c> <Rt>, [<Rn>{, #+-<Imm8>}] 752 // xxxh<c> <Rt>, [<Rn>{, #+-<Imm8>}]
715 // xxxh<c> <Rt>, [<Rn>, #+/-<Imm8>] 753 // xxxh<c> <Rt>, [<Rn>, #+/-<Imm8>]
716 // xxxh<c> <Rt>, [<Rn>, #+/-<Imm8>]! 754 // xxxh<c> <Rt>, [<Rn>, #+/-<Imm8>]!
717 // 755 //
718 // cccc000pu0wxnnnnttttiiiiyyyyjjjj where cccc=Cond, nnnn=Rn, tttt=Rt, 756 // cccc000pu0wxnnnnttttiiiiyyyyjjjj where cccc=Cond, nnnn=Rn, tttt=Rt,
719 // iiiijjjj=Imm8, pu0w<<21 is a BlockAddr, x000000000000yyyy0000=Opcode, 757 // iiiijjjj=Imm8, pu0w<<21 is a BlockAddr, x000000000000yyyy0000=Opcode,
720 // and pu0w0nnnn0000iiii0000jjjj=Address. 758 // and pu0w0nnnn0000iiii0000jjjj=Address.
721 if (!isGPRRegisterDefined(Rt) || !isConditionDefined(Cond)) 759 verifyRegDefined(Rt, "Rt", InstName);
722 return setNeedsTextFixup(); 760 verifyCondDefined(Cond, InstName);
723 if (!isBitSet(P, Address) && isBitSet(W, Address)) 761 verifyNot_NotPAndW(Address, InstName);
724 return setNeedsTextFixup(); 762 verifyRegNotPc(Rt, "Rt", InstName);
725 if ((Rt == RegARM32::Encoded_Reg_pc) || 763 if (isBitSet(W, Address))
726 (isBitSet(W, Address) && 764 verifyRegsNotEq(getGPRReg(kRnShift, Address), "Rn", Rt, "Rt", InstName);
727 (getGPRReg(kRnShift, Address) == decodeGPRRegister(Rt))))
728 return setNeedsTextFixup();
729 const IValueT Encoding = (encodeCondition(Cond) << kConditionShift) | 765 const IValueT Encoding = (encodeCondition(Cond) << kConditionShift) |
730 Opcode | (Rt << kRdShift) | Address; 766 Opcode | (Rt << kRdShift) | Address;
731 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 767 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
732 return emitInst(Encoding); 768 return emitInst(Encoding);
733 } 769 }
734 case EncodedAsShiftRotateImm5: { 770 case EncodedAsShiftRotateImm5: {
735 // XXXH (register) 771 // XXXH (register)
736 // xxxh<c> <Rt>, [<Rn>, +/-<Rm>]{!} 772 // xxxh<c> <Rt>, [<Rn>, +/-<Rm>]{!}
737 // xxxh<c> <Rt>, [<Rn>], +/-<Rm> 773 // xxxh<c> <Rt>, [<Rn>], +/-<Rm>
738 // 774 //
739 // cccc000pu0wxnnnntttt00001011mmmm where cccc=Cond, tttt=Rt, nnnn=Rn, 775 // cccc000pu0wxnnnntttt00001011mmmm where cccc=Cond, tttt=Rt, nnnn=Rn,
740 // mmmm=Rm, pu0w<<21 is a BlockAddr, x000000000000yyyy0000=Opcode, and 776 // mmmm=Rm, pu0w<<21 is a BlockAddr, x000000000000yyyy0000=Opcode, and
741 // pu0w0nnnn000000000000mmmm=Address. 777 // pu0w0nnnn000000000000mmmm=Address.
742 if (!isGPRRegisterDefined(Rt) || !isConditionDefined(Cond)) 778 verifyRegDefined(Rt, "Rt", InstName);
743 return setNeedsTextFixup(); 779 verifyCondDefined(Cond, InstName);
744 if (!isBitSet(P, Address) && isBitSet(W, Address)) 780 verifyNot_NotPAndW(Address, InstName);
745 return setNeedsTextFixup(); 781 verifyRegNotPc(Rt, "Rt", InstName);
746 if (Rt == RegARM32::Encoded_Reg_pc) 782 verifyAddrRegNotPc(kRmShift, Address, "Rm", InstName);
747 return setNeedsTextFixup();
748 if (getGPRReg(kRmShift, Address) == RegARM32::Encoded_Reg_pc)
749 return setNeedsTextFixup();
750 const RegARM32::GPRRegister Rn = getGPRReg(kRnShift, Address); 783 const RegARM32::GPRRegister Rn = getGPRReg(kRnShift, Address);
751 if (isBitSet(W, Address) && 784 if (isBitSet(W, Address)) {
752 ((Rn == RegARM32::Encoded_Reg_pc) || (encodeGPRRegister(Rn) == Rt))) 785 verifyRegNotPc(Rn, "Rn", InstName);
753 return setNeedsTextFixup(); 786 verifyRegsNotEq(Rn, "Rn", Rt, "Rt", InstName);
787 }
754 if (mask(Address, kShiftImmShift, 5) != 0) 788 if (mask(Address, kShiftImmShift, 5) != 0)
755 // For encoding 3, no shift is allowed. 789 // For encoding 3, no shift is allowed.
756 return setNeedsTextFixup(); 790 llvm::report_fatal_error(std::string(InstName) +
791 ": Shift constant not allowed");
757 const IValueT Encoding = (encodeCondition(Cond) << kConditionShift) | 792 const IValueT Encoding = (encodeCondition(Cond) << kConditionShift) |
758 Opcode | (Rt << kRdShift) | Address; 793 Opcode | (Rt << kRdShift) | Address;
759 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 794 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
760 return emitInst(Encoding); 795 return emitInst(Encoding);
761 } 796 }
762 } 797 }
763 } 798 }
764 799
765 void AssemblerARM32::emitDivOp(CondARM32::Cond Cond, IValueT Opcode, IValueT Rd, 800 void AssemblerARM32::emitDivOp(CondARM32::Cond Cond, IValueT Opcode, IValueT Rd,
766 IValueT Rn, IValueT Rm) { 801 IValueT Rn, IValueT Rm, const char *InstName) {
767 if (!isGPRRegisterDefined(Rd) || !isGPRRegisterDefined(Rn) || 802 verifyRegDefined(Rd, "Rd", InstName);
768 !isGPRRegisterDefined(Rm) || !isConditionDefined(Cond)) 803 verifyRegDefined(Rn, "Rn", InstName);
769 return setNeedsTextFixup(); 804 verifyRegDefined(Rm, "Rm", InstName);
805 verifyCondDefined(Cond, InstName);
770 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 806 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
771 const IValueT Encoding = Opcode | (encodeCondition(Cond) << kConditionShift) | 807 const IValueT Encoding = Opcode | (encodeCondition(Cond) << kConditionShift) |
772 (Rn << kDivRnShift) | (Rd << kDivRdShift) | B26 | 808 (Rn << kDivRnShift) | (Rd << kDivRdShift) | B26 |
773 B25 | B24 | B20 | B15 | B14 | B13 | B12 | B4 | 809 B25 | B24 | B20 | B15 | B14 | B13 | B12 | B4 |
774 (Rm << kDivRmShift); 810 (Rm << kDivRmShift);
775 emitInst(Encoding); 811 emitInst(Encoding);
776 } 812 }
777 813
778 void AssemblerARM32::emitMulOp(CondARM32::Cond Cond, IValueT Opcode, IValueT Rd, 814 void AssemblerARM32::emitMulOp(CondARM32::Cond Cond, IValueT Opcode, IValueT Rd,
779 IValueT Rn, IValueT Rm, IValueT Rs, 815 IValueT Rn, IValueT Rm, IValueT Rs,
780 bool SetFlags) { 816 bool SetFlags, const char *InstName) {
781 if (!isGPRRegisterDefined(Rd) || !isGPRRegisterDefined(Rn) || 817 verifyRegDefined(Rd, "Rd", InstName);
782 !isGPRRegisterDefined(Rm) || !isGPRRegisterDefined(Rs) || 818 verifyRegDefined(Rn, "Rn", InstName);
783 !isConditionDefined(Cond)) 819 verifyRegDefined(Rm, "Rm", InstName);
784 return setNeedsTextFixup(); 820 verifyRegDefined(Rs, "Rs", InstName);
821 verifyCondDefined(Cond, InstName);
785 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 822 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
786 IValueT Encoding = Opcode | (encodeCondition(Cond) << kConditionShift) | 823 IValueT Encoding = Opcode | (encodeCondition(Cond) << kConditionShift) |
787 (encodeBool(SetFlags) << kSShift) | (Rn << kRnShift) | 824 (encodeBool(SetFlags) << kSShift) | (Rn << kRnShift) |
788 (Rd << kRdShift) | (Rs << kRsShift) | B7 | B4 | 825 (Rd << kRdShift) | (Rs << kRsShift) | B7 | B4 |
789 (Rm << kRmShift); 826 (Rm << kRmShift);
790 emitInst(Encoding); 827 emitInst(Encoding);
791 } 828 }
792 829
793 void AssemblerARM32::emitUxt(CondARM32::Cond Cond, IValueT Opcode, IValueT Rd, 830 void AssemblerARM32::emitUxt(CondARM32::Cond Cond, IValueT Opcode, IValueT Rd,
794 IValueT Rn, IValueT Rm, RotationValue Rotation) { 831 IValueT Rn, IValueT Rm, RotationValue Rotation,
832 const char *InstName) {
833 verifyCondDefined(Cond, InstName);
795 IValueT Rot = encodeRotation(Rotation); 834 IValueT Rot = encodeRotation(Rotation);
796 if (!isConditionDefined(Cond) || !Utils::IsUint(2, Rot)) 835 if (!Utils::IsUint(2, Rot))
797 return setNeedsTextFixup(); 836 llvm::report_fatal_error(std::string(InstName) +
837 ": Illegal rotation value");
798 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 838 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
799 IValueT Encoding = (encodeCondition(Cond) << kConditionShift) | Opcode | 839 IValueT Encoding = (encodeCondition(Cond) << kConditionShift) | Opcode |
800 (Rn << kRnShift) | (Rd << kRdShift) | 840 (Rn << kRnShift) | (Rd << kRdShift) |
801 (Rot << kRotationShift) | B6 | B5 | B4 | (Rm << kRmShift); 841 (Rot << kRotationShift) | B6 | B5 | B4 | (Rm << kRmShift);
802 emitInst(Encoding); 842 emitInst(Encoding);
803 } 843 }
804 844
805 void AssemblerARM32::emitMultiMemOp(CondARM32::Cond Cond, 845 void AssemblerARM32::emitMultiMemOp(CondARM32::Cond Cond,
806 BlockAddressMode AddressMode, bool IsLoad, 846 BlockAddressMode AddressMode, bool IsLoad,
807 IValueT BaseReg, IValueT Registers) { 847 IValueT BaseReg, IValueT Registers,
848 const char *InstName) {
808 constexpr IValueT NumGPRegisters = 16; 849 constexpr IValueT NumGPRegisters = 16;
809 if (!isConditionDefined(Cond) || !isGPRRegisterDefined(BaseReg) || 850 verifyCondDefined(Cond, InstName);
810 Registers >= (1 << NumGPRegisters)) 851 verifyRegDefined(BaseReg, "base", InstName);
811 return setNeedsTextFixup(); 852 if (Registers >= (1 << NumGPRegisters))
853 llvm::report_fatal_error(std::string(InstName) +
854 ": Register set too large");
812 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 855 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
813 IValueT Encoding = (encodeCondition(Cond) << kConditionShift) | B27 | 856 IValueT Encoding = (encodeCondition(Cond) << kConditionShift) | B27 |
814 AddressMode | (IsLoad ? L : 0) | (BaseReg << kRnShift) | 857 AddressMode | (IsLoad ? L : 0) | (BaseReg << kRnShift) |
815 Registers; 858 Registers;
816 emitInst(Encoding); 859 emitInst(Encoding);
817 } 860 }
818 861
819 void AssemblerARM32::adc(const Operand *OpRd, const Operand *OpRn, 862 void AssemblerARM32::adc(const Operand *OpRd, const Operand *OpRn,
820 const Operand *OpSrc1, bool SetFlags, 863 const Operand *OpSrc1, bool SetFlags,
821 CondARM32::Cond Cond) { 864 CondARM32::Cond Cond) {
822 // ADC (register) - ARM section 18.8.2, encoding A1: 865 // ADC (register) - ARM section 18.8.2, encoding A1:
823 // adc{s}<c> <Rd>, <Rn>, <Rm>{, <shift>} 866 // adc{s}<c> <Rd>, <Rn>, <Rm>{, <shift>}
824 // 867 //
825 // cccc0000101snnnnddddiiiiitt0mmmm where cccc=Cond, dddd=Rd, nnnn=Rn, 868 // cccc0000101snnnnddddiiiiitt0mmmm where cccc=Cond, dddd=Rd, nnnn=Rn,
826 // mmmm=Rm, iiiii=Shift, tt=ShiftKind, and s=SetFlags. 869 // mmmm=Rm, iiiii=Shift, tt=ShiftKind, and s=SetFlags.
827 // 870 //
828 // ADC (Immediate) - ARM section A8.8.1, encoding A1: 871 // ADC (Immediate) - ARM section A8.8.1, encoding A1:
829 // adc{s}<c> <Rd>, <Rn>, #<RotatedImm8> 872 // adc{s}<c> <Rd>, <Rn>, #<RotatedImm8>
830 // 873 //
831 // cccc0010101snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn, 874 // cccc0010101snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn,
832 // s=SetFlags and iiiiiiiiiiii=Src1Value defining RotatedImm8. 875 // s=SetFlags and iiiiiiiiiiii=Src1Value defining RotatedImm8.
833 constexpr IValueT Adc = B2 | B0; // 0101 876 constexpr const char *AdcName = "adc";
Jim Stichnoth 2015/12/03 21:19:50 Too bad you can't easily reuse e.g. InstARM32Adc::
Karl 2015/12/03 23:52:58 Acknowledged.
834 emitType01(Adc, OpRd, OpRn, OpSrc1, SetFlags, Cond, RdIsPcAndSetFlags); 877 constexpr IValueT AdcOpcode = B2 | B0; // 0101
878 emitType01(Cond, AdcOpcode, OpRd, OpRn, OpSrc1, SetFlags, RdIsPcAndSetFlags,
879 AdcName);
835 } 880 }
836 881
837 void AssemblerARM32::add(const Operand *OpRd, const Operand *OpRn, 882 void AssemblerARM32::add(const Operand *OpRd, const Operand *OpRn,
838 const Operand *OpSrc1, bool SetFlags, 883 const Operand *OpSrc1, bool SetFlags,
839 CondARM32::Cond Cond) { 884 CondARM32::Cond Cond) {
840 // ADD (register) - ARM section A8.8.7, encoding A1: 885 // ADD (register) - ARM section A8.8.7, encoding A1:
841 // add{s}<c> <Rd>, <Rn>, <Rm>{, <shiff>} 886 // add{s}<c> <Rd>, <Rn>, <Rm>{, <shiff>}
842 // ADD (Sp plus register) - ARM section A8.8.11, encoding A1: 887 // ADD (Sp plus register) - ARM section A8.8.11, encoding A1:
843 // add{s}<c> sp, <Rn>, <Rm>{, <shiff>} 888 // add{s}<c> sp, <Rn>, <Rm>{, <shiff>}
844 // 889 //
845 // cccc0000100snnnnddddiiiiitt0mmmm where cccc=Cond, dddd=Rd, nnnn=Rn, 890 // cccc0000100snnnnddddiiiiitt0mmmm where cccc=Cond, dddd=Rd, nnnn=Rn,
846 // mmmm=Rm, iiiii=Shift, tt=ShiftKind, and s=SetFlags. 891 // mmmm=Rm, iiiii=Shift, tt=ShiftKind, and s=SetFlags.
847 // 892 //
848 // ADD (Immediate) - ARM section A8.8.5, encoding A1: 893 // ADD (Immediate) - ARM section A8.8.5, encoding A1:
849 // add{s}<c> <Rd>, <Rn>, #<RotatedImm8> 894 // add{s}<c> <Rd>, <Rn>, #<RotatedImm8>
850 // ADD (SP plus immediate) - ARM section A8.8.9, encoding A1. 895 // ADD (SP plus immediate) - ARM section A8.8.9, encoding A1.
851 // add{s}<c> <Rd>, sp, #<RotatedImm8> 896 // add{s}<c> <Rd>, sp, #<RotatedImm8>
852 // 897 //
853 // cccc0010100snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn, 898 // cccc0010100snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn,
854 // s=SetFlags and iiiiiiiiiiii=Src1Value defining RotatedImm8. 899 // s=SetFlags and iiiiiiiiiiii=Src1Value defining RotatedImm8.
900 constexpr const char *AddName = "add";
855 constexpr IValueT Add = B2; // 0100 901 constexpr IValueT Add = B2; // 0100
856 emitType01(Add, OpRd, OpRn, OpSrc1, SetFlags, Cond, RdIsPcAndSetFlags); 902 emitType01(Cond, Add, OpRd, OpRn, OpSrc1, SetFlags, RdIsPcAndSetFlags,
903 AddName);
857 } 904 }
858 905
859 void AssemblerARM32::and_(const Operand *OpRd, const Operand *OpRn, 906 void AssemblerARM32::and_(const Operand *OpRd, const Operand *OpRn,
860 const Operand *OpSrc1, bool SetFlags, 907 const Operand *OpSrc1, bool SetFlags,
861 CondARM32::Cond Cond) { 908 CondARM32::Cond Cond) {
862 // AND (register) - ARM section A8.8.14, encoding A1: 909 // AND (register) - ARM section A8.8.14, encoding A1:
863 // and{s}<c> <Rd>, <Rn>{, <shift>} 910 // and{s}<c> <Rd>, <Rn>{, <shift>}
864 // 911 //
865 // cccc0000000snnnnddddiiiiitt0mmmm where cccc=Cond, dddd=Rd, nnnn=Rn, 912 // cccc0000000snnnnddddiiiiitt0mmmm where cccc=Cond, dddd=Rd, nnnn=Rn,
866 // mmmm=Rm, iiiii=Shift, tt=ShiftKind, and s=SetFlags. 913 // mmmm=Rm, iiiii=Shift, tt=ShiftKind, and s=SetFlags.
867 // 914 //
868 // AND (Immediate) - ARM section A8.8.13, encoding A1: 915 // AND (Immediate) - ARM section A8.8.13, encoding A1:
869 // and{s}<c> <Rd>, <Rn>, #<RotatedImm8> 916 // and{s}<c> <Rd>, <Rn>, #<RotatedImm8>
870 // 917 //
871 // cccc0010100snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn, 918 // cccc0010100snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn,
872 // s=SetFlags and iiiiiiiiiiii=Src1Value defining RotatedImm8. 919 // s=SetFlags and iiiiiiiiiiii=Src1Value defining RotatedImm8.
920 constexpr const char *AndName = "and";
873 constexpr IValueT And = 0; // 0000 921 constexpr IValueT And = 0; // 0000
874 emitType01(And, OpRd, OpRn, OpSrc1, SetFlags, Cond, RdIsPcAndSetFlags); 922 emitType01(Cond, And, OpRd, OpRn, OpSrc1, SetFlags, RdIsPcAndSetFlags,
923 AndName);
875 } 924 }
876 925
877 void AssemblerARM32::b(Label *L, CondARM32::Cond Cond) { 926 void AssemblerARM32::b(Label *L, CondARM32::Cond Cond) {
878 emitBranch(L, Cond, false); 927 emitBranch(L, Cond, false);
879 } 928 }
880 929
881 void AssemblerARM32::bkpt(uint16_t Imm16) { 930 void AssemblerARM32::bkpt(uint16_t Imm16) {
882 // BKPT - ARM section A*.8.24 - encoding A1: 931 // BKPT - ARM section A*.8.24 - encoding A1:
883 // bkpt #<Imm16> 932 // bkpt #<Imm16>
884 // 933 //
(...skipping 11 matching lines...) Expand all
896 // bic{s}<c> <Rd>, <Rn>, <Rm>{, <shift>} 945 // bic{s}<c> <Rd>, <Rn>, <Rm>{, <shift>}
897 // 946 //
898 // cccc0001110snnnnddddiiiiitt0mmmm where cccc=Cond, dddd=Rd, nnnn=Rn, 947 // cccc0001110snnnnddddiiiiitt0mmmm where cccc=Cond, dddd=Rd, nnnn=Rn,
899 // mmmm=Rm, iiiii=Shift, tt=ShiftKind, and s=SetFlags. 948 // mmmm=Rm, iiiii=Shift, tt=ShiftKind, and s=SetFlags.
900 // 949 //
901 // BIC (immediate) - ARM section A8.8.21, encoding A1: 950 // BIC (immediate) - ARM section A8.8.21, encoding A1:
902 // bic{s}<c> <Rd>, <Rn>, #<RotatedImm8> 951 // bic{s}<c> <Rd>, <Rn>, #<RotatedImm8>
903 // 952 //
904 // cccc0011110snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rn, nnnn=Rn, 953 // cccc0011110snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rn, nnnn=Rn,
905 // s=SetFlags, and iiiiiiiiiiii=Src1Value defining RotatedImm8. 954 // s=SetFlags, and iiiiiiiiiiii=Src1Value defining RotatedImm8.
906 IValueT Opcode = B3 | B2 | B1; // i.e. 1110 955 constexpr const char *BicName = "bic";
907 emitType01(Opcode, OpRd, OpRn, OpSrc1, SetFlags, Cond, RdIsPcAndSetFlags); 956 constexpr IValueT BicOpcode = B3 | B2 | B1; // i.e. 1110
957 emitType01(Cond, BicOpcode, OpRd, OpRn, OpSrc1, SetFlags, RdIsPcAndSetFlags,
958 BicName);
908 } 959 }
909 960
910 void AssemblerARM32::bl(const ConstantRelocatable *Target) { 961 void AssemblerARM32::bl(const ConstantRelocatable *Target) {
911 // BL (immediate) - ARM section A8.8.25, encoding A1: 962 // BL (immediate) - ARM section A8.8.25, encoding A1:
912 // bl<c> <label> 963 // bl<c> <label>
913 // 964 //
914 // cccc1011iiiiiiiiiiiiiiiiiiiiiiii where cccc=Cond (not currently allowed) 965 // cccc1011iiiiiiiiiiiiiiiiiiiiiiii where cccc=Cond (not currently allowed)
915 // and iiiiiiiiiiiiiiiiiiiiiiii is the (encoded) Target to branch to. 966 // and iiiiiiiiiiiiiiiiiiiiiiii is the (encoded) Target to branch to.
916 emitFixup(createBlFixup(Target)); 967 emitFixup(createBlFixup(Target));
968 constexpr const char *BlName = "bl";
917 constexpr CondARM32::Cond Cond = CondARM32::AL; 969 constexpr CondARM32::Cond Cond = CondARM32::AL;
918 constexpr IValueT Immed = 0; 970 constexpr IValueT Immed = 0;
919 constexpr bool Link = true; 971 constexpr bool Link = true;
920 emitType05(Cond, Immed, Link); 972 emitType05(Cond, Immed, Link, BlName);
921 } 973 }
922 974
923 void AssemblerARM32::blx(const Operand *Target) { 975 void AssemblerARM32::blx(const Operand *Target) {
924 IValueT Rm;
925 if (encodeOperand(Target, Rm) != EncodedAsRegister)
926 return setNeedsTextFixup();
927 // BLX (register) - ARM section A8.8.26, encoding A1: 976 // BLX (register) - ARM section A8.8.26, encoding A1:
928 // blx<c> <Rm> 977 // blx<c> <Rm>
929 // 978 //
930 // cccc000100101111111111110011mmmm where cccc=Cond (not currently allowed) 979 // cccc000100101111111111110011mmmm where cccc=Cond (not currently allowed)
931 // and mmmm=Rm. 980 // and mmmm=Rm.
932 if (Rm == RegARM32::Encoded_Reg_pc) 981 constexpr const char *BlxName = "Blx";
933 // Unpredictable. 982 IValueT Rm = encodeRegister(Target, "Rm", BlxName);
934 return setNeedsTextFixup(); 983 verifyRegNotPc(Rm, "Rm", BlxName);
935 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 984 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
936 constexpr CondARM32::Cond Cond = CondARM32::AL; 985 constexpr CondARM32::Cond Cond = CondARM32::AL;
937 int32_t Encoding = (encodeCondition(Cond) << kConditionShift) | B24 | B21 | 986 int32_t Encoding = (encodeCondition(Cond) << kConditionShift) | B24 | B21 |
938 (0xfff << 8) | B5 | B4 | (Rm << kRmShift); 987 (0xfff << 8) | B5 | B4 | (Rm << kRmShift);
939 emitInst(Encoding); 988 emitInst(Encoding);
940 } 989 }
941 990
942 void AssemblerARM32::bx(RegARM32::GPRRegister Rm, CondARM32::Cond Cond) { 991 void AssemblerARM32::bx(RegARM32::GPRRegister Rm, CondARM32::Cond Cond) {
943 // BX - ARM section A8.8.27, encoding A1: 992 // BX - ARM section A8.8.27, encoding A1:
944 // bx<c> <Rm> 993 // bx<c> <Rm>
945 // 994 //
946 // cccc000100101111111111110001mmmm where mmmm=rm and cccc=Cond. 995 // cccc000100101111111111110001mmmm where mmmm=rm and cccc=Cond.
947 if (!(isGPRRegisterDefined(Rm) && isConditionDefined(Cond))) 996 constexpr const char *BxName = "bx";
948 return setNeedsTextFixup(); 997 verifyCondDefined(Cond, BxName);
998 verifyRegDefined(Rm, "Rm", BxName);
949 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 999 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
950 const IValueT Encoding = (encodeCondition(Cond) << kConditionShift) | B24 | 1000 const IValueT Encoding = (encodeCondition(Cond) << kConditionShift) | B24 |
951 B21 | (0xfff << 8) | B4 | 1001 B21 | (0xfff << 8) | B4 |
952 (encodeGPRRegister(Rm) << kRmShift); 1002 (encodeGPRRegister(Rm) << kRmShift);
953 emitInst(Encoding); 1003 emitInst(Encoding);
954 } 1004 }
955 1005
956 void AssemblerARM32::cmp(const Operand *OpRn, const Operand *OpSrc1, 1006 void AssemblerARM32::cmp(const Operand *OpRn, const Operand *OpSrc1,
957 CondARM32::Cond Cond) { 1007 CondARM32::Cond Cond) {
958 // CMP (register) - ARM section A8.8.38, encoding A1: 1008 // CMP (register) - ARM section A8.8.38, encoding A1:
959 // cmp<c> <Rn>, <Rm>{, <shift>} 1009 // cmp<c> <Rn>, <Rm>{, <shift>}
960 // 1010 //
961 // cccc00010101nnnn0000iiiiitt0mmmm where cccc=Cond, nnnn=Rn, mmmm=Rm, 1011 // cccc00010101nnnn0000iiiiitt0mmmm where cccc=Cond, nnnn=Rn, mmmm=Rm,
962 // iiiii=Shift, and tt=ShiftKind. 1012 // iiiii=Shift, and tt=ShiftKind.
963 // 1013 //
964 // CMP (immediate) - ARM section A8.8.37 1014 // CMP (immediate) - ARM section A8.8.37
965 // cmp<c: <Rn>, #<RotatedImm8> 1015 // cmp<c: <Rn>, #<RotatedImm8>
966 // 1016 //
967 // cccc00110101nnnn0000iiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn, 1017 // cccc00110101nnnn0000iiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn,
968 // s=SetFlags and iiiiiiiiiiii=Src1Value defining RotatedImm8. 1018 // s=SetFlags and iiiiiiiiiiii=Src1Value defining RotatedImm8.
969 constexpr IValueT Opcode = B3 | B1; // ie. 1010 1019 constexpr const char *CmpName = "cmp";
970 emitCompareOp(Opcode, OpRn, OpSrc1, Cond); 1020 constexpr IValueT CmpOpcode = B3 | B1; // ie. 1010
1021 emitCompareOp(Cond, CmpOpcode, OpRn, OpSrc1, CmpName);
971 } 1022 }
972 1023
973 void AssemblerARM32::eor(const Operand *OpRd, const Operand *OpRn, 1024 void AssemblerARM32::eor(const Operand *OpRd, const Operand *OpRn,
974 const Operand *OpSrc1, bool SetFlags, 1025 const Operand *OpSrc1, bool SetFlags,
975 CondARM32::Cond Cond) { 1026 CondARM32::Cond Cond) {
976 // EOR (register) - ARM section A*.8.47, encoding A1: 1027 // EOR (register) - ARM section A*.8.47, encoding A1:
977 // eor{s}<c> <Rd>, <Rn>, <Rm>{, <shift>} 1028 // eor{s}<c> <Rd>, <Rn>, <Rm>{, <shift>}
978 // 1029 //
979 // cccc0000001snnnnddddiiiiitt0mmmm where cccc=Cond, dddd=Rd, nnnn=Rn, 1030 // cccc0000001snnnnddddiiiiitt0mmmm where cccc=Cond, dddd=Rd, nnnn=Rn,
980 // mmmm=Rm, iiiii=Shift, tt=ShiftKind, and s=SetFlags. 1031 // mmmm=Rm, iiiii=Shift, tt=ShiftKind, and s=SetFlags.
981 // 1032 //
982 // EOR (Immediate) - ARM section A8.*.46, encoding A1: 1033 // EOR (Immediate) - ARM section A8.*.46, encoding A1:
983 // eor{s}<c> <Rd>, <Rn>, #RotatedImm8 1034 // eor{s}<c> <Rd>, <Rn>, #RotatedImm8
984 // 1035 //
985 // cccc0010001snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn, 1036 // cccc0010001snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn,
986 // s=SetFlags and iiiiiiiiiiii=Src1Value defining RotatedImm8. 1037 // s=SetFlags and iiiiiiiiiiii=Src1Value defining RotatedImm8.
987 constexpr IValueT Eor = B0; // 0001 1038 constexpr const char *EorName = "eor";
988 emitType01(Eor, OpRd, OpRn, OpSrc1, SetFlags, Cond, RdIsPcAndSetFlags); 1039 constexpr IValueT EorOpcode = B0; // 0001
1040 emitType01(Cond, EorOpcode, OpRd, OpRn, OpSrc1, SetFlags, RdIsPcAndSetFlags,
1041 EorName);
989 } 1042 }
990 1043
991 void AssemblerARM32::ldr(const Operand *OpRt, const Operand *OpAddress, 1044 void AssemblerARM32::ldr(const Operand *OpRt, const Operand *OpAddress,
992 CondARM32::Cond Cond, const TargetInfo &TInfo) { 1045 CondARM32::Cond Cond, const TargetInfo &TInfo) {
1046 constexpr const char *LdrName = "ldr";
993 constexpr bool IsLoad = true; 1047 constexpr bool IsLoad = true;
994 IValueT Rt; 1048 IValueT Rt = encodeRegister(OpRt, "Rt", LdrName);
995 if (encodeOperand(OpRt, Rt) != EncodedAsRegister)
996 return setNeedsTextFixup();
997 const Type Ty = OpRt->getType(); 1049 const Type Ty = OpRt->getType();
998 switch (typeWidthInBytesLog2(Ty)) { 1050 switch (typeWidthInBytesLog2(Ty)) {
999 case 3: 1051 case 3:
1000 // LDRD is not implemented because target lowering handles i64 and double by 1052 // LDRD is not implemented because target lowering handles i64 and double by
1001 // using two (32-bit) load instructions. Note: Intenionally drop to default 1053 // using two (32-bit) load instructions. Note: Intenionally drop to default
1002 // case. 1054 // case.
1003 default: 1055 default:
1004 llvm::report_fatal_error(std::string("Type ") + typeString(Ty) + 1056 llvm::report_fatal_error(std::string("ldr : Type ") + typeString(Ty) +
1005 " not implementable using ldr\n"); 1057 " not implementable\n");
1006 case 0: { 1058 case 0: {
1007 // Handles i1 and i8 loads. 1059 // Handles i1 and i8 loads.
1008 // 1060 //
1009 // LDRB (immediate) - ARM section A8.8.68, encoding A1: 1061 // LDRB (immediate) - ARM section A8.8.68, encoding A1:
1010 // ldrb<c> <Rt>, [<Rn>{, #+/-<imm12>}] ; p=1, w=0 1062 // ldrb<c> <Rt>, [<Rn>{, #+/-<imm12>}] ; p=1, w=0
1011 // ldrb<c> <Rt>, [<Rn>], #+/-<imm12> ; p=1, w=1 1063 // ldrb<c> <Rt>, [<Rn>], #+/-<imm12> ; p=1, w=1
1012 // ldrb<c> <Rt>, [<Rn>, #+/-<imm12>]! ; p=0, w=1 1064 // ldrb<c> <Rt>, [<Rn>, #+/-<imm12>]! ; p=0, w=1
1013 // 1065 //
1014 // cccc010pu1w1nnnnttttiiiiiiiiiiii where cccc=Cond, tttt=Rt, nnnn=Rn, 1066 // cccc010pu1w1nnnnttttiiiiiiiiiiii where cccc=Cond, tttt=Rt, nnnn=Rn,
1015 // iiiiiiiiiiii=imm12, u=1 if +, pu0w is a BlockAddr, and 1067 // iiiiiiiiiiii=imm12, u=1 if +, pu0w is a BlockAddr, and
1016 // pu0w0nnnn0000iiiiiiiiiiii=Address. 1068 // pu0w0nnnn0000iiiiiiiiiiii=Address.
1017 // 1069 //
1018 // LDRB (register) - ARM section A8.8.66, encoding A1: 1070 // LDRB (register) - ARM section A8.8.66, encoding A1:
1019 // ldrb<c> <Rt>, [<Rn>, +/-<Rm>{, <shift>}]{!} 1071 // ldrb<c> <Rt>, [<Rn>, +/-<Rm>{, <shift>}]{!}
1020 // ldrb<c> <Rt>, [<Rn>], +/-<Rm>{, <shift>} 1072 // ldrb<c> <Rt>, [<Rn>], +/-<Rm>{, <shift>}
1021 // 1073 //
1022 // cccc011pu1w1nnnnttttiiiiiss0mmmm where cccc=Cond, tttt=Rt, U=1 if +, pu0b 1074 // cccc011pu1w1nnnnttttiiiiiss0mmmm where cccc=Cond, tttt=Rt, U=1 if +, pu0b
1023 // is a BlockAddr, and pu0w0nnnn0000iiiiiss0mmmm=Address. 1075 // is a BlockAddr, and pu0w0nnnn0000iiiiiss0mmmm=Address.
1024 constexpr bool IsByte = true; 1076 constexpr bool IsByte = true;
1025 return emitMemOp(Cond, IsLoad, IsByte, Rt, OpAddress, TInfo); 1077 return emitMemOp(Cond, IsLoad, IsByte, Rt, OpAddress, TInfo, LdrName);
1026 } 1078 }
1027 case 1: { 1079 case 1: {
1028 // Handles i16 loads. 1080 // Handles i16 loads.
1029 // 1081 //
1030 // LDRH (immediate) - ARM section A8.8.80, encoding A1: 1082 // LDRH (immediate) - ARM section A8.8.80, encoding A1:
1031 // ldrh<c> <Rt>, [<Rn>{, #+/-<Imm8>}] 1083 // ldrh<c> <Rt>, [<Rn>{, #+/-<Imm8>}]
1032 // ldrh<c> <Rt>, [<Rn>], #+/-<Imm8> 1084 // ldrh<c> <Rt>, [<Rn>], #+/-<Imm8>
1033 // ldrh<c> <Rt>, [<Rn>, #+/-<Imm8>]! 1085 // ldrh<c> <Rt>, [<Rn>, #+/-<Imm8>]!
1034 // 1086 //
1035 // cccc000pu1w1nnnnttttiiii1011iiii where cccc=Cond, tttt=Rt, nnnn=Rn, 1087 // cccc000pu1w1nnnnttttiiii1011iiii where cccc=Cond, tttt=Rt, nnnn=Rn,
1036 // iiiiiiii=Imm8, u=1 if +, pu0w is a BlockAddr, and 1088 // iiiiiiii=Imm8, u=1 if +, pu0w is a BlockAddr, and
1037 // pu0w0nnnn0000iiiiiiiiiiii=Address. 1089 // pu0w0nnnn0000iiiiiiiiiiii=Address.
1038 return emitMemOpEnc3(Cond, L | B7 | B5 | B4, Rt, OpAddress, TInfo); 1090 constexpr const char *Ldrh = "ldrh";
1091 return emitMemOpEnc3(Cond, L | B7 | B5 | B4, Rt, OpAddress, TInfo, Ldrh);
1039 } 1092 }
1040 case 2: { 1093 case 2: {
1041 // Note: Handles i32 and float loads. Target lowering handles i64 and 1094 // Note: Handles i32 and float loads. Target lowering handles i64 and
1042 // double by using two (32 bit) load instructions. 1095 // double by using two (32 bit) load instructions.
1043 // 1096 //
1044 // LDR (immediate) - ARM section A8.8.63, encoding A1: 1097 // LDR (immediate) - ARM section A8.8.63, encoding A1:
1045 // ldr<c> <Rt>, [<Rn>{, #+/-<imm12>}] ; p=1, w=0 1098 // ldr<c> <Rt>, [<Rn>{, #+/-<imm12>}] ; p=1, w=0
1046 // ldr<c> <Rt>, [<Rn>], #+/-<imm12> ; p=1, w=1 1099 // ldr<c> <Rt>, [<Rn>], #+/-<imm12> ; p=1, w=1
1047 // ldr<c> <Rt>, [<Rn>, #+/-<imm12>]! ; p=0, w=1 1100 // ldr<c> <Rt>, [<Rn>, #+/-<imm12>]! ; p=0, w=1
1048 // 1101 //
1049 // cccc010pu0w1nnnnttttiiiiiiiiiiii where cccc=Cond, tttt=Rt, nnnn=Rn, 1102 // cccc010pu0w1nnnnttttiiiiiiiiiiii where cccc=Cond, tttt=Rt, nnnn=Rn,
1050 // iiiiiiiiiiii=imm12, u=1 if +, pu0w is a BlockAddr, and 1103 // iiiiiiiiiiii=imm12, u=1 if +, pu0w is a BlockAddr, and
1051 // 1104 //
1052 // LDR (register) - ARM section A8.8.70, encoding A1: 1105 // LDR (register) - ARM section A8.8.70, encoding A1:
1053 // ldrb<c> <Rt>, [<Rn>, +/-<Rm>{, <shift>}]{!} 1106 // ldrb<c> <Rt>, [<Rn>, +/-<Rm>{, <shift>}]{!}
1054 // ldrb<c> <Rt>, [<Rn>], +-<Rm>{, <shift>} 1107 // ldrb<c> <Rt>, [<Rn>], +-<Rm>{, <shift>}
1055 // 1108 //
1056 // cccc011pu0w1nnnnttttiiiiiss0mmmm where cccc=Cond, tttt=Rt, U=1 if +, pu0b 1109 // cccc011pu0w1nnnnttttiiiiiss0mmmm where cccc=Cond, tttt=Rt, U=1 if +, pu0b
1057 // is a BlockAddr, and pu0w0nnnn0000iiiiiss0mmmm=Address. 1110 // is a BlockAddr, and pu0w0nnnn0000iiiiiss0mmmm=Address.
1058 constexpr bool IsByte = false; 1111 constexpr bool IsByte = false;
1059 return emitMemOp(Cond, IsLoad, IsByte, Rt, OpAddress, TInfo); 1112 return emitMemOp(Cond, IsLoad, IsByte, Rt, OpAddress, TInfo, LdrName);
1060 } 1113 }
1061 } 1114 }
1062 } 1115 }
1063 1116
1064 void AssemblerARM32::lsl(const Operand *OpRd, const Operand *OpRm, 1117 void AssemblerARM32::lsl(const Operand *OpRd, const Operand *OpRm,
1065 const Operand *OpSrc1, bool SetFlags, 1118 const Operand *OpSrc1, bool SetFlags,
1066 CondARM32::Cond Cond) { 1119 CondARM32::Cond Cond) {
1067 constexpr IValueT Lsl = B3 | B2 | B0; // 1101 1120 constexpr const char *LslName = "lsl";
1068 constexpr IValueT Rn = 0; // Rn field is not used. 1121 IValueT Rd = encodeRegister(OpRd, "Rd", LslName);
1069 IValueT Rd; 1122 IValueT Rm = encodeRegister(OpRm, "Rm", LslName);
1070 if (encodeOperand(OpRd, Rd) != EncodedAsRegister)
1071 return setNeedsTextFixup();
1072 IValueT Rm;
1073 if (encodeOperand(OpRm, Rm) != EncodedAsRegister)
1074 return setNeedsTextFixup();
1075 IValueT Value; 1123 IValueT Value;
1076 switch (encodeOperand(OpSrc1, Value)) { 1124 switch (encodeOperand(OpSrc1, Value)) {
1077 default: 1125 default:
1078 return setNeedsTextFixup(); 1126 llvm::report_fatal_error(std::string(LslName) +
1127 ": Last operand not understood");
1079 case EncodedAsShiftImm5: { 1128 case EncodedAsShiftImm5: {
1080 // LSL (immediate) - ARM section A8.8.94, encoding A1: 1129 // LSL (immediate) - ARM section A8.8.94, encoding A1:
1081 // lsl{s}<c> <Rd>, <Rm>, #imm5 1130 // lsl{s}<c> <Rd>, <Rm>, #imm5
1082 // 1131 //
1083 // cccc0001101s0000ddddiiiii000mmmm where cccc=Cond, s=SetFlags, dddd=Rd, 1132 // cccc0001101s0000ddddiiiii000mmmm where cccc=Cond, s=SetFlags, dddd=Rd,
1084 // iiiii=imm5, and mmmm=Rm. 1133 // iiiii=imm5, and mmmm=Rm.
1134 constexpr IValueT LslOpcode = B3 | B2 | B0; // 1101
1135 constexpr IValueT Rn = 0; // Rn field is not used.
1085 Value = Value | (Rm << kRmShift); 1136 Value = Value | (Rm << kRmShift);
1086 emitType01(Cond, kInstTypeDataRegShift, Lsl, SetFlags, Rn, Rd, Value, 1137 emitType01(Cond, kInstTypeDataRegShift, LslOpcode, SetFlags, Rn, Rd, Value,
1087 RdIsPcAndSetFlags); 1138 RdIsPcAndSetFlags, LslName);
1088 return; 1139 return;
1089 } 1140 }
1090 case EncodedAsRegister: { 1141 case EncodedAsRegister: {
1091 // LSL (register) - ARM section A8.8.95, encoding A1: 1142 // LSL (register) - ARM section A8.8.95, encoding A1:
1092 // lsl{S}<c> <Rd>, <Rm>, <Rs> 1143 // lsl{S}<c> <Rd>, <Rm>, <Rs>
1093 // 1144 //
1094 // cccc0001101s0000ddddssss0001mmmm where cccc=Cond, s=SetFlags, dddd=Rd, 1145 // cccc0001101s0000ddddssss0001mmmm where cccc=Cond, s=SetFlags, dddd=Rd,
1095 // mmmm=Rm, and ssss=Rs. 1146 // mmmm=Rm, and ssss=Rs.
1096 IValueT Rs; 1147 constexpr IValueT LslOpcode = B3 | B2 | B0; // 1101
1097 if (encodeOperand(OpSrc1, Rs) != EncodedAsRegister) 1148 constexpr IValueT Rn = 0; // Rn field is not used.
1098 return setNeedsTextFixup(); 1149 IValueT Rs = encodeRegister(OpSrc1, "Rs", LslName);
1099 if ((Rd == RegARM32::Encoded_Reg_pc) || (Rm == RegARM32::Encoded_Reg_pc) || 1150 verifyRegNotPc(Rd, "Rd", LslName);
1100 (Rs == RegARM32::Encoded_Reg_pc)) 1151 verifyRegNotPc(Rm, "Rm", LslName);
1101 setNeedsTextFixup(); 1152 verifyRegNotPc(Rs, "Rs", LslName);
1102 emitType01(Cond, kInstTypeDataRegShift, Lsl, SetFlags, Rn, Rd, 1153 emitType01(Cond, kInstTypeDataRegShift, LslOpcode, SetFlags, Rn, Rd,
1103 encodeShiftRotateReg(Rm, OperandARM32::kNoShift, Rs), NoChecks); 1154 encodeShiftRotateReg(Rm, OperandARM32::kNoShift, Rs), NoChecks,
1155 LslName);
1104 return; 1156 return;
1105 } 1157 }
1106 } 1158 }
1107 } 1159 }
1108 1160
1109 void AssemblerARM32::mov(const Operand *OpRd, const Operand *OpSrc, 1161 void AssemblerARM32::mov(const Operand *OpRd, const Operand *OpSrc,
1110 CondARM32::Cond Cond) { 1162 CondARM32::Cond Cond) {
1111 // MOV (register) - ARM section A8.8.104, encoding A1: 1163 // MOV (register) - ARM section A8.8.104, encoding A1:
1112 // mov{S}<c> <Rd>, <Rn> 1164 // mov{S}<c> <Rd>, <Rn>
1113 // 1165 //
1114 // cccc0001101s0000dddd00000000mmmm where cccc=Cond, s=SetFlags, dddd=Rd, 1166 // cccc0001101s0000dddd00000000mmmm where cccc=Cond, s=SetFlags, dddd=Rd,
1115 // and nnnn=Rn. 1167 // and nnnn=Rn.
1116 // 1168 //
1117 // MOV (immediate) - ARM section A8.8.102, encoding A1: 1169 // MOV (immediate) - ARM section A8.8.102, encoding A1:
1118 // mov{S}<c> <Rd>, #<RotatedImm8> 1170 // mov{S}<c> <Rd>, #<RotatedImm8>
1119 // 1171 //
1120 // cccc0011101s0000ddddiiiiiiiiiiii where cccc=Cond, s=SetFlags, dddd=Rd, 1172 // cccc0011101s0000ddddiiiiiiiiiiii where cccc=Cond, s=SetFlags, dddd=Rd,
1121 // and iiiiiiiiiiii=RotatedImm8=Src. Note: We don't use movs in this 1173 // and iiiiiiiiiiii=RotatedImm8=Src. Note: We don't use movs in this
1122 // assembler. 1174 // assembler.
1123 IValueT Rd; 1175 constexpr const char *MovName = "mov";
1124 if (encodeOperand(OpRd, Rd) != EncodedAsRegister) 1176 IValueT Rd = encodeRegister(OpRd, "Rd", MovName);
1125 return setNeedsTextFixup();
1126 constexpr bool SetFlags = false; 1177 constexpr bool SetFlags = false;
1127 constexpr IValueT Rn = 0; 1178 constexpr IValueT Rn = 0;
1128 constexpr IValueT Mov = B3 | B2 | B0; // 1101. 1179 constexpr IValueT MovOpcode = B3 | B2 | B0; // 1101.
1129 emitType01(Mov, Rd, Rn, OpSrc, SetFlags, Cond, RdIsPcAndSetFlags); 1180 emitType01(Cond, MovOpcode, Rd, Rn, OpSrc, SetFlags, RdIsPcAndSetFlags,
1181 MovName);
1130 } 1182 }
1131 1183
1132 void AssemblerARM32::emitMovw(IValueT Opcode, IValueT Rd, IValueT Imm16, 1184 void AssemblerARM32::emitMovw(IValueT Opcode, IValueT Rd, IValueT Imm16,
1133 bool SetFlags, CondARM32::Cond Cond) { 1185 bool SetFlags, CondARM32::Cond Cond) {
1134 if (!isConditionDefined(Cond) || !Utils::IsAbsoluteUint(16, Imm16)) 1186 constexpr const char *MovwName = "movw";
1135 return setNeedsTextFixup(); 1187 verifyCondDefined(Cond, MovwName);
1188 if (!Utils::IsAbsoluteUint(16, Imm16))
1189 llvm::report_fatal_error(std::string(MovwName) + ": Not I16 constant");
1136 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 1190 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1137 const IValueT Encoding = encodeCondition(Cond) << kConditionShift | Opcode | 1191 const IValueT Encoding = encodeCondition(Cond) << kConditionShift | Opcode |
1138 (encodeBool(SetFlags) << kSShift) | 1192 (encodeBool(SetFlags) << kSShift) |
1139 ((Imm16 >> 12) << 16) | Rd << kRdShift | 1193 ((Imm16 >> 12) << 16) | Rd << kRdShift |
1140 (Imm16 & 0xfff); 1194 (Imm16 & 0xfff);
1141 emitInst(Encoding); 1195 emitInst(Encoding);
1142 } 1196 }
1143 1197
1144 void AssemblerARM32::movw(const Operand *OpRd, const Operand *OpSrc, 1198 void AssemblerARM32::movw(const Operand *OpRd, const Operand *OpSrc,
1145 CondARM32::Cond Cond) { 1199 CondARM32::Cond Cond) {
1146 IValueT Rd; 1200 constexpr const char *MovwName = "movw";
1147 if (encodeOperand(OpRd, Rd) != EncodedAsRegister) 1201 IValueT Rd = encodeRegister(OpRd, "Rd", MovwName);
1148 return setNeedsTextFixup();
1149 if (const auto *Src = llvm::dyn_cast<ConstantRelocatable>(OpSrc)) { 1202 if (const auto *Src = llvm::dyn_cast<ConstantRelocatable>(OpSrc)) {
1150 // MOVW (immediate) - ARM section A8.8.102, encoding A2: 1203 // MOVW (immediate) - ARM section A8.8.102, encoding A2:
1151 // movw<c> <Rd>, #<imm16> 1204 // movw<c> <Rd>, #<imm16>
1152 // 1205 //
1153 // cccc00110000iiiiddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, and 1206 // cccc00110000iiiiddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, and
1154 // iiiiiiiiiiiiiiii=imm16. 1207 // iiiiiiiiiiiiiiii=imm16.
1155 if (!isConditionDefined(Cond)) 1208 verifyCondDefined(Cond, MovwName);
1156 // Conditions of rule violated.
1157 return setNeedsTextFixup();
1158 // Use 0 for the lower 16 bits of the relocatable, and add a fixup to 1209 // Use 0 for the lower 16 bits of the relocatable, and add a fixup to
1159 // install the correct bits. 1210 // install the correct bits.
1160 constexpr bool IsMovW = true; 1211 constexpr bool IsMovW = true;
1161 emitFixup(createMoveFixup(IsMovW, Src)); 1212 emitFixup(createMoveFixup(IsMovW, Src));
1162 constexpr IValueT Imm16 = 0; 1213 constexpr IValueT Imm16 = 0;
1163 constexpr bool SetFlags = false; 1214 constexpr bool SetFlags = false;
1164 emitMovw(B25 | B24, Rd, Imm16, SetFlags, Cond); 1215 emitMovw(B25 | B24, Rd, Imm16, SetFlags, Cond);
1165 return; 1216 return;
1166 } 1217 }
1167 IValueT ConstVal; 1218 IValueT ConstVal;
1168 if (encodeOperand(OpSrc, ConstVal) != EncodedAsConstI32) 1219 if (encodeOperand(OpSrc, ConstVal) != EncodedAsConstI32)
1169 return setNeedsTextFixup(); 1220 llvm::report_fatal_error(std::string(MovwName) + ": Constant not i32");
1221
1170 // TODO(kschimpf): Determine if we want to handle rotated immediate 8 values 1222 // TODO(kschimpf): Determine if we want to handle rotated immediate 8 values
1171 // to handle cases where the constant is greater than 16 bits (encoding A1 1223 // to handle cases where the constant is greater than 16 bits (encoding A1
1172 // below). For now, handle using encoding A2. 1224 // below). For now, handle using encoding A2.
1173 constexpr bool SetFlags = 0; 1225 constexpr bool SetFlags = 0;
1174 emitMovw(B25 | B24, Rd, ConstVal, SetFlags, Cond); 1226 emitMovw(B25 | B24, Rd, ConstVal, SetFlags, Cond);
1175 return; 1227 return;
1176 1228
1177 // MOVW (immediate) - ARM section A8.8.102, encoding A1: 1229 // MOVW (immediate) - ARM section A8.8.102, encoding A1:
1178 // movw<c> <Rd>, #<RotatedImm8> 1230 // movw<c> <Rd>, #<RotatedImm8>
1179 // 1231 //
1180 // cccc0011101s0000ddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, s=SetFlags=0, 1232 // cccc0011101s0000ddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, s=SetFlags=0,
1181 // and iiiiiiiiiiii is a shift-rotated value defining RotatedImm8. 1233 // and iiiiiiiiiiii is a shift-rotated value defining RotatedImm8.
1182 } 1234 }
1183 1235
1184 void AssemblerARM32::movt(const Operand *OpRd, const Operand *OpSrc, 1236 void AssemblerARM32::movt(const Operand *OpRd, const Operand *OpSrc,
1185 CondARM32::Cond Cond) { 1237 CondARM32::Cond Cond) {
1186 IValueT Rd;
1187 if (encodeOperand(OpRd, Rd) != EncodedAsRegister)
1188 return setNeedsTextFixup();
1189 auto *Src = llvm::dyn_cast<ConstantRelocatable>(OpSrc);
1190 if (Src == nullptr)
1191 return setNeedsTextFixup();
1192 // MOVT - ARM section A8.8.102, encoding A2: 1238 // MOVT - ARM section A8.8.102, encoding A2:
1193 // movt<c> <Rd>, #<imm16> 1239 // movt<c> <Rd>, #<imm16>
1194 // 1240 //
1195 // cccc00110100iiiiddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, and 1241 // cccc00110100iiiiddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, and
1196 // iiiiiiiiiiiiiiii=imm16. 1242 // iiiiiiiiiiiiiiii=imm16.
1197 if (!isConditionDefined(Cond)) 1243 constexpr const char *MovtName = "movt";
1198 // Conditions of rule violated. 1244 IValueT Rd = encodeRegister(OpRd, "Rd", MovtName);
1245 auto *Src = llvm::dyn_cast<ConstantRelocatable>(OpSrc);
1246 if (!Src)
1247 // TODO(kschimpf) Figure out what else can appear here.
1199 return setNeedsTextFixup(); 1248 return setNeedsTextFixup();
1249 verifyCondDefined(Cond, MovtName);
1200 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 1250 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1201 // Use 0 for the lower 16 bits of the relocatable, and add a fixup to 1251 // Use 0 for the lower 16 bits of the relocatable, and add a fixup to
1202 // install the correct bits. 1252 // install the correct bits.
1203 constexpr bool IsMovW = false; 1253 constexpr bool IsMovW = false;
1204 emitFixup(createMoveFixup(IsMovW, Src)); 1254 emitFixup(createMoveFixup(IsMovW, Src));
1205 constexpr IValueT Imm16 = 0; 1255 constexpr IValueT Imm16 = 0;
1206 const IValueT Encoding = encodeCondition(Cond) << kConditionShift | B25 | 1256 const IValueT Encoding = encodeCondition(Cond) << kConditionShift | B25 |
1207 B24 | B22 | ((Imm16 >> 12) << 16) | Rd << kRdShift | 1257 B24 | B22 | ((Imm16 >> 12) << 16) | Rd << kRdShift |
1208 (Imm16 & 0xfff); 1258 (Imm16 & 0xfff);
1209 emitInst(Encoding); 1259 emitInst(Encoding);
1210 } 1260 }
1211 1261
1212 void AssemblerARM32::mvn(const Operand *OpRd, const Operand *OpSrc, 1262 void AssemblerARM32::mvn(const Operand *OpRd, const Operand *OpSrc,
1213 CondARM32::Cond Cond) { 1263 CondARM32::Cond Cond) {
1214 // MVN (immediate) - ARM section A8.8.115, encoding A1: 1264 // MVN (immediate) - ARM section A8.8.115, encoding A1:
1215 // mvn{s}<c> <Rd>, #<const> 1265 // mvn{s}<c> <Rd>, #<const>
1216 // 1266 //
1217 // cccc0011111s0000ddddiiiiiiiiiiii where cccc=Cond, s=SetFlags=0, dddd=Rd, 1267 // cccc0011111s0000ddddiiiiiiiiiiii where cccc=Cond, s=SetFlags=0, dddd=Rd,
1218 // and iiiiiiiiiiii=const 1268 // and iiiiiiiiiiii=const
1219 // 1269 //
1220 // MVN (register) - ARM section A8.8.116, encoding A1: 1270 // MVN (register) - ARM section A8.8.116, encoding A1:
1221 // mvn{s}<c> <Rd>, <Rm>{, <shift> 1271 // mvn{s}<c> <Rd>, <Rm>{, <shift>
1222 // 1272 //
1223 // cccc0001111s0000ddddiiiiitt0mmmm where cccc=Cond, s=SetFlags=0, dddd=Rd, 1273 // cccc0001111s0000ddddiiiiitt0mmmm where cccc=Cond, s=SetFlags=0, dddd=Rd,
1224 // mmmm=Rm, iiii defines shift constant, and tt=ShiftKind. 1274 // mmmm=Rm, iiii defines shift constant, and tt=ShiftKind.
1225 IValueT Rd; 1275 constexpr const char *MvnName = "mvn";
1226 if (encodeOperand(OpRd, Rd) != EncodedAsRegister) 1276 IValueT Rd = encodeRegister(OpRd, "Rd", MvnName);
1227 return setNeedsTextFixup();
1228 constexpr IValueT MvnOpcode = B3 | B2 | B1 | B0; // i.e. 1111 1277 constexpr IValueT MvnOpcode = B3 | B2 | B1 | B0; // i.e. 1111
1229 constexpr IValueT Rn = 0; 1278 constexpr IValueT Rn = 0;
1230 constexpr bool SetFlags = false; 1279 constexpr bool SetFlags = false;
1231 emitType01(MvnOpcode, Rd, Rn, OpSrc, SetFlags, Cond, RdIsPcAndSetFlags); 1280 emitType01(Cond, MvnOpcode, Rd, Rn, OpSrc, SetFlags, RdIsPcAndSetFlags,
1281 MvnName);
1232 } 1282 }
1233 1283
1234 void AssemblerARM32::sbc(const Operand *OpRd, const Operand *OpRn, 1284 void AssemblerARM32::sbc(const Operand *OpRd, const Operand *OpRn,
1235 const Operand *OpSrc1, bool SetFlags, 1285 const Operand *OpSrc1, bool SetFlags,
1236 CondARM32::Cond Cond) { 1286 CondARM32::Cond Cond) {
1237 // SBC (register) - ARM section 18.8.162, encoding A1: 1287 // SBC (register) - ARM section 18.8.162, encoding A1:
1238 // sbc{s}<c> <Rd>, <Rn>, <Rm>{, <shift>} 1288 // sbc{s}<c> <Rd>, <Rn>, <Rm>{, <shift>}
1239 // 1289 //
1240 // cccc0000110snnnnddddiiiiitt0mmmm where cccc=Cond, dddd=Rd, nnnn=Rn, 1290 // cccc0000110snnnnddddiiiiitt0mmmm where cccc=Cond, dddd=Rd, nnnn=Rn,
1241 // mmmm=Rm, iiiii=Shift, tt=ShiftKind, and s=SetFlags. 1291 // mmmm=Rm, iiiii=Shift, tt=ShiftKind, and s=SetFlags.
1242 // 1292 //
1243 // SBC (Immediate) - ARM section A8.8.161, encoding A1: 1293 // SBC (Immediate) - ARM section A8.8.161, encoding A1:
1244 // sbc{s}<c> <Rd>, <Rn>, #<RotatedImm8> 1294 // sbc{s}<c> <Rd>, <Rn>, #<RotatedImm8>
1245 // 1295 //
1246 // cccc0010110snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn, 1296 // cccc0010110snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn,
1247 // s=SetFlags and iiiiiiiiiiii=Src1Value defining RotatedImm8. 1297 // s=SetFlags and iiiiiiiiiiii=Src1Value defining RotatedImm8.
1248 constexpr IValueT Sbc = B2 | B1; // 0110 1298 constexpr const char *SbcName = "sbc";
1249 emitType01(Sbc, OpRd, OpRn, OpSrc1, SetFlags, Cond, RdIsPcAndSetFlags); 1299 constexpr IValueT SbcOpcode = B2 | B1; // 0110
1300 emitType01(Cond, SbcOpcode, OpRd, OpRn, OpSrc1, SetFlags, RdIsPcAndSetFlags,
1301 SbcName);
1250 } 1302 }
1251 1303
1252 void AssemblerARM32::sdiv(const Operand *OpRd, const Operand *OpRn, 1304 void AssemblerARM32::sdiv(const Operand *OpRd, const Operand *OpRn,
1253 const Operand *OpSrc1, CondARM32::Cond Cond) { 1305 const Operand *OpSrc1, CondARM32::Cond Cond) {
1254 // SDIV - ARM section A8.8.165, encoding A1. 1306 // SDIV - ARM section A8.8.165, encoding A1.
1255 // sdiv<c> <Rd>, <Rn>, <Rm> 1307 // sdiv<c> <Rd>, <Rn>, <Rm>
1256 // 1308 //
1257 // cccc01110001dddd1111mmmm0001nnnn where cccc=Cond, dddd=Rd, nnnn=Rn, and 1309 // cccc01110001dddd1111mmmm0001nnnn where cccc=Cond, dddd=Rd, nnnn=Rn, and
1258 // mmmm=Rm. 1310 // mmmm=Rm.
1259 IValueT Rd; 1311 constexpr const char *SdivName = "sdiv";
1260 if (encodeOperand(OpRd, Rd) != EncodedAsRegister) 1312 IValueT Rd = encodeRegister(OpRd, "Rd", SdivName);
1261 return setNeedsTextFixup(); 1313 IValueT Rn = encodeRegister(OpRn, "Rn", SdivName);
1262 IValueT Rn; 1314 IValueT Rm = encodeRegister(OpSrc1, "Rm", SdivName);
1263 if (encodeOperand(OpRn, Rn) != EncodedAsRegister) 1315 verifyRegNotPc(Rd, "Rd", SdivName);
1264 return setNeedsTextFixup(); 1316 verifyRegNotPc(Rn, "Rn", SdivName);
1265 IValueT Rm; 1317 verifyRegNotPc(Rm, "Rm", SdivName);
1266 if (encodeOperand(OpSrc1, Rm) != EncodedAsRegister)
1267 return setNeedsTextFixup();
1268 if (Rd == RegARM32::Encoded_Reg_pc || Rn == RegARM32::Encoded_Reg_pc ||
1269 Rm == RegARM32::Encoded_Reg_pc)
1270 llvm::report_fatal_error("Sdiv instruction unpredictable on pc");
1271 // Assembler registers rd, rn, rm are encoded as rn, rm, rs. 1318 // Assembler registers rd, rn, rm are encoded as rn, rm, rs.
1272 constexpr IValueT Opcode = 0; 1319 constexpr IValueT SdivOpcode = 0;
1273 emitDivOp(Cond, Opcode, Rd, Rn, Rm); 1320 emitDivOp(Cond, SdivOpcode, Rd, Rn, Rm, SdivName);
1274 } 1321 }
1275 1322
1276 void AssemblerARM32::str(const Operand *OpRt, const Operand *OpAddress, 1323 void AssemblerARM32::str(const Operand *OpRt, const Operand *OpAddress,
1277 CondARM32::Cond Cond, const TargetInfo &TInfo) { 1324 CondARM32::Cond Cond, const TargetInfo &TInfo) {
1325 constexpr const char *StrName = "str";
1278 constexpr bool IsLoad = false; 1326 constexpr bool IsLoad = false;
1279 IValueT Rt; 1327 IValueT Rt = encodeRegister(OpRt, "Rt", StrName);
1280 if (encodeOperand(OpRt, Rt) != EncodedAsRegister)
1281 return setNeedsTextFixup();
1282 const Type Ty = OpRt->getType(); 1328 const Type Ty = OpRt->getType();
1283 switch (typeWidthInBytesLog2(Ty)) { 1329 switch (typeWidthInBytesLog2(Ty)) {
1284 case 3: 1330 case 3:
1285 // STRD is not implemented because target lowering handles i64 and double by 1331 // STRD is not implemented because target lowering handles i64 and double by
1286 // using two (32-bit) store instructions. Note: Intenionally drop to 1332 // using two (32-bit) store instructions. Note: Intenionally drop to
1287 // default case. 1333 // default case.
1288 default: 1334 default:
1289 llvm::report_fatal_error(std::string("Type ") + typeString(Ty) + 1335 llvm::report_fatal_error(std::string(StrName) + ": Type " + typeString(Ty) +
1290 " not implementable using str\n"); 1336 " not implemented");
1291 case 0: { 1337 case 0: {
1292 // Handles i1 and i8 stores. 1338 // Handles i1 and i8 stores.
1293 // 1339 //
1294 // STRB (immediate) - ARM section A8.8.207, encoding A1: 1340 // STRB (immediate) - ARM section A8.8.207, encoding A1:
1295 // strb<c> <Rt>, [<Rn>{, #+/-<imm12>}] ; p=1, w=0 1341 // strb<c> <Rt>, [<Rn>{, #+/-<imm12>}] ; p=1, w=0
1296 // strb<c> <Rt>, [<Rn>], #+/-<imm12> ; p=1, w=1 1342 // strb<c> <Rt>, [<Rn>], #+/-<imm12> ; p=1, w=1
1297 // strb<c> <Rt>, [<Rn>, #+/-<imm12>]! ; p=0, w=1 1343 // strb<c> <Rt>, [<Rn>, #+/-<imm12>]! ; p=0, w=1
1298 // 1344 //
1299 // cccc010pu1w0nnnnttttiiiiiiiiiiii where cccc=Cond, tttt=Rt, nnnn=Rn, 1345 // cccc010pu1w0nnnnttttiiiiiiiiiiii where cccc=Cond, tttt=Rt, nnnn=Rn,
1300 // iiiiiiiiiiii=imm12, u=1 if +. 1346 // iiiiiiiiiiii=imm12, u=1 if +.
1301 constexpr bool IsByte = true; 1347 constexpr bool IsByte = true;
1302 return emitMemOp(Cond, IsLoad, IsByte, Rt, OpAddress, TInfo); 1348 return emitMemOp(Cond, IsLoad, IsByte, Rt, OpAddress, TInfo, StrName);
1303 } 1349 }
1304 case 1: { 1350 case 1: {
1305 // Handles i16 stores. 1351 // Handles i16 stores.
1306 // 1352 //
1307 // STRH (immediate) - ARM section A8.*.217, encoding A1: 1353 // STRH (immediate) - ARM section A8.*.217, encoding A1:
1308 // strh<c> <Rt>, [<Rn>{, #+/-<Imm8>}] 1354 // strh<c> <Rt>, [<Rn>{, #+/-<Imm8>}]
1309 // strh<c> <Rt>, [<Rn>], #+/-<Imm8> 1355 // strh<c> <Rt>, [<Rn>], #+/-<Imm8>
1310 // strh<c> <Rt>, [<Rn>, #+/-<Imm8>]! 1356 // strh<c> <Rt>, [<Rn>, #+/-<Imm8>]!
1311 // 1357 //
1312 // cccc000pu1w0nnnnttttiiii1011iiii where cccc=Cond, tttt=Rt, nnnn=Rn, 1358 // cccc000pu1w0nnnnttttiiii1011iiii where cccc=Cond, tttt=Rt, nnnn=Rn,
1313 // iiiiiiii=Imm8, u=1 if +, pu0w is a BlockAddr, and 1359 // iiiiiiii=Imm8, u=1 if +, pu0w is a BlockAddr, and
1314 // pu0w0nnnn0000iiiiiiiiiiii=Address. 1360 // pu0w0nnnn0000iiiiiiiiiiii=Address.
1315 return emitMemOpEnc3(Cond, B7 | B5 | B4, Rt, OpAddress, TInfo); 1361 constexpr const char *Strh = "strh";
1362 return emitMemOpEnc3(Cond, B7 | B5 | B4, Rt, OpAddress, TInfo, Strh);
1316 } 1363 }
1317 case 2: { 1364 case 2: {
1318 // Note: Handles i32 and float stores. Target lowering handles i64 and 1365 // Note: Handles i32 and float stores. Target lowering handles i64 and
1319 // double by using two (32 bit) store instructions. 1366 // double by using two (32 bit) store instructions.
1320 // 1367 //
1321 // STR (immediate) - ARM section A8.8.207, encoding A1: 1368 // STR (immediate) - ARM section A8.8.207, encoding A1:
1322 // str<c> <Rt>, [<Rn>{, #+/-<imm12>}] ; p=1, w=0 1369 // str<c> <Rt>, [<Rn>{, #+/-<imm12>}] ; p=1, w=0
1323 // str<c> <Rt>, [<Rn>], #+/-<imm12> ; p=1, w=1 1370 // str<c> <Rt>, [<Rn>], #+/-<imm12> ; p=1, w=1
1324 // str<c> <Rt>, [<Rn>, #+/-<imm12>]! ; p=0, w=1 1371 // str<c> <Rt>, [<Rn>, #+/-<imm12>]! ; p=0, w=1
1325 // 1372 //
1326 // cccc010pu1w0nnnnttttiiiiiiiiiiii where cccc=Cond, tttt=Rt, nnnn=Rn, 1373 // cccc010pu1w0nnnnttttiiiiiiiiiiii where cccc=Cond, tttt=Rt, nnnn=Rn,
1327 // iiiiiiiiiiii=imm12, u=1 if +. 1374 // iiiiiiiiiiii=imm12, u=1 if +.
1328 constexpr bool IsByte = false; 1375 constexpr bool IsByte = false;
1329 return emitMemOp(Cond, IsLoad, IsByte, Rt, OpAddress, TInfo); 1376 return emitMemOp(Cond, IsLoad, IsByte, Rt, OpAddress, TInfo, StrName);
1330 return setNeedsTextFixup(); 1377 return setNeedsTextFixup();
1331 } 1378 }
1332 } 1379 }
1333 } 1380 }
1334 1381
1335 void AssemblerARM32::orr(const Operand *OpRd, const Operand *OpRn, 1382 void AssemblerARM32::orr(const Operand *OpRd, const Operand *OpRn,
1336 const Operand *OpSrc1, bool SetFlags, 1383 const Operand *OpSrc1, bool SetFlags,
1337 CondARM32::Cond Cond) { 1384 CondARM32::Cond Cond) {
1338 // ORR (register) - ARM Section A8.8.123, encoding A1: 1385 // ORR (register) - ARM Section A8.8.123, encoding A1:
1339 // orr{s}<c> <Rd>, <Rn>, <Rm> 1386 // orr{s}<c> <Rd>, <Rn>, <Rm>
1340 // 1387 //
1341 // cccc0001100snnnnddddiiiiitt0mmmm where cccc=Cond, dddd=Rd, nnnn=Rn, 1388 // cccc0001100snnnnddddiiiiitt0mmmm where cccc=Cond, dddd=Rd, nnnn=Rn,
1342 // mmmm=Rm, iiiii=shift, tt=ShiftKind,, and s=SetFlags. 1389 // mmmm=Rm, iiiii=shift, tt=ShiftKind,, and s=SetFlags.
1343 // 1390 //
1344 // ORR (register) - ARM Section A8.8.123, encoding A1: 1391 // ORR (register) - ARM Section A8.8.123, encoding A1:
1345 // orr{s}<c> <Rd>, <Rn>, #<RotatedImm8> 1392 // orr{s}<c> <Rd>, <Rn>, #<RotatedImm8>
1346 // 1393 //
1347 // cccc0001100snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn, 1394 // cccc0001100snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn,
1348 // s=SetFlags and iiiiiiiiiiii=Src1Value defining RotatedImm8. 1395 // s=SetFlags and iiiiiiiiiiii=Src1Value defining RotatedImm8.
1349 constexpr IValueT Orr = B3 | B2; // i.e. 1100 1396 constexpr const char *OrrName = "orr";
1350 emitType01(Orr, OpRd, OpRn, OpSrc1, SetFlags, Cond, RdIsPcAndSetFlags); 1397 constexpr IValueT OrrOpcode = B3 | B2; // i.e. 1100
1398 emitType01(Cond, OrrOpcode, OpRd, OpRn, OpSrc1, SetFlags, RdIsPcAndSetFlags,
1399 OrrName);
1351 } 1400 }
1352 1401
1353 void AssemblerARM32::pop(const Operand *OpRt, CondARM32::Cond Cond) { 1402 void AssemblerARM32::pop(const Operand *OpRt, CondARM32::Cond Cond) {
1354 // POP - ARM section A8.8.132, encoding A2: 1403 // POP - ARM section A8.8.132, encoding A2:
1355 // pop<c> {Rt} 1404 // pop<c> {Rt}
1356 // 1405 //
1357 // cccc010010011101dddd000000000100 where dddd=Rt and cccc=Cond. 1406 // cccc010010011101dddd000000000100 where dddd=Rt and cccc=Cond.
1358 IValueT Rt; 1407 constexpr const char *Pop = "pop";
1359 if (encodeOperand(OpRt, Rt) != EncodedAsRegister) 1408 IValueT Rt = encodeRegister(OpRt, "Rt", Pop);
1360 return setNeedsTextFixup(); 1409 verifyRegsNotEq(Rt, "Rt", RegARM32::Encoded_Reg_sp, "sp", Pop);
1361 assert(Rt != RegARM32::Encoded_Reg_sp);
1362 // Same as load instruction. 1410 // Same as load instruction.
1363 constexpr bool IsLoad = true; 1411 constexpr bool IsLoad = true;
1364 constexpr bool IsByte = false; 1412 constexpr bool IsByte = false;
1365 IValueT Address = encodeImmRegOffset(RegARM32::Encoded_Reg_sp, kWordSize, 1413 IValueT Address = encodeImmRegOffset(RegARM32::Encoded_Reg_sp, kWordSize,
1366 OperandARM32Mem::PostIndex); 1414 OperandARM32Mem::PostIndex);
1367 emitMemOp(Cond, kInstTypeMemImmediate, IsLoad, IsByte, Rt, Address); 1415 emitMemOp(Cond, kInstTypeMemImmediate, IsLoad, IsByte, Rt, Address, Pop);
1368 } 1416 }
1369 1417
1370 void AssemblerARM32::popList(const IValueT Registers, CondARM32::Cond Cond) { 1418 void AssemblerARM32::popList(const IValueT Registers, CondARM32::Cond Cond) {
1371 // POP - ARM section A8.*.131, encoding A1: 1419 // POP - ARM section A8.*.131, encoding A1:
1372 // pop<c> <registers> 1420 // pop<c> <registers>
1373 // 1421 //
1374 // cccc100010111101rrrrrrrrrrrrrrrr where cccc=Cond and 1422 // cccc100010111101rrrrrrrrrrrrrrrr where cccc=Cond and
1375 // rrrrrrrrrrrrrrrr=Registers (one bit for each GP register). 1423 // rrrrrrrrrrrrrrrr=Registers (one bit for each GP register).
1424 constexpr const char *PopListName = "pop {}";
1376 constexpr bool IsLoad = true; 1425 constexpr bool IsLoad = true;
1377 emitMultiMemOp(Cond, IA_W, IsLoad, RegARM32::Encoded_Reg_sp, Registers); 1426 emitMultiMemOp(Cond, IA_W, IsLoad, RegARM32::Encoded_Reg_sp, Registers,
1427 PopListName);
1378 } 1428 }
1379 1429
1380 void AssemblerARM32::push(const Operand *OpRt, CondARM32::Cond Cond) { 1430 void AssemblerARM32::push(const Operand *OpRt, CondARM32::Cond Cond) {
1381 // PUSH - ARM section A8.8.133, encoding A2: 1431 // PUSH - ARM section A8.8.133, encoding A2:
1382 // push<c> {Rt} 1432 // push<c> {Rt}
1383 // 1433 //
1384 // cccc010100101101dddd000000000100 where dddd=Rt and cccc=Cond. 1434 // cccc010100101101dddd000000000100 where dddd=Rt and cccc=Cond.
1385 IValueT Rt; 1435 constexpr const char *Push = "push";
1386 if (encodeOperand(OpRt, Rt) != EncodedAsRegister) 1436 IValueT Rt = encodeRegister(OpRt, "Rt", Push);
1387 return setNeedsTextFixup(); 1437 verifyRegsNotEq(Rt, "Rt", RegARM32::Encoded_Reg_sp, "sp", Push);
1388 assert(Rt != RegARM32::Encoded_Reg_sp);
1389 // Same as store instruction. 1438 // Same as store instruction.
1390 constexpr bool isLoad = false; 1439 constexpr bool isLoad = false;
1391 constexpr bool isByte = false; 1440 constexpr bool isByte = false;
1392 IValueT Address = encodeImmRegOffset(RegARM32::Encoded_Reg_sp, -kWordSize, 1441 IValueT Address = encodeImmRegOffset(RegARM32::Encoded_Reg_sp, -kWordSize,
1393 OperandARM32Mem::PreIndex); 1442 OperandARM32Mem::PreIndex);
1394 emitMemOp(Cond, kInstTypeMemImmediate, isLoad, isByte, Rt, Address); 1443 emitMemOp(Cond, kInstTypeMemImmediate, isLoad, isByte, Rt, Address, Push);
1395 } 1444 }
1396 1445
1397 void AssemblerARM32::pushList(const IValueT Registers, CondARM32::Cond Cond) { 1446 void AssemblerARM32::pushList(const IValueT Registers, CondARM32::Cond Cond) {
1398 // PUSH - ARM section A8.8.133, encoding A1: 1447 // PUSH - ARM section A8.8.133, encoding A1:
1399 // push<c> <Registers> 1448 // push<c> <Registers>
1400 // 1449 //
1401 // cccc100100101101rrrrrrrrrrrrrrrr where cccc=Cond and 1450 // cccc100100101101rrrrrrrrrrrrrrrr where cccc=Cond and
1402 // rrrrrrrrrrrrrrrr=Registers (one bit for each GP register). 1451 // rrrrrrrrrrrrrrrr=Registers (one bit for each GP register).
1452 constexpr const char *PushListName = "push {}";
1403 constexpr bool IsLoad = false; 1453 constexpr bool IsLoad = false;
1404 emitMultiMemOp(Cond, DB_W, IsLoad, RegARM32::Encoded_Reg_sp, Registers); 1454 emitMultiMemOp(Cond, DB_W, IsLoad, RegARM32::Encoded_Reg_sp, Registers,
1455 PushListName);
1405 } 1456 }
1406 1457
1407 void AssemblerARM32::mla(const Operand *OpRd, const Operand *OpRn, 1458 void AssemblerARM32::mla(const Operand *OpRd, const Operand *OpRn,
1408 const Operand *OpRm, const Operand *OpRa, 1459 const Operand *OpRm, const Operand *OpRa,
1409 CondARM32::Cond Cond) { 1460 CondARM32::Cond Cond) {
1410 IValueT Rd;
1411 if (encodeOperand(OpRd, Rd) != EncodedAsRegister)
1412 return setNeedsTextFixup();
1413 IValueT Rn;
1414 if (encodeOperand(OpRn, Rn) != EncodedAsRegister)
1415 return setNeedsTextFixup();
1416 IValueT Rm;
1417 if (encodeOperand(OpRm, Rm) != EncodedAsRegister)
1418 return setNeedsTextFixup();
1419 IValueT Ra;
1420 if (encodeOperand(OpRa, Ra) != EncodedAsRegister)
1421 return setNeedsTextFixup();
1422 // MLA - ARM section A8.8.114, encoding A1. 1461 // MLA - ARM section A8.8.114, encoding A1.
1423 // mla{s}<c> <Rd>, <Rn>, <Rm>, <Ra> 1462 // mla{s}<c> <Rd>, <Rn>, <Rm>, <Ra>
1424 // 1463 //
1425 // cccc0000001sddddaaaammmm1001nnnn where cccc=Cond, s=SetFlags, dddd=Rd, 1464 // cccc0000001sddddaaaammmm1001nnnn where cccc=Cond, s=SetFlags, dddd=Rd,
1426 // aaaa=Ra, mmmm=Rm, and nnnn=Rn. 1465 // aaaa=Ra, mmmm=Rm, and nnnn=Rn.
1427 if (Rd == RegARM32::Encoded_Reg_pc || Rn == RegARM32::Encoded_Reg_pc || 1466 constexpr const char *MlaName = "mla";
1428 Rm == RegARM32::Encoded_Reg_pc || Ra == RegARM32::Encoded_Reg_pc) 1467 IValueT Rd = encodeRegister(OpRd, "Rd", MlaName);
1429 llvm::report_fatal_error("Mul instruction unpredictable on pc"); 1468 IValueT Rn = encodeRegister(OpRn, "Rn", MlaName);
1469 IValueT Rm = encodeRegister(OpRm, "Rm", MlaName);
1470 IValueT Ra = encodeRegister(OpRa, "Ra", MlaName);
1471 verifyRegNotPc(Rd, "Rd", MlaName);
1472 verifyRegNotPc(Rn, "Rn", MlaName);
1473 verifyRegNotPc(Rm, "Rm", MlaName);
1474 verifyRegNotPc(Ra, "Ra", MlaName);
1430 constexpr IValueT MlaOpcode = B21; 1475 constexpr IValueT MlaOpcode = B21;
1431 constexpr bool SetFlags = false; 1476 constexpr bool SetFlags = false;
1432 // Assembler registers rd, rn, rm, ra are encoded as rn, rm, rs, rd. 1477 // Assembler registers rd, rn, rm, ra are encoded as rn, rm, rs, rd.
1433 emitMulOp(Cond, MlaOpcode, Ra, Rd, Rn, Rm, SetFlags); 1478 emitMulOp(Cond, MlaOpcode, Ra, Rd, Rn, Rm, SetFlags, MlaName);
1434 } 1479 }
1435 1480
1436 void AssemblerARM32::mul(const Operand *OpRd, const Operand *OpRn, 1481 void AssemblerARM32::mul(const Operand *OpRd, const Operand *OpRn,
1437 const Operand *OpSrc1, bool SetFlags, 1482 const Operand *OpSrc1, bool SetFlags,
1438 CondARM32::Cond Cond) { 1483 CondARM32::Cond Cond) {
1439 IValueT Rd;
1440 if (encodeOperand(OpRd, Rd) != EncodedAsRegister)
1441 return setNeedsTextFixup();
1442 IValueT Rn;
1443 if (encodeOperand(OpRn, Rn) != EncodedAsRegister)
1444 return setNeedsTextFixup();
1445 IValueT Rm;
1446 if (encodeOperand(OpSrc1, Rm) != EncodedAsRegister)
1447 return setNeedsTextFixup();
1448 // MUL - ARM section A8.8.114, encoding A1. 1484 // MUL - ARM section A8.8.114, encoding A1.
1449 // mul{s}<c> <Rd>, <Rn>, <Rm> 1485 // mul{s}<c> <Rd>, <Rn>, <Rm>
1450 // 1486 //
1451 // cccc0000000sdddd0000mmmm1001nnnn where cccc=Cond, dddd=Rd, nnnn=Rn, 1487 // cccc0000000sdddd0000mmmm1001nnnn where cccc=Cond, dddd=Rd, nnnn=Rn,
1452 // mmmm=Rm, and s=SetFlags. 1488 // mmmm=Rm, and s=SetFlags.
1453 if (Rd == RegARM32::Encoded_Reg_pc || Rn == RegARM32::Encoded_Reg_pc || 1489 constexpr const char *MulName = "mul";
1454 Rm == RegARM32::Encoded_Reg_pc) 1490 IValueT Rd = encodeRegister(OpRd, "Rd", MulName);
1455 llvm::report_fatal_error("Mul instruction unpredictable on pc"); 1491 IValueT Rn = encodeRegister(OpRn, "Rn", MulName);
1492 IValueT Rm = encodeRegister(OpSrc1, "Rm", MulName);
1493 verifyRegNotPc(Rd, "Rd", MulName);
1494 verifyRegNotPc(Rn, "Rn", MulName);
1495 verifyRegNotPc(Rm, "Rm", MulName);
1456 // Assembler registers rd, rn, rm are encoded as rn, rm, rs. 1496 // Assembler registers rd, rn, rm are encoded as rn, rm, rs.
1457 constexpr IValueT MulOpcode = 0; 1497 constexpr IValueT MulOpcode = 0;
1458 emitMulOp(Cond, MulOpcode, RegARM32::Encoded_Reg_r0, Rd, Rn, Rm, SetFlags); 1498 emitMulOp(Cond, MulOpcode, RegARM32::Encoded_Reg_r0, Rd, Rn, Rm, SetFlags,
1499 MulName);
1459 } 1500 }
1460 1501
1461 void AssemblerARM32::udiv(const Operand *OpRd, const Operand *OpRn, 1502 void AssemblerARM32::udiv(const Operand *OpRd, const Operand *OpRn,
1462 const Operand *OpSrc1, CondARM32::Cond Cond) { 1503 const Operand *OpSrc1, CondARM32::Cond Cond) {
1463 // UDIV - ARM section A8.8.248, encoding A1. 1504 // UDIV - ARM section A8.8.248, encoding A1.
1464 // udiv<c> <Rd>, <Rn>, <Rm> 1505 // udiv<c> <Rd>, <Rn>, <Rm>
1465 // 1506 //
1466 // cccc01110011dddd1111mmmm0001nnnn where cccc=Cond, dddd=Rd, nnnn=Rn, and 1507 // cccc01110011dddd1111mmmm0001nnnn where cccc=Cond, dddd=Rd, nnnn=Rn, and
1467 // mmmm=Rm. 1508 // mmmm=Rm.
1468 IValueT Rd; 1509 constexpr const char *UdivName = "udiv";
1469 if (encodeOperand(OpRd, Rd) != EncodedAsRegister) 1510 IValueT Rd = encodeRegister(OpRd, "Rd", UdivName);
1470 return setNeedsTextFixup(); 1511 IValueT Rn = encodeRegister(OpRn, "Rn", UdivName);
1471 IValueT Rn; 1512 IValueT Rm = encodeRegister(OpSrc1, "Rm", UdivName);
1472 if (encodeOperand(OpRn, Rn) != EncodedAsRegister) 1513 verifyRegNotPc(Rd, "Rd", UdivName);
1473 return setNeedsTextFixup(); 1514 verifyRegNotPc(Rn, "Rn", UdivName);
1474 IValueT Rm; 1515 verifyRegNotPc(Rm, "Rm", UdivName);
1475 if (encodeOperand(OpSrc1, Rm) != EncodedAsRegister)
1476 return setNeedsTextFixup();
1477 if (Rd == RegARM32::Encoded_Reg_pc || Rn == RegARM32::Encoded_Reg_pc ||
1478 Rm == RegARM32::Encoded_Reg_pc)
1479 llvm::report_fatal_error("Udiv instruction unpredictable on pc");
1480 // Assembler registers rd, rn, rm are encoded as rn, rm, rs. 1516 // Assembler registers rd, rn, rm are encoded as rn, rm, rs.
1481 constexpr IValueT Opcode = B21; 1517 constexpr IValueT UdivOpcode = B21;
1482 emitDivOp(Cond, Opcode, Rd, Rn, Rm); 1518 emitDivOp(Cond, UdivOpcode, Rd, Rn, Rm, UdivName);
1483 } 1519 }
1484 1520
1485 void AssemblerARM32::sub(const Operand *OpRd, const Operand *OpRn, 1521 void AssemblerARM32::sub(const Operand *OpRd, const Operand *OpRn,
1486 const Operand *OpSrc1, bool SetFlags, 1522 const Operand *OpSrc1, bool SetFlags,
1487 CondARM32::Cond Cond) { 1523 CondARM32::Cond Cond) {
1488 // SUB (register) - ARM section A8.8.223, encoding A1: 1524 // SUB (register) - ARM section A8.8.223, encoding A1:
1489 // sub{s}<c> <Rd>, <Rn>, <Rm>{, <shift>} 1525 // sub{s}<c> <Rd>, <Rn>, <Rm>{, <shift>}
1490 // SUB (SP minus register): See ARM section 8.8.226, encoding A1: 1526 // SUB (SP minus register): See ARM section 8.8.226, encoding A1:
1491 // sub{s}<c> <Rd>, sp, <Rm>{, <Shift>} 1527 // sub{s}<c> <Rd>, sp, <Rm>{, <Shift>}
1492 // 1528 //
1493 // cccc0000010snnnnddddiiiiitt0mmmm where cccc=Cond, dddd=Rd, nnnn=Rn, 1529 // cccc0000010snnnnddddiiiiitt0mmmm where cccc=Cond, dddd=Rd, nnnn=Rn,
1494 // mmmm=Rm, iiiiii=shift, tt=ShiftKind, and s=SetFlags. 1530 // mmmm=Rm, iiiiii=shift, tt=ShiftKind, and s=SetFlags.
1495 // 1531 //
1496 // Sub (Immediate) - ARM section A8.8.222, encoding A1: 1532 // Sub (Immediate) - ARM section A8.8.222, encoding A1:
1497 // sub{s}<c> <Rd>, <Rn>, #<RotatedImm8> 1533 // sub{s}<c> <Rd>, <Rn>, #<RotatedImm8>
1498 // Sub (Sp minus immediate) - ARM section A8.*.225, encoding A1: 1534 // Sub (Sp minus immediate) - ARM section A8.*.225, encoding A1:
1499 // sub{s}<c> sp, <Rn>, #<RotatedImm8> 1535 // sub{s}<c> sp, <Rn>, #<RotatedImm8>
1500 // 1536 //
1501 // cccc0010010snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn, 1537 // cccc0010010snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn,
1502 // s=SetFlags and iiiiiiiiiiii=Src1Value defining RotatedImm8 1538 // s=SetFlags and iiiiiiiiiiii=Src1Value defining RotatedImm8
1503 constexpr IValueT Sub = B1; // 0010 1539 constexpr const char *SubName = "sub";
1504 emitType01(Sub, OpRd, OpRn, OpSrc1, SetFlags, Cond, RdIsPcAndSetFlags); 1540 constexpr IValueT SubOpcode = B1; // 0010
1541 emitType01(Cond, SubOpcode, OpRd, OpRn, OpSrc1, SetFlags, RdIsPcAndSetFlags,
1542 SubName);
1505 } 1543 }
1506 1544
1507 void AssemblerARM32::tst(const Operand *OpRn, const Operand *OpSrc1, 1545 void AssemblerARM32::tst(const Operand *OpRn, const Operand *OpSrc1,
1508 CondARM32::Cond Cond) { 1546 CondARM32::Cond Cond) {
1509 // TST (register) - ARM section A8.8.241, encoding A1: 1547 // TST (register) - ARM section A8.8.241, encoding A1:
1510 // tst<c> <Rn>, <Rm>(, <shift>} 1548 // tst<c> <Rn>, <Rm>(, <shift>}
1511 // 1549 //
1512 // cccc00010001nnnn0000iiiiitt0mmmm where cccc=Cond, nnnn=Rn, mmmm=Rm, 1550 // cccc00010001nnnn0000iiiiitt0mmmm where cccc=Cond, nnnn=Rn, mmmm=Rm,
1513 // iiiii=Shift, and tt=ShiftKind. 1551 // iiiii=Shift, and tt=ShiftKind.
1514 // 1552 //
1515 // TST (immediate) - ARM section A8.8.240, encoding A1: 1553 // TST (immediate) - ARM section A8.8.240, encoding A1:
1516 // tst<c> <Rn>, #<RotatedImm8> 1554 // tst<c> <Rn>, #<RotatedImm8>
1517 // 1555 //
1518 // cccc00110001nnnn0000iiiiiiiiiiii where cccc=Cond, nnnn=Rn, and 1556 // cccc00110001nnnn0000iiiiiiiiiiii where cccc=Cond, nnnn=Rn, and
1519 // iiiiiiiiiiii defines RotatedImm8. 1557 // iiiiiiiiiiii defines RotatedImm8.
1520 constexpr IValueT Opcode = B3; // ie. 1000 1558 constexpr const char *TstName = "tst";
1521 emitCompareOp(Opcode, OpRn, OpSrc1, Cond); 1559 constexpr IValueT TstOpcode = B3; // ie. 1000
1560 emitCompareOp(Cond, TstOpcode, OpRn, OpSrc1, TstName);
1522 } 1561 }
1523 1562
1524 void AssemblerARM32::umull(const Operand *OpRdLo, const Operand *OpRdHi, 1563 void AssemblerARM32::umull(const Operand *OpRdLo, const Operand *OpRdHi,
1525 const Operand *OpRn, const Operand *OpRm, 1564 const Operand *OpRn, const Operand *OpRm,
1526 CondARM32::Cond Cond) { 1565 CondARM32::Cond Cond) {
1527 // UMULL - ARM section A8.8.257, encoding A1: 1566 // UMULL - ARM section A8.8.257, encoding A1:
1528 // umull<c> <RdLo>, <RdHi>, <Rn>, <Rm> 1567 // umull<c> <RdLo>, <RdHi>, <Rn>, <Rm>
1529 // 1568 //
1530 // cccc0000100shhhhllllmmmm1001nnnn where hhhh=RdHi, llll=RdLo, nnnn=Rn, 1569 // cccc0000100shhhhllllmmmm1001nnnn where hhhh=RdHi, llll=RdLo, nnnn=Rn,
1531 // mmmm=Rm, and s=SetFlags 1570 // mmmm=Rm, and s=SetFlags
1532 IValueT RdLo; 1571 constexpr const char *UmullName = "umull";
1533 IValueT RdHi; 1572 IValueT RdLo = encodeRegister(OpRdLo, "RdLo", UmullName);
1534 IValueT Rn; 1573 IValueT RdHi = encodeRegister(OpRdHi, "RdHi", UmullName);
1535 IValueT Rm; 1574 IValueT Rn = encodeRegister(OpRn, "Rn", UmullName);
1536 if (encodeOperand(OpRdLo, RdLo) != EncodedAsRegister || 1575 IValueT Rm = encodeRegister(OpRm, "Rm", UmullName);
1537 encodeOperand(OpRdHi, RdHi) != EncodedAsRegister || 1576 verifyRegNotPc(RdLo, "RdLo", UmullName);
1538 encodeOperand(OpRn, Rn) != EncodedAsRegister || 1577 verifyRegNotPc(RdHi, "RdHi", UmullName);
1539 encodeOperand(OpRm, Rm) != EncodedAsRegister) 1578 verifyRegNotPc(Rn, "Rn", UmullName);
1540 return setNeedsTextFixup(); 1579 verifyRegNotPc(Rm, "Rm", UmullName);
1541 if (RdHi == RegARM32::Encoded_Reg_pc || RdLo == RegARM32::Encoded_Reg_pc || 1580 verifyRegsNotEq(RdHi, "RdHi", RdLo, "RdLo", UmullName);
1542 Rn == RegARM32::Encoded_Reg_pc || Rm == RegARM32::Encoded_Reg_pc || 1581 constexpr IValueT UmullOpcode = B23;
1543 RdHi == RdLo)
1544 llvm::report_fatal_error("Umull instruction unpredictable on pc");
1545 constexpr bool SetFlags = false; 1582 constexpr bool SetFlags = false;
1546 emitMulOp(Cond, B23, RdLo, RdHi, Rn, Rm, SetFlags); 1583 emitMulOp(Cond, UmullOpcode, RdLo, RdHi, Rn, Rm, SetFlags, UmullName);
1547 } 1584 }
1548 1585
1549 void AssemblerARM32::uxt(const Operand *OpRd, const Operand *OpSrc0, 1586 void AssemblerARM32::uxt(const Operand *OpRd, const Operand *OpSrc0,
1550 CondARM32::Cond Cond) { 1587 CondARM32::Cond Cond) {
1551 IValueT Rd; 1588 constexpr const char *UxtName = "uxt";
1552 if (encodeOperand(OpRd, Rd) != EncodedAsRegister) 1589 IValueT Rd = encodeRegister(OpRd, "Rd", UxtName);
1553 return setNeedsTextFixup(); 1590 IValueT Rm = encodeRegister(OpSrc0, "Rm", UxtName);
1554 // Note: For the moment, we assume no rotation is specified. 1591 // Note: For the moment, we assume no rotation is specified.
1555 RotationValue Rotation = kRotateNone; 1592 RotationValue Rotation = kRotateNone;
1556 constexpr IValueT Rn = RegARM32::Encoded_Reg_pc; 1593 constexpr IValueT Rn = RegARM32::Encoded_Reg_pc;
1557 IValueT Rm;
1558 if (encodeOperand(OpSrc0, Rm) != EncodedAsRegister)
1559 return setNeedsTextFixup();
1560 switch (typeWidthInBytes(OpSrc0->getType())) { 1594 switch (typeWidthInBytes(OpSrc0->getType())) {
1561 default: 1595 default:
1562 return setNeedsTextFixup(); 1596 llvm::report_fatal_error("Type of Rm not understood: uxt");
1563 case 1: { 1597 case 1: {
1564 // UXTB - ARM section A8.8.274, encoding A1: 1598 // UXTB - ARM section A8.8.274, encoding A1:
1565 // uxtb<c> <Rd>, <Rm>{, <rotate>} 1599 // uxtb<c> <Rd>, <Rm>{, <rotate>}
1566 // 1600 //
1567 // cccc011011101111ddddrr000111mmmm where cccc=Cond, dddd=Rd, mmmm=Rm, and 1601 // cccc011011101111ddddrr000111mmmm where cccc=Cond, dddd=Rd, mmmm=Rm, and
1568 // rr defined (RotationValue) rotate. 1602 // rr defined (RotationValue) rotate.
1569 constexpr IValueT Opcode = B26 | B25 | B23 | B22 | B21; 1603 constexpr IValueT UxtOpcode = B26 | B25 | B23 | B22 | B21;
1570 emitUxt(Cond, Opcode, Rd, Rn, Rm, Rotation); 1604 emitUxt(Cond, UxtOpcode, Rd, Rn, Rm, Rotation, UxtName);
1571 return; 1605 return;
1572 } 1606 }
1573 case 2: { 1607 case 2: {
1574 // UXTH - ARM section A8.8.276, encoding A1: 1608 // UXTH - ARM section A8.8.276, encoding A1:
1575 // uxth<c> <Rd>< <Rm>{, <rotate>} 1609 // uxth<c> <Rd>< <Rm>{, <rotate>}
1576 // 1610 //
1577 // cccc01101111nnnnddddrr000111mmmm where cccc=Cond, dddd=Rd, mmmm=Rm, and 1611 // cccc01101111nnnnddddrr000111mmmm where cccc=Cond, dddd=Rd, mmmm=Rm, and
1578 // rr defined (RotationValue) rotate. 1612 // rr defined (RotationValue) rotate.
1579 constexpr IValueT Opcode = B26 | B25 | B23 | B22 | B21 | B20; 1613 constexpr IValueT UxtOpcode = B26 | B25 | B23 | B22 | B21 | B20;
1580 emitUxt(Cond, Opcode, Rd, Rn, Rm, Rotation); 1614 emitUxt(Cond, UxtOpcode, Rd, Rn, Rm, Rotation, UxtName);
1581 return; 1615 return;
1582 } 1616 }
1583 } 1617 }
1584 } 1618 }
1585 1619
1586 } // end of namespace ARM32 1620 } // end of namespace ARM32
1587 } // end of namespace Ice 1621 } // end of namespace Ice
OLDNEW
« no previous file with comments | « src/IceAssemblerARM32.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698