mem.isa revision 12236:126ac9da6050
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// 36output header {{ 37 class Load : public RiscvStaticInst 38 { 39 public: 40 /// Displacement for EA calculation (signed). 41 int64_t ldisp; 42 43 protected: 44 /// Memory request flags. See mem_req_base.hh. 45 Request::Flags memAccessFlags; 46 47 /// Constructor 48 Load(const char *mnem, ExtMachInst _machInst, OpClass __opClass) 49 : RiscvStaticInst(mnem, _machInst, __opClass), ldisp(0) 50 {} 51 52 std::string 53 generateDisassembly(Addr pc, const SymbolTable *symtab) const; 54 }; 55 56 class Store : public RiscvStaticInst 57 { 58 public: 59 /// Displacement for EA calculation (signed). 60 int64_t sdisp; 61 62 protected: 63 /// Memory request flags. See mem_req_base.hh. 64 Request::Flags memAccessFlags; 65 66 /// Constructor 67 Store(const char *mnem, ExtMachInst _machInst, OpClass __opClass) 68 : RiscvStaticInst(mnem, _machInst, __opClass), sdisp(0) 69 { 70 sdisp = IMM5 | (IMM7 << 5); 71 if (IMMSIGN > 0) 72 sdisp |= ~((uint64_t)0xFFF); 73 } 74 75 std::string 76 generateDisassembly(Addr pc, const SymbolTable *symtab) const; 77 }; 78 79}}; 80 81 82output decoder {{ 83 std::string 84 Load::generateDisassembly(Addr pc, const SymbolTable *symtab) const 85 { 86 std::stringstream ss; 87 ss << mnemonic << ' ' << registerName(_destRegIdx[0]) << ", " << 88 ldisp << '(' << registerName(_srcRegIdx[0]) << ')'; 89 return ss.str(); 90 } 91 92 std::string 93 Store::generateDisassembly(Addr pc, const SymbolTable *symtab) const 94 { 95 std::stringstream ss; 96 ss << mnemonic << ' ' << registerName(_srcRegIdx[1]) << ", " << 97 sdisp << '(' << registerName(_srcRegIdx[0]) << ')'; 98 return ss.str(); 99 } 100}}; 101 102def template LoadStoreDeclare {{ 103 /** 104 * Static instruction class for "%(mnemonic)s". 105 */ 106 class %(class_name)s : public %(base_class)s 107 { 108 public: 109 /// Constructor. 110 %(class_name)s(ExtMachInst machInst); 111 112 Fault execute(ExecContext *, Trace::InstRecord *) const; 113 Fault eaComp(ExecContext *, Trace::InstRecord *) const; 114 Fault initiateAcc(ExecContext *, Trace::InstRecord *) const; 115 Fault completeAcc(PacketPtr, ExecContext *, Trace::InstRecord *) const; 116 }; 117}}; 118 119 120def template LoadStoreConstructor {{ 121 %(class_name)s::%(class_name)s(ExtMachInst machInst): 122 %(base_class)s("%(mnemonic)s", machInst, %(op_class)s) 123 { 124 %(constructor)s; 125 %(offset_code)s; 126 } 127}}; 128 129def template EACompExecute {{ 130 Fault 131 %(class_name)s::eaComp(ExecContext *xc, Trace::InstRecord *traceData) const 132 { 133 Addr EA; 134 Fault fault = NoFault; 135 136 %(op_decl)s; 137 %(op_rd)s; 138 %(ea_code)s; 139 140 if (fault == NoFault) { 141 %(op_wb)s; 142 xc->setEA(EA); 143 } 144 145 return fault; 146 } 147}}; 148 149let {{ 150def LoadStoreBase(name, Name, offset_code, ea_code, memacc_code, mem_flags, 151 inst_flags, base_class, postacc_code='', decode_template=BasicDecode, 152 exec_template_base=''): 153 # Make sure flags are in lists (convert to lists if not). 154 mem_flags = makeList(mem_flags) 155 inst_flags = makeList(inst_flags) 156 157 iop = InstObjParams(name, Name, base_class, 158 {'offset_code': offset_code, 'ea_code': ea_code, 159 'memacc_code': memacc_code, 'postacc_code': postacc_code }, 160 inst_flags) 161 162 if mem_flags: 163 mem_flags = [ 'Request::%s' % flag for flag in mem_flags ] 164 s = '\n\tmemAccessFlags = ' + string.join(mem_flags, '|') + ';' 165 iop.constructor += s 166 167 # select templates 168 169 fullExecTemplate = eval(exec_template_base + 'Execute') 170 initiateAccTemplate = eval(exec_template_base + 'InitiateAcc') 171 completeAccTemplate = eval(exec_template_base + 'CompleteAcc') 172 173 # (header_output, decoder_output, decode_block, exec_output) 174 return (LoadStoreDeclare.subst(iop), 175 LoadStoreConstructor.subst(iop), 176 decode_template.subst(iop), 177 fullExecTemplate.subst(iop) + 178 EACompExecute.subst(iop) + 179 initiateAccTemplate.subst(iop) + 180 completeAccTemplate.subst(iop)) 181}}; 182 183def template LoadExecute {{ 184 Fault 185 %(class_name)s::execute( 186 ExecContext *xc, Trace::InstRecord *traceData) const 187 { 188 Addr EA; 189 Fault fault = NoFault; 190 191 %(op_decl)s; 192 %(op_rd)s; 193 %(ea_code)s; 194 195 if (fault == NoFault) { 196 fault = readMemAtomic(xc, traceData, EA, Mem, memAccessFlags); 197 %(memacc_code)s; 198 } 199 200 if (fault == NoFault) { 201 %(op_wb)s; 202 } 203 204 return fault; 205 } 206}}; 207 208def template LoadInitiateAcc {{ 209 Fault 210 %(class_name)s::initiateAcc(ExecContext *xc, 211 Trace::InstRecord *traceData) const 212 { 213 Addr EA; 214 Fault fault = NoFault; 215 216 %(op_src_decl)s; 217 %(op_rd)s; 218 %(ea_code)s; 219 220 if (fault == NoFault) { 221 fault = initiateMemRead(xc, traceData, EA, Mem, memAccessFlags); 222 } 223 224 return fault; 225 } 226}}; 227 228def template LoadCompleteAcc {{ 229 Fault 230 %(class_name)s::completeAcc(PacketPtr pkt, ExecContext *xc, 231 Trace::InstRecord *traceData) const 232 { 233 Fault fault = NoFault; 234 235 %(op_decl)s; 236 %(op_rd)s; 237 238 getMem(pkt, Mem, traceData); 239 240 if (fault == NoFault) { 241 %(memacc_code)s; 242 } 243 244 if (fault == NoFault) { 245 %(op_wb)s; 246 } 247 248 return fault; 249 } 250}}; 251 252def template StoreExecute {{ 253 Fault 254 %(class_name)s::execute(ExecContext *xc, 255 Trace::InstRecord *traceData) const 256 { 257 Addr EA; 258 Fault fault = NoFault; 259 260 %(op_decl)s; 261 %(op_rd)s; 262 %(ea_code)s; 263 264 if (fault == NoFault) { 265 %(memacc_code)s; 266 } 267 268 if (fault == NoFault) { 269 fault = writeMemAtomic(xc, traceData, Mem, EA, memAccessFlags, 270 nullptr); 271 } 272 273 if (fault == NoFault) { 274 %(postacc_code)s; 275 } 276 277 if (fault == NoFault) { 278 %(op_wb)s; 279 } 280 281 return fault; 282 } 283}}; 284 285def template StoreInitiateAcc {{ 286 Fault 287 %(class_name)s::initiateAcc(ExecContext *xc, 288 Trace::InstRecord *traceData) const 289 { 290 Addr EA; 291 Fault fault = NoFault; 292 293 %(op_decl)s; 294 %(op_rd)s; 295 %(ea_code)s; 296 297 if (fault == NoFault) { 298 %(memacc_code)s; 299 } 300 301 if (fault == NoFault) { 302 fault = writeMemTiming(xc, traceData, Mem, EA, 303 memAccessFlags, nullptr); 304 } 305 306 if (fault == NoFault) { 307 %(op_wb)s; 308 } 309 310 return fault; 311 } 312}}; 313 314def template StoreCompleteAcc {{ 315 Fault 316 %(class_name)s::completeAcc(PacketPtr pkt, ExecContext *xc, 317 Trace::InstRecord *traceData) const 318 { 319 return NoFault; 320 } 321}}; 322 323def format Load(memacc_code, ea_code = {{EA = Rs1 + ldisp;}}, mem_flags=[], 324 inst_flags=[]) {{ 325 offset_code = """ 326 ldisp = IMM12; 327 if (IMMSIGN > 0) 328 ldisp |= ~((uint64_t)0xFFF); 329 """ 330 (header_output, decoder_output, decode_block, exec_output) = \ 331 LoadStoreBase(name, Name, offset_code, ea_code, memacc_code, mem_flags, 332 inst_flags, 'Load', exec_template_base='Load') 333}}; 334 335def format Store(memacc_code, ea_code={{EA = Rs1 + sdisp;}}, mem_flags=[], 336 inst_flags=[]) {{ 337 offset_code = """ 338 sdisp = IMM5 | (IMM7 << 5); 339 if (IMMSIGN > 0) 340 sdisp |= ~((uint64_t)0xFFF); 341 """ 342 (header_output, decoder_output, decode_block, exec_output) = \ 343 LoadStoreBase(name, Name, offset_code, ea_code, memacc_code, mem_flags, 344 inst_flags, 'Store', exec_template_base='Store') 345}}; 346