macromem.cc revision 7175
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 437170Sgblack@eecs.umich.edu#include "arch/arm/insts/macromem.hh" 447170Sgblack@eecs.umich.edu#include "arch/arm/decoder.hh" 457170Sgblack@eecs.umich.edu 467170Sgblack@eecs.umich.eduusing namespace ArmISAInst; 477170Sgblack@eecs.umich.edu 487170Sgblack@eecs.umich.edunamespace ArmISA 497170Sgblack@eecs.umich.edu{ 507170Sgblack@eecs.umich.edu 517170Sgblack@eecs.umich.eduMacroMemOp::MacroMemOp(const char *mnem, ExtMachInst machInst, 527170Sgblack@eecs.umich.edu OpClass __opClass, IntRegIndex rn, 537170Sgblack@eecs.umich.edu bool index, bool up, bool user, bool writeback, 547170Sgblack@eecs.umich.edu bool load, uint32_t reglist) : 557170Sgblack@eecs.umich.edu PredMacroOp(mnem, machInst, __opClass) 567170Sgblack@eecs.umich.edu{ 577170Sgblack@eecs.umich.edu uint32_t regs = reglist; 587170Sgblack@eecs.umich.edu uint32_t ones = number_of_ones(reglist); 597170Sgblack@eecs.umich.edu // Remember that writeback adds a uop 607170Sgblack@eecs.umich.edu numMicroops = ones + (writeback ? 1 : 0) + 1; 617170Sgblack@eecs.umich.edu microOps = new StaticInstPtr[numMicroops]; 627170Sgblack@eecs.umich.edu uint32_t addr = 0; 637170Sgblack@eecs.umich.edu 647170Sgblack@eecs.umich.edu if (!up) 657170Sgblack@eecs.umich.edu addr = (ones << 2) - 4; 667170Sgblack@eecs.umich.edu 677170Sgblack@eecs.umich.edu if (!index) 687170Sgblack@eecs.umich.edu addr += 4; 697170Sgblack@eecs.umich.edu 707170Sgblack@eecs.umich.edu // Add 0 to Rn and stick it in ureg0. 717170Sgblack@eecs.umich.edu // This is equivalent to a move. 727170Sgblack@eecs.umich.edu microOps[0] = new MicroAddiUop(machInst, INTREG_UREG0, rn, 0); 737170Sgblack@eecs.umich.edu 747170Sgblack@eecs.umich.edu unsigned reg = 0; 757170Sgblack@eecs.umich.edu bool force_user = user & !bits(reglist, 15); 767170Sgblack@eecs.umich.edu bool exception_ret = user & bits(reglist, 15); 777170Sgblack@eecs.umich.edu 787170Sgblack@eecs.umich.edu for (int i = 1; i < ones + 1; i++) { 797170Sgblack@eecs.umich.edu // Find the next register. 807170Sgblack@eecs.umich.edu while (!bits(regs, reg)) 817170Sgblack@eecs.umich.edu reg++; 827170Sgblack@eecs.umich.edu replaceBits(regs, reg, 0); 837170Sgblack@eecs.umich.edu 847170Sgblack@eecs.umich.edu unsigned regIdx = reg; 857170Sgblack@eecs.umich.edu if (force_user) { 867170Sgblack@eecs.umich.edu regIdx = intRegForceUser(regIdx); 877170Sgblack@eecs.umich.edu } 887170Sgblack@eecs.umich.edu 897170Sgblack@eecs.umich.edu if (load) { 907170Sgblack@eecs.umich.edu if (reg == INTREG_PC && exception_ret) { 917170Sgblack@eecs.umich.edu // This must be the exception return form of ldm. 927170Sgblack@eecs.umich.edu microOps[i] = 937170Sgblack@eecs.umich.edu new MicroLdrRetUop(machInst, regIdx, 947170Sgblack@eecs.umich.edu INTREG_UREG0, up, addr); 957170Sgblack@eecs.umich.edu } else { 967170Sgblack@eecs.umich.edu microOps[i] = 977170Sgblack@eecs.umich.edu new MicroLdrUop(machInst, regIdx, INTREG_UREG0, up, addr); 987170Sgblack@eecs.umich.edu } 997170Sgblack@eecs.umich.edu } else { 1007170Sgblack@eecs.umich.edu microOps[i] = 1017170Sgblack@eecs.umich.edu new MicroStrUop(machInst, regIdx, INTREG_UREG0, up, addr); 1027170Sgblack@eecs.umich.edu } 1037170Sgblack@eecs.umich.edu 1047170Sgblack@eecs.umich.edu if (up) 1057170Sgblack@eecs.umich.edu addr += 4; 1067170Sgblack@eecs.umich.edu else 1077170Sgblack@eecs.umich.edu addr -= 4; 1087170Sgblack@eecs.umich.edu } 1097170Sgblack@eecs.umich.edu 1107170Sgblack@eecs.umich.edu StaticInstPtr &lastUop = microOps[numMicroops - 1]; 1117170Sgblack@eecs.umich.edu if (writeback) { 1127170Sgblack@eecs.umich.edu if (up) { 1137170Sgblack@eecs.umich.edu lastUop = new MicroAddiUop(machInst, rn, rn, ones * 4); 1147170Sgblack@eecs.umich.edu } else { 1157170Sgblack@eecs.umich.edu lastUop = new MicroSubiUop(machInst, rn, rn, ones * 4); 1167170Sgblack@eecs.umich.edu } 1177170Sgblack@eecs.umich.edu } 1187170Sgblack@eecs.umich.edu lastUop->setLastMicroop(); 1197170Sgblack@eecs.umich.edu} 1207170Sgblack@eecs.umich.edu 1217175Sgblack@eecs.umich.eduMacroVFPMemOp::MacroVFPMemOp(const char *mnem, ExtMachInst machInst, 1227175Sgblack@eecs.umich.edu OpClass __opClass, IntRegIndex rn, 1237175Sgblack@eecs.umich.edu RegIndex vd, bool single, bool up, 1247175Sgblack@eecs.umich.edu bool writeback, bool load, uint32_t offset) : 1257175Sgblack@eecs.umich.edu PredMacroOp(mnem, machInst, __opClass) 1267175Sgblack@eecs.umich.edu{ 1277175Sgblack@eecs.umich.edu const int maxMicroops = 17; 1287175Sgblack@eecs.umich.edu microOps = new StaticInstPtr[maxMicroops]; 1297175Sgblack@eecs.umich.edu int i = 0; 1307175Sgblack@eecs.umich.edu 1317175Sgblack@eecs.umich.edu // The lowest order bit selects fldmx (set) or fldmd (clear). These seem 1327175Sgblack@eecs.umich.edu // to be functionally identical except that fldmx is deprecated. For now 1337175Sgblack@eecs.umich.edu // we'll assume they're otherwise interchangable. 1347175Sgblack@eecs.umich.edu int count = (single ? offset : (offset / 2)); 1357175Sgblack@eecs.umich.edu if (count == 0 || count > NumFloatArchRegs) 1367175Sgblack@eecs.umich.edu warn_once("Bad offset field for VFP load/store multiple.\n"); 1377175Sgblack@eecs.umich.edu if (count == 0) { 1387175Sgblack@eecs.umich.edu // Force there to be at least one microop so the macroop makes sense. 1397175Sgblack@eecs.umich.edu writeback = true; 1407175Sgblack@eecs.umich.edu } 1417175Sgblack@eecs.umich.edu if (count > NumFloatArchRegs) 1427175Sgblack@eecs.umich.edu count = NumFloatArchRegs; 1437175Sgblack@eecs.umich.edu 1447175Sgblack@eecs.umich.edu uint32_t addr = 0; 1457175Sgblack@eecs.umich.edu 1467175Sgblack@eecs.umich.edu if (up) 1477175Sgblack@eecs.umich.edu addr = -4 * offset; 1487175Sgblack@eecs.umich.edu 1497175Sgblack@eecs.umich.edu for (int j = 0; j < count; j++) { 1507175Sgblack@eecs.umich.edu if (load) { 1517175Sgblack@eecs.umich.edu microOps[i++] = new MicroLdrFpUop(machInst, vd++, rn, 1527175Sgblack@eecs.umich.edu true, addr); 1537175Sgblack@eecs.umich.edu if (!single) 1547175Sgblack@eecs.umich.edu microOps[i++] = new MicroLdrFpUop(machInst, vd++, rn, 1557175Sgblack@eecs.umich.edu true, addr + 4); 1567175Sgblack@eecs.umich.edu } else { 1577175Sgblack@eecs.umich.edu microOps[i++] = new MicroStrFpUop(machInst, vd++, rn, 1587175Sgblack@eecs.umich.edu true, addr); 1597175Sgblack@eecs.umich.edu if (!single) 1607175Sgblack@eecs.umich.edu microOps[i++] = new MicroStrFpUop(machInst, vd++, rn, 1617175Sgblack@eecs.umich.edu true, addr + 4); 1627175Sgblack@eecs.umich.edu } 1637175Sgblack@eecs.umich.edu addr += (single ? 4 : 8); 1647175Sgblack@eecs.umich.edu } 1657175Sgblack@eecs.umich.edu 1667175Sgblack@eecs.umich.edu if (writeback) { 1677175Sgblack@eecs.umich.edu if (up) { 1687175Sgblack@eecs.umich.edu microOps[i++] = 1697175Sgblack@eecs.umich.edu new MicroAddiUop(machInst, rn, rn, 4 * offset); 1707175Sgblack@eecs.umich.edu } else { 1717175Sgblack@eecs.umich.edu microOps[i++] = 1727175Sgblack@eecs.umich.edu new MicroSubiUop(machInst, rn, rn, 4 * offset); 1737175Sgblack@eecs.umich.edu } 1747175Sgblack@eecs.umich.edu } 1757175Sgblack@eecs.umich.edu 1767175Sgblack@eecs.umich.edu numMicroops = i; 1777175Sgblack@eecs.umich.edu assert(numMicroops <= maxMicroops); 1787175Sgblack@eecs.umich.edu microOps[numMicroops - 1]->setLastMicroop(); 1797170Sgblack@eecs.umich.edu} 1807175Sgblack@eecs.umich.edu 1817175Sgblack@eecs.umich.edu} 182