summaryrefslogtreecommitdiff
path: root/src/arch
diff options
context:
space:
mode:
Diffstat (limited to 'src/arch')
-rw-r--r--src/arch/SConscript13
-rw-r--r--src/arch/alpha/ev5.cc3
-rw-r--r--src/arch/alpha/faults.hh2
-rw-r--r--src/arch/alpha/freebsd/system.cc4
-rw-r--r--src/arch/alpha/isa/mem.isa1
-rw-r--r--src/arch/alpha/isa_traits.hh289
-rw-r--r--src/arch/alpha/linux/linux.cc2
-rw-r--r--src/arch/alpha/linux/system.cc4
-rw-r--r--src/arch/alpha/pagetable.hh112
-rw-r--r--src/arch/alpha/process.cc2
-rw-r--r--src/arch/alpha/regfile.hh31
-rw-r--r--src/arch/alpha/syscallreturn.hh87
-rw-r--r--src/arch/alpha/system.cc4
-rw-r--r--src/arch/alpha/tlb.cc2
-rw-r--r--src/arch/alpha/tlb.hh4
-rw-r--r--src/arch/alpha/tru64/system.cc4
-rw-r--r--src/arch/alpha/types.hh9
-rw-r--r--src/arch/alpha/utility.hh2
-rw-r--r--src/arch/alpha/vtophys.hh18
-rw-r--r--src/arch/mips/faults.cc34
-rw-r--r--src/arch/mips/faults.hh3
-rw-r--r--src/arch/mips/isa/base.isa32
-rw-r--r--src/arch/mips/isa/decoder.isa5
-rw-r--r--src/arch/mips/isa/formats/basic.isa5
-rw-r--r--src/arch/mips/isa/formats/branch.isa6
-rw-r--r--src/arch/mips/isa/formats/int.isa1
-rw-r--r--src/arch/mips/isa/formats/mem.isa42
-rw-r--r--src/arch/mips/isa/formats/util.isa14
-rw-r--r--src/arch/mips/isa_traits.cc18
-rw-r--r--src/arch/mips/isa_traits.hh194
-rw-r--r--src/arch/mips/linux/linux.cc2
-rw-r--r--src/arch/mips/process.hh1
-rw-r--r--src/arch/mips/regfile.hh36
-rw-r--r--src/arch/mips/regfile/float_regfile.hh55
-rw-r--r--src/arch/mips/regfile/int_regfile.hh17
-rw-r--r--src/arch/mips/regfile/misc_regfile.hh172
-rw-r--r--src/arch/mips/regfile/regfile.hh10
-rw-r--r--src/arch/mips/syscallreturn.hh84
-rw-r--r--src/arch/mips/types.hh3
-rw-r--r--src/arch/mips/utility.cc7
-rw-r--r--src/arch/mips/utility.hh48
-rw-r--r--src/arch/sparc/SConscript11
-rw-r--r--src/arch/sparc/floatregfile.cc174
-rw-r--r--src/arch/sparc/floatregfile.hh83
-rw-r--r--src/arch/sparc/intregfile.cc133
-rw-r--r--src/arch/sparc/intregfile.hh103
-rw-r--r--src/arch/sparc/isa/base.isa32
-rw-r--r--src/arch/sparc/isa/decoder.isa305
-rw-r--r--src/arch/sparc/isa/formats/basic.isa6
-rw-r--r--src/arch/sparc/isa/formats/branch.isa109
-rw-r--r--src/arch/sparc/isa/formats/integerop.isa145
-rw-r--r--src/arch/sparc/isa/formats/priv.isa20
-rw-r--r--src/arch/sparc/isa/includes.isa6
-rw-r--r--src/arch/sparc/isa/operands.isa45
-rw-r--r--src/arch/sparc/isa_traits.hh106
-rw-r--r--src/arch/sparc/linux/linux.cc1
-rw-r--r--src/arch/sparc/linux/process.cc4
-rw-r--r--src/arch/sparc/linux/process.hh1
-rw-r--r--src/arch/sparc/miscregfile.cc540
-rw-r--r--src/arch/sparc/miscregfile.hh410
-rw-r--r--src/arch/sparc/process.cc65
-rw-r--r--src/arch/sparc/regfile.cc279
-rw-r--r--src/arch/sparc/regfile.hh825
-rw-r--r--src/arch/sparc/solaris/solaris.cc2
-rw-r--r--src/arch/sparc/stacktrace.hh6
-rw-r--r--src/arch/sparc/syscallreturn.hh92
-rw-r--r--src/arch/sparc/system.cc4
-rw-r--r--src/arch/sparc/types.hh63
-rw-r--r--src/arch/sparc/ua2005.cc10
69 files changed, 3468 insertions, 1494 deletions
diff --git a/src/arch/SConscript b/src/arch/SConscript
index bc517341a..59cea6211 100644
--- a/src/arch/SConscript
+++ b/src/arch/SConscript
@@ -48,12 +48,12 @@ sources = []
# List of headers to generate
isa_switch_hdrs = Split('''
arguments.hh
- constants.hh
faults.hh
isa_traits.hh
process.hh
regfile.hh
stacktrace.hh
+ syscallreturn.hh
tlb.hh
types.hh
utility.hh
@@ -140,8 +140,15 @@ def isa_desc_emitter(target, source, env):
# Pieces are in place, so create the builder.
python = sys.executable # use same Python binary used to run scons
-isa_desc_builder = Builder(action=python + ' $SOURCES $TARGET.dir $CPU_MODELS',
- emitter = isa_desc_emitter)
+
+# Also include the CheckerCPU as one of the models if it is being
+# enabled via command line.
+if env['USE_CHECKER']:
+ isa_desc_builder = Builder(action=python + ' $SOURCES $TARGET.dir $CPU_MODELS CheckerCPU',
+ emitter = isa_desc_emitter)
+else:
+ isa_desc_builder = Builder(action=python + ' $SOURCES $TARGET.dir $CPU_MODELS',
+ emitter = isa_desc_emitter)
env.Append(BUILDERS = { 'ISADesc' : isa_desc_builder })
diff --git a/src/arch/alpha/ev5.cc b/src/arch/alpha/ev5.cc
index ae3b668ea..796ed07de 100644
--- a/src/arch/alpha/ev5.cc
+++ b/src/arch/alpha/ev5.cc
@@ -29,9 +29,10 @@
* Nathan Binkert
*/
-#include "arch/alpha/tlb.hh"
+#include "arch/alpha/faults.hh"
#include "arch/alpha/isa_traits.hh"
#include "arch/alpha/osfpal.hh"
+#include "arch/alpha/tlb.hh"
#include "base/kgdb.h"
#include "base/remote_gdb.hh"
#include "base/stats/events.hh"
diff --git a/src/arch/alpha/faults.hh b/src/arch/alpha/faults.hh
index 11a568174..3ef4d5521 100644
--- a/src/arch/alpha/faults.hh
+++ b/src/arch/alpha/faults.hh
@@ -32,7 +32,7 @@
#ifndef __ALPHA_FAULTS_HH__
#define __ALPHA_FAULTS_HH__
-#include "arch/alpha/isa_traits.hh"
+#include "arch/alpha/pagetable.hh"
#include "sim/faults.hh"
// The design of the "name" and "vect" functions is in sim/faults.hh
diff --git a/src/arch/alpha/freebsd/system.cc b/src/arch/alpha/freebsd/system.cc
index 7cf68e0db..8d50e1612 100644
--- a/src/arch/alpha/freebsd/system.cc
+++ b/src/arch/alpha/freebsd/system.cc
@@ -97,6 +97,7 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(FreebsdAlphaSystem)
Param<Tick> boot_cpu_frequency;
SimObjectParam<PhysicalMemory *> physmem;
+ SimpleEnumParam<System::MemoryMode> mem_mode;
Param<string> kernel;
Param<string> console;
@@ -115,6 +116,8 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(FreebsdAlphaSystem)
INIT_PARAM(boot_cpu_frequency, "Frequency of the boot CPU"),
INIT_PARAM(physmem, "phsyical memory"),
+ INIT_ENUM_PARAM(mem_mode, "Memory Mode, (1=atomic, 2=timing)",
+ System::MemoryModeStrings),
INIT_PARAM(kernel, "file that contains the kernel code"),
INIT_PARAM(console, "file that contains the console code"),
INIT_PARAM(pal, "file that contains palcode"),
@@ -133,6 +136,7 @@ CREATE_SIM_OBJECT(FreebsdAlphaSystem)
p->name = getInstanceName();
p->boot_cpu_frequency = boot_cpu_frequency;
p->physmem = physmem;
+ p->mem_mode = mem_mode;
p->kernel_path = kernel;
p->console_path = console;
p->palcode = pal;
diff --git a/src/arch/alpha/isa/mem.isa b/src/arch/alpha/isa/mem.isa
index 08a0a2343..a5dda7fc6 100644
--- a/src/arch/alpha/isa/mem.isa
+++ b/src/arch/alpha/isa/mem.isa
@@ -668,7 +668,6 @@ def LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
+ completeAccTemplate.subst(completeacc_iop))
}};
-
def format LoadOrNop(memacc_code, ea_code = {{ EA = Rb + disp; }},
mem_flags = [], inst_flags = []) {{
(header_output, decoder_output, decode_block, exec_output) = \
diff --git a/src/arch/alpha/isa_traits.hh b/src/arch/alpha/isa_traits.hh
index 663b144ab..72e38ae3e 100644
--- a/src/arch/alpha/isa_traits.hh
+++ b/src/arch/alpha/isa_traits.hh
@@ -35,81 +35,252 @@
namespace LittleEndianGuest {}
#include "arch/alpha/types.hh"
-#include "arch/alpha/constants.hh"
-#include "arch/alpha/regfile.hh"
#include "config/full_system.hh"
#include "sim/host.hh"
class StaticInstPtr;
-#if !FULL_SYSTEM
-class SyscallReturn {
- public:
- template <class T>
- SyscallReturn(T v, bool s)
- {
- retval = (uint64_t)v;
- success = s;
- }
-
- template <class T>
- SyscallReturn(T v)
- {
- success = (v >= 0);
- retval = (uint64_t)v;
- }
-
- ~SyscallReturn() {}
-
- SyscallReturn& operator=(const SyscallReturn& s) {
- retval = s.retval;
- success = s.success;
- return *this;
- }
-
- bool successful() { return success; }
- uint64_t value() { return retval; }
-
-
- private:
- uint64_t retval;
- bool success;
-};
+namespace AlphaISA
+{
+
+ using namespace LittleEndianGuest;
+
+ // These enumerate all the registers for dependence tracking.
+ enum DependenceTags {
+ // 0..31 are the integer regs 0..31
+ // 32..63 are the FP regs 0..31, i.e. use (reg + FP_Base_DepTag)
+ FP_Base_DepTag = 40,
+ Ctrl_Base_DepTag = 72,
+ Fpcr_DepTag = 72, // floating point control register
+ Uniq_DepTag = 73,
+ Lock_Flag_DepTag = 74,
+ Lock_Addr_DepTag = 75,
+ IPR_Base_DepTag = 76
+ };
+
+ StaticInstPtr decodeInst(ExtMachInst);
+
+ const Addr PageShift = 13;
+ const Addr PageBytes = ULL(1) << PageShift;
+ const Addr PageMask = ~(PageBytes - 1);
+ const Addr PageOffset = PageBytes - 1;
-#endif
#if FULL_SYSTEM
-#include "arch/alpha/isa_fullsys_traits.hh"
-#endif
+ ////////////////////////////////////////////////////////////////////////
+ //
+ // Translation stuff
+ //
-namespace AlphaISA
-{
+ const Addr PteShift = 3;
+ const Addr NPtePageShift = PageShift - PteShift;
+ const Addr NPtePage = ULL(1) << NPtePageShift;
+ const Addr PteMask = NPtePage - 1;
-using namespace LittleEndianGuest;
+ // User Virtual
+ const Addr USegBase = ULL(0x0);
+ const Addr USegEnd = ULL(0x000003ffffffffff);
-// redirected register map, really only used for the full system case.
-extern const int reg_redir[NumIntRegs];
+ // Kernel Direct Mapped
+ const Addr K0SegBase = ULL(0xfffffc0000000000);
+ const Addr K0SegEnd = ULL(0xfffffdffffffffff);
- StaticInstPtr decodeInst(ExtMachInst);
+ // Kernel Virtual
+ const Addr K1SegBase = ULL(0xfffffe0000000000);
+ const Addr K1SegEnd = ULL(0xffffffffffffffff);
+
+ // For loading... XXX This maybe could be USegEnd?? --ali
+ const Addr LoadAddrMask = ULL(0xffffffffff);
+
+ ////////////////////////////////////////////////////////////////////////
+ //
+ // Interrupt levels
+ //
+ enum InterruptLevels
+ {
+ INTLEVEL_SOFTWARE_MIN = 4,
+ INTLEVEL_SOFTWARE_MAX = 19,
+
+ INTLEVEL_EXTERNAL_MIN = 20,
+ INTLEVEL_EXTERNAL_MAX = 34,
+
+ INTLEVEL_IRQ0 = 20,
+ INTLEVEL_IRQ1 = 21,
+ INTINDEX_ETHERNET = 0,
+ INTINDEX_SCSI = 1,
+ INTLEVEL_IRQ2 = 22,
+ INTLEVEL_IRQ3 = 23,
+
+ INTLEVEL_SERIAL = 33,
+
+ NumInterruptLevels = INTLEVEL_EXTERNAL_MAX
+ };
+
+
+ // EV5 modes
+ enum mode_type
+ {
+ mode_kernel = 0, // kernel
+ mode_executive = 1, // executive (unused by unix)
+ mode_supervisor = 2, // supervisor (unused by unix)
+ mode_user = 3, // user mode
+ mode_number // number of modes
+ };
+
+#endif
-#if !FULL_SYSTEM
- static inline void setSyscallReturn(SyscallReturn return_value, RegFile *regs)
+#if FULL_SYSTEM
+ ////////////////////////////////////////////////////////////////////////
+ //
+ // Internal Processor Reigsters
+ //
+ enum md_ipr_names
{
- // check for error condition. Alpha syscall convention is to
- // indicate success/failure in reg a3 (r19) and put the
- // return value itself in the standard return value reg (v0).
- if (return_value.successful()) {
- // no error
- regs->setIntReg(SyscallSuccessReg, 0);
- regs->setIntReg(ReturnValueReg, return_value.value());
- } else {
- // got an error, return details
- regs->setIntReg(SyscallSuccessReg, (IntReg)-1);
- regs->setIntReg(ReturnValueReg, -return_value.value());
- }
- }
+ IPR_ISR = 0x100, // interrupt summary register
+ IPR_ITB_TAG = 0x101, // ITLB tag register
+ IPR_ITB_PTE = 0x102, // ITLB page table entry register
+ IPR_ITB_ASN = 0x103, // ITLB address space register
+ IPR_ITB_PTE_TEMP = 0x104, // ITLB page table entry temp register
+ IPR_ITB_IA = 0x105, // ITLB invalidate all register
+ IPR_ITB_IAP = 0x106, // ITLB invalidate all process register
+ IPR_ITB_IS = 0x107, // ITLB invalidate select register
+ IPR_SIRR = 0x108, // software interrupt request register
+ IPR_ASTRR = 0x109, // asynchronous system trap request register
+ IPR_ASTER = 0x10a, // asynchronous system trap enable register
+ IPR_EXC_ADDR = 0x10b, // exception address register
+ IPR_EXC_SUM = 0x10c, // exception summary register
+ IPR_EXC_MASK = 0x10d, // exception mask register
+ IPR_PAL_BASE = 0x10e, // PAL base address register
+ IPR_ICM = 0x10f, // instruction current mode
+ IPR_IPLR = 0x110, // interrupt priority level register
+ IPR_INTID = 0x111, // interrupt ID register
+ IPR_IFAULT_VA_FORM = 0x112, // formatted faulting virtual addr register
+ IPR_IVPTBR = 0x113, // virtual page table base register
+ IPR_HWINT_CLR = 0x115, // H/W interrupt clear register
+ IPR_SL_XMIT = 0x116, // serial line transmit register
+ IPR_SL_RCV = 0x117, // serial line receive register
+ IPR_ICSR = 0x118, // instruction control and status register
+ IPR_IC_FLUSH = 0x119, // instruction cache flush control
+ IPR_IC_PERR_STAT = 0x11a, // inst cache parity error status register
+ IPR_PMCTR = 0x11c, // performance counter register
+
+ // PAL temporary registers...
+ // register meanings gleaned from osfpal.s source code
+ IPR_PALtemp0 = 0x140, // local scratch
+ IPR_PALtemp1 = 0x141, // local scratch
+ IPR_PALtemp2 = 0x142, // entUna
+ IPR_PALtemp3 = 0x143, // CPU specific impure area pointer
+ IPR_PALtemp4 = 0x144, // memory management temp
+ IPR_PALtemp5 = 0x145, // memory management temp
+ IPR_PALtemp6 = 0x146, // memory management temp
+ IPR_PALtemp7 = 0x147, // entIF
+ IPR_PALtemp8 = 0x148, // intmask
+ IPR_PALtemp9 = 0x149, // entSys
+ IPR_PALtemp10 = 0x14a, // ??
+ IPR_PALtemp11 = 0x14b, // entInt
+ IPR_PALtemp12 = 0x14c, // entArith
+ IPR_PALtemp13 = 0x14d, // reserved for platform specific PAL
+ IPR_PALtemp14 = 0x14e, // reserved for platform specific PAL
+ IPR_PALtemp15 = 0x14f, // reserved for platform specific PAL
+ IPR_PALtemp16 = 0x150, // scratch / whami<7:0> / mces<4:0>
+ IPR_PALtemp17 = 0x151, // sysval
+ IPR_PALtemp18 = 0x152, // usp
+ IPR_PALtemp19 = 0x153, // ksp
+ IPR_PALtemp20 = 0x154, // PTBR
+ IPR_PALtemp21 = 0x155, // entMM
+ IPR_PALtemp22 = 0x156, // kgp
+ IPR_PALtemp23 = 0x157, // PCBB
+
+ IPR_DTB_ASN = 0x200, // DTLB address space number register
+ IPR_DTB_CM = 0x201, // DTLB current mode register
+ IPR_DTB_TAG = 0x202, // DTLB tag register
+ IPR_DTB_PTE = 0x203, // DTLB page table entry register
+ IPR_DTB_PTE_TEMP = 0x204, // DTLB page table entry temporary register
+
+ IPR_MM_STAT = 0x205, // data MMU fault status register
+ IPR_VA = 0x206, // fault virtual address register
+ IPR_VA_FORM = 0x207, // formatted virtual address register
+ IPR_MVPTBR = 0x208, // MTU virtual page table base register
+ IPR_DTB_IAP = 0x209, // DTLB invalidate all process register
+ IPR_DTB_IA = 0x20a, // DTLB invalidate all register
+ IPR_DTB_IS = 0x20b, // DTLB invalidate single register
+ IPR_ALT_MODE = 0x20c, // alternate mode register
+ IPR_CC = 0x20d, // cycle counter register
+ IPR_CC_CTL = 0x20e, // cycle counter control register
+ IPR_MCSR = 0x20f, // MTU control register
+
+ IPR_DC_FLUSH = 0x210,
+ IPR_DC_PERR_STAT = 0x212, // Dcache parity error status register
+ IPR_DC_TEST_CTL = 0x213, // Dcache test tag control register
+ IPR_DC_TEST_TAG = 0x214, // Dcache test tag register
+ IPR_DC_TEST_TAG_TEMP = 0x215, // Dcache test tag temporary register
+ IPR_DC_MODE = 0x216, // Dcache mode register
+ IPR_MAF_MODE = 0x217, // miss address file mode register
+
+ NumInternalProcRegs // number of IPR registers
+ };
+#else
+ const int NumInternalProcRegs = 0;
#endif
+
+ // Constants Related to the number of registers
+
+ const int NumIntArchRegs = 32;
+ const int NumPALShadowRegs = 8;
+ const int NumFloatArchRegs = 32;
+ // @todo: Figure out what this number really should be.
+ const int NumMiscArchRegs = 32;
+
+ const int NumIntRegs = NumIntArchRegs + NumPALShadowRegs;
+ const int NumFloatRegs = NumFloatArchRegs;
+ const int NumMiscRegs = NumMiscArchRegs;
+
+ const int TotalNumRegs = NumIntRegs + NumFloatRegs +
+ NumMiscRegs + NumInternalProcRegs;
+
+ const int TotalDataRegs = NumIntRegs + NumFloatRegs;
+
+ // Static instruction parameters
+ const int MaxInstSrcRegs = 3;
+ const int MaxInstDestRegs = 2;
+
+ // semantically meaningful register indices
+ const int ZeroReg = 31; // architecturally meaningful
+ // the rest of these depend on the ABI
+ const int StackPointerReg = 30;
+ const int GlobalPointerReg = 29;
+ const int ProcedureValueReg = 27;
+ const int ReturnAddressReg = 26;
+ const int ReturnValueReg = 0;
+ const int FramePointerReg = 15;
+ const int ArgumentReg0 = 16;
+ const int ArgumentReg1 = 17;
+ const int ArgumentReg2 = 18;
+ const int ArgumentReg3 = 19;
+ const int ArgumentReg4 = 20;
+ const int ArgumentReg5 = 21;
+ const int SyscallNumReg = ReturnValueReg;
+ const int SyscallPseudoReturnReg = ArgumentReg4;
+ const int SyscallSuccessReg = 19;
+
+ const int LogVMPageSize = 13; // 8K bytes
+ const int VMPageSize = (1 << LogVMPageSize);
+
+ const int BranchPredAddrShiftAmt = 2; // instructions are 4-byte aligned
+
+ const int MachineBytes = 8;
+ const int WordBytes = 4;
+ const int HalfwordBytes = 2;
+ const int ByteBytes = 1;
+
+ // return a no-op instruction... used for instruction fetch faults
+ // Alpha UNOP (ldq_u r31,0(r0))
+ const ExtMachInst NoopMachInst = 0x2ffe0000;
+
+ // redirected register map, really only used for the full system case.
+ extern const int reg_redir[NumIntRegs];
+
};
#endif // __ARCH_ALPHA_ISA_TRAITS_HH__
diff --git a/src/arch/alpha/linux/linux.cc b/src/arch/alpha/linux/linux.cc
index bc0d48e0d..e6908a572 100644
--- a/src/arch/alpha/linux/linux.cc
+++ b/src/arch/alpha/linux/linux.cc
@@ -30,6 +30,8 @@
#include "arch/alpha/linux/linux.hh"
+#include <fcntl.h>
+
// open(2) flags translation table
OpenFlagTransTable AlphaLinux::openFlagTable[] = {
#ifdef _MSC_VER
diff --git a/src/arch/alpha/linux/system.cc b/src/arch/alpha/linux/system.cc
index 9fe63c390..ef4e18cb5 100644
--- a/src/arch/alpha/linux/system.cc
+++ b/src/arch/alpha/linux/system.cc
@@ -191,6 +191,7 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(LinuxAlphaSystem)
Param<Tick> boot_cpu_frequency;
SimObjectParam<PhysicalMemory *> physmem;
+ SimpleEnumParam<System::MemoryMode> mem_mode;
Param<string> kernel;
Param<string> console;
@@ -209,6 +210,8 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(LinuxAlphaSystem)
INIT_PARAM(boot_cpu_frequency, "Frequency of the boot CPU"),
INIT_PARAM(physmem, "phsyical memory"),
+ INIT_ENUM_PARAM(mem_mode, "Memory Mode, (1=atomic, 2=timing)",
+ System::MemoryModeStrings),
INIT_PARAM(kernel, "file that contains the kernel code"),
INIT_PARAM(console, "file that contains the console code"),
INIT_PARAM(pal, "file that contains palcode"),
@@ -227,6 +230,7 @@ CREATE_SIM_OBJECT(LinuxAlphaSystem)
p->name = getInstanceName();
p->boot_cpu_frequency = boot_cpu_frequency;
p->physmem = physmem;
+ p->mem_mode = mem_mode;
p->kernel_path = kernel;
p->console_path = console;
p->palcode = pal;
diff --git a/src/arch/alpha/pagetable.hh b/src/arch/alpha/pagetable.hh
new file mode 100644
index 000000000..3108c0a3e
--- /dev/null
+++ b/src/arch/alpha/pagetable.hh
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 2002-2005 The Regents of The University of Michigan
+ * 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
+ */
+
+#ifndef __ARCH_ALPHA_PAGETABLE_H__
+#define __ARCH_ALPHA_PAGETABLE_H__
+
+#include "arch/alpha/isa_traits.hh"
+#include "arch/alpha/utility.hh"
+#include "config/full_system.hh"
+
+namespace AlphaISA {
+
+#if FULL_SYSTEM
+ 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 & PageMask; }
+ Addr offset() const { return addr & PageOffset; }
+
+ Addr level3() const
+ { return AlphaISA::PteAddr(addr >> PageShift); }
+ Addr level2() const
+ { return AlphaISA::PteAddr(addr >> NPtePageShift + PageShift); }
+ Addr level1() const
+ { return AlphaISA::PteAddr(addr >> 2 * NPtePageShift + PageShift); }
+ };
+
+ struct PageTableEntry
+ {
+ PageTableEntry(uint64_t e) : entry(e) {}
+ uint64_t entry;
+ operator uint64_t() const { return entry; }
+ const PageTableEntry &operator=(uint64_t e) { entry = e; return *this; }
+ const PageTableEntry &operator=(const PageTableEntry &e)
+ { entry = e.entry; return *this; }
+
+ Addr _pfn() const { return (entry >> 32) & 0xffffffff; }
+ Addr _sw() const { return (entry >> 16) & 0xffff; }
+ int _rsv0() const { return (entry >> 14) & 0x3; }
+ bool _uwe() const { return (entry >> 13) & 0x1; }
+ bool _kwe() const { return (entry >> 12) & 0x1; }
+ int _rsv1() const { return (entry >> 10) & 0x3; }
+ bool _ure() const { return (entry >> 9) & 0x1; }
+ bool _kre() const { return (entry >> 8) & 0x1; }
+ bool _nomb() const { return (entry >> 7) & 0x1; }
+ int _gh() const { return (entry >> 5) & 0x3; }
+ bool _asm() const { return (entry >> 4) & 0x1; }
+ bool _foe() const { return (entry >> 3) & 0x1; }
+ bool _fow() const { return (entry >> 2) & 0x1; }
+ bool _for() const { return (entry >> 1) & 0x1; }
+ bool valid() const { return (entry >> 0) & 0x1; }
+
+ Addr paddr() const { return _pfn() << PageShift; }
+ };
+
+ // ITB/DTB page table entry
+ struct PTE
+ {
+ Addr tag; // virtual page number tag
+ Addr ppn; // physical page number
+ uint8_t xre; // read permissions - VMEM_PERM_* mask
+ uint8_t xwe; // write permissions - VMEM_PERM_* mask
+ uint8_t asn; // address space number
+ bool asma; // address space match
+ bool fonr; // fault on read
+ bool fonw; // fault on write
+ bool valid; // valid page table entry
+
+ void serialize(std::ostream &os);
+ void unserialize(Checkpoint *cp, const std::string &section);
+ };
+#endif
+};
+#endif // __ARCH_ALPHA_PAGETABLE_H__
+
diff --git a/src/arch/alpha/process.cc b/src/arch/alpha/process.cc
index 970292cd8..32fb97229 100644
--- a/src/arch/alpha/process.cc
+++ b/src/arch/alpha/process.cc
@@ -29,7 +29,7 @@
* Ali Saidi
*/
-#include "arch/alpha/constants.hh"
+#include "arch/alpha/isa_traits.hh"
#include "arch/alpha/process.hh"
#include "base/loader/object_file.hh"
#include "base/misc.hh"
diff --git a/src/arch/alpha/regfile.hh b/src/arch/alpha/regfile.hh
index 9ecad6f42..43b48a0ab 100644
--- a/src/arch/alpha/regfile.hh
+++ b/src/arch/alpha/regfile.hh
@@ -32,14 +32,34 @@
#define __ARCH_ALPHA_REGFILE_HH__
#include "arch/alpha/types.hh"
-#include "arch/alpha/constants.hh"
+#include "arch/alpha/isa_traits.hh"
#include "sim/faults.hh"
+#include <string>
+
+//XXX These should be implemented by someone who knows the alpha stuff better
+
class Checkpoint;
class ThreadContext;
namespace AlphaISA
{
+
+ static inline std::string getIntRegName(RegIndex)
+ {
+ return "";
+ }
+
+ static inline std::string getFloatRegName(RegIndex)
+ {
+ return "";
+ }
+
+ static inline std::string getMiscRegName(RegIndex)
+ {
+ return "";
+ }
+
class IntRegFile
{
protected:
@@ -268,14 +288,7 @@ namespace AlphaISA
void serialize(std::ostream &os);
void unserialize(Checkpoint *cp, const std::string &section);
- enum ContextParam
- {
- CONTEXT_PALMODE
- };
-
- typedef bool ContextVal;
-
- void changeContext(ContextParam param, ContextVal val)
+ void changeContext(RegContextParam param, RegContextVal val)
{
//This would be an alternative place to call/implement
//the swapPALShadow function
diff --git a/src/arch/alpha/syscallreturn.hh b/src/arch/alpha/syscallreturn.hh
new file mode 100644
index 000000000..803c3b7da
--- /dev/null
+++ b/src/arch/alpha/syscallreturn.hh
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2003-2005 The Regents of The University of Michigan
+ * 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
+ * Gabe Black
+ */
+
+#ifndef __ARCH_ALPHA_SYSCALLRETURN_HH__
+#define __ARCH_ALPHA_SYSCALLRETURN_HH__
+
+class SyscallReturn {
+ public:
+ template <class T>
+ SyscallReturn(T v, bool s)
+ {
+ retval = (uint64_t)v;
+ success = s;
+ }
+
+ template <class T>
+ SyscallReturn(T v)
+ {
+ success = (v >= 0);
+ retval = (uint64_t)v;
+ }
+
+ ~SyscallReturn() {}
+
+ SyscallReturn& operator=(const SyscallReturn& s) {
+ retval = s.retval;
+ success = s.success;
+ return *this;
+ }
+
+ bool successful() { return success; }
+ uint64_t value() { return retval; }
+
+
+ private:
+ uint64_t retval;
+ bool success;
+};
+
+namespace AlphaISA
+{
+ static inline void setSyscallReturn(SyscallReturn return_value, RegFile *regs)
+ {
+ // check for error condition. Alpha syscall convention is to
+ // indicate success/failure in reg a3 (r19) and put the
+ // return value itself in the standard return value reg (v0).
+ if (return_value.successful()) {
+ // no error
+ regs->setIntReg(SyscallSuccessReg, 0);
+ regs->setIntReg(ReturnValueReg, return_value.value());
+ } else {
+ // got an error, return details
+ regs->setIntReg(SyscallSuccessReg, (IntReg)-1);
+ regs->setIntReg(ReturnValueReg, -return_value.value());
+ }
+ }
+}
+
+#endif
diff --git a/src/arch/alpha/system.cc b/src/arch/alpha/system.cc
index dce7365aa..a7e615531 100644
--- a/src/arch/alpha/system.cc
+++ b/src/arch/alpha/system.cc
@@ -221,6 +221,7 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(AlphaSystem)
Param<Tick> boot_cpu_frequency;
SimObjectParam<PhysicalMemory *> physmem;
+ SimpleEnumParam<System::MemoryMode> mem_mode;
Param<std::string> kernel;
Param<std::string> console;
@@ -239,6 +240,8 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(AlphaSystem)
INIT_PARAM(boot_cpu_frequency, "Frequency of the boot CPU"),
INIT_PARAM(physmem, "phsyical memory"),
+ INIT_ENUM_PARAM(mem_mode, "Memory Mode, (1=atomic, 2=timing)",
+ System::MemoryModeStrings),
INIT_PARAM(kernel, "file that contains the kernel code"),
INIT_PARAM(console, "file that contains the console code"),
INIT_PARAM(pal, "file that contains palcode"),
@@ -257,6 +260,7 @@ CREATE_SIM_OBJECT(AlphaSystem)
p->name = getInstanceName();
p->boot_cpu_frequency = boot_cpu_frequency;
p->physmem = physmem;
+ p->mem_mode = mem_mode;
p->kernel_path = kernel;
p->console_path = console;
p->palcode = pal;
diff --git a/src/arch/alpha/tlb.cc b/src/arch/alpha/tlb.cc
index c6684274b..bab44c434 100644
--- a/src/arch/alpha/tlb.cc
+++ b/src/arch/alpha/tlb.cc
@@ -33,7 +33,9 @@
#include <string>
#include <vector>
+#include "arch/alpha/pagetable.hh"
#include "arch/alpha/tlb.hh"
+#include "arch/alpha/faults.hh"
#include "base/inifile.hh"
#include "base/str.hh"
#include "base/trace.hh"
diff --git a/src/arch/alpha/tlb.hh b/src/arch/alpha/tlb.hh
index 07d01fa5c..955460649 100644
--- a/src/arch/alpha/tlb.hh
+++ b/src/arch/alpha/tlb.hh
@@ -36,9 +36,11 @@
#include "arch/alpha/ev5.hh"
#include "arch/alpha/isa_traits.hh"
-#include "arch/alpha/faults.hh"
+#include "arch/alpha/utility.hh"
+#include "arch/alpha/vtophys.hh"
#include "base/statistics.hh"
#include "mem/request.hh"
+#include "sim/faults.hh"
#include "sim/sim_object.hh"
class ThreadContext;
diff --git a/src/arch/alpha/tru64/system.cc b/src/arch/alpha/tru64/system.cc
index 6c0edc1ee..3ef1e4d3c 100644
--- a/src/arch/alpha/tru64/system.cc
+++ b/src/arch/alpha/tru64/system.cc
@@ -95,6 +95,7 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(Tru64AlphaSystem)
Param<Tick> boot_cpu_frequency;
SimObjectParam<PhysicalMemory *> physmem;
+ SimpleEnumParam<System::MemoryMode> mem_mode;
Param<string> kernel;
Param<string> console;
@@ -113,6 +114,8 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(Tru64AlphaSystem)
INIT_PARAM(boot_cpu_frequency, "frequency of the boot cpu"),
INIT_PARAM(physmem, "phsyical memory"),
+ INIT_ENUM_PARAM(mem_mode, "Memory Mode, (1=atomic, 2=timing)",
+ System::MemoryModeStrings),
INIT_PARAM(kernel, "file that contains the kernel code"),
INIT_PARAM(console, "file that contains the console code"),
INIT_PARAM(pal, "file that contains palcode"),
@@ -131,6 +134,7 @@ CREATE_SIM_OBJECT(Tru64AlphaSystem)
p->name = getInstanceName();
p->boot_cpu_frequency = boot_cpu_frequency;
p->physmem = physmem;
+ p->mem_mode = mem_mode;
p->kernel_path = kernel;
p->console_path = console;
p->palcode = pal;
diff --git a/src/arch/alpha/types.hh b/src/arch/alpha/types.hh
index 5859052e9..ae42552d8 100644
--- a/src/arch/alpha/types.hh
+++ b/src/arch/alpha/types.hh
@@ -32,7 +32,7 @@
#ifndef __ARCH_ALPHA_TYPES_HH__
#define __ARCH_ALPHA_TYPES_HH__
-#include "sim/host.hh"
+#include <inttypes.h>
namespace AlphaISA
{
@@ -56,6 +56,13 @@ namespace AlphaISA
MiscReg ctrlreg;
} AnyReg;
+ enum RegContextParam
+ {
+ CONTEXT_PALMODE
+ };
+
+ typedef bool RegContextVal;
+
enum annotes {
ANNOTE_NONE = 0,
// An impossible number for instruction annotations
diff --git a/src/arch/alpha/utility.hh b/src/arch/alpha/utility.hh
index ec136091c..d3ccc0444 100644
--- a/src/arch/alpha/utility.hh
+++ b/src/arch/alpha/utility.hh
@@ -34,7 +34,7 @@
#include "config/full_system.hh"
#include "arch/alpha/types.hh"
-#include "arch/alpha/constants.hh"
+#include "arch/alpha/isa_traits.hh"
#include "arch/alpha/regfile.hh"
#include "base/misc.hh"
diff --git a/src/arch/alpha/vtophys.hh b/src/arch/alpha/vtophys.hh
index 472c694ff..32b999c37 100644
--- a/src/arch/alpha/vtophys.hh
+++ b/src/arch/alpha/vtophys.hh
@@ -33,22 +33,24 @@
#define __ARCH_ALPHA_VTOPHYS_H__
#include "arch/alpha/isa_traits.hh"
+#include "arch/alpha/pagetable.hh"
+#include "arch/alpha/utility.hh"
class ThreadContext;
class FunctionalPort;
namespace AlphaISA {
-PageTableEntry
-kernel_pte_lookup(FunctionalPort *mem, Addr ptbr, AlphaISA::VAddr vaddr);
+ PageTableEntry
+ kernel_pte_lookup(FunctionalPort *mem, Addr ptbr, AlphaISA::VAddr vaddr);
-Addr vtophys(Addr vaddr);
-Addr vtophys(ThreadContext *tc, Addr vaddr);
+ Addr vtophys(Addr vaddr);
+ Addr vtophys(ThreadContext *tc, Addr vaddr);
-void CopyOut(ThreadContext *tc, void *dst, Addr src, size_t len);
-void CopyIn(ThreadContext *tc, Addr dst, void *src, size_t len);
-void CopyStringOut(ThreadContext *tc, char *dst, Addr vaddr, size_t maxlen);
-void CopyStringIn(ThreadContext *tc, char *src, Addr vaddr);
+ void CopyOut(ThreadContext *tc, void *dst, Addr src, size_t len);
+ void CopyIn(ThreadContext *tc, Addr dst, void *src, size_t len);
+ void CopyStringOut(ThreadContext *tc, char *dst, Addr vaddr, size_t maxlen);
+ void CopyStringIn(ThreadContext *tc, char *src, Addr vaddr);
};
#endif // __ARCH_ALPHA_VTOPHYS_H__
diff --git a/src/arch/mips/faults.cc b/src/arch/mips/faults.cc
index cfeb045eb..2a8ab1df5 100644
--- a/src/arch/mips/faults.cc
+++ b/src/arch/mips/faults.cc
@@ -25,13 +25,15 @@
* (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
+ * Authors: Gabe Black
+ * Korey Sewell
*/
#include "arch/mips/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"
@@ -110,35 +112,6 @@ FaultName IntegerOverflowFault::_name = "intover";
FaultVect IntegerOverflowFault::_vect = 0x0501;
FaultStat IntegerOverflowFault::_count;
-#if FULL_SYSTEM
-
-void MipsFault::invoke(ThreadContext * tc)
-{
- FaultBase::invoke(tc);
- countStat()++;
-
- // exception restart address
- if (setRestartAddress() || !tc->inPalMode())
- tc->setMiscReg(MipsISA::IPR_EXC_ADDR, tc->readPC());
-
- if (skipFaultingInstruction()) {
- // traps... skip faulting instruction.
- tc->setMiscReg(MipsISA::IPR_EXC_ADDR,
- tc->readMiscReg(MipsISA::IPR_EXC_ADDR) + 4);
- }
-
- tc->setPC(tc->readMiscReg(MipsISA::IPR_PAL_BASE) + vect());
- tc->setNextPC(tc->readPC() + sizeof(MachInst));
-}
-
-void ArithmeticFault::invoke(ThreadContext * tc)
-{
- FaultBase::invoke(tc);
- panic("Arithmetic traps are unimplemented!");
-}
-
-#else //!FULL_SYSTEM
-
void PageTableFault::invoke(ThreadContext *tc)
{
Process *p = tc->getProcessPtr();
@@ -159,6 +132,5 @@ void PageTableFault::invoke(ThreadContext *tc)
}
}
-#endif
} // namespace MipsISA
diff --git a/src/arch/mips/faults.hh b/src/arch/mips/faults.hh
index 95c61cfbc..9d2c5df32 100644
--- a/src/arch/mips/faults.hh
+++ b/src/arch/mips/faults.hh
@@ -25,7 +25,8 @@
* (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
+ * Authors: Gabe Black
+ * Korey Sewell
*/
#ifndef __MIPS_FAULTS_HH__
diff --git a/src/arch/mips/isa/base.isa b/src/arch/mips/isa/base.isa
index f07b06e03..7c042f16f 100644
--- a/src/arch/mips/isa/base.isa
+++ b/src/arch/mips/isa/base.isa
@@ -79,21 +79,27 @@ output decoder {{
ccprintf(ss, "%-10s ", mnemonic);
- if(_numDestRegs > 0){
- printReg(ss, _destRegIdx[0]);
+ // Need to find standard way to not print
+ // this info. Maybe add bool variable to
+ // class?
+ if (mnemonic != "syscall") {
+ if(_numDestRegs > 0){
+ printReg(ss, _destRegIdx[0]);
+ }
+
+ if(_numSrcRegs > 0) {
+ ss << ", ";
+ printReg(ss, _srcRegIdx[0]);
+ }
+
+ if(_numSrcRegs > 1) {
+ ss << ", ";
+ printReg(ss, _srcRegIdx[1]);
+ }
}
- if(_numSrcRegs > 0) {
- ss << ", ";
- printReg(ss, _srcRegIdx[0]);
- }
-
- if(_numSrcRegs > 1) {
- ss << ", ";
- printReg(ss, _srcRegIdx[1]);
- }
-
-
+ // Should we define a separate inst. class
+ // just for two insts?
if(mnemonic == "sll" || mnemonic == "sra"){
ccprintf(ss,", %d",SA);
}
diff --git a/src/arch/mips/isa/decoder.isa b/src/arch/mips/isa/decoder.isa
index 9ac982e34..d65e3eb94 100644
--- a/src/arch/mips/isa/decoder.isa
+++ b/src/arch/mips/isa/decoder.isa
@@ -133,7 +133,8 @@ decode OPCODE_HI default Unknown::unknown() {
format BasicOp {
0x2: movz({{ Rd = (Rt == 0) ? Rs : Rd; }});
0x3: movn({{ Rd = (Rt != 0) ? Rs : Rd; }});
- 0x4: syscall({{ xc->syscall(R2); }}, IsNonSpeculative);
+ 0x4: syscall({{ xc->syscall(R2); }},
+ IsSerializeAfter, IsNonSpeculative);
0x7: sync({{ ; }}, IsMemBarrier);
}
@@ -1089,7 +1090,7 @@ decode OPCODE_HI default Unknown::unknown() {
0x0: StoreCond::sc({{ Mem.uw = Rt.uw;}},
{{ uint64_t tmp = write_result;
Rt.uw = (tmp == 0 || tmp == 1) ? tmp : Rt.uw;
- }}, mem_flags=LOCKED);
+ }}, mem_flags=LOCKED, inst_flags = IsStoreConditional);
format StoreMemory {
0x1: swc1({{ Mem.uw = Ft.uw; }});
diff --git a/src/arch/mips/isa/formats/basic.isa b/src/arch/mips/isa/formats/basic.isa
index 29dafd541..29a445b2c 100644
--- a/src/arch/mips/isa/formats/basic.isa
+++ b/src/arch/mips/isa/formats/basic.isa
@@ -26,7 +26,8 @@
// (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
+// Authors: Steve Reinhardt
+// Korey Sewell
// Declarations for execute() methods.
def template BasicExecDeclare {{
@@ -85,7 +86,7 @@ def template BasicDecodeWithMnemonic {{
return new %(class_name)s("%(mnemonic)s", machInst);
}};
-// The most basic instruction format... used only for a few misc. insts
+// The most basic instruction format...
def format BasicOp(code, *flags) {{
iop = InstObjParams(name, Name, 'MipsStaticInst', CodeBlock(code), flags)
header_output = BasicDeclare.subst(iop)
diff --git a/src/arch/mips/isa/formats/branch.isa b/src/arch/mips/isa/formats/branch.isa
index 5230ce9cc..8c89fbfa2 100644
--- a/src/arch/mips/isa/formats/branch.isa
+++ b/src/arch/mips/isa/formats/branch.isa
@@ -36,7 +36,6 @@
output header {{
#include <iostream>
- using namespace std;
/**
* Base class for instructions whose disassembly is not purely a
@@ -235,10 +234,11 @@ def format Branch(code,*opt_flags) {{
else:
inst_flags += (x, )
+ #Take into account uncond. branch instruction
if 'cond == 1' in code:
- inst_flags += ('IsCondControl', )
+ inst_flags += ('IsUnCondControl', )
else:
- inst_flags += ('IsUncondControl', )
+ inst_flags += ('IsCondControl', )
#Condition code
code = 'bool cond;\n' + code
diff --git a/src/arch/mips/isa/formats/int.isa b/src/arch/mips/isa/formats/int.isa
index 56a4ec204..654dd8921 100644
--- a/src/arch/mips/isa/formats/int.isa
+++ b/src/arch/mips/isa/formats/int.isa
@@ -34,7 +34,6 @@
//
output header {{
#include <iostream>
- using namespace std;
/**
* Base class for integer operations.
*/
diff --git a/src/arch/mips/isa/formats/mem.isa b/src/arch/mips/isa/formats/mem.isa
index f03f7becd..d6b0c2938 100644
--- a/src/arch/mips/isa/formats/mem.isa
+++ b/src/arch/mips/isa/formats/mem.isa
@@ -26,7 +26,7 @@
// (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
+// Authors: Steve Reinhardt
// Korey Sewell
////////////////////////////////////////////////////////////////////
@@ -162,7 +162,7 @@ def template InitiateAccDeclare {{
def template CompleteAccDeclare {{
- Fault completeAcc(uint8_t *, %(CPU_exec_context)s *, Trace::InstRecord *) const;
+ Fault completeAcc(Packet *, %(CPU_exec_context)s *, Trace::InstRecord *) const;
}};
@@ -288,7 +288,7 @@ def template LoadInitiateAcc {{
def template LoadCompleteAcc {{
- Fault %(class_name)s::completeAcc(uint8_t *data,
+ Fault %(class_name)s::completeAcc(Packet *pkt,
%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
{
@@ -297,7 +297,7 @@ def template LoadCompleteAcc {{
%(fp_enable_check)s;
%(op_decl)s;
- memcpy(&Mem, data, sizeof(Mem));
+ Mem = pkt->get<typeof(Mem)>();
if (fault == NoFault) {
%(memacc_code)s;
@@ -390,7 +390,6 @@ def template StoreInitiateAcc {{
{
Addr EA;
Fault fault = NoFault;
- uint64_t write_result = 0;
%(fp_enable_check)s;
%(op_decl)s;
@@ -403,7 +402,7 @@ def template StoreInitiateAcc {{
if (fault == NoFault) {
fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
- memAccessFlags, &write_result);
+ memAccessFlags, NULL);
if (traceData) { traceData->setData(Mem); }
}
@@ -413,17 +412,38 @@ def template StoreInitiateAcc {{
def template StoreCompleteAcc {{
- Fault %(class_name)s::completeAcc(uint8_t *data,
+ Fault %(class_name)s::completeAcc(Packet *pkt,
+ %(CPU_exec_context)s *xc,
+ Trace::InstRecord *traceData) const
+ {
+ Fault fault = NoFault;
+
+ %(fp_enable_check)s;
+ %(op_dest_decl)s;
+
+ if (fault == NoFault) {
+ %(postacc_code)s;
+ }
+
+ if (fault == NoFault) {
+ %(op_wb)s;
+ }
+
+ return fault;
+ }
+}};
+
+def template StoreCondCompleteAcc {{
+ Fault %(class_name)s::completeAcc(Packet *pkt,
%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
{
Fault fault = NoFault;
- uint64_t write_result = 0;
%(fp_enable_check)s;
%(op_dest_decl)s;
- memcpy(&write_result, data, sizeof(write_result));
+ uint64_t write_result = pkt->req->getScResult();
if (fault == NoFault) {
%(postacc_code)s;
@@ -489,7 +509,7 @@ def template MiscInitiateAcc {{
def template MiscCompleteAcc {{
- Fault %(class_name)s::completeAcc(uint8_t *data,
+ Fault %(class_name)s::completeAcc(Packet *pkt,
%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
{
@@ -580,5 +600,5 @@ def format StoreCond(memacc_code, postacc_code,
mem_flags = [], inst_flags = []) {{
(header_output, decoder_output, decode_block, exec_output) = \
LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
- postacc_code, exec_template_base = 'Store')
+ postacc_code, exec_template_base = 'StoreCond')
}};
diff --git a/src/arch/mips/isa/formats/util.isa b/src/arch/mips/isa/formats/util.isa
index 0cc375af3..73164bc0d 100644
--- a/src/arch/mips/isa/formats/util.isa
+++ b/src/arch/mips/isa/formats/util.isa
@@ -65,7 +65,7 @@ def LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
if (exec_template_base == 'Load'):
initiateacc_cblk = CodeBlock(ea_code + memacc_code)
completeacc_cblk = CodeBlock(memacc_code + postacc_code)
- elif (exec_template_base == 'Store'):
+ elif (exec_template_base.startswith('Store')):
initiateacc_cblk = CodeBlock(ea_code + memacc_code)
completeacc_cblk = CodeBlock(postacc_code)
else:
@@ -83,7 +83,7 @@ def LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
initiateacc_iop.memacc_code = memacc_cblk.code
completeacc_iop.memacc_code = memacc_cblk.code
completeacc_iop.postacc_code = postacc_cblk.code
- elif (exec_template_base == 'Store'):
+ elif (exec_template_base.startswith('Store')):
initiateacc_iop.ea_code = ea_cblk.code
initiateacc_iop.memacc_code = memacc_cblk.code
completeacc_iop.postacc_code = postacc_cblk.code
@@ -104,6 +104,13 @@ def LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
memacc_iop.constructor += s
# select templates
+
+ # define aliases... most StoreCond templates are the same as the
+ # corresponding Store templates (only CompleteAcc is different).
+ StoreCondMemAccExecute = StoreMemAccExecute
+ StoreCondExecute = StoreExecute
+ StoreCondInitiateAcc = StoreInitiateAcc
+
memAccExecTemplate = eval(exec_template_base + 'MemAccExecute')
fullExecTemplate = eval(exec_template_base + 'Execute')
initiateAccTemplate = eval(exec_template_base + 'InitiateAcc')
@@ -118,7 +125,6 @@ def LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
+ initiateAccTemplate.subst(initiateacc_iop)
+ completeAccTemplate.subst(completeacc_iop))
}};
-
output header {{
std::string inst2string(MachInst machInst);
}};
@@ -127,7 +133,7 @@ output decoder {{
std::string inst2string(MachInst machInst)
{
- string str = "";
+ std::string str = "";
uint32_t mask = 0x80000000;
for(int i=0; i < 32; i++) {
diff --git a/src/arch/mips/isa_traits.cc b/src/arch/mips/isa_traits.cc
index 85acc4e8c..3a8cb46a5 100644
--- a/src/arch/mips/isa_traits.cc
+++ b/src/arch/mips/isa_traits.cc
@@ -30,15 +30,13 @@
*/
#include "arch/mips/isa_traits.hh"
-//#include "config/full_system.hh"
-#include "cpu/static_inst.hh"
+#include "arch/mips/regfile/regfile.hh"
#include "sim/serialize.hh"
#include "base/bitfield.hh"
using namespace MipsISA;
using namespace std;
-
void
MipsISA::copyRegs(ThreadContext *src, ThreadContext *dest)
{
@@ -46,6 +44,12 @@ MipsISA::copyRegs(ThreadContext *src, ThreadContext *dest)
}
void
+MipsISA::copyMiscRegs(ThreadContext *src, ThreadContext *dest)
+{
+ panic("Copy Misc. Regs Not Implemented Yet\n");
+}
+
+void
MipsISA::MiscRegFile::copyMiscRegs(ThreadContext *tc)
{
panic("Copy Misc. Regs Not Implemented Yet\n");
@@ -67,9 +71,9 @@ void
RegFile::serialize(std::ostream &os)
{
intRegFile.serialize(os);
- //SERIALIZE_ARRAY(floatRegFile.q, NumFloatRegs);
+ //SERIALIZE_ARRAY(floatRegFile, NumFloatRegs);
+ //SERIALZE_ARRAY(miscRegFile);
//SERIALIZE_SCALAR(miscRegs.fpcr);
- //SERIALIZE_SCALAR(miscRegs.uniq);
//SERIALIZE_SCALAR(miscRegs.lock_flag);
//SERIALIZE_SCALAR(miscRegs.lock_addr);
SERIALIZE_SCALAR(pc);
@@ -82,9 +86,9 @@ void
RegFile::unserialize(Checkpoint *cp, const std::string &section)
{
intRegFile.unserialize(cp, section);
- //UNSERIALIZE_ARRAY(floatRegFile.q, NumFloatRegs);
+ //UNSERIALIZE_ARRAY(floatRegFile);
+ //UNSERIALZE_ARRAY(miscRegFile);
//UNSERIALIZE_SCALAR(miscRegs.fpcr);
- //UNSERIALIZE_SCALAR(miscRegs.uniq);
//UNSERIALIZE_SCALAR(miscRegs.lock_flag);
//UNSERIALIZE_SCALAR(miscRegs.lock_addr);
UNSERIALIZE_SCALAR(pc);
diff --git a/src/arch/mips/isa_traits.hh b/src/arch/mips/isa_traits.hh
index ff994bef9..fd484e315 100644
--- a/src/arch/mips/isa_traits.hh
+++ b/src/arch/mips/isa_traits.hh
@@ -32,149 +32,87 @@
#ifndef __ARCH_MIPS_ISA_TRAITS_HH__
#define __ARCH_MIPS_ISA_TRAITS_HH__
-#include "arch/mips/constants.hh"
#include "arch/mips/types.hh"
-#include "arch/mips/regfile/regfile.hh"
-#include "arch/mips/faults.hh"
-#include "arch/mips/utility.hh"
-#include "base/misc.hh"
-#include "config/full_system.hh"
-#include "sim/byteswap.hh"
#include "sim/host.hh"
-#include "sim/faults.hh"
-
-#include <vector>
-
-class FastCPU;
-class FullCPU;
-class Checkpoint;
-class ThreadContext;
namespace LittleEndianGuest {};
#define TARGET_MIPS
-class StaticInst;
class StaticInstPtr;
-class SyscallReturn {
- public:
- template <class T>
- SyscallReturn(T v, bool s)
- {
- retval = (uint32_t)v;
- success = s;
- }
-
- template <class T>
- SyscallReturn(T v)
- {
- success = (v >= 0);
- retval = (uint32_t)v;
- }
-
- ~SyscallReturn() {}
-
- SyscallReturn& operator=(const SyscallReturn& s) {
- retval = s.retval;
- success = s.success;
- return *this;
- }
-
- bool successful() { return success; }
- uint64_t value() { return retval; }
-
-
- private:
- uint64_t retval;
- bool success;
-};
-
namespace MipsISA
{
using namespace LittleEndianGuest;
- static inline void setSyscallReturn(SyscallReturn return_value, RegFile *regs)
- {
- if (return_value.successful()) {
- // no error
- regs->setIntReg(SyscallSuccessReg, 0);
- regs->setIntReg(ReturnValueReg1, return_value.value());
- } else {
- // got an error, return details
- regs->setIntReg(SyscallSuccessReg, (IntReg) -1);
- regs->setIntReg(ReturnValueReg1, -return_value.value());
- }
- }
-
StaticInstPtr decodeInst(ExtMachInst);
- static inline ExtMachInst
- makeExtMI(MachInst inst, const uint64_t &pc) {
-#if FULL_SYSTEM
- ExtMachInst ext_inst = inst;
- if (pc && 0x1)
- return ext_inst|=(static_cast<ExtMachInst>(pc & 0x1) << 32);
- else
- return ext_inst;
-#else
- return ExtMachInst(inst);
-#endif
- }
-
- /**
- * Function to insure ISA semantics about 0 registers.
- * @param tc The thread context.
- */
- template <class TC>
- void zeroRegisters(TC *tc);
-
- const Addr MaxAddr = (Addr)-1;
-
- void copyRegs(ThreadContext *src, ThreadContext *dest);
-
- // Machine operations
-
- void saveMachineReg(AnyReg &savereg, const RegFile &reg_file,
- int regnum);
-
- void restoreMachineReg(RegFile &regs, const AnyReg &reg,
- int regnum);
-
-#if 0
- static void serializeSpecialRegs(const Serializable::Proxy &proxy,
- const RegFile &regs);
-
- static void unserializeSpecialRegs(const IniFile *db,
- const std::string &category,
- ConfigNode *node,
- RegFile &regs);
-#endif
-
- static inline Addr alignAddress(const Addr &addr,
- unsigned int nbytes) {
- return (addr & ~(nbytes - 1));
- }
-
- // 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 (not necessarily the size
- // of real instructions for PISA)
- static inline size_t fetchInstSize() {
- return sizeof(MachInst);
- }
-
- static inline MachInst makeRegisterCopy(int dest, int src) {
- panic("makeRegisterCopy not implemented");
- return 0;
- }
+ const Addr PageShift = 13;
+ const Addr PageBytes = ULL(1) << PageShift;
+ const Addr PageMask = ~(PageBytes - 1);
+ const Addr PageOffset = PageBytes - 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 = 32;
+ const int NumIntSpecialRegs = 2;
+ const int NumFloatArchRegs = 32;
+ const int NumFloatSpecialRegs = 5;
+ const int NumControlRegs = 265;
+ const int NumInternalProcRegs = 0;
+
+ const int NumIntRegs = NumIntArchRegs + NumIntSpecialRegs; //HI & LO Regs
+ const int NumFloatRegs = NumFloatArchRegs + NumFloatSpecialRegs;//
+ const int NumMiscRegs = NumControlRegs;
+
+ const int TotalNumRegs = NumIntRegs + NumFloatRegs +
+ NumMiscRegs + 0/*NumInternalProcRegs*/;
+
+ const int TotalDataRegs = NumIntRegs + NumFloatRegs;
+
+ // Static instruction parameters
+ const int MaxInstSrcRegs = 3;
+ const int MaxInstDestRegs = 2;
+
+ // semantically meaningful register indices
+ const int ZeroReg = 0;
+ const int AssemblerReg = 1;
+ const int ReturnValueReg = 2;
+ const int ReturnValueReg1 = 2;
+ const int ReturnValueReg2 = 3;
+ const int ArgumentReg0 = 4;
+ const int ArgumentReg1 = 5;
+ const int ArgumentReg2 = 6;
+ const int ArgumentReg3 = 7;
+ const int KernelReg0 = 26;
+ const int KernelReg1 = 27;
+ const int GlobalPointerReg = 28;
+ const int StackPointerReg = 29;
+ const int FramePointerReg = 30;
+ const int ReturnAddressReg = 31;
+
+ const int SyscallNumReg = ReturnValueReg1;
+ const int SyscallPseudoReturnReg = ReturnValueReg1;
+ const int SyscallSuccessReg = ArgumentReg3;
+
+ const int LogVMPageSize = 13; // 8K 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 = 34;
+ const int Ctrl_Base_DepTag = 257;
+
+ const int ANNOTE_NONE = 0;
+ const uint32_t ITOUCH_ANNOTE = 0xffffffff;
};
diff --git a/src/arch/mips/linux/linux.cc b/src/arch/mips/linux/linux.cc
index 26e3dd479..90404af53 100644
--- a/src/arch/mips/linux/linux.cc
+++ b/src/arch/mips/linux/linux.cc
@@ -30,6 +30,8 @@
#include "arch/mips/linux/linux.hh"
+#include <fcntl.h>
+
// open(2) flags translation table
OpenFlagTransTable MipsLinux::openFlagTable[] = {
#ifdef _MSC_VER
diff --git a/src/arch/mips/process.hh b/src/arch/mips/process.hh
index b0ef20399..400591599 100644
--- a/src/arch/mips/process.hh
+++ b/src/arch/mips/process.hh
@@ -50,6 +50,7 @@ class MipsLiveProcess : public LiveProcess
std::vector<std::string> &envp);
void startup();
+
};
diff --git a/src/arch/mips/regfile.hh b/src/arch/mips/regfile.hh
new file mode 100644
index 000000000..4b2f1ac35
--- /dev/null
+++ b/src/arch/mips/regfile.hh
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2006 The Regents of The University of Michigan
+ * 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
+ */
+
+#ifndef __ARCH_MIPS_REGFILE_HH__
+#define __ARCH_MIPS_REGFILE_HH__
+
+#include "arch/mips/regfile/regfile.hh"
+
+#endif
diff --git a/src/arch/mips/regfile/float_regfile.hh b/src/arch/mips/regfile/float_regfile.hh
index 61efbb416..ce5f1fdde 100644
--- a/src/arch/mips/regfile/float_regfile.hh
+++ b/src/arch/mips/regfile/float_regfile.hh
@@ -26,24 +26,61 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef __ARCH_MIPS_FLOAT_REGFILE_HH__
-#define __ARCH_MIPS_FLOAT_REGFILE_HH__
+#ifndef __ARCH_MIPS_REGFILE_FLOAT_REGFILE_HH__
+#define __ARCH_MIPS_REGFILE_FLOAT_REGFILE_HH__
#include "arch/mips/types.hh"
-#include "arch/mips/constants.hh"
+#include "arch/mips/isa_traits.hh"
#include "base/misc.hh"
#include "base/bitfield.hh"
-#include "config/full_system.hh"
-#include "sim/byteswap.hh"
#include "sim/faults.hh"
-#include "sim/host.hh"
+
+#include <string>
class Checkpoint;
-class ExecContext;
-class Regfile;
namespace MipsISA
{
+ static inline std::string getFloatRegName(RegIndex)
+ {
+ return "";
+ }
+
+ const uint32_t MIPS32_QNAN = 0x7fbfffff;
+ const uint64_t MIPS64_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:
@@ -102,7 +139,6 @@ namespace MipsISA
Fault setReg(int floatReg, const FloatRegVal &val, int width)
{
- using namespace std;
switch(width)
{
case SingleWidth:
@@ -131,7 +167,6 @@ namespace MipsISA
Fault setRegBits(int floatReg, const FloatRegBits &val, int width)
{
- using namespace std;
switch(width)
{
diff --git a/src/arch/mips/regfile/int_regfile.hh b/src/arch/mips/regfile/int_regfile.hh
index 5add1b7be..a45a17a85 100644
--- a/src/arch/mips/regfile/int_regfile.hh
+++ b/src/arch/mips/regfile/int_regfile.hh
@@ -28,20 +28,29 @@
* Authors: Korey Sewell
*/
-#ifndef __ARCH_MIPS_INT_REGFILE_HH__
-#define __ARCH_MIPS_INT_REGFILE_HH__
+#ifndef __ARCH_MIPS_REGFILE_INT_REGFILE_HH__
+#define __ARCH_MIPS_REGFILE_INT_REGFILE_HH__
#include "arch/mips/types.hh"
-#include "arch/mips/constants.hh"
+#include "arch/mips/isa_traits.hh"
#include "base/misc.hh"
#include "sim/faults.hh"
class Checkpoint;
class ThreadContext;
-class Regfile;
namespace MipsISA
{
+ static inline std::string getIntRegName(RegIndex)
+ {
+ return "";
+ }
+
+ enum MiscIntRegNums {
+ HI = NumIntArchRegs,
+ LO
+ };
+
class IntRegFile
{
protected:
diff --git a/src/arch/mips/regfile/misc_regfile.hh b/src/arch/mips/regfile/misc_regfile.hh
index 87961f97e..a4527a203 100644
--- a/src/arch/mips/regfile/misc_regfile.hh
+++ b/src/arch/mips/regfile/misc_regfile.hh
@@ -28,29 +28,191 @@
* Authors: Korey Sewell
*/
-#ifndef __ARCH_MIPS_MISC_REGFILE_HH__
-#define __ARCH_MIPS_MISC_REGFILE_HH__
+#ifndef __ARCH_MIPS_REGFILE_MISC_REGFILE_HH__
+#define __ARCH_MIPS_REGFILE_MISC_REGFILE_HH__
#include "arch/mips/types.hh"
-#include "arch/mips/constants.hh"
#include "sim/faults.hh"
-class Checkpoint;
class ThreadContext;
-class Regfile;
namespace MipsISA
{
+ static inline std::string getMiscRegName(RegIndex)
+ {
+ return "";
+ }
+
+ //Coprocessor 0 Register Names
+ enum MiscRegTags {
+ //Reference MIPS32 Arch. for Programmers, Vol. III, Ch.8
+ //(Register Number-Register Select) Summary of Register
+ //------------------------------------------------------
+ Index = 0, //Bank 0: 0 - 3
+ MVPControl,
+ MVPConf0,
+ MVPConf1,
+
+ Random = 8, //Bank 1: 8 - 15
+ VPEControl,
+ VPEConf0,
+ VPEConf1,
+ YQMask,
+ VPESchedule,
+ VPEScheFBack,
+ VPEOpt,
+
+ EntryLo0 = 16, //Bank 2: 16 - 23
+ TCStatus,
+ TCBind,
+ TCRestart,
+ TCHalt,
+ TCContext,
+ TCSchedule,
+ TCScheFBack,
+
+ EntryLo1 = 24, // Bank 3: 24
+
+ Context = 32, // Bank 4: 32 - 33
+ ContextConfig,
+
+ //PageMask = 40, //Bank 5: 40 - 41
+ PageGrain = 41,
+
+ Wired = 48, //Bank 6: 48 - 55
+ SRSConf0,
+ SRSConf1,
+ SRSConf2,
+ SRSConf3,
+ SRSConf4,
+
+ HWRena = 56, //Bank 7: 56
+
+ BadVAddr = 63, //Bank 8: 63
+
+ Count = 64, //Bank 9: 64
+
+ EntryHi = 72, //Bank 10:72 - 79
+
+ Compare = 80, //Bank 10:80 - 87
+
+ Status = 88, //Bank 12:88 - 96
+ IntCtl = 89,
+ SRSCtl = 90,
+ SRSMap = 91,
+
+ Cause = 97, //97-104
+
+ EPC = 105, //105-112
+
+ PRId = 113, //113-120,
+ EBase = 114,
+
+ Config = 121, //Bank 16: 121-128
+ Config1 = 122,
+ Config2 = 123,
+ Config3 = 124,
+ Config6 = 127,
+ Config7 = 128,
+
+
+ LLAddr = 129, //Bank 17: 129-136
+
+ WatchLo0 = 137, //Bank 18: 137-144
+ WatchLo1 = 138,
+ WatchLo2 = 139,
+ WatchLo3 = 140,
+ WatchLo4 = 141,
+ WatchLo5 = 142,
+ WatchLo6 = 143,
+ WatchLo7 = 144,
+
+ WatchHi0 = 145,//Bank 19: 145-152
+ WatchHi1 = 146,
+ WatchHi2 = 147,
+ WatchHi3 = 148,
+ WatchHi4 = 149,
+ WatchHi5 = 150,
+ WatchHi6 = 151,
+ WatchHi7 = 152,
+
+ XCContext64 = 153, //Bank 20: 153-160
+
+ //Bank 21: 161-168
+
+ //Bank 22: 169-176
+
+ Debug = 177, //Bank 23: 177-184
+ TraceControl1 = 178,
+ TraceControl2 = 179,
+ UserTraceData = 180,
+ TraceBPC = 181,
+
+ DEPC = 185,//Bank 24: 185-192
+
+ PerfCnt0 = 193,//Bank 25: 193 - 200
+ PerfCnt1 = 194,
+ PerfCnt2 = 195,
+ PerfCnt3 = 196,
+ PerfCnt4 = 197,
+ PerfCnt5 = 198,
+ PerfCnt6 = 199,
+ PerfCnt7 = 200,
+
+ ErrCtl = 201, //Bank 26: 201 - 208
+
+ CacheErr0 = 209, //Bank 27: 209 - 216
+ CacheErr1 = 210,
+ CacheErr2 = 211,
+ CacheErr3 = 212,
+
+ TagLo0 = 217,//Bank 28: 217 - 224
+ DataLo1 = 218,
+ TagLo2 = 219,
+ DataLo3 = 220,
+ TagLo4 = 221,
+ DataLo5 = 222,
+ TagLo6 = 223,
+ DataLo7 = 234,
+
+ TagHi0 = 233,//Bank 29: 233 - 240
+ DataHi1 = 234,
+ TagHi2 = 235,
+ DataHi3 = 236,
+ TagHi4 = 237,
+ DataHi5 = 238,
+ TagHi6 = 239,
+ DataHi7 = 240,
+
+
+ ErrorEPC = 249,//Bank 30: 241 - 248
+
+ DESAVE = 257//Bank 31: 249-256
+ };
+
class MiscRegFile {
protected:
uint64_t fpcr; // floating point condition codes
+ // FPCR is not used in MIPS. Condition
+ // codes are kept as part of the FloatRegFile
+
bool lock_flag; // lock flag for LL/SC
+ // use LL reg. in the future
+
Addr lock_addr; // lock address for LL/SC
+ // use LLAddr reg. in the future
MiscReg miscRegFile[NumMiscRegs];
public:
+ void clear()
+ {
+ fpcr = 0;
+ lock_flag = 0;
+ lock_addr = 0;
+ }
+
void copyMiscRegs(ThreadContext *tc);
MiscReg readReg(int misc_reg)
diff --git a/src/arch/mips/regfile/regfile.hh b/src/arch/mips/regfile/regfile.hh
index a68120299..3a18c681b 100644
--- a/src/arch/mips/regfile/regfile.hh
+++ b/src/arch/mips/regfile/regfile.hh
@@ -28,11 +28,10 @@
* Authors: Korey Sewell
*/
-#ifndef __ARCH_MIPS_REGFILE_HH__
-#define __ARCH_MIPS_REGFILE_HH__
+#ifndef __ARCH_MIPS_REGFILE_REGFILE_HH__
+#define __ARCH_MIPS_REGFILE_REGFILE_HH__
#include "arch/mips/types.hh"
-#include "arch/mips/constants.hh"
#include "arch/mips/regfile/int_regfile.hh"
#include "arch/mips/regfile/float_regfile.hh"
#include "arch/mips/regfile/misc_regfile.hh"
@@ -171,10 +170,7 @@ namespace MipsISA
void serialize(std::ostream &os);
void unserialize(Checkpoint *cp, const std::string &section);
- typedef int ContextParam;
- typedef int ContextVal;
-
- void changeContext(ContextParam param, ContextVal val)
+ void changeContext(RegContextParam param, RegContextVal val)
{
}
};
diff --git a/src/arch/mips/syscallreturn.hh b/src/arch/mips/syscallreturn.hh
new file mode 100644
index 000000000..ef1093caf
--- /dev/null
+++ b/src/arch/mips/syscallreturn.hh
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2003-2005 The Regents of The University of Michigan
+ * 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
+ * Korey Sewell
+ */
+
+#ifndef __ARCH_MIPS_SYSCALLRETURN_HH__
+#define __ARCH_MIPS_SYSCALLRETURN_HH__
+
+class SyscallReturn {
+ public:
+ template <class T>
+ SyscallReturn(T v, bool s)
+ {
+ retval = (uint32_t)v;
+ success = s;
+ }
+
+ template <class T>
+ SyscallReturn(T v)
+ {
+ success = (v >= 0);
+ retval = (uint32_t)v;
+ }
+
+ ~SyscallReturn() {}
+
+ SyscallReturn& operator=(const SyscallReturn& s) {
+ retval = s.retval;
+ success = s.success;
+ return *this;
+ }
+
+ bool successful() { return success; }
+ uint64_t value() { return retval; }
+
+
+ private:
+ uint64_t retval;
+ bool success;
+};
+
+namespace MipsISA
+{
+ static inline void setSyscallReturn(SyscallReturn return_value, RegFile *regs)
+ {
+ if (return_value.successful()) {
+ // no error
+ regs->setIntReg(SyscallSuccessReg, 0);
+ regs->setIntReg(ReturnValueReg1, return_value.value());
+ } else {
+ // got an error, return details
+ regs->setIntReg(SyscallSuccessReg, (IntReg) -1);
+ regs->setIntReg(ReturnValueReg1, -return_value.value());
+ }
+ }
+}
+
+#endif
diff --git a/src/arch/mips/types.hh b/src/arch/mips/types.hh
index 6330044d9..d4fa296fd 100644
--- a/src/arch/mips/types.hh
+++ b/src/arch/mips/types.hh
@@ -58,6 +58,9 @@ namespace MipsISA
MiscReg ctrlreg;
} AnyReg;
+ typedef int RegContextParam;
+ typedef int RegContextVal;
+
//used in FP convert & round function
enum ConvertType{
SINGLE_TO_DOUBLE,
diff --git a/src/arch/mips/utility.cc b/src/arch/mips/utility.cc
index e7455fdbf..9ac4bb6d8 100644
--- a/src/arch/mips/utility.cc
+++ b/src/arch/mips/utility.cc
@@ -28,15 +28,12 @@
* Authors: Korey Sewell
*/
-#include "arch/mips/isa_traits.hh"
+#include "arch/mips/regfile.hh"
#include "arch/mips/utility.hh"
-#include "config/full_system.hh"
-#include "cpu/static_inst.hh"
-#include "sim/serialize.hh"
+#include "base/misc.hh"
#include "base/bitfield.hh"
using namespace MipsISA;
-using namespace std;
uint64_t
MipsISA::fpConvert(ConvertType cvt_type, double fp_val)
diff --git a/src/arch/mips/utility.hh b/src/arch/mips/utility.hh
index c5c69ddcd..ae2fe1aea 100644
--- a/src/arch/mips/utility.hh
+++ b/src/arch/mips/utility.hh
@@ -33,10 +33,14 @@
#define __ARCH_MIPS_UTILITY_HH__
#include "arch/mips/types.hh"
-#include "arch/mips/constants.hh"
#include "base/misc.hh"
+#include "config/full_system.hh"
+//XXX This is needed for size_t. We should use something other than size_t
+//#include "kern/linux/linux.hh"
#include "sim/host.hh"
+class ThreadContext;
+
namespace MipsISA {
//Floating Point Utility Functions
@@ -51,6 +55,48 @@ namespace MipsISA {
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);
+
+ void copyRegs(ThreadContext *src, ThreadContext *dest);
+
+ // 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 (not necessarily the size
+ // of real instructions for PISA)
+ static inline size_t fetchInstSize() {
+ return sizeof(MachInst);
+ }
+
+ static inline MachInst makeRegisterCopy(int dest, int src) {
+ panic("makeRegisterCopy not implemented");
+ return 0;
+ }
+
+ static inline ExtMachInst
+ makeExtMI(MachInst inst, const uint64_t &pc) {
+#if FULL_SYSTEM
+ ExtMachInst ext_inst = inst;
+ if (pc && 0x1)
+ return ext_inst|=(static_cast<ExtMachInst>(pc & 0x1) << 32);
+ else
+ return ext_inst;
+#else
+ return ExtMachInst(inst);
+#endif
+ }
};
diff --git a/src/arch/sparc/SConscript b/src/arch/sparc/SConscript
index e7a8278db..66f2b57e0 100644
--- a/src/arch/sparc/SConscript
+++ b/src/arch/sparc/SConscript
@@ -45,22 +45,25 @@ Import('env')
# Base sources used by all configurations.
base_sources = Split('''
faults.cc
- isa_traits.cc
+ floatregfile.cc
+ intregfile.cc
+ miscregfile.cc
+ regfile.cc
''')
# Full-system sources
full_system_sources = Split('''
- vtophys.cc
ua2005.cc
+ vtophys.cc
''')
# Syscall emulation (non-full-system) sources
syscall_emulation_sources = Split('''
linux/linux.cc
linux/process.cc
- solaris/solaris.cc
- solaris/process.cc
process.cc
+ solaris/process.cc
+ solaris/solaris.cc
''')
sources = base_sources
diff --git a/src/arch/sparc/floatregfile.cc b/src/arch/sparc/floatregfile.cc
new file mode 100644
index 000000000..3cacbb278
--- /dev/null
+++ b/src/arch/sparc/floatregfile.cc
@@ -0,0 +1,174 @@
+/*
+ * Copyright (c) 2003-2005 The Regents of The University of Michigan
+ * 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
+ * Ali Saidi
+ */
+
+#include "arch/sparc/floatregfile.hh"
+#include "base/trace.hh"
+#include "sim/byteswap.hh"
+#include "sim/serialize.hh"
+
+using namespace SparcISA;
+using namespace std;
+
+class Checkpoint;
+
+string SparcISA::getFloatRegName(RegIndex index)
+{
+ static std::string floatRegName[NumFloatRegs] =
+ {"f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
+ "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
+ "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
+ "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
+ "f32", "f33", "f34", "f35", "f36", "f37", "f38", "f39",
+ "f40", "f41", "f42", "f43", "f44", "f45", "f46", "f47",
+ "f48", "f49", "f50", "f51", "f52", "f53", "f54", "f55",
+ "f56", "f57", "f58", "f59", "f60", "f61", "f62", "f63"};
+ return floatRegName[index];
+}
+
+void FloatRegFile::clear()
+{
+ bzero(regSpace, sizeof(regSpace));
+}
+
+FloatReg FloatRegFile::readReg(int floatReg, int width)
+{
+ //In each of these cases, we have to copy the value into a temporary
+ //variable. This is because we may otherwise try to access an
+ //unaligned portion of memory.
+ switch(width)
+ {
+ case SingleWidth:
+ float32_t result32;
+ memcpy(&result32, regSpace + 4 * floatReg, sizeof(result32));
+ return htog(result32);
+ case DoubleWidth:
+ float64_t result64;
+ memcpy(&result64, regSpace + 4 * floatReg, sizeof(result64));
+ return htog(result64);
+ case QuadWidth:
+ float128_t result128;
+ memcpy(&result128, regSpace + 4 * floatReg, sizeof(result128));
+ return htog(result128);
+ default:
+ panic("Attempted to read a %d bit floating point register!", width);
+ }
+}
+
+FloatRegBits FloatRegFile::readRegBits(int floatReg, int width)
+{
+ //In each of these cases, we have to copy the value into a temporary
+ //variable. This is because we may otherwise try to access an
+ //unaligned portion of memory.
+ switch(width)
+ {
+ case SingleWidth:
+ uint32_t result32;
+ memcpy(&result32, regSpace + 4 * floatReg, sizeof(result32));
+ return htog(result32);
+ case DoubleWidth:
+ uint64_t result64;
+ memcpy(&result64, regSpace + 4 * floatReg, sizeof(result64));
+ return htog(result64);
+ case QuadWidth:
+ uint64_t result128;
+ memcpy(&result128, regSpace + 4 * floatReg, sizeof(result128));
+ return htog(result128);
+ default:
+ panic("Attempted to read a %d bit floating point register!", width);
+ }
+}
+
+Fault FloatRegFile::setReg(int floatReg, const FloatReg &val, int width)
+{
+ //In each of these cases, we have to copy the value into a temporary
+ //variable. This is because we may otherwise try to access an
+ //unaligned portion of memory.
+
+ uint32_t result32;
+ uint64_t result64;
+ DPRINTF(Sparc, "Setting floating point register %d\n", floatReg);
+ switch(width)
+ {
+ case SingleWidth:
+ result32 = gtoh((uint32_t)val);
+ memcpy(regSpace + 4 * floatReg, &result32, sizeof(result32));
+ break;
+ case DoubleWidth:
+ result64 = gtoh((uint64_t)val);
+ memcpy(regSpace + 4 * floatReg, &result64, sizeof(result64));
+ break;
+ case QuadWidth:
+ panic("Quad width FP not implemented.");
+ break;
+ default:
+ panic("Attempted to read a %d bit floating point register!", width);
+ }
+ return NoFault;
+}
+
+Fault FloatRegFile::setRegBits(int floatReg, const FloatRegBits &val, int width)
+{
+ //In each of these cases, we have to copy the value into a temporary
+ //variable. This is because we may otherwise try to access an
+ //unaligned portion of memory.
+ uint32_t result32;
+ uint64_t result64;
+ switch(width)
+ {
+ case SingleWidth:
+ result32 = gtoh((uint32_t)val);
+ memcpy(regSpace + 4 * floatReg, &result32, sizeof(result32));
+ break;
+ case DoubleWidth:
+ result64 = gtoh((uint64_t)val);
+ memcpy(regSpace + 4 * floatReg, &result64, sizeof(result64));
+ break;
+ case QuadWidth:
+ panic("Quad width FP not implemented.");
+ break;
+ default:
+ panic("Attempted to read a %d bit floating point register!", width);
+ }
+ return NoFault;
+}
+
+void FloatRegFile::serialize(std::ostream &os)
+{
+ SERIALIZE_ARRAY((unsigned char *)regSpace,
+ SingleWidth / 8 * NumFloatRegs);
+}
+
+void FloatRegFile::unserialize(Checkpoint *cp, const std::string &section)
+{
+ UNSERIALIZE_ARRAY((unsigned char *)regSpace,
+ SingleWidth / 8 * NumFloatRegs);
+}
+
diff --git a/src/arch/sparc/floatregfile.hh b/src/arch/sparc/floatregfile.hh
new file mode 100644
index 000000000..9d760c9ff
--- /dev/null
+++ b/src/arch/sparc/floatregfile.hh
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2003-2005 The Regents of The University of Michigan
+ * 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
+ * Ali Saidi
+ */
+
+#ifndef __ARCH_SPARC_FLOATREGFILE_HH__
+#define __ARCH_SPARC_FLOATREGFILE_HH__
+
+#include "arch/sparc/faults.hh"
+#include "arch/sparc/isa_traits.hh"
+#include "arch/sparc/types.hh"
+
+#include <string>
+
+namespace SparcISA
+{
+ std::string getFloatRegName(RegIndex);
+
+ typedef float float32_t;
+ typedef double float64_t;
+ //FIXME long double refers to a 10 byte float, rather than a
+ //16 byte float as required. This data type may have to be emulated.
+ typedef double float128_t;
+
+ class FloatRegFile
+ {
+ public:
+ static const int SingleWidth = 32;
+ static const int DoubleWidth = 64;
+ static const int QuadWidth = 128;
+
+ protected:
+
+ //Since the floating point registers overlap each other,
+ //A generic storage space is used. The float to be returned is
+ //pulled from the appropriate section of this region.
+ char regSpace[(SingleWidth / 8) * NumFloatRegs];
+
+ public:
+
+ void clear();
+
+ FloatReg readReg(int floatReg, int width);
+
+ FloatRegBits readRegBits(int floatReg, int width);
+
+ Fault setReg(int floatReg, const FloatReg &val, int width);
+
+ Fault setRegBits(int floatReg, const FloatRegBits &val, int width);
+
+ void serialize(std::ostream &os);
+
+ void unserialize(Checkpoint *cp, const std::string &section);
+ };
+}
+
+#endif
diff --git a/src/arch/sparc/intregfile.cc b/src/arch/sparc/intregfile.cc
new file mode 100644
index 000000000..0cc0a886a
--- /dev/null
+++ b/src/arch/sparc/intregfile.cc
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 2003-2005 The Regents of The University of Michigan
+ * 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
+ * Ali Saidi
+ */
+
+#include "arch/sparc/intregfile.hh"
+#include "base/trace.hh"
+#include "sim/serialize.hh"
+
+using namespace SparcISA;
+using namespace std;
+
+class Checkpoint;
+
+string SparcISA::getIntRegName(RegIndex index)
+{
+ static std::string intRegName[NumIntRegs] =
+ {"g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7",
+ "o0", "o1", "o2", "o3", "o4", "o5", "o6", "o7",
+ "l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7",
+ "i0", "i1", "i2", "i3", "i4", "i5", "i6", "i7"};
+ return intRegName[index];
+}
+
+int IntRegFile::flattenIndex(int reg)
+{
+ int flatIndex = offset[reg >> FrameOffsetBits]
+ | (reg & FrameOffsetMask);
+ DPRINTF(Sparc, "Flattened index %d into %d.\n", reg, flatIndex);
+ return flatIndex;
+}
+
+void IntRegFile::clear()
+{
+ int x;
+ for (x = 0; x < MaxGL; x++)
+ memset(regGlobals[x], 0, sizeof(regGlobals[x]));
+ for(int x = 0; x < 2 * NWindows; x++)
+ bzero(regSegments[x], sizeof(regSegments[x]));
+}
+
+IntRegFile::IntRegFile()
+{
+ offset[Globals] = 0;
+ regView[Globals] = regGlobals[0];
+ setCWP(0);
+ clear();
+}
+
+IntReg IntRegFile::readReg(int intReg)
+{
+ IntReg val =
+ regView[intReg >> FrameOffsetBits][intReg & FrameOffsetMask];
+ DPRINTF(Sparc, "Read register %d = 0x%x\n", intReg, val);
+ return val;
+}
+
+Fault IntRegFile::setReg(int intReg, const IntReg &val)
+{
+ if(intReg)
+ DPRINTF(Sparc, "Wrote register %d = 0x%x\n", intReg, val);
+ regView[intReg >> FrameOffsetBits][intReg & FrameOffsetMask] = val;
+ return NoFault;
+}
+
+//This doesn't effect the actual CWP register.
+//It's purpose is to adjust the view of the register file
+//to what it would be if CWP = cwp.
+void IntRegFile::setCWP(int cwp)
+{
+ int index = ((NWindows - cwp) % NWindows) * 2;
+ offset[Outputs] = FrameOffset + (index * RegsPerFrame);
+ offset[Locals] = FrameOffset + ((index+1) * RegsPerFrame);
+ offset[Inputs] = FrameOffset +
+ (((index+2) % (NWindows * 2)) * RegsPerFrame);
+ regView[Outputs] = regSegments[index];
+ regView[Locals] = regSegments[index+1];
+ regView[Inputs] = regSegments[(index+2) % (NWindows * 2)];
+
+ DPRINTF(Sparc, "Changed the CWP value to %d\n", cwp);
+}
+
+void IntRegFile::setGlobals(int gl)
+{
+ DPRINTF(Sparc, "Now using %d globals", gl);
+
+ regView[Globals] = regGlobals[gl];
+ offset[Globals] = RegGlobalOffset + gl * RegsPerFrame;
+}
+
+void IntRegFile::serialize(std::ostream &os)
+{
+ unsigned int x;
+ for(x = 0; x < MaxGL; x++)
+ SERIALIZE_ARRAY(regGlobals[x], RegsPerFrame);
+ for(x = 0; x < 2 * NWindows; x++)
+ SERIALIZE_ARRAY(regSegments[x], RegsPerFrame);
+}
+
+void IntRegFile::unserialize(Checkpoint *cp, const std::string &section)
+{
+ unsigned int x;
+ for(x = 0; x < MaxGL; x++)
+ UNSERIALIZE_ARRAY(regGlobals[x], RegsPerFrame);
+ for(unsigned int x = 0; x < 2 * NWindows; x++)
+ UNSERIALIZE_ARRAY(regSegments[x], RegsPerFrame);
+}
diff --git a/src/arch/sparc/intregfile.hh b/src/arch/sparc/intregfile.hh
new file mode 100644
index 000000000..d305c753b
--- /dev/null
+++ b/src/arch/sparc/intregfile.hh
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2003-2005 The Regents of The University of Michigan
+ * 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
+ * Ali Saidi
+ */
+
+#ifndef __ARCH_SPARC_INTREGFILE_HH__
+#define __ARCH_SPARC_INTREGFILE_HH__
+
+#include "arch/sparc/faults.hh"
+#include "arch/sparc/isa_traits.hh"
+#include "arch/sparc/types.hh"
+
+#include <string>
+
+namespace SparcISA
+{
+ class RegFile;
+
+ //This function translates integer register file indices into names
+ std::string getIntRegName(RegIndex);
+
+ class IntRegFile
+ {
+ private:
+ friend class RegFile;
+ protected:
+ static const int FrameOffsetBits = 3;
+ static const int FrameNumBits = 2;
+
+ static const int RegsPerFrame = 1 << FrameOffsetBits;
+ static const int FrameNumMask =
+ (FrameNumBits == sizeof(int)) ?
+ (unsigned int)(-1) :
+ (1 << FrameNumBits) - 1;
+ static const int FrameOffsetMask =
+ (FrameOffsetBits == sizeof(int)) ?
+ (unsigned int)(-1) :
+ (1 << FrameOffsetBits) - 1;
+
+ IntReg regGlobals[MaxGL][RegsPerFrame];
+ IntReg regSegments[2 * NWindows][RegsPerFrame];
+
+ enum regFrame {Globals, Outputs, Locals, Inputs, NumFrames};
+
+ IntReg * regView[NumFrames];
+
+ static const int RegGlobalOffset = 0;
+ static const int FrameOffset = MaxGL * RegsPerFrame;
+ int offset[NumFrames];
+
+ public:
+
+ int flattenIndex(int reg);
+
+ void clear();
+
+ IntRegFile();
+
+ IntReg readReg(int intReg);
+
+ Fault setReg(int intReg, const IntReg &val);
+
+ void serialize(std::ostream &os);
+
+ void unserialize(Checkpoint *cp, const std::string &section);
+
+ protected:
+ //This doesn't effect the actual CWP register.
+ //It's purpose is to adjust the view of the register file
+ //to what it would be if CWP = cwp.
+ void setCWP(int cwp);
+
+ void setGlobals(int gl);
+ };
+}
+
+#endif
diff --git a/src/arch/sparc/isa/base.isa b/src/arch/sparc/isa/base.isa
index 02f7cf61a..b518265aa 100644
--- a/src/arch/sparc/isa/base.isa
+++ b/src/arch/sparc/isa/base.isa
@@ -86,6 +86,11 @@ output header {{
const SymbolTable *symtab) const;
void printReg(std::ostream &os, int reg) const;
+ void printSrcReg(std::ostream &os, int reg) const;
+ void printDestReg(std::ostream &os, int reg) const;
+
+ void printRegArray(std::ostream &os,
+ const RegIndex indexArray[], int num) const;
};
bool passesCondition(uint32_t codes, uint32_t condition);
@@ -150,6 +155,33 @@ output decoder {{
ccprintf(os, "\t%s ", mnemonic);
}
+ void SparcStaticInst::printRegArray(std::ostream &os,
+ const RegIndex indexArray[], int num) const
+ {
+ if(num <= 0)
+ return;
+ printReg(os, indexArray[0]);
+ for(int x = 1; x < num; x++)
+ {
+ os << ", ";
+ printReg(os, indexArray[x]);
+ }
+ }
+
+ void
+ SparcStaticInst::printSrcReg(std::ostream &os, int reg) const
+ {
+ if(_numSrcRegs > reg)
+ printReg(os, _srcRegIdx[reg]);
+ }
+
+ void
+ SparcStaticInst::printDestReg(std::ostream &os, int reg) const
+ {
+ if(_numDestRegs > reg)
+ printReg(os, _destRegIdx[reg]);
+ }
+
void
SparcStaticInst::printReg(std::ostream &os, int reg) const
{
diff --git a/src/arch/sparc/isa/decoder.isa b/src/arch/sparc/isa/decoder.isa
index fa8832920..0c2729833 100644
--- a/src/arch/sparc/isa/decoder.isa
+++ b/src/arch/sparc/isa/decoder.isa
@@ -39,30 +39,30 @@ decode OP default Unknown::unknown()
{
//Throw an illegal instruction acception
0x0: Trap::illtrap({{fault = new IllegalInstruction;}});
- 0x1: decode BPCC
+ format BranchN
{
- format Branch19
+ 0x1: decode BPCC
{
- 0x0: bpcci({{
+ 0x0: bpcci(19, {{
if(passesCondition(Ccr<3:0>, COND2))
NNPC = xc->readPC() + disp;
else
handle_annul
}});
- 0x2: bpccx({{
+ 0x2: bpccx(19, {{
if(passesCondition(Ccr<7:4>, COND2))
NNPC = xc->readPC() + disp;
else
handle_annul
}});
}
+ 0x2: bicc(22, {{
+ if(passesCondition(Ccr<3:0>, COND2))
+ NNPC = xc->readPC() + disp;
+ else
+ handle_annul
+ }});
}
- 0x2: Branch22::bicc({{
- if(passesCondition(Ccr<3:0>, COND2))
- NNPC = xc->readPC() + disp;
- else
- handle_annul
- }});
0x3: decode RCOND2
{
format BranchSplit
@@ -110,22 +110,22 @@ decode OP default Unknown::unknown()
0x5: Trap::fbpfcc({{fault = new FpDisabled;}});
0x6: Trap::fbfcc({{fault = new FpDisabled;}});
}
- 0x1: Branch30::call({{
+ 0x1: BranchN::call(30, {{
R15 = xc->readPC();
NNPC = R15 + disp;
}});
0x2: decode OP3 {
format IntOp {
0x00: add({{Rd = Rs1.sdw + Rs2_or_imm13;}});
- 0x01: and({{Rd = Rs1.udw & Rs2_or_imm13;}});
- 0x02: or({{Rd = Rs1.udw | Rs2_or_imm13;}});
- 0x03: xor({{Rd = Rs1.udw ^ Rs2_or_imm13;}});
+ 0x01: and({{Rd = Rs1.sdw & Rs2_or_imm13;}});
+ 0x02: or({{Rd = Rs1.sdw | Rs2_or_imm13;}});
+ 0x03: xor({{Rd = Rs1.sdw ^ Rs2_or_imm13;}});
0x04: sub({{Rd = Rs1.sdw - Rs2_or_imm13;}});
- 0x05: andn({{Rd = Rs1.udw & ~Rs2_or_imm13;}});
- 0x06: orn({{Rd = Rs1.udw | ~Rs2_or_imm13;}});
- 0x07: xnor({{Rd = ~(Rs1.udw ^ Rs2_or_imm13);}});
+ 0x05: andn({{Rd = Rs1.sdw & ~Rs2_or_imm13;}});
+ 0x06: orn({{Rd = Rs1.sdw | ~Rs2_or_imm13;}});
+ 0x07: xnor({{Rd = ~(Rs1.sdw ^ Rs2_or_imm13);}});
0x08: addc({{Rd = Rs1.sdw + Rs2_or_imm13 + Ccr<0:0>;}});
- 0x09: mulx({{Rd = Rs1 * Rs2_or_imm13;}});
+ 0x09: mulx({{Rd = Rs1.sdw * Rs2_or_imm13;}});
0x0A: umul({{
Rd = Rs1.udw<31:0> * Rs2_or_imm13<31:0>;
Y = Rd<63:32>;
@@ -134,7 +134,7 @@ decode OP default Unknown::unknown()
Rd.sdw = Rs1.sdw<31:0> * Rs2_or_imm13<31:0>;
Y = Rd.sdw;
}});
- 0x0C: subc({{Rd.sdw = Rs1.sdw + (~Rs2_or_imm13) + 1 + Ccr<0:0>}});
+ 0x0C: subc({{Rd.sdw = Rs1.sdw + (~Rs2_or_imm13) + 1 - Ccr<0:0>}});
0x0D: udivx({{
if(Rs2_or_imm13 == 0) fault = new DivisionByZero;
else Rd.udw = Rs1.udw / Rs2_or_imm13;
@@ -208,7 +208,7 @@ decode OP default Unknown::unknown()
0x1C: subccc({{
int64_t resTemp, val2 = Rs2_or_imm13;
int64_t carryin = Ccr<0:0>;
- Rd = resTemp = Rs1 + ~(val2 + carryin) + 1;}},
+ Rd = resTemp = Rs1 + ~val2 + 1 - carryin;}},
{{(~((Rs1<31:0> + (~(val2 + carryin))<31:0> + 1))<32:>)}},
{{Rs1<31:> != val2<31:> && Rs1<31:> != resTemp<31:>}},
{{(~((Rs1<63:1> + (~(val2 + carryin))<63:1>) + (Rs1<0:> + (~(val2+carryin))<0:> + 1)<63:1>))<63:>}},
@@ -272,8 +272,9 @@ decode OP default Unknown::unknown()
);
0x22: taddcctv({{
int64_t resTemp, val2 = Rs2_or_imm13;
- Rd = resTemp = Rs1 + val2;
- int32_t overflow = Rs1<1:0> || val2<1:0> || (Rs1<31:> == val2<31:> && val2<31:> != resTemp<31:>);
+ Rd = Rs1 + val2;
+ int32_t overflow = Rs1<1:0> || val2<1:0> ||
+ (Rs1<31:> == val2<31:> && val2<31:> != Rd<31:>);
if(overflow) fault = new TagOverflow;}},
{{((Rs1 & 0xFFFFFFFF + val2 & 0xFFFFFFFF) >> 31)}},
{{overflow}},
@@ -322,15 +323,21 @@ decode OP default Unknown::unknown()
0x1: srax({{Rd = Rs1.sdw >> (I ? SHCNT64 : Rs2<5:0>);}});
}
// XXX might want a format rdipr thing here
- 0x28: rdasr({{
+ 0x28: decode RS1 {
+ 0xF: decode I {
+ 0x0: Nop::stbar({{/*stuff*/}});
+ 0x1: Nop::membar({{/*stuff*/}});
+ }
+ default: rdasr({{
Rd = xc->readMiscRegWithEffect(RS1 + AsrStart, fault);
- }});
- 0x29: rdhpr({{
+ }});
+ }
+ 0x29: HPriv::rdhpr({{
// XXX Need to protect with format that traps non-priv/priv
// access
Rd = xc->readMiscRegWithEffect(RS1 + HprStart, fault);
}});
- 0x2A: rdpr({{
+ 0x2A: Priv::rdpr({{
// XXX Need to protect with format that traps non-priv
// access
Rd = xc->readMiscRegWithEffect(RS1 + PrStart, fault);
@@ -397,18 +404,233 @@ decode OP default Unknown::unknown()
0x0: BasicOperate::saved({{/*Boogy Boogy*/}});
0x1: BasicOperate::restored({{/*Boogy Boogy*/}});
}
- 0x32: wrpr({{
+ 0x32: Priv::wrpr({{
// XXX Need to protect with format that traps non-priv
// access
- xc->setMiscRegWithEffect(RD + PrStart, Rs1 ^ Rs2_or_imm13);
+ fault = xc->setMiscRegWithEffect(RD + PrStart, Rs1 ^ Rs2_or_imm13);
}});
- 0x33: wrhpr({{
+ 0x33: HPriv::wrhpr({{
// XXX Need to protect with format that traps non-priv/priv
// access
- xc->setMiscRegWithEffect(RD + HprStart, Rs1 ^ Rs2_or_imm13);
+ fault = xc->setMiscRegWithEffect(RD + HprStart, Rs1 ^ Rs2_or_imm13);
}});
- 0x34: Trap::fpop1({{fault = new FpDisabled;}});
+ 0x34: decode OPF{
+ format BasicOperate{
+ 0x01: fmovs({{
+ Frd.sf = Frs2.sf;
+ //fsr.ftt = fsr.cexc = 0
+ Fsr &= ~(7 << 14);
+ Fsr &= ~(0x1F);
+ }});
+ 0x02: fmovd({{
+ Frd.df = Frs2.df;
+ //fsr.ftt = fsr.cexc = 0
+ Fsr &= ~(7 << 14);
+ Fsr &= ~(0x1F);
+ }});
+ 0x03: Trap::fmovq({{fault = new FpDisabled;}});
+ 0x05: fnegs({{
+ //XXX might want to explicitly flip the sign bit
+ //So cases with Nan and +/-0 don't do weird things
+ Frd.sf = -Frs2.sf;
+ //fsr.ftt = fsr.cexc = 0
+ Fsr &= ~(7 << 14);
+ Fsr &= ~(0x1F);
+ }});
+ 0x06: fnegd({{
+ //XXX might want to explicitly flip the sign bit
+ //So cases with Nan and +/-0 don't do weird things
+ Frd.df = -Frs2.df;
+ //fsr.ftt = fsr.cexc = 0
+ Fsr &= ~(7 << 14);
+ Fsr &= ~(0x1F);
+ }});
+ 0x07: Trap::fnegq({{fault = new FpDisabled;}});
+ 0x09: fabss({{
+ //XXX this instruction should be tested individually
+ //Clear the sign bit
+ Frd.sf = (float)(~(1 << 31) & ((uint32_t)Frs2.sf));
+ //fsr.ftt = fsr.cexc = 0
+ Fsr &= ~(7 << 14);
+ Fsr &= ~(0x1F);
+ }});
+ 0x0A: fabsd({{
+ //XXX this instruction should be tested individually
+ //Clear the sign bit
+ Frd.df = (float)(~((uint64_t)1 << 63) & ((uint64_t)Frs2.df));
+ //fsr.ftt = fsr.cexc = 0
+ Fsr &= ~(7 << 14);
+ Fsr &= ~(0x1F);
+ }});
+ 0x0B: Trap::fabsq({{fault = new FpDisabled;}});
+ 0x29: fsqrts({{Frd.sf = sqrt(Frs2.sf);}});
+ 0x2A: fsqrtd({{Frd.df = sqrt(Frs2.df);}});
+ 0x2B: Trap::fsqrtq({{fault = new FpDisabled;}});
+ 0x41: fadds({{Frd.sf = Frs1.sf + Frs2.sf;}});
+ 0x42: faddd({{Frd.df = Frs1.df + Frs2.df;}});
+ 0x43: Trap::faddq({{fault = new FpDisabled;}});
+ 0x45: fsubs({{Frd.sf = Frs1.sf - Frs2.sf;}});
+ 0x46: fsubd({{Frd.df = Frs1.df - Frs2.df;}});
+ 0x47: Trap::fsubq({{fault = new FpDisabled;}});
+ 0x49: fmuls({{Frd.sf = Frs1.sf * Frs2.sf;}});
+ 0x4A: fmuld({{Frd.df = Frs1.df * Frs2.df;}});
+ 0x4B: Trap::fmulq({{fault = new FpDisabled;}});
+ 0x4D: fdivs({{Frd.sf = Frs1.sf / Frs2.sf;}});
+ 0x4E: fdivd({{Frd.df = Frs1.df / Frs2.df;}});
+ 0x4F: Trap::fdivq({{fault = new FpDisabled;}});
+ 0x69: fsmuld({{Frd.df = Frs1.sf * Frs2.sf;}});
+ 0x6E: Trap::fdmulq({{fault = new FpDisabled;}});
+ 0x81: fstox({{
+ Frd.df = (double)static_cast<int64_t>(Frs2.sf);
+ }});
+ 0x82: fdtox({{
+ Frd.df = (double)static_cast<int64_t>(Frs2.df);
+ }});
+ 0x83: Trap::fqtox({{fault = new FpDisabled;}});
+ 0x84: fxtos({{
+ Frd.sf = static_cast<float>((int64_t)Frs2.df);
+ }});
+ 0x88: fxtod({{
+ Frd.df = static_cast<double>((int64_t)Frs2.df);
+ }});
+ 0x8C: Trap::fxtoq({{fault = new FpDisabled;}});
+ 0xC4: fitos({{
+ Frd.sf = static_cast<float>((int32_t)Frs2.sf);
+ }});
+ 0xC6: fdtos({{Frd.sf = Frs2.df;}});
+ 0xC7: Trap::fqtos({{fault = new FpDisabled;}});
+ 0xC8: fitod({{
+ Frd.df = static_cast<double>((int32_t)Frs2.sf);
+ }});
+ 0xC9: fstod({{Frd.df = Frs2.sf;}});
+ 0xCB: Trap::fqtod({{fault = new FpDisabled;}});
+ 0xCC: Trap::fitoq({{fault = new FpDisabled;}});
+ 0xCD: Trap::fstoq({{fault = new FpDisabled;}});
+ 0xCE: Trap::fdtoq({{fault = new FpDisabled;}});
+ 0xD1: fstoi({{
+ Frd.sf = (float)static_cast<int32_t>(Frs2.sf);
+ }});
+ 0xD2: fdtoi({{
+ Frd.sf = (float)static_cast<int32_t>(Frs2.df);
+ }});
+ 0xD3: Trap::fqtoi({{fault = new FpDisabled;}});
+ default: Trap::fpop1({{fault = new FpDisabled;}});
+ }
+ }
0x35: Trap::fpop2({{fault = new FpDisabled;}});
+ //This used to be just impdep1, but now it's a whole bunch
+ //of instructions
+ 0x36: decode OPF{
+ 0x00: Trap::edge8({{fault = new IllegalInstruction;}});
+ 0x01: Trap::edge8n({{fault = new IllegalInstruction;}});
+ 0x02: Trap::edge8l({{fault = new IllegalInstruction;}});
+ 0x03: Trap::edge8ln({{fault = new IllegalInstruction;}});
+ 0x04: Trap::edge16({{fault = new IllegalInstruction;}});
+ 0x05: Trap::edge16n({{fault = new IllegalInstruction;}});
+ 0x06: Trap::edge16l({{fault = new IllegalInstruction;}});
+ 0x07: Trap::edge16ln({{fault = new IllegalInstruction;}});
+ 0x08: Trap::edge32({{fault = new IllegalInstruction;}});
+ 0x09: Trap::edge32n({{fault = new IllegalInstruction;}});
+ 0x0A: Trap::edge32l({{fault = new IllegalInstruction;}});
+ 0x0B: Trap::edge32ln({{fault = new IllegalInstruction;}});
+ 0x10: Trap::array8({{fault = new IllegalInstruction;}});
+ 0x12: Trap::array16({{fault = new IllegalInstruction;}});
+ 0x14: Trap::array32({{fault = new IllegalInstruction;}});
+ 0x18: BasicOperate::alignaddress({{
+ uint64_t sum = Rs1 + Rs2;
+ Frd = sum & ~7;
+ Gsr = (Gsr & ~7) | (sum & 7);
+ }});
+ 0x19: Trap::bmask({{fault = new IllegalInstruction;}});
+ 0x1A: BasicOperate::alignaddresslittle({{
+ uint64_t sum = Rs1 + Rs2;
+ Frd = sum & ~7;
+ Gsr = (Gsr & ~7) | ((~sum + 1) & 7);
+ }});
+ 0x20: Trap::fcmple16({{fault = new IllegalInstruction;}});
+ 0x22: Trap::fcmpne16({{fault = new IllegalInstruction;}});
+ 0x24: Trap::fcmple32({{fault = new IllegalInstruction;}});
+ 0x26: Trap::fcmpne32({{fault = new IllegalInstruction;}});
+ 0x28: Trap::fcmpgt16({{fault = new IllegalInstruction;}});
+ 0x2A: Trap::fcmpeq16({{fault = new IllegalInstruction;}});
+ 0x2C: Trap::fcmpgt32({{fault = new IllegalInstruction;}});
+ 0x2E: Trap::fcmpeq32({{fault = new IllegalInstruction;}});
+ 0x31: Trap::fmul8x16({{fault = new IllegalInstruction;}});
+ 0x33: Trap::fmul8x16au({{fault = new IllegalInstruction;}});
+ 0x35: Trap::fmul8x16al({{fault = new IllegalInstruction;}});
+ 0x36: Trap::fmul8sux16({{fault = new IllegalInstruction;}});
+ 0x37: Trap::fmul8ulx16({{fault = new IllegalInstruction;}});
+ 0x38: Trap::fmuld8sux16({{fault = new IllegalInstruction;}});
+ 0x39: Trap::fmuld8ulx16({{fault = new IllegalInstruction;}});
+ 0x3A: Trap::fpack32({{fault = new IllegalInstruction;}});
+ 0x3B: Trap::fpack16({{fault = new IllegalInstruction;}});
+ 0x3D: Trap::fpackfix({{fault = new IllegalInstruction;}});
+ 0x3E: Trap::pdist({{fault = new IllegalInstruction;}});
+ 0x48: BasicOperate::faligndata({{
+ uint64_t msbX = (uint64_t)Frs1;
+ uint64_t lsbX = (uint64_t)Frs2;
+ uint64_t msbShift = Gsr<2:0> * 8;
+ uint64_t lsbShift = (8 - Gsr<2:0>) * 8;
+ uint64_t msbMask = ((uint64_t)(-1)) << msbShift;
+ uint64_t lsbMask = ((uint64_t)(-1)) << lsbShift;
+ Frd = ((msbX << msbShift) & msbMask) |
+ ((lsbX << lsbShift) & lsbMask);
+ }});
+ 0x4B: Trap::fpmerge({{fault = new IllegalInstruction;}});
+ 0x4C: Trap::bshuffle({{fault = new IllegalInstruction;}});
+ 0x4D: Trap::fexpand({{fault = new IllegalInstruction;}});
+ 0x50: Trap::fpadd16({{fault = new IllegalInstruction;}});
+ 0x51: Trap::fpadd16s({{fault = new IllegalInstruction;}});
+ 0x52: Trap::fpadd32({{fault = new IllegalInstruction;}});
+ 0x53: Trap::fpadd32s({{fault = new IllegalInstruction;}});
+ 0x54: Trap::fpsub16({{fault = new IllegalInstruction;}});
+ 0x55: Trap::fpsub16s({{fault = new IllegalInstruction;}});
+ 0x56: Trap::fpsub32({{fault = new IllegalInstruction;}});
+ 0x57: Trap::fpsub32s({{fault = new IllegalInstruction;}});
+ 0x60: BasicOperate::fzero({{Frd.df = 0;}});
+ 0x61: BasicOperate::fzeros({{Frd.sf = 0;}});
+ 0x62: Trap::fnor({{fault = new IllegalInstruction;}});
+ 0x63: Trap::fnors({{fault = new IllegalInstruction;}});
+ 0x64: Trap::fandnot2({{fault = new IllegalInstruction;}});
+ 0x65: Trap::fandnot2s({{fault = new IllegalInstruction;}});
+ 0x66: BasicOperate::fnot2({{
+ Frd.df = (double)(~((uint64_t)Frs2.df));
+ }});
+ 0x67: BasicOperate::fnot2s({{
+ Frd.sf = (float)(~((uint32_t)Frs2.sf));
+ }});
+ 0x68: Trap::fandnot1({{fault = new IllegalInstruction;}});
+ 0x69: Trap::fandnot1s({{fault = new IllegalInstruction;}});
+ 0x6A: BasicOperate::fnot1({{
+ Frd.df = (double)(~((uint64_t)Frs1.df));
+ }});
+ 0x6B: BasicOperate::fnot1s({{
+ Frd.sf = (float)(~((uint32_t)Frs1.sf));
+ }});
+ 0x6C: Trap::fxor({{fault = new IllegalInstruction;}});
+ 0x6D: Trap::fxors({{fault = new IllegalInstruction;}});
+ 0x6E: Trap::fnand({{fault = new IllegalInstruction;}});
+ 0x6F: Trap::fnands({{fault = new IllegalInstruction;}});
+ 0x70: Trap::fand({{fault = new IllegalInstruction;}});
+ 0x71: Trap::fands({{fault = new IllegalInstruction;}});
+ 0x72: Trap::fxnor({{fault = new IllegalInstruction;}});
+ 0x73: Trap::fxnors({{fault = new IllegalInstruction;}});
+ 0x74: BasicOperate::fsrc1({{Frd.df = Frs1.df;}});
+ 0x75: BasicOperate::fsrc1s({{Frd.sf = Frs1.sf;}});
+ 0x76: Trap::fornot2({{fault = new IllegalInstruction;}});
+ 0x77: Trap::fornot2s({{fault = new IllegalInstruction;}});
+ 0x78: BasicOperate::fsrc2({{Frd.df = Frs2.df;}});
+ 0x79: BasicOperate::fsrc2s({{Frd.sf = Frs2.sf;}});
+ 0x7A: Trap::fornot1({{fault = new IllegalInstruction;}});
+ 0x7B: Trap::fornot1s({{fault = new IllegalInstruction;}});
+ 0x7C: Trap::for({{fault = new IllegalInstruction;}});
+ 0x7D: Trap::fors({{fault = new IllegalInstruction;}});
+ 0x7E: Trap::fone({{fault = new IllegalInstruction;}});
+ 0x7F: Trap::fones({{fault = new IllegalInstruction;}});
+ 0x80: Trap::shutdown({{fault = new IllegalInstruction;}});
+ 0x81: Trap::siam({{fault = new IllegalInstruction;}});
+ }
+ 0x37: Trap::impdep2({{fault = new IllegalInstruction;}});
0x38: Branch::jmpl({{
Addr target = Rs1 + Rs2_or_imm13;
if(target & 0x3)
@@ -549,7 +771,7 @@ decode OP default Unknown::unknown()
NNPC = Tnpc + 4;
Tl = Tl - 1;
}});
- 0x1: BasicOperate::retry({{
+ 0x1: Priv::retry({{
if(Tl == 0)
return new IllegalInstruction;
Cwp = Tstate<4:0>;
@@ -630,27 +852,28 @@ decode OP default Unknown::unknown()
Mem = temp;
}}, {{32}});
format Trap {
- 0x20: ldf({{fault = new FpDisabled;}});
+ 0x20: Load::ldf({{Frd.sf = ((float)Mem);}}, {{32}});
0x21: decode X {
0x0: Load::ldfsr({{Fsr = Mem<31:0> | Fsr<63:32>;}}, {{32}});
0x1: Load::ldxfsr({{Fsr = Mem;}}, {{64}});
}
0x22: ldqf({{fault = new FpDisabled;}});
- 0x23: lddf({{fault = new FpDisabled;}});
- 0x24: stf({{fault = new FpDisabled;}});
+ 0x23: Load::lddf({{Frd.df = ((double)Mem);}}, {{64}});
+ 0x24: Store::stf({{Mem = ((int32_t)Frd.sf);}}, {{32}});
0x25: decode X {
0x0: Store::stfsr({{Mem = Fsr<31:0>;}}, {{32}});
0x1: Store::stxfsr({{Mem = Fsr;}}, {{64}});
}
0x26: stqf({{fault = new FpDisabled;}});
- 0x27: stdf({{fault = new FpDisabled;}});
+ 0x27: Store::stdf({{Mem = ((int64_t)Frd.df);}}, {{64}});
0x2D: Nop::prefetch({{ }});
- 0x30: ldfa({{return new FpDisabled;}});
+ 0x30: Load::ldfa({{Frd.sf = ((float)Mem);}}, {{32}});
0x32: ldqfa({{fault = new FpDisabled;}});
- 0x33: lddfa({{fault = new FpDisabled;}});
- 0x34: stfa({{fault = new FpDisabled;}});
- 0x35: stqfa({{fault = new FpDisabled;}});
- 0x36: stdfa({{fault = new FpDisabled;}});
+ 0x33: Load::lddfa({{Frd.df = ((double)Mem);}}, {{64}});
+ 0x34: Store::stfa({{Mem = ((int32_t)Frd.sf);}}, {{32}});
+ 0x36: stqfa({{fault = new FpDisabled;}});
+ //XXX need to work in the ASI thing
+ 0x37: Store::stdfa({{Mem = ((uint64_t)Frd.df);}}, {{64}});
0x3C: Cas::casa({{
uint64_t val = Mem.uw;
if(Rs2.uw == val)
diff --git a/src/arch/sparc/isa/formats/basic.isa b/src/arch/sparc/isa/formats/basic.isa
index 60432cb6b..0a47a7ffe 100644
--- a/src/arch/sparc/isa/formats/basic.isa
+++ b/src/arch/sparc/isa/formats/basic.isa
@@ -63,7 +63,6 @@ def template BasicExecute {{
{
Fault fault = NoFault;
- %(fp_enable_check)s;
%(op_decl)s;
%(op_rd)s;
%(code)s;
@@ -81,11 +80,6 @@ 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);
-}};
-
// The most basic instruction format... used only for a few misc. insts
def format BasicOperate(code, *flags) {{
iop = InstObjParams(name, Name, 'SparcStaticInst',
diff --git a/src/arch/sparc/isa/formats/branch.isa b/src/arch/sparc/isa/formats/branch.isa
index 7d46ce739..8a3f05173 100644
--- a/src/arch/sparc/isa/formats/branch.isa
+++ b/src/arch/sparc/isa/formats/branch.isa
@@ -69,47 +69,18 @@ output header {{
};
/**
- * Base class for branches with 19 bit displacements.
+ * Base class for branches with n bit displacements.
*/
- class Branch19 : public BranchDisp
+ template<int bits>
+ class BranchNBits : public BranchDisp
{
protected:
// Constructor
- Branch19(const char *mnem, MachInst _machInst,
+ BranchNBits(const char *mnem, MachInst _machInst,
OpClass __opClass) :
BranchDisp(mnem, _machInst, __opClass)
{
- disp = sign_ext(DISP19 << 2, 21);
- }
- };
-
- /**
- * Base class for branches with 22 bit displacements.
- */
- class Branch22 : public BranchDisp
- {
- protected:
- // Constructor
- Branch22(const char *mnem, MachInst _machInst,
- OpClass __opClass) :
- BranchDisp(mnem, _machInst, __opClass)
- {
- disp = sign_ext(DISP22 << 2, 24);
- }
- };
-
- /**
- * Base class for branches with 30 bit displacements.
- */
- class Branch30 : public BranchDisp
- {
- protected:
- // Constructor
- Branch30(const char *mnem, MachInst _machInst,
- OpClass __opClass) :
- BranchDisp(mnem, _machInst, __opClass)
- {
- disp = sign_ext(DISP30 << 2, 32);
+ disp = sign_ext(_machInst << 2, bits + 2);
}
};
@@ -149,29 +120,23 @@ output header {{
}};
output decoder {{
+
+ template class BranchNBits<19>;
+
+ template class BranchNBits<22>;
+
+ template class BranchNBits<30>;
+
std::string Branch::generateDisassembly(Addr pc,
const SymbolTable *symtab) const
{
std::stringstream response;
printMnemonic(response, mnemonic);
-
- if (_numSrcRegs > 0)
- {
- printReg(response, _srcRegIdx[0]);
- for(int x = 1; x < _numSrcRegs; x++)
- {
+ printRegArray(response, _srcRegIdx, _numSrcRegs);
+ if(_numDestRegs && _numSrcRegs)
response << ", ";
- printReg(response, _srcRegIdx[x]);
- }
- }
-
- if (_numDestRegs > 0)
- {
- if(_numSrcRegs > 0)
- response << ", ";
- printReg(response, _destRegIdx[0]);
- }
+ printDestReg(response, 0);
return response.str();
}
@@ -182,27 +147,13 @@ output decoder {{
std::stringstream response;
printMnemonic(response, mnemonic);
-
- if (_numSrcRegs > 0)
- {
- printReg(response, _srcRegIdx[0]);
- for(int x = 1; x < _numSrcRegs; x++)
- {
- response << ", ";
- printReg(response, _srcRegIdx[x]);
- }
- }
-
+ printRegArray(response, _srcRegIdx, _numSrcRegs);
if(_numSrcRegs > 0)
response << ", ";
-
ccprintf(response, "0x%x", imm);
-
if (_numDestRegs > 0)
- {
response << ", ";
- printReg(response, _destRegIdx[0]);
- }
+ printDestReg(response, 0);
return response.str();
}
@@ -292,32 +243,10 @@ def format Branch(code, *opt_flags) {{
}};
// Primary format for branch instructions:
-def format Branch19(code, *opt_flags) {{
- code = re.sub(r'handle_annul', handle_annul, code)
- codeBlk = CodeBlock(code)
- iop = InstObjParams(name, Name, 'Branch19', codeBlk, opt_flags)
- header_output = BasicDeclare.subst(iop)
- decoder_output = BasicConstructor.subst(iop)
- exec_output = BranchExecute.subst(iop)
- decode_block = BasicDecode.subst(iop)
-}};
-
-// Primary format for branch instructions:
-def format Branch22(code, *opt_flags) {{
- code = re.sub(r'handle_annul', handle_annul, code)
- codeBlk = CodeBlock(code)
- iop = InstObjParams(name, Name, 'Branch22', codeBlk, opt_flags)
- header_output = BasicDeclare.subst(iop)
- decoder_output = BasicConstructor.subst(iop)
- exec_output = BranchExecute.subst(iop)
- decode_block = BasicDecode.subst(iop)
-}};
-
-// Primary format for branch instructions:
-def format Branch30(code, *opt_flags) {{
+def format BranchN(bits, code, *opt_flags) {{
code = re.sub(r'handle_annul', handle_annul, code)
codeBlk = CodeBlock(code)
- iop = InstObjParams(name, Name, 'Branch30', codeBlk, opt_flags)
+ iop = InstObjParams(name, Name, "BranchNBits<%d>" % bits, codeBlk, opt_flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
exec_output = BranchExecute.subst(iop)
diff --git a/src/arch/sparc/isa/formats/integerop.isa b/src/arch/sparc/isa/formats/integerop.isa
index 1894ce541..27616216e 100644
--- a/src/arch/sparc/isa/formats/integerop.isa
+++ b/src/arch/sparc/isa/formats/integerop.isa
@@ -132,7 +132,7 @@ output header {{
OpClass __opClass) :
IntOpImm(mnem, _machInst, __opClass)
{
- imm = (IMM22 << 10) & 0xFFFFFC00;
+ imm = (IMM22 & 0x3FFFFF) << 10;
}
std::string generateDisassembly(Addr pc,
@@ -157,12 +157,9 @@ output decoder {{
if(!strcmp(mnemonic, "or") && _srcRegIdx[0] == 0)
{
printMnemonic(os, "mov");
- if(_numSrcRegs > 0)
- printReg(os, _srcRegIdx[1]);
+ printSrcReg(os, 1);
ccprintf(os, ", ");
- if(_numDestRegs > 0)
- printReg(os, _destRegIdx[0]);
-
+ printDestReg(os, 0);
return true;
}
return false;
@@ -173,32 +170,24 @@ output decoder {{
{
if(!strcmp(mnemonic, "or"))
{
- if(_srcRegIdx[0] == 0)
+ if(_numSrcRegs > 0 && _srcRegIdx[0] == 0)
{
if(imm == 0)
- {
printMnemonic(os, "clr");
- if(_numDestRegs > 0)
- printReg(os, _destRegIdx[0]);
- return true;
- }
else
{
printMnemonic(os, "mov");
- ccprintf(os, ", 0x%x, ", imm);
- if(_numDestRegs > 0)
- printReg(os, _destRegIdx[0]);
- return true;
+ ccprintf(os, " 0x%x, ", imm);
}
+ printDestReg(os, 0);
+ return true;
}
else if(imm == 0)
{
printMnemonic(os, "mov");
- if(_numSrcRegs > 0)
- printReg(os, _srcRegIdx[0]);
+ printSrcReg(os, 0);
ccprintf(os, ", ");
- if(_numDestRegs > 0)
- printReg(os, _destRegIdx[0]);
+ printDestReg(os, 0);
return true;
}
}
@@ -210,25 +199,13 @@ output decoder {{
{
std::stringstream response;
- if(!printPseudoOps(response, pc, symtab))
- {
- printMnemonic(response, mnemonic);
- if (_numSrcRegs > 0)
- {
- printReg(response, _srcRegIdx[0]);
- for(int x = 1; x < _numSrcRegs; x++)
- {
- response << ", ";
- printReg(response, _srcRegIdx[x]);
- }
- }
- if (_numDestRegs > 0)
- {
- if(_numSrcRegs > 0)
- response << ", ";
- printReg(response, _destRegIdx[0]);
- }
- }
+ if(printPseudoOps(response, pc, symtab))
+ return response.str();
+ printMnemonic(response, mnemonic);
+ printRegArray(response, _srcRegIdx, _numSrcRegs);
+ if(_numDestRegs && _numSrcRegs)
+ response << ", ";
+ printDestReg(response, 0);
return response.str();
}
@@ -237,27 +214,16 @@ output decoder {{
{
std::stringstream response;
- if(!printPseudoOps(response, pc, symtab))
- {
- printMnemonic(response, mnemonic);
- if (_numSrcRegs > 0)
- {
- printReg(response, _srcRegIdx[0]);
- for(int x = 1; x < _numSrcRegs - 1; x++)
- {
- response << ", ";
- printReg(response, _srcRegIdx[x]);
- }
- }
- if(_numSrcRegs > 0)
- response << ", ";
- ccprintf(response, "0x%x", imm);
- if (_numDestRegs > 0)
- {
- response << ", ";
- printReg(response, _destRegIdx[0]);
- }
- }
+ if(printPseudoOps(response, pc, symtab))
+ return response.str();
+ printMnemonic(response, mnemonic);
+ printRegArray(response, _srcRegIdx, _numSrcRegs);
+ if(_numSrcRegs > 0)
+ response << ", ";
+ ccprintf(response, "0x%x", imm);
+ if(_numDestRegs > 0)
+ response << ", ";
+ printDestReg(response, 0);
return response.str();
}
@@ -267,10 +233,8 @@ output decoder {{
std::stringstream response;
printMnemonic(response, mnemonic);
- if(_numSrcRegs > 0)
- response << ", ";
ccprintf(response, "%%hi(0x%x), ", imm);
- printReg(response, _destRegIdx[0]);
+ printDestReg(response, 0);
return response.str();
}
}};
@@ -316,38 +280,29 @@ let {{
return (header_output, decoder_output, exec_output, decode_block)
calcCcCode = '''
- uint8_t tmp_ccriccc;
- uint8_t tmp_ccriccv;
- uint8_t tmp_ccriccz;
- uint8_t tmp_ccriccn;
- uint8_t tmp_ccrxccc;
- uint8_t tmp_ccrxccv;
- uint8_t tmp_ccrxccz;
- uint8_t tmp_ccrxccn;
-
- tmp_ccriccn = (Rd >> 31) & 1;
- tmp_ccriccz = ((Rd & 0xFFFFFFFF) == 0);
- tmp_ccrxccn = (Rd >> 63) & 1;
- tmp_ccrxccz = (Rd == 0);
- tmp_ccriccv = %(ivValue)s & 1;
- tmp_ccriccc = %(icValue)s & 1;
- tmp_ccrxccv = %(xvValue)s & 1;
- tmp_ccrxccc = %(xcValue)s & 1;
-
- Ccr = tmp_ccriccc | tmp_ccriccv << 1 |
- tmp_ccriccz << 2 | tmp_ccriccn << 3|
- tmp_ccrxccc << 4 | tmp_ccrxccv << 5|
- tmp_ccrxccz << 6| tmp_ccrxccn << 7;
-
-
- DPRINTF(Sparc, "in = %%d\\n", (uint16_t)tmp_ccriccn);
- DPRINTF(Sparc, "iz = %%d\\n", (uint16_t)tmp_ccriccz);
- DPRINTF(Sparc, "xn = %%d\\n", (uint16_t)tmp_ccrxccn);
- DPRINTF(Sparc, "xz = %%d\\n", (uint16_t)tmp_ccrxccz);
- DPRINTF(Sparc, "iv = %%d\\n", (uint16_t)tmp_ccriccv);
- DPRINTF(Sparc, "ic = %%d\\n", (uint16_t)tmp_ccriccc);
- DPRINTF(Sparc, "xv = %%d\\n", (uint16_t)tmp_ccrxccv);
- DPRINTF(Sparc, "xc = %%d\\n", (uint16_t)tmp_ccrxccc);
+ uint16_t _ic, _iv, _iz, _in, _xc, _xv, _xz, _xn;
+
+ _in = (Rd >> 31) & 1;
+ _iz = ((Rd & 0xFFFFFFFF) == 0);
+ _xn = (Rd >> 63) & 1;
+ _xz = (Rd == 0);
+ _iv = %(ivValue)s & 1;
+ _ic = %(icValue)s & 1;
+ _xv = %(xvValue)s & 1;
+ _xc = %(xcValue)s & 1;
+
+ Ccr = _ic << 0 | _iv << 1 | _iz << 2 | _in << 3 |
+ _xc << 4 | _xv << 5 | _xz << 6 | _xn << 7;
+
+
+ DPRINTF(Sparc, "in = %%d\\n", _in);
+ DPRINTF(Sparc, "iz = %%d\\n", _iz);
+ DPRINTF(Sparc, "xn = %%d\\n", _xn);
+ DPRINTF(Sparc, "xz = %%d\\n", _xz);
+ DPRINTF(Sparc, "iv = %%d\\n", _iv);
+ DPRINTF(Sparc, "ic = %%d\\n", _ic);
+ DPRINTF(Sparc, "xv = %%d\\n", _xv);
+ DPRINTF(Sparc, "xc = %%d\\n", _xc);
'''
}};
diff --git a/src/arch/sparc/isa/formats/priv.isa b/src/arch/sparc/isa/formats/priv.isa
index 7df59d736..d7ee01519 100644
--- a/src/arch/sparc/isa/formats/priv.isa
+++ b/src/arch/sparc/isa/formats/priv.isa
@@ -72,7 +72,11 @@ output decoder {{
std::string Priv::generateDisassembly(Addr pc,
const SymbolTable *symtab) const
{
- return "Privileged Instruction";
+ std::stringstream response;
+
+ printMnemonic(response, mnemonic);
+
+ return response.str();
}
}};
@@ -87,9 +91,10 @@ def template PrivExecute {{
if(%(check)s)
return new PrivilegedAction;
+ Fault fault = NoFault;
%(code)s;
%(op_wb)s;
- return NoFault;
+ return fault;
}
}};
@@ -116,10 +121,17 @@ let {{
// Primary format for integer operate instructions:
def format Priv(code, *opt_flags) {{
- checkCode = "((xc->readMiscReg(PrStart + MISCREG_PSTATE))<2:2>)"
+ checkCode = '''((xc->readMiscReg(PrStart + MISCREG_PSTATE))<2:2>) ||
+ ((xc->readMiscReg(HprStart + MISCREG_HPSTATE))<2:2>)'''
(header_output, decoder_output,
exec_output, decode_block) = doPrivFormat(code,
- checkCode, name, Name, opt_flags)
+ checkCode, name, Name, opt_flags + ('IprAccessOp',))
}};
+def format HPriv(code, *opt_flags) {{
+ checkCode = "((xc->readMiscReg(HprStart + MISCREG_HPSTATE))<2:2>)"
+ (header_output, decoder_output,
+ exec_output, decode_block) = doPrivFormat(code,
+ checkCode, name, Name, opt_flags + ('IprAccessOp',))
+}};
diff --git a/src/arch/sparc/isa/includes.isa b/src/arch/sparc/isa/includes.isa
index 40afb3722..3783051c4 100644
--- a/src/arch/sparc/isa/includes.isa
+++ b/src/arch/sparc/isa/includes.isa
@@ -36,7 +36,6 @@
output header {{
#include <sstream>
#include <iostream>
-#include <iomanip>
#include "cpu/static_inst.hh"
#include "arch/sparc/faults.hh"
@@ -50,7 +49,6 @@ output decoder {{
#include "base/loader/symtab.hh"
#include "cpu/thread_context.hh" // for Jump::branchTarget()
-#include <math.h>
#if defined(linux)
#include <fenv.h>
#endif
@@ -59,14 +57,10 @@ using namespace SparcISA;
}};
output exec {{
-#include <math.h>
#if defined(linux)
#include <fenv.h>
#endif
-#ifdef FULL_SYSTEM
-//#include "sim/pseudo_inst.hh"
-#endif
#include "cpu/base.hh"
#include "cpu/exetrace.hh"
#include "sim/sim_exit.hh"
diff --git a/src/arch/sparc/isa/operands.isa b/src/arch/sparc/isa/operands.isa
index 9e5c783e8..605816083 100644
--- a/src/arch/sparc/isa/operands.isa
+++ b/src/arch/sparc/isa/operands.isa
@@ -51,12 +51,12 @@ def operands {{
'RdHigh': ('IntReg', 'udw', 'RD | 1', 'IsInteger', 3),
'Rs1': ('IntReg', 'udw', 'RS1', 'IsInteger', 4),
'Rs2': ('IntReg', 'udw', 'RS2', 'IsInteger', 5),
- #'Fa': ('FloatReg', 'df', 'FA', 'IsFloating', 1),
- #'Fb': ('FloatReg', 'df', 'FB', 'IsFloating', 2),
- #'Fc': ('FloatReg', 'df', 'FC', 'IsFloating', 3),
- 'Mem': ('Mem', 'udw', None, ('IsMemRef', 'IsLoad', 'IsStore'), 4),
- 'NPC': ('NPC', 'udw', None, ( None, None, 'IsControl' ), 4),
- 'NNPC': ('NNPC', 'udw', None, (None, None, 'IsControl' ), 4),
+ 'Frd': ('FloatReg', 'df', 'RD', 'IsFloating', 10),
+ 'Frs1': ('FloatReg', 'df', 'RS1', 'IsFloating', 11),
+ 'Frs2': ('FloatReg', 'df', 'RS2', 'IsFloating', 12),
+ 'Mem': ('Mem', 'udw', None, ('IsMemRef', 'IsLoad', 'IsStore'), 20),
+ 'NPC': ('NPC', 'udw', None, ( None, None, 'IsControl' ), 31),
+ 'NNPC': ('NNPC', 'udw', None, (None, None, 'IsControl' ), 32),
#'Runiq': ('ControlReg', 'uq', 'Uniq', None, 1),
#'FPCR': ('ControlReg', 'uq', 'Fpcr', None, 1),
'R0': ('IntReg', 'udw', '0', None, 6),
@@ -65,24 +65,25 @@ def operands {{
'R16': ('IntReg', 'udw', '16', None, 9),
# Control registers
- 'Y': ('ControlReg', 'udw', 'MISCREG_Y', None, 12),
- 'Ccr': ('ControlReg', 'udw', 'MISCREG_CCR', None, 17),
- 'Asi': ('ControlReg', 'udw', 'MISCREG_ASI', None, 26),
+ 'Y': ('ControlReg', 'udw', 'MISCREG_Y', None, 40),
+ 'Ccr': ('ControlReg', 'udw', 'MISCREG_CCR', None, 41),
+ 'Asi': ('ControlReg', 'udw', 'MISCREG_ASI', None, 42),
- 'Tpc': ('ControlReg', 'udw', 'MISCREG_TPC', None, 28),
- 'Tnpc': ('ControlReg', 'udw', 'MISCREG_TNPC', None, 28),
- 'Tstate': ('ControlReg', 'udw', 'MISCREG_TSTATE', None, 28),
- 'Pstate': ('ControlReg', 'udw', 'MISCREG_PSTATE', None, 1),
- 'Tl': ('ControlReg', 'udw', 'MISCREG_TL', None, 27),
+ 'Tpc': ('ControlReg', 'udw', 'MISCREG_TPC', None, 43),
+ 'Tnpc': ('ControlReg', 'udw', 'MISCREG_TNPC', None, 44),
+ 'Tstate': ('ControlReg', 'udw', 'MISCREG_TSTATE', None, 45),
+ 'Pstate': ('ControlReg', 'udw', 'MISCREG_PSTATE', None, 46),
+ 'Tl': ('ControlReg', 'udw', 'MISCREG_TL', None, 47),
- 'Cwp': ('ControlReg', 'udw', 'MISCREG_CWP', None, 15),
- 'Cansave': ('ControlReg', 'udw', 'MISCREG_CANSAVE', None, 34),
- 'Canrestore': ('ControlReg', 'udw', 'MISCREG_CANRESTORE', None, 35),
- 'Cleanwin': ('ControlReg', 'udw', 'MISCREG_CLEANWIN', None, 37),
- 'Otherwin': ('ControlReg', 'udw', 'MISCREG_OTHERWIN', None, 36),
- 'Wstate': ('ControlReg', 'udw', 'MISCREG_WSTATE', None, 38),
- 'Gl': ('ControlReg', 'udw', 'MISCREG_GL', None, 12),
+ 'Cwp': ('ControlReg', 'udw', 'MISCREG_CWP', None, 48),
+ 'Cansave': ('ControlReg', 'udw', 'MISCREG_CANSAVE', None, 49),
+ 'Canrestore': ('ControlReg', 'udw', 'MISCREG_CANRESTORE', None, 50),
+ 'Cleanwin': ('ControlReg', 'udw', 'MISCREG_CLEANWIN', None, 51),
+ 'Otherwin': ('ControlReg', 'udw', 'MISCREG_OTHERWIN', None, 52),
+ 'Wstate': ('ControlReg', 'udw', 'MISCREG_WSTATE', None, 53),
+ 'Gl': ('ControlReg', 'udw', 'MISCREG_GL', None, 54),
- 'Fsr': ('ControlReg', 'udw', 'MISCREG_FSR', None, 47)
+ 'Fsr': ('ControlReg', 'udw', 'MISCREG_FSR', None, 55),
+ 'Gsr': ('ControlReg', 'udw', 'MISCREG_GSR', None, 56)
}};
diff --git a/src/arch/sparc/isa_traits.hh b/src/arch/sparc/isa_traits.hh
index 346f7b730..7f830eb28 100644
--- a/src/arch/sparc/isa_traits.hh
+++ b/src/arch/sparc/isa_traits.hh
@@ -25,13 +25,13 @@
* (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
- * Gabe Black
+ * Authors: Gabe Black
*/
#ifndef __ARCH_SPARC_ISA_TRAITS_HH__
#define __ARCH_SPARC_ISA_TRAITS_HH__
+#include "arch/sparc/types.hh"
#include "base/misc.hh"
#include "config/full_system.hh"
#include "sim/host.hh"
@@ -46,70 +46,45 @@ class StaticInstPtr;
namespace BigEndianGuest {}
-#if !FULL_SYSTEM
-class SyscallReturn
-{
- public:
- template <class T>
- SyscallReturn(T v, bool s)
- {
- retval = (uint64_t)v;
- success = s;
- }
-
- template <class T>
- SyscallReturn(T v)
- {
- success = (v >= 0);
- retval = (uint64_t)v;
- }
-
- ~SyscallReturn() {}
-
- SyscallReturn& operator=(const SyscallReturn& s)
- {
- retval = s.retval;
- success = s.success;
- return *this;
- }
-
- bool successful() { return success; }
- uint64_t value() { return retval; }
-
- private:
- uint64_t retval;
- bool success;
-};
-
-#endif
-
#if FULL_SYSTEM
#include "arch/sparc/isa_fullsys_traits.hh"
#endif
namespace SparcISA
{
+ class RegFile;
+
+ //This makes sure the big endian versions of certain functions are used.
+ using namespace BigEndianGuest;
+
+ //TODO this needs to be a SPARC Noop
+ // Alpha UNOP (ldq_u r31,0(r0))
+ const MachInst NoopMachInst = 0x2ffe0000;
+
+ const int NumIntRegs = 32;
+ const int NumFloatRegs = 64;
+ const int NumMiscRegs = 40;
// These enumerate all the registers for dependence tracking.
enum DependenceTags {
// 0..31 are the integer regs 0..31
- // 32..63 are the FP regs 0..31, i.e. use (reg + FP_Base_DepTag)
- FP_Base_DepTag = 32,
- Ctrl_Base_DepTag = 96,
+ // 32..95 are the FP regs 0..31, i.e. use (reg + FP_Base_DepTag)
+ FP_Base_DepTag = NumIntRegs,
+ Ctrl_Base_DepTag = NumIntRegs + NumFloatRegs,
//XXX These are here solely to get compilation and won't work
Fpcr_DepTag = 0,
Uniq_DepTag = 0
};
- //This makes sure the big endian versions of certain functions are used.
- using namespace BigEndianGuest;
- typedef uint32_t MachInst;
- typedef uint64_t ExtMachInst;
+ // MAXTL - maximum trap level
+ const int MaxPTL = 2;
+ const int MaxTL = 6;
+ const int MaxGL = 3;
+ const int MaxPGL = 2;
- const int NumIntRegs = 32;
- const int NumFloatRegs = 64;
- const int NumMiscRegs = 32;
+ // NWINDOWS - number of register windows, can be 3 to 32
+ const int NWindows = 32;
// semantically meaningful register indices
const int ZeroReg = 0; // architecturally meaningful
@@ -131,14 +106,6 @@ namespace SparcISA
const int MaxInstSrcRegs = 8;
const int MaxInstDestRegs = 9;
- typedef uint64_t IntReg;
-
- // control register file contents
- typedef uint64_t MiscReg;
-
- typedef double FloatReg;
- typedef uint64_t FloatRegBits;
-
//8K. This value is implmentation specific; and should probably
//be somewhere else.
const int LogVMPageSize = 13;
@@ -165,29 +132,4 @@ namespace SparcISA
extern const MachInst NoopMachInst;
}
-#include "arch/sparc/regfile.hh"
-
-namespace SparcISA
-{
-
-#if !FULL_SYSTEM
- static inline void setSyscallReturn(SyscallReturn return_value,
- RegFile *regs)
- {
- // check for error condition. SPARC syscall convention is to
- // indicate success/failure in reg the carry bit of the ccr
- // and put the return value itself in the standard return value reg ().
- if (return_value.successful()) {
- // no error, clear XCC.C
- regs->setMiscReg(MISCREG_CCR, regs->readMiscReg(MISCREG_CCR) & 0xEF);
- regs->setIntReg(ReturnValueReg, return_value.value());
- } else {
- // got an error, set XCC.C
- regs->setMiscReg(MISCREG_CCR, regs->readMiscReg(MISCREG_CCR) | 0x10);
- regs->setIntReg(ReturnValueReg, return_value.value());
- }
- }
-#endif
-};
-
#endif // __ARCH_SPARC_ISA_TRAITS_HH__
diff --git a/src/arch/sparc/linux/linux.cc b/src/arch/sparc/linux/linux.cc
index ae6ffbc2a..1211d5f65 100644
--- a/src/arch/sparc/linux/linux.cc
+++ b/src/arch/sparc/linux/linux.cc
@@ -29,6 +29,7 @@
*/
#include "arch/sparc/linux/linux.hh"
+#include <fcntl.h>
// open(2) flags translation table
OpenFlagTransTable SparcLinux::openFlagTable[] = {
diff --git a/src/arch/sparc/linux/process.cc b/src/arch/sparc/linux/process.cc
index e27255e67..8c2de8ca3 100644
--- a/src/arch/sparc/linux/process.cc
+++ b/src/arch/sparc/linux/process.cc
@@ -199,7 +199,7 @@ SyscallDesc SparcLinuxProcess::syscallDescs[] = {
/* 99 */ SyscallDesc("accept", unimplementedFunc),
/* 100 */ SyscallDesc("getpriority", unimplementedFunc),
/* 101 */ SyscallDesc("rt_sigreturn", unimplementedFunc),
- /* 102 */ SyscallDesc("rt_sigaction", unimplementedFunc),
+ /* 102 */ SyscallDesc("rt_sigaction", ignoreFunc),
/* 103 */ SyscallDesc("rt_sigprocmask", unimplementedFunc),
/* 104 */ SyscallDesc("rt_sigpending", unimplementedFunc),
/* 105 */ SyscallDesc("rt_sigtimedwait", unimplementedFunc),
@@ -295,7 +295,7 @@ SyscallDesc SparcLinuxProcess::syscallDescs[] = {
/* 195 */ SyscallDesc("epoll_wait", unimplementedFunc),
/* 196 */ SyscallDesc("ioprio_set", unimplementedFunc),
/* 197 */ SyscallDesc("getppid", getppidFunc),
- /* 198 */ SyscallDesc("sigaction", unimplementedFunc),
+ /* 198 */ SyscallDesc("sigaction", ignoreFunc),
/* 199 */ SyscallDesc("sgetmask", unimplementedFunc),
/* 200 */ SyscallDesc("ssetmask", unimplementedFunc),
/* 201 */ SyscallDesc("sigsuspend", unimplementedFunc),
diff --git a/src/arch/sparc/linux/process.hh b/src/arch/sparc/linux/process.hh
index f4819ba84..4af8f0f75 100644
--- a/src/arch/sparc/linux/process.hh
+++ b/src/arch/sparc/linux/process.hh
@@ -32,6 +32,7 @@
#define __SPARC_LINUX_PROCESS_HH__
#include "arch/sparc/linux/linux.hh"
+#include "arch/sparc/syscallreturn.hh"
#include "arch/sparc/process.hh"
#include "sim/process.hh"
diff --git a/src/arch/sparc/miscregfile.cc b/src/arch/sparc/miscregfile.cc
new file mode 100644
index 000000000..8041e45c0
--- /dev/null
+++ b/src/arch/sparc/miscregfile.cc
@@ -0,0 +1,540 @@
+/*
+ * Copyright (c) 2003-2005 The Regents of The University of Michigan
+ * 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
+ * Ali Saidi
+ */
+
+#include "arch/sparc/miscregfile.hh"
+#include "base/trace.hh"
+#include "cpu/base.hh"
+#include "cpu/thread_context.hh"
+
+using namespace SparcISA;
+using namespace std;
+
+class Checkpoint;
+
+//These functions map register indices to names
+string SparcISA::getMiscRegName(RegIndex index)
+{
+ static::string miscRegName[NumMiscRegs] =
+ {"y", "ccr", "asi", "tick", "pc", "fprs", "pcr", "pic",
+ "gsr", "softint_set", "softint_clr", "softint", "tick_cmpr",
+ "stick", "stick_cmpr",
+ "tpc", "tnpc", "tstate", "tt", "privtick", "tba", "pstate", "tl",
+ "pil", "cwp", "cansave", "canrestore", "cleanwin", "otherwin",
+ "wstate", "gl",
+ "hpstate", "htstate", "hintp", "htba", "hver", "strand_sts_reg",
+ "hstick_cmpr",
+ "fsr"};
+ return miscRegName[index];
+}
+
+#if FULL_SYSTEM
+
+//XXX These need an implementation someplace
+/** Fullsystem only register version of ReadRegWithEffect() */
+MiscReg MiscRegFile::readFSRegWithEffect(int miscReg, Fault &fault, ThreadContext *tc);
+/** Fullsystem only register version of SetRegWithEffect() */
+Fault MiscRegFile::setFSRegWithEffect(int miscReg, const MiscReg &val,
+ ThreadContext * tc);
+#endif
+
+void MiscRegFile::reset()
+{
+ pstateFields.pef = 0; //No FPU
+ //pstateFields.pef = 1; //FPU
+#if FULL_SYSTEM
+ //For SPARC, when a system is first started, there is a power
+ //on reset Trap which sets the processor into the following state.
+ //Bits that aren't set aren't defined on startup.
+ tl = MaxTL;
+ gl = MaxGL;
+
+ tickFields.counter = 0; //The TICK register is unreadable bya
+ tickFields.npt = 1; //The TICK register is unreadable by by !priv
+
+ softint = 0; // Clear all the soft interrupt bits
+ tick_cmprFields.int_dis = 1; // disable timer compare interrupts
+ tick_cmprFields.tick_cmpr = 0; // Reset to 0 for pretty printing
+ stickFields.npt = 1; //The TICK register is unreadable by by !priv
+ stick_cmprFields.int_dis = 1; // disable timer compare interrupts
+ stick_cmprFields.tick_cmpr = 0; // Reset to 0 for pretty printing
+
+
+ tt[tl] = power_on_reset;
+ pstate = 0; // fields 0 but pef
+ pstateFields.pef = 1;
+
+ hpstate = 0;
+ hpstateFields.red = 1;
+ hpstateFields.hpriv = 1;
+ hpstateFields.tlz = 0; // this is a guess
+ hintp = 0; // no interrupts pending
+ hstick_cmprFields.int_dis = 1; // disable timer compare interrupts
+ hstick_cmprFields.tick_cmpr = 0; // Reset to 0 for pretty printing
+#else
+/* //This sets up the initial state of the processor for usermode processes
+ pstateFields.priv = 0; //Process runs in user mode
+ pstateFields.ie = 1; //Interrupts are enabled
+ fsrFields.rd = 0; //Round to nearest
+ fsrFields.tem = 0; //Floating point traps not enabled
+ fsrFields.ns = 0; //Non standard mode off
+ fsrFields.qne = 0; //Floating point queue is empty
+ fsrFields.aexc = 0; //No accrued exceptions
+ fsrFields.cexc = 0; //No current exceptions
+
+ //Register window management registers
+ otherwin = 0; //No windows contain info from other programs
+ canrestore = 0; //There are no windows to pop
+ cansave = MaxTL - 2; //All windows are available to save into
+ cleanwin = MaxTL;*/
+#endif
+}
+
+MiscReg MiscRegFile::readReg(int miscReg)
+{
+ switch (miscReg) {
+ case MISCREG_Y:
+ return y;
+ case MISCREG_CCR:
+ return ccr;
+ case MISCREG_ASI:
+ return asi;
+ case MISCREG_FPRS:
+ return fprs;
+ case MISCREG_TICK:
+ return tick;
+ case MISCREG_PCR:
+ case MISCREG_PIC:
+ panic("ASR number %d not implemented\n", miscReg - AsrStart);
+ case MISCREG_GSR:
+ return gsr;
+ case MISCREG_SOFTINT:
+ return softint;
+ case MISCREG_TICK_CMPR:
+ return tick_cmpr;
+ case MISCREG_STICK:
+ return stick;
+ case MISCREG_STICK_CMPR:
+ return stick_cmpr;
+
+ /** Privilged Registers */
+ case MISCREG_TPC:
+ return tpc[tl-1];
+ case MISCREG_TNPC:
+ return tnpc[tl-1];
+ case MISCREG_TSTATE:
+ return tstate[tl-1];
+ case MISCREG_TT:
+ return tt[tl-1];
+ case MISCREG_PRIVTICK:
+ panic("Priviliged access to tick registers not implemented\n");
+ case MISCREG_TBA:
+ return tba;
+ case MISCREG_PSTATE:
+ return pstate;
+ case MISCREG_TL:
+ return tl;
+ case MISCREG_PIL:
+ return pil;
+ case MISCREG_CWP:
+ return cwp;
+ case MISCREG_CANSAVE:
+ return cansave;
+ case MISCREG_CANRESTORE:
+ return canrestore;
+ case MISCREG_CLEANWIN:
+ return cleanwin;
+ case MISCREG_OTHERWIN:
+ return otherwin;
+ case MISCREG_WSTATE:
+ return wstate;
+ case MISCREG_GL:
+ return gl;
+
+ /** Hyper privileged registers */
+ case MISCREG_HPSTATE:
+ return hpstate;
+ case MISCREG_HTSTATE:
+ return htstate[tl-1];
+ case MISCREG_HINTP:
+ panic("HINTP not implemented\n");
+ case MISCREG_HTBA:
+ return htba;
+ case MISCREG_HVER:
+ return NWindows | MaxTL << 8 | MaxGL << 16;
+ case MISCREG_STRAND_STS_REG:
+ return strandStatusReg;
+ case MISCREG_HSTICK_CMPR:
+ return hstick_cmpr;
+
+ /** Floating Point Status Register */
+ case MISCREG_FSR:
+ return fsr;
+ default:
+ panic("Miscellaneous register %d not implemented\n", miscReg);
+ }
+}
+
+MiscReg MiscRegFile::readRegWithEffect(int miscReg,
+ Fault &fault, ThreadContext * tc)
+{
+ fault = NoFault;
+ switch (miscReg) {
+ case MISCREG_Y:
+ case MISCREG_CCR:
+ case MISCREG_ASI:
+ return readReg(miscReg);
+
+ case MISCREG_TICK:
+ case MISCREG_PRIVTICK:
+ // Check for reading privilege
+ if (tickFields.npt && !isNonPriv()) {
+ fault = new PrivilegedAction;
+ return 0;
+ }
+ return tc->getCpuPtr()->curCycle() - tickFields.counter |
+ tickFields.npt << 63;
+ case MISCREG_PC:
+ return tc->readPC();
+ case MISCREG_FPRS:
+ fault = new UnimpFault("FPU not implemented\n");
+ return 0;
+ case MISCREG_PCR:
+ fault = new UnimpFault("Performance Instrumentation not impl\n");
+ return 0;
+ case MISCREG_PIC:
+ fault = new UnimpFault("Performance Instrumentation not impl\n");
+ return 0;
+ case MISCREG_GSR:
+ return readReg(miscReg);
+
+ /** Privilged Registers */
+ case MISCREG_TPC:
+ case MISCREG_TNPC:
+ case MISCREG_TSTATE:
+ case MISCREG_TT:
+ if (tl == 0) {
+ fault = new IllegalInstruction;
+ return 0;
+ } // NOTE THE FALL THROUGH!
+ case MISCREG_PSTATE:
+ case MISCREG_TL:
+ return readReg(miscReg);
+
+ case MISCREG_TBA:
+ return readReg(miscReg) & ULL(~0x7FFF);
+
+ case MISCREG_PIL:
+
+ case MISCREG_CWP:
+ case MISCREG_CANSAVE:
+ case MISCREG_CANRESTORE:
+ case MISCREG_CLEANWIN:
+ case MISCREG_OTHERWIN:
+ case MISCREG_WSTATE:
+ case MISCREG_GL:
+ return readReg(miscReg);
+
+ /** Floating Point Status Register */
+ case MISCREG_FSR:
+ panic("Floating Point not implemented\n");
+ default:
+#if FULL_SYSTEM
+ return readFSRegWithEffect(miscReg, fault, tc);
+#else
+ fault = new IllegalInstruction;
+ return 0;
+#endif
+ }
+}
+
+Fault MiscRegFile::setReg(int miscReg, const MiscReg &val)
+{
+ switch (miscReg) {
+ case MISCREG_Y:
+ y = val;
+ return NoFault;
+ case MISCREG_CCR:
+ ccr = val;
+ return NoFault;
+ case MISCREG_ASI:
+ asi = val;
+ return NoFault;
+ case MISCREG_FPRS:
+ fprs = val;
+ return NoFault;
+ case MISCREG_TICK:
+ tick = val;
+ return NoFault;
+ case MISCREG_PCR:
+ case MISCREG_PIC:
+ panic("ASR number %d not implemented\n", miscReg - AsrStart);
+ case MISCREG_GSR:
+ gsr = val;
+ case MISCREG_SOFTINT:
+ softint = val;
+ return NoFault;
+ case MISCREG_TICK_CMPR:
+ tick_cmpr = val;
+ return NoFault;
+ case MISCREG_STICK:
+ stick = val;
+ return NoFault;
+ case MISCREG_STICK_CMPR:
+ stick_cmpr = val;
+ return NoFault;
+
+ /** Privilged Registers */
+ case MISCREG_TPC:
+ tpc[tl-1] = val;
+ return NoFault;
+ case MISCREG_TNPC:
+ tnpc[tl-1] = val;
+ return NoFault;
+ case MISCREG_TSTATE:
+ tstate[tl-1] = val;
+ return NoFault;
+ case MISCREG_TT:
+ tt[tl-1] = val;
+ return NoFault;
+ case MISCREG_PRIVTICK:
+ panic("Priviliged access to tick regesiters not implemented\n");
+ case MISCREG_TBA:
+ tba = val;
+ return NoFault;
+ case MISCREG_PSTATE:
+ pstate = val;
+ return NoFault;
+ case MISCREG_TL:
+ tl = val;
+ return NoFault;
+ case MISCREG_PIL:
+ pil = val;
+ return NoFault;
+ case MISCREG_CWP:
+ cwp = val;
+ return NoFault;
+ case MISCREG_CANSAVE:
+ cansave = val;
+ return NoFault;
+ case MISCREG_CANRESTORE:
+ canrestore = val;
+ return NoFault;
+ case MISCREG_CLEANWIN:
+ cleanwin = val;
+ return NoFault;
+ case MISCREG_OTHERWIN:
+ otherwin = val;
+ return NoFault;
+ case MISCREG_WSTATE:
+ wstate = val;
+ return NoFault;
+ case MISCREG_GL:
+ gl = val;
+ return NoFault;
+
+ /** Hyper privileged registers */
+ case MISCREG_HPSTATE:
+ hpstate = val;
+ return NoFault;
+ case MISCREG_HTSTATE:
+ htstate[tl-1] = val;
+ return NoFault;
+ case MISCREG_HINTP:
+ panic("HINTP not implemented\n");
+ case MISCREG_HTBA:
+ htba = val;
+ return NoFault;
+ case MISCREG_STRAND_STS_REG:
+ strandStatusReg = val;
+ return NoFault;
+ case MISCREG_HSTICK_CMPR:
+ hstick_cmpr = val;
+ return NoFault;
+
+ /** Floating Point Status Register */
+ case MISCREG_FSR:
+ fsr = val;
+ return NoFault;
+ default:
+ panic("Miscellaneous register %d not implemented\n", miscReg);
+ }
+}
+
+Fault MiscRegFile::setRegWithEffect(int miscReg,
+ const MiscReg &val, ThreadContext * tc)
+{
+ const uint64_t Bit64 = (1ULL << 63);
+ switch (miscReg) {
+ case MISCREG_Y:
+ case MISCREG_CCR:
+ case MISCREG_ASI:
+ setReg(miscReg, val);
+ return NoFault;
+ case MISCREG_PRIVTICK:
+ case MISCREG_TICK:
+ if (isNonPriv())
+ return new PrivilegedOpcode;
+ if (isPriv())
+ return new PrivilegedAction;
+ tickFields.counter = tc->getCpuPtr()->curCycle() - val & ~Bit64;
+ tickFields.npt = val & Bit64 ? 1 : 0;
+ return NoFault;
+ case MISCREG_PC:
+ return new IllegalInstruction;
+ case MISCREG_FPRS:
+ return new UnimpFault("FPU not implemented\n");
+ case MISCREG_PCR:
+ return new UnimpFault("Performance Instrumentation not impl\n");
+ case MISCREG_PIC:
+ return new UnimpFault("Performance Instrumentation not impl\n");
+ case MISCREG_GSR:
+ return setReg(miscReg, val);
+
+ /** Privilged Registers */
+ case MISCREG_TPC:
+ case MISCREG_TNPC:
+ case MISCREG_TSTATE:
+ case MISCREG_TT:
+ if (tl == 0)
+ return new IllegalInstruction;
+ setReg(miscReg, val);
+ return NoFault;
+
+ case MISCREG_TBA:
+ // clear lower 7 bits on writes.
+ setReg(miscReg, val & ULL(~0x7FFF));
+ return NoFault;
+
+ case MISCREG_PSTATE:
+ setReg(miscReg, val);
+ return NoFault;
+
+ case MISCREG_TL:
+ if (isHyperPriv() && val > MaxTL)
+ setReg(miscReg, MaxTL);
+ else if (isPriv() && !isHyperPriv() && val > MaxPTL)
+ setReg(miscReg, MaxPTL);
+ else
+ setReg(miscReg, val);
+ return NoFault;
+
+ case MISCREG_CWP:
+ tc->changeRegFileContext(CONTEXT_CWP, val);
+ case MISCREG_CANSAVE:
+ case MISCREG_CANRESTORE:
+ case MISCREG_CLEANWIN:
+ case MISCREG_OTHERWIN:
+ case MISCREG_WSTATE:
+ setReg(miscReg, val);
+ return NoFault;
+
+ case MISCREG_GL:
+ int newval;
+ if (isHyperPriv() && val > MaxGL)
+ newval = MaxGL;
+ else if (isPriv() && !isHyperPriv() && val > MaxPGL)
+ newval = MaxPGL;
+ else
+ newval = val;
+ tc->changeRegFileContext(CONTEXT_GLOBALS, newval);
+ setReg(miscReg, newval);
+ return NoFault;
+
+ /** Floating Point Status Register */
+ case MISCREG_FSR:
+ panic("Floating Point not implemented\n");
+ default:
+#if FULL_SYSTEM
+ setFSRegWithEffect(miscReg, val, tc);
+#else
+ return new IllegalInstruction;
+#endif
+ }
+}
+
+void MiscRegFile::serialize(std::ostream & os)
+{
+ SERIALIZE_SCALAR(pstate);
+ SERIALIZE_SCALAR(tba);
+ SERIALIZE_SCALAR(y);
+ SERIALIZE_SCALAR(pil);
+ SERIALIZE_SCALAR(gl);
+ SERIALIZE_SCALAR(cwp);
+ SERIALIZE_ARRAY(tt, MaxTL);
+ SERIALIZE_SCALAR(ccr);
+ SERIALIZE_SCALAR(asi);
+ SERIALIZE_SCALAR(tl);
+ SERIALIZE_ARRAY(tpc, MaxTL);
+ SERIALIZE_ARRAY(tnpc, MaxTL);
+ SERIALIZE_ARRAY(tstate, MaxTL);
+ SERIALIZE_SCALAR(tick);
+ SERIALIZE_SCALAR(cansave);
+ SERIALIZE_SCALAR(canrestore);
+ SERIALIZE_SCALAR(otherwin);
+ SERIALIZE_SCALAR(cleanwin);
+ SERIALIZE_SCALAR(wstate);
+ SERIALIZE_SCALAR(fsr);
+ SERIALIZE_SCALAR(fprs);
+ SERIALIZE_SCALAR(hpstate);
+ SERIALIZE_ARRAY(htstate, MaxTL);
+ SERIALIZE_SCALAR(htba);
+ SERIALIZE_SCALAR(hstick_cmpr);
+}
+
+void MiscRegFile::unserialize(Checkpoint * cp, const std::string & section)
+{
+ UNSERIALIZE_SCALAR(pstate);
+ UNSERIALIZE_SCALAR(tba);
+ UNSERIALIZE_SCALAR(y);
+ UNSERIALIZE_SCALAR(pil);
+ UNSERIALIZE_SCALAR(gl);
+ UNSERIALIZE_SCALAR(cwp);
+ UNSERIALIZE_ARRAY(tt, MaxTL);
+ UNSERIALIZE_SCALAR(ccr);
+ UNSERIALIZE_SCALAR(asi);
+ UNSERIALIZE_SCALAR(tl);
+ UNSERIALIZE_ARRAY(tpc, MaxTL);
+ UNSERIALIZE_ARRAY(tnpc, MaxTL);
+ UNSERIALIZE_ARRAY(tstate, MaxTL);
+ UNSERIALIZE_SCALAR(tick);
+ UNSERIALIZE_SCALAR(cansave);
+ UNSERIALIZE_SCALAR(canrestore);
+ UNSERIALIZE_SCALAR(otherwin);
+ UNSERIALIZE_SCALAR(cleanwin);
+ UNSERIALIZE_SCALAR(wstate);
+ UNSERIALIZE_SCALAR(fsr);
+ UNSERIALIZE_SCALAR(fprs);
+ UNSERIALIZE_SCALAR(hpstate);
+ UNSERIALIZE_ARRAY(htstate, MaxTL);
+ UNSERIALIZE_SCALAR(htba);
+ UNSERIALIZE_SCALAR(hstick_cmpr);
+}
+
diff --git a/src/arch/sparc/miscregfile.hh b/src/arch/sparc/miscregfile.hh
new file mode 100644
index 000000000..be143311f
--- /dev/null
+++ b/src/arch/sparc/miscregfile.hh
@@ -0,0 +1,410 @@
+/*
+ * Copyright (c) 2003-2005 The Regents of The University of Michigan
+ * 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
+ * Ali Saidi
+ */
+
+#ifndef __ARCH_SPARC_MISCREGFILE_HH__
+#define __ARCH_SPARC_MISCREGFILE_HH__
+
+#include "arch/sparc/faults.hh"
+#include "arch/sparc/isa_traits.hh"
+#include "arch/sparc/types.hh"
+
+#include <string>
+
+namespace SparcISA
+{
+
+ //These functions map register indices to names
+ std::string getMiscRegName(RegIndex);
+
+ const int AsrStart = 0;
+ const int PrStart = 32;
+ const int HprStart = 64;
+ const int MiscStart = 96;
+
+ enum MiscRegIndex
+ {
+ /** Ancillary State Registers */
+ MISCREG_Y = AsrStart + 0,
+ MISCREG_CCR = AsrStart + 2,
+ MISCREG_ASI = AsrStart + 3,
+ MISCREG_TICK = AsrStart + 4,
+ MISCREG_PC = AsrStart + 5,
+ MISCREG_FPRS = AsrStart + 6,
+ MISCREG_PCR = AsrStart + 16,
+ MISCREG_PIC = AsrStart + 17,
+ MISCREG_GSR = AsrStart + 19,
+ MISCREG_SOFTINT_SET = AsrStart + 20,
+ MISCREG_SOFTINT_CLR = AsrStart + 21,
+ MISCREG_SOFTINT = AsrStart + 22,
+ MISCREG_TICK_CMPR = AsrStart + 23,
+ MISCREG_STICK = AsrStart + 24,
+ MISCREG_STICK_CMPR = AsrStart + 25,
+
+ /** Privilged Registers */
+ MISCREG_TPC = PrStart + 0,
+ MISCREG_TNPC = PrStart + 1,
+ MISCREG_TSTATE = PrStart + 2,
+ MISCREG_TT = PrStart + 3,
+ MISCREG_PRIVTICK = PrStart + 4,
+ MISCREG_TBA = PrStart + 5,
+ MISCREG_PSTATE = PrStart + 6,
+ MISCREG_TL = PrStart + 7,
+ MISCREG_PIL = PrStart + 8,
+ MISCREG_CWP = PrStart + 9,
+ MISCREG_CANSAVE = PrStart + 10,
+ MISCREG_CANRESTORE = PrStart + 11,
+ MISCREG_CLEANWIN = PrStart + 12,
+ MISCREG_OTHERWIN = PrStart + 13,
+ MISCREG_WSTATE = PrStart + 14,
+ MISCREG_GL = PrStart + 16,
+
+ /** Hyper privileged registers */
+ MISCREG_HPSTATE = HprStart + 0,
+ MISCREG_HTSTATE = HprStart + 1,
+ MISCREG_HINTP = HprStart + 3,
+ MISCREG_HTBA = HprStart + 5,
+ MISCREG_HVER = HprStart + 6,
+ MISCREG_STRAND_STS_REG = HprStart + 16,
+ MISCREG_HSTICK_CMPR = HprStart + 31,
+
+ /** Floating Point Status Register */
+ MISCREG_FSR = MiscStart + 0
+
+ };
+
+ // The control registers, broken out into fields
+ class MiscRegFile
+ {
+ private:
+
+ /* ASR Registers */
+ union {
+ uint64_t y; // Y (used in obsolete multiplication)
+ struct {
+ uint64_t value:32; // The actual value stored in y
+ uint64_t :32; // reserved bits
+ } yFields;
+ };
+ union {
+ uint8_t ccr; // Condition Code Register
+ struct {
+ union {
+ uint8_t icc:4; // 32-bit condition codes
+ struct {
+ uint8_t c:1; // Carry
+ uint8_t v:1; // Overflow
+ uint8_t z:1; // Zero
+ uint8_t n:1; // Negative
+ } iccFields;
+ };
+ union {
+ uint8_t xcc:4; // 64-bit condition codes
+ struct {
+ uint8_t c:1; // Carry
+ uint8_t v:1; // Overflow
+ uint8_t z:1; // Zero
+ uint8_t n:1; // Negative
+ } xccFields;
+ };
+ } ccrFields;
+ };
+ uint8_t asi; // Address Space Identifier
+ union {
+ uint64_t tick; // Hardware clock-tick counter
+ struct {
+ int64_t counter:63; // Clock-tick count
+ uint64_t npt:1; // Non-priveleged trap
+ } tickFields;
+ };
+ union {
+ uint8_t fprs; // Floating-Point Register State
+ struct {
+ uint8_t dl:1; // Dirty lower
+ uint8_t du:1; // Dirty upper
+ uint8_t fef:1; // FPRS enable floating-Point
+ } fprsFields;
+ };
+ union {
+ uint64_t gsr; //General Status Register
+ struct {
+ uint64_t mask:32;
+ uint64_t :4;
+ uint64_t im:1;
+ uint64_t irnd:2;
+ uint64_t :17;
+ uint64_t scale:5;
+ uint64_t align:3;
+ } gsrFields;
+ };
+ union {
+ uint64_t softint;
+ struct {
+ uint64_t tm:1;
+ uint64_t int_level:14;
+ uint64_t sm:1;
+ } softintFields;
+ };
+ union {
+ uint64_t tick_cmpr; // Hardware tick compare registers
+ struct {
+ uint64_t tick_cmpr:63; // Clock-tick count
+ uint64_t int_dis:1; // Non-priveleged trap
+ } tick_cmprFields;
+ };
+ union {
+ uint64_t stick; // Hardware clock-tick counter
+ struct {
+ int64_t :63; // Not used, storage in SparcSystem
+ uint64_t npt:1; // Non-priveleged trap
+ } stickFields;
+ };
+ union {
+ uint64_t stick_cmpr; // Hardware tick compare registers
+ struct {
+ uint64_t tick_cmpr:63; // Clock-tick count
+ uint64_t int_dis:1; // Non-priveleged trap
+ } stick_cmprFields;
+ };
+
+
+ /* Privileged Registers */
+ uint64_t tpc[MaxTL]; // Trap Program Counter (value from
+ // previous trap level)
+ uint64_t tnpc[MaxTL]; // Trap Next Program Counter (value from
+ // previous trap level)
+ union {
+ uint64_t tstate[MaxTL]; // Trap State
+ struct {
+ //Values are from previous trap level
+ uint64_t cwp:5; // Current Window Pointer
+ uint64_t :3; // Reserved bits
+ uint64_t pstate:13; // Process State
+ uint64_t :3; // Reserved bits
+ uint64_t asi:8; // Address Space Identifier
+ uint64_t ccr:8; // Condition Code Register
+ uint64_t gl:8; // Global level
+ } tstateFields[MaxTL];
+ };
+ uint16_t tt[MaxTL]; // Trap Type (Type of trap which occured
+ // on the previous level)
+ uint64_t tba; // Trap Base Address
+
+ union {
+ uint16_t pstate; // Process State Register
+ struct {
+ uint16_t :1; // reserved
+ uint16_t ie:1; // Interrupt enable
+ uint16_t priv:1; // Privelege mode
+ uint16_t am:1; // Address mask
+ uint16_t pef:1; // PSTATE enable floating-point
+ uint16_t :1; // reserved2
+ uint16_t mm:2; // Memory Model
+ uint16_t tle:1; // Trap little-endian
+ uint16_t cle:1; // Current little-endian
+ } pstateFields;
+ };
+ uint8_t tl; // Trap Level
+ uint8_t pil; // Process Interrupt Register
+ uint8_t cwp; // Current Window Pointer
+ uint8_t cansave; // Savable windows
+ uint8_t canrestore; // Restorable windows
+ uint8_t cleanwin; // Clean windows
+ uint8_t otherwin; // Other windows
+ union {
+ uint8_t wstate; // Window State
+ struct {
+ uint8_t normal:3; // Bits TT<4:2> are set to on a normal
+ // register window trap
+ uint8_t other:3; // Bits TT<4:2> are set to on an "otherwin"
+ // register window trap
+ } wstateFields;
+ };
+ uint8_t gl; // Global level register
+
+
+ /** Hyperprivileged Registers */
+ union {
+ uint64_t hpstate; // Hyperprivileged State Register
+ struct {
+ uint8_t tlz: 1;
+ uint8_t :1;
+ uint8_t hpriv:1;
+ uint8_t :2;
+ uint8_t red:1;
+ uint8_t :4;
+ uint8_t ibe:1;
+ uint8_t id:1;
+ } hpstateFields;
+ };
+
+ uint64_t htstate[MaxTL]; // Hyperprivileged Trap State Register
+ uint64_t hintp;
+ uint64_t htba; // Hyperprivileged Trap Base Address register
+ union {
+ uint64_t hstick_cmpr; // Hardware tick compare registers
+ struct {
+ uint64_t tick_cmpr:63; // Clock-tick count
+ uint64_t int_dis:1; // Non-priveleged trap
+ } hstick_cmprFields;
+ };
+
+ uint64_t strandStatusReg; // Per strand status register
+
+
+ /** Floating point misc registers. */
+ union {
+ uint64_t fsr; // Floating-Point State Register
+ struct {
+ union {
+ uint64_t cexc:5; // Current excpetion
+ struct {
+ uint64_t nxc:1; // Inexact
+ uint64_t dzc:1; // Divide by zero
+ uint64_t ufc:1; // Underflow
+ uint64_t ofc:1; // Overflow
+ uint64_t nvc:1; // Invalid operand
+ } cexcFields;
+ };
+ union {
+ uint64_t aexc:5; // Accrued exception
+ struct {
+ uint64_t nxc:1; // Inexact
+ uint64_t dzc:1; // Divide by zero
+ uint64_t ufc:1; // Underflow
+ uint64_t ofc:1; // Overflow
+ uint64_t nvc:1; // Invalid operand
+ } aexcFields;
+ };
+ uint64_t fcc0:2; // Floating-Point condtion codes
+ uint64_t :1; // Reserved bits
+ uint64_t qne:1; // Deferred trap queue not empty
+ // with no queue, it should read 0
+ uint64_t ftt:3; // Floating-Point trap type
+ uint64_t ver:3; // Version (of the FPU)
+ uint64_t :2; // Reserved bits
+ uint64_t ns:1; // Nonstandard floating point
+ union {
+ uint64_t tem:5; // Trap Enable Mask
+ struct {
+ uint64_t nxm:1; // Inexact
+ uint64_t dzm:1; // Divide by zero
+ uint64_t ufm:1; // Underflow
+ uint64_t ofm:1; // Overflow
+ uint64_t nvm:1; // Invalid operand
+ } temFields;
+ };
+ uint64_t :2; // Reserved bits
+ uint64_t rd:2; // Rounding direction
+ uint64_t fcc1:2; // Floating-Point condition codes
+ uint64_t fcc2:2; // Floating-Point condition codes
+ uint64_t fcc3:2; // Floating-Point condition codes
+ uint64_t :26; // Reserved bits
+ } fsrFields;
+ };
+
+ // These need to check the int_dis field and if 0 then
+ // set appropriate bit in softint and checkinterrutps on the cpu
+#if FULL_SYSTEM
+ /** Process a tick compare event and generate an interrupt on the cpu if
+ * appropriate. */
+ void processTickCompare(ThreadContext *tc);
+ void processSTickCompare(ThreadContext *tc);
+ void processHSTickCompare(ThreadContext *tc);
+
+ typedef CpuEventWrapper<MiscRegFile,
+ &MiscRegFile::processTickCompare> TickCompareEvent;
+ TickCompareEvent *tickCompare;
+
+ typedef CpuEventWrapper<MiscRegFile,
+ &MiscRegFile::processSTickCompare> STickCompareEvent;
+ STickCompareEvent *sTickCompare;
+
+ typedef CpuEventWrapper<MiscRegFile,
+ &MiscRegFile::processHSTickCompare> HSTickCompareEvent;
+ HSTickCompareEvent *hSTickCompare;
+
+ /** Fullsystem only register version of ReadRegWithEffect() */
+ MiscReg readFSRegWithEffect(int miscReg, Fault &fault, ThreadContext *tc);
+ /** Fullsystem only register version of SetRegWithEffect() */
+ Fault setFSRegWithEffect(int miscReg, const MiscReg &val,
+ ThreadContext * tc);
+#endif
+ public:
+
+ void reset();
+
+ MiscRegFile()
+ {
+ reset();
+ }
+
+ /** read a value out of an either an SE or FS IPR. No checking is done
+ * about SE vs. FS as this is mostly used to copy the regfile. Thus more
+ * register are copied that are necessary for FS. However this prevents
+ * a bunch of ifdefs and is rarely called so is not performance
+ * criticial. */
+ MiscReg readReg(int miscReg);
+
+ /** Read a value from an IPR. Only the SE iprs are here and the rest
+ * are are readFSRegWithEffect (which is called by readRegWithEffect()).
+ * Checking is done for permission based on state bits in the miscreg
+ * file. */
+ MiscReg readRegWithEffect(int miscReg, Fault &fault, ThreadContext *tc);
+
+ /** write a value into an either an SE or FS IPR. No checking is done
+ * about SE vs. FS as this is mostly used to copy the regfile. Thus more
+ * register are copied that are necessary for FS. However this prevents
+ * a bunch of ifdefs and is rarely called so is not performance
+ * criticial.*/
+ Fault setReg(int miscReg, const MiscReg &val);
+
+ /** Write a value into an IPR. Only the SE iprs are here and the rest
+ * are are setFSRegWithEffect (which is called by setRegWithEffect()).
+ * Checking is done for permission based on state bits in the miscreg
+ * file. */
+ Fault setRegWithEffect(int miscReg,
+ const MiscReg &val, ThreadContext * tc);
+
+ void serialize(std::ostream & os);
+
+ void unserialize(Checkpoint * cp, const std::string & section);
+
+ void copyMiscRegs(ThreadContext * tc);
+
+ protected:
+
+ bool isHyperPriv() { return hpstateFields.hpriv; }
+ bool isPriv() { return hpstateFields.hpriv || pstateFields.priv; }
+ bool isNonPriv() { return !isPriv(); }
+ };
+}
+
+#endif
diff --git a/src/arch/sparc/process.cc b/src/arch/sparc/process.cc
index 75f01e038..70c7e719f 100644
--- a/src/arch/sparc/process.cc
+++ b/src/arch/sparc/process.cc
@@ -32,6 +32,7 @@
#include "arch/sparc/isa_traits.hh"
#include "arch/sparc/process.hh"
#include "base/loader/object_file.hh"
+#include "base/loader/elf_object.hh"
#include "base/misc.hh"
#include "cpu/thread_context.hh"
#include "mem/page_table.hh"
@@ -129,7 +130,8 @@ SparcLiveProcess::argsInit(int intSize, int pageSize)
SPARC_AT_UID = 11,
SPARC_AT_EUID = 12,
SPARC_AT_GID = 13,
- SPARC_AT_EGID = 14
+ SPARC_AT_EGID = 14,
+ SPARC_AT_SECURE = 23
};
enum hardwareCaps
@@ -153,31 +155,42 @@ SparcLiveProcess::argsInit(int intSize, int pageSize)
M5_HWCAP_SPARC_V9 |
M5_HWCAP_SPARC_ULTRA3;
- //Setup the auxilliary vectors. These will already have
- //endian conversion.
- auxv.push_back(buildAuxVect(SPARC_AT_EGID, 100));
- auxv.push_back(buildAuxVect(SPARC_AT_GID, 100));
- auxv.push_back(buildAuxVect(SPARC_AT_EUID, 100));
- auxv.push_back(buildAuxVect(SPARC_AT_UID, 100));
- //This would work, but the entry point is a protected member
- //auxv.push_back(buildAuxVect(SPARC_AT_ENTRY, objFile->entry));
- auxv.push_back(buildAuxVect(SPARC_AT_FLAGS, 0));
- //This is the address of the elf "interpreter", which I don't
- //think we currently set up. It should be set to 0 (I think)
- //auxv.push_back(buildAuxVect(SPARC_AT_BASE, 0));
- //This is the number of headers which were in the original elf
- //file. This information isn't avaibale by this point.
- //auxv.push_back(buildAuxVect(SPARC_AT_PHNUM, 3));
- //This is the size of a program header entry. This isn't easy
- //to compute here.
- //auxv.push_back(buildAuxVect(SPARC_AT_PHENT, blah));
- //This is should be set to load_addr (whatever that is) +
- //e_phoff. I think it's a pointer to the program headers.
- //auxv.push_back(buildAuxVect(SPARC_AT_PHDR, blah));
- //This should be easy to get right, but I won't set it for now
- //auxv.push_back(buildAuxVect(SPARC_AT_CLKTCK, blah));
- auxv.push_back(buildAuxVect(SPARC_AT_PAGESZ, SparcISA::VMPageSize));
- auxv.push_back(buildAuxVect(SPARC_AT_HWCAP, hwcap));
+
+ //Setup the auxilliary vectors. These will already have endian conversion.
+ //Auxilliary vectors are loaded only for elf formatted executables.
+ ElfObject * elfObject = dynamic_cast<ElfObject *>(objFile);
+ if(elfObject)
+ {
+ //Bits which describe the system hardware capabilities
+ auxv.push_back(buildAuxVect(SPARC_AT_HWCAP, hwcap));
+ //The system page size
+ auxv.push_back(buildAuxVect(SPARC_AT_PAGESZ, SparcISA::VMPageSize));
+ //Defined to be 100 in the kernel source.
+ //Frequency at which times() increments
+ auxv.push_back(buildAuxVect(SPARC_AT_CLKTCK, 100));
+ // For statically linked executables, this is the virtual address of the
+ // program header tables if they appear in the executable image
+ auxv.push_back(buildAuxVect(SPARC_AT_PHDR, elfObject->programHeaderTable()));
+ // This is the size of a program header entry from the elf file.
+ auxv.push_back(buildAuxVect(SPARC_AT_PHENT, elfObject->programHeaderSize()));
+ // This is the number of program headers from the original elf file.
+ auxv.push_back(buildAuxVect(SPARC_AT_PHNUM, elfObject->programHeaderCount()));
+ //This is the address of the elf "interpreter", It should be set
+ //to 0 for regular executables. It should be something else
+ //(not sure what) for dynamic libraries.
+ auxv.push_back(buildAuxVect(SPARC_AT_BASE, 0));
+ //This is hardwired to 0 in the elf loading code in the kernel
+ auxv.push_back(buildAuxVect(SPARC_AT_FLAGS, 0));
+ //The entry point to the program
+ auxv.push_back(buildAuxVect(SPARC_AT_ENTRY, objFile->entryPoint()));
+ //Different user and group IDs
+ auxv.push_back(buildAuxVect(SPARC_AT_UID, 100));
+ auxv.push_back(buildAuxVect(SPARC_AT_EUID, 100));
+ auxv.push_back(buildAuxVect(SPARC_AT_GID, 100));
+ auxv.push_back(buildAuxVect(SPARC_AT_EGID, 100));
+ //Whether to enable "secure mode" in the executable
+ auxv.push_back(buildAuxVect(SPARC_AT_SECURE, 0));
+ }
//Figure out how big the initial stack needs to be
diff --git a/src/arch/sparc/regfile.cc b/src/arch/sparc/regfile.cc
new file mode 100644
index 000000000..747426781
--- /dev/null
+++ b/src/arch/sparc/regfile.cc
@@ -0,0 +1,279 @@
+/*
+ * Copyright (c) 2003-2005 The Regents of The University of Michigan
+ * 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
+ * Ali Saidi
+ */
+
+#include "arch/sparc/regfile.hh"
+#include "cpu/thread_context.hh"
+
+class Checkpoint;
+
+using namespace SparcISA;
+using namespace std;
+
+//RegFile class methods
+Addr RegFile::readPC()
+{
+ return pc;
+}
+
+void RegFile::setPC(Addr val)
+{
+ pc = val;
+}
+
+Addr RegFile::readNextPC()
+{
+ return npc;
+}
+
+void RegFile::setNextPC(Addr val)
+{
+ npc = val;
+}
+
+Addr RegFile::readNextNPC()
+{
+ return nnpc;
+}
+
+void RegFile::setNextNPC(Addr val)
+{
+ nnpc = val;
+}
+
+void RegFile::clear()
+{
+ intRegFile.clear();
+ floatRegFile.clear();
+}
+
+MiscReg RegFile::readMiscReg(int miscReg)
+{
+ return miscRegFile.readReg(miscReg);
+}
+
+MiscReg RegFile::readMiscRegWithEffect(int miscReg,
+ Fault &fault, ThreadContext *tc)
+{
+ return miscRegFile.readRegWithEffect(miscReg, fault, tc);
+}
+
+Fault RegFile::setMiscReg(int miscReg, const MiscReg &val)
+{
+ return miscRegFile.setReg(miscReg, val);
+}
+
+Fault RegFile::setMiscRegWithEffect(int miscReg, const MiscReg &val,
+ ThreadContext * tc)
+{
+ return miscRegFile.setRegWithEffect(miscReg, val, tc);
+}
+
+FloatReg RegFile::readFloatReg(int floatReg, int width)
+{
+ return floatRegFile.readReg(floatReg, width);
+}
+
+FloatReg RegFile::readFloatReg(int floatReg)
+{
+ //Use the "natural" width of a single float
+ return floatRegFile.readReg(floatReg, FloatRegFile::SingleWidth);
+}
+
+FloatRegBits RegFile::readFloatRegBits(int floatReg, int width)
+{
+ return floatRegFile.readRegBits(floatReg, width);
+}
+
+FloatRegBits RegFile::readFloatRegBits(int floatReg)
+{
+ //Use the "natural" width of a single float
+ return floatRegFile.readRegBits(floatReg,
+ FloatRegFile::SingleWidth);
+}
+
+Fault RegFile::setFloatReg(int floatReg, const FloatReg &val, int width)
+{
+ return floatRegFile.setReg(floatReg, val, width);
+}
+
+Fault RegFile::setFloatReg(int floatReg, const FloatReg &val)
+{
+ //Use the "natural" width of a single float
+ return setFloatReg(floatReg, val, FloatRegFile::SingleWidth);
+}
+
+Fault RegFile::setFloatRegBits(int floatReg, const FloatRegBits &val, int width)
+{
+ return floatRegFile.setRegBits(floatReg, val, width);
+}
+
+Fault RegFile::setFloatRegBits(int floatReg, const FloatRegBits &val)
+{
+ //Use the "natural" width of a single float
+ return floatRegFile.setRegBits(floatReg, val,
+ FloatRegFile::SingleWidth);
+}
+
+IntReg RegFile::readIntReg(int intReg)
+{
+ return intRegFile.readReg(intReg);
+}
+
+Fault RegFile::setIntReg(int intReg, const IntReg &val)
+{
+ return intRegFile.setReg(intReg, val);
+}
+
+void RegFile::serialize(std::ostream &os)
+{
+ intRegFile.serialize(os);
+ floatRegFile.serialize(os);
+ miscRegFile.serialize(os);
+ SERIALIZE_SCALAR(pc);
+ SERIALIZE_SCALAR(npc);
+}
+
+void RegFile::unserialize(Checkpoint *cp, const std::string &section)
+{
+ intRegFile.unserialize(cp, section);
+ floatRegFile.unserialize(cp, section);
+ miscRegFile.unserialize(cp, section);
+ UNSERIALIZE_SCALAR(pc);
+ UNSERIALIZE_SCALAR(npc);
+}
+
+void RegFile::changeContext(RegContextParam param, RegContextVal val)
+{
+ switch(param)
+ {
+ case CONTEXT_CWP:
+ intRegFile.setCWP(val);
+ break;
+ case CONTEXT_GLOBALS:
+ intRegFile.setGlobals(val);
+ break;
+ default:
+ panic("Tried to set illegal context parameter in the SPARC regfile.\n");
+ }
+}
+
+int SparcISA::InterruptLevel(uint64_t softint)
+{
+ if (softint & 0x10000 || softint & 0x1)
+ return 14;
+
+ int level = 14;
+ while (level >= 0 && !(1 << (level + 1) & softint))
+ level--;
+ if (1 << (level + 1) & softint)
+ return level;
+ return 0;
+}
+
+void SparcISA::copyMiscRegs(ThreadContext *src, ThreadContext *dest)
+{
+
+ uint8_t tl = src->readMiscReg(MISCREG_TL);
+
+ // Read all the trap level dependent registers and save them off
+ for(int i = 1; i <= MaxTL; i++)
+ {
+ src->setMiscReg(MISCREG_TL, i);
+ dest->setMiscReg(MISCREG_TL, i);
+
+ dest->setMiscReg(MISCREG_TT, src->readMiscReg(MISCREG_TT));
+ dest->setMiscReg(MISCREG_TPC, src->readMiscReg(MISCREG_TPC));
+ dest->setMiscReg(MISCREG_TNPC, src->readMiscReg(MISCREG_TNPC));
+ dest->setMiscReg(MISCREG_TSTATE, src->readMiscReg(MISCREG_TSTATE));
+ }
+
+ // Save off the traplevel
+ dest->setMiscReg(MISCREG_TL, tl);
+ src->setMiscReg(MISCREG_TL, tl);
+
+
+ // ASRs
+ dest->setMiscReg(MISCREG_Y, src->readMiscReg(MISCREG_Y));
+ dest->setMiscReg(MISCREG_CCR, src->readMiscReg(MISCREG_CCR));
+ dest->setMiscReg(MISCREG_ASI, src->readMiscReg(MISCREG_ASI));
+ dest->setMiscReg(MISCREG_TICK, src->readMiscReg(MISCREG_TICK));
+ dest->setMiscReg(MISCREG_FPRS, src->readMiscReg(MISCREG_FPRS));
+ dest->setMiscReg(MISCREG_SOFTINT, src->readMiscReg(MISCREG_SOFTINT));
+ dest->setMiscReg(MISCREG_TICK_CMPR, src->readMiscReg(MISCREG_TICK_CMPR));
+ dest->setMiscReg(MISCREG_STICK, src->readMiscReg(MISCREG_STICK));
+ dest->setMiscReg(MISCREG_STICK_CMPR, src->readMiscReg(MISCREG_STICK_CMPR));
+
+ // Priv Registers
+ dest->setMiscReg(MISCREG_TICK, src->readMiscReg(MISCREG_TICK));
+ dest->setMiscReg(MISCREG_TBA, src->readMiscReg(MISCREG_TBA));
+ dest->setMiscReg(MISCREG_PSTATE, src->readMiscReg(MISCREG_PSTATE));
+ dest->setMiscReg(MISCREG_PIL, src->readMiscReg(MISCREG_PIL));
+ dest->setMiscReg(MISCREG_CWP, src->readMiscReg(MISCREG_CWP));
+ dest->setMiscReg(MISCREG_CANSAVE, src->readMiscReg(MISCREG_CANSAVE));
+ dest->setMiscReg(MISCREG_CANRESTORE, src->readMiscReg(MISCREG_CANRESTORE));
+ dest->setMiscReg(MISCREG_OTHERWIN, src->readMiscReg(MISCREG_OTHERWIN));
+ dest->setMiscReg(MISCREG_CLEANWIN, src->readMiscReg(MISCREG_CLEANWIN));
+ dest->setMiscReg(MISCREG_WSTATE, src->readMiscReg(MISCREG_WSTATE));
+ dest->setMiscReg(MISCREG_GL, src->readMiscReg(MISCREG_GL));
+
+ // Hyperprivilged registers
+ dest->setMiscReg(MISCREG_HPSTATE, src->readMiscReg(MISCREG_HPSTATE));
+ dest->setMiscReg(MISCREG_HINTP, src->readMiscReg(MISCREG_HINTP));
+ dest->setMiscReg(MISCREG_HTBA, src->readMiscReg(MISCREG_HTBA));
+ dest->setMiscReg(MISCREG_STRAND_STS_REG,
+ src->readMiscReg(MISCREG_STRAND_STS_REG));
+ dest->setMiscReg(MISCREG_HSTICK_CMPR,
+ src->readMiscReg(MISCREG_HSTICK_CMPR));
+
+ // FSR
+ dest->setMiscReg(MISCREG_FSR, src->readMiscReg(MISCREG_FSR));
+}
+
+void SparcISA::copyRegs(ThreadContext *src, ThreadContext *dest)
+{
+ // First loop through the integer registers.
+ for (int i = 0; i < TheISA::NumIntRegs; ++i) {
+ dest->setIntReg(i, src->readIntReg(i));
+ }
+
+ // Then loop through the floating point registers.
+ for (int i = 0; i < TheISA::NumFloatRegs; ++i) {
+ dest->setFloatRegBits(i, src->readFloatRegBits(i));
+ }
+
+ // Copy misc. registers
+ copyMiscRegs(src, dest);
+
+ // Lastly copy PC/NPC
+ dest->setPC(src->readPC());
+ dest->setNextPC(src->readNextPC());
+ dest->setNextNPC(src->readNextNPC());
+}
diff --git a/src/arch/sparc/regfile.hh b/src/arch/sparc/regfile.hh
index cbeb3c7b9..500fbbba4 100644
--- a/src/arch/sparc/regfile.hh
+++ b/src/arch/sparc/regfile.hh
@@ -32,833 +32,84 @@
#ifndef __ARCH_SPARC_REGFILE_HH__
#define __ARCH_SPARC_REGFILE_HH__
-#include "arch/sparc/exceptions.hh"
#include "arch/sparc/faults.hh"
-#include "base/trace.hh"
-#include "sim/byteswap.hh"
-#include "cpu/cpuevent.hh"
+#include "arch/sparc/floatregfile.hh"
+#include "arch/sparc/intregfile.hh"
+#include "arch/sparc/isa_traits.hh"
+#include "arch/sparc/miscregfile.hh"
+#include "arch/sparc/types.hh"
#include "sim/host.hh"
+#include <string>
+
class Checkpoint;
namespace SparcISA
{
-
- typedef uint8_t RegIndex;
-
- // MAXTL - maximum trap level
- const int MaxPTL = 2;
- const int MaxTL = 6;
- const int MaxGL = 3;
- const int MaxPGL = 2;
-
- // NWINDOWS - number of register windows, can be 3 to 32
- const int NWindows = 32;
-
-
- const int AsrStart = 0;
- const int PrStart = 32;
- const int HprStart = 64;
- const int MiscStart = 96;
-
- const uint64_t Bit64 = (1ULL << 63);
-
- class IntRegFile
+ class RegFile
{
protected:
- static const int FrameOffsetBits = 3;
- static const int FrameNumBits = 2;
-
- static const int RegsPerFrame = 1 << FrameOffsetBits;
- static const int FrameNumMask =
- (FrameNumBits == sizeof(int)) ?
- (unsigned int)(-1) :
- (1 << FrameNumBits) - 1;
- static const int FrameOffsetMask =
- (FrameOffsetBits == sizeof(int)) ?
- (unsigned int)(-1) :
- (1 << FrameOffsetBits) - 1;
-
- IntReg regGlobals[MaxGL][RegsPerFrame];
- IntReg regSegments[2 * NWindows][RegsPerFrame];
-
- enum regFrame {Globals, Outputs, Locals, Inputs, NumFrames};
-
- IntReg * regView[NumFrames];
-
- static const int RegGlobalOffset = 0;
- static const int FrameOffset = MaxGL * RegsPerFrame;
- int offset[NumFrames];
+ Addr pc; // Program Counter
+ Addr npc; // Next Program Counter
+ Addr nnpc;
public:
+ Addr readPC();
+ void setPC(Addr val);
- int flattenIndex(int reg)
- {
- int flatIndex = offset[reg >> FrameOffsetBits]
- | (reg & FrameOffsetMask);
- DPRINTF(Sparc, "Flattened index %d into %d.\n", reg, flatIndex);
- return flatIndex;
- }
-
- void clear()
- {
- int x;
- for (x = 0; x < MaxGL; x++)
- memset(regGlobals[x], 0, sizeof(regGlobals[x]));
- for(int x = 0; x < 2 * NWindows; x++)
- bzero(regSegments[x], sizeof(regSegments[x]));
- }
-
- IntRegFile()
- {
- offset[Globals] = 0;
- regView[Globals] = regGlobals[0];
- setCWP(0);
- clear();
- }
-
- IntReg readReg(int intReg)
- {
- IntReg val =
- regView[intReg >> FrameOffsetBits][intReg & FrameOffsetMask];
- DPRINTF(Sparc, "Read register %d = 0x%x\n", intReg, val);
- return val;
- }
-
- Fault setReg(int intReg, const IntReg &val)
- {
- if(intReg)
- DPRINTF(Sparc, "Wrote register %d = 0x%x\n", intReg, val);
- regView[intReg >> FrameOffsetBits][intReg & FrameOffsetMask] = val;
- return NoFault;
- }
-
- //This doesn't effect the actual CWP register.
- //It's purpose is to adjust the view of the register file
- //to what it would be if CWP = cwp.
- void setCWP(int cwp)
- {
- int index = ((NWindows - cwp) % NWindows) * 2;
- offset[Outputs] = FrameOffset + (index * RegsPerFrame);
- offset[Locals] = FrameOffset + ((index+1) * RegsPerFrame);
- offset[Inputs] = FrameOffset +
- (((index+2) % (NWindows * 2)) * RegsPerFrame);
- regView[Outputs] = regSegments[index];
- regView[Locals] = regSegments[index+1];
- regView[Inputs] = regSegments[(index+2) % (NWindows * 2)];
-
- DPRINTF(Sparc, "Changed the CWP value to %d\n", cwp);
- }
-
- void setGlobals(int gl)
- {
-
- DPRINTF(Sparc, "Now using %d globals", gl);
-
- regView[Globals] = regGlobals[gl];
- offset[Globals] = RegGlobalOffset + gl * RegsPerFrame;
- }
-
- void serialize(std::ostream &os);
-
- void unserialize(Checkpoint *cp, const std::string &section);
- };
-
- typedef float float32_t;
- typedef double float64_t;
- //FIXME long double refers to a 10 byte float, rather than a
- //16 byte float as required. This data type may have to be emulated.
- typedef double float128_t;
+ Addr readNextPC();
+ void setNextPC(Addr val);
- class FloatRegFile
- {
- public:
- static const int SingleWidth = 32;
- static const int DoubleWidth = 64;
- static const int QuadWidth = 128;
+ Addr readNextNPC();
+ void setNextNPC(Addr val);
protected:
-
- //Since the floating point registers overlap each other,
- //A generic storage space is used. The float to be returned is
- //pulled from the appropriate section of this region.
- char regSpace[SingleWidth / 8 * NumFloatRegs];
+ IntRegFile intRegFile; // integer register file
+ FloatRegFile floatRegFile; // floating point register file
+ MiscRegFile miscRegFile; // control register file
public:
- void clear()
- {
- bzero(regSpace, sizeof(regSpace));
- }
-
- FloatReg readReg(int floatReg, int width)
- {
- //In each of these cases, we have to copy the value into a temporary
- //variable. This is because we may otherwise try to access an
- //unaligned portion of memory.
- switch(width)
- {
- case SingleWidth:
- float32_t result32;
- memcpy(&result32, regSpace + 4 * floatReg, width);
- return htog(result32);
- case DoubleWidth:
- float64_t result64;
- memcpy(&result64, regSpace + 4 * floatReg, width);
- return htog(result64);
- case QuadWidth:
- float128_t result128;
- memcpy(&result128, regSpace + 4 * floatReg, width);
- return htog(result128);
- default:
- panic("Attempted to read a %d bit floating point register!", width);
- }
- }
-
- FloatRegBits readRegBits(int floatReg, int width)
- {
- //In each of these cases, we have to copy the value into a temporary
- //variable. This is because we may otherwise try to access an
- //unaligned portion of memory.
- switch(width)
- {
- case SingleWidth:
- uint32_t result32;
- memcpy(&result32, regSpace + 4 * floatReg, width);
- return htog(result32);
- case DoubleWidth:
- uint64_t result64;
- memcpy(&result64, regSpace + 4 * floatReg, width);
- return htog(result64);
- case QuadWidth:
- uint64_t result128;
- memcpy(&result128, regSpace + 4 * floatReg, width);
- return htog(result128);
- default:
- panic("Attempted to read a %d bit floating point register!", width);
- }
- }
-
- Fault setReg(int floatReg, const FloatReg &val, int width)
- {
- //In each of these cases, we have to copy the value into a temporary
- //variable. This is because we may otherwise try to access an
- //unaligned portion of memory.
-
- uint32_t result32;
- uint64_t result64;
- switch(width)
- {
- case SingleWidth:
- result32 = gtoh((uint32_t)val);
- memcpy(regSpace + 4 * floatReg, &result32, width);
- break;
- case DoubleWidth:
- result64 = gtoh((uint64_t)val);
- memcpy(regSpace + 4 * floatReg, &result64, width);
- break;
- case QuadWidth:
- panic("Quad width FP not implemented.");
- break;
- default:
- panic("Attempted to read a %d bit floating point register!", width);
- }
- return NoFault;
- }
-
- Fault setRegBits(int floatReg, const FloatRegBits &val, int width)
- {
- //In each of these cases, we have to copy the value into a temporary
- //variable. This is because we may otherwise try to access an
- //unaligned portion of memory.
- uint32_t result32;
- uint64_t result64;
- switch(width)
- {
- case SingleWidth:
- result32 = gtoh((uint32_t)val);
- memcpy(regSpace + 4 * floatReg, &result32, width);
- break;
- case DoubleWidth:
- result64 = gtoh((uint64_t)val);
- memcpy(regSpace + 4 * floatReg, &result64, width);
- break;
- case QuadWidth:
- panic("Quad width FP not implemented.");
- break;
- default:
- panic("Attempted to read a %d bit floating point register!", width);
- }
- return NoFault;
- }
+ void clear();
- void serialize(std::ostream &os);
+ int FlattenIntIndex(int reg);
- void unserialize(Checkpoint *cp, const std::string &section);
- };
+ MiscReg readMiscReg(int miscReg);
- enum MiscRegIndex
- {
- /** Ancillary State Registers */
- MISCREG_Y = AsrStart + 0,
- MISCREG_CCR = AsrStart + 2,
- MISCREG_ASI = AsrStart + 3,
- MISCREG_TICK = AsrStart + 4,
- MISCREG_PC = AsrStart + 5,
- MISCREG_FPRS = AsrStart + 6,
- MISCREG_PCR = AsrStart + 16,
- MISCREG_PIC = AsrStart + 17,
- MISCREG_GSR = AsrStart + 19,
- MISCREG_SOFTINT_SET = AsrStart + 20,
- MISCREG_SOFTINT_CLR = AsrStart + 21,
- MISCREG_SOFTINT = AsrStart + 22,
- MISCREG_TICK_CMPR = AsrStart + 23,
- MISCREG_STICK = AsrStart + 24,
- MISCREG_STICK_CMPR = AsrStart + 25,
-
- /** Privilged Registers */
- MISCREG_TPC = PrStart + 0,
- MISCREG_TNPC = PrStart + 1,
- MISCREG_TSTATE = PrStart + 2,
- MISCREG_TT = PrStart + 3,
- MISCREG_PRIVTICK = PrStart + 4,
- MISCREG_TBA = PrStart + 5,
- MISCREG_PSTATE = PrStart + 6,
- MISCREG_TL = PrStart + 7,
- MISCREG_PIL = PrStart + 8,
- MISCREG_CWP = PrStart + 9,
- MISCREG_CANSAVE = PrStart + 10,
- MISCREG_CANRESTORE = PrStart + 11,
- MISCREG_CLEANWIN = PrStart + 12,
- MISCREG_OTHERWIN = PrStart + 13,
- MISCREG_WSTATE = PrStart + 14,
- MISCREG_GL = PrStart + 16,
-
- /** Hyper privileged registers */
- MISCREG_HPSTATE = HprStart + 0,
- MISCREG_HTSTATE = HprStart + 1,
- MISCREG_HINTP = HprStart + 3,
- MISCREG_HTBA = HprStart + 5,
- MISCREG_HVER = HprStart + 6,
- MISCREG_STRAND_STS_REG = HprStart + 16,
- MISCREG_HSTICK_CMPR = HprStart + 31,
-
- /** Floating Point Status Register */
- MISCREG_FSR = MiscStart + 0
+ MiscReg readMiscRegWithEffect(int miscReg,
+ Fault &fault, ThreadContext *tc);
- };
+ Fault setMiscReg(int miscReg, const MiscReg &val);
- // The control registers, broken out into fields
- class MiscRegFile
- {
- private:
-
- /* ASR Registers */
- union {
- uint64_t y; // Y (used in obsolete multiplication)
- struct {
- uint64_t value:32; // The actual value stored in y
- uint64_t :32; // reserved bits
- } yFields;
- };
- union {
- uint8_t ccr; // Condition Code Register
- struct {
- union {
- uint8_t icc:4; // 32-bit condition codes
- struct {
- uint8_t c:1; // Carry
- uint8_t v:1; // Overflow
- uint8_t z:1; // Zero
- uint8_t n:1; // Negative
- } iccFields;
- };
- union {
- uint8_t xcc:4; // 64-bit condition codes
- struct {
- uint8_t c:1; // Carry
- uint8_t v:1; // Overflow
- uint8_t z:1; // Zero
- uint8_t n:1; // Negative
- } xccFields;
- };
- } ccrFields;
- };
- uint8_t asi; // Address Space Identifier
- union {
- uint64_t tick; // Hardware clock-tick counter
- struct {
- int64_t counter:63; // Clock-tick count
- uint64_t npt:1; // Non-priveleged trap
- } tickFields;
- };
- union {
- uint8_t fprs; // Floating-Point Register State
- struct {
- uint8_t dl:1; // Dirty lower
- uint8_t du:1; // Dirty upper
- uint8_t fef:1; // FPRS enable floating-Point
- } fprsFields;
- };
- union {
- uint64_t softint;
- struct {
- uint64_t tm:1;
- uint64_t int_level:14;
- uint64_t sm:1;
- } softintFields;
- };
- union {
- uint64_t tick_cmpr; // Hardware tick compare registers
- struct {
- uint64_t tick_cmpr:63; // Clock-tick count
- uint64_t int_dis:1; // Non-priveleged trap
- } tick_cmprFields;
- };
- union {
- uint64_t stick; // Hardware clock-tick counter
- struct {
- int64_t :63; // Not used, storage in SparcSystem
- uint64_t npt:1; // Non-priveleged trap
- } stickFields;
- };
- union {
- uint64_t stick_cmpr; // Hardware tick compare registers
- struct {
- uint64_t tick_cmpr:63; // Clock-tick count
- uint64_t int_dis:1; // Non-priveleged trap
- } stick_cmprFields;
- };
-
-
- /* Privileged Registers */
- uint64_t tpc[MaxTL]; // Trap Program Counter (value from
- // previous trap level)
- uint64_t tnpc[MaxTL]; // Trap Next Program Counter (value from
- // previous trap level)
- union {
- uint64_t tstate[MaxTL]; // Trap State
- struct {
- //Values are from previous trap level
- uint64_t cwp:5; // Current Window Pointer
- uint64_t :3; // Reserved bits
- uint64_t pstate:13; // Process State
- uint64_t :3; // Reserved bits
- uint64_t asi:8; // Address Space Identifier
- uint64_t ccr:8; // Condition Code Register
- uint64_t gl:8; // Global level
- } tstateFields[MaxTL];
- };
- uint16_t tt[MaxTL]; // Trap Type (Type of trap which occured
- // on the previous level)
- uint64_t tba; // Trap Base Address
-
- union {
- uint16_t pstate; // Process State Register
- struct {
- uint16_t :1; // reserved
- uint16_t ie:1; // Interrupt enable
- uint16_t priv:1; // Privelege mode
- uint16_t am:1; // Address mask
- uint16_t pef:1; // PSTATE enable floating-point
- uint16_t :1; // reserved2
- uint16_t mm:2; // Memory Model
- uint16_t tle:1; // Trap little-endian
- uint16_t cle:1; // Current little-endian
- } pstateFields;
- };
- uint8_t tl; // Trap Level
- uint8_t pil; // Process Interrupt Register
- uint8_t cwp; // Current Window Pointer
- uint8_t cansave; // Savable windows
- uint8_t canrestore; // Restorable windows
- uint8_t cleanwin; // Clean windows
- uint8_t otherwin; // Other windows
- union {
- uint8_t wstate; // Window State
- struct {
- uint8_t normal:3; // Bits TT<4:2> are set to on a normal
- // register window trap
- uint8_t other:3; // Bits TT<4:2> are set to on an "otherwin"
- // register window trap
- } wstateFields;
- };
- uint8_t gl; // Global level register
-
-
- /** Hyperprivileged Registers */
- union {
- uint64_t hpstate; // Hyperprivileged State Register
- struct {
- uint8_t tlz: 1;
- uint8_t :1;
- uint8_t hpriv:1;
- uint8_t :2;
- uint8_t red:1;
- uint8_t :4;
- uint8_t ibe:1;
- uint8_t id:1;
- } hpstateFields;
- };
-
- uint64_t htstate[MaxTL]; // Hyperprivileged Trap State Register
- uint64_t hintp;
- uint64_t htba; // Hyperprivileged Trap Base Address register
- union {
- uint64_t hstick_cmpr; // Hardware tick compare registers
- struct {
- uint64_t tick_cmpr:63; // Clock-tick count
- uint64_t int_dis:1; // Non-priveleged trap
- } hstick_cmprFields;
- };
-
- uint64_t strandStatusReg; // Per strand status register
-
-
- /** Floating point misc registers. */
- union {
- uint64_t fsr; // Floating-Point State Register
- struct {
- union {
- uint64_t cexc:5; // Current excpetion
- struct {
- uint64_t nxc:1; // Inexact
- uint64_t dzc:1; // Divide by zero
- uint64_t ufc:1; // Underflow
- uint64_t ofc:1; // Overflow
- uint64_t nvc:1; // Invalid operand
- } cexcFields;
- };
- union {
- uint64_t aexc:5; // Accrued exception
- struct {
- uint64_t nxc:1; // Inexact
- uint64_t dzc:1; // Divide by zero
- uint64_t ufc:1; // Underflow
- uint64_t ofc:1; // Overflow
- uint64_t nvc:1; // Invalid operand
- } aexcFields;
- };
- uint64_t fcc0:2; // Floating-Point condtion codes
- uint64_t :1; // Reserved bits
- uint64_t qne:1; // Deferred trap queue not empty
- // with no queue, it should read 0
- uint64_t ftt:3; // Floating-Point trap type
- uint64_t ver:3; // Version (of the FPU)
- uint64_t :2; // Reserved bits
- uint64_t ns:1; // Nonstandard floating point
- union {
- uint64_t tem:5; // Trap Enable Mask
- struct {
- uint64_t nxm:1; // Inexact
- uint64_t dzm:1; // Divide by zero
- uint64_t ufm:1; // Underflow
- uint64_t ofm:1; // Overflow
- uint64_t nvm:1; // Invalid operand
- } temFields;
- };
- uint64_t :2; // Reserved bits
- uint64_t rd:2; // Rounding direction
- uint64_t fcc1:2; // Floating-Point condition codes
- uint64_t fcc2:2; // Floating-Point condition codes
- uint64_t fcc3:2; // Floating-Point condition codes
- uint64_t :26; // Reserved bits
- } fsrFields;
- };
-
- // These need to check the int_dis field and if 0 then
- // set appropriate bit in softint and checkinterrutps on the cpu
-#if FULL_SYSTEM
- /** Process a tick compare event and generate an interrupt on the cpu if
- * appropriate. */
- void processTickCompare(ThreadContext *tc);
- void processSTickCompare(ThreadContext *tc);
- void processHSTickCompare(ThreadContext *tc);
-
- typedef CpuEventWrapper<MiscRegFile,
- &MiscRegFile::processTickCompare> TickCompareEvent;
- TickCompareEvent *tickCompare;
-
- typedef CpuEventWrapper<MiscRegFile,
- &MiscRegFile::processSTickCompare> STickCompareEvent;
- STickCompareEvent *sTickCompare;
-
- typedef CpuEventWrapper<MiscRegFile,
- &MiscRegFile::processHSTickCompare> HSTickCompareEvent;
- HSTickCompareEvent *hSTickCompare;
-
- /** Fullsystem only register version of ReadRegWithEffect() */
- MiscReg readFSRegWithEffect(int miscReg, Fault &fault, ThreadContext *tc);
- /** Fullsystem only register version of SetRegWithEffect() */
- Fault setFSRegWithEffect(int miscReg, const MiscReg &val,
+ Fault setMiscRegWithEffect(int miscReg, const MiscReg &val,
ThreadContext * tc);
-#endif
- public:
- void reset()
- {
- pstateFields.pef = 0; //No FPU
- //pstateFields.pef = 1; //FPU
-#if FULL_SYSTEM
- //For SPARC, when a system is first started, there is a power
- //on reset Trap which sets the processor into the following state.
- //Bits that aren't set aren't defined on startup.
- tl = MaxTL;
- gl = MaxGL;
-
- tickFields.counter = 0; //The TICK register is unreadable bya
- tickFields.npt = 1; //The TICK register is unreadable by by !priv
-
- softint = 0; // Clear all the soft interrupt bits
- tick_cmprFields.int_dis = 1; // disable timer compare interrupts
- tick_cmprFields.tick_cmpr = 0; // Reset to 0 for pretty printing
- stickFields.npt = 1; //The TICK register is unreadable by by !priv
- stick_cmprFields.int_dis = 1; // disable timer compare interrupts
- stick_cmprFields.tick_cmpr = 0; // Reset to 0 for pretty printing
-
-
- tt[tl] = power_on_reset;
- pstate = 0; // fields 0 but pef
- pstateFields.pef = 1;
-
- hpstate = 0;
- hpstateFields.red = 1;
- hpstateFields.hpriv = 1;
- hpstateFields.tlz = 0; // this is a guess
-
- hintp = 0; // no interrupts pending
- hstick_cmprFields.int_dis = 1; // disable timer compare interrupts
- hstick_cmprFields.tick_cmpr = 0; // Reset to 0 for pretty printing
-
-#else
-/* //This sets up the initial state of the processor for usermode processes
- pstateFields.priv = 0; //Process runs in user mode
- pstateFields.ie = 1; //Interrupts are enabled
- fsrFields.rd = 0; //Round to nearest
- fsrFields.tem = 0; //Floating point traps not enabled
- fsrFields.ns = 0; //Non standard mode off
- fsrFields.qne = 0; //Floating point queue is empty
- fsrFields.aexc = 0; //No accrued exceptions
- fsrFields.cexc = 0; //No current exceptions
-
- //Register window management registers
- otherwin = 0; //No windows contain info from other programs
- canrestore = 0; //There are no windows to pop
- cansave = MaxTL - 2; //All windows are available to save into
- cleanwin = MaxTL;*/
-#endif
- }
-
- MiscRegFile()
- {
- reset();
- }
-
- /** read a value out of an either an SE or FS IPR. No checking is done
- * about SE vs. FS as this is mostly used to copy the regfile. Thus more
- * register are copied that are necessary for FS. However this prevents
- * a bunch of ifdefs and is rarely called so is not performance
- * criticial. */
- MiscReg readReg(int miscReg);
-
- /** Read a value from an IPR. Only the SE iprs are here and the rest
- * are are readFSRegWithEffect (which is called by readRegWithEffect()).
- * Checking is done for permission based on state bits in the miscreg
- * file. */
- MiscReg readRegWithEffect(int miscReg, Fault &fault, ThreadContext *tc);
-
- /** write a value into an either an SE or FS IPR. No checking is done
- * about SE vs. FS as this is mostly used to copy the regfile. Thus more
- * register are copied that are necessary for FS. However this prevents
- * a bunch of ifdefs and is rarely called so is not performance
- * criticial.*/
- Fault setReg(int miscReg, const MiscReg &val);
-
- /** Write a value into an IPR. Only the SE iprs are here and the rest
- * are are setFSRegWithEffect (which is called by setRegWithEffect()).
- * Checking is done for permission based on state bits in the miscreg
- * file. */
- Fault setRegWithEffect(int miscReg,
- const MiscReg &val, ThreadContext * tc);
-
- void serialize(std::ostream & os);
-
- void unserialize(Checkpoint * cp, const std::string & section);
-
- void copyMiscRegs(ThreadContext * tc);
-
- bool isHyperPriv() { return hpstateFields.hpriv; }
- bool isPriv() { return hpstateFields.hpriv || pstateFields.priv; }
- bool isNonPriv() { return !isPriv(); }
- };
+ FloatReg readFloatReg(int floatReg, int width);
- typedef union
- {
- IntReg intreg;
- FloatReg fpreg;
- MiscReg ctrlreg;
- } AnyReg;
+ FloatReg readFloatReg(int floatReg);
- class RegFile
- {
- protected:
- Addr pc; // Program Counter
- Addr npc; // Next Program Counter
- Addr nnpc;
-
- public:
- Addr readPC()
- {
- return pc;
- }
-
- void setPC(Addr val)
- {
- pc = val;
- }
-
- Addr readNextPC()
- {
- return npc;
- }
-
- void setNextPC(Addr val)
- {
- npc = val;
- }
-
- Addr readNextNPC()
- {
- return nnpc;
- }
-
- void setNextNPC(Addr val)
- {
- nnpc = val;
- }
-
- protected:
- IntRegFile intRegFile; // integer register file
- FloatRegFile floatRegFile; // floating point register file
- MiscRegFile miscRegFile; // control register file
+ FloatRegBits readFloatRegBits(int floatReg, int width);
- public:
+ FloatRegBits readFloatRegBits(int floatReg);
- void clear()
- {
- intRegFile.clear();
- floatRegFile.clear();
- }
+ Fault setFloatReg(int floatReg, const FloatReg &val, int width);
- int FlattenIntIndex(int reg)
- {
- return intRegFile.flattenIndex(reg);
- }
+ Fault setFloatReg(int floatReg, const FloatReg &val);
- MiscReg readMiscReg(int miscReg)
- {
- return miscRegFile.readReg(miscReg);
- }
+ Fault setFloatRegBits(int floatReg, const FloatRegBits &val, int width);
- MiscReg readMiscRegWithEffect(int miscReg,
- Fault &fault, ThreadContext *tc)
- {
- return miscRegFile.readRegWithEffect(miscReg, fault, tc);
- }
+ Fault setFloatRegBits(int floatReg, const FloatRegBits &val);
- Fault setMiscReg(int miscReg, const MiscReg &val)
- {
- return miscRegFile.setReg(miscReg, val);
- }
+ IntReg readIntReg(int intReg);
- Fault setMiscRegWithEffect(int miscReg, const MiscReg &val,
- ThreadContext * tc)
- {
- return miscRegFile.setRegWithEffect(miscReg, val, tc);
- }
-
- FloatReg readFloatReg(int floatReg, int width)
- {
- return floatRegFile.readReg(floatReg, width);
- }
-
- FloatReg readFloatReg(int floatReg)
- {
- //Use the "natural" width of a single float
- return floatRegFile.readReg(floatReg, FloatRegFile::SingleWidth);
- }
-
- FloatRegBits readFloatRegBits(int floatReg, int width)
- {
- return floatRegFile.readRegBits(floatReg, width);
- }
-
- FloatRegBits readFloatRegBits(int floatReg)
- {
- //Use the "natural" width of a single float
- return floatRegFile.readRegBits(floatReg,
- FloatRegFile::SingleWidth);
- }
-
- Fault setFloatReg(int floatReg, const FloatReg &val, int width)
- {
- return floatRegFile.setReg(floatReg, val, width);
- }
-
- Fault setFloatReg(int floatReg, const FloatReg &val)
- {
- //Use the "natural" width of a single float
- return setFloatReg(floatReg, val, FloatRegFile::SingleWidth);
- }
-
- Fault setFloatRegBits(int floatReg, const FloatRegBits &val, int width)
- {
- return floatRegFile.setRegBits(floatReg, val, width);
- }
-
- Fault setFloatRegBits(int floatReg, const FloatRegBits &val)
- {
- //Use the "natural" width of a single float
- return floatRegFile.setRegBits(floatReg, val,
- FloatRegFile::SingleWidth);
- }
-
- IntReg readIntReg(int intReg)
- {
- return intRegFile.readReg(intReg);
- }
-
- Fault setIntReg(int intReg, const IntReg &val)
- {
- return intRegFile.setReg(intReg, val);
- }
+ Fault setIntReg(int intReg, const IntReg &val);
void serialize(std::ostream &os);
void unserialize(Checkpoint *cp, const std::string &section);
public:
- enum ContextParam
- {
- CONTEXT_CWP,
- CONTEXT_GLOBALS
- };
- typedef int ContextVal;
-
- void changeContext(ContextParam param, ContextVal val)
- {
- switch(param)
- {
- case CONTEXT_CWP:
- intRegFile.setCWP(val);
- break;
- case CONTEXT_GLOBALS:
- intRegFile.setGlobals(val);
- break;
- default:
- panic("Tried to set illegal context parameter in the SPARC regfile.\n");
- }
- }
+ void changeContext(RegContextParam param, RegContextVal val);
};
void copyRegs(ThreadContext *src, ThreadContext *dest);
diff --git a/src/arch/sparc/solaris/solaris.cc b/src/arch/sparc/solaris/solaris.cc
index c588925b0..c53caa72a 100644
--- a/src/arch/sparc/solaris/solaris.cc
+++ b/src/arch/sparc/solaris/solaris.cc
@@ -30,6 +30,8 @@
#include "arch/sparc/solaris/solaris.hh"
+#include <fcntl.h>
+
// open(2) flags translation table
OpenFlagTransTable SparcSolaris::openFlagTable[] = {
#ifdef _MSC_VER
diff --git a/src/arch/sparc/stacktrace.hh b/src/arch/sparc/stacktrace.hh
index d12aee211..54d3d17be 100644
--- a/src/arch/sparc/stacktrace.hh
+++ b/src/arch/sparc/stacktrace.hh
@@ -28,8 +28,8 @@
* Authors: Nathan Binkert
*/
-#ifndef __ARCH_ALPHA_STACKTRACE_HH__
-#define __ARCH_ALPHA_STACKTRACE_HH__
+#ifndef __ARCH_SPARC_STACKTRACE_HH__
+#define __ARCH_SPARC_STACKTRACE_HH__
#include "base/trace.hh"
#include "cpu/static_inst.hh"
@@ -118,4 +118,4 @@ StackTrace::trace(ThreadContext *tc, StaticInstPtr inst)
return true;
}
-#endif // __ARCH_ALPHA_STACKTRACE_HH__
+#endif // __ARCH_SPARC_STACKTRACE_HH__
diff --git a/src/arch/sparc/syscallreturn.hh b/src/arch/sparc/syscallreturn.hh
new file mode 100644
index 000000000..d850f4b65
--- /dev/null
+++ b/src/arch/sparc/syscallreturn.hh
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2003-2005 The Regents of The University of Michigan
+ * 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
+ */
+
+#ifndef __ARCH_SPARC_SYSCALLRETURN_HH__
+#define __ARCH_SPARC_SYSCALLRETURN_HH__
+
+#include <inttypes.h>
+
+#include "arch/sparc/regfile.hh"
+
+class SyscallReturn
+{
+ public:
+ template <class T>
+ SyscallReturn(T v, bool s)
+ {
+ retval = (uint64_t)v;
+ success = s;
+ }
+
+ template <class T>
+ SyscallReturn(T v)
+ {
+ success = (v >= 0);
+ retval = (uint64_t)v;
+ }
+
+ ~SyscallReturn() {}
+
+ SyscallReturn& operator=(const SyscallReturn& s)
+ {
+ retval = s.retval;
+ success = s.success;
+ return *this;
+ }
+
+ bool successful() { return success; }
+ uint64_t value() { return retval; }
+
+ private:
+ uint64_t retval;
+ bool success;
+};
+
+namespace SparcISA
+{
+ static inline void setSyscallReturn(SyscallReturn return_value,
+ RegFile *regs)
+ {
+ // check for error condition. SPARC syscall convention is to
+ // indicate success/failure in reg the carry bit of the ccr
+ // and put the return value itself in the standard return value reg ().
+ if (return_value.successful()) {
+ // no error, clear XCC.C
+ regs->setMiscReg(MISCREG_CCR, regs->readMiscReg(MISCREG_CCR) & 0xEF);
+ regs->setIntReg(ReturnValueReg, return_value.value());
+ } else {
+ // got an error, set XCC.C
+ regs->setMiscReg(MISCREG_CCR, regs->readMiscReg(MISCREG_CCR) | 0x10);
+ regs->setIntReg(ReturnValueReg, return_value.value());
+ }
+ }
+};
+
+#endif
diff --git a/src/arch/sparc/system.cc b/src/arch/sparc/system.cc
index e197e7918..63cbbe057 100644
--- a/src/arch/sparc/system.cc
+++ b/src/arch/sparc/system.cc
@@ -141,6 +141,7 @@ SparcSystem::unserialize(Checkpoint *cp, const std::string &section)
BEGIN_DECLARE_SIM_OBJECT_PARAMS(SparcSystem)
SimObjectParam<PhysicalMemory *> physmem;
+ SimpleEnumParam<System::MemoryMode> mem_mode;
Param<std::string> kernel;
Param<std::string> reset_bin;
@@ -161,6 +162,8 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(SparcSystem)
INIT_PARAM(boot_cpu_frequency, "Frequency of the boot CPU"),
INIT_PARAM(physmem, "phsyical memory"),
+ INIT_ENUM_PARAM(mem_mode, "Memory Mode, (1=atomic, 2=timing)",
+ System::MemoryModeStrings),
INIT_PARAM(kernel, "file that contains the kernel code"),
INIT_PARAM(reset_bin, "file that contains the reset code"),
INIT_PARAM(hypervisor_bin, "file that contains the hypervisor code"),
@@ -183,6 +186,7 @@ CREATE_SIM_OBJECT(SparcSystem)
p->name = getInstanceName();
p->boot_cpu_frequency = boot_cpu_frequency;
p->physmem = physmem;
+ p->mem_mode = mem_mode;
p->kernel_path = kernel;
p->reset_bin = reset_bin;
p->hypervisor_bin = hypervisor_bin;
diff --git a/src/arch/sparc/types.hh b/src/arch/sparc/types.hh
new file mode 100644
index 000000000..88fb24153
--- /dev/null
+++ b/src/arch/sparc/types.hh
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2003-2005 The Regents of The University of Michigan
+ * 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
+ */
+
+#ifndef __ARCH_SPARC_TYPES_HH__
+#define __ARCH_SPARC_TYPES_HH__
+
+#include <inttypes.h>
+
+namespace SparcISA
+{
+ typedef uint32_t MachInst;
+ typedef uint64_t ExtMachInst;
+
+ typedef uint64_t IntReg;
+ typedef uint64_t MiscReg;
+ typedef double FloatReg;
+ typedef uint64_t FloatRegBits;
+ typedef union
+ {
+ IntReg intReg;
+ FloatReg fpreg;
+ MiscReg ctrlreg;
+ } AnyReg;
+
+ enum RegContextParam
+ {
+ CONTEXT_CWP,
+ CONTEXT_GLOBALS
+ };
+
+ typedef int RegContextVal;
+
+ typedef uint8_t RegIndex;
+}
+
+#endif
diff --git a/src/arch/sparc/ua2005.cc b/src/arch/sparc/ua2005.cc
index b89d48663..6493ddfd5 100644
--- a/src/arch/sparc/ua2005.cc
+++ b/src/arch/sparc/ua2005.cc
@@ -37,7 +37,7 @@ SparcISA::MiscRegFile::setFSRegWithEffect(int miscReg, const MiscReg &val,
int64_t time;
SparcSystem *sys;
switch (miscReg) {
- /** Full system only ASRs */
+ /* Full system only ASRs */
case MISCREG_SOFTINT:
if (isNonPriv())
return new PrivilegedOpcode;
@@ -94,7 +94,7 @@ SparcISA::MiscRegFile::setFSRegWithEffect(int miscReg, const MiscReg &val,
sTickCompare.schedule(time * Clock::Int::ns);
return NoFault;
- /** Fullsystem only Priv registers. */
+ /* Fullsystem only Priv registers. */
case MISCREG_PIL:
if (FULL_SYSTEM) {
setReg(miscReg, val);
@@ -104,7 +104,7 @@ SparcISA::MiscRegFile::setFSRegWithEffect(int miscReg, const MiscReg &val,
} else
panic("PIL not implemented for syscall emulation\n");
- /** Hyper privileged registers */
+ /* Hyper privileged registers */
case MISCREG_HPSTATE:
case MISCREG_HINTP:
setReg(miscReg, val);
@@ -147,7 +147,7 @@ MiscRegFile::readFSRegWithEffect(int miscReg, Fault &fault, ThreadContext * tc)
{
switch (miscReg) {
- /** Privileged registers. */
+ /* Privileged registers. */
case MISCREG_SOFTINT:
if (isNonPriv()) {
fault = new PrivilegedOpcode;
@@ -177,7 +177,7 @@ MiscRegFile::readFSRegWithEffect(int miscReg, Fault &fault, ThreadContext * tc)
return readReg(miscReg);
- /** Hyper privileged registers */
+ /* Hyper privileged registers */
case MISCREG_HPSTATE:
case MISCREG_HINTP:
return readReg(miscReg);