decoder.isa revision 2239
111988Sandreas.sandberg@arm.com// -*- mode:c++ -*- 211988Sandreas.sandberg@arm.com 311988Sandreas.sandberg@arm.com//////////////////////////////////////////////////////////////////// 411988Sandreas.sandberg@arm.com// 511988Sandreas.sandberg@arm.com// The actual MIPS32 ISA decoder 611988Sandreas.sandberg@arm.com// ----------------------------- 711988Sandreas.sandberg@arm.com// The following instructions are specified in the MIPS32 ISA 811988Sandreas.sandberg@arm.com// Specification. Decoding closely follows the style specified 911988Sandreas.sandberg@arm.com// in the MIPS32 ISAthe specification document starting with Table 1011988Sandreas.sandberg@arm.com// A-2 (document available @ www.mips.com) 1111988Sandreas.sandberg@arm.com// 1211988Sandreas.sandberg@arm.com//@todo: Distinguish "unknown/future" use insts from "reserved" 1311988Sandreas.sandberg@arm.com// ones 1411988Sandreas.sandberg@arm.comdecode OPCODE_HI default Unknown::unknown() { 1511988Sandreas.sandberg@arm.com 1611988Sandreas.sandberg@arm.com // Derived From ... Table A-2 MIPS32 ISA Manual 1711988Sandreas.sandberg@arm.com 0x0: decode OPCODE_LO { 1811988Sandreas.sandberg@arm.com 1911988Sandreas.sandberg@arm.com 0x0: decode FUNCTION_HI { 2011988Sandreas.sandberg@arm.com 0x0: decode FUNCTION_LO { 2111988Sandreas.sandberg@arm.com 0x1: decode MOVCI { 2211988Sandreas.sandberg@arm.com format BasicOp { 2311988Sandreas.sandberg@arm.com 0: movf({{ if (xc->readMiscReg(FPCR,0) != CC) Rd = Rs}}); 2411988Sandreas.sandberg@arm.com 1: movt({{ if (xc->readMiscReg(FPCR,0) == CC) Rd = Rs}}); 2511988Sandreas.sandberg@arm.com } 2611988Sandreas.sandberg@arm.com } 2711988Sandreas.sandberg@arm.com 2811988Sandreas.sandberg@arm.com format BasicOp { 2911988Sandreas.sandberg@arm.com 3011988Sandreas.sandberg@arm.com //Table A-3 Note: "1. Specific encodings of the rt, rd, and sa fields 3111988Sandreas.sandberg@arm.com //are used to distinguish among the SLL, NOP, SSNOP and EHB functions." 3211988Sandreas.sandberg@arm.com 3311988Sandreas.sandberg@arm.com 0x0: sll({{ Rd = Rt.uw << SA; }}); 3411988Sandreas.sandberg@arm.com 3511988Sandreas.sandberg@arm.com 0x2: decode SRL { 3611988Sandreas.sandberg@arm.com 0: srl({{ Rd = Rt.uw >> SA; }}); 3711988Sandreas.sandberg@arm.com 3811988Sandreas.sandberg@arm.com //Hardcoded assuming 32-bit ISA, probably need parameter here 3911988Sandreas.sandberg@arm.com 1: rotr({{ Rd = (Rt.uw << (32 - SA)) | (Rt.uw >> SA);}}); 4011988Sandreas.sandberg@arm.com } 4111988Sandreas.sandberg@arm.com 4211988Sandreas.sandberg@arm.com 0x3: sra({{ Rd = Rt.sw >> SA; }}); 4311988Sandreas.sandberg@arm.com 4411988Sandreas.sandberg@arm.com 0x4: sllv({{ Rd = Rt.uw << Rs<4:0>; }}); 4511988Sandreas.sandberg@arm.com 4611988Sandreas.sandberg@arm.com 0x6: decode SRLV { 4711988Sandreas.sandberg@arm.com 0: srlv({{ Rd = Rt.uw >> Rs<4:0>; }}); 4811988Sandreas.sandberg@arm.com 4911988Sandreas.sandberg@arm.com //Hardcoded assuming 32-bit ISA, probably need parameter here 5011988Sandreas.sandberg@arm.com 1: rotrv({{ Rd = (Rt.uw << (32 - Rs<4:0>)) | (Rt.uw >> Rs<4:0>);}}); 5111988Sandreas.sandberg@arm.com } 5211988Sandreas.sandberg@arm.com 5311988Sandreas.sandberg@arm.com 0x7: srav({{ Rd = Rt.sw >> Rs<4:0>; }}); 5411988Sandreas.sandberg@arm.com } 5511988Sandreas.sandberg@arm.com } 5611988Sandreas.sandberg@arm.com 5711988Sandreas.sandberg@arm.com 0x1: decode FUNCTION_LO { 5811988Sandreas.sandberg@arm.com 5911988Sandreas.sandberg@arm.com //Table A-3 Note: "Specific encodings of the hint field are used 6011988Sandreas.sandberg@arm.com //to distinguish JR from JR.HB and JALR from JALR.HB" 6111988Sandreas.sandberg@arm.com format Jump { 6211988Sandreas.sandberg@arm.com 0x0: decode HINT { 6311988Sandreas.sandberg@arm.com 0:jr({{ NNPC = Rs & ~1; }},IsReturn); 6411988Sandreas.sandberg@arm.com 6511988Sandreas.sandberg@arm.com 1:jr_hb({{ NNPC = Rs & ~1; clear_exe_inst_hazards(); }},IsReturn); 6611988Sandreas.sandberg@arm.com } 6711988Sandreas.sandberg@arm.com 6811988Sandreas.sandberg@arm.com 0x1: decode HINT { 6911988Sandreas.sandberg@arm.com 0: jalr({{ NNPC = Rs; }},IsCall,IsReturn); 7011988Sandreas.sandberg@arm.com 7111988Sandreas.sandberg@arm.com 1: jalr_hb({{ NNPC = Rs; clear_exe_inst_hazards();}},IsCall,IsReturn); 7211988Sandreas.sandberg@arm.com } 7311988Sandreas.sandberg@arm.com } 7411988Sandreas.sandberg@arm.com 7511988Sandreas.sandberg@arm.com format BasicOp { 7611988Sandreas.sandberg@arm.com 0x2: movz({{ if (Rt == 0) Rd = Rs; }}); 7711988Sandreas.sandberg@arm.com 0x3: movn({{ if (Rt != 0) Rd = Rs; }}); 7811988Sandreas.sandberg@arm.com } 7911988Sandreas.sandberg@arm.com 8011988Sandreas.sandberg@arm.com format WarnUnimpl { 8111988Sandreas.sandberg@arm.com 0x4: syscall();//{{ xc->syscall()}},IsNonSpeculative 8211988Sandreas.sandberg@arm.com 0x5: break(); 8311988Sandreas.sandberg@arm.com 0x7: sync(); 8411988Sandreas.sandberg@arm.com } 8511988Sandreas.sandberg@arm.com } 8611988Sandreas.sandberg@arm.com 8711988Sandreas.sandberg@arm.com 0x2: decode FUNCTION_LO { 8811988Sandreas.sandberg@arm.com format BasicOp { 8911988Sandreas.sandberg@arm.com 0x0: mfhi({{ Rd = xc->readMiscReg(Hi,0); }}); 9011988Sandreas.sandberg@arm.com 0x1: mthi({{ xc->setMiscReg(Hi,0,Rs); }}); 9111988Sandreas.sandberg@arm.com 0x2: mflo({{ Rd = xc->readMiscReg(Lo,0); }}); 9211988Sandreas.sandberg@arm.com 0x3: mtlo({{ xc->setMiscReg(Lo,0,Rs); }}); 9311988Sandreas.sandberg@arm.com } 9411988Sandreas.sandberg@arm.com } 9511988Sandreas.sandberg@arm.com 9611988Sandreas.sandberg@arm.com 0x3: decode FUNCTION_LO { 9711988Sandreas.sandberg@arm.com format IntOp { 9811988Sandreas.sandberg@arm.com 0x0: mult({{ 9911988Sandreas.sandberg@arm.com int64_t temp1 = Rs.sw * Rt.sw; 10011988Sandreas.sandberg@arm.com xc->setMiscReg(Hi,0,temp1<63:32>); 10111988Sandreas.sandberg@arm.com xc->setMiscReg(Lo,0,temp1<31:0>); 10211988Sandreas.sandberg@arm.com }}); 10311988Sandreas.sandberg@arm.com 10411988Sandreas.sandberg@arm.com 0x1: multu({{ 10511988Sandreas.sandberg@arm.com int64_t temp1 = Rs.uw * Rt.uw; 10611988Sandreas.sandberg@arm.com xc->setMiscReg(Hi,0,temp1<63:32>); 10711988Sandreas.sandberg@arm.com xc->setMiscReg(Lo,0,temp1<31:0>); 10811988Sandreas.sandberg@arm.com }}); 10911988Sandreas.sandberg@arm.com 11011988Sandreas.sandberg@arm.com 0x2: div({{ 11111988Sandreas.sandberg@arm.com xc->setMiscReg(Hi,0,Rs.sw % Rt.sw); 11211988Sandreas.sandberg@arm.com xc->setMiscReg(Lo,0,Rs.sw / Rt.sw); 11311988Sandreas.sandberg@arm.com }}); 11411988Sandreas.sandberg@arm.com 11511988Sandreas.sandberg@arm.com 0x3: divu({{ 11611988Sandreas.sandberg@arm.com xc->setMiscReg(Hi,0,Rs.uw % Rt.uw); 11711988Sandreas.sandberg@arm.com xc->setMiscReg(Lo,0,Rs.uw / Rt.uw); 11811988Sandreas.sandberg@arm.com }}); 11911988Sandreas.sandberg@arm.com } 12011988Sandreas.sandberg@arm.com } 12111988Sandreas.sandberg@arm.com 12211988Sandreas.sandberg@arm.com 0x4: decode FUNCTION_LO { 12311988Sandreas.sandberg@arm.com format IntOp { 12411988Sandreas.sandberg@arm.com 0x0: add({{ Rd.sw = Rs.sw + Rt.sw;/*Trap on Overflow*/}}); 12511988Sandreas.sandberg@arm.com 0x1: addu({{ Rd.sw = Rs.sw + Rt.sw;}}); 12611988Sandreas.sandberg@arm.com 0x2: sub({{ Rd.sw = Rs.sw - Rt.sw; /*Trap on Overflow*/}}); 12711988Sandreas.sandberg@arm.com 0x3: subu({{ Rd.sw = Rs.sw - Rt.uw;}}); 12811988Sandreas.sandberg@arm.com 0x4: and({{ Rd = Rs & Rt;}}); 12911988Sandreas.sandberg@arm.com 0x5: or({{ Rd = Rs | Rt;}}); 13011988Sandreas.sandberg@arm.com 0x6: xor({{ Rd = Rs ^ Rt;}}); 13111988Sandreas.sandberg@arm.com 0x7: nor({{ Rd = ~(Rs | Rt);}}); 13211988Sandreas.sandberg@arm.com } 13311988Sandreas.sandberg@arm.com } 13411988Sandreas.sandberg@arm.com 13511988Sandreas.sandberg@arm.com 0x5: decode FUNCTION_LO { 13611988Sandreas.sandberg@arm.com format IntOp{ 13711988Sandreas.sandberg@arm.com 0x2: slt({{ Rd.sw = ( Rs.sw < Rt.sw ) ? 1 : 0}}); 13811988Sandreas.sandberg@arm.com 0x3: sltu({{ Rd.uw = ( Rs.uw < Rt.uw ) ? 1 : 0}}); 13911988Sandreas.sandberg@arm.com } 14011988Sandreas.sandberg@arm.com } 14111988Sandreas.sandberg@arm.com 14211988Sandreas.sandberg@arm.com 0x6: decode FUNCTION_LO { 14311988Sandreas.sandberg@arm.com format Trap { 14411988Sandreas.sandberg@arm.com 0x0: tge({{ cond = (Rs.sw >= Rt.sw); }}); 14511988Sandreas.sandberg@arm.com 0x1: tgeu({{ cond = (Rs.uw >= Rt.uw); }}); 14611988Sandreas.sandberg@arm.com 0x2: tlt({{ cond = (Rs.sw < Rt.sw); }}); 14711988Sandreas.sandberg@arm.com 0x3: tltu({{ cond = (Rs.uw >= Rt.uw); }}); 14811988Sandreas.sandberg@arm.com 0x4: teq({{ cond = (Rs.sw == Rt.sw); }}); 14911988Sandreas.sandberg@arm.com 0x6: tne({{ cond = (Rs.sw != Rt.sw); }}); 15011988Sandreas.sandberg@arm.com } 15111988Sandreas.sandberg@arm.com } 15211988Sandreas.sandberg@arm.com } 15311988Sandreas.sandberg@arm.com 15411988Sandreas.sandberg@arm.com 0x1: decode REGIMM_HI { 15511988Sandreas.sandberg@arm.com 0x0: decode REGIMM_LO { 15611988Sandreas.sandberg@arm.com format Branch { 15711988Sandreas.sandberg@arm.com 0x0: bltz({{ cond = (Rs.sw < 0); }}); 15811988Sandreas.sandberg@arm.com 0x1: bgez({{ cond = (Rs.sw >= 0); }}); 15911988Sandreas.sandberg@arm.com } 16011988Sandreas.sandberg@arm.com 16111988Sandreas.sandberg@arm.com format BranchLikely { 16211988Sandreas.sandberg@arm.com //MIPS obsolete instructions 16311988Sandreas.sandberg@arm.com 0x2: bltzl({{ cond = (Rs.sw < 0); }}); 16411988Sandreas.sandberg@arm.com 0x3: bgezl({{ cond = (Rs.sw >= 0); }}); 16511988Sandreas.sandberg@arm.com } 16611988Sandreas.sandberg@arm.com } 16711988Sandreas.sandberg@arm.com 16811988Sandreas.sandberg@arm.com 0x1: decode REGIMM_LO { 16911988Sandreas.sandberg@arm.com format Trap { 17011988Sandreas.sandberg@arm.com 0x0: tgei( {{ cond = (Rs.sw >= INTIMM); }}); 17111988Sandreas.sandberg@arm.com 0x1: tgeiu({{ cond = (Rs.uw >= INTIMM); }}); 17211988Sandreas.sandberg@arm.com 0x2: tlti( {{ cond = (Rs.sw < INTIMM); }}); 17311988Sandreas.sandberg@arm.com 0x3: tltiu({{ cond = (Rs.uw < INTIMM); }}); 17411988Sandreas.sandberg@arm.com 0x4: teqi( {{ cond = (Rs.sw == INTIMM);}}); 17511988Sandreas.sandberg@arm.com 0x6: tnei( {{ cond = (Rs.sw != INTIMM);}}); 17611988Sandreas.sandberg@arm.com } 17711988Sandreas.sandberg@arm.com } 17811988Sandreas.sandberg@arm.com 17911988Sandreas.sandberg@arm.com 0x2: decode REGIMM_LO { 18011988Sandreas.sandberg@arm.com format Branch { 18111988Sandreas.sandberg@arm.com 0x0: bltzal({{ cond = (Rs.sw < 0); }}, IsCall,IsReturn); 18211988Sandreas.sandberg@arm.com 0x1: bgezal({{ cond = (Rs.sw >= 0); }}, IsCall,IsReturn); 18311988Sandreas.sandberg@arm.com } 18411988Sandreas.sandberg@arm.com 18511988Sandreas.sandberg@arm.com format BranchLikely { 18611988Sandreas.sandberg@arm.com //Will be removed in future MIPS releases 18711988Sandreas.sandberg@arm.com 0x2: bltzall({{ cond = (Rs.sw < 0); }}, IsCall, IsReturn); 18811988Sandreas.sandberg@arm.com 0x3: bgezall({{ cond = (Rs.sw >= 0); }}, IsCall, IsReturn); 18911988Sandreas.sandberg@arm.com } 19011988Sandreas.sandberg@arm.com } 19111988Sandreas.sandberg@arm.com 19211988Sandreas.sandberg@arm.com 0x3: decode REGIMM_LO { 19311988Sandreas.sandberg@arm.com format WarnUnimpl { 19411988Sandreas.sandberg@arm.com 0x7: synci(); 19511988Sandreas.sandberg@arm.com } 19611988Sandreas.sandberg@arm.com } 19711988Sandreas.sandberg@arm.com } 19811988Sandreas.sandberg@arm.com 19911988Sandreas.sandberg@arm.com format Jump { 20011988Sandreas.sandberg@arm.com 0x2: j({{ NNPC = (NPC & 0xF0000000) | (JMPTARG << 2);}}); 20111988Sandreas.sandberg@arm.com 20211988Sandreas.sandberg@arm.com 0x3: jal({{ NNPC = (NPC & 0xF0000000) | (JMPTARG << 2); }},IsCall,IsReturn); 20311988Sandreas.sandberg@arm.com } 20411988Sandreas.sandberg@arm.com 20511988Sandreas.sandberg@arm.com format Branch { 20611988Sandreas.sandberg@arm.com 0x4: beq({{ cond = (Rs.sw == Rt.sw); }}); 20711988Sandreas.sandberg@arm.com 0x5: bne({{ cond = (Rs.sw != Rt.sw); }}); 20811988Sandreas.sandberg@arm.com 0x6: blez({{ cond = (Rs.sw <= 0); }}); 20911988Sandreas.sandberg@arm.com 0x7: bgtz({{ cond = (Rs.sw > 0); }}); 21011988Sandreas.sandberg@arm.com } 21111988Sandreas.sandberg@arm.com } 21211988Sandreas.sandberg@arm.com 21311988Sandreas.sandberg@arm.com 0x1: decode OPCODE_LO { 21411988Sandreas.sandberg@arm.com format IntOp { 21511988Sandreas.sandberg@arm.com 0x0: addi({{ Rt.sw = Rs.sw + imm; /*Trap If Overflow*/}}); 21611988Sandreas.sandberg@arm.com 0x1: addiu({{ Rt.sw = Rs.sw + imm;}}); 21711988Sandreas.sandberg@arm.com 0x2: slti({{ Rt.sw = ( Rs.sw < imm) ? 1 : 0 }}); 21811988Sandreas.sandberg@arm.com 0x3: sltiu({{ Rt.sw = ( Rs.sw < imm ) ? 1 : 0 }}); 21911988Sandreas.sandberg@arm.com 0x4: andi({{ Rt.sw = Rs.sw & INTIMM;}}); 22011988Sandreas.sandberg@arm.com 0x5: ori({{ Rt.sw = Rs.sw | INTIMM;}}); 22111988Sandreas.sandberg@arm.com 0x6: xori({{ Rt.sw = Rs.sw ^ INTIMM;}}); 22211988Sandreas.sandberg@arm.com 0x7: lui({{ Rt = INTIMM << 16}}); 22311988Sandreas.sandberg@arm.com } 22411988Sandreas.sandberg@arm.com } 22511988Sandreas.sandberg@arm.com 22611988Sandreas.sandberg@arm.com 0x2: decode OPCODE_LO { 22711988Sandreas.sandberg@arm.com 22811988Sandreas.sandberg@arm.com //Table A-11 MIPS32 COP0 Encoding of rs Field 22911988Sandreas.sandberg@arm.com 0x0: decode RS_MSB { 23011988Sandreas.sandberg@arm.com 0x0: decode RS { 23111988Sandreas.sandberg@arm.com format System { 23211988Sandreas.sandberg@arm.com 0x0: mfc0({{ 23311988Sandreas.sandberg@arm.com //uint64_t reg_num = Rd.uw; 23411988Sandreas.sandberg@arm.com 23511988Sandreas.sandberg@arm.com Rt = xc->readMiscReg(RD,SEL); 23611988Sandreas.sandberg@arm.com }}); 23712011Sgabeblack@google.com 23811988Sandreas.sandberg@arm.com 0x4: mtc0({{ 23911988Sandreas.sandberg@arm.com //uint64_t reg_num = Rd.uw; 24011988Sandreas.sandberg@arm.com 24111988Sandreas.sandberg@arm.com xc->setMiscReg(RD,SEL,Rt); 24211988Sandreas.sandberg@arm.com }}); 24311988Sandreas.sandberg@arm.com 24411988Sandreas.sandberg@arm.com 0x8: mftr({{ 24511988Sandreas.sandberg@arm.com //The contents of the coprocessor 0 register specified by the 24611988Sandreas.sandberg@arm.com //combination of rd and sel are loaded into general register 24711988Sandreas.sandberg@arm.com //rt. Note that not all coprocessor 0 registers support the 24811988Sandreas.sandberg@arm.com //sel field. In those instances, the sel field must be zero. 24911988Sandreas.sandberg@arm.com 25011988Sandreas.sandberg@arm.com //MT Code Needed Here 25111988Sandreas.sandberg@arm.com }}); 25211988Sandreas.sandberg@arm.com 25311988Sandreas.sandberg@arm.com 0xC: mttr({{ 25411988Sandreas.sandberg@arm.com //The contents of the coprocessor 0 register specified by the 25511988Sandreas.sandberg@arm.com //combination of rd and sel are loaded into general register 25611988Sandreas.sandberg@arm.com //rt. Note that not all coprocessor 0 registers support the 25711988Sandreas.sandberg@arm.com //sel field. In those instances, the sel field must be zero. 25811988Sandreas.sandberg@arm.com 25911988Sandreas.sandberg@arm.com //MT Code Needed Here 26011988Sandreas.sandberg@arm.com }}); 26111988Sandreas.sandberg@arm.com 26211988Sandreas.sandberg@arm.com 26311988Sandreas.sandberg@arm.com 0xA: rdpgpr({{ 26411988Sandreas.sandberg@arm.com //Accessing Previous Shadow Set Register Number 26511988Sandreas.sandberg@arm.com //uint64_t prev = xc->readMiscReg(SRSCtl)/*[PSS]*/; 26611988Sandreas.sandberg@arm.com //uint64_t reg_num = Rt.uw; 26711988Sandreas.sandberg@arm.com 26811988Sandreas.sandberg@arm.com //Rd = xc->regs.IntRegFile[prev]; 26911988Sandreas.sandberg@arm.com //Rd = xc->shadowIntRegFile[prev][reg_num]; 27011988Sandreas.sandberg@arm.com }}); 27111988Sandreas.sandberg@arm.com 27211988Sandreas.sandberg@arm.com 0xB: decode RD { 27311988Sandreas.sandberg@arm.com 274 0x0: decode SC { 275 0x0: dvpe({{ 276 int idx; 277 int sel; 278 getMiscRegIdx(MVPControl,idx,sel); 279 Rt.sw = xc->readMiscReg(idx,sel); 280 xc->setMiscReg(idx,sel,0); 281 }}); 282 283 0x1: evpe({{ 284 int idx; 285 int sel; 286 getMiscRegIdx(MVPControl,idx,sel); 287 Rt.sw = xc->readMiscReg(idx,sel); 288 xc->setMiscReg(idx,sel,1); 289 }}); 290 } 291 292 0x1: decode SC { 293 0x0: dmt({{ 294 int idx; 295 int sel; 296 getMiscRegIdx(VPEControl,idx,sel); 297 Rt.sw = xc->readMiscReg(idx,sel); 298 xc->setMiscReg(idx,sel,0); 299 }}); 300 301 0x1: emt({{ 302 int idx; 303 int sel; 304 getMiscRegIdx(VPEControl,idx,sel); 305 Rt.sw = xc->readMiscReg(idx,sel); 306 xc->setMiscReg(idx,sel,1); 307 }}); 308 } 309 310 0xC: decode SC { 311 0x0: di({{ 312 int idx; 313 int sel; 314 getMiscRegIdx(Status,idx,sel); 315 Rt.sw = xc->readMiscReg(idx,sel); 316 xc->setMiscReg(idx,sel,0); 317 }}); 318 319 0x1: ei({{ 320 int idx; 321 int sel; 322 getMiscRegIdx(Status,idx,sel); 323 Rt.sw = xc->readMiscReg(idx,sel); 324 xc->setMiscReg(idx,sel,1); 325 }}); 326 } 327 } 328 329 0xE: wrpgpr({{ 330 //Accessing Previous Shadow Set Register Number 331 //uint64_t prev = xc->readMiscReg(SRSCtl/*[PSS]*/); 332 //uint64_t reg_num = Rd.uw; 333 334 //xc->regs.IntRegFile[prev]; 335 //xc->shadowIntRegFile[prev][reg_num] = Rt; 336 }}); 337 } 338 } 339 340 //Table A-12 MIPS32 COP0 Encoding of Function Field When rs=CO 341 0x1: decode FUNCTION { 342 format System { 343 0x01: tlbr({{ }}); 344 0x02: tlbwi({{ }}); 345 0x06: tlbwr({{ }}); 346 0x08: tlbp({{ }}); 347 } 348 349 format WarnUnimpl { 350 0x18: eret(); 351 0x1F: deret(); 352 0x20: wait(); 353 } 354 } 355 } 356 357 //Table A-13 MIPS32 COP1 Encoding of rs Field 358 0x1: decode RS_MSB { 359 360 0x0: decode RS_HI { 361 0x0: decode RS_LO { 362 format FloatOp { 363 0x0: mfc1({{ /*Rt.uw = Fs.ud<31:0>;*/ }}); 364 0x2: cfc1({{ /*Rt.uw = xc->readMiscReg(FPCR[Fs]);*/}}); 365 0x3: mfhc1({{ /*Rt.uw = Fs.ud<63:32>*/;}}); 366 0x4: mtc1({{ /*Fs = Rt.uw*/}}); 367 0x6: ctc1({{ /*xc->setMiscReg(FPCR[Fs],Rt);*/}}); 368 0x7: mthc1({{ /*Fs<63:32> = Rt.uw*/}}); 369 } 370 } 371 372 0x1: decode ND { 373 0x0: decode TF { 374 format Branch { 375 0x0: bc1f({{ cond = (xc->readMiscReg(FPCR,0) == 0); }}); 376 0x1: bc1t({{ cond = (xc->readMiscReg(FPCR,0) == 1); }}); 377 } 378 } 379 380 0x1: decode TF { 381 format BranchLikely { 382 0x0: bc1fl({{ cond = (xc->readMiscReg(FPCR,0) == 0); }}); 383 0x1: bc1tl({{ cond = (xc->readMiscReg(FPCR,0) == 1); }}); 384 } 385 } 386 } 387 } 388 389 0x1: decode RS_HI { 390 0x2: decode RS_LO { 391 392 //Table A-14 MIPS32 COP1 Encoding of Function Field When rs=S 393 //(( single-word )) 394 0x0: decode RS_HI { 395 0x0: decode RS_LO { 396 format FloatOp { 397 0x0: adds({{ Fd.sf = Fs.sf + Ft.sf;}}); 398 0x1: subs({{ Fd.sf = Fs.sf - Ft.sf;}}); 399 0x2: muls({{ Fd.sf = Fs.sf * Ft.sf;}}); 400 0x3: divs({{ Fd.sf = Fs.sf / Ft.sf;}}); 401 0x4: sqrts({{ Fd.sf = sqrt(Fs.sf);}}); 402 0x5: abss({{ Fd.sf = fabs(Fs.sf);}}); 403 0x6: movs({{ Fd.sf = Fs.sf;}}); 404 0x7: negs({{ Fd.sf = -1 * Fs.sf;}}); 405 } 406 } 407 408 0x1: decode RS_LO { 409 //only legal for 64 bit-FP 410 format Float64Op { 411 0x0: round_l_s({{ Fd = convert_and_round(Fs.sf,RND_NEAREST,FP_LONG,FP_SINGLE);}}); 412 0x1: trunc_l_s({{ Fd = convert_and_round(Fs.sf,RND_ZERO,FP_LONG,FP_SINGLE);}}); 413 0x2: ceil_l_s({{ Fd = convert_and_round(Fs.sf,RND_UP,FP_LONG,FP_SINGLE);}}); 414 0x3: floor_l_s({{ Fd = convert_and_round(Fs.sf,RND_DOWN,FP_LONG,FP_SINGLE);}}); 415 } 416 417 format FloatOp { 418 0x4: round_w_s({{ Fd = convert_and_round(Fs.sf,RND_NEAREST,FP_WORD,FP_SINGLE);}}); 419 0x5: trunc_w_s({{ Fd = convert_and_round(Fs.sf,RND_ZERO,FP_WORD,FP_SINGLE);}}); 420 0x6: ceil_w_s({{ Fd = convert_and_round(Fs.sf,RND_UP,FP_WORD,FP_SINGLE);}}); 421 0x7: floor_w_s({{ Fd = convert_and_round(Fs.sf,RND_DOWN,FP_WORD,FP_SINGLE);}}); 422 } 423 } 424 425 0x2: decode RS_LO { 426 0x1: decode MOVCF { 427 format FloatOp { 428 0x0: movfs({{if (xc->readMiscReg(FPCR,0) != CC) Fd = Fs; }}); 429 0x1: movts({{if (xc->readMiscReg(FPCR,0) == CC) Fd = Fs;}}); 430 } 431 } 432 433 format BasicOp { 434 0x2: movzs({{ if (Rt == 0) Fd = Fs; }}); 435 0x3: movns({{ if (Rt != 0) Fd = Fs; }}); 436 } 437 438 format Float64Op { 439 0x5: recips({{ Fd = 1 / Fs; }}); 440 0x6: rsqrts({{ Fd = 1 / sqrt((double)Fs.ud);}}); 441 } 442 } 443 444 0x4: decode RS_LO { 445 446 format FloatOp { 447 0x1: cvt_d_s({{ int rnd_mode = xc->readMiscReg(FCSR,0); 448 Fd = convert_and_round(Fs.sf,rnd_mode,FP_DOUBLE,FP_SINGLE); 449 }}); 450 451 0x4: cvt_w_s({{ int rnd_mode = xc->readMiscReg(FCSR,0); 452 Fd = convert_and_round(Fs.sf,rnd_mode,FP_WORD,FP_SINGLE); 453 }}); 454 } 455 456 //only legal for 64 bit 457 format Float64Op { 458 0x5: cvt_l_s({{ int rnd_mode = xc->readMiscReg(FCSR,0); 459 Fd = convert_and_round(Fs.sf,rnd_mode,FP_LONG,FP_SINGLE); 460 }}); 461 462 0x6: cvt_ps_s({{ /*Fd.df = Fs.df<31:0> | Ft.df<31:0>;*/ }}); 463 } 464 } 465 } 466 467 //Table A-15 MIPS32 COP1 Encoding of Function Field When rs=D 468 0x1: decode RS_HI { 469 0x0: decode RS_LO { 470 format FloatOp { 471 0x0: addd({{ Fd.df = Fs.df + Ft.df;}}); 472 0x1: subd({{ Fd.df = Fs.df - Ft.df;}}); 473 0x2: muld({{ Fd.df = Fs.df * Ft.df;}}); 474 0x3: divd({{ Fd.df = Fs.df / Ft.df;}}); 475 0x4: sqrtd({{ Fd.df = sqrt(Fs.df);}}); 476 0x5: absd({{ Fd.df = fabs(Fs.df);}}); 477 0x6: movd({{ Fd.df = Fs.df;}}); 478 0x7: negd({{ Fd.df = -1 * Fs.df;}}); 479 } 480 } 481 482 0x1: decode RS_LO { 483 //only legal for 64 bit 484 format Float64Op { 485 0x0: round_l_d({{ Fd = convert_and_round(Fs.df,RND_NEAREST,FP_LONG,FP_DOUBLE); }}); 486 0x1: trunc_l_d({{ Fd = convert_and_round(Fs.df,RND_ZERO,FP_LONG,FP_DOUBLE);}}); 487 0x2: ceil_l_d({{ Fd = convert_and_round(Fs.df,RND_UP,FP_LONG,FP_DOUBLE);}}); 488 0x3: floor_l_d({{ Fd = convert_and_round(Fs.df,RND_DOWN,FP_LONG,FP_DOUBLE);}}); 489 } 490 491 format FloatOp { 492 0x4: round_w_d({{ Fd = convert_and_round(Fs.df,RND_NEAREST,FP_LONG,FP_DOUBLE); }}); 493 0x5: trunc_w_d({{ Fd = convert_and_round(Fs.df,RND_ZERO,FP_LONG,FP_DOUBLE); }}); 494 0x6: ceil_w_d({{ Fd = convert_and_round(Fs.df,RND_UP,FP_LONG,FP_DOUBLE); }}); 495 0x7: floor_w_d({{ Fd = convert_and_round(Fs.df,RND_DOWN,FP_LONG,FP_DOUBLE); }}); 496 } 497 } 498 499 0x2: decode RS_LO { 500 0x1: decode MOVCF { 501 format FloatOp { 502 0x0: movfd({{if (xc->readMiscReg(FPCR,0) != CC) Fd.df = Fs.df; }}); 503 0x1: movtd({{if (xc->readMiscReg(FPCR,0) == CC) Fd.df = Fs.df; }}); 504 } 505 } 506 507 format BasicOp { 508 0x2: movzd({{ if (Rt == 0) Fd.df = Fs.df; }}); 509 0x3: movnd({{ if (Rt != 0) Fd.df = Fs.df; }}); 510 } 511 512 format Float64Op { 513 0x5: recipd({{ Fd.df = 1 / Fs.df}}); 514 0x6: rsqrtd({{ Fd.df = 1 / sqrt(Fs.df) }}); 515 } 516 } 517 518 0x4: decode RS_LO { 519 format FloatOp { 520 0x0: cvt_s_d({{ 521 int rnd_mode = xc->readMiscReg(FCSR,0); 522 Fd = convert_and_round(Fs.df,rnd_mode,FP_SINGLE,FP_DOUBLE); 523 }}); 524 525 0x4: cvt_w_d({{ 526 int rnd_mode = xc->readMiscReg(FCSR,0); 527 Fd = convert_and_round(Fs.df,rnd_mode,FP_WORD,FP_DOUBLE); 528 }}); 529 } 530 531 //only legal for 64 bit 532 format Float64Op { 533 0x5: cvt_l_d({{ 534 int rnd_mode = xc->readMiscReg(FCSR,0); 535 Fd = convert_and_round(Fs.df,rnd_mode,FP_LONG,FP_DOUBLE); 536 }}); 537 } 538 } 539 } 540 541 //Table A-16 MIPS32 COP1 Encoding of Function Field When rs=W 542 0x4: decode FUNCTION { 543 format FloatOp { 544 0x20: cvt_s({{ 545 int rnd_mode = xc->readMiscReg(FCSR,0); 546 Fd = convert_and_round(Fs.df,rnd_mode,FP_SINGLE,FP_WORD); 547 }}); 548 549 0x21: cvt_d({{ 550 int rnd_mode = xc->readMiscReg(FCSR,0); 551 Fd = convert_and_round(Fs.df,rnd_mode,FP_DOUBLE,FP_WORD); 552 }}); 553 } 554 } 555 556 //Table A-16 MIPS32 COP1 Encoding of Function Field When rs=L1 557 //Note: "1. Format type L is legal only if 64-bit floating point operations 558 //are enabled." 559 0x5: decode FUNCTION_HI { 560 format FloatOp { 561 0x10: cvt_s_l({{ 562 int rnd_mode = xc->readMiscReg(FCSR,0); 563 Fd = convert_and_round(Fs.df,rnd_mode,FP_SINGLE,FP_LONG); 564 }}); 565 566 0x11: cvt_d_l({{ 567 int rnd_mode = xc->readMiscReg(FCSR,0); 568 Fd = convert_and_round(Fs.df,rnd_mode,FP_DOUBLE,FP_LONG); 569 }}); 570 } 571 } 572 573 //Table A-17 MIPS64 COP1 Encoding of Function Field When rs=PS1 574 //Note: "1. Format type PS is legal only if 64-bit floating point operations 575 //are enabled. " 576 0x6: decode RS_HI { 577 0x0: decode RS_LO { 578 format Float64Op { 579 0x0: addps({{ //Must Check for Exception Here... Supposed to Operate on Upper and 580 //Lower Halves Independently but we take simulator shortcut 581 Fd.df = Fs.df + Ft.df; 582 }}); 583 584 0x1: subps({{ //Must Check for Exception Here... Supposed to Operate on Upper and 585 //Lower Halves Independently but we take simulator shortcut 586 Fd.df = Fs.df - Ft.df; 587 }}); 588 589 0x2: mulps({{ //Must Check for Exception Here... Supposed to Operate on Upper and 590 //Lower Halves Independently but we take simulator shortcut 591 Fd.df = Fs.df * Ft.df; 592 }}); 593 594 0x5: absps({{ //Must Check for Exception Here... Supposed to Operate on Upper and 595 //Lower Halves Independently but we take simulator shortcut 596 Fd.df = fabs(Fs.df); 597 }}); 598 599 0x6: movps({{ //Must Check for Exception Here... Supposed to Operate on Upper and 600 //Lower Halves Independently but we take simulator shortcut 601 //Fd.df = Fs<31:0> | Ft<31:0>; 602 }}); 603 604 0x7: negps({{ //Must Check for Exception Here... Supposed to Operate on Upper and 605 //Lower Halves Independently but we take simulator shortcut 606 Fd.df = -1 * Fs.df; 607 }}); 608 } 609 } 610 611 0x2: decode RS_LO { 612 0x1: decode MOVCF { 613 format Float64Op { 614 0x0: movfps({{if (xc->readMiscReg(FPCR,0) != CC) Fd = Fs;}}); 615 0x1: movtps({{if (xc->readMiscReg(FPCR,0) == CC) Fd = Fs;}}); 616 } 617 } 618 619 format BasicOp { 620 0x2: movzps({{if (xc->readMiscReg(FPCR,0) != CC) Fd = Fs; }}); 621 0x3: movnps({{if (xc->readMiscReg(FPCR,0) == CC) Fd = Fs; }}); 622 } 623 624 } 625 626 0x4: decode RS_LO { 627 0x0: Float64Op::cvt_s_pu({{ 628 int rnd_mode = xc->readMiscReg(FCSR,0); 629 Fd = convert_and_round(Fs.df,rnd_mode,FP_DOUBLE,FP_PS_HI); 630 }}); 631 } 632 633 0x5: decode RS_LO { 634 format Float64Op { 635 0x0: cvt_s_pl({{ 636 int rnd_mode = xc->readMiscReg(FCSR,0); 637 Fd = convert_and_round(Fs.df,rnd_mode,FP_SINGLE,FP_PS_LO); 638 }}); 639 0x4: pll({{ /*Fd.df = Fs<31:0> | Ft<31:0>*/}}); 640 0x5: plu({{ /*Fd.df = Fs<31:0> | Ft<63:32>*/}}); 641 0x6: pul({{ /*Fd.df = Fs<63:32> | Ft<31:0>*/}}); 642 0x7: puu({{ /*Fd.df = Fs<63:32 | Ft<63:32>*/}}); 643 } 644 } 645 } 646 } 647 } 648 } 649 650 //Table A-19 MIPS32 COP2 Encoding of rs Field 651 0x2: decode RS_MSB { 652 0x0: decode RS_HI { 653 0x0: decode RS_LO { 654 format WarnUnimpl { 655 0x0: mfc2(); 656 0x2: cfc2(); 657 0x3: mfhc2(); 658 0x4: mtc2(); 659 0x6: ctc2(); 660 0x7: mftc2(); 661 } 662 } 663 664 0x1: decode ND { 665 0x0: decode TF { 666 format WarnUnimpl { 667 0x0: bc2f(); 668 0x1: bc2t(); 669 } 670 } 671 672 0x1: decode TF { 673 format WarnUnimpl { 674 0x0: bc2fl(); 675 0x1: bc2tl(); 676 } 677 } 678 } 679 } 680 } 681 682 //Table A-20 MIPS64 COP1X Encoding of Function Field 1 683 //Note: "COP1X instructions are legal only if 64-bit floating point 684 //operations are enabled." 685 0x3: decode FUNCTION_HI { 686 0x0: decode FUNCTION_LO { 687 format LoadMemory2 { 688 0x0: lwxc1({{ EA = Rs + Rt; }},{{ /*F_t<31:0> = Mem.sf; */}}); 689 0x1: ldxc1({{ EA = Rs + Rt; }},{{ /*F_t<63:0> = Mem.df;*/ }}); 690 0x5: luxc1({{ //Need to make EA<2:0> = 0 691 EA = Rs + Rt; 692 }}, 693 {{ /*F_t<31:0> = Mem.df; */}}); 694 } 695 } 696 697 0x1: decode FUNCTION_LO { 698 format StoreMemory2 { 699 0x0: swxc1({{ EA = Rs + Rt; }},{{ /*Mem.sf = Ft<31:0>; */}}); 700 0x1: sdxc1({{ EA = Rs + Rt; }},{{ /*Mem.df = Ft<63:0> */}}); 701 0x5: suxc1({{ //Need to make EA<2:0> = 0 702 EA = Rs + Rt; 703 }}, 704 {{ /*Mem.df = F_t<63:0>;*/}}); 705 } 706 707 0x7: WarnUnimpl::prefx(); 708 } 709 710 format FloatOp { 711 0x3: WarnUnimpl::alnv_ps(); 712 713 format BasicOp { 714 0x4: decode FUNCTION_LO { 715 0x0: madd_s({{ Fd.sf = (Fs.sf * Fs.sf) + Fr.sf; }}); 716 0x1: madd_d({{ Fd.df = (Fs.df * Fs.df) + Fr.df; }}); 717 0x6: madd_ps({{ 718 //Must Check for Exception Here... Supposed to Operate on Upper and 719 //Lower Halves Independently but we take simulator shortcut 720 Fd.df = (Fs.df * Fs.df) + Fr.df; 721 }}); 722 } 723 724 0x5: decode FUNCTION_LO { 725 0x0: msub_s({{ Fd.sf = (Fs.sf * Fs.sf) - Fr.sf; }}); 726 0x1: msub_d({{ Fd.df = (Fs.df * Fs.df) - Fr.df; }}); 727 0x6: msub_ps({{ 728 //Must Check for Exception Here... Supposed to Operate on Upper and 729 //Lower Halves Independently but we take simulator shortcut 730 Fd.df = (Fs.df * Fs.df) - Fr.df; 731 }}); 732 } 733 734 0x6: decode FUNCTION_LO { 735 0x0: nmadd_s({{ Fd.sf = (-1 * Fs.sf * Fs.sf) - Fr.sf; }}); 736 0x1: nmadd_d({{ Fd.df = (-1 * Fs.df * Fs.df) + Fr.df; }}); 737 0x6: nmadd_ps({{ 738 //Must Check for Exception Here... Supposed to Operate on Upper and 739 //Lower Halves Independently but we take simulator shortcut 740 Fd.df = (-1 * Fs.df * Fs.df) + Fr.df; 741 }}); 742 } 743 744 0x7: decode FUNCTION_LO { 745 0x0: nmsub_s({{ Fd.sf = (-1 * Fs.sf * Fs.sf) - Fr.sf; }}); 746 0x1: nmsub_d({{ Fd.df = (-1 * Fs.df * Fs.df) - Fr.df; }}); 747 0x6: nmsub_ps({{ 748 //Must Check for Exception Here... Supposed to Operate on Upper and 749 //Lower Halves Independently but we take simulator shortcut 750 Fd.df = (-1 * Fs.df * Fs.df) + Fr.df; 751 }}); 752 } 753 } 754 } 755 } 756 757 //MIPS obsolete instructions 758 format BranchLikely { 759 0x4: beql({{ cond = (Rs.sw == 0); }}); 760 0x5: bnel({{ cond = (Rs.sw != 0); }}); 761 0x6: blezl({{ cond = (Rs.sw <= 0); }}); 762 0x7: bgtzl({{ cond = (Rs.sw > 0); }}); 763 } 764 } 765 766 0x3: decode OPCODE_LO default FailUnimpl::reserved() { 767 768 //Table A-5 MIPS32 SPECIAL2 Encoding of Function Field 769 0x4: decode FUNCTION_HI { 770 771 0x0: decode FUNCTION_LO { 772 format IntOp { 773 0x0: madd({{ 774 int64_t temp1 = xc->readMiscReg(Hi,0) << 32 | xc->readMiscReg(Lo,0) >> 32; 775 temp1 = temp1 + (Rs.sw * Rt.sw); 776 xc->setMiscReg(Hi,0,temp1<63:32>); 777 xc->setMiscReg(Lo,0,temp1<31:0>); 778 }}); 779 780 0x1: maddu({{ 781 int64_t temp1 = xc->readMiscReg(Hi,0) << 32 | xc->readMiscReg(Lo,0) >> 32; 782 temp1 = temp1 + (Rs.uw * Rt.uw); 783 xc->setMiscReg(Hi,0,temp1<63:32>); 784 xc->setMiscReg(Lo,0,temp1<31:0>); 785 }}); 786 787 0x2: mul({{ Rd.sw = Rs.sw * Rt.sw; }}); 788 789 0x4: msub({{ 790 int64_t temp1 = xc->readMiscReg(Hi,0) << 32 | xc->readMiscReg(Lo,0) >> 32; 791 temp1 = temp1 - (Rs.sw * Rt.sw); 792 xc->setMiscReg(Hi,0,temp1<63:32>); 793 xc->setMiscReg(Lo,0,temp1<31:0>); 794 }}); 795 796 0x5: msubu({{ 797 int64_t temp1 = xc->readMiscReg(Hi,0) << 32 | xc->readMiscReg(Lo,0) >> 32; 798 temp1 = temp1 - (Rs.uw * Rt.uw); 799 xc->setMiscReg(Hi,0,temp1<63:32>); 800 xc->setMiscReg(Lo,0,temp1<31:0>); 801 }}); 802 } 803 } 804 805 0x4: decode FUNCTION_LO { 806 format BasicOp { 807 0x0: clz({{ 808 /*int cnt = 0; 809 int idx = 0; 810 while ( Rs.uw<idx> != 1) { 811 cnt++; 812 idx--; 813 } 814 815 Rd.uw = cnt;*/ 816 }}); 817 818 0x1: clo({{ 819 /*int cnt = 0; 820 int idx = 0; 821 while ( Rs.uw<idx> != 0) { 822 cnt++; 823 idx--; 824 } 825 826 Rd.uw = cnt;*/ 827 }}); 828 } 829 } 830 831 0x7: decode FUNCTION_LO { 832 0x7: WarnUnimpl::sdbbp(); 833 } 834 } 835 836 //Table A-6 MIPS32 SPECIAL3 Encoding of Function Field for Release 2 of the Architecture 837 0x7: decode FUNCTION_HI { 838 839 0x0: decode FUNCTION_LO { 840 format WarnUnimpl { 841 0x1: ext(); 842 0x4: ins(); 843 } 844 } 845 846 0x1: decode FUNCTION_LO { 847 format WarnUnimpl { 848 0x0: fork(); 849 0x1: yield(); 850 } 851 } 852 853 854 //Table A-10 MIPS32 BSHFL Encoding of sa Field 855 0x4: decode SA { 856 857 0x02: WarnUnimpl::wsbh(); 858 859 format BasicOp { 860 0x10: seb({{ Rd.sw = /* sext32(Rt<7>,24) | */ Rt<7:0>}}); 861 0x18: seh({{ Rd.sw = /* sext32(Rt<15>,16) | */ Rt<15:0>}}); 862 } 863 } 864 865 0x6: decode FUNCTION_LO { 866 0x7: BasicOp::rdhwr({{ /*Rt = xc->hwRegs[RD];*/ }}); 867 } 868 } 869 } 870 871 0x4: decode OPCODE_LO default FailUnimpl::reserved() { 872 format LoadMemory { 873 0x0: lb({{ Rt.sw = Mem.sb; }}); 874 0x1: lh({{ Rt.sw = Mem.sh; }}); 875 0x2: lwl({{ Rt.sw = Mem.sw; }});//, WordAlign); 876 0x3: lw({{ Rt.sw = Mem.sb; }}); 877 0x4: lbu({{ Rt.uw = Mem.ub; }}); 878 0x5: lhu({{ Rt.uw = Mem.uh; }}); 879 0x6: lwr({{ Rt.uw = Mem.uw; }});//, WordAlign); 880 } 881 882 0x7: FailUnimpl::reserved(); 883 } 884 885 0x5: decode OPCODE_LO default FailUnimpl::reserved() { 886 format StoreMemory { 887 0x0: sb({{ Mem.ub = Rt<7:0>; }}); 888 0x1: sh({{ Mem.uh = Rt<15:0>; }}); 889 0x2: swl({{ Mem.ub = Rt<31:0>; }});//,WordAlign); 890 0x3: sw({{ Mem.ub = Rt<31:0>; }}); 891 0x6: swr({{ Mem.ub = Rt<31:0>; }});//,WordAlign); 892 } 893 894 format WarnUnimpl { 895 0x7: cache(); 896 } 897 898 } 899 900 0x6: decode OPCODE_LO default FailUnimpl::reserved() { 901 0x0: WarnUnimpl::ll(); 902 903 format LoadMemory { 904 0x1: lwc1({{ /*F_t<31:0> = Mem.sf; */}}); 905 0x5: ldc1({{ /*F_t<63:0> = Mem.df; */}}); 906 } 907 } 908 909 910 0x7: decode OPCODE_LO default FailUnimpl::reserved() { 911 0x0: WarnUnimpl::sc(); 912 913 format StoreMemory { 914 0x1: swc1({{ //Mem.sf = Ft<31:0>; }}); 915 0x5: sdc1({{ //Mem.df = Ft<63:0>; }}); 916 } 917 } 918} 919 920 921