diff options
Diffstat (limited to 'src/arch/sparc/isa/formats/integerop.isa')
-rw-r--r-- | src/arch/sparc/isa/formats/integerop.isa | 379 |
1 files changed, 379 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..1fd87b1d3 --- /dev/null +++ b/src/arch/sparc/isa/formats/integerop.isa @@ -0,0 +1,379 @@ +// 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) + { + } + + int32_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 << 10) & 0xFFFFFC00; + } + + 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"); + if(_numSrcRegs > 0) + printReg(os, _srcRegIdx[1]); + ccprintf(os, ", "); + if(_numDestRegs > 0) + printReg(os, _destRegIdx[0]); + + return true; + } + return false; + } + + bool IntOpImm::printPseudoOps(std::ostream &os, Addr pc, + const SymbolTable *symbab) const + { + if(!strcmp(mnemonic, "or")) + { + if(_srcRegIdx[0] == 0) + { + if(imm == 0) + { + printMnemonic(os, "clr"); + if(_numDestRegs > 0) + printReg(os, _destRegIdx[0]); + return true; + } + else + { + printMnemonic(os, "mov"); + ccprintf(os, ", 0x%x, ", imm); + if(_numDestRegs > 0) + printReg(os, _destRegIdx[0]); + return true; + } + } + else if(imm == 0) + { + printMnemonic(os, "mov"); + if(_numSrcRegs > 0) + printReg(os, _srcRegIdx[0]); + ccprintf(os, ", "); + if(_numDestRegs > 0) + printReg(os, _destRegIdx[0]); + return true; + } + } + return false; + } + + std::string IntOp::generateDisassembly(Addr pc, + const SymbolTable *symtab) const + { + std::stringstream response; + + if(!printPseudoOps(response, pc, symtab)) + { + printMnemonic(response, mnemonic); + if (_numSrcRegs > 0) + { + printReg(response, _srcRegIdx[0]); + for(int x = 1; x < _numSrcRegs; x++) + { + response << ", "; + printReg(response, _srcRegIdx[x]); + } + } + if (_numDestRegs > 0) + { + if(_numSrcRegs > 0) + response << ", "; + printReg(response, _destRegIdx[0]); + } + } + return response.str(); + } + + std::string IntOpImm::generateDisassembly(Addr pc, + const SymbolTable *symtab) const + { + std::stringstream response; + + if(!printPseudoOps(response, pc, symtab)) + { + printMnemonic(response, mnemonic); + if (_numSrcRegs > 0) + { + printReg(response, _srcRegIdx[0]); + for(int x = 1; x < _numSrcRegs - 1; x++) + { + response << ", "; + printReg(response, _srcRegIdx[x]); + } + } + if(_numSrcRegs > 0) + response << ", "; + ccprintf(response, "0x%x", imm); + if (_numDestRegs > 0) + { + response << ", "; + printReg(response, _destRegIdx[0]); + } + } + return response.str(); + } + + std::string SetHi::generateDisassembly(Addr pc, + const SymbolTable *symtab) const + { + std::stringstream response; + + printMnemonic(response, mnemonic); + if(_numSrcRegs > 0) + response << ", "; + ccprintf(response, "%%hi(0x%x), ", imm); + printReg(response, _destRegIdx[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 = ''' + CcrIccN = (Rd >> 31) & 1; + CcrIccZ = ((Rd & 0xFFFFFFFF) == 0); + CcrXccN = (Rd >> 63) & 1; + CcrXccZ = (Rd == 0); + CcrIccV = %(ivValue)s; + CcrIccC = %(icValue)s; + CcrXccV = %(xvValue)s; + CcrXccC = %(xcValue)s; + DPRINTF(Sparc, "in = %%d\\n", CcrIccN); + DPRINTF(Sparc, "iz = %%d\\n", CcrIccZ); + DPRINTF(Sparc, "xn = %%d\\n", CcrXccN); + DPRINTF(Sparc, "xz = %%d\\n", CcrXccZ); + DPRINTF(Sparc, "iv = %%d\\n", CcrIccV); + DPRINTF(Sparc, "ic = %%d\\n", CcrIccC); + DPRINTF(Sparc, "xv = %%d\\n", CcrXccV); + DPRINTF(Sparc, "xc = %%d\\n", CcrXccC); + ''' +}}; + +// 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) +}}; + |