Mercurial > hg > CbC > CbC_llvm
comparison lib/Target/SystemZ/SystemZInstrFormats.td @ 0:95c75e76d11b LLVM3.4
LLVM 3.4
author | Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp> |
---|---|
date | Thu, 12 Dec 2013 13:56:28 +0900 |
parents | |
children | 54457678186b |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:95c75e76d11b |
---|---|
1 //==- SystemZInstrFormats.td - SystemZ Instruction Formats --*- tablegen -*-==// | |
2 // | |
3 // The LLVM Compiler Infrastructure | |
4 // | |
5 // This file is distributed under the University of Illinois Open Source | |
6 // License. See LICENSE.TXT for details. | |
7 // | |
8 //===----------------------------------------------------------------------===// | |
9 | |
10 //===----------------------------------------------------------------------===// | |
11 // Basic SystemZ instruction definition | |
12 //===----------------------------------------------------------------------===// | |
13 | |
14 class InstSystemZ<int size, dag outs, dag ins, string asmstr, | |
15 list<dag> pattern> : Instruction { | |
16 let Namespace = "SystemZ"; | |
17 | |
18 dag OutOperandList = outs; | |
19 dag InOperandList = ins; | |
20 let Size = size; | |
21 let Pattern = pattern; | |
22 let AsmString = asmstr; | |
23 | |
24 // Some instructions come in pairs, one having a 12-bit displacement | |
25 // and the other having a 20-bit displacement. Both instructions in | |
26 // the pair have the same DispKey and their DispSizes are "12" and "20" | |
27 // respectively. | |
28 string DispKey = ""; | |
29 string DispSize = "none"; | |
30 | |
31 // Many register-based <INSN>R instructions have a memory-based <INSN> | |
32 // counterpart. OpKey uniquely identifies <INSN>, while OpType is | |
33 // "reg" for <INSN>R and "mem" for <INSN>. | |
34 string OpKey = ""; | |
35 string OpType = "none"; | |
36 | |
37 // Many distinct-operands instructions have older 2-operand equivalents. | |
38 // NumOpsKey uniquely identifies one of these 2-operand and 3-operand pairs, | |
39 // with NumOpsValue being "2" or "3" as appropriate. | |
40 string NumOpsKey = ""; | |
41 string NumOpsValue = "none"; | |
42 | |
43 // True if this instruction is a simple D(X,B) load of a register | |
44 // (with no sign or zero extension). | |
45 bit SimpleBDXLoad = 0; | |
46 | |
47 // True if this instruction is a simple D(X,B) store of a register | |
48 // (with no truncation). | |
49 bit SimpleBDXStore = 0; | |
50 | |
51 // True if this instruction has a 20-bit displacement field. | |
52 bit Has20BitOffset = 0; | |
53 | |
54 // True if addresses in this instruction have an index register. | |
55 bit HasIndex = 0; | |
56 | |
57 // True if this is a 128-bit pseudo instruction that combines two 64-bit | |
58 // operations. | |
59 bit Is128Bit = 0; | |
60 | |
61 // The access size of all memory operands in bytes, or 0 if not known. | |
62 bits<5> AccessBytes = 0; | |
63 | |
64 // If the instruction sets CC to a useful value, this gives the mask | |
65 // of all possible CC results. The mask has the same form as | |
66 // SystemZ::CCMASK_*. | |
67 bits<4> CCValues = 0; | |
68 | |
69 // The subset of CCValues that have the same meaning as they would after | |
70 // a comparison of the first operand against zero. | |
71 bits<4> CompareZeroCCMask = 0; | |
72 | |
73 // True if the instruction is conditional and if the CC mask operand | |
74 // comes first (as for BRC, etc.). | |
75 bit CCMaskFirst = 0; | |
76 | |
77 // Similar, but true if the CC mask operand comes last (as for LOC, etc.). | |
78 bit CCMaskLast = 0; | |
79 | |
80 // True if the instruction is the "logical" rather than "arithmetic" form, | |
81 // in cases where a distinction exists. | |
82 bit IsLogical = 0; | |
83 | |
84 let TSFlags{0} = SimpleBDXLoad; | |
85 let TSFlags{1} = SimpleBDXStore; | |
86 let TSFlags{2} = Has20BitOffset; | |
87 let TSFlags{3} = HasIndex; | |
88 let TSFlags{4} = Is128Bit; | |
89 let TSFlags{9-5} = AccessBytes; | |
90 let TSFlags{13-10} = CCValues; | |
91 let TSFlags{17-14} = CompareZeroCCMask; | |
92 let TSFlags{18} = CCMaskFirst; | |
93 let TSFlags{19} = CCMaskLast; | |
94 let TSFlags{20} = IsLogical; | |
95 } | |
96 | |
97 //===----------------------------------------------------------------------===// | |
98 // Mappings between instructions | |
99 //===----------------------------------------------------------------------===// | |
100 | |
101 // Return the version of an instruction that has an unsigned 12-bit | |
102 // displacement. | |
103 def getDisp12Opcode : InstrMapping { | |
104 let FilterClass = "InstSystemZ"; | |
105 let RowFields = ["DispKey"]; | |
106 let ColFields = ["DispSize"]; | |
107 let KeyCol = ["20"]; | |
108 let ValueCols = [["12"]]; | |
109 } | |
110 | |
111 // Return the version of an instruction that has a signed 20-bit displacement. | |
112 def getDisp20Opcode : InstrMapping { | |
113 let FilterClass = "InstSystemZ"; | |
114 let RowFields = ["DispKey"]; | |
115 let ColFields = ["DispSize"]; | |
116 let KeyCol = ["12"]; | |
117 let ValueCols = [["20"]]; | |
118 } | |
119 | |
120 // Return the memory form of a register instruction. | |
121 def getMemOpcode : InstrMapping { | |
122 let FilterClass = "InstSystemZ"; | |
123 let RowFields = ["OpKey"]; | |
124 let ColFields = ["OpType"]; | |
125 let KeyCol = ["reg"]; | |
126 let ValueCols = [["mem"]]; | |
127 } | |
128 | |
129 // Return the 3-operand form of a 2-operand instruction. | |
130 def getThreeOperandOpcode : InstrMapping { | |
131 let FilterClass = "InstSystemZ"; | |
132 let RowFields = ["NumOpsKey"]; | |
133 let ColFields = ["NumOpsValue"]; | |
134 let KeyCol = ["2"]; | |
135 let ValueCols = [["3"]]; | |
136 } | |
137 | |
138 //===----------------------------------------------------------------------===// | |
139 // Instruction formats | |
140 //===----------------------------------------------------------------------===// | |
141 // | |
142 // Formats are specified using operand field declarations of the form: | |
143 // | |
144 // bits<4> Rn : register input or output for operand n | |
145 // bits<m> In : immediate value of width m for operand n | |
146 // bits<4> BDn : address operand n, which has a base and a displacement | |
147 // bits<m> XBDn : address operand n, which has an index, a base and a | |
148 // displacement | |
149 // bits<4> Xn : index register for address operand n | |
150 // bits<4> Mn : mode value for operand n | |
151 // | |
152 // The operand numbers ("n" in the list above) follow the architecture manual. | |
153 // Assembly operands sometimes have a different order; in particular, R3 often | |
154 // is often written between operands 1 and 2. | |
155 // | |
156 //===----------------------------------------------------------------------===// | |
157 | |
158 class InstRI<bits<12> op, dag outs, dag ins, string asmstr, list<dag> pattern> | |
159 : InstSystemZ<4, outs, ins, asmstr, pattern> { | |
160 field bits<32> Inst; | |
161 field bits<32> SoftFail = 0; | |
162 | |
163 bits<4> R1; | |
164 bits<16> I2; | |
165 | |
166 let Inst{31-24} = op{11-4}; | |
167 let Inst{23-20} = R1; | |
168 let Inst{19-16} = op{3-0}; | |
169 let Inst{15-0} = I2; | |
170 } | |
171 | |
172 class InstRIEb<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern> | |
173 : InstSystemZ<6, outs, ins, asmstr, pattern> { | |
174 field bits<48> Inst; | |
175 field bits<48> SoftFail = 0; | |
176 | |
177 bits<4> R1; | |
178 bits<4> R2; | |
179 bits<4> M3; | |
180 bits<16> RI4; | |
181 | |
182 let Inst{47-40} = op{15-8}; | |
183 let Inst{39-36} = R1; | |
184 let Inst{35-32} = R2; | |
185 let Inst{31-16} = RI4; | |
186 let Inst{15-12} = M3; | |
187 let Inst{11-8} = 0; | |
188 let Inst{7-0} = op{7-0}; | |
189 } | |
190 | |
191 class InstRIEc<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern> | |
192 : InstSystemZ<6, outs, ins, asmstr, pattern> { | |
193 field bits<48> Inst; | |
194 field bits<48> SoftFail = 0; | |
195 | |
196 bits<4> R1; | |
197 bits<8> I2; | |
198 bits<4> M3; | |
199 bits<16> RI4; | |
200 | |
201 let Inst{47-40} = op{15-8}; | |
202 let Inst{39-36} = R1; | |
203 let Inst{35-32} = M3; | |
204 let Inst{31-16} = RI4; | |
205 let Inst{15-8} = I2; | |
206 let Inst{7-0} = op{7-0}; | |
207 } | |
208 | |
209 class InstRIEd<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern> | |
210 : InstSystemZ<6, outs, ins, asmstr, pattern> { | |
211 field bits<48> Inst; | |
212 field bits<48> SoftFail = 0; | |
213 | |
214 bits<4> R1; | |
215 bits<4> R3; | |
216 bits<16> I2; | |
217 | |
218 let Inst{47-40} = op{15-8}; | |
219 let Inst{39-36} = R1; | |
220 let Inst{35-32} = R3; | |
221 let Inst{31-16} = I2; | |
222 let Inst{15-8} = 0; | |
223 let Inst{7-0} = op{7-0}; | |
224 } | |
225 | |
226 class InstRIEf<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern> | |
227 : InstSystemZ<6, outs, ins, asmstr, pattern> { | |
228 field bits<48> Inst; | |
229 field bits<48> SoftFail = 0; | |
230 | |
231 bits<4> R1; | |
232 bits<4> R2; | |
233 bits<8> I3; | |
234 bits<8> I4; | |
235 bits<8> I5; | |
236 | |
237 let Inst{47-40} = op{15-8}; | |
238 let Inst{39-36} = R1; | |
239 let Inst{35-32} = R2; | |
240 let Inst{31-24} = I3; | |
241 let Inst{23-16} = I4; | |
242 let Inst{15-8} = I5; | |
243 let Inst{7-0} = op{7-0}; | |
244 } | |
245 | |
246 class InstRIL<bits<12> op, dag outs, dag ins, string asmstr, list<dag> pattern> | |
247 : InstSystemZ<6, outs, ins, asmstr, pattern> { | |
248 field bits<48> Inst; | |
249 field bits<48> SoftFail = 0; | |
250 | |
251 bits<4> R1; | |
252 bits<32> I2; | |
253 | |
254 let Inst{47-40} = op{11-4}; | |
255 let Inst{39-36} = R1; | |
256 let Inst{35-32} = op{3-0}; | |
257 let Inst{31-0} = I2; | |
258 } | |
259 | |
260 class InstRR<bits<8> op, dag outs, dag ins, string asmstr, list<dag> pattern> | |
261 : InstSystemZ<2, outs, ins, asmstr, pattern> { | |
262 field bits<16> Inst; | |
263 field bits<16> SoftFail = 0; | |
264 | |
265 bits<4> R1; | |
266 bits<4> R2; | |
267 | |
268 let Inst{15-8} = op; | |
269 let Inst{7-4} = R1; | |
270 let Inst{3-0} = R2; | |
271 } | |
272 | |
273 class InstRRD<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern> | |
274 : InstSystemZ<4, outs, ins, asmstr, pattern> { | |
275 field bits<32> Inst; | |
276 field bits<32> SoftFail = 0; | |
277 | |
278 bits<4> R1; | |
279 bits<4> R3; | |
280 bits<4> R2; | |
281 | |
282 let Inst{31-16} = op; | |
283 let Inst{15-12} = R1; | |
284 let Inst{11-8} = 0; | |
285 let Inst{7-4} = R3; | |
286 let Inst{3-0} = R2; | |
287 } | |
288 | |
289 class InstRRE<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern> | |
290 : InstSystemZ<4, outs, ins, asmstr, pattern> { | |
291 field bits<32> Inst; | |
292 field bits<32> SoftFail = 0; | |
293 | |
294 bits<4> R1; | |
295 bits<4> R2; | |
296 | |
297 let Inst{31-16} = op; | |
298 let Inst{15-8} = 0; | |
299 let Inst{7-4} = R1; | |
300 let Inst{3-0} = R2; | |
301 } | |
302 | |
303 class InstRRF<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern> | |
304 : InstSystemZ<4, outs, ins, asmstr, pattern> { | |
305 field bits<32> Inst; | |
306 field bits<32> SoftFail = 0; | |
307 | |
308 bits<4> R1; | |
309 bits<4> R2; | |
310 bits<4> R3; | |
311 bits<4> R4; | |
312 | |
313 let Inst{31-16} = op; | |
314 let Inst{15-12} = R3; | |
315 let Inst{11-8} = R4; | |
316 let Inst{7-4} = R1; | |
317 let Inst{3-0} = R2; | |
318 } | |
319 | |
320 class InstRX<bits<8> op, dag outs, dag ins, string asmstr, list<dag> pattern> | |
321 : InstSystemZ<4, outs, ins, asmstr, pattern> { | |
322 field bits<32> Inst; | |
323 field bits<32> SoftFail = 0; | |
324 | |
325 bits<4> R1; | |
326 bits<20> XBD2; | |
327 | |
328 let Inst{31-24} = op; | |
329 let Inst{23-20} = R1; | |
330 let Inst{19-0} = XBD2; | |
331 | |
332 let HasIndex = 1; | |
333 } | |
334 | |
335 class InstRXE<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern> | |
336 : InstSystemZ<6, outs, ins, asmstr, pattern> { | |
337 field bits<48> Inst; | |
338 field bits<48> SoftFail = 0; | |
339 | |
340 bits<4> R1; | |
341 bits<20> XBD2; | |
342 | |
343 let Inst{47-40} = op{15-8}; | |
344 let Inst{39-36} = R1; | |
345 let Inst{35-16} = XBD2; | |
346 let Inst{15-8} = 0; | |
347 let Inst{7-0} = op{7-0}; | |
348 | |
349 let HasIndex = 1; | |
350 } | |
351 | |
352 class InstRXF<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern> | |
353 : InstSystemZ<6, outs, ins, asmstr, pattern> { | |
354 field bits<48> Inst; | |
355 field bits<48> SoftFail = 0; | |
356 | |
357 bits<4> R1; | |
358 bits<4> R3; | |
359 bits<20> XBD2; | |
360 | |
361 let Inst{47-40} = op{15-8}; | |
362 let Inst{39-36} = R3; | |
363 let Inst{35-16} = XBD2; | |
364 let Inst{15-12} = R1; | |
365 let Inst{11-8} = 0; | |
366 let Inst{7-0} = op{7-0}; | |
367 | |
368 let HasIndex = 1; | |
369 } | |
370 | |
371 class InstRXY<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern> | |
372 : InstSystemZ<6, outs, ins, asmstr, pattern> { | |
373 field bits<48> Inst; | |
374 field bits<48> SoftFail = 0; | |
375 | |
376 bits<4> R1; | |
377 bits<28> XBD2; | |
378 | |
379 let Inst{47-40} = op{15-8}; | |
380 let Inst{39-36} = R1; | |
381 let Inst{35-8} = XBD2; | |
382 let Inst{7-0} = op{7-0}; | |
383 | |
384 let Has20BitOffset = 1; | |
385 let HasIndex = 1; | |
386 } | |
387 | |
388 class InstRS<bits<8> op, dag outs, dag ins, string asmstr, list<dag> pattern> | |
389 : InstSystemZ<4, outs, ins, asmstr, pattern> { | |
390 field bits<32> Inst; | |
391 field bits<32> SoftFail = 0; | |
392 | |
393 bits<4> R1; | |
394 bits<4> R3; | |
395 bits<16> BD2; | |
396 | |
397 let Inst{31-24} = op; | |
398 let Inst{23-20} = R1; | |
399 let Inst{19-16} = R3; | |
400 let Inst{15-0} = BD2; | |
401 } | |
402 | |
403 class InstRSY<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern> | |
404 : InstSystemZ<6, outs, ins, asmstr, pattern> { | |
405 field bits<48> Inst; | |
406 field bits<48> SoftFail = 0; | |
407 | |
408 bits<4> R1; | |
409 bits<4> R3; | |
410 bits<24> BD2; | |
411 | |
412 let Inst{47-40} = op{15-8}; | |
413 let Inst{39-36} = R1; | |
414 let Inst{35-32} = R3; | |
415 let Inst{31-8} = BD2; | |
416 let Inst{7-0} = op{7-0}; | |
417 | |
418 let Has20BitOffset = 1; | |
419 } | |
420 | |
421 class InstSI<bits<8> op, dag outs, dag ins, string asmstr, list<dag> pattern> | |
422 : InstSystemZ<4, outs, ins, asmstr, pattern> { | |
423 field bits<32> Inst; | |
424 field bits<32> SoftFail = 0; | |
425 | |
426 bits<16> BD1; | |
427 bits<8> I2; | |
428 | |
429 let Inst{31-24} = op; | |
430 let Inst{23-16} = I2; | |
431 let Inst{15-0} = BD1; | |
432 } | |
433 | |
434 class InstSIL<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern> | |
435 : InstSystemZ<6, outs, ins, asmstr, pattern> { | |
436 field bits<48> Inst; | |
437 field bits<48> SoftFail = 0; | |
438 | |
439 bits<16> BD1; | |
440 bits<16> I2; | |
441 | |
442 let Inst{47-32} = op; | |
443 let Inst{31-16} = BD1; | |
444 let Inst{15-0} = I2; | |
445 } | |
446 | |
447 class InstSIY<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern> | |
448 : InstSystemZ<6, outs, ins, asmstr, pattern> { | |
449 field bits<48> Inst; | |
450 field bits<48> SoftFail = 0; | |
451 | |
452 bits<24> BD1; | |
453 bits<8> I2; | |
454 | |
455 let Inst{47-40} = op{15-8}; | |
456 let Inst{39-32} = I2; | |
457 let Inst{31-8} = BD1; | |
458 let Inst{7-0} = op{7-0}; | |
459 | |
460 let Has20BitOffset = 1; | |
461 } | |
462 | |
463 class InstSS<bits<8> op, dag outs, dag ins, string asmstr, list<dag> pattern> | |
464 : InstSystemZ<6, outs, ins, asmstr, pattern> { | |
465 field bits<48> Inst; | |
466 field bits<48> SoftFail = 0; | |
467 | |
468 bits<24> BDL1; | |
469 bits<16> BD2; | |
470 | |
471 let Inst{47-40} = op; | |
472 let Inst{39-16} = BDL1; | |
473 let Inst{15-0} = BD2; | |
474 } | |
475 | |
476 //===----------------------------------------------------------------------===// | |
477 // Instruction definitions with semantics | |
478 //===----------------------------------------------------------------------===// | |
479 // | |
480 // These classes have the form [Cond]<Category><Format>, where <Format> is one | |
481 // of the formats defined above and where <Category> describes the inputs | |
482 // and outputs. "Cond" is used if the instruction is conditional, | |
483 // in which case the 4-bit condition-code mask is added as a final operand. | |
484 // <Category> can be one of: | |
485 // | |
486 // Inherent: | |
487 // One register output operand and no input operands. | |
488 // | |
489 // BranchUnary: | |
490 // One register output operand, one register input operand and | |
491 // one branch displacement. The instructions stores a modified | |
492 // form of the source register in the destination register and | |
493 // branches on the result. | |
494 // | |
495 // Store: | |
496 // One register or immediate input operand and one address input operand. | |
497 // The instruction stores the first operand to the address. | |
498 // | |
499 // This category is used for both pure and truncating stores. | |
500 // | |
501 // LoadMultiple: | |
502 // One address input operand and two explicit output operands. | |
503 // The instruction loads a range of registers from the address, | |
504 // with the explicit operands giving the first and last register | |
505 // to load. Other loaded registers are added as implicit definitions. | |
506 // | |
507 // StoreMultiple: | |
508 // Two explicit input register operands and an address operand. | |
509 // The instruction stores a range of registers to the address, | |
510 // with the explicit operands giving the first and last register | |
511 // to store. Other stored registers are added as implicit uses. | |
512 // | |
513 // Unary: | |
514 // One register output operand and one input operand. The input | |
515 // operand may be a register, immediate or memory. | |
516 // | |
517 // Binary: | |
518 // One register output operand and two input operands. The first | |
519 // input operand is always a register and he second may be a register, | |
520 // immediate or memory. | |
521 // | |
522 // Shift: | |
523 // One register output operand and two input operands. The first | |
524 // input operand is a register and the second has the same form as | |
525 // an address (although it isn't actually used to address memory). | |
526 // | |
527 // Compare: | |
528 // Two input operands. The first operand is always a register, | |
529 // the second may be a register, immediate or memory. | |
530 // | |
531 // Ternary: | |
532 // One register output operand and three register input operands. | |
533 // | |
534 // CmpSwap: | |
535 // One output operand and three input operands. The first two | |
536 // operands are registers and the third is an address. The instruction | |
537 // both reads from and writes to the address. | |
538 // | |
539 // RotateSelect: | |
540 // One output operand and five input operands. The first two operands | |
541 // are registers and the other three are immediates. | |
542 // | |
543 // Prefetch: | |
544 // One 4-bit immediate operand and one address operand. The immediate | |
545 // operand is 1 for a load prefetch and 2 for a store prefetch. | |
546 // | |
547 // The format determines which input operands are tied to output operands, | |
548 // and also determines the shape of any address operand. | |
549 // | |
550 // Multiclasses of the form <Category><Format>Pair define two instructions, | |
551 // one with <Category><Format> and one with <Category><Format>Y. The name | |
552 // of the first instruction has no suffix, the name of the second has | |
553 // an extra "y". | |
554 // | |
555 //===----------------------------------------------------------------------===// | |
556 | |
557 class InherentRRE<string mnemonic, bits<16> opcode, RegisterOperand cls, | |
558 dag src> | |
559 : InstRRE<opcode, (outs cls:$R1), (ins), | |
560 mnemonic#"\t$R1", | |
561 [(set cls:$R1, src)]> { | |
562 let R2 = 0; | |
563 } | |
564 | |
565 class BranchUnaryRI<string mnemonic, bits<12> opcode, RegisterOperand cls> | |
566 : InstRI<opcode, (outs cls:$R1), (ins cls:$R1src, brtarget16:$I2), | |
567 mnemonic##"\t$R1, $I2", []> { | |
568 let isBranch = 1; | |
569 let isTerminator = 1; | |
570 let Constraints = "$R1 = $R1src"; | |
571 let DisableEncoding = "$R1src"; | |
572 } | |
573 | |
574 class LoadMultipleRSY<string mnemonic, bits<16> opcode, RegisterOperand cls> | |
575 : InstRSY<opcode, (outs cls:$R1, cls:$R3), (ins bdaddr20only:$BD2), | |
576 mnemonic#"\t$R1, $R3, $BD2", []> { | |
577 let mayLoad = 1; | |
578 } | |
579 | |
580 class StoreRILPC<string mnemonic, bits<12> opcode, SDPatternOperator operator, | |
581 RegisterOperand cls> | |
582 : InstRIL<opcode, (outs), (ins cls:$R1, pcrel32:$I2), | |
583 mnemonic#"\t$R1, $I2", | |
584 [(operator cls:$R1, pcrel32:$I2)]> { | |
585 let mayStore = 1; | |
586 // We want PC-relative addresses to be tried ahead of BD and BDX addresses. | |
587 // However, BDXs have two extra operands and are therefore 6 units more | |
588 // complex. | |
589 let AddedComplexity = 7; | |
590 } | |
591 | |
592 class StoreRX<string mnemonic, bits<8> opcode, SDPatternOperator operator, | |
593 RegisterOperand cls, bits<5> bytes, | |
594 AddressingMode mode = bdxaddr12only> | |
595 : InstRX<opcode, (outs), (ins cls:$R1, mode:$XBD2), | |
596 mnemonic#"\t$R1, $XBD2", | |
597 [(operator cls:$R1, mode:$XBD2)]> { | |
598 let OpKey = mnemonic ## cls; | |
599 let OpType = "mem"; | |
600 let mayStore = 1; | |
601 let AccessBytes = bytes; | |
602 } | |
603 | |
604 class StoreRXY<string mnemonic, bits<16> opcode, SDPatternOperator operator, | |
605 RegisterOperand cls, bits<5> bytes, | |
606 AddressingMode mode = bdxaddr20only> | |
607 : InstRXY<opcode, (outs), (ins cls:$R1, mode:$XBD2), | |
608 mnemonic#"\t$R1, $XBD2", | |
609 [(operator cls:$R1, mode:$XBD2)]> { | |
610 let OpKey = mnemonic ## cls; | |
611 let OpType = "mem"; | |
612 let mayStore = 1; | |
613 let AccessBytes = bytes; | |
614 } | |
615 | |
616 multiclass StoreRXPair<string mnemonic, bits<8> rxOpcode, bits<16> rxyOpcode, | |
617 SDPatternOperator operator, RegisterOperand cls, | |
618 bits<5> bytes> { | |
619 let DispKey = mnemonic ## #cls in { | |
620 let DispSize = "12" in | |
621 def "" : StoreRX<mnemonic, rxOpcode, operator, cls, bytes, bdxaddr12pair>; | |
622 let DispSize = "20" in | |
623 def Y : StoreRXY<mnemonic#"y", rxyOpcode, operator, cls, bytes, | |
624 bdxaddr20pair>; | |
625 } | |
626 } | |
627 | |
628 class StoreMultipleRSY<string mnemonic, bits<16> opcode, RegisterOperand cls> | |
629 : InstRSY<opcode, (outs), (ins cls:$R1, cls:$R3, bdaddr20only:$BD2), | |
630 mnemonic#"\t$R1, $R3, $BD2", []> { | |
631 let mayStore = 1; | |
632 } | |
633 | |
634 // StoreSI* instructions are used to store an integer to memory, but the | |
635 // addresses are more restricted than for normal stores. If we are in the | |
636 // situation of having to force either the address into a register or the | |
637 // constant into a register, it's usually better to do the latter. | |
638 // We therefore match the address in the same way as a normal store and | |
639 // only use the StoreSI* instruction if the matched address is suitable. | |
640 class StoreSI<string mnemonic, bits<8> opcode, SDPatternOperator operator, | |
641 Immediate imm> | |
642 : InstSI<opcode, (outs), (ins mviaddr12pair:$BD1, imm:$I2), | |
643 mnemonic#"\t$BD1, $I2", | |
644 [(operator imm:$I2, mviaddr12pair:$BD1)]> { | |
645 let mayStore = 1; | |
646 } | |
647 | |
648 class StoreSIY<string mnemonic, bits<16> opcode, SDPatternOperator operator, | |
649 Immediate imm> | |
650 : InstSIY<opcode, (outs), (ins mviaddr20pair:$BD1, imm:$I2), | |
651 mnemonic#"\t$BD1, $I2", | |
652 [(operator imm:$I2, mviaddr20pair:$BD1)]> { | |
653 let mayStore = 1; | |
654 } | |
655 | |
656 class StoreSIL<string mnemonic, bits<16> opcode, SDPatternOperator operator, | |
657 Immediate imm> | |
658 : InstSIL<opcode, (outs), (ins mviaddr12pair:$BD1, imm:$I2), | |
659 mnemonic#"\t$BD1, $I2", | |
660 [(operator imm:$I2, mviaddr12pair:$BD1)]> { | |
661 let mayStore = 1; | |
662 } | |
663 | |
664 multiclass StoreSIPair<string mnemonic, bits<8> siOpcode, bits<16> siyOpcode, | |
665 SDPatternOperator operator, Immediate imm> { | |
666 let DispKey = mnemonic in { | |
667 let DispSize = "12" in | |
668 def "" : StoreSI<mnemonic, siOpcode, operator, imm>; | |
669 let DispSize = "20" in | |
670 def Y : StoreSIY<mnemonic#"y", siyOpcode, operator, imm>; | |
671 } | |
672 } | |
673 | |
674 class CondStoreRSY<string mnemonic, bits<16> opcode, | |
675 RegisterOperand cls, bits<5> bytes, | |
676 AddressingMode mode = bdaddr20only> | |
677 : InstRSY<opcode, (outs), (ins cls:$R1, mode:$BD2, cond4:$valid, cond4:$R3), | |
678 mnemonic#"$R3\t$R1, $BD2", []>, | |
679 Requires<[FeatureLoadStoreOnCond]> { | |
680 let mayStore = 1; | |
681 let AccessBytes = bytes; | |
682 let CCMaskLast = 1; | |
683 } | |
684 | |
685 // Like CondStoreRSY, but used for the raw assembly form. The condition-code | |
686 // mask is the third operand rather than being part of the mnemonic. | |
687 class AsmCondStoreRSY<string mnemonic, bits<16> opcode, | |
688 RegisterOperand cls, bits<5> bytes, | |
689 AddressingMode mode = bdaddr20only> | |
690 : InstRSY<opcode, (outs), (ins cls:$R1, mode:$BD2, uimm8zx4:$R3), | |
691 mnemonic#"\t$R1, $BD2, $R3", []>, | |
692 Requires<[FeatureLoadStoreOnCond]> { | |
693 let mayStore = 1; | |
694 let AccessBytes = bytes; | |
695 } | |
696 | |
697 // Like CondStoreRSY, but with a fixed CC mask. | |
698 class FixedCondStoreRSY<string mnemonic, bits<16> opcode, | |
699 RegisterOperand cls, bits<4> ccmask, bits<5> bytes, | |
700 AddressingMode mode = bdaddr20only> | |
701 : InstRSY<opcode, (outs), (ins cls:$R1, mode:$BD2), | |
702 mnemonic#"\t$R1, $BD2", []>, | |
703 Requires<[FeatureLoadStoreOnCond]> { | |
704 let mayStore = 1; | |
705 let AccessBytes = bytes; | |
706 let R3 = ccmask; | |
707 } | |
708 | |
709 class UnaryRR<string mnemonic, bits<8> opcode, SDPatternOperator operator, | |
710 RegisterOperand cls1, RegisterOperand cls2> | |
711 : InstRR<opcode, (outs cls1:$R1), (ins cls2:$R2), | |
712 mnemonic#"r\t$R1, $R2", | |
713 [(set cls1:$R1, (operator cls2:$R2))]> { | |
714 let OpKey = mnemonic ## cls1; | |
715 let OpType = "reg"; | |
716 } | |
717 | |
718 class UnaryRRE<string mnemonic, bits<16> opcode, SDPatternOperator operator, | |
719 RegisterOperand cls1, RegisterOperand cls2> | |
720 : InstRRE<opcode, (outs cls1:$R1), (ins cls2:$R2), | |
721 mnemonic#"r\t$R1, $R2", | |
722 [(set cls1:$R1, (operator cls2:$R2))]> { | |
723 let OpKey = mnemonic ## cls1; | |
724 let OpType = "reg"; | |
725 } | |
726 | |
727 class UnaryRRF<string mnemonic, bits<16> opcode, RegisterOperand cls1, | |
728 RegisterOperand cls2> | |
729 : InstRRF<opcode, (outs cls1:$R1), (ins uimm8zx4:$R3, cls2:$R2), | |
730 mnemonic#"r\t$R1, $R3, $R2", []> { | |
731 let OpKey = mnemonic ## cls1; | |
732 let OpType = "reg"; | |
733 let R4 = 0; | |
734 } | |
735 | |
736 class UnaryRRF4<string mnemonic, bits<16> opcode, RegisterOperand cls1, | |
737 RegisterOperand cls2> | |
738 : InstRRF<opcode, (outs cls1:$R1), (ins uimm8zx4:$R3, cls2:$R2, uimm8zx4:$R4), | |
739 mnemonic#"\t$R1, $R3, $R2, $R4", []>; | |
740 | |
741 // These instructions are generated by if conversion. The old value of R1 | |
742 // is added as an implicit use. | |
743 class CondUnaryRRF<string mnemonic, bits<16> opcode, RegisterOperand cls1, | |
744 RegisterOperand cls2> | |
745 : InstRRF<opcode, (outs cls1:$R1), (ins cls2:$R2, cond4:$valid, cond4:$R3), | |
746 mnemonic#"r$R3\t$R1, $R2", []>, | |
747 Requires<[FeatureLoadStoreOnCond]> { | |
748 let CCMaskLast = 1; | |
749 let R4 = 0; | |
750 } | |
751 | |
752 // Like CondUnaryRRF, but used for the raw assembly form. The condition-code | |
753 // mask is the third operand rather than being part of the mnemonic. | |
754 class AsmCondUnaryRRF<string mnemonic, bits<16> opcode, RegisterOperand cls1, | |
755 RegisterOperand cls2> | |
756 : InstRRF<opcode, (outs cls1:$R1), (ins cls1:$R1src, cls2:$R2, uimm8zx4:$R3), | |
757 mnemonic#"r\t$R1, $R2, $R3", []>, | |
758 Requires<[FeatureLoadStoreOnCond]> { | |
759 let Constraints = "$R1 = $R1src"; | |
760 let DisableEncoding = "$R1src"; | |
761 let R4 = 0; | |
762 } | |
763 | |
764 // Like CondUnaryRRF, but with a fixed CC mask. | |
765 class FixedCondUnaryRRF<string mnemonic, bits<16> opcode, RegisterOperand cls1, | |
766 RegisterOperand cls2, bits<4> ccmask> | |
767 : InstRRF<opcode, (outs cls1:$R1), (ins cls1:$R1src, cls2:$R2), | |
768 mnemonic#"\t$R1, $R2", []>, | |
769 Requires<[FeatureLoadStoreOnCond]> { | |
770 let Constraints = "$R1 = $R1src"; | |
771 let DisableEncoding = "$R1src"; | |
772 let R3 = ccmask; | |
773 let R4 = 0; | |
774 } | |
775 | |
776 class UnaryRI<string mnemonic, bits<12> opcode, SDPatternOperator operator, | |
777 RegisterOperand cls, Immediate imm> | |
778 : InstRI<opcode, (outs cls:$R1), (ins imm:$I2), | |
779 mnemonic#"\t$R1, $I2", | |
780 [(set cls:$R1, (operator imm:$I2))]>; | |
781 | |
782 class UnaryRIL<string mnemonic, bits<12> opcode, SDPatternOperator operator, | |
783 RegisterOperand cls, Immediate imm> | |
784 : InstRIL<opcode, (outs cls:$R1), (ins imm:$I2), | |
785 mnemonic#"\t$R1, $I2", | |
786 [(set cls:$R1, (operator imm:$I2))]>; | |
787 | |
788 class UnaryRILPC<string mnemonic, bits<12> opcode, SDPatternOperator operator, | |
789 RegisterOperand cls> | |
790 : InstRIL<opcode, (outs cls:$R1), (ins pcrel32:$I2), | |
791 mnemonic#"\t$R1, $I2", | |
792 [(set cls:$R1, (operator pcrel32:$I2))]> { | |
793 let mayLoad = 1; | |
794 // We want PC-relative addresses to be tried ahead of BD and BDX addresses. | |
795 // However, BDXs have two extra operands and are therefore 6 units more | |
796 // complex. | |
797 let AddedComplexity = 7; | |
798 } | |
799 | |
800 class CondUnaryRSY<string mnemonic, bits<16> opcode, | |
801 SDPatternOperator operator, RegisterOperand cls, | |
802 bits<5> bytes, AddressingMode mode = bdaddr20only> | |
803 : InstRSY<opcode, (outs cls:$R1), | |
804 (ins cls:$R1src, mode:$BD2, cond4:$valid, cond4:$R3), | |
805 mnemonic#"$R3\t$R1, $BD2", | |
806 [(set cls:$R1, | |
807 (z_select_ccmask (load bdaddr20only:$BD2), cls:$R1src, | |
808 cond4:$valid, cond4:$R3))]>, | |
809 Requires<[FeatureLoadStoreOnCond]> { | |
810 let Constraints = "$R1 = $R1src"; | |
811 let DisableEncoding = "$R1src"; | |
812 let mayLoad = 1; | |
813 let AccessBytes = bytes; | |
814 let CCMaskLast = 1; | |
815 } | |
816 | |
817 // Like CondUnaryRSY, but used for the raw assembly form. The condition-code | |
818 // mask is the third operand rather than being part of the mnemonic. | |
819 class AsmCondUnaryRSY<string mnemonic, bits<16> opcode, | |
820 RegisterOperand cls, bits<5> bytes, | |
821 AddressingMode mode = bdaddr20only> | |
822 : InstRSY<opcode, (outs cls:$R1), (ins cls:$R1src, mode:$BD2, uimm8zx4:$R3), | |
823 mnemonic#"\t$R1, $BD2, $R3", []>, | |
824 Requires<[FeatureLoadStoreOnCond]> { | |
825 let mayLoad = 1; | |
826 let AccessBytes = bytes; | |
827 let Constraints = "$R1 = $R1src"; | |
828 let DisableEncoding = "$R1src"; | |
829 } | |
830 | |
831 // Like CondUnaryRSY, but with a fixed CC mask. | |
832 class FixedCondUnaryRSY<string mnemonic, bits<16> opcode, | |
833 RegisterOperand cls, bits<4> ccmask, bits<5> bytes, | |
834 AddressingMode mode = bdaddr20only> | |
835 : InstRSY<opcode, (outs cls:$R1), (ins cls:$R1src, mode:$BD2), | |
836 mnemonic#"\t$R1, $BD2", []>, | |
837 Requires<[FeatureLoadStoreOnCond]> { | |
838 let Constraints = "$R1 = $R1src"; | |
839 let DisableEncoding = "$R1src"; | |
840 let R3 = ccmask; | |
841 let mayLoad = 1; | |
842 let AccessBytes = bytes; | |
843 } | |
844 | |
845 class UnaryRX<string mnemonic, bits<8> opcode, SDPatternOperator operator, | |
846 RegisterOperand cls, bits<5> bytes, | |
847 AddressingMode mode = bdxaddr12only> | |
848 : InstRX<opcode, (outs cls:$R1), (ins mode:$XBD2), | |
849 mnemonic#"\t$R1, $XBD2", | |
850 [(set cls:$R1, (operator mode:$XBD2))]> { | |
851 let OpKey = mnemonic ## cls; | |
852 let OpType = "mem"; | |
853 let mayLoad = 1; | |
854 let AccessBytes = bytes; | |
855 } | |
856 | |
857 class UnaryRXE<string mnemonic, bits<16> opcode, SDPatternOperator operator, | |
858 RegisterOperand cls, bits<5> bytes> | |
859 : InstRXE<opcode, (outs cls:$R1), (ins bdxaddr12only:$XBD2), | |
860 mnemonic#"\t$R1, $XBD2", | |
861 [(set cls:$R1, (operator bdxaddr12only:$XBD2))]> { | |
862 let OpKey = mnemonic ## cls; | |
863 let OpType = "mem"; | |
864 let mayLoad = 1; | |
865 let AccessBytes = bytes; | |
866 } | |
867 | |
868 class UnaryRXY<string mnemonic, bits<16> opcode, SDPatternOperator operator, | |
869 RegisterOperand cls, bits<5> bytes, | |
870 AddressingMode mode = bdxaddr20only> | |
871 : InstRXY<opcode, (outs cls:$R1), (ins mode:$XBD2), | |
872 mnemonic#"\t$R1, $XBD2", | |
873 [(set cls:$R1, (operator mode:$XBD2))]> { | |
874 let OpKey = mnemonic ## cls; | |
875 let OpType = "mem"; | |
876 let mayLoad = 1; | |
877 let AccessBytes = bytes; | |
878 } | |
879 | |
880 multiclass UnaryRXPair<string mnemonic, bits<8> rxOpcode, bits<16> rxyOpcode, | |
881 SDPatternOperator operator, RegisterOperand cls, | |
882 bits<5> bytes> { | |
883 let DispKey = mnemonic ## #cls in { | |
884 let DispSize = "12" in | |
885 def "" : UnaryRX<mnemonic, rxOpcode, operator, cls, bytes, bdxaddr12pair>; | |
886 let DispSize = "20" in | |
887 def Y : UnaryRXY<mnemonic#"y", rxyOpcode, operator, cls, bytes, | |
888 bdxaddr20pair>; | |
889 } | |
890 } | |
891 | |
892 class BinaryRR<string mnemonic, bits<8> opcode, SDPatternOperator operator, | |
893 RegisterOperand cls1, RegisterOperand cls2> | |
894 : InstRR<opcode, (outs cls1:$R1), (ins cls1:$R1src, cls2:$R2), | |
895 mnemonic#"r\t$R1, $R2", | |
896 [(set cls1:$R1, (operator cls1:$R1src, cls2:$R2))]> { | |
897 let OpKey = mnemonic ## cls1; | |
898 let OpType = "reg"; | |
899 let Constraints = "$R1 = $R1src"; | |
900 let DisableEncoding = "$R1src"; | |
901 } | |
902 | |
903 class BinaryRRE<string mnemonic, bits<16> opcode, SDPatternOperator operator, | |
904 RegisterOperand cls1, RegisterOperand cls2> | |
905 : InstRRE<opcode, (outs cls1:$R1), (ins cls1:$R1src, cls2:$R2), | |
906 mnemonic#"r\t$R1, $R2", | |
907 [(set cls1:$R1, (operator cls1:$R1src, cls2:$R2))]> { | |
908 let OpKey = mnemonic ## cls1; | |
909 let OpType = "reg"; | |
910 let Constraints = "$R1 = $R1src"; | |
911 let DisableEncoding = "$R1src"; | |
912 } | |
913 | |
914 class BinaryRRF<string mnemonic, bits<16> opcode, SDPatternOperator operator, | |
915 RegisterOperand cls1, RegisterOperand cls2> | |
916 : InstRRF<opcode, (outs cls1:$R1), (ins cls1:$R3, cls2:$R2), | |
917 mnemonic#"r\t$R1, $R3, $R2", | |
918 [(set cls1:$R1, (operator cls1:$R3, cls2:$R2))]> { | |
919 let OpKey = mnemonic ## cls1; | |
920 let OpType = "reg"; | |
921 let R4 = 0; | |
922 } | |
923 | |
924 class BinaryRRFK<string mnemonic, bits<16> opcode, SDPatternOperator operator, | |
925 RegisterOperand cls1, RegisterOperand cls2> | |
926 : InstRRF<opcode, (outs cls1:$R1), (ins cls1:$R2, cls2:$R3), | |
927 mnemonic#"rk\t$R1, $R2, $R3", | |
928 [(set cls1:$R1, (operator cls1:$R2, cls2:$R3))]> { | |
929 let R4 = 0; | |
930 } | |
931 | |
932 multiclass BinaryRRAndK<string mnemonic, bits<8> opcode1, bits<16> opcode2, | |
933 SDPatternOperator operator, RegisterOperand cls1, | |
934 RegisterOperand cls2> { | |
935 let NumOpsKey = mnemonic in { | |
936 let NumOpsValue = "3" in | |
937 def K : BinaryRRFK<mnemonic, opcode2, null_frag, cls1, cls2>, | |
938 Requires<[FeatureDistinctOps]>; | |
939 let NumOpsValue = "2", isConvertibleToThreeAddress = 1 in | |
940 def "" : BinaryRR<mnemonic, opcode1, operator, cls1, cls2>; | |
941 } | |
942 } | |
943 | |
944 multiclass BinaryRREAndK<string mnemonic, bits<16> opcode1, bits<16> opcode2, | |
945 SDPatternOperator operator, RegisterOperand cls1, | |
946 RegisterOperand cls2> { | |
947 let NumOpsKey = mnemonic in { | |
948 let NumOpsValue = "3" in | |
949 def K : BinaryRRFK<mnemonic, opcode2, null_frag, cls1, cls2>, | |
950 Requires<[FeatureDistinctOps]>; | |
951 let NumOpsValue = "2", isConvertibleToThreeAddress = 1 in | |
952 def "" : BinaryRRE<mnemonic, opcode1, operator, cls1, cls2>; | |
953 } | |
954 } | |
955 | |
956 class BinaryRI<string mnemonic, bits<12> opcode, SDPatternOperator operator, | |
957 RegisterOperand cls, Immediate imm> | |
958 : InstRI<opcode, (outs cls:$R1), (ins cls:$R1src, imm:$I2), | |
959 mnemonic#"\t$R1, $I2", | |
960 [(set cls:$R1, (operator cls:$R1src, imm:$I2))]> { | |
961 let Constraints = "$R1 = $R1src"; | |
962 let DisableEncoding = "$R1src"; | |
963 } | |
964 | |
965 class BinaryRIE<string mnemonic, bits<16> opcode, SDPatternOperator operator, | |
966 RegisterOperand cls, Immediate imm> | |
967 : InstRIEd<opcode, (outs cls:$R1), (ins cls:$R3, imm:$I2), | |
968 mnemonic#"\t$R1, $R3, $I2", | |
969 [(set cls:$R1, (operator cls:$R3, imm:$I2))]>; | |
970 | |
971 multiclass BinaryRIAndK<string mnemonic, bits<12> opcode1, bits<16> opcode2, | |
972 SDPatternOperator operator, RegisterOperand cls, | |
973 Immediate imm> { | |
974 let NumOpsKey = mnemonic in { | |
975 let NumOpsValue = "3" in | |
976 def K : BinaryRIE<mnemonic##"k", opcode2, null_frag, cls, imm>, | |
977 Requires<[FeatureDistinctOps]>; | |
978 let NumOpsValue = "2", isConvertibleToThreeAddress = 1 in | |
979 def "" : BinaryRI<mnemonic, opcode1, operator, cls, imm>; | |
980 } | |
981 } | |
982 | |
983 class BinaryRIL<string mnemonic, bits<12> opcode, SDPatternOperator operator, | |
984 RegisterOperand cls, Immediate imm> | |
985 : InstRIL<opcode, (outs cls:$R1), (ins cls:$R1src, imm:$I2), | |
986 mnemonic#"\t$R1, $I2", | |
987 [(set cls:$R1, (operator cls:$R1src, imm:$I2))]> { | |
988 let Constraints = "$R1 = $R1src"; | |
989 let DisableEncoding = "$R1src"; | |
990 } | |
991 | |
992 class BinaryRX<string mnemonic, bits<8> opcode, SDPatternOperator operator, | |
993 RegisterOperand cls, SDPatternOperator load, bits<5> bytes, | |
994 AddressingMode mode = bdxaddr12only> | |
995 : InstRX<opcode, (outs cls:$R1), (ins cls:$R1src, mode:$XBD2), | |
996 mnemonic#"\t$R1, $XBD2", | |
997 [(set cls:$R1, (operator cls:$R1src, (load mode:$XBD2)))]> { | |
998 let OpKey = mnemonic ## cls; | |
999 let OpType = "mem"; | |
1000 let Constraints = "$R1 = $R1src"; | |
1001 let DisableEncoding = "$R1src"; | |
1002 let mayLoad = 1; | |
1003 let AccessBytes = bytes; | |
1004 } | |
1005 | |
1006 class BinaryRXE<string mnemonic, bits<16> opcode, SDPatternOperator operator, | |
1007 RegisterOperand cls, SDPatternOperator load, bits<5> bytes> | |
1008 : InstRXE<opcode, (outs cls:$R1), (ins cls:$R1src, bdxaddr12only:$XBD2), | |
1009 mnemonic#"\t$R1, $XBD2", | |
1010 [(set cls:$R1, (operator cls:$R1src, | |
1011 (load bdxaddr12only:$XBD2)))]> { | |
1012 let OpKey = mnemonic ## cls; | |
1013 let OpType = "mem"; | |
1014 let Constraints = "$R1 = $R1src"; | |
1015 let DisableEncoding = "$R1src"; | |
1016 let mayLoad = 1; | |
1017 let AccessBytes = bytes; | |
1018 } | |
1019 | |
1020 class BinaryRXY<string mnemonic, bits<16> opcode, SDPatternOperator operator, | |
1021 RegisterOperand cls, SDPatternOperator load, bits<5> bytes, | |
1022 AddressingMode mode = bdxaddr20only> | |
1023 : InstRXY<opcode, (outs cls:$R1), (ins cls:$R1src, mode:$XBD2), | |
1024 mnemonic#"\t$R1, $XBD2", | |
1025 [(set cls:$R1, (operator cls:$R1src, (load mode:$XBD2)))]> { | |
1026 let OpKey = mnemonic ## cls; | |
1027 let OpType = "mem"; | |
1028 let Constraints = "$R1 = $R1src"; | |
1029 let DisableEncoding = "$R1src"; | |
1030 let mayLoad = 1; | |
1031 let AccessBytes = bytes; | |
1032 } | |
1033 | |
1034 multiclass BinaryRXPair<string mnemonic, bits<8> rxOpcode, bits<16> rxyOpcode, | |
1035 SDPatternOperator operator, RegisterOperand cls, | |
1036 SDPatternOperator load, bits<5> bytes> { | |
1037 let DispKey = mnemonic ## #cls in { | |
1038 let DispSize = "12" in | |
1039 def "" : BinaryRX<mnemonic, rxOpcode, operator, cls, load, bytes, | |
1040 bdxaddr12pair>; | |
1041 let DispSize = "20" in | |
1042 def Y : BinaryRXY<mnemonic#"y", rxyOpcode, operator, cls, load, bytes, | |
1043 bdxaddr20pair>; | |
1044 } | |
1045 } | |
1046 | |
1047 class BinarySI<string mnemonic, bits<8> opcode, SDPatternOperator operator, | |
1048 Operand imm, AddressingMode mode = bdaddr12only> | |
1049 : InstSI<opcode, (outs), (ins mode:$BD1, imm:$I2), | |
1050 mnemonic#"\t$BD1, $I2", | |
1051 [(store (operator (load mode:$BD1), imm:$I2), mode:$BD1)]> { | |
1052 let mayLoad = 1; | |
1053 let mayStore = 1; | |
1054 } | |
1055 | |
1056 class BinarySIY<string mnemonic, bits<16> opcode, SDPatternOperator operator, | |
1057 Operand imm, AddressingMode mode = bdaddr20only> | |
1058 : InstSIY<opcode, (outs), (ins mode:$BD1, imm:$I2), | |
1059 mnemonic#"\t$BD1, $I2", | |
1060 [(store (operator (load mode:$BD1), imm:$I2), mode:$BD1)]> { | |
1061 let mayLoad = 1; | |
1062 let mayStore = 1; | |
1063 } | |
1064 | |
1065 multiclass BinarySIPair<string mnemonic, bits<8> siOpcode, | |
1066 bits<16> siyOpcode, SDPatternOperator operator, | |
1067 Operand imm> { | |
1068 let DispKey = mnemonic ## #cls in { | |
1069 let DispSize = "12" in | |
1070 def "" : BinarySI<mnemonic, siOpcode, operator, imm, bdaddr12pair>; | |
1071 let DispSize = "20" in | |
1072 def Y : BinarySIY<mnemonic#"y", siyOpcode, operator, imm, bdaddr20pair>; | |
1073 } | |
1074 } | |
1075 | |
1076 class ShiftRS<string mnemonic, bits<8> opcode, SDPatternOperator operator, | |
1077 RegisterOperand cls> | |
1078 : InstRS<opcode, (outs cls:$R1), (ins cls:$R1src, shift12only:$BD2), | |
1079 mnemonic#"\t$R1, $BD2", | |
1080 [(set cls:$R1, (operator cls:$R1src, shift12only:$BD2))]> { | |
1081 let R3 = 0; | |
1082 let Constraints = "$R1 = $R1src"; | |
1083 let DisableEncoding = "$R1src"; | |
1084 } | |
1085 | |
1086 class ShiftRSY<string mnemonic, bits<16> opcode, SDPatternOperator operator, | |
1087 RegisterOperand cls> | |
1088 : InstRSY<opcode, (outs cls:$R1), (ins cls:$R3, shift20only:$BD2), | |
1089 mnemonic#"\t$R1, $R3, $BD2", | |
1090 [(set cls:$R1, (operator cls:$R3, shift20only:$BD2))]>; | |
1091 | |
1092 multiclass ShiftRSAndK<string mnemonic, bits<8> opcode1, bits<16> opcode2, | |
1093 SDPatternOperator operator, RegisterOperand cls> { | |
1094 let NumOpsKey = mnemonic in { | |
1095 let NumOpsValue = "3" in | |
1096 def K : ShiftRSY<mnemonic##"k", opcode2, null_frag, cls>, | |
1097 Requires<[FeatureDistinctOps]>; | |
1098 let NumOpsValue = "2", isConvertibleToThreeAddress = 1 in | |
1099 def "" : ShiftRS<mnemonic, opcode1, operator, cls>; | |
1100 } | |
1101 } | |
1102 | |
1103 class CompareRR<string mnemonic, bits<8> opcode, SDPatternOperator operator, | |
1104 RegisterOperand cls1, RegisterOperand cls2> | |
1105 : InstRR<opcode, (outs), (ins cls1:$R1, cls2:$R2), | |
1106 mnemonic#"r\t$R1, $R2", | |
1107 [(operator cls1:$R1, cls2:$R2)]> { | |
1108 let OpKey = mnemonic ## cls1; | |
1109 let OpType = "reg"; | |
1110 let isCompare = 1; | |
1111 } | |
1112 | |
1113 class CompareRRE<string mnemonic, bits<16> opcode, SDPatternOperator operator, | |
1114 RegisterOperand cls1, RegisterOperand cls2> | |
1115 : InstRRE<opcode, (outs), (ins cls1:$R1, cls2:$R2), | |
1116 mnemonic#"r\t$R1, $R2", | |
1117 [(operator cls1:$R1, cls2:$R2)]> { | |
1118 let OpKey = mnemonic ## cls1; | |
1119 let OpType = "reg"; | |
1120 let isCompare = 1; | |
1121 } | |
1122 | |
1123 class CompareRI<string mnemonic, bits<12> opcode, SDPatternOperator operator, | |
1124 RegisterOperand cls, Immediate imm> | |
1125 : InstRI<opcode, (outs), (ins cls:$R1, imm:$I2), | |
1126 mnemonic#"\t$R1, $I2", | |
1127 [(operator cls:$R1, imm:$I2)]> { | |
1128 let isCompare = 1; | |
1129 } | |
1130 | |
1131 class CompareRIL<string mnemonic, bits<12> opcode, SDPatternOperator operator, | |
1132 RegisterOperand cls, Immediate imm> | |
1133 : InstRIL<opcode, (outs), (ins cls:$R1, imm:$I2), | |
1134 mnemonic#"\t$R1, $I2", | |
1135 [(operator cls:$R1, imm:$I2)]> { | |
1136 let isCompare = 1; | |
1137 } | |
1138 | |
1139 class CompareRILPC<string mnemonic, bits<12> opcode, SDPatternOperator operator, | |
1140 RegisterOperand cls, SDPatternOperator load> | |
1141 : InstRIL<opcode, (outs), (ins cls:$R1, pcrel32:$I2), | |
1142 mnemonic#"\t$R1, $I2", | |
1143 [(operator cls:$R1, (load pcrel32:$I2))]> { | |
1144 let isCompare = 1; | |
1145 let mayLoad = 1; | |
1146 // We want PC-relative addresses to be tried ahead of BD and BDX addresses. | |
1147 // However, BDXs have two extra operands and are therefore 6 units more | |
1148 // complex. | |
1149 let AddedComplexity = 7; | |
1150 } | |
1151 | |
1152 class CompareRX<string mnemonic, bits<8> opcode, SDPatternOperator operator, | |
1153 RegisterOperand cls, SDPatternOperator load, bits<5> bytes, | |
1154 AddressingMode mode = bdxaddr12only> | |
1155 : InstRX<opcode, (outs), (ins cls:$R1, mode:$XBD2), | |
1156 mnemonic#"\t$R1, $XBD2", | |
1157 [(operator cls:$R1, (load mode:$XBD2))]> { | |
1158 let OpKey = mnemonic ## cls; | |
1159 let OpType = "mem"; | |
1160 let isCompare = 1; | |
1161 let mayLoad = 1; | |
1162 let AccessBytes = bytes; | |
1163 } | |
1164 | |
1165 class CompareRXE<string mnemonic, bits<16> opcode, SDPatternOperator operator, | |
1166 RegisterOperand cls, SDPatternOperator load, bits<5> bytes> | |
1167 : InstRXE<opcode, (outs), (ins cls:$R1, bdxaddr12only:$XBD2), | |
1168 mnemonic#"\t$R1, $XBD2", | |
1169 [(operator cls:$R1, (load bdxaddr12only:$XBD2))]> { | |
1170 let OpKey = mnemonic ## cls; | |
1171 let OpType = "mem"; | |
1172 let isCompare = 1; | |
1173 let mayLoad = 1; | |
1174 let AccessBytes = bytes; | |
1175 } | |
1176 | |
1177 class CompareRXY<string mnemonic, bits<16> opcode, SDPatternOperator operator, | |
1178 RegisterOperand cls, SDPatternOperator load, bits<5> bytes, | |
1179 AddressingMode mode = bdxaddr20only> | |
1180 : InstRXY<opcode, (outs), (ins cls:$R1, mode:$XBD2), | |
1181 mnemonic#"\t$R1, $XBD2", | |
1182 [(operator cls:$R1, (load mode:$XBD2))]> { | |
1183 let OpKey = mnemonic ## cls; | |
1184 let OpType = "mem"; | |
1185 let isCompare = 1; | |
1186 let mayLoad = 1; | |
1187 let AccessBytes = bytes; | |
1188 } | |
1189 | |
1190 multiclass CompareRXPair<string mnemonic, bits<8> rxOpcode, bits<16> rxyOpcode, | |
1191 SDPatternOperator operator, RegisterOperand cls, | |
1192 SDPatternOperator load, bits<5> bytes> { | |
1193 let DispKey = mnemonic ## #cls in { | |
1194 let DispSize = "12" in | |
1195 def "" : CompareRX<mnemonic, rxOpcode, operator, cls, | |
1196 load, bytes, bdxaddr12pair>; | |
1197 let DispSize = "20" in | |
1198 def Y : CompareRXY<mnemonic#"y", rxyOpcode, operator, cls, | |
1199 load, bytes, bdxaddr20pair>; | |
1200 } | |
1201 } | |
1202 | |
1203 class CompareSI<string mnemonic, bits<8> opcode, SDPatternOperator operator, | |
1204 SDPatternOperator load, Immediate imm, | |
1205 AddressingMode mode = bdaddr12only> | |
1206 : InstSI<opcode, (outs), (ins mode:$BD1, imm:$I2), | |
1207 mnemonic#"\t$BD1, $I2", | |
1208 [(operator (load mode:$BD1), imm:$I2)]> { | |
1209 let isCompare = 1; | |
1210 let mayLoad = 1; | |
1211 } | |
1212 | |
1213 class CompareSIL<string mnemonic, bits<16> opcode, SDPatternOperator operator, | |
1214 SDPatternOperator load, Immediate imm> | |
1215 : InstSIL<opcode, (outs), (ins bdaddr12only:$BD1, imm:$I2), | |
1216 mnemonic#"\t$BD1, $I2", | |
1217 [(operator (load bdaddr12only:$BD1), imm:$I2)]> { | |
1218 let isCompare = 1; | |
1219 let mayLoad = 1; | |
1220 } | |
1221 | |
1222 class CompareSIY<string mnemonic, bits<16> opcode, SDPatternOperator operator, | |
1223 SDPatternOperator load, Immediate imm, | |
1224 AddressingMode mode = bdaddr20only> | |
1225 : InstSIY<opcode, (outs), (ins mode:$BD1, imm:$I2), | |
1226 mnemonic#"\t$BD1, $I2", | |
1227 [(operator (load mode:$BD1), imm:$I2)]> { | |
1228 let isCompare = 1; | |
1229 let mayLoad = 1; | |
1230 } | |
1231 | |
1232 multiclass CompareSIPair<string mnemonic, bits<8> siOpcode, bits<16> siyOpcode, | |
1233 SDPatternOperator operator, SDPatternOperator load, | |
1234 Immediate imm> { | |
1235 let DispKey = mnemonic in { | |
1236 let DispSize = "12" in | |
1237 def "" : CompareSI<mnemonic, siOpcode, operator, load, imm, bdaddr12pair>; | |
1238 let DispSize = "20" in | |
1239 def Y : CompareSIY<mnemonic#"y", siyOpcode, operator, load, imm, | |
1240 bdaddr20pair>; | |
1241 } | |
1242 } | |
1243 | |
1244 class TernaryRRD<string mnemonic, bits<16> opcode, | |
1245 SDPatternOperator operator, RegisterOperand cls> | |
1246 : InstRRD<opcode, (outs cls:$R1), (ins cls:$R1src, cls:$R3, cls:$R2), | |
1247 mnemonic#"r\t$R1, $R3, $R2", | |
1248 [(set cls:$R1, (operator cls:$R1src, cls:$R3, cls:$R2))]> { | |
1249 let OpKey = mnemonic ## cls; | |
1250 let OpType = "reg"; | |
1251 let Constraints = "$R1 = $R1src"; | |
1252 let DisableEncoding = "$R1src"; | |
1253 } | |
1254 | |
1255 class TernaryRXF<string mnemonic, bits<16> opcode, SDPatternOperator operator, | |
1256 RegisterOperand cls, SDPatternOperator load, bits<5> bytes> | |
1257 : InstRXF<opcode, (outs cls:$R1), | |
1258 (ins cls:$R1src, cls:$R3, bdxaddr12only:$XBD2), | |
1259 mnemonic#"\t$R1, $R3, $XBD2", | |
1260 [(set cls:$R1, (operator cls:$R1src, cls:$R3, | |
1261 (load bdxaddr12only:$XBD2)))]> { | |
1262 let OpKey = mnemonic ## cls; | |
1263 let OpType = "mem"; | |
1264 let Constraints = "$R1 = $R1src"; | |
1265 let DisableEncoding = "$R1src"; | |
1266 let mayLoad = 1; | |
1267 let AccessBytes = bytes; | |
1268 } | |
1269 | |
1270 class CmpSwapRS<string mnemonic, bits<8> opcode, SDPatternOperator operator, | |
1271 RegisterOperand cls, AddressingMode mode = bdaddr12only> | |
1272 : InstRS<opcode, (outs cls:$R1), (ins cls:$R1src, cls:$R3, mode:$BD2), | |
1273 mnemonic#"\t$R1, $R3, $BD2", | |
1274 [(set cls:$R1, (operator mode:$BD2, cls:$R1src, cls:$R3))]> { | |
1275 let Constraints = "$R1 = $R1src"; | |
1276 let DisableEncoding = "$R1src"; | |
1277 let mayLoad = 1; | |
1278 let mayStore = 1; | |
1279 } | |
1280 | |
1281 class CmpSwapRSY<string mnemonic, bits<16> opcode, SDPatternOperator operator, | |
1282 RegisterOperand cls, AddressingMode mode = bdaddr20only> | |
1283 : InstRSY<opcode, (outs cls:$R1), (ins cls:$R1src, cls:$R3, mode:$BD2), | |
1284 mnemonic#"\t$R1, $R3, $BD2", | |
1285 [(set cls:$R1, (operator mode:$BD2, cls:$R1src, cls:$R3))]> { | |
1286 let Constraints = "$R1 = $R1src"; | |
1287 let DisableEncoding = "$R1src"; | |
1288 let mayLoad = 1; | |
1289 let mayStore = 1; | |
1290 } | |
1291 | |
1292 multiclass CmpSwapRSPair<string mnemonic, bits<8> rsOpcode, bits<16> rsyOpcode, | |
1293 SDPatternOperator operator, RegisterOperand cls> { | |
1294 let DispKey = mnemonic ## #cls in { | |
1295 let DispSize = "12" in | |
1296 def "" : CmpSwapRS<mnemonic, rsOpcode, operator, cls, bdaddr12pair>; | |
1297 let DispSize = "20" in | |
1298 def Y : CmpSwapRSY<mnemonic#"y", rsyOpcode, operator, cls, bdaddr20pair>; | |
1299 } | |
1300 } | |
1301 | |
1302 class RotateSelectRIEf<string mnemonic, bits<16> opcode, RegisterOperand cls1, | |
1303 RegisterOperand cls2> | |
1304 : InstRIEf<opcode, (outs cls1:$R1), | |
1305 (ins cls1:$R1src, cls2:$R2, uimm8:$I3, uimm8:$I4, uimm8zx6:$I5), | |
1306 mnemonic#"\t$R1, $R2, $I3, $I4, $I5", []> { | |
1307 let Constraints = "$R1 = $R1src"; | |
1308 let DisableEncoding = "$R1src"; | |
1309 } | |
1310 | |
1311 class PrefetchRXY<string mnemonic, bits<16> opcode, SDPatternOperator operator> | |
1312 : InstRXY<opcode, (outs), (ins uimm8zx4:$R1, bdxaddr20only:$XBD2), | |
1313 mnemonic##"\t$R1, $XBD2", | |
1314 [(operator uimm8zx4:$R1, bdxaddr20only:$XBD2)]>; | |
1315 | |
1316 class PrefetchRILPC<string mnemonic, bits<12> opcode, | |
1317 SDPatternOperator operator> | |
1318 : InstRIL<opcode, (outs), (ins uimm8zx4:$R1, pcrel32:$I2), | |
1319 mnemonic##"\t$R1, $I2", | |
1320 [(operator uimm8zx4:$R1, pcrel32:$I2)]> { | |
1321 // We want PC-relative addresses to be tried ahead of BD and BDX addresses. | |
1322 // However, BDXs have two extra operands and are therefore 6 units more | |
1323 // complex. | |
1324 let AddedComplexity = 7; | |
1325 } | |
1326 | |
1327 // A floating-point load-and test operation. Create both a normal unary | |
1328 // operation and one that acts as a comparison against zero. | |
1329 multiclass LoadAndTestRRE<string mnemonic, bits<16> opcode, | |
1330 RegisterOperand cls> { | |
1331 def "" : UnaryRRE<mnemonic, opcode, null_frag, cls, cls>; | |
1332 let isCodeGenOnly = 1 in | |
1333 def Compare : CompareRRE<mnemonic, opcode, null_frag, cls, cls>; | |
1334 } | |
1335 | |
1336 //===----------------------------------------------------------------------===// | |
1337 // Pseudo instructions | |
1338 //===----------------------------------------------------------------------===// | |
1339 // | |
1340 // Convenience instructions that get lowered to real instructions | |
1341 // by either SystemZTargetLowering::EmitInstrWithCustomInserter() | |
1342 // or SystemZInstrInfo::expandPostRAPseudo(). | |
1343 // | |
1344 //===----------------------------------------------------------------------===// | |
1345 | |
1346 class Pseudo<dag outs, dag ins, list<dag> pattern> | |
1347 : InstSystemZ<0, outs, ins, "", pattern> { | |
1348 let isPseudo = 1; | |
1349 let isCodeGenOnly = 1; | |
1350 } | |
1351 | |
1352 // Like UnaryRI, but expanded after RA depending on the choice of register. | |
1353 class UnaryRIPseudo<SDPatternOperator operator, RegisterOperand cls, | |
1354 Immediate imm> | |
1355 : Pseudo<(outs cls:$R1), (ins imm:$I2), | |
1356 [(set cls:$R1, (operator imm:$I2))]>; | |
1357 | |
1358 // Like UnaryRXY, but expanded after RA depending on the choice of register. | |
1359 class UnaryRXYPseudo<string key, SDPatternOperator operator, | |
1360 RegisterOperand cls, bits<5> bytes, | |
1361 AddressingMode mode = bdxaddr20only> | |
1362 : Pseudo<(outs cls:$R1), (ins mode:$XBD2), | |
1363 [(set cls:$R1, (operator mode:$XBD2))]> { | |
1364 let OpKey = key ## cls; | |
1365 let OpType = "mem"; | |
1366 let mayLoad = 1; | |
1367 let Has20BitOffset = 1; | |
1368 let HasIndex = 1; | |
1369 let AccessBytes = bytes; | |
1370 } | |
1371 | |
1372 // Like UnaryRR, but expanded after RA depending on the choice of registers. | |
1373 class UnaryRRPseudo<string key, SDPatternOperator operator, | |
1374 RegisterOperand cls1, RegisterOperand cls2> | |
1375 : Pseudo<(outs cls1:$R1), (ins cls2:$R2), | |
1376 [(set cls1:$R1, (operator cls2:$R2))]> { | |
1377 let OpKey = key ## cls1; | |
1378 let OpType = "reg"; | |
1379 } | |
1380 | |
1381 // Like BinaryRI, but expanded after RA depending on the choice of register. | |
1382 class BinaryRIPseudo<SDPatternOperator operator, RegisterOperand cls, | |
1383 Immediate imm> | |
1384 : Pseudo<(outs cls:$R1), (ins cls:$R1src, imm:$I2), | |
1385 [(set cls:$R1, (operator cls:$R1src, imm:$I2))]> { | |
1386 let Constraints = "$R1 = $R1src"; | |
1387 } | |
1388 | |
1389 // Like BinaryRIE, but expanded after RA depending on the choice of register. | |
1390 class BinaryRIEPseudo<SDPatternOperator operator, RegisterOperand cls, | |
1391 Immediate imm> | |
1392 : Pseudo<(outs cls:$R1), (ins cls:$R3, imm:$I2), | |
1393 [(set cls:$R1, (operator cls:$R3, imm:$I2))]>; | |
1394 | |
1395 // Like BinaryRIAndK, but expanded after RA depending on the choice of register. | |
1396 multiclass BinaryRIAndKPseudo<string key, SDPatternOperator operator, | |
1397 RegisterOperand cls, Immediate imm> { | |
1398 let NumOpsKey = key in { | |
1399 let NumOpsValue = "3" in | |
1400 def K : BinaryRIEPseudo<null_frag, cls, imm>, | |
1401 Requires<[FeatureHighWord, FeatureDistinctOps]>; | |
1402 let NumOpsValue = "2", isConvertibleToThreeAddress = 1 in | |
1403 def "" : BinaryRIPseudo<operator, cls, imm>, | |
1404 Requires<[FeatureHighWord]>; | |
1405 } | |
1406 } | |
1407 | |
1408 // Like CompareRI, but expanded after RA depending on the choice of register. | |
1409 class CompareRIPseudo<SDPatternOperator operator, RegisterOperand cls, | |
1410 Immediate imm> | |
1411 : Pseudo<(outs), (ins cls:$R1, imm:$I2), [(operator cls:$R1, imm:$I2)]>; | |
1412 | |
1413 // Like CompareRXY, but expanded after RA depending on the choice of register. | |
1414 class CompareRXYPseudo<SDPatternOperator operator, RegisterOperand cls, | |
1415 SDPatternOperator load, bits<5> bytes, | |
1416 AddressingMode mode = bdxaddr20only> | |
1417 : Pseudo<(outs), (ins cls:$R1, mode:$XBD2), | |
1418 [(operator cls:$R1, (load mode:$XBD2))]> { | |
1419 let mayLoad = 1; | |
1420 let Has20BitOffset = 1; | |
1421 let HasIndex = 1; | |
1422 let AccessBytes = bytes; | |
1423 } | |
1424 | |
1425 // Like StoreRXY, but expanded after RA depending on the choice of register. | |
1426 class StoreRXYPseudo<SDPatternOperator operator, RegisterOperand cls, | |
1427 bits<5> bytes, AddressingMode mode = bdxaddr20only> | |
1428 : Pseudo<(outs), (ins cls:$R1, mode:$XBD2), | |
1429 [(operator cls:$R1, mode:$XBD2)]> { | |
1430 let mayStore = 1; | |
1431 let Has20BitOffset = 1; | |
1432 let HasIndex = 1; | |
1433 let AccessBytes = bytes; | |
1434 } | |
1435 | |
1436 // Like RotateSelectRIEf, but expanded after RA depending on the choice | |
1437 // of registers. | |
1438 class RotateSelectRIEfPseudo<RegisterOperand cls1, RegisterOperand cls2> | |
1439 : Pseudo<(outs cls1:$R1), | |
1440 (ins cls1:$R1src, cls2:$R2, uimm8:$I3, uimm8:$I4, uimm8zx6:$I5), | |
1441 []> { | |
1442 let Constraints = "$R1 = $R1src"; | |
1443 let DisableEncoding = "$R1src"; | |
1444 } | |
1445 | |
1446 // Implements "$dst = $cc & (8 >> CC) ? $src1 : $src2", where CC is | |
1447 // the value of the PSW's 2-bit condition code field. | |
1448 class SelectWrapper<RegisterOperand cls> | |
1449 : Pseudo<(outs cls:$dst), | |
1450 (ins cls:$src1, cls:$src2, uimm8zx4:$valid, uimm8zx4:$cc), | |
1451 [(set cls:$dst, (z_select_ccmask cls:$src1, cls:$src2, | |
1452 uimm8zx4:$valid, uimm8zx4:$cc))]> { | |
1453 let usesCustomInserter = 1; | |
1454 // Although the instructions used by these nodes do not in themselves | |
1455 // change CC, the insertion requires new blocks, and CC cannot be live | |
1456 // across them. | |
1457 let Defs = [CC]; | |
1458 let Uses = [CC]; | |
1459 } | |
1460 | |
1461 // Stores $new to $addr if $cc is true ("" case) or false (Inv case). | |
1462 multiclass CondStores<RegisterOperand cls, SDPatternOperator store, | |
1463 SDPatternOperator load, AddressingMode mode> { | |
1464 let Defs = [CC], Uses = [CC], usesCustomInserter = 1 in { | |
1465 def "" : Pseudo<(outs), | |
1466 (ins cls:$new, mode:$addr, uimm8zx4:$valid, uimm8zx4:$cc), | |
1467 [(store (z_select_ccmask cls:$new, (load mode:$addr), | |
1468 uimm8zx4:$valid, uimm8zx4:$cc), | |
1469 mode:$addr)]>; | |
1470 def Inv : Pseudo<(outs), | |
1471 (ins cls:$new, mode:$addr, uimm8zx4:$valid, uimm8zx4:$cc), | |
1472 [(store (z_select_ccmask (load mode:$addr), cls:$new, | |
1473 uimm8zx4:$valid, uimm8zx4:$cc), | |
1474 mode:$addr)]>; | |
1475 } | |
1476 } | |
1477 | |
1478 // OPERATOR is ATOMIC_SWAP or an ATOMIC_LOAD_* operation. PAT and OPERAND | |
1479 // describe the second (non-memory) operand. | |
1480 class AtomicLoadBinary<SDPatternOperator operator, RegisterOperand cls, | |
1481 dag pat, DAGOperand operand> | |
1482 : Pseudo<(outs cls:$dst), (ins bdaddr20only:$ptr, operand:$src2), | |
1483 [(set cls:$dst, (operator bdaddr20only:$ptr, pat))]> { | |
1484 let Defs = [CC]; | |
1485 let Has20BitOffset = 1; | |
1486 let mayLoad = 1; | |
1487 let mayStore = 1; | |
1488 let usesCustomInserter = 1; | |
1489 } | |
1490 | |
1491 // Specializations of AtomicLoadWBinary. | |
1492 class AtomicLoadBinaryReg32<SDPatternOperator operator> | |
1493 : AtomicLoadBinary<operator, GR32, (i32 GR32:$src2), GR32>; | |
1494 class AtomicLoadBinaryImm32<SDPatternOperator operator, Immediate imm> | |
1495 : AtomicLoadBinary<operator, GR32, (i32 imm:$src2), imm>; | |
1496 class AtomicLoadBinaryReg64<SDPatternOperator operator> | |
1497 : AtomicLoadBinary<operator, GR64, (i64 GR64:$src2), GR64>; | |
1498 class AtomicLoadBinaryImm64<SDPatternOperator operator, Immediate imm> | |
1499 : AtomicLoadBinary<operator, GR64, (i64 imm:$src2), imm>; | |
1500 | |
1501 // OPERATOR is ATOMIC_SWAPW or an ATOMIC_LOADW_* operation. PAT and OPERAND | |
1502 // describe the second (non-memory) operand. | |
1503 class AtomicLoadWBinary<SDPatternOperator operator, dag pat, | |
1504 DAGOperand operand> | |
1505 : Pseudo<(outs GR32:$dst), | |
1506 (ins bdaddr20only:$ptr, operand:$src2, ADDR32:$bitshift, | |
1507 ADDR32:$negbitshift, uimm32:$bitsize), | |
1508 [(set GR32:$dst, (operator bdaddr20only:$ptr, pat, ADDR32:$bitshift, | |
1509 ADDR32:$negbitshift, uimm32:$bitsize))]> { | |
1510 let Defs = [CC]; | |
1511 let Has20BitOffset = 1; | |
1512 let mayLoad = 1; | |
1513 let mayStore = 1; | |
1514 let usesCustomInserter = 1; | |
1515 } | |
1516 | |
1517 // Specializations of AtomicLoadWBinary. | |
1518 class AtomicLoadWBinaryReg<SDPatternOperator operator> | |
1519 : AtomicLoadWBinary<operator, (i32 GR32:$src2), GR32>; | |
1520 class AtomicLoadWBinaryImm<SDPatternOperator operator, Immediate imm> | |
1521 : AtomicLoadWBinary<operator, (i32 imm:$src2), imm>; | |
1522 | |
1523 // Define an instruction that operates on two fixed-length blocks of memory, | |
1524 // and associated pseudo instructions for operating on blocks of any size. | |
1525 // The Sequence form uses a straight-line sequence of instructions and | |
1526 // the Loop form uses a loop of length-256 instructions followed by | |
1527 // another instruction to handle the excess. | |
1528 multiclass MemorySS<string mnemonic, bits<8> opcode, | |
1529 SDPatternOperator sequence, SDPatternOperator loop> { | |
1530 def "" : InstSS<opcode, (outs), (ins bdladdr12onlylen8:$BDL1, | |
1531 bdaddr12only:$BD2), | |
1532 mnemonic##"\t$BDL1, $BD2", []>; | |
1533 let usesCustomInserter = 1 in { | |
1534 def Sequence : Pseudo<(outs), (ins bdaddr12only:$dest, bdaddr12only:$src, | |
1535 imm64:$length), | |
1536 [(sequence bdaddr12only:$dest, bdaddr12only:$src, | |
1537 imm64:$length)]>; | |
1538 def Loop : Pseudo<(outs), (ins bdaddr12only:$dest, bdaddr12only:$src, | |
1539 imm64:$length, GR64:$count256), | |
1540 [(loop bdaddr12only:$dest, bdaddr12only:$src, | |
1541 imm64:$length, GR64:$count256)]>; | |
1542 } | |
1543 } | |
1544 | |
1545 // Define an instruction that operates on two strings, both terminated | |
1546 // by the character in R0. The instruction processes a CPU-determinated | |
1547 // number of bytes at a time and sets CC to 3 if the instruction needs | |
1548 // to be repeated. Also define a pseudo instruction that represents | |
1549 // the full loop (the main instruction plus the branch on CC==3). | |
1550 multiclass StringRRE<string mnemonic, bits<16> opcode, | |
1551 SDPatternOperator operator> { | |
1552 def "" : InstRRE<opcode, (outs GR64:$R1, GR64:$R2), | |
1553 (ins GR64:$R1src, GR64:$R2src), | |
1554 mnemonic#"\t$R1, $R2", []> { | |
1555 let Constraints = "$R1 = $R1src, $R2 = $R2src"; | |
1556 let DisableEncoding = "$R1src, $R2src"; | |
1557 } | |
1558 let usesCustomInserter = 1 in | |
1559 def Loop : Pseudo<(outs GR64:$end), | |
1560 (ins GR64:$start1, GR64:$start2, GR32:$char), | |
1561 [(set GR64:$end, (operator GR64:$start1, GR64:$start2, | |
1562 GR32:$char))]>; | |
1563 } | |
1564 | |
1565 // A pseudo instruction that is a direct alias of a real instruction. | |
1566 // These aliases are used in cases where a particular register operand is | |
1567 // fixed or where the same instruction is used with different register sizes. | |
1568 // The size parameter is the size in bytes of the associated real instruction. | |
1569 class Alias<int size, dag outs, dag ins, list<dag> pattern> | |
1570 : InstSystemZ<size, outs, ins, "", pattern> { | |
1571 let isPseudo = 1; | |
1572 let isCodeGenOnly = 1; | |
1573 } | |
1574 | |
1575 // An alias of a BinaryRI, but with different register sizes. | |
1576 class BinaryAliasRI<SDPatternOperator operator, RegisterOperand cls, | |
1577 Immediate imm> | |
1578 : Alias<4, (outs cls:$R1), (ins cls:$R1src, imm:$I2), | |
1579 [(set cls:$R1, (operator cls:$R1src, imm:$I2))]> { | |
1580 let Constraints = "$R1 = $R1src"; | |
1581 } | |
1582 | |
1583 // An alias of a BinaryRIL, but with different register sizes. | |
1584 class BinaryAliasRIL<SDPatternOperator operator, RegisterOperand cls, | |
1585 Immediate imm> | |
1586 : Alias<6, (outs cls:$R1), (ins cls:$R1src, imm:$I2), | |
1587 [(set cls:$R1, (operator cls:$R1src, imm:$I2))]> { | |
1588 let Constraints = "$R1 = $R1src"; | |
1589 } | |
1590 | |
1591 // An alias of a CompareRI, but with different register sizes. | |
1592 class CompareAliasRI<SDPatternOperator operator, RegisterOperand cls, | |
1593 Immediate imm> | |
1594 : Alias<4, (outs), (ins cls:$R1, imm:$I2), [(operator cls:$R1, imm:$I2)]> { | |
1595 let isCompare = 1; | |
1596 } | |
1597 | |
1598 // An alias of a RotateSelectRIEf, but with different register sizes. | |
1599 class RotateSelectAliasRIEf<RegisterOperand cls1, RegisterOperand cls2> | |
1600 : Alias<6, (outs cls1:$R1), | |
1601 (ins cls1:$R1src, cls2:$R2, uimm8:$I3, uimm8:$I4, uimm8zx6:$I5), []> { | |
1602 let Constraints = "$R1 = $R1src"; | |
1603 } |