Broke Load/Store instructions into microcode, and partially refactored memory operati...
authorGabe Black <gblack@eecs.umich.edu>
Mon, 23 Oct 2006 11:55:52 +0000 (07:55 -0400)
committerGabe Black <gblack@eecs.umich.edu>
Mon, 23 Oct 2006 11:55:52 +0000 (07:55 -0400)
--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

12 files changed:
src/arch/sparc/isa/decoder.isa
src/arch/sparc/isa/formats.isa [deleted file]
src/arch/sparc/isa/formats/blockmem.isa [deleted file]
src/arch/sparc/isa/formats/formats.isa [new file with mode: 0644]
src/arch/sparc/isa/formats/mem.isa [deleted file]
src/arch/sparc/isa/formats/mem/basicmem.isa [new file with mode: 0644]
src/arch/sparc/isa/formats/mem/blockmem.isa [new file with mode: 0644]
src/arch/sparc/isa/formats/mem/mem.isa [new file with mode: 0644]
src/arch/sparc/isa/formats/mem/util.isa [new file with mode: 0644]
src/arch/sparc/isa/includes.isa
src/arch/sparc/isa/main.isa
src/arch/sparc/isa/operands.isa

index 9da6bdd33a05bcbadcbbfc67e88b058d9296563c..45d3616d95c892815b31d63d8a0577351a9f1549 100644 (file)
@@ -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 (file)
index e044aee..0000000
+++ /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/blockmem.isa b/src/arch/sparc/isa/formats/blockmem.isa
deleted file mode 100644 (file)
index 4a2a14a..0000000
+++ /dev/null
@@ -1,370 +0,0 @@
-////////////////////////////////////////////////////////////////////
-//
-// 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, OpClass __opClass) :
-                SparcMacroInst(mnem, _machInst, __opClass, 8)
-            {}
-        };
-
-        class BlockMemImm : public BlockMem
-        {
-          protected:
-
-            // Constructor
-            BlockMemImm(const char *mnem,
-                    ExtMachInst _machInst, OpClass __opClass) :
-                BlockMem(mnem, _machInst, __opClass),
-                imm(sext<13>(SIMM13))
-            {}
-
-            const int32_t imm;
-        };
-
-        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 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
-         */
-        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, %(op_class)s)
-        {
-            %(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)
-}};
diff --git a/src/arch/sparc/isa/formats/formats.isa b/src/arch/sparc/isa/formats/formats.isa
new file mode 100644 (file)
index 0000000..5b81a1a
--- /dev/null
@@ -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 (file)
index 2d3dd3d..0000000
+++ /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 (file)
index 0000000..b524f30
--- /dev/null
@@ -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/mem/blockmem.isa b/src/arch/sparc/isa/formats/mem/blockmem.isa
new file mode 100644 (file)
index 0000000..8584662
--- /dev/null
@@ -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)
+}};
diff --git a/src/arch/sparc/isa/formats/mem/mem.isa b/src/arch/sparc/isa/formats/mem/mem.isa
new file mode 100644 (file)
index 0000000..20a22c4
--- /dev/null
@@ -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 (file)
index 0000000..296ae18
--- /dev/null
@@ -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
+}};
index 9fed36b03af87c085ba9277abf5b55425b313915..a324756ec14d3408e6981dc1a01d9e999e63421c 100644 (file)
@@ -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;
 }};
index 765c98ed1222f0f353c19406c1897ec78a5ed37c..df5ad0c99900c3601147626d9ec1825598d6933b 100644 (file)
@@ -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"
index 40926a5fb79f5112b6713627c72096e66a8a8503..b8b75170b0a6a70daab1a96e948305492c47f37d 100644 (file)
@@ -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)
 
 }};