5 // Ref: http://www.sgi.com/MIPS/arch/ISA5/MDMXspec.pdf
7 // Note: For OB instructions, the sel field is deduced by special
8 // handling of the "vt" operand.
10 // of the form $vt[0], then sel is 0000
11 // of the form $vt[1], then sel is 0001
12 // of the form $vt[2], then sel is 0010
13 // of the form $vt[3], then sel is 0011
14 // of the form $vt[4], then sel is 0100
15 // of the form $vt[5], then sel is 0101
16 // of the form $vt[6], then sel is 0110
17 // of the form $vt[7], then sel is 0111
18 // Normal register specifier, then sel is 1011
19 // Constant, then sel is 1111
21 // VecAcc is the Vector Accumulator.
22 // This accumulator is organized as 8X24 bit (192 bit) register.
23 // This accumulator holds only signed values.
26 // Verify that the instruction is valid for the curent Architecture
27 // If valid, return the scale (log nr bits) of a vector element
28 // as determined by SEL.
30 :function:64,f::int:get_scale:int sel
32 // start-sanitize-vr5400
34 // end-sanitize-vr5400
37 switch (my_index X STATE_ARCHITECTURE)
47 /* octal byte - ssss0 */
51 /* quad halfword - sss01 */
55 semantic_illegal (CPU_, cia);
59 semantic_illegal (CPU_, cia);
68 // Fetch/Store VALUE in ELEMENT of vector register FPR.
69 // The the of the element determined by SCALE.
71 :function:64,f::signed:value_vr:int scale, int fpr, int el
73 // start-sanitize-vr5400
75 // end-sanitize-vr5400
77 switch (FPR_STATE[fpr])
79 case fmt_uninterpreted:
80 FPR_STATE[fpr] = fmt_long;
86 sim_io_eprintf (SD, "Vector %d format invalid (PC = 0x%08lx)\n",
88 FPR_STATE[fpr] = fmt_unknown;
94 signed8 value = *A1_8 (&FGR[fpr], 7 - el);
99 signed16 value = *A2_8 (&FGR[fpr], 3 - el);
108 :function:64,f::void:store_vr:int scale, int fpr, int element, signed value
110 // start-sanitize-vr5400
112 // end-sanitize-vr5400
114 switch (FPR_STATE[fpr])
116 case fmt_uninterpreted:
117 FPR_STATE[fpr] = fmt_long;
123 sim_io_eprintf (SD, "Vector %d format invalid (PC = 0x%08lx)\n",
125 FPR_STATE[fpr] = fmt_unknown;
131 *A1_8 (&FGR[fpr], 7 - element) = value;
136 *A2_8 (&FGR[fpr], 3 - element) = value;
145 // Select a value from onr of FGR[VT][ELEMENT], VT and GFR[VT][CONST]
148 :function:64,f::unsigned:select_vr:int sel, int vt, int element
150 // start-sanitize-vr5400
152 // end-sanitize-vr5400
156 /* element select - 0xxxx */
157 case 0x00: /* 0 xxx 0 */
165 return value_vr (SD_, 0, vt, sel >> 1);
166 case 0x01: /* 0 xx 01 */
170 return value_vr (SD_, 1, vt, sel >> 2);
171 case 0x03: /* 0 x 011 */
173 return value_vr (SD_, 2, vt, sel >> 3);
174 case 0x07: /* 0 x 111 */
176 return value_vr (SD_, 3, vt, sel >> 4);
178 /* select vector - 10xxx */
179 case 0x16: /* 10 11 0 */
180 return value_vr (SD_, 0, vt, element);
181 case 0x15: /* 10 1 01 */
182 return value_vr (SD_, 1, vt, element);
183 case 0x13: /* 10 011 */
184 return value_vr (SD_, 2, vt, element);
185 case 0x17: /* 10 111 */
186 return value_vr (SD_, 3, vt, element);
188 /* select immediate - 11xxx */
189 case 0x1e: /* 11 11 0 */
190 case 0x1d: /* 11 1 01 */
191 case 0x1b: /* 11 011 */
192 case 0x1f: /* 11 111 */
200 // Saturate (clamp) the signed value to (8 << SCALE) bits.
202 :function:64,f::signed:Clamp:int scale, signed value
204 // start-sanitize-vr5400
206 // end-sanitize-vr5400
212 if (value != (signed8) value)
223 if (value != (signed16) value)
230 return value & 0xffff;
239 // Access a single bit of the floating point CC register.
241 :function:64,f::void:store_cc:int i, int value
243 // start-sanitize-vr5400
245 // end-sanitize-vr5400
250 :function:64,f::int:value_cc:int i
252 // start-sanitize-vr5400
254 // end-sanitize-vr5400
260 // Read/write the accumulator
262 :function:64,f::signed64:value_acc:int scale, int element
264 // start-sanitize-vr5400
266 // end-sanitize-vr5400
272 value |= (unsigned64) (unsigned8) CPU->acc [element * 3 + 0];
273 value |= (unsigned64) (unsigned8) CPU->acc [element * 3 + 1] << 8;
274 value |= (signed64) (signed8) CPU->acc [element * 3 + 2] << 16;
277 value |= (unsigned64) (unsigned8) CPU->acc [element * 3 + 0];
278 value |= (unsigned64) (unsigned8) CPU->acc [element * 3 + 1] << 8;
279 value |= (unsigned64) (unsigned8) CPU->acc [element * 3 + 2] << 16;
280 value |= (unsigned64) (unsigned8) CPU->acc [element * 3 + 3] << 24;
281 value |= (unsigned64) (unsigned8) CPU->acc [element * 3 + 4] << 32;
282 value |= (signed64) (signed8) CPU->acc [element * 3 + 5] << 40;
288 :function:64,f::void:store_acc:int scale, int element, signed64 value
290 // start-sanitize-vr5400
292 // end-sanitize-vr5400
297 CPU->acc [element * 3 + 0] = value >> 0;
298 CPU->acc [element * 3 + 1] = value >> 8;
299 CPU->acc [element * 3 + 2] = value >> 16;
302 CPU->acc [element * 3 + 0] = value >> 0;
303 CPU->acc [element * 3 + 1] = value >> 8;
304 CPU->acc [element * 3 + 2] = value >> 16;
305 CPU->acc [element * 3 + 3] = value >> 24;
306 CPU->acc [element * 3 + 4] = value >> 32;
307 CPU->acc [element * 3 + 5] = value >> 40;
315 :%s:64,f:::VT:int sel, int vt
317 // start-sanitize-vr5400
319 // end-sanitize-vr5400
323 sprintf (buf, "v%d[%d]", vt, sel);
324 else if (sel == 0x13)
325 sprintf (buf, "v%d", vt);
326 else if (sel == 0x1f)
327 sprintf (buf, "%d", vt);
329 sprintf (buf, "(invalid)");
333 :%s:64,f:::SEL:int sel
335 // start-sanitize-vr5400
337 // end-sanitize-vr5400
359 010010,5.SEL,5.VT,5.VS,5.VD,001011::64,f::ADD.fmt
360 "add.%s<SEL> v<VD>, v<VS>, %s<VT#SEL,VT>"
362 // start-sanitize-vr5400
364 // end-sanitize-vr5400
367 int scale = get_scale (SD_, SEL);
368 for (i = 0; i < (8 >> scale); i++)
369 store_vr (SD_, scale, VD, i,
371 (value_vr (SD_, scale, VS, i)
372 + select_vr (SD_, SEL, VT, i))));
376 // Accumulate Vector Add
378 010010,5.SEL,5.VT,5.VS,1,0000,110111::64,f::ADDA.fmt
379 "adda.%s<SEL> v<VD>, v<VS>"
383 int scale = get_scale (SD_, SEL);
384 for (i = 0; i < (8 >> scale); i++)
385 store_acc (SD_, scale, i,
386 (value_acc (SD_, scale, i)
387 + (signed64) value_vr (SD_, scale, VS, i)
388 + (signed64) select_vr (SD_, SEL, VT, i)));
394 010010,5.SEL,5.VT,5.VS,0,0000,110111::64,f::ADDA.fmt
395 "addl.%s<SEL> v<VD>, v<VS>"
399 int scale = get_scale (SD_, SEL);
400 for (i = 0; i < (8 >> scale); i++)
401 store_acc (SD_, scale, i,
402 ((signed64) value_vr (SD_, scale, VS, i)
403 + (signed64) select_vr (SD_, SEL, VT, i)));
408 // Vector align, Constant Alignment
410 :function:64,f::void:ByteAlign:int vd, int imm, int vs, int vt
412 // start-sanitize-vr5400
414 // end-sanitize-vr5400
417 unsigned64 rs = ValueFPR (vs, fmt_long);
418 unsigned64 rt = ValueFPR (vt, fmt_long);
422 /* (vs || vt) [127 - S .. 64 - S] */
426 rd = (MOVED64 (rs, 64 - s, 0, 63, s)
427 | EXTRACTED64 (rt, 63, 64 - s));
431 /* (vs || vt) [63 + S .. S] */
435 rd = (MOVED64 (rs, s, 0, 63, 64 - s)
436 | EXTRACTED64 (rt, 63, s));
438 StoreFPR (vd, fmt_long, rd);
441 010010,00,3.IMM,5.VT,5.VS,5.VD,0110,X,0::64,f::ALNI.fmt
442 "alni.%s<FMT#X> v<VD>, v<VS>, v<VT>, <IMM>"
444 // start-sanitize-vr5400
446 // end-sanitize-vr5400
448 ByteAlign (SD_, VD, IMM, VS, VT);
453 // Vector align, Variable Alignment
455 010010,5.RS,5.VT,5.VS,5.VD,0110,X,1::64,f::ALNV.fmt
456 "alnv.%s<FMT#X> v<VD>, v<VS>, v<VT>, r<RS>"
459 ByteAlign (SD_, VD, GPR[RS], VS, VT);
466 010010,5.SEL,5.VT,5.VS,5.VD,001100::64,f::AND.fmt
467 "and.%s<SEL> v<VD>, v<VS>, %s<VT#SEL,VT>"
469 // start-sanitize-vr5400
471 // end-sanitize-vr5400
474 int scale = get_scale (SD_, SEL);
475 for (i = 0; i < (8 >> scale); i++)
476 store_vr (SD_, scale, VD, i,
477 (value_vr (SD_, scale, VS, i)
478 & select_vr (SD_, SEL, VT, i)));
483 // Vector Compare Equal.
486 010010,5.SEL,5.VT,5.VS,00000,000001::64,f::C.EQ.fmt
487 "c.EQ.%s<SEL> v<VS>, %s<VT#SEL,VT>"
489 // start-sanitize-vr5400
491 // end-sanitize-vr5400
494 int scale = get_scale (SD_, SEL);
495 for (i = 0; i < (8 >> scale); i++)
497 (value_vr (SD_, scale, VS, i)
498 == select_vr (SD_, SEL, VT, i)));
503 // Vector Compare Less Than or Equal.
505 010010,5.SEL,5.VT,5.VS,00000,000101::64,f::C.LE.fmt
506 "c.le.%s<SEL> v<VS>, %s<VT#SEL,VT>"
508 // start-sanitize-vr5400
510 // end-sanitize-vr5400
513 int scale = get_scale (SD_, SEL);
514 for (i = 0; i < (8 >> scale); i++)
516 (value_vr (SD_, scale, VS, i)
517 <= select_vr (SD_, SEL, VT, i)));
522 // Vector Compare Less Than.
524 010010,5.SEL,5.VT,5.VS,00000,000100::64,f::C.LT.fmt
525 "c.lt.%s<SEL> v<VS>, %s<VT#SEL,VT>"
527 // start-sanitize-vr5400
529 // end-sanitize-vr5400
532 int scale = get_scale (SD_, SEL);
533 for (i = 0; i < (8 >> scale); i++)
535 (value_vr (SD_, scale, VS, i)
536 < select_vr (SD_, SEL, VT, i)));
543 :function:64,f::signed:Maxi:int scale, signed l, signed r
545 // start-sanitize-vr5400
547 // end-sanitize-vr5400
555 010010,5.SEL,5.VT,5.VS,5.VD,000111::64,f::MAX.fmt
556 "max.%s<SEL> v<VD>, v<VS>, %s<VT#SEL,VT>"
558 // start-sanitize-vr5400
560 // end-sanitize-vr5400
563 int scale = get_scale (SD_, SEL);
564 for (i = 0; i < (8 >> scale); i++)
565 store_vr (SD_, scale, VD, i,
567 value_vr (SD_, scale, VS, i),
568 select_vr (SD_, SEL, VT, i)));
575 :function:64,f::signed:Mini:int scale, signed l, signed r
577 // start-sanitize-vr5400
579 // end-sanitize-vr5400
587 010010,5.SEL,5.VT,5.VS,5.VD,000110::64,f::MIN.fmt
588 "min.%s<SEL> v<VD>, v<VS>, %s<VT#SEL,VT>"
590 // start-sanitize-vr5400
592 // end-sanitize-vr5400
595 int scale = get_scale (SD_, SEL);
596 for (i = 0; i < (8 >> scale); i++)
597 store_vr (SD_, scale, VD, i,
599 value_vr (SD_, scale, VS, i),
600 select_vr (SD_, SEL, VT, i)));
607 :function:64,f::signed:Sign:int scale, signed l, signed r
609 // start-sanitize-vr5400
611 // end-sanitize-vr5400
619 /* watch for overflow of MIN_INT */
623 if ((r & 0xff) == 0x80)
628 if ((r & 0xffff) == 0x8000)
639 010010,5.SEL,5.VT,5.VS,5.VD,000110::64,f::MSGN.fmt
640 "msgn.%s<SEL> v<VD>, v<VS>, %s<VT#SEL,VT>"
644 int scale = get_scale (SD_, SEL);
646 /* only QH allowed */
647 semantic_illegal (sd, cia);
648 for (i = 0; i < (8 >> scale); i++)
649 store_vr (SD_, scale, VD, i,
651 value_vr (SD_, scale, VS, i),
652 select_vr (SD_, SEL, VT, i)));
659 010010,5.SEL,5.VT,5.VS,5.VD,110000::64,f::MUL.fmt
660 "mul.%s<SEL> v<VD>, v<VS>, %s<VT#SEL,VT>"
662 // start-sanitize-vr5400
664 // end-sanitize-vr5400
667 int scale = get_scale (SD_, SEL);
668 for (i = 0; i < (8 >> scale); i++)
669 store_vr (SD_, scale, VD, i,
671 (value_vr (SD_, scale, VS, i)
672 * select_vr (SD_, SEL, VT, i))));
677 // Accumulate Vector Multiply
679 010010,5.SEL,5.VT,5.VS,00000,110011::64,f::MULA.fmt
680 "mula.%s<SEL> v<VS>, %s<VT#SEL,VT>"
682 // start-sanitize-vr5400
684 // end-sanitize-vr5400
687 int scale = get_scale (SD_, SEL);
688 for (i = 0; i < (8 >> scale); i++)
689 store_acc (SD_, scale, i,
690 (value_acc (SD_, scale, i)
691 + ((signed64) value_vr (SD_, scale, VS, i)
692 * (signed64) select_vr (SD_, SEL, VT, i))));
697 // Add Vector Multiply to Accumulator.
699 010010,5.SEL,5.VT,5.VS,10000,110011::64,f::MULL.fmt
700 "mull.%s<SEL> v<VS>, %s<VT#SEL,VT>"
702 // start-sanitize-vr5400
704 // end-sanitize-vr5400
707 int scale = get_scale (SD_, SEL);
708 for (i = 0; i < (8 >> scale); i++)
709 store_acc (SD_, scale, i,
710 ((signed64) value_vr (SD_, scale, VS, i)
711 * (signed64) select_vr (SD_, SEL, VT, i)));
716 // Subtract Vector Multiply from Accumulator
718 010010,5.SEL,5.VT,5.VS,00000,110010::64,f::MULS.fmt
719 "muls.%s<SEL> v<VS>, %s<VT#SEL,VT>"
721 // start-sanitize-vr5400
723 // end-sanitize-vr5400
726 int scale = get_scale (SD_, SEL);
727 for (i = 0; i < (8 >> scale); i++)
728 store_acc (SD_, scale, i,
729 (value_acc (SD_, scale, i)
730 - ((signed64) value_vr (SD_, scale, VS, i)
731 * (signed64) select_vr (SD_, SEL, VT, i))));
736 // Load Negative Vector Multiply
738 010010,5.SEL,5.VT,5.VS,10000,110010::64,f::MULSL.fmt
739 "mulsl.%s<SEL> v<VS>, %s<VT#SEL,VT>"
741 // start-sanitize-vr5400
743 // end-sanitize-vr5400
746 int scale = get_scale (SD_, SEL);
747 for (i = 0; i < (8 >> scale); i++)
748 store_acc (SD_, scale, i,
749 - ((signed64) value_vr (SD_, scale, VS, i)
750 * (signed64) select_vr (SD_, SEL, VT, i)));
757 010010,5.SEL,5.VT,5.VS,5.VD,001111::64,f::NOR.fmt
758 "nor.%s<SEL> v<VD>, v<VS>, %s<VT#SEL,VT>"
760 // start-sanitize-vr5400
762 // end-sanitize-vr5400
765 int scale = get_scale (SD_, SEL);
766 for (i = 0; i < (8 >> scale); i++)
767 store_vr (SD_, scale, VD, i,
768 ~(value_vr (SD_, scale, VS, i)
769 | select_vr (SD_, SEL, VT, i)));
776 010010,5.SEL,5.VT,5.VS,5.VD,001110::64,f::OR.fmt
777 "or.%s<SEL> v<VD>, v<VS>, %s<VT#SEL,VT>"
779 // start-sanitize-vr5400
781 // end-sanitize-vr5400
784 int scale = get_scale (SD_, SEL);
785 for (i = 0; i < (8 >> scale); i++)
786 store_vr (SD_, scale, VD, i,
787 (value_vr (SD_, scale, VS, i)
788 | select_vr (SD_, SEL, VT, i)));
793 // Select Vector Elements - False
795 010010,5.SEL,5.VT,5.VS,5.VD,000010::64,f::PICKF.fmt
796 "pickf.%s<SEL> v<VD>, v<VS>, %s<VT#SEL,VT>"
798 // start-sanitize-vr5400
800 // end-sanitize-vr5400
803 int scale = get_scale (SD_, SEL);
804 for (i = 0; i < (8 >> scale); i++)
805 store_vr (SD_, scale, VD, i,
806 (value_cc (SD_, i) == 0
807 ? value_vr (SD_, scale, VS, i)
808 : select_vr (SD_, SEL, VT, i)));
813 // Select Vector Elements - True
815 010010,5.SEL,5.VT,5.VS,5.VD,000011::64,f::PICKT.fmt
816 "pickt.%s<SEL> v<VD>, v<VS>, %s<VT#SEL,VT>"
818 // start-sanitize-vr5400
820 // end-sanitize-vr5400
823 int scale = get_scale (SD_, SEL);
824 for (i = 0; i < (8 >> scale); i++)
825 store_vr (SD_, scale, VD, i,
826 (value_cc (SD_, i) != 0
827 ? value_vr (SD_, scale, VS, i)
828 : select_vr (SD_, SEL, VT, i)));
833 // Scale, Round and Clamp Accumulator
835 :%s:64,f:::RND:int rnd
837 // start-sanitize-vr5400
839 // end-sanitize-vr5400
860 :function:64,f::signed:ScaleRoundClamp:int scale, int rnd, signed val, signed shift
862 // start-sanitize-vr5400
864 // end-sanitize-vr5400
866 int halfway = (1 << (shift - 1));
867 /* must be positive */
870 /* too much shift? */
887 case 0: /* round towards zero */
889 case 1: /* nearest, halfaway rounds away from zero */
895 case 2: /* nearest, halfway rounds to even! */
898 if (val & (halfway << 1))
901 val += (halfway - 1);
905 if (val & (halfway << 1))
908 val -= (halfway - 1);
936 /* normal signed clamp */
937 val = Clamp (_SD, scale, val);
943 010010,5.SEL,5.VT,00000,5.VD,100,3.RND::64,f::Rx.fmt
944 "r%s<RND>.%s<SEL> v<VD>, v<VT>"
946 // start-sanitize-vr5400
948 // end-sanitize-vr5400
951 int scale = get_scale (SD_, SEL);
952 for (i = 0; i < (8 >> scale); i++)
953 store_vr (SD_, scale, VD, i,
954 ScaleRoundClamp (SD_, scale, RND,
955 value_acc (SD_, scale, i),
956 select_vr (SD_, SEL, VT, i)));
961 // Vector Read Accumulator Low.
963 010010,0000,1.SEL,00000,00000,5.VD,111111::64,f::RACL.fmt
966 // start-sanitize-vr5400
968 // end-sanitize-vr5400
971 int scale = get_scale (SD_, SEL);
972 for (i = 0; i < (8 >> scale); i++)
973 store_vr (SD_, scale, VD, i,
974 EXTRACTED (value_acc (SD_, scale, i),
981 // Vector Read Accumulator Middle.
983 010010,0100,1.SEL,00000,00000,5.VD,111111::64,f::RACM.fmt
986 // start-sanitize-vr5400
988 // end-sanitize-vr5400
991 int scale = get_scale (SD_, SEL);
992 for (i = 0; i < (8 >> scale); i++)
993 store_vr (SD_, scale, VD, i,
994 EXTRACTED (value_acc (SD_, scale, i),
1001 // Vector Read Accumulator High.
1003 010010,1000,1.SEL,00000,00000,5.VD,111111::64,f::RACH.fmt
1004 "rach.%s<SEL> v<VD>"
1006 // start-sanitize-vr5400
1008 // end-sanitize-vr5400
1011 int scale = get_scale (SD_, SEL);
1012 for (i = 0; i < (8 >> scale); i++)
1013 store_vr (SD_, scale, VD, i,
1014 EXTRACTED (value_acc (SD_, scale, i),
1016 (16 << scale) - 0));
1021 // Vector Element Shuffle.
1023 010010,0000,0,5.VT,5.VS,5.VD,011111::64,f::SHFL.UPUH.fmt
1024 "shfl.upuh.%s<SEL> v<VD>, v<VS>, <VT>"
1028 int scale = get_scale (SD_, SEL);
1029 for (i = 0; i < 4; i++)
1031 store_vr (SD_, 1, VD, i,
1032 value_vr (SD_, 0, VS, i + 4) & 0xff);
1036 010010,0001,0,5.VT,5.VS,5.VD,011111::64,f::SHFL.UPUL.fmt
1037 "shfl.upul.%s<SEL> v<VD>, v<VS>, <VT>"
1041 for (i = 0; i < 4; i++)
1043 store_vr (SD_, 1, VD, i,
1044 value_vr (SD_, 0, VS, i) & 0xff);
1048 010010,0000,0,5.VT,5.VS,5.VD,011111::64,f::SHFL.UPSH.fmt
1049 "shfl.upsh.%s<SEL> v<VD>, v<VS>, <VT>"
1053 int scale = get_scale (SD_, SEL);
1054 for (i = 0; i < 4; i++)
1056 store_vr (SD_, 1, VD, i,
1057 value_vr (SD_, 0, VS, i + 4));
1061 010010,0001,0,5.VT,5.VS,5.VD,011111::64,f::SHFL.UPSL.fmt
1062 "shfl.upsl.%s<SEL> v<VD>, v<VS>, <VT>"
1066 for (i = 0; i < 4; i++)
1068 store_vr (SD_, 1, VD, i,
1069 value_vr (SD_, 0, VS, i));
1073 010010,0100,1.SEL,5.VT,5.VS,5.VD,011111::64,f::SHFL.PACH.fmt
1074 "shfl.pach.%s<SEL> v<VD>, v<VS>, <VT>"
1076 // start-sanitize-vr5400
1078 // end-sanitize-vr5400
1081 int scale = get_scale (SD_, SEL);
1082 for (i = 0; i < (4 >> scale); i++)
1084 store_vr (SD_, scale, VD, i,
1085 value_vr (SD_, scale, VT, i * 2 + 1));
1086 store_vr (SD_, scale, VD, 1 + (4 >> scale),
1087 value_vr (SD_, scale, VS, i * 2 + 1));
1091 010010,0101,1.SEL,5.VT,5.VS,5.VD,011111::64,f::SHFL.PACL.fmt
1092 "shfl.pacl.%s<SEL> v<VD>, v<VS>, <VT>"
1094 // start-sanitize-vr5400
1096 // end-sanitize-vr5400
1099 int scale = get_scale (SD_, SEL);
1100 for (i = 0; i < (4 >> scale); i++)
1102 store_vr (SD_, scale, VD, i,
1103 value_vr (SD_, scale, VT, i * 2));
1104 store_vr (SD_, scale, VD, 1 + (4 >> scale),
1105 value_vr (SD_, scale, VS, i * 2));
1109 010010,0110,1.SEL,5.VT,5.VS,5.VD,011111::64,f::SHFL.MIXH.fmt
1110 "shfl.mixh.%s<SEL> v<VD>, v<VS>, <VT>"
1112 // start-sanitize-vr5400
1114 // end-sanitize-vr5400
1117 int scale = get_scale (SD_, SEL);
1118 for (i = 0; i < (4 >> scale); i++)
1120 store_vr (SD_, scale, VD, i * 2,
1121 value_vr (SD_, scale, VT, i + (4 >> scale)));
1122 store_vr (SD_, scale, VD, i * 2 + 1,
1123 value_vr (SD_, scale, VS, i + (4 >> scale)));
1127 010010,0111,1.SEL,5.VT,5.VS,5.VD,011111::64,f::SHFL.MIXL.fmt
1128 "shfl.mixl.%s<SEL> v<VD>, v<VS>, <VT>"
1130 // start-sanitize-vr5400
1132 // end-sanitize-vr5400
1135 int scale = get_scale (SD_, SEL);
1136 for (i = 0; i < (4 >> scale); i++)
1138 store_vr (SD_, scale, VD, i * 2,
1139 value_vr (SD_, scale, VT, i));
1140 store_vr (SD_, scale, VD, i * 2 + 1,
1141 value_vr (SD_, scale, VS, i));
1145 010010,100,01,5.VT,5.VS,5.VD,011111::64,f::SHFL.BFLA.fmt
1146 "shfl.bfla.qh v<VD>, v<VS>, <VT>"
1149 store_vr (SD_, 1, VD, 0,
1150 value_vr (SD_, 1, VT, 1));
1151 store_vr (SD_, 1, VD, 1,
1152 value_vr (SD_, 1, VS, 0));
1153 store_vr (SD_, 1, VD, 2,
1154 value_vr (SD_, 1, VT, 3));
1155 store_vr (SD_, 1, VD, 3,
1156 value_vr (SD_, 1, VS, 2));
1159 010010,101,01,5.VT,5.VS,5.VD,011111::64,f::SHFL.BFLB.fmt
1160 "shfl.bflb.qh v<VD>, v<VS>, <VT>"
1163 store_vr (SD_, 1, VD, 0,
1164 value_vr (SD_, 1, VT, 3));
1165 store_vr (SD_, 1, VD, 1,
1166 value_vr (SD_, 1, VS, 2));
1167 store_vr (SD_, 1, VD, 2,
1168 value_vr (SD_, 1, VT, 1));
1169 store_vr (SD_, 1, VD, 3,
1170 value_vr (SD_, 1, VS, 0));
1173 010010,101,01,5.VT,5.VS,5.VD,011111::64,f::SHFL.REPA.fmt
1174 "shfl.repa.qh v<VD>, v<VS>, <VT>"
1177 store_vr (SD_, 1, VD, 0,
1178 value_vr (SD_, 1, VT, 2));
1179 store_vr (SD_, 1, VD, 1,
1180 value_vr (SD_, 1, VT, 3));
1181 store_vr (SD_, 1, VD, 2,
1182 value_vr (SD_, 1, VS, 2));
1183 store_vr (SD_, 1, VD, 3,
1184 value_vr (SD_, 1, VS, 3));
1187 010010,101,01,5.VT,5.VS,5.VD,011111::64,f::SHFL.REPB.fmt
1188 "shfl.repb.qh v<VD>, v<VS>, <VT>"
1191 store_vr (SD_, 1, VD, 0,
1192 value_vr (SD_, 1, VT, 0));
1193 store_vr (SD_, 1, VD, 1,
1194 value_vr (SD_, 1, VT, 1));
1195 store_vr (SD_, 1, VD, 2,
1196 value_vr (SD_, 1, VS, 0));
1197 store_vr (SD_, 1, VD, 3,
1198 value_vr (SD_, 1, VS, 1));
1203 // Vector Shift Left Logical
1205 010010,5.SEL,5.VT,5.VS,5.VD,010000::64,f::SLL.fmt
1206 "sll.%s<SEL> v<VD>, v<VS>, %s<VT#SEL,VT>"
1208 // start-sanitize-vr5400
1210 // end-sanitize-vr5400
1213 int scale = get_scale (SD_, SEL);
1214 int mask = (4 << scale) - 1;
1215 for (i = 0; i < (8 >> scale); i++)
1216 store_vr (SD_, scale, VD, i,
1217 (value_vr (SD_, scale, VS, i)
1218 << (select_vr (SD_, SEL, VT, i) & mask)));
1223 // Vector Shift Right Arithmetic
1225 010010,5.SEL,5.VT,5.VS,5.VD,010011::64,f::SRA.fmt
1226 "sra.%s<SEL> v<VD>, v<VS>, %s<VT#SEL,VT>"
1230 int mask = (4 << scale) - 1;
1231 int scale = get_scale (SD_, SEL);
1232 for (i = 0; i < (8 >> scale); i++)
1233 store_vr (SD_, scale, VD, i,
1234 (value_vr (SD_, scale, VS, i)
1235 >> (select_vr (SD_, SEL, VT, i) & mask)));
1240 // Vector Shift Right Logical.
1242 010010,5.SEL,5.VT,5.VS,5.VD,010010::64,f::SRL.fmt
1243 "srl.%s<SEL> v<VD>, v<VS>, %s<VT#SEL,VT>"
1245 // start-sanitize-vr5400
1247 // end-sanitize-vr5400
1250 int scale = get_scale (SD_, SEL);
1251 int mask = (4 << scale) - 1;
1252 int zeros = (1 << (8 << scale)) - 1;
1253 for (i = 0; i < (8 >> scale); i++)
1254 store_vr (SD_, scale, VD, i,
1255 ((value_vr (SD_, scale, VS, i) & zeros)
1256 >> (select_vr (SD_, SEL, VT, i) & mask)));
1263 010010,5.SEL,5.VT,5.VS,5.VD,001010::64,f::SUB.fmt
1264 "sub.%s<SEL> v<VD>, v<VS>, %s<VT#SEL,VT>"
1266 // start-sanitize-vr5400
1268 // end-sanitize-vr5400
1271 int scale = get_scale (SD_, SEL);
1272 for (i = 0; i < (8 >> scale); i++)
1273 store_vr (SD_, scale, VD, i,
1274 (value_vr (SD_, scale, VS, i)
1275 - select_vr (SD_, SEL, VT, i)));
1280 // Accumulate Vector Difference
1282 010010,5.SEL,5.VT,5.VS,0,0000,110110::64,f::SUBA.fmt
1283 "suba.%s<SEL> v<VD>, v<VS>, %s<VT#SEL,VT>"
1287 int scale = get_scale (SD_, SEL);
1288 for (i = 0; i < (8 >> scale); i++)
1289 store_acc (SD_, scale, VD, i,
1290 (value_acc (SD, scale, i)
1291 + (signed64) value_vr (SD_, scale, VS, i)
1292 - (signed64) select_vr (SD_, SEL, VT, i)));
1297 // Load Vector Difference
1299 010010,5.SEL,5.VT,5.VS,1,0000,110110::64,f::SUBL.fmt
1300 "subl.%s<SEL> v<VD>, v<VS>, %s<VT#SEL,VT>"
1304 int scale = get_scale (SD_, SEL);
1305 for (i = 0; i < (8 >> scale); i++)
1306 store_acc (SD_, scale, VD, i,
1307 ((signed64) value_vr (SD_, scale, VS, i)
1308 - (signed64) select_vr (SD_, SEL, VT, i)));
1313 // Write Accumulator High.
1315 010010,1000,1.SEL,00000,5.VS,00000,111110::64,f::WACH.fmt
1316 "wach.%s<SEL> v<VS>"
1318 // start-sanitize-vr5400
1320 // end-sanitize-vr5400
1323 int scale = get_scale (SD_, SEL);
1324 for (i = 0; i < (8 >> scale); i++)
1325 store_acc (SD_, scale, i,
1326 (((signed64) value_vr (SD_, scale, VS, i) << (16 << scale))
1327 | MASKED (value_acc (SD_, scale, i), (16 << scale) - 1, 0)));
1332 // Vector Write Accumulator Low.
1334 010010,0000,1.SEL,5.VT,5.VS,00000,111110::64,f::WACL.fmt
1335 "wacl.%s<SEL> v<VS>, <VT>"
1337 // start-sanitize-vr5400
1339 // end-sanitize-vr5400
1342 int scale = get_scale (SD_, SEL);
1343 for (i = 0; i < (8 >> scale); i++)
1344 store_acc (SD_, scale, i,
1345 (((signed64) value_vr (SD_, scale, VS, i) << (16 << scale))
1346 | MASKED (value_vr (SD_, scale, VT, i),
1347 (16 << scale) - 1, 0)));
1354 010010,5.SEL,5.VT,5.VS,5.VD,001101::64,f::XOR.fmt
1355 "xor.%s<SEL> v<VD>, v<VS>, %s<VT#SEL,VT>"
1357 // start-sanitize-vr5400
1359 // end-sanitize-vr5400
1362 int scale = get_scale (SD_, SEL);
1363 for (i = 0; i < (8 >> scale); i++)
1364 store_vr (SD_, scale, VD, i,
1365 (value_vr (SD_, scale, VS, i)
1366 ^ select_vr (SD_, SEL, VT, i)));