decoder.isa revision 13801:e18de9c80ce3
13898Ssaidi@eecs.umich.edu// -*- mode:c++ -*- 22934Sktlim@umich.edu 32934Sktlim@umich.edu// Copyright (c) 2009 The University of Edinburgh 42934Sktlim@umich.edu// All rights reserved. 52934Sktlim@umich.edu// 62934Sktlim@umich.edu// Redistribution and use in source and binary forms, with or without 72934Sktlim@umich.edu// modification, are permitted provided that the following conditions are 82934Sktlim@umich.edu// met: redistributions of source code must retain the above copyright 92934Sktlim@umich.edu// notice, this list of conditions and the following disclaimer; 102934Sktlim@umich.edu// redistributions in binary form must reproduce the above copyright 112934Sktlim@umich.edu// notice, this list of conditions and the following disclaimer in the 122934Sktlim@umich.edu// documentation and/or other materials provided with the distribution; 132934Sktlim@umich.edu// neither the name of the copyright holders nor the names of its 142934Sktlim@umich.edu// contributors may be used to endorse or promote products derived from 152934Sktlim@umich.edu// this software without specific prior written permission. 162934Sktlim@umich.edu// 172934Sktlim@umich.edu// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 182934Sktlim@umich.edu// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 192934Sktlim@umich.edu// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 202934Sktlim@umich.edu// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 212934Sktlim@umich.edu// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 222934Sktlim@umich.edu// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 232934Sktlim@umich.edu// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 242934Sktlim@umich.edu// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 252934Sktlim@umich.edu// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 262934Sktlim@umich.edu// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 272934Sktlim@umich.edu// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 282934Sktlim@umich.edu// 292934Sktlim@umich.edu// Authors: Timothy M. Jones 302969Sktlim@umich.edu 312934Sktlim@umich.edu//////////////////////////////////////////////////////////////////// 322995Ssaidi@eecs.umich.edu// 332934Sktlim@umich.edu// The actual Power ISA decoder 342934Sktlim@umich.edu// ------------------------------ 352934Sktlim@umich.edu// 362934Sktlim@umich.edu// I've used the Power ISA Book I v2.06 for instruction formats, 372934Sktlim@umich.edu// opcode numbers, register names, etc. 382934Sktlim@umich.edu// 392934Sktlim@umich.edudecode OPCODE default Unknown::unknown() { 402934Sktlim@umich.edu 414520Ssaidi@eecs.umich.edu format IntImmOp { 424520Ssaidi@eecs.umich.edu 10: cmpli({{ 434982Ssaidi@eecs.umich.edu Xer xer = XER; 444520Ssaidi@eecs.umich.edu uint32_t cr = makeCRField(Ra, (uint32_t)uimm, xer.so); 454520Ssaidi@eecs.umich.edu CR = insertCRField(CR, BF, cr); 462934Sktlim@umich.edu }}); 472934Sktlim@umich.edu 11: cmpi({{ 483005Sstever@eecs.umich.edu Xer xer = XER; 493005Sstever@eecs.umich.edu uint32_t cr = makeCRField(Ra_sw, (int32_t)imm, xer.so); 503304Sstever@eecs.umich.edu CR = insertCRField(CR, BF, cr); 512995Ssaidi@eecs.umich.edu }}); 522934Sktlim@umich.edu } 532934Sktlim@umich.edu 544965Ssaidi@eecs.umich.edu // Some instructions use bits 21 - 30, others 22 - 30. We have to use 555266Sksewell@umich.edu // the larger size to account for all opcodes. For those that use the 562934Sktlim@umich.edu // smaller value, the OE bit is bit 21. Therefore, we have two versions 572934Sktlim@umich.edu // of each instruction: 1 with OE set, the other without. For an 582934Sktlim@umich.edu // example see 'add' and 'addo'. 592934Sktlim@umich.edu 31: decode XO_XO { 602934Sktlim@umich.edu 612995Ssaidi@eecs.umich.edu // These instructions can all be reduced to the form 622934Sktlim@umich.edu // Rt = src1 + src2 [+ CA], therefore we just give src1 and src2 632934Sktlim@umich.edu // (and, if necessary, CA) definitions and let the python script 642934Sktlim@umich.edu // deal with setting things up correctly. We also give flags to 652934Sktlim@umich.edu // say which control registers to set. 662934Sktlim@umich.edu format IntSumOp { 672995Ssaidi@eecs.umich.edu 266: add({{ Ra }}, {{ Rb }}); 682934Sktlim@umich.edu 40: subf({{ ~Ra }}, {{ Rb }}, {{ 1 }}); 692934Sktlim@umich.edu 10: addc({{ Ra }}, {{ Rb }}, 702953Sktlim@umich.edu computeCA = true); 714094Sbinkertn@umich.edu 8: subfc({{ ~Ra }}, {{ Rb }}, {{ 1 }}, 722934Sktlim@umich.edu true); 733449Shsul@eecs.umich.edu 104: neg({{ ~Ra }}, {{ 1 }}); 742934Sktlim@umich.edu 138: adde({{ Ra }}, {{ Rb }}, {{ xer.ca }}, 752934Sktlim@umich.edu true); 762934Sktlim@umich.edu 234: addme({{ Ra }}, {{ (uint32_t)-1 }}, {{ xer.ca }}, 772934Sktlim@umich.edu true); 782934Sktlim@umich.edu 136: subfe({{ ~Ra }}, {{ Rb }}, {{ xer.ca }}, 793584Ssaidi@eecs.umich.edu true); 804486Sbinkertn@umich.edu 232: subfme({{ ~Ra }}, {{ (uint32_t)-1 }}, {{ xer.ca }}, 814486Sbinkertn@umich.edu true); 824486Sbinkertn@umich.edu 202: addze({{ Ra }}, {{ xer.ca }}, 834486Sbinkertn@umich.edu computeCA = true); 844486Sbinkertn@umich.edu 200: subfze({{ ~Ra }}, {{ xer.ca }}, 854486Sbinkertn@umich.edu computeCA = true); 864486Sbinkertn@umich.edu } 873584Ssaidi@eecs.umich.edu 883584Ssaidi@eecs.umich.edu // Arithmetic instructions all use source registers Ra and Rb, 893584Ssaidi@eecs.umich.edu // with destination register Rt. 903584Ssaidi@eecs.umich.edu format IntArithOp { 913584Ssaidi@eecs.umich.edu 75: mulhw({{ int64_t prod = Ra_sd * Rb_sd; Rt = prod >> 32; }}); 923743Sgblack@eecs.umich.edu 11: mulhwu({{ uint64_t prod = Ra_ud * Rb_ud; Rt = prod >> 32; }}); 933584Ssaidi@eecs.umich.edu 235: mullw({{ int64_t prod = Ra_sd * Rb_sd; Rt = prod; }}); 944972Ssaidi@eecs.umich.edu 747: mullwo({{ 953743Sgblack@eecs.umich.edu int64_t src1 = Ra_sd; 964104Ssaidi@eecs.umich.edu int64_t src2 = Rb; 973743Sgblack@eecs.umich.edu int64_t prod = src1 * src2; 983823Ssaidi@eecs.umich.edu Rt = prod; 993814Ssaidi@eecs.umich.edu }}, 1003743Sgblack@eecs.umich.edu true); 1013743Sgblack@eecs.umich.edu 1023584Ssaidi@eecs.umich.edu 491: divw({{ 1033814Ssaidi@eecs.umich.edu int32_t src1 = Ra_sw; 1043584Ssaidi@eecs.umich.edu int32_t src2 = Rb_sw; 1053745Sgblack@eecs.umich.edu if ((src1 != 0x80000000 || src2 != 0xffffffff) 1063745Sgblack@eecs.umich.edu && src2 != 0) { 1073745Sgblack@eecs.umich.edu Rt = src1 / src2; 1083584Ssaidi@eecs.umich.edu } else { 1093898Ssaidi@eecs.umich.edu Rt = 0; 1103898Ssaidi@eecs.umich.edu } 1113898Ssaidi@eecs.umich.edu }}); 1124103Ssaidi@eecs.umich.edu 1134103Ssaidi@eecs.umich.edu 1003: divwo({{ 1144103Ssaidi@eecs.umich.edu int32_t src1 = Ra_sw; 1153745Sgblack@eecs.umich.edu int32_t src2 = Rb_sw; 1163745Sgblack@eecs.umich.edu if ((src1 != 0x80000000 || src2 != 0xffffffff) 1173745Sgblack@eecs.umich.edu && src2 != 0) { 1183584Ssaidi@eecs.umich.edu Rt = src1 / src2; 1193584Ssaidi@eecs.umich.edu } else { 1203584Ssaidi@eecs.umich.edu Rt = 0; 1215222Sksewell@umich.edu divSetOV = true; 1225222Sksewell@umich.edu } 1235222Sksewell@umich.edu }}, 1245222Sksewell@umich.edu true); 1255222Sksewell@umich.edu 1265222Sksewell@umich.edu 459: divwu({{ 1275222Sksewell@umich.edu uint32_t src1 = Ra_sw; 1285222Sksewell@umich.edu uint32_t src2 = Rb_sw; 1295222Sksewell@umich.edu if (src2 != 0) { 1305222Sksewell@umich.edu Rt = src1 / src2; 1315222Sksewell@umich.edu } else { 1325222Sksewell@umich.edu Rt = 0; 1335222Sksewell@umich.edu } 1345222Sksewell@umich.edu }}); 1355222Sksewell@umich.edu 1365222Sksewell@umich.edu 971: divwuo({{ 1375222Sksewell@umich.edu uint32_t src1 = Ra_sw; 1385222Sksewell@umich.edu uint32_t src2 = Rb_sw; 1395222Sksewell@umich.edu if (src2 != 0) { 1405222Sksewell@umich.edu Rt = src1 / src2; 1415222Sksewell@umich.edu } else { 1425222Sksewell@umich.edu Rt = 0; 1435222Sksewell@umich.edu divSetOV = true; 1445222Sksewell@umich.edu } 1455222Sksewell@umich.edu }}, 1465222Sksewell@umich.edu true); 1475222Sksewell@umich.edu } 1485222Sksewell@umich.edu 1495222Sksewell@umich.edu // Integer logic instructions use source registers Rs and Rb, 1505222Sksewell@umich.edu // with destination register Ra. 1515222Sksewell@umich.edu format IntLogicOp { 1525222Sksewell@umich.edu 28: and({{ Ra = Rs & Rb; }}); 1535222Sksewell@umich.edu 316: xor({{ Ra = Rs ^ Rb; }}); 1545222Sksewell@umich.edu 476: nand({{ Ra = ~(Rs & Rb); }}); 1555222Sksewell@umich.edu 444: or({{ Ra = Rs | Rb; }}); 1565222Sksewell@umich.edu 124: nor({{ Ra = ~(Rs | Rb); }}); 1575222Sksewell@umich.edu 60: andc({{ Ra = Rs & ~Rb; }}); 1585299Sgblack@eecs.umich.edu 954: extsb({{ Ra = sext<8>(Rs); }}); 1595299Sgblack@eecs.umich.edu 284: eqv({{ Ra = ~(Rs ^ Rb); }}); 1605133Sgblack@eecs.umich.edu 412: orc({{ Ra = Rs | ~Rb; }}); 1615133Sgblack@eecs.umich.edu 922: extsh({{ Ra = sext<16>(Rs); }}); 1625133Sgblack@eecs.umich.edu 26: cntlzw({{ Ra = Rs == 0 ? 32 : 31 - findMsbSet(Rs); }}); 1635133Sgblack@eecs.umich.edu 508: cmpb({{ 1645133Sgblack@eecs.umich.edu uint32_t val = 0; 1655133Sgblack@eecs.umich.edu for (int n = 0; n < 32; n += 8) { 1665133Sgblack@eecs.umich.edu if(bits(Rs, n+7, n) == bits(Rb, n+7, n)) { 1675133Sgblack@eecs.umich.edu val = insertBits(val, n+7, n, 0xff); 1685133Sgblack@eecs.umich.edu } 1695133Sgblack@eecs.umich.edu } 1705133Sgblack@eecs.umich.edu Ra = val; 1715133Sgblack@eecs.umich.edu }}); 1725133Sgblack@eecs.umich.edu 1735133Sgblack@eecs.umich.edu 24: slw({{ 1745133Sgblack@eecs.umich.edu if (Rb & 0x20) { 1755133Sgblack@eecs.umich.edu Ra = 0; 1765133Sgblack@eecs.umich.edu } else { 1773584Ssaidi@eecs.umich.edu Ra = Rs << (Rb & 0x1f); 1783025Ssaidi@eecs.umich.edu } 1792934Sktlim@umich.edu }}); 1802995Ssaidi@eecs.umich.edu 1812995Ssaidi@eecs.umich.edu 536: srw({{ 1824981Ssaidi@eecs.umich.edu if (Rb & 0x20) { 1834981Ssaidi@eecs.umich.edu Ra = 0; 1844981Ssaidi@eecs.umich.edu } else { 1854981Ssaidi@eecs.umich.edu Ra = Rs >> (Rb & 0x1f); 1863025Ssaidi@eecs.umich.edu } 1873025Ssaidi@eecs.umich.edu }}); 1883025Ssaidi@eecs.umich.edu 1892934Sktlim@umich.edu 792: sraw({{ 1902934Sktlim@umich.edu bool shiftSetCA = false; 1915253Sksewell@umich.edu int32_t s = Rs; 1925263Sksewell@umich.edu if (Rb == 0) { 1935253Sksewell@umich.edu Ra = Rs; 1945253Sksewell@umich.edu shiftSetCA = true; 1955253Sksewell@umich.edu } else if (Rb & 0x20) { 1965253Sksewell@umich.edu if (s < 0) { 1975253Sksewell@umich.edu Ra = (uint32_t)-1; 1985253Sksewell@umich.edu if (s & 0x7fffffff) { 1995253Sksewell@umich.edu shiftSetCA = true; 2005253Sksewell@umich.edu } else { 2015253Sksewell@umich.edu shiftSetCA = false; 2025253Sksewell@umich.edu } 2035253Sksewell@umich.edu } else { 2045253Sksewell@umich.edu Ra = 0; 2055253Sksewell@umich.edu shiftSetCA = false; 2065253Sksewell@umich.edu } 2075253Sksewell@umich.edu } else { 2085253Sksewell@umich.edu Ra = s >> (Rb & 0x1f); 2095253Sksewell@umich.edu if (s < 0 && (s << (32 - (Rb & 0x1f))) != 0) { 2105253Sksewell@umich.edu shiftSetCA = true; 2115253Sksewell@umich.edu } else { 2125253Sksewell@umich.edu shiftSetCA = false; 2135253Sksewell@umich.edu } 2145253Sksewell@umich.edu } 2155253Sksewell@umich.edu Xer xer1 = XER; 2165253Sksewell@umich.edu if (shiftSetCA) { 2175253Sksewell@umich.edu xer1.ca = 1; 2185253Sksewell@umich.edu } else { 2195253Sksewell@umich.edu xer1.ca = 0; 2205253Sksewell@umich.edu } 2215253Sksewell@umich.edu XER = xer1; 2225253Sksewell@umich.edu }}); 2235253Sksewell@umich.edu } 2245253Sksewell@umich.edu 2255253Sksewell@umich.edu // Integer logic instructions with a shift value. 2265253Sksewell@umich.edu format IntShiftOp { 2275253Sksewell@umich.edu 824: srawi({{ 2285253Sksewell@umich.edu bool shiftSetCA = false; 2295253Sksewell@umich.edu if (sh == 0) { 2305253Sksewell@umich.edu Ra = Rs; 2315253Sksewell@umich.edu shiftSetCA = false; 2325253Sksewell@umich.edu } else { 2335253Sksewell@umich.edu int32_t s = Rs; 2345253Sksewell@umich.edu Ra = s >> sh; 2355253Sksewell@umich.edu if (s < 0 && (s << (32 - sh)) != 0) { 2365253Sksewell@umich.edu shiftSetCA = true; 2375253Sksewell@umich.edu } else { 2385253Sksewell@umich.edu shiftSetCA = false; 2395253Sksewell@umich.edu } 2405253Sksewell@umich.edu } 2415253Sksewell@umich.edu Xer xer1 = XER; 2425253Sksewell@umich.edu if (shiftSetCA) { 2435253Sksewell@umich.edu xer1.ca = 1; 2445253Sksewell@umich.edu } else { 2455253Sksewell@umich.edu xer1.ca = 0; 2465253Sksewell@umich.edu } 2475253Sksewell@umich.edu XER = xer1; 2485253Sksewell@umich.edu }}); 2495253Sksewell@umich.edu } 2505253Sksewell@umich.edu 2515253Sksewell@umich.edu // Generic integer format instructions. 2525253Sksewell@umich.edu format IntOp { 2535253Sksewell@umich.edu 0: cmp({{ 2545253Sksewell@umich.edu Xer xer = XER; 2555253Sksewell@umich.edu uint32_t cr = makeCRField(Ra_sw, Rb_sw, xer.so); 2565253Sksewell@umich.edu CR = insertCRField(CR, BF, cr); 2575253Sksewell@umich.edu }}); 2585253Sksewell@umich.edu 32: cmpl({{ 2595253Sksewell@umich.edu Xer xer = XER; 2605253Sksewell@umich.edu uint32_t cr = makeCRField(Ra, Rb, xer.so); 261 CR = insertCRField(CR, BF, cr); 262 }}); 263 144: mtcrf({{ 264 uint32_t mask = 0; 265 for (int i = 0; i < 8; ++i) { 266 if (((FXM >> i) & 0x1) == 0x1) { 267 mask |= 0xf << (4 * i); 268 } 269 } 270 CR = (Rs & mask) | (CR & ~mask); 271 }}); 272 19: mfcr({{ Rt = CR; }}); 273 339: decode SPR { 274 0x20: mfxer({{ Rt = XER; }}); 275 0x100: mflr({{ Rt = LR; }}); 276 0x120: mfctr({{ Rt = CTR; }}); 277 } 278 467: decode SPR { 279 0x20: mtxer({{ XER = Rs; }}); 280 0x100: mtlr({{ LR = Rs; }}); 281 0x120: mtctr({{ CTR = Rs; }}); 282 } 283 } 284 285 // All loads with an index register. The non-update versions 286 // all use the value 0 if Ra == R0, not the value contained in 287 // R0. Others update Ra with the effective address. In all cases, 288 // Ra and Rb are source registers, Rt is the destintation. 289 format LoadIndexOp { 290 87: lbzx({{ Rt = Mem_ub; }}); 291 279: lhzx({{ Rt = Mem_uh; }}); 292 343: lhax({{ Rt = Mem_sh; }}); 293 23: lwzx({{ Rt = Mem; }}); 294 341: lwax({{ Rt = Mem_sw; }}); 295 20: lwarx({{ Rt = Mem_sw; Rsv = 1; RsvLen = 4; RsvAddr = EA; }}); 296 535: lfsx({{ Ft_sf = Mem_sf; }}); 297 599: lfdx({{ Ft = Mem_df; }}); 298 855: lfiwax({{ Ft_uw = Mem; }}); 299 } 300 301 format LoadIndexUpdateOp { 302 119: lbzux({{ Rt = Mem_ub; }}); 303 311: lhzux({{ Rt = Mem_uh; }}); 304 375: lhaux({{ Rt = Mem_sh; }}); 305 55: lwzux({{ Rt = Mem; }}); 306 373: lwaux({{ Rt = Mem_sw; }}); 307 567: lfsux({{ Ft_sf = Mem_sf; }}); 308 631: lfdux({{ Ft = Mem_df; }}); 309 } 310 311 format StoreIndexOp { 312 215: stbx({{ Mem_ub = Rs_ub; }}); 313 407: sthx({{ Mem_uh = Rs_uh; }}); 314 151: stwx({{ Mem = Rs; }}); 315 150: stwcx({{ 316 bool store_performed = false; 317 Mem = Rs; 318 if (Rsv) { 319 if (RsvLen == 4) { 320 if (RsvAddr == EA) { 321 store_performed = true; 322 } 323 } 324 } 325 Xer xer = XER; 326 Cr cr = CR; 327 cr.cr0 = ((store_performed ? 0x2 : 0x0) | xer.so); 328 CR = cr; 329 Rsv = 0; 330 }}); 331 663: stfsx({{ Mem_sf = Fs_sf; }}); 332 727: stfdx({{ Mem_df = Fs; }}); 333 983: stfiwx({{ Mem = Fs_uw; }}); 334 } 335 336 format StoreIndexUpdateOp { 337 247: stbux({{ Mem_ub = Rs_ub; }}); 338 439: sthux({{ Mem_uh = Rs_uh; }}); 339 183: stwux({{ Mem = Rs; }}); 340 695: stfsux({{ Mem_sf = Fs_sf; }}); 341 759: stfdux({{ Mem_df = Fs; }}); 342 } 343 344 // These instructions all provide data cache hints 345 format MiscOp { 346 278: dcbt({{ }}); 347 246: dcbtst({{ }}); 348 598: sync({{ }}, [ IsMemBarrier ]); 349 854: eieio({{ }}, [ IsMemBarrier ]); 350 } 351 } 352 353 format IntImmArithCheckRaOp { 354 14: addi({{ Rt = Ra + imm; }}, 355 {{ Rt = imm }}); 356 15: addis({{ Rt = Ra + (imm << 16); }}, 357 {{ Rt = imm << 16; }}); 358 } 359 360 format IntImmArithOp { 361 12: addic({{ uint32_t src = Ra; Rt = src + imm; }}, 362 [computeCA]); 363 13: addic_({{ uint32_t src = Ra; Rt = src + imm; }}, 364 [computeCA, computeCR0]); 365 8: subfic({{ int32_t src = ~Ra; Rt = src + imm + 1; }}, 366 [computeCA]); 367 7: mulli({{ 368 int32_t src = Ra_sw; 369 int64_t prod = src * imm; 370 Rt = (uint32_t)prod; 371 }}); 372 } 373 374 format IntImmLogicOp { 375 24: ori({{ Ra = Rs | uimm; }}); 376 25: oris({{ Ra = Rs | (uimm << 16); }}); 377 26: xori({{ Ra = Rs ^ uimm; }}); 378 27: xoris({{ Ra = Rs ^ (uimm << 16); }}); 379 28: andi_({{ Ra = Rs & uimm; }}, 380 true); 381 29: andis_({{ Ra = Rs & (uimm << 16); }}, 382 true); 383 } 384 385 16: decode AA { 386 387 // Conditionally branch relative to PC based on CR and CTR. 388 format BranchPCRelCondCtr { 389 0: bc({{ NIA = (uint32_t)(CIA + disp); }}); 390 } 391 392 // Conditionally branch to fixed address based on CR and CTR. 393 format BranchNonPCRelCondCtr { 394 1: bca({{ NIA = targetAddr; }}); 395 } 396 } 397 398 18: decode AA { 399 400 // Unconditionally branch relative to PC. 401 format BranchPCRel { 402 0: b({{ NIA = (uint32_t)(CIA + disp); }}); 403 } 404 405 // Unconditionally branch to fixed address. 406 format BranchNonPCRel { 407 1: ba({{ NIA = targetAddr; }}); 408 } 409 } 410 411 19: decode XO_XO { 412 413 // Conditionally branch to address in LR based on CR and CTR. 414 format BranchLrCondCtr { 415 16: bclr({{ NIA = LR & 0xfffffffc; }}); 416 } 417 418 // Conditionally branch to address in CTR based on CR. 419 format BranchCtrCond { 420 528: bcctr({{ NIA = CTR & 0xfffffffc; }}); 421 } 422 423 // Condition register manipulation instructions. 424 format CondLogicOp { 425 257: crand({{ 426 uint32_t crBa = bits(CR, 31 - ba); 427 uint32_t crBb = bits(CR, 31 - bb); 428 CR = insertBits(CR, 31 - bt, crBa & crBb); 429 }}); 430 449: cror({{ 431 uint32_t crBa = bits(CR, 31 - ba); 432 uint32_t crBb = bits(CR, 31 - bb); 433 CR = insertBits(CR, 31 - bt, crBa | crBb); 434 }}); 435 255: crnand({{ 436 uint32_t crBa = bits(CR, 31 - ba); 437 uint32_t crBb = bits(CR, 31 - bb); 438 CR = insertBits(CR, 31 - bt, !(crBa & crBb)); 439 }}); 440 193: crxor({{ 441 uint32_t crBa = bits(CR, 31 - ba); 442 uint32_t crBb = bits(CR, 31 - bb); 443 CR = insertBits(CR, 31 - bt, crBa ^ crBb); 444 }}); 445 33: crnor({{ 446 uint32_t crBa = bits(CR, 31 - ba); 447 uint32_t crBb = bits(CR, 31 - bb); 448 CR = insertBits(CR, 31 - bt, !(crBa | crBb)); 449 }}); 450 289: creqv({{ 451 uint32_t crBa = bits(CR, 31 - ba); 452 uint32_t crBb = bits(CR, 31 - bb); 453 CR = insertBits(CR, 31 - bt, crBa == crBb); 454 }}); 455 129: crandc({{ 456 uint32_t crBa = bits(CR, 31 - ba); 457 uint32_t crBb = bits(CR, 31 - bb); 458 CR = insertBits(CR, 31 - bt, crBa & !crBb); 459 }}); 460 417: crorc({{ 461 uint32_t crBa = bits(CR, 31 - ba); 462 uint32_t crBb = bits(CR, 31 - bb); 463 CR = insertBits(CR, 31 - bt, crBa | !crBb); 464 }}); 465 } 466 format CondMoveOp { 467 0: mcrf({{ 468 uint32_t crBfa = bits(CR, 31 - bfa*4, 28 - bfa*4); 469 CR = insertBits(CR, 31 - bf*4, 28 - bf*4, crBfa); 470 }}); 471 } 472 format MiscOp { 473 150: isync({{ }}, [ IsSerializeAfter ]); 474 } 475 } 476 477 format IntRotateOp { 478 21: rlwinm({{ Ra = rotateValue(Rs, sh) & fullMask; }}); 479 23: rlwnm({{ Ra = rotateValue(Rs, Rb) & fullMask; }}); 480 20: rlwimi({{ Ra = (rotateValue(Rs, sh) & fullMask) | (Ra & ~fullMask); }}); 481 } 482 483 format LoadDispOp { 484 34: lbz({{ Rt = Mem_ub; }}); 485 40: lhz({{ Rt = Mem_uh; }}); 486 42: lha({{ Rt = Mem_sh; }}); 487 32: lwz({{ Rt = Mem; }}); 488 58: lwa({{ Rt = Mem_sw; }}, 489 {{ EA = Ra + (disp & 0xfffffffc); }}, 490 {{ EA = disp & 0xfffffffc; }}); 491 48: lfs({{ Ft_sf = Mem_sf; }}); 492 50: lfd({{ Ft = Mem_df; }}); 493 } 494 495 format LoadDispUpdateOp { 496 35: lbzu({{ Rt = Mem_ub; }}); 497 41: lhzu({{ Rt = Mem_uh; }}); 498 43: lhau({{ Rt = Mem_sh; }}); 499 33: lwzu({{ Rt = Mem; }}); 500 49: lfsu({{ Ft_sf = Mem_sf; }}); 501 51: lfdu({{ Ft = Mem_df; }}); 502 } 503 504 format StoreDispOp { 505 38: stb({{ Mem_ub = Rs_ub; }}); 506 44: sth({{ Mem_uh = Rs_uh; }}); 507 36: stw({{ Mem = Rs; }}); 508 52: stfs({{ Mem_sf = Fs_sf; }}); 509 54: stfd({{ Mem_df = Fs; }}); 510 } 511 512 format StoreDispUpdateOp { 513 39: stbu({{ Mem_ub = Rs_ub; }}); 514 45: sthu({{ Mem_uh = Rs_uh; }}); 515 37: stwu({{ Mem = Rs; }}); 516 53: stfsu({{ Mem_sf = Fs_sf; }}); 517 55: stfdu({{ Mem_df = Fs; }}); 518 } 519 520 17: IntOp::sc({{ xc->syscall(R0, &fault); }}, 521 [ IsSyscall, IsNonSpeculative, IsSerializeAfter ]); 522 523 format FloatArithOp { 524 59: decode A_XO { 525 21: fadds({{ Ft = Fa + Fb; }}); 526 20: fsubs({{ Ft = Fa - Fb; }}); 527 25: fmuls({{ Ft = Fa * Fc; }}); 528 18: fdivs({{ Ft = Fa / Fb; }}); 529 29: fmadds({{ Ft = (Fa * Fc) + Fb; }}); 530 28: fmsubs({{ Ft = (Fa * Fc) - Fb; }}); 531 31: fnmadds({{ Ft = -((Fa * Fc) + Fb); }}); 532 30: fnmsubs({{ Ft = -((Fa * Fc) - Fb); }}); 533 } 534 } 535 536 63: decode A_XO { 537 format FloatArithOp { 538 21: fadd({{ Ft = Fa + Fb; }}); 539 20: fsub({{ Ft = Fa - Fb; }}); 540 25: fmul({{ Ft = Fa * Fc; }}); 541 18: fdiv({{ Ft = Fa / Fb; }}); 542 29: fmadd({{ Ft = (Fa * Fc) + Fb; }}); 543 28: fmsub({{ Ft = (Fa * Fc) - Fb; }}); 544 31: fnmadd({{ Ft = -((Fa * Fc) + Fb); }}); 545 30: fnmsub({{ Ft = -((Fa * Fc) - Fb); }}); 546 } 547 548 default: decode XO_XO { 549 format FloatConvertOp { 550 12: frsp({{ Ft_sf = Fb; }}); 551 15: fctiwz({{ Ft_sw = (int32_t)trunc(Fb); }}); 552 } 553 554 format FloatOp { 555 0: fcmpu({{ 556 uint32_t c = makeCRField(Fa, Fb); 557 Fpscr fpscr = FPSCR; 558 fpscr.fprf.fpcc = c; 559 FPSCR = fpscr; 560 CR = insertCRField(CR, BF, c); 561 }}); 562 } 563 564 format FloatRCCheckOp { 565 72: fmr({{ Ft = Fb; }}); 566 264: fabs({{ 567 Ft_ud = Fb_ud; 568 Ft_ud = insertBits(Ft_ud, 63, 0); }}); 569 136: fnabs({{ 570 Ft_ud = Fb_ud; 571 Ft_ud = insertBits(Ft_ud, 63, 1); }}); 572 40: fneg({{ Ft = -Fb; }}); 573 8: fcpsgn({{ 574 Ft_ud = Fb_ud; 575 Ft_ud = insertBits(Ft_ud, 63, Fa_ud<63:63>); 576 }}); 577 583: mffs({{ Ft_ud = FPSCR; }}); 578 134: mtfsfi({{ 579 FPSCR = insertCRField(FPSCR, BF + (8 * (1 - W_FIELD)), 580 U_FIELD); 581 }}); 582 711: mtfsf({{ 583 if (L_FIELD == 1) { FPSCR = Fb_ud; } 584 else { 585 for (int i = 0; i < 8; ++i) { 586 if (bits(FLM, i) == 1) { 587 int k = 4 * (i + (8 * (1 - W_FIELD))); 588 FPSCR = insertBits(FPSCR, k + 3, k, 589 bits(Fb_ud, k + 3, k)); 590 } 591 } 592 } 593 }}); 594 70: mtfsb0({{ FPSCR = insertBits(FPSCR, 31 - BT, 0); }}); 595 38: mtfsb1({{ FPSCR = insertBits(FPSCR, 31 - BT, 1); }}); 596 } 597 } 598 } 599} 600