Chromium Code Reviews| 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 |