diff options
Diffstat (limited to 'arch/sparc')
-rw-r--r-- | arch/sparc/faults.cc | 248 | ||||
-rw-r--r-- | arch/sparc/faults.hh | 587 | ||||
-rw-r--r-- | arch/sparc/isa/base.isa | 151 | ||||
-rw-r--r-- | arch/sparc/isa/decoder.isa | 490 | ||||
-rw-r--r-- | arch/sparc/isa/formats/basic.isa | 39 | ||||
-rw-r--r-- | arch/sparc/isa/formats/branch.isa | 48 | ||||
-rw-r--r-- | arch/sparc/isa/formats/integerop.isa | 20 | ||||
-rw-r--r-- | arch/sparc/isa/formats/mem.isa | 45 | ||||
-rw-r--r-- | arch/sparc/isa/formats/noop.isa | 29 | ||||
-rw-r--r-- | arch/sparc/isa/formats/trap.isa | 32 | ||||
-rw-r--r-- | arch/sparc/isa/includes.isa | 5 | ||||
-rw-r--r-- | arch/sparc/isa/operands.isa | 7 | ||||
-rw-r--r-- | arch/sparc/isa_traits.hh | 845 | ||||
-rw-r--r-- | arch/sparc/linux/process.cc (renamed from arch/sparc/linux_process.cc) | 2 | ||||
-rw-r--r-- | arch/sparc/linux/process.hh (renamed from arch/sparc/linux_process.hh) | 0 | ||||
-rw-r--r-- | arch/sparc/process.hh | 2 |
16 files changed, 1716 insertions, 834 deletions
diff --git a/arch/sparc/faults.cc b/arch/sparc/faults.cc new file mode 100644 index 000000000..b48fc600b --- /dev/null +++ b/arch/sparc/faults.cc @@ -0,0 +1,248 @@ +/* + * 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. + */ + +#include "arch/sparc/faults.hh" +#include "cpu/exec_context.hh" +#include "cpu/base.hh" +#include "base/trace.hh" + +namespace SparcISA +{ + +FaultName InternalProcessorError::_name = "intprocerr"; +TrapType InternalProcessorError::_trapType = 0x029; +FaultPriority InternalProcessorError::_priority = 4; +FaultStat InternalProcessorError::_count; + +FaultName MemAddressNotAligned::_name = "unalign"; +TrapType MemAddressNotAligned::_trapType = 0x034; +FaultPriority MemAddressNotAligned::_priority = 10; +FaultStat MemAddressNotAligned::_count; + +FaultName PowerOnReset::_name = "pow_reset"; +TrapType PowerOnReset::_trapType = 0x001; +FaultPriority PowerOnReset::_priority = 0; +FaultStat PowerOnReset::_count; + +FaultName WatchDogReset::_name = "watch_dog_reset"; +TrapType WatchDogReset::_trapType = 0x002; +FaultPriority WatchDogReset::_priority = 1; +FaultStat WatchDogReset::_count; + +FaultName ExternallyInitiatedReset::_name = "extern_reset"; +TrapType ExternallyInitiatedReset::_trapType = 0x003; +FaultPriority ExternallyInitiatedReset::_priority = 1; +FaultStat ExternallyInitiatedReset::_count; + +FaultName SoftwareInitiatedReset::_name = "software_reset"; +TrapType SoftwareInitiatedReset::_trapType = 0x004; +FaultPriority SoftwareInitiatedReset::_priority = 1; +FaultStat SoftwareInitiatedReset::_count; + +FaultName REDStateException::_name = "red_counte"; +TrapType REDStateException::_trapType = 0x005; +FaultPriority REDStateException::_priority = 1; +FaultStat REDStateException::_count; + +FaultName InstructionAccessException::_name = "inst_access"; +TrapType InstructionAccessException::_trapType = 0x008; +FaultPriority InstructionAccessException::_priority = 5; +FaultStat InstructionAccessException::_count; + +FaultName InstructionAccessMMUMiss::_name = "inst_mmu"; +TrapType InstructionAccessMMUMiss::_trapType = 0x009; +FaultPriority InstructionAccessMMUMiss::_priority = 2; +FaultStat InstructionAccessMMUMiss::_count; + +FaultName InstructionAccessError::_name = "inst_error"; +TrapType InstructionAccessError::_trapType = 0x00A; +FaultPriority InstructionAccessError::_priority = 3; +FaultStat InstructionAccessError::_count; + +FaultName IllegalInstruction::_name = "illegal_inst"; +TrapType IllegalInstruction::_trapType = 0x010; +FaultPriority IllegalInstruction::_priority = 7; +FaultStat IllegalInstruction::_count; + +FaultName PrivelegedOpcode::_name = "priv_opcode"; +TrapType PrivelegedOpcode::_trapType = 0x011; +FaultPriority PrivelegedOpcode::_priority = 6; +FaultStat PrivelegedOpcode::_count; + +FaultName UnimplementedLDD::_name = "unimp_ldd"; +TrapType UnimplementedLDD::_trapType = 0x012; +FaultPriority UnimplementedLDD::_priority = 6; +FaultStat UnimplementedLDD::_count; + +FaultName UnimplementedSTD::_name = "unimp_std"; +TrapType UnimplementedSTD::_trapType = 0x013; +FaultPriority UnimplementedSTD::_priority = 6; +FaultStat UnimplementedSTD::_count; + +FaultName FpDisabled::_name = "fp_disabled"; +TrapType FpDisabled::_trapType = 0x020; +FaultPriority FpDisabled::_priority = 8; +FaultStat FpDisabled::_count; + +FaultName FpExceptionIEEE754::_name = "fp_754"; +TrapType FpExceptionIEEE754::_trapType = 0x021; +FaultPriority FpExceptionIEEE754::_priority = 11; +FaultStat FpExceptionIEEE754::_count; + +FaultName FpExceptionOther::_name = "fp_other"; +TrapType FpExceptionOther::_trapType = 0x022; +FaultPriority FpExceptionOther::_priority = 11; +FaultStat FpExceptionOther::_count; + +FaultName TagOverflow::_name = "tag_overflow"; +TrapType TagOverflow::_trapType = 0x023; +FaultPriority TagOverflow::_priority = 14; +FaultStat TagOverflow::_count; + +FaultName DivisionByZero::_name = "div_by_zero"; +TrapType DivisionByZero::_trapType = 0x028; +FaultPriority DivisionByZero::_priority = 15; +FaultStat DivisionByZero::_count; + +FaultName DataAccessException::_name = "data_access"; +TrapType DataAccessException::_trapType = 0x030; +FaultPriority DataAccessException::_priority = 12; +FaultStat DataAccessException::_count; + +FaultName DataAccessMMUMiss::_name = "data_mmu"; +TrapType DataAccessMMUMiss::_trapType = 0x031; +FaultPriority DataAccessMMUMiss::_priority = 12; +FaultStat DataAccessMMUMiss::_count; + +FaultName DataAccessError::_name = "data_error"; +TrapType DataAccessError::_trapType = 0x032; +FaultPriority DataAccessError::_priority = 12; +FaultStat DataAccessError::_count; + +FaultName DataAccessProtection::_name = "data_protection"; +TrapType DataAccessProtection::_trapType = 0x033; +FaultPriority DataAccessProtection::_priority = 12; +FaultStat DataAccessProtection::_count; + +FaultName LDDFMemAddressNotAligned::_name = "unalign_lddf"; +TrapType LDDFMemAddressNotAligned::_trapType = 0x035; +FaultPriority LDDFMemAddressNotAligned::_priority = 10; +FaultStat LDDFMemAddressNotAligned::_count; + +FaultName STDFMemAddressNotAligned::_name = "unalign_stdf"; +TrapType STDFMemAddressNotAligned::_trapType = 0x036; +FaultPriority STDFMemAddressNotAligned::_priority = 10; +FaultStat STDFMemAddressNotAligned::_count; + +FaultName PrivelegedAction::_name = "priv_action"; +TrapType PrivelegedAction::_trapType = 0x037; +FaultPriority PrivelegedAction::_priority = 11; +FaultStat PrivelegedAction::_count; + +FaultName LDQFMemAddressNotAligned::_name = "unalign_ldqf"; +TrapType LDQFMemAddressNotAligned::_trapType = 0x038; +FaultPriority LDQFMemAddressNotAligned::_priority = 10; +FaultStat LDQFMemAddressNotAligned::_count; + +FaultName STQFMemAddressNotAligned::_name = "unalign_stqf"; +TrapType STQFMemAddressNotAligned::_trapType = 0x039; +FaultPriority STQFMemAddressNotAligned::_priority = 10; +FaultStat STQFMemAddressNotAligned::_count; + +FaultName AsyncDataError::_name = "async_data"; +TrapType AsyncDataError::_trapType = 0x040; +FaultPriority AsyncDataError::_priority = 2; +FaultStat AsyncDataError::_count; + +//The enumerated faults + +FaultName CleanWindow::_name = "clean_win"; +TrapType CleanWindow::_baseTrapType = 0x024; +FaultPriority CleanWindow::_priority = 10; +FaultStat CleanWindow::_count; + +FaultName InterruptLevelN::_name = "interrupt_n"; +TrapType InterruptLevelN::_baseTrapType = 0x041; +FaultStat InterruptLevelN::_count; + +FaultName SpillNNormal::_name = "spill_n_normal"; +TrapType SpillNNormal::_baseTrapType = 0x080; +FaultPriority SpillNNormal::_priority = 9; +FaultStat SpillNNormal::_count; + +FaultName SpillNOther::_name = "spill_n_other"; +TrapType SpillNOther::_baseTrapType = 0x0A0; +FaultPriority SpillNOther::_priority = 9; +FaultStat SpillNOther::_count; + +FaultName FillNNormal::_name = "fill_n_normal"; +TrapType FillNNormal::_baseTrapType = 0x0C0; +FaultPriority FillNNormal::_priority = 9; +FaultStat FillNNormal::_count; + +FaultName FillNOther::_name = "fill_n_other"; +TrapType FillNOther::_baseTrapType = 0x0E0; +FaultPriority FillNOther::_priority = 9; +FaultStat FillNOther::_count; + +FaultName TrapInstruction::_name = "trap_inst_n"; +TrapType TrapInstruction::_baseTrapType = 0x100; +FaultPriority TrapInstruction::_priority = 16; +FaultStat TrapInstruction::_count; + + + +#if FULL_SYSTEM + +void SparcFault::invoke(ExecContext * xc) +{ + FaultBase::invoke(xc); + countStat()++; + + //Use the SPARC trap state machine + /*// exception restart address + if (setRestartAddress() || !xc->inPalMode()) + xc->setMiscReg(AlphaISA::IPR_EXC_ADDR, xc->regs.pc); + + if (skipFaultingInstruction()) { + // traps... skip faulting instruction. + xc->setMiscReg(AlphaISA::IPR_EXC_ADDR, + xc->readMiscReg(AlphaISA::IPR_EXC_ADDR) + 4); + } + + if (!xc->inPalMode()) + AlphaISA::swap_palshadow(&(xc->regs), true); + + xc->regs.pc = xc->readMiscReg(AlphaISA::IPR_PAL_BASE) + vect(); + xc->regs.npc = xc->regs.pc + sizeof(MachInst);*/ +} + +#endif + +} // namespace SparcISA + diff --git a/arch/sparc/faults.hh b/arch/sparc/faults.hh new file mode 100644 index 000000000..318b1ad5a --- /dev/null +++ b/arch/sparc/faults.hh @@ -0,0 +1,587 @@ +/* + * 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. + */ + +#ifndef __ALPHA_FAULTS_HH__ +#define __ALPHA_FAULTS_HH__ + +#include "sim/faults.hh" + +// The design of the "name" and "vect" functions is in sim/faults.hh + +namespace SparcISA +{ + +typedef const uint32_t TrapType; +typedef const uint32_t FaultPriority; + +class SparcFault : public FaultBase +{ + public: +#if FULL_SYSTEM + void invoke(ExecContext * xc); +#endif + virtual TrapType trapType() = 0; + virtual FaultPriority priority() = 0; + virtual FaultStat & countStat() = 0; +}; + +class InternalProcessorError : public SparcFault +{ + private: + static FaultName _name; + static TrapType _trapType; + static FaultPriority _priority; + static FaultStat _count; + public: + FaultName name() {return _name;} + TrapType trapType() {return _trapType;} + FaultPriority priority() {return _priority;} + FaultStat & countStat() {return _count;} + bool isMachineCheckFault() {return true;} +}; + +class MemAddressNotAligned : public SparcFault +{ + private: + static FaultName _name; + static TrapType _trapType; + static FaultPriority _priority; + static FaultStat _count; + public: + FaultName name() {return _name;} + TrapType trapType() {return _trapType;} + FaultPriority priority() {return _priority;} + FaultStat & countStat() {return _count;} + bool isAlignmentFault() {return true;} +}; + +static inline Fault genMachineCheckFault() +{ + return new InternalProcessorError; +} + +static inline Fault genAlignmentFault() +{ + return new MemAddressNotAligned; +} + +class PowerOnReset : public SparcFault +{ + private: + static FaultName _name; + static TrapType _trapType; + static FaultPriority _priority; + static FaultStat _count; + public: + FaultName name() {return _name;} + TrapType trapType() {return _trapType;} + FaultPriority priority() {return _priority;} + FaultStat & countStat() {return _count;} +}; + +class WatchDogReset : public SparcFault +{ + private: + static FaultName _name; + static TrapType _trapType; + static FaultPriority _priority; + static FaultStat _count; + public: + FaultName name() {return _name;} + TrapType trapType() {return _trapType;} + FaultPriority priority() {return _priority;} + FaultStat & countStat() {return _count;} +}; + +class ExternallyInitiatedReset : public SparcFault +{ + private: + static FaultName _name; + static TrapType _trapType; + static FaultPriority _priority; + static FaultStat _count; + public: + FaultName name() {return _name;} + TrapType trapType() {return _trapType;} + FaultPriority priority() {return _priority;} + FaultStat & countStat() {return _count;} +}; + +class SoftwareInitiatedReset : public SparcFault +{ + private: + static FaultName _name; + static TrapType _trapType; + static FaultPriority _priority; + static FaultStat _count; + public: + FaultName name() {return _name;} + TrapType trapType() {return _trapType;} + FaultPriority priority() {return _priority;} + FaultStat & countStat() {return _count;} +}; + +class REDStateException : public SparcFault +{ + private: + static FaultName _name; + static TrapType _trapType; + static FaultPriority _priority; + static FaultStat _count; + public: + FaultName name() {return _name;} + TrapType trapType() {return _trapType;} + FaultPriority priority() {return _priority;} + FaultStat & countStat() {return _count;} +}; + +class InstructionAccessException : public SparcFault +{ + private: + static FaultName _name; + static TrapType _trapType; + static FaultPriority _priority; + static FaultStat _count; + public: + FaultName name() {return _name;} + TrapType trapType() {return _trapType;} + FaultPriority priority() {return _priority;} + FaultStat & countStat() {return _count;} +}; + +class InstructionAccessMMUMiss : public SparcFault +{ + private: + static FaultName _name; + static TrapType _trapType; + static FaultPriority _priority; + static FaultStat _count; + public: + FaultName name() {return _name;} + TrapType trapType() {return _trapType;} + FaultPriority priority() {return _priority;} + FaultStat & countStat() {return _count;} +}; + +class InstructionAccessError : public SparcFault +{ + private: + static FaultName _name; + static TrapType _trapType; + static FaultPriority _priority; + static FaultStat _count; + public: + FaultName name() {return _name;} + TrapType trapType() {return _trapType;} + FaultPriority priority() {return _priority;} + FaultStat & countStat() {return _count;} +}; + +class IllegalInstruction : public SparcFault +{ + private: + static FaultName _name; + static TrapType _trapType; + static FaultPriority _priority; + static FaultStat _count; + public: + FaultName name() {return _name;} + TrapType trapType() {return _trapType;} + FaultPriority priority() {return _priority;} + FaultStat & countStat() {return _count;} +}; + +class PrivelegedOpcode : public SparcFault +{ + private: + static FaultName _name; + static TrapType _trapType; + static FaultPriority _priority; + static FaultStat _count; + public: + FaultName name() {return _name;} + TrapType trapType() {return _trapType;} + FaultPriority priority() {return _priority;} + FaultStat & countStat() {return _count;} +}; + +class UnimplementedLDD : public SparcFault +{ + private: + static FaultName _name; + static TrapType _trapType; + static FaultPriority _priority; + static FaultStat _count; + public: + FaultName name() {return _name;} + TrapType trapType() {return _trapType;} + FaultPriority priority() {return _priority;} + FaultStat & countStat() {return _count;} +}; + +class UnimplementedSTD : public SparcFault +{ + private: + static FaultName _name; + static TrapType _trapType; + static FaultPriority _priority; + static FaultStat _count; + public: + FaultName name() {return _name;} + TrapType trapType() {return _trapType;} + FaultPriority priority() {return _priority;} + FaultStat & countStat() {return _count;} +}; + +class FpDisabled : public SparcFault +{ + private: + static FaultName _name; + static TrapType _trapType; + static FaultPriority _priority; + static FaultStat _count; + public: + FaultName name() {return _name;} + TrapType trapType() {return _trapType;} + FaultPriority priority() {return _priority;} + FaultStat & countStat() {return _count;} +}; + +class FpExceptionIEEE754 : public SparcFault +{ + private: + static FaultName _name; + static TrapType _trapType; + static FaultPriority _priority; + static FaultStat _count; + public: + FaultName name() {return _name;} + TrapType trapType() {return _trapType;} + FaultPriority priority() {return _priority;} + FaultStat & countStat() {return _count;} +}; + +class FpExceptionOther : public SparcFault +{ + private: + static FaultName _name; + static TrapType _trapType; + static FaultPriority _priority; + static FaultStat _count; + public: + FaultName name() {return _name;} + TrapType trapType() {return _trapType;} + FaultPriority priority() {return _priority;} + FaultStat & countStat() {return _count;} +}; + +class TagOverflow : public SparcFault +{ + private: + static FaultName _name; + static TrapType _trapType; + static FaultPriority _priority; + static FaultStat _count; + public: + FaultName name() {return _name;} + TrapType trapType() {return _trapType;} + FaultPriority priority() {return _priority;} + FaultStat & countStat() {return _count;} +}; + +class DivisionByZero : public SparcFault +{ + private: + static FaultName _name; + static TrapType _trapType; + static FaultPriority _priority; + static FaultStat _count; + public: + FaultName name() {return _name;} + TrapType trapType() {return _trapType;} + FaultPriority priority() {return _priority;} + FaultStat & countStat() {return _count;} +}; + +class DataAccessException : public SparcFault +{ + private: + static FaultName _name; + static TrapType _trapType; + static FaultPriority _priority; + static FaultStat _count; + public: + FaultName name() {return _name;} + TrapType trapType() {return _trapType;} + FaultPriority priority() {return _priority;} + FaultStat & countStat() {return _count;} +}; + +class DataAccessMMUMiss : public SparcFault +{ + private: + static FaultName _name; + static TrapType _trapType; + static FaultPriority _priority; + static FaultStat _count; + public: + FaultName name() {return _name;} + TrapType trapType() {return _trapType;} + FaultPriority priority() {return _priority;} + FaultStat & countStat() {return _count;} +}; + +class DataAccessError : public SparcFault +{ + private: + static FaultName _name; + static TrapType _trapType; + static FaultPriority _priority; + static FaultStat _count; + public: + FaultName name() {return _name;} + TrapType trapType() {return _trapType;} + FaultPriority priority() {return _priority;} + FaultStat & countStat() {return _count;} +}; + +class DataAccessProtection : public SparcFault +{ + private: + static FaultName _name; + static TrapType _trapType; + static FaultPriority _priority; + static FaultStat _count; + public: + FaultName name() {return _name;} + TrapType trapType() {return _trapType;} + FaultPriority priority() {return _priority;} + FaultStat & countStat() {return _count;} +}; + +class LDDFMemAddressNotAligned : public SparcFault +{ + private: + static FaultName _name; + static TrapType _trapType; + static FaultPriority _priority; + static FaultStat _count; + public: + FaultName name() {return _name;} + TrapType trapType() {return _trapType;} + FaultPriority priority() {return _priority;} + FaultStat & countStat() {return _count;} +}; + +class STDFMemAddressNotAligned : public SparcFault +{ + private: + static FaultName _name; + static TrapType _trapType; + static FaultPriority _priority; + static FaultStat _count; + public: + FaultName name() {return _name;} + TrapType trapType() {return _trapType;} + FaultPriority priority() {return _priority;} + FaultStat & countStat() {return _count;} +}; + +class PrivelegedAction : public SparcFault +{ + private: + static FaultName _name; + static TrapType _trapType; + static FaultPriority _priority; + static FaultStat _count; + public: + FaultName name() {return _name;} + TrapType trapType() {return _trapType;} + FaultPriority priority() {return _priority;} + FaultStat & countStat() {return _count;} +}; + +class LDQFMemAddressNotAligned : public SparcFault +{ + private: + static FaultName _name; + static TrapType _trapType; + static FaultPriority _priority; + static FaultStat _count; + public: + FaultName name() {return _name;} + TrapType trapType() {return _trapType;} + FaultPriority priority() {return _priority;} + FaultStat & countStat() {return _count;} +}; + +class STQFMemAddressNotAligned : public SparcFault +{ + private: + static FaultName _name; + static TrapType _trapType; + static FaultPriority _priority; + static FaultStat _count; + public: + FaultName name() {return _name;} + TrapType trapType() {return _trapType;} + FaultPriority priority() {return _priority;} + FaultStat & countStat() {return _count;} +}; + +class AsyncDataError : public SparcFault +{ + private: + static FaultName _name; + static TrapType _trapType; + static FaultPriority _priority; + static FaultStat _count; + public: + FaultName name() {return _name;} + TrapType trapType() {return _trapType;} + FaultPriority priority() {return _priority;} + FaultStat & countStat() {return _count;} +}; + +class EnumeratedFault : public SparcFault +{ + protected: + uint32_t _n; + virtual TrapType baseTrapType() = 0; + public: + EnumeratedFault(uint32_t n) : SparcFault() {_n = n;} + TrapType trapType() {return baseTrapType() + _n;} +}; + +class CleanWindow : public EnumeratedFault +{ + private: + static FaultName _name; + static TrapType _baseTrapType; + static FaultPriority _priority; + static FaultStat _count; + TrapType baseTrapType() {return _baseTrapType;} + public: + CleanWindow(uint32_t n) : EnumeratedFault(n) {;} + FaultName name() {return _name;} + FaultPriority priority() {return _priority;} + FaultStat & countStat() {return _count;} +}; + +class InterruptLevelN : public EnumeratedFault +{ + private: + static FaultName _name; + static TrapType _baseTrapType; + static FaultStat _count; + TrapType baseTrapType() {return _baseTrapType;} + public: + InterruptLevelN(uint32_t n) : EnumeratedFault(n) {;} + FaultName name() {return _name;} + FaultPriority priority() {return 32 - _n;} + FaultStat & countStat() {return _count;} +}; + +class SpillNNormal : public EnumeratedFault +{ + private: + static FaultName _name; + static TrapType _baseTrapType; + static FaultPriority _priority; + static FaultStat _count; + TrapType baseTrapType() {return _baseTrapType;} + public: + SpillNNormal(uint32_t n) : EnumeratedFault(n) {;} + FaultName name() {return _name;} + FaultPriority priority() {return _priority;} + FaultStat & countStat() {return _count;} +}; + +class SpillNOther : public EnumeratedFault +{ + private: + static FaultName _name; + static TrapType _baseTrapType; + static FaultPriority _priority; + static FaultStat _count; + TrapType baseTrapType() {return _baseTrapType;} + public: + SpillNOther(uint32_t n) : EnumeratedFault(n) {;} + FaultName name() {return _name;} + FaultPriority priority() {return _priority;} + FaultStat & countStat() {return _count;} +}; + +class FillNNormal : public EnumeratedFault +{ + private: + static FaultName _name; + static TrapType _baseTrapType; + static FaultPriority _priority; + static FaultStat _count; + TrapType baseTrapType() {return _baseTrapType;} + public: + FillNNormal(uint32_t n) : EnumeratedFault(n) {;} + FaultName name() {return _name;} + FaultPriority priority() {return _priority;} + FaultStat & countStat() {return _count;} +}; + +class FillNOther : public EnumeratedFault +{ + private: + static FaultName _name; + static TrapType _baseTrapType; + static FaultPriority _priority; + static FaultStat _count; + TrapType baseTrapType() {return _baseTrapType;} + public: + FillNOther(uint32_t n) : EnumeratedFault(n) {;} + FaultName name() {return _name;} + FaultPriority priority() {return _priority;} + FaultStat & countStat() {return _count;} +}; + +class TrapInstruction : public EnumeratedFault +{ + private: + static FaultName _name; + static TrapType _baseTrapType; + static FaultPriority _priority; + static FaultStat _count; + TrapType baseTrapType() {return _baseTrapType;} + public: + TrapInstruction(uint32_t n) : EnumeratedFault(n) {;} + FaultName name() {return _name;} + FaultPriority priority() {return _priority;} + FaultStat & countStat() {return _count;} +}; + +} // SparcISA namespace + +#endif // __FAULTS_HH__ diff --git a/arch/sparc/isa/base.isa b/arch/sparc/isa/base.isa index b504f1906..992504369 100644 --- a/arch/sparc/isa/base.isa +++ b/arch/sparc/isa/base.isa @@ -4,79 +4,126 @@ // output header {{ + + struct condCodes + { + uint8_t c:1; + uint8_t v:1; + uint8_t z:1; + uint8_t n:1; + } + + enum condTest + { + Always=0x8, + Never=0x0, + NotEqual=0x9, + Equal=0x1, + Greater=0xA, + LessOrEqual=0x2, + GreaterOrEqual=0xB, + Less=0x3, + GreaterUnsigned=0xC, + LessOrEqualUnsigned=0x4, + CarryClear=0xD, + CarrySet=0x5, + Positive=0xE, + Negative=0x6, + OverflowClear=0xF, + OverflowSet=0x7 + } + /** * Base class for all SPARC static instructions. */ - class SparcStaticInst : public StaticInst<SPARCISA> + class SparcStaticInst : public StaticInst { - protected: - - // Constructor. - SparcStaticInst(const char *mnem, MachInst _machInst, OpClass __opClass) - : StaticInst<SPARCISA>(mnem, _machInst, __opClass) + protected: + // Constructor. + SparcStaticInst(const char *mnem, + MachInst _machInst, OpClass __opClass) + : StaticInst(mnem, _machInst, __opClass) { } - std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; + std::string generateDisassembly(Addr pc, + const SymbolTable *symtab) const; }; - bool passesCondition(struct {uint8_t c:1; uint8_t v:1; uint8_t z:1; uint8_t n:1} codes, uint8_t condition); + bool passesCondition(condCodes codes, condTest condition); }}; output decoder {{ - std::string SparcStaticInst::generateDisassembly(Addr pc, const SymbolTable *symtab) const + std::string SparcStaticInst::generateDisassembly(Addr pc, + const SymbolTable *symtab) const { - std::stringstream ss; + std::stringstream ss; - ccprintf(ss, "%-10s ", mnemonic); + ccprintf(ss, "%-10s ", mnemonic); - // just print the first two source regs... if there's - // a third one, it's a read-modify-write dest (Rc), - // e.g. for CMOVxx - if(_numSrcRegs > 0) - { - printReg(ss, _srcRegIdx[0]); - } - if(_numSrcRegs > 1) - { - ss << ","; - printReg(ss, _srcRegIdx[1]); - } + // just print the first two source regs... if there's + // a third one, it's a read-modify-write dest (Rc), + // e.g. for CMOVxx + if(_numSrcRegs > 0) + { + printReg(ss, _srcRegIdx[0]); + } + if(_numSrcRegs > 1) + { + ss << ","; + printReg(ss, _srcRegIdx[1]); + } - // just print the first dest... if there's a second one, - // it's generally implicit - if(_numDestRegs > 0) - { - if(_numSrcRegs > 0) - ss << ","; - printReg(ss, _destRegIdx[0]); - } + // just print the first dest... if there's a second one, + // it's generally implicit + if(_numDestRegs > 0) + { + if(_numSrcRegs > 0) + ss << ","; + printReg(ss, _destRegIdx[0]); + } - return ss.str(); + return ss.str(); } - bool passesCondition(struct {uint8_t c:1; uint8_t v:1; uint8_t z:1; uint8_t n:1} codes, uint8_t condition) + bool passesCondition(condCodes codes, condTest condition) { - switch(condition) - { - case 0b1000: return true; - case 0b0000: return false; - case 0b1001: return !codes.z; - case 0b0001: return codes.z; - case 0b1010: return !(codes.z | (codes.n ^ codes.v)); - case 0b0010: return codes.z | (codes.n ^ codes.v); - case 0b1011: return !(codes.n ^ codes.v); - case 0b0011: return (codes.n ^ codes.v); - case 0b1100: return !(codes.c | codes.z); - case 0b0100: return (codes.c | codes.z); - case 0b1101: return !codes.c; - case 0b0101: return codes.c; - case 0b1110: return !codes.n; - case 0b0110: return codes.n; - case 0b1111: return !codes.v; - case 0b0111: return codes.v; - } + switch(condition) + { + case Always: + return true; + case Never: + return false; + case NotEqual: + return !codes.z; + case Equal: + return codes.z; + case Greater: + return !(codes.z | (codes.n ^ codes.v)); + case LessOrEqual: + return codes.z | (codes.n ^ codes.v); + case GreaterOrEqual: + return !(codes.n ^ codes.v); + case Less: + return (codes.n ^ codes.v); + case GreaterUnsigned: + return !(codes.c | codes.z); + case LessOrEqualUnsigned: + return (codes.c | codes.z); + case CarryClear: + return !codes.c; + case CarrySet: + return codes.c; + case Positive: + return !codes.n; + case Negative: + return codes.n; + case OverflowClear: + return !codes.v; + case OverflowSet: + return codes.v; + } } }}; diff --git a/arch/sparc/isa/decoder.isa b/arch/sparc/isa/decoder.isa index 06834ecc3..eb458211b 100644 --- a/arch/sparc/isa/decoder.isa +++ b/arch/sparc/isa/decoder.isa @@ -3,55 +3,64 @@ // The actual decoder specification // -decode OP default Trap::unknown({{illegal_instruction}}) { +decode OP default Trap::unknown({{IllegalInstruction}}) { 0x0: decode OP2 { - 0x0: Trap::illtrap({{illegal_instruction}}); //ILLTRAP - 0x1: Branch::bpcc({{ - switch((CC12 << 1) | CC02) - { - case 1: case 3: - throw illegal_instruction; - case 0: - if(passesCondition(xc->regs.MiscRegs.ccrFields.icc, COND2)) - ;//branchHere - break; - case 2: - if(passesCondition(xc->regs.MiscRegs.ccrFields.xcc, COND2)) - ;//branchHere - break; - } - }});//BPcc - 0x2: Branch::bicc({{ - if(passesCondition(xc->regs.MiscRegs.ccrFields.icc, COND2)) - ;//branchHere - }});//Bicc - 0x3: Branch::bpr({{ - switch(RCOND) - { - case 0: case 4: - throw illegal_instruction; - case 1: - if(Rs1 == 0) ;//branchHere - break; - case 2: - if(Rs1 <= 0) ;//branchHere - break; - case 3: - if(Rs1 < 0) ;//branchHere - break; - case 5: - if(Rs1 != 0) ;//branchHere - break; - case 6: - if(Rs1 > 0) ;//branchHere - break; - case 7: - if(Rs1 >= 0) ;//branchHere - break; - } + 0x0: Trap::illtrap({{illegal_instruction}}); //ILLTRAP + 0x1: Branch::bpcc({{ + switch((CC12 << 1) | CC02) + { + case 1: + case 3: + fault = new IllegalInstruction; + case 0: + if(passesCondition(xc->regs.MiscRegs.ccrFields.icc, COND2)) + ;//branchHere + break; + case 2: + if(passesCondition(xc->regs.MiscRegs.ccrFields.xcc, COND2)) + ;//branchHere + break; + } + }});//BPcc + 0x2: Branch::bicc({{ + if(passesCondition(xc->regs.MiscRegs.ccrFields.icc, COND2)) + ;//branchHere + }});//Bicc + 0x3: Branch::bpr({{ + switch(RCOND) + { + case 0: + case 4: + fault = new IllegalInstruction; + case 1: + if(Rs1 == 0) + ;//branchHere + break; + case 2: + if(Rs1 <= 0) + ;//branchHere + break; + case 3: + if(Rs1 < 0) + ;//branchHere + break; + case 5: + if(Rs1 != 0) + ;//branchHere + break; + case 6: + if(Rs1 > 0) + ;//branchHere + break; + case 7: + if(Rs1 >= 0) + ;//branchHere + break; + } }}); //BPr - 0x4: IntegerOp::sethi({{Rd = (IMM22 << 10) & 0xFFFFFC00;}}); //SETHI (or NOP if rd == 0 and imm == 0) + //SETHI (or NOP if rd == 0 and imm == 0) + 0x4: IntegerOp::sethi({{Rd = (IMM22 << 10) & 0xFFFFFC00;}}); 0x5: Trap::fbpfcc({{throw fp_disabled;}}); //FBPfcc 0x6: Trap::fbfcc({{throw fp_disabled;}}); //FBfcc } @@ -60,150 +69,165 @@ decode OP default Trap::unknown({{illegal_instruction}}) { Rd = xc->pc; }}); 0x2: decode OP3 { - format IntegerOp { - 0x00: add({{ - INT64 val2 = (I ? SIMM13.sdw : Rs2.sdw); - Rd = Rs1.sdw + val2; - }});//ADD - 0x01: and({{ - UINT64 val2 = (I ? SIMM13.sdw : Rs2.udw); - Rd = Rs1.udw & val2; - }});//AND - 0x02: or({{ - UINT64 val2 = (I ? SIMM13.sdw : Rs2.udw); - Rd = Rs1.udw | val2; - }});//OR - 0x03: xor({{ - UINT64 val2 = (I ? SIMM13.sdw : Rs2.udw); - Rd = Rs1.udw ^ val2; - }});//XOR - 0x04: sub({{ - INT64 val2 = ~((UINT64)(I ? SIMM13.sdw : Rs2.udw))+1; - Rd = Rs1.sdw + val2; - }});//SUB - 0x05: andn({{ - UINT64 val2 = (I ? SIMM13.sdw : Rs2.udw); - Rd = Rs1.udw & ~val2; - }});//ANDN - 0x06: orn({{ - UINT64 val2 = (I ? SIMM13.sdw : Rs2.udw); - Rd = Rs1.udw | ~val2; - }});//ORN - 0x07: xnor({{ - UINT64 val2 = (I ? SIMM13.sdw : Rs2.udw); - Rd = ~(Rs1.udw ^ val2); - }});//XNOR - 0x08: addc({{ - INT64 val2 = (I ? SIMM13.sdw : Rs2.sdw); - INT64 carryin = xc->regs.MiscRegs.ccrfields.iccfields.c; - Rd = Rs1.sdw + val2 + carryin; - }});//ADDC - 0x09: mulx({{ - INT64 val2 = (I ? SIMM13.sdw : Rs2); - Rd = Rs1 * val2; - }});//MULX - 0x0A: umul({{ - UINT64 resTemp, val2 = (I ? SIMM13.sdw : Rs2.udw); - Rd = resTemp = Rs1.udw<31:0> * val2<31:0>; - xc->regs.MiscRegs.yFields.value = resTemp<63:32>; - }});//UMUL - 0x0B: smul({{ - INT64 resTemp, val2 = (I ? SIMM13.sdw : Rs2.sdw); - rd.sdw = resTemp = Rs1.sdw<31:0> * val2<31:0>; - xc->regs.MiscRegs.yFields.value = resTemp<63:32>; - }});//SMUL - 0x0C: subc({{ - INT64 val2 = ~((INT64)(I ? SIMM13.sdw : Rs2.sdw))+1; - INT64 carryin = xc->regs.MiscRegs.ccrfields.iccfields.c; - Rd.sdw = Rs1.sdw + val2 + carryin; - }});//SUBC - 0x0D: udivx({{ - UINT64 val2 = (I ? SIMM13.sdw : Rs2.udw); - if(val2 == 0) throw division_by_zero; - Rd.udw = Rs1.udw / val2; - }});//UDIVX - 0x0E: udiv({{ - UINT32 resTemp, val2 = (I ? SIMM13.sw : Rs2.udw<31:0>); - if(val2 == 0) throw division_by_zero; - resTemp = (UINT64)((xc->regs.MiscRegs.yFields.value << 32) | Rs1.udw<31:0>) / val2; - INT32 overflow = (resTemp<63:32> != 0); - if(overflow) rd.udw = resTemp = 0xFFFFFFFF; - else rd.udw = resTemp; - }}); //UDIV - 0x0F: sdiv({{ - INT32 resTemp, val2 = (I ? SIMM13.sw : Rs2.sdw<31:0>); - if(val2 == 0) throw division_by_zero; - Rd.sdw = resTemp = (INT64)((xc->regs.MiscRegs.yFields.value << 32) | Rs1.sdw<31:0>) / val2; - INT32 overflow = (resTemp<63:31> != 0); - INT32 underflow = (resTemp<63:> && resTemp<62:31> != 0xFFFFFFFF); - if(overflow) rd.udw = resTemp = 0x7FFFFFFF; - else if(underflow) rd.udw = resTemp = 0xFFFFFFFF80000000; - else rd.udw = resTemp; - }});//SDIV - } - format IntegerOpCc { - 0x10: addcc({{ - INT64 resTemp, val2 = (I ? SIMM13.sdw : Rs2); - Rd = resTemp = Rs1 + val2;}}, - {{((Rs1 & 0xFFFFFFFF + val2 & 0xFFFFFFFF) >> 31)}}, - {{Rs1<31:> == val2<31:> && val2<31:> != resTemp<31:>}}, - {{((Rs1 >> 1) + (val2 >> 1) + (Rs1 & val2 & 0x1))<63:>}}, - {{Rs1<63:> == val2<63:> && val2<63:> != resTemp<63:>}} - );//ADDcc - 0x11: andcc({{ - INT64 val2 = (I ? SIMM13.sdw : Rs2); - Rd = Rs1 & val2;}} - ,{{0}},{{0}},{{0}},{{0}});//ANDcc - 0x12: orcc({{ - INT64 val2 = (I ? SIMM13.sdw : Rs2); - Rd = Rs1 | val2;}} - ,{{0}},{{0}},{{0}},{{0}});//ORcc - 0x13: xorcc({{ - INT64 val2 = (I ? SIMM13.sdw : Rs2); - Rd = Rs1 ^ val2;}} - ,{{0}},{{0}},{{0}},{{0}});//XORcc - 0x14: subcc({{ - INT64 resTemp, val2 = (INT64)(I ? SIMM13.sdw : Rs2); - Rd = resTemp = Rs1 - val2;}}, - {{((Rs1 & 0xFFFFFFFF + (~val2) & 0xFFFFFFFF + 1) >> 31)}}, - {{Rs1<31:> != val2<31:> && Rs1<31:> != resTemp<31:>}}, - {{((Rs1 >> 1) + (~val2) >> 1) + ((Rs1 | ~val2) & 0x1))<63:>}}, - {{Rs1<63:> != val2<63:> && Rs1<63:> != resTemp<63:>}} - );//SUBcc - 0x15: andncc({{ - INT64 val2 = (I ? SIMM13.sdw : Rs2); - Rd = Rs1 & ~val2;}} - ,{{0}},{{0}},{{0}},{{0}});//ANDNcc - 0x16: orncc({{ - INT64 val2 = (I ? SIMM13.sdw : Rs2); - Rd = Rs1 | ~val2;}} - ,{{0}},{{0}},{{0}},{{0}});//ORNcc - 0x17: xnorcc({{ - INT64 val2 = (I ? SIMM13.sdw : Rs2); - Rd = ~(Rs1 ^ val2);}} - ,{{0}},{{0}},{{0}},{{0}});//XNORcc - 0x18: addccc({{ - INT64 resTemp, val2 = (I ? SIMM13.sdw : Rs2); - INT64 carryin = xc->regs.MiscRegs.ccrfields.iccfields.c; - Rd = resTemp = Rs1 + val2 + carryin;}}, - {{((Rs1 & 0xFFFFFFFF + val2 & 0xFFFFFFFF) >> 31 + carryin)}}, - {{Rs1<31:> == val2<31:> && val2<31:> != resTemp<31:>}}, - {{((Rs1 >> 1) + (val2 >> 1) + ((Rs1 & val2) | (carryin & (Rs1 | val2)) & 0x1))<63:>}}, - {{Rs1<63:> == val2<63:> && val2<63:> != resTemp<63:>}} - );//ADDCcc - 0x1A: umulcc({{ - UINT64 resTemp, val2 = (I ? SIMM13.sdw : Rs2); - Rd = resTemp = Rs1.udw<31:0> * val2<31:0>; - xc->regs.MiscRegs.yFields.value = resTemp<63:32>;}} - ,{{0}},{{0}},{{0}},{{0}});//UMULcc + format IntegerOp { + 0x00: add({{ + int64_t val2 = (I ? SIMM13.sdw : Rs2.sdw); + Rd = Rs1.sdw + val2; + }});//ADD + 0x01: and({{ + uint64_t val2 = (I ? SIMM13.sdw : Rs2.udw); + Rd = Rs1.udw & val2; + }});//AND + 0x02: or({{ + uint64_t val2 = (I ? SIMM13.sdw : Rs2.udw); + Rd = Rs1.udw | val2; + }});//OR + 0x03: xor({{ + uint64_t val2 = (I ? SIMM13.sdw : Rs2.udw); + Rd = Rs1.udw ^ val2; + }});//XOR + 0x04: sub({{ + int64_t val2 = ~((uint64_t)(I ? SIMM13.sdw : Rs2.udw))+1; + Rd = Rs1.sdw + val2; + }});//SUB + 0x05: andn({{ + uint64_t val2 = (I ? SIMM13.sdw : Rs2.udw); + Rd = Rs1.udw & ~val2; + }});//ANDN + 0x06: orn({{ + uint64_t val2 = (I ? SIMM13.sdw : Rs2.udw); + Rd = Rs1.udw | ~val2; + }});//ORN + 0x07: xnor({{ + uint64_t val2 = (I ? SIMM13.sdw : Rs2.udw); + Rd = ~(Rs1.udw ^ val2); + }});//XNOR + 0x08: addc({{ + int64_t val2 = (I ? SIMM13.sdw : Rs2.sdw); + int64_t carryin = xc->regs.MiscRegs.ccrfields.iccfields.c; + Rd = Rs1.sdw + val2 + carryin; + }});//ADDC + 0x09: mulx({{ + int64_t val2 = (I ? SIMM13.sdw : Rs2); + Rd = Rs1 * val2; + }});//MULX + 0x0A: umul({{ + uint64_t resTemp, val2 = (I ? SIMM13.sdw : Rs2.udw); + Rd = resTemp = Rs1.udw<31:0> * val2<31:0>; + xc->regs.MiscRegs.yFields.value = resTemp<63:32>; + }});//UMUL + 0x0B: smul({{ + int64_t resTemp, val2 = (I ? SIMM13.sdw : Rs2.sdw); + rd.sdw = resTemp = Rs1.sdw<31:0> * val2<31:0>; + xc->regs.MiscRegs.yFields.value = resTemp<63:32>; + }});//SMUL + 0x0C: subc({{ + int64_t val2 = ~((int64_t)(I ? SIMM13.sdw : Rs2.sdw))+1; + int64_t carryin = xc->regs.MiscRegs.ccrfields.iccfields.c; + Rd.sdw = Rs1.sdw + val2 + carryin; + }});//SUBC + 0x0D: udivx({{ + uint64_t val2 = (I ? SIMM13.sdw : Rs2.udw); + if(val2 == 0) throw division_by_zero; + Rd.udw = Rs1.udw / val2; + }});//UDIVX + 0x0E: udiv({{ + uint32_t resTemp, val2 = (I ? SIMM13.sw : Rs2.udw<31:0>); + if(val2 == 0) + fault = new DivisionByZero; + resTemp = (uint64_t)((xc->regs.MiscRegs.yFields.value << 32) + | Rs1.udw<31:0>) / val2; + int32_t overflow = (resTemp<63:32> != 0); + if(overflow) + rd.udw = resTemp = 0xFFFFFFFF; + else + rd.udw = resTemp; + }}); //UDIV + 0x0F: sdiv({{ + int32_t resTemp, val2 = (I ? SIMM13.sw : Rs2.sdw<31:0>); + if(val2 == 0) + fault = new DivisionByZero; + + Rd.sdw = (int64_t)((xc->regs.MiscRegs.yFields.value << 32) | + Rs1.sdw<31:0>) / val2; + resTemp = Rd.sdw; + int32_t overflow = (resTemp<63:31> != 0); + int32_t underflow = + (resTemp<63:> && resTemp<62:31> != 0xFFFFFFFF); + if(overflow) + rd.udw = resTemp = 0x7FFFFFFF; + else if(underflow) + rd.udw = resTemp = 0xFFFFFFFF80000000; + else + rd.udw = resTemp; + }});//SDIV + } + format IntegerOpCc { + 0x10: addcc({{ + int64_t resTemp, val2 = (I ? SIMM13.sdw : Rs2); + Rd = resTemp = Rs1 + val2;}}, + {{((Rs1 & 0xFFFFFFFF + val2 & 0xFFFFFFFF) >> 31)}}, + {{Rs1<31:> == val2<31:> && val2<31:> != resTemp<31:>}}, + {{((Rs1 >> 1) + (val2 >> 1) + (Rs1 & val2 & 0x1))<63:>}}, + {{Rs1<63:> == val2<63:> && val2<63:> != resTemp<63:>}} + );//ADDcc + 0x11: andcc({{ + int64_t val2 = (I ? SIMM13.sdw : Rs2); + Rd = Rs1 & val2;}}, + {{0}},{{0}},{{0}},{{0}});//ANDcc + 0x12: orcc({{ + int64_t val2 = (I ? SIMM13.sdw : Rs2); + Rd = Rs1 | val2;}}, + {{0}},{{0}},{{0}},{{0}});//ORcc + 0x13: xorcc({{ + int64_t val2 = (I ? SIMM13.sdw : Rs2); + Rd = Rs1 ^ val2;}}, + {{0}},{{0}},{{0}},{{0}});//XORcc + 0x14: subcc({{ + int64_t resTemp, val2 = (int64_t)(I ? SIMM13.sdw : Rs2); + Rd = resTemp = Rs1 - val2;}}, + {{((Rs1 & 0xFFFFFFFF + (~val2) & 0xFFFFFFFF + 1) >> 31)}}, + {{Rs1<31:> != val2<31:> && Rs1<31:> != resTemp<31:>}}, + {{((Rs1 >> 1) + (~val2) >> 1) + + ((Rs1 | ~val2) & 0x1))<63:>}}, + {{Rs1<63:> != val2<63:> && Rs1<63:> != resTemp<63:>}} + );//SUBcc + 0x15: andncc({{ + int64_t val2 = (I ? SIMM13.sdw : Rs2); + Rd = Rs1 & ~val2;}}, + {{0}},{{0}},{{0}},{{0}});//ANDNcc + 0x16: orncc({{ + int64_t val2 = (I ? SIMM13.sdw : Rs2); + Rd = Rs1 | ~val2;}}, + {{0}},{{0}},{{0}},{{0}});//ORNcc + 0x17: xnorcc({{ + int64_t val2 = (I ? SIMM13.sdw : Rs2); + Rd = ~(Rs1 ^ val2);}}, + {{0}},{{0}},{{0}},{{0}});//XNORcc + 0x18: addccc({{ + int64_t resTemp, val2 = (I ? SIMM13.sdw : Rs2); + int64_t carryin = xc->regs.MiscRegs.ccrfields.iccfields.c; + Rd = resTemp = Rs1 + val2 + carryin;}}, + {{((Rs1 & 0xFFFFFFFF + val2 & 0xFFFFFFFF) >> 31 + + carryin)}}, + {{Rs1<31:> == val2<31:> && val2<31:> != resTemp<31:>}}, + {{((Rs1 >> 1) + (val2 >> 1) + + ((Rs1 & val2) | (carryin & (Rs1 | val2)) & 0x1))<63:>}}, + {{Rs1<63:> == val2<63:> && val2<63:> != resTemp<63:>}} + );//ADDCcc + 0x1A: umulcc({{ + uint64_t resTemp, val2 = (I ? SIMM13.sdw : Rs2); + Rd = resTemp = Rs1.udw<31:0> * val2<31:0>; + xc->regs.MiscRegs.yFields.value = resTemp<63:32>;}}, + {{0}},{{0}},{{0}},{{0}});//UMULcc 0x1B: smulcc({{ - INT64 resTemp, val2 = (I ? SIMM13.sdw : Rs2); + int64_t resTemp, val2 = (I ? SIMM13.sdw : Rs2); Rd = resTemp = Rs1.sdw<31:0> * val2<31:0>; xc->regs.MiscRegs.yFields.value = resTemp<63:32>;}} ,{{0}},{{0}},{{0}},{{0}});//SMULcc 0x1C: subccc({{ - INT64 resTemp, val2 = (INT64)(I ? SIMM13.sdw : Rs2); - INT64 carryin = xc->regs.MiscRegs.ccrfields.iccfields.c; + int64_t resTemp, val2 = (int64_t)(I ? SIMM13.sdw : Rs2); + int64_t carryin = xc->regs.MiscRegs.ccrfields.iccfields.c; Rd = resTemp = Rs1 + ~(val2 + carryin) + 1;}}, {{((Rs1 & 0xFFFFFFFF + (~(val2 + carryin)) & 0xFFFFFFFF + 1) >> 31)}}, {{Rs1<31:> != val2<31:> && Rs1<31:> != resTemp<31:>}}, @@ -211,15 +235,15 @@ decode OP default Trap::unknown({{illegal_instruction}}) { {{Rs1<63:> != val2<63:> && Rs1<63:> != resTemp<63:>}} );//SUBCcc 0x1D: udivxcc({{ - UINT64 val2 = (I ? SIMM13.sdw : Rs2.udw); + uint64_t val2 = (I ? SIMM13.sdw : Rs2.udw); if(val2 == 0) throw division_by_zero; Rd.udw = Rs1.udw / val2;}} ,{{0}},{{0}},{{0}},{{0}});//UDIVXcc 0x1E: udivcc({{ - UINT32 resTemp, val2 = (I ? SIMM13.sw : Rs2.udw<31:0>); + uint32_t resTemp, val2 = (I ? SIMM13.sw : Rs2.udw<31:0>); if(val2 == 0) throw division_by_zero; - resTemp = (UINT64)((xc->regs.MiscRegs.yFields.value << 32) | Rs1.udw<31:0>) / val2; - INT32 overflow = (resTemp<63:32> != 0); + resTemp = (uint64_t)((xc->regs.MiscRegs.yFields.value << 32) | Rs1.udw<31:0>) / val2; + int32_t overflow = (resTemp<63:32> != 0); if(overflow) rd.udw = resTemp = 0xFFFFFFFF; else rd.udw = resTemp;}}, {{0}}, @@ -228,11 +252,11 @@ decode OP default Trap::unknown({{illegal_instruction}}) { {{0}} );//UDIVcc 0x1F: sdivcc({{ - INT32 resTemp, val2 = (I ? SIMM13.sw : Rs2.sdw<31:0>); + int32_t resTemp, val2 = (I ? SIMM13.sw : Rs2.sdw<31:0>); if(val2 == 0) throw division_by_zero; - Rd.sdw = resTemp = (INT64)((xc->regs.MiscRegs.yFields.value << 32) | Rs1.sdw<31:0>) / val2; - INT32 overflow = (resTemp<63:31> != 0); - INT32 underflow = (resTemp<63:> && resTemp<62:31> != 0xFFFFFFFF); + Rd.sdw = resTemp = (int64_t)((xc->regs.MiscRegs.yFields.value << 32) | Rs1.sdw<31:0>) / val2; + int32_t overflow = (resTemp<63:31> != 0); + int32_t underflow = (resTemp<63:> && resTemp<62:31> != 0xFFFFFFFF); if(overflow) rd.udw = resTemp = 0x7FFFFFFF; else if(underflow) rd.udw = resTemp = 0xFFFFFFFF80000000; else rd.udw = resTemp;}}, @@ -242,27 +266,27 @@ decode OP default Trap::unknown({{illegal_instruction}}) { {{0}} );//SDIVcc 0x20: taddcc({{ - INT64 resTemp, val2 = (I ? SIMM13.sdw : Rs2); + int64_t resTemp, val2 = (I ? SIMM13.sdw : Rs2); Rd = resTemp = Rs1 + val2; - INT32 overflow = Rs1<1:0> || val2<1:0> || (Rs1<31:> == val2<31:> && val2<31:> != resTemp<31:>);}}, + int32_t overflow = Rs1<1:0> || val2<1:0> || (Rs1<31:> == val2<31:> && val2<31:> != resTemp<31:>);}}, {{((Rs1 & 0xFFFFFFFF + val2 & 0xFFFFFFFF) >> 31)}}, {{overflow}}, {{((Rs1 >> 1) + (val2 >> 1) + (Rs1 & val2 & 0x1))<63:>}}, {{Rs1<63:> == val2<63:> && val2<63:> != resTemp<63:>}} );//TADDcc 0x21: tsubcc({{ - INT64 resTemp, val2 = (I ? SIMM13.sdw : Rs2); + int64_t resTemp, val2 = (I ? SIMM13.sdw : Rs2); Rd = resTemp = Rs1 + val2; - INT32 overflow = Rs1<1:0> || val2<1:0> || (Rs1<31:> == val2<31:> && val2<31:> != resTemp<31:>);}}, + int32_t overflow = Rs1<1:0> || val2<1:0> || (Rs1<31:> == val2<31:> && val2<31:> != resTemp<31:>);}}, {{(Rs1 & 0xFFFFFFFF + val2 & 0xFFFFFFFF) >> 31)}}, {{overflow}}, {{((Rs1 >> 1) + (val2 >> 1) + (Rs1 & val2 & 0x1))<63:>}}, {{Rs1<63:> == val2<63:> && val2<63:> != resTemp<63:>}} );//TSUBcc 0x22: taddcctv({{ - INT64 resTemp, val2 = (I ? SIMM13.sdw : Rs2); + int64_t resTemp, val2 = (I ? SIMM13.sdw : Rs2); Rd = resTemp = Rs1 + val2; - INT32 overflow = Rs1<1:0> || val2<1:0> || (Rs1<31:> == val2<31:> && val2<31:> != resTemp<31:>); + int32_t overflow = Rs1<1:0> || val2<1:0> || (Rs1<31:> == val2<31:> && val2<31:> != resTemp<31:>); if(overflow) throw tag_overflow;}}, {{((Rs1 & 0xFFFFFFFF + val2 & 0xFFFFFFFF) >> 31)}}, {{overflow}}, @@ -270,9 +294,9 @@ decode OP default Trap::unknown({{illegal_instruction}}) { {{Rs1<63:> == val2<63:> && val2<63:> != resTemp<63:>}} );//TADDccTV 0x23: tsubcctv({{ - INT64 resTemp, val2 = (I ? SIMM13.sdw : Rs2); + int64_t resTemp, val2 = (I ? SIMM13.sdw : Rs2); Rd = resTemp = Rs1 + val2; - INT32 overflow = Rs1<1:0> || val2<1:0> || (Rs1<31:> == val2<31:> && val2<31:> != resTemp<31:>); + int32_t overflow = Rs1<1:0> || val2<1:0> || (Rs1<31:> == val2<31:> && val2<31:> != resTemp<31:>); if(overflow) throw tag_overflow;}}, {{((Rs1 & 0xFFFFFFFF + val2 & 0xFFFFFFFF) >> 31)}}, {{overflow}}, @@ -280,9 +304,9 @@ decode OP default Trap::unknown({{illegal_instruction}}) { {{Rs1<63:> == val2<63:> && val2<63:> != resTemp<63:>}} );//TSUBccTV 0x24: mulscc({{ - INT64 resTemp, multiplicand = (I ? SIMM13.sdw : Rs2); - INT32 multiplier = Rs1<31:0>; - INT32 savedLSB = Rs1<0:>; + int64_t resTemp, multiplicand = (I ? SIMM13.sdw : Rs2); + int32_t multiplier = Rs1<31:0>; + int32_t savedLSB = Rs1<0:>; multiplier = multipler<31:1> | ((xc->regs.MiscRegs.ccrFields.iccFields.n ^ xc->regs.MiscRegs.ccrFields.iccFields.v) << 32); @@ -368,14 +392,14 @@ decode OP default Trap::unknown({{illegal_instruction}}) { } }});//MOVcc 0x2D: sdivx({{ - INT64 val2 = (I ? SIMM13.sdw : Rs2.sdw); + int64_t val2 = (I ? SIMM13.sdw : Rs2.sdw); if(val2 == 0) throw division_by_zero; Rd.sdw = Rs1.sdw / val2; }});//SDIVX 0x2E: decode RS1 { 0x0: IntegerOp::popc({{ - INT64 count = 0, val2 = (I ? SIMM13.sdw : Rs2.sdw); - UINT8 oneBits[] = {0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4} + int64_t count = 0, val2 = (I ? SIMM13.sdw : Rs2.sdw); + uint8_t oneBits[] = {0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4} for(unsigned int x = 0; x < 16; x++) { count += oneBits[val2 & 0xF]; @@ -384,7 +408,7 @@ decode OP default Trap::unknown({{illegal_instruction}}) { }});//POPC } 0x2F: movr({{ - UINT64 val2 = (I ? SIMM10.sdw : Rs2.sdw); + uint64_t val2 = (I ? SIMM10.sdw : Rs2.sdw); switch(RCOND) { case 0: case 4: @@ -412,19 +436,19 @@ decode OP default Trap::unknown({{illegal_instruction}}) { }});//MOVR 0x30: decode RD { 0x0: wry({{ - UINT64 val2 = (I ? SIMM13.sdw : Rs2.sdw); + uint64_t val2 = (I ? SIMM13.sdw : Rs2.sdw); xc->regs.MiscRegs.y = Rs1 ^ val2; }});//WRY 0x2: wrccr({{ - UINT64 val2 = (I ? SIMM13.sdw : Rs2.sdw); + uint64_t val2 = (I ? SIMM13.sdw : Rs2.sdw); xc->regs.MiscRegs.ccr = Rs1 ^ val2; }});//WRCCR 0x3: wrasi({{ - UINT64 val2 = (I ? SIMM13.sdw : Rs2.sdw); + uint64_t val2 = (I ? SIMM13.sdw : Rs2.sdw); xc->regs.MiscRegs.asi = Rs1 ^ val2; }});//WRASI 0x6: wrfprs({{ - UINT64 val2 = (I ? SIMM13.sdw : Rs2.sdw); + uint64_t val2 = (I ? SIMM13.sdw : Rs2.sdw); xc->regs.MiscRegs.asi = Rs1 ^ val2; }});//WRFPRS 0xF: Trap::sir({{software_initiated_reset}}); //SIR @@ -435,63 +459,63 @@ decode OP default Trap::unknown({{illegal_instruction}}) { } 0x32: decode RD { 0x0: wrprtpc({{checkPriv - UINT64 val2 = (I ? SIMM13.sdw : Rs2.sdw); + uint64_t val2 = (I ? SIMM13.sdw : Rs2.sdw); xc->regs.MiscRegs.tpc[xc->regs.MiscRegs.tl] = Rs1 ^ val2; }}); 0x1: wrprtnpc({{checkPriv - UINT64 val2 = (I ? SIMM13.sdw : Rs2.sdw); + uint64_t val2 = (I ? SIMM13.sdw : Rs2.sdw); xc->regs.MiscRegs.tnpc[xc->regs.MiscRegs.tl] = Rs1 ^ val2; }}); 0x2: wrprtstate({{checkPriv - UINT64 val2 = (I ? SIMM13.sdw : Rs2.sdw); + uint64_t val2 = (I ? SIMM13.sdw : Rs2.sdw); xc->regs.MiscRegs.tstate[xc->regs.MiscRegs.tl] = Rs1 ^ val2; }}); 0x3: wrprtt({{checkPriv - UINT64 val2 = (I ? SIMM13.sdw : Rs2.sdw); + uint64_t val2 = (I ? SIMM13.sdw : Rs2.sdw); xc->regs.MiscRegs.tt[xc->regs.MiscRegs.tl] = Rs1 ^ val2; }}); 0x4: wrprtick({{checkPriv - UINT64 val2 = (I ? SIMM13.sdw : Rs2.sdw); + uint64_t val2 = (I ? SIMM13.sdw : Rs2.sdw); xc->regs.MiscRegs.tick = Rs1 ^ val2; }}); 0x5: wrprtba({{checkPriv - UINT64 val2 = (I ? SIMM13.sdw : Rs2.sdw); + uint64_t val2 = (I ? SIMM13.sdw : Rs2.sdw); xc->regs.MiscRegs.tba = Rs1 ^ val2; }}); 0x6: wrprpstate({{checkPriv - UINT64 val2 = (I ? SIMM13.sdw : Rs2.sdw); + uint64_t val2 = (I ? SIMM13.sdw : Rs2.sdw); xc->regs.MiscRegs.pstate = Rs1 ^ val2; }}); 0x7: wrprtl({{checkPriv - UINT64 val2 = (I ? SIMM13.sdw : Rs2.sdw); + uint64_t val2 = (I ? SIMM13.sdw : Rs2.sdw); xc->regs.MiscRegs.tl = Rs1 ^ val2; }}); 0x8: wrprpil({{checkPriv - UINT64 val2 = (I ? SIMM13.sdw : Rs2.sdw); + uint64_t val2 = (I ? SIMM13.sdw : Rs2.sdw); xc->regs.MiscRegs.pil = Rs1 ^ val2; }}); 0x9: wrprcwp({{checkPriv - UINT64 val2 = (I ? SIMM13.sdw : Rs2.sdw); + uint64_t val2 = (I ? SIMM13.sdw : Rs2.sdw); xc->regs.MiscRegs.cwp = Rs1 ^ val2; }}); 0xA: wrprcansave({{checkPriv - UINT64 val2 = (I ? SIMM13.sdw : Rs2.sdw); + uint64_t val2 = (I ? SIMM13.sdw : Rs2.sdw); xc->regs.MiscRegs.cansave = Rs1 ^ val2; }}); 0xB: wrprcanrestore({{checkPriv - UINT64 val2 = (I ? SIMM13.sdw : Rs2.sdw); + uint64_t val2 = (I ? SIMM13.sdw : Rs2.sdw); xc->regs.MiscRegs.canrestore = Rs1 ^ val2; }}); 0xC: wrprcleanwin({{checkPriv - UINT64 val2 = (I ? SIMM13.sdw : Rs2.sdw); + uint64_t val2 = (I ? SIMM13.sdw : Rs2.sdw); xc->regs.MiscRegs.cleanwin = Rs1 ^ val2; }}); 0xD: wrprotherwin({{checkPriv - UINT64 val2 = (I ? SIMM13.sdw : Rs2.sdw); + uint64_t val2 = (I ? SIMM13.sdw : Rs2.sdw); xc->regs.MiscRegs.otherwin = Rs1 ^ val2; }}); 0xE: wrprwstate({{checkPriv - UINT64 val2 = (I ? SIMM13.sdw : Rs2.sdw); + uint64_t val2 = (I ? SIMM13.sdw : Rs2.sdw); xc->regs.MiscRegs.wstate = Rs1 ^ val2; }}); } @@ -532,7 +556,7 @@ decode OP default Trap::unknown({{illegal_instruction}}) { 0x01: ldub({{Rd.ub = Mem.ub;}}); //LDUB 0x02: lduh({{Rd.uhw = Mem.uhw;}}); //LDUH 0x03: ldd({{ - UINT64 val = Mem.udw; + uint64_t val = Mem.udw; setIntReg(RD & (~1), val<31:0>); setIntReg(RD | 1, val<63:32>); }});//LDD @@ -553,7 +577,7 @@ decode OP default Trap::unknown({{illegal_instruction}}) { }}); //LDSTUB 0x0E: stx({{Rd.udw = Mem.udw;}}); //STX 0x0F: swap({{ - UINT32 temp = Rd.uw; + uint32_t temp = Rd.uw; Rd.uw = Mem.uw; Mem.uw = temp; }}); //SWAP @@ -561,7 +585,7 @@ decode OP default Trap::unknown({{illegal_instruction}}) { 0x11: lduba({{Rd.ub = Mem.ub;}}); //LDUBA 0x12: lduha({{Rd.uhw = Mem.uhw;}}); //LDUHA 0x13: ldda({{ - UINT64 val = Mem.udw; + uint64_t val = Mem.udw; setIntReg(RD & (~1), val<31:0>); setIntReg(RD | 1, val<63:32>); }}); //LDDA @@ -582,7 +606,7 @@ decode OP default Trap::unknown({{illegal_instruction}}) { }}); //LDSTUBA 0x1E: stxa({{Mem.sdw = Rd.sdw}}); //STXA 0x1F: swapa({{ - UINT32 temp = Rd.uw; + uint32_t temp = Rd.uw; Rd.uw = Mem.uw; Mem.uw = temp; }}); //SWAPA @@ -621,14 +645,14 @@ decode OP default Trap::unknown({{illegal_instruction}}) { 0x3C: Cas::casa( - {{UINT64 val = Mem.uw; + {{uint64_t val = Mem.uw; if(Rs2.uw == val) Mem.uw = Rd.uw; Rd.uw = val; }}); //CASA 0x3D: Noop::prefetcha({{ }}); //PREFETCHA 0x3E: Cas::casxa( - {{UINT64 val = Mem.udw; + {{uint64_t val = Mem.udw; if(Rs2 == val) Mem.udw = Rd; Rd = val; diff --git a/arch/sparc/isa/formats/basic.isa b/arch/sparc/isa/formats/basic.isa index 1994df41c..73df7617d 100644 --- a/arch/sparc/isa/formats/basic.isa +++ b/arch/sparc/isa/formats/basic.isa @@ -11,16 +11,17 @@ def template BasicDeclare {{ */ class %(class_name)s : public %(base_class)s { - public: - /// Constructor. - %(class_name)s(MachInst machInst); - %(BasicExecDeclare)s - }; + public: + // Constructor. + %(class_name)s(MachInst machInst); + %(BasicExecDeclare)s + }; }}; // Basic instruction class constructor template. def template BasicConstructor {{ - inline %(class_name)s::%(class_name)s(MachInst machInst) : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s) + inline %(class_name)s::%(class_name)s(MachInst machInst) + : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s) { %(constructor)s; } @@ -28,20 +29,21 @@ def template BasicConstructor {{ // Basic instruction class execute method template. def template BasicExecute {{ - Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const + Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const { - Fault fault = No_Fault; + Fault fault = NoFault; - %(fp_enable_check)s; - %(op_decl)s; - %(op_rd)s; - %(code)s; + %(fp_enable_check)s; + %(op_decl)s; + %(op_rd)s; + %(code)s; - if(fault == No_Fault) - { - %(op_wb)s; - } - return fault; + if(fault == NoFault) + { + %(op_wb)s; + } + return fault; } }}; @@ -57,7 +59,8 @@ def template BasicDecodeWithMnemonic {{ // The most basic instruction format... used only for a few misc. insts def format BasicOperate(code, *flags) {{ - iop = InstObjParams(name, Name, 'SparcStaticInst', CodeBlock(code), flags) + iop = InstObjParams(name, Name, 'SparcStaticInst', + CodeBlock(code), flags) header_output = BasicDeclare.subst(iop) decoder_output = BasicConstructor.subst(iop) decode_block = BasicDecode.subst(iop) diff --git a/arch/sparc/isa/formats/branch.isa b/arch/sparc/isa/formats/branch.isa index c4c0a90af..80101de1b 100644 --- a/arch/sparc/isa/formats/branch.isa +++ b/arch/sparc/isa/formats/branch.isa @@ -9,48 +9,44 @@ output header {{ */ class Branch : public SparcStaticInst { - protected: - - /// Constructor - Branch(const char *mnem, MachInst _machInst, OpClass __opClass) : SparcStaticInst(mnem, _machInst, __opClass) - { - } - - std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; + protected: + // Constructor + Branch(const char *mnem, MachInst _machInst, OpClass __opClass) : + SparcStaticInst(mnem, _machInst, __opClass) + { + } + + std::string generateDisassembly(Addr pc, + const SymbolTable *symtab) const; }; }}; output decoder {{ std::string Branch::generateDisassembly(Addr pc, const SymbolTable *symtab) const { - return "Disassembly of integer instruction\n"; + return "Branch instruction\n"; } }}; def template BranchExecute {{ - Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const + Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const { - //Attempt to execute the instruction - try - { - checkPriv; + //Attempt to execute the instruction + Fault fault = NoFault; + checkPriv; - %(op_decl)s; - %(op_rd)s; - %(code)s; - } - //If we have an exception for some reason, - //deal with it - catch(SparcException except) - { - //Deal with exception - return No_Fault; - } + %(op_decl)s; + %(op_rd)s; + %(code)s; + if(fault == NoFault) + { //Write the resulting state to the execution context %(op_wb)s; + } - return No_Fault; + return fault; } }}; diff --git a/arch/sparc/isa/formats/integerop.isa b/arch/sparc/isa/formats/integerop.isa index 275a346d3..5a9e09896 100644 --- a/arch/sparc/isa/formats/integerop.isa +++ b/arch/sparc/isa/formats/integerop.isa @@ -9,21 +9,23 @@ output header {{ */ class IntegerOp : public SparcStaticInst { - protected: + protected: + // Constructor + IntegerOp(const char *mnem, MachInst _machInst, OpClass __opClass) : + SparcStaticInst(mnem, _machInst, __opClass) + { + } - /// Constructor - IntegerOp(const char *mnem, MachInst _machInst, OpClass __opClass) : SparcStaticInst(mnem, _machInst, __opClass) - { - } - - std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; + std::string generateDisassembly(Addr pc, + const SymbolTable *symtab) const; }; }}; output decoder {{ - std::string IntegerOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const + std::string IntegerOp::generateDisassembly(Addr pc, + const SymbolTable *symtab) const { - return "Disassembly of integer instruction\n"; + return "Integer instruction\n"; } }}; diff --git a/arch/sparc/isa/formats/mem.isa b/arch/sparc/isa/formats/mem.isa index abc00b6f2..d72de47d0 100644 --- a/arch/sparc/isa/formats/mem.isa +++ b/arch/sparc/isa/formats/mem.isa @@ -9,48 +9,43 @@ output header {{ */ class Mem : public SparcStaticInst { - protected: + protected: - /// Constructor - Mem(const char *mnem, MachInst _machInst, OpClass __opClass) : SparcStaticInst(mnem, _machInst, __opClass) - { - } + // Constructor + Mem(const char *mnem, MachInst _machInst, OpClass __opClass) : + SparcStaticInst(mnem, _machInst, __opClass) + { + } - std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; + std::string generateDisassembly(Addr pc, + const SymbolTable *symtab) const; }; }}; output decoder {{ std::string Mem::generateDisassembly(Addr pc, const SymbolTable *symtab) const { - return "Disassembly of integer instruction\n"; + return "Memory instruction\n"; } }}; def template MemExecute {{ - Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const + Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const { - //Attempt to execute the instruction - try - { - - %(op_decl)s; - %(op_rd)s; - ea_code - %(code)s; - } - //If we have an exception for some reason, - //deal with it - catch(SparcException except) - { - //Deal with exception - return No_Fault; - } + Fault fault = NoFault; + %(op_decl)s; + %(op_rd)s; + ea_code + %(code)s; + if(fault == NoFault) + { //Write the resulting state to the execution context %(op_wb)s; + } - return No_Fault; + return fault; } }}; diff --git a/arch/sparc/isa/formats/noop.isa b/arch/sparc/isa/formats/noop.isa index bc83e3261..fa4047f06 100644 --- a/arch/sparc/isa/formats/noop.isa +++ b/arch/sparc/isa/formats/noop.isa @@ -5,33 +5,36 @@ output header {{ /** - * Base class for integer operations. + * Noop class. */ class Noop : public SparcStaticInst { - protected: + protected: + // Constructor + Noop(const char *mnem, MachInst _machInst, OpClass __opClass) : + SparcStaticInst(mnem, _machInst, __opClass) + { + } - /// Constructor - Noop(const char *mnem, MachInst _machInst, OpClass __opClass) : SparcStaticInst(mnem, _machInst, __opClass) - { - } - - std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; + std::string generateDisassembly(Addr pc, + const SymbolTable *symtab) const; }; }}; output decoder {{ - std::string Noop::generateDisassembly(Addr pc, const SymbolTable *symtab) const + std::string Noop::generateDisassembly(Addr pc, + const SymbolTable *symtab) const { - return "Disassembly of integer instruction\n"; + return "Noop\n"; } }}; def template NoopExecute {{ - Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const + Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const { - //Nothing to see here, move along - return No_Fault; + //Nothing to see here, move along + return NoFault; } }}; diff --git a/arch/sparc/isa/formats/trap.isa b/arch/sparc/isa/formats/trap.isa index bee77fe69..ff3aadf72 100644 --- a/arch/sparc/isa/formats/trap.isa +++ b/arch/sparc/isa/formats/trap.isa @@ -9,35 +9,33 @@ output header {{ */ class Trap : public SparcStaticInst { - protected: + protected: - /// Constructor - Trap(const char *mnem, MachInst _machInst, OpClass __opClass) : SparcStaticInst(mnem, _machInst, __opClass) - { - } + // Constructor + Trap(const char *mnem, MachInst _machInst, OpClass __opClass) : + SparcStaticInst(mnem, _machInst, __opClass) + { + } - std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; + std::string generateDisassembly(Addr pc, + const SymbolTable *symtab) const; }; }}; output decoder {{ - std::string Trap::generateDisassembly(Addr pc, const SymbolTable *symtab) const + std::string Trap::generateDisassembly(Addr pc, + const SymbolTable *symtab) const { - return "Disassembly of integer instruction\n"; + return "Trap instruction\n"; } }}; def template TrapExecute {{ - Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const + Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const { - //Call into the trap handler with the appropriate fault - return No_Fault; - } - - //Write the resulting state to the execution context - %(op_wb)s; - - return No_Fault; + //TODO: set up a software fault and return it. + return NoFault; } }}; diff --git a/arch/sparc/isa/includes.isa b/arch/sparc/isa/includes.isa index ff7cb7d1d..a99018b49 100644 --- a/arch/sparc/isa/includes.isa +++ b/arch/sparc/isa/includes.isa @@ -9,8 +9,9 @@ output header {{ #include <iomanip> #include "cpu/static_inst.hh" -#include "traps.hh" +#include "arch/sparc/faults.hh" #include "mem/mem_req.hh" // some constructors use MemReq flags +#include "arch/sparc/isa_traits.hh" }}; output decoder {{ @@ -22,6 +23,8 @@ output decoder {{ #if defined(linux) #include <fenv.h> #endif + +using namespace SparcISA; }}; output exec {{ diff --git a/arch/sparc/isa/operands.isa b/arch/sparc/isa/operands.isa index c5ba263d6..64f5abd08 100644 --- a/arch/sparc/isa/operands.isa +++ b/arch/sparc/isa/operands.isa @@ -22,11 +22,10 @@ def operands {{ #'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) + 'Mem': ('Mem', 'udw', None, ('IsMemRef', 'IsLoad', 'IsStore'), 4), #'NPC': ('NPC', 'uq', None, ( None, None, 'IsControl' ), 4), #'Runiq': ('ControlReg', 'uq', 'Uniq', None, 1), #'FPCR': ('ControlReg', 'uq', 'Fpcr', None, 1), - # The next two are hacks for non-full-system call-pal emulation - #'R0': ('IntReg', 'uq', '0', None, 1), - #'R16': ('IntReg', 'uq', '16', None, 1) + 'R0': ('IntReg', 'udw', '0', None, 1), + 'R16': ('IntReg', 'udw', '16', None, 1) }}; diff --git a/arch/sparc/isa_traits.hh b/arch/sparc/isa_traits.hh index 7dd49aed9..5a58bbaef 100644 --- a/arch/sparc/isa_traits.hh +++ b/arch/sparc/isa_traits.hh @@ -29,22 +29,24 @@ #ifndef __ARCH_SPARC_ISA_TRAITS_HH__ #define __ARCH_SPARC_ISA_TRAITS_HH__ -//This makes sure the big endian versions of certain functions are used. -namespace BigEndianGuest {} -using namespace BigEndianGuest; - #include "arch/sparc/faults.hh" #include "base/misc.hh" +#include "config/full_system.hh" #include "sim/host.hh" +//This makes sure the big endian versions of certain functions are used. +namespace BigEndianGuest {} +using namespace BigEndianGuest; + +class ExecContext; class FastCPU; //class FullCPU; -//class Checkpoint; +class Checkpoint; #define TARGET_SPARC -template <class ISA> class StaticInst; -template <class ISA> class StaticInstPtr; +class StaticInst; +class StaticInstPtr; //namespace EV5 //{ @@ -52,479 +54,454 @@ template <class ISA> class StaticInstPtr; // int ITB_ASN_ASN(uint64_t reg); //} -class SPARCISA +namespace SparcISA { - public: + typedef uint32_t MachInst; + typedef uint64_t Addr; + typedef uint8_t RegIndex; - typedef uint32_t MachInst; - typedef uint64_t Addr; - typedef uint8_t RegIndex; + enum + { + MemoryEnd = 0xffffffffffffffffULL, - enum - { - MemoryEnd = 0xffffffffffffffffULL, + NumFloatRegs = 32, + NumMiscRegs = 32, - NumFloatRegs = 32, - NumMiscRegs = 32, + MaxRegsOfAnyType = 32, + // Static instruction parameters + MaxInstSrcRegs = 3, + MaxInstDestRegs = 2, - MaxRegsOfAnyType = 32, - // Static instruction parameters - MaxInstSrcRegs = 3, - MaxInstDestRegs = 2, + // Maximum trap level + MaxTL = 4, - // Maximum trap level - MaxTL = 4 + // semantically meaningful register indices + ZeroReg = 0 // architecturally meaningful + // the rest of these depend on the ABI + }; + typedef uint64_t IntReg; - // semantically meaningful register indices - ZeroReg = 0, // architecturally meaningful - // the rest of these depend on the ABI - } - typedef uint64_t IntReg; - - class IntRegFile - { + class IntRegFile + { private: - //For right now, let's pretend the register file is static - IntReg regs[32]; + //For right now, let's pretend the register file is static + IntReg regs[32]; public: - IntReg & operator [] (RegIndex index) - { - //Don't allow indexes outside of the 32 registers - index &= 0x1F - return regs[index]; - } + IntReg & operator [] (RegIndex index) + { + //Don't allow indexes outside of the 32 registers + index &= 0x1F; + return regs[index]; + } + }; + + void serialize(std::ostream & os); + + void unserialize(Checkpoint *cp, const std::string §ion); + + class FloatRegFile + { + private: + //By using the largest data type, we ensure everything + //is aligned correctly in memory + union + { + long double rawRegs[16]; + uint64_t regDump[32]; }; - - void inline serialize(std::ostream & os) + class QuadRegs { - SERIALIZE_ARRAY(regs, 32); - } - - void inline unserialize(Checkpoint &*cp, const std::string §ion) + private: + FloatRegFile * parent; + public: + QuadRegs(FloatRegFile * p) : parent(p) {;} + long double & operator [] (RegIndex index) + { + //Quad floats are index by the single + //precision register the start on, + //and only 16 should be accessed + index = (index >> 2) & 0xF; + return parent->rawRegs[index]; + } + }; + class DoubleRegs { - UNSERIALIZE_ARRAY(regs, 32); - } - - class FloatRegFile + private: + FloatRegFile * parent; + public: + DoubleRegs(FloatRegFile * p) : parent(p) {;} + double & operator [] (RegIndex index) + { + //Double floats are index by the single + //precision register the start on, + //and only 32 should be accessed + index = (index >> 1) & 0x1F; + return ((double *)parent->rawRegs)[index]; + } + }; + class SingleRegs { - private: - //By using the largest data type, we ensure everything - //is aligned correctly in memory - union - { - double double rawRegs[16]; - uint64_t regDump[32]; - }; - class QuadRegs - { - private: - FloatRegFile * parent; - public: - QuadRegs(FloatRegFile * p) : parent(p) {;} - double double & operator [] (RegIndex index) - { - //Quad floats are index by the single - //precision register the start on, - //and only 16 should be accessed - index = (index >> 2) & 0xF; - return parent->rawRegs[index]; - } - }; - class DoubleRegs - { - private: - FloatRegFile * parent; - public: - DoubleRegs(FloatRegFile * p) : parent(p) {;} - double & operator [] (RegIndex index) - { - //Double floats are index by the single - //precision register the start on, - //and only 32 should be accessed - index = (index >> 1) & 0x1F - return ((double [])parent->rawRegs)[index]; - } - } - class SingleRegs - { - private: - FloatRegFile * parent; - public: - SingleRegs(FloatRegFile * p) : parent(p) {;} - double & operator [] (RegFile index) - { - //Only 32 single floats should be accessed - index &= 0x1F - return ((float [])parent->rawRegs)[index]; - } - } - public: - void inline serialize(std::ostream & os) - { - SERIALIZE_ARRAY(regDump, 32); - } - - void inline unserialize(Checkpoint &* cp, std::string & section) - { - UNSERIALIZE_ARRAY(regDump, 32); - } - - QuadRegs quadRegs; - DoubleRegs doubleRegs; - SingleRegs singleRegs; - FloatRegFile() : quadRegs(this), doubleRegs(this), singleRegs(this) - {;} + private: + FloatRegFile * parent; + public: + SingleRegs(FloatRegFile * p) : parent(p) {;} + float & operator [] (RegIndex index) + { + //Only 32 single floats should be accessed + index &= 0x1F; + return ((float *)parent->rawRegs)[index]; + } }; - - // control register file contents - typedef uint64_t MiscReg; - // The control registers, broken out into fields - class MiscRegFile + public: + void serialize(std::ostream & os); + + void unserialize(Checkpoint * cp, std::string & section); + + QuadRegs quadRegs; + DoubleRegs doubleRegs; + SingleRegs singleRegs; + FloatRegFile() : quadRegs(this), doubleRegs(this), singleRegs(this) + {;} + }; + + // control register file contents + typedef uint64_t MiscReg; + // The control registers, broken out into fields + class MiscRegFile + { + public: + union { - public: - union - { - uint16_t pstate; // Process State Register - struct - { - uint16_t ag:1; // Alternate Globals - 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 red:1; // RED (reset, error, debug) state - uint16_t mm:2; // Memory Model - uint16_t tle:1; // Trap little-endian - uint16_t cle:1; // Current little-endian - } pstateFields; - } - uint64_t tba; // Trap Base Address - union - { - uint64_t y; // Y (used in obsolete multiplication) - struct - { - uint64_t value:32; // The actual value stored in y - const uint64_t :32; // reserved bits - } yFields; - } - uint8_t pil; // Process Interrupt Register - uint8_t cwp; // Current Window Pointer - uint16_t tt[MaxTL]; // Trap Type (Type of trap which occured on the previous level) - 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:4; - } :4; - 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:4; - } :4; - } ccrFields; - } - uint8_t asi; // Address Space Identifier - uint8_t tl; // Trap Level - 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 - const uint64_t :2; // Reserved bits - uint64_t pstate:10; // Process State - const uint64_t :6; // Reserved bits - uint64_t asi:8; // Address Space Identifier - uint64_t ccr:8; // Condition Code Register - } tstateFields[MaxTL]; - } + uint16_t pstate; // Process State Register + struct + { + uint16_t ag:1; // Alternate Globals + 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 red:1; // RED (reset, error, debug) state + uint16_t mm:2; // Memory Model + uint16_t tle:1; // Trap little-endian + uint16_t cle:1; // Current little-endian + } pstateFields; + }; + uint64_t tba; // Trap Base Address + union + { + uint64_t y; // Y (used in obsolete multiplication) + struct + { + uint64_t value:32; // The actual value stored in y + const uint64_t :32; // reserved bits + } yFields; + }; + uint8_t pil; // Process Interrupt Register + uint8_t cwp; // Current Window Pointer + uint16_t tt[MaxTL]; // Trap Type (Type of trap which occured + // on the previous level) + union + { + uint8_t ccr; // Condition Code Register + struct + { union { - uint64_t tick; // Hardware clock-tick counter - struct - { - uint64_t counter:63; // Clock-tick count - uint64_t npt:1; // Non-priveleged trap - } tickFields; - } - uint8_t cansave; // Savable windows - uint8_t canrestore; // Restorable windows - uint8_t otherwin; // Other windows - uint8_t cleanwin; // Clean windows + 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:4; + } :4; 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 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:4; + } :4; + } ccrFields; + }; + uint8_t asi; // Address Space Identifier + uint8_t tl; // Trap Level + 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 + const uint64_t :2; // Reserved bits + uint64_t pstate:10; // Process State + const uint64_t :6; // Reserved bits + uint64_t asi:8; // Address Space Identifier + uint64_t ccr:8; // Condition Code Register + } tstateFields[MaxTL]; + }; + union + { + uint64_t tick; // Hardware clock-tick counter + struct + { + uint64_t counter:63; // Clock-tick count + uint64_t npt:1; // Non-priveleged trap + } tickFields; + } + uint8_t cansave; // Savable windows + uint8_t canrestore; // Restorable windows + uint8_t otherwin; // Other windows + uint8_t cleanwin; // Clean 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; + }; + union + { + uint64_t ver; // Version + struct + { + uint64_t maxwin:5; // Max CWP value + const uint64_t :2; // Reserved bits + uint64_t maxtl:8; // Maximum trap level + const uint64_t :8; // Reserved bits + uint64_t mask:8; // Processor mask set revision number + uint64_t impl:16; // Implementation identification number + uint64_t manuf:16; // Manufacturer code + } verFields; + }; + union + { + uint64_t fsr; // Floating-Point State Register + struct + { union { - uint64_t ver; // Version - struct - { - uint64_t maxwin:5; // Max CWP value - const uint64_t :2; // Reserved bits - uint64_t maxtl:8; // Maximum trap level - const uint64_t :8; // Reserved bits - uint64_t mask:8; // Processor mask set revision number - uint64_t impl:16; // Implementation identification number - uint64_t manuf:16; // Manufacturer code - } verFields; - } + 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 + } cexecFields:5; + } :5; 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 - } cexecFields:5; - } :5; - 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 - } aexecFields:5; - } :5; - uint64_t fcc0:2; // Floating-Point condtion codes - const 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) - const 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:5; - } :5; - const 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 - const uint64_t :26; // Reserved bits - } fsrFields; - } + 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 + } aexecFields:5; + } :5; + uint64_t fcc0:2; // Floating-Point condtion codes + const 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) + const uint64_t :2; // Reserved bits + uint64_t ns:1; // Nonstandard floating point union { - uint8_t fprs; // Floating-Point Register State - struct - { - dl:1; // Dirty lower - du:1; // Dirty upper - fef:1; // FPRS enable floating-Point - } fprsFields; - }; - - void serialize(std::ostream & os) - { - SERIALIZE_SCALAR(pstate); - SERIAlIZE_SCALAR(tba); - SERIALIZE_SCALAR(y); - SERIALIZE_SCALAR(pil); - SERIALIZE_SCALAR(cwp); - SERIALIZE_ARRAY(tt, MaxTL); - SERIALIZE_SCALAR(ccr); - SERIALIZE_SCALAR(asi); - SERIALIZE_SCALAR(tl); - SERIALIZE_SCALAR(tpc); - SERIALIZE_SCALAR(tnpc); - SERIALIZE_ARRAY(tstate, MaxTL); - SERIALIZE_SCALAR(tick); - SERIALIZE_SCALAR(cansave); - SERIALIZE_SCALAR(canrestore); - SERIALIZE_SCALAR(otherwin); - SERIALIZE_SCALAR(cleanwin); - SERIALIZE_SCALAR(wstate); - SERIALIZE_SCALAR(ver); - SERIALIZE_SCALAR(fsr); - SERIALIZE_SCALAR(fprs); - } - - void unserialize(Checkpoint &* cp, std::string & section) - { - UNSERIALIZE_SCALAR(pstate); - UNSERIAlIZE_SCALAR(tba); - UNSERIALIZE_SCALAR(y); - UNSERIALIZE_SCALAR(pil); - UNSERIALIZE_SCALAR(cwp); - UNSERIALIZE_ARRAY(tt, MaxTL); - UNSERIALIZE_SCALAR(ccr); - UNSERIALIZE_SCALAR(asi); - UNSERIALIZE_SCALAR(tl); - UNSERIALIZE_SCALAR(tpc); - UNSERIALIZE_SCALAR(tnpc); - UNSERIALIZE_ARRAY(tstate, MaxTL); - UNSERIALIZE_SCALAR(tick); - UNSERIALIZE_SCALAR(cansave); - UNSERIALIZE_SCALAR(canrestore); - UNSERIALIZE_SCALAR(otherwin); - UNSERIALIZE_SCALAR(cleanwin); - UNSERIALIZE_SCALAR(wstate); - UNSERIALIZE_SCALAR(ver); - UNSERIALIZE_SCALAR(fsr); - UNSERIALIZE_SCALAR(fprs); - } - }; - - typedef union - { - IntReg intreg; - FloatReg fpreg; - MiscReg ctrlreg; - } AnyReg; - - struct RegFile + 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:5; + } :5; + const 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 + const uint64_t :26; // Reserved bits + } fsrFields; + } + union { - IntRegFile intRegFile; // (signed) integer register file - FloatRegFile floatRegFile; // floating point register file - MiscRegFile miscRegFile; // control register file - - Addr pc; // Program Counter - Addr npc; // Next Program Counter - - void serialize(std::ostream &os); - void unserialize(Checkpoint *cp, const std::string §ion); + uint8_t fprs; // Floating-Point Register State + struct + { + uint8_t dl:1; // Dirty lower + uint8_t du:1; // Dirty upper + fef:1; // FPRS enable floating-Point + } fprsFields; }; - static StaticInstPtr<AlphaISA> decodeInst(MachInst); - - // return a no-op instruction... used for instruction fetch faults - static const MachInst NoopMachInst; - - // Instruction address compression hooks - static inline Addr realPCToFetchPC(const Addr &addr) + void serialize(std::ostream & os) { - return addr; + SERIALIZE_SCALAR(pstate); + SERIAlIZE_SCALAR(tba); + SERIALIZE_SCALAR(y); + SERIALIZE_SCALAR(pil); + SERIALIZE_SCALAR(cwp); + SERIALIZE_ARRAY(tt, MaxTL); + SERIALIZE_SCALAR(ccr); + SERIALIZE_SCALAR(asi); + SERIALIZE_SCALAR(tl); + SERIALIZE_SCALAR(tpc); + SERIALIZE_SCALAR(tnpc); + SERIALIZE_ARRAY(tstate, MaxTL); + SERIALIZE_SCALAR(tick); + SERIALIZE_SCALAR(cansave); + SERIALIZE_SCALAR(canrestore); + SERIALIZE_SCALAR(otherwin); + SERIALIZE_SCALAR(cleanwin); + SERIALIZE_SCALAR(wstate); + SERIALIZE_SCALAR(ver); + SERIALIZE_SCALAR(fsr); + SERIALIZE_SCALAR(fprs); } - static inline Addr fetchPCToRealPC(const Addr &addr) + void unserialize(Checkpoint &* cp, std::string & section) { - return addr; + UNSERIALIZE_SCALAR(pstate); + UNSERIAlIZE_SCALAR(tba); + UNSERIALIZE_SCALAR(y); + UNSERIALIZE_SCALAR(pil); + UNSERIALIZE_SCALAR(cwp); + UNSERIALIZE_ARRAY(tt, MaxTL); + UNSERIALIZE_SCALAR(ccr); + UNSERIALIZE_SCALAR(asi); + UNSERIALIZE_SCALAR(tl); + UNSERIALIZE_SCALAR(tpc); + UNSERIALIZE_SCALAR(tnpc); + UNSERIALIZE_ARRAY(tstate, MaxTL); + UNSERIALIZE_SCALAR(tick); + UNSERIALIZE_SCALAR(cansave); + UNSERIALIZE_SCALAR(canrestore); + UNSERIALIZE_SCALAR(otherwin); + UNSERIALIZE_SCALAR(cleanwin); + UNSERIALIZE_SCALAR(wstate); + UNSERIALIZE_SCALAR(ver); + UNSERIALIZE_SCALAR(fsr); + UNSERIALIZE_SCALAR(fprs); } - - // the size of "fetched" instructions (not necessarily the size - // of real instructions for PISA) - static inline size_t fetchInstSize() - { - return sizeof(MachInst); - } - - /** - * Function to insure ISA semantics about 0 registers. - * @param xc The execution context. - */ - template <class XC> - static void zeroRegisters(XC *xc); + }; + + typedef union + { + IntReg intreg; + FloatReg fpreg; + MiscReg ctrlreg; + } AnyReg; + + struct RegFile + { + IntRegFile intRegFile; // (signed) integer register file + FloatRegFile floatRegFile; // floating point register file + MiscRegFile miscRegFile; // control register file + + Addr pc; // Program Counter + Addr npc; // Next Program Counter + + void serialize(std::ostream &os); + void unserialize(Checkpoint *cp, const std::string §ion); + }; + + static StaticInstPtr decodeInst(MachInst); + + // return a no-op instruction... used for instruction fetch faults + static const MachInst NoopMachInst; + + // 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); + } + + /** + * Function to insure ISA semantics about 0 registers. + * @param xc The execution context. + */ + template <class XC> + static void zeroRegisters(XC *xc); }; - -typedef SPARCISA TheISA; - -typedef TheISA::MachInst MachInst; -typedef TheISA::Addr Addr; -typedef TheISA::RegIndex RegIndex; -typedef TheISA::IntReg IntReg; -typedef TheISA::IntRegFile IntRegFile; -typedef TheISA::FloatReg FloatReg; -typedef TheISA::FloatRegFile FloatRegFile; -typedef TheISA::MiscReg MiscReg; -typedef TheISA::MiscRegFile MiscRegFile; -typedef TheISA::AnyReg AnyReg; -typedef TheISA::RegFile RegFile; - const int VMPageSize = TheISA::VMPageSize; const int LogVMPageSize = TheISA::LogVMPageSize; const int ZeroReg = TheISA::ZeroReg; const int BranchPredAddrShiftAmt = TheISA::BranchPredAddrShiftAmt; const int MaxAddr = (Addr)-1; -#ifndef 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; +#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 -#ifdef FULL_SYSTEM +#if FULL_SYSTEM #include "arch/alpha/ev5.hh" #endif diff --git a/arch/sparc/linux_process.cc b/arch/sparc/linux/process.cc index d1c439d72..ebfbb2f64 100644 --- a/arch/sparc/linux_process.cc +++ b/arch/sparc/linux/process.cc @@ -27,7 +27,7 @@ */ #include "arch/sparc/common_syscall_emul.hh" -#include "arch/sparc/linux_process.hh" +#include "arch/sparc/linux/process.hh" #include "arch/sparc/isa_traits.hh" #include "base/trace.hh" diff --git a/arch/sparc/linux_process.hh b/arch/sparc/linux/process.hh index c41406b4b..c41406b4b 100644 --- a/arch/sparc/linux_process.hh +++ b/arch/sparc/linux/process.hh diff --git a/arch/sparc/process.hh b/arch/sparc/process.hh index 387649d47..48041a316 100644 --- a/arch/sparc/process.hh +++ b/arch/sparc/process.hh @@ -29,7 +29,7 @@ #ifndef __SPARC_PROCESS_HH__ #define __SPARC_PROCESS_HH__ -#include "arch/sparc/linux_process.hh" +#include "arch/sparc/linux/process.hh" #include "base/loader/object_file.hh" namespace SparcISA |