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