| // -*- 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, n+7) == bits(Rb, n, n+7)) { | |
| val = insertBits(val, n, n+7, 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; | |
| if (Rsv) { | |
| if (RsvLen == 4) { | |
| if (RsvAddr == EA) { | |
| Mem = Rs; | |
| 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); }}, | |
| [ 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, k + 3, | |
| bits(Fb_uq, k, k + 3)); | |
| } | |
| } | |
| } | |
| }}); | |
| 70: mtfsb0({{ FPSCR = insertBits(FPSCR, 31 - BT, 0); }}); | |
| 38: mtfsb1({{ FPSCR = insertBits(FPSCR, 31 - BT, 1); }}); | |
| } | |
| } | |
| } | |
| } |