util.isa (12294:650a9d8b23cc) util.isa (12385:288c62455dde)
1// Copyright (c) 2006-2007 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(ExecContext *xc,
39 Trace::InstRecord *traceData) const
40 {
41 Fault fault = NoFault;
42 Addr EA;
43 %(fp_enable_check)s;
44 %(op_decl)s;
45 %(op_rd)s;
46 %(ea_code)s;
47 DPRINTF(Sparc, "%s: The address is 0x%x\n", mnemonic, EA);
48 %(fault_check)s;
49 if (fault == NoFault) {
50 %(EA_trunc)s
51 fault = readMemAtomic(xc, traceData, EA, Mem, %(asi_val)s);
52 }
53 if (fault == NoFault) {
54 %(code)s;
55 }
56 if (fault == NoFault) {
57 // Write the resulting state to the execution context
58 %(op_wb)s;
59 }
60
61 return fault;
62 }
63}};
64
65def template LoadInitiateAcc {{
66 Fault %(class_name)s::initiateAcc(ExecContext * xc,
67 Trace::InstRecord * traceData) const
68 {
69 Fault fault = NoFault;
70 Addr EA;
71 %(fp_enable_check)s;
72 %(op_decl)s;
73 %(op_rd)s;
74 %(ea_code)s;
75 DPRINTF(Sparc, "%s: The address is 0x%x\n", mnemonic, EA);
76 %(fault_check)s;
77 if (fault == NoFault) {
78 %(EA_trunc)s
79 fault = initiateMemRead(xc, traceData, EA, Mem, %(asi_val)s);
80 }
81 return fault;
82 }
83}};
84
85def template LoadCompleteAcc {{
86 Fault %(class_name)s::completeAcc(PacketPtr pkt, ExecContext * xc,
87 Trace::InstRecord * traceData) const
88 {
89 Fault fault = NoFault;
90 %(op_decl)s;
91 %(op_rd)s;
92 getMem(pkt, Mem, traceData);
93 %(code)s;
94 if (fault == NoFault) {
95 %(op_wb)s;
96 }
97 return fault;
98 }
99}};
100
101// This template provides the execute functions for a store
102def template StoreExecute {{
103 Fault %(class_name)s::execute(ExecContext *xc,
104 Trace::InstRecord *traceData) const
105 {
106 Fault fault = NoFault;
107 // This is to support the conditional store in cas instructions.
108 // It should be optomized out in all the others
109 bool storeCond = true;
110 Addr EA;
111 %(fp_enable_check)s;
112 %(op_decl)s;
113 %(op_rd)s;
114 %(ea_code)s;
115 DPRINTF(Sparc, "%s: The address is 0x%x\n", mnemonic, EA);
116 %(fault_check)s;
117 if (fault == NoFault) {
118 %(code)s;
119 }
120 if (storeCond && fault == NoFault) {
121 %(EA_trunc)s
122 fault = writeMemAtomic(xc, traceData, Mem, EA, %(asi_val)s, 0);
123 }
124 if (fault == NoFault) {
125 // Write the resulting state to the execution context
126 %(op_wb)s;
127 }
128
129 return fault;
130 }
131}};
132
133def template StoreInitiateAcc {{
134 Fault %(class_name)s::initiateAcc(ExecContext * xc,
135 Trace::InstRecord * traceData) const
136 {
137 Fault fault = NoFault;
138 bool storeCond = true;
139 Addr EA;
140 %(fp_enable_check)s;
141 %(op_decl)s;
142
143 %(op_rd)s;
144 %(ea_code)s;
145 DPRINTF(Sparc, "%s: The address is 0x%x\n", mnemonic, EA);
146 %(fault_check)s;
147 if (fault == NoFault) {
148 %(code)s;
149 }
150 if (storeCond && fault == NoFault) {
151 %(EA_trunc)s
152 fault = writeMemTiming(xc, traceData, Mem, EA, %(asi_val)s, 0);
153 }
154 return fault;
155 }
156}};
157
158def template StoreCompleteAcc {{
159 Fault %(class_name)s::completeAcc(PacketPtr, ExecContext * xc,
160 Trace::InstRecord * traceData) const
161 {
162 return NoFault;
163 }
164}};
165
1// Copyright (c) 2006-2007 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(ExecContext *xc,
39 Trace::InstRecord *traceData) const
40 {
41 Fault fault = NoFault;
42 Addr EA;
43 %(fp_enable_check)s;
44 %(op_decl)s;
45 %(op_rd)s;
46 %(ea_code)s;
47 DPRINTF(Sparc, "%s: The address is 0x%x\n", mnemonic, EA);
48 %(fault_check)s;
49 if (fault == NoFault) {
50 %(EA_trunc)s
51 fault = readMemAtomic(xc, traceData, EA, Mem, %(asi_val)s);
52 }
53 if (fault == NoFault) {
54 %(code)s;
55 }
56 if (fault == NoFault) {
57 // Write the resulting state to the execution context
58 %(op_wb)s;
59 }
60
61 return fault;
62 }
63}};
64
65def template LoadInitiateAcc {{
66 Fault %(class_name)s::initiateAcc(ExecContext * xc,
67 Trace::InstRecord * traceData) const
68 {
69 Fault fault = NoFault;
70 Addr EA;
71 %(fp_enable_check)s;
72 %(op_decl)s;
73 %(op_rd)s;
74 %(ea_code)s;
75 DPRINTF(Sparc, "%s: The address is 0x%x\n", mnemonic, EA);
76 %(fault_check)s;
77 if (fault == NoFault) {
78 %(EA_trunc)s
79 fault = initiateMemRead(xc, traceData, EA, Mem, %(asi_val)s);
80 }
81 return fault;
82 }
83}};
84
85def template LoadCompleteAcc {{
86 Fault %(class_name)s::completeAcc(PacketPtr pkt, ExecContext * xc,
87 Trace::InstRecord * traceData) const
88 {
89 Fault fault = NoFault;
90 %(op_decl)s;
91 %(op_rd)s;
92 getMem(pkt, Mem, traceData);
93 %(code)s;
94 if (fault == NoFault) {
95 %(op_wb)s;
96 }
97 return fault;
98 }
99}};
100
101// This template provides the execute functions for a store
102def template StoreExecute {{
103 Fault %(class_name)s::execute(ExecContext *xc,
104 Trace::InstRecord *traceData) const
105 {
106 Fault fault = NoFault;
107 // This is to support the conditional store in cas instructions.
108 // It should be optomized out in all the others
109 bool storeCond = true;
110 Addr EA;
111 %(fp_enable_check)s;
112 %(op_decl)s;
113 %(op_rd)s;
114 %(ea_code)s;
115 DPRINTF(Sparc, "%s: The address is 0x%x\n", mnemonic, EA);
116 %(fault_check)s;
117 if (fault == NoFault) {
118 %(code)s;
119 }
120 if (storeCond && fault == NoFault) {
121 %(EA_trunc)s
122 fault = writeMemAtomic(xc, traceData, Mem, EA, %(asi_val)s, 0);
123 }
124 if (fault == NoFault) {
125 // Write the resulting state to the execution context
126 %(op_wb)s;
127 }
128
129 return fault;
130 }
131}};
132
133def template StoreInitiateAcc {{
134 Fault %(class_name)s::initiateAcc(ExecContext * xc,
135 Trace::InstRecord * traceData) const
136 {
137 Fault fault = NoFault;
138 bool storeCond = true;
139 Addr EA;
140 %(fp_enable_check)s;
141 %(op_decl)s;
142
143 %(op_rd)s;
144 %(ea_code)s;
145 DPRINTF(Sparc, "%s: The address is 0x%x\n", mnemonic, EA);
146 %(fault_check)s;
147 if (fault == NoFault) {
148 %(code)s;
149 }
150 if (storeCond && fault == NoFault) {
151 %(EA_trunc)s
152 fault = writeMemTiming(xc, traceData, Mem, EA, %(asi_val)s, 0);
153 }
154 return fault;
155 }
156}};
157
158def template StoreCompleteAcc {{
159 Fault %(class_name)s::completeAcc(PacketPtr, ExecContext * xc,
160 Trace::InstRecord * traceData) const
161 {
162 return NoFault;
163 }
164}};
165
166def template EACompExecute {{
167 Fault
168 %(class_name)s::eaComp(ExecContext *xc,
169 Trace::InstRecord *traceData) const
170 {
171 Addr EA;
172 Fault fault = NoFault;
173 %(op_decl)s;
174 %(op_rd)s;
175 %(ea_code)s;
176 %(fault_check)s;
177
178 // NOTE: Trace Data is written using execute or completeAcc templates
179 if (fault == NoFault) {
180 %(EA_trunc)s
181 xc->setEA(EA);
182 }
183
184 return fault;
185 }
186}};
187
188// Here are some code snippets which check for various fault conditions
189let {{
190 LoadFuncs = [LoadExecute, LoadInitiateAcc, LoadCompleteAcc]
191 StoreFuncs = [StoreExecute, StoreInitiateAcc, StoreCompleteAcc]
192
193 # The LSB can be zero, since it's really the MSB in doubles and quads
194 # and we're dealing with doubles
195 BlockAlignmentFaultCheck = '''
196 if (RD & 0xe)
197 fault = std::make_shared<IllegalInstruction>();
198 else if (EA & 0x3f)
199 fault = std::make_shared<MemAddressNotAligned>();
200 '''
201 TwinAlignmentFaultCheck = '''
202 if (RD & 0x1)
203 fault = std::make_shared<IllegalInstruction>();
204 else if (EA & 0xf)
205 fault = std::make_shared<MemAddressNotAligned>();
206 '''
207 # XXX Need to take care of pstate.hpriv as well. The lower ASIs
208 # are split into ones that are available in priv and hpriv, and
209 # those that are only available in hpriv
210 AlternateASIPrivFaultCheck = '''
211 if ((!Pstate.priv && !Hpstate.hpriv &&
212 !asiIsUnPriv((ASI)EXT_ASI)) ||
213 (!Hpstate.hpriv && asiIsHPriv((ASI)EXT_ASI)))
214 fault = std::make_shared<PrivilegedAction>();
215 else if (asiIsAsIfUser((ASI)EXT_ASI) && !Pstate.priv)
216 fault = std::make_shared<PrivilegedAction>();
217 '''
218
219 TruncateEA = '''
220 if (!FullSystem) {
221 EA = Pstate.am ? EA<31:0> : EA;
222 }
223 '''
224}};
225
226// A simple function to generate the name of the macro op of a certain
227// instruction at a certain micropc
228let {{
229 def makeMicroName(name, microPc):
230 return name + "::" + name + "_" + str(microPc)
231}};
232
233// This function properly generates the execute functions for one of the
234// templates above. This is needed because in one case, ea computation,
235// fault checks and the actual code all occur in the same function,
236// and in the other they're distributed across two. Also note that for
237// execute functions, the name of the base class doesn't matter.
238let {{
239 def doSplitExecute(execute, name, Name, asi, opt_flags, microParam):
240 microParam["asi_val"] = asi;
241 iop = InstObjParams(name, Name, '', microParam, opt_flags)
242 (execf, initf, compf) = execute
243 return execf.subst(iop) + initf.subst(iop) + compf.subst(iop)
244
245
246 def doDualSplitExecute(code, postacc_code, eaRegCode, eaImmCode, execute,
247 faultCode, nameReg, nameImm, NameReg, NameImm, asi, opt_flags):
248 executeCode = ''
249 for (eaCode, name, Name) in (
250 (eaRegCode, nameReg, NameReg),
251 (eaImmCode, nameImm, NameImm)):
252 microParams = {"code": code, "postacc_code" : postacc_code,
253 "ea_code": eaCode, "fault_check": faultCode,
254 "EA_trunc" : TruncateEA}
255 executeCode += doSplitExecute(execute, name, Name,
256 asi, opt_flags, microParams)
257 return executeCode
258}};
166// Here are some code snippets which check for various fault conditions
167let {{
168 LoadFuncs = [LoadExecute, LoadInitiateAcc, LoadCompleteAcc]
169 StoreFuncs = [StoreExecute, StoreInitiateAcc, StoreCompleteAcc]
170
171 # The LSB can be zero, since it's really the MSB in doubles and quads
172 # and we're dealing with doubles
173 BlockAlignmentFaultCheck = '''
174 if (RD & 0xe)
175 fault = std::make_shared<IllegalInstruction>();
176 else if (EA & 0x3f)
177 fault = std::make_shared<MemAddressNotAligned>();
178 '''
179 TwinAlignmentFaultCheck = '''
180 if (RD & 0x1)
181 fault = std::make_shared<IllegalInstruction>();
182 else if (EA & 0xf)
183 fault = std::make_shared<MemAddressNotAligned>();
184 '''
185 # XXX Need to take care of pstate.hpriv as well. The lower ASIs
186 # are split into ones that are available in priv and hpriv, and
187 # those that are only available in hpriv
188 AlternateASIPrivFaultCheck = '''
189 if ((!Pstate.priv && !Hpstate.hpriv &&
190 !asiIsUnPriv((ASI)EXT_ASI)) ||
191 (!Hpstate.hpriv && asiIsHPriv((ASI)EXT_ASI)))
192 fault = std::make_shared<PrivilegedAction>();
193 else if (asiIsAsIfUser((ASI)EXT_ASI) && !Pstate.priv)
194 fault = std::make_shared<PrivilegedAction>();
195 '''
196
197 TruncateEA = '''
198 if (!FullSystem) {
199 EA = Pstate.am ? EA<31:0> : EA;
200 }
201 '''
202}};
203
204// A simple function to generate the name of the macro op of a certain
205// instruction at a certain micropc
206let {{
207 def makeMicroName(name, microPc):
208 return name + "::" + name + "_" + str(microPc)
209}};
210
211// This function properly generates the execute functions for one of the
212// templates above. This is needed because in one case, ea computation,
213// fault checks and the actual code all occur in the same function,
214// and in the other they're distributed across two. Also note that for
215// execute functions, the name of the base class doesn't matter.
216let {{
217 def doSplitExecute(execute, name, Name, asi, opt_flags, microParam):
218 microParam["asi_val"] = asi;
219 iop = InstObjParams(name, Name, '', microParam, opt_flags)
220 (execf, initf, compf) = execute
221 return execf.subst(iop) + initf.subst(iop) + compf.subst(iop)
222
223
224 def doDualSplitExecute(code, postacc_code, eaRegCode, eaImmCode, execute,
225 faultCode, nameReg, nameImm, NameReg, NameImm, asi, opt_flags):
226 executeCode = ''
227 for (eaCode, name, Name) in (
228 (eaRegCode, nameReg, NameReg),
229 (eaImmCode, nameImm, NameImm)):
230 microParams = {"code": code, "postacc_code" : postacc_code,
231 "ea_code": eaCode, "fault_check": faultCode,
232 "EA_trunc" : TruncateEA}
233 executeCode += doSplitExecute(execute, name, Name,
234 asi, opt_flags, microParams)
235 return executeCode
236}};