1/* 2 * Copyright (c) 2010 ARM Limited 3 * All rights reserved 4 * 5 * The license below extends only to copyright in the software and shall 6 * not be construed as granting a license to any other intellectual 7 * property including but not limited to intellectual property relating 8 * to a hardware implementation of the functionality of the software --- 122 unchanged lines hidden (view full) --- 131} 132 133MacroVFPMemOp::MacroVFPMemOp(const char *mnem, ExtMachInst machInst, 134 OpClass __opClass, IntRegIndex rn, 135 RegIndex vd, bool single, bool up, 136 bool writeback, bool load, uint32_t offset) : 137 PredMacroOp(mnem, machInst, __opClass) 138{ |
139 int i = 0; 140 141 // The lowest order bit selects fldmx (set) or fldmd (clear). These seem 142 // to be functionally identical except that fldmx is deprecated. For now 143 // we'll assume they're otherwise interchangable. 144 int count = (single ? offset : (offset / 2)); 145 if (count == 0 || count > NumFloatArchRegs) 146 warn_once("Bad offset field for VFP load/store multiple.\n"); 147 if (count == 0) { 148 // Force there to be at least one microop so the macroop makes sense. 149 writeback = true; 150 } 151 if (count > NumFloatArchRegs) 152 count = NumFloatArchRegs; 153 |
154 numMicroops = count * (single ? 1 : 2) + (writeback ? 1 : 0); 155 microOps = new StaticInstPtr[numMicroops]; 156 |
157 uint32_t addr = 0; 158 |
159 if (!up) 160 addr = 4 * offset; |
161 |
162 bool tempUp = up; |
163 for (int j = 0; j < count; j++) { 164 if (load) { 165 microOps[i++] = new MicroLdrFpUop(machInst, vd++, rn, |
166 tempUp, addr); |
167 if (!single) 168 microOps[i++] = new MicroLdrFpUop(machInst, vd++, rn, |
169 tempUp, addr + 4); |
170 } else { 171 microOps[i++] = new MicroStrFpUop(machInst, vd++, rn, |
172 tempUp, addr); |
173 if (!single) 174 microOps[i++] = new MicroStrFpUop(machInst, vd++, rn, |
175 tempUp, addr + 4); |
176 } |
177 if (!tempUp) { 178 addr -= (single ? 4 : 8); 179 // The microops don't handle negative displacement, so turn if we 180 // hit zero, flip polarity and start adding. 181 if (addr == 0) { 182 tempUp = true; 183 } 184 } else { 185 addr += (single ? 4 : 8); 186 } |
187 } 188 189 if (writeback) { 190 if (up) { 191 microOps[i++] = 192 new MicroAddiUop(machInst, rn, rn, 4 * offset); 193 } else { 194 microOps[i++] = 195 new MicroSubiUop(machInst, rn, rn, 4 * offset); 196 } 197 } 198 |
199 assert(numMicroops == i); |
200 microOps[numMicroops - 1]->setLastMicroop(); 201} 202 203} |