decoder.isa revision 2616
110338SCurtis.Dunham@arm.com // -*- mode:c++ -*-
210338SCurtis.Dunham@arm.com
310338SCurtis.Dunham@arm.com////////////////////////////////////////////////////////////////////
410338SCurtis.Dunham@arm.com//
510338SCurtis.Dunham@arm.com// The actual MIPS32 ISA decoder
610338SCurtis.Dunham@arm.com// -----------------------------
710338SCurtis.Dunham@arm.com// The following instructions are specified in the MIPS32 ISA
810338SCurtis.Dunham@arm.com// Specification. Decoding closely follows the style specified
910338SCurtis.Dunham@arm.com// in the MIPS32 ISAthe specification document starting with Table
1010338SCurtis.Dunham@arm.com// A-2 (document available @ www.mips.com)
1110338SCurtis.Dunham@arm.com//
1210338SCurtis.Dunham@arm.com//@todo: Distinguish "unknown/future" use insts from "reserved"
1310338SCurtis.Dunham@arm.com// ones
1410338SCurtis.Dunham@arm.comdecode OPCODE_HI default Unknown::unknown() {
1510338SCurtis.Dunham@arm.com
1610338SCurtis.Dunham@arm.com    // Derived From ... Table A-2 MIPS32 ISA Manual
1710338SCurtis.Dunham@arm.com    0x0: decode OPCODE_LO {
1810338SCurtis.Dunham@arm.com
1910338SCurtis.Dunham@arm.com        0x0: decode FUNCTION_HI {
2010338SCurtis.Dunham@arm.com            0x0: decode FUNCTION_LO {
2110338SCurtis.Dunham@arm.com                0x1: decode MOVCI {
2210338SCurtis.Dunham@arm.com                    format BasicOp {
2310338SCurtis.Dunham@arm.com                        0: movf({{ if (getFPConditionCode(FCSR, CC) == 0) Rd = Rs}});
2410338SCurtis.Dunham@arm.com                        1: movt({{ if (getFPConditionCode(FCSR, CC) == 1) Rd = Rs}});
2510338SCurtis.Dunham@arm.com                    }
2610338SCurtis.Dunham@arm.com                }
2710338SCurtis.Dunham@arm.com
2810338SCurtis.Dunham@arm.com                format BasicOp {
2910338SCurtis.Dunham@arm.com
3010338SCurtis.Dunham@arm.com                    //Table A-3 Note: "1. Specific encodings of the rt, rd, and sa fields
3110338SCurtis.Dunham@arm.com                    //are used to distinguish among the SLL, NOP, SSNOP and EHB functions.
3210338SCurtis.Dunham@arm.com                    0x0: decode RS  {
3310338SCurtis.Dunham@arm.com                        0x0: decode RT {     //fix Nop traditional vs. Nop converted disassembly later
3410338SCurtis.Dunham@arm.com                             0x0: decode RD  default Nop::nop(){
3510338SCurtis.Dunham@arm.com                                  0x0: decode SA {
3610338SCurtis.Dunham@arm.com                                      0x1: ssnop({{ ; }}); //really sll r0,r0,1
3710338SCurtis.Dunham@arm.com                                      0x3: ehb({{ ; }});   //really sll r0,r0,3
3810338SCurtis.Dunham@arm.com                                  }
3910338SCurtis.Dunham@arm.com                             }
4010338SCurtis.Dunham@arm.com
4110338SCurtis.Dunham@arm.com                             default: sll({{ Rd = Rt.uw << SA; }});
4210338SCurtis.Dunham@arm.com                        }
4310338SCurtis.Dunham@arm.com
4410338SCurtis.Dunham@arm.com                    }
4510338SCurtis.Dunham@arm.com
4610338SCurtis.Dunham@arm.com                    0x2: decode RS_SRL {
4710338SCurtis.Dunham@arm.com                        0x0:decode SRL {
4810338SCurtis.Dunham@arm.com                            0: srl({{ Rd = Rt.uw >> SA; }});
4910338SCurtis.Dunham@arm.com
5010338SCurtis.Dunham@arm.com                            //Hardcoded assuming 32-bit ISA, probably need parameter here
5110338SCurtis.Dunham@arm.com                            1: rotr({{ Rd = (Rt.uw << (32 - SA)) | (Rt.uw >> SA);}});
5210338SCurtis.Dunham@arm.com                        }
5310338SCurtis.Dunham@arm.com                    }
5410338SCurtis.Dunham@arm.com
5510338SCurtis.Dunham@arm.com                    0x3: decode RS {
5610338SCurtis.Dunham@arm.com                        0x0: sra({{
5710338SCurtis.Dunham@arm.com                            uint32_t temp = Rt >> SA;
5810338SCurtis.Dunham@arm.com
5910338SCurtis.Dunham@arm.com                            if ( (Rt & 0x80000000) > 0 ) {
6010338SCurtis.Dunham@arm.com                                uint32_t mask = 0x80000000;
6110338SCurtis.Dunham@arm.com                                for(int i=0; i < SA; i++) {
6210338SCurtis.Dunham@arm.com                                    temp |= mask;
6310338SCurtis.Dunham@arm.com                                    mask = mask >> 1;
6410338SCurtis.Dunham@arm.com                                }
6510338SCurtis.Dunham@arm.com                            }
6610338SCurtis.Dunham@arm.com
6710338SCurtis.Dunham@arm.com                            Rd = temp;
6810338SCurtis.Dunham@arm.com                        }});
6910338SCurtis.Dunham@arm.com                    }
7010338SCurtis.Dunham@arm.com
7110338SCurtis.Dunham@arm.com                    0x4: sllv({{ Rd = Rt.uw << Rs<4:0>; }});
7210338SCurtis.Dunham@arm.com
7310338SCurtis.Dunham@arm.com                    0x6: decode SRLV {
7410338SCurtis.Dunham@arm.com                        0: srlv({{ Rd = Rt.uw >> Rs<4:0>; }});
7510338SCurtis.Dunham@arm.com
7610338SCurtis.Dunham@arm.com                        //Hardcoded assuming 32-bit ISA, probably need parameter here
7710338SCurtis.Dunham@arm.com                        1: rotrv({{ Rd = (Rt.uw << (32 - Rs<4:0>)) | (Rt.uw >> Rs<4:0>);}});
7810338SCurtis.Dunham@arm.com                    }
7910338SCurtis.Dunham@arm.com
8010338SCurtis.Dunham@arm.com                    0x7: srav({{
8110338SCurtis.Dunham@arm.com                        int shift_amt = Rs<4:0>;
8210338SCurtis.Dunham@arm.com
8310338SCurtis.Dunham@arm.com                        uint32_t temp = Rt >> shift_amt;
8410338SCurtis.Dunham@arm.com
8510338SCurtis.Dunham@arm.com                        if ( (Rt & 0x80000000) > 0 ) {
86                                uint32_t mask = 0x80000000;
87                                for(int i=0; i < shift_amt; i++) {
88                                    temp |= mask;
89                                    mask = mask >> 1;
90                                }
91                            }
92
93                        Rd = temp;
94                    }});
95                }
96            }
97
98            0x1: decode FUNCTION_LO {
99
100                //Table A-3 Note: "Specific encodings of the hint field are used
101                //to distinguish JR from JR.HB and JALR from JALR.HB"
102                format Jump {
103                    0x0: decode HINT {
104                        0:jr({{ NNPC = Rs & ~1; }},IsReturn);
105
106                        1:jr_hb({{ NNPC = Rs & ~1; clear_exe_inst_hazards(); }},IsReturn);
107                    }
108
109                    0x1: decode HINT {
110                        0: jalr({{ Rd = NNPC; NNPC = Rs; }},IsCall,IsReturn);
111
112                        1: jalr_hb({{ Rd = NNPC; NNPC = Rs; clear_exe_inst_hazards();}},IsCall,IsReturn);
113                    }
114                }
115
116                format BasicOp {
117                    0x2: movz({{ if (Rt == 0) Rd = Rs; }});
118                    0x3: movn({{ if (Rt != 0) Rd = Rs; }});
119                }
120
121                format BasicOp {
122                    0x4: syscall({{ xc->syscall(R2); }},IsNonSpeculative);
123                    0x5: break({{ panic("Not implemented break yet"); }},IsNonSpeculative);
124                    0x7: sync({{  panic("Not implemented sync yet"); }},IsNonSpeculative);
125                }
126            }
127
128            0x2: decode FUNCTION_LO {
129                format BasicOp {
130                    0x0: mfhi({{ Rd = HI; }});
131                    0x1: mthi({{ HI = Rs; }});
132                    0x2: mflo({{ Rd = LO; }});
133                    0x3: mtlo({{ LO = Rs; }});
134                }
135            }
136
137            0x3: decode FUNCTION_LO {
138                format IntOp {
139                    0x0: mult({{
140                        int64_t temp1 = Rs.sd * Rt.sd;
141                        HI = temp1<63:32>;
142                        LO = temp1<31:0>;
143                    }});
144
145                    0x1: multu({{
146                        uint64_t temp1 = Rs.ud * Rt.ud;
147                        HI = temp1<63:32>;
148                        LO = temp1<31:0>;
149                    }});
150
151                    0x2: div({{
152                        HI = Rs.sd % Rt.sd;
153                        LO = Rs.sd / Rt.sd;
154                    }});
155
156                    0x3: divu({{
157                        HI = Rs.ud % Rt.ud;
158                        LO = Rs.ud / Rt.ud;
159                    }});
160                }
161            }
162
163            0x4: decode HINT {
164                0x0: decode FUNCTION_LO {
165                    format IntOp {
166                        0x0: add({{  Rd.sw = Rs.sw + Rt.sw; /*Trap on Overflow*/}});
167                        0x1: addu({{ Rd.sw = Rs.sw + Rt.sw;}});
168                        0x2: sub({{ Rd.sw = Rs.sw - Rt.sw;  /*Trap on Overflow*/}});
169                        0x3: subu({{ Rd.sw = Rs.sw - Rt.sw;}});
170                        0x4: and({{ Rd = Rs & Rt;}});
171                        0x5: or({{ Rd = Rs | Rt;}});
172                        0x6: xor({{ Rd = Rs ^ Rt;}});
173                        0x7: nor({{ Rd = ~(Rs | Rt);}});
174                    }
175                }
176            }
177
178            0x5: decode HINT {
179                0x0: decode FUNCTION_LO {
180                    format IntOp{
181                        0x2: slt({{  Rd.sw = ( Rs.sw < Rt.sw ) ? 1 : 0}});
182                        0x3: sltu({{ Rd.uw = ( Rs.uw < Rt.uw ) ? 1 : 0}});
183                    }
184                }
185            }
186
187            0x6: decode FUNCTION_LO {
188                format Trap {
189                    0x0: tge({{  cond = (Rs.sw >= Rt.sw); }});
190                    0x1: tgeu({{ cond = (Rs.uw >= Rt.uw); }});
191                    0x2: tlt({{ cond = (Rs.sw < Rt.sw); }});
192                    0x3: tltu({{ cond = (Rs.uw >= Rt.uw); }});
193                    0x4: teq({{ cond = (Rs.sw == Rt.sw); }});
194                    0x6: tne({{ cond = (Rs.sw != Rt.sw); }});
195                }
196            }
197        }
198
199        0x1: decode REGIMM_HI {
200            0x0: decode REGIMM_LO {
201                format Branch {
202                    0x0: bltz({{ cond = (Rs.sw < 0); }});
203                    0x1: bgez({{ cond = (Rs.sw >= 0); }});
204                }
205
206                format BranchLikely {
207                    0x2: bltzl({{ cond = (Rs.sw < 0); }});
208                    0x3: bgezl({{ cond = (Rs.sw >= 0); }});
209                }
210            }
211
212            0x1: decode REGIMM_LO {
213                format Trap {
214                    0x0: tgei( {{ cond = (Rs.sw >= INTIMM); }});
215                    0x1: tgeiu({{ cond = (Rs.uw >= INTIMM); }});
216                    0x2: tlti( {{ cond = (Rs.sw < INTIMM); }});
217                    0x3: tltiu({{ cond = (Rs.uw < INTIMM); }});
218                    0x4: teqi( {{ cond = (Rs.sw == INTIMM);}});
219                    0x6: tnei( {{ cond = (Rs.sw != INTIMM);}});
220                }
221            }
222
223            0x2: decode REGIMM_LO {
224                format Branch {
225                    0x0: bltzal({{ cond = (Rs.sw < 0); }}, IsCall,IsReturn);
226                    0x1: bgezal({{ cond = (Rs.sw >= 0); }}, IsCall,IsReturn);
227                }
228
229                format BranchLikely {
230                    0x2: bltzall({{ cond = (Rs.sw < 0); }}, IsCall, IsReturn);
231                    0x3: bgezall({{ cond = (Rs.sw >= 0); }}, IsCall, IsReturn);
232                }
233            }
234
235            0x3: decode REGIMM_LO {
236                format WarnUnimpl {
237                    0x7: synci();
238                }
239            }
240        }
241
242        format Jump {
243            0x2: j({{ NNPC = (NPC & 0xF0000000) | (JMPTARG << 2);}});
244
245            0x3: jal({{ NNPC = (NPC & 0xF0000000) | (JMPTARG << 2); }},IsCall,IsReturn);
246        }
247
248        format Branch {
249            0x4: beq({{ cond = (Rs.sw == Rt.sw); }});
250            0x5: bne({{ cond = (Rs.sw != Rt.sw); }});
251            0x6: decode RT {
252                0x0: blez({{ cond = (Rs.sw <= 0); }});
253            }
254
255            0x7: decode RT {
256                0x0: bgtz({{ cond = (Rs.sw > 0); }});
257            }
258        }
259    }
260
261    0x1: decode OPCODE_LO {
262        format IntOp {
263            0x0: addi({{ Rt.sw = Rs.sw + imm; /*Trap If Overflow*/}});
264            0x1: addiu({{ Rt.sw = Rs.sw + imm;}});
265            0x2: slti({{ Rt.sw = ( Rs.sw < imm) ? 1 : 0 }});
266            0x3: sltiu({{ Rt.uw = ( Rs.uw < (uint32_t)sextImm ) ? 1 : 0 }});
267            0x4: andi({{ Rt.sw = Rs.sw & zextImm;}});
268            0x5: ori({{ Rt.sw = Rs.sw | zextImm;}});
269            0x6: xori({{ Rt.sw = Rs.sw ^ zextImm;}});
270
271            0x7: decode RS {
272                0x0: lui({{ Rt = imm << 16}});
273            }
274        }
275    }
276
277    0x2: decode OPCODE_LO {
278
279        //Table A-11 MIPS32 COP0 Encoding of rs Field
280        0x0: decode RS_MSB {
281            0x0: decode RS {
282                format System {
283                    0x0: mfc0({{
284                        //uint64_t reg_num = Rd.uw;
285
286                        Rt = xc->readMiscReg(RD << 5 | SEL);
287                    }});
288
289                    0x4: mtc0({{
290                        //uint64_t reg_num = Rd.uw;
291
292                        xc->setMiscReg(RD << 5 | SEL,Rt);
293                    }});
294
295                    0x8: mftr({{
296                        //The contents of the coprocessor 0 register specified by the
297                        //combination of rd and sel are loaded into general register
298                        //rt. Note that not all coprocessor 0 registers support the
299                        //sel field. In those instances, the sel field must be zero.
300
301                        //MT Code Needed Here
302
303                    }});
304
305                    0xC: mttr({{
306                        //The contents of the coprocessor 0 register specified by the
307                        //combination of rd and sel are loaded into general register
308                        //rt. Note that not all coprocessor 0 registers support the
309                        //sel field. In those instances, the sel field must be zero.
310
311                        //MT Code Needed Here
312                    }});
313
314
315                    0xA: rdpgpr({{
316                        //Accessing Previous Shadow Set Register Number
317                        //uint64_t prev = xc->readMiscReg(SRSCtl)/*[PSS]*/;
318                        //uint64_t reg_num = Rt.uw;
319
320                        //Rd = xc->regs.IntRegFile[prev];
321                       //Rd = xc->shadowIntRegFile[prev][reg_num];
322                    }});
323
324                    0xB: decode RD {
325
326                        0x0: decode SC {
327                            0x0: dvpe({{
328                                Rt.sw = xc->readMiscReg(MVPControl);
329                                xc->setMiscReg(MVPControl,0);
330                            }});
331
332                            0x1: evpe({{
333                                Rt.sw = xc->readMiscReg(MVPControl);
334                                xc->setMiscReg(MVPControl,1);
335                            }});
336                        }
337
338                        0x1: decode SC {
339                            0x0: dmt({{
340                                Rt.sw = xc->readMiscReg(VPEControl);
341                                xc->setMiscReg(VPEControl,0);
342                            }});
343
344                            0x1: emt({{
345                                Rt.sw = xc->readMiscReg(VPEControl);
346                                xc->setMiscReg(VPEControl,1);
347                            }});
348                        }
349
350                        0xC: decode SC {
351                            0x0: di({{
352                                Rt.sw = xc->readMiscReg(Status);
353                                xc->setMiscReg(Status,0);
354                            }});
355
356                            0x1: ei({{
357                                Rt.sw = xc->readMiscReg(Status);
358                                xc->setMiscReg(Status,1);
359                            }});
360                        }
361                    }
362
363                    0xE: wrpgpr({{
364                        //Accessing Previous Shadow Set Register Number
365                        //uint64_t prev = xc->readMiscReg(SRSCtl/*[PSS]*/);
366                        //uint64_t reg_num = Rd.uw;
367
368                        //xc->regs.IntRegFile[prev];
369                        //xc->shadowIntRegFile[prev][reg_num] = Rt;
370                    }});
371                }
372            }
373
374            //Table A-12 MIPS32 COP0 Encoding of Function Field When rs=CO
375            0x1: decode FUNCTION {
376                format System {
377                    0x01: tlbr({{ }});
378                    0x02: tlbwi({{ }});
379                    0x06: tlbwr({{ }});
380                    0x08: tlbp({{ }});
381                }
382
383                format WarnUnimpl {
384                    0x18: eret();
385                    0x1F: deret();
386                    0x20: wait();
387                }
388            }
389        }
390
391        //Table A-13 MIPS32 COP1 Encoding of rs Field
392        0x1: decode RS_MSB {
393
394            0x0: decode RS_HI {
395                0x0: decode RS_LO {
396                    format FloatOp {
397                        0x0: mfc1 ({{ Rt.uw = Fs.uw<31:0>; }});
398                        0x3: mfhc1({{ Rt.uw = Fs.ud<63:32>;}});
399                        0x4: mtc1 ({{ Fs.uw = Rt.uw;       }});
400                        0x7: mthc1({{
401                             uint64_t fs_hi = Rt.uw;
402                             uint64_t fs_lo = Fs.ud & 0x0000FFFF;
403                             Fs.ud = fs_hi << 32 | fs_lo;
404                        }});
405                    }
406
407                    format System {
408                        0x2: cfc1({{
409                            switch (FS)
410                            {
411                              case 0:
412                                Rt = FIR;
413                                break;
414                              case 25:
415                                Rt = 0 | (FCSR & 0xFE000000) >> 24 | (FCSR & 0x00800000) >> 23;
416                                break;
417                              case 26:
418                                Rt = 0 | (FCSR & 0x0003F07C);
419                                break;
420                              case 28:
421                                Rt = 0 | (FCSR & 0x00000F80) | (FCSR & 0x01000000) >> 21 | (FCSR & 0x00000003);
422                                break;
423                              case 31:
424                                Rt = FCSR;
425                                break;
426                              default:
427                                panic("FP Control Value (%d) Not Available. Ignoring Access to"
428                                      "Floating Control Status Register",FS);
429                            }
430                        }});
431
432                        0x6: ctc1({{
433                            switch (FS)
434                            {
435                              case 25:
436                                FCSR = 0 | (Rt.uw<7:1> << 25) // move 31...25
437                                    | (FCSR & 0x01000000) // bit 24
438                                    | (FCSR & 0x004FFFFF);// bit 22...0
439                                break;
440
441                              case 26:
442                                FCSR = 0 | (FCSR & 0xFFFC0000) // move 31...18
443                                    | Rt.uw<17:12> << 12           // bit 17...12
444                                    | (FCSR & 0x00000F80) << 7// bit 11...7
445                                    | Rt.uw<6:2> << 2              // bit 6...2
446                                    | (FCSR & 0x00000002);     // bit 1...0
447                                break;
448
449                              case 28:
450                                FCSR = 0 | (FCSR & 0xFE000000) // move 31...25
451                                    | Rt.uw<2:2> << 24       // bit 24
452                                    | (FCSR & 0x00FFF000) << 23// bit 23...12
453                                    | Rt.uw<11:7> << 7       // bit 24
454                                    | (FCSR & 0x000007E)
455                                    | Rt.uw<1:0>;// bit 22...0
456                                break;
457
458                              case 31:
459                                FCSR  = Rt.uw;
460                                break;
461
462                              default:
463                                panic("FP Control Value (%d) Not Available. Ignoring Access to"
464                                      "Floating Control Status Register", FS);
465                            }
466                        }});
467                    }
468                }
469
470                0x1: decode ND {
471                    0x0: decode TF {
472                        format Branch {
473                            0x0: bc1f({{ cond = (getFPConditionCode(FCSR,CC) == 0); }});
474                            0x1: bc1t({{ cond = (getFPConditionCode(FCSR,CC) == 1); }});
475                        }
476                    }
477
478                    0x1: decode TF {
479                        format BranchLikely {
480                            0x0: bc1fl({{ cond = (getFPConditionCode(FCSR,CC) == 0); }});
481                            0x1: bc1tl({{ cond = (getFPConditionCode(FCSR,CC) == 1); }});
482                        }
483                    }
484                }
485            }
486
487            0x1: decode RS_HI {
488                0x2: decode RS_LO {
489
490                    //Table A-14 MIPS32 COP1 Encoding of Function Field When rs=S
491                    //(( single-word ))
492                    0x0: decode FUNCTION_HI {
493                        0x0: decode FUNCTION_LO {
494                            format FloatOp {
495                                0x0: add_s({{ Fd.sf = Fs.sf + Ft.sf;}});
496                                0x1: sub_s({{ Fd.sf = Fs.sf - Ft.sf;}});
497                                0x2: mul_s({{ Fd.sf = Fs.sf * Ft.sf;}});
498                                0x3: div_s({{ Fd.sf = Fs.sf / Ft.sf;}});
499                                0x4: sqrt_s({{ Fd.sf = sqrt(Fs.sf);}});
500                                0x5: abs_s({{ Fd.sf = fabs(Fs.sf);}});
501                                0x6: mov_s({{ Fd.sf = Fs.sf;}});
502                                0x7: neg_s({{ Fd.sf = -1 * Fs.sf;}});
503                            }
504                        }
505
506                        0x1: decode FUNCTION_LO {
507                            format Float64Op {
508                                0x0: round_l_s({{
509                                    Fd.ud = fpConvert(roundFP(Fs.sf,0), SINGLE_TO_LONG);
510                                }});
511
512                                0x1: trunc_l_s({{
513                                    Fd.ud = fpConvert(truncFP(Fs.sf), SINGLE_TO_LONG);
514                                }});
515
516                                0x2: ceil_l_s({{
517                                    Fd.ud = fpConvert(ceil(Fs.sf),  SINGLE_TO_LONG);
518                                }});
519
520                                0x3: floor_l_s({{
521                                    Fd.ud = fpConvert(floor(Fs.sf), SINGLE_TO_LONG);
522                                }});
523                            }
524
525                            format FloatOp {
526                                0x4: round_w_s({{
527                                    Fd.uw = fpConvert(roundFP(Fs.sf,0), SINGLE_TO_WORD);
528                                }});
529
530                                0x5: trunc_w_s({{
531                                    Fd.uw = fpConvert(truncFP(Fs.sf), SINGLE_TO_WORD);
532                                }});
533
534                                0x6: ceil_w_s({{
535                                    Fd.uw = fpConvert(ceil(Fs.sf),  SINGLE_TO_WORD);
536                                }});
537
538                                0x7: floor_w_s({{
539                                    Fd.uw = fpConvert(floor(Fs.sf), SINGLE_TO_WORD);
540                                }});
541                            }
542                        }
543
544                        0x2: decode FUNCTION_LO {
545                            0x1: decode MOVCF {
546                                format FloatOp {
547                                    0x0: movf_s({{if (getFPConditionCode(FCSR,CC) == 0) Fd = Fs;}});
548                                    0x1: movt_s({{if (getFPConditionCode(FCSR,CC) == 1) Fd = Fs;}});
549                                }
550                            }
551
552                            format FloatOp {
553                                0x2: movz_s({{ if (Rt == 0) Fd = Fs; }});
554                                0x3: movn_s({{ if (Rt != 0) Fd = Fs; }});
555                                0x5: recip_s({{ Fd = 1 / Fs; }});
556                                0x6: rsqrt_s({{ Fd = 1 / sqrt(Fs);}});
557                            }
558                        }
559
560                        0x4: decode FUNCTION_LO {
561
562                            format FloatConvertOp {
563                                0x1: cvt_d_s({{
564                                    Fd.ud = fpConvert(Fs.sf, SINGLE_TO_DOUBLE);
565                                }});
566
567                                0x4: cvt_w_s({{
568                                    Fd.uw = fpConvert(Fs.sf, SINGLE_TO_WORD);
569                                }});
570                            }
571
572                            format FloatConvertOp {
573                                0x5: cvt_l_s({{
574                                    Fd.ud = fpConvert(Fs.sf, SINGLE_TO_LONG);
575                                }});
576
577                                0x6: cvt_ps_st({{
578                                    Fd.ud = (uint64_t)Fs.uw << 32 | (uint64_t)Ft.uw;
579                                }});
580                            }
581                        }
582
583                        0x6: decode FUNCTION_LO {
584                            format FloatCompareOp {
585                                0x0: c_f_s({{ cond = 0; }});
586
587                                0x1: c_un_s({{
588                                    if (isnan(Fs.sf) || isnan(Ft.sf))
589                                        cond = 1;
590                                    else
591                                        cond = 0;
592                                }});
593
594                                0x2: c_eq_s({{
595                                    if (isnan(Fs.sf) || isnan(Ft.sf))
596                                        cond = 0;
597                                    else
598                                        cond = (Fs.sf == Ft.sf);
599                                }});
600
601                                0x3: c_ueq_s({{
602                                    if (isnan(Fs.sf) || isnan(Ft.sf))
603                                        cond = 1;
604                                    else
605                                        cond = (Fs.sf == Ft.sf);
606                                }});
607
608                                0x4: c_olt_s({{
609                                    if (isnan(Fs.sf) || isnan(Ft.sf))
610                                        cond = 0;
611                                    else
612                                        cond = (Fs.sf < Ft.sf);
613                                }});
614
615                                0x5: c_ult_s({{
616                                    if (isnan(Fs.sf) || isnan(Ft.sf))
617                                        cond = 1;
618                                    else
619                                        cond = (Fs.sf < Ft.sf);
620                                }});
621
622                                0x6: c_ole_s({{
623                                    if (isnan(Fs.sf) || isnan(Ft.sf))
624                                        cond = 0;
625                                    else
626                                        cond = (Fs.sf <= Ft.sf);
627                                }});
628
629                                0x7: c_ule_s({{
630                                    if (isnan(Fs.sf) || isnan(Ft.sf))
631                                        cond = 1;
632                                    else
633                                        cond = (Fs.sf <= Ft.sf);
634                                }});
635                            }
636                        }
637
638                        0x7: decode FUNCTION_LO {
639                            format FloatCompareWithXcptOp {
640                                0x0: c_sf_s({{ cond = 0; }});
641
642                                0x1: c_ngle_s({{
643                                    if (isnan(Fs.sf) || isnan(Ft.sf))
644                                        cond = 1;
645                                    else
646                                        cond = 0;
647                                  }});
648
649                                0x2: c_seq_s({{
650                                    if (isnan(Fs.sf) || isnan(Ft.sf))
651                                        cond = 0;
652                                    else
653                                        cond = (Fs.sf == Ft.sf);
654                                  }});
655
656                                0x3: c_ngl_s({{
657                                    if (isnan(Fs.sf) || isnan(Ft.sf))
658                                        cond = 1;
659                                    else
660                                        cond = (Fs.sf == Ft.sf);
661                                  }});
662
663                                0x4: c_lt_s({{
664                                    if (isnan(Fs.sf) || isnan(Ft.sf))
665                                        cond = 0;
666                                    else
667                                        cond = (Fs.sf < Ft.sf);
668                                  }});
669
670                                0x5: c_nge_s({{
671                                    if (isnan(Fs.sf) || isnan(Ft.sf))
672                                        cond = 1;
673                                    else
674                                        cond = (Fs.sf < Ft.sf);
675                                  }});
676
677                                0x6: c_le_s({{
678                                    if (isnan(Fs.sf) || isnan(Ft.sf))
679                                        cond = 0;
680                                    else
681                                        cond = (Fs.sf <= Ft.sf);
682                                  }});
683
684                                0x7: c_ngt_s({{
685                                    if (isnan(Fs.sf) || isnan(Ft.sf))
686                                        cond = 1;
687                                    else
688                                        cond = (Fs.sf <= Ft.sf);
689                                  }});
690                            }
691                        }
692                    }
693
694                    //Table A-15 MIPS32 COP1 Encoding of Function Field When rs=D
695                    0x1: decode FUNCTION_HI {
696                        0x0: decode FUNCTION_LO {
697                            format FloatOp {
698                                0x0: add_d({{ Fd.df = Fs.df + Ft.df;}});
699                                0x1: sub_d({{ Fd.df = Fs.df - Ft.df;}});
700                                0x2: mul_d({{ Fd.df = Fs.df * Ft.df;}});
701                                0x3: div_d({{ Fd.df = Fs.df / Ft.df;}});
702                                0x4: sqrt_d({{ Fd.df = sqrt(Fs.df);}});
703                                0x5: abs_d({{ Fd.df = fabs(Fs.df);}});
704                                0x6: mov_d({{ Fd.ud = Fs.ud;}});
705                                0x7: neg_d({{ Fd.df = -1 * Fs.df;}});
706                            }
707                        }
708
709                        0x1: decode FUNCTION_LO {
710                            format FloatOp {
711                                0x0: round_l_d({{
712                                    Fd.ud = fpConvert(roundFP(Fs.df,0), DOUBLE_TO_LONG);
713                                }});
714
715                                0x1: trunc_l_d({{
716                                    Fd.ud = fpConvert(truncFP(Fs.df), DOUBLE_TO_LONG);
717                                }});
718
719                                0x2: ceil_l_d({{
720                                    Fd.ud = fpConvert(ceil(Fs.df), DOUBLE_TO_LONG);
721                                }});
722
723                                0x3: floor_l_d({{
724                                    Fd.ud = fpConvert(floor(Fs.df), DOUBLE_TO_LONG);
725                                }});
726                            }
727
728                            format FloatOp {
729                                0x4: round_w_d({{
730                                    Fd.uw = fpConvert(roundFP(Fs.df,0), DOUBLE_TO_WORD);
731                                }});
732
733                                0x5: trunc_w_d({{
734                                    Fd.uw = fpConvert(truncFP(Fs.df), DOUBLE_TO_WORD);
735                                }});
736
737                                0x6: ceil_w_d({{
738                                    Fd.uw = fpConvert(ceil(Fs.df), DOUBLE_TO_WORD);
739                                }});
740
741                                0x7: floor_w_d({{
742                                    Fd.uw = fpConvert(floor(Fs.df), DOUBLE_TO_WORD);
743                                }});
744                            }
745                        }
746
747                        0x2: decode FUNCTION_LO {
748                            0x1: decode MOVCF {
749                                format FloatOp {
750                                    0x0: movf_d({{if (getFPConditionCode(FCSR,CC) == 0) Fd.df = Fs.df; }});
751                                    0x1: movt_d({{if (getFPConditionCode(FCSR,CC) == 1) Fd.df = Fs.df; }});
752                                }
753                            }
754
755                            format BasicOp {
756                                0x2: movz_d({{ if (Rt == 0) Fd.df = Fs.df; }});
757                                0x3: movn_d({{ if (Rt != 0) Fd.df = Fs.df; }});
758                            }
759
760                            format FloatOp {
761                                0x5: recip_d({{ Fd.df = 1 / Fs.df}});
762                                0x6: rsqrt_d({{ Fd.df = 1 / sqrt(Fs.df) }});
763                            }
764                        }
765
766                        0x4: decode FUNCTION_LO {
767                            format FloatOp {
768                                0x0: cvt_s_d({{
769                                    Fd.uw = fpConvert(Fs.df, DOUBLE_TO_SINGLE);
770                                }});
771
772                                0x4: cvt_w_d({{
773                                    Fd.uw = fpConvert(Fs.df, DOUBLE_TO_WORD);
774                                }});
775
776                                0x5: cvt_l_d({{
777                                    Fd.ud = fpConvert(Fs.df, DOUBLE_TO_LONG);
778                                }});
779                            }
780                        }
781
782                        0x6: decode FUNCTION_LO {
783                            format FloatCompareOp {
784                                0x0: c_f_d({{ cond = 0; }});
785
786                                0x1: c_un_d({{
787                                    if (isnan(Fs.df) || isnan(Ft.df))
788                                        cond = 1;
789                                    else
790                                        cond = 0;
791                                }});
792
793                                0x2: c_eq_d({{
794                                    if (isnan(Fs.df) || isnan(Ft.df))
795                                        cond = 0;
796                                    else
797                                        cond = (Fs.df == Ft.df);
798                                }});
799
800                                0x3: c_ueq_d({{
801                                    if (isnan(Fs.df) || isnan(Ft.df))
802                                        cond = 1;
803                                    else
804                                        cond = (Fs.df == Ft.df);
805                                }});
806
807                                0x4: c_olt_d({{
808                                    if (isnan(Fs.df) || isnan(Ft.df))
809                                        cond = 0;
810                                    else
811                                        cond = (Fs.df < Ft.df);
812                                }});
813
814                                0x5: c_ult_d({{
815                                    if (isnan(Fs.df) || isnan(Ft.df))
816                                        cond = 1;
817                                    else
818                                        cond = (Fs.df < Ft.df);
819                                }});
820
821                                0x6: c_ole_d({{
822                                    if (isnan(Fs.df) || isnan(Ft.df))
823                                        cond = 0;
824                                    else
825                                        cond = (Fs.df <= Ft.df);
826                                }});
827
828                                0x7: c_ule_d({{
829                                    if (isnan(Fs.df) || isnan(Ft.df))
830                                        cond = 1;
831                                    else
832                                        cond = (Fs.df <= Ft.df);
833                                }});
834                            }
835                        }
836
837                        0x7: decode FUNCTION_LO {
838                            format FloatCompareWithXcptOp {
839                                0x0: c_sf_d({{ cond = 0; }});
840
841                                0x1: c_ngle_d({{
842                                    if (isnan(Fs.df) || isnan(Ft.df))
843                                        cond = 1;
844                                    else
845                                        cond = 0;
846                                  }});
847
848                                0x2: c_seq_d({{
849                                    if (isnan(Fs.df) || isnan(Ft.df))
850                                        cond = 0;
851                                    else
852                                        cond = (Fs.df == Ft.df);
853                                  }});
854
855                                0x3: c_ngl_d({{
856                                    if (isnan(Fs.df) || isnan(Ft.df))
857                                        cond = 1;
858                                    else
859                                        cond = (Fs.df == Ft.df);
860                                  }});
861
862                                0x4: c_lt_d({{
863                                    if (isnan(Fs.df) || isnan(Ft.df))
864                                        cond = 0;
865                                    else
866                                        cond = (Fs.df < Ft.df);
867                                  }});
868
869                                0x5: c_nge_d({{
870                                    if (isnan(Fs.df) || isnan(Ft.df))
871                                        cond = 1;
872                                    else
873                                        cond = (Fs.df < Ft.df);
874                                  }});
875
876                                0x6: c_le_d({{
877                                    if (isnan(Fs.df) || isnan(Ft.df))
878                                        cond = 0;
879                                    else
880                                        cond = (Fs.df <= Ft.df);
881                                  }});
882
883                                0x7: c_ngt_d({{
884                                    if (isnan(Fs.df) || isnan(Ft.df))
885                                        cond = 1;
886                                    else
887                                        cond = (Fs.df <= Ft.df);
888                                  }});
889                            }
890                        }
891                    }
892
893                    //Table A-16 MIPS32 COP1 Encoding of Function Field When rs=W
894                    0x4: decode FUNCTION {
895                        format FloatConvertOp {
896                            0x20: cvt_s_w({{
897                                Fd.uw = fpConvert(Fs.sf, WORD_TO_SINGLE);
898                            }});
899
900                            0x21: cvt_d_w({{
901                                Fd.ud = fpConvert(Fs.sf, WORD_TO_DOUBLE);
902                            }});
903                        }
904
905                        format Float64ConvertOp {
906                            0x26: cvt_ps_pw({{
907                                Fd.ud = fpConvert(Fs.ud, WORD_TO_PS);
908                            }});
909                        }
910                    }
911
912                    //Table A-16 MIPS32 COP1 Encoding of Function Field When rs=L1
913                    //Note: "1. Format type L is legal only if 64-bit floating point operations
914                    //are enabled."
915                    0x5: decode FUNCTION_HI {
916                        format Float64ConvertOp {
917                            0x20: cvt_s_l({{
918                                Fd.uw = fpConvert(Fs.ud, LONG_TO_SINGLE);
919                            }});
920
921                            0x21: cvt_d_l({{
922                                Fd.ud = fpConvert(Fs.ud, LONG_TO_DOUBLE);
923                            }});
924
925                            0x26: cvt_ps_l({{
926                                Fd.ud = fpConvert(Fs.ud, LONG_TO_PS);
927                            }});
928                        }
929                    }
930
931                    //Table A-17 MIPS64 COP1 Encoding of Function Field When rs=PS1
932                    //Note: "1. Format type PS is legal only if 64-bit floating point operations
933                    //are enabled. "
934                    0x6: decode FUNCTION_HI {
935                        0x0: decode FUNCTION_LO {
936                            format Float64Op {
937                                0x0: add_ps({{
938                                    Fd1.sf = Fs1.sf + Ft2.sf;
939                                    Fd2.sf = Fs2.sf + Ft2.sf;
940                                }});
941
942                                0x1: sub_ps({{
943                                    Fd1.sf = Fs1.sf - Ft2.sf;
944                                    Fd2.sf = Fs2.sf - Ft2.sf;
945                                }});
946
947                                0x2: mul_ps({{
948                                    Fd1.sf = Fs1.sf * Ft2.sf;
949                                    Fd2.sf = Fs2.sf * Ft2.sf;
950                                }});
951
952                                0x5: abs_ps({{
953                                    Fd1.sf = fabs(Fs1.sf);
954                                    Fd2.sf = fabs(Fs2.sf);
955                                }});
956
957                                0x6: mov_ps({{
958                                    Fd1.sf = Fs1.sf;
959                                    Fd2.sf = Fs2.sf;
960                                }});
961
962                                0x7: neg_ps({{
963                                    Fd1.sf = -1 * Fs1.sf;
964                                    Fd2.sf = -1 * Fs2.sf;
965                                }});
966                            }
967                        }
968
969                        0x2: decode FUNCTION_LO {
970                            0x1: decode MOVCF {
971                                format Float64Op {
972                                    0x0: movf_ps({{
973                                        if (getFPConditionCode(FCSR, CC) == 0)
974                                            Fd1 = Fs1;
975                                        if (getFPConditionCode(FCSR, CC+1) == 0)
976                                            Fd2 = Fs2;
977                                    }});
978
979                                    0x1: movt_ps({{
980                                        if (getFPConditionCode(FCSR, CC) == 1)
981                                            Fd1 = Fs1;
982                                        if (getFPConditionCode(FCSR, CC+1) == 1)
983                                            Fd2 = Fs2;
984                                    }});
985                                }
986                            }
987
988                            format Float64Op {
989                                0x2: movz_ps({{
990                                    if (getFPConditionCode(FCSR, CC) == 0)
991                                        Fd1 = Fs1;
992                                    if (getFPConditionCode(FCSR, CC) == 0)
993                                        Fd2 = Fs2;
994                                }});
995
996                                0x3: movn_ps({{
997                                    if (getFPConditionCode(FCSR, CC) == 1)
998                                        Fd1 = Fs1;
999                                    if (getFPConditionCode(FCSR, CC) == 1)
1000                                        Fd2 = Fs2;
1001                                }});
1002                            }
1003
1004                        }
1005
1006                        0x4: decode FUNCTION_LO {
1007                            0x0: Float64Op::cvt_s_pu({{
1008                                Fd.uw = fpConvert(Fs2.uw, PU_TO_SINGLE);
1009                            }});
1010                        }
1011
1012                        0x5: decode FUNCTION_LO {
1013                            format Float64Op {
1014                                0x0: cvt_s_pl({{
1015                                    Fd.uw = fpConvert(Fs1.uw, PL_TO_SINGLE);
1016                                }});
1017
1018                                0x4: pll({{ Fd.ud = (uint64_t) Fs1.uw << 32 | Ft1.uw; }});
1019                                0x5: plu({{ Fd.ud = (uint64_t) Fs1.uw << 32 | Ft2.uw; }});
1020                                0x6: pul({{ Fd.ud = (uint64_t) Fs2.uw << 32 | Ft1.uw; }});
1021                                0x7: puu({{ Fd.ud = (uint64_t) Fs2.uw << 32 | Ft2.uw; }});
1022                            }
1023                        }
1024
1025                        0x6: decode FUNCTION_LO {
1026                            format FloatPSCompareOp {
1027                                0x0: c_f_ps({{ cond1 = 0; cond2 = 0; }});
1028
1029                                0x1: c_un_ps({{
1030                                    if (isnan(Fs1.sf) || isnan(Ft1.sf))
1031                                        cond1 = 1;
1032                                    else
1033                                        cond1 = 0;
1034
1035                                    if (isnan(Fs2.sf) || isnan(Ft2.sf))
1036                                        cond2 = 1;
1037                                    else
1038                                        cond2 = 0;
1039
1040                                }});
1041
1042                                0x2: c_eq_ps({{
1043                                    if (isnan(Fs1.sf) || isnan(Ft1.sf))
1044                                        cond1 = 0;
1045                                    else
1046                                        cond1 = (Fs1.sf == Ft1.sf);
1047
1048                                    if (isnan(Fs2.sf) || isnan(Ft2.sf))
1049                                        cond2 = 0;
1050                                    else
1051                                        cond2 = (Fs2.sf == Ft2.sf);
1052                                }});
1053
1054                                0x3: c_ueq_ps({{
1055                                    if (isnan(Fs1.sf) || isnan(Ft1.sf))
1056                                        cond1 = 1;
1057                                    else
1058                                        cond1 = (Fs1.sf == Ft1.sf);
1059
1060                                    if (isnan(Fs2.sf) || isnan(Ft2.sf))
1061                                        cond2 = 1;
1062                                    else
1063                                        cond2 = (Fs2.sf == Ft2.sf);
1064                                }});
1065
1066                                0x4: c_olt_ps({{
1067                                    if (isnan(Fs1.sf) || isnan(Ft1.sf))
1068                                        cond1 = 0;
1069                                    else
1070                                        cond1 = (Fs1.sf < Ft1.sf);
1071
1072                                    if (isnan(Fs2.sf) || isnan(Ft2.sf))
1073                                        cond2 = 0;
1074                                    else
1075                                        cond2 = (Fs2.sf < Ft2.sf);
1076                                }});
1077
1078                                0x5: c_ult_ps({{
1079                                    if (isnan(Fs1.sf) || isnan(Ft1.sf))
1080                                        cond1 = 1;
1081                                    else
1082                                        cond1 = (Fs.sf < Ft.sf);
1083
1084                                    if (isnan(Fs2.sf) || isnan(Ft2.sf))
1085                                        cond2 = 1;
1086                                    else
1087                                        cond2 = (Fs2.sf < Ft2.sf);
1088                                }});
1089
1090                                0x6: c_ole_ps({{
1091                                    if (isnan(Fs.sf) || isnan(Ft.sf))
1092                                        cond1 = 0;
1093                                    else
1094                                        cond1 = (Fs.sf <= Ft.sf);
1095
1096                                    if (isnan(Fs2.sf) || isnan(Ft2.sf))
1097                                        cond2 = 0;
1098                                    else
1099                                        cond2 = (Fs2.sf <= Ft2.sf);
1100                                }});
1101
1102                                0x7: c_ule_ps({{
1103                                    if (isnan(Fs1.sf) || isnan(Ft1.sf))
1104                                        cond1 = 1;
1105                                    else
1106                                        cond1 = (Fs1.sf <= Ft1.sf);
1107
1108                                    if (isnan(Fs2.sf) || isnan(Ft2.sf))
1109                                        cond2 = 1;
1110                                    else
1111                                        cond2 = (Fs2.sf <= Ft2.sf);
1112                                }});
1113                            }
1114                        }
1115
1116                        0x7: decode FUNCTION_LO {
1117                            format FloatPSCompareWithXcptOp {
1118                                0x0: c_sf_ps({{ cond1 = 0; cond2 = 0; }});
1119
1120                                0x1: c_ngle_ps({{
1121                                    if (isnan(Fs1.sf) || isnan(Ft1.sf))
1122                                        cond1 = 1;
1123                                    else
1124                                        cond1 = 0;
1125
1126                                    if (isnan(Fs2.sf) || isnan(Ft2.sf))
1127                                        cond2 = 1;
1128                                    else
1129                                        cond2 = 0;
1130                                  }});
1131
1132                                0x2: c_seq_ps({{
1133                                    if (isnan(Fs1.sf) || isnan(Ft1.sf))
1134                                        cond1 = 0;
1135                                    else
1136                                        cond1 = (Fs1.sf == Ft1.sf);
1137
1138                                    if (isnan(Fs2.sf) || isnan(Ft2.sf))
1139                                        cond2 = 0;
1140                                    else
1141                                        cond2 = (Fs2.sf == Ft2.sf);
1142                                  }});
1143
1144                                0x3: c_ngl_ps({{
1145                                    if (isnan(Fs1.sf) || isnan(Ft1.sf))
1146                                        cond1 = 1;
1147                                    else
1148                                        cond1 = (Fs1.sf == Ft1.sf);
1149
1150                                    if (isnan(Fs2.sf) || isnan(Ft2.sf))
1151                                        cond2 = 1;
1152                                    else
1153                                        cond2 = (Fs2.sf == Ft2.sf);
1154                                  }});
1155
1156                                0x4: c_lt_ps({{
1157                                    if (isnan(Fs1.sf) || isnan(Ft1.sf))
1158                                        cond1 = 0;
1159                                    else
1160                                        cond1 = (Fs1.sf < Ft1.sf);
1161
1162                                    if (isnan(Fs2.sf) || isnan(Ft2.sf))
1163                                        cond2 = 0;
1164                                    else
1165                                        cond2 = (Fs2.sf < Ft2.sf);
1166                                  }});
1167
1168                                0x5: c_nge_ps({{
1169                                    if (isnan(Fs1.sf) || isnan(Ft1.sf))
1170                                        cond1 = 1;
1171                                    else
1172                                        cond1 = (Fs1.sf < Ft1.sf);
1173
1174                                    if (isnan(Fs2.sf) || isnan(Ft2.sf))
1175                                        cond2 = 1;
1176                                    else
1177                                        cond2 = (Fs2.sf < Ft2.sf);
1178                                  }});
1179
1180                                0x6: c_le_ps({{
1181                                    if (isnan(Fs1.sf) || isnan(Ft1.sf))
1182                                        cond1 = 0;
1183                                    else
1184                                        cond1 = (Fs1.sf <= Ft1.sf);
1185
1186                                    if (isnan(Fs2.sf) || isnan(Ft2.sf))
1187                                        cond2 = 0;
1188                                    else
1189                                        cond2 = (Fs2.sf <= Ft2.sf);
1190                                  }});
1191
1192                                0x7: c_ngt_ps({{
1193                                    if (isnan(Fs1.sf) || isnan(Ft1.sf))
1194                                        cond1 = 1;
1195                                    else
1196                                        cond1 = (Fs1.sf <= Ft1.sf);
1197
1198                                    if (isnan(Fs2.sf) || isnan(Ft2.sf))
1199                                        cond2 = 1;
1200                                    else
1201                                        cond2 = (Fs2.sf <= Ft2.sf);
1202                                  }});
1203                            }
1204                        }
1205                    }
1206                }
1207            }
1208        }
1209
1210        //Table A-19 MIPS32 COP2 Encoding of rs Field
1211        0x2: decode RS_MSB {
1212            0x0: decode RS_HI {
1213                0x0: decode RS_LO {
1214                    format WarnUnimpl {
1215                        0x0: mfc2();
1216                        0x2: cfc2();
1217                        0x3: mfhc2();
1218                        0x4: mtc2();
1219                        0x6: ctc2();
1220                        0x7: mftc2();
1221                    }
1222                }
1223
1224                0x1: decode ND {
1225                    0x0: decode TF {
1226                        format WarnUnimpl {
1227                            0x0: bc2f();
1228                            0x1: bc2t();
1229                        }
1230                    }
1231
1232                    0x1: decode TF {
1233                        format WarnUnimpl {
1234                            0x0: bc2fl();
1235                            0x1: bc2tl();
1236                        }
1237                    }
1238                }
1239            }
1240        }
1241
1242        //Table A-20 MIPS64 COP1X Encoding of Function Field 1
1243        //Note: "COP1X instructions are legal only if 64-bit floating point
1244        //operations are enabled."
1245        0x3: decode FUNCTION_HI {
1246            0x0: decode FUNCTION_LO {
1247                format LoadFloatMemory {
1248                    0x0: lwxc1({{ Ft.uw = Mem.uw;}}, {{ EA = Rs + Rt; }});
1249                    0x1: ldxc1({{ Ft.ud = Mem.ud;}}, {{ EA = Rs + Rt; }});
1250                    0x5: luxc1({{ Ft.uw = Mem.ud;}}, {{ EA = Rs + Rt; }});
1251                }
1252            }
1253
1254            0x1: decode FUNCTION_LO {
1255                format StoreFloatMemory {
1256                    0x0: swxc1({{ Mem.uw = Ft.uw;}}, {{ EA = Rs + Rt; }});
1257                    0x1: sdxc1({{ Mem.ud = Ft.ud;}}, {{ EA = Rs + Rt; }});
1258                    0x5: suxc1({{ Mem.ud = Ft.ud;}}, {{ EA = Rs + Rt; }});
1259                }
1260
1261                0x7: WarnUnimpl::prefx();
1262            }
1263
1264            format FloatOp {
1265                0x3: WarnUnimpl::alnv_ps();
1266
1267                format BasicOp {
1268                    0x4: decode FUNCTION_LO {
1269                        0x0: madd_s({{ Fd.sf = (Fs.sf * Ft.sf) + Fr.sf; }});
1270                        0x1: madd_d({{ Fd.df = (Fs.df * Ft.df) + Fr.df; }});
1271                        0x6: madd_ps({{
1272                            Fd1.sf = (Fs1.df * Ft1.df) + Fr1.df;
1273                            Fd2.sf = (Fs2.df * Ft2.df) + Fr2.df;
1274                        }});
1275                    }
1276
1277                    0x5: decode FUNCTION_LO {
1278                        0x0: msub_s({{ Fd.sf = (Fs.sf * Ft.sf) - Fr.sf; }});
1279                        0x1: msub_d({{ Fd.df = (Fs.df * Ft.df) - Fr.df; }});
1280                        0x6: msub_ps({{
1281                            Fd1.sf = (Fs1.df * Ft1.df) - Fr1.df;
1282                            Fd2.sf = (Fs2.df * Ft2.df) - Fr2.df;
1283                        }});
1284                    }
1285
1286                    0x6: decode FUNCTION_LO {
1287                        0x0: nmadd_s({{ Fd.sf = (-1 * Fs.sf * Ft.sf) - Fr.sf; }});
1288                        0x1: nmadd_d({{ Fd.df = (-1 * Fs.df * Ft.df) + Fr.df; }});
1289                        0x6: nmadd_ps({{
1290                            Fd1.sf = -1 * ((Fs1.df * Ft1.df) + Fr1.df);
1291                            Fd2.sf = -1 * ((Fs2.df * Ft2.df) + Fr2.df);
1292                        }});
1293                    }
1294
1295                    0x7: decode FUNCTION_LO {
1296                        0x0: nmsub_s({{ Fd.sf = (-1 * Fs.sf * Ft.sf) - Fr.sf; }});
1297                        0x1: nmsub_d({{ Fd.df = (-1 * Fs.df * Ft.df) - Fr.df; }});
1298                        0x6: nmsub_ps({{
1299                            Fd1.sf = -1 * ((Fs1.df * Ft1.df) - Fr1.df);
1300                            Fd2.sf = -1 * ((Fs2.df * Ft2.df) - Fr2.df);
1301                        }});
1302                    }
1303                }
1304            }
1305        }
1306
1307        format BranchLikely {
1308            0x4: beql({{ cond = (Rs.sw == 0); }});
1309            0x5: bnel({{ cond = (Rs.sw != 0); }});
1310            0x6: blezl({{ cond = (Rs.sw <= 0); }});
1311            0x7: bgtzl({{ cond = (Rs.sw > 0); }});
1312        }
1313    }
1314
1315    0x3: decode OPCODE_LO default FailUnimpl::reserved() {
1316
1317        //Table A-5 MIPS32 SPECIAL2 Encoding of Function Field
1318        0x4: decode FUNCTION_HI {
1319
1320            0x0: decode FUNCTION_LO {
1321                format IntOp {
1322                    0x0: madd({{
1323                        int64_t temp1 = (int64_t) HI << 32 | LO;
1324                        temp1 = temp1 + (Rs.sw * Rt.sw);
1325                        HI = temp1<63:32>;
1326                        LO = temp1<31:0>;
1327                    }});
1328
1329                    0x1: maddu({{
1330                        int64_t temp1 = (int64_t) HI << 32 | LO;
1331                        temp1 = temp1 + (Rs.uw * Rt.uw);
1332                        HI = temp1<63:32>;
1333                        LO = temp1<31:0>;
1334                    }});
1335
1336                    0x2: mul({{ Rd.sw = Rs.sw * Rt.sw; 	}});
1337
1338                    0x4: msub({{
1339                        int64_t temp1 = (int64_t) HI << 32 | LO;
1340                        temp1 = temp1 - (Rs.sw * Rt.sw);
1341                        HI = temp1<63:32>;
1342                        LO = temp1<31:0>;
1343                    }});
1344
1345                    0x5: msubu({{
1346                        int64_t temp1 = (int64_t) HI << 32 | LO;
1347                        temp1 = temp1 - (Rs.uw * Rt.uw);
1348                        HI = temp1<63:32>;
1349                        LO = temp1<31:0>;
1350                    }});
1351                }
1352            }
1353
1354            0x4: decode FUNCTION_LO {
1355                format BasicOp {
1356                    0x0: clz({{
1357                        int cnt = 0;
1358                        uint32_t mask = 0x80000000;
1359                        for (int i=0; i < 32; i++) {
1360                            if( (Rs & mask) == 0) {
1361                                cnt++;
1362                            } else {
1363                                break;
1364                            }
1365                        }
1366                        Rd.uw = cnt;
1367                    }});
1368
1369                    0x1: clo({{
1370                        int cnt = 0;
1371                        uint32_t mask = 0x80000000;
1372                        for (int i=0; i < 32; i++) {
1373                            if( (Rs & mask) != 0) {
1374                                cnt++;
1375                            } else {
1376                                break;
1377                            }
1378                        }
1379                        Rd.uw = cnt;
1380                    }});
1381                }
1382            }
1383
1384            0x7: decode FUNCTION_LO {
1385                0x7: WarnUnimpl::sdbbp();
1386            }
1387        }
1388
1389        //Table A-6 MIPS32 SPECIAL3 Encoding of Function Field for Release 2 of the Architecture
1390        0x7: decode FUNCTION_HI {
1391
1392            0x0: decode FUNCTION_LO {
1393                format FailUnimpl {
1394                    0x1: ext();
1395                    0x4: ins();
1396                }
1397            }
1398
1399            0x1: decode FUNCTION_LO {
1400                format FailUnimpl {
1401                    0x0: fork();
1402                    0x1: yield();
1403                }
1404            }
1405
1406
1407            //Table A-10 MIPS32 BSHFL Encoding of sa Field
1408            0x4: decode SA {
1409
1410                0x02: FailUnimpl::wsbh();
1411
1412                format BasicOp {
1413                    0x10: seb({{ Rd.sw = Rt.sw<7:0>}});
1414                    0x18: seh({{ Rd.sw = Rt.sw<15:0>}});
1415                }
1416            }
1417
1418            0x6: decode FUNCTION_LO {
1419                0x7: FailUnimpl::rdhwr();//{{ /*Rt = xc->hwRegs[RD];*/ }}
1420            }
1421        }
1422    }
1423
1424    0x4: decode OPCODE_LO default FailUnimpl::reserved() {
1425        format LoadMemory {
1426            0x0: lb({{ Rt.sw = Mem.sb; }});
1427            0x1: lh({{ Rt.sw = Mem.sh; }});
1428
1429            0x2: lwl({{
1430                uint32_t mem_word = Mem.uw;
1431                uint32_t unalign_addr = Rs + disp;
1432                uint32_t offset = unalign_addr & 0x00000003;
1433#if BYTE_ORDER == BIG_ENDIAN
1434                switch(offset)
1435                {
1436                  case 0:
1437                    Rt = mem_word;
1438                    break;
1439
1440                  case 1:
1441                    Rt &= 0x000F;
1442                    Rt |= (mem_word << 4);
1443                    break;
1444
1445                  case 2:
1446                    Rt &= 0x00FF;
1447                    Rt |= (mem_word << 8);
1448                    break;
1449
1450                  case 3:
1451                    Rt &= 0x0FFF;
1452                    Rt |= (mem_word << 12);
1453                    break;
1454
1455                  default:
1456                    panic("lwl: bad offset");
1457                }
1458#elif BYTE_ORDER == LITTLE_ENDIAN
1459                switch(offset)
1460                {
1461                  case 0:
1462                    Rt &= 0x0FFF;
1463                    Rt |= (mem_word << 12);
1464                    break;
1465
1466                  case 1:
1467                    Rt &= 0x00FF;
1468                    Rt |= (mem_word << 8);
1469                    break;
1470
1471                  case 2:
1472                    Rt &= 0x000F;
1473                    Rt |= (mem_word << 4);
1474                    break;
1475
1476                  case 3:
1477                    Rt = mem_word;
1478                    break;
1479
1480                  default:
1481                    panic("lwl: bad offset");
1482                }
1483#endif
1484            }}, {{ EA = (Rs + disp) & ~3; }});
1485
1486            0x3: lw({{ Rt.sw = Mem.sw; }});
1487            0x4: lbu({{ Rt.uw = Mem.ub; }});
1488            0x5: lhu({{ Rt.uw = Mem.uh; }});
1489            0x6: lwr({{
1490                uint32_t mem_word = Mem.uw;
1491                uint32_t unalign_addr = Rs + disp;
1492                uint32_t offset = unalign_addr & 0x00000003;
1493
1494#if BYTE_ORDER == BIG_ENDIAN
1495                switch(offset)
1496                {
1497                  case 0: Rt &= 0xFFF0;  Rt |= (mem_word >> 12); break;
1498                  case 1: Rt &= 0xFF00;  Rt |= (mem_word >> 8);  break;
1499                  case 2: Rt &= 0xF000;  Rt |= (mem_word >> 4);  break;
1500                  case 3: Rt = mem_word; break;
1501                  default: panic("lwr: bad offset");
1502                }
1503#elif BYTE_ORDER == LITTLE_ENDIAN
1504                switch(offset)
1505                {
1506                  case 0: Rt = mem_word; break;
1507                  case 1: Rt &= 0xF000;  Rt |= (mem_word >> 4);  break;
1508                  case 2: Rt &= 0xFF00;  Rt |= (mem_word >> 8);  break;
1509                  case 3: Rt &= 0xFFF0;  Rt |= (mem_word >> 12); break;
1510                  default: panic("lwr: bad offset");
1511                }
1512#endif
1513            }},
1514            {{ EA = (Rs + disp) & ~3; }});
1515        }
1516    }
1517
1518    0x5: decode OPCODE_LO default FailUnimpl::reserved() {
1519        format StoreMemory {
1520            0x0: sb({{ Mem.ub = Rt<7:0>; }});
1521            0x1: sh({{ Mem.uh = Rt<15:0>; }});
1522            0x2: swl({{
1523                uint32_t mem_word = 0;
1524                uint32_t aligned_addr = (Rs + disp) & ~3;
1525                uint32_t unalign_addr = Rs + disp;
1526                uint32_t offset = unalign_addr & 0x00000003;
1527
1528                DPRINTF(IEW,"Execute: aligned=0x%x unaligned=0x%x\n offset=0x%x",
1529                        aligned_addr,unalign_addr,offset);
1530
1531                fault = xc->read(aligned_addr, (uint32_t&)mem_word, memAccessFlags);
1532
1533#if BYTE_ORDER == BIG_ENDIAN
1534                switch(offset)
1535                {
1536                  case 0:
1537                    Mem = Rt;
1538                    break;
1539
1540                  case 1:
1541                    mem_word &= 0xF000;
1542                    mem_word |= (Rt >> 4);
1543                    Mem = mem_word;
1544                    break;
1545
1546                  case 2:
1547                    mem_word &= 0xFF00;
1548                    mem_word |= (Rt >> 8);
1549                    Mem = mem_word;
1550                    break;
1551
1552                  case 3:
1553                    mem_word &= 0xFFF0;
1554                    mem_word |= (Rt >> 12);
1555                    Mem = mem_word;
1556                   break;
1557
1558                  default:
1559                    panic("swl: bad offset");
1560                }
1561#elif BYTE_ORDER == LITTLE_ENDIAN
1562                switch(offset)
1563                {
1564                  case 0:
1565                    mem_word &= 0xFFF0;
1566                    mem_word |= (Rt >> 12);
1567                    Mem = mem_word;
1568                    break;
1569
1570                  case 1:
1571                    mem_word &= 0xFF00;
1572                    mem_word |= (Rt >> 8);
1573                    Mem = mem_word;
1574                    break;
1575
1576                  case 2:
1577                    mem_word &= 0xF000;
1578                    mem_word |= (Rt >> 4);
1579                    Mem = mem_word;
1580                    break;
1581
1582                  case 3:
1583                    Mem = Rt;
1584                   break;
1585
1586                  default:
1587                    panic("swl: bad offset");
1588                }
1589#endif
1590            }},{{ EA = (Rs + disp) & ~3; }},mem_flags = NO_ALIGN_FAULT);
1591
1592            0x3: sw({{ Mem.uw = Rt<31:0>; }});
1593
1594            0x6: swr({{
1595                uint32_t mem_word = 0;
1596                uint32_t aligned_addr = (Rs + disp) & ~3;
1597                uint32_t unalign_addr = Rs + disp;
1598                uint32_t offset = unalign_addr & 0x00000003;
1599
1600                fault = xc->read(aligned_addr, (uint32_t&)mem_word, memAccessFlags);
1601
1602#if BYTE_ORDER == BIG_ENDIAN
1603                switch(offset)
1604                {
1605                  case 0:
1606                    mem_word &= 0x0FFF;
1607                    mem_word |= (Rt << 12);
1608                    Mem = mem_word;
1609                    break;
1610
1611                  case 1:
1612                    mem_word &= 0x00FF;
1613                    mem_word |= (Rt << 8);
1614                    Mem = mem_word;
1615                    break;
1616
1617                  case 2:
1618                    mem_word &= 0x000F;
1619                    mem_word |= (Rt << 4);
1620                    Mem = mem_word;
1621                    break;
1622
1623                  case 3:
1624                    Mem = Rt;
1625                    break;
1626
1627                  default:
1628                    panic("swr: bad offset");
1629                }
1630#elif BYTE_ORDER == LITTLE_ENDIAN
1631                switch(offset)
1632                {
1633                  case 0:
1634                    Mem = Rt;
1635                    break;
1636
1637                  case 1:
1638                    mem_word &= 0x000F;
1639                    mem_word |= (Rt << 4);
1640                    Mem = mem_word;
1641                    break;
1642
1643                  case 2:
1644                    mem_word &= 0x00FF;
1645                    mem_word |= (Rt << 8);
1646                    Mem = mem_word;
1647                    break;
1648
1649                  case 3:
1650                    mem_word &= 0x0FFF;
1651                    mem_word |= (Rt << 12);
1652                    Mem = mem_word;
1653                    break;
1654
1655                  default:
1656                    panic("swr: bad offset");
1657                }
1658#endif
1659            }},{{ EA = (Rs + disp) & ~3;}},mem_flags = NO_ALIGN_FAULT);
1660        }
1661
1662        format WarnUnimpl {
1663            0x7: cache();
1664        }
1665
1666    }
1667
1668    0x6: decode OPCODE_LO default FailUnimpl::reserved() {
1669        0x0: LoadMemory::ll({{Rt.uw = Mem.uw}},mem_flags=LOCKED);
1670
1671        format LoadFloatMemory {
1672            0x1: lwc1({{ Ft.uw = Mem.uw;    }});
1673            0x5: ldc1({{ Ft.ud = Mem.ud; }});
1674        }
1675    }
1676
1677
1678    0x7: decode OPCODE_LO default FailUnimpl::reserved() {
1679        0x0: StoreMemory::sc({{ Mem.uw = Rt.uw; Rt.uw = 1; }});
1680
1681        format StoreFloatMemory {
1682            0x1: swc1({{ Mem.uw = Ft.uw; }});
1683            0x5: sdc1({{ Mem.ud = Ft.ud; }});
1684        }
1685    }
1686}
1687
1688
1689