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

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

Powered by Google App Engine
This is Rietveld 408576698