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

Side by Side Diff: src/IceAssemblerARM32.cpp

Issue 1540653003: Add VADD instruction to the ARM integrated assembler. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Clean up ARM register functions. Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/IceAssemblerARM32.h ('k') | src/IceConditionCodesARM32.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 //===- subzero/src/IceAssemblerARM32.cpp - Assembler for ARM32 --*- C++ -*-===// 1 //===- subzero/src/IceAssemblerARM32.cpp - Assembler for ARM32 --*- C++ -*-===//
2 // 2 //
3 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 3 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
4 // for details. All rights reserved. Use of this source code is governed by a 4 // for details. All rights reserved. Use of this source code is governed by a
5 // BSD-style license that can be found in the LICENSE file. 5 // BSD-style license that can be found in the LICENSE file.
6 // 6 //
7 // Modified by the Subzero authors. 7 // Modified by the Subzero authors.
8 // 8 //
9 //===----------------------------------------------------------------------===// 9 //===----------------------------------------------------------------------===//
10 // 10 //
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
133 } 133 }
134 134
135 IValueT encodeGPRRegister(RegARM32::GPRRegister Rn) { 135 IValueT encodeGPRRegister(RegARM32::GPRRegister Rn) {
136 return static_cast<IValueT>(Rn); 136 return static_cast<IValueT>(Rn);
137 } 137 }
138 138
139 RegARM32::GPRRegister decodeGPRRegister(IValueT R) { 139 RegARM32::GPRRegister decodeGPRRegister(IValueT R) {
140 return static_cast<RegARM32::GPRRegister>(R); 140 return static_cast<RegARM32::GPRRegister>(R);
141 } 141 }
142 142
143 bool isGPRRegisterDefined(IValueT R) {
144 return R != encodeGPRRegister(RegARM32::Encoded_Not_GPR);
145 }
146
147 bool isConditionDefined(CondARM32::Cond Cond) {
148 return Cond != CondARM32::kNone;
149 }
150
151 IValueT encodeCondition(CondARM32::Cond Cond) { 143 IValueT encodeCondition(CondARM32::Cond Cond) {
152 return static_cast<IValueT>(Cond); 144 return static_cast<IValueT>(Cond);
153 } 145 }
154 146
155 IValueT encodeShift(OperandARM32::ShiftKind Shift) { 147 IValueT encodeShift(OperandARM32::ShiftKind Shift) {
156 // Follows encoding in ARM section A8.4.1 "Constant shifts". 148 // Follows encoding in ARM section A8.4.1 "Constant shifts".
157 switch (Shift) { 149 switch (Shift) {
158 case OperandARM32::kNoShift: 150 case OperandARM32::kNoShift:
159 case OperandARM32::LSL: 151 case OperandARM32::LSL:
160 return 0; // 0b00 152 return 0; // 0b00
(...skipping 29 matching lines...) Expand all
190 DefaultOpEncoding, 182 DefaultOpEncoding,
191 // Alternate encoding 3 for memory operands (like in strb, strh, ldrb, and 183 // Alternate encoding 3 for memory operands (like in strb, strh, ldrb, and
192 // ldrh. 184 // ldrh.
193 OpEncoding3, 185 OpEncoding3,
194 // Alternate encoding for memory operands for ldrex and strex, which only 186 // Alternate encoding for memory operands for ldrex and strex, which only
195 // actually expect a register. 187 // actually expect a register.
196 OpEncodingMemEx 188 OpEncodingMemEx
197 }; 189 };
198 190
199 IValueT getEncodedGPRegNum(const Variable *Var) { 191 IValueT getEncodedGPRegNum(const Variable *Var) {
192 assert(Var->hasReg());
200 int32_t Reg = Var->getRegNum(); 193 int32_t Reg = Var->getRegNum();
201 return llvm::isa<Variable64On32>(Var) ? RegARM32::getI64PairFirstGPRNum(Reg) 194 return llvm::isa<Variable64On32>(Var) ? RegARM32::getI64PairFirstGPRNum(Reg)
202 : RegARM32::getEncodedGPR(Reg); 195 : RegARM32::getEncodedGPReg(Reg);
203 } 196 }
204 197
205 IValueT getEncodedSRegNum(const Variable *Var) { 198 IValueT getEncodedSRegNum(const Variable *Var) {
206 assert(Var->hasReg());
207 assert(RegARM32::isEncodedSReg(Var->getRegNum()));
208 return RegARM32::getEncodedSReg(Var->getRegNum()); 199 return RegARM32::getEncodedSReg(Var->getRegNum());
209 } 200 }
210 201
202 IValueT getEncodedDRegNum(const Variable *Var) {
203 return RegARM32::getEncodedDReg(Var->getRegNum());
204 }
205
206 IValueT getYInRegXXXXY(IValueT RegXXXXY) { return RegXXXXY & 0x1; }
207
208 IValueT getXXXXInRegXXXXY(IValueT RegXXXXY) { return RegXXXXY >> 1; }
209
210 IValueT getYInRegYXXXX(IValueT RegYXXXX) { return RegYXXXX >> 4; }
211
212 IValueT getXXXXInRegYXXXX(IValueT RegYXXXX) { return RegYXXXX & 0x0f; }
213
211 // The way an operand is encoded into a sequence of bits in functions 214 // The way an operand is encoded into a sequence of bits in functions
212 // encodeOperand and encodeAddress below. 215 // encodeOperand and encodeAddress below.
213 enum EncodedOperand { 216 enum EncodedOperand {
214 // Unable to encode, value left undefined. 217 // Unable to encode, value left undefined.
215 CantEncode = 0, 218 CantEncode = 0,
216 // Value is register found. 219 // Value is register found.
217 EncodedAsRegister, 220 EncodedAsRegister,
218 // Value=rrrriiiiiiii where rrrr is the rotation, and iiiiiiii is the imm8 221 // Value=rrrriiiiiiii where rrrr is the rotation, and iiiiiiii is the imm8
219 // value. 222 // value.
220 EncodedAsRotatedImm8, 223 EncodedAsRotatedImm8,
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
271 } 274 }
272 275
273 // Encodes mmmmtt01ssss for data-processing operands where mmmm=Rm, ssss=Rs, and 276 // Encodes mmmmtt01ssss for data-processing operands where mmmm=Rm, ssss=Rs, and
274 // tt=Shift. 277 // tt=Shift.
275 IValueT encodeShiftRotateReg(IValueT Rm, OperandARM32::ShiftKind Shift, 278 IValueT encodeShiftRotateReg(IValueT Rm, OperandARM32::ShiftKind Shift,
276 IValueT Rs) { 279 IValueT Rs) {
277 return (Rs << kRsShift) | (encodeShift(Shift) << kShiftShift) | B4 | 280 return (Rs << kRsShift) | (encodeShift(Shift) << kShiftShift) | B4 |
278 (Rm << kRmShift); 281 (Rm << kRmShift);
279 } 282 }
280 283
281 EncodedOperand encodeOperand(const Operand *Opnd, IValueT &Value) { 284 // Defines the set of registers expected in an operand.
285 enum RegSetWanted { WantGPRegs, WantSRegs, WantDRegs };
286
287 EncodedOperand encodeOperand(const Operand *Opnd, IValueT &Value,
288 RegSetWanted WantedRegSet) {
282 Value = 0; // Make sure initialized. 289 Value = 0; // Make sure initialized.
283 if (const auto *Var = llvm::dyn_cast<Variable>(Opnd)) { 290 if (const auto *Var = llvm::dyn_cast<Variable>(Opnd)) {
284 if (Var->hasReg()) { 291 if (Var->hasReg()) {
285 Value = getEncodedGPRegNum(Var); 292 switch (WantedRegSet) {
293 case WantGPRegs:
294 Value = getEncodedGPRegNum(Var);
295 break;
296 case WantSRegs:
297 Value = getEncodedSRegNum(Var);
298 break;
299 case WantDRegs:
300 Value = getEncodedDRegNum(Var);
301 break;
302 }
286 return EncodedAsRegister; 303 return EncodedAsRegister;
287 } 304 }
288 return CantEncode; 305 return CantEncode;
289 } 306 }
290 if (const auto *FlexImm = llvm::dyn_cast<OperandARM32FlexImm>(Opnd)) { 307 if (const auto *FlexImm = llvm::dyn_cast<OperandARM32FlexImm>(Opnd)) {
291 const IValueT Immed8 = FlexImm->getImm(); 308 const IValueT Immed8 = FlexImm->getImm();
292 const IValueT Rotate = FlexImm->getRotateAmt(); 309 const IValueT Rotate = FlexImm->getRotateAmt();
293 if (!((Rotate < (1 << kRotateBits)) && (Immed8 < (1 << kImmed8Bits)))) 310 if (!((Rotate < (1 << kRotateBits)) && (Immed8 < (1 << kImmed8Bits))))
294 return CantEncode; 311 return CantEncode;
295 Value = (Rotate << kRotateShift) | (Immed8 << kImmed8Shift); 312 Value = (Rotate << kRotateShift) | (Immed8 << kImmed8Shift);
296 return EncodedAsRotatedImm8; 313 return EncodedAsRotatedImm8;
297 } 314 }
298 if (const auto *Const = llvm::dyn_cast<ConstantInteger32>(Opnd)) { 315 if (const auto *Const = llvm::dyn_cast<ConstantInteger32>(Opnd)) {
299 Value = Const->getValue(); 316 Value = Const->getValue();
300 return EncodedAsConstI32; 317 return EncodedAsConstI32;
301 } 318 }
302 if (const auto *FlexReg = llvm::dyn_cast<OperandARM32FlexReg>(Opnd)) { 319 if (const auto *FlexReg = llvm::dyn_cast<OperandARM32FlexReg>(Opnd)) {
303 Operand *Amt = FlexReg->getShiftAmt(); 320 Operand *Amt = FlexReg->getShiftAmt();
304 IValueT Rm; 321 IValueT Rm;
305 if (encodeOperand(FlexReg->getReg(), Rm) != EncodedAsRegister) 322 if (encodeOperand(FlexReg->getReg(), Rm, WantGPRegs) != EncodedAsRegister)
306 return CantEncode; 323 return CantEncode;
307 if (const auto *Var = llvm::dyn_cast<Variable>(Amt)) { 324 if (const auto *Var = llvm::dyn_cast<Variable>(Amt)) {
308 IValueT Rs; 325 IValueT Rs;
309 if (encodeOperand(Var, Rs) != EncodedAsRegister) 326 if (encodeOperand(Var, Rs, WantGPRegs) != EncodedAsRegister)
310 return CantEncode; 327 return CantEncode;
311 Value = encodeShiftRotateReg(Rm, FlexReg->getShiftOp(), Rs); 328 Value = encodeShiftRotateReg(Rm, FlexReg->getShiftOp(), Rs);
312 return EncodedAsRegShiftReg; 329 return EncodedAsRegShiftReg;
313 } 330 }
314 // If reached, the amount is a shifted amount by some 5-bit immediate. 331 // If reached, the amount is a shifted amount by some 5-bit immediate.
315 uint32_t Imm5; 332 uint32_t Imm5;
316 if (const auto *ShAmt = llvm::dyn_cast<OperandARM32ShAmtImm>(Amt)) { 333 if (const auto *ShAmt = llvm::dyn_cast<OperandARM32ShAmtImm>(Amt)) {
317 Imm5 = ShAmt->getShAmtImm(); 334 Imm5 = ShAmt->getShAmtImm();
318 } else if (const auto *IntConst = llvm::dyn_cast<ConstantInteger32>(Amt)) { 335 } else if (const auto *IntConst = llvm::dyn_cast<ConstantInteger32>(Amt)) {
319 int32_t Val = IntConst->getValue(); 336 int32_t Val = IntConst->getValue();
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
414 } 431 }
415 return CantEncode; 432 return CantEncode;
416 } 433 }
417 434
418 // Checks that Offset can fit in imm24 constant of branch (b) instruction. 435 // Checks that Offset can fit in imm24 constant of branch (b) instruction.
419 bool canEncodeBranchOffset(IOffsetT Offset) { 436 bool canEncodeBranchOffset(IOffsetT Offset) {
420 return Utils::IsAligned(Offset, 4) && 437 return Utils::IsAligned(Offset, 4) &&
421 Utils::IsInt(kBranchOffsetBits, Offset >> 2); 438 Utils::IsInt(kBranchOffsetBits, Offset >> 2);
422 } 439 }
423 440
424 IValueT encodeRegister(const Operand *OpReg, const char *RegName, 441 IValueT encodeRegister(const Operand *OpReg, RegSetWanted WantedRegSet,
425 const char *InstName) { 442 const char *RegName, const char *InstName) {
426 IValueT Reg = 0; 443 IValueT Reg = 0;
427 if (encodeOperand(OpReg, Reg) != EncodedAsRegister) 444 if (encodeOperand(OpReg, Reg, WantedRegSet) != EncodedAsRegister)
428 llvm::report_fatal_error(std::string(InstName) + ": Can't find register " + 445 llvm::report_fatal_error(std::string(InstName) + ": Can't find register " +
429 RegName); 446 RegName);
430 return Reg; 447 return Reg;
431 } 448 }
432 449
433 void verifyRegDefined(IValueT Reg, const char *RegName, const char *InstName) { 450 IValueT encodeGPRegister(const Operand *OpReg, const char *RegName,
434 if (BuildDefs::minimal()) 451 const char *InstName) {
435 return; 452 return encodeRegister(OpReg, WantGPRegs, RegName, InstName);
436 if (!isGPRRegisterDefined(Reg))
437 llvm::report_fatal_error(std::string(InstName) + ": Can't find " + RegName);
438 } 453 }
439 454
440 void verifyCondDefined(CondARM32::Cond Cond, const char *InstName) { 455 IValueT encodeSRegister(const Operand *OpReg, const char *RegName,
441 if (BuildDefs::minimal()) 456 const char *InstName) {
442 return; 457 return encodeRegister(OpReg, WantSRegs, RegName, InstName);
443 if (!isConditionDefined(Cond)) 458 }
444 llvm::report_fatal_error(std::string(InstName) + ": Condition not defined"); 459
460 IValueT encodeDRegister(const Operand *OpReg, const char *RegName,
461 const char *InstName) {
462 return encodeRegister(OpReg, WantDRegs, RegName, InstName);
445 } 463 }
446 464
447 void verifyPOrNotW(IValueT Address, const char *InstName) { 465 void verifyPOrNotW(IValueT Address, const char *InstName) {
448 if (BuildDefs::minimal()) 466 if (BuildDefs::minimal())
449 return; 467 return;
450 if (!isBitSet(P, Address) && isBitSet(W, Address)) 468 if (!isBitSet(P, Address) && isBitSet(W, Address))
451 llvm::report_fatal_error(std::string(InstName) + 469 llvm::report_fatal_error(std::string(InstName) +
452 ": P=0 when W=1 not allowed"); 470 ": P=0 when W=1 not allowed");
453 } 471 }
454 472
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
624 IValueT Opcode, bool SetFlags, IValueT Rn, 642 IValueT Opcode, bool SetFlags, IValueT Rn,
625 IValueT Rd, IValueT Imm12, 643 IValueT Rd, IValueT Imm12,
626 EmitChecks RuleChecks, const char *InstName) { 644 EmitChecks RuleChecks, const char *InstName) {
627 switch (RuleChecks) { 645 switch (RuleChecks) {
628 case NoChecks: 646 case NoChecks:
629 break; 647 break;
630 case RdIsPcAndSetFlags: 648 case RdIsPcAndSetFlags:
631 verifyRegNotPcWhenSetFlags(Rd, SetFlags, InstName); 649 verifyRegNotPcWhenSetFlags(Rd, SetFlags, InstName);
632 break; 650 break;
633 } 651 }
634 verifyRegDefined(Rd, "Rd", InstName); 652 assert(Rd < RegARM32::getNumGPRegs());
635 verifyCondDefined(Cond, InstName); 653 assert(CondARM32::isDefined(Cond));
636 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 654 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
637 const IValueT Encoding = (encodeCondition(Cond) << kConditionShift) | 655 const IValueT Encoding = (encodeCondition(Cond) << kConditionShift) |
638 (InstType << kTypeShift) | (Opcode << kOpcodeShift) | 656 (InstType << kTypeShift) | (Opcode << kOpcodeShift) |
639 (encodeBool(SetFlags) << kSShift) | 657 (encodeBool(SetFlags) << kSShift) |
640 (Rn << kRnShift) | (Rd << kRdShift) | Imm12; 658 (Rn << kRnShift) | (Rd << kRdShift) | Imm12;
641 emitInst(Encoding); 659 emitInst(Encoding);
642 } 660 }
643 661
644 void AssemblerARM32::emitType01(CondARM32::Cond Cond, IValueT Opcode, 662 void AssemblerARM32::emitType01(CondARM32::Cond Cond, IValueT Opcode,
645 const Operand *OpRd, const Operand *OpRn, 663 const Operand *OpRd, const Operand *OpRn,
646 const Operand *OpSrc1, bool SetFlags, 664 const Operand *OpSrc1, bool SetFlags,
647 EmitChecks RuleChecks, const char *InstName) { 665 EmitChecks RuleChecks, const char *InstName) {
648 IValueT Rd = encodeRegister(OpRd, "Rd", InstName); 666 IValueT Rd = encodeGPRegister(OpRd, "Rd", InstName);
649 IValueT Rn = encodeRegister(OpRn, "Rn", InstName); 667 IValueT Rn = encodeGPRegister(OpRn, "Rn", InstName);
650 emitType01(Cond, Opcode, Rd, Rn, OpSrc1, SetFlags, RuleChecks, InstName); 668 emitType01(Cond, Opcode, Rd, Rn, OpSrc1, SetFlags, RuleChecks, InstName);
651 } 669 }
652 670
653 void AssemblerARM32::emitType01(CondARM32::Cond Cond, IValueT Opcode, 671 void AssemblerARM32::emitType01(CondARM32::Cond Cond, IValueT Opcode,
654 IValueT Rd, IValueT Rn, const Operand *OpSrc1, 672 IValueT Rd, IValueT Rn, const Operand *OpSrc1,
655 bool SetFlags, EmitChecks RuleChecks, 673 bool SetFlags, EmitChecks RuleChecks,
656 const char *InstName) { 674 const char *InstName) {
657 IValueT Src1Value; 675 IValueT Src1Value;
658 // TODO(kschimpf) Other possible decodings of data operations. 676 // TODO(kschimpf) Other possible decodings of data operations.
659 switch (encodeOperand(OpSrc1, Src1Value)) { 677 switch (encodeOperand(OpSrc1, Src1Value, WantGPRegs)) {
660 default: 678 default:
661 llvm::report_fatal_error(std::string(InstName) + 679 llvm::report_fatal_error(std::string(InstName) +
662 ": Can't encode instruction"); 680 ": Can't encode instruction");
663 return; 681 return;
664 case EncodedAsRegister: { 682 case EncodedAsRegister: {
665 // XXX (register) 683 // XXX (register)
666 // xxx{s}<c> <Rd>, <Rn>, <Rm>{, <shiff>} 684 // xxx{s}<c> <Rd>, <Rn>, <Rm>{, <shiff>}
667 // 685 //
668 // cccc000xxxxsnnnnddddiiiiitt0mmmm where cccc=Cond, xxxx=Opcode, dddd=Rd, 686 // cccc000xxxxsnnnnddddiiiiitt0mmmm where cccc=Cond, xxxx=Opcode, dddd=Rd,
669 // nnnn=Rn, mmmm=Rm, iiiii=Shift, tt=ShiftKind, and s=SetFlags. 687 // nnnn=Rn, mmmm=Rm, iiiii=Shift, tt=ShiftKind, and s=SetFlags.
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
707 // nnnn=Rn, ssss=Rs, f=SetFlags, tt is encoding of type, and 725 // nnnn=Rn, ssss=Rs, f=SetFlags, tt is encoding of type, and
708 // Src1Value=ssss01tt1mmmm. 726 // Src1Value=ssss01tt1mmmm.
709 emitType01(Cond, kInstTypeDataRegShift, Opcode, SetFlags, Rn, Rd, Src1Value, 727 emitType01(Cond, kInstTypeDataRegShift, Opcode, SetFlags, Rn, Rd, Src1Value,
710 RuleChecks, InstName); 728 RuleChecks, InstName);
711 return; 729 return;
712 } 730 }
713 } 731 }
714 } 732 }
715 733
716 void AssemblerARM32::emitType05(CondARM32::Cond Cond, IOffsetT Offset, 734 void AssemblerARM32::emitType05(CondARM32::Cond Cond, IOffsetT Offset,
717 bool Link, const char *InstName) { 735 bool Link) {
718 // cccc101liiiiiiiiiiiiiiiiiiiiiiii where cccc=Cond, l=Link, and 736 // cccc101liiiiiiiiiiiiiiiiiiiiiiii where cccc=Cond, l=Link, and
719 // iiiiiiiiiiiiiiiiiiiiiiii= 737 // iiiiiiiiiiiiiiiiiiiiiiii=
720 // EncodedBranchOffset(cccc101l000000000000000000000000, Offset); 738 // EncodedBranchOffset(cccc101l000000000000000000000000, Offset);
721 verifyCondDefined(Cond, InstName); 739 assert(CondARM32::isDefined(Cond));
722 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 740 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
723 IValueT Encoding = static_cast<int32_t>(Cond) << kConditionShift | 741 IValueT Encoding = static_cast<int32_t>(Cond) << kConditionShift |
724 5 << kTypeShift | (Link ? 1 : 0) << kLinkShift; 742 5 << kTypeShift | (Link ? 1 : 0) << kLinkShift;
725 Encoding = encodeBranchOffset(Offset, Encoding); 743 Encoding = encodeBranchOffset(Offset, Encoding);
726 emitInst(Encoding); 744 emitInst(Encoding);
727 } 745 }
728 746
729 void AssemblerARM32::emitBranch(Label *L, CondARM32::Cond Cond, bool Link) { 747 void AssemblerARM32::emitBranch(Label *L, CondARM32::Cond Cond, bool Link) {
730 // TODO(kschimpf): Handle far jumps. 748 // TODO(kschimpf): Handle far jumps.
731 constexpr const char *BranchName = "b";
732 if (L->isBound()) { 749 if (L->isBound()) {
733 const int32_t Dest = L->getPosition() - Buffer.size(); 750 const int32_t Dest = L->getPosition() - Buffer.size();
734 emitType05(Cond, Dest, Link, BranchName); 751 emitType05(Cond, Dest, Link);
735 return; 752 return;
736 } 753 }
737 const IOffsetT Position = Buffer.size(); 754 const IOffsetT Position = Buffer.size();
738 // Use the offset field of the branch instruction for linking the sites. 755 // Use the offset field of the branch instruction for linking the sites.
739 emitType05(Cond, L->getEncodedPosition(), Link, BranchName); 756 emitType05(Cond, L->getEncodedPosition(), Link);
740 L->linkTo(*this, Position); 757 L->linkTo(*this, Position);
741 } 758 }
742 759
743 void AssemblerARM32::emitCompareOp(CondARM32::Cond Cond, IValueT Opcode, 760 void AssemblerARM32::emitCompareOp(CondARM32::Cond Cond, IValueT Opcode,
744 const Operand *OpRn, const Operand *OpSrc1, 761 const Operand *OpRn, const Operand *OpSrc1,
745 const char *InstName) { 762 const char *InstName) {
746 // XXX (register) 763 // XXX (register)
747 // XXX<c> <Rn>, <Rm>{, <shift>} 764 // XXX<c> <Rn>, <Rm>{, <shift>}
748 // 765 //
749 // ccccyyyxxxx1nnnn0000iiiiitt0mmmm where cccc=Cond, nnnn=Rn, mmmm=Rm, iiiii 766 // ccccyyyxxxx1nnnn0000iiiiitt0mmmm where cccc=Cond, nnnn=Rn, mmmm=Rm, iiiii
750 // defines shift constant, tt=ShiftKind, yyy=kInstTypeDataRegister, and 767 // defines shift constant, tt=ShiftKind, yyy=kInstTypeDataRegister, and
751 // xxxx=Opcode. 768 // xxxx=Opcode.
752 // 769 //
753 // XXX (immediate) 770 // XXX (immediate)
754 // XXX<c> <Rn>, #<RotatedImm8> 771 // XXX<c> <Rn>, #<RotatedImm8>
755 // 772 //
756 // ccccyyyxxxx1nnnn0000iiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn, 773 // ccccyyyxxxx1nnnn0000iiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn,
757 // yyy=kInstTypeDataImmdiate, xxxx=Opcode, and iiiiiiiiiiii=Src1Value 774 // yyy=kInstTypeDataImmdiate, xxxx=Opcode, and iiiiiiiiiiii=Src1Value
758 // defining RotatedImm8. 775 // defining RotatedImm8.
759 constexpr bool SetFlags = true; 776 constexpr bool SetFlags = true;
760 constexpr IValueT Rd = RegARM32::Encoded_Reg_r0; 777 constexpr IValueT Rd = RegARM32::Encoded_Reg_r0;
761 IValueT Rn = encodeRegister(OpRn, "Rn", InstName); 778 IValueT Rn = encodeGPRegister(OpRn, "Rn", InstName);
762 emitType01(Cond, Opcode, Rd, Rn, OpSrc1, SetFlags, NoChecks, InstName); 779 emitType01(Cond, Opcode, Rd, Rn, OpSrc1, SetFlags, NoChecks, InstName);
763 } 780 }
764 781
765 void AssemblerARM32::emitMemOp(CondARM32::Cond Cond, IValueT InstType, 782 void AssemblerARM32::emitMemOp(CondARM32::Cond Cond, IValueT InstType,
766 bool IsLoad, bool IsByte, IValueT Rt, 783 bool IsLoad, bool IsByte, IValueT Rt,
767 IValueT Address, const char *InstName) { 784 IValueT Address) {
768 verifyRegDefined(Rt, "Rt", InstName); 785 assert(Rt < RegARM32::getNumGPRegs());
769 verifyCondDefined(Cond, InstName); 786 assert(CondARM32::isDefined(Cond));
770 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 787 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
771 const IValueT Encoding = (encodeCondition(Cond) << kConditionShift) | 788 const IValueT Encoding = (encodeCondition(Cond) << kConditionShift) |
772 (InstType << kTypeShift) | (IsLoad ? L : 0) | 789 (InstType << kTypeShift) | (IsLoad ? L : 0) |
773 (IsByte ? B : 0) | (Rt << kRdShift) | Address; 790 (IsByte ? B : 0) | (Rt << kRdShift) | Address;
774 emitInst(Encoding); 791 emitInst(Encoding);
775 } 792 }
776 793
777 void AssemblerARM32::emitMemOp(CondARM32::Cond Cond, bool IsLoad, bool IsByte, 794 void AssemblerARM32::emitMemOp(CondARM32::Cond Cond, bool IsLoad, bool IsByte,
778 IValueT Rt, const Operand *OpAddress, 795 IValueT Rt, const Operand *OpAddress,
779 const TargetInfo &TInfo, const char *InstName) { 796 const TargetInfo &TInfo, const char *InstName) {
(...skipping 15 matching lines...) Expand all
795 812
796 // Check if conditions of rules violated. 813 // Check if conditions of rules violated.
797 verifyRegNotPc(Rn, "Rn", InstName); 814 verifyRegNotPc(Rn, "Rn", InstName);
798 verifyPOrNotW(Address, InstName); 815 verifyPOrNotW(Address, InstName);
799 if (!IsByte && (Rn == RegARM32::Encoded_Reg_sp) && !isBitSet(P, Address) && 816 if (!IsByte && (Rn == RegARM32::Encoded_Reg_sp) && !isBitSet(P, Address) &&
800 isBitSet(U, Address) && !isBitSet(W, Address) && 817 isBitSet(U, Address) && !isBitSet(W, Address) &&
801 (mask(Address, kImm12Shift, kImmed12Bits) == 0x8 /* 000000000100 */)) 818 (mask(Address, kImm12Shift, kImmed12Bits) == 0x8 /* 000000000100 */))
802 llvm::report_fatal_error(std::string(InstName) + 819 llvm::report_fatal_error(std::string(InstName) +
803 ": Use push/pop instead"); 820 ": Use push/pop instead");
804 821
805 emitMemOp(Cond, kInstTypeMemImmediate, IsLoad, IsByte, Rt, Address, 822 emitMemOp(Cond, kInstTypeMemImmediate, IsLoad, IsByte, Rt, Address);
806 InstName);
807 return; 823 return;
808 } 824 }
809 case EncodedAsShiftRotateImm5: { 825 case EncodedAsShiftRotateImm5: {
810 // XXX{B} (register) 826 // XXX{B} (register)
811 // xxx{b}<c> <Rt>, [<Rn>, +/-<Rm>{, <shift>}]{!} 827 // xxx{b}<c> <Rt>, [<Rn>, +/-<Rm>{, <shift>}]{!}
812 // xxx{b}<c> <Rt>, [<Rn>], +/-<Rm>{, <shift>} 828 // xxx{b}<c> <Rt>, [<Rn>], +/-<Rm>{, <shift>}
813 // 829 //
814 // cccc011pubwlnnnnttttiiiiiss0mmmm where cccc=Cond, tttt=Rt, 830 // cccc011pubwlnnnnttttiiiiiss0mmmm where cccc=Cond, tttt=Rt,
815 // b=IsByte, U=1 if +, pu0b is a BlockAddr, l=IsLoad, and 831 // b=IsByte, U=1 if +, pu0b is a BlockAddr, l=IsLoad, and
816 // pu0w0nnnn0000iiiiiss0mmmm=Address. 832 // pu0w0nnnn0000iiiiiss0mmmm=Address.
817 RegARM32::GPRRegister Rn = getGPRReg(kRnShift, Address); 833 RegARM32::GPRRegister Rn = getGPRReg(kRnShift, Address);
818 RegARM32::GPRRegister Rm = getGPRReg(kRmShift, Address); 834 RegARM32::GPRRegister Rm = getGPRReg(kRmShift, Address);
819 835
820 // Check if conditions of rules violated. 836 // Check if conditions of rules violated.
821 verifyPOrNotW(Address, InstName); 837 verifyPOrNotW(Address, InstName);
822 verifyRegNotPc(Rm, "Rm", InstName); 838 verifyRegNotPc(Rm, "Rm", InstName);
823 if (IsByte) 839 if (IsByte)
824 verifyRegNotPc(Rt, "Rt", InstName); 840 verifyRegNotPc(Rt, "Rt", InstName);
825 if (isBitSet(W, Address)) { 841 if (isBitSet(W, Address)) {
826 verifyRegNotPc(Rn, "Rn", InstName); 842 verifyRegNotPc(Rn, "Rn", InstName);
827 verifyRegsNotEq(Rn, "Rn", Rt, "Rt", InstName); 843 verifyRegsNotEq(Rn, "Rn", Rt, "Rt", InstName);
828 } 844 }
829 emitMemOp(Cond, kInstTypeRegisterShift, IsLoad, IsByte, Rt, Address, 845 emitMemOp(Cond, kInstTypeRegisterShift, IsLoad, IsByte, Rt, Address);
830 InstName);
831 return; 846 return;
832 } 847 }
833 } 848 }
834 } 849 }
835 850
836 void AssemblerARM32::emitMemOpEnc3(CondARM32::Cond Cond, IValueT Opcode, 851 void AssemblerARM32::emitMemOpEnc3(CondARM32::Cond Cond, IValueT Opcode,
837 IValueT Rt, const Operand *OpAddress, 852 IValueT Rt, const Operand *OpAddress,
838 const TargetInfo &TInfo, 853 const TargetInfo &TInfo,
839 const char *InstName) { 854 const char *InstName) {
840 IValueT Address; 855 IValueT Address;
841 switch (encodeAddress(OpAddress, Address, TInfo, OpEncoding3)) { 856 switch (encodeAddress(OpAddress, Address, TInfo, OpEncoding3)) {
842 default: 857 default:
843 llvm::report_fatal_error(std::string(InstName) + 858 llvm::report_fatal_error(std::string(InstName) +
844 ": Memory address not understood"); 859 ": Memory address not understood");
845 case EncodedAsImmRegOffset: { 860 case EncodedAsImmRegOffset: {
846 // XXXH (immediate) 861 // XXXH (immediate)
847 // xxxh<c> <Rt>, [<Rn>{, #+-<Imm8>}] 862 // xxxh<c> <Rt>, [<Rn>{, #+-<Imm8>}]
848 // xxxh<c> <Rt>, [<Rn>, #+/-<Imm8>] 863 // xxxh<c> <Rt>, [<Rn>, #+/-<Imm8>]
849 // xxxh<c> <Rt>, [<Rn>, #+/-<Imm8>]! 864 // xxxh<c> <Rt>, [<Rn>, #+/-<Imm8>]!
850 // 865 //
851 // cccc000pu0wxnnnnttttiiiiyyyyjjjj where cccc=Cond, nnnn=Rn, tttt=Rt, 866 // cccc000pu0wxnnnnttttiiiiyyyyjjjj where cccc=Cond, nnnn=Rn, tttt=Rt,
852 // iiiijjjj=Imm8, pu0w<<21 is a BlockAddr, x000000000000yyyy0000=Opcode, 867 // iiiijjjj=Imm8, pu0w<<21 is a BlockAddr, x000000000000yyyy0000=Opcode,
853 // and pu0w0nnnn0000iiii0000jjjj=Address. 868 // and pu0w0nnnn0000iiii0000jjjj=Address.
854 verifyRegDefined(Rt, "Rt", InstName); 869 assert(Rt < RegARM32::getNumGPRegs());
855 verifyCondDefined(Cond, InstName); 870 assert(CondARM32::isDefined(Cond));
856 verifyPOrNotW(Address, InstName); 871 verifyPOrNotW(Address, InstName);
857 verifyRegNotPc(Rt, "Rt", InstName); 872 verifyRegNotPc(Rt, "Rt", InstName);
858 if (isBitSet(W, Address)) 873 if (isBitSet(W, Address))
859 verifyRegsNotEq(getGPRReg(kRnShift, Address), "Rn", Rt, "Rt", InstName); 874 verifyRegsNotEq(getGPRReg(kRnShift, Address), "Rn", Rt, "Rt", InstName);
860 const IValueT Encoding = (encodeCondition(Cond) << kConditionShift) | 875 const IValueT Encoding = (encodeCondition(Cond) << kConditionShift) |
861 Opcode | (Rt << kRdShift) | Address; 876 Opcode | (Rt << kRdShift) | Address;
862 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 877 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
863 emitInst(Encoding); 878 emitInst(Encoding);
864 return; 879 return;
865 } 880 }
866 case EncodedAsShiftRotateImm5: { 881 case EncodedAsShiftRotateImm5: {
867 // XXXH (register) 882 // XXXH (register)
868 // xxxh<c> <Rt>, [<Rn>, +/-<Rm>]{!} 883 // xxxh<c> <Rt>, [<Rn>, +/-<Rm>]{!}
869 // xxxh<c> <Rt>, [<Rn>], +/-<Rm> 884 // xxxh<c> <Rt>, [<Rn>], +/-<Rm>
870 // 885 //
871 // cccc000pu0wxnnnntttt00001011mmmm where cccc=Cond, tttt=Rt, nnnn=Rn, 886 // cccc000pu0wxnnnntttt00001011mmmm where cccc=Cond, tttt=Rt, nnnn=Rn,
872 // mmmm=Rm, pu0w<<21 is a BlockAddr, x000000000000yyyy0000=Opcode, and 887 // mmmm=Rm, pu0w<<21 is a BlockAddr, x000000000000yyyy0000=Opcode, and
873 // pu0w0nnnn000000000000mmmm=Address. 888 // pu0w0nnnn000000000000mmmm=Address.
874 verifyRegDefined(Rt, "Rt", InstName); 889 assert(Rt < RegARM32::getNumGPRegs());
875 verifyCondDefined(Cond, InstName); 890 assert(CondARM32::isDefined(Cond));
876 verifyPOrNotW(Address, InstName); 891 verifyPOrNotW(Address, InstName);
877 verifyRegNotPc(Rt, "Rt", InstName); 892 verifyRegNotPc(Rt, "Rt", InstName);
878 verifyAddrRegNotPc(kRmShift, Address, "Rm", InstName); 893 verifyAddrRegNotPc(kRmShift, Address, "Rm", InstName);
879 const RegARM32::GPRRegister Rn = getGPRReg(kRnShift, Address); 894 const RegARM32::GPRRegister Rn = getGPRReg(kRnShift, Address);
880 if (isBitSet(W, Address)) { 895 if (isBitSet(W, Address)) {
881 verifyRegNotPc(Rn, "Rn", InstName); 896 verifyRegNotPc(Rn, "Rn", InstName);
882 verifyRegsNotEq(Rn, "Rn", Rt, "Rt", InstName); 897 verifyRegsNotEq(Rn, "Rn", Rt, "Rt", InstName);
883 } 898 }
884 if (mask(Address, kShiftImmShift, 5) != 0) 899 if (mask(Address, kShiftImmShift, 5) != 0)
885 // For encoding 3, no shift is allowed. 900 // For encoding 3, no shift is allowed.
886 llvm::report_fatal_error(std::string(InstName) + 901 llvm::report_fatal_error(std::string(InstName) +
887 ": Shift constant not allowed"); 902 ": Shift constant not allowed");
888 const IValueT Encoding = (encodeCondition(Cond) << kConditionShift) | 903 const IValueT Encoding = (encodeCondition(Cond) << kConditionShift) |
889 Opcode | (Rt << kRdShift) | Address; 904 Opcode | (Rt << kRdShift) | Address;
890 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 905 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
891 emitInst(Encoding); 906 emitInst(Encoding);
892 return; 907 return;
893 } 908 }
894 } 909 }
895 } 910 }
896 911
897 void AssemblerARM32::emitDivOp(CondARM32::Cond Cond, IValueT Opcode, IValueT Rd, 912 void AssemblerARM32::emitDivOp(CondARM32::Cond Cond, IValueT Opcode, IValueT Rd,
898 IValueT Rn, IValueT Rm, const char *InstName) { 913 IValueT Rn, IValueT Rm) {
899 verifyRegDefined(Rd, "Rd", InstName); 914 assert(Rd < RegARM32::getNumGPRegs());
900 verifyRegDefined(Rn, "Rn", InstName); 915 assert(Rn < RegARM32::getNumGPRegs());
901 verifyRegDefined(Rm, "Rm", InstName); 916 assert(Rm < RegARM32::getNumGPRegs());
902 verifyCondDefined(Cond, InstName); 917 assert(CondARM32::isDefined(Cond));
903 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 918 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
904 const IValueT Encoding = Opcode | (encodeCondition(Cond) << kConditionShift) | 919 const IValueT Encoding = Opcode | (encodeCondition(Cond) << kConditionShift) |
905 (Rn << kDivRnShift) | (Rd << kDivRdShift) | B26 | 920 (Rn << kDivRnShift) | (Rd << kDivRdShift) | B26 |
906 B25 | B24 | B20 | B15 | B14 | B13 | B12 | B4 | 921 B25 | B24 | B20 | B15 | B14 | B13 | B12 | B4 |
907 (Rm << kDivRmShift); 922 (Rm << kDivRmShift);
908 emitInst(Encoding); 923 emitInst(Encoding);
909 } 924 }
910 925
911 void AssemblerARM32::emitMulOp(CondARM32::Cond Cond, IValueT Opcode, IValueT Rd, 926 void AssemblerARM32::emitMulOp(CondARM32::Cond Cond, IValueT Opcode, IValueT Rd,
912 IValueT Rn, IValueT Rm, IValueT Rs, 927 IValueT Rn, IValueT Rm, IValueT Rs,
913 bool SetFlags, const char *InstName) { 928 bool SetFlags) {
914 verifyRegDefined(Rd, "Rd", InstName); 929 assert(Rd < RegARM32::getNumGPRegs());
915 verifyRegDefined(Rn, "Rn", InstName); 930 assert(Rn < RegARM32::getNumGPRegs());
916 verifyRegDefined(Rm, "Rm", InstName); 931 assert(Rm < RegARM32::getNumGPRegs());
917 verifyRegDefined(Rs, "Rs", InstName); 932 assert(Rs < RegARM32::getNumGPRegs());
918 verifyCondDefined(Cond, InstName); 933 assert(CondARM32::isDefined(Cond));
919 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 934 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
920 IValueT Encoding = Opcode | (encodeCondition(Cond) << kConditionShift) | 935 IValueT Encoding = Opcode | (encodeCondition(Cond) << kConditionShift) |
921 (encodeBool(SetFlags) << kSShift) | (Rn << kRnShift) | 936 (encodeBool(SetFlags) << kSShift) | (Rn << kRnShift) |
922 (Rd << kRdShift) | (Rs << kRsShift) | B7 | B4 | 937 (Rd << kRdShift) | (Rs << kRsShift) | B7 | B4 |
923 (Rm << kRmShift); 938 (Rm << kRmShift);
924 emitInst(Encoding); 939 emitInst(Encoding);
925 } 940 }
926 941
927 void AssemblerARM32::emitMultiMemOp(CondARM32::Cond Cond, 942 void AssemblerARM32::emitMultiMemOp(CondARM32::Cond Cond,
928 BlockAddressMode AddressMode, bool IsLoad, 943 BlockAddressMode AddressMode, bool IsLoad,
929 IValueT BaseReg, IValueT Registers, 944 IValueT BaseReg, IValueT Registers) {
930 const char *InstName) { 945 assert(CondARM32::isDefined(Cond));
931 constexpr IValueT NumGPRegisters = 16; 946 assert(BaseReg < RegARM32::getNumGPRegs());
932 verifyCondDefined(Cond, InstName); 947 assert(Registers < (1 << RegARM32::getNumGPRegs()));
933 verifyRegDefined(BaseReg, "base", InstName);
934 if (Registers >= (1 << NumGPRegisters))
935 llvm::report_fatal_error(std::string(InstName) +
936 ": Register set too large");
937 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 948 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
938 IValueT Encoding = (encodeCondition(Cond) << kConditionShift) | B27 | 949 IValueT Encoding = (encodeCondition(Cond) << kConditionShift) | B27 |
939 AddressMode | (IsLoad ? L : 0) | (BaseReg << kRnShift) | 950 AddressMode | (IsLoad ? L : 0) | (BaseReg << kRnShift) |
940 Registers; 951 Registers;
941 emitInst(Encoding); 952 emitInst(Encoding);
942 } 953 }
943 954
944 void AssemblerARM32::emitSignExtend(CondARM32::Cond Cond, IValueT Opcode, 955 void AssemblerARM32::emitSignExtend(CondARM32::Cond Cond, IValueT Opcode,
945 const Operand *OpRd, const Operand *OpSrc0, 956 const Operand *OpRd, const Operand *OpSrc0,
946 const char *InstName) { 957 const char *InstName) {
947 IValueT Rd = encodeRegister(OpRd, "Rd", InstName); 958 IValueT Rd = encodeGPRegister(OpRd, "Rd", InstName);
948 IValueT Rm = encodeRegister(OpSrc0, "Rm", InstName); 959 IValueT Rm = encodeGPRegister(OpSrc0, "Rm", InstName);
949 // Note: For the moment, we assume no rotation is specified. 960 // Note: For the moment, we assume no rotation is specified.
950 RotationValue Rotation = kRotateNone; 961 RotationValue Rotation = kRotateNone;
951 constexpr IValueT Rn = RegARM32::Encoded_Reg_pc; 962 constexpr IValueT Rn = RegARM32::Encoded_Reg_pc;
952 const Type Ty = OpSrc0->getType(); 963 const Type Ty = OpSrc0->getType();
953 switch (Ty) { 964 switch (Ty) {
954 default: 965 default:
955 llvm::report_fatal_error(std::string(InstName) + ": Type " + 966 llvm::report_fatal_error(std::string(InstName) + ": Type " +
956 typeString(Ty) + " not allowed"); 967 typeString(Ty) + " not allowed");
957 break; 968 break;
958 case IceType_i1: 969 case IceType_i1:
(...skipping 10 matching lines...) Expand all
969 // SXTH/UXTH - ARM sections A8.8.235 and A8.8.276, encoding A1: 980 // SXTH/UXTH - ARM sections A8.8.235 and A8.8.276, encoding A1:
970 // uxth<c> <Rd>< <Rm>{, <rotate>} 981 // uxth<c> <Rd>< <Rm>{, <rotate>}
971 // 982 //
972 // cccc01101111nnnnddddrr000111mmmm where cccc=Cond, dddd=Rd, mmmm=Rm, and 983 // cccc01101111nnnnddddrr000111mmmm where cccc=Cond, dddd=Rd, mmmm=Rm, and
973 // rr defined (RotationValue) rotate. 984 // rr defined (RotationValue) rotate.
974 Opcode |= B20; 985 Opcode |= B20;
975 break; 986 break;
976 } 987 }
977 } 988 }
978 989
979 verifyCondDefined(Cond, InstName); 990 assert(CondARM32::isDefined(Cond));
980 IValueT Rot = encodeRotation(Rotation); 991 IValueT Rot = encodeRotation(Rotation);
981 if (!Utils::IsUint(2, Rot)) 992 if (!Utils::IsUint(2, Rot))
982 llvm::report_fatal_error(std::string(InstName) + 993 llvm::report_fatal_error(std::string(InstName) +
983 ": Illegal rotation value"); 994 ": Illegal rotation value");
984 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 995 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
985 IValueT Encoding = (encodeCondition(Cond) << kConditionShift) | Opcode | 996 IValueT Encoding = (encodeCondition(Cond) << kConditionShift) | Opcode |
986 (Rn << kRnShift) | (Rd << kRdShift) | 997 (Rn << kRnShift) | (Rd << kRdShift) |
987 (Rot << kRotationShift) | B6 | B5 | B4 | (Rm << kRmShift); 998 (Rot << kRotationShift) | B6 | B5 | B4 | (Rm << kRmShift);
988 emitInst(Encoding); 999 emitInst(Encoding);
989 } 1000 }
990 1001
1002 void AssemblerARM32::emitVFPddd(CondARM32::Cond Cond, IValueT Opcode,
1003 IValueT Dd, IValueT Dn, IValueT Dm) {
1004 assert(Dd < RegARM32::getNumDRegs());
1005 assert(Dn < RegARM32::getNumDRegs());
1006 assert(Dm < RegARM32::getNumDRegs());
1007 assert(CondARM32::isDefined(Cond));
1008 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1009 constexpr IValueT VFPOpcode = B27 | B26 | B25 | B11 | B9 | B8;
1010 const IValueT Encoding =
1011 Opcode | VFPOpcode | (encodeCondition(Cond) << kConditionShift) |
1012 (getYInRegYXXXX(Dd) << 22) | (getXXXXInRegYXXXX(Dn) << 16) |
1013 (getXXXXInRegYXXXX(Dn) << 12) | (getYInRegYXXXX(Dn) << 7) |
1014 (getYInRegYXXXX(Dm) << 5) | getXXXXInRegYXXXX(Dm);
1015 emitInst(Encoding);
1016 }
1017
1018 void AssemblerARM32::emitVFPsss(CondARM32::Cond Cond, IValueT Opcode,
1019 IValueT Sd, IValueT Sn, IValueT Sm) {
1020 assert(Sd < RegARM32::getNumSRegs());
1021 assert(Sn < RegARM32::getNumSRegs());
1022 assert(Sm < RegARM32::getNumSRegs());
1023 assert(CondARM32::isDefined(Cond));
1024 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1025 constexpr IValueT VFPOpcode = B27 | B26 | B25 | B11 | B9;
1026 const IValueT Encoding =
1027 Opcode | VFPOpcode | (encodeCondition(Cond) << kConditionShift) |
1028 (getYInRegXXXXY(Sd) << 22) | (getXXXXInRegXXXXY(Sn) << 16) |
1029 (getXXXXInRegXXXXY(Sd) << 12) | (getYInRegXXXXY(Sn) << 7) |
1030 (getYInRegXXXXY(Sm) << 5) | getXXXXInRegXXXXY(Sm);
1031 emitInst(Encoding);
1032 }
1033
991 void AssemblerARM32::adc(const Operand *OpRd, const Operand *OpRn, 1034 void AssemblerARM32::adc(const Operand *OpRd, const Operand *OpRn,
992 const Operand *OpSrc1, bool SetFlags, 1035 const Operand *OpSrc1, bool SetFlags,
993 CondARM32::Cond Cond) { 1036 CondARM32::Cond Cond) {
994 // ADC (register) - ARM section 18.8.2, encoding A1: 1037 // ADC (register) - ARM section 18.8.2, encoding A1:
995 // adc{s}<c> <Rd>, <Rn>, <Rm>{, <shift>} 1038 // adc{s}<c> <Rd>, <Rn>, <Rm>{, <shift>}
996 // 1039 //
997 // cccc0000101snnnnddddiiiiitt0mmmm where cccc=Cond, dddd=Rd, nnnn=Rn, 1040 // cccc0000101snnnnddddiiiiitt0mmmm where cccc=Cond, dddd=Rd, nnnn=Rn,
998 // mmmm=Rm, iiiii=Shift, tt=ShiftKind, and s=SetFlags. 1041 // mmmm=Rm, iiiii=Shift, tt=ShiftKind, and s=SetFlags.
999 // 1042 //
1000 // ADC (Immediate) - ARM section A8.8.1, encoding A1: 1043 // ADC (Immediate) - ARM section A8.8.1, encoding A1:
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
1087 BicName); 1130 BicName);
1088 } 1131 }
1089 1132
1090 void AssemblerARM32::bl(const ConstantRelocatable *Target) { 1133 void AssemblerARM32::bl(const ConstantRelocatable *Target) {
1091 // BL (immediate) - ARM section A8.8.25, encoding A1: 1134 // BL (immediate) - ARM section A8.8.25, encoding A1:
1092 // bl<c> <label> 1135 // bl<c> <label>
1093 // 1136 //
1094 // cccc1011iiiiiiiiiiiiiiiiiiiiiiii where cccc=Cond (not currently allowed) 1137 // cccc1011iiiiiiiiiiiiiiiiiiiiiiii where cccc=Cond (not currently allowed)
1095 // and iiiiiiiiiiiiiiiiiiiiiiii is the (encoded) Target to branch to. 1138 // and iiiiiiiiiiiiiiiiiiiiiiii is the (encoded) Target to branch to.
1096 emitFixup(createBlFixup(Target)); 1139 emitFixup(createBlFixup(Target));
1097 constexpr const char *BlName = "bl";
1098 constexpr CondARM32::Cond Cond = CondARM32::AL; 1140 constexpr CondARM32::Cond Cond = CondARM32::AL;
1099 constexpr IValueT Immed = 0; 1141 constexpr IValueT Immed = 0;
1100 constexpr bool Link = true; 1142 constexpr bool Link = true;
1101 emitType05(Cond, Immed, Link, BlName); 1143 emitType05(Cond, Immed, Link);
1102 } 1144 }
1103 1145
1104 void AssemblerARM32::blx(const Operand *Target) { 1146 void AssemblerARM32::blx(const Operand *Target) {
1105 // BLX (register) - ARM section A8.8.26, encoding A1: 1147 // BLX (register) - ARM section A8.8.26, encoding A1:
1106 // blx<c> <Rm> 1148 // blx<c> <Rm>
1107 // 1149 //
1108 // cccc000100101111111111110011mmmm where cccc=Cond (not currently allowed) 1150 // cccc000100101111111111110011mmmm where cccc=Cond (not currently allowed)
1109 // and mmmm=Rm. 1151 // and mmmm=Rm.
1110 constexpr const char *BlxName = "Blx"; 1152 constexpr const char *BlxName = "Blx";
1111 IValueT Rm = encodeRegister(Target, "Rm", BlxName); 1153 IValueT Rm = encodeGPRegister(Target, "Rm", BlxName);
1112 verifyRegNotPc(Rm, "Rm", BlxName); 1154 verifyRegNotPc(Rm, "Rm", BlxName);
1113 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 1155 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1114 constexpr CondARM32::Cond Cond = CondARM32::AL; 1156 constexpr CondARM32::Cond Cond = CondARM32::AL;
1115 int32_t Encoding = (encodeCondition(Cond) << kConditionShift) | B24 | B21 | 1157 int32_t Encoding = (encodeCondition(Cond) << kConditionShift) | B24 | B21 |
1116 (0xfff << 8) | B5 | B4 | (Rm << kRmShift); 1158 (0xfff << 8) | B5 | B4 | (Rm << kRmShift);
1117 emitInst(Encoding); 1159 emitInst(Encoding);
1118 } 1160 }
1119 1161
1120 void AssemblerARM32::bx(RegARM32::GPRRegister Rm, CondARM32::Cond Cond) { 1162 void AssemblerARM32::bx(RegARM32::GPRRegister Rm, CondARM32::Cond Cond) {
1121 // BX - ARM section A8.8.27, encoding A1: 1163 // BX - ARM section A8.8.27, encoding A1:
1122 // bx<c> <Rm> 1164 // bx<c> <Rm>
1123 // 1165 //
1124 // cccc000100101111111111110001mmmm where mmmm=rm and cccc=Cond. 1166 // cccc000100101111111111110001mmmm where mmmm=rm and cccc=Cond.
1125 constexpr const char *BxName = "bx"; 1167 assert(CondARM32::isDefined(Cond));
1126 verifyCondDefined(Cond, BxName);
1127 verifyRegDefined(Rm, "Rm", BxName);
1128 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 1168 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1129 const IValueT Encoding = (encodeCondition(Cond) << kConditionShift) | B24 | 1169 const IValueT Encoding = (encodeCondition(Cond) << kConditionShift) | B24 |
1130 B21 | (0xfff << 8) | B4 | 1170 B21 | (0xfff << 8) | B4 |
1131 (encodeGPRRegister(Rm) << kRmShift); 1171 (encodeGPRRegister(Rm) << kRmShift);
1132 emitInst(Encoding); 1172 emitInst(Encoding);
1133 } 1173 }
1134 1174
1135 void AssemblerARM32::clz(const Operand *OpRd, const Operand *OpSrc, 1175 void AssemblerARM32::clz(const Operand *OpRd, const Operand *OpSrc,
1136 CondARM32::Cond Cond) { 1176 CondARM32::Cond Cond) {
1137 // CLZ - ARM section A8.8.33, encoding A1: 1177 // CLZ - ARM section A8.8.33, encoding A1:
1138 // clz<c> <Rd> <Rm> 1178 // clz<c> <Rd> <Rm>
1139 // 1179 //
1140 // cccc000101101111dddd11110001mmmm where cccc=Cond, dddd=Rd, and mmmm=Rm. 1180 // cccc000101101111dddd11110001mmmm where cccc=Cond, dddd=Rd, and mmmm=Rm.
1141 constexpr const char *ClzName = "clz"; 1181 constexpr const char *ClzName = "clz";
1142 constexpr const char *RdName = "Rd"; 1182 constexpr const char *RdName = "Rd";
1143 constexpr const char *RmName = "Rm"; 1183 constexpr const char *RmName = "Rm";
1144 IValueT Rd = encodeRegister(OpRd, RdName, ClzName); 1184 IValueT Rd = encodeGPRegister(OpRd, RdName, ClzName);
1145 verifyRegDefined(Rd, RdName, ClzName); 1185 assert(Rd < RegARM32::getNumGPRegs());
1146 verifyRegNotPc(Rd, RdName, ClzName); 1186 verifyRegNotPc(Rd, RdName, ClzName);
1147 IValueT Rm = encodeRegister(OpSrc, RmName, ClzName); 1187 IValueT Rm = encodeGPRegister(OpSrc, RmName, ClzName);
1148 verifyRegDefined(Rm, RmName, ClzName); 1188 assert(Rm < RegARM32::getNumGPRegs());
1149 verifyRegNotPc(Rm, RmName, ClzName); 1189 verifyRegNotPc(Rm, RmName, ClzName);
1150 verifyCondDefined(Cond, ClzName); 1190 assert(CondARM32::isDefined(Cond));
1151 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 1191 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1152 constexpr IValueT PredefinedBits = 1192 constexpr IValueT PredefinedBits =
1153 B24 | B22 | B21 | (0xF << 16) | (0xf << 8) | B4; 1193 B24 | B22 | B21 | (0xF << 16) | (0xf << 8) | B4;
1154 const IValueT Encoding = PredefinedBits | (Cond << kConditionShift) | 1194 const IValueT Encoding = PredefinedBits | (Cond << kConditionShift) |
1155 (Rd << kRdShift) | (Rm << kRmShift); 1195 (Rd << kRdShift) | (Rm << kRmShift);
1156 emitInst(Encoding); 1196 emitInst(Encoding);
1157 } 1197 }
1158 1198
1159 void AssemblerARM32::cmn(const Operand *OpRn, const Operand *OpSrc1, 1199 void AssemblerARM32::cmn(const Operand *OpRn, const Operand *OpSrc1,
1160 CondARM32::Cond Cond) { 1200 CondARM32::Cond Cond) {
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
1223 constexpr const char *EorName = "eor"; 1263 constexpr const char *EorName = "eor";
1224 constexpr IValueT EorOpcode = B0; // 0001 1264 constexpr IValueT EorOpcode = B0; // 0001
1225 emitType01(Cond, EorOpcode, OpRd, OpRn, OpSrc1, SetFlags, RdIsPcAndSetFlags, 1265 emitType01(Cond, EorOpcode, OpRd, OpRn, OpSrc1, SetFlags, RdIsPcAndSetFlags,
1226 EorName); 1266 EorName);
1227 } 1267 }
1228 1268
1229 void AssemblerARM32::ldr(const Operand *OpRt, const Operand *OpAddress, 1269 void AssemblerARM32::ldr(const Operand *OpRt, const Operand *OpAddress,
1230 CondARM32::Cond Cond, const TargetInfo &TInfo) { 1270 CondARM32::Cond Cond, const TargetInfo &TInfo) {
1231 constexpr const char *LdrName = "ldr"; 1271 constexpr const char *LdrName = "ldr";
1232 constexpr bool IsLoad = true; 1272 constexpr bool IsLoad = true;
1233 IValueT Rt = encodeRegister(OpRt, "Rt", LdrName); 1273 IValueT Rt = encodeGPRegister(OpRt, "Rt", LdrName);
1234 const Type Ty = OpRt->getType(); 1274 const Type Ty = OpRt->getType();
1235 switch (Ty) { 1275 switch (Ty) {
1236 case IceType_i64: 1276 case IceType_i64:
1237 // LDRD is not implemented because target lowering handles i64 and double by 1277 // LDRD is not implemented because target lowering handles i64 and double by
1238 // using two (32-bit) load instructions. Note: Intentionally drop to default 1278 // using two (32-bit) load instructions. Note: Intentionally drop to default
1239 // case. 1279 // case.
1240 llvm::report_fatal_error(std::string("ldr : Type ") + typeString(Ty) + 1280 llvm::report_fatal_error(std::string("ldr : Type ") + typeString(Ty) +
1241 " not implemented"); 1281 " not implemented");
1242 default: 1282 default:
1243 llvm::report_fatal_error(std::string("ldr : Type ") + typeString(Ty) + 1283 llvm::report_fatal_error(std::string("ldr : Type ") + typeString(Ty) +
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
1296 return; 1336 return;
1297 } 1337 }
1298 } 1338 }
1299 } 1339 }
1300 1340
1301 void AssemblerARM32::emitMemExOp(CondARM32::Cond Cond, Type Ty, bool IsLoad, 1341 void AssemblerARM32::emitMemExOp(CondARM32::Cond Cond, Type Ty, bool IsLoad,
1302 const Operand *OpRd, IValueT Rt, 1342 const Operand *OpRd, IValueT Rt,
1303 const Operand *OpAddress, 1343 const Operand *OpAddress,
1304 const TargetInfo &TInfo, 1344 const TargetInfo &TInfo,
1305 const char *InstName) { 1345 const char *InstName) {
1306 IValueT Rd = encodeRegister(OpRd, "Rd", InstName); 1346 IValueT Rd = encodeGPRegister(OpRd, "Rd", InstName);
1307 IValueT MemExOpcode = IsLoad ? B0 : 0; 1347 IValueT MemExOpcode = IsLoad ? B0 : 0;
1308 switch (Ty) { 1348 switch (Ty) {
1309 default: 1349 default:
1310 llvm::report_fatal_error(std::string(InstName) + ": Type " + 1350 llvm::report_fatal_error(std::string(InstName) + ": Type " +
1311 typeString(Ty) + " not allowed"); 1351 typeString(Ty) + " not allowed");
1312 case IceType_i1: 1352 case IceType_i1:
1313 case IceType_i8: 1353 case IceType_i8:
1314 MemExOpcode |= B2; 1354 MemExOpcode |= B2;
1315 break; 1355 break;
1316 case IceType_i16: 1356 case IceType_i16:
1317 MemExOpcode |= B2 | B1; 1357 MemExOpcode |= B2 | B1;
1318 break; 1358 break;
1319 case IceType_i32: 1359 case IceType_i32:
1320 break; 1360 break;
1321 case IceType_i64: 1361 case IceType_i64:
1322 MemExOpcode |= B1; 1362 MemExOpcode |= B1;
1323 } 1363 }
1324 IValueT AddressRn; 1364 IValueT AddressRn;
1325 if (encodeAddress(OpAddress, AddressRn, TInfo, OpEncodingMemEx) != 1365 if (encodeAddress(OpAddress, AddressRn, TInfo, OpEncodingMemEx) !=
1326 EncodedAsImmRegOffset) 1366 EncodedAsImmRegOffset)
1327 llvm::report_fatal_error(std::string(InstName) + 1367 llvm::report_fatal_error(std::string(InstName) +
1328 ": Can't extract Rn from address"); 1368 ": Can't extract Rn from address");
1329 assert(Utils::IsAbsoluteUint(3, MemExOpcode)); 1369 assert(Utils::IsAbsoluteUint(3, MemExOpcode));
1330 verifyRegDefined(Rd, "Rd", InstName); 1370 assert(Rd < RegARM32::getNumGPRegs());
1331 verifyRegDefined(Rt, "Rt", InstName); 1371 assert(Rt < RegARM32::getNumGPRegs());
1332 verifyCondDefined(Cond, InstName); 1372 assert(CondARM32::isDefined(Cond));
1333 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 1373 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1334 IValueT Encoding = (Cond << kConditionShift) | B24 | B23 | B11 | B10 | B9 | 1374 IValueT Encoding = (Cond << kConditionShift) | B24 | B23 | B11 | B10 | B9 |
1335 B8 | B7 | B4 | (MemExOpcode << kMemExOpcodeShift) | 1375 B8 | B7 | B4 | (MemExOpcode << kMemExOpcodeShift) |
1336 AddressRn | (Rd << kRdShift) | (Rt << kRmShift); 1376 AddressRn | (Rd << kRdShift) | (Rt << kRmShift);
1337 emitInst(Encoding); 1377 emitInst(Encoding);
1338 return; 1378 return;
1339 } 1379 }
1340 1380
1341 void AssemblerARM32::ldrex(const Operand *OpRt, const Operand *OpAddress, 1381 void AssemblerARM32::ldrex(const Operand *OpRt, const Operand *OpAddress,
1342 CondARM32::Cond Cond, const TargetInfo &TInfo) { 1382 CondARM32::Cond Cond, const TargetInfo &TInfo) {
(...skipping 22 matching lines...) Expand all
1365 constexpr IValueT Rm = RegARM32::Encoded_Reg_pc; 1405 constexpr IValueT Rm = RegARM32::Encoded_Reg_pc;
1366 emitMemExOp(Cond, Ty, IsLoad, OpRt, Rm, OpAddress, TInfo, LdrexName); 1406 emitMemExOp(Cond, Ty, IsLoad, OpRt, Rm, OpAddress, TInfo, LdrexName);
1367 } 1407 }
1368 1408
1369 void AssemblerARM32::emitShift(const CondARM32::Cond Cond, 1409 void AssemblerARM32::emitShift(const CondARM32::Cond Cond,
1370 const OperandARM32::ShiftKind Shift, 1410 const OperandARM32::ShiftKind Shift,
1371 const Operand *OpRd, const Operand *OpRm, 1411 const Operand *OpRd, const Operand *OpRm,
1372 const Operand *OpSrc1, const bool SetFlags, 1412 const Operand *OpSrc1, const bool SetFlags,
1373 const char *InstName) { 1413 const char *InstName) {
1374 constexpr IValueT ShiftOpcode = B3 | B2 | B0; // 1101 1414 constexpr IValueT ShiftOpcode = B3 | B2 | B0; // 1101
1375 IValueT Rd = encodeRegister(OpRd, "Rd", InstName); 1415 IValueT Rd = encodeGPRegister(OpRd, "Rd", InstName);
1376 IValueT Rm = encodeRegister(OpRm, "Rm", InstName); 1416 IValueT Rm = encodeGPRegister(OpRm, "Rm", InstName);
1377 IValueT Value; 1417 IValueT Value;
1378 switch (encodeOperand(OpSrc1, Value)) { 1418 switch (encodeOperand(OpSrc1, Value, WantGPRegs)) {
1379 default: 1419 default:
1380 llvm::report_fatal_error(std::string(InstName) + 1420 llvm::report_fatal_error(std::string(InstName) +
1381 ": Last operand not understood"); 1421 ": Last operand not understood");
1382 case EncodedAsShiftImm5: { 1422 case EncodedAsShiftImm5: {
1383 // XXX (immediate) 1423 // XXX (immediate)
1384 // xxx{s}<c> <Rd>, <Rm>, #imm5 1424 // xxx{s}<c> <Rd>, <Rm>, #imm5
1385 // 1425 //
1386 // cccc0001101s0000ddddiiiii000mmmm where cccc=Cond, s=SetFlags, dddd=Rd, 1426 // cccc0001101s0000ddddiiiii000mmmm where cccc=Cond, s=SetFlags, dddd=Rd,
1387 // iiiii=imm5, and mmmm=Rm. 1427 // iiiii=imm5, and mmmm=Rm.
1388 constexpr IValueT Rn = 0; // Rn field is not used. 1428 constexpr IValueT Rn = 0; // Rn field is not used.
1389 Value = Value | (Rm << kRmShift) | (Shift << kShiftShift); 1429 Value = Value | (Rm << kRmShift) | (Shift << kShiftShift);
1390 emitType01(Cond, kInstTypeDataRegShift, ShiftOpcode, SetFlags, Rn, Rd, 1430 emitType01(Cond, kInstTypeDataRegShift, ShiftOpcode, SetFlags, Rn, Rd,
1391 Value, RdIsPcAndSetFlags, InstName); 1431 Value, RdIsPcAndSetFlags, InstName);
1392 return; 1432 return;
1393 } 1433 }
1394 case EncodedAsRegister: { 1434 case EncodedAsRegister: {
1395 // XXX (register) 1435 // XXX (register)
1396 // xxx{S}<c> <Rd>, <Rm>, <Rs> 1436 // xxx{S}<c> <Rd>, <Rm>, <Rs>
1397 // 1437 //
1398 // cccc0001101s0000ddddssss0001mmmm where cccc=Cond, s=SetFlags, dddd=Rd, 1438 // cccc0001101s0000ddddssss0001mmmm where cccc=Cond, s=SetFlags, dddd=Rd,
1399 // mmmm=Rm, and ssss=Rs. 1439 // mmmm=Rm, and ssss=Rs.
1400 constexpr IValueT Rn = 0; // Rn field is not used. 1440 constexpr IValueT Rn = 0; // Rn field is not used.
1401 IValueT Rs = encodeRegister(OpSrc1, "Rs", InstName); 1441 IValueT Rs = encodeGPRegister(OpSrc1, "Rs", InstName);
1402 verifyRegNotPc(Rd, "Rd", InstName); 1442 verifyRegNotPc(Rd, "Rd", InstName);
1403 verifyRegNotPc(Rm, "Rm", InstName); 1443 verifyRegNotPc(Rm, "Rm", InstName);
1404 verifyRegNotPc(Rs, "Rs", InstName); 1444 verifyRegNotPc(Rs, "Rs", InstName);
1405 emitType01(Cond, kInstTypeDataRegShift, ShiftOpcode, SetFlags, Rn, Rd, 1445 emitType01(Cond, kInstTypeDataRegShift, ShiftOpcode, SetFlags, Rn, Rd,
1406 encodeShiftRotateReg(Rm, Shift, Rs), NoChecks, InstName); 1446 encodeShiftRotateReg(Rm, Shift, Rs), NoChecks, InstName);
1407 return; 1447 return;
1408 } 1448 }
1409 } 1449 }
1410 } 1450 }
1411 1451
(...skipping 26 matching lines...) Expand all
1438 // cccc0001101s0000dddd00000000mmmm where cccc=Cond, s=SetFlags, dddd=Rd, 1478 // cccc0001101s0000dddd00000000mmmm where cccc=Cond, s=SetFlags, dddd=Rd,
1439 // and nnnn=Rn. 1479 // and nnnn=Rn.
1440 // 1480 //
1441 // MOV (immediate) - ARM section A8.8.102, encoding A1: 1481 // MOV (immediate) - ARM section A8.8.102, encoding A1:
1442 // mov{S}<c> <Rd>, #<RotatedImm8> 1482 // mov{S}<c> <Rd>, #<RotatedImm8>
1443 // 1483 //
1444 // cccc0011101s0000ddddiiiiiiiiiiii where cccc=Cond, s=SetFlags, dddd=Rd, 1484 // cccc0011101s0000ddddiiiiiiiiiiii where cccc=Cond, s=SetFlags, dddd=Rd,
1445 // and iiiiiiiiiiii=RotatedImm8=Src. Note: We don't use movs in this 1485 // and iiiiiiiiiiii=RotatedImm8=Src. Note: We don't use movs in this
1446 // assembler. 1486 // assembler.
1447 constexpr const char *MovName = "mov"; 1487 constexpr const char *MovName = "mov";
1448 IValueT Rd = encodeRegister(OpRd, "Rd", MovName); 1488 IValueT Rd = encodeGPRegister(OpRd, "Rd", MovName);
1449 constexpr bool SetFlags = false; 1489 constexpr bool SetFlags = false;
1450 constexpr IValueT Rn = 0; 1490 constexpr IValueT Rn = 0;
1451 constexpr IValueT MovOpcode = B3 | B2 | B0; // 1101. 1491 constexpr IValueT MovOpcode = B3 | B2 | B0; // 1101.
1452 emitType01(Cond, MovOpcode, Rd, Rn, OpSrc, SetFlags, RdIsPcAndSetFlags, 1492 emitType01(Cond, MovOpcode, Rd, Rn, OpSrc, SetFlags, RdIsPcAndSetFlags,
1453 MovName); 1493 MovName);
1454 } 1494 }
1455 1495
1456 void AssemblerARM32::emitMovwt(CondARM32::Cond Cond, bool IsMovW, 1496 void AssemblerARM32::emitMovwt(CondARM32::Cond Cond, bool IsMovW,
1457 const Operand *OpRd, const Operand *OpSrc, 1497 const Operand *OpRd, const Operand *OpSrc,
1458 const char *MovName) { 1498 const char *MovName) {
1459 IValueT Opcode = B25 | B24 | (IsMovW ? 0 : B22); 1499 IValueT Opcode = B25 | B24 | (IsMovW ? 0 : B22);
1460 IValueT Rd = encodeRegister(OpRd, "Rd", MovName); 1500 IValueT Rd = encodeGPRegister(OpRd, "Rd", MovName);
1461 IValueT Imm16; 1501 IValueT Imm16;
1462 if (const auto *Src = llvm::dyn_cast<ConstantRelocatable>(OpSrc)) { 1502 if (const auto *Src = llvm::dyn_cast<ConstantRelocatable>(OpSrc)) {
1463 emitFixup(createMoveFixup(IsMovW, Src)); 1503 emitFixup(createMoveFixup(IsMovW, Src));
1464 // Use 0 for the lower 16 bits of the relocatable, and add a fixup to 1504 // Use 0 for the lower 16 bits of the relocatable, and add a fixup to
1465 // install the correct bits. 1505 // install the correct bits.
1466 Imm16 = 0; 1506 Imm16 = 0;
1467 } else if (encodeOperand(OpSrc, Imm16) != EncodedAsConstI32) { 1507 } else if (encodeOperand(OpSrc, Imm16, WantGPRegs) != EncodedAsConstI32) {
1468 llvm::report_fatal_error(std::string(MovName) + ": Not i32 constant"); 1508 llvm::report_fatal_error(std::string(MovName) + ": Not i32 constant");
1469 } 1509 }
1470 verifyCondDefined(Cond, MovName); 1510 assert(CondARM32::isDefined(Cond));
1471 if (!Utils::IsAbsoluteUint(16, Imm16)) 1511 if (!Utils::IsAbsoluteUint(16, Imm16))
1472 llvm::report_fatal_error(std::string(MovName) + ": Constant not i16"); 1512 llvm::report_fatal_error(std::string(MovName) + ": Constant not i16");
1473 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 1513 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1474 const IValueT Encoding = encodeCondition(Cond) << kConditionShift | Opcode | 1514 const IValueT Encoding = encodeCondition(Cond) << kConditionShift | Opcode |
1475 ((Imm16 >> 12) << 16) | Rd << kRdShift | 1515 ((Imm16 >> 12) << 16) | Rd << kRdShift |
1476 (Imm16 & 0xfff); 1516 (Imm16 & 0xfff);
1477 emitInst(Encoding); 1517 emitInst(Encoding);
1478 } 1518 }
1479 1519
1480 void AssemblerARM32::movw(const Operand *OpRd, const Operand *OpSrc, 1520 void AssemblerARM32::movw(const Operand *OpRd, const Operand *OpSrc,
(...skipping 27 matching lines...) Expand all
1508 // 1548 //
1509 // cccc0011111s0000ddddiiiiiiiiiiii where cccc=Cond, s=SetFlags=0, dddd=Rd, 1549 // cccc0011111s0000ddddiiiiiiiiiiii where cccc=Cond, s=SetFlags=0, dddd=Rd,
1510 // and iiiiiiiiiiii=const 1550 // and iiiiiiiiiiii=const
1511 // 1551 //
1512 // MVN (register) - ARM section A8.8.116, encoding A1: 1552 // MVN (register) - ARM section A8.8.116, encoding A1:
1513 // mvn{s}<c> <Rd>, <Rm>{, <shift> 1553 // mvn{s}<c> <Rd>, <Rm>{, <shift>
1514 // 1554 //
1515 // cccc0001111s0000ddddiiiiitt0mmmm where cccc=Cond, s=SetFlags=0, dddd=Rd, 1555 // cccc0001111s0000ddddiiiiitt0mmmm where cccc=Cond, s=SetFlags=0, dddd=Rd,
1516 // mmmm=Rm, iiii defines shift constant, and tt=ShiftKind. 1556 // mmmm=Rm, iiii defines shift constant, and tt=ShiftKind.
1517 constexpr const char *MvnName = "mvn"; 1557 constexpr const char *MvnName = "mvn";
1518 IValueT Rd = encodeRegister(OpRd, "Rd", MvnName); 1558 IValueT Rd = encodeGPRegister(OpRd, "Rd", MvnName);
1519 constexpr IValueT MvnOpcode = B3 | B2 | B1 | B0; // i.e. 1111 1559 constexpr IValueT MvnOpcode = B3 | B2 | B1 | B0; // i.e. 1111
1520 constexpr IValueT Rn = 0; 1560 constexpr IValueT Rn = 0;
1521 constexpr bool SetFlags = false; 1561 constexpr bool SetFlags = false;
1522 emitType01(Cond, MvnOpcode, Rd, Rn, OpSrc, SetFlags, RdIsPcAndSetFlags, 1562 emitType01(Cond, MvnOpcode, Rd, Rn, OpSrc, SetFlags, RdIsPcAndSetFlags,
1523 MvnName); 1563 MvnName);
1524 } 1564 }
1525 1565
1526 void AssemblerARM32::nop() { 1566 void AssemblerARM32::nop() {
1527 // NOP - Section A8.8.119, encoding A1: 1567 // NOP - Section A8.8.119, encoding A1:
1528 // nop<c> 1568 // nop<c>
(...skipping 27 matching lines...) Expand all
1556 } 1596 }
1557 1597
1558 void AssemblerARM32::sdiv(const Operand *OpRd, const Operand *OpRn, 1598 void AssemblerARM32::sdiv(const Operand *OpRd, const Operand *OpRn,
1559 const Operand *OpSrc1, CondARM32::Cond Cond) { 1599 const Operand *OpSrc1, CondARM32::Cond Cond) {
1560 // SDIV - ARM section A8.8.165, encoding A1. 1600 // SDIV - ARM section A8.8.165, encoding A1.
1561 // sdiv<c> <Rd>, <Rn>, <Rm> 1601 // sdiv<c> <Rd>, <Rn>, <Rm>
1562 // 1602 //
1563 // cccc01110001dddd1111mmmm0001nnnn where cccc=Cond, dddd=Rd, nnnn=Rn, and 1603 // cccc01110001dddd1111mmmm0001nnnn where cccc=Cond, dddd=Rd, nnnn=Rn, and
1564 // mmmm=Rm. 1604 // mmmm=Rm.
1565 constexpr const char *SdivName = "sdiv"; 1605 constexpr const char *SdivName = "sdiv";
1566 IValueT Rd = encodeRegister(OpRd, "Rd", SdivName); 1606 IValueT Rd = encodeGPRegister(OpRd, "Rd", SdivName);
1567 IValueT Rn = encodeRegister(OpRn, "Rn", SdivName); 1607 IValueT Rn = encodeGPRegister(OpRn, "Rn", SdivName);
1568 IValueT Rm = encodeRegister(OpSrc1, "Rm", SdivName); 1608 IValueT Rm = encodeGPRegister(OpSrc1, "Rm", SdivName);
1569 verifyRegNotPc(Rd, "Rd", SdivName); 1609 verifyRegNotPc(Rd, "Rd", SdivName);
1570 verifyRegNotPc(Rn, "Rn", SdivName); 1610 verifyRegNotPc(Rn, "Rn", SdivName);
1571 verifyRegNotPc(Rm, "Rm", SdivName); 1611 verifyRegNotPc(Rm, "Rm", SdivName);
1572 // Assembler registers rd, rn, rm are encoded as rn, rm, rs. 1612 // Assembler registers rd, rn, rm are encoded as rn, rm, rs.
1573 constexpr IValueT SdivOpcode = 0; 1613 constexpr IValueT SdivOpcode = 0;
1574 emitDivOp(Cond, SdivOpcode, Rd, Rn, Rm, SdivName); 1614 emitDivOp(Cond, SdivOpcode, Rd, Rn, Rm);
1575 } 1615 }
1576 1616
1577 void AssemblerARM32::str(const Operand *OpRt, const Operand *OpAddress, 1617 void AssemblerARM32::str(const Operand *OpRt, const Operand *OpAddress,
1578 CondARM32::Cond Cond, const TargetInfo &TInfo) { 1618 CondARM32::Cond Cond, const TargetInfo &TInfo) {
1579 constexpr const char *StrName = "str"; 1619 constexpr const char *StrName = "str";
1580 constexpr bool IsLoad = false; 1620 constexpr bool IsLoad = false;
1581 IValueT Rt = encodeRegister(OpRt, "Rt", StrName); 1621 IValueT Rt = encodeGPRegister(OpRt, "Rt", StrName);
1582 const Type Ty = OpRt->getType(); 1622 const Type Ty = OpRt->getType();
1583 switch (Ty) { 1623 switch (Ty) {
1584 case IceType_i64: 1624 case IceType_i64:
1585 // STRD is not implemented because target lowering handles i64 and double by 1625 // STRD is not implemented because target lowering handles i64 and double by
1586 // using two (32-bit) store instructions. Note: Intentionally drop to 1626 // using two (32-bit) store instructions. Note: Intentionally drop to
1587 // default case. 1627 // default case.
1588 llvm::report_fatal_error(std::string(StrName) + ": Type " + typeString(Ty) + 1628 llvm::report_fatal_error(std::string(StrName) + ": Type " + typeString(Ty) +
1589 " not implemented"); 1629 " not implemented");
1590 default: 1630 default:
1591 llvm::report_fatal_error(std::string(StrName) + ": Type " + typeString(Ty) + 1631 llvm::report_fatal_error(std::string(StrName) + ": Type " + typeString(Ty) +
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
1655 // cccc00011000nnnndddd11111001tttt where cccc=Cond, dddd=Rd, tttt=Rt, and 1695 // cccc00011000nnnndddd11111001tttt where cccc=Cond, dddd=Rd, tttt=Rt, and
1656 // nnnn=Rn. 1696 // nnnn=Rn.
1657 // 1697 //
1658 // STREXD - ARM section A8.8.214, encoding A1: 1698 // STREXD - ARM section A8.8.214, encoding A1:
1659 // strexd<c> <Rd>, <Rt>, [<Rn>] 1699 // strexd<c> <Rd>, <Rt>, [<Rn>]
1660 // 1700 //
1661 // cccc00011010nnnndddd11111001tttt where cccc=Cond, dddd=Rd, tttt=Rt, and 1701 // cccc00011010nnnndddd11111001tttt where cccc=Cond, dddd=Rd, tttt=Rt, and
1662 // nnnn=Rn. 1702 // nnnn=Rn.
1663 constexpr const char *StrexName = "strex"; 1703 constexpr const char *StrexName = "strex";
1664 // Note: Rt uses Rm shift in encoding. 1704 // Note: Rt uses Rm shift in encoding.
1665 IValueT Rt = encodeRegister(OpRt, "Rt", StrexName); 1705 IValueT Rt = encodeGPRegister(OpRt, "Rt", StrexName);
1666 const Type Ty = OpRt->getType(); 1706 const Type Ty = OpRt->getType();
1667 constexpr bool IsLoad = true; 1707 constexpr bool IsLoad = true;
1668 emitMemExOp(Cond, Ty, !IsLoad, OpRd, Rt, OpAddress, TInfo, StrexName); 1708 emitMemExOp(Cond, Ty, !IsLoad, OpRd, Rt, OpAddress, TInfo, StrexName);
1669 } 1709 }
1670 1710
1671 void AssemblerARM32::orr(const Operand *OpRd, const Operand *OpRn, 1711 void AssemblerARM32::orr(const Operand *OpRd, const Operand *OpRn,
1672 const Operand *OpSrc1, bool SetFlags, 1712 const Operand *OpSrc1, bool SetFlags,
1673 CondARM32::Cond Cond) { 1713 CondARM32::Cond Cond) {
1674 // ORR (register) - ARM Section A8.8.123, encoding A1: 1714 // ORR (register) - ARM Section A8.8.123, encoding A1:
1675 // orr{s}<c> <Rd>, <Rn>, <Rm> 1715 // orr{s}<c> <Rd>, <Rn>, <Rm>
(...skipping 11 matching lines...) Expand all
1687 emitType01(Cond, OrrOpcode, OpRd, OpRn, OpSrc1, SetFlags, RdIsPcAndSetFlags, 1727 emitType01(Cond, OrrOpcode, OpRd, OpRn, OpSrc1, SetFlags, RdIsPcAndSetFlags,
1688 OrrName); 1728 OrrName);
1689 } 1729 }
1690 1730
1691 void AssemblerARM32::pop(const Operand *OpRt, CondARM32::Cond Cond) { 1731 void AssemblerARM32::pop(const Operand *OpRt, CondARM32::Cond Cond) {
1692 // POP - ARM section A8.8.132, encoding A2: 1732 // POP - ARM section A8.8.132, encoding A2:
1693 // pop<c> {Rt} 1733 // pop<c> {Rt}
1694 // 1734 //
1695 // cccc010010011101dddd000000000100 where dddd=Rt and cccc=Cond. 1735 // cccc010010011101dddd000000000100 where dddd=Rt and cccc=Cond.
1696 constexpr const char *Pop = "pop"; 1736 constexpr const char *Pop = "pop";
1697 IValueT Rt = encodeRegister(OpRt, "Rt", Pop); 1737 IValueT Rt = encodeGPRegister(OpRt, "Rt", Pop);
1698 verifyRegsNotEq(Rt, "Rt", RegARM32::Encoded_Reg_sp, "sp", Pop); 1738 verifyRegsNotEq(Rt, "Rt", RegARM32::Encoded_Reg_sp, "sp", Pop);
1699 // Same as load instruction. 1739 // Same as load instruction.
1700 constexpr bool IsLoad = true; 1740 constexpr bool IsLoad = true;
1701 constexpr bool IsByte = false; 1741 constexpr bool IsByte = false;
1702 IValueT Address = encodeImmRegOffset(RegARM32::Encoded_Reg_sp, kWordSize, 1742 IValueT Address = encodeImmRegOffset(RegARM32::Encoded_Reg_sp, kWordSize,
1703 OperandARM32Mem::PostIndex); 1743 OperandARM32Mem::PostIndex);
1704 emitMemOp(Cond, kInstTypeMemImmediate, IsLoad, IsByte, Rt, Address, Pop); 1744 emitMemOp(Cond, kInstTypeMemImmediate, IsLoad, IsByte, Rt, Address);
1705 } 1745 }
1706 1746
1707 void AssemblerARM32::popList(const IValueT Registers, CondARM32::Cond Cond) { 1747 void AssemblerARM32::popList(const IValueT Registers, CondARM32::Cond Cond) {
1708 // POP - ARM section A8.*.131, encoding A1: 1748 // POP - ARM section A8.*.131, encoding A1:
1709 // pop<c> <registers> 1749 // pop<c> <registers>
1710 // 1750 //
1711 // cccc100010111101rrrrrrrrrrrrrrrr where cccc=Cond and 1751 // cccc100010111101rrrrrrrrrrrrrrrr where cccc=Cond and
1712 // rrrrrrrrrrrrrrrr=Registers (one bit for each GP register). 1752 // rrrrrrrrrrrrrrrr=Registers (one bit for each GP register).
1713 constexpr const char *PopListName = "pop {}";
1714 constexpr bool IsLoad = true; 1753 constexpr bool IsLoad = true;
1715 emitMultiMemOp(Cond, IA_W, IsLoad, RegARM32::Encoded_Reg_sp, Registers, 1754 emitMultiMemOp(Cond, IA_W, IsLoad, RegARM32::Encoded_Reg_sp, Registers);
1716 PopListName);
1717 } 1755 }
1718 1756
1719 void AssemblerARM32::push(const Operand *OpRt, CondARM32::Cond Cond) { 1757 void AssemblerARM32::push(const Operand *OpRt, CondARM32::Cond Cond) {
1720 // PUSH - ARM section A8.8.133, encoding A2: 1758 // PUSH - ARM section A8.8.133, encoding A2:
1721 // push<c> {Rt} 1759 // push<c> {Rt}
1722 // 1760 //
1723 // cccc010100101101dddd000000000100 where dddd=Rt and cccc=Cond. 1761 // cccc010100101101dddd000000000100 where dddd=Rt and cccc=Cond.
1724 constexpr const char *Push = "push"; 1762 constexpr const char *Push = "push";
1725 IValueT Rt = encodeRegister(OpRt, "Rt", Push); 1763 IValueT Rt = encodeGPRegister(OpRt, "Rt", Push);
1726 verifyRegsNotEq(Rt, "Rt", RegARM32::Encoded_Reg_sp, "sp", Push); 1764 verifyRegsNotEq(Rt, "Rt", RegARM32::Encoded_Reg_sp, "sp", Push);
1727 // Same as store instruction. 1765 // Same as store instruction.
1728 constexpr bool isLoad = false; 1766 constexpr bool isLoad = false;
1729 constexpr bool isByte = false; 1767 constexpr bool isByte = false;
1730 IValueT Address = encodeImmRegOffset(RegARM32::Encoded_Reg_sp, -kWordSize, 1768 IValueT Address = encodeImmRegOffset(RegARM32::Encoded_Reg_sp, -kWordSize,
1731 OperandARM32Mem::PreIndex); 1769 OperandARM32Mem::PreIndex);
1732 emitMemOp(Cond, kInstTypeMemImmediate, isLoad, isByte, Rt, Address, Push); 1770 emitMemOp(Cond, kInstTypeMemImmediate, isLoad, isByte, Rt, Address);
1733 } 1771 }
1734 1772
1735 void AssemblerARM32::pushList(const IValueT Registers, CondARM32::Cond Cond) { 1773 void AssemblerARM32::pushList(const IValueT Registers, CondARM32::Cond Cond) {
1736 // PUSH - ARM section A8.8.133, encoding A1: 1774 // PUSH - ARM section A8.8.133, encoding A1:
1737 // push<c> <Registers> 1775 // push<c> <Registers>
1738 // 1776 //
1739 // cccc100100101101rrrrrrrrrrrrrrrr where cccc=Cond and 1777 // cccc100100101101rrrrrrrrrrrrrrrr where cccc=Cond and
1740 // rrrrrrrrrrrrrrrr=Registers (one bit for each GP register). 1778 // rrrrrrrrrrrrrrrr=Registers (one bit for each GP register).
1741 constexpr const char *PushListName = "push {}";
1742 constexpr bool IsLoad = false; 1779 constexpr bool IsLoad = false;
1743 emitMultiMemOp(Cond, DB_W, IsLoad, RegARM32::Encoded_Reg_sp, Registers, 1780 emitMultiMemOp(Cond, DB_W, IsLoad, RegARM32::Encoded_Reg_sp, Registers);
1744 PushListName);
1745 } 1781 }
1746 1782
1747 void AssemblerARM32::mla(const Operand *OpRd, const Operand *OpRn, 1783 void AssemblerARM32::mla(const Operand *OpRd, const Operand *OpRn,
1748 const Operand *OpRm, const Operand *OpRa, 1784 const Operand *OpRm, const Operand *OpRa,
1749 CondARM32::Cond Cond) { 1785 CondARM32::Cond Cond) {
1750 // MLA - ARM section A8.8.114, encoding A1. 1786 // MLA - ARM section A8.8.114, encoding A1.
1751 // mla{s}<c> <Rd>, <Rn>, <Rm>, <Ra> 1787 // mla{s}<c> <Rd>, <Rn>, <Rm>, <Ra>
1752 // 1788 //
1753 // cccc0000001sddddaaaammmm1001nnnn where cccc=Cond, s=SetFlags, dddd=Rd, 1789 // cccc0000001sddddaaaammmm1001nnnn where cccc=Cond, s=SetFlags, dddd=Rd,
1754 // aaaa=Ra, mmmm=Rm, and nnnn=Rn. 1790 // aaaa=Ra, mmmm=Rm, and nnnn=Rn.
1755 constexpr const char *MlaName = "mla"; 1791 constexpr const char *MlaName = "mla";
1756 IValueT Rd = encodeRegister(OpRd, "Rd", MlaName); 1792 IValueT Rd = encodeGPRegister(OpRd, "Rd", MlaName);
1757 IValueT Rn = encodeRegister(OpRn, "Rn", MlaName); 1793 IValueT Rn = encodeGPRegister(OpRn, "Rn", MlaName);
1758 IValueT Rm = encodeRegister(OpRm, "Rm", MlaName); 1794 IValueT Rm = encodeGPRegister(OpRm, "Rm", MlaName);
1759 IValueT Ra = encodeRegister(OpRa, "Ra", MlaName); 1795 IValueT Ra = encodeGPRegister(OpRa, "Ra", MlaName);
1760 verifyRegNotPc(Rd, "Rd", MlaName); 1796 verifyRegNotPc(Rd, "Rd", MlaName);
1761 verifyRegNotPc(Rn, "Rn", MlaName); 1797 verifyRegNotPc(Rn, "Rn", MlaName);
1762 verifyRegNotPc(Rm, "Rm", MlaName); 1798 verifyRegNotPc(Rm, "Rm", MlaName);
1763 verifyRegNotPc(Ra, "Ra", MlaName); 1799 verifyRegNotPc(Ra, "Ra", MlaName);
1764 constexpr IValueT MlaOpcode = B21; 1800 constexpr IValueT MlaOpcode = B21;
1765 constexpr bool SetFlags = true; 1801 constexpr bool SetFlags = true;
1766 // Assembler registers rd, rn, rm, ra are encoded as rn, rm, rs, rd. 1802 // Assembler registers rd, rn, rm, ra are encoded as rn, rm, rs, rd.
1767 emitMulOp(Cond, MlaOpcode, Ra, Rd, Rn, Rm, !SetFlags, MlaName); 1803 emitMulOp(Cond, MlaOpcode, Ra, Rd, Rn, Rm, !SetFlags);
1768 } 1804 }
1769 1805
1770 void AssemblerARM32::mls(const Operand *OpRd, const Operand *OpRn, 1806 void AssemblerARM32::mls(const Operand *OpRd, const Operand *OpRn,
1771 const Operand *OpRm, const Operand *OpRa, 1807 const Operand *OpRm, const Operand *OpRa,
1772 CondARM32::Cond Cond) { 1808 CondARM32::Cond Cond) {
1773 constexpr const char *MlsName = "mls"; 1809 constexpr const char *MlsName = "mls";
1774 IValueT Rd = encodeRegister(OpRd, "Rd", MlsName); 1810 IValueT Rd = encodeGPRegister(OpRd, "Rd", MlsName);
1775 IValueT Rn = encodeRegister(OpRn, "Rn", MlsName); 1811 IValueT Rn = encodeGPRegister(OpRn, "Rn", MlsName);
1776 IValueT Rm = encodeRegister(OpRm, "Rm", MlsName); 1812 IValueT Rm = encodeGPRegister(OpRm, "Rm", MlsName);
1777 IValueT Ra = encodeRegister(OpRa, "Ra", MlsName); 1813 IValueT Ra = encodeGPRegister(OpRa, "Ra", MlsName);
1778 verifyRegNotPc(Rd, "Rd", MlsName); 1814 verifyRegNotPc(Rd, "Rd", MlsName);
1779 verifyRegNotPc(Rn, "Rn", MlsName); 1815 verifyRegNotPc(Rn, "Rn", MlsName);
1780 verifyRegNotPc(Rm, "Rm", MlsName); 1816 verifyRegNotPc(Rm, "Rm", MlsName);
1781 verifyRegNotPc(Ra, "Ra", MlsName); 1817 verifyRegNotPc(Ra, "Ra", MlsName);
1782 constexpr IValueT MlsOpcode = B22 | B21; 1818 constexpr IValueT MlsOpcode = B22 | B21;
1783 constexpr bool SetFlags = true; 1819 constexpr bool SetFlags = true;
1784 // Assembler registers rd, rn, rm, ra are encoded as rn, rm, rs, rd. 1820 // Assembler registers rd, rn, rm, ra are encoded as rn, rm, rs, rd.
1785 emitMulOp(Cond, MlsOpcode, Ra, Rd, Rn, Rm, !SetFlags, MlsName); 1821 emitMulOp(Cond, MlsOpcode, Ra, Rd, Rn, Rm, !SetFlags);
1786 } 1822 }
1787 1823
1788 void AssemblerARM32::mul(const Operand *OpRd, const Operand *OpRn, 1824 void AssemblerARM32::mul(const Operand *OpRd, const Operand *OpRn,
1789 const Operand *OpSrc1, bool SetFlags, 1825 const Operand *OpSrc1, bool SetFlags,
1790 CondARM32::Cond Cond) { 1826 CondARM32::Cond Cond) {
1791 // MUL - ARM section A8.8.114, encoding A1. 1827 // MUL - ARM section A8.8.114, encoding A1.
1792 // mul{s}<c> <Rd>, <Rn>, <Rm> 1828 // mul{s}<c> <Rd>, <Rn>, <Rm>
1793 // 1829 //
1794 // cccc0000000sdddd0000mmmm1001nnnn where cccc=Cond, dddd=Rd, nnnn=Rn, 1830 // cccc0000000sdddd0000mmmm1001nnnn where cccc=Cond, dddd=Rd, nnnn=Rn,
1795 // mmmm=Rm, and s=SetFlags. 1831 // mmmm=Rm, and s=SetFlags.
1796 constexpr const char *MulName = "mul"; 1832 constexpr const char *MulName = "mul";
1797 IValueT Rd = encodeRegister(OpRd, "Rd", MulName); 1833 IValueT Rd = encodeGPRegister(OpRd, "Rd", MulName);
1798 IValueT Rn = encodeRegister(OpRn, "Rn", MulName); 1834 IValueT Rn = encodeGPRegister(OpRn, "Rn", MulName);
1799 IValueT Rm = encodeRegister(OpSrc1, "Rm", MulName); 1835 IValueT Rm = encodeGPRegister(OpSrc1, "Rm", MulName);
1800 verifyRegNotPc(Rd, "Rd", MulName); 1836 verifyRegNotPc(Rd, "Rd", MulName);
1801 verifyRegNotPc(Rn, "Rn", MulName); 1837 verifyRegNotPc(Rn, "Rn", MulName);
1802 verifyRegNotPc(Rm, "Rm", MulName); 1838 verifyRegNotPc(Rm, "Rm", MulName);
1803 // Assembler registers rd, rn, rm are encoded as rn, rm, rs. 1839 // Assembler registers rd, rn, rm are encoded as rn, rm, rs.
1804 constexpr IValueT MulOpcode = 0; 1840 constexpr IValueT MulOpcode = 0;
1805 emitMulOp(Cond, MulOpcode, RegARM32::Encoded_Reg_r0, Rd, Rn, Rm, SetFlags, 1841 emitMulOp(Cond, MulOpcode, RegARM32::Encoded_Reg_r0, Rd, Rn, Rm, SetFlags);
1806 MulName);
1807 } 1842 }
1808 1843
1809 void AssemblerARM32::emitRdRm(CondARM32::Cond Cond, IValueT Opcode, 1844 void AssemblerARM32::emitRdRm(CondARM32::Cond Cond, IValueT Opcode,
1810 const Operand *OpRd, const Operand *OpRm, 1845 const Operand *OpRd, const Operand *OpRm,
1811 const char *InstName) { 1846 const char *InstName) {
1812 IValueT Rd = encodeRegister(OpRd, "Rd", InstName); 1847 IValueT Rd = encodeGPRegister(OpRd, "Rd", InstName);
1813 IValueT Rm = encodeRegister(OpRm, "Rm", InstName); 1848 IValueT Rm = encodeGPRegister(OpRm, "Rm", InstName);
1814 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 1849 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1815 IValueT Encoding = 1850 IValueT Encoding =
1816 (Cond << kConditionShift) | Opcode | (Rd << kRdShift) | (Rm << kRmShift); 1851 (Cond << kConditionShift) | Opcode | (Rd << kRdShift) | (Rm << kRmShift);
1817 emitInst(Encoding); 1852 emitInst(Encoding);
1818 } 1853 }
1819 1854
1820 void AssemblerARM32::rbit(const Operand *OpRd, const Operand *OpRm, 1855 void AssemblerARM32::rbit(const Operand *OpRd, const Operand *OpRm,
1821 CondARM32::Cond Cond) { 1856 CondARM32::Cond Cond) {
1822 // RBIT - ARM section A8.8.144, encoding A1: 1857 // RBIT - ARM section A8.8.144, encoding A1:
1823 // rbit<c> <Rd>, <Rm> 1858 // rbit<c> <Rd>, <Rm>
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
1958 } 1993 }
1959 1994
1960 void AssemblerARM32::udiv(const Operand *OpRd, const Operand *OpRn, 1995 void AssemblerARM32::udiv(const Operand *OpRd, const Operand *OpRn,
1961 const Operand *OpSrc1, CondARM32::Cond Cond) { 1996 const Operand *OpSrc1, CondARM32::Cond Cond) {
1962 // UDIV - ARM section A8.8.248, encoding A1. 1997 // UDIV - ARM section A8.8.248, encoding A1.
1963 // udiv<c> <Rd>, <Rn>, <Rm> 1998 // udiv<c> <Rd>, <Rn>, <Rm>
1964 // 1999 //
1965 // cccc01110011dddd1111mmmm0001nnnn where cccc=Cond, dddd=Rd, nnnn=Rn, and 2000 // cccc01110011dddd1111mmmm0001nnnn where cccc=Cond, dddd=Rd, nnnn=Rn, and
1966 // mmmm=Rm. 2001 // mmmm=Rm.
1967 constexpr const char *UdivName = "udiv"; 2002 constexpr const char *UdivName = "udiv";
1968 IValueT Rd = encodeRegister(OpRd, "Rd", UdivName); 2003 IValueT Rd = encodeGPRegister(OpRd, "Rd", UdivName);
1969 IValueT Rn = encodeRegister(OpRn, "Rn", UdivName); 2004 IValueT Rn = encodeGPRegister(OpRn, "Rn", UdivName);
1970 IValueT Rm = encodeRegister(OpSrc1, "Rm", UdivName); 2005 IValueT Rm = encodeGPRegister(OpSrc1, "Rm", UdivName);
1971 verifyRegNotPc(Rd, "Rd", UdivName); 2006 verifyRegNotPc(Rd, "Rd", UdivName);
1972 verifyRegNotPc(Rn, "Rn", UdivName); 2007 verifyRegNotPc(Rn, "Rn", UdivName);
1973 verifyRegNotPc(Rm, "Rm", UdivName); 2008 verifyRegNotPc(Rm, "Rm", UdivName);
1974 // Assembler registers rd, rn, rm are encoded as rn, rm, rs. 2009 // Assembler registers rd, rn, rm are encoded as rn, rm, rs.
1975 constexpr IValueT UdivOpcode = B21; 2010 constexpr IValueT UdivOpcode = B21;
1976 emitDivOp(Cond, UdivOpcode, Rd, Rn, Rm, UdivName); 2011 emitDivOp(Cond, UdivOpcode, Rd, Rn, Rm);
1977 } 2012 }
1978 2013
1979 void AssemblerARM32::umull(const Operand *OpRdLo, const Operand *OpRdHi, 2014 void AssemblerARM32::umull(const Operand *OpRdLo, const Operand *OpRdHi,
1980 const Operand *OpRn, const Operand *OpRm, 2015 const Operand *OpRn, const Operand *OpRm,
1981 CondARM32::Cond Cond) { 2016 CondARM32::Cond Cond) {
1982 // UMULL - ARM section A8.8.257, encoding A1: 2017 // UMULL - ARM section A8.8.257, encoding A1:
1983 // umull<c> <RdLo>, <RdHi>, <Rn>, <Rm> 2018 // umull<c> <RdLo>, <RdHi>, <Rn>, <Rm>
1984 // 2019 //
1985 // cccc0000100shhhhllllmmmm1001nnnn where hhhh=RdHi, llll=RdLo, nnnn=Rn, 2020 // cccc0000100shhhhllllmmmm1001nnnn where hhhh=RdHi, llll=RdLo, nnnn=Rn,
1986 // mmmm=Rm, and s=SetFlags 2021 // mmmm=Rm, and s=SetFlags
1987 constexpr const char *UmullName = "umull"; 2022 constexpr const char *UmullName = "umull";
1988 IValueT RdLo = encodeRegister(OpRdLo, "RdLo", UmullName); 2023 IValueT RdLo = encodeGPRegister(OpRdLo, "RdLo", UmullName);
1989 IValueT RdHi = encodeRegister(OpRdHi, "RdHi", UmullName); 2024 IValueT RdHi = encodeGPRegister(OpRdHi, "RdHi", UmullName);
1990 IValueT Rn = encodeRegister(OpRn, "Rn", UmullName); 2025 IValueT Rn = encodeGPRegister(OpRn, "Rn", UmullName);
1991 IValueT Rm = encodeRegister(OpRm, "Rm", UmullName); 2026 IValueT Rm = encodeGPRegister(OpRm, "Rm", UmullName);
1992 verifyRegNotPc(RdLo, "RdLo", UmullName); 2027 verifyRegNotPc(RdLo, "RdLo", UmullName);
1993 verifyRegNotPc(RdHi, "RdHi", UmullName); 2028 verifyRegNotPc(RdHi, "RdHi", UmullName);
1994 verifyRegNotPc(Rn, "Rn", UmullName); 2029 verifyRegNotPc(Rn, "Rn", UmullName);
1995 verifyRegNotPc(Rm, "Rm", UmullName); 2030 verifyRegNotPc(Rm, "Rm", UmullName);
1996 verifyRegsNotEq(RdHi, "RdHi", RdLo, "RdLo", UmullName); 2031 verifyRegsNotEq(RdHi, "RdHi", RdLo, "RdLo", UmullName);
1997 constexpr IValueT UmullOpcode = B23; 2032 constexpr IValueT UmullOpcode = B23;
1998 constexpr bool SetFlags = false; 2033 constexpr bool SetFlags = false;
1999 emitMulOp(Cond, UmullOpcode, RdLo, RdHi, Rn, Rm, SetFlags, UmullName); 2034 emitMulOp(Cond, UmullOpcode, RdLo, RdHi, Rn, Rm, SetFlags);
2000 } 2035 }
2001 2036
2002 void AssemblerARM32::uxt(const Operand *OpRd, const Operand *OpSrc0, 2037 void AssemblerARM32::uxt(const Operand *OpRd, const Operand *OpSrc0,
2003 CondARM32::Cond Cond) { 2038 CondARM32::Cond Cond) {
2004 constexpr const char *UxtName = "uxt"; 2039 constexpr const char *UxtName = "uxt";
2005 constexpr IValueT UxtOpcode = B26 | B25 | B23 | B22 | B21; 2040 constexpr IValueT UxtOpcode = B26 | B25 | B23 | B22 | B21;
2006 emitSignExtend(Cond, UxtOpcode, OpRd, OpSrc0, UxtName); 2041 emitSignExtend(Cond, UxtOpcode, OpRd, OpSrc0, UxtName);
2007 } 2042 }
2008 2043
2044 void AssemblerARM32::vadds(const Operand *OpSd, const Operand *OpSn,
2045 const Operand *OpSm, CondARM32::Cond Cond) {
2046 // VADD (floating-point) - ARM section A8.8.283, encoding A2:
2047 // vadd<c>.f32 <Sd>, <Sn>, <Sm>
2048 //
2049 // cccc11100D11nnnndddd101sN0M0mmmm where cccc=Cond, s=0, ddddD=Rd, nnnnN=Rn,
2050 // and mmmmM=Rm.
2051 constexpr const char *Vadds = "vadds";
2052 IValueT Sd = encodeSRegister(OpSd, "Sd", Vadds);
2053 IValueT Sn = encodeSRegister(OpSn, "Sn", Vadds);
2054 IValueT Sm = encodeSRegister(OpSm, "Sm", Vadds);
2055 constexpr IValueT VaddsOpcode = B21 | B20;
2056 emitVFPsss(Cond, VaddsOpcode, Sd, Sn, Sm);
2057 }
2058
2059 void AssemblerARM32::vaddd(const Operand *OpDd, const Operand *OpDn,
2060 const Operand *OpDm, CondARM32::Cond Cond) {
2061 // VADD (floating-point) - ARM section A8.8.283, encoding A2:
2062 // vadd<c>.f64 <Dd>, <Dn>, <Dm>
2063 //
2064 // cccc11100D11nnnndddd101sN0M0mmmm where cccc=Cond, s=1, Ddddd=Rd, Nnnnn=Rn,
2065 // and Mmmmm=Rm.
2066 constexpr const char *Vaddd = "vaddd";
2067 IValueT Dd = encodeDRegister(OpDd, "Dd", Vaddd);
2068 IValueT Dn = encodeDRegister(OpDn, "Dn", Vaddd);
2069 IValueT Dm = encodeDRegister(OpDm, "Dm", Vaddd);
2070 constexpr IValueT VadddOpcode = B21 | B20;
2071 emitVFPddd(Cond, VadddOpcode, Dd, Dn, Dm);
2072 }
2073
2009 void AssemblerARM32::emitVStackOp(CondARM32::Cond Cond, IValueT Opcode, 2074 void AssemblerARM32::emitVStackOp(CondARM32::Cond Cond, IValueT Opcode,
2010 const Variable *OpBaseReg, 2075 const Variable *OpBaseReg,
2011 SizeT NumConsecRegs, const char *InstName) { 2076 SizeT NumConsecRegs) {
2012
2013 const IValueT BaseReg = getEncodedSRegNum(OpBaseReg); 2077 const IValueT BaseReg = getEncodedSRegNum(OpBaseReg);
2014 const IValueT DLastBit = mask(BaseReg, 0, 1); // Last bit of base register. 2078 const IValueT DLastBit = mask(BaseReg, 0, 1); // Last bit of base register.
2015 const IValueT Rd = mask(BaseReg, 1, 4); // Top 4 bits of base register. 2079 const IValueT Rd = mask(BaseReg, 1, 4); // Top 4 bits of base register.
2016 assert(0 < NumConsecRegs); 2080 assert(0 < NumConsecRegs);
2017 (void)VpushVpopMaxConsecRegs; 2081 (void)VpushVpopMaxConsecRegs;
2018 assert(NumConsecRegs <= VpushVpopMaxConsecRegs); 2082 assert(NumConsecRegs <= VpushVpopMaxConsecRegs);
2019 assert((BaseReg + NumConsecRegs) <= RegARM32::getNumSRegs()); 2083 assert((BaseReg + NumConsecRegs) <= RegARM32::getNumSRegs());
2020 verifyCondDefined(Cond, InstName); 2084 assert(CondARM32::isDefined(Cond));
2021 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 2085 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2022 const IValueT Encoding = Opcode | (Cond << kConditionShift) | DLastBit | 2086 const IValueT Encoding = Opcode | (Cond << kConditionShift) | DLastBit |
2023 (Rd << kRdShift) | NumConsecRegs; 2087 (Rd << kRdShift) | NumConsecRegs;
2024 emitInst(Encoding); 2088 emitInst(Encoding);
2025 } 2089 }
2026 2090
2027 void AssemblerARM32::vpop(const Variable *OpBaseReg, SizeT NumConsecRegs, 2091 void AssemblerARM32::vpop(const Variable *OpBaseReg, SizeT NumConsecRegs,
2028 CondARM32::Cond Cond) { 2092 CondARM32::Cond Cond) {
2029 // Note: Current implementation assumes that OpBaseReg is defined using S 2093 // Note: Current implementation assumes that OpBaseReg is defined using S
2030 // registers. It doesn't implement the D register form. 2094 // registers. It doesn't implement the D register form.
2031 // 2095 //
2032 // VPOP - ARM section A8.8.367, encoding A2: 2096 // VPOP - ARM section A8.8.367, encoding A2:
2033 // vpop<c> <RegList> 2097 // vpop<c> <RegList>
2034 // 2098 //
2035 // cccc11001D111101dddd1010iiiiiiii where cccc=Cond, ddddD=BaseReg, and 2099 // cccc11001D111101dddd1010iiiiiiii where cccc=Cond, ddddD=BaseReg, and
2036 // iiiiiiii=NumConsecRegs. 2100 // iiiiiiii=NumConsecRegs.
2037 constexpr const char *VpopName = "vpop";
2038 constexpr IValueT VpopOpcode = 2101 constexpr IValueT VpopOpcode =
2039 B27 | B26 | B23 | B21 | B20 | B19 | B18 | B16 | B11 | B9; 2102 B27 | B26 | B23 | B21 | B20 | B19 | B18 | B16 | B11 | B9;
2040 emitVStackOp(Cond, VpopOpcode, OpBaseReg, NumConsecRegs, VpopName); 2103 emitVStackOp(Cond, VpopOpcode, OpBaseReg, NumConsecRegs);
2041 } 2104 }
2042 2105
2043 void AssemblerARM32::vpush(const Variable *OpBaseReg, SizeT NumConsecRegs, 2106 void AssemblerARM32::vpush(const Variable *OpBaseReg, SizeT NumConsecRegs,
2044 CondARM32::Cond Cond) { 2107 CondARM32::Cond Cond) {
2045 // Note: Current implementation assumes that OpBaseReg is defined using S 2108 // Note: Current implementation assumes that OpBaseReg is defined using S
2046 // registers. It doesn't implement the D register form. 2109 // registers. It doesn't implement the D register form.
2047 // 2110 //
2048 // VPUSH - ARM section A8.8.368, encoding A2: 2111 // VPUSH - ARM section A8.8.368, encoding A2:
2049 // vpush<c> <RegList> 2112 // vpush<c> <RegList>
2050 // 2113 //
2051 // cccc11010D101101dddd1010iiiiiiii where cccc=Cond, ddddD=BaseReg, and 2114 // cccc11010D101101dddd1010iiiiiiii where cccc=Cond, ddddD=BaseReg, and
2052 // iiiiiiii=NumConsecRegs. 2115 // iiiiiiii=NumConsecRegs.
2053 constexpr const char *VpushName = "vpush";
2054 constexpr IValueT VpushOpcode = 2116 constexpr IValueT VpushOpcode =
2055 B27 | B26 | B24 | B21 | B19 | B18 | B16 | B11 | B9; 2117 B27 | B26 | B24 | B21 | B19 | B18 | B16 | B11 | B9;
2056 emitVStackOp(Cond, VpushOpcode, OpBaseReg, NumConsecRegs, VpushName); 2118 emitVStackOp(Cond, VpushOpcode, OpBaseReg, NumConsecRegs);
2057 } 2119 }
2058 2120
2059 } // end of namespace ARM32 2121 } // end of namespace ARM32
2060 } // end of namespace Ice 2122 } // end of namespace Ice
OLDNEW
« no previous file with comments | « src/IceAssemblerARM32.h ('k') | src/IceConditionCodesARM32.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698