macromem.cc revision 7310
16145Snate@binkert.org/* 26145Snate@binkert.org * Copyright (c) 2010 ARM Limited 36145Snate@binkert.org * All rights reserved 46145Snate@binkert.org * 56145Snate@binkert.org * The license below extends only to copyright in the software and shall 66145Snate@binkert.org * not be construed as granting a license to any other intellectual 76145Snate@binkert.org * property including but not limited to intellectual property relating 86145Snate@binkert.org * to a hardware implementation of the functionality of the software 96145Snate@binkert.org * licensed hereunder. You may use the software subject to the license 106145Snate@binkert.org * terms below provided that you ensure that this notice is replicated 116145Snate@binkert.org * unmodified and in its entirety in all distributions of the software, 126145Snate@binkert.org * modified or unmodified, in source code or in binary form. 136145Snate@binkert.org * 146145Snate@binkert.org * Copyright (c) 2007-2008 The Florida State University 156145Snate@binkert.org * All rights reserved. 166145Snate@binkert.org * 176145Snate@binkert.org * Redistribution and use in source and binary forms, with or without 186145Snate@binkert.org * modification, are permitted provided that the following conditions are 196145Snate@binkert.org * met: redistributions of source code must retain the above copyright 206145Snate@binkert.org * notice, this list of conditions and the following disclaimer; 216145Snate@binkert.org * redistributions in binary form must reproduce the above copyright 226145Snate@binkert.org * notice, this list of conditions and the following disclaimer in the 236145Snate@binkert.org * documentation and/or other materials provided with the distribution; 246145Snate@binkert.org * neither the name of the copyright holders nor the names of its 256145Snate@binkert.org * contributors may be used to endorse or promote products derived from 266145Snate@binkert.org * this software without specific prior written permission. 276145Snate@binkert.org * 286145Snate@binkert.org * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 296145Snate@binkert.org * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 306145Snate@binkert.org * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 316145Snate@binkert.org * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 326145Snate@binkert.org * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 336145Snate@binkert.org * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 346145Snate@binkert.org * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 356145Snate@binkert.org * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 366145Snate@binkert.org * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 376145Snate@binkert.org * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 386145Snate@binkert.org * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 396145Snate@binkert.org * 406145Snate@binkert.org * Authors: Stephen Hines 416145Snate@binkert.org */ 426145Snate@binkert.org 436145Snate@binkert.org#include "arch/arm/insts/macromem.hh" 446145Snate@binkert.org#include "arch/arm/decoder.hh" 457002Snate@binkert.org 467002Snate@binkert.orgusing namespace ArmISAInst; 477002Snate@binkert.org 488946Sandreas.hansson@arm.comnamespace ArmISA 498946Sandreas.hansson@arm.com{ 507002Snate@binkert.org 517454Snate@binkert.orgMacroMemOp::MacroMemOp(const char *mnem, ExtMachInst machInst, 527832Snate@binkert.org OpClass __opClass, IntRegIndex rn, 537454Snate@binkert.org bool index, bool up, bool user, bool writeback, 547454Snate@binkert.org bool load, uint32_t reglist) : 557056Snate@binkert.org PredMacroOp(mnem, machInst, __opClass) 567048Snate@binkert.org{ 578229Snate@binkert.org uint32_t regs = reglist; 587048Snate@binkert.org uint32_t ones = number_of_ones(reglist); 597048Snate@binkert.org // Remember that writeback adds a uop 606154Snate@binkert.org numMicroops = ones + (writeback ? 1 : 0) + 1; 616154Snate@binkert.org microOps = new StaticInstPtr[numMicroops]; 626876Ssteve.reinhardt@amd.com uint32_t addr = 0; 637055Snate@binkert.org 647454Snate@binkert.org if (!up) 657055Snate@binkert.org addr = (ones << 2) - 4; 666145Snate@binkert.org 676145Snate@binkert.org if (!index) 686145Snate@binkert.org addr += 4; 696876Ssteve.reinhardt@amd.com 709171Snilay@cs.wisc.edu StaticInstPtr *uop = microOps; 716145Snate@binkert.org StaticInstPtr wbUop; 727048Snate@binkert.org if (writeback) { 737048Snate@binkert.org if (up) { 746285Snate@binkert.org wbUop = new MicroAddiUop(machInst, rn, rn, ones * 4); 757048Snate@binkert.org } else { 767048Snate@binkert.org wbUop = new MicroSubiUop(machInst, rn, rn, ones * 4); 777048Snate@binkert.org } 786145Snate@binkert.org } 797048Snate@binkert.org 807048Snate@binkert.org // Add 0 to Rn and stick it in ureg0. 816876Ssteve.reinhardt@amd.com // This is equivalent to a move. 827048Snate@binkert.org *uop = new MicroAddiUop(machInst, INTREG_UREG0, rn, 0); 836896SBrad.Beckmann@amd.com 847048Snate@binkert.org // Write back at the start for loads. This covers the ldm exception return 857048Snate@binkert.org // case where the base needs to be written in the old mode. Stores may need 866285Snate@binkert.org // the original value of the base, but they don't change mode and can 877048Snate@binkert.org // write back at the end like before. 887048Snate@binkert.org if (load && writeback) { 897048Snate@binkert.org *++uop = wbUop; 906285Snate@binkert.org } 917048Snate@binkert.org 927048Snate@binkert.org unsigned reg = 0; 937048Snate@binkert.org bool force_user = user & !bits(reglist, 15); 947048Snate@binkert.org bool exception_ret = user & bits(reglist, 15); 957048Snate@binkert.org 968436SBrad.Beckmann@amd.com for (int i = 0; i < ones; i++) { 978436SBrad.Beckmann@amd.com // Find the next register. 986285Snate@binkert.org while (!bits(regs, reg)) 996285Snate@binkert.org reg++; 1006889SBrad.Beckmann@amd.com replaceBits(regs, reg, 0); 1016889SBrad.Beckmann@amd.com 1027048Snate@binkert.org unsigned regIdx = reg; 1037048Snate@binkert.org if (force_user) { 1047048Snate@binkert.org regIdx = intRegInMode(MODE_USER, regIdx); 1056889SBrad.Beckmann@amd.com } 1066889SBrad.Beckmann@amd.com 1077048Snate@binkert.org if (load) { 1087048Snate@binkert.org if (reg == INTREG_PC && exception_ret) { 1096145Snate@binkert.org // This must be the exception return form of ldm. 1107048Snate@binkert.org *++uop = new MicroLdrRetUop(machInst, regIdx, 1116145Snate@binkert.org INTREG_UREG0, up, addr); 1129231Snilay@cs.wisc.edu } else { 1136145Snate@binkert.org *++uop = new MicroLdrUop(machInst, regIdx, 1147048Snate@binkert.org INTREG_UREG0, up, addr); 1157048Snate@binkert.org } 1169171Snilay@cs.wisc.edu } else { 1177048Snate@binkert.org *++uop = new MicroStrUop(machInst, regIdx, INTREG_UREG0, up, addr); 1187048Snate@binkert.org } 1196145Snate@binkert.org 1207048Snate@binkert.org if (up) 1216889SBrad.Beckmann@amd.com addr += 4; 1229171Snilay@cs.wisc.edu else 1237048Snate@binkert.org addr -= 4; 1247048Snate@binkert.org } 1256889SBrad.Beckmann@amd.com 1267048Snate@binkert.org if (!load && writeback) { 1277054Snate@binkert.org *++uop = wbUop; 1287048Snate@binkert.org } 1297048Snate@binkert.org 1306889SBrad.Beckmann@amd.com (*uop)->setLastMicroop(); 1316145Snate@binkert.org} 1326145Snate@binkert.org 1336145Snate@binkert.orgMacroVFPMemOp::MacroVFPMemOp(const char *mnem, ExtMachInst machInst, 1346145Snate@binkert.org OpClass __opClass, IntRegIndex rn, 1357048Snate@binkert.org RegIndex vd, bool single, bool up, 1367048Snate@binkert.org bool writeback, bool load, uint32_t offset) : 1376145Snate@binkert.org PredMacroOp(mnem, machInst, __opClass) 1386145Snate@binkert.org{ 1397048Snate@binkert.org const int maxMicroops = 17; 1409206Snilay@cs.wisc.edu microOps = new StaticInstPtr[maxMicroops]; 1417048Snate@binkert.org int i = 0; 1427048Snate@binkert.org 1437048Snate@binkert.org // The lowest order bit selects fldmx (set) or fldmd (clear). These seem 1447048Snate@binkert.org // to be functionally identical except that fldmx is deprecated. For now 1457048Snate@binkert.org // we'll assume they're otherwise interchangable. 1467048Snate@binkert.org int count = (single ? offset : (offset / 2)); 1477048Snate@binkert.org if (count == 0 || count > NumFloatArchRegs) 1487048Snate@binkert.org warn_once("Bad offset field for VFP load/store multiple.\n"); 1497048Snate@binkert.org if (count == 0) { 1507048Snate@binkert.org // Force there to be at least one microop so the macroop makes sense. 1516145Snate@binkert.org writeback = true; 1526145Snate@binkert.org } 1537048Snate@binkert.org if (count > NumFloatArchRegs) 1549206Snilay@cs.wisc.edu count = NumFloatArchRegs; 1557048Snate@binkert.org 1567048Snate@binkert.org uint32_t addr = 0; 1577048Snate@binkert.org 1589231Snilay@cs.wisc.edu if (up) 1597048Snate@binkert.org addr = -4 * offset; 1607054Snate@binkert.org 1617048Snate@binkert.org for (int j = 0; j < count; j++) { 1627048Snate@binkert.org if (load) { 1637048Snate@binkert.org microOps[i++] = new MicroLdrFpUop(machInst, vd++, rn, 1649206Snilay@cs.wisc.edu true, addr); 1657048Snate@binkert.org if (!single) 1667048Snate@binkert.org microOps[i++] = new MicroLdrFpUop(machInst, vd++, rn, 1677048Snate@binkert.org true, addr + 4); 1687048Snate@binkert.org } else { 1697048Snate@binkert.org microOps[i++] = new MicroStrFpUop(machInst, vd++, rn, 1707048Snate@binkert.org true, addr); 1717048Snate@binkert.org if (!single) 1727048Snate@binkert.org microOps[i++] = new MicroStrFpUop(machInst, vd++, rn, 1737048Snate@binkert.org true, addr + 4); 1747048Snate@binkert.org } 1757048Snate@binkert.org addr += (single ? 4 : 8); 1767048Snate@binkert.org } 1777048Snate@binkert.org 1787048Snate@binkert.org if (writeback) { 1797048Snate@binkert.org if (up) { 1807048Snate@binkert.org microOps[i++] = 1817048Snate@binkert.org new MicroAddiUop(machInst, rn, rn, 4 * offset); 1827048Snate@binkert.org } else { 1837048Snate@binkert.org microOps[i++] = 1847048Snate@binkert.org new MicroSubiUop(machInst, rn, rn, 4 * offset); 1857048Snate@binkert.org } 1867048Snate@binkert.org } 1877048Snate@binkert.org 1889171Snilay@cs.wisc.edu numMicroops = i; 1897048Snate@binkert.org assert(numMicroops <= maxMicroops); 1907048Snate@binkert.org microOps[numMicroops - 1]->setLastMicroop(); 1917048Snate@binkert.org} 1927048Snate@binkert.org 1937048Snate@binkert.org} 1947048Snate@binkert.org