HPI.py revision 12149
1# Copyright (c) 2014-2017 ARM Limited
2# All rights reserved.
3#
4# The license below extends only to copyright in the software and shall
5# not be construed as granting a license to any other intellectual
6# property including but not limited to intellectual property relating
7# to a hardware implementation of the functionality of the software
8# licensed hereunder.  You may use the software subject to the license
9# terms below provided that you ensure that this notice is replicated
10# unmodified and in its entirety in all distributions of the software,
11# modified or unmodified, in source code or in binary form.
12#
13# Redistribution and use in source and binary forms, with or without
14# modification, are permitted provided that the following conditions are
15# met: redistributions of source code must retain the above copyright
16# notice, this list of conditions and the following disclaimer;
17# redistributions in binary form must reproduce the above copyright
18# notice, this list of conditions and the following disclaimer in the
19# documentation and/or other materials provided with the distribution;
20# neither the name of the copyright holders nor the names of its
21# contributors may be used to endorse or promote products derived from
22# this software without specific prior written permission.
23#
24# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
27# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
28# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
29# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
30# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
31# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
32# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
33# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
34# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35#
36# Authors: Andrew Bardsley
37#
38
39"""The High-Performance In-order (HPI) CPU timing model is tuned to be
40representative of a modern in-order ARMv8-A implementation. The HPI
41core and its supporting simulation scripts, namely starter_se.py and
42starter_fs.py (under /configs/example/arm/) are part of the ARM
43Research Starter Kit on System Modeling. More information can be found
44at: http://www.arm.com/ResearchEnablement/SystemModeling
45
46"""
47
48from m5.objects import *
49
50# Simple function to allow a string of [01x_] to be converted into a
51# mask and value for use with MinorFUTiming
52def make_implicant(implicant_string):
53    ret_mask = 0
54    ret_match = 0
55
56    shift = False
57    for char in implicant_string:
58        char = char.lower()
59        if shift:
60            ret_mask <<= 1
61            ret_match <<= 1
62
63        shift = True
64        if char == '_':
65            shift = False
66        elif char == '0':
67            ret_mask |= 1
68        elif char == '1':
69            ret_mask |= 1
70            ret_match |= 1
71        elif char == 'x':
72            pass
73        else:
74            print "Can't parse implicant character", char
75
76    return (ret_mask, ret_match)
77
78#                          ,----- 36 thumb
79#                          | ,--- 35 bigThumb
80#                          | |,-- 34 aarch64
81a64_inst = make_implicant('0_01xx__xxxx_xxxx_xxxx_xxxx__xxxx_xxxx_xxxx_xxxx')
82a32_inst = make_implicant('0_00xx__xxxx_xxxx_xxxx_xxxx__xxxx_xxxx_xxxx_xxxx')
83t32_inst = make_implicant('1_10xx__xxxx_xxxx_xxxx_xxxx__xxxx_xxxx_xxxx_xxxx')
84t16_inst = make_implicant('1_00xx__xxxx_xxxx_xxxx_xxxx__xxxx_xxxx_xxxx_xxxx')
85any_inst = make_implicant('x_xxxx__xxxx_xxxx_xxxx_xxxx__xxxx_xxxx_xxxx_xxxx')
86#                          | ||
87any_a64_inst = \
88           make_implicant('x_x1xx__xxxx_xxxx_xxxx_xxxx__xxxx_xxxx_xxxx_xxxx')
89any_non_a64_inst = \
90           make_implicant('x_x0xx__xxxx_xxxx_xxxx_xxxx__xxxx_xxxx_xxxx_xxxx')
91
92def encode_opcode(pattern):
93    def encode(opcode_string):
94        a64_mask, a64_match = pattern
95        mask, match = make_implicant(opcode_string)
96        return (a64_mask | mask), (a64_match | match)
97    return encode
98
99a64_opcode = encode_opcode(a64_inst)
100a32_opcode = encode_opcode(a32_inst)
101t32_opcode = encode_opcode(t32_inst)
102t16_opcode = encode_opcode(t16_inst)
103
104# These definitions (in some form) should probably be part of TimingExpr
105
106def literal(value):
107    def body(env):
108        ret = TimingExprLiteral()
109        ret.value = value
110        return ret
111    return body
112
113def bin(op, left, right):
114    def body(env):
115        ret = TimingExprBin()
116        ret.op = 'timingExpr' + op
117        ret.left = left(env)
118        ret.right = right(env)
119        return ret
120    return body
121
122def un(op, arg):
123    def body(env):
124        ret = TimingExprUn()
125        ret.op = 'timingExpr' + op
126        ret.arg = arg(env)
127        return ret
128    return body
129
130def ref(name):
131    def body(env):
132        if name in env:
133            ret = TimingExprRef()
134            ret.index = env[name]
135        else:
136            print "Invalid expression name", name
137            ret = TimingExprNull()
138        return ret
139    return body
140
141def if_expr(cond, true_expr, false_expr):
142    def body(env):
143        ret = TimingExprIf()
144        ret.cond = cond(env)
145        ret.trueExpr = true_expr(env)
146        ret.falseExpr = false_expr(env)
147        return ret
148    return body
149
150def src(index):
151    def body(env):
152        ret = TimingExprSrcReg()
153        ret.index = index
154        return ret
155    return body
156
157def int_reg(reg):
158    def body(env):
159        ret = TimingExprReadIntReg()
160        ret.reg = reg(env)
161        return ret
162    return body
163
164def let(bindings, expr):
165    def body(env):
166        ret = TimingExprLet()
167        let_bindings = []
168        new_env = {}
169        i = 0
170
171        # Make the sub-expression as null to start with
172        for name, binding in bindings:
173            new_env[name] = i
174            i += 1
175
176        defns = []
177        # Then apply them to the produced new env
178        for i in xrange(0, len(bindings)):
179            name, binding_expr = bindings[i]
180            defns.append(binding_expr(new_env))
181
182        ret.defns = defns
183        ret.expr = expr(new_env)
184
185        return ret
186    return body
187
188def expr_top(expr):
189    return expr([])
190
191class HPI_DefaultInt(MinorFUTiming):
192    description = 'HPI_DefaultInt'
193    mask, match = any_non_a64_inst
194    srcRegsRelativeLats = [3, 3, 2, 2, 2, 1, 0]
195
196class HPI_DefaultA64Int(MinorFUTiming):
197    description = 'HPI_DefaultA64Int'
198    mask, match = any_a64_inst
199    # r, l, (c)
200    srcRegsRelativeLats = [2, 2, 2, 0]
201
202class HPI_DefaultMul(MinorFUTiming):
203    description = 'HPI_DefaultMul'
204    mask, match = any_non_a64_inst
205    # f, f, f, r, l, a?
206    srcRegsRelativeLats = [0, 0, 0, 0, 0, 0, 0]
207
208class HPI_DefaultA64Mul(MinorFUTiming):
209    description = 'HPI_DefaultA64Mul'
210    mask, match = any_a64_inst
211    # a (zr for mul), l, r
212    srcRegsRelativeLats = [0, 0, 0, 0]
213    # extraCommitLat = 1
214
215class HPI_DefaultVfp(MinorFUTiming):
216    description = 'HPI_DefaultVfp'
217    mask, match = any_non_a64_inst
218    # cpsr, z, z, z, cpacr, fpexc, l_lo, r_lo, l_hi, r_hi (from vadd2h)
219    srcRegsRelativeLats = [5, 5, 5, 5, 5, 5,  2, 2, 2, 2, 2, 2, 2, 2, 0]
220
221class HPI_DefaultA64Vfp(MinorFUTiming):
222    description = 'HPI_DefaultA64Vfp'
223    mask, match = any_a64_inst
224    # cpsr, cpacr_el1, fpscr_exc, ...
225    srcRegsRelativeLats = [5, 5, 5, 2]
226
227class HPI_FMADD_A64(MinorFUTiming):
228    description = 'HPI_FMADD_A64'
229    mask, match = a64_opcode('0001_1111_0x0x_xxxx__0xxx_xxxx_xxxx_xxxx')
230    #                                    t
231    # cpsr, cpacr_el1, fpscr_exc, 1, 1, 2, 2, 3, 3, fpscr_exc, d, d, d, d
232    srcRegsRelativeLats = [5, 5, 5,  0, 0,  0, 0,  1, 1,  0,  0, 0, 0, 0]
233
234class HPI_FMSUB_D_A64(MinorFUTiming):
235    description = 'HPI_FMSUB_D_A64'
236    mask, match = a64_opcode('0001_1111_0x0x_xxxx__1xxx_xxxx_xxxx_xxxx')
237    #                                    t
238    # cpsr, cpacr_el1, fpscr_exc, 1, 1, 2, 2, 3, 3, fpscr_exc, d, d, d, d
239    srcRegsRelativeLats = [5, 5, 5,  0, 0,  0, 0,  1, 1,  0,  0, 0, 0, 0]
240
241class HPI_FMOV_A64(MinorFUTiming):
242    description = 'HPI_FMOV_A64'
243    mask, match = a64_opcode('0001_1110_0x10_0000__0100_00xx_xxxx_xxxx')
244    # cpsr, cpacr_el1, fpscr_exc, 1, 1, 2, 2, 3, 3, fpscr_exc, d, d, d, d
245    srcRegsRelativeLats = [5, 5, 5, 0]
246
247class HPI_ADD_SUB_vector_scalar_A64(MinorFUTiming):
248    description = 'HPI_ADD_SUB_vector_scalar_A64'
249    mask, match = a64_opcode('01x1_1110_xx1x_xxxx__1000_01xx_xxxx_xxxx')
250    # cpsr, z, z, z, cpacr, fpexc, l0, r0, l1, r1, l2, r2, l3, r3 (for vadd2h)
251    srcRegsRelativeLats = [5, 5, 5, 4]
252
253
254class HPI_ADD_SUB_vector_vector_A64(MinorFUTiming):
255    description = 'HPI_ADD_SUB_vector_vector_A64'
256    mask, match = a64_opcode('0xx0_1110_xx1x_xxxx__1000_01xx_xxxx_xxxx')
257    # cpsr, z, z, z, cpacr, fpexc, l0, r0, l1, r1, l2, r2, l3, r3 (for vadd2h)
258    srcRegsRelativeLats = [5, 5, 5, 4]
259
260class HPI_FDIV_scalar_32_A64(MinorFUTiming):
261    description = 'HPI_FDIV_scalar_32_A64'
262    mask, match = a64_opcode('0001_1110_001x_xxxx__0001_10xx_xxxx_xxxx')
263    extraCommitLat = 6
264    srcRegsRelativeLats = [0, 0, 0, 20,  4]
265
266class HPI_FDIV_scalar_64_A64(MinorFUTiming):
267    description = 'HPI_FDIV_scalar_64_A64'
268    mask, match = a64_opcode('0001_1110_011x_xxxx__0001_10xx_xxxx_xxxx')
269    extraCommitLat = 15
270    srcRegsRelativeLats = [0, 0, 0, 20,  4]
271
272# CINC CINV CSEL CSET CSETM CSINC CSINC CSINV CSINV CSNEG
273class HPI_Cxxx_A64(MinorFUTiming):
274    description = 'HPI_Cxxx_A64'
275    mask, match = a64_opcode('xx01_1010_100x_xxxx_xxxx__0xxx_xxxx_xxxx')
276    srcRegsRelativeLats = [3, 3, 3, 2, 2]
277
278class HPI_DefaultMem(MinorFUTiming):
279    description = 'HPI_DefaultMem'
280    mask, match = any_non_a64_inst
281    srcRegsRelativeLats = [1, 1, 1, 1, 1, 2]
282    # Assume that LDR/STR take 2 cycles for resolving dependencies
283    # (1 + 1 of the FU)
284    extraAssumedLat = 2
285
286class HPI_DefaultMem64(MinorFUTiming):
287    description = 'HPI_DefaultMem64'
288    mask, match = any_a64_inst
289    srcRegsRelativeLats = [2]
290    # Assume that LDR/STR take 2 cycles for resolving dependencies
291    # (1 + 1 of the FU)
292    extraAssumedLat = 3
293
294class HPI_DataProcessingMovShiftr(MinorFUTiming):
295    description = 'HPI_DataProcessingMovShiftr'
296    mask, match = a32_opcode('xxxx_0001_101x_xxxx__xxxx_xxxx_xxx1_xxxx')
297    srcRegsRelativeLats = [3, 3, 2, 2, 2, 1, 0]
298
299class HPI_DataProcessingMayShift(MinorFUTiming):
300    description = 'HPI_DataProcessingMayShift'
301    mask, match = a32_opcode('xxxx_000x_xxxx_xxxx__xxxx_xxxx_xxxx_xxxx')
302    srcRegsRelativeLats = [3, 3, 2, 2, 1, 1, 0]
303
304class HPI_DataProcessingNoShift(MinorFUTiming):
305    description = 'HPI_DataProcessingNoShift'
306    mask, match = a32_opcode('xxxx_000x_xxxx_xxxx__xxxx_0000_0xx0_xxxx')
307    srcRegsRelativeLats = [3, 3, 2, 2, 2, 1, 0]
308
309class HPI_DataProcessingAllowShifti(MinorFUTiming):
310    description = 'HPI_DataProcessingAllowShifti'
311    mask, match = a32_opcode('xxxx_000x_xxxx_xxxx__xxxx_xxxx_xxx0_xxxx')
312    srcRegsRelativeLats = [3, 3, 2, 2, 1, 1, 0]
313
314class HPI_DataProcessingSuppressShift(MinorFUTiming):
315    description = 'HPI_DataProcessingSuppressShift'
316    mask, match = a32_opcode('xxxx_000x_xxxx_xxxx__xxxx_xxxx_xxxx_xxxx')
317    srcRegsRelativeLats = []
318    suppress = True
319
320class HPI_DataProcessingSuppressBranch(MinorFUTiming):
321    description = 'HPI_DataProcessingSuppressBranch'
322    mask, match = a32_opcode('xxxx_1010_xxxx_xxxx__xxxx_xxxx_xxxx_xxxx')
323    srcRegsRelativeLats = []
324    suppress = True
325
326class HPI_BFI_T1(MinorFUTiming):
327    description = 'HPI_BFI_T1'
328    mask, match = t32_opcode('1111_0x11_0110_xxxx__0xxx_xxxx_xxxx_xxxx')
329    srcRegsRelativeLats = [0, 0, 0, 1, 1, 0]
330
331class HPI_BFI_A1(MinorFUTiming):
332    description = 'HPI_BFI_A1'
333    mask, match = a32_opcode('xxxx_0111_110x_xxxx__xxxx_xxxx_x001_xxxx')
334    # f, f, f, dest, src
335    srcRegsRelativeLats = [0, 0, 0, 1, 1, 0]
336
337class HPI_CLZ_T1(MinorFUTiming):
338    description = 'HPI_CLZ_T1'
339    mask, match = t32_opcode('1111_1010_1011_xxxx__1111_xxxx_1000_xxxx')
340    srcRegsRelativeLats = [3, 3, 2, 2, 2, 1, 0]
341
342class HPI_CLZ_A1(MinorFUTiming):
343    description = 'HPI_CLZ_A1'
344    mask, match = a32_opcode('xxxx_0001_0110_xxxx__xxxx_xxxx_0001_xxxx')
345    srcRegsRelativeLats = [3, 3, 2, 2, 2, 1, 0]
346
347class HPI_CMN_immediate_A1(MinorFUTiming):
348    description = 'HPI_CMN_immediate_A1'
349    mask, match = a32_opcode('xxxx_0011_0111_xxxx__xxxx_xxxx_xxxx_xxxx')
350    srcRegsRelativeLats = [3, 3, 3, 2, 2, 3, 3, 3, 0]
351
352class HPI_CMN_register_A1(MinorFUTiming):
353    description = 'HPI_CMN_register_A1'
354    mask, match = a32_opcode('xxxx_0001_0111_xxxx__xxxx_xxxx_xxx0_xxxx')
355    srcRegsRelativeLats = [3, 3, 3, 2, 2, 3, 3, 3, 0]
356
357class HPI_CMP_immediate_A1(MinorFUTiming):
358    description = 'HPI_CMP_immediate_A1'
359    mask, match = a32_opcode('xxxx_0011_0101_xxxx__xxxx_xxxx_xxxx_xxxx')
360    srcRegsRelativeLats = [3, 3, 3, 2, 2, 3, 3, 3, 0]
361
362class HPI_CMP_register_A1(MinorFUTiming):
363    description = 'HPI_CMP_register_A1'
364    mask, match = a32_opcode('xxxx_0001_0101_xxxx__xxxx_xxxx_xxx0_xxxx')
365    srcRegsRelativeLats = [3, 3, 3, 2, 2, 3, 3, 3, 0]
366
367class HPI_MLA_T1(MinorFUTiming):
368    description = 'HPI_MLA_T1'
369    mask, match = t32_opcode('1111_1011_0000_xxxx__xxxx_xxxx_0000_xxxx')
370    # z, z, z, a, l?, r?
371    srcRegsRelativeLats = [0, 0, 0, 0, 0, 2, 0]
372
373class HPI_MLA_A1(MinorFUTiming):
374    description = 'HPI_MLA_A1'
375    mask, match = a32_opcode('xxxx_0000_001x_xxxx__xxxx_xxxx_1001_xxxx')
376    # z, z, z, a, l?, r?
377    srcRegsRelativeLats = [0, 0, 0, 0, 0, 2, 0]
378
379class HPI_MADD_A64(MinorFUTiming):
380    description = 'HPI_MADD_A64'
381    mask, match = a64_opcode('x001_1011_000x_xxxx__0xxx_xxxx_xxxx_xxxx')
382    # a, l?, r?
383    srcRegsRelativeLats = [1, 1, 1, 0]
384    extraCommitLat = 1
385
386class HPI_MLS_T1(MinorFUTiming):
387    description = 'HPI_MLS_T1'
388    mask, match = t32_opcode('1111_1011_0000_xxxx__xxxx_xxxx_0001_xxxx')
389    # z, z, z, l?, a, r?
390    srcRegsRelativeLats = [0, 0, 0, 2, 0, 0, 0]
391
392class HPI_MLS_A1(MinorFUTiming):
393    description = 'HPI_MLS_A1'
394    mask, match = a32_opcode('xxxx_0000_0110_xxxx__xxxx_xxxx_1001_xxxx')
395    # z, z, z, l?, a, r?
396    srcRegsRelativeLats = [0, 0, 0, 2, 0, 0, 0]
397
398class HPI_MOVT_A1(MinorFUTiming):
399    description = 'HPI_MOVT_A1'
400    mask, match = t32_opcode('xxxx_0010_0100_xxxx__xxxx_xxxx_xxxx_xxxx')
401
402class HPI_MUL_T1(MinorFUTiming):
403    description = 'HPI_MUL_T1'
404    mask, match = t16_opcode('0100_0011_01xx_xxxx')
405class HPI_MUL_T2(MinorFUTiming):
406    description = 'HPI_MUL_T2'
407    mask, match = t32_opcode('1111_1011_0000_xxxx_1111_xxxx_0000_xxxx')
408
409class HPI_PKH_T1(MinorFUTiming):
410    description = 'HPI_PKH_T1'
411    mask, match = t32_opcode('1110_1010_110x_xxxx__xxxx_xxxx_xxxx_xxxx')
412    srcRegsRelativeLats = [0, 0, 0, 2, 1, 0]
413
414class HPI_PKH_A1(MinorFUTiming):
415    description = 'HPI_PKH_A1'
416    mask, match = a32_opcode('xxxx_0110_1000_xxxx__xxxx_xxxx_xx01_xxxx')
417    srcRegsRelativeLats = [0, 0, 0, 2, 1, 0]
418
419class HPI_QADD_QSUB_T1(MinorFUTiming):
420    description = 'HPI_QADD_QSUB_T1'
421    mask, match = t32_opcode('1111_1010_1000_xxxx__1111_xxxx_10x0_xxxx')
422    srcRegsRelativeLats = [0, 0, 0, 1, 1, 0]
423
424class HPI_QADD_QSUB_A1(MinorFUTiming):
425    description = 'HPI_QADD_QSUB_A1'
426    mask, match = a32_opcode('xxxx_0001_00x0_xxxx__xxxx_xxxx_0101_xxxx')
427    srcRegsRelativeLats = [0, 0, 0, 1, 1, 0]
428
429# T1 QADD16 QADD8 QSUB16 QSUB8 UQADD16 UQADD8 UQSUB16 UQSUB8
430class HPI_QADD_ETC_T1(MinorFUTiming):
431    description = 'HPI_QADD_ETC_T1'
432    mask, match = t32_opcode('1111_1010_1x0x_xxxx__1111_xxxx_0x01_xxxx')
433    srcRegsRelativeLats = [0, 0, 0, 1, 1, 0]
434
435# A1 QADD16 QADD8 QSAX QSUB16 QSUB8 UQADD16 UQADD8 UQASX UQSAX UQSUB16 UQSUB8
436class HPI_QADD_ETC_A1(MinorFUTiming):
437    description = 'HPI_QADD_ETC_A1'
438    mask, match = a32_opcode('xxxx_0110_0x10_xxxx__xxxx_xxxx_xxx1_xxxx')
439    srcRegsRelativeLats = [0, 0, 0, 1, 1, 0]
440
441class HPI_QASX_QSAX_UQASX_UQSAX_T1(MinorFUTiming):
442    description = 'HPI_QASX_QSAX_UQASX_UQSAX_T1'
443    mask, match = t32_opcode('1111_1010_1x10_xxxx__1111_xxxx_0x01_xxxx')
444    srcRegsRelativeLats = [0, 0, 0, 1, 1, 0]
445
446class HPI_QDADD_QDSUB_T1(MinorFUTiming):
447    description = 'HPI_QDADD_QDSUB_T1'
448    mask, match = t32_opcode('1111_1010_1000_xxxx__1111_xxxx_10x1_xxxx')
449    srcRegsRelativeLats = [0, 0, 0, 0, 1, 0]
450
451class HPI_QDADD_QDSUB_A1(MinorFUTiming):
452    description = 'HPI_QDADD_QSUB_A1'
453    mask, match = a32_opcode('xxxx_0001_01x0_xxxx__xxxx_xxxx_0101_xxxx')
454    srcRegsRelativeLats = [0, 0, 0, 0, 1, 0]
455
456class HPI_RBIT_A1(MinorFUTiming):
457    description = 'HPI_RBIT_A1'
458    mask, match = a32_opcode('xxxx_0110_1111_xxxx__xxxx_xxxx_0011_xxxx')
459    srcRegsRelativeLats = [0, 0, 0, 1, 0]
460
461class HPI_REV_REV16_A1(MinorFUTiming):
462    description = 'HPI_REV_REV16_A1'
463    mask, match = a32_opcode('xxxx_0110_1011_xxxx__xxxx_xxxx_x011_xxxx')
464    srcRegsRelativeLats = [0, 0, 0, 1, 0]
465
466class HPI_REVSH_A1(MinorFUTiming):
467    description = 'HPI_REVSH_A1'
468    mask, match = a32_opcode('xxxx_0110_1111_xxxx__xxxx_xxxx_1011_xxxx')
469    srcRegsRelativeLats = [0, 0, 0, 1, 0]
470
471class HPI_ADD_ETC_A1(MinorFUTiming):
472    description = 'HPI_ADD_ETC_A1'
473    mask, match = a32_opcode('xxxx_0110_0xx1_xxxx__xxxx_xxxx_x001_xxxx')
474    srcRegsRelativeLats = [0, 0, 0, 2, 2, 0]
475
476class HPI_ADD_ETC_T1(MinorFUTiming):
477    description = 'HPI_ADD_ETC_A1'
478    mask, match = t32_opcode('1111_1010_100x_xxxx__1111_xxxx_0xx0_xxxx')
479    srcRegsRelativeLats = [0, 0, 0, 2, 2, 0]
480
481class HPI_SASX_SHASX_UASX_UHASX_A1(MinorFUTiming):
482    description = 'HPI_SASX_SHASX_UASX_UHASX_A1'
483    mask, match = a32_opcode('xxxx_0110_0xx1_xxxx__xxxx_xxxx_0011_xxxx')
484    srcRegsRelativeLats = [3, 3, 2, 2, 2, 1, 0]
485
486class HPI_SBFX_UBFX_A1(MinorFUTiming):
487    description = 'HPI_SBFX_UBFX_A1'
488    mask, match = a32_opcode('xxxx_0111_1x1x_xxxx__xxxx_xxxx_x101_xxxx')
489    srcRegsRelativeLats = [0, 0, 0, 1, 0]
490
491### SDIV
492
493sdiv_lat_expr = expr_top(let([
494    ('left', un('SignExtend32To64', int_reg(src(4)))),
495    ('right', un('SignExtend32To64', int_reg(src(3)))),
496    ('either_signed', bin('Or',
497        bin('SLessThan', ref('left'), literal(0)),
498        bin('SLessThan', ref('right'), literal(0)))),
499    ('left_size', un('SizeInBits', un('Abs', ref('left')))),
500    ('signed_adjust', if_expr(ref('either_signed'), literal(1), literal(0))),
501    ('right_size', un('SizeInBits',
502        bin('UDiv', un('Abs', ref('right')),
503            if_expr(ref('either_signed'), literal(4), literal(2))))),
504    ('left_minus_right', if_expr(
505        bin('SLessThan', ref('left_size'), ref('right_size')),
506        literal(0),
507        bin('Sub', ref('left_size'), ref('right_size'))))
508    ],
509    bin('Add',
510        ref('signed_adjust'),
511        if_expr(bin('Equal', ref('right'), literal(0)),
512            literal(0),
513            bin('UDiv', ref('left_minus_right'), literal(4))))
514    ))
515
516sdiv_lat_expr64 = expr_top(let([
517    ('left', un('SignExtend32To64', int_reg(src(0)))),
518    ('right', un('SignExtend32To64', int_reg(src(1)))),
519    ('either_signed', bin('Or',
520        bin('SLessThan', ref('left'), literal(0)),
521        bin('SLessThan', ref('right'), literal(0)))),
522    ('left_size', un('SizeInBits', un('Abs', ref('left')))),
523    ('signed_adjust', if_expr(ref('either_signed'), literal(1), literal(0))),
524    ('right_size', un('SizeInBits',
525        bin('UDiv', un('Abs', ref('right')),
526            if_expr(ref('either_signed'), literal(4), literal(2))))),
527    ('left_minus_right', if_expr(
528        bin('SLessThan', ref('left_size'), ref('right_size')),
529        literal(0),
530        bin('Sub', ref('left_size'), ref('right_size'))))
531    ],
532    bin('Add',
533        ref('signed_adjust'),
534        if_expr(bin('Equal', ref('right'), literal(0)),
535            literal(0),
536            bin('UDiv', ref('left_minus_right'), literal(4))))
537    ))
538
539class HPI_SDIV_A1(MinorFUTiming):
540    description = 'HPI_SDIV_A1'
541    mask, match = a32_opcode('xxxx_0111_0001_xxxx__xxxx_xxxx_0001_xxxx')
542    extraCommitLat = 0
543    srcRegsRelativeLats = []
544    extraCommitLatExpr = sdiv_lat_expr
545
546class HPI_SDIV_A64(MinorFUTiming):
547    description = 'HPI_SDIV_A64'
548    mask, match = a64_opcode('x001_1010_110x_xxxx__0000_11xx_xxxx_xxxx')
549    extraCommitLat = 0
550    srcRegsRelativeLats = []
551    extraCommitLatExpr = sdiv_lat_expr64
552
553### SEL
554
555class HPI_SEL_A1(MinorFUTiming):
556    description = 'HPI_SEL_A1'
557    mask, match = a32_opcode('xxxx_0110_1000_xxxx__xxxx_xxxx_1011_xxxx')
558    srcRegsRelativeLats = [0, 0, 0, 0, 2, 2, 0]
559
560class HPI_SEL_A1_Suppress(MinorFUTiming):
561    description = 'HPI_SEL_A1_Suppress'
562    mask, match = a32_opcode('xxxx_0110_1000_xxxx__xxxx_xxxx_1011_xxxx')
563    srcRegsRelativeLats = []
564    suppress = True
565
566class HPI_SHSAX_SSAX_UHSAX_USAX_A1(MinorFUTiming):
567    description = 'HPI_SHSAX_SSAX_UHSAX_USAX_A1'
568    mask, match = a32_opcode('xxxx_0110_0xx1_xxxx__xxxx_xxxx_0101_xxxx')
569    # As Default
570    srcRegsRelativeLats = [3, 3, 2, 2, 2, 1, 0]
571
572class HPI_USUB_ETC_A1(MinorFUTiming):
573    description = 'HPI_USUB_ETC_A1'
574    mask, match = a32_opcode('xxxx_0110_0xx1_xxxx__xxxx_xxxx_x111_xxxx')
575    srcRegsRelativeLats = [0, 0, 0, 2, 2, 0]
576
577class HPI_SMLABB_T1(MinorFUTiming):
578    description = 'HPI_SMLABB_T1'
579    mask, match = t32_opcode('1111_1011_0001_xxxx__xxxx_xxxx_00xx_xxxx')
580    srcRegsRelativeLats = [0, 0, 0, 0, 0, 2, 0]
581
582class HPI_SMLABB_A1(MinorFUTiming):
583    description = 'HPI_SMLABB_A1'
584    mask, match = a32_opcode('xxxx_0001_0000_xxxx__xxxx_xxxx_1xx0_xxxx')
585    srcRegsRelativeLats = [0, 0, 0, 0, 0, 2, 0]
586
587class HPI_SMLAD_T1(MinorFUTiming):
588    description = 'HPI_SMLAD_T1'
589    mask, match = t32_opcode('1111_1011_0010_xxxx__xxxx_xxxx_000x_xxxx')
590    srcRegsRelativeLats = [0, 0, 0, 0, 0, 2, 0]
591
592class HPI_SMLAD_A1(MinorFUTiming):
593    description = 'HPI_SMLAD_A1'
594    mask, match = a32_opcode('xxxx_0111_0000_xxxx__xxxx_xxxx_00x1_xxxx')
595    # z, z, z, l, r, a
596    srcRegsRelativeLats = [0, 0, 0, 0, 0, 2, 0]
597
598class HPI_SMLAL_T1(MinorFUTiming):
599    description = 'HPI_SMLAL_T1'
600    mask, match = t32_opcode('1111_1011_1100_xxxx__xxxx_xxxx_0000_xxxx')
601class HPI_SMLAL_A1(MinorFUTiming):
602    description = 'HPI_SMLAL_A1'
603    mask, match = a32_opcode('xxxx_0000_111x_xxxx__xxxx_xxxx_1001_xxxx')
604
605class HPI_SMLALBB_T1(MinorFUTiming):
606    description = 'HPI_SMLALBB_T1'
607    mask, match = t32_opcode('1111_1011_1100_xxxx__xxxx_xxxx_10xx_xxxx')
608class HPI_SMLALBB_A1(MinorFUTiming):
609    description = 'HPI_SMLALBB_A1'
610    mask, match = a32_opcode('xxxx_0001_0100_xxxx__xxxx_xxxx_1xx0_xxxx')
611
612class HPI_SMLALD_T1(MinorFUTiming):
613    description = 'HPI_SMLALD_T1'
614    mask, match = t32_opcode('1111_1011_1100_xxxx__xxxx_xxxx_110x_xxxx')
615class HPI_SMLALD_A1(MinorFUTiming):
616    description = 'HPI_SMLALD_A1'
617    mask, match = a32_opcode('xxxx_0111_0100_xxxx__xxxx_xxxx_00x1_xxxx')
618
619class HPI_SMLAWB_T1(MinorFUTiming):
620    description = 'HPI_SMLAWB_T1'
621    mask, match = t32_opcode('1111_1011_0011_xxxx__xxxx_xxxx_000x_xxxx')
622    srcRegsRelativeLats = [0, 0, 0, 0, 0, 2, 0]
623
624class HPI_SMLAWB_A1(MinorFUTiming):
625    description = 'HPI_SMLAWB_A1'
626    mask, match = a32_opcode('xxxx_0001_0010_xxxx__xxxx_xxxx_1x00_xxxx')
627    srcRegsRelativeLats = [0, 0, 0, 0, 0, 2, 0]
628
629class HPI_SMLSD_A1(MinorFUTiming):
630    description = 'HPI_SMLSD_A1'
631    mask, match = a32_opcode('xxxx_0111_0000_xxxx__xxxx_xxxx_01x1_xxxx')
632
633class HPI_SMLSLD_T1(MinorFUTiming):
634    description = 'HPI_SMLSLD_T1'
635    mask, match = t32_opcode('1111_1011_1101_xxxx__xxxx_xxxx_110x_xxxx')
636class HPI_SMLSLD_A1(MinorFUTiming):
637    description = 'HPI_SMLSLD_A1'
638    mask, match = a32_opcode('xxxx_0111_0100_xxxx__xxxx_xxxx_01x1_xxxx')
639
640class HPI_SMMLA_T1(MinorFUTiming):
641    description = 'HPI_SMMLA_T1'
642    mask, match = t32_opcode('1111_1011_0101_xxxx__xxxx_xxxx_000x_xxxx')
643    #                                              ^^^^ != 1111
644    srcRegsRelativeLats = [0, 0, 0, 2, 0, 0, 0]
645
646class HPI_SMMLA_A1(MinorFUTiming):
647    description = 'HPI_SMMLA_A1'
648    # Note that this must be after the encoding for SMMUL
649    mask, match = a32_opcode('xxxx_0111_0101_xxxx__xxxx_xxxx_00x1_xxxx')
650    #                                              ^^^^ != 1111
651    srcRegsRelativeLats = [0, 0, 0, 2, 0, 0, 0]
652
653class HPI_SMMLS_T1(MinorFUTiming):
654    description = 'HPI_SMMLS_T1'
655    mask, match = t32_opcode('1111_1011_0110_xxxx__xxxx_xxxx_000x_xxxx')
656    srcRegsRelativeLats = [0, 0, 0, 2, 0, 0, 0]
657
658class HPI_SMMLS_A1(MinorFUTiming):
659    description = 'HPI_SMMLS_A1'
660    mask, match = a32_opcode('xxxx_0111_0101_xxxx__xxxx_xxxx_11x1_xxxx')
661    srcRegsRelativeLats = [0, 0, 0, 2, 0, 0, 0]
662
663class HPI_SMMUL_T1(MinorFUTiming):
664    description = 'HPI_SMMUL_T1'
665    mask, match = t32_opcode('1111_1011_0101_xxxx__1111_xxxx_000x_xxxx')
666    srcRegsRelativeLats = [0, 0, 0, 0, 0, 0]
667
668class HPI_SMMUL_A1(MinorFUTiming):
669    description = 'HPI_SMMUL_A1'
670    mask, match = a32_opcode('xxxx_0111_0101_xxxx__1111_xxxx_00x1_xxxx')
671    srcRegsRelativeLats = [0, 0, 0, 0, 0, 0]
672
673class HPI_SMUAD_T1(MinorFUTiming):
674    description = 'HPI_SMUAD_T1'
675    mask, match = t32_opcode('1111_1011_0010_xxxx__1111_xxxx_000x_xxxx')
676class HPI_SMUAD_A1(MinorFUTiming):
677    description = 'HPI_SMUAD_A1'
678    mask, match = a32_opcode('xxxx_0111_0000_xxxx__1111_xxxx_00x1_xxxx')
679
680class HPI_SMULBB_T1(MinorFUTiming):
681    description = 'HPI_SMULBB_T1'
682    mask, match = t32_opcode('1111_1011_0001_xxxx__1111_xxxx_00xx_xxxx')
683class HPI_SMULBB_A1(MinorFUTiming):
684    description = 'HPI_SMULBB_A1'
685    mask, match = a32_opcode('xxxx_0001_0110_xxxx__xxxx_xxxx_1xx0_xxxx')
686
687class HPI_SMULL_T1(MinorFUTiming):
688    description = 'HPI_SMULL_T1'
689    mask, match = t32_opcode('1111_1011_1000_xxxx__xxxx_xxxx_0000_xxxx')
690class HPI_SMULL_A1(MinorFUTiming):
691    description = 'HPI_SMULL_A1'
692    mask, match = a32_opcode('xxxx_0000_110x_xxxx__xxxx_xxxx_1001_xxxx')
693
694class HPI_SMULWB_T1(MinorFUTiming):
695    description = 'HPI_SMULWB_T1'
696    mask, match = t32_opcode('1111_1011_0011_xxxx__1111_xxxx_000x_xxxx')
697class HPI_SMULWB_A1(MinorFUTiming):
698    description = 'HPI_SMULWB_A1'
699    mask, match = a32_opcode('xxxx_0001_0010_xxxx__xxxx_xxxx_1x10_xxxx')
700
701class HPI_SMUSD_T1(MinorFUTiming):
702    description = 'HPI_SMUSD_T1'
703    mask, match = t32_opcode('1111_1011_0100_xxxx__1111_xxxx_000x_xxxx')
704class HPI_SMUSD_A1(MinorFUTiming):
705    description = 'HPI_SMUSD_A1'
706    mask, match = a32_opcode('xxxx_0111_0000_xxxx__1111_xxxx_01x1_xxxx')
707
708class HPI_SSAT_USAT_no_shift_A1(MinorFUTiming):
709    description = 'HPI_SSAT_USAT_no_shift_A1'
710    # Order *before* shift
711    mask, match = a32_opcode('xxxx_0110_1x1x_xxxx__xxxx_0000_0001_xxxx')
712    srcRegsRelativeLats = [0, 0, 0, 2, 0]
713
714class HPI_SSAT_USAT_shift_A1(MinorFUTiming):
715    description = 'HPI_SSAT_USAT_shift_A1'
716    # Order after shift
717    mask, match = a32_opcode('xxxx_0110_1x1x_xxxx__xxxx_xxxx_xx01_xxxx')
718    srcRegsRelativeLats = [0, 0, 0, 1, 0]
719
720class HPI_SSAT16_USAT16_A1(MinorFUTiming):
721    description = 'HPI_SSAT16_USAT16_A1'
722    mask, match = a32_opcode('xxxx_0110_1x10_xxxx__xxxx_xxxx_0011_xxxx')
723    srcRegsRelativeLats = [0, 0, 0, 2, 0]
724
725class HPI_SXTAB_T1(MinorFUTiming):
726    description = 'HPI_SXTAB_T1'
727    mask, match = t32_opcode('1111_1010_0100_xxxx__1111_xxxx_1xxx_xxxx')
728    srcRegsRelativeLats = [0, 0, 0, 1, 2, 0]
729
730class HPI_SXTAB_SXTAB16_SXTAH_UXTAB_UXTAB16_UXTAH_A1(MinorFUTiming):
731    description = 'HPI_SXTAB_SXTAB16_SXTAH_UXTAB_UXTAB16_UXTAH_A1'
732    # Place AFTER HPI_SXTB_SXTB16_SXTH_UXTB_UXTB16_UXTH_A1
733    # e6[9d][^f]0070 are undefined
734    mask, match = a32_opcode('xxxx_0110_1xxx_xxxx__xxxx_xxxx_0111_xxxx')
735    srcRegsRelativeLats = [0, 0, 0, 1, 2, 0]
736
737class HPI_SXTAB16_T1(MinorFUTiming):
738    description = 'HPI_SXTAB16_T1'
739    mask, match = t32_opcode('1111_1010_0010_xxxx__1111_xxxx_1xxx_xxxx')
740    srcRegsRelativeLats = [0, 0, 0, 1, 2, 0]
741
742class HPI_SXTAH_T1(MinorFUTiming):
743    description = 'HPI_SXTAH_T1'
744    mask, match = t32_opcode('1111_1010_0000_xxxx__1111_xxxx_1xxx_xxxx')
745    srcRegsRelativeLats = [0, 0, 0, 1, 2, 0]
746
747class HPI_SXTB_T1(MinorFUTiming):
748    description = 'HPI_SXTB_T1'
749    mask, match = t16_opcode('1011_0010_01xx_xxxx')
750class HPI_SXTB_T2(MinorFUTiming):
751    description = 'HPI_SXTB_T2'
752    mask, match = t32_opcode('1111_1010_0100_1111__1111_xxxx_1xxx_xxxx')
753    srcRegsRelativeLats = [0, 0, 0, 1, 2, 0]
754
755class HPI_SXTB_SXTB16_SXTH_UXTB_UXTB16_UXTH_A1(MinorFUTiming):
756    description = 'HPI_SXTB_SXTB16_SXTH_UXTB_UXTB16_UXTH_A1'
757    # e6[9d]f0070 are undefined
758    mask, match = a32_opcode('xxxx_0110_1xxx_1111__xxxx_xxxx_0111_xxxx')
759    srcRegsRelativeLats = [0, 0, 0, 2, 0]
760
761class HPI_SXTB16_T1(MinorFUTiming):
762    description = 'HPI_SXTB16_T1'
763    mask, match = t32_opcode('1111_1010_0010_1111__1111_xxxx_1xxx_xxxx')
764    srcRegsRelativeLats = [0, 0, 0, 1, 2, 0]
765
766class HPI_SXTH_T1(MinorFUTiming):
767    description = 'HPI_SXTH_T1'
768    mask, match = t16_opcode('1011_0010_00xx_xxxx')
769class HPI_SXTH_T2(MinorFUTiming):
770    description = 'HPI_SXTH_T2'
771    mask, match = t32_opcode('1111_1010_0000_1111__1111_xxxx_1xxx_xxxx')
772    srcRegsRelativeLats = [0, 0, 0, 1, 2, 0]
773
774class HPI_UDIV_T1(MinorFUTiming):
775    description = 'HPI_UDIV_T1'
776    mask, match = t32_opcode('1111_1011_1011_xxxx__xxxx_xxxx_1111_xxxx')
777
778udiv_lat_expr = expr_top(let([
779    ('left', int_reg(src(4))),
780    ('right', int_reg(src(3))),
781    ('left_size', un('SizeInBits', ref('left'))),
782    ('right_size', un('SizeInBits',
783        bin('UDiv', ref('right'), literal(2)))),
784    ('left_minus_right', if_expr(
785        bin('SLessThan', ref('left_size'), ref('right_size')),
786        literal(0),
787        bin('Sub', ref('left_size'), ref('right_size'))))
788    ],
789    if_expr(bin('Equal', ref('right'), literal(0)),
790        literal(0),
791        bin('UDiv', ref('left_minus_right'), literal(4)))
792    ))
793
794class HPI_UDIV_A1(MinorFUTiming):
795    description = 'HPI_UDIV_A1'
796    mask, match = a32_opcode('xxxx_0111_0011_xxxx__xxxx_xxxx_0001_xxxx')
797    extraCommitLat = 0
798    srcRegsRelativeLats = []
799    extraCommitLatExpr = udiv_lat_expr
800
801class HPI_UMAAL_T1(MinorFUTiming):
802    description = 'HPI_UMAAL_T1'
803    mask, match = t32_opcode('1111_1011_1110_xxxx__xxxx_xxxx_0110_xxxx')
804    # z, z, z, dlo, dhi, l, r
805    extraCommitLat = 1
806    srcRegsRelativeLats = [0, 0, 0, 0, 0, 0, 0, 0]
807
808class HPI_UMAAL_A1(MinorFUTiming):
809    description = 'HPI_UMAAL_A1'
810    mask, match = a32_opcode('xxxx_0000_0100_xxxx__xxxx_xxxx_1001_xxxx')
811    # z, z, z, dlo, dhi, l, r
812    extraCommitLat = 1
813    srcRegsRelativeLats = [0, 0, 0, 0, 0, 0, 0, 0]
814
815class HPI_UMLAL_T1(MinorFUTiming):
816    description = 'HPI_UMLAL_T1'
817    mask, match = t32_opcode('1111_1011_1110_xxxx__xxxx_xxxx_0000_xxxx')
818
819class HPI_UMLAL_A1(MinorFUTiming):
820    description = 'HPI_UMLAL_A1'
821    mask, match = t32_opcode('xxxx_0000_101x_xxxx__xxxx_xxxx_1001_xxxx')
822
823class HPI_UMULL_T1(MinorFUTiming):
824    description = 'HPI_UMULL_T1'
825    mask, match = t32_opcode('1111_1011_1010_xxxx__xxxx_xxxx_0000_xxxx')
826
827class HPI_UMULL_A1(MinorFUTiming):
828    description = 'HPI_UMULL_A1'
829    mask, match = a32_opcode('xxxx_0000_100x_xxxx__xxxx_xxxx_1001_xxxx')
830
831class HPI_USAD8_USADA8_A1(MinorFUTiming):
832    description = 'HPI_USAD8_USADA8_A1'
833    mask, match = a32_opcode('xxxx_0111_1000_xxxx__xxxx_xxxx_0001_xxxx')
834    srcRegsRelativeLats = [0, 0, 0, 0, 0, 2, 0]
835
836class HPI_USAD8_USADA8_A1_Suppress(MinorFUTiming):
837    description = 'HPI_USAD8_USADA8_A1_Suppress'
838    mask, match = a32_opcode('xxxx_0111_1000_xxxx__xxxx_xxxx_0001_xxxx')
839    srcRegsRelativeLats = []
840    suppress = True
841
842class HPI_VMOV_immediate_A1(MinorFUTiming):
843    description = 'HPI_VMOV_register_A1'
844    mask, match = a32_opcode('1111_0010_0x10_xxxx_xxxx_0001_xxx1_xxxx')
845    # cpsr, z, z, z, hcptr, nsacr, cpacr, fpexc, scr
846    srcRegsRelativeLats = [5, 5, 5, 5, 5, 5, 5, 5, 5, 0]
847
848class HPI_VMRS_A1(MinorFUTiming):
849    description = 'HPI_VMRS_A1'
850    mask, match = a32_opcode('xxxx_1110_1111_0001_xxxx_1010_xxx1_xxxx')
851    # cpsr,z,z,z,hcptr,nsacr,cpacr,scr,r42
852    srcRegsRelativeLats = [5, 5, 5, 5, 5, 5, 5, 5, 5, 0]
853
854class HPI_VMOV_register_A2(MinorFUTiming):
855    description = 'HPI_VMOV_register_A2'
856    mask, match = a32_opcode('xxxx_1110_1x11_0000_xxxx_101x_01x0_xxxx')
857    # cpsr, z, r39, z, hcptr, nsacr, cpacr, fpexc, scr, f4, f5, f0, f1
858    srcRegsRelativeLats = \
859        [5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 0]
860
861# VADD.I16 D/VADD.F32 D/VADD.I8 D/VADD.I32 D
862class HPI_VADD2H_A32(MinorFUTiming):
863    description = 'Vadd2hALU'
864    mask, match = a32_opcode('1111_0010_0xxx_xxxx__xxxx_1000_xxx0_xxxx')
865    # cpsr, z, z, z, cpacr, fpexc, l0, r0, l1, r1, l2, r2, l3, r3 (for vadd2h)
866    srcRegsRelativeLats = [0, 0, 0, 0, 0, 0,  4, 4, 4, 4, 4, 4, 4, 4, 0]
867
868# VAQQHN.I16 Q/VAQQHN.I32 Q/VAQQHN.I64 Q
869class HPI_VADDHN_A32(MinorFUTiming):
870    description = 'VaddhnALU'
871    mask, match = a32_opcode('1111_0010_1xxx_xxxx__xxxx_0100_x0x0_xxxx')
872    # cpsr, z, z, z, cpacr, fpexc, l0, l1, l2, l3, r0, r1, r2, r3
873    srcRegsRelativeLats = [0, 0, 0, 0, 0, 0,  3, 3, 3, 3, 3, 3, 3, 3, 0]
874
875class HPI_VADDL_A32(MinorFUTiming):
876    description = 'VaddlALU'
877    mask, match = a32_opcode('1111_001x_1xxx_xxxx__xxxx_0000_x0x0_xxxx')
878    srcRegsRelativeLats = [0, 0, 0, 0, 0, 0,  3, 3, 3, 3, 3, 3, 3, 3, 0]
879
880class HPI_VADDW_A32(MinorFUTiming):
881    description = 'HPI_VADDW_A32'
882    mask, match = a32_opcode('1111_001x_1xxx_xxxx__xxxx_0001_x0x0_xxxx')
883    # cpsr, z, z, z, cpacr, fpexc, l0, l1, l2, l3, r0, r1
884    srcRegsRelativeLats = [0, 0, 0, 0, 0, 0,  4, 4, 4, 4, 3, 3, 0]
885
886# VHADD/VHSUB S8,S16,S32,U8,U16,U32 Q and D
887class HPI_VHADD_A32(MinorFUTiming):
888    description = 'HPI_VHADD_A32'
889    mask, match = a32_opcode('1111_001x_0xxx_xxxx__xxxx_00x0_xxx0_xxxx')
890    srcRegsRelativeLats = [0, 0, 0, 0, 0, 0,  4, 4, 4, 4, 4, 4, 4, 4, 0]
891
892class HPI_VPADAL_A32(MinorFUTiming):
893    description = 'VpadalALU'
894    mask, match = a32_opcode('1111_0011_1x11_xx00__xxxx_0110_xxx0_xxxx')
895    srcRegsRelativeLats = [0, 0, 0, 0, 0, 0,  2, 2, 2, 2, 2, 2, 2, 2, 0]
896
897# VPADDH.I16
898class HPI_VPADDH_A32(MinorFUTiming):
899    description = 'VpaddhALU'
900    mask, match = a32_opcode('1111_0010_0xxx_xxxx__xxxx_1011_xxx1_xxxx')
901    srcRegsRelativeLats = [0, 0, 0, 0, 0, 0,  3, 3, 3, 3, 3, 3, 3, 3, 0]
902
903# VPADDH.F32
904class HPI_VPADDS_A32(MinorFUTiming):
905    description = 'VpaddsALU'
906    mask, match = a32_opcode('1111_0011_0x0x_xxxx__xxxx_1101_xxx0_xxxx')
907    srcRegsRelativeLats = [0, 0, 0, 0, 0, 0,  2, 2, 2, 2, 2, 2, 2, 2, 0]
908
909# VPADDL.S16
910class HPI_VPADDL_A32(MinorFUTiming):
911    description = 'VpaddlALU'
912    mask, match = a32_opcode('1111_0011_1x11_xx00__xxxx_0010_xxx0_xxxx')
913    srcRegsRelativeLats = [0, 0, 0, 0, 0, 0,  3, 3, 3, 3, 3, 3, 3, 3, 0]
914
915# VRADDHN.I16
916class HPI_VRADDHN_A32(MinorFUTiming):
917    description = 'HPI_VRADDHN_A32'
918    mask, match = a32_opcode('1111_0011_1xxx_xxxx__xxxx_0100_x0x0_xxxx')
919    # cpsr, z, z, z, cpacr, fpexc, l0, l1, l2, l3, r0, r1, r2, r3
920    srcRegsRelativeLats = [0, 0, 0, 0, 0, 0,  4, 4, 4, 4, 4, 4, 4, 4, 0]
921
922class HPI_VRHADD_A32(MinorFUTiming):
923    description = 'VrhaddALU'
924    mask, match = a32_opcode('1111_001x_0xxx_xxxx__xxxx_0001_xxx0_xxxx')
925    srcRegsRelativeLats = [0, 0, 0, 0, 0, 0,  4, 4, 4, 4, 4, 4, 4, 4, 0]
926
927class HPI_VQADD_A32(MinorFUTiming):
928    description = 'VqaddALU'
929    mask, match = a32_opcode('1111_001x_0xxx_xxxx__xxxx_0000_xxx1_xxxx')
930    srcRegsRelativeLats = [0, 0, 0, 0, 0, 0,  3, 3, 3, 3, 3, 3, 3, 3, 0]
931
932class HPI_VANDQ_A32(MinorFUTiming):
933    description = 'VandqALU'
934    mask, match = a32_opcode('1111_0010_0x00_xxxx__xxxx_0001_xxx1_xxxx')
935    srcRegsRelativeLats = [0, 0, 0, 0, 0, 0,  5, 5, 5, 5, 5, 5, 5, 5, 0]
936
937# VMUL (integer)
938class HPI_VMULI_A32(MinorFUTiming):
939    description = 'VmuliALU'
940    mask, match = a32_opcode('1111_001x_0xxx_xxxx__xxxx_1001_xxx1_xxxx')
941    srcRegsRelativeLats = [0, 0, 0, 0, 0, 0,  2, 2, 2, 2, 2, 2, 2, 2, 0]
942
943# VBIC (reg)
944class HPI_VBIC_A32(MinorFUTiming):
945    description = 'VbicALU'
946    mask, match = a32_opcode('1111_0010_0x01_xxxx__xxxx_0001_xxx1_xxxx')
947    srcRegsRelativeLats = [0, 0, 0, 0, 0, 0,  5, 5, 5, 5, 5, 5, 5, 5, 0]
948
949# VBIF VBIT VBSL
950class HPI_VBIF_ETC_A32(MinorFUTiming):
951    description = 'VbifALU'
952    mask, match = a32_opcode('1111_0011_0xxx_xxxx__xxxx_0001_xxx1_xxxx')
953    srcRegsRelativeLats = \
954        [0, 0, 0, 0, 0, 0,  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0]
955
956class HPI_VACGE_A32(MinorFUTiming):
957    description = 'VacgeALU'
958    mask, match = a32_opcode('1111_0011_0xxx_xxxx__xxxx_1110_xxx1_xxxx')
959    srcRegsRelativeLats = [0, 0, 0, 0, 0, 0,  4, 4, 4, 4, 4, 4, 4, 4, 4, 0]
960
961# VCEQ.F32
962class HPI_VCEQ_A32(MinorFUTiming):
963    description = 'VceqALU'
964    mask, match = a32_opcode('1111_0010_0x0x_xxxx__xxxx_1110_xxx0_xxxx')
965    srcRegsRelativeLats = [0, 0, 0, 0, 0, 0,  4, 4, 4, 4, 4, 4, 4, 4, 4, 0]
966
967# VCEQ.[IS]... register
968class HPI_VCEQI_A32(MinorFUTiming):
969    description = 'VceqiALU'
970    mask, match = a32_opcode('1111_0011_0xxx_xxxx__xxxx_1000_xxx1_xxxx')
971    srcRegsRelativeLats = [0, 0, 0, 0, 0, 0,  4, 4, 4, 4, 4, 4, 4, 4, 4, 0]
972
973# VCEQ.[IS]... immediate
974class HPI_VCEQII_A32(MinorFUTiming):
975    description = 'HPI_VCEQII_A32'
976    mask, match = a32_opcode('1111_0011_1x11_xx01__xxxx_0x01_0xx0_xxxx')
977    srcRegsRelativeLats = [0, 0, 0, 0, 0, 0,  4, 4, 4, 4, 4, 4, 4, 4, 4, 0]
978
979class HPI_VTST_A32(MinorFUTiming):
980    description = 'HPI_VTST_A32'
981    mask, match = a32_opcode('1111_0010_0xxx_xxxx__xxxx_1000_xxx1_xxxx')
982    srcRegsRelativeLats = [0, 0, 0, 0, 0, 0,  3, 3, 3, 3, 3, 3, 3, 3, 3, 0]
983
984class HPI_VCLZ_A32(MinorFUTiming):
985    description = 'HPI_VCLZ_A32'
986    mask, match = a32_opcode('1111_0011_1x11_xx00__xxxx_0100_1xx0_xxxx')
987    srcRegsRelativeLats = [0, 0, 0, 0, 0, 0,  4, 4, 4, 4, 4, 4, 4, 4, 4, 0]
988
989class HPI_VCNT_A32(MinorFUTiming):
990    description = 'HPI_VCNT_A32'
991    mask, match = a32_opcode('1111_0011_1x11_xx00__xxxx_0101_0xx0_xxxx')
992    srcRegsRelativeLats = [0, 0, 0, 0, 0, 0,  4, 4, 4, 4, 4, 4, 4, 4, 4, 0]
993
994class HPI_VEXT_A32(MinorFUTiming):
995    description = 'HPI_VCNT_A32'
996    mask, match = a32_opcode('1111_0010_1x11_xxxx__xxxx_xxxx_xxx0_xxxx')
997    srcRegsRelativeLats = [0, 0, 0, 0, 0, 0,  4, 4, 4, 4, 4, 4, 4, 4, 4, 0]
998
999# VMAX VMIN integer
1000class HPI_VMAXI_A32(MinorFUTiming):
1001    description = 'HPI_VMAXI_A32'
1002    mask, match = a32_opcode('1111_001x_0xxx_xxxx__xxxx_0110_xxxx_xxxx')
1003    srcRegsRelativeLats = [0, 0, 0, 0, 0, 0,  4, 4, 4, 4, 4, 4, 4, 4, 4, 0]
1004
1005# VMAX VMIN float
1006class HPI_VMAXS_A32(MinorFUTiming):
1007    description = 'HPI_VMAXS_A32'
1008    mask, match = a32_opcode('1111_0010_0xxx_xxxx__xxxx_1111_xxx0_xxxx')
1009    srcRegsRelativeLats = [0, 0, 0, 0, 0, 0,  2, 2, 2, 2, 2, 2, 2, 2, 2, 0]
1010
1011# VNEG integer
1012class HPI_VNEGI_A32(MinorFUTiming):
1013    description = 'HPI_VNEGI_A32'
1014    mask, match = a32_opcode('1111_0011_1x11_xx01__xxxx_0x11_1xx0_xxxx')
1015    srcRegsRelativeLats = [0, 0, 0, 0, 0, 0,  4, 4, 4, 4, 4, 4, 4, 4, 4, 0]
1016
1017# VNEG float
1018class HPI_VNEGF_A32(MinorFUTiming):
1019    description = 'HPI_VNEGF_A32'
1020    mask, match = a32_opcode('xxxx_1110_1x11_0001__xxxx_101x_01x0_xxxx')
1021    srcRegsRelativeLats = [0, 0, 0, 0, 0, 0,  2, 2, 2, 2, 2, 2, 2, 2, 2, 0]
1022
1023# VREV16 VREV32 VREV64
1024class HPI_VREVN_A32(MinorFUTiming):
1025    description = 'HPI_VREVN_A32'
1026    mask, match = a32_opcode('1111_0011_1x11_xx00__xxxx_000x_xxx0_xxxx')
1027    srcRegsRelativeLats = [0, 0, 0, 0, 0, 0,  4, 4, 4, 4, 4, 4, 4, 4, 4, 0]
1028
1029class HPI_VQNEG_A32(MinorFUTiming):
1030    description = 'HPI_VQNEG_A32'
1031    mask, match = a32_opcode('1111_0011_1x11_xx00__xxxx_0111_1xx0_xxxx')
1032    srcRegsRelativeLats = [0, 0, 0, 0, 0, 0,  3, 3, 3, 3, 3, 3, 3, 3, 3, 0]
1033
1034class HPI_VSWP_A32(MinorFUTiming):
1035    description = 'HPI_VSWP_A32'
1036    mask, match = a32_opcode('1111_0011_1x11_xx10__xxxx_0000_0xx0_xxxx')
1037    srcRegsRelativeLats = [0, 0, 0, 0, 0, 0,  4, 4, 4, 4, 4, 4, 4, 4, 0]
1038
1039class HPI_VTRN_A32(MinorFUTiming):
1040    description = 'HPI_VTRN_A32'
1041    mask, match = a32_opcode('1111_0011_1x11_xx10__xxxx_0000_1xx0_xxxx')
1042    # cpsr, z, z, z, cpact, fpexc, o0, d0, o1, d1, o2, d2, o3, d3
1043    srcRegsRelativeLats = [0, 0, 0, 0, 0, 0,  2, 2, 2, 2, 2, 2, 2, 2, 0]
1044
1045# VQMOVN VQMOVUN
1046class HPI_VQMOVN_A32(MinorFUTiming):
1047    description = 'HPI_VQMOVN_A32'
1048    mask, match = a32_opcode('1111_0011_1x11_xx10__xxxx_0010_xxx0_xxxx')
1049    # cpsr, z, z, z, cpact, fpexc, o[0], o[1], o[2], o[3], fpscr
1050    srcRegsRelativeLats = [0, 0, 0, 0, 0, 0,  2, 2, 2, 2,  2, 0]
1051
1052# VUZP double word
1053class HPI_VUZP_A32(MinorFUTiming):
1054    description = 'HPI_VUZP_A32'
1055    mask, match = a32_opcode('1111_0011_1x11_xx10__xxxx_0001_00x0_xxxx')
1056    srcRegsRelativeLats = [0, 0, 0, 0, 0, 0,  3, 3, 3, 3, 3, 3, 3, 3, 0]
1057
1058# VDIV.F32
1059class HPI_VDIV32_A32(MinorFUTiming):
1060    description = 'HPI_VDIV32_A32'
1061    mask, match = a32_opcode('xxxx_1110_1x00_xxxx__xxxx_1010_x0x0_xxxx')
1062    # cpsr, z, z, z, cpact, fpexc, fpscr_exc, l, r
1063    extraCommitLat = 9
1064    srcRegsRelativeLats = [0, 0, 0, 0, 0, 0, 20,  4, 4, 0]
1065
1066# VDIV.F64
1067class HPI_VDIV64_A32(MinorFUTiming):
1068    description = 'HPI_VDIV64_A32'
1069    mask, match = a32_opcode('xxxx_1110_1x00_xxxx__xxxx_1011_x0x0_xxxx')
1070    # cpsr, z, z, z, cpact, fpexc, fpscr_exc, l, r
1071    extraCommitLat = 18
1072    srcRegsRelativeLats = [0, 0, 0, 0, 0, 0, 20,  4, 4, 0]
1073
1074class HPI_VZIP_A32(MinorFUTiming):
1075    description = 'HPI_VZIP_A32'
1076    mask, match = a32_opcode('1111_0011_1x11_xx10__xxxx_0001_1xx0_xxxx')
1077    srcRegsRelativeLats = [0, 0, 0, 0, 0, 0,  4, 4, 4, 4, 4, 4, 4, 4, 0]
1078
1079# VPMAX integer
1080class HPI_VPMAX_A32(MinorFUTiming):
1081    description = 'HPI_VPMAX_A32'
1082    mask, match = a32_opcode('1111_001x_0xxx_xxxx__xxxx_1010_xxxx_xxxx')
1083    # cpsr, z, z, z, cpact, fpexc, l0, r0, l1, r1, fpscr
1084    srcRegsRelativeLats = [0, 0, 0, 0, 0, 0,  4, 4, 4, 4,  4, 0]
1085
1086# VPMAX float
1087class HPI_VPMAXF_A32(MinorFUTiming):
1088    description = 'HPI_VPMAXF_A32'
1089    mask, match = a32_opcode('1111_0011_0xxx_xxxx__xxxx_1111_xxx0_xxxx')
1090    srcRegsRelativeLats = [0, 0, 0, 0, 0, 0,  2, 2, 2, 2, 0]
1091
1092class HPI_VMOVN_A32(MinorFUTiming):
1093    description = 'HPI_VMOVN_A32'
1094    mask, match = a32_opcode('1111_0011_1x11_xx10__xxxx_0010_00x0_xxxx')
1095    srcRegsRelativeLats = [0, 0, 0, 0, 0, 0,  4, 4, 4, 4, 0]
1096
1097class HPI_VMOVL_A32(MinorFUTiming):
1098    description = 'HPI_VMOVL_A32'
1099    mask, match = a32_opcode('1111_001x_1xxx_x000__xxxx_1010_00x1_xxxx')
1100    srcRegsRelativeLats = [0, 0, 0, 0, 0, 0,  4, 4, 4, 4, 0]
1101
1102# VSQRT.F64
1103class HPI_VSQRT64_A32(MinorFUTiming):
1104    description = 'HPI_VSQRT64_A32'
1105    mask, match = a32_opcode('xxxx_1110_1x11_0001__xxxx_1011_11x0_xxxx')
1106    extraCommitLat = 18
1107    srcRegsRelativeLats = []
1108
1109# VSQRT.F32
1110class HPI_VSQRT32_A32(MinorFUTiming):
1111    description = 'HPI_VSQRT32_A32'
1112    mask, match = a32_opcode('xxxx_1110_1x11_0001__xxxx_1010_11x0_xxxx')
1113    extraCommitLat = 9
1114    srcRegsRelativeLats = []
1115
1116class HPI_FloatSimdFU(MinorFU):
1117    opClasses = minorMakeOpClassSet([
1118        'FloatAdd', 'FloatCmp', 'FloatCvt', 'FloatMult', 'FloatDiv',
1119        'FloatSqrt', 'FloatMisc', 'FloatMultAcc',
1120        'SimdAdd', 'SimdAddAcc', 'SimdAlu', 'SimdCmp', 'SimdCvt',
1121        'SimdMisc', 'SimdMult', 'SimdMultAcc', 'SimdShift', 'SimdShiftAcc',
1122        'SimdSqrt', 'SimdFloatAdd', 'SimdFloatAlu', 'SimdFloatCmp',
1123        'SimdFloatCvt', 'SimdFloatDiv', 'SimdFloatMisc', 'SimdFloatMult',
1124        'SimdFloatMultAcc', 'SimdFloatSqrt'])
1125
1126    timings = [
1127        # VUZP and VZIP must be before VADDW/L
1128        HPI_VUZP_A32(), HPI_VZIP_A32(),
1129        HPI_VADD2H_A32(), HPI_VADDHN_A32(),
1130        HPI_VADDL_A32(), HPI_VADDW_A32(),
1131        HPI_VHADD_A32(), HPI_VPADAL_A32(),
1132        HPI_VPADDH_A32(), HPI_VPADDS_A32(),
1133        HPI_VPADDL_A32(), HPI_VRADDHN_A32(),
1134        HPI_VRHADD_A32(), HPI_VQADD_A32(),
1135        HPI_VANDQ_A32(), HPI_VBIC_A32(),
1136        HPI_VBIF_ETC_A32(), HPI_VACGE_A32(),
1137        HPI_VCEQ_A32(), HPI_VCEQI_A32(),
1138        HPI_VCEQII_A32(), HPI_VTST_A32(),
1139        HPI_VCLZ_A32(), HPI_VCNT_A32(),
1140        HPI_VEXT_A32(), HPI_VMAXI_A32(),
1141        HPI_VMAXS_A32(), HPI_VNEGI_A32(),
1142        HPI_VNEGF_A32(), HPI_VREVN_A32(),
1143        HPI_VQNEG_A32(), HPI_VSWP_A32(),
1144        HPI_VTRN_A32(), HPI_VPMAX_A32(),
1145        HPI_VPMAXF_A32(), HPI_VMOVN_A32(),
1146        HPI_VMRS_A1(),
1147        HPI_VMOV_immediate_A1(),
1148        HPI_VMOV_register_A2(),
1149        HPI_VQMOVN_A32(), HPI_VMOVL_A32(),
1150        HPI_VDIV32_A32(), HPI_VDIV64_A32(),
1151        HPI_VSQRT32_A32(), HPI_VSQRT64_A32(),
1152        HPI_VMULI_A32(),
1153        # Add before here
1154        HPI_FMADD_A64(),
1155        HPI_FMSUB_D_A64(),
1156        HPI_FMOV_A64(),
1157        HPI_ADD_SUB_vector_scalar_A64(),
1158        HPI_ADD_SUB_vector_vector_A64(),
1159        HPI_FDIV_scalar_32_A64(), HPI_FDIV_scalar_64_A64(),
1160        HPI_DefaultA64Vfp(),
1161        HPI_DefaultVfp()]
1162
1163    opLat = 6
1164
1165class HPI_IntFU(MinorFU):
1166    opClasses = minorMakeOpClassSet(['IntAlu'])
1167    # IMPORTANT! Keep the order below, add new entries *at the head*
1168    timings = [
1169        HPI_SSAT_USAT_no_shift_A1(),
1170        HPI_SSAT_USAT_shift_A1(),
1171        HPI_SSAT16_USAT16_A1(),
1172        HPI_QADD_QSUB_A1(),
1173        HPI_QADD_QSUB_T1(),
1174        HPI_QADD_ETC_A1(),
1175        HPI_QASX_QSAX_UQASX_UQSAX_T1(),
1176        HPI_QADD_ETC_T1(),
1177        HPI_USUB_ETC_A1(),
1178        HPI_ADD_ETC_A1(),
1179        HPI_ADD_ETC_T1(),
1180        HPI_QDADD_QDSUB_A1(),
1181        HPI_QDADD_QDSUB_T1(),
1182        HPI_SASX_SHASX_UASX_UHASX_A1(),
1183        HPI_SHSAX_SSAX_UHSAX_USAX_A1(),
1184        HPI_SXTB_SXTB16_SXTH_UXTB_UXTB16_UXTH_A1(),
1185
1186        # Must be after HPI_SXTB_SXTB16_SXTH_UXTB_UXTB16_UXTH_A1
1187        HPI_SXTAB_SXTAB16_SXTAH_UXTAB_UXTAB16_UXTAH_A1(),
1188
1189        HPI_SXTAB_T1(),
1190        HPI_SXTAB16_T1(),
1191        HPI_SXTAH_T1(),
1192        HPI_SXTB_T2(),
1193        HPI_SXTB16_T1(),
1194        HPI_SXTH_T2(),
1195
1196        HPI_PKH_A1(),
1197        HPI_PKH_T1(),
1198        HPI_SBFX_UBFX_A1(),
1199        HPI_SEL_A1(),
1200        HPI_RBIT_A1(),
1201        HPI_REV_REV16_A1(),
1202        HPI_REVSH_A1(),
1203        HPI_USAD8_USADA8_A1(),
1204        HPI_BFI_A1(),
1205        HPI_BFI_T1(),
1206
1207        HPI_CMN_register_A1(),
1208        HPI_CMN_immediate_A1(),
1209        HPI_CMP_register_A1(),
1210        HPI_CMP_immediate_A1(),
1211
1212        HPI_DataProcessingNoShift(),
1213        HPI_DataProcessingMovShiftr(),
1214        HPI_DataProcessingMayShift(),
1215
1216        HPI_Cxxx_A64(),
1217
1218        HPI_DefaultA64Int(),
1219        HPI_DefaultInt()]
1220    opLat = 3
1221
1222class HPI_Int2FU(MinorFU):
1223    opClasses = minorMakeOpClassSet(['IntAlu'])
1224    # IMPORTANT! Keep the order below, add new entries *at the head*
1225    timings = [
1226        HPI_SSAT_USAT_no_shift_A1(),
1227        HPI_SSAT_USAT_shift_A1(),
1228        HPI_SSAT16_USAT16_A1(),
1229        HPI_QADD_QSUB_A1(),
1230        HPI_QADD_QSUB_T1(),
1231        HPI_QADD_ETC_A1(),
1232        HPI_QASX_QSAX_UQASX_UQSAX_T1(),
1233        HPI_QADD_ETC_T1(),
1234        HPI_USUB_ETC_A1(),
1235        HPI_ADD_ETC_A1(),
1236        HPI_ADD_ETC_T1(),
1237        HPI_QDADD_QDSUB_A1(),
1238        HPI_QDADD_QDSUB_T1(),
1239        HPI_SASX_SHASX_UASX_UHASX_A1(),
1240        HPI_SHSAX_SSAX_UHSAX_USAX_A1(),
1241        HPI_SXTB_SXTB16_SXTH_UXTB_UXTB16_UXTH_A1(),
1242
1243        # Must be after HPI_SXTB_SXTB16_SXTH_UXTB_UXTB16_UXTH_A1
1244        HPI_SXTAB_SXTAB16_SXTAH_UXTAB_UXTAB16_UXTAH_A1(),
1245
1246        HPI_SXTAB_T1(),
1247        HPI_SXTAB16_T1(),
1248        HPI_SXTAH_T1(),
1249        HPI_SXTB_T2(),
1250        HPI_SXTB16_T1(),
1251        HPI_SXTH_T2(),
1252
1253        HPI_PKH_A1(),
1254        HPI_PKH_T1(),
1255        HPI_SBFX_UBFX_A1(),
1256        HPI_SEL_A1_Suppress(),
1257        HPI_RBIT_A1(),
1258        HPI_REV_REV16_A1(),
1259        HPI_REVSH_A1(),
1260        HPI_USAD8_USADA8_A1_Suppress(),
1261        HPI_BFI_A1(),
1262        HPI_BFI_T1(),
1263
1264        HPI_CMN_register_A1(), # Need to check for shift
1265        HPI_CMN_immediate_A1(),
1266        HPI_CMP_register_A1(), # Need to check for shift
1267        HPI_CMP_immediate_A1(),
1268
1269        HPI_DataProcessingNoShift(),
1270        HPI_DataProcessingAllowShifti(),
1271        # HPI_DataProcessingAllowMovShiftr(),
1272
1273        # Data processing ops that match SuppressShift but are *not*
1274        # to be suppressed here
1275        HPI_CLZ_A1(),
1276        HPI_CLZ_T1(),
1277        HPI_DataProcessingSuppressShift(),
1278        # Can you dual issue a branch?
1279        # HPI_DataProcessingSuppressBranch(),
1280        HPI_Cxxx_A64(),
1281
1282        HPI_DefaultA64Int(),
1283        HPI_DefaultInt()]
1284    opLat = 3
1285
1286class HPI_IntMulFU(MinorFU):
1287    opClasses = minorMakeOpClassSet(['IntMult'])
1288    timings = [
1289        HPI_MLA_A1(), HPI_MLA_T1(),
1290        HPI_MLS_A1(), HPI_MLS_T1(),
1291        HPI_SMLABB_A1(), HPI_SMLABB_T1(),
1292        HPI_SMLAWB_A1(), HPI_SMLAWB_T1(),
1293        HPI_SMLAD_A1(), HPI_SMLAD_T1(),
1294        HPI_SMMUL_A1(), HPI_SMMUL_T1(),
1295        # SMMUL_A1 must be before SMMLA_A1
1296        HPI_SMMLA_A1(), HPI_SMMLA_T1(),
1297        HPI_SMMLS_A1(), HPI_SMMLS_T1(),
1298        HPI_UMAAL_A1(), HPI_UMAAL_T1(),
1299
1300        HPI_MADD_A64(),
1301        HPI_DefaultA64Mul(),
1302        HPI_DefaultMul()]
1303    opLat = 3
1304    cantForwardFromFUIndices = [0, 1, 5] # Int1, Int2, Mem
1305
1306class HPI_IntDivFU(MinorFU):
1307    opClasses = minorMakeOpClassSet(['IntDiv'])
1308    timings = [HPI_SDIV_A1(), HPI_UDIV_A1(),
1309        HPI_SDIV_A64()]
1310    issueLat = 3
1311    opLat = 3
1312
1313class HPI_MemFU(MinorFU):
1314    opClasses = minorMakeOpClassSet(['MemRead', 'MemWrite', 'FloatMemRead',
1315                                     'FloatMemWrite'])
1316    timings = [HPI_DefaultMem(), HPI_DefaultMem64()]
1317    opLat = 1
1318    cantForwardFromFUIndices = [5] # Mem (this FU)
1319
1320class HPI_MiscFU(MinorFU):
1321    opClasses = minorMakeOpClassSet(['IprAccess', 'InstPrefetch'])
1322    opLat = 1
1323
1324class HPI_FUPool(MinorFUPool):
1325    funcUnits = [HPI_IntFU(), # 0
1326        HPI_Int2FU(), # 1
1327        HPI_IntMulFU(), # 2
1328        HPI_IntDivFU(), # 3
1329        HPI_FloatSimdFU(), # 4
1330        HPI_MemFU(), # 5
1331        HPI_MiscFU() # 6
1332        ]
1333
1334class HPI_DTB(ArmTLB):
1335    size = 256
1336
1337class HPI_ITB(ArmTLB):
1338    size = 256
1339
1340class HPI_WalkCache(Cache):
1341    data_latency = 4
1342    tag_latency = 4
1343    response_latency = 4
1344    mshrs = 6
1345    tgts_per_mshr = 8
1346    size = '1kB'
1347    assoc = 8
1348    write_buffers = 16
1349
1350class HPI_BP(TournamentBP):
1351    localPredictorSize = 64
1352    localCtrBits = 2
1353    localHistoryTableSize = 64
1354    globalPredictorSize = 1024
1355    globalCtrBits = 2
1356    choicePredictorSize = 1024
1357    choiceCtrBits = 2
1358    BTBEntries = 128
1359    BTBTagSize = 18
1360    RASSize = 8
1361    instShiftAmt = 2
1362
1363class HPI_ICache(Cache):
1364    data_latency = 1
1365    tag_latency = 1
1366    response_latency = 1
1367    mshrs = 2
1368    tgts_per_mshr = 8
1369    size = '32kB'
1370    assoc = 2
1371    # No prefetcher, this is handled by the core
1372
1373class HPI_DCache(Cache):
1374    data_latency = 1
1375    tag_latency = 1
1376    response_latency = 1
1377    mshrs = 4
1378    tgts_per_mshr = 8
1379    size = '32kB'
1380    assoc = 4
1381    write_buffers = 4
1382    prefetcher = StridePrefetcher(
1383        queue_size=4,
1384        degree=4)
1385
1386class HPI_L2(Cache):
1387    data_latency = 13
1388    tag_latency = 13
1389    response_latency = 5
1390    mshrs = 4
1391    tgts_per_mshr = 8
1392    size = '1024kB'
1393    assoc = 16
1394    write_buffers = 16
1395    # prefetcher FIXME
1396
1397class HPI(MinorCPU):
1398    # Inherit the doc string from the module to avoid repeating it
1399    # here.
1400    __doc__ = __doc__
1401
1402    fetch1LineSnapWidth = 0
1403    fetch1LineWidth = 0
1404    fetch1FetchLimit = 1
1405    fetch1ToFetch2ForwardDelay = 1
1406    fetch1ToFetch2BackwardDelay = 1
1407
1408    fetch2InputBufferSize = 2
1409    fetch2ToDecodeForwardDelay = 1
1410    fetch2CycleInput = True
1411
1412    decodeInputBufferSize = 3
1413    decodeToExecuteForwardDelay = 1
1414    decodeInputWidth = 2
1415    decodeCycleInput = True
1416
1417    executeInputWidth = 2
1418    executeCycleInput = True
1419    executeIssueLimit = 2
1420
1421    # Only allow one ld/st to be issued but the second ld/st FU allows
1422    # back-to-back loads
1423    executeMemoryIssueLimit = 1
1424
1425    executeCommitLimit = 2
1426    executeMemoryCommitLimit = 1
1427    executeInputBufferSize = 7
1428
1429    executeMaxAccessesInMemory = 2
1430
1431    executeLSQMaxStoreBufferStoresPerCycle = 2
1432    executeLSQRequestsQueueSize = 1
1433    executeLSQTransfersQueueSize = 2
1434    executeLSQStoreBufferSize = 5
1435    executeBranchDelay = 1
1436    executeFuncUnits = HPI_FUPool()
1437    executeSetTraceTimeOnCommit = True
1438    executeSetTraceTimeOnIssue = False
1439
1440    executeAllowEarlyMemoryIssue = True
1441
1442    enableIdling = True
1443
1444    branchPred = HPI_BP(numThreads = Parent.numThreads)
1445
1446    itb = HPI_ITB()
1447    dtb = HPI_DTB()
1448
1449__all__ = [
1450    "HPI_BP",
1451    "HPI_ITB", "HPI_DTB", "HPI_WalkCache",
1452    "HPI_ICache", "HPI_DCache", "HPI_L2",
1453    "HPI",
1454]
1455