summaryrefslogtreecommitdiff
path: root/src/arch/power/isa
diff options
context:
space:
mode:
authorTimothy M. Jones <tjones1@inf.ed.ac.uk>2009-10-27 09:24:39 -0700
committerTimothy M. Jones <tjones1@inf.ed.ac.uk>2009-10-27 09:24:39 -0700
commit835a55e7f347697815fc43851b2dd5a8642d21c4 (patch)
tree637768b1de6de2bc4520fad97f90194ad6d3f8d6 /src/arch/power/isa
parent0fdfc82bde5b8975ee93d5da9c604ad9b99942e0 (diff)
downloadgem5-835a55e7f347697815fc43851b2dd5a8642d21c4.tar.xz
POWER: Add support for the Power ISA
This adds support for the 32-bit, big endian Power ISA. This supports both integer and floating point instructions based on the Power ISA Book I v2.06.
Diffstat (limited to 'src/arch/power/isa')
-rw-r--r--src/arch/power/isa/bitfields.isa84
-rw-r--r--src/arch/power/isa/decoder.isa593
-rw-r--r--src/arch/power/isa/formats/basic.isa103
-rw-r--r--src/arch/power/isa/formats/branch.isa222
-rw-r--r--src/arch/power/isa/formats/condition.isa47
-rw-r--r--src/arch/power/isa/formats/formats.isa60
-rw-r--r--src/arch/power/isa/formats/fp.isa132
-rw-r--r--src/arch/power/isa/formats/integer.isa369
-rw-r--r--src/arch/power/isa/formats/mem.isa351
-rw-r--r--src/arch/power/isa/formats/misc.isa61
-rw-r--r--src/arch/power/isa/formats/unimp.isa146
-rw-r--r--src/arch/power/isa/formats/unknown.isa87
-rw-r--r--src/arch/power/isa/formats/util.isa174
-rw-r--r--src/arch/power/isa/includes.isa92
-rw-r--r--src/arch/power/isa/main.isa57
-rw-r--r--src/arch/power/isa/operands.isa81
16 files changed, 2659 insertions, 0 deletions
diff --git a/src/arch/power/isa/bitfields.isa b/src/arch/power/isa/bitfields.isa
new file mode 100644
index 000000000..8cd323ad5
--- /dev/null
+++ b/src/arch/power/isa/bitfields.isa
@@ -0,0 +1,84 @@
+// -*- 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
+
+////////////////////////////////////////////////////////////////////
+//
+// Bitfield definitions.
+//
+// The endianness is the opposite to what's used here, so things
+// are reversed sometimes. Not sure of a fix to this though...
+
+// Opcode fields
+def bitfield OPCODE <31:26>;
+def bitfield X_XO <10:0>;
+def bitfield XO_XO <10:1>;
+def bitfield A_XO <5:1>;
+
+// Register fields
+def bitfield RA <20:16>;
+def bitfield RB <15:11>;
+def bitfield RS <25:21>;
+def bitfield RT <25:21>;
+def bitfield FRA <20:16>;
+def bitfield FRB <15:11>;
+def bitfield FRC <10:6>;
+def bitfield FRS <25:21>;
+def bitfield FRT <25:21>;
+
+// The record bit can be in two positions
+// Used to enable setting of the condition register
+def bitfield RC31 <0>;
+def bitfield RC21 <10>;
+
+// Used to enable setting of the overflow flags
+def bitfield OE <10>;
+
+// SPR field for mtspr instruction
+def bitfield SPR <20:11>;
+
+// FXM field for mtcrf instruction
+def bitfield FXM <19:12>;
+
+// Branch fields
+def bitfield LK <0>;
+def bitfield AA <1>;
+
+// Specifies a CR or FPSCR field
+def bitfield BF <25:23>;
+
+// Fields for FPSCR manipulation instructions
+def bitfield FLM <24:17>;
+def bitfield L <25>;
+def bitfield W <16>;
+// Named so to avoid conflicts with range.hh
+def bitfield U_FIELD <15:12>;
+
+// Field for specifying a bit in CR or FPSCR
+def bitfield BT <25:21>;
diff --git a/src/arch/power/isa/decoder.isa b/src/arch/power/isa/decoder.isa
new file mode 100644
index 000000000..3252ff14a
--- /dev/null
+++ b/src/arch/power/isa/decoder.isa
@@ -0,0 +1,593 @@
+// -*- 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 = 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 = 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)), U_FIELD);
+ }});
+ 711: mtfsf({{
+ if (L == 1) { FPSCR = Fb.uq; }
+ else {
+ for (int i = 0; i < 8; ++i) {
+ if (bits(FLM, i) == 1) {
+ int k = 4 * (i + (8 * (1 - W)));
+ 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); }});
+ }
+ }
+ }
+}
diff --git a/src/arch/power/isa/formats/basic.isa b/src/arch/power/isa/formats/basic.isa
new file mode 100644
index 000000000..adb5e7ef8
--- /dev/null
+++ b/src/arch/power/isa/formats/basic.isa
@@ -0,0 +1,103 @@
+// -*- 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
+
+// Declarations for execute() methods.
+def template BasicExecDeclare {{
+ Fault execute(%(CPU_exec_context)s *, Trace::InstRecord *) const;
+}};
+
+// Basic instruction class declaration template.
+def template BasicDeclare {{
+ /**
+ * Static instruction class for "%(mnemonic)s".
+ */
+ class %(class_name)s : public %(base_class)s
+ {
+ public:
+ /// Constructor.
+ %(class_name)s(ExtMachInst machInst);
+ %(BasicExecDeclare)s
+ };
+}};
+
+// Basic instruction class constructor template.
+def template BasicConstructor {{
+ inline %(class_name)s::%(class_name)s(ExtMachInst machInst) : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
+ {
+ %(constructor)s;
+ }
+}};
+
+
+// Basic instruction class execute method template.
+def template BasicExecute {{
+ Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
+ {
+ Fault fault = NoFault;
+
+ %(op_decl)s;
+ %(op_rd)s;
+ %(code)s;
+
+ if (fault == NoFault)
+ {
+ %(op_wb)s;
+ }
+
+ return fault;
+ }
+}};
+
+// Basic decode template.
+def template BasicDecode {{
+ return new %(class_name)s(machInst);
+}};
+
+// Basic decode template, passing mnemonic in as string arg to constructor.
+def template BasicDecodeWithMnemonic {{
+ return new %(class_name)s("%(mnemonic)s", machInst);
+}};
+
+// Definitions of execute methods that panic.
+def template BasicExecPanic {{
+Fault execute(%(CPU_exec_context)s *, Trace::InstRecord *) const
+{
+ panic("Execute method called when it shouldn't!");
+}
+}};
+
+// The most basic instruction format...
+def format BasicOp(code, *flags) {{
+ iop = InstObjParams(name, Name, 'PowerStaticInst', code, flags)
+ header_output = BasicDeclare.subst(iop)
+ decoder_output = BasicConstructor.subst(iop)
+ decode_block = BasicDecode.subst(iop)
+ exec_output = BasicExecute.subst(iop)
+}};
diff --git a/src/arch/power/isa/formats/branch.isa b/src/arch/power/isa/formats/branch.isa
new file mode 100644
index 000000000..d51ed5c25
--- /dev/null
+++ b/src/arch/power/isa/formats/branch.isa
@@ -0,0 +1,222 @@
+// -*- 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
+
+////////////////////////////////////////////////////////////////////
+//
+// Control transfer instructions
+//
+// From the Power ISA Book I v2.06, page 33, the following rules should
+// be obeyed by programmers:
+//
+// - Use branch instructions where LK == 1 only as subroutine calls.
+// - Pair each subroutine call with a bclr instruction with BH == 00
+// that returns from the subroutine.
+// - Do not use bclrl as a subroutine call.
+//
+// Therefore, I've flagged all versions that update the link register (LR)
+// as calls, except bclrl (BranchLrCtrCond format) which is flagged as
+// a return.
+
+
+let {{
+
+# Simple code to update link register (LR).
+updateLrCode = 'LR = PC + 4;'
+
+}};
+
+// Instructions that unconditionally branch relative to the current PC.
+def format BranchPCRel(br_code, inst_flags = []) {{
+ inst_flags += ('IsUncondControl', 'IsDirectControl')
+ basic_code = br_code
+
+ # The version that does not update LR
+ (header_output, decoder_output, decode_block, exec_output) = \
+ GenAluOp(name, Name, 'BranchPCRel', basic_code, inst_flags,
+ CheckLkDecode, BasicConstructor)
+
+ # The version that does the update
+ update_code = basic_code + updateLrCode
+ update_flags = inst_flags + [ 'IsCall' ]
+ (header_output_up, decoder_output_up, _, exec_output_up) = \
+ GenAluOp(name, Name + 'UpdateLr', 'BranchPCRel', update_code,
+ update_flags, CheckLkDecode, BasicConstructor)
+
+ # Add the outputs together
+ header_output += header_output_up
+ decoder_output += decoder_output_up
+ exec_output += exec_output_up
+}};
+
+// Instructions that unconditionally branch to a specific address.
+def format BranchNonPCRel(br_code, inst_flags = []) {{
+ inst_flags += ('IsUncondControl', 'IsDirectControl')
+ basic_code = br_code
+
+ # The version that does not update LR
+ (header_output, decoder_output, decode_block, exec_output) = \
+ GenAluOp(name, Name, 'BranchNonPCRel', basic_code, inst_flags,
+ CheckLkDecode, BasicConstructor)
+
+ # The version that does the update
+ update_code = basic_code + updateLrCode
+ update_flags = inst_flags + [ 'IsCall' ]
+ (header_output_up, decoder_output_up, _, exec_output_up) = \
+ GenAluOp(name, Name + 'UpdateLr', 'BranchNonPCRel', update_code,
+ update_flags, CheckLkDecode, BasicConstructor)
+
+ # Add the outputs together
+ header_output += header_output_up
+ decoder_output += decoder_output_up
+ exec_output += exec_output_up
+}};
+
+let {{
+
+# Check the condition register (CR) allows the branch to be taken.
+def GetCondCode(br_code):
+ cond_code = 'if(condOk(CR)) {\n'
+ cond_code += ' ' + br_code + '\n'
+ cond_code += '} else {\n'
+ cond_code += ' NPC = NPC;\n'
+ cond_code += '}\n'
+ return cond_code
+
+# Check the condition register (CR) and count register (CTR) allow the
+# branch to be taken. Also, in certain situations, decrement the count
+# register too. This takes place in ctrOk within BranchCond classes.
+def GetCtrCondCode(br_code):
+ cond_code = 'uint32_t ctr = CTR;\n'
+ cond_code += 'bool ctr_ok = ctrOk(ctr);\n'
+ cond_code += 'bool cond_ok = condOk(CR);\n'
+ cond_code += 'if(ctr_ok && cond_ok) {\n'
+ cond_code += ' ' + br_code + '\n'
+ cond_code += '} else {\n'
+ cond_code += ' NPC = NPC;\n'
+ cond_code += '}\n'
+ cond_code += 'CTR = ctr;\n'
+ return cond_code
+
+}};
+
+// Instructions that conditionally branch relative to the current PC based on
+// the condition register (CR) and count register (CTR).
+def format BranchPCRelCondCtr(br_code, inst_flags = []) {{
+ inst_flags += ('IsCondControl', 'IsDirectControl')
+ basic_code = GetCtrCondCode(br_code)
+
+ # The version that does not update LR
+ (header_output, decoder_output, decode_block, exec_output) = \
+ GenAluOp(name, Name, 'BranchPCRelCond', basic_code, inst_flags,
+ CheckLkDecode, BasicConstructor)
+
+ # The version that does the update
+ update_code = basic_code + updateLrCode
+ update_flags = inst_flags + [ 'IsCall' ]
+ (header_output_up, decoder_output_up, _, exec_output_up) = \
+ GenAluOp(name, Name + 'UpdateLr', 'BranchPCRelCond', update_code,
+ update_flags, CheckLkDecode, BasicConstructor)
+
+ # Add the outputs together
+ header_output += header_output_up
+ decoder_output += decoder_output_up
+ exec_output += exec_output_up
+}};
+
+// Instructions that conditionally branch to a specific address based on the
+// condition register (CR) and count register (CTR).
+def format BranchNonPCRelCondCtr(br_code, inst_flags = []) {{
+ inst_flags += ('IsCondControl', 'IsDirectControl')
+ basic_code = GetCtrCondCode(br_code)
+
+ # The version that does not update LR
+ (header_output, decoder_output, decode_block, exec_output) = \
+ GenAluOp(name, Name, 'BranchNonPCRelCond', basic_code, inst_flags,
+ CheckLkDecode, BasicConstructor)
+
+ # The version that does the update
+ update_code = basic_code + updateLrCode
+ update_flags = inst_flags + [ 'IsCall' ]
+ (header_output_up, decoder_output_up, _, exec_output_up) = \
+ GenAluOp(name, Name + 'UpdateLr', 'BranchNonPCRelCond', update_code,
+ update_flags, CheckLkDecode, BasicConstructor)
+
+ # Add the outputs together
+ header_output += header_output_up
+ decoder_output += decoder_output_up
+ exec_output += exec_output_up
+}};
+
+// Instructions that conditionally branch to the address in the link register
+// (LR) based on the condition register (CR) and count register (CTR).
+def format BranchLrCondCtr(br_code, inst_flags = []) {{
+ inst_flags += ('IsCondControl', 'IsIndirectControl', 'IsReturn')
+ basic_code = GetCtrCondCode(br_code)
+
+ # The version that does not update LR
+ (header_output, decoder_output, decode_block, exec_output) = \
+ GenAluOp(name, Name, 'BranchRegCond', basic_code, inst_flags,
+ CheckLkDecode, BasicConstructor)
+
+ # The version that does the update
+ update_code = basic_code + updateLrCode
+ (header_output_up, decoder_output_up, _, exec_output_up) = \
+ GenAluOp(name, Name + 'UpdateLr', 'BranchRegCond', update_code,
+ inst_flags, CheckLkDecode, BasicConstructor)
+
+ # Add the outputs together
+ header_output += header_output_up
+ decoder_output += decoder_output_up
+ exec_output += exec_output_up
+}};
+
+// Instructions that conditionally branch to the address in the count register
+// (CTR) based on the condition register (CR).
+def format BranchCtrCond(br_code, inst_flags = []) {{
+ inst_flags += ('IsCondControl', 'IsIndirectControl')
+ basic_code = GetCondCode(br_code)
+
+ # The version that does not update LR
+ (header_output, decoder_output, decode_block, exec_output) = \
+ GenAluOp(name, Name, 'BranchRegCond', basic_code, inst_flags,
+ CheckLkDecode, BasicConstructor)
+
+ # The version that does the update
+ update_code = basic_code + updateLrCode
+ update_flags = inst_flags + [ 'IsCall' ]
+ (header_output_up, decoder_output_up, _, exec_output_up) = \
+ GenAluOp(name, Name + 'UpdateLr', 'BranchRegCond', update_code,
+ update_flags, CheckLkDecode, BasicConstructor)
+
+ # Add the outputs together
+ header_output += header_output_up
+ decoder_output += decoder_output_up
+ exec_output += exec_output_up
+}};
diff --git a/src/arch/power/isa/formats/condition.isa b/src/arch/power/isa/formats/condition.isa
new file mode 100644
index 000000000..12ee7ae7d
--- /dev/null
+++ b/src/arch/power/isa/formats/condition.isa
@@ -0,0 +1,47 @@
+// -*- 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
+
+// Logical instructions that manipulate the condition register
+def format CondLogicOp(code, *flags) {{
+ iop = InstObjParams(name, Name, 'CondLogicOp', code, flags)
+ header_output = BasicDeclare.subst(iop)
+ decoder_output = BasicConstructor.subst(iop)
+ decode_block = BasicDecode.subst(iop)
+ exec_output = BasicExecute.subst(iop)
+}};
+
+// Instructions that condition register fields
+def format CondMoveOp(code, *flags) {{
+ iop = InstObjParams(name, Name, 'CondMoveOp', code, flags)
+ header_output = BasicDeclare.subst(iop)
+ decoder_output = BasicConstructor.subst(iop)
+ decode_block = BasicDecode.subst(iop)
+ exec_output = BasicExecute.subst(iop)
+}};
diff --git a/src/arch/power/isa/formats/formats.isa b/src/arch/power/isa/formats/formats.isa
new file mode 100644
index 000000000..ec2575196
--- /dev/null
+++ b/src/arch/power/isa/formats/formats.isa
@@ -0,0 +1,60 @@
+// -*- 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
+
+//Templates from this format are used later
+//Include the basic format
+##include "basic.isa"
+
+//Include integer instructions
+##include "integer.isa"
+
+//Include condition register instructions
+##include "condition.isa"
+
+//Include utility functions
+##include "util.isa"
+
+//Include the float formats
+##include "fp.isa"
+
+//Include the mem format
+##include "mem.isa"
+
+//Include the branch format
+##include "branch.isa"
+
+//Include the misc format
+##include "misc.isa"
+
+//Include the unimplemented format
+##include "unimp.isa"
+
+//Include the unknown format
+##include "unknown.isa"
diff --git a/src/arch/power/isa/formats/fp.isa b/src/arch/power/isa/formats/fp.isa
new file mode 100644
index 000000000..db917476e
--- /dev/null
+++ b/src/arch/power/isa/formats/fp.isa
@@ -0,0 +1,132 @@
+// -*- 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
+
+////////////////////////////////////////////////////////////////////
+//
+// Floating Point operate instructions
+//
+
+
+let {{
+
+ readFPSCRCode = 'Fpscr fpscr = FPSCR;'
+
+ computeCR1Code = '''
+ Cr cr = CR;
+ cr.cr1 = (fpscr.fx << 3) | (fpscr.fex << 2) |
+ (fpscr.vx << 1) | fpscr.ox;
+ CR = cr;
+ '''
+
+}};
+
+// Primary format for floating point operate instructions:
+def format FloatOp(code, inst_flags = []) {{
+ iop = InstObjParams(name, Name, 'FloatOp',
+ {"code": code},
+ inst_flags)
+ header_output = BasicDeclare.subst(iop)
+ decoder_output = BasicConstructor.subst(iop)
+ decode_block = BasicDecode.subst(iop)
+ exec_output = BasicExecute.subst(iop)
+}};
+
+// Floating point operations that compute the CR1 code if RC is set. No other
+// special registers are touched using these operations.
+def format FloatRCCheckOp(code, inst_flags = []) {{
+
+ # Code when Rc is set
+ code_rc1 = code + readFPSCRCode + computeCR1Code
+
+ # Generate the first class
+ (header_output, decoder_output, decode_block, exec_output) = \
+ GenAluOp(name, Name, 'FloatOp', code, inst_flags,
+ CheckRcDecode, BasicConstructor)
+
+ # Generate the second class
+ (header_output_rc1, decoder_output_rc1, _, exec_output_rc1) = \
+ GenAluOp(name, Name + 'RcSet', 'FloatOp', code_rc1, inst_flags,
+ CheckRcDecode, IntRcConstructor)
+
+ # Finally, add to the other outputs
+ header_output += header_output_rc1
+ decoder_output += decoder_output_rc1
+ exec_output += exec_output_rc1
+}};
+
+// Floating point elementary arithmetic operations. Besides having two
+// versions of each instruction for when Rc is set or not, we also have
+// to alter lots of special registers depending on the result of the
+// operation. The result is always in Ft.sf.
+def format FloatArithOp(code, inst_flags = []) {{
+
+ # Code when Rc is set
+ code_rc1 = code + readFPSCRCode + computeCR1Code
+
+ # Generate the first class
+ (header_output, decoder_output, decode_block, exec_output) = \
+ GenAluOp(name, Name, 'FloatOp', code, inst_flags,
+ CheckRcDecode, BasicConstructor)
+
+ # Generate the second class
+ (header_output_rc1, decoder_output_rc1, _, exec_output_rc1) = \
+ GenAluOp(name, Name + 'RcSet', 'FloatOp', code_rc1, inst_flags,
+ CheckRcDecode, IntRcConstructor)
+
+ # Finally, add to the other outputs
+ header_output += header_output_rc1
+ decoder_output += decoder_output_rc1
+ exec_output += exec_output_rc1
+}};
+
+// Floating point rounding and conversion operations. Besides having two
+// versions of each instruction for when Rc is set or not, we also have
+// to alter lots of special registers depending on the result of the
+// operation. The result is always in Ft.sf.
+def format FloatConvertOp(code, inst_flags = []) {{
+
+ # Code when Rc is set
+ code_rc1 = code + readFPSCRCode + computeCR1Code
+
+ # Generate the first class
+ (header_output, decoder_output, decode_block, exec_output) = \
+ GenAluOp(name, Name, 'FloatOp', code, inst_flags,
+ CheckRcDecode, BasicConstructor)
+
+ # Generate the second class
+ (header_output_rc1, decoder_output_rc1, _, exec_output_rc1) = \
+ GenAluOp(name, Name + 'RcSet', 'FloatOp', code_rc1, inst_flags,
+ CheckRcDecode, IntRcConstructor)
+
+ # Finally, add to the other outputs
+ header_output += header_output_rc1
+ decoder_output += decoder_output_rc1
+ exec_output += exec_output_rc1
+}};
diff --git a/src/arch/power/isa/formats/integer.isa b/src/arch/power/isa/formats/integer.isa
new file mode 100644
index 000000000..0766826ec
--- /dev/null
+++ b/src/arch/power/isa/formats/integer.isa
@@ -0,0 +1,369 @@
+// -*- 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
+
+////////////////////////////////////////////////////////////////////
+//
+// Integer ALU instructions
+//
+
+
+// Instruction class constructor template when Rc is set.
+def template IntRcConstructor {{
+ inline %(class_name)s::%(class_name)s(ExtMachInst machInst) : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
+ {
+ %(constructor)s;
+ rcSet = true;
+ }
+}};
+
+
+// Instruction class constructor template when OE is set.
+def template IntOeConstructor {{
+ inline %(class_name)s::%(class_name)s(ExtMachInst machInst) : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
+ {
+ %(constructor)s;
+ oeSet = true;
+ }
+}};
+
+
+// Instruction class constructor template when both Rc and OE are set.
+def template IntRcOeConstructor {{
+ inline %(class_name)s::%(class_name)s(ExtMachInst machInst) : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
+ {
+ %(constructor)s;
+ rcSet = true;
+ oeSet = true;
+ }
+}};
+
+
+let {{
+
+readXERCode = 'Xer xer = XER;'
+
+setXERCode = 'XER = xer;'
+
+computeCR0Code = '''
+ Cr cr = CR;
+ cr.cr0 = makeCRField((int32_t)%(result)s, (int32_t)0, xer.so);
+ CR = cr;
+'''
+
+computeCACode = '''
+ if (findCarry(32, %(result)s, %(inputa)s, %(inputb)s)) {
+ xer.ca = 1;
+ } else {
+ xer.ca = 0;
+ }
+'''
+
+computeOVCode = '''
+ if (findOverflow(32, %(result)s, %(inputa)s, %(inputb)s)) {
+ xer.ov = 1;
+ xer.so = 1;
+ } else {
+ xer.ov = 0;
+ }
+'''
+
+computeDivOVCode = '''
+ if (divSetOV) {
+ xer.ov = 1;
+ xer.so = 1;
+ } else {
+ if (findOverflow(32, %(result)s, %(inputa)s, %(inputb)s)) {
+ xer.ov = 1;
+ xer.so = 1;
+ } else {
+ xer.ov = 0;
+ }
+ }
+'''
+
+}};
+
+
+// A basic integer instruction.
+def format IntOp(code, inst_flags = []) {{
+ (header_output, decoder_output, decode_block, exec_output) = \
+ GenAluOp(name, Name, 'IntOp', code, inst_flags, BasicDecode,
+ BasicConstructor)
+}};
+
+
+// Integer instructions with immediate (signed or unsigned).
+def format IntImmOp(code, inst_flags = []) {{
+ (header_output, decoder_output, decode_block, exec_output) = \
+ GenAluOp(name, Name, 'IntImmOp', code, inst_flags, BasicDecode,
+ BasicConstructor)
+}};
+
+
+// Integer instructions with immediate that perform arithmetic.
+// These instructions all write to Rt and use an altered form of the
+// value in source register Ra, hence the use of src to hold the actual
+// value. The control flags include the use of code to compute the
+// carry bit or the CR0 code.
+def format IntImmArithOp(code, ctrl_flags = [], inst_flags = []) {{
+
+ # Set up the dictionary and deal with control flags
+ dict = {'result':'Rt', 'inputa':'src', 'inputb':'imm'}
+ if ctrl_flags:
+ code += readXERCode
+ for val in ctrl_flags:
+ if val == 'computeCA':
+ code += computeCACode % dict + setXERCode
+ elif val == 'computeCR0':
+ code += computeCR0Code % dict
+
+ # Generate the class
+ (header_output, decoder_output, decode_block, exec_output) = \
+ GenAluOp(name, Name, 'IntImmOp', code, inst_flags, BasicDecode,
+ BasicConstructor)
+}};
+
+
+// Integer instructions with immediate that perform arithmetic but use
+// the value 0 when Ra == 0. We generate two versions of each instruction
+// corresponding to these two different scenarios. The correct version is
+// determined at decode (see the CheckRaDecode template).
+def format IntImmArithCheckRaOp(code, code_ra0, inst_flags = []) {{
+
+ # First the version where Ra is non-zero
+ (header_output, decoder_output, decode_block, exec_output) = \
+ GenAluOp(name, Name, 'IntImmOp', code, inst_flags,
+ CheckRaDecode, BasicConstructor)
+
+ # Now another version where Ra == 0
+ (header_output_ra0, decoder_output_ra0, _, exec_output_ra0) = \
+ GenAluOp(name, Name + 'RaZero', 'IntImmOp', code_ra0, inst_flags,
+ CheckRaDecode, BasicConstructor)
+
+ # Finally, add to the other outputs
+ header_output += header_output_ra0
+ decoder_output += decoder_output_ra0
+ exec_output += exec_output_ra0
+}};
+
+
+// Integer instructions with immediate that perform logic operations.
+// All instructions write to Ra and use Rs as a source register. Some
+// also compute the CR0 code too.
+def format IntImmLogicOp(code, computeCR0 = 0, inst_flags = []) {{
+
+ # Set up the dictionary and deal with computing CR0
+ dict = {'result':'Ra'}
+ if computeCR0:
+ code += readXERCode + computeCR0Code % dict
+
+ # Generate the class
+ (header_output, decoder_output, decode_block, exec_output) = \
+ GenAluOp(name, Name, 'IntImmOp', code, inst_flags, BasicDecode,
+ BasicConstructor)
+}};
+
+
+// Integer instructions that perform logic operations. The result is
+// always written into Ra. All instructions have 2 versions depending on
+// whether the Rc bit is set to compute the CR0 code. This is determined
+// at decode as before.
+def format IntLogicOp(code, inst_flags = []) {{
+ dict = {'result':'Ra'}
+
+ # Code when Rc is set
+ code_rc1 = code + readXERCode + computeCR0Code % dict
+
+ # Generate the first class
+ (header_output, decoder_output, decode_block, exec_output) = \
+ GenAluOp(name, Name, 'IntOp', code, inst_flags,
+ CheckRcDecode, BasicConstructor)
+
+ # Generate the second class
+ (header_output_rc1, decoder_output_rc1, _, exec_output_rc1) = \
+ GenAluOp(name, Name + 'RcSet', 'IntOp', code_rc1, inst_flags,
+ CheckRcDecode, IntRcConstructor)
+
+ # Finally, add to the other outputs
+ header_output += header_output_rc1
+ decoder_output += decoder_output_rc1
+ exec_output += exec_output_rc1
+}};
+
+
+// Integer instructions with a shift amount. As above, except inheriting
+// from the IntShiftOp class.
+def format IntShiftOp(code, inst_flags = []) {{
+ dict = {'result':'Ra'}
+
+ # Code when Rc is set
+ code_rc1 = code + readXERCode + computeCR0Code % dict
+
+ # Generate the first class
+ (header_output, decoder_output, decode_block, exec_output) = \
+ GenAluOp(name, Name, 'IntShiftOp', code, inst_flags,
+ CheckRcDecode, BasicConstructor)
+
+ # Generate the second class
+ (header_output_rc1, decoder_output_rc1, _, exec_output_rc1) = \
+ GenAluOp(name, Name + 'RcSet', 'IntShiftOp', code_rc1, inst_flags,
+ CheckRcDecode, IntRcConstructor)
+
+ # Finally, add to the other outputs
+ header_output += header_output_rc1
+ decoder_output += decoder_output_rc1
+ exec_output += exec_output_rc1
+}};
+
+
+// Instructions in this format are all reduced to the form Rt = src1 + src2,
+// therefore we just give src1 and src2 definitions. In working out the
+// template we first put in the definitions of the variables and then
+// the code for the addition. We also deal with computing the carry flag
+// if required.
+//
+// We generate 4 versions of each instruction. This correspond to the
+// different combinations of having the OE bit set or unset (which controls
+// whether the overflow flag is computed) and the Rc bit set or unset too
+// (which controls whether the CR0 code is computed).
+def format IntSumOp(src1, src2, ca = {{ 0 }}, computeCA = 0,
+ inst_flags = []) {{
+
+ # The result is always in Rt, but the source values vary
+ dict = {'result':'Rt', 'inputa':'src1', 'inputb':'src2'}
+
+ # Add code to set up variables and do the sum
+ code = 'uint32_t src1 = ' + src1 + ';\n'
+ code += 'uint32_t src2 = ' + src2 + ';\n'
+ code += 'uint32_t ca = ' + ca + ';\n'
+ code += 'Rt = src1 + src2 + ca;\n'
+
+ # Add code for calculating the carry, if needed
+ if computeCA:
+ code += computeCACode % dict + setXERCode
+
+ # Setup the 4 code versions and add code to access XER if necessary
+ code_rc1 = readXERCode + code
+ code_oe1 = readXERCode + code + computeOVCode % dict + setXERCode
+ code_rc1_oe1 = readXERCode + code + computeOVCode % dict + setXERCode
+ if (computeCA or ca == 'xer.ca'):
+ code = readXERCode + code
+ code_rc1 += computeCR0Code % dict
+ code_rc1_oe1 += computeCR0Code % dict
+
+ # Generate the classes
+ (header_output, decoder_output, decode_block, exec_output) = \
+ GenAluOp(name, Name, 'IntOp', code, inst_flags,
+ CheckRcOeDecode, BasicConstructor)
+ (header_output_rc1, decoder_output_rc1, _, exec_output_rc1) = \
+ GenAluOp(name, Name + 'RcSet', 'IntOp', code_rc1, inst_flags,
+ CheckRcOeDecode, IntRcConstructor)
+ (header_output_oe1, decoder_output_oe1, _, exec_output_oe1) = \
+ GenAluOp(name, Name + 'OeSet', 'IntOp', code_oe1, inst_flags,
+ CheckRcOeDecode, IntOeConstructor)
+ (header_output_rc1_oe1, decoder_output_rc1_oe1, _, exec_output_rc1_oe1) = \
+ GenAluOp(name, Name + 'RcSetOeSet', 'IntOp', code_rc1_oe1,
+ inst_flags, CheckRcOeDecode, IntRcOeConstructor)
+
+ # Finally, add to the other outputs
+ header_output += \
+ header_output_rc1 + header_output_oe1 + header_output_rc1_oe1
+ decoder_output += \
+ decoder_output_rc1 + decoder_output_oe1 + decoder_output_rc1_oe1
+ exec_output += \
+ exec_output_rc1 + exec_output_oe1 + exec_output_rc1_oe1
+
+}};
+
+
+// Instructions that use source registers Ra and Rb, with the result
+// placed into Rt. Basically multiply and divide instructions. The
+// carry bit is never set, but overflow can be calculated. Division
+// explicitly sets the overflow bit in certain situations and this is
+// dealt with using the 'divSetOV' boolean in decoder.isa. We generate
+// two versions of each instruction to deal with the Rc bit.
+def format IntArithOp(code, computeOV = 0, inst_flags = []) {{
+
+ # The result is always in Rt, but the source values vary
+ dict = {'result':'Rt', 'inputa':'src1', 'inputb':'src2'}
+
+ # Deal with setting the overflow flag
+ if computeOV:
+ code = 'bool divSetOV = false;\n' + code
+ code += computeDivOVCode % dict + setXERCode
+
+ # Setup the 2 code versions and add code to access XER if necessary
+ code_rc1 = readXERCode + code + computeCR0Code % dict
+ if computeOV:
+ code = readXERCode + code
+
+ # Generate the classes
+ (header_output, decoder_output, decode_block, exec_output) = \
+ GenAluOp(name, Name, 'IntOp', code, inst_flags,
+ CheckRcDecode, BasicConstructor)
+
+ # Generate the second class
+ (header_output_rc1, decoder_output_rc1, _, exec_output_rc1) = \
+ GenAluOp(name, Name + 'RcSet', 'IntOp', code_rc1, inst_flags,
+ CheckRcDecode, IntRcConstructor)
+
+ # Finally, add to the other outputs
+ header_output += header_output_rc1
+ decoder_output += decoder_output_rc1
+ exec_output += exec_output_rc1
+}};
+
+
+// A special format for rotate instructions which use certain fields
+// from the instruction's binary encoding. We need two versions for each
+// instruction to deal with the Rc bit.
+def format IntRotateOp(code, inst_flags = []) {{
+
+ # The result is always in Ra
+ dict = {'result':'Ra'}
+
+ # Setup the code for when Rc is set
+ code_rc1 = readXERCode + code + computeCR0Code % dict
+
+ # Generate the first class
+ (header_output, decoder_output, decode_block, exec_output) = \
+ GenAluOp(name, Name, 'IntRotateOp', code, inst_flags,
+ CheckRcDecode, BasicConstructor)
+
+ # Generate the second class
+ (header_output_rc1, decoder_output_rc1, _, exec_output_rc1) = \
+ GenAluOp(name, Name + 'RcSet', 'IntRotateOp', code_rc1, inst_flags,
+ CheckRcDecode, IntRcConstructor)
+
+ # Finally, add to the other outputs
+ header_output += header_output_rc1
+ decoder_output += decoder_output_rc1
+ exec_output += exec_output_rc1
+}};
diff --git a/src/arch/power/isa/formats/mem.isa b/src/arch/power/isa/formats/mem.isa
new file mode 100644
index 000000000..1be49c2f7
--- /dev/null
+++ b/src/arch/power/isa/formats/mem.isa
@@ -0,0 +1,351 @@
+// -*- 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
+
+////////////////////////////////////////////////////////////////////
+//
+// Memory-format instructions
+//
+
+def template LoadStoreDeclare {{
+ /**
+ * Static instruction class for "%(mnemonic)s".
+ */
+ class %(class_name)s : public %(base_class)s
+ {
+ public:
+
+ /// Constructor.
+ %(class_name)s(ExtMachInst machInst);
+
+ %(BasicExecDeclare)s
+
+ %(InitiateAccDeclare)s
+
+ %(CompleteAccDeclare)s
+ };
+}};
+
+
+def template InitiateAccDeclare {{
+ Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const;
+}};
+
+
+def template CompleteAccDeclare {{
+ Fault completeAcc(PacketPtr, %(CPU_exec_context)s *, Trace::InstRecord *) const;
+}};
+
+
+def template LoadStoreConstructor {{
+ inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
+ : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
+ {
+ %(constructor)s;
+ }
+}};
+
+
+def template LoadExecute {{
+ Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
+ Trace::InstRecord *traceData) const
+ {
+ Addr EA;
+ Fault fault = NoFault;
+
+ %(op_decl)s;
+ %(op_rd)s;
+ %(ea_code)s;
+
+ if (fault == NoFault) {
+ fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags);
+ %(memacc_code)s;
+ }
+
+ if (fault == NoFault) {
+ %(op_wb)s;
+ }
+
+ return fault;
+ }
+}};
+
+
+def template LoadInitiateAcc {{
+ Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
+ Trace::InstRecord *traceData) const
+ {
+ Addr EA;
+ Fault fault = NoFault;
+
+ %(op_src_decl)s;
+ %(op_rd)s;
+ %(ea_code)s;
+
+ if (fault == NoFault) {
+ fault = xc->read(EA, (uint%(mem_acc_size)d_t &)Mem, memAccessFlags);
+ xc->setEA(EA);
+ }
+
+ return fault;
+ }
+}};
+
+
+def template LoadCompleteAcc {{
+ Fault %(class_name)s::completeAcc(PacketPtr pkt,
+ %(CPU_exec_context)s *xc,
+ Trace::InstRecord *traceData) const
+ {
+ Addr EA;
+ Fault fault = NoFault;
+ uint%(mem_acc_size)d_t val;
+
+ %(op_decl)s;
+ %(op_rd)s;
+
+ EA = xc->getEA();
+
+ val = pkt->get<uint%(mem_acc_size)d_t>();
+ *((uint%(mem_acc_size)d_t*)&Mem) = val;
+
+ if (fault == NoFault) {
+ %(memacc_code)s;
+ }
+
+ if (fault == NoFault) {
+ %(op_wb)s;
+ }
+
+ return fault;
+ }
+}};
+
+
+def template StoreExecute {{
+ Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
+ Trace::InstRecord *traceData) const
+ {
+ Addr EA;
+ Fault fault = NoFault;
+
+ %(op_decl)s;
+ %(op_rd)s;
+ %(ea_code)s;
+
+ if (fault == NoFault) {
+ %(memacc_code)s;
+ }
+
+ if (fault == NoFault) {
+ fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
+ memAccessFlags, NULL);
+ if (traceData) { traceData->setData(Mem); }
+ }
+
+ if (fault == NoFault) {
+ %(op_wb)s;
+ }
+
+ return fault;
+ }
+}};
+
+
+def template StoreInitiateAcc {{
+ Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
+ Trace::InstRecord *traceData) const
+ {
+ Addr EA;
+ Fault fault = NoFault;
+
+ %(op_decl)s;
+ %(op_rd)s;
+ %(ea_code)s;
+
+ if (fault == NoFault) {
+ %(memacc_code)s;
+ }
+
+ if (fault == NoFault) {
+ fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
+ memAccessFlags, NULL);
+ if (traceData) { traceData->setData(Mem); }
+ }
+
+ // Need to write back any potential address register update
+ if (fault == NoFault) {
+ %(op_wb)s;
+ }
+
+ return fault;
+ }
+}};
+
+
+def template StoreCompleteAcc {{
+ Fault %(class_name)s::completeAcc(PacketPtr pkt,
+ %(CPU_exec_context)s *xc,
+ Trace::InstRecord *traceData) const
+ {
+ Fault fault = NoFault;
+
+ %(op_dest_decl)s;
+
+ if (fault == NoFault) {
+ %(op_wb)s;
+ }
+
+ return fault;
+ }
+}};
+
+
+// The generic memory operation generator. This is called when two versions
+// of an instruction are needed - when Ra == 0 and otherwise. This is so
+// that instructions can use the value 0 when Ra == 0 but avoid having a
+// dependence on Ra.
+let {{
+
+def GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0, base,
+ load_or_store, mem_flags = [], inst_flags = []):
+
+ # First the version where Ra is non-zero
+ (header_output, decoder_output, decode_block, exec_output) = \
+ LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
+ base_class = base,
+ decode_template = CheckRaDecode,
+ exec_template_base = load_or_store)
+
+ # Now another version where Ra == 0
+ (header_output_ra0, decoder_output_ra0, _, exec_output_ra0) = \
+ LoadStoreBase(name, Name + 'RaZero', ea_code_ra0, memacc_code,
+ mem_flags, inst_flags,
+ base_class = base,
+ exec_template_base = load_or_store)
+
+ # Finally, add to the other outputs
+ header_output += header_output_ra0
+ decoder_output += decoder_output_ra0
+ exec_output += exec_output_ra0
+ return (header_output, decoder_output, decode_block, exec_output)
+
+}};
+
+
+def format LoadIndexOp(memacc_code, ea_code = {{ EA = Ra + Rb; }},
+ ea_code_ra0 = {{ EA = Rb; }},
+ mem_flags = [], inst_flags = []) {{
+ (header_output, decoder_output, decode_block, exec_output) = \
+ GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0,
+ 'MemOp', 'Load', mem_flags, inst_flags)
+}};
+
+
+def format StoreIndexOp(memacc_code, ea_code = {{ EA = Ra + Rb; }},
+ ea_code_ra0 = {{ EA = Rb; }},
+ mem_flags = [], inst_flags = []) {{
+ (header_output, decoder_output, decode_block, exec_output) = \
+ GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0,
+ 'MemOp', 'Store', mem_flags, inst_flags)
+}};
+
+
+def format LoadIndexUpdateOp(memacc_code, ea_code = {{ EA = Ra + Rb; }},
+ mem_flags = [], inst_flags = []) {{
+
+ # Add in the update code
+ memacc_code += 'Ra = EA;'
+
+ # Generate the class
+ (header_output, decoder_output, decode_block, exec_output) = \
+ LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
+ base_class = 'MemOp',
+ exec_template_base = 'Load')
+}};
+
+
+def format StoreIndexUpdateOp(memacc_code, ea_code = {{ EA = Ra + Rb; }},
+ mem_flags = [], inst_flags = []) {{
+
+ # Add in the update code
+ memacc_code += 'Ra = EA;'
+
+ # Generate the class
+ (header_output, decoder_output, decode_block, exec_output) = \
+ LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
+ base_class = 'MemOp',
+ exec_template_base = 'Store')
+}};
+
+
+def format LoadDispOp(memacc_code, ea_code = {{ EA = Ra + disp; }},
+ ea_code_ra0 = {{ EA = disp; }},
+ mem_flags = [], inst_flags = []) {{
+ (header_output, decoder_output, decode_block, exec_output) = \
+ GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0,
+ 'MemDispOp', 'Load', mem_flags, inst_flags)
+}};
+
+
+def format StoreDispOp(memacc_code, ea_code = {{ EA = Ra + disp; }},
+ ea_code_ra0 = {{ EA = disp; }},
+ mem_flags = [], inst_flags = []) {{
+ (header_output, decoder_output, decode_block, exec_output) = \
+ GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0,
+ 'MemDispOp', 'Store', mem_flags, inst_flags)
+}};
+
+
+def format LoadDispUpdateOp(memacc_code, ea_code = {{ EA = Ra + disp; }},
+ mem_flags = [], inst_flags = []) {{
+
+ # Add in the update code
+ memacc_code += 'Ra = EA;'
+
+ # Generate the class
+ (header_output, decoder_output, decode_block, exec_output) = \
+ LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
+ base_class = 'MemDispOp',
+ exec_template_base = 'Load')
+}};
+
+
+def format StoreDispUpdateOp(memacc_code, ea_code = {{ EA = Ra + disp; }},
+ mem_flags = [], inst_flags = []) {{
+
+ # Add in the update code
+ memacc_code += 'Ra = EA;'
+
+ # Generate the class
+ (header_output, decoder_output, decode_block, exec_output) = \
+ LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
+ base_class = 'MemDispOp',
+ exec_template_base = 'Store')
+}};
diff --git a/src/arch/power/isa/formats/misc.isa b/src/arch/power/isa/formats/misc.isa
new file mode 100644
index 000000000..93536aa18
--- /dev/null
+++ b/src/arch/power/isa/formats/misc.isa
@@ -0,0 +1,61 @@
+// -*- 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
+
+////////////////////////////////////////////////////////////////////
+//
+// Misc instructions
+//
+
+def template MiscOpExecute {{
+ Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
+ {
+ Fault fault = NoFault;
+ %(op_decl)s;
+ %(op_rd)s;
+
+ %(code)s;
+ if (fault == NoFault)
+ {
+ %(op_wb)s;
+ }
+
+ return fault;
+ }
+}};
+
+def format MiscOp(code, opt_flags = []) {{
+ iop = InstObjParams(name, Name, 'IntOp',
+ {"code": code},
+ opt_flags)
+ header_output = BasicDeclare.subst(iop)
+ decoder_output = BasicConstructor.subst(iop)
+ decode_block = BasicDecode.subst(iop)
+ exec_output = MiscOpExecute.subst(iop)
+}};
diff --git a/src/arch/power/isa/formats/unimp.isa b/src/arch/power/isa/formats/unimp.isa
new file mode 100644
index 000000000..60a7c469d
--- /dev/null
+++ b/src/arch/power/isa/formats/unimp.isa
@@ -0,0 +1,146 @@
+// -*- mode:c++ -*-
+
+// Copyright (c) 2007-2008 The Florida State University
+// 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: Stephen Hines
+// Timothy M. Jones
+
+////////////////////////////////////////////////////////////////////
+//
+// Unimplemented instructions
+//
+
+output header {{
+ /**
+ * Static instruction class for unimplemented instructions that
+ * cause simulator termination. Note that these are recognized
+ * (legal) instructions that the simulator does not support; the
+ * 'Unknown' class is used for unrecognized/illegal instructions.
+ * This is a leaf class.
+ */
+ class FailUnimplemented : public PowerStaticInst
+ {
+ public:
+ /// Constructor
+ FailUnimplemented(const char *_mnemonic, MachInst _machInst)
+ : PowerStaticInst(_mnemonic, _machInst, No_OpClass)
+ {
+ // don't call execute() (which panics) if we're on a
+ // speculative path
+ flags[IsNonSpeculative] = true;
+ }
+
+ %(BasicExecDeclare)s
+
+ std::string
+ generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+ };
+
+ /**
+ * Base class for unimplemented instructions that cause a warning
+ * to be printed (but do not terminate simulation). This
+ * implementation is a little screwy in that it will print a
+ * warning for each instance of a particular unimplemented machine
+ * instruction, not just for each unimplemented opcode. Should
+ * probably make the 'warned' flag a static member of the derived
+ * class.
+ */
+ class WarnUnimplemented : public PowerStaticInst
+ {
+ private:
+ /// Have we warned on this instruction yet?
+ mutable bool warned;
+
+ public:
+ /// Constructor
+ WarnUnimplemented(const char *_mnemonic, MachInst _machInst)
+ : PowerStaticInst(_mnemonic, _machInst, No_OpClass), warned(false)
+ {
+ // don't call execute() (which panics) if we're on a
+ // speculative path
+ flags[IsNonSpeculative] = true;
+ }
+
+ %(BasicExecDeclare)s
+
+ std::string
+ generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+ };
+}};
+
+output decoder {{
+ std::string
+ FailUnimplemented::generateDisassembly(Addr pc,
+ const SymbolTable *symtab) const
+ {
+ return csprintf("%-10s (unimplemented)", mnemonic);
+ }
+
+ std::string
+ WarnUnimplemented::generateDisassembly(Addr pc,
+ const SymbolTable *symtab) const
+ {
+ return csprintf("%-10s (unimplemented)", mnemonic);
+ }
+}};
+
+output exec {{
+ Fault
+ FailUnimplemented::execute(%(CPU_exec_context)s *xc,
+ Trace::InstRecord *traceData) const
+ {
+ panic("attempt to execute unimplemented instruction '%s' "
+ "(inst 0x%08x, opcode 0x%x, binary:%s)", mnemonic, machInst, OPCODE,
+ inst2string(machInst));
+ return new UnimplementedOpcodeFault;
+ }
+
+ Fault
+ WarnUnimplemented::execute(%(CPU_exec_context)s *xc,
+ Trace::InstRecord *traceData) const
+ {
+ if (!warned) {
+ warn("\tinstruction '%s' unimplemented\n", mnemonic);
+ warned = true;
+ }
+
+ return NoFault;
+ }
+}};
+
+
+def format FailUnimpl() {{
+ iop = InstObjParams(name, 'FailUnimplemented')
+ decode_block = BasicDecodeWithMnemonic.subst(iop)
+}};
+
+def format WarnUnimpl() {{
+ iop = InstObjParams(name, 'WarnUnimplemented')
+ decode_block = BasicDecodeWithMnemonic.subst(iop)
+}};
+
diff --git a/src/arch/power/isa/formats/unknown.isa b/src/arch/power/isa/formats/unknown.isa
new file mode 100644
index 000000000..06e6ece26
--- /dev/null
+++ b/src/arch/power/isa/formats/unknown.isa
@@ -0,0 +1,87 @@
+// -*- mode:c++ -*-
+
+// Copyright (c) 2007-2008 The Florida State University
+// 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: Stephen Hines
+// Timothy M. Jones
+
+////////////////////////////////////////////////////////////////////
+//
+// Unknown instructions
+//
+
+output header {{
+ /**
+ * Static instruction class for unknown (illegal) instructions.
+ * These cause simulator termination if they are executed in a
+ * non-speculative mode. This is a leaf class.
+ */
+ class Unknown : public PowerStaticInst
+ {
+ public:
+ /// Constructor
+ Unknown(ExtMachInst _machInst)
+ : PowerStaticInst("unknown", _machInst, No_OpClass)
+ {
+ // don't call execute() (which panics) if we're on a
+ // speculative path
+ flags[IsNonSpeculative] = true;
+ }
+
+ %(BasicExecDeclare)s
+
+ std::string
+ generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+ };
+}};
+
+output decoder {{
+ std::string
+ Unknown::generateDisassembly(Addr pc, const SymbolTable *symtab) const
+ {
+ return csprintf("%-10s (inst 0x%x, opcode 0x%x, binary:%s)",
+ "unknown", machInst, OPCODE, inst2string(machInst));
+ }
+}};
+
+output exec {{
+ Fault
+ Unknown::execute(%(CPU_exec_context)s *xc,
+ Trace::InstRecord *traceData) const
+ {
+ panic("attempt to execute unknown instruction at %#x"
+ "(inst 0x%08x, opcode 0x%x, binary: %s)",
+ xc->readPC(), machInst, OPCODE, inst2string(machInst));
+ return new UnimplementedOpcodeFault;
+ }
+}};
+
+def format Unknown() {{
+ decode_block = 'return new Unknown(machInst);\n'
+}};
+
diff --git a/src/arch/power/isa/formats/util.isa b/src/arch/power/isa/formats/util.isa
new file mode 100644
index 000000000..ab1e530b2
--- /dev/null
+++ b/src/arch/power/isa/formats/util.isa
@@ -0,0 +1,174 @@
+// -*- mode:c++ -*-
+
+// Copyright (c) 2003-2005 The Regents of The University of Michigan
+// 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: Steve Reinhardt
+// Korey Sewell
+// Timothy M. Jones
+
+// Some instructions ignore the contents of Ra if Ra == 0,
+// so check for this.
+def template CheckRaDecode {{
+ {
+ if (RA == 0) {
+ return new %(class_name)sRaZero(machInst);
+ } else {
+ return new %(class_name)s(machInst);
+ }
+ }
+}};
+
+
+// Some instructions have extra behaviour if Rc is set.
+def template CheckRcDecode {{
+ {
+ if (RC31 == 0) {
+ return new %(class_name)s(machInst);
+ } else {
+ return new %(class_name)sRcSet(machInst);
+ }
+ }
+}};
+
+
+// Some instructions have extra behaviour if Rc and OE are set.
+def template CheckRcOeDecode {{
+ {
+ if (RC31 == 0) {
+ if (OE == 0) {
+ return new %(class_name)s(machInst);
+ } else {
+ return new %(class_name)sOeSet(machInst);
+ }
+ } else {
+ if (OE == 0) {
+ return new %(class_name)sRcSet(machInst);
+ } else {
+ return new %(class_name)sRcSetOeSet(machInst);
+ }
+ }
+ }
+}};
+
+// Branch instructions always have two versions, one which sets the link
+// register (LR).
+def template CheckLkDecode {{
+ {
+ if (LK == 0) {
+ return new %(class_name)s(machInst);
+ } else {
+ return new %(class_name)sUpdateLr(machInst);
+ }
+ }
+}};
+
+
+let {{
+
+def LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
+ base_class = 'MemOp',
+ decode_template = BasicDecode, exec_template_base = ''):
+ # Make sure flags are in lists (convert to lists if not).
+ mem_flags = makeList(mem_flags)
+ inst_flags = makeList(inst_flags)
+
+ # add hook to get effective addresses into execution trace output.
+ ea_code += '\nif (traceData) { traceData->setAddr(EA); }\n'
+
+ # Generate InstObjParams for the memory access.
+ iop = InstObjParams(name, Name, base_class,
+ {'ea_code': ea_code,
+ 'memacc_code': memacc_code},
+ inst_flags)
+
+ if mem_flags:
+ s = '\n\tmemAccessFlags = ' + string.join(mem_flags, '|') + ';'
+ iop.constructor += s
+
+ fullExecTemplate = eval(exec_template_base + 'Execute')
+ initiateAccTemplate = eval(exec_template_base + 'InitiateAcc')
+ completeAccTemplate = eval(exec_template_base + 'CompleteAcc')
+
+ # (header_output, decoder_output, decode_block, exec_output)
+ return (LoadStoreDeclare.subst(iop),
+ LoadStoreConstructor.subst(iop),
+ decode_template.subst(iop),
+ fullExecTemplate.subst(iop)
+ + initiateAccTemplate.subst(iop)
+ + completeAccTemplate.subst(iop))
+
+
+# The generic ALU instruction generator. Integer and fp formats calls this
+# to generate the different output sections.
+def GenAluOp(name, Name, base_class, code, inst_flags, decode_template,
+ constructor_template):
+ iop = InstObjParams(name, Name, base_class,
+ {"code": code},
+ inst_flags)
+ header_output = BasicDeclare.subst(iop)
+ exec_output = BasicExecute.subst(iop)
+
+ # We use constructors dependent on the Rc and OE bits being set
+ decoder_output = constructor_template.subst(iop)
+
+ # The decode block defines which version to use
+ decode_block = decode_template.subst(iop)
+ return (header_output, decoder_output, decode_block, exec_output)
+
+}};
+
+
+output header {{
+ std::string
+ inst2string(MachInst machInst);
+}};
+
+output decoder {{
+
+ std::string
+ inst2string(MachInst machInst)
+ {
+ std::string str = "";
+ uint32_t mask = 0x80000000;
+
+ for(int i=0; i < 32; i++) {
+ if ((machInst & mask) == 0) {
+ str += "0";
+ } else {
+ str += "1";
+ }
+
+ mask = mask >> 1;
+ }
+
+ return str;
+ }
+
+}};
+
+
diff --git a/src/arch/power/isa/includes.isa b/src/arch/power/isa/includes.isa
new file mode 100644
index 000000000..47e8c1411
--- /dev/null
+++ b/src/arch/power/isa/includes.isa
@@ -0,0 +1,92 @@
+// -*- 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
+
+////////////////////////////////////////////////////////////////////
+//
+// Output include file directives.
+//
+
+output header {{
+#include <sstream>
+#include <iostream>
+#include <iomanip>
+
+#include "arch/power/insts/branch.hh"
+#include "arch/power/insts/mem.hh"
+#include "arch/power/insts/integer.hh"
+#include "arch/power/insts/floating.hh"
+#include "arch/power/insts/condition.hh"
+#include "arch/power/insts/misc.hh"
+#include "arch/power/insts/static_inst.hh"
+#include "arch/power/isa_traits.hh"
+#include "cpu/static_inst.hh"
+#include "mem/packet.hh"
+
+using namespace PowerISA;
+}};
+
+output decoder {{
+#include <cmath>
+#if defined(linux)
+#include <fenv.h>
+#endif
+
+#include "arch/power/faults.hh"
+#include "arch/power/isa_traits.hh"
+#include "arch/power/utility.hh"
+#include "base/cprintf.hh"
+#include "base/loader/symtab.hh"
+#include "cpu/thread_context.hh"
+
+using namespace PowerISA;
+using std::isnan;
+}};
+
+output exec {{
+#include "arch/power/faults.hh"
+#include "arch/power/isa_traits.hh"
+#include "arch/power/utility.hh"
+
+#include <cmath>
+#if defined(linux)
+#include <fenv.h>
+#endif
+
+#include "base/condcodes.hh"
+#include "cpu/base.hh"
+#include "cpu/exetrace.hh"
+#include "mem/packet.hh"
+#include "mem/packet_access.hh"
+#include "sim/sim_exit.hh"
+
+using namespace PowerISA;
+using std::isnan;
+}};
+
diff --git a/src/arch/power/isa/main.isa b/src/arch/power/isa/main.isa
new file mode 100644
index 000000000..cce7e39ee
--- /dev/null
+++ b/src/arch/power/isa/main.isa
@@ -0,0 +1,57 @@
+// -*- 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
+
+////////////////////////////////////////////////////////////////////
+//
+// Power ISA description file.
+//
+////////////////////////////////////////////////////////////////////
+
+//Include the C++ include directives
+##include "includes.isa"
+
+////////////////////////////////////////////////////////////////////
+//
+// Namespace statement. Everything below this line will be in the
+// PowerISAInst namespace.
+//
+namespace PowerISA;
+
+//Include the bitfield definitions
+##include "bitfields.isa"
+
+//Include the operand_types and operand definitions
+##include "operands.isa"
+
+//Include the definitions for the instruction formats
+##include "formats/formats.isa"
+
+//Include the decoder definition
+##include "decoder.isa"
diff --git a/src/arch/power/isa/operands.isa b/src/arch/power/isa/operands.isa
new file mode 100644
index 000000000..fc6c32685
--- /dev/null
+++ b/src/arch/power/isa/operands.isa
@@ -0,0 +1,81 @@
+// -*- 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
+
+def operand_types {{
+ 'sb' : ('signed int', 8),
+ 'ub' : ('unsigned int', 8),
+ 'sh' : ('signed int', 16),
+ 'uh' : ('unsigned int', 16),
+ 'sw' : ('signed int', 32),
+ 'uw' : ('unsigned int', 32),
+ 'sq' : ('signed int', 64),
+ 'uq' : ('unsigned int', 64),
+ 'sf' : ('float', 32),
+ 'df' : ('float', 64)
+}};
+
+def operands {{
+ # General Purpose Integer Reg Operands
+ 'Ra': ('IntReg', 'uw', 'RA', 'IsInteger', 1),
+ 'Rb': ('IntReg', 'uw', 'RB', 'IsInteger', 2),
+ 'Rs': ('IntReg', 'uw', 'RS', 'IsInteger', 3),
+ 'Rt': ('IntReg', 'uw', 'RT', 'IsInteger', 4),
+
+ # General Purpose Floating Point Reg Operands
+ 'Fa': ('FloatReg', 'df', 'FRA', 'IsFloating', 1),
+ 'Fb': ('FloatReg', 'df', 'FRB', 'IsFloating', 2),
+ 'Fc': ('FloatReg', 'df', 'FRC', 'IsFloating', 3),
+ 'Fs': ('FloatReg', 'df', 'FRS', 'IsFloating', 4),
+ 'Ft': ('FloatReg', 'df', 'FRT', 'IsFloating', 5),
+
+ # Memory Operand
+ 'Mem': ('Mem', 'uw', None, ('IsMemRef', 'IsLoad', 'IsStore'), 8),
+
+ # Program counter and next
+ 'PC': ('PC', 'uw', None, (None, None, 'IsControl'), 9),
+ 'NPC': ('NPC', 'uw', None, (None, None, 'IsControl'), 9),
+
+ # Control registers
+ 'CR': ('IntReg', 'uw', 'INTREG_CR', 'IsInteger', 9),
+ 'LR': ('IntReg', 'uw', 'INTREG_LR', 'IsInteger', 9),
+ 'CTR': ('IntReg', 'uw', 'INTREG_CTR', 'IsInteger', 9),
+ 'XER': ('IntReg', 'uw', 'INTREG_XER', 'IsInteger', 9),
+
+ # Setting as IntReg so things are stored as an integer, not double
+ 'FPSCR': ('IntReg', 'uw', 'INTREG_FPSCR', 'IsFloating', 9),
+
+ # Registers for linked loads and stores
+ 'Rsv': ('IntReg', 'uw', 'INTREG_RSV', 'IsInteger', 9),
+ 'RsvLen': ('IntReg', 'uw', 'INTREG_RSV_LEN', 'IsInteger', 9),
+ 'RsvAddr': ('IntReg', 'uw', 'INTREG_RSV_ADDR', 'IsInteger', 9),
+
+ # Hack for non-full-system syscall emulation
+ 'R0': ('IntReg', 'uw', '0', None, 1),
+}};