diff options
Diffstat (limited to 'src/arch/sparc/isa/formats/integerop.isa')
-rw-r--r-- | src/arch/sparc/isa/formats/integerop.isa | 350 |
1 files changed, 350 insertions, 0 deletions
diff --git a/src/arch/sparc/isa/formats/integerop.isa b/src/arch/sparc/isa/formats/integerop.isa new file mode 100644 index 000000000..83c7e6958 --- /dev/null +++ b/src/arch/sparc/isa/formats/integerop.isa @@ -0,0 +1,350 @@ +// 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: Ali Saidi +// Gabe Black +// Steve Reinhardt + +//////////////////////////////////////////////////////////////////// +// +// Integer operate instructions +// + +output header {{ + /** + * Base class for integer operations. + */ + class IntOp : public SparcStaticInst + { + protected: + // Constructor + IntOp(const char *mnem, ExtMachInst _machInst, + OpClass __opClass) : + SparcStaticInst(mnem, _machInst, __opClass) + { + } + + std::string generateDisassembly(Addr pc, + const SymbolTable *symtab) const; + + virtual bool printPseudoOps(std::ostream &os, Addr pc, + const SymbolTable *symtab) const; + }; + + /** + * Base class for immediate integer operations. + */ + class IntOpImm : public IntOp + { + protected: + // Constructor + IntOpImm(const char *mnem, ExtMachInst _machInst, + OpClass __opClass) : + IntOp(mnem, _machInst, __opClass) + { + } + + int64_t imm; + + std::string generateDisassembly(Addr pc, + const SymbolTable *symtab) const; + + virtual bool printPseudoOps(std::ostream &os, Addr pc, + const SymbolTable *symtab) const; + }; + + /** + * Base class for 10 bit immediate integer operations. + */ + class IntOpImm10 : public IntOpImm + { + protected: + // Constructor + IntOpImm10(const char *mnem, ExtMachInst _machInst, + OpClass __opClass) : + IntOpImm(mnem, _machInst, __opClass) + { + imm = sign_ext(SIMM10, 10); + } + }; + + /** + * Base class for 11 bit immediate integer operations. + */ + class IntOpImm11 : public IntOpImm + { + protected: + // Constructor + IntOpImm11(const char *mnem, ExtMachInst _machInst, + OpClass __opClass) : + IntOpImm(mnem, _machInst, __opClass) + { + imm = sign_ext(SIMM11, 11); + } + }; + + /** + * Base class for 13 bit immediate integer operations. + */ + class IntOpImm13 : public IntOpImm + { + protected: + // Constructor + IntOpImm13(const char *mnem, ExtMachInst _machInst, + OpClass __opClass) : + IntOpImm(mnem, _machInst, __opClass) + { + imm = sign_ext(SIMM13, 13); + } + }; + + /** + * Base class for sethi. + */ + class SetHi : public IntOpImm + { + protected: + // Constructor + SetHi(const char *mnem, ExtMachInst _machInst, + OpClass __opClass) : + IntOpImm(mnem, _machInst, __opClass) + { + imm = (IMM22 & 0x3FFFFF) << 10; + } + + std::string generateDisassembly(Addr pc, + const SymbolTable *symtab) const; + }; +}}; + +def template SetHiDecode {{ + { + if(RD == 0 && IMM22 == 0) + return (SparcStaticInst *)(new Nop("nop", machInst, No_OpClass)); + else + return (SparcStaticInst *)(new %(class_name)s(machInst)); + } +}}; + +output decoder {{ + + bool IntOp::printPseudoOps(std::ostream &os, Addr pc, + const SymbolTable *symbab) const + { + if(!strcmp(mnemonic, "or") && _srcRegIdx[0] == 0) + { + printMnemonic(os, "mov"); + printSrcReg(os, 1); + ccprintf(os, ", "); + printDestReg(os, 0); + return true; + } + return false; + } + + bool IntOpImm::printPseudoOps(std::ostream &os, Addr pc, + const SymbolTable *symbab) const + { + if(!strcmp(mnemonic, "or")) + { + if(_numSrcRegs > 0 && _srcRegIdx[0] == 0) + { + if(imm == 0) + printMnemonic(os, "clr"); + else + { + printMnemonic(os, "mov"); + ccprintf(os, " 0x%x, ", imm); + } + printDestReg(os, 0); + return true; + } + else if(imm == 0) + { + printMnemonic(os, "mov"); + printSrcReg(os, 0); + ccprintf(os, ", "); + printDestReg(os, 0); + return true; + } + } + return false; + } + + std::string IntOp::generateDisassembly(Addr pc, + const SymbolTable *symtab) const + { + std::stringstream response; + + if(printPseudoOps(response, pc, symtab)) + return response.str(); + printMnemonic(response, mnemonic); + printRegArray(response, _srcRegIdx, _numSrcRegs); + if(_numDestRegs && _numSrcRegs) + response << ", "; + printDestReg(response, 0); + return response.str(); + } + + std::string IntOpImm::generateDisassembly(Addr pc, + const SymbolTable *symtab) const + { + std::stringstream response; + + if(printPseudoOps(response, pc, symtab)) + return response.str(); + printMnemonic(response, mnemonic); + printRegArray(response, _srcRegIdx, _numSrcRegs); + if(_numSrcRegs > 0) + response << ", "; + ccprintf(response, "0x%x", imm); + if(_numDestRegs > 0) + response << ", "; + printDestReg(response, 0); + return response.str(); + } + + std::string SetHi::generateDisassembly(Addr pc, + const SymbolTable *symtab) const + { + std::stringstream response; + + printMnemonic(response, mnemonic); + ccprintf(response, "%%hi(0x%x), ", imm); + printDestReg(response, 0); + return response.str(); + } +}}; + +def template IntOpExecute {{ + Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const + { + Fault fault = NoFault; + + %(op_decl)s; + %(op_rd)s; + %(code)s; + + //Write the resulting state to the execution context + if(fault == NoFault) + { + %(cc_code)s; + %(op_wb)s; + } + return fault; + } +}}; + +let {{ + def doIntFormat(code, ccCode, name, Name, opt_flags): + (usesImm, code, immCode, + rString, iString) = splitOutImm(code) + iop = InstObjParams(name, Name, 'IntOp', code, + opt_flags, ("cc_code", ccCode)) + header_output = BasicDeclare.subst(iop) + decoder_output = BasicConstructor.subst(iop) + exec_output = IntOpExecute.subst(iop) + if usesImm: + imm_iop = InstObjParams(name, Name + 'Imm', 'IntOpImm' + iString, + immCode, opt_flags, ("cc_code", ccCode)) + header_output += BasicDeclare.subst(imm_iop) + decoder_output += BasicConstructor.subst(imm_iop) + exec_output += IntOpExecute.subst(imm_iop) + decode_block = ROrImmDecode.subst(iop) + else: + decode_block = BasicDecode.subst(iop) + return (header_output, decoder_output, exec_output, decode_block) + + calcCcCode = ''' + uint16_t _ic, _iv, _iz, _in, _xc, _xv, _xz, _xn; + + _in = (Rd >> 31) & 1; + _iz = ((Rd & 0xFFFFFFFF) == 0); + _xn = (Rd >> 63) & 1; + _xz = (Rd == 0); + _iv = %(ivValue)s & 1; + _ic = %(icValue)s & 1; + _xv = %(xvValue)s & 1; + _xc = %(xcValue)s & 1; + + Ccr = _ic << 0 | _iv << 1 | _iz << 2 | _in << 3 | + _xc << 4 | _xv << 5 | _xz << 6 | _xn << 7; + + + DPRINTF(Sparc, "in = %%d\\n", _in); + DPRINTF(Sparc, "iz = %%d\\n", _iz); + DPRINTF(Sparc, "xn = %%d\\n", _xn); + DPRINTF(Sparc, "xz = %%d\\n", _xz); + DPRINTF(Sparc, "iv = %%d\\n", _iv); + DPRINTF(Sparc, "ic = %%d\\n", _ic); + DPRINTF(Sparc, "xv = %%d\\n", _xv); + DPRINTF(Sparc, "xc = %%d\\n", _xc); + ''' +}}; + +// Primary format for integer operate instructions: +def format IntOp(code, *opt_flags) {{ + ccCode = '' + (header_output, + decoder_output, + exec_output, + decode_block) = doIntFormat(code, ccCode, + name, Name, opt_flags) +}}; + +// Primary format for integer operate instructions: +def format IntOpCc(code, icValue, ivValue, xcValue, xvValue, *opt_flags) {{ + ccCode = calcCcCode % vars() + (header_output, + decoder_output, + exec_output, + decode_block) = doIntFormat(code, ccCode, + name, Name, opt_flags) +}}; + +// Primary format for integer operate instructions: +def format IntOpCcRes(code, *opt_flags) {{ + ccCode = calcCcCode % {"icValue":"0", + "ivValue":"0", + "xcValue":"0", + "xvValue":"0"} + (header_output, + decoder_output, + exec_output, + decode_block) = doIntFormat(code, ccCode, + name, Name, opt_flags) +}}; + +def format SetHi(code, *opt_flags) {{ + iop = InstObjParams(name, Name, 'SetHi', + code, opt_flags, ("cc_code", '')) + header_output = BasicDeclare.subst(iop) + decoder_output = BasicConstructor.subst(iop) + exec_output = IntOpExecute.subst(iop) + decode_block = SetHiDecode.subst(iop) +}}; + |