Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(200)

Side by Side Diff: src/IceAssemblerARM32.cpp

Issue 1413473005: Add TST(register, immediate) to ARM32 integrated assembler. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Fix conflict when merging into master. Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/IceAssemblerARM32.h ('k') | src/IceInstARM32.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/IceAssemblerARM32.h ('k') | src/IceInstARM32.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698