// -*- mode:c++ -*- // Copyright N) 2007 MIPS Technologies, Inc. All Rights Reserved // This software is part of the M5 simulator. // THIS IS A LEGAL AGREEMENT. BY DOWNLOADING, USING, COPYING, CREATING // DERIVATIVE WORKS, AND/OR DISTRIBUTING THIS SOFTWARE YOU ARE AGREEING // TO THESE TERMS AND CONDITIONS. // Permission is granted to use, copy, create derivative works and // distribute this software and such derivative works for any purpose, // so long as (1) the copyright notice above, this grant of permission, // and the disclaimer below appear in all copies and derivative works // made, (2) the copyright notice above is augmented as appropriate to // reflect the addition of any new copyrightable work in a derivative // work (e.g., Copyright N) Copyright Owner), and (3) // the name of MIPS Technologies, Inc. ($(B!H(BMIPS$(B!I(B) is not used in any // advertising or publicity pertaining to the use or distribution of // this software without specific, written prior authorization. // THIS SOFTWARE IS PROVIDED $(B!H(BAS IS.$(B!I(B MIPS MAKES NO WARRANTIES AND // DISCLAIMS ALL WARRANTIES, WHETHER EXPRESS, STATUTORY, IMPLIED OR // OTHERWISE, INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND // NON-INFRINGEMENT OF THIRD PARTY RIGHTS, REGARDING THIS SOFTWARE. // IN NO EVENT SHALL MIPS BE LIABLE FOR ANY DAMAGES, INCLUDING DIRECT, // INDIRECT, INCIDENTAL, CONSEQUENTIAL, SPECIAL, OR PUNITIVE DAMAGES OF // ANY KIND OR NATURE, ARISING OUT OF OR IN CONNECTION WITH THIS AGREEMENT, // THIS SOFTWARE AND/OR THE USE OF THIS SOFTWARE, WHETHER SUCH LIABILITY // IS ASSERTED ON THE BASIS OF CONTRACT, TORT (INCLUDING NEGLIGENCE OR // STRICT LIABILITY), OR OTHERWISE, EVEN IF MIPS HAS BEEN WARNED OF THE // POSSIBILITY OF ANY SUCH LOSS OR DAMAGE IN ADVANCE. //Authors: Korey L. Sewell // Brett Miller //////////////////////////////////////////////////////////////////// // // DSP integer operate instructions // output header {{ #include using namespace std; /** * Base class for integer operations. */ class DspIntOp : public MipsStaticInst { protected: /// Constructor DspIntOp(const char *mnem, MachInst _machInst, OpClass __opClass) : MipsStaticInst(mnem, _machInst, __opClass) { } }; class DspHiLoOp : public MipsStaticInst { protected: /// Constructor DspHiLoOp(const char *mnem, MachInst _machInst, OpClass __opClass) : MipsStaticInst(mnem, _machInst, __opClass) { } }; }}; // Dsp instruction class execute method template. def template DspExecute {{ Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const { Fault fault = NoFault; %(op_decl)s; if (isDspPresent(xc)) { if (isDspEnabled(xc)) { %(op_rd)s; %(code)s; } else { fault = new DspStateDisabledFault(); } } else { fault = new ReservedInstructionFault(); } if(fault == NoFault) { %(op_wb)s; } return fault; } }}; // DspHiLo instruction class execute method template. def template DspHiLoExecute {{ Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const { Fault fault = NoFault; %(op_decl)s; if (isDspPresent(xc)) { if (isDspEnabled(xc)) { %(op_rd)s; %(code)s; } else { fault = new DspStateDisabledFault(); } } else { fault = new ReservedInstructionFault(); } if(fault == NoFault) { %(op_wb)s; //If there are 2 Destination Registers then //concatenate the values for the traceData if(traceData && _numDestRegs == 2) { // FIXME - set the trace value correctly here //uint64_t hilo_final_val = (uint64_t)HI_RD_SEL << 32 | LO_RD_SEL; //traceData->setData(hilo_final_val); } } return fault; } }}; //Outputs to decoder.cc output decoder {{ }}; output exec {{ bool isDspEnabled(%(CPU_exec_context)s *xc) { #if FULL_SYSTEM if( bits( xc->readMiscReg(MipsISA::Status), 24, 24 ) == 0 ) return false; #else //printf("Syscall Emulation Mode: isDspEnabled() check defaults to TRUE\n"); #endif return true; } }}; output exec {{ bool isDspPresent(%(CPU_exec_context)s *xc) { #if FULL_SYSTEM if( bits( xc->readMiscReg(MipsISA::Config3), 10, 10 ) == 0 ) return false; #else //printf("Syscall Emulation Mode: isDspPresent() check defaults to TRUE\n"); #endif return true; } }}; // add code to fetch the DSPControl register // and write it back after execution, giving // the instruction the opportunity to modify // it if necessary def format DspIntOp(code, *opt_flags) {{ decl_code = 'uint32_t dspctl;\n' decl_code += 'dspctl = DSPControl;\n' write_code = 'DSPControl = dspctl;\n' code = decl_code + code + write_code opt_flags += ('IsDspOp',) iop = InstObjParams(name, Name, 'DspIntOp', code, opt_flags) header_output = BasicDeclare.subst(iop) decoder_output = BasicConstructor.subst(iop) decode_block = BasicDecode.subst(iop) exec_output = DspExecute.subst(iop) }}; // add code to fetch the DSPControl register // and write it back after execution, giving // the instruction the opportunity to modify // it if necessary; also, fetch the appropriate // HI/LO register pair, based on the AC // instruction field. def format DspHiLoOp(code, *opt_flags) {{ decl_code = 'int64_t dspac;\n' decl_code += 'uint32_t dspctl;\n' fetch_code = 'dspctl = DSPControl;\n' fetch_code += 'dspac = HI_RD_SEL;\n' fetch_code += 'dspac = dspac << 32 | LO_RD_SEL;\n' write_code = 'DSPControl = dspctl;\n' write_code += 'HI_RD_SEL = dspac<63:32>;\n' write_code += 'LO_RD_SEL = dspac<31:0>;\n' code = decl_code + fetch_code + code + write_code opt_flags += ('IsDspOp',) iop = InstObjParams(name, Name, 'DspHiLoOp', code, opt_flags) header_output = BasicDeclare.subst(iop) decoder_output = BasicConstructor.subst(iop) decode_block = BasicDecode.subst(iop) exec_output = DspHiLoExecute.subst(iop) }};