decoder.isa revision 7952:896a68fc68dc
1// -*- mode:c++ -*-
2
3// Copyright (c) 2007 MIPS Technologies, Inc.
4// All rights reserved.
5//
6// Redistribution and use in source and binary forms, with or without
7// modification, are permitted provided that the following conditions are
8// met: redistributions of source code must retain the above copyright
9// notice, this list of conditions and the following disclaimer;
10// redistributions in binary form must reproduce the above copyright
11// notice, this list of conditions and the following disclaimer in the
12// documentation and/or other materials provided with the distribution;
13// neither the name of the copyright holders nor the names of its
14// contributors may be used to endorse or promote products derived from
15// this software without specific prior written permission.
16//
17// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28//
29// Authors: Korey Sewell
30//          Brett Miller
31//          Jaidev Patwardhan
32
33////////////////////////////////////////////////////////////////////
34//
35// The actual MIPS32 ISA decoder
36// -----------------------------
37// The following instructions are specified in the MIPS32 ISA
38// Specification. Decoding closely follows the style specified
39// in the MIPS32 ISA specification document starting with Table
40// A-2 (document available @ http://www.mips.com)
41//
42decode OPCODE_HI default Unknown::unknown() {
43    //Table A-2
44    0x0: decode OPCODE_LO {
45        0x0: decode FUNCTION_HI {
46            0x0: decode FUNCTION_LO {
47                0x1: decode MOVCI {
48                    format BasicOp {
49                        0: movf({{
50                            Rd = (getCondCode(FCSR, CC) == 0) ? Rd : Rs;
51                        }});
52                        1: movt({{
53                            Rd = (getCondCode(FCSR, CC) == 1) ? Rd : Rs;
54                        }});
55                    }
56                }
57
58                format BasicOp {
59                    //Table A-3 Note: "Specific encodings of the rd, rs, and
60                    //rt fields are used to distinguish SLL, SSNOP, and EHB
61                    //functions
62                    0x0: decode RS  {
63                        0x0: decode RT_RD {
64                            0x0: decode SA default Nop::nop() {
65                                 0x1: ssnop({{;}});
66                                 0x3: ehb({{;}});
67                            }
68                            default: sll({{ Rd = Rt.uw << SA; }});
69                        }
70                    }
71
72                    0x2: decode RS_SRL {
73                        0x0:decode SRL {
74                            0: srl({{ Rd = Rt.uw >> SA; }});
75
76                            //Hardcoded assuming 32-bit ISA,
77                            //probably need parameter here
78                            1: rotr({{
79                                Rd = (Rt.uw << (32 - SA)) | (Rt.uw >> SA);
80                            }});
81                        }
82                    }
83
84                    0x3: decode RS {
85                        0x0: sra({{
86                            uint32_t temp = Rt >> SA;
87                            if ( (Rt & 0x80000000) > 0 ) {
88                                uint32_t mask = 0x80000000;
89                                for(int i=0; i < SA; i++) {
90                                    temp |= mask;
91                                    mask = mask >> 1;
92                                }
93                            }
94                            Rd = temp;
95                        }});
96                    }
97
98                    0x4: sllv({{ Rd = Rt.uw << Rs<4:0>; }});
99
100                    0x6: decode SRLV {
101                        0: srlv({{ Rd = Rt.uw >> Rs<4:0>; }});
102
103                        //Hardcoded assuming 32-bit ISA,
104                        //probably need parameter here
105                        1: rotrv({{
106                            Rd = (Rt.uw << (32 - Rs<4:0>)) |
107                                 (Rt.uw >> Rs<4:0>);
108                        }});
109                    }
110
111                    0x7: srav({{
112                        int shift_amt = Rs<4:0>;
113
114                        uint32_t temp = Rt >> shift_amt;
115
116                        if ((Rt & 0x80000000) > 0) {
117                            uint32_t mask = 0x80000000;
118                            for (int i = 0; i < shift_amt; i++) {
119                                temp |= mask;
120                                mask = mask >> 1;
121                            }
122                        }
123                        Rd = temp;
124                    }});
125                }
126            }
127
128            0x1: decode FUNCTION_LO {
129                //Table A-3 Note: "Specific encodings of the hint field are
130                //used to distinguish JR from JR.HB and JALR from JALR.HB"
131                format Jump {
132                    0x0: decode HINT {
133                        0x1: jr_hb({{
134                            Config1Reg config1 = Config1;
135                            if (config1.ca == 0) {
136                                NNPC = Rs;
137                            } else {
138                                panic("MIPS16e not supported\n");
139                            }
140                        }}, IsReturn, ClearHazards);
141                        default: jr({{
142                            Config1Reg config1 = Config1;
143                            if (config1.ca == 0) {
144                                NNPC = Rs;
145                            } else {
146                                panic("MIPS16e not supported\n");
147                            }
148                        }}, IsReturn);
149                    }
150
151                    0x1: decode HINT {
152                        0x1: jalr_hb({{
153                            Rd = NNPC;
154                            NNPC = Rs;
155                        }}, IsCall, ClearHazards);
156                        default: jalr({{
157                            Rd = NNPC;
158                            NNPC = Rs;
159                        }}, IsCall);
160                    }
161                }
162
163                format BasicOp {
164                    0x2: movz({{ Rd = (Rt == 0) ? Rs : Rd; }});
165                    0x3: movn({{ Rd = (Rt != 0) ? Rs : Rd; }});
166#if FULL_SYSTEM
167                    0x4: syscall({{ fault = new SystemCallFault(); }});
168#else
169                    0x4: syscall({{ xc->syscall(R2); }},
170                                 IsSerializeAfter, IsNonSpeculative);
171#endif
172                    0x7: sync({{ ; }}, IsMemBarrier);
173                    0x5: break({{fault = new BreakpointFault();}});
174                }
175
176            }
177
178            0x2: decode FUNCTION_LO {
179                0x0: HiLoRsSelOp::mfhi({{ Rd = HI_RS_SEL; }},
180                             IntMultOp, IsIprAccess);
181                0x1: HiLoRdSelOp::mthi({{ HI_RD_SEL = Rs; }});
182                0x2: HiLoRsSelOp::mflo({{ Rd = LO_RS_SEL; }},
183                             IntMultOp, IsIprAccess);
184                0x3: HiLoRdSelOp::mtlo({{ LO_RD_SEL = Rs; }});
185            }
186
187            0x3: decode FUNCTION_LO {
188                format HiLoRdSelValOp {
189                    0x0: mult({{ val = Rs.sd * Rt.sd; }}, IntMultOp);
190                    0x1: multu({{ val = Rs.ud * Rt.ud; }}, IntMultOp);
191                }
192
193                format HiLoOp {
194                    0x2: div({{
195                        if (Rt.sd != 0) {
196                            HI0 = Rs.sd % Rt.sd;
197                            LO0 = Rs.sd / Rt.sd;
198                        }
199                    }}, IntDivOp);
200
201                    0x3: divu({{
202                        if (Rt.ud != 0) {
203                            HI0 = Rs.ud % Rt.ud;
204                            LO0 = Rs.ud / Rt.ud;
205                        }
206                    }}, IntDivOp);
207                }
208            }
209
210            0x4: decode HINT {
211                0x0: decode FUNCTION_LO {
212                    format IntOp {
213                        0x0: add({{
214                            /* More complicated since an ADD can cause 
215                               an arithmetic overflow exception */
216                            int64_t Src1 = Rs.sw;
217                            int64_t Src2 = Rt.sw;
218                            int64_t temp_result;
219#if FULL_SYSTEM
220                            if (((Src1 >> 31) & 1) == 1)
221                                Src1 |= 0x100000000LL;
222#endif
223                            temp_result = Src1 + Src2;
224#if FULL_SYSTEM
225                            if (bits(temp_result, 31) ==
226                                bits(temp_result, 32)) {
227#endif
228                                Rd.sw = temp_result;
229#if FULL_SYSTEM
230                            } else {
231                                fault = new ArithmeticFault();
232                            }
233#endif
234                        }});
235                        0x1: addu({{ Rd.sw = Rs.sw + Rt.sw;}});
236                        0x2: sub({{
237                            /* More complicated since an SUB can cause
238                               an arithmetic overflow exception */
239                            int64_t Src1 = Rs.sw;
240                            int64_t Src2 = Rt.sw;
241                            int64_t temp_result = Src1 - Src2;
242#if  FULL_SYSTEM
243                            if (bits(temp_result, 31) == 
244                                bits(temp_result, 32)) {
245#endif
246                                Rd.sw = temp_result;
247#if  FULL_SYSTEM
248                            } else {
249                                fault = new ArithmeticFault();
250                            }
251#endif
252                        }});
253                        0x3: subu({{ Rd.sw = Rs.sw - Rt.sw; }});
254                        0x4: and({{ Rd = Rs & Rt; }});
255                        0x5: or({{ Rd = Rs | Rt; }});
256                        0x6: xor({{ Rd = Rs ^ Rt; }});
257                        0x7: nor({{ Rd = ~(Rs | Rt); }});
258                    }
259                }
260            }
261
262            0x5: decode HINT {
263                0x0: decode FUNCTION_LO {
264                    format IntOp{
265                        0x2: slt({{  Rd.sw = (Rs.sw < Rt.sw) ? 1 : 0 }});
266                        0x3: sltu({{ Rd.uw = (Rs.uw < Rt.uw) ? 1 : 0 }});
267                    }
268                }
269            }
270
271            0x6: decode FUNCTION_LO {
272                format Trap {
273                    0x0: tge({{  cond = (Rs.sw >= Rt.sw); }});
274                    0x1: tgeu({{ cond = (Rs.uw >= Rt.uw); }});
275                    0x2: tlt({{ cond = (Rs.sw < Rt.sw); }});
276                    0x3: tltu({{ cond = (Rs.uw < Rt.uw); }});
277                    0x4: teq({{ cond = (Rs.sw == Rt.sw); }});
278                    0x6: tne({{ cond = (Rs.sw != Rt.sw); }});
279                }
280            }
281        }
282
283        0x1: decode REGIMM_HI {
284            0x0: decode REGIMM_LO {
285                format Branch {
286                    0x0: bltz({{ cond = (Rs.sw < 0); }});
287                    0x1: bgez({{ cond = (Rs.sw >= 0); }});
288                    0x2: bltzl({{ cond = (Rs.sw < 0); }}, Likely);
289                    0x3: bgezl({{ cond = (Rs.sw >= 0); }}, Likely);
290                }
291            }
292
293            0x1: decode REGIMM_LO {
294                format TrapImm {
295                    0x0: tgei( {{ cond = (Rs.sw >= (int16_t)INTIMM); }});
296                    0x1: tgeiu({{
297                        cond = (Rs.uw >= (uint32_t)(int32_t)(int16_t)INTIMM);
298                    }});
299                    0x2: tlti( {{ cond = (Rs.sw < (int16_t)INTIMM); }});
300                    0x3: tltiu({{
301                        cond = (Rs.uw < (uint32_t)(int32_t)(int16_t)INTIMM);
302                    }});
303                    0x4: teqi( {{ cond = (Rs.sw == (int16_t)INTIMM); }});
304                    0x6: tnei( {{ cond = (Rs.sw != (int16_t)INTIMM); }});
305                }
306            }
307
308            0x2: decode REGIMM_LO {
309                format Branch {
310                    0x0: bltzal({{ cond = (Rs.sw < 0); }}, Link);
311                    0x1: decode RS {
312                        0x0: bal ({{ cond = 1; }}, IsCall, Link);
313                        default: bgezal({{ cond = (Rs.sw >= 0); }}, Link);
314                    }
315                    0x2: bltzall({{ cond = (Rs.sw < 0); }}, Link, Likely);
316                    0x3: bgezall({{ cond = (Rs.sw >= 0); }}, Link, Likely);
317                }
318            }
319
320            0x3: decode REGIMM_LO {
321                // from Table 5-4 MIPS32 REGIMM Encoding of rt Field
322                // (DSP ASE MANUAL)
323                0x4: DspBranch::bposge32({{ cond = (dspctl<5:0> >= 32); }});
324                format WarnUnimpl {
325                    0x7: synci();
326                }
327            }
328        }
329
330        format Jump {
331            0x2: j({{ NNPC = (NPC & 0xF0000000) | (JMPTARG << 2); }});
332            0x3: jal({{ NNPC = (NPC & 0xF0000000) | (JMPTARG << 2); }},
333                     IsCall, Link);
334        }
335
336        format Branch {
337            0x4: decode RS_RT  {
338                0x0: b({{ cond = 1; }});
339                default: beq({{ cond = (Rs.sw == Rt.sw); }});
340            }
341            0x5: bne({{ cond = (Rs.sw != Rt.sw); }});
342            0x6: blez({{ cond = (Rs.sw <= 0); }});
343            0x7: bgtz({{ cond = (Rs.sw > 0); }});
344        }
345    }
346
347    0x1: decode OPCODE_LO {
348        format IntImmOp {
349            0x0: addi({{
350                int64_t Src1 = Rs.sw;
351                int64_t Src2 = imm;
352                int64_t temp_result;
353#if  FULL_SYSTEM
354                if (((Src1 >> 31) & 1) == 1)
355                    Src1 |= 0x100000000LL;
356#endif
357                temp_result = Src1 + Src2;
358#if  FULL_SYSTEM
359                if (bits(temp_result, 31) == bits(temp_result, 32)) {
360#endif
361                    Rt.sw = temp_result;
362#if  FULL_SYSTEM
363                } else {
364                    fault = new ArithmeticFault();
365                }
366#endif
367            }});
368            0x1: addiu({{ Rt.sw = Rs.sw + imm; }});
369            0x2: slti({{ Rt.sw = (Rs.sw < imm) ? 1 : 0 }});
370            0x3: sltiu({{ Rt.uw = (Rs.uw < (uint32_t)sextImm) ? 1 : 0;}});
371            0x4: andi({{ Rt.sw = Rs.sw & zextImm; }});
372            0x5: ori({{ Rt.sw = Rs.sw | zextImm; }});
373            0x6: xori({{ Rt.sw = Rs.sw ^ zextImm; }});
374
375            0x7: decode RS {
376                0x0: lui({{ Rt = imm << 16; }});
377            }
378        }
379    }
380
381    0x2: decode OPCODE_LO {
382        //Table A-11 MIPS32 COP0 Encoding of rs Field
383        0x0: decode RS_MSB {
384            0x0: decode RS {
385                format CP0Control {
386                    0x0: mfc0({{
387                        Config3Reg config3 = Config3;
388                        PageGrainReg pageGrain = PageGrain;
389                        Rt = CP0_RD_SEL;
390                        /* Hack for PageMask */
391                        if (RD == 5) {
392                            // PageMask
393                            if (config3.sp == 0 || pageGrain.esp == 0)
394                                Rt &= 0xFFFFE7FF;
395                        }
396                    }});
397                    0x4: mtc0({{ 
398                        CP0_RD_SEL = Rt;
399                        CauseReg cause = Cause;
400                        IntCtlReg intCtl = IntCtl;
401                        if (RD == 11) {
402                            // Compare
403                            if (cause.ti == 1) {
404                                cause.ti = 0;
405                                int offset = 10; // corresponding to cause.ip0
406                                offset += intCtl.ipti - 2;
407                                replaceBits(cause, offset, offset, 0);
408                            }
409                        }
410                        Cause = cause;
411                    }});
412                }
413                format CP0Unimpl {
414                    0x1: dmfc0();
415                    0x5: dmtc0();
416                    default: unknown();
417                }
418                format MT_MFTR {
419                    // Decode MIPS MT MFTR instruction into sub-instructions
420                    0x8: decode MT_U {
421                        0x0: mftc0({{
422                            data = xc->readRegOtherThread((RT << 3 | SEL) +
423                                                          Ctrl_Base_DepTag);
424                        }});
425                        0x1: decode SEL {
426                            0x0: mftgpr({{
427                                data = xc->readRegOtherThread(RT);
428                            }});
429                            0x1: decode RT {
430                                0x0: mftlo_dsp0({{ data = xc->readRegOtherThread(INTREG_DSP_LO0); }});
431                                0x1: mfthi_dsp0({{ data = xc->readRegOtherThread(INTREG_DSP_HI0); }});
432                                0x2: mftacx_dsp0({{ data = xc->readRegOtherThread(INTREG_DSP_ACX0); }});
433                                0x4: mftlo_dsp1({{ data = xc->readRegOtherThread(INTREG_DSP_LO1); }});
434                                0x5: mfthi_dsp1({{ data = xc->readRegOtherThread(INTREG_DSP_HI1); }});
435                                0x6: mftacx_dsp1({{ data = xc->readRegOtherThread(INTREG_DSP_ACX1); }});
436                                0x8: mftlo_dsp2({{ data = xc->readRegOtherThread(INTREG_DSP_LO2); }});
437                                0x9: mfthi_dsp2({{ data = xc->readRegOtherThread(INTREG_DSP_HI2); }});
438                                0x10: mftacx_dsp2({{ data = xc->readRegOtherThread(INTREG_DSP_ACX2); }});
439                                0x12: mftlo_dsp3({{ data = xc->readRegOtherThread(INTREG_DSP_LO3); }});
440                                0x13: mfthi_dsp3({{ data = xc->readRegOtherThread(INTREG_DSP_HI3); }});
441                                0x14: mftacx_dsp3({{ data = xc->readRegOtherThread(INTREG_DSP_ACX3); }});
442                                0x16: mftdsp({{ data = xc->readRegOtherThread(INTREG_DSP_CONTROL); }});
443                                default: CP0Unimpl::unknown();
444                            }
445                            0x2: decode MT_H {
446                                0x0: mftc1({{ data = xc->readRegOtherThread(RT +
447                                                                            FP_Base_DepTag);
448                                }});
449                                0x1: mfthc1({{ data = xc->readRegOtherThread(RT +
450                                                                             FP_Base_DepTag);
451                                }});
452                            }
453                            0x3: cftc1({{
454                                uint32_t fcsr_val = xc->readRegOtherThread(FLOATREG_FCSR +
455                                                                            FP_Base_DepTag);
456                                switch (RT) {
457                                  case 0:
458                                    data = xc->readRegOtherThread(FLOATREG_FIR +
459                                                                  Ctrl_Base_DepTag);
460                                    break;
461                                  case 25:
462                                    data = (fcsr_val & 0xFE000000 >> 24) |
463                                           (fcsr_val & 0x00800000 >> 23);
464                                    break;
465                                  case 26:
466                                    data = fcsr_val & 0x0003F07C;
467                                    break;
468                                  case 28:
469                                    data = (fcsr_val & 0x00000F80) |
470                                           (fcsr_val & 0x01000000 >> 21) |
471                                           (fcsr_val & 0x00000003);
472                                    break;
473                                  case 31:
474                                    data = fcsr_val;
475                                    break;
476                                  default:
477                                    fatal("FP Control Value (%d) Not Valid");
478                                }
479                            }});
480                            default: CP0Unimpl::unknown();
481                        }
482                    }
483                }
484
485                format MT_MTTR {
486                    // Decode MIPS MT MTTR instruction into sub-instructions
487                    0xC: decode MT_U {
488                        0x0: mttc0({{ xc->setRegOtherThread((RD << 3 | SEL) + Ctrl_Base_DepTag,
489                                                            Rt);
490                                   }});
491                        0x1: decode SEL {
492                            0x0: mttgpr({{ xc->setRegOtherThread(RD, Rt); }});
493                            0x1: decode RT {
494                                0x0: mttlo_dsp0({{ xc->setRegOtherThread(INTREG_DSP_LO0, Rt);
495                                                }});
496                                0x1: mtthi_dsp0({{ xc->setRegOtherThread(INTREG_DSP_HI0,
497                                                                         Rt);
498                                                }});
499                                0x2: mttacx_dsp0({{ xc->setRegOtherThread(INTREG_DSP_ACX0,
500                                                                          Rt);
501                                                 }});
502                                0x4: mttlo_dsp1({{ xc->setRegOtherThread(INTREG_DSP_LO1,
503                                                                         Rt);
504                                                }});
505                                0x5: mtthi_dsp1({{ xc->setRegOtherThread(INTREG_DSP_HI1,
506                                                                         Rt);
507                                                }});
508                                0x6: mttacx_dsp1({{ xc->setRegOtherThread(INTREG_DSP_ACX1,
509                                                                          Rt);
510                                                 }});
511                                0x8: mttlo_dsp2({{ xc->setRegOtherThread(INTREG_DSP_LO2,
512                                                                         Rt);
513                                                }});
514                                0x9: mtthi_dsp2({{ xc->setRegOtherThread(INTREG_DSP_HI2,
515                                                                         Rt);
516                                                }});
517                                0x10: mttacx_dsp2({{ xc->setRegOtherThread(INTREG_DSP_ACX2,
518                                                                           Rt);
519                                                  }});
520                                0x12: mttlo_dsp3({{ xc->setRegOtherThread(INTREG_DSP_LO3,
521                                                                          Rt);
522                                                 }});
523                                0x13: mtthi_dsp3({{ xc->setRegOtherThread(INTREG_DSP_HI3,
524                                                                          Rt);
525                                                 }});
526                                0x14: mttacx_dsp3({{ xc->setRegOtherThread(INTREG_DSP_ACX3, Rt);
527                                                  }});
528                                0x16: mttdsp({{ xc->setRegOtherThread(INTREG_DSP_CONTROL, Rt); }});
529                                default: CP0Unimpl::unknown();
530
531                            }
532                            0x2: mttc1({{
533                                uint64_t data = xc->readRegOtherThread(RD +
534                                                                       FP_Base_DepTag);
535                                data = insertBits(data, top_bit,
536                                                  bottom_bit, Rt);
537                                xc->setRegOtherThread(RD + FP_Base_DepTag,
538                                                      data);
539                            }});
540                            0x3: cttc1({{
541                                uint32_t data;
542                                switch (RD) {
543                                  case 25:
544                                    data = (Rt.uw<7:1> << 25) |  // move 31-25
545                                           (FCSR & 0x01000000) | // bit 24
546                                           (FCSR & 0x004FFFFF);  // bit 22-0
547                                    break;
548                                  case 26:
549                                    data = (FCSR & 0xFFFC0000) | // move 31-18
550                                           Rt.uw<17:12> << 12 |  // bit 17-12
551                                           (FCSR & 0x00000F80) << 7 | // bit 11-7
552                                           Rt.uw<6:2> << 2 |     // bit 6-2
553                                           (FCSR & 0x00000002);  // bit 1...0
554                                    break;
555                                  case 28:
556                                    data = (FCSR & 0xFE000000) | // move 31-25
557                                           Rt.uw<2:2> << 24 |    // bit 24
558                                           (FCSR & 0x00FFF000) << 23 | // bit 23-12
559                                           Rt.uw<11:7> << 7 |    // bit 24
560                                           (FCSR & 0x000007E) |
561                                           Rt.uw<1:0>;           // bit 22-0
562                                    break;
563                                  case 31:
564                                    data = Rt.uw;
565                                    break;
566                                  default:
567                                    panic("FP Control Value (%d) "
568                                            "Not Available. Ignoring "
569                                            "Access to Floating Control "
570                                            "Status Register", FS);
571                                }
572                                xc->setRegOtherThread(FLOATREG_FCSR + FP_Base_DepTag, data);
573                            }});
574                            default: CP0Unimpl::unknown();
575                        }
576                    }
577                }
578                0xB: decode RD {
579                    format MT_Control {
580                        0x0: decode POS {
581                            0x0: decode SEL {
582                                0x1: decode SC {
583                                    0x0: dvpe({{
584                                        MVPControlReg mvpControl = MVPControl;
585                                        VPEConf0Reg vpeConf0 = VPEConf0;
586                                        Rt = MVPControl;
587                                        if (vpeConf0.mvp == 1)
588                                            mvpControl.evp = 0;
589                                        MVPControl = mvpControl;
590                                    }});
591                                    0x1: evpe({{
592                                        MVPControlReg mvpControl = MVPControl;
593                                        VPEConf0Reg vpeConf0 = VPEConf0;
594                                        Rt = MVPControl;
595                                        if (vpeConf0.mvp == 1)
596                                            mvpControl.evp = 1;
597                                        MVPControl = mvpControl;
598                                    }});
599                                   default:CP0Unimpl::unknown();
600                                }
601                                default:CP0Unimpl::unknown();
602                            }
603                            default:CP0Unimpl::unknown();
604                        }
605                        0x1: decode POS {
606                            0xF: decode SEL {
607                                0x1: decode SC {
608                                    0x0: dmt({{
609                                        VPEControlReg vpeControl = VPEControl;
610                                        Rt = vpeControl;
611                                        vpeControl.te = 0;
612                                        VPEControl = vpeControl;
613                                    }});
614                                    0x1: emt({{
615                                        VPEControlReg vpeControl = VPEControl;
616                                        Rt = vpeControl;
617                                        vpeControl.te = 1;
618                                        VPEControl = vpeControl;
619                                    }});
620                                   default:CP0Unimpl::unknown();
621                                }
622                                default:CP0Unimpl::unknown();
623                            }
624                            default:CP0Unimpl::unknown();
625                        }
626                    }
627                    0xC: decode POS {
628                        0x0: decode SC {
629                            0x0: CP0Control::di({{
630                                StatusReg status = Status;
631                                ConfigReg config = Config;
632                                // Rev 2.0 or beyond?
633                                if (config.ar >= 1) {
634                                    Rt = status;
635                                    status.ie = 0;
636                                } else {
637                                    // Enable this else branch once we
638                                    // actually set values for Config on init
639                                    fault = new ReservedInstructionFault();
640                                }
641                                Status = status;
642                            }});
643                            0x1: CP0Control::ei({{
644                                StatusReg status = Status;
645                                ConfigReg config = Config;
646                                if (config.ar >= 1) {
647                                    Rt = status;
648                                    status.ie = 1;
649                                } else {
650                                    fault = new ReservedInstructionFault();
651                                }
652                            }});
653                            default:CP0Unimpl::unknown();
654                        }
655                    }
656                    default: CP0Unimpl::unknown();
657                }
658                format CP0Control {
659                    0xA: rdpgpr({{
660                        ConfigReg config = Config;
661                        if (config.ar >= 1) {
662                            // Rev 2 of the architecture
663                            panic("Shadow Sets Not Fully Implemented.\n");
664                        } else {
665                          fault = new ReservedInstructionFault();
666                        }
667                    }});
668                    0xE: wrpgpr({{
669                        ConfigReg config = Config;
670                        if (config.ar >= 1) {
671                            // Rev 2 of the architecture
672                            panic("Shadow Sets Not Fully Implemented.\n");
673                        } else {
674                            fault = new ReservedInstructionFault();
675                        }
676                    }});
677                }
678            }
679
680            //Table A-12 MIPS32 COP0 Encoding of Function Field When rs=CO
681            0x1: decode FUNCTION {
682                format CP0Control {
683                    0x18: eret({{
684                        StatusReg status = Status;
685                        ConfigReg config = Config;
686                        SRSCtlReg srsCtl = SRSCtl;
687                        DPRINTF(MipsPRA,"Restoring PC - %x\n",EPC);
688                        if (status.erl == 1) {
689                            status.erl = 0;
690                            NPC = ErrorEPC;
691                            // Need to adjust NNPC, otherwise things break
692                            NNPC = ErrorEPC + sizeof(MachInst);
693                        } else {
694                            NPC = EPC;
695                            // Need to adjust NNPC, otherwise things break
696                            NNPC = EPC + sizeof(MachInst);
697                            status.exl = 0;
698                            if (config.ar >=1 &&
699                                    srsCtl.hss > 0 &&
700                                    status.bev == 0) {
701                                srsCtl.css = srsCtl.pss;
702                                //xc->setShadowSet(srsCtl.pss);
703                            }
704                        }
705                        LLFlag = 0;
706                        Status = status;
707                        SRSCtl = srsCtl;
708                    }}, IsReturn, IsSerializing, IsERET);
709
710                    0x1F: deret({{
711                        DebugReg debug = Debug;
712                        if (debug.dm == 1) {
713                            debug.dm = 1;
714                            debug.iexi = 0;
715                            NPC = DEPC;
716                        } else {
717                            NPC = NPC;
718                            // Undefined;
719                        }
720                        Debug = debug;
721                    }}, IsReturn, IsSerializing, IsERET);
722                }
723                format CP0TLB {
724                    0x01: tlbr({{
725                        MipsISA::PTE *PTEntry =
726                            xc->tcBase()->getITBPtr()->
727                                getEntry(Index & 0x7FFFFFFF);
728                        if (PTEntry == NULL) {
729                            fatal("Invalid PTE Entry received on "
730                                "a TLBR instruction\n");
731                        }
732                        /* Setup PageMask */
733                        // If 1KB pages are not enabled, a read of PageMask
734                        // must return 0b00 in bits 12, 11
735                        PageMask = (PTEntry->Mask << 11);
736                        /* Setup EntryHi */
737                        EntryHi = ((PTEntry->VPN << 11) | (PTEntry->asid));
738                        /* Setup Entry Lo0 */
739                        EntryLo0 = ((PTEntry->PFN0 << 6) |
740                                    (PTEntry->C0 << 3) |
741                                    (PTEntry->D0 << 2) |
742                                    (PTEntry->V0 << 1) |
743                                    PTEntry->G);
744                        /* Setup Entry Lo1 */
745                        EntryLo1 = ((PTEntry->PFN1 << 6) |
746                                    (PTEntry->C1 << 3) |
747                                    (PTEntry->D1 << 2) |
748                                    (PTEntry->V1 << 1) |
749                                    PTEntry->G);
750                    }}); // Need to hook up to TLB
751
752                    0x02: tlbwi({{
753                        //Create PTE
754                        MipsISA::PTE newEntry;
755                        //Write PTE
756                        newEntry.Mask = (Addr)(PageMask >> 11);
757                        newEntry.VPN = (Addr)(EntryHi >> 11);
758                        /*  PageGrain _ ESP                    Config3 _ SP */
759                        if (bits(PageGrain, 28) == 0 || bits(Config3, 4) ==0) {
760                            // If 1KB pages are *NOT* enabled, lowest bits of
761                            // the mask are 0b11 for TLB writes
762                            newEntry.Mask |= 0x3;
763                            // Reset bits 0 and 1 if 1KB pages are not enabled
764                            newEntry.VPN &= 0xFFFFFFFC;
765                        }
766                        newEntry.asid = (uint8_t)(EntryHi & 0xFF);
767
768                        newEntry.PFN0 = (Addr)(EntryLo0 >> 6);
769                        newEntry.PFN1 = (Addr)(EntryLo1 >> 6);
770                        newEntry.D0 = (bool)((EntryLo0 >> 2) & 1);
771                        newEntry.D1 = (bool)((EntryLo1 >> 2) & 1);
772                        newEntry.V1 = (bool)((EntryLo1 >> 1) & 1);
773                        newEntry.V0 = (bool)((EntryLo0 >> 1) & 1);
774                        newEntry.G = (bool)((EntryLo0 & EntryLo1) & 1);
775                        newEntry.C0 = (uint8_t)((EntryLo0 >> 3) & 0x7);
776                        newEntry.C1 = (uint8_t)((EntryLo1 >> 3) & 0x7);
777                        /* Now, compute the AddrShiftAmount and OffsetMask -
778                           TLB optimizations */
779                        /* Addr Shift Amount for 1KB or larger pages */
780                        if ((newEntry.Mask & 0xFFFF) == 3) {
781                            newEntry.AddrShiftAmount = 12;
782                        } else if ((newEntry.Mask & 0xFFFF) == 0x0000) {
783                            newEntry.AddrShiftAmount = 10;
784                        } else if ((newEntry.Mask & 0xFFFC) == 0x000C) {
785                            newEntry.AddrShiftAmount = 14;
786                        } else if ((newEntry.Mask & 0xFFF0) == 0x0030) {
787                            newEntry.AddrShiftAmount = 16;
788                        } else if ((newEntry.Mask & 0xFFC0) == 0x00C0) {
789                            newEntry.AddrShiftAmount = 18;
790                        } else if ((newEntry.Mask & 0xFF00) == 0x0300) {
791                            newEntry.AddrShiftAmount = 20;
792                        } else if ((newEntry.Mask & 0xFC00) == 0x0C00) {
793                            newEntry.AddrShiftAmount = 22;
794                        } else if ((newEntry.Mask & 0xF000) == 0x3000) {
795                            newEntry.AddrShiftAmount = 24;
796                        } else if ((newEntry.Mask & 0xC000) == 0xC000) {
797                            newEntry.AddrShiftAmount = 26;
798                        } else if ((newEntry.Mask & 0x30000) == 0x30000) {
799                            newEntry.AddrShiftAmount = 28;
800                        } else {
801                            fatal("Invalid Mask Pattern Detected!\n");
802                        }
803                        newEntry.OffsetMask =
804                            (1 << newEntry.AddrShiftAmount) - 1;
805
806                        MipsISA::TLB *Ptr = xc->tcBase()->getITBPtr();
807                        Config3Reg config3 = Config3;
808                        PageGrainReg pageGrain = PageGrain;
809                        int SP = 0;
810                        if (bits(config3, config3.sp) == 1 &&
811                            bits(pageGrain, pageGrain.esp) == 1) {
812                            SP = 1;
813                        }
814                        IndexReg index = Index;
815                        Ptr->insertAt(newEntry, Index & 0x7FFFFFFF, SP);
816                    }});
817                    0x06: tlbwr({{
818                        //Create PTE
819                        MipsISA::PTE newEntry;
820                        //Write PTE
821                        newEntry.Mask = (Addr)(PageMask >> 11);
822                        newEntry.VPN = (Addr)(EntryHi >> 11);
823                        /*  PageGrain _ ESP                    Config3 _ SP */
824                        if (bits(PageGrain, 28) == 0 ||
825                            bits(Config3, 4) == 0) {
826                            // If 1KB pages are *NOT* enabled, lowest bits of
827                            // the mask are 0b11 for TLB writes
828                            newEntry.Mask |= 0x3;
829                            // Reset bits 0 and 1 if 1KB pages are not enabled
830                            newEntry.VPN &= 0xFFFFFFFC;
831                        }
832                        newEntry.asid = (uint8_t)(EntryHi & 0xFF);
833
834                        newEntry.PFN0 = (Addr)(EntryLo0 >> 6);
835                        newEntry.PFN1 = (Addr)(EntryLo1 >> 6);
836                        newEntry.D0 = (bool)((EntryLo0 >> 2) & 1);
837                        newEntry.D1 = (bool)((EntryLo1 >> 2) & 1);
838                        newEntry.V1 = (bool)((EntryLo1 >> 1) & 1);
839                        newEntry.V0 = (bool)((EntryLo0 >> 1) & 1);
840                        newEntry.G = (bool)((EntryLo0 & EntryLo1) & 1);
841                        newEntry.C0 = (uint8_t)((EntryLo0 >> 3) & 0x7);
842                        newEntry.C1 = (uint8_t)((EntryLo1 >> 3) & 0x7);
843                        /* Now, compute the AddrShiftAmount and OffsetMask -
844                           TLB optimizations */
845                        /* Addr Shift Amount for 1KB or larger pages */
846                        if ((newEntry.Mask & 0xFFFF) == 3){
847                            newEntry.AddrShiftAmount = 12;
848                        } else if ((newEntry.Mask & 0xFFFF) == 0x0000) {
849                            newEntry.AddrShiftAmount = 10;
850                        } else if ((newEntry.Mask & 0xFFFC) == 0x000C) {
851                            newEntry.AddrShiftAmount = 14;
852                        } else if ((newEntry.Mask & 0xFFF0) == 0x0030) {
853                            newEntry.AddrShiftAmount = 16;
854                        } else if ((newEntry.Mask & 0xFFC0) == 0x00C0) {
855                            newEntry.AddrShiftAmount = 18;
856                        } else if ((newEntry.Mask & 0xFF00) == 0x0300) {
857                            newEntry.AddrShiftAmount = 20;
858                        } else if ((newEntry.Mask & 0xFC00) == 0x0C00) {
859                            newEntry.AddrShiftAmount = 22;
860                        } else if ((newEntry.Mask & 0xF000) == 0x3000) {
861                            newEntry.AddrShiftAmount = 24;
862                        } else if ((newEntry.Mask & 0xC000) == 0xC000) {
863                            newEntry.AddrShiftAmount = 26;
864                        } else if ((newEntry.Mask & 0x30000) == 0x30000) {
865                            newEntry.AddrShiftAmount = 28;
866                        } else {
867                            fatal("Invalid Mask Pattern Detected!\n");
868                        }
869                        newEntry.OffsetMask =
870                            (1 << newEntry.AddrShiftAmount) - 1;
871
872                        MipsISA::TLB *Ptr = xc->tcBase()->getITBPtr();
873                        Config3Reg config3 = Config3;
874                        PageGrainReg pageGrain = PageGrain;
875                        int SP = 0;
876                        if (bits(config3, config3.sp) == 1 &&
877                            bits(pageGrain, pageGrain.esp) == 1) {
878                            SP = 1;
879                        }
880                        IndexReg index = Index;
881                        Ptr->insertAt(newEntry, Random, SP);
882                    }});
883
884                    0x08: tlbp({{
885                        Config3Reg config3 = Config3;
886                        PageGrainReg pageGrain = PageGrain;
887                        EntryHiReg entryHi = EntryHi;
888                        int tlbIndex;
889                        Addr vpn;
890                        if (pageGrain.esp == 1 && config3.sp ==1) {
891                            vpn = EntryHi >> 11;
892                        } else {
893                            // Mask off lower 2 bits
894                            vpn = ((EntryHi >> 11) & 0xFFFFFFFC);
895                        }
896                        tlbIndex = xc->tcBase()->getITBPtr()->
897                                   probeEntry(vpn, entryHi.asid);
898                        // Check TLB for entry matching EntryHi
899                        if (tlbIndex != -1) {
900                            Index = tlbIndex;
901                        } else {
902                            // else, set Index = 1 << 31
903                            Index = (1 << 31);
904                        }
905                    }});
906                }
907                format CP0Unimpl {
908                    0x20: wait();
909                }
910                default: CP0Unimpl::unknown();
911            }
912        }
913
914        //Table A-13 MIPS32 COP1 Encoding of rs Field
915        0x1: decode RS_MSB {
916            0x0: decode RS_HI {
917                0x0: decode RS_LO {
918                    format CP1Control {
919                        0x0: mfc1 ({{ Rt.uw = Fs.uw; }});
920
921                        0x2: cfc1({{
922                            switch (FS) {
923                              case 0:
924                                Rt = FIR;
925                                break;
926                              case 25:
927                                Rt = (FCSR & 0xFE000000) >> 24 |
928                                     (FCSR & 0x00800000) >> 23;
929                                break;
930                              case 26:
931                                Rt = (FCSR & 0x0003F07C);
932                                break;
933                              case 28:
934                                Rt = (FCSR & 0x00000F80) |
935                                     (FCSR & 0x01000000) >> 21 |
936                                     (FCSR & 0x00000003);
937                                break;
938                              case 31:
939                                Rt = FCSR;
940                                break;
941                              default:
942                                warn("FP Control Value (%d) Not Valid");
943                            }
944                        }});
945
946                        0x3: mfhc1({{ Rt.uw = Fs.ud<63:32>; }});
947
948                        0x4: mtc1({{ Fs.uw = Rt.uw; }});
949
950                        0x6: ctc1({{
951                            switch (FS) {
952                              case 25:
953                                FCSR = (Rt.uw<7:1> << 25) |  // move 31-25
954                                       (FCSR & 0x01000000) | // bit 24
955                                       (FCSR & 0x004FFFFF);  // bit 22-0
956                                break;
957                              case 26:
958                                FCSR = (FCSR & 0xFFFC0000) | // move 31-18
959                                       Rt.uw<17:12> << 12 |  // bit 17-12
960                                       (FCSR & 0x00000F80) << 7 | // bit 11-7
961                                       Rt.uw<6:2> << 2 |     // bit 6-2
962                                       (FCSR & 0x00000002);  // bit 1-0
963                                break;
964                              case 28:
965                                FCSR = (FCSR & 0xFE000000) | // move 31-25
966                                       Rt.uw<2:2> << 24 |    // bit 24
967                                       (FCSR & 0x00FFF000) << 23 | // bit 23-12
968                                       Rt.uw<11:7> << 7 |    // bit 24
969                                       (FCSR & 0x000007E) |
970                                       Rt.uw<1:0>;           // bit 22-0
971                                break;
972                              case 31:
973                                FCSR = Rt.uw;
974                                break;
975
976                              default:
977                                panic("FP Control Value (%d) "
978                                        "Not Available. Ignoring Access "
979                                        "to Floating Control Status "
980                                        "Register", FS);
981                            }
982                        }});
983
984                        0x7: mthc1({{
985                             uint64_t fs_hi = Rt.uw;
986                             uint64_t fs_lo = Fs.ud & 0x0FFFFFFFF;
987                             Fs.ud = (fs_hi << 32) | fs_lo;
988                        }});
989
990                    }
991                    format CP1Unimpl {
992                      0x1: dmfc1();
993                      0x5: dmtc1();
994                    }
995                }
996
997                0x1: decode RS_LO {
998                    0x0: decode ND {
999                        format Branch {
1000                            0x0: decode TF {
1001                                0x0: bc1f({{
1002                                    cond = getCondCode(FCSR, BRANCH_CC) == 0;
1003                                }});
1004                                0x1: bc1t({{
1005                                    cond = getCondCode(FCSR, BRANCH_CC) == 1;
1006                                }});
1007                            }
1008                            0x1: decode TF {
1009                                0x0: bc1fl({{
1010                                    cond = getCondCode(FCSR, BRANCH_CC) == 0;
1011                                }}, Likely);
1012                                0x1: bc1tl({{
1013                                    cond = getCondCode(FCSR, BRANCH_CC) == 1;
1014                                }}, Likely);
1015                            }
1016                        }
1017                    }
1018                    format CP1Unimpl {
1019                        0x1: bc1any2();
1020                        0x2: bc1any4();
1021                        default: unknown();
1022                    }
1023                }
1024            }
1025
1026            0x1: decode RS_HI {
1027                0x2: decode RS_LO {
1028                    //Table A-14 MIPS32 COP1 Encoding of Function Field When
1029                    //rs=S (( single-precision floating point))
1030                    0x0: decode FUNCTION_HI {
1031                        0x0: decode FUNCTION_LO {
1032                            format FloatOp {
1033                                0x0: add_s({{ Fd.sf = Fs.sf + Ft.sf; }});
1034                                0x1: sub_s({{ Fd.sf = Fs.sf - Ft.sf; }});
1035                                0x2: mul_s({{ Fd.sf = Fs.sf * Ft.sf; }});
1036                                0x3: div_s({{ Fd.sf = Fs.sf / Ft.sf; }});
1037                                0x4: sqrt_s({{ Fd.sf = sqrt(Fs.sf); }});
1038                                0x5: abs_s({{ Fd.sf = fabs(Fs.sf); }});
1039                                0x7: neg_s({{ Fd.sf = -Fs.sf; }});
1040                            }
1041                            0x6: BasicOp::mov_s({{ Fd.sf = Fs.sf; }});
1042                        }
1043                        0x1: decode FUNCTION_LO {
1044                            format FloatConvertOp {
1045                                0x0: round_l_s({{ val = Fs.sf; }},
1046                                               ToLong, Round);
1047                                0x1: trunc_l_s({{ val = Fs.sf; }},
1048                                               ToLong, Trunc);
1049                                0x2: ceil_l_s({{ val = Fs.sf;}},
1050                                              ToLong, Ceil);
1051                                0x3: floor_l_s({{ val = Fs.sf; }},
1052                                               ToLong, Floor);
1053                                0x4: round_w_s({{ val = Fs.sf; }},
1054                                               ToWord, Round);
1055                                0x5: trunc_w_s({{ val = Fs.sf; }},
1056                                               ToWord, Trunc);
1057                                0x6: ceil_w_s({{ val = Fs.sf; }},
1058                                              ToWord, Ceil);
1059                                0x7: floor_w_s({{ val = Fs.sf; }},
1060                                               ToWord, Floor);
1061                            }
1062                        }
1063
1064                        0x2: decode FUNCTION_LO {
1065                            0x1: decode MOVCF {
1066                                format BasicOp {
1067                                    0x0: movf_s({{
1068                                        Fd = (getCondCode(FCSR,CC) == 0) ?
1069                                             Fs : Fd;
1070                                    }});
1071                                    0x1: movt_s({{
1072                                        Fd = (getCondCode(FCSR,CC) == 1) ?
1073                                             Fs : Fd;
1074                                    }});
1075                                }
1076                            }
1077
1078                            format BasicOp {
1079                                0x2: movz_s({{ Fd = (Rt == 0) ? Fs : Fd; }});
1080                                0x3: movn_s({{ Fd = (Rt != 0) ? Fs : Fd; }});
1081                            }
1082
1083                            format FloatOp {
1084                                0x5: recip_s({{ Fd = 1 / Fs; }});
1085                                0x6: rsqrt_s({{ Fd = 1 / sqrt(Fs); }});
1086                            }
1087                            format CP1Unimpl {
1088                                default: unknown();
1089                            }
1090                        }
1091                        0x3: CP1Unimpl::unknown();
1092
1093                        0x4: decode FUNCTION_LO {
1094                            format FloatConvertOp {
1095                                0x1: cvt_d_s({{ val = Fs.sf; }}, ToDouble);
1096                                0x4: cvt_w_s({{ val = Fs.sf; }}, ToWord);
1097                                0x5: cvt_l_s({{ val = Fs.sf; }}, ToLong);
1098                            }
1099
1100                            0x6: FloatOp::cvt_ps_s({{
1101                                Fd.ud = (uint64_t) Fs.uw << 32 |
1102                                        (uint64_t) Ft.uw;
1103                            }});
1104                            format CP1Unimpl {
1105                                default: unknown();
1106                            }
1107                        }
1108                        0x5: CP1Unimpl::unknown();
1109
1110                        0x6: decode FUNCTION_LO {
1111                            format FloatCompareOp {
1112                                0x0: c_f_s({{ cond = 0; }},
1113                                           SinglePrecision, UnorderedFalse);
1114                                0x1: c_un_s({{ cond = 0; }},
1115                                            SinglePrecision, UnorderedTrue);
1116                                0x2: c_eq_s({{ cond = (Fs.sf == Ft.sf); }},
1117                                            UnorderedFalse);
1118                                0x3: c_ueq_s({{ cond = (Fs.sf == Ft.sf); }},
1119                                             UnorderedTrue);
1120                                0x4: c_olt_s({{ cond = (Fs.sf < Ft.sf); }},
1121                                             UnorderedFalse);
1122                                0x5: c_ult_s({{ cond = (Fs.sf < Ft.sf); }},
1123                                             UnorderedTrue);
1124                                0x6: c_ole_s({{ cond = (Fs.sf <= Ft.sf); }},
1125                                             UnorderedFalse);
1126                                0x7: c_ule_s({{ cond = (Fs.sf <= Ft.sf); }},
1127                                             UnorderedTrue);
1128                            }
1129                        }
1130
1131                        0x7: decode FUNCTION_LO {
1132                            format FloatCompareOp {
1133                                0x0: c_sf_s({{ cond = 0; }}, SinglePrecision,
1134                                            UnorderedFalse, QnanException);
1135                                0x1: c_ngle_s({{ cond = 0; }}, SinglePrecision,
1136                                              UnorderedTrue, QnanException);
1137                                0x2: c_seq_s({{ cond = (Fs.sf == Ft.sf); }},
1138                                             UnorderedFalse, QnanException);
1139                                0x3: c_ngl_s({{ cond = (Fs.sf == Ft.sf); }},
1140                                             UnorderedTrue, QnanException);
1141                                0x4: c_lt_s({{ cond = (Fs.sf < Ft.sf); }},
1142                                            UnorderedFalse, QnanException);
1143                                0x5: c_nge_s({{ cond = (Fs.sf < Ft.sf); }},
1144                                             UnorderedTrue, QnanException);
1145                                0x6: c_le_s({{ cond = (Fs.sf <= Ft.sf); }},
1146                                            UnorderedFalse, QnanException);
1147                                0x7: c_ngt_s({{ cond = (Fs.sf <= Ft.sf); }},
1148                                             UnorderedTrue, QnanException);
1149                            }
1150                        }
1151                    }
1152
1153                    //Table A-15 MIPS32 COP1 Encoding of Function Field When
1154                    //rs=D
1155                    0x1: decode FUNCTION_HI {
1156                        0x0: decode FUNCTION_LO {
1157                            format FloatOp {
1158                                0x0: add_d({{ Fd.df = Fs.df + Ft.df; }});
1159                                0x1: sub_d({{ Fd.df = Fs.df - Ft.df; }});
1160                                0x2: mul_d({{ Fd.df = Fs.df * Ft.df; }});
1161                                0x3: div_d({{ Fd.df = Fs.df / Ft.df; }});
1162                                0x4: sqrt_d({{ Fd.df = sqrt(Fs.df); }});
1163                                0x5: abs_d({{ Fd.df = fabs(Fs.df); }});
1164                                0x7: neg_d({{ Fd.df = -1 * Fs.df; }});
1165                            }
1166                            0x6: BasicOp::mov_d({{ Fd.df = Fs.df; }});
1167                        }
1168
1169                        0x1: decode FUNCTION_LO {
1170                            format FloatConvertOp {
1171                                0x0: round_l_d({{ val = Fs.df; }},
1172                                               ToLong, Round);
1173                                0x1: trunc_l_d({{ val = Fs.df; }},
1174                                               ToLong, Trunc);
1175                                0x2: ceil_l_d({{ val = Fs.df; }},
1176                                              ToLong, Ceil);
1177                                0x3: floor_l_d({{ val = Fs.df; }},
1178                                               ToLong, Floor);
1179                                0x4: round_w_d({{ val = Fs.df; }},
1180                                               ToWord, Round);
1181                                0x5: trunc_w_d({{ val = Fs.df; }},
1182                                               ToWord, Trunc);
1183                                0x6: ceil_w_d({{ val = Fs.df; }},
1184                                              ToWord, Ceil);
1185                                0x7: floor_w_d({{ val = Fs.df; }},
1186                                               ToWord, Floor);
1187                            }
1188                        }
1189
1190                        0x2: decode FUNCTION_LO {
1191                            0x1: decode MOVCF {
1192                                format BasicOp {
1193                                    0x0: movf_d({{
1194                                        Fd.df = (getCondCode(FCSR,CC) == 0) ?
1195                                                       Fs.df : Fd.df;
1196                                    }});
1197                                    0x1: movt_d({{
1198                                        Fd.df = (getCondCode(FCSR,CC) == 1) ?
1199                                                       Fs.df : Fd.df;
1200                                    }});
1201                                }
1202                            }
1203
1204                            format BasicOp {
1205                                0x2: movz_d({{
1206                                    Fd.df = (Rt == 0) ? Fs.df : Fd.df;
1207                                }});
1208                                0x3: movn_d({{
1209                                    Fd.df = (Rt != 0) ? Fs.df : Fd.df;
1210                                }});
1211                            }
1212
1213                            format FloatOp {
1214                                0x5: recip_d({{ Fd.df = 1 / Fs.df; }});
1215                                0x6: rsqrt_d({{ Fd.df = 1 / sqrt(Fs.df); }});
1216                            }
1217                            format CP1Unimpl {
1218                                default: unknown();
1219                            }
1220
1221                        }
1222                        0x4: decode FUNCTION_LO {
1223                            format FloatConvertOp {
1224                                0x0: cvt_s_d({{ val = Fs.df; }}, ToSingle);
1225                                0x4: cvt_w_d({{ val = Fs.df; }}, ToWord);
1226                                0x5: cvt_l_d({{ val = Fs.df; }}, ToLong);
1227                            }
1228                            default: CP1Unimpl::unknown();
1229                        }
1230
1231                        0x6: decode FUNCTION_LO {
1232                            format FloatCompareOp {
1233                                0x0: c_f_d({{ cond = 0; }},
1234                                           DoublePrecision, UnorderedFalse);
1235                                0x1: c_un_d({{ cond = 0; }},
1236                                            DoublePrecision, UnorderedTrue);
1237                                0x2: c_eq_d({{ cond = (Fs.df == Ft.df); }},
1238                                            UnorderedFalse);
1239                                0x3: c_ueq_d({{ cond = (Fs.df == Ft.df); }},
1240                                             UnorderedTrue);
1241                                0x4: c_olt_d({{ cond = (Fs.df < Ft.df); }},
1242                                             UnorderedFalse);
1243                                0x5: c_ult_d({{ cond = (Fs.df < Ft.df); }},
1244                                             UnorderedTrue);
1245                                0x6: c_ole_d({{ cond = (Fs.df <= Ft.df); }},
1246                                             UnorderedFalse);
1247                                0x7: c_ule_d({{ cond = (Fs.df <= Ft.df); }},
1248                                             UnorderedTrue);
1249                            }
1250                        }
1251
1252                        0x7: decode FUNCTION_LO {
1253                            format FloatCompareOp {
1254                                0x0: c_sf_d({{ cond = 0; }}, DoublePrecision,
1255                                            UnorderedFalse, QnanException);
1256                                0x1: c_ngle_d({{ cond = 0; }}, DoublePrecision,
1257                                              UnorderedTrue, QnanException);
1258                                0x2: c_seq_d({{ cond = (Fs.df == Ft.df); }},
1259                                             UnorderedFalse, QnanException);
1260                                0x3: c_ngl_d({{ cond = (Fs.df == Ft.df); }},
1261                                             UnorderedTrue, QnanException);
1262                                0x4: c_lt_d({{ cond = (Fs.df < Ft.df); }},
1263                                            UnorderedFalse, QnanException);
1264                                0x5: c_nge_d({{ cond = (Fs.df < Ft.df); }},
1265                                             UnorderedTrue, QnanException);
1266                                0x6: c_le_d({{ cond = (Fs.df <= Ft.df); }},
1267                                            UnorderedFalse, QnanException);
1268                                0x7: c_ngt_d({{ cond = (Fs.df <= Ft.df); }},
1269                                             UnorderedTrue, QnanException);
1270                            }
1271                        }
1272                        default: CP1Unimpl::unknown();
1273                    }
1274                    0x2: CP1Unimpl::unknown();
1275                    0x3: CP1Unimpl::unknown();
1276                    0x7: CP1Unimpl::unknown();
1277
1278                    //Table A-16 MIPS32 COP1 Encoding of Function 
1279                    //Field When rs=W
1280                    0x4: decode FUNCTION {
1281                        format FloatConvertOp {
1282                            0x20: cvt_s_w({{ val = Fs.uw; }}, ToSingle);
1283                            0x21: cvt_d_w({{ val = Fs.uw; }}, ToDouble);
1284                            0x26: CP1Unimpl::cvt_ps_w();
1285                        }
1286                        default: CP1Unimpl::unknown();
1287                    }
1288
1289                    //Table A-16 MIPS32 COP1 Encoding of Function Field
1290                    //When rs=L1
1291                    //Note: "1. Format type L is legal only if 64-bit
1292                    //floating point operations are enabled."
1293                    0x5: decode FUNCTION_HI {
1294                        format FloatConvertOp {
1295                            0x20: cvt_s_l({{ val = Fs.ud; }}, ToSingle);
1296                            0x21: cvt_d_l({{ val = Fs.ud; }}, ToDouble);
1297                            0x26: CP1Unimpl::cvt_ps_l();
1298                        }
1299                        default: CP1Unimpl::unknown();
1300                    }
1301
1302                    //Table A-17 MIPS64 COP1 Encoding of Function Field
1303                    //When rs=PS1
1304                    //Note: "1. Format type PS is legal only if 64-bit
1305                    //floating point operations are enabled. "
1306                    0x6: decode FUNCTION_HI {
1307                        0x0: decode FUNCTION_LO {
1308                            format Float64Op {
1309                                0x0: add_ps({{
1310                                    Fd1.sf = Fs1.sf + Ft2.sf;
1311                                    Fd2.sf = Fs2.sf + Ft2.sf;
1312                                }});
1313                                0x1: sub_ps({{
1314                                    Fd1.sf = Fs1.sf - Ft2.sf;
1315                                    Fd2.sf = Fs2.sf - Ft2.sf;
1316                                }});
1317                                0x2: mul_ps({{
1318                                    Fd1.sf = Fs1.sf * Ft2.sf;
1319                                    Fd2.sf = Fs2.sf * Ft2.sf;
1320                                }});
1321                                0x5: abs_ps({{
1322                                    Fd1.sf = fabs(Fs1.sf);
1323                                    Fd2.sf = fabs(Fs2.sf);
1324                                }});
1325                                0x6: mov_ps({{
1326                                    Fd1.sf = Fs1.sf;
1327                                    Fd2.sf = Fs2.sf;
1328                                }});
1329                                0x7: neg_ps({{
1330                                    Fd1.sf = -(Fs1.sf);
1331                                    Fd2.sf = -(Fs2.sf);
1332                                }});
1333                                default: CP1Unimpl::unknown();
1334                            }
1335                        }
1336                        0x1: CP1Unimpl::unknown();
1337                        0x2: decode FUNCTION_LO {
1338                            0x1: decode MOVCF {
1339                                format Float64Op {
1340                                    0x0: movf_ps({{
1341                                        Fd1 = (getCondCode(FCSR, CC) == 0) ?
1342                                            Fs1 : Fd1;
1343                                        Fd2 = (getCondCode(FCSR, CC+1) == 0) ?
1344                                            Fs2 : Fd2;
1345                                    }});
1346                                    0x1: movt_ps({{
1347                                        Fd2 = (getCondCode(FCSR, CC) == 1) ?
1348                                            Fs1 : Fd1;
1349                                        Fd2 = (getCondCode(FCSR, CC+1) == 1) ?
1350                                            Fs2 : Fd2;
1351                                    }});
1352                                }
1353                            }
1354
1355                            format Float64Op {
1356                                0x2: movz_ps({{
1357                                    Fd1 = (getCondCode(FCSR, CC) == 0) ?
1358                                        Fs1 : Fd1;
1359                                    Fd2 = (getCondCode(FCSR, CC) == 0) ?
1360                                        Fs2 : Fd2;
1361                                }});
1362                                0x3: movn_ps({{
1363                                    Fd1 = (getCondCode(FCSR, CC) == 1) ?
1364                                        Fs1 : Fd1;
1365                                    Fd2 = (getCondCode(FCSR, CC) == 1) ?
1366                                        Fs2 : Fd2;
1367                                }});
1368                            }
1369                            default: CP1Unimpl::unknown();
1370                        }
1371                        0x3: CP1Unimpl::unknown();
1372                        0x4: decode FUNCTION_LO {
1373                            0x0: FloatOp::cvt_s_pu({{ Fd.sf = Fs2.sf; }});
1374                            default: CP1Unimpl::unknown();
1375                        }
1376
1377                        0x5: decode FUNCTION_LO {
1378                            0x0: FloatOp::cvt_s_pl({{ Fd.sf = Fs1.sf; }});
1379                            format Float64Op {
1380                                0x4: pll({{
1381                                    Fd.ud = (uint64_t)Fs1.uw << 32 | Ft1.uw;
1382                                }});
1383                                0x5: plu({{
1384                                    Fd.ud = (uint64_t)Fs1.uw << 32 | Ft2.uw;
1385                                }});
1386                                0x6: pul({{
1387                                    Fd.ud = (uint64_t)Fs2.uw << 32 | Ft1.uw;
1388                                }});
1389                                0x7: puu({{
1390                                    Fd.ud = (uint64_t)Fs2.uw << 32 | Ft2.uw;
1391                                }});
1392                            }
1393                            default: CP1Unimpl::unknown();
1394                        }
1395
1396                        0x6: decode FUNCTION_LO {
1397                            format FloatPSCompareOp {
1398                                0x0: c_f_ps({{ cond1 = 0; }}, {{ cond2 = 0; }},
1399                                            UnorderedFalse);
1400                                0x1: c_un_ps({{ cond1 = 0; }}, {{ cond2 = 0; }},
1401                                             UnorderedTrue);
1402                                0x2: c_eq_ps({{ cond1 = (Fs1.sf == Ft1.sf); }},
1403                                             {{ cond2 = (Fs2.sf == Ft2.sf); }},
1404                                             UnorderedFalse);
1405                                0x3: c_ueq_ps({{ cond1 = (Fs1.sf == Ft1.sf); }},
1406                                              {{ cond2 = (Fs2.sf == Ft2.sf); }},
1407                                              UnorderedTrue);
1408                                0x4: c_olt_ps({{ cond1 = (Fs1.sf < Ft1.sf); }},
1409                                              {{ cond2 = (Fs2.sf < Ft2.sf); }},
1410                                              UnorderedFalse);
1411                                0x5: c_ult_ps({{ cond1 = (Fs.sf < Ft.sf); }},
1412                                              {{ cond2 = (Fs2.sf < Ft2.sf); }},
1413                                              UnorderedTrue);
1414                                0x6: c_ole_ps({{ cond1 = (Fs.sf <= Ft.sf); }},
1415                                              {{ cond2 = (Fs2.sf <= Ft2.sf); }},
1416                                              UnorderedFalse);
1417                                0x7: c_ule_ps({{ cond1 = (Fs1.sf <= Ft1.sf); }},
1418                                              {{ cond2 = (Fs2.sf <= Ft2.sf); }},
1419                                              UnorderedTrue);
1420                            }
1421                        }
1422
1423                        0x7: decode FUNCTION_LO {
1424                            format FloatPSCompareOp {
1425                                0x0: c_sf_ps({{ cond1 = 0; }}, {{ cond2 = 0; }},
1426                                             UnorderedFalse, QnanException);
1427                                0x1: c_ngle_ps({{ cond1 = 0; }},
1428                                               {{ cond2 = 0; }},
1429                                               UnorderedTrue, QnanException);
1430                                0x2: c_seq_ps({{ cond1 = (Fs1.sf == Ft1.sf); }},
1431                                              {{ cond2 = (Fs2.sf == Ft2.sf); }},
1432                                              UnorderedFalse, QnanException);
1433                                0x3: c_ngl_ps({{ cond1 = (Fs1.sf == Ft1.sf); }},
1434                                              {{ cond2 = (Fs2.sf == Ft2.sf); }},
1435                                              UnorderedTrue, QnanException);
1436                                0x4: c_lt_ps({{ cond1 = (Fs1.sf < Ft1.sf); }},
1437                                             {{ cond2 = (Fs2.sf < Ft2.sf); }},
1438                                             UnorderedFalse, QnanException);
1439                                0x5: c_nge_ps({{ cond1 = (Fs1.sf < Ft1.sf); }},
1440                                              {{ cond2 = (Fs2.sf < Ft2.sf); }},
1441                                              UnorderedTrue, QnanException);
1442                                0x6: c_le_ps({{ cond1 = (Fs1.sf <= Ft1.sf); }},
1443                                             {{ cond2 = (Fs2.sf <= Ft2.sf); }},
1444                                             UnorderedFalse, QnanException);
1445                                0x7: c_ngt_ps({{ cond1 = (Fs1.sf <= Ft1.sf); }},
1446                                              {{ cond2 = (Fs2.sf <= Ft2.sf); }},
1447                                              UnorderedTrue, QnanException);
1448                            }
1449                        }
1450                    }
1451                }
1452                default: CP1Unimpl::unknown();
1453            }
1454        }
1455
1456        //Table A-19 MIPS32 COP2 Encoding of rs Field
1457        0x2: decode RS_MSB {
1458            format CP2Unimpl {
1459                0x0: decode RS_HI {
1460                    0x0: decode RS_LO {
1461                        0x0: mfc2();
1462                        0x2: cfc2();
1463                        0x3: mfhc2();
1464                        0x4: mtc2();
1465                        0x6: ctc2();
1466                        0x7: mftc2();
1467                        default: unknown();
1468                    }
1469
1470                    0x1: decode ND {
1471                        0x0: decode TF {
1472                            0x0: bc2f();
1473                            0x1: bc2t();
1474                            default: unknown();
1475                        }
1476
1477                        0x1: decode TF {
1478                            0x0: bc2fl();
1479                            0x1: bc2tl();
1480                            default: unknown();
1481                        }
1482                        default: unknown();
1483
1484                    }
1485                    default: unknown();
1486                }
1487                default: unknown();
1488            }
1489        }
1490
1491        //Table A-20 MIPS64 COP1X Encoding of Function Field 1
1492        //Note: "COP1X instructions are legal only if 64-bit floating point
1493        //operations are enabled."
1494        0x3: decode FUNCTION_HI {
1495            0x0: decode FUNCTION_LO {
1496                format LoadIndexedMemory {
1497                    0x0: lwxc1({{ Fd.uw = Mem.uw; }});
1498                    0x1: ldxc1({{ Fd.ud = Mem.ud; }});
1499                    0x5: luxc1({{ Fd.ud = Mem.ud; }},
1500                               {{ EA = (Rs + Rt) & ~7; }});
1501                }
1502            }
1503
1504            0x1: decode FUNCTION_LO {
1505                format StoreIndexedMemory {
1506                    0x0: swxc1({{ Mem.uw = Fs.uw; }});
1507                    0x1: sdxc1({{ Mem.ud = Fs.ud; }});
1508                    0x5: suxc1({{ Mem.ud = Fs.ud; }},
1509                               {{ EA = (Rs + Rt) & ~7; }});
1510                }
1511                0x7: Prefetch::prefx({{ EA = Rs + Rt; }});
1512            }
1513
1514            0x3: decode FUNCTION_LO {
1515                0x6: Float64Op::alnv_ps({{
1516                    if (Rs<2:0> == 0) {
1517                        Fd.ud = Fs.ud;
1518                    } else if (Rs<2:0> == 4) {
1519#if BYTE_ORDER == BIG_ENDIAN
1520                        Fd.ud = Fs.ud<31:0> << 32 | Ft.ud<63:32>;
1521#elif BYTE_ORDER == LITTLE_ENDIAN
1522                        Fd.ud = Ft.ud<31:0> << 32 | Fs.ud<63:32>;
1523#endif
1524                    } else {
1525                        Fd.ud = Fd.ud;
1526                    }
1527                }});
1528            }
1529
1530            format FloatAccOp {
1531                0x4: decode FUNCTION_LO {
1532                    0x0: madd_s({{ Fd.sf = (Fs.sf * Ft.sf) + Fr.sf; }});
1533                    0x1: madd_d({{ Fd.df = (Fs.df * Ft.df) + Fr.df; }});
1534                    0x6: madd_ps({{
1535                        Fd1.sf = (Fs1.df * Ft1.df) + Fr1.df;
1536                        Fd2.sf = (Fs2.df * Ft2.df) + Fr2.df;
1537                    }});
1538                }
1539
1540                0x5: decode FUNCTION_LO {
1541                    0x0: msub_s({{ Fd.sf = (Fs.sf * Ft.sf) - Fr.sf; }});
1542                    0x1: msub_d({{ Fd.df = (Fs.df * Ft.df) - Fr.df; }});
1543                    0x6: msub_ps({{
1544                        Fd1.sf = (Fs1.df * Ft1.df) - Fr1.df;
1545                        Fd2.sf = (Fs2.df * Ft2.df) - Fr2.df;
1546                    }});
1547                }
1548
1549                0x6: decode FUNCTION_LO {
1550                    0x0: nmadd_s({{ Fd.sf = (-1 * Fs.sf * Ft.sf) - Fr.sf; }});
1551                    0x1: nmadd_d({{ Fd.df = (-1 * Fs.df * Ft.df) + Fr.df; }});
1552                    0x6: nmadd_ps({{
1553                        Fd1.sf = -((Fs1.df * Ft1.df) + Fr1.df);
1554                        Fd2.sf = -((Fs2.df * Ft2.df) + Fr2.df);
1555                    }});
1556                }
1557
1558                0x7: decode FUNCTION_LO {
1559                    0x0: nmsub_s({{ Fd.sf = (-1 * Fs.sf * Ft.sf) - Fr.sf; }});
1560                    0x1: nmsub_d({{ Fd.df = (-1 * Fs.df * Ft.df) - Fr.df; }});
1561                    0x6: nmsub_ps({{
1562                        Fd1.sf = -((Fs1.df * Ft1.df) - Fr1.df);
1563                        Fd2.sf = -((Fs2.df * Ft2.df) - Fr2.df);
1564                    }});
1565                }
1566            }
1567        }
1568
1569        format Branch {
1570            0x4: beql({{ cond = (Rs.sw == Rt.sw); }}, Likely);
1571            0x5: bnel({{ cond = (Rs.sw != Rt.sw); }}, Likely);
1572            0x6: blezl({{ cond = (Rs.sw <= 0); }}, Likely);
1573            0x7: bgtzl({{ cond = (Rs.sw > 0); }}, Likely);
1574        }
1575    }
1576
1577    0x3: decode OPCODE_LO {
1578        //Table A-5 MIPS32 SPECIAL2 Encoding of Function Field
1579        0x4: decode FUNCTION_HI {
1580            0x0: decode FUNCTION_LO {
1581                0x2: IntOp::mul({{
1582                    int64_t temp1 = Rs.sd * Rt.sd;
1583                    Rd.sw = temp1<31:0>;
1584                }}, IntMultOp);
1585
1586                format HiLoRdSelValOp {
1587                    0x0: madd({{
1588                        val = ((int64_t)HI_RD_SEL << 32 | LO_RD_SEL) +
1589                              (Rs.sd * Rt.sd);
1590                    }}, IntMultOp);
1591                    0x1: maddu({{
1592                        val = ((uint64_t)HI_RD_SEL << 32 | LO_RD_SEL) +
1593                              (Rs.ud * Rt.ud);
1594                    }}, IntMultOp);
1595                    0x4: msub({{
1596                        val = ((int64_t)HI_RD_SEL << 32 | LO_RD_SEL) -
1597                              (Rs.sd * Rt.sd);
1598                    }}, IntMultOp);
1599                    0x5: msubu({{
1600                        val = ((uint64_t)HI_RD_SEL << 32 | LO_RD_SEL) -
1601                              (Rs.ud * Rt.ud);
1602                    }}, IntMultOp);
1603                }
1604            }
1605
1606            0x4: decode FUNCTION_LO {
1607                format BasicOp {
1608                    0x0: clz({{
1609                        int cnt = 32;
1610                        for (int idx = 31; idx >= 0; idx--) {
1611                            if (Rs<idx:idx> == 1) {
1612                                cnt = 31 - idx;
1613                                break;
1614                            }
1615                        }
1616                        Rd.uw = cnt;
1617                    }});
1618                    0x1: clo({{
1619                        int cnt = 32;
1620                        for (int idx = 31; idx >= 0; idx--) {
1621                            if (Rs<idx:idx> == 0) {
1622                                cnt = 31 - idx;
1623                                break;
1624                            }
1625                        }
1626                        Rd.uw = cnt;
1627                    }});
1628                }
1629            }
1630
1631            0x7: decode FUNCTION_LO {
1632                0x7: FailUnimpl::sdbbp();
1633            }
1634        }
1635
1636        //Table A-6 MIPS32 SPECIAL3 Encoding of Function Field for Release 2
1637        //of the Architecture
1638        0x7: decode FUNCTION_HI {
1639            0x0: decode FUNCTION_LO {
1640                format BasicOp {
1641                    0x0: ext({{ Rt.uw = bits(Rs.uw, MSB+LSB, LSB); }});
1642                    0x4: ins({{
1643                        Rt.uw = bits(Rt.uw, 31, MSB+1) << (MSB+1) |
1644                                bits(Rs.uw, MSB-LSB, 0) << LSB |
1645                                bits(Rt.uw, LSB-1, 0);
1646                    }});
1647                }
1648            }
1649
1650            0x1: decode FUNCTION_LO {
1651                format MT_Control {
1652                    0x0: fork({{
1653                        forkThread(xc->tcBase(), fault, RD, Rs, Rt);
1654                    }}, UserMode);
1655                    0x1: yield({{
1656                        Rd.sw = yieldThread(xc->tcBase(), fault, Rs.sw,
1657                                            YQMask);
1658                    }}, UserMode);
1659                }
1660
1661                //Table 5-9 MIPS32 LX Encoding of the op Field (DSP ASE MANUAL)
1662                0x2: decode OP_HI {
1663                    0x0: decode OP_LO {
1664                        format LoadIndexedMemory {
1665                            0x0: lwx({{ Rd.sw = Mem.sw; }});
1666                            0x4: lhx({{ Rd.sw = Mem.sh; }});
1667                            0x6: lbux({{ Rd.uw = Mem.ub; }});
1668                        }
1669                    }
1670                }
1671                0x4: DspIntOp::insv({{
1672                    int pos = dspctl<5:0>;
1673                    int size = dspctl<12:7> - 1;
1674                    Rt.uw = insertBits(Rt.uw, pos+size,
1675                                       pos, Rs.uw<size:0>);
1676                }});
1677            }
1678
1679            0x2: decode FUNCTION_LO {
1680
1681                //Table 5-5 MIPS32 ADDU.QB Encoding of the op Field
1682                //(DSP ASE MANUAL)
1683                0x0: decode OP_HI {
1684                    0x0: decode OP_LO {
1685                        format DspIntOp {
1686                            0x0: addu_qb({{
1687                                Rd.uw = dspAdd(Rs.uw, Rt.uw, SIMD_FMT_QB,
1688                                               NOSATURATE, UNSIGNED, &dspctl);
1689                            }});
1690                            0x1: subu_qb({{
1691                                Rd.uw = dspSub(Rs.uw, Rt.uw, SIMD_FMT_QB,
1692                                               NOSATURATE, UNSIGNED, &dspctl);
1693                            }});
1694                            0x4: addu_s_qb({{
1695                                Rd.uw = dspAdd(Rs.uw, Rt.uw, SIMD_FMT_QB,
1696                                               SATURATE, UNSIGNED, &dspctl);
1697                            }});
1698                            0x5: subu_s_qb({{
1699                                Rd.uw = dspSub(Rs.uw, Rt.uw, SIMD_FMT_QB,
1700                                               SATURATE, UNSIGNED, &dspctl);
1701                            }});
1702                            0x6: muleu_s_ph_qbl({{
1703                                Rd.uw = dspMuleu(Rs.uw, Rt.uw,
1704                                                 MODE_L, &dspctl);
1705                            }}, IntMultOp);
1706                            0x7: muleu_s_ph_qbr({{
1707                                Rd.uw = dspMuleu(Rs.uw, Rt.uw,
1708                                                 MODE_R, &dspctl);
1709                            }}, IntMultOp);
1710                        }
1711                    }
1712                    0x1: decode OP_LO {
1713                        format DspIntOp {
1714                            0x0: addu_ph({{
1715                                Rd.uw = dspAdd(Rs.uw, Rt.uw, SIMD_FMT_PH,
1716                                               NOSATURATE, UNSIGNED, &dspctl);
1717                            }});
1718                            0x1: subu_ph({{
1719                                Rd.uw = dspSub(Rs.uw, Rt.uw, SIMD_FMT_PH,
1720                                               NOSATURATE, UNSIGNED, &dspctl);
1721                            }});
1722                            0x2: addq_ph({{
1723                                Rd.uw = dspAdd(Rs.uw, Rt.uw, SIMD_FMT_PH,
1724                                               NOSATURATE, SIGNED, &dspctl);
1725                            }});
1726                            0x3: subq_ph({{
1727                                Rd.uw = dspSub(Rs.uw, Rt.uw, SIMD_FMT_PH,
1728                                               NOSATURATE, SIGNED, &dspctl);
1729                            }});
1730                            0x4: addu_s_ph({{
1731                                Rd.uw = dspAdd(Rs.uw, Rt.uw, SIMD_FMT_PH,
1732                                               SATURATE, UNSIGNED, &dspctl);
1733                            }});
1734                            0x5: subu_s_ph({{
1735                                Rd.uw = dspSub(Rs.uw, Rt.uw, SIMD_FMT_PH,
1736                                               SATURATE, UNSIGNED, &dspctl);
1737                            }});
1738                            0x6: addq_s_ph({{
1739                                Rd.uw = dspAdd(Rs.uw, Rt.uw, SIMD_FMT_PH,
1740                                               SATURATE, SIGNED, &dspctl);
1741                            }});
1742                            0x7: subq_s_ph({{
1743                                Rd.uw = dspSub(Rs.uw, Rt.uw, SIMD_FMT_PH,
1744                                               SATURATE, SIGNED, &dspctl);
1745                            }});
1746                        }
1747                    }
1748                    0x2: decode OP_LO {
1749                        format DspIntOp {
1750                            0x0: addsc({{
1751                                int64_t dresult;
1752                                dresult = Rs.ud + Rt.ud;
1753                                Rd.sw = dresult<31:0>;
1754                                dspctl = insertBits(dspctl, 13, 13,
1755                                                    dresult<32:32>);
1756                            }});
1757                            0x1: addwc({{
1758                                int64_t dresult;
1759                                dresult = Rs.sd + Rt.sd + dspctl<13:13>;
1760                                Rd.sw = dresult<31:0>;
1761                                if (dresult<32:32> != dresult<31:31>)
1762                                    dspctl = insertBits(dspctl, 20, 20, 1);
1763                            }});
1764                            0x2: modsub({{
1765                                Rd.sw = (Rs.sw == 0) ? Rt.sw<23:8> :
1766                                                       Rs.sw - Rt.sw<7:0>;
1767                            }});
1768                            0x4: raddu_w_qb({{
1769                                Rd.uw = Rs.uw<31:24> + Rs.uw<23:16> +
1770                                        Rs.uw<15:8> + Rs.uw<7:0>;
1771                            }});
1772                            0x6: addq_s_w({{
1773                                Rd.sw = dspAdd(Rs.sw, Rt.sw, SIMD_FMT_W,
1774                                               SATURATE, SIGNED, &dspctl);
1775                            }});
1776                            0x7: subq_s_w({{
1777                                Rd.sw = dspSub(Rs.sw, Rt.sw, SIMD_FMT_W,
1778                                               SATURATE, SIGNED, &dspctl);
1779                            }});
1780                        }
1781                    }
1782                    0x3: decode OP_LO {
1783                        format DspIntOp {
1784                            0x4: muleq_s_w_phl({{
1785                                Rd.sw = dspMuleq(Rs.sw, Rt.sw,
1786                                                 MODE_L, &dspctl);
1787                            }}, IntMultOp);
1788                            0x5: muleq_s_w_phr({{
1789                                Rd.sw = dspMuleq(Rs.sw, Rt.sw,
1790                                                 MODE_R, &dspctl);
1791                            }}, IntMultOp);
1792                            0x6: mulq_s_ph({{
1793                                Rd.sw = dspMulq(Rs.sw, Rt.sw, SIMD_FMT_PH,
1794                                                SATURATE, NOROUND, &dspctl);
1795                            }}, IntMultOp);
1796                            0x7: mulq_rs_ph({{
1797                                Rd.sw = dspMulq(Rs.sw, Rt.sw, SIMD_FMT_PH,
1798                                                SATURATE, ROUND, &dspctl);
1799                            }}, IntMultOp);
1800                        }
1801                    }
1802                }
1803
1804                //Table 5-6 MIPS32 CMPU_EQ_QB Encoding of the op Field
1805                //(DSP ASE MANUAL)
1806                0x1: decode OP_HI {
1807                    0x0: decode OP_LO {
1808                        format DspIntOp {
1809                            0x0: cmpu_eq_qb({{
1810                                dspCmp(Rs.uw, Rt.uw, SIMD_FMT_QB,
1811                                       UNSIGNED, CMP_EQ, &dspctl);
1812                            }});
1813                            0x1: cmpu_lt_qb({{
1814                                dspCmp(Rs.uw, Rt.uw, SIMD_FMT_QB,
1815                                       UNSIGNED, CMP_LT, &dspctl);
1816                            }});
1817                            0x2: cmpu_le_qb({{
1818                                dspCmp(Rs.uw, Rt.uw, SIMD_FMT_QB,
1819                                       UNSIGNED, CMP_LE, &dspctl);
1820                            }});
1821                            0x3: pick_qb({{
1822                                Rd.uw = dspPick(Rs.uw, Rt.uw,
1823                                                SIMD_FMT_QB, &dspctl);
1824                            }});
1825                            0x4: cmpgu_eq_qb({{
1826                                Rd.uw = dspCmpg(Rs.uw, Rt.uw, SIMD_FMT_QB,
1827                                                UNSIGNED, CMP_EQ );
1828                            }});
1829                            0x5: cmpgu_lt_qb({{
1830                                Rd.uw = dspCmpg(Rs.uw, Rt.uw, SIMD_FMT_QB,
1831                                                UNSIGNED, CMP_LT);
1832                            }});
1833                            0x6: cmpgu_le_qb({{
1834                                Rd.uw = dspCmpg(Rs.uw, Rt.uw, SIMD_FMT_QB,
1835                                                UNSIGNED, CMP_LE);
1836                            }});
1837                        }
1838                    }
1839                    0x1: decode OP_LO {
1840                        format DspIntOp {
1841                            0x0: cmp_eq_ph({{
1842                                dspCmp(Rs.uw, Rt.uw, SIMD_FMT_PH,
1843                                       SIGNED, CMP_EQ, &dspctl);
1844                            }});
1845                            0x1: cmp_lt_ph({{
1846                                dspCmp(Rs.uw, Rt.uw, SIMD_FMT_PH,
1847                                       SIGNED, CMP_LT, &dspctl);
1848                            }});
1849                            0x2: cmp_le_ph({{
1850                                dspCmp(Rs.uw, Rt.uw, SIMD_FMT_PH,
1851                                       SIGNED, CMP_LE, &dspctl);
1852                            }});
1853                            0x3: pick_ph({{
1854                                Rd.uw = dspPick(Rs.uw, Rt.uw,
1855                                                SIMD_FMT_PH, &dspctl);
1856                            }});
1857                            0x4: precrq_qb_ph({{
1858                                Rd.uw = Rs.uw<31:24> << 24 |
1859                                        Rs.uw<15:8> << 16 |
1860                                        Rt.uw<31:24> << 8 |
1861                                        Rt.uw<15:8>;
1862                            }});
1863                            0x5: precr_qb_ph({{
1864                                Rd.uw = Rs.uw<23:16> << 24 |
1865                                        Rs.uw<7:0> << 16 |
1866                                        Rt.uw<23:16> << 8 |
1867                                        Rt.uw<7:0>;
1868                            }});
1869                            0x6: packrl_ph({{
1870                                Rd.uw = dspPack(Rs.uw, Rt.uw, SIMD_FMT_PH);
1871                            }});
1872                            0x7: precrqu_s_qb_ph({{
1873                                Rd.uw = dspPrecrqu(Rs.uw, Rt.uw, &dspctl);
1874                            }});
1875                        }
1876                    }
1877                    0x2: decode OP_LO {
1878                        format DspIntOp {
1879                            0x4: precrq_ph_w({{
1880                                Rd.uw = Rs.uw<31:16> << 16 | Rt.uw<31:16>;
1881                            }});
1882                            0x5: precrq_rs_ph_w({{
1883                                Rd.uw = dspPrecrq(Rs.uw, Rt.uw,
1884                                                  SIMD_FMT_W, &dspctl);
1885                            }});
1886                        }
1887                    }
1888                    0x3: decode OP_LO {
1889                        format DspIntOp {
1890                            0x0: cmpgdu_eq_qb({{
1891                                Rd.uw = dspCmpgd(Rs.uw, Rt.uw, SIMD_FMT_QB,
1892                                                 UNSIGNED, CMP_EQ, &dspctl);
1893                            }});
1894                            0x1: cmpgdu_lt_qb({{
1895                                Rd.uw = dspCmpgd(Rs.uw, Rt.uw, SIMD_FMT_QB,
1896                                                 UNSIGNED, CMP_LT, &dspctl);
1897                            }});
1898                            0x2: cmpgdu_le_qb({{
1899                                Rd.uw = dspCmpgd(Rs.uw, Rt.uw, SIMD_FMT_QB,
1900                                                 UNSIGNED, CMP_LE, &dspctl);
1901                            }});
1902                            0x6: precr_sra_ph_w({{
1903                                Rt.uw = dspPrecrSra(Rt.uw, Rs.uw, RD,
1904                                                    SIMD_FMT_W, NOROUND);
1905                            }});
1906                            0x7: precr_sra_r_ph_w({{
1907                                Rt.uw = dspPrecrSra(Rt.uw, Rs.uw, RD,
1908                                                    SIMD_FMT_W, ROUND); 
1909                            }});
1910                        }
1911                    }
1912                }
1913
1914                //Table 5-7 MIPS32 ABSQ_S.PH Encoding of the op Field
1915                //(DSP ASE MANUAL)
1916                0x2: decode OP_HI {
1917                    0x0: decode OP_LO {
1918                        format DspIntOp {
1919                            0x1: absq_s_qb({{
1920                                Rd.sw = dspAbs(Rt.sw, SIMD_FMT_QB, &dspctl);
1921                            }});
1922                            0x2: repl_qb({{
1923                                Rd.uw = RS_RT<7:0> << 24 |
1924                                        RS_RT<7:0> << 16 |
1925                                        RS_RT<7:0> << 8 |
1926                                        RS_RT<7:0>;
1927                            }});
1928                            0x3: replv_qb({{
1929                                Rd.sw = Rt.uw<7:0> << 24 |
1930                                        Rt.uw<7:0> << 16 |
1931                                        Rt.uw<7:0> << 8 |
1932                                        Rt.uw<7:0>;
1933                            }});
1934                            0x4: precequ_ph_qbl({{
1935                                Rd.uw = dspPrece(Rt.uw, SIMD_FMT_QB, UNSIGNED,
1936                                                 SIMD_FMT_PH, SIGNED, MODE_L);
1937                            }});
1938                            0x5: precequ_ph_qbr({{
1939                                Rd.uw = dspPrece(Rt.uw, SIMD_FMT_QB, UNSIGNED,
1940                                                 SIMD_FMT_PH, SIGNED, MODE_R);
1941                            }});
1942                            0x6: precequ_ph_qbla({{
1943                                Rd.uw = dspPrece(Rt.uw, SIMD_FMT_QB, UNSIGNED,
1944                                                 SIMD_FMT_PH, SIGNED, MODE_LA);
1945                            }});
1946                            0x7: precequ_ph_qbra({{
1947                                Rd.uw = dspPrece(Rt.uw, SIMD_FMT_QB, UNSIGNED,
1948                                                 SIMD_FMT_PH, SIGNED, MODE_RA);
1949                            }});
1950                        }
1951                    }
1952                    0x1: decode OP_LO {
1953                        format DspIntOp {
1954                            0x1: absq_s_ph({{
1955                                Rd.sw = dspAbs(Rt.sw, SIMD_FMT_PH, &dspctl);
1956                            }});
1957                            0x2: repl_ph({{
1958                                Rd.uw = (sext<10>(RS_RT))<15:0> << 16 |
1959                                        (sext<10>(RS_RT))<15:0>;
1960                            }});
1961                            0x3: replv_ph({{
1962                                Rd.uw = Rt.uw<15:0> << 16 |
1963                                        Rt.uw<15:0>;
1964                            }});
1965                            0x4: preceq_w_phl({{
1966                                Rd.uw = dspPrece(Rt.uw, SIMD_FMT_PH, SIGNED,
1967                                                 SIMD_FMT_W, SIGNED, MODE_L);
1968                            }});
1969                            0x5: preceq_w_phr({{
1970                                Rd.uw = dspPrece(Rt.uw, SIMD_FMT_PH, SIGNED,
1971                                                 SIMD_FMT_W, SIGNED, MODE_R);
1972                            }});
1973                        }
1974                    }
1975                    0x2: decode OP_LO {
1976                        format DspIntOp {
1977                            0x1: absq_s_w({{
1978                                Rd.sw = dspAbs(Rt.sw, SIMD_FMT_W, &dspctl);
1979                            }});
1980                        }
1981                    }
1982                    0x3: decode OP_LO {
1983                        0x3: IntOp::bitrev({{
1984                            Rd.uw = bitrev( Rt.uw<15:0> );
1985                        }});
1986                        format DspIntOp {
1987                            0x4: preceu_ph_qbl({{
1988                                Rd.uw = dspPrece(Rt.uw, SIMD_FMT_QB,
1989                                                 UNSIGNED, SIMD_FMT_PH,
1990                                                 UNSIGNED, MODE_L);
1991                            }});
1992                            0x5: preceu_ph_qbr({{
1993                                Rd.uw = dspPrece(Rt.uw, SIMD_FMT_QB,
1994                                                 UNSIGNED, SIMD_FMT_PH,
1995                                                 UNSIGNED, MODE_R );
1996                            }});
1997                            0x6: preceu_ph_qbla({{
1998                                Rd.uw = dspPrece(Rt.uw, SIMD_FMT_QB,
1999                                                 UNSIGNED, SIMD_FMT_PH,
2000                                                 UNSIGNED, MODE_LA );
2001                            }});
2002                            0x7: preceu_ph_qbra({{
2003                                Rd.uw = dspPrece(Rt.uw, SIMD_FMT_QB,
2004                                                 UNSIGNED, SIMD_FMT_PH,
2005                                                 UNSIGNED, MODE_RA);
2006                            }});
2007                        }
2008                    }
2009                }
2010
2011                //Table 5-8 MIPS32 SHLL.QB Encoding of the op Field
2012                //(DSP ASE MANUAL)
2013                0x3: decode OP_HI {
2014                    0x0: decode OP_LO {
2015                        format DspIntOp {
2016                            0x0: shll_qb({{
2017                                Rd.sw = dspShll(Rt.sw, RS, SIMD_FMT_QB,
2018                                                NOSATURATE, UNSIGNED, &dspctl);
2019                            }});
2020                            0x1: shrl_qb({{
2021                                Rd.sw = dspShrl(Rt.sw, RS, SIMD_FMT_QB,
2022                                                UNSIGNED);
2023                            }});
2024                            0x2: shllv_qb({{
2025                                Rd.sw = dspShll(Rt.sw, Rs.sw, SIMD_FMT_QB,
2026                                                NOSATURATE, UNSIGNED, &dspctl);
2027                            }});
2028                            0x3: shrlv_qb({{
2029                                Rd.sw = dspShrl(Rt.sw, Rs.sw, SIMD_FMT_QB,
2030                                                UNSIGNED);
2031                            }});
2032                            0x4: shra_qb({{
2033                                Rd.sw = dspShra(Rt.sw, RS, SIMD_FMT_QB,
2034                                                NOROUND, SIGNED, &dspctl);
2035                            }});
2036                            0x5: shra_r_qb({{
2037                                Rd.sw = dspShra(Rt.sw, RS, SIMD_FMT_QB,
2038                                                ROUND, SIGNED, &dspctl);
2039                            }});
2040                            0x6: shrav_qb({{
2041                                Rd.sw = dspShra(Rt.sw, Rs.sw, SIMD_FMT_QB,
2042                                                NOROUND, SIGNED, &dspctl);
2043                            }});
2044                            0x7: shrav_r_qb({{
2045                                Rd.sw = dspShra(Rt.sw, Rs.sw, SIMD_FMT_QB,
2046                                                ROUND, SIGNED, &dspctl);
2047                            }});
2048                        }
2049                    }
2050                    0x1: decode OP_LO {
2051                        format DspIntOp {
2052                            0x0: shll_ph({{
2053                                Rd.uw = dspShll(Rt.uw, RS, SIMD_FMT_PH,
2054                                                NOSATURATE, SIGNED, &dspctl);
2055                            }});
2056                            0x1: shra_ph({{
2057                                Rd.sw = dspShra(Rt.sw, RS, SIMD_FMT_PH,
2058                                                NOROUND, SIGNED, &dspctl);
2059                            }});
2060                            0x2: shllv_ph({{
2061                                Rd.sw = dspShll(Rt.sw, Rs.sw, SIMD_FMT_PH,
2062                                                NOSATURATE, SIGNED, &dspctl);
2063                            }});
2064                            0x3: shrav_ph({{
2065                                Rd.sw = dspShra(Rt.sw, Rs.sw, SIMD_FMT_PH,
2066                                                NOROUND, SIGNED, &dspctl);
2067                            }});
2068                            0x4: shll_s_ph({{
2069                                Rd.sw = dspShll(Rt.sw, RS, SIMD_FMT_PH,
2070                                                SATURATE, SIGNED, &dspctl);
2071                            }});
2072                            0x5: shra_r_ph({{
2073                                Rd.sw = dspShra(Rt.sw, RS, SIMD_FMT_PH,
2074                                                ROUND, SIGNED, &dspctl);
2075                            }});
2076                            0x6: shllv_s_ph({{
2077                                Rd.sw = dspShll(Rt.sw, Rs.sw, SIMD_FMT_PH,
2078                                                SATURATE, SIGNED, &dspctl);
2079                            }});
2080                            0x7: shrav_r_ph({{
2081                                Rd.sw = dspShra(Rt.sw, Rs.sw, SIMD_FMT_PH,
2082                                                ROUND, SIGNED, &dspctl);
2083                            }});
2084                        }
2085                    }
2086                    0x2: decode OP_LO {
2087                        format DspIntOp {
2088                            0x4: shll_s_w({{
2089                                Rd.sw = dspShll(Rt.sw, RS, SIMD_FMT_W,
2090                                                SATURATE, SIGNED, &dspctl);
2091                            }});
2092                            0x5: shra_r_w({{
2093                                Rd.sw = dspShra(Rt.sw, RS, SIMD_FMT_W,
2094                                                ROUND, SIGNED, &dspctl);
2095                            }});
2096                            0x6: shllv_s_w({{
2097                                Rd.sw = dspShll(Rt.sw, Rs.sw, SIMD_FMT_W,
2098                                                SATURATE, SIGNED, &dspctl);
2099                            }});
2100                            0x7: shrav_r_w({{
2101                                Rd.sw = dspShra(Rt.sw, Rs.sw, SIMD_FMT_W,
2102                                                ROUND, SIGNED, &dspctl);
2103                            }});
2104                        }
2105                    }
2106                    0x3: decode OP_LO {
2107                        format DspIntOp {
2108                            0x1: shrl_ph({{
2109                                Rd.sw = dspShrl(Rt.sw, RS, SIMD_FMT_PH,
2110                                                UNSIGNED);
2111                            }});
2112                            0x3: shrlv_ph({{
2113                                Rd.sw = dspShrl(Rt.sw, Rs.sw, SIMD_FMT_PH,
2114                                                UNSIGNED);
2115                            }});
2116                        }
2117                    }
2118                }
2119            }
2120
2121            0x3: decode FUNCTION_LO {
2122
2123                //Table 3.12 MIPS32 ADDUH.QB Encoding of the op Field
2124                //(DSP ASE Rev2 Manual)
2125                0x0: decode OP_HI {
2126                    0x0: decode OP_LO {
2127                        format DspIntOp {
2128                            0x0: adduh_qb({{
2129                                Rd.uw = dspAddh(Rs.sw, Rt.sw, SIMD_FMT_QB,
2130                                                NOROUND, UNSIGNED);
2131                            }});
2132                            0x1: subuh_qb({{
2133                                Rd.uw = dspSubh(Rs.sw, Rt.sw, SIMD_FMT_QB,
2134                                                NOROUND, UNSIGNED);
2135                            }});
2136                            0x2: adduh_r_qb({{
2137                                Rd.uw = dspAddh(Rs.sw, Rt.sw, SIMD_FMT_QB,
2138                                                ROUND, UNSIGNED);
2139                            }});
2140                            0x3: subuh_r_qb({{
2141                                Rd.uw = dspSubh(Rs.sw, Rt.sw, SIMD_FMT_QB,
2142                                                ROUND, UNSIGNED);
2143                            }});
2144                        }
2145                    }
2146                    0x1: decode OP_LO {
2147                        format DspIntOp {
2148                            0x0: addqh_ph({{
2149                                Rd.uw = dspAddh(Rs.sw, Rt.sw, SIMD_FMT_PH,
2150                                                NOROUND, SIGNED);
2151                            }});
2152                            0x1: subqh_ph({{
2153                                Rd.uw = dspSubh(Rs.sw, Rt.sw, SIMD_FMT_PH,
2154                                                NOROUND, SIGNED);
2155                            }});
2156                            0x2: addqh_r_ph({{
2157                                Rd.uw = dspAddh(Rs.sw, Rt.sw, SIMD_FMT_PH,
2158                                                ROUND, SIGNED);
2159                            }});
2160                            0x3: subqh_r_ph({{
2161                                Rd.uw = dspSubh(Rs.sw, Rt.sw, SIMD_FMT_PH,
2162                                                ROUND, SIGNED);
2163                            }});
2164                            0x4: mul_ph({{
2165                                Rd.sw = dspMul(Rs.sw, Rt.sw, SIMD_FMT_PH,
2166                                               NOSATURATE, &dspctl);
2167                            }}, IntMultOp);
2168                            0x6: mul_s_ph({{
2169                                Rd.sw = dspMul(Rs.sw, Rt.sw, SIMD_FMT_PH,
2170                                               SATURATE, &dspctl);
2171                            }}, IntMultOp);
2172                        }
2173                    }
2174                    0x2: decode OP_LO {
2175                        format DspIntOp {
2176                            0x0: addqh_w({{
2177                                Rd.uw = dspAddh(Rs.sw, Rt.sw, SIMD_FMT_W,
2178                                                NOROUND, SIGNED);
2179                            }});
2180                            0x1: subqh_w({{
2181                                Rd.uw = dspSubh(Rs.sw, Rt.sw, SIMD_FMT_W,
2182                                                NOROUND, SIGNED);
2183                            }});
2184                            0x2: addqh_r_w({{
2185                                Rd.uw = dspAddh(Rs.sw, Rt.sw, SIMD_FMT_W,
2186                                                ROUND, SIGNED);
2187                            }});
2188                            0x3: subqh_r_w({{
2189                                Rd.uw = dspSubh(Rs.sw, Rt.sw, SIMD_FMT_W,
2190                                                ROUND, SIGNED);
2191                            }});
2192                            0x6: mulq_s_w({{
2193                                Rd.sw = dspMulq(Rs.sw, Rt.sw, SIMD_FMT_W,
2194                                                SATURATE, NOROUND, &dspctl);
2195                            }}, IntMultOp);
2196                            0x7: mulq_rs_w({{
2197                                Rd.sw = dspMulq(Rs.sw, Rt.sw, SIMD_FMT_W,
2198                                                SATURATE, ROUND, &dspctl);
2199                            }}, IntMultOp);
2200                        }
2201                    }
2202                }
2203            }
2204
2205            //Table A-10 MIPS32 BSHFL Encoding of sa Field
2206            0x4: decode SA {
2207                format BasicOp {
2208                    0x02: wsbh({{
2209                        Rd.uw = Rt.uw<23:16> << 24 |
2210                                Rt.uw<31:24> << 16 |
2211                                Rt.uw<7:0>   << 8  |
2212                                Rt.uw<15:8>;
2213                    }});
2214                    0x10: seb({{ Rd.sw = Rt.sb; }});
2215                    0x18: seh({{ Rd.sw = Rt.sh; }});
2216                }
2217            }
2218
2219            0x6: decode FUNCTION_LO {
2220
2221                //Table 5-10 MIPS32 DPAQ.W.PH Encoding of the op Field
2222                //(DSP ASE MANUAL)
2223                0x0: decode OP_HI {
2224                    0x0: decode OP_LO {
2225                        format DspHiLoOp {
2226                            0x0: dpa_w_ph({{
2227                                dspac = dspDpa(dspac, Rs.sw, Rt.sw, ACDST,
2228                                               SIMD_FMT_PH, SIGNED, MODE_L);
2229                            }}, IntMultOp);
2230                            0x1: dps_w_ph({{
2231                                dspac = dspDps(dspac, Rs.sw, Rt.sw, ACDST,
2232                                               SIMD_FMT_PH, SIGNED, MODE_L);
2233                            }}, IntMultOp);
2234                            0x2: mulsa_w_ph({{
2235                                dspac = dspMulsa(dspac, Rs.sw, Rt.sw,
2236                                                 ACDST, SIMD_FMT_PH );
2237                            }}, IntMultOp);
2238                            0x3: dpau_h_qbl({{
2239                                dspac = dspDpa(dspac, Rs.sw, Rt.sw, ACDST,
2240                                               SIMD_FMT_QB, UNSIGNED, MODE_L);
2241                            }}, IntMultOp);
2242                            0x4: dpaq_s_w_ph({{
2243                                dspac = dspDpaq(dspac, Rs.sw, Rt.sw,
2244                                                ACDST, SIMD_FMT_PH,
2245                                                SIMD_FMT_W, NOSATURATE,
2246                                                MODE_L, &dspctl);
2247                            }}, IntMultOp);
2248                            0x5: dpsq_s_w_ph({{
2249                                dspac = dspDpsq(dspac, Rs.sw, Rt.sw,
2250                                                ACDST, SIMD_FMT_PH,
2251                                                SIMD_FMT_W, NOSATURATE,
2252                                                MODE_L, &dspctl);
2253                            }}, IntMultOp);
2254                            0x6: mulsaq_s_w_ph({{
2255                                dspac = dspMulsaq(dspac, Rs.sw, Rt.sw,
2256                                                  ACDST, SIMD_FMT_PH,
2257                                                  &dspctl);
2258                            }}, IntMultOp);
2259                            0x7: dpau_h_qbr({{
2260                                dspac = dspDpa(dspac, Rs.sw, Rt.sw, ACDST,
2261                                               SIMD_FMT_QB, UNSIGNED, MODE_R);
2262                            }}, IntMultOp);
2263                        }
2264                    }
2265                    0x1: decode OP_LO {
2266                        format DspHiLoOp {
2267                            0x0: dpax_w_ph({{
2268                                dspac = dspDpa(dspac, Rs.sw, Rt.sw, ACDST,
2269                                               SIMD_FMT_PH, SIGNED, MODE_X);
2270                            }}, IntMultOp);
2271                            0x1: dpsx_w_ph({{
2272                                dspac = dspDps(dspac, Rs.sw, Rt.sw, ACDST,
2273                                               SIMD_FMT_PH, SIGNED, MODE_X);
2274                            }}, IntMultOp);
2275                            0x3: dpsu_h_qbl({{
2276                                dspac = dspDps(dspac, Rs.sw, Rt.sw, ACDST,
2277                                               SIMD_FMT_QB, UNSIGNED, MODE_L);
2278                            }}, IntMultOp);
2279                            0x4: dpaq_sa_l_w({{
2280                                dspac = dspDpaq(dspac, Rs.sw, Rt.sw,
2281                                                ACDST, SIMD_FMT_W,
2282                                                SIMD_FMT_L, SATURATE,
2283                                                MODE_L, &dspctl);
2284                            }}, IntMultOp);
2285                            0x5: dpsq_sa_l_w({{
2286                                dspac = dspDpsq(dspac, Rs.sw, Rt.sw,
2287                                                ACDST, SIMD_FMT_W,
2288                                                SIMD_FMT_L, SATURATE,
2289                                                MODE_L, &dspctl);
2290                            }}, IntMultOp);
2291                            0x7: dpsu_h_qbr({{
2292                                dspac = dspDps(dspac, Rs.sw, Rt.sw, ACDST,
2293                                               SIMD_FMT_QB, UNSIGNED, MODE_R);
2294                            }}, IntMultOp);
2295                        }
2296                    }
2297                    0x2: decode OP_LO {
2298                        format DspHiLoOp {
2299                            0x0: maq_sa_w_phl({{
2300                                dspac = dspMaq(dspac, Rs.uw, Rt.uw,
2301                                               ACDST, SIMD_FMT_PH,
2302                                               MODE_L, SATURATE, &dspctl);
2303                            }}, IntMultOp);
2304                            0x2: maq_sa_w_phr({{
2305                                dspac = dspMaq(dspac, Rs.uw, Rt.uw,
2306                                               ACDST, SIMD_FMT_PH,
2307                                               MODE_R, SATURATE, &dspctl);
2308                            }}, IntMultOp);
2309                            0x4: maq_s_w_phl({{
2310                                dspac = dspMaq(dspac, Rs.uw, Rt.uw,
2311                                               ACDST, SIMD_FMT_PH,
2312                                               MODE_L, NOSATURATE, &dspctl);
2313                            }}, IntMultOp);
2314                            0x6: maq_s_w_phr({{
2315                                dspac = dspMaq(dspac, Rs.uw, Rt.uw,
2316                                               ACDST, SIMD_FMT_PH,
2317                                               MODE_R, NOSATURATE, &dspctl);
2318                            }}, IntMultOp);
2319                        }
2320                    }
2321                    0x3: decode OP_LO {
2322                        format DspHiLoOp {
2323                            0x0: dpaqx_s_w_ph({{
2324                                dspac = dspDpaq(dspac, Rs.sw, Rt.sw,
2325                                                ACDST, SIMD_FMT_PH,
2326                                                SIMD_FMT_W, NOSATURATE,
2327                                                MODE_X, &dspctl);
2328                            }}, IntMultOp);
2329                            0x1: dpsqx_s_w_ph({{
2330                                dspac = dspDpsq(dspac, Rs.sw, Rt.sw,
2331                                                ACDST, SIMD_FMT_PH,
2332                                                SIMD_FMT_W, NOSATURATE,
2333                                                MODE_X, &dspctl);
2334                            }}, IntMultOp);
2335                            0x2: dpaqx_sa_w_ph({{
2336                                dspac = dspDpaq(dspac, Rs.sw, Rt.sw,
2337                                                ACDST, SIMD_FMT_PH,
2338                                                SIMD_FMT_W, SATURATE,
2339                                                MODE_X, &dspctl);
2340                            }}, IntMultOp);
2341                            0x3: dpsqx_sa_w_ph({{
2342                                dspac = dspDpsq(dspac, Rs.sw, Rt.sw,
2343                                                ACDST, SIMD_FMT_PH,
2344                                                SIMD_FMT_W, SATURATE,
2345                                                MODE_X, &dspctl);
2346                            }}, IntMultOp);
2347                        }
2348                    }
2349                }
2350
2351                //Table 3.3 MIPS32 APPEND Encoding of the op Field
2352                0x1: decode OP_HI {
2353                    0x0: decode OP_LO {
2354                        format IntOp {
2355                            0x0: append({{
2356                                Rt.uw = (Rt.uw << RD) | bits(Rs.uw, RD - 1, 0);
2357                                }});
2358                            0x1: prepend({{
2359                                Rt.uw = (Rt.uw >> RD) |
2360                                        (bits(Rs.uw, RD - 1, 0) << (32 - RD));
2361                            }});
2362                        }
2363                    }
2364                    0x2: decode OP_LO {
2365                        format IntOp {
2366                            0x0: balign({{
2367                                Rt.uw = (Rt.uw << (8 * BP)) |
2368                                        (Rs.uw >> (8 * (4 - BP)));
2369                            }});
2370                        }
2371                    }
2372                }
2373
2374            }
2375            0x7: decode FUNCTION_LO {
2376
2377                //Table 5-11 MIPS32 EXTR.W Encoding of the op Field
2378                //(DSP ASE MANUAL)
2379                0x0: decode OP_HI {
2380                    0x0: decode OP_LO {
2381                        format DspHiLoOp {
2382                            0x0: extr_w({{
2383                                Rt.uw = dspExtr(dspac, SIMD_FMT_W, RS,
2384                                                NOROUND, NOSATURATE, &dspctl);
2385                            }});
2386                            0x1: extrv_w({{
2387                                Rt.uw = dspExtr(dspac, SIMD_FMT_W, Rs.uw,
2388                                                NOROUND, NOSATURATE, &dspctl);
2389                            }});
2390                            0x2: extp({{
2391                                Rt.uw = dspExtp(dspac, RS, &dspctl);
2392                            }});
2393                            0x3: extpv({{
2394                                Rt.uw = dspExtp(dspac, Rs.uw, &dspctl);
2395                            }});
2396                            0x4: extr_r_w({{
2397                                Rt.uw = dspExtr(dspac, SIMD_FMT_W, RS,
2398                                                ROUND, NOSATURATE, &dspctl);
2399                            }});
2400                            0x5: extrv_r_w({{
2401                                Rt.uw = dspExtr(dspac, SIMD_FMT_W, Rs.uw,
2402                                                ROUND, NOSATURATE, &dspctl);
2403                            }});
2404                            0x6: extr_rs_w({{
2405                                Rt.uw = dspExtr(dspac, SIMD_FMT_W, RS,
2406                                                ROUND, SATURATE, &dspctl);
2407                            }});
2408                            0x7: extrv_rs_w({{
2409                                Rt.uw = dspExtr(dspac, SIMD_FMT_W, Rs.uw,
2410                                                ROUND, SATURATE, &dspctl);
2411                            }});
2412                        }
2413                    }
2414                    0x1: decode OP_LO {
2415                        format DspHiLoOp {
2416                            0x2: extpdp({{
2417                                Rt.uw = dspExtpd(dspac, RS, &dspctl);
2418                            }});
2419                            0x3: extpdpv({{
2420                                Rt.uw = dspExtpd(dspac, Rs.uw, &dspctl);
2421                            }});
2422                            0x6: extr_s_h({{
2423                                Rt.uw = dspExtr(dspac, SIMD_FMT_PH, RS,
2424                                                NOROUND, SATURATE, &dspctl);
2425                            }});
2426                            0x7: extrv_s_h({{
2427                                Rt.uw = dspExtr(dspac, SIMD_FMT_PH, Rs.uw,
2428                                                NOROUND, SATURATE, &dspctl);
2429                            }});
2430                        }
2431                    }
2432                    0x2: decode OP_LO {
2433                        format DspIntOp {
2434                            0x2: rddsp({{
2435                                Rd.uw = readDSPControl(&dspctl, RDDSPMASK);
2436                            }});
2437                            0x3: wrdsp({{
2438                                writeDSPControl(&dspctl, Rs.uw, WRDSPMASK);
2439                            }});
2440                        }
2441                    }
2442                    0x3: decode OP_LO {
2443                        format DspHiLoOp {
2444                            0x2: shilo({{
2445                                if (sext<6>(HILOSA) < 0) {
2446                                    dspac = (uint64_t)dspac <<
2447                                                -sext<6>(HILOSA);
2448                                } else {
2449                                    dspac = (uint64_t)dspac >>
2450                                                sext<6>(HILOSA);
2451                                }
2452                            }});
2453                            0x3: shilov({{
2454                                if (sext<6>(Rs.sw<5:0>) < 0) {
2455                                    dspac = (uint64_t)dspac <<
2456                                                -sext<6>(Rs.sw<5:0>);
2457                                } else {
2458                                    dspac = (uint64_t)dspac >>
2459                                                sext<6>(Rs.sw<5:0>);
2460                                }
2461                            }});
2462                            0x7: mthlip({{
2463                                dspac = dspac << 32;
2464                                dspac |= Rs.uw;
2465                                dspctl = insertBits(dspctl, 5, 0,
2466                                                    dspctl<5:0> + 32);
2467                            }});
2468                        }
2469                    }
2470                }
2471                0x3: decode OP {
2472#if FULL_SYSTEM
2473                    0x0: FailUnimpl::rdhwr();
2474#else
2475                    0x0: decode RD {
2476                        29: BasicOp::rdhwr({{ Rt = TpValue; }});
2477                    }
2478#endif
2479                }
2480            }
2481        }
2482    }
2483
2484    0x4: decode OPCODE_LO {
2485        format LoadMemory {
2486          0x0: lb({{ Rt.sw = Mem.sb; }});
2487          0x1: lh({{ Rt.sw = Mem.sh; }});
2488            0x3: lw({{ Rt.sw = Mem.sw; }});
2489            0x4: lbu({{ Rt.uw = Mem.ub;}});
2490            0x5: lhu({{ Rt.uw = Mem.uh; }});
2491        }
2492
2493        format LoadUnalignedMemory {
2494            0x2: lwl({{
2495                uint32_t mem_shift = 24 - (8 * byte_offset);
2496                Rt.uw = mem_word << mem_shift | (Rt.uw & mask(mem_shift));
2497            }});
2498            0x6: lwr({{
2499                uint32_t mem_shift = 8 * byte_offset;
2500                Rt.uw = (Rt.uw & (mask(mem_shift) << (32 - mem_shift))) |
2501                        (mem_word >> mem_shift);
2502            }});
2503        }
2504    }
2505
2506    0x5: decode OPCODE_LO {
2507        format StoreMemory {
2508            0x0: sb({{ Mem.ub = Rt<7:0>; }});
2509            0x1: sh({{ Mem.uh = Rt<15:0>; }});
2510            0x3: sw({{ Mem.uw = Rt<31:0>; }});
2511        }
2512
2513        format StoreUnalignedMemory {
2514            0x2: swl({{
2515                uint32_t reg_shift = 24 - (8 * byte_offset);
2516                uint32_t mem_shift = 32 - reg_shift;
2517                mem_word = (mem_word & (mask(reg_shift) << mem_shift)) |
2518                           (Rt.uw >> reg_shift);
2519                }});
2520            0x6: swr({{
2521                uint32_t reg_shift = 8 * byte_offset;
2522                mem_word = Rt.uw << reg_shift |
2523                           (mem_word & (mask(reg_shift)));
2524            }});
2525        }
2526        format CP0Control {
2527            0x7: cache({{
2528                //Addr CacheEA = Rs.uw + OFFSET;
2529                //fault = xc->CacheOp((uint8_t)CACHE_OP,(Addr) CacheEA);
2530            }});
2531        }
2532    }
2533
2534    0x6: decode OPCODE_LO {
2535        format LoadMemory {
2536            0x0: ll({{ Rt.uw = Mem.uw; }}, mem_flags=LLSC);
2537            0x1: lwc1({{ Ft.uw = Mem.uw; }});
2538            0x5: ldc1({{ Ft.ud = Mem.ud; }});
2539        }
2540        0x2: CP2Unimpl::lwc2();
2541        0x6: CP2Unimpl::ldc2();
2542        0x3: Prefetch::pref();
2543    }
2544
2545
2546    0x7: decode OPCODE_LO {
2547        0x0: StoreCond::sc({{ Mem.uw = Rt.uw; }},
2548                           {{ uint64_t tmp = write_result;
2549                              Rt.uw = (tmp == 0 || tmp == 1) ? tmp : Rt.uw;
2550                           }}, mem_flags=LLSC,
2551                               inst_flags = IsStoreConditional);
2552        format StoreMemory {
2553            0x1: swc1({{ Mem.uw = Ft.uw; }});
2554            0x5: sdc1({{ Mem.ud = Ft.ud; }});
2555        }
2556        0x2: CP2Unimpl::swc2();
2557        0x6: CP2Unimpl::sdc2();
2558    }
2559}
2560
2561
2562