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