llvm.org GIT mirror llvm / e072ed7
ARM64: separate load/store operands to simplify assembler This changes ARM64 to use separate operands for each component of an address, and look for separate '[', '$Rn, ..., ']' tokens when parsing. This allows us to do away with quite a bit of special C++ code to handle monolithic "addressing modes" in the MC components. The more incremental matching of the assembler operands also allows for better diagnostics when LLVM is presented with invalid input. Most of the complexity here is with the register-offset instructions, which were extremely dodgy beforehand: even when the instruction used wM, LLVM's model had xM as an operand. We papered over this discrepancy before, but that approach doesn't work now so I split them into separate X and W variants. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@209425 91177308-0d34-0410-b5e6-96231b3b80d8 Tim Northover 5 years ago
15 changed file(s) with 3134 addition(s) and 3299 deletion(s). Raw diff Collapse all Expand all
110110 return SelectAddrModeUnscaled(N, 16, Base, OffImm);
111111 }
112112
113 bool SelectAddrModeRO8(SDValue N, SDValue &Base, SDValue &Offset,
114 SDValue &Imm) {
115 return SelectAddrModeRO(N, 1, Base, Offset, Imm);
116 }
117 bool SelectAddrModeRO16(SDValue N, SDValue &Base, SDValue &Offset,
118 SDValue &Imm) {
119 return SelectAddrModeRO(N, 2, Base, Offset, Imm);
120 }
121 bool SelectAddrModeRO32(SDValue N, SDValue &Base, SDValue &Offset,
122 SDValue &Imm) {
123 return SelectAddrModeRO(N, 4, Base, Offset, Imm);
124 }
125 bool SelectAddrModeRO64(SDValue N, SDValue &Base, SDValue &Offset,
126 SDValue &Imm) {
127 return SelectAddrModeRO(N, 8, Base, Offset, Imm);
128 }
129 bool SelectAddrModeRO128(SDValue N, SDValue &Base, SDValue &Offset,
130 SDValue &Imm) {
131 return SelectAddrModeRO(N, 16, Base, Offset, Imm);
132 }
133 bool SelectAddrModeNoIndex(SDValue N, SDValue &Val);
113 template
114 bool SelectAddrModeWRO(SDValue N, SDValue &Base, SDValue &Offset,
115 SDValue &SignExtend, SDValue &DoShift) {
116 return SelectAddrModeWRO(N, Width / 8, Base, Offset, SignExtend, DoShift);
117 }
118
119 template
120 bool SelectAddrModeXRO(SDValue N, SDValue &Base, SDValue &Offset,
121 SDValue &SignExtend, SDValue &DoShift) {
122 return SelectAddrModeXRO(N, Width / 8, Base, Offset, SignExtend, DoShift);
123 }
124
134125
135126 /// Form sequences of consecutive 64/128-bit registers for use in NEON
136127 /// instructions making use of a vector-list (e.g. ldN, tbl). Vecs must have
178169 SDValue &OffImm);
179170 bool SelectAddrModeUnscaled(SDValue N, unsigned Size, SDValue &Base,
180171 SDValue &OffImm);
181 bool SelectAddrModeRO(SDValue N, unsigned Size, SDValue &Base,
182 SDValue &Offset, SDValue &Imm);
172 bool SelectAddrModeWRO(SDValue N, unsigned Size, SDValue &Base,
173 SDValue &Offset, SDValue &SignExtend,
174 SDValue &DoShift);
175 bool SelectAddrModeXRO(SDValue N, unsigned Size, SDValue &Base,
176 SDValue &Offset, SDValue &SignExtend,
177 SDValue &DoShift);
183178 bool isWorthFolding(SDValue V) const;
184 bool SelectExtendedSHL(SDValue N, unsigned Size, SDValue &Offset,
185 SDValue &Imm);
179 bool SelectExtendedSHL(SDValue N, unsigned Size, bool WantExtend,
180 SDValue &Offset, SDValue &SignExtend);
186181
187182 template
188183 bool SelectCVTFixedPosOperand(SDValue N, SDValue &FixedPos) {
216211 uint64_t &Imm) {
217212 return N->getOpcode() == Opc &&
218213 isIntImmediate(N->getOperand(1).getNode(), Imm);
219 }
220
221 bool ARM64DAGToDAGISel::SelectAddrModeNoIndex(SDValue N, SDValue &Val) {
222 EVT ValTy = N.getValueType();
223 if (ValTy != MVT::i64)
224 return false;
225 Val = N;
226 return true;
227214 }
228215
229216 bool ARM64DAGToDAGISel::SelectInlineAsmMemoryOperand(
562549 // if we're folding a (sext i8), we need the RHS to be a GPR32, even though
563550 // there might not be an actual 32-bit value in the program. We can
564551 // (harmlessly) synthesize one by injected an EXTRACT_SUBREG here.
565 if (Reg.getValueType() == MVT::i64 && Ext != ARM64_AM::UXTX &&
566 Ext != ARM64_AM::SXTX) {
552 assert(Ext != ARM64_AM::UXTX && Ext != ARM64_AM::SXTX);
553 if (Reg.getValueType() == MVT::i64) {
567554 SDValue SubReg = CurDAG->getTargetConstant(ARM64::sub_32, MVT::i32);
568555 MachineSDNode *Node = CurDAG->getMachineNode(
569556 TargetOpcode::EXTRACT_SUBREG, SDLoc(N), MVT::i32, Reg, SubReg);
674661 return SDValue(Node, 0);
675662 }
676663
677 static SDValue WidenIfNeeded(SelectionDAG *CurDAG, SDValue N) {
678 if (N.getValueType() == MVT::i32) {
679 return Widen(CurDAG, N);
680 }
681
682 return N;
683 }
684
685664 /// \brief Check if the given SHL node (\p N), can be used to form an
686665 /// extended register for an addressing mode.
687666 bool ARM64DAGToDAGISel::SelectExtendedSHL(SDValue N, unsigned Size,
688 SDValue &Offset, SDValue &Imm) {
667 bool WantExtend, SDValue &Offset,
668 SDValue &SignExtend) {
689669 assert(N.getOpcode() == ISD::SHL && "Invalid opcode.");
690670 ConstantSDNode *CSD = dyn_cast(N.getOperand(1));
691 if (CSD && (CSD->getZExtValue() & 0x7) == CSD->getZExtValue()) {
692
671 if (!CSD || (CSD->getZExtValue() & 0x7) != CSD->getZExtValue())
672 return false;
673
674 if (WantExtend) {
693675 ARM64_AM::ShiftExtendType Ext = getExtendTypeForNode(N.getOperand(0), true);
694 if (Ext == ARM64_AM::InvalidShiftExtend) {
695 Ext = ARM64_AM::UXTX;
696 Offset = WidenIfNeeded(CurDAG, N.getOperand(0));
697 } else {
698 Offset = WidenIfNeeded(CurDAG, N.getOperand(0).getOperand(0));
699 }
700
701 unsigned LegalShiftVal = Log2_32(Size);
702 unsigned ShiftVal = CSD->getZExtValue();
703
704 if (ShiftVal != 0 && ShiftVal != LegalShiftVal)
676 if (Ext == ARM64_AM::InvalidShiftExtend)
705677 return false;
706678
707 Imm = CurDAG->getTargetConstant(
708 ARM64_AM::getMemExtendImm(Ext, ShiftVal != 0), MVT::i32);
709 if (isWorthFolding(N))
710 return true;
711 }
679 Offset = N.getOperand(0).getOperand(0);
680 SignExtend = CurDAG->getTargetConstant(Ext == ARM64_AM::SXTW, MVT::i32);
681 } else {
682 Offset = N.getOperand(0);
683 SignExtend = CurDAG->getTargetConstant(0, MVT::i32);
684 }
685
686 unsigned LegalShiftVal = Log2_32(Size);
687 unsigned ShiftVal = CSD->getZExtValue();
688
689 if (ShiftVal != 0 && ShiftVal != LegalShiftVal)
690 return false;
691
692 if (isWorthFolding(N))
693 return true;
694
712695 return false;
713696 }
714697
715 bool ARM64DAGToDAGISel::SelectAddrModeRO(SDValue N, unsigned Size,
698 bool ARM64DAGToDAGISel::SelectAddrModeWRO(SDValue N, unsigned Size,
716699 SDValue &Base, SDValue &Offset,
717 SDValue &Imm) {
700 SDValue &SignExtend,
701 SDValue &DoShift) {
718702 if (N.getOpcode() != ISD::ADD)
719703 return false;
720704 SDValue LHS = N.getOperand(0);
739723
740724 // Try to match a shifted extend on the RHS.
741725 if (IsExtendedRegisterWorthFolding && RHS.getOpcode() == ISD::SHL &&
742 SelectExtendedSHL(RHS, Size, Offset, Imm)) {
726 SelectExtendedSHL(RHS, Size, true, Offset, SignExtend)) {
743727 Base = LHS;
728 DoShift = CurDAG->getTargetConstant(true, MVT::i32);
744729 return true;
745730 }
746731
747732 // Try to match a shifted extend on the LHS.
748733 if (IsExtendedRegisterWorthFolding && LHS.getOpcode() == ISD::SHL &&
749 SelectExtendedSHL(LHS, Size, Offset, Imm)) {
734 SelectExtendedSHL(LHS, Size, true, Offset, SignExtend)) {
750735 Base = RHS;
736 DoShift = CurDAG->getTargetConstant(true, MVT::i32);
751737 return true;
752738 }
753739
754 ARM64_AM::ShiftExtendType Ext = ARM64_AM::UXTX;
740 // There was no shift, whatever else we find.
741 DoShift = CurDAG->getTargetConstant(false, MVT::i32);
742
743 ARM64_AM::ShiftExtendType Ext = ARM64_AM::InvalidShiftExtend;
755744 // Try to match an unshifted extend on the LHS.
756745 if (IsExtendedRegisterWorthFolding &&
757746 (Ext = getExtendTypeForNode(LHS, true)) != ARM64_AM::InvalidShiftExtend) {
758747 Base = RHS;
759 Offset = WidenIfNeeded(CurDAG, LHS.getOperand(0));
760 Imm = CurDAG->getTargetConstant(ARM64_AM::getMemExtendImm(Ext, false),
761 MVT::i32);
748 Offset = LHS.getOperand(0);
749 SignExtend = CurDAG->getTargetConstant(Ext == ARM64_AM::SXTW, MVT::i32);
762750 if (isWorthFolding(LHS))
763751 return true;
764752 }
767755 if (IsExtendedRegisterWorthFolding &&
768756 (Ext = getExtendTypeForNode(RHS, true)) != ARM64_AM::InvalidShiftExtend) {
769757 Base = LHS;
770 Offset = WidenIfNeeded(CurDAG, RHS.getOperand(0));
771 Imm = CurDAG->getTargetConstant(ARM64_AM::getMemExtendImm(Ext, false),
772 MVT::i32);
758 Offset = RHS.getOperand(0);
759 SignExtend = CurDAG->getTargetConstant(Ext == ARM64_AM::SXTW, MVT::i32);
773760 if (isWorthFolding(RHS))
774761 return true;
775762 }
776763
764 return false;
765 }
766
767 bool ARM64DAGToDAGISel::SelectAddrModeXRO(SDValue N, unsigned Size,
768 SDValue &Base, SDValue &Offset,
769 SDValue &SignExtend,
770 SDValue &DoShift) {
771 if (N.getOpcode() != ISD::ADD)
772 return false;
773 SDValue LHS = N.getOperand(0);
774 SDValue RHS = N.getOperand(1);
775
776 // We don't want to match immediate adds here, because they are better lowered
777 // to the register-immediate addressing modes.
778 if (isa(LHS) || isa(RHS))
779 return false;
780
781 // Check if this particular node is reused in any non-memory related
782 // operation. If yes, do not try to fold this node into the address
783 // computation, since the computation will be kept.
784 const SDNode *Node = N.getNode();
785 for (SDNode *UI : Node->uses()) {
786 if (!isa(*UI))
787 return false;
788 }
789
790 // Remember if it is worth folding N when it produces extended register.
791 bool IsExtendedRegisterWorthFolding = isWorthFolding(N);
792
793 // Try to match a shifted extend on the RHS.
794 if (IsExtendedRegisterWorthFolding && RHS.getOpcode() == ISD::SHL &&
795 SelectExtendedSHL(RHS, Size, false, Offset, SignExtend)) {
796 Base = LHS;
797 DoShift = CurDAG->getTargetConstant(true, MVT::i32);
798 return true;
799 }
800
801 // Try to match a shifted extend on the LHS.
802 if (IsExtendedRegisterWorthFolding && LHS.getOpcode() == ISD::SHL &&
803 SelectExtendedSHL(LHS, Size, false, Offset, SignExtend)) {
804 Base = RHS;
805 DoShift = CurDAG->getTargetConstant(true, MVT::i32);
806 return true;
807 }
808
777809 // Match any non-shifted, non-extend, non-immediate add expression.
778810 Base = LHS;
779 Offset = WidenIfNeeded(CurDAG, RHS);
780 Ext = ARM64_AM::UXTX;
781 Imm = CurDAG->getTargetConstant(ARM64_AM::getMemExtendImm(Ext, false),
782 MVT::i32);
811 Offset = RHS;
812 SignExtend = CurDAG->getTargetConstant(false, MVT::i32);
813 DoShift = CurDAG->getTargetConstant(false, MVT::i32);
783814 // Reg1 + Reg2 is free: no check needed.
784815 return true;
785816 }
4242
4343 // 8-bit loads
4444 def : Pat<(acquiring_load GPR64sp:$ptr), (LDARB GPR64sp:$ptr)>;
45 def : Pat<(relaxed_load ro_indexed8:$addr),
46 (LDRBBro ro_indexed8:$addr)>;
47 def : Pat<(relaxed_load am_indexed8:$addr),
48 (LDRBBui am_indexed8:$addr)>;
49 def : Pat<(relaxed_load am_unscaled8:$addr),
50 (LDURBBi am_unscaled8:$addr)>;
45 def : Pat<(relaxed_load (ro_Windexed8 GPR64sp:$Rn, GPR32:$Rm,
46 ro_Wextend8:$offset)),
47 (LDRBBroW GPR64sp:$Rn, GPR32:$Rm, ro_Wextend8:$offset)>;
48 def : Pat<(relaxed_load (ro_Xindexed8 GPR64sp:$Rn, GPR64:$Rm,
49 ro_Xextend8:$offset)),
50 (LDRBBroX GPR64sp:$Rn, GPR64:$Rm, ro_Xextend8:$offset)>;
51 def : Pat<(relaxed_load (am_indexed8 GPR64sp:$Rn,
52 uimm12s1:$offset)),
53 (LDRBBui GPR64sp:$Rn, uimm12s1:$offset)>;
54 def : Pat<(relaxed_load
55 (am_unscaled8 GPR64sp:$Rn, simm9:$offset)),
56 (LDURBBi GPR64sp:$Rn, simm9:$offset)>;
5157
5258 // 16-bit loads
5359 def : Pat<(acquiring_load GPR64sp:$ptr), (LDARH GPR64sp:$ptr)>;
54 def : Pat<(relaxed_load ro_indexed16:$addr),
55 (LDRHHro ro_indexed16:$addr)>;
56 def : Pat<(relaxed_load am_indexed16:$addr),
57 (LDRHHui am_indexed16:$addr)>;
58 def : Pat<(relaxed_load am_unscaled16:$addr),
59 (LDURHHi am_unscaled16:$addr)>;
60 def : Pat<(relaxed_load (ro_Windexed16 GPR64sp:$Rn, GPR32:$Rm,
61 ro_Wextend16:$extend)),
62 (LDRHHroW GPR64sp:$Rn, GPR32:$Rm, ro_Wextend16:$extend)>;
63 def : Pat<(relaxed_load (ro_Xindexed16 GPR64sp:$Rn, GPR64:$Rm,
64 ro_Xextend16:$extend)),
65 (LDRHHroX GPR64sp:$Rn, GPR64:$Rm, ro_Xextend16:$extend)>;
66 def : Pat<(relaxed_load (am_indexed16 GPR64sp:$Rn,
67 uimm12s2:$offset)),
68 (LDRHHui GPR64sp:$Rn, uimm12s2:$offset)>;
69 def : Pat<(relaxed_load
70 (am_unscaled16 GPR64sp:$Rn, simm9:$offset)),
71 (LDURHHi GPR64sp:$Rn, simm9:$offset)>;
6072
6173 // 32-bit loads
6274 def : Pat<(acquiring_load GPR64sp:$ptr), (LDARW GPR64sp:$ptr)>;
63 def : Pat<(relaxed_load ro_indexed32:$addr),
64 (LDRWro ro_indexed32:$addr)>;
65 def : Pat<(relaxed_load am_indexed32:$addr),
66 (LDRWui am_indexed32:$addr)>;
67 def : Pat<(relaxed_load am_unscaled32:$addr),
68 (LDURWi am_unscaled32:$addr)>;
75 def : Pat<(relaxed_load (ro_Windexed32 GPR64sp:$Rn, GPR32:$Rm,
76 ro_Wextend32:$extend)),
77 (LDRWroW GPR64sp:$Rn, GPR32:$Rm, ro_Wextend32:$extend)>;
78 def : Pat<(relaxed_load (ro_Xindexed32 GPR64sp:$Rn, GPR64:$Rm,
79 ro_Xextend32:$extend)),
80 (LDRWroX GPR64sp:$Rn, GPR64:$Rm, ro_Xextend32:$extend)>;
81 def : Pat<(relaxed_load (am_indexed32 GPR64sp:$Rn,
82 uimm12s4:$offset)),
83 (LDRWui GPR64sp:$Rn, uimm12s4:$offset)>;
84 def : Pat<(relaxed_load
85 (am_unscaled32 GPR64sp:$Rn, simm9:$offset)),
86 (LDURWi GPR64sp:$Rn, simm9:$offset)>;
6987
7088 // 64-bit loads
7189 def : Pat<(acquiring_load GPR64sp:$ptr), (LDARX GPR64sp:$ptr)>;
72 def : Pat<(relaxed_load ro_indexed64:$addr),
73 (LDRXro ro_indexed64:$addr)>;
74 def : Pat<(relaxed_load am_indexed64:$addr),
75 (LDRXui am_indexed64:$addr)>;
76 def : Pat<(relaxed_load am_unscaled64:$addr),
77 (LDURXi am_unscaled64:$addr)>;
90 def : Pat<(relaxed_load (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm,
91 ro_Wextend64:$extend)),
92 (LDRXroW GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend)>;
93 def : Pat<(relaxed_load (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm,
94 ro_Xextend64:$extend)),
95 (LDRXroX GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend)>;
96 def : Pat<(relaxed_load (am_indexed64 GPR64sp:$Rn,
97 uimm12s8:$offset)),
98 (LDRXui GPR64sp:$Rn, uimm12s8:$offset)>;
99 def : Pat<(relaxed_load
100 (am_unscaled64 GPR64sp:$Rn, simm9:$offset)),
101 (LDURXi GPR64sp:$Rn, simm9:$offset)>;
78102
79103 //===----------------------------------
80104 // Atomic stores
102126 // 8-bit stores
103127 def : Pat<(releasing_store GPR64sp:$ptr, GPR32:$val),
104128 (STLRB GPR32:$val, GPR64sp:$ptr)>;
105 def : Pat<(relaxed_store ro_indexed8:$ptr, GPR32:$val),
106 (STRBBro GPR32:$val, ro_indexed8:$ptr)>;
107 def : Pat<(relaxed_store am_indexed8:$ptr, GPR32:$val),
108 (STRBBui GPR32:$val, am_indexed8:$ptr)>;
109 def : Pat<(relaxed_store am_unscaled8:$ptr, GPR32:$val),
110 (STURBBi GPR32:$val, am_unscaled8:$ptr)>;
129 def : Pat<(relaxed_store
130 (ro_Windexed8 GPR64sp:$Rn, GPR32:$Rm, ro_Wextend8:$extend),
131 GPR32:$val),
132 (STRBBroW GPR32:$val, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend8:$extend)>;
133 def : Pat<(relaxed_store
134 (ro_Xindexed8 GPR64sp:$Rn, GPR64:$Rm, ro_Xextend8:$extend),
135 GPR32:$val),
136 (STRBBroX GPR32:$val, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend8:$extend)>;
137 def : Pat<(relaxed_store
138 (am_indexed8 GPR64sp:$Rn, uimm12s1:$offset), GPR32:$val),
139 (STRBBui GPR32:$val, GPR64sp:$Rn, uimm12s1:$offset)>;
140 def : Pat<(relaxed_store
141 (am_unscaled8 GPR64sp:$Rn, simm9:$offset), GPR32:$val),
142 (STURBBi GPR32:$val, GPR64sp:$Rn, simm9:$offset)>;
111143
112144 // 16-bit stores
113145 def : Pat<(releasing_store GPR64sp:$ptr, GPR32:$val),
114146 (STLRH GPR32:$val, GPR64sp:$ptr)>;
115 def : Pat<(relaxed_store ro_indexed16:$ptr, GPR32:$val),
116 (STRHHro GPR32:$val, ro_indexed16:$ptr)>;
117 def : Pat<(relaxed_store am_indexed16:$ptr, GPR32:$val),
118 (STRHHui GPR32:$val, am_indexed16:$ptr)>;
119 def : Pat<(relaxed_store am_unscaled16:$ptr, GPR32:$val),
120 (STURHHi GPR32:$val, am_unscaled16:$ptr)>;
147 def : Pat<(relaxed_store (ro_Windexed16 GPR64sp:$Rn, GPR32:$Rm,
148 ro_Wextend16:$extend),
149 GPR32:$val),
150 (STRHHroW GPR32:$val, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend16:$extend)>;
151 def : Pat<(relaxed_store (ro_Xindexed16 GPR64sp:$Rn, GPR64:$Rm,
152 ro_Xextend16:$extend),
153 GPR32:$val),
154 (STRHHroX GPR32:$val, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend16:$extend)>;
155 def : Pat<(relaxed_store
156 (am_indexed16 GPR64sp:$Rn, uimm12s2:$offset), GPR32:$val),
157 (STRHHui GPR32:$val, GPR64sp:$Rn, uimm12s2:$offset)>;
158 def : Pat<(relaxed_store
159 (am_unscaled16 GPR64sp:$Rn, simm9:$offset), GPR32:$val),
160 (STURHHi GPR32:$val, GPR64sp:$Rn, simm9:$offset)>;
121161
122162 // 32-bit stores
123163 def : Pat<(releasing_store GPR64sp:$ptr, GPR32:$val),
124164 (STLRW GPR32:$val, GPR64sp:$ptr)>;
125 def : Pat<(relaxed_store ro_indexed32:$ptr, GPR32:$val),
126 (STRWro GPR32:$val, ro_indexed32:$ptr)>;
127 def : Pat<(relaxed_store am_indexed32:$ptr, GPR32:$val),
128 (STRWui GPR32:$val, am_indexed32:$ptr)>;
129 def : Pat<(relaxed_store am_unscaled32:$ptr, GPR32:$val),
130 (STURWi GPR32:$val, am_unscaled32:$ptr)>;
165 def : Pat<(relaxed_store (ro_Windexed32 GPR64sp:$Rn, GPR32:$Rm,
166 ro_Wextend32:$extend),
167 GPR32:$val),
168 (STRWroW GPR32:$val, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend32:$extend)>;
169 def : Pat<(relaxed_store (ro_Xindexed32 GPR64sp:$Rn, GPR64:$Rm,
170 ro_Xextend32:$extend),
171 GPR32:$val),
172 (STRWroX GPR32:$val, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend32:$extend)>;
173 def : Pat<(relaxed_store
174 (am_indexed32 GPR64sp:$Rn, uimm12s4:$offset), GPR32:$val),
175 (STRWui GPR32:$val, GPR64sp:$Rn, uimm12s4:$offset)>;
176 def : Pat<(relaxed_store
177 (am_unscaled32 GPR64sp:$Rn, simm9:$offset), GPR32:$val),
178 (STURWi GPR32:$val, GPR64sp:$Rn, simm9:$offset)>;
131179
132180 // 64-bit stores
133181 def : Pat<(releasing_store GPR64sp:$ptr, GPR64:$val),
134182 (STLRX GPR64:$val, GPR64sp:$ptr)>;
135 def : Pat<(relaxed_store ro_indexed64:$ptr, GPR64:$val),
136 (STRXro GPR64:$val, ro_indexed64:$ptr)>;
137 def : Pat<(relaxed_store am_indexed64:$ptr, GPR64:$val),
138 (STRXui GPR64:$val, am_indexed64:$ptr)>;
139 def : Pat<(relaxed_store am_unscaled64:$ptr, GPR64:$val),
140 (STURXi GPR64:$val, am_unscaled64:$ptr)>;
183 def : Pat<(relaxed_store (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm,
184 ro_Wextend16:$extend),
185 GPR64:$val),
186 (STRXroW GPR64:$val, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend)>;
187 def : Pat<(relaxed_store (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm,
188 ro_Xextend16:$extend),
189 GPR64:$val),
190 (STRXroX GPR64:$val, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend)>;
191 def : Pat<(relaxed_store
192 (am_indexed64 GPR64sp:$Rn, uimm12s8:$offset), GPR64:$val),
193 (STRXui GPR64:$val, GPR64sp:$Rn, uimm12s8:$offset)>;
194 def : Pat<(relaxed_store
195 (am_unscaled64 GPR64sp:$Rn, simm9:$offset), GPR64:$val),
196 (STURXi GPR64:$val, GPR64sp:$Rn, simm9:$offset)>;
141197
142198 //===----------------------------------
143199 // Low-level exclusive operations
161217 return cast(N)->getMemoryVT() == MVT::i64;
162218 }]>;
163219
164 def : Pat<(ldxr_1 am_noindex:$addr),
165 (SUBREG_TO_REG (i64 0), (LDXRB am_noindex:$addr), sub_32)>;
166 def : Pat<(ldxr_2 am_noindex:$addr),
167 (SUBREG_TO_REG (i64 0), (LDXRH am_noindex:$addr), sub_32)>;
168 def : Pat<(ldxr_4 am_noindex:$addr),
169 (SUBREG_TO_REG (i64 0), (LDXRW am_noindex:$addr), sub_32)>;
170 def : Pat<(ldxr_8 am_noindex:$addr), (LDXRX am_noindex:$addr)>;
171
172 def : Pat<(and (ldxr_1 am_noindex:$addr), 0xff),
173 (SUBREG_TO_REG (i64 0), (LDXRB am_noindex:$addr), sub_32)>;
174 def : Pat<(and (ldxr_2 am_noindex:$addr), 0xffff),
175 (SUBREG_TO_REG (i64 0), (LDXRH am_noindex:$addr), sub_32)>;
176 def : Pat<(and (ldxr_4 am_noindex:$addr), 0xffffffff),
177 (SUBREG_TO_REG (i64 0), (LDXRW am_noindex:$addr), sub_32)>;
220 def : Pat<(ldxr_1 GPR64sp:$addr),
221 (SUBREG_TO_REG (i64 0), (LDXRB GPR64sp:$addr), sub_32)>;
222 def : Pat<(ldxr_2 GPR64sp:$addr),
223 (SUBREG_TO_REG (i64 0), (LDXRH GPR64sp:$addr), sub_32)>;
224 def : Pat<(ldxr_4 GPR64sp:$addr),
225 (SUBREG_TO_REG (i64 0), (LDXRW GPR64sp:$addr), sub_32)>;
226 def : Pat<(ldxr_8 GPR64sp:$addr), (LDXRX GPR64sp:$addr)>;
227
228 def : Pat<(and (ldxr_1 GPR64sp:$addr), 0xff),
229 (SUBREG_TO_REG (i64 0), (LDXRB GPR64sp:$addr), sub_32)>;
230 def : Pat<(and (ldxr_2 GPR64sp:$addr), 0xffff),
231 (SUBREG_TO_REG (i64 0), (LDXRH GPR64sp:$addr), sub_32)>;
232 def : Pat<(and (ldxr_4 GPR64sp:$addr), 0xffffffff),
233 (SUBREG_TO_REG (i64 0), (LDXRW GPR64sp:$addr), sub_32)>;
178234
179235 // Load-exclusives.
180236
194250 return cast(N)->getMemoryVT() == MVT::i64;
195251 }]>;
196252
197 def : Pat<(ldaxr_1 am_noindex:$addr),
198 (SUBREG_TO_REG (i64 0), (LDAXRB am_noindex:$addr), sub_32)>;
199 def : Pat<(ldaxr_2 am_noindex:$addr),
200 (SUBREG_TO_REG (i64 0), (LDAXRH am_noindex:$addr), sub_32)>;
201 def : Pat<(ldaxr_4 am_noindex:$addr),
202 (SUBREG_TO_REG (i64 0), (LDAXRW am_noindex:$addr), sub_32)>;
203 def : Pat<(ldaxr_8 am_noindex:$addr), (LDAXRX am_noindex:$addr)>;
204
205 def : Pat<(and (ldaxr_1 am_noindex:$addr), 0xff),
206 (SUBREG_TO_REG (i64 0), (LDAXRB am_noindex:$addr), sub_32)>;
207 def : Pat<(and (ldaxr_2 am_noindex:$addr), 0xffff),
208 (SUBREG_TO_REG (i64 0), (LDAXRH am_noindex:$addr), sub_32)>;
209 def : Pat<(and (ldaxr_4 am_noindex:$addr), 0xffffffff),
210 (SUBREG_TO_REG (i64 0), (LDAXRW am_noindex:$addr), sub_32)>;
253 def : Pat<(ldaxr_1 GPR64sp:$addr),
254 (SUBREG_TO_REG (i64 0), (LDAXRB GPR64sp:$addr), sub_32)>;
255 def : Pat<(ldaxr_2 GPR64sp:$addr),
256 (SUBREG_TO_REG (i64 0), (LDAXRH GPR64sp:$addr), sub_32)>;
257 def : Pat<(ldaxr_4 GPR64sp:$addr),
258 (SUBREG_TO_REG (i64 0), (LDAXRW GPR64sp:$addr), sub_32)>;
259 def : Pat<(ldaxr_8 GPR64sp:$addr), (LDAXRX GPR64sp:$addr)>;
260
261 def : Pat<(and (ldaxr_1 GPR64sp:$addr), 0xff),
262 (SUBREG_TO_REG (i64 0), (LDAXRB GPR64sp:$addr), sub_32)>;
263 def : Pat<(and (ldaxr_2 GPR64sp:$addr), 0xffff),
264 (SUBREG_TO_REG (i64 0), (LDAXRH GPR64sp:$addr), sub_32)>;
265 def : Pat<(and (ldaxr_4 GPR64sp:$addr), 0xffffffff),
266 (SUBREG_TO_REG (i64 0), (LDAXRW GPR64sp:$addr), sub_32)>;
211267
212268 // Store-exclusives.
213269
232288 }]>;
233289
234290
235 def : Pat<(stxr_1 GPR64:$val, am_noindex:$addr),
236 (STXRB (EXTRACT_SUBREG GPR64:$val, sub_32), am_noindex:$addr)>;
237 def : Pat<(stxr_2 GPR64:$val, am_noindex:$addr),
238 (STXRH (EXTRACT_SUBREG GPR64:$val, sub_32), am_noindex:$addr)>;
239 def : Pat<(stxr_4 GPR64:$val, am_noindex:$addr),
240 (STXRW (EXTRACT_SUBREG GPR64:$val, sub_32), am_noindex:$addr)>;
241 def : Pat<(stxr_8 GPR64:$val, am_noindex:$addr),
242 (STXRX GPR64:$val, am_noindex:$addr)>;
243
244 def : Pat<(stxr_1 (zext (and GPR32:$val, 0xff)), am_noindex:$addr),
245 (STXRB GPR32:$val, am_noindex:$addr)>;
246 def : Pat<(stxr_2 (zext (and GPR32:$val, 0xffff)), am_noindex:$addr),
247 (STXRH GPR32:$val, am_noindex:$addr)>;
248 def : Pat<(stxr_4 (zext GPR32:$val), am_noindex:$addr),
249 (STXRW GPR32:$val, am_noindex:$addr)>;
250
251 def : Pat<(stxr_1 (and GPR64:$val, 0xff), am_noindex:$addr),
252 (STXRB (EXTRACT_SUBREG GPR64:$val, sub_32), am_noindex:$addr)>;
253 def : Pat<(stxr_2 (and GPR64:$val, 0xffff), am_noindex:$addr),
254 (STXRH (EXTRACT_SUBREG GPR64:$val, sub_32), am_noindex:$addr)>;
255 def : Pat<(stxr_4 (and GPR64:$val, 0xffffffff), am_noindex:$addr),
256 (STXRW (EXTRACT_SUBREG GPR64:$val, sub_32), am_noindex:$addr)>;
291 def : Pat<(stxr_1 GPR64:$val, GPR64sp:$addr),
292 (STXRB (EXTRACT_SUBREG GPR64:$val, sub_32), GPR64sp:$addr)>;
293 def : Pat<(stxr_2 GPR64:$val, GPR64sp:$addr),
294 (STXRH (EXTRACT_SUBREG GPR64:$val, sub_32), GPR64sp:$addr)>;
295 def : Pat<(stxr_4 GPR64:$val, GPR64sp:$addr),
296 (STXRW (EXTRACT_SUBREG GPR64:$val, sub_32), GPR64sp:$addr)>;
297 def : Pat<(stxr_8 GPR64:$val, GPR64sp:$addr),
298 (STXRX GPR64:$val, GPR64sp:$addr)>;
299
300 def : Pat<(stxr_1 (zext (and GPR32:$val, 0xff)), GPR64sp:$addr),
301 (STXRB GPR32:$val, GPR64sp:$addr)>;
302 def : Pat<(stxr_2 (zext (and GPR32:$val, 0xffff)), GPR64sp:$addr),
303 (STXRH GPR32:$val, GPR64sp:$addr)>;
304 def : Pat<(stxr_4 (zext GPR32:$val), GPR64sp:$addr),
305 (STXRW GPR32:$val, GPR64sp:$addr)>;
306
307 def : Pat<(stxr_1 (and GPR64:$val, 0xff), GPR64sp:$addr),
308 (STXRB (EXTRACT_SUBREG GPR64:$val, sub_32), GPR64sp:$addr)>;
309 def : Pat<(stxr_2 (and GPR64:$val, 0xffff), GPR64sp:$addr),
310 (STXRH (EXTRACT_SUBREG GPR64:$val, sub_32), GPR64sp:$addr)>;
311 def : Pat<(stxr_4 (and GPR64:$val, 0xffffffff), GPR64sp:$addr),
312 (STXRW (EXTRACT_SUBREG GPR64:$val, sub_32), GPR64sp:$addr)>;
257313
258314 // Store-release-exclusives.
259315
278334 }]>;
279335
280336
281 def : Pat<(stlxr_1 GPR64:$val, am_noindex:$addr),
282 (STLXRB (EXTRACT_SUBREG GPR64:$val, sub_32), am_noindex:$addr)>;
283 def : Pat<(stlxr_2 GPR64:$val, am_noindex:$addr),
284 (STLXRH (EXTRACT_SUBREG GPR64:$val, sub_32), am_noindex:$addr)>;
285 def : Pat<(stlxr_4 GPR64:$val, am_noindex:$addr),
286 (STLXRW (EXTRACT_SUBREG GPR64:$val, sub_32), am_noindex:$addr)>;
287 def : Pat<(stlxr_8 GPR64:$val, am_noindex:$addr),
288 (STLXRX GPR64:$val, am_noindex:$addr)>;
289
290 def : Pat<(stlxr_1 (zext (and GPR32:$val, 0xff)), am_noindex:$addr),
291 (STLXRB GPR32:$val, am_noindex:$addr)>;
292 def : Pat<(stlxr_2 (zext (and GPR32:$val, 0xffff)), am_noindex:$addr),
293 (STLXRH GPR32:$val, am_noindex:$addr)>;
294 def : Pat<(stlxr_4 (zext GPR32:$val), am_noindex:$addr),
295 (STLXRW GPR32:$val, am_noindex:$addr)>;
296
297 def : Pat<(stlxr_1 (and GPR64:$val, 0xff), am_noindex:$addr),
298 (STLXRB (EXTRACT_SUBREG GPR64:$val, sub_32), am_noindex:$addr)>;
299 def : Pat<(stlxr_2 (and GPR64:$val, 0xffff), am_noindex:$addr),
300 (STLXRH (EXTRACT_SUBREG GPR64:$val, sub_32), am_noindex:$addr)>;
301 def : Pat<(stlxr_4 (and GPR64:$val, 0xffffffff), am_noindex:$addr),
302 (STLXRW (EXTRACT_SUBREG GPR64:$val, sub_32), am_noindex:$addr)>;
337 def : Pat<(stlxr_1 GPR64:$val, GPR64sp:$addr),
338 (STLXRB (EXTRACT_SUBREG GPR64:$val, sub_32), GPR64sp:$addr)>;
339 def : Pat<(stlxr_2 GPR64:$val, GPR64sp:$addr),
340 (STLXRH (EXTRACT_SUBREG GPR64:$val, sub_32), GPR64sp:$addr)>;
341 def : Pat<(stlxr_4 GPR64:$val, GPR64sp:$addr),
342 (STLXRW (EXTRACT_SUBREG GPR64:$val, sub_32), GPR64sp:$addr)>;
343 def : Pat<(stlxr_8 GPR64:$val, GPR64sp:$addr),
344 (STLXRX GPR64:$val, GPR64sp:$addr)>;
345
346 def : Pat<(stlxr_1 (zext (and GPR32:$val, 0xff)), GPR64sp:$addr),
347 (STLXRB GPR32:$val, GPR64sp:$addr)>;
348 def : Pat<(stlxr_2 (zext (and GPR32:$val, 0xffff)), GPR64sp:$addr),
349 (STLXRH GPR32:$val, GPR64sp:$addr)>;
350 def : Pat<(stlxr_4 (zext GPR32:$val), GPR64sp:$addr),
351 (STLXRW GPR32:$val, GPR64sp:$addr)>;
352
353 def : Pat<(stlxr_1 (and GPR64:$val, 0xff), GPR64sp:$addr),
354 (STLXRB (EXTRACT_SUBREG GPR64:$val, sub_32), GPR64sp:$addr)>;
355 def : Pat<(stlxr_2 (and GPR64:$val, 0xffff), GPR64sp:$addr),
356 (STLXRH (EXTRACT_SUBREG GPR64:$val, sub_32), GPR64sp:$addr)>;
357 def : Pat<(stlxr_4 (and GPR64:$val, 0xffffffff), GPR64sp:$addr),
358 (STLXRW (EXTRACT_SUBREG GPR64:$val, sub_32), GPR64sp:$addr)>;
303359
304360
305361 // And clear exclusive.
221221 let ParserMatchClass = SImm9Operand;
222222 }
223223
224 // simm7s4 predicate - True if the immediate is a multiple of 4 in the range
225 // [-256, 252].
226 def SImm7s4Operand : AsmOperandClass {
227 let Name = "SImm7s4";
228 let DiagnosticType = "InvalidMemoryIndexed32SImm7";
229 }
224 // simm7sN predicate - True if the immediate is a multiple of N in the range
225 // [-64 * N, 63 * N].
226 class SImm7Scaled : AsmOperandClass {
227 let Name = "SImm7s" # Scale;
228 let DiagnosticType = "InvalidMemoryIndexed" # Scale # "SImm7";
229 }
230
231 def SImm7s4Operand : SImm7Scaled<4>;
232 def SImm7s8Operand : SImm7Scaled<8>;
233 def SImm7s16Operand : SImm7Scaled<16>;
234
230235 def simm7s4 : Operand {
231236 let ParserMatchClass = SImm7s4Operand;
232237 let PrintMethod = "printImmScale<4>";
233238 }
234239
235 // simm7s8 predicate - True if the immediate is a multiple of 8 in the range
236 // [-512, 504].
237 def SImm7s8Operand : AsmOperandClass {
238 let Name = "SImm7s8";
239 let DiagnosticType = "InvalidMemoryIndexed64SImm7";
240 }
241240 def simm7s8 : Operand {
242241 let ParserMatchClass = SImm7s8Operand;
243242 let PrintMethod = "printImmScale<8>";
244243 }
245244
246 // simm7s16 predicate - True if the immediate is a multiple of 16 in the range
247 // [-1024, 1008].
248 def SImm7s16Operand : AsmOperandClass {
249 let Name = "SImm7s16";
250 let DiagnosticType = "InvalidMemoryIndexed64SImm7";
251 }
252245 def simm7s16 : Operand {
253246 let ParserMatchClass = SImm7s16Operand;
254247 let PrintMethod = "printImmScale<16>";
638631 // {5-3} - extend type
639632 // {2-0} - imm3
640633 def arith_extend : Operand {
641 let PrintMethod = "printExtend";
634 let PrintMethod = "printArithExtend";
642635 let ParserMatchClass = ExtendOperand;
643636 }
644637 def arith_extend64 : Operand {
645 let PrintMethod = "printExtend";
638 let PrintMethod = "printArithExtend";
646639 let ParserMatchClass = ExtendOperand64;
647640 }
648641
649642 // 'extend' that's a lsl of a 64-bit register.
650643 def arith_extendlsl64 : Operand {
651 let PrintMethod = "printExtend";
644 let PrintMethod = "printArithExtend";
652645 let ParserMatchClass = ExtendOperandLSL64;
653646 }
654647
21772170
21782171 // (unsigned immediate)
21792172 // Indexed for 8-bit registers. offset is in range [0,4095].
2180 def MemoryIndexed8Operand : AsmOperandClass {
2181 let Name = "MemoryIndexed8";
2182 let DiagnosticType = "InvalidMemoryIndexed8";
2183 }
2184 def am_indexed8 : Operand,
2185 ComplexPattern {
2186 let PrintMethod = "printAMIndexed<8>";
2173 def am_indexed8 : ComplexPattern;
2174 def am_indexed16 : ComplexPattern;
2175 def am_indexed32 : ComplexPattern;
2176 def am_indexed64 : ComplexPattern;
2177 def am_indexed128 : ComplexPattern;
2178
2179 class UImm12OffsetOperand : AsmOperandClass {
2180 let Name = "UImm12Offset" # Scale;
2181 let RenderMethod = "addUImm12OffsetOperands<" # Scale # ">";
2182 let PredicateMethod = "isUImm12Offset<" # Scale # ">";
2183 let DiagnosticType = "InvalidMemoryIndexed" # Scale;
2184 }
2185
2186 def UImm12OffsetScale1Operand : UImm12OffsetOperand<1>;
2187 def UImm12OffsetScale2Operand : UImm12OffsetOperand<2>;
2188 def UImm12OffsetScale4Operand : UImm12OffsetOperand<4>;
2189 def UImm12OffsetScale8Operand : UImm12OffsetOperand<8>;
2190 def UImm12OffsetScale16Operand : UImm12OffsetOperand<16>;
2191
2192 class uimm12_scaled : Operand {
2193 let ParserMatchClass
2194 = !cast("UImm12OffsetScale" # Scale # "Operand");
21872195 let EncoderMethod
2188 = "getAMIndexed8OpValue";
2189 let ParserMatchClass = MemoryIndexed8Operand;
2190 let MIOperandInfo = (ops GPR64sp:$base, i64imm:$offset);
2191 }
2192
2193 // Indexed for 16-bit registers. offset is multiple of 2 in range [0,8190],
2194 // stored as immval/2 (the 12-bit literal that encodes directly into the insn).
2195 def MemoryIndexed16Operand : AsmOperandClass {
2196 let Name = "MemoryIndexed16";
2197 let DiagnosticType = "InvalidMemoryIndexed16";
2198 }
2199 def am_indexed16 : Operand,
2200 ComplexPattern {
2201 let PrintMethod = "printAMIndexed<16>";
2202 let EncoderMethod
2203 = "getAMIndexed8OpValue";
2204 let ParserMatchClass = MemoryIndexed16Operand;
2205 let MIOperandInfo = (ops GPR64sp:$base, i64imm:$offset);
2206 }
2207
2208 // Indexed for 32-bit registers. offset is multiple of 4 in range [0,16380],
2209 // stored as immval/4 (the 12-bit literal that encodes directly into the insn).
2210 def MemoryIndexed32Operand : AsmOperandClass {
2211 let Name = "MemoryIndexed32";
2212 let DiagnosticType = "InvalidMemoryIndexed32";
2213 }
2214 def am_indexed32 : Operand,
2215 ComplexPattern {
2216 let PrintMethod = "printAMIndexed<32>";
2217 let EncoderMethod
2218 = "getAMIndexed8OpValue";
2219 let ParserMatchClass = MemoryIndexed32Operand;
2220 let MIOperandInfo = (ops GPR64sp:$base, i64imm:$offset);
2221 }
2222
2223 // Indexed for 64-bit registers. offset is multiple of 8 in range [0,32760],
2224 // stored as immval/8 (the 12-bit literal that encodes directly into the insn).
2225 def MemoryIndexed64Operand : AsmOperandClass {
2226 let Name = "MemoryIndexed64";
2227 let DiagnosticType = "InvalidMemoryIndexed64";
2228 }
2229 def am_indexed64 : Operand,
2230 ComplexPattern {
2231 let PrintMethod = "printAMIndexed<64>";
2232 let EncoderMethod
2233 = "getAMIndexed8OpValue";
2234 let ParserMatchClass = MemoryIndexed64Operand;
2235 let MIOperandInfo = (ops GPR64sp:$base, i64imm:$offset);
2236 }
2237
2238 // Indexed for 128-bit registers. offset is multiple of 16 in range [0,65520],
2239 // stored as immval/16 (the 12-bit literal that encodes directly into the insn).
2240 def MemoryIndexed128Operand : AsmOperandClass {
2241 let Name = "MemoryIndexed128";
2242 let DiagnosticType = "InvalidMemoryIndexed128";
2243 }
2244 def am_indexed128 : Operand,
2245 ComplexPattern {
2246 let PrintMethod = "printAMIndexed<128>";
2247 let EncoderMethod
2248 = "getAMIndexed8OpValue";
2249 let ParserMatchClass = MemoryIndexed128Operand;
2250 let MIOperandInfo = (ops GPR64sp:$base, i64imm:$offset);
2251 }
2252
2253 // No offset.
2254 def MemoryNoIndexOperand : AsmOperandClass { let Name = "MemoryNoIndex"; }
2255 def am_noindex : Operand,
2256 ComplexPattern {
2257 let PrintMethod = "printAMNoIndex";
2258 let ParserMatchClass = MemoryNoIndexOperand;
2259 let MIOperandInfo = (ops GPR64sp:$base);
2260 }
2196 = "getLdStUImm12OpValue";
2197 let PrintMethod = "printUImm12Offset<" # Scale # ">";
2198 }
2199
2200 def uimm12s1 : uimm12_scaled<1>;
2201 def uimm12s2 : uimm12_scaled<2>;
2202 def uimm12s4 : uimm12_scaled<4>;
2203 def uimm12s8 : uimm12_scaled<8>;
2204 def uimm12s16 : uimm12_scaled<16>;
22612205
22622206 class BaseLoadStoreUI sz, bit V, bits<2> opc, dag oops, dag iops,
22632207 string asm, list pattern>
2264 : I {
2265 bits<5> dst;
2266
2267 bits<17> addr;
2268 bits<5> base = addr{4-0};
2269 bits<12> offset = addr{16-5};
2208 : I {
2209 bits<5> Rt;
2210
2211 bits<5> Rn;
2212 bits<12> offset;
22702213
22712214 let Inst{31-30} = sz;
22722215 let Inst{29-27} = 0b111;
22742217 let Inst{25-24} = 0b01;
22752218 let Inst{23-22} = opc;
22762219 let Inst{21-10} = offset;
2277 let Inst{9-5} = base;
2278 let Inst{4-0} = dst;
2220 let Inst{9-5} = Rn;
2221 let Inst{4-0} = Rt;
22792222
22802223 let DecoderMethod = "DecodeUnsignedLdStInstruction";
22812224 }
22822225
2283 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
2284 class LoadUI sz, bit V, bits<2> opc, RegisterClass regtype,
2285 Operand indextype, string asm, list pattern>
2286 : BaseLoadStoreUI
2287 (outs regtype:$Rt), (ins indextype:$addr), asm, pattern>,
2288 Sched<[WriteLD]>;
2289
2290 let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
2291 class StoreUI sz, bit V, bits<2> opc, RegisterClass regtype,
2292 Operand indextype, string asm, list pattern>
2293 : BaseLoadStoreUI
2294 (outs), (ins regtype:$Rt, indextype:$addr), asm, pattern>,
2295 Sched<[WriteST]>;
2226 multiclass LoadUI sz, bit V, bits<2> opc, RegisterClass regtype,
2227 Operand indextype, string asm, list pattern> {
2228 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
2229 def ui : BaseLoadStoreUI
2230 (ins GPR64sp:$Rn, indextype:$offset),
2231 asm, pattern>,
2232 Sched<[WriteLD]>;
2233
2234 def : InstAlias
2235 (!cast(NAME # "ui") regtype:$Rt, GPR64sp:$Rn, 0)>;
2236 }
2237
2238 multiclass StoreUI sz, bit V, bits<2> opc, RegisterClass regtype,
2239 Operand indextype, string asm, list pattern> {
2240 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
2241 def ui : BaseLoadStoreUI
2242 (ins regtype:$Rt, GPR64sp:$Rn, indextype:$offset),
2243 asm, pattern>,
2244 Sched<[WriteST]>;
2245
2246 def : InstAlias
2247 (!cast(NAME # "ui") regtype:$Rt, GPR64sp:$Rn, 0)>;
2248 }
22962249
22972250 def PrefetchOperand : AsmOperandClass {
22982251 let Name = "Prefetch";
23062259 let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
23072260 class PrefetchUI sz, bit V, bits<2> opc, string asm, list pat>
23082261 : BaseLoadStoreUI
2309 (outs), (ins prfop:$Rt, am_indexed64:$addr), asm, pat>,
2262 (outs), (ins prfop:$Rt, GPR64sp:$Rn, uimm12s8:$offset),
2263 asm, pat>,
23102264 Sched<[WriteLD]>;
23112265
23122266 //---
23562310 // Load/store register offset
23572311 //---
23582312
2359 class MemROAsmOperand : AsmOperandClass {
2360 let Name = "MemoryRegisterOffset"#sz;
2361 let DiagnosticType = "InvalidMemoryIndexed";
2362 }
2363
2364 def MemROAsmOperand8 : MemROAsmOperand<8>;
2365 def MemROAsmOperand16 : MemROAsmOperand<16>;
2366 def MemROAsmOperand32 : MemROAsmOperand<32>;
2367 def MemROAsmOperand64 : MemROAsmOperand<64>;
2368 def MemROAsmOperand128 : MemROAsmOperand<128>;
2369
2370 class ro_indexed : Operand { // ComplexPattern<...>
2371 let PrintMethod = "printMemoryRegOffset<" # sz # ">";
2372 let MIOperandInfo = (ops GPR64sp:$base, GPR64:$offset, i32imm:$extend);
2373 }
2374
2375 def ro_indexed8 : ro_indexed<8>, ComplexPattern {
2376 let ParserMatchClass = MemROAsmOperand8;
2377 }
2378
2379 def ro_indexed16 : ro_indexed<16>, ComplexPattern {
2380 let ParserMatchClass = MemROAsmOperand16;
2381 }
2382
2383 def ro_indexed32 : ro_indexed<32>, ComplexPattern {
2384 let ParserMatchClass = MemROAsmOperand32;
2385 }
2386
2387 def ro_indexed64 : ro_indexed<64>, ComplexPattern {
2388 let ParserMatchClass = MemROAsmOperand64;
2389 }
2390
2391 def ro_indexed128 : ro_indexed<128>, ComplexPattern {
2392 let ParserMatchClass = MemROAsmOperand128;
2393 }
2313 def ro_Xindexed8 : ComplexPattern", []>;
2314 def ro_Xindexed16 : ComplexPattern", []>;
2315 def ro_Xindexed32 : ComplexPattern", []>;
2316 def ro_Xindexed64 : ComplexPattern", []>;
2317 def ro_Xindexed128 : ComplexPattern", []>;
2318
2319 def ro_Windexed8 : ComplexPattern", []>;
2320 def ro_Windexed16 : ComplexPattern", []>;
2321 def ro_Windexed32 : ComplexPattern", []>;
2322 def ro_Windexed64 : ComplexPattern", []>;
2323 def ro_Windexed128 : ComplexPattern", []>;
2324
2325 class MemExtendOperand : AsmOperandClass {
2326 let Name = "Mem" # Reg # "Extend" # Width;
2327 let PredicateMethod = "isMem" # Reg # "Extend<" # Width # ">";
2328 let RenderMethod = "addMemExtendOperands";
2329 let DiagnosticType = "InvalidMemory" # Reg # "Extend" # Width;
2330 }
2331
2332 def MemWExtend8Operand : MemExtendOperand<"W", 8> {
2333 // The address "[x0, x1, lsl #0]" actually maps to the variant which performs
2334 // the trivial shift.
2335 let RenderMethod = "addMemExtend8Operands";
2336 }
2337 def MemWExtend16Operand : MemExtendOperand<"W", 16>;
2338 def MemWExtend32Operand : MemExtendOperand<"W", 32>;
2339 def MemWExtend64Operand : MemExtendOperand<"W", 64>;
2340 def MemWExtend128Operand : MemExtendOperand<"W", 128>;
2341
2342 def MemXExtend8Operand : MemExtendOperand<"X", 8> {
2343 // The address "[x0, x1, lsl #0]" actually maps to the variant which performs
2344 // the trivial shift.
2345 let RenderMethod = "addMemExtend8Operands";
2346 }
2347 def MemXExtend16Operand : MemExtendOperand<"X", 16>;
2348 def MemXExtend32Operand : MemExtendOperand<"X", 32>;
2349 def MemXExtend64Operand : MemExtendOperand<"X", 64>;
2350 def MemXExtend128Operand : MemExtendOperand<"X", 128>;
2351
2352 class ro_extend
2353 : Operand {
2354 let ParserMatchClass = ParserClass;
2355 let PrintMethod = "printMemExtend<'" # Reg # "', " # Width # ">";
2356 let DecoderMethod = "DecodeMemExtend";
2357 let EncoderMethod = "getMemExtendOpValue";
2358 let MIOperandInfo = (ops i32imm:$signed, i32imm:$doshift);
2359 }
2360
2361 def ro_Wextend8 : ro_extend;
2362 def ro_Wextend16 : ro_extend;
2363 def ro_Wextend32 : ro_extend;
2364 def ro_Wextend64 : ro_extend;
2365 def ro_Wextend128 : ro_extend;
2366
2367 def ro_Xextend8 : ro_extend;
2368 def ro_Xextend16 : ro_extend;
2369 def ro_Xextend32 : ro_extend;
2370 def ro_Xextend64 : ro_extend;
2371 def ro_Xextend128 : ro_extend;
2372
2373 class ROAddrMode
2374 Operand wextend, Operand xextend> {
2375 // CodeGen-level pattern covering the entire addressing mode.
2376 ComplexPattern Wpat = windex;
2377 ComplexPattern Xpat = xindex;
2378
2379 // Asm-level Operand covering the valid "uxtw #3" style syntax.
2380 Operand Wext = wextend;
2381 Operand Xext = xextend;
2382 }
2383
2384 def ro8 : ROAddrMode;
2385 def ro16 : ROAddrMode;
2386 def ro32 : ROAddrMode;
2387 def ro64 : ROAddrMode;
2388 def ro128 : ROAddrMode
2389 ro_Xextend128>;
23942390
23952391 class LoadStore8RO sz, bit V, bits<2> opc, RegisterClass regtype,
23962392 string asm, dag ins, dag outs, list pat>
2397 : I {
2398 // The operands are in order to match the 'addr' MI operands, so we
2399 // don't need an encoder method and by-name matching. Just use the default
2400 // in-order handling. Since we're using by-order, make sure the names
2401 // do not match.
2402 bits<5> dst;
2403 bits<5> base;
2404 bits<5> offset;
2405 bits<4> extend;
2393 : I {
2394 bits<5> Rt;
2395 bits<5> Rn;
2396 bits<5> Rm;
2397 bits<2> extend;
24062398 let Inst{31-30} = sz;
24072399 let Inst{29-27} = 0b111;
24082400 let Inst{26} = V;
24092401 let Inst{25-24} = 0b00;
24102402 let Inst{23-22} = opc;
24112403 let Inst{21} = 1;
2412 let Inst{20-16} = offset;
2413 let Inst{15-13} = extend{3-1};
2414
2415 let Inst{12} = extend{0};
2404 let Inst{20-16} = Rm;
2405 let Inst{15} = extend{1}; // sign extend Rm?
2406 let Inst{14} = 1;
2407 let Inst{12} = extend{0}; // do shift?
24162408 let Inst{11-10} = 0b10;
2417 let Inst{9-5} = base;
2418 let Inst{4-0} = dst;
2419
2420 let DecoderMethod = "DecodeRegOffsetLdStInstruction";
2421 }
2422
2423 class Load8RO sz, bit V, bits<2> opc, RegisterClass regtype,
2424 string asm, list pat>
2425 : LoadStore8RO
2426 (outs regtype:$Rt), (ins ro_indexed8:$addr), pat>,
2427 Sched<[WriteLDIdx, ReadAdrBase]>;
2428
2429 class Store8RO sz, bit V, bits<2> opc, RegisterClass regtype,
2430 string asm, list pat>
2431 : LoadStore8RO
2432 (outs), (ins regtype:$Rt, ro_indexed8:$addr), pat>,
2433 Sched<[WriteSTIdx, ReadAdrBase]>;
2409 let Inst{9-5} = Rn;
2410 let Inst{4-0} = Rt;
2411 }
2412
2413 class ROInstAlias
2414 : InstAlias
2415 (INST regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, 0, 0)>;
2416
2417 multiclass Load8RO sz, bit V, bits<2> opc, RegisterClass regtype,
2418 string asm, ValueType Ty, SDPatternOperator loadop> {
2419 let AddedComplexity = 10 in
2420 def roW : LoadStore8RO
2421 (outs regtype:$Rt),
2422 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend8:$extend),
2423 [(set (Ty regtype:$Rt),
2424 (loadop (ro_Windexed8 GPR64sp:$Rn, GPR32:$Rm,
2425 ro_Wextend8:$extend)))]>,
2426 Sched<[WriteLDIdx, ReadAdrBase]> {
2427 let Inst{13} = 0b0;
2428 }
2429
2430 let AddedComplexity = 10 in
2431 def roX : LoadStore8RO
2432 (outs regtype:$Rt),
2433 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend8:$extend),
2434 [(set (Ty regtype:$Rt),
2435 (loadop (ro_Xindexed8 GPR64sp:$Rn, GPR64:$Rm,
2436 ro_Xextend8:$extend)))]>,
2437 Sched<[WriteLDIdx, ReadAdrBase]> {
2438 let Inst{13} = 0b1;
2439 }
2440
2441 def : ROInstAlias(NAME # "roX")>;
2442 }
2443
2444 multiclass Store8RO sz, bit V, bits<2> opc, RegisterClass regtype,
2445 string asm, ValueType Ty, SDPatternOperator storeop> {
2446 let AddedComplexity = 10 in
2447 def roW : LoadStore8RO
2448 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend8:$extend),
2449 [(storeop (Ty regtype:$Rt),
2450 (ro_Windexed8 GPR64sp:$Rn, GPR32:$Rm,
2451 ro_Wextend8:$extend))]>,
2452 Sched<[WriteSTIdx, ReadAdrBase]> {
2453 let Inst{13} = 0b0;
2454 }
2455
2456 let AddedComplexity = 10 in
2457 def roX : LoadStore8RO
2458 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend8:$extend),
2459 [(storeop (Ty regtype:$Rt),
2460 (ro_Xindexed8 GPR64sp:$Rn, GPR64:$Rm,
2461 ro_Xextend8:$extend))]>,
2462 Sched<[WriteSTIdx, ReadAdrBase]> {
2463 let Inst{13} = 0b1;
2464 }
2465
2466 def : ROInstAlias(NAME # "roX")>;
2467 }
24342468
24352469 class LoadStore16RO sz, bit V, bits<2> opc, RegisterClass regtype,
24362470 string asm, dag ins, dag outs, list pat>
2437 : I {
2438 // The operands are in order to match the 'addr' MI operands, so we
2439 // don't need an encoder method and by-name matching. Just use the default
2440 // in-order handling. Since we're using by-order, make sure the names
2441 // do not match.
2442 bits<5> dst;
2443 bits<5> base;
2444 bits<5> offset;
2445 bits<4> extend;
2471 : I {
2472 bits<5> Rt;
2473 bits<5> Rn;
2474 bits<5> Rm;
2475 bits<2> extend;
24462476 let Inst{31-30} = sz;
24472477 let Inst{29-27} = 0b111;
24482478 let Inst{26} = V;
24492479 let Inst{25-24} = 0b00;
24502480 let Inst{23-22} = opc;
24512481 let Inst{21} = 1;
2452 let Inst{20-16} = offset;
2453 let Inst{15-13} = extend{3-1};
2454
2455 let Inst{12} = extend{0};
2482 let Inst{20-16} = Rm;
2483 let Inst{15} = extend{1}; // sign extend Rm?
2484 let Inst{14} = 1;
2485 let Inst{12} = extend{0}; // do shift?
24562486 let Inst{11-10} = 0b10;
2457 let Inst{9-5} = base;
2458 let Inst{4-0} = dst;
2459
2460 let DecoderMethod = "DecodeRegOffsetLdStInstruction";
2461 }
2462
2463 class Load16RO sz, bit V, bits<2> opc, RegisterClass regtype,
2464 string asm, list pat>
2465 : LoadStore16RO
2466 (outs regtype:$Rt), (ins ro_indexed16:$addr), pat>,
2467 Sched<[WriteLDIdx, ReadAdrBase]>;
2468
2469 class Store16RO sz, bit V, bits<2> opc, RegisterClass regtype,
2470 string asm, list pat>
2471 : LoadStore16RO
2472 (outs), (ins regtype:$Rt, ro_indexed16:$addr), pat>,
2473 Sched<[WriteSTIdx, ReadAdrBase]>;
2487 let Inst{9-5} = Rn;
2488 let Inst{4-0} = Rt;
2489 }
2490
2491 multiclass Load16RO sz, bit V, bits<2> opc, RegisterClass regtype,
2492 string asm, ValueType Ty, SDPatternOperator loadop> {
2493 let AddedComplexity = 10 in
2494 def roW : LoadStore16RO
2495 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend16:$extend),
2496 [(set (Ty regtype:$Rt),
2497 (loadop (ro_Windexed16 GPR64sp:$Rn, GPR32:$Rm,
2498 ro_Wextend16:$extend)))]>,
2499 Sched<[WriteLDIdx, ReadAdrBase]> {
2500 let Inst{13} = 0b0;
2501 }
2502
2503 let AddedComplexity = 10 in
2504 def roX : LoadStore16RO
2505 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend16:$extend),
2506 [(set (Ty regtype:$Rt),
2507 (loadop (ro_Xindexed16 GPR64sp:$Rn, GPR64:$Rm,
2508 ro_Xextend16:$extend)))]>,
2509 Sched<[WriteLDIdx, ReadAdrBase]> {
2510 let Inst{13} = 0b1;
2511 }
2512
2513 def : ROInstAlias(NAME # "roX")>;
2514 }
2515
2516 multiclass Store16RO sz, bit V, bits<2> opc, RegisterClass regtype,
2517 string asm, ValueType Ty, SDPatternOperator storeop> {
2518 let AddedComplexity = 10 in
2519 def roW : LoadStore16RO
2520 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend16:$extend),
2521 [(storeop (Ty regtype:$Rt),
2522 (ro_Windexed16 GPR64sp:$Rn, GPR32:$Rm,
2523 ro_Wextend16:$extend))]>,
2524 Sched<[WriteSTIdx, ReadAdrBase]> {
2525 let Inst{13} = 0b0;
2526 }
2527
2528 let AddedComplexity = 10 in
2529 def roX : LoadStore16RO
2530 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend16:$extend),
2531 [(storeop (Ty regtype:$Rt),
2532 (ro_Xindexed16 GPR64sp:$Rn, GPR64:$Rm,
2533 ro_Xextend16:$extend))]>,
2534 Sched<[WriteSTIdx, ReadAdrBase]> {
2535 let Inst{13} = 0b1;
2536 }
2537
2538 def : ROInstAlias(NAME # "roX")>;
2539 }
24742540
24752541 class LoadStore32RO sz, bit V, bits<2> opc, RegisterClass regtype,
24762542 string asm, dag ins, dag outs, list pat>
2477 : I {
2478 // The operands are in order to match the 'addr' MI operands, so we
2479 // don't need an encoder method and by-name matching. Just use the default
2480 // in-order handling. Since we're using by-order, make sure the names
2481 // do not match.
2482 bits<5> dst;
2483 bits<5> base;
2484 bits<5> offset;
2485 bits<4> extend;
2543 : I {
2544 bits<5> Rt;
2545 bits<5> Rn;
2546 bits<5> Rm;
2547 bits<2> extend;
24862548 let Inst{31-30} = sz;
24872549 let Inst{29-27} = 0b111;
24882550 let Inst{26} = V;
24892551 let Inst{25-24} = 0b00;
24902552 let Inst{23-22} = opc;
24912553 let Inst{21} = 1;
2492 let Inst{20-16} = offset;
2493 let Inst{15-13} = extend{3-1};
2494
2495 let Inst{12} = extend{0};
2554 let Inst{20-16} = Rm;
2555 let Inst{15} = extend{1}; // sign extend Rm?
2556 let Inst{14} = 1;
2557 let Inst{12} = extend{0}; // do shift?
24962558 let Inst{11-10} = 0b10;
2497 let Inst{9-5} = base;
2498 let Inst{4-0} = dst;
2499
2500 let DecoderMethod = "DecodeRegOffsetLdStInstruction";
2501 }
2502
2503 class Load32RO sz, bit V, bits<2> opc, RegisterClass regtype,
2504 string asm, list pat>
2505 : LoadStore32RO
2506 (outs regtype:$Rt), (ins ro_indexed32:$addr), pat>,
2507 Sched<[WriteLDIdx, ReadAdrBase]>;
2508
2509 class Store32RO sz, bit V, bits<2> opc, RegisterClass regtype,
2510 string asm, list pat>
2511 : LoadStore32RO
2512 (outs), (ins regtype:$Rt, ro_indexed32:$addr), pat>,
2513 Sched<[WriteSTIdx, ReadAdrBase]>;
2559 let Inst{9-5} = Rn;
2560 let Inst{4-0} = Rt;
2561 }
2562
2563 multiclass Load32RO sz, bit V, bits<2> opc, RegisterClass regtype,
2564 string asm, ValueType Ty, SDPatternOperator loadop> {
2565 let AddedComplexity = 10 in
2566 def roW : LoadStore32RO
2567 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend32:$extend),
2568 [(set (Ty regtype:$Rt),
2569 (loadop (ro_Windexed32 GPR64sp:$Rn, GPR32:$Rm,
2570 ro_Wextend32:$extend)))]>,
2571 Sched<[WriteLDIdx, ReadAdrBase]> {
2572 let Inst{13} = 0b0;
2573 }
2574
2575 let AddedComplexity = 10 in
2576 def roX : LoadStore32RO
2577 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend32:$extend),
2578 [(set (Ty regtype:$Rt),
2579 (loadop (ro_Xindexed32 GPR64sp:$Rn, GPR64:$Rm,
2580 ro_Xextend32:$extend)))]>,
2581 Sched<[WriteLDIdx, ReadAdrBase]> {
2582 let Inst{13} = 0b1;
2583 }
2584
2585 def : ROInstAlias(NAME # "roX")>;
2586 }
2587
2588 multiclass Store32RO sz, bit V, bits<2> opc, RegisterClass regtype,
2589 string asm, ValueType Ty, SDPatternOperator storeop> {
2590 let AddedComplexity = 10 in
2591 def roW : LoadStore32RO
2592 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend32:$extend),
2593 [(storeop (Ty regtype:$Rt),
2594 (ro_Windexed32 GPR64sp:$Rn, GPR32:$Rm,
2595 ro_Wextend32:$extend))]>,
2596 Sched<[WriteSTIdx, ReadAdrBase]> {
2597 let Inst{13} = 0b0;
2598 }
2599
2600 let AddedComplexity = 10 in
2601 def roX : LoadStore32RO
2602 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend32:$extend),
2603 [(storeop (Ty regtype:$Rt),
2604 (ro_Xindexed32 GPR64sp:$Rn, GPR64:$Rm,
2605 ro_Xextend32:$extend))]>,
2606 Sched<[WriteSTIdx, ReadAdrBase]> {
2607 let Inst{13} = 0b1;
2608 }
2609
2610 def : ROInstAlias(NAME # "roX")>;
2611 }
25142612
25152613 class LoadStore64RO sz, bit V, bits<2> opc, RegisterClass regtype,
25162614 string asm, dag ins, dag outs, list pat>
2517 : I {
2518 // The operands are in order to match the 'addr' MI operands, so we
2519 // don't need an encoder method and by-name matching. Just use the default
2520 // in-order handling. Since we're using by-order, make sure the names
2521 // do not match.
2522 bits<5> dst;
2523 bits<5> base;
2524 bits<5> offset;
2525 bits<4> extend;
2615 : I {
2616 bits<5> Rt;
2617 bits<5> Rn;
2618 bits<5> Rm;
2619 bits<2> extend;
25262620 let Inst{31-30} = sz;
25272621 let Inst{29-27} = 0b111;
25282622 let Inst{26} = V;
25292623 let Inst{25-24} = 0b00;
25302624 let Inst{23-22} = opc;
25312625 let Inst{21} = 1;
2532 let Inst{20-16} = offset;
2533 let Inst{15-13} = extend{3-1};
2534
2535 let Inst{12} = extend{0};
2626 let Inst{20-16} = Rm;
2627 let Inst{15} = extend{1}; // sign extend Rm?
2628 let Inst{14} = 1;
2629 let Inst{12} = extend{0}; // do shift?
25362630 let Inst{11-10} = 0b10;
2537 let Inst{9-5} = base;
2538 let Inst{4-0} = dst;
2539
2540 let DecoderMethod = "DecodeRegOffsetLdStInstruction";
2541 }
2542
2543 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
2544 class Load64RO sz, bit V, bits<2> opc, RegisterClass regtype,
2545 string asm, list pat>
2546 : LoadStore64RO
2547 (outs regtype:$Rt), (ins ro_indexed64:$addr), pat>,
2548 Sched<[WriteLDIdx, ReadAdrBase]>;
2549
2550 let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
2551 class Store64RO sz, bit V, bits<2> opc, RegisterClass regtype,
2552 string asm, list pat>
2553 : LoadStore64RO
2554 (outs), (ins regtype:$Rt, ro_indexed64:$addr), pat>,
2555 Sched<[WriteSTIdx, ReadAdrBase]>;
2556
2631 let Inst{9-5} = Rn;
2632 let Inst{4-0} = Rt;
2633 }
2634
2635 multiclass Load64RO sz, bit V, bits<2> opc, RegisterClass regtype,
2636 string asm, ValueType Ty, SDPatternOperator loadop> {
2637 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
2638 def roW : LoadStore64RO
2639 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend),
2640 [(set (Ty regtype:$Rt),
2641 (loadop (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm,
2642 ro_Wextend64:$extend)))]>,
2643 Sched<[WriteLDIdx, ReadAdrBase]> {
2644 let Inst{13} = 0b0;
2645 }
2646
2647 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
2648 def roX : LoadStore64RO
2649 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend),
2650 [(set (Ty regtype:$Rt),
2651 (loadop (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm,
2652 ro_Xextend64:$extend)))]>,
2653 Sched<[WriteLDIdx, ReadAdrBase]> {
2654 let Inst{13} = 0b1;
2655 }
2656
2657 def : ROInstAlias(NAME # "roX")>;
2658 }
2659
2660 multiclass Store64RO sz, bit V, bits<2> opc, RegisterClass regtype,
2661 string asm, ValueType Ty, SDPatternOperator storeop> {
2662 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
2663 def roW : LoadStore64RO
2664 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend),
2665 [(storeop (Ty regtype:$Rt),
2666 (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm,
2667 ro_Wextend64:$extend))]>,
2668 Sched<[WriteSTIdx, ReadAdrBase]> {
2669 let Inst{13} = 0b0;
2670 }
2671
2672 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
2673 def roX : LoadStore64RO
2674 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend),
2675 [(storeop (Ty regtype:$Rt),
2676 (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm,
2677 ro_Xextend64:$extend))]>,
2678 Sched<[WriteSTIdx, ReadAdrBase]> {
2679 let Inst{13} = 0b1;
2680 }
2681
2682 def : ROInstAlias(NAME # "roX")>;
2683 }
25572684
25582685 class LoadStore128RO sz, bit V, bits<2> opc, RegisterClass regtype,
25592686 string asm, dag ins, dag outs, list pat>
2560 : I {
2561 // The operands are in order to match the 'addr' MI operands, so we
2562 // don't need an encoder method and by-name matching. Just use the default
2563 // in-order handling. Since we're using by-order, make sure the names
2564 // do not match.
2565 bits<5> dst;
2566 bits<5> base;
2567 bits<5> offset;
2568 bits<4> extend;
2687 : I {
2688 bits<5> Rt;
2689 bits<5> Rn;
2690 bits<5> Rm;
2691 bits<2> extend;
25692692 let Inst{31-30} = sz;
25702693 let Inst{29-27} = 0b111;
25712694 let Inst{26} = V;
25722695 let Inst{25-24} = 0b00;
25732696 let Inst{23-22} = opc;
25742697 let Inst{21} = 1;
2575 let Inst{20-16} = offset;
2576 let Inst{15-13} = extend{3-1};
2577
2578 let Inst{12} = extend{0};
2698 let Inst{20-16} = Rm;
2699 let Inst{15} = extend{1}; // sign extend Rm?
2700 let Inst{14} = 1;
2701 let Inst{12} = extend{0}; // do shift?
25792702 let Inst{11-10} = 0b10;
2580 let Inst{9-5} = base;
2581 let Inst{4-0} = dst;
2582
2583 let DecoderMethod = "DecodeRegOffsetLdStInstruction";
2584 }
2585
2586 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
2587 class Load128RO sz, bit V, bits<2> opc, RegisterClass regtype,
2588 string asm, list pat>
2589 : LoadStore128RO
2590 (outs regtype:$Rt), (ins ro_indexed128:$addr), pat>,
2591 Sched<[WriteLDIdx, ReadAdrBase]>;
2592
2593 let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
2594 class Store128RO sz, bit V, bits<2> opc, RegisterClass regtype,
2595 string asm, list pat>
2596 : LoadStore128RO
2597 (outs), (ins regtype:$Rt, ro_indexed128:$addr), pat>,
2598 Sched<[WriteSTIdx, ReadAdrBase]>;
2703 let Inst{9-5} = Rn;
2704 let Inst{4-0} = Rt;
2705 }
2706
2707 multiclass Load128RO sz, bit V, bits<2> opc, RegisterClass regtype,
2708 string asm, ValueType Ty, SDPatternOperator loadop> {
2709 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
2710 def roW : LoadStore128RO
2711 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend128:$extend),
2712 [(set (Ty regtype:$Rt),
2713 (loadop (ro_Windexed128 GPR64sp:$Rn, GPR32:$Rm,
2714 ro_Wextend128:$extend)))]>,
2715 Sched<[WriteLDIdx, ReadAdrBase]> {
2716 let Inst{13} = 0b0;
2717 }
2718
2719 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
2720 def roX : LoadStore128RO
2721 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend128:$extend),
2722 [(set (Ty regtype:$Rt),
2723 (loadop (ro_Xindexed128 GPR64sp:$Rn, GPR64:$Rm,
2724 ro_Xextend128:$extend)))]>,
2725 Sched<[WriteLDIdx, ReadAdrBase]> {
2726 let Inst{13} = 0b1;
2727 }
2728
2729 def : ROInstAlias(NAME # "roX")>;
2730 }
2731
2732 multiclass Store128RO sz, bit V, bits<2> opc, RegisterClass regtype,
2733 string asm, ValueType Ty, SDPatternOperator storeop> {
2734 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
2735 def roW : LoadStore128RO
2736 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend128:$extend),
2737 [(storeop (Ty regtype:$Rt),
2738 (ro_Windexed128 GPR64sp:$Rn, GPR32:$Rm,
2739 ro_Wextend128:$extend))]>,
2740 Sched<[WriteSTIdx, ReadAdrBase]> {
2741 let Inst{13} = 0b0;
2742 }
2743
2744 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
2745 def roX : LoadStore128RO
2746 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend128:$extend),
2747 [(storeop (Ty regtype:$Rt),
2748 (ro_Xindexed128 GPR64sp:$Rn, GPR64:$Rm,
2749 ro_Xextend128:$extend))]>,
2750 Sched<[WriteSTIdx, ReadAdrBase]> {
2751 let Inst{13} = 0b1;
2752 }
2753
2754 def : ROInstAlias(NAME # "roX")>;
2755 }
25992756
26002757 let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
2601 class PrefetchRO sz, bit V, bits<2> opc, string asm, list pat>
2602 : I<(outs), (ins prfop:$Rt, ro_indexed64:$addr), asm,
2603 "\t$Rt, $addr", "", pat>,
2758 class BasePrefetchRO sz, bit V, bits<2> opc, dag outs, dag ins,
2759 string asm, list pat>
2760 : I,
26042761 Sched<[WriteLD]> {
2605 // The operands are in order to match the 'addr' MI operands, so we
2606 // don't need an encoder method and by-name matching. Just use the default
2607 // in-order handling. Since we're using by-order, make sure the names
2608 // do not match.
2609 bits<5> dst;
2610 bits<5> base;
2611 bits<5> offset;
2612 bits<4> extend;
2762 bits<5> Rt;
2763 bits<5> Rn;
2764 bits<5> Rm;
2765 bits<2> extend;
26132766 let Inst{31-30} = sz;
26142767 let Inst{29-27} = 0b111;
26152768 let Inst{26} = V;
26162769 let Inst{25-24} = 0b00;
26172770 let Inst{23-22} = opc;
26182771 let Inst{21} = 1;
2619 let Inst{20-16} = offset;
2620 let Inst{15-13} = extend{3-1};
2621
2622 let Inst{12} = extend{0};
2772 let Inst{20-16} = Rm;
2773 let Inst{15} = extend{1}; // sign extend Rm?
2774 let Inst{14} = 1;
2775 let Inst{12} = extend{0}; // do shift?
26232776 let Inst{11-10} = 0b10;
2624 let Inst{9-5} = base;
2625 let Inst{4-0} = dst;
2626
2627 let DecoderMethod = "DecodeRegOffsetLdStInstruction";
2777 let Inst{9-5} = Rn;
2778 let Inst{4-0} = Rt;
2779 }
2780
2781 multiclass PrefetchRO sz, bit V, bits<2> opc, string asm> {
2782 def roW : BasePrefetchRO
2783 (ins prfop:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend),
2784 asm, [(ARM64Prefetch imm:$Rt,
2785 (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm,
2786 ro_Wextend64:$extend))]> {
2787 let Inst{13} = 0b0;
2788 }
2789
2790 def roX : BasePrefetchRO
2791 (ins prfop:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend),
2792 asm, [(ARM64Prefetch imm:$Rt,
2793 (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm,
2794 ro_Xextend64:$extend))]> {
2795 let Inst{13} = 0b1;
2796 }
2797
2798 def : InstAlias<"prfm $Rt, [$Rn, $Rm]",
2799 (!cast(NAME # "roX") prfop:$Rt,
2800 GPR64sp:$Rn, GPR64:$Rm, 0, 0)>;
26282801 }
26292802
26302803 //---
26312804 // Load/store unscaled immediate
26322805 //---
26332806
2634 def MemoryUnscaledOperand : AsmOperandClass {
2635 let Name = "MemoryUnscaled";
2636 let DiagnosticType = "InvalidMemoryIndexedSImm9";
2637 }
2638 class am_unscaled_operand : Operand {
2639 let PrintMethod = "printAMIndexed<8>";
2640 let ParserMatchClass = MemoryUnscaledOperand;
2641 let MIOperandInfo = (ops GPR64sp:$base, i64imm:$offset);
2642 }
2643 class am_unscaled_wb_operand : Operand {
2644 let PrintMethod = "printAMIndexedWB<8>";
2645 let ParserMatchClass = MemoryUnscaledOperand;
2646 let MIOperandInfo = (ops GPR64sp:$base, i64imm:$offset);
2647 }
2648 def am_unscaled : am_unscaled_operand;
2649 def am_unscaled_wb: am_unscaled_wb_operand;
2650 def am_unscaled8 : am_unscaled_operand,
2651 ComplexPattern;
2652 def am_unscaled16 : am_unscaled_operand,
2653 ComplexPattern;
2654 def am_unscaled32 : am_unscaled_operand,
2655 ComplexPattern;
2656 def am_unscaled64 : am_unscaled_operand,
2657 ComplexPattern;
2658 def am_unscaled128 : am_unscaled_operand,
2659 ComplexPattern8", []>;
2807 def am_unscaled8 : ComplexPattern8", []>;
2808 def am_unscaled16 : ComplexPattern;
2809 def am_unscaled32 : ComplexPattern;
2810 def am_unscaled64 : ComplexPattern;
2811 def am_unscaled128 :ComplexPattern;
26602812
26612813 class BaseLoadStoreUnscale sz, bit V, bits<2> opc, dag oops, dag iops,
26622814 string asm, list pattern>
2663 : I {
2664 // The operands are in order to match the 'addr' MI operands, so we
2665 // don't need an encoder method and by-name matching. Just use the default
2666 // in-order handling. Since we're using by-order, make sure the names
2667 // do not match.
2668 bits<5> dst;
2669 bits<5> base;
2815 : I {
2816 bits<5> Rt;
2817 bits<5> Rn;
26702818 bits<9> offset;
26712819 let Inst{31-30} = sz;
26722820 let Inst{29-27} = 0b111;
26762824 let Inst{21} = 0;
26772825 let Inst{20-12} = offset;
26782826 let Inst{11-10} = 0b00;
2679 let Inst{9-5} = base;
2680 let Inst{4-0} = dst;
2827 let Inst{9-5} = Rn;
2828 let Inst{4-0} = Rt;
26812829
26822830 let DecoderMethod = "DecodeSignedLdStInstruction";
26832831 }
26842832
2685 let AddedComplexity = 1 in // try this before LoadUI
2686 class LoadUnscaled sz, bit V, bits<2> opc, RegisterClass regtype,
2687 Operand amtype, string asm, list pattern>
2688 : BaseLoadStoreUnscale
2689 (ins amtype:$addr), asm, pattern>,
2690 Sched<[WriteLD]>;
2691
2692 let AddedComplexity = 1 in // try this before StoreUI
2693 class StoreUnscaled sz, bit V, bits<2> opc, RegisterClass regtype,
2694 Operand amtype, string asm, list pattern>
2695 : BaseLoadStoreUnscale
2696 (ins regtype:$Rt, amtype:$addr), asm, pattern>,
2697 Sched<[WriteST]>;
2698
2699 let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
2700 class PrefetchUnscaled sz, bit V, bits<2> opc, string asm, list pat>
2701 : BaseLoadStoreUnscale
2702 (ins prfop:$Rt, am_unscaled:$addr), asm, pat>,
2703 Sched<[WriteLD]>;
2833 multiclass LoadUnscaled sz, bit V, bits<2> opc, RegisterClass regtype,
2834 string asm, list pattern> {
2835 let AddedComplexity = 1 in // try this before LoadUI
2836 def i : BaseLoadStoreUnscale
2837 (ins GPR64sp:$Rn, simm9:$offset), asm, pattern>,
2838 Sched<[WriteLD]>;
2839
2840 def : InstAlias
2841 (!cast(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>;
2842 }
2843
2844 multiclass StoreUnscaled sz, bit V, bits<2> opc, RegisterClass regtype,
2845 string asm, list pattern> {
2846 let AddedComplexity = 1 in // try this before StoreUI
2847 def i : BaseLoadStoreUnscale
2848 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset),
2849 asm, pattern>,
2850 Sched<[WriteST]>;
2851
2852 def : InstAlias
2853 (!cast(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>;
2854 }
2855
2856 multiclass PrefetchUnscaled sz, bit V, bits<2> opc, string asm,
2857 list pat> {
2858 let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
2859 def i : BaseLoadStoreUnscale
2860 (ins prfop:$Rt, GPR64sp:$Rn, simm9:$offset),
2861 asm, pat>,
2862 Sched<[WriteLD]>;
2863
2864 def : InstAlias
2865 (!cast(NAME # "i") prfop:$Rt, GPR64sp:$Rn, 0)>;
2866 }
27042867
27052868 //---
27062869 // Load/store unscaled immediate, unprivileged
27082871
27092872 class BaseLoadStoreUnprivileged sz, bit V, bits<2> opc,
27102873 dag oops, dag iops, string asm>
2711 : I {
2712 // The operands are in order to match the 'addr' MI operands, so we
2713 // don't need an encoder method and by-name matching. Just use the default
2714 // in-order handling. Since we're using by-order, make sure the names
2715 // do not match.
2716 bits<5> dst;
2717 bits<5> base;
2874 : I {
2875 bits<5> Rt;
2876 bits<5> Rn;
27182877 bits<9> offset;
27192878 let Inst{31-30} = sz;
27202879 let Inst{29-27} = 0b111;
27242883 let Inst{21} = 0;
27252884 let Inst{20-12} = offset;
27262885 let Inst{11-10} = 0b10;
2727 let Inst{9-5} = base;
2728 let Inst{4-0} = dst;
2886 let Inst{9-5} = Rn;
2887 let Inst{4-0} = Rt;
27292888
27302889 let DecoderMethod = "DecodeSignedLdStInstruction";
27312890 }
27322891
2733 let mayStore = 0, mayLoad = 1, hasSideEffects = 0 in {
2734 class LoadUnprivileged sz, bit V, bits<2> opc, RegisterClass regtype,
2735 string asm>
2736 : BaseLoadStoreUnprivileged
2737 (outs regtype:$Rt), (ins am_unscaled:$addr), asm>,
2738 Sched<[WriteLD]>;
2739 }
2740
2741 let mayStore = 1, mayLoad = 0, hasSideEffects = 0 in {
2742 class StoreUnprivileged sz, bit V, bits<2> opc, RegisterClass regtype,
2743 string asm>
2744 : BaseLoadStoreUnprivileged
2745 (outs), (ins regtype:$Rt, am_unscaled:$addr), asm>,
2746 Sched<[WriteST]>;
2892 multiclass LoadUnprivileged sz, bit V, bits<2> opc,
2893 RegisterClass regtype, string asm> {
2894 let mayStore = 0, mayLoad = 1, hasSideEffects = 0 in
2895 def i : BaseLoadStoreUnprivileged
2896 (ins GPR64sp:$Rn, simm9:$offset), asm>,
2897 Sched<[WriteLD]>;
2898
2899 def : InstAlias
2900 (!cast(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>;
2901 }
2902
2903 multiclass StoreUnprivileged sz, bit V, bits<2> opc,
2904 RegisterClass regtype, string asm> {
2905 let mayStore = 1, mayLoad = 0, hasSideEffects = 0 in
2906 def i : BaseLoadStoreUnprivileged
2907 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset),
2908 asm>,
2909 Sched<[WriteST]>;
2910
2911 def : InstAlias
2912 (!cast(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>;
27472913 }
27482914
27492915 //---
27522918
27532919 class BaseLoadStorePreIdx sz, bit V, bits<2> opc, dag oops, dag iops,
27542920 string asm, string cstr>
2755 : I {
2756 // The operands are in order to match the 'addr' MI operands, so we
2757 // don't need an encoder method and by-name matching. Just use the default
2758 // in-order handling.
2759 bits<5> dst;
2760 bits<5> base;
2921 : I {
2922 bits<5> Rt;
2923 bits<5> Rn;
27612924 bits<9> offset;
27622925 let Inst{31-30} = sz;
27632926 let Inst{29-27} = 0b111;
27672930 let Inst{21} = 0;
27682931 let Inst{20-12} = offset;
27692932 let Inst{11-10} = 0b11;
2770 let Inst{9-5} = base;
2771 let Inst{4-0} = dst;
2933 let Inst{9-5} = Rn;
2934 let Inst{4-0} = Rt;
27722935
27732936 let DecoderMethod = "DecodeSignedLdStInstruction";
27742937 }
27752938
27762939 let hasSideEffects = 0 in {
27772940 let mayStore = 0, mayLoad = 1 in
2778 // FIXME: Modeling the write-back of these instructions for isel is tricky.
2779 // we need the complex addressing mode for the memory reference, but
2780 // we also need the write-back specified as a tied operand to the
2781 // base register. That combination does not play nicely with
2782 // the asm matcher and friends.
2941 // FIXME: Modeling the write-back of these instructions for isel used
2942 // to be tricky. we need the complex addressing mode for the memory
2943 // reference, but we also need the write-back specified as a tied
2944 // operand to the base register. It should work now, but needs to be
2945 // done as a separate patch. This would allow us to be rid of the
2946 // codegenonly pseudoinstructions below too.
27832947 class LoadPreIdx sz, bit V, bits<2> opc, RegisterClass regtype,
27842948 string asm>
27852949 : BaseLoadStorePreIdx
27862950 (outs regtype:$Rt/*, GPR64sp:$wback*/),
2787 (ins am_unscaled_wb:$addr), asm, ""/*"$addr.base = $wback"*/>,
2951 (ins GPR64sp:$Rn, simm9:$offset), asm,
2952 ""/*"$Rn = $wback"*/>,
27882953 Sched<[WriteLD, WriteAdr]>;
27892954
27902955 let mayStore = 1, mayLoad = 0 in
27922957 string asm>
27932958 : BaseLoadStorePreIdx
27942959 (outs/* GPR64sp:$wback*/),
2795 (ins regtype:$Rt, am_unscaled_wb:$addr),
2796 asm, ""/*"$addr.base = $wback"*/>,
2960 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset),
2961 asm, ""/*"$Rn = $wback"*/>,
27972962 Sched<[WriteAdr, WriteST]>;
27982963 } // hasSideEffects = 0
27992964
28112976 let mayStore = 0, mayLoad = 1, hasSideEffects = 0 in {
28122977 class LoadPreIdxPseudo
28132978 : Pseudo<(outs regtype:$Rt, GPR64sp:$wback),
2814 (ins am_noindex:$addr, simm9:$offset), [],
2815 "$addr.base = $wback,@earlyclobber $wback">,
2979 (ins GPR64sp:$addr, simm9:$offset), [],
2980 "$addr = $wback,@earlyclobber $wback">,
28162981 Sched<[WriteLD, WriteAdr]>;
28172982 class LoadPostIdxPseudo
28182983 : Pseudo<(outs regtype:$Rt, GPR64sp:$wback),
2819 (ins am_noindex:$addr, simm9:$offset), [],
2820 "$addr.base = $wback,@earlyclobber $wback">,
2984 (ins GPR64sp:$addr, simm9:$offset), [],
2985 "$addr = $wback,@earlyclobber $wback">,
28212986 Sched<[WriteLD, WriteI]>;
28222987 }
28232988 multiclass StorePreIdxPseudo
28242989 SDPatternOperator OpNode> {
28252990 let mayStore = 1, mayLoad = 0, hasSideEffects = 0 in
28262991 def _isel: Pseudo<(outs GPR64sp:$wback),
2827 (ins regtype:$Rt, am_noindex:$addr, simm9:$offset), [],
2828 "$addr.base = $wback,@earlyclobber $wback">,
2992 (ins regtype:$Rt, GPR64sp:$addr, simm9:$offset), [],
2993 "$addr = $wback,@earlyclobber $wback">,
28292994 Sched<[WriteAdr, WriteST]>;
28302995
2831 def : Pat<(OpNode (Ty regtype:$Rt), am_noindex:$addr, simm9:$offset),
2832 (!cast(NAME#_isel) regtype:$Rt, am_noindex:$addr,
2996 def : Pat<(OpNode (Ty regtype:$Rt), GPR64sp:$addr, simm9:$offset),
2997 (!cast(NAME#_isel) regtype:$Rt, GPR64sp:$addr,
28332998 simm9:$offset)>;
28342999 }
28353000
28403005 // (pre-index) load/stores.
28413006 class BaseLoadStorePostIdx sz, bit V, bits<2> opc, dag oops, dag iops,
28423007 string asm, string cstr>
2843 : I {
2844 // The operands are in order to match the 'addr' MI operands, so we
2845 // don't need an encoder method and by-name matching. Just use the default
2846 // in-order handling.
2847 bits<5> dst;
2848 bits<5> base;
3008 : I {
3009 bits<5> Rt;
3010 bits<5> Rn;
28493011 bits<9> offset;
28503012 let Inst{31-30} = sz;
28513013 let Inst{29-27} = 0b111;
28553017 let Inst{21} = 0b0;
28563018 let Inst{20-12} = offset;
28573019 let Inst{11-10} = 0b01;
2858 let Inst{9-5} = base;
2859 let Inst{4-0} = dst;
3020 let Inst{9-5} = Rn;
3021 let Inst{4-0} = Rt;
28603022
28613023 let DecoderMethod = "DecodeSignedLdStInstruction";
28623024 }
28633025
28643026 let hasSideEffects = 0 in {
28653027 let mayStore = 0, mayLoad = 1 in
2866 // FIXME: Modeling the write-back of these instructions for isel is tricky.
2867 // we need the complex addressing mode for the memory reference, but
2868 // we also need the write-back specified as a tied operand to the
2869 // base register. That combination does not play nicely with
2870 // the asm matcher and friends.
3028 // FIXME: Modeling the write-back of these instructions for isel used
3029 // to be tricky. we need the complex addressing mode for the memory
3030 // reference, but we also need the write-back specified as a tied
3031 // operand to the base register. It should work now, but needs to be
3032 // done as a separate patch. This would allow us to be rid of the
3033 // codegenonly pseudoinstructions below too.
28713034 class LoadPostIdx sz, bit V, bits<2> opc, RegisterClass regtype,
28723035 string asm>
28733036 : BaseLoadStorePostIdx
28743037 (outs regtype:$Rt/*, GPR64sp:$wback*/),
2875 (ins am_noindex:$addr, simm9:$idx),
3038 (ins GPR64sp:$Rn, simm9:$offset),
28763039 asm, ""/*"$addr.base = $wback"*/>,
28773040 Sched<[WriteLD, WriteI]>;
28783041
28813044 string asm>
28823045 : BaseLoadStorePostIdx
28833046 (outs/* GPR64sp:$wback*/),
2884 (ins regtype:$Rt, am_noindex:$addr, simm9:$idx),
3047 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset),
28853048 asm, ""/*"$addr.base = $wback"*/>,
28863049 Sched<[WriteAdr, WriteST, ReadAdrBase]>;
28873050 } // hasSideEffects = 0
28983061 SDPatternOperator OpNode, Instruction Insn> {
28993062 let mayStore = 1, mayLoad = 0, hasSideEffects = 0 in
29003063 def _isel: Pseudo<(outs GPR64sp:$wback),
2901 (ins regtype:$Rt, am_noindex:$addr, simm9:$idx), [],
2902 "$addr.base = $wback,@earlyclobber $wback">,
2903 PseudoInstExpansion<(Insn regtype:$Rt, am_noindex:$addr, simm9:$idx)>,
3064 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$idx), [],
3065 "$Rn = $wback,@earlyclobber $wback">,
3066 PseudoInstExpansion<(Insn regtype:$Rt, GPR64sp:$Rn, simm9:$idx)>,
29043067 Sched<[WriteAdr, WriteST, ReadAdrBase]>;
29053068
2906 def : Pat<(OpNode (Ty regtype:$Rt), am_noindex:$addr, simm9:$idx),
2907 (!cast(NAME#_isel) regtype:$Rt, am_noindex:$addr,
3069 def : Pat<(OpNode (Ty regtype:$Rt), GPR64sp:$Rn, simm9:$idx),
3070 (!cast(NAME#_isel) regtype:$Rt, GPR64sp:$Rn,
29083071 simm9:$idx)>;
29093072 }
29103073
29163079
29173080 class BaseLoadStorePairOffset opc, bit V, bit L, dag oops, dag iops,
29183081 string asm>
2919 : I {
2920 // The operands are in order to match the 'addr' MI operands, so we
2921 // don't need an encoder method and by-name matching. Just use the default
2922 // in-order handling. Since we're using by-order, make sure the names
2923 // do not match.
2924 bits<5> dst;
2925 bits<5> dst2;
2926 bits<5> base;
3082 : I {
3083 bits<5> Rt;
3084 bits<5> Rt2;
3085 bits<5> Rn;
29273086 bits<7> offset;
29283087 let Inst{31-30} = opc;
29293088 let Inst{29-27} = 0b101;
29313090 let Inst{25-23} = 0b010;
29323091 let Inst{22} = L;
29333092 let Inst{21-15} = offset;
2934 let Inst{14-10} = dst2;
2935 let Inst{9-5} = base;
2936 let Inst{4-0} = dst;
3093 let Inst{14-10} = Rt2;
3094 let Inst{9-5} = Rn;
3095 let Inst{4-0} = Rt;
29373096
29383097 let DecoderMethod = "DecodePairLdStInstruction";
29393098 }
29403099
2941 let hasSideEffects = 0 in {
2942 let mayStore = 0, mayLoad = 1 in
2943 class LoadPairOffset opc, bit V, RegisterClass regtype,
2944 Operand indextype, string asm>
2945 : BaseLoadStorePairOffset
2946 (outs regtype:$Rt, regtype:$Rt2),
2947 (ins indextype:$addr), asm>,
2948 Sched<[WriteLD, WriteLDHi]>;
2949
2950 let mayLoad = 0, mayStore = 1 in
2951 class StorePairOffset opc, bit V, RegisterClass regtype,
2952 Operand indextype, string asm>
2953 : BaseLoadStorePairOffset
2954 (ins regtype:$Rt, regtype:$Rt2, indextype:$addr),
2955 asm>,
2956 Sched<[WriteSTP]>;
2957 } // hasSideEffects = 0
3100 multiclass LoadPairOffset opc, bit V, RegisterClass regtype,
3101 Operand indextype, string asm> {
3102 let hasSideEffects = 0, mayStore = 0, mayLoad = 1 in
3103 def i : BaseLoadStorePairOffset
3104 (outs regtype:$Rt, regtype:$Rt2),
3105 (ins GPR64sp:$Rn, indextype:$offset), asm>,
3106 Sched<[WriteLD, WriteLDHi]>;
3107
3108 def : InstAlias
3109 (!cast(NAME # "i") regtype:$Rt, regtype:$Rt2,
3110 GPR64sp:$Rn, 0)>;
3111 }
3112
3113
3114 multiclass StorePairOffset opc, bit V, RegisterClass regtype,
3115 Operand indextype, string asm> {
3116 let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in
3117 def i : BaseLoadStorePairOffset
3118 (ins regtype:$Rt, regtype:$Rt2,
3119 GPR64sp:$Rn, indextype:$offset),
3120 asm>,
3121 Sched<[WriteSTP]>;
3122
3123 def : InstAlias
3124 (!cast(NAME # "i") regtype:$Rt, regtype:$Rt2,
3125 GPR64sp:$Rn, 0)>;
3126 }
29583127
29593128 // (pre-indexed)
2960
2961 def MemoryIndexed32SImm7 : AsmOperandClass {
2962 let Name = "MemoryIndexed32SImm7";
2963 let DiagnosticType = "InvalidMemoryIndexed32SImm7";
2964 }
2965 def am_indexed32simm7 : Operand { // ComplexPattern<...>
2966 let PrintMethod = "printAMIndexed<32>";
2967 let ParserMatchClass = MemoryIndexed32SImm7;
2968 let MIOperandInfo = (ops GPR64sp:$base, i32imm:$offset);
2969 }
2970 def am_indexed32simm7_wb : Operand { // ComplexPattern<...>
2971 let PrintMethod = "printAMIndexedWB<32>";
2972 let ParserMatchClass = MemoryIndexed32SImm7;
2973 let MIOperandInfo = (ops GPR64sp:$base, i32imm:$offset);
2974 }
2975
2976 def MemoryIndexed64SImm7 : AsmOperandClass {
2977 let Name = "MemoryIndexed64SImm7";
2978 let DiagnosticType = "InvalidMemoryIndexed64SImm7";
2979 }
2980 def am_indexed64simm7 : Operand { // ComplexPattern<...>
2981 let PrintMethod = "printAMIndexed<64>";
2982 let ParserMatchClass = MemoryIndexed64SImm7;
2983 let MIOperandInfo = (ops GPR64sp:$base, i32imm:$offset);
2984 }
2985 def am_indexed64simm7_wb : Operand { // ComplexPattern<...>
2986 let PrintMethod = "printAMIndexedWB<64>";
2987 let ParserMatchClass = MemoryIndexed64SImm7;
2988 let MIOperandInfo = (ops GPR64sp:$base, i32imm:$offset);
2989 }
2990
2991 def MemoryIndexed128SImm7 : AsmOperandClass {
2992 let Name = "MemoryIndexed128SImm7";
2993 let DiagnosticType = "InvalidMemoryIndexed128SImm7";
2994 }
2995 def am_indexed128simm7 : Operand { // ComplexPattern<...>
2996 let PrintMethod = "printAMIndexed<128>";
2997 let ParserMatchClass = MemoryIndexed128SImm7;
2998 let MIOperandInfo = (ops GPR64sp:$base, i32imm:$offset);
2999 }
3000 def am_indexed128simm7_wb : Operand { // ComplexPattern<...>
3001 let PrintMethod = "printAMIndexedWB<128>";
3002 let ParserMatchClass = MemoryIndexed128SImm7;
3003 let MIOperandInfo = (ops GPR64sp:$base, i32imm:$offset);
3004 }
3005
30063129 class BaseLoadStorePairPreIdx opc, bit V, bit L, dag oops, dag iops,
30073130 string asm>
3008 : I {
3009 // The operands are in order to match the 'addr' MI operands, so we
3010 // don't need an encoder method and by-name matching. Just use the default
3011 // in-order handling. Since we're using by-order, make sure the names
3012 // do not match.
3013 bits<5> dst;
3014 bits<5> dst2;
3015 bits<5> base;
3131 : I {
3132 bits<5> Rt;
3133 bits<5> Rt2;
3134 bits<5> Rn;
30163135 bits<7> offset;
30173136 let Inst{31-30} = opc;
30183137 let Inst{29-27} = 0b101;
30203139 let Inst{25-23} = 0b011;
30213140 let Inst{22} = L;
30223141 let Inst{21-15} = offset;
3023 let Inst{14-10} = dst2;
3024 let Inst{9-5} = base;
3025 let Inst{4-0} = dst;
3142 let Inst{14-10} = Rt2;
3143 let Inst{9-5} = Rn;
3144 let Inst{4-0} = Rt;
30263145
30273146 let DecoderMethod = "DecodePairLdStInstruction";
30283147 }
30303149 let hasSideEffects = 0 in {
30313150 let mayStore = 0, mayLoad = 1 in
30323151 class LoadPairPreIdx opc, bit V, RegisterClass regtype,
3033 Operand addrmode, string asm>
3152 Operand indextype, string asm>
30343153 : BaseLoadStorePairPreIdx
30353154 (outs regtype:$Rt, regtype:$Rt2),
3036 (ins addrmode:$addr), asm>,
3155 (ins GPR64sp:$Rn, indextype:$offset), asm>,
30373156 Sched<[WriteLD, WriteLDHi, WriteAdr]>;
30383157
30393158 let mayStore = 1, mayLoad = 0 in
30403159 class StorePairPreIdx opc, bit V, RegisterClass regtype,
3041 Operand addrmode, string asm>
3160 Operand indextype, string asm>
30423161 : BaseLoadStorePairPreIdx
3043 (ins regtype:$Rt, regtype:$Rt2, addrmode:$addr),
3162 (ins regtype:$Rt, regtype:$Rt2,
3163 GPR64sp:$Rn, indextype:$offset),
30443164 asm>,
30453165 Sched<[WriteAdr, WriteSTP]>;
30463166 } // hasSideEffects = 0
30493169
30503170 class BaseLoadStorePairPostIdx opc, bit V, bit L, dag oops, dag iops,
30513171 string asm>
3052 : I {
3053 // The operands are in order to match the 'addr' MI operands, so we
3054 // don't need an encoder method and by-name matching. Just use the default
3055 // in-order handling. Since we're using by-order, make sure the names
3056 // do not match.
3057 bits<5> dst;
3058 bits<5> dst2;
3059 bits<5> base;
3172 : I {
3173 bits<5> Rt;
3174 bits<5> Rt2;
3175 bits<5> Rn;
30603176 bits<7> offset;
30613177 let Inst{31-30} = opc;
30623178 let Inst{29-27} = 0b101;
30643180 let Inst{25-23} = 0b001;
30653181 let Inst{22} = L;
30663182 let Inst{21-15} = offset;
3067 let Inst{14-10} = dst2;
3068 let Inst{9-5} = base;
3069 let Inst{4-0} = dst;
3183 let Inst{14-10} = Rt2;
3184 let Inst{9-5} = Rn;
3185 let Inst{4-0} = Rt;
30703186
30713187 let DecoderMethod = "DecodePairLdStInstruction";
30723188 }
30773193 Operand idxtype, string asm>
30783194 : BaseLoadStorePairPostIdx
30793195 (outs regtype:$Rt, regtype:$Rt2),
3080 (ins am_noindex:$addr, idxtype:$idx), asm>,
3196 (ins GPR64sp:$Rn, idxtype:$offset), asm>,
30813197 Sched<[WriteLD, WriteLDHi, WriteAdr]>;
30823198
30833199 let mayStore = 1, mayLoad = 0 in
30853201 Operand idxtype, string asm>
30863202 : BaseLoadStorePairPostIdx
30873203 (ins regtype:$Rt, regtype:$Rt2,
3088 am_noindex:$addr, idxtype:$idx),
3204 GPR64sp:$Rn, idxtype:$offset),
30893205 asm>,
30903206 Sched<[WriteAdr, WriteSTP]>;
30913207 } // hasSideEffects = 0
30943210
30953211 class BaseLoadStorePairNoAlloc opc, bit V, bit L, dag oops, dag iops,
30963212 string asm>
3097 : I {
3098 // The operands are in order to match the 'addr' MI operands, so we
3099 // don't need an encoder method and by-name matching. Just use the default
3100 // in-order handling. Since we're using by-order, make sure the names
3101 // do not match.
3102 bits<5> dst;
3103 bits<5> dst2;
3104 bits<5> base;
3213 : I {
3214 bits<5> Rt;
3215 bits<5> Rt2;
3216 bits<5> Rn;
31053217 bits<7> offset;
31063218 let Inst{31-30} = opc;
31073219 let Inst{29-27} = 0b101;
31093221 let Inst{25-23} = 0b000;
31103222 let Inst{22} = L;
31113223 let Inst{21-15} = offset;
3112 let Inst{14-10} = dst2;
3113 let Inst{9-5} = base;
3114 let Inst{4-0} = dst;
3224 let Inst{14-10} = Rt2;
3225 let Inst{9-5} = Rn;
3226 let Inst{4-0} = Rt;
31153227
31163228 let DecoderMethod = "DecodePairLdStInstruction";
31173229 }
31183230
3119 let hasSideEffects = 0 in {
3120 let mayStore = 0, mayLoad = 1 in
3121 class LoadPairNoAlloc opc, bit V, RegisterClass regtype,
3122 Operand indextype, string asm>
3123 : BaseLoadStorePairNoAlloc
3124 (outs regtype:$Rt, regtype:$Rt2),
3125 (ins indextype:$addr), asm>,
3126 Sched<[WriteLD, WriteLDHi]>;
3127
3128 let mayStore = 1, mayLoad = 0 in
3129 class StorePairNoAlloc opc, bit V, RegisterClass regtype,
3130 Operand indextype, string asm>
3131 : BaseLoadStorePairNoAlloc
3132 (ins regtype:$Rt, regtype:$Rt2, indextype:$addr),
3133 asm>,
3134 Sched<[WriteSTP]>;
3135 } // hasSideEffects = 0
3231 multiclass LoadPairNoAlloc opc, bit V, RegisterClass regtype,
3232 Operand indextype, string asm> {
3233 let hasSideEffects = 0, mayStore = 0, mayLoad = 1 in
3234 def i : BaseLoadStorePairNoAlloc
3235 (outs regtype:$Rt, regtype:$Rt2),
3236 (ins GPR64sp:$Rn, indextype:$offset), asm>,
3237 Sched<[WriteLD, WriteLDHi]>;
3238
3239
3240 def : InstAlias
3241 (!cast(NAME # "i") regtype:$Rt, regtype:$Rt2,
3242 GPR64sp:$Rn, 0)>;
3243 }
3244
3245 multiclass StorePairNoAlloc opc, bit V, RegisterClass regtype,
3246 Operand indextype, string asm> {
3247 let hasSideEffects = 0, mayStore = 1, mayLoad = 0 in
3248 def i : BaseLoadStorePairNoAlloc
3249 (ins regtype:$Rt, regtype:$Rt2,
3250 GPR64sp:$Rn, indextype:$offset),
3251 asm>,
3252 Sched<[WriteSTP]>;
3253
3254 def : InstAlias
3255 (!cast(NAME # "i") regtype:$Rt, regtype:$Rt2,
3256 GPR64sp:$Rn, 0)>;
3257 }
31363258
31373259 //---
31383260 // Load/store exclusive
31713293 class LoadStoreExclusiveSimple sz, bit o2, bit L, bit o1, bit o0,
31723294 dag oops, dag iops, string asm, string operands>
31733295 : BaseLoadStoreExclusive {
3174 bits<5> reg;
3175 bits<5> base;
3176 let Inst{9-5} = base;
3177 let Inst{4-0} = reg;
3296 bits<5> Rt;
3297 bits<5> Rn;
3298 let Inst{9-5} = Rn;
3299 let Inst{4-0} = Rt;
31783300
31793301 let PostEncoderMethod = "fixLoadStoreExclusive<0,0>";
31803302 }
31843306 class LoadAcquire sz, bit o2, bit L, bit o1, bit o0,
31853307 RegisterClass regtype, string asm>
31863308 : LoadStoreExclusiveSimple
3187 (ins am_noindex:$addr), asm, "\t$Rt, $addr">,
3309 (ins GPR64sp0:$Rn), asm, "\t$Rt, [$Rn]">,
31883310 Sched<[WriteLD]>;
31893311
31903312 class LoadExclusive sz, bit o2, bit L, bit o1, bit o0,
31913313 RegisterClass regtype, string asm>
31923314 : LoadStoreExclusiveSimple
3193 (ins am_noindex:$addr), asm, "\t$Rt, $addr">,
3315 (ins GPR64sp0:$Rn), asm, "\t$Rt, [$Rn]">,
31943316 Sched<[WriteLD]>;
31953317
31963318 class LoadExclusivePair sz, bit o2, bit L, bit o1, bit o0,
31973319 RegisterClass regtype, string asm>
31983320 : BaseLoadStoreExclusive
31993321 (outs regtype:$Rt, regtype:$Rt2),
3200 (ins am_noindex:$addr), asm,
3201 "\t$Rt, $Rt2, $addr">,
3322 (ins GPR64sp0:$Rn), asm,
3323 "\t$Rt, $Rt2, [$Rn]">,
32023324 Sched<[WriteLD, WriteLDHi]> {
3203 bits<5> dst1;
3204 bits<5> dst2;
3205 bits<5> base;
3206 let Inst{14-10} = dst2;
3207 let Inst{9-5} = base;
3208 let Inst{4-0} = dst1;
3325 bits<5> Rt;
3326 bits<5> Rt2;
3327 bits<5> Rn;
3328 let Inst{14-10} = Rt2;
3329 let Inst{9-5} = Rn;
3330 let Inst{4-0} = Rt;
32093331
32103332 let PostEncoderMethod = "fixLoadStoreExclusive<0,1>";
32113333 }
32153337 class StoreRelease sz, bit o2, bit L, bit o1, bit o0,
32163338 RegisterClass regtype, string asm>
32173339 : LoadStoreExclusiveSimple
3218 (ins regtype:$Rt, am_noindex:$addr),
3219 asm, "\t$Rt, $addr">,
3340 (ins regtype:$Rt, GPR64sp0:$Rn),
3341 asm, "\t$Rt, [$Rn]">,
32203342 Sched<[WriteST]>;
32213343
32223344 let mayLoad = 1, mayStore = 1 in
32233345 class StoreExclusive sz, bit o2, bit L, bit o1, bit o0,
32243346 RegisterClass regtype, string asm>
32253347 : BaseLoadStoreExclusive
3226 (ins regtype:$Rt, am_noindex:$addr),
3227 asm, "\t$Ws, $Rt, $addr">,
3348 (ins regtype:$Rt, GPR64sp0:$Rn),
3349 asm, "\t$Ws, $Rt, [$Rn]">,
32283350 Sched<[WriteSTX]> {
3229 bits<5> status;
3230 bits<5> reg;
3231 bits<5> base;
3232 let Inst{20-16} = status;
3233 let Inst{9-5} = base;
3234 let Inst{4-0} = reg;
3351 bits<5> Ws;
3352 bits<5> Rt;
3353 bits<5> Rn;
3354 let Inst{20-16} = Ws;
3355 let Inst{9-5} = Rn;
3356 let Inst{4-0} = Rt;
32353357
32363358 let Constraints = "@earlyclobber $Ws";
32373359 let PostEncoderMethod = "fixLoadStoreExclusive<1,0>";
32413363 RegisterClass regtype, string asm>
32423364 : BaseLoadStoreExclusive
32433365 (outs GPR32:$Ws),
3244 (ins regtype:$Rt, regtype:$Rt2, am_noindex:$addr),
3245 asm, "\t$Ws, $Rt, $Rt2, $addr">,
3366 (ins regtype:$Rt, regtype:$Rt2, GPR64sp0:$Rn),
3367 asm, "\t$Ws, $Rt, $Rt2, [$Rn]">,
32463368 Sched<[WriteSTX]> {
3247 bits<5> status;
3248 bits<5> dst1;
3249 bits<5> dst2;
3250 bits<5> base;
3251 let Inst{20-16} = status;
3252 let Inst{14-10} = dst2;
3253 let Inst{9-5} = base;
3254 let Inst{4-0} = dst1;
3369 bits<5> Ws;
3370 bits<5> Rt;
3371 bits<5> Rt2;
3372 bits<5> Rn;
3373 let Inst{20-16} = Ws;
3374 let Inst{14-10} = Rt2;
3375 let Inst{9-5} = Rn;
3376 let Inst{4-0} = Rt;
32553377
32563378 let Constraints = "@earlyclobber $Ws";
32573379 }
39144036 //----------------------------------------------------------------------------
39154037 // AdvSIMD
39164038 //----------------------------------------------------------------------------
3917
3918 def MemorySIMDNoIndexOperand : AsmOperandClass {
3919 let Name = "MemorySIMDNoIndex";
3920 let ParserMethod = "tryParseNoIndexMemory";
3921 }
3922 def am_simdnoindex : Operand,
3923 ComplexPattern {
3924 let PrintMethod = "printAMNoIndex";
3925 let ParserMatchClass = MemorySIMDNoIndexOperand;
3926 let MIOperandInfo = (ops GPR64sp:$base);
3927 let DecoderMethod = "DecodeGPR64spRegisterClass";
3928 }
39294039
39304040 let Predicates = [HasNEON] in {
39314041
75727682 // SIMD ldX/stX no-index memory references don't allow the optional
75737683 // ", #0" constant and handle post-indexing explicitly, so we use
75747684 // a more specialized parse method for them. Otherwise, it's the same as
7575 // the general am_noindex handling.
7685 // the general GPR64sp handling.
75767686
75777687 class BaseSIMDLdSt opcode, bits<2> size,
75787688 string asm, dag oops, dag iops, list pattern>
7579 : I$vaddr", "", pattern> {
7689 : I[$Rn]", "", pattern> {
75807690 bits<5> Vt;
7581 bits<5> vaddr;
7691 bits<5> Rn;
75827692 let Inst{31} = 0;
75837693 let Inst{30} = Q;
75847694 let Inst{29-23} = 0b0011000;
75867696 let Inst{21-16} = 0b000000;
75877697 let Inst{15-12} = opcode;
75887698 let Inst{11-10} = size;
7589 let Inst{9-5} = vaddr;
7699 let Inst{9-5} = Rn;
75907700 let Inst{4-0} = Vt;
75917701 }
75927702
75937703 class BaseSIMDLdStPost opcode, bits<2> size,
75947704 string asm, dag oops, dag iops>
7595 : I$vaddr, $Xm", "$vaddr = $wback", []> {
7705 : I[$Rn], $Xm", "$Rn = $wback", []> {
75967706 bits<5> Vt;
7597 bits<5> vaddr;
7707 bits<5> Rn;
75987708 bits<5> Xm;
75997709 let Inst{31} = 0;
76007710 let Inst{30} = Q;
76047714 let Inst{20-16} = Xm;
76057715 let Inst{15-12} = opcode;
76067716 let Inst{11-10} = size;
7607 let Inst{9-5} = vaddr;
7717 let Inst{9-5} = Rn;
76087718 let Inst{4-0} = Vt;
76097719 }
76107720
76137723 multiclass SIMDLdStAliases
76147724 int Offset, int Size> {
76157725 // E.g. "ld1 { v0.8b, v1.8b }, [x1], #16"
7616 // "ld1\t$Vt, $vaddr, #16"
7726 // "ld1\t$Vt, [$Rn], #16"
76177727 // may get mapped to
7618 // (LD1Twov8b_POST VecListTwo8b:$Vt, am_simdnoindex:$vaddr, XZR)
7619 def : InstAlias
7728 // (LD1Twov8b_POST VecListTwo8b:$Vt, GPR64sp:$Rn, XZR)
7729 def : InstAlias
76207730 (!cast(NAME # Count # "v" # layout # "_POST")
7621 am_simdnoindex:$vaddr,
7731 GPR64sp:$Rn,
76227732 !cast("VecList" # Count # layout):$Vt,
76237733 XZR), 1>;
76247734
76257735 // E.g. "ld1.8b { v0, v1 }, [x1], #16"
7626 // "ld1.8b\t$Vt, $vaddr, #16"
7736 // "ld1.8b\t$Vt, [$Rn], #16"
76277737 // may get mapped to
7628 // (LD1Twov8b_POST VecListTwo64:$Vt, am_simdnoindex:$vaddr, XZR)
7629 def : InstAlias
7738 // (LD1Twov8b_POST VecListTwo64:$Vt, GPR64sp:$Rn, XZR)
7739 def : InstAlias
76307740 (!cast(NAME # Count # "v" # layout # "_POST")
7631 am_simdnoindex:$vaddr,
7741 GPR64sp:$Rn,
76327742 !cast("VecList" # Count # Size):$Vt,
76337743 XZR), 0>;
76347744
76357745 // E.g. "ld1.8b { v0, v1 }, [x1]"
7636 // "ld1\t$Vt, $vaddr"
7746 // "ld1\t$Vt, [$Rn]"
76377747 // may get mapped to
7638 // (LD1Twov8b VecListTwo64:$Vt, am_simdnoindex:$vaddr)
7639 def : InstAlias
7748 // (LD1Twov8b VecListTwo64:$Vt, GPR64sp:$Rn)
7749 def : InstAlias
76407750 (!cast(NAME # Count # "v" # layout)
76417751 !cast("VecList" # Count # Size):$Vt,
7642 am_simdnoindex:$vaddr), 0>;
7752 GPR64sp:$Rn), 0>;
76437753
76447754 // E.g. "ld1.8b { v0, v1 }, [x1], x2"
7645 // "ld1\t$Vt, $vaddr, $Xm"
7755 // "ld1\t$Vt, [$Rn], $Xm"
76467756 // may get mapped to
7647 // (LD1Twov8b_POST VecListTwo64:$Vt, am_simdnoindex:$vaddr, GPR64pi8:$Xm)
7648 def : InstAlias
7757 // (LD1Twov8b_POST VecListTwo64:$Vt, GPR64sp:$Rn, GPR64pi8:$Xm)
7758 def : InstAlias
76497759 (!cast(NAME # Count # "v" # layout # "_POST")
7650 am_simdnoindex:$vaddr,
7760 GPR64sp:$Rn,
76517761 !cast("VecList" # Count # Size):$Vt,
76527762 !cast("GPR64pi" # Offset):$Xm), 0>;
76537763 }
76577767 let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in {
76587768 def v16b: BaseSIMDLdSt<1, 1, opcode, 0b00, asm,
76597769 (outs !cast(veclist # "16b"):$Vt),
7660 (ins am_simdnoindex:$vaddr), []>;
7770 (ins GPR64sp:$Rn), []>;
76617771 def v8h : BaseSIMDLdSt<1, 1, opcode, 0b01, asm,
76627772 (outs !cast(veclist # "8h"):$Vt),
7663 (ins am_simdnoindex:$vaddr), []>;
7773 (ins GPR64sp:$Rn), []>;
76647774 def v4s : BaseSIMDLdSt<1, 1, opcode, 0b10, asm,
76657775 (outs !cast(veclist # "4s"):$Vt),
7666 (ins am_simdnoindex:$vaddr), []>;
7776 (ins GPR64sp:$Rn), []>;
76677777 def v2d : BaseSIMDLdSt<1, 1, opcode, 0b11, asm,
76687778 (outs !cast(veclist # "2d"):$Vt),
7669 (ins am_simdnoindex:$vaddr), []>;
7779 (ins GPR64sp:$Rn), []>;
76707780 def v8b : BaseSIMDLdSt<0, 1, opcode, 0b00, asm,
76717781 (outs !cast(veclist # "8b"):$Vt),
7672 (ins am_simdnoindex:$vaddr), []>;
7782 (ins GPR64sp:$Rn), []>;
76737783 def v4h : BaseSIMDLdSt<0, 1, opcode, 0b01, asm,
76747784 (outs !cast(veclist # "4h"):$Vt),
7675 (ins am_simdnoindex:$vaddr), []>;
7785 (ins GPR64sp:$Rn), []>;
76767786 def v2s : BaseSIMDLdSt<0, 1, opcode, 0b10, asm,
76777787 (outs !cast(veclist # "2s"):$Vt),
7678 (ins am_simdnoindex:$vaddr), []>;
7788 (ins GPR64sp:$Rn), []>;
76797789
76807790
76817791 def v16b_POST: BaseSIMDLdStPost<1, 1, opcode, 0b00, asm,
7682 (outs am_simdnoindex:$wback,
7792 (outs GPR64sp:$wback,
76837793 !cast(veclist # "16b"):$Vt),
7684 (ins am_simdnoindex:$vaddr,
7794 (ins GPR64sp:$Rn,
76857795 !cast("GPR64pi" # Offset128):$Xm)>;
76867796 def v8h_POST : BaseSIMDLdStPost<1, 1, opcode, 0b01, asm,
7687 (outs am_simdnoindex:$wback,
7797 (outs GPR64sp:$wback,
76887798 !cast(veclist # "8h"):$Vt),
7689 (ins am_simdnoindex:$vaddr,
7799 (ins GPR64sp:$Rn,
76907800 !cast("GPR64pi" # Offset128):$Xm)>;
76917801 def v4s_POST : BaseSIMDLdStPost<1, 1, opcode, 0b10, asm,
7692 (outs am_simdnoindex:$wback,
7802 (outs GPR64sp:$wback,
76937803 !cast(veclist # "4s"):$Vt),
7694 (ins am_simdnoindex:$vaddr,
7804 (ins GPR64sp:$Rn,
76957805 !cast("GPR64pi" # Offset128):$Xm)>;
76967806 def v2d_POST : BaseSIMDLdStPost<1, 1, opcode, 0b11, asm,
7697 (outs am_simdnoindex:$wback,
7807 (outs GPR64sp:$wback,
76987808 !cast(veclist # "2d"):$Vt),
7699 (ins am_simdnoindex:$vaddr,
7809 (ins GPR64sp:$Rn,
77007810 !cast("GPR64pi" # Offset128):$Xm)>;
77017811 def v8b_POST : BaseSIMDLdStPost<0, 1, opcode, 0b00, asm,
7702 (outs am_simdnoindex:$wback,
7812 (outs GPR64sp:$wback,
77037813 !cast(veclist # "8b"):$Vt),
7704 (ins am_simdnoindex:$vaddr,
7814 (ins GPR64sp:$Rn,
77057815 !cast("GPR64pi" # Offset64):$Xm)>;
77067816 def v4h_POST : BaseSIMDLdStPost<0, 1, opcode, 0b01, asm,
7707 (outs am_simdnoindex:$wback,
7817 (outs GPR64sp:$wback,
77087818 !cast(veclist # "4h"):$Vt),
7709 (ins am_simdnoindex:$vaddr,
7819 (ins GPR64sp:$Rn,
77107820 !cast("GPR64pi" # Offset64):$Xm)>;
77117821 def v2s_POST : BaseSIMDLdStPost<0, 1, opcode, 0b10, asm,
7712 (outs am_simdnoindex:$wback,
7822 (outs GPR64sp:$wback,
77137823 !cast(veclist # "2s"):$Vt),
7714 (ins am_simdnoindex:$vaddr,
7824 (ins GPR64sp:$Rn,
77157825 !cast("GPR64pi" # Offset64):$Xm)>;
77167826 }
77177827
77307840 let hasSideEffects = 0, mayStore = 1, mayLoad = 0 in {
77317841 def v16b : BaseSIMDLdSt<1, 0, opcode, 0b00, asm, (outs),
77327842 (ins !cast(veclist # "16b"):$Vt,
7733 am_simdnoindex:$vaddr), []>;
7843 GPR64sp:$Rn), []>;
77347844 def v8h : BaseSIMDLdSt<1, 0, opcode, 0b01, asm, (outs),
77357845 (ins !cast(veclist # "8h"):$Vt,
7736 am_simdnoindex:$vaddr), []>;
7846 GPR64sp:$Rn), []>;
77377847 def v4s : BaseSIMDLdSt<1, 0, opcode, 0b10, asm, (outs),
77387848 (ins !cast(veclist # "4s"):$Vt,
7739 am_simdnoindex:$vaddr), []>;
7849 GPR64sp:$Rn), []>;
77407850 def v2d : BaseSIMDLdSt<1, 0, opcode, 0b11, asm, (outs),
77417851 (ins !cast(veclist # "2d"):$Vt,
7742 am_simdnoindex:$vaddr), []>;
7852 GPR64sp:$Rn), []>;
77437853 def v8b : BaseSIMDLdSt<0, 0, opcode, 0b00, asm, (outs),
77447854 (ins !cast(veclist # "8b"):$Vt,
7745 am_simdnoindex:$vaddr), []>;
7855 GPR64sp:$Rn), []>;
77467856 def v4h : BaseSIMDLdSt<0, 0, opcode, 0b01, asm, (outs),
77477857 (ins !cast(veclist # "4h"):$Vt,
7748 am_simdnoindex:$vaddr), []>;
7858 GPR64sp:$Rn), []>;
77497859 def v2s : BaseSIMDLdSt<0, 0, opcode, 0b10, asm, (outs),
77507860 (ins !cast(veclist # "2s"):$Vt,
7751 am_simdnoindex:$vaddr), []>;
7861 GPR64sp:$Rn), []>;
77527862
77537863 def v16b_POST : BaseSIMDLdStPost<1, 0, opcode, 0b00, asm,
7754 (outs am_simdnoindex:$wback),
7864 (outs GPR64sp:$wback),
77557865 (ins !cast(veclist # "16b"):$Vt,
7756 am_simdnoindex:$vaddr,
7866 GPR64sp:$Rn,
77577867 !cast("GPR64pi" # Offset128):$Xm)>;
77587868 def v8h_POST : BaseSIMDLdStPost<1, 0, opcode, 0b01, asm,
7759 (outs am_simdnoindex:$wback),
7869 (outs GPR64sp:$wback),
77607870 (ins !cast(veclist # "8h"):$Vt,
7761 am_simdnoindex:$vaddr,
7871 GPR64sp:$Rn,
77627872 !cast("GPR64pi" # Offset128):$Xm)>;
77637873 def v4s_POST : BaseSIMDLdStPost<1, 0, opcode, 0b10, asm,
7764 (outs am_simdnoindex:$wback),
7874 (outs GPR64sp:$wback),
77657875 (ins !cast(veclist # "4s"):$Vt,
7766 am_simdnoindex:$vaddr,
7876 GPR64sp:$Rn,
77677877 !cast("GPR64pi" # Offset128):$Xm)>;
77687878 def v2d_POST : BaseSIMDLdStPost<1, 0, opcode, 0b11, asm,
7769 (outs am_simdnoindex:$wback),
7879 (outs GPR64sp:$wback),
77707880 (ins !cast(veclist # "2d"):$Vt,
7771 am_simdnoindex:$vaddr,
7881 GPR64sp:$Rn,
77727882 !cast("GPR64pi" # Offset128):$Xm)>;
77737883 def v8b_POST : BaseSIMDLdStPost<0, 0, opcode, 0b00, asm,
7774 (outs am_simdnoindex:$wback),
7884 (outs GPR64sp:$wback),
77757885 (ins !cast(veclist # "8b"):$Vt,
7776 am_simdnoindex:$vaddr,
7886 GPR64sp:$Rn,
77777887 !cast("GPR64pi" # Offset64):$Xm)>;
77787888 def v4h_POST : BaseSIMDLdStPost<0, 0, opcode, 0b01, asm,
7779 (outs am_simdnoindex:$wback),
7889 (outs GPR64sp:$wback),
77807890 (ins !cast(veclist # "4h"):$Vt,
7781 am_simdnoindex:$vaddr,
7891 GPR64sp:$Rn,
77827892 !cast("GPR64pi" # Offset64):$Xm)>;
77837893 def v2s_POST : BaseSIMDLdStPost<0, 0, opcode, 0b10, asm,
7784 (outs am_simdnoindex:$wback),
7894 (outs GPR64sp:$wback),
77857895 (ins !cast(veclist # "2s"):$Vt,
7786 am_simdnoindex:$vaddr,
7896 GPR64sp:$Rn,
77877897 !cast("GPR64pi" # Offset64):$Xm)>;
77887898 }
77897899
78047914 let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in {
78057915 def v1d : BaseSIMDLdSt<0, 1, opcode, 0b11, asm,
78067916 (outs !cast(veclist # "1d"):$Vt),
7807 (ins am_simdnoindex:$vaddr), []>;
7917 (ins GPR64sp:$Rn), []>;
78087918
78097919 def v1d_POST : BaseSIMDLdStPost<0, 1, opcode, 0b11, asm,
7810 (outs am_simdnoindex:$wback,
7920 (outs GPR64sp:$wback,
78117921 !cast(veclist # "1d"):$Vt),
7812 (ins am_simdnoindex:$vaddr,
7922 (ins GPR64sp:$Rn,
78137923 !cast("GPR64pi" # Offset64):$Xm)>;
78147924 }
78157925
78247934 let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in {
78257935 def v1d : BaseSIMDLdSt<0, 0, opcode, 0b11, asm, (outs),
78267936 (ins !cast(veclist # "1d"):$Vt,
7827 am_simdnoindex:$vaddr), []>;
7937 GPR64sp:$Rn), []>;
78287938
78297939 def v1d_POST : BaseSIMDLdStPost<0, 0, opcode, 0b11, asm,
7830 (outs am_simdnoindex:$wback),
7940 (outs GPR64sp:$wback),
78317941 (ins !cast(veclist # "1d"):$Vt,
7832 am_simdnoindex:$vaddr,
7942 GPR64sp:$Rn,
78337943 !cast("GPR64pi" # Offset64):$Xm)>;
78347944 }
78357945
78837993 dag oops, dag iops, list pattern>
78847994 : I {
78857995 bits<5> Vt;
7886 bits<5> vaddr;
7996 bits<5> Rn;
78877997 let Inst{31} = 0;
78887998 let Inst{29-24} = 0b001101;
78897999 let Inst{22} = L;
78908000 let Inst{21} = R;
78918001 let Inst{15-13} = opcode;
7892 let Inst{9-5} = vaddr;
8002 let Inst{9-5} = Rn;
78938003 let Inst{4-0} = Vt;
78948004 }
78958005
78988008 dag oops, dag iops, list pattern>
78998009 : I {
79008010 bits<5> Vt;
7901 bits<5> vaddr;
8011 bits<5> Rn;
79028012 let Inst{31} = 0;
79038013 let Inst{29-24} = 0b001101;
79048014 let Inst{22} = L;
79058015 let Inst{21} = R;
79068016 let Inst{15-13} = opcode;
7907 let Inst{9-5} = vaddr;
8017 let Inst{9-5} = Rn;
79088018 let Inst{4-0} = Vt;
79098019 }
79108020
79128022 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
79138023 class BaseSIMDLdR opcode, bit S, bits<2> size, string asm,
79148024 Operand listtype>
7915 : BaseSIMDLdStSingle<1, R, opcode, asm, "\t$Vt, $vaddr", "",
7916 (outs listtype:$Vt), (ins am_simdnoindex:$vaddr),
8025 : BaseSIMDLdStSingle<1, R, opcode, asm, "\t$Vt, [$Rn]", "",
8026 (outs listtype:$Vt), (ins GPR64sp:$Rn),
79178027 []> {
79188028 let Inst{30} = Q;
79198029 let Inst{23} = 0;
79248034 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
79258035 class BaseSIMDLdRPost opcode, bit S, bits<2> size,
79268036 string asm, Operand listtype, Operand GPR64pi>
7927 : BaseSIMDLdStSingle<1, R, opcode, asm, "\t$Vt, $vaddr, $Xm",
7928 "$vaddr = $wback",
7929 (outs am_simdnoindex:$wback, listtype:$Vt),
7930 (ins am_simdnoindex:$vaddr, GPR64pi:$Xm), []> {
8037 : BaseSIMDLdStSingle<1, R, opcode, asm, "\t$Vt, [$Rn], $Xm",
8038 "$Rn = $wback",
8039 (outs GPR64sp:$wback, listtype:$Vt),
8040 (ins GPR64sp:$Rn, GPR64pi:$Xm), []> {
79318041 bits<5> Xm;
79328042 let Inst{30} = Q;
79338043 let Inst{23} = 1;
79398049 multiclass SIMDLdrAliases
79408050 int Offset, int Size> {
79418051 // E.g. "ld1r { v0.8b }, [x1], #1"
7942 // "ld1r.8b\t$Vt, $vaddr, #1"
8052 // "ld1r.8b\t$Vt, [$Rn], #1"
79438053 // may get mapped to
7944 // (LD1Rv8b_POST VecListOne8b:$Vt, am_simdnoindex:$vaddr, XZR)
7945 def : InstAlias
8054 // (LD1Rv8b_POST VecListOne8b:$Vt, GPR64sp:$Rn, XZR)
8055 def : InstAlias
79468056 (!cast(NAME # "v" # layout # "_POST")
7947 am_simdnoindex:$vaddr,
8057 GPR64sp:$Rn,
79488058 !cast("VecList" # Count # layout):$Vt,
79498059 XZR), 1>;
79508060
79518061 // E.g. "ld1r.8b { v0 }, [x1], #1"
7952 // "ld1r.8b\t$Vt, $vaddr, #1"
8062 // "ld1r.8b\t$Vt, [$Rn], #1"
79538063 // may get mapped to
7954 // (LD1Rv8b_POST VecListOne64:$Vt, am_simdnoindex:$vaddr, XZR)
7955 def : InstAlias
8064 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, XZR)
8065 def : InstAlias
79568066 (!cast(NAME # "v" # layout # "_POST")
7957 am_simdnoindex:$vaddr,
8067 GPR64sp:$Rn,
79588068 !cast("VecList" # Count # Size):$Vt,
79598069 XZR), 0>;
79608070
79618071 // E.g. "ld1r.8b { v0 }, [x1]"
7962 // "ld1r.8b\t$Vt, $vaddr"
8072 // "ld1r.8b\t$Vt, [$Rn]"
79638073 // may get mapped to
7964 // (LD1Rv8b VecListOne64:$Vt, am_simdnoindex:$vaddr)
7965 def : InstAlias
8074 // (LD1Rv8b VecListOne64:$Vt, GPR64sp:$Rn)
8075 def : InstAlias
79668076 (!cast(NAME # "v" # layout)
79678077 !cast("VecList" # Count # Size):$Vt,
7968 am_simdnoindex:$vaddr), 0>;
8078 GPR64sp:$Rn), 0>;
79698079
79708080 // E.g. "ld1r.8b { v0 }, [x1], x2"
7971 // "ld1r.8b\t$Vt, $vaddr, $Xm"
8081 // "ld1r.8b\t$Vt, [$Rn], $Xm"
79728082 // may get mapped to
7973 // (LD1Rv8b_POST VecListOne64:$Vt, am_simdnoindex:$vaddr, GPR64pi1:$Xm)
7974 def : InstAlias
8083 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, GPR64pi1:$Xm)
8084 def : InstAlias
79758085 (!cast(NAME # "v" # layout # "_POST")
7976 am_simdnoindex:$vaddr,
8086 GPR64sp:$Rn,
79778087 !cast("VecList" # Count # Size):$Vt,
79788088 !cast("GPR64pi" # Offset):$Xm), 0>;
79798089 }
80348144
80358145 class SIMDLdStSingleB opcode, string asm,
80368146 dag oops, dag iops, list pattern>
8037 : BaseSIMDLdStSingle$vaddr", "", oops, iops,
8147 : BaseSIMDLdStSingle[$Rn]", "", oops, iops,
80388148 pattern> {
80398149 // idx encoded in Q:S:size fields.
80408150 bits<4> idx;
80468156 }
80478157 class SIMDLdStSingleBTied opcode, string asm,
80488158 dag oops, dag iops, list pattern>
8049 : BaseSIMDLdStSingleTied$vaddr", "",
8159 : BaseSIMDLdStSingleTied[$Rn]", "",
80508160 oops, iops, pattern> {
80518161 // idx encoded in Q:S:size fields.
80528162 bits<4> idx;
80588168 }
80598169 class SIMDLdStSingleBPost opcode, string asm,
80608170 dag oops, dag iops>
8061 : BaseSIMDLdStSingle
8062 "$vaddr = $wback", oops, iops, []> {
8171 : BaseSIMDLdStSingle
8172 "$Rn = $wback", oops, iops, []> {
80638173 // idx encoded in Q:S:size fields.
80648174 bits<4> idx;
80658175 bits<5> Xm;
80718181 }
80728182 class SIMDLdStSingleBTiedPost opcode, string asm,
80738183 dag oops, dag iops>
8074 : BaseSIMDLdStSingleTied
8075 "$vaddr = $wback", oops, iops, []> {
8184 : BaseSIMDLdStSingleTied
8185 "$Rn = $wback", oops, iops, []> {
80768186 // idx encoded in Q:S:size fields.
80778187 bits<4> idx;
80788188 bits<5> Xm;
80858195
80868196 class SIMDLdStSingleH opcode, bit size, string asm,
80878197 dag oops, dag iops, list pattern>
8088 : BaseSIMDLdStSingle$vaddr", "", oops, iops,
8198 : BaseSIMDLdStSingle[$Rn]", "", oops, iops,
80898199 pattern> {
80908200 // idx encoded in Q:S:size<1> fields.
80918201 bits<3> idx;
80988208 }
80998209 class SIMDLdStSingleHTied opcode, bit size, string asm,
81008210 dag oops, dag iops, list pattern>
8101 : BaseSIMDLdStSingleTied$vaddr", "",
8211 : BaseSIMDLdStSingleTied[$Rn]", "",
81028212 oops, iops, pattern> {
81038213 // idx encoded in Q:S:size<1> fields.
81048214 bits<3> idx;
81128222
81138223 class SIMDLdStSingleHPost opcode, bit size, string asm,
81148224 dag oops, dag iops>
8115 : BaseSIMDLdStSingle
8116 "$vaddr = $wback", oops, iops, []> {
8225 : BaseSIMDLdStSingle
8226 "$Rn = $wback", oops, iops, []> {
81178227 // idx encoded in Q:S:size<1> fields.
81188228 bits<3> idx;
81198229 bits<5> Xm;
81268236 }
81278237 class SIMDLdStSingleHTiedPost opcode, bit size, string asm,
81288238 dag oops, dag iops>
8129 : BaseSIMDLdStSingleTied
8130 "$vaddr = $wback", oops, iops, []> {
8239 : BaseSIMDLdStSingleTied
8240 "$Rn = $wback", oops, iops, []> {
81318241 // idx encoded in Q:S:size<1> fields.
81328242 bits<3> idx;
81338243 bits<5> Xm;
81408250 }
81418251 class SIMDLdStSingleS opcode, bits<2> size, string asm,
81428252 dag oops, dag iops, list pattern>
8143 : BaseSIMDLdStSingle$vaddr", "", oops, iops,
8253 : BaseSIMDLdStSingle[$Rn]", "", oops, iops,
81448254 pattern> {
81458255 // idx encoded in Q:S fields.
81468256 bits<2> idx;
81528262 }
81538263 class SIMDLdStSingleSTied opcode, bits<2> size, string asm,
81548264 dag oops, dag iops, list pattern>
8155 : BaseSIMDLdStSingleTied$vaddr", "",
8265 : BaseSIMDLdStSingleTied[$Rn]", "",
81568266 oops, iops, pattern> {
81578267 // idx encoded in Q:S fields.
81588268 bits<2> idx;
81648274 }
81658275 class SIMDLdStSingleSPost opcode, bits<2> size,
81668276 string asm, dag oops, dag iops>
8167 : BaseSIMDLdStSingle
8168 "$vaddr = $wback", oops, iops, []> {
8277 : BaseSIMDLdStSingle
8278 "$Rn = $wback", oops, iops, []> {
81698279 // idx encoded in Q:S fields.
81708280 bits<2> idx;
81718281 bits<5> Xm;
81778287 }
81788288 class SIMDLdStSingleSTiedPost opcode, bits<2> size,
81798289 string asm, dag oops, dag iops>
8180 : BaseSIMDLdStSingleTied
8181 "$vaddr = $wback", oops, iops, []> {
8290 : BaseSIMDLdStSingleTied
8291 "$Rn = $wback", oops, iops, []> {
81828292 // idx encoded in Q:S fields.
81838293 bits<2> idx;
81848294 bits<5> Xm;
81908300 }
81918301 class SIMDLdStSingleD opcode, bits<2> size, string asm,
81928302 dag oops, dag iops, list pattern>
8193 : BaseSIMDLdStSingle$vaddr", "", oops, iops,
8303 : BaseSIMDLdStSingle[$Rn]", "", oops, iops,
81948304 pattern> {
81958305 // idx encoded in Q field.
81968306 bits<1> idx;
82028312 }
82038313 class SIMDLdStSingleDTied opcode, bits<2> size, string asm,
82048314 dag oops, dag iops, list pattern>
8205 : BaseSIMDLdStSingleTied$vaddr", "",
8315 : BaseSIMDLdStSingleTied[$Rn]", "",
82068316 oops, iops, pattern> {
82078317 // idx encoded in Q field.
82088318 bits<1> idx;
82148324 }
82158325 class SIMDLdStSingleDPost opcode, bits<2> size,
82168326 string asm, dag oops, dag iops>
8217 : BaseSIMDLdStSingle
8218 "$vaddr = $wback", oops, iops, []> {
8327 : BaseSIMDLdStSingle
8328 "$Rn = $wback", oops, iops, []> {
82198329 // idx encoded in Q field.
82208330 bits<1> idx;
82218331 bits<5> Xm;
82278337 }
82288338 class SIMDLdStSingleDTiedPost opcode, bits<2> size,
82298339 string asm, dag oops, dag iops>
8230 : BaseSIMDLdStSingleTied
8231 "$vaddr = $wback", oops, iops, []> {
8340 : BaseSIMDLdStSingleTied
8341 "$Rn = $wback", oops, iops, []> {
82328342 // idx encoded in Q field.
82338343 bits<1> idx;
82348344 bits<5> Xm;
82468356 def i8 : SIMDLdStSingleBTied<1, R, opcode, asm,
82478357 (outs listtype:$dst),
82488358 (ins listtype:$Vt, VectorIndexB:$idx,
8249 am_simdnoindex:$vaddr), []>;
8359 GPR64sp:$Rn), []>;
82508360
82518361 def i8_POST : SIMDLdStSingleBTiedPost<1, R, opcode, asm,
8252 (outs am_simdnoindex:$wback, listtype:$dst),
8362 (outs GPR64sp:$wback, listtype:$dst),
82538363 (ins listtype:$Vt, VectorIndexB:$idx,
8254 am_simdnoindex:$vaddr, GPR64pi:$Xm)>;
8364 GPR64sp:$Rn, GPR64pi:$Xm)>;
82558365 }
82568366 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
82578367 multiclass SIMDLdSingleHTied opcode, bit size, string asm,
82608370 def i16 : SIMDLdStSingleHTied<1, R, opcode, size, asm,
82618371 (outs listtype:$dst),
82628372 (ins listtype:$Vt, VectorIndexH:$idx,
8263 am_simdnoindex:$vaddr), []>;
8373 GPR64sp:$Rn), []>;
82648374
82658375 def i16_POST : SIMDLdStSingleHTiedPost<1, R, opcode, size, asm,
8266 (outs am_simdnoindex:$wback, listtype:$dst),
8376 (outs GPR64sp:$wback, listtype:$dst),
82678377 (ins listtype:$Vt, VectorIndexH:$idx,
8268 am_simdnoindex:$vaddr, GPR64pi:$Xm)>;
8378 GPR64sp:$Rn, GPR64pi:$Xm)>;
82698379 }
82708380 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
82718381 multiclass SIMDLdSingleSTied opcode, bits<2> size,string asm,
82748384 def i32 : SIMDLdStSingleSTied<1, R, opcode, size, asm,
82758385 (outs listtype:$dst),
82768386 (ins listtype:$Vt, VectorIndexS:$idx,
8277 am_simdnoindex:$vaddr), []>;
8387 GPR64sp:$Rn), []>;
82788388
82798389 def i32_POST : SIMDLdStSingleSTiedPost<1, R, opcode, size, asm,
8280 (outs am_simdnoindex:$wback, listtype:$dst),
8390 (outs GPR64sp:$wback, listtype:$dst),
82818391 (ins listtype:$Vt, VectorIndexS:$idx,
8282 am_simdnoindex:$vaddr, GPR64pi:$Xm)>;
8392 GPR64sp:$Rn, GPR64pi:$Xm)>;
82838393 }
82848394 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
82858395 multiclass SIMDLdSingleDTied opcode, bits<2> size, string asm,
82878397 def i64 : SIMDLdStSingleDTied<1, R, opcode, size, asm,
82888398 (outs listtype:$dst),
82898399 (ins listtype:$Vt, VectorIndexD:$idx,
8290 am_simdnoindex:$vaddr), []>;
8400 GPR64sp:$Rn), []>;
82918401
82928402 def i64_POST : SIMDLdStSingleDTiedPost<1, R, opcode, size, asm,
8293 (outs am_simdnoindex:$wback, listtype:$dst),
8403 (outs GPR64sp:$wback, listtype:$dst),
82948404 (ins listtype:$Vt, VectorIndexD:$idx,
8295 am_simdnoindex:$vaddr, GPR64pi:$Xm)>;
8405 GPR64sp:$Rn, GPR64pi:$Xm)>;
82968406 }
82978407 let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
82988408 multiclass SIMDStSingleB opcode, string asm,
82998409 RegisterOperand listtype, RegisterOperand GPR64pi> {
83008410 def i8 : SIMDLdStSingleB<0, R, opcode, asm,
83018411 (outs), (ins listtype:$Vt, VectorIndexB:$idx,
8302 am_simdnoindex:$vaddr), []>;
8412 GPR64sp:$Rn), []>;
83038413
83048414 def i8_POST : SIMDLdStSingleBPost<0, R, opcode, asm,
8305 (outs am_simdnoindex:$wback),
8415 (outs GPR64sp:$wback),
83068416 (ins listtype:$Vt, VectorIndexB:$idx,
8307 am_simdnoindex:$vaddr, GPR64pi:$Xm)>;
8417 GPR64sp:$Rn, GPR64pi:$Xm)>;
83088418 }
83098419 let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
83108420 multiclass SIMDStSingleH opcode, bit size, string asm,
83118421 RegisterOperand listtype, RegisterOperand GPR64pi> {
83128422 def i16 : SIMDLdStSingleH<0, R, opcode, size, asm,
83138423 (outs), (ins listtype:$Vt, VectorIndexH:$idx,
8314 am_simdnoindex:$vaddr), []>;
8424 GPR64sp:$Rn), []>;
83158425
83168426 def i16_POST : SIMDLdStSingleHPost<0, R, opcode, size, asm,
8317 (outs am_simdnoindex:$wback),
8427 (outs GPR64sp:$wback),
83188428 (ins listtype:$Vt, VectorIndexH:$idx,
8319 am_simdnoindex:$vaddr, GPR64pi:$Xm)>;
8429 GPR64sp:$Rn, GPR64pi:$Xm)>;
83208430 }
83218431 let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
83228432 multiclass SIMDStSingleS opcode, bits<2> size,string asm,
83238433 RegisterOperand listtype, RegisterOperand GPR64pi> {
83248434 def i32 : SIMDLdStSingleS<0, R, opcode, size, asm,
83258435 (outs), (ins listtype:$Vt, VectorIndexS:$idx,
8326 am_simdnoindex:$vaddr), []>;
8436 GPR64sp:$Rn), []>;
83278437
83288438 def i32_POST : SIMDLdStSingleSPost<0, R, opcode, size, asm,
8329 (outs am_simdnoindex:$wback),
8439 (outs GPR64sp:$wback),
83308440 (ins listtype:$Vt, VectorIndexS:$idx,
8331 am_simdnoindex:$vaddr, GPR64pi:$Xm)>;
8441 GPR64sp:$Rn, GPR64pi:$Xm)>;
83328442 }
83338443 let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
83348444 multiclass SIMDStSingleD opcode, bits<2> size, string asm,
83358445 RegisterOperand listtype, RegisterOperand GPR64pi> {
83368446 def i64 : SIMDLdStSingleD<0, R, opcode, size, asm,
83378447 (outs), (ins listtype:$Vt, VectorIndexD:$idx,
8338 am_simdnoindex:$vaddr), []>;
8448 GPR64sp:$Rn), []>;
83398449
83408450 def i64_POST : SIMDLdStSingleDPost<0, R, opcode, size, asm,
8341 (outs am_simdnoindex:$wback),
8451 (outs GPR64sp:$wback),
83428452 (ins listtype:$Vt, VectorIndexD:$idx,
8343 am_simdnoindex:$vaddr, GPR64pi:$Xm)>;
8453 GPR64sp:$Rn, GPR64pi:$Xm)>;
83448454 }
83458455
83468456 multiclass SIMDLdStSingleAliases
83478457 string Count, int Offset, Operand idxtype> {
83488458 // E.g. "ld1 { v0.8b }[0], [x1], #1"
8349 // "ld1\t$Vt, $vaddr, #1"
8459 // "ld1\t$Vt, [$Rn], #1"
83508460 // may get mapped to
8351 // (LD1Rv8b_POST VecListOne8b:$Vt, am_simdnoindex:$vaddr, XZR)
8352 def : InstAlias
8461 // (LD1Rv8b_POST VecListOne8b:$Vt, GPR64sp:$Rn, XZR)
8462 def : InstAlias
83538463 (!cast(NAME # Type # "_POST")
8354 am_simdnoindex:$vaddr,
8464 GPR64sp:$Rn,
83558465 !cast("VecList" # Count # layout):$Vt,
83568466 idxtype:$idx, XZR), 1>;
83578467
83588468 // E.g. "ld1.8b { v0 }[0], [x1], #1"
8359 // "ld1.8b\t$Vt, $vaddr, #1"
8469 // "ld1.8b\t$Vt, [$Rn], #1"
83608470 // may get mapped to
8361 // (LD1Rv8b_POST VecListOne64:$Vt, am_simdnoindex:$vaddr, XZR)
8362 def : InstAlias
8471 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, XZR)
8472 def : InstAlias
83638473 (!cast(NAME # Type # "_POST")
8364 am_simdnoindex:$vaddr,
8474 GPR64sp:$Rn,
83658475 !cast("VecList" # Count # "128"):$Vt,
83668476 idxtype:$idx, XZR), 0>;
83678477
83688478 // E.g. "ld1.8b { v0 }[0], [x1]"
8369 // "ld1.8b\t$Vt, $vaddr"
8479 // "ld1.8b\t$Vt, [$Rn]"
83708480 // may get mapped to
8371 // (LD1Rv8b VecListOne64:$Vt, am_simdnoindex:$vaddr)
8372 def : InstAlias
8481 // (LD1Rv8b VecListOne64:$Vt, GPR64sp:$Rn)
8482 def : InstAlias
83738483 (!cast(NAME # Type)
83748484 !cast("VecList" # Count # "128"):$Vt,
8375 idxtype:$idx, am_simdnoindex:$vaddr), 0>;
8485 idxtype:$idx, GPR64sp:$Rn), 0>;
83768486
83778487 // E.g. "ld1.8b { v0 }[0], [x1], x2"
8378 // "ld1.8b\t$Vt, $vaddr, $Xm"
8488 // "ld1.8b\t$Vt, [$Rn], $Xm"
83798489 // may get mapped to
8380 // (LD1Rv8b_POST VecListOne64:$Vt, am_simdnoindex:$vaddr, GPR64pi1:$Xm)
8381 def : InstAlias
8490 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, GPR64pi1:$Xm)
8491 def : InstAlias
83828492 (!cast(NAME # Type # "_POST")
8383 am_simdnoindex:$vaddr,
8493 GPR64sp:$Rn,
83848494 !cast("VecList" # Count # "128"):$Vt,
83858495 idxtype:$idx,
83868496 !cast("GPR64pi" # Offset):$Xm), 0>;
10381038 switch (MI->getOpcode()) {
10391039 default:
10401040 break;
1041 case ARM64::LDRBBro:
1042 case ARM64::LDRBro:
1043 case ARM64::LDRDro:
1044 case ARM64::LDRHHro:
1045 case ARM64::LDRHro:
1046 case ARM64::LDRQro:
1047 case ARM64::LDRSBWro:
1048 case ARM64::LDRSBXro:
1049 case ARM64::LDRSHWro:
1050 case ARM64::LDRSHXro:
1051 case ARM64::LDRSWro:
1052 case ARM64::LDRSro:
1053 case ARM64::LDRWro:
1054 case ARM64::LDRXro:
1055 case ARM64::STRBBro:
1056 case ARM64::STRBro:
1057 case ARM64::STRDro:
1058 case ARM64::STRHHro:
1059 case ARM64::STRHro:
1060 case ARM64::STRQro:
1061 case ARM64::STRSro:
1062 case ARM64::STRWro:
1063 case ARM64::STRXro:
1041 case ARM64::LDRBBroW:
1042 case ARM64::LDRBroW:
1043 case ARM64::LDRDroW:
1044 case ARM64::LDRHHroW:
1045 case ARM64::LDRHroW:
1046 case ARM64::LDRQroW:
1047 case ARM64::LDRSBWroW:
1048 case ARM64::LDRSBXroW:
1049 case ARM64::LDRSHWroW:
1050 case ARM64::LDRSHXroW:
1051 case ARM64::LDRSWroW:
1052 case ARM64::LDRSroW:
1053 case ARM64::LDRWroW:
1054 case ARM64::LDRXroW:
1055 case ARM64::STRBBroW:
1056 case ARM64::STRBroW:
1057 case ARM64::STRDroW:
1058 case ARM64::STRHHroW:
1059 case ARM64::STRHroW:
1060 case ARM64::STRQroW:
1061 case ARM64::STRSroW:
1062 case ARM64::STRWroW:
1063 case ARM64::STRXroW:
1064 case ARM64::LDRBBroX:
1065 case ARM64::LDRBroX:
1066 case ARM64::LDRDroX:
1067 case ARM64::LDRHHroX:
1068 case ARM64::LDRHroX:
1069 case ARM64::LDRQroX:
1070 case ARM64::LDRSBWroX:
1071 case ARM64::LDRSBXroX:
1072 case ARM64::LDRSHWroX:
1073 case ARM64::LDRSHXroX:
1074 case ARM64::LDRSWroX:
1075 case ARM64::LDRSroX:
1076 case ARM64::LDRWroX:
1077 case ARM64::LDRXroX:
1078 case ARM64::STRBBroX:
1079 case ARM64::STRBroX:
1080 case ARM64::STRDroX:
1081 case ARM64::STRHHroX:
1082 case ARM64::STRHroX:
1083 case ARM64::STRQroX:
1084 case ARM64::STRSroX:
1085 case ARM64::STRWroX:
1086 case ARM64::STRXroX:
1087
10641088 unsigned Val = MI->getOperand(3).getImm();
10651089 ARM64_AM::ShiftExtendType ExtType = ARM64_AM::getMemExtendType(Val);
10661090 return (ExtType != ARM64_AM::UXTX) || ARM64_AM::getMemDoShift(Val);
10631063 //===----------------------------------------------------------------------===//
10641064
10651065 // Pair (indexed, offset)
1066 def LDPWi : LoadPairOffset<0b00, 0, GPR32, am_indexed32simm7, "ldp">;
1067 def LDPXi : LoadPairOffset<0b10, 0, GPR64, am_indexed64simm7, "ldp">;
1068 def LDPSi : LoadPairOffset<0b00, 1, FPR32, am_indexed32simm7, "ldp">;
1069 def LDPDi : LoadPairOffset<0b01, 1, FPR64, am_indexed64simm7, "ldp">;
1070 def LDPQi : LoadPairOffset<0b10, 1, FPR128, am_indexed128simm7, "ldp">;
1071
1072 def LDPSWi : LoadPairOffset<0b01, 0, GPR64, am_indexed32simm7, "ldpsw">;
1066 defm LDPW : LoadPairOffset<0b00, 0, GPR32, simm7s4, "ldp">;
1067 defm LDPX : LoadPairOffset<0b10, 0, GPR64, simm7s8, "ldp">;
1068 defm LDPS : LoadPairOffset<0b00, 1, FPR32, simm7s4, "ldp">;
1069 defm LDPD : LoadPairOffset<0b01, 1, FPR64, simm7s8, "ldp">;
1070 defm LDPQ : LoadPairOffset<0b10, 1, FPR128, simm7s16, "ldp">;
1071
1072 defm LDPSW : LoadPairOffset<0b01, 0, GPR64, simm7s4, "ldpsw">;
10731073
10741074 // Pair (pre-indexed)
1075 def LDPWpre : LoadPairPreIdx<0b00, 0, GPR32, am_indexed32simm7_wb, "ldp">;
1076 def LDPXpre : LoadPairPreIdx<0b10, 0, GPR64, am_indexed64simm7_wb, "ldp">;
1077 def LDPSpre : LoadPairPreIdx<0b00, 1, FPR32, am_indexed32simm7_wb, "ldp">;
1078 def LDPDpre : LoadPairPreIdx<0b01, 1, FPR64, am_indexed64simm7_wb, "ldp">;
1079 def LDPQpre : LoadPairPreIdx<0b10, 1, FPR128, am_indexed128simm7_wb, "ldp">;
1080
1081 def LDPSWpre : LoadPairPreIdx<0b01, 0, GPR64, am_indexed32simm7_wb, "ldpsw">;
1075 def LDPWpre : LoadPairPreIdx<0b00, 0, GPR32, simm7s4, "ldp">;
1076 def LDPXpre : LoadPairPreIdx<0b10, 0, GPR64, simm7s8, "ldp">;
1077 def LDPSpre : LoadPairPreIdx<0b00, 1, FPR32, simm7s4, "ldp">;
1078 def LDPDpre : LoadPairPreIdx<0b01, 1, FPR64, simm7s8, "ldp">;
1079 def LDPQpre : LoadPairPreIdx<0b10, 1, FPR128, simm7s16, "ldp">;
1080
1081 def LDPSWpre : LoadPairPreIdx<0b01, 0, GPR64, simm7s4, "ldpsw">;
10821082
10831083 // Pair (post-indexed)
10841084 def LDPWpost : LoadPairPostIdx<0b00, 0, GPR32, simm7s4, "ldp">;
10911091
10921092
10931093 // Pair (no allocate)
1094 def LDNPWi : LoadPairNoAlloc<0b00, 0, GPR32, am_indexed32simm7, "ldnp">;
1095 def LDNPXi : LoadPairNoAlloc<0b10, 0, GPR64, am_indexed64simm7, "ldnp">;
1096 def LDNPSi : LoadPairNoAlloc<0b00, 1, FPR32, am_indexed32simm7, "ldnp">;
1097 def LDNPDi : LoadPairNoAlloc<0b01, 1, FPR64, am_indexed64simm7, "ldnp">;
1098 def LDNPQi : LoadPairNoAlloc<0b10, 1, FPR128, am_indexed128simm7, "ldnp">;
1094 defm LDNPW : LoadPairNoAlloc<0b00, 0, GPR32, simm7s4, "ldnp">;
1095 defm LDNPX : LoadPairNoAlloc<0b10, 0, GPR64, simm7s8, "ldnp">;
1096 defm LDNPS : LoadPairNoAlloc<0b00, 1, FPR32, simm7s4, "ldnp">;
1097 defm LDNPD : LoadPairNoAlloc<0b01, 1, FPR64, simm7s8, "ldnp">;
1098 defm LDNPQ : LoadPairNoAlloc<0b10, 1, FPR128, simm7s16, "ldnp">;
10991099
11001100 //---
11011101 // (register offset)
11021102 //---
11031103
1104 let AddedComplexity = 10 in {
11051104 // Integer
1106 def LDRBBro : Load8RO<0b00, 0, 0b01, GPR32, "ldrb",
1107 [(set GPR32:$Rt, (zextloadi8 ro_indexed8:$addr))]>;
1108 def LDRHHro : Load16RO<0b01, 0, 0b01, GPR32, "ldrh",
1109 [(set GPR32:$Rt, (zextloadi16 ro_indexed16:$addr))]>;
1110 def LDRWro : Load32RO<0b10, 0, 0b01, GPR32, "ldr",
1111 [(set GPR32:$Rt, (load ro_indexed32:$addr))]>;
1112 def LDRXro : Load64RO<0b11, 0, 0b01, GPR64, "ldr",
1113 [(set GPR64:$Rt, (load ro_indexed64:$addr))]>;
1105 defm LDRBB : Load8RO<0b00, 0, 0b01, GPR32, "ldrb", i32, zextloadi8>;
1106 defm LDRHH : Load16RO<0b01, 0, 0b01, GPR32, "ldrh", i32, zextloadi16>;
1107 defm LDRW : Load32RO<0b10, 0, 0b01, GPR32, "ldr", i32, load>;
1108 defm LDRX : Load64RO<0b11, 0, 0b01, GPR64, "ldr", i64, load>;
11141109
11151110 // Floating-point
1116 def LDRBro : Load8RO<0b00, 1, 0b01, FPR8, "ldr",
1117 [(set FPR8:$Rt, (load ro_indexed8:$addr))]>;
1118