Deleted Added
sdiff udiff text old ( 10339:53278be85b40 ) new ( 10346:d96b61d843b2 )
full compact
1/*
2 * Copyright (c) 2010-2014 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

--- 47 unchanged lines hidden (view full) ---

56MacroMemOp::MacroMemOp(const char *mnem, ExtMachInst machInst,
57 OpClass __opClass, IntRegIndex rn,
58 bool index, bool up, bool user, bool writeback,
59 bool load, uint32_t reglist) :
60 PredMacroOp(mnem, machInst, __opClass)
61{
62 uint32_t regs = reglist;
63 uint32_t ones = number_of_ones(reglist);
64 // Remember that writeback adds a uop or two and the temp register adds one
65 numMicroops = ones + (writeback ? (load ? 2 : 1) : 0) + 1;
66
67 // It's technically legal to do a lot of nothing
68 if (!ones)
69 numMicroops = 1;
70
71 microOps = new StaticInstPtr[numMicroops];
72 uint32_t addr = 0;
73
74 if (!up)
75 addr = (ones << 2) - 4;
76
77 if (!index)
78 addr += 4;
79
80 StaticInstPtr *uop = microOps;
81
82 // Add 0 to Rn and stick it in ureg0.
83 // This is equivalent to a move.
84 *uop = new MicroAddiUop(machInst, INTREG_UREG0, rn, 0);
85
86 unsigned reg = 0;
87 unsigned regIdx = 0;
88 bool force_user = user & !bits(reglist, 15);
89 bool exception_ret = user & bits(reglist, 15);
90
91 for (int i = 0; i < ones; i++) {
92 // Find the next register.
93 while (!bits(regs, reg))
94 reg++;
95 replaceBits(regs, reg, 0);
96
97 regIdx = reg;
98 if (force_user) {
99 regIdx = intRegInMode(MODE_USER, regIdx);
100 }
101
102 if (load) {
103 if (writeback && i == ones - 1) {
104 // If it's a writeback and this is the last register
105 // do the load into a temporary register which we'll move
106 // into the final one later
107 *++uop = new MicroLdrUop(machInst, INTREG_UREG1, INTREG_UREG0,
108 up, addr);
109 } else {
110 // Otherwise just do it normally
111 if (reg == INTREG_PC && exception_ret) {
112 // This must be the exception return form of ldm.
113 *++uop = new MicroLdrRetUop(machInst, regIdx,
114 INTREG_UREG0, up, addr);
115 if (!(condCode == COND_AL || condCode == COND_UC))
116 (*uop)->setFlag(StaticInst::IsCondControl);
117 else
118 (*uop)->setFlag(StaticInst::IsUncondControl);
119 } else {
120 *++uop = new MicroLdrUop(machInst, regIdx,
121 INTREG_UREG0, up, addr);
122 if (reg == INTREG_PC) {
123 (*uop)->setFlag(StaticInst::IsControl);
124 if (!(condCode == COND_AL || condCode == COND_UC))
125 (*uop)->setFlag(StaticInst::IsCondControl);
126 else
127 (*uop)->setFlag(StaticInst::IsUncondControl);
128 (*uop)->setFlag(StaticInst::IsIndirectControl);
129 }
130 }
131 }
132 } else {
133 *++uop = new MicroStrUop(machInst, regIdx, INTREG_UREG0, up, addr);
134 }
135
136 if (up)
137 addr += 4;
138 else
139 addr -= 4;
140 }
141
142 if (writeback && ones) {
143 // put the register update after we're done all loading
144 if (up)
145 *++uop = new MicroAddiUop(machInst, rn, rn, ones * 4);
146 else
147 *++uop = new MicroSubiUop(machInst, rn, rn, ones * 4);
148
149 // If this was a load move the last temporary value into place
150 // this way we can't take an exception after we update the base
151 // register.
152 if (load && reg == INTREG_PC && exception_ret) {
153 *++uop = new MicroUopRegMovRet(machInst, 0, INTREG_UREG1);
154 if (!(condCode == COND_AL || condCode == COND_UC))
155 (*uop)->setFlag(StaticInst::IsCondControl);
156 else
157 (*uop)->setFlag(StaticInst::IsUncondControl);
158 } else if (load) {
159 *++uop = new MicroUopRegMov(machInst, regIdx, INTREG_UREG1);
160 if (reg == INTREG_PC) {
161 (*uop)->setFlag(StaticInst::IsControl);
162 (*uop)->setFlag(StaticInst::IsCondControl);
163 (*uop)->setFlag(StaticInst::IsIndirectControl);
164 // This is created as a RAS POP
165 if (rn == INTREG_SP)
166 (*uop)->setFlag(StaticInst::IsReturn);
167
168 }
169 }
170 }
171
172 (*uop)->setLastMicroop();
173
174 /* Take the control flags from the last microop for the macroop */
175 if ((*uop)->isControl())
176 setFlag(StaticInst::IsControl);
177 if ((*uop)->isCondCtrl())
178 setFlag(StaticInst::IsCondControl);
179 if ((*uop)->isIndirectCtrl())
180 setFlag(StaticInst::IsIndirectControl);
181 if ((*uop)->isReturn())
182 setFlag(StaticInst::IsReturn);
183
184 for (StaticInstPtr *curUop = microOps;
185 !(*curUop)->isLastMicroop(); curUop++) {
186 MicroOp * uopPtr = dynamic_cast<MicroOp *>(curUop->get());
187 assert(uopPtr);
188 uopPtr->setDelayedCommit();
189 }
190}
191
192PairMemOp::PairMemOp(const char *mnem, ExtMachInst machInst, OpClass __opClass,
193 uint32_t size, bool fp, bool load, bool noAlloc,
194 bool signExt, bool exclusive, bool acrel,
195 int64_t imm, AddrMode mode,
196 IntRegIndex rn, IntRegIndex rt, IntRegIndex rt2) :
197 PredMacroOp(mnem, machInst, __opClass)
198{
199 bool writeback = (mode != AddrMd_Offset);
200 numMicroops = 1 + (size / 4) + (writeback ? 1 : 0);
201 microOps = new StaticInstPtr[numMicroops];
202
203 StaticInstPtr *uop = microOps;
204
205 bool post = (mode == AddrMd_PostIndex);
206
207 rn = makeSP(rn);
208
209 *uop = new MicroAddXiSpAlignUop(machInst, INTREG_UREG0, rn, post ? 0 : imm);
210
211 if (fp) {
212 if (size == 16) {
213 if (load) {
214 *++uop = new MicroLdrQBFpXImmUop(machInst, rt,
215 INTREG_UREG0, 0, noAlloc, exclusive, acrel);
216 *++uop = new MicroLdrQTFpXImmUop(machInst, rt,
217 INTREG_UREG0, 0, noAlloc, exclusive, acrel);
218 *++uop = new MicroLdrQBFpXImmUop(machInst, rt2,
219 INTREG_UREG0, 16, noAlloc, exclusive, acrel);
220 *++uop = new MicroLdrQTFpXImmUop(machInst, rt2,
221 INTREG_UREG0, 16, noAlloc, exclusive, acrel);
222 } else {
223 *++uop = new MicroStrQBFpXImmUop(machInst, rt,
224 INTREG_UREG0, 0, noAlloc, exclusive, acrel);
225 *++uop = new MicroStrQTFpXImmUop(machInst, rt,
226 INTREG_UREG0, 0, noAlloc, exclusive, acrel);
227 *++uop = new MicroStrQBFpXImmUop(machInst, rt2,
228 INTREG_UREG0, 16, noAlloc, exclusive, acrel);
229 *++uop = new MicroStrQTFpXImmUop(machInst, rt2,
230 INTREG_UREG0, 16, noAlloc, exclusive, acrel);
231 }
232 } else if (size == 8) {
233 if (load) {
234 *++uop = new MicroLdrFpXImmUop(machInst, rt,
235 INTREG_UREG0, 0, noAlloc, exclusive, acrel);
236 *++uop = new MicroLdrFpXImmUop(machInst, rt2,
237 INTREG_UREG0, 8, noAlloc, exclusive, acrel);
238 } else {
239 *++uop = new MicroStrFpXImmUop(machInst, rt,
240 INTREG_UREG0, 0, noAlloc, exclusive, acrel);
241 *++uop = new MicroStrFpXImmUop(machInst, rt2,
242 INTREG_UREG0, 8, noAlloc, exclusive, acrel);
243 }
244 } else if (size == 4) {
245 if (load) {
246 *++uop = new MicroLdrDFpXImmUop(machInst, rt, rt2,
247 INTREG_UREG0, 0, noAlloc, exclusive, acrel);
248 } else {
249 *++uop = new MicroStrDFpXImmUop(machInst, rt, rt2,
250 INTREG_UREG0, 0, noAlloc, exclusive, acrel);
251 }
252 }
253 } else {
254 if (size == 8) {
255 if (load) {
256 *++uop = new MicroLdrXImmUop(machInst, rt, INTREG_UREG0,
257 0, noAlloc, exclusive, acrel);
258 *++uop = new MicroLdrXImmUop(machInst, rt2, INTREG_UREG0,
259 size, noAlloc, exclusive, acrel);
260 } else {
261 *++uop = new MicroStrXImmUop(machInst, rt, INTREG_UREG0,
262 0, noAlloc, exclusive, acrel);
263 *++uop = new MicroStrXImmUop(machInst, rt2, INTREG_UREG0,
264 size, noAlloc, exclusive, acrel);
265 }
266 } else if (size == 4) {
267 if (load) {
268 if (signExt) {
269 *++uop = new MicroLdrDSXImmUop(machInst, rt, rt2,
270 INTREG_UREG0, 0, noAlloc, exclusive, acrel);
271 } else {
272 *++uop = new MicroLdrDUXImmUop(machInst, rt, rt2,
273 INTREG_UREG0, 0, noAlloc, exclusive, acrel);
274 }
275 } else {
276 *++uop = new MicroStrDXImmUop(machInst, rt, rt2,
277 INTREG_UREG0, 0, noAlloc, exclusive, acrel);
278 }
279 }
280 }
281
282 if (writeback) {
283 *++uop = new MicroAddXiUop(machInst, rn, INTREG_UREG0,
284 post ? imm : 0);
285 }
286
287 (*uop)->setLastMicroop();
288
289 for (StaticInstPtr *curUop = microOps;
290 !(*curUop)->isLastMicroop(); curUop++) {
291 (*curUop)->setDelayedCommit();
292 }
293}
294
295BigFpMemImmOp::BigFpMemImmOp(const char *mnem, ExtMachInst machInst,
296 OpClass __opClass, bool load, IntRegIndex dest,
297 IntRegIndex base, int64_t imm) :
298 PredMacroOp(mnem, machInst, __opClass)
299{
300 numMicroops = 2;
301 microOps = new StaticInstPtr[numMicroops];
302
303 if (load) {
304 microOps[0] = new MicroLdrQBFpXImmUop(machInst, dest, base, imm);
305 microOps[1] = new MicroLdrQTFpXImmUop(machInst, dest, base, imm);
306 } else {
307 microOps[0] = new MicroStrQBFpXImmUop(machInst, dest, base, imm);
308 microOps[1] = new MicroStrQTFpXImmUop(machInst, dest, base, imm);
309 }
310 microOps[0]->setDelayedCommit();
311 microOps[1]->setLastMicroop();
312}
313
314BigFpMemPostOp::BigFpMemPostOp(const char *mnem, ExtMachInst machInst,
315 OpClass __opClass, bool load, IntRegIndex dest,
316 IntRegIndex base, int64_t imm) :
317 PredMacroOp(mnem, machInst, __opClass)
318{
319 numMicroops = 3;
320 microOps = new StaticInstPtr[numMicroops];
321
322 if (load) {
323 microOps[0] = new MicroLdrQBFpXImmUop(machInst, dest, base, 0);
324 microOps[1] = new MicroLdrQTFpXImmUop(machInst, dest, base, 0);
325 } else {
326 microOps[0] = new MicroStrQBFpXImmUop(machInst, dest, base, 0);
327 microOps[1] = new MicroStrQTFpXImmUop(machInst, dest, base, 0);
328 }
329 microOps[2] = new MicroAddXiUop(machInst, base, base, imm);
330
331 microOps[0]->setDelayedCommit();
332 microOps[1]->setDelayedCommit();
333 microOps[2]->setLastMicroop();
334}
335
336BigFpMemPreOp::BigFpMemPreOp(const char *mnem, ExtMachInst machInst,
337 OpClass __opClass, bool load, IntRegIndex dest,
338 IntRegIndex base, int64_t imm) :
339 PredMacroOp(mnem, machInst, __opClass)
340{
341 numMicroops = 3;
342 microOps = new StaticInstPtr[numMicroops];
343
344 if (load) {
345 microOps[0] = new MicroLdrQBFpXImmUop(machInst, dest, base, imm);
346 microOps[1] = new MicroLdrQTFpXImmUop(machInst, dest, base, imm);
347 } else {
348 microOps[0] = new MicroStrQBFpXImmUop(machInst, dest, base, imm);
349 microOps[1] = new MicroStrQTFpXImmUop(machInst, dest, base, imm);
350 }
351 microOps[2] = new MicroAddXiUop(machInst, base, base, imm);
352
353 microOps[0]->setDelayedCommit();
354 microOps[1]->setDelayedCommit();
355 microOps[2]->setLastMicroop();
356}
357
358BigFpMemRegOp::BigFpMemRegOp(const char *mnem, ExtMachInst machInst,
359 OpClass __opClass, bool load, IntRegIndex dest,
360 IntRegIndex base, IntRegIndex offset,
361 ArmExtendType type, int64_t imm) :
362 PredMacroOp(mnem, machInst, __opClass)
363{
364 numMicroops = 2;
365 microOps = new StaticInstPtr[numMicroops];
366
367 if (load) {
368 microOps[0] = new MicroLdrQBFpXRegUop(machInst, dest, base,
369 offset, type, imm);
370 microOps[1] = new MicroLdrQTFpXRegUop(machInst, dest, base,
371 offset, type, imm);
372 } else {
373 microOps[0] = new MicroStrQBFpXRegUop(machInst, dest, base,
374 offset, type, imm);
375 microOps[1] = new MicroStrQTFpXRegUop(machInst, dest, base,
376 offset, type, imm);
377 }
378
379 microOps[0]->setDelayedCommit();
380 microOps[1]->setLastMicroop();
381}
382
383BigFpMemLitOp::BigFpMemLitOp(const char *mnem, ExtMachInst machInst,
384 OpClass __opClass, IntRegIndex dest,
385 int64_t imm) :
386 PredMacroOp(mnem, machInst, __opClass)
387{
388 numMicroops = 2;
389 microOps = new StaticInstPtr[numMicroops];
390
391 microOps[0] = new MicroLdrQBFpXLitUop(machInst, dest, imm);
392 microOps[1] = new MicroLdrQTFpXLitUop(machInst, dest, imm);
393
394 microOps[0]->setDelayedCommit();
395 microOps[1]->setLastMicroop();
396}
397
398VldMultOp::VldMultOp(const char *mnem, ExtMachInst machInst, OpClass __opClass,
399 unsigned elems, RegIndex rn, RegIndex vd, unsigned regs,
400 unsigned inc, uint32_t size, uint32_t align, RegIndex rm) :
401 PredMacroOp(mnem, machInst, __opClass)
402{
403 assert(regs > 0 && regs <= 4);

--- 1129 unchanged lines hidden (view full) ---

1533 ss << ", [";
1534 printReg(ss, urb);
1535 ss << ", ";
1536 ccprintf(ss, "#%d", imm);
1537 ss << "]";
1538 return ss.str();
1539}
1540
1541}