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