macromem.cc revision 10180
17170Sgblack@eecs.umich.edu/* 210037SARM gem5 Developers * Copyright (c) 2010-2013 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 1747343Sgblack@eecs.umich.edu for (StaticInstPtr *curUop = microOps; 1757343Sgblack@eecs.umich.edu !(*curUop)->isLastMicroop(); curUop++) { 1767343Sgblack@eecs.umich.edu MicroOp * uopPtr = dynamic_cast<MicroOp *>(curUop->get()); 1777343Sgblack@eecs.umich.edu assert(uopPtr); 1787343Sgblack@eecs.umich.edu uopPtr->setDelayedCommit(); 1797343Sgblack@eecs.umich.edu } 1807170Sgblack@eecs.umich.edu} 1817170Sgblack@eecs.umich.edu 18210037SARM gem5 DevelopersPairMemOp::PairMemOp(const char *mnem, ExtMachInst machInst, OpClass __opClass, 18310037SARM gem5 Developers uint32_t size, bool fp, bool load, bool noAlloc, 18410037SARM gem5 Developers bool signExt, bool exclusive, bool acrel, 18510037SARM gem5 Developers int64_t imm, AddrMode mode, 18610037SARM gem5 Developers IntRegIndex rn, IntRegIndex rt, IntRegIndex rt2) : 18710037SARM gem5 Developers PredMacroOp(mnem, machInst, __opClass) 18810037SARM gem5 Developers{ 18910037SARM gem5 Developers bool writeback = (mode != AddrMd_Offset); 19010037SARM gem5 Developers numMicroops = 1 + (size / 4) + (writeback ? 1 : 0); 19110037SARM gem5 Developers microOps = new StaticInstPtr[numMicroops]; 19210037SARM gem5 Developers 19310037SARM gem5 Developers StaticInstPtr *uop = microOps; 19410037SARM gem5 Developers 19510037SARM gem5 Developers bool post = (mode == AddrMd_PostIndex); 19610037SARM gem5 Developers 19710037SARM gem5 Developers rn = makeSP(rn); 19810037SARM gem5 Developers 19910037SARM gem5 Developers *uop = new MicroAddXiSpAlignUop(machInst, INTREG_UREG0, rn, post ? 0 : imm); 20010037SARM gem5 Developers 20110037SARM gem5 Developers if (fp) { 20210037SARM gem5 Developers if (size == 16) { 20310037SARM gem5 Developers if (load) { 20410037SARM gem5 Developers *++uop = new MicroLdrQBFpXImmUop(machInst, rt, 20510037SARM gem5 Developers INTREG_UREG0, 0, noAlloc, exclusive, acrel); 20610037SARM gem5 Developers *++uop = new MicroLdrQTFpXImmUop(machInst, rt, 20710037SARM gem5 Developers INTREG_UREG0, 0, noAlloc, exclusive, acrel); 20810037SARM gem5 Developers *++uop = new MicroLdrQBFpXImmUop(machInst, rt2, 20910037SARM gem5 Developers INTREG_UREG0, 16, noAlloc, exclusive, acrel); 21010037SARM gem5 Developers *++uop = new MicroLdrQTFpXImmUop(machInst, rt2, 21110037SARM gem5 Developers INTREG_UREG0, 16, noAlloc, exclusive, acrel); 21210037SARM gem5 Developers } else { 21310037SARM gem5 Developers *++uop = new MicroStrQBFpXImmUop(machInst, rt, 21410037SARM gem5 Developers INTREG_UREG0, 0, noAlloc, exclusive, acrel); 21510037SARM gem5 Developers *++uop = new MicroStrQTFpXImmUop(machInst, rt, 21610037SARM gem5 Developers INTREG_UREG0, 0, noAlloc, exclusive, acrel); 21710037SARM gem5 Developers *++uop = new MicroStrQBFpXImmUop(machInst, rt2, 21810037SARM gem5 Developers INTREG_UREG0, 16, noAlloc, exclusive, acrel); 21910037SARM gem5 Developers *++uop = new MicroStrQTFpXImmUop(machInst, rt2, 22010037SARM gem5 Developers INTREG_UREG0, 16, noAlloc, exclusive, acrel); 22110037SARM gem5 Developers } 22210037SARM gem5 Developers } else if (size == 8) { 22310037SARM gem5 Developers if (load) { 22410037SARM gem5 Developers *++uop = new MicroLdrFpXImmUop(machInst, rt, 22510037SARM gem5 Developers INTREG_UREG0, 0, noAlloc, exclusive, acrel); 22610037SARM gem5 Developers *++uop = new MicroLdrFpXImmUop(machInst, rt2, 22710037SARM gem5 Developers INTREG_UREG0, 8, noAlloc, exclusive, acrel); 22810037SARM gem5 Developers } else { 22910037SARM gem5 Developers *++uop = new MicroStrFpXImmUop(machInst, rt, 23010037SARM gem5 Developers INTREG_UREG0, 0, noAlloc, exclusive, acrel); 23110037SARM gem5 Developers *++uop = new MicroStrFpXImmUop(machInst, rt2, 23210037SARM gem5 Developers INTREG_UREG0, 8, noAlloc, exclusive, acrel); 23310037SARM gem5 Developers } 23410037SARM gem5 Developers } else if (size == 4) { 23510037SARM gem5 Developers if (load) { 23610037SARM gem5 Developers *++uop = new MicroLdrDFpXImmUop(machInst, rt, rt2, 23710037SARM gem5 Developers INTREG_UREG0, 0, noAlloc, exclusive, acrel); 23810037SARM gem5 Developers } else { 23910037SARM gem5 Developers *++uop = new MicroStrDFpXImmUop(machInst, rt, rt2, 24010037SARM gem5 Developers INTREG_UREG0, 0, noAlloc, exclusive, acrel); 24110037SARM gem5 Developers } 24210037SARM gem5 Developers } 24310037SARM gem5 Developers } else { 24410037SARM gem5 Developers if (size == 8) { 24510037SARM gem5 Developers if (load) { 24610037SARM gem5 Developers *++uop = new MicroLdrXImmUop(machInst, rt, INTREG_UREG0, 24710037SARM gem5 Developers 0, noAlloc, exclusive, acrel); 24810037SARM gem5 Developers *++uop = new MicroLdrXImmUop(machInst, rt2, INTREG_UREG0, 24910037SARM gem5 Developers size, noAlloc, exclusive, acrel); 25010037SARM gem5 Developers } else { 25110037SARM gem5 Developers *++uop = new MicroStrXImmUop(machInst, rt, INTREG_UREG0, 25210037SARM gem5 Developers 0, noAlloc, exclusive, acrel); 25310037SARM gem5 Developers *++uop = new MicroStrXImmUop(machInst, rt2, INTREG_UREG0, 25410037SARM gem5 Developers size, noAlloc, exclusive, acrel); 25510037SARM gem5 Developers } 25610037SARM gem5 Developers } else if (size == 4) { 25710037SARM gem5 Developers if (load) { 25810037SARM gem5 Developers if (signExt) { 25910037SARM gem5 Developers *++uop = new MicroLdrDSXImmUop(machInst, rt, rt2, 26010037SARM gem5 Developers INTREG_UREG0, 0, noAlloc, exclusive, acrel); 26110037SARM gem5 Developers } else { 26210037SARM gem5 Developers *++uop = new MicroLdrDUXImmUop(machInst, rt, rt2, 26310037SARM gem5 Developers INTREG_UREG0, 0, noAlloc, exclusive, acrel); 26410037SARM gem5 Developers } 26510037SARM gem5 Developers } else { 26610037SARM gem5 Developers *++uop = new MicroStrDXImmUop(machInst, rt, rt2, 26710037SARM gem5 Developers INTREG_UREG0, 0, noAlloc, exclusive, acrel); 26810037SARM gem5 Developers } 26910037SARM gem5 Developers } 27010037SARM gem5 Developers } 27110037SARM gem5 Developers 27210037SARM gem5 Developers if (writeback) { 27310037SARM gem5 Developers *++uop = new MicroAddXiUop(machInst, rn, INTREG_UREG0, 27410037SARM gem5 Developers post ? imm : 0); 27510037SARM gem5 Developers } 27610037SARM gem5 Developers 27710037SARM gem5 Developers (*uop)->setLastMicroop(); 27810037SARM gem5 Developers 27910037SARM gem5 Developers for (StaticInstPtr *curUop = microOps; 28010037SARM gem5 Developers !(*curUop)->isLastMicroop(); curUop++) { 28110037SARM gem5 Developers (*curUop)->setDelayedCommit(); 28210037SARM gem5 Developers } 28310037SARM gem5 Developers} 28410037SARM gem5 Developers 28510037SARM gem5 DevelopersBigFpMemImmOp::BigFpMemImmOp(const char *mnem, ExtMachInst machInst, 28610037SARM gem5 Developers OpClass __opClass, bool load, IntRegIndex dest, 28710037SARM gem5 Developers IntRegIndex base, int64_t imm) : 28810037SARM gem5 Developers PredMacroOp(mnem, machInst, __opClass) 28910037SARM gem5 Developers{ 29010037SARM gem5 Developers numMicroops = 2; 29110037SARM gem5 Developers microOps = new StaticInstPtr[numMicroops]; 29210037SARM gem5 Developers 29310037SARM gem5 Developers if (load) { 29410037SARM gem5 Developers microOps[0] = new MicroLdrQBFpXImmUop(machInst, dest, base, imm); 29510037SARM gem5 Developers microOps[1] = new MicroLdrQTFpXImmUop(machInst, dest, base, imm); 29610037SARM gem5 Developers } else { 29710037SARM gem5 Developers microOps[0] = new MicroStrQBFpXImmUop(machInst, dest, base, imm); 29810037SARM gem5 Developers microOps[1] = new MicroStrQTFpXImmUop(machInst, dest, base, imm); 29910037SARM gem5 Developers } 30010037SARM gem5 Developers microOps[0]->setDelayedCommit(); 30110037SARM gem5 Developers microOps[1]->setLastMicroop(); 30210037SARM gem5 Developers} 30310037SARM gem5 Developers 30410037SARM gem5 DevelopersBigFpMemPostOp::BigFpMemPostOp(const char *mnem, ExtMachInst machInst, 30510037SARM gem5 Developers OpClass __opClass, bool load, IntRegIndex dest, 30610037SARM gem5 Developers IntRegIndex base, int64_t imm) : 30710037SARM gem5 Developers PredMacroOp(mnem, machInst, __opClass) 30810037SARM gem5 Developers{ 30910037SARM gem5 Developers numMicroops = 3; 31010037SARM gem5 Developers microOps = new StaticInstPtr[numMicroops]; 31110037SARM gem5 Developers 31210037SARM gem5 Developers if (load) { 31310037SARM gem5 Developers microOps[0] = new MicroLdrQBFpXImmUop(machInst, dest, base, 0); 31410037SARM gem5 Developers microOps[1] = new MicroLdrQTFpXImmUop(machInst, dest, base, 0); 31510037SARM gem5 Developers } else { 31610037SARM gem5 Developers microOps[0] = new MicroStrQBFpXImmUop(machInst, dest, base, 0); 31710037SARM gem5 Developers microOps[1] = new MicroStrQTFpXImmUop(machInst, dest, base, 0); 31810037SARM gem5 Developers } 31910037SARM gem5 Developers microOps[2] = new MicroAddXiUop(machInst, base, base, imm); 32010037SARM gem5 Developers 32110037SARM gem5 Developers microOps[0]->setDelayedCommit(); 32210037SARM gem5 Developers microOps[1]->setDelayedCommit(); 32310037SARM gem5 Developers microOps[2]->setLastMicroop(); 32410037SARM gem5 Developers} 32510037SARM gem5 Developers 32610037SARM gem5 DevelopersBigFpMemPreOp::BigFpMemPreOp(const char *mnem, ExtMachInst machInst, 32710037SARM gem5 Developers OpClass __opClass, bool load, IntRegIndex dest, 32810037SARM gem5 Developers IntRegIndex base, int64_t imm) : 32910037SARM gem5 Developers PredMacroOp(mnem, machInst, __opClass) 33010037SARM gem5 Developers{ 33110037SARM gem5 Developers numMicroops = 3; 33210037SARM gem5 Developers microOps = new StaticInstPtr[numMicroops]; 33310037SARM gem5 Developers 33410037SARM gem5 Developers if (load) { 33510037SARM gem5 Developers microOps[0] = new MicroLdrQBFpXImmUop(machInst, dest, base, imm); 33610037SARM gem5 Developers microOps[1] = new MicroLdrQTFpXImmUop(machInst, dest, base, imm); 33710037SARM gem5 Developers } else { 33810037SARM gem5 Developers microOps[0] = new MicroStrQBFpXImmUop(machInst, dest, base, imm); 33910037SARM gem5 Developers microOps[1] = new MicroStrQTFpXImmUop(machInst, dest, base, imm); 34010037SARM gem5 Developers } 34110037SARM gem5 Developers microOps[2] = new MicroAddXiUop(machInst, base, base, imm); 34210037SARM gem5 Developers 34310037SARM gem5 Developers microOps[0]->setDelayedCommit(); 34410037SARM gem5 Developers microOps[1]->setDelayedCommit(); 34510037SARM gem5 Developers microOps[2]->setLastMicroop(); 34610037SARM gem5 Developers} 34710037SARM gem5 Developers 34810037SARM gem5 DevelopersBigFpMemRegOp::BigFpMemRegOp(const char *mnem, ExtMachInst machInst, 34910037SARM gem5 Developers OpClass __opClass, bool load, IntRegIndex dest, 35010037SARM gem5 Developers IntRegIndex base, IntRegIndex offset, 35110037SARM gem5 Developers ArmExtendType type, int64_t imm) : 35210037SARM gem5 Developers PredMacroOp(mnem, machInst, __opClass) 35310037SARM gem5 Developers{ 35410037SARM gem5 Developers numMicroops = 2; 35510037SARM gem5 Developers microOps = new StaticInstPtr[numMicroops]; 35610037SARM gem5 Developers 35710037SARM gem5 Developers if (load) { 35810037SARM gem5 Developers microOps[0] = new MicroLdrQBFpXRegUop(machInst, dest, base, 35910037SARM gem5 Developers offset, type, imm); 36010037SARM gem5 Developers microOps[1] = new MicroLdrQTFpXRegUop(machInst, dest, base, 36110037SARM gem5 Developers offset, type, imm); 36210037SARM gem5 Developers } else { 36310037SARM gem5 Developers microOps[0] = new MicroStrQBFpXRegUop(machInst, dest, base, 36410037SARM gem5 Developers offset, type, imm); 36510037SARM gem5 Developers microOps[1] = new MicroStrQTFpXRegUop(machInst, dest, base, 36610037SARM gem5 Developers offset, type, imm); 36710037SARM gem5 Developers } 36810037SARM gem5 Developers 36910037SARM gem5 Developers microOps[0]->setDelayedCommit(); 37010037SARM gem5 Developers microOps[1]->setLastMicroop(); 37110037SARM gem5 Developers} 37210037SARM gem5 Developers 37310037SARM gem5 DevelopersBigFpMemLitOp::BigFpMemLitOp(const char *mnem, ExtMachInst machInst, 37410037SARM gem5 Developers OpClass __opClass, IntRegIndex dest, 37510037SARM gem5 Developers int64_t imm) : 37610037SARM gem5 Developers PredMacroOp(mnem, machInst, __opClass) 37710037SARM gem5 Developers{ 37810037SARM gem5 Developers numMicroops = 2; 37910037SARM gem5 Developers microOps = new StaticInstPtr[numMicroops]; 38010037SARM gem5 Developers 38110037SARM gem5 Developers microOps[0] = new MicroLdrQBFpXLitUop(machInst, dest, imm); 38210037SARM gem5 Developers microOps[1] = new MicroLdrQTFpXLitUop(machInst, dest, imm); 38310037SARM gem5 Developers 38410037SARM gem5 Developers microOps[0]->setDelayedCommit(); 38510037SARM gem5 Developers microOps[1]->setLastMicroop(); 38610037SARM gem5 Developers} 38710037SARM gem5 Developers 3887639Sgblack@eecs.umich.eduVldMultOp::VldMultOp(const char *mnem, ExtMachInst machInst, OpClass __opClass, 3897639Sgblack@eecs.umich.edu unsigned elems, RegIndex rn, RegIndex vd, unsigned regs, 3907639Sgblack@eecs.umich.edu unsigned inc, uint32_t size, uint32_t align, RegIndex rm) : 3917639Sgblack@eecs.umich.edu PredMacroOp(mnem, machInst, __opClass) 3927639Sgblack@eecs.umich.edu{ 3937639Sgblack@eecs.umich.edu assert(regs > 0 && regs <= 4); 3947639Sgblack@eecs.umich.edu assert(regs % elems == 0); 3957639Sgblack@eecs.umich.edu 3967639Sgblack@eecs.umich.edu numMicroops = (regs > 2) ? 2 : 1; 3977639Sgblack@eecs.umich.edu bool wb = (rm != 15); 3987639Sgblack@eecs.umich.edu bool deinterleave = (elems > 1); 3997639Sgblack@eecs.umich.edu 4007639Sgblack@eecs.umich.edu if (wb) numMicroops++; 4017639Sgblack@eecs.umich.edu if (deinterleave) numMicroops += (regs / elems); 4027639Sgblack@eecs.umich.edu microOps = new StaticInstPtr[numMicroops]; 4037639Sgblack@eecs.umich.edu 40410037SARM gem5 Developers RegIndex rMid = deinterleave ? NumFloatV7ArchRegs : vd * 2; 4057639Sgblack@eecs.umich.edu 4067639Sgblack@eecs.umich.edu uint32_t noAlign = TLB::MustBeOne; 4077639Sgblack@eecs.umich.edu 4087639Sgblack@eecs.umich.edu unsigned uopIdx = 0; 4097639Sgblack@eecs.umich.edu switch (regs) { 4107639Sgblack@eecs.umich.edu case 4: 4117639Sgblack@eecs.umich.edu microOps[uopIdx++] = newNeonMemInst<MicroLdrNeon16Uop>( 4127639Sgblack@eecs.umich.edu size, machInst, rMid, rn, 0, align); 4137639Sgblack@eecs.umich.edu microOps[uopIdx++] = newNeonMemInst<MicroLdrNeon16Uop>( 4147639Sgblack@eecs.umich.edu size, machInst, rMid + 4, rn, 16, noAlign); 4157639Sgblack@eecs.umich.edu break; 4167639Sgblack@eecs.umich.edu case 3: 4177639Sgblack@eecs.umich.edu microOps[uopIdx++] = newNeonMemInst<MicroLdrNeon16Uop>( 4187639Sgblack@eecs.umich.edu size, machInst, rMid, rn, 0, align); 4197639Sgblack@eecs.umich.edu microOps[uopIdx++] = newNeonMemInst<MicroLdrNeon8Uop>( 4207639Sgblack@eecs.umich.edu size, machInst, rMid + 4, rn, 16, noAlign); 4217639Sgblack@eecs.umich.edu break; 4227639Sgblack@eecs.umich.edu case 2: 4237639Sgblack@eecs.umich.edu microOps[uopIdx++] = newNeonMemInst<MicroLdrNeon16Uop>( 4247639Sgblack@eecs.umich.edu size, machInst, rMid, rn, 0, align); 4257639Sgblack@eecs.umich.edu break; 4267639Sgblack@eecs.umich.edu case 1: 4277639Sgblack@eecs.umich.edu microOps[uopIdx++] = newNeonMemInst<MicroLdrNeon8Uop>( 4287639Sgblack@eecs.umich.edu size, machInst, rMid, rn, 0, align); 4297639Sgblack@eecs.umich.edu break; 4307639Sgblack@eecs.umich.edu default: 4317853SMatt.Horsnell@ARM.com // Unknown number of registers 4327853SMatt.Horsnell@ARM.com microOps[uopIdx++] = new Unknown(machInst); 4337639Sgblack@eecs.umich.edu } 4347639Sgblack@eecs.umich.edu if (wb) { 4357639Sgblack@eecs.umich.edu if (rm != 15 && rm != 13) { 4367639Sgblack@eecs.umich.edu microOps[uopIdx++] = 4377646Sgene.wu@arm.com new MicroAddUop(machInst, rn, rn, rm, 0, ArmISA::LSL); 4387639Sgblack@eecs.umich.edu } else { 4397639Sgblack@eecs.umich.edu microOps[uopIdx++] = 4407639Sgblack@eecs.umich.edu new MicroAddiUop(machInst, rn, rn, regs * 8); 4417639Sgblack@eecs.umich.edu } 4427639Sgblack@eecs.umich.edu } 4437639Sgblack@eecs.umich.edu if (deinterleave) { 4447639Sgblack@eecs.umich.edu switch (elems) { 4457639Sgblack@eecs.umich.edu case 4: 4467639Sgblack@eecs.umich.edu assert(regs == 4); 4477639Sgblack@eecs.umich.edu microOps[uopIdx++] = newNeonMixInst<MicroDeintNeon8Uop>( 4487639Sgblack@eecs.umich.edu size, machInst, vd * 2, rMid, inc * 2); 4497639Sgblack@eecs.umich.edu break; 4507639Sgblack@eecs.umich.edu case 3: 4517639Sgblack@eecs.umich.edu assert(regs == 3); 4527639Sgblack@eecs.umich.edu microOps[uopIdx++] = newNeonMixInst<MicroDeintNeon6Uop>( 4537639Sgblack@eecs.umich.edu size, machInst, vd * 2, rMid, inc * 2); 4547639Sgblack@eecs.umich.edu break; 4557639Sgblack@eecs.umich.edu case 2: 4567639Sgblack@eecs.umich.edu assert(regs == 4 || regs == 2); 4577639Sgblack@eecs.umich.edu if (regs == 4) { 4587639Sgblack@eecs.umich.edu microOps[uopIdx++] = newNeonMixInst<MicroDeintNeon4Uop>( 4597639Sgblack@eecs.umich.edu size, machInst, vd * 2, rMid, inc * 2); 4607639Sgblack@eecs.umich.edu microOps[uopIdx++] = newNeonMixInst<MicroDeintNeon4Uop>( 4617639Sgblack@eecs.umich.edu size, machInst, vd * 2 + 2, rMid + 4, inc * 2); 4627639Sgblack@eecs.umich.edu } else { 4637639Sgblack@eecs.umich.edu microOps[uopIdx++] = newNeonMixInst<MicroDeintNeon4Uop>( 4647639Sgblack@eecs.umich.edu size, machInst, vd * 2, rMid, inc * 2); 4657639Sgblack@eecs.umich.edu } 4667639Sgblack@eecs.umich.edu break; 4677639Sgblack@eecs.umich.edu default: 4687853SMatt.Horsnell@ARM.com // Bad number of elements to deinterleave 4697853SMatt.Horsnell@ARM.com microOps[uopIdx++] = new Unknown(machInst); 4707639Sgblack@eecs.umich.edu } 4717639Sgblack@eecs.umich.edu } 4727639Sgblack@eecs.umich.edu assert(uopIdx == numMicroops); 4737639Sgblack@eecs.umich.edu 4747639Sgblack@eecs.umich.edu for (unsigned i = 0; i < numMicroops - 1; i++) { 4757639Sgblack@eecs.umich.edu MicroOp * uopPtr = dynamic_cast<MicroOp *>(microOps[i].get()); 4767639Sgblack@eecs.umich.edu assert(uopPtr); 4777639Sgblack@eecs.umich.edu uopPtr->setDelayedCommit(); 4787639Sgblack@eecs.umich.edu } 4797639Sgblack@eecs.umich.edu microOps[numMicroops - 1]->setLastMicroop(); 4807639Sgblack@eecs.umich.edu} 4817639Sgblack@eecs.umich.edu 4827639Sgblack@eecs.umich.eduVldSingleOp::VldSingleOp(const char *mnem, ExtMachInst machInst, 4837639Sgblack@eecs.umich.edu OpClass __opClass, bool all, unsigned elems, 4847639Sgblack@eecs.umich.edu RegIndex rn, RegIndex vd, unsigned regs, 4857639Sgblack@eecs.umich.edu unsigned inc, uint32_t size, uint32_t align, 4867639Sgblack@eecs.umich.edu RegIndex rm, unsigned lane) : 4877639Sgblack@eecs.umich.edu PredMacroOp(mnem, machInst, __opClass) 4887639Sgblack@eecs.umich.edu{ 4897639Sgblack@eecs.umich.edu assert(regs > 0 && regs <= 4); 4907639Sgblack@eecs.umich.edu assert(regs % elems == 0); 4917639Sgblack@eecs.umich.edu 4927639Sgblack@eecs.umich.edu unsigned eBytes = (1 << size); 4937639Sgblack@eecs.umich.edu unsigned loadSize = eBytes * elems; 4947639Sgblack@eecs.umich.edu unsigned loadRegs M5_VAR_USED = (loadSize + sizeof(FloatRegBits) - 1) / 4957639Sgblack@eecs.umich.edu sizeof(FloatRegBits); 4967639Sgblack@eecs.umich.edu 4977639Sgblack@eecs.umich.edu assert(loadRegs > 0 && loadRegs <= 4); 4987639Sgblack@eecs.umich.edu 4997639Sgblack@eecs.umich.edu numMicroops = 1; 5007639Sgblack@eecs.umich.edu bool wb = (rm != 15); 5017639Sgblack@eecs.umich.edu 5027639Sgblack@eecs.umich.edu if (wb) numMicroops++; 5037639Sgblack@eecs.umich.edu numMicroops += (regs / elems); 5047639Sgblack@eecs.umich.edu microOps = new StaticInstPtr[numMicroops]; 5057639Sgblack@eecs.umich.edu 50610037SARM gem5 Developers RegIndex ufp0 = NumFloatV7ArchRegs; 5077639Sgblack@eecs.umich.edu 5087639Sgblack@eecs.umich.edu unsigned uopIdx = 0; 5097639Sgblack@eecs.umich.edu switch (loadSize) { 5107639Sgblack@eecs.umich.edu case 1: 5117639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroLdrNeon1Uop<uint8_t>( 5127639Sgblack@eecs.umich.edu machInst, ufp0, rn, 0, align); 5137639Sgblack@eecs.umich.edu break; 5147639Sgblack@eecs.umich.edu case 2: 5157639Sgblack@eecs.umich.edu if (eBytes == 2) { 5167639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroLdrNeon2Uop<uint16_t>( 5177639Sgblack@eecs.umich.edu machInst, ufp0, rn, 0, align); 5187639Sgblack@eecs.umich.edu } else { 5197639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroLdrNeon2Uop<uint8_t>( 5207639Sgblack@eecs.umich.edu machInst, ufp0, rn, 0, align); 5217639Sgblack@eecs.umich.edu } 5227639Sgblack@eecs.umich.edu break; 5237639Sgblack@eecs.umich.edu case 3: 5247639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroLdrNeon3Uop<uint8_t>( 5257639Sgblack@eecs.umich.edu machInst, ufp0, rn, 0, align); 5267639Sgblack@eecs.umich.edu break; 5277639Sgblack@eecs.umich.edu case 4: 5287639Sgblack@eecs.umich.edu switch (eBytes) { 5297639Sgblack@eecs.umich.edu case 1: 5307639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroLdrNeon4Uop<uint8_t>( 5317639Sgblack@eecs.umich.edu machInst, ufp0, rn, 0, align); 5327639Sgblack@eecs.umich.edu break; 5337639Sgblack@eecs.umich.edu case 2: 5347639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroLdrNeon4Uop<uint16_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 microOps[uopIdx++] = new MicroLdrNeon4Uop<uint32_t>( 5397639Sgblack@eecs.umich.edu machInst, ufp0, rn, 0, align); 5407639Sgblack@eecs.umich.edu break; 5417639Sgblack@eecs.umich.edu } 5427639Sgblack@eecs.umich.edu break; 5437639Sgblack@eecs.umich.edu case 6: 5447639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroLdrNeon6Uop<uint16_t>( 5457639Sgblack@eecs.umich.edu machInst, ufp0, rn, 0, align); 5467639Sgblack@eecs.umich.edu break; 5477639Sgblack@eecs.umich.edu case 8: 5487639Sgblack@eecs.umich.edu switch (eBytes) { 5497639Sgblack@eecs.umich.edu case 2: 5507639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroLdrNeon8Uop<uint16_t>( 5517639Sgblack@eecs.umich.edu machInst, ufp0, rn, 0, align); 5527639Sgblack@eecs.umich.edu break; 5537639Sgblack@eecs.umich.edu case 4: 5547639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroLdrNeon8Uop<uint32_t>( 5557639Sgblack@eecs.umich.edu machInst, ufp0, rn, 0, align); 5567639Sgblack@eecs.umich.edu break; 5577639Sgblack@eecs.umich.edu } 5587639Sgblack@eecs.umich.edu break; 5597639Sgblack@eecs.umich.edu case 12: 5607639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroLdrNeon12Uop<uint32_t>( 5617639Sgblack@eecs.umich.edu machInst, ufp0, rn, 0, align); 5627639Sgblack@eecs.umich.edu break; 5637639Sgblack@eecs.umich.edu case 16: 5647639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroLdrNeon16Uop<uint32_t>( 5657639Sgblack@eecs.umich.edu machInst, ufp0, rn, 0, align); 5667639Sgblack@eecs.umich.edu break; 5677639Sgblack@eecs.umich.edu default: 5687853SMatt.Horsnell@ARM.com // Unrecognized load size 5697853SMatt.Horsnell@ARM.com microOps[uopIdx++] = new Unknown(machInst); 5707639Sgblack@eecs.umich.edu } 5717639Sgblack@eecs.umich.edu if (wb) { 5727639Sgblack@eecs.umich.edu if (rm != 15 && rm != 13) { 5737639Sgblack@eecs.umich.edu microOps[uopIdx++] = 5747646Sgene.wu@arm.com new MicroAddUop(machInst, rn, rn, rm, 0, ArmISA::LSL); 5757639Sgblack@eecs.umich.edu } else { 5767639Sgblack@eecs.umich.edu microOps[uopIdx++] = 5777639Sgblack@eecs.umich.edu new MicroAddiUop(machInst, rn, rn, loadSize); 5787639Sgblack@eecs.umich.edu } 5797639Sgblack@eecs.umich.edu } 5807639Sgblack@eecs.umich.edu switch (elems) { 5817639Sgblack@eecs.umich.edu case 4: 5827639Sgblack@eecs.umich.edu assert(regs == 4); 5837639Sgblack@eecs.umich.edu switch (size) { 5847639Sgblack@eecs.umich.edu case 0: 5857639Sgblack@eecs.umich.edu if (all) { 5867639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroUnpackAllNeon2to8Uop<uint8_t>( 5877639Sgblack@eecs.umich.edu machInst, vd * 2, ufp0, inc * 2); 5887639Sgblack@eecs.umich.edu } else { 5897639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroUnpackNeon2to8Uop<uint8_t>( 5907639Sgblack@eecs.umich.edu machInst, vd * 2, ufp0, inc * 2, lane); 5917639Sgblack@eecs.umich.edu } 5927639Sgblack@eecs.umich.edu break; 5937639Sgblack@eecs.umich.edu case 1: 5947639Sgblack@eecs.umich.edu if (all) { 5957639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroUnpackAllNeon2to8Uop<uint16_t>( 5967639Sgblack@eecs.umich.edu machInst, vd * 2, ufp0, inc * 2); 5977639Sgblack@eecs.umich.edu } else { 5987639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroUnpackNeon2to8Uop<uint16_t>( 5997639Sgblack@eecs.umich.edu machInst, vd * 2, ufp0, inc * 2, lane); 6007639Sgblack@eecs.umich.edu } 6017639Sgblack@eecs.umich.edu break; 6027639Sgblack@eecs.umich.edu case 2: 6037639Sgblack@eecs.umich.edu if (all) { 6047639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroUnpackAllNeon4to8Uop<uint32_t>( 6057639Sgblack@eecs.umich.edu machInst, vd * 2, ufp0, inc * 2); 6067639Sgblack@eecs.umich.edu } else { 6077639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroUnpackNeon4to8Uop<uint32_t>( 6087639Sgblack@eecs.umich.edu machInst, vd * 2, ufp0, inc * 2, lane); 6097639Sgblack@eecs.umich.edu } 6107639Sgblack@eecs.umich.edu break; 6117639Sgblack@eecs.umich.edu default: 6127853SMatt.Horsnell@ARM.com // Bad size 6137853SMatt.Horsnell@ARM.com microOps[uopIdx++] = new Unknown(machInst); 6147639Sgblack@eecs.umich.edu break; 6157639Sgblack@eecs.umich.edu } 6167639Sgblack@eecs.umich.edu break; 6177639Sgblack@eecs.umich.edu case 3: 6187639Sgblack@eecs.umich.edu assert(regs == 3); 6197639Sgblack@eecs.umich.edu switch (size) { 6207639Sgblack@eecs.umich.edu case 0: 6217639Sgblack@eecs.umich.edu if (all) { 6227639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroUnpackAllNeon2to6Uop<uint8_t>( 6237639Sgblack@eecs.umich.edu machInst, vd * 2, ufp0, inc * 2); 6247639Sgblack@eecs.umich.edu } else { 6257639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroUnpackNeon2to6Uop<uint8_t>( 6267639Sgblack@eecs.umich.edu machInst, vd * 2, ufp0, inc * 2, lane); 6277639Sgblack@eecs.umich.edu } 6287639Sgblack@eecs.umich.edu break; 6297639Sgblack@eecs.umich.edu case 1: 6307639Sgblack@eecs.umich.edu if (all) { 6317639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroUnpackAllNeon2to6Uop<uint16_t>( 6327639Sgblack@eecs.umich.edu machInst, vd * 2, ufp0, inc * 2); 6337639Sgblack@eecs.umich.edu } else { 6347639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroUnpackNeon2to6Uop<uint16_t>( 6357639Sgblack@eecs.umich.edu machInst, vd * 2, ufp0, inc * 2, lane); 6367639Sgblack@eecs.umich.edu } 6377639Sgblack@eecs.umich.edu break; 6387639Sgblack@eecs.umich.edu case 2: 6397639Sgblack@eecs.umich.edu if (all) { 6407639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroUnpackAllNeon4to6Uop<uint32_t>( 6417639Sgblack@eecs.umich.edu machInst, vd * 2, ufp0, inc * 2); 6427639Sgblack@eecs.umich.edu } else { 6437639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroUnpackNeon4to6Uop<uint32_t>( 6447639Sgblack@eecs.umich.edu machInst, vd * 2, ufp0, inc * 2, lane); 6457639Sgblack@eecs.umich.edu } 6467639Sgblack@eecs.umich.edu break; 6477639Sgblack@eecs.umich.edu default: 6487853SMatt.Horsnell@ARM.com // Bad size 6497853SMatt.Horsnell@ARM.com microOps[uopIdx++] = new Unknown(machInst); 6507639Sgblack@eecs.umich.edu break; 6517639Sgblack@eecs.umich.edu } 6527639Sgblack@eecs.umich.edu break; 6537639Sgblack@eecs.umich.edu case 2: 6547639Sgblack@eecs.umich.edu assert(regs == 2); 6557639Sgblack@eecs.umich.edu assert(loadRegs <= 2); 6567639Sgblack@eecs.umich.edu switch (size) { 6577639Sgblack@eecs.umich.edu case 0: 6587639Sgblack@eecs.umich.edu if (all) { 6597639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroUnpackAllNeon2to4Uop<uint8_t>( 6607639Sgblack@eecs.umich.edu machInst, vd * 2, ufp0, inc * 2); 6617639Sgblack@eecs.umich.edu } else { 6627639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroUnpackNeon2to4Uop<uint8_t>( 6637639Sgblack@eecs.umich.edu machInst, vd * 2, ufp0, inc * 2, lane); 6647639Sgblack@eecs.umich.edu } 6657639Sgblack@eecs.umich.edu break; 6667639Sgblack@eecs.umich.edu case 1: 6677639Sgblack@eecs.umich.edu if (all) { 6687639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroUnpackAllNeon2to4Uop<uint16_t>( 6697639Sgblack@eecs.umich.edu machInst, vd * 2, ufp0, inc * 2); 6707639Sgblack@eecs.umich.edu } else { 6717639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroUnpackNeon2to4Uop<uint16_t>( 6727639Sgblack@eecs.umich.edu machInst, vd * 2, ufp0, inc * 2, lane); 6737639Sgblack@eecs.umich.edu } 6747639Sgblack@eecs.umich.edu break; 6757639Sgblack@eecs.umich.edu case 2: 6767639Sgblack@eecs.umich.edu if (all) { 6777639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroUnpackAllNeon2to4Uop<uint32_t>( 6787639Sgblack@eecs.umich.edu machInst, vd * 2, ufp0, inc * 2); 6797639Sgblack@eecs.umich.edu } else { 6807639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroUnpackNeon2to4Uop<uint32_t>( 6817639Sgblack@eecs.umich.edu machInst, vd * 2, ufp0, inc * 2, lane); 6827639Sgblack@eecs.umich.edu } 6837639Sgblack@eecs.umich.edu break; 6847639Sgblack@eecs.umich.edu default: 6857853SMatt.Horsnell@ARM.com // Bad size 6867853SMatt.Horsnell@ARM.com microOps[uopIdx++] = new Unknown(machInst); 6877639Sgblack@eecs.umich.edu break; 6887639Sgblack@eecs.umich.edu } 6897639Sgblack@eecs.umich.edu break; 6907639Sgblack@eecs.umich.edu case 1: 6917639Sgblack@eecs.umich.edu assert(regs == 1 || (all && regs == 2)); 6927639Sgblack@eecs.umich.edu assert(loadRegs <= 2); 6937639Sgblack@eecs.umich.edu for (unsigned offset = 0; offset < regs; offset++) { 6947639Sgblack@eecs.umich.edu switch (size) { 6957639Sgblack@eecs.umich.edu case 0: 6967639Sgblack@eecs.umich.edu if (all) { 6977639Sgblack@eecs.umich.edu microOps[uopIdx++] = 6987639Sgblack@eecs.umich.edu new MicroUnpackAllNeon2to2Uop<uint8_t>( 6997639Sgblack@eecs.umich.edu machInst, (vd + offset) * 2, ufp0, inc * 2); 7007639Sgblack@eecs.umich.edu } else { 7017639Sgblack@eecs.umich.edu microOps[uopIdx++] = 7027639Sgblack@eecs.umich.edu new MicroUnpackNeon2to2Uop<uint8_t>( 7037639Sgblack@eecs.umich.edu machInst, (vd + offset) * 2, ufp0, inc * 2, lane); 7047639Sgblack@eecs.umich.edu } 7057639Sgblack@eecs.umich.edu break; 7067639Sgblack@eecs.umich.edu case 1: 7077639Sgblack@eecs.umich.edu if (all) { 7087639Sgblack@eecs.umich.edu microOps[uopIdx++] = 7097639Sgblack@eecs.umich.edu new MicroUnpackAllNeon2to2Uop<uint16_t>( 7107639Sgblack@eecs.umich.edu machInst, (vd + offset) * 2, ufp0, inc * 2); 7117639Sgblack@eecs.umich.edu } else { 7127639Sgblack@eecs.umich.edu microOps[uopIdx++] = 7137639Sgblack@eecs.umich.edu new MicroUnpackNeon2to2Uop<uint16_t>( 7147639Sgblack@eecs.umich.edu machInst, (vd + offset) * 2, ufp0, inc * 2, lane); 7157639Sgblack@eecs.umich.edu } 7167639Sgblack@eecs.umich.edu break; 7177639Sgblack@eecs.umich.edu case 2: 7187639Sgblack@eecs.umich.edu if (all) { 7197639Sgblack@eecs.umich.edu microOps[uopIdx++] = 7207639Sgblack@eecs.umich.edu new MicroUnpackAllNeon2to2Uop<uint32_t>( 7217639Sgblack@eecs.umich.edu machInst, (vd + offset) * 2, ufp0, inc * 2); 7227639Sgblack@eecs.umich.edu } else { 7237639Sgblack@eecs.umich.edu microOps[uopIdx++] = 7247639Sgblack@eecs.umich.edu new MicroUnpackNeon2to2Uop<uint32_t>( 7257639Sgblack@eecs.umich.edu machInst, (vd + offset) * 2, ufp0, inc * 2, lane); 7267639Sgblack@eecs.umich.edu } 7277639Sgblack@eecs.umich.edu break; 7287639Sgblack@eecs.umich.edu default: 7297853SMatt.Horsnell@ARM.com // Bad size 7307853SMatt.Horsnell@ARM.com microOps[uopIdx++] = new Unknown(machInst); 7317639Sgblack@eecs.umich.edu break; 7327639Sgblack@eecs.umich.edu } 7337639Sgblack@eecs.umich.edu } 7347639Sgblack@eecs.umich.edu break; 7357639Sgblack@eecs.umich.edu default: 7367853SMatt.Horsnell@ARM.com // Bad number of elements to unpack 7377853SMatt.Horsnell@ARM.com microOps[uopIdx++] = new Unknown(machInst); 7387639Sgblack@eecs.umich.edu } 7397639Sgblack@eecs.umich.edu assert(uopIdx == numMicroops); 7407639Sgblack@eecs.umich.edu 7417639Sgblack@eecs.umich.edu for (unsigned i = 0; i < numMicroops - 1; i++) { 7427639Sgblack@eecs.umich.edu MicroOp * uopPtr = dynamic_cast<MicroOp *>(microOps[i].get()); 7437639Sgblack@eecs.umich.edu assert(uopPtr); 7447639Sgblack@eecs.umich.edu uopPtr->setDelayedCommit(); 7457639Sgblack@eecs.umich.edu } 7467639Sgblack@eecs.umich.edu microOps[numMicroops - 1]->setLastMicroop(); 7477639Sgblack@eecs.umich.edu} 7487639Sgblack@eecs.umich.edu 7497639Sgblack@eecs.umich.eduVstMultOp::VstMultOp(const char *mnem, ExtMachInst machInst, OpClass __opClass, 7507639Sgblack@eecs.umich.edu unsigned elems, RegIndex rn, RegIndex vd, unsigned regs, 7517639Sgblack@eecs.umich.edu unsigned inc, uint32_t size, uint32_t align, RegIndex rm) : 7527639Sgblack@eecs.umich.edu PredMacroOp(mnem, machInst, __opClass) 7537639Sgblack@eecs.umich.edu{ 7547639Sgblack@eecs.umich.edu assert(regs > 0 && regs <= 4); 7557639Sgblack@eecs.umich.edu assert(regs % elems == 0); 7567639Sgblack@eecs.umich.edu 7577639Sgblack@eecs.umich.edu numMicroops = (regs > 2) ? 2 : 1; 7587639Sgblack@eecs.umich.edu bool wb = (rm != 15); 7597639Sgblack@eecs.umich.edu bool interleave = (elems > 1); 7607639Sgblack@eecs.umich.edu 7617639Sgblack@eecs.umich.edu if (wb) numMicroops++; 7627639Sgblack@eecs.umich.edu if (interleave) numMicroops += (regs / elems); 7637639Sgblack@eecs.umich.edu microOps = new StaticInstPtr[numMicroops]; 7647639Sgblack@eecs.umich.edu 7657639Sgblack@eecs.umich.edu uint32_t noAlign = TLB::MustBeOne; 7667639Sgblack@eecs.umich.edu 76710037SARM gem5 Developers RegIndex rMid = interleave ? NumFloatV7ArchRegs : vd * 2; 7687639Sgblack@eecs.umich.edu 7697639Sgblack@eecs.umich.edu unsigned uopIdx = 0; 7707639Sgblack@eecs.umich.edu if (interleave) { 7717639Sgblack@eecs.umich.edu switch (elems) { 7727639Sgblack@eecs.umich.edu case 4: 7737639Sgblack@eecs.umich.edu assert(regs == 4); 7747639Sgblack@eecs.umich.edu microOps[uopIdx++] = newNeonMixInst<MicroInterNeon8Uop>( 7757639Sgblack@eecs.umich.edu size, machInst, rMid, vd * 2, inc * 2); 7767639Sgblack@eecs.umich.edu break; 7777639Sgblack@eecs.umich.edu case 3: 7787639Sgblack@eecs.umich.edu assert(regs == 3); 7797639Sgblack@eecs.umich.edu microOps[uopIdx++] = newNeonMixInst<MicroInterNeon6Uop>( 7807639Sgblack@eecs.umich.edu size, machInst, rMid, vd * 2, inc * 2); 7817639Sgblack@eecs.umich.edu break; 7827639Sgblack@eecs.umich.edu case 2: 7837639Sgblack@eecs.umich.edu assert(regs == 4 || regs == 2); 7847639Sgblack@eecs.umich.edu if (regs == 4) { 7857639Sgblack@eecs.umich.edu microOps[uopIdx++] = newNeonMixInst<MicroInterNeon4Uop>( 7867639Sgblack@eecs.umich.edu size, machInst, rMid, vd * 2, inc * 2); 7877639Sgblack@eecs.umich.edu microOps[uopIdx++] = newNeonMixInst<MicroInterNeon4Uop>( 7887639Sgblack@eecs.umich.edu size, machInst, rMid + 4, vd * 2 + 2, inc * 2); 7897639Sgblack@eecs.umich.edu } else { 7907639Sgblack@eecs.umich.edu microOps[uopIdx++] = newNeonMixInst<MicroInterNeon4Uop>( 7917639Sgblack@eecs.umich.edu size, machInst, rMid, vd * 2, inc * 2); 7927639Sgblack@eecs.umich.edu } 7937639Sgblack@eecs.umich.edu break; 7947639Sgblack@eecs.umich.edu default: 7957853SMatt.Horsnell@ARM.com // Bad number of elements to interleave 7967853SMatt.Horsnell@ARM.com microOps[uopIdx++] = new Unknown(machInst); 7977639Sgblack@eecs.umich.edu } 7987639Sgblack@eecs.umich.edu } 7997639Sgblack@eecs.umich.edu switch (regs) { 8007639Sgblack@eecs.umich.edu case 4: 8017639Sgblack@eecs.umich.edu microOps[uopIdx++] = newNeonMemInst<MicroStrNeon16Uop>( 8027639Sgblack@eecs.umich.edu size, machInst, rMid, rn, 0, align); 8037639Sgblack@eecs.umich.edu microOps[uopIdx++] = newNeonMemInst<MicroStrNeon16Uop>( 8047639Sgblack@eecs.umich.edu size, machInst, rMid + 4, rn, 16, noAlign); 8057639Sgblack@eecs.umich.edu break; 8067639Sgblack@eecs.umich.edu case 3: 8077639Sgblack@eecs.umich.edu microOps[uopIdx++] = newNeonMemInst<MicroStrNeon16Uop>( 8087639Sgblack@eecs.umich.edu size, machInst, rMid, rn, 0, align); 8097639Sgblack@eecs.umich.edu microOps[uopIdx++] = newNeonMemInst<MicroStrNeon8Uop>( 8107639Sgblack@eecs.umich.edu size, machInst, rMid + 4, rn, 16, noAlign); 8117639Sgblack@eecs.umich.edu break; 8127639Sgblack@eecs.umich.edu case 2: 8137639Sgblack@eecs.umich.edu microOps[uopIdx++] = newNeonMemInst<MicroStrNeon16Uop>( 8147639Sgblack@eecs.umich.edu size, machInst, rMid, rn, 0, align); 8157639Sgblack@eecs.umich.edu break; 8167639Sgblack@eecs.umich.edu case 1: 8177639Sgblack@eecs.umich.edu microOps[uopIdx++] = newNeonMemInst<MicroStrNeon8Uop>( 8187639Sgblack@eecs.umich.edu size, machInst, rMid, rn, 0, align); 8197639Sgblack@eecs.umich.edu break; 8207639Sgblack@eecs.umich.edu default: 8217853SMatt.Horsnell@ARM.com // Unknown number of registers 8227853SMatt.Horsnell@ARM.com microOps[uopIdx++] = new Unknown(machInst); 8237639Sgblack@eecs.umich.edu } 8247639Sgblack@eecs.umich.edu if (wb) { 8257639Sgblack@eecs.umich.edu if (rm != 15 && rm != 13) { 8267639Sgblack@eecs.umich.edu microOps[uopIdx++] = 8277646Sgene.wu@arm.com new MicroAddUop(machInst, rn, rn, rm, 0, ArmISA::LSL); 8287639Sgblack@eecs.umich.edu } else { 8297639Sgblack@eecs.umich.edu microOps[uopIdx++] = 8307639Sgblack@eecs.umich.edu new MicroAddiUop(machInst, rn, rn, regs * 8); 8317639Sgblack@eecs.umich.edu } 8327639Sgblack@eecs.umich.edu } 8337639Sgblack@eecs.umich.edu assert(uopIdx == numMicroops); 8347639Sgblack@eecs.umich.edu 8357639Sgblack@eecs.umich.edu for (unsigned i = 0; i < numMicroops - 1; i++) { 8367639Sgblack@eecs.umich.edu MicroOp * uopPtr = dynamic_cast<MicroOp *>(microOps[i].get()); 8377639Sgblack@eecs.umich.edu assert(uopPtr); 8387639Sgblack@eecs.umich.edu uopPtr->setDelayedCommit(); 8397639Sgblack@eecs.umich.edu } 8407639Sgblack@eecs.umich.edu microOps[numMicroops - 1]->setLastMicroop(); 8417639Sgblack@eecs.umich.edu} 8427639Sgblack@eecs.umich.edu 8437639Sgblack@eecs.umich.eduVstSingleOp::VstSingleOp(const char *mnem, ExtMachInst machInst, 8447639Sgblack@eecs.umich.edu OpClass __opClass, bool all, unsigned elems, 8457639Sgblack@eecs.umich.edu RegIndex rn, RegIndex vd, unsigned regs, 8467639Sgblack@eecs.umich.edu unsigned inc, uint32_t size, uint32_t align, 8477639Sgblack@eecs.umich.edu RegIndex rm, unsigned lane) : 8487639Sgblack@eecs.umich.edu PredMacroOp(mnem, machInst, __opClass) 8497639Sgblack@eecs.umich.edu{ 8507639Sgblack@eecs.umich.edu assert(!all); 8517639Sgblack@eecs.umich.edu assert(regs > 0 && regs <= 4); 8527639Sgblack@eecs.umich.edu assert(regs % elems == 0); 8537639Sgblack@eecs.umich.edu 8547639Sgblack@eecs.umich.edu unsigned eBytes = (1 << size); 8557639Sgblack@eecs.umich.edu unsigned storeSize = eBytes * elems; 8567639Sgblack@eecs.umich.edu unsigned storeRegs M5_VAR_USED = (storeSize + sizeof(FloatRegBits) - 1) / 8577639Sgblack@eecs.umich.edu sizeof(FloatRegBits); 8587639Sgblack@eecs.umich.edu 8597639Sgblack@eecs.umich.edu assert(storeRegs > 0 && storeRegs <= 4); 8607639Sgblack@eecs.umich.edu 8617639Sgblack@eecs.umich.edu numMicroops = 1; 8627639Sgblack@eecs.umich.edu bool wb = (rm != 15); 8637639Sgblack@eecs.umich.edu 8647639Sgblack@eecs.umich.edu if (wb) numMicroops++; 8657639Sgblack@eecs.umich.edu numMicroops += (regs / elems); 8667639Sgblack@eecs.umich.edu microOps = new StaticInstPtr[numMicroops]; 8677639Sgblack@eecs.umich.edu 86810037SARM gem5 Developers RegIndex ufp0 = NumFloatV7ArchRegs; 8697639Sgblack@eecs.umich.edu 8707639Sgblack@eecs.umich.edu unsigned uopIdx = 0; 8717639Sgblack@eecs.umich.edu switch (elems) { 8727639Sgblack@eecs.umich.edu case 4: 8737639Sgblack@eecs.umich.edu assert(regs == 4); 8747639Sgblack@eecs.umich.edu switch (size) { 8757639Sgblack@eecs.umich.edu case 0: 8767639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroPackNeon8to2Uop<uint8_t>( 8777639Sgblack@eecs.umich.edu machInst, ufp0, vd * 2, inc * 2, lane); 8787639Sgblack@eecs.umich.edu break; 8797639Sgblack@eecs.umich.edu case 1: 8807639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroPackNeon8to2Uop<uint16_t>( 8817639Sgblack@eecs.umich.edu machInst, ufp0, vd * 2, inc * 2, lane); 8827639Sgblack@eecs.umich.edu break; 8837639Sgblack@eecs.umich.edu case 2: 8847639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroPackNeon8to4Uop<uint32_t>( 8857639Sgblack@eecs.umich.edu machInst, ufp0, vd * 2, inc * 2, lane); 8867639Sgblack@eecs.umich.edu break; 8877639Sgblack@eecs.umich.edu default: 8887853SMatt.Horsnell@ARM.com // Bad size 8897853SMatt.Horsnell@ARM.com microOps[uopIdx++] = new Unknown(machInst); 8907639Sgblack@eecs.umich.edu break; 8917639Sgblack@eecs.umich.edu } 8927639Sgblack@eecs.umich.edu break; 8937639Sgblack@eecs.umich.edu case 3: 8947639Sgblack@eecs.umich.edu assert(regs == 3); 8957639Sgblack@eecs.umich.edu switch (size) { 8967639Sgblack@eecs.umich.edu case 0: 8977639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroPackNeon6to2Uop<uint8_t>( 8987639Sgblack@eecs.umich.edu machInst, ufp0, vd * 2, inc * 2, lane); 8997639Sgblack@eecs.umich.edu break; 9007639Sgblack@eecs.umich.edu case 1: 9017639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroPackNeon6to2Uop<uint16_t>( 9027639Sgblack@eecs.umich.edu machInst, ufp0, vd * 2, inc * 2, lane); 9037639Sgblack@eecs.umich.edu break; 9047639Sgblack@eecs.umich.edu case 2: 9057639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroPackNeon6to4Uop<uint32_t>( 9067639Sgblack@eecs.umich.edu machInst, ufp0, vd * 2, inc * 2, lane); 9077639Sgblack@eecs.umich.edu break; 9087639Sgblack@eecs.umich.edu default: 9097853SMatt.Horsnell@ARM.com // Bad size 9107853SMatt.Horsnell@ARM.com microOps[uopIdx++] = new Unknown(machInst); 9117639Sgblack@eecs.umich.edu break; 9127639Sgblack@eecs.umich.edu } 9137639Sgblack@eecs.umich.edu break; 9147639Sgblack@eecs.umich.edu case 2: 9157639Sgblack@eecs.umich.edu assert(regs == 2); 9167639Sgblack@eecs.umich.edu assert(storeRegs <= 2); 9177639Sgblack@eecs.umich.edu switch (size) { 9187639Sgblack@eecs.umich.edu case 0: 9197639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroPackNeon4to2Uop<uint8_t>( 9207639Sgblack@eecs.umich.edu machInst, ufp0, vd * 2, inc * 2, lane); 9217639Sgblack@eecs.umich.edu break; 9227639Sgblack@eecs.umich.edu case 1: 9237639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroPackNeon4to2Uop<uint16_t>( 9247639Sgblack@eecs.umich.edu machInst, ufp0, vd * 2, inc * 2, lane); 9257639Sgblack@eecs.umich.edu break; 9267639Sgblack@eecs.umich.edu case 2: 9277639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroPackNeon4to2Uop<uint32_t>( 9287639Sgblack@eecs.umich.edu machInst, ufp0, vd * 2, inc * 2, lane); 9297639Sgblack@eecs.umich.edu break; 9307639Sgblack@eecs.umich.edu default: 9317853SMatt.Horsnell@ARM.com // Bad size 9327853SMatt.Horsnell@ARM.com microOps[uopIdx++] = new Unknown(machInst); 9337639Sgblack@eecs.umich.edu break; 9347639Sgblack@eecs.umich.edu } 9357639Sgblack@eecs.umich.edu break; 9367639Sgblack@eecs.umich.edu case 1: 9377639Sgblack@eecs.umich.edu assert(regs == 1 || (all && regs == 2)); 9387639Sgblack@eecs.umich.edu assert(storeRegs <= 2); 9397639Sgblack@eecs.umich.edu for (unsigned offset = 0; offset < regs; offset++) { 9407639Sgblack@eecs.umich.edu switch (size) { 9417639Sgblack@eecs.umich.edu case 0: 9427639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroPackNeon2to2Uop<uint8_t>( 9437639Sgblack@eecs.umich.edu machInst, ufp0, (vd + offset) * 2, inc * 2, lane); 9447639Sgblack@eecs.umich.edu break; 9457639Sgblack@eecs.umich.edu case 1: 9467639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroPackNeon2to2Uop<uint16_t>( 9477639Sgblack@eecs.umich.edu machInst, ufp0, (vd + offset) * 2, inc * 2, lane); 9487639Sgblack@eecs.umich.edu break; 9497639Sgblack@eecs.umich.edu case 2: 9507639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroPackNeon2to2Uop<uint32_t>( 9517639Sgblack@eecs.umich.edu machInst, ufp0, (vd + offset) * 2, inc * 2, lane); 9527639Sgblack@eecs.umich.edu break; 9537639Sgblack@eecs.umich.edu default: 9547853SMatt.Horsnell@ARM.com // Bad size 9557853SMatt.Horsnell@ARM.com microOps[uopIdx++] = new Unknown(machInst); 9567639Sgblack@eecs.umich.edu break; 9577639Sgblack@eecs.umich.edu } 9587639Sgblack@eecs.umich.edu } 9597639Sgblack@eecs.umich.edu break; 9607639Sgblack@eecs.umich.edu default: 9617853SMatt.Horsnell@ARM.com // Bad number of elements to unpack 9627853SMatt.Horsnell@ARM.com microOps[uopIdx++] = new Unknown(machInst); 9637639Sgblack@eecs.umich.edu } 9647639Sgblack@eecs.umich.edu switch (storeSize) { 9657639Sgblack@eecs.umich.edu case 1: 9667639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroStrNeon1Uop<uint8_t>( 9677639Sgblack@eecs.umich.edu machInst, ufp0, rn, 0, align); 9687639Sgblack@eecs.umich.edu break; 9697639Sgblack@eecs.umich.edu case 2: 9707639Sgblack@eecs.umich.edu if (eBytes == 2) { 9717639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroStrNeon2Uop<uint16_t>( 9727639Sgblack@eecs.umich.edu machInst, ufp0, rn, 0, align); 9737639Sgblack@eecs.umich.edu } else { 9747639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroStrNeon2Uop<uint8_t>( 9757639Sgblack@eecs.umich.edu machInst, ufp0, rn, 0, align); 9767639Sgblack@eecs.umich.edu } 9777639Sgblack@eecs.umich.edu break; 9787639Sgblack@eecs.umich.edu case 3: 9797639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroStrNeon3Uop<uint8_t>( 9807639Sgblack@eecs.umich.edu machInst, ufp0, rn, 0, align); 9817639Sgblack@eecs.umich.edu break; 9827639Sgblack@eecs.umich.edu case 4: 9837639Sgblack@eecs.umich.edu switch (eBytes) { 9847639Sgblack@eecs.umich.edu case 1: 9857639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroStrNeon4Uop<uint8_t>( 9867639Sgblack@eecs.umich.edu machInst, ufp0, rn, 0, align); 9877639Sgblack@eecs.umich.edu break; 9887639Sgblack@eecs.umich.edu case 2: 9897639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroStrNeon4Uop<uint16_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 microOps[uopIdx++] = new MicroStrNeon4Uop<uint32_t>( 9947639Sgblack@eecs.umich.edu machInst, ufp0, rn, 0, align); 9957639Sgblack@eecs.umich.edu break; 9967639Sgblack@eecs.umich.edu } 9977639Sgblack@eecs.umich.edu break; 9987639Sgblack@eecs.umich.edu case 6: 9997639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroStrNeon6Uop<uint16_t>( 10007639Sgblack@eecs.umich.edu machInst, ufp0, rn, 0, align); 10017639Sgblack@eecs.umich.edu break; 10027639Sgblack@eecs.umich.edu case 8: 10037639Sgblack@eecs.umich.edu switch (eBytes) { 10047639Sgblack@eecs.umich.edu case 2: 10057639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroStrNeon8Uop<uint16_t>( 10067639Sgblack@eecs.umich.edu machInst, ufp0, rn, 0, align); 10077639Sgblack@eecs.umich.edu break; 10087639Sgblack@eecs.umich.edu case 4: 10097639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroStrNeon8Uop<uint32_t>( 10107639Sgblack@eecs.umich.edu machInst, ufp0, rn, 0, align); 10117639Sgblack@eecs.umich.edu break; 10127639Sgblack@eecs.umich.edu } 10137639Sgblack@eecs.umich.edu break; 10147639Sgblack@eecs.umich.edu case 12: 10157639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroStrNeon12Uop<uint32_t>( 10167639Sgblack@eecs.umich.edu machInst, ufp0, rn, 0, align); 10177639Sgblack@eecs.umich.edu break; 10187639Sgblack@eecs.umich.edu case 16: 10197639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroStrNeon16Uop<uint32_t>( 10207639Sgblack@eecs.umich.edu machInst, ufp0, rn, 0, align); 10217639Sgblack@eecs.umich.edu break; 10227639Sgblack@eecs.umich.edu default: 10237853SMatt.Horsnell@ARM.com // Bad store size 10247853SMatt.Horsnell@ARM.com microOps[uopIdx++] = new Unknown(machInst); 10257639Sgblack@eecs.umich.edu } 10267639Sgblack@eecs.umich.edu if (wb) { 10277639Sgblack@eecs.umich.edu if (rm != 15 && rm != 13) { 10287639Sgblack@eecs.umich.edu microOps[uopIdx++] = 10297646Sgene.wu@arm.com new MicroAddUop(machInst, rn, rn, rm, 0, ArmISA::LSL); 10307639Sgblack@eecs.umich.edu } else { 10317639Sgblack@eecs.umich.edu microOps[uopIdx++] = 10327639Sgblack@eecs.umich.edu new MicroAddiUop(machInst, rn, rn, storeSize); 10337639Sgblack@eecs.umich.edu } 10347639Sgblack@eecs.umich.edu } 10357639Sgblack@eecs.umich.edu assert(uopIdx == numMicroops); 10367639Sgblack@eecs.umich.edu 10377639Sgblack@eecs.umich.edu for (unsigned i = 0; i < numMicroops - 1; i++) { 10387639Sgblack@eecs.umich.edu MicroOp * uopPtr = dynamic_cast<MicroOp *>(microOps[i].get()); 10397639Sgblack@eecs.umich.edu assert(uopPtr); 10407639Sgblack@eecs.umich.edu uopPtr->setDelayedCommit(); 10417639Sgblack@eecs.umich.edu } 10427639Sgblack@eecs.umich.edu microOps[numMicroops - 1]->setLastMicroop(); 10437639Sgblack@eecs.umich.edu} 10447639Sgblack@eecs.umich.edu 104510037SARM gem5 DevelopersVldMultOp64::VldMultOp64(const char *mnem, ExtMachInst machInst, 104610037SARM gem5 Developers OpClass __opClass, RegIndex rn, RegIndex vd, 104710037SARM gem5 Developers RegIndex rm, uint8_t eSize, uint8_t dataSize, 104810037SARM gem5 Developers uint8_t numStructElems, uint8_t numRegs, bool wb) : 104910037SARM gem5 Developers PredMacroOp(mnem, machInst, __opClass) 105010037SARM gem5 Developers{ 105110037SARM gem5 Developers RegIndex vx = NumFloatV8ArchRegs / 4; 105210037SARM gem5 Developers RegIndex rnsp = (RegIndex) makeSP((IntRegIndex) rn); 105310037SARM gem5 Developers bool baseIsSP = isSP((IntRegIndex) rnsp); 105410037SARM gem5 Developers 105510037SARM gem5 Developers numMicroops = wb ? 1 : 0; 105610037SARM gem5 Developers 105710037SARM gem5 Developers int totNumBytes = numRegs * dataSize / 8; 105810037SARM gem5 Developers assert(totNumBytes <= 64); 105910037SARM gem5 Developers 106010037SARM gem5 Developers // The guiding principle here is that no more than 16 bytes can be 106110037SARM gem5 Developers // transferred at a time 106210037SARM gem5 Developers int numMemMicroops = totNumBytes / 16; 106310037SARM gem5 Developers int residuum = totNumBytes % 16; 106410037SARM gem5 Developers if (residuum) 106510037SARM gem5 Developers ++numMemMicroops; 106610037SARM gem5 Developers numMicroops += numMemMicroops; 106710037SARM gem5 Developers 106810037SARM gem5 Developers int numMarshalMicroops = numRegs / 2 + (numRegs % 2 ? 1 : 0); 106910037SARM gem5 Developers numMicroops += numMarshalMicroops; 107010037SARM gem5 Developers 107110037SARM gem5 Developers microOps = new StaticInstPtr[numMicroops]; 107210037SARM gem5 Developers unsigned uopIdx = 0; 107310037SARM gem5 Developers uint32_t memaccessFlags = TLB::MustBeOne | (TLB::ArmFlags) eSize | 107410037SARM gem5 Developers TLB::AllowUnaligned; 107510037SARM gem5 Developers 107610037SARM gem5 Developers int i = 0; 107710037SARM gem5 Developers for(; i < numMemMicroops - 1; ++i) { 107810037SARM gem5 Developers microOps[uopIdx++] = new MicroNeonLoad64( 107910037SARM gem5 Developers machInst, vx + (RegIndex) i, rnsp, 16 * i, memaccessFlags, 108010037SARM gem5 Developers baseIsSP, 16 /* accSize */, eSize); 108110037SARM gem5 Developers } 108210037SARM gem5 Developers microOps[uopIdx++] = new MicroNeonLoad64( 108310037SARM gem5 Developers machInst, vx + (RegIndex) i, rnsp, 16 * i, memaccessFlags, baseIsSP, 108410037SARM gem5 Developers residuum ? residuum : 16 /* accSize */, eSize); 108510037SARM gem5 Developers 108610037SARM gem5 Developers // Writeback microop: the post-increment amount is encoded in "Rm": a 108710037SARM gem5 Developers // 64-bit general register OR as '11111' for an immediate value equal to 108810037SARM gem5 Developers // the total number of bytes transferred (i.e. 8, 16, 24, 32, 48 or 64) 108910037SARM gem5 Developers if (wb) { 109010037SARM gem5 Developers if (rm != ((RegIndex) INTREG_X31)) { 109110037SARM gem5 Developers microOps[uopIdx++] = new MicroAddXERegUop(machInst, rnsp, rnsp, rm, 109210037SARM gem5 Developers UXTX, 0); 109310037SARM gem5 Developers } else { 109410037SARM gem5 Developers microOps[uopIdx++] = new MicroAddXiUop(machInst, rnsp, rnsp, 109510037SARM gem5 Developers totNumBytes); 109610037SARM gem5 Developers } 109710037SARM gem5 Developers } 109810037SARM gem5 Developers 109910037SARM gem5 Developers for (int i = 0; i < numMarshalMicroops; ++i) { 110010037SARM gem5 Developers microOps[uopIdx++] = new MicroDeintNeon64( 110110037SARM gem5 Developers machInst, vd + (RegIndex) (2 * i), vx, eSize, dataSize, 110210037SARM gem5 Developers numStructElems, numRegs, i /* step */); 110310037SARM gem5 Developers } 110410037SARM gem5 Developers 110510037SARM gem5 Developers assert(uopIdx == numMicroops); 110610037SARM gem5 Developers 110710037SARM gem5 Developers for (int i = 0; i < numMicroops - 1; ++i) { 110810037SARM gem5 Developers microOps[i]->setDelayedCommit(); 110910037SARM gem5 Developers } 111010037SARM gem5 Developers microOps[numMicroops - 1]->setLastMicroop(); 111110037SARM gem5 Developers} 111210037SARM gem5 Developers 111310037SARM gem5 DevelopersVstMultOp64::VstMultOp64(const char *mnem, ExtMachInst machInst, 111410037SARM gem5 Developers OpClass __opClass, RegIndex rn, RegIndex vd, 111510037SARM gem5 Developers RegIndex rm, uint8_t eSize, uint8_t dataSize, 111610037SARM gem5 Developers uint8_t numStructElems, uint8_t numRegs, bool wb) : 111710037SARM gem5 Developers PredMacroOp(mnem, machInst, __opClass) 111810037SARM gem5 Developers{ 111910037SARM gem5 Developers RegIndex vx = NumFloatV8ArchRegs / 4; 112010037SARM gem5 Developers RegIndex rnsp = (RegIndex) makeSP((IntRegIndex) rn); 112110037SARM gem5 Developers bool baseIsSP = isSP((IntRegIndex) rnsp); 112210037SARM gem5 Developers 112310037SARM gem5 Developers numMicroops = wb ? 1 : 0; 112410037SARM gem5 Developers 112510037SARM gem5 Developers int totNumBytes = numRegs * dataSize / 8; 112610037SARM gem5 Developers assert(totNumBytes <= 64); 112710037SARM gem5 Developers 112810037SARM gem5 Developers // The guiding principle here is that no more than 16 bytes can be 112910037SARM gem5 Developers // transferred at a time 113010037SARM gem5 Developers int numMemMicroops = totNumBytes / 16; 113110037SARM gem5 Developers int residuum = totNumBytes % 16; 113210037SARM gem5 Developers if (residuum) 113310037SARM gem5 Developers ++numMemMicroops; 113410037SARM gem5 Developers numMicroops += numMemMicroops; 113510037SARM gem5 Developers 113610037SARM gem5 Developers int numMarshalMicroops = totNumBytes > 32 ? 2 : 1; 113710037SARM gem5 Developers numMicroops += numMarshalMicroops; 113810037SARM gem5 Developers 113910037SARM gem5 Developers microOps = new StaticInstPtr[numMicroops]; 114010037SARM gem5 Developers unsigned uopIdx = 0; 114110037SARM gem5 Developers 114210037SARM gem5 Developers for(int i = 0; i < numMarshalMicroops; ++i) { 114310037SARM gem5 Developers microOps[uopIdx++] = new MicroIntNeon64( 114410037SARM gem5 Developers machInst, vx + (RegIndex) (2 * i), vd, eSize, dataSize, 114510037SARM gem5 Developers numStructElems, numRegs, i /* step */); 114610037SARM gem5 Developers } 114710037SARM gem5 Developers 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; 115210037SARM gem5 Developers for(; i < numMemMicroops - 1; ++i) { 115310037SARM gem5 Developers microOps[uopIdx++] = new MicroNeonStore64( 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 MicroNeonStore64( 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 assert(uopIdx == numMicroops); 117510037SARM gem5 Developers 117610037SARM gem5 Developers for (int i = 0; i < numMicroops - 1; i++) { 117710037SARM gem5 Developers microOps[i]->setDelayedCommit(); 117810037SARM gem5 Developers } 117910037SARM gem5 Developers microOps[numMicroops - 1]->setLastMicroop(); 118010037SARM gem5 Developers} 118110037SARM gem5 Developers 118210037SARM gem5 DevelopersVldSingleOp64::VldSingleOp64(const char *mnem, ExtMachInst machInst, 118310037SARM gem5 Developers OpClass __opClass, RegIndex rn, RegIndex vd, 118410037SARM gem5 Developers RegIndex rm, uint8_t eSize, uint8_t dataSize, 118510037SARM gem5 Developers uint8_t numStructElems, uint8_t index, bool wb, 118610037SARM gem5 Developers bool replicate) : 118710037SARM gem5 Developers PredMacroOp(mnem, machInst, __opClass) 118810037SARM gem5 Developers{ 118910037SARM gem5 Developers RegIndex vx = NumFloatV8ArchRegs / 4; 119010037SARM gem5 Developers RegIndex rnsp = (RegIndex) makeSP((IntRegIndex) rn); 119110037SARM gem5 Developers bool baseIsSP = isSP((IntRegIndex) rnsp); 119210037SARM gem5 Developers 119310037SARM gem5 Developers numMicroops = wb ? 1 : 0; 119410037SARM gem5 Developers 119510037SARM gem5 Developers int eSizeBytes = 1 << eSize; 119610037SARM gem5 Developers int totNumBytes = numStructElems * eSizeBytes; 119710037SARM gem5 Developers assert(totNumBytes <= 64); 119810037SARM gem5 Developers 119910037SARM gem5 Developers // The guiding principle here is that no more than 16 bytes can be 120010037SARM gem5 Developers // transferred at a time 120110037SARM gem5 Developers int numMemMicroops = totNumBytes / 16; 120210037SARM gem5 Developers int residuum = totNumBytes % 16; 120310037SARM gem5 Developers if (residuum) 120410037SARM gem5 Developers ++numMemMicroops; 120510037SARM gem5 Developers numMicroops += numMemMicroops; 120610037SARM gem5 Developers 120710037SARM gem5 Developers int numMarshalMicroops = numStructElems / 2 + (numStructElems % 2 ? 1 : 0); 120810037SARM gem5 Developers numMicroops += numMarshalMicroops; 120910037SARM gem5 Developers 121010037SARM gem5 Developers microOps = new StaticInstPtr[numMicroops]; 121110037SARM gem5 Developers unsigned uopIdx = 0; 121210037SARM gem5 Developers 121310037SARM gem5 Developers uint32_t memaccessFlags = TLB::MustBeOne | (TLB::ArmFlags) eSize | 121410037SARM gem5 Developers TLB::AllowUnaligned; 121510037SARM gem5 Developers 121610037SARM gem5 Developers int i = 0; 121710037SARM gem5 Developers for (; i < numMemMicroops - 1; ++i) { 121810037SARM gem5 Developers microOps[uopIdx++] = new MicroNeonLoad64( 121910037SARM gem5 Developers machInst, vx + (RegIndex) i, rnsp, 16 * i, memaccessFlags, 122010037SARM gem5 Developers baseIsSP, 16 /* accSize */, eSize); 122110037SARM gem5 Developers } 122210037SARM gem5 Developers microOps[uopIdx++] = new MicroNeonLoad64( 122310037SARM gem5 Developers machInst, vx + (RegIndex) i, rnsp, 16 * i, memaccessFlags, baseIsSP, 122410037SARM gem5 Developers residuum ? residuum : 16 /* accSize */, eSize); 122510037SARM gem5 Developers 122610037SARM gem5 Developers // Writeback microop: the post-increment amount is encoded in "Rm": a 122710037SARM gem5 Developers // 64-bit general register OR as '11111' for an immediate value equal to 122810037SARM gem5 Developers // the total number of bytes transferred (i.e. 8, 16, 24, 32, 48 or 64) 122910037SARM gem5 Developers if (wb) { 123010037SARM gem5 Developers if (rm != ((RegIndex) INTREG_X31)) { 123110037SARM gem5 Developers microOps[uopIdx++] = new MicroAddXERegUop(machInst, rnsp, rnsp, rm, 123210037SARM gem5 Developers UXTX, 0); 123310037SARM gem5 Developers } else { 123410037SARM gem5 Developers microOps[uopIdx++] = new MicroAddXiUop(machInst, rnsp, rnsp, 123510037SARM gem5 Developers totNumBytes); 123610037SARM gem5 Developers } 123710037SARM gem5 Developers } 123810037SARM gem5 Developers 123910037SARM gem5 Developers for(int i = 0; i < numMarshalMicroops; ++i) { 124010037SARM gem5 Developers microOps[uopIdx++] = new MicroUnpackNeon64( 124110037SARM gem5 Developers machInst, vd + (RegIndex) (2 * i), vx, eSize, dataSize, 124210037SARM gem5 Developers numStructElems, index, i /* step */, replicate); 124310037SARM gem5 Developers } 124410037SARM gem5 Developers 124510037SARM gem5 Developers assert(uopIdx == numMicroops); 124610037SARM gem5 Developers 124710037SARM gem5 Developers for (int i = 0; i < numMicroops - 1; i++) { 124810037SARM gem5 Developers microOps[i]->setDelayedCommit(); 124910037SARM gem5 Developers } 125010037SARM gem5 Developers microOps[numMicroops - 1]->setLastMicroop(); 125110037SARM gem5 Developers} 125210037SARM gem5 Developers 125310037SARM gem5 DevelopersVstSingleOp64::VstSingleOp64(const char *mnem, ExtMachInst machInst, 125410037SARM gem5 Developers OpClass __opClass, RegIndex rn, RegIndex vd, 125510037SARM gem5 Developers RegIndex rm, uint8_t eSize, uint8_t dataSize, 125610037SARM gem5 Developers uint8_t numStructElems, uint8_t index, bool wb, 125710037SARM gem5 Developers bool replicate) : 125810037SARM gem5 Developers PredMacroOp(mnem, machInst, __opClass) 125910037SARM gem5 Developers{ 126010037SARM gem5 Developers RegIndex vx = NumFloatV8ArchRegs / 4; 126110037SARM gem5 Developers RegIndex rnsp = (RegIndex) makeSP((IntRegIndex) rn); 126210037SARM gem5 Developers bool baseIsSP = isSP((IntRegIndex) rnsp); 126310037SARM gem5 Developers 126410037SARM gem5 Developers numMicroops = wb ? 1 : 0; 126510037SARM gem5 Developers 126610037SARM gem5 Developers int eSizeBytes = 1 << eSize; 126710037SARM gem5 Developers int totNumBytes = numStructElems * eSizeBytes; 126810037SARM gem5 Developers assert(totNumBytes <= 64); 126910037SARM gem5 Developers 127010037SARM gem5 Developers // The guiding principle here is that no more than 16 bytes can be 127110037SARM gem5 Developers // transferred at a time 127210037SARM gem5 Developers int numMemMicroops = totNumBytes / 16; 127310037SARM gem5 Developers int residuum = totNumBytes % 16; 127410037SARM gem5 Developers if (residuum) 127510037SARM gem5 Developers ++numMemMicroops; 127610037SARM gem5 Developers numMicroops += numMemMicroops; 127710037SARM gem5 Developers 127810037SARM gem5 Developers int numMarshalMicroops = totNumBytes > 32 ? 2 : 1; 127910037SARM gem5 Developers numMicroops += numMarshalMicroops; 128010037SARM gem5 Developers 128110037SARM gem5 Developers microOps = new StaticInstPtr[numMicroops]; 128210037SARM gem5 Developers unsigned uopIdx = 0; 128310037SARM gem5 Developers 128410037SARM gem5 Developers for(int i = 0; i < numMarshalMicroops; ++i) { 128510037SARM gem5 Developers microOps[uopIdx++] = new MicroPackNeon64( 128610037SARM gem5 Developers machInst, vx + (RegIndex) (2 * i), vd, eSize, dataSize, 128710037SARM gem5 Developers numStructElems, index, i /* step */, replicate); 128810037SARM gem5 Developers } 128910037SARM gem5 Developers 129010037SARM gem5 Developers uint32_t memaccessFlags = TLB::MustBeOne | (TLB::ArmFlags) eSize | 129110037SARM gem5 Developers TLB::AllowUnaligned; 129210037SARM gem5 Developers 129310037SARM gem5 Developers int i = 0; 129410037SARM gem5 Developers for(; i < numMemMicroops - 1; ++i) { 129510037SARM gem5 Developers microOps[uopIdx++] = new MicroNeonStore64( 129610037SARM gem5 Developers machInst, vx + (RegIndex) i, rnsp, 16 * i, memaccessFlags, 129710037SARM gem5 Developers baseIsSP, 16 /* accsize */, eSize); 129810037SARM gem5 Developers } 129910037SARM gem5 Developers microOps[uopIdx++] = new MicroNeonStore64( 130010037SARM gem5 Developers machInst, vx + (RegIndex) i, rnsp, 16 * i, memaccessFlags, baseIsSP, 130110037SARM gem5 Developers residuum ? residuum : 16 /* accSize */, eSize); 130210037SARM gem5 Developers 130310037SARM gem5 Developers // Writeback microop: the post-increment amount is encoded in "Rm": a 130410037SARM gem5 Developers // 64-bit general register OR as '11111' for an immediate value equal to 130510037SARM gem5 Developers // the total number of bytes transferred (i.e. 8, 16, 24, 32, 48 or 64) 130610037SARM gem5 Developers if (wb) { 130710037SARM gem5 Developers if (rm != ((RegIndex) INTREG_X31)) { 130810037SARM gem5 Developers microOps[uopIdx++] = new MicroAddXERegUop(machInst, rnsp, rnsp, rm, 130910037SARM gem5 Developers UXTX, 0); 131010037SARM gem5 Developers } else { 131110037SARM gem5 Developers microOps[uopIdx++] = new MicroAddXiUop(machInst, rnsp, rnsp, 131210037SARM gem5 Developers totNumBytes); 131310037SARM gem5 Developers } 131410037SARM gem5 Developers } 131510037SARM gem5 Developers 131610037SARM gem5 Developers assert(uopIdx == numMicroops); 131710037SARM gem5 Developers 131810037SARM gem5 Developers for (int i = 0; i < numMicroops - 1; i++) { 131910037SARM gem5 Developers microOps[i]->setDelayedCommit(); 132010037SARM gem5 Developers } 132110037SARM gem5 Developers microOps[numMicroops - 1]->setLastMicroop(); 132210037SARM gem5 Developers} 132310037SARM gem5 Developers 13247175Sgblack@eecs.umich.eduMacroVFPMemOp::MacroVFPMemOp(const char *mnem, ExtMachInst machInst, 13257175Sgblack@eecs.umich.edu OpClass __opClass, IntRegIndex rn, 13267175Sgblack@eecs.umich.edu RegIndex vd, bool single, bool up, 13277175Sgblack@eecs.umich.edu bool writeback, bool load, uint32_t offset) : 13287175Sgblack@eecs.umich.edu PredMacroOp(mnem, machInst, __opClass) 13297175Sgblack@eecs.umich.edu{ 13307175Sgblack@eecs.umich.edu int i = 0; 13317175Sgblack@eecs.umich.edu 13327175Sgblack@eecs.umich.edu // The lowest order bit selects fldmx (set) or fldmd (clear). These seem 13337175Sgblack@eecs.umich.edu // to be functionally identical except that fldmx is deprecated. For now 13347175Sgblack@eecs.umich.edu // we'll assume they're otherwise interchangable. 13357175Sgblack@eecs.umich.edu int count = (single ? offset : (offset / 2)); 133610037SARM gem5 Developers if (count == 0 || count > NumFloatV7ArchRegs) 13377175Sgblack@eecs.umich.edu warn_once("Bad offset field for VFP load/store multiple.\n"); 13387175Sgblack@eecs.umich.edu if (count == 0) { 13397175Sgblack@eecs.umich.edu // Force there to be at least one microop so the macroop makes sense. 13407175Sgblack@eecs.umich.edu writeback = true; 13417175Sgblack@eecs.umich.edu } 134210037SARM gem5 Developers if (count > NumFloatV7ArchRegs) 134310037SARM gem5 Developers count = NumFloatV7ArchRegs; 13447175Sgblack@eecs.umich.edu 13457342Sgblack@eecs.umich.edu numMicroops = count * (single ? 1 : 2) + (writeback ? 1 : 0); 13467342Sgblack@eecs.umich.edu microOps = new StaticInstPtr[numMicroops]; 13477342Sgblack@eecs.umich.edu 13487395Sgblack@eecs.umich.edu int64_t addr = 0; 13497175Sgblack@eecs.umich.edu 13507342Sgblack@eecs.umich.edu if (!up) 13517342Sgblack@eecs.umich.edu addr = 4 * offset; 13527175Sgblack@eecs.umich.edu 13537342Sgblack@eecs.umich.edu bool tempUp = up; 13547175Sgblack@eecs.umich.edu for (int j = 0; j < count; j++) { 13557175Sgblack@eecs.umich.edu if (load) { 13567639Sgblack@eecs.umich.edu if (single) { 13577639Sgblack@eecs.umich.edu microOps[i++] = new MicroLdrFpUop(machInst, vd++, rn, 13587639Sgblack@eecs.umich.edu tempUp, addr); 13597639Sgblack@eecs.umich.edu } else { 13607639Sgblack@eecs.umich.edu microOps[i++] = new MicroLdrDBFpUop(machInst, vd++, rn, 13617639Sgblack@eecs.umich.edu tempUp, addr); 13627639Sgblack@eecs.umich.edu microOps[i++] = new MicroLdrDTFpUop(machInst, vd++, rn, tempUp, 13637639Sgblack@eecs.umich.edu addr + (up ? 4 : -4)); 13647639Sgblack@eecs.umich.edu } 13657175Sgblack@eecs.umich.edu } else { 13667639Sgblack@eecs.umich.edu if (single) { 13677639Sgblack@eecs.umich.edu microOps[i++] = new MicroStrFpUop(machInst, vd++, rn, 13687639Sgblack@eecs.umich.edu tempUp, addr); 13697639Sgblack@eecs.umich.edu } else { 13707639Sgblack@eecs.umich.edu microOps[i++] = new MicroStrDBFpUop(machInst, vd++, rn, 13717639Sgblack@eecs.umich.edu tempUp, addr); 13727639Sgblack@eecs.umich.edu microOps[i++] = new MicroStrDTFpUop(machInst, vd++, rn, tempUp, 13737639Sgblack@eecs.umich.edu addr + (up ? 4 : -4)); 13747639Sgblack@eecs.umich.edu } 13757175Sgblack@eecs.umich.edu } 13767342Sgblack@eecs.umich.edu if (!tempUp) { 13777342Sgblack@eecs.umich.edu addr -= (single ? 4 : 8); 13787342Sgblack@eecs.umich.edu // The microops don't handle negative displacement, so turn if we 13797342Sgblack@eecs.umich.edu // hit zero, flip polarity and start adding. 13807395Sgblack@eecs.umich.edu if (addr <= 0) { 13817342Sgblack@eecs.umich.edu tempUp = true; 13827395Sgblack@eecs.umich.edu addr = -addr; 13837342Sgblack@eecs.umich.edu } 13847342Sgblack@eecs.umich.edu } else { 13857342Sgblack@eecs.umich.edu addr += (single ? 4 : 8); 13867342Sgblack@eecs.umich.edu } 13877175Sgblack@eecs.umich.edu } 13887175Sgblack@eecs.umich.edu 13897175Sgblack@eecs.umich.edu if (writeback) { 13907175Sgblack@eecs.umich.edu if (up) { 13917175Sgblack@eecs.umich.edu microOps[i++] = 13927175Sgblack@eecs.umich.edu new MicroAddiUop(machInst, rn, rn, 4 * offset); 13937175Sgblack@eecs.umich.edu } else { 13947175Sgblack@eecs.umich.edu microOps[i++] = 13957175Sgblack@eecs.umich.edu new MicroSubiUop(machInst, rn, rn, 4 * offset); 13967175Sgblack@eecs.umich.edu } 13977175Sgblack@eecs.umich.edu } 13987175Sgblack@eecs.umich.edu 13997342Sgblack@eecs.umich.edu assert(numMicroops == i); 14007175Sgblack@eecs.umich.edu microOps[numMicroops - 1]->setLastMicroop(); 14017343Sgblack@eecs.umich.edu 14027343Sgblack@eecs.umich.edu for (StaticInstPtr *curUop = microOps; 14037343Sgblack@eecs.umich.edu !(*curUop)->isLastMicroop(); curUop++) { 14047343Sgblack@eecs.umich.edu MicroOp * uopPtr = dynamic_cast<MicroOp *>(curUop->get()); 14057343Sgblack@eecs.umich.edu assert(uopPtr); 14067343Sgblack@eecs.umich.edu uopPtr->setDelayedCommit(); 14077343Sgblack@eecs.umich.edu } 14087170Sgblack@eecs.umich.edu} 14097175Sgblack@eecs.umich.edu 14107615Sminkyu.jeong@arm.comstd::string 14117639Sgblack@eecs.umich.eduMicroIntImmOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const 14127639Sgblack@eecs.umich.edu{ 14137639Sgblack@eecs.umich.edu std::stringstream ss; 14147639Sgblack@eecs.umich.edu printMnemonic(ss); 14157639Sgblack@eecs.umich.edu printReg(ss, ura); 14167639Sgblack@eecs.umich.edu ss << ", "; 14177639Sgblack@eecs.umich.edu printReg(ss, urb); 14187639Sgblack@eecs.umich.edu ss << ", "; 14197639Sgblack@eecs.umich.edu ccprintf(ss, "#%d", imm); 14207639Sgblack@eecs.umich.edu return ss.str(); 14217639Sgblack@eecs.umich.edu} 14227639Sgblack@eecs.umich.edu 14237639Sgblack@eecs.umich.edustd::string 142410037SARM gem5 DevelopersMicroIntImmXOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const 142510037SARM gem5 Developers{ 142610037SARM gem5 Developers std::stringstream ss; 142710037SARM gem5 Developers printMnemonic(ss); 142810037SARM gem5 Developers printReg(ss, ura); 142910037SARM gem5 Developers ss << ", "; 143010037SARM gem5 Developers printReg(ss, urb); 143110037SARM gem5 Developers ss << ", "; 143210037SARM gem5 Developers ccprintf(ss, "#%d", imm); 143310037SARM gem5 Developers return ss.str(); 143410037SARM gem5 Developers} 143510037SARM gem5 Developers 143610037SARM gem5 Developersstd::string 14378140SMatt.Horsnell@arm.comMicroSetPCCPSR::generateDisassembly(Addr pc, const SymbolTable *symtab) const 14388140SMatt.Horsnell@arm.com{ 14398140SMatt.Horsnell@arm.com std::stringstream ss; 14408140SMatt.Horsnell@arm.com printMnemonic(ss); 14418140SMatt.Horsnell@arm.com ss << "[PC,CPSR]"; 14428140SMatt.Horsnell@arm.com return ss.str(); 14438140SMatt.Horsnell@arm.com} 14448140SMatt.Horsnell@arm.com 14458140SMatt.Horsnell@arm.comstd::string 144610037SARM gem5 DevelopersMicroIntRegXOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const 144710037SARM gem5 Developers{ 144810037SARM gem5 Developers std::stringstream ss; 144910037SARM gem5 Developers printMnemonic(ss); 145010037SARM gem5 Developers printReg(ss, ura); 145110037SARM gem5 Developers ccprintf(ss, ", "); 145210037SARM gem5 Developers printReg(ss, urb); 145310037SARM gem5 Developers printExtendOperand(false, ss, (IntRegIndex)urc, type, shiftAmt); 145410037SARM gem5 Developers return ss.str(); 145510037SARM gem5 Developers} 145610037SARM gem5 Developers 145710037SARM gem5 Developersstd::string 14587646Sgene.wu@arm.comMicroIntMov::generateDisassembly(Addr pc, const SymbolTable *symtab) const 14597646Sgene.wu@arm.com{ 14607646Sgene.wu@arm.com std::stringstream ss; 14617646Sgene.wu@arm.com printMnemonic(ss); 14627646Sgene.wu@arm.com printReg(ss, ura); 14637646Sgene.wu@arm.com ss << ", "; 14647646Sgene.wu@arm.com printReg(ss, urb); 14657646Sgene.wu@arm.com return ss.str(); 14667646Sgene.wu@arm.com} 14677646Sgene.wu@arm.com 14687646Sgene.wu@arm.comstd::string 14697615Sminkyu.jeong@arm.comMicroIntOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const 14707615Sminkyu.jeong@arm.com{ 14717615Sminkyu.jeong@arm.com std::stringstream ss; 14727615Sminkyu.jeong@arm.com printMnemonic(ss); 14737615Sminkyu.jeong@arm.com printReg(ss, ura); 14747615Sminkyu.jeong@arm.com ss << ", "; 14757615Sminkyu.jeong@arm.com printReg(ss, urb); 14767615Sminkyu.jeong@arm.com ss << ", "; 14777639Sgblack@eecs.umich.edu printReg(ss, urc); 14787615Sminkyu.jeong@arm.com return ss.str(); 14797175Sgblack@eecs.umich.edu} 14807615Sminkyu.jeong@arm.com 14817615Sminkyu.jeong@arm.comstd::string 14827615Sminkyu.jeong@arm.comMicroMemOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const 14837615Sminkyu.jeong@arm.com{ 14847615Sminkyu.jeong@arm.com std::stringstream ss; 14857615Sminkyu.jeong@arm.com printMnemonic(ss); 148610180SCurtis.Dunham@arm.com if (isFloating()) 148710180SCurtis.Dunham@arm.com printReg(ss, ura + FP_Reg_Base); 148810180SCurtis.Dunham@arm.com else 148910180SCurtis.Dunham@arm.com printReg(ss, ura); 14907615Sminkyu.jeong@arm.com ss << ", ["; 14917615Sminkyu.jeong@arm.com printReg(ss, urb); 14927615Sminkyu.jeong@arm.com ss << ", "; 14937615Sminkyu.jeong@arm.com ccprintf(ss, "#%d", imm); 14947615Sminkyu.jeong@arm.com ss << "]"; 14957615Sminkyu.jeong@arm.com return ss.str(); 14967615Sminkyu.jeong@arm.com} 14977615Sminkyu.jeong@arm.com 14987615Sminkyu.jeong@arm.com} 1499