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