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

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