OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |