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