mem.isa (12385:288c62455dde) mem.isa (12482:35461496d012)
1// -*- mode:c++ -*-
2
3// Copyright (c) 2015 RISC-V Foundation
4// Copyright (c) 2016 The University of Virginia
5// All rights reserved.
6//
7// Redistribution and use in source and binary forms, with or without
8// modification, are permitted provided that the following conditions are
9// met: redistributions of source code must retain the above copyright
10// notice, this list of conditions and the following disclaimer;
11// redistributions in binary form must reproduce the above copyright
12// notice, this list of conditions and the following disclaimer in the
13// documentation and/or other materials provided with the distribution;
14// neither the name of the copyright holders nor the names of its
15// contributors may be used to endorse or promote products derived from
16// this software without specific prior written permission.
17//
18// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29//
30// Authors: Alec Roelke
31
32////////////////////////////////////////////////////////////////////
33//
34// Memory operation instructions
35//
36def template LoadStoreDeclare {{
37 /**
38 * Static instruction class for "%(mnemonic)s".
39 */
40 class %(class_name)s : public %(base_class)s
41 {
42 public:
43 /// Constructor.
44 %(class_name)s(ExtMachInst machInst);
45
1// -*- mode:c++ -*-
2
3// Copyright (c) 2015 RISC-V Foundation
4// Copyright (c) 2016 The University of Virginia
5// All rights reserved.
6//
7// Redistribution and use in source and binary forms, with or without
8// modification, are permitted provided that the following conditions are
9// met: redistributions of source code must retain the above copyright
10// notice, this list of conditions and the following disclaimer;
11// redistributions in binary form must reproduce the above copyright
12// notice, this list of conditions and the following disclaimer in the
13// documentation and/or other materials provided with the distribution;
14// neither the name of the copyright holders nor the names of its
15// contributors may be used to endorse or promote products derived from
16// this software without specific prior written permission.
17//
18// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29//
30// Authors: Alec Roelke
31
32////////////////////////////////////////////////////////////////////
33//
34// Memory operation instructions
35//
36def template LoadStoreDeclare {{
37 /**
38 * Static instruction class for "%(mnemonic)s".
39 */
40 class %(class_name)s : public %(base_class)s
41 {
42 public:
43 /// Constructor.
44 %(class_name)s(ExtMachInst machInst);
45
46 Fault execute(ExecContext *, Trace::InstRecord *) const;
47 Fault initiateAcc(ExecContext *, Trace::InstRecord *) const;
48 Fault completeAcc(PacketPtr, ExecContext *, Trace::InstRecord *) const;
46 Fault execute(ExecContext *, Trace::InstRecord *) const override;
47 Fault initiateAcc(ExecContext *, Trace::InstRecord *) const override;
48 Fault completeAcc(PacketPtr, ExecContext *,
49 Trace::InstRecord *) const override;
49 };
50}};
51
52
53def template LoadStoreConstructor {{
54 %(class_name)s::%(class_name)s(ExtMachInst machInst):
55 %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
56 {
57 %(constructor)s;
58 %(offset_code)s;
59 }
60}};
61
62let {{
63def LoadStoreBase(name, Name, offset_code, ea_code, memacc_code, mem_flags,
64 inst_flags, base_class, postacc_code='', decode_template=BasicDecode,
65 exec_template_base=''):
66 # Make sure flags are in lists (convert to lists if not).
67 mem_flags = makeList(mem_flags)
68 inst_flags = makeList(inst_flags)
69
70 iop = InstObjParams(name, Name, base_class,
71 {'offset_code': offset_code, 'ea_code': ea_code,
72 'memacc_code': memacc_code, 'postacc_code': postacc_code },
73 inst_flags)
74
75 if mem_flags:
76 mem_flags = [ 'Request::%s' % flag for flag in mem_flags ]
77 s = '\n\tmemAccessFlags = ' + string.join(mem_flags, '|') + ';'
78 iop.constructor += s
79
80 # select templates
81
82 fullExecTemplate = eval(exec_template_base + 'Execute')
83 initiateAccTemplate = eval(exec_template_base + 'InitiateAcc')
84 completeAccTemplate = eval(exec_template_base + 'CompleteAcc')
85
86 # (header_output, decoder_output, decode_block, exec_output)
87 return (LoadStoreDeclare.subst(iop),
88 LoadStoreConstructor.subst(iop),
89 decode_template.subst(iop),
90 fullExecTemplate.subst(iop) +
91 initiateAccTemplate.subst(iop) +
92 completeAccTemplate.subst(iop))
93}};
94
95def template LoadExecute {{
96 Fault
97 %(class_name)s::execute(
98 ExecContext *xc, Trace::InstRecord *traceData) const
99 {
100 Addr EA;
101 Fault fault = NoFault;
102
103 %(op_decl)s;
104 %(op_rd)s;
105 %(ea_code)s;
106
107 if (fault == NoFault) {
108 fault = readMemAtomic(xc, traceData, EA, Mem, memAccessFlags);
109 %(memacc_code)s;
110 }
111
112 if (fault == NoFault) {
113 %(op_wb)s;
114 }
115
116 return fault;
117 }
118}};
119
120def template LoadInitiateAcc {{
121 Fault
122 %(class_name)s::initiateAcc(ExecContext *xc,
123 Trace::InstRecord *traceData) const
124 {
125 Addr EA;
126 Fault fault = NoFault;
127
128 %(op_src_decl)s;
129 %(op_rd)s;
130 %(ea_code)s;
131
132 if (fault == NoFault) {
133 fault = initiateMemRead(xc, traceData, EA, Mem, memAccessFlags);
134 }
135
136 return fault;
137 }
138}};
139
140def template LoadCompleteAcc {{
141 Fault
142 %(class_name)s::completeAcc(PacketPtr pkt, ExecContext *xc,
143 Trace::InstRecord *traceData) const
144 {
145 Fault fault = NoFault;
146
147 %(op_decl)s;
148 %(op_rd)s;
149
150 getMem(pkt, Mem, traceData);
151
152 if (fault == NoFault) {
153 %(memacc_code)s;
154 }
155
156 if (fault == NoFault) {
157 %(op_wb)s;
158 }
159
160 return fault;
161 }
162}};
163
164def template StoreExecute {{
165 Fault
166 %(class_name)s::execute(ExecContext *xc,
167 Trace::InstRecord *traceData) const
168 {
169 Addr EA;
170 Fault fault = NoFault;
171
172 %(op_decl)s;
173 %(op_rd)s;
174 %(ea_code)s;
175
176 if (fault == NoFault) {
177 %(memacc_code)s;
178 }
179
180 if (fault == NoFault) {
181 fault = writeMemAtomic(xc, traceData, Mem, EA, memAccessFlags,
182 nullptr);
183 }
184
185 if (fault == NoFault) {
186 %(postacc_code)s;
187 }
188
189 if (fault == NoFault) {
190 %(op_wb)s;
191 }
192
193 return fault;
194 }
195}};
196
197def template StoreInitiateAcc {{
198 Fault
199 %(class_name)s::initiateAcc(ExecContext *xc,
200 Trace::InstRecord *traceData) const
201 {
202 Addr EA;
203 Fault fault = NoFault;
204
205 %(op_decl)s;
206 %(op_rd)s;
207 %(ea_code)s;
208
209 if (fault == NoFault) {
210 %(memacc_code)s;
211 }
212
213 if (fault == NoFault) {
214 fault = writeMemTiming(xc, traceData, Mem, EA,
215 memAccessFlags, nullptr);
216 }
217
218 if (fault == NoFault) {
219 %(op_wb)s;
220 }
221
222 return fault;
223 }
224}};
225
226def template StoreCompleteAcc {{
227 Fault
228 %(class_name)s::completeAcc(PacketPtr pkt, ExecContext *xc,
229 Trace::InstRecord *traceData) const
230 {
231 return NoFault;
232 }
233}};
234
235def format Load(memacc_code, ea_code = {{EA = Rs1 + offset;}},
236 offset_code={{offset = sext<12>(IMM12);}},
237 mem_flags=[], inst_flags=[]) {{
238 (header_output, decoder_output, decode_block, exec_output) = \
239 LoadStoreBase(name, Name, offset_code, ea_code, memacc_code, mem_flags,
240 inst_flags, 'Load', exec_template_base='Load')
241}};
242
243def format Store(memacc_code, ea_code={{EA = Rs1 + offset;}},
244 offset_code={{offset = sext<12>(IMM5 | (IMM7 << 5));}},
245 mem_flags=[], inst_flags=[]) {{
246 (header_output, decoder_output, decode_block, exec_output) = \
247 LoadStoreBase(name, Name, offset_code, ea_code, memacc_code, mem_flags,
248 inst_flags, 'Store', exec_template_base='Store')
249}};
50 };
51}};
52
53
54def template LoadStoreConstructor {{
55 %(class_name)s::%(class_name)s(ExtMachInst machInst):
56 %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
57 {
58 %(constructor)s;
59 %(offset_code)s;
60 }
61}};
62
63let {{
64def LoadStoreBase(name, Name, offset_code, ea_code, memacc_code, mem_flags,
65 inst_flags, base_class, postacc_code='', decode_template=BasicDecode,
66 exec_template_base=''):
67 # Make sure flags are in lists (convert to lists if not).
68 mem_flags = makeList(mem_flags)
69 inst_flags = makeList(inst_flags)
70
71 iop = InstObjParams(name, Name, base_class,
72 {'offset_code': offset_code, 'ea_code': ea_code,
73 'memacc_code': memacc_code, 'postacc_code': postacc_code },
74 inst_flags)
75
76 if mem_flags:
77 mem_flags = [ 'Request::%s' % flag for flag in mem_flags ]
78 s = '\n\tmemAccessFlags = ' + string.join(mem_flags, '|') + ';'
79 iop.constructor += s
80
81 # select templates
82
83 fullExecTemplate = eval(exec_template_base + 'Execute')
84 initiateAccTemplate = eval(exec_template_base + 'InitiateAcc')
85 completeAccTemplate = eval(exec_template_base + 'CompleteAcc')
86
87 # (header_output, decoder_output, decode_block, exec_output)
88 return (LoadStoreDeclare.subst(iop),
89 LoadStoreConstructor.subst(iop),
90 decode_template.subst(iop),
91 fullExecTemplate.subst(iop) +
92 initiateAccTemplate.subst(iop) +
93 completeAccTemplate.subst(iop))
94}};
95
96def template LoadExecute {{
97 Fault
98 %(class_name)s::execute(
99 ExecContext *xc, Trace::InstRecord *traceData) const
100 {
101 Addr EA;
102 Fault fault = NoFault;
103
104 %(op_decl)s;
105 %(op_rd)s;
106 %(ea_code)s;
107
108 if (fault == NoFault) {
109 fault = readMemAtomic(xc, traceData, EA, Mem, memAccessFlags);
110 %(memacc_code)s;
111 }
112
113 if (fault == NoFault) {
114 %(op_wb)s;
115 }
116
117 return fault;
118 }
119}};
120
121def template LoadInitiateAcc {{
122 Fault
123 %(class_name)s::initiateAcc(ExecContext *xc,
124 Trace::InstRecord *traceData) const
125 {
126 Addr EA;
127 Fault fault = NoFault;
128
129 %(op_src_decl)s;
130 %(op_rd)s;
131 %(ea_code)s;
132
133 if (fault == NoFault) {
134 fault = initiateMemRead(xc, traceData, EA, Mem, memAccessFlags);
135 }
136
137 return fault;
138 }
139}};
140
141def template LoadCompleteAcc {{
142 Fault
143 %(class_name)s::completeAcc(PacketPtr pkt, ExecContext *xc,
144 Trace::InstRecord *traceData) const
145 {
146 Fault fault = NoFault;
147
148 %(op_decl)s;
149 %(op_rd)s;
150
151 getMem(pkt, Mem, traceData);
152
153 if (fault == NoFault) {
154 %(memacc_code)s;
155 }
156
157 if (fault == NoFault) {
158 %(op_wb)s;
159 }
160
161 return fault;
162 }
163}};
164
165def template StoreExecute {{
166 Fault
167 %(class_name)s::execute(ExecContext *xc,
168 Trace::InstRecord *traceData) const
169 {
170 Addr EA;
171 Fault fault = NoFault;
172
173 %(op_decl)s;
174 %(op_rd)s;
175 %(ea_code)s;
176
177 if (fault == NoFault) {
178 %(memacc_code)s;
179 }
180
181 if (fault == NoFault) {
182 fault = writeMemAtomic(xc, traceData, Mem, EA, memAccessFlags,
183 nullptr);
184 }
185
186 if (fault == NoFault) {
187 %(postacc_code)s;
188 }
189
190 if (fault == NoFault) {
191 %(op_wb)s;
192 }
193
194 return fault;
195 }
196}};
197
198def template StoreInitiateAcc {{
199 Fault
200 %(class_name)s::initiateAcc(ExecContext *xc,
201 Trace::InstRecord *traceData) const
202 {
203 Addr EA;
204 Fault fault = NoFault;
205
206 %(op_decl)s;
207 %(op_rd)s;
208 %(ea_code)s;
209
210 if (fault == NoFault) {
211 %(memacc_code)s;
212 }
213
214 if (fault == NoFault) {
215 fault = writeMemTiming(xc, traceData, Mem, EA,
216 memAccessFlags, nullptr);
217 }
218
219 if (fault == NoFault) {
220 %(op_wb)s;
221 }
222
223 return fault;
224 }
225}};
226
227def template StoreCompleteAcc {{
228 Fault
229 %(class_name)s::completeAcc(PacketPtr pkt, ExecContext *xc,
230 Trace::InstRecord *traceData) const
231 {
232 return NoFault;
233 }
234}};
235
236def format Load(memacc_code, ea_code = {{EA = Rs1 + offset;}},
237 offset_code={{offset = sext<12>(IMM12);}},
238 mem_flags=[], inst_flags=[]) {{
239 (header_output, decoder_output, decode_block, exec_output) = \
240 LoadStoreBase(name, Name, offset_code, ea_code, memacc_code, mem_flags,
241 inst_flags, 'Load', exec_template_base='Load')
242}};
243
244def format Store(memacc_code, ea_code={{EA = Rs1 + offset;}},
245 offset_code={{offset = sext<12>(IMM5 | (IMM7 << 5));}},
246 mem_flags=[], inst_flags=[]) {{
247 (header_output, decoder_output, decode_block, exec_output) = \
248 LoadStoreBase(name, Name, offset_code, ea_code, memacc_code, mem_flags,
249 inst_flags, 'Store', exec_template_base='Store')
250}};