macromem.cc revision 10346
17170Sgblack@eecs.umich.edu/* 210339Smitch.hayenga@arm.com * Copyright (c) 2010-2014 ARM Limited 37170Sgblack@eecs.umich.edu * All rights reserved 47170Sgblack@eecs.umich.edu * 57170Sgblack@eecs.umich.edu * The license below extends only to copyright in the software and shall 67170Sgblack@eecs.umich.edu * not be construed as granting a license to any other intellectual 77170Sgblack@eecs.umich.edu * property including but not limited to intellectual property relating 87170Sgblack@eecs.umich.edu * to a hardware implementation of the functionality of the software 97170Sgblack@eecs.umich.edu * licensed hereunder. You may use the software subject to the license 107170Sgblack@eecs.umich.edu * terms below provided that you ensure that this notice is replicated 117170Sgblack@eecs.umich.edu * unmodified and in its entirety in all distributions of the software, 127170Sgblack@eecs.umich.edu * modified or unmodified, in source code or in binary form. 137170Sgblack@eecs.umich.edu * 147170Sgblack@eecs.umich.edu * Copyright (c) 2007-2008 The Florida State University 157170Sgblack@eecs.umich.edu * All rights reserved. 167170Sgblack@eecs.umich.edu * 177170Sgblack@eecs.umich.edu * Redistribution and use in source and binary forms, with or without 187170Sgblack@eecs.umich.edu * modification, are permitted provided that the following conditions are 197170Sgblack@eecs.umich.edu * met: redistributions of source code must retain the above copyright 207170Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer; 217170Sgblack@eecs.umich.edu * redistributions in binary form must reproduce the above copyright 227170Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the 237170Sgblack@eecs.umich.edu * documentation and/or other materials provided with the distribution; 247170Sgblack@eecs.umich.edu * neither the name of the copyright holders nor the names of its 257170Sgblack@eecs.umich.edu * contributors may be used to endorse or promote products derived from 267170Sgblack@eecs.umich.edu * this software without specific prior written permission. 277170Sgblack@eecs.umich.edu * 287170Sgblack@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 297170Sgblack@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 307170Sgblack@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 317170Sgblack@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 327170Sgblack@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 337170Sgblack@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 347170Sgblack@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 357170Sgblack@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 367170Sgblack@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 377170Sgblack@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 387170Sgblack@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 397170Sgblack@eecs.umich.edu * 407170Sgblack@eecs.umich.edu * Authors: Stephen Hines 417170Sgblack@eecs.umich.edu */ 427170Sgblack@eecs.umich.edu 438229Snate@binkert.org#include <sstream> 448229Snate@binkert.org 457170Sgblack@eecs.umich.edu#include "arch/arm/insts/macromem.hh" 4610037SARM gem5 Developers 478961Sgblack@eecs.umich.edu#include "arch/arm/generated/decoder.hh" 4810037SARM gem5 Developers#include "arch/arm/insts/neon64_mem.hh" 497170Sgblack@eecs.umich.edu 507853SMatt.Horsnell@ARM.comusing namespace std; 517170Sgblack@eecs.umich.eduusing namespace ArmISAInst; 527170Sgblack@eecs.umich.edu 537170Sgblack@eecs.umich.edunamespace ArmISA 547170Sgblack@eecs.umich.edu{ 557170Sgblack@eecs.umich.edu 567170Sgblack@eecs.umich.eduMacroMemOp::MacroMemOp(const char *mnem, ExtMachInst machInst, 577170Sgblack@eecs.umich.edu OpClass __opClass, IntRegIndex rn, 587170Sgblack@eecs.umich.edu bool index, bool up, bool user, bool writeback, 597170Sgblack@eecs.umich.edu bool load, uint32_t reglist) : 607170Sgblack@eecs.umich.edu PredMacroOp(mnem, machInst, __opClass) 617170Sgblack@eecs.umich.edu{ 627170Sgblack@eecs.umich.edu uint32_t regs = reglist; 637170Sgblack@eecs.umich.edu uint32_t ones = number_of_ones(reglist); 6410346Smitch.hayenga@arm.com uint32_t mem_ops = ones; 658148SAli.Saidi@ARM.com 6610346Smitch.hayenga@arm.com // Copy the base address register if we overwrite it, or if this instruction 6710346Smitch.hayenga@arm.com // is basically a no-op (we have to do something) 6810346Smitch.hayenga@arm.com bool copy_base = (bits(reglist, rn) && load) || !ones; 6910346Smitch.hayenga@arm.com bool force_user = user & !bits(reglist, 15); 7010346Smitch.hayenga@arm.com bool exception_ret = user & bits(reglist, 15); 7110346Smitch.hayenga@arm.com bool pc_temp = load && writeback && bits(reglist, 15); 7210346Smitch.hayenga@arm.com 7310346Smitch.hayenga@arm.com if (!ones) { 748148SAli.Saidi@ARM.com numMicroops = 1; 7510346Smitch.hayenga@arm.com } else if (load) { 7610346Smitch.hayenga@arm.com numMicroops = ((ones + 1) / 2) 7710346Smitch.hayenga@arm.com + ((ones % 2 == 0 && exception_ret) ? 1 : 0) 7810346Smitch.hayenga@arm.com + (copy_base ? 1 : 0) 7910346Smitch.hayenga@arm.com + (writeback? 1 : 0) 8010346Smitch.hayenga@arm.com + (pc_temp ? 1 : 0); 8110346Smitch.hayenga@arm.com } else { 8210346Smitch.hayenga@arm.com numMicroops = ones + (writeback ? 1 : 0); 8310346Smitch.hayenga@arm.com } 848148SAli.Saidi@ARM.com 857170Sgblack@eecs.umich.edu microOps = new StaticInstPtr[numMicroops]; 8610346Smitch.hayenga@arm.com 877170Sgblack@eecs.umich.edu uint32_t addr = 0; 887170Sgblack@eecs.umich.edu 897170Sgblack@eecs.umich.edu if (!up) 907170Sgblack@eecs.umich.edu addr = (ones << 2) - 4; 917170Sgblack@eecs.umich.edu 927170Sgblack@eecs.umich.edu if (!index) 937170Sgblack@eecs.umich.edu addr += 4; 947170Sgblack@eecs.umich.edu 957190Sgblack@eecs.umich.edu StaticInstPtr *uop = microOps; 967190Sgblack@eecs.umich.edu 977170Sgblack@eecs.umich.edu // Add 0 to Rn and stick it in ureg0. 987170Sgblack@eecs.umich.edu // This is equivalent to a move. 9910346Smitch.hayenga@arm.com if (copy_base) 10010346Smitch.hayenga@arm.com *uop++ = new MicroAddiUop(machInst, INTREG_UREG0, rn, 0); 1017190Sgblack@eecs.umich.edu 1027170Sgblack@eecs.umich.edu unsigned reg = 0; 10310346Smitch.hayenga@arm.com while (mem_ops != 0) { 10410346Smitch.hayenga@arm.com // Do load operations in pairs if possible 10510346Smitch.hayenga@arm.com if (load && mem_ops >= 2 && 10610346Smitch.hayenga@arm.com !(mem_ops == 2 && bits(regs,INTREG_PC) && exception_ret)) { 10710346Smitch.hayenga@arm.com // 64-bit memory operation 10810346Smitch.hayenga@arm.com // Find 2 set register bits (clear them after finding) 10910346Smitch.hayenga@arm.com unsigned reg_idx1; 11010346Smitch.hayenga@arm.com unsigned reg_idx2; 1117170Sgblack@eecs.umich.edu 11210346Smitch.hayenga@arm.com // Find the first register 11310346Smitch.hayenga@arm.com while (!bits(regs, reg)) reg++; 11410346Smitch.hayenga@arm.com replaceBits(regs, reg, 0); 11510346Smitch.hayenga@arm.com reg_idx1 = force_user ? intRegInMode(MODE_USER, reg) : reg; 1167170Sgblack@eecs.umich.edu 11710346Smitch.hayenga@arm.com // Find the second register 11810346Smitch.hayenga@arm.com while (!bits(regs, reg)) reg++; 11910346Smitch.hayenga@arm.com replaceBits(regs, reg, 0); 12010346Smitch.hayenga@arm.com reg_idx2 = force_user ? intRegInMode(MODE_USER, reg) : reg; 1217170Sgblack@eecs.umich.edu 12210346Smitch.hayenga@arm.com // Load into temp reg if necessary 12310346Smitch.hayenga@arm.com if (reg_idx2 == INTREG_PC && pc_temp) 12410346Smitch.hayenga@arm.com reg_idx2 = INTREG_UREG1; 12510346Smitch.hayenga@arm.com 12610346Smitch.hayenga@arm.com // Actually load both registers from memory 12710346Smitch.hayenga@arm.com *uop = new MicroLdr2Uop(machInst, reg_idx1, reg_idx2, 12810346Smitch.hayenga@arm.com copy_base ? INTREG_UREG0 : rn, up, addr); 12910346Smitch.hayenga@arm.com 13010346Smitch.hayenga@arm.com if (!writeback && reg_idx2 == INTREG_PC) { 13110346Smitch.hayenga@arm.com // No writeback if idx==pc, set appropriate flags 13210346Smitch.hayenga@arm.com (*uop)->setFlag(StaticInst::IsControl); 13310346Smitch.hayenga@arm.com (*uop)->setFlag(StaticInst::IsIndirectControl); 13410346Smitch.hayenga@arm.com 13510346Smitch.hayenga@arm.com if (!(condCode == COND_AL || condCode == COND_UC)) 13610346Smitch.hayenga@arm.com (*uop)->setFlag(StaticInst::IsCondControl); 13710346Smitch.hayenga@arm.com else 13810346Smitch.hayenga@arm.com (*uop)->setFlag(StaticInst::IsUncondControl); 13910346Smitch.hayenga@arm.com } 14010346Smitch.hayenga@arm.com 14110346Smitch.hayenga@arm.com if (up) addr += 8; 14210346Smitch.hayenga@arm.com else addr -= 8; 14310346Smitch.hayenga@arm.com mem_ops -= 2; 14410346Smitch.hayenga@arm.com } else { 14510346Smitch.hayenga@arm.com // 32-bit memory operation 14610346Smitch.hayenga@arm.com // Find register for operation 14710346Smitch.hayenga@arm.com unsigned reg_idx; 14810346Smitch.hayenga@arm.com while(!bits(regs, reg)) reg++; 14910346Smitch.hayenga@arm.com replaceBits(regs, reg, 0); 15010346Smitch.hayenga@arm.com reg_idx = force_user ? intRegInMode(MODE_USER, reg) : reg; 15110346Smitch.hayenga@arm.com 15210346Smitch.hayenga@arm.com if (load) { 15310346Smitch.hayenga@arm.com if (writeback && reg_idx == INTREG_PC) { 15410346Smitch.hayenga@arm.com // If this instruction changes the PC and performs a 15510346Smitch.hayenga@arm.com // writeback, ensure the pc load/branch is the last uop. 15610346Smitch.hayenga@arm.com // Load into a temp reg here. 15710346Smitch.hayenga@arm.com *uop = new MicroLdrUop(machInst, INTREG_UREG1, 15810346Smitch.hayenga@arm.com copy_base ? INTREG_UREG0 : rn, up, addr); 15910346Smitch.hayenga@arm.com } else if (reg_idx == INTREG_PC && exception_ret) { 16010346Smitch.hayenga@arm.com // Special handling for exception return 16110346Smitch.hayenga@arm.com *uop = new MicroLdrRetUop(machInst, reg_idx, 16210346Smitch.hayenga@arm.com copy_base ? INTREG_UREG0 : rn, up, addr); 16310346Smitch.hayenga@arm.com } else { 16410346Smitch.hayenga@arm.com // standard single load uop 16510346Smitch.hayenga@arm.com *uop = new MicroLdrUop(machInst, reg_idx, 16610346Smitch.hayenga@arm.com copy_base ? INTREG_UREG0 : rn, up, addr); 16710346Smitch.hayenga@arm.com } 16810346Smitch.hayenga@arm.com 16910346Smitch.hayenga@arm.com // Loading pc as last operation? Set appropriate flags. 17010346Smitch.hayenga@arm.com if (!writeback && reg_idx == INTREG_PC) { 17110346Smitch.hayenga@arm.com (*uop)->setFlag(StaticInst::IsControl); 17210346Smitch.hayenga@arm.com (*uop)->setFlag(StaticInst::IsIndirectControl); 17310346Smitch.hayenga@arm.com 1749640Snathanael.premillieu@irisa.fr if (!(condCode == COND_AL || condCode == COND_UC)) 1759640Snathanael.premillieu@irisa.fr (*uop)->setFlag(StaticInst::IsCondControl); 1769640Snathanael.premillieu@irisa.fr else 1779640Snathanael.premillieu@irisa.fr (*uop)->setFlag(StaticInst::IsUncondControl); 1788148SAli.Saidi@ARM.com } 17910346Smitch.hayenga@arm.com } else { 18010346Smitch.hayenga@arm.com *uop = new MicroStrUop(machInst, reg_idx, rn, up, addr); 1817170Sgblack@eecs.umich.edu } 18210346Smitch.hayenga@arm.com 18310346Smitch.hayenga@arm.com if (up) addr += 4; 18410346Smitch.hayenga@arm.com else addr -= 4; 18510346Smitch.hayenga@arm.com --mem_ops; 1867170Sgblack@eecs.umich.edu } 1877170Sgblack@eecs.umich.edu 18810346Smitch.hayenga@arm.com // Load/store micro-op generated, go to next uop 18910346Smitch.hayenga@arm.com ++uop; 1907170Sgblack@eecs.umich.edu } 1917170Sgblack@eecs.umich.edu 1928148SAli.Saidi@ARM.com if (writeback && ones) { 19310346Smitch.hayenga@arm.com // Perform writeback uop operation 1948148SAli.Saidi@ARM.com if (up) 19510346Smitch.hayenga@arm.com *uop++ = new MicroAddiUop(machInst, rn, rn, ones * 4); 1968148SAli.Saidi@ARM.com else 19710346Smitch.hayenga@arm.com *uop++ = new MicroSubiUop(machInst, rn, rn, ones * 4); 1988148SAli.Saidi@ARM.com 19910346Smitch.hayenga@arm.com // Write PC after address writeback? 20010346Smitch.hayenga@arm.com if (pc_temp) { 20110346Smitch.hayenga@arm.com if (exception_ret) { 20210346Smitch.hayenga@arm.com *uop = new MicroUopRegMovRet(machInst, 0, INTREG_UREG1); 20310346Smitch.hayenga@arm.com } else { 20410346Smitch.hayenga@arm.com *uop = new MicroUopRegMov(machInst, INTREG_PC, INTREG_UREG1); 20510346Smitch.hayenga@arm.com } 20610346Smitch.hayenga@arm.com (*uop)->setFlag(StaticInst::IsControl); 20710346Smitch.hayenga@arm.com (*uop)->setFlag(StaticInst::IsIndirectControl); 20810346Smitch.hayenga@arm.com 2099368Snathanael.premillieu@irisa.fr if (!(condCode == COND_AL || condCode == COND_UC)) 2109368Snathanael.premillieu@irisa.fr (*uop)->setFlag(StaticInst::IsCondControl); 2119368Snathanael.premillieu@irisa.fr else 2129368Snathanael.premillieu@irisa.fr (*uop)->setFlag(StaticInst::IsUncondControl); 2138148SAli.Saidi@ARM.com 21410346Smitch.hayenga@arm.com if (rn == INTREG_SP) 21510346Smitch.hayenga@arm.com (*uop)->setFlag(StaticInst::IsReturn); 21610346Smitch.hayenga@arm.com 21710346Smitch.hayenga@arm.com ++uop; 2188148SAli.Saidi@ARM.com } 2197170Sgblack@eecs.umich.edu } 2207190Sgblack@eecs.umich.edu 22110346Smitch.hayenga@arm.com --uop; 2227190Sgblack@eecs.umich.edu (*uop)->setLastMicroop(); 2237343Sgblack@eecs.umich.edu 22410199SAndrew.Bardsley@arm.com /* Take the control flags from the last microop for the macroop */ 22510199SAndrew.Bardsley@arm.com if ((*uop)->isControl()) 22610199SAndrew.Bardsley@arm.com setFlag(StaticInst::IsControl); 22710199SAndrew.Bardsley@arm.com if ((*uop)->isCondCtrl()) 22810199SAndrew.Bardsley@arm.com setFlag(StaticInst::IsCondControl); 22910346Smitch.hayenga@arm.com if ((*uop)->isUncondCtrl()) 23010346Smitch.hayenga@arm.com setFlag(StaticInst::IsUncondControl); 23110199SAndrew.Bardsley@arm.com if ((*uop)->isIndirectCtrl()) 23210199SAndrew.Bardsley@arm.com setFlag(StaticInst::IsIndirectControl); 23310199SAndrew.Bardsley@arm.com if ((*uop)->isReturn()) 23410199SAndrew.Bardsley@arm.com setFlag(StaticInst::IsReturn); 23510199SAndrew.Bardsley@arm.com 23610346Smitch.hayenga@arm.com for (StaticInstPtr *uop = microOps; !(*uop)->isLastMicroop(); uop++) { 23710346Smitch.hayenga@arm.com (*uop)->setDelayedCommit(); 2387343Sgblack@eecs.umich.edu } 2397170Sgblack@eecs.umich.edu} 2407170Sgblack@eecs.umich.edu 24110037SARM gem5 DevelopersPairMemOp::PairMemOp(const char *mnem, ExtMachInst machInst, OpClass __opClass, 24210037SARM gem5 Developers uint32_t size, bool fp, bool load, bool noAlloc, 24310037SARM gem5 Developers bool signExt, bool exclusive, bool acrel, 24410037SARM gem5 Developers int64_t imm, AddrMode mode, 24510037SARM gem5 Developers IntRegIndex rn, IntRegIndex rt, IntRegIndex rt2) : 24610037SARM gem5 Developers PredMacroOp(mnem, machInst, __opClass) 24710037SARM gem5 Developers{ 24810346Smitch.hayenga@arm.com bool post = (mode == AddrMd_PostIndex); 24910037SARM gem5 Developers bool writeback = (mode != AddrMd_Offset); 25010346Smitch.hayenga@arm.com 25110346Smitch.hayenga@arm.com if (load) { 25210346Smitch.hayenga@arm.com // Use integer rounding to round up loads of size 4 25310346Smitch.hayenga@arm.com numMicroops = (post ? 0 : 1) + ((size + 4) / 8) + (writeback ? 1 : 0); 25410346Smitch.hayenga@arm.com } else { 25510346Smitch.hayenga@arm.com numMicroops = (post ? 0 : 1) + (size / 4) + (writeback ? 1 : 0); 25610346Smitch.hayenga@arm.com } 25710037SARM gem5 Developers microOps = new StaticInstPtr[numMicroops]; 25810037SARM gem5 Developers 25910037SARM gem5 Developers StaticInstPtr *uop = microOps; 26010037SARM gem5 Developers 26110037SARM gem5 Developers rn = makeSP(rn); 26210037SARM gem5 Developers 26310346Smitch.hayenga@arm.com if (!post) { 26410346Smitch.hayenga@arm.com *uop++ = new MicroAddXiSpAlignUop(machInst, INTREG_UREG0, rn, 26510346Smitch.hayenga@arm.com post ? 0 : imm); 26610346Smitch.hayenga@arm.com } 26710037SARM gem5 Developers 26810037SARM gem5 Developers if (fp) { 26910037SARM gem5 Developers if (size == 16) { 27010037SARM gem5 Developers if (load) { 27110346Smitch.hayenga@arm.com *uop++ = new MicroLdFp16Uop(machInst, rt, 27210346Smitch.hayenga@arm.com post ? rn : INTREG_UREG0, 0, noAlloc, exclusive, acrel); 27310346Smitch.hayenga@arm.com *uop++ = new MicroLdFp16Uop(machInst, rt2, 27410346Smitch.hayenga@arm.com post ? rn : INTREG_UREG0, 16, noAlloc, exclusive, acrel); 27510037SARM gem5 Developers } else { 27610346Smitch.hayenga@arm.com *uop++ = new MicroStrQBFpXImmUop(machInst, rt, 27710346Smitch.hayenga@arm.com post ? rn : INTREG_UREG0, 0, noAlloc, exclusive, acrel); 27810346Smitch.hayenga@arm.com *uop++ = new MicroStrQTFpXImmUop(machInst, rt, 27910346Smitch.hayenga@arm.com post ? rn : INTREG_UREG0, 0, noAlloc, exclusive, acrel); 28010346Smitch.hayenga@arm.com *uop++ = new MicroStrQBFpXImmUop(machInst, rt2, 28110346Smitch.hayenga@arm.com post ? rn : INTREG_UREG0, 16, noAlloc, exclusive, acrel); 28210346Smitch.hayenga@arm.com *uop++ = new MicroStrQTFpXImmUop(machInst, rt2, 28310346Smitch.hayenga@arm.com post ? rn : INTREG_UREG0, 16, noAlloc, exclusive, acrel); 28410037SARM gem5 Developers } 28510037SARM gem5 Developers } else if (size == 8) { 28610037SARM gem5 Developers if (load) { 28710346Smitch.hayenga@arm.com *uop++ = new MicroLdPairFp8Uop(machInst, rt, rt2, 28810346Smitch.hayenga@arm.com post ? rn : INTREG_UREG0, 0, noAlloc, exclusive, acrel); 28910037SARM gem5 Developers } else { 29010346Smitch.hayenga@arm.com *uop++ = new MicroStrFpXImmUop(machInst, rt, 29110346Smitch.hayenga@arm.com post ? rn : INTREG_UREG0, 0, noAlloc, exclusive, acrel); 29210346Smitch.hayenga@arm.com *uop++ = new MicroStrFpXImmUop(machInst, rt2, 29310346Smitch.hayenga@arm.com post ? rn : INTREG_UREG0, 8, noAlloc, exclusive, acrel); 29410037SARM gem5 Developers } 29510037SARM gem5 Developers } else if (size == 4) { 29610037SARM gem5 Developers if (load) { 29710346Smitch.hayenga@arm.com *uop++ = new MicroLdrDFpXImmUop(machInst, rt, rt2, 29810346Smitch.hayenga@arm.com post ? rn : INTREG_UREG0, 0, noAlloc, exclusive, acrel); 29910037SARM gem5 Developers } else { 30010346Smitch.hayenga@arm.com *uop++ = new MicroStrDFpXImmUop(machInst, rt, rt2, 30110346Smitch.hayenga@arm.com post ? rn : INTREG_UREG0, 0, noAlloc, exclusive, acrel); 30210037SARM gem5 Developers } 30310037SARM gem5 Developers } 30410037SARM gem5 Developers } else { 30510037SARM gem5 Developers if (size == 8) { 30610037SARM gem5 Developers if (load) { 30710346Smitch.hayenga@arm.com *uop++ = new MicroLdPairUop(machInst, rt, rt2, 30810346Smitch.hayenga@arm.com post ? rn : INTREG_UREG0, 0, noAlloc, exclusive, acrel); 30910346Smitch.hayenga@arm.com } else { 31010346Smitch.hayenga@arm.com *uop++ = new MicroStrXImmUop(machInst, rt, post ? rn : INTREG_UREG0, 31110037SARM gem5 Developers 0, noAlloc, exclusive, acrel); 31210346Smitch.hayenga@arm.com *uop++ = new MicroStrXImmUop(machInst, rt2, post ? rn : INTREG_UREG0, 31310037SARM gem5 Developers size, noAlloc, exclusive, acrel); 31410037SARM gem5 Developers } 31510037SARM gem5 Developers } else if (size == 4) { 31610037SARM gem5 Developers if (load) { 31710037SARM gem5 Developers if (signExt) { 31810346Smitch.hayenga@arm.com *uop++ = new MicroLdrDSXImmUop(machInst, rt, rt2, 31910346Smitch.hayenga@arm.com post ? rn : INTREG_UREG0, 0, noAlloc, exclusive, acrel); 32010037SARM gem5 Developers } else { 32110346Smitch.hayenga@arm.com *uop++ = new MicroLdrDUXImmUop(machInst, rt, rt2, 32210346Smitch.hayenga@arm.com post ? rn : INTREG_UREG0, 0, noAlloc, exclusive, acrel); 32310037SARM gem5 Developers } 32410037SARM gem5 Developers } else { 32510346Smitch.hayenga@arm.com *uop++ = new MicroStrDXImmUop(machInst, rt, rt2, 32610346Smitch.hayenga@arm.com post ? rn : INTREG_UREG0, 0, noAlloc, exclusive, acrel); 32710037SARM gem5 Developers } 32810037SARM gem5 Developers } 32910037SARM gem5 Developers } 33010037SARM gem5 Developers 33110037SARM gem5 Developers if (writeback) { 33210346Smitch.hayenga@arm.com *uop++ = new MicroAddXiUop(machInst, rn, post ? rn : INTREG_UREG0, 33310037SARM gem5 Developers post ? imm : 0); 33410037SARM gem5 Developers } 33510037SARM gem5 Developers 33610346Smitch.hayenga@arm.com assert(uop == µOps[numMicroops]); 33710346Smitch.hayenga@arm.com (*--uop)->setLastMicroop(); 33810037SARM gem5 Developers 33910037SARM gem5 Developers for (StaticInstPtr *curUop = microOps; 34010037SARM gem5 Developers !(*curUop)->isLastMicroop(); curUop++) { 34110037SARM gem5 Developers (*curUop)->setDelayedCommit(); 34210037SARM gem5 Developers } 34310037SARM gem5 Developers} 34410037SARM gem5 Developers 34510037SARM gem5 DevelopersBigFpMemImmOp::BigFpMemImmOp(const char *mnem, ExtMachInst machInst, 34610037SARM gem5 Developers OpClass __opClass, bool load, IntRegIndex dest, 34710037SARM gem5 Developers IntRegIndex base, int64_t imm) : 34810037SARM gem5 Developers PredMacroOp(mnem, machInst, __opClass) 34910037SARM gem5 Developers{ 35010346Smitch.hayenga@arm.com numMicroops = load ? 1 : 2; 35110037SARM gem5 Developers microOps = new StaticInstPtr[numMicroops]; 35210037SARM gem5 Developers 35310346Smitch.hayenga@arm.com StaticInstPtr *uop = microOps; 35410346Smitch.hayenga@arm.com 35510037SARM gem5 Developers if (load) { 35610346Smitch.hayenga@arm.com *uop = new MicroLdFp16Uop(machInst, dest, base, imm); 35710037SARM gem5 Developers } else { 35810346Smitch.hayenga@arm.com *uop = new MicroStrQBFpXImmUop(machInst, dest, base, imm); 35910346Smitch.hayenga@arm.com (*uop)->setDelayedCommit(); 36010346Smitch.hayenga@arm.com *++uop = new MicroStrQTFpXImmUop(machInst, dest, base, imm); 36110037SARM gem5 Developers } 36210346Smitch.hayenga@arm.com (*uop)->setLastMicroop(); 36310037SARM gem5 Developers} 36410037SARM gem5 Developers 36510037SARM gem5 DevelopersBigFpMemPostOp::BigFpMemPostOp(const char *mnem, ExtMachInst machInst, 36610037SARM gem5 Developers OpClass __opClass, bool load, IntRegIndex dest, 36710037SARM gem5 Developers IntRegIndex base, int64_t imm) : 36810037SARM gem5 Developers PredMacroOp(mnem, machInst, __opClass) 36910037SARM gem5 Developers{ 37010346Smitch.hayenga@arm.com numMicroops = load ? 2 : 3; 37110037SARM gem5 Developers microOps = new StaticInstPtr[numMicroops]; 37210037SARM gem5 Developers 37310346Smitch.hayenga@arm.com StaticInstPtr *uop = microOps; 37410346Smitch.hayenga@arm.com 37510037SARM gem5 Developers if (load) { 37610346Smitch.hayenga@arm.com *uop++ = new MicroLdFp16Uop(machInst, dest, base, 0); 37710037SARM gem5 Developers } else { 37810346Smitch.hayenga@arm.com *uop++= new MicroStrQBFpXImmUop(machInst, dest, base, 0); 37910346Smitch.hayenga@arm.com *uop++ = new MicroStrQTFpXImmUop(machInst, dest, base, 0); 38010037SARM gem5 Developers } 38110346Smitch.hayenga@arm.com *uop = new MicroAddXiUop(machInst, base, base, imm); 38210346Smitch.hayenga@arm.com (*uop)->setLastMicroop(); 38310037SARM gem5 Developers 38410346Smitch.hayenga@arm.com for (StaticInstPtr *curUop = microOps; 38510346Smitch.hayenga@arm.com !(*curUop)->isLastMicroop(); curUop++) { 38610346Smitch.hayenga@arm.com (*curUop)->setDelayedCommit(); 38710346Smitch.hayenga@arm.com } 38810037SARM gem5 Developers} 38910037SARM gem5 Developers 39010037SARM gem5 DevelopersBigFpMemPreOp::BigFpMemPreOp(const char *mnem, ExtMachInst machInst, 39110037SARM gem5 Developers OpClass __opClass, bool load, IntRegIndex dest, 39210037SARM gem5 Developers IntRegIndex base, int64_t imm) : 39310037SARM gem5 Developers PredMacroOp(mnem, machInst, __opClass) 39410037SARM gem5 Developers{ 39510346Smitch.hayenga@arm.com numMicroops = load ? 2 : 3; 39610037SARM gem5 Developers microOps = new StaticInstPtr[numMicroops]; 39710037SARM gem5 Developers 39810346Smitch.hayenga@arm.com StaticInstPtr *uop = microOps; 39910346Smitch.hayenga@arm.com 40010037SARM gem5 Developers if (load) { 40110346Smitch.hayenga@arm.com *uop++ = new MicroLdFp16Uop(machInst, dest, base, imm); 40210037SARM gem5 Developers } else { 40310346Smitch.hayenga@arm.com *uop++ = new MicroStrQBFpXImmUop(machInst, dest, base, imm); 40410346Smitch.hayenga@arm.com *uop++ = new MicroStrQTFpXImmUop(machInst, dest, base, imm); 40510037SARM gem5 Developers } 40610346Smitch.hayenga@arm.com *uop = new MicroAddXiUop(machInst, base, base, imm); 40710346Smitch.hayenga@arm.com (*uop)->setLastMicroop(); 40810037SARM gem5 Developers 40910346Smitch.hayenga@arm.com for (StaticInstPtr *curUop = microOps; 41010346Smitch.hayenga@arm.com !(*curUop)->isLastMicroop(); curUop++) { 41110346Smitch.hayenga@arm.com (*curUop)->setDelayedCommit(); 41210346Smitch.hayenga@arm.com } 41310037SARM gem5 Developers} 41410037SARM gem5 Developers 41510037SARM gem5 DevelopersBigFpMemRegOp::BigFpMemRegOp(const char *mnem, ExtMachInst machInst, 41610037SARM gem5 Developers OpClass __opClass, bool load, IntRegIndex dest, 41710037SARM gem5 Developers IntRegIndex base, IntRegIndex offset, 41810037SARM gem5 Developers ArmExtendType type, int64_t imm) : 41910037SARM gem5 Developers PredMacroOp(mnem, machInst, __opClass) 42010037SARM gem5 Developers{ 42110346Smitch.hayenga@arm.com numMicroops = load ? 1 : 2; 42210037SARM gem5 Developers microOps = new StaticInstPtr[numMicroops]; 42310037SARM gem5 Developers 42410346Smitch.hayenga@arm.com StaticInstPtr *uop = microOps; 42510346Smitch.hayenga@arm.com 42610037SARM gem5 Developers if (load) { 42710346Smitch.hayenga@arm.com *uop = new MicroLdFp16RegUop(machInst, dest, base, 42810346Smitch.hayenga@arm.com offset, type, imm); 42910037SARM gem5 Developers } else { 43010346Smitch.hayenga@arm.com *uop = new MicroStrQBFpXRegUop(machInst, dest, base, 43110346Smitch.hayenga@arm.com offset, type, imm); 43210346Smitch.hayenga@arm.com (*uop)->setDelayedCommit(); 43310346Smitch.hayenga@arm.com *++uop = new MicroStrQTFpXRegUop(machInst, dest, base, 43410346Smitch.hayenga@arm.com offset, type, imm); 43510037SARM gem5 Developers } 43610037SARM gem5 Developers 43710346Smitch.hayenga@arm.com (*uop)->setLastMicroop(); 43810037SARM gem5 Developers} 43910037SARM gem5 Developers 44010037SARM gem5 DevelopersBigFpMemLitOp::BigFpMemLitOp(const char *mnem, ExtMachInst machInst, 44110037SARM gem5 Developers OpClass __opClass, IntRegIndex dest, 44210037SARM gem5 Developers int64_t imm) : 44310037SARM gem5 Developers PredMacroOp(mnem, machInst, __opClass) 44410037SARM gem5 Developers{ 44510346Smitch.hayenga@arm.com numMicroops = 1; 44610037SARM gem5 Developers microOps = new StaticInstPtr[numMicroops]; 44710037SARM gem5 Developers 44810346Smitch.hayenga@arm.com microOps[0] = new MicroLdFp16LitUop(machInst, dest, imm); 44910346Smitch.hayenga@arm.com microOps[0]->setLastMicroop(); 45010037SARM gem5 Developers} 45110037SARM gem5 Developers 4527639Sgblack@eecs.umich.eduVldMultOp::VldMultOp(const char *mnem, ExtMachInst machInst, OpClass __opClass, 4537639Sgblack@eecs.umich.edu unsigned elems, RegIndex rn, RegIndex vd, unsigned regs, 4547639Sgblack@eecs.umich.edu unsigned inc, uint32_t size, uint32_t align, RegIndex rm) : 4557639Sgblack@eecs.umich.edu PredMacroOp(mnem, machInst, __opClass) 4567639Sgblack@eecs.umich.edu{ 4577639Sgblack@eecs.umich.edu assert(regs > 0 && regs <= 4); 4587639Sgblack@eecs.umich.edu assert(regs % elems == 0); 4597639Sgblack@eecs.umich.edu 4607639Sgblack@eecs.umich.edu numMicroops = (regs > 2) ? 2 : 1; 4617639Sgblack@eecs.umich.edu bool wb = (rm != 15); 4627639Sgblack@eecs.umich.edu bool deinterleave = (elems > 1); 4637639Sgblack@eecs.umich.edu 4647639Sgblack@eecs.umich.edu if (wb) numMicroops++; 4657639Sgblack@eecs.umich.edu if (deinterleave) numMicroops += (regs / elems); 4667639Sgblack@eecs.umich.edu microOps = new StaticInstPtr[numMicroops]; 4677639Sgblack@eecs.umich.edu 46810037SARM gem5 Developers RegIndex rMid = deinterleave ? NumFloatV7ArchRegs : vd * 2; 4697639Sgblack@eecs.umich.edu 4707639Sgblack@eecs.umich.edu uint32_t noAlign = TLB::MustBeOne; 4717639Sgblack@eecs.umich.edu 4727639Sgblack@eecs.umich.edu unsigned uopIdx = 0; 4737639Sgblack@eecs.umich.edu switch (regs) { 4747639Sgblack@eecs.umich.edu case 4: 4757639Sgblack@eecs.umich.edu microOps[uopIdx++] = newNeonMemInst<MicroLdrNeon16Uop>( 4767639Sgblack@eecs.umich.edu size, machInst, rMid, rn, 0, align); 4777639Sgblack@eecs.umich.edu microOps[uopIdx++] = newNeonMemInst<MicroLdrNeon16Uop>( 4787639Sgblack@eecs.umich.edu size, machInst, rMid + 4, rn, 16, noAlign); 4797639Sgblack@eecs.umich.edu break; 4807639Sgblack@eecs.umich.edu case 3: 4817639Sgblack@eecs.umich.edu microOps[uopIdx++] = newNeonMemInst<MicroLdrNeon16Uop>( 4827639Sgblack@eecs.umich.edu size, machInst, rMid, rn, 0, align); 4837639Sgblack@eecs.umich.edu microOps[uopIdx++] = newNeonMemInst<MicroLdrNeon8Uop>( 4847639Sgblack@eecs.umich.edu size, machInst, rMid + 4, rn, 16, noAlign); 4857639Sgblack@eecs.umich.edu break; 4867639Sgblack@eecs.umich.edu case 2: 4877639Sgblack@eecs.umich.edu microOps[uopIdx++] = newNeonMemInst<MicroLdrNeon16Uop>( 4887639Sgblack@eecs.umich.edu size, machInst, rMid, rn, 0, align); 4897639Sgblack@eecs.umich.edu break; 4907639Sgblack@eecs.umich.edu case 1: 4917639Sgblack@eecs.umich.edu microOps[uopIdx++] = newNeonMemInst<MicroLdrNeon8Uop>( 4927639Sgblack@eecs.umich.edu size, machInst, rMid, rn, 0, align); 4937639Sgblack@eecs.umich.edu break; 4947639Sgblack@eecs.umich.edu default: 4957853SMatt.Horsnell@ARM.com // Unknown number of registers 4967853SMatt.Horsnell@ARM.com microOps[uopIdx++] = new Unknown(machInst); 4977639Sgblack@eecs.umich.edu } 4987639Sgblack@eecs.umich.edu if (wb) { 4997639Sgblack@eecs.umich.edu if (rm != 15 && rm != 13) { 5007639Sgblack@eecs.umich.edu microOps[uopIdx++] = 5017646Sgene.wu@arm.com new MicroAddUop(machInst, rn, rn, rm, 0, ArmISA::LSL); 5027639Sgblack@eecs.umich.edu } else { 5037639Sgblack@eecs.umich.edu microOps[uopIdx++] = 5047639Sgblack@eecs.umich.edu new MicroAddiUop(machInst, rn, rn, regs * 8); 5057639Sgblack@eecs.umich.edu } 5067639Sgblack@eecs.umich.edu } 5077639Sgblack@eecs.umich.edu if (deinterleave) { 5087639Sgblack@eecs.umich.edu switch (elems) { 5097639Sgblack@eecs.umich.edu case 4: 5107639Sgblack@eecs.umich.edu assert(regs == 4); 5117639Sgblack@eecs.umich.edu microOps[uopIdx++] = newNeonMixInst<MicroDeintNeon8Uop>( 5127639Sgblack@eecs.umich.edu size, machInst, vd * 2, rMid, inc * 2); 5137639Sgblack@eecs.umich.edu break; 5147639Sgblack@eecs.umich.edu case 3: 5157639Sgblack@eecs.umich.edu assert(regs == 3); 5167639Sgblack@eecs.umich.edu microOps[uopIdx++] = newNeonMixInst<MicroDeintNeon6Uop>( 5177639Sgblack@eecs.umich.edu size, machInst, vd * 2, rMid, inc * 2); 5187639Sgblack@eecs.umich.edu break; 5197639Sgblack@eecs.umich.edu case 2: 5207639Sgblack@eecs.umich.edu assert(regs == 4 || regs == 2); 5217639Sgblack@eecs.umich.edu if (regs == 4) { 5227639Sgblack@eecs.umich.edu microOps[uopIdx++] = newNeonMixInst<MicroDeintNeon4Uop>( 5237639Sgblack@eecs.umich.edu size, machInst, vd * 2, rMid, inc * 2); 5247639Sgblack@eecs.umich.edu microOps[uopIdx++] = newNeonMixInst<MicroDeintNeon4Uop>( 5257639Sgblack@eecs.umich.edu size, machInst, vd * 2 + 2, rMid + 4, inc * 2); 5267639Sgblack@eecs.umich.edu } else { 5277639Sgblack@eecs.umich.edu microOps[uopIdx++] = newNeonMixInst<MicroDeintNeon4Uop>( 5287639Sgblack@eecs.umich.edu size, machInst, vd * 2, rMid, inc * 2); 5297639Sgblack@eecs.umich.edu } 5307639Sgblack@eecs.umich.edu break; 5317639Sgblack@eecs.umich.edu default: 5327853SMatt.Horsnell@ARM.com // Bad number of elements to deinterleave 5337853SMatt.Horsnell@ARM.com microOps[uopIdx++] = new Unknown(machInst); 5347639Sgblack@eecs.umich.edu } 5357639Sgblack@eecs.umich.edu } 5367639Sgblack@eecs.umich.edu assert(uopIdx == numMicroops); 5377639Sgblack@eecs.umich.edu 5387639Sgblack@eecs.umich.edu for (unsigned i = 0; i < numMicroops - 1; i++) { 5397639Sgblack@eecs.umich.edu MicroOp * uopPtr = dynamic_cast<MicroOp *>(microOps[i].get()); 5407639Sgblack@eecs.umich.edu assert(uopPtr); 5417639Sgblack@eecs.umich.edu uopPtr->setDelayedCommit(); 5427639Sgblack@eecs.umich.edu } 5437639Sgblack@eecs.umich.edu microOps[numMicroops - 1]->setLastMicroop(); 5447639Sgblack@eecs.umich.edu} 5457639Sgblack@eecs.umich.edu 5467639Sgblack@eecs.umich.eduVldSingleOp::VldSingleOp(const char *mnem, ExtMachInst machInst, 5477639Sgblack@eecs.umich.edu OpClass __opClass, bool all, unsigned elems, 5487639Sgblack@eecs.umich.edu RegIndex rn, RegIndex vd, unsigned regs, 5497639Sgblack@eecs.umich.edu unsigned inc, uint32_t size, uint32_t align, 5507639Sgblack@eecs.umich.edu RegIndex rm, unsigned lane) : 5517639Sgblack@eecs.umich.edu PredMacroOp(mnem, machInst, __opClass) 5527639Sgblack@eecs.umich.edu{ 5537639Sgblack@eecs.umich.edu assert(regs > 0 && regs <= 4); 5547639Sgblack@eecs.umich.edu assert(regs % elems == 0); 5557639Sgblack@eecs.umich.edu 5567639Sgblack@eecs.umich.edu unsigned eBytes = (1 << size); 5577639Sgblack@eecs.umich.edu unsigned loadSize = eBytes * elems; 5587639Sgblack@eecs.umich.edu unsigned loadRegs M5_VAR_USED = (loadSize + sizeof(FloatRegBits) - 1) / 5597639Sgblack@eecs.umich.edu sizeof(FloatRegBits); 5607639Sgblack@eecs.umich.edu 5617639Sgblack@eecs.umich.edu assert(loadRegs > 0 && loadRegs <= 4); 5627639Sgblack@eecs.umich.edu 5637639Sgblack@eecs.umich.edu numMicroops = 1; 5647639Sgblack@eecs.umich.edu bool wb = (rm != 15); 5657639Sgblack@eecs.umich.edu 5667639Sgblack@eecs.umich.edu if (wb) numMicroops++; 5677639Sgblack@eecs.umich.edu numMicroops += (regs / elems); 5687639Sgblack@eecs.umich.edu microOps = new StaticInstPtr[numMicroops]; 5697639Sgblack@eecs.umich.edu 57010037SARM gem5 Developers RegIndex ufp0 = NumFloatV7ArchRegs; 5717639Sgblack@eecs.umich.edu 5727639Sgblack@eecs.umich.edu unsigned uopIdx = 0; 5737639Sgblack@eecs.umich.edu switch (loadSize) { 5747639Sgblack@eecs.umich.edu case 1: 5757639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroLdrNeon1Uop<uint8_t>( 5767639Sgblack@eecs.umich.edu machInst, ufp0, rn, 0, align); 5777639Sgblack@eecs.umich.edu break; 5787639Sgblack@eecs.umich.edu case 2: 5797639Sgblack@eecs.umich.edu if (eBytes == 2) { 5807639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroLdrNeon2Uop<uint16_t>( 5817639Sgblack@eecs.umich.edu machInst, ufp0, rn, 0, align); 5827639Sgblack@eecs.umich.edu } else { 5837639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroLdrNeon2Uop<uint8_t>( 5847639Sgblack@eecs.umich.edu machInst, ufp0, rn, 0, align); 5857639Sgblack@eecs.umich.edu } 5867639Sgblack@eecs.umich.edu break; 5877639Sgblack@eecs.umich.edu case 3: 5887639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroLdrNeon3Uop<uint8_t>( 5897639Sgblack@eecs.umich.edu machInst, ufp0, rn, 0, align); 5907639Sgblack@eecs.umich.edu break; 5917639Sgblack@eecs.umich.edu case 4: 5927639Sgblack@eecs.umich.edu switch (eBytes) { 5937639Sgblack@eecs.umich.edu case 1: 5947639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroLdrNeon4Uop<uint8_t>( 5957639Sgblack@eecs.umich.edu machInst, ufp0, rn, 0, align); 5967639Sgblack@eecs.umich.edu break; 5977639Sgblack@eecs.umich.edu case 2: 5987639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroLdrNeon4Uop<uint16_t>( 5997639Sgblack@eecs.umich.edu machInst, ufp0, rn, 0, align); 6007639Sgblack@eecs.umich.edu break; 6017639Sgblack@eecs.umich.edu case 4: 6027639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroLdrNeon4Uop<uint32_t>( 6037639Sgblack@eecs.umich.edu machInst, ufp0, rn, 0, align); 6047639Sgblack@eecs.umich.edu break; 6057639Sgblack@eecs.umich.edu } 6067639Sgblack@eecs.umich.edu break; 6077639Sgblack@eecs.umich.edu case 6: 6087639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroLdrNeon6Uop<uint16_t>( 6097639Sgblack@eecs.umich.edu machInst, ufp0, rn, 0, align); 6107639Sgblack@eecs.umich.edu break; 6117639Sgblack@eecs.umich.edu case 8: 6127639Sgblack@eecs.umich.edu switch (eBytes) { 6137639Sgblack@eecs.umich.edu case 2: 6147639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroLdrNeon8Uop<uint16_t>( 6157639Sgblack@eecs.umich.edu machInst, ufp0, rn, 0, align); 6167639Sgblack@eecs.umich.edu break; 6177639Sgblack@eecs.umich.edu case 4: 6187639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroLdrNeon8Uop<uint32_t>( 6197639Sgblack@eecs.umich.edu machInst, ufp0, rn, 0, align); 6207639Sgblack@eecs.umich.edu break; 6217639Sgblack@eecs.umich.edu } 6227639Sgblack@eecs.umich.edu break; 6237639Sgblack@eecs.umich.edu case 12: 6247639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroLdrNeon12Uop<uint32_t>( 6257639Sgblack@eecs.umich.edu machInst, ufp0, rn, 0, align); 6267639Sgblack@eecs.umich.edu break; 6277639Sgblack@eecs.umich.edu case 16: 6287639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroLdrNeon16Uop<uint32_t>( 6297639Sgblack@eecs.umich.edu machInst, ufp0, rn, 0, align); 6307639Sgblack@eecs.umich.edu break; 6317639Sgblack@eecs.umich.edu default: 6327853SMatt.Horsnell@ARM.com // Unrecognized load size 6337853SMatt.Horsnell@ARM.com microOps[uopIdx++] = new Unknown(machInst); 6347639Sgblack@eecs.umich.edu } 6357639Sgblack@eecs.umich.edu if (wb) { 6367639Sgblack@eecs.umich.edu if (rm != 15 && rm != 13) { 6377639Sgblack@eecs.umich.edu microOps[uopIdx++] = 6387646Sgene.wu@arm.com new MicroAddUop(machInst, rn, rn, rm, 0, ArmISA::LSL); 6397639Sgblack@eecs.umich.edu } else { 6407639Sgblack@eecs.umich.edu microOps[uopIdx++] = 6417639Sgblack@eecs.umich.edu new MicroAddiUop(machInst, rn, rn, loadSize); 6427639Sgblack@eecs.umich.edu } 6437639Sgblack@eecs.umich.edu } 6447639Sgblack@eecs.umich.edu switch (elems) { 6457639Sgblack@eecs.umich.edu case 4: 6467639Sgblack@eecs.umich.edu assert(regs == 4); 6477639Sgblack@eecs.umich.edu switch (size) { 6487639Sgblack@eecs.umich.edu case 0: 6497639Sgblack@eecs.umich.edu if (all) { 6507639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroUnpackAllNeon2to8Uop<uint8_t>( 6517639Sgblack@eecs.umich.edu machInst, vd * 2, ufp0, inc * 2); 6527639Sgblack@eecs.umich.edu } else { 6537639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroUnpackNeon2to8Uop<uint8_t>( 6547639Sgblack@eecs.umich.edu machInst, vd * 2, ufp0, inc * 2, lane); 6557639Sgblack@eecs.umich.edu } 6567639Sgblack@eecs.umich.edu break; 6577639Sgblack@eecs.umich.edu case 1: 6587639Sgblack@eecs.umich.edu if (all) { 6597639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroUnpackAllNeon2to8Uop<uint16_t>( 6607639Sgblack@eecs.umich.edu machInst, vd * 2, ufp0, inc * 2); 6617639Sgblack@eecs.umich.edu } else { 6627639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroUnpackNeon2to8Uop<uint16_t>( 6637639Sgblack@eecs.umich.edu machInst, vd * 2, ufp0, inc * 2, lane); 6647639Sgblack@eecs.umich.edu } 6657639Sgblack@eecs.umich.edu break; 6667639Sgblack@eecs.umich.edu case 2: 6677639Sgblack@eecs.umich.edu if (all) { 6687639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroUnpackAllNeon4to8Uop<uint32_t>( 6697639Sgblack@eecs.umich.edu machInst, vd * 2, ufp0, inc * 2); 6707639Sgblack@eecs.umich.edu } else { 6717639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroUnpackNeon4to8Uop<uint32_t>( 6727639Sgblack@eecs.umich.edu machInst, vd * 2, ufp0, inc * 2, lane); 6737639Sgblack@eecs.umich.edu } 6747639Sgblack@eecs.umich.edu break; 6757639Sgblack@eecs.umich.edu default: 6767853SMatt.Horsnell@ARM.com // Bad size 6777853SMatt.Horsnell@ARM.com microOps[uopIdx++] = new Unknown(machInst); 6787639Sgblack@eecs.umich.edu break; 6797639Sgblack@eecs.umich.edu } 6807639Sgblack@eecs.umich.edu break; 6817639Sgblack@eecs.umich.edu case 3: 6827639Sgblack@eecs.umich.edu assert(regs == 3); 6837639Sgblack@eecs.umich.edu switch (size) { 6847639Sgblack@eecs.umich.edu case 0: 6857639Sgblack@eecs.umich.edu if (all) { 6867639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroUnpackAllNeon2to6Uop<uint8_t>( 6877639Sgblack@eecs.umich.edu machInst, vd * 2, ufp0, inc * 2); 6887639Sgblack@eecs.umich.edu } else { 6897639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroUnpackNeon2to6Uop<uint8_t>( 6907639Sgblack@eecs.umich.edu machInst, vd * 2, ufp0, inc * 2, lane); 6917639Sgblack@eecs.umich.edu } 6927639Sgblack@eecs.umich.edu break; 6937639Sgblack@eecs.umich.edu case 1: 6947639Sgblack@eecs.umich.edu if (all) { 6957639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroUnpackAllNeon2to6Uop<uint16_t>( 6967639Sgblack@eecs.umich.edu machInst, vd * 2, ufp0, inc * 2); 6977639Sgblack@eecs.umich.edu } else { 6987639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroUnpackNeon2to6Uop<uint16_t>( 6997639Sgblack@eecs.umich.edu machInst, vd * 2, ufp0, inc * 2, lane); 7007639Sgblack@eecs.umich.edu } 7017639Sgblack@eecs.umich.edu break; 7027639Sgblack@eecs.umich.edu case 2: 7037639Sgblack@eecs.umich.edu if (all) { 7047639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroUnpackAllNeon4to6Uop<uint32_t>( 7057639Sgblack@eecs.umich.edu machInst, vd * 2, ufp0, inc * 2); 7067639Sgblack@eecs.umich.edu } else { 7077639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroUnpackNeon4to6Uop<uint32_t>( 7087639Sgblack@eecs.umich.edu machInst, vd * 2, ufp0, inc * 2, lane); 7097639Sgblack@eecs.umich.edu } 7107639Sgblack@eecs.umich.edu break; 7117639Sgblack@eecs.umich.edu default: 7127853SMatt.Horsnell@ARM.com // Bad size 7137853SMatt.Horsnell@ARM.com microOps[uopIdx++] = new Unknown(machInst); 7147639Sgblack@eecs.umich.edu break; 7157639Sgblack@eecs.umich.edu } 7167639Sgblack@eecs.umich.edu break; 7177639Sgblack@eecs.umich.edu case 2: 7187639Sgblack@eecs.umich.edu assert(regs == 2); 7197639Sgblack@eecs.umich.edu assert(loadRegs <= 2); 7207639Sgblack@eecs.umich.edu switch (size) { 7217639Sgblack@eecs.umich.edu case 0: 7227639Sgblack@eecs.umich.edu if (all) { 7237639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroUnpackAllNeon2to4Uop<uint8_t>( 7247639Sgblack@eecs.umich.edu machInst, vd * 2, ufp0, inc * 2); 7257639Sgblack@eecs.umich.edu } else { 7267639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroUnpackNeon2to4Uop<uint8_t>( 7277639Sgblack@eecs.umich.edu machInst, vd * 2, ufp0, inc * 2, lane); 7287639Sgblack@eecs.umich.edu } 7297639Sgblack@eecs.umich.edu break; 7307639Sgblack@eecs.umich.edu case 1: 7317639Sgblack@eecs.umich.edu if (all) { 7327639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroUnpackAllNeon2to4Uop<uint16_t>( 7337639Sgblack@eecs.umich.edu machInst, vd * 2, ufp0, inc * 2); 7347639Sgblack@eecs.umich.edu } else { 7357639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroUnpackNeon2to4Uop<uint16_t>( 7367639Sgblack@eecs.umich.edu machInst, vd * 2, ufp0, inc * 2, lane); 7377639Sgblack@eecs.umich.edu } 7387639Sgblack@eecs.umich.edu break; 7397639Sgblack@eecs.umich.edu case 2: 7407639Sgblack@eecs.umich.edu if (all) { 7417639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroUnpackAllNeon2to4Uop<uint32_t>( 7427639Sgblack@eecs.umich.edu machInst, vd * 2, ufp0, inc * 2); 7437639Sgblack@eecs.umich.edu } else { 7447639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroUnpackNeon2to4Uop<uint32_t>( 7457639Sgblack@eecs.umich.edu machInst, vd * 2, ufp0, inc * 2, lane); 7467639Sgblack@eecs.umich.edu } 7477639Sgblack@eecs.umich.edu break; 7487639Sgblack@eecs.umich.edu default: 7497853SMatt.Horsnell@ARM.com // Bad size 7507853SMatt.Horsnell@ARM.com microOps[uopIdx++] = new Unknown(machInst); 7517639Sgblack@eecs.umich.edu break; 7527639Sgblack@eecs.umich.edu } 7537639Sgblack@eecs.umich.edu break; 7547639Sgblack@eecs.umich.edu case 1: 7557639Sgblack@eecs.umich.edu assert(regs == 1 || (all && regs == 2)); 7567639Sgblack@eecs.umich.edu assert(loadRegs <= 2); 7577639Sgblack@eecs.umich.edu for (unsigned offset = 0; offset < regs; offset++) { 7587639Sgblack@eecs.umich.edu switch (size) { 7597639Sgblack@eecs.umich.edu case 0: 7607639Sgblack@eecs.umich.edu if (all) { 7617639Sgblack@eecs.umich.edu microOps[uopIdx++] = 7627639Sgblack@eecs.umich.edu new MicroUnpackAllNeon2to2Uop<uint8_t>( 7637639Sgblack@eecs.umich.edu machInst, (vd + offset) * 2, ufp0, inc * 2); 7647639Sgblack@eecs.umich.edu } else { 7657639Sgblack@eecs.umich.edu microOps[uopIdx++] = 7667639Sgblack@eecs.umich.edu new MicroUnpackNeon2to2Uop<uint8_t>( 7677639Sgblack@eecs.umich.edu machInst, (vd + offset) * 2, ufp0, inc * 2, lane); 7687639Sgblack@eecs.umich.edu } 7697639Sgblack@eecs.umich.edu break; 7707639Sgblack@eecs.umich.edu case 1: 7717639Sgblack@eecs.umich.edu if (all) { 7727639Sgblack@eecs.umich.edu microOps[uopIdx++] = 7737639Sgblack@eecs.umich.edu new MicroUnpackAllNeon2to2Uop<uint16_t>( 7747639Sgblack@eecs.umich.edu machInst, (vd + offset) * 2, ufp0, inc * 2); 7757639Sgblack@eecs.umich.edu } else { 7767639Sgblack@eecs.umich.edu microOps[uopIdx++] = 7777639Sgblack@eecs.umich.edu new MicroUnpackNeon2to2Uop<uint16_t>( 7787639Sgblack@eecs.umich.edu machInst, (vd + offset) * 2, ufp0, inc * 2, lane); 7797639Sgblack@eecs.umich.edu } 7807639Sgblack@eecs.umich.edu break; 7817639Sgblack@eecs.umich.edu case 2: 7827639Sgblack@eecs.umich.edu if (all) { 7837639Sgblack@eecs.umich.edu microOps[uopIdx++] = 7847639Sgblack@eecs.umich.edu new MicroUnpackAllNeon2to2Uop<uint32_t>( 7857639Sgblack@eecs.umich.edu machInst, (vd + offset) * 2, ufp0, inc * 2); 7867639Sgblack@eecs.umich.edu } else { 7877639Sgblack@eecs.umich.edu microOps[uopIdx++] = 7887639Sgblack@eecs.umich.edu new MicroUnpackNeon2to2Uop<uint32_t>( 7897639Sgblack@eecs.umich.edu machInst, (vd + offset) * 2, ufp0, inc * 2, lane); 7907639Sgblack@eecs.umich.edu } 7917639Sgblack@eecs.umich.edu break; 7927639Sgblack@eecs.umich.edu default: 7937853SMatt.Horsnell@ARM.com // Bad size 7947853SMatt.Horsnell@ARM.com microOps[uopIdx++] = new Unknown(machInst); 7957639Sgblack@eecs.umich.edu break; 7967639Sgblack@eecs.umich.edu } 7977639Sgblack@eecs.umich.edu } 7987639Sgblack@eecs.umich.edu break; 7997639Sgblack@eecs.umich.edu default: 8007853SMatt.Horsnell@ARM.com // Bad number of elements to unpack 8017853SMatt.Horsnell@ARM.com microOps[uopIdx++] = new Unknown(machInst); 8027639Sgblack@eecs.umich.edu } 8037639Sgblack@eecs.umich.edu assert(uopIdx == numMicroops); 8047639Sgblack@eecs.umich.edu 8057639Sgblack@eecs.umich.edu for (unsigned i = 0; i < numMicroops - 1; i++) { 8067639Sgblack@eecs.umich.edu MicroOp * uopPtr = dynamic_cast<MicroOp *>(microOps[i].get()); 8077639Sgblack@eecs.umich.edu assert(uopPtr); 8087639Sgblack@eecs.umich.edu uopPtr->setDelayedCommit(); 8097639Sgblack@eecs.umich.edu } 8107639Sgblack@eecs.umich.edu microOps[numMicroops - 1]->setLastMicroop(); 8117639Sgblack@eecs.umich.edu} 8127639Sgblack@eecs.umich.edu 8137639Sgblack@eecs.umich.eduVstMultOp::VstMultOp(const char *mnem, ExtMachInst machInst, OpClass __opClass, 8147639Sgblack@eecs.umich.edu unsigned elems, RegIndex rn, RegIndex vd, unsigned regs, 8157639Sgblack@eecs.umich.edu unsigned inc, uint32_t size, uint32_t align, RegIndex rm) : 8167639Sgblack@eecs.umich.edu PredMacroOp(mnem, machInst, __opClass) 8177639Sgblack@eecs.umich.edu{ 8187639Sgblack@eecs.umich.edu assert(regs > 0 && regs <= 4); 8197639Sgblack@eecs.umich.edu assert(regs % elems == 0); 8207639Sgblack@eecs.umich.edu 8217639Sgblack@eecs.umich.edu numMicroops = (regs > 2) ? 2 : 1; 8227639Sgblack@eecs.umich.edu bool wb = (rm != 15); 8237639Sgblack@eecs.umich.edu bool interleave = (elems > 1); 8247639Sgblack@eecs.umich.edu 8257639Sgblack@eecs.umich.edu if (wb) numMicroops++; 8267639Sgblack@eecs.umich.edu if (interleave) numMicroops += (regs / elems); 8277639Sgblack@eecs.umich.edu microOps = new StaticInstPtr[numMicroops]; 8287639Sgblack@eecs.umich.edu 8297639Sgblack@eecs.umich.edu uint32_t noAlign = TLB::MustBeOne; 8307639Sgblack@eecs.umich.edu 83110037SARM gem5 Developers RegIndex rMid = interleave ? NumFloatV7ArchRegs : vd * 2; 8327639Sgblack@eecs.umich.edu 8337639Sgblack@eecs.umich.edu unsigned uopIdx = 0; 8347639Sgblack@eecs.umich.edu if (interleave) { 8357639Sgblack@eecs.umich.edu switch (elems) { 8367639Sgblack@eecs.umich.edu case 4: 8377639Sgblack@eecs.umich.edu assert(regs == 4); 8387639Sgblack@eecs.umich.edu microOps[uopIdx++] = newNeonMixInst<MicroInterNeon8Uop>( 8397639Sgblack@eecs.umich.edu size, machInst, rMid, vd * 2, inc * 2); 8407639Sgblack@eecs.umich.edu break; 8417639Sgblack@eecs.umich.edu case 3: 8427639Sgblack@eecs.umich.edu assert(regs == 3); 8437639Sgblack@eecs.umich.edu microOps[uopIdx++] = newNeonMixInst<MicroInterNeon6Uop>( 8447639Sgblack@eecs.umich.edu size, machInst, rMid, vd * 2, inc * 2); 8457639Sgblack@eecs.umich.edu break; 8467639Sgblack@eecs.umich.edu case 2: 8477639Sgblack@eecs.umich.edu assert(regs == 4 || regs == 2); 8487639Sgblack@eecs.umich.edu if (regs == 4) { 8497639Sgblack@eecs.umich.edu microOps[uopIdx++] = newNeonMixInst<MicroInterNeon4Uop>( 8507639Sgblack@eecs.umich.edu size, machInst, rMid, vd * 2, inc * 2); 8517639Sgblack@eecs.umich.edu microOps[uopIdx++] = newNeonMixInst<MicroInterNeon4Uop>( 8527639Sgblack@eecs.umich.edu size, machInst, rMid + 4, vd * 2 + 2, inc * 2); 8537639Sgblack@eecs.umich.edu } else { 8547639Sgblack@eecs.umich.edu microOps[uopIdx++] = newNeonMixInst<MicroInterNeon4Uop>( 8557639Sgblack@eecs.umich.edu size, machInst, rMid, vd * 2, inc * 2); 8567639Sgblack@eecs.umich.edu } 8577639Sgblack@eecs.umich.edu break; 8587639Sgblack@eecs.umich.edu default: 8597853SMatt.Horsnell@ARM.com // Bad number of elements to interleave 8607853SMatt.Horsnell@ARM.com microOps[uopIdx++] = new Unknown(machInst); 8617639Sgblack@eecs.umich.edu } 8627639Sgblack@eecs.umich.edu } 8637639Sgblack@eecs.umich.edu switch (regs) { 8647639Sgblack@eecs.umich.edu case 4: 8657639Sgblack@eecs.umich.edu microOps[uopIdx++] = newNeonMemInst<MicroStrNeon16Uop>( 8667639Sgblack@eecs.umich.edu size, machInst, rMid, rn, 0, align); 8677639Sgblack@eecs.umich.edu microOps[uopIdx++] = newNeonMemInst<MicroStrNeon16Uop>( 8687639Sgblack@eecs.umich.edu size, machInst, rMid + 4, rn, 16, noAlign); 8697639Sgblack@eecs.umich.edu break; 8707639Sgblack@eecs.umich.edu case 3: 8717639Sgblack@eecs.umich.edu microOps[uopIdx++] = newNeonMemInst<MicroStrNeon16Uop>( 8727639Sgblack@eecs.umich.edu size, machInst, rMid, rn, 0, align); 8737639Sgblack@eecs.umich.edu microOps[uopIdx++] = newNeonMemInst<MicroStrNeon8Uop>( 8747639Sgblack@eecs.umich.edu size, machInst, rMid + 4, rn, 16, noAlign); 8757639Sgblack@eecs.umich.edu break; 8767639Sgblack@eecs.umich.edu case 2: 8777639Sgblack@eecs.umich.edu microOps[uopIdx++] = newNeonMemInst<MicroStrNeon16Uop>( 8787639Sgblack@eecs.umich.edu size, machInst, rMid, rn, 0, align); 8797639Sgblack@eecs.umich.edu break; 8807639Sgblack@eecs.umich.edu case 1: 8817639Sgblack@eecs.umich.edu microOps[uopIdx++] = newNeonMemInst<MicroStrNeon8Uop>( 8827639Sgblack@eecs.umich.edu size, machInst, rMid, rn, 0, align); 8837639Sgblack@eecs.umich.edu break; 8847639Sgblack@eecs.umich.edu default: 8857853SMatt.Horsnell@ARM.com // Unknown number of registers 8867853SMatt.Horsnell@ARM.com microOps[uopIdx++] = new Unknown(machInst); 8877639Sgblack@eecs.umich.edu } 8887639Sgblack@eecs.umich.edu if (wb) { 8897639Sgblack@eecs.umich.edu if (rm != 15 && rm != 13) { 8907639Sgblack@eecs.umich.edu microOps[uopIdx++] = 8917646Sgene.wu@arm.com new MicroAddUop(machInst, rn, rn, rm, 0, ArmISA::LSL); 8927639Sgblack@eecs.umich.edu } else { 8937639Sgblack@eecs.umich.edu microOps[uopIdx++] = 8947639Sgblack@eecs.umich.edu new MicroAddiUop(machInst, rn, rn, regs * 8); 8957639Sgblack@eecs.umich.edu } 8967639Sgblack@eecs.umich.edu } 8977639Sgblack@eecs.umich.edu assert(uopIdx == numMicroops); 8987639Sgblack@eecs.umich.edu 8997639Sgblack@eecs.umich.edu for (unsigned i = 0; i < numMicroops - 1; i++) { 9007639Sgblack@eecs.umich.edu MicroOp * uopPtr = dynamic_cast<MicroOp *>(microOps[i].get()); 9017639Sgblack@eecs.umich.edu assert(uopPtr); 9027639Sgblack@eecs.umich.edu uopPtr->setDelayedCommit(); 9037639Sgblack@eecs.umich.edu } 9047639Sgblack@eecs.umich.edu microOps[numMicroops - 1]->setLastMicroop(); 9057639Sgblack@eecs.umich.edu} 9067639Sgblack@eecs.umich.edu 9077639Sgblack@eecs.umich.eduVstSingleOp::VstSingleOp(const char *mnem, ExtMachInst machInst, 9087639Sgblack@eecs.umich.edu OpClass __opClass, bool all, unsigned elems, 9097639Sgblack@eecs.umich.edu RegIndex rn, RegIndex vd, unsigned regs, 9107639Sgblack@eecs.umich.edu unsigned inc, uint32_t size, uint32_t align, 9117639Sgblack@eecs.umich.edu RegIndex rm, unsigned lane) : 9127639Sgblack@eecs.umich.edu PredMacroOp(mnem, machInst, __opClass) 9137639Sgblack@eecs.umich.edu{ 9147639Sgblack@eecs.umich.edu assert(!all); 9157639Sgblack@eecs.umich.edu assert(regs > 0 && regs <= 4); 9167639Sgblack@eecs.umich.edu assert(regs % elems == 0); 9177639Sgblack@eecs.umich.edu 9187639Sgblack@eecs.umich.edu unsigned eBytes = (1 << size); 9197639Sgblack@eecs.umich.edu unsigned storeSize = eBytes * elems; 9207639Sgblack@eecs.umich.edu unsigned storeRegs M5_VAR_USED = (storeSize + sizeof(FloatRegBits) - 1) / 9217639Sgblack@eecs.umich.edu sizeof(FloatRegBits); 9227639Sgblack@eecs.umich.edu 9237639Sgblack@eecs.umich.edu assert(storeRegs > 0 && storeRegs <= 4); 9247639Sgblack@eecs.umich.edu 9257639Sgblack@eecs.umich.edu numMicroops = 1; 9267639Sgblack@eecs.umich.edu bool wb = (rm != 15); 9277639Sgblack@eecs.umich.edu 9287639Sgblack@eecs.umich.edu if (wb) numMicroops++; 9297639Sgblack@eecs.umich.edu numMicroops += (regs / elems); 9307639Sgblack@eecs.umich.edu microOps = new StaticInstPtr[numMicroops]; 9317639Sgblack@eecs.umich.edu 93210037SARM gem5 Developers RegIndex ufp0 = NumFloatV7ArchRegs; 9337639Sgblack@eecs.umich.edu 9347639Sgblack@eecs.umich.edu unsigned uopIdx = 0; 9357639Sgblack@eecs.umich.edu switch (elems) { 9367639Sgblack@eecs.umich.edu case 4: 9377639Sgblack@eecs.umich.edu assert(regs == 4); 9387639Sgblack@eecs.umich.edu switch (size) { 9397639Sgblack@eecs.umich.edu case 0: 9407639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroPackNeon8to2Uop<uint8_t>( 9417639Sgblack@eecs.umich.edu machInst, ufp0, vd * 2, inc * 2, lane); 9427639Sgblack@eecs.umich.edu break; 9437639Sgblack@eecs.umich.edu case 1: 9447639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroPackNeon8to2Uop<uint16_t>( 9457639Sgblack@eecs.umich.edu machInst, ufp0, vd * 2, inc * 2, lane); 9467639Sgblack@eecs.umich.edu break; 9477639Sgblack@eecs.umich.edu case 2: 9487639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroPackNeon8to4Uop<uint32_t>( 9497639Sgblack@eecs.umich.edu machInst, ufp0, vd * 2, inc * 2, lane); 9507639Sgblack@eecs.umich.edu break; 9517639Sgblack@eecs.umich.edu default: 9527853SMatt.Horsnell@ARM.com // Bad size 9537853SMatt.Horsnell@ARM.com microOps[uopIdx++] = new Unknown(machInst); 9547639Sgblack@eecs.umich.edu break; 9557639Sgblack@eecs.umich.edu } 9567639Sgblack@eecs.umich.edu break; 9577639Sgblack@eecs.umich.edu case 3: 9587639Sgblack@eecs.umich.edu assert(regs == 3); 9597639Sgblack@eecs.umich.edu switch (size) { 9607639Sgblack@eecs.umich.edu case 0: 9617639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroPackNeon6to2Uop<uint8_t>( 9627639Sgblack@eecs.umich.edu machInst, ufp0, vd * 2, inc * 2, lane); 9637639Sgblack@eecs.umich.edu break; 9647639Sgblack@eecs.umich.edu case 1: 9657639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroPackNeon6to2Uop<uint16_t>( 9667639Sgblack@eecs.umich.edu machInst, ufp0, vd * 2, inc * 2, lane); 9677639Sgblack@eecs.umich.edu break; 9687639Sgblack@eecs.umich.edu case 2: 9697639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroPackNeon6to4Uop<uint32_t>( 9707639Sgblack@eecs.umich.edu machInst, ufp0, vd * 2, inc * 2, lane); 9717639Sgblack@eecs.umich.edu break; 9727639Sgblack@eecs.umich.edu default: 9737853SMatt.Horsnell@ARM.com // Bad size 9747853SMatt.Horsnell@ARM.com microOps[uopIdx++] = new Unknown(machInst); 9757639Sgblack@eecs.umich.edu break; 9767639Sgblack@eecs.umich.edu } 9777639Sgblack@eecs.umich.edu break; 9787639Sgblack@eecs.umich.edu case 2: 9797639Sgblack@eecs.umich.edu assert(regs == 2); 9807639Sgblack@eecs.umich.edu assert(storeRegs <= 2); 9817639Sgblack@eecs.umich.edu switch (size) { 9827639Sgblack@eecs.umich.edu case 0: 9837639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroPackNeon4to2Uop<uint8_t>( 9847639Sgblack@eecs.umich.edu machInst, ufp0, vd * 2, inc * 2, lane); 9857639Sgblack@eecs.umich.edu break; 9867639Sgblack@eecs.umich.edu case 1: 9877639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroPackNeon4to2Uop<uint16_t>( 9887639Sgblack@eecs.umich.edu machInst, ufp0, vd * 2, inc * 2, lane); 9897639Sgblack@eecs.umich.edu break; 9907639Sgblack@eecs.umich.edu case 2: 9917639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroPackNeon4to2Uop<uint32_t>( 9927639Sgblack@eecs.umich.edu machInst, ufp0, vd * 2, inc * 2, lane); 9937639Sgblack@eecs.umich.edu break; 9947639Sgblack@eecs.umich.edu default: 9957853SMatt.Horsnell@ARM.com // Bad size 9967853SMatt.Horsnell@ARM.com microOps[uopIdx++] = new Unknown(machInst); 9977639Sgblack@eecs.umich.edu break; 9987639Sgblack@eecs.umich.edu } 9997639Sgblack@eecs.umich.edu break; 10007639Sgblack@eecs.umich.edu case 1: 10017639Sgblack@eecs.umich.edu assert(regs == 1 || (all && regs == 2)); 10027639Sgblack@eecs.umich.edu assert(storeRegs <= 2); 10037639Sgblack@eecs.umich.edu for (unsigned offset = 0; offset < regs; offset++) { 10047639Sgblack@eecs.umich.edu switch (size) { 10057639Sgblack@eecs.umich.edu case 0: 10067639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroPackNeon2to2Uop<uint8_t>( 10077639Sgblack@eecs.umich.edu machInst, ufp0, (vd + offset) * 2, inc * 2, lane); 10087639Sgblack@eecs.umich.edu break; 10097639Sgblack@eecs.umich.edu case 1: 10107639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroPackNeon2to2Uop<uint16_t>( 10117639Sgblack@eecs.umich.edu machInst, ufp0, (vd + offset) * 2, inc * 2, lane); 10127639Sgblack@eecs.umich.edu break; 10137639Sgblack@eecs.umich.edu case 2: 10147639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroPackNeon2to2Uop<uint32_t>( 10157639Sgblack@eecs.umich.edu machInst, ufp0, (vd + offset) * 2, inc * 2, lane); 10167639Sgblack@eecs.umich.edu break; 10177639Sgblack@eecs.umich.edu default: 10187853SMatt.Horsnell@ARM.com // Bad size 10197853SMatt.Horsnell@ARM.com microOps[uopIdx++] = new Unknown(machInst); 10207639Sgblack@eecs.umich.edu break; 10217639Sgblack@eecs.umich.edu } 10227639Sgblack@eecs.umich.edu } 10237639Sgblack@eecs.umich.edu break; 10247639Sgblack@eecs.umich.edu default: 10257853SMatt.Horsnell@ARM.com // Bad number of elements to unpack 10267853SMatt.Horsnell@ARM.com microOps[uopIdx++] = new Unknown(machInst); 10277639Sgblack@eecs.umich.edu } 10287639Sgblack@eecs.umich.edu switch (storeSize) { 10297639Sgblack@eecs.umich.edu case 1: 10307639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroStrNeon1Uop<uint8_t>( 10317639Sgblack@eecs.umich.edu machInst, ufp0, rn, 0, align); 10327639Sgblack@eecs.umich.edu break; 10337639Sgblack@eecs.umich.edu case 2: 10347639Sgblack@eecs.umich.edu if (eBytes == 2) { 10357639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroStrNeon2Uop<uint16_t>( 10367639Sgblack@eecs.umich.edu machInst, ufp0, rn, 0, align); 10377639Sgblack@eecs.umich.edu } else { 10387639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroStrNeon2Uop<uint8_t>( 10397639Sgblack@eecs.umich.edu machInst, ufp0, rn, 0, align); 10407639Sgblack@eecs.umich.edu } 10417639Sgblack@eecs.umich.edu break; 10427639Sgblack@eecs.umich.edu case 3: 10437639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroStrNeon3Uop<uint8_t>( 10447639Sgblack@eecs.umich.edu machInst, ufp0, rn, 0, align); 10457639Sgblack@eecs.umich.edu break; 10467639Sgblack@eecs.umich.edu case 4: 10477639Sgblack@eecs.umich.edu switch (eBytes) { 10487639Sgblack@eecs.umich.edu case 1: 10497639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroStrNeon4Uop<uint8_t>( 10507639Sgblack@eecs.umich.edu machInst, ufp0, rn, 0, align); 10517639Sgblack@eecs.umich.edu break; 10527639Sgblack@eecs.umich.edu case 2: 10537639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroStrNeon4Uop<uint16_t>( 10547639Sgblack@eecs.umich.edu machInst, ufp0, rn, 0, align); 10557639Sgblack@eecs.umich.edu break; 10567639Sgblack@eecs.umich.edu case 4: 10577639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroStrNeon4Uop<uint32_t>( 10587639Sgblack@eecs.umich.edu machInst, ufp0, rn, 0, align); 10597639Sgblack@eecs.umich.edu break; 10607639Sgblack@eecs.umich.edu } 10617639Sgblack@eecs.umich.edu break; 10627639Sgblack@eecs.umich.edu case 6: 10637639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroStrNeon6Uop<uint16_t>( 10647639Sgblack@eecs.umich.edu machInst, ufp0, rn, 0, align); 10657639Sgblack@eecs.umich.edu break; 10667639Sgblack@eecs.umich.edu case 8: 10677639Sgblack@eecs.umich.edu switch (eBytes) { 10687639Sgblack@eecs.umich.edu case 2: 10697639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroStrNeon8Uop<uint16_t>( 10707639Sgblack@eecs.umich.edu machInst, ufp0, rn, 0, align); 10717639Sgblack@eecs.umich.edu break; 10727639Sgblack@eecs.umich.edu case 4: 10737639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroStrNeon8Uop<uint32_t>( 10747639Sgblack@eecs.umich.edu machInst, ufp0, rn, 0, align); 10757639Sgblack@eecs.umich.edu break; 10767639Sgblack@eecs.umich.edu } 10777639Sgblack@eecs.umich.edu break; 10787639Sgblack@eecs.umich.edu case 12: 10797639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroStrNeon12Uop<uint32_t>( 10807639Sgblack@eecs.umich.edu machInst, ufp0, rn, 0, align); 10817639Sgblack@eecs.umich.edu break; 10827639Sgblack@eecs.umich.edu case 16: 10837639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroStrNeon16Uop<uint32_t>( 10847639Sgblack@eecs.umich.edu machInst, ufp0, rn, 0, align); 10857639Sgblack@eecs.umich.edu break; 10867639Sgblack@eecs.umich.edu default: 10877853SMatt.Horsnell@ARM.com // Bad store size 10887853SMatt.Horsnell@ARM.com microOps[uopIdx++] = new Unknown(machInst); 10897639Sgblack@eecs.umich.edu } 10907639Sgblack@eecs.umich.edu if (wb) { 10917639Sgblack@eecs.umich.edu if (rm != 15 && rm != 13) { 10927639Sgblack@eecs.umich.edu microOps[uopIdx++] = 10937646Sgene.wu@arm.com new MicroAddUop(machInst, rn, rn, rm, 0, ArmISA::LSL); 10947639Sgblack@eecs.umich.edu } else { 10957639Sgblack@eecs.umich.edu microOps[uopIdx++] = 10967639Sgblack@eecs.umich.edu new MicroAddiUop(machInst, rn, rn, storeSize); 10977639Sgblack@eecs.umich.edu } 10987639Sgblack@eecs.umich.edu } 10997639Sgblack@eecs.umich.edu assert(uopIdx == numMicroops); 11007639Sgblack@eecs.umich.edu 11017639Sgblack@eecs.umich.edu for (unsigned i = 0; i < numMicroops - 1; i++) { 11027639Sgblack@eecs.umich.edu MicroOp * uopPtr = dynamic_cast<MicroOp *>(microOps[i].get()); 11037639Sgblack@eecs.umich.edu assert(uopPtr); 11047639Sgblack@eecs.umich.edu uopPtr->setDelayedCommit(); 11057639Sgblack@eecs.umich.edu } 11067639Sgblack@eecs.umich.edu microOps[numMicroops - 1]->setLastMicroop(); 11077639Sgblack@eecs.umich.edu} 11087639Sgblack@eecs.umich.edu 110910037SARM gem5 DevelopersVldMultOp64::VldMultOp64(const char *mnem, ExtMachInst machInst, 111010037SARM gem5 Developers OpClass __opClass, RegIndex rn, RegIndex vd, 111110037SARM gem5 Developers RegIndex rm, uint8_t eSize, uint8_t dataSize, 111210037SARM gem5 Developers uint8_t numStructElems, uint8_t numRegs, bool wb) : 111310037SARM gem5 Developers PredMacroOp(mnem, machInst, __opClass) 111410037SARM gem5 Developers{ 111510037SARM gem5 Developers RegIndex vx = NumFloatV8ArchRegs / 4; 111610037SARM gem5 Developers RegIndex rnsp = (RegIndex) makeSP((IntRegIndex) rn); 111710037SARM gem5 Developers bool baseIsSP = isSP((IntRegIndex) rnsp); 111810037SARM gem5 Developers 111910037SARM gem5 Developers numMicroops = wb ? 1 : 0; 112010037SARM gem5 Developers 112110037SARM gem5 Developers int totNumBytes = numRegs * dataSize / 8; 112210037SARM gem5 Developers assert(totNumBytes <= 64); 112310037SARM gem5 Developers 112410037SARM gem5 Developers // The guiding principle here is that no more than 16 bytes can be 112510037SARM gem5 Developers // transferred at a time 112610037SARM gem5 Developers int numMemMicroops = totNumBytes / 16; 112710037SARM gem5 Developers int residuum = totNumBytes % 16; 112810037SARM gem5 Developers if (residuum) 112910037SARM gem5 Developers ++numMemMicroops; 113010037SARM gem5 Developers numMicroops += numMemMicroops; 113110037SARM gem5 Developers 113210037SARM gem5 Developers int numMarshalMicroops = numRegs / 2 + (numRegs % 2 ? 1 : 0); 113310037SARM gem5 Developers numMicroops += numMarshalMicroops; 113410037SARM gem5 Developers 113510037SARM gem5 Developers microOps = new StaticInstPtr[numMicroops]; 113610037SARM gem5 Developers unsigned uopIdx = 0; 113710037SARM gem5 Developers uint32_t memaccessFlags = TLB::MustBeOne | (TLB::ArmFlags) eSize | 113810037SARM gem5 Developers TLB::AllowUnaligned; 113910037SARM gem5 Developers 114010037SARM gem5 Developers int i = 0; 114110037SARM gem5 Developers for(; i < numMemMicroops - 1; ++i) { 114210037SARM gem5 Developers microOps[uopIdx++] = new MicroNeonLoad64( 114310037SARM gem5 Developers machInst, vx + (RegIndex) i, rnsp, 16 * i, memaccessFlags, 114410037SARM gem5 Developers baseIsSP, 16 /* accSize */, eSize); 114510037SARM gem5 Developers } 114610037SARM gem5 Developers microOps[uopIdx++] = new MicroNeonLoad64( 114710037SARM gem5 Developers machInst, vx + (RegIndex) i, rnsp, 16 * i, memaccessFlags, baseIsSP, 114810037SARM gem5 Developers residuum ? residuum : 16 /* accSize */, eSize); 114910037SARM gem5 Developers 115010037SARM gem5 Developers // Writeback microop: the post-increment amount is encoded in "Rm": a 115110037SARM gem5 Developers // 64-bit general register OR as '11111' for an immediate value equal to 115210037SARM gem5 Developers // the total number of bytes transferred (i.e. 8, 16, 24, 32, 48 or 64) 115310037SARM gem5 Developers if (wb) { 115410037SARM gem5 Developers if (rm != ((RegIndex) INTREG_X31)) { 115510037SARM gem5 Developers microOps[uopIdx++] = new MicroAddXERegUop(machInst, rnsp, rnsp, rm, 115610037SARM gem5 Developers UXTX, 0); 115710037SARM gem5 Developers } else { 115810037SARM gem5 Developers microOps[uopIdx++] = new MicroAddXiUop(machInst, rnsp, rnsp, 115910037SARM gem5 Developers totNumBytes); 116010037SARM gem5 Developers } 116110037SARM gem5 Developers } 116210037SARM gem5 Developers 116310037SARM gem5 Developers for (int i = 0; i < numMarshalMicroops; ++i) { 116410339Smitch.hayenga@arm.com switch(numRegs) { 116510339Smitch.hayenga@arm.com case 1: microOps[uopIdx++] = new MicroDeintNeon64_1Reg( 116610339Smitch.hayenga@arm.com machInst, vd + (RegIndex) (2 * i), vx, eSize, dataSize, 116710339Smitch.hayenga@arm.com numStructElems, 1, i /* step */); 116810339Smitch.hayenga@arm.com break; 116910339Smitch.hayenga@arm.com case 2: microOps[uopIdx++] = new MicroDeintNeon64_2Reg( 117010339Smitch.hayenga@arm.com machInst, vd + (RegIndex) (2 * i), vx, eSize, dataSize, 117110339Smitch.hayenga@arm.com numStructElems, 2, i /* step */); 117210339Smitch.hayenga@arm.com break; 117310339Smitch.hayenga@arm.com case 3: microOps[uopIdx++] = new MicroDeintNeon64_3Reg( 117410339Smitch.hayenga@arm.com machInst, vd + (RegIndex) (2 * i), vx, eSize, dataSize, 117510339Smitch.hayenga@arm.com numStructElems, 3, i /* step */); 117610339Smitch.hayenga@arm.com break; 117710339Smitch.hayenga@arm.com case 4: microOps[uopIdx++] = new MicroDeintNeon64_4Reg( 117810339Smitch.hayenga@arm.com machInst, vd + (RegIndex) (2 * i), vx, eSize, dataSize, 117910339Smitch.hayenga@arm.com numStructElems, 4, i /* step */); 118010339Smitch.hayenga@arm.com break; 118110339Smitch.hayenga@arm.com default: panic("Invalid number of registers"); 118210339Smitch.hayenga@arm.com } 118310339Smitch.hayenga@arm.com 118410037SARM gem5 Developers } 118510037SARM gem5 Developers 118610037SARM gem5 Developers assert(uopIdx == numMicroops); 118710037SARM gem5 Developers 118810037SARM gem5 Developers for (int i = 0; i < numMicroops - 1; ++i) { 118910037SARM gem5 Developers microOps[i]->setDelayedCommit(); 119010037SARM gem5 Developers } 119110037SARM gem5 Developers microOps[numMicroops - 1]->setLastMicroop(); 119210037SARM gem5 Developers} 119310037SARM gem5 Developers 119410037SARM gem5 DevelopersVstMultOp64::VstMultOp64(const char *mnem, ExtMachInst machInst, 119510037SARM gem5 Developers OpClass __opClass, RegIndex rn, RegIndex vd, 119610037SARM gem5 Developers RegIndex rm, uint8_t eSize, uint8_t dataSize, 119710037SARM gem5 Developers uint8_t numStructElems, uint8_t numRegs, bool wb) : 119810037SARM gem5 Developers PredMacroOp(mnem, machInst, __opClass) 119910037SARM gem5 Developers{ 120010037SARM gem5 Developers RegIndex vx = NumFloatV8ArchRegs / 4; 120110037SARM gem5 Developers RegIndex rnsp = (RegIndex) makeSP((IntRegIndex) rn); 120210037SARM gem5 Developers bool baseIsSP = isSP((IntRegIndex) rnsp); 120310037SARM gem5 Developers 120410037SARM gem5 Developers numMicroops = wb ? 1 : 0; 120510037SARM gem5 Developers 120610037SARM gem5 Developers int totNumBytes = numRegs * dataSize / 8; 120710037SARM gem5 Developers assert(totNumBytes <= 64); 120810037SARM gem5 Developers 120910037SARM gem5 Developers // The guiding principle here is that no more than 16 bytes can be 121010037SARM gem5 Developers // transferred at a time 121110037SARM gem5 Developers int numMemMicroops = totNumBytes / 16; 121210037SARM gem5 Developers int residuum = totNumBytes % 16; 121310037SARM gem5 Developers if (residuum) 121410037SARM gem5 Developers ++numMemMicroops; 121510037SARM gem5 Developers numMicroops += numMemMicroops; 121610037SARM gem5 Developers 121710037SARM gem5 Developers int numMarshalMicroops = totNumBytes > 32 ? 2 : 1; 121810037SARM gem5 Developers numMicroops += numMarshalMicroops; 121910037SARM gem5 Developers 122010037SARM gem5 Developers microOps = new StaticInstPtr[numMicroops]; 122110037SARM gem5 Developers unsigned uopIdx = 0; 122210037SARM gem5 Developers 122310037SARM gem5 Developers for(int i = 0; i < numMarshalMicroops; ++i) { 122410339Smitch.hayenga@arm.com switch (numRegs) { 122510339Smitch.hayenga@arm.com case 1: microOps[uopIdx++] = new MicroIntNeon64_1Reg( 122610339Smitch.hayenga@arm.com machInst, vx + (RegIndex) (2 * i), vd, eSize, dataSize, 122710339Smitch.hayenga@arm.com numStructElems, 1, i /* step */); 122810339Smitch.hayenga@arm.com break; 122910339Smitch.hayenga@arm.com case 2: microOps[uopIdx++] = new MicroIntNeon64_2Reg( 123010339Smitch.hayenga@arm.com machInst, vx + (RegIndex) (2 * i), vd, eSize, dataSize, 123110339Smitch.hayenga@arm.com numStructElems, 2, i /* step */); 123210339Smitch.hayenga@arm.com break; 123310339Smitch.hayenga@arm.com case 3: microOps[uopIdx++] = new MicroIntNeon64_3Reg( 123410339Smitch.hayenga@arm.com machInst, vx + (RegIndex) (2 * i), vd, eSize, dataSize, 123510339Smitch.hayenga@arm.com numStructElems, 3, i /* step */); 123610339Smitch.hayenga@arm.com break; 123710339Smitch.hayenga@arm.com case 4: microOps[uopIdx++] = new MicroIntNeon64_4Reg( 123810339Smitch.hayenga@arm.com machInst, vx + (RegIndex) (2 * i), vd, eSize, dataSize, 123910339Smitch.hayenga@arm.com numStructElems, 4, i /* step */); 124010339Smitch.hayenga@arm.com break; 124110339Smitch.hayenga@arm.com default: panic("Invalid number of registers"); 124210339Smitch.hayenga@arm.com } 124310037SARM gem5 Developers } 124410037SARM gem5 Developers 124510037SARM gem5 Developers uint32_t memaccessFlags = TLB::MustBeOne | (TLB::ArmFlags) eSize | 124610037SARM gem5 Developers TLB::AllowUnaligned; 124710037SARM gem5 Developers 124810037SARM gem5 Developers int i = 0; 124910037SARM gem5 Developers for(; i < numMemMicroops - 1; ++i) { 125010037SARM gem5 Developers microOps[uopIdx++] = new MicroNeonStore64( 125110037SARM gem5 Developers machInst, vx + (RegIndex) i, rnsp, 16 * i, memaccessFlags, 125210037SARM gem5 Developers baseIsSP, 16 /* accSize */, eSize); 125310037SARM gem5 Developers } 125410037SARM gem5 Developers microOps[uopIdx++] = new MicroNeonStore64( 125510037SARM gem5 Developers machInst, vx + (RegIndex) i, rnsp, 16 * i, memaccessFlags, baseIsSP, 125610037SARM gem5 Developers residuum ? residuum : 16 /* accSize */, eSize); 125710037SARM gem5 Developers 125810037SARM gem5 Developers // Writeback microop: the post-increment amount is encoded in "Rm": a 125910037SARM gem5 Developers // 64-bit general register OR as '11111' for an immediate value equal to 126010037SARM gem5 Developers // the total number of bytes transferred (i.e. 8, 16, 24, 32, 48 or 64) 126110037SARM gem5 Developers if (wb) { 126210037SARM gem5 Developers if (rm != ((RegIndex) INTREG_X31)) { 126310037SARM gem5 Developers microOps[uopIdx++] = new MicroAddXERegUop(machInst, rnsp, rnsp, rm, 126410037SARM gem5 Developers UXTX, 0); 126510037SARM gem5 Developers } else { 126610037SARM gem5 Developers microOps[uopIdx++] = new MicroAddXiUop(machInst, rnsp, rnsp, 126710037SARM gem5 Developers totNumBytes); 126810037SARM gem5 Developers } 126910037SARM gem5 Developers } 127010037SARM gem5 Developers 127110037SARM gem5 Developers assert(uopIdx == numMicroops); 127210037SARM gem5 Developers 127310037SARM gem5 Developers for (int i = 0; i < numMicroops - 1; i++) { 127410037SARM gem5 Developers microOps[i]->setDelayedCommit(); 127510037SARM gem5 Developers } 127610037SARM gem5 Developers microOps[numMicroops - 1]->setLastMicroop(); 127710037SARM gem5 Developers} 127810037SARM gem5 Developers 127910037SARM gem5 DevelopersVldSingleOp64::VldSingleOp64(const char *mnem, ExtMachInst machInst, 128010037SARM gem5 Developers OpClass __opClass, RegIndex rn, RegIndex vd, 128110037SARM gem5 Developers RegIndex rm, uint8_t eSize, uint8_t dataSize, 128210037SARM gem5 Developers uint8_t numStructElems, uint8_t index, bool wb, 128310037SARM gem5 Developers bool replicate) : 128410037SARM gem5 Developers PredMacroOp(mnem, machInst, __opClass) 128510037SARM gem5 Developers{ 128610037SARM gem5 Developers RegIndex vx = NumFloatV8ArchRegs / 4; 128710037SARM gem5 Developers RegIndex rnsp = (RegIndex) makeSP((IntRegIndex) rn); 128810037SARM gem5 Developers bool baseIsSP = isSP((IntRegIndex) rnsp); 128910037SARM gem5 Developers 129010037SARM gem5 Developers numMicroops = wb ? 1 : 0; 129110037SARM gem5 Developers 129210037SARM gem5 Developers int eSizeBytes = 1 << eSize; 129310037SARM gem5 Developers int totNumBytes = numStructElems * eSizeBytes; 129410037SARM gem5 Developers assert(totNumBytes <= 64); 129510037SARM gem5 Developers 129610037SARM gem5 Developers // The guiding principle here is that no more than 16 bytes can be 129710037SARM gem5 Developers // transferred at a time 129810037SARM gem5 Developers int numMemMicroops = totNumBytes / 16; 129910037SARM gem5 Developers int residuum = totNumBytes % 16; 130010037SARM gem5 Developers if (residuum) 130110037SARM gem5 Developers ++numMemMicroops; 130210037SARM gem5 Developers numMicroops += numMemMicroops; 130310037SARM gem5 Developers 130410037SARM gem5 Developers int numMarshalMicroops = numStructElems / 2 + (numStructElems % 2 ? 1 : 0); 130510037SARM gem5 Developers numMicroops += numMarshalMicroops; 130610037SARM gem5 Developers 130710037SARM gem5 Developers microOps = new StaticInstPtr[numMicroops]; 130810037SARM gem5 Developers unsigned uopIdx = 0; 130910037SARM gem5 Developers 131010037SARM gem5 Developers uint32_t memaccessFlags = TLB::MustBeOne | (TLB::ArmFlags) eSize | 131110037SARM gem5 Developers TLB::AllowUnaligned; 131210037SARM gem5 Developers 131310037SARM gem5 Developers int i = 0; 131410037SARM gem5 Developers for (; i < numMemMicroops - 1; ++i) { 131510037SARM gem5 Developers microOps[uopIdx++] = new MicroNeonLoad64( 131610037SARM gem5 Developers machInst, vx + (RegIndex) i, rnsp, 16 * i, memaccessFlags, 131710037SARM gem5 Developers baseIsSP, 16 /* accSize */, eSize); 131810037SARM gem5 Developers } 131910037SARM gem5 Developers microOps[uopIdx++] = new MicroNeonLoad64( 132010037SARM gem5 Developers machInst, vx + (RegIndex) i, rnsp, 16 * i, memaccessFlags, baseIsSP, 132110037SARM gem5 Developers residuum ? residuum : 16 /* accSize */, eSize); 132210037SARM gem5 Developers 132310037SARM gem5 Developers // Writeback microop: the post-increment amount is encoded in "Rm": a 132410037SARM gem5 Developers // 64-bit general register OR as '11111' for an immediate value equal to 132510037SARM gem5 Developers // the total number of bytes transferred (i.e. 8, 16, 24, 32, 48 or 64) 132610037SARM gem5 Developers if (wb) { 132710037SARM gem5 Developers if (rm != ((RegIndex) INTREG_X31)) { 132810037SARM gem5 Developers microOps[uopIdx++] = new MicroAddXERegUop(machInst, rnsp, rnsp, rm, 132910037SARM gem5 Developers UXTX, 0); 133010037SARM gem5 Developers } else { 133110037SARM gem5 Developers microOps[uopIdx++] = new MicroAddXiUop(machInst, rnsp, rnsp, 133210037SARM gem5 Developers totNumBytes); 133310037SARM gem5 Developers } 133410037SARM gem5 Developers } 133510037SARM gem5 Developers 133610037SARM gem5 Developers for(int i = 0; i < numMarshalMicroops; ++i) { 133710037SARM gem5 Developers microOps[uopIdx++] = new MicroUnpackNeon64( 133810037SARM gem5 Developers machInst, vd + (RegIndex) (2 * i), vx, eSize, dataSize, 133910037SARM gem5 Developers numStructElems, index, i /* step */, replicate); 134010037SARM gem5 Developers } 134110037SARM gem5 Developers 134210037SARM gem5 Developers assert(uopIdx == numMicroops); 134310037SARM gem5 Developers 134410037SARM gem5 Developers for (int i = 0; i < numMicroops - 1; i++) { 134510037SARM gem5 Developers microOps[i]->setDelayedCommit(); 134610037SARM gem5 Developers } 134710037SARM gem5 Developers microOps[numMicroops - 1]->setLastMicroop(); 134810037SARM gem5 Developers} 134910037SARM gem5 Developers 135010037SARM gem5 DevelopersVstSingleOp64::VstSingleOp64(const char *mnem, ExtMachInst machInst, 135110037SARM gem5 Developers OpClass __opClass, RegIndex rn, RegIndex vd, 135210037SARM gem5 Developers RegIndex rm, uint8_t eSize, uint8_t dataSize, 135310037SARM gem5 Developers uint8_t numStructElems, uint8_t index, bool wb, 135410037SARM gem5 Developers bool replicate) : 135510037SARM gem5 Developers PredMacroOp(mnem, machInst, __opClass) 135610037SARM gem5 Developers{ 135710037SARM gem5 Developers RegIndex vx = NumFloatV8ArchRegs / 4; 135810037SARM gem5 Developers RegIndex rnsp = (RegIndex) makeSP((IntRegIndex) rn); 135910037SARM gem5 Developers bool baseIsSP = isSP((IntRegIndex) rnsp); 136010037SARM gem5 Developers 136110037SARM gem5 Developers numMicroops = wb ? 1 : 0; 136210037SARM gem5 Developers 136310037SARM gem5 Developers int eSizeBytes = 1 << eSize; 136410037SARM gem5 Developers int totNumBytes = numStructElems * eSizeBytes; 136510037SARM gem5 Developers assert(totNumBytes <= 64); 136610037SARM gem5 Developers 136710037SARM gem5 Developers // The guiding principle here is that no more than 16 bytes can be 136810037SARM gem5 Developers // transferred at a time 136910037SARM gem5 Developers int numMemMicroops = totNumBytes / 16; 137010037SARM gem5 Developers int residuum = totNumBytes % 16; 137110037SARM gem5 Developers if (residuum) 137210037SARM gem5 Developers ++numMemMicroops; 137310037SARM gem5 Developers numMicroops += numMemMicroops; 137410037SARM gem5 Developers 137510037SARM gem5 Developers int numMarshalMicroops = totNumBytes > 32 ? 2 : 1; 137610037SARM gem5 Developers numMicroops += numMarshalMicroops; 137710037SARM gem5 Developers 137810037SARM gem5 Developers microOps = new StaticInstPtr[numMicroops]; 137910037SARM gem5 Developers unsigned uopIdx = 0; 138010037SARM gem5 Developers 138110037SARM gem5 Developers for(int i = 0; i < numMarshalMicroops; ++i) { 138210037SARM gem5 Developers microOps[uopIdx++] = new MicroPackNeon64( 138310037SARM gem5 Developers machInst, vx + (RegIndex) (2 * i), vd, eSize, dataSize, 138410037SARM gem5 Developers numStructElems, index, i /* step */, replicate); 138510037SARM gem5 Developers } 138610037SARM gem5 Developers 138710037SARM gem5 Developers uint32_t memaccessFlags = TLB::MustBeOne | (TLB::ArmFlags) eSize | 138810037SARM gem5 Developers TLB::AllowUnaligned; 138910037SARM gem5 Developers 139010037SARM gem5 Developers int i = 0; 139110037SARM gem5 Developers for(; i < numMemMicroops - 1; ++i) { 139210037SARM gem5 Developers microOps[uopIdx++] = new MicroNeonStore64( 139310037SARM gem5 Developers machInst, vx + (RegIndex) i, rnsp, 16 * i, memaccessFlags, 139410037SARM gem5 Developers baseIsSP, 16 /* accsize */, eSize); 139510037SARM gem5 Developers } 139610037SARM gem5 Developers microOps[uopIdx++] = new MicroNeonStore64( 139710037SARM gem5 Developers machInst, vx + (RegIndex) i, rnsp, 16 * i, memaccessFlags, baseIsSP, 139810037SARM gem5 Developers residuum ? residuum : 16 /* accSize */, eSize); 139910037SARM gem5 Developers 140010037SARM gem5 Developers // Writeback microop: the post-increment amount is encoded in "Rm": a 140110037SARM gem5 Developers // 64-bit general register OR as '11111' for an immediate value equal to 140210037SARM gem5 Developers // the total number of bytes transferred (i.e. 8, 16, 24, 32, 48 or 64) 140310037SARM gem5 Developers if (wb) { 140410037SARM gem5 Developers if (rm != ((RegIndex) INTREG_X31)) { 140510037SARM gem5 Developers microOps[uopIdx++] = new MicroAddXERegUop(machInst, rnsp, rnsp, rm, 140610037SARM gem5 Developers UXTX, 0); 140710037SARM gem5 Developers } else { 140810037SARM gem5 Developers microOps[uopIdx++] = new MicroAddXiUop(machInst, rnsp, rnsp, 140910037SARM gem5 Developers totNumBytes); 141010037SARM gem5 Developers } 141110037SARM gem5 Developers } 141210037SARM gem5 Developers 141310037SARM gem5 Developers assert(uopIdx == numMicroops); 141410037SARM gem5 Developers 141510037SARM gem5 Developers for (int i = 0; i < numMicroops - 1; i++) { 141610037SARM gem5 Developers microOps[i]->setDelayedCommit(); 141710037SARM gem5 Developers } 141810037SARM gem5 Developers microOps[numMicroops - 1]->setLastMicroop(); 141910037SARM gem5 Developers} 142010037SARM gem5 Developers 14217175Sgblack@eecs.umich.eduMacroVFPMemOp::MacroVFPMemOp(const char *mnem, ExtMachInst machInst, 14227175Sgblack@eecs.umich.edu OpClass __opClass, IntRegIndex rn, 14237175Sgblack@eecs.umich.edu RegIndex vd, bool single, bool up, 14247175Sgblack@eecs.umich.edu bool writeback, bool load, uint32_t offset) : 14257175Sgblack@eecs.umich.edu PredMacroOp(mnem, machInst, __opClass) 14267175Sgblack@eecs.umich.edu{ 14277175Sgblack@eecs.umich.edu int i = 0; 14287175Sgblack@eecs.umich.edu 14297175Sgblack@eecs.umich.edu // The lowest order bit selects fldmx (set) or fldmd (clear). These seem 14307175Sgblack@eecs.umich.edu // to be functionally identical except that fldmx is deprecated. For now 14317175Sgblack@eecs.umich.edu // we'll assume they're otherwise interchangable. 14327175Sgblack@eecs.umich.edu int count = (single ? offset : (offset / 2)); 143310037SARM gem5 Developers if (count == 0 || count > NumFloatV7ArchRegs) 14347175Sgblack@eecs.umich.edu warn_once("Bad offset field for VFP load/store multiple.\n"); 14357175Sgblack@eecs.umich.edu if (count == 0) { 14367175Sgblack@eecs.umich.edu // Force there to be at least one microop so the macroop makes sense. 14377175Sgblack@eecs.umich.edu writeback = true; 14387175Sgblack@eecs.umich.edu } 143910037SARM gem5 Developers if (count > NumFloatV7ArchRegs) 144010037SARM gem5 Developers count = NumFloatV7ArchRegs; 14417175Sgblack@eecs.umich.edu 14427342Sgblack@eecs.umich.edu numMicroops = count * (single ? 1 : 2) + (writeback ? 1 : 0); 14437342Sgblack@eecs.umich.edu microOps = new StaticInstPtr[numMicroops]; 14447342Sgblack@eecs.umich.edu 14457395Sgblack@eecs.umich.edu int64_t addr = 0; 14467175Sgblack@eecs.umich.edu 14477342Sgblack@eecs.umich.edu if (!up) 14487342Sgblack@eecs.umich.edu addr = 4 * offset; 14497175Sgblack@eecs.umich.edu 14507342Sgblack@eecs.umich.edu bool tempUp = up; 14517175Sgblack@eecs.umich.edu for (int j = 0; j < count; j++) { 14527175Sgblack@eecs.umich.edu if (load) { 14537639Sgblack@eecs.umich.edu if (single) { 14547639Sgblack@eecs.umich.edu microOps[i++] = new MicroLdrFpUop(machInst, vd++, rn, 14557639Sgblack@eecs.umich.edu tempUp, addr); 14567639Sgblack@eecs.umich.edu } else { 14577639Sgblack@eecs.umich.edu microOps[i++] = new MicroLdrDBFpUop(machInst, vd++, rn, 14587639Sgblack@eecs.umich.edu tempUp, addr); 14597639Sgblack@eecs.umich.edu microOps[i++] = new MicroLdrDTFpUop(machInst, vd++, rn, tempUp, 14607639Sgblack@eecs.umich.edu addr + (up ? 4 : -4)); 14617639Sgblack@eecs.umich.edu } 14627175Sgblack@eecs.umich.edu } else { 14637639Sgblack@eecs.umich.edu if (single) { 14647639Sgblack@eecs.umich.edu microOps[i++] = new MicroStrFpUop(machInst, vd++, rn, 14657639Sgblack@eecs.umich.edu tempUp, addr); 14667639Sgblack@eecs.umich.edu } else { 14677639Sgblack@eecs.umich.edu microOps[i++] = new MicroStrDBFpUop(machInst, vd++, rn, 14687639Sgblack@eecs.umich.edu tempUp, addr); 14697639Sgblack@eecs.umich.edu microOps[i++] = new MicroStrDTFpUop(machInst, vd++, rn, tempUp, 14707639Sgblack@eecs.umich.edu addr + (up ? 4 : -4)); 14717639Sgblack@eecs.umich.edu } 14727175Sgblack@eecs.umich.edu } 14737342Sgblack@eecs.umich.edu if (!tempUp) { 14747342Sgblack@eecs.umich.edu addr -= (single ? 4 : 8); 14757342Sgblack@eecs.umich.edu // The microops don't handle negative displacement, so turn if we 14767342Sgblack@eecs.umich.edu // hit zero, flip polarity and start adding. 14777395Sgblack@eecs.umich.edu if (addr <= 0) { 14787342Sgblack@eecs.umich.edu tempUp = true; 14797395Sgblack@eecs.umich.edu addr = -addr; 14807342Sgblack@eecs.umich.edu } 14817342Sgblack@eecs.umich.edu } else { 14827342Sgblack@eecs.umich.edu addr += (single ? 4 : 8); 14837342Sgblack@eecs.umich.edu } 14847175Sgblack@eecs.umich.edu } 14857175Sgblack@eecs.umich.edu 14867175Sgblack@eecs.umich.edu if (writeback) { 14877175Sgblack@eecs.umich.edu if (up) { 14887175Sgblack@eecs.umich.edu microOps[i++] = 14897175Sgblack@eecs.umich.edu new MicroAddiUop(machInst, rn, rn, 4 * offset); 14907175Sgblack@eecs.umich.edu } else { 14917175Sgblack@eecs.umich.edu microOps[i++] = 14927175Sgblack@eecs.umich.edu new MicroSubiUop(machInst, rn, rn, 4 * offset); 14937175Sgblack@eecs.umich.edu } 14947175Sgblack@eecs.umich.edu } 14957175Sgblack@eecs.umich.edu 14967342Sgblack@eecs.umich.edu assert(numMicroops == i); 14977175Sgblack@eecs.umich.edu microOps[numMicroops - 1]->setLastMicroop(); 14987343Sgblack@eecs.umich.edu 14997343Sgblack@eecs.umich.edu for (StaticInstPtr *curUop = microOps; 15007343Sgblack@eecs.umich.edu !(*curUop)->isLastMicroop(); curUop++) { 15017343Sgblack@eecs.umich.edu MicroOp * uopPtr = dynamic_cast<MicroOp *>(curUop->get()); 15027343Sgblack@eecs.umich.edu assert(uopPtr); 15037343Sgblack@eecs.umich.edu uopPtr->setDelayedCommit(); 15047343Sgblack@eecs.umich.edu } 15057170Sgblack@eecs.umich.edu} 15067175Sgblack@eecs.umich.edu 15077615Sminkyu.jeong@arm.comstd::string 15087639Sgblack@eecs.umich.eduMicroIntImmOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const 15097639Sgblack@eecs.umich.edu{ 15107639Sgblack@eecs.umich.edu std::stringstream ss; 15117639Sgblack@eecs.umich.edu printMnemonic(ss); 15127639Sgblack@eecs.umich.edu printReg(ss, ura); 15137639Sgblack@eecs.umich.edu ss << ", "; 15147639Sgblack@eecs.umich.edu printReg(ss, urb); 15157639Sgblack@eecs.umich.edu ss << ", "; 15167639Sgblack@eecs.umich.edu ccprintf(ss, "#%d", imm); 15177639Sgblack@eecs.umich.edu return ss.str(); 15187639Sgblack@eecs.umich.edu} 15197639Sgblack@eecs.umich.edu 15207639Sgblack@eecs.umich.edustd::string 152110037SARM gem5 DevelopersMicroIntImmXOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const 152210037SARM gem5 Developers{ 152310037SARM gem5 Developers std::stringstream ss; 152410037SARM gem5 Developers printMnemonic(ss); 152510037SARM gem5 Developers printReg(ss, ura); 152610037SARM gem5 Developers ss << ", "; 152710037SARM gem5 Developers printReg(ss, urb); 152810037SARM gem5 Developers ss << ", "; 152910037SARM gem5 Developers ccprintf(ss, "#%d", imm); 153010037SARM gem5 Developers return ss.str(); 153110037SARM gem5 Developers} 153210037SARM gem5 Developers 153310037SARM gem5 Developersstd::string 15348140SMatt.Horsnell@arm.comMicroSetPCCPSR::generateDisassembly(Addr pc, const SymbolTable *symtab) const 15358140SMatt.Horsnell@arm.com{ 15368140SMatt.Horsnell@arm.com std::stringstream ss; 15378140SMatt.Horsnell@arm.com printMnemonic(ss); 15388140SMatt.Horsnell@arm.com ss << "[PC,CPSR]"; 15398140SMatt.Horsnell@arm.com return ss.str(); 15408140SMatt.Horsnell@arm.com} 15418140SMatt.Horsnell@arm.com 15428140SMatt.Horsnell@arm.comstd::string 154310037SARM gem5 DevelopersMicroIntRegXOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const 154410037SARM gem5 Developers{ 154510037SARM gem5 Developers std::stringstream ss; 154610037SARM gem5 Developers printMnemonic(ss); 154710037SARM gem5 Developers printReg(ss, ura); 154810037SARM gem5 Developers ccprintf(ss, ", "); 154910037SARM gem5 Developers printReg(ss, urb); 155010037SARM gem5 Developers printExtendOperand(false, ss, (IntRegIndex)urc, type, shiftAmt); 155110037SARM gem5 Developers return ss.str(); 155210037SARM gem5 Developers} 155310037SARM gem5 Developers 155410037SARM gem5 Developersstd::string 15557646Sgene.wu@arm.comMicroIntMov::generateDisassembly(Addr pc, const SymbolTable *symtab) const 15567646Sgene.wu@arm.com{ 15577646Sgene.wu@arm.com std::stringstream ss; 15587646Sgene.wu@arm.com printMnemonic(ss); 15597646Sgene.wu@arm.com printReg(ss, ura); 15607646Sgene.wu@arm.com ss << ", "; 15617646Sgene.wu@arm.com printReg(ss, urb); 15627646Sgene.wu@arm.com return ss.str(); 15637646Sgene.wu@arm.com} 15647646Sgene.wu@arm.com 15657646Sgene.wu@arm.comstd::string 15667615Sminkyu.jeong@arm.comMicroIntOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const 15677615Sminkyu.jeong@arm.com{ 15687615Sminkyu.jeong@arm.com std::stringstream ss; 15697615Sminkyu.jeong@arm.com printMnemonic(ss); 15707615Sminkyu.jeong@arm.com printReg(ss, ura); 15717615Sminkyu.jeong@arm.com ss << ", "; 15727615Sminkyu.jeong@arm.com printReg(ss, urb); 15737615Sminkyu.jeong@arm.com ss << ", "; 15747639Sgblack@eecs.umich.edu printReg(ss, urc); 15757615Sminkyu.jeong@arm.com return ss.str(); 15767175Sgblack@eecs.umich.edu} 15777615Sminkyu.jeong@arm.com 15787615Sminkyu.jeong@arm.comstd::string 15797615Sminkyu.jeong@arm.comMicroMemOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const 15807615Sminkyu.jeong@arm.com{ 15817615Sminkyu.jeong@arm.com std::stringstream ss; 15827615Sminkyu.jeong@arm.com printMnemonic(ss); 158310180SCurtis.Dunham@arm.com if (isFloating()) 158410180SCurtis.Dunham@arm.com printReg(ss, ura + FP_Reg_Base); 158510180SCurtis.Dunham@arm.com else 158610180SCurtis.Dunham@arm.com printReg(ss, ura); 15877615Sminkyu.jeong@arm.com ss << ", ["; 15887615Sminkyu.jeong@arm.com printReg(ss, urb); 15897615Sminkyu.jeong@arm.com ss << ", "; 15907615Sminkyu.jeong@arm.com ccprintf(ss, "#%d", imm); 15917615Sminkyu.jeong@arm.com ss << "]"; 15927615Sminkyu.jeong@arm.com return ss.str(); 15937615Sminkyu.jeong@arm.com} 15947615Sminkyu.jeong@arm.com 159510346Smitch.hayenga@arm.comstd::string 159610346Smitch.hayenga@arm.comMicroMemPairOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const 159710346Smitch.hayenga@arm.com{ 159810346Smitch.hayenga@arm.com std::stringstream ss; 159910346Smitch.hayenga@arm.com printMnemonic(ss); 160010346Smitch.hayenga@arm.com printReg(ss, dest); 160110346Smitch.hayenga@arm.com ss << ","; 160210346Smitch.hayenga@arm.com printReg(ss, dest2); 160310346Smitch.hayenga@arm.com ss << ", ["; 160410346Smitch.hayenga@arm.com printReg(ss, urb); 160510346Smitch.hayenga@arm.com ss << ", "; 160610346Smitch.hayenga@arm.com ccprintf(ss, "#%d", imm); 160710346Smitch.hayenga@arm.com ss << "]"; 160810346Smitch.hayenga@arm.com return ss.str(); 16097615Sminkyu.jeong@arm.com} 161010346Smitch.hayenga@arm.com 161110346Smitch.hayenga@arm.com} 1612