summaryrefslogtreecommitdiff
path: root/src/arch/sparc/isa
diff options
context:
space:
mode:
authorGabe Black <gblack@eecs.umich.edu>2006-10-23 07:55:52 -0400
committerGabe Black <gblack@eecs.umich.edu>2006-10-23 07:55:52 -0400
commit20208d00e6566a7946e589184a7ed9dffb54fc74 (patch)
tree77764410222fd4f064360a8fa624675121d9f40f /src/arch/sparc/isa
parente9908e3c854e534a391448907773ca03c60b13c8 (diff)
downloadgem5-20208d00e6566a7946e589184a7ed9dffb54fc74.tar.xz
Broke Load/Store instructions into microcode, and partially refactored memory operations in the SPARC ISA description.
--HG-- rename : src/arch/sparc/isa/formats.isa => src/arch/sparc/isa/formats/formats.isa rename : src/arch/sparc/isa/formats/mem.isa => src/arch/sparc/isa/formats/mem/basicmem.isa rename : src/arch/sparc/isa/formats/blockmem.isa => src/arch/sparc/isa/formats/mem/blockmem.isa rename : src/arch/sparc/isa/formats/mem.isa => src/arch/sparc/isa/formats/mem/mem.isa extra : convert_revision : dbbb00f997a102871b084b209b9fa08c5e1853ee
Diffstat (limited to 'src/arch/sparc/isa')
-rw-r--r--src/arch/sparc/isa/decoder.isa25
-rw-r--r--src/arch/sparc/isa/formats.isa37
-rw-r--r--src/arch/sparc/isa/formats/formats.isa62
-rw-r--r--src/arch/sparc/isa/formats/mem.isa347
-rw-r--r--src/arch/sparc/isa/formats/mem/basicmem.isa202
-rw-r--r--src/arch/sparc/isa/formats/mem/blockmem.isa (renamed from src/arch/sparc/isa/formats/blockmem.isa)72
-rw-r--r--src/arch/sparc/isa/formats/mem/mem.isa45
-rw-r--r--src/arch/sparc/isa/formats/mem/util.isa183
-rw-r--r--src/arch/sparc/isa/includes.isa3
-rw-r--r--src/arch/sparc/isa/main.isa2
-rw-r--r--src/arch/sparc/isa/operands.isa5
11 files changed, 545 insertions, 438 deletions
diff --git a/src/arch/sparc/isa/decoder.isa b/src/arch/sparc/isa/decoder.isa
index 9da6bdd33..45d3616d9 100644
--- a/src/arch/sparc/isa/decoder.isa
+++ b/src/arch/sparc/isa/decoder.isa
@@ -846,11 +846,10 @@ decode OP default Unknown::unknown()
}});
}
0x0E: Store::stx({{Mem.udw = Rd}});
- 0x0F: LoadStore::swap({{
- uint32_t temp = Rd;
- Rd = Mem.uw;
- Mem.uw = temp;
- }});
+ 0x0F: LoadStore::swap(
+ {{*temp = Rd.uw;
+ Rd.uw = Mem.uw;}},
+ {{Mem.uw = *temp;}});
format Load {
0x10: lduwa({{Rd = Mem.uw;}});
0x11: lduba({{Rd = Mem.ub;}});
@@ -873,16 +872,14 @@ decode OP default Unknown::unknown()
0x1A: ldsha({{Rd = (int16_t)Mem.shw;}});
0x1B: ldxa({{Rd = (int64_t)Mem.sdw;}});
}
- 0x1D: LoadStore::ldstuba({{
- Rd = Mem.ub;
- Mem.ub = 0xFF;
- }});
+ 0x1D: LoadStore::ldstuba(
+ {{Rd = Mem.ub;}},
+ {{Mem.ub = 0xFF}});
0x1E: Store::stxa({{Mem.udw = Rd}});
- 0x1F: LoadStore::swapa({{
- uint32_t temp = Rd;
- Rd = Mem.uw;
- Mem.uw = temp;
- }});
+ 0x1F: LoadStore::swapa(
+ {{*temp = Rd.uw;
+ Rd.uw = Mem.uw;}},
+ {{Mem.uw = *temp;}});
format Trap {
0x20: Load::ldf({{Frd.uw = Mem.uw;}});
0x21: decode X {
diff --git a/src/arch/sparc/isa/formats.isa b/src/arch/sparc/isa/formats.isa
deleted file mode 100644
index e044aee1f..000000000
--- a/src/arch/sparc/isa/formats.isa
+++ /dev/null
@@ -1,37 +0,0 @@
-//Include the basic format
-//Templates from this format are used later
-##include "formats/basic.isa"
-
-//Include base classes for microcoding instructions
-##include "formats/micro.isa"
-
-//Include the noop format
-##include "formats/nop.isa"
-
-//Include the integerOp and integerOpCc format
-##include "formats/integerop.isa"
-
-//Include the memory format
-##include "formats/mem.isa"
-
-//Include the block memory format
-##include "formats/blockmem.isa"
-
-//Include the compare and swap format
-##include "formats/cas.isa"
-
-//Include the trap format
-##include "formats/trap.isa"
-
-//Include the unimplemented format
-##include "formats/unimp.isa"
-
-//Include the "unknown" format
-##include "formats/unknown.isa"
-
-//Include the priveleged mode format
-##include "formats/priv.isa"
-
-//Include the branch format
-##include "formats/branch.isa"
-
diff --git a/src/arch/sparc/isa/formats/formats.isa b/src/arch/sparc/isa/formats/formats.isa
new file mode 100644
index 000000000..5b81a1ab1
--- /dev/null
+++ b/src/arch/sparc/isa/formats/formats.isa
@@ -0,0 +1,62 @@
+// 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: Gabe Black
+
+//Include the basic format
+//Templates from this format are used later
+##include "basic.isa"
+
+//Include base classes for microcoding instructions
+##include "micro.isa"
+
+//Include the noop format
+##include "nop.isa"
+
+//Include the integerOp and integerOpCc format
+##include "integerop.isa"
+
+//Include the memory formats
+##include "mem/mem.isa"
+
+//Include the compare and swap format
+##include "cas.isa"
+
+//Include the trap format
+##include "trap.isa"
+
+//Include the unimplemented format
+##include "unimp.isa"
+
+//Include the "unknown" format
+##include "unknown.isa"
+
+//Include the priveleged mode format
+##include "priv.isa"
+
+//Include the branch format
+##include "branch.isa"
+
diff --git a/src/arch/sparc/isa/formats/mem.isa b/src/arch/sparc/isa/formats/mem.isa
deleted file mode 100644
index 2d3dd3d9a..000000000
--- a/src/arch/sparc/isa/formats/mem.isa
+++ /dev/null
@@ -1,347 +0,0 @@
-////////////////////////////////////////////////////////////////////
-//
-// Mem instructions
-//
-
-output header {{
- /**
- * Base class for memory operations.
- */
- class Mem : public SparcStaticInst
- {
- protected:
-
- // Constructor
- Mem(const char *mnem, ExtMachInst _machInst, OpClass __opClass) :
- SparcStaticInst(mnem, _machInst, __opClass)
- {
- }
-
- std::string generateDisassembly(Addr pc,
- const SymbolTable *symtab) const;
- };
-
- /**
- * Class for memory operations which use an immediate offset.
- */
- class MemImm : public Mem
- {
- protected:
-
- // Constructor
- MemImm(const char *mnem, ExtMachInst _machInst, OpClass __opClass) :
- Mem(mnem, _machInst, __opClass)
- {
- imm = sext<13>(SIMM13);
- }
-
- std::string generateDisassembly(Addr pc,
- const SymbolTable *symtab) const;
-
- int32_t imm;
- };
-}};
-
-output decoder {{
- std::string Mem::generateDisassembly(Addr pc,
- const SymbolTable *symtab) const
- {
- std::stringstream response;
- bool load = flags[IsLoad];
- bool save = flags[IsStore];
-
- printMnemonic(response, mnemonic);
- if(save)
- {
- printReg(response, _srcRegIdx[0]);
- ccprintf(response, ", ");
- }
- ccprintf(response, "[ ");
- printReg(response, _srcRegIdx[!save ? 0 : 1]);
- ccprintf(response, " + ");
- printReg(response, _srcRegIdx[!save ? 1 : 2]);
- ccprintf(response, " ]");
- if(load)
- {
- ccprintf(response, ", ");
- printReg(response, _destRegIdx[0]);
- }
-
- return response.str();
- }
-
- std::string MemImm::generateDisassembly(Addr pc,
- const SymbolTable *symtab) const
- {
- std::stringstream response;
- bool load = flags[IsLoad];
- bool save = flags[IsStore];
-
- printMnemonic(response, mnemonic);
- if(save)
- {
- printReg(response, _srcRegIdx[0]);
- ccprintf(response, ", ");
- }
- ccprintf(response, "[ ");
- printReg(response, _srcRegIdx[!save ? 0 : 1]);
- if(imm >= 0)
- ccprintf(response, " + 0x%x ]", imm);
- else
- ccprintf(response, " + -0x%x ]", -imm);
- if(load)
- {
- ccprintf(response, ", ");
- printReg(response, _destRegIdx[0]);
- }
-
- return response.str();
- }
-
-}};
-
-def template LoadExecute {{
- Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
- Trace::InstRecord *traceData) const
- {
- Fault fault = NoFault;
- Addr EA;
- %(op_decl)s;
- %(op_rd)s;
- %(priv_check)s;
- %(ea_code)s;
- DPRINTF(Sparc, "The address is 0x%x\n", EA);
- fault = xc->read(EA, (uint%(mem_acc_size)s_t&)Mem, 0);
- %(code)s;
- if(fault == NoFault)
- {
- //Write the resulting state to the execution context
- %(op_wb)s;
- }
-
- return fault;
- }
-
- Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s * xc,
- Trace::InstRecord * traceData) const
- {
- Fault fault = NoFault;
- Addr EA;
- uint%(mem_acc_size)s_t Mem;
- %(ea_decl)s;
- %(ea_rd)s;
- %(priv_check)s;
- %(ea_code)s;
- fault = xc->read(EA, (uint%(mem_acc_size)s_t&)Mem, 0);
- return fault;
- }
-
- Fault %(class_name)s::completeAcc(PacketPtr pkt, %(CPU_exec_context)s * xc,
- Trace::InstRecord * traceData) const
- {
- Fault fault = NoFault;
- %(code_decl)s;
- %(code_rd)s;
- Mem = pkt->get<typeof(Mem)>();
- %(code)s;
- if(fault == NoFault)
- {
- %(code_wb)s;
- }
- return fault;
- }
-}};
-
-def template StoreExecute {{
- Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
- Trace::InstRecord *traceData) const
- {
- Fault fault = NoFault;
- uint64_t write_result = 0;
- Addr EA;
- %(op_decl)s;
- %(op_rd)s;
- %(priv_check)s;
- %(ea_code)s;
- DPRINTF(Sparc, "The address is 0x%x\n", EA);
- %(code)s;
-
- if(fault == NoFault)
- {
- fault = xc->write((uint%(mem_acc_size)s_t)Mem, EA, 0, &write_result);
- }
- if(fault == NoFault)
- {
- //Write the resulting state to the execution context
- %(op_wb)s;
- }
-
- return fault;
- }
-
- Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s * xc,
- Trace::InstRecord * traceData) const
- {
- Fault fault = NoFault;
- uint64_t write_result = 0;
- Addr EA;
- %(op_decl)s;
- %(op_rd)s;
- %(priv_check)s;
- %(ea_code)s;
- DPRINTF(Sparc, "The address is 0x%x\n", EA);
- %(code)s;
- if(fault == NoFault)
- {
- fault = xc->write((uint%(mem_acc_size)s_t)Mem, EA, 0, &write_result);
- }
- if(fault == NoFault)
- {
- //Write the resulting state to the execution context
- %(op_wb)s;
- }
- return fault;
- }
-
- Fault %(class_name)s::completeAcc(PacketPtr, %(CPU_exec_context)s * xc,
- Trace::InstRecord * traceData) const
- {
- return NoFault;
- }
-}};
-
-def template LoadStoreExecute {{
- Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
- Trace::InstRecord *traceData) const
- {
- Fault fault = NoFault;
- uint64_t write_result = 0;
- Addr EA;
- %(op_decl)s;
- %(op_rd)s;
- %(priv_check)s;
- %(ea_code)s;
- DPRINTF(Sparc, "The address is 0x%x\n", EA);
- xc->read(EA, (uint%(mem_acc_size)s_t&)Mem, 0);
- %(code)s;
-
- if(fault == NoFault)
- {
- xc->write((uint%(mem_acc_size)s_t)Mem, EA, 0, &write_result);
- //Write the resulting state to the execution context
- %(op_wb)s;
- }
-
- return fault;
- }
-}};
-
-def template MemDeclare {{
- /**
- * Static instruction class for "%(mnemonic)s".
- */
- class %(class_name)s : public %(base_class)s
- {
- public:
-
- /// Constructor.
- %(class_name)s(ExtMachInst machInst);
-
- %(BasicExecDeclare)s
-
- %(InitiateAccDeclare)s
-
- %(CompleteAccDeclare)s
- };
-}};
-
-def template InitiateAccDeclare {{
- Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const;
-}};
-
-def template CompleteAccDeclare {{
- Fault completeAcc(PacketPtr, %(CPU_exec_context)s *, Trace::InstRecord *) const;
-}};
-
-
-let {{
- # XXX Need to take care of pstate.hpriv as well. The lower ASIs are split
- # into ones that are available in priv and hpriv, and those that are only
- # available in hpriv
- privilegedString = '''if(bits(Pstate,2,2) == 0 && (EXT_ASI & 0x80) == 0)
- return new PrivilegedAction;
- if(AsiIsAsIfUser(EXT_ASI) && !bits(Pstate,2,2))
- return new PrivilegedAction;'''
-
- def doMemFormat(code, execute, priv, name, Name, opt_flags):
- addrCalcReg = 'EA = Rs1 + Rs2;'
- addrCalcImm = 'EA = Rs1 + imm;'
- ea_iop = InstObjParams(name, Name, 'Mem',
- addrCalcReg, opt_flags, {"priv_check": priv})
- ea_iop_imm = InstObjParams(name, Name, 'MemImm',
- addrCalcImm, opt_flags, {"priv_check": priv})
- code_iop = InstObjParams(name, Name, 'Mem', code, opt_flags)
- iop = InstObjParams(name, Name, 'Mem', code,
- opt_flags, {"ea_code": addrCalcReg,
- "priv_check": priv})
- (iop.ea_decl,
- iop.ea_rd,
- iop.ea_wb) = (ea_iop.op_decl, ea_iop.op_rd, ea_iop.op_wb)
- (iop.code_decl,
- iop.code_rd,
- iop.code_wb) = (code_iop.op_decl, code_iop.op_rd, code_iop.op_wb)
- iop_imm = InstObjParams(name, Name + 'Imm', 'MemImm', code,
- opt_flags, {"ea_code": addrCalcImm,
- "priv_check": priv})
- (iop_imm.ea_decl,
- iop_imm.ea_rd,
- iop_imm.ea_wb) = (ea_iop_imm.op_decl, ea_iop_imm.op_rd, ea_iop_imm.op_wb)
- (iop_imm.code_decl,
- iop_imm.code_rd,
- iop_imm.code_wb) = (code_iop.op_decl, code_iop.op_rd, code_iop.op_wb)
- header_output = MemDeclare.subst(iop) + MemDeclare.subst(iop_imm)
- decoder_output = BasicConstructor.subst(iop) + BasicConstructor.subst(iop_imm)
- decode_block = ROrImmDecode.subst(iop)
- exec_output = execute.subst(iop) + execute.subst(iop_imm)
- return (header_output, decoder_output, exec_output, decode_block)
-}};
-
-def format LoadAlt(code, *opt_flags) {{
- (header_output,
- decoder_output,
- exec_output,
- decode_block) = doMemFormat(code, LoadExecute,
- privelegedString, name, Name, opt_flags)
-}};
-
-def format StoreAlt(code, *opt_flags) {{
- (header_output,
- decoder_output,
- exec_output,
- decode_block) = doMemFormat(code, StoreExecute,
- privilegedString, name, Name, opt_flags)
-}};
-
-def format Load(code, *opt_flags) {{
- (header_output,
- decoder_output,
- exec_output,
- decode_block) = doMemFormat(code,
- LoadExecute, '', name, Name, opt_flags)
-}};
-
-def format Store(code, *opt_flags) {{
- (header_output,
- decoder_output,
- exec_output,
- decode_block) = doMemFormat(code,
- StoreExecute, '', name, Name, opt_flags)
-}};
-
-def format LoadStore(code, *opt_flags) {{
- (header_output,
- decoder_output,
- exec_output,
- decode_block) = doMemFormat(code,
- LoadStoreExecute, '', name, Name, opt_flags)
-}};
diff --git a/src/arch/sparc/isa/formats/mem/basicmem.isa b/src/arch/sparc/isa/formats/mem/basicmem.isa
new file mode 100644
index 000000000..b524f309a
--- /dev/null
+++ b/src/arch/sparc/isa/formats/mem/basicmem.isa
@@ -0,0 +1,202 @@
+// 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
+
+////////////////////////////////////////////////////////////////////
+//
+// Mem instructions
+//
+
+output header {{
+ /**
+ * Base class for memory operations.
+ */
+ class Mem : public SparcStaticInst
+ {
+ protected:
+
+ // Constructor
+ Mem(const char *mnem, ExtMachInst _machInst, OpClass __opClass) :
+ SparcStaticInst(mnem, _machInst, __opClass)
+ {
+ }
+
+ std::string generateDisassembly(Addr pc,
+ const SymbolTable *symtab) const;
+ };
+
+ /**
+ * Class for memory operations which use an immediate offset.
+ */
+ class MemImm : public Mem
+ {
+ protected:
+
+ // Constructor
+ MemImm(const char *mnem, ExtMachInst _machInst, OpClass __opClass) :
+ Mem(mnem, _machInst, __opClass), imm(sext<13>(SIMM13))
+ {}
+
+ std::string generateDisassembly(Addr pc,
+ const SymbolTable *symtab) const;
+
+ const int32_t imm;
+ };
+}};
+
+output decoder {{
+ std::string Mem::generateDisassembly(Addr pc,
+ const SymbolTable *symtab) const
+ {
+ std::stringstream response;
+ bool load = flags[IsLoad];
+ bool save = flags[IsStore];
+
+ printMnemonic(response, mnemonic);
+ if(save)
+ {
+ printReg(response, _srcRegIdx[0]);
+ ccprintf(response, ", ");
+ }
+ ccprintf(response, "[ ");
+ printReg(response, _srcRegIdx[!save ? 0 : 1]);
+ ccprintf(response, " + ");
+ printReg(response, _srcRegIdx[!save ? 1 : 2]);
+ ccprintf(response, " ]");
+ if(load)
+ {
+ ccprintf(response, ", ");
+ printReg(response, _destRegIdx[0]);
+ }
+
+ return response.str();
+ }
+
+ std::string MemImm::generateDisassembly(Addr pc,
+ const SymbolTable *symtab) const
+ {
+ std::stringstream response;
+ bool load = flags[IsLoad];
+ bool save = flags[IsStore];
+
+ printMnemonic(response, mnemonic);
+ if(save)
+ {
+ printReg(response, _srcRegIdx[0]);
+ ccprintf(response, ", ");
+ }
+ ccprintf(response, "[ ");
+ printReg(response, _srcRegIdx[!save ? 0 : 1]);
+ if(imm >= 0)
+ ccprintf(response, " + 0x%x ]", imm);
+ else
+ ccprintf(response, " + -0x%x ]", -imm);
+ if(load)
+ {
+ ccprintf(response, ", ");
+ printReg(response, _destRegIdx[0]);
+ }
+
+ return response.str();
+ }
+}};
+
+def template MemDeclare {{
+ /**
+ * Static instruction class for "%(mnemonic)s".
+ */
+ class %(class_name)s : public %(base_class)s
+ {
+ public:
+
+ /// Constructor.
+ %(class_name)s(ExtMachInst machInst);
+
+ %(BasicExecDeclare)s
+
+ %(InitiateAccDeclare)s
+
+ %(CompleteAccDeclare)s
+ };
+}};
+
+let {{
+ # XXX Need to take care of pstate.hpriv as well. The lower ASIs are split
+ # into ones that are available in priv and hpriv, and those that are only
+ # available in hpriv
+ privilegedString = '''if(bits(Pstate,2,2) == 0 && (EXT_ASI & 0x80) == 0)
+ return new PrivilegedAction;
+ if(AsiIsAsIfUser(EXT_ASI) && !bits(Pstate,2,2))
+ return new PrivilegedAction;'''
+
+ def doMemFormat(code, execute, priv, name, Name, opt_flags):
+ addrCalcReg = 'EA = Rs1 + Rs2;'
+ addrCalcImm = 'EA = Rs1 + imm;'
+ iop = InstObjParams(name, Name, 'Mem', code,
+ opt_flags, {"priv_check": priv, "ea_code": addrCalcReg})
+ iop_imm = InstObjParams(name, Name + "Imm", 'MemImm', code,
+ opt_flags, {"priv_check": priv, "ea_code": addrCalcImm})
+ header_output = MemDeclare.subst(iop) + MemDeclare.subst(iop_imm)
+ decoder_output = BasicConstructor.subst(iop) + BasicConstructor.subst(iop_imm)
+ decode_block = ROrImmDecode.subst(iop)
+ exec_output = doSplitExecute(code, addrCalcReg, addrCalcImm, execute,
+ priv, name, name + "Imm", Name, Name + "Imm", opt_flags)
+ return (header_output, decoder_output, exec_output, decode_block)
+}};
+
+def format LoadAlt(code, *opt_flags) {{
+ (header_output,
+ decoder_output,
+ exec_output,
+ decode_block) = doMemFormat(code, LoadExecute,
+ privelegedString, name, Name, opt_flags)
+}};
+
+def format StoreAlt(code, *opt_flags) {{
+ (header_output,
+ decoder_output,
+ exec_output,
+ decode_block) = doMemFormat(code, StoreExecute,
+ privilegedString, name, Name, opt_flags)
+}};
+
+def format Load(code, *opt_flags) {{
+ (header_output,
+ decoder_output,
+ exec_output,
+ decode_block) = doMemFormat(code,
+ LoadExecute, '', name, Name, opt_flags)
+}};
+
+def format Store(code, *opt_flags) {{
+ (header_output,
+ decoder_output,
+ exec_output,
+ decode_block) = doMemFormat(code,
+ StoreExecute, '', name, Name, opt_flags)
+}};
diff --git a/src/arch/sparc/isa/formats/blockmem.isa b/src/arch/sparc/isa/formats/mem/blockmem.isa
index 4a2a14a15..8584662a1 100644
--- a/src/arch/sparc/isa/formats/blockmem.isa
+++ b/src/arch/sparc/isa/formats/mem/blockmem.isa
@@ -1,3 +1,32 @@
+// 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
+
////////////////////////////////////////////////////////////////////
//
// Block Memory instructions
@@ -12,9 +41,8 @@ output header {{
// Constructor
// We make the assumption that all block memory operations
// Will take 8 instructions to execute
- BlockMem(const char *mnem,
- ExtMachInst _machInst, OpClass __opClass) :
- SparcMacroInst(mnem, _machInst, __opClass, 8)
+ BlockMem(const char *mnem, ExtMachInst _machInst) :
+ SparcMacroInst(mnem, _machInst, No_OpClass, 8)
{}
};
@@ -23,13 +51,9 @@ output header {{
protected:
// Constructor
- BlockMemImm(const char *mnem,
- ExtMachInst _machInst, OpClass __opClass) :
- BlockMem(mnem, _machInst, __opClass),
- imm(sext<13>(SIMM13))
+ BlockMemImm(const char *mnem, ExtMachInst _machInst) :
+ BlockMem(mnem, _machInst)
{}
-
- const int32_t imm;
};
class BlockMemMicro : public SparcDelayedMicroInst
@@ -125,32 +149,6 @@ output decoder {{
}};
-def template LoadStoreExecute {{
- Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
- Trace::InstRecord *traceData) const
- {
- Fault fault = NoFault;
- uint64_t write_result = 0;
- Addr EA;
- %(op_decl)s;
- %(op_rd)s;
- %(priv_check)s;
- %(ea_code)s;
- DPRINTF(Sparc, "The address is 0x%x\n", EA);
- xc->read(EA, (uint%(mem_acc_size)s_t&)Mem, 0);
- %(code)s;
-
- if(fault == NoFault)
- {
- xc->write((uint%(mem_acc_size)s_t)Mem, EA, 0, &write_result);
- //Write the resulting state to the execution context
- %(op_wb)s;
- }
-
- return fault;
- }
-}};
-
def template BlockMemDeclare {{
/**
* Static instruction class for a block memory operation
@@ -231,7 +229,7 @@ def template BlockMemDeclare {{
// Basic instruction class constructor template.
def template BlockMemConstructor {{
inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
- : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
+ : %(base_class)s("%(mnemonic)s", machInst)
{
%(constructor)s;
microOps[0] = new %(class_name)s_0(machInst);
@@ -335,7 +333,7 @@ let {{
for microPC in range(8):
flag_code = ''
if (microPC == 7):
- flag_code = "flags[IsLastMicroOp] = true"
+ flag_code = "flags[IsLastMicroOp] = true;"
pcedCode = matcher.sub("Frd_%d" % microPC, code)
iop = InstObjParams(name, Name, 'BlockMem', pcedCode,
opt_flags, {"ea_code": addrCalcReg,
diff --git a/src/arch/sparc/isa/formats/mem/mem.isa b/src/arch/sparc/isa/formats/mem/mem.isa
new file mode 100644
index 000000000..20a22c45d
--- /dev/null
+++ b/src/arch/sparc/isa/formats/mem/mem.isa
@@ -0,0 +1,45 @@
+// 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
+
+////////////////////////////////////////////////////////////////////
+//
+// Mem formats
+//
+
+//Include mem utility templates and functions
+##include "util.isa"
+
+//Include the basic memory format
+##include "basicmem.isa"
+
+//Include the block memory format
+##include "blockmem.isa"
+
+//Include the load/store memory format
+##include "loadstore.isa"
diff --git a/src/arch/sparc/isa/formats/mem/util.isa b/src/arch/sparc/isa/formats/mem/util.isa
new file mode 100644
index 000000000..296ae1888
--- /dev/null
+++ b/src/arch/sparc/isa/formats/mem/util.isa
@@ -0,0 +1,183 @@
+// 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
+
+////////////////////////////////////////////////////////////////////
+//
+// Mem utility templates and functions
+//
+
+//This template provides the execute functions for a load
+def template LoadExecute {{
+ Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
+ Trace::InstRecord *traceData) const
+ {
+ Fault fault = NoFault;
+ Addr EA;
+ %(op_decl)s;
+ %(op_rd)s;
+ %(priv_check)s;
+ %(ea_code)s;
+ DPRINTF(Sparc, "The address is 0x%x\n", EA);
+ fault = xc->read(EA, (uint%(mem_acc_size)s_t&)Mem, 0);
+ %(code)s;
+ if(fault == NoFault)
+ {
+ //Write the resulting state to the execution context
+ %(op_wb)s;
+ }
+
+ return fault;
+ }
+
+ Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s * xc,
+ Trace::InstRecord * traceData) const
+ {
+ Fault fault = NoFault;
+ Addr EA;
+ uint%(mem_acc_size)s_t Mem;
+ %(ea_decl)s;
+ %(ea_rd)s;
+ %(priv_check)s;
+ %(ea_code)s;
+ fault = xc->read(EA, (uint%(mem_acc_size)s_t&)Mem, 0);
+ return fault;
+ }
+
+ Fault %(class_name)s::completeAcc(PacketPtr pkt, %(CPU_exec_context)s * xc,
+ Trace::InstRecord * traceData) const
+ {
+ Fault fault = NoFault;
+ %(code_decl)s;
+ %(code_rd)s;
+ Mem = pkt->get<typeof(Mem)>();
+ %(code)s;
+ if(fault == NoFault)
+ {
+ %(code_wb)s;
+ }
+ return fault;
+ }
+}};
+
+//This template provides the execute functions for a store
+def template StoreExecute {{
+ Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
+ Trace::InstRecord *traceData) const
+ {
+ Fault fault = NoFault;
+ uint64_t write_result = 0;
+ Addr EA;
+ %(op_decl)s;
+ %(op_rd)s;
+ %(priv_check)s;
+ %(ea_code)s;
+ DPRINTF(Sparc, "The address is 0x%x\n", EA);
+ %(code)s;
+
+ if(fault == NoFault)
+ {
+ fault = xc->write((uint%(mem_acc_size)s_t)Mem, EA, 0, &write_result);
+ }
+ if(fault == NoFault)
+ {
+ //Write the resulting state to the execution context
+ %(op_wb)s;
+ }
+
+ return fault;
+ }
+
+ Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s * xc,
+ Trace::InstRecord * traceData) const
+ {
+ Fault fault = NoFault;
+ uint64_t write_result = 0;
+ Addr EA;
+ %(op_decl)s;
+ %(op_rd)s;
+ %(priv_check)s;
+ %(ea_code)s;
+ DPRINTF(Sparc, "The address is 0x%x\n", EA);
+ %(code)s;
+ if(fault == NoFault)
+ {
+ fault = xc->write((uint%(mem_acc_size)s_t)Mem, EA, 0, &write_result);
+ }
+ if(fault == NoFault)
+ {
+ //Write the resulting state to the execution context
+ %(op_wb)s;
+ }
+ return fault;
+ }
+
+ Fault %(class_name)s::completeAcc(PacketPtr, %(CPU_exec_context)s * xc,
+ Trace::InstRecord * traceData) const
+ {
+ return NoFault;
+ }
+}};
+
+//This delcares the initiateAcc function in memory operations
+def template InitiateAccDeclare {{
+ Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const;
+}};
+
+//This declares the completeAcc function in memory operations
+def template CompleteAccDeclare {{
+ Fault completeAcc(PacketPtr, %(CPU_exec_context)s *, Trace::InstRecord *) const;
+}};
+
+//This function properly generates the execute functions for one of the
+//templates above. This is needed because in one case, ea computation,
+//privelege checks and the actual code all occur in the same function,
+//and in the other they're distributed across two. Also note that for
+//execute functions, the name of the base class doesn't matter.
+let {{
+ def doSplitExecute(code, eaRegCode, eaImmCode, execute,
+ priv, nameReg, nameImm, NameReg, NameImm, opt_flags):
+ codeIop = InstObjParams(nameReg, NameReg, '', code, opt_flags)
+ executeCode = ''
+ for (eaCode, name, Name) in (
+ (eaRegCode, nameReg, NameReg),
+ (eaImmCode, nameImm, NameImm)):
+ eaIop = InstObjParams(name, Name, '', eaCode,
+ opt_flags, {"priv_check": priv})
+ iop = InstObjParams(name, Name, '', code, opt_flags,
+ {"priv_check": priv, "ea_code" : eaCode})
+ (iop.ea_decl,
+ iop.ea_rd,
+ iop.ea_wb) = (eaIop.op_decl, eaIop.op_rd, eaIop.op_wb)
+ (iop.code_decl,
+ iop.code_rd,
+ iop.code_wb) = (codeIop.op_decl, codeIop.op_rd, codeIop.op_wb)
+ executeCode += execute.subst(iop)
+ return executeCode
+}};
diff --git a/src/arch/sparc/isa/includes.isa b/src/arch/sparc/isa/includes.isa
index 9fed36b03..a324756ec 100644
--- a/src/arch/sparc/isa/includes.isa
+++ b/src/arch/sparc/isa/includes.isa
@@ -49,6 +49,7 @@ output decoder {{
#include "base/cprintf.hh"
#include "base/loader/symtab.hh"
#include "cpu/thread_context.hh" // for Jump::branchTarget()
+#include "mem/packet.hh"
#if defined(linux)
#include <fenv.h>
@@ -66,6 +67,8 @@ output exec {{
#include "cpu/base.hh"
#include "cpu/exetrace.hh"
#include "sim/sim_exit.hh"
+#include "mem/packet.hh"
+#include "mem/packet_access.hh"
using namespace SparcISA;
}};
diff --git a/src/arch/sparc/isa/main.isa b/src/arch/sparc/isa/main.isa
index 765c98ed1..df5ad0c99 100644
--- a/src/arch/sparc/isa/main.isa
+++ b/src/arch/sparc/isa/main.isa
@@ -55,7 +55,7 @@ namespace SparcISA;
##include "base.isa"
//Include the definitions for the instruction formats
-##include "formats.isa"
+##include "formats/formats.isa"
//Include the decoder definition
##include "decoder.isa"
diff --git a/src/arch/sparc/isa/operands.isa b/src/arch/sparc/isa/operands.isa
index 40926a5fb..b8b75170b 100644
--- a/src/arch/sparc/isa/operands.isa
+++ b/src/arch/sparc/isa/operands.isa
@@ -77,7 +77,6 @@ def operands {{
'Frs1': ('FloatReg', 'df', 'dfpr(RS1)', 'IsFloating', 11),
'Frs2s': ('FloatReg', 'df', 'RS2', 'IsFloating', 12),
'Frs2': ('FloatReg', 'df', 'dfpr(RS2)', 'IsFloating', 12),
- 'Mem': ('Mem', 'udw', None, ('IsMemRef', 'IsLoad', 'IsStore'), 20),
'NPC': ('NPC', 'udw', None, ( None, None, 'IsControl' ), 31),
'NNPC': ('NNPC', 'udw', None, (None, None, 'IsControl' ), 32),
#'Runiq': ('ControlReg', 'uq', 'Uniq', None, 1),
@@ -107,6 +106,8 @@ def operands {{
'Gl': ('ControlReg', 'udw', 'MISCREG_GL', None, 54),
'Fsr': ('ControlReg', 'udw', 'MISCREG_FSR', None, 55),
- 'Gsr': ('ControlReg', 'udw', 'MISCREG_GSR', None, 56)
+ 'Gsr': ('ControlReg', 'udw', 'MISCREG_GSR', None, 56),
+ # Mem gets a large number so it's always last
+ 'Mem': ('Mem', 'udw', None, ('IsMemRef', 'IsLoad', 'IsStore'), 100)
}};