macromem.cc (10339:53278be85b40) macromem.cc (10346:d96b61d843b2)
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);
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;
64 uint32_t mem_ops = ones;
66
65
67 // It's technically legal to do a lot of nothing
68 if (!ones)
66 // Copy the base address register if we overwrite it, or if this instruction
67 // is basically a no-op (we have to do something)
68 bool copy_base = (bits(reglist, rn) && load) || !ones;
69 bool force_user = user & !bits(reglist, 15);
70 bool exception_ret = user & bits(reglist, 15);
71 bool pc_temp = load && writeback && bits(reglist, 15);
72
73 if (!ones) {
69 numMicroops = 1;
74 numMicroops = 1;
75 } else if (load) {
76 numMicroops = ((ones + 1) / 2)
77 + ((ones % 2 == 0 && exception_ret) ? 1 : 0)
78 + (copy_base ? 1 : 0)
79 + (writeback? 1 : 0)
80 + (pc_temp ? 1 : 0);
81 } else {
82 numMicroops = ones + (writeback ? 1 : 0);
83 }
70
71 microOps = new StaticInstPtr[numMicroops];
84
85 microOps = new StaticInstPtr[numMicroops];
86
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.
87 uint32_t addr = 0;
88
89 if (!up)
90 addr = (ones << 2) - 4;
91
92 if (!index)
93 addr += 4;
94
95 StaticInstPtr *uop = microOps;
96
97 // Add 0 to Rn and stick it in ureg0.
98 // This is equivalent to a move.
84 *uop = new MicroAddiUop(machInst, INTREG_UREG0, rn, 0);
99 if (copy_base)
100 *uop++ = new MicroAddiUop(machInst, INTREG_UREG0, rn, 0);
85
86 unsigned reg = 0;
101
102 unsigned reg = 0;
87 unsigned regIdx = 0;
88 bool force_user = user & !bits(reglist, 15);
89 bool exception_ret = user & bits(reglist, 15);
103 while (mem_ops != 0) {
104 // Do load operations in pairs if possible
105 if (load && mem_ops >= 2 &&
106 !(mem_ops == 2 && bits(regs,INTREG_PC) && exception_ret)) {
107 // 64-bit memory operation
108 // Find 2 set register bits (clear them after finding)
109 unsigned reg_idx1;
110 unsigned reg_idx2;
90
111
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);
112 // Find the first register
113 while (!bits(regs, reg)) reg++;
114 replaceBits(regs, reg, 0);
115 reg_idx1 = force_user ? intRegInMode(MODE_USER, reg) : reg;
96
116
97 regIdx = reg;
98 if (force_user) {
99 regIdx = intRegInMode(MODE_USER, regIdx);
100 }
117 // Find the second register
118 while (!bits(regs, reg)) reg++;
119 replaceBits(regs, reg, 0);
120 reg_idx2 = force_user ? intRegInMode(MODE_USER, reg) : reg;
101
121
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);
122 // Load into temp reg if necessary
123 if (reg_idx2 == INTREG_PC && pc_temp)
124 reg_idx2 = INTREG_UREG1;
125
126 // Actually load both registers from memory
127 *uop = new MicroLdr2Uop(machInst, reg_idx1, reg_idx2,
128 copy_base ? INTREG_UREG0 : rn, up, addr);
129
130 if (!writeback && reg_idx2 == INTREG_PC) {
131 // No writeback if idx==pc, set appropriate flags
132 (*uop)->setFlag(StaticInst::IsControl);
133 (*uop)->setFlag(StaticInst::IsIndirectControl);
134
135 if (!(condCode == COND_AL || condCode == COND_UC))
136 (*uop)->setFlag(StaticInst::IsCondControl);
137 else
138 (*uop)->setFlag(StaticInst::IsUncondControl);
139 }
140
141 if (up) addr += 8;
142 else addr -= 8;
143 mem_ops -= 2;
144 } else {
145 // 32-bit memory operation
146 // Find register for operation
147 unsigned reg_idx;
148 while(!bits(regs, reg)) reg++;
149 replaceBits(regs, reg, 0);
150 reg_idx = force_user ? intRegInMode(MODE_USER, reg) : reg;
151
152 if (load) {
153 if (writeback && reg_idx == INTREG_PC) {
154 // If this instruction changes the PC and performs a
155 // writeback, ensure the pc load/branch is the last uop.
156 // Load into a temp reg here.
157 *uop = new MicroLdrUop(machInst, INTREG_UREG1,
158 copy_base ? INTREG_UREG0 : rn, up, addr);
159 } else if (reg_idx == INTREG_PC && exception_ret) {
160 // Special handling for exception return
161 *uop = new MicroLdrRetUop(machInst, reg_idx,
162 copy_base ? INTREG_UREG0 : rn, up, addr);
163 } else {
164 // standard single load uop
165 *uop = new MicroLdrUop(machInst, reg_idx,
166 copy_base ? INTREG_UREG0 : rn, up, addr);
167 }
168
169 // Loading pc as last operation? Set appropriate flags.
170 if (!writeback && reg_idx == INTREG_PC) {
171 (*uop)->setFlag(StaticInst::IsControl);
172 (*uop)->setFlag(StaticInst::IsIndirectControl);
173
115 if (!(condCode == COND_AL || condCode == COND_UC))
116 (*uop)->setFlag(StaticInst::IsCondControl);
117 else
118 (*uop)->setFlag(StaticInst::IsUncondControl);
174 if (!(condCode == COND_AL || condCode == COND_UC))
175 (*uop)->setFlag(StaticInst::IsCondControl);
176 else
177 (*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 }
178 }
179 } else {
180 *uop = new MicroStrUop(machInst, reg_idx, rn, up, addr);
131 }
181 }
132 } else {
133 *++uop = new MicroStrUop(machInst, regIdx, INTREG_UREG0, up, addr);
182
183 if (up) addr += 4;
184 else addr -= 4;
185 --mem_ops;
134 }
135
186 }
187
136 if (up)
137 addr += 4;
138 else
139 addr -= 4;
188 // Load/store micro-op generated, go to next uop
189 ++uop;
140 }
141
142 if (writeback && ones) {
190 }
191
192 if (writeback && ones) {
143 // put the register update after we're done all loading
193 // Perform writeback uop operation
144 if (up)
194 if (up)
145 *++uop = new MicroAddiUop(machInst, rn, rn, ones * 4);
195 *uop++ = new MicroAddiUop(machInst, rn, rn, ones * 4);
146 else
196 else
147 *++uop = new MicroSubiUop(machInst, rn, rn, ones * 4);
197 *uop++ = new MicroSubiUop(machInst, rn, rn, ones * 4);
148
198
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);
199 // Write PC after address writeback?
200 if (pc_temp) {
201 if (exception_ret) {
202 *uop = new MicroUopRegMovRet(machInst, 0, INTREG_UREG1);
203 } else {
204 *uop = new MicroUopRegMov(machInst, INTREG_PC, INTREG_UREG1);
205 }
206 (*uop)->setFlag(StaticInst::IsControl);
207 (*uop)->setFlag(StaticInst::IsIndirectControl);
208
154 if (!(condCode == COND_AL || condCode == COND_UC))
155 (*uop)->setFlag(StaticInst::IsCondControl);
156 else
157 (*uop)->setFlag(StaticInst::IsUncondControl);
209 if (!(condCode == COND_AL || condCode == COND_UC))
210 (*uop)->setFlag(StaticInst::IsCondControl);
211 else
212 (*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
213
168 }
214 if (rn == INTREG_SP)
215 (*uop)->setFlag(StaticInst::IsReturn);
216
217 ++uop;
169 }
170 }
171
218 }
219 }
220
221 --uop;
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);
222 (*uop)->setLastMicroop();
223
224 /* Take the control flags from the last microop for the macroop */
225 if ((*uop)->isControl())
226 setFlag(StaticInst::IsControl);
227 if ((*uop)->isCondCtrl())
228 setFlag(StaticInst::IsCondControl);
229 if ((*uop)->isUncondCtrl())
230 setFlag(StaticInst::IsUncondControl);
179 if ((*uop)->isIndirectCtrl())
180 setFlag(StaticInst::IsIndirectControl);
181 if ((*uop)->isReturn())
182 setFlag(StaticInst::IsReturn);
183
231 if ((*uop)->isIndirectCtrl())
232 setFlag(StaticInst::IsIndirectControl);
233 if ((*uop)->isReturn())
234 setFlag(StaticInst::IsReturn);
235
184 for (StaticInstPtr *curUop = microOps;
185 !(*curUop)->isLastMicroop(); curUop++) {
186 MicroOp * uopPtr = dynamic_cast<MicroOp *>(curUop->get());
187 assert(uopPtr);
188 uopPtr->setDelayedCommit();
236 for (StaticInstPtr *uop = microOps; !(*uop)->isLastMicroop(); uop++) {
237 (*uop)->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{
238 }
239}
240
241PairMemOp::PairMemOp(const char *mnem, ExtMachInst machInst, OpClass __opClass,
242 uint32_t size, bool fp, bool load, bool noAlloc,
243 bool signExt, bool exclusive, bool acrel,
244 int64_t imm, AddrMode mode,
245 IntRegIndex rn, IntRegIndex rt, IntRegIndex rt2) :
246 PredMacroOp(mnem, machInst, __opClass)
247{
248 bool post = (mode == AddrMd_PostIndex);
199 bool writeback = (mode != AddrMd_Offset);
249 bool writeback = (mode != AddrMd_Offset);
200 numMicroops = 1 + (size / 4) + (writeback ? 1 : 0);
250
251 if (load) {
252 // Use integer rounding to round up loads of size 4
253 numMicroops = (post ? 0 : 1) + ((size + 4) / 8) + (writeback ? 1 : 0);
254 } else {
255 numMicroops = (post ? 0 : 1) + (size / 4) + (writeback ? 1 : 0);
256 }
201 microOps = new StaticInstPtr[numMicroops];
202
203 StaticInstPtr *uop = microOps;
204
257 microOps = new StaticInstPtr[numMicroops];
258
259 StaticInstPtr *uop = microOps;
260
205 bool post = (mode == AddrMd_PostIndex);
206
207 rn = makeSP(rn);
208
261 rn = makeSP(rn);
262
209 *uop = new MicroAddXiSpAlignUop(machInst, INTREG_UREG0, rn, post ? 0 : imm);
263 if (!post) {
264 *uop++ = new MicroAddXiSpAlignUop(machInst, INTREG_UREG0, rn,
265 post ? 0 : imm);
266 }
210
211 if (fp) {
212 if (size == 16) {
213 if (load) {
267
268 if (fp) {
269 if (size == 16) {
270 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);
271 *uop++ = new MicroLdFp16Uop(machInst, rt,
272 post ? rn : INTREG_UREG0, 0, noAlloc, exclusive, acrel);
273 *uop++ = new MicroLdFp16Uop(machInst, rt2,
274 post ? rn : INTREG_UREG0, 16, noAlloc, exclusive, acrel);
222 } else {
275 } 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);
276 *uop++ = new MicroStrQBFpXImmUop(machInst, rt,
277 post ? rn : INTREG_UREG0, 0, noAlloc, exclusive, acrel);
278 *uop++ = new MicroStrQTFpXImmUop(machInst, rt,
279 post ? rn : INTREG_UREG0, 0, noAlloc, exclusive, acrel);
280 *uop++ = new MicroStrQBFpXImmUop(machInst, rt2,
281 post ? rn : INTREG_UREG0, 16, noAlloc, exclusive, acrel);
282 *uop++ = new MicroStrQTFpXImmUop(machInst, rt2,
283 post ? rn : INTREG_UREG0, 16, noAlloc, exclusive, acrel);
231 }
232 } else if (size == 8) {
233 if (load) {
284 }
285 } else if (size == 8) {
286 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);
287 *uop++ = new MicroLdPairFp8Uop(machInst, rt, rt2,
288 post ? rn : INTREG_UREG0, 0, noAlloc, exclusive, acrel);
238 } else {
289 } 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);
290 *uop++ = new MicroStrFpXImmUop(machInst, rt,
291 post ? rn : INTREG_UREG0, 0, noAlloc, exclusive, acrel);
292 *uop++ = new MicroStrFpXImmUop(machInst, rt2,
293 post ? rn : INTREG_UREG0, 8, noAlloc, exclusive, acrel);
243 }
244 } else if (size == 4) {
245 if (load) {
294 }
295 } else if (size == 4) {
296 if (load) {
246 *++uop = new MicroLdrDFpXImmUop(machInst, rt, rt2,
247 INTREG_UREG0, 0, noAlloc, exclusive, acrel);
297 *uop++ = new MicroLdrDFpXImmUop(machInst, rt, rt2,
298 post ? rn : INTREG_UREG0, 0, noAlloc, exclusive, acrel);
248 } else {
299 } else {
249 *++uop = new MicroStrDFpXImmUop(machInst, rt, rt2,
250 INTREG_UREG0, 0, noAlloc, exclusive, acrel);
300 *uop++ = new MicroStrDFpXImmUop(machInst, rt, rt2,
301 post ? rn : INTREG_UREG0, 0, noAlloc, exclusive, acrel);
251 }
252 }
253 } else {
254 if (size == 8) {
255 if (load) {
302 }
303 }
304 } else {
305 if (size == 8) {
306 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);
307 *uop++ = new MicroLdPairUop(machInst, rt, rt2,
308 post ? rn : INTREG_UREG0, 0, noAlloc, exclusive, acrel);
260 } else {
309 } else {
261 *++uop = new MicroStrXImmUop(machInst, rt, INTREG_UREG0,
310 *uop++ = new MicroStrXImmUop(machInst, rt, post ? rn : INTREG_UREG0,
262 0, noAlloc, exclusive, acrel);
311 0, noAlloc, exclusive, acrel);
263 *++uop = new MicroStrXImmUop(machInst, rt2, INTREG_UREG0,
312 *uop++ = new MicroStrXImmUop(machInst, rt2, post ? rn : INTREG_UREG0,
264 size, noAlloc, exclusive, acrel);
265 }
266 } else if (size == 4) {
267 if (load) {
268 if (signExt) {
313 size, noAlloc, exclusive, acrel);
314 }
315 } else if (size == 4) {
316 if (load) {
317 if (signExt) {
269 *++uop = new MicroLdrDSXImmUop(machInst, rt, rt2,
270 INTREG_UREG0, 0, noAlloc, exclusive, acrel);
318 *uop++ = new MicroLdrDSXImmUop(machInst, rt, rt2,
319 post ? rn : INTREG_UREG0, 0, noAlloc, exclusive, acrel);
271 } else {
320 } else {
272 *++uop = new MicroLdrDUXImmUop(machInst, rt, rt2,
273 INTREG_UREG0, 0, noAlloc, exclusive, acrel);
321 *uop++ = new MicroLdrDUXImmUop(machInst, rt, rt2,
322 post ? rn : INTREG_UREG0, 0, noAlloc, exclusive, acrel);
274 }
275 } else {
323 }
324 } else {
276 *++uop = new MicroStrDXImmUop(machInst, rt, rt2,
277 INTREG_UREG0, 0, noAlloc, exclusive, acrel);
325 *uop++ = new MicroStrDXImmUop(machInst, rt, rt2,
326 post ? rn : INTREG_UREG0, 0, noAlloc, exclusive, acrel);
278 }
279 }
280 }
281
282 if (writeback) {
327 }
328 }
329 }
330
331 if (writeback) {
283 *++uop = new MicroAddXiUop(machInst, rn, INTREG_UREG0,
332 *uop++ = new MicroAddXiUop(machInst, rn, post ? rn : INTREG_UREG0,
284 post ? imm : 0);
285 }
286
333 post ? imm : 0);
334 }
335
287 (*uop)->setLastMicroop();
336 assert(uop == &microOps[numMicroops]);
337 (*--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{
338
339 for (StaticInstPtr *curUop = microOps;
340 !(*curUop)->isLastMicroop(); curUop++) {
341 (*curUop)->setDelayedCommit();
342 }
343}
344
345BigFpMemImmOp::BigFpMemImmOp(const char *mnem, ExtMachInst machInst,
346 OpClass __opClass, bool load, IntRegIndex dest,
347 IntRegIndex base, int64_t imm) :
348 PredMacroOp(mnem, machInst, __opClass)
349{
300 numMicroops = 2;
350 numMicroops = load ? 1 : 2;
301 microOps = new StaticInstPtr[numMicroops];
302
351 microOps = new StaticInstPtr[numMicroops];
352
353 StaticInstPtr *uop = microOps;
354
303 if (load) {
355 if (load) {
304 microOps[0] = new MicroLdrQBFpXImmUop(machInst, dest, base, imm);
305 microOps[1] = new MicroLdrQTFpXImmUop(machInst, dest, base, imm);
356 *uop = new MicroLdFp16Uop(machInst, dest, base, imm);
306 } else {
357 } else {
307 microOps[0] = new MicroStrQBFpXImmUop(machInst, dest, base, imm);
308 microOps[1] = new MicroStrQTFpXImmUop(machInst, dest, base, imm);
358 *uop = new MicroStrQBFpXImmUop(machInst, dest, base, imm);
359 (*uop)->setDelayedCommit();
360 *++uop = new MicroStrQTFpXImmUop(machInst, dest, base, imm);
309 }
361 }
310 microOps[0]->setDelayedCommit();
311 microOps[1]->setLastMicroop();
362 (*uop)->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{
363}
364
365BigFpMemPostOp::BigFpMemPostOp(const char *mnem, ExtMachInst machInst,
366 OpClass __opClass, bool load, IntRegIndex dest,
367 IntRegIndex base, int64_t imm) :
368 PredMacroOp(mnem, machInst, __opClass)
369{
319 numMicroops = 3;
370 numMicroops = load ? 2 : 3;
320 microOps = new StaticInstPtr[numMicroops];
321
371 microOps = new StaticInstPtr[numMicroops];
372
373 StaticInstPtr *uop = microOps;
374
322 if (load) {
375 if (load) {
323 microOps[0] = new MicroLdrQBFpXImmUop(machInst, dest, base, 0);
324 microOps[1] = new MicroLdrQTFpXImmUop(machInst, dest, base, 0);
376 *uop++ = new MicroLdFp16Uop(machInst, dest, base, 0);
325 } else {
377 } else {
326 microOps[0] = new MicroStrQBFpXImmUop(machInst, dest, base, 0);
327 microOps[1] = new MicroStrQTFpXImmUop(machInst, dest, base, 0);
378 *uop++= new MicroStrQBFpXImmUop(machInst, dest, base, 0);
379 *uop++ = new MicroStrQTFpXImmUop(machInst, dest, base, 0);
328 }
380 }
329 microOps[2] = new MicroAddXiUop(machInst, base, base, imm);
381 *uop = new MicroAddXiUop(machInst, base, base, imm);
382 (*uop)->setLastMicroop();
330
383
331 microOps[0]->setDelayedCommit();
332 microOps[1]->setDelayedCommit();
333 microOps[2]->setLastMicroop();
384 for (StaticInstPtr *curUop = microOps;
385 !(*curUop)->isLastMicroop(); curUop++) {
386 (*curUop)->setDelayedCommit();
387 }
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{
388}
389
390BigFpMemPreOp::BigFpMemPreOp(const char *mnem, ExtMachInst machInst,
391 OpClass __opClass, bool load, IntRegIndex dest,
392 IntRegIndex base, int64_t imm) :
393 PredMacroOp(mnem, machInst, __opClass)
394{
341 numMicroops = 3;
395 numMicroops = load ? 2 : 3;
342 microOps = new StaticInstPtr[numMicroops];
343
396 microOps = new StaticInstPtr[numMicroops];
397
398 StaticInstPtr *uop = microOps;
399
344 if (load) {
400 if (load) {
345 microOps[0] = new MicroLdrQBFpXImmUop(machInst, dest, base, imm);
346 microOps[1] = new MicroLdrQTFpXImmUop(machInst, dest, base, imm);
401 *uop++ = new MicroLdFp16Uop(machInst, dest, base, imm);
347 } else {
402 } else {
348 microOps[0] = new MicroStrQBFpXImmUop(machInst, dest, base, imm);
349 microOps[1] = new MicroStrQTFpXImmUop(machInst, dest, base, imm);
403 *uop++ = new MicroStrQBFpXImmUop(machInst, dest, base, imm);
404 *uop++ = new MicroStrQTFpXImmUop(machInst, dest, base, imm);
350 }
405 }
351 microOps[2] = new MicroAddXiUop(machInst, base, base, imm);
406 *uop = new MicroAddXiUop(machInst, base, base, imm);
407 (*uop)->setLastMicroop();
352
408
353 microOps[0]->setDelayedCommit();
354 microOps[1]->setDelayedCommit();
355 microOps[2]->setLastMicroop();
409 for (StaticInstPtr *curUop = microOps;
410 !(*curUop)->isLastMicroop(); curUop++) {
411 (*curUop)->setDelayedCommit();
412 }
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{
413}
414
415BigFpMemRegOp::BigFpMemRegOp(const char *mnem, ExtMachInst machInst,
416 OpClass __opClass, bool load, IntRegIndex dest,
417 IntRegIndex base, IntRegIndex offset,
418 ArmExtendType type, int64_t imm) :
419 PredMacroOp(mnem, machInst, __opClass)
420{
364 numMicroops = 2;
421 numMicroops = load ? 1 : 2;
365 microOps = new StaticInstPtr[numMicroops];
366
422 microOps = new StaticInstPtr[numMicroops];
423
424 StaticInstPtr *uop = microOps;
425
367 if (load) {
426 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);
427 *uop = new MicroLdFp16RegUop(machInst, dest, base,
428 offset, type, imm);
372 } else {
429 } 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);
430 *uop = new MicroStrQBFpXRegUop(machInst, dest, base,
431 offset, type, imm);
432 (*uop)->setDelayedCommit();
433 *++uop = new MicroStrQTFpXRegUop(machInst, dest, base,
434 offset, type, imm);
377 }
378
435 }
436
379 microOps[0]->setDelayedCommit();
380 microOps[1]->setLastMicroop();
437 (*uop)->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{
438}
439
440BigFpMemLitOp::BigFpMemLitOp(const char *mnem, ExtMachInst machInst,
441 OpClass __opClass, IntRegIndex dest,
442 int64_t imm) :
443 PredMacroOp(mnem, machInst, __opClass)
444{
388 numMicroops = 2;
445 numMicroops = 1;
389 microOps = new StaticInstPtr[numMicroops];
390
446 microOps = new StaticInstPtr[numMicroops];
447
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();
448 microOps[0] = new MicroLdFp16LitUop(machInst, dest, imm);
449 microOps[0]->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
450}
451
452VldMultOp::VldMultOp(const char *mnem, ExtMachInst machInst, OpClass __opClass,
453 unsigned elems, RegIndex rn, RegIndex vd, unsigned regs,
454 unsigned inc, uint32_t size, uint32_t align, RegIndex rm) :
455 PredMacroOp(mnem, machInst, __opClass)
456{
457 assert(regs > 0 && regs <= 4);

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

1587 ss << ", [";
1588 printReg(ss, urb);
1589 ss << ", ";
1590 ccprintf(ss, "#%d", imm);
1591 ss << "]";
1592 return ss.str();
1593}
1594
1595std::string
1596MicroMemPairOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
1597{
1598 std::stringstream ss;
1599 printMnemonic(ss);
1600 printReg(ss, dest);
1601 ss << ",";
1602 printReg(ss, dest2);
1603 ss << ", [";
1604 printReg(ss, urb);
1605 ss << ", ";
1606 ccprintf(ss, "#%d", imm);
1607 ss << "]";
1608 return ss.str();
1541}
1609}
1610
1611}