Rename SDOperand to SDValue.
[oota-llvm.git] / lib / Target / CellSPU / SPUOperands.td
1 //===- SPUOperands.td - Cell SPU Instruction Operands ------*- 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 // Cell SPU Instruction Operands:
10 //===----------------------------------------------------------------------===//
11
12 def LO16 : SDNodeXForm<imm, [{
13   unsigned val = N->getValue();
14   // Transformation function: get the low 16 bits.
15   return getI32Imm(val & 0xffff);
16 }]>;
17
18 def LO16_vec : SDNodeXForm<scalar_to_vector, [{
19   SDValue OpVal(0, 0);
20
21   // Transformation function: get the low 16 bit immediate from a build_vector
22   // node.
23   assert(N->getOpcode() == ISD::BUILD_VECTOR
24          && "LO16_vec got something other than a BUILD_VECTOR");
25
26   // Get first constant operand...
27   for (unsigned i = 0, e = N->getNumOperands(); OpVal.Val == 0 && i != e; ++i) {
28     if (N->getOperand(i).getOpcode() == ISD::UNDEF) continue;
29     if (OpVal.Val == 0)
30       OpVal = N->getOperand(i);
31   }
32   
33   assert(OpVal.Val != 0 && "LO16_vec did not locate a <defined> node");
34   ConstantSDNode *CN = dyn_cast<ConstantSDNode>(OpVal);
35   return getI32Imm((unsigned)CN->getValue() & 0xffff);
36 }]>;
37
38 // Transform an immediate, returning the high 16 bits shifted down:
39 def HI16 : SDNodeXForm<imm, [{
40   return getI32Imm((unsigned)N->getValue() >> 16);
41 }]>;
42
43 // Transformation function: shift the high 16 bit immediate from a build_vector
44 // node into the low 16 bits, and return a 16-bit constant.
45 def HI16_vec : SDNodeXForm<scalar_to_vector, [{
46   SDValue OpVal(0, 0);
47
48   assert(N->getOpcode() == ISD::BUILD_VECTOR
49          && "HI16_vec got something other than a BUILD_VECTOR");
50   
51   // Get first constant operand...
52   for (unsigned i = 0, e = N->getNumOperands(); OpVal.Val == 0 && i != e; ++i) {
53     if (N->getOperand(i).getOpcode() == ISD::UNDEF) continue;
54     if (OpVal.Val == 0)
55       OpVal = N->getOperand(i);
56   }
57   
58   assert(OpVal.Val != 0 && "HI16_vec did not locate a <defined> node");
59   ConstantSDNode *CN = dyn_cast<ConstantSDNode>(OpVal);
60   return getI32Imm((unsigned)CN->getValue() >> 16);
61 }]>;
62
63 // simm7 predicate - True if the immediate fits in an 7-bit signed
64 // field.
65 def simm7: PatLeaf<(imm), [{
66   int sextVal = int(N->getSignExtended());
67   return (sextVal >= -64 && sextVal <= 63);
68 }]>;
69
70 // uimm7 predicate - True if the immediate fits in an 7-bit unsigned
71 // field.
72 def uimm7: PatLeaf<(imm), [{
73   return (N->getValue() <= 0x7f);
74 }]>;
75
76 // immSExt8 predicate - True if the immediate fits in an 8-bit sign extended
77 // field.
78 def immSExt8  : PatLeaf<(imm), [{
79   int Value = int(N->getSignExtended());
80   return (Value >= -(1 << 8) && Value <= (1 << 8) - 1);
81 }]>;
82
83 // immU8: immediate, unsigned 8-bit quantity
84 def immU8 : PatLeaf<(imm), [{
85   return (N->getValue() <= 0xff);
86 }]>;
87
88 // i64ImmSExt10 predicate - True if the i64 immediate fits in a 10-bit sign
89 // extended field.  Used by RI10Form instructions like 'ldq'.
90 def i64ImmSExt10  : PatLeaf<(imm), [{
91   return isI64IntS10Immediate(N);
92 }]>;
93
94 // i32ImmSExt10 predicate - True if the i32 immediate fits in a 10-bit sign
95 // extended field.  Used by RI10Form instructions like 'ldq'.
96 def i32ImmSExt10  : PatLeaf<(imm), [{
97   return isI32IntS10Immediate(N);
98 }]>;
99
100 // i32ImmUns10 predicate - True if the i32 immediate fits in a 10-bit unsigned
101 // field.  Used by RI10Form instructions like 'ldq'.
102 def i32ImmUns10  : PatLeaf<(imm), [{
103   return isI32IntU10Immediate(N);
104 }]>;
105
106 // i16ImmSExt10 predicate - True if the i16 immediate fits in a 10-bit sign
107 // extended field.  Used by RI10Form instructions like 'ldq'.
108 def i16ImmSExt10  : PatLeaf<(imm), [{
109   return isI16IntS10Immediate(N);
110 }]>;
111
112 // i16ImmUns10 predicate - True if the i16 immediate fits into a 10-bit unsigned
113 // value. Used by RI10Form instructions.
114 def i16ImmUns10 : PatLeaf<(imm), [{
115   return isI16IntU10Immediate(N);
116 }]>;
117
118 def immSExt16  : PatLeaf<(imm), [{
119   // immSExt16 predicate - True if the immediate fits in a 16-bit sign extended
120   // field.
121   short Ignored;
122   return isIntS16Immediate(N, Ignored);
123 }]>;
124
125 def immZExt16  : PatLeaf<(imm), [{
126   // immZExt16 predicate - True if the immediate fits in a 16-bit zero extended
127   // field.
128   return (uint64_t)N->getValue() == (unsigned short)N->getValue();
129 }], LO16>;
130
131 def immU16 : PatLeaf<(imm), [{
132   // immU16 predicate- True if the immediate fits into a 16-bit unsigned field.
133   return (uint64_t)N->getValue() == (N->getValue() & 0xffff);
134 }]>;
135
136 def imm18  : PatLeaf<(imm), [{
137   // imm18 predicate: True if the immediate fits into an 18-bit unsigned field.
138   int Value = (int) N->getValue();
139   return ((Value & ((1 << 19) - 1)) == Value);
140 }]>;
141
142 def lo16 : PatLeaf<(imm), [{
143   // lo16 predicate - returns true if the immediate has all zeros in the
144   // low order bits and is a 32-bit constant:
145   if (N->getValueType(0) == MVT::i32) {
146     uint32_t val = N->getValue();
147     return ((val & 0x0000ffff) == val);
148   }
149
150   return false;
151 }], LO16>;
152
153 def hi16 : PatLeaf<(imm), [{
154   // hi16 predicate - returns true if the immediate has all zeros in the
155   // low order bits and is a 32-bit constant:
156   if (N->getValueType(0) == MVT::i32) {
157     uint32_t val = uint32_t(N->getValue());
158     return ((val & 0xffff0000) == val);
159   } else if (N->getValueType(0) == MVT::i64) {
160     uint64_t val = N->getValue();
161     return ((val & 0xffff0000ULL) == val);
162   }
163
164   return false;
165 }], HI16>;
166
167 def bitshift : PatLeaf<(imm), [{
168   // bitshift predicate - returns true if 0 < imm <= 7 for SHLQBII
169   // (shift left quadword by bits immediate)
170   int64_t Val = N->getValue();
171   return (Val > 0 && Val <= 7);
172 }]>;
173
174 //===----------------------------------------------------------------------===//
175 // Floating point operands:
176 //===----------------------------------------------------------------------===//
177
178 // Transform a float, returning the high 16 bits shifted down, as if
179 // the float was really an unsigned integer:
180 def HI16_f32 : SDNodeXForm<fpimm, [{
181   float fval = N->getValueAPF().convertToFloat();
182   return getI32Imm(FloatToBits(fval) >> 16);
183 }]>;
184
185 // Transformation function on floats: get the low 16 bits as if the float was
186 // an unsigned integer.
187 def LO16_f32 : SDNodeXForm<fpimm, [{
188   float fval = N->getValueAPF().convertToFloat();
189   return getI32Imm(FloatToBits(fval) & 0xffff);
190 }]>;
191
192 def FPimm_sext16 : SDNodeXForm<fpimm, [{
193   float fval = N->getValueAPF().convertToFloat();
194   return getI32Imm((int) ((FloatToBits(fval) << 16) >> 16));
195 }]>;
196
197 def FPimm_u18 : SDNodeXForm<fpimm, [{
198   float fval = N->getValueAPF().convertToFloat();
199   return getI32Imm(FloatToBits(fval) & ((1 << 19) - 1));
200 }]>;
201
202 def fpimmSExt16 : PatLeaf<(fpimm), [{
203   short Ignored;
204   return isFPS16Immediate(N, Ignored);  
205 }], FPimm_sext16>;
206
207 // Does the SFP constant only have upp 16 bits set?
208 def hi16_f32 : PatLeaf<(fpimm), [{
209   if (N->getValueType(0) == MVT::f32) {
210     uint32_t val = FloatToBits(N->getValueAPF().convertToFloat());
211     return ((val & 0xffff0000) == val);
212   }
213
214   return false;
215 }], HI16_f32>;
216
217 // Does the SFP constant fit into 18 bits?
218 def fpimm18  : PatLeaf<(fpimm), [{
219   if (N->getValueType(0) == MVT::f32) {
220     uint32_t Value = FloatToBits(N->getValueAPF().convertToFloat());
221     return ((Value & ((1 << 19) - 1)) == Value);
222   }
223
224   return false;
225 }], FPimm_u18>;
226
227 //===----------------------------------------------------------------------===//
228 // 64-bit operands (TODO):
229 //===----------------------------------------------------------------------===//
230
231 //===----------------------------------------------------------------------===//
232 // build_vector operands:
233 //===----------------------------------------------------------------------===//
234
235 // v16i8SExt8Imm_xform function: convert build_vector to 8-bit sign extended
236 // immediate constant load for v16i8 vectors. N.B.: The incoming constant has
237 // to be a 16-bit quantity with the upper and lower bytes equal (e.g., 0x2a2a).
238 def v16i8SExt8Imm_xform: SDNodeXForm<build_vector, [{
239   return SPU::get_vec_i8imm(N, *CurDAG, MVT::i8);
240 }]>;
241
242 // v16i8SExt8Imm: Predicate test for 8-bit sign extended immediate constant
243 // load, works in conjunction with its transform function. N.B.: This relies the
244 // incoming constant being a 16-bit quantity, where the upper and lower bytes
245 // are EXACTLY the same (e.g., 0x2a2a)
246 def v16i8SExt8Imm: PatLeaf<(build_vector), [{
247   return SPU::get_vec_i8imm(N, *CurDAG, MVT::i8).Val != 0;
248 }], v16i8SExt8Imm_xform>;
249
250 // v16i8U8Imm_xform function: convert build_vector to unsigned 8-bit
251 // immediate constant load for v16i8 vectors. N.B.: The incoming constant has
252 // to be a 16-bit quantity with the upper and lower bytes equal (e.g., 0x2a2a).
253 def v16i8U8Imm_xform: SDNodeXForm<build_vector, [{
254   return SPU::get_vec_i8imm(N, *CurDAG, MVT::i8);
255 }]>;
256
257 // v16i8U8Imm: Predicate test for unsigned 8-bit immediate constant
258 // load, works in conjunction with its transform function. N.B.: This relies the
259 // incoming constant being a 16-bit quantity, where the upper and lower bytes
260 // are EXACTLY the same (e.g., 0x2a2a)
261 def v16i8U8Imm: PatLeaf<(build_vector), [{
262   return SPU::get_vec_i8imm(N, *CurDAG, MVT::i8).Val != 0;
263 }], v16i8U8Imm_xform>;
264
265 // v8i16SExt8Imm_xform function: convert build_vector to 8-bit sign extended
266 // immediate constant load for v8i16 vectors.
267 def v8i16SExt8Imm_xform: SDNodeXForm<build_vector, [{
268   return SPU::get_vec_i8imm(N, *CurDAG, MVT::i16);
269 }]>;
270
271 // v8i16SExt8Imm: Predicate test for 8-bit sign extended immediate constant
272 // load, works in conjunction with its transform function.
273 def v8i16SExt8Imm: PatLeaf<(build_vector), [{
274   return SPU::get_vec_i8imm(N, *CurDAG, MVT::i16).Val != 0;
275 }], v8i16SExt8Imm_xform>;
276
277 // v8i16SExt10Imm_xform function: convert build_vector to 16-bit sign extended
278 // immediate constant load for v8i16 vectors.
279 def v8i16SExt10Imm_xform: SDNodeXForm<build_vector, [{
280   return SPU::get_vec_i10imm(N, *CurDAG, MVT::i16);
281 }]>;
282
283 // v8i16SExt10Imm: Predicate test for 16-bit sign extended immediate constant
284 // load, works in conjunction with its transform function.
285 def v8i16SExt10Imm: PatLeaf<(build_vector), [{
286   return SPU::get_vec_i10imm(N, *CurDAG, MVT::i16).Val != 0;
287 }], v8i16SExt10Imm_xform>;
288
289 // v8i16Uns10Imm_xform function: convert build_vector to 16-bit unsigned
290 // immediate constant load for v8i16 vectors.
291 def v8i16Uns10Imm_xform: SDNodeXForm<build_vector, [{
292   return SPU::get_vec_i10imm(N, *CurDAG, MVT::i16);
293 }]>;
294
295 // v8i16Uns10Imm: Predicate test for 16-bit unsigned immediate constant
296 // load, works in conjunction with its transform function.
297 def v8i16Uns10Imm: PatLeaf<(build_vector), [{
298   return SPU::get_vec_i10imm(N, *CurDAG, MVT::i16).Val != 0;
299 }], v8i16Uns10Imm_xform>;
300
301 // v8i16SExt16Imm_xform function: convert build_vector to 16-bit sign extended
302 // immediate constant load for v8i16 vectors.
303 def v8i16Uns16Imm_xform: SDNodeXForm<build_vector, [{
304   return SPU::get_vec_i16imm(N, *CurDAG, MVT::i16);
305 }]>;
306
307 // v8i16SExt16Imm: Predicate test for 16-bit sign extended immediate constant
308 // load, works in conjunction with its transform function.
309 def v8i16SExt16Imm: PatLeaf<(build_vector), [{
310   return SPU::get_vec_i16imm(N, *CurDAG, MVT::i16).Val != 0;
311 }], v8i16Uns16Imm_xform>;
312
313 // v4i32SExt10Imm_xform function: convert build_vector to 10-bit sign extended
314 // immediate constant load for v4i32 vectors.
315 def v4i32SExt10Imm_xform: SDNodeXForm<build_vector, [{
316   return SPU::get_vec_i10imm(N, *CurDAG, MVT::i32);
317 }]>;
318
319 // v4i32SExt10Imm: Predicate test for 10-bit sign extended immediate constant
320 // load, works in conjunction with its transform function.
321 def v4i32SExt10Imm: PatLeaf<(build_vector), [{
322   return SPU::get_vec_i10imm(N, *CurDAG, MVT::i32).Val != 0;
323 }], v4i32SExt10Imm_xform>;
324
325 // v4i32Uns10Imm_xform function: convert build_vector to 10-bit unsigned
326 // immediate constant load for v4i32 vectors.
327 def v4i32Uns10Imm_xform: SDNodeXForm<build_vector, [{
328   return SPU::get_vec_i10imm(N, *CurDAG, MVT::i32);
329 }]>;
330
331 // v4i32Uns10Imm: Predicate test for 10-bit unsigned immediate constant
332 // load, works in conjunction with its transform function.
333 def v4i32Uns10Imm: PatLeaf<(build_vector), [{
334   return SPU::get_vec_i10imm(N, *CurDAG, MVT::i32).Val != 0;
335 }], v4i32Uns10Imm_xform>;
336
337 // v4i32SExt16Imm_xform function: convert build_vector to 16-bit sign extended
338 // immediate constant load for v4i32 vectors.
339 def v4i32SExt16Imm_xform: SDNodeXForm<build_vector, [{
340   return SPU::get_vec_i16imm(N, *CurDAG, MVT::i32);
341 }]>;
342
343 // v4i32SExt16Imm: Predicate test for 16-bit sign extended immediate constant
344 // load, works in conjunction with its transform function.
345 def v4i32SExt16Imm: PatLeaf<(build_vector), [{
346   return SPU::get_vec_i16imm(N, *CurDAG, MVT::i32).Val != 0;
347 }], v4i32SExt16Imm_xform>;
348
349 // v4i32Uns18Imm_xform function: convert build_vector to 18-bit unsigned
350 // immediate constant load for v4i32 vectors.
351 def v4i32Uns18Imm_xform: SDNodeXForm<build_vector, [{
352   return SPU::get_vec_u18imm(N, *CurDAG, MVT::i32);
353 }]>;
354
355 // v4i32Uns18Imm: Predicate test for 18-bit unsigned immediate constant load,
356 // works in conjunction with its transform function.
357 def v4i32Uns18Imm: PatLeaf<(build_vector), [{
358   return SPU::get_vec_u18imm(N, *CurDAG, MVT::i32).Val != 0;
359 }], v4i32Uns18Imm_xform>;
360
361 // ILHUvec_get_imm xform function: convert build_vector to ILHUvec imm constant
362 // load.
363 def ILHUvec_get_imm: SDNodeXForm<build_vector, [{
364   return SPU::get_ILHUvec_imm(N, *CurDAG, MVT::i32);
365 }]>;
366
367 /// immILHUvec: Predicate test for a ILHU constant vector.
368 def immILHUvec: PatLeaf<(build_vector), [{
369   return SPU::get_ILHUvec_imm(N, *CurDAG, MVT::i32).Val != 0;
370 }], ILHUvec_get_imm>;
371
372 // Catch-all for any other i32 vector constants
373 def v4i32_get_imm: SDNodeXForm<build_vector, [{
374   return SPU::get_v4i32_imm(N, *CurDAG);
375 }]>;
376
377 def v4i32Imm: PatLeaf<(build_vector), [{
378   return SPU::get_v4i32_imm(N, *CurDAG).Val != 0;
379 }], v4i32_get_imm>;
380
381 // v2i64SExt10Imm_xform function: convert build_vector to 10-bit sign extended
382 // immediate constant load for v2i64 vectors.
383 def v2i64SExt10Imm_xform: SDNodeXForm<build_vector, [{
384   return SPU::get_vec_i10imm(N, *CurDAG, MVT::i64);
385 }]>;
386
387 // v2i64SExt10Imm: Predicate test for 10-bit sign extended immediate constant
388 // load, works in conjunction with its transform function.
389 def v2i64SExt10Imm: PatLeaf<(build_vector), [{
390   return SPU::get_vec_i10imm(N, *CurDAG, MVT::i64).Val != 0;
391 }], v2i64SExt10Imm_xform>;
392
393 // v2i64SExt16Imm_xform function: convert build_vector to 16-bit sign extended
394 // immediate constant load for v2i64 vectors.
395 def v2i64SExt16Imm_xform: SDNodeXForm<build_vector, [{
396   return SPU::get_vec_i16imm(N, *CurDAG, MVT::i64);
397 }]>;
398
399 // v2i64SExt16Imm: Predicate test for 16-bit sign extended immediate constant
400 // load, works in conjunction with its transform function.
401 def v2i64SExt16Imm: PatLeaf<(build_vector), [{
402   return SPU::get_vec_i16imm(N, *CurDAG, MVT::i64).Val != 0;
403 }], v2i64SExt16Imm_xform>;
404
405 // v2i64Uns18Imm_xform function: convert build_vector to 18-bit unsigned
406 // immediate constant load for v2i64 vectors.
407 def v2i64Uns18Imm_xform: SDNodeXForm<build_vector, [{
408   return SPU::get_vec_u18imm(N, *CurDAG, MVT::i64);
409 }]>;
410
411 // v2i64Uns18Imm: Predicate test for 18-bit unsigned immediate constant load,
412 // works in conjunction with its transform function.
413 def v2i64Uns18Imm: PatLeaf<(build_vector), [{
414   return SPU::get_vec_u18imm(N, *CurDAG, MVT::i64).Val != 0;
415 }], v2i64Uns18Imm_xform>;
416
417 /// immILHUvec: Predicate test for a ILHU constant vector.
418 def immILHUvec_i64: PatLeaf<(build_vector), [{
419   return SPU::get_ILHUvec_imm(N, *CurDAG, MVT::i64).Val != 0;
420 }], ILHUvec_get_imm>;
421
422 // Catch-all for any other i32 vector constants
423 def v2i64_get_imm: SDNodeXForm<build_vector, [{
424   return SPU::get_v2i64_imm(N, *CurDAG);
425 }]>;
426
427 def v2i64Imm: PatLeaf<(build_vector), [{
428   return SPU::get_v2i64_imm(N, *CurDAG).Val != 0;
429 }], v2i64_get_imm>;
430
431 //===----------------------------------------------------------------------===//
432 // Operand Definitions.
433
434 def s7imm: Operand<i8> {
435   let PrintMethod = "printS7ImmOperand";
436 }
437
438 def s7imm_i8: Operand<i8> {
439   let PrintMethod = "printS7ImmOperand";
440 }
441
442 def u7imm: Operand<i16> {
443   let PrintMethod = "printU7ImmOperand";
444 }
445
446 def u7imm_i8: Operand<i8> {
447   let PrintMethod = "printU7ImmOperand";
448 }
449
450 def u7imm_i32: Operand<i32> {
451   let PrintMethod = "printU7ImmOperand";
452 }
453
454 // Halfword, signed 10-bit constant
455 def s10imm : Operand<i16> {
456   let PrintMethod = "printS10ImmOperand";
457 }
458
459 def s10imm_i8: Operand<i8> {
460   let PrintMethod = "printS10ImmOperand";
461 }
462
463 def s10imm_i32: Operand<i32> {
464   let PrintMethod = "printS10ImmOperand";
465 }
466
467 def s10imm_i64: Operand<i64> {
468   let PrintMethod = "printS10ImmOperand";
469 }
470
471 // Unsigned 10-bit integers:
472 def u10imm: Operand<i16> {
473   let PrintMethod = "printU10ImmOperand";
474 }
475
476 def u10imm_i8: Operand<i8> {
477   let PrintMethod = "printU10ImmOperand";
478 }
479
480 def u10imm_i32: Operand<i32> {
481   let PrintMethod = "printU10ImmOperand";
482 }
483
484 def s16imm  : Operand<i16> {
485   let PrintMethod = "printS16ImmOperand";
486 }
487
488 def s16imm_i8: Operand<i8> {
489   let PrintMethod = "printS16ImmOperand";
490 }
491
492 def s16imm_i32: Operand<i32> {
493   let PrintMethod = "printS16ImmOperand";
494 }
495
496 def s16imm_i64: Operand<i64> {
497   let PrintMethod = "printS16ImmOperand";
498 }
499
500 def s16imm_f32: Operand<f32> {
501   let PrintMethod = "printS16ImmOperand";
502 }
503
504 def s16imm_f64: Operand<f64> {
505   let PrintMethod = "printS16ImmOperand";
506 }
507
508 def u16imm_i64 : Operand<i64> {
509   let PrintMethod = "printU16ImmOperand";
510 }
511
512 def u16imm_i32 : Operand<i32> {
513   let PrintMethod = "printU16ImmOperand";
514 }
515
516 def u16imm : Operand<i16> {
517   let PrintMethod = "printU16ImmOperand";
518 }
519
520 def f16imm : Operand<f32> {
521   let PrintMethod = "printU16ImmOperand";
522 }
523
524 def s18imm  : Operand<i32> {
525   let PrintMethod = "printS18ImmOperand";
526 }
527
528 def u18imm : Operand<i32> {
529   let PrintMethod = "printU18ImmOperand";
530 }
531
532 def u18imm_i64 : Operand<i64> {
533   let PrintMethod = "printU18ImmOperand";
534 }
535
536 def f18imm : Operand<f32> {
537   let PrintMethod = "printU18ImmOperand";
538 }
539
540 def f18imm_f64 : Operand<f64> {
541   let PrintMethod = "printU18ImmOperand";
542 }
543
544 // Negated 7-bit halfword rotate immediate operands
545 def rothNeg7imm : Operand<i32> {
546   let PrintMethod = "printROTHNeg7Imm";
547 }
548
549 def rothNeg7imm_i16 : Operand<i16> {
550   let PrintMethod = "printROTHNeg7Imm";
551 }
552
553 // Negated 7-bit word rotate immediate operands
554 def rotNeg7imm : Operand<i32> {
555   let PrintMethod = "printROTNeg7Imm";
556 }
557
558 def rotNeg7imm_i16 : Operand<i16> {
559   let PrintMethod = "printROTNeg7Imm";
560 }
561
562 def rotNeg7imm_i8 : Operand<i8> {
563   let PrintMethod = "printROTNeg7Imm";
564 }
565
566 def target : Operand<OtherVT> {
567   let PrintMethod = "printBranchOperand";
568 }
569
570 // Absolute address call target
571 def calltarget : Operand<iPTR> {
572   let PrintMethod = "printCallOperand";
573   let MIOperandInfo = (ops u18imm:$calldest);
574 }
575
576 // Relative call target
577 def relcalltarget : Operand<iPTR> {
578   let PrintMethod = "printPCRelativeOperand";
579   let MIOperandInfo = (ops s16imm:$calldest);
580 }
581
582 // Branch targets:
583 def brtarget : Operand<OtherVT> {
584   let PrintMethod = "printPCRelativeOperand";
585 }
586
587 // Indirect call target
588 def indcalltarget : Operand<iPTR> {
589   let PrintMethod = "printCallOperand";
590   let MIOperandInfo = (ops ptr_rc:$calldest);
591 }
592
593 def symbolHi: Operand<i32> {
594   let PrintMethod = "printSymbolHi";
595 }
596
597 def symbolLo: Operand<i32> {
598   let PrintMethod = "printSymbolLo";
599 }
600
601 def symbolLSA: Operand<i32> {
602   let PrintMethod = "printSymbolLSA";
603 }
604
605 // memory s7imm(reg) operaand
606 def memri7 : Operand<iPTR> {
607   let PrintMethod = "printMemRegImmS7";
608   let MIOperandInfo = (ops s7imm:$imm, ptr_rc:$reg);
609 }
610
611 // memory s10imm(reg) operand
612 def memri10 : Operand<iPTR> {
613   let PrintMethod = "printMemRegImmS10";
614   let MIOperandInfo = (ops s10imm:$imm, ptr_rc:$reg);
615 }
616
617 // 256K local store address
618 // N.B.: The tblgen code generator expects to have two operands, an offset
619 // and a pointer. Of these, only the immediate is actually used.
620 def addr256k : Operand<iPTR> {
621   let PrintMethod = "printAddr256K";
622   let MIOperandInfo = (ops s16imm:$imm, ptr_rc:$reg);
623 }
624
625 // memory s18imm(reg) operand
626 def memri18 : Operand<iPTR> {
627   let PrintMethod = "printMemRegImmS18";
628   let MIOperandInfo = (ops s18imm:$imm, ptr_rc:$reg);
629 }
630
631 // memory register + register operand
632 def memrr : Operand<iPTR> {
633   let PrintMethod = "printMemRegReg";
634   let MIOperandInfo = (ops ptr_rc:$reg_a, ptr_rc:$reg_b);
635 }
636
637 // Define SPU-specific addressing modes: These come in three basic
638 // flavors:
639 //
640 // D-form   : [r+I10] (10-bit signed offset + reg)
641 // X-form   : [r+r]   (reg+reg)
642 // A-form   : abs     (256K LSA offset)
643 // D-form(2): [r+I7]  (7-bit signed offset + reg)
644
645 def dform_addr   : ComplexPattern<iPTR, 2, "SelectDFormAddr",     [], []>;
646 def xform_addr   : ComplexPattern<iPTR, 2, "SelectXFormAddr",     [], []>;
647 def aform_addr   : ComplexPattern<iPTR, 2, "SelectAFormAddr",     [], []>;
648 def dform2_addr  : ComplexPattern<iPTR, 2, "SelectDForm2Addr",    [], []>;