Merge ARM into the head. ARM will compile but may not actually work.
authorGabe Black <gblack@eecs.umich.edu>
Mon, 6 Apr 2009 17:19:36 +0000 (10:19 -0700)
committerGabe Black <gblack@eecs.umich.edu>
Mon, 6 Apr 2009 17:19:36 +0000 (10:19 -0700)
50 files changed:
src/arch/arm/ArmTLB.py [new file with mode: 0644]
src/arch/arm/SConscript [new file with mode: 0644]
src/arch/arm/SConsopts [new file with mode: 0644]
src/arch/arm/faults.cc [new file with mode: 0644]
src/arch/arm/faults.hh [new file with mode: 0644]
src/arch/arm/isa/base.isa [new file with mode: 0644]
src/arch/arm/isa/bitfields.isa [new file with mode: 0644]
src/arch/arm/isa/copyright.txt [new file with mode: 0644]
src/arch/arm/isa/decoder.isa [new file with mode: 0644]
src/arch/arm/isa/formats/basic.isa [new file with mode: 0644]
src/arch/arm/isa/formats/branch.isa [new file with mode: 0644]
src/arch/arm/isa/formats/formats.isa [new file with mode: 0644]
src/arch/arm/isa/formats/fp.isa [new file with mode: 0644]
src/arch/arm/isa/formats/macromem.isa [new file with mode: 0644]
src/arch/arm/isa/formats/mem.isa [new file with mode: 0644]
src/arch/arm/isa/formats/pred.isa [new file with mode: 0644]
src/arch/arm/isa/formats/unimp.isa [new file with mode: 0644]
src/arch/arm/isa/formats/unknown.isa [new file with mode: 0644]
src/arch/arm/isa/formats/util.isa [new file with mode: 0644]
src/arch/arm/isa/includes.isa [new file with mode: 0644]
src/arch/arm/isa/main.isa [new file with mode: 0644]
src/arch/arm/isa/operands.isa [new file with mode: 0644]
src/arch/arm/isa/util.isa [new file with mode: 0644]
src/arch/arm/isa_traits.hh [new file with mode: 0644]
src/arch/arm/linux/linux.cc [new file with mode: 0644]
src/arch/arm/linux/linux.hh [new file with mode: 0644]
src/arch/arm/linux/process.cc [new file with mode: 0644]
src/arch/arm/linux/process.hh [new file with mode: 0644]
src/arch/arm/locked_mem.hh [new file with mode: 0644]
src/arch/arm/mmaped_ipr.hh [new file with mode: 0644]
src/arch/arm/pagetable.cc [new file with mode: 0644]
src/arch/arm/pagetable.hh [new file with mode: 0644]
src/arch/arm/predecoder.hh [new file with mode: 0644]
src/arch/arm/process.cc [new file with mode: 0644]
src/arch/arm/process.hh [new file with mode: 0644]
src/arch/arm/regfile.hh [new file with mode: 0644]
src/arch/arm/regfile/float_regfile.hh [new file with mode: 0644]
src/arch/arm/regfile/int_regfile.hh [new file with mode: 0644]
src/arch/arm/regfile/misc_regfile.hh [new file with mode: 0644]
src/arch/arm/regfile/regfile.cc [new file with mode: 0644]
src/arch/arm/regfile/regfile.hh [new file with mode: 0644]
src/arch/arm/remote_gdb.hh [new file with mode: 0644]
src/arch/arm/stacktrace.hh [new file with mode: 0644]
src/arch/arm/tlb.cc [new file with mode: 0644]
src/arch/arm/tlb.hh [new file with mode: 0644]
src/arch/arm/types.hh [new file with mode: 0644]
src/arch/arm/utility.cc [new file with mode: 0644]
src/arch/arm/utility.hh [new file with mode: 0644]
src/arch/arm/vtophys.cc [new file with mode: 0644]
src/arch/arm/vtophys.hh [new file with mode: 0644]

diff --git a/src/arch/arm/ArmTLB.py b/src/arch/arm/ArmTLB.py
new file mode 100644 (file)
index 0000000..fa9faad
--- /dev/null
@@ -0,0 +1,54 @@
+# -*- mode:python -*-
+
+# Copyright (c) 2007-2008 The Florida State University
+# 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
+
+from m5.SimObject import SimObject
+from m5.params import *
+
+class ArmTLB(SimObject):
+    abstract = True
+    type = 'ArmTLB'
+    cxx_class = 'ArmISA::TLB'
+    size = Param.Int("TLB size")
+
+class ArmDTB(ArmTLB):
+    type = 'ArmDTB'
+    cxx_class = 'ArmISA::DTB'
+    size = 64
+
+class ArmITB(ArmTLB):
+    type = 'ArmITB'
+    cxx_class = 'ArmISA::ITB'
+    size = 64
+
+class ArmUTB(ArmTLB):
+    type = 'ArmUTB'
+    cxx_class = 'ArmISA::UTB'
+    size = 64
+
diff --git a/src/arch/arm/SConscript b/src/arch/arm/SConscript
new file mode 100644 (file)
index 0000000..d563732
--- /dev/null
@@ -0,0 +1,61 @@
+# -*- mode:python -*-
+
+# Copyright (c) 2007-2008 The Florida State University
+# 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
+
+Import('*')
+
+if env['TARGET_ISA'] == 'arm':
+# Workaround for bug in SCons version > 0.97d20071212
+# Scons bug id: 2006 M5 Bug id: 308 
+    Dir('isa/formats')
+    Source('faults.cc')
+    Source('pagetable.cc')
+    Source('regfile/regfile.cc')
+    Source('tlb.cc')
+    Source('utility.cc')
+    Source('vtophys.cc')
+
+    SimObject('ArmTLB.py')
+    TraceFlag('Arm')
+
+    if env['FULL_SYSTEM']:
+        #Insert Full-System Files Here
+        pass
+    else:
+        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/arm/SConsopts b/src/arch/arm/SConsopts
new file mode 100644 (file)
index 0000000..fd95169
--- /dev/null
@@ -0,0 +1,33 @@
+# -*- mode:python -*-
+
+# Copyright (c) 2007-2008 The Florida State University
+# 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
+
+Import('*')
+
+all_isa_list.append('arm')
diff --git a/src/arch/arm/faults.cc b/src/arch/arm/faults.cc
new file mode 100644 (file)
index 0000000..b79c091
--- /dev/null
@@ -0,0 +1,515 @@
+/*
+ * Copyright (c) 2003-2005 The Regents of The University of Michigan
+ * Copyright (c) 2007-2008 The Florida State University
+ * 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
+ */
+
+#include "arch/arm/faults.hh"
+#include "cpu/thread_context.hh"
+#include "cpu/base.hh"
+#include "base/trace.hh"
+#if !FULL_SYSTEM
+#include "sim/process.hh"
+#include "mem/page_table.hh"
+#endif
+
+namespace ArmISA
+{
+
+FaultName MachineCheckFault::_name = "Machine Check";
+FaultVect MachineCheckFault::_vect = 0x0401;
+FaultStat MachineCheckFault::_count;
+
+FaultName AlignmentFault::_name = "Alignment";
+FaultVect AlignmentFault::_vect = 0x0301;
+FaultStat AlignmentFault::_count;
+
+FaultName ResetFault::_name = "Reset Fault";
+#if  FULL_SYSTEM
+FaultVect ResetFault::_vect = 0xBFC00000;
+#else
+FaultVect ResetFault::_vect = 0x001;
+#endif
+FaultStat ResetFault::_count;
+
+FaultName AddressErrorFault::_name = "Address Error";
+FaultVect AddressErrorFault::_vect = 0x0180;
+FaultStat AddressErrorFault::_count;
+
+FaultName StoreAddressErrorFault::_name = "Store Address Error";
+FaultVect StoreAddressErrorFault::_vect = 0x0180;
+FaultStat StoreAddressErrorFault::_count;
+
+
+FaultName SystemCallFault::_name = "Syscall";
+FaultVect SystemCallFault::_vect = 0x0180;
+FaultStat SystemCallFault::_count;
+
+FaultName CoprocessorUnusableFault::_name = "Coprocessor Unusable Fault";
+FaultVect CoprocessorUnusableFault::_vect = 0x180;
+FaultStat CoprocessorUnusableFault::_count;
+
+FaultName ReservedInstructionFault::_name = "Reserved Instruction Fault";
+FaultVect ReservedInstructionFault::_vect = 0x0180;
+FaultStat ReservedInstructionFault::_count;
+
+FaultName ThreadFault::_name = "Thread Fault";
+FaultVect ThreadFault::_vect = 0x00F1;
+FaultStat ThreadFault::_count;
+
+
+FaultName ArithmeticFault::_name = "Arithmetic Overflow Exception";
+FaultVect ArithmeticFault::_vect = 0x180;
+FaultStat ArithmeticFault::_count;
+
+FaultName UnimplementedOpcodeFault::_name = "opdec";
+FaultVect UnimplementedOpcodeFault::_vect = 0x0481;
+FaultStat UnimplementedOpcodeFault::_count;
+
+FaultName InterruptFault::_name = "interrupt";
+FaultVect InterruptFault::_vect = 0x0180;
+FaultStat InterruptFault::_count;
+
+FaultName TrapFault::_name = "Trap";
+FaultVect TrapFault::_vect = 0x0180;
+FaultStat TrapFault::_count;
+
+FaultName BreakpointFault::_name = "Breakpoint";
+FaultVect BreakpointFault::_vect = 0x0180;
+FaultStat BreakpointFault::_count;
+
+
+FaultName ItbInvalidFault::_name = "Invalid TLB Entry Exception (I-Fetch/LW)";
+FaultVect ItbInvalidFault::_vect = 0x0180;
+FaultStat ItbInvalidFault::_count;
+
+FaultName ItbPageFault::_name = "itbmiss";
+FaultVect ItbPageFault::_vect = 0x0181;
+FaultStat ItbPageFault::_count;
+
+FaultName ItbMissFault::_name = "itbmiss";
+FaultVect ItbMissFault::_vect = 0x0181;
+FaultStat ItbMissFault::_count;
+
+FaultName ItbAcvFault::_name = "iaccvio";
+FaultVect ItbAcvFault::_vect = 0x0081;
+FaultStat ItbAcvFault::_count;
+
+FaultName ItbRefillFault::_name = "TLB Refill Exception (I-Fetch/LW)";
+FaultVect ItbRefillFault::_vect = 0x0180;
+FaultStat ItbRefillFault::_count;
+
+FaultName NDtbMissFault::_name = "dtb_miss_single";
+FaultVect NDtbMissFault::_vect = 0x0201;
+FaultStat NDtbMissFault::_count;
+
+FaultName PDtbMissFault::_name = "dtb_miss_double";
+FaultVect PDtbMissFault::_vect = 0x0281;
+FaultStat PDtbMissFault::_count;
+
+FaultName DtbPageFault::_name = "dfault";
+FaultVect DtbPageFault::_vect = 0x0381;
+FaultStat DtbPageFault::_count;
+
+FaultName DtbAcvFault::_name = "dfault";
+FaultVect DtbAcvFault::_vect = 0x0381;
+FaultStat DtbAcvFault::_count;
+
+FaultName DtbInvalidFault::_name = "Invalid TLB Entry Exception (Store)";
+FaultVect DtbInvalidFault::_vect = 0x0180;
+FaultStat DtbInvalidFault::_count;
+
+FaultName DtbRefillFault::_name = "TLB Refill Exception (Store)";
+FaultVect DtbRefillFault::_vect = 0x0180;
+FaultStat DtbRefillFault::_count;
+
+FaultName TLBModifiedFault::_name = "TLB Modified Exception";
+FaultVect TLBModifiedFault::_vect = 0x0180;
+FaultStat TLBModifiedFault::_count;
+
+FaultName FloatEnableFault::_name = "float_enable_fault";
+FaultVect FloatEnableFault::_vect = 0x0581;
+FaultStat FloatEnableFault::_count;
+
+FaultName IntegerOverflowFault::_name = "Integer Overflow Fault";
+FaultVect IntegerOverflowFault::_vect = 0x0501;
+FaultStat IntegerOverflowFault::_count;
+
+FaultName DspStateDisabledFault::_name = "DSP Disabled Fault";
+FaultVect DspStateDisabledFault::_vect = 0x001a;
+FaultStat DspStateDisabledFault::_count;
+
+#if FULL_SYSTEM
+void ArmFault::setHandlerPC(Addr HandlerBase, ThreadContext *tc)
+{
+  tc->setPC(HandlerBase);
+  tc->setNextPC(HandlerBase+sizeof(MachInst));
+  tc->setNextNPC(HandlerBase+2*sizeof(MachInst));
+}
+
+void ArmFault::setExceptionState(ThreadContext *tc,uint8_t ExcCode)
+{
+  // modify SRS Ctl - Save CSS, put ESS into CSS
+  MiscReg stat = tc->readMiscReg(ArmISA::Status);
+  if(bits(stat,Status_EXL) != 1 && bits(stat,Status_BEV) != 1)
+    {
+      // SRS Ctl is modified only if Status_EXL and Status_BEV are not set
+      MiscReg srs = tc->readMiscReg(ArmISA::SRSCtl);
+      uint8_t CSS,ESS;
+      CSS = bits(srs,SRSCtl_CSS_HI,SRSCtl_CSS_LO);
+      ESS = bits(srs,SRSCtl_ESS_HI,SRSCtl_ESS_LO);
+      // Move CSS to PSS
+      replaceBits(srs,SRSCtl_PSS_HI,SRSCtl_PSS_LO,CSS);
+      // Move ESS to CSS
+      replaceBits(srs,SRSCtl_CSS_HI,SRSCtl_CSS_LO,ESS);
+      tc->setMiscRegNoEffect(ArmISA::SRSCtl,srs);
+      //tc->setShadowSet(ESS);
+    }
+
+  // set EXL bit (don't care if it is already set!)
+  replaceBits(stat,Status_EXL_HI,Status_EXL_LO,1);
+  tc->setMiscRegNoEffect(ArmISA::Status,stat);
+
+  // write EPC
+  //  warn("Set EPC to %x\n",tc->readPC());
+  // CHECK ME  or FIXME or FIX ME or POSSIBLE HACK
+  // Check to see if the exception occurred in the branch delay slot
+  DPRINTF(Arm,"PC: %x, NextPC: %x, NNPC: %x\n",tc->readPC(),tc->readNextPC(),tc->readNextNPC());
+  int C_BD=0;
+  if(tc->readPC() + sizeof(MachInst) != tc->readNextPC()){
+    tc->setMiscRegNoEffect(ArmISA::EPC,tc->readPC()-sizeof(MachInst));
+    // In the branch delay slot? set CAUSE_31
+    C_BD = 1;
+  } else {
+    tc->setMiscRegNoEffect(ArmISA::EPC,tc->readPC());
+    // In the branch delay slot? reset CAUSE_31
+    C_BD = 0;
+  }
+
+  // Set Cause_EXCCODE field
+  MiscReg cause = tc->readMiscReg(ArmISA::Cause);
+  replaceBits(cause,Cause_EXCCODE_HI,Cause_EXCCODE_LO,ExcCode);
+  replaceBits(cause,Cause_BD_HI,Cause_BD_LO,C_BD);
+  replaceBits(cause,Cause_CE_HI,Cause_CE_LO,0);
+  tc->setMiscRegNoEffect(ArmISA::Cause,cause);
+
+}
+
+void ArithmeticFault::invoke(ThreadContext *tc)
+{
+  DPRINTF(Arm,"%s encountered.\n", name());
+  setExceptionState(tc,0xC);
+
+  // Set new PC
+  Addr HandlerBase;
+  MiscReg stat = tc->readMiscReg(ArmISA::Status);
+  // Here, the handler is dependent on BEV, which is not modified by setExceptionState()
+  if(bits(stat,Status_BEV)==0){ // See MIPS ARM Vol 3, Revision 2, Page 38
+    HandlerBase= vect() + tc->readMiscReg(ArmISA::EBase);
+  }else{
+    HandlerBase = 0xBFC00200;
+  }
+  setHandlerPC(HandlerBase,tc);
+  //      warn("Exception Handler At: %x \n",HandlerBase);
+}
+
+void StoreAddressErrorFault::invoke(ThreadContext *tc)
+{
+  DPRINTF(Arm,"%s encountered.\n", name());
+  setExceptionState(tc,0x5);
+  tc->setMiscRegNoEffect(ArmISA::BadVAddr,BadVAddr);
+
+  // Set new PC
+  Addr HandlerBase;
+  HandlerBase= vect() + tc->readMiscReg(ArmISA::EBase); // Offset 0x180 - General Exception Vector
+  setHandlerPC(HandlerBase,tc);
+  //      warn("Exception Handler At: %x \n",HandlerBase);
+  //      warn("Exception Handler At: %x , EPC set to %x\n",HandlerBase,tc->readMiscReg(ArmISA::EPC));
+
+}
+
+void TrapFault::invoke(ThreadContext *tc)
+{
+  DPRINTF(Arm,"%s encountered.\n", name());
+  //  warn("%s encountered.\n", name());
+  setExceptionState(tc,0xD);
+
+  // Set new PC
+  Addr HandlerBase;
+  HandlerBase= vect() + tc->readMiscReg(ArmISA::EBase); // Offset 0x180 - General Exception Vector
+  setHandlerPC(HandlerBase,tc);
+  //      warn("Exception Handler At: %x \n",HandlerBase);
+  //      warn("Exception Handler At: %x , EPC set to %x\n",HandlerBase,tc->readMiscReg(ArmISA::EPC));
+}
+
+void BreakpointFault::invoke(ThreadContext *tc)
+{
+      setExceptionState(tc,0x9);
+
+      // Set new PC
+      Addr HandlerBase;
+      HandlerBase= vect() + tc->readMiscReg(ArmISA::EBase); // Offset 0x180 - General Exception Vector
+      setHandlerPC(HandlerBase,tc);
+      //      warn("Exception Handler At: %x \n",HandlerBase);
+      //      warn("Exception Handler At: %x , EPC set to %x\n",HandlerBase,tc->readMiscReg(ArmISA::EPC));
+
+}
+
+void DtbInvalidFault::invoke(ThreadContext *tc)
+{
+  DPRINTF(Arm,"%s encountered.\n", name());
+  //    warn("%s encountered.\n", name());
+  tc->setMiscRegNoEffect(ArmISA::BadVAddr,BadVAddr);
+  MiscReg eh = tc->readMiscReg(ArmISA::EntryHi);
+  replaceBits(eh,EntryHi_ASID_HI,EntryHi_ASID_LO,EntryHi_Asid);
+  replaceBits(eh,EntryHi_VPN2_HI,EntryHi_VPN2_LO,EntryHi_VPN2);
+  replaceBits(eh,EntryHi_VPN2X_HI,EntryHi_VPN2X_LO,EntryHi_VPN2X);
+  tc->setMiscRegNoEffect(ArmISA::EntryHi,eh);
+  MiscReg ctxt = tc->readMiscReg(ArmISA::Context);
+  replaceBits(ctxt,Context_BadVPN2_HI,Context_BadVPN2_LO,Context_BadVPN2);
+  tc->setMiscRegNoEffect(ArmISA::Context,ctxt);
+  setExceptionState(tc,0x3);
+
+
+  // Set new PC
+  Addr HandlerBase;
+  HandlerBase= vect() + tc->readMiscReg(ArmISA::EBase); // Offset 0x180 - General Exception Vector
+  setHandlerPC(HandlerBase,tc);
+  //      warn("Exception Handler At: %x , EPC set to %x\n",HandlerBase,tc->readMiscReg(ArmISA::EPC));
+}
+
+void AddressErrorFault::invoke(ThreadContext *tc)
+{
+  DPRINTF(Arm,"%s encountered.\n", name());
+      setExceptionState(tc,0x4);
+      tc->setMiscRegNoEffect(ArmISA::BadVAddr,BadVAddr);
+
+      // Set new PC
+      Addr HandlerBase;
+      HandlerBase= vect() + tc->readMiscReg(ArmISA::EBase); // Offset 0x180 - General Exception Vector
+      setHandlerPC(HandlerBase,tc);
+}
+
+void ItbInvalidFault::invoke(ThreadContext *tc)
+{
+  DPRINTF(Arm,"%s encountered.\n", name());
+      setExceptionState(tc,0x2);
+      tc->setMiscRegNoEffect(ArmISA::BadVAddr,BadVAddr);
+      MiscReg eh = tc->readMiscReg(ArmISA::EntryHi);
+      replaceBits(eh,EntryHi_ASID_HI,EntryHi_ASID_LO,EntryHi_Asid);
+      replaceBits(eh,EntryHi_VPN2_HI,EntryHi_VPN2_LO,EntryHi_VPN2);
+      replaceBits(eh,EntryHi_VPN2X_HI,EntryHi_VPN2X_LO,EntryHi_VPN2X);
+      tc->setMiscRegNoEffect(ArmISA::EntryHi,eh);
+      MiscReg ctxt = tc->readMiscReg(ArmISA::Context);
+      replaceBits(ctxt,Context_BadVPN2_HI,Context_BadVPN2_LO,Context_BadVPN2);
+      tc->setMiscRegNoEffect(ArmISA::Context,ctxt);
+
+
+      // Set new PC
+      Addr HandlerBase;
+      HandlerBase= vect() + tc->readMiscReg(ArmISA::EBase); // Offset 0x180 - General Exception Vector
+      setHandlerPC(HandlerBase,tc);
+      DPRINTF(Arm,"Exception Handler At: %x , EPC set to %x\n",HandlerBase,tc->readMiscReg(ArmISA::EPC));
+}
+
+void ItbRefillFault::invoke(ThreadContext *tc)
+{
+  DPRINTF(Arm,"%s encountered (%x).\n", name(),BadVAddr);
+  Addr HandlerBase;
+  tc->setMiscRegNoEffect(ArmISA::BadVAddr,BadVAddr);
+  MiscReg eh = tc->readMiscReg(ArmISA::EntryHi);
+  replaceBits(eh,EntryHi_ASID_HI,EntryHi_ASID_LO,EntryHi_Asid);
+  replaceBits(eh,EntryHi_VPN2_HI,EntryHi_VPN2_LO,EntryHi_VPN2);
+  replaceBits(eh,EntryHi_VPN2X_HI,EntryHi_VPN2X_LO,EntryHi_VPN2X);
+  tc->setMiscRegNoEffect(ArmISA::EntryHi,eh);
+  MiscReg ctxt = tc->readMiscReg(ArmISA::Context);
+  replaceBits(ctxt,Context_BadVPN2_HI,Context_BadVPN2_LO,Context_BadVPN2);
+  tc->setMiscRegNoEffect(ArmISA::Context,ctxt);
+
+  MiscReg stat = tc->readMiscReg(ArmISA::Status);
+  // Since handler depends on EXL bit, must check EXL bit before setting it!!
+  if(bits(stat,Status_EXL)==1){ // See MIPS ARM Vol 3, Revision 2, Page 38
+    HandlerBase= vect() + tc->readMiscReg(ArmISA::EBase); // Offset 0x180 - General Exception Vector
+  }else{
+    HandlerBase = tc->readMiscReg(ArmISA::EBase); // Offset 0x000
+  }
+
+  setExceptionState(tc,0x2);
+  setHandlerPC(HandlerBase,tc);
+}
+
+void DtbRefillFault::invoke(ThreadContext *tc)
+{
+  // Set new PC
+  DPRINTF(Arm,"%s encountered.\n", name());
+  Addr HandlerBase;
+  tc->setMiscRegNoEffect(ArmISA::BadVAddr,BadVAddr);
+  MiscReg eh = tc->readMiscReg(ArmISA::EntryHi);
+  replaceBits(eh,EntryHi_ASID_HI,EntryHi_ASID_LO,EntryHi_Asid);
+  replaceBits(eh,EntryHi_VPN2_HI,EntryHi_VPN2_LO,EntryHi_VPN2);
+  replaceBits(eh,EntryHi_VPN2X_HI,EntryHi_VPN2X_LO,EntryHi_VPN2X);
+  tc->setMiscRegNoEffect(ArmISA::EntryHi,eh);
+  MiscReg ctxt = tc->readMiscReg(ArmISA::Context);
+  replaceBits(ctxt,Context_BadVPN2_HI,Context_BadVPN2_LO,Context_BadVPN2);
+  tc->setMiscRegNoEffect(ArmISA::Context,ctxt);
+
+  MiscReg stat = tc->readMiscReg(ArmISA::Status);
+  // Since handler depends on EXL bit, must check EXL bit before setting it!!
+  if(bits(stat,Status_EXL)==1){ // See MIPS ARM Vol 3, Revision 2, Page 38
+    HandlerBase= vect() + tc->readMiscReg(ArmISA::EBase); // Offset 0x180 - General Exception Vector
+  }else{
+    HandlerBase = tc->readMiscReg(ArmISA::EBase); // Offset 0x000
+  }
+
+
+  setExceptionState(tc,0x3);
+
+  setHandlerPC(HandlerBase,tc);
+}
+
+void TLBModifiedFault::invoke(ThreadContext *tc)
+{
+  DPRINTF(Arm,"%s encountered.\n", name());
+  tc->setMiscRegNoEffect(ArmISA::BadVAddr,BadVAddr);
+  MiscReg eh = tc->readMiscReg(ArmISA::EntryHi);
+  replaceBits(eh,EntryHi_ASID_HI,EntryHi_ASID_LO,EntryHi_Asid);
+  replaceBits(eh,EntryHi_VPN2_HI,EntryHi_VPN2_LO,EntryHi_VPN2);
+  replaceBits(eh,EntryHi_VPN2X_HI,EntryHi_VPN2X_LO,EntryHi_VPN2X);
+  tc->setMiscRegNoEffect(ArmISA::EntryHi,eh);
+  MiscReg ctxt = tc->readMiscReg(ArmISA::Context);
+  replaceBits(ctxt,Context_BadVPN2_HI,Context_BadVPN2_LO,Context_BadVPN2);
+  tc->setMiscRegNoEffect(ArmISA::Context,ctxt);
+
+    // Set new PC
+      Addr HandlerBase;
+      HandlerBase= vect() + tc->readMiscReg(ArmISA::EBase); // Offset 0x180 - General Exception Vector
+      setExceptionState(tc,0x1);
+      setHandlerPC(HandlerBase,tc);
+      //      warn("Exception Handler At: %x , EPC set to %x\n",HandlerBase,tc->readMiscReg(ArmISA::EPC));
+
+}
+
+void SystemCallFault::invoke(ThreadContext *tc)
+{
+  DPRINTF(Arm,"%s encountered.\n", name());
+      setExceptionState(tc,0x8);
+
+      // Set new PC
+      Addr HandlerBase;
+      HandlerBase= vect() + tc->readMiscReg(ArmISA::EBase); // Offset 0x180 - General Exception Vector
+      setHandlerPC(HandlerBase,tc);
+      //      warn("Exception Handler At: %x \n",HandlerBase);
+      //      warn("Exception Handler At: %x , EPC set to %x\n",HandlerBase,tc->readMiscReg(ArmISA::EPC));
+
+}
+
+void InterruptFault::invoke(ThreadContext *tc)
+{
+#if  FULL_SYSTEM
+  DPRINTF(Arm,"%s encountered.\n", name());
+  //RegFile *Reg = tc->getRegFilePtr(); // Get pointer to the register fil
+  setExceptionState(tc,0x0A);
+  Addr HandlerBase;
+
+
+  uint8_t IV = bits(tc->readMiscRegNoEffect(ArmISA::Cause),Cause_IV);
+  if (IV)// Offset 200 for release 2
+      HandlerBase= 0x20 + vect() + tc->readMiscRegNoEffect(ArmISA::EBase);
+  else//Ofset at 180 for release 1
+      HandlerBase= vect() + tc->readMiscRegNoEffect(ArmISA::EBase);
+
+  setHandlerPC(HandlerBase,tc);
+#endif
+}
+
+#endif // FULL_SYSTEM
+
+void ResetFault::invoke(ThreadContext *tc)
+{
+#if FULL_SYSTEM
+  DPRINTF(Arm,"%s encountered.\n", name());
+  /* All reset activity must be invoked from here */
+  tc->setPC(vect());
+  tc->setNextPC(vect()+sizeof(MachInst));
+  tc->setNextNPC(vect()+sizeof(MachInst)+sizeof(MachInst));
+  DPRINTF(Arm,"(%x)  -  ResetFault::invoke : PC set to %x",(unsigned)tc,(unsigned)tc->readPC());
+#endif
+
+  // Set Coprocessor 1 (Floating Point) To Usable
+  //tc->setMiscReg(ArmISA::Status, ArmISA::Status | 0x20000000);
+}
+
+void ReservedInstructionFault::invoke(ThreadContext *tc)
+{
+#if  FULL_SYSTEM
+  DPRINTF(Arm,"%s encountered.\n", name());
+  //RegFile *Reg = tc->getRegFilePtr(); // Get pointer to the register fil
+  setExceptionState(tc,0x0A);
+  Addr HandlerBase;
+  HandlerBase= vect() + tc->readMiscRegNoEffect(ArmISA::EBase); // Offset 0x180 - General Exception Vector
+  setHandlerPC(HandlerBase,tc);
+#else
+    panic("%s encountered.\n", name());
+#endif
+}
+
+void ThreadFault::invoke(ThreadContext *tc)
+{
+  DPRINTF(Arm,"%s encountered.\n", name());
+  panic("%s encountered.\n", name());
+}
+
+void DspStateDisabledFault::invoke(ThreadContext *tc)
+{
+  DPRINTF(Arm,"%s encountered.\n", name());
+  panic("%s encountered.\n", name());
+}
+
+void CoprocessorUnusableFault::invoke(ThreadContext *tc)
+{
+#if FULL_SYSTEM
+  DPRINTF(Arm,"%s encountered.\n", name());
+  setExceptionState(tc,0xb);
+  /* The ID of the coprocessor causing the exception is stored in CoprocessorUnusableFault::coProcID */
+  MiscReg cause = tc->readMiscReg(ArmISA::Cause);
+  replaceBits(cause,Cause_CE_HI,Cause_CE_LO,coProcID);
+  tc->setMiscRegNoEffect(ArmISA::Cause,cause);
+
+  Addr HandlerBase;
+  HandlerBase= vect() + tc->readMiscReg(ArmISA::EBase); // Offset 0x180 - General Exception Vector
+  setHandlerPC(HandlerBase,tc);
+
+  //      warn("Status: %x, Cause: %x\n",tc->readMiscReg(ArmISA::Status),tc->readMiscReg(ArmISA::Cause));
+#else
+    warn("%s (CP%d) encountered.\n", name(), coProcID);
+#endif
+}
+
+} // namespace ArmISA
+
diff --git a/src/arch/arm/faults.hh b/src/arch/arm/faults.hh
new file mode 100644 (file)
index 0000000..28ecd75
--- /dev/null
@@ -0,0 +1,574 @@
+/*
+ * Copyright (c) 2003-2005 The Regents of The University of Michigan
+ * Copyright (c) 2007-2008 The Florida State University
+ * 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
+ */
+
+#ifndef __ARM_FAULTS_HH__
+#define __ARM_FAULTS_HH__
+
+#include "sim/faults.hh"
+
+// The design of the "name" and "vect" functions is in sim/faults.hh
+
+namespace ArmISA
+{
+typedef const Addr FaultVect;
+
+class ArmFault : public FaultBase
+{
+  protected:
+    virtual bool skipFaultingInstruction() {return false;}
+    virtual bool setRestartAddress() {return true;}
+  public:
+    Addr BadVAddr;
+    Addr EntryHi_Asid;
+    Addr EntryHi_VPN2;
+    Addr EntryHi_VPN2X;
+    Addr Context_BadVPN2;
+#if FULL_SYSTEM
+  void invoke(ThreadContext * tc) {};
+  void setExceptionState(ThreadContext *,uint8_t);
+  void setHandlerPC(Addr,ThreadContext *);
+#endif
+    virtual FaultVect vect() = 0;
+    virtual FaultStat & countStat() = 0;
+};
+
+class MachineCheckFault : public ArmFault
+{
+  private:
+    static FaultName _name;
+    static FaultVect _vect;
+    static FaultStat _count;
+  public:
+    FaultName name() const {return _name;}
+    FaultVect vect() {return _vect;}
+    FaultStat & countStat() {return _count;}
+    bool isMachineCheckFault() {return true;}
+};
+
+class NonMaskableInterrupt : public ArmFault
+{
+  private:
+    static FaultName _name;
+    static FaultVect _vect;
+    static FaultStat _count;
+  public:
+    FaultName name() const {return _name;}
+    FaultVect vect() {return _vect;}
+    FaultStat & countStat() {return _count;}
+    bool isNonMaskableInterrupt() {return true;}
+};
+
+class AlignmentFault : public ArmFault
+{
+  private:
+    static FaultName _name;
+    static FaultVect _vect;
+    static FaultStat _count;
+  public:
+    FaultName name() const {return _name;}
+    FaultVect vect() {return _vect;}
+    FaultStat & countStat() {return _count;}
+    bool isAlignmentFault() {return true;}
+};
+
+class AddressErrorFault : public ArmFault
+{
+  private:
+    static FaultName _name;
+    static FaultVect _vect;
+    static FaultStat _count;
+  public:
+    FaultName name() const {return _name;}
+    FaultVect vect() {return _vect;}
+    FaultStat & countStat() {return _count;}
+#if FULL_SYSTEM
+    void invoke(ThreadContext * tc);
+#endif
+
+};
+class StoreAddressErrorFault : public ArmFault
+{
+  private:
+    static FaultName _name;
+    static FaultVect _vect;
+    static FaultStat _count;
+  public:
+    FaultName name() const {return _name;}
+    FaultVect vect() {return _vect;}
+    FaultStat & countStat() {return _count;}
+#if FULL_SYSTEM
+    void invoke(ThreadContext * tc);
+#endif
+
+};
+class UnimplementedOpcodeFault : public ArmFault
+{
+  private:
+    static FaultName _name;
+    static FaultVect _vect;
+    static FaultStat _count;
+  public:
+    FaultName name() const {return _name;}
+    FaultVect vect() {return _vect;}
+    FaultStat & countStat() {return _count;}
+};
+
+
+class TLBRefillIFetchFault : public ArmFault
+{
+  private:
+    Addr vaddr;
+    static FaultName _name;
+    static FaultVect _vect;
+    static FaultStat _count;
+  public:
+    FaultName name() const {return _name;}
+    FaultVect vect() {return _vect;}
+    FaultStat & countStat() {return _count;}
+    void invoke(ThreadContext * tc);
+};
+class TLBInvalidIFetchFault : public ArmFault
+{
+  private:
+    Addr vaddr;
+    static FaultName _name;
+    static FaultVect _vect;
+    static FaultStat _count;
+  public:
+    FaultName name() const {return _name;}
+    FaultVect vect() {return _vect;}
+    FaultStat & countStat() {return _count;}
+    void invoke(ThreadContext * tc);
+};
+
+class NDtbMissFault : public ArmFault
+{
+  private:
+    static FaultName _name;
+    static FaultVect _vect;
+    static FaultStat _count;
+  public:
+    FaultName name() const {return _name;}
+    FaultVect vect() {return _vect;}
+    FaultStat & countStat() {return _count;}
+};
+
+class PDtbMissFault : public ArmFault
+{
+  private:
+    static FaultName _name;
+    static FaultVect _vect;
+    static FaultStat _count;
+  public:
+    FaultName name() const {return _name;}
+    FaultVect vect() {return _vect;}
+    FaultStat & countStat() {return _count;}
+};
+
+class DtbPageFault : public ArmFault
+{
+  private:
+    static FaultName _name;
+    static FaultVect _vect;
+    static FaultStat _count;
+  public:
+    FaultName name() const {return _name;}
+    FaultVect vect() {return _vect;}
+    FaultStat & countStat() {return _count;}
+};
+
+class DtbAcvFault : public ArmFault
+{
+  private:
+    static FaultName _name;
+    static FaultVect _vect;
+    static FaultStat _count;
+  public:
+    FaultName name() const {return _name;}
+    FaultVect vect() {return _vect;}
+    FaultStat & countStat() {return _count;}
+};
+
+class CacheErrorFault : public ArmFault
+{
+  private:
+    Addr vaddr;
+    static FaultName _name;
+    static FaultVect _vect;
+    static FaultStat _count;
+  public:
+    FaultName name() const {return _name;}
+    FaultVect vect() {return _vect;}
+    FaultStat & countStat() {return _count;}
+    void invoke(ThreadContext * tc);
+};
+
+
+
+
+static inline Fault genMachineCheckFault()
+{
+    return new MachineCheckFault;
+}
+
+static inline Fault genAlignmentFault()
+{
+    return new AlignmentFault;
+}
+
+class ResetFault : public ArmFault
+{
+  private:
+    static FaultName _name;
+    static FaultVect _vect;
+    static FaultStat _count;
+  public:
+    FaultName name() const {return _name;}
+    FaultVect vect() {return _vect;}
+    FaultStat & countStat() {return _count;}
+    void invoke(ThreadContext * tc);
+
+};
+class SystemCallFault : public ArmFault
+{
+  private:
+    static FaultName _name;
+    static FaultVect _vect;
+    static FaultStat _count;
+  public:
+    FaultName name() const {return _name;}
+    FaultVect vect() {return _vect;}
+    FaultStat & countStat() {return _count;}
+    void invoke(ThreadContext * tc);
+};
+
+class SoftResetFault : public ArmFault
+{
+  private:
+    static FaultName _name;
+    static FaultVect _vect;
+    static FaultStat _count;
+  public:
+    FaultName name() const {return _name;}
+    FaultVect vect() {return _vect;}
+    FaultStat & countStat() {return _count;}
+    void invoke(ThreadContext * tc);
+};
+class DebugSingleStep : public ArmFault
+{
+  private:
+    static FaultName _name;
+    static FaultVect _vect;
+    static FaultStat _count;
+  public:
+    FaultName name() const {return _name;}
+    FaultVect vect() {return _vect;}
+    FaultStat & countStat() {return _count;}
+    void invoke(ThreadContext * tc);
+};
+class DebugInterrupt : public ArmFault
+{
+  private:
+    static FaultName _name;
+    static FaultVect _vect;
+    static FaultStat _count;
+  public:
+    FaultName name() const {return _name;}
+    FaultVect vect() {return _vect;}
+    FaultStat & countStat() {return _count;}
+    void invoke(ThreadContext * tc);
+};
+
+class CoprocessorUnusableFault : public ArmFault
+{
+  private:
+    static FaultName _name;
+    static FaultVect _vect;
+    static FaultStat _count;
+    int coProcID;
+  public:
+    FaultName name() const {return _name;}
+    FaultVect vect() {return _vect;}
+    FaultStat & countStat() {return _count;}
+    void invoke(ThreadContext * tc);
+    CoprocessorUnusableFault(int _procid){ coProcID = _procid;}
+};
+
+class ReservedInstructionFault : public ArmFault
+{
+  private:
+    static FaultName _name;
+    static FaultVect _vect;
+    static FaultStat _count;
+  public:
+    FaultName name() const {return _name;}
+    FaultVect vect() {return _vect;}
+    FaultStat & countStat() {return _count;}
+    void invoke(ThreadContext * tc);
+};
+
+class ThreadFault : public ArmFault
+{
+  private:
+    static FaultName _name;
+    static FaultVect _vect;
+    static FaultStat _count;
+  public:
+    FaultName name() const {return _name;}
+    FaultVect vect() {return _vect;}
+    FaultStat & countStat() {return _count;}
+    void invoke(ThreadContext * tc);
+};
+
+
+class ArithmeticFault : public ArmFault
+{
+  protected:
+    bool skipFaultingInstruction() {return true;}
+  private:
+    static FaultName _name;
+    static FaultVect _vect;
+    static FaultStat _count;
+  public:
+    FaultName name() const {return _name;}
+    FaultVect vect() {return _vect;}
+    FaultStat & countStat() {return _count;}
+#if FULL_SYSTEM
+    void invoke(ThreadContext * tc);
+#endif
+};
+
+class InterruptFault : public ArmFault
+{
+  protected:
+    bool setRestartAddress() {return false;}
+  private:
+    static FaultName _name;
+    static FaultVect _vect;
+    static FaultStat _count;
+  public:
+    FaultName name() const {return _name;}
+    FaultVect vect() {return _vect;}
+    FaultStat & countStat() {return _count;}
+
+#if FULL_SYSTEM
+    void invoke(ThreadContext * tc);
+#endif
+
+    //void invoke(ThreadContext * tc);
+};
+
+class TrapFault : public ArmFault
+{
+  private:
+    static FaultName _name;
+    static FaultVect _vect;
+    static FaultStat _count;
+  public:
+    FaultName name() const {return _name;}
+    FaultVect vect() {return _vect;}
+    FaultStat & countStat() {return _count;}
+#if FULL_SYSTEM
+    void invoke(ThreadContext * tc);
+#endif
+};
+
+class BreakpointFault : public ArmFault
+{
+  private:
+    static FaultName _name;
+    static FaultVect _vect;
+    static FaultStat _count;
+  public:
+    FaultName name() const {return _name;}
+    FaultVect vect() {return _vect;}
+    FaultStat & countStat() {return _count;}
+#if FULL_SYSTEM
+    void invoke(ThreadContext * tc);
+#endif
+};
+
+class ItbRefillFault : public ArmFault
+{
+  private:
+    static FaultName _name;
+    static FaultVect _vect;
+    static FaultStat _count;
+  public:
+    FaultName name() const {return _name;}
+    FaultVect vect() {return _vect;}
+    FaultStat & countStat() {return _count;}
+#if FULL_SYSTEM
+    void invoke(ThreadContext * tc);
+#endif
+};
+class DtbRefillFault : public ArmFault
+{
+  private:
+    static FaultName _name;
+    static FaultVect _vect;
+    static FaultStat _count;
+  public:
+    FaultName name() const {return _name;}
+    FaultVect vect() {return _vect;}
+    FaultStat & countStat() {return _count;}
+#if FULL_SYSTEM
+    void invoke(ThreadContext * tc);
+#endif
+};
+
+class ItbPageFault : public ArmFault
+{
+  private:
+    static FaultName _name;
+    static FaultVect _vect;
+    static FaultStat _count;
+  public:
+    FaultName name() const {return _name;}
+    FaultVect vect() {return _vect;}
+    FaultStat & countStat() {return _count;}
+#if FULL_SYSTEM
+    void invoke(ThreadContext * tc);
+#endif
+};
+
+class ItbInvalidFault : public ArmFault
+{
+  private:
+    static FaultName _name;
+    static FaultVect _vect;
+    static FaultStat _count;
+  public:
+    FaultName name() const {return _name;}
+    FaultVect vect() {return _vect;}
+    FaultStat & countStat() {return _count;}
+#if FULL_SYSTEM
+    void invoke(ThreadContext * tc);
+#endif
+
+};
+class TLBModifiedFault : public ArmFault
+{
+  private:
+    static FaultName _name;
+    static FaultVect _vect;
+    static FaultStat _count;
+  public:
+    FaultName name() const {return _name;}
+    FaultVect vect() {return _vect;}
+    FaultStat & countStat() {return _count;}
+#if FULL_SYSTEM
+    void invoke(ThreadContext * tc);
+#endif
+
+};
+
+class DtbInvalidFault : public ArmFault
+{
+  private:
+    static FaultName _name;
+    static FaultVect _vect;
+    static FaultStat _count;
+  public:
+    FaultName name() const {return _name;}
+    FaultVect vect() {return _vect;}
+    FaultStat & countStat() {return _count;}
+#if FULL_SYSTEM
+    void invoke(ThreadContext * tc);
+#endif
+
+};
+
+class FloatEnableFault : public ArmFault
+{
+  private:
+    static FaultName _name;
+    static FaultVect _vect;
+    static FaultStat _count;
+  public:
+    FaultName name() const {return _name;}
+    FaultVect vect() {return _vect;}
+    FaultStat & countStat() {return _count;}
+};
+
+class ItbMissFault : public ArmFault
+{
+  private:
+    static FaultName _name;
+    static FaultVect _vect;
+    static FaultStat _count;
+  public:
+    FaultName name() const {return _name;}
+    FaultVect vect() {return _vect;}
+    FaultStat & countStat() {return _count;}
+};
+
+class ItbAcvFault : public ArmFault
+{
+  private:
+    static FaultName _name;
+    static FaultVect _vect;
+    static FaultStat _count;
+  public:
+    FaultName name() const {return _name;}
+    FaultVect vect() {return _vect;}
+    FaultStat & countStat() {return _count;}
+};
+
+class IntegerOverflowFault : public ArmFault
+{
+  private:
+    static FaultName _name;
+    static FaultVect _vect;
+    static FaultStat _count;
+  public:
+    FaultName name() const {return _name;}
+    FaultVect vect() {return _vect;}
+    FaultStat & countStat() {return _count;}
+};
+
+class DspStateDisabledFault : public ArmFault
+{
+  private:
+    static FaultName _name;
+    static FaultVect _vect;
+    static FaultStat _count;
+  public:
+    FaultName name() const {return _name;}
+    FaultVect vect() {return _vect;}
+    FaultStat & countStat() {return _count;}
+    void invoke(ThreadContext * tc);
+};
+
+} // ArmISA namespace
+
+#endif // __ARM_FAULTS_HH__
diff --git a/src/arch/arm/isa/base.isa b/src/arch/arm/isa/base.isa
new file mode 100644 (file)
index 0000000..d492bd3
--- /dev/null
@@ -0,0 +1,87 @@
+// -*- mode:c++ -*-
+
+// Copyright (c) 2007-2008 The Florida State University
+// 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
+
+////////////////////////////////////////////////////////////////////
+//
+// Base class for ARM instructions, and some support functions
+//
+
+//Outputs to decoder.hh
+output header {{
+
+    using namespace ArmISA;
+
+    /**
+     * Base class for all MIPS static instructions.
+     */
+    class ArmStaticInst : public StaticInst
+    {
+      protected:
+
+        // Constructor
+        ArmStaticInst(const char *mnem, MachInst _machInst, OpClass __opClass)
+            : StaticInst(mnem, _machInst, __opClass)
+        {
+        }
+
+        /// 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;
+    };
+
+}};
+
+//Ouputs to decoder.cc
+output decoder {{
+
+    void ArmStaticInst::printReg(std::ostream &os, int reg) const
+    {
+        if (reg < FP_Base_DepTag) {
+            ccprintf(os, "r%d", reg);
+        }
+        else {
+            ccprintf(os, "f%d", reg - FP_Base_DepTag);
+        }
+    }
+
+    std::string ArmStaticInst::generateDisassembly(Addr pc,
+            const SymbolTable *symtab) const
+    {
+        std::stringstream ss;
+
+        ccprintf(ss, "%-10s ", mnemonic);
+
+        return ss.str();
+    }
+
+}};
+
diff --git a/src/arch/arm/isa/bitfields.isa b/src/arch/arm/isa/bitfields.isa
new file mode 100644 (file)
index 0000000..bcb2869
--- /dev/null
@@ -0,0 +1,170 @@
+// -*- mode:c++ -*-
+
+// Copyright (c) 2007-2008 The Florida State University
+// 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
+
+////////////////////////////////////////////////////////////////////
+//
+// Bitfield definitions.
+//
+
+// Opcode fields
+def bitfield OPCODE        <27:25>;
+def bitfield OPCODE_27_25  <27:25>;
+def bitfield OPCODE_24_21  <24:21>;
+def bitfield OPCODE_24_23  <24:23>;
+def bitfield OPCODE_24    <24:24>;
+def bitfield OPCODE_23_20  <23:20>;
+def bitfield OPCODE_23_21  <23:21>;
+def bitfield OPCODE_23     <23:23>;
+def bitfield OPCODE_22_8   <22: 8>;
+def bitfield OPCODE_22_21  <22:21>;
+def bitfield OPCODE_22     <22:22>;
+def bitfield OPCODE_21_20  <21:20>;
+def bitfield OPCODE_20     <20:20>;
+def bitfield OPCODE_19_18  <19:18>;
+def bitfield OPCODE_19    <19:19>;
+def bitfield OPCODE_15_12  <15:12>;
+def bitfield OPCODE_15    <15:15>;
+def bitfield OPCODE_9      < 9: 9>;
+def bitfield OPCODE_7_4    < 7: 4>;
+def bitfield OPCODE_7_5           < 7: 5>;
+def bitfield OPCODE_7_6    < 7: 6>;
+def bitfield OPCODE_7      < 7: 7>;
+def bitfield OPCODE_6_5           < 6: 5>;
+def bitfield OPCODE_6     < 6: 6>;
+def bitfield OPCODE_5     < 5: 5>;
+def bitfield OPCODE_4      < 4: 4>;
+
+// Other
+def bitfield COND_CODE     <31:28>;
+def bitfield S_FIELD       <20:20>;
+def bitfield RN            <19:16>;
+def bitfield RD            <15:12>;
+def bitfield SHIFT_SIZE    <11: 7>;
+def bitfield SHIFT         < 6: 5>;
+def bitfield RM            < 3: 0>;
+
+def bitfield RE            <20:16>;
+
+def bitfield RS            <11: 8>;
+
+def bitfield RDUP          <19:16>;
+def bitfield RNDN          <15:12>;
+
+def bitfield RDHI          <15:12>;
+def bitfield RDLO          <11: 8>;
+
+def bitfield U_FIELD       <23:23>;
+
+def bitfield PUSWL        <24:20>;
+def bitfield PREPOST      <24:24>;
+def bitfield UP                   <23:23>;
+def bitfield PSRUSER      <22:22>;
+def bitfield WRITEBACK    <21:21>;
+def bitfield LOADOP        <20:20>;
+
+def bitfield PUBWL        <24:20>;
+def bitfield PUIWL        <24:20>;
+def bitfield BYTEACCESS           <22:22>;
+
+def bitfield LUAS         <23:20>;
+
+def bitfield IMM          < 7: 0>;
+def bitfield IMMED_7_4     < 7: 4>;
+def bitfield IMMED_3_0     < 3: 0>;
+
+def bitfield F_MSR         <19:19>;
+def bitfield S_MSR         <18:18>;
+def bitfield X_MSR         <17:17>;
+def bitfield C_MSR         <16:16>;
+
+def bitfield Y_6           < 6: 6>;
+def bitfield X_5           < 5: 5>;
+
+def bitfield IMMED_15_4    <15: 4>;
+
+def bitfield W_FIELD       <21:21>;
+
+def bitfield ROTATE        <11: 8>;
+def bitfield IMMED_7_0     < 7: 0>;
+
+def bitfield T_FIELD       <21:21>;
+def bitfield IMMED_11_0    <11: 0>;
+
+def bitfield IMMED_20_16   <20:16>;
+def bitfield IMMED_19_16   <19:16>;
+
+def bitfield IMMED_HI_11_8 <11: 8>;
+def bitfield IMMED_LO_3_0  < 3: 0>;
+
+def bitfield ROT           <11:10>;
+
+def bitfield R_FIELD       < 5: 5>;
+
+def bitfield CARET         <22:22>;
+def bitfield REGLIST       <15: 0>;
+
+def bitfield OFFSET        <23: 0>;
+def bitfield COPRO         <11: 8>;
+def bitfield OP1_7_4       < 7: 4>;
+def bitfield CM            < 3: 0>;
+
+def bitfield L_FIELD       <22:22>;
+def bitfield CD            <15:12>;
+def bitfield OPTION        < 7: 0>;
+
+def bitfield OP1_23_20     <23:20>;
+def bitfield CN            <19:16>;
+def bitfield OP2_7_5       < 7: 5>;
+
+def bitfield OP1_23_21     <23:21>;
+
+def bitfield IMMED_23_0    <23: 0>;
+def bitfield M_FIELD       <17:17>;
+def bitfield A_FIELD       < 8: 8>;
+def bitfield I_FIELD       < 7: 7>;
+def bitfield F_FIELD       < 6: 6>;
+def bitfield MODE          < 4: 0>;
+
+def bitfield A_BLX         <24:24>;
+
+def bitfield CPNUM        <11: 8>;
+// Note that FP Regs are only 3 bits
+def bitfield FN                   <18:16>;
+def bitfield FD                   <14:12>;
+def bitfield FPREGIMM     < 3: 3>;
+// We can just use 3:0 for FM since the hard-wired FP regs are handled in
+// float_regfile.hh
+def bitfield FM                   < 3: 0>;
+def bitfield FPIMM        < 2: 0>;
+def bitfield PUNWL        <24:20>;
+
+// M5 instructions
+def bitfield M5FUNC <7:0>;
+
diff --git a/src/arch/arm/isa/copyright.txt b/src/arch/arm/isa/copyright.txt
new file mode 100644 (file)
index 0000000..5a5c487
--- /dev/null
@@ -0,0 +1,28 @@
+// Copyright (c) 2007, 2008
+// The Florida State University
+// All Rights Reserved
+//
+// This code is part of the M5 simulator.
+//
+// Permission is granted to use, copy, create derivative works and
+// redistribute this software and such derivative works for any
+// purpose, so long as the copyright notice above, this grant of
+// permission, and the disclaimer below appear in all copies made; and
+// so long as the name of The Florida State University is not used in
+// any advertising or publicity pertaining to the use or distribution
+// of this software without specific, written prior authorization.
+//
+// THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION FROM THE
+// FLORIDA STATE UNIVERSITY AS TO ITS FITNESS FOR ANY PURPOSE, AND
+// WITHOUT WARRANTY BY THE FLORIDA STATE UNIVERSITY OF ANY KIND, EITHER
+// EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+// PURPOSE. THE REGENTS OF THE FLORIDA STATE UNIVERSITY SHALL NOT BE
+// LIABLE FOR ANY DAMAGES, INCLUDING DIRECT, SPECIAL, INDIRECT,
+// INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM
+// ARISING OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN
+// IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF SUCH
+// DAMAGES.
+//
+// Authors: Stephen R. Hines - modified for use in ARM version
+
diff --git a/src/arch/arm/isa/decoder.isa b/src/arch/arm/isa/decoder.isa
new file mode 100644 (file)
index 0000000..459c978
--- /dev/null
@@ -0,0 +1,845 @@
+// -*- mode:c++ -*-
+
+// Copyright (c) 2007-2008 The Florida State University
+// 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
+
+////////////////////////////////////////////////////////////////////
+//
+// The actual ARM ISA decoder
+// --------------------------
+// The following instructions are specified in the ARM ISA
+// Specification. Decoding closely follows the style specified
+// in the ARM ISA specification document starting with Table B.1 or 3-1
+//
+//
+decode COND_CODE default Unknown::unknown() {
+    0xf: decode COND_CODE {
+        0x0: decode OPCODE_27_25 {
+            // Just a simple trick to allow us to specify our new uops here
+            0x0: PredImmOp::addi_uop({{ Raddr = Rn + rotated_imm; }},
+                                        'IsMicroop');
+            0x1: PredImmOp::subi_uop({{ Raddr = Rn - rotated_imm; }},
+                                        'IsMicroop');
+            0x2: ArmLoadMemory::ldr_uop({{ Rd = Mem; }},
+                                        {{ EA = Raddr + disp; }},
+                                           inst_flags = [IsMicroop]);
+            0x3: ArmStoreMemory::str_uop({{ Mem = Rd; }},
+                                         {{ EA = Raddr + disp; }},
+                                            inst_flags = [IsMicroop]);
+            0x4: PredImmOp::addi_rd_uop({{ Rd = Rn + rotated_imm; }},
+                                           'IsMicroop');
+            0x5: PredImmOp::subi_rd_uop({{ Rd = Rn - rotated_imm; }},
+                                           'IsMicroop');
+        }
+        0x1: decode OPCODE_27_25 {
+            0x0: PredIntOp::mvtd_uop({{ Fd.ud = ((uint64_t) Rhi << 32)|Rlo; }},
+                                        'IsMicroop');
+            0x1: PredIntOp::mvfd_uop({{ Rhi = (Fd.ud >> 32) & 0xffffffff;
+                                        Rlo = Fd.ud & 0xffffffff; }},
+                                        'IsMicroop');
+            0x2: ArmLoadMemory::ldhi_uop({{ Rhi = Mem; }},
+                                         {{ EA = Rn + disp; }},
+                                            inst_flags = [IsMicroop]);
+            0x3: ArmLoadMemory::ldlo_uop({{ Rlo = Mem; }},
+                                         {{ EA = Rn + disp; }},
+                                            inst_flags = [IsMicroop]);
+            0x4: ArmStoreMemory::sthi_uop({{ Mem = Rhi; }},
+                                          {{ EA = Rn + disp; }},
+                                             inst_flags = [IsMicroop]);
+            0x5: ArmStoreMemory::stlo_uop({{ Mem = Rlo; }},
+                                          {{ EA = Rn + disp; }},
+                                             inst_flags = [IsMicroop]);
+        }
+        default: Unknown::unknown(); // TODO: Ignore other NV space for now
+    }
+    format BasicOp{
+    default: decode OPCODE_27_25 {
+        0x0: decode OPCODE_4 {
+            0: decode S_FIELD {
+                0: decode OPCODE_24_21 {
+                    format PredIntOp {
+                    0x0: and({{ Rd = Rn & Rm_Imm; }});
+                    0x1: eor({{ Rd = Rn ^ Rm_Imm; }});
+                    0x2: sub({{ Rd = Rn - Rm_Imm; }});
+                    0x3: rsb({{ Rd = Rm_Imm - Rn; }});
+                    0x4: add({{ Rd = Rn + Rm_Imm; }});
+                    0x5: adc({{ Rd = Rn + Rm_Imm + Cpsr<29:>; }});
+                    0x6: sbc({{ Rd = Rn - Rm_Imm + Cpsr<29:> - 1; }});
+                    0x7: rsc({{ Rd = Rm_Imm - Rn + Cpsr<29:> - 1; }});
+                    //0x8:mrs_cpsr -- TODO
+                    //0x9:msr_cpsr -- TODO
+                    //0xa:mrs_spsr -- TODO
+                    //0xb:msr_spsr -- TODO
+                    0xc: orr({{ Rd = Rn | Rm_Imm; }});
+                    0xd: mov({{ Rd = Rm_Imm; }});
+                    0xe: bic({{ Rd = Rn & ~Rm_Imm; }});
+                    0xf: mvn({{ Rd = ~Rm_Imm; }});
+                    }
+                }
+                1: decode OPCODE_24_21 {
+                    format PredIntOpCc {
+                    0x0: ands({{
+                        uint32_t resTemp;
+                        Rd = resTemp = Rn & Rm_Imm;
+                        }},
+                        {{ shift_carry_imm(Rm, shift_size, shift, Cpsr<29:>) }},
+                        {{ Cpsr<28:> }});
+                    0x1: eors({{
+                        uint32_t resTemp;
+                        Rd = resTemp = Rn ^ Rm_Imm;
+                        }},
+                        {{ shift_carry_imm(Rm, shift_size, shift, Cpsr<29:>) }},
+                        {{ Cpsr<28:> }});
+                    0x2: subs({{
+                        uint32_t resTemp,
+                            val2 = Rm_Imm;
+                        Rd = resTemp = Rn - val2;
+                        }},
+                        {{ arm_sub_carry(resTemp, Rn, val2) }},
+                        {{ arm_sub_overflow(resTemp, Rn, val2) }});
+                    0x3: rsbs({{
+                        uint32_t resTemp,
+                            val2 = Rm_Imm;
+                        Rd = resTemp = val2 - Rn;
+                        }},
+                        {{ arm_sub_carry(resTemp, val2, Rn) }},
+                        {{ arm_sub_overflow(resTemp, val2, Rn) }});
+                    0x4: adds({{
+                        uint32_t resTemp,
+                            val2 = Rm_Imm;
+                        Rd = resTemp = Rn + val2;
+                        }},
+                        {{ arm_add_carry(resTemp, Rn, val2) }},
+                        {{ arm_add_overflow(resTemp, Rn, val2) }});
+                    0x5: adcs({{
+                        uint32_t resTemp,
+                            val2 = Rm_Imm;
+                        Rd = resTemp = Rn + val2 + Cpsr<29:>;
+                        }},
+                        {{ arm_add_carry(resTemp, Rn, val2) }},
+                        {{ arm_add_overflow(resTemp, Rn, val2) }});
+                    0x6: sbcs({{
+                        uint32_t resTemp,
+                            val2 = Rm_Imm;
+                        Rd = resTemp = Rn - val2 + Cpsr<29:> - 1;
+                        }},
+                        {{ arm_sub_carry(resTemp, Rn, val2) }},
+                        {{ arm_sub_overflow(resTemp, Rn, val2) }});
+                    0x7: rscs({{
+                        uint32_t resTemp,
+                            val2 = Rm_Imm;
+                        Rd = resTemp = val2 - Rn + Cpsr<29:> - 1;
+                        }},
+                        {{ arm_sub_carry(resTemp, val2, Rn) }},
+                        {{ arm_sub_overflow(resTemp, val2, Rn) }});
+                    0x8: tst({{
+                        uint32_t resTemp;
+                        resTemp = Rn & Rm_Imm;
+                        }},
+                        {{ shift_carry_imm(Rm, shift_size, shift, Cpsr<29:>) }},
+                        {{ Cpsr<28:> }});
+                    0x9: teq({{
+                        uint32_t resTemp;
+                        resTemp = Rn ^ Rm_Imm;
+                        }},
+                        {{ shift_carry_imm(Rm, shift_size, shift, Cpsr<29:>) }},
+                        {{ Cpsr<28:> }});
+                    0xa: cmp({{
+                        uint32_t resTemp,
+                            val2 = Rm_Imm;
+                        resTemp = Rn - val2;
+                        }},
+                        {{ arm_sub_carry(resTemp, Rn, val2) }},
+                        {{ arm_sub_overflow(resTemp, Rn, val2) }});
+                    0xb: cmn({{
+                        uint32_t resTemp,
+                            val2 = Rm_Imm;
+                        resTemp = Rn + val2;
+                        }},
+                        {{ arm_add_carry(resTemp, Rn, val2) }},
+                        {{ arm_add_overflow(resTemp, Rn, val2) }});
+                    0xc: orrs({{
+                        uint32_t resTemp,
+                            val2 = Rm_Imm;
+                        Rd = resTemp = Rn | val2;
+                        }},
+                        {{ shift_carry_imm(Rm, shift_size, shift, Cpsr<29:>) }},
+                        {{ Cpsr<28:> }});
+                    0xd: movs({{
+                        uint32_t resTemp;
+                        Rd = resTemp = Rm_Imm;
+                        }},
+                        {{ shift_carry_imm(Rm, shift_size, shift, Cpsr<29:>) }},
+                        {{ Cpsr<28:> }});
+                    0xe: bics({{
+                        uint32_t resTemp;
+                        Rd = resTemp = Rn & ~Rm_Imm;
+                        }},
+                        {{ shift_carry_imm(Rm, shift_size, shift, Cpsr<29:>) }},
+                        {{ Cpsr<28:> }});
+                    0xf: mvns({{
+                        uint32_t resTemp;
+                        Rd = resTemp = ~Rm_Imm;
+                        }},
+                        {{ shift_carry_imm(Rm, shift_size, shift, Cpsr<29:>) }},
+                        {{ Cpsr<28:> }});
+                    }
+                }
+            }
+            1: decode OPCODE_7 {
+                0: decode S_FIELD {
+                    0: decode OPCODE_24_21 {
+                        format PredIntOp {
+                        0x0: and_rs({{ Rd = Rn & Rm_Rs; }});
+                        0x1: eor_rs({{ Rd = Rn ^ Rm_Rs; }});
+                        0x2: sub_rs({{ Rd = Rn - Rm_Rs; }});
+                        0x3: rsb_rs({{ Rd = Rm_Rs - Rn; }});
+                        0x4: add_rs({{ Rd = Rn + Rm_Rs; }});
+                        0x5: adc_rs({{ Rd = Rn + Rm_Rs + Cpsr<29:>; }});
+                        0x6: sbc_rs({{ Rd = Rn - Rm_Rs + Cpsr<29:> - 1; }});
+                        0x7: rsc_rs({{ Rd = Rm_Rs - Rn + Cpsr<29:> - 1; }});
+                        0xc: orr_rs({{ Rd = Rn | Rm_Rs; }});
+                        0xd: mov_rs({{ Rd = Rm_Rs; }});
+                        0xe: bic_rs({{ Rd = Rn & ~Rm_Rs; }});
+                        0xf: mvn_rs({{ Rd = ~Rm_Rs; }});
+                        default: decode OPCODE_7_4 {
+                            0x1: decode OPCODE_24_21 {
+                                0x9: BranchExchange::bx({{ }});
+                                0xb: PredOp::clz({{
+                                    if (Rm == 0)
+                                        Rd = 32;
+                                    else
+                                    {
+                                        int i;
+                                        for (i = 0; i < 32; i++)
+                                        {
+                                            if (Rm & (1<<(31-i)))
+                                            break;
+                                        }
+                                        Rd = i;
+                                    }
+                                }});
+                            }
+                            0x3: decode OPCODE_24_21 {
+                                0x9: BranchExchange::blx({{ LR = NPC; }});
+                            }
+                        }
+                        }
+                    }
+                    1: decode OPCODE_24_21 {
+                        format PredIntOpCc {
+                        0x0: ands_rs({{
+                            uint32_t resTemp;
+                            Rd = resTemp = Rn & Rm_Rs;
+                            }},
+                            {{ shift_carry_rs(Rm, Rs, shift, Cpsr<29:>) }},
+                            {{ Cpsr<28:> }});
+                        0x1: eors_rs({{
+                            uint32_t resTemp;
+                            Rd = resTemp = Rn ^ Rm_Rs;
+                            }},
+                            {{ shift_carry_rs(Rm, Rs, shift, Cpsr<29:>) }},
+                            {{ Cpsr<28:> }});
+                        0x2: subs_rs({{
+                            uint32_t resTemp,
+                                val2 = Rm_Rs;
+                            Rd = resTemp = Rn - val2;
+                            }},
+                            {{ arm_sub_carry(resTemp, Rn, val2) }},
+                            {{ arm_sub_overflow(resTemp, Rn, val2) }});
+                        0x3: rsbs_rs({{
+                            uint32_t resTemp,
+                                val2 = Rm_Rs;
+                            Rd = resTemp = val2 - Rn;
+                            }},
+                            {{ arm_sub_carry(resTemp, val2, Rn) }},
+                            {{ arm_sub_overflow(resTemp, val2, Rn) }});
+                        0x4: adds_rs({{
+                            uint32_t resTemp,
+                                val2 = Rm_Rs;
+                            Rd = resTemp = Rn + val2;
+                            }},
+                            {{ arm_add_carry(resTemp, Rn, val2) }},
+                            {{ arm_add_overflow(resTemp, Rn, val2) }});
+                        0x5: adcs_rs({{
+                            uint32_t resTemp,
+                                val2 = Rm_Rs;
+                            Rd = resTemp = Rn + val2 + Cpsr<29:>;
+                            }},
+                            {{ arm_add_carry(resTemp, Rn, val2) }},
+                            {{ arm_add_overflow(resTemp, Rn, val2) }});
+                        0x6: sbcs_rs({{
+                            uint32_t resTemp,
+                                val2 = Rm_Rs;
+                            Rd = resTemp = Rn - val2 + Cpsr<29:> - 1;
+                            }},
+                            {{ arm_sub_carry(resTemp, Rn, val2) }},
+                            {{ arm_sub_overflow(resTemp, Rn, val2) }});
+                        0x7: rscs_rs({{
+                            uint32_t resTemp,
+                                val2 = Rm_Rs;
+                            Rd = resTemp = val2 - Rn + Cpsr<29:> - 1;
+                            }},
+                            {{ arm_sub_carry(resTemp, val2, Rn) }},
+                            {{ arm_sub_overflow(resTemp, val2, Rn) }});
+                        0x8: tst_rs({{
+                            uint32_t resTemp;
+                            resTemp = Rn & Rm_Rs;
+                            }},
+                            {{ shift_carry_rs(Rm, Rs, shift, Cpsr<29:>) }},
+                            {{ Cpsr<28:> }});
+                        0x9: teq_rs({{
+                            uint32_t resTemp;
+                            resTemp = Rn ^ Rm_Rs;
+                            }},
+                            {{ shift_carry_rs(Rm, Rs, shift, Cpsr<29:>) }},
+                            {{ Cpsr<28:> }});
+                        0xa: cmp_rs({{
+                            uint32_t resTemp,
+                                val2 = Rm_Rs;
+                            resTemp = Rn - val2;
+                            }},
+                            {{ arm_sub_carry(resTemp, Rn, val2) }},
+                            {{ arm_sub_overflow(resTemp, Rn, val2) }});
+                        0xb: cmn_rs({{
+                            uint32_t resTemp,
+                                val2 = Rm_Rs;
+                            resTemp = Rn + val2;
+                            }},
+                            {{ arm_add_carry(resTemp, Rn, val2) }},
+                            {{ arm_add_overflow(resTemp, Rn, val2) }});
+                        0xc: orrs_rs({{
+                            uint32_t resTemp,
+                                val2 = Rm_Rs;
+                            Rd = resTemp = Rn | val2;
+                            }},
+                            {{ shift_carry_rs(Rm, Rs, shift, Cpsr<29:>) }},
+                            {{ Cpsr<28:> }});
+                        0xd: movs_rs({{
+                            uint32_t resTemp;
+                            Rd = resTemp = Rm_Rs;
+                            }},
+                            {{ shift_carry_rs(Rm, Rs, shift, Cpsr<29:>) }},
+                            {{ Cpsr<28:> }});
+                        0xe: bics_rs({{
+                            uint32_t resTemp;
+                            Rd = resTemp = Rn & ~Rm_Rs;
+                            }},
+                            {{ shift_carry_rs(Rm, Rs, shift, Cpsr<29:>) }},
+                            {{ Cpsr<28:> }});
+                        0xf: mvns_rs({{
+                            uint32_t resTemp;
+                            Rd = resTemp = ~Rm_Rs;
+                            }},
+                            {{ shift_carry_rs(Rm, Rs, shift, Cpsr<29:>) }},
+                            {{ Cpsr<28:> }});
+                        }
+                    }
+                }
+                1: decode OPCODE_6_5 {
+                    0x0: decode OPCODE_24 {
+                        0: decode LUAS {
+                            format PredIntOp {
+                            0x0: mul({{ Rn = Rm * Rs; }});
+                            0x1: PredIntOpCc::muls({{
+                                uint32_t resTemp;
+                                Rn = resTemp = Rm * Rs;
+                                }},
+                                {{ Cpsr<29:> }},
+                                {{ Cpsr<28:> }});
+                            0x2: mla_a({{ Rn = Rm * Rs + Rd; }});
+                            0x8: umull_l({{
+                                uint64_t resTemp;
+                                resTemp = ((uint64_t)Rm)*((uint64_t)Rs);
+                                Rd = (uint32_t)(resTemp & 0xffffffff);
+                                Rn = (uint32_t)(resTemp >> 32);
+                            }});
+                            0xa: umlal_lu({{
+                                uint64_t resTemp;
+                                resTemp = ((uint64_t)Rm)*((uint64_t)Rs);
+                                resTemp += ((uint64_t)Rn << 32)+((uint64_t)Rd);
+                                Rd = (uint32_t)(resTemp & 0xffffffff);
+                                Rn = (uint32_t)(resTemp >> 32);
+                            }});
+                            0xc: smull_lu({{
+                                int64_t resTemp;
+                                resTemp = ((int64_t)Rm)*((int64_t)Rs);
+                                Rd = (int32_t)(resTemp & 0xffffffff);
+                                Rn = (int32_t)(resTemp >> 32);
+                            }});
+                            }
+                        }
+                    }
+                    0x1: decode PUIWL {
+                        0x04,0x0c: ArmStoreMemory::strh_i({{ Mem.uh = Rd.uh;
+                                                          Rn = Rn + hilo; }},
+                                                       {{ EA = Rn; }});
+                        0x05,0x0d: ArmLoadMemory::ldrh_il({{ Rd.uh = Mem.uh;
+                                                          Rn = Rn + hilo; }},
+                                                       {{ EA = Rn; }});
+                        0x10,0x18: ArmStoreMemory::strh_p({{ Mem.uh = Rd.uh; }},
+                                                        {{ EA = Rn + Rm; }});
+                        0x11,0x19: ArmLoadMemory::ldrh_pl({{ Rd.uh = Mem.uh; }},
+                                                        {{ EA = Rn + Rm; }});
+                        0x12,0x1a: ArmStoreMemory::strh_pw({{ Mem.uh = Rd.uh;
+                                                          Rn = Rn + Rm; }},
+                                                       {{ EA = Rn + Rm; }});
+                        0x13,0x1b: ArmLoadMemory::ldrh_pwl({{ Rd.uh = Mem.uh;
+                                                          Rn = Rn + Rm; }},
+                                                       {{ EA = Rn + Rm; }});
+                        0x14,0x1c: ArmStoreMemory::strh_pi({{ Mem.uh = Rd.uh; }},
+                                                        {{ EA = Rn + hilo; }});
+                        0x15,0x1d: ArmLoadMemory::ldrh_pil({{ Rd.uh = Mem.uh; }},
+                                                       {{ EA = Rn + hilo; }});
+                        0x16,0x1e: ArmStoreMemory::strh_piw({{ Mem.uh = Rd.uh;
+                                                           Rn = Rn + hilo; }},
+                                                        {{ EA = Rn + hilo; }});
+                        0x17,0x1f: ArmLoadMemory::ldrh_piwl({{ Rd.uh = Mem.uh;
+                                                           Rn = Rn + hilo; }},
+                                                        {{ EA = Rn + hilo; }});
+                    }
+                    0x2: decode PUIWL {
+                        format ArmLoadMemory {
+                            0x11,0x19: ldrsb_pl({{ Rd.sb = Mem.sb; }},
+                                                {{ EA = Rn + Rm; }});
+                            0x13,0x1b: ldrsb_pwl({{ Rd.sb = Mem.sb;
+                                                    Rn = Rn + Rm; }},
+                                                 {{ EA = Rn + Rm; }});
+                            0x15,0x1d: ldrsb_pil({{ Rd.sb = Mem.sb; }},
+                                                 {{ EA = Rn + hilo; }});
+                            0x17,0x1f: ldrsb_piwl({{ Rd.sb = Mem.sb;
+                                                     Rn = Rn + hilo; }},
+                                                  {{ EA = Rn + hilo; }});
+                        }
+                    }
+                    0x3: decode PUIWL {
+                        format ArmLoadMemory {
+                            0x11,0x19: ldrsh_pl({{ Rd.sh = Mem.sh; }},
+                                                {{ EA = Rn + Rm; }});
+                            0x13,0x1b: ldrsh_pwl({{ Rd.sh = Mem.sh;
+                                                    Rn = Rn + Rm; }},
+                                                 {{ EA = Rn + Rm; }});
+                            0x15,0x1d: ldrsh_pil({{ Rd.sh = Mem.sh; }},
+                                                 {{ EA = Rn + hilo; }});
+                            0x17,0x1f: ldrsh_piwl({{ Rd.sh = Mem.sh;
+                                                     Rn = Rn + hilo; }},
+                                                  {{ EA = Rn + hilo; }});
+                        }
+                    }
+                }
+            }
+        }
+        0x1: decode S_FIELD {
+            0: decode OPCODE_24_21 {
+                format PredImmOp {
+                    0x0: andi({{ Rd = Rn & rotated_imm; }});
+                    0x1: eori({{ Rd = Rn ^ rotated_imm; }});
+                    0x2: subi({{ Rd = Rn - rotated_imm; }});
+                    0x3: rsbi({{ Rd = rotated_imm - Rn; }});
+                    0x4: addi({{ Rd = Rn + rotated_imm; }});
+                    0x5: adci({{ Rd = Rn + rotated_imm + Cpsr<29:>; }});
+                    0x6: sbci({{ Rd = Rn - rotated_imm + Cpsr<29:> - 1; }});
+                    0x7: rsci({{ Rd = rotated_imm - Rn + Cpsr<29:> - 1; }});
+                    0xc: orri({{ Rd = Rn | rotated_imm; }});
+                    0xd: decode RN {
+                        0: movi({{ Rd = rotated_imm; }});
+                    }
+                    0xe: bici({{ Rd = Rn & ~rotated_imm; }});
+                    0xf: decode RN {
+                        0: mvni({{ Rd = ~rotated_imm; }});
+                    }
+                }
+            }
+            1: decode OPCODE_24_21 {
+                format PredImmOpCc {
+                    0x0: andsi({{
+                        uint32_t resTemp;
+                        Rd = resTemp = Rn & rotated_imm;
+                        }},
+                        {{ (rotate ? rotated_carry:Cpsr<29:>) }},
+                        {{ Cpsr<28:> }});
+                    0x1: eorsi({{
+                        uint32_t resTemp;
+                        Rd = resTemp = Rn ^ rotated_imm;
+                        }},
+                        {{ (rotate ? rotated_carry:Cpsr<29:>) }},
+                        {{ Cpsr<28:> }});
+                    0x2: subsi({{
+                        uint32_t resTemp;
+                        Rd = resTemp = Rn - rotated_imm;
+                        }},
+                        {{ arm_sub_carry(resTemp, Rn, rotated_imm) }},
+                        {{ arm_sub_overflow(resTemp, Rn, rotated_imm) }});
+                    0x3: rsbsi({{
+                        uint32_t resTemp;
+                        Rd = resTemp = rotated_imm - Rn;
+                        }},
+                        {{ arm_sub_carry(resTemp, rotated_imm, Rn) }},
+                        {{ arm_sub_overflow(resTemp, rotated_imm, Rn) }});
+                    0x4: addsi({{
+                        uint32_t resTemp;
+                        Rd = resTemp = Rn + rotated_imm;
+                        }},
+                        {{ arm_add_carry(resTemp, Rn, rotated_imm) }},
+                        {{ arm_add_overflow(resTemp, Rn, rotated_imm) }});
+                    0x5: adcsi({{
+                        uint32_t resTemp;
+                        Rd = resTemp = Rn + rotated_imm + Cpsr<29:>;
+                        }},
+                        {{ arm_add_carry(resTemp, Rn, rotated_imm) }},
+                        {{ arm_add_overflow(resTemp, Rn, rotated_imm) }});
+                    0x6: sbcsi({{
+                        uint32_t resTemp;
+                        Rd = resTemp = Rn -rotated_imm + Cpsr<29:> - 1;
+                        }},
+                        {{ arm_sub_carry(resTemp, Rn, rotated_imm) }},
+                        {{ arm_sub_overflow(resTemp, Rn, rotated_imm) }});
+                    0x7: rscsi({{
+                        uint32_t resTemp;
+                        Rd = resTemp = rotated_imm - Rn + Cpsr<29:> - 1;
+                        }},
+                        {{ arm_sub_carry(resTemp, rotated_imm, Rn) }},
+                        {{ arm_sub_overflow(resTemp, rotated_imm, Rn) }});
+                    0x8: tsti({{
+                        uint32_t resTemp;
+                        resTemp = Rn & rotated_imm;
+                        }},
+                        {{ (rotate ? rotated_carry:Cpsr<29:>) }},
+                        {{ Cpsr<28:> }});
+                    0x9: teqi({{
+                        uint32_t resTemp;
+                        resTemp = Rn ^ rotated_imm;
+                        }},
+                        {{ (rotate ? rotated_carry:Cpsr<29:>) }},
+                        {{ Cpsr<28:> }});
+                    0xa: cmpi({{
+                        uint32_t resTemp;
+                        resTemp = Rn - rotated_imm;
+                        }},
+                        {{ arm_sub_carry(resTemp, Rn, rotated_imm) }},
+                        {{ arm_sub_overflow(resTemp, Rn, rotated_imm) }});
+                    0xb: cmni({{
+                        uint32_t resTemp;
+                        resTemp = Rn + rotated_imm;
+                        }},
+                        {{ arm_add_carry(resTemp, Rn, rotated_imm) }},
+                        {{ arm_add_overflow(resTemp, Rn, rotated_imm) }});
+                    0xc: orrsi({{
+                        uint32_t resTemp;
+                        Rd = resTemp = Rn | rotated_imm;
+                        }},
+                        {{ (rotate ? rotated_carry:Cpsr<29:>) }},
+                        {{ Cpsr<28:> }});
+                    0xd: movsi({{
+                        uint32_t resTemp;
+                        Rd = resTemp = rotated_imm;
+                        }},
+                        {{ (rotate ? rotated_carry:Cpsr<29:>) }},
+                        {{ Cpsr<28:> }});
+                    0xe: bicsi({{
+                        uint32_t resTemp;
+                        Rd = resTemp = Rn & ~rotated_imm;
+                        }},
+                        {{ (rotate ? rotated_carry:Cpsr<29:>) }},
+                        {{ Cpsr<28:> }});
+                    0xf: mvnsi({{
+                        uint32_t resTemp;
+                        Rd = resTemp = ~rotated_imm;
+                        }},
+                        {{ (rotate ? rotated_carry:Cpsr<29:>) }},
+                        {{ Cpsr<28:> }});
+                }
+            }
+        }
+        0x2: decode PUBWL {
+            // CAREFUL:
+            // Can always do EA + disp, since we negate disp using the UP flag
+            // Post-indexed variants
+            0x00,0x08: ArmStoreMemory::str_({{ Mem = Rd;
+                                               Rn = Rn + disp; }},
+                                            {{ EA = Rn; }});
+            0x01,0x09: ArmLoadMemory::ldr_l({{ Rd = Mem;
+                                               Rn = Rn + disp; }},
+                                            {{ EA = Rn; }});
+            0x04,0x0c: ArmStoreMemory::strb_b({{ Mem.ub = Rd.ub;
+                                                 Rn = Rn + disp; }},
+                                              {{ EA = Rn; }});
+            0x05,0x0d: ArmLoadMemory::ldrb_bl({{ Rd.ub = Mem.ub;
+                                                 Rn = Rn + disp; }},
+                                              {{ EA = Rn; }});
+            // Pre-indexed variants
+            0x10,0x18: ArmStoreMemory::str_p({{ Mem = Rd; }});
+            0x11,0x19: ArmLoadMemory::ldr_pl({{ Rd = Mem; }});
+            0x12,0x1a: ArmStoreMemory::str_pw({{ Mem = Rd;
+                                                 Rn = Rn + disp; }});
+            0x13,0x1b: ArmLoadMemory::ldr_pwl({{ Rd = Mem;
+                                                 Rn = Rn + disp; }});
+            0x14,0x1c: ArmStoreMemory::strb_pb({{ Mem.ub = Rd.ub; }});
+            0x15,0x1d: ArmLoadMemory::ldrb_pbl({{ Rd.ub = Mem.ub; }});
+            0x16,0x1e: ArmStoreMemory::strb_pbw({{ Mem.ub = Rd.ub;
+                                                   Rn = Rn + disp; }});
+            0x17,0x1f: ArmLoadMemory::ldrb_pbwl({{ Rd.ub = Mem.ub;
+                                                   Rn = Rn + disp; }});
+        }
+        0x3: decode OPCODE_4 {
+            0: decode PUBWL {
+                0x00,0x08: ArmStoreMemory::strr_({{
+                        Mem = Rd;
+                        Rn = Rn + Rm_Imm; }},
+                     {{ EA = Rn; }});
+                0x01,0x09: ArmLoadMemory::ldrr_l({{
+                        Rd = Mem;
+                        Rn = Rn + Rm_Imm; }},
+                     {{ EA = Rn; }});
+                0x04,0x0c: ArmStoreMemory::strr_b({{
+                        Mem.ub = Rd.ub;
+                        Rn = Rn + Rm_Imm; }},
+                     {{ EA = Rn; }});
+                0x05,0x0d: ArmLoadMemory::ldrr_bl({{
+                        Rd.ub = Mem.ub;
+                        Rn = Rn + Rm_Imm; }},
+                     {{ EA = Rn; }});
+                0x10,0x18: ArmStoreMemory::strr_p({{
+                        Mem = Rd; }},
+                     {{ EA = Rn + Rm_Imm; }});
+                0x11,0x19: ArmLoadMemory::ldrr_pl({{
+                        Rd = Mem; }},
+                     {{ EA = Rn + Rm_Imm; }});
+                0x12,0x1a: ArmStoreMemory::strr_pw({{
+                        Mem = Rd;
+                        Rn = Rn + Rm_Imm; }},
+                     {{ EA = Rn + Rm_Imm; }});
+                0x13,0x1b: ArmLoadMemory::ldrr_pwl({{
+                        Rd = Mem;
+                        Rn = Rn + Rm_Imm; }},
+                     {{ EA = Rn + Rm_Imm; }});
+                0x14,0x1c: ArmStoreMemory::strr_pb({{
+                        Mem.ub = Rd.ub; }},
+                     {{ EA = Rn + Rm_Imm; }});
+                0x15,0x1d: ArmLoadMemory::ldrr_pbl({{
+                        Rd.ub = Mem.ub; }},
+                     {{ EA = Rn + Rm_Imm; }});
+                0x16,0x1e: ArmStoreMemory::strr_pbw({{
+                        Mem.ub = Rd.ub;
+                        Rn = Rn + Rm_Imm; }},
+                     {{ EA = Rn + Rm_Imm; }});
+                0x17,0x1f: ArmLoadMemory::ldrr_pbwl({{
+                        Rd.ub = Mem.ub;
+                        Rn = Rn + Rm_Imm; }},
+                     {{ EA = Rn + Rm_Imm; }});
+            }
+        }
+        0x4: decode PUSWL {
+            // Right now we only handle cases when S (PSRUSER) is not set
+            default: ArmMacroStore::ldmstm({{ }});
+        }
+        0x5: decode OPCODE_24 {
+            // Branch (and Link) Instructions
+            0: Branch::b({{ }});
+            1: Branch::bl({{ LR = NPC; }});
+        }
+        0x6: decode CPNUM {
+            0x1: decode PUNWL {
+                0x02,0x0a: decode OPCODE_15 {
+                    0: ArmStoreMemory::stfs_({{ Mem.sf = Fd.sf;
+                                                Rn = Rn + disp8; }},
+                        {{ EA = Rn; }});
+                    1: ArmMacroFPAOp::stfd_({{ }});
+                }
+                0x03,0x0b: decode OPCODE_15 {
+                    0: ArmLoadMemory::ldfs_({{ Fd.sf = Mem.sf;
+                                               Rn = Rn + disp8; }},
+                        {{ EA = Rn; }});
+                    1: ArmMacroFPAOp::ldfd_({{ }});
+                }
+                0x06,0x0e: decode OPCODE_15 {
+                    0: ArmMacroFPAOp::stfe_nw({{ }});
+                }
+                0x07,0x0f: decode OPCODE_15 {
+                    0: ArmMacroFPAOp::ldfe_nw({{ }});
+                }
+                0x10,0x18: decode OPCODE_15 {
+                    0: ArmStoreMemory::stfs_p({{ Mem.sf = Fd.sf; }},
+                        {{ EA = Rn + disp8; }});
+                    1: ArmMacroFPAOp::stfd_p({{ }});
+                }
+                0x11,0x19: decode OPCODE_15 {
+                    0: ArmLoadMemory::ldfs_p({{ Fd.sf = Mem.sf; }},
+                        {{ EA = Rn + disp8; }});
+                    1: ArmMacroFPAOp::ldfd_p({{ }});
+                }
+                0x12,0x1a: decode OPCODE_15 {
+                    0: ArmStoreMemory::stfs_pw({{ Mem.sf = Fd.sf;
+                                                  Rn = Rn + disp8; }},
+                        {{ EA = Rn + disp8; }});
+                    1: ArmMacroFPAOp::stfd_pw({{ }});
+                }
+                0x13,0x1b: decode OPCODE_15 {
+                    0: ArmLoadMemory::ldfs_pw({{ Fd.sf = Mem.sf;
+                                                 Rn = Rn + disp8; }},
+                        {{ EA = Rn + disp8; }});
+                    1: ArmMacroFPAOp::ldfd_pw({{ }});
+                }
+                0x14,0x1c: decode OPCODE_15 {
+                    0: ArmMacroFPAOp::stfe_pn({{ }});
+                }
+                0x15,0x1d: decode OPCODE_15 {
+                    0: ArmMacroFPAOp::ldfe_pn({{ }});
+                }
+                0x16,0x1e: decode OPCODE_15 {
+                    0: ArmMacroFPAOp::stfe_pnw({{ }});
+                }
+                0x17,0x1f: decode OPCODE_15 {
+                    0: ArmMacroFPAOp::ldfe_pnw({{ }});
+                }
+            }
+            0x2: decode PUNWL {
+                // could really just decode as a single instruction
+                0x00,0x04,0x08,0x0c: ArmMacroFMOp::sfm_({{ }});
+                0x01,0x05,0x09,0x0d: ArmMacroFMOp::lfm_({{ }});
+                0x02,0x06,0x0a,0x0e: ArmMacroFMOp::sfm_w({{ }});
+                0x03,0x07,0x0b,0x0f: ArmMacroFMOp::lfm_w({{ }});
+                0x10,0x14,0x18,0x1c: ArmMacroFMOp::sfm_p({{ }});
+                0x11,0x15,0x19,0x1d: ArmMacroFMOp::lfm_p({{ }});
+                0x12,0x16,0x1a,0x1e: ArmMacroFMOp::sfm_pw({{ }});
+                0x13,0x17,0x1b,0x1f: ArmMacroFMOp::lfm_pw({{ }});
+            }
+        }
+        0x7: decode OPCODE_24 {
+            0: decode CPNUM {
+                // Coprocessor Instructions
+                0x1: decode OPCODE_4 {
+                    format FloatOp {
+                        // Basic FPA Instructions
+                        0: decode OPCODE_23_20 {
+                            0x0: decode OPCODE_15 {
+                                0: adf({{ Fd.sf = Fn.sf + Fm.sf; }});
+                                1: mvf({{ Fd.sf = Fm.sf; }});
+                            }
+                            0x1: decode OPCODE_15 {
+                                0: muf({{ Fd.sf = Fn.sf * Fm.sf; }});
+                                1: mnf({{ Fd.sf = -Fm.sf; }});
+                            }
+                            0x2: decode OPCODE_15 {
+                                0: suf({{ Fd.sf = Fn.sf - Fm.sf; }});
+                                1: abs({{ Fd.sf = fabs(Fm.sf); }});
+                            }
+                            0x3: decode OPCODE_15 {
+                                0: rsf({{ Fd.sf = Fm.sf - Fn.sf; }});
+                                1: rnd({{ Fd.sf = rint(Fm.sf); }});
+                            }
+                            0x4: decode OPCODE_15 {
+                                0: dvf({{ Fd.sf = Fn.sf / Fm.sf; }});
+                                1: sqt({{ Fd.sf = sqrt(Fm.sf); }});
+                            }
+                            0x5: decode OPCODE_15 {
+                                0: rdf({{ Fd.sf = Fm.sf / Fn.sf; }});
+                                1: log({{ Fd.sf = log10(Fm.sf); }});
+                            }
+                            0x6: decode OPCODE_15 {
+                                0: pow({{ Fd.sf = pow(Fm.sf, Fn.sf); }});
+                                1: lgn({{ Fd.sf = log(Fm.sf); }});
+                            }
+                            0x7: decode OPCODE_15 {
+                                0: rpw({{ Fd.sf = pow(Fn.sf, Fm.sf); }});
+                                1: exp({{ Fd.sf = exp(Fm.sf); }});
+                            }
+                            0x8: decode OPCODE_15 {
+                                0: rmf({{ Fd.sf = drem(Fn.sf, Fm.sf); }});
+                                1: sin({{ Fd.sf = sin(Fm.sf); }});
+                            }
+                            0x9: decode OPCODE_15 {
+                                0: fml({{ Fd.sf = Fn.sf * Fm.sf; }});
+                                1: cos({{ Fd.sf = cos(Fm.sf); }});
+                            }
+                            0xa: decode OPCODE_15 {
+                                0: fdv({{ Fd.sf = Fn.sf / Fm.sf; }});
+                                1: tan({{ Fd.sf = tan(Fm.sf); }});
+                            }
+                            0xb: decode OPCODE_15 {
+                                0: frd({{ Fd.sf = Fm.sf / Fn.sf; }});
+                                1: asn({{ Fd.sf = asin(Fm.sf); }});
+                            }
+                            0xc: decode OPCODE_15 {
+                                0: pol({{ Fd.sf = atan2(Fn.sf, Fm.sf); }});
+                                1: acs({{ Fd.sf = acos(Fm.sf); }});
+                            }
+                            0xd: decode OPCODE_15 {
+                                1: atn({{ Fd.sf = atan(Fm.sf); }});
+                            }
+                            0xe: decode OPCODE_15 {
+                                // Unnormalised Round
+                                1: FailUnimpl::urd();
+                            }
+                            0xf: decode OPCODE_15 {
+                                // Normalise
+                                1: FailUnimpl::nrm();
+                            }
+                        }
+                        1: decode OPCODE_15_12 {
+                            0xf: decode OPCODE_23_21 {
+                                format FloatCmp {
+                                    0x4: cmf({{ Fn.df }}, {{ Fm.df }});
+                                    0x5: cnf({{ Fn.df }}, {{ -Fm.df }});
+                                    0x6: cmfe({{ Fn.df }}, {{ Fm.df}});
+                                    0x7: cnfe({{ Fn.df }}, {{ -Fm.df}});
+                                }
+                            }
+                            default: decode OPCODE_23_20 {
+                                0x0: decode OPCODE_7 {
+                                    0: flts({{ Fn.sf = (float) Rd.sw; }});
+                                    1: fltd({{ Fn.df = (double) Rd.sw; }});
+                                }
+                                0x1: decode OPCODE_7 {
+                                    0: fixs({{ Rd = (uint32_t) Fm.sf; }});
+                                    1: fixd({{ Rd = (uint32_t) Fm.df; }});
+                                }
+                                0x2: wfs({{ Fpsr = Rd; }});
+                                0x3: rfs({{ Rd = Fpsr; }});
+                                0x4: FailUnimpl::wfc();
+                                0x5: FailUnimpl::rfc();
+                            }
+                        }
+                    }
+                }
+            }
+            format PredOp {
+                // ARM System Call (SoftWare Interrupt)
+                1: swi({{ if (arm_predicate(xc->readMiscReg(ArmISA::CPSR),
+                              condCode))
+                          {
+                              //xc->syscall(R7);
+                              xc->syscall(IMMED_23_0);
+                          }
+                }});
+            }
+        }
+    }
+    }
+}
+
diff --git a/src/arch/arm/isa/formats/basic.isa b/src/arch/arm/isa/formats/basic.isa
new file mode 100644 (file)
index 0000000..d154b98
--- /dev/null
@@ -0,0 +1,103 @@
+// -*- mode:c++ -*-
+
+// Copyright (c) 2007-2008 The Florida State University
+// 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
+
+// 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(MachInst machInst);
+                %(BasicExecDeclare)s
+        };
+}};
+
+// Basic instruction class constructor template.
+def template BasicConstructor {{
+        inline %(class_name)s::%(class_name)s(MachInst 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;
+
+                %(fp_enable_check)s;
+                %(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, 'ArmStaticInst', 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/arm/isa/formats/branch.isa b/src/arch/arm/isa/formats/branch.isa
new file mode 100644 (file)
index 0000000..40aa4a9
--- /dev/null
@@ -0,0 +1,307 @@
+// -*- mode:c++ -*-
+
+// Copyright (c) 2007-2008 The Florida State University
+// 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
+
+////////////////////////////////////////////////////////////////////
+//
+// Control transfer instructions
+//
+
+output header {{
+
+#include <iostream>
+
+    /**
+     * 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 PredOp
+    {
+      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, MachInst _machInst,
+                               OpClass __opClass)
+            : PredOp(mnem, _machInst, __opClass),
+              cachedPC(0), cachedSymtab(0)
+        {
+        }
+
+        const std::string &
+        disassemble(Addr pc, const SymbolTable *symtab) const;
+    };
+
+    /**
+     * Base class for branches (PC-relative control transfers),
+     * conditional or unconditional.
+     */
+    class Branch : public PCDependentDisassembly
+    {
+      protected:
+        /// target address (signed) Displacement .
+        int32_t disp;
+
+        /// Constructor.
+        Branch(const char *mnem, MachInst _machInst, OpClass __opClass)
+            : PCDependentDisassembly(mnem, _machInst, __opClass),
+              disp(OFFSET << 2)
+        {
+            //If Bit 26 is 1 then Sign Extend
+            if ( (disp & 0x02000000) > 0  ) {
+                disp |=  0xFC000000;
+            }
+        }
+
+        Addr branchTarget(Addr branchPC) const;
+
+        std::string
+        generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+    };
+
+    /**
+     * Base class for branch and exchange instructions on the ARM
+     */
+    class BranchExchange : public PredOp
+    {
+      protected:
+        /// Constructor
+        BranchExchange(const char *mnem, MachInst _machInst,
+                               OpClass __opClass)
+            : PredOp(mnem, _machInst, __opClass)
+        {
+        }
+
+        std::string
+        generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+    };
+
+
+    /**
+     * Base class for jumps (register-indirect control transfers).  In
+     * the Arm ISA, these are always unconditional.
+     */
+    class Jump : public PCDependentDisassembly
+    {
+      protected:
+
+        /// Displacement to target address (signed).
+        int32_t disp;
+
+        uint32_t target;
+
+      public:
+        /// Constructor
+        Jump(const char *mnem, MachInst _machInst, OpClass __opClass)
+            : PCDependentDisassembly(mnem, _machInst, __opClass),
+              disp(OFFSET << 2)
+        {
+        }
+
+        Addr branchTarget(ThreadContext *tc) const;
+
+        std::string
+        generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+    };
+}};
+
+output decoder {{
+    Addr
+    Branch::branchTarget(Addr branchPC) const
+    {
+        return branchPC + 8 + disp;
+    }
+
+    Addr
+    Jump::branchTarget(ThreadContext *tc) const
+    {
+        Addr NPC = tc->readPC() + 8;
+        uint64_t Rb = tc->readIntReg(_srcRegIdx[0]);
+        return (Rb & ~3) | (NPC & 1);
+    }
+
+    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;
+    }
+
+    std::string
+    Branch::generateDisassembly(Addr pc, const SymbolTable *symtab) const
+    {
+        std::stringstream ss;
+
+        ccprintf(ss, "%-10s ", mnemonic);
+
+        Addr target = pc + 8 + disp;
+
+        std::string str;
+        if (symtab && symtab->findSymbol(target, str))
+            ss << str;
+        else
+            ccprintf(ss, "0x%x", target);
+
+        return ss.str();
+    }
+
+    std::string
+    BranchExchange::generateDisassembly(Addr pc, const SymbolTable *symtab) const
+    {
+        std::stringstream ss;
+
+        ccprintf(ss, "%-10s ", mnemonic);
+
+        if (_numSrcRegs > 0) {
+            printReg(ss, _srcRegIdx[0]);
+        }
+
+        return ss.str();
+    }
+
+    std::string
+    Jump::generateDisassembly(Addr pc, const SymbolTable *symtab) const
+    {
+        std::stringstream ss;
+
+        ccprintf(ss, "%-10s ", mnemonic);
+
+        return ss.str();
+    }
+}};
+
+def format Branch(code,*opt_flags) {{
+
+    #Build Instruction Flags
+    #Use Link & Likely Flags to Add Link/Condition Code
+    inst_flags = ('IsDirectControl', )
+    for x in opt_flags:
+        if x == 'Link':
+            code += 'LR = NPC;\n'
+        else:
+            inst_flags += (x, )
+
+    #Take into account uncond. branch instruction
+    if 'cond == 1' in code:
+         inst_flags += ('IsUnCondControl', )
+    else:
+         inst_flags += ('IsCondControl', )
+
+    icode =  'if (arm_predicate(xc->readMiscReg(ArmISA::CPSR), condCode)) {\n'
+    icode += code
+    icode += '  NPC = NPC + 4 + disp;\n'
+    icode += '} else {\n'
+    icode += '  NPC = NPC;\n'
+    icode += '};\n'
+
+    code = icode
+
+    iop = InstObjParams(name, Name, 'Branch', code, inst_flags)
+    header_output = BasicDeclare.subst(iop)
+    decoder_output = BasicConstructor.subst(iop)
+    decode_block = BasicDecode.subst(iop)
+    exec_output = BasicExecute.subst(iop)
+}};
+
+def format BranchExchange(code,*opt_flags) {{
+    #Build Instruction Flags
+    #Use Link & Likely Flags to Add Link/Condition Code
+    inst_flags = ('IsIndirectControl', )
+    for x in opt_flags:
+        if x == 'Link':
+            code += 'LR = NPC;\n'
+        else:
+            inst_flags += (x, )
+
+    #Take into account uncond. branch instruction
+    if 'cond == 1' in code:
+         inst_flags += ('IsUnCondControl', )
+    else:
+         inst_flags += ('IsCondControl', )
+
+    #Condition code
+
+    icode =  'if (arm_predicate(xc->readMiscReg(ArmISA::CPSR), condCode)) {\n'
+    icode += code
+    icode += '  NPC = Rm & 0xfffffffe; // Masks off bottom bit\n'
+    icode += '} else {\n'
+    icode += '  NPC = NPC;\n'
+    icode += '};\n'
+
+    code = icode
+
+    iop = InstObjParams(name, Name, 'BranchExchange', code, inst_flags)
+    header_output = BasicDeclare.subst(iop)
+    decoder_output = BasicConstructor.subst(iop)
+    decode_block = BasicDecode.subst(iop)
+    exec_output = BasicExecute.subst(iop)
+}};
+
+def format Jump(code, *opt_flags) {{
+    #Build Instruction Flags
+    #Use Link Flag to Add Link Code
+    inst_flags = ('IsIndirectControl', 'IsUncondControl')
+    for x in opt_flags:
+        if x == 'Link':
+            code = 'LR = NPC;\n' + code
+        elif x == 'ClearHazards':
+            code += '/* Code Needed to Clear Execute & Inst Hazards */\n'
+        else:
+            inst_flags += (x, )
+
+    iop = InstObjParams(name, Name, 'Jump', code, inst_flags)
+    header_output = BasicDeclare.subst(iop)
+    decoder_output = BasicConstructor.subst(iop)
+    decode_block = BasicDecode.subst(iop)
+    exec_output = BasicExecute.subst(iop)
+    #exec_output = PredOpExecute.subst(iop)
+}};
+
+
diff --git a/src/arch/arm/isa/formats/formats.isa b/src/arch/arm/isa/formats/formats.isa
new file mode 100644 (file)
index 0000000..5f6faa7
--- /dev/null
@@ -0,0 +1,57 @@
+// -*- mode:c++ -*-
+
+// Copyright (c) 2007-2008 The Florida State University
+// 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
+
+//Templates from this format are used later
+//Include the basic format
+##include "basic.isa"
+
+//Include support for predicated instructions
+##include "pred.isa"
+
+//Include utility functions
+##include "util.isa"
+
+//Include the float formats
+##include "fp.isa"
+
+//Include the mem format
+##include "mem.isa"
+
+//Include the macro-mem format
+##include "macromem.isa"
+
+//Include the branch format
+##include "branch.isa"
+
+//Include the unimplemented format
+##include "unimp.isa"
+
+//Include the unknown format
+##include "unknown.isa"
diff --git a/src/arch/arm/isa/formats/fp.isa b/src/arch/arm/isa/formats/fp.isa
new file mode 100644 (file)
index 0000000..682c760
--- /dev/null
@@ -0,0 +1,150 @@
+// -*- mode:c++ -*-
+
+// Copyright (c) 2007-2008 The Florida State University
+// 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
+
+////////////////////////////////////////////////////////////////////
+//
+// Floating Point operate instructions
+//
+
+output header {{
+
+        /**
+         * Base class for FP operations.
+         */
+        class FPAOp : public PredOp
+        {
+                protected:
+
+                /// Constructor
+                FPAOp(const char *mnem, MachInst _machInst, OpClass __opClass) : PredOp(mnem, _machInst, __opClass)
+                {
+                }
+
+            //std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+        };
+
+}};
+
+output exec {{
+}};
+
+def template FPAExecute {{
+        Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
+        {
+                Fault fault = NoFault;
+
+                %(fp_enable_check)s;
+
+                %(op_decl)s;
+                %(op_rd)s;
+
+                %(code)s;
+
+                if (arm_predicate(xc->readMiscReg(ArmISA::CPSR), condCode) &&
+                        fault == NoFault)
+                {
+                    %(op_wb)s;
+                }
+
+                return fault;
+        }
+}};
+
+def template FloatDoubleDecode {{
+    {
+        ArmStaticInst *i = NULL;
+        switch (OPCODE_19 << 1 | OPCODE_7)
+        {
+            case 0:
+                i = (ArmStaticInst *)new %(class_name)sS(machInst);
+                break;
+            case 1:
+                i = (ArmStaticInst *)new %(class_name)sD(machInst);
+                break;
+            case 2:
+            case 3:
+            default:
+                panic("Cannot decode float/double nature of the instruction");
+        }
+        return i;
+    }
+}};
+
+// Primary format for float point operate instructions:
+def format FloatOp(code, *flags) {{
+        orig_code = code
+
+        cblk = code
+        iop = InstObjParams(name, Name, 'FPAOp', cblk, flags)
+        header_output = BasicDeclare.subst(iop)
+        decoder_output = BasicConstructor.subst(iop)
+        exec_output = FPAExecute.subst(iop)
+
+        sng_cblk = code
+        sng_iop = InstObjParams(name, Name+'S', 'FPAOp', sng_cblk, flags)
+        header_output += BasicDeclare.subst(sng_iop)
+        decoder_output += BasicConstructor.subst(sng_iop)
+        exec_output += FPAExecute.subst(sng_iop)
+
+        dbl_code = re.sub(r'\.sf', '.df', orig_code)
+
+        dbl_cblk = dbl_code
+        dbl_iop = InstObjParams(name, Name+'D', 'FPAOp', dbl_cblk, flags)
+        header_output += BasicDeclare.subst(dbl_iop)
+        decoder_output += BasicConstructor.subst(dbl_iop)
+        exec_output += FPAExecute.subst(dbl_iop)
+
+        decode_block = FloatDoubleDecode.subst(iop)
+}};
+
+let {{
+        calcFPCcCode = '''
+        uint16_t _in, _iz, _ic, _iv;
+
+        _in = %(fReg1)s < %(fReg2)s;
+        _iz = %(fReg1)s == %(fReg2)s;
+        _ic = %(fReg1)s >= %(fReg2)s;
+        _iv = (isnan(%(fReg1)s) || isnan(%(fReg2)s)) & 1;
+
+        Cpsr = _in << 31 | _iz << 30 | _ic << 29 | _iv << 28 |
+            (Cpsr & 0x0FFFFFFF);
+        '''
+}};
+
+def format FloatCmp(fReg1, fReg2, *flags) {{
+        code = calcFPCcCode % vars()
+        iop = InstObjParams(name, Name, 'FPAOp', code, flags)
+        header_output = BasicDeclare.subst(iop)
+        decoder_output = BasicConstructor.subst(iop)
+        decode_block = BasicDecode.subst(iop)
+        exec_output = FPAExecute.subst(iop)
+}};
+
+
diff --git a/src/arch/arm/isa/formats/macromem.isa b/src/arch/arm/isa/formats/macromem.isa
new file mode 100644 (file)
index 0000000..bc055d7
--- /dev/null
@@ -0,0 +1,389 @@
+// -*- mode:c++ -*-
+
+// Copyright (c) 2007-2008 The Florida State University
+// 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
+
+////////////////////////////////////////////////////////////////////
+//
+// Macro Memory-format instructions
+//
+
+output header {{
+
+    /**
+     * Arm Macro Memory operations like LDM/STM
+     */
+    class ArmMacroMemoryOp : public PredMacroOp
+    {
+        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;
+
+        uint32_t reglist;
+        uint32_t ones;
+        uint32_t puswl,
+                 prepost,
+                 up,
+                 psruser,
+                 writeback,
+                 loadop;
+
+        ArmMacroMemoryOp(const char *mnem, MachInst _machInst, OpClass __opClass,
+                     StaticInstPtr _eaCompPtr = nullStaticInstPtr,
+                     StaticInstPtr _memAccPtr = nullStaticInstPtr)
+            : PredMacroOp(mnem, _machInst, __opClass),
+            memAccessFlags(0), eaCompPtr(_eaCompPtr), memAccPtr(_memAccPtr),
+            reglist(REGLIST), ones(0), puswl(PUSWL), prepost(PREPOST), up(UP),
+            psruser(PSRUSER), writeback(WRITEBACK), loadop(LOADOP)
+        {
+            ones = number_of_ones(reglist);
+            numMicroops = ones + writeback + 1;
+            // Remember that writeback adds a uop
+            microOps = new StaticInstPtr[numMicroops];
+        }
+    };
+
+    /**
+     * Arm Macro FPA operations to fix ldfd and stfd instructions
+     */
+    class ArmMacroFPAOp : public PredMacroOp
+    {
+        protected:
+        uint32_t puswl,
+                 prepost,
+                 up,
+                 psruser,
+                 writeback,
+                 loadop;
+        int32_t disp8;
+
+        ArmMacroFPAOp(const char *mnem, MachInst _machInst, OpClass __opClass)
+            : PredMacroOp(mnem, _machInst, __opClass),
+            puswl(PUSWL), prepost(PREPOST), up(UP),
+            psruser(PSRUSER), writeback(WRITEBACK), loadop(LOADOP),
+            disp8(IMMED_7_0 << 2)
+        {
+            numMicroops = 3 + writeback;
+            microOps = new StaticInstPtr[numMicroops];
+        }
+    };
+
+    /**
+     * Arm Macro FM operations to fix lfm and sfm
+     */
+    class ArmMacroFMOp : public PredMacroOp
+    {
+        protected:
+        uint32_t punwl,
+                 prepost,
+                 up,
+                 n1bit,
+                 writeback,
+                 loadop,
+                 n0bit,
+                 count;
+        int32_t disp8;
+
+        ArmMacroFMOp(const char *mnem, MachInst _machInst, OpClass __opClass)
+            : PredMacroOp(mnem, _machInst, __opClass),
+            punwl(PUNWL), prepost(PREPOST), up(UP),
+            n1bit(OPCODE_22), writeback(WRITEBACK), loadop(LOADOP),
+            n0bit(OPCODE_15), disp8(IMMED_7_0 << 2)
+        {
+            // Transfer 1-4 registers based on n1 and n0 bits (with 00 repr. 4)
+            count = (n1bit << 1) | n0bit;
+            if (count == 0)
+                count = 4;
+            numMicroops = (3*count) + writeback;
+            microOps = new StaticInstPtr[numMicroops];
+        }
+    };
+
+
+}};
+
+
+output decoder {{
+}};
+
+def template MacroStoreDeclare {{
+    /**
+     * Static instructions class for a store multiple instruction
+     */
+    class %(class_name)s : public %(base_class)s
+    {
+        public:
+            // Constructor
+            %(class_name)s(MachInst machInst);
+            %(BasicExecDeclare)s
+    };
+}};
+
+def template MacroStoreConstructor {{
+    inline %(class_name)s::%(class_name)s(MachInst machInst)
+        : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
+    {
+        %(constructor)s;
+        uint32_t regs_to_handle = reglist;
+        uint32_t j = 0,
+                 start_addr = 0,
+                 end_addr = 0;
+
+        switch (puswl)
+        {
+            case 0x01: //     L ldmda_l
+                start_addr = (ones << 2) - 4;
+                end_addr = 0;
+                break;
+            case 0x03: //    WL ldmda_wl
+                start_addr = (ones << 2) - 4;
+                end_addr = 0;
+                break;
+            case 0x08: //  U    stmia_u
+                start_addr = 0;
+                end_addr = (ones << 2) - 4;
+                break;
+            case 0x09: //  U  L ldmia_ul
+                start_addr = 0;
+                end_addr = (ones << 2) - 4;
+                break;
+            case 0x0b: //  U WL ldmia
+                start_addr = 0;
+                end_addr = (ones << 2) - 4;
+                break;
+            case 0x11: // P   L ldmdb
+                start_addr = (ones << 2); // U-bit is already 0 for subtract
+                end_addr = 4; // negative 4
+                break;
+            case 0x12: // P  W  stmdb
+                start_addr = (ones << 2); // U-bit is already 0 for subtract
+                end_addr = 4; // negative 4
+                break;
+            case 0x18: // PU    stmib
+                start_addr = 4;
+                end_addr = (ones << 2) + 4;
+                break;
+            case 0x19: // PU  L ldmib
+                start_addr = 4;
+                end_addr = (ones << 2) + 4;
+                break;
+            default:
+                panic("Unhandled Load/Store Multiple Instruction");
+                break;
+        }
+
+        //TODO - Add addi_uop/subi_uop here to create starting addresses
+        //Just using addi with 0 offset makes a "copy" of Rn for our use
+        uint32_t newMachInst = 0;
+        newMachInst = machInst & 0xffff0000;
+        microOps[0] = new Addi_uop(newMachInst);
+
+        for (int i = 1; i < ones+1; i++)
+        {
+            // Get next available bit for transfer
+            while (! ( regs_to_handle & (1<<j)))
+                j++;
+            regs_to_handle &= ~(1<<j);
+
+            microOps[i] = gen_ldrstr_uop(machInst, loadop, j, start_addr);
+
+            if (up)
+                start_addr += 4;
+            else
+                start_addr -= 4;
+        }
+
+        /* TODO: Take a look at how these 2 values should meet together
+        if (start_addr != (end_addr - 4))
+        {
+            fprintf(stderr, "start_addr: %d\n", start_addr);
+            fprintf(stderr, "end_addr:   %d\n", end_addr);
+            panic("start_addr does not meet end_addr");
+        }
+        */
+
+        if (writeback)
+        {
+            uint32_t newMachInst = machInst & 0xf0000000;
+            uint32_t rn = (machInst >> 16) & 0x0f;
+            // 3322 2222 2222 1111 1111 11
+            // 1098 7654 3210 9876 5432 1098 7654 3210
+            // COND 0010 0100 [RN] [RD] 0000 [  IMM  ]
+            // sub rn, rn, imm
+            newMachInst |= 0x02400000;
+            newMachInst |= ((rn << 16) | (rn << 12));
+            newMachInst |= (ones << 2);
+            if (up)
+            {
+                microOps[numMicroops-1] = new Addi_rd_uop(newMachInst);
+            }
+            else
+            {
+                microOps[numMicroops-1] = new Subi_rd_uop(newMachInst);
+            }
+        }
+        microOps[numMicroops-1]->setLastMicroop();
+    }
+
+}};
+
+def template MacroStoreExecute {{
+    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
+    {
+        Fault fault = NoFault;
+
+        %(fp_enable_check)s;
+        %(op_decl)s;
+        %(op_rd)s;
+        %(code)s;
+        if (fault == NoFault)
+        {
+            %(op_wb)s;
+        }
+
+        return fault;
+    }
+}};
+
+def template MacroFPAConstructor {{
+    inline %(class_name)s::%(class_name)s(MachInst machInst)
+        : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
+    {
+        %(constructor)s;
+
+        uint32_t start_addr = 0;
+
+        if (prepost)
+            start_addr = disp8;
+        else
+            start_addr = 0;
+
+        emit_ldfstf_uops(microOps, 0, machInst, loadop, up, start_addr);
+
+        if (writeback)
+        {
+            uint32_t newMachInst = machInst & 0xf0000000;
+            uint32_t rn = (machInst >> 16) & 0x0f;
+            // 3322 2222 2222 1111 1111 11
+            // 1098 7654 3210 9876 5432 1098 7654 3210
+            // COND 0010 0100 [RN] [RD] 0000 [  IMM  ]
+            // sub rn, rn, imm
+            newMachInst |= 0x02400000;
+            newMachInst |= ((rn << 16) | (rn << 12));
+            if (up)
+            {
+                newMachInst |= disp8;
+                microOps[numMicroops-1] = new Addi_rd_uop(newMachInst);
+            }
+            else
+            {
+                newMachInst |= disp8;
+                microOps[numMicroops-1] = new Subi_rd_uop(newMachInst);
+            }
+        }
+        microOps[numMicroops-1]->setLastMicroop();
+    }
+
+}};
+
+
+def template MacroFMConstructor {{
+    inline %(class_name)s::%(class_name)s(MachInst machInst)
+        : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
+    {
+        %(constructor)s;
+
+        uint32_t start_addr = 0;
+
+        if (prepost)
+            start_addr = disp8;
+        else
+            start_addr = 0;
+
+        for (int i = 0; i < count; i++)
+        {
+            emit_ldfstf_uops(microOps, 3*i, machInst, loadop, up, start_addr);
+        }
+
+        if (writeback)
+        {
+            uint32_t newMachInst = machInst & 0xf0000000;
+            uint32_t rn = (machInst >> 16) & 0x0f;
+            // 3322 2222 2222 1111 1111 11
+            // 1098 7654 3210 9876 5432 1098 7654 3210
+            // COND 0010 0100 [RN] [RD] 0000 [  IMM  ]
+            // sub rn, rn, imm
+            newMachInst |= 0x02400000;
+            newMachInst |= ((rn << 16) | (rn << 12));
+            if (up)
+            {
+                newMachInst |= disp8;
+                microOps[numMicroops-1] = new Addi_rd_uop(newMachInst);
+            }
+            else
+            {
+                newMachInst |= disp8;
+                microOps[numMicroops-1] = new Subi_rd_uop(newMachInst);
+            }
+        }
+        microOps[numMicroops-1]->setLastMicroop();
+    }
+
+}};
+
+
+def format ArmMacroStore(code, mem_flags = [], inst_flag = [], *opt_flags) {{
+    iop = InstObjParams(name, Name, 'ArmMacroMemoryOp', code, opt_flags)
+    header_output = MacroStoreDeclare.subst(iop)
+    decoder_output = MacroStoreConstructor.subst(iop)
+    decode_block = BasicDecode.subst(iop)
+    exec_output = MacroStoreExecute.subst(iop)
+}};
+
+def format ArmMacroFPAOp(code, mem_flags = [], inst_flag = [], *opt_flags) {{
+    iop = InstObjParams(name, Name, 'ArmMacroFPAOp', code, opt_flags)
+    header_output = BasicDeclare.subst(iop)
+    decoder_output = MacroFPAConstructor.subst(iop)
+    decode_block = BasicDecode.subst(iop)
+    exec_output = PredOpExecute.subst(iop)
+}};
+
+def format ArmMacroFMOp(code, mem_flags = [], inst_flag = [], *opt_flags) {{
+    iop = InstObjParams(name, Name, 'ArmMacroFMOp', code, opt_flags)
+    header_output = BasicDeclare.subst(iop)
+    decoder_output = MacroFMConstructor.subst(iop)
+    decode_block = BasicDecode.subst(iop)
+    exec_output = PredOpExecute.subst(iop)
+}};
+
+
+
diff --git a/src/arch/arm/isa/formats/mem.isa b/src/arch/arm/isa/formats/mem.isa
new file mode 100644 (file)
index 0000000..0c736f9
--- /dev/null
@@ -0,0 +1,593 @@
+// -*- mode:c++ -*-
+
+// Copyright (c) 2007-2008 The Florida State University
+// 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
+
+////////////////////////////////////////////////////////////////////
+//
+// Memory-format instructions
+//
+
+output header {{
+    /**
+     * Base class for general Arm memory-format instructions.
+     */
+    class Memory : public PredOp
+    {
+      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;
+
+        /// Displacement for EA calculation (signed).
+        int32_t disp;
+        int32_t disp8;
+        int32_t up;
+        int32_t hilo,
+                shift_size,
+                shift;
+
+        /// Constructor
+        Memory(const char *mnem, MachInst _machInst, OpClass __opClass,
+               StaticInstPtr _eaCompPtr = nullStaticInstPtr,
+               StaticInstPtr _memAccPtr = nullStaticInstPtr)
+            : PredOp(mnem, _machInst, __opClass),
+              memAccessFlags(0), eaCompPtr(_eaCompPtr), memAccPtr(_memAccPtr),
+              disp(IMMED_11_0), disp8(IMMED_7_0 << 2), up(UP),
+              hilo((IMMED_HI_11_8 << 4) | IMMED_LO_3_0),
+              shift_size(SHIFT_SIZE), shift(SHIFT)
+        {
+            // When Up is not set, then we must subtract by the displacement
+            if (!up)
+            {
+                disp = -disp;
+                disp8 = -disp8;
+                hilo = -hilo;
+            }
+        }
+
+        std::string
+        generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+
+      public:
+
+        const StaticInstPtr &eaCompInst() const { return eaCompPtr; }
+        const StaticInstPtr &memAccInst() const { return memAccPtr; }
+    };
+
+     /**
+     * Base class for a few miscellaneous memory-format insts
+     * that don't interpret the disp field
+     */
+    class MemoryNoDisp : public Memory
+    {
+      protected:
+        /// Constructor
+        MemoryNoDisp(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
+                     StaticInstPtr _eaCompPtr = nullStaticInstPtr,
+                     StaticInstPtr _memAccPtr = nullStaticInstPtr)
+            : Memory(mnem, _machInst, __opClass, _eaCompPtr, _memAccPtr)
+        {
+        }
+
+        std::string
+        generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+    };
+}};
+
+
+output decoder {{
+    std::string
+    Memory::generateDisassembly(Addr pc, const SymbolTable *symtab) const
+    {
+        return csprintf("%-10s", mnemonic);
+    }
+
+    std::string
+    MemoryNoDisp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
+    {
+        return csprintf("%-10s", mnemonic);
+    }
+}};
+
+def template LoadStoreDeclare {{
+    /**
+     * Static instruction class for "%(mnemonic)s".
+     */
+    class %(class_name)s : public %(base_class)s
+    {
+      protected:
+
+        /**
+         * "Fake" effective address computation class for "%(mnemonic)s".
+         */
+        class EAComp : public %(base_class)s
+        {
+          public:
+            /// Constructor
+            EAComp(MachInst machInst);
+
+            %(BasicExecDeclare)s
+        };
+
+        /**
+         * "Fake" memory access instruction class for "%(mnemonic)s".
+         */
+        class MemAcc : public %(base_class)s
+        {
+          public:
+            /// Constructor
+            MemAcc(MachInst machInst);
+
+            %(BasicExecDeclare)s
+        };
+
+      public:
+
+        /// Constructor.
+        %(class_name)s(MachInst 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 EACompConstructor {{
+    inline %(class_name)s::EAComp::EAComp(MachInst machInst)
+        : %(base_class)s("%(mnemonic)s (EAComp)", machInst, IntAluOp)
+    {
+        %(constructor)s;
+    }
+}};
+
+
+def template MemAccConstructor {{
+    inline %(class_name)s::MemAcc::MemAcc(MachInst machInst)
+        : %(base_class)s("%(mnemonic)s (MemAcc)", machInst, %(op_class)s)
+    {
+        %(constructor)s;
+    }
+}};
+
+
+def template LoadStoreConstructor {{
+    inline %(class_name)s::%(class_name)s(MachInst machInst)
+         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
+                          new EAComp(machInst), new MemAcc(machInst))
+    {
+        %(constructor)s;
+    }
+}};
+
+
+def template EACompExecute {{
+    Fault
+    %(class_name)s::EAComp::execute(%(CPU_exec_context)s *xc,
+                                   Trace::InstRecord *traceData) const
+    {
+        Addr EA;
+        Fault fault = NoFault;
+
+        %(fp_enable_check)s;
+        %(op_decl)s;
+        %(op_rd)s;
+        %(ea_code)s;
+
+        if (arm_predicate(xc->readMiscReg(ArmISA::CPSR), condCode))
+        {
+            if (fault == NoFault) {
+                %(op_wb)s;
+                xc->setEA(EA);
+            }
+        }
+
+        return fault;
+    }
+}};
+
+def template LoadMemAccExecute {{
+    Fault
+    %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc,
+                                   Trace::InstRecord *traceData) const
+    {
+        Addr EA;
+        Fault fault = NoFault;
+
+        %(fp_enable_check)s;
+        %(op_decl)s;
+        %(op_rd)s;
+        EA = xc->getEA();
+
+        if (arm_predicate(xc->readMiscReg(ArmISA::CPSR), condCode))
+        {
+            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 LoadExecute {{
+    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
+                                  Trace::InstRecord *traceData) const
+    {
+        Addr EA;
+        Fault fault = NoFault;
+
+        %(fp_enable_check)s;
+        %(op_decl)s;
+        %(op_rd)s;
+        %(ea_code)s;
+
+        if (arm_predicate(xc->readMiscReg(ArmISA::CPSR), condCode))
+        {
+            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;
+
+        %(fp_enable_check)s;
+        %(op_src_decl)s;
+        %(op_rd)s;
+        %(ea_code)s;
+
+        if (arm_predicate(xc->readMiscReg(ArmISA::CPSR), condCode))
+        {
+            if (fault == NoFault) {
+                fault = xc->read(EA, (uint%(mem_acc_size)d_t &)Mem, memAccessFlags);
+            }
+        }
+
+        return fault;
+    }
+}};
+
+
+def template LoadCompleteAcc {{
+    Fault %(class_name)s::completeAcc(PacketPtr pkt,
+                                      %(CPU_exec_context)s *xc,
+                                      Trace::InstRecord *traceData) const
+    {
+        Fault fault = NoFault;
+
+        %(fp_enable_check)s;
+        %(op_decl)s;
+        %(op_rd)s;
+
+        if (arm_predicate(xc->readMiscReg(ArmISA::CPSR), condCode))
+        {
+            // ARM instructions will not have a pkt if the predicate is false
+            Mem = pkt->get<typeof(Mem)>();
+
+            if (fault == NoFault) {
+                %(memacc_code)s;
+            }
+
+            if (fault == NoFault) {
+                %(op_wb)s;
+            }
+        }
+
+        return fault;
+    }
+}};
+
+
+def template StoreMemAccExecute {{
+    Fault
+    %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc,
+                                   Trace::InstRecord *traceData) const
+    {
+        Addr EA;
+        Fault fault = NoFault;
+
+        %(fp_enable_check)s;
+        %(op_decl)s;
+        %(op_rd)s;
+
+        if (arm_predicate(xc->readMiscReg(ArmISA::CPSR), condCode))
+        {
+            EA = xc->getEA();
+
+            if (fault == NoFault) {
+                %(postacc_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) {
+                %(postacc_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;
+
+        %(fp_enable_check)s;
+        %(op_decl)s;
+        %(op_rd)s;
+        %(ea_code)s;
+
+        if (arm_predicate(xc->readMiscReg(ArmISA::CPSR), condCode))
+        {
+            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) {
+                %(postacc_code)s;
+            }
+
+            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;
+
+        %(fp_enable_check)s;
+        %(op_decl)s;
+        %(op_rd)s;
+        %(ea_code)s;
+
+        if (arm_predicate(xc->readMiscReg(ArmISA::CPSR), condCode))
+        {
+            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;
+
+        %(fp_enable_check)s;
+        %(op_dest_decl)s;
+
+        if (arm_predicate(xc->readMiscReg(ArmISA::CPSR), condCode))
+        {
+            if (fault == NoFault) {
+                %(postacc_code)s;
+            }
+
+            if (fault == NoFault) {
+                %(op_wb)s;
+            }
+        }
+
+        return fault;
+    }
+}};
+
+def template StoreCondCompleteAcc {{
+    Fault %(class_name)s::completeAcc(PacketPtr pkt,
+                                      %(CPU_exec_context)s *xc,
+                                      Trace::InstRecord *traceData) const
+    {
+        Fault fault = NoFault;
+
+        %(fp_enable_check)s;
+        %(op_dest_decl)s;
+
+        if (arm_predicate(xc->readMiscReg(ArmISA::CPSR), condCode))
+        {
+            if (fault == NoFault) {
+                %(postacc_code)s;
+            }
+
+            if (fault == NoFault) {
+                %(op_wb)s;
+            }
+        }
+
+        return fault;
+    }
+}};
+
+
+def template MiscMemAccExecute {{
+    Fault %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc,
+                                          Trace::InstRecord *traceData) const
+    {
+        Addr EA;
+        Fault fault = NoFault;
+
+        %(fp_enable_check)s;
+        %(op_decl)s;
+        %(op_rd)s;
+
+        if (arm_predicate(xc->readMiscReg(ArmISA::CPSR), condCode))
+        {
+            EA = xc->getEA();
+
+            if (fault == NoFault) {
+                %(memacc_code)s;
+            }
+        }
+
+        return NoFault;
+    }
+}};
+
+def template MiscExecute {{
+    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
+                                  Trace::InstRecord *traceData) const
+    {
+        Addr EA;
+        Fault fault = NoFault;
+
+        %(fp_enable_check)s;
+        %(op_decl)s;
+        %(op_rd)s;
+        %(ea_code)s;
+
+        if (arm_predicate(xc->readMiscReg(ArmISA::CPSR), condCode))
+        {
+            if (fault == NoFault) {
+                %(memacc_code)s;
+            }
+        }
+
+        return NoFault;
+    }
+}};
+
+def template MiscInitiateAcc {{
+    Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
+                                      Trace::InstRecord *traceData) const
+    {
+        panic("Misc instruction does not support split access method!");
+        return NoFault;
+    }
+}};
+
+
+def template MiscCompleteAcc {{
+    Fault %(class_name)s::completeAcc(PacketPtr pkt,
+                                      %(CPU_exec_context)s *xc,
+                                      Trace::InstRecord *traceData) const
+    {
+        panic("Misc instruction does not support split access method!");
+
+        return NoFault;
+    }
+}};
+
+def format ArmLoadMemory(memacc_code, ea_code = {{ EA = Rn + disp; }},
+                     mem_flags = [], inst_flags = []) {{
+    ea_code = ArmGenericCodeSubs(ea_code)
+    memacc_code = ArmGenericCodeSubs(memacc_code)
+    (header_output, decoder_output, decode_block, exec_output) = \
+        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
+                      decode_template = BasicDecode,
+                      exec_template_base = 'Load')
+}};
+
+def format ArmStoreMemory(memacc_code, ea_code = {{ EA = Rn + disp; }},
+                     mem_flags = [], inst_flags = []) {{
+    ea_code = ArmGenericCodeSubs(ea_code)
+    memacc_code = ArmGenericCodeSubs(memacc_code)
+    (header_output, decoder_output, decode_block, exec_output) = \
+        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
+                      exec_template_base = 'Store')
+}};
+
diff --git a/src/arch/arm/isa/formats/pred.isa b/src/arch/arm/isa/formats/pred.isa
new file mode 100644 (file)
index 0000000..1e9dba0
--- /dev/null
@@ -0,0 +1,402 @@
+// -*- mode:c++ -*-
+
+// Copyright (c) 2007-2008 The Florida State University
+// 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
+
+////////////////////////////////////////////////////////////////////
+//
+// Predicated Instruction Execution
+//
+
+output header {{
+#include <iostream>
+
+    enum ArmPredicateBits {
+        COND_EQ  =   0,
+        COND_NE, //  1
+        COND_CS, //  2
+        COND_CC, //  3
+        COND_MI, //  4
+        COND_PL, //  5
+        COND_VS, //  6
+        COND_VC, //  7
+        COND_HI, //  8
+        COND_LS, //  9
+        COND_GE, // 10
+        COND_LT, // 11
+        COND_GT, // 12
+        COND_LE, // 13
+        COND_AL, // 14
+        COND_NV  // 15
+    };
+
+    inline uint32_t
+    rotate_imm(uint32_t immValue, uint32_t rotateValue)
+    {
+        return ((immValue >> (int)(rotateValue & 31)) |
+                (immValue << (32 - (int)(rotateValue & 31))));
+    }
+
+    inline uint32_t nSet(uint32_t cpsr) { return cpsr & (1<<31); }
+    inline uint32_t zSet(uint32_t cpsr) { return cpsr & (1<<30); }
+    inline uint32_t cSet(uint32_t cpsr) { return cpsr & (1<<29); }
+    inline uint32_t vSet(uint32_t cpsr) { return cpsr & (1<<28); }
+
+    inline bool arm_predicate(uint32_t cpsr, uint32_t predBits)
+    {
+
+        enum ArmPredicateBits armPredBits = (enum ArmPredicateBits) predBits;
+        uint32_t result = 0;
+        switch (armPredBits)
+        {
+            case COND_EQ:
+                result = zSet(cpsr); break;
+            case COND_NE:
+                result = !zSet(cpsr); break;
+            case COND_CS:
+                result = cSet(cpsr); break;
+            case COND_CC:
+                result = !cSet(cpsr); break;
+            case COND_MI:
+                result = nSet(cpsr); break;
+            case COND_PL:
+                result = !nSet(cpsr); break;
+            case COND_VS:
+                result = vSet(cpsr); break;
+            case COND_VC:
+                result = !vSet(cpsr); break;
+            case COND_HI:
+                result = cSet(cpsr) && !zSet(cpsr); break;
+            case COND_LS:
+                result = !cSet(cpsr) || zSet(cpsr); break;
+            case COND_GE:
+                result = (!nSet(cpsr) && !vSet(cpsr)) || (nSet(cpsr) && vSet(cpsr)); break;
+            case COND_LT:
+                result = (nSet(cpsr) && !vSet(cpsr)) || (!nSet(cpsr) && vSet(cpsr)); break;
+            case COND_GT:
+                result = (!nSet(cpsr) && !vSet(cpsr) && !zSet(cpsr)) || (nSet(cpsr) && vSet(cpsr) && !zSet(cpsr)); break;
+            case COND_LE:
+                result = (nSet(cpsr) && !vSet(cpsr)) || (!nSet(cpsr) && vSet(cpsr)) || zSet(cpsr); break;
+            case COND_AL: result = 1; break;
+            case COND_NV: result = 0; break;
+            default:
+                fprintf(stderr, "Unhandled predicate condition: %d\n", armPredBits);
+                exit(1);
+        }
+        if (result)
+            return true;
+        else
+            return false;
+    }
+
+
+    /**
+     * Base class for predicated integer operations.
+     */
+    class PredOp : public ArmStaticInst
+    {
+            protected:
+
+            uint32_t condCode;
+
+            /// Constructor
+            PredOp(const char *mnem, MachInst _machInst, OpClass __opClass) :
+                            ArmStaticInst(mnem, _machInst, __opClass),
+                            condCode(COND_CODE)
+            {
+            }
+
+            std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+    };
+
+    /**
+     * Base class for predicated immediate operations.
+     */
+    class PredImmOp : public PredOp
+    {
+            protected:
+
+            uint32_t imm;
+            uint32_t rotate;
+            uint32_t rotated_imm;
+            uint32_t rotated_carry;
+
+            /// Constructor
+            PredImmOp(const char *mnem, MachInst _machInst, OpClass __opClass) :
+                            PredOp(mnem, _machInst, __opClass),
+                            imm(IMM), rotate(ROTATE << 1), rotated_imm(0),
+                            rotated_carry(0)
+            {
+                rotated_imm = rotate_imm(imm, rotate);
+                if (rotate != 0)
+                    rotated_carry = (rotated_imm >> 31) & 1;
+            }
+
+            std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+    };
+
+    /**
+     * Base class for predicated integer operations.
+     */
+    class PredIntOp : public PredOp
+    {
+            protected:
+
+            uint32_t shift_size;
+            uint32_t shift;
+
+            /// Constructor
+            PredIntOp(const char *mnem, MachInst _machInst, OpClass __opClass) :
+                            PredOp(mnem, _machInst, __opClass),
+                            shift_size(SHIFT_SIZE), shift(SHIFT)
+            {
+            }
+
+            std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+    };
+
+    /**
+     * Base class for predicated macro-operations.
+     */
+    class PredMacroOp : public PredOp
+    {
+            protected:
+
+            uint32_t numMicroops;
+            StaticInstPtr * microOps;
+
+            /// Constructor
+            PredMacroOp(const char *mnem, MachInst _machInst, OpClass __opClass) :
+                            PredOp(mnem, _machInst, __opClass),
+                            numMicroops(0)
+            {
+                // We rely on the subclasses of this object to handle the
+                // initialization of the micro-operations, since they are
+                // all of variable length
+                flags[IsMacroop] = true;
+            }
+
+            ~PredMacroOp()
+            {
+                if (numMicroops)
+                    delete [] microOps;
+            }
+
+            StaticInstPtr fetchMicroop(MicroPC microPC)
+            {
+                assert(microPC < numMicroops);
+                return microOps[microPC];
+            }
+
+            %(BasicExecPanic)s
+
+            std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+    };
+
+    /**
+     * Base class for predicated micro-operations.
+     */
+    class PredMicroop : public PredOp
+    {
+            /// Constructor
+            PredMicroop(const char *mnem, MachInst _machInst, OpClass __opClass) :
+                            PredOp(mnem, _machInst, __opClass)
+            {
+                flags[IsMicroop] = true;
+            }
+    };
+
+}};
+
+def template PredOpExecute {{
+    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
+    {
+        Fault fault = NoFault;
+
+        %(fp_enable_check)s;
+        %(op_decl)s;
+        %(op_rd)s;
+        %(code)s;
+
+        if (arm_predicate(xc->readMiscReg(ArmISA::CPSR), condCode))
+        {
+            if (fault == NoFault)
+            {
+                %(op_wb)s;
+            }
+        }
+        else
+            return NoFault;
+            // Predicated false instructions should not return faults
+
+        return fault;
+    }
+}};
+
+//Outputs to decoder.cc
+output decoder {{
+    std::string PredOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
+    {
+        std::stringstream ss;
+
+        ccprintf(ss, "%-10s ", mnemonic);
+
+        if (_numDestRegs > 0) {
+            printReg(ss, _destRegIdx[0]);
+        }
+
+        ss << ", ";
+
+        if (_numSrcRegs > 0) {
+            printReg(ss, _srcRegIdx[0]);
+            ss << ", ";
+        }
+
+        return ss.str();
+    }
+
+    std::string PredImmOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
+    {
+        std::stringstream ss;
+
+        ccprintf(ss, "%-10s ", mnemonic);
+
+        if (_numDestRegs > 0) {
+            printReg(ss, _destRegIdx[0]);
+        }
+
+        ss << ", ";
+
+        if (_numSrcRegs > 0) {
+            printReg(ss, _srcRegIdx[0]);
+            ss << ", ";
+        }
+
+        return ss.str();
+    }
+
+    std::string PredIntOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
+    {
+        std::stringstream ss;
+
+        ccprintf(ss, "%-10s ", mnemonic);
+
+        if (_numDestRegs > 0) {
+            printReg(ss, _destRegIdx[0]);
+        }
+
+        ss << ", ";
+
+        if (_numSrcRegs > 0) {
+            printReg(ss, _srcRegIdx[0]);
+            ss << ", ";
+        }
+
+        return ss.str();
+    }
+
+    std::string PredMacroOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
+    {
+        std::stringstream ss;
+
+        ccprintf(ss, "%-10s ", mnemonic);
+
+        return ss.str();
+    }
+
+}};
+
+let {{
+
+    calcCcCode = '''
+        uint16_t _ic, _iv, _iz, _in;
+
+        _in = (resTemp >> 31) & 1;
+        _iz = (resTemp == 0);
+        _iv = %(ivValue)s & 1;
+        _ic = %(icValue)s & 1;
+
+        Cpsr =  _in << 31 | _iz << 30 | _ic << 29 | _iv << 28 |
+            (Cpsr & 0x0FFFFFFF);
+
+        DPRINTF(Arm, "in = %%d\\n", _in);
+        DPRINTF(Arm, "iz = %%d\\n", _iz);
+        DPRINTF(Arm, "ic = %%d\\n", _ic);
+        DPRINTF(Arm, "iv = %%d\\n", _iv);
+        '''
+
+}};
+
+def format PredOp(code, *opt_flags) {{
+    iop = InstObjParams(name, Name, 'PredOp', code, opt_flags)
+    header_output = BasicDeclare.subst(iop)
+    decoder_output = BasicConstructor.subst(iop)
+    decode_block = BasicDecode.subst(iop)
+    exec_output = PredOpExecute.subst(iop)
+}};
+
+def format PredImmOp(code, *opt_flags) {{
+    iop = InstObjParams(name, Name, 'PredImmOp', code, opt_flags)
+    header_output = BasicDeclare.subst(iop)
+    decoder_output = BasicConstructor.subst(iop)
+    decode_block = BasicDecode.subst(iop)
+    exec_output = PredOpExecute.subst(iop)
+}};
+
+def format PredImmOpCc(code, icValue, ivValue, *opt_flags) {{
+    ccCode = calcCcCode % vars()
+    code += ccCode;
+    iop = InstObjParams(name, Name, 'PredImmOp',
+        {"code": code, "cc_code": ccCode}, opt_flags)
+    header_output = BasicDeclare.subst(iop)
+    decoder_output = BasicConstructor.subst(iop)
+    decode_block = BasicDecode.subst(iop)
+    exec_output = PredOpExecute.subst(iop)
+}};
+
+def format PredIntOp(code, *opt_flags) {{
+    new_code = ArmGenericCodeSubs(code)
+    iop = InstObjParams(name, Name, 'PredIntOp', new_code, opt_flags)
+    header_output = BasicDeclare.subst(iop)
+    decoder_output = BasicConstructor.subst(iop)
+    decode_block = BasicDecode.subst(iop)
+    exec_output = PredOpExecute.subst(iop)
+}};
+
+def format PredIntOpCc(code, icValue, ivValue, *opt_flags) {{
+    ccCode = calcCcCode % vars()
+    code += ccCode;
+    new_code = ArmGenericCodeSubs(code)
+    iop = InstObjParams(name, Name, 'PredIntOp',
+        {"code": new_code, "cc_code": ccCode }, opt_flags)
+    header_output = BasicDeclare.subst(iop)
+    decoder_output = BasicConstructor.subst(iop)
+    decode_block = BasicDecode.subst(iop)
+    exec_output = PredOpExecute.subst(iop)
+}};
+
diff --git a/src/arch/arm/isa/formats/unimp.isa b/src/arch/arm/isa/formats/unimp.isa
new file mode 100644 (file)
index 0000000..c82bb41
--- /dev/null
@@ -0,0 +1,144 @@
+// -*- mode:c++ -*-
+
+// Copyright (c) 2007-2008 The Florida State University
+// 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
+
+////////////////////////////////////////////////////////////////////
+//
+// 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 ArmStaticInst
+    {
+      public:
+        /// Constructor
+        FailUnimplemented(const char *_mnemonic, MachInst _machInst)
+            : ArmStaticInst(_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 ArmStaticInst
+    {
+      private:
+        /// Have we warned on this instruction yet?
+        mutable bool warned;
+
+      public:
+        /// Constructor
+        WarnUnimplemented(const char *_mnemonic, MachInst _machInst)
+            : ArmStaticInst(_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/arm/isa/formats/unknown.isa b/src/arch/arm/isa/formats/unknown.isa
new file mode 100644 (file)
index 0000000..3d13ef6
--- /dev/null
@@ -0,0 +1,84 @@
+// -*- mode:c++ -*-
+
+// Copyright (c) 2007-2008 The Florida State University
+// 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
+
+////////////////////////////////////////////////////////////////////
+//
+// 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 ArmStaticInst
+    {
+      public:
+        /// Constructor
+        Unknown(MachInst _machInst)
+            : ArmStaticInst("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 "
+              "(inst 0x%08x, opcode 0x%x, binary: %s)", machInst, OPCODE, inst2string(machInst));
+        return new UnimplementedOpcodeFault;
+    }
+}};
+
+def format Unknown() {{
+    decode_block = 'return new Unknown(machInst);\n'
+}};
+
diff --git a/src/arch/arm/isa/formats/util.isa b/src/arch/arm/isa/formats/util.isa
new file mode 100644 (file)
index 0000000..ee6339c
--- /dev/null
@@ -0,0 +1,217 @@
+// -*- mode:c++ -*-
+
+// Copyright (c) 2007-2008 The Florida State University
+// 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
+
+let {{
+
+# Generic substitutions for Arm instructions
+def ArmGenericCodeSubs(code):
+    # Substitute in the shifted portion of operations
+    new_code = re.sub(r'Rm_Imm', 'shift_rm_imm(Rm, shift_size, shift, Cpsr<29:>)', code)
+    new_code = re.sub(r'Rm_Rs', 'shift_rm_rs(Rm, Rs, shift, Cpsr<29:>)', new_code)
+    new_code = re.sub(r'^', 'Cpsr = Cpsr;', new_code)
+    return new_code
+
+def LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
+                  postacc_code = '', base_class = 'Memory',
+                  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'
+
+    # Some CPU models execute the memory operation as an atomic unit,
+    # while others want to separate them into an effective address
+    # computation and a memory access operation.  As a result, we need
+    # to generate three StaticInst objects.  Note that the latter two
+    # are nested inside the larger "atomic" one.
+
+    # Generate InstObjParams for each of the three objects.  Note that
+    # they differ only in the set of code objects contained (which in
+    # turn affects the object's overall operand list).
+    iop = InstObjParams(name, Name, base_class,
+                        { 'ea_code':ea_code, 'memacc_code':memacc_code, 'postacc_code':postacc_code },
+                        inst_flags)
+    ea_iop = InstObjParams(name, Name, base_class,
+                        { 'ea_code':ea_code },
+                        inst_flags)
+    memacc_iop = InstObjParams(name, Name, base_class,
+                        { 'memacc_code':memacc_code, 'postacc_code':postacc_code },
+                        inst_flags)
+
+    if mem_flags:
+        s = '\n\tmemAccessFlags = ' + string.join(mem_flags, '|') + ';'
+        iop.constructor += s
+        memacc_iop.constructor += s
+
+    # select templates
+
+    # The InitiateAcc template is the same for StoreCond templates as the
+    # corresponding Store template..
+    StoreCondInitiateAcc = StoreInitiateAcc
+
+    memAccExecTemplate = eval(exec_template_base + 'MemAccExecute')
+    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),
+            EACompConstructor.subst(ea_iop)
+            + MemAccConstructor.subst(memacc_iop)
+            + LoadStoreConstructor.subst(iop),
+            decode_template.subst(iop),
+            EACompExecute.subst(ea_iop)
+            + memAccExecTemplate.subst(memacc_iop)
+            + fullExecTemplate.subst(iop)
+            + initiateAccTemplate.subst(iop)
+            + completeAccTemplate.subst(iop))
+}};
+
+
+output header {{
+        std::string inst2string(MachInst machInst);
+        StaticInstPtr gen_ldrstr_uop(uint32_t baseinst, int loadop, uint32_t rd, int32_t disp);
+        int emit_ldfstf_uops(StaticInstPtr* microOps, int index, uint32_t baseinst, int loadop, int up, int32_t disp);
+}};
+
+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;
+    }
+
+    // Generate the bit pattern for an Ldr_uop or Str_uop;
+    StaticInstPtr
+    gen_ldrstr_uop(uint32_t baseinst, int loadop, uint32_t rd, int32_t disp)
+    {
+        StaticInstPtr newInst;
+        uint32_t newMachInst = baseinst & 0xffff0000;
+        newMachInst |= (rd << 12);
+        newMachInst |= disp;
+        if (loadop)
+            newInst = new Ldr_uop(newMachInst);
+        else
+            newInst = new Str_uop(newMachInst);
+        return newInst;
+    }
+
+    // Emits uops for a double fp move
+    int
+    emit_ldfstf_uops(StaticInstPtr* microOps, int index, uint32_t baseinst, int loadop, int up, int32_t disp)
+    {
+        StaticInstPtr newInst;
+        uint32_t newMachInst;
+
+        if (loadop)
+        {
+            newMachInst = baseinst & 0xfffff000;
+            newMachInst |= (disp & 0x0fff);
+            newInst = new Ldlo_uop(newMachInst);
+            microOps[index++] = newInst;
+
+            newMachInst = baseinst & 0xfffff000;
+            if (up)
+                newMachInst |= ((disp + 4) & 0x0fff);
+            else
+                newMachInst |= ((disp - 4) & 0x0fff);
+            newInst = new Ldhi_uop(newMachInst);
+            microOps[index++] = newInst;
+
+            newMachInst = baseinst & 0xf000f000;
+            newInst = new Mvtd_uop(newMachInst);
+            microOps[index++] = newInst;
+        }
+        else
+        {
+            newMachInst = baseinst & 0xf000f000;
+            newInst = new Mvfd_uop(newMachInst);
+            microOps[index++] = newInst;
+
+            newMachInst = baseinst & 0xfffff000;
+            newMachInst |= (disp & 0x0fff);
+            newInst = new Stlo_uop(newMachInst);
+            microOps[index++] = newInst;
+
+            newMachInst = baseinst & 0xfffff000;
+            if (up)
+                newMachInst |= ((disp + 4) & 0x0fff);
+            else
+                newMachInst |= ((disp - 4) & 0x0fff);
+            newInst = new Sthi_uop(newMachInst);
+            microOps[index++] = newInst;
+        }
+        return 3;
+    }
+
+}};
+
+output exec {{
+
+    using namespace ArmISA;
+
+    /// CLEAR ALL CPU INST/EXE HAZARDS
+    inline void
+    clear_exe_inst_hazards()
+    {
+        //CODE HERE
+    }
+
+#if FULL_SYSTEM
+    inline Fault checkFpEnableFault(%(CPU_exec_context)s *xc)
+    {
+        return NoFault;
+    }
+#else
+    inline Fault checkFpEnableFault(%(CPU_exec_context)s *xc)
+    {
+        return NoFault;
+    }
+#endif
+
+
+}};
+
+
diff --git a/src/arch/arm/isa/includes.isa b/src/arch/arm/isa/includes.isa
new file mode 100644 (file)
index 0000000..6205a8f
--- /dev/null
@@ -0,0 +1,82 @@
+// -*- mode:c++ -*-
+
+// Copyright (c) 2007-2008 The Florida State University
+// 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
+
+////////////////////////////////////////////////////////////////////
+//
+// Output include file directives.
+//
+
+output header {{
+#include <sstream>
+#include <iostream>
+#include <iomanip>
+
+#include "arch/arm/isa_traits.hh"
+#include "cpu/static_inst.hh"
+#include "mem/packet.hh"
+}};
+
+output decoder {{
+#include <cmath>
+#if defined(linux)
+#include <fenv.h>
+#endif
+
+#include "arch/arm/faults.hh"
+#include "arch/arm/isa_traits.hh"
+#include "arch/arm/utility.hh"
+#include "base/cprintf.hh"
+#include "base/loader/symtab.hh"
+#include "cpu/thread_context.hh"
+
+using namespace ArmISA;
+using std::isnan;
+}};
+
+output exec {{
+#include "arch/arm/faults.hh"
+#include "arch/arm/isa_traits.hh"
+#include "arch/arm/utility.hh"
+
+#include <cmath>
+#if defined(linux)
+#include <fenv.h>
+#endif
+
+#include "cpu/base.hh"
+#include "cpu/exetrace.hh"
+#include "mem/packet.hh"
+#include "mem/packet_access.hh"
+#include "sim/sim_exit.hh"
+
+using namespace ArmISA;
+using std::isnan;
+}};
+
diff --git a/src/arch/arm/isa/main.isa b/src/arch/arm/isa/main.isa
new file mode 100644 (file)
index 0000000..aeb8b69
--- /dev/null
@@ -0,0 +1,63 @@
+// -*- mode:c++ -*-
+
+// Copyright (c) 2007-2008 The Florida State University
+// 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
+
+////////////////////////////////////////////////////////////////////
+//
+// ARM ISA description file.
+//
+////////////////////////////////////////////////////////////////////
+
+//Include the C++ include directives
+##include "includes.isa"
+
+////////////////////////////////////////////////////////////////////
+//
+// Namespace statement.  Everything below this line will be in the
+// ArmISAInst namespace.
+//
+namespace ArmISA;
+
+//Include the utility functions
+##include "util.isa"
+
+//Include the bitfield definitions
+##include "bitfields.isa"
+
+//Include the operand_types and operand definitions
+##include "operands.isa"
+
+//Include the base class for Arm instructions, and some support code
+##include "base.isa"
+
+//Include the definitions for the instruction formats
+##include "formats/formats.isa"
+
+//Include the decoder definition
+##include "decoder.isa"
diff --git a/src/arch/arm/isa/operands.isa b/src/arch/arm/isa/operands.isa
new file mode 100644 (file)
index 0000000..b2c4f84
--- /dev/null
@@ -0,0 +1,72 @@
+// -*- mode:c++ -*-
+
+// Copyright (c) 2007-2008 The Florida State University
+// 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
+
+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),
+    'ud' : ('unsigned int', 64),
+    'sf' : ('float', 32),
+    'df' : ('float', 64)
+}};
+
+def operands {{
+    #General Purpose Integer Reg Operands
+    'Rd': ('IntReg', 'uw', 'RD', 'IsInteger', 1),
+    'Rm': ('IntReg', 'uw', 'RM', 'IsInteger', 2),
+    'Rs': ('IntReg', 'uw', 'RS', 'IsInteger', 3),
+    'Rn': ('IntReg', 'uw', 'RN', 'IsInteger', 4),
+    'Re': ('IntReg', 'uw', 'RE', 'IsInteger', 5),
+
+    'Raddr': ('IntReg', 'uw', '17', 'IsInteger', 5),
+    'R0': ('IntReg', 'uw', '0', 'IsInteger', 5),
+    'R7': ('IntReg', 'uw', '7', 'IsInteger', 5),
+    'Rhi': ('IntReg', 'uw', '18', 'IsInteger', 5),
+    'Rlo': ('IntReg', 'uw', '19', 'IsInteger', 6),
+    'LR': ('IntReg', 'uw', '14', 'IsInteger', 6),
+    'Ignore': ('IntReg', 'uw', '16', 'IsInteger', 99),
+
+    #General Purpose Floating Point Reg Operands
+    'Fd': ('FloatReg', 'df', 'FD', 'IsFloating', 1),
+    'Fn': ('FloatReg', 'df', 'FN', 'IsFloating', 2),
+    'Fm': ('FloatReg', 'df', 'FM', 'IsFloating', 3),
+
+    #Memory Operand
+    'Mem': ('Mem', 'uw', None, ('IsMemRef', 'IsLoad', 'IsStore'), 8),
+
+    'Cpsr': ('ControlReg', 'uw', 'CPSR', 'IsInteger', 7),
+    'Fpsr': ('ControlReg', 'uw', 'FPSR', 'IsInteger', 7),
+    'NPC': ('NPC', 'uw', None, (None, None, 'IsControl'), 9),
+    'NNPC': ('NNPC', 'uw', None, (None, None, 'IsControl'), 9),
+
+}};
diff --git a/src/arch/arm/isa/util.isa b/src/arch/arm/isa/util.isa
new file mode 100644 (file)
index 0000000..4fe0d73
--- /dev/null
@@ -0,0 +1,282 @@
+// -*- mode:c++ -*-
+
+// Copyright (c) 2007-2008 The Florida State University
+// 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
+
+////////////////////////////////////////////////////////////////////
+//
+// Utility functions for execute methods
+//
+//
+output header {{
+
+    // Shift types for ARM instructions
+    enum ArmShiftType {
+        LSL = 0,
+        LSR,
+        ASR,
+        ROR
+    };
+
+    enum ArmShiftMode {
+    };
+
+    inline uint32_t number_of_ones(int32_t val)
+    {
+        uint32_t ones = 0;
+        for (int i = 0; i < 32; i++ )
+        {
+            if ( val & (1<<i) )
+                ones++;
+        }
+        return ones;
+    }
+
+}};
+
+output exec {{
+
+    static int32_t arm_NEG(int32_t val) { return (val >> 31); }
+    static int32_t arm_POS(int32_t val) { return ((~val) >> 31); }
+
+    // Shift Rm by an immediate value
+    inline int32_t
+    shift_rm_imm(uint32_t base, uint32_t shamt, uint32_t type, uint32_t cfval)
+    {
+        enum ArmShiftType shiftType;
+        shiftType = (enum ArmShiftType) type;
+
+        switch (shiftType)
+        {
+            case LSL:
+                return (base << shamt);
+            case LSR:
+                if (shamt == 0)
+                    return (0);
+                else
+                    return (base >> shamt);
+            case ASR:
+                if (shamt == 0)
+                    return ((uint32_t) ((int32_t) base >> 31L));
+                else
+                    return ((uint32_t) (((int32_t) base) >> shamt));
+            case ROR:
+                //shamt = shamt & 0x1f;
+                if (shamt == 0)
+                    return (cfval << 31) | (base >> 1); // RRX
+                else
+                    return (base << (32 - shamt)) | (base >> shamt);
+            default:
+                fprintf(stderr, "Unhandled shift type\n");
+                exit(1);
+                break;
+        }
+        return 0;
+    }
+
+    // Shift Rm by Rs
+    inline int32_t
+    shift_rm_rs(uint32_t base, uint32_t shamt, uint32_t type, uint32_t cfval)
+    {
+        enum ArmShiftType shiftType;
+        shiftType = (enum ArmShiftType) type;
+
+        switch (shiftType)
+        {
+            case LSL:
+                if (shamt == 0)
+                    return (base);
+                else if (shamt >= 32)
+                    return (0);
+                else
+                    return (base << shamt);
+            case LSR:
+                if (shamt == 0)
+                    return (base);
+                else if (shamt >= 32)
+                    return (0);
+                else
+                    return (base >> shamt);
+            case ASR:
+                if (shamt == 0)
+                    return base;
+                else if (shamt >= 32)
+                    return ((uint32_t) ((int32_t) base >> 31L));
+                else
+                    return ((uint32_t) (((int32_t) base) >> (int) shamt));
+            case ROR:
+                shamt = shamt & 0x1f;
+                if (shamt == 0)
+                    return (base);
+                else
+                    return ((base << (32 - shamt)) | (base >> shamt));
+            default:
+                fprintf(stderr, "Unhandled shift type\n");
+                exit(1);
+                break;
+        }
+        return 0;
+    }
+
+
+    // Generate C for a shift by immediate
+    inline int32_t
+    shift_carry_imm(uint32_t base, uint32_t shamt, uint32_t type,
+        uint32_t cfval)
+    {
+        enum ArmShiftType shiftType;
+        shiftType = (enum ArmShiftType) type;
+
+        switch (shiftType)
+        {
+            case LSL:
+                return (base >> (32 - shamt)) & 1;
+            case LSR:
+                if (shamt == 0)
+                    return (base >> 31) & 1;
+                else
+                    return (base >> (shamt - 1)) & 1;
+            case ASR:
+                if (shamt == 0)
+                    return (base >> 31L);
+                else
+                    return ((uint32_t) (((int32_t) base) >> (shamt - 1))) & 1;
+            case ROR:
+                shamt = shamt & 0x1f;
+                if (shamt == 0)
+                    return (base & 1); // RRX
+                else
+                    return (base >> (shamt - 1)) & 1;
+            default:
+                fprintf(stderr, "Unhandled shift type\n");
+                exit(1);
+                break;
+
+        }
+        return 0;
+    }
+
+
+    // Generate C for a shift by Rs
+    inline int32_t
+    shift_carry_rs(uint32_t base, uint32_t shamt, uint32_t type, uint32_t cfval)
+    {
+        enum ArmShiftType shiftType;
+        shiftType = (enum ArmShiftType) type;
+
+        switch (shiftType)
+        {
+            case LSL:
+                if (shamt == 0)
+                    return (!!cfval);
+                else if (shamt == 32)
+                    return (base & 1);
+                else if (shamt > 32)
+                    return (0);
+                else
+                    return ((base >> (32 - shamt)) & 1);
+            case LSR:
+                if (shamt == 0)
+                    return (!!cfval);
+                else if (shamt == 32)
+                    return (base >> 31);
+                else if (shamt > 32)
+                    return (0);
+                else
+                    return ((base >> (shamt - 1)) & 1);
+            case ASR:
+                if (shamt == 0)
+                    return (!!cfval);
+                else if (shamt >= 32)
+                    return (base >> 31L);
+                else
+                    return (((uint32_t) (((int32_t) base) >> (shamt - 1))) & 1);
+            case ROR:
+                if (shamt == 0)
+                    return (!!cfval);
+                shamt = shamt & 0x1f;
+                if (shamt == 0)
+                    return (base >> 31); // RRX
+                else
+                    return ((base >> (shamt - 1)) & 1);
+            default:
+                fprintf(stderr, "Unhandled shift type\n");
+                exit(1);
+                break;
+
+        }
+        return 0;
+    }
+
+
+    // Generate the appropriate carry bit for an addition operation
+    inline int32_t
+    arm_add_carry(int32_t result, int32_t lhs, int32_t rhs)
+    {
+        if ((lhs | rhs) >> 30)
+            return ((arm_NEG(lhs) && arm_NEG(rhs)) ||
+                    (arm_NEG(lhs) && arm_POS(result)) ||
+                    (arm_NEG(rhs) && arm_POS(result)));
+        else
+            return 0;
+    }
+
+    // Generate the appropriate carry bit for a subtraction operation
+    inline int32_t
+    arm_sub_carry(int32_t result, int32_t lhs, int32_t rhs)
+    {
+        if ((lhs >= rhs) || ((rhs | lhs) >> 31))
+            return ((arm_NEG(lhs) && arm_POS(rhs)) ||
+                    (arm_NEG(lhs) && arm_POS(result)) ||
+                    (arm_POS(rhs) && arm_POS(result)));
+        else
+            return 0;
+    }
+
+    inline int32_t
+    arm_add_overflow(int32_t result, int32_t lhs, int32_t rhs)
+    {
+        if ((lhs | rhs) >> 30)
+            return ((arm_NEG(lhs) && arm_NEG(rhs) && arm_POS(result)) ||
+                    (arm_POS(lhs) && arm_POS(rhs) && arm_NEG(result)));
+        else
+            return 0;
+    }
+
+    inline int32_t
+    arm_sub_overflow(int32_t result, int32_t lhs, int32_t rhs)
+    {
+        if ((lhs >= rhs) || ((rhs | lhs) >> 31))
+            return ((arm_NEG(lhs) && arm_POS(rhs) && arm_POS(result)) ||
+                    (arm_POS(lhs) && arm_NEG(rhs) && arm_NEG(result)));
+        else
+            return 0;
+    }
+
+}};
+
diff --git a/src/arch/arm/isa_traits.hh b/src/arch/arm/isa_traits.hh
new file mode 100644 (file)
index 0000000..cf07699
--- /dev/null
@@ -0,0 +1,155 @@
+/*
+ * Copyright (c) 2003-2005 The Regents of The University of Michigan
+ * Copyright (c) 2007-2008 The Florida State University
+ * 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
+ */
+
+#ifndef __ARCH_ARM_ISA_TRAITS_HH__
+#define __ARCH_ARM_ISA_TRAITS_HH__
+
+#include "arch/arm/types.hh"
+#include "sim/host.hh"
+
+namespace LittleEndianGuest {};
+
+#define TARGET_ARM
+
+class StaticInstPtr;
+
+namespace ArmISA
+{
+    using namespace LittleEndianGuest;
+
+    StaticInstPtr decodeInst(ExtMachInst);
+
+    // ARM 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;
+
+
+    ////////////////////////////////////////////////////////////////////////
+    //
+    //  Translation stuff
+    //
+
+    const Addr PteShift = 3;
+    const Addr NPtePageShift = PageShift - PteShift;
+    const Addr NPtePage = ULL(1) << NPtePageShift;
+    const Addr PteMask = NPtePage - 1;
+
+    //// All 'Mapped' segments go through the TLB
+    //// All other segments are translated by dropping the MSB, to give
+    //// the corresponding physical address
+    // User Segment - Mapped
+    const Addr USegBase = ULL(0x0);
+    const Addr USegEnd = ULL(0x7FFFFFFF);
+
+    // Kernel Segment 0 - Unmapped
+    const Addr KSeg0End = ULL(0x9FFFFFFF);
+    const Addr KSeg0Base =  ULL(0x80000000);
+    const Addr KSeg0Mask = ULL(0x1FFFFFFF);
+
+    // For loading... XXX This maybe could be USegEnd?? --ali
+    const Addr LoadAddrMask = ULL(0xffffffffff);
+
+    const unsigned VABits = 32;
+    const unsigned PABits = 32; // Is this correct?
+    const Addr VAddrImplMask = (ULL(1) << VABits) - 1;
+    const Addr VAddrUnImplMask = ~VAddrImplMask;
+    inline Addr VAddrImpl(Addr a) { return a & VAddrImplMask; }
+    inline Addr VAddrVPN(Addr a) { return a >> ArmISA::PageShift; }
+    inline Addr VAddrOffset(Addr a) { return a & ArmISA::PageOffset; }
+
+    const Addr PAddrImplMask = (ULL(1) << PABits) - 1;
+
+    // return a no-op instruction... used for instruction fetch faults
+    const ExtMachInst NoopMachInst = 0x00000000;
+
+    // Constants Related to the number of registers
+    const int NumIntArchRegs = 16;
+    const int NumIntSpecialRegs = 19;
+    const int NumFloatArchRegs = 16;
+    const int NumFloatSpecialRegs = 5;
+    const int NumControlRegs = 7;
+    const int NumInternalProcRegs = 0;
+
+    const int NumIntRegs = NumIntArchRegs + NumIntSpecialRegs;
+    const int NumFloatRegs = NumFloatArchRegs + NumFloatSpecialRegs;
+    const int NumMiscRegs = NumControlRegs;
+
+    const int TotalNumRegs = NumIntRegs + NumFloatRegs + NumMiscRegs;
+
+    const int TotalDataRegs = NumIntRegs + NumFloatRegs;
+
+    // Static instruction parameters
+    const int MaxInstSrcRegs = 5;
+    const int MaxInstDestRegs = 3;
+
+    // semantically meaningful register indices
+    const int ReturnValueReg = 0;
+    const int ReturnValueReg1 = 1;
+    const int ReturnValueReg2 = 2;
+    const int ArgumentReg0 = 0;
+    const int ArgumentReg1 = 1;
+    const int ArgumentReg2 = 2;
+    const int ArgumentReg3 = 3;
+    const int FramePointerReg = 11;
+    const int StackPointerReg = 13;
+    const int ReturnAddressReg = 14;
+    const int PCReg = 15;
+
+    const int ZeroReg = NumIntArchRegs;
+    const int AddrReg = ZeroReg + 1; // Used to generate address for uops
+
+    const int SyscallNumReg = ReturnValueReg;
+    const int SyscallPseudoReturnReg = ReturnValueReg;
+    const int SyscallSuccessReg = ReturnValueReg;
+
+    const int LogVMPageSize = 12;      // 4K bytes
+    const int VMPageSize = (1 << LogVMPageSize);
+
+    const int BranchPredAddrShiftAmt = 2; // instructions are 4-byte aligned
+
+    const int MachineBytes = 4;
+    const int WordBytes = 4;
+    const int HalfwordBytes = 2;
+    const int ByteBytes = 1;
+
+    // These help enumerate all the registers for dependence tracking.
+    const int FP_Base_DepTag = NumIntRegs;
+    const int Ctrl_Base_DepTag = FP_Base_DepTag + NumFloatRegs;
+};
+
+using namespace ArmISA;
+
+#endif // __ARCH_ARM_ISA_TRAITS_HH__
diff --git a/src/arch/arm/linux/linux.cc b/src/arch/arm/linux/linux.cc
new file mode 100644 (file)
index 0000000..a4c7824
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2003-2005 The Regents of The University of Michigan
+ * Copyright (c) 2007-2008 The Florida State University
+ * 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
+ */
+
+#include "arch/arm/linux/linux.hh"
+
+#include <fcntl.h>
+
+// open(2) flags translation table
+OpenFlagTransTable ArmLinux::openFlagTable[] = {
+#ifdef _MSC_VER
+  { ArmLinux::TGT_O_RDONLY,    _O_RDONLY },
+  { ArmLinux::TGT_O_WRONLY,    _O_WRONLY },
+  { ArmLinux::TGT_O_RDWR,      _O_RDWR },
+  { ArmLinux::TGT_O_APPEND,    _O_APPEND },
+  { ArmLinux::TGT_O_CREAT,     _O_CREAT },
+  { ArmLinux::TGT_O_TRUNC,     _O_TRUNC },
+  { ArmLinux::TGT_O_EXCL,      _O_EXCL },
+#ifdef _O_NONBLOCK
+  { ArmLinux::TGT_O_NONBLOCK,  _O_NONBLOCK },
+#endif
+#ifdef _O_NOCTTY
+  { ArmLinux::TGT_O_NOCTTY,    _O_NOCTTY },
+#endif
+#ifdef _O_SYNC
+  { ArmLinux::TGT_O_SYNC,      _O_SYNC },
+#endif
+#else /* !_MSC_VER */
+  { ArmLinux::TGT_O_RDONLY,    O_RDONLY },
+  { ArmLinux::TGT_O_WRONLY,    O_WRONLY },
+  { ArmLinux::TGT_O_RDWR,      O_RDWR },
+  { ArmLinux::TGT_O_APPEND,    O_APPEND },
+  { ArmLinux::TGT_O_CREAT,     O_CREAT },
+  { ArmLinux::TGT_O_TRUNC,     O_TRUNC },
+  { ArmLinux::TGT_O_EXCL,      O_EXCL },
+  { ArmLinux::TGT_O_NONBLOCK,  O_NONBLOCK },
+  { ArmLinux::TGT_O_NOCTTY,    O_NOCTTY },
+#ifdef O_SYNC
+  { ArmLinux::TGT_O_SYNC,      O_SYNC },
+#endif
+#endif /* _MSC_VER */
+};
+
+const int ArmLinux::NUM_OPEN_FLAGS =
+        (sizeof(ArmLinux::openFlagTable)/sizeof(ArmLinux::openFlagTable[0]));
+
diff --git a/src/arch/arm/linux/linux.hh b/src/arch/arm/linux/linux.hh
new file mode 100644 (file)
index 0000000..e054576
--- /dev/null
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 2003-2005 The Regents of The University of Michigan
+ * Copyright (c) 2007-2008 The Florida State University
+ * 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
+ */
+
+#ifndef __ARCH_ARM_LINUX_LINUX_HH__
+#define __ARCH_ARM_LINUX_LINUX_HH__
+
+#include "kern/linux/linux.hh"
+
+class ArmLinux : public Linux
+{
+  public:
+
+    /// 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      = 0x00000000;   //!< O_RDONLY
+    static const int TGT_O_WRONLY      = 0x00000001;   //!< O_WRONLY
+    static const int TGT_O_RDWR                = 0x00000002;   //!< O_RDWR
+    static const int TGT_O_CREAT       = 0x00000100;   //!< O_CREAT
+    static const int TGT_O_EXCL                = 0x00000200;   //!< O_EXCL
+    static const int TGT_O_NOCTTY      = 0x00000400;   //!< O_NOCTTY
+    static const int TGT_O_TRUNC       = 0x00001000;   //!< O_TRUNC
+    static const int TGT_O_APPEND      = 0x00002000;   //!< O_APPEND
+    static const int TGT_O_NONBLOCK     = 0x00004000;  //!< O_NONBLOCK
+    static const int TGT_O_SYNC                = 0x00010000;   //!< O_SYNC
+    static const int TGT_FASYNC                = 0x00020000;   //!< FASYNC
+    static const int TGT_O_DIRECT      = 0x00040000;   //!< O_DIRECT
+    static const int TGT_O_LARGEFILE   = 0x00100000;   //!< O_LARGEFILE
+    static const int TGT_O_DIRECTORY   = 0x00200000;   //!< O_DIRECTORY
+    static const int TGT_O_NOFOLLOW    = 0x00400000;   //!< O_NOFOLLOW
+    static const int TGT_O_NOATIME     = 0x01000000;   //!< O_NOATIME
+    //@}
+
+    /// For mmap().
+    static const unsigned TGT_MAP_ANONYMOUS = 0x800;
+
+    //@{
+    /// For getsysinfo().
+    static const unsigned GSI_PLATFORM_NAME = 103;  //!< platform name as string
+    static const unsigned GSI_CPU_INFO = 59;   //!< CPU information
+    static const unsigned GSI_PROC_TYPE = 60;  //!< get proc_type
+    static const unsigned GSI_MAX_CPU = 30;         //!< max # cpu's on this machine
+    static const unsigned GSI_CPUS_IN_BOX = 55;        //!< number of CPUs in system
+    static const unsigned GSI_PHYSMEM = 19;            //!< Physical memory in KB
+    static const unsigned GSI_CLK_TCK = 42;            //!< clock freq in Hz
+    //@}
+
+    //@{
+    /// For getrusage().
+    static const int TGT_RUSAGE_SELF = 0;
+    static const int TGT_RUSAGE_CHILDREN = -1;
+    static const int TGT_RUSAGE_BOTH = -2;
+    //@}
+
+    //@{
+    /// For setsysinfo().
+    static const unsigned SSI_IEEE_FP_CONTROL = 14; //!< ieee_set_fp_control()
+    //@}
+
+    //@{
+    /// ioctl() command codes.
+    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_   = 0x40127417;
+    //@}
+
+    /// For table().
+    static const int TBL_SYSINFO = 12;
+
+    /// Resource enumeration for getrlimit().
+    enum rlimit_resources {
+        TGT_RLIMIT_CPU = 0,
+        TGT_RLIMIT_FSIZE = 1,
+        TGT_RLIMIT_DATA = 2,
+        TGT_RLIMIT_STACK = 3,
+        TGT_RLIMIT_CORE = 4,
+        TGT_RLIMIT_NOFILE = 5,
+        TGT_RLIMIT_AS = 6,
+        TGT_RLIMIT_RSS = 7,
+        TGT_RLIMIT_VMEM = 7,
+        TGT_RLIMIT_NPROC = 8,
+        TGT_RLIMIT_MEMLOCK = 9,
+        TGT_RLIMIT_LOCKS = 10
+    };
+
+};
+
+#endif
diff --git a/src/arch/arm/linux/process.cc b/src/arch/arm/linux/process.cc
new file mode 100644 (file)
index 0000000..46b2f9b
--- /dev/null
@@ -0,0 +1,434 @@
+/*
+ * Copyright (c) 2003-2005 The Regents of The University of Michigan
+ * Copyright (c) 2007-2008 The Florida State University
+ * 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
+ */
+
+#include "arch/arm/linux/linux.hh"
+#include "arch/arm/linux/process.hh"
+#include "arch/arm/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"
+
+using namespace std;
+using namespace ArmISA;
+
+/// 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.4.20");
+    strcpy(name->version, "#1 Mon Aug 18 11:32:15 EDT 2003");
+    strcpy(name->machine, "arm");
+
+    name.copyOut(tc->getMemPort());
+    return 0;
+}
+
+SyscallDesc ArmLinuxProcess::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<ArmLinux>),
+    /*  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", unimplementedFunc),
+    /* 14 */ SyscallDesc("mknod", unimplementedFunc),
+    /* 15 */ SyscallDesc("chmod", chmodFunc<ArmLinux>),
+    /* 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", unimplementedFunc),
+    /* 39 */ SyscallDesc("mkdir", unimplementedFunc),
+    /* 40 */ SyscallDesc("rmdir", unimplementedFunc),
+    /* 41 */ SyscallDesc("dup", unimplementedFunc),
+    /* 42 */ SyscallDesc("pipe", unimplementedFunc),
+    /* 43 */ SyscallDesc("times", unimplementedFunc),
+    /* 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<ArmLinux>),
+    /* 55 */ SyscallDesc("fcntl", fcntlFunc),
+    /* 56 */ SyscallDesc("mpx", unimplementedFunc),
+    /* 57 */ SyscallDesc("setpgid", unimplementedFunc),
+    /* 58 */ SyscallDesc("ulimit", unimplementedFunc),
+    /* 59 */ SyscallDesc("unused#59", unimplementedFunc),
+    /* 60 */ SyscallDesc("umask", unimplementedFunc),
+    /* 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", unimplementedFunc),
+    /* 76 */ SyscallDesc("getrlimit", unimplementedFunc),
+    /* 77 */ SyscallDesc("getrusage", unimplementedFunc),
+    /* 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<ArmLinux>),
+    /* 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<ArmLinux>),
+    /* 107 */ SyscallDesc("lstat", unimplementedFunc),
+    /* 108 */ SyscallDesc("fstat", fstatFunc<ArmLinux>),
+    /* 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", unimplementedFunc),
+    /* 141 */ SyscallDesc("getdents", unimplementedFunc),
+    /* 142 */ SyscallDesc("newselect", unimplementedFunc),
+    /* 143 */ SyscallDesc("flock", unimplementedFunc),
+    /* 144 */ SyscallDesc("msync", unimplementedFunc),
+    /* 145 */ SyscallDesc("readv", unimplementedFunc),
+    /* 146 */ SyscallDesc("writev", writevFunc<ArmLinux>),
+    /* 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), // ARM-specific
+    /* 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_sigreturn", unimplementedFunc),
+    /* 174 */ SyscallDesc("rt_sigaction", unimplementedFunc),
+    /* 175 */ SyscallDesc("rt_sigprocmask", 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("vfork", unimplementedFunc),
+    /* 191 */ SyscallDesc("getrlimit", unimplementedFunc),
+    /* 192 */ SyscallDesc("mmap2", unimplementedFunc),
+    /* 193 */ SyscallDesc("truncate64", unimplementedFunc),
+    /* 194 */ SyscallDesc("ftruncate64", unimplementedFunc),
+    /* 195 */ SyscallDesc("stat64", unimplementedFunc),
+    /* 196 */ SyscallDesc("lstat64", lstat64Func<ArmLinux>),
+    /* 197 */ SyscallDesc("fstat64", fstatFunc<ArmLinux>),
+    /* 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("setregid", unimplementedFunc),
+    /* 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("fcntl64", fcntl64Func),
+    /* 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("flistxattr", unimplementedFunc),
+    /* 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("exit_group", exitFunc),
+    /* 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),
+};
+
+ArmLinuxProcess::ArmLinuxProcess(LiveProcessParams * params,
+        ObjectFile *objFile)
+    : ArmLiveProcess(params, objFile),
+     Num_Syscall_Descs(sizeof(syscallDescs) / sizeof(SyscallDesc))
+{ }
+
+SyscallDesc*
+ArmLinuxProcess::getDesc(int callnum)
+{
+    // Angel SWI syscalls are unsupported in this release
+    if (callnum == 0x123456)
+        panic("Attempt to execute an ANGEL_SWI system call (newlib-related)");
+    else if ((callnum & 0x00f00000) == 0x00900000)
+        callnum &= 0x000fffff;
+    // Linux syscalls have to strip off the 0x00900000
+
+    if (callnum < 0 || callnum > Num_Syscall_Descs)
+        return NULL;
+
+    return &syscallDescs[callnum];
+}
diff --git a/src/arch/arm/linux/process.hh b/src/arch/arm/linux/process.hh
new file mode 100644 (file)
index 0000000..524661b
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2007-2008 The Florida State University
+ * 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
+ */
+
+#ifndef __ARM_LINUX_PROCESS_HH__
+#define __ARM_LINUX_PROCESS_HH__
+
+#include "arch/arm/process.hh"
+
+
+/// A process with emulated Arm/Linux syscalls.
+class ArmLinuxProcess : public ArmLiveProcess
+{
+  public:
+    ArmLinuxProcess(LiveProcessParams * params, ObjectFile *objFile);
+
+    virtual SyscallDesc* getDesc(int callnum);
+
+    /// The target system's hostname.
+    static const char *hostname;
+
+     /// Array of syscall descriptors, indexed by call number.
+    static SyscallDesc syscallDescs[];
+
+    const int Num_Syscall_Descs;
+};
+
+#endif // __ARM_LINUX_PROCESS_HH__
diff --git a/src/arch/arm/locked_mem.hh b/src/arch/arm/locked_mem.hh
new file mode 100644 (file)
index 0000000..4189927
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2006 The Regents of The University of Michigan
+ * Copyright (c) 2007-2008 The Florida State University
+ * 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
+ */
+
+#ifndef __ARCH_ARM_LOCKED_MEM_HH__
+#define __ARCH_ARM_LOCKED_MEM_HH__
+
+/**
+ * @file
+ *
+ * ISA-specific helper functions for locked memory accesses.
+ */
+
+#include "mem/request.hh"
+
+
+namespace ArmISA
+{
+template <class XC>
+inline void
+handleLockedRead(XC *xc, Request *req)
+{
+}
+
+
+template <class XC>
+inline bool
+handleLockedWrite(XC *xc, Request *req)
+{
+    return true;
+}
+
+
+} // namespace ArmISA
+
+#endif
diff --git a/src/arch/arm/mmaped_ipr.hh b/src/arch/arm/mmaped_ipr.hh
new file mode 100644 (file)
index 0000000..8483ef7
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2006 The Regents of The University of Michigan
+ * Copyright (c) 2007-2008 The Florida State University
+ * 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
+ */
+
+#ifndef __ARCH_ARM_MMAPED_IPR_HH__
+#define __ARCH_ARM_MMAPED_IPR_HH__
+
+/**
+ * @file
+ *
+ * ISA-specific helper functions for memory mapped IPR accesses.
+ */
+
+#include "base/misc.hh"
+#include "mem/packet.hh"
+
+class ThreadContext;
+
+namespace ArmISA
+{
+inline Tick
+handleIprRead(ThreadContext *xc, Packet *pkt)
+{
+    panic("No implementation for handleIprRead in ARM\n");
+}
+
+inline Tick
+handleIprWrite(ThreadContext *xc, Packet *pkt)
+{
+    panic("No implementation for handleIprWrite in ARM\n");
+}
+
+
+} // namespace ArmISA
+
+#endif
diff --git a/src/arch/arm/pagetable.cc b/src/arch/arm/pagetable.cc
new file mode 100644 (file)
index 0000000..aebe7f0
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * 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
+ * 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
+ */
+
+#include "arch/arm/pagetable.hh"
+#include "sim/serialize.hh"
+
+namespace ArmISA
+{
+    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);
+    }
+}
diff --git a/src/arch/arm/pagetable.hh b/src/arch/arm/pagetable.hh
new file mode 100644 (file)
index 0000000..ad3464a
--- /dev/null
@@ -0,0 +1,102 @@
+/*
+ * 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
+ * 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
+ */
+
+#ifndef __ARCH_ARM_PAGETABLE_H__
+#define __ARCH_ARM_PAGETABLE_H__
+
+#include "arch/arm/isa_traits.hh"
+#include "arch/arm/utility.hh"
+#include "arch/arm/vtophys.hh"
+#include "config/full_system.hh"
+
+namespace ArmISA {
+
+    struct VAddr
+    {
+        static const int ImplBits = 43;
+        static const Addr ImplMask = (ULL(1) << ImplBits) - 1;
+        static const Addr UnImplMask = ~ImplMask;
+
+        VAddr(Addr a) : addr(a) {}
+        Addr addr;
+        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 ArmISA::PteAddr(addr >> PageShift); }
+        Addr level2() const
+        { return ArmISA::PteAddr(addr >> (NPtePageShift + PageShift)); }
+        Addr level1() const
+        { return ArmISA::PteAddr(addr >> (2 * NPtePageShift + PageShift)); }
+    };
+
+    // ITB/DTB page table entry
+    struct PTE
+    {
+      Addr Mask; // What parts of the VAddr (from bits 28..11) should be used in translation (includes Mask and MaskX from PageMask)
+      Addr VPN; // Virtual Page Number (/2) (Includes VPN2 + VPN2X .. bits 31..11 from EntryHi)
+      uint8_t asid; // Address Space ID (8 bits) // Lower 8 bits of EntryHi
+
+      bool G;    // Global Bit - Obtained by an *AND* of EntryLo0 and EntryLo1 G bit
+
+      /* 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);
+    };
+
+};
+#endif // __ARCH_ARM_PAGETABLE_H__
+
diff --git a/src/arch/arm/predecoder.hh b/src/arch/arm/predecoder.hh
new file mode 100644 (file)
index 0000000..86d344b
--- /dev/null
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2006 The Regents of The University of Michigan
+ * Copyright (c) 2007-2008 The Florida State University
+ * 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
+ */
+
+#ifndef __ARCH_ARM_PREDECODER_HH__
+#define __ARCH_ARM_PREDECODER_HH__
+
+#include "arch/arm/types.hh"
+#include "base/misc.hh"
+#include "sim/host.hh"
+
+class ThreadContext;
+
+namespace ArmISA
+{
+    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;
+        }
+    };
+};
+
+#endif // __ARCH_ARM_PREDECODER_HH__
diff --git a/src/arch/arm/process.cc b/src/arch/arm/process.cc
new file mode 100644 (file)
index 0000000..365d5b2
--- /dev/null
@@ -0,0 +1,180 @@
+/*
+ * Copyright (c) 2007-2008 The Florida State University
+ * 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
+ */
+
+#include "arch/arm/isa_traits.hh"
+#include "arch/arm/process.hh"
+#include "arch/arm/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 ArmISA;
+
+ArmLiveProcess::ArmLiveProcess(LiveProcessParams *params, ObjectFile *objFile)
+    : LiveProcess(params, objFile)
+{
+    stack_base = 0xc0000000L;
+
+    // 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
+ArmLiveProcess::startup()
+{
+    argsInit(MachineBytes, VMPageSize);
+}
+
+void
+ArmLiveProcess::copyStringArray32(std::vector<std::string> &strings,
+        Addr array_ptr, Addr data_ptr,
+        TranslatingPort* memPort)
+{
+    Addr data_ptr_swap;
+    for (int i = 0; i < strings.size(); ++i) {
+        data_ptr_swap = htog(data_ptr);
+        memPort->writeBlob(array_ptr, (uint8_t*)&data_ptr_swap,
+                sizeof(uint32_t));
+        memPort->writeString(data_ptr, strings[i].c_str());
+        array_ptr += sizeof(uint32_t);
+        data_ptr += strings[i].size() + 1;
+    }
+    // add NULL terminator
+    data_ptr = 0;
+
+    memPort->writeBlob(array_ptr, (uint8_t*)&data_ptr, sizeof(uint32_t));
+}
+
+void
+ArmLiveProcess::argsInit(int intSize, int pageSize)
+{
+    // Overloaded argsInit so that we can fine-tune for ARM architecture
+    Process::startup();
+
+    // load object file into target memory
+    objFile->loadSections(initVirtMem);
+
+    // Calculate how much space we need for arg & env arrays.
+    int argv_array_size = intSize * (argv.size() + 1);
+    int envp_array_size = intSize * (envp.size() + 1);
+    int arg_data_size = 0;
+    for (int i = 0; i < argv.size(); ++i) {
+        arg_data_size += argv[i].size() + 1;
+    }
+    int env_data_size = 0;
+    for (int i = 0; i < envp.size(); ++i) {
+        env_data_size += envp[i].size() + 1;
+    }
+
+    int space_needed =
+        argv_array_size + envp_array_size + arg_data_size + env_data_size;
+    if (space_needed < 16*1024)
+        space_needed = 16*1024;
+
+    // set bottom of stack
+    stack_min = stack_base - space_needed;
+    // align it
+    stack_min = roundDown(stack_min, pageSize);
+    stack_size = stack_base - stack_min;
+    // map memory
+    pTable->allocate(stack_min, roundUp(stack_size, pageSize));
+
+    // map out initial stack contents
+    Addr argv_array_base = stack_min + intSize; // room for argc
+    Addr envp_array_base = argv_array_base + argv_array_size;
+    Addr arg_data_base = envp_array_base + envp_array_size;
+    Addr env_data_base = arg_data_base + arg_data_size;
+
+    // write contents to stack
+    uint64_t argc = argv.size();
+    if (intSize == 8)
+        argc = htog((uint64_t)argc);
+    else if (intSize == 4)
+        argc = htog((uint32_t)argc);
+    else
+        panic("Unknown int size");
+
+    initVirtMem->writeBlob(stack_min, (uint8_t*)&argc, intSize);
+
+    copyStringArray32(argv, argv_array_base, arg_data_base, initVirtMem);
+    copyStringArray32(envp, envp_array_base, env_data_base, initVirtMem);
+
+    /*
+    //uint8_t insns[] = {0xe5, 0x9f, 0x00, 0x08, 0xe1, 0xa0, 0xf0, 0x0e};
+    uint8_t insns[] = {0x08, 0x00, 0x9f, 0xe5, 0x0e, 0xf0, 0xa0, 0xe1};
+
+    initVirtMem->writeBlob(0xffff0fe0, insns, 8);
+    */
+
+    ThreadContext *tc = system->getThreadContext(contextIds[0]);
+
+    tc->setIntReg(ArgumentReg1, argc);
+    tc->setIntReg(ArgumentReg2, argv_array_base);
+    tc->setIntReg(StackPointerReg, stack_min);
+
+    Addr prog_entry = objFile->entryPoint();
+    tc->setPC(prog_entry);
+    tc->setNextPC(prog_entry + sizeof(MachInst));
+}
+
+ArmISA::IntReg
+ArmLiveProcess::getSyscallArg(ThreadContext *tc, int i)
+{
+    assert(i < 4);
+    return tc->readIntReg(ArgumentReg0 + i);
+}
+
+void
+ArmLiveProcess::setSyscallArg(ThreadContext *tc,
+        int i, ArmISA::IntReg val)
+{
+    assert(i < 4);
+    tc->setIntReg(ArgumentReg0 + i, val);
+}
+
+void
+ArmLiveProcess::setSyscallReturn(ThreadContext *tc,
+        SyscallReturn return_value)
+{
+    tc->setIntReg(ReturnValueReg, return_value.value());
+}
diff --git a/src/arch/arm/process.hh b/src/arch/arm/process.hh
new file mode 100644 (file)
index 0000000..8954d37
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2007-2008 The Florida State University
+ * 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
+ */
+
+#ifndef __ARM_PROCESS_HH__
+#define __ARM_PROCESS_HH__
+
+#include <string>
+#include <vector>
+#include "sim/process.hh"
+
+class LiveProcess;
+class ObjectFile;
+class System;
+
+class ArmLiveProcess : public LiveProcess
+{
+  protected:
+    ArmLiveProcess(LiveProcessParams * params, ObjectFile *objFile);
+
+    void startup();
+
+    void copyStringArray32(std::vector<std::string> &strings,
+            Addr array_ptr, Addr data_ptr,
+            TranslatingPort* memPort);
+
+  public:
+    void argsInit(int intSize, int pageSize);
+
+    ArmISA::IntReg getSyscallArg(ThreadContext *tc, int i);
+    void setSyscallArg(ThreadContext *tc, int i, ArmISA::IntReg val);
+    void setSyscallReturn(ThreadContext *tc, SyscallReturn return_value);
+};
+
+#endif // __ARM_PROCESS_HH__
+
diff --git a/src/arch/arm/regfile.hh b/src/arch/arm/regfile.hh
new file mode 100644 (file)
index 0000000..91cc67b
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2007-2008 The Florida State University
+ * 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
+ */
+
+#ifndef __ARCH_ARM_REGFILE_HH__
+#define __ARCH_ARM_REGFILE_HH__
+
+#include "arch/arm/regfile/regfile.hh"
+
+#endif
diff --git a/src/arch/arm/regfile/float_regfile.hh b/src/arch/arm/regfile/float_regfile.hh
new file mode 100644 (file)
index 0000000..757f5f0
--- /dev/null
@@ -0,0 +1,181 @@
+/*
+ * Copyright (c) 2007-2008 The Florida State University
+ * 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
+ */
+
+#ifndef __ARCH_ARM_REGFILE_FLOAT_REGFILE_HH__
+#define __ARCH_ARM_REGFILE_FLOAT_REGFILE_HH__
+
+#include "arch/arm/types.hh"
+#include "arch/arm/isa_traits.hh"
+#include "base/misc.hh"
+#include "base/bitfield.hh"
+#include "sim/faults.hh"
+#include "sim/serialize.hh"
+
+#include <string>
+
+class Checkpoint;
+
+namespace ArmISA
+{
+    static inline std::string getFloatRegName(RegIndex)
+    {
+        return "";
+    }
+
+    const uint32_t ARM32_QNAN = 0x7fbfffff;
+    const uint64_t ARM64_QNAN = ULL(0x7fbfffffffffffff);
+
+    enum FPControlRegNums {
+       FIR = NumFloatArchRegs,
+       FCCR,
+       FEXR,
+       FENR,
+       FCSR
+    };
+
+    enum FCSRBits {
+        Inexact = 1,
+        Underflow,
+        Overflow,
+        DivideByZero,
+        Invalid,
+        Unimplemented
+    };
+
+    enum FCSRFields {
+        Flag_Field = 1,
+        Enable_Field = 6,
+        Cause_Field = 11
+    };
+
+    const int SingleWidth = 32;
+    const int SingleBytes = SingleWidth / 4;
+
+    const int DoubleWidth = 64;
+    const int DoubleBytes = DoubleWidth / 4;
+
+    const int QuadWidth = 128;
+    const int QuadBytes = QuadWidth / 4;
+
+    class FloatRegFile
+    {
+      protected:
+          union {
+            FloatRegBits qregs[NumFloatRegs];
+            FloatRegVal regs[NumFloatRegs];
+          };
+
+      public:
+
+        void clear()
+        {
+            bzero(regs, sizeof(regs));
+            regs[8] = 0.0;
+            regs[9] = 1.0;
+            regs[10] = 2.0;
+            regs[11] = 3.0;
+            regs[12] = 4.0;
+            regs[13] = 5.0;
+            regs[14] = 0.5;
+            regs[15] = 10.0;
+        }
+
+        FloatRegVal readReg(int floatReg, int width)
+        {
+            return regs[floatReg];
+        }
+
+        FloatRegBits readRegBits(int floatReg, int width)
+        {
+            //return qregs[floatReg];
+            switch(width)
+            {
+                case SingleWidth:
+                {
+                    union {
+                        float f;
+                        uint32_t i;
+                    } s;
+                    s.f = (float) regs[floatReg];
+                    return s.i;
+                }
+                case DoubleWidth:
+                {
+                    uint64_t tmp = (qregs[floatReg]<<32|qregs[floatReg]>>32);
+                    return tmp;
+                }
+                default:
+                    panic("Attempted to read a %d bit floating point "
+                        "register!", width);
+
+            }
+        }
+
+        Fault setReg(int floatReg, const FloatRegVal &val, int width)
+        {
+            if (floatReg > 7)
+                panic("Writing to a hard-wired FP register");
+            regs[floatReg] = val;
+            return NoFault;
+        }
+
+        Fault setRegBits(int floatReg, const FloatRegBits &val, int width)
+        {
+            if (floatReg > 7)
+                panic("Writing to a hard-wired FP register");
+            switch(width)
+            {
+                case DoubleWidth:
+                {
+                    uint64_t tmp = (val << 32 | val >> 32);
+                    qregs[floatReg] = tmp;
+                    return NoFault;
+                }
+                case SingleWidth:
+                default:
+                    panic("Attempted to write a %d bit floating point "
+                        "register!", width);
+            }
+        }
+
+        void serialize(std::ostream &os)
+        {
+            SERIALIZE_ARRAY(regs, NumFloatRegs);
+        }
+
+        void unserialize(Checkpoint *cp, const std::string &section)
+        {
+            UNSERIALIZE_ARRAY(regs, NumFloatRegs);
+        }
+    };
+
+} // namespace ArmISA
+
+#endif
diff --git a/src/arch/arm/regfile/int_regfile.hh b/src/arch/arm/regfile/int_regfile.hh
new file mode 100644 (file)
index 0000000..938e688
--- /dev/null
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2007-2008 The Florida State University
+ * 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
+ */
+
+#ifndef __ARCH_ARM_REGFILE_INT_REGFILE_HH__
+#define __ARCH_ARM_REGFILE_INT_REGFILE_HH__
+
+#include "arch/arm/isa_traits.hh"
+#include "arch/arm/types.hh"
+#include "base/misc.hh"
+#include "sim/faults.hh"
+#include "sim/serialize.hh"
+
+class Checkpoint;
+class ThreadContext;
+
+namespace ArmISA
+{
+    static inline std::string getIntRegName(RegIndex)
+    {
+        return "";
+    }
+
+    enum MiscIntRegNums {
+        zero_reg = NumIntArchRegs,
+        addr_reg,
+
+        rhi,
+        rlo,
+
+        r8_fiq,    /* FIQ mode register bank */
+        r9_fiq,
+        r10_fiq,
+        r11_fiq,
+        r12_fiq,
+
+        r13_fiq,   /* FIQ mode SP and LR */
+        r14_fiq,
+
+        r13_irq,   /* IRQ mode SP and LR */
+        r14_irq,
+
+        r13_svc,   /* SVC mode SP and LR */
+        r14_svc,
+
+        r13_undef, /* UNDEF mode SP and LR */
+        r14_undef,
+
+        r13_abt,   /* ABT mode SP and LR */
+        r14_abt
+    };
+
+    class IntRegFile
+    {
+      protected:
+        IntReg regs[NumIntRegs];
+
+      public:
+        IntReg readReg(int intReg)
+        {
+            return regs[intReg];
+        }
+
+        void clear()
+        {
+            bzero(regs, sizeof(regs));
+        }
+
+        Fault setReg(int intReg, const IntReg &val)
+        {
+            regs[intReg] = val;
+            return NoFault;
+        }
+
+        void serialize(std::ostream &os)
+        {
+            SERIALIZE_ARRAY(regs, NumIntRegs);
+        }
+
+        void unserialize(Checkpoint *cp, const std::string &section)
+        {
+            UNSERIALIZE_ARRAY(regs, NumIntRegs);
+        }
+    };
+
+} // namespace ArmISA
+
+#endif
diff --git a/src/arch/arm/regfile/misc_regfile.hh b/src/arch/arm/regfile/misc_regfile.hh
new file mode 100644 (file)
index 0000000..f8301be
--- /dev/null
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2007-2008 The Florida State University
+ * 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
+ */
+
+#ifndef __ARCH_ARM_REGFILE_MISC_REGFILE_HH__
+#define __ARCH_ARM_REGFILE_MISC_REGFILE_HH__
+
+#include "arch/arm/types.hh"
+#include "sim/faults.hh"
+
+class ThreadContext;
+
+namespace ArmISA
+{
+    static inline std::string getMiscRegName(RegIndex)
+    {
+        return "";
+    }
+
+    //Coprocessor 0 Register Names
+    enum MiscRegTags {
+        // Status Registers for the ARM
+        //
+        // CPSR Layout
+        // 31302928  ...  7 6 5 4 3 2 1 0
+        // N Z C V   ...  I F T {  MODE }
+        CPSR = 0,
+        SPSR_FIQ,
+        SPSR_IRQ,
+        SPSR_SVC,
+        SPSR_UND,
+        SPSR_ABT,
+        FPSR
+    };
+
+    class MiscRegFile {
+
+      protected:
+        MiscReg miscRegFile[NumMiscRegs];
+
+      public:
+        void clear()
+        {
+            // Unknown startup state in misc register file currently
+        }
+
+        void copyMiscRegs(ThreadContext *tc);
+
+        MiscReg readRegNoEffect(int misc_reg)
+        {
+            return miscRegFile[misc_reg];
+        }
+
+        MiscReg readReg(int misc_reg, ThreadContext *tc)
+        {
+            return miscRegFile[misc_reg];
+        }
+
+        void setRegNoEffect(int misc_reg, const MiscReg &val)
+        {
+            miscRegFile[misc_reg] = val;
+        }
+
+        void setReg(int misc_reg, const MiscReg &val,
+                               ThreadContext *tc)
+        {
+            miscRegFile[misc_reg] = val;
+        }
+
+        friend class RegFile;
+    };
+} // namespace ArmISA
+
+#endif
diff --git a/src/arch/arm/regfile/regfile.cc b/src/arch/arm/regfile/regfile.cc
new file mode 100644 (file)
index 0000000..a4d6e9a
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2007-2008 The Florida State University
+ * 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
+ */
+
+#include "arch/arm/regfile/regfile.hh"
+#include "sim/serialize.hh"
+
+using namespace std;
+
+namespace ArmISA
+{
+
+void
+copyRegs(ThreadContext *src, ThreadContext *dest)
+{
+    panic("Copy Regs Not Implemented Yet\n");
+}
+
+void
+copyMiscRegs(ThreadContext *src, ThreadContext *dest)
+{
+    panic("Copy Misc. Regs Not Implemented Yet\n");
+}
+
+void
+MiscRegFile::copyMiscRegs(ThreadContext *tc)
+{
+    panic("Copy Misc. Regs Not Implemented Yet\n");
+}
+
+void
+RegFile::serialize(EventManager *em, ostream &os)
+{
+    intRegFile.serialize(os);
+    //SERIALIZE_ARRAY(floatRegFile, NumFloatRegs);
+    //SERIALZE_ARRAY(miscRegFile);
+    //SERIALIZE_SCALAR(miscRegs.fpcr);
+    //SERIALIZE_SCALAR(miscRegs.lock_flag);
+    //SERIALIZE_SCALAR(miscRegs.lock_addr);
+    //SERIALIZE_SCALAR(pc);
+    SERIALIZE_SCALAR(npc);
+    SERIALIZE_SCALAR(nnpc);
+}
+
+void
+RegFile::unserialize(EventManager *em, Checkpoint *cp, const string &section)
+{
+    intRegFile.unserialize(cp, section);
+    //UNSERIALIZE_ARRAY(floatRegFile);
+    //UNSERIALZE_ARRAY(miscRegFile);
+    //UNSERIALIZE_SCALAR(miscRegs.fpcr);
+    //UNSERIALIZE_SCALAR(miscRegs.lock_flag);
+    //UNSERIALIZE_SCALAR(miscRegs.lock_addr);
+    //UNSERIALIZE_SCALAR(pc);
+    UNSERIALIZE_SCALAR(npc);
+    UNSERIALIZE_SCALAR(nnpc);
+
+}
+
+} // namespace ArmISA
diff --git a/src/arch/arm/regfile/regfile.hh b/src/arch/arm/regfile/regfile.hh
new file mode 100644 (file)
index 0000000..7f4d213
--- /dev/null
@@ -0,0 +1,206 @@
+/*
+ * Copyright (c) 2007-2008 The Florida State University
+ * 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
+ */
+
+#ifndef __ARCH_ARM_REGFILE_REGFILE_HH__
+#define __ARCH_ARM_REGFILE_REGFILE_HH__
+
+#include "arch/arm/types.hh"
+#include "arch/arm/regfile/int_regfile.hh"
+#include "arch/arm/regfile/float_regfile.hh"
+#include "arch/arm/regfile/misc_regfile.hh"
+#include "sim/faults.hh"
+
+class Checkpoint;
+class EventManager;
+class ThreadContext;
+
+namespace ArmISA
+{
+    class RegFile
+    {
+      protected:
+        IntRegFile intRegFile;         // (signed) integer register file
+        FloatRegFile floatRegFile;     // floating point register file
+        MiscRegFile miscRegFile;       // control register file
+
+      public:
+
+        void clear()
+        {
+            intRegFile.clear();
+            floatRegFile.clear();
+            miscRegFile.clear();
+        }
+
+        MiscReg readMiscRegNoEffect(int miscReg)
+        {
+            return miscRegFile.readRegNoEffect(miscReg);
+        }
+
+        MiscReg readMiscReg(int miscReg, ThreadContext *tc)
+        {
+            return miscRegFile.readReg(miscReg, tc);
+        }
+
+        void setMiscRegNoEffect(int miscReg, const MiscReg &val)
+        {
+            miscRegFile.setRegNoEffect(miscReg, val);
+        }
+
+        void setMiscReg(int miscReg, const MiscReg &val,
+                ThreadContext * tc)
+        {
+            miscRegFile.setReg(miscReg, val, tc);
+        }
+
+        FloatRegVal readFloatReg(int floatReg)
+        {
+            return floatRegFile.readReg(floatReg,SingleWidth);
+        }
+
+        FloatRegVal readFloatReg(int floatReg, int width)
+        {
+            return floatRegFile.readReg(floatReg,width);
+        }
+
+        FloatRegBits readFloatRegBits(int floatReg)
+        {
+            return floatRegFile.readRegBits(floatReg,SingleWidth);
+        }
+
+        FloatRegBits readFloatRegBits(int floatReg, int width)
+        {
+            return floatRegFile.readRegBits(floatReg,width);
+        }
+
+        void setFloatReg(int floatReg, const FloatRegVal &val)
+        {
+            floatRegFile.setReg(floatReg, val, SingleWidth);
+        }
+
+        void setFloatReg(int floatReg, const FloatRegVal &val, int width)
+        {
+            floatRegFile.setReg(floatReg, val, width);
+        }
+
+        void setFloatRegBits(int floatReg, const FloatRegBits &val)
+        {
+            floatRegFile.setRegBits(floatReg, val, SingleWidth);
+        }
+
+        void setFloatRegBits(int floatReg, const FloatRegBits &val, int width)
+        {
+            floatRegFile.setRegBits(floatReg, val, width);
+        }
+
+        IntReg readIntReg(int intReg)
+        {
+            // In the Arm, reading from the PC for a generic instruction yields
+            // the current PC + 8, due to previous pipeline implementations
+            if (intReg == PCReg)
+                return intRegFile.readReg(intReg) + 8;
+                //return pc + 8;
+            else
+                return intRegFile.readReg(intReg);
+        }
+
+        void setIntReg(int intReg, const IntReg &val)
+        {
+            // Have to trap writes to PC so that they update NPC instead
+            if (intReg == PCReg)
+                setNextPC(val);
+            else
+                intRegFile.setReg(intReg, val);
+        }
+      protected:
+
+        Addr pc;                       // program counter
+        Addr npc;                      // next-cycle program counter
+        Addr nnpc;                     // next-next-cycle program counter
+
+      public:
+        Addr readPC()
+        {
+            return intRegFile.readReg(PCReg);
+            //return pc;
+        }
+
+        void setPC(Addr val)
+        {
+            intRegFile.setReg(PCReg, val);
+            //pc = val;
+        }
+
+        Addr readNextPC()
+        {
+            return npc;
+        }
+
+        void setNextPC(Addr val)
+        {
+            npc = val;
+        }
+
+        Addr readNextNPC()
+        {
+            return npc + sizeof(MachInst);
+        }
+
+        void setNextNPC(Addr val)
+        {
+            //nnpc = val;
+        }
+
+        void serialize(EventManager *em, std::ostream &os);
+        void unserialize(EventManager *em, Checkpoint *cp,
+                         const std::string &section);
+
+        void changeContext(RegContextParam param, RegContextVal val)
+        {
+        }
+    };
+
+    static inline int flattenIntIndex(ThreadContext * tc, int reg)
+    {
+        return reg;
+    }
+
+    static inline int flattenFloatIndex(ThreadContext * tc, int reg)
+    {
+        return reg;
+    }
+
+    void copyRegs(ThreadContext *src, ThreadContext *dest);
+
+    void copyMiscRegs(ThreadContext *src, ThreadContext *dest);
+
+} // namespace ArmISA
+
+#endif
diff --git a/src/arch/arm/remote_gdb.hh b/src/arch/arm/remote_gdb.hh
new file mode 100644 (file)
index 0000000..ec8098c
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2002-2005 The Regents of The University of Michigan
+ * Copyright (c) 2007-2008 The Florida State University
+ * 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
+ */
+
+#ifndef __ARCH_ARM_REMOTE_GDB_HH__
+#define __ARCH_ARM_REMOTE_GDB_HH__
+
+#include "base/remote_gdb.hh"
+
+namespace ArmISA
+{
+    class RemoteGDB : public BaseRemoteGDB
+    {
+      public:
+        //These needs to be written to suit ARM
+
+        RemoteGDB(System *system, ThreadContext *context)
+            : BaseRemoteGDB(system, context, 1)
+        {}
+
+        bool acc(Addr, size_t)
+        { panic("acc not implemented for ARM!"); }
+
+        void getregs()
+        { panic("getregs not implemented for ARM!"); }
+
+        void setregs()
+        { panic("setregs not implemented for ARM!"); }
+
+        void clearSingleStep()
+        { panic("clearSingleStep not implemented for ARM!"); }
+
+        void setSingleStep()
+        { panic("setSingleStep not implemented for ARM!"); }
+    };
+}
+
+#endif /* __ARCH_ARM_REMOTE_GDB_H__ */
diff --git a/src/arch/arm/stacktrace.hh b/src/arch/arm/stacktrace.hh
new file mode 100644 (file)
index 0000000..3f9c910
--- /dev/null
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 2005 The Regents of The University of Michigan
+ * Copyright (c) 2007-2008 The Florida State University
+ * 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
+ */
+
+#ifndef __ARCH_ARM_STACKTRACE_HH__
+#define __ARCH_ARM_STACKTRACE_HH__
+
+#include "base/trace.hh"
+#include "cpu/static_inst.hh"
+
+class ThreadContext;
+class StackTrace;
+
+namespace ArmISA
+{
+
+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;
+}
+
+}
+
+#endif // __ARCH_ARM_STACKTRACE_HH__
diff --git a/src/arch/arm/tlb.cc b/src/arch/arm/tlb.cc
new file mode 100644 (file)
index 0000000..78eebdd
--- /dev/null
@@ -0,0 +1,382 @@
+/*
+ * 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
+ * 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
+ */
+
+#include <string>
+#include <vector>
+
+#include "arch/arm/pagetable.hh"
+#include "arch/arm/tlb.hh"
+#include "arch/arm/faults.hh"
+#include "arch/arm/utility.hh"
+#include "base/inifile.hh"
+#include "base/str.hh"
+#include "base/trace.hh"
+#include "cpu/thread_context.hh"
+#include "sim/process.hh"
+#include "mem/page_table.hh"
+#include "params/ArmDTB.hh"
+#include "params/ArmITB.hh"
+#include "params/ArmTLB.hh"
+#include "params/ArmUTB.hh"
+
+
+using namespace std;
+using namespace ArmISA;
+
+///////////////////////////////////////////////////////////////////////
+//
+//  ARM TLB
+//
+
+#define MODE2MASK(X)                   (1 << (X))
+
+TLB::TLB(const Params *p)
+    : BaseTLB(p), size(p->size), nlu(0)
+{
+    table = new ArmISA::PTE[size];
+    memset(table, 0, sizeof(ArmISA::PTE[size]));
+    smallPages=0;
+}
+
+TLB::~TLB()
+{
+    if (table)
+        delete [] table;
+}
+
+// look up an entry in the TLB
+ArmISA::PTE *
+TLB::lookup(Addr vpn, uint8_t asn) const
+{
+    // assume not found...
+    ArmISA::PTE *retval = NULL;
+    PageTable::const_iterator i = lookupTable.find(vpn);
+    if (i != lookupTable.end()) {
+        while (i->first == vpn) {
+            int index = i->second;
+            ArmISA::PTE *pte = &table[index];
+
+            /* 1KB TLB Lookup code - from ARM ARM Volume III - Rev. 2.50 */
+            Addr Mask = pte->Mask;
+            Addr InvMask = ~Mask;
+            Addr VPN  = pte->VPN;
+            //     warn("Valid: %d - %d\n",pte->V0,pte->V1);
+            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;
+}
+
+ArmISA::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...
+    ArmISA::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;
+            ArmISA::PTE *pte = &table[index];
+
+            /* 1KB TLB Lookup code - from ARM ARM Volume III - Rev. 2.50 */
+            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(Arm,"VPN: %x, asid: %d, Result of TLBP: %d\n",vpn,asn,Ind);
+    return Ind;
+}
+Fault inline
+TLB::checkCacheability(RequestPtr &req)
+{
+  Addr VAddrUncacheable = 0xA0000000;
+  // In ARM, cacheability is controlled by certain bits of the virtual address
+  // or by the TLB entry
+  if((req->getVaddr() & VAddrUncacheable) == VAddrUncacheable) {
+    // mark request as uncacheable
+    req->setFlags(req->getFlags() | Request::UNCACHEABLE);
+  }
+  return NoFault;
+}
+void TLB::insertAt(ArmISA::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
+    DPRINTF(TLB,"TLB[%d]: %x %x %x %x\n",Index,pte.Mask<<11,((pte.VPN << 11) | pte.asid),((pte.PFN0 <<6) | (pte.C0 << 3) | (pte.D0 << 2) | (pte.V0 <<1) | pte.G),
+            ((pte.PFN1 <<6) | (pte.C1 << 3) | (pte.D1 << 2) | (pte.V1 <<1) | pte.G));
+    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));
+    //    int TestIndex=probeEntry(pte.VPN,pte.asid);
+    //    warn("Inserted at: %d, Found at: %d (%x)\n",Index,TestIndex,pte.Mask);
+  }
+
+}
+
+// insert a new TLB entry
+void
+TLB::insert(Addr addr, ArmISA::PTE &pte)
+{
+  fatal("TLB Insert not yet implemented\n");
+}
+
+void
+TLB::flushAll()
+{
+    DPRINTF(TLB, "flushAll\n");
+    memset(table, 0, sizeof(ArmISA::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
+ITB::translateAtomic(RequestPtr req, ThreadContext *tc)
+{
+#if !FULL_SYSTEM
+    Process * p = tc->getProcessPtr();
+
+    Fault fault = p->pTable->translate(req);
+    if(fault != NoFault)
+        return fault;
+
+    return NoFault;
+#else
+  fatal("ITB translate not yet implemented\n");
+#endif
+}
+
+void
+ITB::translateTiming(RequestPtr req, ThreadContext *tc,
+        Translation *translation)
+{
+    assert(translation);
+    translation->finish(translateAtomic(req, tc), req, tc, false);
+}
+
+
+Fault
+DTB::translateAtomic(RequestPtr req, ThreadContext *tc, bool write)
+{
+#if !FULL_SYSTEM
+    Process * p = tc->getProcessPtr();
+
+    Fault fault = p->pTable->translate(req);
+    if(fault != NoFault)
+        return fault;
+
+    return NoFault;
+#else
+  fatal("DTB translate not yet implemented\n");
+#endif
+}
+
+void
+DTB::translateTiming(RequestPtr req, ThreadContext *tc,
+        Translation *translation, bool write)
+{
+    assert(translation);
+    translation->finish(translateAtomic(req, tc, write), req, tc, write);
+}
+
+///////////////////////////////////////////////////////////////////////
+//
+//  Arm ITB
+//
+ITB::ITB(const Params *p)
+    : TLB(p)
+{}
+
+
+///////////////////////////////////////////////////////////////////////
+//
+//  Arm DTB
+//
+DTB::DTB(const Params *p)
+    : TLB(p)
+{}
+
+///////////////////////////////////////////////////////////////////////
+//
+//  Arm UTB
+//
+UTB::UTB(const Params *p)
+    : ITB(p), DTB(p)
+{}
+
+ArmISA::PTE &
+TLB::index(bool advance)
+{
+    ArmISA::PTE *pte = &table[nlu];
+
+    if (advance)
+        nextnlu();
+
+    return *pte;
+}
+
+ArmISA::ITB *
+ArmITBParams::create()
+{
+    return new ArmISA::ITB(this);
+}
+
+ArmISA::DTB *
+ArmDTBParams::create()
+{
+    return new ArmISA::DTB(this);
+}
+
+ArmISA::UTB *
+ArmUTBParams::create()
+{
+    return new ArmISA::UTB(this);
+}
diff --git a/src/arch/arm/tlb.hh b/src/arch/arm/tlb.hh
new file mode 100644 (file)
index 0000000..fea317e
--- /dev/null
@@ -0,0 +1,177 @@
+/*
+ * 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
+ * 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
+ */
+
+#ifndef __ARCH_ARM_TLB_HH__
+#define __ARCH_ARM_TLB_HH__
+
+#include <map>
+
+#include "arch/arm/isa_traits.hh"
+#include "arch/arm/utility.hh"
+#include "arch/arm/vtophys.hh"
+#include "arch/arm/pagetable.hh"
+#include "base/statistics.hh"
+#include "mem/request.hh"
+#include "params/ArmDTB.hh"
+#include "params/ArmITB.hh"
+#include "sim/faults.hh"
+#include "sim/tlb.hh"
+
+class ThreadContext;
+
+/* ARM does not distinguish between a DTLB and an ITLB -> unified TLB
+   However, to maintain compatibility with other architectures, we'll
+   simply create an ITLB and DTLB that will point to the real TLB */
+namespace ArmISA {
+
+// WARN: This particular TLB entry is not necessarily conformed to ARM ISA
+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
+
+    ArmISA::PTE *table;        // the Page Table
+    int size;                  // TLB Size
+    int nlu;                   // not last used entry (for replacement)
+
+    void nextnlu() { if (++nlu >= size) nlu = 0; }
+    ArmISA::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 ArmTLBParams Params;
+    TLB(const Params *p);
+
+    int probeEntry(Addr vpn,uint8_t) const;
+    ArmISA::PTE *getEntry(unsigned) const;
+    virtual ~TLB();
+    int smallPages;
+    int getsize() const { return size; }
+
+    ArmISA::PTE &index(bool advance = true);
+    void insert(Addr vaddr, ArmISA::PTE &pte);
+    void insertAt(ArmISA::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);
+
+    // Checkpointing
+    void serialize(std::ostream &os);
+    void unserialize(Checkpoint *cp, const std::string &section);
+
+    void regStats();
+};
+
+class ITB : public TLB
+{
+  public:
+    typedef ArmTLBParams Params;
+    ITB(const Params *p);
+
+    Fault translateAtomic(RequestPtr req, ThreadContext *tc);
+    void translateTiming(RequestPtr req, ThreadContext *tc,
+            Translation *translation);
+};
+
+class DTB : public TLB
+{
+  public:
+    typedef ArmTLBParams Params;
+    DTB(const Params *p);
+
+    Fault translateAtomic(RequestPtr req, ThreadContext *tc, bool write);
+    void translateTiming(RequestPtr req, ThreadContext *tc,
+            Translation *translation, bool write);
+};
+
+class UTB : public ITB, public DTB
+{
+  public:
+    typedef ArmTLBParams Params;
+    UTB(const Params *p);
+
+};
+
+}
+
+#endif // __ARCH_ARM_TLB_HH__
diff --git a/src/arch/arm/types.hh b/src/arch/arm/types.hh
new file mode 100644 (file)
index 0000000..0a8d5d6
--- /dev/null
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2007-2008 The Florida State University
+ * 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
+ */
+
+#ifndef __ARCH_ARM_TYPES_HH__
+#define __ARCH_ARM_TYPES_HH__
+
+#include "sim/host.hh"
+
+namespace ArmISA
+{
+    typedef uint32_t MachInst;
+    typedef uint64_t ExtMachInst;
+    typedef uint8_t  RegIndex;
+
+    typedef uint64_t IntReg;
+    typedef uint64_t LargestRead;
+    // Need to use 64 bits to make sure that read requests get handled properly
+
+    // floating point register file entry type
+    typedef uint32_t FloatReg32;
+    typedef uint64_t FloatReg64;
+    typedef uint64_t FloatRegBits;
+
+    typedef double FloatRegVal;
+    typedef double FloatReg;
+
+    // cop-0/cop-1 system control register
+    typedef uint64_t MiscReg;
+
+    typedef union {
+        IntReg   intreg;
+        FloatReg fpreg;
+        MiscReg  ctrlreg;
+    } AnyReg;
+
+    typedef int RegContextParam;
+    typedef int RegContextVal;
+
+    //used in FP convert & round function
+    enum ConvertType{
+        SINGLE_TO_DOUBLE,
+        SINGLE_TO_WORD,
+        SINGLE_TO_LONG,
+
+        DOUBLE_TO_SINGLE,
+        DOUBLE_TO_WORD,
+        DOUBLE_TO_LONG,
+
+        LONG_TO_SINGLE,
+        LONG_TO_DOUBLE,
+        LONG_TO_WORD,
+        LONG_TO_PS,
+
+        WORD_TO_SINGLE,
+        WORD_TO_DOUBLE,
+        WORD_TO_LONG,
+        WORD_TO_PS,
+
+        PL_TO_SINGLE,
+        PU_TO_SINGLE
+    };
+
+    //used in FP convert & round function
+    enum RoundMode{
+        RND_ZERO,
+        RND_DOWN,
+        RND_UP,
+        RND_NEAREST
+    };
+
+    enum OperatingMode {
+        MODE_USER = 16,
+        MODE_FIQ = 17,
+        MODE_IRQ = 18,
+        MODE_SVC = 19,
+        MODE_ABORT = 23,
+        MODE_UNDEFINED = 27,
+        MODE_SYSTEM = 31
+    };
+
+    struct CoreSpecific {
+        // Empty for now on the ARM
+    };
+
+} // namespace ArmISA
+
+#endif
diff --git a/src/arch/arm/utility.cc b/src/arch/arm/utility.cc
new file mode 100644 (file)
index 0000000..83d7412
--- /dev/null
@@ -0,0 +1,201 @@
+/*
+ * Copyright (c) 2003-2006 The Regents of The University of Michigan
+ * Copyright (c) 2007-2008 The Florida State University
+ * 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
+ */
+
+#include "arch/arm/regfile.hh"
+#include "arch/arm/utility.hh"
+#include "base/misc.hh"
+#include "base/bitfield.hh"
+
+using namespace ArmISA;
+
+uint64_t
+ArmISA::fpConvert(ConvertType cvt_type, double fp_val)
+{
+
+    switch (cvt_type)
+    {
+      case SINGLE_TO_DOUBLE:
+        {
+            double sdouble_val = fp_val;
+            void  *sdouble_ptr = &sdouble_val;
+            uint64_t sdp_bits  = *(uint64_t *) sdouble_ptr;
+            return sdp_bits;
+        }
+
+      case SINGLE_TO_WORD:
+        {
+            int32_t sword_val  = (int32_t) fp_val;
+            void  *sword_ptr   = &sword_val;
+            uint64_t sword_bits= *(uint32_t *) sword_ptr;
+            return sword_bits;
+        }
+
+      case WORD_TO_SINGLE:
+        {
+            float wfloat_val   = fp_val;
+            void  *wfloat_ptr  = &wfloat_val;
+            uint64_t wfloat_bits = *(uint32_t *) wfloat_ptr;
+            return wfloat_bits;
+        }
+
+      case WORD_TO_DOUBLE:
+        {
+            double wdouble_val = fp_val;
+            void  *wdouble_ptr = &wdouble_val;
+            uint64_t wdp_bits  = *(uint64_t *) wdouble_ptr;
+            return wdp_bits;
+        }
+
+      default:
+        panic("Invalid Floating Point Conversion Type (%d). See \"types.hh\" for List of Conversions\n",cvt_type);
+        return 0;
+    }
+}
+
+double
+ArmISA::roundFP(double val, int digits)
+{
+    double digit_offset = pow(10.0,digits);
+    val = val * digit_offset;
+    val = val + 0.5;
+    val = floor(val);
+    val = val / digit_offset;
+    return val;
+}
+
+double
+ArmISA::truncFP(double val)
+{
+    int trunc_val = (int) val;
+    return (double) trunc_val;
+}
+
+bool
+ArmISA::getCondCode(uint32_t fcsr, int cc_idx)
+{
+    int shift = (cc_idx == 0) ? 23 : cc_idx + 24;
+    bool cc_val = (fcsr >> shift) & 0x00000001;
+    return cc_val;
+}
+
+uint32_t
+ArmISA::genCCVector(uint32_t fcsr, int cc_num, uint32_t cc_val)
+{
+    int cc_idx = (cc_num == 0) ? 23 : cc_num + 24;
+
+    fcsr = bits(fcsr, 31, cc_idx + 1) << (cc_idx + 1) |
+           cc_val << cc_idx |
+           bits(fcsr, cc_idx - 1, 0);
+
+    return fcsr;
+}
+
+uint32_t
+ArmISA::genInvalidVector(uint32_t fcsr_bits)
+{
+    //Set FCSR invalid in "flag" field
+    int invalid_offset = Invalid + Flag_Field;
+    fcsr_bits = fcsr_bits | (1 << invalid_offset);
+
+    //Set FCSR invalid in "cause" flag
+    int cause_offset = Invalid + Cause_Field;
+    fcsr_bits = fcsr_bits | (1 << cause_offset);
+
+    return fcsr_bits;
+}
+
+bool
+ArmISA::isNan(void *val_ptr, int size)
+{
+    switch (size)
+    {
+      case 32:
+        {
+            uint32_t val_bits = *(uint32_t *) val_ptr;
+            return (bits(val_bits, 30, 23) == 0xFF);
+        }
+
+      case 64:
+        {
+            uint64_t val_bits = *(uint64_t *) val_ptr;
+            return (bits(val_bits, 62, 52) == 0x7FF);
+        }
+
+      default:
+        panic("Type unsupported. Size mismatch\n");
+    }
+}
+
+
+bool
+ArmISA::isQnan(void *val_ptr, int size)
+{
+    switch (size)
+    {
+      case 32:
+        {
+            uint32_t val_bits = *(uint32_t *) val_ptr;
+            return (bits(val_bits, 30, 22) == 0x1FE);
+        }
+
+      case 64:
+        {
+            uint64_t val_bits = *(uint64_t *) val_ptr;
+            return (bits(val_bits, 62, 51) == 0xFFE);
+        }
+
+      default:
+        panic("Type unsupported. Size mismatch\n");
+    }
+}
+
+bool
+ArmISA::isSnan(void *val_ptr, int size)
+{
+    switch (size)
+    {
+      case 32:
+        {
+            uint32_t val_bits = *(uint32_t *) val_ptr;
+            return (bits(val_bits, 30, 22) == 0x1FF);
+        }
+
+      case 64:
+        {
+            uint64_t val_bits = *(uint64_t *) val_ptr;
+            return (bits(val_bits, 62, 51) == 0xFFF);
+        }
+
+      default:
+        panic("Type unsupported. Size mismatch\n");
+    }
+}
diff --git a/src/arch/arm/utility.hh b/src/arch/arm/utility.hh
new file mode 100644 (file)
index 0000000..fedf1fa
--- /dev/null
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2003-2005 The Regents of The University of Michigan
+ * Copyright (c) 2007-2008 The Florida State University
+ * 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
+ */
+
+#ifndef __ARCH_ARM_UTILITY_HH__
+#define __ARCH_ARM_UTILITY_HH__
+
+#include "arch/arm/types.hh"
+#include "base/misc.hh"
+#include "config/full_system.hh"
+#include "cpu/thread_context.hh"
+#include "sim/host.hh"
+
+class ThreadContext;
+
+namespace ArmISA {
+
+    //Floating Point Utility Functions
+    uint64_t fpConvert(ConvertType cvt_type, double fp_val);
+    double roundFP(double val, int digits);
+    double truncFP(double val);
+
+    bool getCondCode(uint32_t fcsr, int cc);
+    uint32_t genCCVector(uint32_t fcsr, int num, uint32_t cc_val);
+    uint32_t genInvalidVector(uint32_t fcsr);
+
+    bool isNan(void *val_ptr, int size);
+    bool isQnan(void *val_ptr, int size);
+    bool isSnan(void *val_ptr, int size);
+
+    /**
+     * Function to insure 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);
+    }
+};
+
+
+#endif
diff --git a/src/arch/arm/vtophys.cc b/src/arch/arm/vtophys.cc
new file mode 100644 (file)
index 0000000..086c034
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2002-2005 The Regents of The University of Michigan
+ * Copyright (c) 2007-2008 The Florida State University
+ * 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
+ */
+
+#include <string>
+
+#include "arch/arm/vtophys.hh"
+#include "base/chunk_generator.hh"
+#include "base/trace.hh"
+#include "cpu/thread_context.hh"
+#include "mem/vport.hh"
+
+using namespace std;
+using namespace ArmISA;
+
+Addr
+ArmISA::vtophys(Addr vaddr)
+{
+    Addr paddr = 0;
+    if (ArmISA::IsUSeg(vaddr))
+        DPRINTF(VtoPhys, "vtophys: invalid vaddr %#x", vaddr);
+    else if (ArmISA::IsKSeg0(vaddr))
+        paddr = ArmISA::KSeg02Phys(vaddr);
+    else
+        panic("vtophys: ptbr is not set on virtual lookup for vaddr %#x", vaddr);
+
+    DPRINTF(VtoPhys, "vtophys(%#x) -> %#x\n", vaddr, paddr);
+
+    return paddr;
+}
+
+Addr
+ArmISA::vtophys(ThreadContext *tc, Addr addr)
+{
+  fatal("VTOPHYS: Unimplemented on ARM\n");
+}
+
diff --git a/src/arch/arm/vtophys.hh b/src/arch/arm/vtophys.hh
new file mode 100644 (file)
index 0000000..edd2155
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2002-2005 The Regents of The University of Michigan
+ * Copyright (c) 2007-2008 The Florida State University
+ * 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
+ */
+
+#ifndef __ARCH_ARM_VTOPHYS_H__
+#define __ARCH_ARM_VTOPHYS_H__
+
+#include "arch/arm/isa_traits.hh"
+#include "arch/arm/utility.hh"
+
+
+class ThreadContext;
+class FunctionalPort;
+
+namespace ArmISA {
+    inline Addr PteAddr(Addr a) { return (a & PteMask) << PteShift; }
+
+    // User Virtual
+    inline bool IsUSeg(Addr a) { return USegBase <= a && a <= USegEnd; }
+
+    inline bool IsKSeg0(Addr a) { return KSeg0Base <= a && a <= KSeg0End; }
+
+    inline Addr KSeg02Phys(Addr addr) { return addr & KSeg0Mask; }
+
+    Addr vtophys(Addr vaddr);
+    Addr vtophys(ThreadContext *tc, Addr vaddr);
+};
+
+#endif // __ARCH_ARM_VTOPHYS_H__
+