macromem.isa revision 6019
1955SN/A// -*- mode:c++ -*- 2955SN/A 35871Snate@binkert.org// Copyright (c) 2007-2008 The Florida State University 41762SN/A// All rights reserved. 5955SN/A// 6955SN/A// Redistribution and use in source and binary forms, with or without 7955SN/A// modification, are permitted provided that the following conditions are 8955SN/A// met: redistributions of source code must retain the above copyright 9955SN/A// notice, this list of conditions and the following disclaimer; 10955SN/A// redistributions in binary form must reproduce the above copyright 11955SN/A// notice, this list of conditions and the following disclaimer in the 12955SN/A// documentation and/or other materials provided with the distribution; 13955SN/A// neither the name of the copyright holders nor the names of its 14955SN/A// contributors may be used to endorse or promote products derived from 15955SN/A// this software without specific prior written permission. 16955SN/A// 17955SN/A// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18955SN/A// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19955SN/A// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20955SN/A// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21955SN/A// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22955SN/A// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23955SN/A// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24955SN/A// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25955SN/A// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26955SN/A// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27955SN/A// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28955SN/A// 292665Ssaidi@eecs.umich.edu// Authors: Stephen Hines 302665Ssaidi@eecs.umich.edu 315863Snate@binkert.org//////////////////////////////////////////////////////////////////// 32955SN/A// 33955SN/A// Macro Memory-format instructions 34955SN/A// 35955SN/A 36955SN/Aoutput header {{ 372632Sstever@eecs.umich.edu 382632Sstever@eecs.umich.edu /** 392632Sstever@eecs.umich.edu * Arm Macro Memory operations like LDM/STM 402632Sstever@eecs.umich.edu */ 41955SN/A class ArmMacroMemoryOp : public PredMacroOp 422632Sstever@eecs.umich.edu { 432632Sstever@eecs.umich.edu protected: 442761Sstever@eecs.umich.edu /// Memory request flags. See mem_req_base.hh. 452632Sstever@eecs.umich.edu unsigned memAccessFlags; 462632Sstever@eecs.umich.edu /// Pointer to EAComp object. 472632Sstever@eecs.umich.edu const StaticInstPtr eaCompPtr; 482761Sstever@eecs.umich.edu /// Pointer to MemAcc object. 492761Sstever@eecs.umich.edu const StaticInstPtr memAccPtr; 502761Sstever@eecs.umich.edu 512632Sstever@eecs.umich.edu uint32_t reglist; 522632Sstever@eecs.umich.edu uint32_t ones; 532761Sstever@eecs.umich.edu uint32_t puswl, 542761Sstever@eecs.umich.edu prepost, 552761Sstever@eecs.umich.edu up, 562761Sstever@eecs.umich.edu psruser, 572761Sstever@eecs.umich.edu writeback, 582632Sstever@eecs.umich.edu loadop; 592632Sstever@eecs.umich.edu 602632Sstever@eecs.umich.edu ArmMacroMemoryOp(const char *mnem, MachInst _machInst, OpClass __opClass, 612632Sstever@eecs.umich.edu StaticInstPtr _eaCompPtr = nullStaticInstPtr, 622632Sstever@eecs.umich.edu StaticInstPtr _memAccPtr = nullStaticInstPtr) 632632Sstever@eecs.umich.edu : PredMacroOp(mnem, _machInst, __opClass), 642632Sstever@eecs.umich.edu memAccessFlags(0), eaCompPtr(_eaCompPtr), memAccPtr(_memAccPtr), 65955SN/A reglist(REGLIST), ones(0), puswl(PUSWL), prepost(PREPOST), up(UP), 66955SN/A psruser(PSRUSER), writeback(WRITEBACK), loadop(LOADOP) 67955SN/A { 685863Snate@binkert.org ones = number_of_ones(reglist); 695863Snate@binkert.org numMicroops = ones + writeback + 1; 705863Snate@binkert.org // Remember that writeback adds a uop 715863Snate@binkert.org microOps = new StaticInstPtr[numMicroops]; 725863Snate@binkert.org } 735863Snate@binkert.org }; 745863Snate@binkert.org 755863Snate@binkert.org /** 765863Snate@binkert.org * Arm Macro FPA operations to fix ldfd and stfd instructions 775863Snate@binkert.org */ 785863Snate@binkert.org class ArmMacroFPAOp : public PredMacroOp 795863Snate@binkert.org { 805863Snate@binkert.org protected: 815863Snate@binkert.org uint32_t puswl, 825863Snate@binkert.org prepost, 835863Snate@binkert.org up, 845863Snate@binkert.org psruser, 855863Snate@binkert.org writeback, 865863Snate@binkert.org loadop; 875863Snate@binkert.org int32_t disp8; 885863Snate@binkert.org 895863Snate@binkert.org ArmMacroFPAOp(const char *mnem, MachInst _machInst, OpClass __opClass) 905863Snate@binkert.org : PredMacroOp(mnem, _machInst, __opClass), 915863Snate@binkert.org puswl(PUSWL), prepost(PREPOST), up(UP), 925863Snate@binkert.org psruser(PSRUSER), writeback(WRITEBACK), loadop(LOADOP), 935863Snate@binkert.org disp8(IMMED_7_0 << 2) 945863Snate@binkert.org { 955863Snate@binkert.org numMicroops = 3 + writeback; 965863Snate@binkert.org microOps = new StaticInstPtr[numMicroops]; 975863Snate@binkert.org } 985863Snate@binkert.org }; 996654Snate@binkert.org 100955SN/A /** 1015396Ssaidi@eecs.umich.edu * Arm Macro FM operations to fix lfm and sfm 1025863Snate@binkert.org */ 1035863Snate@binkert.org class ArmMacroFMOp : public PredMacroOp 1044202Sbinkertn@umich.edu { 1055863Snate@binkert.org protected: 1065863Snate@binkert.org uint32_t punwl, 1075863Snate@binkert.org prepost, 1085863Snate@binkert.org up, 109955SN/A n1bit, 1106654Snate@binkert.org writeback, 1115273Sstever@gmail.com loadop, 1125871Snate@binkert.org n0bit, 1135273Sstever@gmail.com count; 1146655Snate@binkert.org int32_t disp8; 1156655Snate@binkert.org 1166655Snate@binkert.org ArmMacroFMOp(const char *mnem, MachInst _machInst, OpClass __opClass) 1176655Snate@binkert.org : PredMacroOp(mnem, _machInst, __opClass), 1186655Snate@binkert.org punwl(PUNWL), prepost(PREPOST), up(UP), 1196655Snate@binkert.org n1bit(OPCODE_22), writeback(WRITEBACK), loadop(LOADOP), 1205871Snate@binkert.org n0bit(OPCODE_15), disp8(IMMED_7_0 << 2) 1216654Snate@binkert.org { 1225396Ssaidi@eecs.umich.edu // Transfer 1-4 registers based on n1 and n0 bits (with 00 repr. 4) 1235871Snate@binkert.org count = (n1bit << 1) | n0bit; 1245871Snate@binkert.org if (count == 0) 1256121Snate@binkert.org count = 4; 1265871Snate@binkert.org numMicroops = (3*count) + writeback; 1275871Snate@binkert.org microOps = new StaticInstPtr[numMicroops]; 1286003Snate@binkert.org } 1296655Snate@binkert.org }; 130955SN/A 1315871Snate@binkert.org 1325871Snate@binkert.org}}; 1335871Snate@binkert.org 1345871Snate@binkert.org 135955SN/Aoutput decoder {{ 1366121Snate@binkert.org}}; 1376121Snate@binkert.org 1386121Snate@binkert.orgdef template MacroStoreDeclare {{ 1391533SN/A /** 1406655Snate@binkert.org * Static instructions class for a store multiple instruction 1416655Snate@binkert.org */ 1426655Snate@binkert.org class %(class_name)s : public %(base_class)s 1436655Snate@binkert.org { 1445871Snate@binkert.org public: 1455871Snate@binkert.org // Constructor 1465863Snate@binkert.org %(class_name)s(MachInst machInst); 1475871Snate@binkert.org %(BasicExecDeclare)s 1485871Snate@binkert.org }; 1495871Snate@binkert.org}}; 1505871Snate@binkert.org 1515871Snate@binkert.orgdef template MacroStoreConstructor {{ 1525863Snate@binkert.org inline %(class_name)s::%(class_name)s(MachInst machInst) 1536121Snate@binkert.org : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s) 1545863Snate@binkert.org { 1555871Snate@binkert.org %(constructor)s; 1564678Snate@binkert.org uint32_t regs_to_handle = reglist; 1574678Snate@binkert.org uint32_t j = 0, 1584678Snate@binkert.org start_addr = 0, 1594678Snate@binkert.org end_addr = 0; 1604678Snate@binkert.org 1614678Snate@binkert.org switch (puswl) 1624678Snate@binkert.org { 1634678Snate@binkert.org case 0x01: // L ldmda_l 1644678Snate@binkert.org start_addr = (ones << 2) - 4; 1654678Snate@binkert.org end_addr = 0; 1664678Snate@binkert.org break; 1674678Snate@binkert.org case 0x03: // WL ldmda_wl 1686121Snate@binkert.org start_addr = (ones << 2) - 4; 1694678Snate@binkert.org end_addr = 0; 1705871Snate@binkert.org break; 1715871Snate@binkert.org case 0x08: // U stmia_u 1725871Snate@binkert.org start_addr = 0; 1735871Snate@binkert.org end_addr = (ones << 2) - 4; 1745871Snate@binkert.org break; 1755871Snate@binkert.org case 0x09: // U L ldmia_ul 1765871Snate@binkert.org start_addr = 0; 1775871Snate@binkert.org end_addr = (ones << 2) - 4; 1785871Snate@binkert.org break; 1795871Snate@binkert.org case 0x0b: // U WL ldmia 1805871Snate@binkert.org start_addr = 0; 1815871Snate@binkert.org end_addr = (ones << 2) - 4; 1825871Snate@binkert.org break; 1835990Ssaidi@eecs.umich.edu case 0x11: // P L ldmdb 1845871Snate@binkert.org start_addr = (ones << 2); // U-bit is already 0 for subtract 1855871Snate@binkert.org end_addr = 4; // negative 4 1865871Snate@binkert.org break; 1874678Snate@binkert.org case 0x12: // P W stmdb 1886654Snate@binkert.org start_addr = (ones << 2); // U-bit is already 0 for subtract 1895871Snate@binkert.org end_addr = 4; // negative 4 1905871Snate@binkert.org break; 1915871Snate@binkert.org case 0x18: // PU stmib 1925871Snate@binkert.org start_addr = 4; 1935871Snate@binkert.org end_addr = (ones << 2) + 4; 1945871Snate@binkert.org break; 1955871Snate@binkert.org case 0x19: // PU L ldmib 1965871Snate@binkert.org start_addr = 4; 1975871Snate@binkert.org end_addr = (ones << 2) + 4; 1984678Snate@binkert.org break; 1995871Snate@binkert.org default: 2004678Snate@binkert.org panic("Unhandled Load/Store Multiple Instruction"); 2015871Snate@binkert.org break; 2025871Snate@binkert.org } 2035871Snate@binkert.org 2045871Snate@binkert.org //TODO - Add addi_uop/subi_uop here to create starting addresses 2055871Snate@binkert.org //Just using addi with 0 offset makes a "copy" of Rn for our use 2065871Snate@binkert.org uint32_t newMachInst = 0; 2075871Snate@binkert.org newMachInst = machInst & 0xffff0000; 2085871Snate@binkert.org microOps[0] = new Addi_uop(newMachInst); 2095871Snate@binkert.org 2106121Snate@binkert.org for (int i = 1; i < ones+1; i++) 2116121Snate@binkert.org { 2125863Snate@binkert.org // Get next available bit for transfer 213955SN/A while (! ( regs_to_handle & (1<<j))) 214955SN/A j++; 2152632Sstever@eecs.umich.edu regs_to_handle &= ~(1<<j); 2162632Sstever@eecs.umich.edu 217955SN/A microOps[i] = gen_ldrstr_uop(machInst, loadop, j, start_addr); 218955SN/A 219955SN/A if (up) 220955SN/A start_addr += 4; 2215863Snate@binkert.org else 222955SN/A start_addr -= 4; 2232632Sstever@eecs.umich.edu } 2242632Sstever@eecs.umich.edu 2252632Sstever@eecs.umich.edu /* TODO: Take a look at how these 2 values should meet together 2262632Sstever@eecs.umich.edu if (start_addr != (end_addr - 4)) 2272632Sstever@eecs.umich.edu { 2282632Sstever@eecs.umich.edu fprintf(stderr, "start_addr: %d\n", start_addr); 2292632Sstever@eecs.umich.edu fprintf(stderr, "end_addr: %d\n", end_addr); 2302632Sstever@eecs.umich.edu panic("start_addr does not meet end_addr"); 2312632Sstever@eecs.umich.edu } 2322632Sstever@eecs.umich.edu */ 2332632Sstever@eecs.umich.edu 2342632Sstever@eecs.umich.edu if (writeback) 2352632Sstever@eecs.umich.edu { 2363718Sstever@eecs.umich.edu uint32_t newMachInst = machInst & 0xf0000000; 2373718Sstever@eecs.umich.edu uint32_t rn = (machInst >> 16) & 0x0f; 2383718Sstever@eecs.umich.edu // 3322 2222 2222 1111 1111 11 2393718Sstever@eecs.umich.edu // 1098 7654 3210 9876 5432 1098 7654 3210 2403718Sstever@eecs.umich.edu // COND 0010 0100 [RN] [RD] 0000 [ IMM ] 2415863Snate@binkert.org // sub rn, rn, imm 2425863Snate@binkert.org newMachInst |= 0x02400000; 2433718Sstever@eecs.umich.edu newMachInst |= ((rn << 16) | (rn << 12)); 2443718Sstever@eecs.umich.edu newMachInst |= (ones << 2); 2456121Snate@binkert.org if (up) 2465863Snate@binkert.org { 2473718Sstever@eecs.umich.edu microOps[numMicroops-1] = new Addi_rd_uop(newMachInst); 2483718Sstever@eecs.umich.edu } 2492634Sstever@eecs.umich.edu else 2502634Sstever@eecs.umich.edu { 2515863Snate@binkert.org microOps[numMicroops-1] = new Subi_rd_uop(newMachInst); 2522638Sstever@eecs.umich.edu } 2532632Sstever@eecs.umich.edu } 2542632Sstever@eecs.umich.edu microOps[numMicroops-1]->setLastMicroop(); 2552632Sstever@eecs.umich.edu } 2562632Sstever@eecs.umich.edu 2572632Sstever@eecs.umich.edu}}; 2582632Sstever@eecs.umich.edu 2591858SN/Adef template MacroStoreExecute {{ 2603716Sstever@eecs.umich.edu Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const 2612638Sstever@eecs.umich.edu { 2622638Sstever@eecs.umich.edu Fault fault = NoFault; 2632638Sstever@eecs.umich.edu 2642638Sstever@eecs.umich.edu %(fp_enable_check)s; 2652638Sstever@eecs.umich.edu %(op_decl)s; 2662638Sstever@eecs.umich.edu %(op_rd)s; 2672638Sstever@eecs.umich.edu %(code)s; 2685863Snate@binkert.org if (fault == NoFault) 2695863Snate@binkert.org { 2705863Snate@binkert.org %(op_wb)s; 271955SN/A } 2725341Sstever@gmail.com 2735341Sstever@gmail.com return fault; 2745863Snate@binkert.org } 2757756SAli.Saidi@ARM.com}}; 2765341Sstever@gmail.com 2776121Snate@binkert.orgdef template MacroFPAConstructor {{ 2784494Ssaidi@eecs.umich.edu inline %(class_name)s::%(class_name)s(MachInst machInst) 2796121Snate@binkert.org : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s) 2801105SN/A { 2812667Sstever@eecs.umich.edu %(constructor)s; 2822667Sstever@eecs.umich.edu 2832667Sstever@eecs.umich.edu uint32_t start_addr = 0; 2842667Sstever@eecs.umich.edu 2856121Snate@binkert.org if (prepost) 2862667Sstever@eecs.umich.edu start_addr = disp8; 2875341Sstever@gmail.com else 2885863Snate@binkert.org start_addr = 0; 2895341Sstever@gmail.com 2905341Sstever@gmail.com emit_ldfstf_uops(microOps, 0, machInst, loadop, up, start_addr); 2915341Sstever@gmail.com 2925863Snate@binkert.org if (writeback) 2935341Sstever@gmail.com { 2945341Sstever@gmail.com uint32_t newMachInst = machInst & 0xf0000000; 2955341Sstever@gmail.com uint32_t rn = (machInst >> 16) & 0x0f; 2965863Snate@binkert.org // 3322 2222 2222 1111 1111 11 2975341Sstever@gmail.com // 1098 7654 3210 9876 5432 1098 7654 3210 2985341Sstever@gmail.com // COND 0010 0100 [RN] [RD] 0000 [ IMM ] 2995341Sstever@gmail.com // sub rn, rn, imm 3005341Sstever@gmail.com newMachInst |= 0x02400000; 3015341Sstever@gmail.com newMachInst |= ((rn << 16) | (rn << 12)); 3025341Sstever@gmail.com if (up) 3035341Sstever@gmail.com { 3045341Sstever@gmail.com newMachInst |= disp8; 3055341Sstever@gmail.com microOps[numMicroops-1] = new Addi_rd_uop(newMachInst); 3065341Sstever@gmail.com } 3075863Snate@binkert.org else 3085341Sstever@gmail.com { 3095863Snate@binkert.org newMachInst |= disp8; 3107756SAli.Saidi@ARM.com microOps[numMicroops-1] = new Subi_rd_uop(newMachInst); 3115341Sstever@gmail.com } 3125863Snate@binkert.org } 3136121Snate@binkert.org microOps[numMicroops-1]->setLastMicroop(); 3146121Snate@binkert.org } 3155397Ssaidi@eecs.umich.edu 3165397Ssaidi@eecs.umich.edu}}; 3177727SAli.Saidi@ARM.com 3185341Sstever@gmail.com 3196168Snate@binkert.orgdef template MacroFMConstructor {{ 3206168Snate@binkert.org inline %(class_name)s::%(class_name)s(MachInst machInst) 3215341Sstever@gmail.com : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s) 3227756SAli.Saidi@ARM.com { 3237756SAli.Saidi@ARM.com %(constructor)s; 3247756SAli.Saidi@ARM.com 3257756SAli.Saidi@ARM.com uint32_t start_addr = 0; 3267756SAli.Saidi@ARM.com 3277756SAli.Saidi@ARM.com if (prepost) 3285341Sstever@gmail.com start_addr = disp8; 3295341Sstever@gmail.com else 3305341Sstever@gmail.com start_addr = 0; 3315341Sstever@gmail.com 3325863Snate@binkert.org for (int i = 0; i < count; i++) 3335341Sstever@gmail.com { 3345341Sstever@gmail.com emit_ldfstf_uops(microOps, 3*i, machInst, loadop, up, start_addr); 3356121Snate@binkert.org } 3366121Snate@binkert.org 3377756SAli.Saidi@ARM.com if (writeback) 3385341Sstever@gmail.com { 3396814Sgblack@eecs.umich.edu uint32_t newMachInst = machInst & 0xf0000000; 3407756SAli.Saidi@ARM.com uint32_t rn = (machInst >> 16) & 0x0f; 3416814Sgblack@eecs.umich.edu // 3322 2222 2222 1111 1111 11 3425863Snate@binkert.org // 1098 7654 3210 9876 5432 1098 7654 3210 3436121Snate@binkert.org // COND 0010 0100 [RN] [RD] 0000 [ IMM ] 3445341Sstever@gmail.com // sub rn, rn, imm 3455863Snate@binkert.org newMachInst |= 0x02400000; 3465341Sstever@gmail.com newMachInst |= ((rn << 16) | (rn << 12)); 3476121Snate@binkert.org if (up) 3486121Snate@binkert.org { 3496121Snate@binkert.org newMachInst |= disp8; 3505742Snate@binkert.org microOps[numMicroops-1] = new Addi_rd_uop(newMachInst); 3515742Snate@binkert.org } 3525341Sstever@gmail.com else 3535742Snate@binkert.org { 3545742Snate@binkert.org newMachInst |= disp8; 3555341Sstever@gmail.com microOps[numMicroops-1] = new Subi_rd_uop(newMachInst); 3566017Snate@binkert.org } 3576121Snate@binkert.org } 3586017Snate@binkert.org microOps[numMicroops-1]->setLastMicroop(); 3597756SAli.Saidi@ARM.com } 3607756SAli.Saidi@ARM.com 3617756SAli.Saidi@ARM.com}}; 3627756SAli.Saidi@ARM.com 3637756SAli.Saidi@ARM.com 3647756SAli.Saidi@ARM.comdef format ArmMacroStore(code, mem_flags = [], inst_flag = [], *opt_flags) {{ 3657756SAli.Saidi@ARM.com iop = InstObjParams(name, Name, 'ArmMacroMemoryOp', code, opt_flags) 3667756SAli.Saidi@ARM.com header_output = MacroStoreDeclare.subst(iop) 3677756SAli.Saidi@ARM.com decoder_output = MacroStoreConstructor.subst(iop) 3687756SAli.Saidi@ARM.com decode_block = BasicDecode.subst(iop) 3697756SAli.Saidi@ARM.com exec_output = MacroStoreExecute.subst(iop) 3707756SAli.Saidi@ARM.com}}; 3717756SAli.Saidi@ARM.com 3727756SAli.Saidi@ARM.comdef format ArmMacroFPAOp(code, mem_flags = [], inst_flag = [], *opt_flags) {{ 3737756SAli.Saidi@ARM.com iop = InstObjParams(name, Name, 'ArmMacroFPAOp', code, opt_flags) 3747756SAli.Saidi@ARM.com header_output = BasicDeclare.subst(iop) 3757756SAli.Saidi@ARM.com decoder_output = MacroFPAConstructor.subst(iop) 3767756SAli.Saidi@ARM.com decode_block = BasicDecode.subst(iop) 3777756SAli.Saidi@ARM.com exec_output = PredOpExecute.subst(iop) 3787756SAli.Saidi@ARM.com}}; 3797756SAli.Saidi@ARM.com 3807756SAli.Saidi@ARM.comdef format ArmMacroFMOp(code, mem_flags = [], inst_flag = [], *opt_flags) {{ 3817756SAli.Saidi@ARM.com iop = InstObjParams(name, Name, 'ArmMacroFMOp', code, opt_flags) 3827756SAli.Saidi@ARM.com header_output = BasicDeclare.subst(iop) 3837756SAli.Saidi@ARM.com decoder_output = MacroFMConstructor.subst(iop) 3847756SAli.Saidi@ARM.com decode_block = BasicDecode.subst(iop) 3857756SAli.Saidi@ARM.com exec_output = PredOpExecute.subst(iop) 3867756SAli.Saidi@ARM.com}}; 3877756SAli.Saidi@ARM.com 3887756SAli.Saidi@ARM.com 3897756SAli.Saidi@ARM.com 3907756SAli.Saidi@ARM.com