// -*- mode:c++ -*- // Copyright (c) 2009 The University of Edinburgh // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer; // redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution; // neither the name of the copyright holders nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Authors: Timothy M. Jones //////////////////////////////////////////////////////////////////// // // The actual Power ISA decoder // ------------------------------ // // I've used the Power ISA Book I v2.06 for instruction formats, // opcode numbers, register names, etc. // decode OPCODE default Unknown::unknown() { format IntImmOp { 10: cmpli({{ Xer xer = XER; uint32_t cr = makeCRField(Ra, (uint32_t)uimm, xer.so); CR = insertCRField(CR, BF, cr); }}); 11: cmpi({{ Xer xer = XER; uint32_t cr = makeCRField(Ra_sw, (int32_t)imm, xer.so); CR = insertCRField(CR, BF, cr); }}); } // Some instructions use bits 21 - 30, others 22 - 30. We have to use // the larger size to account for all opcodes. For those that use the // smaller value, the OE bit is bit 21. Therefore, we have two versions // of each instruction: 1 with OE set, the other without. For an // example see 'add' and 'addo'. 31: decode XO_XO { // These instructions can all be reduced to the form // Rt = src1 + src2 [+ CA], therefore we just give src1 and src2 // (and, if necessary, CA) definitions and let the python script // deal with setting things up correctly. We also give flags to // say which control registers to set. format IntSumOp { 266: add({{ Ra }}, {{ Rb }}); 40: subf({{ ~Ra }}, {{ Rb }}, {{ 1 }}); 10: addc({{ Ra }}, {{ Rb }}, computeCA = true); 8: subfc({{ ~Ra }}, {{ Rb }}, {{ 1 }}, true); 104: neg({{ ~Ra }}, {{ 1 }}); 138: adde({{ Ra }}, {{ Rb }}, {{ xer.ca }}, true); 234: addme({{ Ra }}, {{ (uint32_t)-1 }}, {{ xer.ca }}, true); 136: subfe({{ ~Ra }}, {{ Rb }}, {{ xer.ca }}, true); 232: subfme({{ ~Ra }}, {{ (uint32_t)-1 }}, {{ xer.ca }}, true); 202: addze({{ Ra }}, {{ xer.ca }}, computeCA = true); 200: subfze({{ ~Ra }}, {{ xer.ca }}, computeCA = true); } // Arithmetic instructions all use source registers Ra and Rb, // with destination register Rt. format IntArithOp { 75: mulhw({{ int64_t prod = Ra_sq * Rb_sq; Rt = prod >> 32; }}); 11: mulhwu({{ uint64_t prod = Ra_uq * Rb_uq; Rt = prod >> 32; }}); 235: mullw({{ int64_t prod = Ra_sq * Rb_sq; Rt = prod; }}); 747: mullwo({{ int64_t src1 = Ra_sq; int64_t src2 = Rb; int64_t prod = src1 * src2; Rt = prod; }}, true); 491: divw({{ int32_t src1 = Ra_sw; int32_t src2 = Rb_sw; if ((src1 != 0x80000000 || src2 != 0xffffffff) && src2 != 0) { Rt = src1 / src2; } else { Rt = 0; } }}); 1003: divwo({{ int32_t src1 = Ra_sw; int32_t src2 = Rb_sw; if ((src1 != 0x80000000 || src2 != 0xffffffff) && src2 != 0) { Rt = src1 / src2; } else { Rt = 0; divSetOV = true; } }}, true); 459: divwu({{ uint32_t src1 = Ra_sw; uint32_t src2 = Rb_sw; if (src2 != 0) { Rt = src1 / src2; } else { Rt = 0; } }}); 971: divwuo({{ uint32_t src1 = Ra_sw; uint32_t src2 = Rb_sw; if (src2 != 0) { Rt = src1 / src2; } else { Rt = 0; divSetOV = true; } }}, true); } // Integer logic instructions use source registers Rs and Rb, // with destination register Ra. format IntLogicOp { 28: and({{ Ra = Rs & Rb; }}); 316: xor({{ Ra = Rs ^ Rb; }}); 476: nand({{ Ra = ~(Rs & Rb); }}); 444: or({{ Ra = Rs | Rb; }}); 124: nor({{ Ra = ~(Rs | Rb); }}); 60: andc({{ Ra = Rs & ~Rb; }}); 954: extsb({{ Ra = sext<8>(Rs); }}); 284: eqv({{ Ra = ~(Rs ^ Rb); }}); 412: orc({{ Ra = Rs | ~Rb; }}); 922: extsh({{ Ra = sext<16>(Rs); }}); 26: cntlzw({{ Ra = Rs == 0 ? 32 : 31 - findMsbSet(Rs); }}); 508: cmpb({{ uint32_t val = 0; for (int n = 0; n < 32; n += 8) { if(bits(Rs, n+7, n) == bits(Rb, n+7, n)) { val = insertBits(val, n+7, n, 0xff); } } Ra = val; }}); 24: slw({{ if (Rb & 0x20) { Ra = 0; } else { Ra = Rs << (Rb & 0x1f); } }}); 536: srw({{ if (Rb & 0x20) { Ra = 0; } else { Ra = Rs >> (Rb & 0x1f); } }}); 792: sraw({{ bool shiftSetCA = false; int32_t s = Rs; if (Rb == 0) { Ra = Rs; shiftSetCA = true; } else if (Rb & 0x20) { if (s < 0) { Ra = (uint32_t)-1; if (s & 0x7fffffff) { shiftSetCA = true; } else { shiftSetCA = false; } } else { Ra = 0; shiftSetCA = false; } } else { Ra = s >> (Rb & 0x1f); if (s < 0 && (s << (32 - (Rb & 0x1f))) != 0) { shiftSetCA = true; } else { shiftSetCA = false; } } Xer xer1 = XER; if (shiftSetCA) { xer1.ca = 1; } else { xer1.ca = 0; } XER = xer1; }}); } // Integer logic instructions with a shift value. format IntShiftOp { 824: srawi({{ bool shiftSetCA = false; if (sh == 0) { Ra = Rs; shiftSetCA = false; } else { int32_t s = Rs; Ra = s >> sh; if (s < 0 && (s << (32 - sh)) != 0) { shiftSetCA = true; } else { shiftSetCA = false; } } Xer xer1 = XER; if (shiftSetCA) { xer1.ca = 1; } else { xer1.ca = 0; } XER = xer1; }}); } // Generic integer format instructions. format IntOp { 0: cmp({{ Xer xer = XER; uint32_t cr = makeCRField(Ra_sw, Rb_sw, xer.so); CR = insertCRField(CR, BF, cr); }}); 32: cmpl({{ Xer xer = XER; uint32_t cr = makeCRField(Ra, Rb, xer.so); CR = insertCRField(CR, BF, cr); }}); 144: mtcrf({{ uint32_t mask = 0; for (int i = 0; i < 8; ++i) { if (((FXM >> i) & 0x1) == 0x1) { mask |= 0xf << (4 * i); } } CR = (Rs & mask) | (CR & ~mask); }}); 19: mfcr({{ Rt = CR; }}); 339: decode SPR { 0x20: mfxer({{ Rt = XER; }}); 0x100: mflr({{ Rt = LR; }}); 0x120: mfctr({{ Rt = CTR; }}); } 467: decode SPR { 0x20: mtxer({{ XER = Rs; }}); 0x100: mtlr({{ LR = Rs; }}); 0x120: mtctr({{ CTR = Rs; }}); } } // All loads with an index register. The non-update versions // all use the value 0 if Ra == R0, not the value contained in // R0. Others update Ra with the effective address. In all cases, // Ra and Rb are source registers, Rt is the destintation. format LoadIndexOp { 87: lbzx({{ Rt = Mem_ub; }}); 279: lhzx({{ Rt = Mem_uh; }}); 343: lhax({{ Rt = Mem_sh; }}); 23: lwzx({{ Rt = Mem; }}); 341: lwax({{ Rt = Mem_sw; }}); 20: lwarx({{ Rt = Mem_sw; Rsv = 1; RsvLen = 4; RsvAddr = EA; }}); 535: lfsx({{ Ft_sf = Mem_sf; }}); 599: lfdx({{ Ft = Mem_df; }}); 855: lfiwax({{ Ft_uw = Mem; }}); } format LoadIndexUpdateOp { 119: lbzux({{ Rt = Mem_ub; }}); 311: lhzux({{ Rt = Mem_uh; }}); 375: lhaux({{ Rt = Mem_sh; }}); 55: lwzux({{ Rt = Mem; }}); 373: lwaux({{ Rt = Mem_sw; }}); 567: lfsux({{ Ft_sf = Mem_sf; }}); 631: lfdux({{ Ft = Mem_df; }}); } format StoreIndexOp { 215: stbx({{ Mem_ub = Rs_ub; }}); 407: sthx({{ Mem_uh = Rs_uh; }}); 151: stwx({{ Mem = Rs; }}); 150: stwcx({{ bool store_performed = false; Mem = Rs; if (Rsv) { if (RsvLen == 4) { if (RsvAddr == EA) { store_performed = true; } } } Xer xer = XER; Cr cr = CR; cr.cr0 = ((store_performed ? 0x2 : 0x0) | xer.so); CR = cr; Rsv = 0; }}); 663: stfsx({{ Mem_sf = Fs_sf; }}); 727: stfdx({{ Mem_df = Fs; }}); 983: stfiwx({{ Mem = Fs_uw; }}); } format StoreIndexUpdateOp { 247: stbux({{ Mem_ub = Rs_ub; }}); 439: sthux({{ Mem_uh = Rs_uh; }}); 183: stwux({{ Mem = Rs; }}); 695: stfsux({{ Mem_sf = Fs_sf; }}); 759: stfdux({{ Mem_df = Fs; }}); } // These instructions all provide data cache hints format MiscOp { 278: dcbt({{ }}); 246: dcbtst({{ }}); 598: sync({{ }}, [ IsMemBarrier ]); 854: eieio({{ }}, [ IsMemBarrier ]); } } format IntImmArithCheckRaOp { 14: addi({{ Rt = Ra + imm; }}, {{ Rt = imm }}); 15: addis({{ Rt = Ra + (imm << 16); }}, {{ Rt = imm << 16; }}); } format IntImmArithOp { 12: addic({{ uint32_t src = Ra; Rt = src + imm; }}, [computeCA]); 13: addic_({{ uint32_t src = Ra; Rt = src + imm; }}, [computeCA, computeCR0]); 8: subfic({{ int32_t src = ~Ra; Rt = src + imm + 1; }}, [computeCA]); 7: mulli({{ int32_t src = Ra_sw; int64_t prod = src * imm; Rt = (uint32_t)prod; }}); } format IntImmLogicOp { 24: ori({{ Ra = Rs | uimm; }}); 25: oris({{ Ra = Rs | (uimm << 16); }}); 26: xori({{ Ra = Rs ^ uimm; }}); 27: xoris({{ Ra = Rs ^ (uimm << 16); }}); 28: andi_({{ Ra = Rs & uimm; }}, true); 29: andis_({{ Ra = Rs & (uimm << 16); }}, true); } 16: decode AA { // Conditionally branch relative to PC based on CR and CTR. format BranchPCRelCondCtr { 0: bc({{ NPC = (uint32_t)(PC + disp); }}); } // Conditionally branch to fixed address based on CR and CTR. format BranchNonPCRelCondCtr { 1: bca({{ NPC = targetAddr; }}); } } 18: decode AA { // Unconditionally branch relative to PC. format BranchPCRel { 0: b({{ NPC = (uint32_t)(PC + disp); }}); } // Unconditionally branch to fixed address. format BranchNonPCRel { 1: ba({{ NPC = targetAddr; }}); } } 19: decode XO_XO { // Conditionally branch to address in LR based on CR and CTR. format BranchLrCondCtr { 16: bclr({{ NPC = LR & 0xfffffffc; }}); } // Conditionally branch to address in CTR based on CR. format BranchCtrCond { 528: bcctr({{ NPC = CTR & 0xfffffffc; }}); } // Condition register manipulation instructions. format CondLogicOp { 257: crand({{ uint32_t crBa = bits(CR, 31 - ba); uint32_t crBb = bits(CR, 31 - bb); CR = insertBits(CR, 31 - bt, crBa & crBb); }}); 449: cror({{ uint32_t crBa = bits(CR, 31 - ba); uint32_t crBb = bits(CR, 31 - bb); CR = insertBits(CR, 31 - bt, crBa | crBb); }}); 255: crnand({{ uint32_t crBa = bits(CR, 31 - ba); uint32_t crBb = bits(CR, 31 - bb); CR = insertBits(CR, 31 - bt, !(crBa & crBb)); }}); 193: crxor({{ uint32_t crBa = bits(CR, 31 - ba); uint32_t crBb = bits(CR, 31 - bb); CR = insertBits(CR, 31 - bt, crBa ^ crBb); }}); 33: crnor({{ uint32_t crBa = bits(CR, 31 - ba); uint32_t crBb = bits(CR, 31 - bb); CR = insertBits(CR, 31 - bt, !(crBa | crBb)); }}); 289: creqv({{ uint32_t crBa = bits(CR, 31 - ba); uint32_t crBb = bits(CR, 31 - bb); CR = insertBits(CR, 31 - bt, crBa == crBb); }}); 129: crandc({{ uint32_t crBa = bits(CR, 31 - ba); uint32_t crBb = bits(CR, 31 - bb); CR = insertBits(CR, 31 - bt, crBa & !crBb); }}); 417: crorc({{ uint32_t crBa = bits(CR, 31 - ba); uint32_t crBb = bits(CR, 31 - bb); CR = insertBits(CR, 31 - bt, crBa | !crBb); }}); } format CondMoveOp { 0: mcrf({{ uint32_t crBfa = bits(CR, 31 - bfa*4, 28 - bfa*4); CR = insertBits(CR, 31 - bf*4, 28 - bf*4, crBfa); }}); } format MiscOp { 150: isync({{ }}, [ IsSerializeAfter ]); } } format IntRotateOp { 21: rlwinm({{ Ra = rotateValue(Rs, sh) & fullMask; }}); 23: rlwnm({{ Ra = rotateValue(Rs, Rb) & fullMask; }}); 20: rlwimi({{ Ra = (rotateValue(Rs, sh) & fullMask) | (Ra & ~fullMask); }}); } format LoadDispOp { 34: lbz({{ Rt = Mem_ub; }}); 40: lhz({{ Rt = Mem_uh; }}); 42: lha({{ Rt = Mem_sh; }}); 32: lwz({{ Rt = Mem; }}); 58: lwa({{ Rt = Mem_sw; }}, {{ EA = Ra + (disp & 0xfffffffc); }}, {{ EA = disp & 0xfffffffc; }}); 48: lfs({{ Ft_sf = Mem_sf; }}); 50: lfd({{ Ft = Mem_df; }}); } format LoadDispUpdateOp { 35: lbzu({{ Rt = Mem_ub; }}); 41: lhzu({{ Rt = Mem_uh; }}); 43: lhau({{ Rt = Mem_sh; }}); 33: lwzu({{ Rt = Mem; }}); 49: lfsu({{ Ft_sf = Mem_sf; }}); 51: lfdu({{ Ft = Mem_df; }}); } format StoreDispOp { 38: stb({{ Mem_ub = Rs_ub; }}); 44: sth({{ Mem_uh = Rs_uh; }}); 36: stw({{ Mem = Rs; }}); 52: stfs({{ Mem_sf = Fs_sf; }}); 54: stfd({{ Mem_df = Fs; }}); } format StoreDispUpdateOp { 39: stbu({{ Mem_ub = Rs_ub; }}); 45: sthu({{ Mem_uh = Rs_uh; }}); 37: stwu({{ Mem = Rs; }}); 53: stfsu({{ Mem_sf = Fs_sf; }}); 55: stfdu({{ Mem_df = Fs; }}); } 17: IntOp::sc({{ xc->syscall(R0, &fault); }}, [ IsSyscall, IsNonSpeculative, IsSerializeAfter ]); format FloatArithOp { 59: decode A_XO { 21: fadds({{ Ft = Fa + Fb; }}); 20: fsubs({{ Ft = Fa - Fb; }}); 25: fmuls({{ Ft = Fa * Fc; }}); 18: fdivs({{ Ft = Fa / Fb; }}); 29: fmadds({{ Ft = (Fa * Fc) + Fb; }}); 28: fmsubs({{ Ft = (Fa * Fc) - Fb; }}); 31: fnmadds({{ Ft = -((Fa * Fc) + Fb); }}); 30: fnmsubs({{ Ft = -((Fa * Fc) - Fb); }}); } } 63: decode A_XO { format FloatArithOp { 21: fadd({{ Ft = Fa + Fb; }}); 20: fsub({{ Ft = Fa - Fb; }}); 25: fmul({{ Ft = Fa * Fc; }}); 18: fdiv({{ Ft = Fa / Fb; }}); 29: fmadd({{ Ft = (Fa * Fc) + Fb; }}); 28: fmsub({{ Ft = (Fa * Fc) - Fb; }}); 31: fnmadd({{ Ft = -((Fa * Fc) + Fb); }}); 30: fnmsub({{ Ft = -((Fa * Fc) - Fb); }}); } default: decode XO_XO { format FloatConvertOp { 12: frsp({{ Ft_sf = Fb; }}); 15: fctiwz({{ Ft_sw = (int32_t)trunc(Fb); }}); } format FloatOp { 0: fcmpu({{ uint32_t c = makeCRField(Fa, Fb); Fpscr fpscr = FPSCR; fpscr.fprf.fpcc = c; FPSCR = fpscr; CR = insertCRField(CR, BF, c); }}); } format FloatRCCheckOp { 72: fmr({{ Ft = Fb; }}); 264: fabs({{ Ft_uq = Fb_uq; Ft_uq = insertBits(Ft_uq, 63, 0); }}); 136: fnabs({{ Ft_uq = Fb_uq; Ft_uq = insertBits(Ft_uq, 63, 1); }}); 40: fneg({{ Ft = -Fb; }}); 8: fcpsgn({{ Ft_uq = Fb_uq; Ft_uq = insertBits(Ft_uq, 63, Fa_uq<63:63>); }}); 583: mffs({{ Ft_uq = FPSCR; }}); 134: mtfsfi({{ FPSCR = insertCRField(FPSCR, BF + (8 * (1 - W_FIELD)), U_FIELD); }}); 711: mtfsf({{ if (L_FIELD == 1) { FPSCR = Fb_uq; } else { for (int i = 0; i < 8; ++i) { if (bits(FLM, i) == 1) { int k = 4 * (i + (8 * (1 - W_FIELD))); FPSCR = insertBits(FPSCR, k + 3, k, bits(Fb_uq, k + 3, k)); } } } }}); 70: mtfsb0({{ FPSCR = insertBits(FPSCR, 31 - BT, 0); }}); 38: mtfsb1({{ FPSCR = insertBits(FPSCR, 31 - BT, 1); }}); } } } }