4 // Ref: http://www.sgi.com/MIPS/arch/ISA5/MDMXspec.pdf
6 // Note: For OB instructions, the sel field is deduced by special
7 // handling of the "vt" operand.
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
20 // VecAcc is the Vector Accumulator.
21 // This accumulator is organized as 8X24 bit (192 bit) register.
22 // This accumulator holds only signed values.
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.
29 :function:::int:get_scale:int sel
32 switch (my_index X STATE_ARCHITECTURE)
42 /* octal byte - ssss0 */
46 /* quad halfword - sss01 */
50 semantic_illegal (sd, cia);
54 semantic_illegal (sd, cia);
63 // Fetch/Store VALUE in ELEMENT of vector register FPR.
64 // The the of the element determined by SCALE.
66 :function:::signed:value_vr:int scale, int fpr, int el
68 switch (FPR_STATE[fpr])
70 case fmt_uninterpreted:
71 FPR_STATE[fpr] = fmt_long;
77 sim_io_eprintf(sd, "Vector %d format invalid (PC = 0x08lx)\n",
79 FPR_STATE[fpr] = fmt_unknown;
85 signed8 value = *A1_8 (&FGR[fpr], 7 - el);
90 signed16 value = *A2_8 (&FGR[fpr], 3 - el);
99 :function:::signed:store_vr:int scale, int fpr, int element, signed value
101 switch (FPR_STATE[fpr])
103 case fmt_uninterpreted:
104 FPR_STATE[fpr] = fmt_long;
110 sim_io_eprintf(sd, "Vector %d format invalid (PC = 0x08lx)\n",
112 FPR_STATE[fpr] = fmt_unknown;
118 *A1_8 (&FGR[fpr], 7 - element) = value;
123 *A2_8 (&FGR[fpr], 3 - element) = value;
132 // Select a value from onr of FGR[VT][ELEMENT], VT and GFR[VT][CONST]
135 :function:::unsigned:select_vr:int sel, int vt, int element
139 /* element select - 0xxxx */
140 case 0x00: /* 0 xxx 0 */
148 return value_vr (SD_, 0, vt, sel >> 1);
149 case 0x01: /* 0 xx 01 */
153 return value_vr (SD_, 1, vt, sel >> 2);
154 case 0x03: /* 0 x 011 */
156 return value_vr (SD_, 2, vt, sel >> 3);
157 case 0x07: /* 0 x 111 */
159 return value_vr (SD_, 3, vt, sel >> 4);
161 /* select vector - 10xxx */
162 case 0x16: /* 10 11 0 */
163 return value_vr (SD_, 0, vt, element);
164 case 0x15: /* 10 1 01 */
165 return value_vr (SD_, 1, vt, element);
166 case 0x13: /* 10 011 */
167 return value_vr (SD_, 2, vt, element);
168 case 0x17: /* 10 111 */
169 return value_vr (SD_, 3, vt, element);
171 /* select immediate - 11xxx */
172 case 0x1e: /* 11 11 0 */
173 case 0x1d: /* 11 1 01 */
174 case 0x1b: /* 11 011 */
175 case 0x1f: /* 11 111 */
183 // Saturate (clamp) the signed value to (8 << SCALE) bits.
185 :function:::signed:Clamp:int scale, signed value
191 if (value != (signed8) value)
202 if (value != (signed16) value)
209 return value & 0xffff;
218 // Access a single bit of the floating point CC register.
220 :function:::void:store_cc:int i, int value
225 :function:::int:fetch_cc:int i
232 // Read/write the accumulator
234 :function:::signed64:value_acc:int scale, int element
240 value |= (unsigned64) (unsigned8) CPU->acc [element * 3 + 0];
241 value |= (unsigned64) (unsigned8) CPU->acc [element * 3 + 1] << 8;
242 value |= (signed64) (signed8) CPU->acc [element * 3 + 2] << 16;
245 value |= (unsigned64) (unsigned8) CPU->acc [element * 3 + 0];
246 value |= (unsigned64) (unsigned8) CPU->acc [element * 3 + 1] << 8;
247 value |= (unsigned64) (unsigned8) CPU->acc [element * 3 + 2] << 16;
248 value |= (unsigned64) (unsigned8) CPU->acc [element * 3 + 3] << 24;
249 value |= (unsigned64) (unsigned8) CPU->acc [element * 3 + 4] << 32;
250 value |= (signed64) (signed8) CPU->acc [element * 3 + 5] << 40;
256 :function:::void:store_acc:int scale, int element, signed64 value
261 CPU->acc [element * 3 + 0] = value >> 0;
262 CPU->acc [element * 3 + 1] = value >> 8;
263 CPU->acc [element * 3 + 2] = value >> 16;
266 CPU->acc [element * 3 + 0] = value >> 0;
267 CPU->acc [element * 3 + 1] = value >> 8;
268 CPU->acc [element * 3 + 2] = value >> 16;
269 CPU->acc [element * 3 + 3] = value >> 24;
270 CPU->acc [element * 3 + 4] = value >> 32;
271 CPU->acc [element * 3 + 5] = value >> 40;
279 :%s::::VT:int sel, int vt
283 sprintf (buf, "v%d[%d]", vt, sel);
284 else if (sel == 0x13)
285 sprintf (buf, "v%d", vt);
286 else if (sel == 0x1f)
287 sprintf (buf, "%d", vt);
289 sprintf (buf, "(invalid)");
315 010010,5.SEL,5.VT,5.VS,5.VD,001011::::ADD.fmt
316 "add.%s<SEL> v<VD>, v<VS>, %s<VT#SEL,VT>"
318 // start-sanitize-vr5400
320 // end-sanitize-vr5400
323 int scale = get_scale (SD_, SEL);
324 for (i = 0; i < (8 >> scale); i++)
325 store_vr (SD_, scale, VD, i,
327 (value_vr (SD_, scale, VS, i)
328 + select_vr (SD_, SEL, VT, i))));
332 // Accumulate Vector Add
334 010010,5.SEL,5.VT,5.VS,1,0000,110111::::ADDA.fmt
335 "adda.%s<SEL> v<VD>, v<VS>"
339 int scale = get_scale (SD_, SEL);
340 for (i = 0; i < (8 >> scale); i++)
341 store_acc (SD_, scale, i,
342 (value_acc (SD_, scale, i)
343 + (signed64) value_vr (SD_, scale, VS, i)
344 + (signed64) select_vr (SD_, SEL, VT, i)));
350 010010,5.SEL,5.VT,5.VS,0,0000,110111::::ADDA.fmt
351 "addl.%s<SEL> v<VD>, v<VS>"
355 int scale = get_scale (SD_, SEL);
356 for (i = 0; i < (8 >> scale); i++)
357 store_acc (SD_, scale, i,
358 ((signed64) value_vr (SD_, scale, VS, i)
359 + (signed64) select_vr (SD_, SEL, VT, i)));
364 // Vector align, Constant Alignment
366 :function:::void:ByteAlign:int vd, int imm, int vs, int vt
369 unsigned64 rs = value_fpr (sd, cia, vs, fmt_long);
370 unsigned64 rt = value_fpr (sd, cia, vt, fmt_long);
374 /* (vs || vt) [127 - S .. 64 - S] */
378 rd = (MOVED64 (rs, 64 - s, 0, 63, s)
379 | EXTRACTED64 (rt, 63, 64 - s));
383 /* (vs || vt) [63 + S .. S] */
387 rd = (MOVED64 (rs, s, 0, 63, 64 - s)
388 | EXTRACTED64 (rt, 63, s));
390 store_fpr (sd, cia, vd, rd, fmt_long);
393 010010,00,3.IMM,5.VT,5.VS,5.VD,0110,X,0::::ALNI.fmt
394 "alni.%s<FMT#X> v<VD>, v<VS>, v<VT>, <IMM>"
396 // start-sanitize-vr5400
398 // end-sanitize-vr5400
400 ByteAlign (SD_, VD, IMM, VS, VT);
405 // Vector align, Variable Alignment
407 010010,5.RS,5.VT,5.VS,5.VD,0110,X,1::::ALNV.fmt
408 "alnv.%s<FMT#X> v<VD>, v<VS>, v<VT>, r<RS>"
411 ByteAlign (SD_, VD, GPR[RS], VS, VT);
418 010010,5.SEL,5.VT,5.VS,5.VD,001100::::AND.fmt
419 "and.%s<SEL> v<VD>, v<VS>, %s<VT#SEL,VT>"
421 // start-sanitize-vr5400
423 // end-sanitize-vr5400
426 int scale = get_scale (SD_, SEL);
427 for (i = 0; i < (8 >> scale); i++)
428 store_vr (SD_, scale, VD, i,
429 (value_vr (SD_, scale, VS, i)
430 & select_vr (SD_, SEL, VT, i)));
435 // Vector Compare Equal.
438 010010,5.SEL,5.VT,5.VS,00000,000001::::C.EQ.fmt
439 "c.EQ.%s<SEL> v<VS>, %s<VT#SEL,VT>"
441 // start-sanitize-vr5400
443 // end-sanitize-vr5400
446 int scale = get_scale (SD_, SEL);
447 for (i = 0; i < (8 >> scale); i++)
449 (value_vr (SD_, scale, VS, i)
450 == select_vr (SD_, SEL, VT, i)));
455 // Vector Compare Less Than or Equal.
457 010010,5.SEL,5.VT,5.VS,00000,000101::::C.LE.fmt
458 "c.le.%s<SEL> v<VS>, %s<VT#SEL,VT>"
460 // start-sanitize-vr5400
462 // end-sanitize-vr5400
465 int scale = get_scale (SD_, SEL);
466 for (i = 0; i < (8 >> scale); i++)
468 (value_vr (SD_, scale, VS, i)
469 <= select_vr (SD_, SEL, VT, i)));
474 // Vector Compare Less Than.
476 010010,5.SEL,5.VT,5.VS,00000,000100::::C.LT.fmt
477 "c.lt.%s<SEL> v<VS>, %s<VT#SEL,VT>"
479 // start-sanitize-vr5400
481 // end-sanitize-vr5400
484 int scale = get_scale (SD_, SEL);
485 for (i = 0; i < (8 >> scale); i++)
487 (value_vr (SD_, scale, VS, i)
488 < select_vr (SD_, SEL, VT, i)));
495 :function:::signed:Max:int scale, signed l, signed r
503 010010,5.SEL,5.VT,5.VS,5.VD,000111::::MAX.fmt
504 "max.%s<SEL> v<VD>, v<VS>, %s<VT#SEL,VT>"
506 // start-sanitize-vr5400
508 // end-sanitize-vr5400
511 int scale = get_scale (SD_, SEL);
512 for (i = 0; i < (8 >> scale); i++)
513 store_vr (SD_, scale, VD, i,
515 value_vr (SD_, scale, VS, i),
516 select_vr (SD_, SEL, VT, i)));
523 :function:::signed:Min:int scale, signed l, signed r
531 010010,5.SEL,5.VT,5.VS,5.VD,000110::::MIN.fmt
532 "min.%s<SEL> v<VD>, v<VS>, %s<VT#SEL,VT>"
534 // start-sanitize-vr5400
536 // end-sanitize-vr5400
539 int scale = get_scale (SD_, SEL);
540 for (i = 0; i < (8 >> scale); i++)
541 store_vr (SD_, scale, VD, i,
543 value_vr (SD_, scale, VS, i),
544 select_vr (SD_, SEL, VT, i)));
551 :function:::signed:Sign:int scale, signed l, signed r
559 /* watch for overflow of MIN_INT */
563 if ((r & 0xff) == 0x80)
568 if ((r & 0xffff) == 0x8000)
579 010010,5.SEL,5.VT,5.VS,5.VD,000110::::MSGN.fmt
580 "msgn.%s<SEL> v<VD>, v<VS>, %s<VT#SEL,VT>"
584 int scale = get_scale (SD_, SEL);
586 /* only QH allowed */
587 semantic_illegal (sd, cia);
588 for (i = 0; i < (8 >> scale); i++)
589 store_vr (SD_, scale, VD, i,
591 value_vr (SD_, scale, VS, i),
592 select_vr (SD_, SEL, VT, i)));
599 010010,5.SEL,5.VT,5.VS,5.VD,110000::::MUL.fmt
600 "mul.%s<SEL> v<VD>, v<VS>, %s<VT#SEL,VT>"
602 // start-sanitize-vr5400
604 // end-sanitize-vr5400
607 int scale = get_scale (SD_, SEL);
608 for (i = 0; i < (8 >> scale); i++)
609 store_vr (SD_, scale, VD, i,
611 (value_vr (SD_, scale, VS, i)
612 * select_vr (SD_, SEL, VT, i))));
617 // Accumulate Vector Multiply
619 010010,5.SEL,5.VT,5.VS,00000,110011::::MULA.fmt
620 "mula.%s<SEL> v<VS>, %s<VT#SEL,VT>"
622 // start-sanitize-vr5400
624 // end-sanitize-vr5400
627 int scale = get_scale (SD_, SEL);
628 for (i = 0; i < (8 >> scale); i++)
629 store_acc (SD_, scale, i,
630 (value_acc (SD_, scale, i)
631 + ((signed64) value_vr (SD_, scale, VS, i)
632 * (signed64) select_vr (SD_, SEL, VT, i))));
637 // Add Vector Multiply to Accumulator.
639 010010,5.SEL,5.VT,5.VS,10000,110011::::MULL.fmt
640 "mull.%s<SEL> v<VS>, %s<VT#SEL,VT>"
642 // start-sanitize-vr5400
644 // end-sanitize-vr5400
647 int scale = get_scale (SD_, SEL);
648 for (i = 0; i < (8 >> scale); i++)
649 store_acc (SD_, scale, i,
650 ((signed64) value_vr (SD_, scale, VS, i)
651 * (signed64) select_vr (SD_, SEL, VT, i)));
656 // Subtract Vector Multiply from Accumulator
658 010010,5.SEL,5.VT,5.VS,00000,110010::::MULS.fmt
659 "muls.%s<SEL> v<VS>, %s<VT#SEL,VT>"
661 // start-sanitize-vr5400
663 // end-sanitize-vr5400
666 int scale = get_scale (SD_, SEL);
667 for (i = 0; i < (8 >> scale); i++)
668 store_acc (SD_, scale, i,
669 (value_acc (SD_, scale, i)
670 - ((signed64) value_vr (SD_, scale, VS, i)
671 * (signed64) select_vr (SD_, SEL, VT, i))));
676 // Load Negative Vector Multiply
678 010010,5.SEL,5.VT,5.VS,10000,110010::::MULSL.fmt
679 "mulsl.%s<SEL> v<VS>, %s<VT#SEL,VT>"
681 // start-sanitize-vr5400
683 // end-sanitize-vr5400
686 int scale = get_scale (SD_, SEL);
687 for (i = 0; i < (8 >> scale); i++)
688 store_acc (SD_, scale, i,
689 - ((signed64) value_vr (SD_, scale, VS, i)
690 * (signed64) select_vr (SD_, SEL, VT, i)));
697 010010,5.SEL,5.VT,5.VS,5.VD,001111::::NOR.fmt
698 "nor.%s<SEL> v<VD>, v<VS>, %s<VT#SEL,VT>"
700 // start-sanitize-vr5400
702 // end-sanitize-vr5400
705 int scale = get_scale (SD_, SEL);
706 for (i = 0; i < (8 >> scale); i++)
707 store_vr (SD_, scale, VD, i,
708 ~(value_vr (SD_, scale, VS, i)
709 | select_vr (SD_, SEL, VT, i)));
716 010010,5.SEL,5.VT,5.VS,5.VD,001110::::OR.fmt
717 "or.%s<SEL> v<VD>, v<VS>, %s<VT#SEL,VT>"
719 // start-sanitize-vr5400
721 // end-sanitize-vr5400
724 int scale = get_scale (SD_, SEL);
725 for (i = 0; i < (8 >> scale); i++)
726 store_vr (SD_, scale, VD, i,
727 (value_vr (SD_, scale, VS, i)
728 | select_vr (SD_, SEL, VT, i)));
733 // Select Vector Elements - False
735 010010,5.SEL,5.VT,5.VS,5.VD,000010::::PICKF.fmt
736 "pickf.%s<SEL> v<VD>, v<VS>, %s<VT#SEL,VT>"
738 // start-sanitize-vr5400
740 // end-sanitize-vr5400
743 int scale = get_scale (SD_, SEL);
744 for (i = 0; i < (8 >> scale); i++)
745 store_vr (SD_, scale, VD, i,
746 (fetch_cc (SD_, i) == 0
747 ? value_vr (SD_, scale, VS, i)
748 : select_vr (SD_, SEL, VT, i)));
753 // Select Vector Elements - True
755 010010,5.SEL,5.VT,5.VS,5.VD,000011::::PICKT.fmt
756 "pickt.%s<SEL> v<VD>, v<VS>, %s<VT#SEL,VT>"
758 // start-sanitize-vr5400
760 // end-sanitize-vr5400
763 int scale = get_scale (SD_, SEL);
764 for (i = 0; i < (8 >> scale); i++)
765 store_vr (SD_, scale, VD, i,
766 (fetch_cc (SD_, i) != 0
767 ? value_vr (SD_, scale, VS, i)
768 : select_vr (SD_, SEL, VT, i)));
773 // Scale, Round and Clamp Accumulator
796 :function:::signed:ScaleRoundClamp:int scale, int rnd, signed val, signed shift
798 int halfway = (1 << (shift - 1));
799 /* must be positive */
802 /* too much shift? */
819 case 0: /* round towards zero */
821 case 1: /* nearest, halfaway rounds away from zero */
827 case 2: /* nearest, halfway rounds to even! */
830 if (val & (halfway << 1))
833 val += (halfway - 1);
837 if (val & (halfway << 1))
840 val -= (halfway - 1);
868 /* normal signed clamp */
869 val = Clamp (_SD, scale, val);
875 010010,5.SEL,5.VT,00000,5.VD,100,3.RND::::Rx.fmt
876 "r%s<RND>.%s<SEL> v<VD>, v<VT>"
878 // start-sanitize-vr5400
880 // end-sanitize-vr5400
883 int scale = get_scale (SD_, SEL);
884 for (i = 0; i < (8 >> scale); i++)
885 store_vr (SD_, scale, VD, i,
886 ScaleRoundClamp (SD_, scale, RND,
887 value_acc (SD_, scale, i),
888 select_vr (SD_, SEL, VT, i)));
893 // Vector Read Accumulator Low.
895 010010,0000,1.SEL,00000,00000,5.VD,111111::::RACL.fmt
898 // start-sanitize-vr5400
900 // end-sanitize-vr5400
903 int scale = get_scale (SD_, SEL);
904 for (i = 0; i < (8 >> scale); i++)
905 store_vr (SD_, scale, VD, i,
906 EXTRACTED (value_acc (SD_, scale, i),
913 // Vector Read Accumulator Middle.
915 010010,0100,1.SEL,00000,00000,5.VD,111111::::RACM.fmt
918 // start-sanitize-vr5400
920 // end-sanitize-vr5400
923 int scale = get_scale (SD_, SEL);
924 for (i = 0; i < (8 >> scale); i++)
925 store_vr (SD_, scale, VD, i,
926 EXTRACTED (value_acc (SD_, scale, i),
933 // Vector Read Accumulator High.
935 010010,1000,1.SEL,00000,00000,5.VD,111111::::RACH.fmt
938 // start-sanitize-vr5400
940 // end-sanitize-vr5400
943 int scale = get_scale (SD_, SEL);
944 for (i = 0; i < (8 >> scale); i++)
945 store_vr (SD_, scale, VD, i,
946 EXTRACTED (value_acc (SD_, scale, i),
953 // Vector Element Shuffle.
955 010010,0000,0,5.VT,5.VS,5.VD,011111::::SHFL.UPUH.fmt
956 "shfl.upuh.%s<SEL> v<VD>, v<VS>, <VT>"
960 int scale = get_scale (SD_, SEL);
961 for (i = 0; i < 4; i++)
963 store_vr (SD_, 1, VD, i,
964 value_vr (SD_, 0, VS, i + 4) & 0xff);
968 010010,0001,0,5.VT,5.VS,5.VD,011111::::SHFL.UPUL.fmt
969 "shfl.upul.%s<SEL> v<VD>, v<VS>, <VT>"
973 for (i = 0; i < 4; i++)
975 store_vr (SD_, 1, VD, i,
976 value_vr (SD_, 0, VS, i) & 0xff);
980 010010,0000,0,5.VT,5.VS,5.VD,011111::::SHFL.UPSH.fmt
981 "shfl.upsh.%s<SEL> v<VD>, v<VS>, <VT>"
985 int scale = get_scale (SD_, SEL);
986 for (i = 0; i < 4; i++)
988 store_vr (SD_, 1, VD, i,
989 value_vr (SD_, 0, VS, i + 4));
993 010010,0001,0,5.VT,5.VS,5.VD,011111::::SHFL.UPSL.fmt
994 "shfl.upsl.%s<SEL> v<VD>, v<VS>, <VT>"
998 for (i = 0; i < 4; i++)
1000 store_vr (SD_, 1, VD, i,
1001 value_vr (SD_, 0, VS, i));
1005 010010,0100,1.SEL,5.VT,5.VS,5.VD,011111::::SHFL.PACH.fmt
1006 "shfl.pach.%s<SEL> v<VD>, v<VS>, <VT>"
1008 // start-sanitize-vr5400
1010 // end-sanitize-vr5400
1013 int scale = get_scale (SD_, SEL);
1014 for (i = 0; i < (4 >> scale); i++)
1016 store_vr (SD_, scale, VD, i,
1017 value_vr (SD_, scale, VT, i * 2 + 1));
1018 store_vr (SD_, scale, VD, 1 + (4 >> scale),
1019 value_vr (SD_, scale, VS, i * 2 + 1));
1023 010010,0101,1.SEL,5.VT,5.VS,5.VD,011111::::SHFL.PACL.fmt
1024 "shfl.pacl.%s<SEL> v<VD>, v<VS>, <VT>"
1026 // start-sanitize-vr5400
1028 // end-sanitize-vr5400
1031 int scale = get_scale (SD_, SEL);
1032 for (i = 0; i < (4 >> scale); i++)
1034 store_vr (SD_, scale, VD, i,
1035 value_vr (SD_, scale, VT, i * 2));
1036 store_vr (SD_, scale, VD, 1 + (4 >> scale),
1037 value_vr (SD_, scale, VS, i * 2));
1041 010010,0110,1.SEL,5.VT,5.VS,5.VD,011111::::SHFL.MIXH.fmt
1042 "shfl.mixh.%s<SEL> v<VD>, v<VS>, <VT>"
1044 // start-sanitize-vr5400
1046 // end-sanitize-vr5400
1049 int scale = get_scale (SD_, SEL);
1050 for (i = 0; i < (4 >> scale); i++)
1052 store_vr (SD_, scale, VD, i * 2,
1053 value_vr (SD_, scale, VT, i + (4 >> scale)));
1054 store_vr (SD_, scale, VD, i * 2 + 1,
1055 value_vr (SD_, scale, VS, i + (4 >> scale)));
1059 010010,0111,1.SEL,5.VT,5.VS,5.VD,011111::::SHFL.MIXL.fmt
1060 "shfl.mixl.%s<SEL> v<VD>, v<VS>, <VT>"
1062 // start-sanitize-vr5400
1064 // end-sanitize-vr5400
1067 int scale = get_scale (SD_, SEL);
1068 for (i = 0; i < (4 >> scale); i++)
1070 store_vr (SD_, scale, VD, i * 2,
1071 value_vr (SD_, scale, VT, i));
1072 store_vr (SD_, scale, VD, i * 2 + 1,
1073 value_vr (SD_, scale, VS, i));
1077 010010,100,01,5.VT,5.VS,5.VD,011111::::SHFL.BFLA.fmt
1078 "shfl.bfla.qh v<VD>, v<VS>, <VT>"
1081 store_vr (SD_, 1, VD, 0,
1082 value_vr (SD_, 1, VT, 1));
1083 store_vr (SD_, 1, VD, 1,
1084 value_vr (SD_, 1, VS, 0));
1085 store_vr (SD_, 1, VD, 2,
1086 value_vr (SD_, 1, VT, 3));
1087 store_vr (SD_, 1, VD, 3,
1088 value_vr (SD_, 1, VS, 2));
1091 010010,101,01,5.VT,5.VS,5.VD,011111::::SHFL.BFLB.fmt
1092 "shfl.bflb.qh v<VD>, v<VS>, <VT>"
1095 store_vr (SD_, 1, VD, 0,
1096 value_vr (SD_, 1, VT, 3));
1097 store_vr (SD_, 1, VD, 1,
1098 value_vr (SD_, 1, VS, 2));
1099 store_vr (SD_, 1, VD, 2,
1100 value_vr (SD_, 1, VT, 1));
1101 store_vr (SD_, 1, VD, 3,
1102 value_vr (SD_, 1, VS, 0));
1105 010010,101,01,5.VT,5.VS,5.VD,011111::::SHFL.REPA.fmt
1106 "shfl.repa.qh v<VD>, v<VS>, <VT>"
1109 store_vr (SD_, 1, VD, 0,
1110 value_vr (SD_, 1, VT, 2));
1111 store_vr (SD_, 1, VD, 1,
1112 value_vr (SD_, 1, VT, 3));
1113 store_vr (SD_, 1, VD, 2,
1114 value_vr (SD_, 1, VS, 2));
1115 store_vr (SD_, 1, VD, 3,
1116 value_vr (SD_, 1, VS, 3));
1119 010010,101,01,5.VT,5.VS,5.VD,011111::::SHFL.REPB.fmt
1120 "shfl.repb.qh v<VD>, v<VS>, <VT>"
1123 store_vr (SD_, 1, VD, 0,
1124 value_vr (SD_, 1, VT, 0));
1125 store_vr (SD_, 1, VD, 1,
1126 value_vr (SD_, 1, VT, 1));
1127 store_vr (SD_, 1, VD, 2,
1128 value_vr (SD_, 1, VS, 0));
1129 store_vr (SD_, 1, VD, 3,
1130 value_vr (SD_, 1, VS, 1));
1135 // Vector Shift Left Logical
1137 010010,5.SEL,5.VT,5.VS,5.VD,010000::::SLL.fmt
1138 "sll.%s<SEL> v<VD>, v<VS>, %s<VT#SEL,VT>"
1140 // start-sanitize-vr5400
1142 // end-sanitize-vr5400
1145 int scale = get_scale (SD_, SEL);
1146 int mask = (4 << scale) - 1;
1147 for (i = 0; i < (8 >> scale); i++)
1148 store_vr (SD_, scale, VD, i,
1149 (value_vr (SD_, scale, VS, i)
1150 << (select_vr (SD_, SEL, VT, i) & mask)));
1155 // Vector Shift Right Arithmetic
1157 010010,5.SEL,5.VT,5.VS,5.VD,010011::::SRA.fmt
1158 "sra.%s<SEL> v<VD>, v<VS>, %s<VT#SEL,VT>"
1162 int mask = (4 << scale) - 1;
1163 int scale = get_scale (SD_, SEL);
1164 for (i = 0; i < (8 >> scale); i++)
1165 store_vr (SD_, scale, VD, i,
1166 (value_vr (SD_, scale, VS, i)
1167 >> (select_vr (SD_, SEL, VT, i) & mask)));
1172 // Vector Shift Right Logical.
1174 010010,5.SEL,5.VT,5.VS,5.VD,010010::::SRL.fmt
1175 "srl.%s<SEL> v<VD>, v<VS>, %s<VT#SEL,VT>"
1177 // start-sanitize-vr5400
1179 // end-sanitize-vr5400
1182 int scale = get_scale (SD_, SEL);
1183 int mask = (4 << scale) - 1;
1184 int zeros = (1 << (8 << scale)) - 1;
1185 for (i = 0; i < (8 >> scale); i++)
1186 store_vr (SD_, scale, VD, i,
1187 ((value_vr (SD_, scale, VS, i) & zeros)
1188 >> (select_vr (SD_, SEL, VT, i) & mask)));
1195 010010,5.SEL,5.VT,5.VS,5.VD,001010::::SUB.fmt
1196 "sub.%s<SEL> v<VD>, v<VS>, %s<VT#SEL,VT>"
1198 // start-sanitize-vr5400
1200 // end-sanitize-vr5400
1203 int scale = get_scale (SD_, SEL);
1204 for (i = 0; i < (8 >> scale); i++)
1205 store_vr (SD_, scale, VD, i,
1206 (value_vr (SD_, scale, VS, i)
1207 - select_vr (SD_, SEL, VT, i)));
1212 // Accumulate Vector Difference
1214 010010,5.SEL,5.VT,5.VS,0,0000,110110::::SUBA.fmt
1215 "suba.%s<SEL> v<VD>, v<VS>, %s<VT#SEL,VT>"
1219 int scale = get_scale (SD_, SEL);
1220 for (i = 0; i < (8 >> scale); i++)
1221 store_acc (SD_, scale, VD, i,
1222 (value_acc (SD, scale, i)
1223 + (signed64) value_vr (SD_, scale, VS, i)
1224 - (signed64) select_vr (SD_, SEL, VT, i)));
1229 // Load Vector Difference
1231 010010,5.SEL,5.VT,5.VS,1,0000,110110::::SUBL.fmt
1232 "subl.%s<SEL> v<VD>, v<VS>, %s<VT#SEL,VT>"
1236 int scale = get_scale (SD_, SEL);
1237 for (i = 0; i < (8 >> scale); i++)
1238 store_acc (SD_, scale, VD, i,
1239 ((signed64) value_vr (SD_, scale, VS, i)
1240 - (signed64) select_vr (SD_, SEL, VT, i)));
1245 // Write Accumulator High.
1247 010010,1000,1.SEL,00000,5.VS,00000,111110::::WACH.fmt
1248 "wach.%s<SEL> v<VS>"
1250 // start-sanitize-vr5400
1252 // end-sanitize-vr5400
1255 int scale = get_scale (SD_, SEL);
1256 for (i = 0; i < (8 >> scale); i++)
1257 store_acc (SD_, scale, i,
1258 (((signed64) value_vr (SD_, scale, VS, i) << (16 << scale))
1259 | MASKED (value_acc (SD_, scale, i), (16 << scale) - 1, 0)));
1264 // Vector Write Accumulator Low.
1266 010010,0000,1.SEL,5.VT,5.VS,00000,111110::::WACL.fmt
1267 "wacl.%s<SEL> v<VS>, <VT>"
1269 // start-sanitize-vr5400
1271 // end-sanitize-vr5400
1274 int scale = get_scale (SD_, SEL);
1275 for (i = 0; i < (8 >> scale); i++)
1276 store_acc (SD_, scale, i,
1277 (((signed64) value_vr (SD_, scale, VS, i) << (16 << scale))
1278 | MASKED (value_vr (SD_, scale, VT, i),
1279 (16 << scale) - 1, 0)));
1286 010010,5.SEL,5.VT,5.VS,5.VD,001101::::XOR.fmt
1287 "xor.%s<SEL> v<VD>, v<VS>, %s<VT#SEL,VT>"
1289 // start-sanitize-vr5400
1291 // end-sanitize-vr5400
1294 int scale = get_scale (SD_, SEL);
1295 for (i = 0; i < (8 >> scale); i++)
1296 store_vr (SD_, scale, VD, i,
1297 (value_vr (SD_, scale, VS, i)
1298 ^ select_vr (SD_, SEL, VT, i)));