summaryrefslogtreecommitdiff
path: root/src/arch/power/isa/formats/mem.isa
diff options
context:
space:
mode:
Diffstat (limited to 'src/arch/power/isa/formats/mem.isa')
-rw-r--r--src/arch/power/isa/formats/mem.isa351
1 files changed, 351 insertions, 0 deletions
diff --git a/src/arch/power/isa/formats/mem.isa b/src/arch/power/isa/formats/mem.isa
new file mode 100644
index 000000000..1be49c2f7
--- /dev/null
+++ b/src/arch/power/isa/formats/mem.isa
@@ -0,0 +1,351 @@
+// -*- mode:c++ -*-
+
+// Copyright (c) 2009 The University of Edinburgh
+// 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: Timothy M. Jones
+
+////////////////////////////////////////////////////////////////////
+//
+// Memory-format instructions
+//
+
+def template LoadStoreDeclare {{
+ /**
+ * 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;
+}};
+
+
+def template LoadStoreConstructor {{
+ inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
+ : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
+ {
+ %(constructor)s;
+ }
+}};
+
+
+def template LoadExecute {{
+ Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
+ Trace::InstRecord *traceData) const
+ {
+ Addr EA;
+ Fault fault = NoFault;
+
+ %(op_decl)s;
+ %(op_rd)s;
+ %(ea_code)s;
+
+ if (fault == NoFault) {
+ fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags);
+ %(memacc_code)s;
+ }
+
+ if (fault == NoFault) {
+ %(op_wb)s;
+ }
+
+ return fault;
+ }
+}};
+
+
+def template LoadInitiateAcc {{
+ Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
+ Trace::InstRecord *traceData) const
+ {
+ Addr EA;
+ Fault fault = NoFault;
+
+ %(op_src_decl)s;
+ %(op_rd)s;
+ %(ea_code)s;
+
+ if (fault == NoFault) {
+ fault = xc->read(EA, (uint%(mem_acc_size)d_t &)Mem, memAccessFlags);
+ xc->setEA(EA);
+ }
+
+ return fault;
+ }
+}};
+
+
+def template LoadCompleteAcc {{
+ Fault %(class_name)s::completeAcc(PacketPtr pkt,
+ %(CPU_exec_context)s *xc,
+ Trace::InstRecord *traceData) const
+ {
+ Addr EA;
+ Fault fault = NoFault;
+ uint%(mem_acc_size)d_t val;
+
+ %(op_decl)s;
+ %(op_rd)s;
+
+ EA = xc->getEA();
+
+ val = pkt->get<uint%(mem_acc_size)d_t>();
+ *((uint%(mem_acc_size)d_t*)&Mem) = val;
+
+ if (fault == NoFault) {
+ %(memacc_code)s;
+ }
+
+ if (fault == NoFault) {
+ %(op_wb)s;
+ }
+
+ return fault;
+ }
+}};
+
+
+def template StoreExecute {{
+ Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
+ Trace::InstRecord *traceData) const
+ {
+ Addr EA;
+ Fault fault = NoFault;
+
+ %(op_decl)s;
+ %(op_rd)s;
+ %(ea_code)s;
+
+ if (fault == NoFault) {
+ %(memacc_code)s;
+ }
+
+ if (fault == NoFault) {
+ fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
+ memAccessFlags, NULL);
+ if (traceData) { traceData->setData(Mem); }
+ }
+
+ if (fault == NoFault) {
+ %(op_wb)s;
+ }
+
+ return fault;
+ }
+}};
+
+
+def template StoreInitiateAcc {{
+ Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
+ Trace::InstRecord *traceData) const
+ {
+ Addr EA;
+ Fault fault = NoFault;
+
+ %(op_decl)s;
+ %(op_rd)s;
+ %(ea_code)s;
+
+ if (fault == NoFault) {
+ %(memacc_code)s;
+ }
+
+ if (fault == NoFault) {
+ fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
+ memAccessFlags, NULL);
+ if (traceData) { traceData->setData(Mem); }
+ }
+
+ // Need to write back any potential address register update
+ if (fault == NoFault) {
+ %(op_wb)s;
+ }
+
+ return fault;
+ }
+}};
+
+
+def template StoreCompleteAcc {{
+ Fault %(class_name)s::completeAcc(PacketPtr pkt,
+ %(CPU_exec_context)s *xc,
+ Trace::InstRecord *traceData) const
+ {
+ Fault fault = NoFault;
+
+ %(op_dest_decl)s;
+
+ if (fault == NoFault) {
+ %(op_wb)s;
+ }
+
+ return fault;
+ }
+}};
+
+
+// The generic memory operation generator. This is called when two versions
+// of an instruction are needed - when Ra == 0 and otherwise. This is so
+// that instructions can use the value 0 when Ra == 0 but avoid having a
+// dependence on Ra.
+let {{
+
+def GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0, base,
+ load_or_store, mem_flags = [], inst_flags = []):
+
+ # First the version where Ra is non-zero
+ (header_output, decoder_output, decode_block, exec_output) = \
+ LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
+ base_class = base,
+ decode_template = CheckRaDecode,
+ exec_template_base = load_or_store)
+
+ # Now another version where Ra == 0
+ (header_output_ra0, decoder_output_ra0, _, exec_output_ra0) = \
+ LoadStoreBase(name, Name + 'RaZero', ea_code_ra0, memacc_code,
+ mem_flags, inst_flags,
+ base_class = base,
+ exec_template_base = load_or_store)
+
+ # Finally, add to the other outputs
+ header_output += header_output_ra0
+ decoder_output += decoder_output_ra0
+ exec_output += exec_output_ra0
+ return (header_output, decoder_output, decode_block, exec_output)
+
+}};
+
+
+def format LoadIndexOp(memacc_code, ea_code = {{ EA = Ra + Rb; }},
+ ea_code_ra0 = {{ EA = Rb; }},
+ mem_flags = [], inst_flags = []) {{
+ (header_output, decoder_output, decode_block, exec_output) = \
+ GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0,
+ 'MemOp', 'Load', mem_flags, inst_flags)
+}};
+
+
+def format StoreIndexOp(memacc_code, ea_code = {{ EA = Ra + Rb; }},
+ ea_code_ra0 = {{ EA = Rb; }},
+ mem_flags = [], inst_flags = []) {{
+ (header_output, decoder_output, decode_block, exec_output) = \
+ GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0,
+ 'MemOp', 'Store', mem_flags, inst_flags)
+}};
+
+
+def format LoadIndexUpdateOp(memacc_code, ea_code = {{ EA = Ra + Rb; }},
+ mem_flags = [], inst_flags = []) {{
+
+ # Add in the update code
+ memacc_code += 'Ra = EA;'
+
+ # Generate the class
+ (header_output, decoder_output, decode_block, exec_output) = \
+ LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
+ base_class = 'MemOp',
+ exec_template_base = 'Load')
+}};
+
+
+def format StoreIndexUpdateOp(memacc_code, ea_code = {{ EA = Ra + Rb; }},
+ mem_flags = [], inst_flags = []) {{
+
+ # Add in the update code
+ memacc_code += 'Ra = EA;'
+
+ # Generate the class
+ (header_output, decoder_output, decode_block, exec_output) = \
+ LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
+ base_class = 'MemOp',
+ exec_template_base = 'Store')
+}};
+
+
+def format LoadDispOp(memacc_code, ea_code = {{ EA = Ra + disp; }},
+ ea_code_ra0 = {{ EA = disp; }},
+ mem_flags = [], inst_flags = []) {{
+ (header_output, decoder_output, decode_block, exec_output) = \
+ GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0,
+ 'MemDispOp', 'Load', mem_flags, inst_flags)
+}};
+
+
+def format StoreDispOp(memacc_code, ea_code = {{ EA = Ra + disp; }},
+ ea_code_ra0 = {{ EA = disp; }},
+ mem_flags = [], inst_flags = []) {{
+ (header_output, decoder_output, decode_block, exec_output) = \
+ GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0,
+ 'MemDispOp', 'Store', mem_flags, inst_flags)
+}};
+
+
+def format LoadDispUpdateOp(memacc_code, ea_code = {{ EA = Ra + disp; }},
+ mem_flags = [], inst_flags = []) {{
+
+ # Add in the update code
+ memacc_code += 'Ra = EA;'
+
+ # Generate the class
+ (header_output, decoder_output, decode_block, exec_output) = \
+ LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
+ base_class = 'MemDispOp',
+ exec_template_base = 'Load')
+}};
+
+
+def format StoreDispUpdateOp(memacc_code, ea_code = {{ EA = Ra + disp; }},
+ mem_flags = [], inst_flags = []) {{
+
+ # Add in the update code
+ memacc_code += 'Ra = EA;'
+
+ # Generate the class
+ (header_output, decoder_output, decode_block, exec_output) = \
+ LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
+ base_class = 'MemDispOp',
+ exec_template_base = 'Store')
+}};