decoder.isa revision 2100
12068SN/A// -*- mode:c++ -*-
22068SN/A
32068SN/A////////////////////////////////////////////////////////////////////
42068SN/A//
52068SN/A// The actual MIPS32 ISA decoder
62068SN/A// -----------------------------
72068SN/A// The following instructions are specified in the MIPS32 ISA
82068SN/A// Specification. Decoding closely follows the style specified
92068SN/A// in the MIPS32 ISAthe specification document starting with Table
102068SN/A// A-2 (document available @ www.mips.com)
112068SN/A//
122068SN/A//@todo: Distinguish "unknown/future" use insts from "reserved"
132068SN/A// ones
142068SN/Adecode OPCODE_HI default Unknown::unknown() {
152068SN/A
162068SN/A    // Derived From ... Table A-2 MIPS32 ISA Manual
172068SN/A    0x0: decode OPCODE_LO default FailUnimpl::reserved(){
182068SN/A
192068SN/A        0x0: decode FUNCTION_HI {
202068SN/A            0x0: decode FUNCTION_LO {
212068SN/A              0x1: decode MOVCI {
222068SN/A                format BasicOp {
232068SN/A                  0: movf({{ if( xc->miscRegs.fpcr == 0) Rd = Rs}});
242068SN/A                  1: movt({{ if( xc->miscRegs.fpcr == 1) Rd = Rs}});
252068SN/A                }
262068SN/A              }
272068SN/A
282665Ssaidi@eecs.umich.edu              format BasicOp {
292665Ssaidi@eecs.umich.edu
302665Ssaidi@eecs.umich.edu                //Table A-3 Note: "1. Specific encodings of the rt, rd, and sa fields
312068SN/A                //are used to distinguish among the SLL, NOP, SSNOP and EHB functions."
322649Ssaidi@eecs.umich.edu
332649Ssaidi@eecs.umich.edu                0x0: sll({{ Rd = Rt.uw << SA; }});
342649Ssaidi@eecs.umich.edu
352649Ssaidi@eecs.umich.edu                0x2: decode SRL {
362649Ssaidi@eecs.umich.edu                   0: srl({{ Rd = Rt.uw >> SA; }});
372068SN/A
382068SN/A                   //Hardcoded assuming 32-bit ISA, probably need parameter here
392068SN/A                   1: rotr({{ Rd = (Rt.uw << (32 - SA)) | (Rt.uw >> SA);}});
402068SN/A                 }
412068SN/A
422068SN/A                 0x3: sra({{ Rd = Rt.sw >> SA; }});
432068SN/A
442068SN/A                 0x4: sllv({{ Rd = Rt.uw << Rs<4:0>; }});
452068SN/A
465736Snate@binkert.org                 0x6: decode SRLV {
472068SN/A                   0: srlv({{ Rd = Rt.uw >> Rs<4:0>; }});
482068SN/A
496181Sksewell@umich.edu                   //Hardcoded assuming 32-bit ISA, probably need parameter here
506181Sksewell@umich.edu                   1: rotrv({{ Rd = (Rt.uw << (32 - Rs<4:0>)) | (Rt.uw >> Rs<4:0>);}});
512068SN/A                 }
522068SN/A
532068SN/A                 0x7: srav({{ Rd = Rt.sw >> Rs<4:0>; }});
542068SN/A              }
552068SN/A            }
562068SN/A
572068SN/A            0x1: decode FUNCTION_LO {
582068SN/A
592068SN/A              //Table A-3 Note: "Specific encodings of the hint field are used
602068SN/A              //to distinguish JR from JR.HB and JALR from JALR.HB"
612068SN/A              format Jump {
622068SN/A                0x0: jr(IsReturn);
632068SN/A                0x1: jalr(IsCall,IsReturn);
642068SN/A              }
652068SN/A
662068SN/A              format BasicOp {
672068SN/A                0x2: movz({{ if (Rt == 0) Rd = Rs; }});
682068SN/A                0x3: movn({{ if (Rt != 0) Rd = Rs; }});
696181Sksewell@umich.edu              }
706181Sksewell@umich.edu
712068SN/A
722068SN/A              format WarnUnimpl {
732068SN/A                0x4: syscall();//{{ xc->syscall()}},IsNonSpeculative
742068SN/A                0x5: break();
752068SN/A                0x7: sync();
762068SN/A              }
772068SN/A            }
782068SN/A
792068SN/A            0x2: decode FUNCTION_LO {
802068SN/A              format BasicOp {
812068SN/A                0x0: mfhi({{ Rd = xc->miscRegs.hi; }});
822068SN/A                0x1: mthi({{ xc->miscRegs.hi = Rs; }});
832068SN/A                0x2: mflo({{ Rd = xc->miscRegs.lo; }});
842068SN/A                0x3: mtlo({{ xc->miscRegs.lo = Rs; }});
852068SN/A              }
866181Sksewell@umich.edu            }
876181Sksewell@umich.edu
882068SN/A            0x3: decode FUNCTION_LO {
892068SN/A              format IntOp {
902068SN/A                0x0: mult({{
912068SN/A                        INT64 temp1 = Rs.sw * Rt.sw;
922068SN/A                        xc->miscRegs.hi->temp1<63:32>;
932068SN/A                        xc->miscRegs.lo->temp1<31:0>;
942068SN/A                }});
952068SN/A
962068SN/A                0x1: multu({{
972068SN/A                        INT64 temp1 = Rs.uw * Rt.uw;
982068SN/A                        xc->miscRegs.hi->temp1<63:32>;
992068SN/A                        xc->miscRegs.lo->temp1<31:0>
1002068SN/A                        Rd.sw = Rs.uw * Rt.uw;
1012068SN/A                }});
1022068SN/A
1032068SN/A                0x2: div({{
1042068SN/A                        xc->miscRegs.hi = Rs.sw % Rt.sw;
1052068SN/A                        xc->miscRegs.lo = Rs.sw / Rt.sw;
1062068SN/A                        }});
1072068SN/A
1082068SN/A                0x3: divu({{
1092068SN/A                        xc->miscRegs.hi = Rs.uw % Rt.uw;
1102068SN/A                        xc->miscRegs.lo = Rs.uw / Rt.uw;
1112068SN/A                        }});
1122068SN/A              }
1133953Sstever@eecs.umich.edu            }
1142068SN/A
1152068SN/A            0x4: decode FUNCTION_LO {
1162068SN/A              format IntOp {
1172068SN/A                0x0: add({{  Rd.sw = Rs.sw + Rt.sw;}});
1182068SN/A                0x1: addu({{ Rd.uw = Rs.uw + Rt.uw;}});
1192068SN/A                0x2: sub({{ Rd.sw = Rs.sw - Rt.sw;}});
1202068SN/A                0x3: subu({{ Rd.uw = Rs.uw - Rt.uw;}});
1212068SN/A                0x4: and({{ Rd.sw = Rs.uw & Rt.uw;}});
1222068SN/A                0x5: or({{ Rd.sw = Rs.uw | Rt.uw;}});
1232068SN/A                0x6: xor({{ Rd.sw = Rs.uw ^ Rt.uw;}});
1242068SN/A                0x7: nor({{ Rd.sw = ~(Rs.uw | Rt.uw);}});
1252068SN/A              }
1262068SN/A            }
1272068SN/A
1282068SN/A            0x5: decode FUNCTION_LO {
1292068SN/A              format IntOp{
1302227SN/A                0x2: slt({{  Rd.sw = ( Rs.sw < Rt.sw ) ? 1 : 0}});
1312068SN/A                0x3: sltu({{ Rd.uw = ( Rs.uw < Rt.uw ) ? 1 : 0}});
1322068SN/A              }
1332095SN/A            }
1346181Sksewell@umich.edu
1356181Sksewell@umich.edu            0x6: decode FUNCTION_LO {
1362095SN/A              format Trap {
1372095SN/A                 0x0: tge({{ cond = (Rs.sw >= Rt.sw); }});
1382095SN/A                 0x1: tgeu({{ cond = (Rs.uw >= Rt.uw); }});
1392068SN/A                 0x2: tlt({{ cond = (Rs.sw < Rt.sw); }});
1402068SN/A                 0x3: tltu({{ cond = (Rs.uw >= Rt.uw); }});
1412068SN/A                 0x4: teq({{ cond = (Rs.sw == Rt.sw); }});
1422095SN/A                 0x6: tne({{ cond = (Rs.sw != Rt.sw); }});
1436181Sksewell@umich.edu              }
1446181Sksewell@umich.edu            }
1456181Sksewell@umich.edu        }
1466181Sksewell@umich.edu
1472095SN/A        0x1: decode REGIMM_HI {
1482132SN/A            0x0: decode REGIMM_LO {
1492095SN/A              format Branch {
1502095SN/A                0x0: bltz({{ cond = (Rs.sw < 0); }});
1512095SN/A                0x1: bgez({{ cond = (Rs.sw >= 0); }});
1522095SN/A
1533349Sbinkertn@umich.edu              }
1542623SN/A
1552095SN/A              format BranchLikely {
1562095SN/A                //MIPS obsolete instructions
1576181Sksewell@umich.edu                0x2: bltzl({{ cond = (Rs.sw < 0); }});
1586181Sksewell@umich.edu                0x3: bgezl({{ cond = (Rs.sw >= 0); }});
1596181Sksewell@umich.edu              }
1602068SN/A            }
1613953Sstever@eecs.umich.edu
1622068SN/A            0x1: decode REGIMM_LO {
1633953Sstever@eecs.umich.edu              format Trap {
1642068SN/A                 0x0: tgei({{ cond = (Rs.sw >= INTIMM;  }});
1652068SN/A                 0x1: tgeiu({{ cond = (Rs.uw < INTIMM); }});
1666181Sksewell@umich.edu                 0x2: tlti({{ cond = (Rs.sw < INTIMM);  }});
1676181Sksewell@umich.edu                 0x3: tltiu({{ cond = (Rs.uw < INTIMM); }});
1682068SN/A                 0x4: teqi({{ cond = (Rs.sw == INTIMM); }});
1692068SN/A                 0x6: tnei({{ cond = (Rs.sw != INTIMM); }});
1702132SN/A              }
1712068SN/A            }
1722068SN/A
1732068SN/A            0x2: decode REGIMM_LO {
1742068SN/A              format Branch {
1753953Sstever@eecs.umich.edu                0x0: bltzal({{ cond = (Rs.sw < 0); }});
1762068SN/A                0x1: bgezal({{ cond = (Rs.sw >= 0); }});
1772090SN/A              }
1782068SN/A
1792068SN/A              format BranchLikely {
1802068SN/A                //MIPS obsolete instructions
1812068SN/A                0x2: bltzall({{ cond = (Rs.sw < 0); }});
1822068SN/A                0x3: bgezall({{ cond = (Rs.sw >= 0); }});
1832068SN/A              }
1842068SN/A            }
1852068SN/A
1862068SN/A            0x3: decode REGIMM_LO {
1872069SN/A              format WarnUnimpl {
1882132SN/A                0x7: synci();
1892068SN/A              }
1902068SN/A            }
1912068SN/A        }
1922132SN/A
1932068SN/A        format Jump {
1942068SN/A            0x2: j();
1952068SN/A            0x3: jal(IsCall);
1962069SN/A        }
1972068SN/A
1982068SN/A        format Branch {
1992090SN/A            0x4: beq({{ cond = (Rs.sw == 0); }});
2002069SN/A            0x5: bne({{ cond = (Rs.sw !=  0); }});
2012068SN/A            0x6: blez({{ cond = (Rs.sw <= 0); }});
2022068SN/A            0x7: bgtz({{ cond = (Rs.sw > 0); }});
2032068SN/A        }
2042090SN/A    }
2052069SN/A
2062069SN/A    0x1: decode OPCODE_LO default FailUnimpl::reserved(){
2072069SN/A        format IntOp {
2082069SN/A            0x0: addi({{ Rt.sw = Rs.sw + INTIMM; }});
2092069SN/A            0x1: addiu({{ Rt.uw = Rs.uw + INTIMM;}});
2102069SN/A            0x2: slti({{ Rt.sw = ( Rs.sw < INTIMM ) ? 1 : 0 }});
2112069SN/A            0x3: sltiu({{ Rt.uw = ( Rs.uw < INTIMM ) ? 1 : 0 }});
2122069SN/A            0x4: andi({{ Rt.sw = Rs.sw & INTIMM;}});
2132095SN/A            0x5: ori({{ Rt.sw = Rs.sw | INTIMM;}});
2142132SN/A            0x6: xori({{ Rt.sw = Rs.sw ^ INTIMM;}});
2152095SN/A            0x7: lui({{ Rt = INTIMM << 16}});
2162095SN/A        }
2172095SN/A    }
2182132SN/A
2192095SN/A    0x2: decode OPCODE_LO default FailUnimpl::reserved(){
2202095SN/A
2212095SN/A      //Table A-11 MIPS32 COP0 Encoding of rs Field
2222095SN/A      0x0: decode RS_MSB {
2232095SN/A        0x0: decode RS {
2242095SN/A
2252098SN/A           format BasicOp {
2262095SN/A                0x0: mfc0({{
2272095SN/A                        //The contents of the coprocessor 0 register specified by the
2282095SN/A                        //combination of rd and sel are loaded into general register
2292095SN/A                        //rt. Note that not all coprocessor 0 registers support the
2302095SN/A                        //sel field. In those instances, the sel field must be zero.
2312095SN/A
2322095SN/A                        if (SEL > 0)
2332095SN/A                                panic("Can't Handle Cop0 with register select yet\n");
2342095SN/A
2353349Sbinkertn@umich.edu                        uint64_t reg_num = Rd.uw;
2362095SN/A
2372095SN/A                        Rt = xc->miscRegs.cop0[reg_num];
2382095SN/A                        }});
2392132SN/A
2402095SN/A                0x4: mtc0({{
2412095SN/A                        //The contents of the coprocessor 0 register specified by the
2422506SN/A                        //combination of rd and sel are loaded into general register
2432095SN/A                        //rt. Note that not all coprocessor 0 registers support the
2442623SN/A                        //sel field. In those instances, the sel field must be zero.
2452095SN/A
2462098SN/A                        if (SEL > 0)
2472095SN/A                                panic("Can't Handle Cop0 with register select yet\n");
2482095SN/A
2492095SN/A                        uint64_t reg_num = Rd.uw;
2502098SN/A
2512095SN/A                        xc->miscRegs.cop0[reg_num] = Rt;
2522095SN/A                        }});
2532095SN/A
2542095SN/A                0x8: mftr({{
2552095SN/A                        //The contents of the coprocessor 0 register specified by the
2562095SN/A                        //combination of rd and sel are loaded into general register
2572095SN/A                        //rt. Note that not all coprocessor 0 registers support the
2582095SN/A                        //sel field. In those instances, the sel field must be zero.
2592069SN/A
2602132SN/A                        //MT Code Needed Here
2612069SN/A                        }});
2622069SN/A
2632069SN/A                0xC: mttr({{
2642132SN/A                        //The contents of the coprocessor 0 register specified by the
2654027Sstever@eecs.umich.edu                        //combination of rd and sel are loaded into general register
2664027Sstever@eecs.umich.edu                        //rt. Note that not all coprocessor 0 registers support the
2674027Sstever@eecs.umich.edu                        //sel field. In those instances, the sel field must be zero.
2684027Sstever@eecs.umich.edu
2694027Sstever@eecs.umich.edu                        //MT Code Needed Here
2704027Sstever@eecs.umich.edu                        }});
2714027Sstever@eecs.umich.edu
2724027Sstever@eecs.umich.edu
2734027Sstever@eecs.umich.edu                0xA: rdpgpr({{
2744027Sstever@eecs.umich.edu                        //Accessing Previous Shadow Set Register Number
2754027Sstever@eecs.umich.edu                        uint64_t prev = xc->miscRegs.cop0[SRSCtl][PSS];
2764027Sstever@eecs.umich.edu                        uint64_t reg_num = Rt.uw;
2774027Sstever@eecs.umich.edu
2784027Sstever@eecs.umich.edu                        Rd = xc->shadowIntRegFile[prev][reg_num];
2794027Sstever@eecs.umich.edu                        }});
2804027Sstever@eecs.umich.edu            }
2814027Sstever@eecs.umich.edu
2824027Sstever@eecs.umich.edu            0xB: decode RD {
2834027Sstever@eecs.umich.edu
2844027Sstever@eecs.umich.edu                0x0: decode SC {
2854027Sstever@eecs.umich.edu                  format BasicOp {
2864027Sstever@eecs.umich.edu                    0x0: dvpe({{
2874027Sstever@eecs.umich.edu                        Rt.sw = xc->miscRegs.cop0.MVPControl;
2884027Sstever@eecs.umich.edu                        xc->miscRegs.cop0.MVPControl[EVP] = 0;
2894027Sstever@eecs.umich.edu                        }});
2904027Sstever@eecs.umich.edu
2914027Sstever@eecs.umich.edu                    0x1: evpe({{
2924027Sstever@eecs.umich.edu                        Rt.sw = xc->miscRegs.cop0.MVPControl;
2934027Sstever@eecs.umich.edu                        xc->miscRegs.cop0.MVPControl[EVP] = 1;
2944027Sstever@eecs.umich.edu                        }});
2954027Sstever@eecs.umich.edu                  }
2964027Sstever@eecs.umich.edu                }
2974027Sstever@eecs.umich.edu
2984027Sstever@eecs.umich.edu                0x1: decode SC {
2992069SN/A                  format BasicOp {
3002069SN/A                    0x0: dmt({{
3012069SN/A                        Rt.sw = xc->miscRegs.cop0.VPEControl;
3022069SN/A                        xc->miscRegs.cop0.VPEControl[THREAD_ENABLE] = 0;
3032069SN/A                        }});
3042069SN/A
3052069SN/A                    0x1: emt({{
3062090SN/A                        Rt.sw = xc->miscRegs.cop0.VPEControl;
3072069SN/A                        xc->miscRegs.cop0.VPEControl[THREAD_ENABLE] = 1;
3082069SN/A                        }});
3092069SN/A                  }
3102090SN/A                }
3112069SN/A
3122069SN/A                0xC: decode SC {
3132069SN/A                  format BasicOp {
3142069SN/A                    0x0: di({{
3152069SN/A                        Rt.sw = xc->miscRegs.cop0.Status;
3162090SN/A                        xc->miscRegs.cop0.Status[INTERRUPT_ENABLE] = 0;
3172069SN/A                        }});
3182069SN/A
3192069SN/A                    0x1: ei({{
3202090SN/A                        Rt.sw = xc->miscRegs.cop0.Status;
3212069SN/A                        xc->miscRegs.cop0.Status[INTERRUPT_ENABLE] = 1;
3222069SN/A                        }});
3232069SN/A                  }
3242069SN/A                }
3252069SN/A            }
3262069SN/A
3272069SN/A            0xE: BasicOp::wrpgpr({{
3282095SN/A                        //Accessing Previous Shadow Set Register Number
3292132SN/A                        uint64_t prev = xc->miscRegs.cop0[SRSCtl][PSS];
3302095SN/A                        uint64_t reg_num = Rd.uw;
3312095SN/A
3322095SN/A                        xc->shadowIntRegFile[prev][reg_num] = Rt;
3332132SN/A                        }});
3342095SN/A        }
3352095SN/A
3362506SN/A        //Table A-12 MIPS32 COP0 Encoding of Function Field When rs=CO
3372095SN/A        0x1: decode FUNCTION {
3382095SN/A          format Trap {
3392095SN/A                0x01: tlbr({{ }});
3402098SN/A                0x02: tlbwi({{ }});
3412095SN/A                0x06: tlbwr({{ }});
3422095SN/A                0x08: tlbp({{ }});
3432095SN/A          }
3442098SN/A
3452095SN/A          format WarnUnimpl {
3462623SN/A                0x18: eret();
3472095SN/A                0x1F: deret();
3482095SN/A                0x20: wait();
3492095SN/A          }
3502095SN/A        }
3512095SN/A      }
3522095SN/A
3532095SN/A      //Table A-13 MIPS32 COP1 Encoding of rs Field
3542095SN/A      0x1: decode RS_MSB {
3552095SN/A
3563349Sbinkertn@umich.edu        0x0: decode RS_HI {
3572095SN/A          0x0: decode RS_LO {
3582095SN/A            format FloatOp {
3592095SN/A              0x0: mfc1({{ Rt = Fs<31:0>; }});
3602132SN/A              0x2: cfc1({{ Rt = xc->miscRegs.fpcr[Fs];}});
3612095SN/A              0x3: mfhc1({{ Rt = Fs<63:32>;}});
3622095SN/A              0x4: mtc1({{ Fs<31:0> = Rt}});
3632095SN/A              0x6: ctc1({{ xc->miscRegs.fpcr[Fs] = Rt;}});
3642095SN/A              0x7: mftc1({{ Fs<63:32> = Rt}});
3652623SN/A            }
3662623SN/A          }
3672623SN/A
3682623SN/A          0x1: decode ND {
3692623SN/A            0x0: decode TF {
3702623SN/A              format Branch {
3712623SN/A                0x0: bc1f({{ cond = (xc->miscRegs.fpcr == 0); }});
3722623SN/A                0x1: bc1t({{ cond = (xc->miscRegs.fpcr == 1); }});
3732623SN/A              }
3742623SN/A            }
3752623SN/A
3762623SN/A            0x1: decode TF {
3772623SN/A              format BranchLikely {
3782623SN/A                0x0: bc1fl({{ cond = (xc->miscRegs.fpcr == 0); }});
3793349Sbinkertn@umich.edu                0x1: bc1tl({{ cond = (xc->miscRegs.fpcr == 1); }});
3802623SN/A              }
3812623SN/A            }
3822623SN/A          }
3832623SN/A        }
3842623SN/A
3852623SN/A        0x1: decode RS_HI {
3862623SN/A          0x2: decode RS_LO {
3872623SN/A
3884040Ssaidi@eecs.umich.edu            //Table A-14 MIPS32 COP1 Encoding of Function Field When rs=S
3892095SN/A            //(( single-word ))
3902098SN/A            0x0: decode RS_HI {
3912095SN/A              0x0: decode RS_LO {
3922095SN/A                format FloatOp {
3932095SN/A                  0x0: adds({{ Fd.sf = Fs.sf + Ft.sf;}});
3942098SN/A                  0x1: subs({{ Fd.sf = Fs.sf - Ft.sf;}});
3952095SN/A                  0x2: muls({{ Fd.sf = Fs.sf * Ft.sf;}});
3962095SN/A                  0x3: divs({{ Fd.sf = Fs.sf / Ft.sf;}});
3972095SN/A                  0x4: sqrts({{ Fd.sf = sqrt(Fs.sf);}});
3982095SN/A                  0x5: abss({{ Fd.sf = abs(Fs.sf);}});
3992095SN/A                  0x6: movs({{ Fd.sf = Fs.sf;}});
4002095SN/A                  0x7: negs({{ Fd.sf = -1 * Fs.sf;}});
4012095SN/A                }
4022069SN/A              }
4032069SN/A
4042132SN/A              0x1: decode RS_LO {
4052068SN/A                //only legal for 64 bit-FP
4062068SN/A                format Float64Op {
4072068SN/A                  0x0: round_l_s({{ Fd = convert_and_round(Fs.sf,RND_NEAREST,FP_LONG,FP_SINGLE);}});
4082132SN/A                  0x1: trunc_l_s({{ Fd = convert_and_round(Fs.sf,RND_ZERO,FP_LONG,FP_SINGLE);}});
4092068SN/A                  0x2: ceil_l_s({{ Fd = convert_and_round(Fs.sf,RND_UP,FP_LONG,FP_SINGLE);}});
4102068SN/A                  0x3: floor_l_s({{ Fd = convert_and_round(Fs.sf,RND_DOWN,FP_LONG,FP_SINGLE);}});
4112068SN/A                }
4122069SN/A
4132068SN/A                format FloatOp {
4142068SN/A                  0x4: round_w_s({{ Fd = convert_and_round(Fs.sf,RND_NEAREST,FP_WORD,FP_SINGLE);}});
4152090SN/A                  0x5: trunc_w_s({{ Fd = convert_and_round(Fs.sf,RND_ZERO,FP_WORD,FP_SINGLE);}});
4162069SN/A                  0x6: ceil_w_s({{  Fd = convert_and_round(Fs.sf,RND_UP,FP_WORD,FP_SINGLE);}});
4172068SN/A                  0x7: floor_w_s({{ Fd = convert_and_round(Fs.sf,RND_DOWN,FP_WORD,FP_SINGLE);}});
4182068SN/A                }
4192090SN/A              }
4202068SN/A
4212068SN/A              0x2: decode RS_LO {
4222068SN/A                0x1: decode MOVCF {
4232095SN/A                  format FloatOp {
4242132SN/A                    0x0: movfs({{ if ( FPConditionCode(CC) == 0 ) Fd = Fs; }});
4252095SN/A                    0x1: movts({{ if ( FPConditionCode(CC) == 1 ) Fd = Fs;}});
4262095SN/A                  }
4276185Sksewell@umich.edu                }
4286185Sksewell@umich.edu
4292098SN/A                format BasicOp {
4302095SN/A                  0x2: movzs({{ if (Rt == 0) Fd = Fs; }});
4312095SN/A                  0x3: movns({{ if (Rt != 0) Fd = Fs; }});
4322095SN/A                }
4332095SN/A
4342095SN/A                format Float64Op {
4353349Sbinkertn@umich.edu                  0x2: recips({{ Fd = 1 / Fs; }});
4362095SN/A                  0x3: rsqrts({{ Fd = 1 / sqrt(Fs.ud);}});
4372095SN/A                }
4382095SN/A              }
4396185Sksewell@umich.edu
4406185Sksewell@umich.edu              0x4: decode RS_LO {
4412110SN/A
4422098SN/A                format FloatOp {
4432095SN/A                  0x1: cvt_d_s({{ int rnd_mode = xc->miscRegs.fcsr;
4442095SN/A                                Fd = convert_and_round(Fs.sf,rnd_mode,FP_DOUBLE,FP_SINGLE);
4452095SN/A                             }});
4466179Sksewell@umich.edu
4472068SN/A                  0x4: cvt_w_s({{ int rnd_mode = xc->miscRegs.fcsr;
4482068SN/A                                Fd = convert_and_round(Fs.sf,rnd_mode,FP_WORD,FP_SINGLE);
4492068SN/A                             }});
4502068SN/A                }
4512068SN/A
4522068SN/A                //only legal for 64 bit
4532068SN/A                format Float64Op {
4542068SN/A                  0x5: cvt_l_s({{ int rnd_mode = xc->miscRegs.fcsr;
4552068SN/A                                Fd = convert_and_round(Fs.sf,rnd_mode,FP_LONG,FP_SINGLE);
4562068SN/A                               }});
4572068SN/A
4582068SN/A                  0x6: cvt_ps_s({{ Fd.df = Fs.df<31:0> | Ft.df<31:0>; }});
4592068SN/A                }
4602068SN/A              }
4612068SN/A            }
4622068SN/A
4632068SN/A            //Table A-15 MIPS32 COP1 Encoding of Function Field When rs=D
4642068SN/A            0x1: decode RS_HI {
4652068SN/A              0x0: decode RS_LO {
4662068SN/A                format FloatOp {
4672068SN/A                  0x0: addd({{ Fd.df = Fs.df + Ft.df;}});
4682068SN/A                  0x1: subd({{ Fd.df = Fs.df - Ft.df;}});
4692068SN/A                  0x2: muld({{ Fd.df = Fs.df * Ft.df;}});
4702068SN/A                  0x3: divd({{ Fd.df = Fs.df / Ft.df;}});
4712068SN/A                  0x4: sqrtd({{ Fd.df = sqrt(Fs.df);}});
4722068SN/A                  0x5: absd({{ Fd.df = abs(Fs.df);}});
4732068SN/A                  0x6: movd({{ Fd.df = Fs.df;}});
4742075SN/A                  0x7: negd({{ Fd.df = -1 * Fs.df;}});
4752075SN/A                }
4762069SN/A              }
4772075SN/A
4782075SN/A              0x1: decode RS_LO {
4792075SN/A                //only legal for 64 bit
4802068SN/A                format Float64Op {
4812068SN/A                  0x0: round_l_d({{ Fd = convert_and_round(Fs.df,RND_NEAREST,FP_LONG,FP_DOUBLE); }});
4822068SN/A                  0x1: trunc_l_d({{ Fd = convert_and_round(Fs.df,RND_ZERO,FP_LONG,FP_DOUBLE);}});
4832068SN/A                  0x2: ceil_l_d({{ Fd = convert_and_round(Fs.df,RND_UP,FP_LONG,FP_DOUBLE);}});
4842068SN/A                  0x3: floor_l_d({{ Fd = convert_and_round(Fs.df,RND_DOWN,FP_LONG,FP_DOUBLE);}});
4852068SN/A                }
4862068SN/A
4872068SN/A                format FloatOp {
4882068SN/A                  0x4: round_w_d({{ Fd = convert_and_round(Fs.df,RND_NEAREST,FP_LONG,FP_DOUBLE); }});
4892068SN/A                  0x5: trunc_w_d({{ Fd = convert_and_round(Fs.df,RND_ZERO,FP_LONG,FP_DOUBLE); }});
4903953Sstever@eecs.umich.edu                  0x6: ceil_w_d({{  Fd = convert_and_round(Fs.df,RND_UP,FP_LONG,FP_DOUBLE); }});
4913953Sstever@eecs.umich.edu                  0x7: floor_w_d({{ Fd = convert_and_round(Fs.df,RND_DOWN,FP_LONG,FP_DOUBLE); }});
4923953Sstever@eecs.umich.edu                }
4933953Sstever@eecs.umich.edu              }
4943953Sstever@eecs.umich.edu
4953953Sstever@eecs.umich.edu              0x2: decode RS_LO {
4963953Sstever@eecs.umich.edu                0x1: decode MOVCF {
4973953Sstever@eecs.umich.edu                  format FloatOp {
4983953Sstever@eecs.umich.edu                    0x0: movfd({{ if (FPConditionCode(CC) == 0) Fd.df = Fs.df; }});
4992068SN/A                    0x1: movtd({{ if (FPConditionCode(CC) == 1) Fd.df = Fs.df; }});
5002068SN/A                  }
5015736Snate@binkert.org                }
5025745Snate@binkert.org
5032068SN/A                format BasicOp {
5042068SN/A                  0x2: movz({{ if (Rt == 0) Fd.df = Fs.df; }});
5052068SN/A                  0x3: movn({{ if (Rt != 0) Fd.df = Fs.df; }});
5062069SN/A                }
5072623SN/A
5084027Sstever@eecs.umich.edu                format Float64Op {
5094027Sstever@eecs.umich.edu                  0x5: recipd({{ Fd.df = 1 / Fs.df}});
5102623SN/A                  0x6: rsqrtd({{ Fd.df = 1 / sqrt(Fs.df) }});
5112623SN/A                }
5122069SN/A              }
5132095SN/A
5142095SN/A              0x4: decode RS_LO {
5152069SN/A                format FloatOp {
5162068SN/A                  0x0: cvt_s_d({{
5173953Sstever@eecs.umich.edu                                int rnd_mode = xc->miscRegs.fcsr;
5186181Sksewell@umich.edu                                Fd = convert_and_round(Fs.df,rnd_mode,FP_SINGLE,FP_DOUBLE);
5192068SN/A                              }});
5206181Sksewell@umich.edu
5216181Sksewell@umich.edu                  0x4: cvt_w_d({{
5223953Sstever@eecs.umich.edu                                int rnd_mode = xc->miscRegs.fcsr;
5236192Sksewell@umich.edu                                Fd = convert_and_round(Fs.df,rnd_mode,FP_WORD,FP_DOUBLE);
5242068SN/A                              }});
5252068SN/A                }
5262075SN/A
5272075SN/A                //only legal for 64 bit
5282068SN/A                format Float64Op {
5292075SN/A                  0x5: cvt_l_d({{
5302069SN/A                                int rnd_mode = xc->miscRegs.fcsr;
5312069SN/A                                Fd = convert_and_round(Fs.df,rnd_mode,FP_LONG,FP_DOUBLE);
5322068SN/A                              }});
5332068SN/A                }
5342068SN/A              }
5352068SN/A            }
5362075SN/A
5372075SN/A            //Table A-16 MIPS32 COP1 Encoding of Function Field When rs=W
5382068SN/A            0x4: decode FUNCTION {
5392068SN/A              format FloatOp {
5402075SN/A                0x10: cvt_s({{
5412069SN/A                                int rnd_mode = xc->miscRegs.fcsr;
5422069SN/A                                Fd = convert_and_round(Fs.df,rnd_mode,FP_SINGLE,FP_WORD);
5432068SN/A                            }});
5442068SN/A
5452068SN/A                0x10: cvt_d({{
5462075SN/A                                int rnd_mode = xc->miscRegs.fcsr;
5472075SN/A                                Fd = convert_and_round(Fs.df,rnd_mode,FP_DOUBLE,FP_WORD);
5482075SN/A                            }});
5492075SN/A              }
5502075SN/A            }
5512075SN/A
5522075SN/A            //Table A-16 MIPS32 COP1 Encoding of Function Field When rs=L1
5532075SN/A            //Note: "1. Format type L is legal only if 64-bit floating point operations
5542068SN/A            //are enabled."
5552068SN/A            0x5: decode FUNCTION_HI {
5562069SN/A              format FloatOp {
5572069SN/A                0x10: cvt_s_l({{
5582075SN/A                                int rnd_mode = xc->miscRegs.fcsr;
5592068SN/A                                Fd = convert_and_round(Fs.df,rnd_mode,FP_SINGLE,FP_LONG);
5602068SN/A                            }});
5612068SN/A
5622068SN/A                0x11: cvt_d_l({{
5632068SN/A                                int rnd_mode = xc->miscRegs.fcsr;
5642068SN/A                                Fd = convert_and_round(Fs.df,rnd_mode,FP_DOUBLE,FP_LONG);
5652068SN/A                            }});
5662075SN/A              }
5672075SN/A            }
5682068SN/A
5692075SN/A            //Table A-17 MIPS64 COP1 Encoding of Function Field When rs=PS1
5702069SN/A            //Note: "1. Format type PS is legal only if 64-bit floating point operations
5712068SN/A            //are enabled. "
5722068SN/A            0x6: decode RS_HI {
5732068SN/A              0x0: decode RS_LO {
5742075SN/A                format Float64Op {
5752075SN/A                  0x0: addps({{ //Must Check for Exception Here... Supposed to Operate on Upper and
5762075SN/A                                //Lower Halves Independently but we take simulator shortcut
5772068SN/A                                Fd.df = Fs.df + Ft.df;
5782075SN/A                             }});
5792623SN/A
5802068SN/A                  0x1: subps({{ //Must Check for Exception Here... Supposed to Operate on Upper and
5812068SN/A                                //Lower Halves Independently but we take simulator shortcut
5822068SN/A                                Fd.df = Fs.df - Ft.df;
5832068SN/A                            }});
5842075SN/A
5852075SN/A                  0x2: mulps({{ //Must Check for Exception Here... Supposed to Operate on Upper and
5862068SN/A                                //Lower Halves Independently but we take simulator shortcut
5872075SN/A                                Fd.df = Fs.df * Ft.df;
5882069SN/A                            }});
5892068SN/A
5902068SN/A                  0x5: absps({{ //Must Check for Exception Here... Supposed to Operate on Upper and
5912068SN/A                                //Lower Halves Independently but we take simulator shortcut
592                                Fd.df = abs(Fs.df);
593                            }});
594
595                  0x6: movps({{ //Must Check for Exception Here... Supposed to Operate on Upper and
596                                //Lower Halves Independently but we take simulator shortcut
597                                Fd.df = Fs<31:0> |  Ft<31:0>;
598                            }});
599
600                  0x7: negps({{ //Must Check for Exception Here... Supposed to Operate on Upper and
601                                //Lower Halves Independently but we take simulator shortcut
602                                Fd.df = -1 * Fs.df;
603                            }});
604                }
605              }
606
607              0x2: decode RS_LO {
608                0x1: decode MOVCF {
609                  format Float64Op {
610                    0x0: movfps({{ if ( FPConditionCode(CC) == 0) Fd = Fs;}});
611                    0x1: movtps({{ if ( FPConditionCode(CC) == 0) Fd = Fs;}});
612                  }
613                }
614
615              }
616
617              0x4: decode RS_LO {
618                0x0: Float64Op::cvt_s_pu({{
619                                int rnd_mode = xc->miscRegs.fcsr;
620                                Fd = convert_and_round(Fs.df,rnd_mode,FP_DOUBLE,FP_PS_HI);
621                           }});
622              }
623
624              0x5: decode RS_LO {
625                format Float64Op {
626                  0x0: cvt_s_pl({{
627                                int rnd_mode = xc->miscRegs.fcsr;
628                                Fd = convert_and_round(Fs.df,rnd_mode,FP_SINGLE,FP_PS_LO);
629                           }});
630                  0x4: pll({{ Fd.df = Fs<31:0> | Ft<31:0>}});
631                  0x5: plu({{ Fd.df = Fs<31:0> | Ft<63:32>}});
632                  0x6: pul({{ Fd.df = Fs<63:32> | Ft<31:0>}});
633                  0x7: puu({{ Fd.df = Fs<63:32 | Ft<63:32>}});
634                }
635              }
636            }
637      }
638
639      //Table A-19 MIPS32 COP2 Encoding of rs Field
640      0x2: decode RS_MSB {
641        0x0: decode RS_HI {
642          0x0: decode RS_LO {
643            format WarnUnimpl {
644                0x0: mfc2();
645                0x2: cfc2();
646                0x3: mfhc2();
647                0x4: mtc2();
648                0x6: ctc2();
649                0x7: mftc2();
650            }
651          }
652
653          0x1: decode ND {
654            0x0: decode TF {
655              format WarnUnimpl {
656                0x0: bc2f();
657                0x1: bc2t();
658              }
659            }
660
661            0x1: decode TF {
662              format WarnUnimpl {
663                0x0: bc2fl();
664                0x1: bc2tl();
665              }
666            }
667          }
668        }
669      }
670
671      //Table A-20 MIPS64 COP1X Encoding of Function Field 1
672      //Note: "COP1X instructions are legal only if 64-bit floating point
673      //operations are enabled."
674      0x3: decode FUNCTION_HI {
675        0x0: decode FUNCTION_LO {
676                format Memory {
677                  0x0: lwxc1({{ EA = Rs + Rt; }},{{ Ft<31:0> = Mem.uf; }});
678                  0x1: ldxc1({{ EA = Rs + Rt; }},{{ Ft<63:0> = Mem.df; }});
679                  0x5: luxc1({{ //Need to make EA<2:0> = 0
680                                EA = Rs + Rt;
681                             }},
682                             {{ Ft<31:0> = Mem.df; }});
683                }
684        }
685
686        0x1: decode FUNCTION_LO {
687                format Memory {
688                  0x0: swxc1({{ EA = Rs + Rt; }},{{ Mem.uf = Ft<31:0>; }});
689                  0x1: sdxc1({{ EA = Rs + Rt; }},{{ Mem.uf = Ft<63:0>}});
690                  0x5: suxc1({{ //Need to make EA<2:0> = 0
691                                EA = Rs + Rt;
692                             }},
693                             {{ Mem.df = Ft<63:0>;}});
694                }
695
696                0x7: WarnUnimpl::prefx();
697        }
698
699        format FloatOp {
700                0x3: WarnUnimpl::alnv_ps();
701
702                format BasicOp {
703                  0x4: decode FUNCTION_LO {
704                    0x0: madd_s({{ Fd.sf = (Fs.sf * Fs.sf) + Fr.sf; }});
705                    0x1: madd_d({{ Fd.df = (Fs.df * Fs.df) + Fr.df; }});
706                    0x6: madd_ps({{
707                                //Must Check for Exception Here... Supposed to Operate on Upper and
708                                //Lower Halves Independently but we take simulator shortcut
709                                Fd.df = (Fs.df * Fs.df) + Fr.df;
710                                }});
711                  }
712
713                  0x5: decode FUNCTION_LO {
714                    0x0: msub_s({{ Fd.sf = (Fs.sf * Fs.sf) - Fr.sf; }});
715                    0x1: msub_d({{ Fd.df = (Fs.df * Fs.df) - Fr.df; }});
716                    0x6: msub_ps({{
717                                //Must Check for Exception Here... Supposed to Operate on Upper and
718                                //Lower Halves Independently but we take simulator shortcut
719                                Fd.df = (Fs.df * Fs.df) - Fr.df;
720                                }});
721                  }
722
723                  0x6: decode FUNCTION_LO {
724                    0x0: nmadd_s({{ Fd.sf = (-1 * Fs.sf * Fs.sf) - Fr.sf; }});
725                    0x1: nmadd_d({{ Fd.df = (-1 * Fs.df * Fs.df) + Fr.df; }});
726                    0x6: nmadd_ps({{
727                                //Must Check for Exception Here... Supposed to Operate on Upper and
728                                //Lower Halves Independently but we take simulator shortcut
729                                Fd.df = (-1 * Fs.df * Fs.df) + Fr.df;
730                                }});
731                  }
732
733                  0x7: decode FUNCTION_LO {
734                    0x0: nmsub_s({{ Fd.sf = (-1 * Fs.sf * Fs.sf) - Fr.sf; }});
735                    0x1: nmsub_d({{ Fd.df = (-1 * Fs.df * Fs.df) - Fr.df; }});
736                    0x6: nmsub_ps({{
737                                //Must Check for Exception Here... Supposed to Operate on Upper and
738                                //Lower Halves Independently but we take simulator shortcut
739                                Fd.df = (-1 * Fs.df * Fs.df) + Fr.df;
740                                }});
741                  }
742                }
743        }
744      }
745
746      //MIPS obsolete instructions
747        format BranchLikely {
748              0x4: beql({{ cond = (Rs.sw == 0); }});
749              0x5: bnel({{ cond = (Rs.sw != 0); }});
750              0x6: blezl({{ cond = (Rs.sw <= 0); }});
751              0x7: bgtzl({{ cond = (Rs.sw > 0); }});
752        }
753    }
754
755    0x3: decode OPCODE_LO default FailUnimpl::reserved() {
756
757        //Table A-5 MIPS32 SPECIAL2 Encoding of Function Field
758        0x4: decode FUNCTION_HI {
759
760            0x0: decode FUNCTION_LO {
761                format IntOp {
762                   0x0: madd({{
763                        INT64 temp1 = Hi.sw << 32 | Lo.sw >> 32;
764                        temp1 = temp1 + (Rs.sw * Rt.sw);
765                        xc->miscRegs.hi->temp1<63:32>;
766                        xc->miscRegs.lo->temp1<31:0>
767                        }});
768
769                   0x1: maddu({{
770                        INT64 temp1 = Hi.uw << 32 | Lo.uw >> 32;
771                        temp1 = temp1 + (Rs.uw * Rt.uw);
772                        xc->miscRegs.hi->temp1<63:32>;
773                        xc->miscRegs.lo->temp1<31:0>
774                        }});
775
776                   0x2: mul({{ 	Rd.sw = Rs.sw * Rt.sw; 	}});
777
778                   0x4: msub({{
779                        INT64 temp1 = Hi.sw << 32 | Lo.sw >> 32;
780                        temp1 = temp1 - (Rs.sw * Rt.sw);
781                        xc->miscRegs.hi->temp1<63:32>;
782                        xc->miscRegs.lo->temp1<31:0>
783                        }});
784
785                   0x5: msubu({{
786                        INT64 temp1 = Hi.uw << 32 | Lo.uw >> 32;
787                        temp1 = temp1 - (Rs.uw * Rt.uw);
788                        xc->miscRegs.hi->temp1<63:32>;
789                        xc->miscRegs.lo->temp1<31:0>
790                        }});
791                }
792            }
793
794            0x4: decode FUNCTION_LO {
795                  format BasicOp {
796                      0x0: clz({{
797                        int cnt = 0;
798                        int idx = 0;
799                        while ( Rs.uw<idx>!= 1) {
800                                cnt++;
801                                idx--;
802                        }
803
804                        Rd.uw = cnt;
805                        }});
806
807                      0x1: clo({{
808                        int cnt = 0;
809                        int idx = 0;
810                        while ( Rs.uw<idx>!= 0) {
811                                cnt++;
812                                idx--;
813                        }
814
815                        Rd.uw = cnt;
816                        }});
817                  }
818            }
819
820            0x7: decode FUNCTION_LO {
821              0x7: WarnUnimpl::sdbbp();
822            }
823        }
824
825        //Table A-6 MIPS32 SPECIAL3 Encoding of Function Field for Release 2 of the Architecture
826        0x7: decode FUNCTION_HI {
827
828          0x0: decode FUNCTION_LO {
829                format WarnUnimpl {
830                    0x1: ext();
831                    0x4: ins();
832                }
833          }
834
835          0x1: decode FUNCTION_LO {
836                format WarnUnimpl {
837                    0x0: fork();
838                    0x1: yield();
839                }
840          }
841
842
843          //Table A-10 MIPS32 BSHFL Encoding of sa Field
844          0x4: decode SA {
845
846                0x02: WarnUnimpl::wsbh();
847
848                format BasicOp {
849                    0x10: seb({{ Rd.sw = /* sext32(Rt<7>,24)  | */ Rt<7:0>}});
850                    0x18: seh({{ Rd.sw = /* sext32(Rt<15>,16) | */ Rt<15:0>}});
851                }
852          }
853
854          0x6: decode FUNCTION_LO {
855            0x7: BasicOp::rdhwr({{ Rt = xc->hwRegs[RD];}});
856          }
857        }
858    }
859
860    0x4: decode OPCODE_LO default FailUnimpl::reserved() {
861        format Memory {
862            0x0: lb({{ EA = Rs + disp; }}, {{ Rb.sw = Mem.sb; }});
863            0x1: lh({{ EA = Rs + disp; }}, {{ Rb.sw = Mem.sh; }});
864            0x2: lwl({{ EA = Rs + disp; }}, {{ Rb.sw = Mem.sw; }});//, WordAlign);
865            0x3: lw({{ EA = Rs + disp; }}, {{ Rb.uq = Mem.sb; }});
866            0x4: lbu({{ EA = Rs + disp; }}, {{ Rb.uw = Mem.ub; }});
867            0x5: lhu({{ EA = Rs + disp; }}, {{ Rb.uw = Mem.uh; }});
868            0x6: lwr({{ EA = Rs + disp; }}, {{ Rb.uw = Mem.uw; }});//, WordAlign);
869        }
870
871        0x7: FailUnimpl::reserved();
872    }
873
874    0x5: decode OPCODE_LO default FailUnimpl::reserved() {
875        format Memory {
876            0x0: sb({{ EA = Rs + disp; }}, {{ Mem.ub = Rt<7:0>; }});
877            0x1: sh({{ EA = Rs + disp; }},{{ Mem.uh = Rt<15:0>; }});
878            0x2: swl({{ EA = Rs + disp; }},{{ Mem.ub = Rt<31:0>; }});//,WordAlign);
879            0x3: sw({{ EA = Rs + disp; }},{{ Mem.ub = Rt<31:0>; }});
880            0x6: swr({{ EA = Rs + disp; }},{{ Mem.ub = Rt<31:0>; }});//,WordAlign);
881        }
882
883        format WarnUnimpl {
884            0x7: cache();
885        }
886
887    }
888
889    0x6: decode OPCODE_LO default FailUnimpl::reserved() {
890            0x0: WarnUnimpl::ll();
891
892        format Memory {
893            0x1: lwc1({{ EA = Rs + disp; }},{{ Ft<31:0> = Mem.uf; }});
894            0x5: ldc1({{ EA = Rs + disp; }},{{ Ft<63:0> = Mem.df; }});
895        }
896    }
897
898    0x7: decode OPCODE_LO default FailUnimpl::reserved() {
899        0x0: WarnUnimpl::sc();
900
901        format Memory {
902            0x1: swc1({{ EA = Rs + disp; }},{{ Mem.uf = Ft<31:0>; }});
903            0x5: sdc1({{ EA = Rs + disp; }},{{ Mem.df = Ft<63:0>; }});
904        }
905
906    }
907}
908
909
910