3 // Copyright (c) 2015 RISC-V Foundation
4 // Copyright (c) 2016 The University of Virginia
5 // All rights reserved.
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.
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.
30 // Authors: Alec Roelke
32 ////////////////////////////////////////////////////////////////////
34 // Memory operation instructions
36 def template LoadStoreDeclare {{
38 * Static instruction class for "%(mnemonic)s".
40 class %(class_name)s : public %(base_class)s
44 %(class_name)s(ExtMachInst machInst);
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;
54 def template LoadStoreConstructor {{
55 %(class_name)s::%(class_name)s(ExtMachInst machInst):
56 %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
64 def 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)
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 },
77 mem_flags = [ 'Request::%s' % flag for flag in mem_flags ]
78 s = '\n\tmemAccessFlags = ' + string.join(mem_flags, '|') + ';'
83 fullExecTemplate = eval(exec_template_base + 'Execute')
84 initiateAccTemplate = eval(exec_template_base + 'InitiateAcc')
85 completeAccTemplate = eval(exec_template_base + 'CompleteAcc')
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))
96 def template LoadExecute {{
98 %(class_name)s::execute(
99 ExecContext *xc, Trace::InstRecord *traceData) const
102 Fault fault = NoFault;
108 if (fault == NoFault) {
109 fault = readMemAtomicLE(xc, traceData, EA, Mem, memAccessFlags);
113 if (fault == NoFault) {
121 def template LoadInitiateAcc {{
123 %(class_name)s::initiateAcc(ExecContext *xc,
124 Trace::InstRecord *traceData) const
127 Fault fault = NoFault;
133 if (fault == NoFault) {
134 fault = initiateMemRead(xc, traceData, EA, Mem, memAccessFlags);
141 def template LoadCompleteAcc {{
143 %(class_name)s::completeAcc(PacketPtr pkt, ExecContext *xc,
144 Trace::InstRecord *traceData) const
146 Fault fault = NoFault;
151 getMemLE(pkt, Mem, traceData);
153 if (fault == NoFault) {
157 if (fault == NoFault) {
165 def template StoreExecute {{
167 %(class_name)s::execute(ExecContext *xc,
168 Trace::InstRecord *traceData) const
171 Fault fault = NoFault;
177 if (fault == NoFault) {
181 if (fault == NoFault) {
182 fault = writeMemAtomicLE(xc, traceData, Mem, EA, memAccessFlags,
186 if (fault == NoFault) {
190 if (fault == NoFault) {
198 def template StoreInitiateAcc {{
200 %(class_name)s::initiateAcc(ExecContext *xc,
201 Trace::InstRecord *traceData) const
204 Fault fault = NoFault;
210 if (fault == NoFault) {
214 if (fault == NoFault) {
215 fault = writeMemTimingLE(xc, traceData, Mem, EA,
216 memAccessFlags, nullptr);
219 if (fault == NoFault) {
227 def template StoreCompleteAcc {{
229 %(class_name)s::completeAcc(PacketPtr pkt, ExecContext *xc,
230 Trace::InstRecord *traceData) const
236 def 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')
244 def 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')