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) { | 143 bool isGPRRegisterDefined(IValueT R) { return R <= RegARM32::getNumGPRRegs(); } |
Jim Stichnoth
2015/12/19 15:31:25
This "<=" looked like a bug to me, until I looked
Karl
2016/01/05 20:24:31
The problem here is that R is the assembler encode
| |
144 return R != encodeGPRRegister(RegARM32::Encoded_Not_GPR); | 144 |
145 } | 145 bool isSRegisterDefined(IValueT S) { return S <= RegARM32::getNumSRegs(); } |
146 | |
147 bool isDRegisterDefined(IValueT D) { return D <= RegARM32::getNumDRegs(); } | |
146 | 148 |
147 bool isConditionDefined(CondARM32::Cond Cond) { | 149 bool isConditionDefined(CondARM32::Cond Cond) { |
148 return Cond != CondARM32::kNone; | 150 return Cond != CondARM32::kNone; |
149 } | 151 } |
150 | 152 |
151 IValueT encodeCondition(CondARM32::Cond Cond) { | 153 IValueT encodeCondition(CondARM32::Cond Cond) { |
152 return static_cast<IValueT>(Cond); | 154 return static_cast<IValueT>(Cond); |
153 } | 155 } |
154 | 156 |
155 IValueT encodeShift(OperandARM32::ShiftKind Shift) { | 157 IValueT encodeShift(OperandARM32::ShiftKind Shift) { |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
201 return llvm::isa<Variable64On32>(Var) ? RegARM32::getI64PairFirstGPRNum(Reg) | 203 return llvm::isa<Variable64On32>(Var) ? RegARM32::getI64PairFirstGPRNum(Reg) |
202 : RegARM32::getEncodedGPR(Reg); | 204 : RegARM32::getEncodedGPR(Reg); |
203 } | 205 } |
204 | 206 |
205 IValueT getEncodedSRegNum(const Variable *Var) { | 207 IValueT getEncodedSRegNum(const Variable *Var) { |
206 assert(Var->hasReg()); | 208 assert(Var->hasReg()); |
207 assert(RegARM32::isEncodedSReg(Var->getRegNum())); | 209 assert(RegARM32::isEncodedSReg(Var->getRegNum())); |
208 return RegARM32::getEncodedSReg(Var->getRegNum()); | 210 return RegARM32::getEncodedSReg(Var->getRegNum()); |
209 } | 211 } |
210 | 212 |
213 IValueT getEncodedDRegNum(const Variable *Var) { | |
214 assert(Var->hasReg()); | |
215 assert(RegARM32::isEncodedDReg(Var->getRegNum())); | |
216 return RegARM32::getEncodedDReg(Var->getRegNum()); | |
217 } | |
218 | |
219 IValueT getYInRegXXXXY(IValueT RegXXXXY) { return RegXXXXY & 0x1; } | |
220 | |
221 IValueT getXXXXInRegXXXXY(IValueT RegXXXXY) { return RegXXXXY >> 1; } | |
222 | |
223 IValueT getYInRegYXXXX(IValueT RegYXXXX) { return RegYXXXX >> 4; } | |
224 | |
225 IValueT getXXXXInRegYXXXX(IValueT RegYXXXX) { return RegYXXXX & 0x0f; } | |
226 | |
211 // The way an operand is encoded into a sequence of bits in functions | 227 // The way an operand is encoded into a sequence of bits in functions |
212 // encodeOperand and encodeAddress below. | 228 // encodeOperand and encodeAddress below. |
213 enum EncodedOperand { | 229 enum EncodedOperand { |
214 // Unable to encode, value left undefined. | 230 // Unable to encode, value left undefined. |
215 CantEncode = 0, | 231 CantEncode = 0, |
216 // Value is register found. | 232 // Value is register found. |
217 EncodedAsRegister, | 233 EncodedAsRegister, |
218 // Value=rrrriiiiiiii where rrrr is the rotation, and iiiiiiii is the imm8 | 234 // Value=rrrriiiiiiii where rrrr is the rotation, and iiiiiiii is the imm8 |
219 // value. | 235 // value. |
220 EncodedAsRotatedImm8, | 236 EncodedAsRotatedImm8, |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
271 } | 287 } |
272 | 288 |
273 // Encodes mmmmtt01ssss for data-processing operands where mmmm=Rm, ssss=Rs, and | 289 // Encodes mmmmtt01ssss for data-processing operands where mmmm=Rm, ssss=Rs, and |
274 // tt=Shift. | 290 // tt=Shift. |
275 IValueT encodeShiftRotateReg(IValueT Rm, OperandARM32::ShiftKind Shift, | 291 IValueT encodeShiftRotateReg(IValueT Rm, OperandARM32::ShiftKind Shift, |
276 IValueT Rs) { | 292 IValueT Rs) { |
277 return (Rs << kRsShift) | (encodeShift(Shift) << kShiftShift) | B4 | | 293 return (Rs << kRsShift) | (encodeShift(Shift) << kShiftShift) | B4 | |
278 (Rm << kRmShift); | 294 (Rm << kRmShift); |
279 } | 295 } |
280 | 296 |
281 EncodedOperand encodeOperand(const Operand *Opnd, IValueT &Value) { | 297 // Defines the set of registers expected in an operand. |
298 enum RegSetWanted { WantGPRegs, WantSRegs, WantDRegs }; | |
299 | |
300 EncodedOperand encodeOperand(const Operand *Opnd, IValueT &Value, | |
301 RegSetWanted WantedRegSet) { | |
302 (void)WantedRegSet; | |
282 Value = 0; // Make sure initialized. | 303 Value = 0; // Make sure initialized. |
283 if (const auto *Var = llvm::dyn_cast<Variable>(Opnd)) { | 304 if (const auto *Var = llvm::dyn_cast<Variable>(Opnd)) { |
284 if (Var->hasReg()) { | 305 if (Var->hasReg()) { |
285 Value = getEncodedGPRegNum(Var); | 306 switch (WantedRegSet) { |
307 case WantGPRegs: | |
308 Value = getEncodedGPRegNum(Var); | |
309 break; | |
310 case WantSRegs: | |
311 Value = getEncodedSRegNum(Var); | |
312 break; | |
313 case WantDRegs: | |
314 Value = getEncodedDRegNum(Var); | |
315 break; | |
316 } | |
286 return EncodedAsRegister; | 317 return EncodedAsRegister; |
287 } | 318 } |
288 return CantEncode; | 319 return CantEncode; |
289 } | 320 } |
290 if (const auto *FlexImm = llvm::dyn_cast<OperandARM32FlexImm>(Opnd)) { | 321 if (const auto *FlexImm = llvm::dyn_cast<OperandARM32FlexImm>(Opnd)) { |
291 const IValueT Immed8 = FlexImm->getImm(); | 322 const IValueT Immed8 = FlexImm->getImm(); |
292 const IValueT Rotate = FlexImm->getRotateAmt(); | 323 const IValueT Rotate = FlexImm->getRotateAmt(); |
293 if (!((Rotate < (1 << kRotateBits)) && (Immed8 < (1 << kImmed8Bits)))) | 324 if (!((Rotate < (1 << kRotateBits)) && (Immed8 < (1 << kImmed8Bits)))) |
294 return CantEncode; | 325 return CantEncode; |
295 Value = (Rotate << kRotateShift) | (Immed8 << kImmed8Shift); | 326 Value = (Rotate << kRotateShift) | (Immed8 << kImmed8Shift); |
296 return EncodedAsRotatedImm8; | 327 return EncodedAsRotatedImm8; |
297 } | 328 } |
298 if (const auto *Const = llvm::dyn_cast<ConstantInteger32>(Opnd)) { | 329 if (const auto *Const = llvm::dyn_cast<ConstantInteger32>(Opnd)) { |
299 Value = Const->getValue(); | 330 Value = Const->getValue(); |
300 return EncodedAsConstI32; | 331 return EncodedAsConstI32; |
301 } | 332 } |
302 if (const auto *FlexReg = llvm::dyn_cast<OperandARM32FlexReg>(Opnd)) { | 333 if (const auto *FlexReg = llvm::dyn_cast<OperandARM32FlexReg>(Opnd)) { |
303 Operand *Amt = FlexReg->getShiftAmt(); | 334 Operand *Amt = FlexReg->getShiftAmt(); |
304 IValueT Rm; | 335 IValueT Rm; |
305 if (encodeOperand(FlexReg->getReg(), Rm) != EncodedAsRegister) | 336 if (encodeOperand(FlexReg->getReg(), Rm, WantGPRegs) != EncodedAsRegister) |
306 return CantEncode; | 337 return CantEncode; |
307 if (const auto *Var = llvm::dyn_cast<Variable>(Amt)) { | 338 if (const auto *Var = llvm::dyn_cast<Variable>(Amt)) { |
308 IValueT Rs; | 339 IValueT Rs; |
309 if (encodeOperand(Var, Rs) != EncodedAsRegister) | 340 if (encodeOperand(Var, Rs, WantGPRegs) != EncodedAsRegister) |
310 return CantEncode; | 341 return CantEncode; |
311 Value = encodeShiftRotateReg(Rm, FlexReg->getShiftOp(), Rs); | 342 Value = encodeShiftRotateReg(Rm, FlexReg->getShiftOp(), Rs); |
312 return EncodedAsRegShiftReg; | 343 return EncodedAsRegShiftReg; |
313 } | 344 } |
314 // If reached, the amount is a shifted amount by some 5-bit immediate. | 345 // If reached, the amount is a shifted amount by some 5-bit immediate. |
315 uint32_t Imm5; | 346 uint32_t Imm5; |
316 if (const auto *ShAmt = llvm::dyn_cast<OperandARM32ShAmtImm>(Amt)) { | 347 if (const auto *ShAmt = llvm::dyn_cast<OperandARM32ShAmtImm>(Amt)) { |
317 Imm5 = ShAmt->getShAmtImm(); | 348 Imm5 = ShAmt->getShAmtImm(); |
318 } else if (const auto *IntConst = llvm::dyn_cast<ConstantInteger32>(Amt)) { | 349 } else if (const auto *IntConst = llvm::dyn_cast<ConstantInteger32>(Amt)) { |
319 int32_t Val = IntConst->getValue(); | 350 int32_t Val = IntConst->getValue(); |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
414 } | 445 } |
415 return CantEncode; | 446 return CantEncode; |
416 } | 447 } |
417 | 448 |
418 // Checks that Offset can fit in imm24 constant of branch (b) instruction. | 449 // Checks that Offset can fit in imm24 constant of branch (b) instruction. |
419 bool canEncodeBranchOffset(IOffsetT Offset) { | 450 bool canEncodeBranchOffset(IOffsetT Offset) { |
420 return Utils::IsAligned(Offset, 4) && | 451 return Utils::IsAligned(Offset, 4) && |
421 Utils::IsInt(kBranchOffsetBits, Offset >> 2); | 452 Utils::IsInt(kBranchOffsetBits, Offset >> 2); |
422 } | 453 } |
423 | 454 |
424 IValueT encodeRegister(const Operand *OpReg, const char *RegName, | 455 IValueT encodeRegister(const Operand *OpReg, RegSetWanted WantedRegSet, |
425 const char *InstName) { | 456 const char *RegName, const char *InstName) { |
426 IValueT Reg = 0; | 457 IValueT Reg = 0; |
427 if (encodeOperand(OpReg, Reg) != EncodedAsRegister) | 458 if (encodeOperand(OpReg, Reg, WantedRegSet) != EncodedAsRegister) |
428 llvm::report_fatal_error(std::string(InstName) + ": Can't find register " + | 459 llvm::report_fatal_error(std::string(InstName) + ": Can't find register " + |
429 RegName); | 460 RegName); |
430 return Reg; | 461 return Reg; |
431 } | 462 } |
432 | 463 |
433 void verifyRegDefined(IValueT Reg, const char *RegName, const char *InstName) { | 464 IValueT encodeGPRegister(const Operand *OpReg, const char *RegName, |
465 const char *InstName) { | |
466 return encodeRegister(OpReg, WantGPRegs, RegName, InstName); | |
467 } | |
468 | |
469 IValueT encodeSRegister(const Operand *OpReg, const char *RegName, | |
470 const char *InstName) { | |
471 return encodeRegister(OpReg, WantSRegs, RegName, InstName); | |
472 } | |
473 | |
474 IValueT encodeDRegister(const Operand *OpReg, const char *RegName, | |
475 const char *InstName) { | |
476 return encodeRegister(OpReg, WantDRegs, RegName, InstName); | |
477 } | |
478 | |
479 void verifyGPRegDefined(IValueT Reg, const char *RegName, | |
480 const char *InstName) { | |
434 if (BuildDefs::minimal()) | 481 if (BuildDefs::minimal()) |
435 return; | 482 return; |
436 if (!isGPRRegisterDefined(Reg)) | 483 if (!isGPRRegisterDefined(Reg)) |
437 llvm::report_fatal_error(std::string(InstName) + ": Can't find " + RegName); | 484 llvm::report_fatal_error(std::string(InstName) + ": Can't find " + RegName); |
438 } | 485 } |
439 | 486 |
487 void verifySRegDefined(IValueT Reg, const char *RegName, const char *InstName) { | |
488 if (BuildDefs::minimal()) | |
489 return; | |
490 if (!isSRegisterDefined(Reg)) | |
491 llvm::report_fatal_error(std::string(InstName) + ": Can't find " + RegName); | |
492 } | |
493 | |
494 void verifyDRegDefined(IValueT Reg, const char *RegName, const char *InstName) { | |
495 if (BuildDefs::minimal()) | |
496 return; | |
497 if (!isDRegisterDefined(Reg)) | |
498 llvm::report_fatal_error(std::string(InstName) + ": Can't find " + RegName); | |
499 } | |
500 | |
440 void verifyCondDefined(CondARM32::Cond Cond, const char *InstName) { | 501 void verifyCondDefined(CondARM32::Cond Cond, const char *InstName) { |
441 if (BuildDefs::minimal()) | 502 if (BuildDefs::minimal()) |
442 return; | 503 return; |
443 if (!isConditionDefined(Cond)) | 504 if (!isConditionDefined(Cond)) |
444 llvm::report_fatal_error(std::string(InstName) + ": Condition not defined"); | 505 llvm::report_fatal_error(std::string(InstName) + ": Condition not defined"); |
445 } | 506 } |
446 | 507 |
447 void verifyPOrNotW(IValueT Address, const char *InstName) { | 508 void verifyPOrNotW(IValueT Address, const char *InstName) { |
448 if (BuildDefs::minimal()) | 509 if (BuildDefs::minimal()) |
449 return; | 510 return; |
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
624 IValueT Opcode, bool SetFlags, IValueT Rn, | 685 IValueT Opcode, bool SetFlags, IValueT Rn, |
625 IValueT Rd, IValueT Imm12, | 686 IValueT Rd, IValueT Imm12, |
626 EmitChecks RuleChecks, const char *InstName) { | 687 EmitChecks RuleChecks, const char *InstName) { |
627 switch (RuleChecks) { | 688 switch (RuleChecks) { |
628 case NoChecks: | 689 case NoChecks: |
629 break; | 690 break; |
630 case RdIsPcAndSetFlags: | 691 case RdIsPcAndSetFlags: |
631 verifyRegNotPcWhenSetFlags(Rd, SetFlags, InstName); | 692 verifyRegNotPcWhenSetFlags(Rd, SetFlags, InstName); |
632 break; | 693 break; |
633 } | 694 } |
634 verifyRegDefined(Rd, "Rd", InstName); | 695 verifyGPRegDefined(Rd, "Rd", InstName); |
635 verifyCondDefined(Cond, InstName); | 696 verifyCondDefined(Cond, InstName); |
636 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 697 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
637 const IValueT Encoding = (encodeCondition(Cond) << kConditionShift) | | 698 const IValueT Encoding = (encodeCondition(Cond) << kConditionShift) | |
638 (InstType << kTypeShift) | (Opcode << kOpcodeShift) | | 699 (InstType << kTypeShift) | (Opcode << kOpcodeShift) | |
639 (encodeBool(SetFlags) << kSShift) | | 700 (encodeBool(SetFlags) << kSShift) | |
640 (Rn << kRnShift) | (Rd << kRdShift) | Imm12; | 701 (Rn << kRnShift) | (Rd << kRdShift) | Imm12; |
641 emitInst(Encoding); | 702 emitInst(Encoding); |
642 } | 703 } |
643 | 704 |
644 void AssemblerARM32::emitType01(CondARM32::Cond Cond, IValueT Opcode, | 705 void AssemblerARM32::emitType01(CondARM32::Cond Cond, IValueT Opcode, |
645 const Operand *OpRd, const Operand *OpRn, | 706 const Operand *OpRd, const Operand *OpRn, |
646 const Operand *OpSrc1, bool SetFlags, | 707 const Operand *OpSrc1, bool SetFlags, |
647 EmitChecks RuleChecks, const char *InstName) { | 708 EmitChecks RuleChecks, const char *InstName) { |
648 IValueT Rd = encodeRegister(OpRd, "Rd", InstName); | 709 IValueT Rd = encodeGPRegister(OpRd, "Rd", InstName); |
649 IValueT Rn = encodeRegister(OpRn, "Rn", InstName); | 710 IValueT Rn = encodeGPRegister(OpRn, "Rn", InstName); |
650 emitType01(Cond, Opcode, Rd, Rn, OpSrc1, SetFlags, RuleChecks, InstName); | 711 emitType01(Cond, Opcode, Rd, Rn, OpSrc1, SetFlags, RuleChecks, InstName); |
651 } | 712 } |
652 | 713 |
653 void AssemblerARM32::emitType01(CondARM32::Cond Cond, IValueT Opcode, | 714 void AssemblerARM32::emitType01(CondARM32::Cond Cond, IValueT Opcode, |
654 IValueT Rd, IValueT Rn, const Operand *OpSrc1, | 715 IValueT Rd, IValueT Rn, const Operand *OpSrc1, |
655 bool SetFlags, EmitChecks RuleChecks, | 716 bool SetFlags, EmitChecks RuleChecks, |
656 const char *InstName) { | 717 const char *InstName) { |
657 IValueT Src1Value; | 718 IValueT Src1Value; |
658 // TODO(kschimpf) Other possible decodings of data operations. | 719 // TODO(kschimpf) Other possible decodings of data operations. |
659 switch (encodeOperand(OpSrc1, Src1Value)) { | 720 switch (encodeOperand(OpSrc1, Src1Value, WantGPRegs)) { |
660 default: | 721 default: |
661 llvm::report_fatal_error(std::string(InstName) + | 722 llvm::report_fatal_error(std::string(InstName) + |
662 ": Can't encode instruction"); | 723 ": Can't encode instruction"); |
663 return; | 724 return; |
664 case EncodedAsRegister: { | 725 case EncodedAsRegister: { |
665 // XXX (register) | 726 // XXX (register) |
666 // xxx{s}<c> <Rd>, <Rn>, <Rm>{, <shiff>} | 727 // xxx{s}<c> <Rd>, <Rn>, <Rm>{, <shiff>} |
667 // | 728 // |
668 // cccc000xxxxsnnnnddddiiiiitt0mmmm where cccc=Cond, xxxx=Opcode, dddd=Rd, | 729 // cccc000xxxxsnnnnddddiiiiitt0mmmm where cccc=Cond, xxxx=Opcode, dddd=Rd, |
669 // nnnn=Rn, mmmm=Rm, iiiii=Shift, tt=ShiftKind, and s=SetFlags. | 730 // nnnn=Rn, mmmm=Rm, iiiii=Shift, tt=ShiftKind, and s=SetFlags. |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
751 // xxxx=Opcode. | 812 // xxxx=Opcode. |
752 // | 813 // |
753 // XXX (immediate) | 814 // XXX (immediate) |
754 // XXX<c> <Rn>, #<RotatedImm8> | 815 // XXX<c> <Rn>, #<RotatedImm8> |
755 // | 816 // |
756 // ccccyyyxxxx1nnnn0000iiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn, | 817 // ccccyyyxxxx1nnnn0000iiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn, |
757 // yyy=kInstTypeDataImmdiate, xxxx=Opcode, and iiiiiiiiiiii=Src1Value | 818 // yyy=kInstTypeDataImmdiate, xxxx=Opcode, and iiiiiiiiiiii=Src1Value |
758 // defining RotatedImm8. | 819 // defining RotatedImm8. |
759 constexpr bool SetFlags = true; | 820 constexpr bool SetFlags = true; |
760 constexpr IValueT Rd = RegARM32::Encoded_Reg_r0; | 821 constexpr IValueT Rd = RegARM32::Encoded_Reg_r0; |
761 IValueT Rn = encodeRegister(OpRn, "Rn", InstName); | 822 IValueT Rn = encodeGPRegister(OpRn, "Rn", InstName); |
762 emitType01(Cond, Opcode, Rd, Rn, OpSrc1, SetFlags, NoChecks, InstName); | 823 emitType01(Cond, Opcode, Rd, Rn, OpSrc1, SetFlags, NoChecks, InstName); |
763 } | 824 } |
764 | 825 |
765 void AssemblerARM32::emitMemOp(CondARM32::Cond Cond, IValueT InstType, | 826 void AssemblerARM32::emitMemOp(CondARM32::Cond Cond, IValueT InstType, |
766 bool IsLoad, bool IsByte, IValueT Rt, | 827 bool IsLoad, bool IsByte, IValueT Rt, |
767 IValueT Address, const char *InstName) { | 828 IValueT Address, const char *InstName) { |
768 verifyRegDefined(Rt, "Rt", InstName); | 829 verifyGPRegDefined(Rt, "Rt", InstName); |
769 verifyCondDefined(Cond, InstName); | 830 verifyCondDefined(Cond, InstName); |
770 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 831 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
771 const IValueT Encoding = (encodeCondition(Cond) << kConditionShift) | | 832 const IValueT Encoding = (encodeCondition(Cond) << kConditionShift) | |
772 (InstType << kTypeShift) | (IsLoad ? L : 0) | | 833 (InstType << kTypeShift) | (IsLoad ? L : 0) | |
773 (IsByte ? B : 0) | (Rt << kRdShift) | Address; | 834 (IsByte ? B : 0) | (Rt << kRdShift) | Address; |
774 emitInst(Encoding); | 835 emitInst(Encoding); |
775 } | 836 } |
776 | 837 |
777 void AssemblerARM32::emitMemOp(CondARM32::Cond Cond, bool IsLoad, bool IsByte, | 838 void AssemblerARM32::emitMemOp(CondARM32::Cond Cond, bool IsLoad, bool IsByte, |
778 IValueT Rt, const Operand *OpAddress, | 839 IValueT Rt, const Operand *OpAddress, |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
844 ": Memory address not understood"); | 905 ": Memory address not understood"); |
845 case EncodedAsImmRegOffset: { | 906 case EncodedAsImmRegOffset: { |
846 // XXXH (immediate) | 907 // XXXH (immediate) |
847 // xxxh<c> <Rt>, [<Rn>{, #+-<Imm8>}] | 908 // xxxh<c> <Rt>, [<Rn>{, #+-<Imm8>}] |
848 // xxxh<c> <Rt>, [<Rn>, #+/-<Imm8>] | 909 // xxxh<c> <Rt>, [<Rn>, #+/-<Imm8>] |
849 // xxxh<c> <Rt>, [<Rn>, #+/-<Imm8>]! | 910 // xxxh<c> <Rt>, [<Rn>, #+/-<Imm8>]! |
850 // | 911 // |
851 // cccc000pu0wxnnnnttttiiiiyyyyjjjj where cccc=Cond, nnnn=Rn, tttt=Rt, | 912 // cccc000pu0wxnnnnttttiiiiyyyyjjjj where cccc=Cond, nnnn=Rn, tttt=Rt, |
852 // iiiijjjj=Imm8, pu0w<<21 is a BlockAddr, x000000000000yyyy0000=Opcode, | 913 // iiiijjjj=Imm8, pu0w<<21 is a BlockAddr, x000000000000yyyy0000=Opcode, |
853 // and pu0w0nnnn0000iiii0000jjjj=Address. | 914 // and pu0w0nnnn0000iiii0000jjjj=Address. |
854 verifyRegDefined(Rt, "Rt", InstName); | 915 verifyGPRegDefined(Rt, "Rt", InstName); |
855 verifyCondDefined(Cond, InstName); | 916 verifyCondDefined(Cond, InstName); |
856 verifyPOrNotW(Address, InstName); | 917 verifyPOrNotW(Address, InstName); |
857 verifyRegNotPc(Rt, "Rt", InstName); | 918 verifyRegNotPc(Rt, "Rt", InstName); |
858 if (isBitSet(W, Address)) | 919 if (isBitSet(W, Address)) |
859 verifyRegsNotEq(getGPRReg(kRnShift, Address), "Rn", Rt, "Rt", InstName); | 920 verifyRegsNotEq(getGPRReg(kRnShift, Address), "Rn", Rt, "Rt", InstName); |
860 const IValueT Encoding = (encodeCondition(Cond) << kConditionShift) | | 921 const IValueT Encoding = (encodeCondition(Cond) << kConditionShift) | |
861 Opcode | (Rt << kRdShift) | Address; | 922 Opcode | (Rt << kRdShift) | Address; |
862 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 923 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
863 emitInst(Encoding); | 924 emitInst(Encoding); |
864 return; | 925 return; |
865 } | 926 } |
866 case EncodedAsShiftRotateImm5: { | 927 case EncodedAsShiftRotateImm5: { |
867 // XXXH (register) | 928 // XXXH (register) |
868 // xxxh<c> <Rt>, [<Rn>, +/-<Rm>]{!} | 929 // xxxh<c> <Rt>, [<Rn>, +/-<Rm>]{!} |
869 // xxxh<c> <Rt>, [<Rn>], +/-<Rm> | 930 // xxxh<c> <Rt>, [<Rn>], +/-<Rm> |
870 // | 931 // |
871 // cccc000pu0wxnnnntttt00001011mmmm where cccc=Cond, tttt=Rt, nnnn=Rn, | 932 // cccc000pu0wxnnnntttt00001011mmmm where cccc=Cond, tttt=Rt, nnnn=Rn, |
872 // mmmm=Rm, pu0w<<21 is a BlockAddr, x000000000000yyyy0000=Opcode, and | 933 // mmmm=Rm, pu0w<<21 is a BlockAddr, x000000000000yyyy0000=Opcode, and |
873 // pu0w0nnnn000000000000mmmm=Address. | 934 // pu0w0nnnn000000000000mmmm=Address. |
874 verifyRegDefined(Rt, "Rt", InstName); | 935 verifyGPRegDefined(Rt, "Rt", InstName); |
875 verifyCondDefined(Cond, InstName); | 936 verifyCondDefined(Cond, InstName); |
876 verifyPOrNotW(Address, InstName); | 937 verifyPOrNotW(Address, InstName); |
877 verifyRegNotPc(Rt, "Rt", InstName); | 938 verifyRegNotPc(Rt, "Rt", InstName); |
878 verifyAddrRegNotPc(kRmShift, Address, "Rm", InstName); | 939 verifyAddrRegNotPc(kRmShift, Address, "Rm", InstName); |
879 const RegARM32::GPRRegister Rn = getGPRReg(kRnShift, Address); | 940 const RegARM32::GPRRegister Rn = getGPRReg(kRnShift, Address); |
880 if (isBitSet(W, Address)) { | 941 if (isBitSet(W, Address)) { |
881 verifyRegNotPc(Rn, "Rn", InstName); | 942 verifyRegNotPc(Rn, "Rn", InstName); |
882 verifyRegsNotEq(Rn, "Rn", Rt, "Rt", InstName); | 943 verifyRegsNotEq(Rn, "Rn", Rt, "Rt", InstName); |
883 } | 944 } |
884 if (mask(Address, kShiftImmShift, 5) != 0) | 945 if (mask(Address, kShiftImmShift, 5) != 0) |
885 // For encoding 3, no shift is allowed. | 946 // For encoding 3, no shift is allowed. |
886 llvm::report_fatal_error(std::string(InstName) + | 947 llvm::report_fatal_error(std::string(InstName) + |
887 ": Shift constant not allowed"); | 948 ": Shift constant not allowed"); |
888 const IValueT Encoding = (encodeCondition(Cond) << kConditionShift) | | 949 const IValueT Encoding = (encodeCondition(Cond) << kConditionShift) | |
889 Opcode | (Rt << kRdShift) | Address; | 950 Opcode | (Rt << kRdShift) | Address; |
890 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 951 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
891 emitInst(Encoding); | 952 emitInst(Encoding); |
892 return; | 953 return; |
893 } | 954 } |
894 } | 955 } |
895 } | 956 } |
896 | 957 |
897 void AssemblerARM32::emitDivOp(CondARM32::Cond Cond, IValueT Opcode, IValueT Rd, | 958 void AssemblerARM32::emitDivOp(CondARM32::Cond Cond, IValueT Opcode, IValueT Rd, |
898 IValueT Rn, IValueT Rm, const char *InstName) { | 959 IValueT Rn, IValueT Rm, const char *InstName) { |
899 verifyRegDefined(Rd, "Rd", InstName); | 960 verifyGPRegDefined(Rd, "Rd", InstName); |
900 verifyRegDefined(Rn, "Rn", InstName); | 961 verifyGPRegDefined(Rn, "Rn", InstName); |
901 verifyRegDefined(Rm, "Rm", InstName); | 962 verifyGPRegDefined(Rm, "Rm", InstName); |
902 verifyCondDefined(Cond, InstName); | 963 verifyCondDefined(Cond, InstName); |
903 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 964 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
904 const IValueT Encoding = Opcode | (encodeCondition(Cond) << kConditionShift) | | 965 const IValueT Encoding = Opcode | (encodeCondition(Cond) << kConditionShift) | |
905 (Rn << kDivRnShift) | (Rd << kDivRdShift) | B26 | | 966 (Rn << kDivRnShift) | (Rd << kDivRdShift) | B26 | |
906 B25 | B24 | B20 | B15 | B14 | B13 | B12 | B4 | | 967 B25 | B24 | B20 | B15 | B14 | B13 | B12 | B4 | |
907 (Rm << kDivRmShift); | 968 (Rm << kDivRmShift); |
908 emitInst(Encoding); | 969 emitInst(Encoding); |
909 } | 970 } |
910 | 971 |
911 void AssemblerARM32::emitMulOp(CondARM32::Cond Cond, IValueT Opcode, IValueT Rd, | 972 void AssemblerARM32::emitMulOp(CondARM32::Cond Cond, IValueT Opcode, IValueT Rd, |
912 IValueT Rn, IValueT Rm, IValueT Rs, | 973 IValueT Rn, IValueT Rm, IValueT Rs, |
913 bool SetFlags, const char *InstName) { | 974 bool SetFlags, const char *InstName) { |
914 verifyRegDefined(Rd, "Rd", InstName); | 975 verifyGPRegDefined(Rd, "Rd", InstName); |
915 verifyRegDefined(Rn, "Rn", InstName); | 976 verifyGPRegDefined(Rn, "Rn", InstName); |
916 verifyRegDefined(Rm, "Rm", InstName); | 977 verifyGPRegDefined(Rm, "Rm", InstName); |
917 verifyRegDefined(Rs, "Rs", InstName); | 978 verifyGPRegDefined(Rs, "Rs", InstName); |
918 verifyCondDefined(Cond, InstName); | 979 verifyCondDefined(Cond, InstName); |
919 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 980 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
920 IValueT Encoding = Opcode | (encodeCondition(Cond) << kConditionShift) | | 981 IValueT Encoding = Opcode | (encodeCondition(Cond) << kConditionShift) | |
921 (encodeBool(SetFlags) << kSShift) | (Rn << kRnShift) | | 982 (encodeBool(SetFlags) << kSShift) | (Rn << kRnShift) | |
922 (Rd << kRdShift) | (Rs << kRsShift) | B7 | B4 | | 983 (Rd << kRdShift) | (Rs << kRsShift) | B7 | B4 | |
923 (Rm << kRmShift); | 984 (Rm << kRmShift); |
924 emitInst(Encoding); | 985 emitInst(Encoding); |
925 } | 986 } |
926 | 987 |
927 void AssemblerARM32::emitMultiMemOp(CondARM32::Cond Cond, | 988 void AssemblerARM32::emitMultiMemOp(CondARM32::Cond Cond, |
928 BlockAddressMode AddressMode, bool IsLoad, | 989 BlockAddressMode AddressMode, bool IsLoad, |
929 IValueT BaseReg, IValueT Registers, | 990 IValueT BaseReg, IValueT Registers, |
930 const char *InstName) { | 991 const char *InstName) { |
931 constexpr IValueT NumGPRegisters = 16; | 992 constexpr IValueT NumGPRegisters = 16; |
932 verifyCondDefined(Cond, InstName); | 993 verifyCondDefined(Cond, InstName); |
933 verifyRegDefined(BaseReg, "base", InstName); | 994 verifyGPRegDefined(BaseReg, "base", InstName); |
934 if (Registers >= (1 << NumGPRegisters)) | 995 if (Registers >= (1 << NumGPRegisters)) |
935 llvm::report_fatal_error(std::string(InstName) + | 996 llvm::report_fatal_error(std::string(InstName) + |
936 ": Register set too large"); | 997 ": Register set too large"); |
937 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 998 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
938 IValueT Encoding = (encodeCondition(Cond) << kConditionShift) | B27 | | 999 IValueT Encoding = (encodeCondition(Cond) << kConditionShift) | B27 | |
939 AddressMode | (IsLoad ? L : 0) | (BaseReg << kRnShift) | | 1000 AddressMode | (IsLoad ? L : 0) | (BaseReg << kRnShift) | |
940 Registers; | 1001 Registers; |
941 emitInst(Encoding); | 1002 emitInst(Encoding); |
942 } | 1003 } |
943 | 1004 |
944 void AssemblerARM32::emitSignExtend(CondARM32::Cond Cond, IValueT Opcode, | 1005 void AssemblerARM32::emitSignExtend(CondARM32::Cond Cond, IValueT Opcode, |
945 const Operand *OpRd, const Operand *OpSrc0, | 1006 const Operand *OpRd, const Operand *OpSrc0, |
946 const char *InstName) { | 1007 const char *InstName) { |
947 IValueT Rd = encodeRegister(OpRd, "Rd", InstName); | 1008 IValueT Rd = encodeGPRegister(OpRd, "Rd", InstName); |
948 IValueT Rm = encodeRegister(OpSrc0, "Rm", InstName); | 1009 IValueT Rm = encodeGPRegister(OpSrc0, "Rm", InstName); |
949 // Note: For the moment, we assume no rotation is specified. | 1010 // Note: For the moment, we assume no rotation is specified. |
950 RotationValue Rotation = kRotateNone; | 1011 RotationValue Rotation = kRotateNone; |
951 constexpr IValueT Rn = RegARM32::Encoded_Reg_pc; | 1012 constexpr IValueT Rn = RegARM32::Encoded_Reg_pc; |
952 const Type Ty = OpSrc0->getType(); | 1013 const Type Ty = OpSrc0->getType(); |
953 switch (Ty) { | 1014 switch (Ty) { |
954 default: | 1015 default: |
955 llvm::report_fatal_error(std::string(InstName) + ": Type " + | 1016 llvm::report_fatal_error(std::string(InstName) + ": Type " + |
956 typeString(Ty) + " not allowed"); | 1017 typeString(Ty) + " not allowed"); |
957 break; | 1018 break; |
958 case IceType_i1: | 1019 case IceType_i1: |
(...skipping 22 matching lines...) Expand all Loading... | |
981 if (!Utils::IsUint(2, Rot)) | 1042 if (!Utils::IsUint(2, Rot)) |
982 llvm::report_fatal_error(std::string(InstName) + | 1043 llvm::report_fatal_error(std::string(InstName) + |
983 ": Illegal rotation value"); | 1044 ": Illegal rotation value"); |
984 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 1045 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
985 IValueT Encoding = (encodeCondition(Cond) << kConditionShift) | Opcode | | 1046 IValueT Encoding = (encodeCondition(Cond) << kConditionShift) | Opcode | |
986 (Rn << kRnShift) | (Rd << kRdShift) | | 1047 (Rn << kRnShift) | (Rd << kRdShift) | |
987 (Rot << kRotationShift) | B6 | B5 | B4 | (Rm << kRmShift); | 1048 (Rot << kRotationShift) | B6 | B5 | B4 | (Rm << kRmShift); |
988 emitInst(Encoding); | 1049 emitInst(Encoding); |
989 } | 1050 } |
990 | 1051 |
1052 void AssemblerARM32::emitVFPddd(CondARM32::Cond Cond, IValueT Opcode, | |
1053 IValueT Dd, IValueT Dn, IValueT Dm, | |
1054 const char *InstName) { | |
1055 verifyDRegDefined(Dd, "Dd", InstName); | |
1056 verifyDRegDefined(Dn, "Dn", InstName); | |
1057 verifyDRegDefined(Dm, "Dm", InstName); | |
1058 verifyCondDefined(Cond, InstName); | |
1059 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | |
1060 constexpr IValueT VFPOpcode = B27 | B26 | B25 | B11 | B9 | B8; | |
1061 const IValueT Encoding = | |
1062 Opcode | VFPOpcode | (encodeCondition(Cond) << kConditionShift) | | |
1063 (getYInRegYXXXX(Dd) << 22) | (getXXXXInRegYXXXX(Dn) << 16) | | |
1064 (getXXXXInRegYXXXX(Dn) << 12) | (getYInRegYXXXX(Dn) << 7) | | |
1065 (getYInRegYXXXX(Dm) << 5) | getXXXXInRegYXXXX(Dm); | |
1066 emitInst(Encoding); | |
1067 } | |
1068 | |
1069 void AssemblerARM32::emitVFPsss(CondARM32::Cond Cond, IValueT Opcode, | |
1070 IValueT Sd, IValueT Sn, IValueT Sm, | |
1071 const char *InstName) { | |
1072 verifySRegDefined(Sd, "Sd", InstName); | |
1073 verifySRegDefined(Sn, "Sn", InstName); | |
1074 verifySRegDefined(Sm, "Sm", InstName); | |
1075 verifyCondDefined(Cond, InstName); | |
1076 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | |
1077 constexpr IValueT VFPOpcode = B27 | B26 | B25 | B11 | B9; | |
1078 const IValueT Encoding = | |
1079 Opcode | VFPOpcode | (encodeCondition(Cond) << kConditionShift) | | |
1080 (getYInRegXXXXY(Sd) << 22) | (getXXXXInRegXXXXY(Sn) << 16) | | |
1081 (getXXXXInRegXXXXY(Sd) << 12) | (getYInRegXXXXY(Sn) << 7) | | |
1082 (getYInRegXXXXY(Sm) << 5) | getXXXXInRegXXXXY(Sm); | |
1083 emitInst(Encoding); | |
1084 } | |
1085 | |
991 void AssemblerARM32::adc(const Operand *OpRd, const Operand *OpRn, | 1086 void AssemblerARM32::adc(const Operand *OpRd, const Operand *OpRn, |
992 const Operand *OpSrc1, bool SetFlags, | 1087 const Operand *OpSrc1, bool SetFlags, |
993 CondARM32::Cond Cond) { | 1088 CondARM32::Cond Cond) { |
994 // ADC (register) - ARM section 18.8.2, encoding A1: | 1089 // ADC (register) - ARM section 18.8.2, encoding A1: |
995 // adc{s}<c> <Rd>, <Rn>, <Rm>{, <shift>} | 1090 // adc{s}<c> <Rd>, <Rn>, <Rm>{, <shift>} |
996 // | 1091 // |
997 // cccc0000101snnnnddddiiiiitt0mmmm where cccc=Cond, dddd=Rd, nnnn=Rn, | 1092 // cccc0000101snnnnddddiiiiitt0mmmm where cccc=Cond, dddd=Rd, nnnn=Rn, |
998 // mmmm=Rm, iiiii=Shift, tt=ShiftKind, and s=SetFlags. | 1093 // mmmm=Rm, iiiii=Shift, tt=ShiftKind, and s=SetFlags. |
999 // | 1094 // |
1000 // ADC (Immediate) - ARM section A8.8.1, encoding A1: | 1095 // ADC (Immediate) - ARM section A8.8.1, encoding A1: |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1101 emitType05(Cond, Immed, Link, BlName); | 1196 emitType05(Cond, Immed, Link, BlName); |
1102 } | 1197 } |
1103 | 1198 |
1104 void AssemblerARM32::blx(const Operand *Target) { | 1199 void AssemblerARM32::blx(const Operand *Target) { |
1105 // BLX (register) - ARM section A8.8.26, encoding A1: | 1200 // BLX (register) - ARM section A8.8.26, encoding A1: |
1106 // blx<c> <Rm> | 1201 // blx<c> <Rm> |
1107 // | 1202 // |
1108 // cccc000100101111111111110011mmmm where cccc=Cond (not currently allowed) | 1203 // cccc000100101111111111110011mmmm where cccc=Cond (not currently allowed) |
1109 // and mmmm=Rm. | 1204 // and mmmm=Rm. |
1110 constexpr const char *BlxName = "Blx"; | 1205 constexpr const char *BlxName = "Blx"; |
1111 IValueT Rm = encodeRegister(Target, "Rm", BlxName); | 1206 IValueT Rm = encodeGPRegister(Target, "Rm", BlxName); |
1112 verifyRegNotPc(Rm, "Rm", BlxName); | 1207 verifyRegNotPc(Rm, "Rm", BlxName); |
1113 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 1208 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
1114 constexpr CondARM32::Cond Cond = CondARM32::AL; | 1209 constexpr CondARM32::Cond Cond = CondARM32::AL; |
1115 int32_t Encoding = (encodeCondition(Cond) << kConditionShift) | B24 | B21 | | 1210 int32_t Encoding = (encodeCondition(Cond) << kConditionShift) | B24 | B21 | |
1116 (0xfff << 8) | B5 | B4 | (Rm << kRmShift); | 1211 (0xfff << 8) | B5 | B4 | (Rm << kRmShift); |
1117 emitInst(Encoding); | 1212 emitInst(Encoding); |
1118 } | 1213 } |
1119 | 1214 |
1120 void AssemblerARM32::bx(RegARM32::GPRRegister Rm, CondARM32::Cond Cond) { | 1215 void AssemblerARM32::bx(RegARM32::GPRRegister Rm, CondARM32::Cond Cond) { |
1121 // BX - ARM section A8.8.27, encoding A1: | 1216 // BX - ARM section A8.8.27, encoding A1: |
1122 // bx<c> <Rm> | 1217 // bx<c> <Rm> |
1123 // | 1218 // |
1124 // cccc000100101111111111110001mmmm where mmmm=rm and cccc=Cond. | 1219 // cccc000100101111111111110001mmmm where mmmm=rm and cccc=Cond. |
1125 constexpr const char *BxName = "bx"; | 1220 constexpr const char *BxName = "bx"; |
1126 verifyCondDefined(Cond, BxName); | 1221 verifyCondDefined(Cond, BxName); |
1127 verifyRegDefined(Rm, "Rm", BxName); | 1222 verifyGPRegDefined(Rm, "Rm", BxName); |
1128 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 1223 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
1129 const IValueT Encoding = (encodeCondition(Cond) << kConditionShift) | B24 | | 1224 const IValueT Encoding = (encodeCondition(Cond) << kConditionShift) | B24 | |
1130 B21 | (0xfff << 8) | B4 | | 1225 B21 | (0xfff << 8) | B4 | |
1131 (encodeGPRRegister(Rm) << kRmShift); | 1226 (encodeGPRRegister(Rm) << kRmShift); |
1132 emitInst(Encoding); | 1227 emitInst(Encoding); |
1133 } | 1228 } |
1134 | 1229 |
1135 void AssemblerARM32::clz(const Operand *OpRd, const Operand *OpSrc, | 1230 void AssemblerARM32::clz(const Operand *OpRd, const Operand *OpSrc, |
1136 CondARM32::Cond Cond) { | 1231 CondARM32::Cond Cond) { |
1137 // CLZ - ARM section A8.8.33, encoding A1: | 1232 // CLZ - ARM section A8.8.33, encoding A1: |
1138 // clz<c> <Rd> <Rm> | 1233 // clz<c> <Rd> <Rm> |
1139 // | 1234 // |
1140 // cccc000101101111dddd11110001mmmm where cccc=Cond, dddd=Rd, and mmmm=Rm. | 1235 // cccc000101101111dddd11110001mmmm where cccc=Cond, dddd=Rd, and mmmm=Rm. |
1141 constexpr const char *ClzName = "clz"; | 1236 constexpr const char *ClzName = "clz"; |
1142 constexpr const char *RdName = "Rd"; | 1237 constexpr const char *RdName = "Rd"; |
1143 constexpr const char *RmName = "Rm"; | 1238 constexpr const char *RmName = "Rm"; |
1144 IValueT Rd = encodeRegister(OpRd, RdName, ClzName); | 1239 IValueT Rd = encodeGPRegister(OpRd, RdName, ClzName); |
1145 verifyRegDefined(Rd, RdName, ClzName); | 1240 verifyGPRegDefined(Rd, RdName, ClzName); |
1146 verifyRegNotPc(Rd, RdName, ClzName); | 1241 verifyRegNotPc(Rd, RdName, ClzName); |
1147 IValueT Rm = encodeRegister(OpSrc, RmName, ClzName); | 1242 IValueT Rm = encodeGPRegister(OpSrc, RmName, ClzName); |
1148 verifyRegDefined(Rm, RmName, ClzName); | 1243 verifyGPRegDefined(Rm, RmName, ClzName); |
1149 verifyRegNotPc(Rm, RmName, ClzName); | 1244 verifyRegNotPc(Rm, RmName, ClzName); |
1150 verifyCondDefined(Cond, ClzName); | 1245 verifyCondDefined(Cond, ClzName); |
1151 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 1246 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
1152 constexpr IValueT PredefinedBits = | 1247 constexpr IValueT PredefinedBits = |
1153 B24 | B22 | B21 | (0xF << 16) | (0xf << 8) | B4; | 1248 B24 | B22 | B21 | (0xF << 16) | (0xf << 8) | B4; |
1154 const IValueT Encoding = PredefinedBits | (Cond << kConditionShift) | | 1249 const IValueT Encoding = PredefinedBits | (Cond << kConditionShift) | |
1155 (Rd << kRdShift) | (Rm << kRmShift); | 1250 (Rd << kRdShift) | (Rm << kRmShift); |
1156 emitInst(Encoding); | 1251 emitInst(Encoding); |
1157 } | 1252 } |
1158 | 1253 |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1223 constexpr const char *EorName = "eor"; | 1318 constexpr const char *EorName = "eor"; |
1224 constexpr IValueT EorOpcode = B0; // 0001 | 1319 constexpr IValueT EorOpcode = B0; // 0001 |
1225 emitType01(Cond, EorOpcode, OpRd, OpRn, OpSrc1, SetFlags, RdIsPcAndSetFlags, | 1320 emitType01(Cond, EorOpcode, OpRd, OpRn, OpSrc1, SetFlags, RdIsPcAndSetFlags, |
1226 EorName); | 1321 EorName); |
1227 } | 1322 } |
1228 | 1323 |
1229 void AssemblerARM32::ldr(const Operand *OpRt, const Operand *OpAddress, | 1324 void AssemblerARM32::ldr(const Operand *OpRt, const Operand *OpAddress, |
1230 CondARM32::Cond Cond, const TargetInfo &TInfo) { | 1325 CondARM32::Cond Cond, const TargetInfo &TInfo) { |
1231 constexpr const char *LdrName = "ldr"; | 1326 constexpr const char *LdrName = "ldr"; |
1232 constexpr bool IsLoad = true; | 1327 constexpr bool IsLoad = true; |
1233 IValueT Rt = encodeRegister(OpRt, "Rt", LdrName); | 1328 IValueT Rt = encodeGPRegister(OpRt, "Rt", LdrName); |
1234 const Type Ty = OpRt->getType(); | 1329 const Type Ty = OpRt->getType(); |
1235 switch (Ty) { | 1330 switch (Ty) { |
1236 case IceType_i64: | 1331 case IceType_i64: |
1237 // LDRD is not implemented because target lowering handles i64 and double by | 1332 // LDRD is not implemented because target lowering handles i64 and double by |
1238 // using two (32-bit) load instructions. Note: Intentionally drop to default | 1333 // using two (32-bit) load instructions. Note: Intentionally drop to default |
1239 // case. | 1334 // case. |
1240 llvm::report_fatal_error(std::string("ldr : Type ") + typeString(Ty) + | 1335 llvm::report_fatal_error(std::string("ldr : Type ") + typeString(Ty) + |
1241 " not implemented"); | 1336 " not implemented"); |
1242 default: | 1337 default: |
1243 llvm::report_fatal_error(std::string("ldr : Type ") + typeString(Ty) + | 1338 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; | 1391 return; |
1297 } | 1392 } |
1298 } | 1393 } |
1299 } | 1394 } |
1300 | 1395 |
1301 void AssemblerARM32::emitMemExOp(CondARM32::Cond Cond, Type Ty, bool IsLoad, | 1396 void AssemblerARM32::emitMemExOp(CondARM32::Cond Cond, Type Ty, bool IsLoad, |
1302 const Operand *OpRd, IValueT Rt, | 1397 const Operand *OpRd, IValueT Rt, |
1303 const Operand *OpAddress, | 1398 const Operand *OpAddress, |
1304 const TargetInfo &TInfo, | 1399 const TargetInfo &TInfo, |
1305 const char *InstName) { | 1400 const char *InstName) { |
1306 IValueT Rd = encodeRegister(OpRd, "Rd", InstName); | 1401 IValueT Rd = encodeGPRegister(OpRd, "Rd", InstName); |
1307 IValueT MemExOpcode = IsLoad ? B0 : 0; | 1402 IValueT MemExOpcode = IsLoad ? B0 : 0; |
1308 switch (Ty) { | 1403 switch (Ty) { |
1309 default: | 1404 default: |
1310 llvm::report_fatal_error(std::string(InstName) + ": Type " + | 1405 llvm::report_fatal_error(std::string(InstName) + ": Type " + |
1311 typeString(Ty) + " not allowed"); | 1406 typeString(Ty) + " not allowed"); |
1312 case IceType_i1: | 1407 case IceType_i1: |
1313 case IceType_i8: | 1408 case IceType_i8: |
1314 MemExOpcode |= B2; | 1409 MemExOpcode |= B2; |
1315 break; | 1410 break; |
1316 case IceType_i16: | 1411 case IceType_i16: |
1317 MemExOpcode |= B2 | B1; | 1412 MemExOpcode |= B2 | B1; |
1318 break; | 1413 break; |
1319 case IceType_i32: | 1414 case IceType_i32: |
1320 break; | 1415 break; |
1321 case IceType_i64: | 1416 case IceType_i64: |
1322 MemExOpcode |= B1; | 1417 MemExOpcode |= B1; |
1323 } | 1418 } |
1324 IValueT AddressRn; | 1419 IValueT AddressRn; |
1325 if (encodeAddress(OpAddress, AddressRn, TInfo, OpEncodingMemEx) != | 1420 if (encodeAddress(OpAddress, AddressRn, TInfo, OpEncodingMemEx) != |
1326 EncodedAsImmRegOffset) | 1421 EncodedAsImmRegOffset) |
1327 llvm::report_fatal_error(std::string(InstName) + | 1422 llvm::report_fatal_error(std::string(InstName) + |
1328 ": Can't extract Rn from address"); | 1423 ": Can't extract Rn from address"); |
1329 assert(Utils::IsAbsoluteUint(3, MemExOpcode)); | 1424 assert(Utils::IsAbsoluteUint(3, MemExOpcode)); |
1330 verifyRegDefined(Rd, "Rd", InstName); | 1425 verifyGPRegDefined(Rd, "Rd", InstName); |
1331 verifyRegDefined(Rt, "Rt", InstName); | 1426 verifyGPRegDefined(Rt, "Rt", InstName); |
1332 verifyCondDefined(Cond, InstName); | 1427 verifyCondDefined(Cond, InstName); |
1333 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 1428 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
1334 IValueT Encoding = (Cond << kConditionShift) | B24 | B23 | B11 | B10 | B9 | | 1429 IValueT Encoding = (Cond << kConditionShift) | B24 | B23 | B11 | B10 | B9 | |
1335 B8 | B7 | B4 | (MemExOpcode << kMemExOpcodeShift) | | 1430 B8 | B7 | B4 | (MemExOpcode << kMemExOpcodeShift) | |
1336 AddressRn | (Rd << kRdShift) | (Rt << kRmShift); | 1431 AddressRn | (Rd << kRdShift) | (Rt << kRmShift); |
1337 emitInst(Encoding); | 1432 emitInst(Encoding); |
1338 return; | 1433 return; |
1339 } | 1434 } |
1340 | 1435 |
1341 void AssemblerARM32::ldrex(const Operand *OpRt, const Operand *OpAddress, | 1436 void AssemblerARM32::ldrex(const Operand *OpRt, const Operand *OpAddress, |
(...skipping 23 matching lines...) Expand all Loading... | |
1365 constexpr IValueT Rm = RegARM32::Encoded_Reg_pc; | 1460 constexpr IValueT Rm = RegARM32::Encoded_Reg_pc; |
1366 emitMemExOp(Cond, Ty, IsLoad, OpRt, Rm, OpAddress, TInfo, LdrexName); | 1461 emitMemExOp(Cond, Ty, IsLoad, OpRt, Rm, OpAddress, TInfo, LdrexName); |
1367 } | 1462 } |
1368 | 1463 |
1369 void AssemblerARM32::emitShift(const CondARM32::Cond Cond, | 1464 void AssemblerARM32::emitShift(const CondARM32::Cond Cond, |
1370 const OperandARM32::ShiftKind Shift, | 1465 const OperandARM32::ShiftKind Shift, |
1371 const Operand *OpRd, const Operand *OpRm, | 1466 const Operand *OpRd, const Operand *OpRm, |
1372 const Operand *OpSrc1, const bool SetFlags, | 1467 const Operand *OpSrc1, const bool SetFlags, |
1373 const char *InstName) { | 1468 const char *InstName) { |
1374 constexpr IValueT ShiftOpcode = B3 | B2 | B0; // 1101 | 1469 constexpr IValueT ShiftOpcode = B3 | B2 | B0; // 1101 |
1375 IValueT Rd = encodeRegister(OpRd, "Rd", InstName); | 1470 IValueT Rd = encodeGPRegister(OpRd, "Rd", InstName); |
1376 IValueT Rm = encodeRegister(OpRm, "Rm", InstName); | 1471 IValueT Rm = encodeGPRegister(OpRm, "Rm", InstName); |
1377 IValueT Value; | 1472 IValueT Value; |
1378 switch (encodeOperand(OpSrc1, Value)) { | 1473 switch (encodeOperand(OpSrc1, Value, WantGPRegs)) { |
1379 default: | 1474 default: |
1380 llvm::report_fatal_error(std::string(InstName) + | 1475 llvm::report_fatal_error(std::string(InstName) + |
1381 ": Last operand not understood"); | 1476 ": Last operand not understood"); |
1382 case EncodedAsShiftImm5: { | 1477 case EncodedAsShiftImm5: { |
1383 // XXX (immediate) | 1478 // XXX (immediate) |
1384 // xxx{s}<c> <Rd>, <Rm>, #imm5 | 1479 // xxx{s}<c> <Rd>, <Rm>, #imm5 |
1385 // | 1480 // |
1386 // cccc0001101s0000ddddiiiii000mmmm where cccc=Cond, s=SetFlags, dddd=Rd, | 1481 // cccc0001101s0000ddddiiiii000mmmm where cccc=Cond, s=SetFlags, dddd=Rd, |
1387 // iiiii=imm5, and mmmm=Rm. | 1482 // iiiii=imm5, and mmmm=Rm. |
1388 constexpr IValueT Rn = 0; // Rn field is not used. | 1483 constexpr IValueT Rn = 0; // Rn field is not used. |
1389 Value = Value | (Rm << kRmShift) | (Shift << kShiftShift); | 1484 Value = Value | (Rm << kRmShift) | (Shift << kShiftShift); |
1390 emitType01(Cond, kInstTypeDataRegShift, ShiftOpcode, SetFlags, Rn, Rd, | 1485 emitType01(Cond, kInstTypeDataRegShift, ShiftOpcode, SetFlags, Rn, Rd, |
1391 Value, RdIsPcAndSetFlags, InstName); | 1486 Value, RdIsPcAndSetFlags, InstName); |
1392 return; | 1487 return; |
1393 } | 1488 } |
1394 case EncodedAsRegister: { | 1489 case EncodedAsRegister: { |
1395 // XXX (register) | 1490 // XXX (register) |
1396 // xxx{S}<c> <Rd>, <Rm>, <Rs> | 1491 // xxx{S}<c> <Rd>, <Rm>, <Rs> |
1397 // | 1492 // |
1398 // cccc0001101s0000ddddssss0001mmmm where cccc=Cond, s=SetFlags, dddd=Rd, | 1493 // cccc0001101s0000ddddssss0001mmmm where cccc=Cond, s=SetFlags, dddd=Rd, |
1399 // mmmm=Rm, and ssss=Rs. | 1494 // mmmm=Rm, and ssss=Rs. |
1400 constexpr IValueT Rn = 0; // Rn field is not used. | 1495 constexpr IValueT Rn = 0; // Rn field is not used. |
1401 IValueT Rs = encodeRegister(OpSrc1, "Rs", InstName); | 1496 IValueT Rs = encodeGPRegister(OpSrc1, "Rs", InstName); |
1402 verifyRegNotPc(Rd, "Rd", InstName); | 1497 verifyRegNotPc(Rd, "Rd", InstName); |
1403 verifyRegNotPc(Rm, "Rm", InstName); | 1498 verifyRegNotPc(Rm, "Rm", InstName); |
1404 verifyRegNotPc(Rs, "Rs", InstName); | 1499 verifyRegNotPc(Rs, "Rs", InstName); |
1405 emitType01(Cond, kInstTypeDataRegShift, ShiftOpcode, SetFlags, Rn, Rd, | 1500 emitType01(Cond, kInstTypeDataRegShift, ShiftOpcode, SetFlags, Rn, Rd, |
1406 encodeShiftRotateReg(Rm, Shift, Rs), NoChecks, InstName); | 1501 encodeShiftRotateReg(Rm, Shift, Rs), NoChecks, InstName); |
1407 return; | 1502 return; |
1408 } | 1503 } |
1409 } | 1504 } |
1410 } | 1505 } |
1411 | 1506 |
(...skipping 26 matching lines...) Expand all Loading... | |
1438 // cccc0001101s0000dddd00000000mmmm where cccc=Cond, s=SetFlags, dddd=Rd, | 1533 // cccc0001101s0000dddd00000000mmmm where cccc=Cond, s=SetFlags, dddd=Rd, |
1439 // and nnnn=Rn. | 1534 // and nnnn=Rn. |
1440 // | 1535 // |
1441 // MOV (immediate) - ARM section A8.8.102, encoding A1: | 1536 // MOV (immediate) - ARM section A8.8.102, encoding A1: |
1442 // mov{S}<c> <Rd>, #<RotatedImm8> | 1537 // mov{S}<c> <Rd>, #<RotatedImm8> |
1443 // | 1538 // |
1444 // cccc0011101s0000ddddiiiiiiiiiiii where cccc=Cond, s=SetFlags, dddd=Rd, | 1539 // cccc0011101s0000ddddiiiiiiiiiiii where cccc=Cond, s=SetFlags, dddd=Rd, |
1445 // and iiiiiiiiiiii=RotatedImm8=Src. Note: We don't use movs in this | 1540 // and iiiiiiiiiiii=RotatedImm8=Src. Note: We don't use movs in this |
1446 // assembler. | 1541 // assembler. |
1447 constexpr const char *MovName = "mov"; | 1542 constexpr const char *MovName = "mov"; |
1448 IValueT Rd = encodeRegister(OpRd, "Rd", MovName); | 1543 IValueT Rd = encodeGPRegister(OpRd, "Rd", MovName); |
1449 constexpr bool SetFlags = false; | 1544 constexpr bool SetFlags = false; |
1450 constexpr IValueT Rn = 0; | 1545 constexpr IValueT Rn = 0; |
1451 constexpr IValueT MovOpcode = B3 | B2 | B0; // 1101. | 1546 constexpr IValueT MovOpcode = B3 | B2 | B0; // 1101. |
1452 emitType01(Cond, MovOpcode, Rd, Rn, OpSrc, SetFlags, RdIsPcAndSetFlags, | 1547 emitType01(Cond, MovOpcode, Rd, Rn, OpSrc, SetFlags, RdIsPcAndSetFlags, |
1453 MovName); | 1548 MovName); |
1454 } | 1549 } |
1455 | 1550 |
1456 void AssemblerARM32::emitMovwt(CondARM32::Cond Cond, bool IsMovW, | 1551 void AssemblerARM32::emitMovwt(CondARM32::Cond Cond, bool IsMovW, |
1457 const Operand *OpRd, const Operand *OpSrc, | 1552 const Operand *OpRd, const Operand *OpSrc, |
1458 const char *MovName) { | 1553 const char *MovName) { |
1459 IValueT Opcode = B25 | B24 | (IsMovW ? 0 : B22); | 1554 IValueT Opcode = B25 | B24 | (IsMovW ? 0 : B22); |
1460 IValueT Rd = encodeRegister(OpRd, "Rd", MovName); | 1555 IValueT Rd = encodeGPRegister(OpRd, "Rd", MovName); |
1461 IValueT Imm16; | 1556 IValueT Imm16; |
1462 if (const auto *Src = llvm::dyn_cast<ConstantRelocatable>(OpSrc)) { | 1557 if (const auto *Src = llvm::dyn_cast<ConstantRelocatable>(OpSrc)) { |
1463 emitFixup(createMoveFixup(IsMovW, Src)); | 1558 emitFixup(createMoveFixup(IsMovW, Src)); |
1464 // Use 0 for the lower 16 bits of the relocatable, and add a fixup to | 1559 // Use 0 for the lower 16 bits of the relocatable, and add a fixup to |
1465 // install the correct bits. | 1560 // install the correct bits. |
1466 Imm16 = 0; | 1561 Imm16 = 0; |
1467 } else if (encodeOperand(OpSrc, Imm16) != EncodedAsConstI32) { | 1562 } else if (encodeOperand(OpSrc, Imm16, WantGPRegs) != EncodedAsConstI32) { |
1468 llvm::report_fatal_error(std::string(MovName) + ": Not i32 constant"); | 1563 llvm::report_fatal_error(std::string(MovName) + ": Not i32 constant"); |
1469 } | 1564 } |
1470 verifyCondDefined(Cond, MovName); | 1565 verifyCondDefined(Cond, MovName); |
1471 if (!Utils::IsAbsoluteUint(16, Imm16)) | 1566 if (!Utils::IsAbsoluteUint(16, Imm16)) |
1472 llvm::report_fatal_error(std::string(MovName) + ": Constant not i16"); | 1567 llvm::report_fatal_error(std::string(MovName) + ": Constant not i16"); |
1473 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 1568 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
1474 const IValueT Encoding = encodeCondition(Cond) << kConditionShift | Opcode | | 1569 const IValueT Encoding = encodeCondition(Cond) << kConditionShift | Opcode | |
1475 ((Imm16 >> 12) << 16) | Rd << kRdShift | | 1570 ((Imm16 >> 12) << 16) | Rd << kRdShift | |
1476 (Imm16 & 0xfff); | 1571 (Imm16 & 0xfff); |
1477 emitInst(Encoding); | 1572 emitInst(Encoding); |
(...skipping 30 matching lines...) Expand all Loading... | |
1508 // | 1603 // |
1509 // cccc0011111s0000ddddiiiiiiiiiiii where cccc=Cond, s=SetFlags=0, dddd=Rd, | 1604 // cccc0011111s0000ddddiiiiiiiiiiii where cccc=Cond, s=SetFlags=0, dddd=Rd, |
1510 // and iiiiiiiiiiii=const | 1605 // and iiiiiiiiiiii=const |
1511 // | 1606 // |
1512 // MVN (register) - ARM section A8.8.116, encoding A1: | 1607 // MVN (register) - ARM section A8.8.116, encoding A1: |
1513 // mvn{s}<c> <Rd>, <Rm>{, <shift> | 1608 // mvn{s}<c> <Rd>, <Rm>{, <shift> |
1514 // | 1609 // |
1515 // cccc0001111s0000ddddiiiiitt0mmmm where cccc=Cond, s=SetFlags=0, dddd=Rd, | 1610 // cccc0001111s0000ddddiiiiitt0mmmm where cccc=Cond, s=SetFlags=0, dddd=Rd, |
1516 // mmmm=Rm, iiii defines shift constant, and tt=ShiftKind. | 1611 // mmmm=Rm, iiii defines shift constant, and tt=ShiftKind. |
1517 constexpr const char *MvnName = "mvn"; | 1612 constexpr const char *MvnName = "mvn"; |
1518 IValueT Rd = encodeRegister(OpRd, "Rd", MvnName); | 1613 IValueT Rd = encodeGPRegister(OpRd, "Rd", MvnName); |
1519 constexpr IValueT MvnOpcode = B3 | B2 | B1 | B0; // i.e. 1111 | 1614 constexpr IValueT MvnOpcode = B3 | B2 | B1 | B0; // i.e. 1111 |
1520 constexpr IValueT Rn = 0; | 1615 constexpr IValueT Rn = 0; |
1521 constexpr bool SetFlags = false; | 1616 constexpr bool SetFlags = false; |
1522 emitType01(Cond, MvnOpcode, Rd, Rn, OpSrc, SetFlags, RdIsPcAndSetFlags, | 1617 emitType01(Cond, MvnOpcode, Rd, Rn, OpSrc, SetFlags, RdIsPcAndSetFlags, |
1523 MvnName); | 1618 MvnName); |
1524 } | 1619 } |
1525 | 1620 |
1526 void AssemblerARM32::nop() { | 1621 void AssemblerARM32::nop() { |
1527 // NOP - Section A8.8.119, encoding A1: | 1622 // NOP - Section A8.8.119, encoding A1: |
1528 // nop<c> | 1623 // nop<c> |
(...skipping 27 matching lines...) Expand all Loading... | |
1556 } | 1651 } |
1557 | 1652 |
1558 void AssemblerARM32::sdiv(const Operand *OpRd, const Operand *OpRn, | 1653 void AssemblerARM32::sdiv(const Operand *OpRd, const Operand *OpRn, |
1559 const Operand *OpSrc1, CondARM32::Cond Cond) { | 1654 const Operand *OpSrc1, CondARM32::Cond Cond) { |
1560 // SDIV - ARM section A8.8.165, encoding A1. | 1655 // SDIV - ARM section A8.8.165, encoding A1. |
1561 // sdiv<c> <Rd>, <Rn>, <Rm> | 1656 // sdiv<c> <Rd>, <Rn>, <Rm> |
1562 // | 1657 // |
1563 // cccc01110001dddd1111mmmm0001nnnn where cccc=Cond, dddd=Rd, nnnn=Rn, and | 1658 // cccc01110001dddd1111mmmm0001nnnn where cccc=Cond, dddd=Rd, nnnn=Rn, and |
1564 // mmmm=Rm. | 1659 // mmmm=Rm. |
1565 constexpr const char *SdivName = "sdiv"; | 1660 constexpr const char *SdivName = "sdiv"; |
1566 IValueT Rd = encodeRegister(OpRd, "Rd", SdivName); | 1661 IValueT Rd = encodeGPRegister(OpRd, "Rd", SdivName); |
1567 IValueT Rn = encodeRegister(OpRn, "Rn", SdivName); | 1662 IValueT Rn = encodeGPRegister(OpRn, "Rn", SdivName); |
1568 IValueT Rm = encodeRegister(OpSrc1, "Rm", SdivName); | 1663 IValueT Rm = encodeGPRegister(OpSrc1, "Rm", SdivName); |
1569 verifyRegNotPc(Rd, "Rd", SdivName); | 1664 verifyRegNotPc(Rd, "Rd", SdivName); |
1570 verifyRegNotPc(Rn, "Rn", SdivName); | 1665 verifyRegNotPc(Rn, "Rn", SdivName); |
1571 verifyRegNotPc(Rm, "Rm", SdivName); | 1666 verifyRegNotPc(Rm, "Rm", SdivName); |
1572 // Assembler registers rd, rn, rm are encoded as rn, rm, rs. | 1667 // Assembler registers rd, rn, rm are encoded as rn, rm, rs. |
1573 constexpr IValueT SdivOpcode = 0; | 1668 constexpr IValueT SdivOpcode = 0; |
1574 emitDivOp(Cond, SdivOpcode, Rd, Rn, Rm, SdivName); | 1669 emitDivOp(Cond, SdivOpcode, Rd, Rn, Rm, SdivName); |
1575 } | 1670 } |
1576 | 1671 |
1577 void AssemblerARM32::str(const Operand *OpRt, const Operand *OpAddress, | 1672 void AssemblerARM32::str(const Operand *OpRt, const Operand *OpAddress, |
1578 CondARM32::Cond Cond, const TargetInfo &TInfo) { | 1673 CondARM32::Cond Cond, const TargetInfo &TInfo) { |
1579 constexpr const char *StrName = "str"; | 1674 constexpr const char *StrName = "str"; |
1580 constexpr bool IsLoad = false; | 1675 constexpr bool IsLoad = false; |
1581 IValueT Rt = encodeRegister(OpRt, "Rt", StrName); | 1676 IValueT Rt = encodeGPRegister(OpRt, "Rt", StrName); |
1582 const Type Ty = OpRt->getType(); | 1677 const Type Ty = OpRt->getType(); |
1583 switch (Ty) { | 1678 switch (Ty) { |
1584 case IceType_i64: | 1679 case IceType_i64: |
1585 // STRD is not implemented because target lowering handles i64 and double by | 1680 // STRD is not implemented because target lowering handles i64 and double by |
1586 // using two (32-bit) store instructions. Note: Intentionally drop to | 1681 // using two (32-bit) store instructions. Note: Intentionally drop to |
1587 // default case. | 1682 // default case. |
1588 llvm::report_fatal_error(std::string(StrName) + ": Type " + typeString(Ty) + | 1683 llvm::report_fatal_error(std::string(StrName) + ": Type " + typeString(Ty) + |
1589 " not implemented"); | 1684 " not implemented"); |
1590 default: | 1685 default: |
1591 llvm::report_fatal_error(std::string(StrName) + ": Type " + typeString(Ty) + | 1686 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 | 1750 // cccc00011000nnnndddd11111001tttt where cccc=Cond, dddd=Rd, tttt=Rt, and |
1656 // nnnn=Rn. | 1751 // nnnn=Rn. |
1657 // | 1752 // |
1658 // STREXD - ARM section A8.8.214, encoding A1: | 1753 // STREXD - ARM section A8.8.214, encoding A1: |
1659 // strexd<c> <Rd>, <Rt>, [<Rn>] | 1754 // strexd<c> <Rd>, <Rt>, [<Rn>] |
1660 // | 1755 // |
1661 // cccc00011010nnnndddd11111001tttt where cccc=Cond, dddd=Rd, tttt=Rt, and | 1756 // cccc00011010nnnndddd11111001tttt where cccc=Cond, dddd=Rd, tttt=Rt, and |
1662 // nnnn=Rn. | 1757 // nnnn=Rn. |
1663 constexpr const char *StrexName = "strex"; | 1758 constexpr const char *StrexName = "strex"; |
1664 // Note: Rt uses Rm shift in encoding. | 1759 // Note: Rt uses Rm shift in encoding. |
1665 IValueT Rt = encodeRegister(OpRt, "Rt", StrexName); | 1760 IValueT Rt = encodeGPRegister(OpRt, "Rt", StrexName); |
1666 const Type Ty = OpRt->getType(); | 1761 const Type Ty = OpRt->getType(); |
1667 constexpr bool IsLoad = true; | 1762 constexpr bool IsLoad = true; |
1668 emitMemExOp(Cond, Ty, !IsLoad, OpRd, Rt, OpAddress, TInfo, StrexName); | 1763 emitMemExOp(Cond, Ty, !IsLoad, OpRd, Rt, OpAddress, TInfo, StrexName); |
1669 } | 1764 } |
1670 | 1765 |
1671 void AssemblerARM32::orr(const Operand *OpRd, const Operand *OpRn, | 1766 void AssemblerARM32::orr(const Operand *OpRd, const Operand *OpRn, |
1672 const Operand *OpSrc1, bool SetFlags, | 1767 const Operand *OpSrc1, bool SetFlags, |
1673 CondARM32::Cond Cond) { | 1768 CondARM32::Cond Cond) { |
1674 // ORR (register) - ARM Section A8.8.123, encoding A1: | 1769 // ORR (register) - ARM Section A8.8.123, encoding A1: |
1675 // orr{s}<c> <Rd>, <Rn>, <Rm> | 1770 // orr{s}<c> <Rd>, <Rn>, <Rm> |
(...skipping 11 matching lines...) Expand all Loading... | |
1687 emitType01(Cond, OrrOpcode, OpRd, OpRn, OpSrc1, SetFlags, RdIsPcAndSetFlags, | 1782 emitType01(Cond, OrrOpcode, OpRd, OpRn, OpSrc1, SetFlags, RdIsPcAndSetFlags, |
1688 OrrName); | 1783 OrrName); |
1689 } | 1784 } |
1690 | 1785 |
1691 void AssemblerARM32::pop(const Operand *OpRt, CondARM32::Cond Cond) { | 1786 void AssemblerARM32::pop(const Operand *OpRt, CondARM32::Cond Cond) { |
1692 // POP - ARM section A8.8.132, encoding A2: | 1787 // POP - ARM section A8.8.132, encoding A2: |
1693 // pop<c> {Rt} | 1788 // pop<c> {Rt} |
1694 // | 1789 // |
1695 // cccc010010011101dddd000000000100 where dddd=Rt and cccc=Cond. | 1790 // cccc010010011101dddd000000000100 where dddd=Rt and cccc=Cond. |
1696 constexpr const char *Pop = "pop"; | 1791 constexpr const char *Pop = "pop"; |
1697 IValueT Rt = encodeRegister(OpRt, "Rt", Pop); | 1792 IValueT Rt = encodeGPRegister(OpRt, "Rt", Pop); |
1698 verifyRegsNotEq(Rt, "Rt", RegARM32::Encoded_Reg_sp, "sp", Pop); | 1793 verifyRegsNotEq(Rt, "Rt", RegARM32::Encoded_Reg_sp, "sp", Pop); |
1699 // Same as load instruction. | 1794 // Same as load instruction. |
1700 constexpr bool IsLoad = true; | 1795 constexpr bool IsLoad = true; |
1701 constexpr bool IsByte = false; | 1796 constexpr bool IsByte = false; |
1702 IValueT Address = encodeImmRegOffset(RegARM32::Encoded_Reg_sp, kWordSize, | 1797 IValueT Address = encodeImmRegOffset(RegARM32::Encoded_Reg_sp, kWordSize, |
1703 OperandARM32Mem::PostIndex); | 1798 OperandARM32Mem::PostIndex); |
1704 emitMemOp(Cond, kInstTypeMemImmediate, IsLoad, IsByte, Rt, Address, Pop); | 1799 emitMemOp(Cond, kInstTypeMemImmediate, IsLoad, IsByte, Rt, Address, Pop); |
1705 } | 1800 } |
1706 | 1801 |
1707 void AssemblerARM32::popList(const IValueT Registers, CondARM32::Cond Cond) { | 1802 void AssemblerARM32::popList(const IValueT Registers, CondARM32::Cond Cond) { |
1708 // POP - ARM section A8.*.131, encoding A1: | 1803 // POP - ARM section A8.*.131, encoding A1: |
1709 // pop<c> <registers> | 1804 // pop<c> <registers> |
1710 // | 1805 // |
1711 // cccc100010111101rrrrrrrrrrrrrrrr where cccc=Cond and | 1806 // cccc100010111101rrrrrrrrrrrrrrrr where cccc=Cond and |
1712 // rrrrrrrrrrrrrrrr=Registers (one bit for each GP register). | 1807 // rrrrrrrrrrrrrrrr=Registers (one bit for each GP register). |
1713 constexpr const char *PopListName = "pop {}"; | 1808 constexpr const char *PopListName = "pop {}"; |
1714 constexpr bool IsLoad = true; | 1809 constexpr bool IsLoad = true; |
1715 emitMultiMemOp(Cond, IA_W, IsLoad, RegARM32::Encoded_Reg_sp, Registers, | 1810 emitMultiMemOp(Cond, IA_W, IsLoad, RegARM32::Encoded_Reg_sp, Registers, |
1716 PopListName); | 1811 PopListName); |
1717 } | 1812 } |
1718 | 1813 |
1719 void AssemblerARM32::push(const Operand *OpRt, CondARM32::Cond Cond) { | 1814 void AssemblerARM32::push(const Operand *OpRt, CondARM32::Cond Cond) { |
1720 // PUSH - ARM section A8.8.133, encoding A2: | 1815 // PUSH - ARM section A8.8.133, encoding A2: |
1721 // push<c> {Rt} | 1816 // push<c> {Rt} |
1722 // | 1817 // |
1723 // cccc010100101101dddd000000000100 where dddd=Rt and cccc=Cond. | 1818 // cccc010100101101dddd000000000100 where dddd=Rt and cccc=Cond. |
1724 constexpr const char *Push = "push"; | 1819 constexpr const char *Push = "push"; |
1725 IValueT Rt = encodeRegister(OpRt, "Rt", Push); | 1820 IValueT Rt = encodeGPRegister(OpRt, "Rt", Push); |
1726 verifyRegsNotEq(Rt, "Rt", RegARM32::Encoded_Reg_sp, "sp", Push); | 1821 verifyRegsNotEq(Rt, "Rt", RegARM32::Encoded_Reg_sp, "sp", Push); |
1727 // Same as store instruction. | 1822 // Same as store instruction. |
1728 constexpr bool isLoad = false; | 1823 constexpr bool isLoad = false; |
1729 constexpr bool isByte = false; | 1824 constexpr bool isByte = false; |
1730 IValueT Address = encodeImmRegOffset(RegARM32::Encoded_Reg_sp, -kWordSize, | 1825 IValueT Address = encodeImmRegOffset(RegARM32::Encoded_Reg_sp, -kWordSize, |
1731 OperandARM32Mem::PreIndex); | 1826 OperandARM32Mem::PreIndex); |
1732 emitMemOp(Cond, kInstTypeMemImmediate, isLoad, isByte, Rt, Address, Push); | 1827 emitMemOp(Cond, kInstTypeMemImmediate, isLoad, isByte, Rt, Address, Push); |
1733 } | 1828 } |
1734 | 1829 |
1735 void AssemblerARM32::pushList(const IValueT Registers, CondARM32::Cond Cond) { | 1830 void AssemblerARM32::pushList(const IValueT Registers, CondARM32::Cond Cond) { |
(...skipping 10 matching lines...) Expand all Loading... | |
1746 | 1841 |
1747 void AssemblerARM32::mla(const Operand *OpRd, const Operand *OpRn, | 1842 void AssemblerARM32::mla(const Operand *OpRd, const Operand *OpRn, |
1748 const Operand *OpRm, const Operand *OpRa, | 1843 const Operand *OpRm, const Operand *OpRa, |
1749 CondARM32::Cond Cond) { | 1844 CondARM32::Cond Cond) { |
1750 // MLA - ARM section A8.8.114, encoding A1. | 1845 // MLA - ARM section A8.8.114, encoding A1. |
1751 // mla{s}<c> <Rd>, <Rn>, <Rm>, <Ra> | 1846 // mla{s}<c> <Rd>, <Rn>, <Rm>, <Ra> |
1752 // | 1847 // |
1753 // cccc0000001sddddaaaammmm1001nnnn where cccc=Cond, s=SetFlags, dddd=Rd, | 1848 // cccc0000001sddddaaaammmm1001nnnn where cccc=Cond, s=SetFlags, dddd=Rd, |
1754 // aaaa=Ra, mmmm=Rm, and nnnn=Rn. | 1849 // aaaa=Ra, mmmm=Rm, and nnnn=Rn. |
1755 constexpr const char *MlaName = "mla"; | 1850 constexpr const char *MlaName = "mla"; |
1756 IValueT Rd = encodeRegister(OpRd, "Rd", MlaName); | 1851 IValueT Rd = encodeGPRegister(OpRd, "Rd", MlaName); |
1757 IValueT Rn = encodeRegister(OpRn, "Rn", MlaName); | 1852 IValueT Rn = encodeGPRegister(OpRn, "Rn", MlaName); |
1758 IValueT Rm = encodeRegister(OpRm, "Rm", MlaName); | 1853 IValueT Rm = encodeGPRegister(OpRm, "Rm", MlaName); |
1759 IValueT Ra = encodeRegister(OpRa, "Ra", MlaName); | 1854 IValueT Ra = encodeGPRegister(OpRa, "Ra", MlaName); |
1760 verifyRegNotPc(Rd, "Rd", MlaName); | 1855 verifyRegNotPc(Rd, "Rd", MlaName); |
1761 verifyRegNotPc(Rn, "Rn", MlaName); | 1856 verifyRegNotPc(Rn, "Rn", MlaName); |
1762 verifyRegNotPc(Rm, "Rm", MlaName); | 1857 verifyRegNotPc(Rm, "Rm", MlaName); |
1763 verifyRegNotPc(Ra, "Ra", MlaName); | 1858 verifyRegNotPc(Ra, "Ra", MlaName); |
1764 constexpr IValueT MlaOpcode = B21; | 1859 constexpr IValueT MlaOpcode = B21; |
1765 constexpr bool SetFlags = true; | 1860 constexpr bool SetFlags = true; |
1766 // Assembler registers rd, rn, rm, ra are encoded as rn, rm, rs, rd. | 1861 // Assembler registers rd, rn, rm, ra are encoded as rn, rm, rs, rd. |
1767 emitMulOp(Cond, MlaOpcode, Ra, Rd, Rn, Rm, !SetFlags, MlaName); | 1862 emitMulOp(Cond, MlaOpcode, Ra, Rd, Rn, Rm, !SetFlags, MlaName); |
1768 } | 1863 } |
1769 | 1864 |
1770 void AssemblerARM32::mls(const Operand *OpRd, const Operand *OpRn, | 1865 void AssemblerARM32::mls(const Operand *OpRd, const Operand *OpRn, |
1771 const Operand *OpRm, const Operand *OpRa, | 1866 const Operand *OpRm, const Operand *OpRa, |
1772 CondARM32::Cond Cond) { | 1867 CondARM32::Cond Cond) { |
1773 constexpr const char *MlsName = "mls"; | 1868 constexpr const char *MlsName = "mls"; |
1774 IValueT Rd = encodeRegister(OpRd, "Rd", MlsName); | 1869 IValueT Rd = encodeGPRegister(OpRd, "Rd", MlsName); |
1775 IValueT Rn = encodeRegister(OpRn, "Rn", MlsName); | 1870 IValueT Rn = encodeGPRegister(OpRn, "Rn", MlsName); |
1776 IValueT Rm = encodeRegister(OpRm, "Rm", MlsName); | 1871 IValueT Rm = encodeGPRegister(OpRm, "Rm", MlsName); |
1777 IValueT Ra = encodeRegister(OpRa, "Ra", MlsName); | 1872 IValueT Ra = encodeGPRegister(OpRa, "Ra", MlsName); |
1778 verifyRegNotPc(Rd, "Rd", MlsName); | 1873 verifyRegNotPc(Rd, "Rd", MlsName); |
1779 verifyRegNotPc(Rn, "Rn", MlsName); | 1874 verifyRegNotPc(Rn, "Rn", MlsName); |
1780 verifyRegNotPc(Rm, "Rm", MlsName); | 1875 verifyRegNotPc(Rm, "Rm", MlsName); |
1781 verifyRegNotPc(Ra, "Ra", MlsName); | 1876 verifyRegNotPc(Ra, "Ra", MlsName); |
1782 constexpr IValueT MlsOpcode = B22 | B21; | 1877 constexpr IValueT MlsOpcode = B22 | B21; |
1783 constexpr bool SetFlags = true; | 1878 constexpr bool SetFlags = true; |
1784 // Assembler registers rd, rn, rm, ra are encoded as rn, rm, rs, rd. | 1879 // Assembler registers rd, rn, rm, ra are encoded as rn, rm, rs, rd. |
1785 emitMulOp(Cond, MlsOpcode, Ra, Rd, Rn, Rm, !SetFlags, MlsName); | 1880 emitMulOp(Cond, MlsOpcode, Ra, Rd, Rn, Rm, !SetFlags, MlsName); |
1786 } | 1881 } |
1787 | 1882 |
1788 void AssemblerARM32::mul(const Operand *OpRd, const Operand *OpRn, | 1883 void AssemblerARM32::mul(const Operand *OpRd, const Operand *OpRn, |
1789 const Operand *OpSrc1, bool SetFlags, | 1884 const Operand *OpSrc1, bool SetFlags, |
1790 CondARM32::Cond Cond) { | 1885 CondARM32::Cond Cond) { |
1791 // MUL - ARM section A8.8.114, encoding A1. | 1886 // MUL - ARM section A8.8.114, encoding A1. |
1792 // mul{s}<c> <Rd>, <Rn>, <Rm> | 1887 // mul{s}<c> <Rd>, <Rn>, <Rm> |
1793 // | 1888 // |
1794 // cccc0000000sdddd0000mmmm1001nnnn where cccc=Cond, dddd=Rd, nnnn=Rn, | 1889 // cccc0000000sdddd0000mmmm1001nnnn where cccc=Cond, dddd=Rd, nnnn=Rn, |
1795 // mmmm=Rm, and s=SetFlags. | 1890 // mmmm=Rm, and s=SetFlags. |
1796 constexpr const char *MulName = "mul"; | 1891 constexpr const char *MulName = "mul"; |
1797 IValueT Rd = encodeRegister(OpRd, "Rd", MulName); | 1892 IValueT Rd = encodeGPRegister(OpRd, "Rd", MulName); |
1798 IValueT Rn = encodeRegister(OpRn, "Rn", MulName); | 1893 IValueT Rn = encodeGPRegister(OpRn, "Rn", MulName); |
1799 IValueT Rm = encodeRegister(OpSrc1, "Rm", MulName); | 1894 IValueT Rm = encodeGPRegister(OpSrc1, "Rm", MulName); |
1800 verifyRegNotPc(Rd, "Rd", MulName); | 1895 verifyRegNotPc(Rd, "Rd", MulName); |
1801 verifyRegNotPc(Rn, "Rn", MulName); | 1896 verifyRegNotPc(Rn, "Rn", MulName); |
1802 verifyRegNotPc(Rm, "Rm", MulName); | 1897 verifyRegNotPc(Rm, "Rm", MulName); |
1803 // Assembler registers rd, rn, rm are encoded as rn, rm, rs. | 1898 // Assembler registers rd, rn, rm are encoded as rn, rm, rs. |
1804 constexpr IValueT MulOpcode = 0; | 1899 constexpr IValueT MulOpcode = 0; |
1805 emitMulOp(Cond, MulOpcode, RegARM32::Encoded_Reg_r0, Rd, Rn, Rm, SetFlags, | 1900 emitMulOp(Cond, MulOpcode, RegARM32::Encoded_Reg_r0, Rd, Rn, Rm, SetFlags, |
1806 MulName); | 1901 MulName); |
1807 } | 1902 } |
1808 | 1903 |
1809 void AssemblerARM32::emitRdRm(CondARM32::Cond Cond, IValueT Opcode, | 1904 void AssemblerARM32::emitRdRm(CondARM32::Cond Cond, IValueT Opcode, |
1810 const Operand *OpRd, const Operand *OpRm, | 1905 const Operand *OpRd, const Operand *OpRm, |
1811 const char *InstName) { | 1906 const char *InstName) { |
1812 IValueT Rd = encodeRegister(OpRd, "Rd", InstName); | 1907 IValueT Rd = encodeGPRegister(OpRd, "Rd", InstName); |
1813 IValueT Rm = encodeRegister(OpRm, "Rm", InstName); | 1908 IValueT Rm = encodeGPRegister(OpRm, "Rm", InstName); |
1814 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 1909 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
1815 IValueT Encoding = | 1910 IValueT Encoding = |
1816 (Cond << kConditionShift) | Opcode | (Rd << kRdShift) | (Rm << kRmShift); | 1911 (Cond << kConditionShift) | Opcode | (Rd << kRdShift) | (Rm << kRmShift); |
1817 emitInst(Encoding); | 1912 emitInst(Encoding); |
1818 } | 1913 } |
1819 | 1914 |
1820 void AssemblerARM32::rbit(const Operand *OpRd, const Operand *OpRm, | 1915 void AssemblerARM32::rbit(const Operand *OpRd, const Operand *OpRm, |
1821 CondARM32::Cond Cond) { | 1916 CondARM32::Cond Cond) { |
1822 // RBIT - ARM section A8.8.144, encoding A1: | 1917 // RBIT - ARM section A8.8.144, encoding A1: |
1823 // rbit<c> <Rd>, <Rm> | 1918 // rbit<c> <Rd>, <Rm> |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1958 } | 2053 } |
1959 | 2054 |
1960 void AssemblerARM32::udiv(const Operand *OpRd, const Operand *OpRn, | 2055 void AssemblerARM32::udiv(const Operand *OpRd, const Operand *OpRn, |
1961 const Operand *OpSrc1, CondARM32::Cond Cond) { | 2056 const Operand *OpSrc1, CondARM32::Cond Cond) { |
1962 // UDIV - ARM section A8.8.248, encoding A1. | 2057 // UDIV - ARM section A8.8.248, encoding A1. |
1963 // udiv<c> <Rd>, <Rn>, <Rm> | 2058 // udiv<c> <Rd>, <Rn>, <Rm> |
1964 // | 2059 // |
1965 // cccc01110011dddd1111mmmm0001nnnn where cccc=Cond, dddd=Rd, nnnn=Rn, and | 2060 // cccc01110011dddd1111mmmm0001nnnn where cccc=Cond, dddd=Rd, nnnn=Rn, and |
1966 // mmmm=Rm. | 2061 // mmmm=Rm. |
1967 constexpr const char *UdivName = "udiv"; | 2062 constexpr const char *UdivName = "udiv"; |
1968 IValueT Rd = encodeRegister(OpRd, "Rd", UdivName); | 2063 IValueT Rd = encodeGPRegister(OpRd, "Rd", UdivName); |
1969 IValueT Rn = encodeRegister(OpRn, "Rn", UdivName); | 2064 IValueT Rn = encodeGPRegister(OpRn, "Rn", UdivName); |
1970 IValueT Rm = encodeRegister(OpSrc1, "Rm", UdivName); | 2065 IValueT Rm = encodeGPRegister(OpSrc1, "Rm", UdivName); |
1971 verifyRegNotPc(Rd, "Rd", UdivName); | 2066 verifyRegNotPc(Rd, "Rd", UdivName); |
1972 verifyRegNotPc(Rn, "Rn", UdivName); | 2067 verifyRegNotPc(Rn, "Rn", UdivName); |
1973 verifyRegNotPc(Rm, "Rm", UdivName); | 2068 verifyRegNotPc(Rm, "Rm", UdivName); |
1974 // Assembler registers rd, rn, rm are encoded as rn, rm, rs. | 2069 // Assembler registers rd, rn, rm are encoded as rn, rm, rs. |
1975 constexpr IValueT UdivOpcode = B21; | 2070 constexpr IValueT UdivOpcode = B21; |
1976 emitDivOp(Cond, UdivOpcode, Rd, Rn, Rm, UdivName); | 2071 emitDivOp(Cond, UdivOpcode, Rd, Rn, Rm, UdivName); |
1977 } | 2072 } |
1978 | 2073 |
1979 void AssemblerARM32::umull(const Operand *OpRdLo, const Operand *OpRdHi, | 2074 void AssemblerARM32::umull(const Operand *OpRdLo, const Operand *OpRdHi, |
1980 const Operand *OpRn, const Operand *OpRm, | 2075 const Operand *OpRn, const Operand *OpRm, |
1981 CondARM32::Cond Cond) { | 2076 CondARM32::Cond Cond) { |
1982 // UMULL - ARM section A8.8.257, encoding A1: | 2077 // UMULL - ARM section A8.8.257, encoding A1: |
1983 // umull<c> <RdLo>, <RdHi>, <Rn>, <Rm> | 2078 // umull<c> <RdLo>, <RdHi>, <Rn>, <Rm> |
1984 // | 2079 // |
1985 // cccc0000100shhhhllllmmmm1001nnnn where hhhh=RdHi, llll=RdLo, nnnn=Rn, | 2080 // cccc0000100shhhhllllmmmm1001nnnn where hhhh=RdHi, llll=RdLo, nnnn=Rn, |
1986 // mmmm=Rm, and s=SetFlags | 2081 // mmmm=Rm, and s=SetFlags |
1987 constexpr const char *UmullName = "umull"; | 2082 constexpr const char *UmullName = "umull"; |
1988 IValueT RdLo = encodeRegister(OpRdLo, "RdLo", UmullName); | 2083 IValueT RdLo = encodeGPRegister(OpRdLo, "RdLo", UmullName); |
1989 IValueT RdHi = encodeRegister(OpRdHi, "RdHi", UmullName); | 2084 IValueT RdHi = encodeGPRegister(OpRdHi, "RdHi", UmullName); |
1990 IValueT Rn = encodeRegister(OpRn, "Rn", UmullName); | 2085 IValueT Rn = encodeGPRegister(OpRn, "Rn", UmullName); |
1991 IValueT Rm = encodeRegister(OpRm, "Rm", UmullName); | 2086 IValueT Rm = encodeGPRegister(OpRm, "Rm", UmullName); |
1992 verifyRegNotPc(RdLo, "RdLo", UmullName); | 2087 verifyRegNotPc(RdLo, "RdLo", UmullName); |
1993 verifyRegNotPc(RdHi, "RdHi", UmullName); | 2088 verifyRegNotPc(RdHi, "RdHi", UmullName); |
1994 verifyRegNotPc(Rn, "Rn", UmullName); | 2089 verifyRegNotPc(Rn, "Rn", UmullName); |
1995 verifyRegNotPc(Rm, "Rm", UmullName); | 2090 verifyRegNotPc(Rm, "Rm", UmullName); |
1996 verifyRegsNotEq(RdHi, "RdHi", RdLo, "RdLo", UmullName); | 2091 verifyRegsNotEq(RdHi, "RdHi", RdLo, "RdLo", UmullName); |
1997 constexpr IValueT UmullOpcode = B23; | 2092 constexpr IValueT UmullOpcode = B23; |
1998 constexpr bool SetFlags = false; | 2093 constexpr bool SetFlags = false; |
1999 emitMulOp(Cond, UmullOpcode, RdLo, RdHi, Rn, Rm, SetFlags, UmullName); | 2094 emitMulOp(Cond, UmullOpcode, RdLo, RdHi, Rn, Rm, SetFlags, UmullName); |
2000 } | 2095 } |
2001 | 2096 |
2002 void AssemblerARM32::uxt(const Operand *OpRd, const Operand *OpSrc0, | 2097 void AssemblerARM32::uxt(const Operand *OpRd, const Operand *OpSrc0, |
2003 CondARM32::Cond Cond) { | 2098 CondARM32::Cond Cond) { |
2004 constexpr const char *UxtName = "uxt"; | 2099 constexpr const char *UxtName = "uxt"; |
2005 constexpr IValueT UxtOpcode = B26 | B25 | B23 | B22 | B21; | 2100 constexpr IValueT UxtOpcode = B26 | B25 | B23 | B22 | B21; |
2006 emitSignExtend(Cond, UxtOpcode, OpRd, OpSrc0, UxtName); | 2101 emitSignExtend(Cond, UxtOpcode, OpRd, OpSrc0, UxtName); |
2007 } | 2102 } |
2008 | 2103 |
2104 void AssemblerARM32::vadds(const Operand *OpSd, const Operand *OpSn, | |
2105 const Operand *OpSm, CondARM32::Cond Cond) { | |
2106 // VADD (floating-point) - ARM section A8.8.283, encoding A2: | |
2107 // vadd<c>.f32 <Sd>, <Sn>, <Sm> | |
2108 // | |
2109 // cccc11100D11nnnndddd101sN0M0mmmm where cccc=Cond, s=0, ddddD=Rd, nnnnN=Rn, | |
2110 // and mmmmM=Rm. | |
2111 constexpr const char *Vadds = "vadds"; | |
2112 IValueT Sd = encodeSRegister(OpSd, "Sd", Vadds); | |
2113 IValueT Sn = encodeSRegister(OpSn, "Sn", Vadds); | |
2114 IValueT Sm = encodeSRegister(OpSm, "Sm", Vadds); | |
2115 constexpr IValueT VaddsOpcode = B21 | B20; | |
2116 emitVFPsss(Cond, VaddsOpcode, Sd, Sn, Sm, Vadds); | |
2117 } | |
2118 | |
2119 void AssemblerARM32::vaddd(const Operand *OpDd, const Operand *OpDn, | |
2120 const Operand *OpDm, CondARM32::Cond Cond) { | |
2121 // VADD (floating-point) - ARM section A8.8.283, encoding A2: | |
2122 // vadd<c>.f64 <Dd>, <Dn>, <Dm> | |
2123 // | |
2124 // cccc11100D11nnnndddd101sN0M0mmmm where cccc=Cond, s=1, Ddddd=Rd, Nnnnn=Rn, | |
2125 // and Mmmmm=Rm. | |
2126 constexpr const char *Vaddd = "vaddd"; | |
2127 IValueT Dd = encodeDRegister(OpDd, "Dd", Vaddd); | |
2128 IValueT Dn = encodeDRegister(OpDn, "Dn", Vaddd); | |
2129 IValueT Dm = encodeDRegister(OpDm, "Dm", Vaddd); | |
2130 constexpr IValueT VadddOpcode = B21 | B20; | |
2131 emitVFPddd(Cond, VadddOpcode, Dd, Dn, Dm, Vaddd); | |
2132 } | |
2133 | |
2009 void AssemblerARM32::emitVStackOp(CondARM32::Cond Cond, IValueT Opcode, | 2134 void AssemblerARM32::emitVStackOp(CondARM32::Cond Cond, IValueT Opcode, |
2010 const Variable *OpBaseReg, | 2135 const Variable *OpBaseReg, |
2011 SizeT NumConsecRegs, const char *InstName) { | 2136 SizeT NumConsecRegs, const char *InstName) { |
2012 | 2137 |
2013 const IValueT BaseReg = getEncodedSRegNum(OpBaseReg); | 2138 const IValueT BaseReg = getEncodedSRegNum(OpBaseReg); |
2014 const IValueT DLastBit = mask(BaseReg, 0, 1); // Last bit of base register. | 2139 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. | 2140 const IValueT Rd = mask(BaseReg, 1, 4); // Top 4 bits of base register. |
2016 assert(0 < NumConsecRegs); | 2141 assert(0 < NumConsecRegs); |
2017 (void)VpushVpopMaxConsecRegs; | 2142 (void)VpushVpopMaxConsecRegs; |
2018 assert(NumConsecRegs <= VpushVpopMaxConsecRegs); | 2143 assert(NumConsecRegs <= VpushVpopMaxConsecRegs); |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2051 // cccc11010D101101dddd1010iiiiiiii where cccc=Cond, ddddD=BaseReg, and | 2176 // cccc11010D101101dddd1010iiiiiiii where cccc=Cond, ddddD=BaseReg, and |
2052 // iiiiiiii=NumConsecRegs. | 2177 // iiiiiiii=NumConsecRegs. |
2053 constexpr const char *VpushName = "vpush"; | 2178 constexpr const char *VpushName = "vpush"; |
2054 constexpr IValueT VpushOpcode = | 2179 constexpr IValueT VpushOpcode = |
2055 B27 | B26 | B24 | B21 | B19 | B18 | B16 | B11 | B9; | 2180 B27 | B26 | B24 | B21 | B19 | B18 | B16 | B11 | B9; |
2056 emitVStackOp(Cond, VpushOpcode, OpBaseReg, NumConsecRegs, VpushName); | 2181 emitVStackOp(Cond, VpushOpcode, OpBaseReg, NumConsecRegs, VpushName); |
2057 } | 2182 } |
2058 | 2183 |
2059 } // end of namespace ARM32 | 2184 } // end of namespace ARM32 |
2060 } // end of namespace Ice | 2185 } // end of namespace Ice |
OLD | NEW |