mem.isa revision 11729:f37b5fcd66fe
14309Sgblack@eecs.umich.edu// -*- mode:c++ -*-
24309Sgblack@eecs.umich.edu
35426Sgblack@eecs.umich.edu// Copyright (c) 2015 RISC-V Foundation
44309Sgblack@eecs.umich.edu// Copyright (c) 2016 The University of Virginia
54309Sgblack@eecs.umich.edu// All rights reserved.
64309Sgblack@eecs.umich.edu//
74309Sgblack@eecs.umich.edu// Redistribution and use in source and binary forms, with or without
84309Sgblack@eecs.umich.edu// modification, are permitted provided that the following conditions are
94309Sgblack@eecs.umich.edu// met: redistributions of source code must retain the above copyright
104309Sgblack@eecs.umich.edu// notice, this list of conditions and the following disclaimer;
114309Sgblack@eecs.umich.edu// redistributions in binary form must reproduce the above copyright
124309Sgblack@eecs.umich.edu// notice, this list of conditions and the following disclaimer in the
134309Sgblack@eecs.umich.edu// documentation and/or other materials provided with the distribution;
144309Sgblack@eecs.umich.edu// neither the name of the copyright holders nor the names of its
154309Sgblack@eecs.umich.edu// contributors may be used to endorse or promote products derived from
164309Sgblack@eecs.umich.edu// this software without specific prior written permission.
174309Sgblack@eecs.umich.edu//
184309Sgblack@eecs.umich.edu// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
194309Sgblack@eecs.umich.edu// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
204309Sgblack@eecs.umich.edu// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
214309Sgblack@eecs.umich.edu// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
224309Sgblack@eecs.umich.edu// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
234309Sgblack@eecs.umich.edu// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
244309Sgblack@eecs.umich.edu// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
254309Sgblack@eecs.umich.edu// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
264309Sgblack@eecs.umich.edu// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
274309Sgblack@eecs.umich.edu// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
284309Sgblack@eecs.umich.edu// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
294309Sgblack@eecs.umich.edu//
304309Sgblack@eecs.umich.edu// Authors: Alec Roelke
314309Sgblack@eecs.umich.edu
324309Sgblack@eecs.umich.edu////////////////////////////////////////////////////////////////////
334309Sgblack@eecs.umich.edu//
344309Sgblack@eecs.umich.edu// Memory operation instructions
354309Sgblack@eecs.umich.edu//
364309Sgblack@eecs.umich.eduoutput header {{
374309Sgblack@eecs.umich.edu    class Load : public RiscvStaticInst
384309Sgblack@eecs.umich.edu    {
394309Sgblack@eecs.umich.edu      public:
404309Sgblack@eecs.umich.edu        /// Displacement for EA calculation (signed).
414309Sgblack@eecs.umich.edu        int64_t ldisp;
424309Sgblack@eecs.umich.edu
434309Sgblack@eecs.umich.edu      protected:
444309Sgblack@eecs.umich.edu        /// Memory request flags.  See mem_req_base.hh.
454309Sgblack@eecs.umich.edu        Request::Flags memAccessFlags;
464309Sgblack@eecs.umich.edu
474309Sgblack@eecs.umich.edu        /// Constructor
484309Sgblack@eecs.umich.edu        Load(const char *mnem, ExtMachInst _machInst, OpClass __opClass)
494309Sgblack@eecs.umich.edu            : RiscvStaticInst(mnem, _machInst, __opClass), ldisp(IMM12)
504309Sgblack@eecs.umich.edu        {
514309Sgblack@eecs.umich.edu            if (IMMSIGN > 0)
524309Sgblack@eecs.umich.edu                ldisp |= ~((uint64_t)0xFFF);
534309Sgblack@eecs.umich.edu        }
544309Sgblack@eecs.umich.edu
554309Sgblack@eecs.umich.edu        std::string
564309Sgblack@eecs.umich.edu        generateDisassembly(Addr pc, const SymbolTable *symtab) const;
574309Sgblack@eecs.umich.edu    };
584533Sgblack@eecs.umich.edu
594679Sgblack@eecs.umich.edu    class Store : public RiscvStaticInst
604679Sgblack@eecs.umich.edu    {
614679Sgblack@eecs.umich.edu      public:
624533Sgblack@eecs.umich.edu        /// Displacement for EA calculation (signed).
634533Sgblack@eecs.umich.edu        int64_t sdisp;
644537Sgblack@eecs.umich.edu
654533Sgblack@eecs.umich.edu      protected:
664528Sgblack@eecs.umich.edu        /// Memory request flags.  See mem_req_base.hh.
675666Sgblack@eecs.umich.edu        Request::Flags memAccessFlags;
685666Sgblack@eecs.umich.edu
695666Sgblack@eecs.umich.edu        /// Constructor
704528Sgblack@eecs.umich.edu        Store(const char *mnem, ExtMachInst _machInst, OpClass __opClass)
714528Sgblack@eecs.umich.edu            : RiscvStaticInst(mnem, _machInst, __opClass), sdisp(IMM5)
724528Sgblack@eecs.umich.edu        {
734528Sgblack@eecs.umich.edu            sdisp |= IMM7 << 5;
744605Sgblack@eecs.umich.edu            if (IMMSIGN > 0)
755666Sgblack@eecs.umich.edu                sdisp |= ~((uint64_t)0xFFF);
765666Sgblack@eecs.umich.edu        }
774528Sgblack@eecs.umich.edu
786345Sgblack@eecs.umich.edu        std::string
796345Sgblack@eecs.umich.edu        generateDisassembly(Addr pc, const SymbolTable *symtab) const;
806345Sgblack@eecs.umich.edu    };
816345Sgblack@eecs.umich.edu
826345Sgblack@eecs.umich.edu}};
836345Sgblack@eecs.umich.edu
844615Sgblack@eecs.umich.edu
855854Sgblack@eecs.umich.eduoutput decoder {{
866345Sgblack@eecs.umich.edu    std::string
875854Sgblack@eecs.umich.edu    Load::generateDisassembly(Addr pc, const SymbolTable *symtab) const
886345Sgblack@eecs.umich.edu    {
896345Sgblack@eecs.umich.edu        std::stringstream ss;
904615Sgblack@eecs.umich.edu        ss << mnemonic << ' ' << regName(_destRegIdx[0]) << ", " << ldisp <<
915671Sgblack@eecs.umich.edu            '(' << regName(_srcRegIdx[0]) << ')';
926345Sgblack@eecs.umich.edu        return ss.str();
936345Sgblack@eecs.umich.edu    }
945291Sgblack@eecs.umich.edu
955428Sgblack@eecs.umich.edu    std::string
965674Sgblack@eecs.umich.edu    Store::generateDisassembly(Addr pc, const SymbolTable *symtab) const
975899Sgblack@eecs.umich.edu    {
985936Sgblack@eecs.umich.edu        std::stringstream ss;
995428Sgblack@eecs.umich.edu        ss << mnemonic << ' ' << regName(_srcRegIdx[1]) << ", " << sdisp <<
1005428Sgblack@eecs.umich.edu            '(' << regName(_srcRegIdx[0]) << ')';
1015294Sgblack@eecs.umich.edu        return ss.str();
1026345Sgblack@eecs.umich.edu    }
1035291Sgblack@eecs.umich.edu}};
1045294Sgblack@eecs.umich.edu
1056345Sgblack@eecs.umich.edudef template LoadStoreDeclare {{
1065294Sgblack@eecs.umich.edu    /**
1074615Sgblack@eecs.umich.edu     * Static instruction class for "%(mnemonic)s".
1084615Sgblack@eecs.umich.edu     */
1096345Sgblack@eecs.umich.edu    class %(class_name)s : public %(base_class)s
1106345Sgblack@eecs.umich.edu    {
1116345Sgblack@eecs.umich.edu      public:
1126345Sgblack@eecs.umich.edu        /// Constructor.
1136345Sgblack@eecs.umich.edu        %(class_name)s(ExtMachInst machInst);
1146345Sgblack@eecs.umich.edu
1156517Sgblack@eecs.umich.edu        %(BasicExecDeclare)s
1166517Sgblack@eecs.umich.edu
1175161Sgblack@eecs.umich.edu        %(EACompDeclare)s
1185161Sgblack@eecs.umich.edu
1196345Sgblack@eecs.umich.edu        %(InitiateAccDeclare)s
1204615Sgblack@eecs.umich.edu
1216345Sgblack@eecs.umich.edu        %(CompleteAccDeclare)s
1226345Sgblack@eecs.umich.edu    };
1234615Sgblack@eecs.umich.edu}};
1244953Sgblack@eecs.umich.edu
1254615Sgblack@eecs.umich.edudef template EACompDeclare {{
1264615Sgblack@eecs.umich.edu    Fault
1274863Sgblack@eecs.umich.edu    eaComp(%(CPU_exec_context)s *, Trace::InstRecord *) const;
1284863Sgblack@eecs.umich.edu}};
1295326Sgblack@eecs.umich.edu
1305326Sgblack@eecs.umich.edudef template InitiateAccDeclare {{
1315326Sgblack@eecs.umich.edu    Fault
1325326Sgblack@eecs.umich.edu    initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const;
1335326Sgblack@eecs.umich.edu}};
1345326Sgblack@eecs.umich.edu
1355326Sgblack@eecs.umich.edu
1365326Sgblack@eecs.umich.edudef template CompleteAccDeclare {{
1375326Sgblack@eecs.umich.edu    Fault
1384863Sgblack@eecs.umich.edu    completeAcc(PacketPtr, %(CPU_exec_context)s *, Trace::InstRecord *) const;
1394863Sgblack@eecs.umich.edu}};
1404863Sgblack@eecs.umich.edu
1414863Sgblack@eecs.umich.edudef template LoadStoreConstructor {{
1424863Sgblack@eecs.umich.edu    %(class_name)s::%(class_name)s(ExtMachInst machInst):
1434620Sgblack@eecs.umich.edu        %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
1445149Sgblack@eecs.umich.edu    {
1455149Sgblack@eecs.umich.edu        %(constructor)s;
1466345Sgblack@eecs.umich.edu    }
1475294Sgblack@eecs.umich.edu}};
1485294Sgblack@eecs.umich.edu
1496345Sgblack@eecs.umich.edudef template EACompExecute {{
1505149Sgblack@eecs.umich.edu    Fault
1515906Sgblack@eecs.umich.edu    %(class_name)s::eaComp(CPU_EXEC_CONTEXT *xc,
1525906Sgblack@eecs.umich.edu        Trace::InstRecord *traceData) const
1536345Sgblack@eecs.umich.edu    {
1546345Sgblack@eecs.umich.edu        Addr EA;
1554615Sgblack@eecs.umich.edu        Fault fault = NoFault;
1566457Sgblack@eecs.umich.edu
1576457Sgblack@eecs.umich.edu        %(op_decl)s;
1586457Sgblack@eecs.umich.edu        %(op_rd)s;
1596457Sgblack@eecs.umich.edu        %(ea_code)s;
1605854Sgblack@eecs.umich.edu
1616345Sgblack@eecs.umich.edu        if (fault == NoFault) {
1625241Sgblack@eecs.umich.edu            %(op_wb)s;
1635426Sgblack@eecs.umich.edu            xc->setEA(EA);
1645426Sgblack@eecs.umich.edu        }
1654686Sgblack@eecs.umich.edu
1664686Sgblack@eecs.umich.edu        return fault;
1674686Sgblack@eecs.umich.edu    }
1684953Sgblack@eecs.umich.edu}};
1694686Sgblack@eecs.umich.edu
1704686Sgblack@eecs.umich.edulet {{
1714686Sgblack@eecs.umich.edudef LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
1724686Sgblack@eecs.umich.edu        base_class, postacc_code='', decode_template=BasicDecode,
1734953Sgblack@eecs.umich.edu        exec_template_base=''):
1744953Sgblack@eecs.umich.edu    # Make sure flags are in lists (convert to lists if not).
1754686Sgblack@eecs.umich.edu    mem_flags = makeList(mem_flags)
1764686Sgblack@eecs.umich.edu    inst_flags = makeList(inst_flags) # + ['IsNonSpeculative']
1774686Sgblack@eecs.umich.edu
1784686Sgblack@eecs.umich.edu    iop = InstObjParams(name, Name, base_class,
1795682Sgblack@eecs.umich.edu        { 'ea_code':ea_code, 'memacc_code':memacc_code,
1805682Sgblack@eecs.umich.edu        'postacc_code':postacc_code }, inst_flags)
1815682Sgblack@eecs.umich.edu
1826345Sgblack@eecs.umich.edu    if mem_flags:
1835682Sgblack@eecs.umich.edu        mem_flags = [ 'Request::%s' % flag for flag in mem_flags ]
1846799Sgblack@eecs.umich.edu        s = '\n\tmemAccessFlags = ' + string.join(mem_flags, '|') + ';'
1856799Sgblack@eecs.umich.edu        iop.constructor += s
1866799Sgblack@eecs.umich.edu
1874615Sgblack@eecs.umich.edu    # select templates
1884615Sgblack@eecs.umich.edu
1894615Sgblack@eecs.umich.edu    # The InitiateAcc template is the same for StoreCond templates as the
1904615Sgblack@eecs.umich.edu    # corresponding Store template..
1914615Sgblack@eecs.umich.edu    StoreCondInitiateAcc = StoreInitiateAcc
1924615Sgblack@eecs.umich.edu
1934615Sgblack@eecs.umich.edu    fullExecTemplate = eval(exec_template_base + 'Execute')
1945930Sgblack@eecs.umich.edu    initiateAccTemplate = eval(exec_template_base + 'InitiateAcc')
1955291Sgblack@eecs.umich.edu    completeAccTemplate = eval(exec_template_base + 'CompleteAcc')
1965291Sgblack@eecs.umich.edu
1975291Sgblack@eecs.umich.edu    # (header_output, decoder_output, decode_block, exec_output)
1985291Sgblack@eecs.umich.edu    return (LoadStoreDeclare.subst(iop),
1995291Sgblack@eecs.umich.edu        LoadStoreConstructor.subst(iop),
2005291Sgblack@eecs.umich.edu        decode_template.subst(iop),
2015161Sgblack@eecs.umich.edu        fullExecTemplate.subst(iop) +
2025161Sgblack@eecs.umich.edu        EACompExecute.subst(iop) +
2035161Sgblack@eecs.umich.edu        initiateAccTemplate.subst(iop) +
2045161Sgblack@eecs.umich.edu        completeAccTemplate.subst(iop))
2055161Sgblack@eecs.umich.edu}};
2065008Sgblack@eecs.umich.edu
2075008Sgblack@eecs.umich.edudef template LoadExecute {{
2085008Sgblack@eecs.umich.edu    Fault
2095008Sgblack@eecs.umich.edu    %(class_name)s::execute(CPU_EXEC_CONTEXT *xc,
2105008Sgblack@eecs.umich.edu        Trace::InstRecord *traceData) const
2115667Sgblack@eecs.umich.edu    {
2125667Sgblack@eecs.umich.edu        Addr EA;
2135667Sgblack@eecs.umich.edu        Fault fault = NoFault;
2145667Sgblack@eecs.umich.edu
2155667Sgblack@eecs.umich.edu        %(op_decl)s;
2165676Sgblack@eecs.umich.edu        %(op_rd)s;
2175676Sgblack@eecs.umich.edu        %(ea_code)s;
2185676Sgblack@eecs.umich.edu
2195676Sgblack@eecs.umich.edu        if (fault == NoFault) {
2205676Sgblack@eecs.umich.edu            fault = readMemAtomic(xc, traceData, EA, Mem, memAccessFlags);
2215082Sgblack@eecs.umich.edu            %(memacc_code)s;
2226345Sgblack@eecs.umich.edu        }
2235082Sgblack@eecs.umich.edu
2245082Sgblack@eecs.umich.edu        if (fault == NoFault) {
2256618Sgblack@eecs.umich.edu            %(op_wb)s;
2266618Sgblack@eecs.umich.edu        }
2275082Sgblack@eecs.umich.edu
2284528Sgblack@eecs.umich.edu        return fault;
2295666Sgblack@eecs.umich.edu    }
2305666Sgblack@eecs.umich.edu}};
2315666Sgblack@eecs.umich.edu
2324528Sgblack@eecs.umich.edudef template LoadInitiateAcc {{
233    Fault
234    %(class_name)s::initiateAcc(CPU_EXEC_CONTEXT *xc,
235        Trace::InstRecord *traceData) const
236    {
237        Addr EA;
238        Fault fault = NoFault;
239
240        %(op_src_decl)s;
241        %(op_rd)s;
242        %(ea_code)s;
243
244        if (fault == NoFault) {
245            fault = initiateMemRead(xc, traceData, EA, Mem, memAccessFlags);
246        }
247
248        return fault;
249    }
250}};
251
252def template LoadCompleteAcc {{
253    Fault
254    %(class_name)s::completeAcc(PacketPtr pkt, CPU_EXEC_CONTEXT *xc,
255        Trace::InstRecord *traceData) const
256    {
257        Fault fault = NoFault;
258
259        %(op_decl)s;
260        %(op_rd)s;
261
262        getMem(pkt, Mem, traceData);
263
264        if (fault == NoFault) {
265            %(memacc_code)s;
266        }
267
268        if (fault == NoFault) {
269            %(op_wb)s;
270        }
271
272        return fault;
273    }
274}};
275
276def template StoreExecute {{
277    Fault
278    %(class_name)s::execute(CPU_EXEC_CONTEXT *xc,
279        Trace::InstRecord *traceData) const
280    {
281        Addr EA;
282        Fault fault = NoFault;
283
284        %(op_decl)s;
285        %(op_rd)s;
286        %(ea_code)s;
287
288        if (fault == NoFault) {
289            %(memacc_code)s;
290        }
291
292        if (fault == NoFault) {
293            fault = writeMemAtomic(xc, traceData, Mem, EA, memAccessFlags,
294                nullptr);
295        }
296
297        if (fault == NoFault) {
298            %(postacc_code)s;
299        }
300
301        if (fault == NoFault) {
302            %(op_wb)s;
303        }
304
305        return fault;
306    }
307}};
308
309def template StoreInitiateAcc {{
310    Fault
311    %(class_name)s::initiateAcc(CPU_EXEC_CONTEXT *xc,
312        Trace::InstRecord *traceData) const
313    {
314        Addr EA;
315        Fault fault = NoFault;
316
317        %(op_decl)s;
318        %(op_rd)s;
319        %(ea_code)s;
320
321        if (fault == NoFault) {
322            %(memacc_code)s;
323        }
324
325        if (fault == NoFault) {
326            fault = writeMemTiming(xc, traceData, Mem, EA,
327                memAccessFlags, nullptr);
328        }
329
330        if (fault == NoFault) {
331            %(op_wb)s;
332        }
333
334        return fault;
335    }
336}};
337
338def template StoreCompleteAcc {{
339    Fault
340    %(class_name)s::completeAcc(PacketPtr pkt, CPU_EXEC_CONTEXT *xc,
341        Trace::InstRecord *traceData) const
342    {
343        return NoFault;
344    }
345}};
346
347def template StoreCondExecute {{
348    Fault %(class_name)s::execute(CPU_EXEC_CONTEXT *xc,
349        Trace::InstRecord *traceData) const
350    {
351        Addr EA;
352        Fault fault = NoFault;
353        uint64_t result;
354
355        %(op_decl)s;
356        %(op_rd)s;
357        %(ea_code)s;
358
359        if (fault == NoFault) {
360            %(memacc_code)s;
361        }
362
363        if (fault == NoFault) {
364            fault = writeMemAtomic(xc, traceData, Mem, EA, memAccessFlags,
365                &result);
366            // RISC-V has the opposite convention gem5 has for success flags,
367            // so we invert the result here.
368            result = !result;
369        }
370
371        if (fault == NoFault) {
372            %(postacc_code)s;
373        }
374
375        if (fault == NoFault) {
376            %(op_wb)s;
377        }
378
379        return fault;
380    }
381}};
382
383def template StoreCondCompleteAcc {{
384    Fault %(class_name)s::completeAcc(Packet *pkt, CPU_EXEC_CONTEXT *xc,
385        Trace::InstRecord *traceData) const
386    {
387        Fault fault = NoFault;
388
389        %(op_dest_decl)s;
390
391        // RISC-V has the opposite convention gem5 has for success flags,
392        // so we invert the result here.
393        uint64_t result = !pkt->req->getExtraData();
394
395        if (fault == NoFault) {
396            %(postacc_code)s;
397        }
398
399        if (fault == NoFault) {
400            %(op_wb)s;
401        }
402
403        return fault;
404    }
405}};
406
407def format Load(memacc_code, ea_code = {{EA = Rs1 + ldisp;}}, mem_flags=[],
408        inst_flags=[]) {{
409    (header_output, decoder_output, decode_block, exec_output) = \
410        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
411        'Load', exec_template_base='Load')
412}};
413
414def format Store(memacc_code, ea_code={{EA = Rs1 + sdisp;}}, mem_flags=[],
415        inst_flags=[]) {{
416    (header_output, decoder_output, decode_block, exec_output) = \
417        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
418        'Store', exec_template_base='Store')
419}};
420
421def format StoreCond(memacc_code, postacc_code, ea_code={{EA = Rs1;}},
422        mem_flags=[], inst_flags=[], aq=0, rl=0) {{
423    if aq:
424        mem_flags = makeList(mem_flags) + ["ACQUIRE"]
425    if rl:
426        mem_flags = makeList(mem_flags) + ["RELEASE"]
427    (header_output, decoder_output, decode_block, exec_output) = LoadStoreBase(
428            name, Name, ea_code, memacc_code, mem_flags, inst_flags, 'Store',
429            postacc_code, exec_template_base='StoreCond')
430}};
431
432def format LoadReserved(memacc_code, ea_code={{EA = Rs1;}}, mem_flags=[],
433        inst_flags=[], aq=0, rl=0) {{
434    if aq:
435        mem_flags = makeList(mem_flags) + ["ACQUIRE"]
436    if rl:
437        mem_flags = makeList(mem_flags) + ["RELEASE"]
438    (header_output, decoder_output, decode_block, exec_output) = LoadStoreBase(
439            name, Name, ea_code, memacc_code, mem_flags, inst_flags, 'Load',
440            exec_template_base='Load')
441}};
442