macromem.isa revision 6258
16019Shines@cs.fsu.edu// -*- mode:c++ -*-
26019Shines@cs.fsu.edu
36019Shines@cs.fsu.edu// Copyright (c) 2007-2008 The Florida State University
46019Shines@cs.fsu.edu// All rights reserved.
56019Shines@cs.fsu.edu//
66019Shines@cs.fsu.edu// Redistribution and use in source and binary forms, with or without
76019Shines@cs.fsu.edu// modification, are permitted provided that the following conditions are
86019Shines@cs.fsu.edu// met: redistributions of source code must retain the above copyright
96019Shines@cs.fsu.edu// notice, this list of conditions and the following disclaimer;
106019Shines@cs.fsu.edu// redistributions in binary form must reproduce the above copyright
116019Shines@cs.fsu.edu// notice, this list of conditions and the following disclaimer in the
126019Shines@cs.fsu.edu// documentation and/or other materials provided with the distribution;
136019Shines@cs.fsu.edu// neither the name of the copyright holders nor the names of its
146019Shines@cs.fsu.edu// contributors may be used to endorse or promote products derived from
156019Shines@cs.fsu.edu// this software without specific prior written permission.
166019Shines@cs.fsu.edu//
176019Shines@cs.fsu.edu// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
186019Shines@cs.fsu.edu// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
196019Shines@cs.fsu.edu// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
206019Shines@cs.fsu.edu// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
216019Shines@cs.fsu.edu// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
226019Shines@cs.fsu.edu// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
236019Shines@cs.fsu.edu// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
246019Shines@cs.fsu.edu// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
256019Shines@cs.fsu.edu// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
266019Shines@cs.fsu.edu// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
276019Shines@cs.fsu.edu// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
286019Shines@cs.fsu.edu//
296019Shines@cs.fsu.edu// Authors: Stephen Hines
306019Shines@cs.fsu.edu
316019Shines@cs.fsu.edu////////////////////////////////////////////////////////////////////
326019Shines@cs.fsu.edu//
336019Shines@cs.fsu.edu// Macro Memory-format instructions
346019Shines@cs.fsu.edu//
356019Shines@cs.fsu.edu
366019Shines@cs.fsu.edudef template MacroStoreDeclare {{
376253Sgblack@eecs.umich.edu/**
386253Sgblack@eecs.umich.edu * Static instructions class for a store multiple instruction
396253Sgblack@eecs.umich.edu */
406253Sgblack@eecs.umich.educlass %(class_name)s : public %(base_class)s
416253Sgblack@eecs.umich.edu{
426253Sgblack@eecs.umich.edu    public:
436253Sgblack@eecs.umich.edu        // Constructor
446253Sgblack@eecs.umich.edu        %(class_name)s(ExtMachInst machInst);
456253Sgblack@eecs.umich.edu        %(BasicExecDeclare)s
466253Sgblack@eecs.umich.edu};
476019Shines@cs.fsu.edu}};
486019Shines@cs.fsu.edu
496019Shines@cs.fsu.edudef template MacroStoreConstructor {{
506253Sgblack@eecs.umich.eduinline %(class_name)s::%(class_name)s(ExtMachInst machInst)
516253Sgblack@eecs.umich.edu    : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
526253Sgblack@eecs.umich.edu{
536253Sgblack@eecs.umich.edu    %(constructor)s;
546253Sgblack@eecs.umich.edu    uint32_t regs_to_handle = reglist;
556253Sgblack@eecs.umich.edu    uint32_t j = 0,
566253Sgblack@eecs.umich.edu             start_addr = 0,
576253Sgblack@eecs.umich.edu             end_addr = 0;
586253Sgblack@eecs.umich.edu
596253Sgblack@eecs.umich.edu    switch (puswl)
606019Shines@cs.fsu.edu    {
616258Sjack-m5ml2@cs.york.ac.uk        case 0x00: //       stmda
626253Sgblack@eecs.umich.edu        case 0x01: //     L ldmda_l
636258Sjack-m5ml2@cs.york.ac.uk        case 0x02: //    W  stmda_w
646253Sgblack@eecs.umich.edu        case 0x03: //    WL ldmda_wl
656253Sgblack@eecs.umich.edu            start_addr = (ones << 2) - 4;
666253Sgblack@eecs.umich.edu            end_addr = 0;
676253Sgblack@eecs.umich.edu            break;
686253Sgblack@eecs.umich.edu        case 0x08: //  U    stmia_u
696253Sgblack@eecs.umich.edu        case 0x09: //  U  L ldmia_ul
706258Sjack-m5ml2@cs.york.ac.uk        case 0x0a: //  U W  stmia
716253Sgblack@eecs.umich.edu        case 0x0b: //  U WL ldmia
726253Sgblack@eecs.umich.edu            start_addr = 0;
736253Sgblack@eecs.umich.edu            end_addr = (ones << 2) - 4;
746253Sgblack@eecs.umich.edu            break;
756258Sjack-m5ml2@cs.york.ac.uk        case 0x10: // P     stmdb
766253Sgblack@eecs.umich.edu        case 0x11: // P   L ldmdb
776253Sgblack@eecs.umich.edu        case 0x12: // P  W  stmdb
786258Sjack-m5ml2@cs.york.ac.uk        case 0x13: // P  WL ldmdb
796253Sgblack@eecs.umich.edu            start_addr = (ones << 2); // U-bit is already 0 for subtract
806253Sgblack@eecs.umich.edu            end_addr = 4; // negative 4
816253Sgblack@eecs.umich.edu            break;
826253Sgblack@eecs.umich.edu        case 0x18: // PU    stmib
836253Sgblack@eecs.umich.edu        case 0x19: // PU  L ldmib
846258Sjack-m5ml2@cs.york.ac.uk        case 0x1a: // PU W  stmib
856258Sjack-m5ml2@cs.york.ac.uk        case 0x1b: // PU WL ldmib
866253Sgblack@eecs.umich.edu            start_addr = 4;
876253Sgblack@eecs.umich.edu            end_addr = (ones << 2) + 4;
886253Sgblack@eecs.umich.edu            break;
896253Sgblack@eecs.umich.edu        default:
906258Sjack-m5ml2@cs.york.ac.uk            panic("Unhandled Load/Store Multiple Instruction, "
916258Sjack-m5ml2@cs.york.ac.uk                "puswl = 0x%x", (unsigned) puswl);
926253Sgblack@eecs.umich.edu            break;
936253Sgblack@eecs.umich.edu    }
946019Shines@cs.fsu.edu
956253Sgblack@eecs.umich.edu    //TODO - Add addi_uop/subi_uop here to create starting addresses
966253Sgblack@eecs.umich.edu    //Just using addi with 0 offset makes a "copy" of Rn for our use
976253Sgblack@eecs.umich.edu    uint32_t newMachInst = 0;
986253Sgblack@eecs.umich.edu    newMachInst = machInst & 0xffff0000;
996253Sgblack@eecs.umich.edu    microOps[0] = new Addi_uop(newMachInst);
1006253Sgblack@eecs.umich.edu
1016253Sgblack@eecs.umich.edu    for (int i = 1; i < ones+1; i++)
1026253Sgblack@eecs.umich.edu    {
1036253Sgblack@eecs.umich.edu        // Get next available bit for transfer
1046253Sgblack@eecs.umich.edu        while (! ( regs_to_handle & (1<<j)))
1056253Sgblack@eecs.umich.edu            j++;
1066253Sgblack@eecs.umich.edu        regs_to_handle &= ~(1<<j);
1076253Sgblack@eecs.umich.edu
1086253Sgblack@eecs.umich.edu        microOps[i] = gen_ldrstr_uop(machInst, loadop, j, start_addr);
1096253Sgblack@eecs.umich.edu
1106253Sgblack@eecs.umich.edu        if (up)
1116253Sgblack@eecs.umich.edu            start_addr += 4;
1126253Sgblack@eecs.umich.edu        else
1136253Sgblack@eecs.umich.edu            start_addr -= 4;
1146253Sgblack@eecs.umich.edu    }
1156253Sgblack@eecs.umich.edu
1166253Sgblack@eecs.umich.edu    /* TODO: Take a look at how these 2 values should meet together
1176253Sgblack@eecs.umich.edu    if (start_addr != (end_addr - 4))
1186253Sgblack@eecs.umich.edu    {
1196253Sgblack@eecs.umich.edu        fprintf(stderr, "start_addr: %d\n", start_addr);
1206253Sgblack@eecs.umich.edu        fprintf(stderr, "end_addr:   %d\n", end_addr);
1216253Sgblack@eecs.umich.edu        panic("start_addr does not meet end_addr");
1226253Sgblack@eecs.umich.edu    }
1236253Sgblack@eecs.umich.edu    */
1246253Sgblack@eecs.umich.edu
1256253Sgblack@eecs.umich.edu    if (writeback)
1266253Sgblack@eecs.umich.edu    {
1276253Sgblack@eecs.umich.edu        uint32_t newMachInst = machInst & 0xf0000000;
1286253Sgblack@eecs.umich.edu        uint32_t rn = (machInst >> 16) & 0x0f;
1296253Sgblack@eecs.umich.edu        // 3322 2222 2222 1111 1111 11
1306253Sgblack@eecs.umich.edu        // 1098 7654 3210 9876 5432 1098 7654 3210
1316253Sgblack@eecs.umich.edu        // COND 0010 0100 [RN] [RD] 0000 [  IMM  ]
1326253Sgblack@eecs.umich.edu        // sub rn, rn, imm
1336253Sgblack@eecs.umich.edu        newMachInst |= 0x02400000;
1346253Sgblack@eecs.umich.edu        newMachInst |= ((rn << 16) | (rn << 12));
1356253Sgblack@eecs.umich.edu        newMachInst |= (ones << 2);
1366253Sgblack@eecs.umich.edu        if (up)
1376019Shines@cs.fsu.edu        {
1386253Sgblack@eecs.umich.edu            microOps[numMicroops-1] = new Addi_rd_uop(newMachInst);
1396019Shines@cs.fsu.edu        }
1406253Sgblack@eecs.umich.edu        else
1416019Shines@cs.fsu.edu        {
1426253Sgblack@eecs.umich.edu            microOps[numMicroops-1] = new Subi_rd_uop(newMachInst);
1436019Shines@cs.fsu.edu        }
1446019Shines@cs.fsu.edu    }
1456253Sgblack@eecs.umich.edu    microOps[numMicroops-1]->setLastMicroop();
1466253Sgblack@eecs.umich.edu}
1476019Shines@cs.fsu.edu
1486019Shines@cs.fsu.edu}};
1496019Shines@cs.fsu.edu
1506019Shines@cs.fsu.edudef template MacroStoreExecute {{
1516253Sgblack@eecs.umich.eduFault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
1526253Sgblack@eecs.umich.edu{
1536253Sgblack@eecs.umich.edu    Fault fault = NoFault;
1546253Sgblack@eecs.umich.edu
1556253Sgblack@eecs.umich.edu    %(fp_enable_check)s;
1566253Sgblack@eecs.umich.edu    %(op_decl)s;
1576253Sgblack@eecs.umich.edu    %(op_rd)s;
1586253Sgblack@eecs.umich.edu    %(code)s;
1596253Sgblack@eecs.umich.edu    if (fault == NoFault)
1606019Shines@cs.fsu.edu    {
1616253Sgblack@eecs.umich.edu        %(op_wb)s;
1626253Sgblack@eecs.umich.edu    }
1636019Shines@cs.fsu.edu
1646253Sgblack@eecs.umich.edu    return fault;
1656253Sgblack@eecs.umich.edu}
1666019Shines@cs.fsu.edu}};
1676019Shines@cs.fsu.edu
1686019Shines@cs.fsu.edudef template MacroFPAConstructor {{
1696253Sgblack@eecs.umich.eduinline %(class_name)s::%(class_name)s(ExtMachInst machInst)
1706253Sgblack@eecs.umich.edu    : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
1716253Sgblack@eecs.umich.edu{
1726253Sgblack@eecs.umich.edu    %(constructor)s;
1736253Sgblack@eecs.umich.edu
1746253Sgblack@eecs.umich.edu    uint32_t start_addr = 0;
1756253Sgblack@eecs.umich.edu
1766253Sgblack@eecs.umich.edu    if (prepost)
1776253Sgblack@eecs.umich.edu        start_addr = disp8;
1786253Sgblack@eecs.umich.edu    else
1796253Sgblack@eecs.umich.edu        start_addr = 0;
1806253Sgblack@eecs.umich.edu
1816253Sgblack@eecs.umich.edu    emit_ldfstf_uops(microOps, 0, machInst, loadop, up, start_addr);
1826253Sgblack@eecs.umich.edu
1836253Sgblack@eecs.umich.edu    if (writeback)
1846019Shines@cs.fsu.edu    {
1856253Sgblack@eecs.umich.edu        uint32_t newMachInst = machInst & 0xf0000000;
1866253Sgblack@eecs.umich.edu        uint32_t rn = (machInst >> 16) & 0x0f;
1876253Sgblack@eecs.umich.edu        // 3322 2222 2222 1111 1111 11
1886253Sgblack@eecs.umich.edu        // 1098 7654 3210 9876 5432 1098 7654 3210
1896253Sgblack@eecs.umich.edu        // COND 0010 0100 [RN] [RD] 0000 [  IMM  ]
1906253Sgblack@eecs.umich.edu        // sub rn, rn, imm
1916253Sgblack@eecs.umich.edu        newMachInst |= 0x02400000;
1926253Sgblack@eecs.umich.edu        newMachInst |= ((rn << 16) | (rn << 12));
1936253Sgblack@eecs.umich.edu        if (up)
1946253Sgblack@eecs.umich.edu        {
1956253Sgblack@eecs.umich.edu            newMachInst |= disp8;
1966253Sgblack@eecs.umich.edu            microOps[numMicroops-1] = new Addi_rd_uop(newMachInst);
1976253Sgblack@eecs.umich.edu        }
1986019Shines@cs.fsu.edu        else
1996019Shines@cs.fsu.edu        {
2006253Sgblack@eecs.umich.edu            newMachInst |= disp8;
2016253Sgblack@eecs.umich.edu            microOps[numMicroops-1] = new Subi_rd_uop(newMachInst);
2026019Shines@cs.fsu.edu        }
2036019Shines@cs.fsu.edu    }
2046253Sgblack@eecs.umich.edu    microOps[numMicroops-1]->setLastMicroop();
2056253Sgblack@eecs.umich.edu}
2066019Shines@cs.fsu.edu
2076019Shines@cs.fsu.edu}};
2086019Shines@cs.fsu.edu
2096019Shines@cs.fsu.edu
2106019Shines@cs.fsu.edudef template MacroFMConstructor {{
2116253Sgblack@eecs.umich.eduinline %(class_name)s::%(class_name)s(ExtMachInst machInst)
2126253Sgblack@eecs.umich.edu    : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
2136253Sgblack@eecs.umich.edu{
2146253Sgblack@eecs.umich.edu    %(constructor)s;
2156253Sgblack@eecs.umich.edu
2166253Sgblack@eecs.umich.edu    uint32_t start_addr = 0;
2176253Sgblack@eecs.umich.edu
2186253Sgblack@eecs.umich.edu    if (prepost)
2196253Sgblack@eecs.umich.edu        start_addr = disp8;
2206253Sgblack@eecs.umich.edu    else
2216253Sgblack@eecs.umich.edu        start_addr = 0;
2226253Sgblack@eecs.umich.edu
2236253Sgblack@eecs.umich.edu    for (int i = 0; i < count; i++)
2246019Shines@cs.fsu.edu    {
2256253Sgblack@eecs.umich.edu        emit_ldfstf_uops(microOps, 3*i, machInst, loadop, up, start_addr);
2266019Shines@cs.fsu.edu    }
2276019Shines@cs.fsu.edu
2286253Sgblack@eecs.umich.edu    if (writeback)
2296253Sgblack@eecs.umich.edu    {
2306253Sgblack@eecs.umich.edu        uint32_t newMachInst = machInst & 0xf0000000;
2316253Sgblack@eecs.umich.edu        uint32_t rn = (machInst >> 16) & 0x0f;
2326253Sgblack@eecs.umich.edu        // 3322 2222 2222 1111 1111 11
2336253Sgblack@eecs.umich.edu        // 1098 7654 3210 9876 5432 1098 7654 3210
2346253Sgblack@eecs.umich.edu        // COND 0010 0100 [RN] [RD] 0000 [  IMM  ]
2356253Sgblack@eecs.umich.edu        // sub rn, rn, imm
2366253Sgblack@eecs.umich.edu        newMachInst |= 0x02400000;
2376253Sgblack@eecs.umich.edu        newMachInst |= ((rn << 16) | (rn << 12));
2386253Sgblack@eecs.umich.edu        if (up)
2396253Sgblack@eecs.umich.edu        {
2406253Sgblack@eecs.umich.edu            newMachInst |= disp8;
2416253Sgblack@eecs.umich.edu            microOps[numMicroops-1] = new Addi_rd_uop(newMachInst);
2426253Sgblack@eecs.umich.edu        }
2436253Sgblack@eecs.umich.edu        else
2446253Sgblack@eecs.umich.edu        {
2456253Sgblack@eecs.umich.edu            newMachInst |= disp8;
2466253Sgblack@eecs.umich.edu            microOps[numMicroops-1] = new Subi_rd_uop(newMachInst);
2476253Sgblack@eecs.umich.edu        }
2486253Sgblack@eecs.umich.edu    }
2496253Sgblack@eecs.umich.edu    microOps[numMicroops-1]->setLastMicroop();
2506253Sgblack@eecs.umich.edu}
2516019Shines@cs.fsu.edu}};
2526019Shines@cs.fsu.edu
2536019Shines@cs.fsu.edu
2546019Shines@cs.fsu.edudef format ArmMacroStore(code, mem_flags = [], inst_flag = [], *opt_flags) {{
2556019Shines@cs.fsu.edu    iop = InstObjParams(name, Name, 'ArmMacroMemoryOp', code, opt_flags)
2566019Shines@cs.fsu.edu    header_output = MacroStoreDeclare.subst(iop)
2576019Shines@cs.fsu.edu    decoder_output = MacroStoreConstructor.subst(iop)
2586019Shines@cs.fsu.edu    decode_block = BasicDecode.subst(iop)
2596019Shines@cs.fsu.edu    exec_output = MacroStoreExecute.subst(iop)
2606019Shines@cs.fsu.edu}};
2616019Shines@cs.fsu.edu
2626019Shines@cs.fsu.edudef format ArmMacroFPAOp(code, mem_flags = [], inst_flag = [], *opt_flags) {{
2636243Sgblack@eecs.umich.edu    iop = InstObjParams(name, Name, 'ArmMacroFPAOp',
2646243Sgblack@eecs.umich.edu                        {"code": code,
2656243Sgblack@eecs.umich.edu                         "predicate_test": predicateTest},
2666243Sgblack@eecs.umich.edu                        opt_flags)
2676019Shines@cs.fsu.edu    header_output = BasicDeclare.subst(iop)
2686019Shines@cs.fsu.edu    decoder_output = MacroFPAConstructor.subst(iop)
2696019Shines@cs.fsu.edu    decode_block = BasicDecode.subst(iop)
2706019Shines@cs.fsu.edu    exec_output = PredOpExecute.subst(iop)
2716019Shines@cs.fsu.edu}};
2726019Shines@cs.fsu.edu
2736019Shines@cs.fsu.edudef format ArmMacroFMOp(code, mem_flags = [], inst_flag = [], *opt_flags) {{
2746243Sgblack@eecs.umich.edu    iop = InstObjParams(name, Name, 'ArmMacroFMOp',
2756243Sgblack@eecs.umich.edu                        {"code": code,
2766243Sgblack@eecs.umich.edu                         "predicate_test": predicateTest},
2776243Sgblack@eecs.umich.edu                        opt_flags)
2786019Shines@cs.fsu.edu    header_output = BasicDeclare.subst(iop)
2796019Shines@cs.fsu.edu    decoder_output = MacroFMConstructor.subst(iop)
2806019Shines@cs.fsu.edu    decode_block = BasicDecode.subst(iop)
2816019Shines@cs.fsu.edu    exec_output = PredOpExecute.subst(iop)
2826019Shines@cs.fsu.edu}};
283