POWER: Add support for the Power ISA
authorTimothy M. Jones <tjones1@inf.ed.ac.uk>
Tue, 27 Oct 2009 16:24:39 +0000 (09:24 -0700)
committerTimothy M. Jones <tjones1@inf.ed.ac.uk>
Tue, 27 Oct 2009 16:24:39 +0000 (09:24 -0700)
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.

63 files changed:
build_opts/POWER_SE [new file with mode: 0644]
src/arch/isa_parser.py
src/arch/power/PowerTLB.py [new file with mode: 0644]
src/arch/power/SConscript [new file with mode: 0644]
src/arch/power/SConsopts [new file with mode: 0644]
src/arch/power/faults.hh [new file with mode: 0644]
src/arch/power/insts/branch.cc [new file with mode: 0644]
src/arch/power/insts/branch.hh [new file with mode: 0644]
src/arch/power/insts/condition.cc [new file with mode: 0644]
src/arch/power/insts/condition.hh [new file with mode: 0644]
src/arch/power/insts/floating.cc [new file with mode: 0644]
src/arch/power/insts/floating.hh [new file with mode: 0644]
src/arch/power/insts/integer.cc [new file with mode: 0644]
src/arch/power/insts/integer.hh [new file with mode: 0644]
src/arch/power/insts/mem.cc [new file with mode: 0644]
src/arch/power/insts/mem.hh [new file with mode: 0644]
src/arch/power/insts/misc.cc [new file with mode: 0644]
src/arch/power/insts/misc.hh [new file with mode: 0644]
src/arch/power/insts/static_inst.cc [new file with mode: 0644]
src/arch/power/insts/static_inst.hh [new file with mode: 0644]
src/arch/power/isa.hh [new file with mode: 0644]
src/arch/power/isa/bitfields.isa [new file with mode: 0644]
src/arch/power/isa/decoder.isa [new file with mode: 0644]
src/arch/power/isa/formats/basic.isa [new file with mode: 0644]
src/arch/power/isa/formats/branch.isa [new file with mode: 0644]
src/arch/power/isa/formats/condition.isa [new file with mode: 0644]
src/arch/power/isa/formats/formats.isa [new file with mode: 0644]
src/arch/power/isa/formats/fp.isa [new file with mode: 0644]
src/arch/power/isa/formats/integer.isa [new file with mode: 0644]
src/arch/power/isa/formats/mem.isa [new file with mode: 0644]
src/arch/power/isa/formats/misc.isa [new file with mode: 0644]
src/arch/power/isa/formats/unimp.isa [new file with mode: 0644]
src/arch/power/isa/formats/unknown.isa [new file with mode: 0644]
src/arch/power/isa/formats/util.isa [new file with mode: 0644]
src/arch/power/isa/includes.isa [new file with mode: 0644]
src/arch/power/isa/main.isa [new file with mode: 0644]
src/arch/power/isa/operands.isa [new file with mode: 0644]
src/arch/power/isa_traits.hh [new file with mode: 0644]
src/arch/power/linux/linux.cc [new file with mode: 0644]
src/arch/power/linux/linux.hh [new file with mode: 0644]
src/arch/power/linux/process.cc [new file with mode: 0644]
src/arch/power/linux/process.hh [new file with mode: 0644]
src/arch/power/locked_mem.hh [new file with mode: 0644]
src/arch/power/microcode_rom.hh [new file with mode: 0644]
src/arch/power/miscregs.hh [new file with mode: 0644]
src/arch/power/mmaped_ipr.hh [new file with mode: 0644]
src/arch/power/pagetable.cc [new file with mode: 0644]
src/arch/power/pagetable.hh [new file with mode: 0644]
src/arch/power/predecoder.hh [new file with mode: 0644]
src/arch/power/process.cc [new file with mode: 0644]
src/arch/power/process.hh [new file with mode: 0644]
src/arch/power/registers.hh [new file with mode: 0644]
src/arch/power/remote_gdb.hh [new file with mode: 0644]
src/arch/power/stacktrace.hh [new file with mode: 0644]
src/arch/power/tlb.cc [new file with mode: 0644]
src/arch/power/tlb.hh [new file with mode: 0644]
src/arch/power/types.hh [new file with mode: 0644]
src/arch/power/utility.hh [new file with mode: 0644]
src/arch/power/vtophys.hh [new file with mode: 0644]
src/base/loader/elf_object.cc
src/base/loader/object_file.hh
src/cpu/BaseCPU.py
src/sim/process.cc

diff --git a/build_opts/POWER_SE b/build_opts/POWER_SE
new file mode 100644 (file)
index 0000000..d76ca71
--- /dev/null
@@ -0,0 +1,3 @@
+TARGET_ISA = 'power'
+FULL_SYSTEM = 0
+CPU_MODELS = 'AtomicSimpleCPU,TimingSimpleCPU,O3CPU'
index f001eff41c1f49c7ee7ebe8f0dd4b32e602eb217..e3da240d2550774ad4fc9fb558ed5bf4fe0d1be7 100755 (executable)
@@ -1465,6 +1465,16 @@ class MemOperand(Operand):
     def makeAccSize(self):
         return self.size
 
+class PCOperand(Operand):
+    def makeConstructor(self):
+        return ''
+
+    def makeRead(self):
+        return '%s = xc->readPC();\n' % self.base_name
+
+    def makeWrite(self):
+        return 'xc->setPC(%s);\n' % self.base_name
+
 class UPCOperand(Operand):
     def makeConstructor(self):
         return ''
diff --git a/src/arch/power/PowerTLB.py b/src/arch/power/PowerTLB.py
new file mode 100644 (file)
index 0000000..36dff53
--- /dev/null
@@ -0,0 +1,37 @@
+# -*- mode:python -*-
+
+# 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
+
+from m5.SimObject import SimObject
+from m5.params import *
+
+class PowerTLB(SimObject):
+    type = 'PowerTLB'
+    cxx_class = 'PowerISA::TLB'
+    size = Param.Int(64, "TLB size")
diff --git a/src/arch/power/SConscript b/src/arch/power/SConscript
new file mode 100644 (file)
index 0000000..1fb36ea
--- /dev/null
@@ -0,0 +1,61 @@
+# -*- mode:python -*-
+
+# 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
+
+Import('*')
+
+if env['TARGET_ISA'] == 'power':
+# Workaround for bug in SCons version > 0.97d20071212
+# Scons bug id: 2006 M5 Bug id: 308 
+    Dir('isa/formats')
+    Source('insts/branch.cc')
+    Source('insts/mem.cc')
+    Source('insts/integer.cc')
+    Source('insts/floating.cc')
+    Source('insts/condition.cc')
+    Source('insts/static_inst.cc')
+    Source('pagetable.cc')
+    Source('tlb.cc')
+
+    SimObject('PowerTLB.py')
+    TraceFlag('Power')
+
+    if not env['FULL_SYSTEM']:
+        Source('process.cc')
+        Source('linux/linux.cc')
+        Source('linux/process.cc')
+
+    # Add in files generated by the ISA description.
+    isa_desc_files = env.ISADesc('isa/main.isa')
+
+    # Only non-header files need to be compiled.
+    for f in isa_desc_files:
+        if not f.path.endswith('.hh'):
+            Source(f)
+
diff --git a/src/arch/power/SConsopts b/src/arch/power/SConsopts
new file mode 100644 (file)
index 0000000..d762c2d
--- /dev/null
@@ -0,0 +1,33 @@
+# -*- mode:python -*-
+
+# 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
+
+Import('*')
+
+all_isa_list.append('power')
diff --git a/src/arch/power/faults.hh b/src/arch/power/faults.hh
new file mode 100644 (file)
index 0000000..eadcb79
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+ * 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: Gabe Black
+ *          Timothy M. Jones
+ */
+
+#ifndef __ARCH_POWER_FAULTS_HH__
+#define __ARCH_POWER_FAULTS_HH__
+
+#include "sim/faults.hh"
+
+namespace PowerISA
+{
+
+class PowerFault : public FaultBase
+{
+  protected:
+    FaultName _name;
+
+    PowerFault(FaultName name)
+        : _name(name)
+    {
+    }
+
+    FaultName
+    name() const
+    {
+        return _name;
+    }
+};
+
+
+class UnimplementedOpcodeFault : public PowerFault
+{
+  public:
+    UnimplementedOpcodeFault()
+        : PowerFault("Unimplemented Opcode")
+    {
+    }
+};
+
+
+class MachineCheckFault : public PowerFault
+{
+  public:
+    MachineCheckFault()
+        : PowerFault("Machine Check")
+    {
+    }
+};
+
+
+static inline Fault
+genMachineCheckFault()
+{
+    return new MachineCheckFault();
+}
+
+} // PowerISA namespace
+
+#endif // __ARCH_POWER_FAULTS_HH__
diff --git a/src/arch/power/insts/branch.cc b/src/arch/power/insts/branch.cc
new file mode 100644 (file)
index 0000000..3f4346c
--- /dev/null
@@ -0,0 +1,169 @@
+/*
+ * 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
+ */
+
+#include "arch/power/insts/branch.hh"
+#include "base/loader/symtab.hh"
+
+using namespace PowerISA;
+
+const std::string &
+PCDependentDisassembly::disassemble(Addr pc, const SymbolTable *symtab) const
+{
+    if (!cachedDisassembly ||
+        pc != cachedPC || symtab != cachedSymtab)
+    {
+        if (cachedDisassembly)
+            delete cachedDisassembly;
+
+        cachedDisassembly =
+            new std::string(generateDisassembly(pc, symtab));
+        cachedPC = pc;
+        cachedSymtab = symtab;
+    }
+
+    return *cachedDisassembly;
+}
+
+Addr
+BranchPCRel::branchTarget(Addr pc) const
+{
+    return (uint32_t)(pc + disp);
+}
+
+std::string
+BranchPCRel::generateDisassembly(Addr pc, const SymbolTable *symtab) const
+{
+    std::stringstream ss;
+
+    ccprintf(ss, "%-10s ", mnemonic);
+
+    Addr target = pc + disp;
+
+    std::string str;
+    if (symtab && symtab->findSymbol(target, str))
+        ss << str;
+    else
+        ccprintf(ss, "0x%x", target);
+
+    return ss.str();
+}
+
+Addr
+BranchNonPCRel::branchTarget(Addr pc) const
+{
+    return targetAddr;
+}
+
+std::string
+BranchNonPCRel::generateDisassembly(Addr pc, const SymbolTable *symtab) const
+{
+    std::stringstream ss;
+
+    ccprintf(ss, "%-10s ", mnemonic);
+
+    std::string str;
+    if (symtab && symtab->findSymbol(targetAddr, str))
+        ss << str;
+    else
+        ccprintf(ss, "0x%x", targetAddr);
+
+    return ss.str();
+}
+
+Addr
+BranchPCRelCond::branchTarget(Addr pc) const
+{
+    return (uint32_t)(pc + disp);
+}
+
+std::string
+BranchPCRelCond::generateDisassembly(Addr pc, const SymbolTable *symtab) const
+{
+    std::stringstream ss;
+
+    ccprintf(ss, "%-10s ", mnemonic);
+
+    ss << bo << ", " << bi << ", ";
+
+    Addr target = pc + disp;
+
+    std::string str;
+    if (symtab && symtab->findSymbol(target, str))
+        ss << str;
+    else
+        ccprintf(ss, "0x%x", target);
+
+    return ss.str();
+}
+
+Addr
+BranchNonPCRelCond::branchTarget(Addr pc) const
+{
+    return targetAddr;
+}
+
+std::string
+BranchNonPCRelCond::generateDisassembly(Addr pc,
+                                        const SymbolTable *symtab) const
+{
+    std::stringstream ss;
+
+    ccprintf(ss, "%-10s ", mnemonic);
+
+    ss << bo << ", " << bi << ", ";
+
+    std::string str;
+    if (symtab && symtab->findSymbol(targetAddr, str))
+        ss << str;
+    else
+        ccprintf(ss, "0x%x", targetAddr);
+
+    return ss.str();
+}
+
+Addr
+BranchRegCond::branchTarget(ThreadContext *tc) const
+{
+    uint32_t regVal = tc->readIntReg(_srcRegIdx[_numSrcRegs - 1]);
+    return (regVal & 0xfffffffc);
+}
+
+std::string
+BranchRegCond::generateDisassembly(Addr pc,
+                                   const SymbolTable *symtab) const
+{
+    std::stringstream ss;
+
+    ccprintf(ss, "%-10s ", mnemonic);
+
+    ss << bo << ", " << bi << ", ";
+
+    return ss.str();
+}
diff --git a/src/arch/power/insts/branch.hh b/src/arch/power/insts/branch.hh
new file mode 100644 (file)
index 0000000..dd00e42
--- /dev/null
@@ -0,0 +1,241 @@
+/* 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: Timothy M. Jones
+ */
+
+#ifndef __ARCH_POWER_INSTS_BRANCH_HH__
+#define __ARCH_POWER_INSTS_BRANCH_HH__
+
+#include "arch/power/insts/static_inst.hh"
+
+namespace PowerISA
+{
+
+/**
+ * Base class for instructions whose disassembly is not purely a
+ * function of the machine instruction (i.e., it depends on the
+ * PC).  This class overrides the disassemble() method to check
+ * the PC and symbol table values before re-using a cached
+ * disassembly string.  This is necessary for branches and jumps,
+ * where the disassembly string includes the target address (which
+ * may depend on the PC and/or symbol table).
+ */
+class PCDependentDisassembly : public PowerStaticInst
+{
+  protected:
+    /// Cached program counter from last disassembly
+    mutable Addr cachedPC;
+    /// Cached symbol table pointer from last disassembly
+    mutable const SymbolTable *cachedSymtab;
+
+    /// Constructor
+    PCDependentDisassembly(const char *mnem, ExtMachInst _machInst,
+                           OpClass __opClass)
+        : PowerStaticInst(mnem, _machInst, __opClass),
+          cachedPC(0), cachedSymtab(0)
+    {
+    }
+
+    const std::string &
+    disassemble(Addr pc, const SymbolTable *symtab) const;
+};
+
+/**
+ * Base class for unconditional, PC-relative branches.
+ */
+class BranchPCRel : public PCDependentDisassembly
+{
+  protected:
+
+    /// Displacement
+    uint32_t disp;
+
+    /// Constructor.
+    BranchPCRel(const char *mnem, MachInst _machInst, OpClass __opClass)
+        : PCDependentDisassembly(mnem, _machInst, __opClass),
+          disp(machInst.li << 2)
+    {
+        // If bit 26 is 1 then sign extend
+        if (disp & 0x2000000) {
+            disp |= 0xfc000000;
+        }
+    }
+
+    Addr branchTarget(Addr pc) const;
+
+    std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+};
+
+/**
+ * Base class for unconditional, non PC-relative branches.
+ */
+class BranchNonPCRel : public PCDependentDisassembly
+{
+  protected:
+
+    /// Target address
+    uint32_t targetAddr;
+
+    /// Constructor.
+    BranchNonPCRel(const char *mnem, MachInst _machInst, OpClass __opClass)
+        : PCDependentDisassembly(mnem, _machInst, __opClass),
+          targetAddr(machInst.li << 2)
+    {
+        // If bit 26 is 1 then sign extend
+        if (targetAddr & 0x2000000) {
+            targetAddr |= 0xfc000000;
+        }
+    }
+
+    Addr branchTarget(Addr pc) const;
+
+    std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+};
+
+/**
+ * Base class for conditional branches.
+ */
+class BranchCond : public PCDependentDisassembly
+{
+  protected:
+
+    /// Fields needed for conditions
+    uint32_t bo;
+    uint32_t bi;
+
+    /// Constructor.
+    BranchCond(const char *mnem, MachInst _machInst, OpClass __opClass)
+        : PCDependentDisassembly(mnem, _machInst, __opClass),
+          bo(machInst.bo),
+          bi(machInst.bi)
+    {
+    }
+
+    inline bool
+    ctrOk(uint32_t& ctr) const
+    {
+        bool ctr_ok;
+        if (bo & 4) {
+            ctr_ok = true;
+        } else {
+            ctr--;
+            if (ctr != 0) {
+                ctr_ok = ((bo & 2) == 0);
+            } else {
+                ctr_ok = ((bo & 2) != 0);
+            }
+        }
+        return ctr_ok;
+    }
+
+    inline bool
+    condOk(uint32_t cr) const
+    {
+        bool cond_ok;
+        if (bo & 16) {
+            cond_ok = true;
+        } else {
+            cond_ok = (((cr >> (31 - bi)) & 1) == ((bo >> 3) & 1));
+        }
+        return cond_ok;
+    }
+};
+
+/**
+ * Base class for conditional, PC-relative branches.
+ */
+class BranchPCRelCond : public BranchCond
+{
+  protected:
+
+    /// Displacement
+    uint32_t disp;
+
+    /// Constructor.
+    BranchPCRelCond(const char *mnem, MachInst _machInst, OpClass __opClass)
+        : BranchCond(mnem, _machInst, __opClass),
+          disp(machInst.bd << 2)
+    {
+        // If bit 16 is 1 then sign extend
+        if (disp & 0x8000) {
+            disp |= 0xffff0000;
+        }
+    }
+
+    Addr branchTarget(Addr pc) const;
+
+    std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+};
+
+/**
+ * Base class for conditional, non PC-relative branches.
+ */
+class BranchNonPCRelCond : public BranchCond
+{
+  protected:
+
+    /// Target address
+    uint32_t targetAddr;
+
+    /// Constructor.
+    BranchNonPCRelCond(const char *mnem, MachInst _machInst, OpClass __opClass)
+        : BranchCond(mnem, _machInst, __opClass),
+          targetAddr(machInst.bd << 2)
+    {
+        // If bit 16 is 1 then sign extend
+        if (targetAddr & 0x8000) {
+            targetAddr |= 0xffff0000;
+        }
+    }
+
+    Addr branchTarget(Addr pc) const;
+
+    std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+};
+
+/**
+ * Base class for conditional, register-based branches
+ */
+class BranchRegCond : public BranchCond
+{
+  protected:
+
+    /// Constructor.
+    BranchRegCond(const char *mnem, MachInst _machInst, OpClass __opClass)
+        : BranchCond(mnem, _machInst, __opClass)
+    {
+    }
+
+    Addr branchTarget(ThreadContext *tc) const;
+
+    std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+};
+
+} // PowerISA namespace
+
+#endif //__ARCH_POWER_INSTS_BRANCH_HH__
diff --git a/src/arch/power/insts/condition.cc b/src/arch/power/insts/condition.cc
new file mode 100644 (file)
index 0000000..0a942a9
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * 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
+ */
+
+#include "arch/power/insts/condition.hh"
+
+using namespace PowerISA;
+
+std::string
+CondLogicOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
+{
+    std::stringstream ss;
+
+    ccprintf(ss, "%-10s ", mnemonic);
+
+    // Format is <mnemonic> bt, ba, bb
+    ss << bt << ", " << ba << ", " << bb;
+
+    return ss.str();
+}
+
+std::string
+CondMoveOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
+{
+    std::stringstream ss;
+
+    ccprintf(ss, "%-10s ", mnemonic);
+
+    // Format is <mnemonic> bf, bfa
+    ss << bf << ", " << bfa;
+
+    return ss.str();
+}
diff --git a/src/arch/power/insts/condition.hh b/src/arch/power/insts/condition.hh
new file mode 100644 (file)
index 0000000..a23667d
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ * 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
+ */
+
+#ifndef __ARCH_POWER_INSTS_CONDITION_HH__
+#define __ARCH_POWER_INSTS_CONDITION_HH__
+
+#include "arch/power/insts/static_inst.hh"
+#include "base/cprintf.hh"
+
+namespace PowerISA
+{
+
+/**
+ * Class for condition register logical operations.
+ */
+class CondLogicOp : public PowerStaticInst
+{
+  protected:
+
+    uint32_t ba;
+    uint32_t bb;
+    uint32_t bt;
+
+    /// Constructor
+    CondLogicOp(const char *mnem, MachInst _machInst, OpClass __opClass)
+      : PowerStaticInst(mnem, _machInst, __opClass),
+        ba(machInst.ba),
+        bb(machInst.bb),
+        bt(machInst.bt)
+    {
+    }
+
+    std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+};
+
+/**
+ * Class for condition register move operations.
+ */
+class CondMoveOp : public PowerStaticInst
+{
+  protected:
+
+    uint32_t bf;
+    uint32_t bfa;
+
+    /// Constructor
+    CondMoveOp(const char *mnem, MachInst _machInst, OpClass __opClass)
+      : PowerStaticInst(mnem, _machInst, __opClass),
+        bf(machInst.bf),
+        bfa(machInst.bfa)
+    {
+    }
+
+    std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+};
+
+} // PowerISA namespace
+
+#endif //__ARCH_POWER_INSTS_CONDITION_HH__
diff --git a/src/arch/power/insts/floating.cc b/src/arch/power/insts/floating.cc
new file mode 100644 (file)
index 0000000..f5c34ee
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * 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
+ */
+
+#include "arch/power/insts/floating.hh"
+
+using namespace PowerISA;
+
+std::string
+FloatOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
+{
+    std::stringstream ss;
+
+    ccprintf(ss, "%-10s ", mnemonic);
+
+    // Print the first destination only
+    if (_numDestRegs > 0) {
+        printReg(ss, _destRegIdx[0]);
+    }
+
+    // Print the (possibly) two source registers
+    if (_numSrcRegs > 0) {
+        if (_numDestRegs > 0) {
+            ss << ", ";
+        }
+        printReg(ss, _srcRegIdx[0]);
+        if (_numSrcRegs > 1) {
+          ss << ", ";
+          printReg(ss, _srcRegIdx[1]);
+        }
+    }
+
+    return ss.str();
+}
diff --git a/src/arch/power/insts/floating.hh b/src/arch/power/insts/floating.hh
new file mode 100644 (file)
index 0000000..2b26684
--- /dev/null
@@ -0,0 +1,153 @@
+/*
+ * 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
+ *          Korey Sewell
+ */
+
+#ifndef __ARCH_POWER_INSTS_FLOATING_HH__
+#define __ARCH_POWER_INSTS_FLOATING_HH__
+
+#include "arch/power/insts/static_inst.hh"
+#include "base/cprintf.hh"
+#include "base/bitfield.hh"
+
+namespace PowerISA
+{
+
+/**
+ * Base class for floating point operations.
+ */
+class FloatOp : public PowerStaticInst
+{
+  protected:
+
+    bool rcSet;
+
+    /// Constructor
+    FloatOp(const char *mnem, MachInst _machInst, OpClass __opClass)
+      : PowerStaticInst(mnem, _machInst, __opClass)
+    {
+    }
+
+    // Test for NaN (maximum biased exponent & non-zero fraction)
+    inline bool
+    isNan(uint32_t val_bits) const
+    {
+        return ((bits(val_bits, 30, 23) == 0xFF) && bits(val_bits, 22, 0));
+    }
+
+    inline bool
+    isNan(uint64_t val_bits) const
+    {
+        return ((bits(val_bits, 62, 52) == 0x7FF) && bits(val_bits, 51, 0));
+    }
+
+    inline bool
+    isNan(float val) const
+    {
+        void *val_ptr = &val;
+        uint32_t val_bits = *(uint32_t *) val_ptr;
+        return isNan(val_bits);
+    }
+
+    inline bool
+    isNan(double val) const
+    {
+        void *val_ptr = &val;
+        uint64_t val_bits = *(uint64_t *) val_ptr;
+        return isNan(val_bits);
+    }
+
+    // Test for SNaN (NaN with high order bit of fraction set to 0)
+    inline bool
+    isSnan(uint32_t val_bits) const
+    {
+        return ((bits(val_bits, 30, 22) == 0x1FE) && bits(val_bits, 22, 0));
+    }
+
+    // Test for QNaN (NaN with high order bit of fraction set to 1)
+    inline bool
+    isQnan(uint32_t val_bits) const
+    {
+        return (bits(val_bits, 30, 22) == 0x1FF);
+    }
+
+    // Test for infinity (maximum biased exponent and zero fraction)
+    inline bool
+    isInfinity(uint32_t val_bits) const
+    {
+        return ((bits(val_bits, 30, 23) == 0xFF) && !bits(val_bits, 22, 0));
+    }
+
+    // Test for normalized numbers (biased exponent in the range 1 to 254)
+    inline bool
+    isNormalized(uint32_t val_bits) const
+    {
+        return ((bits(val_bits, 30, 23) != 0xFF) && bits(val_bits, 22, 0));
+    }
+
+    // Test for denormalized numbers (biased exponent of zero and
+    // non-zero fraction)
+    inline bool
+    isDenormalized(uint32_t val_bits) const
+    {
+        return (!bits(val_bits, 30, 23) && bits(val_bits, 22, 0));
+    }
+
+    // Test for zero (biased exponent of zero and fraction of zero)
+    inline bool
+    isZero(uint32_t val_bits) const
+    {
+        return (!bits(val_bits, 30, 23) && !bits(val_bits, 22, 0));
+    }
+
+    // Test for negative
+    inline bool
+    isNegative(uint32_t val_bits) const
+    {
+        return (bits(val_bits, 31));
+    }
+
+    // Compute the CR field
+    inline uint32_t
+    makeCRField(double a, double b) const
+    {
+        uint32_t c = 0;
+        if (isNan(a) || isNan(b)) { c = 0x1; }
+        else if (a < b)           { c = 0x8; }
+        else if (a > b)           { c = 0x4; }
+        else                      { c = 0x2; }
+        return c;
+    }
+
+    std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+};
+
+} // PowerISA namespace
+
+#endif //__ARCH_POWER_INSTS_FLOATING_HH__
diff --git a/src/arch/power/insts/integer.cc b/src/arch/power/insts/integer.cc
new file mode 100644 (file)
index 0000000..1f81a15
--- /dev/null
@@ -0,0 +1,170 @@
+/*
+ * 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
+ */
+
+#include "arch/power/insts/integer.hh"
+
+using namespace std;
+using namespace PowerISA;
+
+string
+IntOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
+{
+    stringstream ss;
+    bool printDest = true;
+    bool printSrcs = true;
+    bool printSecondSrc = true;
+
+    // Generate the correct mnemonic
+    string myMnemonic(mnemonic);
+
+    // Special cases
+    if (!myMnemonic.compare("or") && _srcRegIdx[0] == _srcRegIdx[1]) {
+        myMnemonic = "mr";
+        printSecondSrc = false;
+    } else if (!myMnemonic.compare("mtlr") || !myMnemonic.compare("cmpi")) {
+        printDest = false;
+    } else if (!myMnemonic.compare("mflr")) {
+        printSrcs = false;
+    }
+
+    // Additional characters depending on isa bits being set
+    if (oeSet) myMnemonic = myMnemonic + "o";
+    if (rcSet) myMnemonic = myMnemonic + ".";
+    ccprintf(ss, "%-10s ", myMnemonic);
+
+    // Print the first destination only
+    if (_numDestRegs > 0 && printDest) {
+        printReg(ss, _destRegIdx[0]);
+    }
+
+    // Print the (possibly) two source registers
+    if (_numSrcRegs > 0 && printSrcs) {
+        if (_numDestRegs > 0 && printDest) {
+            ss << ", ";
+        }
+        printReg(ss, _srcRegIdx[0]);
+        if (_numSrcRegs > 1 && printSecondSrc) {
+          ss << ", ";
+          printReg(ss, _srcRegIdx[1]);
+        }
+    }
+
+    return ss.str();
+}
+
+
+string
+IntImmOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
+{
+    stringstream ss;
+
+    // Generate the correct mnemonic
+    string myMnemonic(mnemonic);
+
+    // Special cases
+    if (!myMnemonic.compare("addi") && _numSrcRegs == 0) {
+        myMnemonic = "li";
+    } else if (!myMnemonic.compare("addis") && _numSrcRegs == 0) {
+        myMnemonic = "lis";
+    }
+    ccprintf(ss, "%-10s ", myMnemonic);
+
+    // Print the first destination only
+    if (_numDestRegs > 0) {
+        printReg(ss, _destRegIdx[0]);
+    }
+
+    // Print the source register
+    if (_numSrcRegs > 0) {
+        if (_numDestRegs > 0) {
+            ss << ", ";
+        }
+        printReg(ss, _srcRegIdx[0]);
+    }
+
+    // Print the immediate value last
+    ss << ", " << (int32_t)imm;
+
+    return ss.str();
+}
+
+
+string
+IntShiftOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
+{
+    stringstream ss;
+
+    ccprintf(ss, "%-10s ", mnemonic);
+
+    // Print the first destination only
+    if (_numDestRegs > 0) {
+        printReg(ss, _destRegIdx[0]);
+    }
+
+    // Print the first source register
+    if (_numSrcRegs > 0) {
+        if (_numDestRegs > 0) {
+            ss << ", ";
+        }
+        printReg(ss, _srcRegIdx[0]);
+    }
+
+    // Print the shift
+    ss << ", " << sh;
+
+    return ss.str();
+}
+
+
+string
+IntRotateOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
+{
+    stringstream ss;
+
+    ccprintf(ss, "%-10s ", mnemonic);
+
+    // Print the first destination only
+    if (_numDestRegs > 0) {
+        printReg(ss, _destRegIdx[0]);
+    }
+
+    // Print the first source register
+    if (_numSrcRegs > 0) {
+        if (_numDestRegs > 0) {
+            ss << ", ";
+        }
+        printReg(ss, _srcRegIdx[0]);
+    }
+
+    // Print the shift, mask begin and mask end
+    ss << ", " << sh << ", " << mb << ", " << me;
+
+    return ss.str();
+}
diff --git a/src/arch/power/insts/integer.hh b/src/arch/power/insts/integer.hh
new file mode 100644 (file)
index 0000000..b4b96d5
--- /dev/null
@@ -0,0 +1,176 @@
+/*
+ * 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
+ */
+
+#ifndef __ARCH_POWER_INSTS_INTEGER_HH__
+#define __ARCH_POWER_INSTS_INTEGER_HH__
+
+#include "arch/power/insts/static_inst.hh"
+#include "base/cprintf.hh"
+#include "base/bitfield.hh"
+
+namespace PowerISA
+{
+
+/**
+ * We provide a base class for integer operations and then inherit for
+ * several other classes. These specialise for instructions using immediate
+ * values and also rotate instructions. We also need to have versions that
+ * consider the Rc and OE bits.
+ */
+
+/**
+ * Base class for integer operations.
+ */
+class IntOp : public PowerStaticInst
+{
+  protected:
+
+    bool rcSet;
+    bool oeSet;
+
+    // Needed for srawi only
+    uint32_t sh;
+
+    /// Constructor
+    IntOp(const char *mnem, MachInst _machInst, OpClass __opClass)
+      : PowerStaticInst(mnem, _machInst, __opClass),
+        rcSet(false), oeSet(false)
+    {
+    }
+
+    /* Compute the CR (condition register) field using signed comparison */
+    inline uint32_t
+    makeCRField(int32_t a, int32_t b, uint32_t xerSO) const
+    {
+        uint32_t c = xerSO;
+
+        /* We've pre-shifted the immediate values here */
+        if (a < b)      { c += 0x8; }
+        else if (a > b) { c += 0x4; }
+        else            { c += 0x2; }
+        return c;
+    }
+
+    /* Compute the CR (condition register) field using unsigned comparison */
+    inline uint32_t
+    makeCRField(uint32_t a, uint32_t b, uint32_t xerSO) const
+    {
+        uint32_t c = xerSO;
+
+        /* We've pre-shifted the immediate values here */
+        if (a < b)      { c += 0x8; }
+        else if (a > b) { c += 0x4; }
+        else            { c += 0x2; }
+        return c;
+    }
+
+    std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+};
+
+
+/**
+ * Class for integer immediate (signed and unsigned) operations.
+ */
+class IntImmOp : public IntOp
+{
+  protected:
+
+    int32_t imm;
+    uint32_t uimm;
+
+    /// Constructor
+    IntImmOp(const char *mnem, MachInst _machInst, OpClass __opClass)
+      : IntOp(mnem, _machInst, __opClass),
+        imm(sext<16>(machInst.si)),
+        uimm(machInst.si)
+    {
+    }
+
+    std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+};
+
+
+/**
+ * Class for integer operations with a shift.
+ */
+class IntShiftOp : public IntOp
+{
+  protected:
+
+    uint32_t sh;
+
+    /// Constructor
+    IntShiftOp(const char *mnem, MachInst _machInst, OpClass __opClass)
+      : IntOp(mnem, _machInst, __opClass),
+        sh(machInst.sh)
+    {
+    }
+
+    std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+};
+
+
+/**
+ * Class for integer rotate operations.
+ */
+class IntRotateOp : public IntShiftOp
+{
+  protected:
+
+    uint32_t mb;
+    uint32_t me;
+    uint32_t fullMask;
+
+    /// Constructor
+    IntRotateOp(const char *mnem, MachInst _machInst, OpClass __opClass)
+      : IntShiftOp(mnem, _machInst, __opClass),
+        mb(machInst.mb),
+        me(machInst.me)
+    {
+        if (me >= mb) {
+            fullMask = mask(31 - mb, 31 - me);
+        } else {
+            fullMask = ~mask(31 - (me + 1), 31 - (mb - 1));
+        }
+    }
+
+    uint32_t
+    rotateValue(uint32_t rs, uint32_t shift) const
+    {
+        uint32_t n = shift & 31;
+        return (rs << n) | (rs >> (32 - n));
+    }
+
+    std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+};
+
+} // PowerISA namespace
+
+#endif //__ARCH_POWER_INSTS_INTEGER_HH__
diff --git a/src/arch/power/insts/mem.cc b/src/arch/power/insts/mem.cc
new file mode 100644 (file)
index 0000000..447efa2
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * 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
+ */
+
+#include "arch/power/insts/mem.hh"
+#include "base/loader/symtab.hh"
+
+using namespace PowerISA;
+
+std::string
+MemOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
+{
+    return csprintf("%-10s", mnemonic);
+}
+
+std::string
+MemDispOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
+{
+    std::stringstream ss;
+
+    ccprintf(ss, "%-10s ", mnemonic);
+
+    // Print the destination only for a load
+    if (!flags[IsStore]) {
+        if (_numDestRegs > 0) {
+
+            // If the instruction updates the source register with the
+            // EA, then this source register is placed in position 0,
+            // therefore we print the last destination register.
+            printReg(ss, _destRegIdx[_numDestRegs-1]);
+        }
+    }
+
+    // Print the data register for a store
+    else {
+        printReg(ss, _srcRegIdx[1]);
+    }
+
+    // Print the displacement
+    ss << ", " << (int32_t)disp;
+
+    // Print the address register
+    ss << "(";
+    printReg(ss, _srcRegIdx[0]);
+    ss << ")";
+
+    return ss.str();
+}
diff --git a/src/arch/power/insts/mem.hh b/src/arch/power/insts/mem.hh
new file mode 100644 (file)
index 0000000..329dafe
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+ * 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
+ */
+
+#ifndef __ARCH_POWER_MEM_HH__
+#define __ARCH_POWER_MEM_HH__
+
+#include "arch/power/insts/static_inst.hh"
+
+namespace PowerISA
+{
+
+/**
+ * Base class for memory operations.
+ */
+class MemOp : public PowerStaticInst
+{
+  protected:
+
+    /// Memory request flags.  See mem_req_base.hh.
+    unsigned memAccessFlags;
+    /// Pointer to EAComp object.
+    const StaticInstPtr eaCompPtr;
+    /// Pointer to MemAcc object.
+    const StaticInstPtr memAccPtr;
+
+    /// Constructor
+    MemOp(const char *mnem, MachInst _machInst, OpClass __opClass,
+          StaticInstPtr _eaCompPtr = nullStaticInstPtr,
+          StaticInstPtr _memAccPtr = nullStaticInstPtr)
+      : PowerStaticInst(mnem, _machInst, __opClass),
+        memAccessFlags(0),
+        eaCompPtr(_eaCompPtr),
+        memAccPtr(_memAccPtr)
+    {
+    }
+
+    std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+};
+
+
+/**
+ * Class for memory operations with displacement.
+ */
+class MemDispOp : public MemOp
+{
+  protected:
+
+    int16_t disp;
+
+    /// Constructor
+    MemDispOp(const char *mnem, MachInst _machInst, OpClass __opClass,
+              StaticInstPtr _eaCompPtr = nullStaticInstPtr,
+              StaticInstPtr _memAccPtr = nullStaticInstPtr)
+      : MemOp(mnem, _machInst, __opClass, _eaCompPtr, _memAccPtr),
+        disp(machInst.d)
+    {
+    }
+
+    std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+};
+
+} // PowerISA namespace
+
+#endif //__ARCH_POWER_INSTS_MEM_HH__
diff --git a/src/arch/power/insts/misc.cc b/src/arch/power/insts/misc.cc
new file mode 100644 (file)
index 0000000..913030b
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * 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
+ */
+
+#include "arch/power/insts/misc.hh"
+
+using namespace PowerISA;
+
+std::string
+MiscOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
+{
+    std::stringstream ss;
+
+    ccprintf(ss, "%-10s ", mnemonic);
+
+    // Print the first destination only
+    if (_numDestRegs > 0) {
+        printReg(ss, _destRegIdx[0]);
+    }
+
+    // Print the (possibly) two source registers
+    if (_numSrcRegs > 0) {
+        if (_numDestRegs > 0) {
+            ss << ", ";
+        }
+        printReg(ss, _srcRegIdx[0]);
+        if (_numSrcRegs > 1) {
+          ss << ", ";
+          printReg(ss, _srcRegIdx[1]);
+        }
+    }
+
+    return ss.str();
+}
diff --git a/src/arch/power/insts/misc.hh b/src/arch/power/insts/misc.hh
new file mode 100644 (file)
index 0000000..dd4941b
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * 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
+ */
+
+#ifndef __ARCH_POWER_INSTS_MISC_HH__
+#define __ARCH_POWER_INSTS_MISC_HH__
+
+#include "arch/power/insts/static_inst.hh"
+
+namespace PowerISA
+{
+
+/**
+ * Class for misc operations.
+ */
+class MiscOp : public PowerStaticInst
+{
+  protected:
+
+    /// Constructor
+    MiscOp(const char *mnem, MachInst _machInst, OpClass __opClass)
+      : PowerStaticInst(mnem, _machInst, __opClass)
+    {
+    }
+
+    std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+};
+
+} // PowerISA namespace
+
+#endif //__ARCH_POWER_INSTS_MISC_HH__
diff --git a/src/arch/power/insts/static_inst.cc b/src/arch/power/insts/static_inst.cc
new file mode 100644 (file)
index 0000000..1982744
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * 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
+ */
+
+#include "arch/power/insts/static_inst.hh"
+
+using namespace PowerISA;
+
+void
+PowerStaticInst::printReg(std::ostream &os, int reg) const
+{
+    if (reg < FP_Base_DepTag) {
+        ccprintf(os, "r%d", reg);
+    } else if (reg < Ctrl_Base_DepTag) {
+        ccprintf(os, "f%d", reg - FP_Base_DepTag);
+    } else {
+        switch (reg - Ctrl_Base_DepTag) {
+        case 0: ccprintf(os, "cr"); break;
+        case 1: ccprintf(os, "xer"); break;
+        case 2: ccprintf(os, "lr"); break;
+        case 3: ccprintf(os, "ctr"); break;
+        default: ccprintf(os, "unknown_reg");
+        }
+    }
+}
+
+std::string
+PowerStaticInst::generateDisassembly(Addr pc,
+                                       const SymbolTable *symtab) const
+{
+    std::stringstream ss;
+
+    ccprintf(ss, "%-10s ", mnemonic);
+
+    return ss.str();
+}
diff --git a/src/arch/power/insts/static_inst.hh b/src/arch/power/insts/static_inst.hh
new file mode 100644 (file)
index 0000000..399e753
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ * 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
+ */
+
+#ifndef __ARCH_POWER_INSTS_STATICINST_HH__
+#define __ARCH_POWER_INSTS_STATICINST_HH__
+
+#include "base/trace.hh"
+#include "cpu/static_inst.hh"
+
+namespace PowerISA
+{
+
+class PowerStaticInst : public StaticInst
+{
+  protected:
+
+    // Constructor
+    PowerStaticInst(const char *mnem, MachInst _machInst, OpClass __opClass)
+        : StaticInst(mnem, _machInst, __opClass)
+    {
+    }
+
+    // Insert a condition value into a CR (condition register) field
+    inline uint32_t
+    insertCRField(uint32_t cr, uint32_t bf, uint32_t value) const
+    {
+        uint32_t bits = value << ((7 - bf) * 4);
+        uint32_t mask = ~(0xf << ((7 - bf) * 4));
+        return (cr & mask) | bits;
+    }
+
+    /// Print a register name for disassembly given the unique
+    /// dependence tag number (FP or int).
+    void
+    printReg(std::ostream &os, int reg) const;
+
+    std::string
+    generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+};
+
+} // PowerISA namespace
+
+#endif //__ARCH_POWER_INSTS_STATICINST_HH__
diff --git a/src/arch/power/isa.hh b/src/arch/power/isa.hh
new file mode 100644 (file)
index 0000000..ba1b501
--- /dev/null
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2009 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: Gabe Black
+ *          Timothy M. Jones
+ */
+
+#ifndef __ARCH_POWER_ISA_HH__
+#define __ARCH_POWER_ISA_HH__
+
+#include "arch/power/registers.hh"
+#include "arch/power/types.hh"
+#include "base/misc.hh"
+
+class ThreadContext;
+class Checkpoint;
+class EventManager;
+
+namespace PowerISA
+{
+
+class ISA
+{
+  protected:
+    MiscReg dummy;
+    MiscReg miscRegs[NumMiscRegs];
+
+  public:
+    void
+    clear()
+    {
+    }
+
+    MiscReg
+    readMiscRegNoEffect(int misc_reg)
+    {
+        fatal("Power does not currently have any misc regs defined\n");
+        return dummy;
+    }
+
+    MiscReg
+    readMiscReg(int misc_reg, ThreadContext *tc)
+    {
+        fatal("Power does not currently have any misc regs defined\n");
+        return dummy;
+    }
+
+    void
+    setMiscRegNoEffect(int misc_reg, const MiscReg &val)
+    {
+        fatal("Power does not currently have any misc regs defined\n");
+    }
+
+    void
+    setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc)
+    {
+        fatal("Power does not currently have any misc regs defined\n");
+    }
+
+    int
+    flattenIntIndex(int reg)
+    {
+        return reg;
+    }
+
+    int
+    flattenFloatIndex(int reg)
+    {
+        return reg;
+    }
+
+    void
+    serialize(EventManager *em, std::ostream &os)
+    {
+    }
+
+    void
+    unserialize(EventManager *em, Checkpoint *cp, const std::string &section)
+    {
+    }
+
+    ISA()
+    {
+        clear();
+    }
+};
+
+} // PowerISA namespace
+
+#endif // __ARCH_POWER_ISA_HH__
diff --git a/src/arch/power/isa/bitfields.isa b/src/arch/power/isa/bitfields.isa
new file mode 100644 (file)
index 0000000..8cd323a
--- /dev/null
@@ -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 (file)
index 0000000..3252ff1
--- /dev/null
@@ -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 (file)
index 0000000..adb5e7e
--- /dev/null
@@ -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 (file)
index 0000000..d51ed5c
--- /dev/null
@@ -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 (file)
index 0000000..12ee7ae
--- /dev/null
@@ -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 (file)
index 0000000..ec25751
--- /dev/null
@@ -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 (file)
index 0000000..db91747
--- /dev/null
@@ -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 (file)
index 0000000..0766826
--- /dev/null
@@ -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 (file)
index 0000000..1be49c2
--- /dev/null
@@ -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 (file)
index 0000000..93536aa
--- /dev/null
@@ -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 (file)
index 0000000..60a7c46
--- /dev/null
@@ -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 (file)
index 0000000..06e6ece
--- /dev/null
@@ -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 (file)
index 0000000..ab1e530
--- /dev/null
@@ -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 (file)
index 0000000..47e8c14
--- /dev/null
@@ -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 (file)
index 0000000..cce7e39
--- /dev/null
@@ -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 (file)
index 0000000..fc6c326
--- /dev/null
@@ -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),
+}};
diff --git a/src/arch/power/isa_traits.hh b/src/arch/power/isa_traits.hh
new file mode 100644 (file)
index 0000000..886c2cb
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2003-2005 The Regents of The University of Michigan
+ * 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: Timothy M. Jones
+ *          Gabe Black
+ *          Stephen Hines
+ */
+
+#ifndef __ARCH_POWER_ISA_TRAITS_HH__
+#define __ARCH_POWER_ISA_TRAITS_HH__
+
+#include "arch/power/types.hh"
+#include "base/types.hh"
+
+namespace BigEndianGuest {};
+
+class StaticInstPtr;
+
+namespace PowerISA
+{
+
+using namespace BigEndianGuest;
+
+StaticInstPtr decodeInst(ExtMachInst);
+
+// POWER DOES NOT have a delay slot
+#define ISA_HAS_DELAY_SLOT 0
+
+const Addr PageShift = 12;
+const Addr PageBytes = ULL(1) << PageShift;
+const Addr Page_Mask = ~(PageBytes - 1);
+const Addr PageOffset = PageBytes - 1;
+
+const Addr PteShift = 3;
+const Addr NPtePageShift = PageShift - PteShift;
+const Addr NPtePage = ULL(1) << NPtePageShift;
+const Addr PteMask = NPtePage - 1;
+
+const int LogVMPageSize = 12;  // 4K bytes
+const int VMPageSize = (1 << LogVMPageSize);
+
+const int MachineBytes = 4;
+
+// This is ori 0, 0, 0
+const ExtMachInst NoopMachInst = 0x60000000;
+
+} // PowerISA namespace
+
+#endif // __ARCH_POWER_ISA_TRAITS_HH__
diff --git a/src/arch/power/linux/linux.cc b/src/arch/power/linux/linux.cc
new file mode 100644 (file)
index 0000000..113f3e4
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ * 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: Timothy M. Jones
+ */
+
+#include "arch/power/linux/linux.hh"
+
+#include <fcntl.h>
+
+// open(2) flags translation table
+OpenFlagTransTable PowerLinux::openFlagTable[] = {
+#ifdef _MSC_VER
+  { PowerLinux::TGT_O_RDONLY,    _O_RDONLY },
+  { PowerLinux::TGT_O_WRONLY,    _O_WRONLY },
+  { PowerLinux::TGT_O_RDWR,      _O_RDWR },
+  { PowerLinux::TGT_O_APPEND,    _O_APPEND },
+  { PowerLinux::TGT_O_CREAT,     _O_CREAT },
+  { PowerLinux::TGT_O_TRUNC,     _O_TRUNC },
+  { PowerLinux::TGT_O_EXCL,      _O_EXCL },
+#ifdef _O_NONBLOCK
+  { PowerLinux::TGT_O_NONBLOCK,  _O_NONBLOCK },
+#endif
+#ifdef _O_NOCTTY
+  { PowerLinux::TGT_O_NOCTTY,    _O_NOCTTY },
+#endif
+#ifdef _O_SYNC
+  { PowerLinux::TGT_O_SYNC,      _O_SYNC },
+#endif
+#ifdef _O_LARGEFILE
+  { PowerLinux::TGT_O_LARGEFILE, _O_LARGEFILE },
+#endif
+#else /* !_MSC_VER */
+  { PowerLinux::TGT_O_RDONLY,    O_RDONLY },
+  { PowerLinux::TGT_O_WRONLY,    O_WRONLY },
+  { PowerLinux::TGT_O_RDWR,      O_RDWR },
+  { PowerLinux::TGT_O_APPEND,    O_APPEND },
+  { PowerLinux::TGT_O_CREAT,     O_CREAT },
+  { PowerLinux::TGT_O_TRUNC,     O_TRUNC },
+  { PowerLinux::TGT_O_EXCL,      O_EXCL },
+  { PowerLinux::TGT_O_NONBLOCK,  O_NONBLOCK },
+  { PowerLinux::TGT_O_NOCTTY,    O_NOCTTY },
+#ifdef O_SYNC
+  { PowerLinux::TGT_O_SYNC,      O_SYNC },
+#endif
+#ifdef O_LARGEFILE
+  { PowerLinux::TGT_O_LARGEFILE, O_LARGEFILE },
+#endif
+#endif /* _MSC_VER */
+};
+
+const int PowerLinux::NUM_OPEN_FLAGS =
+        (sizeof(PowerLinux::openFlagTable)/sizeof(PowerLinux::openFlagTable[0]));
+
diff --git a/src/arch/power/linux/linux.hh b/src/arch/power/linux/linux.hh
new file mode 100644 (file)
index 0000000..c681c8b
--- /dev/null
@@ -0,0 +1,148 @@
+/*
+ * 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: Timothy M. Jones
+ */
+
+#ifndef __ARCH_POWER_LINUX_LINUX_HH__
+#define __ARCH_POWER_LINUX_LINUX_HH__
+
+#include "kern/linux/linux.hh"
+
+/*
+ * This works for a 2.6.15 kernel.
+ */
+
+class PowerLinux : public Linux
+{
+  public:
+
+    typedef int32_t time_t;
+
+    typedef struct {
+        uint64_t st_dev;
+        uint32_t __pad1;
+        uint32_t st_ino;
+        uint32_t st_mode;
+        uint32_t st_nlink;
+        uint32_t st_uid;
+        uint32_t st_gid;
+        uint64_t st_rdev;
+        uint32_t __pad2;
+        uint32_t st_size;
+        uint32_t st_blksize;
+        uint32_t st_blocks;
+        uint32_t st_atimeX;
+        uint32_t st_atime_nsec;
+        uint32_t st_mtimeX;
+        uint32_t st_mtime_nsec;
+        uint32_t st_ctimeX;
+        uint32_t st_ctime_nsec;
+        uint32_t __unused4;
+        uint32_t __unused5;
+    } tgt_stat;
+
+    typedef struct {
+        uint64_t st_dev;
+        uint64_t st_ino;
+        uint32_t st_mode;
+        uint32_t st_nlink;
+        uint32_t st_uid;
+        uint32_t st_gid;
+        uint64_t st_rdev;
+        uint64_t __pad2;
+        uint64_t st_size;
+        uint32_t st_blksize;
+        uint32_t __blksize_pad;
+        uint64_t st_blocks;
+        uint32_t st_atimeX;
+        uint32_t st_atime_nsec;
+        uint32_t st_mtimeX;
+        uint32_t st_mtime_nsec;
+        uint32_t st_ctimeX;
+        uint32_t st_ctime_nsec;
+        uint32_t __unused4;
+        uint32_t __unused5;
+    } tgt_stat64;
+
+    /// For times().
+    struct tms {
+        int32_t tms_utime;      //!< user time
+        int32_t tms_stime;      //!< system time
+        int32_t tms_cutime;     //!< user time of children
+        int32_t tms_cstime;     //!< system time of children
+    };
+
+    /// This table maps the target open() flags to the corresponding
+    /// host open() flags.
+    static OpenFlagTransTable openFlagTable[];
+
+    /// Number of entries in openFlagTable[].
+    static const int NUM_OPEN_FLAGS;
+
+    //@{
+    /// open(2) flag values.
+    static const int TGT_O_RDONLY    = 00000000; //!< O_RDONLY
+    static const int TGT_O_WRONLY    = 00000001; //!< O_WRONLY
+    static const int TGT_O_RDWR      = 00000002; //!< O_RDWR
+    static const int TGT_O_CREAT     = 00000100; //!< O_CREAT
+    static const int TGT_O_EXCL      = 00000200; //!< O_EXCL
+    static const int TGT_O_NOCTTY    = 00000400; //!< O_NOCTTY
+    static const int TGT_O_TRUNC     = 00001000; //!< O_TRUNC
+    static const int TGT_O_APPEND    = 00002000; //!< O_APPEND
+    static const int TGT_O_NONBLOCK  = 00004000; //!< O_NONBLOCK
+    static const int TGT_O_SYNC      = 00010000; //!< O_SYNC
+    static const int TGT_FASYNC      = 00020000; //!< FASYNC
+    static const int TGT_O_DIRECTORY = 00040000; //!< O_DIRECTORY
+    static const int TGT_O_NOFOLLOW  = 00100000; //!< O_NOFOLLOW
+    static const int TGT_O_LARGEFILE = 00200000; //!< O_LARGEFILE
+    static const int TGT_O_DIRECT    = 00400000; //!< O_DIRECT
+    static const int TGT_O_NOATIME   = 01000000; //!< O_NOATIME
+    //@}
+
+    /// For mmap().
+    static const unsigned TGT_MAP_ANONYMOUS = 0x800;
+
+    //@{
+    /// ioctl() command codes.
+    /// These are for the 2.6.15 kernel. Some have changed for
+    /// later versions.
+    static const unsigned TIOCGETP_   = 0x40067408;
+    static const unsigned TIOCSETP_   = 0x80067409;
+    static const unsigned TIOCSETN_   = 0x8006740a;
+    static const unsigned TIOCSETC_   = 0x80067411;
+    static const unsigned TIOCGETC_   = 0x40067412;
+    static const unsigned FIONREAD_   = 0x4004667f;
+    static const unsigned TIOCISATTY_ = 0x2000745e;
+    static const unsigned TIOCGETS_   = 0x402c7413;
+    static const unsigned TIOCGETA_   = 0x40147417;
+    static const unsigned TCSETAW_    = 0x80147419;
+    //@}
+};
+
+#endif // __ARCH_POWER_LINUX_LINUX_HH__
diff --git a/src/arch/power/linux/process.cc b/src/arch/power/linux/process.cc
new file mode 100644 (file)
index 0000000..b03ccfc
--- /dev/null
@@ -0,0 +1,455 @@
+/*
+ * Copyright (c) 2003-2005 The Regents of The University of Michigan
+ * 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: Korey Sewell
+ *          Stephen Hines
+ *          Timothy M. Jones
+ */
+
+#include "arch/power/linux/linux.hh"
+#include "arch/power/linux/process.hh"
+#include "arch/power/isa_traits.hh"
+
+#include "base/trace.hh"
+#include "cpu/thread_context.hh"
+#include "kern/linux/linux.hh"
+
+#include "sim/process.hh"
+#include "sim/syscall_emul.hh"
+#include "sim/system.hh"
+
+using namespace std;
+using namespace PowerISA;
+
+/// Target uname() handler.
+static SyscallReturn
+unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
+          ThreadContext *tc)
+{
+    TypedBufferArg<Linux::utsname> name(process->getSyscallArg(tc, 0));
+
+    strcpy(name->sysname, "Linux");
+    strcpy(name->nodename, "m5.eecs.umich.edu");
+    strcpy(name->release, "2.6.16.19");
+    strcpy(name->version, "#1 Mon Aug 18 11:32:15 EDT 2003");
+    strcpy(name->machine, "power");
+
+    name.copyOut(tc->getMemPort());
+    return 0;
+}
+
+SyscallDesc PowerLinuxProcess::syscallDescs[] = {
+    /*  0 */ SyscallDesc("syscall", unimplementedFunc),
+    /*  1 */ SyscallDesc("exit", exitFunc),
+    /*  2 */ SyscallDesc("fork", unimplementedFunc),
+    /*  3 */ SyscallDesc("read", readFunc),
+    /*  4 */ SyscallDesc("write", writeFunc),
+    /*  5 */ SyscallDesc("open", openFunc<PowerLinux>),
+    /*  6 */ SyscallDesc("close", closeFunc),
+    /*  7 */ SyscallDesc("waitpid", unimplementedFunc), //???
+    /*  8 */ SyscallDesc("creat", unimplementedFunc),
+    /*  9 */ SyscallDesc("link", unimplementedFunc),
+    /* 10 */ SyscallDesc("unlink", unlinkFunc),
+    /* 11 */ SyscallDesc("execve", unimplementedFunc),
+    /* 12 */ SyscallDesc("chdir", unimplementedFunc),
+    /* 13 */ SyscallDesc("time", timeFunc<PowerLinux>),
+    /* 14 */ SyscallDesc("mknod", unimplementedFunc),
+    /* 15 */ SyscallDesc("chmod", chmodFunc<PowerLinux>),
+    /* 16 */ SyscallDesc("lchown", chownFunc),
+    /* 17 */ SyscallDesc("break", brkFunc), //???
+    /* 18 */ SyscallDesc("unused#18", unimplementedFunc), //???
+    /* 19 */ SyscallDesc("lseek", lseekFunc),
+    /* 20 */ SyscallDesc("getpid", getpidFunc),
+    /* 21 */ SyscallDesc("mount", unimplementedFunc),
+    /* 22 */ SyscallDesc("umount", unimplementedFunc),
+    /* 23 */ SyscallDesc("setuid", setuidFunc),
+    /* 24 */ SyscallDesc("getuid", getuidFunc),
+    /* 25 */ SyscallDesc("stime", unimplementedFunc),
+    /* 26 */ SyscallDesc("ptrace", unimplementedFunc),
+    /* 27 */ SyscallDesc("alarm", unimplementedFunc),
+    /* 28 */ SyscallDesc("unused#28", unimplementedFunc),
+    /* 29 */ SyscallDesc("pause", unimplementedFunc),
+    /* 30 */ SyscallDesc("utime", unimplementedFunc),
+    /* 31 */ SyscallDesc("stty", unimplementedFunc),
+    /* 32 */ SyscallDesc("gtty", unimplementedFunc),
+    /* 33 */ SyscallDesc("access", unimplementedFunc),
+    /* 34 */ SyscallDesc("nice", unimplementedFunc),
+    /* 35 */ SyscallDesc("ftime", unimplementedFunc),
+    /* 36 */ SyscallDesc("sync", unimplementedFunc),
+    /* 37 */ SyscallDesc("kill", ignoreFunc),
+    /* 38 */ SyscallDesc("rename", renameFunc),
+    /* 39 */ SyscallDesc("mkdir", unimplementedFunc),
+    /* 40 */ SyscallDesc("rmdir", unimplementedFunc),
+    /* 41 */ SyscallDesc("dup", dupFunc),
+    /* 42 */ SyscallDesc("pipe", unimplementedFunc),
+    /* 43 */ SyscallDesc("times", timesFunc<PowerLinux>),
+    /* 44 */ SyscallDesc("prof", unimplementedFunc),
+    /* 45 */ SyscallDesc("brk", brkFunc),
+    /* 46 */ SyscallDesc("setgid", unimplementedFunc),
+    /* 47 */ SyscallDesc("getgid", getgidFunc),
+    /* 48 */ SyscallDesc("signal", ignoreFunc),
+    /* 49 */ SyscallDesc("geteuid", geteuidFunc),
+    /* 50 */ SyscallDesc("getegid", getegidFunc),
+    /* 51 */ SyscallDesc("acct", unimplementedFunc),
+    /* 52 */ SyscallDesc("umount2", unimplementedFunc),
+    /* 53 */ SyscallDesc("lock", unimplementedFunc),
+    /* 54 */ SyscallDesc("ioctl", ioctlFunc<PowerLinux>),
+    /* 55 */ SyscallDesc("fcntl", fcntlFunc),
+    /* 56 */ SyscallDesc("mpx", unimplementedFunc),
+    /* 57 */ SyscallDesc("setpgid", unimplementedFunc),
+    /* 58 */ SyscallDesc("ulimit", unimplementedFunc),
+    /* 59 */ SyscallDesc("unused#59", unimplementedFunc),
+    /* 60 */ SyscallDesc("umask", umaskFunc),
+    /* 61 */ SyscallDesc("chroot", unimplementedFunc),
+    /* 62 */ SyscallDesc("ustat", unimplementedFunc),
+    /* 63 */ SyscallDesc("dup2", unimplementedFunc),
+    /* 64 */ SyscallDesc("getppid", getpagesizeFunc),
+    /* 65 */ SyscallDesc("getpgrp", unimplementedFunc),
+    /* 66 */ SyscallDesc("setsid", unimplementedFunc),
+    /* 67 */ SyscallDesc("sigaction",unimplementedFunc),
+    /* 68 */ SyscallDesc("sgetmask", unimplementedFunc),
+    /* 69 */ SyscallDesc("ssetmask", unimplementedFunc),
+    /* 70 */ SyscallDesc("setreuid", unimplementedFunc),
+    /* 71 */ SyscallDesc("setregid", unimplementedFunc),
+    /* 72 */ SyscallDesc("sigsuspend", unimplementedFunc),
+    /* 73 */ SyscallDesc("sigpending", unimplementedFunc),
+    /* 74 */ SyscallDesc("sethostname", ignoreFunc),
+    /* 75 */ SyscallDesc("setrlimit", ignoreFunc),
+    /* 76 */ SyscallDesc("getrlimit", unimplementedFunc),
+    /* 77 */ SyscallDesc("getrusage", ignoreFunc),
+    /* 78 */ SyscallDesc("gettimeofday", unimplementedFunc),
+    /* 79 */ SyscallDesc("settimeofday", unimplementedFunc),
+    /* 80 */ SyscallDesc("getgroups", unimplementedFunc),
+    /* 81 */ SyscallDesc("setgroups", unimplementedFunc),
+    /* 82 */ SyscallDesc("reserved#82", unimplementedFunc),
+    /* 83 */ SyscallDesc("symlink", unimplementedFunc),
+    /* 84 */ SyscallDesc("unused#84", unimplementedFunc),
+    /* 85 */ SyscallDesc("readlink", unimplementedFunc),
+    /* 86 */ SyscallDesc("uselib", unimplementedFunc),
+    /* 87 */ SyscallDesc("swapon", gethostnameFunc),
+    /* 88 */ SyscallDesc("reboot", unimplementedFunc),
+    /* 89 */ SyscallDesc("readdir", unimplementedFunc),
+    /* 90 */ SyscallDesc("mmap", mmapFunc<PowerLinux>),
+    /* 91 */ SyscallDesc("munmap",munmapFunc),
+    /* 92 */ SyscallDesc("truncate", truncateFunc),
+    /* 93 */ SyscallDesc("ftruncate", ftruncateFunc),
+    /* 94 */ SyscallDesc("fchmod", unimplementedFunc),
+    /* 95 */ SyscallDesc("fchown", unimplementedFunc),
+    /* 96 */ SyscallDesc("getpriority", unimplementedFunc),
+    /* 97 */ SyscallDesc("setpriority", unimplementedFunc),
+    /* 98 */ SyscallDesc("profil", unimplementedFunc),
+    /* 99 */ SyscallDesc("statfs", unimplementedFunc),
+    /* 100 */ SyscallDesc("fstatfs", unimplementedFunc),
+    /* 101 */ SyscallDesc("ioperm", unimplementedFunc),
+    /* 102 */ SyscallDesc("socketcall", unimplementedFunc),
+    /* 103 */ SyscallDesc("syslog", unimplementedFunc),
+    /* 104 */ SyscallDesc("setitimer", unimplementedFunc),
+    /* 105 */ SyscallDesc("getitimer", unimplementedFunc),
+    /* 106 */ SyscallDesc("stat",  statFunc<PowerLinux>),
+    /* 107 */ SyscallDesc("lstat", unimplementedFunc),
+    /* 108 */ SyscallDesc("fstat", fstatFunc<PowerLinux>),
+    /* 109 */ SyscallDesc("unused#109", unimplementedFunc),
+    /* 110 */ SyscallDesc("iopl", unimplementedFunc),
+    /* 111 */ SyscallDesc("vhangup", unimplementedFunc),
+    /* 112 */ SyscallDesc("idle", ignoreFunc),
+    /* 113 */ SyscallDesc("vm86", unimplementedFunc),
+    /* 114 */ SyscallDesc("wait4", unimplementedFunc),
+    /* 115 */ SyscallDesc("swapoff", unimplementedFunc),
+    /* 116 */ SyscallDesc("sysinfo", unimplementedFunc),
+    /* 117 */ SyscallDesc("ipc", unimplementedFunc),
+    /* 118 */ SyscallDesc("fsync", unimplementedFunc),
+    /* 119 */ SyscallDesc("sigreturn", unimplementedFunc),
+    /* 120 */ SyscallDesc("clone", unimplementedFunc),
+    /* 121 */ SyscallDesc("setdomainname", unimplementedFunc),
+    /* 122 */ SyscallDesc("uname", unameFunc),
+    /* 123 */ SyscallDesc("modify_ldt", unimplementedFunc),
+    /* 124 */ SyscallDesc("adjtimex", unimplementedFunc),
+    /* 125 */ SyscallDesc("mprotect", ignoreFunc),
+    /* 126 */ SyscallDesc("sigprocmask", unimplementedFunc),
+    /* 127 */ SyscallDesc("create_module", unimplementedFunc),
+    /* 128 */ SyscallDesc("init_module", unimplementedFunc),
+    /* 129 */ SyscallDesc("delete_module", unimplementedFunc),
+    /* 130 */ SyscallDesc("get_kernel_syms", unimplementedFunc),
+    /* 131 */ SyscallDesc("quotactl", unimplementedFunc),
+    /* 132 */ SyscallDesc("getpgid", unimplementedFunc),
+    /* 133 */ SyscallDesc("fchdir", unimplementedFunc),
+    /* 134 */ SyscallDesc("bdflush", unimplementedFunc),
+    /* 135 */ SyscallDesc("sysfs", unimplementedFunc),
+    /* 136 */ SyscallDesc("personality", unimplementedFunc),
+    /* 137 */ SyscallDesc("afs_syscall", unimplementedFunc),
+    /* 138 */ SyscallDesc("setfsuid", unimplementedFunc),
+    /* 139 */ SyscallDesc("setfsgid", unimplementedFunc),
+    /* 140 */ SyscallDesc("llseek", _llseekFunc),
+    /* 141 */ SyscallDesc("getdents", unimplementedFunc),
+    /* 142 */ SyscallDesc("newselect", unimplementedFunc),
+    /* 143 */ SyscallDesc("flock", unimplementedFunc),
+    /* 144 */ SyscallDesc("msync", unimplementedFunc),
+    /* 145 */ SyscallDesc("readv", unimplementedFunc),
+    /* 146 */ SyscallDesc("writev", writevFunc<PowerLinux>),
+    /* 147 */ SyscallDesc("getsid", unimplementedFunc),
+    /* 148 */ SyscallDesc("fdatasync", unimplementedFunc),
+    /* 149 */ SyscallDesc("sysctl", unimplementedFunc),
+    /* 150 */ SyscallDesc("mlock", unimplementedFunc),
+    /* 151 */ SyscallDesc("munlock", unimplementedFunc),
+    /* 152 */ SyscallDesc("mlockall", unimplementedFunc),
+    /* 153 */ SyscallDesc("munlockall", unimplementedFunc),
+    /* 154 */ SyscallDesc("sched_setparam", unimplementedFunc),
+    /* 155 */ SyscallDesc("sched_getparam", unimplementedFunc),
+    /* 156 */ SyscallDesc("sched_setscheduler", unimplementedFunc),
+    /* 157 */ SyscallDesc("sched_getscheduler", unimplementedFunc),
+    /* 158 */ SyscallDesc("sched_yield", unimplementedFunc),
+    /* 159 */ SyscallDesc("sched_get_priority_max", unimplementedFunc),
+    /* 160 */ SyscallDesc("sched_get_priority_min", unimplementedFunc),
+    /* 161 */ SyscallDesc("sched_rr_get_interval", unimplementedFunc),
+    /* 162 */ SyscallDesc("nanosleep", unimplementedFunc),
+    /* 163 */ SyscallDesc("mremap", unimplementedFunc),
+    /* 164 */ SyscallDesc("setresuid", unimplementedFunc),
+    /* 165 */ SyscallDesc("getresuid", unimplementedFunc),
+    /* 166 */ SyscallDesc("vm862", unimplementedFunc),
+    /* 167 */ SyscallDesc("query_module", unimplementedFunc),
+    /* 168 */ SyscallDesc("poll", unimplementedFunc),
+    /* 169 */ SyscallDesc("nfsservctl", unimplementedFunc),
+    /* 170 */ SyscallDesc("setresgid", unimplementedFunc),
+    /* 171 */ SyscallDesc("getresgid", unimplementedFunc),
+    /* 172 */ SyscallDesc("prctl", unimplementedFunc),
+    /* 173 */ SyscallDesc("rt_sigaction", ignoreFunc),
+    /* 174 */ SyscallDesc("rt_sigprocmask", unimplementedFunc),
+    /* 175 */ SyscallDesc("unknown#175", unimplementedFunc),
+    /* 176 */ SyscallDesc("rt_sigpending", unimplementedFunc),
+    /* 177 */ SyscallDesc("rt_sigtimedwait", unimplementedFunc),
+    /* 178 */ SyscallDesc("rt_sigqueueinfo", ignoreFunc),
+    /* 179 */ SyscallDesc("rt_sigsuspend", unimplementedFunc),
+    /* 180 */ SyscallDesc("pread64", unimplementedFunc),
+    /* 181 */ SyscallDesc("pwrite64", unimplementedFunc),
+    /* 182 */ SyscallDesc("chown", unimplementedFunc),
+    /* 183 */ SyscallDesc("getcwd", unimplementedFunc),
+    /* 184 */ SyscallDesc("capget", unimplementedFunc),
+    /* 185 */ SyscallDesc("capset", unimplementedFunc),
+    /* 186 */ SyscallDesc("sigaltstack", unimplementedFunc),
+    /* 187 */ SyscallDesc("sendfile", unimplementedFunc),
+    /* 188 */ SyscallDesc("getpmsg", unimplementedFunc),
+    /* 189 */ SyscallDesc("putpmsg", unimplementedFunc),
+    /* 190 */ SyscallDesc("ugetrlimit", ignoreFunc),
+    /* 191 */ SyscallDesc("getrlimit", unimplementedFunc),
+    /* 192 */ SyscallDesc("mmap2", mmapFunc<PowerLinux>),
+    /* 193 */ SyscallDesc("truncate64", unimplementedFunc),
+    /* 194 */ SyscallDesc("ftruncate64", ftruncate64Func),
+    /* 195 */ SyscallDesc("stat64", stat64Func<PowerLinux>),
+    /* 196 */ SyscallDesc("lstat64", lstat64Func<PowerLinux>),
+    /* 197 */ SyscallDesc("fstat64", fstat64Func<PowerLinux>),
+    /* 198 */ SyscallDesc("lchown", unimplementedFunc),
+    /* 199 */ SyscallDesc("getuid", getuidFunc),
+    /* 200 */ SyscallDesc("getgid", getgidFunc),
+    /* 201 */ SyscallDesc("geteuid", geteuidFunc),
+    /* 202 */ SyscallDesc("getegid", getegidFunc),
+    /* 203 */ SyscallDesc("setreuid", unimplementedFunc),
+    /* 204 */ SyscallDesc("fcntl64", fcntl64Func),
+    /* 205 */ SyscallDesc("getgroups", unimplementedFunc),
+    /* 206 */ SyscallDesc("setgroups", unimplementedFunc),
+    /* 207 */ SyscallDesc("fchown", unimplementedFunc),
+    /* 208 */ SyscallDesc("setresuid", unimplementedFunc),
+    /* 209 */ SyscallDesc("getresuid", unimplementedFunc),
+    /* 210 */ SyscallDesc("setresgid", unimplementedFunc),
+    /* 211 */ SyscallDesc("getresgid", unimplementedFunc),
+    /* 212 */ SyscallDesc("chown", unimplementedFunc),
+    /* 213 */ SyscallDesc("setuid", unimplementedFunc),
+    /* 214 */ SyscallDesc("setgid", unimplementedFunc),
+    /* 215 */ SyscallDesc("setfsuid", unimplementedFunc),
+    /* 216 */ SyscallDesc("setfsgid", unimplementedFunc),
+    /* 217 */ SyscallDesc("getdents64", unimplementedFunc),
+    /* 218 */ SyscallDesc("pivot_root", unimplementedFunc),
+    /* 219 */ SyscallDesc("mincore", unimplementedFunc),
+    /* 220 */ SyscallDesc("madvise", unimplementedFunc),
+    /* 221 */ SyscallDesc("unknown#221", unimplementedFunc),
+    /* 222 */ SyscallDesc("tux", unimplementedFunc),
+    /* 223 */ SyscallDesc("unknown#223", unimplementedFunc),
+    /* 224 */ SyscallDesc("gettid", unimplementedFunc),
+    /* 225 */ SyscallDesc("readahead", unimplementedFunc),
+    /* 226 */ SyscallDesc("setxattr", unimplementedFunc),
+    /* 227 */ SyscallDesc("lsetxattr", unimplementedFunc),
+    /* 228 */ SyscallDesc("fsetxattr", unimplementedFunc),
+    /* 229 */ SyscallDesc("getxattr", unimplementedFunc),
+    /* 230 */ SyscallDesc("lgetxattr", unimplementedFunc),
+    /* 231 */ SyscallDesc("fgetxattr", unimplementedFunc),
+    /* 232 */ SyscallDesc("listxattr", unimplementedFunc),
+    /* 233 */ SyscallDesc("llistxattr", unimplementedFunc),
+    /* 234 */ SyscallDesc("exit_group", exitGroupFunc),
+    /* 235 */ SyscallDesc("removexattr", unimplementedFunc),
+    /* 236 */ SyscallDesc("lremovexattr", unimplementedFunc),
+    /* 237 */ SyscallDesc("fremovexattr", unimplementedFunc),
+    /* 238 */ SyscallDesc("tkill", unimplementedFunc),
+    /* 239 */ SyscallDesc("sendfile64", unimplementedFunc),
+    /* 240 */ SyscallDesc("futex", unimplementedFunc),
+    /* 241 */ SyscallDesc("sched_setaffinity", unimplementedFunc),
+    /* 242 */ SyscallDesc("sched_getaffinity", unimplementedFunc),
+    /* 243 */ SyscallDesc("io_setup", unimplementedFunc),
+    /* 244 */ SyscallDesc("io_destory", unimplementedFunc),
+    /* 245 */ SyscallDesc("io_getevents", unimplementedFunc),
+    /* 246 */ SyscallDesc("io_submit", unimplementedFunc),
+    /* 247 */ SyscallDesc("io_cancel", unimplementedFunc),
+    /* 248 */ SyscallDesc("unknown#248", unimplementedFunc),
+    /* 249 */ SyscallDesc("lookup_dcookie", unimplementedFunc),
+    /* 250 */ SyscallDesc("epoll_create", unimplementedFunc),
+    /* 251 */ SyscallDesc("epoll_ctl", unimplementedFunc),
+    /* 252 */ SyscallDesc("epoll_wait", unimplementedFunc),
+    /* 253 */ SyscallDesc("remap_file_pages", unimplementedFunc),
+    /* 254 */ SyscallDesc("set_thread_area", unimplementedFunc),
+    /* 255 */ SyscallDesc("get_thread_area", unimplementedFunc),
+    /* 256 */ SyscallDesc("set_tid_address", unimplementedFunc),
+    /* 257 */ SyscallDesc("timer_create", unimplementedFunc),
+    /* 258 */ SyscallDesc("timer_settime", unimplementedFunc),
+    /* 259 */ SyscallDesc("timer_gettime", unimplementedFunc),
+    /* 260 */ SyscallDesc("timer_getoverrun", unimplementedFunc),
+    /* 261 */ SyscallDesc("timer_delete", unimplementedFunc),
+    /* 262 */ SyscallDesc("clock_settime", unimplementedFunc),
+    /* 263 */ SyscallDesc("clock_gettime", unimplementedFunc),
+    /* 264 */ SyscallDesc("clock_getres", unimplementedFunc),
+    /* 265 */ SyscallDesc("clock_nanosleep", unimplementedFunc),
+    /* 266 */ SyscallDesc("statfs64", unimplementedFunc),
+    /* 267 */ SyscallDesc("fstatfs64", unimplementedFunc),
+    /* 268 */ SyscallDesc("tgkill", unimplementedFunc),
+    /* 269 */ SyscallDesc("utimes", unimplementedFunc),
+    /* 270 */ SyscallDesc("arm_fadvise64_64", unimplementedFunc),
+    /* 271 */ SyscallDesc("pciconfig_iobase", unimplementedFunc),
+    /* 272 */ SyscallDesc("pciconfig_read", unimplementedFunc),
+    /* 273 */ SyscallDesc("pciconfig_write", unimplementedFunc),
+    /* 274 */ SyscallDesc("mq_open", unimplementedFunc),
+    /* 275 */ SyscallDesc("mq_unlink", unimplementedFunc),
+    /* 276 */ SyscallDesc("mq_timedsend", unimplementedFunc),
+    /* 277 */ SyscallDesc("mq_timedreceive", unimplementedFunc),
+    /* 278 */ SyscallDesc("mq_notify", unimplementedFunc),
+    /* 279 */ SyscallDesc("mq_getsetattr", unimplementedFunc),
+    /* 280 */ SyscallDesc("waitid", unimplementedFunc),
+    /* 281 */ SyscallDesc("socket", unimplementedFunc),
+    /* 282 */ SyscallDesc("bind", unimplementedFunc),
+    /* 283 */ SyscallDesc("connect", unimplementedFunc),
+    /* 284 */ SyscallDesc("listen", unimplementedFunc),
+    /* 285 */ SyscallDesc("accept", unimplementedFunc),
+    /* 286 */ SyscallDesc("getsockname", unimplementedFunc),
+    /* 287 */ SyscallDesc("getpeername", unimplementedFunc),
+    /* 288 */ SyscallDesc("socketpair", unimplementedFunc),
+    /* 289 */ SyscallDesc("send", unimplementedFunc),
+    /* 290 */ SyscallDesc("sendto", unimplementedFunc),
+    /* 291 */ SyscallDesc("recv", unimplementedFunc),
+    /* 292 */ SyscallDesc("recvfrom", unimplementedFunc),
+    /* 293 */ SyscallDesc("shutdown", unimplementedFunc),
+    /* 294 */ SyscallDesc("setsockopt", unimplementedFunc),
+    /* 295 */ SyscallDesc("getsockopt", unimplementedFunc),
+    /* 296 */ SyscallDesc("sendmsg", unimplementedFunc),
+    /* 297 */ SyscallDesc("rcvmsg", unimplementedFunc),
+    /* 298 */ SyscallDesc("semop", unimplementedFunc),
+    /* 299 */ SyscallDesc("semget", unimplementedFunc),
+    /* 300 */ SyscallDesc("semctl", unimplementedFunc),
+    /* 301 */ SyscallDesc("msgsend", unimplementedFunc),
+    /* 302 */ SyscallDesc("msgrcv", unimplementedFunc),
+    /* 303 */ SyscallDesc("msgget", unimplementedFunc),
+    /* 304 */ SyscallDesc("msgctl", unimplementedFunc),
+    /* 305 */ SyscallDesc("shmat", unimplementedFunc),
+    /* 306 */ SyscallDesc("shmdt", unimplementedFunc),
+    /* 307 */ SyscallDesc("shmget", unimplementedFunc),
+    /* 308 */ SyscallDesc("shmctl", unimplementedFunc),
+    /* 309 */ SyscallDesc("add_key", unimplementedFunc),
+    /* 310 */ SyscallDesc("request_key", unimplementedFunc),
+    /* 311 */ SyscallDesc("keyctl", unimplementedFunc),
+    /* 312 */ SyscallDesc("semtimedop", unimplementedFunc),
+    /* 313 */ SyscallDesc("vserver", unimplementedFunc),
+    /* 314 */ SyscallDesc("ioprio_set", unimplementedFunc),
+    /* 315 */ SyscallDesc("ioprio_get", unimplementedFunc),
+    /* 316 */ SyscallDesc("inotify_init", unimplementedFunc),
+    /* 317 */ SyscallDesc("inotify_add_watch", unimplementedFunc),
+    /* 318 */ SyscallDesc("inotify_rm_watch", unimplementedFunc),
+    /* 319 */ SyscallDesc("mbind", unimplementedFunc),
+    /* 320 */ SyscallDesc("get_mempolicy", unimplementedFunc),
+    /* 321 */ SyscallDesc("set_mempolicy", unimplementedFunc),
+    /* 322 */ SyscallDesc("openat", unimplementedFunc),
+    /* 323 */ SyscallDesc("mkdirat", unimplementedFunc),
+    /* 324 */ SyscallDesc("mknodat", unimplementedFunc),
+    /* 325 */ SyscallDesc("fchownat", unimplementedFunc),
+    /* 326 */ SyscallDesc("futimesat", unimplementedFunc),
+    /* 327 */ SyscallDesc("fstatat64", unimplementedFunc),
+    /* 328 */ SyscallDesc("unlinkat", unimplementedFunc),
+    /* 329 */ SyscallDesc("renameat", unimplementedFunc),
+    /* 330 */ SyscallDesc("linkat", unimplementedFunc),
+    /* 331 */ SyscallDesc("symlinkat", unimplementedFunc),
+    /* 332 */ SyscallDesc("readlinkat", unimplementedFunc),
+    /* 333 */ SyscallDesc("fchmodat", unimplementedFunc),
+    /* 334 */ SyscallDesc("faccessat", unimplementedFunc),
+    /* 335 */ SyscallDesc("pselect6", unimplementedFunc),
+    /* 336 */ SyscallDesc("ppoll", unimplementedFunc),
+    /* 337 */ SyscallDesc("unshare", unimplementedFunc),
+    /* 338 */ SyscallDesc("set_robust_list", unimplementedFunc),
+    /* 339 */ SyscallDesc("get_robust_list", unimplementedFunc),
+    /* 340 */ SyscallDesc("splice", unimplementedFunc),
+    /* 341 */ SyscallDesc("arm_sync_file_range", unimplementedFunc),
+    /* 342 */ SyscallDesc("tee", unimplementedFunc),
+    /* 343 */ SyscallDesc("vmsplice", unimplementedFunc),
+    /* 344 */ SyscallDesc("move_pages", unimplementedFunc),
+    /* 345 */ SyscallDesc("getcpu", unimplementedFunc),
+    /* 346 */ SyscallDesc("epoll_pwait", unimplementedFunc),
+};
+
+PowerLinuxProcess::PowerLinuxProcess(LiveProcessParams * params,
+        ObjectFile *objFile)
+    : PowerLiveProcess(params, objFile),
+     Num_Syscall_Descs(sizeof(syscallDescs) / sizeof(SyscallDesc))
+{
+}
+
+SyscallDesc*
+PowerLinuxProcess::getDesc(int callnum)
+{
+    if (callnum < 0 || callnum > Num_Syscall_Descs)
+        return NULL;
+
+    return &syscallDescs[callnum];
+}
+
+void
+PowerLinuxProcess::startup()
+{
+    PowerLiveProcess::startup();
+}
+
+PowerISA::IntReg
+PowerLinuxProcess::getSyscallArg(ThreadContext *tc, int i)
+{
+    // Linux apparently allows more parameter than the ABI says it should.
+    // This limit may need to be increased even further.
+    assert(i < 6);
+    return tc->readIntReg(ArgumentReg0 + i);
+}
+
+void
+PowerLinuxProcess::setSyscallArg(ThreadContext *tc, int i, PowerISA::IntReg val)
+{
+    // Linux apparently allows more parameter than the ABI says it should.
+    // This limit may need to be increased even further.
+    assert(i < 6);
+    tc->setIntReg(ArgumentReg0 + i, val);
+}
diff --git a/src/arch/power/linux/process.hh b/src/arch/power/linux/process.hh
new file mode 100644 (file)
index 0000000..78b0eef
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * 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
+ */
+
+#ifndef __POWER_LINUX_PROCESS_HH__
+#define __POWER_LINUX_PROCESS_HH__
+
+#include "arch/power/process.hh"
+
+
+/// A process with emulated PPC/Linux syscalls.
+class PowerLinuxProcess : public PowerLiveProcess
+{
+  public:
+    PowerLinuxProcess(LiveProcessParams * params, ObjectFile *objFile);
+
+    virtual SyscallDesc* getDesc(int callnum);
+
+    void startup();
+
+    PowerISA::IntReg getSyscallArg(ThreadContext *tc, int i);
+    void setSyscallArg(ThreadContext *tc, int i, PowerISA::IntReg val);
+
+    /// Array of syscall descriptors, indexed by call number.
+    static SyscallDesc syscallDescs[];
+
+    const int Num_Syscall_Descs;
+};
+
+#endif // __POWER_LINUX_PROCESS_HH__
diff --git a/src/arch/power/locked_mem.hh b/src/arch/power/locked_mem.hh
new file mode 100644 (file)
index 0000000..56ab1d4
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2006 The Regents of The University of Michigan
+ * 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: Steve Reinhardt
+ *          Stephen Hines
+ *          Timothy M. Jones
+ */
+
+#ifndef __ARCH_POWER_LOCKED_MEM_HH__
+#define __ARCH_POWER_LOCKED_MEM_HH__
+
+/**
+ * @file
+ *
+ * ISA-specific helper functions for locked memory accesses.
+ */
+
+#include "mem/request.hh"
+
+namespace PowerISA
+{
+
+template <class XC>
+inline void
+handleLockedRead(XC *xc, Request *req)
+{
+}
+
+template <class XC>
+inline bool
+handleLockedWrite(XC *xc, Request *req)
+{
+    return true;
+}
+
+} // PowerISA namespace
+
+#endif // __ARCH_POWER_LOCKED_MEM_HH__
diff --git a/src/arch/power/microcode_rom.hh b/src/arch/power/microcode_rom.hh
new file mode 100644 (file)
index 0000000..e35db51
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2008 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: Gabe Black
+ *          Timothy M. Jones
+ */
+
+#ifndef __ARCH_POWER_MICROCODE_ROM_HH__
+#define __ARCH_POWER_MICROCODE_ROM_HH__
+
+#include "sim/microcode_rom.hh"
+
+namespace PowerISA
+{
+
+using ::MicrocodeRom;
+
+} // PowerISA namespace
+
+#endif // __ARCH_POWER_MICROCODE_ROM_HH__
diff --git a/src/arch/power/miscregs.hh b/src/arch/power/miscregs.hh
new file mode 100644 (file)
index 0000000..cd9815b
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+ * 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
+ */
+
+#ifndef __ARCH_POWER_MISCREGS_HH__
+#define __ARCH_POWER_MISCREGS_HH__
+
+#include "base/bitunion.hh"
+
+namespace PowerISA
+{
+
+enum MiscRegIndex {
+    NUM_MISCREGS = 0
+};
+
+const char * const miscRegName[NUM_MISCREGS] = {
+};
+
+BitUnion32(Cr)
+    Bitfield<31,28> cr0;
+    Bitfield<27,24> cr1;
+EndBitUnion(Cr)
+
+BitUnion32(Xer)
+    Bitfield<31> so;
+    Bitfield<30> ov;
+    Bitfield<29> ca;
+EndBitUnion(Xer)
+
+BitUnion32(Fpscr)
+    Bitfield<31> fx;
+    Bitfield<30> fex;
+    Bitfield<29> vx;
+    Bitfield<28> ox;
+    Bitfield<27> ux;
+    Bitfield<26> zx;
+    Bitfield<25> xx;
+    Bitfield<24> vxsnan;
+    Bitfield<23> vxisi;
+    Bitfield<22> vxidi;
+    Bitfield<21> vxzdz;
+    Bitfield<20> vximz;
+    Bitfield<19> vxvc;
+    Bitfield<18> fr;
+    Bitfield<17> fi;
+    SubBitUnion(fprf, 16, 12)
+        Bitfield<16> c;
+        SubBitUnion(fpcc, 15, 12)
+            Bitfield<15> fl;
+            Bitfield<14> fg;
+            Bitfield<13> fe;
+            Bitfield<12> fu;
+        EndSubBitUnion(fpcc)
+    EndSubBitUnion(fprf)
+    Bitfield<10> vxsqrt;
+    Bitfield<9> vxcvi;
+    Bitfield<8> ve;
+    Bitfield<7> oe;
+    Bitfield<6> ue;
+    Bitfield<5> ze;
+    Bitfield<4> xe;
+    Bitfield<3> ni;
+    Bitfield<2,1> rn;
+EndBitUnion(Fpscr)
+
+}; // PowerISA namespace
+
+#endif // __ARCH_POWER_MISCREGS_HH__
diff --git a/src/arch/power/mmaped_ipr.hh b/src/arch/power/mmaped_ipr.hh
new file mode 100644 (file)
index 0000000..bd1ea10
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2006 The Regents of The University of Michigan
+ * 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: Ali Saidi
+ *          Stephen Hines
+ *          Timothy M. Jones
+ */
+
+#ifndef __ARCH_POWER_MMAPED_IPR_HH__
+#define __ARCH_POWER_MMAPED_IPR_HH__
+
+/**
+ * @file
+ *
+ * ISA-specific helper functions for memory mapped IPR accesses.
+ */
+
+#include "base/misc.hh"
+#include "mem/packet.hh"
+
+class ThreadContext;
+
+namespace PowerISA
+{
+
+inline Tick
+handleIprRead(ThreadContext *xc, Packet *pkt)
+{
+    panic("No implementation for handleIprRead in POWER\n");
+}
+
+inline Tick
+handleIprWrite(ThreadContext *xc, Packet *pkt)
+{
+    panic("No implementation for handleIprWrite in POWER\n");
+}
+
+} // PowerISA namespace
+
+#endif // __ARCH_POWER_MMAPED_IPR_HH__
diff --git a/src/arch/power/pagetable.cc b/src/arch/power/pagetable.cc
new file mode 100644 (file)
index 0000000..8624045
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2002-2005 The Regents of The University of Michigan
+ * Copyright (c) 2007 MIPS Technologies, Inc.
+ * 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: Nathan Binkert
+ *          Steve Reinhardt
+ *          Jaidev Patwardhan
+ *          Stephen Hines
+ *          Timothy M. Jones
+ */
+
+#include "arch/power/pagetable.hh"
+#include "sim/serialize.hh"
+
+namespace PowerISA
+{
+
+void
+PTE::serialize(std::ostream &os)
+{
+    SERIALIZE_SCALAR(Mask);
+    SERIALIZE_SCALAR(VPN);
+    SERIALIZE_SCALAR(asid);
+    SERIALIZE_SCALAR(G);
+    SERIALIZE_SCALAR(PFN0);
+    SERIALIZE_SCALAR(D0);
+    SERIALIZE_SCALAR(V0);
+    SERIALIZE_SCALAR(C0);
+    SERIALIZE_SCALAR(PFN1);
+    SERIALIZE_SCALAR(D1);
+    SERIALIZE_SCALAR(V1);
+    SERIALIZE_SCALAR(C1);
+    SERIALIZE_SCALAR(AddrShiftAmount);
+    SERIALIZE_SCALAR(OffsetMask);
+}
+
+void
+PTE::unserialize(Checkpoint *cp, const std::string &section)
+{
+    UNSERIALIZE_SCALAR(Mask);
+    UNSERIALIZE_SCALAR(VPN);
+    UNSERIALIZE_SCALAR(asid);
+    UNSERIALIZE_SCALAR(G);
+    UNSERIALIZE_SCALAR(PFN0);
+    UNSERIALIZE_SCALAR(D0);
+    UNSERIALIZE_SCALAR(V0);
+    UNSERIALIZE_SCALAR(C0);
+    UNSERIALIZE_SCALAR(PFN1);
+    UNSERIALIZE_SCALAR(D1);
+    UNSERIALIZE_SCALAR(V1);
+    UNSERIALIZE_SCALAR(C1);
+    UNSERIALIZE_SCALAR(AddrShiftAmount);
+    UNSERIALIZE_SCALAR(OffsetMask);
+}
+
+} // PowerISA namespace
diff --git a/src/arch/power/pagetable.hh b/src/arch/power/pagetable.hh
new file mode 100644 (file)
index 0000000..bd2b9d3
--- /dev/null
@@ -0,0 +1,158 @@
+/*
+ * Copyright (c) 2002-2005 The Regents of The University of Michigan
+ * Copyright (c) 2007 MIPS Technologies, Inc.
+ * 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: Nathan Binkert
+ *          Steve Reinhardt
+ *          Jaidev Patwardhan
+ *          Stephen Hines
+ *          Timothy M. Jones
+ */
+
+#ifndef __ARCH_POWER_PAGETABLE_H__
+#define __ARCH_POWER_PAGETABLE_H__
+
+#include "arch/power/isa_traits.hh"
+#include "arch/power/utility.hh"
+#include "arch/power/vtophys.hh"
+#include "config/full_system.hh"
+
+namespace PowerISA {
+
+struct VAddr
+{
+    static const int ImplBits = 43;
+    static const Addr ImplMask = (ULL(1) << ImplBits) - 1;
+    static const Addr UnImplMask = ~ImplMask;
+
+    Addr addr;
+
+    VAddr(Addr a)
+        : addr(a)
+    {}
+
+    operator Addr() const
+    {
+        return addr;
+    }
+
+    const VAddr
+    &operator=(Addr a)
+    {
+        addr = a;
+        return *this;
+    }
+
+    Addr
+    vpn() const
+    {
+        return (addr & ImplMask) >> PageShift;
+    }
+
+    Addr
+    page() const
+    {
+        return addr & Page_Mask;
+    }
+
+    Addr
+    offset() const
+    {
+        return addr & PageOffset;
+    }
+
+    Addr
+    level3() const
+    {
+        return PowerISA::PteAddr(addr >> PageShift);
+    }
+
+    Addr
+    level2() const
+    {
+        return PowerISA::PteAddr(addr >> (NPtePageShift + PageShift));
+    }
+
+    Addr
+    level1() const
+    {
+        return PowerISA::PteAddr(addr >> (2 * NPtePageShift + PageShift));
+    }
+};
+
+// ITB/DTB page table entry
+struct PTE
+{
+    // What parts of the VAddr (from bits 28..11) should be used in
+    // translation (includes Mask and MaskX from PageMask)
+    Addr Mask;
+
+    // Virtual Page Number (/2) (Includes VPN2 + VPN2X .. bits 31..11
+    // from EntryHi)
+    Addr VPN;
+
+    // Address Space ID (8 bits) // Lower 8 bits of EntryHi
+    uint8_t asid;
+
+    // Global Bit - Obtained by an *AND* of EntryLo0 and EntryLo1 G bit
+    bool G;
+
+    /* Contents of Entry Lo0 */
+    Addr PFN0; // Physical Frame Number - Even
+    bool D0;   // Even entry Dirty Bit
+    bool V0;   // Even entry Valid Bit
+    uint8_t C0; // Cache Coherency Bits - Even
+
+    /* Contents of Entry Lo1 */
+    Addr PFN1; // Physical Frame Number - Odd
+    bool D1;   // Odd entry Dirty Bit
+    bool V1;   // Odd entry Valid Bit
+    uint8_t C1; // Cache Coherency Bits (3 bits)
+
+    // The next few variables are put in as optimizations to reduce TLB
+    // lookup overheads. For a given Mask, what is the address shift amount
+    // and what is the OffsetMask
+    int AddrShiftAmount;
+    int OffsetMask;
+
+    bool
+    Valid()
+    {
+        return (V0 | V1);
+    };
+
+    void serialize(std::ostream &os);
+
+    void unserialize(Checkpoint *cp, const std::string &section);
+};
+
+} // PowerISA namespace
+
+#endif // __ARCH_POWER_PAGETABLE_H__
+
diff --git a/src/arch/power/predecoder.hh b/src/arch/power/predecoder.hh
new file mode 100644 (file)
index 0000000..1f3ac41
--- /dev/null
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) 2006 The Regents of The University of Michigan
+ * 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: Gabe Black
+ *          Stephen Hines
+ *          Timothy M. Jones
+ */
+
+#ifndef __ARCH_ARM_PREDECODER_HH__
+#define __ARCH_ARM_PREDECODER_HH__
+
+#include "arch/power/types.hh"
+#include "base/misc.hh"
+#include "base/types.hh"
+
+class ThreadContext;
+
+namespace PowerISA
+{
+
+class Predecoder
+{
+  protected:
+    ThreadContext * tc;
+
+    // The extended machine instruction being generated
+    ExtMachInst emi;
+
+  public:
+    Predecoder(ThreadContext * _tc)
+        : tc(_tc)
+    {
+    }
+
+    ThreadContext *
+    getTC()
+    {
+        return tc;
+    }
+
+    void
+    setTC(ThreadContext * _tc)
+    {
+        tc = _tc;
+    }
+
+    void
+    process()
+    {
+    }
+
+    void
+    reset()
+    {
+    }
+
+    // Use this to give data to the predecoder. This should be used
+    // when there is control flow.
+    void
+    moreBytes(Addr pc, Addr fetchPC, MachInst inst)
+    {
+        emi = inst;
+    }
+
+    // Use this to give data to the predecoder. This should be used
+    // when instructions are executed in order.
+    void
+    moreBytes(MachInst machInst)
+    {
+        moreBytes(0, 0, machInst);
+    }
+
+    bool
+    needMoreBytes()
+    {
+        return true;
+    }
+
+    bool
+    extMachInstReady()
+    {
+        return true;
+    }
+
+    // This returns a constant reference to the ExtMachInst to avoid a copy
+    const ExtMachInst &
+    getExtMachInst()
+    {
+        return emi;
+    }
+};
+
+} // PowerISA namespace
+
+#endif // __ARCH_POWER_PREDECODER_HH__
diff --git a/src/arch/power/process.cc b/src/arch/power/process.cc
new file mode 100644 (file)
index 0000000..8828a1a
--- /dev/null
@@ -0,0 +1,288 @@
+/*
+ * 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
+ */
+
+#include "arch/power/isa_traits.hh"
+#include "arch/power/process.hh"
+#include "arch/power/types.hh"
+#include "base/loader/elf_object.hh"
+#include "base/loader/object_file.hh"
+#include "base/misc.hh"
+#include "cpu/thread_context.hh"
+#include "mem/page_table.hh"
+#include "mem/translating_port.hh"
+#include "sim/process_impl.hh"
+#include "sim/system.hh"
+
+using namespace std;
+using namespace PowerISA;
+
+PowerLiveProcess::PowerLiveProcess(LiveProcessParams *params,
+        ObjectFile *objFile)
+    : LiveProcess(params, objFile)
+{
+    stack_base = 0xbf000000L;
+
+    // Set pointer for next thread stack.  Reserve 8M for main stack.
+    next_thread_stack_base = stack_base - (8 * 1024 * 1024);
+
+    // Set up break point (Top of Heap)
+    brk_point = objFile->dataBase() + objFile->dataSize() + objFile->bssSize();
+    brk_point = roundUp(brk_point, VMPageSize);
+
+    // Set up region for mmaps. For now, start at bottom of kuseg space.
+    mmap_start = mmap_end = 0x70000000L;
+}
+
+void
+PowerLiveProcess::startup()
+{
+    argsInit(MachineBytes, VMPageSize);
+}
+
+void
+PowerLiveProcess::argsInit(int intSize, int pageSize)
+{
+    typedef AuxVector<uint32_t> auxv_t;
+    std::vector<auxv_t> auxv;
+
+    string filename;
+    if (argv.size() < 1)
+        filename = "";
+    else
+        filename = argv[0];
+
+    //We want 16 byte alignment
+    uint64_t align = 16;
+
+    // Overloaded argsInit so that we can fine-tune for POWER architecture
+    Process::startup();
+
+    // load object file into target memory
+    objFile->loadSections(initVirtMem);
+
+    //Setup the auxilliary vectors. These will already have endian conversion.
+    //Auxilliary vectors are loaded only for elf formatted executables.
+    ElfObject * elfObject = dynamic_cast<ElfObject *>(objFile);
+    if (elfObject) {
+        uint32_t features = 0;
+
+        //Bits which describe the system hardware capabilities
+        //XXX Figure out what these should be
+        auxv.push_back(auxv_t(M5_AT_HWCAP, features));
+        //The system page size
+        auxv.push_back(auxv_t(M5_AT_PAGESZ, PowerISA::VMPageSize));
+        //Frequency at which times() increments
+        auxv.push_back(auxv_t(M5_AT_CLKTCK, 0x64));
+        // For statically linked executables, this is the virtual address of the
+        // program header tables if they appear in the executable image
+        auxv.push_back(auxv_t(M5_AT_PHDR, elfObject->programHeaderTable()));
+        // This is the size of a program header entry from the elf file.
+        auxv.push_back(auxv_t(M5_AT_PHENT, elfObject->programHeaderSize()));
+        // This is the number of program headers from the original elf file.
+        auxv.push_back(auxv_t(M5_AT_PHNUM, elfObject->programHeaderCount()));
+        //This is the address of the elf "interpreter", It should be set
+        //to 0 for regular executables. It should be something else
+        //(not sure what) for dynamic libraries.
+        auxv.push_back(auxv_t(M5_AT_BASE, 0));
+
+        //XXX Figure out what this should be.
+        auxv.push_back(auxv_t(M5_AT_FLAGS, 0));
+        //The entry point to the program
+        auxv.push_back(auxv_t(M5_AT_ENTRY, objFile->entryPoint()));
+        //Different user and group IDs
+        auxv.push_back(auxv_t(M5_AT_UID, uid()));
+        auxv.push_back(auxv_t(M5_AT_EUID, euid()));
+        auxv.push_back(auxv_t(M5_AT_GID, gid()));
+        auxv.push_back(auxv_t(M5_AT_EGID, egid()));
+        //Whether to enable "secure mode" in the executable
+        auxv.push_back(auxv_t(M5_AT_SECURE, 0));
+        //The filename of the program
+        auxv.push_back(auxv_t(M5_AT_EXECFN, 0));
+        //The string "v51" with unknown meaning
+        auxv.push_back(auxv_t(M5_AT_PLATFORM, 0));
+    }
+
+    //Figure out how big the initial stack nedes to be
+
+    // A sentry NULL void pointer at the top of the stack.
+    int sentry_size = intSize;
+
+    string platform = "v51";
+    int platform_size = platform.size() + 1;
+
+    // The aux vectors are put on the stack in two groups. The first group are
+    // the vectors that are generated as the elf is loaded. The second group
+    // are the ones that were computed ahead of time and include the platform
+    // string.
+    int aux_data_size = filename.size() + 1;
+
+    int env_data_size = 0;
+    for (int i = 0; i < envp.size(); ++i) {
+        env_data_size += envp[i].size() + 1;
+    }
+    int arg_data_size = 0;
+    for (int i = 0; i < argv.size(); ++i) {
+        arg_data_size += argv[i].size() + 1;
+    }
+
+    int info_block_size =
+        sentry_size + env_data_size + arg_data_size +
+        aux_data_size + platform_size;
+
+    //Each auxilliary vector is two 4 byte words
+    int aux_array_size = intSize * 2 * (auxv.size() + 1);
+
+    int envp_array_size = intSize * (envp.size() + 1);
+    int argv_array_size = intSize * (argv.size() + 1);
+
+    int argc_size = intSize;
+
+    //Figure out the size of the contents of the actual initial frame
+    int frame_size =
+        info_block_size +
+        aux_array_size +
+        envp_array_size +
+        argv_array_size +
+        argc_size;
+
+    //There needs to be padding after the auxiliary vector data so that the
+    //very bottom of the stack is aligned properly.
+    int partial_size = frame_size;
+    int aligned_partial_size = roundUp(partial_size, align);
+    int aux_padding = aligned_partial_size - partial_size;
+
+    int space_needed = frame_size + aux_padding;
+
+    stack_min = stack_base - space_needed;
+    stack_min = roundDown(stack_min, align);
+    stack_size = stack_base - stack_min;
+
+    // map memory
+    pTable->allocate(roundDown(stack_min, pageSize),
+                     roundUp(stack_size, pageSize));
+
+    // map out initial stack contents
+    uint32_t sentry_base = stack_base - sentry_size;
+    uint32_t aux_data_base = sentry_base - aux_data_size;
+    uint32_t env_data_base = aux_data_base - env_data_size;
+    uint32_t arg_data_base = env_data_base - arg_data_size;
+    uint32_t platform_base = arg_data_base - platform_size;
+    uint32_t auxv_array_base = platform_base - aux_array_size - aux_padding;
+    uint32_t envp_array_base = auxv_array_base - envp_array_size;
+    uint32_t argv_array_base = envp_array_base - argv_array_size;
+    uint32_t argc_base = argv_array_base - argc_size;
+
+    DPRINTF(Stack, "The addresses of items on the initial stack:\n");
+    DPRINTF(Stack, "0x%x - aux data\n", aux_data_base);
+    DPRINTF(Stack, "0x%x - env data\n", env_data_base);
+    DPRINTF(Stack, "0x%x - arg data\n", arg_data_base);
+    DPRINTF(Stack, "0x%x - platform base\n", platform_base);
+    DPRINTF(Stack, "0x%x - auxv array\n", auxv_array_base);
+    DPRINTF(Stack, "0x%x - envp array\n", envp_array_base);
+    DPRINTF(Stack, "0x%x - argv array\n", argv_array_base);
+    DPRINTF(Stack, "0x%x - argc \n", argc_base);
+    DPRINTF(Stack, "0x%x - stack min\n", stack_min);
+
+    // write contents to stack
+
+    // figure out argc
+    uint32_t argc = argv.size();
+    uint32_t guestArgc = PowerISA::htog(argc);
+
+    //Write out the sentry void *
+    uint32_t sentry_NULL = 0;
+    initVirtMem->writeBlob(sentry_base,
+            (uint8_t*)&sentry_NULL, sentry_size);
+
+    //Fix up the aux vectors which point to other data
+    for (int i = auxv.size() - 1; i >= 0; i--) {
+        if (auxv[i].a_type == M5_AT_PLATFORM) {
+            auxv[i].a_val = platform_base;
+            initVirtMem->writeString(platform_base, platform.c_str());
+        } else if (auxv[i].a_type == M5_AT_EXECFN) {
+            auxv[i].a_val = aux_data_base;
+            initVirtMem->writeString(aux_data_base, filename.c_str());
+        }
+    }
+
+    //Copy the aux stuff
+    for (int x = 0; x < auxv.size(); x++)
+    {
+        initVirtMem->writeBlob(auxv_array_base + x * 2 * intSize,
+                (uint8_t*)&(auxv[x].a_type), intSize);
+        initVirtMem->writeBlob(auxv_array_base + (x * 2 + 1) * intSize,
+                (uint8_t*)&(auxv[x].a_val), intSize);
+    }
+    //Write out the terminating zeroed auxilliary vector
+    const uint64_t zero = 0;
+    initVirtMem->writeBlob(auxv_array_base + 2 * intSize * auxv.size(),
+            (uint8_t*)&zero, 2 * intSize);
+
+    copyStringArray(envp, envp_array_base, env_data_base, initVirtMem);
+    copyStringArray(argv, argv_array_base, arg_data_base, initVirtMem);
+
+    initVirtMem->writeBlob(argc_base, (uint8_t*)&guestArgc, intSize);
+
+    ThreadContext *tc = system->getThreadContext(contextIds[0]);
+
+    //Set the stack pointer register
+    tc->setIntReg(StackPointerReg, stack_min);
+
+    Addr prog_entry = objFile->entryPoint();
+    tc->setPC(prog_entry);
+    tc->setNextPC(prog_entry + sizeof(MachInst));
+
+    //Align the "stack_min" to a page boundary.
+    stack_min = roundDown(stack_min, pageSize);
+}
+
+PowerISA::IntReg
+PowerLiveProcess::getSyscallArg(ThreadContext *tc, int i)
+{
+    assert(i < 5);
+    return tc->readIntReg(ArgumentReg0 + i);
+}
+
+void
+PowerLiveProcess::setSyscallArg(ThreadContext *tc,
+        int i, PowerISA::IntReg val)
+{
+    assert(i < 5);
+    tc->setIntReg(ArgumentReg0 + i, val);
+}
+
+void
+PowerLiveProcess::setSyscallReturn(ThreadContext *tc,
+        SyscallReturn return_value)
+{
+    tc->setIntReg(ReturnValueReg, return_value.value());
+}
diff --git a/src/arch/power/process.hh b/src/arch/power/process.hh
new file mode 100644 (file)
index 0000000..dae776c
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * 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
+ */
+
+#ifndef __POWER_PROCESS_HH__
+#define __POWER_PROCESS_HH__
+
+#include <string>
+#include <vector>
+#include "sim/process.hh"
+
+class LiveProcess;
+class ObjectFile;
+class System;
+
+class PowerLiveProcess : public LiveProcess
+{
+  protected:
+    PowerLiveProcess(LiveProcessParams * params, ObjectFile *objFile);
+
+    void startup();
+
+  public:
+    void argsInit(int intSize, int pageSize);
+    PowerISA::IntReg getSyscallArg(ThreadContext *tc, int i);
+    void setSyscallArg(ThreadContext *tc, int i, PowerISA::IntReg val);
+    void setSyscallReturn(ThreadContext *tc, SyscallReturn return_value);
+};
+
+#endif // __POWER_PROCESS_HH__
+
diff --git a/src/arch/power/registers.hh b/src/arch/power/registers.hh
new file mode 100644 (file)
index 0000000..5bcca36
--- /dev/null
@@ -0,0 +1,105 @@
+/*
+ * 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
+ */
+
+#ifndef __ARCH_POWER_REGISTERS_HH__
+#define __ARCH_POWER_REGISTERS_HH__
+
+#include "arch/power/max_inst_regs.hh"
+#include "arch/power/miscregs.hh"
+
+namespace PowerISA {
+
+using PowerISAInst::MaxInstSrcRegs;
+using PowerISAInst::MaxInstDestRegs;
+
+typedef uint8_t RegIndex;
+
+typedef uint64_t IntReg;
+
+// Floating point register file entry type
+typedef uint64_t FloatRegBits;
+typedef double FloatReg;
+typedef uint64_t MiscReg;
+
+// Constants Related to the number of registers
+const int NumIntArchRegs = 32;
+
+// CR, XER, LR, CTR, FPSCR, RSV, RSV-LEN, RSV-ADDR
+// and zero register, which doesn't actually exist but needs a number
+const int NumIntSpecialRegs = 9;
+const int NumFloatArchRegs = 32;
+const int NumFloatSpecialRegs = 0;
+const int NumInternalProcRegs = 0;
+
+const int NumIntRegs = NumIntArchRegs + NumIntSpecialRegs;
+const int NumFloatRegs = NumFloatArchRegs + NumFloatSpecialRegs;
+const int NumMiscRegs = NUM_MISCREGS;
+
+// Semantically meaningful register indices
+const int ReturnValueReg = 3;
+const int ArgumentReg0 = 3;
+const int ArgumentReg1 = 4;
+const int ArgumentReg2 = 5;
+const int ArgumentReg3 = 6;
+const int ArgumentReg4 = 7;
+const int FramePointerReg = 31;
+const int StackPointerReg = 1;
+
+// There isn't one in Power, but we need to define one somewhere
+const int ZeroReg = NumIntRegs - 1;
+
+const int SyscallNumReg = 0;
+const int SyscallPseudoReturnReg = 3;
+const int SyscallSuccessReg = 3;
+
+// These help enumerate all the registers for dependence tracking.
+const int FP_Base_DepTag = NumIntRegs;
+const int Ctrl_Base_DepTag = FP_Base_DepTag + NumFloatRegs;
+
+typedef union {
+    IntReg   intreg;
+    FloatReg fpreg;
+    MiscReg  ctrlreg;
+} AnyReg;
+
+enum MiscIntRegNums {
+    INTREG_CR = NumIntArchRegs,
+    INTREG_XER,
+    INTREG_LR,
+    INTREG_CTR,
+    INTREG_FPSCR,
+    INTREG_RSV,
+    INTREG_RSV_LEN,
+    INTREG_RSV_ADDR
+};
+
+} // PowerISA namespace
+
+#endif // __ARCH_POWER_REGISTERS_HH__
diff --git a/src/arch/power/remote_gdb.hh b/src/arch/power/remote_gdb.hh
new file mode 100644 (file)
index 0000000..34bb4bd
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2002-2005 The Regents of The University of Michigan
+ * 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: Nathan Binkert
+ *          Stephen Hines
+ *          Timothy M. Jones
+ */
+
+#ifndef __ARCH_ARM_REMOTE_GDB_HH__
+#define __ARCH_ARM_REMOTE_GDB_HH__
+
+#include "base/remote_gdb.hh"
+
+namespace PowerISA
+{
+
+class RemoteGDB : public BaseRemoteGDB
+{
+  public:
+    RemoteGDB(System *system, ThreadContext *context)
+        : BaseRemoteGDB(system, context, 1)
+    {
+    }
+
+    bool
+    acc(Addr, size_t)
+    {
+        panic("acc not implemented for POWER!");
+    }
+
+    void
+    getregs()
+    {
+        panic("getregs not implemented for POWER!");
+    }
+
+    void
+    setregs()
+    {
+        panic("setregs not implemented for POWER!");
+    }
+
+    void
+    clearSingleStep()
+    {
+        panic("clearSingleStep not implemented for POWER!");
+    }
+
+    void
+    setSingleStep()
+    {
+        panic("setSingleStep not implemented for POWER!");
+    }
+};
+
+} // PowerISA namespace
+
+#endif /* __ARCH_POWER_REMOTE_GDB_H__ */
diff --git a/src/arch/power/stacktrace.hh b/src/arch/power/stacktrace.hh
new file mode 100644 (file)
index 0000000..49d687a
--- /dev/null
@@ -0,0 +1,148 @@
+/*
+ * Copyright (c) 2005 The Regents of The University of Michigan
+ * 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: Ali Saidi
+ *          Stephen Hines
+ *          Timothy M. Jones
+ */
+
+#ifndef __ARCH_POWER_STACKTRACE_HH__
+#define __ARCH_POWER_STACKTRACE_HH__
+
+#include "base/trace.hh"
+#include "cpu/static_inst.hh"
+
+class ThreadContext;
+class StackTrace;
+
+namespace PowerISA
+{
+
+class ProcessInfo
+{
+  private:
+    ThreadContext *tc;
+
+    int thread_info_size;
+    int task_struct_size;
+    int task_off;
+    int pid_off;
+    int name_off;
+
+  public:
+    ProcessInfo(ThreadContext *_tc);
+
+    Addr task(Addr ksp) const;
+    int pid(Addr ksp) const;
+    std::string name(Addr ksp) const;
+};
+
+class StackTrace
+{
+  protected:
+    typedef TheISA::MachInst MachInst;
+  private:
+    ThreadContext *tc;
+    std::vector<Addr> stack;
+
+  private:
+    bool isEntry(Addr addr);
+    bool decodePrologue(Addr sp, Addr callpc, Addr func, int &size, Addr &ra);
+    bool decodeSave(MachInst inst, int &reg, int &disp);
+    bool decodeStack(MachInst inst, int &disp);
+
+    void trace(ThreadContext *tc, bool is_call);
+
+  public:
+    StackTrace();
+    StackTrace(ThreadContext *tc, StaticInstPtr inst);
+    ~StackTrace();
+
+    void
+    clear()
+    {
+        tc = 0;
+        stack.clear();
+    }
+
+    bool
+    valid() const
+    {
+        return tc != NULL;
+    }
+
+    bool trace(ThreadContext *tc, StaticInstPtr inst);
+
+  public:
+    const std::vector<Addr> &
+    getstack() const
+    {
+        return stack;
+    }
+
+    static const int user = 1;
+    static const int console = 2;
+    static const int unknown = 3;
+
+#if TRACING_ON
+  private:
+    void dump();
+
+  public:
+    void
+    dprintf()
+    {
+        if (DTRACE(Stack))
+            dump();
+    }
+#else
+  public:
+    void
+    dprintf()
+    {
+    }
+#endif
+};
+
+inline bool
+StackTrace::trace(ThreadContext *tc, StaticInstPtr inst)
+{
+    if (!inst->isCall() && !inst->isReturn())
+        return false;
+
+    if (valid())
+        clear();
+
+    trace(tc, !inst->isReturn());
+    return true;
+}
+
+} // PowerISA namespace
+
+#endif // __ARCH_POWER_STACKTRACE_HH__
diff --git a/src/arch/power/tlb.cc b/src/arch/power/tlb.cc
new file mode 100644 (file)
index 0000000..125c92a
--- /dev/null
@@ -0,0 +1,322 @@
+/*
+ * Copyright (c) 2001-2005 The Regents of The University of Michigan
+ * Copyright (c) 2007 MIPS Technologies, Inc.
+ * 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: Nathan Binkert
+ *          Steve Reinhardt
+ *          Jaidev Patwardhan
+ *          Stephen Hines
+ *          Timothy M. Jones
+ */
+
+#include <string>
+#include <vector>
+
+#include "arch/power/faults.hh"
+#include "arch/power/pagetable.hh"
+#include "arch/power/tlb.hh"
+#include "arch/power/utility.hh"
+#include "base/inifile.hh"
+#include "base/str.hh"
+#include "base/trace.hh"
+#include "cpu/thread_context.hh"
+#include "mem/page_table.hh"
+#include "params/PowerTLB.hh"
+#include "sim/process.hh"
+
+
+using namespace std;
+using namespace PowerISA;
+
+///////////////////////////////////////////////////////////////////////
+//
+//  POWER TLB
+//
+
+#define MODE2MASK(X) (1 << (X))
+
+TLB::TLB(const Params *p)
+    : BaseTLB(p), size(p->size), nlu(0)
+{
+    table = new PowerISA::PTE[size];
+    memset(table, 0, sizeof(PowerISA::PTE[size]));
+    smallPages = 0;
+}
+
+TLB::~TLB()
+{
+    if (table)
+        delete [] table;
+}
+
+// look up an entry in the TLB
+PowerISA::PTE *
+TLB::lookup(Addr vpn, uint8_t asn) const
+{
+    // assume not found...
+    PowerISA::PTE *retval = NULL;
+    PageTable::const_iterator i = lookupTable.find(vpn);
+    if (i != lookupTable.end()) {
+        while (i->first == vpn) {
+            int index = i->second;
+            PowerISA::PTE *pte = &table[index];
+            Addr Mask = pte->Mask;
+            Addr InvMask = ~Mask;
+            Addr VPN  = pte->VPN;
+            if (((vpn & InvMask) == (VPN & InvMask))
+               && (pte->G  || (asn == pte->asid))) {
+
+                // We have a VPN + ASID Match
+                retval = pte;
+                break;
+            }
+            ++i;
+        }
+    }
+
+    DPRINTF(TLB, "lookup %#x, asn %#x -> %s ppn %#x\n", vpn, (int)asn,
+            retval ? "hit" : "miss", retval ? retval->PFN1 : 0);
+    return retval;
+}
+
+PowerISA::PTE*
+TLB::getEntry(unsigned Index) const
+{
+    // Make sure that Index is valid
+    assert(Index<size);
+    return &table[Index];
+}
+
+int
+TLB::probeEntry(Addr vpn,uint8_t asn) const
+{
+    // assume not found...
+    PowerISA::PTE *retval = NULL;
+    int Ind = -1;
+    PageTable::const_iterator i = lookupTable.find(vpn);
+    if (i != lookupTable.end()) {
+        while (i->first == vpn) {
+            int index = i->second;
+            PowerISA::PTE *pte = &table[index];
+            Addr Mask = pte->Mask;
+            Addr InvMask = ~Mask;
+            Addr VPN  = pte->VPN;
+            if (((vpn & InvMask) == (VPN & InvMask))
+                && (pte->G  || (asn == pte->asid))) {
+
+                // We have a VPN + ASID Match
+                retval = pte;
+                Ind = index;
+                break;
+            }
+            ++i;
+        }
+    }
+
+    DPRINTF(Power, "VPN: %x, asid: %d, Result of TLBP: %d\n", vpn, asn, Ind);
+    return Ind;
+}
+
+inline Fault
+TLB::checkCacheability(RequestPtr &req)
+{
+    Addr VAddrUncacheable = 0xA0000000;
+    if ((req->getVaddr() & VAddrUncacheable) == VAddrUncacheable) {
+
+        // mark request as uncacheable
+        req->setFlags(Request::UNCACHEABLE);
+    }
+    return NoFault;
+}
+
+void
+TLB::insertAt(PowerISA::PTE &pte, unsigned Index, int _smallPages)
+{
+    smallPages=_smallPages;
+    if (Index > size){
+        warn("Attempted to write at index (%d) beyond TLB size (%d)",
+             Index, size);
+    } else {
+
+        // Update TLB
+        if (table[Index].V0 == true || table[Index].V1 == true) {
+
+            // Previous entry is valid
+            PageTable::iterator i = lookupTable.find(table[Index].VPN);
+            lookupTable.erase(i);
+        }
+        table[Index]=pte;
+
+        // Update fast lookup table
+        lookupTable.insert(make_pair(table[Index].VPN, Index));
+    }
+}
+
+// insert a new TLB entry
+void
+TLB::insert(Addr addr, PowerISA::PTE &pte)
+{
+    fatal("TLB Insert not yet implemented\n");
+}
+
+void
+TLB::flushAll()
+{
+    DPRINTF(TLB, "flushAll\n");
+    memset(table, 0, sizeof(PowerISA::PTE[size]));
+    lookupTable.clear();
+    nlu = 0;
+}
+
+void
+TLB::serialize(ostream &os)
+{
+    SERIALIZE_SCALAR(size);
+    SERIALIZE_SCALAR(nlu);
+
+    for (int i = 0; i < size; i++) {
+        nameOut(os, csprintf("%s.PTE%d", name(), i));
+        table[i].serialize(os);
+    }
+}
+
+void
+TLB::unserialize(Checkpoint *cp, const string &section)
+{
+    UNSERIALIZE_SCALAR(size);
+    UNSERIALIZE_SCALAR(nlu);
+
+    for (int i = 0; i < size; i++) {
+        table[i].unserialize(cp, csprintf("%s.PTE%d", section, i));
+        if (table[i].V0 || table[i].V1) {
+            lookupTable.insert(make_pair(table[i].VPN, i));
+        }
+    }
+}
+
+void
+TLB::regStats()
+{
+    read_hits
+        .name(name() + ".read_hits")
+        .desc("DTB read hits")
+        ;
+
+    read_misses
+        .name(name() + ".read_misses")
+        .desc("DTB read misses")
+        ;
+
+
+    read_accesses
+        .name(name() + ".read_accesses")
+        .desc("DTB read accesses")
+        ;
+
+    write_hits
+        .name(name() + ".write_hits")
+        .desc("DTB write hits")
+        ;
+
+    write_misses
+        .name(name() + ".write_misses")
+        .desc("DTB write misses")
+        ;
+
+
+    write_accesses
+        .name(name() + ".write_accesses")
+        .desc("DTB write accesses")
+        ;
+
+    hits
+        .name(name() + ".hits")
+        .desc("DTB hits")
+        ;
+
+    misses
+        .name(name() + ".misses")
+        .desc("DTB misses")
+        ;
+
+    invalids
+        .name(name() + ".invalids")
+        .desc("DTB access violations")
+        ;
+
+    accesses
+        .name(name() + ".accesses")
+        .desc("DTB accesses")
+        ;
+
+    hits = read_hits + write_hits;
+    misses = read_misses + write_misses;
+    accesses = read_accesses + write_accesses;
+}
+
+Fault
+TLB::translateAtomic(RequestPtr req, ThreadContext *tc, Mode mode)
+{
+#if !FULL_SYSTEM
+    Process * p = tc->getProcessPtr();
+
+    Fault fault = p->pTable->translate(req);
+    if (fault != NoFault)
+        return fault;
+
+    return NoFault;
+#else
+  fatal("translate atomic not yet implemented\n");
+#endif
+}
+
+void
+TLB::translateTiming(RequestPtr req, ThreadContext *tc,
+                     Translation *translation, Mode mode)
+{
+    assert(translation);
+    translation->finish(translateAtomic(req, tc, mode), req, tc, mode);
+}
+
+PowerISA::PTE &
+TLB::index(bool advance)
+{
+    PowerISA::PTE *pte = &table[nlu];
+
+    if (advance)
+        nextnlu();
+
+    return *pte;
+}
+
+PowerISA::TLB *
+PowerTLBParams::create()
+{
+    return new PowerISA::TLB(this);
+}
diff --git a/src/arch/power/tlb.hh b/src/arch/power/tlb.hh
new file mode 100644 (file)
index 0000000..8b6c723
--- /dev/null
@@ -0,0 +1,171 @@
+/*
+ * Copyright (c) 2001-2005 The Regents of The University of Michigan
+ * Copyright (c) 2007 MIPS Technologies, Inc.
+ * 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: Nathan Binkert
+ *          Steve Reinhardt
+ *          Stephen Hines
+ *          Timothy M. Jones
+ */
+
+#ifndef __ARCH_POWER_TLB_HH__
+#define __ARCH_POWER_TLB_HH__
+
+#include <map>
+
+#include "arch/power/isa_traits.hh"
+#include "arch/power/utility.hh"
+#include "arch/power/vtophys.hh"
+#include "arch/power/pagetable.hh"
+#include "base/statistics.hh"
+#include "mem/request.hh"
+#include "params/PowerTLB.hh"
+#include "sim/faults.hh"
+#include "sim/tlb.hh"
+
+class ThreadContext;
+
+namespace PowerISA {
+
+// This is copied from the ARM ISA and has not been checked against the
+// Power at all.
+struct TlbEntry
+{
+    Addr _pageStart;
+
+    TlbEntry()
+    {
+    }
+
+    TlbEntry(Addr asn, Addr vaddr, Addr paddr)
+        : _pageStart(paddr)
+    {
+    }
+
+    void
+    updateVaddr(Addr new_vaddr)
+    {
+        panic("unimplemented");
+    }
+
+    Addr
+    pageStart()
+    {
+        return _pageStart;
+    }
+
+    void
+    serialize(std::ostream &os)
+    {
+        SERIALIZE_SCALAR(_pageStart);
+    }
+
+    void
+    unserialize(Checkpoint *cp, const std::string &section)
+    {
+        UNSERIALIZE_SCALAR(_pageStart);
+    }
+};
+
+class TLB : public BaseTLB
+{
+  protected:
+    typedef std::multimap<Addr, int> PageTable;
+    PageTable lookupTable;      // Quick lookup into page table
+
+    PowerISA::PTE *table;       // the Page Table
+    int size;                   // TLB Size
+    int nlu;                    // not last used entry (for replacement)
+
+    void
+    nextnlu()
+    {
+        if (++nlu >= size) {
+            nlu = 0;
+        }
+    }
+
+    PowerISA::PTE *lookup(Addr vpn, uint8_t asn) const;
+
+    mutable Stats::Scalar read_hits;
+    mutable Stats::Scalar read_misses;
+    mutable Stats::Scalar read_acv;
+    mutable Stats::Scalar read_accesses;
+    mutable Stats::Scalar write_hits;
+    mutable Stats::Scalar write_misses;
+    mutable Stats::Scalar write_acv;
+    mutable Stats::Scalar write_accesses;
+    Stats::Formula hits;
+    Stats::Formula misses;
+    Stats::Formula invalids;
+    Stats::Formula accesses;
+
+  public:
+    typedef PowerTLBParams Params;
+    TLB(const Params *p);
+    virtual ~TLB();
+
+    int probeEntry(Addr vpn,uint8_t) const;
+    PowerISA::PTE *getEntry(unsigned) const;
+
+    int smallPages;
+
+    int
+    getsize() const
+    {
+        return size;
+    }
+
+    PowerISA::PTE &index(bool advance = true);
+    void insert(Addr vaddr, PowerISA::PTE &pte);
+    void insertAt(PowerISA::PTE &pte, unsigned Index, int _smallPages);
+    void flushAll();
+
+    void
+    demapPage(Addr vaddr, uint64_t asn)
+    {
+        panic("demapPage unimplemented.\n");
+    }
+
+    // static helper functions... really
+    static bool validVirtualAddress(Addr vaddr);
+    static Fault checkCacheability(RequestPtr &req);
+    Fault translateAtomic(RequestPtr req, ThreadContext *tc, Mode mode);
+    void translateTiming(RequestPtr req, ThreadContext *tc,
+                         Translation *translation, Mode mode);
+
+    // Checkpointing
+    void serialize(std::ostream &os);
+    void unserialize(Checkpoint *cp, const std::string &section);
+    void regStats();
+};
+
+} // PowerISA namespace
+
+#endif // __ARCH_POWER_TLB_HH__
diff --git a/src/arch/power/types.hh b/src/arch/power/types.hh
new file mode 100644 (file)
index 0000000..7b994ad
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+ * 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
+ */
+
+#ifndef __ARCH_POWER_TYPES_HH__
+#define __ARCH_POWER_TYPES_HH__
+
+#include "base/bitunion.hh"
+#include "base/types.hh"
+
+namespace PowerISA
+{
+
+typedef uint32_t MachInst;
+
+BitUnion32(ExtMachInst)
+
+    // Registers
+    Bitfield<25, 21> rs;
+    Bitfield<20, 16> ra;
+
+    // Shifts and masks
+    Bitfield<15, 11> sh;
+    Bitfield<10,  6> mb;
+    Bitfield< 5,  1> me;
+
+    // Immediate fields
+    Bitfield<15,  0> si;
+    Bitfield<15,  0> d;
+
+    // Special purpose register identifier
+    Bitfield<20, 11> spr;
+    Bitfield<25,  2> li;
+    Bitfield<1>      aa;
+    Bitfield<25, 23> bf;
+    Bitfield<15,  2> bd;
+    Bitfield<25, 21> bo;
+    Bitfield<20, 16> bi;
+    Bitfield<20, 18> bfa;
+
+    // Record bits
+    Bitfield<0>      rc31;
+    Bitfield<10>     oe;
+
+    // Condition register fields
+    Bitfield<25, 21> bt;
+    Bitfield<20, 16> ba;
+    Bitfield<15, 11> bb;
+
+    // FXM field for mtcrf instruction
+    Bitfield<19, 12> fxm;
+EndBitUnion(ExtMachInst)
+
+// typedef uint64_t LargestRead;
+// // Need to use 64 bits to make sure that read requests get handled properly
+
+// typedef int RegContextParam;
+// typedef int RegContextVal;
+
+struct CoreSpecific {
+};
+
+} // PowerISA namspace
+
+#endif // __ARCH_POWER_TYPES_HH__
diff --git a/src/arch/power/utility.hh b/src/arch/power/utility.hh
new file mode 100644 (file)
index 0000000..442075a
--- /dev/null
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2003-2005 The Regents of The University of Michigan
+ * 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: Korey Sewell
+ *          Stephen Hines
+ *          Timothy M. Jones
+ */
+
+#ifndef __ARCH_POWER_UTILITY_HH__
+#define __ARCH_POWER_UTILITY_HH__
+
+#include "arch/power/miscregs.hh"
+#include "arch/power/types.hh"
+#include "base/hashmap.hh"
+#include "base/types.hh"
+#include "cpu/thread_context.hh"
+
+namespace __hash_namespace {
+
+template<>
+struct hash<PowerISA::ExtMachInst> : public hash<uint32_t> {
+    size_t operator()(const PowerISA::ExtMachInst &emi) const {
+        return hash<uint32_t>::operator()((uint32_t)emi);
+    };
+};
+
+} // __hash_namespace namespace
+
+namespace PowerISA {
+
+/**
+ * Function to ensure ISA semantics about 0 registers.
+ * @param tc The thread context.
+ */
+template <class TC>
+void zeroRegisters(TC *tc);
+
+// Instruction address compression hooks
+static inline Addr
+realPCToFetchPC(const Addr &addr)
+{
+    return addr;
+}
+
+static inline Addr
+fetchPCToRealPC(const Addr &addr)
+{
+    return addr;
+}
+
+// the size of "fetched" instructions
+static inline size_t
+fetchInstSize()
+{
+    return sizeof(MachInst);
+}
+
+static inline MachInst
+makeRegisterCopy(int dest, int src)
+{
+    panic("makeRegisterCopy not implemented");
+    return 0;
+}
+
+inline void
+startupCPU(ThreadContext *tc, int cpuId)
+{
+    tc->activate(0);
+}
+
+template <class XC>
+Fault
+checkFpEnableFault(XC *xc)
+{
+    return NoFault;
+}
+
+static inline void
+copyRegs(ThreadContext *src, ThreadContext *dest)
+{
+    panic("Copy Regs Not Implemented Yet\n");
+}
+
+static inline void
+copyMiscRegs(ThreadContext *src, ThreadContext *dest)
+{
+    panic("Copy Misc. Regs Not Implemented Yet\n");
+}
+
+} // PowerISA namespace
+
+#endif // __ARCH_POWER_UTILITY_HH__
diff --git a/src/arch/power/vtophys.hh b/src/arch/power/vtophys.hh
new file mode 100644 (file)
index 0000000..3cfebcf
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2002-2005 The Regents of The University of Michigan
+ * 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: Ali Saidi
+ *          Nathan Binkert
+ *          Stephen Hines
+ *          Timothy M. Jones
+ */
+
+#ifndef __ARCH_POWER_VTOPHYS_HH__
+#define __ARCH_POWER_VTOPHYS_HH__
+
+#include "arch/power/isa_traits.hh"
+#include "arch/power/utility.hh"
+
+
+class ThreadContext;
+class FunctionalPort;
+
+namespace PowerISA {
+
+inline Addr
+PteAddr(Addr a)
+{
+    return (a & PteMask) << PteShift;
+}
+
+} // PowerISA namespace
+
+#endif // __ARCH_POWER_VTOPHYS_HH__
+
index 15ad88f762a04716ae899d6774161302c8071c45..60f0f99b49b3e8ba8d68f573afafe2a76388ef41 100644 (file)
@@ -97,6 +97,19 @@ ElfObject::tryFile(const string &fname, int fd, size_t len, uint8_t *data)
             arch = ObjectFile::Alpha;
         } else if (ehdr.e_machine == EM_ARM) {
             arch = ObjectFile::Arm;
+        } else if (ehdr.e_machine == EM_PPC &&
+                ehdr.e_ident[EI_CLASS] == ELFCLASS32) {
+          if (ehdr.e_ident[EI_DATA] == ELFDATA2MSB) {
+                arch = ObjectFile::Power;
+          } else {
+                fatal("The binary you're trying to load is compiled for "
+                        "little endian Power.\nM5 only supports big "
+                        "endian Power. Please recompile your binary.\n");
+          }
+        } else if (ehdr.e_machine == EM_PPC64) {
+            fatal("The binary you're trying to load is compiled for 64-bit "
+                  "Power. M5\n only supports 32-bit Power. Please "
+                  "recompile your binary.\n");
         } else {
             warn("Unknown architecture: %d\n", ehdr.e_machine);
             arch = ObjectFile::UnknownArch;
index e511451b79cc0d1937679f0463e835c1a98f4cb3..b08f1c633b810ab35988d38f7a2fb0be43d0089d 100644 (file)
@@ -52,7 +52,8 @@ class ObjectFile
         Mips,
         X86_64,
         I386,
-        Arm
+        Arm,
+        Power
     };
 
     enum OpSys {
index 75114053e7a8f3de2c02beea66591414b66dfaf5..ac734e5ac409c0282d5386c6ef8546884f210125 100644 (file)
@@ -59,6 +59,10 @@ elif buildEnv['TARGET_ISA'] == 'arm':
     from ArmTLB import ArmTLB
     if buildEnv['FULL_SYSTEM']:
         from ArmInterrupts import ArmInterrupts
+elif buildEnv['TARGET_ISA'] == 'power':
+    from PowerTLB import PowerTLB
+    if buildEnv['FULL_SYSTEM']:
+        from PowerInterrupts import PowerInterrupts
 
 class BaseCPU(MemObject):
     type = 'BaseCPU'
@@ -116,6 +120,13 @@ class BaseCPU(MemObject):
         if buildEnv['FULL_SYSTEM']:
             interrupts = Param.ArmInterrupts(
                     ArmInterrupts(), "Interrupt Controller")
+    elif buildEnv['TARGET_ISA'] == 'power':
+        UnifiedTLB = Param.Bool(True, "Is this a Unified TLB?")
+        dtb = Param.PowerTLB(PowerTLB(), "Data TLB")
+        itb = Param.PowerTLB(PowerTLB(), "Instruction TLB")
+        if buildEnv['FULL_SYSTEM']:
+            interrupts = Param.PowerInterrupts(
+                    PowerInterrupts(), "Interrupt Controller")
     else:
         print "Don't know what TLB to use for ISA %s" % \
             buildEnv['TARGET_ISA']
index ec6ac04492f2bfcef9296f7cc1051a2ed9297fdf..cf0f2b84d2b2eef35cffc0dfaec3defde12ae59e 100644 (file)
@@ -66,6 +66,8 @@
 #include "arch/arm/linux/process.hh"
 #elif THE_ISA == X86_ISA
 #include "arch/x86/linux/process.hh"
+#elif THE_ISA == POWER_ISA
+#include "arch/power/linux/process.hh"
 #else
 #error "THE_ISA not set"
 #endif
@@ -626,7 +628,7 @@ LiveProcess::argsInit(int intSize, int pageSize)
     tc->setPC(prog_entry);
     tc->setNextPC(prog_entry + sizeof(MachInst));
 
-#if THE_ISA != ALPHA_ISA //e.g. MIPS or Sparc
+#if THE_ISA != ALPHA_ISA && THE_ISA != POWER_ISA //e.g. MIPS or Sparc
     tc->setNextNPC(prog_entry + (2 * sizeof(MachInst)));
 #endif
 
@@ -754,6 +756,20 @@ LiveProcess::create(LiveProcessParams * params)
       default:
         fatal("Unknown/unsupported operating system.");
     }
+#elif THE_ISA == POWER_ISA
+    if (objFile->getArch() != ObjectFile::Power)
+        fatal("Object file architecture does not match compiled ISA (Power).");
+    switch (objFile->getOpSys()) {
+      case ObjectFile::UnknownOpSys:
+        warn("Unknown operating system; assuming Linux.");
+        // fall through
+      case ObjectFile::Linux:
+        process = new PowerLinuxProcess(params, objFile);
+        break;
+
+      default:
+        fatal("Unknown/unsupported operating system.");
+    }
 #else
 #error "THE_ISA not set"
 #endif