macromem.cc revision 10339
17170Sgblack@eecs.umich.edu/* 210339Smitch.hayenga@arm.com * Copyright (c) 2010-2014 ARM Limited 37170Sgblack@eecs.umich.edu * All rights reserved 47170Sgblack@eecs.umich.edu * 57170Sgblack@eecs.umich.edu * The license below extends only to copyright in the software and shall 67170Sgblack@eecs.umich.edu * not be construed as granting a license to any other intellectual 77170Sgblack@eecs.umich.edu * property including but not limited to intellectual property relating 87170Sgblack@eecs.umich.edu * to a hardware implementation of the functionality of the software 97170Sgblack@eecs.umich.edu * licensed hereunder. You may use the software subject to the license 107170Sgblack@eecs.umich.edu * terms below provided that you ensure that this notice is replicated 117170Sgblack@eecs.umich.edu * unmodified and in its entirety in all distributions of the software, 127170Sgblack@eecs.umich.edu * modified or unmodified, in source code or in binary form. 137170Sgblack@eecs.umich.edu * 147170Sgblack@eecs.umich.edu * Copyright (c) 2007-2008 The Florida State University 157170Sgblack@eecs.umich.edu * All rights reserved. 167170Sgblack@eecs.umich.edu * 177170Sgblack@eecs.umich.edu * Redistribution and use in source and binary forms, with or without 187170Sgblack@eecs.umich.edu * modification, are permitted provided that the following conditions are 197170Sgblack@eecs.umich.edu * met: redistributions of source code must retain the above copyright 207170Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer; 217170Sgblack@eecs.umich.edu * redistributions in binary form must reproduce the above copyright 227170Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the 237170Sgblack@eecs.umich.edu * documentation and/or other materials provided with the distribution; 247170Sgblack@eecs.umich.edu * neither the name of the copyright holders nor the names of its 257170Sgblack@eecs.umich.edu * contributors may be used to endorse or promote products derived from 267170Sgblack@eecs.umich.edu * this software without specific prior written permission. 277170Sgblack@eecs.umich.edu * 287170Sgblack@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 297170Sgblack@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 307170Sgblack@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 317170Sgblack@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 327170Sgblack@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 337170Sgblack@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 347170Sgblack@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 357170Sgblack@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 367170Sgblack@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 377170Sgblack@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 387170Sgblack@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 397170Sgblack@eecs.umich.edu * 407170Sgblack@eecs.umich.edu * Authors: Stephen Hines 417170Sgblack@eecs.umich.edu */ 427170Sgblack@eecs.umich.edu 438229Snate@binkert.org#include <sstream> 448229Snate@binkert.org 457170Sgblack@eecs.umich.edu#include "arch/arm/insts/macromem.hh" 4610037SARM gem5 Developers 478961Sgblack@eecs.umich.edu#include "arch/arm/generated/decoder.hh" 4810037SARM gem5 Developers#include "arch/arm/insts/neon64_mem.hh" 497170Sgblack@eecs.umich.edu 507853SMatt.Horsnell@ARM.comusing namespace std; 517170Sgblack@eecs.umich.eduusing namespace ArmISAInst; 527170Sgblack@eecs.umich.edu 537170Sgblack@eecs.umich.edunamespace ArmISA 547170Sgblack@eecs.umich.edu{ 557170Sgblack@eecs.umich.edu 567170Sgblack@eecs.umich.eduMacroMemOp::MacroMemOp(const char *mnem, ExtMachInst machInst, 577170Sgblack@eecs.umich.edu OpClass __opClass, IntRegIndex rn, 587170Sgblack@eecs.umich.edu bool index, bool up, bool user, bool writeback, 597170Sgblack@eecs.umich.edu bool load, uint32_t reglist) : 607170Sgblack@eecs.umich.edu PredMacroOp(mnem, machInst, __opClass) 617170Sgblack@eecs.umich.edu{ 627170Sgblack@eecs.umich.edu uint32_t regs = reglist; 637170Sgblack@eecs.umich.edu uint32_t ones = number_of_ones(reglist); 648148SAli.Saidi@ARM.com // Remember that writeback adds a uop or two and the temp register adds one 658148SAli.Saidi@ARM.com numMicroops = ones + (writeback ? (load ? 2 : 1) : 0) + 1; 668148SAli.Saidi@ARM.com 678148SAli.Saidi@ARM.com // It's technically legal to do a lot of nothing 688148SAli.Saidi@ARM.com if (!ones) 698148SAli.Saidi@ARM.com numMicroops = 1; 708148SAli.Saidi@ARM.com 717170Sgblack@eecs.umich.edu microOps = new StaticInstPtr[numMicroops]; 727170Sgblack@eecs.umich.edu uint32_t addr = 0; 737170Sgblack@eecs.umich.edu 747170Sgblack@eecs.umich.edu if (!up) 757170Sgblack@eecs.umich.edu addr = (ones << 2) - 4; 767170Sgblack@eecs.umich.edu 777170Sgblack@eecs.umich.edu if (!index) 787170Sgblack@eecs.umich.edu addr += 4; 797170Sgblack@eecs.umich.edu 807190Sgblack@eecs.umich.edu StaticInstPtr *uop = microOps; 817190Sgblack@eecs.umich.edu 827170Sgblack@eecs.umich.edu // Add 0 to Rn and stick it in ureg0. 837170Sgblack@eecs.umich.edu // This is equivalent to a move. 847190Sgblack@eecs.umich.edu *uop = new MicroAddiUop(machInst, INTREG_UREG0, rn, 0); 857190Sgblack@eecs.umich.edu 867170Sgblack@eecs.umich.edu unsigned reg = 0; 878148SAli.Saidi@ARM.com unsigned regIdx = 0; 887170Sgblack@eecs.umich.edu bool force_user = user & !bits(reglist, 15); 897170Sgblack@eecs.umich.edu bool exception_ret = user & bits(reglist, 15); 907170Sgblack@eecs.umich.edu 917190Sgblack@eecs.umich.edu for (int i = 0; i < ones; i++) { 927170Sgblack@eecs.umich.edu // Find the next register. 937170Sgblack@eecs.umich.edu while (!bits(regs, reg)) 947170Sgblack@eecs.umich.edu reg++; 957170Sgblack@eecs.umich.edu replaceBits(regs, reg, 0); 967170Sgblack@eecs.umich.edu 978148SAli.Saidi@ARM.com regIdx = reg; 987170Sgblack@eecs.umich.edu if (force_user) { 997310Sgblack@eecs.umich.edu regIdx = intRegInMode(MODE_USER, regIdx); 1007170Sgblack@eecs.umich.edu } 1017170Sgblack@eecs.umich.edu 1027170Sgblack@eecs.umich.edu if (load) { 1038148SAli.Saidi@ARM.com if (writeback && i == ones - 1) { 1048148SAli.Saidi@ARM.com // If it's a writeback and this is the last register 1058148SAli.Saidi@ARM.com // do the load into a temporary register which we'll move 1068148SAli.Saidi@ARM.com // into the final one later 1078148SAli.Saidi@ARM.com *++uop = new MicroLdrUop(machInst, INTREG_UREG1, INTREG_UREG0, 1088148SAli.Saidi@ARM.com up, addr); 1097170Sgblack@eecs.umich.edu } else { 1108148SAli.Saidi@ARM.com // Otherwise just do it normally 1118148SAli.Saidi@ARM.com if (reg == INTREG_PC && exception_ret) { 1128148SAli.Saidi@ARM.com // This must be the exception return form of ldm. 1138148SAli.Saidi@ARM.com *++uop = new MicroLdrRetUop(machInst, regIdx, 1148148SAli.Saidi@ARM.com INTREG_UREG0, up, addr); 1159640Snathanael.premillieu@irisa.fr if (!(condCode == COND_AL || condCode == COND_UC)) 1169640Snathanael.premillieu@irisa.fr (*uop)->setFlag(StaticInst::IsCondControl); 1179640Snathanael.premillieu@irisa.fr else 1189640Snathanael.premillieu@irisa.fr (*uop)->setFlag(StaticInst::IsUncondControl); 1198148SAli.Saidi@ARM.com } else { 1208148SAli.Saidi@ARM.com *++uop = new MicroLdrUop(machInst, regIdx, 1218148SAli.Saidi@ARM.com INTREG_UREG0, up, addr); 1229250SAli.Saidi@ARM.com if (reg == INTREG_PC) { 1239250SAli.Saidi@ARM.com (*uop)->setFlag(StaticInst::IsControl); 1249250SAli.Saidi@ARM.com if (!(condCode == COND_AL || condCode == COND_UC)) 1259250SAli.Saidi@ARM.com (*uop)->setFlag(StaticInst::IsCondControl); 1269250SAli.Saidi@ARM.com else 1279250SAli.Saidi@ARM.com (*uop)->setFlag(StaticInst::IsUncondControl); 1289250SAli.Saidi@ARM.com (*uop)->setFlag(StaticInst::IsIndirectControl); 1299250SAli.Saidi@ARM.com } 1308148SAli.Saidi@ARM.com } 1317170Sgblack@eecs.umich.edu } 1327170Sgblack@eecs.umich.edu } else { 1337190Sgblack@eecs.umich.edu *++uop = new MicroStrUop(machInst, regIdx, INTREG_UREG0, up, addr); 1347170Sgblack@eecs.umich.edu } 1357170Sgblack@eecs.umich.edu 1367170Sgblack@eecs.umich.edu if (up) 1377170Sgblack@eecs.umich.edu addr += 4; 1387170Sgblack@eecs.umich.edu else 1397170Sgblack@eecs.umich.edu addr -= 4; 1407170Sgblack@eecs.umich.edu } 1417170Sgblack@eecs.umich.edu 1428148SAli.Saidi@ARM.com if (writeback && ones) { 1438148SAli.Saidi@ARM.com // put the register update after we're done all loading 1448148SAli.Saidi@ARM.com if (up) 1458148SAli.Saidi@ARM.com *++uop = new MicroAddiUop(machInst, rn, rn, ones * 4); 1468148SAli.Saidi@ARM.com else 1478148SAli.Saidi@ARM.com *++uop = new MicroSubiUop(machInst, rn, rn, ones * 4); 1488148SAli.Saidi@ARM.com 1498148SAli.Saidi@ARM.com // If this was a load move the last temporary value into place 1508148SAli.Saidi@ARM.com // this way we can't take an exception after we update the base 1518148SAli.Saidi@ARM.com // register. 1528148SAli.Saidi@ARM.com if (load && reg == INTREG_PC && exception_ret) { 1538148SAli.Saidi@ARM.com *++uop = new MicroUopRegMovRet(machInst, 0, INTREG_UREG1); 1549368Snathanael.premillieu@irisa.fr if (!(condCode == COND_AL || condCode == COND_UC)) 1559368Snathanael.premillieu@irisa.fr (*uop)->setFlag(StaticInst::IsCondControl); 1569368Snathanael.premillieu@irisa.fr else 1579368Snathanael.premillieu@irisa.fr (*uop)->setFlag(StaticInst::IsUncondControl); 1588148SAli.Saidi@ARM.com } else if (load) { 1598148SAli.Saidi@ARM.com *++uop = new MicroUopRegMov(machInst, regIdx, INTREG_UREG1); 1608148SAli.Saidi@ARM.com if (reg == INTREG_PC) { 1618542Sgblack@eecs.umich.edu (*uop)->setFlag(StaticInst::IsControl); 1628542Sgblack@eecs.umich.edu (*uop)->setFlag(StaticInst::IsCondControl); 1638542Sgblack@eecs.umich.edu (*uop)->setFlag(StaticInst::IsIndirectControl); 1648148SAli.Saidi@ARM.com // This is created as a RAS POP 1658148SAli.Saidi@ARM.com if (rn == INTREG_SP) 1668542Sgblack@eecs.umich.edu (*uop)->setFlag(StaticInst::IsReturn); 1678148SAli.Saidi@ARM.com 1688148SAli.Saidi@ARM.com } 1698148SAli.Saidi@ARM.com } 1707170Sgblack@eecs.umich.edu } 1717190Sgblack@eecs.umich.edu 1727190Sgblack@eecs.umich.edu (*uop)->setLastMicroop(); 1737343Sgblack@eecs.umich.edu 17410199SAndrew.Bardsley@arm.com /* Take the control flags from the last microop for the macroop */ 17510199SAndrew.Bardsley@arm.com if ((*uop)->isControl()) 17610199SAndrew.Bardsley@arm.com setFlag(StaticInst::IsControl); 17710199SAndrew.Bardsley@arm.com if ((*uop)->isCondCtrl()) 17810199SAndrew.Bardsley@arm.com setFlag(StaticInst::IsCondControl); 17910199SAndrew.Bardsley@arm.com if ((*uop)->isIndirectCtrl()) 18010199SAndrew.Bardsley@arm.com setFlag(StaticInst::IsIndirectControl); 18110199SAndrew.Bardsley@arm.com if ((*uop)->isReturn()) 18210199SAndrew.Bardsley@arm.com setFlag(StaticInst::IsReturn); 18310199SAndrew.Bardsley@arm.com 1847343Sgblack@eecs.umich.edu for (StaticInstPtr *curUop = microOps; 1857343Sgblack@eecs.umich.edu !(*curUop)->isLastMicroop(); curUop++) { 1867343Sgblack@eecs.umich.edu MicroOp * uopPtr = dynamic_cast<MicroOp *>(curUop->get()); 1877343Sgblack@eecs.umich.edu assert(uopPtr); 1887343Sgblack@eecs.umich.edu uopPtr->setDelayedCommit(); 1897343Sgblack@eecs.umich.edu } 1907170Sgblack@eecs.umich.edu} 1917170Sgblack@eecs.umich.edu 19210037SARM gem5 DevelopersPairMemOp::PairMemOp(const char *mnem, ExtMachInst machInst, OpClass __opClass, 19310037SARM gem5 Developers uint32_t size, bool fp, bool load, bool noAlloc, 19410037SARM gem5 Developers bool signExt, bool exclusive, bool acrel, 19510037SARM gem5 Developers int64_t imm, AddrMode mode, 19610037SARM gem5 Developers IntRegIndex rn, IntRegIndex rt, IntRegIndex rt2) : 19710037SARM gem5 Developers PredMacroOp(mnem, machInst, __opClass) 19810037SARM gem5 Developers{ 19910037SARM gem5 Developers bool writeback = (mode != AddrMd_Offset); 20010037SARM gem5 Developers numMicroops = 1 + (size / 4) + (writeback ? 1 : 0); 20110037SARM gem5 Developers microOps = new StaticInstPtr[numMicroops]; 20210037SARM gem5 Developers 20310037SARM gem5 Developers StaticInstPtr *uop = microOps; 20410037SARM gem5 Developers 20510037SARM gem5 Developers bool post = (mode == AddrMd_PostIndex); 20610037SARM gem5 Developers 20710037SARM gem5 Developers rn = makeSP(rn); 20810037SARM gem5 Developers 20910037SARM gem5 Developers *uop = new MicroAddXiSpAlignUop(machInst, INTREG_UREG0, rn, post ? 0 : imm); 21010037SARM gem5 Developers 21110037SARM gem5 Developers if (fp) { 21210037SARM gem5 Developers if (size == 16) { 21310037SARM gem5 Developers if (load) { 21410037SARM gem5 Developers *++uop = new MicroLdrQBFpXImmUop(machInst, rt, 21510037SARM gem5 Developers INTREG_UREG0, 0, noAlloc, exclusive, acrel); 21610037SARM gem5 Developers *++uop = new MicroLdrQTFpXImmUop(machInst, rt, 21710037SARM gem5 Developers INTREG_UREG0, 0, noAlloc, exclusive, acrel); 21810037SARM gem5 Developers *++uop = new MicroLdrQBFpXImmUop(machInst, rt2, 21910037SARM gem5 Developers INTREG_UREG0, 16, noAlloc, exclusive, acrel); 22010037SARM gem5 Developers *++uop = new MicroLdrQTFpXImmUop(machInst, rt2, 22110037SARM gem5 Developers INTREG_UREG0, 16, noAlloc, exclusive, acrel); 22210037SARM gem5 Developers } else { 22310037SARM gem5 Developers *++uop = new MicroStrQBFpXImmUop(machInst, rt, 22410037SARM gem5 Developers INTREG_UREG0, 0, noAlloc, exclusive, acrel); 22510037SARM gem5 Developers *++uop = new MicroStrQTFpXImmUop(machInst, rt, 22610037SARM gem5 Developers INTREG_UREG0, 0, noAlloc, exclusive, acrel); 22710037SARM gem5 Developers *++uop = new MicroStrQBFpXImmUop(machInst, rt2, 22810037SARM gem5 Developers INTREG_UREG0, 16, noAlloc, exclusive, acrel); 22910037SARM gem5 Developers *++uop = new MicroStrQTFpXImmUop(machInst, rt2, 23010037SARM gem5 Developers INTREG_UREG0, 16, noAlloc, exclusive, acrel); 23110037SARM gem5 Developers } 23210037SARM gem5 Developers } else if (size == 8) { 23310037SARM gem5 Developers if (load) { 23410037SARM gem5 Developers *++uop = new MicroLdrFpXImmUop(machInst, rt, 23510037SARM gem5 Developers INTREG_UREG0, 0, noAlloc, exclusive, acrel); 23610037SARM gem5 Developers *++uop = new MicroLdrFpXImmUop(machInst, rt2, 23710037SARM gem5 Developers INTREG_UREG0, 8, noAlloc, exclusive, acrel); 23810037SARM gem5 Developers } else { 23910037SARM gem5 Developers *++uop = new MicroStrFpXImmUop(machInst, rt, 24010037SARM gem5 Developers INTREG_UREG0, 0, noAlloc, exclusive, acrel); 24110037SARM gem5 Developers *++uop = new MicroStrFpXImmUop(machInst, rt2, 24210037SARM gem5 Developers INTREG_UREG0, 8, noAlloc, exclusive, acrel); 24310037SARM gem5 Developers } 24410037SARM gem5 Developers } else if (size == 4) { 24510037SARM gem5 Developers if (load) { 24610037SARM gem5 Developers *++uop = new MicroLdrDFpXImmUop(machInst, rt, rt2, 24710037SARM gem5 Developers INTREG_UREG0, 0, noAlloc, exclusive, acrel); 24810037SARM gem5 Developers } else { 24910037SARM gem5 Developers *++uop = new MicroStrDFpXImmUop(machInst, rt, rt2, 25010037SARM gem5 Developers INTREG_UREG0, 0, noAlloc, exclusive, acrel); 25110037SARM gem5 Developers } 25210037SARM gem5 Developers } 25310037SARM gem5 Developers } else { 25410037SARM gem5 Developers if (size == 8) { 25510037SARM gem5 Developers if (load) { 25610037SARM gem5 Developers *++uop = new MicroLdrXImmUop(machInst, rt, INTREG_UREG0, 25710037SARM gem5 Developers 0, noAlloc, exclusive, acrel); 25810037SARM gem5 Developers *++uop = new MicroLdrXImmUop(machInst, rt2, INTREG_UREG0, 25910037SARM gem5 Developers size, noAlloc, exclusive, acrel); 26010037SARM gem5 Developers } else { 26110037SARM gem5 Developers *++uop = new MicroStrXImmUop(machInst, rt, INTREG_UREG0, 26210037SARM gem5 Developers 0, noAlloc, exclusive, acrel); 26310037SARM gem5 Developers *++uop = new MicroStrXImmUop(machInst, rt2, INTREG_UREG0, 26410037SARM gem5 Developers size, noAlloc, exclusive, acrel); 26510037SARM gem5 Developers } 26610037SARM gem5 Developers } else if (size == 4) { 26710037SARM gem5 Developers if (load) { 26810037SARM gem5 Developers if (signExt) { 26910037SARM gem5 Developers *++uop = new MicroLdrDSXImmUop(machInst, rt, rt2, 27010037SARM gem5 Developers INTREG_UREG0, 0, noAlloc, exclusive, acrel); 27110037SARM gem5 Developers } else { 27210037SARM gem5 Developers *++uop = new MicroLdrDUXImmUop(machInst, rt, rt2, 27310037SARM gem5 Developers INTREG_UREG0, 0, noAlloc, exclusive, acrel); 27410037SARM gem5 Developers } 27510037SARM gem5 Developers } else { 27610037SARM gem5 Developers *++uop = new MicroStrDXImmUop(machInst, rt, rt2, 27710037SARM gem5 Developers INTREG_UREG0, 0, noAlloc, exclusive, acrel); 27810037SARM gem5 Developers } 27910037SARM gem5 Developers } 28010037SARM gem5 Developers } 28110037SARM gem5 Developers 28210037SARM gem5 Developers if (writeback) { 28310037SARM gem5 Developers *++uop = new MicroAddXiUop(machInst, rn, INTREG_UREG0, 28410037SARM gem5 Developers post ? imm : 0); 28510037SARM gem5 Developers } 28610037SARM gem5 Developers 28710037SARM gem5 Developers (*uop)->setLastMicroop(); 28810037SARM gem5 Developers 28910037SARM gem5 Developers for (StaticInstPtr *curUop = microOps; 29010037SARM gem5 Developers !(*curUop)->isLastMicroop(); curUop++) { 29110037SARM gem5 Developers (*curUop)->setDelayedCommit(); 29210037SARM gem5 Developers } 29310037SARM gem5 Developers} 29410037SARM gem5 Developers 29510037SARM gem5 DevelopersBigFpMemImmOp::BigFpMemImmOp(const char *mnem, ExtMachInst machInst, 29610037SARM gem5 Developers OpClass __opClass, bool load, IntRegIndex dest, 29710037SARM gem5 Developers IntRegIndex base, int64_t imm) : 29810037SARM gem5 Developers PredMacroOp(mnem, machInst, __opClass) 29910037SARM gem5 Developers{ 30010037SARM gem5 Developers numMicroops = 2; 30110037SARM gem5 Developers microOps = new StaticInstPtr[numMicroops]; 30210037SARM gem5 Developers 30310037SARM gem5 Developers if (load) { 30410037SARM gem5 Developers microOps[0] = new MicroLdrQBFpXImmUop(machInst, dest, base, imm); 30510037SARM gem5 Developers microOps[1] = new MicroLdrQTFpXImmUop(machInst, dest, base, imm); 30610037SARM gem5 Developers } else { 30710037SARM gem5 Developers microOps[0] = new MicroStrQBFpXImmUop(machInst, dest, base, imm); 30810037SARM gem5 Developers microOps[1] = new MicroStrQTFpXImmUop(machInst, dest, base, imm); 30910037SARM gem5 Developers } 31010037SARM gem5 Developers microOps[0]->setDelayedCommit(); 31110037SARM gem5 Developers microOps[1]->setLastMicroop(); 31210037SARM gem5 Developers} 31310037SARM gem5 Developers 31410037SARM gem5 DevelopersBigFpMemPostOp::BigFpMemPostOp(const char *mnem, ExtMachInst machInst, 31510037SARM gem5 Developers OpClass __opClass, bool load, IntRegIndex dest, 31610037SARM gem5 Developers IntRegIndex base, int64_t imm) : 31710037SARM gem5 Developers PredMacroOp(mnem, machInst, __opClass) 31810037SARM gem5 Developers{ 31910037SARM gem5 Developers numMicroops = 3; 32010037SARM gem5 Developers microOps = new StaticInstPtr[numMicroops]; 32110037SARM gem5 Developers 32210037SARM gem5 Developers if (load) { 32310037SARM gem5 Developers microOps[0] = new MicroLdrQBFpXImmUop(machInst, dest, base, 0); 32410037SARM gem5 Developers microOps[1] = new MicroLdrQTFpXImmUop(machInst, dest, base, 0); 32510037SARM gem5 Developers } else { 32610037SARM gem5 Developers microOps[0] = new MicroStrQBFpXImmUop(machInst, dest, base, 0); 32710037SARM gem5 Developers microOps[1] = new MicroStrQTFpXImmUop(machInst, dest, base, 0); 32810037SARM gem5 Developers } 32910037SARM gem5 Developers microOps[2] = new MicroAddXiUop(machInst, base, base, imm); 33010037SARM gem5 Developers 33110037SARM gem5 Developers microOps[0]->setDelayedCommit(); 33210037SARM gem5 Developers microOps[1]->setDelayedCommit(); 33310037SARM gem5 Developers microOps[2]->setLastMicroop(); 33410037SARM gem5 Developers} 33510037SARM gem5 Developers 33610037SARM gem5 DevelopersBigFpMemPreOp::BigFpMemPreOp(const char *mnem, ExtMachInst machInst, 33710037SARM gem5 Developers OpClass __opClass, bool load, IntRegIndex dest, 33810037SARM gem5 Developers IntRegIndex base, int64_t imm) : 33910037SARM gem5 Developers PredMacroOp(mnem, machInst, __opClass) 34010037SARM gem5 Developers{ 34110037SARM gem5 Developers numMicroops = 3; 34210037SARM gem5 Developers microOps = new StaticInstPtr[numMicroops]; 34310037SARM gem5 Developers 34410037SARM gem5 Developers if (load) { 34510037SARM gem5 Developers microOps[0] = new MicroLdrQBFpXImmUop(machInst, dest, base, imm); 34610037SARM gem5 Developers microOps[1] = new MicroLdrQTFpXImmUop(machInst, dest, base, imm); 34710037SARM gem5 Developers } else { 34810037SARM gem5 Developers microOps[0] = new MicroStrQBFpXImmUop(machInst, dest, base, imm); 34910037SARM gem5 Developers microOps[1] = new MicroStrQTFpXImmUop(machInst, dest, base, imm); 35010037SARM gem5 Developers } 35110037SARM gem5 Developers microOps[2] = new MicroAddXiUop(machInst, base, base, imm); 35210037SARM gem5 Developers 35310037SARM gem5 Developers microOps[0]->setDelayedCommit(); 35410037SARM gem5 Developers microOps[1]->setDelayedCommit(); 35510037SARM gem5 Developers microOps[2]->setLastMicroop(); 35610037SARM gem5 Developers} 35710037SARM gem5 Developers 35810037SARM gem5 DevelopersBigFpMemRegOp::BigFpMemRegOp(const char *mnem, ExtMachInst machInst, 35910037SARM gem5 Developers OpClass __opClass, bool load, IntRegIndex dest, 36010037SARM gem5 Developers IntRegIndex base, IntRegIndex offset, 36110037SARM gem5 Developers ArmExtendType type, int64_t imm) : 36210037SARM gem5 Developers PredMacroOp(mnem, machInst, __opClass) 36310037SARM gem5 Developers{ 36410037SARM gem5 Developers numMicroops = 2; 36510037SARM gem5 Developers microOps = new StaticInstPtr[numMicroops]; 36610037SARM gem5 Developers 36710037SARM gem5 Developers if (load) { 36810037SARM gem5 Developers microOps[0] = new MicroLdrQBFpXRegUop(machInst, dest, base, 36910037SARM gem5 Developers offset, type, imm); 37010037SARM gem5 Developers microOps[1] = new MicroLdrQTFpXRegUop(machInst, dest, base, 37110037SARM gem5 Developers offset, type, imm); 37210037SARM gem5 Developers } else { 37310037SARM gem5 Developers microOps[0] = new MicroStrQBFpXRegUop(machInst, dest, base, 37410037SARM gem5 Developers offset, type, imm); 37510037SARM gem5 Developers microOps[1] = new MicroStrQTFpXRegUop(machInst, dest, base, 37610037SARM gem5 Developers offset, type, imm); 37710037SARM gem5 Developers } 37810037SARM gem5 Developers 37910037SARM gem5 Developers microOps[0]->setDelayedCommit(); 38010037SARM gem5 Developers microOps[1]->setLastMicroop(); 38110037SARM gem5 Developers} 38210037SARM gem5 Developers 38310037SARM gem5 DevelopersBigFpMemLitOp::BigFpMemLitOp(const char *mnem, ExtMachInst machInst, 38410037SARM gem5 Developers OpClass __opClass, IntRegIndex dest, 38510037SARM gem5 Developers int64_t imm) : 38610037SARM gem5 Developers PredMacroOp(mnem, machInst, __opClass) 38710037SARM gem5 Developers{ 38810037SARM gem5 Developers numMicroops = 2; 38910037SARM gem5 Developers microOps = new StaticInstPtr[numMicroops]; 39010037SARM gem5 Developers 39110037SARM gem5 Developers microOps[0] = new MicroLdrQBFpXLitUop(machInst, dest, imm); 39210037SARM gem5 Developers microOps[1] = new MicroLdrQTFpXLitUop(machInst, dest, imm); 39310037SARM gem5 Developers 39410037SARM gem5 Developers microOps[0]->setDelayedCommit(); 39510037SARM gem5 Developers microOps[1]->setLastMicroop(); 39610037SARM gem5 Developers} 39710037SARM gem5 Developers 3987639Sgblack@eecs.umich.eduVldMultOp::VldMultOp(const char *mnem, ExtMachInst machInst, OpClass __opClass, 3997639Sgblack@eecs.umich.edu unsigned elems, RegIndex rn, RegIndex vd, unsigned regs, 4007639Sgblack@eecs.umich.edu unsigned inc, uint32_t size, uint32_t align, RegIndex rm) : 4017639Sgblack@eecs.umich.edu PredMacroOp(mnem, machInst, __opClass) 4027639Sgblack@eecs.umich.edu{ 4037639Sgblack@eecs.umich.edu assert(regs > 0 && regs <= 4); 4047639Sgblack@eecs.umich.edu assert(regs % elems == 0); 4057639Sgblack@eecs.umich.edu 4067639Sgblack@eecs.umich.edu numMicroops = (regs > 2) ? 2 : 1; 4077639Sgblack@eecs.umich.edu bool wb = (rm != 15); 4087639Sgblack@eecs.umich.edu bool deinterleave = (elems > 1); 4097639Sgblack@eecs.umich.edu 4107639Sgblack@eecs.umich.edu if (wb) numMicroops++; 4117639Sgblack@eecs.umich.edu if (deinterleave) numMicroops += (regs / elems); 4127639Sgblack@eecs.umich.edu microOps = new StaticInstPtr[numMicroops]; 4137639Sgblack@eecs.umich.edu 41410037SARM gem5 Developers RegIndex rMid = deinterleave ? NumFloatV7ArchRegs : vd * 2; 4157639Sgblack@eecs.umich.edu 4167639Sgblack@eecs.umich.edu uint32_t noAlign = TLB::MustBeOne; 4177639Sgblack@eecs.umich.edu 4187639Sgblack@eecs.umich.edu unsigned uopIdx = 0; 4197639Sgblack@eecs.umich.edu switch (regs) { 4207639Sgblack@eecs.umich.edu case 4: 4217639Sgblack@eecs.umich.edu microOps[uopIdx++] = newNeonMemInst<MicroLdrNeon16Uop>( 4227639Sgblack@eecs.umich.edu size, machInst, rMid, rn, 0, align); 4237639Sgblack@eecs.umich.edu microOps[uopIdx++] = newNeonMemInst<MicroLdrNeon16Uop>( 4247639Sgblack@eecs.umich.edu size, machInst, rMid + 4, rn, 16, noAlign); 4257639Sgblack@eecs.umich.edu break; 4267639Sgblack@eecs.umich.edu case 3: 4277639Sgblack@eecs.umich.edu microOps[uopIdx++] = newNeonMemInst<MicroLdrNeon16Uop>( 4287639Sgblack@eecs.umich.edu size, machInst, rMid, rn, 0, align); 4297639Sgblack@eecs.umich.edu microOps[uopIdx++] = newNeonMemInst<MicroLdrNeon8Uop>( 4307639Sgblack@eecs.umich.edu size, machInst, rMid + 4, rn, 16, noAlign); 4317639Sgblack@eecs.umich.edu break; 4327639Sgblack@eecs.umich.edu case 2: 4337639Sgblack@eecs.umich.edu microOps[uopIdx++] = newNeonMemInst<MicroLdrNeon16Uop>( 4347639Sgblack@eecs.umich.edu size, machInst, rMid, rn, 0, align); 4357639Sgblack@eecs.umich.edu break; 4367639Sgblack@eecs.umich.edu case 1: 4377639Sgblack@eecs.umich.edu microOps[uopIdx++] = newNeonMemInst<MicroLdrNeon8Uop>( 4387639Sgblack@eecs.umich.edu size, machInst, rMid, rn, 0, align); 4397639Sgblack@eecs.umich.edu break; 4407639Sgblack@eecs.umich.edu default: 4417853SMatt.Horsnell@ARM.com // Unknown number of registers 4427853SMatt.Horsnell@ARM.com microOps[uopIdx++] = new Unknown(machInst); 4437639Sgblack@eecs.umich.edu } 4447639Sgblack@eecs.umich.edu if (wb) { 4457639Sgblack@eecs.umich.edu if (rm != 15 && rm != 13) { 4467639Sgblack@eecs.umich.edu microOps[uopIdx++] = 4477646Sgene.wu@arm.com new MicroAddUop(machInst, rn, rn, rm, 0, ArmISA::LSL); 4487639Sgblack@eecs.umich.edu } else { 4497639Sgblack@eecs.umich.edu microOps[uopIdx++] = 4507639Sgblack@eecs.umich.edu new MicroAddiUop(machInst, rn, rn, regs * 8); 4517639Sgblack@eecs.umich.edu } 4527639Sgblack@eecs.umich.edu } 4537639Sgblack@eecs.umich.edu if (deinterleave) { 4547639Sgblack@eecs.umich.edu switch (elems) { 4557639Sgblack@eecs.umich.edu case 4: 4567639Sgblack@eecs.umich.edu assert(regs == 4); 4577639Sgblack@eecs.umich.edu microOps[uopIdx++] = newNeonMixInst<MicroDeintNeon8Uop>( 4587639Sgblack@eecs.umich.edu size, machInst, vd * 2, rMid, inc * 2); 4597639Sgblack@eecs.umich.edu break; 4607639Sgblack@eecs.umich.edu case 3: 4617639Sgblack@eecs.umich.edu assert(regs == 3); 4627639Sgblack@eecs.umich.edu microOps[uopIdx++] = newNeonMixInst<MicroDeintNeon6Uop>( 4637639Sgblack@eecs.umich.edu size, machInst, vd * 2, rMid, inc * 2); 4647639Sgblack@eecs.umich.edu break; 4657639Sgblack@eecs.umich.edu case 2: 4667639Sgblack@eecs.umich.edu assert(regs == 4 || regs == 2); 4677639Sgblack@eecs.umich.edu if (regs == 4) { 4687639Sgblack@eecs.umich.edu microOps[uopIdx++] = newNeonMixInst<MicroDeintNeon4Uop>( 4697639Sgblack@eecs.umich.edu size, machInst, vd * 2, rMid, inc * 2); 4707639Sgblack@eecs.umich.edu microOps[uopIdx++] = newNeonMixInst<MicroDeintNeon4Uop>( 4717639Sgblack@eecs.umich.edu size, machInst, vd * 2 + 2, rMid + 4, inc * 2); 4727639Sgblack@eecs.umich.edu } else { 4737639Sgblack@eecs.umich.edu microOps[uopIdx++] = newNeonMixInst<MicroDeintNeon4Uop>( 4747639Sgblack@eecs.umich.edu size, machInst, vd * 2, rMid, inc * 2); 4757639Sgblack@eecs.umich.edu } 4767639Sgblack@eecs.umich.edu break; 4777639Sgblack@eecs.umich.edu default: 4787853SMatt.Horsnell@ARM.com // Bad number of elements to deinterleave 4797853SMatt.Horsnell@ARM.com microOps[uopIdx++] = new Unknown(machInst); 4807639Sgblack@eecs.umich.edu } 4817639Sgblack@eecs.umich.edu } 4827639Sgblack@eecs.umich.edu assert(uopIdx == numMicroops); 4837639Sgblack@eecs.umich.edu 4847639Sgblack@eecs.umich.edu for (unsigned i = 0; i < numMicroops - 1; i++) { 4857639Sgblack@eecs.umich.edu MicroOp * uopPtr = dynamic_cast<MicroOp *>(microOps[i].get()); 4867639Sgblack@eecs.umich.edu assert(uopPtr); 4877639Sgblack@eecs.umich.edu uopPtr->setDelayedCommit(); 4887639Sgblack@eecs.umich.edu } 4897639Sgblack@eecs.umich.edu microOps[numMicroops - 1]->setLastMicroop(); 4907639Sgblack@eecs.umich.edu} 4917639Sgblack@eecs.umich.edu 4927639Sgblack@eecs.umich.eduVldSingleOp::VldSingleOp(const char *mnem, ExtMachInst machInst, 4937639Sgblack@eecs.umich.edu OpClass __opClass, bool all, unsigned elems, 4947639Sgblack@eecs.umich.edu RegIndex rn, RegIndex vd, unsigned regs, 4957639Sgblack@eecs.umich.edu unsigned inc, uint32_t size, uint32_t align, 4967639Sgblack@eecs.umich.edu RegIndex rm, unsigned lane) : 4977639Sgblack@eecs.umich.edu PredMacroOp(mnem, machInst, __opClass) 4987639Sgblack@eecs.umich.edu{ 4997639Sgblack@eecs.umich.edu assert(regs > 0 && regs <= 4); 5007639Sgblack@eecs.umich.edu assert(regs % elems == 0); 5017639Sgblack@eecs.umich.edu 5027639Sgblack@eecs.umich.edu unsigned eBytes = (1 << size); 5037639Sgblack@eecs.umich.edu unsigned loadSize = eBytes * elems; 5047639Sgblack@eecs.umich.edu unsigned loadRegs M5_VAR_USED = (loadSize + sizeof(FloatRegBits) - 1) / 5057639Sgblack@eecs.umich.edu sizeof(FloatRegBits); 5067639Sgblack@eecs.umich.edu 5077639Sgblack@eecs.umich.edu assert(loadRegs > 0 && loadRegs <= 4); 5087639Sgblack@eecs.umich.edu 5097639Sgblack@eecs.umich.edu numMicroops = 1; 5107639Sgblack@eecs.umich.edu bool wb = (rm != 15); 5117639Sgblack@eecs.umich.edu 5127639Sgblack@eecs.umich.edu if (wb) numMicroops++; 5137639Sgblack@eecs.umich.edu numMicroops += (regs / elems); 5147639Sgblack@eecs.umich.edu microOps = new StaticInstPtr[numMicroops]; 5157639Sgblack@eecs.umich.edu 51610037SARM gem5 Developers RegIndex ufp0 = NumFloatV7ArchRegs; 5177639Sgblack@eecs.umich.edu 5187639Sgblack@eecs.umich.edu unsigned uopIdx = 0; 5197639Sgblack@eecs.umich.edu switch (loadSize) { 5207639Sgblack@eecs.umich.edu case 1: 5217639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroLdrNeon1Uop<uint8_t>( 5227639Sgblack@eecs.umich.edu machInst, ufp0, rn, 0, align); 5237639Sgblack@eecs.umich.edu break; 5247639Sgblack@eecs.umich.edu case 2: 5257639Sgblack@eecs.umich.edu if (eBytes == 2) { 5267639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroLdrNeon2Uop<uint16_t>( 5277639Sgblack@eecs.umich.edu machInst, ufp0, rn, 0, align); 5287639Sgblack@eecs.umich.edu } else { 5297639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroLdrNeon2Uop<uint8_t>( 5307639Sgblack@eecs.umich.edu machInst, ufp0, rn, 0, align); 5317639Sgblack@eecs.umich.edu } 5327639Sgblack@eecs.umich.edu break; 5337639Sgblack@eecs.umich.edu case 3: 5347639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroLdrNeon3Uop<uint8_t>( 5357639Sgblack@eecs.umich.edu machInst, ufp0, rn, 0, align); 5367639Sgblack@eecs.umich.edu break; 5377639Sgblack@eecs.umich.edu case 4: 5387639Sgblack@eecs.umich.edu switch (eBytes) { 5397639Sgblack@eecs.umich.edu case 1: 5407639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroLdrNeon4Uop<uint8_t>( 5417639Sgblack@eecs.umich.edu machInst, ufp0, rn, 0, align); 5427639Sgblack@eecs.umich.edu break; 5437639Sgblack@eecs.umich.edu case 2: 5447639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroLdrNeon4Uop<uint16_t>( 5457639Sgblack@eecs.umich.edu machInst, ufp0, rn, 0, align); 5467639Sgblack@eecs.umich.edu break; 5477639Sgblack@eecs.umich.edu case 4: 5487639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroLdrNeon4Uop<uint32_t>( 5497639Sgblack@eecs.umich.edu machInst, ufp0, rn, 0, align); 5507639Sgblack@eecs.umich.edu break; 5517639Sgblack@eecs.umich.edu } 5527639Sgblack@eecs.umich.edu break; 5537639Sgblack@eecs.umich.edu case 6: 5547639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroLdrNeon6Uop<uint16_t>( 5557639Sgblack@eecs.umich.edu machInst, ufp0, rn, 0, align); 5567639Sgblack@eecs.umich.edu break; 5577639Sgblack@eecs.umich.edu case 8: 5587639Sgblack@eecs.umich.edu switch (eBytes) { 5597639Sgblack@eecs.umich.edu case 2: 5607639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroLdrNeon8Uop<uint16_t>( 5617639Sgblack@eecs.umich.edu machInst, ufp0, rn, 0, align); 5627639Sgblack@eecs.umich.edu break; 5637639Sgblack@eecs.umich.edu case 4: 5647639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroLdrNeon8Uop<uint32_t>( 5657639Sgblack@eecs.umich.edu machInst, ufp0, rn, 0, align); 5667639Sgblack@eecs.umich.edu break; 5677639Sgblack@eecs.umich.edu } 5687639Sgblack@eecs.umich.edu break; 5697639Sgblack@eecs.umich.edu case 12: 5707639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroLdrNeon12Uop<uint32_t>( 5717639Sgblack@eecs.umich.edu machInst, ufp0, rn, 0, align); 5727639Sgblack@eecs.umich.edu break; 5737639Sgblack@eecs.umich.edu case 16: 5747639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroLdrNeon16Uop<uint32_t>( 5757639Sgblack@eecs.umich.edu machInst, ufp0, rn, 0, align); 5767639Sgblack@eecs.umich.edu break; 5777639Sgblack@eecs.umich.edu default: 5787853SMatt.Horsnell@ARM.com // Unrecognized load size 5797853SMatt.Horsnell@ARM.com microOps[uopIdx++] = new Unknown(machInst); 5807639Sgblack@eecs.umich.edu } 5817639Sgblack@eecs.umich.edu if (wb) { 5827639Sgblack@eecs.umich.edu if (rm != 15 && rm != 13) { 5837639Sgblack@eecs.umich.edu microOps[uopIdx++] = 5847646Sgene.wu@arm.com new MicroAddUop(machInst, rn, rn, rm, 0, ArmISA::LSL); 5857639Sgblack@eecs.umich.edu } else { 5867639Sgblack@eecs.umich.edu microOps[uopIdx++] = 5877639Sgblack@eecs.umich.edu new MicroAddiUop(machInst, rn, rn, loadSize); 5887639Sgblack@eecs.umich.edu } 5897639Sgblack@eecs.umich.edu } 5907639Sgblack@eecs.umich.edu switch (elems) { 5917639Sgblack@eecs.umich.edu case 4: 5927639Sgblack@eecs.umich.edu assert(regs == 4); 5937639Sgblack@eecs.umich.edu switch (size) { 5947639Sgblack@eecs.umich.edu case 0: 5957639Sgblack@eecs.umich.edu if (all) { 5967639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroUnpackAllNeon2to8Uop<uint8_t>( 5977639Sgblack@eecs.umich.edu machInst, vd * 2, ufp0, inc * 2); 5987639Sgblack@eecs.umich.edu } else { 5997639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroUnpackNeon2to8Uop<uint8_t>( 6007639Sgblack@eecs.umich.edu machInst, vd * 2, ufp0, inc * 2, lane); 6017639Sgblack@eecs.umich.edu } 6027639Sgblack@eecs.umich.edu break; 6037639Sgblack@eecs.umich.edu case 1: 6047639Sgblack@eecs.umich.edu if (all) { 6057639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroUnpackAllNeon2to8Uop<uint16_t>( 6067639Sgblack@eecs.umich.edu machInst, vd * 2, ufp0, inc * 2); 6077639Sgblack@eecs.umich.edu } else { 6087639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroUnpackNeon2to8Uop<uint16_t>( 6097639Sgblack@eecs.umich.edu machInst, vd * 2, ufp0, inc * 2, lane); 6107639Sgblack@eecs.umich.edu } 6117639Sgblack@eecs.umich.edu break; 6127639Sgblack@eecs.umich.edu case 2: 6137639Sgblack@eecs.umich.edu if (all) { 6147639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroUnpackAllNeon4to8Uop<uint32_t>( 6157639Sgblack@eecs.umich.edu machInst, vd * 2, ufp0, inc * 2); 6167639Sgblack@eecs.umich.edu } else { 6177639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroUnpackNeon4to8Uop<uint32_t>( 6187639Sgblack@eecs.umich.edu machInst, vd * 2, ufp0, inc * 2, lane); 6197639Sgblack@eecs.umich.edu } 6207639Sgblack@eecs.umich.edu break; 6217639Sgblack@eecs.umich.edu default: 6227853SMatt.Horsnell@ARM.com // Bad size 6237853SMatt.Horsnell@ARM.com microOps[uopIdx++] = new Unknown(machInst); 6247639Sgblack@eecs.umich.edu break; 6257639Sgblack@eecs.umich.edu } 6267639Sgblack@eecs.umich.edu break; 6277639Sgblack@eecs.umich.edu case 3: 6287639Sgblack@eecs.umich.edu assert(regs == 3); 6297639Sgblack@eecs.umich.edu switch (size) { 6307639Sgblack@eecs.umich.edu case 0: 6317639Sgblack@eecs.umich.edu if (all) { 6327639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroUnpackAllNeon2to6Uop<uint8_t>( 6337639Sgblack@eecs.umich.edu machInst, vd * 2, ufp0, inc * 2); 6347639Sgblack@eecs.umich.edu } else { 6357639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroUnpackNeon2to6Uop<uint8_t>( 6367639Sgblack@eecs.umich.edu machInst, vd * 2, ufp0, inc * 2, lane); 6377639Sgblack@eecs.umich.edu } 6387639Sgblack@eecs.umich.edu break; 6397639Sgblack@eecs.umich.edu case 1: 6407639Sgblack@eecs.umich.edu if (all) { 6417639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroUnpackAllNeon2to6Uop<uint16_t>( 6427639Sgblack@eecs.umich.edu machInst, vd * 2, ufp0, inc * 2); 6437639Sgblack@eecs.umich.edu } else { 6447639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroUnpackNeon2to6Uop<uint16_t>( 6457639Sgblack@eecs.umich.edu machInst, vd * 2, ufp0, inc * 2, lane); 6467639Sgblack@eecs.umich.edu } 6477639Sgblack@eecs.umich.edu break; 6487639Sgblack@eecs.umich.edu case 2: 6497639Sgblack@eecs.umich.edu if (all) { 6507639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroUnpackAllNeon4to6Uop<uint32_t>( 6517639Sgblack@eecs.umich.edu machInst, vd * 2, ufp0, inc * 2); 6527639Sgblack@eecs.umich.edu } else { 6537639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroUnpackNeon4to6Uop<uint32_t>( 6547639Sgblack@eecs.umich.edu machInst, vd * 2, ufp0, inc * 2, lane); 6557639Sgblack@eecs.umich.edu } 6567639Sgblack@eecs.umich.edu break; 6577639Sgblack@eecs.umich.edu default: 6587853SMatt.Horsnell@ARM.com // Bad size 6597853SMatt.Horsnell@ARM.com microOps[uopIdx++] = new Unknown(machInst); 6607639Sgblack@eecs.umich.edu break; 6617639Sgblack@eecs.umich.edu } 6627639Sgblack@eecs.umich.edu break; 6637639Sgblack@eecs.umich.edu case 2: 6647639Sgblack@eecs.umich.edu assert(regs == 2); 6657639Sgblack@eecs.umich.edu assert(loadRegs <= 2); 6667639Sgblack@eecs.umich.edu switch (size) { 6677639Sgblack@eecs.umich.edu case 0: 6687639Sgblack@eecs.umich.edu if (all) { 6697639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroUnpackAllNeon2to4Uop<uint8_t>( 6707639Sgblack@eecs.umich.edu machInst, vd * 2, ufp0, inc * 2); 6717639Sgblack@eecs.umich.edu } else { 6727639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroUnpackNeon2to4Uop<uint8_t>( 6737639Sgblack@eecs.umich.edu machInst, vd * 2, ufp0, inc * 2, lane); 6747639Sgblack@eecs.umich.edu } 6757639Sgblack@eecs.umich.edu break; 6767639Sgblack@eecs.umich.edu case 1: 6777639Sgblack@eecs.umich.edu if (all) { 6787639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroUnpackAllNeon2to4Uop<uint16_t>( 6797639Sgblack@eecs.umich.edu machInst, vd * 2, ufp0, inc * 2); 6807639Sgblack@eecs.umich.edu } else { 6817639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroUnpackNeon2to4Uop<uint16_t>( 6827639Sgblack@eecs.umich.edu machInst, vd * 2, ufp0, inc * 2, lane); 6837639Sgblack@eecs.umich.edu } 6847639Sgblack@eecs.umich.edu break; 6857639Sgblack@eecs.umich.edu case 2: 6867639Sgblack@eecs.umich.edu if (all) { 6877639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroUnpackAllNeon2to4Uop<uint32_t>( 6887639Sgblack@eecs.umich.edu machInst, vd * 2, ufp0, inc * 2); 6897639Sgblack@eecs.umich.edu } else { 6907639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroUnpackNeon2to4Uop<uint32_t>( 6917639Sgblack@eecs.umich.edu machInst, vd * 2, ufp0, inc * 2, lane); 6927639Sgblack@eecs.umich.edu } 6937639Sgblack@eecs.umich.edu break; 6947639Sgblack@eecs.umich.edu default: 6957853SMatt.Horsnell@ARM.com // Bad size 6967853SMatt.Horsnell@ARM.com microOps[uopIdx++] = new Unknown(machInst); 6977639Sgblack@eecs.umich.edu break; 6987639Sgblack@eecs.umich.edu } 6997639Sgblack@eecs.umich.edu break; 7007639Sgblack@eecs.umich.edu case 1: 7017639Sgblack@eecs.umich.edu assert(regs == 1 || (all && regs == 2)); 7027639Sgblack@eecs.umich.edu assert(loadRegs <= 2); 7037639Sgblack@eecs.umich.edu for (unsigned offset = 0; offset < regs; offset++) { 7047639Sgblack@eecs.umich.edu switch (size) { 7057639Sgblack@eecs.umich.edu case 0: 7067639Sgblack@eecs.umich.edu if (all) { 7077639Sgblack@eecs.umich.edu microOps[uopIdx++] = 7087639Sgblack@eecs.umich.edu new MicroUnpackAllNeon2to2Uop<uint8_t>( 7097639Sgblack@eecs.umich.edu machInst, (vd + offset) * 2, ufp0, inc * 2); 7107639Sgblack@eecs.umich.edu } else { 7117639Sgblack@eecs.umich.edu microOps[uopIdx++] = 7127639Sgblack@eecs.umich.edu new MicroUnpackNeon2to2Uop<uint8_t>( 7137639Sgblack@eecs.umich.edu machInst, (vd + offset) * 2, ufp0, inc * 2, lane); 7147639Sgblack@eecs.umich.edu } 7157639Sgblack@eecs.umich.edu break; 7167639Sgblack@eecs.umich.edu case 1: 7177639Sgblack@eecs.umich.edu if (all) { 7187639Sgblack@eecs.umich.edu microOps[uopIdx++] = 7197639Sgblack@eecs.umich.edu new MicroUnpackAllNeon2to2Uop<uint16_t>( 7207639Sgblack@eecs.umich.edu machInst, (vd + offset) * 2, ufp0, inc * 2); 7217639Sgblack@eecs.umich.edu } else { 7227639Sgblack@eecs.umich.edu microOps[uopIdx++] = 7237639Sgblack@eecs.umich.edu new MicroUnpackNeon2to2Uop<uint16_t>( 7247639Sgblack@eecs.umich.edu machInst, (vd + offset) * 2, ufp0, inc * 2, lane); 7257639Sgblack@eecs.umich.edu } 7267639Sgblack@eecs.umich.edu break; 7277639Sgblack@eecs.umich.edu case 2: 7287639Sgblack@eecs.umich.edu if (all) { 7297639Sgblack@eecs.umich.edu microOps[uopIdx++] = 7307639Sgblack@eecs.umich.edu new MicroUnpackAllNeon2to2Uop<uint32_t>( 7317639Sgblack@eecs.umich.edu machInst, (vd + offset) * 2, ufp0, inc * 2); 7327639Sgblack@eecs.umich.edu } else { 7337639Sgblack@eecs.umich.edu microOps[uopIdx++] = 7347639Sgblack@eecs.umich.edu new MicroUnpackNeon2to2Uop<uint32_t>( 7357639Sgblack@eecs.umich.edu machInst, (vd + offset) * 2, ufp0, inc * 2, lane); 7367639Sgblack@eecs.umich.edu } 7377639Sgblack@eecs.umich.edu break; 7387639Sgblack@eecs.umich.edu default: 7397853SMatt.Horsnell@ARM.com // Bad size 7407853SMatt.Horsnell@ARM.com microOps[uopIdx++] = new Unknown(machInst); 7417639Sgblack@eecs.umich.edu break; 7427639Sgblack@eecs.umich.edu } 7437639Sgblack@eecs.umich.edu } 7447639Sgblack@eecs.umich.edu break; 7457639Sgblack@eecs.umich.edu default: 7467853SMatt.Horsnell@ARM.com // Bad number of elements to unpack 7477853SMatt.Horsnell@ARM.com microOps[uopIdx++] = new Unknown(machInst); 7487639Sgblack@eecs.umich.edu } 7497639Sgblack@eecs.umich.edu assert(uopIdx == numMicroops); 7507639Sgblack@eecs.umich.edu 7517639Sgblack@eecs.umich.edu for (unsigned i = 0; i < numMicroops - 1; i++) { 7527639Sgblack@eecs.umich.edu MicroOp * uopPtr = dynamic_cast<MicroOp *>(microOps[i].get()); 7537639Sgblack@eecs.umich.edu assert(uopPtr); 7547639Sgblack@eecs.umich.edu uopPtr->setDelayedCommit(); 7557639Sgblack@eecs.umich.edu } 7567639Sgblack@eecs.umich.edu microOps[numMicroops - 1]->setLastMicroop(); 7577639Sgblack@eecs.umich.edu} 7587639Sgblack@eecs.umich.edu 7597639Sgblack@eecs.umich.eduVstMultOp::VstMultOp(const char *mnem, ExtMachInst machInst, OpClass __opClass, 7607639Sgblack@eecs.umich.edu unsigned elems, RegIndex rn, RegIndex vd, unsigned regs, 7617639Sgblack@eecs.umich.edu unsigned inc, uint32_t size, uint32_t align, RegIndex rm) : 7627639Sgblack@eecs.umich.edu PredMacroOp(mnem, machInst, __opClass) 7637639Sgblack@eecs.umich.edu{ 7647639Sgblack@eecs.umich.edu assert(regs > 0 && regs <= 4); 7657639Sgblack@eecs.umich.edu assert(regs % elems == 0); 7667639Sgblack@eecs.umich.edu 7677639Sgblack@eecs.umich.edu numMicroops = (regs > 2) ? 2 : 1; 7687639Sgblack@eecs.umich.edu bool wb = (rm != 15); 7697639Sgblack@eecs.umich.edu bool interleave = (elems > 1); 7707639Sgblack@eecs.umich.edu 7717639Sgblack@eecs.umich.edu if (wb) numMicroops++; 7727639Sgblack@eecs.umich.edu if (interleave) numMicroops += (regs / elems); 7737639Sgblack@eecs.umich.edu microOps = new StaticInstPtr[numMicroops]; 7747639Sgblack@eecs.umich.edu 7757639Sgblack@eecs.umich.edu uint32_t noAlign = TLB::MustBeOne; 7767639Sgblack@eecs.umich.edu 77710037SARM gem5 Developers RegIndex rMid = interleave ? NumFloatV7ArchRegs : vd * 2; 7787639Sgblack@eecs.umich.edu 7797639Sgblack@eecs.umich.edu unsigned uopIdx = 0; 7807639Sgblack@eecs.umich.edu if (interleave) { 7817639Sgblack@eecs.umich.edu switch (elems) { 7827639Sgblack@eecs.umich.edu case 4: 7837639Sgblack@eecs.umich.edu assert(regs == 4); 7847639Sgblack@eecs.umich.edu microOps[uopIdx++] = newNeonMixInst<MicroInterNeon8Uop>( 7857639Sgblack@eecs.umich.edu size, machInst, rMid, vd * 2, inc * 2); 7867639Sgblack@eecs.umich.edu break; 7877639Sgblack@eecs.umich.edu case 3: 7887639Sgblack@eecs.umich.edu assert(regs == 3); 7897639Sgblack@eecs.umich.edu microOps[uopIdx++] = newNeonMixInst<MicroInterNeon6Uop>( 7907639Sgblack@eecs.umich.edu size, machInst, rMid, vd * 2, inc * 2); 7917639Sgblack@eecs.umich.edu break; 7927639Sgblack@eecs.umich.edu case 2: 7937639Sgblack@eecs.umich.edu assert(regs == 4 || regs == 2); 7947639Sgblack@eecs.umich.edu if (regs == 4) { 7957639Sgblack@eecs.umich.edu microOps[uopIdx++] = newNeonMixInst<MicroInterNeon4Uop>( 7967639Sgblack@eecs.umich.edu size, machInst, rMid, vd * 2, inc * 2); 7977639Sgblack@eecs.umich.edu microOps[uopIdx++] = newNeonMixInst<MicroInterNeon4Uop>( 7987639Sgblack@eecs.umich.edu size, machInst, rMid + 4, vd * 2 + 2, inc * 2); 7997639Sgblack@eecs.umich.edu } else { 8007639Sgblack@eecs.umich.edu microOps[uopIdx++] = newNeonMixInst<MicroInterNeon4Uop>( 8017639Sgblack@eecs.umich.edu size, machInst, rMid, vd * 2, inc * 2); 8027639Sgblack@eecs.umich.edu } 8037639Sgblack@eecs.umich.edu break; 8047639Sgblack@eecs.umich.edu default: 8057853SMatt.Horsnell@ARM.com // Bad number of elements to interleave 8067853SMatt.Horsnell@ARM.com microOps[uopIdx++] = new Unknown(machInst); 8077639Sgblack@eecs.umich.edu } 8087639Sgblack@eecs.umich.edu } 8097639Sgblack@eecs.umich.edu switch (regs) { 8107639Sgblack@eecs.umich.edu case 4: 8117639Sgblack@eecs.umich.edu microOps[uopIdx++] = newNeonMemInst<MicroStrNeon16Uop>( 8127639Sgblack@eecs.umich.edu size, machInst, rMid, rn, 0, align); 8137639Sgblack@eecs.umich.edu microOps[uopIdx++] = newNeonMemInst<MicroStrNeon16Uop>( 8147639Sgblack@eecs.umich.edu size, machInst, rMid + 4, rn, 16, noAlign); 8157639Sgblack@eecs.umich.edu break; 8167639Sgblack@eecs.umich.edu case 3: 8177639Sgblack@eecs.umich.edu microOps[uopIdx++] = newNeonMemInst<MicroStrNeon16Uop>( 8187639Sgblack@eecs.umich.edu size, machInst, rMid, rn, 0, align); 8197639Sgblack@eecs.umich.edu microOps[uopIdx++] = newNeonMemInst<MicroStrNeon8Uop>( 8207639Sgblack@eecs.umich.edu size, machInst, rMid + 4, rn, 16, noAlign); 8217639Sgblack@eecs.umich.edu break; 8227639Sgblack@eecs.umich.edu case 2: 8237639Sgblack@eecs.umich.edu microOps[uopIdx++] = newNeonMemInst<MicroStrNeon16Uop>( 8247639Sgblack@eecs.umich.edu size, machInst, rMid, rn, 0, align); 8257639Sgblack@eecs.umich.edu break; 8267639Sgblack@eecs.umich.edu case 1: 8277639Sgblack@eecs.umich.edu microOps[uopIdx++] = newNeonMemInst<MicroStrNeon8Uop>( 8287639Sgblack@eecs.umich.edu size, machInst, rMid, rn, 0, align); 8297639Sgblack@eecs.umich.edu break; 8307639Sgblack@eecs.umich.edu default: 8317853SMatt.Horsnell@ARM.com // Unknown number of registers 8327853SMatt.Horsnell@ARM.com microOps[uopIdx++] = new Unknown(machInst); 8337639Sgblack@eecs.umich.edu } 8347639Sgblack@eecs.umich.edu if (wb) { 8357639Sgblack@eecs.umich.edu if (rm != 15 && rm != 13) { 8367639Sgblack@eecs.umich.edu microOps[uopIdx++] = 8377646Sgene.wu@arm.com new MicroAddUop(machInst, rn, rn, rm, 0, ArmISA::LSL); 8387639Sgblack@eecs.umich.edu } else { 8397639Sgblack@eecs.umich.edu microOps[uopIdx++] = 8407639Sgblack@eecs.umich.edu new MicroAddiUop(machInst, rn, rn, regs * 8); 8417639Sgblack@eecs.umich.edu } 8427639Sgblack@eecs.umich.edu } 8437639Sgblack@eecs.umich.edu assert(uopIdx == numMicroops); 8447639Sgblack@eecs.umich.edu 8457639Sgblack@eecs.umich.edu for (unsigned i = 0; i < numMicroops - 1; i++) { 8467639Sgblack@eecs.umich.edu MicroOp * uopPtr = dynamic_cast<MicroOp *>(microOps[i].get()); 8477639Sgblack@eecs.umich.edu assert(uopPtr); 8487639Sgblack@eecs.umich.edu uopPtr->setDelayedCommit(); 8497639Sgblack@eecs.umich.edu } 8507639Sgblack@eecs.umich.edu microOps[numMicroops - 1]->setLastMicroop(); 8517639Sgblack@eecs.umich.edu} 8527639Sgblack@eecs.umich.edu 8537639Sgblack@eecs.umich.eduVstSingleOp::VstSingleOp(const char *mnem, ExtMachInst machInst, 8547639Sgblack@eecs.umich.edu OpClass __opClass, bool all, unsigned elems, 8557639Sgblack@eecs.umich.edu RegIndex rn, RegIndex vd, unsigned regs, 8567639Sgblack@eecs.umich.edu unsigned inc, uint32_t size, uint32_t align, 8577639Sgblack@eecs.umich.edu RegIndex rm, unsigned lane) : 8587639Sgblack@eecs.umich.edu PredMacroOp(mnem, machInst, __opClass) 8597639Sgblack@eecs.umich.edu{ 8607639Sgblack@eecs.umich.edu assert(!all); 8617639Sgblack@eecs.umich.edu assert(regs > 0 && regs <= 4); 8627639Sgblack@eecs.umich.edu assert(regs % elems == 0); 8637639Sgblack@eecs.umich.edu 8647639Sgblack@eecs.umich.edu unsigned eBytes = (1 << size); 8657639Sgblack@eecs.umich.edu unsigned storeSize = eBytes * elems; 8667639Sgblack@eecs.umich.edu unsigned storeRegs M5_VAR_USED = (storeSize + sizeof(FloatRegBits) - 1) / 8677639Sgblack@eecs.umich.edu sizeof(FloatRegBits); 8687639Sgblack@eecs.umich.edu 8697639Sgblack@eecs.umich.edu assert(storeRegs > 0 && storeRegs <= 4); 8707639Sgblack@eecs.umich.edu 8717639Sgblack@eecs.umich.edu numMicroops = 1; 8727639Sgblack@eecs.umich.edu bool wb = (rm != 15); 8737639Sgblack@eecs.umich.edu 8747639Sgblack@eecs.umich.edu if (wb) numMicroops++; 8757639Sgblack@eecs.umich.edu numMicroops += (regs / elems); 8767639Sgblack@eecs.umich.edu microOps = new StaticInstPtr[numMicroops]; 8777639Sgblack@eecs.umich.edu 87810037SARM gem5 Developers RegIndex ufp0 = NumFloatV7ArchRegs; 8797639Sgblack@eecs.umich.edu 8807639Sgblack@eecs.umich.edu unsigned uopIdx = 0; 8817639Sgblack@eecs.umich.edu switch (elems) { 8827639Sgblack@eecs.umich.edu case 4: 8837639Sgblack@eecs.umich.edu assert(regs == 4); 8847639Sgblack@eecs.umich.edu switch (size) { 8857639Sgblack@eecs.umich.edu case 0: 8867639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroPackNeon8to2Uop<uint8_t>( 8877639Sgblack@eecs.umich.edu machInst, ufp0, vd * 2, inc * 2, lane); 8887639Sgblack@eecs.umich.edu break; 8897639Sgblack@eecs.umich.edu case 1: 8907639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroPackNeon8to2Uop<uint16_t>( 8917639Sgblack@eecs.umich.edu machInst, ufp0, vd * 2, inc * 2, lane); 8927639Sgblack@eecs.umich.edu break; 8937639Sgblack@eecs.umich.edu case 2: 8947639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroPackNeon8to4Uop<uint32_t>( 8957639Sgblack@eecs.umich.edu machInst, ufp0, vd * 2, inc * 2, lane); 8967639Sgblack@eecs.umich.edu break; 8977639Sgblack@eecs.umich.edu default: 8987853SMatt.Horsnell@ARM.com // Bad size 8997853SMatt.Horsnell@ARM.com microOps[uopIdx++] = new Unknown(machInst); 9007639Sgblack@eecs.umich.edu break; 9017639Sgblack@eecs.umich.edu } 9027639Sgblack@eecs.umich.edu break; 9037639Sgblack@eecs.umich.edu case 3: 9047639Sgblack@eecs.umich.edu assert(regs == 3); 9057639Sgblack@eecs.umich.edu switch (size) { 9067639Sgblack@eecs.umich.edu case 0: 9077639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroPackNeon6to2Uop<uint8_t>( 9087639Sgblack@eecs.umich.edu machInst, ufp0, vd * 2, inc * 2, lane); 9097639Sgblack@eecs.umich.edu break; 9107639Sgblack@eecs.umich.edu case 1: 9117639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroPackNeon6to2Uop<uint16_t>( 9127639Sgblack@eecs.umich.edu machInst, ufp0, vd * 2, inc * 2, lane); 9137639Sgblack@eecs.umich.edu break; 9147639Sgblack@eecs.umich.edu case 2: 9157639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroPackNeon6to4Uop<uint32_t>( 9167639Sgblack@eecs.umich.edu machInst, ufp0, vd * 2, inc * 2, lane); 9177639Sgblack@eecs.umich.edu break; 9187639Sgblack@eecs.umich.edu default: 9197853SMatt.Horsnell@ARM.com // Bad size 9207853SMatt.Horsnell@ARM.com microOps[uopIdx++] = new Unknown(machInst); 9217639Sgblack@eecs.umich.edu break; 9227639Sgblack@eecs.umich.edu } 9237639Sgblack@eecs.umich.edu break; 9247639Sgblack@eecs.umich.edu case 2: 9257639Sgblack@eecs.umich.edu assert(regs == 2); 9267639Sgblack@eecs.umich.edu assert(storeRegs <= 2); 9277639Sgblack@eecs.umich.edu switch (size) { 9287639Sgblack@eecs.umich.edu case 0: 9297639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroPackNeon4to2Uop<uint8_t>( 9307639Sgblack@eecs.umich.edu machInst, ufp0, vd * 2, inc * 2, lane); 9317639Sgblack@eecs.umich.edu break; 9327639Sgblack@eecs.umich.edu case 1: 9337639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroPackNeon4to2Uop<uint16_t>( 9347639Sgblack@eecs.umich.edu machInst, ufp0, vd * 2, inc * 2, lane); 9357639Sgblack@eecs.umich.edu break; 9367639Sgblack@eecs.umich.edu case 2: 9377639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroPackNeon4to2Uop<uint32_t>( 9387639Sgblack@eecs.umich.edu machInst, ufp0, vd * 2, inc * 2, lane); 9397639Sgblack@eecs.umich.edu break; 9407639Sgblack@eecs.umich.edu default: 9417853SMatt.Horsnell@ARM.com // Bad size 9427853SMatt.Horsnell@ARM.com microOps[uopIdx++] = new Unknown(machInst); 9437639Sgblack@eecs.umich.edu break; 9447639Sgblack@eecs.umich.edu } 9457639Sgblack@eecs.umich.edu break; 9467639Sgblack@eecs.umich.edu case 1: 9477639Sgblack@eecs.umich.edu assert(regs == 1 || (all && regs == 2)); 9487639Sgblack@eecs.umich.edu assert(storeRegs <= 2); 9497639Sgblack@eecs.umich.edu for (unsigned offset = 0; offset < regs; offset++) { 9507639Sgblack@eecs.umich.edu switch (size) { 9517639Sgblack@eecs.umich.edu case 0: 9527639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroPackNeon2to2Uop<uint8_t>( 9537639Sgblack@eecs.umich.edu machInst, ufp0, (vd + offset) * 2, inc * 2, lane); 9547639Sgblack@eecs.umich.edu break; 9557639Sgblack@eecs.umich.edu case 1: 9567639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroPackNeon2to2Uop<uint16_t>( 9577639Sgblack@eecs.umich.edu machInst, ufp0, (vd + offset) * 2, inc * 2, lane); 9587639Sgblack@eecs.umich.edu break; 9597639Sgblack@eecs.umich.edu case 2: 9607639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroPackNeon2to2Uop<uint32_t>( 9617639Sgblack@eecs.umich.edu machInst, ufp0, (vd + offset) * 2, inc * 2, lane); 9627639Sgblack@eecs.umich.edu break; 9637639Sgblack@eecs.umich.edu default: 9647853SMatt.Horsnell@ARM.com // Bad size 9657853SMatt.Horsnell@ARM.com microOps[uopIdx++] = new Unknown(machInst); 9667639Sgblack@eecs.umich.edu break; 9677639Sgblack@eecs.umich.edu } 9687639Sgblack@eecs.umich.edu } 9697639Sgblack@eecs.umich.edu break; 9707639Sgblack@eecs.umich.edu default: 9717853SMatt.Horsnell@ARM.com // Bad number of elements to unpack 9727853SMatt.Horsnell@ARM.com microOps[uopIdx++] = new Unknown(machInst); 9737639Sgblack@eecs.umich.edu } 9747639Sgblack@eecs.umich.edu switch (storeSize) { 9757639Sgblack@eecs.umich.edu case 1: 9767639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroStrNeon1Uop<uint8_t>( 9777639Sgblack@eecs.umich.edu machInst, ufp0, rn, 0, align); 9787639Sgblack@eecs.umich.edu break; 9797639Sgblack@eecs.umich.edu case 2: 9807639Sgblack@eecs.umich.edu if (eBytes == 2) { 9817639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroStrNeon2Uop<uint16_t>( 9827639Sgblack@eecs.umich.edu machInst, ufp0, rn, 0, align); 9837639Sgblack@eecs.umich.edu } else { 9847639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroStrNeon2Uop<uint8_t>( 9857639Sgblack@eecs.umich.edu machInst, ufp0, rn, 0, align); 9867639Sgblack@eecs.umich.edu } 9877639Sgblack@eecs.umich.edu break; 9887639Sgblack@eecs.umich.edu case 3: 9897639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroStrNeon3Uop<uint8_t>( 9907639Sgblack@eecs.umich.edu machInst, ufp0, rn, 0, align); 9917639Sgblack@eecs.umich.edu break; 9927639Sgblack@eecs.umich.edu case 4: 9937639Sgblack@eecs.umich.edu switch (eBytes) { 9947639Sgblack@eecs.umich.edu case 1: 9957639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroStrNeon4Uop<uint8_t>( 9967639Sgblack@eecs.umich.edu machInst, ufp0, rn, 0, align); 9977639Sgblack@eecs.umich.edu break; 9987639Sgblack@eecs.umich.edu case 2: 9997639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroStrNeon4Uop<uint16_t>( 10007639Sgblack@eecs.umich.edu machInst, ufp0, rn, 0, align); 10017639Sgblack@eecs.umich.edu break; 10027639Sgblack@eecs.umich.edu case 4: 10037639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroStrNeon4Uop<uint32_t>( 10047639Sgblack@eecs.umich.edu machInst, ufp0, rn, 0, align); 10057639Sgblack@eecs.umich.edu break; 10067639Sgblack@eecs.umich.edu } 10077639Sgblack@eecs.umich.edu break; 10087639Sgblack@eecs.umich.edu case 6: 10097639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroStrNeon6Uop<uint16_t>( 10107639Sgblack@eecs.umich.edu machInst, ufp0, rn, 0, align); 10117639Sgblack@eecs.umich.edu break; 10127639Sgblack@eecs.umich.edu case 8: 10137639Sgblack@eecs.umich.edu switch (eBytes) { 10147639Sgblack@eecs.umich.edu case 2: 10157639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroStrNeon8Uop<uint16_t>( 10167639Sgblack@eecs.umich.edu machInst, ufp0, rn, 0, align); 10177639Sgblack@eecs.umich.edu break; 10187639Sgblack@eecs.umich.edu case 4: 10197639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroStrNeon8Uop<uint32_t>( 10207639Sgblack@eecs.umich.edu machInst, ufp0, rn, 0, align); 10217639Sgblack@eecs.umich.edu break; 10227639Sgblack@eecs.umich.edu } 10237639Sgblack@eecs.umich.edu break; 10247639Sgblack@eecs.umich.edu case 12: 10257639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroStrNeon12Uop<uint32_t>( 10267639Sgblack@eecs.umich.edu machInst, ufp0, rn, 0, align); 10277639Sgblack@eecs.umich.edu break; 10287639Sgblack@eecs.umich.edu case 16: 10297639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroStrNeon16Uop<uint32_t>( 10307639Sgblack@eecs.umich.edu machInst, ufp0, rn, 0, align); 10317639Sgblack@eecs.umich.edu break; 10327639Sgblack@eecs.umich.edu default: 10337853SMatt.Horsnell@ARM.com // Bad store size 10347853SMatt.Horsnell@ARM.com microOps[uopIdx++] = new Unknown(machInst); 10357639Sgblack@eecs.umich.edu } 10367639Sgblack@eecs.umich.edu if (wb) { 10377639Sgblack@eecs.umich.edu if (rm != 15 && rm != 13) { 10387639Sgblack@eecs.umich.edu microOps[uopIdx++] = 10397646Sgene.wu@arm.com new MicroAddUop(machInst, rn, rn, rm, 0, ArmISA::LSL); 10407639Sgblack@eecs.umich.edu } else { 10417639Sgblack@eecs.umich.edu microOps[uopIdx++] = 10427639Sgblack@eecs.umich.edu new MicroAddiUop(machInst, rn, rn, storeSize); 10437639Sgblack@eecs.umich.edu } 10447639Sgblack@eecs.umich.edu } 10457639Sgblack@eecs.umich.edu assert(uopIdx == numMicroops); 10467639Sgblack@eecs.umich.edu 10477639Sgblack@eecs.umich.edu for (unsigned i = 0; i < numMicroops - 1; i++) { 10487639Sgblack@eecs.umich.edu MicroOp * uopPtr = dynamic_cast<MicroOp *>(microOps[i].get()); 10497639Sgblack@eecs.umich.edu assert(uopPtr); 10507639Sgblack@eecs.umich.edu uopPtr->setDelayedCommit(); 10517639Sgblack@eecs.umich.edu } 10527639Sgblack@eecs.umich.edu microOps[numMicroops - 1]->setLastMicroop(); 10537639Sgblack@eecs.umich.edu} 10547639Sgblack@eecs.umich.edu 105510037SARM gem5 DevelopersVldMultOp64::VldMultOp64(const char *mnem, ExtMachInst machInst, 105610037SARM gem5 Developers OpClass __opClass, RegIndex rn, RegIndex vd, 105710037SARM gem5 Developers RegIndex rm, uint8_t eSize, uint8_t dataSize, 105810037SARM gem5 Developers uint8_t numStructElems, uint8_t numRegs, bool wb) : 105910037SARM gem5 Developers PredMacroOp(mnem, machInst, __opClass) 106010037SARM gem5 Developers{ 106110037SARM gem5 Developers RegIndex vx = NumFloatV8ArchRegs / 4; 106210037SARM gem5 Developers RegIndex rnsp = (RegIndex) makeSP((IntRegIndex) rn); 106310037SARM gem5 Developers bool baseIsSP = isSP((IntRegIndex) rnsp); 106410037SARM gem5 Developers 106510037SARM gem5 Developers numMicroops = wb ? 1 : 0; 106610037SARM gem5 Developers 106710037SARM gem5 Developers int totNumBytes = numRegs * dataSize / 8; 106810037SARM gem5 Developers assert(totNumBytes <= 64); 106910037SARM gem5 Developers 107010037SARM gem5 Developers // The guiding principle here is that no more than 16 bytes can be 107110037SARM gem5 Developers // transferred at a time 107210037SARM gem5 Developers int numMemMicroops = totNumBytes / 16; 107310037SARM gem5 Developers int residuum = totNumBytes % 16; 107410037SARM gem5 Developers if (residuum) 107510037SARM gem5 Developers ++numMemMicroops; 107610037SARM gem5 Developers numMicroops += numMemMicroops; 107710037SARM gem5 Developers 107810037SARM gem5 Developers int numMarshalMicroops = numRegs / 2 + (numRegs % 2 ? 1 : 0); 107910037SARM gem5 Developers numMicroops += numMarshalMicroops; 108010037SARM gem5 Developers 108110037SARM gem5 Developers microOps = new StaticInstPtr[numMicroops]; 108210037SARM gem5 Developers unsigned uopIdx = 0; 108310037SARM gem5 Developers uint32_t memaccessFlags = TLB::MustBeOne | (TLB::ArmFlags) eSize | 108410037SARM gem5 Developers TLB::AllowUnaligned; 108510037SARM gem5 Developers 108610037SARM gem5 Developers int i = 0; 108710037SARM gem5 Developers for(; i < numMemMicroops - 1; ++i) { 108810037SARM gem5 Developers microOps[uopIdx++] = new MicroNeonLoad64( 108910037SARM gem5 Developers machInst, vx + (RegIndex) i, rnsp, 16 * i, memaccessFlags, 109010037SARM gem5 Developers baseIsSP, 16 /* accSize */, eSize); 109110037SARM gem5 Developers } 109210037SARM gem5 Developers microOps[uopIdx++] = new MicroNeonLoad64( 109310037SARM gem5 Developers machInst, vx + (RegIndex) i, rnsp, 16 * i, memaccessFlags, baseIsSP, 109410037SARM gem5 Developers residuum ? residuum : 16 /* accSize */, eSize); 109510037SARM gem5 Developers 109610037SARM gem5 Developers // Writeback microop: the post-increment amount is encoded in "Rm": a 109710037SARM gem5 Developers // 64-bit general register OR as '11111' for an immediate value equal to 109810037SARM gem5 Developers // the total number of bytes transferred (i.e. 8, 16, 24, 32, 48 or 64) 109910037SARM gem5 Developers if (wb) { 110010037SARM gem5 Developers if (rm != ((RegIndex) INTREG_X31)) { 110110037SARM gem5 Developers microOps[uopIdx++] = new MicroAddXERegUop(machInst, rnsp, rnsp, rm, 110210037SARM gem5 Developers UXTX, 0); 110310037SARM gem5 Developers } else { 110410037SARM gem5 Developers microOps[uopIdx++] = new MicroAddXiUop(machInst, rnsp, rnsp, 110510037SARM gem5 Developers totNumBytes); 110610037SARM gem5 Developers } 110710037SARM gem5 Developers } 110810037SARM gem5 Developers 110910037SARM gem5 Developers for (int i = 0; i < numMarshalMicroops; ++i) { 111010339Smitch.hayenga@arm.com switch(numRegs) { 111110339Smitch.hayenga@arm.com case 1: microOps[uopIdx++] = new MicroDeintNeon64_1Reg( 111210339Smitch.hayenga@arm.com machInst, vd + (RegIndex) (2 * i), vx, eSize, dataSize, 111310339Smitch.hayenga@arm.com numStructElems, 1, i /* step */); 111410339Smitch.hayenga@arm.com break; 111510339Smitch.hayenga@arm.com case 2: microOps[uopIdx++] = new MicroDeintNeon64_2Reg( 111610339Smitch.hayenga@arm.com machInst, vd + (RegIndex) (2 * i), vx, eSize, dataSize, 111710339Smitch.hayenga@arm.com numStructElems, 2, i /* step */); 111810339Smitch.hayenga@arm.com break; 111910339Smitch.hayenga@arm.com case 3: microOps[uopIdx++] = new MicroDeintNeon64_3Reg( 112010339Smitch.hayenga@arm.com machInst, vd + (RegIndex) (2 * i), vx, eSize, dataSize, 112110339Smitch.hayenga@arm.com numStructElems, 3, i /* step */); 112210339Smitch.hayenga@arm.com break; 112310339Smitch.hayenga@arm.com case 4: microOps[uopIdx++] = new MicroDeintNeon64_4Reg( 112410339Smitch.hayenga@arm.com machInst, vd + (RegIndex) (2 * i), vx, eSize, dataSize, 112510339Smitch.hayenga@arm.com numStructElems, 4, i /* step */); 112610339Smitch.hayenga@arm.com break; 112710339Smitch.hayenga@arm.com default: panic("Invalid number of registers"); 112810339Smitch.hayenga@arm.com } 112910339Smitch.hayenga@arm.com 113010037SARM gem5 Developers } 113110037SARM gem5 Developers 113210037SARM gem5 Developers assert(uopIdx == numMicroops); 113310037SARM gem5 Developers 113410037SARM gem5 Developers for (int i = 0; i < numMicroops - 1; ++i) { 113510037SARM gem5 Developers microOps[i]->setDelayedCommit(); 113610037SARM gem5 Developers } 113710037SARM gem5 Developers microOps[numMicroops - 1]->setLastMicroop(); 113810037SARM gem5 Developers} 113910037SARM gem5 Developers 114010037SARM gem5 DevelopersVstMultOp64::VstMultOp64(const char *mnem, ExtMachInst machInst, 114110037SARM gem5 Developers OpClass __opClass, RegIndex rn, RegIndex vd, 114210037SARM gem5 Developers RegIndex rm, uint8_t eSize, uint8_t dataSize, 114310037SARM gem5 Developers uint8_t numStructElems, uint8_t numRegs, bool wb) : 114410037SARM gem5 Developers PredMacroOp(mnem, machInst, __opClass) 114510037SARM gem5 Developers{ 114610037SARM gem5 Developers RegIndex vx = NumFloatV8ArchRegs / 4; 114710037SARM gem5 Developers RegIndex rnsp = (RegIndex) makeSP((IntRegIndex) rn); 114810037SARM gem5 Developers bool baseIsSP = isSP((IntRegIndex) rnsp); 114910037SARM gem5 Developers 115010037SARM gem5 Developers numMicroops = wb ? 1 : 0; 115110037SARM gem5 Developers 115210037SARM gem5 Developers int totNumBytes = numRegs * dataSize / 8; 115310037SARM gem5 Developers assert(totNumBytes <= 64); 115410037SARM gem5 Developers 115510037SARM gem5 Developers // The guiding principle here is that no more than 16 bytes can be 115610037SARM gem5 Developers // transferred at a time 115710037SARM gem5 Developers int numMemMicroops = totNumBytes / 16; 115810037SARM gem5 Developers int residuum = totNumBytes % 16; 115910037SARM gem5 Developers if (residuum) 116010037SARM gem5 Developers ++numMemMicroops; 116110037SARM gem5 Developers numMicroops += numMemMicroops; 116210037SARM gem5 Developers 116310037SARM gem5 Developers int numMarshalMicroops = totNumBytes > 32 ? 2 : 1; 116410037SARM gem5 Developers numMicroops += numMarshalMicroops; 116510037SARM gem5 Developers 116610037SARM gem5 Developers microOps = new StaticInstPtr[numMicroops]; 116710037SARM gem5 Developers unsigned uopIdx = 0; 116810037SARM gem5 Developers 116910037SARM gem5 Developers for(int i = 0; i < numMarshalMicroops; ++i) { 117010339Smitch.hayenga@arm.com switch (numRegs) { 117110339Smitch.hayenga@arm.com case 1: microOps[uopIdx++] = new MicroIntNeon64_1Reg( 117210339Smitch.hayenga@arm.com machInst, vx + (RegIndex) (2 * i), vd, eSize, dataSize, 117310339Smitch.hayenga@arm.com numStructElems, 1, i /* step */); 117410339Smitch.hayenga@arm.com break; 117510339Smitch.hayenga@arm.com case 2: microOps[uopIdx++] = new MicroIntNeon64_2Reg( 117610339Smitch.hayenga@arm.com machInst, vx + (RegIndex) (2 * i), vd, eSize, dataSize, 117710339Smitch.hayenga@arm.com numStructElems, 2, i /* step */); 117810339Smitch.hayenga@arm.com break; 117910339Smitch.hayenga@arm.com case 3: microOps[uopIdx++] = new MicroIntNeon64_3Reg( 118010339Smitch.hayenga@arm.com machInst, vx + (RegIndex) (2 * i), vd, eSize, dataSize, 118110339Smitch.hayenga@arm.com numStructElems, 3, i /* step */); 118210339Smitch.hayenga@arm.com break; 118310339Smitch.hayenga@arm.com case 4: microOps[uopIdx++] = new MicroIntNeon64_4Reg( 118410339Smitch.hayenga@arm.com machInst, vx + (RegIndex) (2 * i), vd, eSize, dataSize, 118510339Smitch.hayenga@arm.com numStructElems, 4, i /* step */); 118610339Smitch.hayenga@arm.com break; 118710339Smitch.hayenga@arm.com default: panic("Invalid number of registers"); 118810339Smitch.hayenga@arm.com } 118910037SARM gem5 Developers } 119010037SARM gem5 Developers 119110037SARM gem5 Developers uint32_t memaccessFlags = TLB::MustBeOne | (TLB::ArmFlags) eSize | 119210037SARM gem5 Developers TLB::AllowUnaligned; 119310037SARM gem5 Developers 119410037SARM gem5 Developers int i = 0; 119510037SARM gem5 Developers for(; i < numMemMicroops - 1; ++i) { 119610037SARM gem5 Developers microOps[uopIdx++] = new MicroNeonStore64( 119710037SARM gem5 Developers machInst, vx + (RegIndex) i, rnsp, 16 * i, memaccessFlags, 119810037SARM gem5 Developers baseIsSP, 16 /* accSize */, eSize); 119910037SARM gem5 Developers } 120010037SARM gem5 Developers microOps[uopIdx++] = new MicroNeonStore64( 120110037SARM gem5 Developers machInst, vx + (RegIndex) i, rnsp, 16 * i, memaccessFlags, baseIsSP, 120210037SARM gem5 Developers residuum ? residuum : 16 /* accSize */, eSize); 120310037SARM gem5 Developers 120410037SARM gem5 Developers // Writeback microop: the post-increment amount is encoded in "Rm": a 120510037SARM gem5 Developers // 64-bit general register OR as '11111' for an immediate value equal to 120610037SARM gem5 Developers // the total number of bytes transferred (i.e. 8, 16, 24, 32, 48 or 64) 120710037SARM gem5 Developers if (wb) { 120810037SARM gem5 Developers if (rm != ((RegIndex) INTREG_X31)) { 120910037SARM gem5 Developers microOps[uopIdx++] = new MicroAddXERegUop(machInst, rnsp, rnsp, rm, 121010037SARM gem5 Developers UXTX, 0); 121110037SARM gem5 Developers } else { 121210037SARM gem5 Developers microOps[uopIdx++] = new MicroAddXiUop(machInst, rnsp, rnsp, 121310037SARM gem5 Developers totNumBytes); 121410037SARM gem5 Developers } 121510037SARM gem5 Developers } 121610037SARM gem5 Developers 121710037SARM gem5 Developers assert(uopIdx == numMicroops); 121810037SARM gem5 Developers 121910037SARM gem5 Developers for (int i = 0; i < numMicroops - 1; i++) { 122010037SARM gem5 Developers microOps[i]->setDelayedCommit(); 122110037SARM gem5 Developers } 122210037SARM gem5 Developers microOps[numMicroops - 1]->setLastMicroop(); 122310037SARM gem5 Developers} 122410037SARM gem5 Developers 122510037SARM gem5 DevelopersVldSingleOp64::VldSingleOp64(const char *mnem, ExtMachInst machInst, 122610037SARM gem5 Developers OpClass __opClass, RegIndex rn, RegIndex vd, 122710037SARM gem5 Developers RegIndex rm, uint8_t eSize, uint8_t dataSize, 122810037SARM gem5 Developers uint8_t numStructElems, uint8_t index, bool wb, 122910037SARM gem5 Developers bool replicate) : 123010037SARM gem5 Developers PredMacroOp(mnem, machInst, __opClass) 123110037SARM gem5 Developers{ 123210037SARM gem5 Developers RegIndex vx = NumFloatV8ArchRegs / 4; 123310037SARM gem5 Developers RegIndex rnsp = (RegIndex) makeSP((IntRegIndex) rn); 123410037SARM gem5 Developers bool baseIsSP = isSP((IntRegIndex) rnsp); 123510037SARM gem5 Developers 123610037SARM gem5 Developers numMicroops = wb ? 1 : 0; 123710037SARM gem5 Developers 123810037SARM gem5 Developers int eSizeBytes = 1 << eSize; 123910037SARM gem5 Developers int totNumBytes = numStructElems * eSizeBytes; 124010037SARM gem5 Developers assert(totNumBytes <= 64); 124110037SARM gem5 Developers 124210037SARM gem5 Developers // The guiding principle here is that no more than 16 bytes can be 124310037SARM gem5 Developers // transferred at a time 124410037SARM gem5 Developers int numMemMicroops = totNumBytes / 16; 124510037SARM gem5 Developers int residuum = totNumBytes % 16; 124610037SARM gem5 Developers if (residuum) 124710037SARM gem5 Developers ++numMemMicroops; 124810037SARM gem5 Developers numMicroops += numMemMicroops; 124910037SARM gem5 Developers 125010037SARM gem5 Developers int numMarshalMicroops = numStructElems / 2 + (numStructElems % 2 ? 1 : 0); 125110037SARM gem5 Developers numMicroops += numMarshalMicroops; 125210037SARM gem5 Developers 125310037SARM gem5 Developers microOps = new StaticInstPtr[numMicroops]; 125410037SARM gem5 Developers unsigned uopIdx = 0; 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; 126010037SARM gem5 Developers for (; i < numMemMicroops - 1; ++i) { 126110037SARM gem5 Developers microOps[uopIdx++] = new MicroNeonLoad64( 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 MicroNeonLoad64( 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 for(int i = 0; i < numMarshalMicroops; ++i) { 128310037SARM gem5 Developers microOps[uopIdx++] = new MicroUnpackNeon64( 128410037SARM gem5 Developers machInst, vd + (RegIndex) (2 * i), vx, eSize, dataSize, 128510037SARM gem5 Developers numStructElems, index, i /* step */, replicate); 128610037SARM gem5 Developers } 128710037SARM gem5 Developers 128810037SARM gem5 Developers assert(uopIdx == numMicroops); 128910037SARM gem5 Developers 129010037SARM gem5 Developers for (int i = 0; i < numMicroops - 1; i++) { 129110037SARM gem5 Developers microOps[i]->setDelayedCommit(); 129210037SARM gem5 Developers } 129310037SARM gem5 Developers microOps[numMicroops - 1]->setLastMicroop(); 129410037SARM gem5 Developers} 129510037SARM gem5 Developers 129610037SARM gem5 DevelopersVstSingleOp64::VstSingleOp64(const char *mnem, ExtMachInst machInst, 129710037SARM gem5 Developers OpClass __opClass, RegIndex rn, RegIndex vd, 129810037SARM gem5 Developers RegIndex rm, uint8_t eSize, uint8_t dataSize, 129910037SARM gem5 Developers uint8_t numStructElems, uint8_t index, bool wb, 130010037SARM gem5 Developers bool replicate) : 130110037SARM gem5 Developers PredMacroOp(mnem, machInst, __opClass) 130210037SARM gem5 Developers{ 130310037SARM gem5 Developers RegIndex vx = NumFloatV8ArchRegs / 4; 130410037SARM gem5 Developers RegIndex rnsp = (RegIndex) makeSP((IntRegIndex) rn); 130510037SARM gem5 Developers bool baseIsSP = isSP((IntRegIndex) rnsp); 130610037SARM gem5 Developers 130710037SARM gem5 Developers numMicroops = wb ? 1 : 0; 130810037SARM gem5 Developers 130910037SARM gem5 Developers int eSizeBytes = 1 << eSize; 131010037SARM gem5 Developers int totNumBytes = numStructElems * eSizeBytes; 131110037SARM gem5 Developers assert(totNumBytes <= 64); 131210037SARM gem5 Developers 131310037SARM gem5 Developers // The guiding principle here is that no more than 16 bytes can be 131410037SARM gem5 Developers // transferred at a time 131510037SARM gem5 Developers int numMemMicroops = totNumBytes / 16; 131610037SARM gem5 Developers int residuum = totNumBytes % 16; 131710037SARM gem5 Developers if (residuum) 131810037SARM gem5 Developers ++numMemMicroops; 131910037SARM gem5 Developers numMicroops += numMemMicroops; 132010037SARM gem5 Developers 132110037SARM gem5 Developers int numMarshalMicroops = totNumBytes > 32 ? 2 : 1; 132210037SARM gem5 Developers numMicroops += numMarshalMicroops; 132310037SARM gem5 Developers 132410037SARM gem5 Developers microOps = new StaticInstPtr[numMicroops]; 132510037SARM gem5 Developers unsigned uopIdx = 0; 132610037SARM gem5 Developers 132710037SARM gem5 Developers for(int i = 0; i < numMarshalMicroops; ++i) { 132810037SARM gem5 Developers microOps[uopIdx++] = new MicroPackNeon64( 132910037SARM gem5 Developers machInst, vx + (RegIndex) (2 * i), vd, eSize, dataSize, 133010037SARM gem5 Developers numStructElems, index, i /* step */, replicate); 133110037SARM gem5 Developers } 133210037SARM gem5 Developers 133310037SARM gem5 Developers uint32_t memaccessFlags = TLB::MustBeOne | (TLB::ArmFlags) eSize | 133410037SARM gem5 Developers TLB::AllowUnaligned; 133510037SARM gem5 Developers 133610037SARM gem5 Developers int i = 0; 133710037SARM gem5 Developers for(; i < numMemMicroops - 1; ++i) { 133810037SARM gem5 Developers microOps[uopIdx++] = new MicroNeonStore64( 133910037SARM gem5 Developers machInst, vx + (RegIndex) i, rnsp, 16 * i, memaccessFlags, 134010037SARM gem5 Developers baseIsSP, 16 /* accsize */, eSize); 134110037SARM gem5 Developers } 134210037SARM gem5 Developers microOps[uopIdx++] = new MicroNeonStore64( 134310037SARM gem5 Developers machInst, vx + (RegIndex) i, rnsp, 16 * i, memaccessFlags, baseIsSP, 134410037SARM gem5 Developers residuum ? residuum : 16 /* accSize */, eSize); 134510037SARM gem5 Developers 134610037SARM gem5 Developers // Writeback microop: the post-increment amount is encoded in "Rm": a 134710037SARM gem5 Developers // 64-bit general register OR as '11111' for an immediate value equal to 134810037SARM gem5 Developers // the total number of bytes transferred (i.e. 8, 16, 24, 32, 48 or 64) 134910037SARM gem5 Developers if (wb) { 135010037SARM gem5 Developers if (rm != ((RegIndex) INTREG_X31)) { 135110037SARM gem5 Developers microOps[uopIdx++] = new MicroAddXERegUop(machInst, rnsp, rnsp, rm, 135210037SARM gem5 Developers UXTX, 0); 135310037SARM gem5 Developers } else { 135410037SARM gem5 Developers microOps[uopIdx++] = new MicroAddXiUop(machInst, rnsp, rnsp, 135510037SARM gem5 Developers totNumBytes); 135610037SARM gem5 Developers } 135710037SARM gem5 Developers } 135810037SARM gem5 Developers 135910037SARM gem5 Developers assert(uopIdx == numMicroops); 136010037SARM gem5 Developers 136110037SARM gem5 Developers for (int i = 0; i < numMicroops - 1; i++) { 136210037SARM gem5 Developers microOps[i]->setDelayedCommit(); 136310037SARM gem5 Developers } 136410037SARM gem5 Developers microOps[numMicroops - 1]->setLastMicroop(); 136510037SARM gem5 Developers} 136610037SARM gem5 Developers 13677175Sgblack@eecs.umich.eduMacroVFPMemOp::MacroVFPMemOp(const char *mnem, ExtMachInst machInst, 13687175Sgblack@eecs.umich.edu OpClass __opClass, IntRegIndex rn, 13697175Sgblack@eecs.umich.edu RegIndex vd, bool single, bool up, 13707175Sgblack@eecs.umich.edu bool writeback, bool load, uint32_t offset) : 13717175Sgblack@eecs.umich.edu PredMacroOp(mnem, machInst, __opClass) 13727175Sgblack@eecs.umich.edu{ 13737175Sgblack@eecs.umich.edu int i = 0; 13747175Sgblack@eecs.umich.edu 13757175Sgblack@eecs.umich.edu // The lowest order bit selects fldmx (set) or fldmd (clear). These seem 13767175Sgblack@eecs.umich.edu // to be functionally identical except that fldmx is deprecated. For now 13777175Sgblack@eecs.umich.edu // we'll assume they're otherwise interchangable. 13787175Sgblack@eecs.umich.edu int count = (single ? offset : (offset / 2)); 137910037SARM gem5 Developers if (count == 0 || count > NumFloatV7ArchRegs) 13807175Sgblack@eecs.umich.edu warn_once("Bad offset field for VFP load/store multiple.\n"); 13817175Sgblack@eecs.umich.edu if (count == 0) { 13827175Sgblack@eecs.umich.edu // Force there to be at least one microop so the macroop makes sense. 13837175Sgblack@eecs.umich.edu writeback = true; 13847175Sgblack@eecs.umich.edu } 138510037SARM gem5 Developers if (count > NumFloatV7ArchRegs) 138610037SARM gem5 Developers count = NumFloatV7ArchRegs; 13877175Sgblack@eecs.umich.edu 13887342Sgblack@eecs.umich.edu numMicroops = count * (single ? 1 : 2) + (writeback ? 1 : 0); 13897342Sgblack@eecs.umich.edu microOps = new StaticInstPtr[numMicroops]; 13907342Sgblack@eecs.umich.edu 13917395Sgblack@eecs.umich.edu int64_t addr = 0; 13927175Sgblack@eecs.umich.edu 13937342Sgblack@eecs.umich.edu if (!up) 13947342Sgblack@eecs.umich.edu addr = 4 * offset; 13957175Sgblack@eecs.umich.edu 13967342Sgblack@eecs.umich.edu bool tempUp = up; 13977175Sgblack@eecs.umich.edu for (int j = 0; j < count; j++) { 13987175Sgblack@eecs.umich.edu if (load) { 13997639Sgblack@eecs.umich.edu if (single) { 14007639Sgblack@eecs.umich.edu microOps[i++] = new MicroLdrFpUop(machInst, vd++, rn, 14017639Sgblack@eecs.umich.edu tempUp, addr); 14027639Sgblack@eecs.umich.edu } else { 14037639Sgblack@eecs.umich.edu microOps[i++] = new MicroLdrDBFpUop(machInst, vd++, rn, 14047639Sgblack@eecs.umich.edu tempUp, addr); 14057639Sgblack@eecs.umich.edu microOps[i++] = new MicroLdrDTFpUop(machInst, vd++, rn, tempUp, 14067639Sgblack@eecs.umich.edu addr + (up ? 4 : -4)); 14077639Sgblack@eecs.umich.edu } 14087175Sgblack@eecs.umich.edu } else { 14097639Sgblack@eecs.umich.edu if (single) { 14107639Sgblack@eecs.umich.edu microOps[i++] = new MicroStrFpUop(machInst, vd++, rn, 14117639Sgblack@eecs.umich.edu tempUp, addr); 14127639Sgblack@eecs.umich.edu } else { 14137639Sgblack@eecs.umich.edu microOps[i++] = new MicroStrDBFpUop(machInst, vd++, rn, 14147639Sgblack@eecs.umich.edu tempUp, addr); 14157639Sgblack@eecs.umich.edu microOps[i++] = new MicroStrDTFpUop(machInst, vd++, rn, tempUp, 14167639Sgblack@eecs.umich.edu addr + (up ? 4 : -4)); 14177639Sgblack@eecs.umich.edu } 14187175Sgblack@eecs.umich.edu } 14197342Sgblack@eecs.umich.edu if (!tempUp) { 14207342Sgblack@eecs.umich.edu addr -= (single ? 4 : 8); 14217342Sgblack@eecs.umich.edu // The microops don't handle negative displacement, so turn if we 14227342Sgblack@eecs.umich.edu // hit zero, flip polarity and start adding. 14237395Sgblack@eecs.umich.edu if (addr <= 0) { 14247342Sgblack@eecs.umich.edu tempUp = true; 14257395Sgblack@eecs.umich.edu addr = -addr; 14267342Sgblack@eecs.umich.edu } 14277342Sgblack@eecs.umich.edu } else { 14287342Sgblack@eecs.umich.edu addr += (single ? 4 : 8); 14297342Sgblack@eecs.umich.edu } 14307175Sgblack@eecs.umich.edu } 14317175Sgblack@eecs.umich.edu 14327175Sgblack@eecs.umich.edu if (writeback) { 14337175Sgblack@eecs.umich.edu if (up) { 14347175Sgblack@eecs.umich.edu microOps[i++] = 14357175Sgblack@eecs.umich.edu new MicroAddiUop(machInst, rn, rn, 4 * offset); 14367175Sgblack@eecs.umich.edu } else { 14377175Sgblack@eecs.umich.edu microOps[i++] = 14387175Sgblack@eecs.umich.edu new MicroSubiUop(machInst, rn, rn, 4 * offset); 14397175Sgblack@eecs.umich.edu } 14407175Sgblack@eecs.umich.edu } 14417175Sgblack@eecs.umich.edu 14427342Sgblack@eecs.umich.edu assert(numMicroops == i); 14437175Sgblack@eecs.umich.edu microOps[numMicroops - 1]->setLastMicroop(); 14447343Sgblack@eecs.umich.edu 14457343Sgblack@eecs.umich.edu for (StaticInstPtr *curUop = microOps; 14467343Sgblack@eecs.umich.edu !(*curUop)->isLastMicroop(); curUop++) { 14477343Sgblack@eecs.umich.edu MicroOp * uopPtr = dynamic_cast<MicroOp *>(curUop->get()); 14487343Sgblack@eecs.umich.edu assert(uopPtr); 14497343Sgblack@eecs.umich.edu uopPtr->setDelayedCommit(); 14507343Sgblack@eecs.umich.edu } 14517170Sgblack@eecs.umich.edu} 14527175Sgblack@eecs.umich.edu 14537615Sminkyu.jeong@arm.comstd::string 14547639Sgblack@eecs.umich.eduMicroIntImmOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const 14557639Sgblack@eecs.umich.edu{ 14567639Sgblack@eecs.umich.edu std::stringstream ss; 14577639Sgblack@eecs.umich.edu printMnemonic(ss); 14587639Sgblack@eecs.umich.edu printReg(ss, ura); 14597639Sgblack@eecs.umich.edu ss << ", "; 14607639Sgblack@eecs.umich.edu printReg(ss, urb); 14617639Sgblack@eecs.umich.edu ss << ", "; 14627639Sgblack@eecs.umich.edu ccprintf(ss, "#%d", imm); 14637639Sgblack@eecs.umich.edu return ss.str(); 14647639Sgblack@eecs.umich.edu} 14657639Sgblack@eecs.umich.edu 14667639Sgblack@eecs.umich.edustd::string 146710037SARM gem5 DevelopersMicroIntImmXOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const 146810037SARM gem5 Developers{ 146910037SARM gem5 Developers std::stringstream ss; 147010037SARM gem5 Developers printMnemonic(ss); 147110037SARM gem5 Developers printReg(ss, ura); 147210037SARM gem5 Developers ss << ", "; 147310037SARM gem5 Developers printReg(ss, urb); 147410037SARM gem5 Developers ss << ", "; 147510037SARM gem5 Developers ccprintf(ss, "#%d", imm); 147610037SARM gem5 Developers return ss.str(); 147710037SARM gem5 Developers} 147810037SARM gem5 Developers 147910037SARM gem5 Developersstd::string 14808140SMatt.Horsnell@arm.comMicroSetPCCPSR::generateDisassembly(Addr pc, const SymbolTable *symtab) const 14818140SMatt.Horsnell@arm.com{ 14828140SMatt.Horsnell@arm.com std::stringstream ss; 14838140SMatt.Horsnell@arm.com printMnemonic(ss); 14848140SMatt.Horsnell@arm.com ss << "[PC,CPSR]"; 14858140SMatt.Horsnell@arm.com return ss.str(); 14868140SMatt.Horsnell@arm.com} 14878140SMatt.Horsnell@arm.com 14888140SMatt.Horsnell@arm.comstd::string 148910037SARM gem5 DevelopersMicroIntRegXOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const 149010037SARM gem5 Developers{ 149110037SARM gem5 Developers std::stringstream ss; 149210037SARM gem5 Developers printMnemonic(ss); 149310037SARM gem5 Developers printReg(ss, ura); 149410037SARM gem5 Developers ccprintf(ss, ", "); 149510037SARM gem5 Developers printReg(ss, urb); 149610037SARM gem5 Developers printExtendOperand(false, ss, (IntRegIndex)urc, type, shiftAmt); 149710037SARM gem5 Developers return ss.str(); 149810037SARM gem5 Developers} 149910037SARM gem5 Developers 150010037SARM gem5 Developersstd::string 15017646Sgene.wu@arm.comMicroIntMov::generateDisassembly(Addr pc, const SymbolTable *symtab) const 15027646Sgene.wu@arm.com{ 15037646Sgene.wu@arm.com std::stringstream ss; 15047646Sgene.wu@arm.com printMnemonic(ss); 15057646Sgene.wu@arm.com printReg(ss, ura); 15067646Sgene.wu@arm.com ss << ", "; 15077646Sgene.wu@arm.com printReg(ss, urb); 15087646Sgene.wu@arm.com return ss.str(); 15097646Sgene.wu@arm.com} 15107646Sgene.wu@arm.com 15117646Sgene.wu@arm.comstd::string 15127615Sminkyu.jeong@arm.comMicroIntOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const 15137615Sminkyu.jeong@arm.com{ 15147615Sminkyu.jeong@arm.com std::stringstream ss; 15157615Sminkyu.jeong@arm.com printMnemonic(ss); 15167615Sminkyu.jeong@arm.com printReg(ss, ura); 15177615Sminkyu.jeong@arm.com ss << ", "; 15187615Sminkyu.jeong@arm.com printReg(ss, urb); 15197615Sminkyu.jeong@arm.com ss << ", "; 15207639Sgblack@eecs.umich.edu printReg(ss, urc); 15217615Sminkyu.jeong@arm.com return ss.str(); 15227175Sgblack@eecs.umich.edu} 15237615Sminkyu.jeong@arm.com 15247615Sminkyu.jeong@arm.comstd::string 15257615Sminkyu.jeong@arm.comMicroMemOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const 15267615Sminkyu.jeong@arm.com{ 15277615Sminkyu.jeong@arm.com std::stringstream ss; 15287615Sminkyu.jeong@arm.com printMnemonic(ss); 152910180SCurtis.Dunham@arm.com if (isFloating()) 153010180SCurtis.Dunham@arm.com printReg(ss, ura + FP_Reg_Base); 153110180SCurtis.Dunham@arm.com else 153210180SCurtis.Dunham@arm.com printReg(ss, ura); 15337615Sminkyu.jeong@arm.com ss << ", ["; 15347615Sminkyu.jeong@arm.com printReg(ss, urb); 15357615Sminkyu.jeong@arm.com ss << ", "; 15367615Sminkyu.jeong@arm.com ccprintf(ss, "#%d", imm); 15377615Sminkyu.jeong@arm.com ss << "]"; 15387615Sminkyu.jeong@arm.com return ss.str(); 15397615Sminkyu.jeong@arm.com} 15407615Sminkyu.jeong@arm.com 15417615Sminkyu.jeong@arm.com} 1542