summaryrefslogtreecommitdiff
path: root/src/arch/sparc/isa/formats/mem/blockmem.isa
diff options
context:
space:
mode:
Diffstat (limited to 'src/arch/sparc/isa/formats/mem/blockmem.isa')
-rw-r--r--src/arch/sparc/isa/formats/mem/blockmem.isa368
1 files changed, 368 insertions, 0 deletions
diff --git a/src/arch/sparc/isa/formats/mem/blockmem.isa b/src/arch/sparc/isa/formats/mem/blockmem.isa
new file mode 100644
index 000000000..8584662a1
--- /dev/null
+++ b/src/arch/sparc/isa/formats/mem/blockmem.isa
@@ -0,0 +1,368 @@
+// 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
+//
+
+output header {{
+
+ class BlockMem : public SparcMacroInst
+ {
+ protected:
+
+ // Constructor
+ // We make the assumption that all block memory operations
+ // Will take 8 instructions to execute
+ BlockMem(const char *mnem, ExtMachInst _machInst) :
+ SparcMacroInst(mnem, _machInst, No_OpClass, 8)
+ {}
+ };
+
+ class BlockMemImm : public BlockMem
+ {
+ protected:
+
+ // Constructor
+ BlockMemImm(const char *mnem, ExtMachInst _machInst) :
+ BlockMem(mnem, _machInst)
+ {}
+ };
+
+ class BlockMemMicro : public SparcDelayedMicroInst
+ {
+ protected:
+
+ // Constructor
+ BlockMemMicro(const char *mnem, ExtMachInst _machInst,
+ OpClass __opClass, int8_t _offset) :
+ SparcDelayedMicroInst(mnem, _machInst, __opClass),
+ offset(_offset)
+ {}
+
+ std::string generateDisassembly(Addr pc,
+ const SymbolTable *symtab) const;
+
+ const int8_t offset;
+ };
+
+ class BlockMemImmMicro : public BlockMemMicro
+ {
+ protected:
+
+ // Constructor
+ BlockMemImmMicro(const char *mnem, ExtMachInst _machInst,
+ OpClass __opClass, int8_t _offset) :
+ BlockMemMicro(mnem, _machInst, __opClass, _offset),
+ imm(sext<13>(SIMM13))
+ {}
+
+ std::string generateDisassembly(Addr pc,
+ const SymbolTable *symtab) const;
+
+ const int32_t imm;
+ };
+}};
+
+output decoder {{
+ std::string BlockMemMicro::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 BlockMemImmMicro::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[1]);
+ ccprintf(response, ", ");
+ }
+ ccprintf(response, "[ ");
+ printReg(response, _srcRegIdx[0]);
+ 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 BlockMemDeclare {{
+ /**
+ * Static instruction class for a block memory operation
+ */
+ class %(class_name)s : public %(base_class)s
+ {
+ public:
+ //Constructor
+ %(class_name)s(ExtMachInst machInst);
+
+ protected:
+ class %(class_name)s_0 : public %(base_class)sMicro
+ {
+ public:
+ //Constructor
+ %(class_name)s_0(ExtMachInst machInst);
+ %(BasicExecDeclare)s
+ };
+
+ class %(class_name)s_1 : public %(base_class)sMicro
+ {
+ public:
+ //Constructor
+ %(class_name)s_1(ExtMachInst machInst);
+ %(BasicExecDeclare)s
+ };
+
+ class %(class_name)s_2 : public %(base_class)sMicro
+ {
+ public:
+ //Constructor
+ %(class_name)s_2(ExtMachInst machInst);
+ %(BasicExecDeclare)s
+ };
+
+ class %(class_name)s_3 : public %(base_class)sMicro
+ {
+ public:
+ //Constructor
+ %(class_name)s_3(ExtMachInst machInst);
+ %(BasicExecDeclare)s
+ };
+
+ class %(class_name)s_4 : public %(base_class)sMicro
+ {
+ public:
+ //Constructor
+ %(class_name)s_4(ExtMachInst machInst);
+ %(BasicExecDeclare)s
+ };
+
+ class %(class_name)s_5 : public %(base_class)sMicro
+ {
+ public:
+ //Constructor
+ %(class_name)s_5(ExtMachInst machInst);
+ %(BasicExecDeclare)s
+ };
+
+ class %(class_name)s_6 : public %(base_class)sMicro
+ {
+ public:
+ //Constructor
+ %(class_name)s_6(ExtMachInst machInst);
+ %(BasicExecDeclare)s
+ };
+
+ class %(class_name)s_7 : public %(base_class)sMicro
+ {
+ public:
+ //Constructor
+ %(class_name)s_7(ExtMachInst machInst);
+ %(BasicExecDeclare)s
+ };
+ };
+}};
+
+// Basic instruction class constructor template.
+def template BlockMemConstructor {{
+ inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
+ : %(base_class)s("%(mnemonic)s", machInst)
+ {
+ %(constructor)s;
+ microOps[0] = new %(class_name)s_0(machInst);
+ microOps[1] = new %(class_name)s_1(machInst);
+ microOps[2] = new %(class_name)s_2(machInst);
+ microOps[3] = new %(class_name)s_3(machInst);
+ microOps[4] = new %(class_name)s_4(machInst);
+ microOps[5] = new %(class_name)s_5(machInst);
+ microOps[6] = new %(class_name)s_6(machInst);
+ microOps[7] = new %(class_name)s_7(machInst);
+ }
+}};
+
+def template BlockMemMicroConstructor {{
+ inline %(class_name)s::
+ %(class_name)s_%(micro_pc)s::
+ %(class_name)s_%(micro_pc)s(ExtMachInst machInst) :
+ %(base_class)sMicro("%(mnemonic)s[%(micro_pc)s]",
+ machInst, %(op_class)s, %(micro_pc)s * 8)
+ {
+ %(constructor)s;
+ %(set_flags)s;
+ }
+}};
+
+def template MicroLoadExecute {{
+ Fault %(class_name)s::%(class_name)s_%(micro_pc)s::execute(
+ %(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
+ {
+ Fault fault = NoFault;
+ Addr EA;
+ %(op_decl)s;
+ %(op_rd)s;
+ %(ea_code)s;
+ %(fault_check)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)
+ {
+ //Write the resulting state to the execution context
+ %(op_wb)s;
+ }
+
+ return fault;
+ }
+}};
+
+def template MicroStoreExecute {{
+ Fault %(class_name)s::%(class_name)s_%(micro_pc)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;
+ %(ea_code)s;
+ %(fault_check)s;
+ DPRINTF(Sparc, "The address is 0x%x\n", EA);
+ %(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;
+ }
+}};
+
+let {{
+
+ def doBlockMemFormat(code, execute, name, Name, opt_flags):
+ # 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
+ faultCheck = '''if(bits(Pstate,2,2) == 0 && (EXT_ASI & 0x80) == 0)
+ return new PrivilegedAction;
+ if(AsiIsAsIfUser((ASI)EXT_ASI) && !bits(Pstate,2,2))
+ return new PrivilegedAction;
+ //The LSB can be zero, since it's really the MSB in doubles
+ //and quads
+ if(RD & 0xe)
+ return new IllegalInstruction;
+ if(EA & 0x3f)
+ return new MemAddressNotAligned;
+ '''
+ addrCalcReg = 'EA = Rs1 + Rs2 + offset;'
+ addrCalcImm = 'EA = Rs1 + imm + offset;'
+ iop = InstObjParams(name, Name, 'BlockMem', code, opt_flags)
+ iop_imm = InstObjParams(name, Name + 'Imm', 'BlockMemImm', code, opt_flags)
+ header_output = BlockMemDeclare.subst(iop) + BlockMemDeclare.subst(iop_imm)
+ decoder_output = BlockMemConstructor.subst(iop) + BlockMemConstructor.subst(iop_imm)
+ decode_block = ROrImmDecode.subst(iop)
+ matcher = re.compile(r'Frd_N')
+ exec_output = ''
+ for microPC in range(8):
+ flag_code = ''
+ if (microPC == 7):
+ flag_code = "flags[IsLastMicroOp] = true;"
+ pcedCode = matcher.sub("Frd_%d" % microPC, code)
+ iop = InstObjParams(name, Name, 'BlockMem', pcedCode,
+ opt_flags, {"ea_code": addrCalcReg,
+ "fault_check": faultCheck, "micro_pc": microPC,
+ "set_flags": flag_code})
+ iop_imm = InstObjParams(name, Name + 'Imm', 'BlockMemImm', pcedCode,
+ opt_flags, {"ea_code": addrCalcImm,
+ "fault_check": faultCheck, "micro_pc": microPC,
+ "set_flags": flag_code})
+ exec_output += execute.subst(iop)
+ exec_output += execute.subst(iop_imm)
+ decoder_output += BlockMemMicroConstructor.subst(iop)
+ decoder_output += BlockMemMicroConstructor.subst(iop_imm)
+ faultCheck = ''
+ return (header_output, decoder_output, exec_output, decode_block)
+}};
+
+def format BlockLoad(code, *opt_flags) {{
+ (header_output,
+ decoder_output,
+ exec_output,
+ decode_block) = doBlockMemFormat(code, MicroLoadExecute,
+ name, Name, opt_flags)
+}};
+
+def format BlockStore(code, *opt_flags) {{
+ (header_output,
+ decoder_output,
+ exec_output,
+ decode_block) = doBlockMemFormat(code, MicroStoreExecute,
+ name, Name, opt_flags)
+}};