util.isa revision 3391:3b6298cab636
1// Copyright (c) 2006 The Regents of The University of Michigan
2// All rights reserved.
3//
4// Redistribution and use in source and binary forms, with or without
5// modification, are permitted provided that the following conditions are
6// met: redistributions of source code must retain the above copyright
7// notice, this list of conditions and the following disclaimer;
8// redistributions in binary form must reproduce the above copyright
9// notice, this list of conditions and the following disclaimer in the
10// documentation and/or other materials provided with the distribution;
11// neither the name of the copyright holders nor the names of its
12// contributors may be used to endorse or promote products derived from
13// this software without specific prior written permission.
14//
15// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
19// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26//
27// Authors: Ali Saidi
28//          Gabe Black
29//          Steve Reinhardt
30
31////////////////////////////////////////////////////////////////////
32//
33// Mem utility templates and functions
34//
35
36//This template provides the execute functions for a load
37def template LoadExecute {{
38        Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
39                Trace::InstRecord *traceData) const
40        {
41            Fault fault = NoFault;
42            Addr EA;
43            %(op_decl)s;
44            %(op_rd)s;
45            %(ea_code)s;
46            DPRINTF(Sparc, "The address is 0x%x\n", EA);
47            %(fault_check)s;
48            if(fault == NoFault)
49            {
50                fault = xc->read(EA, (uint%(mem_acc_size)s_t&)Mem, 0);
51            }
52            if(fault == NoFault)
53            {
54                %(code)s;
55            }
56            if(fault == NoFault)
57            {
58                //Write the resulting state to the execution context
59                %(op_wb)s;
60            }
61
62            return fault;
63        }
64
65        Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s * xc,
66                Trace::InstRecord * traceData) const
67        {
68            Fault fault = NoFault;
69            Addr EA;
70            uint%(mem_acc_size)s_t Mem;
71            %(ea_decl)s;
72            %(ea_rd)s;
73            %(ea_code)s;
74            %(fault_check)s;
75            if(fault == NoFault)
76            {
77                fault = xc->read(EA, (uint%(mem_acc_size)s_t&)Mem, 0);
78            }
79            return fault;
80        }
81
82        Fault %(class_name)s::completeAcc(PacketPtr pkt, %(CPU_exec_context)s * xc,
83                Trace::InstRecord * traceData) const
84        {
85            Fault fault = NoFault;
86            %(code_decl)s;
87            %(code_rd)s;
88            Mem = pkt->get<typeof(Mem)>();
89            %(code)s;
90            if(fault == NoFault)
91            {
92                %(code_wb)s;
93            }
94            return fault;
95        }
96}};
97
98//This template provides the execute functions for a store
99def template StoreExecute {{
100        Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
101                Trace::InstRecord *traceData) const
102        {
103            Fault fault = NoFault;
104            uint64_t write_result = 0;
105            Addr EA;
106            %(op_decl)s;
107            %(op_rd)s;
108            %(ea_code)s;
109            DPRINTF(Sparc, "The address is 0x%x\n", EA);
110            %(fault_check)s;
111            if(fault == NoFault)
112            {
113                %(code)s;
114            }
115            if(fault == NoFault)
116            {
117                fault = xc->write((uint%(mem_acc_size)s_t)Mem, EA, 0, &write_result);
118            }
119            if(fault == NoFault)
120            {
121                //Write the resulting state to the execution context
122                %(op_wb)s;
123            }
124
125            return fault;
126        }
127
128        Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s * xc,
129                Trace::InstRecord * traceData) const
130        {
131            Fault fault = NoFault;
132            uint64_t write_result = 0;
133            Addr EA;
134            %(op_decl)s;
135            %(op_rd)s;
136            %(ea_code)s;
137            DPRINTF(Sparc, "The address is 0x%x\n", EA);
138            %(fault_check)s;
139            if(fault == NoFault)
140            {
141                %(code)s;
142            }
143            if(fault == NoFault)
144            {
145                fault = xc->write((uint%(mem_acc_size)s_t)Mem, EA, 0, &write_result);
146            }
147            if(fault == NoFault)
148            {
149                //Write the resulting state to the execution context
150                %(op_wb)s;
151            }
152            return fault;
153        }
154
155        Fault %(class_name)s::completeAcc(PacketPtr, %(CPU_exec_context)s * xc,
156                Trace::InstRecord * traceData) const
157        {
158            return NoFault;
159        }
160}};
161
162//This delcares the initiateAcc function in memory operations
163def template InitiateAccDeclare {{
164    Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const;
165}};
166
167//This declares the completeAcc function in memory operations
168def template CompleteAccDeclare {{
169    Fault completeAcc(PacketPtr, %(CPU_exec_context)s *, Trace::InstRecord *) const;
170}};
171
172//Here are some code snippets which check for various fault conditions
173let {{
174    # The LSB can be zero, since it's really the MSB in doubles and quads
175    # and we're dealing with doubles
176    BlockAlignmentFaultCheck = '''
177        if(RD & 0xe)
178            fault = new IllegalInstruction;
179        else if(EA & 0x3f)
180            fault = new MemAddressNotAligned;
181    '''
182    # XXX Need to take care of pstate.hpriv as well. The lower ASIs
183    # are split into ones that are available in priv and hpriv, and
184    # those that are only available in hpriv
185    AlternateASIPrivFaultCheck = '''
186        if(bits(Pstate,2,2) == 0 && (EXT_ASI & 0x80) == 0)
187            fault = new PrivilegedAction;
188        else if(AsiIsAsIfUser((ASI)EXT_ASI) && !bits(Pstate,2,2))
189            fault = new PrivilegedAction;
190    '''
191
192}};
193
194//A simple function to generate the name of the macro op of a certain
195//instruction at a certain micropc
196let {{
197    def makeMicroName(name, microPc):
198        return name + "::" + name + "_" + str(microPc)
199}};
200
201//This function properly generates the execute functions for one of the
202//templates above. This is needed because in one case, ea computation,
203//fault checks and the actual code all occur in the same function,
204//and in the other they're distributed across two. Also note that for
205//execute functions, the name of the base class doesn't matter.
206let {{
207    def doSplitExecute(code, eaRegCode, eaImmCode, execute,
208            faultCode, nameReg, nameImm, NameReg, NameImm, opt_flags):
209        codeIop = InstObjParams(nameReg, NameReg, '', code, opt_flags)
210        executeCode = ''
211        for (eaCode, name, Name) in (
212                (eaRegCode, nameReg, NameReg),
213                (eaImmCode, nameImm, NameImm)):
214            eaIop = InstObjParams(name, Name, '', eaCode,
215                    opt_flags, {"fault_check": faultCode})
216            iop = InstObjParams(name, Name, '', code, opt_flags,
217                    {"fault_check": faultCode, "ea_code" : eaCode})
218            (iop.ea_decl,
219             iop.ea_rd,
220             iop.ea_wb) = (eaIop.op_decl, eaIop.op_rd, eaIop.op_wb)
221            (iop.code_decl,
222             iop.code_rd,
223             iop.code_wb) = (codeIop.op_decl, codeIop.op_rd, codeIop.op_wb)
224            executeCode += execute.subst(iop)
225        return executeCode
226}};
227