macromem.cc revision 11793
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 4311793Sbrandon.potter@amd.com#include "arch/arm/insts/macromem.hh" 4411793Sbrandon.potter@amd.com 458229Snate@binkert.org#include <sstream> 468229Snate@binkert.org 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; 14811321Ssteve.reinhardt@amd.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(); 22310666SAli.Saidi@ARM.com microOps[0]->setFirstMicroop(); 2247343Sgblack@eecs.umich.edu 22510199SAndrew.Bardsley@arm.com /* Take the control flags from the last microop for the macroop */ 22610199SAndrew.Bardsley@arm.com if ((*uop)->isControl()) 22710199SAndrew.Bardsley@arm.com setFlag(StaticInst::IsControl); 22810199SAndrew.Bardsley@arm.com if ((*uop)->isCondCtrl()) 22910199SAndrew.Bardsley@arm.com setFlag(StaticInst::IsCondControl); 23010346Smitch.hayenga@arm.com if ((*uop)->isUncondCtrl()) 23110346Smitch.hayenga@arm.com setFlag(StaticInst::IsUncondControl); 23210199SAndrew.Bardsley@arm.com if ((*uop)->isIndirectCtrl()) 23310199SAndrew.Bardsley@arm.com setFlag(StaticInst::IsIndirectControl); 23410199SAndrew.Bardsley@arm.com if ((*uop)->isReturn()) 23510199SAndrew.Bardsley@arm.com setFlag(StaticInst::IsReturn); 23610199SAndrew.Bardsley@arm.com 23710346Smitch.hayenga@arm.com for (StaticInstPtr *uop = microOps; !(*uop)->isLastMicroop(); uop++) { 23810346Smitch.hayenga@arm.com (*uop)->setDelayedCommit(); 2397343Sgblack@eecs.umich.edu } 2407170Sgblack@eecs.umich.edu} 2417170Sgblack@eecs.umich.edu 24210037SARM gem5 DevelopersPairMemOp::PairMemOp(const char *mnem, ExtMachInst machInst, OpClass __opClass, 24310037SARM gem5 Developers uint32_t size, bool fp, bool load, bool noAlloc, 24410037SARM gem5 Developers bool signExt, bool exclusive, bool acrel, 24510037SARM gem5 Developers int64_t imm, AddrMode mode, 24610037SARM gem5 Developers IntRegIndex rn, IntRegIndex rt, IntRegIndex rt2) : 24710037SARM gem5 Developers PredMacroOp(mnem, machInst, __opClass) 24810037SARM gem5 Developers{ 24910346Smitch.hayenga@arm.com bool post = (mode == AddrMd_PostIndex); 25010037SARM gem5 Developers bool writeback = (mode != AddrMd_Offset); 25110346Smitch.hayenga@arm.com 25210346Smitch.hayenga@arm.com if (load) { 25310346Smitch.hayenga@arm.com // Use integer rounding to round up loads of size 4 25410346Smitch.hayenga@arm.com numMicroops = (post ? 0 : 1) + ((size + 4) / 8) + (writeback ? 1 : 0); 25510346Smitch.hayenga@arm.com } else { 25610346Smitch.hayenga@arm.com numMicroops = (post ? 0 : 1) + (size / 4) + (writeback ? 1 : 0); 25710346Smitch.hayenga@arm.com } 25810037SARM gem5 Developers microOps = new StaticInstPtr[numMicroops]; 25910037SARM gem5 Developers 26010037SARM gem5 Developers StaticInstPtr *uop = microOps; 26110037SARM gem5 Developers 26210037SARM gem5 Developers rn = makeSP(rn); 26310037SARM gem5 Developers 26410346Smitch.hayenga@arm.com if (!post) { 26510346Smitch.hayenga@arm.com *uop++ = new MicroAddXiSpAlignUop(machInst, INTREG_UREG0, rn, 26610346Smitch.hayenga@arm.com post ? 0 : imm); 26710346Smitch.hayenga@arm.com } 26810037SARM gem5 Developers 26910037SARM gem5 Developers if (fp) { 27010037SARM gem5 Developers if (size == 16) { 27110037SARM gem5 Developers if (load) { 27210346Smitch.hayenga@arm.com *uop++ = new MicroLdFp16Uop(machInst, rt, 27310346Smitch.hayenga@arm.com post ? rn : INTREG_UREG0, 0, noAlloc, exclusive, acrel); 27410346Smitch.hayenga@arm.com *uop++ = new MicroLdFp16Uop(machInst, rt2, 27510346Smitch.hayenga@arm.com post ? rn : INTREG_UREG0, 16, noAlloc, exclusive, acrel); 27610037SARM gem5 Developers } else { 27710346Smitch.hayenga@arm.com *uop++ = new MicroStrQBFpXImmUop(machInst, rt, 27810346Smitch.hayenga@arm.com post ? rn : INTREG_UREG0, 0, noAlloc, exclusive, acrel); 27910346Smitch.hayenga@arm.com *uop++ = new MicroStrQTFpXImmUop(machInst, rt, 28010346Smitch.hayenga@arm.com post ? rn : INTREG_UREG0, 0, noAlloc, exclusive, acrel); 28110346Smitch.hayenga@arm.com *uop++ = new MicroStrQBFpXImmUop(machInst, rt2, 28210346Smitch.hayenga@arm.com post ? rn : INTREG_UREG0, 16, noAlloc, exclusive, acrel); 28310346Smitch.hayenga@arm.com *uop++ = new MicroStrQTFpXImmUop(machInst, rt2, 28410346Smitch.hayenga@arm.com post ? rn : INTREG_UREG0, 16, noAlloc, exclusive, acrel); 28510037SARM gem5 Developers } 28610037SARM gem5 Developers } else if (size == 8) { 28710037SARM gem5 Developers if (load) { 28810346Smitch.hayenga@arm.com *uop++ = new MicroLdPairFp8Uop(machInst, rt, rt2, 28910346Smitch.hayenga@arm.com post ? rn : INTREG_UREG0, 0, noAlloc, exclusive, acrel); 29010037SARM gem5 Developers } else { 29110346Smitch.hayenga@arm.com *uop++ = new MicroStrFpXImmUop(machInst, rt, 29210346Smitch.hayenga@arm.com post ? rn : INTREG_UREG0, 0, noAlloc, exclusive, acrel); 29310346Smitch.hayenga@arm.com *uop++ = new MicroStrFpXImmUop(machInst, rt2, 29410346Smitch.hayenga@arm.com post ? rn : INTREG_UREG0, 8, noAlloc, exclusive, acrel); 29510037SARM gem5 Developers } 29610037SARM gem5 Developers } else if (size == 4) { 29710037SARM gem5 Developers if (load) { 29810346Smitch.hayenga@arm.com *uop++ = new MicroLdrDFpXImmUop(machInst, rt, rt2, 29910346Smitch.hayenga@arm.com post ? rn : INTREG_UREG0, 0, noAlloc, exclusive, acrel); 30010037SARM gem5 Developers } else { 30110346Smitch.hayenga@arm.com *uop++ = new MicroStrDFpXImmUop(machInst, rt, rt2, 30210346Smitch.hayenga@arm.com post ? rn : INTREG_UREG0, 0, noAlloc, exclusive, acrel); 30310037SARM gem5 Developers } 30410037SARM gem5 Developers } 30510037SARM gem5 Developers } else { 30610037SARM gem5 Developers if (size == 8) { 30710037SARM gem5 Developers if (load) { 30810346Smitch.hayenga@arm.com *uop++ = new MicroLdPairUop(machInst, rt, rt2, 30910346Smitch.hayenga@arm.com post ? rn : INTREG_UREG0, 0, noAlloc, exclusive, acrel); 31010346Smitch.hayenga@arm.com } else { 31110346Smitch.hayenga@arm.com *uop++ = new MicroStrXImmUop(machInst, rt, post ? rn : INTREG_UREG0, 31210037SARM gem5 Developers 0, noAlloc, exclusive, acrel); 31310346Smitch.hayenga@arm.com *uop++ = new MicroStrXImmUop(machInst, rt2, post ? rn : INTREG_UREG0, 31410037SARM gem5 Developers size, noAlloc, exclusive, acrel); 31510037SARM gem5 Developers } 31610037SARM gem5 Developers } else if (size == 4) { 31710037SARM gem5 Developers if (load) { 31810037SARM gem5 Developers if (signExt) { 31910346Smitch.hayenga@arm.com *uop++ = new MicroLdrDSXImmUop(machInst, rt, rt2, 32010346Smitch.hayenga@arm.com post ? rn : INTREG_UREG0, 0, noAlloc, exclusive, acrel); 32110037SARM gem5 Developers } else { 32210346Smitch.hayenga@arm.com *uop++ = new MicroLdrDUXImmUop(machInst, rt, rt2, 32310346Smitch.hayenga@arm.com post ? rn : INTREG_UREG0, 0, noAlloc, exclusive, acrel); 32410037SARM gem5 Developers } 32510037SARM gem5 Developers } else { 32610346Smitch.hayenga@arm.com *uop++ = new MicroStrDXImmUop(machInst, rt, rt2, 32710346Smitch.hayenga@arm.com post ? rn : INTREG_UREG0, 0, noAlloc, exclusive, acrel); 32810037SARM gem5 Developers } 32910037SARM gem5 Developers } 33010037SARM gem5 Developers } 33110037SARM gem5 Developers 33210037SARM gem5 Developers if (writeback) { 33310346Smitch.hayenga@arm.com *uop++ = new MicroAddXiUop(machInst, rn, post ? rn : INTREG_UREG0, 33410037SARM gem5 Developers post ? imm : 0); 33510037SARM gem5 Developers } 33610037SARM gem5 Developers 33710346Smitch.hayenga@arm.com assert(uop == µOps[numMicroops]); 33810346Smitch.hayenga@arm.com (*--uop)->setLastMicroop(); 33910666SAli.Saidi@ARM.com microOps[0]->setFirstMicroop(); 34010037SARM gem5 Developers 34110037SARM gem5 Developers for (StaticInstPtr *curUop = microOps; 34210037SARM gem5 Developers !(*curUop)->isLastMicroop(); curUop++) { 34310037SARM gem5 Developers (*curUop)->setDelayedCommit(); 34410037SARM gem5 Developers } 34510037SARM gem5 Developers} 34610037SARM gem5 Developers 34710037SARM gem5 DevelopersBigFpMemImmOp::BigFpMemImmOp(const char *mnem, ExtMachInst machInst, 34810037SARM gem5 Developers OpClass __opClass, bool load, IntRegIndex dest, 34910037SARM gem5 Developers IntRegIndex base, int64_t imm) : 35010037SARM gem5 Developers PredMacroOp(mnem, machInst, __opClass) 35110037SARM gem5 Developers{ 35210346Smitch.hayenga@arm.com numMicroops = load ? 1 : 2; 35310037SARM gem5 Developers microOps = new StaticInstPtr[numMicroops]; 35410037SARM gem5 Developers 35510346Smitch.hayenga@arm.com StaticInstPtr *uop = microOps; 35610346Smitch.hayenga@arm.com 35710037SARM gem5 Developers if (load) { 35810346Smitch.hayenga@arm.com *uop = new MicroLdFp16Uop(machInst, dest, base, imm); 35910037SARM gem5 Developers } else { 36010346Smitch.hayenga@arm.com *uop = new MicroStrQBFpXImmUop(machInst, dest, base, imm); 36110346Smitch.hayenga@arm.com (*uop)->setDelayedCommit(); 36210346Smitch.hayenga@arm.com *++uop = new MicroStrQTFpXImmUop(machInst, dest, base, imm); 36310037SARM gem5 Developers } 36410346Smitch.hayenga@arm.com (*uop)->setLastMicroop(); 36510666SAli.Saidi@ARM.com microOps[0]->setFirstMicroop(); 36610037SARM gem5 Developers} 36710037SARM gem5 Developers 36810037SARM gem5 DevelopersBigFpMemPostOp::BigFpMemPostOp(const char *mnem, ExtMachInst machInst, 36910037SARM gem5 Developers OpClass __opClass, bool load, IntRegIndex dest, 37010037SARM gem5 Developers IntRegIndex base, int64_t imm) : 37110037SARM gem5 Developers PredMacroOp(mnem, machInst, __opClass) 37210037SARM gem5 Developers{ 37310346Smitch.hayenga@arm.com numMicroops = load ? 2 : 3; 37410037SARM gem5 Developers microOps = new StaticInstPtr[numMicroops]; 37510037SARM gem5 Developers 37610346Smitch.hayenga@arm.com StaticInstPtr *uop = microOps; 37710346Smitch.hayenga@arm.com 37810037SARM gem5 Developers if (load) { 37910346Smitch.hayenga@arm.com *uop++ = new MicroLdFp16Uop(machInst, dest, base, 0); 38010037SARM gem5 Developers } else { 38110346Smitch.hayenga@arm.com *uop++= new MicroStrQBFpXImmUop(machInst, dest, base, 0); 38210346Smitch.hayenga@arm.com *uop++ = new MicroStrQTFpXImmUop(machInst, dest, base, 0); 38310037SARM gem5 Developers } 38410346Smitch.hayenga@arm.com *uop = new MicroAddXiUop(machInst, base, base, imm); 38510346Smitch.hayenga@arm.com (*uop)->setLastMicroop(); 38610666SAli.Saidi@ARM.com microOps[0]->setFirstMicroop(); 38710037SARM gem5 Developers 38810346Smitch.hayenga@arm.com for (StaticInstPtr *curUop = microOps; 38910346Smitch.hayenga@arm.com !(*curUop)->isLastMicroop(); curUop++) { 39010346Smitch.hayenga@arm.com (*curUop)->setDelayedCommit(); 39110346Smitch.hayenga@arm.com } 39210037SARM gem5 Developers} 39310037SARM gem5 Developers 39410037SARM gem5 DevelopersBigFpMemPreOp::BigFpMemPreOp(const char *mnem, ExtMachInst machInst, 39510037SARM gem5 Developers OpClass __opClass, bool load, IntRegIndex dest, 39610037SARM gem5 Developers IntRegIndex base, int64_t imm) : 39710037SARM gem5 Developers PredMacroOp(mnem, machInst, __opClass) 39810037SARM gem5 Developers{ 39910346Smitch.hayenga@arm.com numMicroops = load ? 2 : 3; 40010037SARM gem5 Developers microOps = new StaticInstPtr[numMicroops]; 40110037SARM gem5 Developers 40210346Smitch.hayenga@arm.com StaticInstPtr *uop = microOps; 40310346Smitch.hayenga@arm.com 40410037SARM gem5 Developers if (load) { 40510346Smitch.hayenga@arm.com *uop++ = new MicroLdFp16Uop(machInst, dest, base, imm); 40610037SARM gem5 Developers } else { 40710346Smitch.hayenga@arm.com *uop++ = new MicroStrQBFpXImmUop(machInst, dest, base, imm); 40810346Smitch.hayenga@arm.com *uop++ = new MicroStrQTFpXImmUop(machInst, dest, base, imm); 40910037SARM gem5 Developers } 41010346Smitch.hayenga@arm.com *uop = new MicroAddXiUop(machInst, base, base, imm); 41110346Smitch.hayenga@arm.com (*uop)->setLastMicroop(); 41210666SAli.Saidi@ARM.com microOps[0]->setFirstMicroop(); 41310037SARM gem5 Developers 41410346Smitch.hayenga@arm.com for (StaticInstPtr *curUop = microOps; 41510346Smitch.hayenga@arm.com !(*curUop)->isLastMicroop(); curUop++) { 41610346Smitch.hayenga@arm.com (*curUop)->setDelayedCommit(); 41710346Smitch.hayenga@arm.com } 41810037SARM gem5 Developers} 41910037SARM gem5 Developers 42010037SARM gem5 DevelopersBigFpMemRegOp::BigFpMemRegOp(const char *mnem, ExtMachInst machInst, 42110037SARM gem5 Developers OpClass __opClass, bool load, IntRegIndex dest, 42210037SARM gem5 Developers IntRegIndex base, IntRegIndex offset, 42310037SARM gem5 Developers ArmExtendType type, int64_t imm) : 42410037SARM gem5 Developers PredMacroOp(mnem, machInst, __opClass) 42510037SARM gem5 Developers{ 42610346Smitch.hayenga@arm.com numMicroops = load ? 1 : 2; 42710037SARM gem5 Developers microOps = new StaticInstPtr[numMicroops]; 42810037SARM gem5 Developers 42910346Smitch.hayenga@arm.com StaticInstPtr *uop = microOps; 43010346Smitch.hayenga@arm.com 43110037SARM gem5 Developers if (load) { 43210346Smitch.hayenga@arm.com *uop = new MicroLdFp16RegUop(machInst, dest, base, 43310346Smitch.hayenga@arm.com offset, type, imm); 43410037SARM gem5 Developers } else { 43510346Smitch.hayenga@arm.com *uop = new MicroStrQBFpXRegUop(machInst, dest, base, 43610346Smitch.hayenga@arm.com offset, type, imm); 43710346Smitch.hayenga@arm.com (*uop)->setDelayedCommit(); 43810346Smitch.hayenga@arm.com *++uop = new MicroStrQTFpXRegUop(machInst, dest, base, 43910346Smitch.hayenga@arm.com offset, type, imm); 44010037SARM gem5 Developers } 44110037SARM gem5 Developers 44210346Smitch.hayenga@arm.com (*uop)->setLastMicroop(); 44310666SAli.Saidi@ARM.com microOps[0]->setFirstMicroop(); 44410037SARM gem5 Developers} 44510037SARM gem5 Developers 44610037SARM gem5 DevelopersBigFpMemLitOp::BigFpMemLitOp(const char *mnem, ExtMachInst machInst, 44710037SARM gem5 Developers OpClass __opClass, IntRegIndex dest, 44810037SARM gem5 Developers int64_t imm) : 44910037SARM gem5 Developers PredMacroOp(mnem, machInst, __opClass) 45010037SARM gem5 Developers{ 45110346Smitch.hayenga@arm.com numMicroops = 1; 45210037SARM gem5 Developers microOps = new StaticInstPtr[numMicroops]; 45310037SARM gem5 Developers 45410346Smitch.hayenga@arm.com microOps[0] = new MicroLdFp16LitUop(machInst, dest, imm); 45510346Smitch.hayenga@arm.com microOps[0]->setLastMicroop(); 45610666SAli.Saidi@ARM.com microOps[0]->setFirstMicroop(); 45710037SARM gem5 Developers} 45810037SARM gem5 Developers 4597639Sgblack@eecs.umich.eduVldMultOp::VldMultOp(const char *mnem, ExtMachInst machInst, OpClass __opClass, 4607639Sgblack@eecs.umich.edu unsigned elems, RegIndex rn, RegIndex vd, unsigned regs, 4617639Sgblack@eecs.umich.edu unsigned inc, uint32_t size, uint32_t align, RegIndex rm) : 4627639Sgblack@eecs.umich.edu PredMacroOp(mnem, machInst, __opClass) 4637639Sgblack@eecs.umich.edu{ 4647639Sgblack@eecs.umich.edu assert(regs > 0 && regs <= 4); 4657639Sgblack@eecs.umich.edu assert(regs % elems == 0); 4667639Sgblack@eecs.umich.edu 4677639Sgblack@eecs.umich.edu numMicroops = (regs > 2) ? 2 : 1; 4687639Sgblack@eecs.umich.edu bool wb = (rm != 15); 4697639Sgblack@eecs.umich.edu bool deinterleave = (elems > 1); 4707639Sgblack@eecs.umich.edu 4717639Sgblack@eecs.umich.edu if (wb) numMicroops++; 4727639Sgblack@eecs.umich.edu if (deinterleave) numMicroops += (regs / elems); 4737639Sgblack@eecs.umich.edu microOps = new StaticInstPtr[numMicroops]; 4747639Sgblack@eecs.umich.edu 47510037SARM gem5 Developers RegIndex rMid = deinterleave ? NumFloatV7ArchRegs : vd * 2; 4767639Sgblack@eecs.umich.edu 4777639Sgblack@eecs.umich.edu uint32_t noAlign = TLB::MustBeOne; 4787639Sgblack@eecs.umich.edu 4797639Sgblack@eecs.umich.edu unsigned uopIdx = 0; 4807639Sgblack@eecs.umich.edu switch (regs) { 4817639Sgblack@eecs.umich.edu case 4: 4827639Sgblack@eecs.umich.edu microOps[uopIdx++] = newNeonMemInst<MicroLdrNeon16Uop>( 4837639Sgblack@eecs.umich.edu size, machInst, rMid, rn, 0, align); 4847639Sgblack@eecs.umich.edu microOps[uopIdx++] = newNeonMemInst<MicroLdrNeon16Uop>( 4857639Sgblack@eecs.umich.edu size, machInst, rMid + 4, rn, 16, noAlign); 4867639Sgblack@eecs.umich.edu break; 4877639Sgblack@eecs.umich.edu case 3: 4887639Sgblack@eecs.umich.edu microOps[uopIdx++] = newNeonMemInst<MicroLdrNeon16Uop>( 4897639Sgblack@eecs.umich.edu size, machInst, rMid, rn, 0, align); 4907639Sgblack@eecs.umich.edu microOps[uopIdx++] = newNeonMemInst<MicroLdrNeon8Uop>( 4917639Sgblack@eecs.umich.edu size, machInst, rMid + 4, rn, 16, noAlign); 4927639Sgblack@eecs.umich.edu break; 4937639Sgblack@eecs.umich.edu case 2: 4947639Sgblack@eecs.umich.edu microOps[uopIdx++] = newNeonMemInst<MicroLdrNeon16Uop>( 4957639Sgblack@eecs.umich.edu size, machInst, rMid, rn, 0, align); 4967639Sgblack@eecs.umich.edu break; 4977639Sgblack@eecs.umich.edu case 1: 4987639Sgblack@eecs.umich.edu microOps[uopIdx++] = newNeonMemInst<MicroLdrNeon8Uop>( 4997639Sgblack@eecs.umich.edu size, machInst, rMid, rn, 0, align); 5007639Sgblack@eecs.umich.edu break; 5017639Sgblack@eecs.umich.edu default: 5027853SMatt.Horsnell@ARM.com // Unknown number of registers 5037853SMatt.Horsnell@ARM.com microOps[uopIdx++] = new Unknown(machInst); 5047639Sgblack@eecs.umich.edu } 5057639Sgblack@eecs.umich.edu if (wb) { 5067639Sgblack@eecs.umich.edu if (rm != 15 && rm != 13) { 5077639Sgblack@eecs.umich.edu microOps[uopIdx++] = 5087646Sgene.wu@arm.com new MicroAddUop(machInst, rn, rn, rm, 0, ArmISA::LSL); 5097639Sgblack@eecs.umich.edu } else { 5107639Sgblack@eecs.umich.edu microOps[uopIdx++] = 5117639Sgblack@eecs.umich.edu new MicroAddiUop(machInst, rn, rn, regs * 8); 5127639Sgblack@eecs.umich.edu } 5137639Sgblack@eecs.umich.edu } 5147639Sgblack@eecs.umich.edu if (deinterleave) { 5157639Sgblack@eecs.umich.edu switch (elems) { 5167639Sgblack@eecs.umich.edu case 4: 5177639Sgblack@eecs.umich.edu assert(regs == 4); 5187639Sgblack@eecs.umich.edu microOps[uopIdx++] = newNeonMixInst<MicroDeintNeon8Uop>( 5197639Sgblack@eecs.umich.edu size, machInst, vd * 2, rMid, inc * 2); 5207639Sgblack@eecs.umich.edu break; 5217639Sgblack@eecs.umich.edu case 3: 5227639Sgblack@eecs.umich.edu assert(regs == 3); 5237639Sgblack@eecs.umich.edu microOps[uopIdx++] = newNeonMixInst<MicroDeintNeon6Uop>( 5247639Sgblack@eecs.umich.edu size, machInst, vd * 2, rMid, inc * 2); 5257639Sgblack@eecs.umich.edu break; 5267639Sgblack@eecs.umich.edu case 2: 5277639Sgblack@eecs.umich.edu assert(regs == 4 || regs == 2); 5287639Sgblack@eecs.umich.edu if (regs == 4) { 5297639Sgblack@eecs.umich.edu microOps[uopIdx++] = newNeonMixInst<MicroDeintNeon4Uop>( 5307639Sgblack@eecs.umich.edu size, machInst, vd * 2, rMid, inc * 2); 5317639Sgblack@eecs.umich.edu microOps[uopIdx++] = newNeonMixInst<MicroDeintNeon4Uop>( 5327639Sgblack@eecs.umich.edu size, machInst, vd * 2 + 2, rMid + 4, inc * 2); 5337639Sgblack@eecs.umich.edu } else { 5347639Sgblack@eecs.umich.edu microOps[uopIdx++] = newNeonMixInst<MicroDeintNeon4Uop>( 5357639Sgblack@eecs.umich.edu size, machInst, vd * 2, rMid, inc * 2); 5367639Sgblack@eecs.umich.edu } 5377639Sgblack@eecs.umich.edu break; 5387639Sgblack@eecs.umich.edu default: 5397853SMatt.Horsnell@ARM.com // Bad number of elements to deinterleave 5407853SMatt.Horsnell@ARM.com microOps[uopIdx++] = new Unknown(machInst); 5417639Sgblack@eecs.umich.edu } 5427639Sgblack@eecs.umich.edu } 5437639Sgblack@eecs.umich.edu assert(uopIdx == numMicroops); 5447639Sgblack@eecs.umich.edu 5457639Sgblack@eecs.umich.edu for (unsigned i = 0; i < numMicroops - 1; i++) { 5467639Sgblack@eecs.umich.edu MicroOp * uopPtr = dynamic_cast<MicroOp *>(microOps[i].get()); 5477639Sgblack@eecs.umich.edu assert(uopPtr); 5487639Sgblack@eecs.umich.edu uopPtr->setDelayedCommit(); 5497639Sgblack@eecs.umich.edu } 55010666SAli.Saidi@ARM.com microOps[0]->setFirstMicroop(); 5517639Sgblack@eecs.umich.edu microOps[numMicroops - 1]->setLastMicroop(); 5527639Sgblack@eecs.umich.edu} 5537639Sgblack@eecs.umich.edu 5547639Sgblack@eecs.umich.eduVldSingleOp::VldSingleOp(const char *mnem, ExtMachInst machInst, 5557639Sgblack@eecs.umich.edu OpClass __opClass, bool all, unsigned elems, 5567639Sgblack@eecs.umich.edu RegIndex rn, RegIndex vd, unsigned regs, 5577639Sgblack@eecs.umich.edu unsigned inc, uint32_t size, uint32_t align, 5587639Sgblack@eecs.umich.edu RegIndex rm, unsigned lane) : 5597639Sgblack@eecs.umich.edu PredMacroOp(mnem, machInst, __opClass) 5607639Sgblack@eecs.umich.edu{ 5617639Sgblack@eecs.umich.edu assert(regs > 0 && regs <= 4); 5627639Sgblack@eecs.umich.edu assert(regs % elems == 0); 5637639Sgblack@eecs.umich.edu 5647639Sgblack@eecs.umich.edu unsigned eBytes = (1 << size); 5657639Sgblack@eecs.umich.edu unsigned loadSize = eBytes * elems; 5667639Sgblack@eecs.umich.edu unsigned loadRegs M5_VAR_USED = (loadSize + sizeof(FloatRegBits) - 1) / 5677639Sgblack@eecs.umich.edu sizeof(FloatRegBits); 5687639Sgblack@eecs.umich.edu 5697639Sgblack@eecs.umich.edu assert(loadRegs > 0 && loadRegs <= 4); 5707639Sgblack@eecs.umich.edu 5717639Sgblack@eecs.umich.edu numMicroops = 1; 5727639Sgblack@eecs.umich.edu bool wb = (rm != 15); 5737639Sgblack@eecs.umich.edu 5747639Sgblack@eecs.umich.edu if (wb) numMicroops++; 5757639Sgblack@eecs.umich.edu numMicroops += (regs / elems); 5767639Sgblack@eecs.umich.edu microOps = new StaticInstPtr[numMicroops]; 5777639Sgblack@eecs.umich.edu 57810037SARM gem5 Developers RegIndex ufp0 = NumFloatV7ArchRegs; 5797639Sgblack@eecs.umich.edu 5807639Sgblack@eecs.umich.edu unsigned uopIdx = 0; 5817639Sgblack@eecs.umich.edu switch (loadSize) { 5827639Sgblack@eecs.umich.edu case 1: 5837639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroLdrNeon1Uop<uint8_t>( 5847639Sgblack@eecs.umich.edu machInst, ufp0, rn, 0, align); 5857639Sgblack@eecs.umich.edu break; 5867639Sgblack@eecs.umich.edu case 2: 5877639Sgblack@eecs.umich.edu if (eBytes == 2) { 5887639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroLdrNeon2Uop<uint16_t>( 5897639Sgblack@eecs.umich.edu machInst, ufp0, rn, 0, align); 5907639Sgblack@eecs.umich.edu } else { 5917639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroLdrNeon2Uop<uint8_t>( 5927639Sgblack@eecs.umich.edu machInst, ufp0, rn, 0, align); 5937639Sgblack@eecs.umich.edu } 5947639Sgblack@eecs.umich.edu break; 5957639Sgblack@eecs.umich.edu case 3: 5967639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroLdrNeon3Uop<uint8_t>( 5977639Sgblack@eecs.umich.edu machInst, ufp0, rn, 0, align); 5987639Sgblack@eecs.umich.edu break; 5997639Sgblack@eecs.umich.edu case 4: 6007639Sgblack@eecs.umich.edu switch (eBytes) { 6017639Sgblack@eecs.umich.edu case 1: 6027639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroLdrNeon4Uop<uint8_t>( 6037639Sgblack@eecs.umich.edu machInst, ufp0, rn, 0, align); 6047639Sgblack@eecs.umich.edu break; 6057639Sgblack@eecs.umich.edu case 2: 6067639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroLdrNeon4Uop<uint16_t>( 6077639Sgblack@eecs.umich.edu machInst, ufp0, rn, 0, align); 6087639Sgblack@eecs.umich.edu break; 6097639Sgblack@eecs.umich.edu case 4: 6107639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroLdrNeon4Uop<uint32_t>( 6117639Sgblack@eecs.umich.edu machInst, ufp0, rn, 0, align); 6127639Sgblack@eecs.umich.edu break; 6137639Sgblack@eecs.umich.edu } 6147639Sgblack@eecs.umich.edu break; 6157639Sgblack@eecs.umich.edu case 6: 6167639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroLdrNeon6Uop<uint16_t>( 6177639Sgblack@eecs.umich.edu machInst, ufp0, rn, 0, align); 6187639Sgblack@eecs.umich.edu break; 6197639Sgblack@eecs.umich.edu case 8: 6207639Sgblack@eecs.umich.edu switch (eBytes) { 6217639Sgblack@eecs.umich.edu case 2: 6227639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroLdrNeon8Uop<uint16_t>( 6237639Sgblack@eecs.umich.edu machInst, ufp0, rn, 0, align); 6247639Sgblack@eecs.umich.edu break; 6257639Sgblack@eecs.umich.edu case 4: 6267639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroLdrNeon8Uop<uint32_t>( 6277639Sgblack@eecs.umich.edu machInst, ufp0, rn, 0, align); 6287639Sgblack@eecs.umich.edu break; 6297639Sgblack@eecs.umich.edu } 6307639Sgblack@eecs.umich.edu break; 6317639Sgblack@eecs.umich.edu case 12: 6327639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroLdrNeon12Uop<uint32_t>( 6337639Sgblack@eecs.umich.edu machInst, ufp0, rn, 0, align); 6347639Sgblack@eecs.umich.edu break; 6357639Sgblack@eecs.umich.edu case 16: 6367639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroLdrNeon16Uop<uint32_t>( 6377639Sgblack@eecs.umich.edu machInst, ufp0, rn, 0, align); 6387639Sgblack@eecs.umich.edu break; 6397639Sgblack@eecs.umich.edu default: 6407853SMatt.Horsnell@ARM.com // Unrecognized load size 6417853SMatt.Horsnell@ARM.com microOps[uopIdx++] = new Unknown(machInst); 6427639Sgblack@eecs.umich.edu } 6437639Sgblack@eecs.umich.edu if (wb) { 6447639Sgblack@eecs.umich.edu if (rm != 15 && rm != 13) { 6457639Sgblack@eecs.umich.edu microOps[uopIdx++] = 6467646Sgene.wu@arm.com new MicroAddUop(machInst, rn, rn, rm, 0, ArmISA::LSL); 6477639Sgblack@eecs.umich.edu } else { 6487639Sgblack@eecs.umich.edu microOps[uopIdx++] = 6497639Sgblack@eecs.umich.edu new MicroAddiUop(machInst, rn, rn, loadSize); 6507639Sgblack@eecs.umich.edu } 6517639Sgblack@eecs.umich.edu } 6527639Sgblack@eecs.umich.edu switch (elems) { 6537639Sgblack@eecs.umich.edu case 4: 6547639Sgblack@eecs.umich.edu assert(regs == 4); 6557639Sgblack@eecs.umich.edu switch (size) { 6567639Sgblack@eecs.umich.edu case 0: 6577639Sgblack@eecs.umich.edu if (all) { 6587639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroUnpackAllNeon2to8Uop<uint8_t>( 6597639Sgblack@eecs.umich.edu machInst, vd * 2, ufp0, inc * 2); 6607639Sgblack@eecs.umich.edu } else { 6617639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroUnpackNeon2to8Uop<uint8_t>( 6627639Sgblack@eecs.umich.edu machInst, vd * 2, ufp0, inc * 2, lane); 6637639Sgblack@eecs.umich.edu } 6647639Sgblack@eecs.umich.edu break; 6657639Sgblack@eecs.umich.edu case 1: 6667639Sgblack@eecs.umich.edu if (all) { 6677639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroUnpackAllNeon2to8Uop<uint16_t>( 6687639Sgblack@eecs.umich.edu machInst, vd * 2, ufp0, inc * 2); 6697639Sgblack@eecs.umich.edu } else { 6707639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroUnpackNeon2to8Uop<uint16_t>( 6717639Sgblack@eecs.umich.edu machInst, vd * 2, ufp0, inc * 2, lane); 6727639Sgblack@eecs.umich.edu } 6737639Sgblack@eecs.umich.edu break; 6747639Sgblack@eecs.umich.edu case 2: 6757639Sgblack@eecs.umich.edu if (all) { 6767639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroUnpackAllNeon4to8Uop<uint32_t>( 6777639Sgblack@eecs.umich.edu machInst, vd * 2, ufp0, inc * 2); 6787639Sgblack@eecs.umich.edu } else { 6797639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroUnpackNeon4to8Uop<uint32_t>( 6807639Sgblack@eecs.umich.edu machInst, vd * 2, ufp0, inc * 2, lane); 6817639Sgblack@eecs.umich.edu } 6827639Sgblack@eecs.umich.edu break; 6837639Sgblack@eecs.umich.edu default: 6847853SMatt.Horsnell@ARM.com // Bad size 6857853SMatt.Horsnell@ARM.com microOps[uopIdx++] = new Unknown(machInst); 6867639Sgblack@eecs.umich.edu break; 6877639Sgblack@eecs.umich.edu } 6887639Sgblack@eecs.umich.edu break; 6897639Sgblack@eecs.umich.edu case 3: 6907639Sgblack@eecs.umich.edu assert(regs == 3); 6917639Sgblack@eecs.umich.edu switch (size) { 6927639Sgblack@eecs.umich.edu case 0: 6937639Sgblack@eecs.umich.edu if (all) { 6947639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroUnpackAllNeon2to6Uop<uint8_t>( 6957639Sgblack@eecs.umich.edu machInst, vd * 2, ufp0, inc * 2); 6967639Sgblack@eecs.umich.edu } else { 6977639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroUnpackNeon2to6Uop<uint8_t>( 6987639Sgblack@eecs.umich.edu machInst, vd * 2, ufp0, inc * 2, lane); 6997639Sgblack@eecs.umich.edu } 7007639Sgblack@eecs.umich.edu break; 7017639Sgblack@eecs.umich.edu case 1: 7027639Sgblack@eecs.umich.edu if (all) { 7037639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroUnpackAllNeon2to6Uop<uint16_t>( 7047639Sgblack@eecs.umich.edu machInst, vd * 2, ufp0, inc * 2); 7057639Sgblack@eecs.umich.edu } else { 7067639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroUnpackNeon2to6Uop<uint16_t>( 7077639Sgblack@eecs.umich.edu machInst, vd * 2, ufp0, inc * 2, lane); 7087639Sgblack@eecs.umich.edu } 7097639Sgblack@eecs.umich.edu break; 7107639Sgblack@eecs.umich.edu case 2: 7117639Sgblack@eecs.umich.edu if (all) { 7127639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroUnpackAllNeon4to6Uop<uint32_t>( 7137639Sgblack@eecs.umich.edu machInst, vd * 2, ufp0, inc * 2); 7147639Sgblack@eecs.umich.edu } else { 7157639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroUnpackNeon4to6Uop<uint32_t>( 7167639Sgblack@eecs.umich.edu machInst, vd * 2, ufp0, inc * 2, lane); 7177639Sgblack@eecs.umich.edu } 7187639Sgblack@eecs.umich.edu break; 7197639Sgblack@eecs.umich.edu default: 7207853SMatt.Horsnell@ARM.com // Bad size 7217853SMatt.Horsnell@ARM.com microOps[uopIdx++] = new Unknown(machInst); 7227639Sgblack@eecs.umich.edu break; 7237639Sgblack@eecs.umich.edu } 7247639Sgblack@eecs.umich.edu break; 7257639Sgblack@eecs.umich.edu case 2: 7267639Sgblack@eecs.umich.edu assert(regs == 2); 7277639Sgblack@eecs.umich.edu assert(loadRegs <= 2); 7287639Sgblack@eecs.umich.edu switch (size) { 7297639Sgblack@eecs.umich.edu case 0: 7307639Sgblack@eecs.umich.edu if (all) { 7317639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroUnpackAllNeon2to4Uop<uint8_t>( 7327639Sgblack@eecs.umich.edu machInst, vd * 2, ufp0, inc * 2); 7337639Sgblack@eecs.umich.edu } else { 7347639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroUnpackNeon2to4Uop<uint8_t>( 7357639Sgblack@eecs.umich.edu machInst, vd * 2, ufp0, inc * 2, lane); 7367639Sgblack@eecs.umich.edu } 7377639Sgblack@eecs.umich.edu break; 7387639Sgblack@eecs.umich.edu case 1: 7397639Sgblack@eecs.umich.edu if (all) { 7407639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroUnpackAllNeon2to4Uop<uint16_t>( 7417639Sgblack@eecs.umich.edu machInst, vd * 2, ufp0, inc * 2); 7427639Sgblack@eecs.umich.edu } else { 7437639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroUnpackNeon2to4Uop<uint16_t>( 7447639Sgblack@eecs.umich.edu machInst, vd * 2, ufp0, inc * 2, lane); 7457639Sgblack@eecs.umich.edu } 7467639Sgblack@eecs.umich.edu break; 7477639Sgblack@eecs.umich.edu case 2: 7487639Sgblack@eecs.umich.edu if (all) { 7497639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroUnpackAllNeon2to4Uop<uint32_t>( 7507639Sgblack@eecs.umich.edu machInst, vd * 2, ufp0, inc * 2); 7517639Sgblack@eecs.umich.edu } else { 7527639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroUnpackNeon2to4Uop<uint32_t>( 7537639Sgblack@eecs.umich.edu machInst, vd * 2, ufp0, inc * 2, lane); 7547639Sgblack@eecs.umich.edu } 7557639Sgblack@eecs.umich.edu break; 7567639Sgblack@eecs.umich.edu default: 7577853SMatt.Horsnell@ARM.com // Bad size 7587853SMatt.Horsnell@ARM.com microOps[uopIdx++] = new Unknown(machInst); 7597639Sgblack@eecs.umich.edu break; 7607639Sgblack@eecs.umich.edu } 7617639Sgblack@eecs.umich.edu break; 7627639Sgblack@eecs.umich.edu case 1: 7637639Sgblack@eecs.umich.edu assert(regs == 1 || (all && regs == 2)); 7647639Sgblack@eecs.umich.edu assert(loadRegs <= 2); 7657639Sgblack@eecs.umich.edu for (unsigned offset = 0; offset < regs; offset++) { 7667639Sgblack@eecs.umich.edu switch (size) { 7677639Sgblack@eecs.umich.edu case 0: 7687639Sgblack@eecs.umich.edu if (all) { 7697639Sgblack@eecs.umich.edu microOps[uopIdx++] = 7707639Sgblack@eecs.umich.edu new MicroUnpackAllNeon2to2Uop<uint8_t>( 7717639Sgblack@eecs.umich.edu machInst, (vd + offset) * 2, ufp0, inc * 2); 7727639Sgblack@eecs.umich.edu } else { 7737639Sgblack@eecs.umich.edu microOps[uopIdx++] = 7747639Sgblack@eecs.umich.edu new MicroUnpackNeon2to2Uop<uint8_t>( 7757639Sgblack@eecs.umich.edu machInst, (vd + offset) * 2, ufp0, inc * 2, lane); 7767639Sgblack@eecs.umich.edu } 7777639Sgblack@eecs.umich.edu break; 7787639Sgblack@eecs.umich.edu case 1: 7797639Sgblack@eecs.umich.edu if (all) { 7807639Sgblack@eecs.umich.edu microOps[uopIdx++] = 7817639Sgblack@eecs.umich.edu new MicroUnpackAllNeon2to2Uop<uint16_t>( 7827639Sgblack@eecs.umich.edu machInst, (vd + offset) * 2, ufp0, inc * 2); 7837639Sgblack@eecs.umich.edu } else { 7847639Sgblack@eecs.umich.edu microOps[uopIdx++] = 7857639Sgblack@eecs.umich.edu new MicroUnpackNeon2to2Uop<uint16_t>( 7867639Sgblack@eecs.umich.edu machInst, (vd + offset) * 2, ufp0, inc * 2, lane); 7877639Sgblack@eecs.umich.edu } 7887639Sgblack@eecs.umich.edu break; 7897639Sgblack@eecs.umich.edu case 2: 7907639Sgblack@eecs.umich.edu if (all) { 7917639Sgblack@eecs.umich.edu microOps[uopIdx++] = 7927639Sgblack@eecs.umich.edu new MicroUnpackAllNeon2to2Uop<uint32_t>( 7937639Sgblack@eecs.umich.edu machInst, (vd + offset) * 2, ufp0, inc * 2); 7947639Sgblack@eecs.umich.edu } else { 7957639Sgblack@eecs.umich.edu microOps[uopIdx++] = 7967639Sgblack@eecs.umich.edu new MicroUnpackNeon2to2Uop<uint32_t>( 7977639Sgblack@eecs.umich.edu machInst, (vd + offset) * 2, ufp0, inc * 2, lane); 7987639Sgblack@eecs.umich.edu } 7997639Sgblack@eecs.umich.edu break; 8007639Sgblack@eecs.umich.edu default: 8017853SMatt.Horsnell@ARM.com // Bad size 8027853SMatt.Horsnell@ARM.com microOps[uopIdx++] = new Unknown(machInst); 8037639Sgblack@eecs.umich.edu break; 8047639Sgblack@eecs.umich.edu } 8057639Sgblack@eecs.umich.edu } 8067639Sgblack@eecs.umich.edu break; 8077639Sgblack@eecs.umich.edu default: 8087853SMatt.Horsnell@ARM.com // Bad number of elements to unpack 8097853SMatt.Horsnell@ARM.com microOps[uopIdx++] = new Unknown(machInst); 8107639Sgblack@eecs.umich.edu } 8117639Sgblack@eecs.umich.edu assert(uopIdx == numMicroops); 8127639Sgblack@eecs.umich.edu 8137639Sgblack@eecs.umich.edu for (unsigned i = 0; i < numMicroops - 1; i++) { 8147639Sgblack@eecs.umich.edu MicroOp * uopPtr = dynamic_cast<MicroOp *>(microOps[i].get()); 8157639Sgblack@eecs.umich.edu assert(uopPtr); 8167639Sgblack@eecs.umich.edu uopPtr->setDelayedCommit(); 8177639Sgblack@eecs.umich.edu } 81810666SAli.Saidi@ARM.com microOps[0]->setFirstMicroop(); 8197639Sgblack@eecs.umich.edu microOps[numMicroops - 1]->setLastMicroop(); 8207639Sgblack@eecs.umich.edu} 8217639Sgblack@eecs.umich.edu 8227639Sgblack@eecs.umich.eduVstMultOp::VstMultOp(const char *mnem, ExtMachInst machInst, OpClass __opClass, 8237639Sgblack@eecs.umich.edu unsigned elems, RegIndex rn, RegIndex vd, unsigned regs, 8247639Sgblack@eecs.umich.edu unsigned inc, uint32_t size, uint32_t align, RegIndex rm) : 8257639Sgblack@eecs.umich.edu PredMacroOp(mnem, machInst, __opClass) 8267639Sgblack@eecs.umich.edu{ 8277639Sgblack@eecs.umich.edu assert(regs > 0 && regs <= 4); 8287639Sgblack@eecs.umich.edu assert(regs % elems == 0); 8297639Sgblack@eecs.umich.edu 8307639Sgblack@eecs.umich.edu numMicroops = (regs > 2) ? 2 : 1; 8317639Sgblack@eecs.umich.edu bool wb = (rm != 15); 8327639Sgblack@eecs.umich.edu bool interleave = (elems > 1); 8337639Sgblack@eecs.umich.edu 8347639Sgblack@eecs.umich.edu if (wb) numMicroops++; 8357639Sgblack@eecs.umich.edu if (interleave) numMicroops += (regs / elems); 8367639Sgblack@eecs.umich.edu microOps = new StaticInstPtr[numMicroops]; 8377639Sgblack@eecs.umich.edu 8387639Sgblack@eecs.umich.edu uint32_t noAlign = TLB::MustBeOne; 8397639Sgblack@eecs.umich.edu 84010037SARM gem5 Developers RegIndex rMid = interleave ? NumFloatV7ArchRegs : vd * 2; 8417639Sgblack@eecs.umich.edu 8427639Sgblack@eecs.umich.edu unsigned uopIdx = 0; 8437639Sgblack@eecs.umich.edu if (interleave) { 8447639Sgblack@eecs.umich.edu switch (elems) { 8457639Sgblack@eecs.umich.edu case 4: 8467639Sgblack@eecs.umich.edu assert(regs == 4); 8477639Sgblack@eecs.umich.edu microOps[uopIdx++] = newNeonMixInst<MicroInterNeon8Uop>( 8487639Sgblack@eecs.umich.edu size, machInst, rMid, vd * 2, inc * 2); 8497639Sgblack@eecs.umich.edu break; 8507639Sgblack@eecs.umich.edu case 3: 8517639Sgblack@eecs.umich.edu assert(regs == 3); 8527639Sgblack@eecs.umich.edu microOps[uopIdx++] = newNeonMixInst<MicroInterNeon6Uop>( 8537639Sgblack@eecs.umich.edu size, machInst, rMid, vd * 2, inc * 2); 8547639Sgblack@eecs.umich.edu break; 8557639Sgblack@eecs.umich.edu case 2: 8567639Sgblack@eecs.umich.edu assert(regs == 4 || regs == 2); 8577639Sgblack@eecs.umich.edu if (regs == 4) { 8587639Sgblack@eecs.umich.edu microOps[uopIdx++] = newNeonMixInst<MicroInterNeon4Uop>( 8597639Sgblack@eecs.umich.edu size, machInst, rMid, vd * 2, inc * 2); 8607639Sgblack@eecs.umich.edu microOps[uopIdx++] = newNeonMixInst<MicroInterNeon4Uop>( 8617639Sgblack@eecs.umich.edu size, machInst, rMid + 4, vd * 2 + 2, inc * 2); 8627639Sgblack@eecs.umich.edu } else { 8637639Sgblack@eecs.umich.edu microOps[uopIdx++] = newNeonMixInst<MicroInterNeon4Uop>( 8647639Sgblack@eecs.umich.edu size, machInst, rMid, vd * 2, inc * 2); 8657639Sgblack@eecs.umich.edu } 8667639Sgblack@eecs.umich.edu break; 8677639Sgblack@eecs.umich.edu default: 8687853SMatt.Horsnell@ARM.com // Bad number of elements to interleave 8697853SMatt.Horsnell@ARM.com microOps[uopIdx++] = new Unknown(machInst); 8707639Sgblack@eecs.umich.edu } 8717639Sgblack@eecs.umich.edu } 8727639Sgblack@eecs.umich.edu switch (regs) { 8737639Sgblack@eecs.umich.edu case 4: 8747639Sgblack@eecs.umich.edu microOps[uopIdx++] = newNeonMemInst<MicroStrNeon16Uop>( 8757639Sgblack@eecs.umich.edu size, machInst, rMid, rn, 0, align); 8767639Sgblack@eecs.umich.edu microOps[uopIdx++] = newNeonMemInst<MicroStrNeon16Uop>( 8777639Sgblack@eecs.umich.edu size, machInst, rMid + 4, rn, 16, noAlign); 8787639Sgblack@eecs.umich.edu break; 8797639Sgblack@eecs.umich.edu case 3: 8807639Sgblack@eecs.umich.edu microOps[uopIdx++] = newNeonMemInst<MicroStrNeon16Uop>( 8817639Sgblack@eecs.umich.edu size, machInst, rMid, rn, 0, align); 8827639Sgblack@eecs.umich.edu microOps[uopIdx++] = newNeonMemInst<MicroStrNeon8Uop>( 8837639Sgblack@eecs.umich.edu size, machInst, rMid + 4, rn, 16, noAlign); 8847639Sgblack@eecs.umich.edu break; 8857639Sgblack@eecs.umich.edu case 2: 8867639Sgblack@eecs.umich.edu microOps[uopIdx++] = newNeonMemInst<MicroStrNeon16Uop>( 8877639Sgblack@eecs.umich.edu size, machInst, rMid, rn, 0, align); 8887639Sgblack@eecs.umich.edu break; 8897639Sgblack@eecs.umich.edu case 1: 8907639Sgblack@eecs.umich.edu microOps[uopIdx++] = newNeonMemInst<MicroStrNeon8Uop>( 8917639Sgblack@eecs.umich.edu size, machInst, rMid, rn, 0, align); 8927639Sgblack@eecs.umich.edu break; 8937639Sgblack@eecs.umich.edu default: 8947853SMatt.Horsnell@ARM.com // Unknown number of registers 8957853SMatt.Horsnell@ARM.com microOps[uopIdx++] = new Unknown(machInst); 8967639Sgblack@eecs.umich.edu } 8977639Sgblack@eecs.umich.edu if (wb) { 8987639Sgblack@eecs.umich.edu if (rm != 15 && rm != 13) { 8997639Sgblack@eecs.umich.edu microOps[uopIdx++] = 9007646Sgene.wu@arm.com new MicroAddUop(machInst, rn, rn, rm, 0, ArmISA::LSL); 9017639Sgblack@eecs.umich.edu } else { 9027639Sgblack@eecs.umich.edu microOps[uopIdx++] = 9037639Sgblack@eecs.umich.edu new MicroAddiUop(machInst, rn, rn, regs * 8); 9047639Sgblack@eecs.umich.edu } 9057639Sgblack@eecs.umich.edu } 9067639Sgblack@eecs.umich.edu assert(uopIdx == numMicroops); 9077639Sgblack@eecs.umich.edu 9087639Sgblack@eecs.umich.edu for (unsigned i = 0; i < numMicroops - 1; i++) { 9097639Sgblack@eecs.umich.edu MicroOp * uopPtr = dynamic_cast<MicroOp *>(microOps[i].get()); 9107639Sgblack@eecs.umich.edu assert(uopPtr); 9117639Sgblack@eecs.umich.edu uopPtr->setDelayedCommit(); 9127639Sgblack@eecs.umich.edu } 91310666SAli.Saidi@ARM.com microOps[0]->setFirstMicroop(); 9147639Sgblack@eecs.umich.edu microOps[numMicroops - 1]->setLastMicroop(); 9157639Sgblack@eecs.umich.edu} 9167639Sgblack@eecs.umich.edu 9177639Sgblack@eecs.umich.eduVstSingleOp::VstSingleOp(const char *mnem, ExtMachInst machInst, 9187639Sgblack@eecs.umich.edu OpClass __opClass, bool all, unsigned elems, 9197639Sgblack@eecs.umich.edu RegIndex rn, RegIndex vd, unsigned regs, 9207639Sgblack@eecs.umich.edu unsigned inc, uint32_t size, uint32_t align, 9217639Sgblack@eecs.umich.edu RegIndex rm, unsigned lane) : 9227639Sgblack@eecs.umich.edu PredMacroOp(mnem, machInst, __opClass) 9237639Sgblack@eecs.umich.edu{ 9247639Sgblack@eecs.umich.edu assert(!all); 9257639Sgblack@eecs.umich.edu assert(regs > 0 && regs <= 4); 9267639Sgblack@eecs.umich.edu assert(regs % elems == 0); 9277639Sgblack@eecs.umich.edu 9287639Sgblack@eecs.umich.edu unsigned eBytes = (1 << size); 9297639Sgblack@eecs.umich.edu unsigned storeSize = eBytes * elems; 9307639Sgblack@eecs.umich.edu unsigned storeRegs M5_VAR_USED = (storeSize + sizeof(FloatRegBits) - 1) / 9317639Sgblack@eecs.umich.edu sizeof(FloatRegBits); 9327639Sgblack@eecs.umich.edu 9337639Sgblack@eecs.umich.edu assert(storeRegs > 0 && storeRegs <= 4); 9347639Sgblack@eecs.umich.edu 9357639Sgblack@eecs.umich.edu numMicroops = 1; 9367639Sgblack@eecs.umich.edu bool wb = (rm != 15); 9377639Sgblack@eecs.umich.edu 9387639Sgblack@eecs.umich.edu if (wb) numMicroops++; 9397639Sgblack@eecs.umich.edu numMicroops += (regs / elems); 9407639Sgblack@eecs.umich.edu microOps = new StaticInstPtr[numMicroops]; 9417639Sgblack@eecs.umich.edu 94210037SARM gem5 Developers RegIndex ufp0 = NumFloatV7ArchRegs; 9437639Sgblack@eecs.umich.edu 9447639Sgblack@eecs.umich.edu unsigned uopIdx = 0; 9457639Sgblack@eecs.umich.edu switch (elems) { 9467639Sgblack@eecs.umich.edu case 4: 9477639Sgblack@eecs.umich.edu assert(regs == 4); 9487639Sgblack@eecs.umich.edu switch (size) { 9497639Sgblack@eecs.umich.edu case 0: 9507639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroPackNeon8to2Uop<uint8_t>( 9517639Sgblack@eecs.umich.edu machInst, ufp0, vd * 2, inc * 2, lane); 9527639Sgblack@eecs.umich.edu break; 9537639Sgblack@eecs.umich.edu case 1: 9547639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroPackNeon8to2Uop<uint16_t>( 9557639Sgblack@eecs.umich.edu machInst, ufp0, vd * 2, inc * 2, lane); 9567639Sgblack@eecs.umich.edu break; 9577639Sgblack@eecs.umich.edu case 2: 9587639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroPackNeon8to4Uop<uint32_t>( 9597639Sgblack@eecs.umich.edu machInst, ufp0, vd * 2, inc * 2, lane); 9607639Sgblack@eecs.umich.edu break; 9617639Sgblack@eecs.umich.edu default: 9627853SMatt.Horsnell@ARM.com // Bad size 9637853SMatt.Horsnell@ARM.com microOps[uopIdx++] = new Unknown(machInst); 9647639Sgblack@eecs.umich.edu break; 9657639Sgblack@eecs.umich.edu } 9667639Sgblack@eecs.umich.edu break; 9677639Sgblack@eecs.umich.edu case 3: 9687639Sgblack@eecs.umich.edu assert(regs == 3); 9697639Sgblack@eecs.umich.edu switch (size) { 9707639Sgblack@eecs.umich.edu case 0: 9717639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroPackNeon6to2Uop<uint8_t>( 9727639Sgblack@eecs.umich.edu machInst, ufp0, vd * 2, inc * 2, lane); 9737639Sgblack@eecs.umich.edu break; 9747639Sgblack@eecs.umich.edu case 1: 9757639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroPackNeon6to2Uop<uint16_t>( 9767639Sgblack@eecs.umich.edu machInst, ufp0, vd * 2, inc * 2, lane); 9777639Sgblack@eecs.umich.edu break; 9787639Sgblack@eecs.umich.edu case 2: 9797639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroPackNeon6to4Uop<uint32_t>( 9807639Sgblack@eecs.umich.edu machInst, ufp0, vd * 2, inc * 2, lane); 9817639Sgblack@eecs.umich.edu break; 9827639Sgblack@eecs.umich.edu default: 9837853SMatt.Horsnell@ARM.com // Bad size 9847853SMatt.Horsnell@ARM.com microOps[uopIdx++] = new Unknown(machInst); 9857639Sgblack@eecs.umich.edu break; 9867639Sgblack@eecs.umich.edu } 9877639Sgblack@eecs.umich.edu break; 9887639Sgblack@eecs.umich.edu case 2: 9897639Sgblack@eecs.umich.edu assert(regs == 2); 9907639Sgblack@eecs.umich.edu assert(storeRegs <= 2); 9917639Sgblack@eecs.umich.edu switch (size) { 9927639Sgblack@eecs.umich.edu case 0: 9937639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroPackNeon4to2Uop<uint8_t>( 9947639Sgblack@eecs.umich.edu machInst, ufp0, vd * 2, inc * 2, lane); 9957639Sgblack@eecs.umich.edu break; 9967639Sgblack@eecs.umich.edu case 1: 9977639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroPackNeon4to2Uop<uint16_t>( 9987639Sgblack@eecs.umich.edu machInst, ufp0, vd * 2, inc * 2, lane); 9997639Sgblack@eecs.umich.edu break; 10007639Sgblack@eecs.umich.edu case 2: 10017639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroPackNeon4to2Uop<uint32_t>( 10027639Sgblack@eecs.umich.edu machInst, ufp0, vd * 2, inc * 2, lane); 10037639Sgblack@eecs.umich.edu break; 10047639Sgblack@eecs.umich.edu default: 10057853SMatt.Horsnell@ARM.com // Bad size 10067853SMatt.Horsnell@ARM.com microOps[uopIdx++] = new Unknown(machInst); 10077639Sgblack@eecs.umich.edu break; 10087639Sgblack@eecs.umich.edu } 10097639Sgblack@eecs.umich.edu break; 10107639Sgblack@eecs.umich.edu case 1: 10117639Sgblack@eecs.umich.edu assert(regs == 1 || (all && regs == 2)); 10127639Sgblack@eecs.umich.edu assert(storeRegs <= 2); 10137639Sgblack@eecs.umich.edu for (unsigned offset = 0; offset < regs; offset++) { 10147639Sgblack@eecs.umich.edu switch (size) { 10157639Sgblack@eecs.umich.edu case 0: 10167639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroPackNeon2to2Uop<uint8_t>( 10177639Sgblack@eecs.umich.edu machInst, ufp0, (vd + offset) * 2, inc * 2, lane); 10187639Sgblack@eecs.umich.edu break; 10197639Sgblack@eecs.umich.edu case 1: 10207639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroPackNeon2to2Uop<uint16_t>( 10217639Sgblack@eecs.umich.edu machInst, ufp0, (vd + offset) * 2, inc * 2, lane); 10227639Sgblack@eecs.umich.edu break; 10237639Sgblack@eecs.umich.edu case 2: 10247639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroPackNeon2to2Uop<uint32_t>( 10257639Sgblack@eecs.umich.edu machInst, ufp0, (vd + offset) * 2, inc * 2, lane); 10267639Sgblack@eecs.umich.edu break; 10277639Sgblack@eecs.umich.edu default: 10287853SMatt.Horsnell@ARM.com // Bad size 10297853SMatt.Horsnell@ARM.com microOps[uopIdx++] = new Unknown(machInst); 10307639Sgblack@eecs.umich.edu break; 10317639Sgblack@eecs.umich.edu } 10327639Sgblack@eecs.umich.edu } 10337639Sgblack@eecs.umich.edu break; 10347639Sgblack@eecs.umich.edu default: 10357853SMatt.Horsnell@ARM.com // Bad number of elements to unpack 10367853SMatt.Horsnell@ARM.com microOps[uopIdx++] = new Unknown(machInst); 10377639Sgblack@eecs.umich.edu } 10387639Sgblack@eecs.umich.edu switch (storeSize) { 10397639Sgblack@eecs.umich.edu case 1: 10407639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroStrNeon1Uop<uint8_t>( 10417639Sgblack@eecs.umich.edu machInst, ufp0, rn, 0, align); 10427639Sgblack@eecs.umich.edu break; 10437639Sgblack@eecs.umich.edu case 2: 10447639Sgblack@eecs.umich.edu if (eBytes == 2) { 10457639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroStrNeon2Uop<uint16_t>( 10467639Sgblack@eecs.umich.edu machInst, ufp0, rn, 0, align); 10477639Sgblack@eecs.umich.edu } else { 10487639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroStrNeon2Uop<uint8_t>( 10497639Sgblack@eecs.umich.edu machInst, ufp0, rn, 0, align); 10507639Sgblack@eecs.umich.edu } 10517639Sgblack@eecs.umich.edu break; 10527639Sgblack@eecs.umich.edu case 3: 10537639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroStrNeon3Uop<uint8_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 switch (eBytes) { 10587639Sgblack@eecs.umich.edu case 1: 10597639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroStrNeon4Uop<uint8_t>( 10607639Sgblack@eecs.umich.edu machInst, ufp0, rn, 0, align); 10617639Sgblack@eecs.umich.edu break; 10627639Sgblack@eecs.umich.edu case 2: 10637639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroStrNeon4Uop<uint16_t>( 10647639Sgblack@eecs.umich.edu machInst, ufp0, rn, 0, align); 10657639Sgblack@eecs.umich.edu break; 10667639Sgblack@eecs.umich.edu case 4: 10677639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroStrNeon4Uop<uint32_t>( 10687639Sgblack@eecs.umich.edu machInst, ufp0, rn, 0, align); 10697639Sgblack@eecs.umich.edu break; 10707639Sgblack@eecs.umich.edu } 10717639Sgblack@eecs.umich.edu break; 10727639Sgblack@eecs.umich.edu case 6: 10737639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroStrNeon6Uop<uint16_t>( 10747639Sgblack@eecs.umich.edu machInst, ufp0, rn, 0, align); 10757639Sgblack@eecs.umich.edu break; 10767639Sgblack@eecs.umich.edu case 8: 10777639Sgblack@eecs.umich.edu switch (eBytes) { 10787639Sgblack@eecs.umich.edu case 2: 10797639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroStrNeon8Uop<uint16_t>( 10807639Sgblack@eecs.umich.edu machInst, ufp0, rn, 0, align); 10817639Sgblack@eecs.umich.edu break; 10827639Sgblack@eecs.umich.edu case 4: 10837639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroStrNeon8Uop<uint32_t>( 10847639Sgblack@eecs.umich.edu machInst, ufp0, rn, 0, align); 10857639Sgblack@eecs.umich.edu break; 10867639Sgblack@eecs.umich.edu } 10877639Sgblack@eecs.umich.edu break; 10887639Sgblack@eecs.umich.edu case 12: 10897639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroStrNeon12Uop<uint32_t>( 10907639Sgblack@eecs.umich.edu machInst, ufp0, rn, 0, align); 10917639Sgblack@eecs.umich.edu break; 10927639Sgblack@eecs.umich.edu case 16: 10937639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroStrNeon16Uop<uint32_t>( 10947639Sgblack@eecs.umich.edu machInst, ufp0, rn, 0, align); 10957639Sgblack@eecs.umich.edu break; 10967639Sgblack@eecs.umich.edu default: 10977853SMatt.Horsnell@ARM.com // Bad store size 10987853SMatt.Horsnell@ARM.com microOps[uopIdx++] = new Unknown(machInst); 10997639Sgblack@eecs.umich.edu } 11007639Sgblack@eecs.umich.edu if (wb) { 11017639Sgblack@eecs.umich.edu if (rm != 15 && rm != 13) { 11027639Sgblack@eecs.umich.edu microOps[uopIdx++] = 11037646Sgene.wu@arm.com new MicroAddUop(machInst, rn, rn, rm, 0, ArmISA::LSL); 11047639Sgblack@eecs.umich.edu } else { 11057639Sgblack@eecs.umich.edu microOps[uopIdx++] = 11067639Sgblack@eecs.umich.edu new MicroAddiUop(machInst, rn, rn, storeSize); 11077639Sgblack@eecs.umich.edu } 11087639Sgblack@eecs.umich.edu } 11097639Sgblack@eecs.umich.edu assert(uopIdx == numMicroops); 11107639Sgblack@eecs.umich.edu 11117639Sgblack@eecs.umich.edu for (unsigned i = 0; i < numMicroops - 1; i++) { 11127639Sgblack@eecs.umich.edu MicroOp * uopPtr = dynamic_cast<MicroOp *>(microOps[i].get()); 11137639Sgblack@eecs.umich.edu assert(uopPtr); 11147639Sgblack@eecs.umich.edu uopPtr->setDelayedCommit(); 11157639Sgblack@eecs.umich.edu } 111610666SAli.Saidi@ARM.com microOps[0]->setFirstMicroop(); 11177639Sgblack@eecs.umich.edu microOps[numMicroops - 1]->setLastMicroop(); 11187639Sgblack@eecs.umich.edu} 11197639Sgblack@eecs.umich.edu 112010037SARM gem5 DevelopersVldMultOp64::VldMultOp64(const char *mnem, ExtMachInst machInst, 112110037SARM gem5 Developers OpClass __opClass, RegIndex rn, RegIndex vd, 112210037SARM gem5 Developers RegIndex rm, uint8_t eSize, uint8_t dataSize, 112310037SARM gem5 Developers uint8_t numStructElems, uint8_t numRegs, bool wb) : 112410037SARM gem5 Developers PredMacroOp(mnem, machInst, __opClass) 112510037SARM gem5 Developers{ 112610037SARM gem5 Developers RegIndex vx = NumFloatV8ArchRegs / 4; 112710037SARM gem5 Developers RegIndex rnsp = (RegIndex) makeSP((IntRegIndex) rn); 112810037SARM gem5 Developers bool baseIsSP = isSP((IntRegIndex) rnsp); 112910037SARM gem5 Developers 113010037SARM gem5 Developers numMicroops = wb ? 1 : 0; 113110037SARM gem5 Developers 113210037SARM gem5 Developers int totNumBytes = numRegs * dataSize / 8; 113310037SARM gem5 Developers assert(totNumBytes <= 64); 113410037SARM gem5 Developers 113510037SARM gem5 Developers // The guiding principle here is that no more than 16 bytes can be 113610037SARM gem5 Developers // transferred at a time 113710037SARM gem5 Developers int numMemMicroops = totNumBytes / 16; 113810037SARM gem5 Developers int residuum = totNumBytes % 16; 113910037SARM gem5 Developers if (residuum) 114010037SARM gem5 Developers ++numMemMicroops; 114110037SARM gem5 Developers numMicroops += numMemMicroops; 114210037SARM gem5 Developers 114310037SARM gem5 Developers int numMarshalMicroops = numRegs / 2 + (numRegs % 2 ? 1 : 0); 114410037SARM gem5 Developers numMicroops += numMarshalMicroops; 114510037SARM gem5 Developers 114610037SARM gem5 Developers microOps = new StaticInstPtr[numMicroops]; 114710037SARM gem5 Developers unsigned uopIdx = 0; 114810037SARM gem5 Developers uint32_t memaccessFlags = TLB::MustBeOne | (TLB::ArmFlags) eSize | 114910037SARM gem5 Developers TLB::AllowUnaligned; 115010037SARM gem5 Developers 115110037SARM gem5 Developers int i = 0; 115211321Ssteve.reinhardt@amd.com for (; i < numMemMicroops - 1; ++i) { 115310037SARM gem5 Developers microOps[uopIdx++] = new MicroNeonLoad64( 115410037SARM gem5 Developers machInst, vx + (RegIndex) i, rnsp, 16 * i, memaccessFlags, 115510037SARM gem5 Developers baseIsSP, 16 /* accSize */, eSize); 115610037SARM gem5 Developers } 115710037SARM gem5 Developers microOps[uopIdx++] = new MicroNeonLoad64( 115810037SARM gem5 Developers machInst, vx + (RegIndex) i, rnsp, 16 * i, memaccessFlags, baseIsSP, 115910037SARM gem5 Developers residuum ? residuum : 16 /* accSize */, eSize); 116010037SARM gem5 Developers 116110037SARM gem5 Developers // Writeback microop: the post-increment amount is encoded in "Rm": a 116210037SARM gem5 Developers // 64-bit general register OR as '11111' for an immediate value equal to 116310037SARM gem5 Developers // the total number of bytes transferred (i.e. 8, 16, 24, 32, 48 or 64) 116410037SARM gem5 Developers if (wb) { 116510037SARM gem5 Developers if (rm != ((RegIndex) INTREG_X31)) { 116610037SARM gem5 Developers microOps[uopIdx++] = new MicroAddXERegUop(machInst, rnsp, rnsp, rm, 116710037SARM gem5 Developers UXTX, 0); 116810037SARM gem5 Developers } else { 116910037SARM gem5 Developers microOps[uopIdx++] = new MicroAddXiUop(machInst, rnsp, rnsp, 117010037SARM gem5 Developers totNumBytes); 117110037SARM gem5 Developers } 117210037SARM gem5 Developers } 117310037SARM gem5 Developers 117410037SARM gem5 Developers for (int i = 0; i < numMarshalMicroops; ++i) { 117510339Smitch.hayenga@arm.com switch(numRegs) { 117610339Smitch.hayenga@arm.com case 1: microOps[uopIdx++] = new MicroDeintNeon64_1Reg( 117710339Smitch.hayenga@arm.com machInst, vd + (RegIndex) (2 * i), vx, eSize, dataSize, 117810339Smitch.hayenga@arm.com numStructElems, 1, i /* step */); 117910339Smitch.hayenga@arm.com break; 118010339Smitch.hayenga@arm.com case 2: microOps[uopIdx++] = new MicroDeintNeon64_2Reg( 118110339Smitch.hayenga@arm.com machInst, vd + (RegIndex) (2 * i), vx, eSize, dataSize, 118210339Smitch.hayenga@arm.com numStructElems, 2, i /* step */); 118310339Smitch.hayenga@arm.com break; 118410339Smitch.hayenga@arm.com case 3: microOps[uopIdx++] = new MicroDeintNeon64_3Reg( 118510339Smitch.hayenga@arm.com machInst, vd + (RegIndex) (2 * i), vx, eSize, dataSize, 118610339Smitch.hayenga@arm.com numStructElems, 3, i /* step */); 118710339Smitch.hayenga@arm.com break; 118810339Smitch.hayenga@arm.com case 4: microOps[uopIdx++] = new MicroDeintNeon64_4Reg( 118910339Smitch.hayenga@arm.com machInst, vd + (RegIndex) (2 * i), vx, eSize, dataSize, 119010339Smitch.hayenga@arm.com numStructElems, 4, i /* step */); 119110339Smitch.hayenga@arm.com break; 119210339Smitch.hayenga@arm.com default: panic("Invalid number of registers"); 119310339Smitch.hayenga@arm.com } 119410339Smitch.hayenga@arm.com 119510037SARM gem5 Developers } 119610037SARM gem5 Developers 119710037SARM gem5 Developers assert(uopIdx == numMicroops); 119810037SARM gem5 Developers 119910037SARM gem5 Developers for (int i = 0; i < numMicroops - 1; ++i) { 120010037SARM gem5 Developers microOps[i]->setDelayedCommit(); 120110037SARM gem5 Developers } 120210037SARM gem5 Developers microOps[numMicroops - 1]->setLastMicroop(); 120310037SARM gem5 Developers} 120410037SARM gem5 Developers 120510037SARM gem5 DevelopersVstMultOp64::VstMultOp64(const char *mnem, ExtMachInst machInst, 120610037SARM gem5 Developers OpClass __opClass, RegIndex rn, RegIndex vd, 120710037SARM gem5 Developers RegIndex rm, uint8_t eSize, uint8_t dataSize, 120810037SARM gem5 Developers uint8_t numStructElems, uint8_t numRegs, bool wb) : 120910037SARM gem5 Developers PredMacroOp(mnem, machInst, __opClass) 121010037SARM gem5 Developers{ 121110037SARM gem5 Developers RegIndex vx = NumFloatV8ArchRegs / 4; 121210037SARM gem5 Developers RegIndex rnsp = (RegIndex) makeSP((IntRegIndex) rn); 121310037SARM gem5 Developers bool baseIsSP = isSP((IntRegIndex) rnsp); 121410037SARM gem5 Developers 121510037SARM gem5 Developers numMicroops = wb ? 1 : 0; 121610037SARM gem5 Developers 121710037SARM gem5 Developers int totNumBytes = numRegs * dataSize / 8; 121810037SARM gem5 Developers assert(totNumBytes <= 64); 121910037SARM gem5 Developers 122010037SARM gem5 Developers // The guiding principle here is that no more than 16 bytes can be 122110037SARM gem5 Developers // transferred at a time 122210037SARM gem5 Developers int numMemMicroops = totNumBytes / 16; 122310037SARM gem5 Developers int residuum = totNumBytes % 16; 122410037SARM gem5 Developers if (residuum) 122510037SARM gem5 Developers ++numMemMicroops; 122610037SARM gem5 Developers numMicroops += numMemMicroops; 122710037SARM gem5 Developers 122810037SARM gem5 Developers int numMarshalMicroops = totNumBytes > 32 ? 2 : 1; 122910037SARM gem5 Developers numMicroops += numMarshalMicroops; 123010037SARM gem5 Developers 123110037SARM gem5 Developers microOps = new StaticInstPtr[numMicroops]; 123210037SARM gem5 Developers unsigned uopIdx = 0; 123310037SARM gem5 Developers 123411321Ssteve.reinhardt@amd.com for (int i = 0; i < numMarshalMicroops; ++i) { 123510339Smitch.hayenga@arm.com switch (numRegs) { 123610339Smitch.hayenga@arm.com case 1: microOps[uopIdx++] = new MicroIntNeon64_1Reg( 123710339Smitch.hayenga@arm.com machInst, vx + (RegIndex) (2 * i), vd, eSize, dataSize, 123810339Smitch.hayenga@arm.com numStructElems, 1, i /* step */); 123910339Smitch.hayenga@arm.com break; 124010339Smitch.hayenga@arm.com case 2: microOps[uopIdx++] = new MicroIntNeon64_2Reg( 124110339Smitch.hayenga@arm.com machInst, vx + (RegIndex) (2 * i), vd, eSize, dataSize, 124210339Smitch.hayenga@arm.com numStructElems, 2, i /* step */); 124310339Smitch.hayenga@arm.com break; 124410339Smitch.hayenga@arm.com case 3: microOps[uopIdx++] = new MicroIntNeon64_3Reg( 124510339Smitch.hayenga@arm.com machInst, vx + (RegIndex) (2 * i), vd, eSize, dataSize, 124610339Smitch.hayenga@arm.com numStructElems, 3, i /* step */); 124710339Smitch.hayenga@arm.com break; 124810339Smitch.hayenga@arm.com case 4: microOps[uopIdx++] = new MicroIntNeon64_4Reg( 124910339Smitch.hayenga@arm.com machInst, vx + (RegIndex) (2 * i), vd, eSize, dataSize, 125010339Smitch.hayenga@arm.com numStructElems, 4, i /* step */); 125110339Smitch.hayenga@arm.com break; 125210339Smitch.hayenga@arm.com default: panic("Invalid number of registers"); 125310339Smitch.hayenga@arm.com } 125410037SARM gem5 Developers } 125510037SARM gem5 Developers 125610037SARM gem5 Developers uint32_t memaccessFlags = TLB::MustBeOne | (TLB::ArmFlags) eSize | 125710037SARM gem5 Developers TLB::AllowUnaligned; 125810037SARM gem5 Developers 125910037SARM gem5 Developers int i = 0; 126011321Ssteve.reinhardt@amd.com for (; i < numMemMicroops - 1; ++i) { 126110037SARM gem5 Developers microOps[uopIdx++] = new MicroNeonStore64( 126210037SARM gem5 Developers machInst, vx + (RegIndex) i, rnsp, 16 * i, memaccessFlags, 126310037SARM gem5 Developers baseIsSP, 16 /* accSize */, eSize); 126410037SARM gem5 Developers } 126510037SARM gem5 Developers microOps[uopIdx++] = new MicroNeonStore64( 126610037SARM gem5 Developers machInst, vx + (RegIndex) i, rnsp, 16 * i, memaccessFlags, baseIsSP, 126710037SARM gem5 Developers residuum ? residuum : 16 /* accSize */, eSize); 126810037SARM gem5 Developers 126910037SARM gem5 Developers // Writeback microop: the post-increment amount is encoded in "Rm": a 127010037SARM gem5 Developers // 64-bit general register OR as '11111' for an immediate value equal to 127110037SARM gem5 Developers // the total number of bytes transferred (i.e. 8, 16, 24, 32, 48 or 64) 127210037SARM gem5 Developers if (wb) { 127310037SARM gem5 Developers if (rm != ((RegIndex) INTREG_X31)) { 127410037SARM gem5 Developers microOps[uopIdx++] = new MicroAddXERegUop(machInst, rnsp, rnsp, rm, 127510037SARM gem5 Developers UXTX, 0); 127610037SARM gem5 Developers } else { 127710037SARM gem5 Developers microOps[uopIdx++] = new MicroAddXiUop(machInst, rnsp, rnsp, 127810037SARM gem5 Developers totNumBytes); 127910037SARM gem5 Developers } 128010037SARM gem5 Developers } 128110037SARM gem5 Developers 128210037SARM gem5 Developers assert(uopIdx == numMicroops); 128310037SARM gem5 Developers 128410037SARM gem5 Developers for (int i = 0; i < numMicroops - 1; i++) { 128510037SARM gem5 Developers microOps[i]->setDelayedCommit(); 128610037SARM gem5 Developers } 128710037SARM gem5 Developers microOps[numMicroops - 1]->setLastMicroop(); 128810037SARM gem5 Developers} 128910037SARM gem5 Developers 129010037SARM gem5 DevelopersVldSingleOp64::VldSingleOp64(const char *mnem, ExtMachInst machInst, 129110037SARM gem5 Developers OpClass __opClass, RegIndex rn, RegIndex vd, 129210037SARM gem5 Developers RegIndex rm, uint8_t eSize, uint8_t dataSize, 129310037SARM gem5 Developers uint8_t numStructElems, uint8_t index, bool wb, 129410037SARM gem5 Developers bool replicate) : 129510537Sandreas.hansson@arm.com PredMacroOp(mnem, machInst, __opClass), 129610537Sandreas.hansson@arm.com eSize(0), dataSize(0), numStructElems(0), index(0), 129710537Sandreas.hansson@arm.com wb(false), replicate(false) 129810537Sandreas.hansson@arm.com 129910037SARM gem5 Developers{ 130010037SARM gem5 Developers RegIndex vx = NumFloatV8ArchRegs / 4; 130110037SARM gem5 Developers RegIndex rnsp = (RegIndex) makeSP((IntRegIndex) rn); 130210037SARM gem5 Developers bool baseIsSP = isSP((IntRegIndex) rnsp); 130310037SARM gem5 Developers 130410037SARM gem5 Developers numMicroops = wb ? 1 : 0; 130510037SARM gem5 Developers 130610037SARM gem5 Developers int eSizeBytes = 1 << eSize; 130710037SARM gem5 Developers int totNumBytes = numStructElems * eSizeBytes; 130810037SARM gem5 Developers assert(totNumBytes <= 64); 130910037SARM gem5 Developers 131010037SARM gem5 Developers // The guiding principle here is that no more than 16 bytes can be 131110037SARM gem5 Developers // transferred at a time 131210037SARM gem5 Developers int numMemMicroops = totNumBytes / 16; 131310037SARM gem5 Developers int residuum = totNumBytes % 16; 131410037SARM gem5 Developers if (residuum) 131510037SARM gem5 Developers ++numMemMicroops; 131610037SARM gem5 Developers numMicroops += numMemMicroops; 131710037SARM gem5 Developers 131810037SARM gem5 Developers int numMarshalMicroops = numStructElems / 2 + (numStructElems % 2 ? 1 : 0); 131910037SARM gem5 Developers numMicroops += numMarshalMicroops; 132010037SARM gem5 Developers 132110037SARM gem5 Developers microOps = new StaticInstPtr[numMicroops]; 132210037SARM gem5 Developers unsigned uopIdx = 0; 132310037SARM gem5 Developers 132410037SARM gem5 Developers uint32_t memaccessFlags = TLB::MustBeOne | (TLB::ArmFlags) eSize | 132510037SARM gem5 Developers TLB::AllowUnaligned; 132610037SARM gem5 Developers 132710037SARM gem5 Developers int i = 0; 132810037SARM gem5 Developers for (; i < numMemMicroops - 1; ++i) { 132910037SARM gem5 Developers microOps[uopIdx++] = new MicroNeonLoad64( 133010037SARM gem5 Developers machInst, vx + (RegIndex) i, rnsp, 16 * i, memaccessFlags, 133110037SARM gem5 Developers baseIsSP, 16 /* accSize */, eSize); 133210037SARM gem5 Developers } 133310037SARM gem5 Developers microOps[uopIdx++] = new MicroNeonLoad64( 133410037SARM gem5 Developers machInst, vx + (RegIndex) i, rnsp, 16 * i, memaccessFlags, baseIsSP, 133510037SARM gem5 Developers residuum ? residuum : 16 /* accSize */, eSize); 133610037SARM gem5 Developers 133710037SARM gem5 Developers // Writeback microop: the post-increment amount is encoded in "Rm": a 133810037SARM gem5 Developers // 64-bit general register OR as '11111' for an immediate value equal to 133910037SARM gem5 Developers // the total number of bytes transferred (i.e. 8, 16, 24, 32, 48 or 64) 134010037SARM gem5 Developers if (wb) { 134110037SARM gem5 Developers if (rm != ((RegIndex) INTREG_X31)) { 134210037SARM gem5 Developers microOps[uopIdx++] = new MicroAddXERegUop(machInst, rnsp, rnsp, rm, 134310037SARM gem5 Developers UXTX, 0); 134410037SARM gem5 Developers } else { 134510037SARM gem5 Developers microOps[uopIdx++] = new MicroAddXiUop(machInst, rnsp, rnsp, 134610037SARM gem5 Developers totNumBytes); 134710037SARM gem5 Developers } 134810037SARM gem5 Developers } 134910037SARM gem5 Developers 135011321Ssteve.reinhardt@amd.com for (int i = 0; i < numMarshalMicroops; ++i) { 135110037SARM gem5 Developers microOps[uopIdx++] = new MicroUnpackNeon64( 135210037SARM gem5 Developers machInst, vd + (RegIndex) (2 * i), vx, eSize, dataSize, 135310037SARM gem5 Developers numStructElems, index, i /* step */, replicate); 135410037SARM gem5 Developers } 135510037SARM gem5 Developers 135610037SARM gem5 Developers assert(uopIdx == numMicroops); 135710037SARM gem5 Developers 135810037SARM gem5 Developers for (int i = 0; i < numMicroops - 1; i++) { 135910037SARM gem5 Developers microOps[i]->setDelayedCommit(); 136010037SARM gem5 Developers } 136110037SARM gem5 Developers microOps[numMicroops - 1]->setLastMicroop(); 136210037SARM gem5 Developers} 136310037SARM gem5 Developers 136410037SARM gem5 DevelopersVstSingleOp64::VstSingleOp64(const char *mnem, ExtMachInst machInst, 136510037SARM gem5 Developers OpClass __opClass, RegIndex rn, RegIndex vd, 136610037SARM gem5 Developers RegIndex rm, uint8_t eSize, uint8_t dataSize, 136710037SARM gem5 Developers uint8_t numStructElems, uint8_t index, bool wb, 136810037SARM gem5 Developers bool replicate) : 136910537Sandreas.hansson@arm.com PredMacroOp(mnem, machInst, __opClass), 137010537Sandreas.hansson@arm.com eSize(0), dataSize(0), numStructElems(0), index(0), 137110537Sandreas.hansson@arm.com wb(false), replicate(false) 137210037SARM gem5 Developers{ 137310037SARM gem5 Developers RegIndex vx = NumFloatV8ArchRegs / 4; 137410037SARM gem5 Developers RegIndex rnsp = (RegIndex) makeSP((IntRegIndex) rn); 137510037SARM gem5 Developers bool baseIsSP = isSP((IntRegIndex) rnsp); 137610037SARM gem5 Developers 137710037SARM gem5 Developers numMicroops = wb ? 1 : 0; 137810037SARM gem5 Developers 137910037SARM gem5 Developers int eSizeBytes = 1 << eSize; 138010037SARM gem5 Developers int totNumBytes = numStructElems * eSizeBytes; 138110037SARM gem5 Developers assert(totNumBytes <= 64); 138210037SARM gem5 Developers 138310037SARM gem5 Developers // The guiding principle here is that no more than 16 bytes can be 138410037SARM gem5 Developers // transferred at a time 138510037SARM gem5 Developers int numMemMicroops = totNumBytes / 16; 138610037SARM gem5 Developers int residuum = totNumBytes % 16; 138710037SARM gem5 Developers if (residuum) 138810037SARM gem5 Developers ++numMemMicroops; 138910037SARM gem5 Developers numMicroops += numMemMicroops; 139010037SARM gem5 Developers 139110037SARM gem5 Developers int numMarshalMicroops = totNumBytes > 32 ? 2 : 1; 139210037SARM gem5 Developers numMicroops += numMarshalMicroops; 139310037SARM gem5 Developers 139410037SARM gem5 Developers microOps = new StaticInstPtr[numMicroops]; 139510037SARM gem5 Developers unsigned uopIdx = 0; 139610037SARM gem5 Developers 139711321Ssteve.reinhardt@amd.com for (int i = 0; i < numMarshalMicroops; ++i) { 139810037SARM gem5 Developers microOps[uopIdx++] = new MicroPackNeon64( 139910037SARM gem5 Developers machInst, vx + (RegIndex) (2 * i), vd, eSize, dataSize, 140010037SARM gem5 Developers numStructElems, index, i /* step */, replicate); 140110037SARM gem5 Developers } 140210037SARM gem5 Developers 140310037SARM gem5 Developers uint32_t memaccessFlags = TLB::MustBeOne | (TLB::ArmFlags) eSize | 140410037SARM gem5 Developers TLB::AllowUnaligned; 140510037SARM gem5 Developers 140610037SARM gem5 Developers int i = 0; 140711321Ssteve.reinhardt@amd.com for (; i < numMemMicroops - 1; ++i) { 140810037SARM gem5 Developers microOps[uopIdx++] = new MicroNeonStore64( 140910037SARM gem5 Developers machInst, vx + (RegIndex) i, rnsp, 16 * i, memaccessFlags, 141010037SARM gem5 Developers baseIsSP, 16 /* accsize */, eSize); 141110037SARM gem5 Developers } 141210037SARM gem5 Developers microOps[uopIdx++] = new MicroNeonStore64( 141310037SARM gem5 Developers machInst, vx + (RegIndex) i, rnsp, 16 * i, memaccessFlags, baseIsSP, 141410037SARM gem5 Developers residuum ? residuum : 16 /* accSize */, eSize); 141510037SARM gem5 Developers 141610037SARM gem5 Developers // Writeback microop: the post-increment amount is encoded in "Rm": a 141710037SARM gem5 Developers // 64-bit general register OR as '11111' for an immediate value equal to 141810037SARM gem5 Developers // the total number of bytes transferred (i.e. 8, 16, 24, 32, 48 or 64) 141910037SARM gem5 Developers if (wb) { 142010037SARM gem5 Developers if (rm != ((RegIndex) INTREG_X31)) { 142110037SARM gem5 Developers microOps[uopIdx++] = new MicroAddXERegUop(machInst, rnsp, rnsp, rm, 142210037SARM gem5 Developers UXTX, 0); 142310037SARM gem5 Developers } else { 142410037SARM gem5 Developers microOps[uopIdx++] = new MicroAddXiUop(machInst, rnsp, rnsp, 142510037SARM gem5 Developers totNumBytes); 142610037SARM gem5 Developers } 142710037SARM gem5 Developers } 142810037SARM gem5 Developers 142910037SARM gem5 Developers assert(uopIdx == numMicroops); 143010037SARM gem5 Developers 143110037SARM gem5 Developers for (int i = 0; i < numMicroops - 1; i++) { 143210037SARM gem5 Developers microOps[i]->setDelayedCommit(); 143310037SARM gem5 Developers } 143410037SARM gem5 Developers microOps[numMicroops - 1]->setLastMicroop(); 143510037SARM gem5 Developers} 143610037SARM gem5 Developers 14377175Sgblack@eecs.umich.eduMacroVFPMemOp::MacroVFPMemOp(const char *mnem, ExtMachInst machInst, 14387175Sgblack@eecs.umich.edu OpClass __opClass, IntRegIndex rn, 14397175Sgblack@eecs.umich.edu RegIndex vd, bool single, bool up, 14407175Sgblack@eecs.umich.edu bool writeback, bool load, uint32_t offset) : 14417175Sgblack@eecs.umich.edu PredMacroOp(mnem, machInst, __opClass) 14427175Sgblack@eecs.umich.edu{ 14437175Sgblack@eecs.umich.edu int i = 0; 14447175Sgblack@eecs.umich.edu 14457175Sgblack@eecs.umich.edu // The lowest order bit selects fldmx (set) or fldmd (clear). These seem 14467175Sgblack@eecs.umich.edu // to be functionally identical except that fldmx is deprecated. For now 14477175Sgblack@eecs.umich.edu // we'll assume they're otherwise interchangable. 14487175Sgblack@eecs.umich.edu int count = (single ? offset : (offset / 2)); 144910037SARM gem5 Developers if (count == 0 || count > NumFloatV7ArchRegs) 14507175Sgblack@eecs.umich.edu warn_once("Bad offset field for VFP load/store multiple.\n"); 14517175Sgblack@eecs.umich.edu if (count == 0) { 14527175Sgblack@eecs.umich.edu // Force there to be at least one microop so the macroop makes sense. 14537175Sgblack@eecs.umich.edu writeback = true; 14547175Sgblack@eecs.umich.edu } 145510037SARM gem5 Developers if (count > NumFloatV7ArchRegs) 145610037SARM gem5 Developers count = NumFloatV7ArchRegs; 14577175Sgblack@eecs.umich.edu 14587342Sgblack@eecs.umich.edu numMicroops = count * (single ? 1 : 2) + (writeback ? 1 : 0); 14597342Sgblack@eecs.umich.edu microOps = new StaticInstPtr[numMicroops]; 14607342Sgblack@eecs.umich.edu 14617395Sgblack@eecs.umich.edu int64_t addr = 0; 14627175Sgblack@eecs.umich.edu 14637342Sgblack@eecs.umich.edu if (!up) 14647342Sgblack@eecs.umich.edu addr = 4 * offset; 14657175Sgblack@eecs.umich.edu 14667342Sgblack@eecs.umich.edu bool tempUp = up; 14677175Sgblack@eecs.umich.edu for (int j = 0; j < count; j++) { 14687175Sgblack@eecs.umich.edu if (load) { 14697639Sgblack@eecs.umich.edu if (single) { 14707639Sgblack@eecs.umich.edu microOps[i++] = new MicroLdrFpUop(machInst, vd++, rn, 14717639Sgblack@eecs.umich.edu tempUp, addr); 14727639Sgblack@eecs.umich.edu } else { 14737639Sgblack@eecs.umich.edu microOps[i++] = new MicroLdrDBFpUop(machInst, vd++, rn, 14747639Sgblack@eecs.umich.edu tempUp, addr); 14757639Sgblack@eecs.umich.edu microOps[i++] = new MicroLdrDTFpUop(machInst, vd++, rn, tempUp, 14767639Sgblack@eecs.umich.edu addr + (up ? 4 : -4)); 14777639Sgblack@eecs.umich.edu } 14787175Sgblack@eecs.umich.edu } else { 14797639Sgblack@eecs.umich.edu if (single) { 14807639Sgblack@eecs.umich.edu microOps[i++] = new MicroStrFpUop(machInst, vd++, rn, 14817639Sgblack@eecs.umich.edu tempUp, addr); 14827639Sgblack@eecs.umich.edu } else { 14837639Sgblack@eecs.umich.edu microOps[i++] = new MicroStrDBFpUop(machInst, vd++, rn, 14847639Sgblack@eecs.umich.edu tempUp, addr); 14857639Sgblack@eecs.umich.edu microOps[i++] = new MicroStrDTFpUop(machInst, vd++, rn, tempUp, 14867639Sgblack@eecs.umich.edu addr + (up ? 4 : -4)); 14877639Sgblack@eecs.umich.edu } 14887175Sgblack@eecs.umich.edu } 14897342Sgblack@eecs.umich.edu if (!tempUp) { 14907342Sgblack@eecs.umich.edu addr -= (single ? 4 : 8); 14917342Sgblack@eecs.umich.edu // The microops don't handle negative displacement, so turn if we 14927342Sgblack@eecs.umich.edu // hit zero, flip polarity and start adding. 14937395Sgblack@eecs.umich.edu if (addr <= 0) { 14947342Sgblack@eecs.umich.edu tempUp = true; 14957395Sgblack@eecs.umich.edu addr = -addr; 14967342Sgblack@eecs.umich.edu } 14977342Sgblack@eecs.umich.edu } else { 14987342Sgblack@eecs.umich.edu addr += (single ? 4 : 8); 14997342Sgblack@eecs.umich.edu } 15007175Sgblack@eecs.umich.edu } 15017175Sgblack@eecs.umich.edu 15027175Sgblack@eecs.umich.edu if (writeback) { 15037175Sgblack@eecs.umich.edu if (up) { 15047175Sgblack@eecs.umich.edu microOps[i++] = 15057175Sgblack@eecs.umich.edu new MicroAddiUop(machInst, rn, rn, 4 * offset); 15067175Sgblack@eecs.umich.edu } else { 15077175Sgblack@eecs.umich.edu microOps[i++] = 15087175Sgblack@eecs.umich.edu new MicroSubiUop(machInst, rn, rn, 4 * offset); 15097175Sgblack@eecs.umich.edu } 15107175Sgblack@eecs.umich.edu } 15117175Sgblack@eecs.umich.edu 15127342Sgblack@eecs.umich.edu assert(numMicroops == i); 15137175Sgblack@eecs.umich.edu microOps[numMicroops - 1]->setLastMicroop(); 15147343Sgblack@eecs.umich.edu 15157343Sgblack@eecs.umich.edu for (StaticInstPtr *curUop = microOps; 15167343Sgblack@eecs.umich.edu !(*curUop)->isLastMicroop(); curUop++) { 15177343Sgblack@eecs.umich.edu MicroOp * uopPtr = dynamic_cast<MicroOp *>(curUop->get()); 15187343Sgblack@eecs.umich.edu assert(uopPtr); 15197343Sgblack@eecs.umich.edu uopPtr->setDelayedCommit(); 15207343Sgblack@eecs.umich.edu } 15217170Sgblack@eecs.umich.edu} 15227175Sgblack@eecs.umich.edu 15237615Sminkyu.jeong@arm.comstd::string 15247639Sgblack@eecs.umich.eduMicroIntImmOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const 15257639Sgblack@eecs.umich.edu{ 15267639Sgblack@eecs.umich.edu std::stringstream ss; 15277639Sgblack@eecs.umich.edu printMnemonic(ss); 15287639Sgblack@eecs.umich.edu printReg(ss, ura); 15297639Sgblack@eecs.umich.edu ss << ", "; 15307639Sgblack@eecs.umich.edu printReg(ss, urb); 15317639Sgblack@eecs.umich.edu ss << ", "; 15327639Sgblack@eecs.umich.edu ccprintf(ss, "#%d", imm); 15337639Sgblack@eecs.umich.edu return ss.str(); 15347639Sgblack@eecs.umich.edu} 15357639Sgblack@eecs.umich.edu 15367639Sgblack@eecs.umich.edustd::string 153710037SARM gem5 DevelopersMicroIntImmXOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const 153810037SARM gem5 Developers{ 153910037SARM gem5 Developers std::stringstream ss; 154010037SARM gem5 Developers printMnemonic(ss); 154110037SARM gem5 Developers printReg(ss, ura); 154210037SARM gem5 Developers ss << ", "; 154310037SARM gem5 Developers printReg(ss, urb); 154410037SARM gem5 Developers ss << ", "; 154510037SARM gem5 Developers ccprintf(ss, "#%d", imm); 154610037SARM gem5 Developers return ss.str(); 154710037SARM gem5 Developers} 154810037SARM gem5 Developers 154910037SARM gem5 Developersstd::string 15508140SMatt.Horsnell@arm.comMicroSetPCCPSR::generateDisassembly(Addr pc, const SymbolTable *symtab) const 15518140SMatt.Horsnell@arm.com{ 15528140SMatt.Horsnell@arm.com std::stringstream ss; 15538140SMatt.Horsnell@arm.com printMnemonic(ss); 15548140SMatt.Horsnell@arm.com ss << "[PC,CPSR]"; 15558140SMatt.Horsnell@arm.com return ss.str(); 15568140SMatt.Horsnell@arm.com} 15578140SMatt.Horsnell@arm.com 15588140SMatt.Horsnell@arm.comstd::string 155910037SARM gem5 DevelopersMicroIntRegXOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const 156010037SARM gem5 Developers{ 156110037SARM gem5 Developers std::stringstream ss; 156210037SARM gem5 Developers printMnemonic(ss); 156310037SARM gem5 Developers printReg(ss, ura); 156410037SARM gem5 Developers ccprintf(ss, ", "); 156510037SARM gem5 Developers printReg(ss, urb); 156610037SARM gem5 Developers printExtendOperand(false, ss, (IntRegIndex)urc, type, shiftAmt); 156710037SARM gem5 Developers return ss.str(); 156810037SARM gem5 Developers} 156910037SARM gem5 Developers 157010037SARM gem5 Developersstd::string 15717646Sgene.wu@arm.comMicroIntMov::generateDisassembly(Addr pc, const SymbolTable *symtab) const 15727646Sgene.wu@arm.com{ 15737646Sgene.wu@arm.com std::stringstream ss; 15747646Sgene.wu@arm.com printMnemonic(ss); 15757646Sgene.wu@arm.com printReg(ss, ura); 15767646Sgene.wu@arm.com ss << ", "; 15777646Sgene.wu@arm.com printReg(ss, urb); 15787646Sgene.wu@arm.com return ss.str(); 15797646Sgene.wu@arm.com} 15807646Sgene.wu@arm.com 15817646Sgene.wu@arm.comstd::string 15827615Sminkyu.jeong@arm.comMicroIntOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const 15837615Sminkyu.jeong@arm.com{ 15847615Sminkyu.jeong@arm.com std::stringstream ss; 15857615Sminkyu.jeong@arm.com printMnemonic(ss); 15867615Sminkyu.jeong@arm.com printReg(ss, ura); 15877615Sminkyu.jeong@arm.com ss << ", "; 15887615Sminkyu.jeong@arm.com printReg(ss, urb); 15897615Sminkyu.jeong@arm.com ss << ", "; 15907639Sgblack@eecs.umich.edu printReg(ss, urc); 15917615Sminkyu.jeong@arm.com return ss.str(); 15927175Sgblack@eecs.umich.edu} 15937615Sminkyu.jeong@arm.com 15947615Sminkyu.jeong@arm.comstd::string 15957615Sminkyu.jeong@arm.comMicroMemOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const 15967615Sminkyu.jeong@arm.com{ 15977615Sminkyu.jeong@arm.com std::stringstream ss; 15987615Sminkyu.jeong@arm.com printMnemonic(ss); 159910180SCurtis.Dunham@arm.com if (isFloating()) 160010180SCurtis.Dunham@arm.com printReg(ss, ura + FP_Reg_Base); 160110180SCurtis.Dunham@arm.com else 160210180SCurtis.Dunham@arm.com printReg(ss, ura); 16037615Sminkyu.jeong@arm.com ss << ", ["; 16047615Sminkyu.jeong@arm.com printReg(ss, urb); 16057615Sminkyu.jeong@arm.com ss << ", "; 16067615Sminkyu.jeong@arm.com ccprintf(ss, "#%d", imm); 16077615Sminkyu.jeong@arm.com ss << "]"; 16087615Sminkyu.jeong@arm.com return ss.str(); 16097615Sminkyu.jeong@arm.com} 16107615Sminkyu.jeong@arm.com 161110346Smitch.hayenga@arm.comstd::string 161210346Smitch.hayenga@arm.comMicroMemPairOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const 161310346Smitch.hayenga@arm.com{ 161410346Smitch.hayenga@arm.com std::stringstream ss; 161510346Smitch.hayenga@arm.com printMnemonic(ss); 161610346Smitch.hayenga@arm.com printReg(ss, dest); 161710346Smitch.hayenga@arm.com ss << ","; 161810346Smitch.hayenga@arm.com printReg(ss, dest2); 161910346Smitch.hayenga@arm.com ss << ", ["; 162010346Smitch.hayenga@arm.com printReg(ss, urb); 162110346Smitch.hayenga@arm.com ss << ", "; 162210346Smitch.hayenga@arm.com ccprintf(ss, "#%d", imm); 162310346Smitch.hayenga@arm.com ss << "]"; 162410346Smitch.hayenga@arm.com return ss.str(); 16257615Sminkyu.jeong@arm.com} 162610346Smitch.hayenga@arm.com 162710346Smitch.hayenga@arm.com} 1628