| 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 364 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 375 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 375 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 376 const IValueT Encoding = (encodeCondition(Cond) << kConditionShift) | | 376 const IValueT Encoding = (encodeCondition(Cond) << kConditionShift) | |
| 377 (Type << kTypeShift) | (Opcode << kOpcodeShift) | | 377 (Type << kTypeShift) | (Opcode << kOpcodeShift) | |
| 378 (encodeBool(SetCc) << kSShift) | (Rn << kRnShift) | | 378 (encodeBool(SetCc) << kSShift) | (Rn << kRnShift) | |
| 379 (Rd << kRdShift) | Imm12; | 379 (Rd << kRdShift) | Imm12; |
| 380 emitInst(Encoding); | 380 emitInst(Encoding); |
| 381 } | 381 } |
| 382 | 382 |
| 383 void AssemblerARM32::emitType01(IValueT Opcode, const Operand *OpRd, | 383 void AssemblerARM32::emitType01(IValueT Opcode, const Operand *OpRd, |
| 384 const Operand *OpRn, const Operand *OpSrc1, | 384 const Operand *OpRn, const Operand *OpSrc1, |
| 385 bool SetFlags, CondARM32::Cond Cond) { | 385 bool SetFlags, CondARM32::Cond Cond, |
| 386 Type01Checks RuleChecks) { |
| 386 IValueT Rd; | 387 IValueT Rd; |
| 387 if (decodeOperand(OpRd, Rd) != DecodedAsRegister) | 388 if (decodeOperand(OpRd, Rd) != DecodedAsRegister) |
| 388 return setNeedsTextFixup(); | 389 return setNeedsTextFixup(); |
| 389 IValueT Rn; | 390 IValueT Rn; |
| 390 if (decodeOperand(OpRn, Rn) != DecodedAsRegister) | 391 if (decodeOperand(OpRn, Rn) != DecodedAsRegister) |
| 391 return setNeedsTextFixup(); | 392 return setNeedsTextFixup(); |
| 393 emitType01(Opcode, Rd, Rn, OpSrc1, SetFlags, Cond, RuleChecks); |
| 394 } |
| 395 |
| 396 void AssemblerARM32::emitType01(IValueT Opcode, IValueT Rd, |
| 397 IValueT Rn, const Operand *OpSrc1, |
| 398 bool SetFlags, CondARM32::Cond Cond, |
| 399 Type01Checks RuleChecks) { |
| 400 switch (RuleChecks) { |
| 401 case NoChecks: |
| 402 break; |
| 403 case RdIsPcAndSetFlags: |
| 404 if (((Rd == RegARM32::Encoded_Reg_pc) && SetFlags)) |
| 405 // Conditions of rule violated. |
| 406 return setNeedsTextFixup(); |
| 407 break; |
| 408 } |
| 409 |
| 392 IValueT Src1Value; | 410 IValueT Src1Value; |
| 393 // TODO(kschimpf) Other possible decodings of add. | 411 // TODO(kschimpf) Other possible decodings of data operations. |
| 394 switch (decodeOperand(OpSrc1, Src1Value)) { | 412 switch (decodeOperand(OpSrc1, Src1Value)) { |
| 395 default: | 413 default: |
| 396 return setNeedsTextFixup(); | 414 return setNeedsTextFixup(); |
| 397 case DecodedAsRegister: { | 415 case DecodedAsRegister: { |
| 398 // XXX (register) | 416 // XXX (register) |
| 399 // xxx{s}<c> <Rd>, <Rn>, <Rm>{, <shiff>} | 417 // xxx{s}<c> <Rd>, <Rn>, <Rm>{, <shiff>} |
| 400 // | 418 // |
| 401 // cccc0000100snnnnddddiiiiitt0mmmm where cccc=Cond, dddd=Rd, nnnn=Rn, | 419 // cccc0000100snnnnddddiiiiitt0mmmm where cccc=Cond, dddd=Rd, nnnn=Rn, |
| 402 // mmmm=Rm, iiiii=Shift, tt=ShiftKind, and s=SetFlags. | 420 // mmmm=Rm, iiiii=Shift, tt=ShiftKind, and s=SetFlags. |
| 403 constexpr IValueT Imm5 = 0; | 421 constexpr IValueT Imm5 = 0; |
| 404 Src1Value = encodeShiftRotateImm5(Src1Value, OperandARM32::kNoShift, Imm5); | 422 Src1Value = encodeShiftRotateImm5(Src1Value, OperandARM32::kNoShift, Imm5); |
| 405 if (((Rd == RegARM32::Encoded_Reg_pc) && SetFlags)) | |
| 406 // Conditions of rule violated. | |
| 407 return setNeedsTextFixup(); | |
| 408 emitType01(Cond, kInstTypeDataRegister, Opcode, SetFlags, Rn, Rd, | 423 emitType01(Cond, kInstTypeDataRegister, Opcode, SetFlags, Rn, Rd, |
| 409 Src1Value); | 424 Src1Value); |
| 410 return; | 425 return; |
| 411 } | 426 } |
| 427 case DecodedAsConstI32: { |
| 428 // See if we can convert this to an XXX (immediate). |
| 429 IValueT RotateAmt; |
| 430 IValueT Imm8; |
| 431 if (!OperandARM32FlexImm::canHoldImm(Src1Value, &RotateAmt, &Imm8)) |
| 432 return setNeedsTextFixup(); |
| 433 Src1Value = encodeRotatedImm8(RotateAmt, Imm8); |
| 434 // Intentionally fall to next case! |
| 435 } |
| 412 case DecodedAsRotatedImm8: { | 436 case DecodedAsRotatedImm8: { |
| 413 // XXX (Immediate) | 437 // XXX (Immediate) |
| 414 // xxx{s}<c> <Rd>, <Rn>, #<RotatedImm8> | 438 // xxx{s}<c> <Rd>, <Rn>, #<RotatedImm8> |
| 415 // | 439 // |
| 416 // cccc0010100snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn, | 440 // cccc0010100snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn, |
| 417 // s=SetFlags and iiiiiiiiiiii=Src1Value defining RotatedImm8. | 441 // s=SetFlags and iiiiiiiiiiii=Src1Value defining RotatedImm8. |
| 418 if ((Rd == RegARM32::Encoded_Reg_pc && SetFlags)) | |
| 419 // Conditions of rule violated. | |
| 420 return setNeedsTextFixup(); | |
| 421 emitType01(Cond, kInstTypeDataImmediate, Opcode, SetFlags, Rn, Rd, | 442 emitType01(Cond, kInstTypeDataImmediate, Opcode, SetFlags, Rn, Rd, |
| 422 Src1Value); | 443 Src1Value); |
| 423 return; | 444 return; |
| 424 } | 445 } |
| 425 } | 446 } |
| 426 } | 447 } |
| 427 | 448 |
| 428 void AssemblerARM32::emitType05(CondARM32::Cond Cond, IOffsetT Offset, | 449 void AssemblerARM32::emitType05(CondARM32::Cond Cond, IOffsetT Offset, |
| 429 bool Link) { | 450 bool Link) { |
| 430 // cccc101liiiiiiiiiiiiiiiiiiiiiiii where cccc=Cond, l=Link, and | 451 // cccc101liiiiiiiiiiiiiiiiiiiiiiii where cccc=Cond, l=Link, and |
| (...skipping 15 matching lines...) Expand all Loading... |
| 446 emitType05(Cond, Dest, Link); | 467 emitType05(Cond, Dest, Link); |
| 447 return; | 468 return; |
| 448 } | 469 } |
| 449 const IOffsetT Position = Buffer.size(); | 470 const IOffsetT Position = Buffer.size(); |
| 450 // Use the offset field of the branch instruction for linking the sites. | 471 // Use the offset field of the branch instruction for linking the sites. |
| 451 emitType05(Cond, L->getEncodedPosition(), Link); | 472 emitType05(Cond, L->getEncodedPosition(), Link); |
| 452 if (!needsTextFixup()) | 473 if (!needsTextFixup()) |
| 453 L->linkTo(Position); | 474 L->linkTo(Position); |
| 454 } | 475 } |
| 455 | 476 |
| 477 void AssemblerARM32::emitCompareOp(IValueT Opcode, const Operand *OpRn, |
| 478 const Operand *OpSrc1, |
| 479 CondARM32::Cond Cond) { |
| 480 // XXX (register) |
| 481 // XXX<c> <Rn>, <Rm>{, <shift>} |
| 482 // |
| 483 // ccccyyyxxxx1nnnn0000iiiiitt0mmmm where cccc=Cond, nnnn=Rn, mmmm=Rm, |
| 484 // iiiii=Shift, tt=ShiftKind, yyy=kInstTypeDataRegister, and xxxx=Opcode. |
| 485 // |
| 486 // XXX (immediate) |
| 487 // XXX<c> <Rn>, #<RotatedImm8> |
| 488 // |
| 489 // ccccyyyxxxx1nnnn0000iiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn, |
| 490 // yyy=kInstTypeDataImmdiate, xxxx=Opcode, and iiiiiiiiiiii=Src1Value |
| 491 // defining RotatedImm8. |
| 492 constexpr bool SetFlags = true; |
| 493 constexpr IValueT Rd = RegARM32::Encoded_Reg_r0; |
| 494 IValueT Rn; |
| 495 if (decodeOperand(OpRn, Rn) != DecodedAsRegister) |
| 496 return setNeedsTextFixup(); |
| 497 emitType01(Opcode, Rd, Rn, OpSrc1, SetFlags, Cond, NoChecks); |
| 498 } |
| 499 |
| 456 void AssemblerARM32::emitMemOp(CondARM32::Cond Cond, IValueT InstType, | 500 void AssemblerARM32::emitMemOp(CondARM32::Cond Cond, IValueT InstType, |
| 457 bool IsLoad, bool IsByte, IValueT Rt, | 501 bool IsLoad, bool IsByte, IValueT Rt, |
| 458 IValueT Address) { | 502 IValueT Address) { |
| 459 if (!isGPRRegisterDefined(Rt) || !isConditionDefined(Cond)) | 503 if (!isGPRRegisterDefined(Rt) || !isConditionDefined(Cond)) |
| 460 return setNeedsTextFixup(); | 504 return setNeedsTextFixup(); |
| 461 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 505 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 462 const IValueT Encoding = (encodeCondition(Cond) << kConditionShift) | | 506 const IValueT Encoding = (encodeCondition(Cond) << kConditionShift) | |
| 463 (InstType << kTypeShift) | (IsLoad ? L : 0) | | 507 (InstType << kTypeShift) | (IsLoad ? L : 0) | |
| 464 (IsByte ? B : 0) | (Rt << kRdShift) | Address; | 508 (IsByte ? B : 0) | (Rt << kRdShift) | Address; |
| 465 emitInst(Encoding); | 509 emitInst(Encoding); |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 592 return setNeedsTextFixup(); | 636 return setNeedsTextFixup(); |
| 593 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 637 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 594 const IValueT Encoding = (encodeCondition(Cond) << kConditionShift) | B24 | | 638 const IValueT Encoding = (encodeCondition(Cond) << kConditionShift) | B24 | |
| 595 B21 | (0xfff << 8) | B4 | | 639 B21 | (0xfff << 8) | B4 | |
| 596 (encodeGPRRegister(Rm) << kRmShift); | 640 (encodeGPRRegister(Rm) << kRmShift); |
| 597 emitInst(Encoding); | 641 emitInst(Encoding); |
| 598 } | 642 } |
| 599 | 643 |
| 600 void AssemblerARM32::cmp(const Operand *OpRn, const Operand *OpSrc1, | 644 void AssemblerARM32::cmp(const Operand *OpRn, const Operand *OpSrc1, |
| 601 CondARM32::Cond Cond) { | 645 CondARM32::Cond Cond) { |
| 602 IValueT Rn; | 646 // CMP (register) - ARM section A8.8.38, encoding A1: |
| 603 if (decodeOperand(OpRn, Rn) != DecodedAsRegister) | 647 // cmp<c> <Rn>, <Rm>{, <shift>} |
| 604 return setNeedsTextFixup(); | 648 // |
| 605 constexpr IValueT Cmp = B3 | B1; // ie. 1010 | 649 // cccc00010101nnnn0000iiiiitt0mmmm where cccc=Cond, nnnn=Rn, mmmm=Rm, |
| 606 constexpr bool SetFlags = true; | 650 // iiiii=Shift, and tt=ShiftKind. |
| 607 constexpr IValueT Rd = RegARM32::Encoded_Reg_r0; | 651 // |
| 608 IValueT Src1Value; | 652 // CMP (immediate) - ARM section A8.8.37 |
| 609 // TODO(kschimpf) Other possible decodings of cmp. | 653 // cmp<c: <Rn>, #<RotatedImm8> |
| 610 switch (decodeOperand(OpSrc1, Src1Value)) { | 654 // |
| 611 default: | 655 // cccc00110101nnnn0000iiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn, |
| 612 return setNeedsTextFixup(); | 656 // s=SetFlags and iiiiiiiiiiii=Src1Value defining RotatedImm8. |
| 613 case DecodedAsRegister: { | 657 constexpr IValueT Opcode = B3 | B1; // ie. 1010 |
| 614 // CMP (register) - ARM section A8.8.38, encoding A1: | 658 emitCompareOp(Opcode, OpRn, OpSrc1, Cond); |
| 615 // cmp<c> <Rn>, <Rm>{, <shift>} | |
| 616 // | |
| 617 // cccc00010101nnnn0000iiiiitt0mmmm where cccc=Cond, nnnn=Rn, mmmm=Rm, | |
| 618 // iiiii=Shift, and tt=ShiftKind. | |
| 619 constexpr IValueT Imm5 = 0; | |
| 620 Src1Value = encodeShiftRotateImm5(Src1Value, OperandARM32::kNoShift, Imm5); | |
| 621 emitType01(Cond, kInstTypeDataRegister, Cmp, SetFlags, Rn, Rd, Src1Value); | |
| 622 return; | |
| 623 } | |
| 624 case DecodedAsConstI32: { | |
| 625 // See if we can convert this to an CMP (immediate). | |
| 626 IValueT RotateAmt; | |
| 627 IValueT Imm8; | |
| 628 if (!OperandARM32FlexImm::canHoldImm(Src1Value, &RotateAmt, &Imm8)) | |
| 629 return setNeedsTextFixup(); | |
| 630 Src1Value = encodeRotatedImm8(RotateAmt, Imm8); | |
| 631 // Intentionally fall to next case! | |
| 632 } | |
| 633 case DecodedAsRotatedImm8: { | |
| 634 // CMP (immediate) - ARM section A8.8.37 | |
| 635 // cmp<c: <Rn>, #<RotatedImm8> | |
| 636 // | |
| 637 // cccc00110101nnnn0000iiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn, | |
| 638 // s=SetFlags and iiiiiiiiiiii=Src1Value defining RotatedImm8. | |
| 639 emitType01(Cond, kInstTypeDataImmediate, Cmp, SetFlags, Rn, Rd, Src1Value); | |
| 640 return; | |
| 641 } | |
| 642 } | |
| 643 setNeedsTextFixup(); | |
| 644 } | 659 } |
| 645 | 660 |
| 646 void AssemblerARM32::eor(const Operand *OpRd, const Operand *OpRn, | 661 void AssemblerARM32::eor(const Operand *OpRd, const Operand *OpRn, |
| 647 const Operand *OpSrc1, bool SetFlags, | 662 const Operand *OpSrc1, bool SetFlags, |
| 648 CondARM32::Cond Cond) { | 663 CondARM32::Cond Cond) { |
| 649 // EOR (register) - ARM section A*.8.47, encoding A1: | 664 // EOR (register) - ARM section A*.8.47, encoding A1: |
| 650 // eor{s}<c> <Rd>, <Rn>, <Rm>{, <shift>} | 665 // eor{s}<c> <Rd>, <Rn>, <Rm>{, <shift>} |
| 651 // | 666 // |
| 652 // cccc0000001snnnnddddiiiiitt0mmmm where cccc=Cond, dddd=Rd, nnnn=Rn, | 667 // cccc0000001snnnnddddiiiiitt0mmmm where cccc=Cond, dddd=Rd, nnnn=Rn, |
| 653 // mmmm=Rm, iiiii=Shift, tt=ShiftKind, and s=SetFlags. | 668 // mmmm=Rm, iiiii=Shift, tt=ShiftKind, and s=SetFlags. |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 692 return setNeedsTextFixup(); | 707 return setNeedsTextFixup(); |
| 693 if (!IsByte && (getGPRReg(kRnShift, Address) == RegARM32::Encoded_Reg_sp) && | 708 if (!IsByte && (getGPRReg(kRnShift, Address) == RegARM32::Encoded_Reg_sp) && |
| 694 !isBitSet(P, Address) && isBitSet(U, Address) & !isBitSet(W, Address) && | 709 !isBitSet(P, Address) && isBitSet(U, Address) & !isBitSet(W, Address) && |
| 695 (mask(Address, kImm12Shift, kImmed12Bits) == 0x8 /* 000000000100 */)) | 710 (mask(Address, kImm12Shift, kImmed12Bits) == 0x8 /* 000000000100 */)) |
| 696 return setNeedsTextFixup(); | 711 return setNeedsTextFixup(); |
| 697 emitMemOp(Cond, kInstTypeMemImmediate, IsLoad, IsByte, Rt, Address); | 712 emitMemOp(Cond, kInstTypeMemImmediate, IsLoad, IsByte, Rt, Address); |
| 698 } | 713 } |
| 699 | 714 |
| 700 void AssemblerARM32::mov(const Operand *OpRd, const Operand *OpSrc, | 715 void AssemblerARM32::mov(const Operand *OpRd, const Operand *OpSrc, |
| 701 CondARM32::Cond Cond) { | 716 CondARM32::Cond Cond) { |
| 717 // MOV (register) - ARM section A8.8.104, encoding A1: |
| 718 // mov{S}<c> <Rd>, <Rn> |
| 719 // |
| 720 // cccc0001101s0000dddd00000000mmmm where cccc=Cond, s=SetFlags, dddd=Rd, |
| 721 // and nnnn=Rn. |
| 722 // |
| 723 // MOV (immediate) - ARM section A8.8.102, encoding A1: |
| 724 // mov{S}<c> <Rd>, #<RotatedImm8> |
| 725 // |
| 726 // cccc0011101s0000ddddiiiiiiiiiiii where cccc=Cond, s=SetFlags, dddd=Rd, |
| 727 // and iiiiiiiiiiii=RotatedImm8=Src. Note: We don't use movs in this |
| 728 // assembler. |
| 702 IValueT Rd; | 729 IValueT Rd; |
| 703 if (decodeOperand(OpRd, Rd) != DecodedAsRegister) | 730 if (decodeOperand(OpRd, Rd) != DecodedAsRegister) |
| 704 return setNeedsTextFixup(); | 731 return setNeedsTextFixup(); |
| 705 IValueT Src; | |
| 706 // TODO(kschimpf) Handle other forms of mov. | |
| 707 constexpr bool SetFlags = false; | 732 constexpr bool SetFlags = false; |
| 708 constexpr IValueT Rn = 0; | 733 constexpr IValueT Rn = 0; |
| 709 constexpr IValueT Mov = B3 | B2 | B0; // 1101. | 734 constexpr IValueT Mov = B3 | B2 | B0; // 1101. |
| 710 switch (decodeOperand(OpSrc, Src)) { | 735 emitType01(Mov, Rd, Rn, OpSrc, SetFlags, Cond); |
| 711 default: | |
| 712 return setNeedsTextFixup(); | |
| 713 case DecodedAsRegister: { | |
| 714 // MOV (register) - ARM section A8.8.104, encoding A1: | |
| 715 // mov{S}<c> <Rd>, <Rn> | |
| 716 // | |
| 717 // cccc0001101s0000dddd00000000mmmm where cccc=Cond, s=SetFlags, dddd=Rd, | |
| 718 // and nnnn=Rn. | |
| 719 if ((Rd == RegARM32::Encoded_Reg_pc && SetFlags)) | |
| 720 // Conditions of rule violated. | |
| 721 return setNeedsTextFixup(); | |
| 722 emitType01(Cond, kInstTypeDataRegister, Mov, SetFlags, Rn, Rd, Src); | |
| 723 return; | |
| 724 } | |
| 725 case DecodedAsRotatedImm8: { | |
| 726 // MOV (immediate) - ARM section A8.8.102, encoding A1: | |
| 727 // mov{S}<c> <Rd>, #<RotatedImm8> | |
| 728 // | |
| 729 // cccc0011101s0000ddddiiiiiiiiiiii where cccc=Cond, s=SetFlags, dddd=Rd, | |
| 730 // and iiiiiiiiiiii=RotatedImm8=Src. Note: We don't use movs in this | |
| 731 // assembler. | |
| 732 if ((Rd == RegARM32::Encoded_Reg_pc && SetFlags)) | |
| 733 // Conditions of rule violated. | |
| 734 return setNeedsTextFixup(); | |
| 735 emitType01(Cond, kInstTypeDataImmediate, Mov, SetFlags, Rn, Rd, Src); | |
| 736 return; | |
| 737 } | |
| 738 } | |
| 739 } | 736 } |
| 740 | 737 |
| 741 void AssemblerARM32::movw(const Operand *OpRd, const Operand *OpSrc, | 738 void AssemblerARM32::movw(const Operand *OpRd, const Operand *OpSrc, |
| 742 CondARM32::Cond Cond) { | 739 CondARM32::Cond Cond) { |
| 743 IValueT Rd; | 740 IValueT Rd; |
| 744 if (decodeOperand(OpRd, Rd) != DecodedAsRegister) | 741 if (decodeOperand(OpRd, Rd) != DecodedAsRegister) |
| 745 return setNeedsTextFixup(); | 742 return setNeedsTextFixup(); |
| 746 auto *Src = llvm::dyn_cast<ConstantRelocatable>(OpSrc); | 743 auto *Src = llvm::dyn_cast<ConstantRelocatable>(OpSrc); |
| 747 if (Src == nullptr) | 744 if (Src == nullptr) |
| 748 return setNeedsTextFixup(); | 745 return setNeedsTextFixup(); |
| 749 // MOV (immediate) - ARM section A8.8.102, encoding A2: | 746 // MOVW (immediate) - ARM section A8.8.102, encoding A2: |
| 750 // movw<c> <Rd>, #<imm16> | 747 // movw<c> <Rd>, #<imm16> |
| 751 // | 748 // |
| 752 // cccc00110000iiiiddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, and | 749 // cccc00110000iiiiddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, and |
| 753 // iiiiiiiiiiiiiiii=imm16. | 750 // iiiiiiiiiiiiiiii=imm16. |
| 754 if (!isConditionDefined(Cond)) | 751 if (!isConditionDefined(Cond)) |
| 755 // Conditions of rule violated. | 752 // Conditions of rule violated. |
| 756 return setNeedsTextFixup(); | 753 return setNeedsTextFixup(); |
| 757 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 754 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 758 // Use 0 for the lower 16 bits of the relocatable, and add a fixup to | 755 // Use 0 for the lower 16 bits of the relocatable, and add a fixup to |
| 759 // install the correct bits. | 756 // install the correct bits. |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 868 if (!IsByte && (getGPRReg(kRnShift, Address) == RegARM32::Encoded_Reg_sp) && | 865 if (!IsByte && (getGPRReg(kRnShift, Address) == RegARM32::Encoded_Reg_sp) && |
| 869 isBitSet(P, Address) && !isBitSet(U, Address) && isBitSet(W, Address) && | 866 isBitSet(P, Address) && !isBitSet(U, Address) && isBitSet(W, Address) && |
| 870 (mask(Address, kImm12Shift, kImmed12Bits) == 0x8 /* 000000000100 */)) | 867 (mask(Address, kImm12Shift, kImmed12Bits) == 0x8 /* 000000000100 */)) |
| 871 return setNeedsTextFixup(); | 868 return setNeedsTextFixup(); |
| 872 emitMemOp(Cond, kInstTypeMemImmediate, IsLoad, IsByte, Rt, Address); | 869 emitMemOp(Cond, kInstTypeMemImmediate, IsLoad, IsByte, Rt, Address); |
| 873 } | 870 } |
| 874 | 871 |
| 875 void AssemblerARM32::orr(const Operand *OpRd, const Operand *OpRn, | 872 void AssemblerARM32::orr(const Operand *OpRd, const Operand *OpRn, |
| 876 const Operand *OpSrc1, bool SetFlags, | 873 const Operand *OpSrc1, bool SetFlags, |
| 877 CondARM32::Cond Cond) { | 874 CondARM32::Cond Cond) { |
| 878 IValueT Rd; | 875 // ORR (register) - ARM Section A8.8.123, encoding A1: |
| 879 if (decodeOperand(OpRd, Rd) != DecodedAsRegister) | 876 // orr{s}<c> <Rd>, <Rn>, <Rm> |
| 880 return setNeedsTextFixup(); | 877 // |
| 881 IValueT Rn; | 878 // cccc0001100snnnnddddiiiiitt0mmmm where cccc=Cond, dddd=Rd, nnnn=Rn, |
| 882 if (decodeOperand(OpRn, Rn) != DecodedAsRegister) | 879 // mmmm=Rm, iiiii=shift, tt=ShiftKind,, and s=SetFlags. |
| 883 return setNeedsTextFixup(); | 880 // |
| 881 // ORR (register) - ARM Section A8.8.123, encoding A1: |
| 882 // orr{s}<c> <Rd>, <Rn>, #<RotatedImm8> |
| 883 // |
| 884 // cccc0001100snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn, |
| 885 // s=SetFlags and iiiiiiiiiiii=Src1Value defining RotatedImm8. |
| 884 constexpr IValueT Orr = B3 | B2; // i.e. 1100 | 886 constexpr IValueT Orr = B3 | B2; // i.e. 1100 |
| 885 IValueT Src1Value; | 887 emitType01(Orr, OpRd, OpRn, OpSrc1, SetFlags, Cond); |
| 886 // TODO(kschimpf) Handle other possible decodings of orr. | |
| 887 switch (decodeOperand(OpSrc1, Src1Value)) { | |
| 888 default: | |
| 889 return setNeedsTextFixup(); | |
| 890 case DecodedAsRegister: { | |
| 891 // ORR (register) - ARM Section A8.8.123, encoding A1: | |
| 892 // orr{s}<c> <Rd>, <Rn>, <Rm> | |
| 893 // | |
| 894 // cccc0001100snnnnddddiiiiitt0mmmm where cccc=Cond, dddd=Rd, nnnn=Rn, | |
| 895 // mmmm=Rm, iiiii=shift, tt=ShiftKind,, and s=SetFlags. | |
| 896 constexpr IValueT Shift = 0; | |
| 897 Src1Value = encodeShiftRotateImm5(Src1Value, OperandARM32::kNoShift, Shift); | |
| 898 if (((Rd == RegARM32::Encoded_Reg_pc) && SetFlags)) | |
| 899 // Conditions of rule violated. | |
| 900 return setNeedsTextFixup(); | |
| 901 emitType01(Cond, kInstTypeDataRegister, Orr, SetFlags, Rn, Rd, Src1Value); | |
| 902 return; | |
| 903 } | |
| 904 case DecodedAsRotatedImm8: { | |
| 905 // ORR (register) - ARM Section A8.8.123, encoding A1: | |
| 906 // orr{s}<c> <Rd>, <Rn>, #<RotatedImm8> | |
| 907 // | |
| 908 // cccc0001100snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn, | |
| 909 // s=SetFlags and iiiiiiiiiiii=Src1Value defining RotatedImm8. | |
| 910 if (Rd == RegARM32::Encoded_Reg_pc && SetFlags) | |
| 911 // Conditions of rule violated. | |
| 912 return setNeedsTextFixup(); | |
| 913 emitType01(Cond, kInstTypeDataImmediate, Orr, SetFlags, Rn, Rd, Src1Value); | |
| 914 return; | |
| 915 } | |
| 916 } | |
| 917 } | 888 } |
| 918 | 889 |
| 919 void AssemblerARM32::mul(const Operand *OpRd, const Operand *OpRn, | 890 void AssemblerARM32::mul(const Operand *OpRd, const Operand *OpRn, |
| 920 const Operand *OpSrc1, bool SetFlags, | 891 const Operand *OpSrc1, bool SetFlags, |
| 921 CondARM32::Cond Cond) { | 892 CondARM32::Cond Cond) { |
| 922 IValueT Rd; | 893 IValueT Rd; |
| 923 if (decodeOperand(OpRd, Rd) != DecodedAsRegister) | 894 if (decodeOperand(OpRd, Rd) != DecodedAsRegister) |
| 924 return setNeedsTextFixup(); | 895 return setNeedsTextFixup(); |
| 925 IValueT Rn; | 896 IValueT Rn; |
| 926 if (decodeOperand(OpRn, Rn) != DecodedAsRegister) | 897 if (decodeOperand(OpRn, Rn) != DecodedAsRegister) |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 980 // sub{s}<c> <Rd>, <Rn>, #<RotatedImm8> | 951 // sub{s}<c> <Rd>, <Rn>, #<RotatedImm8> |
| 981 // Sub (Sp minus immediate) - ARM section A8.*.225, encoding A1: | 952 // Sub (Sp minus immediate) - ARM section A8.*.225, encoding A1: |
| 982 // sub{s}<c> sp, <Rn>, #<RotatedImm8> | 953 // sub{s}<c> sp, <Rn>, #<RotatedImm8> |
| 983 // | 954 // |
| 984 // cccc0010010snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn, | 955 // cccc0010010snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn, |
| 985 // s=SetFlags and iiiiiiiiiiii=Src1Value defining RotatedImm8 | 956 // s=SetFlags and iiiiiiiiiiii=Src1Value defining RotatedImm8 |
| 986 constexpr IValueT Sub = B1; // 0010 | 957 constexpr IValueT Sub = B1; // 0010 |
| 987 emitType01(Sub, OpRd, OpRn, OpSrc1, SetFlags, Cond); | 958 emitType01(Sub, OpRd, OpRn, OpSrc1, SetFlags, Cond); |
| 988 } | 959 } |
| 989 | 960 |
| 961 void AssemblerARM32::tst(const Operand *OpRn, const Operand *OpSrc1, |
| 962 CondARM32::Cond Cond) { |
| 963 // TST (register) - ARM section A8.8.241, encoding A1: |
| 964 // tst<c> <Rn>, <Rm>(, <shift>} |
| 965 // |
| 966 // cccc00010001nnnn0000iiiiitt0mmmm where cccc=Cond, nnnn=Rn, mmmm=Rm, |
| 967 // iiiii=Shift, and tt=ShiftKind. |
| 968 // |
| 969 // TST (immediate) - ARM section A8.8.240, encoding A1: |
| 970 // tst<c> <Rn>, #<RotatedImm8> |
| 971 // |
| 972 // cccc00110001nnnn0000iiiiiiiiiiii where cccc=Cond, nnnn=Rn, and |
| 973 // iiiiiiiiiiii defines RotatedImm8. |
| 974 constexpr IValueT Opcode = B3; // ie. 1000 |
| 975 emitCompareOp(Opcode, OpRn, OpSrc1, Cond); |
| 976 } |
| 977 |
| 990 } // end of namespace ARM32 | 978 } // end of namespace ARM32 |
| 991 } // end of namespace Ice | 979 } // end of namespace Ice |
| OLD | NEW |