decoder.isa revision 2572
11689SN/A// -*- mode:c++ -*-
22326SN/A
31689SN/A////////////////////////////////////////////////////////////////////
41689SN/A//
51689SN/A// The actual MIPS32 ISA decoder
61689SN/A// -----------------------------
71689SN/A// The following instructions are specified in the MIPS32 ISA
81689SN/A// Specification. Decoding closely follows the style specified
91689SN/A// in the MIPS32 ISAthe specification document starting with Table
101689SN/A// A-2 (document available @ www.mips.com)
111689SN/A//
121689SN/A//@todo: Distinguish "unknown/future" use insts from "reserved"
131689SN/A// ones
141689SN/Adecode OPCODE_HI default Unknown::unknown() {
151689SN/A
161689SN/A    // Derived From ... Table A-2 MIPS32 ISA Manual
171689SN/A    0x0: decode OPCODE_LO {
181689SN/A
191689SN/A        0x0: decode FUNCTION_HI {
201689SN/A            0x0: decode FUNCTION_LO {
211689SN/A                0x1: decode MOVCI {
221689SN/A                    format BasicOp {
231689SN/A                        0: movf({{ if (xc->readMiscReg(FPCR) != CC) Rd = Rs}});
241689SN/A                        1: movt({{ if (xc->readMiscReg(FPCR) == CC) Rd = Rs}});
251689SN/A                    }
261689SN/A                }
272665Ssaidi@eecs.umich.edu
282665Ssaidi@eecs.umich.edu                format BasicOp {
291689SN/A
301689SN/A                    //Table A-3 Note: "1. Specific encodings of the rt, rd, and sa fields
311060SN/A                    //are used to distinguish among the SLL, NOP, SSNOP and EHB functions.
321060SN/A                    0x0: decode RS  {
331689SN/A                        0x0: decode RT {     //fix Nop traditional vs. Nop converted disassembly later
341060SN/A                             0x0: decode RD  default Nop::nop(){
351060SN/A                                  0x0: decode SA {
361060SN/A                                      0x1: ssnop({{ ; }}); //really sll r0,r0,1
371060SN/A                                      0x3: ehb({{ ; }});   //really sll r0,r0,3
382292SN/A                                  }
391717SN/A                             }
401060SN/A
411681SN/A                             default: sll({{ Rd = Rt.uw << SA; }});
424329Sktlim@umich.edu                        }
432873Sktlim@umich.edu
444329Sktlim@umich.edu                    }
454329Sktlim@umich.edu
464329Sktlim@umich.edu                    0x2: decode RS_SRL {
472292SN/A                        0x0:decode SRL {
482292SN/A                            0: srl({{ Rd = Rt.uw >> SA; }});
492292SN/A
502292SN/A                            //Hardcoded assuming 32-bit ISA, probably need parameter here
512820Sktlim@umich.edu                            1: rotr({{ Rd = (Rt.uw << (32 - SA)) | (Rt.uw >> SA);}});
522292SN/A                        }
532820Sktlim@umich.edu                    }
542820Sktlim@umich.edu
552307SN/A                    0x3: decode RS {
562307SN/A                        0x0: sra({{
571060SN/A                            uint32_t temp = Rt >> SA;
582292SN/A
592292SN/A                            if ( (Rt & 0x80000000) > 0 ) {
602292SN/A                                uint32_t mask = 0x80000000;
611060SN/A                                for(int i=0; i < SA; i++) {
621060SN/A                                    temp |= mask;
631060SN/A                                    mask = mask >> 1;
641060SN/A                                }
651060SN/A                            }
661060SN/A
671681SN/A                            Rd = temp;
682292SN/A                        }});
692292SN/A                    }
702292SN/A
712292SN/A                    0x4: sllv({{ Rd = Rt.uw << Rs<4:0>; }});
722935Sksewell@umich.edu
732292SN/A                    0x6: decode SRLV {
742292SN/A                        0: srlv({{ Rd = Rt.uw >> Rs<4:0>; }});
752820Sktlim@umich.edu
762820Sktlim@umich.edu                        //Hardcoded assuming 32-bit ISA, probably need parameter here
772292SN/A                        1: rotrv({{ Rd = (Rt.uw << (32 - Rs<4:0>)) | (Rt.uw >> Rs<4:0>);}});
782292SN/A                    }
792820Sktlim@umich.edu
802820Sktlim@umich.edu                    0x7: srav({{
812292SN/A                        int shift_amt = Rs<4:0>;
822292SN/A
832292SN/A                        uint32_t temp = Rt >> shift_amt;
842292SN/A
852292SN/A                        if ( (Rt & 0x80000000) > 0 ) {
862292SN/A                                uint32_t mask = 0x80000000;
872292SN/A                                for(int i=0; i < shift_amt; i++) {
882292SN/A                                    temp |= mask;
891060SN/A                                    mask = mask >> 1;
901060SN/A                                }
911681SN/A                            }
921062SN/A
932292SN/A                        Rd = temp;
941062SN/A                    }});
952301SN/A                }
962301SN/A            }
971062SN/A
982727Sktlim@umich.edu            0x1: decode FUNCTION_LO {
991062SN/A
1001062SN/A                //Table A-3 Note: "Specific encodings of the hint field are used
1011062SN/A                //to distinguish JR from JR.HB and JALR from JALR.HB"
1021062SN/A                format Jump {
1031062SN/A                    0x0: decode HINT {
1041062SN/A                        0:jr({{ NNPC = Rs & ~1; }},IsReturn);
1051062SN/A
1061062SN/A                        1:jr_hb({{ NNPC = Rs & ~1; clear_exe_inst_hazards(); }},IsReturn);
1071062SN/A                    }
1081062SN/A
1091062SN/A                    0x1: decode HINT {
1101062SN/A                        0: jalr({{ Rd = NNPC; NNPC = Rs; }},IsCall,IsReturn);
1111062SN/A
1121062SN/A                        1: jalr_hb({{ Rd = NNPC; NNPC = Rs; clear_exe_inst_hazards();}},IsCall,IsReturn);
1131062SN/A                    }
1141062SN/A                }
1151062SN/A
1161062SN/A                format BasicOp {
1171062SN/A                    0x2: movz({{ if (Rt == 0) Rd = Rs; }});
1181062SN/A                    0x3: movn({{ if (Rt != 0) Rd = Rs; }});
1191062SN/A                }
1201062SN/A
1211062SN/A                format BasicOp {
1221062SN/A                    0x4: syscall({{ xc->syscall(R2); }},IsNonSpeculative);
1231062SN/A                    0x5: break({{ panic("Not implemented break yet"); }},IsNonSpeculative);
1241062SN/A                    0x7: sync({{  panic("Not implemented sync yet"); }},IsNonSpeculative);
1251062SN/A                }
1261062SN/A            }
1271062SN/A
1281062SN/A            0x2: decode FUNCTION_LO {
1291062SN/A                format BasicOp {
1301062SN/A                    0x0: mfhi({{ Rd = xc->readMiscReg(Hi); }});
1311062SN/A                    0x1: mthi({{ xc->setMiscReg(Hi,Rs); }});
1321062SN/A                    0x2: mflo({{ Rd = xc->readMiscReg(Lo); }});
1331062SN/A                    0x3: mtlo({{ xc->setMiscReg(Lo,Rs); }});
1341062SN/A                }
1351062SN/A            }
1361062SN/A
1371062SN/A            0x3: decode FUNCTION_LO {
1381062SN/A                format IntOp {
1391062SN/A                    0x0: mult({{
1402292SN/A                        int64_t temp1 = Rs.sd * Rt.sd;
1412292SN/A                        xc->setMiscReg(Hi,temp1<63:32>);
1422292SN/A                        xc->setMiscReg(Lo,temp1<31:0>);
1432292SN/A                    }});
1441062SN/A
1451062SN/A                    0x1: multu({{
1461062SN/A                        uint64_t temp1 = Rs.ud * Rt.ud;
1471062SN/A                        xc->setMiscReg(Hi,temp1<63:32>);
1481062SN/A                        xc->setMiscReg(Lo,temp1<31:0>);
1491062SN/A                    }});
1501062SN/A
1512292SN/A                    0x2: div({{
1522292SN/A                        xc->setMiscReg(Hi,Rs.sw % Rt.sw);
1532292SN/A                        xc->setMiscReg(Lo,Rs.sw / Rt.sw);
1542292SN/A                    }});
1552292SN/A
1562292SN/A                    0x3: divu({{
1572292SN/A                        xc->setMiscReg(Hi,Rs.uw % Rt.uw);
1582292SN/A                        xc->setMiscReg(Lo,Rs.uw / Rt.uw);
1592292SN/A                    }});
1602292SN/A                }
1612301SN/A            }
1622727Sktlim@umich.edu
1632353SN/A            0x4: decode HINT {
1642727Sktlim@umich.edu                0x0: decode FUNCTION_LO {
1652727Sktlim@umich.edu                    format IntOp {
1662727Sktlim@umich.edu                        0x0: add({{  Rd.sw = Rs.sw + Rt.sw;/*Trap on Overflow*/}});
1672727Sktlim@umich.edu                        0x1: addu({{ Rd.sw = Rs.sw + Rt.sw;}});
1682353SN/A                        0x2: sub({{ Rd.sw = Rs.sw - Rt.sw; /*Trap on Overflow*/}});
1692727Sktlim@umich.edu                        0x3: subu({{ Rd.sw = Rs.sw - Rt.sw;}});
1702727Sktlim@umich.edu                        0x4: and({{ Rd = Rs & Rt;}});
1712727Sktlim@umich.edu                        0x5: or({{ Rd = Rs | Rt;}});
1722727Sktlim@umich.edu                        0x6: xor({{ Rd = Rs ^ Rt;}});
1732353SN/A                        0x7: nor({{ Rd = ~(Rs | Rt);}});
1742727Sktlim@umich.edu                    }
1752727Sktlim@umich.edu                }
1762727Sktlim@umich.edu            }
1772301SN/A
1782301SN/A            0x5: decode HINT {
1792301SN/A                0x0: decode FUNCTION_LO {
1802727Sktlim@umich.edu                    format IntOp{
1812301SN/A                        0x2: slt({{  Rd.sw = ( Rs.sw < Rt.sw ) ? 1 : 0}});
1822727Sktlim@umich.edu                        0x3: sltu({{ Rd.uw = ( Rs.uw < Rt.uw ) ? 1 : 0}});
1832301SN/A                    }
1842301SN/A                }
1852301SN/A            }
1862727Sktlim@umich.edu
1872301SN/A            0x6: decode FUNCTION_LO {
1882727Sktlim@umich.edu                format Trap {
1892301SN/A                    0x0: tge({{  cond = (Rs.sw >= Rt.sw); }});
1902301SN/A                    0x1: tgeu({{ cond = (Rs.uw >= Rt.uw); }});
1912301SN/A                    0x2: tlt({{ cond = (Rs.sw < Rt.sw); }});
1922727Sktlim@umich.edu                    0x3: tltu({{ cond = (Rs.uw >= Rt.uw); }});
1932301SN/A                    0x4: teq({{ cond = (Rs.sw == Rt.sw); }});
1942727Sktlim@umich.edu                    0x6: tne({{ cond = (Rs.sw != Rt.sw); }});
1952301SN/A                }
1962301SN/A            }
1972301SN/A        }
1982727Sktlim@umich.edu
1992301SN/A        0x1: decode REGIMM_HI {
2002301SN/A            0x0: decode REGIMM_LO {
2012301SN/A                format Branch {
2022301SN/A                    0x0: bltz({{ cond = (Rs.sw < 0); }});
2032727Sktlim@umich.edu                    0x1: bgez({{ cond = (Rs.sw >= 0); }});
2042727Sktlim@umich.edu                }
2052727Sktlim@umich.edu
2062727Sktlim@umich.edu                format BranchLikely {
2072727Sktlim@umich.edu                    //MIPS obsolete instructions
2082727Sktlim@umich.edu                    0x2: bltzl({{ cond = (Rs.sw < 0); }});
2092727Sktlim@umich.edu                    0x3: bgezl({{ cond = (Rs.sw >= 0); }});
2102727Sktlim@umich.edu                }
2112727Sktlim@umich.edu            }
2122301SN/A
2132301SN/A            0x1: decode REGIMM_LO {
2142301SN/A                format Trap {
2152301SN/A                    0x0: tgei( {{ cond = (Rs.sw >= INTIMM); }});
2162301SN/A                    0x1: tgeiu({{ cond = (Rs.uw >= INTIMM); }});
2172727Sktlim@umich.edu                    0x2: tlti( {{ cond = (Rs.sw < INTIMM); }});
2182301SN/A                    0x3: tltiu({{ cond = (Rs.uw < INTIMM); }});
2192326SN/A                    0x4: teqi( {{ cond = (Rs.sw == INTIMM);}});
2202301SN/A                    0x6: tnei( {{ cond = (Rs.sw != INTIMM);}});
2212301SN/A                }
2222301SN/A            }
2232727Sktlim@umich.edu
2242301SN/A            0x2: decode REGIMM_LO {
2252326SN/A                format Branch {
2262301SN/A                    0x0: bltzal({{ cond = (Rs.sw < 0); }}, IsCall,IsReturn);
2272301SN/A                    0x1: bgezal({{ cond = (Rs.sw >= 0); }}, IsCall,IsReturn);
2282301SN/A                }
2292727Sktlim@umich.edu
2302301SN/A                format BranchLikely {
2312326SN/A                    //Will be removed in future MIPS releases
2322301SN/A                    0x2: bltzall({{ cond = (Rs.sw < 0); }}, IsCall, IsReturn);
2332301SN/A                    0x3: bgezall({{ cond = (Rs.sw >= 0); }}, IsCall, IsReturn);
2342301SN/A                }
2352727Sktlim@umich.edu            }
2362301SN/A
2372326SN/A            0x3: decode REGIMM_LO {
2382301SN/A                format WarnUnimpl {
2392301SN/A                    0x7: synci();
2402301SN/A                }
2412727Sktlim@umich.edu            }
2422301SN/A        }
2432326SN/A
2442301SN/A        format Jump {
2452301SN/A            0x2: j({{ NNPC = (NPC & 0xF0000000) | (JMPTARG << 2);}});
2462727Sktlim@umich.edu
2472301SN/A            0x3: jal({{ NNPC = (NPC & 0xF0000000) | (JMPTARG << 2); }},IsCall,IsReturn);
2482326SN/A        }
2492301SN/A
2502326SN/A        format Branch {
2512301SN/A            0x4: beq({{ cond = (Rs.sw == Rt.sw); }});
2522301SN/A            0x5: bne({{ cond = (Rs.sw != Rt.sw); }});
2532727Sktlim@umich.edu            0x6: decode RT {
2542301SN/A                0x0: blez({{ cond = (Rs.sw <= 0); }});
2552326SN/A            }
2562301SN/A
2572326SN/A            0x7: decode RT {
2582301SN/A                0x0: bgtz({{ cond = (Rs.sw > 0); }});
2592301SN/A            }
2602727Sktlim@umich.edu        }
2612326SN/A    }
2621062SN/A
2631062SN/A    0x1: decode OPCODE_LO {
2641681SN/A        format IntOp {
2651060SN/A            0x0: addi({{ Rt.sw = Rs.sw + imm; /*Trap If Overflow*/}});
2662292SN/A            0x1: addiu({{ Rt.sw = Rs.sw + imm;}});
2671060SN/A            0x2: slti({{ Rt.sw = ( Rs.sw < imm) ? 1 : 0 }});
2682292SN/A            0x3: sltiu({{ Rt.uw = ( Rs.uw < (uint32_t)sextImm ) ? 1 : 0 }});
2692292SN/A            0x4: andi({{ Rt.sw = Rs.sw & zextImm;}});
2702292SN/A            0x5: ori({{ Rt.sw = Rs.sw | zextImm;}});
2712292SN/A            0x6: xori({{ Rt.sw = Rs.sw ^ zextImm;}});
2722292SN/A
2732292SN/A            0x7: decode RS {
2742292SN/A                0x0: lui({{ Rt = imm << 16}});
2752292SN/A            }
2762292SN/A        }
2772292SN/A    }
2782733Sktlim@umich.edu
2791060SN/A    0x2: decode OPCODE_LO {
2801060SN/A
2811681SN/A        //Table A-11 MIPS32 COP0 Encoding of rs Field
2821060SN/A        0x0: decode RS_MSB {
2832292SN/A            0x0: decode RS {
2841060SN/A                format System {
2851060SN/A                    0x0: mfc0({{
2861060SN/A                        //uint64_t reg_num = Rd.uw;
2871060SN/A
2881060SN/A                        Rt = xc->readMiscReg(RD << 5 | SEL);
2891060SN/A                    }});
2901060SN/A
2911060SN/A                    0x4: mtc0({{
2921060SN/A                        //uint64_t reg_num = Rd.uw;
2932292SN/A
2942292SN/A                        xc->setMiscReg(RD << 5 | SEL,Rt);
2951060SN/A                    }});
2961060SN/A
2971060SN/A                    0x8: mftr({{
2981060SN/A                        //The contents of the coprocessor 0 register specified by the
2991681SN/A                        //combination of rd and sel are loaded into general register
3001060SN/A                        //rt. Note that not all coprocessor 0 registers support the
3012292SN/A                        //sel field. In those instances, the sel field must be zero.
3021060SN/A
3031060SN/A                        //MT Code Needed Here
3041060SN/A                    }});
3051060SN/A
3061060SN/A                    0xC: mttr({{
3071060SN/A                        //The contents of the coprocessor 0 register specified by the
3081060SN/A                        //combination of rd and sel are loaded into general register
3091681SN/A                        //rt. Note that not all coprocessor 0 registers support the
3101060SN/A                        //sel field. In those instances, the sel field must be zero.
3112292SN/A
3121060SN/A                        //MT Code Needed Here
3131060SN/A                    }});
3141060SN/A
3151060SN/A
3161060SN/A                    0xA: rdpgpr({{
3171060SN/A                        //Accessing Previous Shadow Set Register Number
3181060SN/A                        //uint64_t prev = xc->readMiscReg(SRSCtl)/*[PSS]*/;
3191681SN/A                        //uint64_t reg_num = Rt.uw;
3201060SN/A
3212980Sgblack@eecs.umich.edu                        //Rd = xc->regs.IntRegFile[prev];
3221060SN/A                       //Rd = xc->shadowIntRegFile[prev][reg_num];
3232292SN/A                    }});
3242292SN/A
3252292SN/A                    0xB: decode RD {
3262292SN/A
3271060SN/A                        0x0: decode SC {
3281060SN/A                            0x0: dvpe({{
3291681SN/A                                Rt.sw = xc->readMiscReg(MVPControl);
3301060SN/A                                xc->setMiscReg(MVPControl,0);
3312292SN/A                            }});
3321060SN/A
3332292SN/A                            0x1: evpe({{
3341060SN/A                                Rt.sw = xc->readMiscReg(MVPControl);
3351060SN/A                                xc->setMiscReg(MVPControl,1);
3362307SN/A                            }});
3372863Sktlim@umich.edu                        }
3382843Sktlim@umich.edu
3392307SN/A                        0x1: decode SC {
3402843Sktlim@umich.edu                            0x0: dmt({{
3412843Sktlim@umich.edu                                Rt.sw = xc->readMiscReg(VPEControl);
3422863Sktlim@umich.edu                                xc->setMiscReg(VPEControl,0);
3431681SN/A                            }});
3441681SN/A
3452316SN/A                            0x1: emt({{
3461681SN/A                                Rt.sw = xc->readMiscReg(VPEControl);
3472843Sktlim@umich.edu                                xc->setMiscReg(VPEControl,1);
3482843Sktlim@umich.edu                            }});
3492843Sktlim@umich.edu                        }
3502843Sktlim@umich.edu
3512843Sktlim@umich.edu                        0xC: decode SC {
3522843Sktlim@umich.edu                            0x0: di({{
3532843Sktlim@umich.edu                                Rt.sw = xc->readMiscReg(Status);
3541681SN/A                                xc->setMiscReg(Status,0);
3552348SN/A                            }});
3562307SN/A
3572367SN/A                            0x1: ei({{
3582367SN/A                                Rt.sw = xc->readMiscReg(Status);
3591681SN/A                                xc->setMiscReg(Status,1);
3602307SN/A                            }});
3612307SN/A                        }
3622307SN/A                    }
3632307SN/A
3642307SN/A                    0xE: wrpgpr({{
3652307SN/A                        //Accessing Previous Shadow Set Register Number
3662307SN/A                        //uint64_t prev = xc->readMiscReg(SRSCtl/*[PSS]*/);
3672307SN/A                        //uint64_t reg_num = Rd.uw;
3682307SN/A
3692307SN/A                        //xc->regs.IntRegFile[prev];
3701681SN/A                        //xc->shadowIntRegFile[prev][reg_num] = Rt;
3711681SN/A                    }});
3722307SN/A                }
3731681SN/A            }
3742307SN/A
3751060SN/A            //Table A-12 MIPS32 COP0 Encoding of Function Field When rs=CO
3762348SN/A            0x1: decode FUNCTION {
3772307SN/A                format System {
3782307SN/A                    0x01: tlbr({{ }});
3792307SN/A                    0x02: tlbwi({{ }});
3802307SN/A                    0x06: tlbwr({{ }});
3811060SN/A                    0x08: tlbp({{ }});
3822307SN/A                }
3832307SN/A
3842307SN/A                format WarnUnimpl {
3851060SN/A                    0x18: eret();
3862307SN/A                    0x1F: deret();
3872307SN/A                    0x20: wait();
3881060SN/A                }
3892307SN/A            }
3902307SN/A        }
3912307SN/A
3922307SN/A        //Table A-13 MIPS32 COP1 Encoding of rs Field
3932307SN/A        0x1: decode RS_MSB {
3941060SN/A
3952307SN/A            0x0: decode RS_HI {
3962307SN/A                0x0: decode RS_LO {
3972873Sktlim@umich.edu                    format WarnUnimpl {
3982307SN/A                        0x0: mfc1();//{{ /*Rt.uw = Fs.ud<31:0>;*/ }}
3991060SN/A                        0x3: mfhc1();// /*Rt.uw = Fs.ud<63:32>*/;
4001060SN/A                        0x4: mtc1();// /*Fs = Rt.uw*/
4011060SN/A                        0x7: mthc1();//{{/*Fs<63:32> = Rt.uw*/}}
4021681SN/A                    }
4031060SN/A
4042292SN/A                    format System {
4052107SN/A                        0x2: cfc1({{
4062292SN/A                            uint32_t fcsr_reg = xc->readMiscReg(FCSR);
4072292SN/A
4082107SN/A                            if (Fs == 0){
4092292SN/A                                Rt = xc->readMiscReg(FIR);
4102292SN/A                            } else if (Fs == 25) {
4112107SN/A                                Rt = 0 | (fcsr_reg & 0xFE000000) >> 24 | (fcsr_reg & 0x00800000) >> 23;
4122292SN/A                            } else if (Fs == 26) {
4133093Sksewell@umich.edu                                Rt = 0 | (fcsr_reg & 0x0003F07C);
4143093Sksewell@umich.edu                            } else if (Fs == 28) {
4153093Sksewell@umich.edu                                Rt = 0 | (fcsr_reg);
4162326SN/A                            } else if (Fs == 31) {
4172935Sksewell@umich.edu                                Rt = fcsr_reg;
4182292SN/A                            } else {
4192107SN/A                                panic("FP Control Value (%d) Not Available. Ignoring Access to"
4202292SN/A                                      "Floating Control Status Register",fcsr_reg);
4212935Sksewell@umich.edu                            }
4222935Sksewell@umich.edu
4232935Sksewell@umich.edu                        }});
4242292SN/A
4253093Sksewell@umich.edu                        0x6: ctc1({{
4262935Sksewell@umich.edu                            /*xc->setMiscReg(FPCR[Fs],Rt);*/
4272935Sksewell@umich.edu                        }});
4282935Sksewell@umich.edu                    }
4292935Sksewell@umich.edu                }
4302935Sksewell@umich.edu
4312935Sksewell@umich.edu                0x1: decode ND {
4322935Sksewell@umich.edu                    0x0: decode TF {
4332935Sksewell@umich.edu                        format Branch {
4342935Sksewell@umich.edu                            0x0: bc1f({{ cond = (xc->readMiscReg(FPCR) == 0); }});
4352935Sksewell@umich.edu                            0x1: bc1t({{ cond = (xc->readMiscReg(FPCR) == 1); }});
4362935Sksewell@umich.edu                        }
4372935Sksewell@umich.edu                    }
4382292SN/A
4392292SN/A                    0x1: decode TF {
4402292SN/A                        format BranchLikely {
4412292SN/A                            0x0: bc1fl({{ cond = (xc->readMiscReg(FPCR) == 0); }});
4422107SN/A                            0x1: bc1tl({{ cond = (xc->readMiscReg(FPCR) == 1); }});
4432292SN/A                        }
4442107SN/A                    }
4452292SN/A                }
4462292SN/A            }
4472107SN/A
4482935Sksewell@umich.edu            0x1: decode RS_HI {
4492935Sksewell@umich.edu                0x2: decode RS_LO {
4502702Sktlim@umich.edu
4512107SN/A                    //Table A-14 MIPS32 COP1 Encoding of Function Field When rs=S
4522107SN/A                    //(( single-word ))
4532107SN/A                    0x0: decode FUNCTION_HI {
4542107SN/A                        0x0: decode FUNCTION_LO {
4552292SN/A                            format FloatOp {
4562292SN/A                                0x0: adds({{ Fd.sf = Fs.sf + Ft.sf;}});
4572292SN/A                                0x1: subs({{ Fd.sf = Fs.sf - Ft.sf;}});
4582292SN/A                                0x2: muls({{ Fd.sf = Fs.sf * Ft.sf;}});
4592292SN/A                                0x3: divs({{ Fd.sf = Fs.sf / Ft.sf;}});
4602292SN/A                                0x4: sqrts({{ Fd.sf = sqrt(Fs.sf);}});
4612292SN/A                                0x5: abss({{ Fd.sf = fabs(Fs.sf);}});
4622292SN/A                                0x6: movs({{ Fd.sf = Fs.sf;}});
4632292SN/A                                0x7: negs({{ Fd.sf = -1 * Fs.sf;}});
4642935Sksewell@umich.edu                            }
4653969Sgblack@eecs.umich.edu                        }
4663093Sksewell@umich.edu
4673771Sgblack@eecs.umich.edu                        0x1: decode FUNCTION_LO {
4683795Sgblack@eecs.umich.edu                            //only legal for 64 bit-FP
4693795Sgblack@eecs.umich.edu                            format Float64Op {
4703795Sgblack@eecs.umich.edu                                0x0: round_l_s({{ Fd = convert_and_round(Fs.sf,RND_NEAREST,FP_LONG,FP_SINGLE);}});
4713771Sgblack@eecs.umich.edu                                0x1: trunc_l_s({{ Fd = convert_and_round(Fs.sf,RND_ZERO,FP_LONG,FP_SINGLE);}});
4723771Sgblack@eecs.umich.edu                                0x2: ceil_l_s({{ Fd = convert_and_round(Fs.sf,RND_UP,FP_LONG,FP_SINGLE);}});
4732935Sksewell@umich.edu                                0x3: floor_l_s({{ Fd = convert_and_round(Fs.sf,RND_DOWN,FP_LONG,FP_SINGLE);}});
4742935Sksewell@umich.edu                            }
4752935Sksewell@umich.edu
4763795Sgblack@eecs.umich.edu                            format FloatOp {
4773795Sgblack@eecs.umich.edu                                0x4: round_w_s({{ Fd = convert_and_round(Fs.sf,RND_NEAREST,FP_WORD,FP_SINGLE);}});
4783771Sgblack@eecs.umich.edu                                0x5: trunc_w_s({{ Fd = convert_and_round(Fs.sf,RND_ZERO,FP_WORD,FP_SINGLE);}});
4793771Sgblack@eecs.umich.edu                                0x6: ceil_w_s({{  Fd = convert_and_round(Fs.sf,RND_UP,FP_WORD,FP_SINGLE);}});
4803771Sgblack@eecs.umich.edu                                0x7: floor_w_s({{ Fd = convert_and_round(Fs.sf,RND_DOWN,FP_WORD,FP_SINGLE);}});
4813771Sgblack@eecs.umich.edu                            }
4823771Sgblack@eecs.umich.edu                        }
4833771Sgblack@eecs.umich.edu
4843795Sgblack@eecs.umich.edu                        0x2: decode FUNCTION_LO {
4852935Sksewell@umich.edu                            0x1: decode MOVCF {
4863795Sgblack@eecs.umich.edu                                format FloatOp {
4872935Sksewell@umich.edu                                    0x0: movfs({{if (xc->readMiscReg(FPCR) != CC) Fd = Fs; }});
4882935Sksewell@umich.edu                                    0x1: movts({{if (xc->readMiscReg(FPCR) == CC) Fd = Fs;}});
4893969Sgblack@eecs.umich.edu                                }
4902935Sksewell@umich.edu                            }
4913093Sksewell@umich.edu
4923093Sksewell@umich.edu                            format BasicOp {
4933093Sksewell@umich.edu                                0x2: movzs({{ if (Rt == 0) Fd = Fs; }});
4943093Sksewell@umich.edu                                0x3: movns({{ if (Rt != 0) Fd = Fs; }});
4953969Sgblack@eecs.umich.edu                            }
4962935Sksewell@umich.edu
4972292SN/A                            format Float64Op {
4982292SN/A                                0x5: recips({{ Fd = 1 / Fs; }});
4992292SN/A                                0x6: rsqrts({{ Fd = 1 / sqrt((double)Fs.ud);}});
5002292SN/A                            }
5012292SN/A                        }
5022292SN/A
5032292SN/A                        0x4: decode FUNCTION_LO {
5042292SN/A
5052292SN/A                            format FloatOp {
5062292SN/A                                0x1: cvt_d_s({{ int rnd_mode = xc->readMiscReg(FCSR);
5072292SN/A                                Fd = convert_and_round(Fs.sf,rnd_mode,FP_DOUBLE,FP_SINGLE);
5082292SN/A                                }});
5092292SN/A
5102292SN/A                                0x4: cvt_w_s({{ int rnd_mode = xc->readMiscReg(FCSR);
5112292SN/A                                Fd = convert_and_round(Fs.sf,rnd_mode,FP_WORD,FP_SINGLE);
5122292SN/A                                }});
5133795Sgblack@eecs.umich.edu                            }
5143795Sgblack@eecs.umich.edu
5153969Sgblack@eecs.umich.edu                            //only legal for 64 bit
5163969Sgblack@eecs.umich.edu                            format Float64Op {
5173795Sgblack@eecs.umich.edu                                0x5: cvt_l_s({{ int rnd_mode = xc->readMiscReg(FCSR);
5183732Sktlim@umich.edu                                Fd = convert_and_round(Fs.sf,rnd_mode,FP_LONG,FP_SINGLE);
5192292SN/A                                }});
5202292SN/A
5212292SN/A                                0x6: cvt_ps_s({{ /*Fd.df = Fs.df<31:0> | Ft.df<31:0>;*/ }});
5222292SN/A                            }
5232292SN/A                        }
5242292SN/A                    }
5252292SN/A
5262292SN/A                    //Table A-15 MIPS32 COP1 Encoding of Function Field When rs=D
5272292SN/A                    0x1: decode FUNCTION_HI {
5282292SN/A                        0x0: decode FUNCTION_LO {
5292292SN/A                            format FloatOp {
5302292SN/A                                0x0: addd({{ Fd.df = Fs.df + Ft.df;}});
5312292SN/A                                0x1: subd({{ Fd.df = Fs.df - Ft.df;}});
5322292SN/A                                0x2: muld({{ Fd.df = Fs.df * Ft.df;}});
5332292SN/A                                0x3: divd({{ Fd.df = Fs.df / Ft.df;}});
5342292SN/A                                0x4: sqrtd({{ Fd.df = sqrt(Fs.df);}});
5353795Sgblack@eecs.umich.edu                                0x5: absd({{ Fd.df = fabs(Fs.df);}});
5363958Sgblack@eecs.umich.edu                                0x6: movd({{ Fd.df = Fs.df;}});
5373969Sgblack@eecs.umich.edu                                0x7: negd({{ Fd.df = -1 * Fs.df;}});
5383969Sgblack@eecs.umich.edu                            }
5393795Sgblack@eecs.umich.edu                        }
5403732Sktlim@umich.edu
5412292SN/A                        0x1: decode FUNCTION_LO {
5422348SN/A                            //only legal for 64 bit
5432292SN/A                            format Float64Op {
5442292SN/A                                0x0: round_l_d({{ Fd = convert_and_round(Fs.df,RND_NEAREST,FP_LONG,FP_DOUBLE); }});
5452292SN/A                                0x1: trunc_l_d({{ Fd = convert_and_round(Fs.df,RND_ZERO,FP_LONG,FP_DOUBLE);}});
5462292SN/A                                0x2: ceil_l_d({{ Fd = convert_and_round(Fs.df,RND_UP,FP_LONG,FP_DOUBLE);}});
5472292SN/A                                0x3: floor_l_d({{ Fd = convert_and_round(Fs.df,RND_DOWN,FP_LONG,FP_DOUBLE);}});
5482292SN/A                            }
5492292SN/A
5502292SN/A                            format FloatOp {
5512292SN/A                                0x4: round_w_d({{ Fd = convert_and_round(Fs.df,RND_NEAREST,FP_LONG,FP_DOUBLE); }});
5522292SN/A                                0x5: trunc_w_d({{ Fd = convert_and_round(Fs.df,RND_ZERO,FP_LONG,FP_DOUBLE); }});
5532292SN/A                                0x6: ceil_w_d({{  Fd = convert_and_round(Fs.df,RND_UP,FP_LONG,FP_DOUBLE); }});
5542292SN/A                                0x7: floor_w_d({{ Fd = convert_and_round(Fs.df,RND_DOWN,FP_LONG,FP_DOUBLE); }});
5552292SN/A                            }
5562292SN/A                        }
5572292SN/A
5582292SN/A                        0x2: decode FUNCTION_LO {
5592292SN/A                            0x1: decode MOVCF {
5602292SN/A                                format FloatOp {
5612292SN/A                                    0x0: movfd({{if (xc->readMiscReg(FPCR) != CC) Fd.df = Fs.df; }});
5622292SN/A                                    0x1: movtd({{if (xc->readMiscReg(FPCR) == CC) Fd.df = Fs.df; }});
5632292SN/A                                }
5642292SN/A                            }
5652292SN/A
5662292SN/A                            format BasicOp {
5672292SN/A                                0x2: movzd({{ if (Rt == 0) Fd.df = Fs.df; }});
5682292SN/A                                0x3: movnd({{ if (Rt != 0) Fd.df = Fs.df; }});
5692292SN/A                            }
5702292SN/A
5712292SN/A                            format Float64Op {
5722292SN/A                                0x5: recipd({{ Fd.df = 1 / Fs.df}});
5732292SN/A                                0x6: rsqrtd({{ Fd.df = 1 / sqrt(Fs.df) }});
5742292SN/A                            }
5752292SN/A                        }
5762292SN/A
5772292SN/A                        0x4: decode FUNCTION_LO {
5782292SN/A                            format FloatOp {
5792292SN/A                                0x0: cvt_s_d({{
5802292SN/A                                    int rnd_mode = xc->readMiscReg(FCSR);
5812292SN/A                                    Fd = convert_and_round(Fs.df,rnd_mode,FP_SINGLE,FP_DOUBLE);
5822292SN/A                                }});
5832292SN/A
5842292SN/A                                0x4: cvt_w_d({{
5852292SN/A                                    int rnd_mode = xc->readMiscReg(FCSR);
5862292SN/A                                    Fd = convert_and_round(Fs.df,rnd_mode,FP_WORD,FP_DOUBLE);
5872292SN/A                                }});
5882292SN/A                            }
5891060SN/A
5901681SN/A                            //only legal for 64 bit
5911060SN/A                            format Float64Op {
5921060SN/A                                0x5: cvt_l_d({{
5932292SN/A                                    int rnd_mode = xc->readMiscReg(FCSR);
5942292SN/A                                    Fd = convert_and_round(Fs.df,rnd_mode,FP_LONG,FP_DOUBLE);
5952292SN/A                                }});
5962292SN/A                            }
5972292SN/A                        }
5982292SN/A                    }
5991681SN/A
6001681SN/A                    //Table A-16 MIPS32 COP1 Encoding of Function Field When rs=W
6011060SN/A                    0x4: decode FUNCTION {
6022292SN/A                        format FloatOp {
6031060SN/A                            0x20: cvt_s({{
6042292SN/A                                int rnd_mode = xc->readMiscReg(FCSR);
6052292SN/A                                Fd = convert_and_round(Fs.df,rnd_mode,FP_SINGLE,FP_WORD);
6061060SN/A                            }});
6072292SN/A
6082292SN/A                            0x21: cvt_d({{
6092292SN/A                                int rnd_mode = xc->readMiscReg(FCSR);
6102292SN/A                                Fd = convert_and_round(Fs.df,rnd_mode,FP_DOUBLE,FP_WORD);
6113221Sktlim@umich.edu                            }});
6123221Sktlim@umich.edu                        }
6133221Sktlim@umich.edu                    }
6143221Sktlim@umich.edu
6153221Sktlim@umich.edu                    //Table A-16 MIPS32 COP1 Encoding of Function Field When rs=L1
6162292SN/A                    //Note: "1. Format type L is legal only if 64-bit floating point operations
6172292SN/A                    //are enabled."
6182292SN/A                    0x5: decode FUNCTION_HI {
6192292SN/A                        format FloatOp {
6202326SN/A                            0x10: cvt_s_l({{
6212292SN/A                                int rnd_mode = xc->readMiscReg(FCSR);
6222292SN/A                                Fd = convert_and_round(Fs.df,rnd_mode,FP_SINGLE,FP_LONG);
6232820Sktlim@umich.edu                            }});
6242292SN/A
6252292SN/A                            0x11: cvt_d_l({{
6262292SN/A                                int rnd_mode = xc->readMiscReg(FCSR);
6272292SN/A                                Fd = convert_and_round(Fs.df,rnd_mode,FP_DOUBLE,FP_LONG);
6282353SN/A                            }});
6292292SN/A                        }
6302292SN/A                    }
6312353SN/A
6322353SN/A                    //Table A-17 MIPS64 COP1 Encoding of Function Field When rs=PS1
6332292SN/A                    //Note: "1. Format type PS is legal only if 64-bit floating point operations
6342292SN/A                    //are enabled. "
6352292SN/A                    0x6: decode FUNCTION_HI {
6362292SN/A                        0x0: decode FUNCTION_LO {
6372292SN/A                            format Float64Op {
6382292SN/A                                0x0: addps({{ //Must Check for Exception Here... Supposed to Operate on Upper and
6392292SN/A                                    //Lower Halves Independently but we take simulator shortcut
6402292SN/A                                    Fd.df = Fs.df + Ft.df;
6412292SN/A                                }});
6422292SN/A
6432292SN/A                                0x1: subps({{ //Must Check for Exception Here... Supposed to Operate on Upper and
6442292SN/A                                    //Lower Halves Independently but we take simulator shortcut
6452731Sktlim@umich.edu                                    Fd.df = Fs.df - Ft.df;
6462292SN/A                                }});
6472292SN/A
6482292SN/A                                0x2: mulps({{ //Must Check for Exception Here... Supposed to Operate on Upper and
6492292SN/A                                    //Lower Halves Independently but we take simulator shortcut
6502292SN/A                                    Fd.df = Fs.df * Ft.df;
6512292SN/A                                }});
6522292SN/A
6532292SN/A                                0x5: absps({{ //Must Check for Exception Here... Supposed to Operate on Upper and
6542292SN/A                                    //Lower Halves Independently but we take simulator shortcut
6552292SN/A                                    Fd.df = fabs(Fs.df);
6562292SN/A                                }});
6572292SN/A
6582292SN/A                                0x6: movps({{ //Must Check for Exception Here... Supposed to Operate on Upper and
6592292SN/A                                    //Lower Halves Independently but we take simulator shortcut
6602292SN/A                                    //Fd.df = Fs<31:0> |  Ft<31:0>;
6612292SN/A                                }});
6622292SN/A
6632292SN/A                                0x7: negps({{ //Must Check for Exception Here... Supposed to Operate on Upper and
6642292SN/A                                    //Lower Halves Independently but we take simulator shortcut
6652292SN/A                                    Fd.df = -1 * Fs.df;
6662292SN/A                                }});
6672292SN/A                            }
6682292SN/A                        }
6692292SN/A
6702292SN/A                        0x2: decode FUNCTION_LO {
6712292SN/A                            0x1: decode MOVCF {
6722292SN/A                                format Float64Op {
6732292SN/A                                    0x0: movfps({{if (xc->readMiscReg(FPCR) != CC) Fd = Fs;}});
6742292SN/A                                    0x1: movtps({{if (xc->readMiscReg(FPCR) == CC) Fd = Fs;}});
6752292SN/A                                }
6762292SN/A                            }
6772292SN/A
6782292SN/A                            format BasicOp {
6792292SN/A                                0x2: movzps({{if (xc->readMiscReg(FPCR) != CC) Fd = Fs; }});
6803867Sbinkertn@umich.edu                                0x3: movnps({{if (xc->readMiscReg(FPCR) == CC) Fd = Fs; }});
6813867Sbinkertn@umich.edu                            }
6822292SN/A
6833867Sbinkertn@umich.edu                        }
6843867Sbinkertn@umich.edu
6853867Sbinkertn@umich.edu                        0x4: decode FUNCTION_LO {
6862292SN/A                            0x0: Float64Op::cvt_s_pu({{
6872292SN/A                                int rnd_mode = xc->readMiscReg(FCSR);
6882292SN/A                                Fd = convert_and_round(Fs.df,rnd_mode,FP_DOUBLE,FP_PS_HI);
6892292SN/A                            }});
6902292SN/A                        }
6912292SN/A
6922292SN/A                        0x5: decode FUNCTION_LO {
6932292SN/A                            format Float64Op {
6942292SN/A                                0x0: cvt_s_pl({{
6952292SN/A                                    int rnd_mode = xc->readMiscReg(FCSR);
6962292SN/A                                    Fd = convert_and_round(Fs.df,rnd_mode,FP_SINGLE,FP_PS_LO);
6973867Sbinkertn@umich.edu                                }});
6983867Sbinkertn@umich.edu                                0x4: pll({{ /*Fd.df = Fs<31:0> | Ft<31:0>*/}});
6992292SN/A                                0x5: plu({{ /*Fd.df = Fs<31:0> | Ft<63:32>*/}});
7003867Sbinkertn@umich.edu                                0x6: pul({{ /*Fd.df = Fs<63:32> | Ft<31:0>*/}});
7013867Sbinkertn@umich.edu                                0x7: puu({{ /*Fd.df = Fs<63:32 | Ft<63:32>*/}});
7023867Sbinkertn@umich.edu                            }
7033867Sbinkertn@umich.edu                        }
7042292SN/A                    }
7052292SN/A                }
7062292SN/A            }
7072292SN/A        }
7081062SN/A
7091062SN/A        //Table A-19 MIPS32 COP2 Encoding of rs Field
7101681SN/A        0x2: decode RS_MSB {
7111062SN/A            0x0: decode RS_HI {
7122292SN/A                0x0: decode RS_LO {
7131062SN/A                    format WarnUnimpl {
7142292SN/A                        0x0: mfc2();
7151062SN/A                        0x2: cfc2();
7163867Sbinkertn@umich.edu                        0x3: mfhc2();
7173867Sbinkertn@umich.edu                        0x4: mtc2();
7181062SN/A                        0x6: ctc2();
7193867Sbinkertn@umich.edu                        0x7: mftc2();
7202292SN/A                    }
7211062SN/A                }
7222292SN/A
7232292SN/A                0x1: decode ND {
7242292SN/A                    0x0: decode TF {
7252292SN/A                        format WarnUnimpl {
7262292SN/A                            0x0: bc2f();
7271062SN/A                            0x1: bc2t();
7282292SN/A                        }
7292292SN/A                    }
7302292SN/A
7312292SN/A                    0x1: decode TF {
7322292SN/A                        format WarnUnimpl {
7332292SN/A                            0x0: bc2fl();
7341062SN/A                            0x1: bc2tl();
7352292SN/A                        }
7361062SN/A                    }
7372292SN/A                }
7382292SN/A            }
7392292SN/A        }
7402292SN/A
7412292SN/A        //Table A-20 MIPS64 COP1X Encoding of Function Field 1
7422292SN/A        //Note: "COP1X instructions are legal only if 64-bit floating point
7431062SN/A        //operations are enabled."
7442292SN/A        0x3: decode FUNCTION_HI {
7451062SN/A            0x0: decode FUNCTION_LO {
7462292SN/A                format LoadMemory2 {
7471062SN/A                    0x0: lwxc1({{ EA = Rs + Rt; }},{{ /*F_t<31:0> = Mem.sf; */}});
7481062SN/A                    0x1: ldxc1({{ EA = Rs + Rt; }},{{ /*F_t<63:0> = Mem.df;*/ }});
7491062SN/A                    0x5: luxc1({{ //Need to make EA<2:0> = 0
7501681SN/A                        EA = Rs + Rt;
7511062SN/A                    }},
7522292SN/A                {{ /*F_t<31:0> = Mem.df; */}});
7531062SN/A                }
7542292SN/A            }
7552292SN/A
7562292SN/A            0x1: decode FUNCTION_LO {
7571062SN/A                format StoreMemory2 {
7582292SN/A                    0x0: swxc1({{ EA = Rs + Rt; }},{{ /*Mem.sf = Ft<31:0>; */}});
7592292SN/A                    0x1: sdxc1({{ EA = Rs + Rt; }},{{ /*Mem.df = Ft<63:0> */}});
7602292SN/A                    0x5: suxc1({{ //Need to make EA<2:0> = 0
7612292SN/A                        EA = Rs + Rt;
7622292SN/A                    }},
7632292SN/A                {{ /*Mem.df = F_t<63:0>;*/}});
7642292SN/A                }
7651062SN/A
7662292SN/A                0x7: WarnUnimpl::prefx();
7672292SN/A            }
7682292SN/A
7692292SN/A            format FloatOp {
7702292SN/A                0x3: WarnUnimpl::alnv_ps();
7712292SN/A
7722292SN/A                format BasicOp {
7732292SN/A                    0x4: decode FUNCTION_LO {
7742292SN/A                        0x0: madd_s({{ Fd.sf = (Fs.sf * Fs.sf) + Fr.sf; }});
7752292SN/A                        0x1: madd_d({{ Fd.df = (Fs.df * Fs.df) + Fr.df; }});
7762292SN/A                        0x6: madd_ps({{
7772292SN/A                            //Must Check for Exception Here... Supposed to Operate on Upper and
7782292SN/A                            //Lower Halves Independently but we take simulator shortcut
7792292SN/A                            Fd.df = (Fs.df * Fs.df) + Fr.df;
7802292SN/A                        }});
7812292SN/A                    }
7822292SN/A
7832292SN/A                    0x5: decode FUNCTION_LO {
7842292SN/A                        0x0: msub_s({{ Fd.sf = (Fs.sf * Fs.sf) - Fr.sf; }});
7852292SN/A                        0x1: msub_d({{ Fd.df = (Fs.df * Fs.df) - Fr.df; }});
7862292SN/A                        0x6: msub_ps({{
7872292SN/A                            //Must Check for Exception Here... Supposed to Operate on Upper and
7882292SN/A                            //Lower Halves Independently but we take simulator shortcut
7892292SN/A                            Fd.df = (Fs.df * Fs.df) - Fr.df;
7902292SN/A                        }});
7912292SN/A                    }
7922292SN/A
7932292SN/A                    0x6: decode FUNCTION_LO {
7942292SN/A                        0x0: nmadd_s({{ Fd.sf = (-1 * Fs.sf * Fs.sf) - Fr.sf; }});
7952292SN/A                        0x1: nmadd_d({{ Fd.df = (-1 * Fs.df * Fs.df) + Fr.df; }});
7962292SN/A                        0x6: nmadd_ps({{
7972292SN/A                            //Must Check for Exception Here... Supposed to Operate on Upper and
7982292SN/A                            //Lower Halves Independently but we take simulator shortcut
7992292SN/A                            Fd.df = (-1 * Fs.df * Fs.df) + Fr.df;
8002292SN/A                        }});
8012292SN/A                    }
8022292SN/A
8032292SN/A                    0x7: decode FUNCTION_LO {
8042292SN/A                        0x0: nmsub_s({{ Fd.sf = (-1 * Fs.sf * Fs.sf) - Fr.sf; }});
8052292SN/A                        0x1: nmsub_d({{ Fd.df = (-1 * Fs.df * Fs.df) - Fr.df; }});
8062292SN/A                        0x6: nmsub_ps({{
8072292SN/A                            //Must Check for Exception Here... Supposed to Operate on Upper and
8082292SN/A                            //Lower Halves Independently but we take simulator shortcut
8092292SN/A                            Fd.df = (-1 * Fs.df * Fs.df) + Fr.df;
8102292SN/A                        }});
8112292SN/A                    }
8122292SN/A                }
8132292SN/A            }
8142292SN/A        }
8152292SN/A
8162292SN/A        //MIPS obsolete instructions
8172292SN/A        format BranchLikely {
8182292SN/A            0x4: beql({{ cond = (Rs.sw == 0); }});
8192292SN/A            0x5: bnel({{ cond = (Rs.sw != 0); }});
8202292SN/A            0x6: blezl({{ cond = (Rs.sw <= 0); }});
8212292SN/A            0x7: bgtzl({{ cond = (Rs.sw > 0); }});
8222292SN/A        }
8232292SN/A    }
8242292SN/A
8252292SN/A    0x3: decode OPCODE_LO default FailUnimpl::reserved() {
8262292SN/A
8272292SN/A        //Table A-5 MIPS32 SPECIAL2 Encoding of Function Field
8282292SN/A        0x4: decode FUNCTION_HI {
8292292SN/A
8302292SN/A            0x0: decode FUNCTION_LO {
8312292SN/A                format IntOp {
8322292SN/A                    0x0: madd({{
8332292SN/A                        int64_t temp1 = xc->readMiscReg(Hi) << 32 | xc->readMiscReg(Lo) >> 32;
8342292SN/A                        temp1 = temp1 + (Rs.sw * Rt.sw);
8352292SN/A                        xc->setMiscReg(Hi,temp1<63:32>);
8362292SN/A                        xc->setMiscReg(Lo,temp1<31:0>);
8372702Sktlim@umich.edu                            }});
8382292SN/A
8392292SN/A                    0x1: maddu({{
8402292SN/A                        int64_t temp1 = xc->readMiscReg(Hi) << 32 | xc->readMiscReg(Lo) >> 32;
8412702Sktlim@umich.edu                        temp1 = temp1 + (Rs.uw * Rt.uw);
8422702Sktlim@umich.edu                        xc->setMiscReg(Hi,temp1<63:32>);
8432292SN/A                        xc->setMiscReg(Lo,temp1<31:0>);
8442292SN/A                            }});
8452292SN/A
8462292SN/A                    0x2: mul({{ Rd.sw = Rs.sw * Rt.sw; 	}});
8472292SN/A
8482292SN/A                    0x4: msub({{
8492292SN/A                        int64_t temp1 = xc->readMiscReg(Hi) << 32 | xc->readMiscReg(Lo) >> 32;
8502292SN/A                        temp1 = temp1 - (Rs.sw * Rt.sw);
8512292SN/A                        xc->setMiscReg(Hi,temp1<63:32>);
8522292SN/A                        xc->setMiscReg(Lo,temp1<31:0>);
8532292SN/A                            }});
8542292SN/A
8552292SN/A                    0x5: msubu({{
8562292SN/A                        int64_t temp1 = xc->readMiscReg(Hi) << 32 | xc->readMiscReg(Lo) >> 32;
8572292SN/A                        temp1 = temp1 - (Rs.uw * Rt.uw);
8582292SN/A                        xc->setMiscReg(Hi,temp1<63:32>);
8592292SN/A                        xc->setMiscReg(Lo,temp1<31:0>);
8602292SN/A                            }});
8612292SN/A                }
8622292SN/A            }
8632292SN/A
8642292SN/A            0x4: decode FUNCTION_LO {
8652292SN/A                format BasicOp {
8662292SN/A                    0x0: clz({{
8672292SN/A                        /*int cnt = 0;
8682292SN/A                        int idx = 0;
8692292SN/A                        while ( Rs.uw<idx> != 1) {
8702292SN/A                            cnt++;
8712292SN/A                            idx--;
8722292SN/A                        }
8732292SN/A
8742292SN/A                        Rd.uw = cnt;*/
8752292SN/A                    }});
8762292SN/A
8772292SN/A                    0x1: clo({{
8782292SN/A                        /*int cnt = 0;
8792292SN/A                        int idx = 0;
8802292SN/A                        while ( Rs.uw<idx> != 0) {
8812292SN/A                            cnt++;
8822326SN/A                            idx--;
8833093Sksewell@umich.edu                        }
8842292SN/A
8852292SN/A                        Rd.uw = cnt;*/
8862326SN/A                    }});
8872935Sksewell@umich.edu                }
8882292SN/A            }
8892292SN/A
8902292SN/A            0x7: decode FUNCTION_LO {
8912292SN/A                0x7: WarnUnimpl::sdbbp();
8922292SN/A            }
8932292SN/A        }
8942292SN/A
8952702Sktlim@umich.edu        //Table A-6 MIPS32 SPECIAL3 Encoding of Function Field for Release 2 of the Architecture
8962702Sktlim@umich.edu        0x7: decode FUNCTION_HI {
8972935Sksewell@umich.edu
8982935Sksewell@umich.edu            0x0: decode FUNCTION_LO {
8992935Sksewell@umich.edu                format FailUnimpl {
9002702Sktlim@umich.edu                    0x1: ext();
9013093Sksewell@umich.edu                    0x4: ins();
9022935Sksewell@umich.edu                }
9032935Sksewell@umich.edu            }
9042935Sksewell@umich.edu
9052935Sksewell@umich.edu            0x1: decode FUNCTION_LO {
9062935Sksewell@umich.edu                format FailUnimpl {
9072935Sksewell@umich.edu                    0x0: fork();
9082935Sksewell@umich.edu                    0x1: yield();
9092935Sksewell@umich.edu                }
9102935Sksewell@umich.edu            }
9112935Sksewell@umich.edu
9122935Sksewell@umich.edu
9132702Sktlim@umich.edu            //Table A-10 MIPS32 BSHFL Encoding of sa Field
9142702Sktlim@umich.edu            0x4: decode SA {
9152702Sktlim@umich.edu
9162702Sktlim@umich.edu                0x02: FailUnimpl::wsbh();
9172702Sktlim@umich.edu
9182702Sktlim@umich.edu                format BasicOp {
9192702Sktlim@umich.edu                    0x10: seb({{ Rd.sw = Rt<7:0>}});
9202702Sktlim@umich.edu                    0x18: seh({{ Rd.sw = Rt<15:0>}});
9212702Sktlim@umich.edu                }
9222702Sktlim@umich.edu            }
9232702Sktlim@umich.edu
9242702Sktlim@umich.edu            0x6: decode FUNCTION_LO {
9252702Sktlim@umich.edu                0x7: FailUnimpl::rdhwr();//{{ /*Rt = xc->hwRegs[RD];*/ }}
9262292SN/A            }
9272292SN/A        }
9282292SN/A    }
9292292SN/A
9302292SN/A    0x4: decode OPCODE_LO default FailUnimpl::reserved() {
9312292SN/A        format LoadMemory {
9322292SN/A            0x0: lb({{ Rt.sw = Mem.sb; }});
9332292SN/A            0x1: lh({{ Rt.sw = Mem.sh; }});
9342292SN/A
9352292SN/A            0x2: lwl({{
9362292SN/A                uint32_t mem_word = Mem.uw;
9372292SN/A                uint32_t unalign_addr = Rs + disp;
9382292SN/A                uint32_t offset = unalign_addr & 0x00000003;
9392292SN/A#if BYTE_ORDER == BIG_ENDIAN
9402292SN/A                std::cout << "Big Endian Byte Order\n";
9412292SN/A
9422292SN/A                switch(offset)
9432292SN/A                {
9442733Sktlim@umich.edu                  case 0:
9452292SN/A                    Rt = mem_word;
9462292SN/A                    break;
9472292SN/A
9482292SN/A                  case 1:
9492292SN/A                    Rt &= 0x000F;
9502292SN/A                    Rt |= (mem_word << 4);
9512292SN/A                    break;
9522733Sktlim@umich.edu
9532292SN/A                  case 2:
9542292SN/A                    Rt &= 0x00FF;
9552292SN/A                    Rt |= (mem_word << 8);
9562292SN/A                    break;
9572292SN/A
9582292SN/A                  case 3:
9592292SN/A                    Rt &= 0x0FFF;
9602292SN/A                    Rt |= (mem_word << 12);
9612292SN/A                    break;
9622292SN/A
9632292SN/A                  default:
9642292SN/A                    panic("lwl: bad offset");
9652292SN/A                }
9662292SN/A#elif BYTE_ORDER == LITTLE_ENDIAN
9672292SN/A                std::cout << "Little Endian Byte Order\n";
9682292SN/A
9692292SN/A                switch(offset)
9702292SN/A                {
9712292SN/A                  case 0:
9722292SN/A                    Rt &= 0x0FFF;
9732292SN/A                    Rt |= (mem_word << 12);
9742292SN/A                    break;
9752292SN/A
9762292SN/A                  case 1:
9772292SN/A                    Rt &= 0x00FF;
9782292SN/A                    Rt |= (mem_word << 8);
9792292SN/A                    break;
9802292SN/A
9812292SN/A                  case 2:
9822292SN/A                    Rt &= 0x000F;
9832292SN/A                    Rt |= (mem_word << 4);
9842292SN/A                    break;
9852292SN/A
9862292SN/A                  case 3:
9872292SN/A                    Rt = mem_word;
9882292SN/A                    break;
9892292SN/A
9902292SN/A                  default:
9912292SN/A                    panic("lwl: bad offset");
9922292SN/A                }
9932292SN/A#endif
9942292SN/A            }}, {{ EA = (Rs + disp) & ~3; }});
9952292SN/A
9962292SN/A            0x3: lw({{ Rt.sw = Mem.sw; }});
9972292SN/A            0x4: lbu({{ Rt.uw = Mem.ub; }});
9982292SN/A            0x5: lhu({{ Rt.uw = Mem.uh; }});
9992292SN/A            0x6: lwr({{
10002292SN/A                uint32_t mem_word = Mem.uw;
10012292SN/A                uint32_t unalign_addr = Rs + disp;
10022292SN/A                uint32_t offset = unalign_addr & 0x00000003;
10032292SN/A
10042292SN/A#if BYTE_ORDER == BIG_ENDIAN
10052292SN/A                switch(offset)
10062292SN/A                {
10072292SN/A                  case 0: Rt &= 0xFFF0;  Rt |= (mem_word >> 12); break;
10082292SN/A                  case 1: Rt &= 0xFF00;  Rt |= (mem_word >> 8);  break;
10092292SN/A                  case 2: Rt &= 0xF000;  Rt |= (mem_word >> 4);  break;
10102292SN/A                  case 3: Rt = mem_word; break;
10112292SN/A                  default: panic("lwr: bad offset");
10122292SN/A                }
10132292SN/A#elif BYTE_ORDER == LITTLE_ENDIAN
10142292SN/A                switch(offset)
10152292SN/A                {
10162292SN/A                  case 0: Rt = mem_word; break;
10172292SN/A                  case 1: Rt &= 0xF000;  Rt |= (mem_word >> 4);  break;
10182292SN/A                  case 2: Rt &= 0xFF00;  Rt |= (mem_word >> 8);  break;
10192292SN/A                  case 3: Rt &= 0xFFF0;  Rt |= (mem_word >> 12); break;
10202292SN/A                  default: panic("lwr: bad offset");
10212292SN/A                }
10222292SN/A#endif
10232292SN/A            }},
10242820Sktlim@umich.edu            {{ EA = (Rs + disp) & ~3; }});
10252292SN/A        }
10262292SN/A
10272292SN/A        0x7: FailUnimpl::reserved();
10282292SN/A    }
10292292SN/A
10302292SN/A    0x5: decode OPCODE_LO default FailUnimpl::reserved() {
10312292SN/A        format StoreMemory {
10322292SN/A            0x0: sb({{ Mem.ub = Rt<7:0>; }});
10332292SN/A            0x1: sh({{ Mem.uh = Rt<15:0>; }});
10342292SN/A            0x2: swl({{
10352292SN/A                uint32_t mem_word = 0;
10362292SN/A                uint32_t aligned_addr = (Rs + disp) & ~3;
10372292SN/A                uint32_t unalign_addr = Rs + disp;
10382292SN/A                uint32_t offset = unalign_addr & 0x00000003;
10392292SN/A
10402292SN/A                DPRINTF(IEW,"Execute: aligned=0x%x unaligned=0x%x\n offset=0x%x",
10412292SN/A                        aligned_addr,unalign_addr,offset);
10422292SN/A
10432292SN/A                fault = xc->read(aligned_addr, (uint32_t&)mem_word, memAccessFlags);
10442292SN/A
10452292SN/A#if BYTE_ORDER == BIG_ENDIAN
10462292SN/A                switch(offset)
10472292SN/A                {
10482292SN/A                  case 0:
10492292SN/A                    Mem = Rt;
10502292SN/A                    break;
10512292SN/A
10522292SN/A                  case 1:
10532292SN/A                    mem_word &= 0xF000;
10542292SN/A                    mem_word |= (Rt >> 4);
10552292SN/A                    Mem = mem_word;
10562292SN/A                    break;
10572292SN/A
10582292SN/A                  case 2:
10592292SN/A                    mem_word &= 0xFF00;
10602292SN/A                    mem_word |= (Rt >> 8);
10612292SN/A                    Mem = mem_word;
10622292SN/A                    break;
10632292SN/A
10642292SN/A                  case 3:
10652292SN/A                    mem_word &= 0xFFF0;
10662292SN/A                    mem_word |= (Rt >> 12);
10672292SN/A                    Mem = mem_word;
10682292SN/A                   break;
10692292SN/A
10702292SN/A                  default:
10712292SN/A                    panic("swl: bad offset");
10722292SN/A                }
10732292SN/A#elif BYTE_ORDER == LITTLE_ENDIAN
10742292SN/A                switch(offset)
10752292SN/A                {
10762292SN/A                  case 0:
10772292SN/A                    mem_word &= 0xFFF0;
10782292SN/A                    mem_word |= (Rt >> 12);
10792292SN/A                    Mem = mem_word;
10802292SN/A                    break;
10812292SN/A
10822292SN/A                  case 1:
10832292SN/A                    mem_word &= 0xFF00;
10842292SN/A                    mem_word |= (Rt >> 8);
10852292SN/A                    Mem = mem_word;
10862292SN/A                    break;
10872292SN/A
10882292SN/A                  case 2:
10892292SN/A                    mem_word &= 0xF000;
10902292SN/A                    mem_word |= (Rt >> 4);
10912292SN/A                    Mem = mem_word;
10922292SN/A                    break;
10932292SN/A
10942292SN/A                  case 3:
10952292SN/A                    Mem = Rt;
10962292SN/A                   break;
10972292SN/A
10982292SN/A                  default:
10992292SN/A                    panic("swl: bad offset");
11002292SN/A                }
11012292SN/A#endif
11022292SN/A            }},{{ EA = (Rs + disp) & ~3; }},mem_flags = NO_ALIGN_FAULT);
11032292SN/A
11042292SN/A            0x3: sw({{ Mem.uw = Rt<31:0>; }});
11052292SN/A
11062292SN/A            0x6: swr({{
11072292SN/A                uint32_t mem_word = 0;
11082292SN/A                uint32_t aligned_addr = (Rs + disp) & ~3;
11092292SN/A                uint32_t unalign_addr = Rs + disp;
11102292SN/A                uint32_t offset = unalign_addr & 0x00000003;
11112292SN/A
11122292SN/A                fault = xc->read(aligned_addr, (uint32_t&)mem_word, memAccessFlags);
11132292SN/A
11142292SN/A#if BYTE_ORDER == BIG_ENDIAN
11152292SN/A                switch(offset)
11162292SN/A                {
11172292SN/A                  case 0:
11182336SN/A                    mem_word &= 0x0FFF;
11192336SN/A                    mem_word |= (Rt << 12);
11202336SN/A                    Mem = mem_word;
11212336SN/A                    break;
11222348SN/A
11232292SN/A                  case 1:
11242292SN/A                    mem_word &= 0x00FF;
11252292SN/A                    mem_word |= (Rt << 8);
11262292SN/A                    Mem = mem_word;
11272292SN/A                    break;
11282292SN/A
11292292SN/A                  case 2:
11302292SN/A                    mem_word &= 0x000F;
11312292SN/A                    mem_word |= (Rt << 4);
11322292SN/A                    Mem = mem_word;
11332292SN/A                    break;
11342326SN/A
11352292SN/A                  case 3:
11362292SN/A                    Mem = Rt;
11372292SN/A                    break;
11382292SN/A
11392292SN/A                  default:
11402292SN/A                    panic("swr: bad offset");
11412292SN/A                }
11422292SN/A#elif BYTE_ORDER == LITTLE_ENDIAN
11432292SN/A                switch(offset)
11442292SN/A                {
11452292SN/A                  case 0:
11462326SN/A                    Mem = Rt;
11472292SN/A                    break;
11482727Sktlim@umich.edu
11492301SN/A                  case 1:
11502292SN/A                    mem_word &= 0x000F;
11512292SN/A                    mem_word |= (Rt << 4);
11522292SN/A                    Mem = mem_word;
11532292SN/A                    break;
11542292SN/A
11552292SN/A                  case 2:
11562292SN/A                    mem_word &= 0x00FF;
11572292SN/A                    mem_word |= (Rt << 8);
11582292SN/A                    Mem = mem_word;
11592326SN/A                    break;
11602292SN/A
11612292SN/A                  case 3:
11622292SN/A                    mem_word &= 0x0FFF;
11632292SN/A                    mem_word |= (Rt << 12);
11642292SN/A                    Mem = mem_word;
11654033Sktlim@umich.edu                    break;
11664033Sktlim@umich.edu
11674033Sktlim@umich.edu                  default:
11684033Sktlim@umich.edu                    panic("swr: bad offset");
11694033Sktlim@umich.edu                }
11704033Sktlim@umich.edu#endif
11714033Sktlim@umich.edu            }},{{ EA = (Rs + disp) & ~3;}},mem_flags = NO_ALIGN_FAULT);
11724033Sktlim@umich.edu        }
11734033Sktlim@umich.edu
11744033Sktlim@umich.edu        format WarnUnimpl {
11754033Sktlim@umich.edu            0x7: cache();
11764033Sktlim@umich.edu        }
11774033Sktlim@umich.edu
11784033Sktlim@umich.edu    }
11792292SN/A
11802292SN/A    0x6: decode OPCODE_LO default FailUnimpl::reserved() {
11812292SN/A        0x0: FailUnimpl::ll();
11822292SN/A
11832292SN/A        format LoadMemory {
11842292SN/A            0x1: lwc1({{ /*F_t<31:0> = Mem.sf; */}});
11852292SN/A            0x5: ldc1({{ /*F_t<63:0> = Mem.df; */}});
11862292SN/A        }
11872292SN/A    }
11882292SN/A
11892292SN/A
11902292SN/A    0x7: decode OPCODE_LO default FailUnimpl::reserved() {
11912292SN/A        0x0: FailUnimpl::sc();
11922292SN/A
11932292SN/A        format StoreMemory {
11942935Sksewell@umich.edu            0x1: swc1({{ //Mem.sf = Ft<31:0>; }});
11952292SN/A            0x5: sdc1({{ //Mem.df = Ft<63:0>; }});
11962292SN/A        }
11972292SN/A    }
11982292SN/A}
11992292SN/A
12002292SN/A
12012292SN/A