macromem.cc revision 9640
17170Sgblack@eecs.umich.edu/* 27170Sgblack@eecs.umich.edu * Copyright (c) 2010 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" 468961Sgblack@eecs.umich.edu#include "arch/arm/generated/decoder.hh" 477170Sgblack@eecs.umich.edu 487853SMatt.Horsnell@ARM.comusing namespace std; 497170Sgblack@eecs.umich.eduusing namespace ArmISAInst; 507170Sgblack@eecs.umich.edu 517170Sgblack@eecs.umich.edunamespace ArmISA 527170Sgblack@eecs.umich.edu{ 537170Sgblack@eecs.umich.edu 547170Sgblack@eecs.umich.eduMacroMemOp::MacroMemOp(const char *mnem, ExtMachInst machInst, 557170Sgblack@eecs.umich.edu OpClass __opClass, IntRegIndex rn, 567170Sgblack@eecs.umich.edu bool index, bool up, bool user, bool writeback, 577170Sgblack@eecs.umich.edu bool load, uint32_t reglist) : 587170Sgblack@eecs.umich.edu PredMacroOp(mnem, machInst, __opClass) 597170Sgblack@eecs.umich.edu{ 607170Sgblack@eecs.umich.edu uint32_t regs = reglist; 617170Sgblack@eecs.umich.edu uint32_t ones = number_of_ones(reglist); 628148SAli.Saidi@ARM.com // Remember that writeback adds a uop or two and the temp register adds one 638148SAli.Saidi@ARM.com numMicroops = ones + (writeback ? (load ? 2 : 1) : 0) + 1; 648148SAli.Saidi@ARM.com 658148SAli.Saidi@ARM.com // It's technically legal to do a lot of nothing 668148SAli.Saidi@ARM.com if (!ones) 678148SAli.Saidi@ARM.com numMicroops = 1; 688148SAli.Saidi@ARM.com 697170Sgblack@eecs.umich.edu microOps = new StaticInstPtr[numMicroops]; 707170Sgblack@eecs.umich.edu uint32_t addr = 0; 717170Sgblack@eecs.umich.edu 727170Sgblack@eecs.umich.edu if (!up) 737170Sgblack@eecs.umich.edu addr = (ones << 2) - 4; 747170Sgblack@eecs.umich.edu 757170Sgblack@eecs.umich.edu if (!index) 767170Sgblack@eecs.umich.edu addr += 4; 777170Sgblack@eecs.umich.edu 787190Sgblack@eecs.umich.edu StaticInstPtr *uop = microOps; 797190Sgblack@eecs.umich.edu 807170Sgblack@eecs.umich.edu // Add 0 to Rn and stick it in ureg0. 817170Sgblack@eecs.umich.edu // This is equivalent to a move. 827190Sgblack@eecs.umich.edu *uop = new MicroAddiUop(machInst, INTREG_UREG0, rn, 0); 837190Sgblack@eecs.umich.edu 847170Sgblack@eecs.umich.edu unsigned reg = 0; 858148SAli.Saidi@ARM.com unsigned regIdx = 0; 867170Sgblack@eecs.umich.edu bool force_user = user & !bits(reglist, 15); 877170Sgblack@eecs.umich.edu bool exception_ret = user & bits(reglist, 15); 887170Sgblack@eecs.umich.edu 897190Sgblack@eecs.umich.edu for (int i = 0; i < ones; i++) { 907170Sgblack@eecs.umich.edu // Find the next register. 917170Sgblack@eecs.umich.edu while (!bits(regs, reg)) 927170Sgblack@eecs.umich.edu reg++; 937170Sgblack@eecs.umich.edu replaceBits(regs, reg, 0); 947170Sgblack@eecs.umich.edu 958148SAli.Saidi@ARM.com regIdx = reg; 967170Sgblack@eecs.umich.edu if (force_user) { 977310Sgblack@eecs.umich.edu regIdx = intRegInMode(MODE_USER, regIdx); 987170Sgblack@eecs.umich.edu } 997170Sgblack@eecs.umich.edu 1007170Sgblack@eecs.umich.edu if (load) { 1018148SAli.Saidi@ARM.com if (writeback && i == ones - 1) { 1028148SAli.Saidi@ARM.com // If it's a writeback and this is the last register 1038148SAli.Saidi@ARM.com // do the load into a temporary register which we'll move 1048148SAli.Saidi@ARM.com // into the final one later 1058148SAli.Saidi@ARM.com *++uop = new MicroLdrUop(machInst, INTREG_UREG1, INTREG_UREG0, 1068148SAli.Saidi@ARM.com up, addr); 1077170Sgblack@eecs.umich.edu } else { 1088148SAli.Saidi@ARM.com // Otherwise just do it normally 1098148SAli.Saidi@ARM.com if (reg == INTREG_PC && exception_ret) { 1108148SAli.Saidi@ARM.com // This must be the exception return form of ldm. 1118148SAli.Saidi@ARM.com *++uop = new MicroLdrRetUop(machInst, regIdx, 1128148SAli.Saidi@ARM.com INTREG_UREG0, up, addr); 1139640Snathanael.premillieu@irisa.fr if (!(condCode == COND_AL || condCode == COND_UC)) 1149640Snathanael.premillieu@irisa.fr (*uop)->setFlag(StaticInst::IsCondControl); 1159640Snathanael.premillieu@irisa.fr else 1169640Snathanael.premillieu@irisa.fr (*uop)->setFlag(StaticInst::IsUncondControl); 1178148SAli.Saidi@ARM.com } else { 1188148SAli.Saidi@ARM.com *++uop = new MicroLdrUop(machInst, regIdx, 1198148SAli.Saidi@ARM.com INTREG_UREG0, up, addr); 1209250SAli.Saidi@ARM.com if (reg == INTREG_PC) { 1219250SAli.Saidi@ARM.com (*uop)->setFlag(StaticInst::IsControl); 1229250SAli.Saidi@ARM.com if (!(condCode == COND_AL || condCode == COND_UC)) 1239250SAli.Saidi@ARM.com (*uop)->setFlag(StaticInst::IsCondControl); 1249250SAli.Saidi@ARM.com else 1259250SAli.Saidi@ARM.com (*uop)->setFlag(StaticInst::IsUncondControl); 1269250SAli.Saidi@ARM.com (*uop)->setFlag(StaticInst::IsIndirectControl); 1279250SAli.Saidi@ARM.com } 1288148SAli.Saidi@ARM.com } 1297170Sgblack@eecs.umich.edu } 1307170Sgblack@eecs.umich.edu } else { 1317190Sgblack@eecs.umich.edu *++uop = new MicroStrUop(machInst, regIdx, INTREG_UREG0, up, addr); 1327170Sgblack@eecs.umich.edu } 1337170Sgblack@eecs.umich.edu 1347170Sgblack@eecs.umich.edu if (up) 1357170Sgblack@eecs.umich.edu addr += 4; 1367170Sgblack@eecs.umich.edu else 1377170Sgblack@eecs.umich.edu addr -= 4; 1387170Sgblack@eecs.umich.edu } 1397170Sgblack@eecs.umich.edu 1408148SAli.Saidi@ARM.com if (writeback && ones) { 1418148SAli.Saidi@ARM.com // put the register update after we're done all loading 1428148SAli.Saidi@ARM.com if (up) 1438148SAli.Saidi@ARM.com *++uop = new MicroAddiUop(machInst, rn, rn, ones * 4); 1448148SAli.Saidi@ARM.com else 1458148SAli.Saidi@ARM.com *++uop = new MicroSubiUop(machInst, rn, rn, ones * 4); 1468148SAli.Saidi@ARM.com 1478148SAli.Saidi@ARM.com // If this was a load move the last temporary value into place 1488148SAli.Saidi@ARM.com // this way we can't take an exception after we update the base 1498148SAli.Saidi@ARM.com // register. 1508148SAli.Saidi@ARM.com if (load && reg == INTREG_PC && exception_ret) { 1518148SAli.Saidi@ARM.com *++uop = new MicroUopRegMovRet(machInst, 0, INTREG_UREG1); 1529368Snathanael.premillieu@irisa.fr if (!(condCode == COND_AL || condCode == COND_UC)) 1539368Snathanael.premillieu@irisa.fr (*uop)->setFlag(StaticInst::IsCondControl); 1549368Snathanael.premillieu@irisa.fr else 1559368Snathanael.premillieu@irisa.fr (*uop)->setFlag(StaticInst::IsUncondControl); 1568148SAli.Saidi@ARM.com } else if (load) { 1578148SAli.Saidi@ARM.com *++uop = new MicroUopRegMov(machInst, regIdx, INTREG_UREG1); 1588148SAli.Saidi@ARM.com if (reg == INTREG_PC) { 1598542Sgblack@eecs.umich.edu (*uop)->setFlag(StaticInst::IsControl); 1608542Sgblack@eecs.umich.edu (*uop)->setFlag(StaticInst::IsCondControl); 1618542Sgblack@eecs.umich.edu (*uop)->setFlag(StaticInst::IsIndirectControl); 1628148SAli.Saidi@ARM.com // This is created as a RAS POP 1638148SAli.Saidi@ARM.com if (rn == INTREG_SP) 1648542Sgblack@eecs.umich.edu (*uop)->setFlag(StaticInst::IsReturn); 1658148SAli.Saidi@ARM.com 1668148SAli.Saidi@ARM.com } 1678148SAli.Saidi@ARM.com } 1687170Sgblack@eecs.umich.edu } 1697190Sgblack@eecs.umich.edu 1707190Sgblack@eecs.umich.edu (*uop)->setLastMicroop(); 1717343Sgblack@eecs.umich.edu 1727343Sgblack@eecs.umich.edu for (StaticInstPtr *curUop = microOps; 1737343Sgblack@eecs.umich.edu !(*curUop)->isLastMicroop(); curUop++) { 1747343Sgblack@eecs.umich.edu MicroOp * uopPtr = dynamic_cast<MicroOp *>(curUop->get()); 1757343Sgblack@eecs.umich.edu assert(uopPtr); 1767343Sgblack@eecs.umich.edu uopPtr->setDelayedCommit(); 1777343Sgblack@eecs.umich.edu } 1787170Sgblack@eecs.umich.edu} 1797170Sgblack@eecs.umich.edu 1807639Sgblack@eecs.umich.eduVldMultOp::VldMultOp(const char *mnem, ExtMachInst machInst, OpClass __opClass, 1817639Sgblack@eecs.umich.edu unsigned elems, RegIndex rn, RegIndex vd, unsigned regs, 1827639Sgblack@eecs.umich.edu unsigned inc, uint32_t size, uint32_t align, RegIndex rm) : 1837639Sgblack@eecs.umich.edu PredMacroOp(mnem, machInst, __opClass) 1847639Sgblack@eecs.umich.edu{ 1857639Sgblack@eecs.umich.edu assert(regs > 0 && regs <= 4); 1867639Sgblack@eecs.umich.edu assert(regs % elems == 0); 1877639Sgblack@eecs.umich.edu 1887639Sgblack@eecs.umich.edu numMicroops = (regs > 2) ? 2 : 1; 1897639Sgblack@eecs.umich.edu bool wb = (rm != 15); 1907639Sgblack@eecs.umich.edu bool deinterleave = (elems > 1); 1917639Sgblack@eecs.umich.edu 1927639Sgblack@eecs.umich.edu if (wb) numMicroops++; 1937639Sgblack@eecs.umich.edu if (deinterleave) numMicroops += (regs / elems); 1947639Sgblack@eecs.umich.edu microOps = new StaticInstPtr[numMicroops]; 1957639Sgblack@eecs.umich.edu 1967639Sgblack@eecs.umich.edu RegIndex rMid = deinterleave ? NumFloatArchRegs : vd * 2; 1977639Sgblack@eecs.umich.edu 1987639Sgblack@eecs.umich.edu uint32_t noAlign = TLB::MustBeOne; 1997639Sgblack@eecs.umich.edu 2007639Sgblack@eecs.umich.edu unsigned uopIdx = 0; 2017639Sgblack@eecs.umich.edu switch (regs) { 2027639Sgblack@eecs.umich.edu case 4: 2037639Sgblack@eecs.umich.edu microOps[uopIdx++] = newNeonMemInst<MicroLdrNeon16Uop>( 2047639Sgblack@eecs.umich.edu size, machInst, rMid, rn, 0, align); 2057639Sgblack@eecs.umich.edu microOps[uopIdx++] = newNeonMemInst<MicroLdrNeon16Uop>( 2067639Sgblack@eecs.umich.edu size, machInst, rMid + 4, rn, 16, noAlign); 2077639Sgblack@eecs.umich.edu break; 2087639Sgblack@eecs.umich.edu case 3: 2097639Sgblack@eecs.umich.edu microOps[uopIdx++] = newNeonMemInst<MicroLdrNeon16Uop>( 2107639Sgblack@eecs.umich.edu size, machInst, rMid, rn, 0, align); 2117639Sgblack@eecs.umich.edu microOps[uopIdx++] = newNeonMemInst<MicroLdrNeon8Uop>( 2127639Sgblack@eecs.umich.edu size, machInst, rMid + 4, rn, 16, noAlign); 2137639Sgblack@eecs.umich.edu break; 2147639Sgblack@eecs.umich.edu case 2: 2157639Sgblack@eecs.umich.edu microOps[uopIdx++] = newNeonMemInst<MicroLdrNeon16Uop>( 2167639Sgblack@eecs.umich.edu size, machInst, rMid, rn, 0, align); 2177639Sgblack@eecs.umich.edu break; 2187639Sgblack@eecs.umich.edu case 1: 2197639Sgblack@eecs.umich.edu microOps[uopIdx++] = newNeonMemInst<MicroLdrNeon8Uop>( 2207639Sgblack@eecs.umich.edu size, machInst, rMid, rn, 0, align); 2217639Sgblack@eecs.umich.edu break; 2227639Sgblack@eecs.umich.edu default: 2237853SMatt.Horsnell@ARM.com // Unknown number of registers 2247853SMatt.Horsnell@ARM.com microOps[uopIdx++] = new Unknown(machInst); 2257639Sgblack@eecs.umich.edu } 2267639Sgblack@eecs.umich.edu if (wb) { 2277639Sgblack@eecs.umich.edu if (rm != 15 && rm != 13) { 2287639Sgblack@eecs.umich.edu microOps[uopIdx++] = 2297646Sgene.wu@arm.com new MicroAddUop(machInst, rn, rn, rm, 0, ArmISA::LSL); 2307639Sgblack@eecs.umich.edu } else { 2317639Sgblack@eecs.umich.edu microOps[uopIdx++] = 2327639Sgblack@eecs.umich.edu new MicroAddiUop(machInst, rn, rn, regs * 8); 2337639Sgblack@eecs.umich.edu } 2347639Sgblack@eecs.umich.edu } 2357639Sgblack@eecs.umich.edu if (deinterleave) { 2367639Sgblack@eecs.umich.edu switch (elems) { 2377639Sgblack@eecs.umich.edu case 4: 2387639Sgblack@eecs.umich.edu assert(regs == 4); 2397639Sgblack@eecs.umich.edu microOps[uopIdx++] = newNeonMixInst<MicroDeintNeon8Uop>( 2407639Sgblack@eecs.umich.edu size, machInst, vd * 2, rMid, inc * 2); 2417639Sgblack@eecs.umich.edu break; 2427639Sgblack@eecs.umich.edu case 3: 2437639Sgblack@eecs.umich.edu assert(regs == 3); 2447639Sgblack@eecs.umich.edu microOps[uopIdx++] = newNeonMixInst<MicroDeintNeon6Uop>( 2457639Sgblack@eecs.umich.edu size, machInst, vd * 2, rMid, inc * 2); 2467639Sgblack@eecs.umich.edu break; 2477639Sgblack@eecs.umich.edu case 2: 2487639Sgblack@eecs.umich.edu assert(regs == 4 || regs == 2); 2497639Sgblack@eecs.umich.edu if (regs == 4) { 2507639Sgblack@eecs.umich.edu microOps[uopIdx++] = newNeonMixInst<MicroDeintNeon4Uop>( 2517639Sgblack@eecs.umich.edu size, machInst, vd * 2, rMid, inc * 2); 2527639Sgblack@eecs.umich.edu microOps[uopIdx++] = newNeonMixInst<MicroDeintNeon4Uop>( 2537639Sgblack@eecs.umich.edu size, machInst, vd * 2 + 2, rMid + 4, inc * 2); 2547639Sgblack@eecs.umich.edu } else { 2557639Sgblack@eecs.umich.edu microOps[uopIdx++] = newNeonMixInst<MicroDeintNeon4Uop>( 2567639Sgblack@eecs.umich.edu size, machInst, vd * 2, rMid, inc * 2); 2577639Sgblack@eecs.umich.edu } 2587639Sgblack@eecs.umich.edu break; 2597639Sgblack@eecs.umich.edu default: 2607853SMatt.Horsnell@ARM.com // Bad number of elements to deinterleave 2617853SMatt.Horsnell@ARM.com microOps[uopIdx++] = new Unknown(machInst); 2627639Sgblack@eecs.umich.edu } 2637639Sgblack@eecs.umich.edu } 2647639Sgblack@eecs.umich.edu assert(uopIdx == numMicroops); 2657639Sgblack@eecs.umich.edu 2667639Sgblack@eecs.umich.edu for (unsigned i = 0; i < numMicroops - 1; i++) { 2677639Sgblack@eecs.umich.edu MicroOp * uopPtr = dynamic_cast<MicroOp *>(microOps[i].get()); 2687639Sgblack@eecs.umich.edu assert(uopPtr); 2697639Sgblack@eecs.umich.edu uopPtr->setDelayedCommit(); 2707639Sgblack@eecs.umich.edu } 2717639Sgblack@eecs.umich.edu microOps[numMicroops - 1]->setLastMicroop(); 2727639Sgblack@eecs.umich.edu} 2737639Sgblack@eecs.umich.edu 2747639Sgblack@eecs.umich.eduVldSingleOp::VldSingleOp(const char *mnem, ExtMachInst machInst, 2757639Sgblack@eecs.umich.edu OpClass __opClass, bool all, unsigned elems, 2767639Sgblack@eecs.umich.edu RegIndex rn, RegIndex vd, unsigned regs, 2777639Sgblack@eecs.umich.edu unsigned inc, uint32_t size, uint32_t align, 2787639Sgblack@eecs.umich.edu RegIndex rm, unsigned lane) : 2797639Sgblack@eecs.umich.edu PredMacroOp(mnem, machInst, __opClass) 2807639Sgblack@eecs.umich.edu{ 2817639Sgblack@eecs.umich.edu assert(regs > 0 && regs <= 4); 2827639Sgblack@eecs.umich.edu assert(regs % elems == 0); 2837639Sgblack@eecs.umich.edu 2847639Sgblack@eecs.umich.edu unsigned eBytes = (1 << size); 2857639Sgblack@eecs.umich.edu unsigned loadSize = eBytes * elems; 2867639Sgblack@eecs.umich.edu unsigned loadRegs M5_VAR_USED = (loadSize + sizeof(FloatRegBits) - 1) / 2877639Sgblack@eecs.umich.edu sizeof(FloatRegBits); 2887639Sgblack@eecs.umich.edu 2897639Sgblack@eecs.umich.edu assert(loadRegs > 0 && loadRegs <= 4); 2907639Sgblack@eecs.umich.edu 2917639Sgblack@eecs.umich.edu numMicroops = 1; 2927639Sgblack@eecs.umich.edu bool wb = (rm != 15); 2937639Sgblack@eecs.umich.edu 2947639Sgblack@eecs.umich.edu if (wb) numMicroops++; 2957639Sgblack@eecs.umich.edu numMicroops += (regs / elems); 2967639Sgblack@eecs.umich.edu microOps = new StaticInstPtr[numMicroops]; 2977639Sgblack@eecs.umich.edu 2987639Sgblack@eecs.umich.edu RegIndex ufp0 = NumFloatArchRegs; 2997639Sgblack@eecs.umich.edu 3007639Sgblack@eecs.umich.edu unsigned uopIdx = 0; 3017639Sgblack@eecs.umich.edu switch (loadSize) { 3027639Sgblack@eecs.umich.edu case 1: 3037639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroLdrNeon1Uop<uint8_t>( 3047639Sgblack@eecs.umich.edu machInst, ufp0, rn, 0, align); 3057639Sgblack@eecs.umich.edu break; 3067639Sgblack@eecs.umich.edu case 2: 3077639Sgblack@eecs.umich.edu if (eBytes == 2) { 3087639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroLdrNeon2Uop<uint16_t>( 3097639Sgblack@eecs.umich.edu machInst, ufp0, rn, 0, align); 3107639Sgblack@eecs.umich.edu } else { 3117639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroLdrNeon2Uop<uint8_t>( 3127639Sgblack@eecs.umich.edu machInst, ufp0, rn, 0, align); 3137639Sgblack@eecs.umich.edu } 3147639Sgblack@eecs.umich.edu break; 3157639Sgblack@eecs.umich.edu case 3: 3167639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroLdrNeon3Uop<uint8_t>( 3177639Sgblack@eecs.umich.edu machInst, ufp0, rn, 0, align); 3187639Sgblack@eecs.umich.edu break; 3197639Sgblack@eecs.umich.edu case 4: 3207639Sgblack@eecs.umich.edu switch (eBytes) { 3217639Sgblack@eecs.umich.edu case 1: 3227639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroLdrNeon4Uop<uint8_t>( 3237639Sgblack@eecs.umich.edu machInst, ufp0, rn, 0, align); 3247639Sgblack@eecs.umich.edu break; 3257639Sgblack@eecs.umich.edu case 2: 3267639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroLdrNeon4Uop<uint16_t>( 3277639Sgblack@eecs.umich.edu machInst, ufp0, rn, 0, align); 3287639Sgblack@eecs.umich.edu break; 3297639Sgblack@eecs.umich.edu case 4: 3307639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroLdrNeon4Uop<uint32_t>( 3317639Sgblack@eecs.umich.edu machInst, ufp0, rn, 0, align); 3327639Sgblack@eecs.umich.edu break; 3337639Sgblack@eecs.umich.edu } 3347639Sgblack@eecs.umich.edu break; 3357639Sgblack@eecs.umich.edu case 6: 3367639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroLdrNeon6Uop<uint16_t>( 3377639Sgblack@eecs.umich.edu machInst, ufp0, rn, 0, align); 3387639Sgblack@eecs.umich.edu break; 3397639Sgblack@eecs.umich.edu case 8: 3407639Sgblack@eecs.umich.edu switch (eBytes) { 3417639Sgblack@eecs.umich.edu case 2: 3427639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroLdrNeon8Uop<uint16_t>( 3437639Sgblack@eecs.umich.edu machInst, ufp0, rn, 0, align); 3447639Sgblack@eecs.umich.edu break; 3457639Sgblack@eecs.umich.edu case 4: 3467639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroLdrNeon8Uop<uint32_t>( 3477639Sgblack@eecs.umich.edu machInst, ufp0, rn, 0, align); 3487639Sgblack@eecs.umich.edu break; 3497639Sgblack@eecs.umich.edu } 3507639Sgblack@eecs.umich.edu break; 3517639Sgblack@eecs.umich.edu case 12: 3527639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroLdrNeon12Uop<uint32_t>( 3537639Sgblack@eecs.umich.edu machInst, ufp0, rn, 0, align); 3547639Sgblack@eecs.umich.edu break; 3557639Sgblack@eecs.umich.edu case 16: 3567639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroLdrNeon16Uop<uint32_t>( 3577639Sgblack@eecs.umich.edu machInst, ufp0, rn, 0, align); 3587639Sgblack@eecs.umich.edu break; 3597639Sgblack@eecs.umich.edu default: 3607853SMatt.Horsnell@ARM.com // Unrecognized load size 3617853SMatt.Horsnell@ARM.com microOps[uopIdx++] = new Unknown(machInst); 3627639Sgblack@eecs.umich.edu } 3637639Sgblack@eecs.umich.edu if (wb) { 3647639Sgblack@eecs.umich.edu if (rm != 15 && rm != 13) { 3657639Sgblack@eecs.umich.edu microOps[uopIdx++] = 3667646Sgene.wu@arm.com new MicroAddUop(machInst, rn, rn, rm, 0, ArmISA::LSL); 3677639Sgblack@eecs.umich.edu } else { 3687639Sgblack@eecs.umich.edu microOps[uopIdx++] = 3697639Sgblack@eecs.umich.edu new MicroAddiUop(machInst, rn, rn, loadSize); 3707639Sgblack@eecs.umich.edu } 3717639Sgblack@eecs.umich.edu } 3727639Sgblack@eecs.umich.edu switch (elems) { 3737639Sgblack@eecs.umich.edu case 4: 3747639Sgblack@eecs.umich.edu assert(regs == 4); 3757639Sgblack@eecs.umich.edu switch (size) { 3767639Sgblack@eecs.umich.edu case 0: 3777639Sgblack@eecs.umich.edu if (all) { 3787639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroUnpackAllNeon2to8Uop<uint8_t>( 3797639Sgblack@eecs.umich.edu machInst, vd * 2, ufp0, inc * 2); 3807639Sgblack@eecs.umich.edu } else { 3817639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroUnpackNeon2to8Uop<uint8_t>( 3827639Sgblack@eecs.umich.edu machInst, vd * 2, ufp0, inc * 2, lane); 3837639Sgblack@eecs.umich.edu } 3847639Sgblack@eecs.umich.edu break; 3857639Sgblack@eecs.umich.edu case 1: 3867639Sgblack@eecs.umich.edu if (all) { 3877639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroUnpackAllNeon2to8Uop<uint16_t>( 3887639Sgblack@eecs.umich.edu machInst, vd * 2, ufp0, inc * 2); 3897639Sgblack@eecs.umich.edu } else { 3907639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroUnpackNeon2to8Uop<uint16_t>( 3917639Sgblack@eecs.umich.edu machInst, vd * 2, ufp0, inc * 2, lane); 3927639Sgblack@eecs.umich.edu } 3937639Sgblack@eecs.umich.edu break; 3947639Sgblack@eecs.umich.edu case 2: 3957639Sgblack@eecs.umich.edu if (all) { 3967639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroUnpackAllNeon4to8Uop<uint32_t>( 3977639Sgblack@eecs.umich.edu machInst, vd * 2, ufp0, inc * 2); 3987639Sgblack@eecs.umich.edu } else { 3997639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroUnpackNeon4to8Uop<uint32_t>( 4007639Sgblack@eecs.umich.edu machInst, vd * 2, ufp0, inc * 2, lane); 4017639Sgblack@eecs.umich.edu } 4027639Sgblack@eecs.umich.edu break; 4037639Sgblack@eecs.umich.edu default: 4047853SMatt.Horsnell@ARM.com // Bad size 4057853SMatt.Horsnell@ARM.com microOps[uopIdx++] = new Unknown(machInst); 4067639Sgblack@eecs.umich.edu break; 4077639Sgblack@eecs.umich.edu } 4087639Sgblack@eecs.umich.edu break; 4097639Sgblack@eecs.umich.edu case 3: 4107639Sgblack@eecs.umich.edu assert(regs == 3); 4117639Sgblack@eecs.umich.edu switch (size) { 4127639Sgblack@eecs.umich.edu case 0: 4137639Sgblack@eecs.umich.edu if (all) { 4147639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroUnpackAllNeon2to6Uop<uint8_t>( 4157639Sgblack@eecs.umich.edu machInst, vd * 2, ufp0, inc * 2); 4167639Sgblack@eecs.umich.edu } else { 4177639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroUnpackNeon2to6Uop<uint8_t>( 4187639Sgblack@eecs.umich.edu machInst, vd * 2, ufp0, inc * 2, lane); 4197639Sgblack@eecs.umich.edu } 4207639Sgblack@eecs.umich.edu break; 4217639Sgblack@eecs.umich.edu case 1: 4227639Sgblack@eecs.umich.edu if (all) { 4237639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroUnpackAllNeon2to6Uop<uint16_t>( 4247639Sgblack@eecs.umich.edu machInst, vd * 2, ufp0, inc * 2); 4257639Sgblack@eecs.umich.edu } else { 4267639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroUnpackNeon2to6Uop<uint16_t>( 4277639Sgblack@eecs.umich.edu machInst, vd * 2, ufp0, inc * 2, lane); 4287639Sgblack@eecs.umich.edu } 4297639Sgblack@eecs.umich.edu break; 4307639Sgblack@eecs.umich.edu case 2: 4317639Sgblack@eecs.umich.edu if (all) { 4327639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroUnpackAllNeon4to6Uop<uint32_t>( 4337639Sgblack@eecs.umich.edu machInst, vd * 2, ufp0, inc * 2); 4347639Sgblack@eecs.umich.edu } else { 4357639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroUnpackNeon4to6Uop<uint32_t>( 4367639Sgblack@eecs.umich.edu machInst, vd * 2, ufp0, inc * 2, lane); 4377639Sgblack@eecs.umich.edu } 4387639Sgblack@eecs.umich.edu break; 4397639Sgblack@eecs.umich.edu default: 4407853SMatt.Horsnell@ARM.com // Bad size 4417853SMatt.Horsnell@ARM.com microOps[uopIdx++] = new Unknown(machInst); 4427639Sgblack@eecs.umich.edu break; 4437639Sgblack@eecs.umich.edu } 4447639Sgblack@eecs.umich.edu break; 4457639Sgblack@eecs.umich.edu case 2: 4467639Sgblack@eecs.umich.edu assert(regs == 2); 4477639Sgblack@eecs.umich.edu assert(loadRegs <= 2); 4487639Sgblack@eecs.umich.edu switch (size) { 4497639Sgblack@eecs.umich.edu case 0: 4507639Sgblack@eecs.umich.edu if (all) { 4517639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroUnpackAllNeon2to4Uop<uint8_t>( 4527639Sgblack@eecs.umich.edu machInst, vd * 2, ufp0, inc * 2); 4537639Sgblack@eecs.umich.edu } else { 4547639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroUnpackNeon2to4Uop<uint8_t>( 4557639Sgblack@eecs.umich.edu machInst, vd * 2, ufp0, inc * 2, lane); 4567639Sgblack@eecs.umich.edu } 4577639Sgblack@eecs.umich.edu break; 4587639Sgblack@eecs.umich.edu case 1: 4597639Sgblack@eecs.umich.edu if (all) { 4607639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroUnpackAllNeon2to4Uop<uint16_t>( 4617639Sgblack@eecs.umich.edu machInst, vd * 2, ufp0, inc * 2); 4627639Sgblack@eecs.umich.edu } else { 4637639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroUnpackNeon2to4Uop<uint16_t>( 4647639Sgblack@eecs.umich.edu machInst, vd * 2, ufp0, inc * 2, lane); 4657639Sgblack@eecs.umich.edu } 4667639Sgblack@eecs.umich.edu break; 4677639Sgblack@eecs.umich.edu case 2: 4687639Sgblack@eecs.umich.edu if (all) { 4697639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroUnpackAllNeon2to4Uop<uint32_t>( 4707639Sgblack@eecs.umich.edu machInst, vd * 2, ufp0, inc * 2); 4717639Sgblack@eecs.umich.edu } else { 4727639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroUnpackNeon2to4Uop<uint32_t>( 4737639Sgblack@eecs.umich.edu machInst, vd * 2, ufp0, inc * 2, lane); 4747639Sgblack@eecs.umich.edu } 4757639Sgblack@eecs.umich.edu break; 4767639Sgblack@eecs.umich.edu default: 4777853SMatt.Horsnell@ARM.com // Bad size 4787853SMatt.Horsnell@ARM.com microOps[uopIdx++] = new Unknown(machInst); 4797639Sgblack@eecs.umich.edu break; 4807639Sgblack@eecs.umich.edu } 4817639Sgblack@eecs.umich.edu break; 4827639Sgblack@eecs.umich.edu case 1: 4837639Sgblack@eecs.umich.edu assert(regs == 1 || (all && regs == 2)); 4847639Sgblack@eecs.umich.edu assert(loadRegs <= 2); 4857639Sgblack@eecs.umich.edu for (unsigned offset = 0; offset < regs; offset++) { 4867639Sgblack@eecs.umich.edu switch (size) { 4877639Sgblack@eecs.umich.edu case 0: 4887639Sgblack@eecs.umich.edu if (all) { 4897639Sgblack@eecs.umich.edu microOps[uopIdx++] = 4907639Sgblack@eecs.umich.edu new MicroUnpackAllNeon2to2Uop<uint8_t>( 4917639Sgblack@eecs.umich.edu machInst, (vd + offset) * 2, ufp0, inc * 2); 4927639Sgblack@eecs.umich.edu } else { 4937639Sgblack@eecs.umich.edu microOps[uopIdx++] = 4947639Sgblack@eecs.umich.edu new MicroUnpackNeon2to2Uop<uint8_t>( 4957639Sgblack@eecs.umich.edu machInst, (vd + offset) * 2, ufp0, inc * 2, lane); 4967639Sgblack@eecs.umich.edu } 4977639Sgblack@eecs.umich.edu break; 4987639Sgblack@eecs.umich.edu case 1: 4997639Sgblack@eecs.umich.edu if (all) { 5007639Sgblack@eecs.umich.edu microOps[uopIdx++] = 5017639Sgblack@eecs.umich.edu new MicroUnpackAllNeon2to2Uop<uint16_t>( 5027639Sgblack@eecs.umich.edu machInst, (vd + offset) * 2, ufp0, inc * 2); 5037639Sgblack@eecs.umich.edu } else { 5047639Sgblack@eecs.umich.edu microOps[uopIdx++] = 5057639Sgblack@eecs.umich.edu new MicroUnpackNeon2to2Uop<uint16_t>( 5067639Sgblack@eecs.umich.edu machInst, (vd + offset) * 2, ufp0, inc * 2, lane); 5077639Sgblack@eecs.umich.edu } 5087639Sgblack@eecs.umich.edu break; 5097639Sgblack@eecs.umich.edu case 2: 5107639Sgblack@eecs.umich.edu if (all) { 5117639Sgblack@eecs.umich.edu microOps[uopIdx++] = 5127639Sgblack@eecs.umich.edu new MicroUnpackAllNeon2to2Uop<uint32_t>( 5137639Sgblack@eecs.umich.edu machInst, (vd + offset) * 2, ufp0, inc * 2); 5147639Sgblack@eecs.umich.edu } else { 5157639Sgblack@eecs.umich.edu microOps[uopIdx++] = 5167639Sgblack@eecs.umich.edu new MicroUnpackNeon2to2Uop<uint32_t>( 5177639Sgblack@eecs.umich.edu machInst, (vd + offset) * 2, ufp0, inc * 2, lane); 5187639Sgblack@eecs.umich.edu } 5197639Sgblack@eecs.umich.edu break; 5207639Sgblack@eecs.umich.edu default: 5217853SMatt.Horsnell@ARM.com // Bad size 5227853SMatt.Horsnell@ARM.com microOps[uopIdx++] = new Unknown(machInst); 5237639Sgblack@eecs.umich.edu break; 5247639Sgblack@eecs.umich.edu } 5257639Sgblack@eecs.umich.edu } 5267639Sgblack@eecs.umich.edu break; 5277639Sgblack@eecs.umich.edu default: 5287853SMatt.Horsnell@ARM.com // Bad number of elements to unpack 5297853SMatt.Horsnell@ARM.com microOps[uopIdx++] = new Unknown(machInst); 5307639Sgblack@eecs.umich.edu } 5317639Sgblack@eecs.umich.edu assert(uopIdx == numMicroops); 5327639Sgblack@eecs.umich.edu 5337639Sgblack@eecs.umich.edu for (unsigned i = 0; i < numMicroops - 1; i++) { 5347639Sgblack@eecs.umich.edu MicroOp * uopPtr = dynamic_cast<MicroOp *>(microOps[i].get()); 5357639Sgblack@eecs.umich.edu assert(uopPtr); 5367639Sgblack@eecs.umich.edu uopPtr->setDelayedCommit(); 5377639Sgblack@eecs.umich.edu } 5387639Sgblack@eecs.umich.edu microOps[numMicroops - 1]->setLastMicroop(); 5397639Sgblack@eecs.umich.edu} 5407639Sgblack@eecs.umich.edu 5417639Sgblack@eecs.umich.eduVstMultOp::VstMultOp(const char *mnem, ExtMachInst machInst, OpClass __opClass, 5427639Sgblack@eecs.umich.edu unsigned elems, RegIndex rn, RegIndex vd, unsigned regs, 5437639Sgblack@eecs.umich.edu unsigned inc, uint32_t size, uint32_t align, RegIndex rm) : 5447639Sgblack@eecs.umich.edu PredMacroOp(mnem, machInst, __opClass) 5457639Sgblack@eecs.umich.edu{ 5467639Sgblack@eecs.umich.edu assert(regs > 0 && regs <= 4); 5477639Sgblack@eecs.umich.edu assert(regs % elems == 0); 5487639Sgblack@eecs.umich.edu 5497639Sgblack@eecs.umich.edu numMicroops = (regs > 2) ? 2 : 1; 5507639Sgblack@eecs.umich.edu bool wb = (rm != 15); 5517639Sgblack@eecs.umich.edu bool interleave = (elems > 1); 5527639Sgblack@eecs.umich.edu 5537639Sgblack@eecs.umich.edu if (wb) numMicroops++; 5547639Sgblack@eecs.umich.edu if (interleave) numMicroops += (regs / elems); 5557639Sgblack@eecs.umich.edu microOps = new StaticInstPtr[numMicroops]; 5567639Sgblack@eecs.umich.edu 5577639Sgblack@eecs.umich.edu uint32_t noAlign = TLB::MustBeOne; 5587639Sgblack@eecs.umich.edu 5597639Sgblack@eecs.umich.edu RegIndex rMid = interleave ? NumFloatArchRegs : vd * 2; 5607639Sgblack@eecs.umich.edu 5617639Sgblack@eecs.umich.edu unsigned uopIdx = 0; 5627639Sgblack@eecs.umich.edu if (interleave) { 5637639Sgblack@eecs.umich.edu switch (elems) { 5647639Sgblack@eecs.umich.edu case 4: 5657639Sgblack@eecs.umich.edu assert(regs == 4); 5667639Sgblack@eecs.umich.edu microOps[uopIdx++] = newNeonMixInst<MicroInterNeon8Uop>( 5677639Sgblack@eecs.umich.edu size, machInst, rMid, vd * 2, inc * 2); 5687639Sgblack@eecs.umich.edu break; 5697639Sgblack@eecs.umich.edu case 3: 5707639Sgblack@eecs.umich.edu assert(regs == 3); 5717639Sgblack@eecs.umich.edu microOps[uopIdx++] = newNeonMixInst<MicroInterNeon6Uop>( 5727639Sgblack@eecs.umich.edu size, machInst, rMid, vd * 2, inc * 2); 5737639Sgblack@eecs.umich.edu break; 5747639Sgblack@eecs.umich.edu case 2: 5757639Sgblack@eecs.umich.edu assert(regs == 4 || regs == 2); 5767639Sgblack@eecs.umich.edu if (regs == 4) { 5777639Sgblack@eecs.umich.edu microOps[uopIdx++] = newNeonMixInst<MicroInterNeon4Uop>( 5787639Sgblack@eecs.umich.edu size, machInst, rMid, vd * 2, inc * 2); 5797639Sgblack@eecs.umich.edu microOps[uopIdx++] = newNeonMixInst<MicroInterNeon4Uop>( 5807639Sgblack@eecs.umich.edu size, machInst, rMid + 4, vd * 2 + 2, inc * 2); 5817639Sgblack@eecs.umich.edu } else { 5827639Sgblack@eecs.umich.edu microOps[uopIdx++] = newNeonMixInst<MicroInterNeon4Uop>( 5837639Sgblack@eecs.umich.edu size, machInst, rMid, vd * 2, inc * 2); 5847639Sgblack@eecs.umich.edu } 5857639Sgblack@eecs.umich.edu break; 5867639Sgblack@eecs.umich.edu default: 5877853SMatt.Horsnell@ARM.com // Bad number of elements to interleave 5887853SMatt.Horsnell@ARM.com microOps[uopIdx++] = new Unknown(machInst); 5897639Sgblack@eecs.umich.edu } 5907639Sgblack@eecs.umich.edu } 5917639Sgblack@eecs.umich.edu switch (regs) { 5927639Sgblack@eecs.umich.edu case 4: 5937639Sgblack@eecs.umich.edu microOps[uopIdx++] = newNeonMemInst<MicroStrNeon16Uop>( 5947639Sgblack@eecs.umich.edu size, machInst, rMid, rn, 0, align); 5957639Sgblack@eecs.umich.edu microOps[uopIdx++] = newNeonMemInst<MicroStrNeon16Uop>( 5967639Sgblack@eecs.umich.edu size, machInst, rMid + 4, rn, 16, noAlign); 5977639Sgblack@eecs.umich.edu break; 5987639Sgblack@eecs.umich.edu case 3: 5997639Sgblack@eecs.umich.edu microOps[uopIdx++] = newNeonMemInst<MicroStrNeon16Uop>( 6007639Sgblack@eecs.umich.edu size, machInst, rMid, rn, 0, align); 6017639Sgblack@eecs.umich.edu microOps[uopIdx++] = newNeonMemInst<MicroStrNeon8Uop>( 6027639Sgblack@eecs.umich.edu size, machInst, rMid + 4, rn, 16, noAlign); 6037639Sgblack@eecs.umich.edu break; 6047639Sgblack@eecs.umich.edu case 2: 6057639Sgblack@eecs.umich.edu microOps[uopIdx++] = newNeonMemInst<MicroStrNeon16Uop>( 6067639Sgblack@eecs.umich.edu size, machInst, rMid, rn, 0, align); 6077639Sgblack@eecs.umich.edu break; 6087639Sgblack@eecs.umich.edu case 1: 6097639Sgblack@eecs.umich.edu microOps[uopIdx++] = newNeonMemInst<MicroStrNeon8Uop>( 6107639Sgblack@eecs.umich.edu size, machInst, rMid, rn, 0, align); 6117639Sgblack@eecs.umich.edu break; 6127639Sgblack@eecs.umich.edu default: 6137853SMatt.Horsnell@ARM.com // Unknown number of registers 6147853SMatt.Horsnell@ARM.com microOps[uopIdx++] = new Unknown(machInst); 6157639Sgblack@eecs.umich.edu } 6167639Sgblack@eecs.umich.edu if (wb) { 6177639Sgblack@eecs.umich.edu if (rm != 15 && rm != 13) { 6187639Sgblack@eecs.umich.edu microOps[uopIdx++] = 6197646Sgene.wu@arm.com new MicroAddUop(machInst, rn, rn, rm, 0, ArmISA::LSL); 6207639Sgblack@eecs.umich.edu } else { 6217639Sgblack@eecs.umich.edu microOps[uopIdx++] = 6227639Sgblack@eecs.umich.edu new MicroAddiUop(machInst, rn, rn, regs * 8); 6237639Sgblack@eecs.umich.edu } 6247639Sgblack@eecs.umich.edu } 6257639Sgblack@eecs.umich.edu assert(uopIdx == numMicroops); 6267639Sgblack@eecs.umich.edu 6277639Sgblack@eecs.umich.edu for (unsigned i = 0; i < numMicroops - 1; i++) { 6287639Sgblack@eecs.umich.edu MicroOp * uopPtr = dynamic_cast<MicroOp *>(microOps[i].get()); 6297639Sgblack@eecs.umich.edu assert(uopPtr); 6307639Sgblack@eecs.umich.edu uopPtr->setDelayedCommit(); 6317639Sgblack@eecs.umich.edu } 6327639Sgblack@eecs.umich.edu microOps[numMicroops - 1]->setLastMicroop(); 6337639Sgblack@eecs.umich.edu} 6347639Sgblack@eecs.umich.edu 6357639Sgblack@eecs.umich.eduVstSingleOp::VstSingleOp(const char *mnem, ExtMachInst machInst, 6367639Sgblack@eecs.umich.edu OpClass __opClass, bool all, unsigned elems, 6377639Sgblack@eecs.umich.edu RegIndex rn, RegIndex vd, unsigned regs, 6387639Sgblack@eecs.umich.edu unsigned inc, uint32_t size, uint32_t align, 6397639Sgblack@eecs.umich.edu RegIndex rm, unsigned lane) : 6407639Sgblack@eecs.umich.edu PredMacroOp(mnem, machInst, __opClass) 6417639Sgblack@eecs.umich.edu{ 6427639Sgblack@eecs.umich.edu assert(!all); 6437639Sgblack@eecs.umich.edu assert(regs > 0 && regs <= 4); 6447639Sgblack@eecs.umich.edu assert(regs % elems == 0); 6457639Sgblack@eecs.umich.edu 6467639Sgblack@eecs.umich.edu unsigned eBytes = (1 << size); 6477639Sgblack@eecs.umich.edu unsigned storeSize = eBytes * elems; 6487639Sgblack@eecs.umich.edu unsigned storeRegs M5_VAR_USED = (storeSize + sizeof(FloatRegBits) - 1) / 6497639Sgblack@eecs.umich.edu sizeof(FloatRegBits); 6507639Sgblack@eecs.umich.edu 6517639Sgblack@eecs.umich.edu assert(storeRegs > 0 && storeRegs <= 4); 6527639Sgblack@eecs.umich.edu 6537639Sgblack@eecs.umich.edu numMicroops = 1; 6547639Sgblack@eecs.umich.edu bool wb = (rm != 15); 6557639Sgblack@eecs.umich.edu 6567639Sgblack@eecs.umich.edu if (wb) numMicroops++; 6577639Sgblack@eecs.umich.edu numMicroops += (regs / elems); 6587639Sgblack@eecs.umich.edu microOps = new StaticInstPtr[numMicroops]; 6597639Sgblack@eecs.umich.edu 6607639Sgblack@eecs.umich.edu RegIndex ufp0 = NumFloatArchRegs; 6617639Sgblack@eecs.umich.edu 6627639Sgblack@eecs.umich.edu unsigned uopIdx = 0; 6637639Sgblack@eecs.umich.edu switch (elems) { 6647639Sgblack@eecs.umich.edu case 4: 6657639Sgblack@eecs.umich.edu assert(regs == 4); 6667639Sgblack@eecs.umich.edu switch (size) { 6677639Sgblack@eecs.umich.edu case 0: 6687639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroPackNeon8to2Uop<uint8_t>( 6697639Sgblack@eecs.umich.edu machInst, ufp0, vd * 2, inc * 2, lane); 6707639Sgblack@eecs.umich.edu break; 6717639Sgblack@eecs.umich.edu case 1: 6727639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroPackNeon8to2Uop<uint16_t>( 6737639Sgblack@eecs.umich.edu machInst, ufp0, vd * 2, inc * 2, lane); 6747639Sgblack@eecs.umich.edu break; 6757639Sgblack@eecs.umich.edu case 2: 6767639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroPackNeon8to4Uop<uint32_t>( 6777639Sgblack@eecs.umich.edu machInst, ufp0, vd * 2, inc * 2, lane); 6787639Sgblack@eecs.umich.edu break; 6797639Sgblack@eecs.umich.edu default: 6807853SMatt.Horsnell@ARM.com // Bad size 6817853SMatt.Horsnell@ARM.com microOps[uopIdx++] = new Unknown(machInst); 6827639Sgblack@eecs.umich.edu break; 6837639Sgblack@eecs.umich.edu } 6847639Sgblack@eecs.umich.edu break; 6857639Sgblack@eecs.umich.edu case 3: 6867639Sgblack@eecs.umich.edu assert(regs == 3); 6877639Sgblack@eecs.umich.edu switch (size) { 6887639Sgblack@eecs.umich.edu case 0: 6897639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroPackNeon6to2Uop<uint8_t>( 6907639Sgblack@eecs.umich.edu machInst, ufp0, vd * 2, inc * 2, lane); 6917639Sgblack@eecs.umich.edu break; 6927639Sgblack@eecs.umich.edu case 1: 6937639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroPackNeon6to2Uop<uint16_t>( 6947639Sgblack@eecs.umich.edu machInst, ufp0, vd * 2, inc * 2, lane); 6957639Sgblack@eecs.umich.edu break; 6967639Sgblack@eecs.umich.edu case 2: 6977639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroPackNeon6to4Uop<uint32_t>( 6987639Sgblack@eecs.umich.edu machInst, ufp0, vd * 2, inc * 2, lane); 6997639Sgblack@eecs.umich.edu break; 7007639Sgblack@eecs.umich.edu default: 7017853SMatt.Horsnell@ARM.com // Bad size 7027853SMatt.Horsnell@ARM.com microOps[uopIdx++] = new Unknown(machInst); 7037639Sgblack@eecs.umich.edu break; 7047639Sgblack@eecs.umich.edu } 7057639Sgblack@eecs.umich.edu break; 7067639Sgblack@eecs.umich.edu case 2: 7077639Sgblack@eecs.umich.edu assert(regs == 2); 7087639Sgblack@eecs.umich.edu assert(storeRegs <= 2); 7097639Sgblack@eecs.umich.edu switch (size) { 7107639Sgblack@eecs.umich.edu case 0: 7117639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroPackNeon4to2Uop<uint8_t>( 7127639Sgblack@eecs.umich.edu machInst, ufp0, vd * 2, inc * 2, lane); 7137639Sgblack@eecs.umich.edu break; 7147639Sgblack@eecs.umich.edu case 1: 7157639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroPackNeon4to2Uop<uint16_t>( 7167639Sgblack@eecs.umich.edu machInst, ufp0, vd * 2, inc * 2, lane); 7177639Sgblack@eecs.umich.edu break; 7187639Sgblack@eecs.umich.edu case 2: 7197639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroPackNeon4to2Uop<uint32_t>( 7207639Sgblack@eecs.umich.edu machInst, ufp0, vd * 2, inc * 2, lane); 7217639Sgblack@eecs.umich.edu break; 7227639Sgblack@eecs.umich.edu default: 7237853SMatt.Horsnell@ARM.com // Bad size 7247853SMatt.Horsnell@ARM.com microOps[uopIdx++] = new Unknown(machInst); 7257639Sgblack@eecs.umich.edu break; 7267639Sgblack@eecs.umich.edu } 7277639Sgblack@eecs.umich.edu break; 7287639Sgblack@eecs.umich.edu case 1: 7297639Sgblack@eecs.umich.edu assert(regs == 1 || (all && regs == 2)); 7307639Sgblack@eecs.umich.edu assert(storeRegs <= 2); 7317639Sgblack@eecs.umich.edu for (unsigned offset = 0; offset < regs; offset++) { 7327639Sgblack@eecs.umich.edu switch (size) { 7337639Sgblack@eecs.umich.edu case 0: 7347639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroPackNeon2to2Uop<uint8_t>( 7357639Sgblack@eecs.umich.edu machInst, ufp0, (vd + offset) * 2, inc * 2, lane); 7367639Sgblack@eecs.umich.edu break; 7377639Sgblack@eecs.umich.edu case 1: 7387639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroPackNeon2to2Uop<uint16_t>( 7397639Sgblack@eecs.umich.edu machInst, ufp0, (vd + offset) * 2, inc * 2, lane); 7407639Sgblack@eecs.umich.edu break; 7417639Sgblack@eecs.umich.edu case 2: 7427639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroPackNeon2to2Uop<uint32_t>( 7437639Sgblack@eecs.umich.edu machInst, ufp0, (vd + offset) * 2, inc * 2, lane); 7447639Sgblack@eecs.umich.edu break; 7457639Sgblack@eecs.umich.edu default: 7467853SMatt.Horsnell@ARM.com // Bad size 7477853SMatt.Horsnell@ARM.com microOps[uopIdx++] = new Unknown(machInst); 7487639Sgblack@eecs.umich.edu break; 7497639Sgblack@eecs.umich.edu } 7507639Sgblack@eecs.umich.edu } 7517639Sgblack@eecs.umich.edu break; 7527639Sgblack@eecs.umich.edu default: 7537853SMatt.Horsnell@ARM.com // Bad number of elements to unpack 7547853SMatt.Horsnell@ARM.com microOps[uopIdx++] = new Unknown(machInst); 7557639Sgblack@eecs.umich.edu } 7567639Sgblack@eecs.umich.edu switch (storeSize) { 7577639Sgblack@eecs.umich.edu case 1: 7587639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroStrNeon1Uop<uint8_t>( 7597639Sgblack@eecs.umich.edu machInst, ufp0, rn, 0, align); 7607639Sgblack@eecs.umich.edu break; 7617639Sgblack@eecs.umich.edu case 2: 7627639Sgblack@eecs.umich.edu if (eBytes == 2) { 7637639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroStrNeon2Uop<uint16_t>( 7647639Sgblack@eecs.umich.edu machInst, ufp0, rn, 0, align); 7657639Sgblack@eecs.umich.edu } else { 7667639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroStrNeon2Uop<uint8_t>( 7677639Sgblack@eecs.umich.edu machInst, ufp0, rn, 0, align); 7687639Sgblack@eecs.umich.edu } 7697639Sgblack@eecs.umich.edu break; 7707639Sgblack@eecs.umich.edu case 3: 7717639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroStrNeon3Uop<uint8_t>( 7727639Sgblack@eecs.umich.edu machInst, ufp0, rn, 0, align); 7737639Sgblack@eecs.umich.edu break; 7747639Sgblack@eecs.umich.edu case 4: 7757639Sgblack@eecs.umich.edu switch (eBytes) { 7767639Sgblack@eecs.umich.edu case 1: 7777639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroStrNeon4Uop<uint8_t>( 7787639Sgblack@eecs.umich.edu machInst, ufp0, rn, 0, align); 7797639Sgblack@eecs.umich.edu break; 7807639Sgblack@eecs.umich.edu case 2: 7817639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroStrNeon4Uop<uint16_t>( 7827639Sgblack@eecs.umich.edu machInst, ufp0, rn, 0, align); 7837639Sgblack@eecs.umich.edu break; 7847639Sgblack@eecs.umich.edu case 4: 7857639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroStrNeon4Uop<uint32_t>( 7867639Sgblack@eecs.umich.edu machInst, ufp0, rn, 0, align); 7877639Sgblack@eecs.umich.edu break; 7887639Sgblack@eecs.umich.edu } 7897639Sgblack@eecs.umich.edu break; 7907639Sgblack@eecs.umich.edu case 6: 7917639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroStrNeon6Uop<uint16_t>( 7927639Sgblack@eecs.umich.edu machInst, ufp0, rn, 0, align); 7937639Sgblack@eecs.umich.edu break; 7947639Sgblack@eecs.umich.edu case 8: 7957639Sgblack@eecs.umich.edu switch (eBytes) { 7967639Sgblack@eecs.umich.edu case 2: 7977639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroStrNeon8Uop<uint16_t>( 7987639Sgblack@eecs.umich.edu machInst, ufp0, rn, 0, align); 7997639Sgblack@eecs.umich.edu break; 8007639Sgblack@eecs.umich.edu case 4: 8017639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroStrNeon8Uop<uint32_t>( 8027639Sgblack@eecs.umich.edu machInst, ufp0, rn, 0, align); 8037639Sgblack@eecs.umich.edu break; 8047639Sgblack@eecs.umich.edu } 8057639Sgblack@eecs.umich.edu break; 8067639Sgblack@eecs.umich.edu case 12: 8077639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroStrNeon12Uop<uint32_t>( 8087639Sgblack@eecs.umich.edu machInst, ufp0, rn, 0, align); 8097639Sgblack@eecs.umich.edu break; 8107639Sgblack@eecs.umich.edu case 16: 8117639Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroStrNeon16Uop<uint32_t>( 8127639Sgblack@eecs.umich.edu machInst, ufp0, rn, 0, align); 8137639Sgblack@eecs.umich.edu break; 8147639Sgblack@eecs.umich.edu default: 8157853SMatt.Horsnell@ARM.com // Bad store size 8167853SMatt.Horsnell@ARM.com microOps[uopIdx++] = new Unknown(machInst); 8177639Sgblack@eecs.umich.edu } 8187639Sgblack@eecs.umich.edu if (wb) { 8197639Sgblack@eecs.umich.edu if (rm != 15 && rm != 13) { 8207639Sgblack@eecs.umich.edu microOps[uopIdx++] = 8217646Sgene.wu@arm.com new MicroAddUop(machInst, rn, rn, rm, 0, ArmISA::LSL); 8227639Sgblack@eecs.umich.edu } else { 8237639Sgblack@eecs.umich.edu microOps[uopIdx++] = 8247639Sgblack@eecs.umich.edu new MicroAddiUop(machInst, rn, rn, storeSize); 8257639Sgblack@eecs.umich.edu } 8267639Sgblack@eecs.umich.edu } 8277639Sgblack@eecs.umich.edu assert(uopIdx == numMicroops); 8287639Sgblack@eecs.umich.edu 8297639Sgblack@eecs.umich.edu for (unsigned i = 0; i < numMicroops - 1; i++) { 8307639Sgblack@eecs.umich.edu MicroOp * uopPtr = dynamic_cast<MicroOp *>(microOps[i].get()); 8317639Sgblack@eecs.umich.edu assert(uopPtr); 8327639Sgblack@eecs.umich.edu uopPtr->setDelayedCommit(); 8337639Sgblack@eecs.umich.edu } 8347639Sgblack@eecs.umich.edu microOps[numMicroops - 1]->setLastMicroop(); 8357639Sgblack@eecs.umich.edu} 8367639Sgblack@eecs.umich.edu 8377175Sgblack@eecs.umich.eduMacroVFPMemOp::MacroVFPMemOp(const char *mnem, ExtMachInst machInst, 8387175Sgblack@eecs.umich.edu OpClass __opClass, IntRegIndex rn, 8397175Sgblack@eecs.umich.edu RegIndex vd, bool single, bool up, 8407175Sgblack@eecs.umich.edu bool writeback, bool load, uint32_t offset) : 8417175Sgblack@eecs.umich.edu PredMacroOp(mnem, machInst, __opClass) 8427175Sgblack@eecs.umich.edu{ 8437175Sgblack@eecs.umich.edu int i = 0; 8447175Sgblack@eecs.umich.edu 8457175Sgblack@eecs.umich.edu // The lowest order bit selects fldmx (set) or fldmd (clear). These seem 8467175Sgblack@eecs.umich.edu // to be functionally identical except that fldmx is deprecated. For now 8477175Sgblack@eecs.umich.edu // we'll assume they're otherwise interchangable. 8487175Sgblack@eecs.umich.edu int count = (single ? offset : (offset / 2)); 8497175Sgblack@eecs.umich.edu if (count == 0 || count > NumFloatArchRegs) 8507175Sgblack@eecs.umich.edu warn_once("Bad offset field for VFP load/store multiple.\n"); 8517175Sgblack@eecs.umich.edu if (count == 0) { 8527175Sgblack@eecs.umich.edu // Force there to be at least one microop so the macroop makes sense. 8537175Sgblack@eecs.umich.edu writeback = true; 8547175Sgblack@eecs.umich.edu } 8557175Sgblack@eecs.umich.edu if (count > NumFloatArchRegs) 8567175Sgblack@eecs.umich.edu count = NumFloatArchRegs; 8577175Sgblack@eecs.umich.edu 8587342Sgblack@eecs.umich.edu numMicroops = count * (single ? 1 : 2) + (writeback ? 1 : 0); 8597342Sgblack@eecs.umich.edu microOps = new StaticInstPtr[numMicroops]; 8607342Sgblack@eecs.umich.edu 8617395Sgblack@eecs.umich.edu int64_t addr = 0; 8627175Sgblack@eecs.umich.edu 8637342Sgblack@eecs.umich.edu if (!up) 8647342Sgblack@eecs.umich.edu addr = 4 * offset; 8657175Sgblack@eecs.umich.edu 8667342Sgblack@eecs.umich.edu bool tempUp = up; 8677175Sgblack@eecs.umich.edu for (int j = 0; j < count; j++) { 8687175Sgblack@eecs.umich.edu if (load) { 8697639Sgblack@eecs.umich.edu if (single) { 8707639Sgblack@eecs.umich.edu microOps[i++] = new MicroLdrFpUop(machInst, vd++, rn, 8717639Sgblack@eecs.umich.edu tempUp, addr); 8727639Sgblack@eecs.umich.edu } else { 8737639Sgblack@eecs.umich.edu microOps[i++] = new MicroLdrDBFpUop(machInst, vd++, rn, 8747639Sgblack@eecs.umich.edu tempUp, addr); 8757639Sgblack@eecs.umich.edu microOps[i++] = new MicroLdrDTFpUop(machInst, vd++, rn, tempUp, 8767639Sgblack@eecs.umich.edu addr + (up ? 4 : -4)); 8777639Sgblack@eecs.umich.edu } 8787175Sgblack@eecs.umich.edu } else { 8797639Sgblack@eecs.umich.edu if (single) { 8807639Sgblack@eecs.umich.edu microOps[i++] = new MicroStrFpUop(machInst, vd++, rn, 8817639Sgblack@eecs.umich.edu tempUp, addr); 8827639Sgblack@eecs.umich.edu } else { 8837639Sgblack@eecs.umich.edu microOps[i++] = new MicroStrDBFpUop(machInst, vd++, rn, 8847639Sgblack@eecs.umich.edu tempUp, addr); 8857639Sgblack@eecs.umich.edu microOps[i++] = new MicroStrDTFpUop(machInst, vd++, rn, tempUp, 8867639Sgblack@eecs.umich.edu addr + (up ? 4 : -4)); 8877639Sgblack@eecs.umich.edu } 8887175Sgblack@eecs.umich.edu } 8897342Sgblack@eecs.umich.edu if (!tempUp) { 8907342Sgblack@eecs.umich.edu addr -= (single ? 4 : 8); 8917342Sgblack@eecs.umich.edu // The microops don't handle negative displacement, so turn if we 8927342Sgblack@eecs.umich.edu // hit zero, flip polarity and start adding. 8937395Sgblack@eecs.umich.edu if (addr <= 0) { 8947342Sgblack@eecs.umich.edu tempUp = true; 8957395Sgblack@eecs.umich.edu addr = -addr; 8967342Sgblack@eecs.umich.edu } 8977342Sgblack@eecs.umich.edu } else { 8987342Sgblack@eecs.umich.edu addr += (single ? 4 : 8); 8997342Sgblack@eecs.umich.edu } 9007175Sgblack@eecs.umich.edu } 9017175Sgblack@eecs.umich.edu 9027175Sgblack@eecs.umich.edu if (writeback) { 9037175Sgblack@eecs.umich.edu if (up) { 9047175Sgblack@eecs.umich.edu microOps[i++] = 9057175Sgblack@eecs.umich.edu new MicroAddiUop(machInst, rn, rn, 4 * offset); 9067175Sgblack@eecs.umich.edu } else { 9077175Sgblack@eecs.umich.edu microOps[i++] = 9087175Sgblack@eecs.umich.edu new MicroSubiUop(machInst, rn, rn, 4 * offset); 9097175Sgblack@eecs.umich.edu } 9107175Sgblack@eecs.umich.edu } 9117175Sgblack@eecs.umich.edu 9127342Sgblack@eecs.umich.edu assert(numMicroops == i); 9137175Sgblack@eecs.umich.edu microOps[numMicroops - 1]->setLastMicroop(); 9147343Sgblack@eecs.umich.edu 9157343Sgblack@eecs.umich.edu for (StaticInstPtr *curUop = microOps; 9167343Sgblack@eecs.umich.edu !(*curUop)->isLastMicroop(); curUop++) { 9177343Sgblack@eecs.umich.edu MicroOp * uopPtr = dynamic_cast<MicroOp *>(curUop->get()); 9187343Sgblack@eecs.umich.edu assert(uopPtr); 9197343Sgblack@eecs.umich.edu uopPtr->setDelayedCommit(); 9207343Sgblack@eecs.umich.edu } 9217170Sgblack@eecs.umich.edu} 9227175Sgblack@eecs.umich.edu 9237615Sminkyu.jeong@arm.comstd::string 9247639Sgblack@eecs.umich.eduMicroIntImmOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const 9257639Sgblack@eecs.umich.edu{ 9267639Sgblack@eecs.umich.edu std::stringstream ss; 9277639Sgblack@eecs.umich.edu printMnemonic(ss); 9287639Sgblack@eecs.umich.edu printReg(ss, ura); 9297639Sgblack@eecs.umich.edu ss << ", "; 9307639Sgblack@eecs.umich.edu printReg(ss, urb); 9317639Sgblack@eecs.umich.edu ss << ", "; 9327639Sgblack@eecs.umich.edu ccprintf(ss, "#%d", imm); 9337639Sgblack@eecs.umich.edu return ss.str(); 9347639Sgblack@eecs.umich.edu} 9357639Sgblack@eecs.umich.edu 9367639Sgblack@eecs.umich.edustd::string 9378140SMatt.Horsnell@arm.comMicroSetPCCPSR::generateDisassembly(Addr pc, const SymbolTable *symtab) const 9388140SMatt.Horsnell@arm.com{ 9398140SMatt.Horsnell@arm.com std::stringstream ss; 9408140SMatt.Horsnell@arm.com printMnemonic(ss); 9418140SMatt.Horsnell@arm.com ss << "[PC,CPSR]"; 9428140SMatt.Horsnell@arm.com return ss.str(); 9438140SMatt.Horsnell@arm.com} 9448140SMatt.Horsnell@arm.com 9458140SMatt.Horsnell@arm.comstd::string 9467646Sgene.wu@arm.comMicroIntMov::generateDisassembly(Addr pc, const SymbolTable *symtab) const 9477646Sgene.wu@arm.com{ 9487646Sgene.wu@arm.com std::stringstream ss; 9497646Sgene.wu@arm.com printMnemonic(ss); 9507646Sgene.wu@arm.com printReg(ss, ura); 9517646Sgene.wu@arm.com ss << ", "; 9527646Sgene.wu@arm.com printReg(ss, urb); 9537646Sgene.wu@arm.com return ss.str(); 9547646Sgene.wu@arm.com} 9557646Sgene.wu@arm.com 9567646Sgene.wu@arm.comstd::string 9577615Sminkyu.jeong@arm.comMicroIntOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const 9587615Sminkyu.jeong@arm.com{ 9597615Sminkyu.jeong@arm.com std::stringstream ss; 9607615Sminkyu.jeong@arm.com printMnemonic(ss); 9617615Sminkyu.jeong@arm.com printReg(ss, ura); 9627615Sminkyu.jeong@arm.com ss << ", "; 9637615Sminkyu.jeong@arm.com printReg(ss, urb); 9647615Sminkyu.jeong@arm.com ss << ", "; 9657639Sgblack@eecs.umich.edu printReg(ss, urc); 9667615Sminkyu.jeong@arm.com return ss.str(); 9677175Sgblack@eecs.umich.edu} 9687615Sminkyu.jeong@arm.com 9697615Sminkyu.jeong@arm.comstd::string 9707615Sminkyu.jeong@arm.comMicroMemOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const 9717615Sminkyu.jeong@arm.com{ 9727615Sminkyu.jeong@arm.com std::stringstream ss; 9737615Sminkyu.jeong@arm.com printMnemonic(ss); 9747615Sminkyu.jeong@arm.com printReg(ss, ura); 9757615Sminkyu.jeong@arm.com ss << ", ["; 9767615Sminkyu.jeong@arm.com printReg(ss, urb); 9777615Sminkyu.jeong@arm.com ss << ", "; 9787615Sminkyu.jeong@arm.com ccprintf(ss, "#%d", imm); 9797615Sminkyu.jeong@arm.com ss << "]"; 9807615Sminkyu.jeong@arm.com return ss.str(); 9817615Sminkyu.jeong@arm.com} 9827615Sminkyu.jeong@arm.com 9837615Sminkyu.jeong@arm.com} 984