2 // Copyright (c) 2010-2014 ARM Limited
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
9 // licensed hereunder. You may use the software subject to the license
10 // terms below provided that you ensure that this notice is replicated
11 // unmodified and in its entirety in all distributions of the software,
12 // modified or unmodified, in source code or in binary form.
14 // Copyright (c) 2007-2008 The Florida State University
15 // All rights reserved.
17 // Redistribution and use in source and binary forms, with or without
18 // modification, are permitted provided that the following conditions are
19 // met: redistributions of source code must retain the above copyright
20 // notice, this list of conditions and the following disclaimer;
21 // redistributions in binary form must reproduce the above copyright
22 // notice, this list of conditions and the following disclaimer in the
23 // documentation and/or other materials provided with the distribution;
24 // neither the name of the copyright holders nor the names of its
25 // contributors may be used to endorse or promote products derived from
26 // this software without specific prior written permission.
28 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
31 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
32 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
33 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
34 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
35 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
36 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
38 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
40 // Authors: Stephen Hines
57 ((%(reg_idx)s == PCReg) ? readPC(xc) : xc->%(func)s(this, %(op_idx)s))
59 maybeAlignedPCRead = '''
60 ((%(reg_idx)s == PCReg) ? (roundDown(readPC(xc), 4)) :
61 xc->%(func)s(this, %(op_idx)s))
64 ((%(reg_idx)s == PCReg) ? setNextPC(xc, %(final_val)s) :
65 xc->%(func)s(this, %(op_idx)s, %(final_val)s))
68 ((%(reg_idx)s == PCReg) ? setIWNextPC(xc, %(final_val)s) :
69 xc->%(func)s(this, %(op_idx)s, %(final_val)s))
72 if (%(reg_idx)s == PCReg) {
75 setNextPC(xc, %(final_val)s);
77 setIWNextPC(xc, %(final_val)s);
80 xc->%(func)s(this, %(op_idx)s, %(final_val)s);
84 ((xc->%(func)s(this, %(op_idx)s)) & mask(intWidth))
87 xc->%(func)s(this, %(op_idx)s, (%(final_val)s) & mask(intWidth))
90 ((xc->%(func)s(this, %(op_idx)s)) & mask(aarch64 ? 64 : 32))
93 xc->%(func)s(this, %(op_idx)s, (%(final_val)s) & mask(aarch64 ? 64 : 32))
96 ((xc->%(func)s(this, %(op_idx)s)) & mask(32))
99 xc->%(func)s(this, %(op_idx)s, (%(final_val)s) & mask(32))
101 cntrlNsBankedWrite = '''
102 xc->setMiscReg(flattenMiscRegNsBanked(dest, xc->tcBase()), %(final_val)s)
105 cntrlNsBankedRead = '''
106 xc->readMiscReg(flattenMiscRegNsBanked(op1, xc->tcBase()))
109 #PCState operands need to have a sorting index (the number at the end)
110 #less than all the integer registers which might update the PC. That way
111 #if the flag bits of the pc state are updated and a branch happens through
112 #R15, the updates are layered properly and the R15 update isn't lost.
121 return ('FloatReg', 'sf', idx, 'IsFloating', srtNormal)
124 return ('IntReg', 'uw', idx, 'IsInteger', srtNormal,
125 maybePCRead, maybePCWrite)
128 return ('IntReg', 'ud', idx, 'IsInteger', srtNormal,
129 aarch64Read, aarch64Write)
131 def intRegX64(idx, id = srtNormal):
132 return ('IntReg', 'ud', idx, 'IsInteger', id,
133 aarchX64Read, aarchX64Write)
135 def intRegW64(idx, id = srtNormal):
136 return ('IntReg', 'ud', idx, 'IsInteger', id,
137 aarchW64Read, aarchW64Write)
140 return ('IntReg', 'uw', idx, 'IsInteger', srtNormal)
142 def intRegAPC(idx, id = srtNormal):
143 return ('IntReg', 'uw', idx, 'IsInteger', id,
144 maybeAlignedPCRead, maybePCWrite)
147 return ('IntReg', 'uw', idx, 'IsInteger', srtNormal,
148 maybePCRead, maybeIWPCWrite)
150 def intRegAIWPC(idx):
151 return ('IntReg', 'uw', idx, 'IsInteger', srtNormal,
152 maybePCRead, maybeAIWPCWrite)
155 return ('CCReg', 'uw', idx, None, srtNormal)
157 def cntrlReg(idx, id = srtNormal, type = 'uw'):
158 return ('ControlReg', type, idx, None, id)
160 def cntrlNsBankedReg(idx, id = srtNormal, type = 'uw'):
161 return ('ControlReg', type, idx, (None, None, 'IsControl'), id, cntrlNsBankedRead, cntrlNsBankedWrite)
163 def cntrlNsBankedReg64(idx, id = srtNormal, type = 'ud'):
164 return ('ControlReg', type, idx, (None, None, 'IsControl'), id, cntrlNsBankedRead, cntrlNsBankedWrite)
166 def cntrlRegNC(idx, id = srtNormal, type = 'uw'):
167 return ('ControlReg', type, idx, None, id)
169 def pcStateReg(idx, id):
170 return ('PCState', 'ud', idx, (None, None, 'IsControl'), id)
174 #Abstracted integer reg operands
175 'Dest': intReg('dest'),
176 'Dest64': intReg64('dest'),
177 'XDest': intRegX64('dest'),
178 'WDest': intRegW64('dest'),
179 'IWDest': intRegIWPC('dest'),
180 'AIWDest': intRegAIWPC('dest'),
181 'Dest2': intReg('dest2'),
182 'XDest2': intRegX64('dest2'),
183 'FDest2': floatReg('dest2'),
184 'Result': intReg('result'),
185 'XResult': intRegX64('result'),
186 'XBase': intRegX64('base', id = srtBase),
187 'Base': intRegAPC('base', id = srtBase),
188 'XOffset': intRegX64('offset'),
189 'Index': intReg('index'),
190 'Shift': intReg('shift'),
191 'Op1': intReg('op1'),
192 'Op2': intReg('op2'),
193 'Op3': intReg('op3'),
194 'Op164': intReg64('op1'),
195 'Op264': intReg64('op2'),
196 'Op364': intReg64('op3'),
197 'XOp1': intRegX64('op1'),
198 'XOp2': intRegX64('op2'),
199 'XOp3': intRegX64('op3'),
200 'WOp1': intRegW64('op1'),
201 'WOp2': intRegW64('op2'),
202 'WOp3': intRegW64('op3'),
203 'Reg0': intReg('reg0'),
204 'Reg1': intReg('reg1'),
205 'Reg2': intReg('reg2'),
206 'Reg3': intReg('reg3'),
208 #Fixed index integer reg operands
209 'SpMode': intRegNPC('intRegInMode((OperatingMode)regMode, INTREG_SP)'),
210 'DecodedBankedIntReg': intRegNPC('decodeMrsMsrBankedIntRegIndex(byteMask, r)'),
211 'LR': intRegNPC('INTREG_LR'),
212 'XLR': intRegX64('INTREG_X30'),
213 'R7': intRegNPC('7'),
214 # First four arguments are passed in registers
215 'R0': intRegNPC('0'),
216 'R1': intRegNPC('1'),
217 'R2': intRegNPC('2'),
218 'R3': intRegNPC('3'),
219 'X0': intRegX64('0'),
220 'X1': intRegX64('1'),
221 'X2': intRegX64('2'),
222 'X3': intRegX64('3'),
224 # Condition code registers
225 'CondCodesNZ': ccReg('CCREG_NZ'),
226 'CondCodesC': ccReg('CCREG_C'),
227 'CondCodesV': ccReg('CCREG_V'),
228 'CondCodesGE': ccReg('CCREG_GE'),
229 'OptCondCodesNZ': ccReg(
230 '''((condCode == COND_AL || condCode == COND_UC ||
231 condCode == COND_CC || condCode == COND_CS ||
232 condCode == COND_VS || condCode == COND_VC) ?
233 CCREG_ZERO : CCREG_NZ)'''),
234 'OptCondCodesC': ccReg(
235 '''((condCode == COND_HI || condCode == COND_LS ||
236 condCode == COND_CS || condCode == COND_CC) ?
237 CCREG_C : CCREG_ZERO)'''),
238 'OptShiftRmCondCodesC': ccReg(
239 '''((condCode == COND_HI || condCode == COND_LS ||
240 condCode == COND_CS || condCode == COND_CC ||
242 CCREG_C : CCREG_ZERO)'''),
243 'OptCondCodesV': ccReg(
244 '''((condCode == COND_VS || condCode == COND_VC ||
245 condCode == COND_GE || condCode == COND_LT ||
246 condCode == COND_GT || condCode == COND_LE) ?
247 CCREG_V : CCREG_ZERO)'''),
248 'FpCondCodes': ccReg('CCREG_FP'),
250 #Abstracted floating point reg operands
251 'FpDest': floatReg('(dest + 0)'),
252 'FpDestP0': floatReg('(dest + 0)'),
253 'FpDestP1': floatReg('(dest + 1)'),
254 'FpDestP2': floatReg('(dest + 2)'),
255 'FpDestP3': floatReg('(dest + 3)'),
256 'FpDestP4': floatReg('(dest + 4)'),
257 'FpDestP5': floatReg('(dest + 5)'),
258 'FpDestP6': floatReg('(dest + 6)'),
259 'FpDestP7': floatReg('(dest + 7)'),
260 'FpDestS0P0': floatReg('(dest + step * 0 + 0)'),
261 'FpDestS0P1': floatReg('(dest + step * 0 + 1)'),
262 'FpDestS1P0': floatReg('(dest + step * 1 + 0)'),
263 'FpDestS1P1': floatReg('(dest + step * 1 + 1)'),
264 'FpDestS2P0': floatReg('(dest + step * 2 + 0)'),
265 'FpDestS2P1': floatReg('(dest + step * 2 + 1)'),
266 'FpDestS3P0': floatReg('(dest + step * 3 + 0)'),
267 'FpDestS3P1': floatReg('(dest + step * 3 + 1)'),
269 'FpDest2': floatReg('(dest2 + 0)'),
270 'FpDest2P0': floatReg('(dest2 + 0)'),
271 'FpDest2P1': floatReg('(dest2 + 1)'),
272 'FpDest2P2': floatReg('(dest2 + 2)'),
273 'FpDest2P3': floatReg('(dest2 + 3)'),
275 'FpOp1': floatReg('(op1 + 0)'),
276 'FpOp1P0': floatReg('(op1 + 0)'),
277 'FpOp1P1': floatReg('(op1 + 1)'),
278 'FpOp1P2': floatReg('(op1 + 2)'),
279 'FpOp1P3': floatReg('(op1 + 3)'),
280 'FpOp1P4': floatReg('(op1 + 4)'),
281 'FpOp1P5': floatReg('(op1 + 5)'),
282 'FpOp1P6': floatReg('(op1 + 6)'),
283 'FpOp1P7': floatReg('(op1 + 7)'),
284 'FpOp1S0P0': floatReg('(op1 + step * 0 + 0)'),
285 'FpOp1S0P1': floatReg('(op1 + step * 0 + 1)'),
286 'FpOp1S1P0': floatReg('(op1 + step * 1 + 0)'),
287 'FpOp1S1P1': floatReg('(op1 + step * 1 + 1)'),
288 'FpOp1S2P0': floatReg('(op1 + step * 2 + 0)'),
289 'FpOp1S2P1': floatReg('(op1 + step * 2 + 1)'),
290 'FpOp1S3P0': floatReg('(op1 + step * 3 + 0)'),
291 'FpOp1S3P1': floatReg('(op1 + step * 3 + 1)'),
293 'FpOp2': floatReg('(op2 + 0)'),
294 'FpOp2P0': floatReg('(op2 + 0)'),
295 'FpOp2P1': floatReg('(op2 + 1)'),
296 'FpOp2P2': floatReg('(op2 + 2)'),
297 'FpOp2P3': floatReg('(op2 + 3)'),
299 # Create AArch64 unpacked view of the FP registers
300 'AA64FpOp1P0': floatReg('((op1 * 4) + 0)'),
301 'AA64FpOp1P1': floatReg('((op1 * 4) + 1)'),
302 'AA64FpOp1P2': floatReg('((op1 * 4) + 2)'),
303 'AA64FpOp1P3': floatReg('((op1 * 4) + 3)'),
304 'AA64FpOp2P0': floatReg('((op2 * 4) + 0)'),
305 'AA64FpOp2P1': floatReg('((op2 * 4) + 1)'),
306 'AA64FpOp2P2': floatReg('((op2 * 4) + 2)'),
307 'AA64FpOp2P3': floatReg('((op2 * 4) + 3)'),
308 'AA64FpOp3P0': floatReg('((op3 * 4) + 0)'),
309 'AA64FpOp3P1': floatReg('((op3 * 4) + 1)'),
310 'AA64FpOp3P2': floatReg('((op3 * 4) + 2)'),
311 'AA64FpOp3P3': floatReg('((op3 * 4) + 3)'),
312 'AA64FpDestP0': floatReg('((dest * 4) + 0)'),
313 'AA64FpDestP1': floatReg('((dest * 4) + 1)'),
314 'AA64FpDestP2': floatReg('((dest * 4) + 2)'),
315 'AA64FpDestP3': floatReg('((dest * 4) + 3)'),
316 'AA64FpDest2P0': floatReg('((dest2 * 4) + 0)'),
317 'AA64FpDest2P1': floatReg('((dest2 * 4) + 1)'),
318 'AA64FpDest2P2': floatReg('((dest2 * 4) + 2)'),
319 'AA64FpDest2P3': floatReg('((dest2 * 4) + 3)'),
321 'AA64FpOp1P0V0': floatReg('((((op1+0)) * 4) + 0)'),
322 'AA64FpOp1P1V0': floatReg('((((op1+0)) * 4) + 1)'),
323 'AA64FpOp1P2V0': floatReg('((((op1+0)) * 4) + 2)'),
324 'AA64FpOp1P3V0': floatReg('((((op1+0)) * 4) + 3)'),
326 'AA64FpOp1P0V1': floatReg('((((op1+1)) * 4) + 0)'),
327 'AA64FpOp1P1V1': floatReg('((((op1+1)) * 4) + 1)'),
328 'AA64FpOp1P2V1': floatReg('((((op1+1)) * 4) + 2)'),
329 'AA64FpOp1P3V1': floatReg('((((op1+1)) * 4) + 3)'),
331 'AA64FpOp1P0V2': floatReg('((((op1+2)) * 4) + 0)'),
332 'AA64FpOp1P1V2': floatReg('((((op1+2)) * 4) + 1)'),
333 'AA64FpOp1P2V2': floatReg('((((op1+2)) * 4) + 2)'),
334 'AA64FpOp1P3V2': floatReg('((((op1+2)) * 4) + 3)'),
336 'AA64FpOp1P0V3': floatReg('((((op1+3)) * 4) + 0)'),
337 'AA64FpOp1P1V3': floatReg('((((op1+3)) * 4) + 1)'),
338 'AA64FpOp1P2V3': floatReg('((((op1+3)) * 4) + 2)'),
339 'AA64FpOp1P3V3': floatReg('((((op1+3)) * 4) + 3)'),
341 'AA64FpOp1P0V0S': floatReg('((((op1+0)%32) * 4) + 0)'),
342 'AA64FpOp1P1V0S': floatReg('((((op1+0)%32) * 4) + 1)'),
343 'AA64FpOp1P2V0S': floatReg('((((op1+0)%32) * 4) + 2)'),
344 'AA64FpOp1P3V0S': floatReg('((((op1+0)%32) * 4) + 3)'),
346 'AA64FpOp1P0V1S': floatReg('((((op1+1)%32) * 4) + 0)'),
347 'AA64FpOp1P1V1S': floatReg('((((op1+1)%32) * 4) + 1)'),
348 'AA64FpOp1P2V1S': floatReg('((((op1+1)%32) * 4) + 2)'),
349 'AA64FpOp1P3V1S': floatReg('((((op1+1)%32) * 4) + 3)'),
351 'AA64FpOp1P0V2S': floatReg('((((op1+2)%32) * 4) + 0)'),
352 'AA64FpOp1P1V2S': floatReg('((((op1+2)%32) * 4) + 1)'),
353 'AA64FpOp1P2V2S': floatReg('((((op1+2)%32) * 4) + 2)'),
354 'AA64FpOp1P3V2S': floatReg('((((op1+2)%32) * 4) + 3)'),
356 'AA64FpOp1P0V3S': floatReg('((((op1+3)%32) * 4) + 0)'),
357 'AA64FpOp1P1V3S': floatReg('((((op1+3)%32) * 4) + 1)'),
358 'AA64FpOp1P2V3S': floatReg('((((op1+3)%32) * 4) + 2)'),
359 'AA64FpOp1P3V3S': floatReg('((((op1+3)%32) * 4) + 3)'),
361 'AA64FpDestP0V0': floatReg('((((dest+0)) * 4) + 0)'),
362 'AA64FpDestP1V0': floatReg('((((dest+0)) * 4) + 1)'),
363 'AA64FpDestP2V0': floatReg('((((dest+0)) * 4) + 2)'),
364 'AA64FpDestP3V0': floatReg('((((dest+0)) * 4) + 3)'),
366 'AA64FpDestP0V1': floatReg('((((dest+1)) * 4) + 0)'),
367 'AA64FpDestP1V1': floatReg('((((dest+1)) * 4) + 1)'),
368 'AA64FpDestP2V1': floatReg('((((dest+1)) * 4) + 2)'),
369 'AA64FpDestP3V1': floatReg('((((dest+1)) * 4) + 3)'),
371 'AA64FpDestP0V0L': floatReg('((((dest+0)%32) * 4) + 0)'),
372 'AA64FpDestP1V0L': floatReg('((((dest+0)%32) * 4) + 1)'),
373 'AA64FpDestP2V0L': floatReg('((((dest+0)%32) * 4) + 2)'),
374 'AA64FpDestP3V0L': floatReg('((((dest+0)%32) * 4) + 3)'),
376 'AA64FpDestP0V1L': floatReg('((((dest+1)%32) * 4) + 0)'),
377 'AA64FpDestP1V1L': floatReg('((((dest+1)%32) * 4) + 1)'),
378 'AA64FpDestP2V1L': floatReg('((((dest+1)%32) * 4) + 2)'),
379 'AA64FpDestP3V1L': floatReg('((((dest+1)%32) * 4) + 3)'),
381 #Abstracted control reg operands
382 'MiscDest': cntrlReg('dest'),
383 'MiscOp1': cntrlReg('op1'),
384 'MiscNsBankedDest': cntrlNsBankedReg('dest'),
385 'MiscNsBankedOp1': cntrlNsBankedReg('op1'),
386 'MiscNsBankedDest64': cntrlNsBankedReg64('dest'),
387 'MiscNsBankedOp164': cntrlNsBankedReg64('op1'),
389 #Fixed index control regs
390 'Cpsr': cntrlReg('MISCREG_CPSR', srtCpsr),
391 'CpsrQ': cntrlReg('MISCREG_CPSR_Q', srtCpsr),
392 'Spsr': cntrlRegNC('MISCREG_SPSR'),
393 'Fpsr': cntrlRegNC('MISCREG_FPSR'),
394 'Fpsid': cntrlRegNC('MISCREG_FPSID'),
395 'Fpscr': cntrlRegNC('MISCREG_FPSCR'),
396 'FpscrQc': cntrlRegNC('MISCREG_FPSCR_QC'),
397 'FpscrExc': cntrlRegNC('MISCREG_FPSCR_EXC'),
398 'Cpacr': cntrlReg('MISCREG_CPACR'),
399 'Cpacr64': cntrlReg('MISCREG_CPACR_EL1'),
400 'Fpexc': cntrlRegNC('MISCREG_FPEXC'),
401 'Nsacr': cntrlReg('MISCREG_NSACR'),
402 'ElrHyp': cntrlRegNC('MISCREG_ELR_HYP'),
403 'Hcr': cntrlReg('MISCREG_HCR'),
404 'Hcr64': cntrlReg('MISCREG_HCR_EL2'),
405 'Hdcr': cntrlReg('MISCREG_HDCR'),
406 'Hcptr': cntrlReg('MISCREG_HCPTR'),
407 'CptrEl264': cntrlReg('MISCREG_CPTR_EL2'),
408 'CptrEl364': cntrlReg('MISCREG_CPTR_EL3'),
409 'Hstr': cntrlReg('MISCREG_HSTR'),
410 'Scr': cntrlReg('MISCREG_SCR'),
411 'Scr64': cntrlReg('MISCREG_SCR_EL3'),
412 'Sctlr': cntrlRegNC('MISCREG_SCTLR'),
413 'SevMailbox': cntrlRegNC('MISCREG_SEV_MAILBOX'),
414 'LLSCLock': cntrlRegNC('MISCREG_LOCKFLAG'),
415 'Dczid' : cntrlRegNC('MISCREG_DCZID_EL0'),
417 #Register fields for microops
418 'URa' : intReg('ura'),
419 'XURa' : intRegX64('ura'),
420 'WURa' : intRegW64('ura'),
421 'IWRa' : intRegIWPC('ura'),
422 'Fa' : floatReg('ura'),
423 'FaP1' : floatReg('ura + 1'),
424 'URb' : intReg('urb'),
425 'XURb' : intRegX64('urb'),
426 'URc' : intReg('urc'),
427 'XURc' : intRegX64('urc'),
430 'Mem': ('Mem', 'uw', None, ('IsMemRef', 'IsLoad', 'IsStore'), srtNormal),
433 'RawPC': pcStateReg('pc', srtPC),
434 'PC': pcStateReg('instPC', srtPC),
435 'NPC': pcStateReg('instNPC', srtPC),
436 'pNPC': pcStateReg('instNPC', srtEPC),
437 'IWNPC': pcStateReg('instIWNPC', srtPC),
438 'Thumb': pcStateReg('thumb', srtPC),
439 'NextThumb': pcStateReg('nextThumb', srtMode),
440 'NextJazelle': pcStateReg('nextJazelle', srtMode),
441 'NextItState': pcStateReg('nextItstate', srtMode),
442 'Itstate': pcStateReg('itstate', srtMode),
444 #Register operands depending on a field in the instruction encoding. These
445 #should be avoided since they may not be portable across different
446 #encodings of the same instruction.