3 // Simulator definition for the MIPS MDMX ASE.
4 // Copyright (C) 2002-2016 Free Software Foundation, Inc.
5 // Contributed by Ed Satterthwaite and Chris Demetriou, of Broadcom
6 // Corporation (SiByte).
8 // This file is part of GDB, the GNU debugger.
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.
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.
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/>.
23 // Reference: MIPS64 Architecture Volume IV-b:
24 // The MDMX Application-Specific Extension
26 // Notes on "format selectors" (FMTSEL):
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.
32 // Similarly, for the single-bit fields which differentiate between
33 // formats (FMTOP), 0 is OB format and 1 is QH format.
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.
42 // Check whether MDMX is usable, and if not signal an appropriate exception.
45 :function:::void:check_mdmx:instruction_word insn
49 SignalExceptionCoProcessorUnusable (1);
50 if ((SR & (status_MX|status_FR)) != (status_MX|status_FR))
51 SignalExceptionMDMX ();
52 check_u64 (SD_, insn);
58 // Check whether a given MDMX format selector indicates a valid and usable
59 // format, and if not signal an appropriate exception.
62 :function:::int:check_mdmx_fmtsel:instruction_word insn, int fmtsel
65 switch (fmtsel & 0x03)
71 case 0x03: /* UNPREDICTABLE */
72 SignalException (ReservedInstruction, insn);
81 // Check whether a given MDMX format bit indicates a valid and usable
82 // format, and if not signal an appropriate exception.
85 :function:::int:check_mdmx_fmtop:instruction_word insn, int fmtop
98 :%s::::FMTSEL:int fmtsel
102 if ((fmtsel & 0x1) == 0)
104 else if ((fmtsel & 0x3) == 1)
111 :%s::::FMTOP:int fmtop
128 if ((shop & 0x11) == 0x00)
129 switch ((shop >> 1) & 0x07)
131 case 3: return "upsl.ob";
132 case 4: return "pach.ob";
133 case 6: return "mixh.ob";
134 case 7: return "mixl.ob";
137 else if ((shop & 0x03) == 0x01)
138 switch ((shop >> 2) & 0x07)
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";
153 011110,5.FMTSEL,5.VT,5.VS,5.VD,001011:MDMX:64::ADD.fmt
154 "add.%s<FMTSEL> v<VD>, v<VS>, v<VT>"
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));
164 011110,5.FMTSEL,5.VT,5.VS,0,0000,110111:MDMX:64::ADDA.fmt
165 "adda.%s<FMTSEL> v<VS>, v<VT>"
169 check_mdmx (SD_, instruction_0);
170 if (check_mdmx_fmtsel (SD_, instruction_0, FMTSEL))
171 MX_AddA(ValueFPR(VS,fmt_mdmx),VT,FMTSEL);
175 011110,5.FMTSEL,5.VT,5.VS,1,0000,110111:MDMX:64::ADDL.fmt
176 "addl.%s<FMTSEL> v<VS>, v<VT>"
180 check_mdmx (SD_, instruction_0);
181 if (check_mdmx_fmtsel (SD_, instruction_0, FMTSEL))
182 MX_AddL(ValueFPR(VS,fmt_mdmx),VT,FMTSEL);
186 011110,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>"
193 check_mdmx (SD_, instruction_0);
194 check_mdmx_fmtop (SD_, instruction_0, FMTOP);
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);
203 011110,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>"
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);
220 011110,5.FMTSEL,5.VT,5.VS,5.VD,001100:MDMX:64::AND.fmt
221 "and.%s<FMTSEL> v<VD>, v<VS>, v<VT>"
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));
231 011110,5.FMTSEL,5.VT,5.VS,00000,000001:MDMX:64::C.EQ.fmt
232 "c.eq.%s<FMTSEL> v<VS>, v<VT>"
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);
242 011110,5.FMTSEL,5.VT,5.VS,00000,000101:MDMX:64::C.LE.fmt
243 "c.le.%s<FMTSEL> v<VS>, v<VT>"
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);
253 011110,5.FMTSEL,5.VT,5.VS,00000,000100:MDMX:64::C.LT.fmt
254 "c.lt.%s<FMTSEL> v<VS>, v<VT>"
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);
264 011110,5.FMTSEL,5.VT,5.VS,5.VD,000111:MDMX:64::MAX.fmt
265 "max.%s<FMTSEL> v<VD>, v<VS>, v<VT>"
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));
275 011110,5.FMTSEL,5.VT,5.VS,5.VD,000110:MDMX:64::MIN.fmt
276 "min.%s<FMTSEL> v<VD>, v<VS>, v<VT>"
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));
286 011110,3.SEL,01,5.VT,5.VS,5.VD,000000:MDMX:64::MSGN.QH
287 "msgn.qh v<VD>, v<VS>, v<VT>"
290 check_mdmx (SD_, instruction_0);
291 StoreFPR(VD,fmt_mdmx,MX_Msgn(ValueFPR(VS,fmt_mdmx),VT,qh_fmtsel(SEL)));
295 011110,5.FMTSEL,5.VT,5.VS,5.VD,110000:MDMX:64::MUL.fmt
296 "mul.%s<FMTSEL> v<VD>, v<VS>, v<VT>"
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));
306 011110,5.FMTSEL,5.VT,5.VS,0,0000,110011:MDMX:64::MULA.fmt
307 "mula.%s<FMTSEL> v<VS>, v<VT>"
311 check_mdmx (SD_, instruction_0);
312 if (check_mdmx_fmtsel (SD_, instruction_0, FMTSEL))
313 MX_MulA(ValueFPR(VS,fmt_mdmx),VT,FMTSEL);
317 011110,5.FMTSEL,5.VT,5.VS,1,0000,110011:MDMX:64::MULL.fmt
318 "mull.%s<FMTSEL> v<VS>, v<VT>"
322 check_mdmx (SD_, instruction_0);
323 if (check_mdmx_fmtsel (SD_, instruction_0, FMTSEL))
324 MX_MulL(ValueFPR(VS,fmt_mdmx),VT,FMTSEL);
328 011110,5.FMTSEL,5.VT,5.VS,0,0000,110010:MDMX:64::MULS.fmt
329 "muls.%s<FMTSEL> v<VS>, v<VT>"
333 check_mdmx (SD_, instruction_0);
334 if (check_mdmx_fmtsel (SD_, instruction_0, FMTSEL))
335 MX_MulS(ValueFPR(VS,fmt_mdmx),VT,FMTSEL);
339 011110,5.FMTSEL,5.VT,5.VS,1,0000,110010:MDMX:64::MULSL.fmt
340 "mulsl.%s<FMTSEL> v<VS>, v<VT>"
344 check_mdmx (SD_, instruction_0);
345 if (check_mdmx_fmtsel (SD_, instruction_0, FMTSEL))
346 MX_MulSL(ValueFPR(VS,fmt_mdmx),VT,FMTSEL);
350 011110,5.FMTSEL,5.VT,5.VS,5.VD,001111:MDMX:64::NOR.fmt
351 "nor.%s<FMTSEL> v<VD>, v<VS>, v<VT>"
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));
361 011110,5.FMTSEL,5.VT,5.VS,5.VD,001110:MDMX:64::OR.fmt
362 "or.%s<FMTSEL> v<VD>, v<VS>, v<VT>"
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));
372 011110,5.FMTSEL,5.VT,5.VS,5.VD,000010:MDMX:64::PICKF.fmt
373 "pickf.%s<FMTSEL> v<VD>, v<VS>, v<VT>"
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));
383 011110,5.FMTSEL,5.VT,5.VS,5.VD,000011:MDMX:64::PICKT.fmt
384 "pickt.%s<FMTSEL> v<VD>, v<VS>, v<VT>"
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));
394 011110,1000,1.FMTOP,00000,00000,5.VD,111111:MDMX:64::RACH.fmt
395 "rach.%s<FMTOP> v<VD>"
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));
405 011110,0000,1.FMTOP,00000,00000,5.VD,111111:MDMX:64::RACL.fmt
406 "racl.%s<FMTOP> v<VD>"
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));
416 011110,0100,1.FMTOP,00000,00000,5.VD,111111:MDMX:64::RACM.fmt
417 "racm.%s<FMTOP> v<VD>"
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));
427 011110,3.SEL,01,5.VT,00000,5.VD,100101:MDMX:64::RNAS.QH
428 "rnas.qh v<VD>, v<VT>"
431 check_mdmx (SD_, instruction_0);
432 StoreFPR(VD,fmt_mdmx,MX_RNAS(VT,qh_fmtsel(SEL)));
436 011110,5.FMTSEL,5.VT,00000,5.VD,100001:MDMX:64::RNAU.fmt
437 "rnau.%s<FMTSEL> v<VD>, v<VT>"
441 check_mdmx (SD_, instruction_0);
442 if (check_mdmx_fmtsel (SD_, instruction_0, FMTSEL))
443 StoreFPR(VD,fmt_mdmx,MX_RNAU(VT,FMTSEL));
447 011110,3.SEL,01,5.VT,00000,5.VD,100110:MDMX:64::RNES.QH
448 "rnes.qh v<VD>, v<VT>"
451 check_mdmx (SD_, instruction_0);
452 StoreFPR(VD,fmt_mdmx,MX_RNES(VT,qh_fmtsel(SEL)));
456 011110,5.FMTSEL,5.VT,00000,5.VD,100010:MDMX:64::RNEU.fmt
457 "rneu.%s<FMTSEL> v<VD>, v<VT>"
461 check_mdmx (SD_, instruction_0);
462 if (check_mdmx_fmtsel (SD_, instruction_0, FMTSEL))
463 StoreFPR(VD,fmt_mdmx,MX_RNEU(VT,FMTSEL));
467 011110,3.SEL,01,5.VT,00000,5.VD,100100:MDMX:64::RZS.QH
468 "rzs.qh v<VD>, v<VT>"
471 check_mdmx (SD_, instruction_0);
472 StoreFPR(VD,fmt_mdmx,MX_RZS(VT,qh_fmtsel(SEL)));
476 011110,5.FMTSEL,5.VT,00000,5.VD,100000:MDMX:64::RZU.fmt
477 "rzu.%s<FMTSEL> v<VD>, v<VT>"
481 check_mdmx (SD_, instruction_0);
482 if (check_mdmx_fmtsel (SD_, instruction_0, FMTSEL))
483 StoreFPR(VD,fmt_mdmx,MX_RZU(VT,FMTSEL));
487 011110,5.SHOP,5.VT,5.VS,5.VD,011111:MDMX:64::SHFL.op.fmt
488 "shfl.%s<SHOP> v<VD>, v<VS>, v<VT>"
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)));
498 011110,5.FMTSEL,5.VT,5.VS,5.VD,010000:MDMX:64::SLL.fmt
499 "sll.%s<FMTSEL> v<VD>, v<VS>, v<VT>"
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));
509 011110,3.SEL,01,5.VT,5.VS,5.VD,010011:MDMX:64::SRA.QH
510 "sra.qh v<VD>, v<VS>, v<VT>"
513 check_mdmx (SD_, instruction_0);
514 StoreFPR(VD,fmt_mdmx,MX_ShiftRightArith(ValueFPR(VS,fmt_mdmx),VT,qh_fmtsel(SEL)));
518 011110,5.FMTSEL,5.VT,5.VS,5.VD,010010:MDMX:64::SRL.fmt
519 "srl.%s<FMTSEL> v<VD>, v<VS>, v<VT>"
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));
529 011110,5.FMTSEL,5.VT,5.VS,5.VD,001010:MDMX:64::SUB.fmt
530 "sub.%s<FMTSEL> v<VD>, v<VS>, v<VT>"
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));
540 011110,5.FMTSEL,5.VT,5.VS,0,0000,110110:MDMX:64::SUBA.fmt
541 "suba.%s<FMTSEL> v<VS>, v<VT>"
545 check_mdmx (SD_, instruction_0);
546 if (check_mdmx_fmtsel (SD_, instruction_0, FMTSEL))
547 MX_SubA(ValueFPR(VS,fmt_mdmx),VT,FMTSEL);
551 011110,5.FMTSEL,5.VT,5.VS,1,0000,110110:MDMX:64::SUBL.fmt
552 "subl.%s<FMTSEL> v<VS>, v<VT>"
556 check_mdmx (SD_, instruction_0);
557 if (check_mdmx_fmtsel (SD_, instruction_0, FMTSEL))
558 MX_SubL(ValueFPR(VS,fmt_mdmx),VT,FMTSEL);
562 011110,1000,1.FMTOP,00000,5.VS,00000,111110:MDMX:64::WACH.fmt
563 "wach.%s<FMTOP> v<VS>"
567 check_mdmx (SD_, instruction_0);
568 check_mdmx_fmtop (SD_, instruction_0, FMTOP);
569 MX_WACH(FMTOP,ValueFPR(VS,fmt_mdmx));
573 011110,0000,1.FMTOP,5.VT,5.VS,00000,111110:MDMX:64::WACL.fmt
574 "wacl.%s<FMTOP> v<VS>, v<VT>"
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));
584 011110,5.FMTSEL,5.VT,5.VS,5.VD,001101:MDMX:64::XOR.fmt
585 "xor.%s<FMTSEL> v<VD>, v<VS>, v<VT>"
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));