sim-main.h: Re-arange r5900 registers so that they have their own
[deliverable/binutils-gdb.git] / sim / mips / mdmx.igen
CommitLineData
35c246c9
AC
1// Media Instructions
2// ------------------
3
4// Ref: http://www.sgi.com/MIPS/arch/ISA5/MDMXspec.pdf
5
6// Note: For OB instructions, the sel field is deduced by special
7// handling of the "vt" operand.
8// If vt is:
9// of the form $vt[0], then sel is 0000
10// of the form $vt[1], then sel is 0001
11// of the form $vt[2], then sel is 0010
12// of the form $vt[3], then sel is 0011
13// of the form $vt[4], then sel is 0100
14// of the form $vt[5], then sel is 0101
15// of the form $vt[6], then sel is 0110
16// of the form $vt[7], then sel is 0111
17// Normal register specifier, then sel is 1011
18// Constant, then sel is 1111
19//
20// VecAcc is the Vector Accumulator.
21// This accumulator is organized as 8X24 bit (192 bit) register.
22// This accumulator holds only signed values.
23
24
25// Verify that the instruction is valid for the curent Architecture
26// If valid, return the scale (log nr bits) of a vector element
27// as determined by SEL.
28
a48e8c8d
AC
29:function:64,f::int:get_scale:int sel
30*mdmx:
31// start-sanitize-vr5400
32*vr5400:
33// end-sanitize-vr5400
35c246c9
AC
34{
35#if 0
36 switch (my_index X STATE_ARCHITECTURE)
37 {
38 }
39#endif
40 switch (sel & 0x7)
41 {
42 case 0:
43 case 2:
44 case 4:
45 case 6:
46 /* octal byte - ssss0 */
47 return 0;
48 case 1:
49 case 5:
50 /* quad halfword - sss01 */
51 return 1;
52 case 3:
53 /* bi word - ss011 */
01737f42 54 semantic_illegal (CPU_, cia);
35c246c9
AC
55 return 2;
56 case 7:
57 /* long - ss111 */
01737f42 58 semantic_illegal (CPU_, cia);
35c246c9
AC
59 return 3;
60 default:
61 abort ();
62 return -1;
63 }
64}
65
66
67// Fetch/Store VALUE in ELEMENT of vector register FPR.
68// The the of the element determined by SCALE.
69
a48e8c8d
AC
70:function:64,f::signed:value_vr:int scale, int fpr, int el
71*mdmx:
72// start-sanitize-vr5400
73*vr5400:
74// end-sanitize-vr5400
35c246c9
AC
75{
76 switch (FPR_STATE[fpr])
77 {
78 case fmt_uninterpreted:
79 FPR_STATE[fpr] = fmt_long;
80 break;
81 case fmt_long:
82 case fmt_unknown:
83 break;
84 default:
01737f42
AC
85 sim_io_eprintf (SD, "Vector %d format invalid (PC = 0x%08lx)\n",
86 fpr, (long) CIA);
35c246c9
AC
87 FPR_STATE[fpr] = fmt_unknown;
88 }
89 switch (scale)
90 {
91 case 0:
92 {
93 signed8 value = *A1_8 (&FGR[fpr], 7 - el);
94 return value;
95 }
96 case 1:
97 {
98 signed16 value = *A2_8 (&FGR[fpr], 3 - el);
99 return value;
100 }
101 default:
102 abort;
103 }
104 return 0;
105}
106
a48e8c8d
AC
107:function:64,f::void:store_vr:int scale, int fpr, int element, signed value
108*mdmx:
109// start-sanitize-vr5400
110*vr5400:
111// end-sanitize-vr5400
35c246c9
AC
112{
113 switch (FPR_STATE[fpr])
114 {
115 case fmt_uninterpreted:
116 FPR_STATE[fpr] = fmt_long;
117 break;
118 case fmt_long:
119 case fmt_unknown:
120 break;
121 default:
01737f42
AC
122 sim_io_eprintf (SD, "Vector %d format invalid (PC = 0x%08lx)\n",
123 fpr, (long) cia);
35c246c9
AC
124 FPR_STATE[fpr] = fmt_unknown;
125 }
126 switch (scale)
127 {
128 case 0:
129 {
130 *A1_8 (&FGR[fpr], 7 - element) = value;
131 break;
132 }
133 case 1:
134 {
135 *A2_8 (&FGR[fpr], 3 - element) = value;
136 break;
137 }
138 default:
139 abort ();
140 }
141}
142
143
144// Select a value from onr of FGR[VT][ELEMENT], VT and GFR[VT][CONST]
145// according to SEL
146
a48e8c8d
AC
147:function:64,f::unsigned:select_vr:int sel, int vt, int element
148*mdmx:
149// start-sanitize-vr5400
150*vr5400:
151// end-sanitize-vr5400
35c246c9
AC
152{
153 switch (sel)
154 {
155 /* element select - 0xxxx */
156 case 0x00: /* 0 xxx 0 */
157 case 0x02:
158 case 0x04:
159 case 0x06:
160 case 0x08:
161 case 0x0a:
162 case 0x0c:
163 case 0x0e:
164 return value_vr (SD_, 0, vt, sel >> 1);
165 case 0x01: /* 0 xx 01 */
166 case 0x05:
167 case 0x09:
168 case 0x0d:
169 return value_vr (SD_, 1, vt, sel >> 2);
170 case 0x03: /* 0 x 011 */
171 case 0x0b:
172 return value_vr (SD_, 2, vt, sel >> 3);
173 case 0x07: /* 0 x 111 */
174 case 0x0f:
175 return value_vr (SD_, 3, vt, sel >> 4);
176
177 /* select vector - 10xxx */
178 case 0x16: /* 10 11 0 */
179 return value_vr (SD_, 0, vt, element);
180 case 0x15: /* 10 1 01 */
181 return value_vr (SD_, 1, vt, element);
182 case 0x13: /* 10 011 */
183 return value_vr (SD_, 2, vt, element);
184 case 0x17: /* 10 111 */
185 return value_vr (SD_, 3, vt, element);
186
187 /* select immediate - 11xxx */
188 case 0x1e: /* 11 11 0 */
189 case 0x1d: /* 11 1 01 */
190 case 0x1b: /* 11 011 */
191 case 0x1f: /* 11 111 */
192 return vt;
193
194 }
195 return 0;
196}
197
198
199// Saturate (clamp) the signed value to (8 << SCALE) bits.
200
a48e8c8d
AC
201:function:64,f::signed:Clamp:int scale, signed value
202*mdmx:
203// start-sanitize-vr5400
204*vr5400:
205// end-sanitize-vr5400
35c246c9
AC
206{
207 switch (scale)
208 {
209 case 0:
210 {
211 if (value != (signed8) value)
212 {
213 if (value > 0)
214 return 0x7f;
215 else
216 return 0x80;
217 }
218 return value & 0xff;
219 }
220 case 1:
221 {
222 if (value != (signed16) value)
223 {
224 if (value > 0)
225 return 0x7fff;
226 else
227 return 0x8000;
228 }
229 return value & 0xffff;
230 }
231 default:
232 abort ();
233 return 0;
234 }
235}
236
237
238// Access a single bit of the floating point CC register.
239
a48e8c8d
AC
240:function:64,f::void:store_cc:int i, int value
241*mdmx:
242// start-sanitize-vr5400
243*vr5400:
244// end-sanitize-vr5400
35c246c9 245{
01737f42 246 SETFCC (i, value);
35c246c9
AC
247}
248
a48e8c8d
AC
249:function:64,f::int:value_cc:int i
250*mdmx:
251// start-sanitize-vr5400
252*vr5400:
253// end-sanitize-vr5400
35c246c9 254{
01737f42 255 return GETFCC (i);
35c246c9
AC
256}
257
258
259// Read/write the accumulator
260
a48e8c8d
AC
261:function:64,f::signed64:value_acc:int scale, int element
262*mdmx:
263// start-sanitize-vr5400
264*vr5400:
265// end-sanitize-vr5400
35c246c9
AC
266{
267 signed64 value = 0;
268 switch (scale)
269 {
270 case 0:
271 value |= (unsigned64) (unsigned8) CPU->acc [element * 3 + 0];
272 value |= (unsigned64) (unsigned8) CPU->acc [element * 3 + 1] << 8;
273 value |= (signed64) (signed8) CPU->acc [element * 3 + 2] << 16;
274 break;
275 case 1:
276 value |= (unsigned64) (unsigned8) CPU->acc [element * 3 + 0];
277 value |= (unsigned64) (unsigned8) CPU->acc [element * 3 + 1] << 8;
278 value |= (unsigned64) (unsigned8) CPU->acc [element * 3 + 2] << 16;
279 value |= (unsigned64) (unsigned8) CPU->acc [element * 3 + 3] << 24;
280 value |= (unsigned64) (unsigned8) CPU->acc [element * 3 + 4] << 32;
281 value |= (signed64) (signed8) CPU->acc [element * 3 + 5] << 40;
282 break;
283 }
284 return value;
285}
286
a48e8c8d
AC
287:function:64,f::void:store_acc:int scale, int element, signed64 value
288*mdmx:
289// start-sanitize-vr5400
290*vr5400:
291// end-sanitize-vr5400
35c246c9
AC
292{
293 switch (scale)
294 {
295 case 0:
296 CPU->acc [element * 3 + 0] = value >> 0;
297 CPU->acc [element * 3 + 1] = value >> 8;
298 CPU->acc [element * 3 + 2] = value >> 16;
299 break;
300 case 1:
301 CPU->acc [element * 3 + 0] = value >> 0;
302 CPU->acc [element * 3 + 1] = value >> 8;
303 CPU->acc [element * 3 + 2] = value >> 16;
304 CPU->acc [element * 3 + 3] = value >> 24;
305 CPU->acc [element * 3 + 4] = value >> 32;
306 CPU->acc [element * 3 + 5] = value >> 40;
307 break;
308 }
309}
310
311
312// Formatting
313
a48e8c8d
AC
314:%s:64,f:::VT:int sel, int vt
315*mdmx:
316// start-sanitize-vr5400
317*vr5400:
318// end-sanitize-vr5400
35c246c9
AC
319{
320 static char buf[20];
321 if (sel < 8)
322 sprintf (buf, "v%d[%d]", vt, sel);
323 else if (sel == 0x13)
324 sprintf (buf, "v%d", vt);
325 else if (sel == 0x1f)
326 sprintf (buf, "%d", vt);
327 else
328 sprintf (buf, "(invalid)");
329 return buf;
330}
331
a48e8c8d
AC
332:%s:64,f:::SEL:int sel
333*mdmx:
334// start-sanitize-vr5400
335*vr5400:
336// end-sanitize-vr5400
35c246c9
AC
337{
338 switch (sel & 7)
339 {
340 case 0:
341 case 2:
342 case 4:
343 case 6:
344 return "ob";
345 case 1:
346 case 5:
347 return "qh";
348 case 3:
349 return "bw";
350 default:
351 return "l";
352 }
353}
354
355
356// Vector Add.
357
a48e8c8d 358010010,5.SEL,5.VT,5.VS,5.VD,001011::64,f::ADD.fmt
35c246c9
AC
359"add.%s<SEL> v<VD>, v<VS>, %s<VT#SEL,VT>"
360*mdmx:
361// start-sanitize-vr5400
362*vr5400:
363// end-sanitize-vr5400
364{
365 int i;
366 int scale = get_scale (SD_, SEL);
367 for (i = 0; i < (8 >> scale); i++)
368 store_vr (SD_, scale, VD, i,
369 Clamp (SD_, scale,
370 (value_vr (SD_, scale, VS, i)
371 + select_vr (SD_, SEL, VT, i))));
372}
373
374
375// Accumulate Vector Add
376
a48e8c8d 377010010,5.SEL,5.VT,5.VS,1,0000,110111::64,f::ADDA.fmt
35c246c9
AC
378"adda.%s<SEL> v<VD>, v<VS>"
379*mdmx:
380{
381 int i;
382 int scale = get_scale (SD_, SEL);
383 for (i = 0; i < (8 >> scale); i++)
384 store_acc (SD_, scale, i,
385 (value_acc (SD_, scale, i)
386 + (signed64) value_vr (SD_, scale, VS, i)
387 + (signed64) select_vr (SD_, SEL, VT, i)));
388}
389
390
391// Load Vector Add
392
a48e8c8d 393010010,5.SEL,5.VT,5.VS,0,0000,110111::64,f::ADDA.fmt
35c246c9
AC
394"addl.%s<SEL> v<VD>, v<VS>"
395*mdmx:
396{
397 int i;
398 int scale = get_scale (SD_, SEL);
399 for (i = 0; i < (8 >> scale); i++)
400 store_acc (SD_, scale, i,
401 ((signed64) value_vr (SD_, scale, VS, i)
402 + (signed64) select_vr (SD_, SEL, VT, i)));
403}
404
405
406
407// Vector align, Constant Alignment
408
a48e8c8d
AC
409:function:64,f::void:ByteAlign:int vd, int imm, int vs, int vt
410*mdmx:
411// start-sanitize-vr5400
412*vr5400:
413// end-sanitize-vr5400
35c246c9
AC
414{
415 int s = imm * 8;
01737f42
AC
416 unsigned64 rs = ValueFPR (vs, fmt_long);
417 unsigned64 rt = ValueFPR (vt, fmt_long);
35c246c9
AC
418 unsigned64 rd;
419 if (BigEndianCPU)
420 {
421 /* (vs || vt) [127 - S .. 64 - S] */
422 if (s == 0)
423 rd = rs;
424 else
425 rd = (MOVED64 (rs, 64 - s, 0, 63, s)
426 | EXTRACTED64 (rt, 63, 64 - s));
427 }
428 else
429 {
430 /* (vs || vt) [63 + S .. S] */
431 if (s == 0)
432 rd = rt;
433 else
434 rd = (MOVED64 (rs, s, 0, 63, 64 - s)
435 | EXTRACTED64 (rt, 63, s));
436 }
01737f42 437 StoreFPR (vd, fmt_long, rd);
35c246c9
AC
438}
439
a48e8c8d 440010010,00,3.IMM,5.VT,5.VS,5.VD,0110,X,0::64,f::ALNI.fmt
35c246c9
AC
441"alni.%s<FMT#X> v<VD>, v<VS>, v<VT>, <IMM>"
442*mdmx:
443// start-sanitize-vr5400
444*vr5400:
445// end-sanitize-vr5400
446{
447 ByteAlign (SD_, VD, IMM, VS, VT);
448}
449
450
451
452// Vector align, Variable Alignment
453
a48e8c8d 454010010,5.RS,5.VT,5.VS,5.VD,0110,X,1::64,f::ALNV.fmt
35c246c9
AC
455"alnv.%s<FMT#X> v<VD>, v<VS>, v<VT>, r<RS>"
456*mdmx:
457{
458 ByteAlign (SD_, VD, GPR[RS], VS, VT);
459}
460
461
462
463// Vector And.
464
a48e8c8d 465010010,5.SEL,5.VT,5.VS,5.VD,001100::64,f::AND.fmt
35c246c9
AC
466"and.%s<SEL> v<VD>, v<VS>, %s<VT#SEL,VT>"
467*mdmx:
468// start-sanitize-vr5400
469*vr5400:
470// end-sanitize-vr5400
471{
472 int i;
473 int scale = get_scale (SD_, SEL);
474 for (i = 0; i < (8 >> scale); i++)
475 store_vr (SD_, scale, VD, i,
476 (value_vr (SD_, scale, VS, i)
477 & select_vr (SD_, SEL, VT, i)));
478}
479
480
481
482// Vector Compare Equal.
483
484
a48e8c8d 485010010,5.SEL,5.VT,5.VS,00000,000001::64,f::C.EQ.fmt
35c246c9
AC
486"c.EQ.%s<SEL> v<VS>, %s<VT#SEL,VT>"
487*mdmx:
488// start-sanitize-vr5400
489*vr5400:
490// end-sanitize-vr5400
491{
492 int i;
493 int scale = get_scale (SD_, SEL);
494 for (i = 0; i < (8 >> scale); i++)
495 store_cc (SD_, i,
496 (value_vr (SD_, scale, VS, i)
497 == select_vr (SD_, SEL, VT, i)));
498}
499
500
501
502// Vector Compare Less Than or Equal.
503
a48e8c8d 504010010,5.SEL,5.VT,5.VS,00000,000101::64,f::C.LE.fmt
35c246c9
AC
505"c.le.%s<SEL> v<VS>, %s<VT#SEL,VT>"
506*mdmx:
507// start-sanitize-vr5400
508*vr5400:
509// end-sanitize-vr5400
510{
511 int i;
512 int scale = get_scale (SD_, SEL);
513 for (i = 0; i < (8 >> scale); i++)
514 store_cc (SD_, i,
515 (value_vr (SD_, scale, VS, i)
516 <= select_vr (SD_, SEL, VT, i)));
517}
518
519
520
521// Vector Compare Less Than.
522
a48e8c8d 523010010,5.SEL,5.VT,5.VS,00000,000100::64,f::C.LT.fmt
35c246c9
AC
524"c.lt.%s<SEL> v<VS>, %s<VT#SEL,VT>"
525*mdmx:
526// start-sanitize-vr5400
527*vr5400:
528// end-sanitize-vr5400
529{
530 int i;
531 int scale = get_scale (SD_, SEL);
532 for (i = 0; i < (8 >> scale); i++)
533 store_cc (SD_, i,
534 (value_vr (SD_, scale, VS, i)
535 < select_vr (SD_, SEL, VT, i)));
536}
537
538
539
540// Vector Maximum.
541
a48e8c8d
AC
542:function:64,f::signed:Max:int scale, signed l, signed r
543*mdmx:
544// start-sanitize-vr5400
545*vr5400:
546// end-sanitize-vr5400
35c246c9
AC
547{
548 if (l < r)
549 return r;
550 else
551 return l;
552}
553
a48e8c8d 554010010,5.SEL,5.VT,5.VS,5.VD,000111::64,f::MAX.fmt
35c246c9
AC
555"max.%s<SEL> v<VD>, v<VS>, %s<VT#SEL,VT>"
556*mdmx:
557// start-sanitize-vr5400
558*vr5400:
559// end-sanitize-vr5400
560{
561 int i;
562 int scale = get_scale (SD_, SEL);
563 for (i = 0; i < (8 >> scale); i++)
564 store_vr (SD_, scale, VD, i,
565 Max (SD_, scale,
566 value_vr (SD_, scale, VS, i),
567 select_vr (SD_, SEL, VT, i)));
568}
569
570
571
572// Vector Minimum.
573
a48e8c8d
AC
574:function:64,f::signed:Min:int scale, signed l, signed r
575*mdmx:
576// start-sanitize-vr5400
577*vr5400:
578// end-sanitize-vr5400
35c246c9
AC
579{
580 if (l < r)
581 return l;
582 else
583 return r;
584}
585
a48e8c8d 586010010,5.SEL,5.VT,5.VS,5.VD,000110::64,f::MIN.fmt
35c246c9
AC
587"min.%s<SEL> v<VD>, v<VS>, %s<VT#SEL,VT>"
588*mdmx:
589// start-sanitize-vr5400
590*vr5400:
591// end-sanitize-vr5400
592{
593 int i;
594 int scale = get_scale (SD_, SEL);
595 for (i = 0; i < (8 >> scale); i++)
596 store_vr (SD_, scale, VD, i,
597 Min (SD_, scale,
598 value_vr (SD_, scale, VS, i),
599 select_vr (SD_, SEL, VT, i)));
600}
601
602
603
604// Vector Sign.
605
a48e8c8d
AC
606:function:64,f::signed:Sign:int scale, signed l, signed r
607*mdmx:
608// start-sanitize-vr5400
609*vr5400:
610// end-sanitize-vr5400
35c246c9
AC
611{
612 if (l >= 0)
613 return r;
614 else if (r >= 0)
615 return -r;
616 else
617 {
618 /* watch for overflow of MIN_INT */
619 switch (scale)
620 {
621 case 0:
622 if ((r & 0xff) == 0x80)
623 return 0x7ff;
624 else
625 return -r;
626 case 1:
627 if ((r & 0xffff) == 0x8000)
628 return 0x7ffff;
629 else
630 return -r;
631 default:
632 abort ();
633 }
634 return -r;
635 }
636}
637
a48e8c8d 638010010,5.SEL,5.VT,5.VS,5.VD,000110::64,f::MSGN.fmt
35c246c9
AC
639"msgn.%s<SEL> v<VD>, v<VS>, %s<VT#SEL,VT>"
640*mdmx:
641{
642 int i;
643 int scale = get_scale (SD_, SEL);
644 if ((SEL & 1) != 1)
645 /* only QH allowed */
646 semantic_illegal (sd, cia);
647 for (i = 0; i < (8 >> scale); i++)
648 store_vr (SD_, scale, VD, i,
649 Sign (SD_, scale,
650 value_vr (SD_, scale, VS, i),
651 select_vr (SD_, SEL, VT, i)));
652}
653
654
655
656// Vector Multiply.
657
a48e8c8d 658010010,5.SEL,5.VT,5.VS,5.VD,110000::64,f::MUL.fmt
35c246c9
AC
659"mul.%s<SEL> v<VD>, v<VS>, %s<VT#SEL,VT>"
660*mdmx:
661// start-sanitize-vr5400
662*vr5400:
663// end-sanitize-vr5400
664{
665 int i;
666 int scale = get_scale (SD_, SEL);
667 for (i = 0; i < (8 >> scale); i++)
668 store_vr (SD_, scale, VD, i,
669 Clamp (SD_, scale,
670 (value_vr (SD_, scale, VS, i)
671 * select_vr (SD_, SEL, VT, i))));
672}
673
674
675
676// Accumulate Vector Multiply
677
a48e8c8d 678010010,5.SEL,5.VT,5.VS,00000,110011::64,f::MULA.fmt
35c246c9
AC
679"mula.%s<SEL> v<VS>, %s<VT#SEL,VT>"
680*mdmx:
681// start-sanitize-vr5400
682*vr5400:
683// end-sanitize-vr5400
684{
685 int i;
686 int scale = get_scale (SD_, SEL);
687 for (i = 0; i < (8 >> scale); i++)
688 store_acc (SD_, scale, i,
689 (value_acc (SD_, scale, i)
690 + ((signed64) value_vr (SD_, scale, VS, i)
691 * (signed64) select_vr (SD_, SEL, VT, i))));
692}
693
694
695
696// Add Vector Multiply to Accumulator.
697
a48e8c8d 698010010,5.SEL,5.VT,5.VS,10000,110011::64,f::MULL.fmt
35c246c9
AC
699"mull.%s<SEL> v<VS>, %s<VT#SEL,VT>"
700*mdmx:
701// start-sanitize-vr5400
702*vr5400:
703// end-sanitize-vr5400
704{
705 int i;
706 int scale = get_scale (SD_, SEL);
707 for (i = 0; i < (8 >> scale); i++)
708 store_acc (SD_, scale, i,
709 ((signed64) value_vr (SD_, scale, VS, i)
710 * (signed64) select_vr (SD_, SEL, VT, i)));
711}
712
713
714
715// Subtract Vector Multiply from Accumulator
716
a48e8c8d 717010010,5.SEL,5.VT,5.VS,00000,110010::64,f::MULS.fmt
35c246c9
AC
718"muls.%s<SEL> v<VS>, %s<VT#SEL,VT>"
719*mdmx:
720// start-sanitize-vr5400
721*vr5400:
722// end-sanitize-vr5400
723{
724 int i;
725 int scale = get_scale (SD_, SEL);
726 for (i = 0; i < (8 >> scale); i++)
727 store_acc (SD_, scale, i,
728 (value_acc (SD_, scale, i)
729 - ((signed64) value_vr (SD_, scale, VS, i)
730 * (signed64) select_vr (SD_, SEL, VT, i))));
731}
732
733
734
735// Load Negative Vector Multiply
736
a48e8c8d 737010010,5.SEL,5.VT,5.VS,10000,110010::64,f::MULSL.fmt
35c246c9
AC
738"mulsl.%s<SEL> v<VS>, %s<VT#SEL,VT>"
739*mdmx:
740// start-sanitize-vr5400
741*vr5400:
742// end-sanitize-vr5400
743{
744 int i;
745 int scale = get_scale (SD_, SEL);
746 for (i = 0; i < (8 >> scale); i++)
747 store_acc (SD_, scale, i,
748 - ((signed64) value_vr (SD_, scale, VS, i)
749 * (signed64) select_vr (SD_, SEL, VT, i)));
750}
751
752
753
754// Vector Nor.
755
a48e8c8d 756010010,5.SEL,5.VT,5.VS,5.VD,001111::64,f::NOR.fmt
35c246c9
AC
757"nor.%s<SEL> v<VD>, v<VS>, %s<VT#SEL,VT>"
758*mdmx:
759// start-sanitize-vr5400
760*vr5400:
761// end-sanitize-vr5400
762{
763 int i;
764 int scale = get_scale (SD_, SEL);
765 for (i = 0; i < (8 >> scale); i++)
766 store_vr (SD_, scale, VD, i,
767 ~(value_vr (SD_, scale, VS, i)
768 | select_vr (SD_, SEL, VT, i)));
769}
770
771
772
773// Vector Or.
774
a48e8c8d 775010010,5.SEL,5.VT,5.VS,5.VD,001110::64,f::OR.fmt
35c246c9
AC
776"or.%s<SEL> v<VD>, v<VS>, %s<VT#SEL,VT>"
777*mdmx:
778// start-sanitize-vr5400
779*vr5400:
780// end-sanitize-vr5400
781{
782 int i;
783 int scale = get_scale (SD_, SEL);
784 for (i = 0; i < (8 >> scale); i++)
785 store_vr (SD_, scale, VD, i,
786 (value_vr (SD_, scale, VS, i)
787 | select_vr (SD_, SEL, VT, i)));
788}
789
790
791
792// Select Vector Elements - False
793
a48e8c8d 794010010,5.SEL,5.VT,5.VS,5.VD,000010::64,f::PICKF.fmt
35c246c9
AC
795"pickf.%s<SEL> v<VD>, v<VS>, %s<VT#SEL,VT>"
796*mdmx:
797// start-sanitize-vr5400
798*vr5400:
799// end-sanitize-vr5400
800{
801 int i;
802 int scale = get_scale (SD_, SEL);
803 for (i = 0; i < (8 >> scale); i++)
804 store_vr (SD_, scale, VD, i,
01737f42 805 (value_cc (SD_, i) == 0
35c246c9
AC
806 ? value_vr (SD_, scale, VS, i)
807 : select_vr (SD_, SEL, VT, i)));
808}
809
810
811
812// Select Vector Elements - True
813
a48e8c8d 814010010,5.SEL,5.VT,5.VS,5.VD,000011::64,f::PICKT.fmt
35c246c9
AC
815"pickt.%s<SEL> v<VD>, v<VS>, %s<VT#SEL,VT>"
816*mdmx:
817// start-sanitize-vr5400
818*vr5400:
819// end-sanitize-vr5400
820{
821 int i;
822 int scale = get_scale (SD_, SEL);
823 for (i = 0; i < (8 >> scale); i++)
824 store_vr (SD_, scale, VD, i,
01737f42 825 (value_cc (SD_, i) != 0
35c246c9
AC
826 ? value_vr (SD_, scale, VS, i)
827 : select_vr (SD_, SEL, VT, i)));
828}
829
830
831
832// Scale, Round and Clamp Accumulator
833
a48e8c8d
AC
834:%s:64,f:::RND:int rnd
835*mdmx:
836// start-sanitize-vr5400
837*vr5400:
838// end-sanitize-vr5400
35c246c9
AC
839{
840 switch (rnd)
841 {
842 case 0:
843 return "zu";
844 case 1:
845 return "nau";
846 case 2:
847 return "neu";
848 case 4:
849 return "rzs";
850 case 5:
851 return "nas";
852 case 6:
853 return "nes";
854 default:
855 return "(invalid)";
856 }
857}
858
a48e8c8d
AC
859:function:64,f::signed:ScaleRoundClamp:int scale, int rnd, signed val, signed shift
860*mdmx:
861// start-sanitize-vr5400
862*vr5400:
863// end-sanitize-vr5400
35c246c9
AC
864{
865 int halfway = (1 << (shift - 1));
866 /* must be positive */
867 if (shift < 0)
868 return 0;
869 /* too much shift? */
870 switch (scale)
871 {
872 case 0:
873 if (shift >= 24)
874 return 0;
875 break;
876 case 1:
877 if (shift >= 48)
878 return 0;
879 break;
880 default:
881 abort ();
882 }
883 /* round */
884 switch (rnd & 3)
885 {
886 case 0: /* round towards zero */
887 break;
888 case 1: /* nearest, halfaway rounds away from zero */
889 if (val >= 0)
890 val += halfway;
891 else
892 val -= halfway;
893 break;
894 case 2: /* nearest, halfway rounds to even! */
895 if (val >= 0)
896 {
897 if (val & (halfway << 1))
898 val += halfway;
899 else
900 val += (halfway - 1);
901 }
902 else
903 {
904 if (val & (halfway << 1))
905 val -= halfway;
906 else
907 val -= (halfway - 1);
908 }
909 default:
910 abort ();
911 }
912 /* shift */
913 val >>= shift;
914 /* clamp */
915 switch (rnd & 4)
916 {
917 case 0:
918 /* unsigned clamp */
919 if (val < 0)
920 val = 0;
921 else
922 switch (scale)
923 {
924 case 0:
925 if (val > 0xff)
926 val = 0xff;
927 break;
928 case 1:
929 if (val > 0xffff)
930 val = 0xffff;
931 break;
932 }
933 break;
934 case 8:
935 /* normal signed clamp */
936 val = Clamp (_SD, scale, val);
937 break;
938 }
939 return val;
940}
941
a48e8c8d 942010010,5.SEL,5.VT,00000,5.VD,100,3.RND::64,f::Rx.fmt
35c246c9
AC
943"r%s<RND>.%s<SEL> v<VD>, v<VT>"
944*mdmx:
945// start-sanitize-vr5400
946*vr5400:
947// end-sanitize-vr5400
948{
949 int i;
950 int scale = get_scale (SD_, SEL);
951 for (i = 0; i < (8 >> scale); i++)
952 store_vr (SD_, scale, VD, i,
953 ScaleRoundClamp (SD_, scale, RND,
954 value_acc (SD_, scale, i),
955 select_vr (SD_, SEL, VT, i)));
956}
957
958
959
960// Vector Read Accumulator Low.
961
a48e8c8d 962010010,0000,1.SEL,00000,00000,5.VD,111111::64,f::RACL.fmt
35c246c9
AC
963"racl.%s<SEL> v<VD>"
964*mdmx:
965// start-sanitize-vr5400
966*vr5400:
967// end-sanitize-vr5400
968{
969 int i;
970 int scale = get_scale (SD_, SEL);
971 for (i = 0; i < (8 >> scale); i++)
972 store_vr (SD_, scale, VD, i,
973 EXTRACTED (value_acc (SD_, scale, i),
974 (8 << scale) - 1,
975 0));
976}
977
978
979
980// Vector Read Accumulator Middle.
981
a48e8c8d 982010010,0100,1.SEL,00000,00000,5.VD,111111::64,f::RACM.fmt
35c246c9
AC
983"racm.%s<SEL> v<VD>"
984*mdmx:
985// start-sanitize-vr5400
986*vr5400:
987// end-sanitize-vr5400
988{
989 int i;
990 int scale = get_scale (SD_, SEL);
991 for (i = 0; i < (8 >> scale); i++)
992 store_vr (SD_, scale, VD, i,
993 EXTRACTED (value_acc (SD_, scale, i),
994 (16 << scale) - 1,
995 (8 << scale) - 0));
996}
997
998
999
1000// Vector Read Accumulator High.
1001
a48e8c8d 1002010010,1000,1.SEL,00000,00000,5.VD,111111::64,f::RACH.fmt
35c246c9
AC
1003"rach.%s<SEL> v<VD>"
1004*mdmx:
1005// start-sanitize-vr5400
1006*vr5400:
1007// end-sanitize-vr5400
1008{
1009 int i;
1010 int scale = get_scale (SD_, SEL);
1011 for (i = 0; i < (8 >> scale); i++)
1012 store_vr (SD_, scale, VD, i,
1013 EXTRACTED (value_acc (SD_, scale, i),
1014 (24 << scale) - 1,
1015 (16 << scale) - 0));
1016}
1017
1018
1019
1020// Vector Element Shuffle.
1021
a48e8c8d 1022010010,0000,0,5.VT,5.VS,5.VD,011111::64,f::SHFL.UPUH.fmt
35c246c9
AC
1023"shfl.upuh.%s<SEL> v<VD>, v<VS>, <VT>"
1024*mdmx:
1025{
1026 int i;
1027 int scale = get_scale (SD_, SEL);
1028 for (i = 0; i < 4; i++)
1029 {
1030 store_vr (SD_, 1, VD, i,
1031 value_vr (SD_, 0, VS, i + 4) & 0xff);
1032 }
1033}
1034
a48e8c8d 1035010010,0001,0,5.VT,5.VS,5.VD,011111::64,f::SHFL.UPUL.fmt
35c246c9
AC
1036"shfl.upul.%s<SEL> v<VD>, v<VS>, <VT>"
1037*mdmx:
1038{
1039 int i;
1040 for (i = 0; i < 4; i++)
1041 {
1042 store_vr (SD_, 1, VD, i,
1043 value_vr (SD_, 0, VS, i) & 0xff);
1044 }
1045}
1046
a48e8c8d 1047010010,0000,0,5.VT,5.VS,5.VD,011111::64,f::SHFL.UPSH.fmt
35c246c9
AC
1048"shfl.upsh.%s<SEL> v<VD>, v<VS>, <VT>"
1049*mdmx:
1050{
1051 int i;
1052 int scale = get_scale (SD_, SEL);
1053 for (i = 0; i < 4; i++)
1054 {
1055 store_vr (SD_, 1, VD, i,
1056 value_vr (SD_, 0, VS, i + 4));
1057 }
1058}
1059
a48e8c8d 1060010010,0001,0,5.VT,5.VS,5.VD,011111::64,f::SHFL.UPSL.fmt
35c246c9
AC
1061"shfl.upsl.%s<SEL> v<VD>, v<VS>, <VT>"
1062*mdmx:
1063{
1064 int i;
1065 for (i = 0; i < 4; i++)
1066 {
1067 store_vr (SD_, 1, VD, i,
1068 value_vr (SD_, 0, VS, i));
1069 }
1070}
1071
a48e8c8d 1072010010,0100,1.SEL,5.VT,5.VS,5.VD,011111::64,f::SHFL.PACH.fmt
35c246c9
AC
1073"shfl.pach.%s<SEL> v<VD>, v<VS>, <VT>"
1074*mdmx:
1075// start-sanitize-vr5400
1076*vr5400:
1077// end-sanitize-vr5400
1078{
1079 int i;
1080 int scale = get_scale (SD_, SEL);
1081 for (i = 0; i < (4 >> scale); i++)
1082 {
1083 store_vr (SD_, scale, VD, i,
1084 value_vr (SD_, scale, VT, i * 2 + 1));
1085 store_vr (SD_, scale, VD, 1 + (4 >> scale),
1086 value_vr (SD_, scale, VS, i * 2 + 1));
1087 }
1088}
1089
a48e8c8d 1090010010,0101,1.SEL,5.VT,5.VS,5.VD,011111::64,f::SHFL.PACL.fmt
35c246c9
AC
1091"shfl.pacl.%s<SEL> v<VD>, v<VS>, <VT>"
1092*mdmx:
1093// start-sanitize-vr5400
1094*vr5400:
1095// end-sanitize-vr5400
1096{
1097 int i;
1098 int scale = get_scale (SD_, SEL);
1099 for (i = 0; i < (4 >> scale); i++)
1100 {
1101 store_vr (SD_, scale, VD, i,
1102 value_vr (SD_, scale, VT, i * 2));
1103 store_vr (SD_, scale, VD, 1 + (4 >> scale),
1104 value_vr (SD_, scale, VS, i * 2));
1105 }
1106}
1107
a48e8c8d 1108010010,0110,1.SEL,5.VT,5.VS,5.VD,011111::64,f::SHFL.MIXH.fmt
35c246c9
AC
1109"shfl.mixh.%s<SEL> v<VD>, v<VS>, <VT>"
1110*mdmx:
1111// start-sanitize-vr5400
1112*vr5400:
1113// end-sanitize-vr5400
1114{
1115 int i;
1116 int scale = get_scale (SD_, SEL);
1117 for (i = 0; i < (4 >> scale); i++)
1118 {
1119 store_vr (SD_, scale, VD, i * 2,
1120 value_vr (SD_, scale, VT, i + (4 >> scale)));
1121 store_vr (SD_, scale, VD, i * 2 + 1,
1122 value_vr (SD_, scale, VS, i + (4 >> scale)));
1123 }
1124}
1125
a48e8c8d 1126010010,0111,1.SEL,5.VT,5.VS,5.VD,011111::64,f::SHFL.MIXL.fmt
35c246c9
AC
1127"shfl.mixl.%s<SEL> v<VD>, v<VS>, <VT>"
1128*mdmx:
1129// start-sanitize-vr5400
1130*vr5400:
1131// end-sanitize-vr5400
1132{
1133 int i;
1134 int scale = get_scale (SD_, SEL);
1135 for (i = 0; i < (4 >> scale); i++)
1136 {
1137 store_vr (SD_, scale, VD, i * 2,
1138 value_vr (SD_, scale, VT, i));
1139 store_vr (SD_, scale, VD, i * 2 + 1,
1140 value_vr (SD_, scale, VS, i));
1141 }
1142}
1143
a48e8c8d 1144010010,100,01,5.VT,5.VS,5.VD,011111::64,f::SHFL.BFLA.fmt
35c246c9
AC
1145"shfl.bfla.qh v<VD>, v<VS>, <VT>"
1146*mdmx:
1147{
1148 store_vr (SD_, 1, VD, 0,
1149 value_vr (SD_, 1, VT, 1));
1150 store_vr (SD_, 1, VD, 1,
1151 value_vr (SD_, 1, VS, 0));
1152 store_vr (SD_, 1, VD, 2,
1153 value_vr (SD_, 1, VT, 3));
1154 store_vr (SD_, 1, VD, 3,
1155 value_vr (SD_, 1, VS, 2));
1156}
1157
a48e8c8d 1158010010,101,01,5.VT,5.VS,5.VD,011111::64,f::SHFL.BFLB.fmt
35c246c9
AC
1159"shfl.bflb.qh v<VD>, v<VS>, <VT>"
1160*mdmx:
1161{
1162 store_vr (SD_, 1, VD, 0,
1163 value_vr (SD_, 1, VT, 3));
1164 store_vr (SD_, 1, VD, 1,
1165 value_vr (SD_, 1, VS, 2));
1166 store_vr (SD_, 1, VD, 2,
1167 value_vr (SD_, 1, VT, 1));
1168 store_vr (SD_, 1, VD, 3,
1169 value_vr (SD_, 1, VS, 0));
1170}
1171
a48e8c8d 1172010010,101,01,5.VT,5.VS,5.VD,011111::64,f::SHFL.REPA.fmt
35c246c9
AC
1173"shfl.repa.qh v<VD>, v<VS>, <VT>"
1174*mdmx:
1175{
1176 store_vr (SD_, 1, VD, 0,
1177 value_vr (SD_, 1, VT, 2));
1178 store_vr (SD_, 1, VD, 1,
1179 value_vr (SD_, 1, VT, 3));
1180 store_vr (SD_, 1, VD, 2,
1181 value_vr (SD_, 1, VS, 2));
1182 store_vr (SD_, 1, VD, 3,
1183 value_vr (SD_, 1, VS, 3));
1184}
1185
a48e8c8d 1186010010,101,01,5.VT,5.VS,5.VD,011111::64,f::SHFL.REPB.fmt
35c246c9
AC
1187"shfl.repb.qh v<VD>, v<VS>, <VT>"
1188*mdmx:
1189{
1190 store_vr (SD_, 1, VD, 0,
1191 value_vr (SD_, 1, VT, 0));
1192 store_vr (SD_, 1, VD, 1,
1193 value_vr (SD_, 1, VT, 1));
1194 store_vr (SD_, 1, VD, 2,
1195 value_vr (SD_, 1, VS, 0));
1196 store_vr (SD_, 1, VD, 3,
1197 value_vr (SD_, 1, VS, 1));
1198}
1199
1200
1201
1202// Vector Shift Left Logical
1203
a48e8c8d 1204010010,5.SEL,5.VT,5.VS,5.VD,010000::64,f::SLL.fmt
35c246c9
AC
1205"sll.%s<SEL> v<VD>, v<VS>, %s<VT#SEL,VT>"
1206*mdmx:
1207// start-sanitize-vr5400
1208*vr5400:
1209// end-sanitize-vr5400
1210{
1211 int i;
1212 int scale = get_scale (SD_, SEL);
1213 int mask = (4 << scale) - 1;
1214 for (i = 0; i < (8 >> scale); i++)
1215 store_vr (SD_, scale, VD, i,
1216 (value_vr (SD_, scale, VS, i)
1217 << (select_vr (SD_, SEL, VT, i) & mask)));
1218}
1219
1220
1221
1222// Vector Shift Right Arithmetic
1223
a48e8c8d 1224010010,5.SEL,5.VT,5.VS,5.VD,010011::64,f::SRA.fmt
35c246c9
AC
1225"sra.%s<SEL> v<VD>, v<VS>, %s<VT#SEL,VT>"
1226*mdmx:
1227{
1228 int i;
1229 int mask = (4 << scale) - 1;
1230 int scale = get_scale (SD_, SEL);
1231 for (i = 0; i < (8 >> scale); i++)
1232 store_vr (SD_, scale, VD, i,
1233 (value_vr (SD_, scale, VS, i)
1234 >> (select_vr (SD_, SEL, VT, i) & mask)));
1235}
1236
1237
1238
1239// Vector Shift Right Logical.
1240
a48e8c8d 1241010010,5.SEL,5.VT,5.VS,5.VD,010010::64,f::SRL.fmt
35c246c9
AC
1242"srl.%s<SEL> v<VD>, v<VS>, %s<VT#SEL,VT>"
1243*mdmx:
1244// start-sanitize-vr5400
1245*vr5400:
1246// end-sanitize-vr5400
1247{
1248 int i;
1249 int scale = get_scale (SD_, SEL);
1250 int mask = (4 << scale) - 1;
1251 int zeros = (1 << (8 << scale)) - 1;
1252 for (i = 0; i < (8 >> scale); i++)
1253 store_vr (SD_, scale, VD, i,
1254 ((value_vr (SD_, scale, VS, i) & zeros)
1255 >> (select_vr (SD_, SEL, VT, i) & mask)));
1256}
1257
1258
1259
1260// Vector Subtract.
1261
a48e8c8d 1262010010,5.SEL,5.VT,5.VS,5.VD,001010::64,f::SUB.fmt
35c246c9
AC
1263"sub.%s<SEL> v<VD>, v<VS>, %s<VT#SEL,VT>"
1264*mdmx:
1265// start-sanitize-vr5400
1266*vr5400:
1267// end-sanitize-vr5400
1268{
1269 int i;
1270 int scale = get_scale (SD_, SEL);
1271 for (i = 0; i < (8 >> scale); i++)
1272 store_vr (SD_, scale, VD, i,
1273 (value_vr (SD_, scale, VS, i)
1274 - select_vr (SD_, SEL, VT, i)));
1275}
1276
1277
1278
1279// Accumulate Vector Difference
1280
a48e8c8d 1281010010,5.SEL,5.VT,5.VS,0,0000,110110::64,f::SUBA.fmt
35c246c9
AC
1282"suba.%s<SEL> v<VD>, v<VS>, %s<VT#SEL,VT>"
1283*mdmx:
1284{
1285 int i;
1286 int scale = get_scale (SD_, SEL);
1287 for (i = 0; i < (8 >> scale); i++)
1288 store_acc (SD_, scale, VD, i,
1289 (value_acc (SD, scale, i)
1290 + (signed64) value_vr (SD_, scale, VS, i)
1291 - (signed64) select_vr (SD_, SEL, VT, i)));
1292}
1293
1294
1295
1296// Load Vector Difference
1297
a48e8c8d 1298010010,5.SEL,5.VT,5.VS,1,0000,110110::64,f::SUBL.fmt
35c246c9
AC
1299"subl.%s<SEL> v<VD>, v<VS>, %s<VT#SEL,VT>"
1300*mdmx:
1301{
1302 int i;
1303 int scale = get_scale (SD_, SEL);
1304 for (i = 0; i < (8 >> scale); i++)
1305 store_acc (SD_, scale, VD, i,
1306 ((signed64) value_vr (SD_, scale, VS, i)
1307 - (signed64) select_vr (SD_, SEL, VT, i)));
1308}
1309
1310
1311
1312// Write Accumulator High.
1313
a48e8c8d 1314010010,1000,1.SEL,00000,5.VS,00000,111110::64,f::WACH.fmt
35c246c9
AC
1315"wach.%s<SEL> v<VS>"
1316*mdmx:
1317// start-sanitize-vr5400
1318*vr5400:
1319// end-sanitize-vr5400
1320{
1321 int i;
1322 int scale = get_scale (SD_, SEL);
1323 for (i = 0; i < (8 >> scale); i++)
1324 store_acc (SD_, scale, i,
1325 (((signed64) value_vr (SD_, scale, VS, i) << (16 << scale))
1326 | MASKED (value_acc (SD_, scale, i), (16 << scale) - 1, 0)));
1327}
1328
1329
1330
1331// Vector Write Accumulator Low.
1332
a48e8c8d 1333010010,0000,1.SEL,5.VT,5.VS,00000,111110::64,f::WACL.fmt
35c246c9
AC
1334"wacl.%s<SEL> v<VS>, <VT>"
1335*mdmx:
1336// start-sanitize-vr5400
1337*vr5400:
1338// end-sanitize-vr5400
1339{
1340 int i;
1341 int scale = get_scale (SD_, SEL);
1342 for (i = 0; i < (8 >> scale); i++)
1343 store_acc (SD_, scale, i,
1344 (((signed64) value_vr (SD_, scale, VS, i) << (16 << scale))
1345 | MASKED (value_vr (SD_, scale, VT, i),
1346 (16 << scale) - 1, 0)));
1347}
1348
1349
1350
1351// Vector Xor.
1352
a48e8c8d 1353010010,5.SEL,5.VT,5.VS,5.VD,001101::64,f::XOR.fmt
35c246c9
AC
1354"xor.%s<SEL> v<VD>, v<VS>, %s<VT#SEL,VT>"
1355*mdmx:
1356// start-sanitize-vr5400
1357*vr5400:
1358// end-sanitize-vr5400
1359{
1360 int i;
1361 int scale = get_scale (SD_, SEL);
1362 for (i = 0; i < (8 >> scale); i++)
1363 store_vr (SD_, scale, VD, i,
1364 (value_vr (SD_, scale, VS, i)
1365 ^ select_vr (SD_, SEL, VT, i)));
1366}
This page took 0.084006 seconds and 4 git commands to generate.