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 |