macromem.cc revision 10199
1360SN/A/* 210850SGiacomo.Gabrielli@arm.com * Copyright (c) 2010-2013 ARM Limited 310796Sbrandon.potter@amd.com * All rights reserved 410027SChris.Adeniyi-Jones@arm.com * 510027SChris.Adeniyi-Jones@arm.com * The license below extends only to copyright in the software and shall 610027SChris.Adeniyi-Jones@arm.com * not be construed as granting a license to any other intellectual 710027SChris.Adeniyi-Jones@arm.com * property including but not limited to intellectual property relating 810027SChris.Adeniyi-Jones@arm.com * to a hardware implementation of the functionality of the software 910027SChris.Adeniyi-Jones@arm.com * licensed hereunder. You may use the software subject to the license 1010027SChris.Adeniyi-Jones@arm.com * terms below provided that you ensure that this notice is replicated 1110027SChris.Adeniyi-Jones@arm.com * unmodified and in its entirety in all distributions of the software, 1210027SChris.Adeniyi-Jones@arm.com * modified or unmodified, in source code or in binary form. 1310027SChris.Adeniyi-Jones@arm.com * 1410027SChris.Adeniyi-Jones@arm.com * Copyright (c) 2007-2008 The Florida State University 151458SN/A * All rights reserved. 16360SN/A * 17360SN/A * Redistribution and use in source and binary forms, with or without 18360SN/A * modification, are permitted provided that the following conditions are 19360SN/A * met: redistributions of source code must retain the above copyright 20360SN/A * notice, this list of conditions and the following disclaimer; 21360SN/A * redistributions in binary form must reproduce the above copyright 22360SN/A * notice, this list of conditions and the following disclaimer in the 23360SN/A * documentation and/or other materials provided with the distribution; 24360SN/A * neither the name of the copyright holders nor the names of its 25360SN/A * contributors may be used to endorse or promote products derived from 26360SN/A * this software without specific prior written permission. 27360SN/A * 28360SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 29360SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 30360SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 31360SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 32360SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 33360SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 34360SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 35360SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 36360SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 37360SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 38360SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 39360SN/A * 402665Ssaidi@eecs.umich.edu * Authors: Stephen Hines 412665Ssaidi@eecs.umich.edu */ 422665Ssaidi@eecs.umich.edu 43360SN/A#include <sstream> 44360SN/A 451354SN/A#include "arch/arm/insts/macromem.hh" 461354SN/A 47360SN/A#include "arch/arm/generated/decoder.hh" 4812018Sandreas.sandberg@arm.com#include "arch/arm/insts/neon64_mem.hh" 4912018Sandreas.sandberg@arm.com 5012018Sandreas.sandberg@arm.comusing namespace std; 5112018Sandreas.sandberg@arm.comusing namespace ArmISAInst; 5212018Sandreas.sandberg@arm.com 5312018Sandreas.sandberg@arm.comnamespace ArmISA 5412018Sandreas.sandberg@arm.com{ 552064SN/A 5612018Sandreas.sandberg@arm.comMacroMemOp::MacroMemOp(const char *mnem, ExtMachInst machInst, 5712018Sandreas.sandberg@arm.com OpClass __opClass, IntRegIndex rn, 5812018Sandreas.sandberg@arm.com bool index, bool up, bool user, bool writeback, 5912018Sandreas.sandberg@arm.com bool load, uint32_t reglist) : 6012018Sandreas.sandberg@arm.com PredMacroOp(mnem, machInst, __opClass) 6112018Sandreas.sandberg@arm.com{ 6211799Sbrandon.potter@amd.com uint32_t regs = reglist; 6312018Sandreas.sandberg@arm.com uint32_t ones = number_of_ones(reglist); 6412018Sandreas.sandberg@arm.com // Remember that writeback adds a uop or two and the temp register adds one 6512018Sandreas.sandberg@arm.com numMicroops = ones + (writeback ? (load ? 2 : 1) : 0) + 1; 6612018Sandreas.sandberg@arm.com 6712018Sandreas.sandberg@arm.com // It's technically legal to do a lot of nothing 6812018Sandreas.sandberg@arm.com if (!ones) 6911799Sbrandon.potter@amd.com numMicroops = 1; 70360SN/A 71360SN/A microOps = new StaticInstPtr[numMicroops]; 72360SN/A uint32_t addr = 0; 73360SN/A 74360SN/A if (!up) 75360SN/A addr = (ones << 2) - 4; 761809SN/A 7711800Sbrandon.potter@amd.com if (!index) 7811392Sbrandon.potter@amd.com addr += 4; 791809SN/A 8011392Sbrandon.potter@amd.com StaticInstPtr *uop = microOps; 8111383Sbrandon.potter@amd.com 823113Sgblack@eecs.umich.edu // Add 0 to Rn and stick it in ureg0. 8311799Sbrandon.potter@amd.com // This is equivalent to a move. 8411759Sbrandon.potter@amd.com *uop = new MicroAddiUop(machInst, INTREG_UREG0, rn, 0); 8511812Sbaz21@cam.ac.uk 8611812Sbaz21@cam.ac.uk unsigned reg = 0; 8711799Sbrandon.potter@amd.com unsigned regIdx = 0; 888229Snate@binkert.org bool force_user = user & !bits(reglist, 15); 898229Snate@binkert.org bool exception_ret = user & bits(reglist, 15); 9011594Santhony.gutierrez@amd.com 917075Snate@binkert.org for (int i = 0; i < ones; i++) { 928229Snate@binkert.org // Find the next register. 9311856Sbrandon.potter@amd.com while (!bits(regs, reg)) 947075Snate@binkert.org reg++; 95360SN/A replaceBits(regs, reg, 0); 9611886Sbrandon.potter@amd.com 9711800Sbrandon.potter@amd.com regIdx = reg; 9811392Sbrandon.potter@amd.com if (force_user) { 992462SN/A regIdx = intRegInMode(MODE_USER, regIdx); 1001354SN/A } 1016216Snate@binkert.org 1026658Snate@binkert.org if (load) { 1032474SN/A if (writeback && i == ones - 1) { 1042680Sktlim@umich.edu // If it's a writeback and this is the last register 1058229Snate@binkert.org // do the load into a temporary register which we'll move 10611886Sbrandon.potter@amd.com // into the final one later 10710496Ssteve.reinhardt@amd.com *++uop = new MicroLdrUop(machInst, INTREG_UREG1, INTREG_UREG0, 10811911SBrandon.Potter@amd.com up, addr); 1098229Snate@binkert.org } else { 11011794Sbrandon.potter@amd.com // Otherwise just do it normally 11111886Sbrandon.potter@amd.com if (reg == INTREG_PC && exception_ret) { 11210497Ssteve.reinhardt@amd.com // This must be the exception return form of ldm. 11311794Sbrandon.potter@amd.com *++uop = new MicroLdrRetUop(machInst, regIdx, 114360SN/A INTREG_UREG0, up, addr); 115360SN/A if (!(condCode == COND_AL || condCode == COND_UC)) 116360SN/A (*uop)->setFlag(StaticInst::IsCondControl); 117360SN/A else 118360SN/A (*uop)->setFlag(StaticInst::IsUncondControl); 119360SN/A } else { 120360SN/A *++uop = new MicroLdrUop(machInst, regIdx, 121360SN/A INTREG_UREG0, up, addr); 122360SN/A if (reg == INTREG_PC) { 123360SN/A (*uop)->setFlag(StaticInst::IsControl); 124378SN/A if (!(condCode == COND_AL || condCode == COND_UC)) 1251706SN/A (*uop)->setFlag(StaticInst::IsCondControl); 12611851Sbrandon.potter@amd.com else 127378SN/A (*uop)->setFlag(StaticInst::IsUncondControl); 128378SN/A (*uop)->setFlag(StaticInst::IsIndirectControl); 129378SN/A } 130378SN/A } 131378SN/A } 1321706SN/A } else { 13311851Sbrandon.potter@amd.com *++uop = new MicroStrUop(machInst, regIdx, INTREG_UREG0, up, addr); 134360SN/A } 13511760Sbrandon.potter@amd.com 13611760Sbrandon.potter@amd.com if (up) 13711851Sbrandon.potter@amd.com addr += 4; 13811760Sbrandon.potter@amd.com else 1396109Ssanchezd@stanford.edu addr -= 4; 1401706SN/A } 14111851Sbrandon.potter@amd.com 142378SN/A if (writeback && ones) { 1436109Ssanchezd@stanford.edu // put the register update after we're done all loading 1446109Ssanchezd@stanford.edu if (up) 14511851Sbrandon.potter@amd.com *++uop = new MicroAddiUop(machInst, rn, rn, ones * 4); 1466109Ssanchezd@stanford.edu else 14711886Sbrandon.potter@amd.com *++uop = new MicroSubiUop(machInst, rn, rn, ones * 4); 14811886Sbrandon.potter@amd.com 14911886Sbrandon.potter@amd.com // If this was a load move the last temporary value into place 15011886Sbrandon.potter@amd.com // this way we can't take an exception after we update the base 151378SN/A // register. 1521706SN/A if (load && reg == INTREG_PC && exception_ret) { 15311851Sbrandon.potter@amd.com *++uop = new MicroUopRegMovRet(machInst, 0, INTREG_UREG1); 154378SN/A if (!(condCode == COND_AL || condCode == COND_UC)) 1555748SSteve.Reinhardt@amd.com (*uop)->setFlag(StaticInst::IsCondControl); 1565748SSteve.Reinhardt@amd.com else 15711851Sbrandon.potter@amd.com (*uop)->setFlag(StaticInst::IsUncondControl); 158378SN/A } else if (load) { 159378SN/A *++uop = new MicroUopRegMov(machInst, regIdx, INTREG_UREG1); 1601706SN/A if (reg == INTREG_PC) { 16111851Sbrandon.potter@amd.com (*uop)->setFlag(StaticInst::IsControl); 162378SN/A (*uop)->setFlag(StaticInst::IsCondControl); 16311886Sbrandon.potter@amd.com (*uop)->setFlag(StaticInst::IsIndirectControl); 1641706SN/A // This is created as a RAS POP 16511851Sbrandon.potter@amd.com if (rn == INTREG_SP) 166378SN/A (*uop)->setFlag(StaticInst::IsReturn); 167378SN/A 1681706SN/A } 16911851Sbrandon.potter@amd.com } 170378SN/A } 171378SN/A 1721706SN/A (*uop)->setLastMicroop(); 17311851Sbrandon.potter@amd.com 174378SN/A /* Take the control flags from the last microop for the macroop */ 1754118Sgblack@eecs.umich.edu if ((*uop)->isControl()) 1764118Sgblack@eecs.umich.edu setFlag(StaticInst::IsControl); 17711851Sbrandon.potter@amd.com if ((*uop)->isCondCtrl()) 1784118Sgblack@eecs.umich.edu setFlag(StaticInst::IsCondControl); 179378SN/A if ((*uop)->isIndirectCtrl()) 1801706SN/A setFlag(StaticInst::IsIndirectControl); 18111851Sbrandon.potter@amd.com if ((*uop)->isReturn()) 182378SN/A setFlag(StaticInst::IsReturn); 183378SN/A 1841706SN/A for (StaticInstPtr *curUop = microOps; 18511851Sbrandon.potter@amd.com !(*curUop)->isLastMicroop(); curUop++) { 186360SN/A MicroOp * uopPtr = dynamic_cast<MicroOp *>(curUop->get()); 1875513SMichael.Adler@intel.com assert(uopPtr); 1885513SMichael.Adler@intel.com uopPtr->setDelayedCommit(); 18911851Sbrandon.potter@amd.com } 1905513SMichael.Adler@intel.com} 19110203SAli.Saidi@ARM.com 19210203SAli.Saidi@ARM.comPairMemOp::PairMemOp(const char *mnem, ExtMachInst machInst, OpClass __opClass, 19311851Sbrandon.potter@amd.com uint32_t size, bool fp, bool load, bool noAlloc, 19410203SAli.Saidi@ARM.com bool signExt, bool exclusive, bool acrel, 1955513SMichael.Adler@intel.com int64_t imm, AddrMode mode, 19611851Sbrandon.potter@amd.com IntRegIndex rn, IntRegIndex rt, IntRegIndex rt2) : 1975513SMichael.Adler@intel.com PredMacroOp(mnem, machInst, __opClass) 198511SN/A{ 19910633Smichaelupton@gmail.com bool writeback = (mode != AddrMd_Offset); 20011851Sbrandon.potter@amd.com numMicroops = 1 + (size / 4) + (writeback ? 1 : 0); 20110633Smichaelupton@gmail.com microOps = new StaticInstPtr[numMicroops]; 2021706SN/A 20311851Sbrandon.potter@amd.com StaticInstPtr *uop = microOps; 204511SN/A 2055513SMichael.Adler@intel.com bool post = (mode == AddrMd_PostIndex); 2065513SMichael.Adler@intel.com 20711851Sbrandon.potter@amd.com rn = makeSP(rn); 2085513SMichael.Adler@intel.com 209511SN/A *uop = new MicroAddXiSpAlignUop(machInst, INTREG_UREG0, rn, post ? 0 : imm); 2101706SN/A 21111851Sbrandon.potter@amd.com if (fp) { 2121706SN/A if (size == 16) { 2131706SN/A if (load) { 2141706SN/A *++uop = new MicroLdrQBFpXImmUop(machInst, rt, 2151706SN/A INTREG_UREG0, 0, noAlloc, exclusive, acrel); 21611851Sbrandon.potter@amd.com *++uop = new MicroLdrQTFpXImmUop(machInst, rt, 2171706SN/A INTREG_UREG0, 0, noAlloc, exclusive, acrel); 2181706SN/A *++uop = new MicroLdrQBFpXImmUop(machInst, rt2, 2191706SN/A INTREG_UREG0, 16, noAlloc, exclusive, acrel); 2201706SN/A *++uop = new MicroLdrQTFpXImmUop(machInst, rt2, 22111851Sbrandon.potter@amd.com INTREG_UREG0, 16, noAlloc, exclusive, acrel); 2221706SN/A } else { 223511SN/A *++uop = new MicroStrQBFpXImmUop(machInst, rt, 2246703Svince@csl.cornell.edu INTREG_UREG0, 0, noAlloc, exclusive, acrel); 2256703Svince@csl.cornell.edu *++uop = new MicroStrQTFpXImmUop(machInst, rt, 22611851Sbrandon.potter@amd.com INTREG_UREG0, 0, noAlloc, exclusive, acrel); 2276703Svince@csl.cornell.edu *++uop = new MicroStrQBFpXImmUop(machInst, rt2, 2286685Stjones1@inf.ed.ac.uk INTREG_UREG0, 16, noAlloc, exclusive, acrel); 2296685Stjones1@inf.ed.ac.uk *++uop = new MicroStrQTFpXImmUop(machInst, rt2, 23011851Sbrandon.potter@amd.com INTREG_UREG0, 16, noAlloc, exclusive, acrel); 2316685Stjones1@inf.ed.ac.uk } 2326685Stjones1@inf.ed.ac.uk } else if (size == 8) { 2335513SMichael.Adler@intel.com if (load) { 2345513SMichael.Adler@intel.com *++uop = new MicroLdrFpXImmUop(machInst, rt, 23511851Sbrandon.potter@amd.com INTREG_UREG0, 0, noAlloc, exclusive, acrel); 2365513SMichael.Adler@intel.com *++uop = new MicroLdrFpXImmUop(machInst, rt2, 23711885Sbrandon.potter@amd.com INTREG_UREG0, 8, noAlloc, exclusive, acrel); 23811885Sbrandon.potter@amd.com } else { 23911885Sbrandon.potter@amd.com *++uop = new MicroStrFpXImmUop(machInst, rt, 2405513SMichael.Adler@intel.com INTREG_UREG0, 0, noAlloc, exclusive, acrel); 2411999SN/A *++uop = new MicroStrFpXImmUop(machInst, rt2, 2421999SN/A INTREG_UREG0, 8, noAlloc, exclusive, acrel); 24311851Sbrandon.potter@amd.com } 2441999SN/A } else if (size == 4) { 24511885Sbrandon.potter@amd.com if (load) { 24611885Sbrandon.potter@amd.com *++uop = new MicroLdrDFpXImmUop(machInst, rt, rt2, 24711885Sbrandon.potter@amd.com INTREG_UREG0, 0, noAlloc, exclusive, acrel); 2481999SN/A } else { 2491999SN/A *++uop = new MicroStrDFpXImmUop(machInst, rt, rt2, 2501999SN/A INTREG_UREG0, 0, noAlloc, exclusive, acrel); 25111851Sbrandon.potter@amd.com } 2521999SN/A } 2533079Sstever@eecs.umich.edu } else { 2543079Sstever@eecs.umich.edu if (size == 8) { 25511851Sbrandon.potter@amd.com if (load) { 2563079Sstever@eecs.umich.edu *++uop = new MicroLdrXImmUop(machInst, rt, INTREG_UREG0, 25711908SBrandon.Potter@amd.com 0, noAlloc, exclusive, acrel); 25811908SBrandon.Potter@amd.com *++uop = new MicroLdrXImmUop(machInst, rt2, INTREG_UREG0, 25911908SBrandon.Potter@amd.com size, noAlloc, exclusive, acrel); 26011908SBrandon.Potter@amd.com } else { 26111875Sbrandon.potter@amd.com *++uop = new MicroStrXImmUop(machInst, rt, INTREG_UREG0, 2622093SN/A 0, noAlloc, exclusive, acrel); 26311851Sbrandon.potter@amd.com *++uop = new MicroStrXImmUop(machInst, rt2, INTREG_UREG0, 2642093SN/A size, noAlloc, exclusive, acrel); 2652687Sksewell@umich.edu } 2662687Sksewell@umich.edu } else if (size == 4) { 26711851Sbrandon.potter@amd.com if (load) { 2682687Sksewell@umich.edu if (signExt) { 2692238SN/A *++uop = new MicroLdrDSXImmUop(machInst, rt, rt2, 2702238SN/A INTREG_UREG0, 0, noAlloc, exclusive, acrel); 27111851Sbrandon.potter@amd.com } else { 2722238SN/A *++uop = new MicroLdrDUXImmUop(machInst, rt, rt2, 27311908SBrandon.Potter@amd.com INTREG_UREG0, 0, noAlloc, exclusive, acrel); 27411908SBrandon.Potter@amd.com } 27511908SBrandon.Potter@amd.com } else { 27611908SBrandon.Potter@amd.com *++uop = new MicroStrDXImmUop(machInst, rt, rt2, 27711908SBrandon.Potter@amd.com INTREG_UREG0, 0, noAlloc, exclusive, acrel); 27811908SBrandon.Potter@amd.com } 27911908SBrandon.Potter@amd.com } 28011908SBrandon.Potter@amd.com } 2812238SN/A 2822238SN/A if (writeback) { 28311851Sbrandon.potter@amd.com *++uop = new MicroAddXiUop(machInst, rn, INTREG_UREG0, 2842238SN/A post ? imm : 0); 2852238SN/A } 2862238SN/A 28711851Sbrandon.potter@amd.com (*uop)->setLastMicroop(); 2882238SN/A 2892238SN/A for (StaticInstPtr *curUop = microOps; 2902238SN/A !(*curUop)->isLastMicroop(); curUop++) { 29111851Sbrandon.potter@amd.com (*curUop)->setDelayedCommit(); 2922238SN/A } 2932238SN/A} 2942238SN/A 29511851Sbrandon.potter@amd.comBigFpMemImmOp::BigFpMemImmOp(const char *mnem, ExtMachInst machInst, 2962238SN/A OpClass __opClass, bool load, IntRegIndex dest, 2972238SN/A IntRegIndex base, int64_t imm) : 2982238SN/A PredMacroOp(mnem, machInst, __opClass) 29911851Sbrandon.potter@amd.com{ 3002238SN/A numMicroops = 2; 3012238SN/A microOps = new StaticInstPtr[numMicroops]; 3022238SN/A 30311851Sbrandon.potter@amd.com if (load) { 3042238SN/A microOps[0] = new MicroLdrQBFpXImmUop(machInst, dest, base, imm); 3059455Smitch.hayenga+gem5@gmail.com microOps[1] = new MicroLdrQTFpXImmUop(machInst, dest, base, imm); 3069455Smitch.hayenga+gem5@gmail.com } else { 30711851Sbrandon.potter@amd.com microOps[0] = new MicroStrQBFpXImmUop(machInst, dest, base, imm); 30810203SAli.Saidi@ARM.com microOps[1] = new MicroStrQTFpXImmUop(machInst, dest, base, imm); 30911851Sbrandon.potter@amd.com } 31011851Sbrandon.potter@amd.com microOps[0]->setDelayedCommit(); 3119455Smitch.hayenga+gem5@gmail.com microOps[1]->setLastMicroop(); 3129112Smarc.orr@gmail.com} 31311906SBrandon.Potter@amd.com 31411906SBrandon.Potter@amd.comBigFpMemPostOp::BigFpMemPostOp(const char *mnem, ExtMachInst machInst, 3159112Smarc.orr@gmail.com OpClass __opClass, bool load, IntRegIndex dest, 3169112Smarc.orr@gmail.com IntRegIndex base, int64_t imm) : 31711851Sbrandon.potter@amd.com PredMacroOp(mnem, machInst, __opClass) 3189112Smarc.orr@gmail.com{ 3199112Smarc.orr@gmail.com numMicroops = 3; 32011911SBrandon.Potter@amd.com microOps = new StaticInstPtr[numMicroops]; 3219112Smarc.orr@gmail.com 32211911SBrandon.Potter@amd.com if (load) { 32311911SBrandon.Potter@amd.com microOps[0] = new MicroLdrQBFpXImmUop(machInst, dest, base, 0); 32411911SBrandon.Potter@amd.com microOps[1] = new MicroLdrQTFpXImmUop(machInst, dest, base, 0); 32511911SBrandon.Potter@amd.com } else { 3269112Smarc.orr@gmail.com microOps[0] = new MicroStrQBFpXImmUop(machInst, dest, base, 0); 32711911SBrandon.Potter@amd.com microOps[1] = new MicroStrQTFpXImmUop(machInst, dest, base, 0); 32811911SBrandon.Potter@amd.com } 32911911SBrandon.Potter@amd.com microOps[2] = new MicroAddXiUop(machInst, base, base, imm); 33011911SBrandon.Potter@amd.com 3319238Slluc.alvarez@bsc.es microOps[0]->setDelayedCommit(); 3329112Smarc.orr@gmail.com microOps[1]->setDelayedCommit(); 33311911SBrandon.Potter@amd.com microOps[2]->setLastMicroop(); 3349112Smarc.orr@gmail.com} 33511911SBrandon.Potter@amd.com 33611911SBrandon.Potter@amd.comBigFpMemPreOp::BigFpMemPreOp(const char *mnem, ExtMachInst machInst, 33711911SBrandon.Potter@amd.com OpClass __opClass, bool load, IntRegIndex dest, 33811911SBrandon.Potter@amd.com IntRegIndex base, int64_t imm) : 33911911SBrandon.Potter@amd.com PredMacroOp(mnem, machInst, __opClass) 3409112Smarc.orr@gmail.com{ 34111911SBrandon.Potter@amd.com numMicroops = 3; 34211911SBrandon.Potter@amd.com microOps = new StaticInstPtr[numMicroops]; 34311911SBrandon.Potter@amd.com 34411911SBrandon.Potter@amd.com if (load) { 34511911SBrandon.Potter@amd.com microOps[0] = new MicroLdrQBFpXImmUop(machInst, dest, base, imm); 34611911SBrandon.Potter@amd.com microOps[1] = new MicroLdrQTFpXImmUop(machInst, dest, base, imm); 3479112Smarc.orr@gmail.com } else { 3489112Smarc.orr@gmail.com microOps[0] = new MicroStrQBFpXImmUop(machInst, dest, base, imm); 34911911SBrandon.Potter@amd.com microOps[1] = new MicroStrQTFpXImmUop(machInst, dest, base, imm); 35011911SBrandon.Potter@amd.com } 3519112Smarc.orr@gmail.com microOps[2] = new MicroAddXiUop(machInst, base, base, imm); 35211911SBrandon.Potter@amd.com 35311911SBrandon.Potter@amd.com microOps[0]->setDelayedCommit(); 3549112Smarc.orr@gmail.com microOps[1]->setDelayedCommit(); 3559112Smarc.orr@gmail.com microOps[2]->setLastMicroop(); 35611911SBrandon.Potter@amd.com} 35711911SBrandon.Potter@amd.com 3589112Smarc.orr@gmail.comBigFpMemRegOp::BigFpMemRegOp(const char *mnem, ExtMachInst machInst, 3599112Smarc.orr@gmail.com OpClass __opClass, bool load, IntRegIndex dest, 3602238SN/A IntRegIndex base, IntRegIndex offset, 3612238SN/A ArmExtendType type, int64_t imm) : 3622238SN/A PredMacroOp(mnem, machInst, __opClass) 3632238SN/A{ 36411851Sbrandon.potter@amd.com numMicroops = 2; 3652238SN/A microOps = new StaticInstPtr[numMicroops]; 3662238SN/A 3672238SN/A if (load) { 36811851Sbrandon.potter@amd.com microOps[0] = new MicroLdrQBFpXRegUop(machInst, dest, base, 3692238SN/A offset, type, imm); 3702238SN/A microOps[1] = new MicroLdrQTFpXRegUop(machInst, dest, base, 3712238SN/A offset, type, imm); 37211851Sbrandon.potter@amd.com } else { 3732238SN/A microOps[0] = new MicroStrQBFpXRegUop(machInst, dest, base, 3742238SN/A offset, type, imm); 3752238SN/A microOps[1] = new MicroStrQTFpXRegUop(machInst, dest, base, 37611851Sbrandon.potter@amd.com offset, type, imm); 3772238SN/A } 3782238SN/A 3791354SN/A microOps[0]->setDelayedCommit(); 3801354SN/A microOps[1]->setLastMicroop(); 38110796Sbrandon.potter@amd.com} 38210796Sbrandon.potter@amd.com 3831354SN/ABigFpMemLitOp::BigFpMemLitOp(const char *mnem, ExtMachInst machInst, 3841354SN/A OpClass __opClass, IntRegIndex dest, 3851354SN/A int64_t imm) : 3861354SN/A PredMacroOp(mnem, machInst, __opClass) 3871354SN/A{ 3881354SN/A numMicroops = 2; 3891354SN/A microOps = new StaticInstPtr[numMicroops]; 3901354SN/A 3911354SN/A microOps[0] = new MicroLdrQBFpXLitUop(machInst, dest, imm); 3921354SN/A microOps[1] = new MicroLdrQTFpXLitUop(machInst, dest, imm); 39310796Sbrandon.potter@amd.com 3941354SN/A microOps[0]->setDelayedCommit(); 39510796Sbrandon.potter@amd.com microOps[1]->setLastMicroop(); 3961354SN/A} 3971354SN/A 3981354SN/AVldMultOp::VldMultOp(const char *mnem, ExtMachInst machInst, OpClass __opClass, 3991354SN/A unsigned elems, RegIndex rn, RegIndex vd, unsigned regs, 40010796Sbrandon.potter@amd.com unsigned inc, uint32_t size, uint32_t align, RegIndex rm) : 40110796Sbrandon.potter@amd.com PredMacroOp(mnem, machInst, __opClass) 40210796Sbrandon.potter@amd.com{ 40310796Sbrandon.potter@amd.com assert(regs > 0 && regs <= 4); 40410796Sbrandon.potter@amd.com assert(regs % elems == 0); 40510796Sbrandon.potter@amd.com 40610796Sbrandon.potter@amd.com numMicroops = (regs > 2) ? 2 : 1; 40710796Sbrandon.potter@amd.com bool wb = (rm != 15); 40810796Sbrandon.potter@amd.com bool deinterleave = (elems > 1); 40910796Sbrandon.potter@amd.com 41010796Sbrandon.potter@amd.com if (wb) numMicroops++; 411360SN/A if (deinterleave) numMicroops += (regs / elems); 412360SN/A microOps = new StaticInstPtr[numMicroops]; 413360SN/A 414360SN/A RegIndex rMid = deinterleave ? NumFloatV7ArchRegs : vd * 2; 415360SN/A 416360SN/A uint32_t noAlign = TLB::MustBeOne; 417360SN/A 41811759Sbrandon.potter@amd.com unsigned uopIdx = 0; 4193113Sgblack@eecs.umich.edu switch (regs) { 4203113Sgblack@eecs.umich.edu case 4: 4213113Sgblack@eecs.umich.edu microOps[uopIdx++] = newNeonMemInst<MicroLdrNeon16Uop>( 4223113Sgblack@eecs.umich.edu size, machInst, rMid, rn, 0, align); 4233113Sgblack@eecs.umich.edu microOps[uopIdx++] = newNeonMemInst<MicroLdrNeon16Uop>( 4243113Sgblack@eecs.umich.edu size, machInst, rMid + 4, rn, 16, noAlign); 4253113Sgblack@eecs.umich.edu break; 4263113Sgblack@eecs.umich.edu case 3: 4273113Sgblack@eecs.umich.edu microOps[uopIdx++] = newNeonMemInst<MicroLdrNeon16Uop>( 4283113Sgblack@eecs.umich.edu size, machInst, rMid, rn, 0, align); 4293113Sgblack@eecs.umich.edu microOps[uopIdx++] = newNeonMemInst<MicroLdrNeon8Uop>( 4303113Sgblack@eecs.umich.edu size, machInst, rMid + 4, rn, 16, noAlign); 4313113Sgblack@eecs.umich.edu break; 4323113Sgblack@eecs.umich.edu case 2: 4333113Sgblack@eecs.umich.edu microOps[uopIdx++] = newNeonMemInst<MicroLdrNeon16Uop>( 4343113Sgblack@eecs.umich.edu size, machInst, rMid, rn, 0, align); 4354189Sgblack@eecs.umich.edu break; 4364189Sgblack@eecs.umich.edu case 1: 4373113Sgblack@eecs.umich.edu microOps[uopIdx++] = newNeonMemInst<MicroLdrNeon8Uop>( 4383113Sgblack@eecs.umich.edu size, machInst, rMid, rn, 0, align); 4393113Sgblack@eecs.umich.edu break; 4403113Sgblack@eecs.umich.edu default: 4418737Skoansin.tan@gmail.com // Unknown number of registers 4423113Sgblack@eecs.umich.edu microOps[uopIdx++] = new Unknown(machInst); 4438737Skoansin.tan@gmail.com } 4443277Sgblack@eecs.umich.edu if (wb) { 4455515SMichael.Adler@intel.com if (rm != 15 && rm != 13) { 4465515SMichael.Adler@intel.com microOps[uopIdx++] = 4475515SMichael.Adler@intel.com new MicroAddUop(machInst, rn, rn, rm, 0, ArmISA::LSL); 4485515SMichael.Adler@intel.com } else { 4495515SMichael.Adler@intel.com microOps[uopIdx++] = 4508737Skoansin.tan@gmail.com new MicroAddiUop(machInst, rn, rn, regs * 8); 4513277Sgblack@eecs.umich.edu } 4528737Skoansin.tan@gmail.com } 4533277Sgblack@eecs.umich.edu if (deinterleave) { 4548737Skoansin.tan@gmail.com switch (elems) { 4553277Sgblack@eecs.umich.edu case 4: 4568737Skoansin.tan@gmail.com assert(regs == 4); 4573113Sgblack@eecs.umich.edu microOps[uopIdx++] = newNeonMixInst<MicroDeintNeon8Uop>( 4583113Sgblack@eecs.umich.edu size, machInst, vd * 2, rMid, inc * 2); 4593113Sgblack@eecs.umich.edu break; 4603113Sgblack@eecs.umich.edu case 3: 4618737Skoansin.tan@gmail.com assert(regs == 3); 4623113Sgblack@eecs.umich.edu microOps[uopIdx++] = newNeonMixInst<MicroDeintNeon6Uop>( 4638737Skoansin.tan@gmail.com size, machInst, vd * 2, rMid, inc * 2); 4643114Sgblack@eecs.umich.edu break; 4658737Skoansin.tan@gmail.com case 2: 4663114Sgblack@eecs.umich.edu assert(regs == 4 || regs == 2); 4678737Skoansin.tan@gmail.com if (regs == 4) { 4683114Sgblack@eecs.umich.edu microOps[uopIdx++] = newNeonMixInst<MicroDeintNeon4Uop>( 4698737Skoansin.tan@gmail.com size, machInst, vd * 2, rMid, inc * 2); 47011906SBrandon.Potter@amd.com microOps[uopIdx++] = newNeonMixInst<MicroDeintNeon4Uop>( 4714061Sgblack@eecs.umich.edu size, machInst, vd * 2 + 2, rMid + 4, inc * 2); 4724061Sgblack@eecs.umich.edu } else { 4738737Skoansin.tan@gmail.com microOps[uopIdx++] = newNeonMixInst<MicroDeintNeon4Uop>( 4743113Sgblack@eecs.umich.edu size, machInst, vd * 2, rMid, inc * 2); 4758737Skoansin.tan@gmail.com } 4763113Sgblack@eecs.umich.edu break; 4773113Sgblack@eecs.umich.edu default: 4783113Sgblack@eecs.umich.edu // Bad number of elements to deinterleave 4793113Sgblack@eecs.umich.edu microOps[uopIdx++] = new Unknown(machInst); 4803113Sgblack@eecs.umich.edu } 4813113Sgblack@eecs.umich.edu } 4823113Sgblack@eecs.umich.edu assert(uopIdx == numMicroops); 4833113Sgblack@eecs.umich.edu 4844189Sgblack@eecs.umich.edu for (unsigned i = 0; i < numMicroops - 1; i++) { 4854189Sgblack@eecs.umich.edu MicroOp * uopPtr = dynamic_cast<MicroOp *>(microOps[i].get()); 4863113Sgblack@eecs.umich.edu assert(uopPtr); 4873113Sgblack@eecs.umich.edu uopPtr->setDelayedCommit(); 4883113Sgblack@eecs.umich.edu } 4898737Skoansin.tan@gmail.com microOps[numMicroops - 1]->setLastMicroop(); 4903113Sgblack@eecs.umich.edu} 4918737Skoansin.tan@gmail.com 4923113Sgblack@eecs.umich.eduVldSingleOp::VldSingleOp(const char *mnem, ExtMachInst machInst, 4938737Skoansin.tan@gmail.com OpClass __opClass, bool all, unsigned elems, 4943113Sgblack@eecs.umich.edu RegIndex rn, RegIndex vd, unsigned regs, 4953113Sgblack@eecs.umich.edu unsigned inc, uint32_t size, uint32_t align, 4963113Sgblack@eecs.umich.edu RegIndex rm, unsigned lane) : 4973113Sgblack@eecs.umich.edu PredMacroOp(mnem, machInst, __opClass) 4983113Sgblack@eecs.umich.edu{ 4993113Sgblack@eecs.umich.edu assert(regs > 0 && regs <= 4); 5003113Sgblack@eecs.umich.edu assert(regs % elems == 0); 50111906SBrandon.Potter@amd.com 5023113Sgblack@eecs.umich.edu unsigned eBytes = (1 << size); 5033113Sgblack@eecs.umich.edu unsigned loadSize = eBytes * elems; 5048852Sandreas.hansson@arm.com unsigned loadRegs M5_VAR_USED = (loadSize + sizeof(FloatRegBits) - 1) / 50511906SBrandon.Potter@amd.com sizeof(FloatRegBits); 5063113Sgblack@eecs.umich.edu 5073113Sgblack@eecs.umich.edu assert(loadRegs > 0 && loadRegs <= 4); 5083113Sgblack@eecs.umich.edu 5093113Sgblack@eecs.umich.edu numMicroops = 1; 5103113Sgblack@eecs.umich.edu bool wb = (rm != 15); 5113113Sgblack@eecs.umich.edu 5123113Sgblack@eecs.umich.edu if (wb) numMicroops++; 5133113Sgblack@eecs.umich.edu numMicroops += (regs / elems); 5143113Sgblack@eecs.umich.edu microOps = new StaticInstPtr[numMicroops]; 5158852Sandreas.hansson@arm.com 51611906SBrandon.Potter@amd.com RegIndex ufp0 = NumFloatV7ArchRegs; 5173113Sgblack@eecs.umich.edu 5183113Sgblack@eecs.umich.edu unsigned uopIdx = 0; 5193113Sgblack@eecs.umich.edu switch (loadSize) { 5206686Stjones1@inf.ed.ac.uk case 1: 5213113Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroLdrNeon1Uop<uint8_t>( 5223113Sgblack@eecs.umich.edu machInst, ufp0, rn, 0, align); 5233113Sgblack@eecs.umich.edu break; 52411759Sbrandon.potter@amd.com case 2: 52511759Sbrandon.potter@amd.com if (eBytes == 2) { 52611759Sbrandon.potter@amd.com microOps[uopIdx++] = new MicroLdrNeon2Uop<uint16_t>( 52711759Sbrandon.potter@amd.com machInst, ufp0, rn, 0, align); 52811759Sbrandon.potter@amd.com } else { 52911759Sbrandon.potter@amd.com microOps[uopIdx++] = new MicroLdrNeon2Uop<uint8_t>( 53011759Sbrandon.potter@amd.com machInst, ufp0, rn, 0, align); 53111812Sbaz21@cam.ac.uk } 53211812Sbaz21@cam.ac.uk break; 53311812Sbaz21@cam.ac.uk case 3: 53411759Sbrandon.potter@amd.com microOps[uopIdx++] = new MicroLdrNeon3Uop<uint8_t>( 53511812Sbaz21@cam.ac.uk machInst, ufp0, rn, 0, align); 53611759Sbrandon.potter@amd.com break; 53711759Sbrandon.potter@amd.com case 4: 53811759Sbrandon.potter@amd.com switch (eBytes) { 53911759Sbrandon.potter@amd.com case 1: 54011759Sbrandon.potter@amd.com microOps[uopIdx++] = new MicroLdrNeon4Uop<uint8_t>( 54111759Sbrandon.potter@amd.com machInst, ufp0, rn, 0, align); 54211759Sbrandon.potter@amd.com break; 54311812Sbaz21@cam.ac.uk case 2: 54411812Sbaz21@cam.ac.uk microOps[uopIdx++] = new MicroLdrNeon4Uop<uint16_t>( 54511812Sbaz21@cam.ac.uk machInst, ufp0, rn, 0, align); 54611812Sbaz21@cam.ac.uk break; 54711812Sbaz21@cam.ac.uk case 4: 54811812Sbaz21@cam.ac.uk microOps[uopIdx++] = new MicroLdrNeon4Uop<uint32_t>( 54911812Sbaz21@cam.ac.uk machInst, ufp0, rn, 0, align); 55011759Sbrandon.potter@amd.com break; 55111759Sbrandon.potter@amd.com } 55211812Sbaz21@cam.ac.uk break; 55311812Sbaz21@cam.ac.uk case 6: 55411759Sbrandon.potter@amd.com microOps[uopIdx++] = new MicroLdrNeon6Uop<uint16_t>( 55511812Sbaz21@cam.ac.uk machInst, ufp0, rn, 0, align); 55611812Sbaz21@cam.ac.uk break; 55711812Sbaz21@cam.ac.uk case 8: 55811812Sbaz21@cam.ac.uk switch (eBytes) { 55911812Sbaz21@cam.ac.uk case 2: 56011812Sbaz21@cam.ac.uk microOps[uopIdx++] = new MicroLdrNeon8Uop<uint16_t>( 56111812Sbaz21@cam.ac.uk machInst, ufp0, rn, 0, align); 56211759Sbrandon.potter@amd.com break; 56311759Sbrandon.potter@amd.com case 4: 56411759Sbrandon.potter@amd.com microOps[uopIdx++] = new MicroLdrNeon8Uop<uint32_t>( 56511759Sbrandon.potter@amd.com machInst, ufp0, rn, 0, align); 566378SN/A break; 567378SN/A } 5689141Smarc.orr@gmail.com break; 5699141Smarc.orr@gmail.com case 12: 570360SN/A microOps[uopIdx++] = new MicroLdrNeon12Uop<uint32_t>( 5711450SN/A machInst, ufp0, rn, 0, align); 57211856Sbrandon.potter@amd.com break; 573360SN/A case 16: 5746701Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroLdrNeon16Uop<uint32_t>( 57511856Sbrandon.potter@amd.com machInst, ufp0, rn, 0, align); 57611856Sbrandon.potter@amd.com break; 577360SN/A default: 57810930Sbrandon.potter@amd.com // Unrecognized load size 579360SN/A microOps[uopIdx++] = new Unknown(machInst); 58011856Sbrandon.potter@amd.com } 58111856Sbrandon.potter@amd.com if (wb) { 58210496Ssteve.reinhardt@amd.com if (rm != 15 && rm != 13) { 58311856Sbrandon.potter@amd.com microOps[uopIdx++] = 58411856Sbrandon.potter@amd.com new MicroAddUop(machInst, rn, rn, rm, 0, ArmISA::LSL); 5851458SN/A } else { 586360SN/A microOps[uopIdx++] = 58711856Sbrandon.potter@amd.com new MicroAddiUop(machInst, rn, rn, loadSize); 58811856Sbrandon.potter@amd.com } 58911856Sbrandon.potter@amd.com } 59011856Sbrandon.potter@amd.com switch (elems) { 59111856Sbrandon.potter@amd.com case 4: 59211856Sbrandon.potter@amd.com assert(regs == 4); 59311856Sbrandon.potter@amd.com switch (size) { 59411856Sbrandon.potter@amd.com case 0: 59510496Ssteve.reinhardt@amd.com if (all) { 59611856Sbrandon.potter@amd.com microOps[uopIdx++] = new MicroUnpackAllNeon2to8Uop<uint8_t>( 59711856Sbrandon.potter@amd.com machInst, vd * 2, ufp0, inc * 2); 59811856Sbrandon.potter@amd.com } else { 59911856Sbrandon.potter@amd.com microOps[uopIdx++] = new MicroUnpackNeon2to8Uop<uint8_t>( 60011856Sbrandon.potter@amd.com machInst, vd * 2, ufp0, inc * 2, lane); 60110930Sbrandon.potter@amd.com } 6029141Smarc.orr@gmail.com break; 603360SN/A case 1: 604360SN/A if (all) { 605360SN/A microOps[uopIdx++] = new MicroUnpackAllNeon2to8Uop<uint16_t>( 60611907SBrandon.Potter@amd.com machInst, vd * 2, ufp0, inc * 2); 60711907SBrandon.Potter@amd.com } else { 60811907SBrandon.Potter@amd.com microOps[uopIdx++] = new MicroUnpackNeon2to8Uop<uint16_t>( 609360SN/A machInst, vd * 2, ufp0, inc * 2, lane); 61011907SBrandon.Potter@amd.com } 61111907SBrandon.Potter@amd.com break; 61211907SBrandon.Potter@amd.com case 2: 61311907SBrandon.Potter@amd.com if (all) { 61411907SBrandon.Potter@amd.com microOps[uopIdx++] = new MicroUnpackAllNeon4to8Uop<uint32_t>( 61511907SBrandon.Potter@amd.com machInst, vd * 2, ufp0, inc * 2); 61611907SBrandon.Potter@amd.com } else { 61711907SBrandon.Potter@amd.com microOps[uopIdx++] = new MicroUnpackNeon4to8Uop<uint32_t>( 61811907SBrandon.Potter@amd.com machInst, vd * 2, ufp0, inc * 2, lane); 61911907SBrandon.Potter@amd.com } 62011907SBrandon.Potter@amd.com break; 62111907SBrandon.Potter@amd.com default: 62211907SBrandon.Potter@amd.com // Bad size 62311907SBrandon.Potter@amd.com microOps[uopIdx++] = new Unknown(machInst); 624360SN/A break; 62511907SBrandon.Potter@amd.com } 6261458SN/A break; 627360SN/A case 3: 62811907SBrandon.Potter@amd.com assert(regs == 3); 62911907SBrandon.Potter@amd.com switch (size) { 63011907SBrandon.Potter@amd.com case 0: 63111907SBrandon.Potter@amd.com if (all) { 63211907SBrandon.Potter@amd.com microOps[uopIdx++] = new MicroUnpackAllNeon2to6Uop<uint8_t>( 63311907SBrandon.Potter@amd.com machInst, vd * 2, ufp0, inc * 2); 63411907SBrandon.Potter@amd.com } else { 63511907SBrandon.Potter@amd.com microOps[uopIdx++] = new MicroUnpackNeon2to6Uop<uint8_t>( 63611907SBrandon.Potter@amd.com machInst, vd * 2, ufp0, inc * 2, lane); 63711907SBrandon.Potter@amd.com } 638360SN/A break; 63911907SBrandon.Potter@amd.com case 1: 64011907SBrandon.Potter@amd.com if (all) { 64111907SBrandon.Potter@amd.com microOps[uopIdx++] = new MicroUnpackAllNeon2to6Uop<uint16_t>( 642360SN/A machInst, vd * 2, ufp0, inc * 2); 643360SN/A } else { 64411907SBrandon.Potter@amd.com microOps[uopIdx++] = new MicroUnpackNeon2to6Uop<uint16_t>( 64511907SBrandon.Potter@amd.com machInst, vd * 2, ufp0, inc * 2, lane); 64611907SBrandon.Potter@amd.com } 64711907SBrandon.Potter@amd.com break; 648360SN/A case 2: 64911907SBrandon.Potter@amd.com if (all) { 650360SN/A microOps[uopIdx++] = new MicroUnpackAllNeon4to6Uop<uint32_t>( 651360SN/A machInst, vd * 2, ufp0, inc * 2); 65211907SBrandon.Potter@amd.com } else { 6533669Sbinkertn@umich.edu microOps[uopIdx++] = new MicroUnpackNeon4to6Uop<uint32_t>( 65411907SBrandon.Potter@amd.com machInst, vd * 2, ufp0, inc * 2, lane); 65511907SBrandon.Potter@amd.com } 65611907SBrandon.Potter@amd.com break; 65711907SBrandon.Potter@amd.com default: 65811907SBrandon.Potter@amd.com // Bad size 65911907SBrandon.Potter@amd.com microOps[uopIdx++] = new Unknown(machInst); 66011907SBrandon.Potter@amd.com break; 66111907SBrandon.Potter@amd.com } 66211907SBrandon.Potter@amd.com break; 66311907SBrandon.Potter@amd.com case 2: 66411907SBrandon.Potter@amd.com assert(regs == 2); 66511907SBrandon.Potter@amd.com assert(loadRegs <= 2); 66611907SBrandon.Potter@amd.com switch (size) { 66711907SBrandon.Potter@amd.com case 0: 66811907SBrandon.Potter@amd.com if (all) { 66911907SBrandon.Potter@amd.com microOps[uopIdx++] = new MicroUnpackAllNeon2to4Uop<uint8_t>( 67011907SBrandon.Potter@amd.com machInst, vd * 2, ufp0, inc * 2); 67111907SBrandon.Potter@amd.com } else { 67211907SBrandon.Potter@amd.com microOps[uopIdx++] = new MicroUnpackNeon2to4Uop<uint8_t>( 67311907SBrandon.Potter@amd.com machInst, vd * 2, ufp0, inc * 2, lane); 67411907SBrandon.Potter@amd.com } 6751706SN/A break; 67611907SBrandon.Potter@amd.com case 1: 67711907SBrandon.Potter@amd.com if (all) { 67811907SBrandon.Potter@amd.com microOps[uopIdx++] = new MicroUnpackAllNeon2to4Uop<uint16_t>( 67911907SBrandon.Potter@amd.com machInst, vd * 2, ufp0, inc * 2); 68011907SBrandon.Potter@amd.com } else { 68111907SBrandon.Potter@amd.com microOps[uopIdx++] = new MicroUnpackNeon2to4Uop<uint16_t>( 68210496Ssteve.reinhardt@amd.com machInst, vd * 2, ufp0, inc * 2, lane); 68310496Ssteve.reinhardt@amd.com } 68411907SBrandon.Potter@amd.com break; 68511907SBrandon.Potter@amd.com case 2: 68611907SBrandon.Potter@amd.com if (all) { 68711907SBrandon.Potter@amd.com microOps[uopIdx++] = new MicroUnpackAllNeon2to4Uop<uint32_t>( 68811907SBrandon.Potter@amd.com machInst, vd * 2, ufp0, inc * 2); 68911907SBrandon.Potter@amd.com } else { 69010496Ssteve.reinhardt@amd.com microOps[uopIdx++] = new MicroUnpackNeon2to4Uop<uint32_t>( 69111907SBrandon.Potter@amd.com machInst, vd * 2, ufp0, inc * 2, lane); 69211907SBrandon.Potter@amd.com } 69311907SBrandon.Potter@amd.com break; 69411907SBrandon.Potter@amd.com default: 69510496Ssteve.reinhardt@amd.com // Bad size 69610496Ssteve.reinhardt@amd.com microOps[uopIdx++] = new Unknown(machInst); 69711907SBrandon.Potter@amd.com break; 69811907SBrandon.Potter@amd.com } 69911907SBrandon.Potter@amd.com break; 70011907SBrandon.Potter@amd.com case 1: 70111907SBrandon.Potter@amd.com assert(regs == 1 || (all && regs == 2)); 70211907SBrandon.Potter@amd.com assert(loadRegs <= 2); 70311907SBrandon.Potter@amd.com for (unsigned offset = 0; offset < regs; offset++) { 70411907SBrandon.Potter@amd.com switch (size) { 70511907SBrandon.Potter@amd.com case 0: 70611907SBrandon.Potter@amd.com if (all) { 70711907SBrandon.Potter@amd.com microOps[uopIdx++] = 70811907SBrandon.Potter@amd.com new MicroUnpackAllNeon2to2Uop<uint8_t>( 70911907SBrandon.Potter@amd.com machInst, (vd + offset) * 2, ufp0, inc * 2); 71011907SBrandon.Potter@amd.com } else { 71111907SBrandon.Potter@amd.com microOps[uopIdx++] = 71211907SBrandon.Potter@amd.com new MicroUnpackNeon2to2Uop<uint8_t>( 71311907SBrandon.Potter@amd.com machInst, (vd + offset) * 2, ufp0, inc * 2, lane); 71411907SBrandon.Potter@amd.com } 71511907SBrandon.Potter@amd.com break; 71611907SBrandon.Potter@amd.com case 1: 71711907SBrandon.Potter@amd.com if (all) { 71811907SBrandon.Potter@amd.com microOps[uopIdx++] = 71911907SBrandon.Potter@amd.com new MicroUnpackAllNeon2to2Uop<uint16_t>( 72011907SBrandon.Potter@amd.com machInst, (vd + offset) * 2, ufp0, inc * 2); 72111907SBrandon.Potter@amd.com } else { 722360SN/A microOps[uopIdx++] = 72311907SBrandon.Potter@amd.com new MicroUnpackNeon2to2Uop<uint16_t>( 72411907SBrandon.Potter@amd.com machInst, (vd + offset) * 2, ufp0, inc * 2, lane); 72511907SBrandon.Potter@amd.com } 72611907SBrandon.Potter@amd.com break; 72711907SBrandon.Potter@amd.com case 2: 72811907SBrandon.Potter@amd.com if (all) { 72911907SBrandon.Potter@amd.com microOps[uopIdx++] = 73011907SBrandon.Potter@amd.com new MicroUnpackAllNeon2to2Uop<uint32_t>( 73111907SBrandon.Potter@amd.com machInst, (vd + offset) * 2, ufp0, inc * 2); 73211907SBrandon.Potter@amd.com } else { 73311907SBrandon.Potter@amd.com microOps[uopIdx++] = 73411907SBrandon.Potter@amd.com new MicroUnpackNeon2to2Uop<uint32_t>( 73511907SBrandon.Potter@amd.com machInst, (vd + offset) * 2, ufp0, inc * 2, lane); 736360SN/A } 737360SN/A break; 73810027SChris.Adeniyi-Jones@arm.com default: 73910027SChris.Adeniyi-Jones@arm.com // Bad size 74010027SChris.Adeniyi-Jones@arm.com microOps[uopIdx++] = new Unknown(machInst); 74111851Sbrandon.potter@amd.com break; 74210027SChris.Adeniyi-Jones@arm.com } 74310027SChris.Adeniyi-Jones@arm.com } 74411907SBrandon.Potter@amd.com break; 74510027SChris.Adeniyi-Jones@arm.com default: 74610027SChris.Adeniyi-Jones@arm.com // Bad number of elements to unpack 74710027SChris.Adeniyi-Jones@arm.com microOps[uopIdx++] = new Unknown(machInst); 74810027SChris.Adeniyi-Jones@arm.com } 74910027SChris.Adeniyi-Jones@arm.com assert(uopIdx == numMicroops); 75011851Sbrandon.potter@amd.com 75111851Sbrandon.potter@amd.com for (unsigned i = 0; i < numMicroops - 1; i++) { 75210027SChris.Adeniyi-Jones@arm.com MicroOp * uopPtr = dynamic_cast<MicroOp *>(microOps[i].get()); 75311907SBrandon.Potter@amd.com assert(uopPtr); 75410027SChris.Adeniyi-Jones@arm.com uopPtr->setDelayedCommit(); 75510027SChris.Adeniyi-Jones@arm.com } 75610633Smichaelupton@gmail.com microOps[numMicroops - 1]->setLastMicroop(); 75710633Smichaelupton@gmail.com} 75810633Smichaelupton@gmail.com 75911851Sbrandon.potter@amd.comVstMultOp::VstMultOp(const char *mnem, ExtMachInst machInst, OpClass __opClass, 76010633Smichaelupton@gmail.com unsigned elems, RegIndex rn, RegIndex vd, unsigned regs, 76110633Smichaelupton@gmail.com unsigned inc, uint32_t size, uint32_t align, RegIndex rm) : 76210633Smichaelupton@gmail.com PredMacroOp(mnem, machInst, __opClass) 76310633Smichaelupton@gmail.com{ 76410633Smichaelupton@gmail.com assert(regs > 0 && regs <= 4); 76510633Smichaelupton@gmail.com assert(regs % elems == 0); 76610633Smichaelupton@gmail.com 76710633Smichaelupton@gmail.com numMicroops = (regs > 2) ? 2 : 1; 76810633Smichaelupton@gmail.com bool wb = (rm != 15); 76910633Smichaelupton@gmail.com bool interleave = (elems > 1); 77010203SAli.Saidi@ARM.com 77110203SAli.Saidi@ARM.com if (wb) numMicroops++; 77210203SAli.Saidi@ARM.com if (interleave) numMicroops += (regs / elems); 77311851Sbrandon.potter@amd.com microOps = new StaticInstPtr[numMicroops]; 77411851Sbrandon.potter@amd.com 77510203SAli.Saidi@ARM.com uint32_t noAlign = TLB::MustBeOne; 77610203SAli.Saidi@ARM.com 77710203SAli.Saidi@ARM.com RegIndex rMid = interleave ? NumFloatV7ArchRegs : vd * 2; 77810203SAli.Saidi@ARM.com 77910203SAli.Saidi@ARM.com unsigned uopIdx = 0; 78010203SAli.Saidi@ARM.com if (interleave) { 78110203SAli.Saidi@ARM.com switch (elems) { 78210203SAli.Saidi@ARM.com case 4: 78310203SAli.Saidi@ARM.com assert(regs == 4); 78410203SAli.Saidi@ARM.com microOps[uopIdx++] = newNeonMixInst<MicroInterNeon8Uop>( 78510203SAli.Saidi@ARM.com size, machInst, rMid, vd * 2, inc * 2); 78611851Sbrandon.potter@amd.com break; 78711851Sbrandon.potter@amd.com case 3: 78810203SAli.Saidi@ARM.com assert(regs == 3); 78910203SAli.Saidi@ARM.com microOps[uopIdx++] = newNeonMixInst<MicroInterNeon6Uop>( 79010203SAli.Saidi@ARM.com size, machInst, rMid, vd * 2, inc * 2); 79110203SAli.Saidi@ARM.com break; 79210203SAli.Saidi@ARM.com case 2: 79310203SAli.Saidi@ARM.com assert(regs == 4 || regs == 2); 79410203SAli.Saidi@ARM.com if (regs == 4) { 79510203SAli.Saidi@ARM.com microOps[uopIdx++] = newNeonMixInst<MicroInterNeon4Uop>( 79610850SGiacomo.Gabrielli@arm.com size, machInst, rMid, vd * 2, inc * 2); 79710850SGiacomo.Gabrielli@arm.com microOps[uopIdx++] = newNeonMixInst<MicroInterNeon4Uop>( 79810850SGiacomo.Gabrielli@arm.com size, machInst, rMid + 4, vd * 2 + 2, inc * 2); 79911851Sbrandon.potter@amd.com } else { 80010850SGiacomo.Gabrielli@arm.com microOps[uopIdx++] = newNeonMixInst<MicroInterNeon4Uop>( 80110850SGiacomo.Gabrielli@arm.com size, machInst, rMid, vd * 2, inc * 2); 80210850SGiacomo.Gabrielli@arm.com } 80310850SGiacomo.Gabrielli@arm.com break; 80410850SGiacomo.Gabrielli@arm.com default: 80510850SGiacomo.Gabrielli@arm.com // Bad number of elements to interleave 80610850SGiacomo.Gabrielli@arm.com microOps[uopIdx++] = new Unknown(machInst); 80710850SGiacomo.Gabrielli@arm.com } 80810850SGiacomo.Gabrielli@arm.com } 80910850SGiacomo.Gabrielli@arm.com switch (regs) { 81010850SGiacomo.Gabrielli@arm.com case 4: 81110850SGiacomo.Gabrielli@arm.com microOps[uopIdx++] = newNeonMemInst<MicroStrNeon16Uop>( 81210850SGiacomo.Gabrielli@arm.com size, machInst, rMid, rn, 0, align); 81310850SGiacomo.Gabrielli@arm.com microOps[uopIdx++] = newNeonMemInst<MicroStrNeon16Uop>( 81410850SGiacomo.Gabrielli@arm.com size, machInst, rMid + 4, rn, 16, noAlign); 81510850SGiacomo.Gabrielli@arm.com break; 81610850SGiacomo.Gabrielli@arm.com case 3: 81710850SGiacomo.Gabrielli@arm.com microOps[uopIdx++] = newNeonMemInst<MicroStrNeon16Uop>( 81810850SGiacomo.Gabrielli@arm.com size, machInst, rMid, rn, 0, align); 81910850SGiacomo.Gabrielli@arm.com microOps[uopIdx++] = newNeonMemInst<MicroStrNeon8Uop>( 82010850SGiacomo.Gabrielli@arm.com size, machInst, rMid + 4, rn, 16, noAlign); 82110850SGiacomo.Gabrielli@arm.com break; 82210850SGiacomo.Gabrielli@arm.com case 2: 82310850SGiacomo.Gabrielli@arm.com microOps[uopIdx++] = newNeonMemInst<MicroStrNeon16Uop>( 82410850SGiacomo.Gabrielli@arm.com size, machInst, rMid, rn, 0, align); 82510850SGiacomo.Gabrielli@arm.com break; 82610850SGiacomo.Gabrielli@arm.com case 1: 82710850SGiacomo.Gabrielli@arm.com microOps[uopIdx++] = newNeonMemInst<MicroStrNeon8Uop>( 82810850SGiacomo.Gabrielli@arm.com size, machInst, rMid, rn, 0, align); 82910850SGiacomo.Gabrielli@arm.com break; 83010850SGiacomo.Gabrielli@arm.com default: 83110850SGiacomo.Gabrielli@arm.com // Unknown number of registers 8326640Svince@csl.cornell.edu microOps[uopIdx++] = new Unknown(machInst); 8336640Svince@csl.cornell.edu } 8346640Svince@csl.cornell.edu if (wb) { 83511851Sbrandon.potter@amd.com if (rm != 15 && rm != 13) { 83611851Sbrandon.potter@amd.com microOps[uopIdx++] = 8376640Svince@csl.cornell.edu new MicroAddUop(machInst, rn, rn, rm, 0, ArmISA::LSL); 8386640Svince@csl.cornell.edu } else { 8396701Sgblack@eecs.umich.edu microOps[uopIdx++] = 8406701Sgblack@eecs.umich.edu new MicroAddiUop(machInst, rn, rn, regs * 8); 84110793Sbrandon.potter@amd.com } 8426640Svince@csl.cornell.edu } 84311758Sbrandon.potter@amd.com assert(uopIdx == numMicroops); 84411758Sbrandon.potter@amd.com 84511758Sbrandon.potter@amd.com for (unsigned i = 0; i < numMicroops - 1; i++) { 8466640Svince@csl.cornell.edu MicroOp * uopPtr = dynamic_cast<MicroOp *>(microOps[i].get()); 8478706Sandreas.hansson@arm.com assert(uopPtr); 8486640Svince@csl.cornell.edu uopPtr->setDelayedCommit(); 8496701Sgblack@eecs.umich.edu } 8506640Svince@csl.cornell.edu microOps[numMicroops - 1]->setLastMicroop(); 851360SN/A} 8521999SN/A 8531999SN/AVstSingleOp::VstSingleOp(const char *mnem, ExtMachInst machInst, 8541999SN/A OpClass __opClass, bool all, unsigned elems, 85511851Sbrandon.potter@amd.com RegIndex rn, RegIndex vd, unsigned regs, 8562680Sktlim@umich.edu unsigned inc, uint32_t size, uint32_t align, 8571999SN/A RegIndex rm, unsigned lane) : 8581999SN/A PredMacroOp(mnem, machInst, __opClass) 8591999SN/A{ 8606701Sgblack@eecs.umich.edu assert(!all); 8618852Sandreas.hansson@arm.com assert(regs > 0 && regs <= 4); 8626701Sgblack@eecs.umich.edu assert(regs % elems == 0); 8631999SN/A 8646701Sgblack@eecs.umich.edu unsigned eBytes = (1 << size); 8651999SN/A unsigned storeSize = eBytes * elems; 8666701Sgblack@eecs.umich.edu unsigned storeRegs M5_VAR_USED = (storeSize + sizeof(FloatRegBits) - 1) / 8671999SN/A sizeof(FloatRegBits); 8681999SN/A 8691999SN/A assert(storeRegs > 0 && storeRegs <= 4); 8701999SN/A 8711999SN/A numMicroops = 1; 8723669Sbinkertn@umich.edu bool wb = (rm != 15); 8733669Sbinkertn@umich.edu 8743669Sbinkertn@umich.edu if (wb) numMicroops++; 8751999SN/A numMicroops += (regs / elems); 8761999SN/A microOps = new StaticInstPtr[numMicroops]; 8771999SN/A 8782218SN/A RegIndex ufp0 = NumFloatV7ArchRegs; 8791999SN/A 8801999SN/A unsigned uopIdx = 0; 8811999SN/A switch (elems) { 8821999SN/A case 4: 8831999SN/A assert(regs == 4); 8841999SN/A switch (size) { 8851999SN/A case 0: 8861999SN/A microOps[uopIdx++] = new MicroPackNeon8to2Uop<uint8_t>( 88711856Sbrandon.potter@amd.com machInst, ufp0, vd * 2, inc * 2, lane); 8881999SN/A break; 8896701Sgblack@eecs.umich.edu case 1: 89011856Sbrandon.potter@amd.com microOps[uopIdx++] = new MicroPackNeon8to2Uop<uint16_t>( 89111856Sbrandon.potter@amd.com machInst, ufp0, vd * 2, inc * 2, lane); 89210931Sbrandon.potter@amd.com break; 89311856Sbrandon.potter@amd.com case 2: 89411856Sbrandon.potter@amd.com microOps[uopIdx++] = new MicroPackNeon8to4Uop<uint32_t>( 8951999SN/A machInst, ufp0, vd * 2, inc * 2, lane); 89611856Sbrandon.potter@amd.com break; 8971999SN/A default: 89811856Sbrandon.potter@amd.com // Bad size 8991999SN/A microOps[uopIdx++] = new Unknown(machInst); 90011856Sbrandon.potter@amd.com break; 9011999SN/A } 90211856Sbrandon.potter@amd.com break; 9031999SN/A case 3: 9041999SN/A assert(regs == 3); 9055877Shsul@eecs.umich.edu switch (size) { 9065877Shsul@eecs.umich.edu case 0: 9075877Shsul@eecs.umich.edu microOps[uopIdx++] = new MicroPackNeon6to2Uop<uint8_t>( 90811851Sbrandon.potter@amd.com machInst, ufp0, vd * 2, inc * 2, lane); 9095877Shsul@eecs.umich.edu break; 9106701Sgblack@eecs.umich.edu case 1: 9116701Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroPackNeon6to2Uop<uint16_t>( 9126701Sgblack@eecs.umich.edu machInst, ufp0, vd * 2, inc * 2, lane); 9136701Sgblack@eecs.umich.edu break; 9146701Sgblack@eecs.umich.edu case 2: 91510027SChris.Adeniyi-Jones@arm.com microOps[uopIdx++] = new MicroPackNeon6to4Uop<uint32_t>( 91610027SChris.Adeniyi-Jones@arm.com machInst, ufp0, vd * 2, inc * 2, lane); 91710027SChris.Adeniyi-Jones@arm.com break; 91810027SChris.Adeniyi-Jones@arm.com default: 91910027SChris.Adeniyi-Jones@arm.com // Bad size 9205877Shsul@eecs.umich.edu microOps[uopIdx++] = new Unknown(machInst); 92110318Sandreas.hansson@arm.com break; 92210318Sandreas.hansson@arm.com } 9235877Shsul@eecs.umich.edu break; 9245877Shsul@eecs.umich.edu case 2: 9255877Shsul@eecs.umich.edu assert(regs == 2); 9265877Shsul@eecs.umich.edu assert(storeRegs <= 2); 92710486Stjablin@gmail.com switch (size) { 92810486Stjablin@gmail.com case 0: 9295877Shsul@eecs.umich.edu microOps[uopIdx++] = new MicroPackNeon4to2Uop<uint8_t>( 93011905SBrandon.Potter@amd.com machInst, ufp0, vd * 2, inc * 2, lane); 93111905SBrandon.Potter@amd.com break; 93211905SBrandon.Potter@amd.com case 1: 93311905SBrandon.Potter@amd.com microOps[uopIdx++] = new MicroPackNeon4to2Uop<uint16_t>( 93410027SChris.Adeniyi-Jones@arm.com machInst, ufp0, vd * 2, inc * 2, lane); 9355877Shsul@eecs.umich.edu break; 93611905SBrandon.Potter@amd.com case 2: 93711905SBrandon.Potter@amd.com microOps[uopIdx++] = new MicroPackNeon4to2Uop<uint32_t>( 9385877Shsul@eecs.umich.edu machInst, ufp0, vd * 2, inc * 2, lane); 9395877Shsul@eecs.umich.edu break; 94010027SChris.Adeniyi-Jones@arm.com default: 9415877Shsul@eecs.umich.edu // Bad size 9425877Shsul@eecs.umich.edu microOps[uopIdx++] = new Unknown(machInst); 9435877Shsul@eecs.umich.edu break; 94410027SChris.Adeniyi-Jones@arm.com } 94511905SBrandon.Potter@amd.com break; 94610027SChris.Adeniyi-Jones@arm.com case 1: 94710027SChris.Adeniyi-Jones@arm.com assert(regs == 1 || (all && regs == 2)); 94810027SChris.Adeniyi-Jones@arm.com assert(storeRegs <= 2); 94910027SChris.Adeniyi-Jones@arm.com for (unsigned offset = 0; offset < regs; offset++) { 9505877Shsul@eecs.umich.edu switch (size) { 95110027SChris.Adeniyi-Jones@arm.com case 0: 95210027SChris.Adeniyi-Jones@arm.com microOps[uopIdx++] = new MicroPackNeon2to2Uop<uint8_t>( 95310027SChris.Adeniyi-Jones@arm.com machInst, ufp0, (vd + offset) * 2, inc * 2, lane); 95410027SChris.Adeniyi-Jones@arm.com break; 95511905SBrandon.Potter@amd.com case 1: 95610027SChris.Adeniyi-Jones@arm.com microOps[uopIdx++] = new MicroPackNeon2to2Uop<uint16_t>( 95711905SBrandon.Potter@amd.com machInst, ufp0, (vd + offset) * 2, inc * 2, lane); 95810027SChris.Adeniyi-Jones@arm.com break; 95910027SChris.Adeniyi-Jones@arm.com case 2: 96010027SChris.Adeniyi-Jones@arm.com microOps[uopIdx++] = new MicroPackNeon2to2Uop<uint32_t>( 96110027SChris.Adeniyi-Jones@arm.com machInst, ufp0, (vd + offset) * 2, inc * 2, lane); 96210027SChris.Adeniyi-Jones@arm.com break; 96310027SChris.Adeniyi-Jones@arm.com default: 9645877Shsul@eecs.umich.edu // Bad size 9655877Shsul@eecs.umich.edu microOps[uopIdx++] = new Unknown(machInst); 9665877Shsul@eecs.umich.edu break; 96710027SChris.Adeniyi-Jones@arm.com } 96810027SChris.Adeniyi-Jones@arm.com } 9698601Ssteve.reinhardt@amd.com break; 97010027SChris.Adeniyi-Jones@arm.com default: 9715877Shsul@eecs.umich.edu // Bad number of elements to unpack 9725877Shsul@eecs.umich.edu microOps[uopIdx++] = new Unknown(machInst); 9731999SN/A } 974378SN/A switch (storeSize) { 975360SN/A case 1: 9761450SN/A microOps[uopIdx++] = new MicroStrNeon1Uop<uint8_t>( 97711851Sbrandon.potter@amd.com machInst, ufp0, rn, 0, align); 9782680Sktlim@umich.edu break; 979360SN/A case 2: 980360SN/A if (eBytes == 2) { 981360SN/A microOps[uopIdx++] = new MicroStrNeon2Uop<uint16_t>( 9826701Sgblack@eecs.umich.edu machInst, ufp0, rn, 0, align); 9838852Sandreas.hansson@arm.com } else { 9846701Sgblack@eecs.umich.edu microOps[uopIdx++] = new MicroStrNeon2Uop<uint8_t>( 9856701Sgblack@eecs.umich.edu machInst, ufp0, rn, 0, align); 9866701Sgblack@eecs.umich.edu } 9876701Sgblack@eecs.umich.edu break; 988360SN/A case 3: 9893669Sbinkertn@umich.edu microOps[uopIdx++] = new MicroStrNeon3Uop<uint8_t>( 9903669Sbinkertn@umich.edu machInst, ufp0, rn, 0, align); 9913669Sbinkertn@umich.edu break; 992360SN/A case 4: 993360SN/A switch (eBytes) { 994360SN/A case 1: 995360SN/A microOps[uopIdx++] = new MicroStrNeon4Uop<uint8_t>( 9962218SN/A machInst, ufp0, rn, 0, align); 997360SN/A break; 9988706Sandreas.hansson@arm.com case 2: 999360SN/A microOps[uopIdx++] = new MicroStrNeon4Uop<uint16_t>( 10001458SN/A machInst, ufp0, rn, 0, align); 1001360SN/A break; 1002360SN/A case 4: 1003360SN/A microOps[uopIdx++] = new MicroStrNeon4Uop<uint32_t>( 10045074Ssaidi@eecs.umich.edu machInst, ufp0, rn, 0, align); 10055074Ssaidi@eecs.umich.edu break; 10065074Ssaidi@eecs.umich.edu } 100711851Sbrandon.potter@amd.com break; 10085074Ssaidi@eecs.umich.edu case 6: 10095074Ssaidi@eecs.umich.edu microOps[uopIdx++] = new MicroStrNeon6Uop<uint16_t>( 10105074Ssaidi@eecs.umich.edu machInst, ufp0, rn, 0, align); 10115074Ssaidi@eecs.umich.edu break; 10126701Sgblack@eecs.umich.edu case 8: 10138852Sandreas.hansson@arm.com switch (eBytes) { 10146701Sgblack@eecs.umich.edu case 2: 10155074Ssaidi@eecs.umich.edu microOps[uopIdx++] = new MicroStrNeon8Uop<uint16_t>( 10166701Sgblack@eecs.umich.edu machInst, ufp0, rn, 0, align); 10175074Ssaidi@eecs.umich.edu break; 10185074Ssaidi@eecs.umich.edu case 4: 10195074Ssaidi@eecs.umich.edu microOps[uopIdx++] = new MicroStrNeon8Uop<uint32_t>( 10205074Ssaidi@eecs.umich.edu machInst, ufp0, rn, 0, align); 10215208Ssaidi@eecs.umich.edu break; 10225208Ssaidi@eecs.umich.edu } 10235208Ssaidi@eecs.umich.edu break; 10245208Ssaidi@eecs.umich.edu case 12: 10255074Ssaidi@eecs.umich.edu microOps[uopIdx++] = new MicroStrNeon12Uop<uint32_t>( 10265074Ssaidi@eecs.umich.edu machInst, ufp0, rn, 0, align); 10275208Ssaidi@eecs.umich.edu break; 10285074Ssaidi@eecs.umich.edu case 16: 10295074Ssaidi@eecs.umich.edu microOps[uopIdx++] = new MicroStrNeon16Uop<uint32_t>( 10305074Ssaidi@eecs.umich.edu machInst, ufp0, rn, 0, align); 10315074Ssaidi@eecs.umich.edu break; 10328706Sandreas.hansson@arm.com default: 10335074Ssaidi@eecs.umich.edu // Bad store size 10345074Ssaidi@eecs.umich.edu microOps[uopIdx++] = new Unknown(machInst); 10355074Ssaidi@eecs.umich.edu } 10365074Ssaidi@eecs.umich.edu if (wb) { 10375074Ssaidi@eecs.umich.edu if (rm != 15 && rm != 13) { 103810027SChris.Adeniyi-Jones@arm.com microOps[uopIdx++] = 103910027SChris.Adeniyi-Jones@arm.com new MicroAddUop(machInst, rn, rn, rm, 0, ArmISA::LSL); 104010027SChris.Adeniyi-Jones@arm.com } else { 104111851Sbrandon.potter@amd.com microOps[uopIdx++] = 104210027SChris.Adeniyi-Jones@arm.com new MicroAddiUop(machInst, rn, rn, storeSize); 104310027SChris.Adeniyi-Jones@arm.com } 104410027SChris.Adeniyi-Jones@arm.com } 104510027SChris.Adeniyi-Jones@arm.com assert(uopIdx == numMicroops); 104610027SChris.Adeniyi-Jones@arm.com 104710793Sbrandon.potter@amd.com for (unsigned i = 0; i < numMicroops - 1; i++) { 104810027SChris.Adeniyi-Jones@arm.com MicroOp * uopPtr = dynamic_cast<MicroOp *>(microOps[i].get()); 104910027SChris.Adeniyi-Jones@arm.com assert(uopPtr); 105010027SChris.Adeniyi-Jones@arm.com uopPtr->setDelayedCommit(); 105110027SChris.Adeniyi-Jones@arm.com } 105210027SChris.Adeniyi-Jones@arm.com microOps[numMicroops - 1]->setLastMicroop(); 105310027SChris.Adeniyi-Jones@arm.com} 105410027SChris.Adeniyi-Jones@arm.com 105510027SChris.Adeniyi-Jones@arm.comVldMultOp64::VldMultOp64(const char *mnem, ExtMachInst machInst, 105610027SChris.Adeniyi-Jones@arm.com OpClass __opClass, RegIndex rn, RegIndex vd, 105710027SChris.Adeniyi-Jones@arm.com RegIndex rm, uint8_t eSize, uint8_t dataSize, 105810027SChris.Adeniyi-Jones@arm.com uint8_t numStructElems, uint8_t numRegs, bool wb) : 105910027SChris.Adeniyi-Jones@arm.com PredMacroOp(mnem, machInst, __opClass) 106010027SChris.Adeniyi-Jones@arm.com{ 106110027SChris.Adeniyi-Jones@arm.com RegIndex vx = NumFloatV8ArchRegs / 4; 106210027SChris.Adeniyi-Jones@arm.com RegIndex rnsp = (RegIndex) makeSP((IntRegIndex) rn); 106310027SChris.Adeniyi-Jones@arm.com bool baseIsSP = isSP((IntRegIndex) rnsp); 106410027SChris.Adeniyi-Jones@arm.com 106510027SChris.Adeniyi-Jones@arm.com numMicroops = wb ? 1 : 0; 106610027SChris.Adeniyi-Jones@arm.com 106710027SChris.Adeniyi-Jones@arm.com int totNumBytes = numRegs * dataSize / 8; 106810027SChris.Adeniyi-Jones@arm.com assert(totNumBytes <= 64); 106910027SChris.Adeniyi-Jones@arm.com 107010027SChris.Adeniyi-Jones@arm.com // The guiding principle here is that no more than 16 bytes can be 107110027SChris.Adeniyi-Jones@arm.com // transferred at a time 107210027SChris.Adeniyi-Jones@arm.com int numMemMicroops = totNumBytes / 16; 107310027SChris.Adeniyi-Jones@arm.com int residuum = totNumBytes % 16; 107410027SChris.Adeniyi-Jones@arm.com if (residuum) 10751999SN/A ++numMemMicroops; 10761999SN/A numMicroops += numMemMicroops; 10771999SN/A 107811856Sbrandon.potter@amd.com int numMarshalMicroops = numRegs / 2 + (numRegs % 2 ? 1 : 0); 10791999SN/A numMicroops += numMarshalMicroops; 10806701Sgblack@eecs.umich.edu 108111856Sbrandon.potter@amd.com microOps = new StaticInstPtr[numMicroops]; 108211856Sbrandon.potter@amd.com unsigned uopIdx = 0; 108310931Sbrandon.potter@amd.com uint32_t memaccessFlags = TLB::MustBeOne | (TLB::ArmFlags) eSize | 108411856Sbrandon.potter@amd.com TLB::AllowUnaligned; 108511856Sbrandon.potter@amd.com 10861999SN/A int i = 0; 108711856Sbrandon.potter@amd.com for(; i < numMemMicroops - 1; ++i) { 10881999SN/A microOps[uopIdx++] = new MicroNeonLoad64( 10892764Sstever@eecs.umich.edu machInst, vx + (RegIndex) i, rnsp, 16 * i, memaccessFlags, 10902064SN/A baseIsSP, 16 /* accSize */, eSize); 109110931Sbrandon.potter@amd.com } 10922064SN/A microOps[uopIdx++] = new MicroNeonLoad64( 10932064SN/A machInst, vx + (RegIndex) i, rnsp, 16 * i, memaccessFlags, baseIsSP, 109410931Sbrandon.potter@amd.com residuum ? residuum : 16 /* accSize */, eSize); 10952064SN/A 10961999SN/A // Writeback microop: the post-increment amount is encoded in "Rm": a 10971999SN/A // 64-bit general register OR as '11111' for an immediate value equal to 10982218SN/A // the total number of bytes transferred (i.e. 8, 16, 24, 32, 48 or 64) 10991999SN/A if (wb) { 110010931Sbrandon.potter@amd.com if (rm != ((RegIndex) INTREG_X31)) { 11011999SN/A microOps[uopIdx++] = new MicroAddXERegUop(machInst, rnsp, rnsp, rm, 11021999SN/A UXTX, 0); 11031999SN/A } else { 11041999SN/A microOps[uopIdx++] = new MicroAddXiUop(machInst, rnsp, rnsp, 11051999SN/A totNumBytes); 1106378SN/A } 1107360SN/A } 11081450SN/A 110911851Sbrandon.potter@amd.com for (int i = 0; i < numMarshalMicroops; ++i) { 11102680Sktlim@umich.edu microOps[uopIdx++] = new MicroDeintNeon64( 1111360SN/A machInst, vd + (RegIndex) (2 * i), vx, eSize, dataSize, 1112360SN/A numStructElems, numRegs, i /* step */); 1113360SN/A } 11146701Sgblack@eecs.umich.edu 11158852Sandreas.hansson@arm.com assert(uopIdx == numMicroops); 11166701Sgblack@eecs.umich.edu 11176701Sgblack@eecs.umich.edu for (int i = 0; i < numMicroops - 1; ++i) { 11186701Sgblack@eecs.umich.edu microOps[i]->setDelayedCommit(); 11196701Sgblack@eecs.umich.edu } 1120360SN/A microOps[numMicroops - 1]->setLastMicroop(); 11213669Sbinkertn@umich.edu} 11223669Sbinkertn@umich.edu 11233669Sbinkertn@umich.eduVstMultOp64::VstMultOp64(const char *mnem, ExtMachInst machInst, 1124360SN/A OpClass __opClass, RegIndex rn, RegIndex vd, 1125360SN/A RegIndex rm, uint8_t eSize, uint8_t dataSize, 1126360SN/A uint8_t numStructElems, uint8_t numRegs, bool wb) : 1127360SN/A PredMacroOp(mnem, machInst, __opClass) 11281458SN/A{ 1129360SN/A RegIndex vx = NumFloatV8ArchRegs / 4; 11308706Sandreas.hansson@arm.com RegIndex rnsp = (RegIndex) makeSP((IntRegIndex) rn); 1131360SN/A bool baseIsSP = isSP((IntRegIndex) rnsp); 11321458SN/A 1133360SN/A numMicroops = wb ? 1 : 0; 1134360SN/A 11351999SN/A int totNumBytes = numRegs * dataSize / 8; 11361999SN/A assert(totNumBytes <= 64); 11371999SN/A 113811851Sbrandon.potter@amd.com // The guiding principle here is that no more than 16 bytes can be 11392680Sktlim@umich.edu // transferred at a time 11401999SN/A int numMemMicroops = totNumBytes / 16; 11411999SN/A int residuum = totNumBytes % 16; 11421999SN/A if (residuum) 11436701Sgblack@eecs.umich.edu ++numMemMicroops; 11448852Sandreas.hansson@arm.com numMicroops += numMemMicroops; 11456701Sgblack@eecs.umich.edu 11466701Sgblack@eecs.umich.edu int numMarshalMicroops = totNumBytes > 32 ? 2 : 1; 11476701Sgblack@eecs.umich.edu numMicroops += numMarshalMicroops; 11486701Sgblack@eecs.umich.edu 11491999SN/A microOps = new StaticInstPtr[numMicroops]; 11503669Sbinkertn@umich.edu unsigned uopIdx = 0; 11513669Sbinkertn@umich.edu 11523669Sbinkertn@umich.edu for(int i = 0; i < numMarshalMicroops; ++i) { 11532764Sstever@eecs.umich.edu microOps[uopIdx++] = new MicroIntNeon64( 11542064SN/A machInst, vx + (RegIndex) (2 * i), vd, eSize, dataSize, 11552064SN/A numStructElems, numRegs, i /* step */); 11562064SN/A } 11571999SN/A 11581999SN/A uint32_t memaccessFlags = TLB::MustBeOne | (TLB::ArmFlags) eSize | 11592064SN/A TLB::AllowUnaligned; 11601999SN/A 11611999SN/A int i = 0; 11621999SN/A for(; i < numMemMicroops - 1; ++i) { 11631999SN/A microOps[uopIdx++] = new MicroNeonStore64( 11648706Sandreas.hansson@arm.com machInst, vx + (RegIndex) i, rnsp, 16 * i, memaccessFlags, 11651999SN/A baseIsSP, 16 /* accSize */, eSize); 11661999SN/A } 11671999SN/A microOps[uopIdx++] = new MicroNeonStore64( 11681999SN/A machInst, vx + (RegIndex) i, rnsp, 16 * i, memaccessFlags, baseIsSP, 1169378SN/A residuum ? residuum : 16 /* accSize */, eSize); 1170360SN/A 11711450SN/A // Writeback microop: the post-increment amount is encoded in "Rm": a 117211856Sbrandon.potter@amd.com // 64-bit general register OR as '11111' for an immediate value equal to 1173360SN/A // the total number of bytes transferred (i.e. 8, 16, 24, 32, 48 or 64) 11746701Sgblack@eecs.umich.edu if (wb) { 117511856Sbrandon.potter@amd.com if (rm != ((RegIndex) INTREG_X31)) { 117611856Sbrandon.potter@amd.com microOps[uopIdx++] = new MicroAddXERegUop(machInst, rnsp, rnsp, rm, 1177360SN/A UXTX, 0); 117811380Salexandru.dutu@amd.com } else { 1179360SN/A microOps[uopIdx++] = new MicroAddXiUop(machInst, rnsp, rnsp, 118011856Sbrandon.potter@amd.com totNumBytes); 118111856Sbrandon.potter@amd.com } 11821458SN/A } 118311856Sbrandon.potter@amd.com 1184360SN/A assert(uopIdx == numMicroops); 1185360SN/A 118610931Sbrandon.potter@amd.com for (int i = 0; i < numMicroops - 1; i++) { 1187360SN/A microOps[i]->setDelayedCommit(); 1188360SN/A } 11891458SN/A microOps[numMicroops - 1]->setLastMicroop(); 1190360SN/A} 119110931Sbrandon.potter@amd.com 11922021SN/AVldSingleOp64::VldSingleOp64(const char *mnem, ExtMachInst machInst, 11931458SN/A OpClass __opClass, RegIndex rn, RegIndex vd, 1194360SN/A RegIndex rm, uint8_t eSize, uint8_t dataSize, 1195360SN/A uint8_t numStructElems, uint8_t index, bool wb, 1196360SN/A bool replicate) : 11971706SN/A PredMacroOp(mnem, machInst, __opClass) 11981706SN/A{ 11991706SN/A RegIndex vx = NumFloatV8ArchRegs / 4; 120011851Sbrandon.potter@amd.com RegIndex rnsp = (RegIndex) makeSP((IntRegIndex) rn); 12012680Sktlim@umich.edu bool baseIsSP = isSP((IntRegIndex) rnsp); 12021706SN/A 120311799Sbrandon.potter@amd.com numMicroops = wb ? 1 : 0; 120411799Sbrandon.potter@amd.com 120511799Sbrandon.potter@amd.com int eSizeBytes = 1 << eSize; 12061706SN/A int totNumBytes = numStructElems * eSizeBytes; 12071706SN/A assert(totNumBytes <= 64); 12086701Sgblack@eecs.umich.edu 12098852Sandreas.hansson@arm.com // The guiding principle here is that no more than 16 bytes can be 12106701Sgblack@eecs.umich.edu // transferred at a time 12116701Sgblack@eecs.umich.edu int numMemMicroops = totNumBytes / 16; 12126701Sgblack@eecs.umich.edu int residuum = totNumBytes % 16; 12136701Sgblack@eecs.umich.edu if (residuum) 12141706SN/A ++numMemMicroops; 12153669Sbinkertn@umich.edu numMicroops += numMemMicroops; 12163669Sbinkertn@umich.edu 12173669Sbinkertn@umich.edu int numMarshalMicroops = numStructElems / 2 + (numStructElems % 2 ? 1 : 0); 12181706SN/A numMicroops += numMarshalMicroops; 12191706SN/A 12201706SN/A microOps = new StaticInstPtr[numMicroops]; 12211706SN/A unsigned uopIdx = 0; 12222218SN/A 12231706SN/A uint32_t memaccessFlags = TLB::MustBeOne | (TLB::ArmFlags) eSize | 122411759Sbrandon.potter@amd.com TLB::AllowUnaligned; 122511799Sbrandon.potter@amd.com 12261706SN/A int i = 0; 12271706SN/A for (; i < numMemMicroops - 1; ++i) { 12281706SN/A microOps[uopIdx++] = new MicroNeonLoad64( 122911886Sbrandon.potter@amd.com machInst, vx + (RegIndex) i, rnsp, 16 * i, memaccessFlags, 123011886Sbrandon.potter@amd.com baseIsSP, 16 /* accSize */, eSize); 123111886Sbrandon.potter@amd.com } 123211886Sbrandon.potter@amd.com microOps[uopIdx++] = new MicroNeonLoad64( 123311886Sbrandon.potter@amd.com machInst, vx + (RegIndex) i, rnsp, 16 * i, memaccessFlags, baseIsSP, 123411886Sbrandon.potter@amd.com residuum ? residuum : 16 /* accSize */, eSize); 123511886Sbrandon.potter@amd.com 123611886Sbrandon.potter@amd.com // Writeback microop: the post-increment amount is encoded in "Rm": a 123711886Sbrandon.potter@amd.com // 64-bit general register OR as '11111' for an immediate value equal to 123811886Sbrandon.potter@amd.com // the total number of bytes transferred (i.e. 8, 16, 24, 32, 48 or 64) 123911886Sbrandon.potter@amd.com if (wb) { 124011886Sbrandon.potter@amd.com if (rm != ((RegIndex) INTREG_X31)) { 124111886Sbrandon.potter@amd.com microOps[uopIdx++] = new MicroAddXERegUop(machInst, rnsp, rnsp, rm, 124211886Sbrandon.potter@amd.com UXTX, 0); 124311886Sbrandon.potter@amd.com } else { 124411886Sbrandon.potter@amd.com microOps[uopIdx++] = new MicroAddXiUop(machInst, rnsp, rnsp, 124511886Sbrandon.potter@amd.com totNumBytes); 124611886Sbrandon.potter@amd.com } 124711886Sbrandon.potter@amd.com } 124811886Sbrandon.potter@amd.com 124911886Sbrandon.potter@amd.com for(int i = 0; i < numMarshalMicroops; ++i) { 125011886Sbrandon.potter@amd.com microOps[uopIdx++] = new MicroUnpackNeon64( 125111886Sbrandon.potter@amd.com machInst, vd + (RegIndex) (2 * i), vx, eSize, dataSize, 125211886Sbrandon.potter@amd.com numStructElems, index, i /* step */, replicate); 125311886Sbrandon.potter@amd.com } 125411886Sbrandon.potter@amd.com 125511886Sbrandon.potter@amd.com assert(uopIdx == numMicroops); 125611886Sbrandon.potter@amd.com 125711886Sbrandon.potter@amd.com for (int i = 0; i < numMicroops - 1; i++) { 125811886Sbrandon.potter@amd.com microOps[i]->setDelayedCommit(); 125911886Sbrandon.potter@amd.com } 126011886Sbrandon.potter@amd.com microOps[numMicroops - 1]->setLastMicroop(); 126111886Sbrandon.potter@amd.com} 126211886Sbrandon.potter@amd.com 126311886Sbrandon.potter@amd.comVstSingleOp64::VstSingleOp64(const char *mnem, ExtMachInst machInst, 126411886Sbrandon.potter@amd.com OpClass __opClass, RegIndex rn, RegIndex vd, 126511886Sbrandon.potter@amd.com RegIndex rm, uint8_t eSize, uint8_t dataSize, 126611886Sbrandon.potter@amd.com uint8_t numStructElems, uint8_t index, bool wb, 126711886Sbrandon.potter@amd.com bool replicate) : 126811886Sbrandon.potter@amd.com PredMacroOp(mnem, machInst, __opClass) 126911886Sbrandon.potter@amd.com{ 127011886Sbrandon.potter@amd.com RegIndex vx = NumFloatV8ArchRegs / 4; 127111886Sbrandon.potter@amd.com RegIndex rnsp = (RegIndex) makeSP((IntRegIndex) rn); 127211886Sbrandon.potter@amd.com bool baseIsSP = isSP((IntRegIndex) rnsp); 127311886Sbrandon.potter@amd.com 127411886Sbrandon.potter@amd.com numMicroops = wb ? 1 : 0; 127511886Sbrandon.potter@amd.com 127611886Sbrandon.potter@amd.com int eSizeBytes = 1 << eSize; 127711886Sbrandon.potter@amd.com int totNumBytes = numStructElems * eSizeBytes; 127811886Sbrandon.potter@amd.com assert(totNumBytes <= 64); 127911886Sbrandon.potter@amd.com 128011886Sbrandon.potter@amd.com // The guiding principle here is that no more than 16 bytes can be 128111886Sbrandon.potter@amd.com // transferred at a time 128211886Sbrandon.potter@amd.com int numMemMicroops = totNumBytes / 16; 128311886Sbrandon.potter@amd.com int residuum = totNumBytes % 16; 128411886Sbrandon.potter@amd.com if (residuum) 128511886Sbrandon.potter@amd.com ++numMemMicroops; 128611886Sbrandon.potter@amd.com numMicroops += numMemMicroops; 128711886Sbrandon.potter@amd.com 128811886Sbrandon.potter@amd.com int numMarshalMicroops = totNumBytes > 32 ? 2 : 1; 128911886Sbrandon.potter@amd.com numMicroops += numMarshalMicroops; 129011886Sbrandon.potter@amd.com 129111886Sbrandon.potter@amd.com microOps = new StaticInstPtr[numMicroops]; 129211886Sbrandon.potter@amd.com unsigned uopIdx = 0; 129311886Sbrandon.potter@amd.com 129411886Sbrandon.potter@amd.com for(int i = 0; i < numMarshalMicroops; ++i) { 129511886Sbrandon.potter@amd.com microOps[uopIdx++] = new MicroPackNeon64( 129611886Sbrandon.potter@amd.com machInst, vx + (RegIndex) (2 * i), vd, eSize, dataSize, 129711886Sbrandon.potter@amd.com numStructElems, index, i /* step */, replicate); 129811886Sbrandon.potter@amd.com } 129911886Sbrandon.potter@amd.com 130011911SBrandon.Potter@amd.com uint32_t memaccessFlags = TLB::MustBeOne | (TLB::ArmFlags) eSize | 130111911SBrandon.Potter@amd.com TLB::AllowUnaligned; 130211911SBrandon.Potter@amd.com 130311911SBrandon.Potter@amd.com int i = 0; 130411911SBrandon.Potter@amd.com for(; i < numMemMicroops - 1; ++i) { 130511911SBrandon.Potter@amd.com microOps[uopIdx++] = new MicroNeonStore64( 130611911SBrandon.Potter@amd.com machInst, vx + (RegIndex) i, rnsp, 16 * i, memaccessFlags, 130711886Sbrandon.potter@amd.com baseIsSP, 16 /* accsize */, eSize); 130811886Sbrandon.potter@amd.com } 130911886Sbrandon.potter@amd.com microOps[uopIdx++] = new MicroNeonStore64( 131011886Sbrandon.potter@amd.com machInst, vx + (RegIndex) i, rnsp, 16 * i, memaccessFlags, baseIsSP, 131111886Sbrandon.potter@amd.com residuum ? residuum : 16 /* accSize */, eSize); 131211886Sbrandon.potter@amd.com 131311886Sbrandon.potter@amd.com // Writeback microop: the post-increment amount is encoded in "Rm": a 131411886Sbrandon.potter@amd.com // 64-bit general register OR as '11111' for an immediate value equal to 131511886Sbrandon.potter@amd.com // the total number of bytes transferred (i.e. 8, 16, 24, 32, 48 or 64) 131611886Sbrandon.potter@amd.com if (wb) { 131711886Sbrandon.potter@amd.com if (rm != ((RegIndex) INTREG_X31)) { 131811886Sbrandon.potter@amd.com microOps[uopIdx++] = new MicroAddXERegUop(machInst, rnsp, rnsp, rm, 131911886Sbrandon.potter@amd.com UXTX, 0); 132011886Sbrandon.potter@amd.com } else { 132111886Sbrandon.potter@amd.com microOps[uopIdx++] = new MicroAddXiUop(machInst, rnsp, rnsp, 132211886Sbrandon.potter@amd.com totNumBytes); 132311886Sbrandon.potter@amd.com } 132411886Sbrandon.potter@amd.com } 132511886Sbrandon.potter@amd.com 132611886Sbrandon.potter@amd.com assert(uopIdx == numMicroops); 132711886Sbrandon.potter@amd.com 132811886Sbrandon.potter@amd.com for (int i = 0; i < numMicroops - 1; i++) { 132911886Sbrandon.potter@amd.com microOps[i]->setDelayedCommit(); 133011886Sbrandon.potter@amd.com } 133111886Sbrandon.potter@amd.com microOps[numMicroops - 1]->setLastMicroop(); 133211886Sbrandon.potter@amd.com} 133311886Sbrandon.potter@amd.com 133411886Sbrandon.potter@amd.comMacroVFPMemOp::MacroVFPMemOp(const char *mnem, ExtMachInst machInst, 133511886Sbrandon.potter@amd.com OpClass __opClass, IntRegIndex rn, 133611886Sbrandon.potter@amd.com RegIndex vd, bool single, bool up, 133711886Sbrandon.potter@amd.com bool writeback, bool load, uint32_t offset) : 133811886Sbrandon.potter@amd.com PredMacroOp(mnem, machInst, __opClass) 133911886Sbrandon.potter@amd.com{ 134011886Sbrandon.potter@amd.com int i = 0; 134111886Sbrandon.potter@amd.com 134211886Sbrandon.potter@amd.com // The lowest order bit selects fldmx (set) or fldmd (clear). These seem 134311886Sbrandon.potter@amd.com // to be functionally identical except that fldmx is deprecated. For now 134411886Sbrandon.potter@amd.com // we'll assume they're otherwise interchangable. 134511886Sbrandon.potter@amd.com int count = (single ? offset : (offset / 2)); 134611886Sbrandon.potter@amd.com if (count == 0 || count > NumFloatV7ArchRegs) 134711886Sbrandon.potter@amd.com warn_once("Bad offset field for VFP load/store multiple.\n"); 134811886Sbrandon.potter@amd.com if (count == 0) { 134911886Sbrandon.potter@amd.com // Force there to be at least one microop so the macroop makes sense. 135011886Sbrandon.potter@amd.com writeback = true; 135111886Sbrandon.potter@amd.com } 135211886Sbrandon.potter@amd.com if (count > NumFloatV7ArchRegs) 135311886Sbrandon.potter@amd.com count = NumFloatV7ArchRegs; 135411886Sbrandon.potter@amd.com 135511886Sbrandon.potter@amd.com numMicroops = count * (single ? 1 : 2) + (writeback ? 1 : 0); 135611886Sbrandon.potter@amd.com microOps = new StaticInstPtr[numMicroops]; 135711886Sbrandon.potter@amd.com 135811886Sbrandon.potter@amd.com int64_t addr = 0; 135911886Sbrandon.potter@amd.com 136011886Sbrandon.potter@amd.com if (!up) 13611706SN/A addr = 4 * offset; 13621706SN/A 13631706SN/A bool tempUp = up; 13641706SN/A for (int j = 0; j < count; j++) { 136511856Sbrandon.potter@amd.com if (load) { 13661706SN/A if (single) { 13676701Sgblack@eecs.umich.edu microOps[i++] = new MicroLdrFpUop(machInst, vd++, rn, 136811856Sbrandon.potter@amd.com tempUp, addr); 136911856Sbrandon.potter@amd.com } else { 13701706SN/A microOps[i++] = new MicroLdrDBFpUop(machInst, vd++, rn, 137111856Sbrandon.potter@amd.com tempUp, addr); 137211856Sbrandon.potter@amd.com microOps[i++] = new MicroLdrDTFpUop(machInst, vd++, rn, tempUp, 13731706SN/A addr + (up ? 4 : -4)); 137411856Sbrandon.potter@amd.com } 13751706SN/A } else { 13761706SN/A if (single) { 137710931Sbrandon.potter@amd.com microOps[i++] = new MicroStrFpUop(machInst, vd++, rn, 13781706SN/A tempUp, addr); 13791706SN/A } else { 13802218SN/A microOps[i++] = new MicroStrDBFpUop(machInst, vd++, rn, 13811706SN/A tempUp, addr); 138211759Sbrandon.potter@amd.com microOps[i++] = new MicroStrDTFpUop(machInst, vd++, rn, tempUp, 13831706SN/A addr + (up ? 4 : -4)); 13841706SN/A } 13851706SN/A } 13861706SN/A if (!tempUp) { 13871706SN/A addr -= (single ? 4 : 8); 13881999SN/A // The microops don't handle negative displacement, so turn if we 13891999SN/A // hit zero, flip polarity and start adding. 13901999SN/A if (addr <= 0) { 139111856Sbrandon.potter@amd.com tempUp = true; 13921999SN/A addr = -addr; 13936701Sgblack@eecs.umich.edu } 139411856Sbrandon.potter@amd.com } else { 139510931Sbrandon.potter@amd.com addr += (single ? 4 : 8); 139611856Sbrandon.potter@amd.com } 139711856Sbrandon.potter@amd.com } 13981999SN/A 139911856Sbrandon.potter@amd.com if (writeback) { 14001999SN/A if (up) { 140111856Sbrandon.potter@amd.com microOps[i++] = 140211856Sbrandon.potter@amd.com new MicroAddiUop(machInst, rn, rn, 4 * offset); 140311856Sbrandon.potter@amd.com } else { 14041999SN/A microOps[i++] = 14056227Snate@binkert.org new MicroSubiUop(machInst, rn, rn, 4 * offset); 14061999SN/A } 14072461SN/A } 140811856Sbrandon.potter@amd.com 140911856Sbrandon.potter@amd.com assert(numMicroops == i); 14108737Skoansin.tan@gmail.com microOps[numMicroops - 1]->setLastMicroop(); 14111999SN/A 141211856Sbrandon.potter@amd.com for (StaticInstPtr *curUop = microOps; 141311856Sbrandon.potter@amd.com !(*curUop)->isLastMicroop(); curUop++) { 14141999SN/A MicroOp * uopPtr = dynamic_cast<MicroOp *>(curUop->get()); 14151999SN/A assert(uopPtr); 141610931Sbrandon.potter@amd.com uopPtr->setDelayedCommit(); 14171999SN/A } 14186227Snate@binkert.org} 14191999SN/A 14201999SN/Astd::string 14211999SN/AMicroIntImmOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const 14222218SN/A{ 14231999SN/A std::stringstream ss; 142410629Sjthestness@gmail.com printMnemonic(ss); 14251999SN/A printReg(ss, ura); 14261999SN/A ss << ", "; 142711385Sbrandon.potter@amd.com printReg(ss, urb); 1428360SN/A ss << ", "; 14291450SN/A ccprintf(ss, "#%d", imm); 143011851Sbrandon.potter@amd.com return ss.str(); 143111385Sbrandon.potter@amd.com} 1432360SN/A 14336701Sgblack@eecs.umich.edustd::string 14346701Sgblack@eecs.umich.eduMicroIntImmXOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const 14356701Sgblack@eecs.umich.edu{ 143611383Sbrandon.potter@amd.com std::stringstream ss; 143711383Sbrandon.potter@amd.com printMnemonic(ss); 14388324Ssteve.reinhardt@amd.com printReg(ss, ura); 143910486Stjablin@gmail.com ss << ", "; 1440360SN/A printReg(ss, urb); 144111385Sbrandon.potter@amd.com ss << ", "; 144211385Sbrandon.potter@amd.com ccprintf(ss, "#%d", imm); 14439008Sgblack@eecs.umich.edu return ss.str(); 144411383Sbrandon.potter@amd.com} 144511383Sbrandon.potter@amd.com 144611383Sbrandon.potter@amd.comstd::string 144711383Sbrandon.potter@amd.comMicroSetPCCPSR::generateDisassembly(Addr pc, const SymbolTable *symtab) const 144811383Sbrandon.potter@amd.com{ 144911383Sbrandon.potter@amd.com std::stringstream ss; 145011383Sbrandon.potter@amd.com printMnemonic(ss); 145111383Sbrandon.potter@amd.com ss << "[PC,CPSR]"; 145211383Sbrandon.potter@amd.com return ss.str(); 14538324Ssteve.reinhardt@amd.com} 145411383Sbrandon.potter@amd.com 145511383Sbrandon.potter@amd.comstd::string 145611383Sbrandon.potter@amd.comMicroIntRegXOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const 145711383Sbrandon.potter@amd.com{ 145811383Sbrandon.potter@amd.com std::stringstream ss; 145911383Sbrandon.potter@amd.com printMnemonic(ss); 146011383Sbrandon.potter@amd.com printReg(ss, ura); 146111383Sbrandon.potter@amd.com ccprintf(ss, ", "); 146211383Sbrandon.potter@amd.com printReg(ss, urb); 146311383Sbrandon.potter@amd.com printExtendOperand(false, ss, (IntRegIndex)urc, type, shiftAmt); 146411383Sbrandon.potter@amd.com return ss.str(); 146511383Sbrandon.potter@amd.com} 146611383Sbrandon.potter@amd.com 146711383Sbrandon.potter@amd.comstd::string 146811383Sbrandon.potter@amd.comMicroIntMov::generateDisassembly(Addr pc, const SymbolTable *symtab) const 146911383Sbrandon.potter@amd.com{ 147011383Sbrandon.potter@amd.com std::stringstream ss; 147111383Sbrandon.potter@amd.com printMnemonic(ss); 147211383Sbrandon.potter@amd.com printReg(ss, ura); 147311383Sbrandon.potter@amd.com ss << ", "; 147411383Sbrandon.potter@amd.com printReg(ss, urb); 147511383Sbrandon.potter@amd.com return ss.str(); 147611383Sbrandon.potter@amd.com} 147711383Sbrandon.potter@amd.com 14788324Ssteve.reinhardt@amd.comstd::string 14795877Shsul@eecs.umich.eduMicroIntOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const 148010486Stjablin@gmail.com{ 148110486Stjablin@gmail.com std::stringstream ss; 148211383Sbrandon.potter@amd.com printMnemonic(ss); 148311383Sbrandon.potter@amd.com printReg(ss, ura); 148411383Sbrandon.potter@amd.com ss << ", "; 148511856Sbrandon.potter@amd.com printReg(ss, urb); 148611624Smichael.lebeane@amd.com ss << ", "; 148711856Sbrandon.potter@amd.com printReg(ss, urc); 148811856Sbrandon.potter@amd.com return ss.str(); 148911856Sbrandon.potter@amd.com} 149011856Sbrandon.potter@amd.com 149111624Smichael.lebeane@amd.comstd::string 149211624Smichael.lebeane@amd.comMicroMemOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const 149311624Smichael.lebeane@amd.com{ 149411856Sbrandon.potter@amd.com std::stringstream ss; 149511856Sbrandon.potter@amd.com printMnemonic(ss); 149611383Sbrandon.potter@amd.com if (isFloating()) 149711856Sbrandon.potter@amd.com printReg(ss, ura + FP_Reg_Base); 1498360SN/A else 149911913SBrandon.Potter@amd.com printReg(ss, ura); 150011383Sbrandon.potter@amd.com ss << ", ["; 15018600Ssteve.reinhardt@amd.com printReg(ss, urb); 150211383Sbrandon.potter@amd.com ss << ", "; 150311383Sbrandon.potter@amd.com ccprintf(ss, "#%d", imm); 150411383Sbrandon.potter@amd.com ss << "]"; 15058600Ssteve.reinhardt@amd.com return ss.str(); 15062544SN/A} 15072544SN/A 150811383Sbrandon.potter@amd.com} 150911383Sbrandon.potter@amd.com