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 eaComp(ExecContext *, Trace::InstRecord *) const; 48 Fault initiateAcc(ExecContext *, Trace::InstRecord *) const; 49 Fault completeAcc(PacketPtr, ExecContext *, Trace::InstRecord *) const; 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 63def template EACompExecute {{ 64 Fault 65 %(class_name)s::eaComp(ExecContext *xc, Trace::InstRecord *traceData) const 66 { 67 Addr EA; 68 Fault fault = NoFault; 69 70 %(op_decl)s; 71 %(op_rd)s; 72 %(ea_code)s; 73 74 if (fault == NoFault) { 75 %(op_wb)s; 76 xc->setEA(EA); 77 } 78 79 return fault; 80 } 81}}; 82 83let {{ 84def LoadStoreBase(name, Name, offset_code, ea_code, memacc_code, mem_flags, 85 inst_flags, base_class, postacc_code='', decode_template=BasicDecode, 86 exec_template_base=''): 87 # Make sure flags are in lists (convert to lists if not). 88 mem_flags = makeList(mem_flags) 89 inst_flags = makeList(inst_flags) 90 91 iop = InstObjParams(name, Name, base_class, 92 {'offset_code': offset_code, 'ea_code': ea_code, 93 'memacc_code': memacc_code, 'postacc_code': postacc_code }, 94 inst_flags) 95 96 if mem_flags: 97 mem_flags = [ 'Request::%s' % flag for flag in mem_flags ] 98 s = '\n\tmemAccessFlags = ' + string.join(mem_flags, '|') + ';' 99 iop.constructor += s 100 101 # select templates 102 103 fullExecTemplate = eval(exec_template_base + 'Execute') 104 initiateAccTemplate = eval(exec_template_base + 'InitiateAcc') 105 completeAccTemplate = eval(exec_template_base + 'CompleteAcc') 106 107 # (header_output, decoder_output, decode_block, exec_output) 108 return (LoadStoreDeclare.subst(iop), 109 LoadStoreConstructor.subst(iop), 110 decode_template.subst(iop), 111 fullExecTemplate.subst(iop) + 112 EACompExecute.subst(iop) + 113 initiateAccTemplate.subst(iop) + 114 completeAccTemplate.subst(iop)) 115}}; 116 117def template LoadExecute {{ 118 Fault 119 %(class_name)s::execute( 120 ExecContext *xc, Trace::InstRecord *traceData) const 121 { 122 Addr EA; 123 Fault fault = NoFault; 124 125 %(op_decl)s; 126 %(op_rd)s; 127 %(ea_code)s; 128 129 if (fault == NoFault) { 130 fault = readMemAtomic(xc, traceData, EA, Mem, memAccessFlags); 131 %(memacc_code)s; 132 } 133 134 if (fault == NoFault) { 135 %(op_wb)s; 136 } 137 138 return fault; 139 } 140}}; 141 142def template LoadInitiateAcc {{ 143 Fault 144 %(class_name)s::initiateAcc(ExecContext *xc, 145 Trace::InstRecord *traceData) const 146 { 147 Addr EA; 148 Fault fault = NoFault; 149 150 %(op_src_decl)s; 151 %(op_rd)s; 152 %(ea_code)s; 153 154 if (fault == NoFault) { 155 fault = initiateMemRead(xc, traceData, EA, Mem, memAccessFlags); 156 } 157 158 return fault; 159 } 160}}; 161 162def template LoadCompleteAcc {{ 163 Fault 164 %(class_name)s::completeAcc(PacketPtr pkt, ExecContext *xc, 165 Trace::InstRecord *traceData) const 166 { 167 Fault fault = NoFault; 168 169 %(op_decl)s; 170 %(op_rd)s; 171 172 getMem(pkt, Mem, traceData); 173 174 if (fault == NoFault) { 175 %(memacc_code)s; 176 } 177 178 if (fault == NoFault) { 179 %(op_wb)s; 180 } 181 182 return fault; 183 } 184}}; 185 186def template StoreExecute {{ 187 Fault 188 %(class_name)s::execute(ExecContext *xc, 189 Trace::InstRecord *traceData) const 190 { 191 Addr EA; 192 Fault fault = NoFault; 193 194 %(op_decl)s; 195 %(op_rd)s; 196 %(ea_code)s; 197 198 if (fault == NoFault) { 199 %(memacc_code)s; 200 } 201 202 if (fault == NoFault) { 203 fault = writeMemAtomic(xc, traceData, Mem, EA, memAccessFlags, 204 nullptr); 205 } 206 207 if (fault == NoFault) { 208 %(postacc_code)s; 209 } 210 211 if (fault == NoFault) { 212 %(op_wb)s; 213 } 214 215 return fault; 216 } 217}}; 218 219def template StoreInitiateAcc {{ 220 Fault 221 %(class_name)s::initiateAcc(ExecContext *xc, 222 Trace::InstRecord *traceData) const 223 { 224 Addr EA; 225 Fault fault = NoFault; 226 227 %(op_decl)s; 228 %(op_rd)s; 229 %(ea_code)s; 230 231 if (fault == NoFault) { 232 %(memacc_code)s; 233 } 234 235 if (fault == NoFault) { 236 fault = writeMemTiming(xc, traceData, Mem, EA, 237 memAccessFlags, nullptr); 238 } 239 240 if (fault == NoFault) { 241 %(op_wb)s; 242 } 243 244 return fault; 245 } 246}}; 247 248def template StoreCompleteAcc {{ 249 Fault 250 %(class_name)s::completeAcc(PacketPtr pkt, ExecContext *xc, 251 Trace::InstRecord *traceData) const 252 { 253 return NoFault; 254 } 255}}; 256
| 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 eaComp(ExecContext *, Trace::InstRecord *) const; 48 Fault initiateAcc(ExecContext *, Trace::InstRecord *) const; 49 Fault completeAcc(PacketPtr, ExecContext *, Trace::InstRecord *) const; 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 63def template EACompExecute {{ 64 Fault 65 %(class_name)s::eaComp(ExecContext *xc, Trace::InstRecord *traceData) const 66 { 67 Addr EA; 68 Fault fault = NoFault; 69 70 %(op_decl)s; 71 %(op_rd)s; 72 %(ea_code)s; 73 74 if (fault == NoFault) { 75 %(op_wb)s; 76 xc->setEA(EA); 77 } 78 79 return fault; 80 } 81}}; 82 83let {{ 84def LoadStoreBase(name, Name, offset_code, ea_code, memacc_code, mem_flags, 85 inst_flags, base_class, postacc_code='', decode_template=BasicDecode, 86 exec_template_base=''): 87 # Make sure flags are in lists (convert to lists if not). 88 mem_flags = makeList(mem_flags) 89 inst_flags = makeList(inst_flags) 90 91 iop = InstObjParams(name, Name, base_class, 92 {'offset_code': offset_code, 'ea_code': ea_code, 93 'memacc_code': memacc_code, 'postacc_code': postacc_code }, 94 inst_flags) 95 96 if mem_flags: 97 mem_flags = [ 'Request::%s' % flag for flag in mem_flags ] 98 s = '\n\tmemAccessFlags = ' + string.join(mem_flags, '|') + ';' 99 iop.constructor += s 100 101 # select templates 102 103 fullExecTemplate = eval(exec_template_base + 'Execute') 104 initiateAccTemplate = eval(exec_template_base + 'InitiateAcc') 105 completeAccTemplate = eval(exec_template_base + 'CompleteAcc') 106 107 # (header_output, decoder_output, decode_block, exec_output) 108 return (LoadStoreDeclare.subst(iop), 109 LoadStoreConstructor.subst(iop), 110 decode_template.subst(iop), 111 fullExecTemplate.subst(iop) + 112 EACompExecute.subst(iop) + 113 initiateAccTemplate.subst(iop) + 114 completeAccTemplate.subst(iop)) 115}}; 116 117def template LoadExecute {{ 118 Fault 119 %(class_name)s::execute( 120 ExecContext *xc, Trace::InstRecord *traceData) const 121 { 122 Addr EA; 123 Fault fault = NoFault; 124 125 %(op_decl)s; 126 %(op_rd)s; 127 %(ea_code)s; 128 129 if (fault == NoFault) { 130 fault = readMemAtomic(xc, traceData, EA, Mem, memAccessFlags); 131 %(memacc_code)s; 132 } 133 134 if (fault == NoFault) { 135 %(op_wb)s; 136 } 137 138 return fault; 139 } 140}}; 141 142def template LoadInitiateAcc {{ 143 Fault 144 %(class_name)s::initiateAcc(ExecContext *xc, 145 Trace::InstRecord *traceData) const 146 { 147 Addr EA; 148 Fault fault = NoFault; 149 150 %(op_src_decl)s; 151 %(op_rd)s; 152 %(ea_code)s; 153 154 if (fault == NoFault) { 155 fault = initiateMemRead(xc, traceData, EA, Mem, memAccessFlags); 156 } 157 158 return fault; 159 } 160}}; 161 162def template LoadCompleteAcc {{ 163 Fault 164 %(class_name)s::completeAcc(PacketPtr pkt, ExecContext *xc, 165 Trace::InstRecord *traceData) const 166 { 167 Fault fault = NoFault; 168 169 %(op_decl)s; 170 %(op_rd)s; 171 172 getMem(pkt, Mem, traceData); 173 174 if (fault == NoFault) { 175 %(memacc_code)s; 176 } 177 178 if (fault == NoFault) { 179 %(op_wb)s; 180 } 181 182 return fault; 183 } 184}}; 185 186def template StoreExecute {{ 187 Fault 188 %(class_name)s::execute(ExecContext *xc, 189 Trace::InstRecord *traceData) const 190 { 191 Addr EA; 192 Fault fault = NoFault; 193 194 %(op_decl)s; 195 %(op_rd)s; 196 %(ea_code)s; 197 198 if (fault == NoFault) { 199 %(memacc_code)s; 200 } 201 202 if (fault == NoFault) { 203 fault = writeMemAtomic(xc, traceData, Mem, EA, memAccessFlags, 204 nullptr); 205 } 206 207 if (fault == NoFault) { 208 %(postacc_code)s; 209 } 210 211 if (fault == NoFault) { 212 %(op_wb)s; 213 } 214 215 return fault; 216 } 217}}; 218 219def template StoreInitiateAcc {{ 220 Fault 221 %(class_name)s::initiateAcc(ExecContext *xc, 222 Trace::InstRecord *traceData) const 223 { 224 Addr EA; 225 Fault fault = NoFault; 226 227 %(op_decl)s; 228 %(op_rd)s; 229 %(ea_code)s; 230 231 if (fault == NoFault) { 232 %(memacc_code)s; 233 } 234 235 if (fault == NoFault) { 236 fault = writeMemTiming(xc, traceData, Mem, EA, 237 memAccessFlags, nullptr); 238 } 239 240 if (fault == NoFault) { 241 %(op_wb)s; 242 } 243 244 return fault; 245 } 246}}; 247 248def template StoreCompleteAcc {{ 249 Fault 250 %(class_name)s::completeAcc(PacketPtr pkt, ExecContext *xc, 251 Trace::InstRecord *traceData) const 252 { 253 return NoFault; 254 } 255}}; 256
|
258 inst_flags=[]) {{ 259 offset_code = """ 260 offset = IMM12; 261 if (IMMSIGN > 0) 262 offset |= ~((uint64_t)0xFFF); 263 """ 264 (header_output, decoder_output, decode_block, exec_output) = \ 265 LoadStoreBase(name, Name, offset_code, ea_code, memacc_code, mem_flags, 266 inst_flags, 'Load', exec_template_base='Load') 267}}; 268 269def format Store(memacc_code, ea_code={{EA = Rs1 + offset;}}, mem_flags=[], 270 inst_flags=[]) {{ 271 offset_code = """ 272 offset = IMM5 | (IMM7 << 5); 273 if (IMMSIGN > 0) 274 offset |= ~((uint64_t)0xFFF); 275 """ 276 (header_output, decoder_output, decode_block, exec_output) = \ 277 LoadStoreBase(name, Name, offset_code, ea_code, memacc_code, mem_flags, 278 inst_flags, 'Store', exec_template_base='Store') 279}};
| 258 inst_flags=[]) {{ 259 offset_code = """ 260 offset = IMM12; 261 if (IMMSIGN > 0) 262 offset |= ~((uint64_t)0xFFF); 263 """ 264 (header_output, decoder_output, decode_block, exec_output) = \ 265 LoadStoreBase(name, Name, offset_code, ea_code, memacc_code, mem_flags, 266 inst_flags, 'Load', exec_template_base='Load') 267}}; 268 269def format Store(memacc_code, ea_code={{EA = Rs1 + offset;}}, mem_flags=[], 270 inst_flags=[]) {{ 271 offset_code = """ 272 offset = IMM5 | (IMM7 << 5); 273 if (IMMSIGN > 0) 274 offset |= ~((uint64_t)0xFFF); 275 """ 276 (header_output, decoder_output, decode_block, exec_output) = \ 277 LoadStoreBase(name, Name, offset_code, ea_code, memacc_code, mem_flags, 278 inst_flags, 'Store', exec_template_base='Store') 279}};
|