1// -*- C -*-
2
3// Simulator definition for the MIPS MDMX ASE.
4// Copyright (C) 2002-2023 Free Software Foundation, Inc.
5// Contributed by Ed Satterthwaite and Chris Demetriou, of Broadcom
6// Corporation (SiByte).
7//
8// This file is part of GDB, the GNU debugger.
9//
10// This program is free software; you can redistribute it and/or modify
11// it under the terms of the GNU General Public License as published by
12// the Free Software Foundation; either version 3 of the License, or
13// (at your option) any later version.
14//
15// This program is distributed in the hope that it will be useful,
16// but WITHOUT ANY WARRANTY; without even the implied warranty of
17// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18// GNU General Public License for more details.
19//
20// You should have received a copy of the GNU General Public License
21// along with this program.  If not, see <http://www.gnu.org/licenses/>.
22
23//  Reference: MIPS64 Architecture Volume IV-b:
24//             The MDMX Application-Specific Extension
25
26//  Notes on "format selectors" (FMTSEL):
27//
28//   A selector with final bit 0 indicates OB format.
29//   A selector with final bits 01 indicates QH format.
30//   A selector with final bits 11 has UNPREDICTABLE result per the spec.
31//
32//  Similarly, for the single-bit fields which differentiate between
33//  formats (FMTOP), 0 is OB format and 1 is QH format.
34
35//  If you change this file to add instructions, please make sure that model
36//  "sb1" configurations still build, and that you've added no new
37//  instructions to the "sb1" model.
38
39
40// Helper:
41//
42// Check whether MDMX is usable, and if not signal an appropriate exception.
43//
44
45:function:::void:check_mdmx:instruction_word insn
46*mdmx:
47{
48  if (! COP_Usable (1))
49    SignalExceptionCoProcessorUnusable (1);
50  if ((SR & (status_MX|status_FR)) != (status_MX|status_FR))
51    SignalExceptionMDMX ();
52  check_u64 (SD_, insn);
53}
54
55
56// Helper:
57//
58// Check whether a given MDMX format selector indicates a valid and usable
59// format, and if not signal an appropriate exception.
60//
61
62:function:::int:check_mdmx_fmtsel:instruction_word insn, int fmtsel
63*mdmx:
64{
65  switch (fmtsel & 0x03)
66    {
67    case 0x00:     /* ob */
68    case 0x02:
69    case 0x01:     /* qh */
70      return 1;
71    case 0x03:     /* UNPREDICTABLE */
72      SignalException (ReservedInstruction, insn);
73      return 0;
74    }
75  return 0;
76}
77
78
79// Helper:
80//
81// Check whether a given MDMX format bit indicates a valid and usable
82// format, and if not signal an appropriate exception.
83//
84
85:function:::int:check_mdmx_fmtop:instruction_word insn, int fmtop
86*mdmx:
87{
88  switch (fmtop & 0x01)
89    {
90    case 0x00:     /* ob */
91    case 0x01:     /* qh */
92      return 1;
93    }
94  return 0;
95}
96
97
98:%s::::FMTSEL:int fmtsel
99*mdmx:
100*sb1:
101{
102  if ((fmtsel & 0x1) == 0)
103    return "ob";
104  else if ((fmtsel & 0x3) == 1)
105    return "qh";
106  else
107    return "?";
108}
109
110
111:%s::::FMTOP:int fmtop
112*mdmx:
113*sb1:
114{
115  switch (fmtop)
116    {
117    case 0: return "ob";
118    case 1: return "qh";
119    default: return "?";
120    }
121}
122
123
124:%s::::SHOP:int shop
125*mdmx:
126*sb1:
127{
128  if ((shop & 0x11) == 0x00)
129    switch ((shop >> 1) & 0x07)
130      {
131      case 3:  return "upsl.ob";
132      case 4:  return "pach.ob";
133      case 6:  return "mixh.ob";
134      case 7:  return "mixl.ob";
135      default: return "?";
136      }
137  else if ((shop & 0x03) == 0x01)
138    switch ((shop >> 2) & 0x07)
139      {
140      case 0:  return "mixh.qh";
141      case 1:  return "mixl.qh";
142      case 2:  return "pach.qh";
143      case 4:  return "bfla.qh";
144      case 6:  return "repa.qh";
145      case 7:  return "repb.qh";
146      default: return "?";
147      }
148  else
149    return "?";
150}
151
152
153011110,5.FMTSEL,5.VT,5.VS,5.VD,001011:MDMX:64::ADD.fmt
154"add.%s<FMTSEL> v<VD>, v<VS>, v<VT>"
155*mdmx:
156*sb1:
157{
158  check_mdmx (SD_, instruction_0);
159  if (check_mdmx_fmtsel (SD_, instruction_0, FMTSEL))
160    StoreFPR(VD,fmt_mdmx,MX_Add(ValueFPR(VS,fmt_mdmx),VT,FMTSEL));
161}
162
163
164011110,5.FMTSEL,5.VT,5.VS,0,0000,110111:MDMX:64::ADDA.fmt
165"adda.%s<FMTSEL> v<VS>, v<VT>"
166*mdmx:
167*sb1:
168{
169  check_mdmx (SD_, instruction_0);
170  if (check_mdmx_fmtsel (SD_, instruction_0, FMTSEL))
171    MX_AddA(ValueFPR(VS,fmt_mdmx),VT,FMTSEL);
172}
173
174
175011110,5.FMTSEL,5.VT,5.VS,1,0000,110111:MDMX:64::ADDL.fmt
176"addl.%s<FMTSEL> v<VS>, v<VT>"
177*mdmx:
178*sb1:
179{
180  check_mdmx (SD_, instruction_0);
181  if (check_mdmx_fmtsel (SD_, instruction_0, FMTSEL))
182    MX_AddL(ValueFPR(VS,fmt_mdmx),VT,FMTSEL);
183}
184
185
186011110,00,3.IMM,5.VT,5.VS,5.VD,0110,1.FMTOP,0:MDMX:64::ALNI.fmt
187"alni.%s<FMTOP> v<VD>, v<VS>, v<VT>, <IMM>"
188*mdmx:
189*sb1:
190{
191  uint64_t result;
192  int s;
193  check_mdmx (SD_, instruction_0);
194  check_mdmx_fmtop (SD_, instruction_0, FMTOP);
195  s = (IMM << 3);
196  result = ValueFPR(VS,fmt_mdmx) << s;
197  if (s != 0)  // x86 gcc treats >> 64 as >> 0
198    result |= ValueFPR(VT,fmt_mdmx) >> (64 - s);
199  StoreFPR(VD,fmt_mdmx,result);
200}
201
202
203011110,5.RS,5.VT,5.VS,5.VD,0110,1.FMTOP,1:MDMX:64::ALNV.fmt
204"alnv.%s<FMTOP> v<VD>, v<VS>, v<VT>, r<RS>"
205*mdmx:
206*sb1:
207{
208  uint64_t result;
209  int s;
210  check_mdmx (SD_, instruction_0);
211  check_mdmx_fmtop (SD_, instruction_0, FMTOP);
212  s = ((GPR[RS] & 0x7) << 3);
213  result = ValueFPR(VS,fmt_mdmx) << s;
214  if (s != 0)  // x86 gcc treats >> 64 as >> 0
215    result |= ValueFPR(VT,fmt_mdmx) >> (64 - s);
216  StoreFPR(VD,fmt_mdmx,result);
217}
218
219
220011110,5.FMTSEL,5.VT,5.VS,5.VD,001100:MDMX:64::AND.fmt
221"and.%s<FMTSEL> v<VD>, v<VS>, v<VT>"
222*mdmx:
223*sb1:
224{
225  check_mdmx (SD_, instruction_0);
226  if (check_mdmx_fmtsel (SD_, instruction_0, FMTSEL))
227    StoreFPR(VD,fmt_mdmx,MX_And(ValueFPR(VS,fmt_mdmx),VT,FMTSEL));
228}
229
230
231011110,5.FMTSEL,5.VT,5.VS,00000,000001:MDMX:64::C.EQ.fmt
232"c.eq.%s<FMTSEL> v<VS>, v<VT>"
233*mdmx:
234*sb1:
235{
236  check_mdmx (SD_, instruction_0);
237  if (check_mdmx_fmtsel (SD_, instruction_0, FMTSEL))
238    MX_Comp(ValueFPR(VS,fmt_mdmx),MX_C_EQ,VT,FMTSEL);
239}
240
241
242011110,5.FMTSEL,5.VT,5.VS,00000,000101:MDMX:64::C.LE.fmt
243"c.le.%s<FMTSEL> v<VS>, v<VT>"
244*mdmx:
245*sb1:
246{
247  check_mdmx (SD_, instruction_0);
248  if (check_mdmx_fmtsel (SD_, instruction_0, FMTSEL))
249    MX_Comp(ValueFPR(VS,fmt_mdmx),MX_C_LT|MX_C_EQ,VT,FMTSEL);
250}
251
252
253011110,5.FMTSEL,5.VT,5.VS,00000,000100:MDMX:64::C.LT.fmt
254"c.lt.%s<FMTSEL> v<VS>, v<VT>"
255*mdmx:
256*sb1:
257{
258  check_mdmx (SD_, instruction_0);
259  if (check_mdmx_fmtsel (SD_, instruction_0, FMTSEL))
260    MX_Comp(ValueFPR(VS,fmt_mdmx),MX_C_LT,VT,FMTSEL);
261}
262
263
264011110,5.FMTSEL,5.VT,5.VS,5.VD,000111:MDMX:64::MAX.fmt
265"max.%s<FMTSEL> v<VD>, v<VS>, v<VT>"
266*mdmx:
267*sb1:
268{
269  check_mdmx (SD_, instruction_0);
270  if (check_mdmx_fmtsel (SD_, instruction_0, FMTSEL))
271    StoreFPR(VD,fmt_mdmx,MX_Max(ValueFPR(VS,fmt_mdmx),VT,FMTSEL));
272}
273
274
275011110,5.FMTSEL,5.VT,5.VS,5.VD,000110:MDMX:64::MIN.fmt
276"min.%s<FMTSEL> v<VD>, v<VS>, v<VT>"
277*mdmx:
278*sb1:
279{
280  check_mdmx (SD_, instruction_0);
281  if (check_mdmx_fmtsel (SD_, instruction_0, FMTSEL))
282    StoreFPR(VD,fmt_mdmx,MX_Min(ValueFPR(VS,fmt_mdmx),VT,FMTSEL));
283}
284
285
286011110,3.SEL,01,5.VT,5.VS,5.VD,000000:MDMX:64::MSGN.QH
287"msgn.qh v<VD>, v<VS>, v<VT>"
288*mdmx:
289{
290  check_mdmx (SD_, instruction_0);
291  StoreFPR(VD,fmt_mdmx,MX_Msgn(ValueFPR(VS,fmt_mdmx),VT,qh_fmtsel(SEL)));
292}
293
294
295011110,5.FMTSEL,5.VT,5.VS,5.VD,110000:MDMX:64::MUL.fmt
296"mul.%s<FMTSEL> v<VD>, v<VS>, v<VT>"
297*mdmx:
298*sb1:
299{
300  check_mdmx (SD_, instruction_0);
301  if (check_mdmx_fmtsel (SD_, instruction_0, FMTSEL))
302    StoreFPR(VD,fmt_mdmx,MX_Mul(ValueFPR(VS,fmt_mdmx),VT,FMTSEL));
303}
304
305
306011110,5.FMTSEL,5.VT,5.VS,0,0000,110011:MDMX:64::MULA.fmt
307"mula.%s<FMTSEL> v<VS>, v<VT>"
308*mdmx:
309*sb1:
310{
311  check_mdmx (SD_, instruction_0);
312  if (check_mdmx_fmtsel (SD_, instruction_0, FMTSEL))
313    MX_MulA(ValueFPR(VS,fmt_mdmx),VT,FMTSEL);
314}
315
316
317011110,5.FMTSEL,5.VT,5.VS,1,0000,110011:MDMX:64::MULL.fmt
318"mull.%s<FMTSEL> v<VS>, v<VT>"
319*mdmx:
320*sb1:
321{
322  check_mdmx (SD_, instruction_0);
323  if (check_mdmx_fmtsel (SD_, instruction_0, FMTSEL))
324    MX_MulL(ValueFPR(VS,fmt_mdmx),VT,FMTSEL);
325}
326
327
328011110,5.FMTSEL,5.VT,5.VS,0,0000,110010:MDMX:64::MULS.fmt
329"muls.%s<FMTSEL> v<VS>, v<VT>"
330*mdmx:
331*sb1:
332{
333  check_mdmx (SD_, instruction_0);
334  if (check_mdmx_fmtsel (SD_, instruction_0, FMTSEL))
335    MX_MulS(ValueFPR(VS,fmt_mdmx),VT,FMTSEL);
336}
337
338
339011110,5.FMTSEL,5.VT,5.VS,1,0000,110010:MDMX:64::MULSL.fmt
340"mulsl.%s<FMTSEL> v<VS>, v<VT>"
341*mdmx:
342*sb1:
343{
344  check_mdmx (SD_, instruction_0);
345  if (check_mdmx_fmtsel (SD_, instruction_0, FMTSEL))
346    MX_MulSL(ValueFPR(VS,fmt_mdmx),VT,FMTSEL);
347}
348
349
350011110,5.FMTSEL,5.VT,5.VS,5.VD,001111:MDMX:64::NOR.fmt
351"nor.%s<FMTSEL> v<VD>, v<VS>, v<VT>"
352*mdmx:
353*sb1:
354{
355  check_mdmx (SD_, instruction_0);
356  if (check_mdmx_fmtsel (SD_, instruction_0, FMTSEL))
357    StoreFPR(VD,fmt_mdmx,MX_Nor(ValueFPR(VS,fmt_mdmx),VT,FMTSEL));
358}
359
360
361011110,5.FMTSEL,5.VT,5.VS,5.VD,001110:MDMX:64::OR.fmt
362"or.%s<FMTSEL> v<VD>, v<VS>, v<VT>"
363*mdmx:
364*sb1:
365{
366  check_mdmx (SD_, instruction_0);
367  if (check_mdmx_fmtsel (SD_, instruction_0, FMTSEL))
368    StoreFPR(VD,fmt_mdmx,MX_Or(ValueFPR(VS,fmt_mdmx),VT,FMTSEL));
369}
370
371
372011110,5.FMTSEL,5.VT,5.VS,5.VD,000010:MDMX:64::PICKF.fmt
373"pickf.%s<FMTSEL> v<VD>, v<VS>, v<VT>"
374*mdmx:
375*sb1:
376{
377  check_mdmx (SD_, instruction_0);
378  if (check_mdmx_fmtsel (SD_, instruction_0, FMTSEL))
379    StoreFPR(VD,fmt_mdmx,MX_Pick(0,ValueFPR(VS,fmt_mdmx),VT,FMTSEL));
380}
381
382
383011110,5.FMTSEL,5.VT,5.VS,5.VD,000011:MDMX:64::PICKT.fmt
384"pickt.%s<FMTSEL> v<VD>, v<VS>, v<VT>"
385*mdmx:
386*sb1:
387{
388  check_mdmx (SD_, instruction_0);
389  if (check_mdmx_fmtsel (SD_, instruction_0, FMTSEL))
390    StoreFPR(VD,fmt_mdmx,MX_Pick(1,ValueFPR(VS,fmt_mdmx),VT,FMTSEL));
391}
392
393
394011110,1000,1.FMTOP,00000,00000,5.VD,111111:MDMX:64::RACH.fmt
395"rach.%s<FMTOP> v<VD>"
396*mdmx:
397*sb1:
398{
399  check_mdmx (SD_, instruction_0);
400  check_mdmx_fmtop (SD_, instruction_0, FMTOP);
401  StoreFPR(VD,fmt_mdmx,MX_RAC(MX_RAC_H,FMTOP));
402}
403
404
405011110,0000,1.FMTOP,00000,00000,5.VD,111111:MDMX:64::RACL.fmt
406"racl.%s<FMTOP> v<VD>"
407*mdmx:
408*sb1:
409{
410  check_mdmx (SD_, instruction_0);
411  check_mdmx_fmtop (SD_, instruction_0, FMTOP);
412  StoreFPR(VD,fmt_mdmx,MX_RAC(MX_RAC_L,FMTOP));
413}
414
415
416011110,0100,1.FMTOP,00000,00000,5.VD,111111:MDMX:64::RACM.fmt
417"racm.%s<FMTOP> v<VD>"
418*mdmx:
419*sb1:
420{
421  check_mdmx (SD_, instruction_0);
422  check_mdmx_fmtop (SD_, instruction_0, FMTOP);
423  StoreFPR(VD,fmt_mdmx,MX_RAC(MX_RAC_M,FMTOP));
424}
425
426
427011110,3.SEL,01,5.VT,00000,5.VD,100101:MDMX:64::RNAS.QH
428"rnas.qh v<VD>, v<VT>"
429*mdmx:
430{
431  check_mdmx (SD_, instruction_0);
432  StoreFPR(VD,fmt_mdmx,MX_RNAS(VT,qh_fmtsel(SEL)));
433}
434
435
436011110,5.FMTSEL,5.VT,00000,5.VD,100001:MDMX:64::RNAU.fmt
437"rnau.%s<FMTSEL> v<VD>, v<VT>"
438*mdmx:
439*sb1:
440{
441  check_mdmx (SD_, instruction_0);
442  if (check_mdmx_fmtsel (SD_, instruction_0, FMTSEL))
443    StoreFPR(VD,fmt_mdmx,MX_RNAU(VT,FMTSEL));
444}
445
446
447011110,3.SEL,01,5.VT,00000,5.VD,100110:MDMX:64::RNES.QH
448"rnes.qh v<VD>, v<VT>"
449*mdmx:
450{
451  check_mdmx (SD_, instruction_0);
452  StoreFPR(VD,fmt_mdmx,MX_RNES(VT,qh_fmtsel(SEL)));
453}
454
455
456011110,5.FMTSEL,5.VT,00000,5.VD,100010:MDMX:64::RNEU.fmt
457"rneu.%s<FMTSEL> v<VD>, v<VT>"
458*mdmx:
459*sb1:
460{
461  check_mdmx (SD_, instruction_0);
462  if (check_mdmx_fmtsel (SD_, instruction_0, FMTSEL))
463    StoreFPR(VD,fmt_mdmx,MX_RNEU(VT,FMTSEL));
464}
465
466
467011110,3.SEL,01,5.VT,00000,5.VD,100100:MDMX:64::RZS.QH
468"rzs.qh v<VD>, v<VT>"
469*mdmx:
470{
471  check_mdmx (SD_, instruction_0);
472  StoreFPR(VD,fmt_mdmx,MX_RZS(VT,qh_fmtsel(SEL)));
473}
474
475
476011110,5.FMTSEL,5.VT,00000,5.VD,100000:MDMX:64::RZU.fmt
477"rzu.%s<FMTSEL> v<VD>, v<VT>"
478*mdmx:
479*sb1:
480{
481  check_mdmx (SD_, instruction_0);
482  if (check_mdmx_fmtsel (SD_, instruction_0, FMTSEL))
483    StoreFPR(VD,fmt_mdmx,MX_RZU(VT,FMTSEL));
484}
485
486
487011110,5.SHOP,5.VT,5.VS,5.VD,011111:MDMX:64::SHFL.op.fmt
488"shfl.%s<SHOP> v<VD>, v<VS>, v<VT>"
489*mdmx:
490*sb1:
491{
492  check_mdmx (SD_, instruction_0);
493  if (check_mdmx_fmtsel (SD_, instruction_0, SHOP))
494    StoreFPR(VD,fmt_mdmx,MX_SHFL(SHOP,ValueFPR(VS,fmt_mdmx),ValueFPR(VT,fmt_mdmx)));
495}
496
497
498011110,5.FMTSEL,5.VT,5.VS,5.VD,010000:MDMX:64::SLL.fmt
499"sll.%s<FMTSEL> v<VD>, v<VS>, v<VT>"
500*mdmx:
501*sb1:
502{
503  check_mdmx (SD_, instruction_0);
504  if (check_mdmx_fmtsel (SD_, instruction_0, FMTSEL))
505    StoreFPR(VD,fmt_mdmx,MX_ShiftLeftLogical(ValueFPR(VS,fmt_mdmx),VT,FMTSEL));
506}
507
508
509011110,3.SEL,01,5.VT,5.VS,5.VD,010011:MDMX:64::SRA.QH
510"sra.qh v<VD>, v<VS>, v<VT>"
511*mdmx:
512{
513  check_mdmx (SD_, instruction_0);
514  StoreFPR(VD,fmt_mdmx,MX_ShiftRightArith(ValueFPR(VS,fmt_mdmx),VT,qh_fmtsel(SEL)));
515}
516
517
518011110,5.FMTSEL,5.VT,5.VS,5.VD,010010:MDMX:64::SRL.fmt
519"srl.%s<FMTSEL> v<VD>, v<VS>, v<VT>"
520*mdmx:
521*sb1:
522{
523  check_mdmx (SD_, instruction_0);
524  if (check_mdmx_fmtsel (SD_, instruction_0, FMTSEL))
525    StoreFPR(VD,fmt_mdmx,MX_ShiftRightLogical(ValueFPR(VS,fmt_mdmx),VT,FMTSEL));
526}
527
528
529011110,5.FMTSEL,5.VT,5.VS,5.VD,001010:MDMX:64::SUB.fmt
530"sub.%s<FMTSEL> v<VD>, v<VS>, v<VT>"
531*mdmx:
532*sb1:
533{
534  check_mdmx (SD_, instruction_0);
535  if (check_mdmx_fmtsel (SD_, instruction_0, FMTSEL))
536    StoreFPR(VD,fmt_mdmx,MX_Sub(ValueFPR(VS,fmt_mdmx),VT,FMTSEL));
537}
538
539
540011110,5.FMTSEL,5.VT,5.VS,0,0000,110110:MDMX:64::SUBA.fmt
541"suba.%s<FMTSEL> v<VS>, v<VT>"
542*mdmx:
543*sb1:
544{
545  check_mdmx (SD_, instruction_0);
546  if (check_mdmx_fmtsel (SD_, instruction_0, FMTSEL))
547    MX_SubA(ValueFPR(VS,fmt_mdmx),VT,FMTSEL);
548}
549
550
551011110,5.FMTSEL,5.VT,5.VS,1,0000,110110:MDMX:64::SUBL.fmt
552"subl.%s<FMTSEL> v<VS>, v<VT>"
553*mdmx:
554*sb1:
555{
556  check_mdmx (SD_, instruction_0);
557  if (check_mdmx_fmtsel (SD_, instruction_0, FMTSEL))
558    MX_SubL(ValueFPR(VS,fmt_mdmx),VT,FMTSEL);
559}
560
561
562011110,1000,1.FMTOP,00000,5.VS,00000,111110:MDMX:64::WACH.fmt
563"wach.%s<FMTOP> v<VS>"
564*mdmx:
565*sb1:
566{
567  check_mdmx (SD_, instruction_0);
568  check_mdmx_fmtop (SD_, instruction_0, FMTOP);
569  MX_WACH(FMTOP,ValueFPR(VS,fmt_mdmx));
570}
571
572
573011110,0000,1.FMTOP,5.VT,5.VS,00000,111110:MDMX:64::WACL.fmt
574"wacl.%s<FMTOP> v<VS>, v<VT>"
575*mdmx:
576*sb1:
577{
578  check_mdmx (SD_, instruction_0);
579  check_mdmx_fmtop (SD_, instruction_0, FMTOP);
580  MX_WACL(FMTOP,ValueFPR(VS,fmt_mdmx),ValueFPR(VT,fmt_mdmx));
581}
582
583
584011110,5.FMTSEL,5.VT,5.VS,5.VD,001101:MDMX:64::XOR.fmt
585"xor.%s<FMTSEL> v<VD>, v<VS>, v<VT>"
586*mdmx:
587*sb1:
588{
589  check_mdmx (SD_, instruction_0);
590  if (check_mdmx_fmtsel (SD_, instruction_0, FMTSEL))
591    StoreFPR(VD,fmt_mdmx,MX_Xor(ValueFPR(VS,fmt_mdmx),VT,FMTSEL));
592}
593