decoder.isa revision 2470
111986Sandreas.sandberg@arm.com// -*- mode:c++ -*-
211986Sandreas.sandberg@arm.com
311986Sandreas.sandberg@arm.com////////////////////////////////////////////////////////////////////
411986Sandreas.sandberg@arm.com//
511986Sandreas.sandberg@arm.com// The actual MIPS32 ISA decoder
611986Sandreas.sandberg@arm.com// -----------------------------
711986Sandreas.sandberg@arm.com// The following instructions are specified in the MIPS32 ISA
811986Sandreas.sandberg@arm.com// Specification. Decoding closely follows the style specified
911986Sandreas.sandberg@arm.com// in the MIPS32 ISAthe specification document starting with Table
1011986Sandreas.sandberg@arm.com// A-2 (document available @ www.mips.com)
1111986Sandreas.sandberg@arm.com//
1211986Sandreas.sandberg@arm.com//@todo: Distinguish "unknown/future" use insts from "reserved"
1311986Sandreas.sandberg@arm.com// ones
1411986Sandreas.sandberg@arm.comdecode OPCODE_HI default Unknown::unknown() {
1511986Sandreas.sandberg@arm.com
1611986Sandreas.sandberg@arm.com    // Derived From ... Table A-2 MIPS32 ISA Manual
1711986Sandreas.sandberg@arm.com    0x0: decode OPCODE_LO {
1811986Sandreas.sandberg@arm.com
1911986Sandreas.sandberg@arm.com        0x0: decode FUNCTION_HI {
2012037Sandreas.sandberg@arm.com            0x0: decode FUNCTION_LO {
2111986Sandreas.sandberg@arm.com                0x1: decode MOVCI {
2211986Sandreas.sandberg@arm.com                    format BasicOp {
2311986Sandreas.sandberg@arm.com                        0: movf({{ if (xc->readMiscReg(FPCR) != CC) Rd = Rs}});
2411986Sandreas.sandberg@arm.com                        1: movt({{ if (xc->readMiscReg(FPCR) == CC) Rd = Rs}});
2511986Sandreas.sandberg@arm.com                    }
2611986Sandreas.sandberg@arm.com                }
2711986Sandreas.sandberg@arm.com
2811986Sandreas.sandberg@arm.com                format BasicOp {
2911986Sandreas.sandberg@arm.com
3011986Sandreas.sandberg@arm.com                    //Table A-3 Note: "1. Specific encodings of the rt, rd, and sa fields
3111986Sandreas.sandberg@arm.com                    //are used to distinguish among the SLL, NOP, SSNOP and EHB functions."
3211986Sandreas.sandberg@arm.com
3311986Sandreas.sandberg@arm.com                    0x0: decode RS  {
3411986Sandreas.sandberg@arm.com                        0x0: decode RT {
3511986Sandreas.sandberg@arm.com                                 0x0: decode RD default Nop::nop() {
3611986Sandreas.sandberg@arm.com                                  0x0: decode SA {
3711986Sandreas.sandberg@arm.com                                      0x1: ssnop({{ ; }});  //really sll r0,r0,1
3811986Sandreas.sandberg@arm.com                                      0x3: ehb({{ ; }});  //really sll r0,r0,3
3911986Sandreas.sandberg@arm.com                                  }
4011986Sandreas.sandberg@arm.com                             }
4111986Sandreas.sandberg@arm.com                        }
4211986Sandreas.sandberg@arm.com
4311986Sandreas.sandberg@arm.com                      default: sll({{ Rd = Rt.uw << SA; }});
4411986Sandreas.sandberg@arm.com                    }
4511986Sandreas.sandberg@arm.com
4611986Sandreas.sandberg@arm.com                    0x2: decode SRL {
4711986Sandreas.sandberg@arm.com                        0: srl({{ Rd = Rt.uw >> SA; }});
4811986Sandreas.sandberg@arm.com
4911986Sandreas.sandberg@arm.com                        //Hardcoded assuming 32-bit ISA, probably need parameter here
5011986Sandreas.sandberg@arm.com                        1: rotr({{ Rd = (Rt.uw << (32 - SA)) | (Rt.uw >> SA);}});
5111986Sandreas.sandberg@arm.com                    }
5211986Sandreas.sandberg@arm.com
5311986Sandreas.sandberg@arm.com                    0x3: sra({{ Rd = Rt.sw >> SA; }});
5411986Sandreas.sandberg@arm.com
5511986Sandreas.sandberg@arm.com                    0x4: sllv({{ Rd = Rt.uw << Rs<4:0>; }});
5611986Sandreas.sandberg@arm.com
5711986Sandreas.sandberg@arm.com                    0x6: decode SRLV {
5811986Sandreas.sandberg@arm.com                        0: srlv({{ Rd = Rt.uw >> Rs<4:0>; }});
5911986Sandreas.sandberg@arm.com
6011986Sandreas.sandberg@arm.com                        //Hardcoded assuming 32-bit ISA, probably need parameter here
6111986Sandreas.sandberg@arm.com                        1: rotrv({{ Rd = (Rt.uw << (32 - Rs<4:0>)) | (Rt.uw >> Rs<4:0>);}});
6211986Sandreas.sandberg@arm.com                    }
6311986Sandreas.sandberg@arm.com
6411986Sandreas.sandberg@arm.com                    0x7: srav({{ Rd = Rt.sw >> Rs<4:0>; }});
6511986Sandreas.sandberg@arm.com                }
6611986Sandreas.sandberg@arm.com            }
6711986Sandreas.sandberg@arm.com
6811986Sandreas.sandberg@arm.com            0x1: decode FUNCTION_LO {
6911986Sandreas.sandberg@arm.com
7011986Sandreas.sandberg@arm.com                //Table A-3 Note: "Specific encodings of the hint field are used
7112037Sandreas.sandberg@arm.com                //to distinguish JR from JR.HB and JALR from JALR.HB"
7212037Sandreas.sandberg@arm.com                format Jump {
7312037Sandreas.sandberg@arm.com                    0x0: decode HINT {
7412037Sandreas.sandberg@arm.com                        0:jr({{ NNPC = Rs & ~1; }},IsReturn);
7512037Sandreas.sandberg@arm.com
7612037Sandreas.sandberg@arm.com                        1:jr_hb({{ NNPC = Rs & ~1; clear_exe_inst_hazards(); }},IsReturn);
7712037Sandreas.sandberg@arm.com                    }
7812037Sandreas.sandberg@arm.com
7912037Sandreas.sandberg@arm.com                    0x1: decode HINT {
8012037Sandreas.sandberg@arm.com                        0: jalr({{ NNPC = Rs; }},IsCall,IsReturn);
8112037Sandreas.sandberg@arm.com
8212037Sandreas.sandberg@arm.com                        1: jalr_hb({{ NNPC = Rs; clear_exe_inst_hazards();}},IsCall,IsReturn);
8312037Sandreas.sandberg@arm.com                    }
8412037Sandreas.sandberg@arm.com                }
8512037Sandreas.sandberg@arm.com
8611986Sandreas.sandberg@arm.com                format BasicOp {
8711986Sandreas.sandberg@arm.com                    0x2: movz({{ if (Rt == 0) Rd = Rs; }});
8811986Sandreas.sandberg@arm.com                    0x3: movn({{ if (Rt != 0) Rd = Rs; }});
8911986Sandreas.sandberg@arm.com                }
9011986Sandreas.sandberg@arm.com
9111986Sandreas.sandberg@arm.com                format WarnUnimpl {
9211986Sandreas.sandberg@arm.com                    0x4: syscall();//{{ xc->syscall()}},IsNonSpeculative
9311986Sandreas.sandberg@arm.com                    0x5: break();
9411986Sandreas.sandberg@arm.com                    0x7: sync();
9511986Sandreas.sandberg@arm.com                }
9611986Sandreas.sandberg@arm.com            }
9711986Sandreas.sandberg@arm.com
9811986Sandreas.sandberg@arm.com            0x2: decode FUNCTION_LO {
9911986Sandreas.sandberg@arm.com                format BasicOp {
10011986Sandreas.sandberg@arm.com                    0x0: mfhi({{ Rd = xc->readMiscReg(Hi); }});
10111986Sandreas.sandberg@arm.com                    0x1: mthi({{ xc->setMiscReg(Hi,Rs); }});
10211986Sandreas.sandberg@arm.com                    0x2: mflo({{ Rd = xc->readMiscReg(Lo); }});
10311986Sandreas.sandberg@arm.com                    0x3: mtlo({{ xc->setMiscReg(Lo,Rs); }});
10411986Sandreas.sandberg@arm.com                }
10511986Sandreas.sandberg@arm.com            }
10611986Sandreas.sandberg@arm.com
10711986Sandreas.sandberg@arm.com            0x3: decode FUNCTION_LO {
10811986Sandreas.sandberg@arm.com                format IntOp {
10911986Sandreas.sandberg@arm.com                    0x0: mult({{
11011986Sandreas.sandberg@arm.com                        int64_t temp1 = Rs.sw * Rt.sw;
11111986Sandreas.sandberg@arm.com                        xc->setMiscReg(Hi,temp1<63:32>);
11211986Sandreas.sandberg@arm.com                        xc->setMiscReg(Lo,temp1<31:0>);
11311986Sandreas.sandberg@arm.com                    }});
11411986Sandreas.sandberg@arm.com
11511986Sandreas.sandberg@arm.com                    0x1: multu({{
11611986Sandreas.sandberg@arm.com                        int64_t temp1 = Rs.uw * Rt.uw;
11711986Sandreas.sandberg@arm.com                        xc->setMiscReg(Hi,temp1<63:32>);
11811986Sandreas.sandberg@arm.com                        xc->setMiscReg(Lo,temp1<31:0>);
11911986Sandreas.sandberg@arm.com                    }});
12011986Sandreas.sandberg@arm.com
12111986Sandreas.sandberg@arm.com                    0x2: div({{
12211986Sandreas.sandberg@arm.com                        xc->setMiscReg(Hi,Rs.sw % Rt.sw);
12311986Sandreas.sandberg@arm.com                        xc->setMiscReg(Lo,Rs.sw / Rt.sw);
12411986Sandreas.sandberg@arm.com                    }});
12511986Sandreas.sandberg@arm.com
12611986Sandreas.sandberg@arm.com                    0x3: divu({{
12711986Sandreas.sandberg@arm.com                        xc->setMiscReg(Hi,Rs.uw % Rt.uw);
12811986Sandreas.sandberg@arm.com                        xc->setMiscReg(Lo,Rs.uw / Rt.uw);
12911986Sandreas.sandberg@arm.com                    }});
13011986Sandreas.sandberg@arm.com                }
13111986Sandreas.sandberg@arm.com            }
13211986Sandreas.sandberg@arm.com
13311986Sandreas.sandberg@arm.com            0x4: decode FUNCTION_LO {
13411986Sandreas.sandberg@arm.com                format IntOp {
13511986Sandreas.sandberg@arm.com                    0x0: add({{  Rd.sw = Rs.sw + Rt.sw;/*Trap on Overflow*/}});
13611986Sandreas.sandberg@arm.com                    0x1: addu({{ Rd.sw = Rs.sw + Rt.sw;}});
13711986Sandreas.sandberg@arm.com                    0x2: sub({{ Rd.sw = Rs.sw - Rt.sw; /*Trap on Overflow*/}});
13811986Sandreas.sandberg@arm.com                    0x3: subu({{ Rd.sw = Rs.sw - Rt.uw;}});
13911986Sandreas.sandberg@arm.com                    0x4: and({{ Rd = Rs & Rt;}});
14011986Sandreas.sandberg@arm.com                    0x5: or({{ Rd = Rs | Rt;}});
14111986Sandreas.sandberg@arm.com                    0x6: xor({{ Rd = Rs ^ Rt;}});
14211986Sandreas.sandberg@arm.com                    0x7: nor({{ Rd = ~(Rs | Rt);}});
14311986Sandreas.sandberg@arm.com                }
14411986Sandreas.sandberg@arm.com            }
14511986Sandreas.sandberg@arm.com
14611986Sandreas.sandberg@arm.com            0x5: decode FUNCTION_LO {
14711986Sandreas.sandberg@arm.com                format IntOp{
14811986Sandreas.sandberg@arm.com                    0x2: slt({{  Rd.sw = ( Rs.sw < Rt.sw ) ? 1 : 0}});
14911986Sandreas.sandberg@arm.com                    0x3: sltu({{ Rd.uw = ( Rs.uw < Rt.uw ) ? 1 : 0}});
15011986Sandreas.sandberg@arm.com                }
15111986Sandreas.sandberg@arm.com            }
15211986Sandreas.sandberg@arm.com
15311986Sandreas.sandberg@arm.com            0x6: decode FUNCTION_LO {
15411986Sandreas.sandberg@arm.com                format Trap {
15511986Sandreas.sandberg@arm.com                    0x0: tge({{  cond = (Rs.sw >= Rt.sw); }});
15611986Sandreas.sandberg@arm.com                    0x1: tgeu({{ cond = (Rs.uw >= Rt.uw); }});
15711986Sandreas.sandberg@arm.com                    0x2: tlt({{ cond = (Rs.sw < Rt.sw); }});
15811986Sandreas.sandberg@arm.com                    0x3: tltu({{ cond = (Rs.uw >= Rt.uw); }});
15911986Sandreas.sandberg@arm.com                    0x4: teq({{ cond = (Rs.sw == Rt.sw); }});
16011986Sandreas.sandberg@arm.com                    0x6: tne({{ cond = (Rs.sw != Rt.sw); }});
16111986Sandreas.sandberg@arm.com                }
16211986Sandreas.sandberg@arm.com            }
16311986Sandreas.sandberg@arm.com        }
16411986Sandreas.sandberg@arm.com
16511986Sandreas.sandberg@arm.com        0x1: decode REGIMM_HI {
16611986Sandreas.sandberg@arm.com            0x0: decode REGIMM_LO {
16711986Sandreas.sandberg@arm.com                format Branch {
16811986Sandreas.sandberg@arm.com                    0x0: bltz({{ cond = (Rs.sw < 0); }});
16912037Sandreas.sandberg@arm.com                    0x1: bgez({{ cond = (Rs.sw >= 0); }});
17012037Sandreas.sandberg@arm.com                }
17112037Sandreas.sandberg@arm.com
17212037Sandreas.sandberg@arm.com                format BranchLikely {
17312037Sandreas.sandberg@arm.com                    //MIPS obsolete instructions
17412037Sandreas.sandberg@arm.com                    0x2: bltzl({{ cond = (Rs.sw < 0); }});
17512037Sandreas.sandberg@arm.com                    0x3: bgezl({{ cond = (Rs.sw >= 0); }});
17612037Sandreas.sandberg@arm.com                }
17712037Sandreas.sandberg@arm.com            }
17812037Sandreas.sandberg@arm.com
17912037Sandreas.sandberg@arm.com            0x1: decode REGIMM_LO {
18012037Sandreas.sandberg@arm.com                format Trap {
18112037Sandreas.sandberg@arm.com                    0x0: tgei( {{ cond = (Rs.sw >= INTIMM); }});
18212037Sandreas.sandberg@arm.com                    0x1: tgeiu({{ cond = (Rs.uw >= INTIMM); }});
18312037Sandreas.sandberg@arm.com                    0x2: tlti( {{ cond = (Rs.sw < INTIMM); }});
18412037Sandreas.sandberg@arm.com                    0x3: tltiu({{ cond = (Rs.uw < INTIMM); }});
18512037Sandreas.sandberg@arm.com                    0x4: teqi( {{ cond = (Rs.sw == INTIMM);}});
18612037Sandreas.sandberg@arm.com                    0x6: tnei( {{ cond = (Rs.sw != INTIMM);}});
18712037Sandreas.sandberg@arm.com                }
18812037Sandreas.sandberg@arm.com            }
18912037Sandreas.sandberg@arm.com
19012037Sandreas.sandberg@arm.com            0x2: decode REGIMM_LO {
19112037Sandreas.sandberg@arm.com                format Branch {
19212037Sandreas.sandberg@arm.com                    0x0: bltzal({{ cond = (Rs.sw < 0); }}, IsCall,IsReturn);
19312037Sandreas.sandberg@arm.com                    0x1: bgezal({{ cond = (Rs.sw >= 0); }}, IsCall,IsReturn);
19412037Sandreas.sandberg@arm.com                }
19512037Sandreas.sandberg@arm.com
19612037Sandreas.sandberg@arm.com                format BranchLikely {
19712037Sandreas.sandberg@arm.com                    //Will be removed in future MIPS releases
19812037Sandreas.sandberg@arm.com                    0x2: bltzall({{ cond = (Rs.sw < 0); }}, IsCall, IsReturn);
19912037Sandreas.sandberg@arm.com                    0x3: bgezall({{ cond = (Rs.sw >= 0); }}, IsCall, IsReturn);
20012037Sandreas.sandberg@arm.com                }
20112037Sandreas.sandberg@arm.com            }
20212037Sandreas.sandberg@arm.com
20312037Sandreas.sandberg@arm.com            0x3: decode REGIMM_LO {
20412037Sandreas.sandberg@arm.com                format WarnUnimpl {
20512037Sandreas.sandberg@arm.com                    0x7: synci();
20612037Sandreas.sandberg@arm.com                }
20712037Sandreas.sandberg@arm.com            }
20812037Sandreas.sandberg@arm.com        }
20912037Sandreas.sandberg@arm.com
21012037Sandreas.sandberg@arm.com        format Jump {
21112037Sandreas.sandberg@arm.com            0x2: j({{ NNPC = (NPC & 0xF0000000) | (JMPTARG << 2);}});
21212037Sandreas.sandberg@arm.com
21312037Sandreas.sandberg@arm.com            0x3: jal({{ NNPC = (NPC & 0xF0000000) | (JMPTARG << 2); }},IsCall,IsReturn);
21412037Sandreas.sandberg@arm.com        }
21512037Sandreas.sandberg@arm.com
21612037Sandreas.sandberg@arm.com        format Branch {
21712037Sandreas.sandberg@arm.com            0x4: beq({{ cond = (Rs.sw == Rt.sw); }});
21812037Sandreas.sandberg@arm.com            0x5: bne({{ cond = (Rs.sw != Rt.sw); }});
21912037Sandreas.sandberg@arm.com            0x6: blez({{ cond = (Rs.sw <= 0); }});
22012037Sandreas.sandberg@arm.com            0x7: bgtz({{ cond = (Rs.sw > 0); }});
22112037Sandreas.sandberg@arm.com        }
22212037Sandreas.sandberg@arm.com    }
22312037Sandreas.sandberg@arm.com
22412037Sandreas.sandberg@arm.com    0x1: decode OPCODE_LO {
22512037Sandreas.sandberg@arm.com        format IntOp {
22612037Sandreas.sandberg@arm.com            0x0: addi({{ Rt.sw = Rs.sw + imm; /*Trap If Overflow*/}});
22712037Sandreas.sandberg@arm.com            0x1: addiu({{ Rt.sw = Rs.sw + imm;}});
22812037Sandreas.sandberg@arm.com            0x2: slti({{ Rt.sw = ( Rs.sw < imm) ? 1 : 0 }});
22912037Sandreas.sandberg@arm.com            0x3: sltiu({{ Rt.sw = ( Rs.sw < imm ) ? 1 : 0 }});
23012037Sandreas.sandberg@arm.com            0x4: andi({{ Rt.sw = Rs.sw & INTIMM;}});
23112037Sandreas.sandberg@arm.com            0x5: ori({{ Rt.sw = Rs.sw | INTIMM;}});
23212037Sandreas.sandberg@arm.com            0x6: xori({{ Rt.sw = Rs.sw ^ INTIMM;}});
23312037Sandreas.sandberg@arm.com            0x7: lui({{ Rt = INTIMM << 16}});
23412037Sandreas.sandberg@arm.com        }
23512037Sandreas.sandberg@arm.com    }
23612037Sandreas.sandberg@arm.com
23712037Sandreas.sandberg@arm.com    0x2: decode OPCODE_LO {
23812037Sandreas.sandberg@arm.com
23912037Sandreas.sandberg@arm.com        //Table A-11 MIPS32 COP0 Encoding of rs Field
24012037Sandreas.sandberg@arm.com        0x0: decode RS_MSB {
24112037Sandreas.sandberg@arm.com            0x0: decode RS {
24212037Sandreas.sandberg@arm.com                format System {
24312037Sandreas.sandberg@arm.com                    0x0: mfc0({{
24412037Sandreas.sandberg@arm.com                        //uint64_t reg_num = Rd.uw;
24512037Sandreas.sandberg@arm.com
24612037Sandreas.sandberg@arm.com                        Rt = xc->readMiscReg(RD << 5 | SEL);
24712037Sandreas.sandberg@arm.com                    }});
24812037Sandreas.sandberg@arm.com
24912037Sandreas.sandberg@arm.com                    0x4: mtc0({{
25012037Sandreas.sandberg@arm.com                        //uint64_t reg_num = Rd.uw;
25112037Sandreas.sandberg@arm.com
25212037Sandreas.sandberg@arm.com                        xc->setMiscReg(RD << 5 | SEL,Rt);
25312037Sandreas.sandberg@arm.com                    }});
25412037Sandreas.sandberg@arm.com
25512037Sandreas.sandberg@arm.com                    0x8: mftr({{
25612037Sandreas.sandberg@arm.com                        //The contents of the coprocessor 0 register specified by the
25712037Sandreas.sandberg@arm.com                        //combination of rd and sel are loaded into general register
25812037Sandreas.sandberg@arm.com                        //rt. Note that not all coprocessor 0 registers support the
25912037Sandreas.sandberg@arm.com                        //sel field. In those instances, the sel field must be zero.
26012037Sandreas.sandberg@arm.com
26112037Sandreas.sandberg@arm.com                        //MT Code Needed Here
26212037Sandreas.sandberg@arm.com                    }});
26312037Sandreas.sandberg@arm.com
26412037Sandreas.sandberg@arm.com                    0xC: mttr({{
26512037Sandreas.sandberg@arm.com                        //The contents of the coprocessor 0 register specified by the
26612037Sandreas.sandberg@arm.com                        //combination of rd and sel are loaded into general register
26711986Sandreas.sandberg@arm.com                        //rt. Note that not all coprocessor 0 registers support the
268                        //sel field. In those instances, the sel field must be zero.
269
270                        //MT Code Needed Here
271                    }});
272
273
274                    0xA: rdpgpr({{
275                        //Accessing Previous Shadow Set Register Number
276                        //uint64_t prev = xc->readMiscReg(SRSCtl)/*[PSS]*/;
277                        //uint64_t reg_num = Rt.uw;
278
279                        //Rd = xc->regs.IntRegFile[prev];
280                       //Rd = xc->shadowIntRegFile[prev][reg_num];
281                    }});
282
283                    0xB: decode RD {
284
285                        0x0: decode SC {
286                            0x0: dvpe({{
287                                Rt.sw = xc->readMiscReg(MVPControl);
288                                xc->setMiscReg(MVPControl,0);
289                            }});
290
291                            0x1: evpe({{
292                                Rt.sw = xc->readMiscReg(MVPControl);
293                                xc->setMiscReg(MVPControl,1);
294                            }});
295                        }
296
297                        0x1: decode SC {
298                            0x0: dmt({{
299                                Rt.sw = xc->readMiscReg(VPEControl);
300                                xc->setMiscReg(VPEControl,0);
301                            }});
302
303                            0x1: emt({{
304                                Rt.sw = xc->readMiscReg(VPEControl);
305                                xc->setMiscReg(VPEControl,1);
306                            }});
307                        }
308
309                        0xC: decode SC {
310                            0x0: di({{
311                                Rt.sw = xc->readMiscReg(Status);
312                                xc->setMiscReg(Status,0);
313                            }});
314
315                            0x1: ei({{
316                                Rt.sw = xc->readMiscReg(Status);
317                                xc->setMiscReg(Status,1);
318                            }});
319                        }
320                    }
321
322                    0xE: wrpgpr({{
323                        //Accessing Previous Shadow Set Register Number
324                        //uint64_t prev = xc->readMiscReg(SRSCtl/*[PSS]*/);
325                        //uint64_t reg_num = Rd.uw;
326
327                        //xc->regs.IntRegFile[prev];
328                        //xc->shadowIntRegFile[prev][reg_num] = Rt;
329                    }});
330                }
331            }
332
333            //Table A-12 MIPS32 COP0 Encoding of Function Field When rs=CO
334            0x1: decode FUNCTION {
335                format System {
336                    0x01: tlbr({{ }});
337                    0x02: tlbwi({{ }});
338                    0x06: tlbwr({{ }});
339                    0x08: tlbp({{ }});
340                }
341
342                format WarnUnimpl {
343                    0x18: eret();
344                    0x1F: deret();
345                    0x20: wait();
346                }
347            }
348        }
349
350        //Table A-13 MIPS32 COP1 Encoding of rs Field
351        0x1: decode RS_MSB {
352
353            0x0: decode RS_HI {
354                0x0: decode RS_LO {
355                    format FloatOp {
356                        0x0: mfc1({{ /*Rt.uw = Fs.ud<31:0>;*/ }});
357                        0x2: cfc1({{ /*Rt.uw = xc->readMiscReg(FPCR[Fs]);*/}});
358                        0x3: mfhc1({{ /*Rt.uw = Fs.ud<63:32>*/;}});
359                        0x4: mtc1({{ /*Fs = Rt.uw*/}});
360                        0x6: ctc1({{ /*xc->setMiscReg(FPCR[Fs],Rt);*/}});
361                        0x7: mthc1({{ /*Fs<63:32> = Rt.uw*/}});
362                    }
363                }
364
365                0x1: decode ND {
366                    0x0: decode TF {
367                        format Branch {
368                            0x0: bc1f({{ cond = (xc->readMiscReg(FPCR) == 0); }});
369                            0x1: bc1t({{ cond = (xc->readMiscReg(FPCR) == 1); }});
370                        }
371                    }
372
373                    0x1: decode TF {
374                        format BranchLikely {
375                            0x0: bc1fl({{ cond = (xc->readMiscReg(FPCR) == 0); }});
376                            0x1: bc1tl({{ cond = (xc->readMiscReg(FPCR) == 1); }});
377                        }
378                    }
379                }
380            }
381
382            0x1: decode RS_HI {
383                0x2: decode RS_LO {
384
385                    //Table A-14 MIPS32 COP1 Encoding of Function Field When rs=S
386                    //(( single-word ))
387                    0x0: decode RS_HI {
388                        0x0: decode RS_LO {
389                            format FloatOp {
390                                0x0: adds({{ Fd.sf = Fs.sf + Ft.sf;}});
391                                0x1: subs({{ Fd.sf = Fs.sf - Ft.sf;}});
392                                0x2: muls({{ Fd.sf = Fs.sf * Ft.sf;}});
393                                0x3: divs({{ Fd.sf = Fs.sf / Ft.sf;}});
394                                0x4: sqrts({{ Fd.sf = sqrt(Fs.sf);}});
395                                0x5: abss({{ Fd.sf = fabs(Fs.sf);}});
396                                0x6: movs({{ Fd.sf = Fs.sf;}});
397                                0x7: negs({{ Fd.sf = -1 * Fs.sf;}});
398                            }
399                        }
400
401                        0x1: decode RS_LO {
402                            //only legal for 64 bit-FP
403                            format Float64Op {
404                                0x0: round_l_s({{ Fd = convert_and_round(Fs.sf,RND_NEAREST,FP_LONG,FP_SINGLE);}});
405                                0x1: trunc_l_s({{ Fd = convert_and_round(Fs.sf,RND_ZERO,FP_LONG,FP_SINGLE);}});
406                                0x2: ceil_l_s({{ Fd = convert_and_round(Fs.sf,RND_UP,FP_LONG,FP_SINGLE);}});
407                                0x3: floor_l_s({{ Fd = convert_and_round(Fs.sf,RND_DOWN,FP_LONG,FP_SINGLE);}});
408                            }
409
410                            format FloatOp {
411                                0x4: round_w_s({{ Fd = convert_and_round(Fs.sf,RND_NEAREST,FP_WORD,FP_SINGLE);}});
412                                0x5: trunc_w_s({{ Fd = convert_and_round(Fs.sf,RND_ZERO,FP_WORD,FP_SINGLE);}});
413                                0x6: ceil_w_s({{  Fd = convert_and_round(Fs.sf,RND_UP,FP_WORD,FP_SINGLE);}});
414                                0x7: floor_w_s({{ Fd = convert_and_round(Fs.sf,RND_DOWN,FP_WORD,FP_SINGLE);}});
415                            }
416                        }
417
418                        0x2: decode RS_LO {
419                            0x1: decode MOVCF {
420                                format FloatOp {
421                                    0x0: movfs({{if (xc->readMiscReg(FPCR) != CC) Fd = Fs; }});
422                                    0x1: movts({{if (xc->readMiscReg(FPCR) == CC) Fd = Fs;}});
423                                }
424                            }
425
426                            format BasicOp {
427                                0x2: movzs({{ if (Rt == 0) Fd = Fs; }});
428                                0x3: movns({{ if (Rt != 0) Fd = Fs; }});
429                            }
430
431                            format Float64Op {
432                                0x5: recips({{ Fd = 1 / Fs; }});
433                                0x6: rsqrts({{ Fd = 1 / sqrt((double)Fs.ud);}});
434                            }
435                        }
436
437                        0x4: decode RS_LO {
438
439                            format FloatOp {
440                                0x1: cvt_d_s({{ int rnd_mode = xc->readMiscReg(FCSR);
441                                Fd = convert_and_round(Fs.sf,rnd_mode,FP_DOUBLE,FP_SINGLE);
442                                }});
443
444                                0x4: cvt_w_s({{ int rnd_mode = xc->readMiscReg(FCSR);
445                                Fd = convert_and_round(Fs.sf,rnd_mode,FP_WORD,FP_SINGLE);
446                                }});
447                            }
448
449                            //only legal for 64 bit
450                            format Float64Op {
451                                0x5: cvt_l_s({{ int rnd_mode = xc->readMiscReg(FCSR);
452                                Fd = convert_and_round(Fs.sf,rnd_mode,FP_LONG,FP_SINGLE);
453                                }});
454
455                                0x6: cvt_ps_s({{ /*Fd.df = Fs.df<31:0> | Ft.df<31:0>;*/ }});
456                            }
457                        }
458                    }
459
460                    //Table A-15 MIPS32 COP1 Encoding of Function Field When rs=D
461                    0x1: decode RS_HI {
462                        0x0: decode RS_LO {
463                            format FloatOp {
464                                0x0: addd({{ Fd.df = Fs.df + Ft.df;}});
465                                0x1: subd({{ Fd.df = Fs.df - Ft.df;}});
466                                0x2: muld({{ Fd.df = Fs.df * Ft.df;}});
467                                0x3: divd({{ Fd.df = Fs.df / Ft.df;}});
468                                0x4: sqrtd({{ Fd.df = sqrt(Fs.df);}});
469                                0x5: absd({{ Fd.df = fabs(Fs.df);}});
470                                0x6: movd({{ Fd.df = Fs.df;}});
471                                0x7: negd({{ Fd.df = -1 * Fs.df;}});
472                            }
473                        }
474
475                        0x1: decode RS_LO {
476                            //only legal for 64 bit
477                            format Float64Op {
478                                0x0: round_l_d({{ Fd = convert_and_round(Fs.df,RND_NEAREST,FP_LONG,FP_DOUBLE); }});
479                                0x1: trunc_l_d({{ Fd = convert_and_round(Fs.df,RND_ZERO,FP_LONG,FP_DOUBLE);}});
480                                0x2: ceil_l_d({{ Fd = convert_and_round(Fs.df,RND_UP,FP_LONG,FP_DOUBLE);}});
481                                0x3: floor_l_d({{ Fd = convert_and_round(Fs.df,RND_DOWN,FP_LONG,FP_DOUBLE);}});
482                            }
483
484                            format FloatOp {
485                                0x4: round_w_d({{ Fd = convert_and_round(Fs.df,RND_NEAREST,FP_LONG,FP_DOUBLE); }});
486                                0x5: trunc_w_d({{ Fd = convert_and_round(Fs.df,RND_ZERO,FP_LONG,FP_DOUBLE); }});
487                                0x6: ceil_w_d({{  Fd = convert_and_round(Fs.df,RND_UP,FP_LONG,FP_DOUBLE); }});
488                                0x7: floor_w_d({{ Fd = convert_and_round(Fs.df,RND_DOWN,FP_LONG,FP_DOUBLE); }});
489                            }
490                        }
491
492                        0x2: decode RS_LO {
493                            0x1: decode MOVCF {
494                                format FloatOp {
495                                    0x0: movfd({{if (xc->readMiscReg(FPCR) != CC) Fd.df = Fs.df; }});
496                                    0x1: movtd({{if (xc->readMiscReg(FPCR) == CC) Fd.df = Fs.df; }});
497                                }
498                            }
499
500                            format BasicOp {
501                                0x2: movzd({{ if (Rt == 0) Fd.df = Fs.df; }});
502                                0x3: movnd({{ if (Rt != 0) Fd.df = Fs.df; }});
503                            }
504
505                            format Float64Op {
506                                0x5: recipd({{ Fd.df = 1 / Fs.df}});
507                                0x6: rsqrtd({{ Fd.df = 1 / sqrt(Fs.df) }});
508                            }
509                        }
510
511                        0x4: decode RS_LO {
512                            format FloatOp {
513                                0x0: cvt_s_d({{
514                                    int rnd_mode = xc->readMiscReg(FCSR);
515                                    Fd = convert_and_round(Fs.df,rnd_mode,FP_SINGLE,FP_DOUBLE);
516                                }});
517
518                                0x4: cvt_w_d({{
519                                    int rnd_mode = xc->readMiscReg(FCSR);
520                                    Fd = convert_and_round(Fs.df,rnd_mode,FP_WORD,FP_DOUBLE);
521                                }});
522                            }
523
524                            //only legal for 64 bit
525                            format Float64Op {
526                                0x5: cvt_l_d({{
527                                    int rnd_mode = xc->readMiscReg(FCSR);
528                                    Fd = convert_and_round(Fs.df,rnd_mode,FP_LONG,FP_DOUBLE);
529                                }});
530                            }
531                        }
532                    }
533
534                    //Table A-16 MIPS32 COP1 Encoding of Function Field When rs=W
535                    0x4: decode FUNCTION {
536                        format FloatOp {
537                            0x20: cvt_s({{
538                                int rnd_mode = xc->readMiscReg(FCSR);
539                                Fd = convert_and_round(Fs.df,rnd_mode,FP_SINGLE,FP_WORD);
540                            }});
541
542                            0x21: cvt_d({{
543                                int rnd_mode = xc->readMiscReg(FCSR);
544                                Fd = convert_and_round(Fs.df,rnd_mode,FP_DOUBLE,FP_WORD);
545                            }});
546                        }
547                    }
548
549                    //Table A-16 MIPS32 COP1 Encoding of Function Field When rs=L1
550                    //Note: "1. Format type L is legal only if 64-bit floating point operations
551                    //are enabled."
552                    0x5: decode FUNCTION_HI {
553                        format FloatOp {
554                            0x10: cvt_s_l({{
555                                int rnd_mode = xc->readMiscReg(FCSR);
556                                Fd = convert_and_round(Fs.df,rnd_mode,FP_SINGLE,FP_LONG);
557                            }});
558
559                            0x11: cvt_d_l({{
560                                int rnd_mode = xc->readMiscReg(FCSR);
561                                Fd = convert_and_round(Fs.df,rnd_mode,FP_DOUBLE,FP_LONG);
562                            }});
563                        }
564                    }
565
566                    //Table A-17 MIPS64 COP1 Encoding of Function Field When rs=PS1
567                    //Note: "1. Format type PS is legal only if 64-bit floating point operations
568                    //are enabled. "
569                    0x6: decode RS_HI {
570                        0x0: decode RS_LO {
571                            format Float64Op {
572                                0x0: addps({{ //Must Check for Exception Here... Supposed to Operate on Upper and
573                                    //Lower Halves Independently but we take simulator shortcut
574                                    Fd.df = Fs.df + Ft.df;
575                                }});
576
577                                0x1: subps({{ //Must Check for Exception Here... Supposed to Operate on Upper and
578                                    //Lower Halves Independently but we take simulator shortcut
579                                    Fd.df = Fs.df - Ft.df;
580                                }});
581
582                                0x2: mulps({{ //Must Check for Exception Here... Supposed to Operate on Upper and
583                                    //Lower Halves Independently but we take simulator shortcut
584                                    Fd.df = Fs.df * Ft.df;
585                                }});
586
587                                0x5: absps({{ //Must Check for Exception Here... Supposed to Operate on Upper and
588                                    //Lower Halves Independently but we take simulator shortcut
589                                    Fd.df = fabs(Fs.df);
590                                }});
591
592                                0x6: movps({{ //Must Check for Exception Here... Supposed to Operate on Upper and
593                                    //Lower Halves Independently but we take simulator shortcut
594                                    //Fd.df = Fs<31:0> |  Ft<31:0>;
595                                }});
596
597                                0x7: negps({{ //Must Check for Exception Here... Supposed to Operate on Upper and
598                                    //Lower Halves Independently but we take simulator shortcut
599                                    Fd.df = -1 * Fs.df;
600                                }});
601                            }
602                        }
603
604                        0x2: decode RS_LO {
605                            0x1: decode MOVCF {
606                                format Float64Op {
607                                    0x0: movfps({{if (xc->readMiscReg(FPCR) != CC) Fd = Fs;}});
608                                    0x1: movtps({{if (xc->readMiscReg(FPCR) == CC) Fd = Fs;}});
609                                }
610                            }
611
612                            format BasicOp {
613                                0x2: movzps({{if (xc->readMiscReg(FPCR) != CC) Fd = Fs; }});
614                                0x3: movnps({{if (xc->readMiscReg(FPCR) == CC) Fd = Fs; }});
615                            }
616
617                        }
618
619                        0x4: decode RS_LO {
620                            0x0: Float64Op::cvt_s_pu({{
621                                int rnd_mode = xc->readMiscReg(FCSR);
622                                Fd = convert_and_round(Fs.df,rnd_mode,FP_DOUBLE,FP_PS_HI);
623                            }});
624                        }
625
626                        0x5: decode RS_LO {
627                            format Float64Op {
628                                0x0: cvt_s_pl({{
629                                    int rnd_mode = xc->readMiscReg(FCSR);
630                                    Fd = convert_and_round(Fs.df,rnd_mode,FP_SINGLE,FP_PS_LO);
631                                }});
632                                0x4: pll({{ /*Fd.df = Fs<31:0> | Ft<31:0>*/}});
633                                0x5: plu({{ /*Fd.df = Fs<31:0> | Ft<63:32>*/}});
634                                0x6: pul({{ /*Fd.df = Fs<63:32> | Ft<31:0>*/}});
635                                0x7: puu({{ /*Fd.df = Fs<63:32 | Ft<63:32>*/}});
636                            }
637                        }
638                    }
639                }
640            }
641        }
642
643        //Table A-19 MIPS32 COP2 Encoding of rs Field
644        0x2: decode RS_MSB {
645            0x0: decode RS_HI {
646                0x0: decode RS_LO {
647                    format WarnUnimpl {
648                        0x0: mfc2();
649                        0x2: cfc2();
650                        0x3: mfhc2();
651                        0x4: mtc2();
652                        0x6: ctc2();
653                        0x7: mftc2();
654                    }
655                }
656
657                0x1: decode ND {
658                    0x0: decode TF {
659                        format WarnUnimpl {
660                            0x0: bc2f();
661                            0x1: bc2t();
662                        }
663                    }
664
665                    0x1: decode TF {
666                        format WarnUnimpl {
667                            0x0: bc2fl();
668                            0x1: bc2tl();
669                        }
670                    }
671                }
672            }
673        }
674
675        //Table A-20 MIPS64 COP1X Encoding of Function Field 1
676        //Note: "COP1X instructions are legal only if 64-bit floating point
677        //operations are enabled."
678        0x3: decode FUNCTION_HI {
679            0x0: decode FUNCTION_LO {
680                format LoadMemory2 {
681                    0x0: lwxc1({{ EA = Rs + Rt; }},{{ /*F_t<31:0> = Mem.sf; */}});
682                    0x1: ldxc1({{ EA = Rs + Rt; }},{{ /*F_t<63:0> = Mem.df;*/ }});
683                    0x5: luxc1({{ //Need to make EA<2:0> = 0
684                        EA = Rs + Rt;
685                    }},
686                {{ /*F_t<31:0> = Mem.df; */}});
687                }
688            }
689
690            0x1: decode FUNCTION_LO {
691                format StoreMemory2 {
692                    0x0: swxc1({{ EA = Rs + Rt; }},{{ /*Mem.sf = Ft<31:0>; */}});
693                    0x1: sdxc1({{ EA = Rs + Rt; }},{{ /*Mem.df = Ft<63:0> */}});
694                    0x5: suxc1({{ //Need to make EA<2:0> = 0
695                        EA = Rs + Rt;
696                    }},
697                {{ /*Mem.df = F_t<63:0>;*/}});
698                }
699
700                0x7: WarnUnimpl::prefx();
701            }
702
703            format FloatOp {
704                0x3: WarnUnimpl::alnv_ps();
705
706                format BasicOp {
707                    0x4: decode FUNCTION_LO {
708                        0x0: madd_s({{ Fd.sf = (Fs.sf * Fs.sf) + Fr.sf; }});
709                        0x1: madd_d({{ Fd.df = (Fs.df * Fs.df) + Fr.df; }});
710                        0x6: madd_ps({{
711                            //Must Check for Exception Here... Supposed to Operate on Upper and
712                            //Lower Halves Independently but we take simulator shortcut
713                            Fd.df = (Fs.df * Fs.df) + Fr.df;
714                        }});
715                    }
716
717                    0x5: decode FUNCTION_LO {
718                        0x0: msub_s({{ Fd.sf = (Fs.sf * Fs.sf) - Fr.sf; }});
719                        0x1: msub_d({{ Fd.df = (Fs.df * Fs.df) - Fr.df; }});
720                        0x6: msub_ps({{
721                            //Must Check for Exception Here... Supposed to Operate on Upper and
722                            //Lower Halves Independently but we take simulator shortcut
723                            Fd.df = (Fs.df * Fs.df) - Fr.df;
724                        }});
725                    }
726
727                    0x6: decode FUNCTION_LO {
728                        0x0: nmadd_s({{ Fd.sf = (-1 * Fs.sf * Fs.sf) - Fr.sf; }});
729                        0x1: nmadd_d({{ Fd.df = (-1 * Fs.df * Fs.df) + Fr.df; }});
730                        0x6: nmadd_ps({{
731                            //Must Check for Exception Here... Supposed to Operate on Upper and
732                            //Lower Halves Independently but we take simulator shortcut
733                            Fd.df = (-1 * Fs.df * Fs.df) + Fr.df;
734                        }});
735                    }
736
737                    0x7: decode FUNCTION_LO {
738                        0x0: nmsub_s({{ Fd.sf = (-1 * Fs.sf * Fs.sf) - Fr.sf; }});
739                        0x1: nmsub_d({{ Fd.df = (-1 * Fs.df * Fs.df) - Fr.df; }});
740                        0x6: nmsub_ps({{
741                            //Must Check for Exception Here... Supposed to Operate on Upper and
742                            //Lower Halves Independently but we take simulator shortcut
743                            Fd.df = (-1 * Fs.df * Fs.df) + Fr.df;
744                        }});
745                    }
746                }
747            }
748        }
749
750        //MIPS obsolete instructions
751        format BranchLikely {
752            0x4: beql({{ cond = (Rs.sw == 0); }});
753            0x5: bnel({{ cond = (Rs.sw != 0); }});
754            0x6: blezl({{ cond = (Rs.sw <= 0); }});
755            0x7: bgtzl({{ cond = (Rs.sw > 0); }});
756        }
757    }
758
759    0x3: decode OPCODE_LO default FailUnimpl::reserved() {
760
761        //Table A-5 MIPS32 SPECIAL2 Encoding of Function Field
762        0x4: decode FUNCTION_HI {
763
764            0x0: decode FUNCTION_LO {
765                format IntOp {
766                    0x0: madd({{
767                        int64_t temp1 = xc->readMiscReg(Hi) << 32 | xc->readMiscReg(Lo) >> 32;
768                        temp1 = temp1 + (Rs.sw * Rt.sw);
769                        xc->setMiscReg(Hi,temp1<63:32>);
770                        xc->setMiscReg(Lo,temp1<31:0>);
771                            }});
772
773                    0x1: maddu({{
774                        int64_t temp1 = xc->readMiscReg(Hi) << 32 | xc->readMiscReg(Lo) >> 32;
775                        temp1 = temp1 + (Rs.uw * Rt.uw);
776                        xc->setMiscReg(Hi,temp1<63:32>);
777                        xc->setMiscReg(Lo,temp1<31:0>);
778                            }});
779
780                    0x2: mul({{ Rd.sw = Rs.sw * Rt.sw; 	}});
781
782                    0x4: msub({{
783                        int64_t temp1 = xc->readMiscReg(Hi) << 32 | xc->readMiscReg(Lo) >> 32;
784                        temp1 = temp1 - (Rs.sw * Rt.sw);
785                        xc->setMiscReg(Hi,temp1<63:32>);
786                        xc->setMiscReg(Lo,temp1<31:0>);
787                            }});
788
789                    0x5: msubu({{
790                        int64_t temp1 = xc->readMiscReg(Hi) << 32 | xc->readMiscReg(Lo) >> 32;
791                        temp1 = temp1 - (Rs.uw * Rt.uw);
792                        xc->setMiscReg(Hi,temp1<63:32>);
793                        xc->setMiscReg(Lo,temp1<31:0>);
794                            }});
795                }
796            }
797
798            0x4: decode FUNCTION_LO {
799                format BasicOp {
800                    0x0: clz({{
801                        /*int cnt = 0;
802                        int idx = 0;
803                        while ( Rs.uw<idx> != 1) {
804                            cnt++;
805                            idx--;
806                        }
807
808                        Rd.uw = cnt;*/
809                    }});
810
811                    0x1: clo({{
812                        /*int cnt = 0;
813                        int idx = 0;
814                        while ( Rs.uw<idx> != 0) {
815                            cnt++;
816                            idx--;
817                        }
818
819                        Rd.uw = cnt;*/
820                    }});
821                }
822            }
823
824            0x7: decode FUNCTION_LO {
825                0x7: WarnUnimpl::sdbbp();
826            }
827        }
828
829        //Table A-6 MIPS32 SPECIAL3 Encoding of Function Field for Release 2 of the Architecture
830        0x7: decode FUNCTION_HI {
831
832            0x0: decode FUNCTION_LO {
833                format WarnUnimpl {
834                    0x1: ext();
835                    0x4: ins();
836                }
837            }
838
839            0x1: decode FUNCTION_LO {
840                format WarnUnimpl {
841                    0x0: fork();
842                    0x1: yield();
843                }
844            }
845
846
847            //Table A-10 MIPS32 BSHFL Encoding of sa Field
848            0x4: decode SA {
849
850                0x02: WarnUnimpl::wsbh();
851
852                format BasicOp {
853                    0x10: seb({{ Rd.sw = /* sext32(Rt<7>,24)  | */ Rt<7:0>}});
854                    0x18: seh({{ Rd.sw = /* sext32(Rt<15>,16) | */ Rt<15:0>}});
855                }
856            }
857
858            0x6: decode FUNCTION_LO {
859                0x7: BasicOp::rdhwr({{ /*Rt = xc->hwRegs[RD];*/ }});
860            }
861        }
862    }
863
864    0x4: decode OPCODE_LO default FailUnimpl::reserved() {
865        format LoadMemory {
866            0x0: lb({{ Rt.sw = Mem.sb; }});
867            0x1: lh({{ Rt.sw = Mem.sh; }});
868            0x2: lwl({{ Rt.sw = Mem.sw; }});//, WordAlign);
869            0x3: lw({{ Rt.sw = Mem.sb; }});
870            0x4: lbu({{ Rt.uw = Mem.ub; }});
871            0x5: lhu({{ Rt.uw = Mem.uh; }});
872            0x6: lwr({{ Rt.uw = Mem.uw; }});//, WordAlign);
873        }
874
875        0x7: FailUnimpl::reserved();
876    }
877
878    0x5: decode OPCODE_LO default FailUnimpl::reserved() {
879        format StoreMemory {
880            0x0: sb({{ Mem.ub = Rt<7:0>; }});
881            0x1: sh({{ Mem.uh = Rt<15:0>; }});
882            0x2: swl({{ Mem.ub = Rt<31:0>; }});//,WordAlign);
883            0x3: sw({{ Mem.ub = Rt<31:0>; }});
884            0x6: swr({{ Mem.ub = Rt<31:0>; }});//,WordAlign);
885        }
886
887        format WarnUnimpl {
888            0x7: cache();
889        }
890
891    }
892
893    0x6: decode OPCODE_LO default FailUnimpl::reserved() {
894        0x0: WarnUnimpl::ll();
895
896        format LoadMemory {
897            0x1: lwc1({{ /*F_t<31:0> = Mem.sf; */}});
898            0x5: ldc1({{ /*F_t<63:0> = Mem.df; */}});
899        }
900    }
901
902
903    0x7: decode OPCODE_LO default FailUnimpl::reserved() {
904        0x0: WarnUnimpl::sc();
905
906        format StoreMemory {
907            0x1: swc1({{ //Mem.sf = Ft<31:0>; }});
908            0x5: sdc1({{ //Mem.df = Ft<63:0>; }});
909        }
910    }
911}
912
913
914