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