decoder.isa revision 2135
12SN/A// -*- mode:c++ -*-
21762SN/A
32SN/A////////////////////////////////////////////////////////////////////
42SN/A//
52SN/A// The actual MIPS32 ISA decoder
62SN/A// -----------------------------
72SN/A// The following instructions are specified in the MIPS32 ISA
82SN/A// Specification. Decoding closely follows the style specified
92SN/A// in the MIPS32 ISAthe specification document starting with Table
102SN/A// A-2 (document available @ www.mips.com)
112SN/A//
122SN/A//@todo: Distinguish "unknown/future" use insts from "reserved"
132SN/A// ones
142SN/Adecode OPCODE_HI default Unknown::unknown() {
152SN/A
162SN/A    // Derived From ... Table A-2 MIPS32 ISA Manual
172SN/A    0x0: decode OPCODE_LO {
182SN/A
192SN/A        0x0: decode FUNCTION_HI {
202SN/A            0x0: decode FUNCTION_LO {
212SN/A                0x1: decode MOVCI {
222SN/A                    format BasicOp {
232SN/A                        0: movf({{ if( xc->miscRegs.fpcr == 0) Rd = Rs}});
242SN/A                        1: movt({{ if( xc->miscRegs.fpcr == 1) Rd = Rs}});
252SN/A                    }
262SN/A                }
272665Ssaidi@eecs.umich.edu
282665Ssaidi@eecs.umich.edu                format BasicOp {
292SN/A
302SN/A                    //Table A-3 Note: "1. Specific encodings of the rt, rd, and sa fields
312439SN/A                    //are used to distinguish among the SLL, NOP, SSNOP and EHB functions."
322984Sgblack@eecs.umich.edu
33146SN/A                    0x0: sll({{ Rd = Rt.uw << SA; }});
34146SN/A
35146SN/A                    0x2: decode SRL {
36146SN/A                        0: srl({{ Rd = Rt.uw >> SA; }});
37146SN/A
38146SN/A                        //Hardcoded assuming 32-bit ISA, probably need parameter here
391717SN/A                        1: rotr({{ Rd = (Rt.uw << (32 - SA)) | (Rt.uw >> SA);}});
40146SN/A                    }
411717SN/A
42146SN/A                    0x3: sra({{ Rd = Rt.sw >> SA; }});
431977SN/A
442623SN/A                    0x4: sllv({{ Rd = Rt.uw << Rs<4:0>; }});
452683Sktlim@umich.edu
461717SN/A                    0x6: decode SRLV {
47146SN/A                        0: srlv({{ Rd = Rt.uw >> Rs<4:0>; }});
482683Sktlim@umich.edu
493348Sbinkertn@umich.edu                        //Hardcoded assuming 32-bit ISA, probably need parameter here
502683Sktlim@umich.edu                        1: rotrv({{ Rd = (Rt.uw << (32 - Rs<4:0>)) | (Rt.uw >> Rs<4:0>);}});
512036SN/A                    }
52146SN/A
5356SN/A                    0x7: srav({{ Rd = Rt.sw >> Rs<4:0>; }});
5456SN/A                }
5556SN/A            }
56695SN/A
572901Ssaidi@eecs.umich.edu            0x1: decode FUNCTION_LO {
582SN/A
591858SN/A                //Table A-3 Note: "Specific encodings of the hint field are used
603565Sgblack@eecs.umich.edu                //to distinguish JR from JR.HB and JALR from JALR.HB"
613565Sgblack@eecs.umich.edu                format Jump {
622171SN/A                    0x0: decode HINT {
632170SN/A                        0:jr({{ NNPC = Rs; }},IsReturn);
643562Sgblack@eecs.umich.edu
65146SN/A                        1:jr_hb({{ NNPC = Rs; clear_exe_inst_hazards(); }},IsReturn);
662462SN/A                    }
67146SN/A
682SN/A                    0x1: decode HINT {
692SN/A                        0: jalr({{ NNPC = Rs; }},IsCall,IsReturn);
702449SN/A
711355SN/A                        1: jalr_hb({{ NNPC = Rs; clear_exe_inst_hazards();}},IsCall,IsReturn);
722623SN/A                    }
734182Sgblack@eecs.umich.edu                }
74224SN/A
751858SN/A                format BasicOp {
762683Sktlim@umich.edu                    0x2: movz({{ if (Rt == 0) Rd = Rs; }});
772420SN/A                    0x3: movn({{ if (Rt != 0) Rd = Rs; }});
782683Sktlim@umich.edu                }
793402Sktlim@umich.edu
802420SN/A                format WarnUnimpl {
812SN/A                    0x4: syscall();//{{ xc->syscall()}},IsNonSpeculative
822683Sktlim@umich.edu                    0x5: break();
832672Sktlim@umich.edu                    0x7: sync();
842683Sktlim@umich.edu                }
852SN/A            }
862SN/A
87334SN/A            0x2: decode FUNCTION_LO {
88140SN/A                format BasicOp {
89334SN/A                    0x0: mfhi({{ Rd = xc->miscRegs.hi; }});
902SN/A                    0x1: mthi({{ xc->miscRegs.hi = Rs; }});
912SN/A                    0x2: mflo({{ Rd = xc->miscRegs.lo; }});
922SN/A                    0x3: mtlo({{ xc->miscRegs.lo = Rs; }});
932680Sktlim@umich.edu                }
942SN/A            }
952SN/A
962623SN/A            0x3: decode FUNCTION_LO {
972SN/A                format IntOp {
982SN/A                    0x0: mult({{
992SN/A                        int64_t temp1 = Rs.sw * Rt.sw;
100180SN/A                        xc->miscRegs.hi->temp1<63:32>;
1012623SN/A                        xc->miscRegs.lo->temp1<31:0>;
102393SN/A                    }});
103393SN/A
104393SN/A                    0x1: multu({{
105393SN/A                        int64_t temp1 = Rs.uw * Rt.uw;
106384SN/A                        xc->miscRegs.hi->temp1<63:32>;
107384SN/A                        xc->miscRegs.lo->temp1<31:0>
108393SN/A                            Rd.sw = Rs.uw * Rt.uw;
1092623SN/A                    }});
110393SN/A
111393SN/A                    0x2: div({{
112393SN/A                        xc->miscRegs.hi = Rs.sw % Rt.sw;
113393SN/A                        xc->miscRegs.lo = Rs.sw / Rt.sw;
114384SN/A                    }});
115189SN/A
116189SN/A                    0x3: divu({{
1172623SN/A                        xc->miscRegs.hi = Rs.uw % Rt.uw;
1182SN/A                        xc->miscRegs.lo = Rs.uw / Rt.uw;
119729SN/A                    }});
120334SN/A                }
1212SN/A            }
1222SN/A
1232SN/A            0x4: decode FUNCTION_LO {
1242SN/A                format IntOp {
1252SN/A                    0x0: add({{  Rd.sw = Rs.sw + Rt.sw;}});
1262SN/A                    0x1: addu({{ Rd.uw = Rs.uw + Rt.uw;}});
1272SN/A                    0x2: sub({{ Rd.sw = Rs.sw - Rt.sw;}});
1282SN/A                    0x3: subu({{ Rd.uw = Rs.uw - Rt.uw;}});
1292SN/A                    0x4: and({{ Rd.sw = Rs.uw & Rt.uw;}});
1302SN/A                    0x5: or({{ Rd.sw = Rs.uw | Rt.uw;}});
1312SN/A                    0x6: xor({{ Rd.sw = Rs.uw ^ Rt.uw;}});
1322SN/A                    0x7: nor({{ Rd.sw = ~(Rs.uw | Rt.uw);}});
1331001SN/A                }
1341001SN/A            }
1351001SN/A
1361001SN/A            0x5: decode FUNCTION_LO {
1371001SN/A                format IntOp{
1382SN/A                    0x2: slt({{  Rd.sw = ( Rs.sw < Rt.sw ) ? 1 : 0}});
1392SN/A                    0x3: sltu({{ Rd.uw = ( Rs.uw < Rt.uw ) ? 1 : 0}});
1402SN/A                }
1412SN/A            }
1422SN/A
1432SN/A            0x6: decode FUNCTION_LO {
1442SN/A                format BasicOp {
1452SN/A                    0x0: tge({{ cond = (Rs.sw >= Rt.sw); }});
1462SN/A                    0x1: tgeu({{ cond = (Rs.uw >= Rt.uw); }});
1472SN/A                    0x2: tlt({{ cond = (Rs.sw < Rt.sw); }});
1482SN/A                    0x3: tltu({{ cond = (Rs.uw >= Rt.uw); }});
1492SN/A                    0x4: teq({{ cond = (Rs.sw == Rt.sw); }});
1502SN/A                    0x6: tne({{ cond = (Rs.sw != Rt.sw); }});
1512SN/A                }
1522SN/A            }
1532SN/A        }
1542SN/A
1552390SN/A        0x1: decode REGIMM_HI {
1562390SN/A            0x0: decode REGIMM_LO {
1572390SN/A                format Branch {
1582390SN/A                    0x0: bltz({{ cond = (Rs.sw < 0); }});
1592390SN/A                    0x1: bgez({{ cond = (Rs.sw >= 0); }});
1602390SN/A                }
1612390SN/A
1622390SN/A                format BranchLikely {
1632390SN/A                    //MIPS obsolete instructions
1642390SN/A                    0x2: bltzl({{ cond = (Rs.sw < 0); }});
1652390SN/A                    0x3: bgezl({{ cond = (Rs.sw >= 0); }});
1662390SN/A                }
167385SN/A            }
1682SN/A
1692SN/A            0x1: decode REGIMM_LO {
1702SN/A                format BasicOp {
1712623SN/A                    0x0: tgei( {{ cond = (Rs.sw >= INTIMM); }});
172334SN/A                    0x1: tgeiu({{ cond = (Rs.uw >= INTIMM); }});
1732361SN/A                    0x2: tlti( {{ cond = (Rs.sw < INTIMM); }});
1742623SN/A                    0x3: tltiu({{ cond = (Rs.uw < INTIMM); }});
175334SN/A                    0x4: teqi( {{ cond = (Rs.sw == INTIMM);}});
176334SN/A                    0x6: tnei( {{ cond = (Rs.sw != INTIMM);}});
177334SN/A                }
1782623SN/A            }
1792SN/A
180921SN/A            0x2: decode REGIMM_LO {
1812915Sktlim@umich.edu                format Branch {
1822915Sktlim@umich.edu                    0x0: bltzal({{ cond = (Rs.sw < 0); }}, IsCall,IsReturn);
1832683Sktlim@umich.edu                    0x1: bgezal({{ cond = (Rs.sw >= 0); }}, IsCall,IsReturn);
1842SN/A                }
1852SN/A
1862SN/A                format BranchLikely {
1872623SN/A                    //Will be removed in future MIPS releases
1882SN/A                    0x2: bltzall({{ cond = (Rs.sw < 0); }}, IsCall, IsReturn);
189921SN/A                    0x3: bgezall({{ cond = (Rs.sw >= 0); }}, IsCall, IsReturn);
1902915Sktlim@umich.edu                }
1912915Sktlim@umich.edu            }
1922SN/A
1932SN/A            0x3: decode REGIMM_LO {
1942SN/A                format WarnUnimpl {
1952SN/A                    0x7: synci();
1962SN/A                }
1972SN/A            }
1982SN/A        }
199595SN/A
2002623SN/A        format Jump {
201595SN/A            0x2: j({{ NNPC = (NPC & 0xF0000000) & (0x00000000 & JMPTARG << 2);}});
2022390SN/A
2031080SN/A            0x3: jal({{ NNPC = (NPC & 0xF0000000) & (0x00000000 & JMPTARG << 2);}},IsCall,IsReturn);
2041080SN/A        }
2051080SN/A
2061080SN/A        format Branch {
2071080SN/A            0x4: beq({{ cond = (Rs.sw == 0); }});
2081080SN/A            0x5: bne({{ cond = (Rs.sw !=  0); }});
2091080SN/A            0x6: blez({{ cond = (Rs.sw <= 0); }});
2101121SN/A            0x7: bgtz({{ cond = (Rs.sw > 0); }});
2112107SN/A        }
2121089SN/A    }
2131089SN/A
2141080SN/A    0x1: decode OPCODE_LO {
2151080SN/A        format IntOp {
2161080SN/A            0x0: addi({{ Rt.sw = Rs.sw + INTIMM; }});
2171080SN/A            0x1: addiu({{ Rt.uw = Rs.uw + INTIMM;}});
218595SN/A            0x2: slti({{ Rt.sw = ( Rs.sw < INTIMM ) ? 1 : 0 }});
2192623SN/A            0x3: sltiu({{ Rt.uw = ( Rs.uw < INTIMM ) ? 1 : 0 }});
2202683Sktlim@umich.edu            0x4: andi({{ Rt.sw = Rs.sw & INTIMM;}});
221595SN/A            0x5: ori({{ Rt.sw = Rs.sw | INTIMM;}});
2222090SN/A            0x6: xori({{ Rt.sw = Rs.sw ^ INTIMM;}});
2232683Sktlim@umich.edu            0x7: lui({{ Rt = INTIMM << 16}});
2242683Sktlim@umich.edu        }
225595SN/A    }
2262205SN/A
2272205SN/A    0x2: decode OPCODE_LO {
2282683Sktlim@umich.edu
2292683Sktlim@umich.edu        //Table A-11 MIPS32 COP0 Encoding of rs Field
230595SN/A        0x0: decode RS_MSB {
231595SN/A            0x0: decode RS {
2322390SN/A                format BasicOp {
2332423SN/A                    0x0: mfc0({{
2342390SN/A                        //The contents of the coprocessor 0 register specified by the
235595SN/A                        //combination of rd and sel are loaded into general register
236595SN/A                        //rt. Note that not all coprocessor 0 registers support the
237595SN/A                        //sel field. In those instances, the sel field must be zero.
2382623SN/A
239595SN/A                        if (SEL > 0)
2402390SN/A                            panic("Can't Handle Cop0 with register select yet\n");
2411080SN/A
242595SN/A                        uint64_t reg_num = Rd.uw;
2431080SN/A
2441080SN/A                        Rt = xc->miscRegs.cop0[reg_num];
245595SN/A                    }});
2462683Sktlim@umich.edu
2471080SN/A                    0x4: mtc0({{
2481080SN/A                        //The contents of the coprocessor 0 register specified by the
2491080SN/A                        //combination of rd and sel are loaded into general register
2501121SN/A                        //rt. Note that not all coprocessor 0 registers support the
2512107SN/A                        //sel field. In those instances, the sel field must be zero.
2521089SN/A
2531080SN/A                        if (SEL > 0)
2541089SN/A                            panic("Can't Handle Cop0 with register select yet\n");
2551080SN/A
2561080SN/A                        uint64_t reg_num = Rd.uw;
2571080SN/A
258595SN/A                        xc->miscRegs.cop0[reg_num] = Rt;
2592683Sktlim@umich.edu                    }});
2601080SN/A
2612090SN/A                    0x8: mftr({{
2621080SN/A                        //The contents of the coprocessor 0 register specified by the
263595SN/A                        //combination of rd and sel are loaded into general register
2642683Sktlim@umich.edu                        //rt. Note that not all coprocessor 0 registers support the
2652683Sktlim@umich.edu                        //sel field. In those instances, the sel field must be zero.
266595SN/A
2672683Sktlim@umich.edu                        //MT Code Needed Here
2681098SN/A                    }});
2691098SN/A
2701098SN/A                    0xC: mttr({{
2712683Sktlim@umich.edu                        //The contents of the coprocessor 0 register specified by the
2721098SN/A                        //combination of rd and sel are loaded into general register
2731098SN/A                        //rt. Note that not all coprocessor 0 registers support the
2741098SN/A                        //sel field. In those instances, the sel field must be zero.
2752012SN/A
2761098SN/A                        //MT Code Needed Here
2771098SN/A                    }});
278595SN/A
2792205SN/A
2802205SN/A                    0xA: rdpgpr({{
2812205SN/A                        //Accessing Previous Shadow Set Register Number
282595SN/A                        uint64_t prev = xc->miscRegs.cop0[SRSCtl][PSS];
2832390SN/A                        uint64_t reg_num = Rt.uw;
2842420SN/A
2852423SN/A                        Rd = xc->shadowIntRegFile[prev][reg_num];
2862390SN/A                    }});
287595SN/A
288595SN/A                    0xB: decode RD {
2891858SN/A
2902SN/A                        0x0: decode SC {
2912623SN/A                            0x0: dvpe({{
2922SN/A                                Rt.sw = xc->miscRegs.cop0.MVPControl;
2932680Sktlim@umich.edu                                xc->miscRegs.cop0.MVPControl[EVP] = 0;
2942SN/A                            }});
2952SN/A
2962SN/A                            0x1: evpe({{
2971858SN/A                                Rt.sw = xc->miscRegs.cop0.MVPControl;
2982SN/A                                xc->miscRegs.cop0.MVPControl[EVP] = 1;
2992623SN/A                            }});
3002SN/A                        }
3012SN/A
3022SN/A                        0x1: decode SC {
3032683Sktlim@umich.edu                            0x0: dmt({{
3044216Ssaidi@eecs.umich.edu                                Rt.sw = xc->miscRegs.cop0.VPEControl;
3052683Sktlim@umich.edu                                xc->miscRegs.cop0.VPEControl[THREAD_ENABLE] = 0;
3062SN/A                            }});
3072SN/A
3082SN/A                            0x1: emt({{
3092SN/A                                Rt.sw = xc->miscRegs.cop0.VPEControl;
3102SN/A                                xc->miscRegs.cop0.VPEControl[THREAD_ENABLE] = 1;
3112623SN/A                            }});
3122SN/A                        }
3131858SN/A
3143923Shsul@eecs.umich.edu                        0xC: decode SC {
3153520Sgblack@eecs.umich.edu                            0x0: di({{
3162SN/A                                Rt.sw = xc->miscRegs.cop0.Status;
3173520Sgblack@eecs.umich.edu                                xc->miscRegs.cop0.Status[INTERRUPT_ENABLE] = 0;
3183633Sktlim@umich.edu                            }});
3193520Sgblack@eecs.umich.edu
3202SN/A                            0x1: ei({{
3212SN/A                                Rt.sw = xc->miscRegs.cop0.Status;
3222SN/A                                xc->miscRegs.cop0.Status[INTERRUPT_ENABLE] = 1;
3232623SN/A                            }});
3242SN/A                        }
3252623SN/A                    }
3262623SN/A
3272662Sstever@eecs.umich.edu                    0xE: wrpgpr({{
3282623SN/A                        //Accessing Previous Shadow Set Register Number
3292623SN/A                        uint64_t prev = xc->miscRegs.cop0[SRSCtl][PSS];
3303093Sksewell@umich.edu                        uint64_t reg_num = Rd.uw;
3313093Sksewell@umich.edu
3323093Sksewell@umich.edu                        xc->shadowIntRegFile[prev][reg_num] = Rt;
3333093Sksewell@umich.edu                    }});
3342741Sksewell@umich.edu                }
3352741Sksewell@umich.edu            }
3362741Sksewell@umich.edu
3372623SN/A            //Table A-12 MIPS32 COP0 Encoding of Function Field When rs=CO
3384375Sgblack@eecs.umich.edu            0x1: decode FUNCTION {
3394375Sgblack@eecs.umich.edu                format BasicOp {
3402623SN/A                    0x01: tlbr({{ }});
3412683Sktlim@umich.edu                    0x02: tlbwi({{ }});
3422623SN/A                    0x06: tlbwr({{ }});
3432623SN/A                    0x08: tlbp({{ }});
3442623SN/A                }
3452623SN/A
3462623SN/A                format WarnUnimpl {
3472623SN/A                    0x18: eret();
3482623SN/A                    0x1F: deret();
3492623SN/A                    0x20: wait();
3502SN/A                }
3512683Sktlim@umich.edu            }
3522427SN/A        }
3532683Sktlim@umich.edu
3542427SN/A        //Table A-13 MIPS32 COP1 Encoding of rs Field
3552SN/A        0x1: decode RS_MSB {
3562623SN/A
3572623SN/A            0x0: decode RS_HI {
3582623SN/A                0x0: decode RS_LO {
3592SN/A                    format FloatOp {
3602683Sktlim@umich.edu                        0x0: mfc1({{ Rt = Fs<31:0>; }});
3612SN/A                        0x2: cfc1({{ Rt = xc->miscRegs.fpcr[Fs];}});
3622623SN/A                        0x3: mfhc1({{ Rt = Fs<63:32>;}});
3632623SN/A                        0x4: mtc1({{ Fs<31:0> = Rt}});
3642SN/A                        0x6: ctc1({{ xc->miscRegs.fpcr[Fs] = Rt;}});
3652623SN/A                        0x7: mftc1({{ Fs<63:32> = Rt}});
3662623SN/A                    }
3673276Sgblack@eecs.umich.edu                }
3683276Sgblack@eecs.umich.edu
3694181Sgblack@eecs.umich.edu                0x1: decode ND {
3704181Sgblack@eecs.umich.edu                    0x0: decode TF {
3714181Sgblack@eecs.umich.edu                        format Branch {
3724182Sgblack@eecs.umich.edu                            0x0: bc1f({{ cond = (xc->miscRegs.fpcr == 0); }});
3734182Sgblack@eecs.umich.edu                            0x1: bc1t({{ cond = (xc->miscRegs.fpcr == 1); }});
3744182Sgblack@eecs.umich.edu                        }
3754182Sgblack@eecs.umich.edu                    }
3764182Sgblack@eecs.umich.edu
3774182Sgblack@eecs.umich.edu                    0x1: decode TF {
3784182Sgblack@eecs.umich.edu                        format BranchLikely {
3794181Sgblack@eecs.umich.edu                            0x0: bc1fl({{ cond = (xc->miscRegs.fpcr == 0); }});
3804182Sgblack@eecs.umich.edu                            0x1: bc1tl({{ cond = (xc->miscRegs.fpcr == 1); }});
3814182Sgblack@eecs.umich.edu                        }
3824181Sgblack@eecs.umich.edu                    }
3834181Sgblack@eecs.umich.edu                }
3844181Sgblack@eecs.umich.edu            }
3854181Sgblack@eecs.umich.edu
3863276Sgblack@eecs.umich.edu            0x1: decode RS_HI {
3873442Sgblack@eecs.umich.edu                0x2: decode RS_LO {
3883442Sgblack@eecs.umich.edu
3893280Sgblack@eecs.umich.edu                    //Table A-14 MIPS32 COP1 Encoding of Function Field When rs=S
3903280Sgblack@eecs.umich.edu                    //(( single-word ))
3913276Sgblack@eecs.umich.edu                    0x0: decode RS_HI {
3923276Sgblack@eecs.umich.edu                        0x0: decode RS_LO {
3933276Sgblack@eecs.umich.edu                            format FloatOp {
3943442Sgblack@eecs.umich.edu                                0x0: adds({{ Fd.sf = Fs.sf + Ft.sf;}});
3953442Sgblack@eecs.umich.edu                                0x1: subs({{ Fd.sf = Fs.sf - Ft.sf;}});
3963276Sgblack@eecs.umich.edu                                0x2: muls({{ Fd.sf = Fs.sf * Ft.sf;}});
3973276Sgblack@eecs.umich.edu                                0x3: divs({{ Fd.sf = Fs.sf / Ft.sf;}});
3984181Sgblack@eecs.umich.edu                                0x4: sqrts({{ Fd.sf = sqrt(Fs.sf);}});
3994181Sgblack@eecs.umich.edu                                0x5: abss({{ Fd.sf = abs(Fs.sf);}});
4004181Sgblack@eecs.umich.edu                                0x6: movs({{ Fd.sf = Fs.sf;}});
4014181Sgblack@eecs.umich.edu                                0x7: negs({{ Fd.sf = -1 * Fs.sf;}});
4024181Sgblack@eecs.umich.edu                            }
4032470SN/A                        }
4044181Sgblack@eecs.umich.edu
4054181Sgblack@eecs.umich.edu                        0x1: decode RS_LO {
4062623SN/A                            //only legal for 64 bit-FP
4072623SN/A                            format Float64Op {
4084181Sgblack@eecs.umich.edu                                0x0: round_l_s({{ Fd = convert_and_round(Fs.sf,RND_NEAREST,FP_LONG,FP_SINGLE);}});
4092623SN/A                                0x1: trunc_l_s({{ Fd = convert_and_round(Fs.sf,RND_ZERO,FP_LONG,FP_SINGLE);}});
4104181Sgblack@eecs.umich.edu                                0x2: ceil_l_s({{ Fd = convert_and_round(Fs.sf,RND_UP,FP_LONG,FP_SINGLE);}});
4112623SN/A                                0x3: floor_l_s({{ Fd = convert_and_round(Fs.sf,RND_DOWN,FP_LONG,FP_SINGLE);}});
4122623SN/A                            }
4132623SN/A
4142623SN/A                            format FloatOp {
4152623SN/A                                0x4: round_w_s({{ Fd = convert_and_round(Fs.sf,RND_NEAREST,FP_WORD,FP_SINGLE);}});
4162623SN/A                                0x5: trunc_w_s({{ Fd = convert_and_round(Fs.sf,RND_ZERO,FP_WORD,FP_SINGLE);}});
4172683Sktlim@umich.edu                                0x6: ceil_w_s({{  Fd = convert_and_round(Fs.sf,RND_UP,FP_WORD,FP_SINGLE);}});
4183577Sgblack@eecs.umich.edu                                0x7: floor_w_s({{ Fd = convert_and_round(Fs.sf,RND_DOWN,FP_WORD,FP_SINGLE);}});
4192683Sktlim@umich.edu                            }
4204254Sgblack@eecs.umich.edu                        }
4214254Sgblack@eecs.umich.edu
4222623SN/A                        0x2: decode RS_LO {
4232683Sktlim@umich.edu                            0x1: decode MOVCF {
4242623SN/A                                format FloatOp {
4252420SN/A                                    0x0: movfs({{ if ( FPConditionCode(CC) == 0 ) Fd = Fs; }});
4262SN/A                                    0x1: movts({{ if ( FPConditionCode(CC) == 1 ) Fd = Fs;}});
4272623SN/A                                }
4282623SN/A                            }
4292SN/A
4302SN/A                            format BasicOp {
4312623SN/A                                0x2: movzs({{ if (Rt == 0) Fd = Fs; }});
4322623SN/A                                0x3: movns({{ if (Rt != 0) Fd = Fs; }});
4332623SN/A                            }
4342623SN/A
4352SN/A                            format Float64Op {
4362683Sktlim@umich.edu                                0x5: recips({{ Fd = 1 / Fs; }});
4372644Sstever@eecs.umich.edu                                0x6: rsqrts({{ Fd = 1 / sqrt(Fs.ud);}});
4382644Sstever@eecs.umich.edu                            }
4394046Sbinkertn@umich.edu                        }
4404046Sbinkertn@umich.edu
4414046Sbinkertn@umich.edu                        0x4: decode RS_LO {
4422644Sstever@eecs.umich.edu
4432623SN/A                            format FloatOp {
4442SN/A                                0x1: cvt_d_s({{ int rnd_mode = xc->miscRegs.fcsr;
4452SN/A                                Fd = convert_and_round(Fs.sf,rnd_mode,FP_DOUBLE,FP_SINGLE);
4462623SN/A                                }});
4472623SN/A
4482623SN/A                                0x4: cvt_w_s({{ int rnd_mode = xc->miscRegs.fcsr;
4492090SN/A                                Fd = convert_and_round(Fs.sf,rnd_mode,FP_WORD,FP_SINGLE);
4503905Ssaidi@eecs.umich.edu                                }});
4512680Sktlim@umich.edu                            }
4523929Ssaidi@eecs.umich.edu
4533929Ssaidi@eecs.umich.edu                            //only legal for 64 bit
4544182Sgblack@eecs.umich.edu                            format Float64Op {
4553276Sgblack@eecs.umich.edu                                0x5: cvt_l_s({{ int rnd_mode = xc->miscRegs.fcsr;
4564182Sgblack@eecs.umich.edu                                Fd = convert_and_round(Fs.sf,rnd_mode,FP_LONG,FP_SINGLE);
4573276Sgblack@eecs.umich.edu                                }});
4583276Sgblack@eecs.umich.edu
4593276Sgblack@eecs.umich.edu                                0x6: cvt_ps_s({{ Fd.df = Fs.df<31:0> | Ft.df<31:0>; }});
4603276Sgblack@eecs.umich.edu                            }
4613280Sgblack@eecs.umich.edu                        }
4623276Sgblack@eecs.umich.edu                    }
4633280Sgblack@eecs.umich.edu
4643276Sgblack@eecs.umich.edu                    //Table A-15 MIPS32 COP1 Encoding of Function Field When rs=D
4653276Sgblack@eecs.umich.edu                    0x1: decode RS_HI {
4663276Sgblack@eecs.umich.edu                        0x0: decode RS_LO {
4673276Sgblack@eecs.umich.edu                            format FloatOp {
4683280Sgblack@eecs.umich.edu                                0x0: addd({{ Fd.df = Fs.df + Ft.df;}});
4693276Sgblack@eecs.umich.edu                                0x1: subd({{ Fd.df = Fs.df - Ft.df;}});
4703276Sgblack@eecs.umich.edu                                0x2: muld({{ Fd.df = Fs.df * Ft.df;}});
4713280Sgblack@eecs.umich.edu                                0x3: divd({{ Fd.df = Fs.df / Ft.df;}});
4723276Sgblack@eecs.umich.edu                                0x4: sqrtd({{ Fd.df = sqrt(Fs.df);}});
4733276Sgblack@eecs.umich.edu                                0x5: absd({{ Fd.df = abs(Fs.df);}});
4743276Sgblack@eecs.umich.edu                                0x6: movd({{ Fd.df = Fs.df;}});
4753276Sgblack@eecs.umich.edu                                0x7: negd({{ Fd.df = -1 * Fs.df;}});
4763276Sgblack@eecs.umich.edu                            }
4773276Sgblack@eecs.umich.edu                        }
4783276Sgblack@eecs.umich.edu
4792SN/A                        0x1: decode RS_LO {
4802SN/A                            //only legal for 64 bit
4811858SN/A                            format Float64Op {
4822SN/A                                0x0: round_l_d({{ Fd = convert_and_round(Fs.df,RND_NEAREST,FP_LONG,FP_DOUBLE); }});
4832SN/A                                0x1: trunc_l_d({{ Fd = convert_and_round(Fs.df,RND_ZERO,FP_LONG,FP_DOUBLE);}});
4842683Sktlim@umich.edu                                0x2: ceil_l_d({{ Fd = convert_and_round(Fs.df,RND_UP,FP_LONG,FP_DOUBLE);}});
4852680Sktlim@umich.edu                                0x3: floor_l_d({{ Fd = convert_and_round(Fs.df,RND_DOWN,FP_LONG,FP_DOUBLE);}});
4862683Sktlim@umich.edu                            }
4872SN/A
4882SN/A                            format FloatOp {
4892SN/A                                0x4: round_w_d({{ Fd = convert_and_round(Fs.df,RND_NEAREST,FP_LONG,FP_DOUBLE); }});
490                                0x5: trunc_w_d({{ Fd = convert_and_round(Fs.df,RND_ZERO,FP_LONG,FP_DOUBLE); }});
491                                0x6: ceil_w_d({{  Fd = convert_and_round(Fs.df,RND_UP,FP_LONG,FP_DOUBLE); }});
492                                0x7: floor_w_d({{ Fd = convert_and_round(Fs.df,RND_DOWN,FP_LONG,FP_DOUBLE); }});
493                            }
494                        }
495
496                        0x2: decode RS_LO {
497                            0x1: decode MOVCF {
498                                format FloatOp {
499                                    0x0: movfd({{ if (FPConditionCode(CC) == 0) Fd.df = Fs.df; }});
500                                    0x1: movtd({{ if (FPConditionCode(CC) == 1) Fd.df = Fs.df; }});
501                                }
502                            }
503
504                            format BasicOp {
505                                0x2: movzd({{ if (Rt == 0) Fd.df = Fs.df; }});
506                                0x3: movnd({{ if (Rt != 0) Fd.df = Fs.df; }});
507                            }
508
509                            format Float64Op {
510                                0x5: recipd({{ Fd.df = 1 / Fs.df}});
511                                0x6: rsqrtd({{ Fd.df = 1 / sqrt(Fs.df) }});
512                            }
513                        }
514
515                        0x4: decode RS_LO {
516                            format FloatOp {
517                                0x0: cvt_s_d({{
518                                    int rnd_mode = xc->miscRegs.fcsr;
519                                    Fd = convert_and_round(Fs.df,rnd_mode,FP_SINGLE,FP_DOUBLE);
520                                }});
521
522                                0x4: cvt_w_d({{
523                                    int rnd_mode = xc->miscRegs.fcsr;
524                                    Fd = convert_and_round(Fs.df,rnd_mode,FP_WORD,FP_DOUBLE);
525                                }});
526                            }
527
528                            //only legal for 64 bit
529                            format Float64Op {
530                                0x5: cvt_l_d({{
531                                    int rnd_mode = xc->miscRegs.fcsr;
532                                    Fd = convert_and_round(Fs.df,rnd_mode,FP_LONG,FP_DOUBLE);
533                                }});
534                            }
535                        }
536                    }
537
538                    //Table A-16 MIPS32 COP1 Encoding of Function Field When rs=W
539                    0x4: decode FUNCTION {
540                        format FloatOp {
541                            0x20: cvt_s({{
542                                int rnd_mode = xc->miscRegs.fcsr;
543                                Fd = convert_and_round(Fs.df,rnd_mode,FP_SINGLE,FP_WORD);
544                            }});
545
546                            0x21: cvt_d({{
547                                int rnd_mode = xc->miscRegs.fcsr;
548                                Fd = convert_and_round(Fs.df,rnd_mode,FP_DOUBLE,FP_WORD);
549                            }});
550                        }
551                    }
552
553                    //Table A-16 MIPS32 COP1 Encoding of Function Field When rs=L1
554                    //Note: "1. Format type L is legal only if 64-bit floating point operations
555                    //are enabled."
556                    0x5: decode FUNCTION_HI {
557                        format FloatOp {
558                            0x10: cvt_s_l({{
559                                int rnd_mode = xc->miscRegs.fcsr;
560                                Fd = convert_and_round(Fs.df,rnd_mode,FP_SINGLE,FP_LONG);
561                            }});
562
563                            0x11: cvt_d_l({{
564                                int rnd_mode = xc->miscRegs.fcsr;
565                                Fd = convert_and_round(Fs.df,rnd_mode,FP_DOUBLE,FP_LONG);
566                            }});
567                        }
568                    }
569
570                    //Table A-17 MIPS64 COP1 Encoding of Function Field When rs=PS1
571                    //Note: "1. Format type PS is legal only if 64-bit floating point operations
572                    //are enabled. "
573                    0x6: decode RS_HI {
574                        0x0: decode RS_LO {
575                            format Float64Op {
576                                0x0: addps({{ //Must Check for Exception Here... Supposed to Operate on Upper and
577                                    //Lower Halves Independently but we take simulator shortcut
578                                    Fd.df = Fs.df + Ft.df;
579                                }});
580
581                                0x1: subps({{ //Must Check for Exception Here... Supposed to Operate on Upper and
582                                    //Lower Halves Independently but we take simulator shortcut
583                                    Fd.df = Fs.df - Ft.df;
584                                }});
585
586                                0x2: mulps({{ //Must Check for Exception Here... Supposed to Operate on Upper and
587                                    //Lower Halves Independently but we take simulator shortcut
588                                    Fd.df = Fs.df * Ft.df;
589                                }});
590
591                                0x5: absps({{ //Must Check for Exception Here... Supposed to Operate on Upper and
592                                    //Lower Halves Independently but we take simulator shortcut
593                                    Fd.df = abs(Fs.df);
594                                }});
595
596                                0x6: movps({{ //Must Check for Exception Here... Supposed to Operate on Upper and
597                                    //Lower Halves Independently but we take simulator shortcut
598                                    Fd.df = Fs<31:0> |  Ft<31:0>;
599                                }});
600
601                                0x7: negps({{ //Must Check for Exception Here... Supposed to Operate on Upper and
602                                    //Lower Halves Independently but we take simulator shortcut
603                                    Fd.df = -1 * Fs.df;
604                                }});
605                            }
606                        }
607
608                        0x2: decode RS_LO {
609                            0x1: decode MOVCF {
610                                format Float64Op {
611                                    0x0: movfps({{ if ( FPConditionCode(CC) == 0) Fd = Fs;}});
612                                    0x1: movtps({{ if ( FPConditionCode(CC) == 0) Fd = Fs;}});
613                                }
614                            }
615
616                            format BasicOp {
617                                0x2: movzps({{ if ( FPConditionCode(CC) == 0) Fd = Fs; }});
618                                0x3: movnps({{ if ( FPConditionCode(CC) == 0) Fd = Fs; }});
619                            }
620
621                        }
622
623                        0x4: decode RS_LO {
624                            0x0: Float64Op::cvt_s_pu({{
625                                int rnd_mode = xc->miscRegs.fcsr;
626                                Fd = convert_and_round(Fs.df,rnd_mode,FP_DOUBLE,FP_PS_HI);
627                            }});
628                        }
629
630                        0x5: decode RS_LO {
631                            format Float64Op {
632                                0x0: cvt_s_pl({{
633                                    int rnd_mode = xc->miscRegs.fcsr;
634                                    Fd = convert_and_round(Fs.df,rnd_mode,FP_SINGLE,FP_PS_LO);
635                                }});
636                                0x4: pll({{ Fd.df = Fs<31:0> | Ft<31:0>}});
637                                0x5: plu({{ Fd.df = Fs<31:0> | Ft<63:32>}});
638                                0x6: pul({{ Fd.df = Fs<63:32> | Ft<31:0>}});
639                                0x7: puu({{ Fd.df = Fs<63:32 | Ft<63:32>}});
640                            }
641                        }
642                    }
643                }
644            }
645        }
646
647        //Table A-19 MIPS32 COP2 Encoding of rs Field
648        0x2: decode RS_MSB {
649            0x0: decode RS_HI {
650                0x0: decode RS_LO {
651                    format WarnUnimpl {
652                        0x0: mfc2();
653                        0x2: cfc2();
654                        0x3: mfhc2();
655                        0x4: mtc2();
656                        0x6: ctc2();
657                        0x7: mftc2();
658                    }
659                }
660
661                0x1: decode ND {
662                    0x0: decode TF {
663                        format WarnUnimpl {
664                            0x0: bc2f();
665                            0x1: bc2t();
666                        }
667                    }
668
669                    0x1: decode TF {
670                        format WarnUnimpl {
671                            0x0: bc2fl();
672                            0x1: bc2tl();
673                        }
674                    }
675                }
676            }
677        }
678
679        //Table A-20 MIPS64 COP1X Encoding of Function Field 1
680        //Note: "COP1X instructions are legal only if 64-bit floating point
681        //operations are enabled."
682        0x3: decode FUNCTION_HI {
683            0x0: decode FUNCTION_LO {
684                format LoadMemory2 {
685                    0x0: lwxc1({{ EA = Rs + Rt; }},{{ Ft<31:0> = Mem.sf; }});
686                    0x1: ldxc1({{ EA = Rs + Rt; }},{{ Ft<63:0> = Mem.df; }});
687                    0x5: luxc1({{ //Need to make EA<2:0> = 0
688                        EA = Rs + Rt;
689                    }},
690                {{ Ft<31:0> = Mem.df; }});
691                }
692            }
693
694            0x1: decode FUNCTION_LO {
695                format StoreMemory2 {
696                    0x0: swxc1({{ EA = Rs + Rt; }},{{ Mem.sf = Ft<31:0>; }});
697                    0x1: sdxc1({{ EA = Rs + Rt; }},{{ Mem.df = Ft<63:0>}});
698                    0x5: suxc1({{ //Need to make EA<2:0> = 0
699                        EA = Rs + Rt;
700                    }},
701                {{ Mem.df = Ft<63:0>;}});
702                }
703
704                0x7: WarnUnimpl::prefx();
705            }
706
707            format FloatOp {
708                0x3: WarnUnimpl::alnv_ps();
709
710                format BasicOp {
711                    0x4: decode FUNCTION_LO {
712                        0x0: madd_s({{ Fd.sf = (Fs.sf * Fs.sf) + Fr.sf; }});
713                        0x1: madd_d({{ Fd.df = (Fs.df * Fs.df) + Fr.df; }});
714                        0x6: madd_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 = (Fs.df * Fs.df) + Fr.df;
718                        }});
719                    }
720
721                    0x5: decode FUNCTION_LO {
722                        0x0: msub_s({{ Fd.sf = (Fs.sf * Fs.sf) - Fr.sf; }});
723                        0x1: msub_d({{ Fd.df = (Fs.df * Fs.df) - Fr.df; }});
724                        0x6: msub_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 = (Fs.df * Fs.df) - Fr.df;
728                        }});
729                    }
730
731                    0x6: decode FUNCTION_LO {
732                        0x0: nmadd_s({{ Fd.sf = (-1 * Fs.sf * Fs.sf) - Fr.sf; }});
733                        0x1: nmadd_d({{ Fd.df = (-1 * Fs.df * Fs.df) + Fr.df; }});
734                        0x6: nmadd_ps({{
735                            //Must Check for Exception Here... Supposed to Operate on Upper and
736                            //Lower Halves Independently but we take simulator shortcut
737                            Fd.df = (-1 * Fs.df * Fs.df) + Fr.df;
738                        }});
739                    }
740
741                    0x7: decode FUNCTION_LO {
742                        0x0: nmsub_s({{ Fd.sf = (-1 * Fs.sf * Fs.sf) - Fr.sf; }});
743                        0x1: nmsub_d({{ Fd.df = (-1 * Fs.df * Fs.df) - Fr.df; }});
744                        0x6: nmsub_ps({{
745                            //Must Check for Exception Here... Supposed to Operate on Upper and
746                            //Lower Halves Independently but we take simulator shortcut
747                            Fd.df = (-1 * Fs.df * Fs.df) + Fr.df;
748                        }});
749                    }
750                }
751            }
752        }
753
754        //MIPS obsolete instructions
755        format BranchLikely {
756            0x4: beql({{ cond = (Rs.sw == 0); }});
757            0x5: bnel({{ cond = (Rs.sw != 0); }});
758            0x6: blezl({{ cond = (Rs.sw <= 0); }});
759            0x7: bgtzl({{ cond = (Rs.sw > 0); }});
760        }
761    }
762
763    0x3: decode OPCODE_LO default FailUnimpl::reserved() {
764
765        //Table A-5 MIPS32 SPECIAL2 Encoding of Function Field
766        0x4: decode FUNCTION_HI {
767
768            0x0: decode FUNCTION_LO {
769                format IntOp {
770                    0x0: madd({{
771                        int64_t temp1 = Hi.sw << 32 | Lo.sw >> 32;
772                        temp1 = temp1 + (Rs.sw * Rt.sw);
773                        xc->miscRegs.hi->temp1<63:32>;
774                        xc->miscRegs.lo->temp1<31:0>
775                            }});
776
777                    0x1: maddu({{
778                        int64_t temp1 = Hi.uw << 32 | Lo.uw >> 32;
779                        temp1 = temp1 + (Rs.uw * Rt.uw);
780                        xc->miscRegs.hi->temp1<63:32>;
781                        xc->miscRegs.lo->temp1<31:0>
782                            }});
783
784                    0x2: mul({{ 	Rd.sw = Rs.sw * Rt.sw; 	}});
785
786                    0x4: msub({{
787                        int64_t temp1 = Hi.sw << 32 | Lo.sw >> 32;
788                        temp1 = temp1 - (Rs.sw * Rt.sw);
789                        xc->miscRegs.hi->temp1<63:32>;
790                        xc->miscRegs.lo->temp1<31:0>
791                            }});
792
793                    0x5: msubu({{
794                        int64_t temp1 = Hi.uw << 32 | Lo.uw >> 32;
795                        temp1 = temp1 - (Rs.uw * Rt.uw);
796                        xc->miscRegs.hi->temp1<63:32>;
797                        xc->miscRegs.lo->temp1<31:0>
798                            }});
799                }
800            }
801
802            0x4: decode FUNCTION_LO {
803                format BasicOp {
804                    0x0: clz({{
805                        int cnt = 0;
806                        int idx = 0;
807                        while ( Rs.uw<idx>!= 1) {
808                            cnt++;
809                            idx--;
810                        }
811
812                        Rd.uw = cnt;
813                    }});
814
815                    0x1: clo({{
816                        int cnt = 0;
817                        int idx = 0;
818                        while ( Rs.uw<idx>!= 0) {
819                            cnt++;
820                            idx--;
821                        }
822
823                        Rd.uw = cnt;
824                    }});
825                }
826            }
827
828            0x7: decode FUNCTION_LO {
829                0x7: WarnUnimpl::sdbbp();
830            }
831        }
832
833        //Table A-6 MIPS32 SPECIAL3 Encoding of Function Field for Release 2 of the Architecture
834        0x7: decode FUNCTION_HI {
835
836            0x0: decode FUNCTION_LO {
837                format WarnUnimpl {
838                    0x1: ext();
839                    0x4: ins();
840                }
841            }
842
843            0x1: decode FUNCTION_LO {
844                format WarnUnimpl {
845                    0x0: fork();
846                    0x1: yield();
847                }
848            }
849
850
851            //Table A-10 MIPS32 BSHFL Encoding of sa Field
852            0x4: decode SA {
853
854                0x02: WarnUnimpl::wsbh();
855
856                format BasicOp {
857                    0x10: seb({{ Rd.sw = /* sext32(Rt<7>,24)  | */ Rt<7:0>}});
858                    0x18: seh({{ Rd.sw = /* sext32(Rt<15>,16) | */ Rt<15:0>}});
859                }
860            }
861
862            0x6: decode FUNCTION_LO {
863                0x7: BasicOp::rdhwr({{ Rt = xc->hwRegs[RD];}});
864            }
865        }
866    }
867
868    0x4: decode OPCODE_LO default FailUnimpl::reserved() {
869        format LoadMemory {
870            0x0: lb({{ Rb.sw = Mem.sb; }});
871            0x1: lh({{ Rb.sw = Mem.sh; }});
872            0x2: lwl({{ Rb.sw = Mem.sw; }});//, WordAlign);
873            0x3: lw({{ Rb.uq = Mem.sb; }});
874            0x4: lbu({{ Rb.uw = Mem.ub; }});
875            0x5: lhu({{ Rb.uw = Mem.uh; }});
876            0x6: lwr({{ Rb.uw = Mem.uw; }});//, WordAlign);
877        }
878
879        0x7: FailUnimpl::reserved();
880    }
881
882    0x5: decode OPCODE_LO default FailUnimpl::reserved() {
883        format StoreMemory {
884            0x0: sb({{ Mem.ub = Rt<7:0>; }});
885            0x1: sh({{ Mem.uh = Rt<15:0>; }});
886            0x2: swl({{ Mem.ub = Rt<31:0>; }});//,WordAlign);
887            0x3: sw({{ Mem.ub = Rt<31:0>; }});
888            0x6: swr({{ Mem.ub = Rt<31:0>; }});//,WordAlign);
889        }
890
891        format WarnUnimpl {
892            0x7: cache();
893        }
894
895    }
896
897    0x6: decode OPCODE_LO default FailUnimpl::reserved() {
898        0x0: WarnUnimpl::ll();
899
900        format LoadMemory {
901            0x1: lwc1({{ Ft<31:0> = Mem.sf; }});
902            0x5: ldc1({{ Ft<63:0> = Mem.df; }});
903        }
904    }
905
906    0x7: decode OPCODE_LO default FailUnimpl::reserved() {
907        0x0: WarnUnimpl::sc();
908
909        format StoreMemory {
910            0x1: swc1({{ Mem.sf = Ft<31:0>; }});
911            0x5: sdc1({{ Mem.df = Ft<63:0>; }});
912        }
913
914    }
915}
916
917
918