decoder.isa revision 2061
111251Sradhika.jagtap@ARM.com////////////////////////////////////////////////////////////////////
211251Sradhika.jagtap@ARM.com//
311251Sradhika.jagtap@ARM.com// The actual MIPS32 ISA decoder
411251Sradhika.jagtap@ARM.com// -----------------------------
511251Sradhika.jagtap@ARM.com// The following instructions are specified in the MIPS32 ISA
611251Sradhika.jagtap@ARM.com// Specification. Decoding closely follows the style specified
711251Sradhika.jagtap@ARM.com// in the MIPS32 ISAthe specification document starting with Table
811251Sradhika.jagtap@ARM.com// A-2 (document available @ www.mips.com)
911251Sradhika.jagtap@ARM.com//
1011251Sradhika.jagtap@ARM.com//@todo: Distinguish "unknown/future" use insts from "reserved"
1111251Sradhika.jagtap@ARM.com// ones
1211251Sradhika.jagtap@ARM.comdecode OPCODE_HI default FailUnimpl::unknown() {
1311251Sradhika.jagtap@ARM.com
1411251Sradhika.jagtap@ARM.com    // Derived From ... Table A-2 MIPS32 ISA Manual
1511251Sradhika.jagtap@ARM.com    0x0: decode OPCODE_LO default FailUnimpl::reserved(){
1611251Sradhika.jagtap@ARM.com
1711251Sradhika.jagtap@ARM.com        0x0: decode FUNCTION_HI {
1811251Sradhika.jagtap@ARM.com            0x0: decode FUNCTION_LO {
1911251Sradhika.jagtap@ARM.com              0x1: decode MOVCI {
2011251Sradhika.jagtap@ARM.com                format BasicOp {
2111251Sradhika.jagtap@ARM.com                  0: movf({{ if( xc->miscRegs.fpcr == 0) Rd = Rs}});
2211251Sradhika.jagtap@ARM.com                  1: movt({{ if( xc->miscRegs.fpcr == 1) Rd = Rs}});
2311251Sradhika.jagtap@ARM.com                }
2411251Sradhika.jagtap@ARM.com              }
2511251Sradhika.jagtap@ARM.com
2611251Sradhika.jagtap@ARM.com              format BasicOp {
2711251Sradhika.jagtap@ARM.com
2811251Sradhika.jagtap@ARM.com                //Table A-3 Note: "1. Specific encodings of the rt, rd, and sa fields
2911251Sradhika.jagtap@ARM.com                //are used to distinguish among the SLL, NOP, SSNOP and EHB functions."
3011251Sradhika.jagtap@ARM.com
3111251Sradhika.jagtap@ARM.com                0x0: sll({{ Rd = Rt.uw << SA; }});
3211251Sradhika.jagtap@ARM.com
3311251Sradhika.jagtap@ARM.com                0x2: decode SRL {
3411251Sradhika.jagtap@ARM.com                   0: srl({{ Rd = Rt.uw >> SA; }});
3511251Sradhika.jagtap@ARM.com
3611251Sradhika.jagtap@ARM.com                   //Hardcoded assuming 32-bit ISA, probably need parameter here
3711251Sradhika.jagtap@ARM.com                   1: rotr({{ Rd = (Rt.uw << (32 - SA)) | (Rt.uw >> SA);}});
3811251Sradhika.jagtap@ARM.com                 }
3911251Sradhika.jagtap@ARM.com
4011251Sradhika.jagtap@ARM.com                 0x3: sra({{ Rd = Rt.sw >> SA; }});
4111251Sradhika.jagtap@ARM.com
4211251Sradhika.jagtap@ARM.com                 0x4: sllv({{ Rd = Rt.uw << Rs<4:0>; }});
4311251Sradhika.jagtap@ARM.com
4411251Sradhika.jagtap@ARM.com                 0x6: decode SRLV {
4511251Sradhika.jagtap@ARM.com                   0: srlv({{ Rd = Rt.uw >> Rs<4:0>; }});
4611251Sradhika.jagtap@ARM.com
4711251Sradhika.jagtap@ARM.com                   //Hardcoded assuming 32-bit ISA, probably need parameter here
4811251Sradhika.jagtap@ARM.com                   1: rotrv({{ Rd = (Rt.uw << (32 - Rs<4:0>)) | (Rt.uw >> Rs<4:0>);}});
4911251Sradhika.jagtap@ARM.com                 }
5011251Sradhika.jagtap@ARM.com
5111251Sradhika.jagtap@ARM.com                 0x7: srav({{ Rd = Rt.sw >> Rs<4:0>; }});
5211251Sradhika.jagtap@ARM.com              }
5311251Sradhika.jagtap@ARM.com            }
5411251Sradhika.jagtap@ARM.com
5511251Sradhika.jagtap@ARM.com            0x1: decode FUNCTION_LO {
5611251Sradhika.jagtap@ARM.com
5711251Sradhika.jagtap@ARM.com              //Table A-3 Note: "Specific encodings of the hint field are used
5811251Sradhika.jagtap@ARM.com              //to distinguish JR from JR.HB and JALR from JALR.HB"
5911251Sradhika.jagtap@ARM.com              format Jump {
6011251Sradhika.jagtap@ARM.com                0x0: jr(IsReturn);
6111251Sradhika.jagtap@ARM.com                0x1: jalr(IsCall,IsReturn);
6211251Sradhika.jagtap@ARM.com              }
6311251Sradhika.jagtap@ARM.com
6411251Sradhika.jagtap@ARM.com              format BasicOp {
6511251Sradhika.jagtap@ARM.com                0x2: movz({{ if (Rt == 0) Rd = Rs; }});
6611251Sradhika.jagtap@ARM.com                0x3: movn({{ if (Rt != 0) Rd = Rs; }});
6711251Sradhika.jagtap@ARM.com              }
6811251Sradhika.jagtap@ARM.com
6911251Sradhika.jagtap@ARM.com              format WarnUnimpl {
7011251Sradhika.jagtap@ARM.com                0x4: syscall({{ xc->syscall()}},IsNonSpeculative);
7111251Sradhika.jagtap@ARM.com                0x5: break({{ }});
7211251Sradhika.jagtap@ARM.com                0x7: sync({{ }});
7311251Sradhika.jagtap@ARM.com              }
7411251Sradhika.jagtap@ARM.com            }
7511251Sradhika.jagtap@ARM.com
7611251Sradhika.jagtap@ARM.com            0x2: decode FUNCTION_LO {
7711251Sradhika.jagtap@ARM.com              format BasicOp {
7811251Sradhika.jagtap@ARM.com                0x0: mfhi({{ Rd = xc->miscRegs.hi; }});
7911251Sradhika.jagtap@ARM.com                0x1: mthi({{ xc->miscRegs.hi = Rs; }});
8011251Sradhika.jagtap@ARM.com                0x2: mflo({{ Rd = xc->miscRegs.lo; }});
8111251Sradhika.jagtap@ARM.com                0x3: mtlo({{ xc->miscRegs.lo = Rs; }});
8211251Sradhika.jagtap@ARM.com              }
8311251Sradhika.jagtap@ARM.com            };
8411251Sradhika.jagtap@ARM.com
8511251Sradhika.jagtap@ARM.com            0x3: decode FUNCTION_LO {
8611251Sradhika.jagtap@ARM.com              format IntOp {
8711251Sradhika.jagtap@ARM.com                0x0: mult({{
8811251Sradhika.jagtap@ARM.com                        INT64 temp1 = Rs.sw * Rt.sw;
8911251Sradhika.jagtap@ARM.com                        xc->miscRegs.hi->temp1<63:32>;
9011251Sradhika.jagtap@ARM.com                        xc->miscRegs.lo->temp1<31:0>
9111251Sradhika.jagtap@ARM.com                }});
9211251Sradhika.jagtap@ARM.com
9311251Sradhika.jagtap@ARM.com                0x1: multu({{
9411251Sradhika.jagtap@ARM.com                        INT64 temp1 = Rs.uw * Rt.uw;
9511251Sradhika.jagtap@ARM.com                        xc->miscRegs.hi->temp1<63:32>;
9611251Sradhika.jagtap@ARM.com                        xc->miscRegs.lo->temp1<31:0>
9711251Sradhika.jagtap@ARM.com                        Rd.sw = Rs.uw * Rt.uw;
9811251Sradhika.jagtap@ARM.com                }});
9911251Sradhika.jagtap@ARM.com
10011251Sradhika.jagtap@ARM.com                0x2: div({{
10111251Sradhika.jagtap@ARM.com                        xc->miscRegs.hi = Rs.sw % Rt.sw;
10211251Sradhika.jagtap@ARM.com                        xc->miscRegs.lo = Rs.sw / Rt.sw;
10311251Sradhika.jagtap@ARM.com                        }});
10411251Sradhika.jagtap@ARM.com
10511251Sradhika.jagtap@ARM.com                0x3: divu({{
10611251Sradhika.jagtap@ARM.com                        xc->miscRegs.hi = Rs.uw % Rt.uw;
10711251Sradhika.jagtap@ARM.com                        xc->miscRegs.lo = Rs.uw / Rt.uw;
10811251Sradhika.jagtap@ARM.com                        }});
10911251Sradhika.jagtap@ARM.com              }
11011251Sradhika.jagtap@ARM.com            };
11111251Sradhika.jagtap@ARM.com
11211251Sradhika.jagtap@ARM.com            0x4: decode FUNCTION_LO {
11311251Sradhika.jagtap@ARM.com              format IntOp {
11411251Sradhika.jagtap@ARM.com                0x0: add({{  Rd.sw = Rs.sw + Rt.sw;}});
11511251Sradhika.jagtap@ARM.com                0x1: addu({{ Rd.uw = Rs.uw + Rt.uw;}});
11611251Sradhika.jagtap@ARM.com                0x2: sub({{ Rd.sw = Rs.sw - Rt.sw;}});
11711251Sradhika.jagtap@ARM.com                0x3: subu({{ Rd.uw = Rs.uw - Rt.uw;}});
11811251Sradhika.jagtap@ARM.com                0x4: and({{ Rd.sw = Rs.uw & Rt.uw;}});
11911251Sradhika.jagtap@ARM.com                0x5: or({{ Rd.sw = Rs.uw | Rt.uw;}});
120                0x6: xor({{ Rd.sw = Rs.uw ^ Rt.uw;}});
121                0x7: nor({{ Rd.sw = ~(Rs.uw | Rt.uw);}});
122              }
123            }
124
125            0x5: decode FUNCTION_LO {
126              format IntOp{
127                0x2: slt({{  Rd.sw = ( Rs.sw < Rt.sw ) ? 1 : 0}});
128                0x3: sltu({{ Rd.uw = ( Rs.uw < Rt.uw ) ? 1 : 0}});
129              }
130            };
131
132            0x6: decode FUNCTION_LO {
133              format Trap {
134                 0x0: tge({{ cond = (Rs.sw >= Rt.sw); }});
135                 0x1: tgeu({{ cond = (Rs.uw >= Rt.uw); }});
136                 0x2: tlt({{ cond = (Rs.sw < Rt.sw); }});
137                 0x3: tltu({{ cond = (Rs.uw >= Rt.uw); }});
138                 0x4: teq({{ cond = (Rs.sw == Rt.sw); }});
139                 0x6: tne({{ cond = (Rs.sw != Rt.sw); }});
140              }
141            }
142        }
143
144        0x1: decode REGIMM_HI {
145            0x0: decode REGIMM_LO {
146              format Branch {
147                0x0: bltz({{ cond = (Rs.sq < 0); }});
148                0x1: bgez({{ cond = (Rs.sq >= 0); }});
149
150                //MIPS obsolete instructions
151                0x2: bltzl({{ cond = (Rs.sq < 0); }});
152                0x3: bgezl({{ cond = (Rs.sq >= 0); }});
153              }
154            }
155
156            0x1: decode REGIMM_LO {
157              format Trap {
158                 0x0: tgei({{ cond = (Rs.sw >= INTIMM;  }});
159                 0x1: tgeiu({{ cond = (Rs.uw < INTIMM); }});
160                 0x2: tlti({{ cond = (Rs.sw < INTIMM);  }});
161                 0x3: tltiu({{ cond = (Rs.uw < INTIMM); }});
162                 0x4: teqi({{ cond = (Rs.sw == INTIMM); }});
163                 0x6: tnei({{ cond = (Rs.sw != INTIMM); }});
164              }
165            }
166
167            0x2: decode REGIMM_LO {
168              format Branch {
169                0x0: bltzal({{ cond = (Rs.sq < 0); }});
170                0x1: bgezal({{ cond = (Rs.sq >= 0); }});
171
172                //MIPS obsolete instructions
173                0x2: bltzall({{ cond = (Rs.sq < 0); }});
174                0x3: bgezall({{ cond = (Rs.sq >= 0); }});
175              }
176            }
177
178            0x3: decode REGIMM_LO {
179              format WarnUnimpl {
180                0x7: synci({{ }});
181              }
182            }
183        }
184
185        format Jump {
186            0x2: j();
187            0x3: jal(IsCall);
188        }
189
190        format Branch {
191            0x4: beq({{ cond = (Rs.sq == 0); }});
192            0x5: bne({{ cond = (Rs.sq !=  0); }});
193            0x6: blez({{ cond = (Rs.sq <= 0); }});
194            0x7: bgtz({{ cond = (Rs.sq > 0); }});
195        }
196    };
197
198    0x1: decode OPCODE_LO default FailUnimpl::reserved(){
199        format IntOp {
200            0x0: addi({{ Rt.sw = Rs.sw + INTIMM; }});
201            0x1: addiu({{ Rt.uw = Rs.uw + INTIMM;}});
202            0x2: slti({{ Rt.sw = ( Rs.sw < INTIMM ) ? 1 : 0 }});
203            0x3: sltiu({{ Rt.uw = ( Rs.uw < INTIMM ) ? 1 : 0 }});
204            0x4: andi({{ Rt.sw = Rs.sw & INTIMM;}});
205            0x5: ori({{ Rt.sw = Rs.sw | INTIMM;}});
206            0x6: xori({{ Rt.sw = Rs.sw ^ INTIMM;}});
207            0x7: lui({{ Rt = INTIMM << 16}});
208        };
209    };
210
211    0x2: decode OPCODE_LO default FailUnimpl::reserved(){
212
213      //Table A-11 MIPS32 COP0 Encoding of rs Field
214      0x0: decode RS_MSB {
215        0x0: decode RS {
216
217           format BasicOp {
218                0x0: mfc0({{
219                        //The contents of the coprocessor 0 register specified by the
220                        //combination of rd and sel are loaded into general register
221                        //rt. Note that not all coprocessor 0 registers support the
222                        //sel field. In those instances, the sel field must be zero.
223
224                        if (SEL > 0)
225                                panic("Can't Handle Cop0 with register select yet\n");
226
227                        uint64_t reg_num = Rd.uw;
228
229                        Rt = xc->miscRegs.cop0[reg_num];
230                        }});
231
232                0x4: mtc0({{
233                        //The contents of the coprocessor 0 register specified by the
234                        //combination of rd and sel are loaded into general register
235                        //rt. Note that not all coprocessor 0 registers support the
236                        //sel field. In those instances, the sel field must be zero.
237
238                        if (SEL > 0)
239                                panic("Can't Handle Cop0 with register select yet\n");
240
241                        uint64_t reg_num = Rd.uw;
242
243                        xc->miscRegs.cop0[reg_num] = Rt;
244                        }});
245
246                0x8: mftr({{
247                        //The contents of the coprocessor 0 register specified by the
248                        //combination of rd and sel are loaded into general register
249                        //rt. Note that not all coprocessor 0 registers support the
250                        //sel field. In those instances, the sel field must be zero.
251
252                        //MT Code Needed Here
253                        }});
254
255                0xC: mttr({{
256                        //The contents of the coprocessor 0 register specified by the
257                        //combination of rd and sel are loaded into general register
258                        //rt. Note that not all coprocessor 0 registers support the
259                        //sel field. In those instances, the sel field must be zero.
260
261                        //MT Code Needed Here
262                        }});
263
264
265                0xA: rdpgpr({{
266                        //Accessing Previous Shadow Set Register Number
267                        uint64_t prev = xc->miscRegs.cop0[SRSCtl][PSS];
268                        uint64_t reg_num = Rt.uw;
269
270                        Rd = xc->shadowIntRegFile[prev][reg_num];
271                        }});
272            }
273
274            0xB: decode RD {
275
276                0x0: decode SC {
277                  format BasicOp {
278                    0x0: dvpe({{
279                        Rt.sw = xc->miscRegs.cop0.MVPControl;
280                        xc->miscRegs.cop0.MVPControl[EVP] = 0;
281                        }});
282
283                    0x1: evpe({{
284                        Rt.sw = xc->miscRegs.cop0.MVPControl;
285                        xc->miscRegs.cop0.MVPControl[EVP] = 1;
286                        }});
287                  }
288                }
289
290                0x1: decode SC {
291                  format BasicOp {
292                    0x0: dmt({{
293                        Rt.sw = xc->miscRegs.cop0.VPEControl;
294                        xc->miscRegs.cop0.VPEControl[THREAD_ENABLE] = 0;
295                        }});
296
297                    0x1: emt({{
298                        Rt.sw = xc->miscRegs.cop0.VPEControl;
299                        xc->miscRegs.cop0.VPEControl[THREAD_ENABLE] = 1;
300                        }});
301                  }
302                }
303
304                0xC: decode SC {
305                  format BasicOp {
306                    0x0: di({{
307                        Rt.sw = xc->miscRegs.cop0.Status;
308                        xc->miscRegs.cop0.Status[INTERRUPT_ENABLE] = 0;
309                        }});
310
311                    0x1: ei({{
312                        Rt.sw = xc->miscRegs.cop0.Status;
313                        xc->miscRegs.cop0.Status[INTERRUPT_ENABLE] = 1;
314                        }});
315                  }
316                }
317            }
318
319            0xE: BasicOp::wrpgpr({{
320                        //Accessing Previous Shadow Set Register Number
321                        uint64_t prev = xc->miscRegs.cop0[SRSCtl][PSS];
322                        uint64_t reg_num = Rd.uw;
323
324                        xc->shadowIntRegFile[prev][reg_num] = Rt;
325                        }});
326        }
327
328        //Table A-12 MIPS32 COP0 Encoding of Function Field When rs=CO
329        0x1: decode FUNCTION {
330          format Trap {
331                0x01: tlbr({{ }});
332                0x02: tlbwi({{ }});
333                0x06: tlbwr({{ }});
334                0x08: tlbp({{ }});
335          }
336
337          format WarnUnimpl {
338                0x18: eret({{ }});
339                0x1F: deret({{ }});
340                0x20: wait({{ }});
341          }
342        }
343      }
344
345      //Table A-13 MIPS32 COP1 Encoding of rs Field
346      0x1: decode RS_MSB {
347
348        0x0: decode RS_HI {
349          0x0: decode RS_LO {
350            format FloatOp {
351              0x0: mfc1({{ Rt = Fs<31:0>; }});
352              0x2: cfc1({{ Rt = xc->miscRegs.fpcr[Fs];}});
353              0x3: mfhc1({{ Rt = Fs<63:32>;}});
354              0x4: mtc1({{ Fs<31:0> = Rt}});
355              0x6: ctc1({{ xc->miscRegs.fpcr[Fs] = Rt;}});
356              0x7: mftc1({{ Fs<63:32> = Rt}});
357            }
358          }
359
360          0x1: decode ND {
361            0x0: decode TF {
362              format Branch {
363                0x0: bc1f({{ cond = (xc->miscRegs.fpcr == 0); }});
364                0x1: bc1t({{ cond = (xc->miscRegs.fpcr == 1); }});
365              }
366            }
367
368            0x1: decode TF {
369              format Branch {
370                0x0: bc1fl({{ cond = (xc->miscRegs.fpcr == 0); }});
371                0x1: bc1tl({{ cond = (xc->miscRegs.fpcr == 1); }});
372              }
373            }
374          }
375        }
376
377        0x1: decode RS_HI {
378          0x2: decode RS_LO {
379
380            //Table A-14 MIPS32 COP1 Encoding of Function Field When rs=S
381            //(( single-word ))
382            0x0: decode RS_HI {
383              0x0: decode RS_LO {
384                format FloatOp {
385                  0x0: adds({{ Fd.sf = Fs.sf + Ft.sf;}});
386                  0x1: subs({{ Fd.sf = Fs.sf - Ft.sf;}});
387                  0x2: muls({{ Fd.sf = Fs.sf * Ft.sf;}});
388                  0x3: divs({{ Fd.sf = Fs.sf / Ft.sf;}});
389                  0x4: sqrts({{ Fd.sf = sqrt(Fs.sf);}});
390                  0x5: abss({{ Fd.sf = abs(Fs.sf);}});
391                  0x6: movs({{ Fd.sf = Fs.sf;}});
392                  0x7: negs({{ Fd.sf = -1 * Fs.sf;}});
393                }
394              }
395
396              0x1: decode RS_LO {
397                //only legal for 64 bit
398                format Float64Op {
399                  0x0: round_l_s({{ Fd = convert_and_round(Fs.sf,RND_NEAREST,FP_LONG,FP_SINGLE);}});
400                  0x1: trunc_l_s({{ Fd = convert_and_round(Fs.sf,RND_ZERO,FP_LONG,FP_SINGLE);}});
401                  0x2: ceil_l_s({{ Fd = convert_and_round(Fs.sf,RND_UP,FP_LONG,FP_SINGLE);}});
402                  0x3: floor_l_s({{ Fd = convert_and_round(Fs.sf,RND_DOWN,FP_LONG,FP_SINGLE);}});
403                }
404
405                format FloatOp {
406                  0x4: round_w_s({{ Fd = convert_and_round(Fs.sf,RND_NEAREST,FP_WORD,FP_SINGLE);}});
407                  0x5: trunc_w_s({{ Fd = convert_and_round(Fs.sf,RND_ZERO,FP_WORD,FP_SINGLE);}});
408                  0x6: ceil_w_s({{  Fd = convert_and_round(Fs.sf,RND_UP,FP_WORD,FP_SINGLE);}});
409                  0x7: floor_w_s({{ Fd = convert_and_round(Fs.sf,RND_DOWN,FP_WORD,FP_SINGLE);}});
410                }
411              }
412
413              0x2: decode RS_LO {
414                0x1: decode MOVCF {
415                  format FloatOp {
416                    0x0: movfs({{ if ( FPConditionCode(CC) == 0 ) Fd = Fs; }});
417                    0x1: movts({{ if ( FPConditionCode(CC) == 1 ) Fd = Fs;}});
418                  }
419                }
420
421                format BasicOp {
422                  0x2: movzs({{ if (Rt == 0) Fd = Fs; }});
423                  0x3: movns({{ if (Rt != 0) Fd = Fs; }});
424                }
425
426                format Float64Op {
427                  0x2: recips({{ Fd = 1 / Fs; }});
428                  0x3: rsqrts{{  Fd = 1 / sqrt(Fs); }});
429                }
430              }
431
432              0x4: decode RS_LO {
433                0x1: cvt_d_s({{ int rnd_mode = xc->miscRegs.fcsr;
434                                Fd = convert_and_round(Fs.sf,rnd_mode,FP_DOUBLE,FP_SINGLE);
435                             }});
436
437                0x4: cvt_w_s({{ int rnd_mode = xc->miscRegs.fcsr;
438                                Fd = convert_and_round(Fs.sf,rnd_mode,FP_WORD,FP_SINGLE);
439                             }});
440
441                //only legal for 64 bit
442                format Float64Op {
443                  0x5: cvt_l_s({{ int rnd_mode = xc->miscRegs.fcsr;
444                                Fd = convert_and_round(Fs.sf,rnd_mode,FP_LONG,FP_SINGLE);
445                               }});
446
447                  0x6: cvt_ps_s({{ Fd.df = Fs.df<31:0> | Ft.df<31:0>; }});
448                }
449              }
450            }
451
452            //Table A-15 MIPS32 COP1 Encoding of Function Field When rs=D
453            0x1: decode RS_HI {
454              0x0: decode RS_LO {
455                format FloatOp {
456                  0x0: addd({{ Fd.df = Fs.df + Ft.df;}});
457                  0x1: subd({{ Fd.df = Fs.df - Ft.df;}});
458                  0x2: muld({{ Fd.df = Fs.df * Ft.df;}});
459                  0x3: divd({{ Fd.df = Fs.df / Ft.df;}});
460                  0x4: sqrtd({{ Fd.df = sqrt(Fs.df);}});
461                  0x5: absd({{ Fd.df = abs(Fs.df);}});
462                  0x6: movd({{ Fd.df = Fs.df;}});
463                  0x7: negd({{ Fd.df = -1 * Fs.df;}});
464                }
465              }
466
467              0x1: decode RS_LO {
468                //only legal for 64 bit
469                format FloatOp64 {
470                  0x0: round_l_d({{ Fd = convert_and_round(Fs.df,RND_NEAREST,FP_LONG,FP_DOUBLE); }});
471                  0x1: trunc_l_d({{ Fd = convert_and_round(Fs.df,RND_ZERO,FP_LONG,FP_DOUBLE);}});
472                  0x2: ceil_l_d({{ Fd = convert_and_round(Fs.df,RND_UP,FP_LONG,FP_DOUBLE);}});
473                  0x3: floor_l_d({{ Fd = convert_and_round(Fs.df,RND_DOWN,FP_LONG,FP_DOUBLE);}});
474                }
475
476                format FloatOp {
477                  0x4: round_w_d({{ Fd = convert_and_round(Fs.df,RND_NEAREST,FP_LONG,FP_DOUBLE); }});
478                  0x5: trunc_w_d({{ Fd = convert_and_round(Fs.df,RND_ZERO,FP_LONG,FP_DOUBLE); }});
479                  0x6: ceil_w_d({{  Fd = convert_and_round(Fs.df,RND_UP,FP_LONG,FP_DOUBLE); }});
480                  0x7: floor_w_d({{ Fd = convert_and_round(Fs.df,RND_DOWN,FP_LONG,FP_DOUBLE); }});
481                }
482              }
483
484              0x2: decode RS_LO {
485                0x1: decode MOVCF {
486                  format FloatOp {
487                    0x0: movfd({{ if (FPConditionCode(CC) == 0) Fd.df = Fs.df; }});
488                    0x1: movtd({{ if (FPConditionCode(CC) == 1) Fd.df = Fs.df; }});
489                  }
490                }
491
492                format BasicOp {
493                  0x2: movz({{ if (Rt == 0) Fd.df = Fs.df; }});
494                  0x3: movn({{ if (Rt != 0) Fd.df = Fs.df; }});
495                }
496
497                format FloatOp64 {
498                  0x5: recipd({{ Fd.df = 1 / Fs.df}});
499                  0x6: rsqrtd{{ Fd.df = 1 / sqrt(Fs.df) }});
500                }
501              }
502
503              0x4: decode RS_LO {
504                format FloatOp {
505                  0x0: cvt_s_d({{
506                                int rnd_mode = xc->miscRegs.fcsr;
507                                Fd = convert_and_round(Fs.df,rnd_mode,FP_SINGLE,FP_DOUBLE);
508                              }});
509
510                  0x4: cvt_w_d({{
511                                int rnd_mode = xc->miscRegs.fcsr;
512                                Fd = convert_and_round(Fs.df,rnd_mode,FP_WORD,FP_DOUBLE);
513                              }});
514                }
515
516                //only legal for 64 bit
517                format FloatOp64 {
518                  0x5: cvt_l_d({{
519                                int rnd_mode = xc->miscRegs.fcsr;
520                                Fd = convert_and_round(Fs.df,rnd_mode,FP_LONG,FP_DOUBLE);
521                              }});
522                }
523              }
524            }
525
526            //Table A-16 MIPS32 COP1 Encoding of Function Field When rs=W
527            0x4: decode FUNCTION {
528              format FloatOp {
529                0x10: cvt_s({{
530                                int rnd_mode = xc->miscRegs.fcsr;
531                                Fd = convert_and_round(Fs.df,rnd_mode,FP_SINGLE,FP_WORD);
532                            }});
533
534                0x10: cvt_d({{
535                                int rnd_mode = xc->miscRegs.fcsr;
536                                Fd = convert_and_round(Fs.df,rnd_mode,FP_DOUBLE,FP_WORD);
537                            }});
538              }
539            }
540
541            //Table A-16 MIPS32 COP1 Encoding of Function Field When rs=L1
542            //Note: "1. Format type L is legal only if 64-bit floating point operations
543            //are enabled."
544            0x5: decode FUNCTION_HI {
545              format FloatOp {
546                0x10: cvt_s_l({{
547                                int rnd_mode = xc->miscRegs.fcsr;
548                                Fd = convert_and_round(Fs.df,rnd_mode,FP_SINGLE,FP_LONG);
549                            }});
550
551                0x11: cvt_d_l({{
552                                int rnd_mode = xc->miscRegs.fcsr;
553                                Fd = convert_and_round(Fs.df,rnd_mode,FP_DOUBLE,FP_LONG);
554                            }});
555              }
556            }
557
558            //Table A-17 MIPS64 COP1 Encoding of Function Field When rs=PS1
559            //Note: "1. Format type PS is legal only if 64-bit floating point operations
560            //are enabled. "
561            0x6: decode RS_HI {
562              0x0: decode RS_LO {
563                format FloatOp64 {
564                  0x0: addps({{ //Must Check for Exception Here... Supposed to Operate on Upper and
565                                //Lower Halves Independently but we take simulator shortcut
566                                Fd.df = Fs.df + Ft.df;
567                             }});
568
569                  0x1: subps({{ //Must Check for Exception Here... Supposed to Operate on Upper and
570                                //Lower Halves Independently but we take simulator shortcut
571                                Fd.df = Fs.df - Ft.df;
572                            }});
573
574                  0x2: mulps({{ //Must Check for Exception Here... Supposed to Operate on Upper and
575                                //Lower Halves Independently but we take simulator shortcut
576                                Fd.df = Fs.df * Ft.df;
577                            }});
578
579                  0x5: absps({{ //Must Check for Exception Here... Supposed to Operate on Upper and
580                                //Lower Halves Independently but we take simulator shortcut
581                                Fd.df = abs(Fs.df);
582                            }});
583
584                  0x6: movps({{ //Must Check for Exception Here... Supposed to Operate on Upper and
585                                //Lower Halves Independently but we take simulator shortcut
586                                Fd.df = Fs<31:0> |  Ft<31:0>;
587                            }});
588
589                  0x7: negps({{ //Must Check for Exception Here... Supposed to Operate on Upper and
590                                //Lower Halves Independently but we take simulator shortcut
591                                Fd.df = -1 * Fs.df;
592                            }});
593                }
594              }
595
596              0x2: decode RS_LO {
597                0x1: decode MOVCF {
598                  format FloatOp64 {
599                    0x0: movfps({{ if ( FPConditionCode(CC) == 0) Fd = Fs;}})
600                    0x1: movtps({{ if ( FPConditionCode(CC) == 0) Fd = Fs;}})
601                  }
602                }
603
604              }
605
606              0x4: decode RS_LO {
607                0x0: FloatOp64::cvt_s_pu({{
608                                int rnd_mode = xc->miscRegs.fcsr;
609                                Fd = convert_and_round(Fs.df,rnd_mode,FP_DOUBLE,FP_PS_HI);
610                           }});
611              }
612
613              0x5: decode RS_LO {
614                format FloatOp64 {
615                  0x0: cvt_s_pl({{
616                                int rnd_mode = xc->miscRegs.fcsr;
617                                Fd = convert_and_round(Fs.df,rnd_mode,FP_SINGLE,FP_PS_LO);
618                           }});
619                  0x4: pll({{ Fd.df = Fs<31:0> | Ft<31:0>}});
620                  0x5: plu({{ Fd.df = Fs<31:0> | Ft<63:32>}});
621                  0x6: pul({{ Fd.df = Fs<63:32> | Ft<31:0>}});
622                  0x7: puu({{ Fd.df = Fs<63:32 | Ft<63:32>}});
623                }
624              }
625            }
626      }
627
628      //Table A-19 MIPS32 COP2 Encoding of rs Field
629      0x2: decode RS_MSB {
630        0x0: decode RS_HI {
631          0x0: decode RS_LO {
632            format WarnUnimpl {
633                0x0: mfc2({{ }});
634                0x2: cfc2({{ }});
635                0x3: mfhc2({{ }});
636                0x4: mtc2({{ }});
637                0x6: ctc2({{ }});
638                0x7: mftc2({{ }});
639            }
640          }
641
642          0x1: decode ND {
643            0x0: decode TF {
644              format WarnUnimpl {
645                0x0: bc2f({{ cond = (xc->miscRegs.cop2cc == 0); }}, COP2);
646                0x1: bc2t({{ cond = (xc->miscRegs.cop2cc == 1); }}, COP2}});
647              }
648            }
649
650            0x1: decode TF {
651              format WarnUnimpl {
652                0x0: bc2fl({{ cond = (xc->miscRegs.cop2cc == 0); }}, COP2}});
653                0x1: bc2tl({{ cond = (xc->miscRegs.cop2cc == 1); }}, COP2}});
654              }
655            }
656          }
657        }
658      }
659
660      //Table A-20 MIPS64 COP1X Encoding of Function Field 1
661      //Note: "COP1X instructions are legal only if 64-bit floating point
662      //operations are enabled."
663      0x3: decode FUNCTION_HI {
664        0x0: decode FUNCTION_LO {
665                format Memory {
666                  0x0: lwxc1({{ EA = Rs + Rt; }},{{ Ft<31:0> = Mem.uf; }});
667                  0x1: ldxc1({{ EA = Rs + Rt; }},{{ Ft<63:0> = Mem.df; }});
668                  0x5: luxc1({{ //Need to make EA<2:0> = 0
669                                EA = Rs + Rt;
670                             }},
671                             {{ Ft<31:0> = Mem.df; }});
672                }
673        }
674
675        0x1: decode FUNCTION_LO {
676                format Memory {
677                  0x0: swxc1({{ EA = Rs + Rt; }},{{ Mem.uf = Ft<31:0>; }});
678                  0x1: sdxc1({{ EA = Rs + Rt; }},{{ Mem.uf = Ft<63:0>}});
679                  0x5: suxc1({{ //Need to make EA<2:0> = 0
680                                EA = Rs + Rt;
681                             }},
682                             {{ Mem.df = Ft<63:0>;}});
683                  0x7: prefx({{ }});
684                }
685        }
686
687        format FloatOp {
688                0x3: WarnUnimpl::alnv_ps({{ }});
689
690                format BasicOp {
691                  0x4: decode FUNCTION_LO {
692                    0x0: madd_s({{ Fd.sf = (Fs.sf * Fs.sf) + Fr.sf; }});
693                    0x1: madd_d({{ Fd.df = (Fs.df * Fs.df) + Fr.df; }});
694                    0x6: madd_ps({{
695                                //Must Check for Exception Here... Supposed to Operate on Upper and
696                                //Lower Halves Independently but we take simulator shortcut
697                                Fd.df = (Fs.df * Fs.df) + Fr.df;
698                                }});
699                  }
700
701                  0x5: decode FUNCTION_LO {
702                    0x0: msub_s({{ Fd.sf = (Fs.sf * Fs.sf) - Fr.sf; }});
703                    0x1: msub_d({{ Fd.df = (Fs.df * Fs.df) - Fr.df; }});
704                    0x6: msub_ps({{
705                                //Must Check for Exception Here... Supposed to Operate on Upper and
706                                //Lower Halves Independently but we take simulator shortcut
707                                Fd.df = (Fs.df * Fs.df) - Fr.df;
708                                }});
709                  }
710
711                  0x6: decode FUNCTION_LO {
712                    0x0: nmadd_s({{ Fd.sf = (-1 * Fs.sf * Fs.sf) - Fr.sf; }});
713                    0x1: nmadd_d({{ Fd.df = (-1 * Fs.df * Fs.df) + Fr.df; }});
714                    0x6: nmadd_ps({{
715                                //Must Check for Exception Here... Supposed to Operate on Upper and
716                                //Lower Halves Independently but we take simulator shortcut
717                                Fd.df = (-1 * Fs.df * Fs.df) + Fr.df;
718                                }});
719                  }
720
721                  0x7: decode FUNCTION_LO {
722                    0x0: nmsub_s({{ Fd.sf = (-1 * Fs.sf * Fs.sf) - Fr.sf; }});
723                    0x1: nmsub_d({{ Fd.df = (-1 * Fs.df * Fs.df) - Fr.df; }});
724                    0x6: nmsub_ps({{
725                                //Must Check for Exception Here... Supposed to Operate on Upper and
726                                //Lower Halves Independently but we take simulator shortcut
727                                Fd.df = (-1 * Fs.df * Fs.df) + Fr.df;
728                                }});
729                  }
730                }
731        }
732      }
733
734      //MIPS obsolete instructions
735        format Branch {
736              0x4: beql({{ cond = (Rs.sq == 0); }});
737              0x5: bnel({{ cond = (Rs.sq != 0); }});
738              0x6: blezl({{ cond = (Rs.sq <= 0); }});
739              0x7: bgtzl({{ cond = (Rs.sq > 0); }});
740        }
741    };
742
743    0x3: decode OPCODE_LO default FailUnimpl::reserved() {
744
745        //Table A-5 MIPS32 SPECIAL2 Encoding of Function Field
746        0x4: decode FUNCTION_HI {
747
748            0x0: decode FUNCTION_LO {
749                format IntOp {
750                   0x0: madd({{
751                        INT64 temp1 = Hi.sw << 32 | Lo.sw >> 32;
752                        temp1 = temp1 + (Rs.sw * Rt.sw);
753                        xc->miscRegs.hi->temp1<63:32>;
754                        xc->miscRegs.lo->temp1<31:0>
755                        }});
756
757                   0x1: maddu({{
758                        INT64 temp1 = Hi.uw << 32 | Lo.uw >> 32;
759                        temp1 = temp1 + (Rs.uw * Rt.uw);
760                        xc->miscRegs.hi->temp1<63:32>;
761                        xc->miscRegs.lo->temp1<31:0>
762                        }});
763
764                   0x2: mul({{ 	Rd.sw = Rs.sw * Rt.sw; 	}});
765
766                   0x4: msub({{
767                        INT64 temp1 = Hi.sw << 32 | Lo.sw >> 32;
768                        temp1 = temp1 - (Rs.sw * Rt.sw);
769                        xc->miscRegs.hi->temp1<63:32>;
770                        xc->miscRegs.lo->temp1<31:0>
771                        }});
772
773                   0x5: msubu({{
774                        INT64 temp1 = Hi.uw << 32 | Lo.uw >> 32;
775                        temp1 = temp1 - (Rs.uw * Rt.uw);
776                        xc->miscRegs.hi->temp1<63:32>;
777                        xc->miscRegs.lo->temp1<31:0>
778                        }});
779                }
780            }
781
782            0x4: decode FUNCTION_LO {
783                  format BasicOp {
784                      0x0: clz({{
785                        int cnt = 0;
786                        int idx = 0;
787                        while ( Rs.uw<idx>!= 1) {
788                                cnt++;
789                                idx--;
790                        }
791
792                        Rd.uw = cnt;
793                        }});
794
795                      0x1: clo({{
796                        int cnt = 0;
797                        int idx = 0;
798                        while ( Rs.uw<idx>!= 0) {
799                                cnt++;
800                                idx--;
801                        }
802
803                        Rd.uw = cnt;
804                        }});
805                  }
806            }
807
808            0x7: decode FUNCTION_LO {
809              0x7: WarnUnimpl::sdbbp({{ }});
810            }
811        }
812
813        //Table A-6 MIPS32 SPECIAL3 Encoding of Function Field for Release 2 of the Architecture
814        0x7: decode FUNCTION_HI {
815
816          0x0: decode FUNCTION_LO {
817                format WarnUnimpl {
818                    0x1: ext({{ }});
819                    0x4: ins({{ }});
820                }
821          }
822
823          0x1: decode FUNCTION_LO {
824                format WarnUnimpl {
825                    0x0: fork({{ }});
826                    0x1: yield({{ }});
827                }
828          }
829
830
831          //Table A-10 MIPS32 BSHFL Encoding of sa Field
832          0x4: decode SA {
833
834                0x02: WarnUnimpl::wsbh({{ }});
835
836                format BasicOp {
837                    0x10: seb({{ Rd.sw = /* sext32(Rt<7>,24)  | */ Rt<7:0>}});
838                    0x18: seh({{ Rd.sw = /* sext32(Rt<15>,16) | */ Rt<15:0>}});
839                }
840          }
841
842          0x6: decode FUNCTION_LO {
843            0x7: BasicOp::rdhwr({{ Rt = xc->hwRegs[RD];}});
844          }
845        }
846    };
847
848    0x4: decode OPCODE_LO default FailUnimpl::reserved() {
849        format Memory {
850            0x0: lb({{ EA = Rs + disp; }}, {{ Rb.sw = Mem.sb; }});
851            0x1: lh({{ EA = Rs + disp; }}, {{ Rb.sw = Mem.sh; }});
852            0x2: lwl({{ EA = Rs + disp; }}, {{ Rb.sw = Mem.sw; }}, WordAlign);
853            0x3: lw({{ EA = Rs + disp; }}, {{ Rb.uq = Mem.sb; }});
854            0x4: lbu({{ EA = Rs + disp; }}, {{ Rb.uw = Mem.ub; }});
855            0x5: lhu({{ EA = Rs + disp; }}, {{ Rb.uw = Mem.uh; }});
856            0x6: lwr({{ EA = Rs + disp; }}, {{ Rb.uw = Mem.uw; }}, WordAlign);
857        };
858
859        0x7: FailUnimpl::reserved({{ }});
860    };
861
862    0x5: decode OPCODE_LO default FailUnimpl::reserved() {
863        format Memory {
864            0x0: sb({{ EA = Rs + disp; }}, {{ Mem.ub = Rt<7:0>; }});
865            0x1: sh({{ EA = Rs + disp; }},{{ Mem.uh = Rt<15:0>; }});
866            0x2: swl({{ EA = Rs + disp; }},{{ Mem.ub = Rt<31:0>; }},WordAlign);
867            0x3: sw({{ EA = Rs + disp; }},{{ Mem.ub = Rt<31:0>; }});
868            0x6: swr({{ EA = Rs + disp; }},{{ Mem.ub = Rt<31:0>; }},WordAlign);
869        };
870
871        format WarnUnimpl {
872            0x7: cache({{ }});
873        };
874
875    };
876
877    0x6: decode OPCODE_LO default FailUnimpl::reserved() {
878            0x0: WarnUnimpl::ll({{ }});
879
880        format Memory {
881            0x1: lwc1({{ EA = Rs + disp; }},{{ Ft<31:0> = Mem.uf; }});
882            0x5: ldc1({{ EA = Rs + disp; }},{{ Ft<63:0> = Mem.df; }});
883        };
884    };
885
886    0x7: decode OPCODE_LO default FailUnimpl::reserved() {
887        0x0: WarnUnimpl::sc({{ }});
888
889        format Memory {
890            0x1: swc1({{ EA = Rs + disp; }},{{ Mem.uf = Ft<31:0>; }});
891            0x5: sdc1({{ EA = Rs + disp; }},{{ Mem.df = Ft<63:0>; }});
892        };
893
894    }
895}
896
897
898