diff options
Diffstat (limited to 'src/arch/mips')
39 files changed, 6897 insertions, 0 deletions
diff --git a/src/arch/mips/SConscript b/src/arch/mips/SConscript new file mode 100644 index 000000000..6295a6c11 --- /dev/null +++ b/src/arch/mips/SConscript @@ -0,0 +1,84 @@ +# -*- mode:python -*- + +# Copyright (c) 2004-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 +# Steve Reinhardt +# Korey Sewell + +import os +import sys +from os.path import isdir + +# Import build environment variable from SConstruct. +Import('env') + +################################################### +# +# Define needed sources. +# +################################################### + +# Base sources used by all configurations. +base_sources = Split(''' + faults.cc + isa_traits.cc + utility.cc + ''') + +# Full-system sources +full_system_sources = Split(''' + memory.cc + mips34k.cc + ''') + +# Syscall emulation (non-full-system) sources +syscall_emulation_sources = Split(''' + linux/linux.cc + linux/process.cc + process.cc + ''') + +# Set up complete list of sources based on configuration. +sources = base_sources + +if env['FULL_SYSTEM']: + sources += full_system_sources +else: + sources += syscall_emulation_sources + +# Convert file names to SCons File objects. This takes care of the +# path relative to the top of the directory tree. +sources = [File(s) for s in sources] + +# Add in files generated by the ISA description. +isa_desc_files = env.ISADesc('isa/main.isa') +# Only non-header files need to be compiled. +isa_desc_sources = [f for f in isa_desc_files if not f.path.endswith('.hh')] +sources += isa_desc_sources + +Return('sources') diff --git a/src/arch/mips/faults.cc b/src/arch/mips/faults.cc new file mode 100644 index 000000000..810c3fed4 --- /dev/null +++ b/src/arch/mips/faults.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: Korey Sewell + */ + +#include "arch/mips/faults.hh" +#include "cpu/thread_context.hh" +#include "cpu/base.hh" +#include "base/trace.hh" + +namespace MipsISA +{ + +FaultName MachineCheckFault::_name = "Machine Check"; +FaultVect MachineCheckFault::_vect = 0x0401; +FaultStat MachineCheckFault::_count; + +FaultName AlignmentFault::_name = "Alignment"; +FaultVect AlignmentFault::_vect = 0x0301; +FaultStat AlignmentFault::_count; + +FaultName ResetFault::_name = "reset"; +FaultVect ResetFault::_vect = 0x0001; +FaultStat ResetFault::_count; + +FaultName ArithmeticFault::_name = "arith"; +FaultVect ArithmeticFault::_vect = 0x0501; +FaultStat ArithmeticFault::_count; + +FaultName InterruptFault::_name = "interrupt"; +FaultVect InterruptFault::_vect = 0x0101; +FaultStat InterruptFault::_count; + +FaultName NDtbMissFault::_name = "dtb_miss_single"; +FaultVect NDtbMissFault::_vect = 0x0201; +FaultStat NDtbMissFault::_count; + +FaultName PDtbMissFault::_name = "dtb_miss_double"; +FaultVect PDtbMissFault::_vect = 0x0281; +FaultStat PDtbMissFault::_count; + +FaultName DtbPageFault::_name = "dfault"; +FaultVect DtbPageFault::_vect = 0x0381; +FaultStat DtbPageFault::_count; + +FaultName DtbAcvFault::_name = "dfault"; +FaultVect DtbAcvFault::_vect = 0x0381; +FaultStat DtbAcvFault::_count; + +FaultName ItbMissFault::_name = "itbmiss"; +FaultVect ItbMissFault::_vect = 0x0181; +FaultStat ItbMissFault::_count; + +FaultName ItbPageFault::_name = "itbmiss"; +FaultVect ItbPageFault::_vect = 0x0181; +FaultStat ItbPageFault::_count; + +FaultName ItbAcvFault::_name = "iaccvio"; +FaultVect ItbAcvFault::_vect = 0x0081; +FaultStat ItbAcvFault::_count; + +FaultName UnimplementedOpcodeFault::_name = "opdec"; +FaultVect UnimplementedOpcodeFault::_vect = 0x0481; +FaultStat UnimplementedOpcodeFault::_count; + +FaultName FloatEnableFault::_name = "fen"; +FaultVect FloatEnableFault::_vect = 0x0581; +FaultStat FloatEnableFault::_count; + +FaultName PalFault::_name = "pal"; +FaultVect PalFault::_vect = 0x2001; +FaultStat PalFault::_count; + +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!"); +} + +#endif + +} // namespace MipsISA + diff --git a/src/arch/mips/faults.hh b/src/arch/mips/faults.hh new file mode 100644 index 000000000..d8bf59cc1 --- /dev/null +++ b/src/arch/mips/faults.hh @@ -0,0 +1,271 @@ +/* + * 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: Korey Sewell + */ + +#ifndef __MIPS_FAULTS_HH__ +#define __MIPS_FAULTS_HH__ + +#include "sim/faults.hh" + +// The design of the "name" and "vect" functions is in sim/faults.hh + +namespace MipsISA +{ + +typedef const Addr FaultVect; + +class MipsFault : public FaultBase +{ + protected: + virtual bool skipFaultingInstruction() {return false;} + virtual bool setRestartAddress() {return true;} + public: +#if FULL_SYSTEM + void invoke(ThreadContext * tc); +#endif + virtual FaultVect vect() = 0; + virtual FaultStat & countStat() = 0; +}; + +class MachineCheckFault : public MipsFault +{ + private: + static FaultName _name; + static FaultVect _vect; + static FaultStat _count; + public: + FaultName name() {return _name;} + FaultVect vect() {return _vect;} + FaultStat & countStat() {return _count;} + bool isMachineCheckFault() {return true;} +}; + +class AlignmentFault : public MipsFault +{ + private: + static FaultName _name; + static FaultVect _vect; + static FaultStat _count; + public: + FaultName name() {return _name;} + FaultVect vect() {return _vect;} + FaultStat & countStat() {return _count;} + bool isAlignmentFault() {return true;} +}; + +static inline Fault genMachineCheckFault() +{ + return new MachineCheckFault; +} + +static inline Fault genAlignmentFault() +{ + return new AlignmentFault; +} + +class ResetFault : public MipsFault +{ + private: + static FaultName _name; + static FaultVect _vect; + static FaultStat _count; + public: + FaultName name() {return _name;} + FaultVect vect() {return _vect;} + FaultStat & countStat() {return _count;} +}; + +class ArithmeticFault : public MipsFault +{ + protected: + bool skipFaultingInstruction() {return true;} + private: + static FaultName _name; + static FaultVect _vect; + static FaultStat _count; + public: + FaultName name() {return _name;} + FaultVect vect() {return _vect;} + FaultStat & countStat() {return _count;} +#if FULL_SYSTEM + void invoke(ThreadContext * tc); +#endif +}; + +class InterruptFault : public MipsFault +{ + protected: + bool setRestartAddress() {return false;} + private: + static FaultName _name; + static FaultVect _vect; + static FaultStat _count; + public: + FaultName name() {return _name;} + FaultVect vect() {return _vect;} + FaultStat & countStat() {return _count;} +}; + +class NDtbMissFault : public MipsFault +{ + private: + static FaultName _name; + static FaultVect _vect; + static FaultStat _count; + public: + FaultName name() {return _name;} + FaultVect vect() {return _vect;} + FaultStat & countStat() {return _count;} +}; + +class PDtbMissFault : public MipsFault +{ + private: + static FaultName _name; + static FaultVect _vect; + static FaultStat _count; + public: + FaultName name() {return _name;} + FaultVect vect() {return _vect;} + FaultStat & countStat() {return _count;} +}; + +class DtbPageFault : public MipsFault +{ + private: + static FaultName _name; + static FaultVect _vect; + static FaultStat _count; + public: + FaultName name() {return _name;} + FaultVect vect() {return _vect;} + FaultStat & countStat() {return _count;} +}; + +class DtbAcvFault : public MipsFault +{ + private: + static FaultName _name; + static FaultVect _vect; + static FaultStat _count; + public: + FaultName name() {return _name;} + FaultVect vect() {return _vect;} + FaultStat & countStat() {return _count;} +}; + +class ItbMissFault : public MipsFault +{ + private: + static FaultName _name; + static FaultVect _vect; + static FaultStat _count; + public: + FaultName name() {return _name;} + FaultVect vect() {return _vect;} + FaultStat & countStat() {return _count;} +}; + +class ItbPageFault : public MipsFault +{ + private: + static FaultName _name; + static FaultVect _vect; + static FaultStat _count; + public: + FaultName name() {return _name;} + FaultVect vect() {return _vect;} + FaultStat & countStat() {return _count;} +}; + +class ItbAcvFault : public MipsFault +{ + private: + static FaultName _name; + static FaultVect _vect; + static FaultStat _count; + public: + FaultName name() {return _name;} + FaultVect vect() {return _vect;} + FaultStat & countStat() {return _count;} +}; + +class UnimplementedOpcodeFault : public MipsFault +{ + private: + static FaultName _name; + static FaultVect _vect; + static FaultStat _count; + public: + FaultName name() {return _name;} + FaultVect vect() {return _vect;} + FaultStat & countStat() {return _count;} +}; + +class FloatEnableFault : public MipsFault +{ + private: + static FaultName _name; + static FaultVect _vect; + static FaultStat _count; + public: + FaultName name() {return _name;} + FaultVect vect() {return _vect;} + FaultStat & countStat() {return _count;} +}; + +class PalFault : public MipsFault +{ + protected: + bool skipFaultingInstruction() {return true;} + private: + static FaultName _name; + static FaultVect _vect; + static FaultStat _count; + public: + FaultName name() {return _name;} + FaultVect vect() {return _vect;} + FaultStat & countStat() {return _count;} +}; + +class IntegerOverflowFault : public MipsFault +{ + private: + static FaultName _name; + static FaultVect _vect; + static FaultStat _count; + public: + FaultName name() {return _name;} + FaultVect vect() {return _vect;} + FaultStat & countStat() {return _count;} +}; + +} // MipsISA namespace + +#endif // __FAULTS_HH__ diff --git a/src/arch/mips/isa/base.isa b/src/arch/mips/isa/base.isa new file mode 100644 index 000000000..b733da7da --- /dev/null +++ b/src/arch/mips/isa/base.isa @@ -0,0 +1,106 @@ +// -*- mode:c++ -*- + +// Copyright (c) 2003-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 + +//////////////////////////////////////////////////////////////////// +// +// Base class for MIPS instructions, and some support functions +// + +//Outputs to decoder.hh +output header {{ + + using namespace MipsISA; + + + /** + * Base class for all MIPS static instructions. + */ + class MipsStaticInst : public StaticInst + { + protected: + + // Constructor + MipsStaticInst(const char *mnem, MachInst _machInst, OpClass __opClass) + : StaticInst(mnem, _machInst, __opClass) + { + } + + /// Print a register name for disassembly given the unique + /// dependence tag number (FP or int). + void printReg(std::ostream &os, int reg) const; + + std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; + }; + +}}; + +//Ouputs to decoder.cc +output decoder {{ + + void MipsStaticInst::printReg(std::ostream &os, int reg) const + { + if (reg < FP_Base_DepTag) { + ccprintf(os, "r%d", reg); + } + else { + ccprintf(os, "f%d", reg - FP_Base_DepTag); + } + } + + std::string MipsStaticInst::generateDisassembly(Addr pc, const SymbolTable *symtab) const + { + std::stringstream ss; + + ccprintf(ss, "%-10s ", mnemonic); + + if(_numDestRegs > 0){ + printReg(ss, _destRegIdx[0]); + } + + if(_numSrcRegs > 0) { + ss << ", "; + printReg(ss, _srcRegIdx[0]); + } + + if(_numSrcRegs > 1) { + ss << ", "; + printReg(ss, _srcRegIdx[1]); + } + + + if(mnemonic == "sll" || mnemonic == "sra"){ + ccprintf(ss,", %d",SA); + } + + return ss.str(); + } + +}}; + diff --git a/src/arch/mips/isa/bitfields.isa b/src/arch/mips/isa/bitfields.isa new file mode 100644 index 000000000..e8d4578c7 --- /dev/null +++ b/src/arch/mips/isa/bitfields.isa @@ -0,0 +1,102 @@ +// -*- mode:c++ -*- + +// Copyright (c) 2003-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 + +//////////////////////////////////////////////////////////////////// +// +// Bitfield definitions. +// + +def bitfield OPCODE <31:26>; +def bitfield OPCODE_HI <31:29>; +def bitfield OPCODE_LO <28:26>; + +def bitfield REGIMM <20:16>; +def bitfield REGIMM_HI <20:19>; +def bitfield REGIMM_LO <18:16>; + +def bitfield FUNCTION < 5: 0>; +def bitfield FUNCTION_HI < 5: 3>; +def bitfield FUNCTION_LO < 2: 0>; + +def bitfield RS <25:21>; +def bitfield RS_MSB <25:25>; +def bitfield RS_HI <25:24>; +def bitfield RS_LO <23:21>; +def bitfield RS_SRL <25:22>; +def bitfield RS_RT <25:16>; +def bitfield RT <20:16>; +def bitfield RT_HI <20:19>; +def bitfield RT_LO <18:16>; +def bitfield RT_RD <20:11>; +def bitfield RD <15:11>; + +def bitfield INTIMM <15: 0>; + +// Floating-point operate format +def bitfield FMT <25:21>; +def bitfield FR <25:21>; +def bitfield FT <20:16>; +def bitfield FS <15:11>; +def bitfield FD <10:6>; + +def bitfield ND <17:17>; +def bitfield TF <16:16>; +def bitfield MOVCI <16:16>; +def bitfield MOVCF <16:16>; +def bitfield SRL <21:21>; +def bitfield SRLV < 6: 6>; +def bitfield SA <10: 6>; + +// Floating Point Condition Codes +def bitfield CC <10:8>; +def bitfield BRANCH_CC <20:18>; + +// CP0 Register Select +def bitfield SEL < 2: 0>; + +// Interrupts +def bitfield SC < 5: 5>; + +// Branch format +def bitfield OFFSET <15: 0>; // displacement + +// Jmp format +def bitfield JMPTARG <25: 0>; +def bitfield HINT <10: 6>; + +def bitfield SYSCALLCODE <25: 6>; +def bitfield TRAPCODE <15:13>; + +// EXT/INS instructions +def bitfield MSB <15:11>; +def bitfield LSB <10: 6>; + +// M5 instructions +def bitfield M5FUNC <7:0>; diff --git a/src/arch/mips/isa/decoder.isa b/src/arch/mips/isa/decoder.isa new file mode 100644 index 000000000..a64f74c4f --- /dev/null +++ b/src/arch/mips/isa/decoder.isa @@ -0,0 +1,1095 @@ +// -*- mode:c++ -*- + +// Copyright (c) 2003-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 + +//////////////////////////////////////////////////////////////////// +// +// The actual MIPS32 ISA decoder +// ----------------------------- +// The following instructions are specified in the MIPS32 ISA +// Specification. Decoding closely follows the style specified +// in the MIPS32 ISA specification document starting with Table +// A-2 (document available @ www.mips.com) +// +decode OPCODE_HI default Unknown::unknown() { + //Table A-2 + 0x0: decode OPCODE_LO { + 0x0: decode FUNCTION_HI { + 0x0: decode FUNCTION_LO { + 0x1: decode MOVCI { + format BasicOp { + 0: movf({{ Rd = (getCondCode(FCSR, CC) == 0) ? Rd : Rs; }}); + 1: movt({{ Rd = (getCondCode(FCSR, CC) == 1) ? Rd : Rs; }}); + } + } + + format BasicOp { + //Table A-3 Note: "Specific encodings of the rd, rs, and + //rt fields are used to distinguish SLL, SSNOP, and EHB + //functions + 0x0: decode RS { + 0x0: decode RT_RD { + 0x0: decode SA default Nop::nop(){ + 0x1: WarnUnimpl::ssnop(); + 0x3: WarnUnimpl::ehb(); + } + default: sll({{ Rd = Rt.uw << SA; }}); + } + } + + 0x2: decode RS_SRL { + 0x0:decode SRL { + 0: srl({{ Rd = Rt.uw >> SA; }}); + + //Hardcoded assuming 32-bit ISA, probably need parameter here + 1: rotr({{ Rd = (Rt.uw << (32 - SA)) | (Rt.uw >> SA);}}); + } + } + + 0x3: decode RS { + 0x0: sra({{ + uint32_t temp = Rt >> SA; + if ( (Rt & 0x80000000) > 0 ) { + uint32_t mask = 0x80000000; + for(int i=0; i < SA; i++) { + temp |= mask; + mask = mask >> 1; + } + } + Rd = temp; + }}); + } + + 0x4: sllv({{ Rd = Rt.uw << Rs<4:0>; }}); + + 0x6: decode SRLV { + 0: srlv({{ Rd = Rt.uw >> Rs<4:0>; }}); + + //Hardcoded assuming 32-bit ISA, probably need parameter here + 1: rotrv({{ Rd = (Rt.uw << (32 - Rs<4:0>)) | (Rt.uw >> Rs<4:0>);}}); + } + + 0x7: srav({{ + int shift_amt = Rs<4:0>; + + uint32_t temp = Rt >> shift_amt; + + if ( (Rt & 0x80000000) > 0 ) { + uint32_t mask = 0x80000000; + for(int i=0; i < shift_amt; i++) { + temp |= mask; + mask = mask >> 1; + } + } + + Rd = temp; + }}); + } + } + + 0x1: decode FUNCTION_LO { + //Table A-3 Note: "Specific encodings of the hint field are + //used to distinguish JR from JR.HB and JALR from JALR.HB" + format Jump { + 0x0: decode HINT { + 0x1: jr_hb({{ NNPC = Rs & ~1; }}, IsReturn, ClearHazards); + default: jr({{ NNPC = Rs & ~1; }}, IsReturn); + } + + 0x1: decode HINT { + 0x1: jalr_hb({{ Rd = NNPC; NNPC = Rs; }}, IsCall, Link + , ClearHazards); + default: jalr({{ Rd = NNPC; NNPC = Rs; }}, IsCall, + Link); + } + } + + format BasicOp { + 0x2: movz({{ Rd = (Rt == 0) ? Rs : Rd; }}); + 0x3: movn({{ Rd = (Rt != 0) ? Rs : Rd; }}); + 0x4: syscall({{ xc->syscall(R2); }}, IsNonSpeculative); + 0x7: sync({{ ; }}, IsMemBarrier); + } + + format FailUnimpl { + 0x5: break(); + } + } + + 0x2: decode FUNCTION_LO { + format HiLoMiscOp { + 0x0: mfhi({{ Rd = HI; }}); + 0x1: mthi({{ HI = Rs; }}); + 0x2: mflo({{ Rd = LO; }}); + 0x3: mtlo({{ LO = Rs; }}); + } + } + + 0x3: decode FUNCTION_LO { + format HiLoOp { + 0x0: mult({{ val = Rs.sd * Rt.sd; }}); + 0x1: multu({{ val = Rs.ud * Rt.ud; }}); + } + + format HiLoMiscOp { + 0x2: div({{ + HI = Rs.sd % Rt.sd; + LO = Rs.sd / Rt.sd; + }}); + 0x3: divu({{ + HI = Rs.ud % Rt.ud; + LO = Rs.ud / Rt.ud; + }}); + } + } + + 0x4: decode HINT { + 0x0: decode FUNCTION_LO { + format IntOp { + 0x0: add({{ Rd.sw = Rs.sw + Rt.sw; /*Trap on Overflow*/}}); + 0x1: addu({{ Rd.sw = Rs.sw + Rt.sw;}}); + 0x2: sub({{ Rd.sw = Rs.sw - Rt.sw; /*Trap on Overflow*/}}); + 0x3: subu({{ Rd.sw = Rs.sw - Rt.sw;}}); + 0x4: and({{ Rd = Rs & Rt;}}); + 0x5: or({{ Rd = Rs | Rt;}}); + 0x6: xor({{ Rd = Rs ^ Rt;}}); + 0x7: nor({{ Rd = ~(Rs | Rt);}}); + } + } + } + + 0x5: decode HINT { + 0x0: decode FUNCTION_LO { + format IntOp{ + 0x2: slt({{ Rd.sw = ( Rs.sw < Rt.sw ) ? 1 : 0}}); + 0x3: sltu({{ Rd.uw = ( Rs.uw < Rt.uw ) ? 1 : 0}}); + } + } + } + + 0x6: decode FUNCTION_LO { + format Trap { + 0x0: tge({{ cond = (Rs.sw >= Rt.sw); }}); + 0x1: tgeu({{ cond = (Rs.uw >= Rt.uw); }}); + 0x2: tlt({{ cond = (Rs.sw < Rt.sw); }}); + 0x3: tltu({{ cond = (Rs.uw >= Rt.uw); }}); + 0x4: teq({{ cond = (Rs.sw == Rt.sw); }}); + 0x6: tne({{ cond = (Rs.sw != Rt.sw); }}); + } + } + } + + 0x1: decode REGIMM_HI { + 0x0: decode REGIMM_LO { + format Branch { + 0x0: bltz({{ cond = (Rs.sw < 0); }}); + 0x1: bgez({{ cond = (Rs.sw >= 0); }}); + 0x2: bltzl({{ cond = (Rs.sw < 0); }}, Likely); + 0x3: bgezl({{ cond = (Rs.sw >= 0); }}, Likely); + } + } + + 0x1: decode REGIMM_LO { + format Trap { + 0x0: tgei( {{ cond = (Rs.sw >= INTIMM); }}); + 0x1: tgeiu({{ cond = (Rs.uw >= INTIMM); }}); + 0x2: tlti( {{ cond = (Rs.sw < INTIMM); }}); + 0x3: tltiu({{ cond = (Rs.uw < INTIMM); }}); + 0x4: teqi( {{ cond = (Rs.sw == INTIMM);}}); + 0x6: tnei( {{ cond = (Rs.sw != INTIMM);}}); + } + } + + 0x2: decode REGIMM_LO { + format Branch { + 0x0: bltzal({{ cond = (Rs.sw < 0); }}, Link); + 0x1: decode RS { + 0x0: bal ({{ cond = 1; }}, IsCall, Link); + default: bgezal({{ cond = (Rs.sw >= 0); }}, Link); + } + 0x2: bltzall({{ cond = (Rs.sw < 0); }}, Link, Likely); + 0x3: bgezall({{ cond = (Rs.sw >= 0); }}, Link, Likely); + } + } + + 0x3: decode REGIMM_LO { + format WarnUnimpl { + 0x7: synci(); + } + } + } + + format Jump { + 0x2: j({{ NNPC = (NPC & 0xF0000000) | (JMPTARG << 2);}}); + 0x3: jal({{ NNPC = (NPC & 0xF0000000) | (JMPTARG << 2); }}, IsCall, + Link); + } + + format Branch { + 0x4: decode RS_RT { + 0x0: b({{ cond = 1; }}); + default: beq({{ cond = (Rs.sw == Rt.sw); }}); + } + 0x5: bne({{ cond = (Rs.sw != Rt.sw); }}); + 0x6: blez({{ cond = (Rs.sw <= 0); }}); + 0x7: bgtz({{ cond = (Rs.sw > 0); }}); + } + } + + 0x1: decode OPCODE_LO { + format IntImmOp { + 0x0: addi({{ Rt.sw = Rs.sw + imm; /*Trap If Overflow*/}}); + 0x1: addiu({{ Rt.sw = Rs.sw + imm;}}); + 0x2: slti({{ Rt.sw = ( Rs.sw < imm) ? 1 : 0 }}); + 0x3: sltiu({{ Rt.uw = ( Rs.uw < (uint32_t)sextImm ) ? 1 : 0 }}); + 0x4: andi({{ Rt.sw = Rs.sw & zextImm;}}); + 0x5: ori({{ Rt.sw = Rs.sw | zextImm;}}); + 0x6: xori({{ Rt.sw = Rs.sw ^ zextImm;}}); + + 0x7: decode RS { + 0x0: lui({{ Rt = imm << 16}}); + } + } + } + + 0x2: decode OPCODE_LO { + //Table A-11 MIPS32 COP0 Encoding of rs Field + 0x0: decode RS_MSB { + 0x0: decode RS { + format CP0Control { + 0x0: mfc0({{ Rt = xc->readMiscReg(RD << 5 | SEL); }}); + 0x4: mtc0({{ xc->setMiscReg(RD << 5 | SEL, Rt); }}); + } + + format MipsMT { + 0x8: mftr(); + 0xC: mttr(); + 0xB: decode RD { + 0x0: decode SC { + 0x0: dvpe(); + 0x1: evpe(); + } + 0x1: decode SC { + 0x0: dmt(); + 0x1: emt(); + 0xC: decode SC { + 0x0: di(); + 0x1: ei(); + } + } + } + } + + format FailUnimpl { + 0xA: rdpgpr(); + 0xE: wrpgpr(); + } + } + + //Table A-12 MIPS32 COP0 Encoding of Function Field When rs=CO + 0x1: decode FUNCTION { + format FailUnimpl { + 0x01: tlbr(); + 0x02: tlbwi(); + 0x06: tlbwr(); + 0x08: tlbp(); + + 0x18: eret(); + 0x1F: deret(); + 0x20: wait(); + } + } + } + + //Table A-13 MIPS32 COP1 Encoding of rs Field + 0x1: decode RS_MSB { + + 0x0: decode RS_HI { + 0x0: decode RS_LO { + format CP1Control { + 0x0: mfc1 ({{ Rt.uw = Fs.uw<31:0>; }}); + + 0x2: cfc1({{ + switch (FS) + { + case 0: + Rt = FIR; + break; + case 25: + Rt = 0 | (FCSR & 0xFE000000) >> 24 | (FCSR & 0x00800000) >> 23; + break; + case 26: + Rt = 0 | (FCSR & 0x0003F07C); + break; + case 28: + Rt = 0 | (FCSR & 0x00000F80) | (FCSR & 0x01000000) >> 21 | (FCSR & 0x00000003); + break; + case 31: + Rt = FCSR; + break; + default: + panic("FP Control Value (%d) Not Valid"); + } + }}); + + 0x3: mfhc1({{ Rt.uw = Fs.ud<63:32>;}}); + + 0x4: mtc1 ({{ Fs.uw = Rt.uw; }}); + + 0x6: ctc1({{ + switch (FS) + { + case 25: + FCSR = 0 | (Rt.uw<7:1> << 25) // move 31...25 + | (FCSR & 0x01000000) // bit 24 + | (FCSR & 0x004FFFFF);// bit 22...0 + break; + + case 26: + FCSR = 0 | (FCSR & 0xFFFC0000) // move 31...18 + | Rt.uw<17:12> << 12 // bit 17...12 + | (FCSR & 0x00000F80) << 7// bit 11...7 + | Rt.uw<6:2> << 2 // bit 6...2 + | (FCSR & 0x00000002); // bit 1...0 + break; + + case 28: + FCSR = 0 | (FCSR & 0xFE000000) // move 31...25 + | Rt.uw<2:2> << 24 // bit 24 + | (FCSR & 0x00FFF000) << 23// bit 23...12 + | Rt.uw<11:7> << 7 // bit 24 + | (FCSR & 0x000007E) + | Rt.uw<1:0>;// bit 22...0 + break; + + case 31: + FCSR = Rt.uw; + break; + + default: + panic("FP Control Value (%d) Not Available. Ignoring Access to" + "Floating Control Status Register", FS); + } + }}); + + 0x7: mthc1({{ + uint64_t fs_hi = Rt.uw; + uint64_t fs_lo = Fs.ud & 0x0FFFFFFFF; + Fs.ud = (fs_hi << 32) | fs_lo; + }}); + + } + } + + 0x1: decode ND { + format Branch { + 0x0: decode TF { + 0x0: bc1f({{ cond = getCondCode(FCSR, BRANCH_CC) == 0; + }}); + 0x1: bc1t({{ cond = getCondCode(FCSR, BRANCH_CC) == 1; + }}); + } + 0x1: decode TF { + 0x0: bc1fl({{ cond = getCondCode(FCSR, BRANCH_CC) == 0; + }}, Likely); + 0x1: bc1tl({{ cond = getCondCode(FCSR, BRANCH_CC) == 1; + }}, Likely); + } + } + } + } + + 0x1: decode RS_HI { + 0x2: decode RS_LO { + //Table A-14 MIPS32 COP1 Encoding of Function Field When rs=S + //(( single-precision floating point)) + 0x0: decode FUNCTION_HI { + 0x0: decode FUNCTION_LO { + format FloatOp { + 0x0: add_s({{ Fd.sf = Fs.sf + Ft.sf;}}); + 0x1: sub_s({{ Fd.sf = Fs.sf - Ft.sf;}}); + 0x2: mul_s({{ Fd.sf = Fs.sf * Ft.sf;}}); + 0x3: div_s({{ Fd.sf = Fs.sf / Ft.sf;}}); + 0x4: sqrt_s({{ Fd.sf = sqrt(Fs.sf);}}); + 0x5: abs_s({{ Fd.sf = fabs(Fs.sf);}}); + 0x6: mov_s({{ Fd.sf = Fs.sf;}}); + 0x7: neg_s({{ Fd.sf = -Fs.sf;}}); + } + } + + 0x1: decode FUNCTION_LO { + format FloatConvertOp { + 0x0: round_l_s({{ val = Fs.sf; }}, ToLong, + Round); + 0x1: trunc_l_s({{ val = Fs.sf; }}, ToLong, + Trunc); + 0x2: ceil_l_s({{ val = Fs.sf; }}, ToLong, + Ceil); + 0x3: floor_l_s({{ val = Fs.sf; }}, ToLong, + Floor); + 0x4: round_w_s({{ val = Fs.sf; }}, ToWord, + Round); + 0x5: trunc_w_s({{ val = Fs.sf; }}, ToWord, + Trunc); + 0x6: ceil_w_s({{ val = Fs.sf; }}, ToWord, + Ceil); + 0x7: floor_w_s({{ val = Fs.sf; }}, ToWord, + Floor); + } + } + + 0x2: decode FUNCTION_LO { + 0x1: decode MOVCF { + format BasicOp { + 0x0: movf_s({{ Fd = (getCondCode(FCSR,CC) == 0) ? Fs : Fd; }}); + 0x1: movt_s({{ Fd = (getCondCode(FCSR,CC) == 1) ? Fs : Fd; }}); + } + } + + format BasicOp { + 0x2: movz_s({{ Fd = (Rt == 0) ? Fs : Fd; }}); + 0x3: movn_s({{ Fd = (Rt != 0) ? Fs : Fd; }}); + } + + format FloatOp { + 0x5: recip_s({{ Fd = 1 / Fs; }}); + 0x6: rsqrt_s({{ Fd = 1 / sqrt(Fs);}}); + } + } + + 0x4: decode FUNCTION_LO { + format FloatConvertOp { + 0x1: cvt_d_s({{ val = Fs.sf; }}, ToDouble); + 0x4: cvt_w_s({{ val = Fs.sf; }}, ToWord); + 0x5: cvt_l_s({{ val = Fs.sf; }}, ToLong); + } + + 0x6: FloatOp::cvt_ps_s({{ + Fd.ud = (uint64_t) Fs.uw << 32 | + (uint64_t) Ft.uw; + }}); + } + + 0x6: decode FUNCTION_LO { + format FloatCompareOp { + 0x0: c_f_s({{ cond = 0; }}, SinglePrecision, + UnorderedFalse); + 0x1: c_un_s({{ cond = 0; }}, SinglePrecision, + UnorderedTrue); + 0x2: c_eq_s({{ cond = (Fs.sf == Ft.sf); }}, + UnorderedFalse); + 0x3: c_ueq_s({{ cond = (Fs.sf == Ft.sf); }}, + UnorderedTrue); + 0x4: c_olt_s({{ cond = (Fs.sf < Ft.sf); }}, + UnorderedFalse); + 0x5: c_ult_s({{ cond = (Fs.sf < Ft.sf); }}, + UnorderedTrue); + 0x6: c_ole_s({{ cond = (Fs.sf <= Ft.sf); }}, + UnorderedFalse); + 0x7: c_ule_s({{ cond = (Fs.sf <= Ft.sf); }}, + UnorderedTrue); + } + } + + 0x7: decode FUNCTION_LO { + format FloatCompareOp { + 0x0: c_sf_s({{ cond = 0; }}, SinglePrecision, + UnorderedFalse, QnanException); + 0x1: c_ngle_s({{ cond = 0; }}, SinglePrecision, + UnorderedTrue, QnanException); + 0x2: c_seq_s({{ cond = (Fs.sf == Ft.sf);}}, + UnorderedFalse, QnanException); + 0x3: c_ngl_s({{ cond = (Fs.sf == Ft.sf); }}, + UnorderedTrue, QnanException); + 0x4: c_lt_s({{ cond = (Fs.sf < Ft.sf); }}, + UnorderedFalse, QnanException); + 0x5: c_nge_s({{ cond = (Fs.sf < Ft.sf); }}, + UnorderedTrue, QnanException); + 0x6: c_le_s({{ cond = (Fs.sf <= Ft.sf); }}, + UnorderedFalse, QnanException); + 0x7: c_ngt_s({{ cond = (Fs.sf <= Ft.sf); }}, + UnorderedTrue, QnanException); + } + } + } + + //Table A-15 MIPS32 COP1 Encoding of Function Field When rs=D + 0x1: decode FUNCTION_HI { + 0x0: decode FUNCTION_LO { + format FloatOp { + 0x0: add_d({{ Fd.df = Fs.df + Ft.df; }}); + 0x1: sub_d({{ Fd.df = Fs.df - Ft.df; }}); + 0x2: mul_d({{ Fd.df = Fs.df * Ft.df; }}); + 0x3: div_d({{ Fd.df = Fs.df / Ft.df; }}); + 0x4: sqrt_d({{ Fd.df = sqrt(Fs.df); }}); + 0x5: abs_d({{ Fd.df = fabs(Fs.df); }}); + 0x6: mov_d({{ Fd.df = Fs.df; }}); + 0x7: neg_d({{ Fd.df = -1 * Fs.df; }}); + } + } + + 0x1: decode FUNCTION_LO { + format FloatConvertOp { + 0x0: round_l_d({{ val = Fs.df; }}, ToLong, + Round); + 0x1: trunc_l_d({{ val = Fs.df; }}, ToLong, + Trunc); + 0x2: ceil_l_d({{ val = Fs.df; }}, ToLong, + Ceil); + 0x3: floor_l_d({{ val = Fs.df; }}, ToLong, + Floor); + 0x4: round_w_d({{ val = Fs.df; }}, ToWord, + Round); + 0x5: trunc_w_d({{ val = Fs.df; }}, ToWord, + Trunc); + 0x6: ceil_w_d({{ val = Fs.df; }}, ToWord, + Ceil); + 0x7: floor_w_d({{ val = Fs.df; }}, ToWord, + Floor); + } + } + + 0x2: decode FUNCTION_LO { + 0x1: decode MOVCF { + format BasicOp { + 0x0: movf_d({{ Fd.df = (getCondCode(FCSR,CC) == 0) ? + Fs.df : Fd.df; + }}); + 0x1: movt_d({{ Fd.df = (getCondCode(FCSR,CC) == 1) ? + Fs.df : Fd.df; + }}); + } + } + + format BasicOp { + 0x2: movz_d({{ Fd.df = (Rt == 0) ? Fs.df : Fd.df; }}); + 0x3: movn_d({{ Fd.df = (Rt != 0) ? Fs.df : Fd.df; }}); + } + + format FloatOp { + 0x5: recip_d({{ Fd.df = 1 / Fs.df }}); + 0x6: rsqrt_d({{ Fd.df = 1 / sqrt(Fs.df) }}); + } + } + + 0x4: decode FUNCTION_LO { + format FloatConvertOp { + 0x0: cvt_s_d({{ val = Fs.df; }}, ToSingle); + 0x4: cvt_w_d({{ val = Fs.df; }}, ToWord); + 0x5: cvt_l_d({{ val = Fs.df; }}, ToLong); + } + } + + 0x6: decode FUNCTION_LO { + format FloatCompareOp { + 0x0: c_f_d({{ cond = 0; }}, DoublePrecision, + UnorderedFalse); + 0x1: c_un_d({{ cond = 0; }}, DoublePrecision, + UnorderedTrue); + 0x2: c_eq_d({{ cond = (Fs.df == Ft.df); }}, + UnorderedFalse); + 0x3: c_ueq_d({{ cond = (Fs.df == Ft.df); }}, + UnorderedTrue); + 0x4: c_olt_d({{ cond = (Fs.df < Ft.df); }}, + UnorderedFalse); + 0x5: c_ult_d({{ cond = (Fs.df < Ft.df); }}, + UnorderedTrue); + 0x6: c_ole_d({{ cond = (Fs.df <= Ft.df); }}, + UnorderedFalse); + 0x7: c_ule_d({{ cond = (Fs.df <= Ft.df); }}, + UnorderedTrue); + } + } + + 0x7: decode FUNCTION_LO { + format FloatCompareOp { + 0x0: c_sf_d({{ cond = 0; }}, DoublePrecision, + UnorderedFalse, QnanException); + 0x1: c_ngle_d({{ cond = 0; }}, DoublePrecision, + UnorderedTrue, QnanException); + 0x2: c_seq_d({{ cond = (Fs.df == Ft.df); }}, + UnorderedFalse, QnanException); + 0x3: c_ngl_d({{ cond = (Fs.df == Ft.df); }}, + UnorderedTrue, QnanException); + 0x4: c_lt_d({{ cond = (Fs.df < Ft.df); }}, + UnorderedFalse, QnanException); + 0x5: c_nge_d({{ cond = (Fs.df < Ft.df); }}, + UnorderedTrue, QnanException); + 0x6: c_le_d({{ cond = (Fs.df <= Ft.df); }}, + UnorderedFalse, QnanException); + 0x7: c_ngt_d({{ cond = (Fs.df <= Ft.df); }}, + UnorderedTrue, QnanException); + } + } + } + + //Table A-16 MIPS32 COP1 Encoding of Function Field When rs=W + 0x4: decode FUNCTION { + format FloatConvertOp { + 0x20: cvt_s_w({{ val = Fs.uw; }}, ToSingle); + 0x21: cvt_d_w({{ val = Fs.uw; }}, ToDouble); + 0x26: FailUnimpl::cvt_ps_w(); + } + } + + //Table A-16 MIPS32 COP1 Encoding of Function Field When rs=L1 + //Note: "1. Format type L is legal only if 64-bit floating point operations + //are enabled." + 0x5: decode FUNCTION_HI { + format FloatConvertOp { + 0x20: cvt_s_l({{ val = Fs.ud; }}, ToSingle); + 0x21: cvt_d_l({{ val = Fs.ud; }}, ToDouble); + 0x26: FailUnimpl::cvt_ps_l(); + } + } + + //Table A-17 MIPS64 COP1 Encoding of Function Field When rs=PS1 + //Note: "1. Format type PS is legal only if 64-bit floating point operations + //are enabled. " + 0x6: decode FUNCTION_HI { + 0x0: decode FUNCTION_LO { + format Float64Op { + 0x0: add_ps({{ + Fd1.sf = Fs1.sf + Ft2.sf; + Fd2.sf = Fs2.sf + Ft2.sf; + }}); + 0x1: sub_ps({{ + Fd1.sf = Fs1.sf - Ft2.sf; + Fd2.sf = Fs2.sf - Ft2.sf; + }}); + 0x2: mul_ps({{ + Fd1.sf = Fs1.sf * Ft2.sf; + Fd2.sf = Fs2.sf * Ft2.sf; + }}); + 0x5: abs_ps({{ + Fd1.sf = fabs(Fs1.sf); + Fd2.sf = fabs(Fs2.sf); + }}); + 0x6: mov_ps({{ + Fd1.sf = Fs1.sf; + Fd2.sf = Fs2.sf; + }}); + 0x7: neg_ps({{ + Fd1.sf = -(Fs1.sf); + Fd2.sf = -(Fs2.sf); + }}); + } + } + + 0x2: decode FUNCTION_LO { + 0x1: decode MOVCF { + format Float64Op { + 0x0: movf_ps({{ + Fd1 = (getCondCode(FCSR, CC) == 0) ? + Fs1 : Fd1; + Fd2 = (getCondCode(FCSR, CC+1) == 0) ? + Fs2 : Fd2; + }}); + 0x1: movt_ps({{ + Fd2 = (getCondCode(FCSR, CC) == 1) ? + Fs1 : Fd1; + Fd2 = (getCondCode(FCSR, CC+1) == 1) ? + Fs2 : Fd2; + }}); + } + } + + format Float64Op { + 0x2: movz_ps({{ + Fd1 = (getCondCode(FCSR, CC) == 0) ? + Fs1 : Fd1; + Fd2 = (getCondCode(FCSR, CC) == 0) ? + Fs2 : Fd2; + }}); + 0x3: movn_ps({{ + Fd1 = (getCondCode(FCSR, CC) == 1) ? + Fs1 : Fd1; + Fd2 = (getCondCode(FCSR, CC) == 1) ? + Fs2 : Fd2; + }}); + } + + } + + 0x4: decode FUNCTION_LO { + 0x0: FloatOp::cvt_s_pu({{ Fd.sf = Fs2.sf; }}); + } + + 0x5: decode FUNCTION_LO { + 0x0: FloatOp::cvt_s_pl({{ Fd.sf = Fs1.sf; }}); + + format Float64Op { + 0x4: pll({{ Fd.ud = (uint64_t) Fs1.uw << 32 | + Ft1.uw; + }}); + 0x5: plu({{ Fd.ud = (uint64_t) Fs1.uw << 32 | + Ft2.uw; + }}); + 0x6: pul({{ Fd.ud = (uint64_t) Fs2.uw << 32 | + Ft1.uw; + }}); + 0x7: puu({{ Fd.ud = (uint64_t) Fs2.uw << 32 | + Ft2.uw; + }}); + } + } + + 0x6: decode FUNCTION_LO { + format FloatPSCompareOp { + 0x0: c_f_ps({{ cond1 = 0; }}, {{ cond2 = 0; }}, + UnorderedFalse); + 0x1: c_un_ps({{ cond1 = 0; }}, {{ cond2 = 0; }}, + UnorderedTrue); + 0x2: c_eq_ps({{ cond1 = (Fs1.sf == Ft1.sf); }}, + {{ cond2 = (Fs2.sf == Ft2.sf); }}, + UnorderedFalse); + 0x3: c_ueq_ps({{ cond1 = (Fs1.sf == Ft1.sf); }}, + {{ cond2 = (Fs2.sf == Ft2.sf); }}, + UnorderedTrue); + 0x4: c_olt_ps({{ cond1 = (Fs1.sf < Ft1.sf); }}, + {{ cond2 = (Fs2.sf < Ft2.sf); }}, + UnorderedFalse); + 0x5: c_ult_ps({{ cond1 = (Fs.sf < Ft.sf); }}, + {{ cond2 = (Fs2.sf < Ft2.sf); }}, + UnorderedTrue); + 0x6: c_ole_ps({{ cond1 = (Fs.sf <= Ft.sf); }}, + {{ cond2 = (Fs2.sf <= Ft2.sf); }}, + UnorderedFalse); + 0x7: c_ule_ps({{ cond1 = (Fs1.sf <= Ft1.sf); }}, + {{ cond2 = (Fs2.sf <= Ft2.sf); }}, + UnorderedTrue); + } + } + + 0x7: decode FUNCTION_LO { + format FloatPSCompareOp { + 0x0: c_sf_ps({{ cond1 = 0; }}, {{ cond2 = 0; }}, + UnorderedFalse, QnanException); + 0x1: c_ngle_ps({{ cond1 = 0; }}, + {{ cond2 = 0; }}, + UnorderedTrue, QnanException); + 0x2: c_seq_ps({{ cond1 = (Fs1.sf == Ft1.sf); }}, + {{ cond2 = (Fs2.sf == Ft2.sf); }}, + UnorderedFalse, QnanException); + 0x3: c_ngl_ps({{ cond1 = (Fs1.sf == Ft1.sf); }}, + {{ cond2 = (Fs2.sf == Ft2.sf); }}, + UnorderedTrue, QnanException); + 0x4: c_lt_ps({{ cond1 = (Fs1.sf < Ft1.sf); }}, + {{ cond2 = (Fs2.sf < Ft2.sf); }}, + UnorderedFalse, QnanException); + 0x5: c_nge_ps({{ cond1 = (Fs1.sf < Ft1.sf); }}, + {{ cond2 = (Fs2.sf < Ft2.sf); }}, + UnorderedTrue, QnanException); + 0x6: c_le_ps({{ cond1 = (Fs1.sf <= Ft1.sf); }}, + {{ cond2 = (Fs2.sf <= Ft2.sf); }}, + UnorderedFalse, QnanException); + 0x7: c_ngt_ps({{ cond1 = (Fs1.sf <= Ft1.sf); }}, + {{ cond2 = (Fs2.sf <= Ft2.sf); }}, + UnorderedTrue, QnanException); + } + } + } + } + } + } + + //Table A-19 MIPS32 COP2 Encoding of rs Field + 0x2: decode RS_MSB { + format FailUnimpl { + 0x0: decode RS_HI { + 0x0: decode RS_LO { + 0x0: mfc2(); + 0x2: cfc2(); + 0x3: mfhc2(); + 0x4: mtc2(); + 0x6: ctc2(); + 0x7: mftc2(); + } + + 0x1: decode ND { + 0x0: decode TF { + 0x0: bc2f(); + 0x1: bc2t(); + } + + 0x1: decode TF { + 0x0: bc2fl(); + 0x1: bc2tl(); + } + } + } + } + } + + //Table A-20 MIPS64 COP1X Encoding of Function Field 1 + //Note: "COP1X instructions are legal only if 64-bit floating point + //operations are enabled." + 0x3: decode FUNCTION_HI { + 0x0: decode FUNCTION_LO { + format LoadIndexedMemory { + 0x0: lwxc1({{ Ft.uw = Mem.uw;}}); + 0x1: ldxc1({{ Ft.ud = Mem.ud;}}); + 0x5: luxc1({{ Ft.uw = Mem.ud;}}); + } + } + + 0x1: decode FUNCTION_LO { + format StoreIndexedMemory { + 0x0: swxc1({{ Mem.uw = Ft.uw;}}); + 0x1: sdxc1({{ Mem.ud = Ft.ud;}}); + 0x5: suxc1({{ Mem.ud = Ft.ud;}}); + } + + 0x7: Prefetch::prefx({{ EA = Rs + Rt; }}); + } + + 0x3: decode FUNCTION_LO { + 0x6: Float64Op::alnv_ps({{ if (Rs<2:0> == 0) { + Fd.ud = Fs.ud; + } else if (Rs<2:0> == 4) { + #if BYTE_ORDER == BIG_ENDIAN + Fd.ud = Fs.ud<31:0> << 32 | + Ft.ud<63:32>; + #elif BYTE_ORDER == LITTLE_ENDIAN + Fd.ud = Ft.ud<31:0> << 32 | + Fs.ud<63:32>; + #endif + } else { + Fd.ud = Fd.ud; + } + }}); + } + + format FloatAccOp { + 0x4: decode FUNCTION_LO { + 0x0: madd_s({{ Fd.sf = (Fs.sf * Ft.sf) + Fr.sf; }}); + 0x1: madd_d({{ Fd.df = (Fs.df * Ft.df) + Fr.df; }}); + 0x6: madd_ps({{ + Fd1.sf = (Fs1.df * Ft1.df) + Fr1.df; + Fd2.sf = (Fs2.df * Ft2.df) + Fr2.df; + }}); + } + + 0x5: decode FUNCTION_LO { + 0x0: msub_s({{ Fd.sf = (Fs.sf * Ft.sf) - Fr.sf; }}); + 0x1: msub_d({{ Fd.df = (Fs.df * Ft.df) - Fr.df; }}); + 0x6: msub_ps({{ + Fd1.sf = (Fs1.df * Ft1.df) - Fr1.df; + Fd2.sf = (Fs2.df * Ft2.df) - Fr2.df; + }}); + } + + 0x6: decode FUNCTION_LO { + 0x0: nmadd_s({{ Fd.sf = (-1 * Fs.sf * Ft.sf) - Fr.sf; }}); + 0x1: nmadd_d({{ Fd.df = (-1 * Fs.df * Ft.df) + Fr.df; }}); + 0x6: nmadd_ps({{ + Fd1.sf = -((Fs1.df * Ft1.df) + Fr1.df); + Fd2.sf = -((Fs2.df * Ft2.df) + Fr2.df); + }}); + } + + 0x7: decode FUNCTION_LO { + 0x0: nmsub_s({{ Fd.sf = (-1 * Fs.sf * Ft.sf) - Fr.sf; }}); + 0x1: nmsub_d({{ Fd.df = (-1 * Fs.df * Ft.df) - Fr.df; }}); + 0x6: nmsub_ps({{ + Fd1.sf = -((Fs1.df * Ft1.df) - Fr1.df); + Fd2.sf = -((Fs2.df * Ft2.df) - Fr2.df); + }}); + } + + } + } + + format Branch { + 0x4: beql({{ cond = (Rs.sw == Rt.sw); }}, Likely); + 0x5: bnel({{ cond = (Rs.sw != Rt.sw); }}, Likely); + 0x6: blezl({{ cond = (Rs.sw <= 0); }}, Likely); + 0x7: bgtzl({{ cond = (Rs.sw > 0); }}, Likely); + } + } + + 0x3: decode OPCODE_LO { + //Table A-5 MIPS32 SPECIAL2 Encoding of Function Field + 0x4: decode FUNCTION_HI { + 0x0: decode FUNCTION_LO { + 0x2: IntOp::mul({{ int64_t temp1 = Rs.sd * Rt.sd; + Rd.sw = temp1<31:0> + }}); + + format HiLoOp { + 0x0: madd({{ val = ((int64_t) HI << 32 | LO) + + (Rs.sd * Rt.sd); + }}); + 0x1: maddu({{ val = ((uint64_t) HI << 32 | LO) + + (Rs.ud * Rt.ud); + }}); + 0x4: msub({{ val = ((int64_t) HI << 32 | LO) - + (Rs.sd * Rt.sd); + }}); + 0x5: msubu({{ val = ((uint64_t) HI << 32 | LO) - + (Rs.ud * Rt.ud); + }}); + } + } + + 0x4: decode FUNCTION_LO { + format BasicOp { + 0x0: clz({{ int cnt = 32; + for (int idx = 31; idx >= 0; idx--) { + if( Rs<idx:idx> == 1) { + cnt = 31 - idx; + break; + } + } + Rd.uw = cnt; + }}); + 0x1: clo({{ int cnt = 32; + for (int idx = 31; idx >= 0; idx--) { + if( Rs<idx:idx> == 0) { + cnt = 31 - idx; + break; + } + } + Rd.uw = cnt; + }}); + } + } + + 0x7: decode FUNCTION_LO { + 0x7: FailUnimpl::sdbbp(); + } + } + + //Table A-6 MIPS32 SPECIAL3 Encoding of Function Field for Release 2 + //of the Architecture + 0x7: decode FUNCTION_HI { + 0x0: decode FUNCTION_LO { + format BasicOp { + 0x1: ext({{ Rt.uw = bits(Rs.uw, MSB+LSB, LSB); }}); + 0x4: ins({{ Rt.uw = bits(Rt.uw, 31, MSB+1) << (MSB+1) | + bits(Rs.uw, MSB-LSB, 0) << LSB | + bits(Rt.uw, LSB-1, 0); + }}); + } + } + + 0x1: decode FUNCTION_LO { + format MipsMT { + 0x0: fork(); + 0x1: yield(); + } + } + + //Table A-10 MIPS32 BSHFL Encoding of sa Field + 0x4: decode SA { + format BasicOp { + 0x02: wsbh({{ Rd.uw = Rt.uw<23:16> << 24 | + Rt.uw<31:24> << 16 | + Rt.uw<7:0> << 8 | + Rt.uw<15:8>; + }}); + 0x10: seb({{ Rd.sw = Rt.sw<7:0>}}); + 0x18: seh({{ Rd.sw = Rt.sw<15:0>}}); + } + } + + 0x6: decode FUNCTION_LO { + 0x7: FailUnimpl::rdhwr(); + } + } + } + + 0x4: decode OPCODE_LO { + format LoadMemory { + 0x0: lb({{ Rt.sw = Mem.sb; }}); + 0x1: lh({{ Rt.sw = Mem.sh; }}); + 0x3: lw({{ Rt.sw = Mem.sw; }}); + 0x4: lbu({{ Rt.uw = Mem.ub; }}); + 0x5: lhu({{ Rt.uw = Mem.uh; }}); + } + + format LoadUnalignedMemory { + 0x2: lwl({{ uint32_t mem_shift = 24 - (8 * byte_offset); + Rt.uw = mem_word << mem_shift | + Rt.uw & mask(mem_shift); + }}); + 0x6: lwr({{ uint32_t mem_shift = 8 * byte_offset; + Rt.uw = Rt.uw & (mask(mem_shift) << (32 - mem_shift)) | + mem_word >> mem_shift; + }}); + } + } + + 0x5: decode OPCODE_LO { + format StoreMemory { + 0x0: sb({{ Mem.ub = Rt<7:0>; }}); + 0x1: sh({{ Mem.uh = Rt<15:0>; }}); + 0x3: sw({{ Mem.uw = Rt<31:0>; }}); + } + + format StoreUnalignedMemory { + 0x2: swl({{ uint32_t reg_shift = 24 - (8 * byte_offset); + uint32_t mem_shift = 32 - reg_shift; + mem_word = mem_word & (mask(reg_shift) << mem_shift) | + Rt.uw >> reg_shift; + }}); + 0x6: swr({{ uint32_t reg_shift = 8 * byte_offset; + mem_word = Rt.uw << reg_shift | + mem_word & (mask(reg_shift)); + }}); + } + + 0x7: FailUnimpl::cache(); + } + + 0x6: decode OPCODE_LO { + format LoadMemory { + 0x0: ll({{ Rt.uw = Mem.uw; }}, mem_flags=LOCKED); + 0x1: lwc1({{ Ft.uw = Mem.uw; }}); + 0x5: ldc1({{ Ft.ud = Mem.ud; }}); + } + + 0x3: Prefetch::pref(); + } + + + 0x7: decode OPCODE_LO { + 0x0: StoreCond::sc({{ Mem.uw = Rt.uw;}}, + {{ uint64_t tmp = write_result; + Rt.uw = (tmp == 0 || tmp == 1) ? tmp : Rt.uw; + }}, mem_flags=LOCKED); + + format StoreMemory { + 0x1: swc1({{ Mem.uw = Ft.uw; }}); + 0x5: sdc1({{ Mem.ud = Ft.ud; }}); + } + } +} + + diff --git a/src/arch/mips/isa/formats/basic.isa b/src/arch/mips/isa/formats/basic.isa new file mode 100644 index 000000000..35ce09205 --- /dev/null +++ b/src/arch/mips/isa/formats/basic.isa @@ -0,0 +1,95 @@ +// -*- mode:c++ -*- + +// Copyright (c) 2003-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 + +// Declarations for execute() methods. +def template BasicExecDeclare {{ + Fault execute(%(CPU_exec_context)s *, Trace::InstRecord *) const; +}}; + +// Basic instruction class declaration template. +def template BasicDeclare {{ + /** + * Static instruction class for "%(mnemonic)s". + */ + class %(class_name)s : public %(base_class)s + { + public: + /// Constructor. + %(class_name)s(MachInst machInst); + %(BasicExecDeclare)s + }; +}}; + +// Basic instruction class constructor template. +def template BasicConstructor {{ + inline %(class_name)s::%(class_name)s(MachInst machInst) : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s) + { + %(constructor)s; + } +}}; + + +// Basic instruction class execute method template. +def template BasicExecute {{ + Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const + { + Fault fault = NoFault; + + %(fp_enable_check)s; + %(op_decl)s; + %(op_rd)s; + %(code)s; + + if(fault == NoFault) + { + %(op_wb)s; + } + return fault; + } +}}; + +// Basic decode template. +def template BasicDecode {{ + return new %(class_name)s(machInst); +}}; + +// Basic decode template, passing mnemonic in as string arg to constructor. +def template BasicDecodeWithMnemonic {{ + return new %(class_name)s("%(mnemonic)s", machInst); +}}; + +// The most basic instruction format... used only for a few misc. insts +def format BasicOp(code, *flags) {{ + iop = InstObjParams(name, Name, 'MipsStaticInst', CodeBlock(code), flags) + header_output = BasicDeclare.subst(iop) + decoder_output = BasicConstructor.subst(iop) + decode_block = BasicDecode.subst(iop) + exec_output = BasicExecute.subst(iop) +}}; diff --git a/src/arch/mips/isa/formats/branch.isa b/src/arch/mips/isa/formats/branch.isa new file mode 100644 index 000000000..827e3ccf0 --- /dev/null +++ b/src/arch/mips/isa/formats/branch.isa @@ -0,0 +1,278 @@ +// -*- mode:c++ -*- + +// Copyright (c) 2003-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 + +//////////////////////////////////////////////////////////////////// +// +// Control transfer instructions +// + +output header {{ + +#include <iostream> + using namespace std; + + /** + * Base class for instructions whose disassembly is not purely a + * function of the machine instruction (i.e., it depends on the + * PC). This class overrides the disassemble() method to check + * the PC and symbol table values before re-using a cached + * disassembly string. This is necessary for branches and jumps, + * where the disassembly string includes the target address (which + * may depend on the PC and/or symbol table). + */ + class PCDependentDisassembly : public MipsStaticInst + { + protected: + /// Cached program counter from last disassembly + mutable Addr cachedPC; + + /// Cached symbol table pointer from last disassembly + mutable const SymbolTable *cachedSymtab; + + /// Constructor + PCDependentDisassembly(const char *mnem, MachInst _machInst, + OpClass __opClass) + : MipsStaticInst(mnem, _machInst, __opClass), + cachedPC(0), cachedSymtab(0) + { + } + + const std::string & + disassemble(Addr pc, const SymbolTable *symtab) const; + }; + + /** + * Base class for branches (PC-relative control transfers), + * conditional or unconditional. + */ + class Branch : public PCDependentDisassembly + { + protected: + /// target address (signed) Displacement . + int32_t disp; + + /// Constructor. + Branch(const char *mnem, MachInst _machInst, OpClass __opClass) + : PCDependentDisassembly(mnem, _machInst, __opClass), + disp(OFFSET << 2) + { + //If Bit 17 is 1 then Sign Extend + if ( (disp & 0x00020000) > 0 ) { + disp |= 0xFFFE0000; + } + } + + Addr branchTarget(Addr branchPC) const; + + std::string + generateDisassembly(Addr pc, const SymbolTable *symtab) const; + }; + + /** + * Base class for jumps (register-indirect control transfers). In + * the Mips ISA, these are always unconditional. + */ + class Jump : public PCDependentDisassembly + { + protected: + + /// Displacement to target address (signed). + int32_t disp; + + uint32_t target; + + public: + /// Constructor + Jump(const char *mnem, MachInst _machInst, OpClass __opClass) + : PCDependentDisassembly(mnem, _machInst, __opClass), + disp(JMPTARG << 2) + { + } + + Addr branchTarget(ThreadContext *tc) const; + + std::string + generateDisassembly(Addr pc, const SymbolTable *symtab) const; + }; +}}; + +output decoder {{ + Addr + Branch::branchTarget(Addr branchPC) const + { + return branchPC + 4 + disp; + } + + Addr + Jump::branchTarget(ThreadContext *tc) const + { + Addr NPC = tc->readPC() + 4; + uint64_t Rb = tc->readIntReg(_srcRegIdx[0]); + return (Rb & ~3) | (NPC & 1); + } + + const std::string & + PCDependentDisassembly::disassemble(Addr pc, + const SymbolTable *symtab) const + { + if (!cachedDisassembly || + pc != cachedPC || symtab != cachedSymtab) + { + if (cachedDisassembly) + delete cachedDisassembly; + + cachedDisassembly = + new std::string(generateDisassembly(pc, symtab)); + cachedPC = pc; + cachedSymtab = symtab; + } + + return *cachedDisassembly; + } + + std::string + Branch::generateDisassembly(Addr pc, const SymbolTable *symtab) const + { + std::stringstream ss; + + ccprintf(ss, "%-10s ", mnemonic); + + // There's only one register arg (RA), but it could be + // either a source (the condition for conditional + // branches) or a destination (the link reg for + // unconditional branches) + if (_numSrcRegs == 1) { + printReg(ss, _srcRegIdx[0]); + ss << ", "; + } else if(_numSrcRegs == 2) { + printReg(ss, _srcRegIdx[0]); + ss << ", "; + printReg(ss, _srcRegIdx[1]); + ss << ", "; + } + + Addr target = pc + 4 + disp; + + std::string str; + if (symtab && symtab->findSymbol(target, str)) + ss << str; + else + ccprintf(ss, "0x%x", target); + + return ss.str(); + } + + std::string + Jump::generateDisassembly(Addr pc, const SymbolTable *symtab) const + { + std::stringstream ss; + + ccprintf(ss, "%-10s ", mnemonic); + + if ( mnemonic == "jal" ) { + Addr npc = pc + 4; + ccprintf(ss,"0x%x",(npc & 0xF0000000) | disp); + } else if (_numSrcRegs == 0) { + std::string str; + if (symtab && symtab->findSymbol(disp, str)) + ss << str; + else + ccprintf(ss, "0x%x", disp); + } else if (_numSrcRegs == 1) { + printReg(ss, _srcRegIdx[0]); + } else if(_numSrcRegs == 2) { + printReg(ss, _srcRegIdx[0]); + ss << ", "; + printReg(ss, _srcRegIdx[1]); + } + + return ss.str(); + } +}}; + +def format Branch(code,*opt_flags) {{ + not_taken_code = ' NNPC = NNPC;\n' + not_taken_code += '} \n' + + #Build Instruction Flags + #Use Link & Likely Flags to Add Link/Condition Code + inst_flags = ('IsDirectControl', ) + for x in opt_flags: + if x == 'Link': + code += 'R31 = NNPC;\n' + elif x == 'Likely': + not_taken_code = ' NPC = NNPC;\n' + not_taken_code += ' NNPC = NNPC + 4;\n' + not_taken_code += '} \n' + inst_flags = ('IsCondDelaySlot', ) + else: + inst_flags += (x, ) + + if 'cond == 1' in code: + inst_flags += ('IsCondControl', ) + else: + inst_flags += ('IsUncondControl', ) + + #Condition code + code = 'bool cond;\n' + code + code += 'if (cond) {\n' + code += ' NNPC = NPC + disp;\n' + code += '} else {\n' + code += not_taken_code + + iop = InstObjParams(name, Name, 'Branch', CodeBlock(code), inst_flags) + header_output = BasicDeclare.subst(iop) + decoder_output = BasicConstructor.subst(iop) + decode_block = BasicDecode.subst(iop) + exec_output = BasicExecute.subst(iop) +}}; + +def format Jump(code, *opt_flags) {{ + #Build Instruction Flags + #Use Link Flag to Add Link Code + inst_flags = ('IsIndirectControl', 'IsUncondControl') + for x in opt_flags: + if x == 'Link': + code = 'R31 = NNPC;\n' + code + elif x == 'ClearHazards': + code += '/* Code Needed to Clear Execute & Inst Hazards */\n' + else: + inst_flags += (x, ) + + iop = InstObjParams(name, Name, 'Jump', CodeBlock(code), inst_flags) + header_output = BasicDeclare.subst(iop) + decoder_output = BasicConstructor.subst(iop) + decode_block = BasicDecode.subst(iop) + exec_output = BasicExecute.subst(iop) +}}; + + + + diff --git a/src/arch/mips/isa/formats/control.isa b/src/arch/mips/isa/formats/control.isa new file mode 100644 index 000000000..509ee7e87 --- /dev/null +++ b/src/arch/mips/isa/formats/control.isa @@ -0,0 +1,156 @@ +// -*- mode:c++ -*- + +// Copyright (c) 2003-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 + +//////////////////////////////////////////////////////////////////// +// +// Integer operate instructions +// + +//Outputs to decoder.hh +output header {{ + + class Control : public MipsStaticInst + { + protected: + + /// Constructor + Control(const char *mnem, MachInst _machInst, OpClass __opClass) : + MipsStaticInst(mnem, _machInst, __opClass) + { + } + + std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; + }; + + class CP0Control : public Control + { + protected: + + /// Constructor + CP0Control(const char *mnem, MachInst _machInst, OpClass __opClass) : + Control(mnem, _machInst, __opClass) + { + } + + std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; + }; + + class CP1Control : public Control + { + protected: + + /// Constructor + CP1Control(const char *mnem, MachInst _machInst, OpClass __opClass) : + Control(mnem, _machInst, __opClass) + { + } + + std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; + }; + +}}; + +//Outputs to decoder.cc +output decoder {{ + std::string Control::generateDisassembly(Addr pc, const SymbolTable *symtab) const + { + std::stringstream ss; + + ccprintf(ss, "%-10s ", mnemonic); + + if (mnemonic == "mfc0" || mnemonic == "mtc0") { + ccprintf(ss, "%-10s %d,%d,%d", mnemonic,RT,RD,SEL); + } else { + + // just print the first dest... if there's a second one, + // it's generally implicit + if (_numDestRegs > 0) { + printReg(ss, _destRegIdx[0]); + } + + ss << ", "; + + // 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]); + } + } + + return ss.str(); + } + + std::string CP0Control::generateDisassembly(Addr pc, const SymbolTable *symtab) const + { + std::stringstream ss; + ccprintf(ss, "%-10s r%d, r%d, %d", mnemonic, RT, RD, SEL); + return ss.str(); + } + + std::string CP1Control::generateDisassembly(Addr pc, const SymbolTable *symtab) const + { + std::stringstream ss; + ccprintf(ss, "%-10s r%d, f%d", mnemonic, RT, FS); + return ss.str(); + } + +}}; + +def format System(code, *flags) {{ + iop = InstObjParams(name, Name, 'Control', CodeBlock(code), flags) + header_output = BasicDeclare.subst(iop) + decoder_output = BasicConstructor.subst(iop) + decode_block = BasicDecode.subst(iop) + exec_output = BasicExecute.subst(iop) +}}; + +def format CP0Control(code, *flags) {{ + iop = InstObjParams(name, Name, 'CP0Control', CodeBlock(code), flags) + header_output = BasicDeclare.subst(iop) + decoder_output = BasicConstructor.subst(iop) + decode_block = BasicDecode.subst(iop) + exec_output = BasicExecute.subst(iop) +}}; + +def format CP1Control(code, *flags) {{ + iop = InstObjParams(name, Name, 'CP1Control', CodeBlock(code), flags) + header_output = BasicDeclare.subst(iop) + decoder_output = BasicConstructor.subst(iop) + decode_block = BasicDecode.subst(iop) + exec_output = BasicExecute.subst(iop) +}}; + + diff --git a/src/arch/mips/isa/formats/formats.isa b/src/arch/mips/isa/formats/formats.isa new file mode 100644 index 000000000..4c3eec132 --- /dev/null +++ b/src/arch/mips/isa/formats/formats.isa @@ -0,0 +1,66 @@ +// -*- mode:c++ -*- + +// Copyright (c) 2003-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 + +//Templates from this format are used later +//Include the basic format +##include "basic.isa" + +//Include the basic format +##include "noop.isa" + +//Include utility functions +##include "util.isa" + +//Include the control/cp0/cp1 formats +##include "control.isa" + +//Include the integer formats +##include "int.isa" + +//Include the floatOp format +##include "fp.isa" + +//Include the mem format +##include "mem.isa" + +//Include the mem format +##include "mt.isa" + +//Include the trap format +##include "trap.isa" + +//Include the branch format +##include "branch.isa" + +//Include the noop format +##include "unimp.isa" + +//Include the noop format +##include "unknown.isa" diff --git a/src/arch/mips/isa/formats/fp.isa b/src/arch/mips/isa/formats/fp.isa new file mode 100644 index 000000000..d05b04d0e --- /dev/null +++ b/src/arch/mips/isa/formats/fp.isa @@ -0,0 +1,369 @@ +// -*- mode:c++ -*- + +// Copyright (c) 2003-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 + +//////////////////////////////////////////////////////////////////// +// +// Floating Point operate instructions +// + +output header {{ + /** + * Base class for FP operations. + */ + class FPOp : public MipsStaticInst + { + protected: + + /// Constructor + FPOp(const char *mnem, MachInst _machInst, OpClass __opClass) : MipsStaticInst(mnem, _machInst, __opClass) + { + } + + //std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; + + //needs function to check for fpEnable or not + }; + + class FPCompareOp : public FPOp + { + protected: + FPCompareOp(const char *mnem, MachInst _machInst, OpClass __opClass) : FPOp(mnem, _machInst, __opClass) + { + } + + std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; + + }; +}}; + +output decoder {{ + std::string FPCompareOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const + { + std::stringstream ss; + + ccprintf(ss, "%-10s ", mnemonic); + + ccprintf(ss,"%d",CC); + + if(_numSrcRegs > 0) { + ss << ", "; + printReg(ss, _srcRegIdx[0]); + } + + if(_numSrcRegs > 1) { + ss << ", "; + printReg(ss, _srcRegIdx[1]); + } + + return ss.str(); + } +}}; + +output exec {{ + + //If any operand is Nan return the appropriate QNaN + template <class T> + bool + fpNanOperands(FPOp *inst, %(CPU_exec_context)s *xc, const T &src_type, + Trace::InstRecord *traceData) + { + uint64_t mips_nan = 0; + T src_op = 0; + int size = sizeof(src_op) * 8; + + for (int i = 0; i < inst->numSrcRegs(); i++) { + uint64_t src_bits = xc->readFloatRegBits(inst, 0, size); + + if (isNan(&src_bits, size) ) { + if (isSnan(&src_bits, size)) { + switch (size) + { + case 32: mips_nan = MIPS32_QNAN; break; + case 64: mips_nan = MIPS64_QNAN; break; + default: panic("Unsupported Floating Point Size (%d)", size); + } + } else { + mips_nan = src_bits; + } + + xc->setFloatRegBits(inst, 0, mips_nan, size); + if (traceData) { traceData->setData(mips_nan); } + return true; + } + } + return false; + } + + template <class T> + bool + fpInvalidOp(FPOp *inst, %(CPU_exec_context)s *cpu, const T dest_val, + Trace::InstRecord *traceData) + { + uint64_t mips_nan = 0; + T src_op = dest_val; + int size = sizeof(src_op) * 8; + + if (isNan(&src_op, size)) { + switch (size) + { + case 32: mips_nan = MIPS32_QNAN; break; + case 64: mips_nan = MIPS64_QNAN; break; + default: panic("Unsupported Floating Point Size (%d)", size); + } + + //Set value to QNAN + cpu->setFloatRegBits(inst, 0, mips_nan, size); + + //Read FCSR from FloatRegFile + uint32_t fcsr_bits = cpu->tc->readFloatRegBits(FCSR); + + //Write FCSR from FloatRegFile + cpu->tc->setFloatRegBits(FCSR, genInvalidVector(fcsr_bits)); + + if (traceData) { traceData->setData(mips_nan); } + return true; + } + + return false; + } + + void + fpResetCauseBits(%(CPU_exec_context)s *cpu) + { + //Read FCSR from FloatRegFile + uint32_t fcsr = cpu->tc->readFloatRegBits(FCSR); + + fcsr = bits(fcsr, 31, 18) << 18 | bits(fcsr, 11, 0); + + //Write FCSR from FloatRegFile + cpu->tc->setFloatRegBits(FCSR, fcsr); + } +}}; + +def template FloatingPointExecute {{ + Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const + { + Fault fault = NoFault; + + %(fp_enable_check)s; + + //When is the right time to reset cause bits? + //start of every instruction or every cycle? + fpResetCauseBits(xc); + + %(op_decl)s; + %(op_rd)s; + + //Check if any FP operand is a NaN value + if (!fpNanOperands((FPOp*)this, xc, Fd, traceData)) { + %(code)s; + + //Change this code for Full-System/Sycall Emulation + //separation + //---- + //Should Full System-Mode throw a fault here? + //---- + //Check for IEEE 754 FP Exceptions + //fault = fpNanOperands((FPOp*)this, xc, Fd, traceData); + if (!fpInvalidOp((FPOp*)this, xc, Fd, traceData) && + fault == NoFault) + { + %(op_wb)s; + } + } + + return fault; + } +}}; + +// Primary format for float point operate instructions: +def format FloatOp(code, *flags) {{ + iop = InstObjParams(name, Name, 'FPOp', CodeBlock(code), flags) + header_output = BasicDeclare.subst(iop) + decoder_output = BasicConstructor.subst(iop) + decode_block = BasicDecode.subst(iop) + exec_output = FloatingPointExecute.subst(iop) +}}; + +def format FloatCompareOp(cond_code, *flags) {{ + import sys + + code = 'bool cond;\n' + if '.sf' in cond_code or 'SinglePrecision' in flags: + if 'QnanException' in flags: + code += 'if (isQnan(&Fs.sf, 32) || isQnan(&Ft.sf, 32)) {\n' + code += '\tFCSR = genInvalidVector(FCSR);\n' + code += '\treturn NoFault;' + code += '}\n else ' + code += 'if (isNan(&Fs.sf, 32) || isNan(&Ft.sf, 32)) {\n' + elif '.df' in cond_code or 'DoublePrecision' in flags: + if 'QnanException' in flags: + code += 'if (isQnan(&Fs.df, 64) || isQnan(&Ft.df, 64)) {\n' + code += '\tFCSR = genInvalidVector(FCSR);\n' + code += '\treturn NoFault;' + code += '}\n else ' + code += 'if (isNan(&Fs.df, 64) || isNan(&Ft.df, 64)) {\n' + else: + sys.exit('Decoder Failed: Can\'t Determine Operand Type\n') + + if 'UnorderedTrue' in flags: + code += 'cond = 1;\n' + elif 'UnorderedFalse' in flags: + code += 'cond = 0;\n' + else: + sys.exit('Decoder Failed: Float Compare Instruction Needs A Unordered Flag\n') + + code += '} else {\n' + code += cond_code + '}' + code += 'FCSR = genCCVector(FCSR, CC, cond);\n' + + iop = InstObjParams(name, Name, 'FPCompareOp', CodeBlock(code)) + header_output = BasicDeclare.subst(iop) + decoder_output = BasicConstructor.subst(iop) + decode_block = BasicDecode.subst(iop) + exec_output = BasicExecute.subst(iop) +}}; + +def format FloatConvertOp(code, *flags) {{ + import sys + + #Determine Source Type + convert = 'fpConvert(' + if '.sf' in code: + code = 'float ' + code + '\n' + convert += 'SINGLE_TO_' + elif '.df' in code: + code = 'double ' + code + '\n' + convert += 'DOUBLE_TO_' + elif '.uw' in code: + code = 'uint32_t ' + code + '\n' + convert += 'WORD_TO_' + elif '.ud' in code: + code = 'uint64_t ' + code + '\n' + convert += 'LONG_TO_' + else: + sys.exit("Error Determining Source Type for Conversion") + + #Determine Destination Type + if 'ToSingle' in flags: + code += 'Fd.uw = ' + convert + 'SINGLE, ' + elif 'ToDouble' in flags: + code += 'Fd.ud = ' + convert + 'DOUBLE, ' + elif 'ToWord' in flags: + code += 'Fd.uw = ' + convert + 'WORD, ' + elif 'ToLong' in flags: + code += 'Fd.ud = ' + convert + 'LONG, ' + else: + sys.exit("Error Determining Destination Type for Conversion") + + #Figure out how to round value + if 'Ceil' in flags: + code += 'ceil(val)); ' + elif 'Floor' in flags: + code += 'floor(val)); ' + elif 'Round' in flags: + code += 'roundFP(val, 0)); ' + elif 'Trunc' in flags: + code += 'truncFP(val));' + else: + code += 'val); ' + + iop = InstObjParams(name, Name, 'FPOp', CodeBlock(code)) + header_output = BasicDeclare.subst(iop) + decoder_output = BasicConstructor.subst(iop) + decode_block = BasicDecode.subst(iop) + exec_output = BasicExecute.subst(iop) +}}; + +def format FloatAccOp(code, *flags) {{ + iop = InstObjParams(name, Name, 'FPOp', CodeBlock(code), flags) + header_output = BasicDeclare.subst(iop) + decoder_output = BasicConstructor.subst(iop) + decode_block = BasicDecode.subst(iop) + exec_output = BasicExecute.subst(iop) +}}; + +// Primary format for float64 operate instructions: +def format Float64Op(code, *flags) {{ + iop = InstObjParams(name, Name, 'MipsStaticInst', CodeBlock(code), flags) + header_output = BasicDeclare.subst(iop) + decoder_output = BasicConstructor.subst(iop) + decode_block = BasicDecode.subst(iop) + exec_output = BasicExecute.subst(iop) +}}; + +def format FloatPSCompareOp(cond_code1, cond_code2, *flags) {{ + import sys + + code = 'bool cond1, cond2;\n' + code += 'bool code_block1, code_block2;\n' + code += 'code_block1 = code_block2 = true;\n' + + if 'QnanException' in flags: + code += 'if (isQnan(&Fs1.sf, 32) || isQnan(&Ft1.sf, 32)) {\n' + code += '\tFCSR = genInvalidVector(FCSR);\n' + code += 'code_block1 = false;' + code += '}\n' + code += 'if (isQnan(&Fs2.sf, 32) || isQnan(&Ft2.sf, 32)) {\n' + code += '\tFCSR = genInvalidVector(FCSR);\n' + code += 'code_block2 = false;' + code += '}\n' + + code += 'if (code_block1) {' + code += '\tif (isNan(&Fs1.sf, 32) || isNan(&Ft1.sf, 32)) {\n' + if 'UnorderedTrue' in flags: + code += 'cond1 = 1;\n' + elif 'UnorderedFalse' in flags: + code += 'cond1 = 0;\n' + else: + sys.exit('Decoder Failed: Float Compare Instruction Needs A Unordered Flag\n') + code += '} else {\n' + code += cond_code1 + code += 'FCSR = genCCVector(FCSR, CC, cond1);}\n}\n' + + code += 'if (code_block2) {' + code += '\tif (isNan(&Fs2.sf, 32) || isNan(&Ft2.sf, 32)) {\n' + if 'UnorderedTrue' in flags: + code += 'cond2 = 1;\n' + elif 'UnorderedFalse' in flags: + code += 'cond2 = 0;\n' + else: + sys.exit('Decoder Failed: Float Compare Instruction Needs A Unordered Flag\n') + code += '} else {\n' + code += cond_code2 + code += 'FCSR = genCCVector(FCSR, CC, cond2);}\n}' + + iop = InstObjParams(name, Name, 'FPCompareOp', CodeBlock(code)) + header_output = BasicDeclare.subst(iop) + decoder_output = BasicConstructor.subst(iop) + decode_block = BasicDecode.subst(iop) + exec_output = BasicExecute.subst(iop) +}}; + diff --git a/src/arch/mips/isa/formats/int.isa b/src/arch/mips/isa/formats/int.isa new file mode 100644 index 000000000..7b5affb5c --- /dev/null +++ b/src/arch/mips/isa/formats/int.isa @@ -0,0 +1,270 @@ +// -*- mode:c++ -*- + +// Copyright (c) 2003-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 + +//////////////////////////////////////////////////////////////////// +// +// Integer operate instructions +// +output header {{ +#include <iostream> + using namespace std; + /** + * Base class for integer operations. + */ + class IntOp : public MipsStaticInst + { + protected: + + /// Constructor + IntOp(const char *mnem, MachInst _machInst, OpClass __opClass) : + MipsStaticInst(mnem, _machInst, __opClass) + { + } + + std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; + }; + + + class HiLoOp: public IntOp + { + protected: + + /// Constructor + HiLoOp(const char *mnem, MachInst _machInst, OpClass __opClass) : + IntOp(mnem, _machInst, __opClass) + { + } + + std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; + }; + + class HiLoMiscOp: public HiLoOp + { + protected: + + /// Constructor + HiLoMiscOp(const char *mnem, MachInst _machInst, OpClass __opClass) : + HiLoOp(mnem, _machInst, __opClass) + { + } + + std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; + }; + + + class IntImmOp : public MipsStaticInst + { + protected: + + int16_t imm; + int32_t sextImm; + uint32_t zextImm; + + /// Constructor + IntImmOp(const char *mnem, MachInst _machInst, OpClass __opClass) : + MipsStaticInst(mnem, _machInst, __opClass),imm(INTIMM), + sextImm(INTIMM),zextImm(0x0000FFFF & INTIMM) + { + //If Bit 15 is 1 then Sign Extend + int32_t temp = sextImm & 0x00008000; + if (temp > 0 && mnemonic != "lui") { + sextImm |= 0xFFFF0000; + } + } + + std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; + + + }; + +}}; + +// HiLo<Misc> instruction class execute method template. +// Mainly to get instruction trace data to print out +// correctly +def template HiLoExecute {{ + Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const + { + Fault fault = NoFault; + + %(fp_enable_check)s; + %(op_decl)s; + %(op_rd)s; + %(code)s; + + if(fault == NoFault) + { + %(op_wb)s; + //If there are 2 Destination Registers then + //concatenate the values for the traceData + if(traceData && _numDestRegs == 2) { + uint64_t hilo_final_val = (uint64_t)HI << 32 | LO; + traceData->setData(hilo_final_val); + } + } + return fault; + } +}}; + +//Outputs to decoder.cc +output decoder {{ + std::string IntOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const + { + std::stringstream ss; + + ccprintf(ss, "%-10s ", mnemonic); + + // just print the first dest... if there's a second one, + // it's generally implicit + if (_numDestRegs > 0) { + printReg(ss, _destRegIdx[0]); + ss << ", "; + } + + // 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]); + } + + return ss.str(); + } + + std::string HiLoOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const + { + std::stringstream ss; + + ccprintf(ss, "%-10s ", mnemonic); + + //Destination Registers are implicit for HI/LO ops + if (_numSrcRegs > 0) { + printReg(ss, _srcRegIdx[0]); + } + + if (_numSrcRegs > 1) { + ss << ", "; + printReg(ss, _srcRegIdx[1]); + } + + return ss.str(); + } + + std::string HiLoMiscOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const + { + std::stringstream ss; + + ccprintf(ss, "%-10s ", mnemonic); + + if (_numDestRegs > 0 && _destRegIdx[0] < 32) { + printReg(ss, _destRegIdx[0]); + } else if (_numSrcRegs > 0 && _srcRegIdx[0] < 32) { + printReg(ss, _srcRegIdx[0]); + } + + return ss.str(); + } + + std::string IntImmOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const + { + std::stringstream ss; + + ccprintf(ss, "%-10s ", mnemonic); + + if (_numDestRegs > 0) { + printReg(ss, _destRegIdx[0]); + } + + ss << ", "; + + if (_numSrcRegs > 0) { + printReg(ss, _srcRegIdx[0]); + ss << ", "; + } + + if( mnemonic == "lui") + ccprintf(ss, "0x%x ", sextImm); + else + ss << (int) sextImm; + + return ss.str(); + } + +}}; + +def format IntOp(code, *opt_flags) {{ + iop = InstObjParams(name, Name, 'IntOp', CodeBlock(code), opt_flags) + header_output = BasicDeclare.subst(iop) + decoder_output = BasicConstructor.subst(iop) + decode_block = OperateNopCheckDecode.subst(iop) + exec_output = BasicExecute.subst(iop) +}}; + +def format IntImmOp(code, *opt_flags) {{ + iop = InstObjParams(name, Name, 'IntImmOp', CodeBlock(code), opt_flags) + header_output = BasicDeclare.subst(iop) + decoder_output = BasicConstructor.subst(iop) + decode_block = OperateNopCheckDecode.subst(iop) + exec_output = BasicExecute.subst(iop) +}}; + +def format HiLoOp(code, *opt_flags) {{ + if '.sd' in code: + code = 'int64_t ' + code + elif '.ud' in code: + code = 'uint64_t ' + code + + code += 'HI = val<63:32>;\n' + code += 'LO = val<31:0>;\n' + + iop = InstObjParams(name, Name, 'HiLoOp', CodeBlock(code), opt_flags) + header_output = BasicDeclare.subst(iop) + decoder_output = BasicConstructor.subst(iop) + decode_block = OperateNopCheckDecode.subst(iop) + exec_output = HiLoExecute.subst(iop) +}}; + +def format HiLoMiscOp(code, *opt_flags) {{ + iop = InstObjParams(name, Name, 'HiLoMiscOp', CodeBlock(code), opt_flags) + header_output = BasicDeclare.subst(iop) + decoder_output = BasicConstructor.subst(iop) + decode_block = OperateNopCheckDecode.subst(iop) + exec_output = HiLoExecute.subst(iop) +}}; + + + + + diff --git a/src/arch/mips/isa/formats/mem.isa b/src/arch/mips/isa/formats/mem.isa new file mode 100644 index 000000000..f52247056 --- /dev/null +++ b/src/arch/mips/isa/formats/mem.isa @@ -0,0 +1,577 @@ +// -*- mode:c++ -*- + +// 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 + +//////////////////////////////////////////////////////////////////// +// +// Memory-format instructions +// + +output header {{ + /** + * Base class for general Mips memory-format instructions. + */ + class Memory : public MipsStaticInst + { + protected: + + /// Memory request flags. See mem_req_base.hh. + unsigned memAccessFlags; + /// Pointer to EAComp object. + const StaticInstPtr eaCompPtr; + /// Pointer to MemAcc object. + const StaticInstPtr memAccPtr; + + /// Displacement for EA calculation (signed). + int32_t disp; + + /// Constructor + Memory(const char *mnem, MachInst _machInst, OpClass __opClass, + StaticInstPtr _eaCompPtr = nullStaticInstPtr, + StaticInstPtr _memAccPtr = nullStaticInstPtr) + : MipsStaticInst(mnem, _machInst, __opClass), + memAccessFlags(0), eaCompPtr(_eaCompPtr), memAccPtr(_memAccPtr), + disp(OFFSET) + { + //If Bit 15 is 1 then Sign Extend + int32_t temp = disp & 0x00008000; + + if (temp > 0) { + disp |= 0xFFFF0000; + } + } + + std::string + generateDisassembly(Addr pc, const SymbolTable *symtab) const; + + public: + + const StaticInstPtr &eaCompInst() const { return eaCompPtr; } + const StaticInstPtr &memAccInst() const { return memAccPtr; } + }; + +}}; + + +output decoder {{ + std::string + Memory::generateDisassembly(Addr pc, const SymbolTable *symtab) const + { + return csprintf("%-10s %c%d,%d(r%d)", mnemonic, + flags[IsFloating] ? 'f' : 'r', RT, disp, RS); + } + +}}; + +def template LoadStoreDeclare {{ + /** + * Static instruction class for "%(mnemonic)s". + */ + class %(class_name)s : public %(base_class)s + { + protected: + + /** + * "Fake" effective address computation class for "%(mnemonic)s". + */ + class EAComp : public %(base_class)s + { + public: + /// Constructor + EAComp(MachInst machInst); + + %(BasicExecDeclare)s + }; + + /** + * "Fake" memory access instruction class for "%(mnemonic)s". + */ + class MemAcc : public %(base_class)s + { + public: + /// Constructor + MemAcc(MachInst machInst); + + %(BasicExecDeclare)s + }; + + public: + + /// Constructor. + %(class_name)s(MachInst machInst); + + %(BasicExecDeclare)s + + %(InitiateAccDeclare)s + + %(CompleteAccDeclare)s + }; +}}; + + +def template InitiateAccDeclare {{ + Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const; +}}; + + +def template CompleteAccDeclare {{ + Fault completeAcc(uint8_t *, %(CPU_exec_context)s *, Trace::InstRecord *) const; +}}; + + +def template LoadStoreConstructor {{ + /** TODO: change op_class to AddrGenOp or something (requires + * creating new member of OpClass enum in op_class.hh, updating + * config files, etc.). */ + inline %(class_name)s::EAComp::EAComp(MachInst machInst) + : %(base_class)s("%(mnemonic)s (EAComp)", machInst, IntAluOp) + { + %(ea_constructor)s; + } + + inline %(class_name)s::MemAcc::MemAcc(MachInst machInst) + : %(base_class)s("%(mnemonic)s (MemAcc)", machInst, %(op_class)s) + { + %(memacc_constructor)s; + } + + inline %(class_name)s::%(class_name)s(MachInst machInst) + : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, + new EAComp(machInst), new MemAcc(machInst)) + { + %(constructor)s; + } +}}; + + +def template EACompExecute {{ + Fault + %(class_name)s::EAComp::execute(%(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const + { + Addr EA; + Fault fault = NoFault; + + %(fp_enable_check)s; + %(op_decl)s; + %(op_rd)s; + %(code)s; + + if (fault == NoFault) { + %(op_wb)s; + xc->setEA(EA); + } + + return fault; + } +}}; + +def template LoadMemAccExecute {{ + Fault + %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const + { + Addr EA; + Fault fault = NoFault; + + %(fp_enable_check)s; + %(op_decl)s; + %(op_rd)s; + EA = xc->getEA(); + + if (fault == NoFault) { + fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags); + %(code)s; + } + + if (fault == NoFault) { + %(op_wb)s; + } + + return fault; + } +}}; + + +def template LoadExecute {{ + Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const + { + Addr EA; + Fault fault = NoFault; + + %(fp_enable_check)s; + %(op_decl)s; + %(op_rd)s; + %(ea_code)s; + + if (fault == NoFault) { + fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags); + %(memacc_code)s; + } + + if (fault == NoFault) { + %(op_wb)s; + } + + return fault; + } +}}; + + +def template LoadInitiateAcc {{ + Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const + { + Addr EA; + Fault fault = NoFault; + + %(fp_enable_check)s; + %(op_src_decl)s; + %(op_rd)s; + %(ea_code)s; + + if (fault == NoFault) { + fault = xc->read(EA, (uint%(mem_acc_size)d_t &)Mem, memAccessFlags); + } + + return fault; + } +}}; + + +def template LoadCompleteAcc {{ + Fault %(class_name)s::completeAcc(uint8_t *data, + %(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const + { + Fault fault = NoFault; + + %(fp_enable_check)s; + %(op_decl)s; + + memcpy(&Mem, data, sizeof(Mem)); + + if (fault == NoFault) { + %(memacc_code)s; + } + + if (fault == NoFault) { + %(op_wb)s; + } + + return fault; + } +}}; + + +def template StoreMemAccExecute {{ + Fault + %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const + { + Addr EA; + Fault fault = NoFault; + uint64_t write_result = 0; + + %(fp_enable_check)s; + %(op_decl)s; + %(op_rd)s; + EA = xc->getEA(); + + if (fault == NoFault) { + %(code)s; + } + + if (fault == NoFault) { + fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA, + memAccessFlags, &write_result); + if (traceData) { traceData->setData(Mem); } + } + + if (fault == NoFault) { + %(postacc_code)s; + } + + if (fault == NoFault) { + %(op_wb)s; + } + + return fault; + } +}}; + + +def template StoreExecute {{ + Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const + { + Addr EA; + Fault fault = NoFault; + uint64_t write_result = 0; + + %(fp_enable_check)s; + %(op_decl)s; + %(op_rd)s; + %(ea_code)s; + + if (fault == NoFault) { + %(memacc_code)s; + } + + if (fault == NoFault) { + fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA, + memAccessFlags, &write_result); + if (traceData) { traceData->setData(Mem); } + } + + if (fault == NoFault) { + %(postacc_code)s; + } + + if (fault == NoFault) { + %(op_wb)s; + } + + return fault; + } +}}; + +def template StoreInitiateAcc {{ + Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const + { + Addr EA; + Fault fault = NoFault; + uint64_t write_result = 0; + + %(fp_enable_check)s; + %(op_decl)s; + %(op_rd)s; + %(ea_code)s; + + if (fault == NoFault) { + %(memacc_code)s; + } + + if (fault == NoFault) { + fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA, + memAccessFlags, &write_result); + if (traceData) { traceData->setData(Mem); } + } + + return fault; + } +}}; + + +def template StoreCompleteAcc {{ + Fault %(class_name)s::completeAcc(uint8_t *data, + %(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)); + + if (fault == NoFault) { + %(postacc_code)s; + } + + if (fault == NoFault) { + %(op_wb)s; + } + + return fault; + } +}}; + + +def template MiscMemAccExecute {{ + Fault %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const + { + Addr EA; + Fault fault = NoFault; + + %(fp_enable_check)s; + %(op_decl)s; + %(op_rd)s; + EA = xc->getEA(); + + if (fault == NoFault) { + %(code)s; + } + + return NoFault; + } +}}; + +def template MiscExecute {{ + Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const + { + Addr EA; + Fault fault = NoFault; + + %(fp_enable_check)s; + %(op_decl)s; + %(op_rd)s; + %(ea_code)s; + + if (fault == NoFault) { + %(memacc_code)s; + } + + return NoFault; + } +}}; + +def template MiscInitiateAcc {{ + Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const + { + panic("Misc instruction does not support split access method!"); + return NoFault; + } +}}; + + +def template MiscCompleteAcc {{ + Fault %(class_name)s::completeAcc(uint8_t *data, + %(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const + { + panic("Misc instruction does not support split access method!"); + + return NoFault; + } +}}; + +// load instructions use Rt as dest, so check for +// Rt == 0 to detect nops +def template LoadNopCheckDecode {{ + { + MipsStaticInst *i = new %(class_name)s(machInst); + if (RT == 0) { + i = makeNop(i); + } + return i; + } +}}; + +def format LoadMemory(memacc_code, ea_code = {{ EA = Rs + disp; }}, + mem_flags = [], inst_flags = []) {{ + (header_output, decoder_output, decode_block, exec_output) = \ + LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, + decode_template = LoadNopCheckDecode, + exec_template_base = 'Load') +}}; + +def format StoreMemory(memacc_code, ea_code = {{ EA = Rs + disp; }}, + mem_flags = [], inst_flags = []) {{ + (header_output, decoder_output, decode_block, exec_output) = \ + LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, + exec_template_base = 'Store') +}}; + +def format LoadIndexedMemory(memacc_code, ea_code = {{ EA = Rs + Rt; }}, + mem_flags = [], inst_flags = []) {{ + (header_output, decoder_output, decode_block, exec_output) = \ + LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, + decode_template = LoadNopCheckDecode, + exec_template_base = 'Load') +}}; + +def format StoreIndexedMemory(memacc_code, ea_code = {{ EA = Rs + Rt; }}, + mem_flags = [], inst_flags = []) {{ + (header_output, decoder_output, decode_block, exec_output) = \ + LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, + exec_template_base = 'Store') +}}; + +def format LoadUnalignedMemory(memacc_code, ea_code = {{ EA = (Rs + disp) & ~3; }}, + mem_flags = [], inst_flags = []) {{ + decl_code = 'uint32_t mem_word = Mem.uw;\n' + decl_code += 'uint32_t unalign_addr = Rs + disp;\n' + decl_code += 'uint32_t byte_offset = unalign_addr & 3;\n' + decl_code += '#if BYTE_ORDER == BIG_ENDIAN\n' + decl_code += '\tbyte_offset ^= 3;\n' + decl_code += '#endif\n' + + memacc_code = decl_code + memacc_code + + (header_output, decoder_output, decode_block, exec_output) = \ + LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, + decode_template = LoadNopCheckDecode, + exec_template_base = 'Load') +}}; + +def format StoreUnalignedMemory(memacc_code, ea_code = {{ EA = (Rs + disp) & ~3; }}, + mem_flags = [], inst_flags = []) {{ + decl_code = 'uint32_t mem_word = 0;\n' + decl_code += 'uint32_t unaligned_addr = Rs + disp;\n' + decl_code += 'uint32_t byte_offset = unaligned_addr & 3;\n' + decl_code += '#if BYTE_ORDER == BIG_ENDIAN\n' + decl_code += '\tbyte_offset ^= 3;\n' + decl_code += '#endif\n' + decl_code += 'fault = xc->read(EA, (uint32_t&)mem_word, memAccessFlags);\n' + memacc_code = decl_code + memacc_code + '\nMem = mem_word;\n' + + (header_output, decoder_output, decode_block, exec_output) = \ + LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, + decode_template = LoadNopCheckDecode, + exec_template_base = 'Store') +}}; + +def format Prefetch(ea_code = {{ EA = Rs + disp; }}, + mem_flags = [], pf_flags = [], inst_flags = []) {{ + pf_mem_flags = mem_flags + pf_flags + ['NO_FAULT'] + pf_inst_flags = inst_flags + ['IsMemRef', 'IsLoad', + 'IsDataPrefetch', 'MemReadOp'] + + (header_output, decoder_output, decode_block, exec_output) = \ + LoadStoreBase(name, Name, ea_code, + 'xc->prefetch(EA, memAccessFlags);', + pf_mem_flags, pf_inst_flags, exec_template_base = 'Misc') + +}}; + +def format StoreCond(memacc_code, postacc_code, + ea_code = {{ EA = Rs + disp; }}, + 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') +}}; diff --git a/src/arch/mips/isa/formats/mt.isa b/src/arch/mips/isa/formats/mt.isa new file mode 100644 index 000000000..521b01123 --- /dev/null +++ b/src/arch/mips/isa/formats/mt.isa @@ -0,0 +1,81 @@ +// -*- mode:c++ -*- + +// Copyright (c) 2003-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 + +//////////////////////////////////////////////////////////////////// +// +// MT instructions +// + +output header {{ + /** + * Base class for integer operations. + */ + class MT : public MipsStaticInst + { + protected: + + /// Constructor + MT(const char *mnem, MachInst _machInst, OpClass __opClass) : MipsStaticInst(mnem, _machInst, __opClass) + { + } + + std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; + }; +}}; + +output decoder {{ + //Edit This Template When MT is Implemented + std::string MT::generateDisassembly(Addr pc, const SymbolTable *symtab) const + { + return "Disassembly of MT instruction\n"; + } +}}; + +def template MTExecute {{ + //Edit This Template When MT is Implemented + Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const + { + //Write the resulting state to the execution context + %(op_wb)s; + + //Call into the trap handler with the appropriate fault + return No_Fault; + } +}}; + +// Primary format for integer operate instructions: +def format MipsMT() {{ + code = 'panic(\"Mips MT Is Currently Unimplemented.\");\n' + iop = InstObjParams(name, Name, 'MT', CodeBlock(code)) + header_output = BasicDeclare.subst(iop) + decoder_output = BasicConstructor.subst(iop) + decode_block = BasicDecode.subst(iop) + exec_output = BasicExecute.subst(iop) +}}; diff --git a/src/arch/mips/isa/formats/noop.isa b/src/arch/mips/isa/formats/noop.isa new file mode 100644 index 000000000..4fd8235e4 --- /dev/null +++ b/src/arch/mips/isa/formats/noop.isa @@ -0,0 +1,118 @@ +// -*- mode:c++ -*- + +// Copyright (c) 2003-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 + +//////////////////////////////////////////////////////////////////// +// +// Nop +// + +output header {{ + /** + * Static instruction class for no-ops. This is a leaf class. + */ + class Nop : public MipsStaticInst + { + /// Disassembly of original instruction. + const std::string originalDisassembly; + + public: + /// Constructor + Nop(const std::string _originalDisassembly, MachInst _machInst) + : MipsStaticInst("nop", _machInst, No_OpClass), + originalDisassembly(_originalDisassembly) + { + flags[IsNop] = true; + } + + ~Nop() { } + + std::string + generateDisassembly(Addr pc, const SymbolTable *symtab) const; + + %(BasicExecDeclare)s + }; +}}; + +output decoder {{ + std::string Nop::generateDisassembly(Addr pc, + const SymbolTable *symtab) const + { + return csprintf("%-10s %s", "nop", originalDisassembly); + } + + /// Helper function for decoding nops. Substitute Nop object + /// for original inst passed in as arg (and delete latter). + inline + MipsStaticInst * + makeNop(MipsStaticInst *inst) + { + MipsStaticInst *nop = new Nop(inst->disassemble(0), inst->machInst); + delete inst; + return nop; + } +}}; + +output exec {{ + Fault + Nop::execute(%(CPU_exec_context)s *, Trace::InstRecord *) const + { + return NoFault; + } +}}; + +// integer & FP operate instructions use RT as dest, so check for +// RT == 0 to detect nops +def template OperateNopCheckDecode {{ + { + MipsStaticInst *i = new %(class_name)s(machInst); + + //if (RD == 0) { + // i = makeNop(i); + //} + + return i; + } +}}; + + +// Like BasicOperate format, but generates NOP if RC/FC == 31 +def format BasicOperateWithNopCheck(code, *opt_args) {{ + iop = InstObjParams(name, Name, 'MipsStaticInst', CodeBlock(code), + opt_args) + header_output = BasicDeclare.subst(iop) + decoder_output = BasicConstructor.subst(iop) + decode_block = OperateNopCheckDecode.subst(iop) + exec_output = BasicExecute.subst(iop) +}}; + +def format Nop() {{ + decode_block = 'return new Nop(\"\",machInst);\n' +}}; + diff --git a/src/arch/mips/isa/formats/tlbop.isa b/src/arch/mips/isa/formats/tlbop.isa new file mode 100644 index 000000000..75ab71c48 --- /dev/null +++ b/src/arch/mips/isa/formats/tlbop.isa @@ -0,0 +1,80 @@ +// -*- mode:c++ -*- + +// Copyright (c) 2003-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 + +//////////////////////////////////////////////////////////////////// +// +// TlbOp instructions +// + +output header {{ + /** + * Base class for integer operations. + */ + class TlbOp : public MipsStaticInst + { + protected: + + /// Constructor + TlbOp(const char *mnem, MachInst _machInst, OpClass __opClass) : MipsStaticInst(mnem, _machInst, __opClass) + { + } + + std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; + }; +}}; + +output decoder {{ + std::string TlbOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const + { + return "Disassembly of integer instruction\n"; + } +}}; + +def template TlbOpExecute {{ + Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const + { + //Write the resulting state to the execution context + %(op_wb)s; + + //Call into the trap handler with the appropriate fault + return No_Fault; + } +}}; + +// Primary format for integer operate instructions: +def format TlbOp(code, *opt_flags) {{ + orig_code = code + cblk = CodeBlock(code) + iop = InstObjParams(name, Name, 'MipsStaticInst', cblk, opt_flags) + header_output = BasicDeclare.subst(iop) + decoder_output = BasicConstructor.subst(iop) + decode_block = BasicDecodeWithMnemonic.subst(iop) + exec_output = TlbOpExecute.subst(iop) +}}; diff --git a/src/arch/mips/isa/formats/trap.isa b/src/arch/mips/isa/formats/trap.isa new file mode 100644 index 000000000..574b808cc --- /dev/null +++ b/src/arch/mips/isa/formats/trap.isa @@ -0,0 +1,81 @@ +// -*- mode:c++ -*- + +// Copyright (c) 2003-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 + +//////////////////////////////////////////////////////////////////// +// +// Trap instructions +// + +output header {{ + /** + * Base class for integer operations. + */ + class Trap : public MipsStaticInst + { + protected: + + /// Constructor + Trap(const char *mnem, MachInst _machInst, OpClass __opClass) : MipsStaticInst(mnem, _machInst, __opClass) + { + } + + std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; + }; +}}; + +output decoder {{ + std::string Trap::generateDisassembly(Addr pc, const SymbolTable *symtab) const + { + return "Disassembly of trap instruction\n"; + } +}}; + +def template TrapExecute {{ + //Edit This Template When Traps Are Implemented + Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const + { + //Write the resulting state to the execution context + %(op_wb)s; + + //Call into the trap handler with the appropriate fault + return No_Fault; + } +}}; + +def format Trap(code, *flags) {{ + code = 'panic(\"' + code += 'Trap Exception Handler Is Currently Not Implemented.' + code += '\");' + iop = InstObjParams(name, Name, 'MipsStaticInst', CodeBlock(code), flags) + header_output = BasicDeclare.subst(iop) + decoder_output = BasicConstructor.subst(iop) + decode_block = BasicDecode.subst(iop) + exec_output = BasicExecute.subst(iop) +}}; diff --git a/src/arch/mips/isa/formats/unimp.isa b/src/arch/mips/isa/formats/unimp.isa new file mode 100644 index 000000000..e17b5f832 --- /dev/null +++ b/src/arch/mips/isa/formats/unimp.isa @@ -0,0 +1,145 @@ +// -*- mode:c++ -*- + + +// 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: Korey Sewell + +//////////////////////////////////////////////////////////////////// +// +// Unimplemented instructions +// + +output header {{ + /** + * Static instruction class for unimplemented instructions that + * cause simulator termination. Note that these are recognized + * (legal) instructions that the simulator does not support; the + * 'Unknown' class is used for unrecognized/illegal instructions. + * This is a leaf class. + */ + class FailUnimplemented : public MipsStaticInst + { + public: + /// Constructor + FailUnimplemented(const char *_mnemonic, MachInst _machInst) + : MipsStaticInst(_mnemonic, _machInst, No_OpClass) + { + // don't call execute() (which panics) if we're on a + // speculative path + flags[IsNonSpeculative] = true; + } + + %(BasicExecDeclare)s + + std::string + generateDisassembly(Addr pc, const SymbolTable *symtab) const; + }; + + /** + * Base class for unimplemented instructions that cause a warning + * to be printed (but do not terminate simulation). This + * implementation is a little screwy in that it will print a + * warning for each instance of a particular unimplemented machine + * instruction, not just for each unimplemented opcode. Should + * probably make the 'warned' flag a static member of the derived + * class. + */ + class WarnUnimplemented : public MipsStaticInst + { + private: + /// Have we warned on this instruction yet? + mutable bool warned; + + public: + /// Constructor + WarnUnimplemented(const char *_mnemonic, MachInst _machInst) + : MipsStaticInst(_mnemonic, _machInst, No_OpClass), warned(false) + { + // don't call execute() (which panics) if we're on a + // speculative path + flags[IsNonSpeculative] = true; + } + + %(BasicExecDeclare)s + + std::string + generateDisassembly(Addr pc, const SymbolTable *symtab) const; + }; +}}; + +output decoder {{ + std::string + FailUnimplemented::generateDisassembly(Addr pc, + const SymbolTable *symtab) const + { + return csprintf("%-10s (unimplemented)", mnemonic); + } + + std::string + WarnUnimplemented::generateDisassembly(Addr pc, + const SymbolTable *symtab) const + { + return csprintf("%-10s (unimplemented)", mnemonic); + } +}}; + +output exec {{ + Fault + FailUnimplemented::execute(%(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const + { + panic("attempt to execute unimplemented instruction '%s' " + "(inst 0x%08x, opcode 0x%x, binary:%s)", mnemonic, machInst, OPCODE, + inst2string(machInst)); + return new UnimplementedOpcodeFault; + } + + Fault + WarnUnimplemented::execute(%(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const + { + if (!warned) { + warn("\tinstruction '%s' unimplemented\n", mnemonic); + warned = true; + } + + return NoFault; + } +}}; + + +def format FailUnimpl() {{ + iop = InstObjParams(name, 'FailUnimplemented') + decode_block = BasicDecodeWithMnemonic.subst(iop) +}}; + +def format WarnUnimpl() {{ + iop = InstObjParams(name, 'WarnUnimplemented') + decode_block = BasicDecodeWithMnemonic.subst(iop) +}}; + diff --git a/src/arch/mips/isa/formats/unknown.isa b/src/arch/mips/isa/formats/unknown.isa new file mode 100644 index 000000000..41387adca --- /dev/null +++ b/src/arch/mips/isa/formats/unknown.isa @@ -0,0 +1,84 @@ +// -*- mode:c++ -*- + +// Copyright (c) 2003-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 + +//////////////////////////////////////////////////////////////////// +// +// Unknown instructions +// + +output header {{ + /** + * Static instruction class for unknown (illegal) instructions. + * These cause simulator termination if they are executed in a + * non-speculative mode. This is a leaf class. + */ + class Unknown : public MipsStaticInst + { + public: + /// Constructor + Unknown(MachInst _machInst) + : MipsStaticInst("unknown", _machInst, No_OpClass) + { + // don't call execute() (which panics) if we're on a + // speculative path + flags[IsNonSpeculative] = true; + } + + %(BasicExecDeclare)s + + std::string + generateDisassembly(Addr pc, const SymbolTable *symtab) const; + }; +}}; + +output decoder {{ + std::string + Unknown::generateDisassembly(Addr pc, const SymbolTable *symtab) const + { + return csprintf("%-10s (inst 0x%x, opcode 0x%x, binary:%s)", + "unknown", machInst, OPCODE, inst2string(machInst)); + } +}}; + +output exec {{ + Fault + Unknown::execute(%(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const + { + panic("attempt to execute unknown instruction " + "(inst 0x%08x, opcode 0x%x, binary: %s)", machInst, OPCODE, inst2string(machInst)); + return new UnimplementedOpcodeFault; + } +}}; + +def format Unknown() {{ + decode_block = 'return new Unknown(machInst);\n' +}}; + diff --git a/src/arch/mips/isa/formats/util.isa b/src/arch/mips/isa/formats/util.isa new file mode 100644 index 000000000..b67a02d07 --- /dev/null +++ b/src/arch/mips/isa/formats/util.isa @@ -0,0 +1,183 @@ +// -*- mode:c++ -*- + +// Copyright (c) 2003-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: Steve Reinhardt +// Korey Sewell + +let {{ +def LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, + postacc_code = '', base_class = 'Memory', + decode_template = BasicDecode, exec_template_base = ''): + # Make sure flags are in lists (convert to lists if not). + mem_flags = makeList(mem_flags) + inst_flags = makeList(inst_flags) + + # add hook to get effective addresses into execution trace output. + ea_code += '\nif (traceData) { traceData->setAddr(EA); }\n' + + # generate code block objects + ea_cblk = CodeBlock(ea_code) + memacc_cblk = CodeBlock(memacc_code) + postacc_cblk = CodeBlock(postacc_code) + + # Some CPU models execute the memory operation as an atomic unit, + # while others want to separate them into an effective address + # computation and a memory access operation. As a result, we need + # to generate three StaticInst objects. Note that the latter two + # are nested inside the larger "atomic" one. + + # generate InstObjParams for EAComp object + ea_iop = InstObjParams(name, Name, base_class, ea_cblk, inst_flags) + + # generate InstObjParams for MemAcc object + memacc_iop = InstObjParams(name, Name, base_class, memacc_cblk, inst_flags) + # in the split execution model, the MemAcc portion is responsible + # for the post-access code. + memacc_iop.postacc_code = postacc_cblk.code + + # generate InstObjParams for InitiateAcc, CompleteAcc object + # The code used depends on the template being used + if (exec_template_base == 'Load'): + initiateacc_cblk = CodeBlock(ea_code + memacc_code) + completeacc_cblk = CodeBlock(memacc_code + postacc_code) + elif (exec_template_base == 'Store'): + initiateacc_cblk = CodeBlock(ea_code + memacc_code) + completeacc_cblk = CodeBlock(postacc_code) + else: + initiateacc_cblk = '' + completeacc_cblk = '' + + initiateacc_iop = InstObjParams(name, Name, base_class, initiateacc_cblk, + inst_flags) + + completeacc_iop = InstObjParams(name, Name, base_class, completeacc_cblk, + inst_flags) + + if (exec_template_base == 'Load'): + initiateacc_iop.ea_code = ea_cblk.code + 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'): + initiateacc_iop.ea_code = ea_cblk.code + initiateacc_iop.memacc_code = memacc_cblk.code + completeacc_iop.postacc_code = postacc_cblk.code + + # generate InstObjParams for unified execution + cblk = CodeBlock(ea_code + memacc_code + postacc_code) + iop = InstObjParams(name, Name, base_class, cblk, inst_flags) + + iop.ea_constructor = ea_cblk.constructor + iop.ea_code = ea_cblk.code + iop.memacc_constructor = memacc_cblk.constructor + iop.memacc_code = memacc_cblk.code + iop.postacc_code = postacc_cblk.code + + if mem_flags: + s = '\n\tmemAccessFlags = ' + string.join(mem_flags, '|') + ';' + iop.constructor += s + memacc_iop.constructor += s + + # select templates + memAccExecTemplate = eval(exec_template_base + 'MemAccExecute') + fullExecTemplate = eval(exec_template_base + 'Execute') + initiateAccTemplate = eval(exec_template_base + 'InitiateAcc') + completeAccTemplate = eval(exec_template_base + 'CompleteAcc') + + # (header_output, decoder_output, decode_block, exec_output) + return (LoadStoreDeclare.subst(iop), LoadStoreConstructor.subst(iop), + decode_template.subst(iop), + EACompExecute.subst(ea_iop) + + memAccExecTemplate.subst(memacc_iop) + + fullExecTemplate.subst(iop) + + initiateAccTemplate.subst(initiateacc_iop) + + completeAccTemplate.subst(completeacc_iop)) +}}; + +output header {{ + std::string inst2string(MachInst machInst); +}}; + +output decoder {{ + +std::string inst2string(MachInst machInst) +{ + string str = ""; + uint32_t mask = 0x80000000; + + for(int i=0; i < 32; i++) { + if ((machInst & mask) == 0) { + str += "0"; + } else { + str += "1"; + } + + mask = mask >> 1; + } + + return str; +} + +}}; +output exec {{ + + using namespace MipsISA; + + /// CLEAR ALL CPU INST/EXE HAZARDS + inline void + clear_exe_inst_hazards() + { + //CODE HERE + } + + + /// Check "FP enabled" machine status bit. Called when executing any FP + /// instruction in full-system mode. + /// @retval Full-system mode: NoFault if FP is enabled, FenFault + /// if not. Non-full-system mode: always returns NoFault. +#if FULL_SYSTEM + inline Fault checkFpEnableFault(%(CPU_exec_context)s *xc) + { + Fault fault = NoFault; // dummy... this ipr access should not fault + if (!Mips34k::ICSR_FPE(xc->readIpr(MipsISA::IPR_ICSR, fault))) { + fault = FloatEnableFault; + } + return fault; + } +#else + inline Fault checkFpEnableFault(%(CPU_exec_context)s *xc) + { + return NoFault; + } +#endif + + + +}}; + + diff --git a/src/arch/mips/isa/includes.isa b/src/arch/mips/isa/includes.isa new file mode 100644 index 000000000..555cec255 --- /dev/null +++ b/src/arch/mips/isa/includes.isa @@ -0,0 +1,81 @@ +// -*- mode:c++ -*- + +// Copyright (c) 2003-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 + +//////////////////////////////////////////////////////////////////// +// +// Output include file directives. +// + +output header {{ +#include <sstream> +#include <iostream> +#include <iomanip> + +#include "cpu/static_inst.hh" +#include "arch/mips/isa_traits.hh" +}}; + +output decoder {{ +#include "arch/mips/isa_traits.hh" +#include "base/cprintf.hh" +#include "base/loader/symtab.hh" +#include "cpu/thread_context.hh" +#include "arch/mips/faults.hh" +#include "arch/mips/isa_traits.hh" +#include "arch/mips/utility.hh" + +#include <math.h> +#if defined(linux) +#include <fenv.h> +#endif + +using namespace MipsISA; +}}; + +output exec {{ +#include "arch/mips/faults.hh" +#include "arch/mips/isa_traits.hh" +#include "arch/mips/utility.hh" + +#include <math.h> +#if defined(linux) +#include <fenv.h> +#endif + +#ifdef FULL_SYSTEM +//#include "arch/alpha/pseudo_inst.hh" +#endif +#include "cpu/base.hh" +#include "cpu/exetrace.hh" +#include "sim/sim_exit.hh" + +using namespace MipsISA; +}}; + diff --git a/src/arch/mips/isa/main.isa b/src/arch/mips/isa/main.isa new file mode 100644 index 000000000..9da3fc0db --- /dev/null +++ b/src/arch/mips/isa/main.isa @@ -0,0 +1,61 @@ +// -*- mode:c++ -*- + +// 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: Korey Sewell + +//////////////////////////////////////////////////////////////////// +// +// MIPS ISA description file. +// +//////////////////////////////////////////////////////////////////// + +//Include the C++ include directives +##include "includes.isa" + +//////////////////////////////////////////////////////////////////// +// +// Namespace statement. Everything below this line will be in the +// MipsISAInst namespace. +// + +namespace MipsISA; + +//Include the bitfield definitions +##include "bitfields.isa" + +//Include the operand_types and operand definitions +##include "operands.isa" + +//Include the base class for mips instructions, and some support code +##include "base.isa" + +//Include the definitions for the instruction formats +##include "formats/formats.isa" + +//Include the decoder definition +##include "decoder.isa" diff --git a/src/arch/mips/isa/operands.isa b/src/arch/mips/isa/operands.isa new file mode 100644 index 000000000..316552ef4 --- /dev/null +++ b/src/arch/mips/isa/operands.isa @@ -0,0 +1,91 @@ +// -*- mode:c++ -*- + +// Copyright (c) 2003-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 + +def operand_types {{ + 'sb' : ('signed int', 8), + 'ub' : ('unsigned int', 8), + 'sh' : ('signed int', 16), + 'uh' : ('unsigned int', 16), + 'sw' : ('signed int', 32), + 'uw' : ('unsigned int', 32), + 'sd' : ('signed int', 64), + 'ud' : ('unsigned int', 64), + 'sf' : ('float', 32), + 'df' : ('float', 64), + 'qf' : ('float', 128) +}}; + +def operands {{ + #General Purpose Integer Reg Operands + 'Rd': ('IntReg', 'uw', 'RD', 'IsInteger', 1), + 'Rs': ('IntReg', 'uw', 'RS', 'IsInteger', 2), + 'Rt': ('IntReg', 'uw', 'RT', 'IsInteger', 3), + + #Operands used for Link or Syscall Insts + 'R31': ('IntReg', 'uw','31','IsInteger', 4), + 'R2': ('IntReg', 'uw','2', 'IsInteger', 5), + + #Special Integer Reg operands + 'HI': ('IntReg', 'uw','32', 'IsInteger', 6), + 'LO': ('IntReg', 'uw','33', 'IsInteger', 7), + + #Immediate Value operand + 'IntImm': ('IntReg', 'uw', 'INTIMM', 'IsInteger', 3), + + #Floating Point Reg Operands + 'Fd': ('FloatReg', 'sf', 'FD', 'IsFloating', 1), + 'Fs': ('FloatReg', 'sf', 'FS', 'IsFloating', 2), + 'Ft': ('FloatReg', 'sf', 'FT', 'IsFloating', 3), + 'Fr': ('FloatReg', 'sf', 'FR', 'IsFloating', 3), + + #Special Floating Point Control Reg Operands + 'FIR': ('FloatReg', 'uw', '32', 'IsFloating', 1), + 'FCCR': ('FloatReg', 'uw', '33', 'IsFloating', 2), + 'FEXR': ('FloatReg', 'uw', '34', 'IsFloating', 3), + 'FENR': ('FloatReg', 'uw', '35', 'IsFloating', 3), + 'FCSR': ('FloatReg', 'uw', '36', 'IsFloating', 3), + + #Operands For Paired Singles FP Operations + 'Fd1': ('FloatReg', 'sf', 'FD', 'IsFloating', 4), + 'Fd2': ('FloatReg', 'sf', 'FD+1', 'IsFloating', 4), + 'Fs1': ('FloatReg', 'sf', 'FS', 'IsFloating', 5), + 'Fs2': ('FloatReg', 'sf', 'FS+1', 'IsFloating', 5), + 'Ft1': ('FloatReg', 'sf', 'FT', 'IsFloating', 6), + 'Ft2': ('FloatReg', 'sf', 'FT+1', 'IsFloating', 6), + 'Fr1': ('FloatReg', 'sf', 'FR', 'IsFloating', 7), + 'Fr2': ('FloatReg', 'sf', 'FR+1', 'IsFloating', 7), + + #Memory Operand + 'Mem': ('Mem', 'uw', None, ('IsMemRef', 'IsLoad', 'IsStore'), 4), + + #Program Counter Operands + 'NPC': ('NPC', 'uw', None, ( None, None, 'IsControl' ), 4), + 'NNPC':('NNPC', 'uw', None, ( None, None, 'IsControl' ), 4) +}}; diff --git a/src/arch/mips/isa_traits.cc b/src/arch/mips/isa_traits.cc new file mode 100644 index 000000000..9f3817a60 --- /dev/null +++ b/src/arch/mips/isa_traits.cc @@ -0,0 +1,163 @@ +/* + * 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 + */ + +#include "arch/mips/isa_traits.hh" +#include "config/full_system.hh" +#include "cpu/static_inst.hh" +#include "sim/serialize.hh" +#include "base/bitfield.hh" + +using namespace MipsISA; +using namespace std; + + +void +MipsISA::copyRegs(ThreadContext *src, ThreadContext *dest) +{ + panic("Copy Regs Not Implemented Yet\n"); + /*fpcr = xc->readMiscReg(MipsISA::Fpcr_DepTag); + uniq = xc->readMiscReg(MipsISA::Uniq_DepTag); + lock_flag = xc->readMiscReg(MipsISA::Lock_Flag_DepTag); + lock_addr = xc->readMiscReg(MipsISA::Lock_Addr_DepTag); + +#if FULL_SYSTEM + copyIprs(xc); + #endif*/ +} + +void +MipsISA::MiscRegFile::copyMiscRegs(ThreadContext *tc) +{ + panic("Copy Misc. Regs Not Implemented Yet\n"); + /*fpcr = xc->readMiscReg(MipsISA::Fpcr_DepTag); + uniq = xc->readMiscReg(MipsISA::Uniq_DepTag); + lock_flag = xc->readMiscReg(MipsISA::Lock_Flag_DepTag); + lock_addr = xc->readMiscReg(MipsISA::Lock_Addr_DepTag); + + #endif*/ +} + +#if FULL_SYSTEM + +static inline Addr +TruncPage(Addr addr) +{ return addr & ~(MipsISA::PageBytes - 1); } + +static inline Addr +RoundPage(Addr addr) +{ return (addr + MipsISA::PageBytes - 1) & ~(MipsISA::PageBytes - 1); } +#endif + +void +IntRegFile::serialize(std::ostream &os) +{ + SERIALIZE_ARRAY(regs, NumIntRegs); +} + +void +IntRegFile::unserialize(Checkpoint *cp, const std::string §ion) +{ + UNSERIALIZE_ARRAY(regs, NumIntRegs); +} + +void +RegFile::serialize(std::ostream &os) +{ + intRegFile.serialize(os); + //SERIALIZE_ARRAY(floatRegFile.q, NumFloatRegs); + //SERIALIZE_SCALAR(miscRegs.fpcr); + //SERIALIZE_SCALAR(miscRegs.uniq); + //SERIALIZE_SCALAR(miscRegs.lock_flag); + //SERIALIZE_SCALAR(miscRegs.lock_addr); + SERIALIZE_SCALAR(pc); + SERIALIZE_SCALAR(npc); + SERIALIZE_SCALAR(nnpc); +#if FULL_SYSTEM + SERIALIZE_ARRAY(palregs, NumIntRegs); + SERIALIZE_ARRAY(ipr, NumInternalProcRegs); + SERIALIZE_SCALAR(intrflag); + SERIALIZE_SCALAR(pal_shadow); +#endif +} + + +void +RegFile::unserialize(Checkpoint *cp, const std::string §ion) +{ + intRegFile.unserialize(cp, section); + //UNSERIALIZE_ARRAY(floatRegFile.q, NumFloatRegs); + //UNSERIALIZE_SCALAR(miscRegs.fpcr); + //UNSERIALIZE_SCALAR(miscRegs.uniq); + //UNSERIALIZE_SCALAR(miscRegs.lock_flag); + //UNSERIALIZE_SCALAR(miscRegs.lock_addr); + UNSERIALIZE_SCALAR(pc); + UNSERIALIZE_SCALAR(npc); + UNSERIALIZE_SCALAR(nnpc); +#if FULL_SYSTEM + UNSERIALIZE_ARRAY(palregs, NumIntRegs); + UNSERIALIZE_ARRAY(ipr, NumInternalProcRegs); + UNSERIALIZE_SCALAR(intrflag); + UNSERIALIZE_SCALAR(pal_shadow); +#endif +} + + +#if FULL_SYSTEM +void +PTE::serialize(std::ostream &os) +{ + SERIALIZE_SCALAR(tag); + SERIALIZE_SCALAR(ppn); + SERIALIZE_SCALAR(xre); + SERIALIZE_SCALAR(xwe); + SERIALIZE_SCALAR(asn); + SERIALIZE_SCALAR(asma); + SERIALIZE_SCALAR(fonr); + SERIALIZE_SCALAR(fonw); + SERIALIZE_SCALAR(valid); +} + + +void +PTE::unserialize(Checkpoint *cp, const std::string §ion) +{ + UNSERIALIZE_SCALAR(tag); + UNSERIALIZE_SCALAR(ppn); + UNSERIALIZE_SCALAR(xre); + UNSERIALIZE_SCALAR(xwe); + UNSERIALIZE_SCALAR(asn); + UNSERIALIZE_SCALAR(asma); + UNSERIALIZE_SCALAR(fonr); + UNSERIALIZE_SCALAR(fonw); + UNSERIALIZE_SCALAR(valid); +} + +#endif //FULL_SYSTEM diff --git a/src/arch/mips/isa_traits.hh b/src/arch/mips/isa_traits.hh new file mode 100644 index 000000000..dc8b6758a --- /dev/null +++ b/src/arch/mips/isa_traits.hh @@ -0,0 +1,202 @@ +/* + * 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_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; + +namespace MIPS34K { +int DTB_ASN_ASN(uint64_t reg); +int ITB_ASN_ASN(uint64_t reg); +}; + +#if !FULL_SYSTEM +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; +}; +#endif + +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); + + uint64_t fpConvert(double fp_val, ConvertType cvt_type); + double roundFP(double val, int digits); + double truncFP(double val); + bool getFPConditionCode(uint32_t fcsr_reg, int cc); + uint32_t makeCCVector(uint32_t fcsr, int num, bool val); + + // Machine operations + + void saveMachineReg(AnyReg &savereg, const RegFile ®_file, + int regnum); + + void restoreMachineReg(RegFile ®s, const AnyReg ®, + int regnum); + +#if 0 + static void serializeSpecialRegs(const Serializable::Proxy &proxy, + const RegFile ®s); + + static void unserializeSpecialRegs(const IniFile *db, + const std::string &category, + ConfigNode *node, + RegFile ®s); +#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; + } + +}; + +#if FULL_SYSTEM + +#include "arch/mips/mips34k.hh" + +#endif + +using namespace MipsISA; + +#endif // __ARCH_MIPS_ISA_TRAITS_HH__ diff --git a/src/arch/mips/linux/linux.cc b/src/arch/mips/linux/linux.cc new file mode 100644 index 000000000..26e3dd479 --- /dev/null +++ b/src/arch/mips/linux/linux.cc @@ -0,0 +1,72 @@ +/* + * 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 + */ + +#include "arch/mips/linux/linux.hh" + +// open(2) flags translation table +OpenFlagTransTable MipsLinux::openFlagTable[] = { +#ifdef _MSC_VER + { MipsLinux::TGT_O_RDONLY, _O_RDONLY }, + { MipsLinux::TGT_O_WRONLY, _O_WRONLY }, + { MipsLinux::TGT_O_RDWR, _O_RDWR }, + { MipsLinux::TGT_O_APPEND, _O_APPEND }, + { MipsLinux::TGT_O_CREAT, _O_CREAT }, + { MipsLinux::TGT_O_TRUNC, _O_TRUNC }, + { MipsLinux::TGT_O_EXCL, _O_EXCL }, +#ifdef _O_NONBLOCK + { MipsLinux::TGT_O_NONBLOCK, _O_NONBLOCK }, +#endif +#ifdef _O_NOCTTY + { MipsLinux::TGT_O_NOCTTY, _O_NOCTTY }, +#endif +#ifdef _O_SYNC + { MipsLinux::TGT_O_SYNC, _O_SYNC }, +#endif +#else /* !_MSC_VER */ + { MipsLinux::TGT_O_RDONLY, O_RDONLY }, + { MipsLinux::TGT_O_WRONLY, O_WRONLY }, + { MipsLinux::TGT_O_RDWR, O_RDWR }, + { MipsLinux::TGT_O_APPEND, O_APPEND }, + { MipsLinux::TGT_O_CREAT, O_CREAT }, + { MipsLinux::TGT_O_TRUNC, O_TRUNC }, + { MipsLinux::TGT_O_EXCL, O_EXCL }, + { MipsLinux::TGT_O_NONBLOCK, O_NONBLOCK }, + { MipsLinux::TGT_O_NOCTTY, O_NOCTTY }, +#ifdef O_SYNC + { MipsLinux::TGT_O_SYNC, O_SYNC }, +#endif +#endif /* _MSC_VER */ +}; + +const int MipsLinux::NUM_OPEN_FLAGS = + (sizeof(MipsLinux::openFlagTable)/sizeof(MipsLinux::openFlagTable[0])); + + + diff --git a/src/arch/mips/linux/linux.hh b/src/arch/mips/linux/linux.hh new file mode 100644 index 000000000..f85935bb9 --- /dev/null +++ b/src/arch/mips/linux/linux.hh @@ -0,0 +1,126 @@ +/* + * 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_LINUX_LINUX_HH__ +#define __ARCH_MIPS_LINUX_LINUX_HH__ + +#include "kern/linux/linux.hh" + +class MipsLinux : public Linux +{ + public: + + /// This table maps the target open() flags to the corresponding + /// host open() flags. + static OpenFlagTransTable openFlagTable[]; + + /// Number of entries in openFlagTable[]. + static const int NUM_OPEN_FLAGS; + + //@{ + /// open(2) flag values. + static const int TGT_O_RDONLY = 0x00000000; //!< O_RDONLY + static const int TGT_O_WRONLY = 0x00000001; //!< O_WRONLY + static const int TGT_O_RDWR = 0x00000002; //!< O_RDWR + static const int TGT_O_NONBLOCK = 0x00000080; //!< O_NONBLOCK + static const int TGT_O_APPEND = 0x00000008; //!< O_APPEND + static const int TGT_O_CREAT = 0x00000100; //!< O_CREAT + static const int TGT_O_TRUNC = 0x00000200; //!< O_TRUNC + static const int TGT_O_EXCL = 0x00000400; //!< O_EXCL + static const int TGT_O_NOCTTY = 0x00000800; //!< O_NOCTTY + static const int TGT_O_SYNC = 0x00000010; //!< O_SYNC + static const int TGT_O_DRD = 0x00010000; //!< O_DRD + static const int TGT_O_DIRECTIO = 0x00020000; //!< O_DIRECTIO + static const int TGT_O_CACHE = 0x00002000; //!< O_CACHE + static const int TGT_O_DSYNC = 0x00008000; //!< O_DSYNC + static const int TGT_O_RSYNC = 0x00040000; //!< O_RSYNC + //@} + + /// For mmap(). + static const unsigned TGT_MAP_ANONYMOUS = 0x800; + + //@{ + /// For getsysinfo(). + static const unsigned GSI_PLATFORM_NAME = 103; //!< platform name as string + static const unsigned GSI_CPU_INFO = 59; //!< CPU information + static const unsigned GSI_PROC_TYPE = 60; //!< get proc_type + static const unsigned GSI_MAX_CPU = 30; //!< max # cpu's on this machine + static const unsigned GSI_CPUS_IN_BOX = 55; //!< number of CPUs in system + static const unsigned GSI_PHYSMEM = 19; //!< Physical memory in KB + static const unsigned GSI_CLK_TCK = 42; //!< clock freq in Hz + //@} + + //@{ + /// For getrusage(). + static const int TGT_RUSAGE_SELF = 0; + static const int TGT_RUSAGE_CHILDREN = -1; + static const int TGT_RUSAGE_BOTH = -2; + //@} + + //@{ + /// For setsysinfo(). + static const unsigned SSI_IEEE_FP_CONTROL = 14; //!< ieee_set_fp_control() + //@} + + //@{ + /// ioctl() command codes. + static const unsigned TIOCGETP = 0x7408; + static const unsigned TIOCSETP = 0x7409; + static const unsigned TIOCSETN = 0x740a; + static const unsigned TIOCSETC = 0x7411; + static const unsigned TIOCGETC = 0x7412; + static const unsigned FIONREAD = 0x467f; + static const unsigned TIOCISATTY = 0x5480; + static const unsigned TIOCGETS = 0x7413; + static const unsigned TIOCGETA = 0x7417; + //@} + + /// For table(). + static const int TBL_SYSINFO = 12; + + /// Resource enumeration for getrlimit(). + enum rlimit_resources { + TGT_RLIMIT_CPU = 0, + TGT_RLIMIT_FSIZE = 1, + TGT_RLIMIT_DATA = 2, + TGT_RLIMIT_STACK = 3, + TGT_RLIMIT_CORE = 4, + TGT_RLIMIT_NOFILE = 5, + TGT_RLIMIT_AS = 6, + TGT_RLIMIT_RSS = 7, + TGT_RLIMIT_VMEM = 7, + TGT_RLIMIT_NPROC = 8, + TGT_RLIMIT_MEMLOCK = 9, + TGT_RLIMIT_LOCKS = 10 + }; + +}; + +#endif diff --git a/src/arch/mips/linux/process.cc b/src/arch/mips/linux/process.cc new file mode 100644 index 000000000..17e735527 --- /dev/null +++ b/src/arch/mips/linux/process.cc @@ -0,0 +1,429 @@ +/* + * 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: Korey Sewell + */ + +#include "arch/mips/linux/linux.hh" +#include "arch/mips/linux/process.hh" +#include "arch/mips/isa_traits.hh" + +#include "base/trace.hh" +#include "cpu/thread_context.hh" +#include "kern/linux/linux.hh" + +#include "sim/process.hh" +#include "sim/syscall_emul.hh" + +using namespace std; +using namespace MipsISA; + +/// Target uname() handler. +static SyscallReturn +unameFunc(SyscallDesc *desc, int callnum, Process *process, + ThreadContext *tc) +{ + TypedBufferArg<Linux::utsname> name(tc->getSyscallArg(0)); + + strcpy(name->sysname, "Linux"); + strcpy(name->nodename, "m5.eecs.umich.edu"); + strcpy(name->release, "2.4.20"); + strcpy(name->version, "#1 Mon Aug 18 11:32:15 EDT 2003"); + strcpy(name->machine, "mips"); + + name.copyOut(tc->getMemPort()); + return 0; +} + +/// Target sys_getsysyinfo() handler. Even though this call is +/// borrowed from Tru64, the subcases that get used appear to be +/// different in practice from those used by Tru64 processes. +static SyscallReturn +sys_getsysinfoFunc(SyscallDesc *desc, int callnum, Process *process, + ThreadContext *tc) +{ + unsigned op = tc->getSyscallArg(0); + // unsigned nbytes = tc->getSyscallArg(2); + + switch (op) { + + case 45: { // GSI_IEEE_FP_CONTROL + TypedBufferArg<uint64_t> fpcr(tc->getSyscallArg(1)); + // I don't think this exactly matches the HW FPCR + *fpcr = 0; + fpcr.copyOut(tc->getMemPort()); + return 0; + } + + default: + cerr << "sys_getsysinfo: unknown op " << op << endl; + abort(); + break; + } + + return 1; +} + +/// Target sys_setsysinfo() handler. +static SyscallReturn +sys_setsysinfoFunc(SyscallDesc *desc, int callnum, Process *process, + ThreadContext *tc) +{ + unsigned op = tc->getSyscallArg(0); + // unsigned nbytes = tc->getSyscallArg(2); + + switch (op) { + + case 14: { // SSI_IEEE_FP_CONTROL + TypedBufferArg<uint64_t> fpcr(tc->getSyscallArg(1)); + // I don't think this exactly matches the HW FPCR + fpcr.copyIn(tc->getMemPort()); + DPRINTFR(SyscallVerbose, "sys_setsysinfo(SSI_IEEE_FP_CONTROL): " + " setting FPCR to 0x%x\n", gtoh(*(uint64_t*)fpcr)); + return 0; + } + + default: + cerr << "sys_setsysinfo: unknown op " << op << endl; + abort(); + break; + } + + return 1; +} + + +SyscallDesc MipsLinuxProcess::syscallDescs[] = { + /* 0 */ SyscallDesc("syscall", unimplementedFunc), + /* 1 */ SyscallDesc("exit", exitFunc), + /* 2 */ SyscallDesc("fork", unimplementedFunc), + /* 3 */ SyscallDesc("read", readFunc), + /* 4 */ SyscallDesc("write", writeFunc), + /* 5 */ SyscallDesc("open", openFunc<MipsLinux>), + /* 6 */ SyscallDesc("close", closeFunc), + /* 7 */ SyscallDesc("waitpid", unimplementedFunc), + /* 8 */ SyscallDesc("creat", unimplementedFunc), + /* 9 */ SyscallDesc("link", unimplementedFunc), + /* 10 */ SyscallDesc("unlink", unlinkFunc), + /* 11 */ SyscallDesc("execve", unimplementedFunc), + /* 12 */ SyscallDesc("chdir", unimplementedFunc), + /* 13 */ SyscallDesc("time", unimplementedFunc), + /* 14 */ SyscallDesc("mknod", unimplementedFunc), + /* 15 */ SyscallDesc("chmod", chmodFunc<MipsLinux>), + /* 16 */ SyscallDesc("lchown", chownFunc), + /* 17 */ SyscallDesc("break", obreakFunc), + /* 18 */ SyscallDesc("unused#18", unimplementedFunc), + /* 19 */ SyscallDesc("lseek", lseekFunc), + /* 20 */ SyscallDesc("getpid", getpidFunc), + /* 21 */ SyscallDesc("mount", unimplementedFunc), + /* 22 */ SyscallDesc("umount", unimplementedFunc), + /* 23 */ SyscallDesc("setuid", setuidFunc), + /* 24 */ SyscallDesc("getuid", getuidFunc), + /* 25 */ SyscallDesc("stime", unimplementedFunc), + /* 26 */ SyscallDesc("ptrace", unimplementedFunc), + /* 27 */ SyscallDesc("alarm", unimplementedFunc), + /* 28 */ SyscallDesc("unused#28", unimplementedFunc), + /* 29 */ SyscallDesc("pause", unimplementedFunc), + /* 30 */ SyscallDesc("utime", unimplementedFunc), + /* 31 */ SyscallDesc("stty", unimplementedFunc), + /* 32 */ SyscallDesc("gtty", unimplementedFunc), + /* 33 */ SyscallDesc("access", unimplementedFunc), + /* 34 */ SyscallDesc("nice", unimplementedFunc), + /* 35 */ SyscallDesc("ftime", unimplementedFunc), + /* 36 */ SyscallDesc("sync", unimplementedFunc), + /* 37 */ SyscallDesc("kill", ignoreFunc), + /* 38 */ SyscallDesc("rename", unimplementedFunc), + /* 39 */ SyscallDesc("mkdir", unimplementedFunc), + /* 40 */ SyscallDesc("rmdir", unimplementedFunc), + /* 41 */ SyscallDesc("dup", unimplementedFunc), + /* 42 */ SyscallDesc("pipe", unimplementedFunc), + /* 43 */ SyscallDesc("times", unimplementedFunc), + /* 44 */ SyscallDesc("prof", unimplementedFunc), + /* 45 */ SyscallDesc("brk", obreakFunc), + /* 46 */ SyscallDesc("setgid", unimplementedFunc), + /* 47 */ SyscallDesc("getgid", getgidFunc), + /* 48 */ SyscallDesc("signal", ignoreFunc), + /* 49 */ SyscallDesc("geteuid", geteuidFunc), + /* 50 */ SyscallDesc("getegid", getegidFunc), + /* 51 */ SyscallDesc("acct", unimplementedFunc), + /* 52 */ SyscallDesc("umount2", unimplementedFunc), + /* 53 */ SyscallDesc("lock", unimplementedFunc), + /* 54 */ SyscallDesc("ioctl", ioctlFunc<MipsLinux>), + /* 55 */ SyscallDesc("fcntl", fcntlFunc), + /* 56 */ SyscallDesc("mpx", unimplementedFunc), + /* 57 */ SyscallDesc("setpgid", unimplementedFunc), + /* 58 */ SyscallDesc("ulimit", unimplementedFunc), + /* 59 */ SyscallDesc("unused#59", unimplementedFunc), + /* 60 */ SyscallDesc("umask", unimplementedFunc), + /* 61 */ SyscallDesc("chroot", unimplementedFunc), + /* 62 */ SyscallDesc("ustat", unimplementedFunc), + /* 63 */ SyscallDesc("dup2", unimplementedFunc), + /* 64 */ SyscallDesc("getppid", getpagesizeFunc), + /* 65 */ SyscallDesc("getpgrp", unimplementedFunc), + /* 66 */ SyscallDesc("setsid", unimplementedFunc), + /* 67 */ SyscallDesc("sigaction",unimplementedFunc), + /* 68 */ SyscallDesc("sgetmask", unimplementedFunc), + /* 69 */ SyscallDesc("ssetmask", unimplementedFunc), + /* 70 */ SyscallDesc("setreuid", unimplementedFunc), + /* 71 */ SyscallDesc("setregid", unimplementedFunc), + /* 72 */ SyscallDesc("sigsuspend", unimplementedFunc), + /* 73 */ SyscallDesc("sigpending", unimplementedFunc), + /* 74 */ SyscallDesc("sethostname", ignoreFunc), + /* 75 */ SyscallDesc("setrlimit", unimplementedFunc), + /* 76 */ SyscallDesc("getrlimit", unimplementedFunc), + /* 77 */ SyscallDesc("getrusage", unimplementedFunc), + /* 78 */ SyscallDesc("gettimeofday", unimplementedFunc), + /* 79 */ SyscallDesc("settimeofday", unimplementedFunc), + /* 80 */ SyscallDesc("getgroups", unimplementedFunc), + /* 81 */ SyscallDesc("setgroups", unimplementedFunc), + /* 82 */ SyscallDesc("reserved#82", unimplementedFunc), + /* 83 */ SyscallDesc("symlink", unimplementedFunc), + /* 84 */ SyscallDesc("unused#84", unimplementedFunc), + /* 85 */ SyscallDesc("readlink", unimplementedFunc), + /* 86 */ SyscallDesc("uselib", unimplementedFunc), + /* 87 */ SyscallDesc("swapon", gethostnameFunc), + /* 88 */ SyscallDesc("reboot", unimplementedFunc), + /* 89 */ SyscallDesc("readdir", unimplementedFunc), + /* 90 */ SyscallDesc("mmap", mmapFunc<MipsLinux>), + /* 91 */ SyscallDesc("munmap",munmapFunc), + /* 92 */ SyscallDesc("truncate", truncateFunc), + /* 93 */ SyscallDesc("ftruncate", ftruncateFunc), + /* 94 */ SyscallDesc("fchmod", unimplementedFunc), + /* 95 */ SyscallDesc("fchown", unimplementedFunc), + /* 96 */ SyscallDesc("getpriority", unimplementedFunc), + /* 97 */ SyscallDesc("setpriority", unimplementedFunc), + /* 98 */ SyscallDesc("profil", unimplementedFunc), + /* 99 */ SyscallDesc("statfs", unimplementedFunc), + /* 100 */ SyscallDesc("fstatfs", unimplementedFunc), + /* 101 */ SyscallDesc("ioperm", unimplementedFunc), + /* 102 */ SyscallDesc("socketcall", unimplementedFunc), + /* 103 */ SyscallDesc("syslog", unimplementedFunc), + /* 104 */ SyscallDesc("setitimer", unimplementedFunc), + /* 105 */ SyscallDesc("getitimer", unimplementedFunc), + /* 106 */ SyscallDesc("stat", statFunc<MipsLinux>), + /* 107 */ SyscallDesc("lstat", unimplementedFunc), + /* 108 */ SyscallDesc("fstat", fstatFunc<MipsLinux>), + /* 109 */ SyscallDesc("unused#109", unimplementedFunc), + /* 110 */ SyscallDesc("iopl", unimplementedFunc), + /* 111 */ SyscallDesc("vhangup", unimplementedFunc), + /* 112 */ SyscallDesc("idle", ignoreFunc), + /* 113 */ SyscallDesc("vm86", unimplementedFunc), + /* 114 */ SyscallDesc("wait4", unimplementedFunc), + /* 115 */ SyscallDesc("swapoff", unimplementedFunc), + /* 116 */ SyscallDesc("sysinfo", unimplementedFunc), + /* 117 */ SyscallDesc("ipc", unimplementedFunc), + /* 118 */ SyscallDesc("fsync", unimplementedFunc), + /* 119 */ SyscallDesc("sigreturn", unimplementedFunc), + /* 120 */ SyscallDesc("clone", unimplementedFunc), + /* 121 */ SyscallDesc("setdomainname", unimplementedFunc), + /* 122 */ SyscallDesc("uname", unameFunc), + /* 123 */ SyscallDesc("modify_ldt", unimplementedFunc), + /* 124 */ SyscallDesc("adjtimex", unimplementedFunc), + /* 125 */ SyscallDesc("mprotect", ignoreFunc), + /* 126 */ SyscallDesc("sigprocmask", unimplementedFunc), + /* 127 */ SyscallDesc("create_module", unimplementedFunc), + /* 128 */ SyscallDesc("init_module", unimplementedFunc), + /* 129 */ SyscallDesc("delete_module", unimplementedFunc), + /* 130 */ SyscallDesc("get_kernel_syms", unimplementedFunc), + /* 131 */ SyscallDesc("quotactl", unimplementedFunc), + /* 132 */ SyscallDesc("getpgid", unimplementedFunc), + /* 133 */ SyscallDesc("fchdir", unimplementedFunc), + /* 134 */ SyscallDesc("bdflush", unimplementedFunc), + /* 135 */ SyscallDesc("sysfs", unimplementedFunc), + /* 136 */ SyscallDesc("personality", unimplementedFunc), + /* 137 */ SyscallDesc("afs_syscall", unimplementedFunc), + /* 138 */ SyscallDesc("setfsuid", unimplementedFunc), + /* 139 */ SyscallDesc("setfsgid", unimplementedFunc), + /* 140 */ SyscallDesc("llseek", unimplementedFunc), + /* 141 */ SyscallDesc("getdents", unimplementedFunc), + /* 142 */ SyscallDesc("newselect", unimplementedFunc), + /* 143 */ SyscallDesc("flock", unimplementedFunc), + /* 144 */ SyscallDesc("msync", unimplementedFunc), + /* 145 */ SyscallDesc("readv", unimplementedFunc), + /* 146 */ SyscallDesc("writev", writevFunc<MipsLinux>), + /* 147 */ SyscallDesc("cacheflush", unimplementedFunc), + /* 148 */ SyscallDesc("cachectl", unimplementedFunc), + /* 149 */ SyscallDesc("sysmips", unimplementedFunc), + /* 150 */ SyscallDesc("unused#150", unimplementedFunc), + /* 151 */ SyscallDesc("getsid", unimplementedFunc), + /* 152 */ SyscallDesc("fdatasync", unimplementedFunc), + /* 153 */ SyscallDesc("sysctl", unimplementedFunc), + /* 154 */ SyscallDesc("mlock", unimplementedFunc), + /* 155 */ SyscallDesc("munlock", unimplementedFunc), + /* 156 */ SyscallDesc("mlockall", unimplementedFunc), + /* 157 */ SyscallDesc("munlockall", unimplementedFunc), + /* 158 */ SyscallDesc("sched_setparam", unimplementedFunc), + /* 159 */ SyscallDesc("sched_getparam", unimplementedFunc), + /* 160 */ SyscallDesc("sched_setscheduler", unimplementedFunc), + /* 161 */ SyscallDesc("sched_getscheduler", unimplementedFunc), + /* 162 */ SyscallDesc("sched_yield", unimplementedFunc), + /* 163 */ SyscallDesc("sched_get_prioritymax", unimplementedFunc), + /* 164 */ SyscallDesc("sched_get_priority_min", unimplementedFunc), + /* 165 */ SyscallDesc("sched_rr_get_interval", unimplementedFunc), + /* 166 */ SyscallDesc("nanosleep", unimplementedFunc), + /* 167 */ SyscallDesc("mremap", unimplementedFunc), + /* 168 */ SyscallDesc("accept", unimplementedFunc), + /* 169 */ SyscallDesc("bind", unimplementedFunc), + /* 170 */ SyscallDesc("connect", unimplementedFunc), + /* 171 */ SyscallDesc("getpeername", unimplementedFunc), + /* 172 */ SyscallDesc("getsockname", unimplementedFunc), + /* 173 */ SyscallDesc("getsockopt", unimplementedFunc), + /* 174 */ SyscallDesc("listen", unimplementedFunc), + /* 175 */ SyscallDesc("recv", unimplementedFunc), + /* 176 */ SyscallDesc("recvmsg", unimplementedFunc), + /* 177 */ SyscallDesc("send", unimplementedFunc), + /* 178 */ SyscallDesc("sendmsg", ignoreFunc), + /* 179 */ SyscallDesc("sendto", unimplementedFunc), + /* 180 */ SyscallDesc("setsockopt", unimplementedFunc), + /* 181 */ SyscallDesc("shutdown", unimplementedFunc), + /* 182 */ SyscallDesc("unknown #182", unimplementedFunc), + /* 183 */ SyscallDesc("socket", ignoreFunc), + /* 184 */ SyscallDesc("socketpair", unimplementedFunc), + /* 185 */ SyscallDesc("setresuid", unimplementedFunc), + /* 186 */ SyscallDesc("getresuid", unimplementedFunc), + /* 187 */ SyscallDesc("query_module", unimplementedFunc), + /* 188 */ SyscallDesc("poll", unimplementedFunc), + /* 189 */ SyscallDesc("nfsservctl", unimplementedFunc), + /* 190 */ SyscallDesc("setresgid", unimplementedFunc), + /* 191 */ SyscallDesc("getresgid", unimplementedFunc), + /* 192 */ SyscallDesc("prctl", unimplementedFunc), + /* 193 */ SyscallDesc("rt_sigreturn", unimplementedFunc), + /* 194 */ SyscallDesc("rt_sigaction", ignoreFunc), + /* 195 */ SyscallDesc("rt_sigprocmask", ignoreFunc), + /* 196 */ SyscallDesc("rt_sigpending", unimplementedFunc), + /* 197 */ SyscallDesc("rt_sigtimedwait", unimplementedFunc), + /* 198 */ SyscallDesc("rt_sigqueueinfo", ignoreFunc), + /* 199 */ SyscallDesc("rt_sigsuspend", unimplementedFunc), + /* 200 */ SyscallDesc("pread64", unimplementedFunc), + /* 201 */ SyscallDesc("pwrite64", unimplementedFunc), + /* 202 */ SyscallDesc("chown", unimplementedFunc), + /* 203 */ SyscallDesc("getcwd", unimplementedFunc), + /* 204 */ SyscallDesc("capget", unimplementedFunc), + /* 205 */ SyscallDesc("capset", unimplementedFunc), + /* 206 */ SyscallDesc("sigalstack", unimplementedFunc), + /* 207 */ SyscallDesc("sendfile", unimplementedFunc), + /* 208 */ SyscallDesc("getpmsg", unimplementedFunc), + /* 209 */ SyscallDesc("putpmsg", unimplementedFunc), + /* 210 */ SyscallDesc("mmap2", unimplementedFunc), + /* 211 */ SyscallDesc("truncate64", unimplementedFunc), + /* 212 */ SyscallDesc("ftruncate64", unimplementedFunc), + /* 213 */ SyscallDesc("stat64", unimplementedFunc), + /* 214 */ SyscallDesc("lstat64", lstat64Func<MipsLinux>), + /* 215 */ SyscallDesc("fstat64", fstat64Func<MipsLinux>), + /* 216 */ SyscallDesc("pivot_root", unimplementedFunc), + /* 217 */ SyscallDesc("mincore", unimplementedFunc), + /* 218 */ SyscallDesc("madvise", unimplementedFunc), + /* 219 */ SyscallDesc("getdents64", unimplementedFunc), + /* 220 */ SyscallDesc("fcntl64", fcntl64Func), + /* 221 */ SyscallDesc("reserved#221", unimplementedFunc), + /* 222 */ SyscallDesc("gettid", unimplementedFunc), + /* 223 */ SyscallDesc("readahead", unimplementedFunc), + /* 224 */ SyscallDesc("setxattr", unimplementedFunc), + /* 225 */ SyscallDesc("lsetxattr", unimplementedFunc), + /* 226 */ SyscallDesc("fsetxattr", unimplementedFunc), + /* 227 */ SyscallDesc("getxattr", unimplementedFunc), + /* 228 */ SyscallDesc("lgetxattr", unimplementedFunc), + /* 229 */ SyscallDesc("fgetxattr", unimplementedFunc), + /* 230 */ SyscallDesc("listxattr", unimplementedFunc), + /* 231 */ SyscallDesc("llistxattr", unimplementedFunc), + /* 232 */ SyscallDesc("flistxattr", unimplementedFunc), + /* 233 */ SyscallDesc("removexattr", unimplementedFunc), + /* 234 */ SyscallDesc("lremovexattr", unimplementedFunc), + /* 235 */ SyscallDesc("fremovexattr", ignoreFunc), + /* 236 */ SyscallDesc("tkill", unimplementedFunc), + /* 237 */ SyscallDesc("sendfile64", unimplementedFunc), + /* 238 */ SyscallDesc("futex", unimplementedFunc), + /* 239 */ SyscallDesc("sched_setaffinity", unimplementedFunc), + /* 240 */ SyscallDesc("sched_getaffinity", unimplementedFunc), + /* 241 */ SyscallDesc("io_setup", unimplementedFunc), + /* 242 */ SyscallDesc("io_destroy", unimplementedFunc), + /* 243 */ SyscallDesc("io_getevents", unimplementedFunc), + /* 244 */ SyscallDesc("io_submit", unimplementedFunc), + /* 245 */ SyscallDesc("io_cancel", unimplementedFunc), + /* 246 */ SyscallDesc("exit_group", exitFunc), + /* 247 */ SyscallDesc("lookup_dcookie", unimplementedFunc), + /* 248 */ SyscallDesc("epoll_create", unimplementedFunc), + /* 249 */ SyscallDesc("epoll_ctl", unimplementedFunc), + /* 250 */ SyscallDesc("epoll_wait", unimplementedFunc), + /* 251 */ SyscallDesc("remap_file_pages", unimplementedFunc), + /* 252 */ SyscallDesc("set_tid_address", unimplementedFunc), + /* 253 */ SyscallDesc("restart_syscall", unimplementedFunc), + /* 254 */ SyscallDesc("fadvise64", unimplementedFunc), + /* 255 */ SyscallDesc("statfs64", unimplementedFunc), + /* 256 */ SyscallDesc("fstafs64", unimplementedFunc), + /* 257 */ SyscallDesc("timer_create", sys_getsysinfoFunc), + /* 258 */ SyscallDesc("timer_settime", sys_setsysinfoFunc), + /* 259 */ SyscallDesc("timer_gettime", unimplementedFunc), + /* 260 */ SyscallDesc("timer_getoverrun", unimplementedFunc), + /* 261 */ SyscallDesc("timer_delete", unimplementedFunc), + /* 262 */ SyscallDesc("clock_settime", unimplementedFunc), + /* 263 */ SyscallDesc("clock_gettime", unimplementedFunc), + /* 264 */ SyscallDesc("clock_getres", unimplementedFunc), + /* 265 */ SyscallDesc("clock_nanosleep", unimplementedFunc), + /* 266 */ SyscallDesc("tgkill", unimplementedFunc), + /* 267 */ SyscallDesc("utimes", unimplementedFunc), + /* 268 */ SyscallDesc("mbind", unimplementedFunc), + /* 269 */ SyscallDesc("get_mempolicy", unimplementedFunc), + /* 270 */ SyscallDesc("set_mempolicy", unimplementedFunc), + /* 271 */ SyscallDesc("mq_open", unimplementedFunc), + /* 272 */ SyscallDesc("mq_unlink", unimplementedFunc), + /* 273 */ SyscallDesc("mq_timedsend", unimplementedFunc), + /* 274 */ SyscallDesc("mq_timedreceive", unimplementedFunc), + /* 275 */ SyscallDesc("mq_notify", unimplementedFunc), + /* 276 */ SyscallDesc("mq_getsetattr", unimplementedFunc), + /* 277 */ SyscallDesc("vserver", unimplementedFunc), + /* 278 */ SyscallDesc("waitid", unimplementedFunc), + /* 279 */ SyscallDesc("unknown #279", unimplementedFunc), + /* 280 */ SyscallDesc("add_key", unimplementedFunc), + /* 281 */ SyscallDesc("request_key", unimplementedFunc), + /* 282 */ SyscallDesc("keyctl", unimplementedFunc), +}; + +MipsLinuxProcess::MipsLinuxProcess(const std::string &name, + ObjectFile *objFile, + System *system, + int stdin_fd, + int stdout_fd, + int stderr_fd, + std::vector<std::string> &argv, + std::vector<std::string> &envp) + : MipsLiveProcess(name, objFile, system, stdin_fd, stdout_fd, stderr_fd, + argv, envp), + Num_Syscall_Descs(sizeof(syscallDescs) / sizeof(SyscallDesc)) +{ } + +SyscallDesc* +MipsLinuxProcess::getDesc(int callnum) +{ + //MIPS32 syscalls are in the range of 4000 - 4999 + int m5_sys_idx = callnum - 4000; + + if (m5_sys_idx < 0 || m5_sys_idx > Num_Syscall_Descs) + return NULL; + + return &syscallDescs[m5_sys_idx]; +} diff --git a/src/arch/mips/linux/process.hh b/src/arch/mips/linux/process.hh new file mode 100644 index 000000000..68da3227b --- /dev/null +++ b/src/arch/mips/linux/process.hh @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2003-2004 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 __MIPS_LINUX_PROCESS_HH__ +#define __MIPS_LINUX_PROCESS_HH__ + +#include "arch/mips/process.hh" + + +/// A process with emulated Mips/Linux syscalls. +class MipsLinuxProcess : public MipsLiveProcess +{ + public: + /// Constructor. + MipsLinuxProcess(const std::string &name, + ObjectFile *objFile, + System *system, + int stdin_fd, int stdout_fd, int stderr_fd, + std::vector<std::string> &argv, + std::vector<std::string> &envp); + + virtual SyscallDesc* getDesc(int callnum); + + /// The target system's hostname. + static const char *hostname; + + /// Array of syscall descriptors, indexed by call number. + static SyscallDesc syscallDescs[]; + + const int Num_Syscall_Descs; +}; + + +#endif // __MIPS_LINUX_PROCESS_HH__ diff --git a/src/arch/mips/process.cc b/src/arch/mips/process.cc new file mode 100644 index 000000000..6f2c88f69 --- /dev/null +++ b/src/arch/mips/process.cc @@ -0,0 +1,163 @@ +/* + * Copyright (c) 2003-2004 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 + * Korey Sewell + */ + +#include "arch/mips/isa_traits.hh" +#include "arch/mips/process.hh" +#include "arch/mips/linux/process.hh" +#include "base/loader/object_file.hh" +#include "base/misc.hh" +#include "cpu/thread_context.hh" +#include "sim/builder.hh" +#include "sim/system.hh" + +using namespace std; +using namespace MipsISA; + + +MipsLiveProcess * +MipsLiveProcess::create(const std::string &nm, System *system, int stdin_fd, + int stdout_fd, int stderr_fd, std::string executable, + std::vector<std::string> &argv, std::vector<std::string> &envp) +{ + MipsLiveProcess *process = NULL; + + ObjectFile *objFile = createObjectFile(executable); + if (objFile == NULL) { + fatal("Can't load object file %s", executable); + } + + + if (objFile->getArch() != ObjectFile::Mips) + fatal("Object file does not match MIPS architecture."); + + switch (objFile->getOpSys()) { + case ObjectFile::Linux: + process = new MipsLinuxProcess(nm, objFile, system, + stdin_fd, stdout_fd, stderr_fd, + argv, envp); + break; + + default: + fatal("Unknown/unsupported operating system."); + } + + if (process == NULL) + fatal("Unknown error creating process object."); + return process; +} + +MipsLiveProcess::MipsLiveProcess(const std::string &nm, ObjectFile *objFile, + System *_system, int stdin_fd, int stdout_fd, int stderr_fd, + std::vector<std::string> &argv, std::vector<std::string> &envp) + : LiveProcess(nm, objFile, _system, stdin_fd, stdout_fd, stderr_fd, + argv, envp) +{ + // Set up stack. On MIPS, stack starts at the top of kuseg + // user address space. MIPS stack grows down from here + stack_base = 0x7FFFFFFF; + + // Set pointer for next thread stack. Reserve 8M for main stack. + next_thread_stack_base = stack_base - (8 * 1024 * 1024); + + // Set up break point (Top of Heap) + brk_point = objFile->dataBase() + objFile->dataSize() + objFile->bssSize(); + brk_point = roundUp(brk_point, VMPageSize); + + // Set up region for mmaps. For now, start at bottom of kuseg space. + mmap_start = mmap_end = 0x10000; +} + +void +MipsLiveProcess::startup() +{ + argsInit(MachineBytes, VMPageSize); +} + + + + +BEGIN_DECLARE_SIM_OBJECT_PARAMS(MipsLiveProcess) + + VectorParam<string> cmd; + Param<string> executable; + Param<string> input; + Param<string> output; + VectorParam<string> env; + SimObjectParam<System *> system; + +END_DECLARE_SIM_OBJECT_PARAMS(MipsLiveProcess) + + +BEGIN_INIT_SIM_OBJECT_PARAMS(MipsLiveProcess) + + INIT_PARAM(cmd, "command line (executable plus arguments)"), + INIT_PARAM(executable, "executable (overrides cmd[0] if set)"), + INIT_PARAM(input, "filename for stdin (dflt: use sim stdin)"), + INIT_PARAM(output, "filename for stdout/stderr (dflt: use sim stdout)"), + INIT_PARAM(env, "environment settings"), + INIT_PARAM(system, "system") + +END_INIT_SIM_OBJECT_PARAMS(MipsLiveProcess) + + +CREATE_SIM_OBJECT(MipsLiveProcess) +{ + string in = input; + string out = output; + + // initialize file descriptors to default: same as simulator + int stdin_fd, stdout_fd, stderr_fd; + + if (in == "stdin" || in == "cin") + stdin_fd = STDIN_FILENO; + else + stdin_fd = Process::openInputFile(input); + + if (out == "stdout" || out == "cout") + stdout_fd = STDOUT_FILENO; + else if (out == "stderr" || out == "cerr") + stdout_fd = STDERR_FILENO; + else + stdout_fd = Process::openOutputFile(out); + + stderr_fd = (stdout_fd != STDOUT_FILENO) ? stdout_fd : STDERR_FILENO; + + return MipsLiveProcess::create(getInstanceName(), system, + stdin_fd, stdout_fd, stderr_fd, + (string)executable == "" ? cmd[0] : executable, + cmd, env); +} + + +REGISTER_SIM_OBJECT("MipsLiveProcess", MipsLiveProcess) + + diff --git a/src/arch/mips/process.hh b/src/arch/mips/process.hh new file mode 100644 index 000000000..dae891125 --- /dev/null +++ b/src/arch/mips/process.hh @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2003-2004 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 + * Korey Sewell + */ + +#ifndef __MIPS_PROCESS_HH__ +#define __MIPS_PROCESS_HH__ + +#include <string> +#include <vector> +#include "sim/process.hh" + +class LiveProcess; +class ObjectFile; +class System; + +class MipsLiveProcess : public LiveProcess +{ + protected: + MipsLiveProcess(const std::string &nm, ObjectFile *objFile, + System *_system, int stdin_fd, int stdout_fd, int stderr_fd, + std::vector<std::string> &argv, + std::vector<std::string> &envp); + + void startup(); + + public: + // this function is used to create the LiveProcess object, since + // we can't tell which subclass of LiveProcess to use until we + // open and look at the object file. + static MipsLiveProcess *create(const std::string &nm, + System *_system, + int stdin_fd, int stdout_fd, int stderr_fd, + std::string executable, + std::vector<std::string> &argv, + std::vector<std::string> &envp); + +}; + + +#endif // __MIPS_PROCESS_HH__ diff --git a/src/arch/mips/regfile/float_regfile.hh b/src/arch/mips/regfile/float_regfile.hh new file mode 100644 index 000000000..d1a60298a --- /dev/null +++ b/src/arch/mips/regfile/float_regfile.hh @@ -0,0 +1,160 @@ +/* + * 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: Korey Sewell + */ + +#ifndef __ARCH_MIPS_FLOAT_REGFILE_HH__ +#define __ARCH_MIPS_FLOAT_REGFILE_HH__ + +#include "arch/mips/types.hh" +#include "arch/mips/constants.hh" +#include "base/misc.hh" +#include "config/full_system.hh" +#include "sim/byteswap.hh" +#include "sim/faults.hh" +#include "sim/host.hh" + +class Checkpoint; +class ThreadContext; +class Regfile; + +namespace MipsISA +{ + class FloatRegFile + { + protected: + FloatReg32 regs[NumFloatRegs]; + + public: + + void clear() + { + bzero(regs, sizeof(regs)); + } + + double readReg(int floatReg, int width) + { + switch(width) + { + case SingleWidth: + { + void *float_ptr = ®s[floatReg]; + return *(float *) float_ptr; + } + + case DoubleWidth: + { + uint64_t double_val = (FloatReg64)regs[floatReg + 1] << 32 | regs[floatReg]; + void *double_ptr = &double_val; + return *(double *) double_ptr; + } + + default: + panic("Attempted to read a %d bit floating point register!", width); + } + } + + FloatRegBits readRegBits(int floatReg, int width) + { + if (floatReg < NumFloatArchRegs - 1) { + switch(width) + { + case SingleWidth: + return regs[floatReg]; + + case DoubleWidth: + return (FloatReg64)regs[floatReg + 1] << 32 | regs[floatReg]; + + default: + panic("Attempted to read a %d bit floating point register!", width); + } + } else { + if (width > SingleWidth) + assert("Control Regs are only 32 bits wide"); + + return regs[floatReg]; + } + } + + Fault setReg(int floatReg, const FloatReg &val, int width) + { + switch(width) + { + case SingleWidth: + { + float temp = val; + void *float_ptr = &temp; + regs[floatReg] = *(FloatReg32 *) float_ptr; + break; + } + + case DoubleWidth: + { + const void *double_ptr = &val; + FloatReg64 temp_double = *(FloatReg64 *) double_ptr; + regs[floatReg + 1] = temp_double >> 32; + regs[floatReg] = 0x0000FFFF & temp_double; + break; + } + + default: + panic("Attempted to read a %d bit floating point register!", width); + } + + return NoFault; + } + + Fault setRegBits(int floatReg, const FloatRegBits &val, int width) + { + using namespace std; + + switch(width) + { + case SingleWidth: + regs[floatReg] = val; + break; + + case DoubleWidth: + regs[floatReg + 1] = val >> 32; + regs[floatReg] = val; + break; + + default: + panic("Attempted to read a %d bit floating point register!", width); + } + return NoFault; + } + + void serialize(std::ostream &os); + + void unserialize(Checkpoint *cp, const std::string §ion); + }; + +} // namespace MipsISA + +#endif diff --git a/src/arch/mips/regfile/int_regfile.hh b/src/arch/mips/regfile/int_regfile.hh new file mode 100644 index 000000000..dc82a3c26 --- /dev/null +++ b/src/arch/mips/regfile/int_regfile.hh @@ -0,0 +1,75 @@ +/* + * 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: Korey Sewell + */ + +#ifndef __ARCH_MIPS_INT_REGFILE_HH__ +#define __ARCH_MIPS_INT_REGFILE_HH__ + +#include "arch/mips/types.hh" +#include "arch/mips/constants.hh" +#include "base/misc.hh" +#include "sim/faults.hh" + +class Checkpoint; +class ThreadContext; +class Regfile; + +namespace MipsISA +{ + class IntRegFile + { + protected: + IntReg regs[NumIntRegs]; + + public: + IntReg readReg(int intReg) + { + return regs[intReg]; + } + + Fault setReg(int intReg, const IntReg &val) + { + regs[intReg] = val; + return NoFault; + } + + void serialize(std::ostream &os); + + void unserialize(Checkpoint *cp, const std::string §ion); + + }; + + enum MiscIntRegNums { + HI = NumIntArchRegs, + LO + }; + +} // namespace MipsISA + +#endif diff --git a/src/arch/mips/regfile/misc_regfile.hh b/src/arch/mips/regfile/misc_regfile.hh new file mode 100644 index 000000000..f8aeab8cb --- /dev/null +++ b/src/arch/mips/regfile/misc_regfile.hh @@ -0,0 +1,98 @@ +/* + * 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: Korey Sewell + */ + +#ifndef __ARCH_MIPS_MISC_REGFILE_HH__ +#define __ARCH_MIPS_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 +{ + class MiscRegFile { + + protected: + uint64_t fpcr; // floating point condition codes + uint64_t uniq; // process-unique register + bool lock_flag; // lock flag for LL/SC + Addr lock_addr; // lock address for LL/SC + + MiscReg miscRegFile[NumMiscRegs]; + + public: + //These functions should be removed once the simplescalar cpu model + //has been replaced. + int getInstAsid(); + int getDataAsid(); + + void copyMiscRegs(ThreadContext *tc); + + MiscReg readReg(int misc_reg) + { + return miscRegFile[misc_reg]; + } + + MiscReg readRegWithEffect(int misc_reg, Fault &fault, ThreadContext *tc) + { + return miscRegFile[misc_reg]; + } + + Fault setReg(int misc_reg, const MiscReg &val) + { + miscRegFile[misc_reg] = val; return NoFault; + } + + Fault setRegWithEffect(int misc_reg, const MiscReg &val, + ThreadContext *tc) + { + miscRegFile[misc_reg] = val; return NoFault; + } + +#if FULL_SYSTEM + void clearIprs() { } + + protected: + InternalProcReg ipr[NumInternalProcRegs]; // Internal processor regs + + private: + MiscReg readIpr(int idx, Fault &fault, ThreadContext *tc) { } + + Fault setIpr(int idx, uint64_t val, ThreadContext *tc) { } +#endif + friend class RegFile; + }; +} // namespace MipsISA + +#endif diff --git a/src/arch/mips/regfile/regfile.hh b/src/arch/mips/regfile/regfile.hh new file mode 100644 index 000000000..af61e62cd --- /dev/null +++ b/src/arch/mips/regfile/regfile.hh @@ -0,0 +1,201 @@ +/* + * 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: Korey Sewell + */ + +#ifndef __ARCH_MIPS_REGFILE_HH__ +#define __ARCH_MIPS_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" +#include "sim/faults.hh" + +class Checkpoint; +class ThreadContext; + +namespace MipsISA +{ + class RegFile { + protected: + IntRegFile intRegFile; // (signed) integer register file + FloatRegFile floatRegFile; // floating point register file + MiscRegFile miscRegFile; // control register file + + public: + + void clear() + { + bzero(&intRegFile, sizeof(intRegFile)); + bzero(&floatRegFile, sizeof(floatRegFile)); + bzero(&miscRegFile, sizeof(miscRegFile)); + } + + MiscReg readMiscReg(int miscReg) + { + return miscRegFile.readReg(miscReg); + } + + MiscReg readMiscRegWithEffect(int miscReg, + Fault &fault, ThreadContext *tc) + { + fault = NoFault; + return miscRegFile.readRegWithEffect(miscReg, fault, tc); + } + + Fault setMiscReg(int miscReg, const MiscReg &val) + { + return miscRegFile.setReg(miscReg, val); + } + + Fault setMiscRegWithEffect(int miscReg, const MiscReg &val, + ThreadContext * tc) + { + return miscRegFile.setRegWithEffect(miscReg, val, tc); + } + + FloatReg readFloatReg(int floatReg) + { + return floatRegFile.readReg(floatReg,SingleWidth); + } + + FloatReg readFloatReg(int floatReg, int width) + { + return floatRegFile.readReg(floatReg,width); + } + + FloatRegBits readFloatRegBits(int floatReg) + { + return floatRegFile.readRegBits(floatReg,SingleWidth); + } + + FloatRegBits readFloatRegBits(int floatReg, int width) + { + return floatRegFile.readRegBits(floatReg,width); + } + + Fault setFloatReg(int floatReg, const FloatReg &val) + { + return floatRegFile.setReg(floatReg, val, SingleWidth); + } + + Fault setFloatReg(int floatReg, const FloatReg &val, int width) + { + return floatRegFile.setReg(floatReg, val, width); + } + + Fault setFloatRegBits(int floatReg, const FloatRegBits &val) + { + return floatRegFile.setRegBits(floatReg, val, SingleWidth); + } + + Fault setFloatRegBits(int floatReg, const FloatRegBits &val, int width) + { + return floatRegFile.setRegBits(floatReg, val, width); + } + + IntReg readIntReg(int intReg) + { + return intRegFile.readReg(intReg); + } + + Fault setIntReg(int intReg, const IntReg &val) + { + return intRegFile.setReg(intReg, val); + } + protected: + + Addr pc; // program counter + Addr npc; // next-cycle program counter + Addr nnpc; // next-next-cycle program counter + // used to implement branch delay slot + // not real register + 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; + } + + +#if FULL_SYSTEM + IntReg palregs[NumIntRegs]; // PAL shadow registers + InternalProcReg ipr[NumInternalProcRegs]; // internal processor regs + int intrflag; // interrupt flag + bool pal_shadow; // using pal_shadow registers + inline int instAsid() { return MIPS34K::ITB_ASN_ASN(ipr[IPR_ITB_ASN]); } + inline int dataAsid() { return MIPS34K::DTB_ASN_ASN(ipr[IPR_DTB_ASN]); } +#endif // FULL_SYSTEM + + void serialize(std::ostream &os); + void unserialize(Checkpoint *cp, const std::string §ion); + + typedef int ContextParam; + typedef int ContextVal; + + void changeContext(ContextParam param, ContextVal val) + { + } + }; + + void copyRegs(ThreadContext *src, ThreadContext *dest); + + void copyMiscRegs(ThreadContext *src, ThreadContext *dest); + +#if FULL_SYSTEM + void copyIprs(ThreadContext *src, ThreadContext *dest); +#endif +} // namespace MipsISA + +#endif diff --git a/src/arch/mips/stacktrace.hh b/src/arch/mips/stacktrace.hh new file mode 100644 index 000000000..38767cef7 --- /dev/null +++ b/src/arch/mips/stacktrace.hh @@ -0,0 +1,121 @@ +/* + * Copyright (c) 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: Korey Sewell + */ + +#ifndef __ARCH_ALPHA_STACKTRACE_HH__ +#define __ARCH_ALPHA_STACKTRACE_HH__ + +#include "base/trace.hh" +#include "cpu/static_inst.hh" + +class ThreadContext; +class StackTrace; + +class ProcessInfo +{ + private: + ThreadContext *tc; + + int thread_info_size; + int task_struct_size; + int task_off; + int pid_off; + int name_off; + + public: + ProcessInfo(ThreadContext *_tc); + + Addr task(Addr ksp) const; + int pid(Addr ksp) const; + std::string name(Addr ksp) const; +}; + +class StackTrace +{ + protected: + typedef TheISA::MachInst MachInst; + private: + ThreadContext *tc; + std::vector<Addr> stack; + + private: + bool isEntry(Addr addr); + bool decodePrologue(Addr sp, Addr callpc, Addr func, int &size, Addr &ra); + bool decodeSave(MachInst inst, int ®, int &disp); + bool decodeStack(MachInst inst, int &disp); + + void trace(ThreadContext *tc, bool is_call); + + public: + StackTrace(); + StackTrace(ThreadContext *tc, StaticInstPtr inst); + ~StackTrace(); + + void clear() + { + tc = 0; + stack.clear(); + } + + bool valid() const { return tc != NULL; } + bool trace(ThreadContext *tc, StaticInstPtr inst); + + public: + const std::vector<Addr> &getstack() const { return stack; } + + static const int user = 1; + static const int console = 2; + static const int unknown = 3; + +#if TRACING_ON + private: + void dump(); + + public: + void dprintf() { if (DTRACE(Stack)) dump(); } +#else + public: + void dprintf() {} +#endif +}; + +inline bool +StackTrace::trace(ThreadContext *tc, StaticInstPtr inst) +{ + if (!inst->isCall() && !inst->isReturn()) + return false; + + if (valid()) + clear(); + + trace(tc, !inst->isReturn()); + return true; +} + +#endif // __ARCH_ALPHA_STACKTRACE_HH__ diff --git a/src/arch/mips/types.hh b/src/arch/mips/types.hh new file mode 100644 index 000000000..7cd2eed0c --- /dev/null +++ b/src/arch/mips/types.hh @@ -0,0 +1,94 @@ +/* + * 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: Korey Sewell + */ + +#ifndef __ARCH_MIPS_TYPES_HH__ +#define __ARCH_MIPS_TYPES_HH__ + +#include "sim/host.hh" + +namespace MipsISA +{ + typedef uint32_t MachInst; + typedef uint64_t ExtMachInst; + typedef uint8_t RegIndex; + + typedef uint32_t IntReg; + + // floating point register file entry type + typedef double FloatReg; + typedef uint32_t FloatReg32; + typedef uint64_t FloatReg64; + typedef uint64_t FloatRegBits; + + // cop-0/cop-1 system control register + typedef uint64_t MiscReg; + typedef uint64_t InternalProcReg; + + typedef union { + IntReg intreg; + FloatReg fpreg; + MiscReg ctrlreg; + } AnyReg; + + //used in FP convert & round function + enum ConvertType{ + SINGLE_TO_DOUBLE, + SINGLE_TO_WORD, + SINGLE_TO_LONG, + + DOUBLE_TO_SINGLE, + DOUBLE_TO_WORD, + DOUBLE_TO_LONG, + + LONG_TO_SINGLE, + LONG_TO_DOUBLE, + LONG_TO_WORD, + LONG_TO_PS, + + WORD_TO_SINGLE, + WORD_TO_DOUBLE, + WORD_TO_LONG, + WORD_TO_PS, + + PL_TO_SINGLE, + PU_TO_SINGLE + }; + + //used in FP convert & round function + enum RoundMode{ + RND_ZERO, + RND_DOWN, + RND_UP, + RND_NEAREST + }; + +} // namespace MipsISA + +#endif diff --git a/src/arch/mips/utility.cc b/src/arch/mips/utility.cc new file mode 100644 index 000000000..e7455fdbf --- /dev/null +++ b/src/arch/mips/utility.cc @@ -0,0 +1,202 @@ +/* + * Copyright (c) 2003-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 + */ + +#include "arch/mips/isa_traits.hh" +#include "arch/mips/utility.hh" +#include "config/full_system.hh" +#include "cpu/static_inst.hh" +#include "sim/serialize.hh" +#include "base/bitfield.hh" + +using namespace MipsISA; +using namespace std; + +uint64_t +MipsISA::fpConvert(ConvertType cvt_type, double fp_val) +{ + + switch (cvt_type) + { + case SINGLE_TO_DOUBLE: + { + double sdouble_val = fp_val; + void *sdouble_ptr = &sdouble_val; + uint64_t sdp_bits = *(uint64_t *) sdouble_ptr; + return sdp_bits; + } + + case SINGLE_TO_WORD: + { + int32_t sword_val = (int32_t) fp_val; + void *sword_ptr = &sword_val; + uint64_t sword_bits= *(uint32_t *) sword_ptr; + return sword_bits; + } + + case WORD_TO_SINGLE: + { + float wfloat_val = fp_val; + void *wfloat_ptr = &wfloat_val; + uint64_t wfloat_bits = *(uint32_t *) wfloat_ptr; + return wfloat_bits; + } + + case WORD_TO_DOUBLE: + { + double wdouble_val = fp_val; + void *wdouble_ptr = &wdouble_val; + uint64_t wdp_bits = *(uint64_t *) wdouble_ptr; + return wdp_bits; + } + + default: + panic("Invalid Floating Point Conversion Type (%d). See \"types.hh\" for List of Conversions\n",cvt_type); + return 0; + } +} + +double +MipsISA::roundFP(double val, int digits) +{ + double digit_offset = pow(10.0,digits); + val = val * digit_offset; + val = val + 0.5; + val = floor(val); + val = val / digit_offset; + return val; +} + +double +MipsISA::truncFP(double val) +{ + int trunc_val = (int) val; + return (double) trunc_val; +} + +bool +MipsISA::getCondCode(uint32_t fcsr, int cc_idx) +{ + int shift = (cc_idx == 0) ? 23 : cc_idx + 24; + bool cc_val = (fcsr >> shift) & 0x00000001; + return cc_val; +} + +uint32_t +MipsISA::genCCVector(uint32_t fcsr, int cc_num, uint32_t cc_val) +{ + int cc_idx = (cc_num == 0) ? 23 : cc_num + 24; + + fcsr = bits(fcsr, 31, cc_idx + 1) << cc_idx + 1 | + cc_val << cc_idx | + bits(fcsr, cc_idx - 1, 0); + + return fcsr; +} + +uint32_t +MipsISA::genInvalidVector(uint32_t fcsr_bits) +{ + //Set FCSR invalid in "flag" field + int invalid_offset = Invalid + Flag_Field; + fcsr_bits = fcsr_bits | (1 << invalid_offset); + + //Set FCSR invalid in "cause" flag + int cause_offset = Invalid + Cause_Field; + fcsr_bits = fcsr_bits | (1 << cause_offset); + + return fcsr_bits; +} + +bool +MipsISA::isNan(void *val_ptr, int size) +{ + switch (size) + { + case 32: + { + uint32_t val_bits = *(uint32_t *) val_ptr; + return (bits(val_bits, 30, 23) == 0xFF); + } + + case 64: + { + uint64_t val_bits = *(uint64_t *) val_ptr; + return (bits(val_bits, 62, 52) == 0x7FF); + } + + default: + panic("Type unsupported. Size mismatch\n"); + } +} + + +bool +MipsISA::isQnan(void *val_ptr, int size) +{ + switch (size) + { + case 32: + { + uint32_t val_bits = *(uint32_t *) val_ptr; + return (bits(val_bits, 30, 22) == 0x1FE); + } + + case 64: + { + uint64_t val_bits = *(uint64_t *) val_ptr; + return (bits(val_bits, 62, 51) == 0xFFE); + } + + default: + panic("Type unsupported. Size mismatch\n"); + } +} + +bool +MipsISA::isSnan(void *val_ptr, int size) +{ + switch (size) + { + case 32: + { + uint32_t val_bits = *(uint32_t *) val_ptr; + return (bits(val_bits, 30, 22) == 0x1FF); + } + + case 64: + { + uint64_t val_bits = *(uint64_t *) val_ptr; + return (bits(val_bits, 62, 51) == 0xFFF); + } + + default: + panic("Type unsupported. Size mismatch\n"); + } +} diff --git a/src/arch/mips/utility.hh b/src/arch/mips/utility.hh new file mode 100644 index 000000000..c5c69ddcd --- /dev/null +++ b/src/arch/mips/utility.hh @@ -0,0 +1,57 @@ +/* + * 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: Nathan Binkert + * Steve Reinhardt + */ + +#ifndef __ARCH_MIPS_UTILITY_HH__ +#define __ARCH_MIPS_UTILITY_HH__ + +#include "arch/mips/types.hh" +#include "arch/mips/constants.hh" +#include "base/misc.hh" +#include "sim/host.hh" + +namespace MipsISA { + + //Floating Point Utility Functions + uint64_t fpConvert(ConvertType cvt_type, double fp_val); + double roundFP(double val, int digits); + double truncFP(double val); + + bool getCondCode(uint32_t fcsr, int cc); + uint32_t genCCVector(uint32_t fcsr, int num, uint32_t cc_val); + uint32_t genInvalidVector(uint32_t fcsr); + + bool isNan(void *val_ptr, int size); + bool isQnan(void *val_ptr, int size); + bool isSnan(void *val_ptr, int size); +}; + + +#endif |