summaryrefslogtreecommitdiff
path: root/src/arch/sparc
diff options
context:
space:
mode:
authorGabe Black <gblack@eecs.umich.edu>2006-11-10 15:28:58 -0500
committerGabe Black <gblack@eecs.umich.edu>2006-11-10 15:28:58 -0500
commit13a8752c11ae8e2c9fbf97c405e27b4ec2f8fd3b (patch)
tree5cb702e3b5e51f28522a94815d7a390562a5b7a7 /src/arch/sparc
parent7bf1c8981d78e3f3384e0ab493cb10d736aef355 (diff)
downloadgem5-13a8752c11ae8e2c9fbf97c405e27b4ec2f8fd3b.tar.xz
Put in provisions for rd, rdpr, rdhpr, wr, wrpr, and wrhpr to disassemble properly.
--HG-- extra : convert_revision : f2cad8a5879999438ba9b05f15a91320e7a4cc4a
Diffstat (limited to 'src/arch/sparc')
-rw-r--r--src/arch/sparc/isa/formats/priv.isa140
1 files changed, 134 insertions, 6 deletions
diff --git a/src/arch/sparc/isa/formats/priv.isa b/src/arch/sparc/isa/formats/priv.isa
index 55bf968f4..94a68aebe 100644
--- a/src/arch/sparc/isa/formats/priv.isa
+++ b/src/arch/sparc/isa/formats/priv.isa
@@ -50,6 +50,42 @@ output header {{
const SymbolTable *symtab) const;
};
+ //This class is for instructions that explicitly read control
+ //registers. It provides a special generateDisassembly function.
+ class RdPriv : public Priv
+ {
+ protected:
+ //Constructor
+ RdPriv(const char *mnem, ExtMachInst _machInst,
+ OpClass __opClass, char const * _regName) :
+ Priv(mnem, _machInst, __opClass), regName(_regName)
+ {
+ }
+
+ std::string generateDisassembly(Addr pc,
+ const SymbolTable *symtab) const;
+
+ char const * regName;
+ };
+
+ //This class is for instructions that explicitly write control
+ //registers. It provides a special generateDisassembly function.
+ class WrPriv : public Priv
+ {
+ protected:
+ //Constructor
+ WrPriv(const char *mnem, ExtMachInst _machInst,
+ OpClass __opClass, char const * _regName) :
+ Priv(mnem, _machInst, __opClass), regName(_regName)
+ {
+ }
+
+ std::string generateDisassembly(Addr pc,
+ const SymbolTable *symtab) const;
+
+ char const * regName;
+ };
+
/**
* Base class for privelege mode operations with immediates.
*/
@@ -66,6 +102,23 @@ output header {{
int32_t imm;
};
+ //This class is for instructions that explicitly write control
+ //registers. It provides a special generateDisassembly function.
+ class WrPrivImm : public PrivImm
+ {
+ protected:
+ //Constructor
+ WrPrivImm(const char *mnem, ExtMachInst _machInst,
+ OpClass __opClass, char const * _regName) :
+ PrivImm(mnem, _machInst, __opClass), regName(_regName)
+ {
+ }
+
+ std::string generateDisassembly(Addr pc,
+ const SymbolTable *symtab) const;
+
+ char const * regName;
+ };
}};
output decoder {{
@@ -78,6 +131,58 @@ output decoder {{
return response.str();
}
+
+ std::string RdPriv::generateDisassembly(Addr pc,
+ const SymbolTable *symtab) const
+ {
+ std::stringstream response;
+
+ printMnemonic(response, mnemonic);
+
+ ccprintf(response, " %%%s, ", regName);
+ printDestReg(response, 0);
+
+ return response.str();
+ }
+
+ std::string WrPriv::generateDisassembly(Addr pc,
+ const SymbolTable *symtab) const
+ {
+ std::stringstream response;
+
+ printMnemonic(response, mnemonic);
+
+ ccprintf(response, " ");
+ printSrcReg(response, 0);
+ ccprintf(response, ", ");
+ printSrcReg(response, 1);
+ ccprintf(response, ", %%%s", regName);
+
+ return response.str();
+ }
+
+ std::string WrPrivImm::generateDisassembly(Addr pc,
+ const SymbolTable *symtab) const
+ {
+ std::stringstream response;
+
+ printMnemonic(response, mnemonic);
+
+ ccprintf(response, " ");
+ printSrcReg(response, 0);
+ ccprintf(response, ", 0x%x, %%%s", imm, regName);
+
+ return response.str();
+ }
+}};
+
+def template ControlRegConstructor {{
+ inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
+ : %(base_class)s("%(mnemonic)s", machInst,
+ %(op_class)s, "%(reg_name)s")
+ {
+ %(constructor)s;
+ }
}};
def template PrivExecute {{
@@ -102,16 +207,39 @@ let {{
def doPrivFormat(code, checkCode, name, Name, opt_flags):
(usesImm, code, immCode,
rString, iString) = splitOutImm(code)
- iop = InstObjParams(name, Name, 'Priv', code,
- opt_flags, {"check": checkCode})
+ #If these are rd, rdpr, rdhpr, wr, wrpr, or wrhpr instructions,
+ #cut any other info out of the mnemonic. Also pick a different
+ #base class.
+ regBase = 'Priv'
+ regName = ''
+ for mnem in ["rdhpr", "rdpr", "rd"]:
+ if name.startswith(mnem):
+ regName = name[len(mnem):]
+ name = mnem
+ regBase = 'RdPriv'
+ break
+ for mnem in ["wrhpr", "wrpr", "wr"]:
+ if name.startswith(mnem):
+ regName = name[len(mnem):]
+ name = mnem
+ regBase = 'WrPriv'
+ break
+ iop = InstObjParams(name, Name, regBase, code,
+ opt_flags, {"check": checkCode, "reg_name": regName})
header_output = BasicDeclare.subst(iop)
- decoder_output = BasicConstructor.subst(iop)
+ if regName == '':
+ decoder_output = BasicConstructor.subst(iop)
+ else:
+ decoder_output = ControlRegConstructor.subst(iop)
exec_output = PrivExecute.subst(iop)
if usesImm:
- imm_iop = InstObjParams(name, Name + 'Imm', 'PrivImm',
- immCode, opt_flags, {"check": checkCode})
+ imm_iop = InstObjParams(name, Name + 'Imm', regBase + 'Imm',
+ immCode, opt_flags, {"check": checkCode, "reg_name": regName})
header_output += BasicDeclare.subst(imm_iop)
- decoder_output += BasicConstructor.subst(imm_iop)
+ if regName == '':
+ decoder_output += BasicConstructor.subst(imm_iop)
+ else:
+ decoder_output += ControlRegConstructor.subst(imm_iop)
exec_output += PrivExecute.subst(imm_iop)
decode_block = ROrImmDecode.subst(iop)
else: