summaryrefslogtreecommitdiff
path: root/src/arch/sparc/isa/formats/integerop.isa
diff options
context:
space:
mode:
Diffstat (limited to 'src/arch/sparc/isa/formats/integerop.isa')
-rw-r--r--src/arch/sparc/isa/formats/integerop.isa379
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)
+}};
+