decoder.isa revision 2241
1// -*- mode:c++ -*-
2
3////////////////////////////////////////////////////////////////////
4//
5// The actual MIPS32 ISA decoder
6// -----------------------------
7// The following instructions are specified in the MIPS32 ISA
8// Specification. Decoding closely follows the style specified
9// in the MIPS32 ISAthe specification document starting with Table
10// A-2 (document available @ www.mips.com)
11//
12//@todo: Distinguish "unknown/future" use insts from "reserved"
13// ones
14decode OPCODE_HI default Unknown::unknown() {
15
16    // Derived From ... Table A-2 MIPS32 ISA Manual
17    0x0: decode OPCODE_LO {
18
19        0x0: decode FUNCTION_HI {
20            0x0: decode FUNCTION_LO {
21                0x1: decode MOVCI {
22                    format BasicOp {
23                        0: movf({{ if (xc->readMiscReg(FPCR,0) != CC) Rd = Rs}});
24                        1: movt({{ if (xc->readMiscReg(FPCR,0) == CC) Rd = Rs}});
25                    }
26                }
27
28                format BasicOp {
29
30                    //Table A-3 Note: "1. Specific encodings of the rt, rd, and sa fields
31                    //are used to distinguish among the SLL, NOP, SSNOP and EHB functions."
32
33                    0x0: decode RS {
34                        0x0: decode RT default BasicOp::sll({{ Rd = Rt.uw << SA; }}) {
35                            0x0: decode RD{
36                                0x0: decode HINT {
37                                    0x0:nop({{}});
38                                    0x1:ssnop({{}});
39                                    0x3:ehb({{}});
40                                }
41                            }
42                        }
43                    }
44
45                    0x2: decode SRL {
46                        0: srl({{ Rd = Rt.uw >> SA; }});
47
48                        //Hardcoded assuming 32-bit ISA, probably need parameter here
49                        1: rotr({{ Rd = (Rt.uw << (32 - SA)) | (Rt.uw >> SA);}});
50                    }
51
52                    0x3: sra({{ Rd = Rt.sw >> SA; }});
53
54                    0x4: sllv({{ Rd = Rt.uw << Rs<4:0>; }});
55
56                    0x6: decode SRLV {
57                        0: srlv({{ Rd = Rt.uw >> Rs<4:0>; }});
58
59                        //Hardcoded assuming 32-bit ISA, probably need parameter here
60                        1: rotrv({{ Rd = (Rt.uw << (32 - Rs<4:0>)) | (Rt.uw >> Rs<4:0>);}});
61                    }
62
63                    0x7: srav({{ Rd = Rt.sw >> Rs<4:0>; }});
64                }
65            }
66
67            0x1: decode FUNCTION_LO {
68
69                //Table A-3 Note: "Specific encodings of the hint field are used
70                //to distinguish JR from JR.HB and JALR from JALR.HB"
71                format Jump {
72                    0x0: decode HINT {
73                        0:jr({{ NNPC = Rs & ~1; }},IsReturn);
74
75                        1:jr_hb({{ NNPC = Rs & ~1; clear_exe_inst_hazards(); }},IsReturn);
76                    }
77
78                    0x1: decode HINT {
79                        0: jalr({{ NNPC = Rs; }},IsCall,IsReturn);
80
81                        1: jalr_hb({{ NNPC = Rs; clear_exe_inst_hazards();}},IsCall,IsReturn);
82                    }
83                }
84
85                format BasicOp {
86                    0x2: movz({{ if (Rt == 0) Rd = Rs; }});
87                    0x3: movn({{ if (Rt != 0) Rd = Rs; }});
88                }
89
90                format WarnUnimpl {
91                    0x4: syscall();//{{ xc->syscall()}},IsNonSpeculative
92                    0x5: break();
93                    0x7: sync();
94                }
95            }
96
97            0x2: decode FUNCTION_LO {
98                format BasicOp {
99                    0x0: mfhi({{ Rd = xc->readMiscReg(Hi); }});
100                    0x1: mthi({{ xc->setMiscReg(Hi,Rs); }});
101                    0x2: mflo({{ Rd = xc->readMiscReg(Lo); }});
102                    0x3: mtlo({{ xc->setMiscReg(Lo,Rs); }});
103                }
104            }
105
106            0x3: decode FUNCTION_LO {
107                format IntOp {
108                    0x0: mult({{
109                        int64_t temp1 = Rs.sw * Rt.sw;
110                        xc->setMiscReg(Hi,temp1<63:32>);
111                        xc->setMiscReg(Lo,temp1<31:0>);
112                    }});
113
114                    0x1: multu({{
115                        int64_t temp1 = Rs.uw * Rt.uw;
116                        xc->setMiscReg(Hi,temp1<63:32>);
117                        xc->setMiscReg(Lo,temp1<31:0>);
118                    }});
119
120                    0x2: div({{
121                        xc->setMiscReg(Hi,Rs.sw % Rt.sw);
122                        xc->setMiscReg(Lo,Rs.sw / Rt.sw);
123                    }});
124
125                    0x3: divu({{
126                        xc->setMiscReg(Hi,Rs.uw % Rt.uw);
127                        xc->setMiscReg(Lo,Rs.uw / Rt.uw);
128                    }});
129                }
130            }
131
132            0x4: decode FUNCTION_LO {
133                format IntOp {
134                    0x0: add({{  Rd.sw = Rs.sw + Rt.sw;/*Trap on Overflow*/}});
135                    0x1: addu({{ Rd.sw = Rs.sw + Rt.sw;}});
136                    0x2: sub({{ Rd.sw = Rs.sw - Rt.sw; /*Trap on Overflow*/}});
137                    0x3: subu({{ Rd.sw = Rs.sw - Rt.uw;}});
138                    0x4: and({{ Rd = Rs & Rt;}});
139                    0x5: or({{ Rd = Rs | Rt;}});
140                    0x6: xor({{ Rd = Rs ^ Rt;}});
141                    0x7: nor({{ Rd = ~(Rs | Rt);}});
142                }
143            }
144
145            0x5: decode FUNCTION_LO {
146                format IntOp{
147                    0x2: slt({{  Rd.sw = ( Rs.sw < Rt.sw ) ? 1 : 0}});
148                    0x3: sltu({{ Rd.uw = ( Rs.uw < Rt.uw ) ? 1 : 0}});
149                }
150            }
151
152            0x6: decode FUNCTION_LO {
153                format Trap {
154                    0x0: tge({{  cond = (Rs.sw >= Rt.sw); }});
155                    0x1: tgeu({{ cond = (Rs.uw >= Rt.uw); }});
156                    0x2: tlt({{ cond = (Rs.sw < Rt.sw); }});
157                    0x3: tltu({{ cond = (Rs.uw >= Rt.uw); }});
158                    0x4: teq({{ cond = (Rs.sw == Rt.sw); }});
159                    0x6: tne({{ cond = (Rs.sw != Rt.sw); }});
160                }
161            }
162        }
163
164        0x1: decode REGIMM_HI {
165            0x0: decode REGIMM_LO {
166                format Branch {
167                    0x0: bltz({{ cond = (Rs.sw < 0); }});
168                    0x1: bgez({{ cond = (Rs.sw >= 0); }});
169                }
170
171                format BranchLikely {
172                    //MIPS obsolete instructions
173                    0x2: bltzl({{ cond = (Rs.sw < 0); }});
174                    0x3: bgezl({{ cond = (Rs.sw >= 0); }});
175                }
176            }
177
178            0x1: decode REGIMM_LO {
179                format Trap {
180                    0x0: tgei( {{ cond = (Rs.sw >= INTIMM); }});
181                    0x1: tgeiu({{ cond = (Rs.uw >= INTIMM); }});
182                    0x2: tlti( {{ cond = (Rs.sw < INTIMM); }});
183                    0x3: tltiu({{ cond = (Rs.uw < INTIMM); }});
184                    0x4: teqi( {{ cond = (Rs.sw == INTIMM);}});
185                    0x6: tnei( {{ cond = (Rs.sw != INTIMM);}});
186                }
187            }
188
189            0x2: decode REGIMM_LO {
190                format Branch {
191                    0x0: bltzal({{ cond = (Rs.sw < 0); }}, IsCall,IsReturn);
192                    0x1: bgezal({{ cond = (Rs.sw >= 0); }}, IsCall,IsReturn);
193                }
194
195                format BranchLikely {
196                    //Will be removed in future MIPS releases
197                    0x2: bltzall({{ cond = (Rs.sw < 0); }}, IsCall, IsReturn);
198                    0x3: bgezall({{ cond = (Rs.sw >= 0); }}, IsCall, IsReturn);
199                }
200            }
201
202            0x3: decode REGIMM_LO {
203                format WarnUnimpl {
204                    0x7: synci();
205                }
206            }
207        }
208
209        format Jump {
210            0x2: j({{ NNPC = (NPC & 0xF0000000) | (JMPTARG << 2);}});
211
212            0x3: jal({{ NNPC = (NPC & 0xF0000000) | (JMPTARG << 2); }},IsCall,IsReturn);
213        }
214
215        format Branch {
216            0x4: beq({{ cond = (Rs.sw == Rt.sw); }});
217            0x5: bne({{ cond = (Rs.sw != Rt.sw); }});
218            0x6: blez({{ cond = (Rs.sw <= 0); }});
219            0x7: bgtz({{ cond = (Rs.sw > 0); }});
220        }
221    }
222
223    0x1: decode OPCODE_LO {
224        format IntOp {
225            0x0: addi({{ Rt.sw = Rs.sw + imm; /*Trap If Overflow*/}});
226            0x1: addiu({{ Rt.sw = Rs.sw + imm;}});
227            0x2: slti({{ Rt.sw = ( Rs.sw < imm) ? 1 : 0 }});
228            0x3: sltiu({{ Rt.sw = ( Rs.sw < imm ) ? 1 : 0 }});
229            0x4: andi({{ Rt.sw = Rs.sw & INTIMM;}});
230            0x5: ori({{ Rt.sw = Rs.sw | INTIMM;}});
231            0x6: xori({{ Rt.sw = Rs.sw ^ INTIMM;}});
232            0x7: lui({{ Rt = INTIMM << 16}});
233        }
234    }
235
236    0x2: decode OPCODE_LO {
237
238        //Table A-11 MIPS32 COP0 Encoding of rs Field
239        0x0: decode RS_MSB {
240            0x0: decode RS {
241                format System {
242                    0x0: mfc0({{
243                        //uint64_t reg_num = Rd.uw;
244
245                        Rt = xc->readMiscReg(RD << 5 | SEL);
246                    }});
247
248                    0x4: mtc0({{
249                        //uint64_t reg_num = Rd.uw;
250
251                        xc->setMiscReg(RD << 5 | SEL,Rt);
252                    }});
253
254                    0x8: mftr({{
255                        //The contents of the coprocessor 0 register specified by the
256                        //combination of rd and sel are loaded into general register
257                        //rt. Note that not all coprocessor 0 registers support the
258                        //sel field. In those instances, the sel field must be zero.
259
260                        //MT Code Needed Here
261                    }});
262
263                    0xC: mttr({{
264                        //The contents of the coprocessor 0 register specified by the
265                        //combination of rd and sel are loaded into general register
266                        //rt. Note that not all coprocessor 0 registers support the
267                        //sel field. In those instances, the sel field must be zero.
268
269                        //MT Code Needed Here
270                    }});
271
272
273                    0xA: rdpgpr({{
274                        //Accessing Previous Shadow Set Register Number
275                        //uint64_t prev = xc->readMiscReg(SRSCtl)/*[PSS]*/;
276                        //uint64_t reg_num = Rt.uw;
277
278                        //Rd = xc->regs.IntRegFile[prev];
279                       //Rd = xc->shadowIntRegFile[prev][reg_num];
280                    }});
281
282                    0xB: decode RD {
283
284                        0x0: decode SC {
285                            0x0: dvpe({{
286                                int idx;
287                                int sel;
288                                getMiscRegIdx(MVPControl,idx,sel);
289                                Rt.sw = xc->readMiscReg(idx,sel);
290                                xc->setMiscReg(idx,sel);
291                            }});
292
293                            0x1: evpe({{
294                                int idx;
295                                int sel;
296                                getMiscRegIdx(MVPControl,idx,sel);
297                                Rt.sw = xc->readMiscReg(idx,sel);
298                                xc->setMiscReg(idx,sel,1);
299                            }});
300                        }
301
302                        0x1: decode SC {
303                            0x0: dmt({{
304                                int idx;
305                                int sel;
306                                getMiscRegIdx(VPEControl,idx,sel);
307                                Rt.sw = xc->readMiscReg(idx,sel);
308                                xc->setMiscReg(idx,sel);
309                            }});
310
311                            0x1: emt({{
312                                int idx;
313                                int sel;
314                                getMiscRegIdx(VPEControl,idx,sel);
315                                Rt.sw = xc->readMiscReg(idx,sel);
316                                xc->setMiscReg(idx,sel,1);
317                            }});
318                        }
319
320                        0xC: decode SC {
321                            0x0: di({{
322                                int idx;
323                                int sel;
324                                getMiscRegIdx(Status,idx,sel);
325                                Rt.sw = xc->readMiscReg(idx,sel);
326                                xc->setMiscReg(idx,sel);
327                            }});
328
329                            0x1: ei({{
330                                int idx;
331                                int sel;
332                                getMiscRegIdx(Status,idx,sel);
333                                Rt.sw = xc->readMiscReg(idx,sel);
334                                xc->setMiscReg(idx,sel,1);
335                            }});
336                        }
337                    }
338
339                    0xE: wrpgpr({{
340                        //Accessing Previous Shadow Set Register Number
341                        //uint64_t prev = xc->readMiscReg(SRSCtl/*[PSS]*/);
342                        //uint64_t reg_num = Rd.uw;
343
344                        //xc->regs.IntRegFile[prev];
345                        //xc->shadowIntRegFile[prev][reg_num] = Rt;
346                    }});
347                }
348            }
349
350            //Table A-12 MIPS32 COP0 Encoding of Function Field When rs=CO
351            0x1: decode FUNCTION {
352                format System {
353                    0x01: tlbr({{ }});
354                    0x02: tlbwi({{ }});
355                    0x06: tlbwr({{ }});
356                    0x08: tlbp({{ }});
357                }
358
359                format WarnUnimpl {
360                    0x18: eret();
361                    0x1F: deret();
362                    0x20: wait();
363                }
364            }
365        }
366
367        //Table A-13 MIPS32 COP1 Encoding of rs Field
368        0x1: decode RS_MSB {
369
370            0x0: decode RS_HI {
371                0x0: decode RS_LO {
372                    format FloatOp {
373                        0x0: mfc1({{ /*Rt.uw = Fs.ud<31:0>;*/ }});
374                        0x2: cfc1({{ /*Rt.uw = xc->readMiscReg(FPCR[Fs]);*/}});
375                        0x3: mfhc1({{ /*Rt.uw = Fs.ud<63:32>*/;}});
376                        0x4: mtc1({{ /*Fs = Rt.uw*/}});
377                        0x6: ctc1({{ /*xc->setMiscReg(FPCR[Fs],Rt);*/}});
378                        0x7: mthc1({{ /*Fs<63:32> = Rt.uw*/}});
379                    }
380                }
381
382                0x1: decode ND {
383                    0x0: decode TF {
384                        format Branch {
385                            0x0: bc1f({{ cond = (xc->readMiscReg(FPCR) == 0); }});
386                            0x1: bc1t({{ cond = (xc->readMiscReg(FPCR) == 1); }});
387                        }
388                    }
389
390                    0x1: decode TF {
391                        format BranchLikely {
392                            0x0: bc1fl({{ cond = (xc->readMiscReg(FPCR) == 0); }});
393                            0x1: bc1tl({{ cond = (xc->readMiscReg(FPCR) == 1); }});
394                        }
395                    }
396                }
397            }
398
399            0x1: decode RS_HI {
400                0x2: decode RS_LO {
401
402                    //Table A-14 MIPS32 COP1 Encoding of Function Field When rs=S
403                    //(( single-word ))
404                    0x0: decode RS_HI {
405                        0x0: decode RS_LO {
406                            format FloatOp {
407                                0x0: adds({{ Fd.sf = Fs.sf + Ft.sf;}});
408                                0x1: subs({{ Fd.sf = Fs.sf - Ft.sf;}});
409                                0x2: muls({{ Fd.sf = Fs.sf * Ft.sf;}});
410                                0x3: divs({{ Fd.sf = Fs.sf / Ft.sf;}});
411                                0x4: sqrts({{ Fd.sf = sqrt(Fs.sf);}});
412                                0x5: abss({{ Fd.sf = fabs(Fs.sf);}});
413                                0x6: movs({{ Fd.sf = Fs.sf;}});
414                                0x7: negs({{ Fd.sf = -1 * Fs.sf;}});
415                            }
416                        }
417
418                        0x1: decode RS_LO {
419                            //only legal for 64 bit-FP
420                            format Float64Op {
421                                0x0: round_l_s({{ Fd = convert_and_round(Fs.sf,RND_NEAREST,FP_LONG,FP_SINGLE);}});
422                                0x1: trunc_l_s({{ Fd = convert_and_round(Fs.sf,RND_ZERO,FP_LONG,FP_SINGLE);}});
423                                0x2: ceil_l_s({{ Fd = convert_and_round(Fs.sf,RND_UP,FP_LONG,FP_SINGLE);}});
424                                0x3: floor_l_s({{ Fd = convert_and_round(Fs.sf,RND_DOWN,FP_LONG,FP_SINGLE);}});
425                            }
426
427                            format FloatOp {
428                                0x4: round_w_s({{ Fd = convert_and_round(Fs.sf,RND_NEAREST,FP_WORD,FP_SINGLE);}});
429                                0x5: trunc_w_s({{ Fd = convert_and_round(Fs.sf,RND_ZERO,FP_WORD,FP_SINGLE);}});
430                                0x6: ceil_w_s({{  Fd = convert_and_round(Fs.sf,RND_UP,FP_WORD,FP_SINGLE);}});
431                                0x7: floor_w_s({{ Fd = convert_and_round(Fs.sf,RND_DOWN,FP_WORD,FP_SINGLE);}});
432                            }
433                        }
434
435                        0x2: decode RS_LO {
436                            0x1: decode MOVCF {
437                                format FloatOp {
438                                    0x0: movfs({{if (xc->readMiscReg(FPCR) != CC) Fd = Fs; }});
439                                    0x1: movts({{if (xc->readMiscReg(FPCR) == CC) Fd = Fs;}});
440                                }
441                            }
442
443                            format BasicOp {
444                                0x2: movzs({{ if (Rt == 0) Fd = Fs; }});
445                                0x3: movns({{ if (Rt != 0) Fd = Fs; }});
446                            }
447
448                            format Float64Op {
449                                0x5: recips({{ Fd = 1 / Fs; }});
450                                0x6: rsqrts({{ Fd = 1 / sqrt((double)Fs.ud);}});
451                            }
452                        }
453
454                        0x4: decode RS_LO {
455
456                            format FloatOp {
457                                0x1: cvt_d_s({{ int rnd_mode = xc->readMiscReg(FCSR);
458                                Fd = convert_and_round(Fs.sf,rnd_mode,FP_DOUBLE,FP_SINGLE);
459                                }});
460
461                                0x4: cvt_w_s({{ int rnd_mode = xc->readMiscReg(FCSR);
462                                Fd = convert_and_round(Fs.sf,rnd_mode,FP_WORD,FP_SINGLE);
463                                }});
464                            }
465
466                            //only legal for 64 bit
467                            format Float64Op {
468                                0x5: cvt_l_s({{ int rnd_mode = xc->readMiscReg(FCSR);
469                                Fd = convert_and_round(Fs.sf,rnd_mode,FP_LONG,FP_SINGLE);
470                                }});
471
472                                0x6: cvt_ps_s({{ /*Fd.df = Fs.df<31:0> | Ft.df<31:0>;*/ }});
473                            }
474                        }
475                    }
476
477                    //Table A-15 MIPS32 COP1 Encoding of Function Field When rs=D
478                    0x1: decode RS_HI {
479                        0x0: decode RS_LO {
480                            format FloatOp {
481                                0x0: addd({{ Fd.df = Fs.df + Ft.df;}});
482                                0x1: subd({{ Fd.df = Fs.df - Ft.df;}});
483                                0x2: muld({{ Fd.df = Fs.df * Ft.df;}});
484                                0x3: divd({{ Fd.df = Fs.df / Ft.df;}});
485                                0x4: sqrtd({{ Fd.df = sqrt(Fs.df);}});
486                                0x5: absd({{ Fd.df = fabs(Fs.df);}});
487                                0x6: movd({{ Fd.df = Fs.df;}});
488                                0x7: negd({{ Fd.df = -1 * Fs.df;}});
489                            }
490                        }
491
492                        0x1: decode RS_LO {
493                            //only legal for 64 bit
494                            format Float64Op {
495                                0x0: round_l_d({{ Fd = convert_and_round(Fs.df,RND_NEAREST,FP_LONG,FP_DOUBLE); }});
496                                0x1: trunc_l_d({{ Fd = convert_and_round(Fs.df,RND_ZERO,FP_LONG,FP_DOUBLE);}});
497                                0x2: ceil_l_d({{ Fd = convert_and_round(Fs.df,RND_UP,FP_LONG,FP_DOUBLE);}});
498                                0x3: floor_l_d({{ Fd = convert_and_round(Fs.df,RND_DOWN,FP_LONG,FP_DOUBLE);}});
499                            }
500
501                            format FloatOp {
502                                0x4: round_w_d({{ Fd = convert_and_round(Fs.df,RND_NEAREST,FP_LONG,FP_DOUBLE); }});
503                                0x5: trunc_w_d({{ Fd = convert_and_round(Fs.df,RND_ZERO,FP_LONG,FP_DOUBLE); }});
504                                0x6: ceil_w_d({{  Fd = convert_and_round(Fs.df,RND_UP,FP_LONG,FP_DOUBLE); }});
505                                0x7: floor_w_d({{ Fd = convert_and_round(Fs.df,RND_DOWN,FP_LONG,FP_DOUBLE); }});
506                            }
507                        }
508
509                        0x2: decode RS_LO {
510                            0x1: decode MOVCF {
511                                format FloatOp {
512                                    0x0: movfd({{if (xc->readMiscReg(FPCR) != CC) Fd.df = Fs.df; }});
513                                    0x1: movtd({{if (xc->readMiscReg(FPCR) == CC) Fd.df = Fs.df; }});
514                                }
515                            }
516
517                            format BasicOp {
518                                0x2: movzd({{ if (Rt == 0) Fd.df = Fs.df; }});
519                                0x3: movnd({{ if (Rt != 0) Fd.df = Fs.df; }});
520                            }
521
522                            format Float64Op {
523                                0x5: recipd({{ Fd.df = 1 / Fs.df}});
524                                0x6: rsqrtd({{ Fd.df = 1 / sqrt(Fs.df) }});
525                            }
526                        }
527
528                        0x4: decode RS_LO {
529                            format FloatOp {
530                                0x0: cvt_s_d({{
531                                    int rnd_mode = xc->readMiscReg(FCSR);
532                                    Fd = convert_and_round(Fs.df,rnd_mode,FP_SINGLE,FP_DOUBLE);
533                                }});
534
535                                0x4: cvt_w_d({{
536                                    int rnd_mode = xc->readMiscReg(FCSR);
537                                    Fd = convert_and_round(Fs.df,rnd_mode,FP_WORD,FP_DOUBLE);
538                                }});
539                            }
540
541                            //only legal for 64 bit
542                            format Float64Op {
543                                0x5: cvt_l_d({{
544                                    int rnd_mode = xc->readMiscReg(FCSR);
545                                    Fd = convert_and_round(Fs.df,rnd_mode,FP_LONG,FP_DOUBLE);
546                                }});
547                            }
548                        }
549                    }
550
551                    //Table A-16 MIPS32 COP1 Encoding of Function Field When rs=W
552                    0x4: decode FUNCTION {
553                        format FloatOp {
554                            0x20: cvt_s({{
555                                int rnd_mode = xc->readMiscReg(FCSR);
556                                Fd = convert_and_round(Fs.df,rnd_mode,FP_SINGLE,FP_WORD);
557                            }});
558
559                            0x21: cvt_d({{
560                                int rnd_mode = xc->readMiscReg(FCSR);
561                                Fd = convert_and_round(Fs.df,rnd_mode,FP_DOUBLE,FP_WORD);
562                            }});
563                        }
564                    }
565
566                    //Table A-16 MIPS32 COP1 Encoding of Function Field When rs=L1
567                    //Note: "1. Format type L is legal only if 64-bit floating point operations
568                    //are enabled."
569                    0x5: decode FUNCTION_HI {
570                        format FloatOp {
571                            0x10: cvt_s_l({{
572                                int rnd_mode = xc->readMiscReg(FCSR);
573                                Fd = convert_and_round(Fs.df,rnd_mode,FP_SINGLE,FP_LONG);
574                            }});
575
576                            0x11: cvt_d_l({{
577                                int rnd_mode = xc->readMiscReg(FCSR);
578                                Fd = convert_and_round(Fs.df,rnd_mode,FP_DOUBLE,FP_LONG);
579                            }});
580                        }
581                    }
582
583                    //Table A-17 MIPS64 COP1 Encoding of Function Field When rs=PS1
584                    //Note: "1. Format type PS is legal only if 64-bit floating point operations
585                    //are enabled. "
586                    0x6: decode RS_HI {
587                        0x0: decode RS_LO {
588                            format Float64Op {
589                                0x0: addps({{ //Must Check for Exception Here... Supposed to Operate on Upper and
590                                    //Lower Halves Independently but we take simulator shortcut
591                                    Fd.df = Fs.df + Ft.df;
592                                }});
593
594                                0x1: subps({{ //Must Check for Exception Here... Supposed to Operate on Upper and
595                                    //Lower Halves Independently but we take simulator shortcut
596                                    Fd.df = Fs.df - Ft.df;
597                                }});
598
599                                0x2: mulps({{ //Must Check for Exception Here... Supposed to Operate on Upper and
600                                    //Lower Halves Independently but we take simulator shortcut
601                                    Fd.df = Fs.df * Ft.df;
602                                }});
603
604                                0x5: absps({{ //Must Check for Exception Here... Supposed to Operate on Upper and
605                                    //Lower Halves Independently but we take simulator shortcut
606                                    Fd.df = fabs(Fs.df);
607                                }});
608
609                                0x6: movps({{ //Must Check for Exception Here... Supposed to Operate on Upper and
610                                    //Lower Halves Independently but we take simulator shortcut
611                                    //Fd.df = Fs<31:0> |  Ft<31:0>;
612                                }});
613
614                                0x7: negps({{ //Must Check for Exception Here... Supposed to Operate on Upper and
615                                    //Lower Halves Independently but we take simulator shortcut
616                                    Fd.df = -1 * Fs.df;
617                                }});
618                            }
619                        }
620
621                        0x2: decode RS_LO {
622                            0x1: decode MOVCF {
623                                format Float64Op {
624                                    0x0: movfps({{if (xc->readMiscReg(FPCR) != CC) Fd = Fs;}});
625                                    0x1: movtps({{if (xc->readMiscReg(FPCR) == CC) Fd = Fs;}});
626                                }
627                            }
628
629                            format BasicOp {
630                                0x2: movzps({{if (xc->readMiscReg(FPCR) != CC) Fd = Fs; }});
631                                0x3: movnps({{if (xc->readMiscReg(FPCR) == CC) Fd = Fs; }});
632                            }
633
634                        }
635
636                        0x4: decode RS_LO {
637                            0x0: Float64Op::cvt_s_pu({{
638                                int rnd_mode = xc->readMiscReg(FCSR);
639                                Fd = convert_and_round(Fs.df,rnd_mode,FP_DOUBLE,FP_PS_HI);
640                            }});
641                        }
642
643                        0x5: decode RS_LO {
644                            format Float64Op {
645                                0x0: cvt_s_pl({{
646                                    int rnd_mode = xc->readMiscReg(FCSR);
647                                    Fd = convert_and_round(Fs.df,rnd_mode,FP_SINGLE,FP_PS_LO);
648                                }});
649                                0x4: pll({{ /*Fd.df = Fs<31:0> | Ft<31:0>*/}});
650                                0x5: plu({{ /*Fd.df = Fs<31:0> | Ft<63:32>*/}});
651                                0x6: pul({{ /*Fd.df = Fs<63:32> | Ft<31:0>*/}});
652                                0x7: puu({{ /*Fd.df = Fs<63:32 | Ft<63:32>*/}});
653                            }
654                        }
655                    }
656                }
657            }
658        }
659
660        //Table A-19 MIPS32 COP2 Encoding of rs Field
661        0x2: decode RS_MSB {
662            0x0: decode RS_HI {
663                0x0: decode RS_LO {
664                    format WarnUnimpl {
665                        0x0: mfc2();
666                        0x2: cfc2();
667                        0x3: mfhc2();
668                        0x4: mtc2();
669                        0x6: ctc2();
670                        0x7: mftc2();
671                    }
672                }
673
674                0x1: decode ND {
675                    0x0: decode TF {
676                        format WarnUnimpl {
677                            0x0: bc2f();
678                            0x1: bc2t();
679                        }
680                    }
681
682                    0x1: decode TF {
683                        format WarnUnimpl {
684                            0x0: bc2fl();
685                            0x1: bc2tl();
686                        }
687                    }
688                }
689            }
690        }
691
692        //Table A-20 MIPS64 COP1X Encoding of Function Field 1
693        //Note: "COP1X instructions are legal only if 64-bit floating point
694        //operations are enabled."
695        0x3: decode FUNCTION_HI {
696            0x0: decode FUNCTION_LO {
697                format LoadMemory2 {
698                    0x0: lwxc1({{ EA = Rs + Rt; }},{{ /*F_t<31:0> = Mem.sf; */}});
699                    0x1: ldxc1({{ EA = Rs + Rt; }},{{ /*F_t<63:0> = Mem.df;*/ }});
700                    0x5: luxc1({{ //Need to make EA<2:0> = 0
701                        EA = Rs + Rt;
702                    }},
703                {{ /*F_t<31:0> = Mem.df; */}});
704                }
705            }
706
707            0x1: decode FUNCTION_LO {
708                format StoreMemory2 {
709                    0x0: swxc1({{ EA = Rs + Rt; }},{{ /*Mem.sf = Ft<31:0>; */}});
710                    0x1: sdxc1({{ EA = Rs + Rt; }},{{ /*Mem.df = Ft<63:0> */}});
711                    0x5: suxc1({{ //Need to make EA<2:0> = 0
712                        EA = Rs + Rt;
713                    }},
714                {{ /*Mem.df = F_t<63:0>;*/}});
715                }
716
717                0x7: WarnUnimpl::prefx();
718            }
719
720            format FloatOp {
721                0x3: WarnUnimpl::alnv_ps();
722
723                format BasicOp {
724                    0x4: decode FUNCTION_LO {
725                        0x0: madd_s({{ Fd.sf = (Fs.sf * Fs.sf) + Fr.sf; }});
726                        0x1: madd_d({{ Fd.df = (Fs.df * Fs.df) + Fr.df; }});
727                        0x6: madd_ps({{
728                            //Must Check for Exception Here... Supposed to Operate on Upper and
729                            //Lower Halves Independently but we take simulator shortcut
730                            Fd.df = (Fs.df * Fs.df) + Fr.df;
731                        }});
732                    }
733
734                    0x5: decode FUNCTION_LO {
735                        0x0: msub_s({{ Fd.sf = (Fs.sf * Fs.sf) - Fr.sf; }});
736                        0x1: msub_d({{ Fd.df = (Fs.df * Fs.df) - Fr.df; }});
737                        0x6: msub_ps({{
738                            //Must Check for Exception Here... Supposed to Operate on Upper and
739                            //Lower Halves Independently but we take simulator shortcut
740                            Fd.df = (Fs.df * Fs.df) - Fr.df;
741                        }});
742                    }
743
744                    0x6: decode FUNCTION_LO {
745                        0x0: nmadd_s({{ Fd.sf = (-1 * Fs.sf * Fs.sf) - Fr.sf; }});
746                        0x1: nmadd_d({{ Fd.df = (-1 * Fs.df * Fs.df) + Fr.df; }});
747                        0x6: nmadd_ps({{
748                            //Must Check for Exception Here... Supposed to Operate on Upper and
749                            //Lower Halves Independently but we take simulator shortcut
750                            Fd.df = (-1 * Fs.df * Fs.df) + Fr.df;
751                        }});
752                    }
753
754                    0x7: decode FUNCTION_LO {
755                        0x0: nmsub_s({{ Fd.sf = (-1 * Fs.sf * Fs.sf) - Fr.sf; }});
756                        0x1: nmsub_d({{ Fd.df = (-1 * Fs.df * Fs.df) - Fr.df; }});
757                        0x6: nmsub_ps({{
758                            //Must Check for Exception Here... Supposed to Operate on Upper and
759                            //Lower Halves Independently but we take simulator shortcut
760                            Fd.df = (-1 * Fs.df * Fs.df) + Fr.df;
761                        }});
762                    }
763                }
764            }
765        }
766
767        //MIPS obsolete instructions
768        format BranchLikely {
769            0x4: beql({{ cond = (Rs.sw == 0); }});
770            0x5: bnel({{ cond = (Rs.sw != 0); }});
771            0x6: blezl({{ cond = (Rs.sw <= 0); }});
772            0x7: bgtzl({{ cond = (Rs.sw > 0); }});
773        }
774    }
775
776    0x3: decode OPCODE_LO default FailUnimpl::reserved() {
777
778        //Table A-5 MIPS32 SPECIAL2 Encoding of Function Field
779        0x4: decode FUNCTION_HI {
780
781            0x0: decode FUNCTION_LO {
782                format IntOp {
783                    0x0: madd({{
784                        int64_t temp1 = xc->readMiscReg(Hi) << 32 | xc->readMiscReg(Lo) >> 32;
785                        temp1 = temp1 + (Rs.sw * Rt.sw);
786                        xc->setMiscReg(Hi,temp1<63:32>);
787                        xc->setMiscReg(Lo,temp1<31:0>);
788                            }});
789
790                    0x1: maddu({{
791                        int64_t temp1 = xc->readMiscReg(Hi) << 32 | xc->readMiscReg(Lo) >> 32;
792                        temp1 = temp1 + (Rs.uw * Rt.uw);
793                        xc->setMiscReg(Hi,temp1<63:32>);
794                        xc->setMiscReg(Lo,temp1<31:0>);
795                            }});
796
797                    0x2: mul({{ Rd.sw = Rs.sw * Rt.sw; 	}});
798
799                    0x4: msub({{
800                        int64_t temp1 = xc->readMiscReg(Hi) << 32 | xc->readMiscReg(Lo) >> 32;
801                        temp1 = temp1 - (Rs.sw * Rt.sw);
802                        xc->setMiscReg(Hi,temp1<63:32>);
803                        xc->setMiscReg(Lo,temp1<31:0>);
804                            }});
805
806                    0x5: msubu({{
807                        int64_t temp1 = xc->readMiscReg(Hi) << 32 | xc->readMiscReg(Lo) >> 32;
808                        temp1 = temp1 - (Rs.uw * Rt.uw);
809                        xc->setMiscReg(Hi,temp1<63:32>);
810                        xc->setMiscReg(Lo,temp1<31:0>);
811                            }});
812                }
813            }
814
815            0x4: decode FUNCTION_LO {
816                format BasicOp {
817                    0x0: clz({{
818                        /*int cnt = 0;
819                        int idx = 0;
820                        while ( Rs.uw<idx> != 1) {
821                            cnt++;
822                            idx--;
823                        }
824
825                        Rd.uw = cnt;*/
826                    }});
827
828                    0x1: clo({{
829                        /*int cnt = 0;
830                        int idx = 0;
831                        while ( Rs.uw<idx> != 0) {
832                            cnt++;
833                            idx--;
834                        }
835
836                        Rd.uw = cnt;*/
837                    }});
838                }
839            }
840
841            0x7: decode FUNCTION_LO {
842                0x7: WarnUnimpl::sdbbp();
843            }
844        }
845
846        //Table A-6 MIPS32 SPECIAL3 Encoding of Function Field for Release 2 of the Architecture
847        0x7: decode FUNCTION_HI {
848
849            0x0: decode FUNCTION_LO {
850                format WarnUnimpl {
851                    0x1: ext();
852                    0x4: ins();
853                }
854            }
855
856            0x1: decode FUNCTION_LO {
857                format WarnUnimpl {
858                    0x0: fork();
859                    0x1: yield();
860                }
861            }
862
863
864            //Table A-10 MIPS32 BSHFL Encoding of sa Field
865            0x4: decode SA {
866
867                0x02: WarnUnimpl::wsbh();
868
869                format BasicOp {
870                    0x10: seb({{ Rd.sw = /* sext32(Rt<7>,24)  | */ Rt<7:0>}});
871                    0x18: seh({{ Rd.sw = /* sext32(Rt<15>,16) | */ Rt<15:0>}});
872                }
873            }
874
875            0x6: decode FUNCTION_LO {
876                0x7: BasicOp::rdhwr({{ /*Rt = xc->hwRegs[RD];*/ }});
877            }
878        }
879    }
880
881    0x4: decode OPCODE_LO default FailUnimpl::reserved() {
882        format LoadMemory {
883            0x0: lb({{ Rt.sw = Mem.sb; }});
884            0x1: lh({{ Rt.sw = Mem.sh; }});
885            0x2: lwl({{ Rt.sw = Mem.sw; }});//, WordAlign);
886            0x3: lw({{ Rt.sw = Mem.sb; }});
887            0x4: lbu({{ Rt.uw = Mem.ub; }});
888            0x5: lhu({{ Rt.uw = Mem.uh; }});
889            0x6: lwr({{ Rt.uw = Mem.uw; }});//, WordAlign);
890        }
891
892        0x7: FailUnimpl::reserved();
893    }
894
895    0x5: decode OPCODE_LO default FailUnimpl::reserved() {
896        format StoreMemory {
897            0x0: sb({{ Mem.ub = Rt<7:0>; }});
898            0x1: sh({{ Mem.uh = Rt<15:0>; }});
899            0x2: swl({{ Mem.ub = Rt<31:0>; }});//,WordAlign);
900            0x3: sw({{ Mem.ub = Rt<31:0>; }});
901            0x6: swr({{ Mem.ub = Rt<31:0>; }});//,WordAlign);
902        }
903
904        format WarnUnimpl {
905            0x7: cache();
906        }
907
908    }
909
910    0x6: decode OPCODE_LO default FailUnimpl::reserved() {
911        0x0: WarnUnimpl::ll();
912
913        format LoadMemory {
914            0x1: lwc1({{ /*F_t<31:0> = Mem.sf; */}});
915            0x5: ldc1({{ /*F_t<63:0> = Mem.df; */}});
916        }
917    }
918
919
920    0x7: decode OPCODE_LO default FailUnimpl::reserved() {
921        0x0: WarnUnimpl::sc();
922
923        format StoreMemory {
924            0x1: swc1({{ //Mem.sf = Ft<31:0>; }});
925            0x5: sdc1({{ //Mem.df = Ft<63:0>; }});
926        }
927    }
928}
929
930
931