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