neon64.isa revision 13120
110037SARM gem5 Developers// -*- mode: c++ -*-
210037SARM gem5 Developers
313120SEdmund.Grimley-Evans@arm.com// Copyright (c) 2012-2013, 2015-2018 ARM Limited
410037SARM gem5 Developers// All rights reserved
510037SARM gem5 Developers//
610037SARM gem5 Developers// The license below extends only to copyright in the software and shall
710037SARM gem5 Developers// not be construed as granting a license to any other intellectual
810037SARM gem5 Developers// property including but not limited to intellectual property relating
910037SARM gem5 Developers// to a hardware implementation of the functionality of the software
1010037SARM gem5 Developers// licensed hereunder.  You may use the software subject to the license
1110037SARM gem5 Developers// terms below provided that you ensure that this notice is replicated
1210037SARM gem5 Developers// unmodified and in its entirety in all distributions of the software,
1310037SARM gem5 Developers// modified or unmodified, in source code or in binary form.
1410037SARM gem5 Developers//
1510037SARM gem5 Developers// Redistribution and use in source and binary forms, with or without
1610037SARM gem5 Developers// modification, are permitted provided that the following conditions are
1710037SARM gem5 Developers// met: redistributions of source code must retain the above copyright
1810037SARM gem5 Developers// notice, this list of conditions and the following disclaimer;
1910037SARM gem5 Developers// redistributions in binary form must reproduce the above copyright
2010037SARM gem5 Developers// notice, this list of conditions and the following disclaimer in the
2110037SARM gem5 Developers// documentation and/or other materials provided with the distribution;
2210037SARM gem5 Developers// neither the name of the copyright holders nor the names of its
2310037SARM gem5 Developers// contributors may be used to endorse or promote products derived from
2410037SARM gem5 Developers// this software without specific prior written permission.
2510037SARM gem5 Developers//
2610037SARM gem5 Developers// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2710037SARM gem5 Developers// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2810037SARM gem5 Developers// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2910037SARM gem5 Developers// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
3010037SARM gem5 Developers// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
3110037SARM gem5 Developers// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
3210037SARM gem5 Developers// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
3310037SARM gem5 Developers// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
3410037SARM gem5 Developers// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3510037SARM gem5 Developers// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
3610037SARM gem5 Developers// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3710037SARM gem5 Developers//
3810037SARM gem5 Developers// Authors: Giacomo Gabrielli
3910037SARM gem5 Developers//          Mbou Eyole
4010037SARM gem5 Developers
4110037SARM gem5 Developerslet {{
4210037SARM gem5 Developers
4310037SARM gem5 Developers    header_output = ""
4410037SARM gem5 Developers    exec_output = ""
4511165SRekai.GonzalezAlberquilla@arm.com    decoders = { 'Generic' : {} }
4610037SARM gem5 Developers
4710037SARM gem5 Developers    # FP types (FP operations always work with unsigned representations)
4813120SEdmund.Grimley-Evans@arm.com    floatTypes = ("uint16_t", "uint32_t", "uint64_t")
4910037SARM gem5 Developers    smallFloatTypes = ("uint32_t",)
5010037SARM gem5 Developers
5110037SARM gem5 Developers    def threeEqualRegInstX(name, Name, opClass, types, rCount, op,
5210037SARM gem5 Developers                           readDest=False, pairwise=False, scalar=False,
5311165SRekai.GonzalezAlberquilla@arm.com                           byElem=False, decoder='Generic'):
5410037SARM gem5 Developers        assert (not pairwise) or ((not byElem) and (not scalar))
5511165SRekai.GonzalezAlberquilla@arm.com        global header_output, exec_output, decoders
5610037SARM gem5 Developers        eWalkCode = simd64EnabledCheckCode + '''
5710037SARM gem5 Developers        RegVect srcReg1, destReg;
5810037SARM gem5 Developers        '''
5910037SARM gem5 Developers        if byElem:
6010037SARM gem5 Developers            # 2nd register operand has to be read fully
6110037SARM gem5 Developers            eWalkCode += '''
6210037SARM gem5 Developers        FullRegVect srcReg2;
6310037SARM gem5 Developers        '''
6410037SARM gem5 Developers        else:
6510037SARM gem5 Developers            eWalkCode += '''
6610037SARM gem5 Developers        RegVect srcReg2;
6710037SARM gem5 Developers        '''
6810037SARM gem5 Developers        for reg in range(rCount):
6910037SARM gem5 Developers            eWalkCode += '''
7010037SARM gem5 Developers        srcReg1.regs[%(reg)d] = htog(AA64FpOp1P%(reg)d_uw);
7110037SARM gem5 Developers        srcReg2.regs[%(reg)d] = htog(AA64FpOp2P%(reg)d_uw);
7210037SARM gem5 Developers        ''' % { "reg" : reg }
7310037SARM gem5 Developers            if readDest:
7410037SARM gem5 Developers                eWalkCode += '''
7510037SARM gem5 Developers        destReg.regs[%(reg)d] = htog(AA64FpDestP%(reg)d_uw);
7610037SARM gem5 Developers        ''' % { "reg" : reg }
7710037SARM gem5 Developers        if byElem:
7810037SARM gem5 Developers            # 2nd operand has to be read fully
7910037SARM gem5 Developers            for reg in range(rCount, 4):
8010037SARM gem5 Developers                eWalkCode += '''
8110037SARM gem5 Developers        srcReg2.regs[%(reg)d] = htog(AA64FpOp2P%(reg)d_uw);
8210037SARM gem5 Developers        ''' % { "reg" : reg }
8310037SARM gem5 Developers        readDestCode = ''
8410037SARM gem5 Developers        if readDest:
8510037SARM gem5 Developers            readDestCode = 'destElem = gtoh(destReg.elements[i]);'
8610037SARM gem5 Developers        if pairwise:
8710037SARM gem5 Developers            eWalkCode += '''
8810037SARM gem5 Developers        for (unsigned i = 0; i < eCount; i++) {
8910037SARM gem5 Developers            Element srcElem1 = gtoh(2 * i < eCount ?
9010037SARM gem5 Developers                                    srcReg1.elements[2 * i] :
9110037SARM gem5 Developers                                    srcReg2.elements[2 * i - eCount]);
9210037SARM gem5 Developers            Element srcElem2 = gtoh(2 * i < eCount ?
9310037SARM gem5 Developers                                    srcReg1.elements[2 * i + 1] :
9410037SARM gem5 Developers                                    srcReg2.elements[2 * i + 1 - eCount]);
9510037SARM gem5 Developers            Element destElem;
9610037SARM gem5 Developers            %(readDest)s
9710037SARM gem5 Developers            %(op)s
9810037SARM gem5 Developers            destReg.elements[i] = htog(destElem);
9910037SARM gem5 Developers        }
10010037SARM gem5 Developers        ''' % { "op" : op, "readDest" : readDestCode }
10110037SARM gem5 Developers        else:
10210037SARM gem5 Developers            scalarCheck = '''
10310037SARM gem5 Developers            if (i != 0) {
10410037SARM gem5 Developers                destReg.elements[i] = 0;
10510037SARM gem5 Developers                continue;
10610037SARM gem5 Developers            }
10710037SARM gem5 Developers            '''
10810037SARM gem5 Developers            eWalkCode += '''
10910037SARM gem5 Developers        for (unsigned i = 0; i < eCount; i++) {
11010037SARM gem5 Developers            %(scalarCheck)s
11110037SARM gem5 Developers            Element srcElem1 = gtoh(srcReg1.elements[i]);
11210037SARM gem5 Developers            Element srcElem2 = gtoh(srcReg2.elements[%(src2Index)s]);
11310037SARM gem5 Developers            Element destElem;
11410037SARM gem5 Developers            %(readDest)s
11510037SARM gem5 Developers            %(op)s
11610037SARM gem5 Developers            destReg.elements[i] = htog(destElem);
11710037SARM gem5 Developers        }
11810037SARM gem5 Developers        ''' % { "op" : op, "readDest" : readDestCode,
11910037SARM gem5 Developers                "scalarCheck" : scalarCheck if scalar else "",
12010037SARM gem5 Developers                "src2Index" : "imm" if byElem else "i" }
12110037SARM gem5 Developers        for reg in range(rCount):
12210037SARM gem5 Developers            eWalkCode += '''
12310037SARM gem5 Developers        AA64FpDestP%(reg)d_uw = gtoh(destReg.regs[%(reg)d]);
12410037SARM gem5 Developers        ''' % { "reg" : reg }
12510037SARM gem5 Developers        if rCount < 4:  # zero upper half
12610037SARM gem5 Developers            for reg in range(rCount, 4):
12710037SARM gem5 Developers                eWalkCode += '''
12810037SARM gem5 Developers        AA64FpDestP%(reg)d_uw = 0;
12910037SARM gem5 Developers        ''' % { "reg" : reg }
13010037SARM gem5 Developers        iop = InstObjParams(name, Name,
13110037SARM gem5 Developers                            "DataX2RegImmOp" if byElem else "DataX2RegOp",
13210037SARM gem5 Developers                            { "code": eWalkCode,
13310037SARM gem5 Developers                              "r_count": rCount,
13410037SARM gem5 Developers                              "op_class": opClass }, [])
13510037SARM gem5 Developers        if byElem:
13610037SARM gem5 Developers            header_output += NeonX2RegImmOpDeclare.subst(iop)
13710037SARM gem5 Developers        else:
13810037SARM gem5 Developers            header_output += NeonX2RegOpDeclare.subst(iop)
13910037SARM gem5 Developers        exec_output += NeonXEqualRegOpExecute.subst(iop)
14010037SARM gem5 Developers        for type in types:
14110037SARM gem5 Developers            substDict = { "targs" : type,
14210037SARM gem5 Developers                          "class_name" : Name }
14310037SARM gem5 Developers            exec_output += NeonXExecDeclare.subst(substDict)
14410037SARM gem5 Developers
14510037SARM gem5 Developers    def threeUnequalRegInstX(name, Name, opClass, types, op,
14610037SARM gem5 Developers                             bigSrc1, bigSrc2, bigDest, readDest, scalar=False,
14710037SARM gem5 Developers                             byElem=False, hi=False):
14810037SARM gem5 Developers        assert not (scalar and hi)
14910037SARM gem5 Developers        global header_output, exec_output
15010037SARM gem5 Developers        src1Cnt = src2Cnt = destCnt = 2
15110037SARM gem5 Developers        src1Prefix = src2Prefix = destPrefix = ''
15210037SARM gem5 Developers        if bigSrc1:
15310037SARM gem5 Developers            src1Cnt = 4
15410037SARM gem5 Developers            src1Prefix = 'Big'
15510037SARM gem5 Developers        if bigSrc2:
15610037SARM gem5 Developers            src2Cnt = 4
15710037SARM gem5 Developers            src2Prefix = 'Big'
15810037SARM gem5 Developers        if bigDest:
15910037SARM gem5 Developers            destCnt = 4
16010037SARM gem5 Developers            destPrefix = 'Big'
16110037SARM gem5 Developers        if byElem:
16210037SARM gem5 Developers            src2Prefix = 'Full'
16310037SARM gem5 Developers        eWalkCode = simd64EnabledCheckCode + '''
16410037SARM gem5 Developers        %sRegVect srcReg1;
16510037SARM gem5 Developers        %sRegVect srcReg2;
16610037SARM gem5 Developers        %sRegVect destReg;
16710037SARM gem5 Developers        ''' % (src1Prefix, src2Prefix, destPrefix)
16810037SARM gem5 Developers        srcReg1 = 0
16910037SARM gem5 Developers        if hi and not bigSrc1:  # long/widening operations
17010037SARM gem5 Developers            srcReg1 = 2
17110037SARM gem5 Developers        for reg in range(src1Cnt):
17210037SARM gem5 Developers            eWalkCode += '''
17310037SARM gem5 Developers        srcReg1.regs[%(reg)d] = htog(AA64FpOp1P%(srcReg1)d_uw);
17410037SARM gem5 Developers        ''' % { "reg" : reg, "srcReg1" : srcReg1 }
17510037SARM gem5 Developers            srcReg1 += 1
17610037SARM gem5 Developers        srcReg2 = 0
17710037SARM gem5 Developers        if (not byElem) and (hi and not bigSrc2):  # long/widening operations
17810037SARM gem5 Developers            srcReg2 = 2
17910037SARM gem5 Developers        for reg in range(src2Cnt):
18010037SARM gem5 Developers            eWalkCode += '''
18110037SARM gem5 Developers        srcReg2.regs[%(reg)d] = htog(AA64FpOp2P%(srcReg2)d_uw);
18210037SARM gem5 Developers        ''' % { "reg" : reg, "srcReg2" : srcReg2 }
18310037SARM gem5 Developers            srcReg2 += 1
18410037SARM gem5 Developers        if byElem:
18510037SARM gem5 Developers            # 2nd operand has to be read fully
18610037SARM gem5 Developers            for reg in range(src2Cnt, 4):
18710037SARM gem5 Developers                eWalkCode += '''
18810037SARM gem5 Developers        srcReg2.regs[%(reg)d] = htog(AA64FpOp2P%(reg)d_uw);
18910037SARM gem5 Developers        ''' % { "reg" : reg }
19010037SARM gem5 Developers        if readDest:
19110037SARM gem5 Developers            for reg in range(destCnt):
19210037SARM gem5 Developers                eWalkCode += '''
19310037SARM gem5 Developers        destReg.regs[%(reg)d] = htog(AA64FpDestP%(reg)d_uw);
19410037SARM gem5 Developers        ''' % { "reg" : reg }
19510037SARM gem5 Developers        readDestCode = ''
19610037SARM gem5 Developers        if readDest:
19710037SARM gem5 Developers            readDestCode = 'destElem = gtoh(destReg.elements[i]);'
19810037SARM gem5 Developers        scalarCheck = '''
19910037SARM gem5 Developers            if (i != 0) {
20010037SARM gem5 Developers                destReg.elements[i] = 0;
20110037SARM gem5 Developers                continue;
20210037SARM gem5 Developers            }
20310037SARM gem5 Developers            '''
20410037SARM gem5 Developers        eWalkCode += '''
20510037SARM gem5 Developers        for (unsigned i = 0; i < eCount; i++) {
20610037SARM gem5 Developers            %(scalarCheck)s
20710037SARM gem5 Developers            %(src1Prefix)sElement srcElem1 = gtoh(srcReg1.elements[i]);
20810037SARM gem5 Developers            %(src1Prefix)sElement srcElem2 = gtoh(srcReg2.elements[%(src2Index)s]);
20910037SARM gem5 Developers            %(destPrefix)sElement destElem;
21010037SARM gem5 Developers            %(readDest)s
21110037SARM gem5 Developers            %(op)s
21210037SARM gem5 Developers            destReg.elements[i] = htog(destElem);
21310037SARM gem5 Developers        }
21410037SARM gem5 Developers        ''' % { "op" : op, "readDest" : readDestCode,
21510037SARM gem5 Developers                "src1Prefix" : src1Prefix, "src2Prefix" : src2Prefix,
21610037SARM gem5 Developers                "destPrefix" : destPrefix,
21710037SARM gem5 Developers                "scalarCheck" : scalarCheck if scalar else "",
21810037SARM gem5 Developers                "src2Index" : "imm" if byElem else "i" }
21910037SARM gem5 Developers        destReg = 0
22010037SARM gem5 Developers        if hi and not bigDest:
22110037SARM gem5 Developers            # narrowing operations
22210037SARM gem5 Developers            destReg = 2
22310037SARM gem5 Developers        for reg in range(destCnt):
22410037SARM gem5 Developers            eWalkCode += '''
22510037SARM gem5 Developers        AA64FpDestP%(destReg)d_uw = gtoh(destReg.regs[%(reg)d]);
22610037SARM gem5 Developers        ''' % { "reg" : reg, "destReg": destReg }
22710037SARM gem5 Developers            destReg += 1
22812110SRekai.GonzalezAlberquilla@arm.com        if destCnt < 4:
22912110SRekai.GonzalezAlberquilla@arm.com            if hi:  # Explicitly merge with lower half
23012110SRekai.GonzalezAlberquilla@arm.com                for reg in range(0, destCnt):
23112110SRekai.GonzalezAlberquilla@arm.com                    eWalkCode += '''
23212110SRekai.GonzalezAlberquilla@arm.com        AA64FpDestP%(reg)d_uw = AA64FpDestP%(reg)d_uw;''' % { "reg" : reg }
23312110SRekai.GonzalezAlberquilla@arm.com            else:  # zero upper half
23412110SRekai.GonzalezAlberquilla@arm.com                for reg in range(destCnt, 4):
23512110SRekai.GonzalezAlberquilla@arm.com                    eWalkCode += '''
23612110SRekai.GonzalezAlberquilla@arm.com        AA64FpDestP%(reg)d_uw = 0;''' % { "reg" : reg }
23712110SRekai.GonzalezAlberquilla@arm.com
23810037SARM gem5 Developers        iop = InstObjParams(name, Name,
23910037SARM gem5 Developers                            "DataX2RegImmOp" if byElem else "DataX2RegOp",
24010037SARM gem5 Developers                            { "code": eWalkCode,
24110037SARM gem5 Developers                              "r_count": 2,
24210037SARM gem5 Developers                              "op_class": opClass }, [])
24310037SARM gem5 Developers        if byElem:
24410037SARM gem5 Developers            header_output += NeonX2RegImmOpDeclare.subst(iop)
24510037SARM gem5 Developers        else:
24610037SARM gem5 Developers            header_output += NeonX2RegOpDeclare.subst(iop)
24710037SARM gem5 Developers        exec_output += NeonXUnequalRegOpExecute.subst(iop)
24810037SARM gem5 Developers        for type in types:
24910037SARM gem5 Developers            substDict = { "targs" : type,
25010037SARM gem5 Developers                          "class_name" : Name }
25110037SARM gem5 Developers            exec_output += NeonXExecDeclare.subst(substDict)
25210037SARM gem5 Developers
25310037SARM gem5 Developers    def threeRegNarrowInstX(name, Name, opClass, types, op, readDest=False,
25410037SARM gem5 Developers                            scalar=False, byElem=False, hi=False):
25510037SARM gem5 Developers        assert not byElem
25610037SARM gem5 Developers        threeUnequalRegInstX(name, Name, opClass, types, op,
25710037SARM gem5 Developers                             True, True, False, readDest, scalar, byElem, hi)
25810037SARM gem5 Developers
25910037SARM gem5 Developers    def threeRegLongInstX(name, Name, opClass, types, op, readDest=False,
26010037SARM gem5 Developers                          scalar=False, byElem=False, hi=False):
26110037SARM gem5 Developers        threeUnequalRegInstX(name, Name, opClass, types, op,
26210037SARM gem5 Developers                             False, False, True, readDest, scalar, byElem, hi)
26310037SARM gem5 Developers
26410037SARM gem5 Developers    def threeRegWideInstX(name, Name, opClass, types, op, readDest=False,
26510037SARM gem5 Developers                          scalar=False, byElem=False, hi=False):
26610037SARM gem5 Developers        assert not byElem
26710037SARM gem5 Developers        threeUnequalRegInstX(name, Name, opClass, types, op,
26810037SARM gem5 Developers                             True, False, True, readDest, scalar, byElem, hi)
26910037SARM gem5 Developers
27010037SARM gem5 Developers    def twoEqualRegInstX(name, Name, opClass, types, rCount, op,
27110037SARM gem5 Developers                         readDest=False, scalar=False, byElem=False,
27210037SARM gem5 Developers                         hasImm=False, isDup=False):
27310037SARM gem5 Developers        global header_output, exec_output
27410037SARM gem5 Developers        assert (not isDup) or byElem
27510037SARM gem5 Developers        if byElem:
27610037SARM gem5 Developers            hasImm = True
27710037SARM gem5 Developers        if isDup:
27810037SARM gem5 Developers            eWalkCode = simd64EnabledCheckCode + '''
27910037SARM gem5 Developers        FullRegVect srcReg1;
28010037SARM gem5 Developers        RegVect destReg;
28110037SARM gem5 Developers        '''
28210037SARM gem5 Developers        else:
28310037SARM gem5 Developers            eWalkCode = simd64EnabledCheckCode + '''
28410037SARM gem5 Developers        RegVect srcReg1, destReg;
28510037SARM gem5 Developers        '''
28610037SARM gem5 Developers        for reg in range(4 if isDup else rCount):
28710037SARM gem5 Developers            eWalkCode += '''
28810037SARM gem5 Developers        srcReg1.regs[%(reg)d] = htog(AA64FpOp1P%(reg)d_uw);
28910037SARM gem5 Developers        ''' % { "reg" : reg }
29010037SARM gem5 Developers            if readDest:
29110037SARM gem5 Developers                eWalkCode += '''
29210037SARM gem5 Developers        destReg.regs[%(reg)d] = htog(AA64FpDestP%(reg)d_uw);
29310037SARM gem5 Developers        ''' % { "reg" : reg }
29410037SARM gem5 Developers        readDestCode = ''
29510037SARM gem5 Developers        if readDest:
29610037SARM gem5 Developers            readDestCode = 'destElem = gtoh(destReg.elements[i]);'
29710037SARM gem5 Developers        scalarCheck = '''
29810037SARM gem5 Developers            if (i != 0) {
29910037SARM gem5 Developers                destReg.elements[i] = 0;
30010037SARM gem5 Developers                continue;
30110037SARM gem5 Developers            }
30210037SARM gem5 Developers            '''
30310037SARM gem5 Developers        eWalkCode += '''
30410037SARM gem5 Developers        for (unsigned i = 0; i < eCount; i++) {
30510037SARM gem5 Developers            %(scalarCheck)s
30610037SARM gem5 Developers            unsigned j = i;
30710037SARM gem5 Developers            Element srcElem1 = gtoh(srcReg1.elements[%(src1Index)s]);
30810037SARM gem5 Developers            Element destElem;
30910037SARM gem5 Developers            %(readDest)s
31010037SARM gem5 Developers            %(op)s
31110037SARM gem5 Developers            destReg.elements[j] = htog(destElem);
31210037SARM gem5 Developers        }
31310037SARM gem5 Developers        ''' % { "op" : op, "readDest" : readDestCode,
31410037SARM gem5 Developers                "scalarCheck" : scalarCheck if scalar else "",
31510037SARM gem5 Developers                "src1Index" : "imm" if byElem else "i" }
31610037SARM gem5 Developers        for reg in range(rCount):
31710037SARM gem5 Developers            eWalkCode += '''
31810037SARM gem5 Developers        AA64FpDestP%(reg)d_uw = gtoh(destReg.regs[%(reg)d]);
31910037SARM gem5 Developers        ''' % { "reg" : reg }
32010037SARM gem5 Developers        if rCount < 4:  # zero upper half
32110037SARM gem5 Developers            for reg in range(rCount, 4):
32210037SARM gem5 Developers                eWalkCode += '''
32310037SARM gem5 Developers        AA64FpDestP%(reg)d_uw = 0;
32410037SARM gem5 Developers        ''' % { "reg" : reg }
32510037SARM gem5 Developers        iop = InstObjParams(name, Name,
32610037SARM gem5 Developers                            "DataX1RegImmOp" if hasImm else "DataX1RegOp",
32710037SARM gem5 Developers                            { "code": eWalkCode,
32810037SARM gem5 Developers                              "r_count": rCount,
32910037SARM gem5 Developers                              "op_class": opClass }, [])
33010037SARM gem5 Developers        if hasImm:
33110037SARM gem5 Developers            header_output += NeonX1RegImmOpDeclare.subst(iop)
33210037SARM gem5 Developers        else:
33310037SARM gem5 Developers            header_output += NeonX1RegOpDeclare.subst(iop)
33410037SARM gem5 Developers        exec_output += NeonXEqualRegOpExecute.subst(iop)
33510037SARM gem5 Developers        for type in types:
33610037SARM gem5 Developers            substDict = { "targs" : type,
33710037SARM gem5 Developers                          "class_name" : Name }
33810037SARM gem5 Developers            exec_output += NeonXExecDeclare.subst(substDict)
33910037SARM gem5 Developers
34010037SARM gem5 Developers    def twoRegLongInstX(name, Name, opClass, types, op, readDest=False,
34110037SARM gem5 Developers                        hi=False, hasImm=False):
34210037SARM gem5 Developers        global header_output, exec_output
34310037SARM gem5 Developers        eWalkCode = simd64EnabledCheckCode + '''
34410037SARM gem5 Developers        RegVect srcReg1;
34510037SARM gem5 Developers        BigRegVect destReg;
34610037SARM gem5 Developers        '''
34710037SARM gem5 Developers        destReg = 0 if not hi else 2
34810037SARM gem5 Developers        for reg in range(2):
34910037SARM gem5 Developers            eWalkCode += '''
35010037SARM gem5 Developers        srcReg1.regs[%(reg)d] = htog(AA64FpOp1P%(destReg)d_uw);
35110037SARM gem5 Developers        ''' % { "reg" : reg, "destReg": destReg }
35210037SARM gem5 Developers            destReg += 1
35310037SARM gem5 Developers        destReg = 0 if not hi else 2
35410037SARM gem5 Developers        if readDest:
35510037SARM gem5 Developers            for reg in range(4):
35610037SARM gem5 Developers                eWalkCode += '''
35710037SARM gem5 Developers        destReg.regs[%(reg)d] = htog(AA64FpDestP%(reg)d_uw);
35810037SARM gem5 Developers        ''' % { "reg" : reg }
35910037SARM gem5 Developers                destReg += 1
36010037SARM gem5 Developers        readDestCode = ''
36110037SARM gem5 Developers        if readDest:
36210037SARM gem5 Developers            readDestCode = 'destReg = gtoh(destReg.elements[i]);'
36310037SARM gem5 Developers        eWalkCode += '''
36410037SARM gem5 Developers        for (unsigned i = 0; i < eCount; i++) {
36510037SARM gem5 Developers            Element srcElem1 = gtoh(srcReg1.elements[i]);
36610037SARM gem5 Developers            BigElement destElem;
36710037SARM gem5 Developers            %(readDest)s
36810037SARM gem5 Developers            %(op)s
36910037SARM gem5 Developers            destReg.elements[i] = htog(destElem);
37010037SARM gem5 Developers        }
37110037SARM gem5 Developers        ''' % { "op" : op, "readDest" : readDestCode }
37210037SARM gem5 Developers        for reg in range(4):
37310037SARM gem5 Developers            eWalkCode += '''
37410037SARM gem5 Developers        AA64FpDestP%(reg)d_uw = gtoh(destReg.regs[%(reg)d]);
37510037SARM gem5 Developers        ''' % { "reg" : reg }
37610037SARM gem5 Developers        iop = InstObjParams(name, Name,
37710037SARM gem5 Developers                            "DataX1RegImmOp" if hasImm else "DataX1RegOp",
37810037SARM gem5 Developers                            { "code": eWalkCode,
37910037SARM gem5 Developers                              "r_count": 2,
38010037SARM gem5 Developers                              "op_class": opClass }, [])
38110037SARM gem5 Developers        if hasImm:
38210037SARM gem5 Developers            header_output += NeonX1RegImmOpDeclare.subst(iop)
38310037SARM gem5 Developers        else:
38410037SARM gem5 Developers            header_output += NeonX1RegOpDeclare.subst(iop)
38510037SARM gem5 Developers        exec_output += NeonXUnequalRegOpExecute.subst(iop)
38610037SARM gem5 Developers        for type in types:
38710037SARM gem5 Developers            substDict = { "targs" : type,
38810037SARM gem5 Developers                          "class_name" : Name }
38910037SARM gem5 Developers            exec_output += NeonXExecDeclare.subst(substDict)
39010037SARM gem5 Developers
39110037SARM gem5 Developers    def twoRegNarrowInstX(name, Name, opClass, types, op, readDest=False,
39210037SARM gem5 Developers                          scalar=False, hi=False, hasImm=False):
39310037SARM gem5 Developers        global header_output, exec_output
39410037SARM gem5 Developers        eWalkCode = simd64EnabledCheckCode + '''
39510037SARM gem5 Developers        BigRegVect srcReg1;
39610037SARM gem5 Developers        RegVect destReg;
39710037SARM gem5 Developers        '''
39810037SARM gem5 Developers        for reg in range(4):
39910037SARM gem5 Developers            eWalkCode += '''
40010037SARM gem5 Developers        srcReg1.regs[%(reg)d] = htog(AA64FpOp1P%(reg)d_uw);
40110037SARM gem5 Developers        ''' % { "reg" : reg }
40210037SARM gem5 Developers        if readDest:
40310037SARM gem5 Developers            for reg in range(2):
40410037SARM gem5 Developers                eWalkCode += '''
40510037SARM gem5 Developers        destReg.regs[%(reg)d] = htog(AA64FpDestP%(reg)d_uw);
40610037SARM gem5 Developers        ''' % { "reg" : reg }
40710037SARM gem5 Developers        else:
40810037SARM gem5 Developers            eWalkCode += '''
40910037SARM gem5 Developers        destReg.elements[0] = 0;
41010037SARM gem5 Developers        ''' % { "reg" : reg }
41110037SARM gem5 Developers        readDestCode = ''
41210037SARM gem5 Developers        if readDest:
41310037SARM gem5 Developers            readDestCode = 'destElem = gtoh(destReg.elements[i]);'
41410037SARM gem5 Developers        scalarCheck = '''
41510037SARM gem5 Developers            if (i != 0) {
41610037SARM gem5 Developers                destReg.elements[i] = 0;
41710037SARM gem5 Developers                continue;
41810037SARM gem5 Developers            }
41910037SARM gem5 Developers            '''
42010037SARM gem5 Developers        eWalkCode += '''
42110037SARM gem5 Developers        for (unsigned i = 0; i < eCount; i++) {
42210037SARM gem5 Developers            %(scalarCheck)s
42310037SARM gem5 Developers            BigElement srcElem1 = gtoh(srcReg1.elements[i]);
42410037SARM gem5 Developers            Element destElem;
42510037SARM gem5 Developers            %(readDest)s
42610037SARM gem5 Developers            %(op)s
42710037SARM gem5 Developers            destReg.elements[i] = htog(destElem);
42810037SARM gem5 Developers        }
42910037SARM gem5 Developers        ''' % { "op" : op, "readDest" : readDestCode,
43010037SARM gem5 Developers                "scalarCheck" : scalarCheck if scalar else "" }
43110037SARM gem5 Developers        destReg = 0 if not hi else 2
43210037SARM gem5 Developers        for reg in range(2):
43310037SARM gem5 Developers            eWalkCode += '''
43410037SARM gem5 Developers        AA64FpDestP%(destReg)d_uw = gtoh(destReg.regs[%(reg)d]);
43510037SARM gem5 Developers        ''' % { "reg" : reg, "destReg": destReg }
43610037SARM gem5 Developers            destReg += 1
43712110SRekai.GonzalezAlberquilla@arm.com        if hi:
43812110SRekai.GonzalezAlberquilla@arm.com            for reg in range(0, 2):  # Explicitly merge with the lower half
43912110SRekai.GonzalezAlberquilla@arm.com                eWalkCode += '''
44012110SRekai.GonzalezAlberquilla@arm.com        AA64FpDestP%(reg)d_uw = AA64FpDestP%(reg)d_uw;''' % { "reg" : reg }
44112110SRekai.GonzalezAlberquilla@arm.com        else:
44210037SARM gem5 Developers            for reg in range(2, 4):  # zero upper half
44310037SARM gem5 Developers                eWalkCode += '''
44410037SARM gem5 Developers        AA64FpDestP%(reg)d_uw = 0;
44510037SARM gem5 Developers        ''' % { "reg" : reg }
44612110SRekai.GonzalezAlberquilla@arm.com
44710037SARM gem5 Developers        iop = InstObjParams(name, Name,
44810037SARM gem5 Developers                            "DataX1RegImmOp" if hasImm else "DataX1RegOp",
44910037SARM gem5 Developers                            { "code": eWalkCode,
45010037SARM gem5 Developers                              "r_count": 2,
45110037SARM gem5 Developers                              "op_class": opClass }, [])
45210037SARM gem5 Developers        if hasImm:
45310037SARM gem5 Developers            header_output += NeonX1RegImmOpDeclare.subst(iop)
45410037SARM gem5 Developers        else:
45510037SARM gem5 Developers            header_output += NeonX1RegOpDeclare.subst(iop)
45610037SARM gem5 Developers        exec_output += NeonXUnequalRegOpExecute.subst(iop)
45710037SARM gem5 Developers        for type in types:
45810037SARM gem5 Developers            substDict = { "targs" : type,
45910037SARM gem5 Developers                          "class_name" : Name }
46010037SARM gem5 Developers            exec_output += NeonXExecDeclare.subst(substDict)
46110037SARM gem5 Developers
46210037SARM gem5 Developers    def threeRegScrambleInstX(name, Name, opClass, types, rCount, op):
46310037SARM gem5 Developers        global header_output, exec_output
46410037SARM gem5 Developers        eWalkCode = simd64EnabledCheckCode + '''
46510037SARM gem5 Developers        RegVect srcReg1, srcReg2, destReg;
46610037SARM gem5 Developers        '''
46710037SARM gem5 Developers        for reg in range(rCount):
46810037SARM gem5 Developers            eWalkCode += '''
46910037SARM gem5 Developers        srcReg1.regs[%(reg)d] = htog(AA64FpOp1P%(reg)d_uw);
47010037SARM gem5 Developers        srcReg2.regs[%(reg)d] = htog(AA64FpOp2P%(reg)d_uw);
47110037SARM gem5 Developers        ''' % { "reg" : reg }
47210037SARM gem5 Developers        eWalkCode += op
47310037SARM gem5 Developers        for reg in range(rCount):
47410037SARM gem5 Developers            eWalkCode += '''
47510037SARM gem5 Developers        AA64FpDestP%(reg)d_uw = gtoh(destReg.regs[%(reg)d]);
47610037SARM gem5 Developers        ''' % { "reg" : reg }
47710037SARM gem5 Developers        if rCount < 4:
47810037SARM gem5 Developers            for reg in range(rCount, 4):
47910037SARM gem5 Developers                eWalkCode += '''
48010037SARM gem5 Developers        AA64FpDestP%(reg)d_uw = 0;
48110037SARM gem5 Developers        ''' % { "reg" : reg }
48210037SARM gem5 Developers        iop = InstObjParams(name, Name,
48310037SARM gem5 Developers                            "DataX2RegOp",
48410037SARM gem5 Developers                            { "code": eWalkCode,
48510037SARM gem5 Developers                              "r_count": rCount,
48610037SARM gem5 Developers                              "op_class": opClass }, [])
48710037SARM gem5 Developers        header_output += NeonX2RegOpDeclare.subst(iop)
48810037SARM gem5 Developers        exec_output += NeonXEqualRegOpExecute.subst(iop)
48910037SARM gem5 Developers        for type in types:
49010037SARM gem5 Developers            substDict = { "targs" : type,
49110037SARM gem5 Developers                          "class_name" : Name }
49210037SARM gem5 Developers            exec_output += NeonXExecDeclare.subst(substDict)
49310037SARM gem5 Developers
49410037SARM gem5 Developers    def insFromVecElemInstX(name, Name, opClass, types, rCount):
49510037SARM gem5 Developers        global header_output, exec_output
49610037SARM gem5 Developers        eWalkCode = simd64EnabledCheckCode + '''
49710037SARM gem5 Developers        FullRegVect srcReg1;
49810037SARM gem5 Developers        RegVect destReg;
49910037SARM gem5 Developers        '''
50010037SARM gem5 Developers        for reg in range(4):
50110037SARM gem5 Developers            eWalkCode += '''
50210037SARM gem5 Developers        srcReg1.regs[%(reg)d] = htog(AA64FpOp1P%(reg)d_uw);
50310037SARM gem5 Developers        ''' % { "reg" : reg }
50410037SARM gem5 Developers        for reg in range(rCount):
50510037SARM gem5 Developers            eWalkCode += '''
50610037SARM gem5 Developers        destReg.regs[%(reg)d] = htog(AA64FpDestP%(reg)d_uw);
50710037SARM gem5 Developers        ''' % { "reg" : reg }
50810037SARM gem5 Developers        eWalkCode += '''
50910037SARM gem5 Developers        Element srcElem1 = gtoh(srcReg1.elements[imm2]);
51010037SARM gem5 Developers        Element destElem = srcElem1;
51110037SARM gem5 Developers        destReg.elements[imm1] = htog(destElem);
51210037SARM gem5 Developers        '''
51310037SARM gem5 Developers        for reg in range(rCount):
51410037SARM gem5 Developers            eWalkCode += '''
51510037SARM gem5 Developers        AA64FpDestP%(reg)d_uw = gtoh(destReg.regs[%(reg)d]);
51610037SARM gem5 Developers        ''' % { "reg" : reg }
51710037SARM gem5 Developers        iop = InstObjParams(name, Name,
51810037SARM gem5 Developers                            "DataX1Reg2ImmOp",
51910037SARM gem5 Developers                            { "code": eWalkCode,
52010037SARM gem5 Developers                              "r_count": rCount,
52110037SARM gem5 Developers                              "op_class": opClass }, [])
52210037SARM gem5 Developers        header_output += NeonX1Reg2ImmOpDeclare.subst(iop)
52310037SARM gem5 Developers        exec_output += NeonXEqualRegOpExecute.subst(iop)
52410037SARM gem5 Developers        for type in types:
52510037SARM gem5 Developers            substDict = { "targs" : type,
52610037SARM gem5 Developers                          "class_name" : Name }
52710037SARM gem5 Developers            exec_output += NeonXExecDeclare.subst(substDict)
52810037SARM gem5 Developers
52910037SARM gem5 Developers    def twoRegPairwiseScInstX(name, Name, opClass, types, rCount, op):
53010037SARM gem5 Developers        global header_output, exec_output
53110037SARM gem5 Developers        eWalkCode = simd64EnabledCheckCode + '''
53210037SARM gem5 Developers        RegVect srcReg1, destReg;
53310037SARM gem5 Developers        '''
53410037SARM gem5 Developers        for reg in range(rCount):
53510037SARM gem5 Developers            eWalkCode += '''
53610037SARM gem5 Developers        srcReg1.regs[%(reg)d] = htog(AA64FpOp1P%(reg)d_uw);
53710037SARM gem5 Developers        ''' % { "reg" : reg }
53810037SARM gem5 Developers        eWalkCode += '''
53910037SARM gem5 Developers        Element srcElem1 = gtoh(srcReg1.elements[0]);
54010037SARM gem5 Developers        Element srcElem2 = gtoh(srcReg1.elements[1]);
54110037SARM gem5 Developers        Element destElem;
54210037SARM gem5 Developers        %(op)s
54310037SARM gem5 Developers        destReg.elements[0] = htog(destElem);
54410037SARM gem5 Developers        ''' % { "op" : op }
54510037SARM gem5 Developers        destCnt = rCount / 2
54610037SARM gem5 Developers        for reg in range(destCnt):
54710037SARM gem5 Developers            eWalkCode += '''
54810037SARM gem5 Developers        AA64FpDestP%(reg)d_uw = gtoh(destReg.regs[%(reg)d]);
54910037SARM gem5 Developers        ''' % { "reg" : reg }
55010037SARM gem5 Developers        for reg in range(destCnt, 4):  # zero upper half
55110037SARM gem5 Developers            eWalkCode += '''
55210037SARM gem5 Developers        AA64FpDestP%(reg)d_uw = 0;
55310037SARM gem5 Developers        ''' % { "reg" : reg }
55410037SARM gem5 Developers        iop = InstObjParams(name, Name,
55510037SARM gem5 Developers                            "DataX1RegOp",
55610037SARM gem5 Developers                            { "code": eWalkCode,
55710037SARM gem5 Developers                              "r_count": rCount,
55810037SARM gem5 Developers                              "op_class": opClass }, [])
55910037SARM gem5 Developers        header_output += NeonX1RegOpDeclare.subst(iop)
56010037SARM gem5 Developers        exec_output += NeonXEqualRegOpExecute.subst(iop)
56110037SARM gem5 Developers        for type in types:
56210037SARM gem5 Developers            substDict = { "targs" : type,
56310037SARM gem5 Developers                          "class_name" : Name }
56410037SARM gem5 Developers            exec_output += NeonXExecDeclare.subst(substDict)
56510037SARM gem5 Developers
56610037SARM gem5 Developers    def twoRegAcrossInstX(name, Name, opClass, types, rCount, op,
56710037SARM gem5 Developers                          doubleDest=False, long=False):
56810037SARM gem5 Developers        global header_output, exec_output
56910037SARM gem5 Developers        destPrefix = "Big" if long else ""
57010037SARM gem5 Developers        eWalkCode = simd64EnabledCheckCode + '''
57110037SARM gem5 Developers        RegVect srcReg1;
57210037SARM gem5 Developers        %sRegVect destReg;
57310037SARM gem5 Developers        ''' % destPrefix
57410037SARM gem5 Developers        for reg in range(rCount):
57510037SARM gem5 Developers            eWalkCode += '''
57610037SARM gem5 Developers        srcReg1.regs[%(reg)d] = htog(AA64FpOp1P%(reg)d_uw);
57710037SARM gem5 Developers        ''' % { "reg" : reg }
57810037SARM gem5 Developers        eWalkCode += '''
57910037SARM gem5 Developers        destReg.regs[0] = 0;
58010037SARM gem5 Developers        %(destPrefix)sElement destElem = 0;
58110037SARM gem5 Developers        for (unsigned i = 0; i < eCount; i++) {
58210037SARM gem5 Developers            Element srcElem1 = gtoh(srcReg1.elements[i]);
58310037SARM gem5 Developers            if (i == 0) {
58410037SARM gem5 Developers                destElem = srcElem1;
58510037SARM gem5 Developers            } else {
58610037SARM gem5 Developers                %(op)s
58710037SARM gem5 Developers            }
58810037SARM gem5 Developers        }
58910037SARM gem5 Developers        destReg.elements[0] = htog(destElem);
59010037SARM gem5 Developers        ''' % { "op" : op, "destPrefix" : destPrefix }
59110037SARM gem5 Developers        destCnt = 2 if doubleDest else 1
59210037SARM gem5 Developers        for reg in range(destCnt):
59310037SARM gem5 Developers            eWalkCode += '''
59410037SARM gem5 Developers        AA64FpDestP%(reg)d_uw = gtoh(destReg.regs[%(reg)d]);
59510037SARM gem5 Developers        ''' % { "reg" : reg }
59610037SARM gem5 Developers        for reg in range(destCnt, 4):  # zero upper half
59710037SARM gem5 Developers            eWalkCode += '''
59810037SARM gem5 Developers        AA64FpDestP%(reg)d_uw = 0;
59910037SARM gem5 Developers        ''' % { "reg" : reg }
60010037SARM gem5 Developers        iop = InstObjParams(name, Name,
60110037SARM gem5 Developers                            "DataX1RegOp",
60210037SARM gem5 Developers                            { "code": eWalkCode,
60310037SARM gem5 Developers                              "r_count": rCount,
60410037SARM gem5 Developers                              "op_class": opClass }, [])
60510037SARM gem5 Developers        header_output += NeonX1RegOpDeclare.subst(iop)
60610037SARM gem5 Developers        if long:
60710037SARM gem5 Developers            exec_output += NeonXUnequalRegOpExecute.subst(iop)
60810037SARM gem5 Developers        else:
60910037SARM gem5 Developers            exec_output += NeonXEqualRegOpExecute.subst(iop)
61010037SARM gem5 Developers        for type in types:
61110037SARM gem5 Developers            substDict = { "targs" : type,
61210037SARM gem5 Developers                          "class_name" : Name }
61310037SARM gem5 Developers            exec_output += NeonXExecDeclare.subst(substDict)
61410037SARM gem5 Developers
61510037SARM gem5 Developers    def twoRegCondenseInstX(name, Name, opClass, types, rCount, op,
61610037SARM gem5 Developers                            readDest=False):
61710037SARM gem5 Developers        global header_output, exec_output
61810037SARM gem5 Developers        eWalkCode = simd64EnabledCheckCode + '''
61910037SARM gem5 Developers        RegVect srcRegs;
62010037SARM gem5 Developers        BigRegVect destReg;
62110037SARM gem5 Developers        '''
62210037SARM gem5 Developers        for reg in range(rCount):
62310037SARM gem5 Developers            eWalkCode += '''
62410037SARM gem5 Developers        srcRegs.regs[%(reg)d] = htog(AA64FpOp1P%(reg)d_uw);
62510037SARM gem5 Developers        ''' % { "reg" : reg }
62610037SARM gem5 Developers            if readDest:
62710037SARM gem5 Developers                eWalkCode += '''
62810037SARM gem5 Developers        destReg.regs[%(reg)d] = htog(AA64FpDestP%(reg)d_uw);
62910037SARM gem5 Developers        ''' % { "reg" : reg }
63010037SARM gem5 Developers        readDestCode = ''
63110037SARM gem5 Developers        if readDest:
63210037SARM gem5 Developers            readDestCode = 'destElem = gtoh(destReg.elements[i]);'
63310037SARM gem5 Developers        eWalkCode += '''
63410037SARM gem5 Developers        for (unsigned i = 0; i < eCount / 2; i++) {
63510037SARM gem5 Developers            Element srcElem1 = gtoh(srcRegs.elements[2 * i]);
63610037SARM gem5 Developers            Element srcElem2 = gtoh(srcRegs.elements[2 * i + 1]);
63710037SARM gem5 Developers            BigElement destElem;
63810037SARM gem5 Developers            %(readDest)s
63910037SARM gem5 Developers            %(op)s
64010037SARM gem5 Developers            destReg.elements[i] = htog(destElem);
64110037SARM gem5 Developers        }
64210037SARM gem5 Developers        ''' % { "op" : op, "readDest" : readDestCode }
64310037SARM gem5 Developers        for reg in range(rCount):
64410037SARM gem5 Developers            eWalkCode += '''
64510037SARM gem5 Developers        AA64FpDestP%(reg)d_uw = gtoh(destReg.regs[%(reg)d]);
64610037SARM gem5 Developers        ''' % { "reg" : reg }
64710037SARM gem5 Developers        if rCount < 4:  # zero upper half
64810037SARM gem5 Developers            for reg in range(rCount, 4):
64910037SARM gem5 Developers                eWalkCode += '''
65010037SARM gem5 Developers        AA64FpDestP%(reg)d_uw = 0;
65110037SARM gem5 Developers        ''' % { "reg" : reg }
65210037SARM gem5 Developers        iop = InstObjParams(name, Name,
65310037SARM gem5 Developers                            "DataX1RegOp",
65410037SARM gem5 Developers                            { "code": eWalkCode,
65510037SARM gem5 Developers                              "r_count": rCount,
65610037SARM gem5 Developers                              "op_class": opClass }, [])
65710037SARM gem5 Developers        header_output += NeonX1RegOpDeclare.subst(iop)
65810037SARM gem5 Developers        exec_output += NeonXUnequalRegOpExecute.subst(iop)
65910037SARM gem5 Developers        for type in types:
66010037SARM gem5 Developers            substDict = { "targs" : type,
66110037SARM gem5 Developers                          "class_name" : Name }
66210037SARM gem5 Developers            exec_output += NeonXExecDeclare.subst(substDict)
66310037SARM gem5 Developers
66410037SARM gem5 Developers    def oneRegImmInstX(name, Name, opClass, types, rCount, op, readDest=False):
66510037SARM gem5 Developers        global header_output, exec_output
66610037SARM gem5 Developers        eWalkCode = simd64EnabledCheckCode + '''
66710037SARM gem5 Developers        RegVect destReg;
66810037SARM gem5 Developers        '''
66910037SARM gem5 Developers        if readDest:
67010037SARM gem5 Developers            for reg in range(rCount):
67110037SARM gem5 Developers                eWalkCode += '''
67210037SARM gem5 Developers        destReg.regs[%(reg)d] = htog(AA64FpDestP%(reg)d_uw);
67310037SARM gem5 Developers        ''' % { "reg" : reg }
67410037SARM gem5 Developers        readDestCode = ''
67510037SARM gem5 Developers        if readDest:
67610037SARM gem5 Developers            readDestCode = 'destElem = gtoh(destReg.elements[i]);'
67710037SARM gem5 Developers        eWalkCode += '''
67810037SARM gem5 Developers        for (unsigned i = 0; i < eCount; i++) {
67910037SARM gem5 Developers            Element destElem;
68010037SARM gem5 Developers            %(readDest)s
68110037SARM gem5 Developers            %(op)s
68210037SARM gem5 Developers            destReg.elements[i] = htog(destElem);
68310037SARM gem5 Developers        }
68410037SARM gem5 Developers        ''' % { "op" : op, "readDest" : readDestCode }
68510037SARM gem5 Developers        for reg in range(rCount):
68610037SARM gem5 Developers            eWalkCode += '''
68710037SARM gem5 Developers        AA64FpDestP%(reg)d_uw = gtoh(destReg.regs[%(reg)d]);
68810037SARM gem5 Developers        ''' % { "reg" : reg }
68910037SARM gem5 Developers        if rCount < 4:  # zero upper half
69010037SARM gem5 Developers            for reg in range(rCount, 4):
69110037SARM gem5 Developers                eWalkCode += '''
69210037SARM gem5 Developers        AA64FpDestP%(reg)d_uw = 0;
69310037SARM gem5 Developers        ''' % { "reg" : reg }
69410037SARM gem5 Developers        iop = InstObjParams(name, Name,
69510037SARM gem5 Developers                            "DataXImmOnlyOp",
69610037SARM gem5 Developers                            { "code": eWalkCode,
69710037SARM gem5 Developers                              "r_count": rCount,
69810037SARM gem5 Developers                              "op_class": opClass }, [])
69910037SARM gem5 Developers        header_output += NeonX1RegImmOnlyOpDeclare.subst(iop)
70010037SARM gem5 Developers        exec_output += NeonXEqualRegOpExecute.subst(iop)
70110037SARM gem5 Developers        for type in types:
70210037SARM gem5 Developers            substDict = { "targs" : type,
70310037SARM gem5 Developers                          "class_name" : Name }
70410037SARM gem5 Developers            exec_output += NeonXExecDeclare.subst(substDict)
70510037SARM gem5 Developers
70610037SARM gem5 Developers    def dupGprInstX(name, Name, opClass, types, rCount, gprSpec):
70710037SARM gem5 Developers        global header_output, exec_output
70810037SARM gem5 Developers        eWalkCode = simd64EnabledCheckCode + '''
70910037SARM gem5 Developers        RegVect destReg;
71010037SARM gem5 Developers        for (unsigned i = 0; i < eCount; i++) {
71110037SARM gem5 Developers            destReg.elements[i] = htog((Element) %sOp1);
71210037SARM gem5 Developers        }
71310037SARM gem5 Developers        ''' % gprSpec
71410037SARM gem5 Developers        for reg in range(rCount):
71510037SARM gem5 Developers            eWalkCode += '''
71610037SARM gem5 Developers        AA64FpDestP%(reg)d_uw = gtoh(destReg.regs[%(reg)d]);
71710037SARM gem5 Developers        ''' % { "reg" : reg }
71810037SARM gem5 Developers        if rCount < 4:  # zero upper half
71910037SARM gem5 Developers            for reg in range(rCount, 4):
72010037SARM gem5 Developers                eWalkCode += '''
72110037SARM gem5 Developers        AA64FpDestP%(reg)d_uw = 0;
72210037SARM gem5 Developers        ''' % { "reg" : reg }
72310037SARM gem5 Developers        iop = InstObjParams(name, Name,
72410037SARM gem5 Developers                            "DataX1RegOp",
72510037SARM gem5 Developers                            { "code": eWalkCode,
72610037SARM gem5 Developers                              "r_count": rCount,
72710037SARM gem5 Developers                              "op_class": opClass }, [])
72810037SARM gem5 Developers        header_output += NeonX1RegOpDeclare.subst(iop)
72910037SARM gem5 Developers        exec_output += NeonXEqualRegOpExecute.subst(iop)
73010037SARM gem5 Developers        for type in types:
73110037SARM gem5 Developers            substDict = { "targs" : type,
73210037SARM gem5 Developers                          "class_name" : Name }
73310037SARM gem5 Developers            exec_output += NeonXExecDeclare.subst(substDict)
73410037SARM gem5 Developers
73510037SARM gem5 Developers    def extInstX(name, Name, opClass, types, rCount, op):
73610037SARM gem5 Developers        global header_output, exec_output
73710037SARM gem5 Developers        eWalkCode = simd64EnabledCheckCode + '''
73810037SARM gem5 Developers        RegVect srcReg1, srcReg2, destReg;
73910037SARM gem5 Developers        '''
74010037SARM gem5 Developers        for reg in range(rCount):
74110037SARM gem5 Developers            eWalkCode += '''
74210037SARM gem5 Developers        srcReg1.regs[%(reg)d] = htog(AA64FpOp1P%(reg)d_uw);
74310037SARM gem5 Developers        srcReg2.regs[%(reg)d] = htog(AA64FpOp2P%(reg)d_uw);
74410037SARM gem5 Developers        ''' % { "reg" : reg }
74510037SARM gem5 Developers        eWalkCode += op
74610037SARM gem5 Developers        for reg in range(rCount):
74710037SARM gem5 Developers            eWalkCode += '''
74810037SARM gem5 Developers        AA64FpDestP%(reg)d_uw = gtoh(destReg.regs[%(reg)d]);
74910037SARM gem5 Developers        ''' % { "reg" : reg }
75010037SARM gem5 Developers        if rCount < 4:  # zero upper half
75110037SARM gem5 Developers            for reg in range(rCount, 4):
75210037SARM gem5 Developers                eWalkCode += '''
75310037SARM gem5 Developers        AA64FpDestP%(reg)d_uw = 0;
75410037SARM gem5 Developers        ''' % { "reg" : reg }
75510037SARM gem5 Developers        iop = InstObjParams(name, Name,
75610037SARM gem5 Developers                            "DataX2RegImmOp",
75710037SARM gem5 Developers                            { "code": eWalkCode,
75810037SARM gem5 Developers                              "r_count": rCount,
75910037SARM gem5 Developers                              "op_class": opClass }, [])
76010037SARM gem5 Developers        header_output += NeonX2RegImmOpDeclare.subst(iop)
76110037SARM gem5 Developers        exec_output += NeonXEqualRegOpExecute.subst(iop)
76210037SARM gem5 Developers        for type in types:
76310037SARM gem5 Developers            substDict = { "targs" : type,
76410037SARM gem5 Developers                          "class_name" : Name }
76510037SARM gem5 Developers            exec_output += NeonXExecDeclare.subst(substDict)
76610037SARM gem5 Developers
76710037SARM gem5 Developers    def insFromGprInstX(name, Name, opClass, types, rCount, gprSpec):
76810037SARM gem5 Developers        global header_output, exec_output
76910037SARM gem5 Developers        eWalkCode = simd64EnabledCheckCode + '''
77010037SARM gem5 Developers        RegVect destReg;
77110037SARM gem5 Developers        '''
77210037SARM gem5 Developers        for reg in range(rCount):
77310037SARM gem5 Developers            eWalkCode += '''
77410037SARM gem5 Developers        destReg.regs[%(reg)d] = htog(AA64FpDestP%(reg)d_uw);
77510037SARM gem5 Developers        ''' % { "reg" : reg }
77610037SARM gem5 Developers        eWalkCode += '''
77710037SARM gem5 Developers        destReg.elements[imm] = htog((Element) %sOp1);
77810037SARM gem5 Developers        ''' % gprSpec
77910037SARM gem5 Developers        for reg in range(rCount):
78010037SARM gem5 Developers            eWalkCode += '''
78110037SARM gem5 Developers        AA64FpDestP%(reg)d_uw = gtoh(destReg.regs[%(reg)d]);
78210037SARM gem5 Developers        ''' % { "reg" : reg }
78310037SARM gem5 Developers        iop = InstObjParams(name, Name,
78410037SARM gem5 Developers                            "DataX1RegImmOp",
78510037SARM gem5 Developers                            { "code": eWalkCode,
78610037SARM gem5 Developers                              "r_count": rCount,
78710037SARM gem5 Developers                              "op_class": opClass }, [])
78810037SARM gem5 Developers        header_output += NeonX1RegImmOpDeclare.subst(iop)
78910037SARM gem5 Developers        exec_output += NeonXEqualRegOpExecute.subst(iop)
79010037SARM gem5 Developers        for type in types:
79110037SARM gem5 Developers            substDict = { "targs" : type,
79210037SARM gem5 Developers                          "class_name" : Name }
79310037SARM gem5 Developers            exec_output += NeonXExecDeclare.subst(substDict)
79410037SARM gem5 Developers
79510037SARM gem5 Developers    def insToGprInstX(name, Name, opClass, types, rCount, gprSpec,
79610037SARM gem5 Developers                      signExt=False):
79710037SARM gem5 Developers        global header_output, exec_output
79810037SARM gem5 Developers        eWalkCode = simd64EnabledCheckCode + '''
79910037SARM gem5 Developers        FullRegVect srcReg;
80010037SARM gem5 Developers        '''
80110037SARM gem5 Developers        for reg in range(4):
80210037SARM gem5 Developers            eWalkCode += '''
80310037SARM gem5 Developers        srcReg.regs[%(reg)d] = htog(AA64FpOp1P%(reg)d_uw);
80410037SARM gem5 Developers        ''' % { "reg" : reg }
80510037SARM gem5 Developers        if signExt:
80610037SARM gem5 Developers            eWalkCode += '''
80710037SARM gem5 Developers        %sDest = sext<sizeof(Element) * 8>(srcReg.elements[imm]);
80810037SARM gem5 Developers        ''' % gprSpec
80910037SARM gem5 Developers        else:
81010037SARM gem5 Developers            eWalkCode += '''
81110037SARM gem5 Developers        %sDest = srcReg.elements[imm];
81210037SARM gem5 Developers        ''' % gprSpec
81310037SARM gem5 Developers        iop = InstObjParams(name, Name,
81410037SARM gem5 Developers                            "DataX1RegImmOp",
81510037SARM gem5 Developers                            { "code": eWalkCode,
81610037SARM gem5 Developers                              "r_count": rCount,
81710037SARM gem5 Developers                              "op_class": opClass }, [])
81810037SARM gem5 Developers        header_output += NeonX1RegImmOpDeclare.subst(iop)
81910037SARM gem5 Developers        exec_output += NeonXEqualRegOpExecute.subst(iop)
82010037SARM gem5 Developers        for type in types:
82110037SARM gem5 Developers            substDict = { "targs" : type,
82210037SARM gem5 Developers                          "class_name" : Name }
82310037SARM gem5 Developers            exec_output += NeonXExecDeclare.subst(substDict)
82410037SARM gem5 Developers
82510037SARM gem5 Developers    def tbxTblInstX(name, Name, opClass, types, length, isTbl, rCount):
82610037SARM gem5 Developers        global header_output, decoder_output, exec_output
82710037SARM gem5 Developers        code = simd64EnabledCheckCode + '''
82810037SARM gem5 Developers        union
82910037SARM gem5 Developers        {
83010037SARM gem5 Developers            uint8_t bytes[64];
83110037SARM gem5 Developers            FloatRegBits regs[16];
83210037SARM gem5 Developers        } table;
83310037SARM gem5 Developers
83410037SARM gem5 Developers        union
83510037SARM gem5 Developers        {
83610037SARM gem5 Developers            uint8_t bytes[%(rCount)d * 4];
83710037SARM gem5 Developers            FloatRegBits regs[%(rCount)d];
83810037SARM gem5 Developers        } destReg, srcReg2;
83910037SARM gem5 Developers
84010037SARM gem5 Developers        const unsigned length = %(length)d;
84110037SARM gem5 Developers        const bool isTbl = %(isTbl)s;
84210037SARM gem5 Developers        ''' % { "rCount" : rCount, "length" : length, "isTbl" : isTbl }
84310037SARM gem5 Developers        for reg in range(rCount):
84410037SARM gem5 Developers            code += '''
84510037SARM gem5 Developers        srcReg2.regs[%(reg)d] = htog(AA64FpOp2P%(reg)d_uw);
84610037SARM gem5 Developers        destReg.regs[%(reg)d] = htog(AA64FpDestP%(reg)d_uw);
84710037SARM gem5 Developers        ''' % { "reg" : reg }
84810037SARM gem5 Developers        for reg in range(16):
84910037SARM gem5 Developers            if reg < length * 4:
85010037SARM gem5 Developers                code += '''
85110037SARM gem5 Developers        table.regs[%(reg)d] = htog(AA64FpOp1P%(p)dV%(v)dS_uw);
85210037SARM gem5 Developers        ''' % { "reg" : reg, "p" : reg % 4, "v" : reg / 4 }
85310037SARM gem5 Developers            else:
85410037SARM gem5 Developers                code += '''
85510037SARM gem5 Developers        table.regs[%(reg)d] = 0;
85610037SARM gem5 Developers        ''' % { "reg" : reg }
85710037SARM gem5 Developers        code += '''
85810037SARM gem5 Developers        for (unsigned i = 0; i < sizeof(destReg); i++) {
85910037SARM gem5 Developers            uint8_t index = srcReg2.bytes[i];
86010037SARM gem5 Developers            if (index < 16 * length) {
86110037SARM gem5 Developers                destReg.bytes[i] = table.bytes[index];
86210037SARM gem5 Developers            } else {
86310037SARM gem5 Developers                if (isTbl)
86410037SARM gem5 Developers                    destReg.bytes[i] = 0;
86510037SARM gem5 Developers                // else destReg.bytes[i] unchanged
86610037SARM gem5 Developers            }
86710037SARM gem5 Developers        }
86810037SARM gem5 Developers        '''
86910037SARM gem5 Developers        for reg in range(rCount):
87010037SARM gem5 Developers            code += '''
87110037SARM gem5 Developers        AA64FpDestP%(reg)d_uw = gtoh(destReg.regs[%(reg)d]);
87210037SARM gem5 Developers        ''' % { "reg" : reg }
87310037SARM gem5 Developers        if rCount < 4:  # zero upper half
87410037SARM gem5 Developers            for reg in range(rCount, 4):
87510037SARM gem5 Developers                code += '''
87610037SARM gem5 Developers        AA64FpDestP%(reg)d_uw = 0;
87710037SARM gem5 Developers        ''' % { "reg" : reg }
87810037SARM gem5 Developers        iop = InstObjParams(name, Name,
87910037SARM gem5 Developers                            "DataX2RegOp",
88010037SARM gem5 Developers                            { "code": code,
88110037SARM gem5 Developers                              "r_count": rCount,
88210037SARM gem5 Developers                              "op_class": opClass }, [])
88310037SARM gem5 Developers        header_output += NeonX2RegOpDeclare.subst(iop)
88410037SARM gem5 Developers        exec_output += NeonXEqualRegOpExecute.subst(iop)
88510037SARM gem5 Developers        for type in types:
88610037SARM gem5 Developers            substDict = { "targs" : type,
88710037SARM gem5 Developers                          "class_name" : Name }
88810037SARM gem5 Developers            exec_output += NeonXExecDeclare.subst(substDict)
88910037SARM gem5 Developers
89010037SARM gem5 Developers    # ABS
89110037SARM gem5 Developers    absCode = '''
89210037SARM gem5 Developers            if (srcElem1 < 0) {
89310037SARM gem5 Developers                destElem = -srcElem1;
89410037SARM gem5 Developers            } else {
89510037SARM gem5 Developers                destElem = srcElem1;
89610037SARM gem5 Developers            }
89710037SARM gem5 Developers    '''
89810037SARM gem5 Developers    twoEqualRegInstX("abs", "AbsDX", "SimdAluOp", signedTypes, 2, absCode)
89910037SARM gem5 Developers    twoEqualRegInstX("abs", "AbsQX", "SimdAluOp", signedTypes, 4, absCode)
90010037SARM gem5 Developers    # ADD
90110037SARM gem5 Developers    addCode = "destElem = srcElem1 + srcElem2;"
90210037SARM gem5 Developers    threeEqualRegInstX("add", "AddDX", "SimdAddOp", unsignedTypes, 2, addCode)
90310037SARM gem5 Developers    threeEqualRegInstX("add", "AddQX", "SimdAddOp", unsignedTypes, 4, addCode)
90410037SARM gem5 Developers    # ADDHN, ADDHN2
90510037SARM gem5 Developers    addhnCode = '''
90610037SARM gem5 Developers            destElem = ((BigElement)srcElem1 + (BigElement)srcElem2) >>
90710037SARM gem5 Developers                        (sizeof(Element) * 8);
90810037SARM gem5 Developers    '''
90910037SARM gem5 Developers    threeRegNarrowInstX("addhn", "AddhnX", "SimdAddOp", smallUnsignedTypes,
91010037SARM gem5 Developers                        addhnCode)
91110037SARM gem5 Developers    threeRegNarrowInstX("addhn2", "Addhn2X", "SimdAddOp", smallUnsignedTypes,
91210037SARM gem5 Developers                        addhnCode, hi=True)
91310037SARM gem5 Developers    # ADDP (scalar)
91410037SARM gem5 Developers    twoRegPairwiseScInstX("addp", "AddpScQX", "SimdAddOp", ("uint64_t",), 4,
91510037SARM gem5 Developers                          addCode)
91610037SARM gem5 Developers    # ADDP (vector)
91710037SARM gem5 Developers    threeEqualRegInstX("addp", "AddpDX", "SimdAddOp", smallUnsignedTypes, 2,
91810037SARM gem5 Developers                       addCode, pairwise=True)
91910037SARM gem5 Developers    threeEqualRegInstX("addp", "AddpQX", "SimdAddOp", unsignedTypes, 4,
92010037SARM gem5 Developers                       addCode, pairwise=True)
92110037SARM gem5 Developers    # ADDV
92210037SARM gem5 Developers    # Note: SimdAddOp can be a bit optimistic here
92310037SARM gem5 Developers    addAcrossCode = "destElem += srcElem1;"
92410037SARM gem5 Developers    twoRegAcrossInstX("addv", "AddvDX", "SimdAddOp", ("uint8_t", "uint16_t"),
92510037SARM gem5 Developers                      2, addAcrossCode)
92610037SARM gem5 Developers    twoRegAcrossInstX("addv", "AddvQX", "SimdAddOp", smallUnsignedTypes, 4,
92710037SARM gem5 Developers                      addAcrossCode)
92810037SARM gem5 Developers    # AND
92910037SARM gem5 Developers    andCode = "destElem = srcElem1 & srcElem2;"
93010037SARM gem5 Developers    threeEqualRegInstX("and", "AndDX", "SimdAluOp", ("uint64_t",), 2, andCode)
93110037SARM gem5 Developers    threeEqualRegInstX("and", "AndQX", "SimdAluOp", ("uint64_t",), 4, andCode)
93210037SARM gem5 Developers    # BIC (immediate)
93310037SARM gem5 Developers    bicImmCode = "destElem &= ~imm;"
93410037SARM gem5 Developers    oneRegImmInstX("bic", "BicImmDX", "SimdAluOp", ("uint64_t",), 2,
93510037SARM gem5 Developers                   bicImmCode, True)
93610037SARM gem5 Developers    oneRegImmInstX("bic", "BicImmQX", "SimdAluOp", ("uint64_t",), 4,
93710037SARM gem5 Developers                   bicImmCode, True)
93810037SARM gem5 Developers    # BIC (register)
93910037SARM gem5 Developers    bicCode = "destElem = srcElem1 & ~srcElem2;"
94010037SARM gem5 Developers    threeEqualRegInstX("bic", "BicDX", "SimdAluOp", ("uint64_t",), 2, bicCode)
94110037SARM gem5 Developers    threeEqualRegInstX("bic", "BicQX", "SimdAluOp", ("uint64_t",), 4, bicCode)
94210037SARM gem5 Developers    # BIF
94310037SARM gem5 Developers    bifCode = "destElem = (destElem & srcElem2) | (srcElem1 & ~srcElem2);"
94410037SARM gem5 Developers    threeEqualRegInstX("bif", "BifDX", "SimdAluOp", ("uint64_t",), 2, bifCode,
94510037SARM gem5 Developers                       True)
94610037SARM gem5 Developers    threeEqualRegInstX("bif", "BifQX", "SimdAluOp", ("uint64_t",), 4, bifCode,
94710037SARM gem5 Developers                       True)
94810037SARM gem5 Developers    # BIT
94910037SARM gem5 Developers    bitCode = "destElem = (srcElem1 & srcElem2) | (destElem & ~srcElem2);"
95010037SARM gem5 Developers    threeEqualRegInstX("bit", "BitDX", "SimdAluOp", ("uint64_t",), 2, bitCode,
95110037SARM gem5 Developers                       True)
95210037SARM gem5 Developers    threeEqualRegInstX("bit", "BitQX", "SimdAluOp", ("uint64_t",), 4, bitCode,
95310037SARM gem5 Developers                       True)
95410037SARM gem5 Developers    # BSL
95510037SARM gem5 Developers    bslCode = "destElem = (srcElem1 & destElem) | (srcElem2 & ~destElem);"
95610037SARM gem5 Developers    threeEqualRegInstX("bsl", "BslDX", "SimdAluOp", ("uint64_t",), 2, bslCode,
95710037SARM gem5 Developers                       True)
95810037SARM gem5 Developers    threeEqualRegInstX("bsl", "BslQX", "SimdAluOp", ("uint64_t",), 4, bslCode,
95910037SARM gem5 Developers                       True)
96010037SARM gem5 Developers    # CLS
96110037SARM gem5 Developers    clsCode = '''
96210037SARM gem5 Developers            unsigned count = 0;
96310037SARM gem5 Developers            if (srcElem1 < 0) {
96410037SARM gem5 Developers                srcElem1 <<= 1;
96510037SARM gem5 Developers                while (srcElem1 < 0 && count < sizeof(Element) * 8 - 1) {
96610037SARM gem5 Developers                    count++;
96710037SARM gem5 Developers                    srcElem1 <<= 1;
96810037SARM gem5 Developers                }
96910037SARM gem5 Developers            } else {
97010037SARM gem5 Developers                srcElem1 <<= 1;
97110037SARM gem5 Developers                while (srcElem1 >= 0 && count < sizeof(Element) * 8 - 1) {
97210037SARM gem5 Developers                    count++;
97310037SARM gem5 Developers                    srcElem1 <<= 1;
97410037SARM gem5 Developers                }
97510037SARM gem5 Developers            }
97610037SARM gem5 Developers            destElem = count;
97710037SARM gem5 Developers    '''
97810037SARM gem5 Developers    twoEqualRegInstX("cls", "ClsDX", "SimdAluOp", smallSignedTypes, 2, clsCode)
97910037SARM gem5 Developers    twoEqualRegInstX("cls", "ClsQX", "SimdAluOp", smallSignedTypes, 4, clsCode)
98010037SARM gem5 Developers    # CLZ
98110037SARM gem5 Developers    clzCode = '''
98210037SARM gem5 Developers            unsigned count = 0;
98310037SARM gem5 Developers            while (srcElem1 >= 0 && count < sizeof(Element) * 8) {
98410037SARM gem5 Developers                count++;
98510037SARM gem5 Developers                srcElem1 <<= 1;
98610037SARM gem5 Developers            }
98710037SARM gem5 Developers            destElem = count;
98810037SARM gem5 Developers    '''
98910037SARM gem5 Developers    twoEqualRegInstX("clz", "ClzDX", "SimdAluOp", smallSignedTypes, 2, clzCode)
99010037SARM gem5 Developers    twoEqualRegInstX("clz", "ClzQX", "SimdAluOp", smallSignedTypes, 4, clzCode)
99110037SARM gem5 Developers    # CMEQ (register)
99210037SARM gem5 Developers    cmeqCode = "destElem = (srcElem1 == srcElem2) ? (Element)(-1) : 0;"
99310037SARM gem5 Developers    threeEqualRegInstX("cmeq", "CmeqDX", "SimdCmpOp", unsignedTypes, 2,
99410037SARM gem5 Developers                       cmeqCode)
99510037SARM gem5 Developers    threeEqualRegInstX("cmeq", "CmeqQX", "SimdCmpOp", unsignedTypes, 4,
99610037SARM gem5 Developers                       cmeqCode)
99710037SARM gem5 Developers    # CMEQ (zero)
99810037SARM gem5 Developers    cmeqZeroCode = "destElem = (srcElem1 == 0) ? (Element)(-1) : 0;"
99910037SARM gem5 Developers    twoEqualRegInstX("cmeq", "CmeqZeroDX", "SimdCmpOp", signedTypes, 2,
100010037SARM gem5 Developers                     cmeqZeroCode)
100110037SARM gem5 Developers    twoEqualRegInstX("cmeq", "CmeqZeroQX", "SimdCmpOp", signedTypes, 4,
100210037SARM gem5 Developers                     cmeqZeroCode)
100310037SARM gem5 Developers    # CMGE (register)
100410037SARM gem5 Developers    cmgeCode = "destElem = (srcElem1 >= srcElem2) ? (Element)(-1) : 0;"
100510037SARM gem5 Developers    threeEqualRegInstX("cmge", "CmgeDX", "SimdCmpOp", signedTypes, 2, cmgeCode)
100610037SARM gem5 Developers    threeEqualRegInstX("cmge", "CmgeQX", "SimdCmpOp", signedTypes, 4, cmgeCode)
100710037SARM gem5 Developers    # CMGE (zero)
100810037SARM gem5 Developers    cmgeZeroCode = "destElem = (srcElem1 >= 0) ? (Element)(-1) : 0;"
100910037SARM gem5 Developers    twoEqualRegInstX("cmge", "CmgeZeroDX", "SimdCmpOp", signedTypes, 2,
101010037SARM gem5 Developers                     cmgeZeroCode)
101110037SARM gem5 Developers    twoEqualRegInstX("cmge", "CmgeZeroQX", "SimdCmpOp", signedTypes, 4,
101210037SARM gem5 Developers                     cmgeZeroCode)
101310037SARM gem5 Developers    # CMGT (register)
101410037SARM gem5 Developers    cmgtCode = "destElem = (srcElem1 > srcElem2) ? (Element)(-1) : 0;"
101510037SARM gem5 Developers    threeEqualRegInstX("cmgt", "CmgtDX", "SimdCmpOp", signedTypes, 2, cmgtCode)
101610037SARM gem5 Developers    threeEqualRegInstX("cmgt", "CmgtQX", "SimdCmpOp", signedTypes, 4, cmgtCode)
101710037SARM gem5 Developers    # CMGT (zero)
101810037SARM gem5 Developers    cmgtZeroCode = "destElem = (srcElem1 > 0) ? (Element)(-1) : 0;"
101910037SARM gem5 Developers    twoEqualRegInstX("cmgt", "CmgtZeroDX", "SimdCmpOp", signedTypes, 2,
102010037SARM gem5 Developers                     cmgtZeroCode)
102110037SARM gem5 Developers    twoEqualRegInstX("cmgt", "CmgtZeroQX", "SimdCmpOp", signedTypes, 4,
102210037SARM gem5 Developers                     cmgtZeroCode)
102310037SARM gem5 Developers    # CMHI (register)
102410037SARM gem5 Developers    threeEqualRegInstX("cmhi", "CmhiDX", "SimdCmpOp", unsignedTypes, 2,
102510037SARM gem5 Developers                       cmgtCode)
102610037SARM gem5 Developers    threeEqualRegInstX("cmhi", "CmhiQX", "SimdCmpOp", unsignedTypes, 4,
102710037SARM gem5 Developers                       cmgtCode)
102810037SARM gem5 Developers    # CMHS (register)
102910037SARM gem5 Developers    threeEqualRegInstX("cmhs", "CmhsDX", "SimdCmpOp", unsignedTypes, 2,
103010037SARM gem5 Developers                       cmgeCode)
103110037SARM gem5 Developers    threeEqualRegInstX("cmhs", "CmhsQX", "SimdCmpOp", unsignedTypes, 4,
103210037SARM gem5 Developers                       cmgeCode)
103310037SARM gem5 Developers    # CMLE (zero)
103410037SARM gem5 Developers    cmleZeroCode = "destElem = (srcElem1 <= 0) ? (Element)(-1) : 0;"
103510037SARM gem5 Developers    twoEqualRegInstX("cmle", "CmleZeroDX", "SimdCmpOp", signedTypes, 2,
103610037SARM gem5 Developers                     cmleZeroCode)
103710037SARM gem5 Developers    twoEqualRegInstX("cmle", "CmleZeroQX", "SimdCmpOp", signedTypes, 4,
103810037SARM gem5 Developers                     cmleZeroCode)
103910037SARM gem5 Developers    # CMLT (zero)
104010037SARM gem5 Developers    cmltZeroCode = "destElem = (srcElem1 < 0) ? (Element)(-1) : 0;"
104110037SARM gem5 Developers    twoEqualRegInstX("cmlt", "CmltZeroDX", "SimdCmpOp", signedTypes, 2,
104210037SARM gem5 Developers                     cmltZeroCode)
104310037SARM gem5 Developers    twoEqualRegInstX("cmlt", "CmltZeroQX", "SimdCmpOp", signedTypes, 4,
104410037SARM gem5 Developers                     cmltZeroCode)
104510037SARM gem5 Developers    # CMTST (register)
104610037SARM gem5 Developers    tstCode = "destElem = (srcElem1 & srcElem2) ? (Element)(-1) : 0;"
104710037SARM gem5 Developers    threeEqualRegInstX("cmtst", "CmtstDX", "SimdAluOp", unsignedTypes, 2,
104810037SARM gem5 Developers                       tstCode)
104910037SARM gem5 Developers    threeEqualRegInstX("cmtst", "CmtstQX", "SimdAluOp", unsignedTypes, 4,
105010037SARM gem5 Developers                       tstCode)
105110037SARM gem5 Developers    # CNT
105210037SARM gem5 Developers    cntCode = '''
105310037SARM gem5 Developers            unsigned count = 0;
105410037SARM gem5 Developers            while (srcElem1 && count < sizeof(Element) * 8) {
105510037SARM gem5 Developers                count += srcElem1 & 0x1;
105610037SARM gem5 Developers                srcElem1 >>= 1;
105710037SARM gem5 Developers            }
105810037SARM gem5 Developers            destElem = count;
105910037SARM gem5 Developers    '''
106010037SARM gem5 Developers    twoEqualRegInstX("cnt", "CntDX", "SimdAluOp", ("uint8_t",), 2, cntCode)
106110037SARM gem5 Developers    twoEqualRegInstX("cnt", "CntQX", "SimdAluOp", ("uint8_t",), 4, cntCode)
106210037SARM gem5 Developers    # DUP (element)
106310037SARM gem5 Developers    dupCode = "destElem = srcElem1;"
106410037SARM gem5 Developers    twoEqualRegInstX("dup", "DupElemDX", "SimdMiscOp", smallUnsignedTypes, 2,
106510037SARM gem5 Developers                     dupCode, isDup=True, byElem=True)
106610037SARM gem5 Developers    twoEqualRegInstX("dup", "DupElemQX", "SimdMiscOp", unsignedTypes, 4,
106710037SARM gem5 Developers                     dupCode, isDup=True, byElem=True)
106810037SARM gem5 Developers    twoEqualRegInstX("dup", "DupElemScX", "SimdMiscOp", unsignedTypes, 4,
106910037SARM gem5 Developers                     dupCode, isDup=True, byElem=True, scalar=True)
107010037SARM gem5 Developers    # DUP (general register)
107110037SARM gem5 Developers    dupGprInstX("dup", "DupGprWDX", "SimdMiscOp", smallUnsignedTypes, 2, 'W')
107210037SARM gem5 Developers    dupGprInstX("dup", "DupGprWQX", "SimdMiscOp", smallUnsignedTypes, 4, 'W')
107310037SARM gem5 Developers    dupGprInstX("dup", "DupGprXQX", "SimdMiscOp", ("uint64_t",), 4, 'X')
107410037SARM gem5 Developers    # EOR
107510037SARM gem5 Developers    eorCode = "destElem = srcElem1 ^ srcElem2;"
107610037SARM gem5 Developers    threeEqualRegInstX("eor", "EorDX", "SimdAluOp", ("uint64_t",), 2, eorCode)
107710037SARM gem5 Developers    threeEqualRegInstX("eor", "EorQX", "SimdAluOp", ("uint64_t",), 4, eorCode)
107810037SARM gem5 Developers    # EXT
107910037SARM gem5 Developers    extCode = '''
108010037SARM gem5 Developers            for (unsigned i = 0; i < eCount; i++) {
108110037SARM gem5 Developers                unsigned index = i + imm;
108210037SARM gem5 Developers                if (index < eCount) {
108310037SARM gem5 Developers                    destReg.elements[i] = srcReg1.elements[index];
108410037SARM gem5 Developers                } else {
108510037SARM gem5 Developers                    index -= eCount;
108610037SARM gem5 Developers                    if (index >= eCount) {
108710474Sandreas.hansson@arm.com                        fault = std::make_shared<UndefinedInstruction>(
108810474Sandreas.hansson@arm.com                                      machInst, false, mnemonic);
108910037SARM gem5 Developers                    } else {
109010037SARM gem5 Developers                        destReg.elements[i] = srcReg2.elements[index];
109110037SARM gem5 Developers                    }
109210037SARM gem5 Developers                }
109310037SARM gem5 Developers            }
109410037SARM gem5 Developers    '''
109510037SARM gem5 Developers    extInstX("Ext", "ExtDX", "SimdMiscOp", ("uint8_t",), 2, extCode)
109610037SARM gem5 Developers    extInstX("Ext", "ExtQX", "SimdMiscOp", ("uint8_t",), 4, extCode)
109710037SARM gem5 Developers    # FABD
109810037SARM gem5 Developers    fpOp = '''
109910037SARM gem5 Developers            FPSCR fpscr = (FPSCR) FpscrExc;
110010037SARM gem5 Developers            destElem = %s;
110110037SARM gem5 Developers            FpscrExc = fpscr;
110210037SARM gem5 Developers    '''
110310037SARM gem5 Developers    fabdCode = fpOp % "fplibAbs<Element>(fplibSub(srcElem1, srcElem2, fpscr))"
110410037SARM gem5 Developers    threeEqualRegInstX("fabd", "FabdDX", "SimdFloatAddOp", smallFloatTypes, 2,
110510037SARM gem5 Developers                       fabdCode)
110610037SARM gem5 Developers    threeEqualRegInstX("fabd", "FabdQX", "SimdFloatAddOp", floatTypes, 4,
110710037SARM gem5 Developers                       fabdCode)
110810037SARM gem5 Developers    threeEqualRegInstX("fabd", "FabdScX", "SimdFloatAddOp", floatTypes, 4,
110910037SARM gem5 Developers                       fabdCode, scalar=True)
111010037SARM gem5 Developers    # FABS
111110037SARM gem5 Developers    fabsCode = fpOp % "fplibAbs<Element>(srcElem1)"
111210037SARM gem5 Developers    twoEqualRegInstX("Abs", "FabsDX", "SimdFloatAluOp", smallFloatTypes, 2,
111310037SARM gem5 Developers                     fabsCode)
111410037SARM gem5 Developers    twoEqualRegInstX("Abs", "FabsQX", "SimdFloatAluOp", floatTypes, 4,
111510037SARM gem5 Developers                     fabsCode)
111610037SARM gem5 Developers    # FACGE
111710037SARM gem5 Developers    fpCmpAbsOp = fpOp % ("fplibCompare%s<Element>(fplibAbs<Element>(srcElem1),"
111810037SARM gem5 Developers                         " fplibAbs<Element>(srcElem2), fpscr) ? -1 : 0")
111910037SARM gem5 Developers    facgeCode = fpCmpAbsOp % "GE"
112010037SARM gem5 Developers    threeEqualRegInstX("facge", "FacgeDX", "SimdFloatCmpOp", smallFloatTypes,
112110037SARM gem5 Developers                       2, facgeCode)
112210037SARM gem5 Developers    threeEqualRegInstX("facge", "FacgeQX", "SimdFloatCmpOp", floatTypes, 4,
112310037SARM gem5 Developers                       facgeCode)
112410037SARM gem5 Developers    threeEqualRegInstX("facge", "FacgeScX", "SimdFloatCmpOp", floatTypes, 4,
112510037SARM gem5 Developers                       facgeCode, scalar=True)
112610037SARM gem5 Developers    # FACGT
112710037SARM gem5 Developers    facgtCode = fpCmpAbsOp % "GT"
112810037SARM gem5 Developers    threeEqualRegInstX("facgt", "FacgtDX", "SimdFloatCmpOp", smallFloatTypes,
112910037SARM gem5 Developers                       2, facgtCode)
113010037SARM gem5 Developers    threeEqualRegInstX("facgt", "FacgtQX", "SimdFloatCmpOp", floatTypes, 4,
113110037SARM gem5 Developers                       facgtCode)
113210037SARM gem5 Developers    threeEqualRegInstX("facgt", "FacgtScX", "SimdFloatCmpOp", floatTypes, 4,
113310037SARM gem5 Developers                       facgtCode, scalar=True)
113410037SARM gem5 Developers    # FADD
113510037SARM gem5 Developers    fpBinOp = fpOp % "fplib%s<Element>(srcElem1, srcElem2, fpscr)"
113610037SARM gem5 Developers    faddCode = fpBinOp % "Add"
113710037SARM gem5 Developers    threeEqualRegInstX("fadd", "FaddDX", "SimdFloatAddOp", smallFloatTypes, 2,
113810037SARM gem5 Developers                       faddCode)
113910037SARM gem5 Developers    threeEqualRegInstX("fadd", "FaddQX", "SimdFloatAddOp", floatTypes, 4,
114010037SARM gem5 Developers                       faddCode)
114110037SARM gem5 Developers    # FADDP (scalar)
114210037SARM gem5 Developers    twoRegPairwiseScInstX("faddp", "FaddpScDX", "SimdFloatAddOp",
114310037SARM gem5 Developers                          ("uint32_t",), 2, faddCode)
114410037SARM gem5 Developers    twoRegPairwiseScInstX("faddp", "FaddpScQX", "SimdFloatAddOp",
114510037SARM gem5 Developers                          ("uint64_t",), 4, faddCode)
114610037SARM gem5 Developers    # FADDP (vector)
114710037SARM gem5 Developers    threeEqualRegInstX("faddp", "FaddpDX", "SimdFloatAddOp", smallFloatTypes,
114810037SARM gem5 Developers                       2, faddCode, pairwise=True)
114910037SARM gem5 Developers    threeEqualRegInstX("faddp", "FaddpQX", "SimdFloatAddOp", floatTypes, 4,
115010037SARM gem5 Developers                       faddCode, pairwise=True)
115110037SARM gem5 Developers    # FCMEQ (register)
115210037SARM gem5 Developers    fpCmpOp = fpOp % ("fplibCompare%s<Element>(srcElem1, srcElem2, fpscr) ?"
115310037SARM gem5 Developers                      " -1 : 0")
115410037SARM gem5 Developers    fcmeqCode = fpCmpOp % "EQ"
115510037SARM gem5 Developers    threeEqualRegInstX("fcmeq", "FcmeqDX", "SimdFloatCmpOp", smallFloatTypes,
115610037SARM gem5 Developers                       2, fcmeqCode)
115710037SARM gem5 Developers    threeEqualRegInstX("fcmeq", "FcmeqQX", "SimdFloatCmpOp", floatTypes, 4,
115810037SARM gem5 Developers                       fcmeqCode)
115910037SARM gem5 Developers    threeEqualRegInstX("fcmeq", "FcmeqScX", "SimdFloatCmpOp", floatTypes, 4,
116010037SARM gem5 Developers                       fcmeqCode, scalar=True)
116110037SARM gem5 Developers    # FCMEQ (zero)
116210037SARM gem5 Developers    fpCmpZeroOp = fpOp % "fplibCompare%s<Element>(srcElem1, 0, fpscr) ? -1 : 0"
116310037SARM gem5 Developers    fcmeqZeroCode = fpCmpZeroOp % "EQ"
116410037SARM gem5 Developers    twoEqualRegInstX("fcmeq", "FcmeqZeroDX", "SimdFloatCmpOp", smallFloatTypes,
116510037SARM gem5 Developers                     2, fcmeqZeroCode)
116610037SARM gem5 Developers    twoEqualRegInstX("fcmeq", "FcmeqZeroQX", "SimdFloatCmpOp", floatTypes, 4,
116710037SARM gem5 Developers                     fcmeqZeroCode)
116810037SARM gem5 Developers    twoEqualRegInstX("fcmeq", "FcmeqZeroScX", "SimdFloatCmpOp", floatTypes, 4,
116910037SARM gem5 Developers                     fcmeqZeroCode, scalar=True)
117010037SARM gem5 Developers    # FCMGE (register)
117110037SARM gem5 Developers    fcmgeCode = fpCmpOp % "GE"
117210037SARM gem5 Developers    threeEqualRegInstX("fcmge", "FcmgeDX", "SimdFloatCmpOp", smallFloatTypes,
117310037SARM gem5 Developers                       2, fcmgeCode)
117410037SARM gem5 Developers    threeEqualRegInstX("fcmge", "FcmgeQX", "SimdFloatCmpOp", floatTypes, 4,
117510037SARM gem5 Developers                       fcmgeCode)
117610037SARM gem5 Developers    threeEqualRegInstX("fcmge", "FcmgeScX", "SimdFloatCmpOp", floatTypes, 4,
117710037SARM gem5 Developers                       fcmgeCode, scalar=True)
117810037SARM gem5 Developers    # FCMGE (zero)
117910037SARM gem5 Developers    fcmgeZeroCode = fpCmpZeroOp % "GE"
118010037SARM gem5 Developers    twoEqualRegInstX("fcmge", "FcmgeZeroDX", "SimdFloatCmpOp", smallFloatTypes,
118110037SARM gem5 Developers                     2, fcmgeZeroCode)
118210037SARM gem5 Developers    twoEqualRegInstX("fcmge", "FcmgeZeroQX", "SimdFloatCmpOp", floatTypes, 4,
118310037SARM gem5 Developers                     fcmgeZeroCode)
118410037SARM gem5 Developers    twoEqualRegInstX("fcmge", "FcmgeZeroScX", "SimdFloatCmpOp", floatTypes, 4,
118510037SARM gem5 Developers                     fcmgeZeroCode, scalar=True)
118610037SARM gem5 Developers    # FCMGT (register)
118710037SARM gem5 Developers    fcmgtCode = fpCmpOp % "GT"
118810037SARM gem5 Developers    threeEqualRegInstX("fcmgt", "FcmgtDX", "SimdFloatCmpOp", smallFloatTypes,
118910037SARM gem5 Developers                       2, fcmgtCode)
119010037SARM gem5 Developers    threeEqualRegInstX("fcmgt", "FcmgtQX", "SimdFloatCmpOp", floatTypes, 4,
119110037SARM gem5 Developers                       fcmgtCode)
119210037SARM gem5 Developers    threeEqualRegInstX("fcmgt", "FcmgtScX", "SimdFloatCmpOp", floatTypes, 4,
119310037SARM gem5 Developers                       fcmgtCode, scalar=True)
119410037SARM gem5 Developers    # FCMGT (zero)
119510037SARM gem5 Developers    fcmgtZeroCode = fpCmpZeroOp % "GT"
119610037SARM gem5 Developers    twoEqualRegInstX("fcmgt", "FcmgtZeroDX", "SimdFloatCmpOp", smallFloatTypes,
119710037SARM gem5 Developers                     2, fcmgtZeroCode)
119810037SARM gem5 Developers    twoEqualRegInstX("fcmgt", "FcmgtZeroQX", "SimdFloatCmpOp", floatTypes, 4,
119910037SARM gem5 Developers                     fcmgtZeroCode)
120010037SARM gem5 Developers    twoEqualRegInstX("fcmgt", "FcmgtZeroScX", "SimdFloatCmpOp", floatTypes, 4,
120110037SARM gem5 Developers                     fcmgtZeroCode, scalar=True)
120210037SARM gem5 Developers    # FCMLE (zero)
120310037SARM gem5 Developers    fpCmpRevZeroOp = fpOp % ("fplibCompare%s<Element>(0, srcElem1, fpscr) ?"
120410037SARM gem5 Developers                             " -1 : 0")
120510037SARM gem5 Developers    fcmleZeroCode = fpCmpRevZeroOp % "GE"
120610037SARM gem5 Developers    twoEqualRegInstX("fcmle", "FcmleZeroDX", "SimdFloatCmpOp", smallFloatTypes,
120710037SARM gem5 Developers                     2, fcmleZeroCode)
120810037SARM gem5 Developers    twoEqualRegInstX("fcmle", "FcmleZeroQX", "SimdFloatCmpOp", floatTypes, 4,
120910037SARM gem5 Developers                     fcmleZeroCode)
121010037SARM gem5 Developers    twoEqualRegInstX("fcmle", "FcmleZeroScX", "SimdFloatCmpOp", floatTypes, 4,
121110037SARM gem5 Developers                     fcmleZeroCode, scalar=True)
121210037SARM gem5 Developers    # FCMLT (zero)
121310037SARM gem5 Developers    fcmltZeroCode = fpCmpRevZeroOp % "GT"
121410037SARM gem5 Developers    twoEqualRegInstX("fcmlt", "FcmltZeroDX", "SimdFloatCmpOp", smallFloatTypes,
121510037SARM gem5 Developers                     2, fcmltZeroCode)
121610037SARM gem5 Developers    twoEqualRegInstX("fcmlt", "FcmltZeroQX", "SimdFloatCmpOp", floatTypes, 4,
121710037SARM gem5 Developers                     fcmltZeroCode)
121810037SARM gem5 Developers    twoEqualRegInstX("fcmlt", "FcmltZeroScX", "SimdFloatCmpOp", floatTypes, 4,
121910037SARM gem5 Developers                     fcmltZeroCode, scalar=True)
122010037SARM gem5 Developers    # FCVTAS
122110037SARM gem5 Developers    fcvtCode = fpOp % ("fplibFPToFixed<Element, Element>("
122210037SARM gem5 Developers                       "srcElem1, %s, %s, %s, fpscr)")
122310037SARM gem5 Developers    fcvtasCode = fcvtCode % ("0", "false", "FPRounding_TIEAWAY")
122410037SARM gem5 Developers    twoEqualRegInstX("fcvtas", "FcvtasDX", "SimdCvtOp", smallFloatTypes, 2,
122510037SARM gem5 Developers                     fcvtasCode)
122610037SARM gem5 Developers    twoEqualRegInstX("fcvtas", "FcvtasQX", "SimdCvtOp", floatTypes, 4,
122710037SARM gem5 Developers                     fcvtasCode)
122810037SARM gem5 Developers    twoEqualRegInstX("fcvtas", "FcvtasScX", "SimdCvtOp", floatTypes, 4,
122910037SARM gem5 Developers                     fcvtasCode, scalar=True)
123010037SARM gem5 Developers    # FCVTAU
123110037SARM gem5 Developers    fcvtauCode = fcvtCode % ("0", "true", "FPRounding_TIEAWAY")
123210037SARM gem5 Developers    twoEqualRegInstX("fcvtau", "FcvtauDX", "SimdCvtOp", smallFloatTypes, 2,
123310037SARM gem5 Developers                     fcvtauCode)
123410037SARM gem5 Developers    twoEqualRegInstX("fcvtau", "FcvtauQX", "SimdCvtOp", floatTypes, 4,
123510037SARM gem5 Developers                     fcvtauCode)
123610037SARM gem5 Developers    twoEqualRegInstX("fcvtau", "FcvtauScX", "SimdCvtOp", floatTypes, 4,
123710037SARM gem5 Developers                     fcvtauCode, scalar=True)
123810037SARM gem5 Developers    # FCVTL, FCVTL2
123910037SARM gem5 Developers    fcvtlCode = fpOp % ("fplibConvert<Element, BigElement>("
124010037SARM gem5 Developers                        "srcElem1, FPCRRounding(fpscr), fpscr)")
124110037SARM gem5 Developers    twoRegLongInstX("fcvtl", "FcvtlX", "SimdCvtOp", ("uint16_t", "uint32_t"),
124210037SARM gem5 Developers                    fcvtlCode)
124310037SARM gem5 Developers    twoRegLongInstX("fcvtl", "Fcvtl2X", "SimdCvtOp", ("uint16_t", "uint32_t"),
124410037SARM gem5 Developers                    fcvtlCode, hi=True)
124510037SARM gem5 Developers    # FCVTMS
124610037SARM gem5 Developers    fcvtmsCode = fcvtCode % ("0", "false", "FPRounding_NEGINF")
124710037SARM gem5 Developers    twoEqualRegInstX("fcvtms", "FcvtmsDX", "SimdCvtOp", smallFloatTypes, 2,
124810037SARM gem5 Developers                     fcvtmsCode)
124910037SARM gem5 Developers    twoEqualRegInstX("fcvtms", "FcvtmsQX", "SimdCvtOp", floatTypes, 4,
125010037SARM gem5 Developers                     fcvtmsCode)
125110037SARM gem5 Developers    twoEqualRegInstX("fcvtms", "FcvtmsScX", "SimdCvtOp", floatTypes, 4,
125210037SARM gem5 Developers                     fcvtmsCode, scalar=True)
125310037SARM gem5 Developers    # FCVTMU
125410037SARM gem5 Developers    fcvtmuCode = fcvtCode % ("0", "true", "FPRounding_NEGINF")
125510037SARM gem5 Developers    twoEqualRegInstX("fcvtmu", "FcvtmuDX", "SimdCvtOp", smallFloatTypes, 2,
125610037SARM gem5 Developers                     fcvtmuCode)
125710037SARM gem5 Developers    twoEqualRegInstX("fcvtmu", "FcvtmuQX", "SimdCvtOp", floatTypes, 4,
125810037SARM gem5 Developers                     fcvtmuCode)
125910037SARM gem5 Developers    twoEqualRegInstX("fcvtmu", "FcvtmuScX", "SimdCvtOp", floatTypes, 4,
126010037SARM gem5 Developers                     fcvtmuCode, scalar=True)
126110037SARM gem5 Developers    # FCVTN, FCVTN2
126210037SARM gem5 Developers    fcvtnCode = fpOp % ("fplibConvert<BigElement, Element>("
126310037SARM gem5 Developers                        "srcElem1, FPCRRounding(fpscr), fpscr)")
126410037SARM gem5 Developers    twoRegNarrowInstX("fcvtn", "FcvtnX", "SimdCvtOp",
126510037SARM gem5 Developers                      ("uint16_t", "uint32_t"), fcvtnCode)
126610037SARM gem5 Developers    twoRegNarrowInstX("fcvtn", "Fcvtn2X", "SimdCvtOp",
126710037SARM gem5 Developers                      ("uint16_t", "uint32_t"), fcvtnCode, hi=True)
126810037SARM gem5 Developers    # FCVTNS
126910037SARM gem5 Developers    fcvtnsCode = fcvtCode % ("0", "false", "FPRounding_TIEEVEN")
127010037SARM gem5 Developers    twoEqualRegInstX("fcvtns", "FcvtnsDX", "SimdCvtOp", smallFloatTypes, 2,
127110037SARM gem5 Developers                     fcvtnsCode)
127210037SARM gem5 Developers    twoEqualRegInstX("fcvtns", "FcvtnsQX", "SimdCvtOp", floatTypes, 4,
127310037SARM gem5 Developers                     fcvtnsCode)
127410037SARM gem5 Developers    twoEqualRegInstX("fcvtns", "FcvtnsScX", "SimdCvtOp", floatTypes, 4,
127510037SARM gem5 Developers                     fcvtnsCode, scalar=True)
127610037SARM gem5 Developers    # FCVTNU
127710037SARM gem5 Developers    fcvtnuCode = fcvtCode % ("0", "true", "FPRounding_TIEEVEN")
127810037SARM gem5 Developers    twoEqualRegInstX("fcvtnu", "FcvtnuDX", "SimdCvtOp", smallFloatTypes, 2,
127910037SARM gem5 Developers                     fcvtnuCode)
128010037SARM gem5 Developers    twoEqualRegInstX("fcvtnu", "FcvtnuQX", "SimdCvtOp", floatTypes, 4,
128110037SARM gem5 Developers                     fcvtnuCode)
128210037SARM gem5 Developers    twoEqualRegInstX("fcvtnu", "FcvtnuScX", "SimdCvtOp", floatTypes, 4,
128310037SARM gem5 Developers                     fcvtnuCode, scalar=True)
128410037SARM gem5 Developers    # FCVTPS
128510037SARM gem5 Developers    fcvtpsCode = fcvtCode % ("0", "false", "FPRounding_POSINF")
128610037SARM gem5 Developers    twoEqualRegInstX("fcvtps", "FcvtpsDX", "SimdCvtOp", smallFloatTypes, 2,
128710037SARM gem5 Developers                     fcvtpsCode)
128810037SARM gem5 Developers    twoEqualRegInstX("fcvtps", "FcvtpsQX", "SimdCvtOp", floatTypes, 4,
128910037SARM gem5 Developers                     fcvtpsCode)
129010037SARM gem5 Developers    twoEqualRegInstX("fcvtps", "FcvtpsScX", "SimdCvtOp", floatTypes, 4,
129110037SARM gem5 Developers                     fcvtpsCode, scalar=True)
129210037SARM gem5 Developers    # FCVTPU
129310037SARM gem5 Developers    fcvtpuCode = fcvtCode % ("0", "true", "FPRounding_POSINF")
129410037SARM gem5 Developers    twoEqualRegInstX("fcvtpu", "FcvtpuDX", "SimdCvtOp", smallFloatTypes, 2,
129510037SARM gem5 Developers                     fcvtpuCode)
129610037SARM gem5 Developers    twoEqualRegInstX("fcvtpu", "FcvtpuQX", "SimdCvtOp", floatTypes, 4,
129710037SARM gem5 Developers                     fcvtpuCode)
129810037SARM gem5 Developers    twoEqualRegInstX("fcvtpu", "FcvtpuScX", "SimdCvtOp", floatTypes, 4,
129910037SARM gem5 Developers                     fcvtpuCode, scalar=True)
130010037SARM gem5 Developers    # FCVTXN, FCVTXN2
130110037SARM gem5 Developers    fcvtxnCode = fpOp % ("fplibConvert<BigElement, Element>("
130210037SARM gem5 Developers                         "srcElem1, FPRounding_ODD, fpscr)")
130310037SARM gem5 Developers    twoRegNarrowInstX("fcvtxn", "FcvtxnX", "SimdCvtOp", smallFloatTypes,
130410037SARM gem5 Developers                      fcvtxnCode)
130510037SARM gem5 Developers    twoRegNarrowInstX("fcvtxn", "Fcvtxn2X", "SimdCvtOp", smallFloatTypes,
130610037SARM gem5 Developers                      fcvtxnCode, hi=True)
130710037SARM gem5 Developers    twoRegNarrowInstX("fcvtxn", "FcvtxnScX", "SimdCvtOp", smallFloatTypes,
130810037SARM gem5 Developers                      fcvtxnCode, scalar=True)
130910037SARM gem5 Developers    # FCVTZS (fixed-point)
131010037SARM gem5 Developers    fcvtzsCode = fcvtCode % ("imm", "false", "FPRounding_ZERO")
131110037SARM gem5 Developers    twoEqualRegInstX("fcvtzs", "FcvtzsFixedDX", "SimdCvtOp", smallFloatTypes,
131210037SARM gem5 Developers                     2, fcvtzsCode, hasImm=True)
131310037SARM gem5 Developers    twoEqualRegInstX("fcvtzs", "FcvtzsFixedQX", "SimdCvtOp", floatTypes, 4,
131410037SARM gem5 Developers                     fcvtzsCode, hasImm=True)
131510037SARM gem5 Developers    twoEqualRegInstX("fcvtzs", "FcvtzsFixedScX", "SimdCvtOp", floatTypes, 4,
131610037SARM gem5 Developers                     fcvtzsCode, hasImm=True, scalar=True)
131710037SARM gem5 Developers    # FCVTZS (integer)
131810037SARM gem5 Developers    fcvtzsIntCode = fcvtCode % ("0", "false", "FPRounding_ZERO")
131910037SARM gem5 Developers    twoEqualRegInstX("fcvtzs", "FcvtzsIntDX", "SimdCvtOp", smallFloatTypes,
132010037SARM gem5 Developers                     2, fcvtzsIntCode)
132110037SARM gem5 Developers    twoEqualRegInstX("fcvtzs", "FcvtzsIntQX", "SimdCvtOp", floatTypes, 4,
132210037SARM gem5 Developers                     fcvtzsIntCode)
132310037SARM gem5 Developers    twoEqualRegInstX("fcvtzs", "FcvtzsIntScX", "SimdCvtOp", floatTypes, 4,
132410037SARM gem5 Developers                     fcvtzsIntCode, scalar=True)
132510037SARM gem5 Developers    # FCVTZU (fixed-point)
132610037SARM gem5 Developers    fcvtzuCode = fcvtCode % ("imm", "true", "FPRounding_ZERO")
132710037SARM gem5 Developers    twoEqualRegInstX("fcvtzu", "FcvtzuFixedDX", "SimdCvtOp", smallFloatTypes,
132810037SARM gem5 Developers                     2, fcvtzuCode, hasImm=True)
132910037SARM gem5 Developers    twoEqualRegInstX("fcvtzu", "FcvtzuFixedQX", "SimdCvtOp", floatTypes, 4,
133010037SARM gem5 Developers                     fcvtzuCode, hasImm=True)
133110037SARM gem5 Developers    twoEqualRegInstX("fcvtzu", "FcvtzuFixedScX", "SimdCvtOp", floatTypes, 4,
133210037SARM gem5 Developers                     fcvtzuCode, hasImm=True, scalar=True)
133310037SARM gem5 Developers    # FCVTZU (integer)
133410037SARM gem5 Developers    fcvtzuIntCode = fcvtCode % ("0", "true", "FPRounding_ZERO")
133510037SARM gem5 Developers    twoEqualRegInstX("fcvtzu", "FcvtzuIntDX", "SimdCvtOp", smallFloatTypes, 2,
133610037SARM gem5 Developers                     fcvtzuIntCode)
133710037SARM gem5 Developers    twoEqualRegInstX("fcvtzu", "FcvtzuIntQX", "SimdCvtOp", floatTypes, 4,
133810037SARM gem5 Developers                     fcvtzuIntCode)
133910037SARM gem5 Developers    twoEqualRegInstX("fcvtzu", "FcvtzuIntScX", "SimdCvtOp", floatTypes, 4,
134010037SARM gem5 Developers                     fcvtzuIntCode, scalar=True)
134110037SARM gem5 Developers    # FDIV
134210037SARM gem5 Developers    fdivCode = fpBinOp % "Div"
134310037SARM gem5 Developers    threeEqualRegInstX("fdiv", "FdivDX", "SimdFloatDivOp", smallFloatTypes, 2,
134410037SARM gem5 Developers                       fdivCode)
134510037SARM gem5 Developers    threeEqualRegInstX("fdiv", "FdivQX", "SimdFloatDivOp", floatTypes, 4,
134610037SARM gem5 Developers                       fdivCode)
134710037SARM gem5 Developers    # FMAX
134810037SARM gem5 Developers    fmaxCode = fpBinOp % "Max"
134910037SARM gem5 Developers    threeEqualRegInstX("fmax", "FmaxDX", "SimdFloatCmpOp", smallFloatTypes, 2,
135010037SARM gem5 Developers                       fmaxCode)
135110037SARM gem5 Developers    threeEqualRegInstX("fmax", "FmaxQX", "SimdFloatCmpOp", floatTypes, 4,
135210037SARM gem5 Developers                       fmaxCode)
135310037SARM gem5 Developers    # FMAXNM
135410037SARM gem5 Developers    fmaxnmCode = fpBinOp % "MaxNum"
135510037SARM gem5 Developers    threeEqualRegInstX("fmaxnm", "FmaxnmDX", "SimdFloatCmpOp", smallFloatTypes,
135610037SARM gem5 Developers                       2, fmaxnmCode)
135710037SARM gem5 Developers    threeEqualRegInstX("fmaxnm", "FmaxnmQX", "SimdFloatCmpOp", floatTypes, 4,
135810037SARM gem5 Developers                       fmaxnmCode)
135910037SARM gem5 Developers    # FMAXNMP (scalar)
136010037SARM gem5 Developers    twoRegPairwiseScInstX("fmaxnmp", "FmaxnmpScDX", "SimdFloatCmpOp",
136110037SARM gem5 Developers                          ("uint32_t",), 2, fmaxnmCode)
136210037SARM gem5 Developers    twoRegPairwiseScInstX("fmaxnmp", "FmaxnmpScQX", "SimdFloatCmpOp",
136310037SARM gem5 Developers                          ("uint64_t",), 4, fmaxnmCode)
136410037SARM gem5 Developers    # FMAXNMP (vector)
136510037SARM gem5 Developers    threeEqualRegInstX("fmaxnmp", "FmaxnmpDX", "SimdFloatCmpOp",
136610037SARM gem5 Developers                       smallFloatTypes, 2, fmaxnmCode, pairwise=True)
136710037SARM gem5 Developers    threeEqualRegInstX("fmaxnmp", "FmaxnmpQX", "SimdFloatCmpOp", floatTypes, 4,
136810037SARM gem5 Developers                       fmaxnmCode, pairwise=True)
136910037SARM gem5 Developers    # FMAXNMV
137010037SARM gem5 Developers    # Note: SimdFloatCmpOp can be a bit optimistic here
137110037SARM gem5 Developers    fpAcrossOp = fpOp % "fplib%s<Element>(destElem, srcElem1, fpscr)"
137210037SARM gem5 Developers    fmaxnmAcrossCode = fpAcrossOp % "MaxNum"
137310037SARM gem5 Developers    twoRegAcrossInstX("fmaxnmv", "FmaxnmvQX", "SimdFloatCmpOp", ("uint32_t",),
137410037SARM gem5 Developers                      4, fmaxnmAcrossCode)
137510037SARM gem5 Developers    # FMAXP (scalar)
137610037SARM gem5 Developers    twoRegPairwiseScInstX("fmaxp", "FmaxpScDX", "SimdFloatCmpOp",
137710037SARM gem5 Developers                          ("uint32_t",), 2, fmaxCode)
137810037SARM gem5 Developers    twoRegPairwiseScInstX("fmaxp", "FmaxpScQX", "SimdFloatCmpOp",
137910037SARM gem5 Developers                          ("uint64_t",), 4, fmaxCode)
138010037SARM gem5 Developers    # FMAXP (vector)
138110037SARM gem5 Developers    threeEqualRegInstX("fmaxp", "FmaxpDX", "SimdFloatCmpOp", smallFloatTypes,
138210037SARM gem5 Developers                       2, fmaxCode, pairwise=True)
138310037SARM gem5 Developers    threeEqualRegInstX("fmaxp", "FmaxpQX", "SimdFloatCmpOp", floatTypes, 4,
138410037SARM gem5 Developers                       fmaxCode, pairwise=True)
138510037SARM gem5 Developers    # FMAXV
138610037SARM gem5 Developers    # Note: SimdFloatCmpOp can be a bit optimistic here
138710037SARM gem5 Developers    fmaxAcrossCode = fpAcrossOp % "Max"
138810037SARM gem5 Developers    twoRegAcrossInstX("fmaxv", "FmaxvQX", "SimdFloatCmpOp", ("uint32_t",), 4,
138910037SARM gem5 Developers                      fmaxAcrossCode)
139010037SARM gem5 Developers    # FMIN
139110037SARM gem5 Developers    fminCode = fpBinOp % "Min"
139210037SARM gem5 Developers    threeEqualRegInstX("fmin", "FminDX", "SimdFloatCmpOp", smallFloatTypes, 2,
139310037SARM gem5 Developers                       fminCode)
139410037SARM gem5 Developers    threeEqualRegInstX("fmin", "FminQX", "SimdFloatCmpOp", floatTypes, 4,
139510037SARM gem5 Developers                       fminCode)
139610037SARM gem5 Developers    # FMINNM
139710037SARM gem5 Developers    fminnmCode = fpBinOp % "MinNum"
139810037SARM gem5 Developers    threeEqualRegInstX("fminnm", "FminnmDX", "SimdFloatCmpOp", smallFloatTypes,
139910037SARM gem5 Developers                       2, fminnmCode)
140010037SARM gem5 Developers    threeEqualRegInstX("fminnm", "FminnmQX", "SimdFloatCmpOp", floatTypes, 4,
140110037SARM gem5 Developers                       fminnmCode)
140210037SARM gem5 Developers    # FMINNMP (scalar)
140310037SARM gem5 Developers    twoRegPairwiseScInstX("fminnmp", "FminnmpScDX", "SimdFloatCmpOp",
140410037SARM gem5 Developers                          ("uint32_t",), 2, fminnmCode)
140510037SARM gem5 Developers    twoRegPairwiseScInstX("fminnmp", "FminnmpScQX", "SimdFloatCmpOp",
140610037SARM gem5 Developers                          ("uint64_t",), 4, fminnmCode)
140710037SARM gem5 Developers    # FMINNMP (vector)
140810037SARM gem5 Developers    threeEqualRegInstX("fminnmp", "FminnmpDX", "SimdFloatCmpOp",
140910037SARM gem5 Developers                       smallFloatTypes, 2, fminnmCode, pairwise=True)
141010037SARM gem5 Developers    threeEqualRegInstX("fminnmp", "FminnmpQX", "SimdFloatCmpOp", floatTypes, 4,
141110037SARM gem5 Developers                       fminnmCode, pairwise=True)
141210037SARM gem5 Developers    # FMINNMV
141310037SARM gem5 Developers    # Note: SimdFloatCmpOp can be a bit optimistic here
141410037SARM gem5 Developers    fminnmAcrossCode = fpAcrossOp % "MinNum"
141510037SARM gem5 Developers    twoRegAcrossInstX("fminnmv", "FminnmvQX", "SimdFloatCmpOp", ("uint32_t",),
141610037SARM gem5 Developers                      4, fminnmAcrossCode)
141710037SARM gem5 Developers    # FMINP (scalar)
141810037SARM gem5 Developers    twoRegPairwiseScInstX("fminp", "FminpScDX", "SimdFloatCmpOp",
141910037SARM gem5 Developers                          ("uint32_t",), 2, fminCode)
142010037SARM gem5 Developers    twoRegPairwiseScInstX("fminp", "FminpScQX", "SimdFloatCmpOp",
142110037SARM gem5 Developers                          ("uint64_t",), 4, fminCode)
142210037SARM gem5 Developers    # FMINP (vector)
142310037SARM gem5 Developers    threeEqualRegInstX("fminp", "FminpDX", "SimdFloatCmpOp", smallFloatTypes,
142410037SARM gem5 Developers                       2, fminCode, pairwise=True)
142510037SARM gem5 Developers    threeEqualRegInstX("fminp", "FminpQX", "SimdFloatCmpOp", floatTypes, 4,
142610037SARM gem5 Developers                       fminCode, pairwise=True)
142710037SARM gem5 Developers    # FMINV
142810037SARM gem5 Developers    # Note: SimdFloatCmpOp can be a bit optimistic here
142910037SARM gem5 Developers    fminAcrossCode = fpAcrossOp % "Min"
143010037SARM gem5 Developers    twoRegAcrossInstX("fminv", "FminvQX", "SimdFloatCmpOp", ("uint32_t",), 4,
143110037SARM gem5 Developers                      fminAcrossCode)
143210037SARM gem5 Developers    # FMLA (by element)
143310037SARM gem5 Developers    fmlaCode = fpOp % ("fplibMulAdd<Element>("
143410037SARM gem5 Developers                       "destElem, srcElem1, srcElem2, fpscr)")
143510037SARM gem5 Developers    threeEqualRegInstX("fmla", "FmlaElemDX", "SimdFloatMultAccOp",
143610037SARM gem5 Developers                       smallFloatTypes, 2, fmlaCode, True, byElem=True)
143710037SARM gem5 Developers    threeEqualRegInstX("fmla", "FmlaElemQX", "SimdFloatMultAccOp", floatTypes,
143810037SARM gem5 Developers                       4, fmlaCode, True, byElem=True)
143910037SARM gem5 Developers    threeEqualRegInstX("fmla", "FmlaElemScX", "SimdFloatMultAccOp", floatTypes,
144010037SARM gem5 Developers                       4, fmlaCode, True, byElem=True, scalar=True)
144110037SARM gem5 Developers    # FMLA (vector)
144210037SARM gem5 Developers    threeEqualRegInstX("fmla", "FmlaDX", "SimdFloatMultAccOp", smallFloatTypes,
144310037SARM gem5 Developers                       2, fmlaCode, True)
144410037SARM gem5 Developers    threeEqualRegInstX("fmla", "FmlaQX", "SimdFloatMultAccOp", floatTypes, 4,
144510037SARM gem5 Developers                       fmlaCode, True)
144610037SARM gem5 Developers    # FMLS (by element)
144710037SARM gem5 Developers    fmlsCode = fpOp % ("fplibMulAdd<Element>(destElem,"
144810037SARM gem5 Developers                       " fplibNeg<Element>(srcElem1), srcElem2, fpscr)")
144910037SARM gem5 Developers    threeEqualRegInstX("fmls", "FmlsElemDX", "SimdFloatMultAccOp",
145010037SARM gem5 Developers                       smallFloatTypes, 2, fmlsCode, True, byElem=True)
145110037SARM gem5 Developers    threeEqualRegInstX("fmls", "FmlsElemQX", "SimdFloatMultAccOp", floatTypes,
145210037SARM gem5 Developers                       4, fmlsCode, True, byElem=True)
145310037SARM gem5 Developers    threeEqualRegInstX("fmls", "FmlsElemScX", "SimdFloatMultAccOp", floatTypes,
145410037SARM gem5 Developers                       4, fmlsCode, True, byElem=True, scalar=True)
145510037SARM gem5 Developers    # FMLS (vector)
145610037SARM gem5 Developers    threeEqualRegInstX("fmls", "FmlsDX", "SimdFloatMultAccOp", smallFloatTypes,
145710037SARM gem5 Developers                       2, fmlsCode, True)
145810037SARM gem5 Developers    threeEqualRegInstX("fmls", "FmlsQX", "SimdFloatMultAccOp", floatTypes, 4,
145910037SARM gem5 Developers                       fmlsCode, True)
146010037SARM gem5 Developers    # FMOV
146110037SARM gem5 Developers    fmovCode = 'destElem = imm;'
146210037SARM gem5 Developers    oneRegImmInstX("fmov", "FmovDX", "SimdMiscOp", smallFloatTypes, 2,
146310037SARM gem5 Developers                   fmovCode)
146410037SARM gem5 Developers    oneRegImmInstX("fmov", "FmovQX", "SimdMiscOp", floatTypes, 4, fmovCode)
146510037SARM gem5 Developers    # FMUL (by element)
146610037SARM gem5 Developers    fmulCode = fpBinOp % "Mul"
146710037SARM gem5 Developers    threeEqualRegInstX("fmul", "FmulElemDX", "SimdFloatMultOp",
146810037SARM gem5 Developers                       smallFloatTypes, 2, fmulCode, byElem=True)
146910037SARM gem5 Developers    threeEqualRegInstX("fmul", "FmulElemQX", "SimdFloatMultOp", floatTypes, 4,
147010037SARM gem5 Developers                       fmulCode, byElem=True)
147110037SARM gem5 Developers    threeEqualRegInstX("fmul", "FmulElemScX", "SimdFloatMultOp", floatTypes, 4,
147210037SARM gem5 Developers                       fmulCode, byElem=True, scalar=True)
147310037SARM gem5 Developers    # FMUL (vector)
147410037SARM gem5 Developers    threeEqualRegInstX("fmul", "FmulDX", "SimdFloatMultOp", smallFloatTypes, 2,
147510037SARM gem5 Developers                       fmulCode)
147610037SARM gem5 Developers    threeEqualRegInstX("fmul", "FmulQX", "SimdFloatMultOp", floatTypes, 4,
147710037SARM gem5 Developers                       fmulCode)
147810037SARM gem5 Developers    # FMULX
147910037SARM gem5 Developers    fmulxCode = fpBinOp % "MulX"
148010037SARM gem5 Developers    threeEqualRegInstX("fmulx", "FmulxDX", "SimdFloatMultOp", smallFloatTypes,
148110037SARM gem5 Developers                       2, fmulxCode)
148210037SARM gem5 Developers    threeEqualRegInstX("fmulx", "FmulxQX", "SimdFloatMultOp", floatTypes, 4,
148310037SARM gem5 Developers                       fmulxCode)
148410037SARM gem5 Developers    threeEqualRegInstX("fmulx", "FmulxScX", "SimdFloatMultOp", floatTypes, 4,
148510037SARM gem5 Developers                       fmulxCode, scalar=True)
148610037SARM gem5 Developers    # FMULX (by element)
148710037SARM gem5 Developers    threeEqualRegInstX("fmulx", "FmulxElemDX", "SimdFloatMultOp",
148810037SARM gem5 Developers                       smallFloatTypes, 2, fmulxCode, byElem=True)
148910037SARM gem5 Developers    threeEqualRegInstX("fmulx", "FmulxElemQX", "SimdFloatMultOp", floatTypes,
149010037SARM gem5 Developers                       4, fmulxCode, byElem=True)
149110037SARM gem5 Developers    threeEqualRegInstX("fmulx", "FmulxElemScX", "SimdFloatMultOp", floatTypes,
149210037SARM gem5 Developers                       4, fmulxCode, byElem=True, scalar=True)
149310037SARM gem5 Developers    # FNEG
149410037SARM gem5 Developers    fnegCode = fpOp % "fplibNeg<Element>(srcElem1)"
149510037SARM gem5 Developers    twoEqualRegInstX("Neg", "FnegDX", "SimdFloatAluOp", smallFloatTypes, 2,
149610037SARM gem5 Developers                     fnegCode)
149710037SARM gem5 Developers    twoEqualRegInstX("Neg", "FnegQX", "SimdFloatAluOp", floatTypes, 4,
149810037SARM gem5 Developers                     fnegCode)
149910037SARM gem5 Developers    # FRECPE
150010037SARM gem5 Developers    frecpeCode = fpOp % "fplibRecipEstimate<Element>(srcElem1, fpscr)"
150110037SARM gem5 Developers    twoEqualRegInstX("frecpe", "FrecpeDX", "SimdFloatMultAccOp",
150210037SARM gem5 Developers                     smallFloatTypes, 2, frecpeCode)
150310037SARM gem5 Developers    twoEqualRegInstX("frecpe", "FrecpeQX", "SimdFloatMultAccOp", floatTypes, 4,
150410037SARM gem5 Developers                     frecpeCode)
150510037SARM gem5 Developers    twoEqualRegInstX("frecpe", "FrecpeScX", "SimdFloatMultAccOp", floatTypes,
150610037SARM gem5 Developers                     4, frecpeCode, scalar=True)
150710037SARM gem5 Developers    # FRECPS
150810037SARM gem5 Developers    frecpsCode = fpBinOp % "RecipStepFused"
150910037SARM gem5 Developers    threeEqualRegInstX("frecps", "FrecpsDX", "SimdFloatMultAccOp",
151010037SARM gem5 Developers                       smallFloatTypes, 2, frecpsCode)
151110037SARM gem5 Developers    threeEqualRegInstX("frecps", "FrecpsQX", "SimdFloatMultAccOp", floatTypes,
151210037SARM gem5 Developers                       4, frecpsCode)
151310037SARM gem5 Developers    threeEqualRegInstX("frecps", "FrecpsScX", "SimdFloatMultAccOp", floatTypes,
151410037SARM gem5 Developers                       4, frecpsCode, scalar=True)
151510037SARM gem5 Developers    # FRECPX
151610037SARM gem5 Developers    frecpxCode = fpOp % "fplibRecpX<Element>(srcElem1, fpscr)"
151710037SARM gem5 Developers    twoEqualRegInstX("frecpx", "FrecpxX", "SimdFloatMultAccOp", floatTypes, 4,
151810037SARM gem5 Developers                     frecpxCode, scalar=True)
151910037SARM gem5 Developers    # FRINTA
152010037SARM gem5 Developers    frintCode = fpOp % "fplibRoundInt<Element>(srcElem1, %s, %s, fpscr)"
152110037SARM gem5 Developers    frintaCode = frintCode % ("FPRounding_TIEAWAY", "false")
152210037SARM gem5 Developers    twoEqualRegInstX("frinta", "FrintaDX", "SimdCvtOp", smallFloatTypes, 2,
152310037SARM gem5 Developers                     frintaCode)
152410037SARM gem5 Developers    twoEqualRegInstX("frinta", "FrintaQX", "SimdCvtOp", floatTypes, 4,
152510037SARM gem5 Developers                     frintaCode)
152610037SARM gem5 Developers    # FRINTI
152710037SARM gem5 Developers    frintiCode = frintCode % ("FPCRRounding(fpscr)", "false")
152810037SARM gem5 Developers    twoEqualRegInstX("frinti", "FrintiDX", "SimdCvtOp", smallFloatTypes, 2,
152910037SARM gem5 Developers                     frintiCode)
153010037SARM gem5 Developers    twoEqualRegInstX("frinti", "FrintiQX", "SimdCvtOp", floatTypes, 4,
153110037SARM gem5 Developers                     frintiCode)
153210037SARM gem5 Developers    # FRINTM
153310037SARM gem5 Developers    frintmCode = frintCode % ("FPRounding_NEGINF", "false")
153410037SARM gem5 Developers    twoEqualRegInstX("frintm", "FrintmDX", "SimdCvtOp", smallFloatTypes, 2,
153510037SARM gem5 Developers                     frintmCode)
153610037SARM gem5 Developers    twoEqualRegInstX("frintm", "FrintmQX", "SimdCvtOp", floatTypes, 4,
153710037SARM gem5 Developers                     frintmCode)
153810037SARM gem5 Developers    # FRINTN
153910037SARM gem5 Developers    frintnCode = frintCode % ("FPRounding_TIEEVEN", "false")
154010037SARM gem5 Developers    twoEqualRegInstX("frintn", "FrintnDX", "SimdCvtOp", smallFloatTypes, 2,
154110037SARM gem5 Developers                     frintnCode)
154210037SARM gem5 Developers    twoEqualRegInstX("frintn", "FrintnQX", "SimdCvtOp", floatTypes, 4,
154310037SARM gem5 Developers                     frintnCode)
154410037SARM gem5 Developers    # FRINTP
154510037SARM gem5 Developers    frintpCode = frintCode % ("FPRounding_POSINF", "false")
154610037SARM gem5 Developers    twoEqualRegInstX("frintp", "FrintpDX", "SimdCvtOp", smallFloatTypes, 2,
154710037SARM gem5 Developers                     frintpCode)
154810037SARM gem5 Developers    twoEqualRegInstX("frintp", "FrintpQX", "SimdCvtOp", floatTypes, 4,
154910037SARM gem5 Developers                     frintpCode)
155010037SARM gem5 Developers    # FRINTX
155110037SARM gem5 Developers    frintxCode = frintCode % ("FPCRRounding(fpscr)", "true")
155210037SARM gem5 Developers    twoEqualRegInstX("frintx", "FrintxDX", "SimdCvtOp", smallFloatTypes, 2,
155310037SARM gem5 Developers                     frintxCode)
155410037SARM gem5 Developers    twoEqualRegInstX("frintx", "FrintxQX", "SimdCvtOp", floatTypes, 4,
155510037SARM gem5 Developers                     frintxCode)
155610037SARM gem5 Developers    # FRINTZ
155710037SARM gem5 Developers    frintzCode = frintCode % ("FPRounding_ZERO", "false")
155810037SARM gem5 Developers    twoEqualRegInstX("frintz", "FrintzDX", "SimdCvtOp", smallFloatTypes, 2,
155910037SARM gem5 Developers                     frintzCode)
156010037SARM gem5 Developers    twoEqualRegInstX("frintz", "FrintzQX", "SimdCvtOp", floatTypes, 4,
156110037SARM gem5 Developers                     frintzCode)
156210037SARM gem5 Developers    # FRSQRTE
156310037SARM gem5 Developers    frsqrteCode = fpOp % "fplibRSqrtEstimate<Element>(srcElem1, fpscr)"
156410037SARM gem5 Developers    twoEqualRegInstX("frsqrte", "FrsqrteDX", "SimdFloatSqrtOp",
156510037SARM gem5 Developers                     smallFloatTypes, 2, frsqrteCode)
156610037SARM gem5 Developers    twoEqualRegInstX("frsqrte", "FrsqrteQX", "SimdFloatSqrtOp", floatTypes, 4,
156710037SARM gem5 Developers                     frsqrteCode)
156810037SARM gem5 Developers    twoEqualRegInstX("frsqrte", "FrsqrteScX", "SimdFloatSqrtOp", floatTypes, 4,
156910037SARM gem5 Developers                     frsqrteCode, scalar=True)
157010037SARM gem5 Developers    # FRSQRTS
157110037SARM gem5 Developers    frsqrtsCode = fpBinOp % "RSqrtStepFused"
157210037SARM gem5 Developers    threeEqualRegInstX("frsqrts", "FrsqrtsDX", "SimdFloatMiscOp",
157310037SARM gem5 Developers                       smallFloatTypes, 2, frsqrtsCode)
157410037SARM gem5 Developers    threeEqualRegInstX("frsqrts", "FrsqrtsQX", "SimdFloatMiscOp", floatTypes,
157510037SARM gem5 Developers                       4, frsqrtsCode)
157610037SARM gem5 Developers    threeEqualRegInstX("frsqrts", "FrsqrtsScX", "SimdFloatMiscOp", floatTypes,
157710037SARM gem5 Developers                       4, frsqrtsCode, scalar=True)
157810037SARM gem5 Developers    # FSQRT
157910037SARM gem5 Developers    fsqrtCode = fpOp % "fplibSqrt<Element>(srcElem1, fpscr)"
158010037SARM gem5 Developers    twoEqualRegInstX("fsqrt", "FsqrtDX", "SimdFloatSqrtOp", smallFloatTypes, 2,
158110037SARM gem5 Developers                     fsqrtCode)
158210037SARM gem5 Developers    twoEqualRegInstX("fsqrt", "FsqrtQX", "SimdFloatSqrtOp", floatTypes, 4,
158310037SARM gem5 Developers                     fsqrtCode)
158410037SARM gem5 Developers    # FSUB
158510037SARM gem5 Developers    fsubCode = fpBinOp % "Sub"
158610037SARM gem5 Developers    threeEqualRegInstX("fsub", "FsubDX", "SimdFloatAddOp", smallFloatTypes, 2,
158710037SARM gem5 Developers                       fsubCode)
158810037SARM gem5 Developers    threeEqualRegInstX("fsub", "FsubQX", "SimdFloatAddOp", floatTypes, 4,
158910037SARM gem5 Developers                       fsubCode)
159010037SARM gem5 Developers    # INS (element)
159110037SARM gem5 Developers    insFromVecElemInstX("ins", "InsElemX", "SimdMiscOp", unsignedTypes, 4)
159210037SARM gem5 Developers    # INS (general register)
159310037SARM gem5 Developers    insFromGprInstX("ins", "InsGprWX", "SimdMiscOp", smallUnsignedTypes, 4,
159410037SARM gem5 Developers                    'W')
159510037SARM gem5 Developers    insFromGprInstX("ins", "InsGprXX", "SimdMiscOp", unsignedTypes, 4, 'X')
159610037SARM gem5 Developers    # MLA (by element)
159710037SARM gem5 Developers    mlaCode = "destElem += srcElem1 * srcElem2;"
159810037SARM gem5 Developers    threeEqualRegInstX("mla", "MlaElemDX", "SimdMultAccOp",
159910037SARM gem5 Developers                       ("uint16_t", "uint32_t"), 2, mlaCode, True, byElem=True)
160010037SARM gem5 Developers    threeEqualRegInstX("mla", "MlaElemQX", "SimdMultAccOp",
160110037SARM gem5 Developers                       ("uint16_t", "uint32_t"), 4, mlaCode, True, byElem=True)
160210037SARM gem5 Developers    # MLA (vector)
160310037SARM gem5 Developers    threeEqualRegInstX("mla", "MlaDX", "SimdMultAccOp", smallUnsignedTypes, 2,
160410037SARM gem5 Developers                       mlaCode, True)
160510037SARM gem5 Developers    threeEqualRegInstX("mla", "MlaQX", "SimdMultAccOp", smallUnsignedTypes, 4,
160610037SARM gem5 Developers                       mlaCode, True)
160710037SARM gem5 Developers    # MLS (by element)
160810037SARM gem5 Developers    mlsCode = "destElem -= srcElem1 * srcElem2;"
160910037SARM gem5 Developers    threeEqualRegInstX("mls", "MlsElemDX", "SimdMultAccOp",
161010037SARM gem5 Developers                       ("uint16_t", "uint32_t"), 2, mlsCode, True, byElem=True)
161110037SARM gem5 Developers    threeEqualRegInstX("mls", "MlsElemQX", "SimdMultAccOp",
161210037SARM gem5 Developers                       ("uint16_t", "uint32_t"), 4, mlsCode, True, byElem=True)
161310037SARM gem5 Developers    # MLS (vector)
161410037SARM gem5 Developers    threeEqualRegInstX("mls", "MlsDX", "SimdMultAccOp", smallUnsignedTypes, 2,
161510037SARM gem5 Developers                       mlsCode, True)
161610037SARM gem5 Developers    threeEqualRegInstX("mls", "MlsQX", "SimdMultAccOp", smallUnsignedTypes, 4,
161710037SARM gem5 Developers                       mlsCode, True)
161810037SARM gem5 Developers    # MOV (element) -> alias to INS (element)
161910037SARM gem5 Developers    # MOV (from general) -> alias to INS (general register)
162010037SARM gem5 Developers    # MOV (scalar) -> alias to DUP (element)
162110037SARM gem5 Developers    # MOV (to general) -> alias to UMOV
162210037SARM gem5 Developers    # MOV (vector) -> alias to ORR (register)
162310037SARM gem5 Developers    # MOVI
162410037SARM gem5 Developers    movImmCode = "destElem = imm;"
162510037SARM gem5 Developers    oneRegImmInstX("movi", "MoviDX", "SimdMiscOp", ("uint64_t",), 2,
162610037SARM gem5 Developers                   movImmCode)
162710037SARM gem5 Developers    oneRegImmInstX("movi", "MoviQX", "SimdMiscOp", ("uint64_t",), 4,
162810037SARM gem5 Developers                   movImmCode)
162910037SARM gem5 Developers    # MUL (by element)
163010037SARM gem5 Developers    mulCode = "destElem = srcElem1 * srcElem2;"
163110037SARM gem5 Developers    threeEqualRegInstX("mul", "MulElemDX", "SimdMultOp",
163210037SARM gem5 Developers                       ("uint16_t", "uint32_t"), 2, mulCode, byElem=True)
163310037SARM gem5 Developers    threeEqualRegInstX("mul", "MulElemQX", "SimdMultOp",
163410037SARM gem5 Developers                       ("uint16_t", "uint32_t"), 4, mulCode, byElem=True)
163510037SARM gem5 Developers    # MUL (vector)
163610037SARM gem5 Developers    threeEqualRegInstX("mul", "MulDX", "SimdMultOp", smallUnsignedTypes, 2,
163710037SARM gem5 Developers                       mulCode)
163810037SARM gem5 Developers    threeEqualRegInstX("mul", "MulQX", "SimdMultOp", smallUnsignedTypes, 4,
163910037SARM gem5 Developers                       mulCode)
164010037SARM gem5 Developers    # MVN
164110037SARM gem5 Developers    mvnCode = "destElem = ~srcElem1;"
164210037SARM gem5 Developers    twoEqualRegInstX("mvn", "MvnDX", "SimdAluOp", ("uint64_t",), 2, mvnCode)
164310037SARM gem5 Developers    twoEqualRegInstX("mvn", "MvnQX", "SimdAluOp", ("uint64_t",), 4, mvnCode)
164410037SARM gem5 Developers    # MVNI
164510037SARM gem5 Developers    mvniCode = "destElem = ~imm;"
164610037SARM gem5 Developers    oneRegImmInstX("mvni", "MvniDX", "SimdAluOp", ("uint64_t",), 2, mvniCode)
164710037SARM gem5 Developers    oneRegImmInstX("mvni", "MvniQX", "SimdAluOp", ("uint64_t",), 4, mvniCode)
164810037SARM gem5 Developers    # NEG
164910037SARM gem5 Developers    negCode = "destElem = -srcElem1;"
165010037SARM gem5 Developers    twoEqualRegInstX("neg", "NegDX", "SimdAluOp", signedTypes, 2, negCode)
165110037SARM gem5 Developers    twoEqualRegInstX("neg", "NegQX", "SimdAluOp", signedTypes, 4, negCode)
165210037SARM gem5 Developers    # NOT -> alias to MVN
165310037SARM gem5 Developers    # ORN
165410037SARM gem5 Developers    ornCode = "destElem = srcElem1 | ~srcElem2;"
165510037SARM gem5 Developers    threeEqualRegInstX("orn", "OrnDX", "SimdAluOp", ("uint64_t",), 2, ornCode)
165610037SARM gem5 Developers    threeEqualRegInstX("orn", "OrnQX", "SimdAluOp", ("uint64_t",), 4, ornCode)
165710037SARM gem5 Developers    # ORR (immediate)
165810037SARM gem5 Developers    orrImmCode = "destElem |= imm;"
165910037SARM gem5 Developers    oneRegImmInstX("orr", "OrrImmDX", "SimdAluOp", ("uint64_t",), 2,
166010037SARM gem5 Developers                   orrImmCode, True)
166110037SARM gem5 Developers    oneRegImmInstX("orr", "OrrImmQX", "SimdAluOp", ("uint64_t",), 4,
166210037SARM gem5 Developers                   orrImmCode, True)
166310037SARM gem5 Developers    # ORR (register)
166410037SARM gem5 Developers    orrCode = "destElem = srcElem1 | srcElem2;"
166510037SARM gem5 Developers    threeEqualRegInstX("orr", "OrrDX", "SimdAluOp", ("uint64_t",), 2, orrCode)
166610037SARM gem5 Developers    threeEqualRegInstX("orr", "OrrQX", "SimdAluOp", ("uint64_t",), 4, orrCode)
166710037SARM gem5 Developers    # PMUL
166810037SARM gem5 Developers    pmulCode = '''
166910037SARM gem5 Developers            destElem = 0;
167010037SARM gem5 Developers            for (unsigned j = 0; j < sizeof(Element) * 8; j++) {
167110037SARM gem5 Developers                if (bits(srcElem2, j))
167210037SARM gem5 Developers                    destElem ^= srcElem1 << j;
167310037SARM gem5 Developers            }
167410037SARM gem5 Developers    '''
167510037SARM gem5 Developers    threeEqualRegInstX("pmul", "PmulDX", "SimdMultOp", ("uint8_t",), 2,
167610037SARM gem5 Developers                       pmulCode)
167710037SARM gem5 Developers    threeEqualRegInstX("pmul", "PmulQX", "SimdMultOp", ("uint8_t",), 4,
167810037SARM gem5 Developers                       pmulCode)
167910037SARM gem5 Developers    # PMULL, PMULL2
168010037SARM gem5 Developers    # Note: 64-bit PMULL is not available (Crypto. Extension)
168110037SARM gem5 Developers    pmullCode = '''
168210037SARM gem5 Developers            destElem = 0;
168310037SARM gem5 Developers            for (unsigned j = 0; j < sizeof(Element) * 8; j++) {
168410037SARM gem5 Developers                if (bits(srcElem2, j))
168510037SARM gem5 Developers                    destElem ^= (BigElement)srcElem1 << j;
168610037SARM gem5 Developers            }
168710037SARM gem5 Developers    '''
168810037SARM gem5 Developers    threeRegLongInstX("pmull", "PmullX", "SimdMultOp", ("uint8_t",), pmullCode)
168910037SARM gem5 Developers    threeRegLongInstX("pmull", "Pmull2X", "SimdMultOp", ("uint8_t",),
169010037SARM gem5 Developers                      pmullCode, hi=True)
169110037SARM gem5 Developers    # RADDHN, RADDHN2
169210037SARM gem5 Developers    raddhnCode = '''
169310037SARM gem5 Developers            destElem = ((BigElement)srcElem1 + (BigElement)srcElem2 +
169410037SARM gem5 Developers                        ((BigElement)1 << (sizeof(Element) * 8 - 1))) >>
169510037SARM gem5 Developers                       (sizeof(Element) * 8);
169610037SARM gem5 Developers    '''
169710037SARM gem5 Developers    threeRegNarrowInstX("raddhn", "RaddhnX", "SimdAddOp", smallUnsignedTypes,
169810037SARM gem5 Developers                        raddhnCode)
169910037SARM gem5 Developers    threeRegNarrowInstX("raddhn2", "Raddhn2X", "SimdAddOp", smallUnsignedTypes,
170010037SARM gem5 Developers                        raddhnCode, hi=True)
170110037SARM gem5 Developers    # RBIT
170210037SARM gem5 Developers    rbitCode = '''
170310037SARM gem5 Developers            destElem = 0;
170410037SARM gem5 Developers            Element temp = srcElem1;
170510037SARM gem5 Developers            for (int i = 0; i < 8 * sizeof(Element); i++) {
170610037SARM gem5 Developers                destElem = destElem  | ((temp & 0x1) <<
170710037SARM gem5 Developers                                        (8 * sizeof(Element) - 1 - i));
170810037SARM gem5 Developers                temp >>= 1;
170910037SARM gem5 Developers            }
171010037SARM gem5 Developers    '''
171110037SARM gem5 Developers    twoEqualRegInstX("rbit", "RbitDX", "SimdAluOp", ("uint8_t",), 2, rbitCode)
171210037SARM gem5 Developers    twoEqualRegInstX("rbit", "RbitQX", "SimdAluOp", ("uint8_t",), 4, rbitCode)
171310037SARM gem5 Developers    # REV16
171410037SARM gem5 Developers    rev16Code = '''
171510037SARM gem5 Developers            destElem = srcElem1;
171610037SARM gem5 Developers            unsigned groupSize = ((1 << 1) / sizeof(Element));
171710037SARM gem5 Developers            unsigned reverseMask = (groupSize - 1);
171810037SARM gem5 Developers            j = i ^ reverseMask;
171910037SARM gem5 Developers    '''
172010037SARM gem5 Developers    twoEqualRegInstX("rev16", "Rev16DX", "SimdAluOp", ("uint8_t",), 2,
172110037SARM gem5 Developers                     rev16Code)
172210037SARM gem5 Developers    twoEqualRegInstX("rev16", "Rev16QX", "SimdAluOp", ("uint8_t",), 4,
172310037SARM gem5 Developers                     rev16Code)
172410037SARM gem5 Developers    # REV32
172510037SARM gem5 Developers    rev32Code = '''
172610037SARM gem5 Developers            destElem = srcElem1;
172710037SARM gem5 Developers            unsigned groupSize = ((1 << 2) / sizeof(Element));
172810037SARM gem5 Developers            unsigned reverseMask = (groupSize - 1);
172910037SARM gem5 Developers            j = i ^ reverseMask;
173010037SARM gem5 Developers    '''
173110037SARM gem5 Developers    twoEqualRegInstX("rev32", "Rev32DX", "SimdAluOp", ("uint8_t", "uint16_t"),
173210037SARM gem5 Developers                     2, rev32Code)
173310037SARM gem5 Developers    twoEqualRegInstX("rev32", "Rev32QX", "SimdAluOp", ("uint8_t", "uint16_t"),
173410037SARM gem5 Developers                     4, rev32Code)
173510037SARM gem5 Developers    # REV64
173610037SARM gem5 Developers    rev64Code = '''
173710037SARM gem5 Developers            destElem = srcElem1;
173810037SARM gem5 Developers            unsigned groupSize = ((1 << 3) / sizeof(Element));
173910037SARM gem5 Developers            unsigned reverseMask = (groupSize - 1);
174010037SARM gem5 Developers            j = i ^ reverseMask;
174110037SARM gem5 Developers    '''
174210037SARM gem5 Developers    twoEqualRegInstX("rev64", "Rev64DX", "SimdAluOp", smallUnsignedTypes, 2,
174310037SARM gem5 Developers                     rev64Code)
174410037SARM gem5 Developers    twoEqualRegInstX("rev64", "Rev64QX", "SimdAluOp", smallUnsignedTypes, 4,
174510037SARM gem5 Developers                     rev64Code)
174610037SARM gem5 Developers    # RSHRN, RSHRN2
174710037SARM gem5 Developers    rshrnCode = '''
174810037SARM gem5 Developers            if (imm > sizeof(srcElem1) * 8) {
174910037SARM gem5 Developers                destElem = 0;
175010037SARM gem5 Developers            } else if (imm) {
175110037SARM gem5 Developers                Element rBit = bits(srcElem1, imm - 1);
175210037SARM gem5 Developers                destElem = ((srcElem1 >> (imm - 1)) >> 1) + rBit;
175310037SARM gem5 Developers            } else {
175410037SARM gem5 Developers                destElem = srcElem1;
175510037SARM gem5 Developers            }
175610037SARM gem5 Developers    '''
175710037SARM gem5 Developers    twoRegNarrowInstX("rshrn", "RshrnX", "SimdShiftOp", smallUnsignedTypes,
175810037SARM gem5 Developers                      rshrnCode, hasImm=True)
175910037SARM gem5 Developers    twoRegNarrowInstX("rshrn2", "Rshrn2X", "SimdShiftOp", smallUnsignedTypes,
176010037SARM gem5 Developers                      rshrnCode, hasImm=True, hi=True)
176110037SARM gem5 Developers    # RSUBHN, RSUBHN2
176210037SARM gem5 Developers    rsubhnCode = '''
176310037SARM gem5 Developers            destElem = ((BigElement)srcElem1 - (BigElement)srcElem2 +
176410037SARM gem5 Developers                        ((BigElement)1 << (sizeof(Element) * 8 - 1))) >>
176510037SARM gem5 Developers                       (sizeof(Element) * 8);
176610037SARM gem5 Developers    '''
176710037SARM gem5 Developers    threeRegNarrowInstX("rsubhn", "RsubhnX", "SimdAddOp", smallTypes,
176810037SARM gem5 Developers                        rsubhnCode)
176910037SARM gem5 Developers    threeRegNarrowInstX("rsubhn2", "Rsubhn2X", "SimdAddOp", smallTypes,
177010037SARM gem5 Developers                        rsubhnCode, hi=True)
177110037SARM gem5 Developers    # SABA
177210037SARM gem5 Developers    abaCode = '''
177310037SARM gem5 Developers            destElem += (srcElem1 > srcElem2) ? (srcElem1 - srcElem2) :
177410037SARM gem5 Developers                                                (srcElem2 - srcElem1);
177510037SARM gem5 Developers    '''
177610037SARM gem5 Developers    threeEqualRegInstX("saba", "SabaDX", "SimdAddAccOp", smallSignedTypes, 2,
177710037SARM gem5 Developers                       abaCode, True)
177810037SARM gem5 Developers    threeEqualRegInstX("saba", "SabaQX", "SimdAddAccOp", smallSignedTypes, 4,
177910037SARM gem5 Developers                       abaCode, True)
178010037SARM gem5 Developers    # SABAL, SABAL2
178110037SARM gem5 Developers    abalCode = '''
178210037SARM gem5 Developers            destElem += (srcElem1 > srcElem2) ?
178310037SARM gem5 Developers                ((BigElement)srcElem1 - (BigElement)srcElem2) :
178410037SARM gem5 Developers                ((BigElement)srcElem2 - (BigElement)srcElem1);
178510037SARM gem5 Developers    '''
178610037SARM gem5 Developers    threeRegLongInstX("sabal", "SabalX", "SimdAddAccOp", smallSignedTypes,
178710037SARM gem5 Developers                      abalCode, True)
178810037SARM gem5 Developers    threeRegLongInstX("sabal2", "Sabal2X", "SimdAddAccOp", smallSignedTypes,
178910037SARM gem5 Developers                      abalCode, True, hi=True)
179010037SARM gem5 Developers    # SABD
179110037SARM gem5 Developers    abdCode = '''
179210037SARM gem5 Developers            destElem = (srcElem1 > srcElem2) ? (srcElem1 - srcElem2) :
179310037SARM gem5 Developers                                               (srcElem2 - srcElem1);
179410037SARM gem5 Developers    '''
179510037SARM gem5 Developers    threeEqualRegInstX("sabd", "SabdDX", "SimdAddOp", smallSignedTypes, 2,
179610037SARM gem5 Developers                       abdCode)
179710037SARM gem5 Developers    threeEqualRegInstX("sabd", "SabdQX", "SimdAddOp", smallSignedTypes, 4,
179810037SARM gem5 Developers                       abdCode)
179910037SARM gem5 Developers    # SABDL, SABDL2
180010037SARM gem5 Developers    abdlCode = '''
180110037SARM gem5 Developers            destElem = (srcElem1 > srcElem2) ?
180210037SARM gem5 Developers                ((BigElement)srcElem1 - (BigElement)srcElem2) :
180310037SARM gem5 Developers                ((BigElement)srcElem2 - (BigElement)srcElem1);
180410037SARM gem5 Developers    '''
180510037SARM gem5 Developers    threeRegLongInstX("sabdl", "SabdlX", "SimdAddAccOp", smallSignedTypes,
180610037SARM gem5 Developers                      abdlCode, True)
180710037SARM gem5 Developers    threeRegLongInstX("sabdl2", "Sabdl2X", "SimdAddAccOp", smallSignedTypes,
180810037SARM gem5 Developers                      abdlCode, True, hi=True)
180910037SARM gem5 Developers    # SADALP
181010037SARM gem5 Developers    adalpCode = "destElem += (BigElement)srcElem1 + (BigElement)srcElem2;"
181110037SARM gem5 Developers    twoRegCondenseInstX("sadalp", "SadalpDX", "SimdAddOp", smallSignedTypes, 2,
181210037SARM gem5 Developers                        adalpCode, True)
181310037SARM gem5 Developers    twoRegCondenseInstX("sadalp", "SadalpQX", "SimdAddOp", smallSignedTypes, 4,
181410037SARM gem5 Developers                        adalpCode, True)
181510037SARM gem5 Developers    # SADDL, SADDL2
181610037SARM gem5 Developers    addlwCode = "destElem = (BigElement)srcElem1 + (BigElement)srcElem2;"
181710037SARM gem5 Developers    threeRegLongInstX("saddl", "SaddlX", "SimdAddAccOp", smallSignedTypes,
181810037SARM gem5 Developers                      addlwCode)
181910037SARM gem5 Developers    threeRegLongInstX("saddl2", "Saddl2X", "SimdAddAccOp", smallSignedTypes,
182010037SARM gem5 Developers                      addlwCode, hi=True)
182110037SARM gem5 Developers    # SADDLP
182210037SARM gem5 Developers    twoRegCondenseInstX("saddlp", "SaddlpDX", "SimdAddOp", smallSignedTypes, 2,
182310037SARM gem5 Developers                        addlwCode)
182410037SARM gem5 Developers    twoRegCondenseInstX("saddlp", "SaddlpQX", "SimdAddOp", smallSignedTypes, 4,
182510037SARM gem5 Developers                        addlwCode)
182610037SARM gem5 Developers    # SADDLV
182710037SARM gem5 Developers    # Note: SimdAddOp can be a bit optimistic here
182810037SARM gem5 Developers    addAcrossLongCode = "destElem += (BigElement)srcElem1;"
182910037SARM gem5 Developers    twoRegAcrossInstX("saddlv", "SaddlvDX", "SimdAddOp", ("int8_t", "int16_t"),
183010037SARM gem5 Developers                      2, addAcrossLongCode, long=True)
183110037SARM gem5 Developers    twoRegAcrossInstX("saddlv", "SaddlvQX", "SimdAddOp", ("int8_t", "int16_t"),
183210037SARM gem5 Developers                      4, addAcrossLongCode, long=True)
183310037SARM gem5 Developers    twoRegAcrossInstX("saddlv", "SaddlvBQX", "SimdAddOp", ("int32_t",), 4,
183410037SARM gem5 Developers                      addAcrossLongCode, doubleDest=True, long=True)
183510037SARM gem5 Developers    # SADDW, SADDW2
183610037SARM gem5 Developers    threeRegWideInstX("saddw", "SaddwX", "SimdAddAccOp", smallSignedTypes,
183710037SARM gem5 Developers                      addlwCode)
183810037SARM gem5 Developers    threeRegWideInstX("saddw2", "Saddw2X", "SimdAddAccOp", smallSignedTypes,
183910037SARM gem5 Developers                      addlwCode, hi=True)
184010037SARM gem5 Developers    # SCVTF (fixed-point)
184110037SARM gem5 Developers    scvtfFixedCode = fpOp % ("fplibFixedToFP<Element>((int%d_t) srcElem1, imm,"
184210037SARM gem5 Developers                             " false, FPCRRounding(fpscr), fpscr)")
184310037SARM gem5 Developers    twoEqualRegInstX("scvtf", "ScvtfFixedDX", "SimdCvtOp", smallFloatTypes, 2,
184410037SARM gem5 Developers                     scvtfFixedCode % 32, hasImm=True)
184510037SARM gem5 Developers    twoEqualRegInstX("scvtf", "ScvtfFixedSQX", "SimdCvtOp", smallFloatTypes, 4,
184610037SARM gem5 Developers                     scvtfFixedCode % 32, hasImm=True)
184710037SARM gem5 Developers    twoEqualRegInstX("scvtf", "ScvtfFixedDQX", "SimdCvtOp", ("uint64_t",), 4,
184810037SARM gem5 Developers                     scvtfFixedCode % 64, hasImm=True)
184910037SARM gem5 Developers    twoEqualRegInstX("scvtf", "ScvtfFixedScSX", "SimdCvtOp", smallFloatTypes,
185010037SARM gem5 Developers                     4, scvtfFixedCode % 32, hasImm=True, scalar=True)
185110037SARM gem5 Developers    twoEqualRegInstX("scvtf", "ScvtfFixedScDX", "SimdCvtOp", ("uint64_t",), 4,
185210037SARM gem5 Developers                     scvtfFixedCode % 64, hasImm=True, scalar=True)
185310037SARM gem5 Developers    # SCVTF (integer)
185410037SARM gem5 Developers    scvtfIntCode = fpOp % ("fplibFixedToFP<Element>((int%d_t) srcElem1, 0,"
185510037SARM gem5 Developers                           " false, FPCRRounding(fpscr), fpscr)")
185610037SARM gem5 Developers    twoEqualRegInstX("scvtf", "ScvtfIntDX", "SimdCvtOp", smallFloatTypes, 2,
185710037SARM gem5 Developers                     scvtfIntCode % 32)
185810037SARM gem5 Developers    twoEqualRegInstX("scvtf", "ScvtfIntSQX", "SimdCvtOp", smallFloatTypes, 4,
185910037SARM gem5 Developers                     scvtfIntCode % 32)
186010037SARM gem5 Developers    twoEqualRegInstX("scvtf", "ScvtfIntDQX", "SimdCvtOp", ("uint64_t",), 4,
186110037SARM gem5 Developers                     scvtfIntCode % 64)
186210037SARM gem5 Developers    twoEqualRegInstX("scvtf", "ScvtfIntScSX", "SimdCvtOp", smallFloatTypes, 4,
186310037SARM gem5 Developers                     scvtfIntCode % 32, scalar=True)
186410037SARM gem5 Developers    twoEqualRegInstX("scvtf", "ScvtfIntScDX", "SimdCvtOp", ("uint64_t",), 4,
186510037SARM gem5 Developers                     scvtfIntCode % 64, scalar=True)
186610037SARM gem5 Developers    # SHADD
186710037SARM gem5 Developers    haddCode = '''
186810037SARM gem5 Developers            Element carryBit =
186910037SARM gem5 Developers                (((unsigned)srcElem1 & 0x1) +
187010037SARM gem5 Developers                 ((unsigned)srcElem2 & 0x1)) >> 1;
187110037SARM gem5 Developers            // Use division instead of a shift to ensure the sign extension works
187210037SARM gem5 Developers            // right. The compiler will figure out if it can be a shift. Mask the
187310037SARM gem5 Developers            // inputs so they get truncated correctly.
187410037SARM gem5 Developers            destElem = (((srcElem1 & ~(Element)1) / 2) +
187510037SARM gem5 Developers                        ((srcElem2 & ~(Element)1) / 2)) + carryBit;
187610037SARM gem5 Developers    '''
187710037SARM gem5 Developers    threeEqualRegInstX("shadd", "ShaddDX", "SimdAddOp", smallSignedTypes, 2,
187810037SARM gem5 Developers                       haddCode)
187910037SARM gem5 Developers    threeEqualRegInstX("shadd", "ShaddQX", "SimdAddOp", smallSignedTypes, 4,
188010037SARM gem5 Developers                       haddCode)
188110037SARM gem5 Developers    # SHL
188210037SARM gem5 Developers    shlCode = '''
188310037SARM gem5 Developers            if (imm >= sizeof(Element) * 8)
188410037SARM gem5 Developers                destElem = (srcElem1 << (sizeof(Element) * 8 - 1)) << 1;
188510037SARM gem5 Developers            else
188610037SARM gem5 Developers                destElem = srcElem1 << imm;
188710037SARM gem5 Developers    '''
188810037SARM gem5 Developers    twoEqualRegInstX("shl", "ShlDX", "SimdShiftOp", unsignedTypes, 2, shlCode,
188910037SARM gem5 Developers                     hasImm=True)
189010037SARM gem5 Developers    twoEqualRegInstX("shl", "ShlQX", "SimdShiftOp", unsignedTypes, 4, shlCode,
189110037SARM gem5 Developers                     hasImm=True)
189210037SARM gem5 Developers    # SHLL, SHLL2
189310037SARM gem5 Developers    shllCode = "destElem = ((BigElement)srcElem1) << (sizeof(Element) * 8);"
189410037SARM gem5 Developers    twoRegLongInstX("shll", "ShllX", "SimdShiftOp", smallTypes, shllCode)
189510037SARM gem5 Developers    twoRegLongInstX("shll", "Shll2X", "SimdShiftOp", smallTypes, shllCode,
189610037SARM gem5 Developers                    hi=True)
189710037SARM gem5 Developers    # SHRN, SHRN2
189810037SARM gem5 Developers    shrnCode = '''
189910037SARM gem5 Developers            if (imm >= sizeof(srcElem1) * 8) {
190010037SARM gem5 Developers                destElem = 0;
190110037SARM gem5 Developers            } else {
190210037SARM gem5 Developers                destElem = srcElem1 >> imm;
190310037SARM gem5 Developers            }
190410037SARM gem5 Developers    '''
190510037SARM gem5 Developers    twoRegNarrowInstX("shrn", "ShrnX", "SimdShiftOp", smallUnsignedTypes,
190610037SARM gem5 Developers                      shrnCode, hasImm=True)
190710037SARM gem5 Developers    twoRegNarrowInstX("shrn2", "Shrn2X", "SimdShiftOp", smallUnsignedTypes,
190810037SARM gem5 Developers                      shrnCode, hasImm=True, hi=True)
190910037SARM gem5 Developers    # SHSUB
191010037SARM gem5 Developers    hsubCode = '''
191110037SARM gem5 Developers            Element borrowBit =
191210037SARM gem5 Developers                (((srcElem1 & 0x1) - (srcElem2 & 0x1)) >> 1) & 0x1;
191310037SARM gem5 Developers            // Use division instead of a shift to ensure the sign extension works
191410037SARM gem5 Developers            // right. The compiler will figure out if it can be a shift. Mask the
191510037SARM gem5 Developers            // inputs so they get truncated correctly.
191610037SARM gem5 Developers            destElem = (((srcElem1 & ~(Element)1) / 2) -
191710037SARM gem5 Developers                        ((srcElem2 & ~(Element)1) / 2)) - borrowBit;
191810037SARM gem5 Developers    '''
191910037SARM gem5 Developers    threeEqualRegInstX("shsub", "ShsubDX", "SimdAddOp", smallSignedTypes, 2,
192010037SARM gem5 Developers                       hsubCode)
192110037SARM gem5 Developers    threeEqualRegInstX("shsub", "ShsubQX", "SimdAddOp", smallSignedTypes, 4,
192210037SARM gem5 Developers                       hsubCode)
192310037SARM gem5 Developers    # SLI
192410037SARM gem5 Developers    sliCode = '''
192510037SARM gem5 Developers            if (imm >= sizeof(Element) * 8)
192610037SARM gem5 Developers                destElem = destElem;
192710037SARM gem5 Developers            else
192810037SARM gem5 Developers                destElem = (srcElem1 << imm) | (destElem & mask(imm));
192910037SARM gem5 Developers    '''
193010037SARM gem5 Developers    twoEqualRegInstX("sli", "SliDX", "SimdShiftOp", unsignedTypes, 2, sliCode,
193110037SARM gem5 Developers                     True, hasImm=True)
193210037SARM gem5 Developers    twoEqualRegInstX("sli", "SliQX", "SimdShiftOp", unsignedTypes, 4, sliCode,
193310037SARM gem5 Developers                     True, hasImm=True)
193410037SARM gem5 Developers    # SMAX
193510037SARM gem5 Developers    maxCode = "destElem = (srcElem1 > srcElem2) ? srcElem1 : srcElem2;"
193610037SARM gem5 Developers    threeEqualRegInstX("smax", "SmaxDX", "SimdCmpOp", smallSignedTypes, 2,
193710037SARM gem5 Developers                       maxCode)
193810037SARM gem5 Developers    threeEqualRegInstX("smax", "SmaxQX", "SimdCmpOp", smallSignedTypes, 4,
193910037SARM gem5 Developers                       maxCode)
194010037SARM gem5 Developers    # SMAXP
194110037SARM gem5 Developers    threeEqualRegInstX("smaxp", "SmaxpDX", "SimdCmpOp", smallSignedTypes, 2,
194210037SARM gem5 Developers                       maxCode, pairwise=True)
194310037SARM gem5 Developers    threeEqualRegInstX("smaxp", "SmaxpQX", "SimdCmpOp", smallSignedTypes, 4,
194410037SARM gem5 Developers                       maxCode, pairwise=True)
194510037SARM gem5 Developers    # SMAXV
194610037SARM gem5 Developers    maxAcrossCode = '''
194710037SARM gem5 Developers            if (i == 0 || srcElem1 > destElem)
194810037SARM gem5 Developers                destElem = srcElem1;
194910037SARM gem5 Developers    '''
195010037SARM gem5 Developers    twoRegAcrossInstX("smaxv", "SmaxvDX", "SimdCmpOp", ("int8_t", "int16_t"),
195110037SARM gem5 Developers                      2, maxAcrossCode)
195210037SARM gem5 Developers    twoRegAcrossInstX("smaxv", "SmaxvQX", "SimdCmpOp", smallSignedTypes, 4,
195310037SARM gem5 Developers                      maxAcrossCode)
195410037SARM gem5 Developers    # SMIN
195510037SARM gem5 Developers    minCode = "destElem = (srcElem1 < srcElem2) ? srcElem1 : srcElem2;"
195610037SARM gem5 Developers    threeEqualRegInstX("smin", "SminDX", "SimdCmpOp", smallSignedTypes, 2,
195710037SARM gem5 Developers                       minCode)
195810037SARM gem5 Developers    threeEqualRegInstX("smin", "SminQX", "SimdCmpOp", smallSignedTypes, 4,
195910037SARM gem5 Developers                       minCode)
196010037SARM gem5 Developers    # SMINP
196110037SARM gem5 Developers    threeEqualRegInstX("sminp", "SminpDX", "SimdCmpOp", smallSignedTypes, 2,
196210037SARM gem5 Developers                       minCode, pairwise=True)
196310037SARM gem5 Developers    threeEqualRegInstX("sminp", "SminpQX", "SimdCmpOp", smallSignedTypes, 4,
196410037SARM gem5 Developers                       minCode, pairwise=True)
196510037SARM gem5 Developers    # SMINV
196610037SARM gem5 Developers    minAcrossCode = '''
196710037SARM gem5 Developers            if (i == 0 || srcElem1 < destElem)
196810037SARM gem5 Developers                destElem = srcElem1;
196910037SARM gem5 Developers    '''
197010037SARM gem5 Developers    twoRegAcrossInstX("sminv", "SminvDX", "SimdCmpOp", ("int8_t", "int16_t"),
197110037SARM gem5 Developers                      2, minAcrossCode)
197210037SARM gem5 Developers    twoRegAcrossInstX("sminv", "SminvQX", "SimdCmpOp", smallSignedTypes, 4,
197310037SARM gem5 Developers                      minAcrossCode)
197410197SCurtis.Dunham@arm.com
197510197SCurtis.Dunham@arm.com    split('exec')
197610197SCurtis.Dunham@arm.com
197710037SARM gem5 Developers    # SMLAL, SMLAL2 (by element)
197810037SARM gem5 Developers    mlalCode = "destElem += (BigElement)srcElem1 * (BigElement)srcElem2;"
197910037SARM gem5 Developers    threeRegLongInstX("smlal", "SmlalElemX", "SimdMultAccOp",
198010037SARM gem5 Developers                      ("int16_t", "int32_t"), mlalCode, True, byElem=True)
198110037SARM gem5 Developers    threeRegLongInstX("smlal", "SmlalElem2X", "SimdMultAccOp",
198210037SARM gem5 Developers                      ("int16_t", "int32_t"), mlalCode, True, byElem=True,
198310037SARM gem5 Developers                      hi=True)
198410037SARM gem5 Developers    # SMLAL, SMLAL2 (vector)
198510037SARM gem5 Developers    threeRegLongInstX("smlal", "SmlalX", "SimdMultAccOp", smallSignedTypes,
198610037SARM gem5 Developers                      mlalCode, True)
198710037SARM gem5 Developers    threeRegLongInstX("smlal", "Smlal2X", "SimdMultAccOp", smallSignedTypes,
198810037SARM gem5 Developers                      mlalCode, True, hi=True)
198910037SARM gem5 Developers    # SMLSL, SMLSL2 (by element)
199010037SARM gem5 Developers    mlslCode = "destElem -= (BigElement)srcElem1 * (BigElement)srcElem2;"
199110037SARM gem5 Developers    threeRegLongInstX("smlsl", "SmlslElemX", "SimdMultAccOp", smallSignedTypes,
199210037SARM gem5 Developers                      mlslCode, True, byElem=True)
199310037SARM gem5 Developers    threeRegLongInstX("smlsl", "SmlslElem2X", "SimdMultAccOp",
199410037SARM gem5 Developers                      smallSignedTypes, mlslCode, True, byElem=True, hi=True)
199510037SARM gem5 Developers    # SMLSL, SMLSL2 (vector)
199610037SARM gem5 Developers    threeRegLongInstX("smlsl", "SmlslX", "SimdMultAccOp", smallSignedTypes,
199710037SARM gem5 Developers                      mlslCode, True)
199810037SARM gem5 Developers    threeRegLongInstX("smlsl", "Smlsl2X", "SimdMultAccOp", smallSignedTypes,
199910037SARM gem5 Developers                      mlslCode, True, hi=True)
200010037SARM gem5 Developers    # SMOV
200110037SARM gem5 Developers    insToGprInstX("smov", "SmovWX", "SimdMiscOp", ("int8_t", "int16_t"), 4,
200210037SARM gem5 Developers                  'W', True)
200310037SARM gem5 Developers    insToGprInstX("smov", "SmovXX", "SimdMiscOp", smallSignedTypes, 4, 'X',
200410037SARM gem5 Developers                  True)
200510037SARM gem5 Developers    # SMULL, SMULL2 (by element)
200610037SARM gem5 Developers    mullCode = "destElem = (BigElement)srcElem1 * (BigElement)srcElem2;"
200710037SARM gem5 Developers    threeRegLongInstX("smull", "SmullElemX", "SimdMultOp", smallSignedTypes,
200810037SARM gem5 Developers                      mullCode, byElem=True)
200910037SARM gem5 Developers    threeRegLongInstX("smull", "SmullElem2X", "SimdMultOp", smallSignedTypes,
201010037SARM gem5 Developers                      mullCode, byElem=True, hi=True)
201110037SARM gem5 Developers    # SMULL, SMULL2 (vector)
201210037SARM gem5 Developers    threeRegLongInstX("smull", "SmullX", "SimdMultOp", smallSignedTypes,
201310037SARM gem5 Developers                      mullCode)
201410037SARM gem5 Developers    threeRegLongInstX("smull", "Smull2X", "SimdMultOp", smallSignedTypes,
201510037SARM gem5 Developers                      mullCode, hi=True)
201610037SARM gem5 Developers    # SQABS
201710037SARM gem5 Developers    sqabsCode = '''
201810037SARM gem5 Developers        FPSCR fpscr = (FPSCR) FpscrQc;
201912038Srekai.gonzalezalberquilla@arm.com        if (srcElem1 == (Element)(std::numeric_limits<Element>::min())) {
202010037SARM gem5 Developers            fpscr.qc = 1;
202110037SARM gem5 Developers            destElem = ~srcElem1;
202210037SARM gem5 Developers        } else if (srcElem1 < 0) {
202310037SARM gem5 Developers            destElem = -srcElem1;
202410037SARM gem5 Developers        } else {
202510037SARM gem5 Developers            destElem = srcElem1;
202610037SARM gem5 Developers        }
202710037SARM gem5 Developers        FpscrQc = fpscr;
202810037SARM gem5 Developers    '''
202910037SARM gem5 Developers    twoEqualRegInstX("sqabs", "SqabsDX", "SimdAluOp", smallSignedTypes, 2,
203010037SARM gem5 Developers                     sqabsCode)
203110037SARM gem5 Developers    twoEqualRegInstX("sqabs", "SqabsQX", "SimdAluOp", signedTypes, 4,
203210037SARM gem5 Developers                     sqabsCode)
203310037SARM gem5 Developers    twoEqualRegInstX("sqabs", "SqabsScX", "SimdAluOp", signedTypes, 4,
203410037SARM gem5 Developers                     sqabsCode, scalar=True)
203510037SARM gem5 Developers    # SQADD
203610037SARM gem5 Developers    sqaddCode = '''
203710037SARM gem5 Developers            destElem = srcElem1 + srcElem2;
203810037SARM gem5 Developers            FPSCR fpscr = (FPSCR) FpscrQc;
203910037SARM gem5 Developers            bool negDest = (destElem < 0);
204010037SARM gem5 Developers            bool negSrc1 = (srcElem1 < 0);
204110037SARM gem5 Developers            bool negSrc2 = (srcElem2 < 0);
204210037SARM gem5 Developers            if ((negDest != negSrc1) && (negSrc1 == negSrc2)) {
204312038Srekai.gonzalezalberquilla@arm.com                destElem = std::numeric_limits<Element>::min();
204410037SARM gem5 Developers                if (negDest)
204510037SARM gem5 Developers                    destElem -= 1;
204610037SARM gem5 Developers                fpscr.qc = 1;
204710037SARM gem5 Developers            }
204810037SARM gem5 Developers            FpscrQc = fpscr;
204910037SARM gem5 Developers    '''
205010037SARM gem5 Developers    threeEqualRegInstX("sqadd", "SqaddDX", "SimdAddOp", smallSignedTypes, 2,
205110037SARM gem5 Developers                       sqaddCode)
205210037SARM gem5 Developers    threeEqualRegInstX("sqadd", "SqaddQX", "SimdAddOp", signedTypes, 4,
205310037SARM gem5 Developers                       sqaddCode)
205410037SARM gem5 Developers    threeEqualRegInstX("sqadd", "SqaddScX", "SimdAddOp", signedTypes, 4,
205510037SARM gem5 Developers                       sqaddCode, scalar=True)
205610037SARM gem5 Developers    # SQDMLAL, SQDMLAL2 (by element)
205710037SARM gem5 Developers    qdmlalCode = '''
205810037SARM gem5 Developers        FPSCR fpscr = (FPSCR) FpscrQc;
205910037SARM gem5 Developers        BigElement midElem = (2 * (int64_t)srcElem1 * (int64_t)srcElem2);
206012038Srekai.gonzalezalberquilla@arm.com        Element maxNeg = std::numeric_limits<Element>::min();
206110037SARM gem5 Developers        Element halfNeg = maxNeg / 2;
206210037SARM gem5 Developers        if ((srcElem1 == maxNeg && srcElem2 == maxNeg) ||
206310037SARM gem5 Developers            (srcElem1 == halfNeg && srcElem2 == maxNeg) ||
206410037SARM gem5 Developers            (srcElem1 == maxNeg && srcElem2 == halfNeg)) {
206510037SARM gem5 Developers            midElem = ~((BigElement)maxNeg << (sizeof(Element) * 8));
206610037SARM gem5 Developers            fpscr.qc = 1;
206710037SARM gem5 Developers        }
206810037SARM gem5 Developers        bool negPreDest = ltz(destElem);
206910037SARM gem5 Developers        destElem += midElem;
207010037SARM gem5 Developers        bool negDest = ltz(destElem);
207110037SARM gem5 Developers        bool negMid = ltz(midElem);
207210037SARM gem5 Developers        if (negPreDest == negMid && negMid != negDest) {
207310037SARM gem5 Developers            destElem = mask(sizeof(BigElement) * 8 - 1);
207410037SARM gem5 Developers            if (negPreDest)
207510037SARM gem5 Developers                destElem = ~destElem;
207610037SARM gem5 Developers            fpscr.qc = 1;
207710037SARM gem5 Developers        }
207810037SARM gem5 Developers        FpscrQc = fpscr;
207910037SARM gem5 Developers    '''
208010037SARM gem5 Developers    threeRegLongInstX("sqdmlal", "SqdmlalElemX", "SimdMultAccOp",
208110037SARM gem5 Developers                      ("int16_t", "int32_t"), qdmlalCode, True, byElem=True)
208210037SARM gem5 Developers    threeRegLongInstX("sqdmlal", "SqdmlalElem2X", "SimdMultAccOp",
208310037SARM gem5 Developers                      ("int16_t", "int32_t"), qdmlalCode, True, byElem=True,
208410037SARM gem5 Developers                      hi=True)
208510037SARM gem5 Developers    threeRegLongInstX("sqdmlal", "SqdmlalElemScX", "SimdMultAccOp",
208610037SARM gem5 Developers                      ("int16_t", "int32_t"), qdmlalCode, True, byElem=True,
208710037SARM gem5 Developers                      scalar=True)
208810037SARM gem5 Developers    # SQDMLAL, SQDMLAL2 (vector)
208910037SARM gem5 Developers    threeRegLongInstX("sqdmlal", "SqdmlalX", "SimdMultAccOp",
209010037SARM gem5 Developers                      ("int16_t", "int32_t"), qdmlalCode, True)
209110037SARM gem5 Developers    threeRegLongInstX("sqdmlal", "Sqdmlal2X", "SimdMultAccOp",
209210037SARM gem5 Developers                      ("int16_t", "int32_t"), qdmlalCode, True, hi=True)
209310037SARM gem5 Developers    threeRegLongInstX("sqdmlal", "SqdmlalScX", "SimdMultAccOp",
209410037SARM gem5 Developers                      ("int16_t", "int32_t"), qdmlalCode, True, scalar=True)
209510037SARM gem5 Developers    # SQDMLSL, SQDMLSL2 (by element)
209610037SARM gem5 Developers    qdmlslCode = '''
209710037SARM gem5 Developers        FPSCR fpscr = (FPSCR) FpscrQc;
209810037SARM gem5 Developers        BigElement midElem = (2 * (int64_t)srcElem1 * (int64_t)srcElem2);
209912038Srekai.gonzalezalberquilla@arm.com        Element maxNeg = std::numeric_limits<Element>::min();
210010037SARM gem5 Developers        Element halfNeg = maxNeg / 2;
210110037SARM gem5 Developers        if ((srcElem1 == maxNeg && srcElem2 == maxNeg) ||
210210037SARM gem5 Developers            (srcElem1 == halfNeg && srcElem2 == maxNeg) ||
210310037SARM gem5 Developers            (srcElem1 == maxNeg && srcElem2 == halfNeg)) {
210410037SARM gem5 Developers            midElem = ~((BigElement)maxNeg << (sizeof(Element) * 8));
210510037SARM gem5 Developers            fpscr.qc = 1;
210610037SARM gem5 Developers        }
210710037SARM gem5 Developers        bool negPreDest = ltz(destElem);
210810037SARM gem5 Developers        destElem -= midElem;
210910037SARM gem5 Developers        bool negDest = ltz(destElem);
211010037SARM gem5 Developers        bool posMid = ltz((BigElement)-midElem);
211110037SARM gem5 Developers        if (negPreDest == posMid && posMid != negDest) {
211210037SARM gem5 Developers            destElem = mask(sizeof(BigElement) * 8 - 1);
211310037SARM gem5 Developers            if (negPreDest)
211410037SARM gem5 Developers                destElem = ~destElem;
211510037SARM gem5 Developers            fpscr.qc = 1;
211610037SARM gem5 Developers        }
211710037SARM gem5 Developers        FpscrQc = fpscr;
211810037SARM gem5 Developers    '''
211910037SARM gem5 Developers    threeRegLongInstX("sqdmlsl", "SqdmlslElemX", "SimdMultAccOp",
212010037SARM gem5 Developers                      ("int16_t", "int32_t"), qdmlslCode, True, byElem=True)
212110037SARM gem5 Developers    threeRegLongInstX("sqdmlsl", "SqdmlslElem2X", "SimdMultAccOp",
212210037SARM gem5 Developers                      ("int16_t", "int32_t"), qdmlslCode, True, byElem=True,
212310037SARM gem5 Developers                      hi=True)
212410037SARM gem5 Developers    threeRegLongInstX("sqdmlsl", "SqdmlslElemScX", "SimdMultAccOp",
212510037SARM gem5 Developers                      ("int16_t", "int32_t"), qdmlslCode, True, byElem=True,
212610037SARM gem5 Developers                      scalar=True)
212710037SARM gem5 Developers    # SQDMLSL, SQDMLSL2 (vector)
212810037SARM gem5 Developers    threeRegLongInstX("sqdmlsl", "SqdmlslX", "SimdMultAccOp",
212910037SARM gem5 Developers                      ("int16_t", "int32_t"), qdmlslCode, True)
213010037SARM gem5 Developers    threeRegLongInstX("sqdmlsl", "Sqdmlsl2X", "SimdMultAccOp",
213110037SARM gem5 Developers                      ("int16_t", "int32_t"), qdmlslCode, True, hi=True)
213210037SARM gem5 Developers    threeRegLongInstX("sqdmlsl", "SqdmlslScX", "SimdMultAccOp",
213310037SARM gem5 Developers                      ("int16_t", "int32_t"), qdmlslCode, True, scalar=True)
213410037SARM gem5 Developers    # SQDMULH (by element)
213510037SARM gem5 Developers    sqdmulhCode = '''
213610037SARM gem5 Developers            FPSCR fpscr = (FPSCR) FpscrQc;
213710037SARM gem5 Developers            destElem = (2 * (int64_t)srcElem1 * (int64_t)srcElem2) >>
213810037SARM gem5 Developers                       (sizeof(Element) * 8);
213910037SARM gem5 Developers            if (srcElem1 == srcElem2 &&
214010037SARM gem5 Developers                    srcElem1 == (Element)((Element)1 <<
214110037SARM gem5 Developers                        (sizeof(Element) * 8 - 1))) {
214210037SARM gem5 Developers                destElem = ~srcElem1;
214310037SARM gem5 Developers                fpscr.qc = 1;
214410037SARM gem5 Developers            }
214510037SARM gem5 Developers            FpscrQc = fpscr;
214610037SARM gem5 Developers    '''
214710037SARM gem5 Developers    threeEqualRegInstX("sqdmulh", "SqdmulhElemDX", "SimdMultOp",
214810037SARM gem5 Developers                       ("int16_t", "int32_t"), 2, sqdmulhCode, byElem=True)
214910037SARM gem5 Developers    threeEqualRegInstX("sqdmulh", "SqdmulhElemQX", "SimdMultOp",
215010037SARM gem5 Developers                       ("int16_t", "int32_t"), 4, sqdmulhCode, byElem=True)
215110037SARM gem5 Developers    threeEqualRegInstX("sqdmulh", "SqdmulhElemScX", "SimdMultOp",
215210037SARM gem5 Developers                       ("int16_t", "int32_t"), 4, sqdmulhCode, byElem=True,
215310037SARM gem5 Developers                       scalar=True)
215410037SARM gem5 Developers    # SQDMULH (vector)
215510037SARM gem5 Developers    threeEqualRegInstX("sqdmulh", "SqdmulhDX", "SimdMultOp",
215610037SARM gem5 Developers                       ("int16_t", "int32_t"), 2, sqdmulhCode)
215710037SARM gem5 Developers    threeEqualRegInstX("sqdmulh", "SqdmulhQX", "SimdMultOp",
215810037SARM gem5 Developers                       ("int16_t", "int32_t"), 4, sqdmulhCode)
215910037SARM gem5 Developers    threeEqualRegInstX("sqdmulh", "SqdmulhScX", "SimdMultOp",
216010037SARM gem5 Developers                       ("int16_t", "int32_t"), 4, sqdmulhCode, scalar=True)
216110037SARM gem5 Developers    # SQDMULL, SQDMULL2 (by element)
216210037SARM gem5 Developers    qdmullCode = '''
216310037SARM gem5 Developers        FPSCR fpscr = (FPSCR) FpscrQc;
216410037SARM gem5 Developers        destElem = (2 * (int64_t)srcElem1 * (int64_t)srcElem2);
216510037SARM gem5 Developers        if (srcElem1 == srcElem2 &&
216610037SARM gem5 Developers                srcElem1 == (Element)((Element)1 <<
216710037SARM gem5 Developers                    (Element)(sizeof(Element) * 8 - 1))) {
216810037SARM gem5 Developers            destElem = ~((BigElement)srcElem1 << (sizeof(Element) * 8));
216910037SARM gem5 Developers            fpscr.qc = 1;
217010037SARM gem5 Developers        }
217110037SARM gem5 Developers        FpscrQc = fpscr;
217210037SARM gem5 Developers    '''
217310037SARM gem5 Developers    threeRegLongInstX("sqdmull", "SqdmullElemX", "SimdMultOp",
217410037SARM gem5 Developers                      ("int16_t", "int32_t"), qdmullCode, True, byElem=True)
217510037SARM gem5 Developers    threeRegLongInstX("sqdmull", "SqdmullElem2X", "SimdMultOp",
217610037SARM gem5 Developers                      ("int16_t", "int32_t"), qdmullCode, True, byElem=True,
217710037SARM gem5 Developers                      hi=True)
217810037SARM gem5 Developers    threeRegLongInstX("sqdmull", "SqdmullElemScX", "SimdMultOp",
217910037SARM gem5 Developers                      ("int16_t", "int32_t"), qdmullCode, True, byElem=True,
218010037SARM gem5 Developers                      scalar=True)
218110037SARM gem5 Developers    # SQDMULL, SQDMULL2 (vector)
218210037SARM gem5 Developers    threeRegLongInstX("sqdmull", "SqdmullX", "SimdMultOp",
218310037SARM gem5 Developers                      ("int16_t", "int32_t"), qdmullCode, True)
218410037SARM gem5 Developers    threeRegLongInstX("sqdmull", "Sqdmull2X", "SimdMultOp",
218510037SARM gem5 Developers                      ("int16_t", "int32_t"), qdmullCode, True, hi=True)
218610037SARM gem5 Developers    threeRegLongInstX("sqdmull", "SqdmullScX", "SimdMultOp",
218710037SARM gem5 Developers                      ("int16_t", "int32_t"), qdmullCode, True, scalar=True)
218810037SARM gem5 Developers    # SQNEG
218910037SARM gem5 Developers    sqnegCode = '''
219010037SARM gem5 Developers        FPSCR fpscr = (FPSCR) FpscrQc;
219112038Srekai.gonzalezalberquilla@arm.com        if (srcElem1 == (Element)(std::numeric_limits<Element>::min())) {
219210037SARM gem5 Developers            fpscr.qc = 1;
219310037SARM gem5 Developers            destElem = ~srcElem1;
219410037SARM gem5 Developers        } else {
219510037SARM gem5 Developers            destElem = -srcElem1;
219610037SARM gem5 Developers        }
219710037SARM gem5 Developers        FpscrQc = fpscr;
219810037SARM gem5 Developers    '''
219910037SARM gem5 Developers    twoEqualRegInstX("sqneg", "SqnegDX", "SimdAluOp", smallSignedTypes, 2,
220010037SARM gem5 Developers                     sqnegCode)
220110037SARM gem5 Developers    twoEqualRegInstX("sqneg", "SqnegQX", "SimdAluOp", signedTypes, 4,
220210037SARM gem5 Developers                     sqnegCode)
220310037SARM gem5 Developers    twoEqualRegInstX("sqneg", "SqnegScX", "SimdAluOp", signedTypes, 4,
220410037SARM gem5 Developers                     sqnegCode, scalar=True)
220510037SARM gem5 Developers    # SQRDMULH (by element)
220610037SARM gem5 Developers    sqrdmulhCode = '''
220710037SARM gem5 Developers            FPSCR fpscr = (FPSCR) FpscrQc;
220810037SARM gem5 Developers            destElem = (2 * (int64_t)srcElem1 * (int64_t)srcElem2 +
220910037SARM gem5 Developers                        ((int64_t)1 << (sizeof(Element) * 8 - 1))) >>
221010037SARM gem5 Developers                       (sizeof(Element) * 8);
221112038Srekai.gonzalezalberquilla@arm.com            Element maxNeg = std::numeric_limits<Element>::min();
221210037SARM gem5 Developers            Element halfNeg = maxNeg / 2;
221310037SARM gem5 Developers            if ((srcElem1 == maxNeg && srcElem2 == maxNeg) ||
221410037SARM gem5 Developers                (srcElem1 == halfNeg && srcElem2 == maxNeg) ||
221510037SARM gem5 Developers                (srcElem1 == maxNeg && srcElem2 == halfNeg)) {
221610037SARM gem5 Developers                if (destElem < 0) {
221710037SARM gem5 Developers                    destElem = mask(sizeof(Element) * 8 - 1);
221810037SARM gem5 Developers                } else {
221912038Srekai.gonzalezalberquilla@arm.com                    destElem = std::numeric_limits<Element>::min();
222010037SARM gem5 Developers                }
222110037SARM gem5 Developers                fpscr.qc = 1;
222210037SARM gem5 Developers            }
222310037SARM gem5 Developers            FpscrQc = fpscr;
222410037SARM gem5 Developers    '''
222510037SARM gem5 Developers    threeEqualRegInstX("sqrdmulh", "SqrdmulhElemDX", "SimdMultOp",
222610037SARM gem5 Developers                       ("int16_t", "int32_t"), 2, sqrdmulhCode, byElem=True)
222710037SARM gem5 Developers    threeEqualRegInstX("sqrdmulh", "SqrdmulhElemQX", "SimdMultOp",
222810037SARM gem5 Developers                       ("int16_t", "int32_t"), 4, sqrdmulhCode, byElem=True)
222910037SARM gem5 Developers    threeEqualRegInstX("sqrdmulh", "SqrdmulhElemScX", "SimdMultOp",
223010037SARM gem5 Developers                       ("int16_t", "int32_t"), 4, sqrdmulhCode, byElem=True,
223110037SARM gem5 Developers                       scalar=True)
223210037SARM gem5 Developers    # SQRDMULH (vector)
223310037SARM gem5 Developers    threeEqualRegInstX("sqrdmulh", "SqrdmulhDX", "SimdMultOp",
223410037SARM gem5 Developers                       ("int16_t", "int32_t"), 2, sqrdmulhCode)
223510037SARM gem5 Developers    threeEqualRegInstX("sqrdmulh", "SqrdmulhQX", "SimdMultOp",
223610037SARM gem5 Developers                       ("int16_t", "int32_t"), 4, sqrdmulhCode)
223710037SARM gem5 Developers    threeEqualRegInstX("sqrdmulh", "SqrdmulhScX", "SimdMultOp",
223810037SARM gem5 Developers                       ("int16_t", "int32_t"), 4, sqrdmulhCode, scalar=True)
223910037SARM gem5 Developers    # SQRSHL
224010037SARM gem5 Developers    sqrshlCode = '''
224110037SARM gem5 Developers            int16_t shiftAmt = (int8_t)srcElem2;
224210037SARM gem5 Developers            FPSCR fpscr = (FPSCR) FpscrQc;
224310037SARM gem5 Developers            if (shiftAmt < 0) {
224410037SARM gem5 Developers                shiftAmt = -shiftAmt;
224510037SARM gem5 Developers                Element rBit = 0;
224610037SARM gem5 Developers                if (shiftAmt <= sizeof(Element) * 8)
224710037SARM gem5 Developers                    rBit = bits(srcElem1, shiftAmt - 1);
224810037SARM gem5 Developers                if (shiftAmt > sizeof(Element) * 8 && srcElem1 < 0)
224910037SARM gem5 Developers                    rBit = 1;
225010037SARM gem5 Developers                if (shiftAmt >= sizeof(Element) * 8) {
225110037SARM gem5 Developers                    shiftAmt = sizeof(Element) * 8 - 1;
225210037SARM gem5 Developers                    destElem = 0;
225310037SARM gem5 Developers                } else {
225410037SARM gem5 Developers                    destElem = (srcElem1 >> shiftAmt);
225510037SARM gem5 Developers                }
225610037SARM gem5 Developers                // Make sure the right shift sign extended when it should.
225710037SARM gem5 Developers                if (srcElem1 < 0 && destElem >= 0) {
225810037SARM gem5 Developers                    destElem |= -((Element)1 << (sizeof(Element) * 8 -
225910037SARM gem5 Developers                                                 1 - shiftAmt));
226010037SARM gem5 Developers                }
226110037SARM gem5 Developers                destElem += rBit;
226210037SARM gem5 Developers            } else if (shiftAmt > 0) {
226310037SARM gem5 Developers                bool sat = false;
226410037SARM gem5 Developers                if (shiftAmt >= sizeof(Element) * 8) {
226510037SARM gem5 Developers                    if (srcElem1 != 0)
226610037SARM gem5 Developers                        sat = true;
226710037SARM gem5 Developers                    else
226810037SARM gem5 Developers                        destElem = 0;
226910037SARM gem5 Developers                } else {
227010037SARM gem5 Developers                    if (bits((uint64_t) srcElem1, sizeof(Element) * 8 - 1,
227110037SARM gem5 Developers                                sizeof(Element) * 8 - 1 - shiftAmt) !=
227210037SARM gem5 Developers                            ((srcElem1 < 0) ? mask(shiftAmt + 1) : 0)) {
227310037SARM gem5 Developers                        sat = true;
227410037SARM gem5 Developers                    } else {
227510037SARM gem5 Developers                        destElem = srcElem1 << shiftAmt;
227610037SARM gem5 Developers                    }
227710037SARM gem5 Developers                }
227810037SARM gem5 Developers                if (sat) {
227910037SARM gem5 Developers                    fpscr.qc = 1;
228010037SARM gem5 Developers                    destElem = mask(sizeof(Element) * 8 - 1);
228110037SARM gem5 Developers                    if (srcElem1 < 0)
228210037SARM gem5 Developers                        destElem = ~destElem;
228310037SARM gem5 Developers                }
228410037SARM gem5 Developers            } else {
228510037SARM gem5 Developers                destElem = srcElem1;
228610037SARM gem5 Developers            }
228710037SARM gem5 Developers            FpscrQc = fpscr;
228810037SARM gem5 Developers    '''
228910037SARM gem5 Developers    threeEqualRegInstX("sqrshl", "SqrshlDX", "SimdCmpOp", smallSignedTypes, 2,
229010037SARM gem5 Developers                       sqrshlCode)
229110037SARM gem5 Developers    threeEqualRegInstX("sqrshl", "SqrshlQX", "SimdCmpOp", signedTypes, 4,
229210037SARM gem5 Developers                       sqrshlCode)
229310037SARM gem5 Developers    threeEqualRegInstX("sqrshl", "SqrshlScX", "SimdCmpOp", signedTypes, 4,
229410037SARM gem5 Developers                       sqrshlCode, scalar=True)
229510037SARM gem5 Developers    # SQRSHRN, SQRSHRN2
229610037SARM gem5 Developers    sqrshrnCode = '''
229710037SARM gem5 Developers            FPSCR fpscr = (FPSCR) FpscrQc;
229810037SARM gem5 Developers            if (imm > sizeof(srcElem1) * 8) {
229910037SARM gem5 Developers                if (srcElem1 != 0 && srcElem1 != -1)
230010037SARM gem5 Developers                    fpscr.qc = 1;
230110037SARM gem5 Developers                destElem = 0;
230210037SARM gem5 Developers            } else if (imm) {
230310037SARM gem5 Developers                BigElement mid = (srcElem1 >> (imm - 1));
230410037SARM gem5 Developers                uint64_t rBit = mid & 0x1;
230510037SARM gem5 Developers                mid >>= 1;
230610037SARM gem5 Developers                mid |= -(mid & ((BigElement)1 <<
230710037SARM gem5 Developers                            (sizeof(BigElement) * 8 - 1 - imm)));
230810037SARM gem5 Developers                mid += rBit;
230910037SARM gem5 Developers                if (mid != (Element)mid) {
231010037SARM gem5 Developers                    destElem = mask(sizeof(Element) * 8 - 1);
231110037SARM gem5 Developers                    if (srcElem1 < 0)
231210037SARM gem5 Developers                        destElem = ~destElem;
231310037SARM gem5 Developers                    fpscr.qc = 1;
231410037SARM gem5 Developers                } else {
231510037SARM gem5 Developers                    destElem = mid;
231610037SARM gem5 Developers                }
231710037SARM gem5 Developers            } else {
231810037SARM gem5 Developers                if (srcElem1 != (Element)srcElem1) {
231910037SARM gem5 Developers                    destElem = mask(sizeof(Element) * 8 - 1);
232010037SARM gem5 Developers                    if (srcElem1 < 0)
232110037SARM gem5 Developers                        destElem = ~destElem;
232210037SARM gem5 Developers                    fpscr.qc = 1;
232310037SARM gem5 Developers                } else {
232410037SARM gem5 Developers                    destElem = srcElem1;
232510037SARM gem5 Developers                }
232610037SARM gem5 Developers            }
232710037SARM gem5 Developers            FpscrQc = fpscr;
232810037SARM gem5 Developers    '''
232910037SARM gem5 Developers    twoRegNarrowInstX("sqrshrn", "SqrshrnX", "SimdShiftOp", smallSignedTypes,
233010037SARM gem5 Developers                      sqrshrnCode, hasImm=True)
233110037SARM gem5 Developers    twoRegNarrowInstX("sqrshrn2", "Sqrshrn2X", "SimdShiftOp", smallSignedTypes,
233210037SARM gem5 Developers                      sqrshrnCode, hasImm=True, hi=True)
233310037SARM gem5 Developers    twoRegNarrowInstX("sqrshrn", "SqrshrnScX", "SimdShiftOp", smallSignedTypes,
233410037SARM gem5 Developers                      sqrshrnCode, hasImm=True, scalar=True)
233510037SARM gem5 Developers    # SQRSHRUN, SQRSHRUN2
233610037SARM gem5 Developers    sqrshrunCode = '''
233710037SARM gem5 Developers            FPSCR fpscr = (FPSCR) FpscrQc;
233810037SARM gem5 Developers            if (imm > sizeof(srcElem1) * 8) {
233910037SARM gem5 Developers                if (srcElem1 != 0)
234010037SARM gem5 Developers                    fpscr.qc = 1;
234110037SARM gem5 Developers                destElem = 0;
234210037SARM gem5 Developers            } else if (imm) {
234310037SARM gem5 Developers                BigElement mid = (srcElem1 >> (imm - 1));
234410037SARM gem5 Developers                uint64_t rBit = mid & 0x1;
234510037SARM gem5 Developers                mid >>= 1;
234610037SARM gem5 Developers                mid |= -(mid & ((BigElement)1 <<
234710037SARM gem5 Developers                                (sizeof(BigElement) * 8 - 1 - imm)));
234810037SARM gem5 Developers                mid += rBit;
234910037SARM gem5 Developers                if (bits(mid, sizeof(BigElement) * 8 - 1,
235010037SARM gem5 Developers                              sizeof(Element) * 8) != 0) {
235110037SARM gem5 Developers                    if (srcElem1 < 0) {
235210037SARM gem5 Developers                        destElem = 0;
235310037SARM gem5 Developers                    } else {
235410037SARM gem5 Developers                        destElem = mask(sizeof(Element) * 8);
235510037SARM gem5 Developers                    }
235610037SARM gem5 Developers                    fpscr.qc = 1;
235710037SARM gem5 Developers                } else {
235810037SARM gem5 Developers                    destElem = mid;
235910037SARM gem5 Developers                }
236010037SARM gem5 Developers            } else {
236110037SARM gem5 Developers                if (srcElem1 < 0) {
236210037SARM gem5 Developers                    fpscr.qc = 1;
236310037SARM gem5 Developers                    destElem = 0;
236410037SARM gem5 Developers                } else {
236510037SARM gem5 Developers                    destElem = srcElem1;
236610037SARM gem5 Developers                }
236710037SARM gem5 Developers            }
236810037SARM gem5 Developers            FpscrQc = fpscr;
236910037SARM gem5 Developers    '''
237010037SARM gem5 Developers    twoRegNarrowInstX("sqrshrun", "SqrshrunX", "SimdShiftOp", smallSignedTypes,
237110037SARM gem5 Developers                      sqrshrunCode, hasImm=True)
237210037SARM gem5 Developers    twoRegNarrowInstX("sqrshrun", "Sqrshrun2X", "SimdShiftOp",
237310037SARM gem5 Developers                      smallSignedTypes, sqrshrunCode, hasImm=True, hi=True)
237410037SARM gem5 Developers    twoRegNarrowInstX("sqrshrun", "SqrshrunScX", "SimdShiftOp",
237510037SARM gem5 Developers                      smallSignedTypes, sqrshrunCode, hasImm=True, scalar=True)
237610037SARM gem5 Developers    # SQSHL (immediate)
237710037SARM gem5 Developers    sqshlImmCode = '''
237810037SARM gem5 Developers            FPSCR fpscr = (FPSCR) FpscrQc;
237910037SARM gem5 Developers            if (imm >= sizeof(Element) * 8) {
238010037SARM gem5 Developers                if (srcElem1 != 0) {
238112038Srekai.gonzalezalberquilla@arm.com                    destElem = std::numeric_limits<Element>::min();
238210037SARM gem5 Developers                    if (srcElem1 > 0)
238310037SARM gem5 Developers                        destElem = ~destElem;
238410037SARM gem5 Developers                    fpscr.qc = 1;
238510037SARM gem5 Developers                } else {
238610037SARM gem5 Developers                    destElem = 0;
238710037SARM gem5 Developers                }
238810037SARM gem5 Developers            } else if (imm) {
238910037SARM gem5 Developers                destElem = (srcElem1 << imm);
239010037SARM gem5 Developers                uint64_t topBits = bits((uint64_t)srcElem1,
239110037SARM gem5 Developers                                        sizeof(Element) * 8 - 1,
239210037SARM gem5 Developers                                        sizeof(Element) * 8 - 1 - imm);
239310037SARM gem5 Developers                if (topBits != 0 && topBits != mask(imm + 1)) {
239412038Srekai.gonzalezalberquilla@arm.com                    destElem = std::numeric_limits<Element>::min();
239510037SARM gem5 Developers                    if (srcElem1 > 0)
239610037SARM gem5 Developers                        destElem = ~destElem;
239710037SARM gem5 Developers                    fpscr.qc = 1;
239810037SARM gem5 Developers                }
239910037SARM gem5 Developers            } else {
240010037SARM gem5 Developers                destElem = srcElem1;
240110037SARM gem5 Developers            }
240210037SARM gem5 Developers            FpscrQc = fpscr;
240310037SARM gem5 Developers    '''
240410037SARM gem5 Developers    twoEqualRegInstX("sqshl", "SqshlImmDX", "SimdAluOp", smallSignedTypes, 2,
240510037SARM gem5 Developers                     sqshlImmCode, hasImm=True)
240610037SARM gem5 Developers    twoEqualRegInstX("sqshl", "SqshlImmQX", "SimdAluOp", signedTypes, 4,
240710037SARM gem5 Developers                     sqshlImmCode, hasImm=True)
240810037SARM gem5 Developers    twoEqualRegInstX("sqshl", "SqshlImmScX", "SimdAluOp", signedTypes, 4,
240910037SARM gem5 Developers                     sqshlImmCode, hasImm=True, scalar=True)
241010037SARM gem5 Developers    # SQSHL (register)
241110037SARM gem5 Developers    sqshlCode = '''
241210037SARM gem5 Developers            int16_t shiftAmt = (int8_t)srcElem2;
241310037SARM gem5 Developers            FPSCR fpscr = (FPSCR) FpscrQc;
241410037SARM gem5 Developers            if (shiftAmt < 0) {
241510037SARM gem5 Developers                shiftAmt = -shiftAmt;
241610037SARM gem5 Developers                if (shiftAmt >= sizeof(Element) * 8) {
241710037SARM gem5 Developers                    shiftAmt = sizeof(Element) * 8 - 1;
241810037SARM gem5 Developers                    destElem = 0;
241910037SARM gem5 Developers                } else {
242010037SARM gem5 Developers                    destElem = (srcElem1 >> shiftAmt);
242110037SARM gem5 Developers                }
242210037SARM gem5 Developers                // Make sure the right shift sign extended when it should.
242310037SARM gem5 Developers                if (srcElem1 < 0 && destElem >= 0) {
242410037SARM gem5 Developers                    destElem |= -((Element)1 << (sizeof(Element) * 8 -
242510037SARM gem5 Developers                                                 1 - shiftAmt));
242610037SARM gem5 Developers                }
242710037SARM gem5 Developers            } else if (shiftAmt > 0) {
242810037SARM gem5 Developers                bool sat = false;
242910037SARM gem5 Developers                if (shiftAmt >= sizeof(Element) * 8) {
243010037SARM gem5 Developers                    if (srcElem1 != 0)
243110037SARM gem5 Developers                        sat = true;
243210037SARM gem5 Developers                    else
243310037SARM gem5 Developers                        destElem = 0;
243410037SARM gem5 Developers                } else {
243510037SARM gem5 Developers                    if (bits((uint64_t) srcElem1, sizeof(Element) * 8 - 1,
243610037SARM gem5 Developers                                sizeof(Element) * 8 - 1 - shiftAmt) !=
243710037SARM gem5 Developers                            ((srcElem1 < 0) ? mask(shiftAmt + 1) : 0)) {
243810037SARM gem5 Developers                        sat = true;
243910037SARM gem5 Developers                    } else {
244010037SARM gem5 Developers                        destElem = srcElem1 << shiftAmt;
244110037SARM gem5 Developers                    }
244210037SARM gem5 Developers                }
244310037SARM gem5 Developers                if (sat) {
244410037SARM gem5 Developers                    fpscr.qc = 1;
244510037SARM gem5 Developers                    destElem = mask(sizeof(Element) * 8 - 1);
244610037SARM gem5 Developers                    if (srcElem1 < 0)
244710037SARM gem5 Developers                        destElem = ~destElem;
244810037SARM gem5 Developers                }
244910037SARM gem5 Developers            } else {
245010037SARM gem5 Developers                destElem = srcElem1;
245110037SARM gem5 Developers            }
245210037SARM gem5 Developers            FpscrQc = fpscr;
245310037SARM gem5 Developers    '''
245410037SARM gem5 Developers    threeEqualRegInstX("sqshl", "SqshlDX", "SimdAluOp", smallSignedTypes, 2,
245510037SARM gem5 Developers                       sqshlCode)
245610037SARM gem5 Developers    threeEqualRegInstX("sqshl", "SqshlQX", "SimdAluOp", signedTypes, 4,
245710037SARM gem5 Developers                       sqshlCode)
245810037SARM gem5 Developers    threeEqualRegInstX("sqshl", "SqshlScX", "SimdAluOp", signedTypes, 4,
245910037SARM gem5 Developers                       sqshlCode, scalar=True)
246010037SARM gem5 Developers    # SQSHLU
246110037SARM gem5 Developers    sqshluCode = '''
246210037SARM gem5 Developers            FPSCR fpscr = (FPSCR) FpscrQc;
246310037SARM gem5 Developers            if (imm >= sizeof(Element) * 8) {
246410037SARM gem5 Developers                if (srcElem1 < 0) {
246510037SARM gem5 Developers                    destElem = 0;
246610037SARM gem5 Developers                    fpscr.qc = 1;
246710037SARM gem5 Developers                } else if (srcElem1 > 0) {
246810037SARM gem5 Developers                    destElem = mask(sizeof(Element) * 8);
246910037SARM gem5 Developers                    fpscr.qc = 1;
247010037SARM gem5 Developers                } else {
247110037SARM gem5 Developers                    destElem = 0;
247210037SARM gem5 Developers                }
247310037SARM gem5 Developers            } else if (imm) {
247410037SARM gem5 Developers                destElem = (srcElem1 << imm);
247510037SARM gem5 Developers                uint64_t topBits = bits((uint64_t)srcElem1,
247610037SARM gem5 Developers                                        sizeof(Element) * 8 - 1,
247710037SARM gem5 Developers                                        sizeof(Element) * 8 - imm);
247810037SARM gem5 Developers                if (srcElem1 < 0) {
247910037SARM gem5 Developers                    destElem = 0;
248010037SARM gem5 Developers                    fpscr.qc = 1;
248110037SARM gem5 Developers                } else if (topBits != 0) {
248210037SARM gem5 Developers                    destElem = mask(sizeof(Element) * 8);
248310037SARM gem5 Developers                    fpscr.qc = 1;
248410037SARM gem5 Developers                }
248510037SARM gem5 Developers            } else {
248610037SARM gem5 Developers                if (srcElem1 < 0) {
248710037SARM gem5 Developers                    fpscr.qc = 1;
248810037SARM gem5 Developers                    destElem = 0;
248910037SARM gem5 Developers                } else {
249010037SARM gem5 Developers                    destElem = srcElem1;
249110037SARM gem5 Developers                }
249210037SARM gem5 Developers            }
249310037SARM gem5 Developers            FpscrQc = fpscr;
249410037SARM gem5 Developers    '''
249510037SARM gem5 Developers    twoEqualRegInstX("sqshlu", "SqshluDX", "SimdAluOp", smallSignedTypes, 2,
249610037SARM gem5 Developers                     sqshluCode, hasImm=True)
249710037SARM gem5 Developers    twoEqualRegInstX("sqshlu", "SqshluQX", "SimdAluOp", signedTypes, 4,
249810037SARM gem5 Developers                     sqshluCode, hasImm=True)
249910037SARM gem5 Developers    twoEqualRegInstX("sqshlu", "SqshluScX", "SimdAluOp", signedTypes, 4,
250010037SARM gem5 Developers                     sqshluCode, hasImm=True, scalar=True)
250110037SARM gem5 Developers    # SQSHRN, SQSHRN2
250210037SARM gem5 Developers    sqshrnCode = '''
250310037SARM gem5 Developers        FPSCR fpscr = (FPSCR) FpscrQc;
250410037SARM gem5 Developers        if (imm > sizeof(srcElem1) * 8) {
250510037SARM gem5 Developers            if (srcElem1 != 0 && srcElem1 != -1)
250610037SARM gem5 Developers                fpscr.qc = 1;
250710037SARM gem5 Developers            destElem = 0;
250810037SARM gem5 Developers        } else if (imm) {
250910037SARM gem5 Developers            BigElement mid = ((srcElem1 >> (imm - 1)) >> 1);
251010037SARM gem5 Developers            mid |= -(mid & ((BigElement)1 <<
251110037SARM gem5 Developers                        (sizeof(BigElement) * 8 - 1 - imm)));
251210037SARM gem5 Developers            if (mid != (Element)mid) {
251310037SARM gem5 Developers                destElem = mask(sizeof(Element) * 8 - 1);
251410037SARM gem5 Developers                if (srcElem1 < 0)
251510037SARM gem5 Developers                    destElem = ~destElem;
251610037SARM gem5 Developers                fpscr.qc = 1;
251710037SARM gem5 Developers            } else {
251810037SARM gem5 Developers                destElem = mid;
251910037SARM gem5 Developers            }
252010037SARM gem5 Developers        } else {
252110037SARM gem5 Developers            destElem = srcElem1;
252210037SARM gem5 Developers        }
252310037SARM gem5 Developers        FpscrQc = fpscr;
252410037SARM gem5 Developers    '''
252510037SARM gem5 Developers    twoRegNarrowInstX("sqshrn", "SqshrnX", "SimdShiftOp", smallSignedTypes,
252610037SARM gem5 Developers                      sqshrnCode, hasImm=True)
252710037SARM gem5 Developers    twoRegNarrowInstX("sqshrn2", "Sqshrn2X", "SimdShiftOp", smallSignedTypes,
252810037SARM gem5 Developers                      sqshrnCode, hasImm=True, hi=True)
252910037SARM gem5 Developers    twoRegNarrowInstX("sqshrn", "SqshrnScX", "SimdShiftOp", smallSignedTypes,
253010037SARM gem5 Developers                      sqshrnCode, hasImm=True, scalar=True)
253110037SARM gem5 Developers    # SQSHRUN, SQSHRUN2
253210037SARM gem5 Developers    sqshrunCode = '''
253310037SARM gem5 Developers            FPSCR fpscr = (FPSCR) FpscrQc;
253410037SARM gem5 Developers            if (imm > sizeof(srcElem1) * 8) {
253510037SARM gem5 Developers                if (srcElem1 != 0)
253610037SARM gem5 Developers                    fpscr.qc = 1;
253710037SARM gem5 Developers                destElem = 0;
253810037SARM gem5 Developers            } else if (imm) {
253910037SARM gem5 Developers                BigElement mid = ((srcElem1 >> (imm - 1)) >> 1);
254010037SARM gem5 Developers                if (bits(mid, sizeof(BigElement) * 8 - 1,
254110037SARM gem5 Developers                              sizeof(Element) * 8) != 0) {
254210037SARM gem5 Developers                    if (srcElem1 < 0) {
254310037SARM gem5 Developers                        destElem = 0;
254410037SARM gem5 Developers                    } else {
254510037SARM gem5 Developers                        destElem = mask(sizeof(Element) * 8);
254610037SARM gem5 Developers                    }
254710037SARM gem5 Developers                    fpscr.qc = 1;
254810037SARM gem5 Developers                } else {
254910037SARM gem5 Developers                    destElem = mid;
255010037SARM gem5 Developers                }
255110037SARM gem5 Developers            } else {
255210037SARM gem5 Developers                destElem = srcElem1;
255310037SARM gem5 Developers            }
255410037SARM gem5 Developers            FpscrQc = fpscr;
255510037SARM gem5 Developers    '''
255610037SARM gem5 Developers    twoRegNarrowInstX("sqshrun", "SqshrunX", "SimdShiftOp", smallSignedTypes,
255710037SARM gem5 Developers                      sqshrunCode, hasImm=True)
255810037SARM gem5 Developers    twoRegNarrowInstX("sqshrun", "Sqshrun2X", "SimdShiftOp", smallSignedTypes,
255910037SARM gem5 Developers                      sqshrunCode, hasImm=True, hi=True)
256010037SARM gem5 Developers    twoRegNarrowInstX("sqshrun", "SqshrunScX", "SimdShiftOp", smallSignedTypes,
256110037SARM gem5 Developers                      sqshrunCode, hasImm=True, scalar=True)
256210037SARM gem5 Developers    # SQSUB
256310037SARM gem5 Developers    sqsubCode = '''
256410037SARM gem5 Developers            destElem = srcElem1 - srcElem2;
256510037SARM gem5 Developers            FPSCR fpscr = (FPSCR) FpscrQc;
256610037SARM gem5 Developers            bool negDest = (destElem < 0);
256710037SARM gem5 Developers            bool negSrc1 = (srcElem1 < 0);
256810037SARM gem5 Developers            bool posSrc2 = (srcElem2 >= 0);
256910037SARM gem5 Developers            if ((negDest != negSrc1) && (negSrc1 == posSrc2)) {
257012038Srekai.gonzalezalberquilla@arm.com                destElem = std::numeric_limits<Element>::min();
257110037SARM gem5 Developers                if (negDest)
257210037SARM gem5 Developers                    destElem -= 1;
257310037SARM gem5 Developers                fpscr.qc = 1;
257410037SARM gem5 Developers            }
257510037SARM gem5 Developers            FpscrQc = fpscr;
257610037SARM gem5 Developers    '''
257710037SARM gem5 Developers    threeEqualRegInstX("sqsub", "SqsubDX", "SimdAddOp", smallSignedTypes, 2,
257810037SARM gem5 Developers                       sqsubCode)
257910037SARM gem5 Developers    threeEqualRegInstX("sqsub", "SqsubQX", "SimdAddOp", signedTypes, 4,
258010037SARM gem5 Developers                       sqsubCode)
258110037SARM gem5 Developers    threeEqualRegInstX("sqsub", "SqsubScX", "SimdAddOp", signedTypes, 4,
258210037SARM gem5 Developers                       sqsubCode, scalar=True)
258310037SARM gem5 Developers    # SQXTN, SQXTN2
258410037SARM gem5 Developers    sqxtnCode = '''
258510037SARM gem5 Developers            FPSCR fpscr = (FPSCR) FpscrQc;
258610037SARM gem5 Developers            destElem = srcElem1;
258710037SARM gem5 Developers            if ((BigElement)destElem != srcElem1) {
258810037SARM gem5 Developers                fpscr.qc = 1;
258910037SARM gem5 Developers                destElem = mask(sizeof(Element) * 8 - 1);
259010037SARM gem5 Developers                if (srcElem1 < 0)
259110037SARM gem5 Developers                    destElem = ~destElem;
259210037SARM gem5 Developers            }
259310037SARM gem5 Developers            FpscrQc = fpscr;
259410037SARM gem5 Developers    '''
259510037SARM gem5 Developers    twoRegNarrowInstX("sqxtn", "SqxtnX", "SimdMiscOp", smallSignedTypes,
259610037SARM gem5 Developers                      sqxtnCode)
259710037SARM gem5 Developers    twoRegNarrowInstX("sqxtn", "Sqxtn2X", "SimdMiscOp", smallSignedTypes,
259810037SARM gem5 Developers                      sqxtnCode, hi=True)
259910037SARM gem5 Developers    twoRegNarrowInstX("sqxtn", "SqxtnScX", "SimdMiscOp", smallSignedTypes,
260010037SARM gem5 Developers                      sqxtnCode, scalar=True)
260110037SARM gem5 Developers    # SQXTUN, SQXTUN2
260210037SARM gem5 Developers    sqxtunCode = '''
260310037SARM gem5 Developers            FPSCR fpscr = (FPSCR) FpscrQc;
260410037SARM gem5 Developers            destElem = srcElem1;
260510037SARM gem5 Developers            if (srcElem1 < 0 ||
260610037SARM gem5 Developers                    ((BigElement)destElem & mask(sizeof(Element) * 8)) != srcElem1) {
260710037SARM gem5 Developers                fpscr.qc = 1;
260810037SARM gem5 Developers                destElem = mask(sizeof(Element) * 8);
260910037SARM gem5 Developers                if (srcElem1 < 0)
261010037SARM gem5 Developers                    destElem = ~destElem;
261110037SARM gem5 Developers            }
261210037SARM gem5 Developers            FpscrQc = fpscr;
261310037SARM gem5 Developers    '''
261410037SARM gem5 Developers    twoRegNarrowInstX("sqxtun", "SqxtunX", "SimdMiscOp", smallSignedTypes,
261510037SARM gem5 Developers                      sqxtunCode)
261610037SARM gem5 Developers    twoRegNarrowInstX("sqxtun", "Sqxtun2X", "SimdMiscOp", smallSignedTypes,
261710037SARM gem5 Developers                      sqxtunCode, hi=True)
261810037SARM gem5 Developers    twoRegNarrowInstX("sqxtun", "SqxtunScX", "SimdMiscOp", smallSignedTypes,
261910037SARM gem5 Developers                      sqxtunCode, scalar=True)
262010037SARM gem5 Developers    # SRHADD
262110037SARM gem5 Developers    rhaddCode = '''
262210037SARM gem5 Developers            Element carryBit =
262310037SARM gem5 Developers                (((unsigned)srcElem1 & 0x1) +
262410037SARM gem5 Developers                 ((unsigned)srcElem2 & 0x1) + 1) >> 1;
262510037SARM gem5 Developers            // Use division instead of a shift to ensure the sign extension works
262610037SARM gem5 Developers            // right. The compiler will figure out if it can be a shift. Mask the
262710037SARM gem5 Developers            // inputs so they get truncated correctly.
262810037SARM gem5 Developers            destElem = (((srcElem1 & ~(Element)1) / 2) +
262910037SARM gem5 Developers                        ((srcElem2 & ~(Element)1) / 2)) + carryBit;
263010037SARM gem5 Developers    '''
263110037SARM gem5 Developers    threeEqualRegInstX("srhadd", "SrhaddDX", "SimdAddOp", smallSignedTypes, 2,
263210037SARM gem5 Developers                       rhaddCode)
263310037SARM gem5 Developers    threeEqualRegInstX("srhadd", "SrhaddQX", "SimdAddOp", smallSignedTypes, 4,
263410037SARM gem5 Developers                       rhaddCode)
263510037SARM gem5 Developers    # SRI
263610037SARM gem5 Developers    sriCode = '''
263710037SARM gem5 Developers            if (imm >= sizeof(Element) * 8)
263810037SARM gem5 Developers                destElem = destElem;
263910037SARM gem5 Developers            else
264010037SARM gem5 Developers                destElem = (srcElem1 >> imm) |
264110037SARM gem5 Developers                    (destElem & ~mask(sizeof(Element) * 8 - imm));
264210037SARM gem5 Developers    '''
264310037SARM gem5 Developers    twoEqualRegInstX("sri", "SriDX", "SimdShiftOp", unsignedTypes, 2, sriCode,
264410037SARM gem5 Developers                     True, hasImm=True)
264510037SARM gem5 Developers    twoEqualRegInstX("sri", "SriQX", "SimdShiftOp", unsignedTypes, 4, sriCode,
264610037SARM gem5 Developers                     True, hasImm=True)
264710037SARM gem5 Developers    # SRSHL
264810037SARM gem5 Developers    rshlCode = '''
264910037SARM gem5 Developers            int16_t shiftAmt = (int8_t)srcElem2;
265010037SARM gem5 Developers            if (shiftAmt < 0) {
265110037SARM gem5 Developers                shiftAmt = -shiftAmt;
265210037SARM gem5 Developers                Element rBit = 0;
265310037SARM gem5 Developers                if (shiftAmt <= sizeof(Element) * 8)
265410037SARM gem5 Developers                    rBit = bits(srcElem1, shiftAmt - 1);
265510037SARM gem5 Developers                if (shiftAmt > sizeof(Element) * 8 && ltz(srcElem1))
265610037SARM gem5 Developers                    rBit = 1;
265710037SARM gem5 Developers                if (shiftAmt >= sizeof(Element) * 8) {
265810037SARM gem5 Developers                    shiftAmt = sizeof(Element) * 8 - 1;
265910037SARM gem5 Developers                    destElem = 0;
266010037SARM gem5 Developers                } else {
266110037SARM gem5 Developers                    destElem = (srcElem1 >> shiftAmt);
266210037SARM gem5 Developers                }
266310037SARM gem5 Developers                // Make sure the right shift sign extended when it should.
266410037SARM gem5 Developers                if (ltz(srcElem1) && !ltz(destElem)) {
266510037SARM gem5 Developers                    destElem |= -((Element)1 << (sizeof(Element) * 8 -
266610037SARM gem5 Developers                                                 1 - shiftAmt));
266710037SARM gem5 Developers                }
266810037SARM gem5 Developers                destElem += rBit;
266910037SARM gem5 Developers            } else if (shiftAmt > 0) {
267010037SARM gem5 Developers                if (shiftAmt >= sizeof(Element) * 8) {
267110037SARM gem5 Developers                    destElem = 0;
267210037SARM gem5 Developers                } else {
267310037SARM gem5 Developers                    destElem = srcElem1 << shiftAmt;
267410037SARM gem5 Developers                }
267510037SARM gem5 Developers            } else {
267610037SARM gem5 Developers                destElem = srcElem1;
267710037SARM gem5 Developers            }
267810037SARM gem5 Developers    '''
267910037SARM gem5 Developers    threeEqualRegInstX("srshl", "SrshlDX", "SimdShiftOp", signedTypes, 2,
268010037SARM gem5 Developers                       rshlCode)
268110037SARM gem5 Developers    threeEqualRegInstX("srshl", "SrshlQX", "SimdShiftOp", signedTypes, 4,
268210037SARM gem5 Developers                       rshlCode)
268310037SARM gem5 Developers    # SRSHR
268410037SARM gem5 Developers    rshrCode = '''
268510037SARM gem5 Developers            if (imm > sizeof(srcElem1) * 8) {
268610037SARM gem5 Developers                destElem = 0;
268710037SARM gem5 Developers            } else if (imm) {
268810037SARM gem5 Developers                Element rBit = bits(srcElem1, imm - 1);
268910037SARM gem5 Developers                destElem = ((srcElem1 >> (imm - 1)) >> 1) + rBit;
269010037SARM gem5 Developers            } else {
269110037SARM gem5 Developers                destElem = srcElem1;
269210037SARM gem5 Developers            }
269310037SARM gem5 Developers    '''
269410037SARM gem5 Developers    twoEqualRegInstX("srshr", "SrshrDX", "SimdShiftOp", signedTypes, 2,
269510037SARM gem5 Developers                     rshrCode, hasImm=True)
269610037SARM gem5 Developers    twoEqualRegInstX("srshr", "SrshrQX", "SimdShiftOp", signedTypes, 4,
269710037SARM gem5 Developers                     rshrCode, hasImm=True)
269810037SARM gem5 Developers    # SRSRA
269910037SARM gem5 Developers    rsraCode = '''
270010037SARM gem5 Developers            if (imm > sizeof(srcElem1) * 8) {
270110037SARM gem5 Developers                destElem += 0;
270210037SARM gem5 Developers            } else if (imm) {
270310037SARM gem5 Developers                Element rBit = bits(srcElem1, imm - 1);
270410037SARM gem5 Developers                destElem += ((srcElem1 >> (imm - 1)) >> 1) + rBit;
270510037SARM gem5 Developers            } else {
270610037SARM gem5 Developers                destElem += srcElem1;
270710037SARM gem5 Developers            }
270810037SARM gem5 Developers    '''
270910037SARM gem5 Developers    twoEqualRegInstX("srsra", "SrsraDX", "SimdShiftOp", signedTypes, 2,
271010037SARM gem5 Developers                     rsraCode, True, hasImm=True)
271110037SARM gem5 Developers    twoEqualRegInstX("srsra", "SrsraQX", "SimdShiftOp", signedTypes, 4,
271210037SARM gem5 Developers                     rsraCode, True, hasImm=True)
271310037SARM gem5 Developers    # SSHL
271410037SARM gem5 Developers    shlCode = '''
271510037SARM gem5 Developers            int16_t shiftAmt = (int8_t)srcElem2;
271610037SARM gem5 Developers            if (shiftAmt < 0) {
271710037SARM gem5 Developers                shiftAmt = -shiftAmt;
271810037SARM gem5 Developers                if (shiftAmt >= sizeof(Element) * 8) {
271910037SARM gem5 Developers                    shiftAmt = sizeof(Element) * 8 - 1;
272010037SARM gem5 Developers                    destElem = 0;
272110037SARM gem5 Developers                } else {
272210037SARM gem5 Developers                    destElem = (srcElem1 >> shiftAmt);
272310037SARM gem5 Developers                }
272410037SARM gem5 Developers                // Make sure the right shift sign extended when it should.
272510037SARM gem5 Developers                if (ltz(srcElem1) && !ltz(destElem)) {
272610037SARM gem5 Developers                    destElem |= -((Element)1 << (sizeof(Element) * 8 -
272710037SARM gem5 Developers                                                 1 - shiftAmt));
272810037SARM gem5 Developers                }
272910037SARM gem5 Developers            } else {
273010037SARM gem5 Developers                if (shiftAmt >= sizeof(Element) * 8) {
273110037SARM gem5 Developers                    destElem = 0;
273210037SARM gem5 Developers                } else {
273310037SARM gem5 Developers                    destElem = srcElem1 << shiftAmt;
273410037SARM gem5 Developers                }
273510037SARM gem5 Developers            }
273610037SARM gem5 Developers    '''
273710037SARM gem5 Developers    threeEqualRegInstX("sshl", "SshlDX", "SimdShiftOp", signedTypes, 2,
273810037SARM gem5 Developers                       shlCode)
273910037SARM gem5 Developers    threeEqualRegInstX("sshl", "SshlQX", "SimdShiftOp", signedTypes, 4,
274010037SARM gem5 Developers                       shlCode)
274110037SARM gem5 Developers    # SSHLL, SSHLL2
274210037SARM gem5 Developers    shllCode = '''
274310037SARM gem5 Developers            if (imm >= sizeof(destElem) * 8) {
274410037SARM gem5 Developers                destElem = 0;
274510037SARM gem5 Developers            } else {
274610037SARM gem5 Developers                destElem = (BigElement)srcElem1 << imm;
274710037SARM gem5 Developers            }
274810037SARM gem5 Developers    '''
274910037SARM gem5 Developers    twoRegLongInstX("sshll", "SshllX", "SimdShiftOp", smallSignedTypes,
275010037SARM gem5 Developers                    shllCode, hasImm=True)
275110037SARM gem5 Developers    twoRegLongInstX("sshll", "Sshll2X", "SimdShiftOp", smallSignedTypes,
275210037SARM gem5 Developers                    shllCode, hasImm=True, hi=True)
275310037SARM gem5 Developers    # SSHR
275410037SARM gem5 Developers    shrCode = '''
275510037SARM gem5 Developers            if (imm >= sizeof(srcElem1) * 8) {
275610037SARM gem5 Developers                if (ltz(srcElem1))
275710037SARM gem5 Developers                    destElem = -1;
275810037SARM gem5 Developers                else
275910037SARM gem5 Developers                    destElem = 0;
276010037SARM gem5 Developers            } else {
276110037SARM gem5 Developers                destElem = srcElem1 >> imm;
276210037SARM gem5 Developers            }
276310037SARM gem5 Developers    '''
276410037SARM gem5 Developers    twoEqualRegInstX("sshr", "SshrDX", "SimdShiftOp", signedTypes, 2, shrCode,
276510037SARM gem5 Developers                     hasImm=True)
276610037SARM gem5 Developers    twoEqualRegInstX("sshr", "SshrQX", "SimdShiftOp", signedTypes, 4, shrCode,
276710037SARM gem5 Developers                     hasImm=True)
276810037SARM gem5 Developers    # SSRA
276910037SARM gem5 Developers    sraCode = '''
277010037SARM gem5 Developers            Element mid;;
277110037SARM gem5 Developers            if (imm >= sizeof(srcElem1) * 8) {
277210037SARM gem5 Developers                mid = ltz(srcElem1) ? -1 : 0;
277310037SARM gem5 Developers            } else {
277410037SARM gem5 Developers                mid = srcElem1 >> imm;
277510037SARM gem5 Developers                if (ltz(srcElem1) && !ltz(mid)) {
277610037SARM gem5 Developers                    mid |= -(mid & ((Element)1 <<
277710037SARM gem5 Developers                                    (sizeof(Element) * 8 - 1 - imm)));
277810037SARM gem5 Developers                }
277910037SARM gem5 Developers            }
278010037SARM gem5 Developers            destElem += mid;
278110037SARM gem5 Developers    '''
278210037SARM gem5 Developers    twoEqualRegInstX("ssra", "SsraDX", "SimdShiftOp", signedTypes, 2, sraCode,
278310037SARM gem5 Developers                     True, hasImm=True)
278410037SARM gem5 Developers    twoEqualRegInstX("ssra", "SsraQX", "SimdShiftOp", signedTypes, 4, sraCode,
278510037SARM gem5 Developers                     True, hasImm=True)
278610037SARM gem5 Developers    # SSUBL
278710037SARM gem5 Developers    sublwCode = "destElem = (BigElement)srcElem1 - (BigElement)srcElem2;"
278810037SARM gem5 Developers    threeRegLongInstX("ssubl", "SsublX", "SimdAddOp", smallSignedTypes,
278910037SARM gem5 Developers                      sublwCode)
279010037SARM gem5 Developers    threeRegLongInstX("ssubl2", "Ssubl2X", "SimdAddOp", smallSignedTypes,
279110037SARM gem5 Developers                      sublwCode, hi=True)
279210037SARM gem5 Developers    # SSUBW
279310037SARM gem5 Developers    threeRegWideInstX("ssubw", "SsubwX", "SimdAddOp", smallSignedTypes,
279410037SARM gem5 Developers                      sublwCode)
279510037SARM gem5 Developers    threeRegWideInstX("ssubw2", "Ssubw2X", "SimdAddOp", smallSignedTypes,
279610037SARM gem5 Developers                      sublwCode, hi=True)
279710037SARM gem5 Developers    # SUB
279810037SARM gem5 Developers    subCode = "destElem = srcElem1 - srcElem2;"
279910037SARM gem5 Developers    threeEqualRegInstX("sub", "SubDX", "SimdAddOp", unsignedTypes, 2, subCode)
280010037SARM gem5 Developers    threeEqualRegInstX("sub", "SubQX", "SimdAddOp", unsignedTypes, 4, subCode)
280110037SARM gem5 Developers    # SUBHN, SUBHN2
280210037SARM gem5 Developers    subhnCode = '''
280310037SARM gem5 Developers            destElem = ((BigElement)srcElem1 - (BigElement)srcElem2) >>
280410037SARM gem5 Developers                        (sizeof(Element) * 8);
280510037SARM gem5 Developers    '''
280610037SARM gem5 Developers    threeRegNarrowInstX("subhn", "SubhnX", "SimdAddOp", smallUnsignedTypes,
280710037SARM gem5 Developers                        subhnCode)
280810037SARM gem5 Developers    threeRegNarrowInstX("subhn2", "Subhn2X", "SimdAddOp", smallUnsignedTypes,
280910037SARM gem5 Developers                        subhnCode, hi=True)
281010037SARM gem5 Developers    # SUQADD
281110037SARM gem5 Developers    suqaddCode = '''
281210037SARM gem5 Developers            FPSCR fpscr = (FPSCR) FpscrQc;
281310037SARM gem5 Developers            Element tmp = destElem + srcElem1;
281410037SARM gem5 Developers            if (bits(destElem, sizeof(Element) * 8 - 1) == 0) {
281510037SARM gem5 Developers                if (bits(tmp, sizeof(Element) * 8 - 1) == 1 ||
281610037SARM gem5 Developers                        tmp < srcElem1 || tmp < destElem) {
281710037SARM gem5 Developers                    destElem = (((Element) 1) << (sizeof(Element) * 8 - 1)) - 1;
281810037SARM gem5 Developers                    fpscr.qc = 1;
281910037SARM gem5 Developers                } else {
282010037SARM gem5 Developers                    destElem = tmp;
282110037SARM gem5 Developers                }
282210037SARM gem5 Developers            } else {
282310037SARM gem5 Developers                Element absDestElem = (~destElem) + 1;
282410037SARM gem5 Developers                if (absDestElem < srcElem1) {
282510037SARM gem5 Developers                    // Still check for positive sat., no need to check for negative sat.
282610037SARM gem5 Developers                    if (bits(tmp, sizeof(Element) * 8 - 1) == 1) {
282710037SARM gem5 Developers                        destElem = (((Element) 1) << (sizeof(Element) * 8 - 1)) - 1;
282810037SARM gem5 Developers                        fpscr.qc = 1;
282910037SARM gem5 Developers                    } else {
283010037SARM gem5 Developers                        destElem = tmp;
283110037SARM gem5 Developers                    }
283210037SARM gem5 Developers                } else {
283310037SARM gem5 Developers                    destElem = tmp;
283410037SARM gem5 Developers                }
283510037SARM gem5 Developers            }
283610037SARM gem5 Developers            FpscrQc = fpscr;
283710037SARM gem5 Developers    '''
283810037SARM gem5 Developers    twoEqualRegInstX("suqadd", "SuqaddDX", "SimdAddOp", smallUnsignedTypes, 2,
283910037SARM gem5 Developers                     suqaddCode, True)
284010037SARM gem5 Developers    twoEqualRegInstX("suqadd", "SuqaddQX", "SimdAddOp", unsignedTypes, 4,
284110037SARM gem5 Developers                     suqaddCode, True)
284210037SARM gem5 Developers    twoEqualRegInstX("suqadd", "SuqaddScX", "SimdAddOp", unsignedTypes, 4,
284310037SARM gem5 Developers                     suqaddCode, True, scalar=True)
284410037SARM gem5 Developers    # SXTL -> alias to SSHLL
284510037SARM gem5 Developers    # TBL
284610037SARM gem5 Developers    tbxTblInstX("tbl", "Tbl1DX", "SimdMiscOp", ("uint8_t",), 1, "true", 2)
284710037SARM gem5 Developers    tbxTblInstX("tbl", "Tbl1QX", "SimdMiscOp", ("uint8_t",), 1, "true", 4)
284810037SARM gem5 Developers    tbxTblInstX("tbl", "Tbl2DX", "SimdMiscOp", ("uint8_t",), 2, "true", 2)
284910037SARM gem5 Developers    tbxTblInstX("tbl", "Tbl2QX", "SimdMiscOp", ("uint8_t",), 2, "true", 4)
285010037SARM gem5 Developers    tbxTblInstX("tbl", "Tbl3DX", "SimdMiscOp", ("uint8_t",), 3, "true", 2)
285110037SARM gem5 Developers    tbxTblInstX("tbl", "Tbl3QX", "SimdMiscOp", ("uint8_t",), 3, "true", 4)
285210037SARM gem5 Developers    tbxTblInstX("tbl", "Tbl4DX", "SimdMiscOp", ("uint8_t",), 4, "true", 2)
285310037SARM gem5 Developers    tbxTblInstX("tbl", "Tbl4QX", "SimdMiscOp", ("uint8_t",), 4, "true", 4)
285410037SARM gem5 Developers    # TBX
285510037SARM gem5 Developers    tbxTblInstX("tbx", "Tbx1DX", "SimdMiscOp", ("uint8_t",), 1, "false", 2)
285610037SARM gem5 Developers    tbxTblInstX("tbx", "Tbx1QX", "SimdMiscOp", ("uint8_t",), 1, "false", 4)
285710037SARM gem5 Developers    tbxTblInstX("tbx", "Tbx2DX", "SimdMiscOp", ("uint8_t",), 2, "false", 2)
285810037SARM gem5 Developers    tbxTblInstX("tbx", "Tbx2QX", "SimdMiscOp", ("uint8_t",), 2, "false", 4)
285910037SARM gem5 Developers    tbxTblInstX("tbx", "Tbx3DX", "SimdMiscOp", ("uint8_t",), 3, "false", 2)
286010037SARM gem5 Developers    tbxTblInstX("tbx", "Tbx3QX", "SimdMiscOp", ("uint8_t",), 3, "false", 4)
286110037SARM gem5 Developers    tbxTblInstX("tbx", "Tbx4DX", "SimdMiscOp", ("uint8_t",), 4, "false", 2)
286210037SARM gem5 Developers    tbxTblInstX("tbx", "Tbx4QX", "SimdMiscOp", ("uint8_t",), 4, "false", 4)
286310037SARM gem5 Developers    # TRN1
286410037SARM gem5 Developers    trnCode = '''
286510037SARM gem5 Developers        unsigned part = %s;
286610037SARM gem5 Developers        for (unsigned i = 0; i < eCount / 2; i++) {
286710037SARM gem5 Developers            destReg.elements[2 * i] = srcReg1.elements[2 * i + part];
286810037SARM gem5 Developers            destReg.elements[2 * i + 1] = srcReg2.elements[2 * i + part];
286910037SARM gem5 Developers        }
287010037SARM gem5 Developers    '''
287110037SARM gem5 Developers    threeRegScrambleInstX("trn1", "Trn1DX", "SimdAluOp", smallUnsignedTypes, 2,
287210037SARM gem5 Developers                          trnCode % "0")
287310037SARM gem5 Developers    threeRegScrambleInstX("trn1", "Trn1QX", "SimdAluOp", unsignedTypes, 4,
287410037SARM gem5 Developers                          trnCode % "0")
287510037SARM gem5 Developers    # TRN2
287610037SARM gem5 Developers    threeRegScrambleInstX("trn2", "Trn2DX", "SimdAluOp", smallUnsignedTypes, 2,
287710037SARM gem5 Developers                          trnCode % "1")
287810037SARM gem5 Developers    threeRegScrambleInstX("trn2", "Trn2QX", "SimdAluOp", unsignedTypes, 4,
287910037SARM gem5 Developers                          trnCode % "1")
288010037SARM gem5 Developers    # UABA
288110037SARM gem5 Developers    threeEqualRegInstX("uaba", "UabaDX", "SimdAddAccOp", smallUnsignedTypes, 2,
288210037SARM gem5 Developers                       abaCode, True)
288310037SARM gem5 Developers    threeEqualRegInstX("uaba", "UabaQX", "SimdAddAccOp", smallUnsignedTypes, 4,
288410037SARM gem5 Developers                       abaCode, True)
288510037SARM gem5 Developers    # UABAL, UABAL2
288610037SARM gem5 Developers    threeRegLongInstX("uabal", "UabalX", "SimdAddAccOp", smallUnsignedTypes,
288710037SARM gem5 Developers                      abalCode, True)
288810037SARM gem5 Developers    threeRegLongInstX("uabal2", "Uabal2X", "SimdAddAccOp", smallUnsignedTypes,
288910037SARM gem5 Developers                      abalCode, True, hi=True)
289010037SARM gem5 Developers    # UABD
289110037SARM gem5 Developers    threeEqualRegInstX("uabd", "UabdDX", "SimdAddOp", smallUnsignedTypes, 2,
289210037SARM gem5 Developers                       abdCode)
289310037SARM gem5 Developers    threeEqualRegInstX("uabd", "UabdQX", "SimdAddOp", smallUnsignedTypes, 4,
289410037SARM gem5 Developers                       abdCode)
289510037SARM gem5 Developers    # UABDL, UABDL2
289610037SARM gem5 Developers    threeRegLongInstX("uabdl", "UabdlX", "SimdAddAccOp", smallUnsignedTypes,
289710037SARM gem5 Developers                      abdlCode, True)
289810037SARM gem5 Developers    threeRegLongInstX("uabdl2", "Uabdl2X", "SimdAddAccOp", smallUnsignedTypes,
289910037SARM gem5 Developers                      abdlCode, True, hi=True)
290010037SARM gem5 Developers    # UADALP
290110037SARM gem5 Developers    twoRegCondenseInstX("uadalp", "UadalpDX", "SimdAddOp", smallUnsignedTypes,
290210037SARM gem5 Developers                        2, adalpCode, True)
290310037SARM gem5 Developers    twoRegCondenseInstX("uadalp", "UadalpQX", "SimdAddOp", smallUnsignedTypes,
290410037SARM gem5 Developers                        4, adalpCode, True)
290510037SARM gem5 Developers    # UADDL, UADDL2
290610037SARM gem5 Developers    threeRegLongInstX("uaddl", "UaddlX", "SimdAddAccOp", smallUnsignedTypes,
290710037SARM gem5 Developers                      addlwCode)
290810037SARM gem5 Developers    threeRegLongInstX("uaddl2", "Uaddl2X", "SimdAddAccOp", smallUnsignedTypes,
290910037SARM gem5 Developers                      addlwCode, hi=True)
291010037SARM gem5 Developers    # UADDLP
291110037SARM gem5 Developers    twoRegCondenseInstX("uaddlp", "UaddlpDX", "SimdAddOp", smallUnsignedTypes,
291210037SARM gem5 Developers                        2, addlwCode)
291310037SARM gem5 Developers    twoRegCondenseInstX("uaddlp", "UaddlpQX", "SimdAddOp", smallUnsignedTypes,
291410037SARM gem5 Developers                        4, addlwCode)
291510037SARM gem5 Developers    # UADDLV
291610037SARM gem5 Developers    twoRegAcrossInstX("uaddlv", "UaddlvDX", "SimdAddOp",
291710037SARM gem5 Developers                      ("uint8_t", "uint16_t"), 2, addAcrossLongCode, long=True)
291810037SARM gem5 Developers    twoRegAcrossInstX("uaddlv", "UaddlvQX", "SimdAddOp",
291910037SARM gem5 Developers                      ("uint8_t", "uint16_t"), 4, addAcrossLongCode, long=True)
292010037SARM gem5 Developers    twoRegAcrossInstX("uaddlv", "UaddlvBQX", "SimdAddOp", ("uint32_t",), 4,
292110037SARM gem5 Developers                      addAcrossLongCode, doubleDest=True, long=True)
292210037SARM gem5 Developers    # UADDW
292310037SARM gem5 Developers    threeRegWideInstX("uaddw", "UaddwX", "SimdAddAccOp", smallUnsignedTypes,
292410037SARM gem5 Developers                      addlwCode)
292510037SARM gem5 Developers    threeRegWideInstX("uaddw2", "Uaddw2X", "SimdAddAccOp", smallUnsignedTypes,
292610037SARM gem5 Developers                      addlwCode, hi=True)
292710037SARM gem5 Developers    # UCVTF (fixed-point)
292810037SARM gem5 Developers    ucvtfFixedCode = fpOp % ("fplibFixedToFP<Element>(srcElem1, imm, true,"
292910037SARM gem5 Developers                             " FPCRRounding(fpscr), fpscr)")
293010037SARM gem5 Developers    twoEqualRegInstX("ucvtf", "UcvtfFixedDX", "SimdCvtOp", smallFloatTypes, 2,
293110037SARM gem5 Developers                     ucvtfFixedCode, hasImm=True)
293210037SARM gem5 Developers    twoEqualRegInstX("ucvtf", "UcvtfFixedQX", "SimdCvtOp", floatTypes, 4,
293310037SARM gem5 Developers                     ucvtfFixedCode, hasImm=True)
293410037SARM gem5 Developers    twoEqualRegInstX("ucvtf", "UcvtfFixedScX", "SimdCvtOp", floatTypes, 4,
293510037SARM gem5 Developers                     ucvtfFixedCode, hasImm=True, scalar=True)
293610037SARM gem5 Developers    # UCVTF (integer)
293710037SARM gem5 Developers    ucvtfIntCode = fpOp % ("fplibFixedToFP<Element>(srcElem1, 0, true,"
293810037SARM gem5 Developers                           " FPCRRounding(fpscr), fpscr)")
293910037SARM gem5 Developers    twoEqualRegInstX("ucvtf", "UcvtfIntDX", "SimdCvtOp", smallFloatTypes, 2,
294010037SARM gem5 Developers                     ucvtfIntCode)
294110037SARM gem5 Developers    twoEqualRegInstX("ucvtf", "UcvtfIntQX", "SimdCvtOp", floatTypes, 4,
294210037SARM gem5 Developers                     ucvtfIntCode)
294310037SARM gem5 Developers    twoEqualRegInstX("ucvtf", "UcvtfIntScX", "SimdCvtOp", floatTypes, 4,
294410037SARM gem5 Developers                     ucvtfIntCode, scalar=True)
294510037SARM gem5 Developers    # UHADD
294610037SARM gem5 Developers    threeEqualRegInstX("uhadd", "UhaddDX", "SimdAddOp", smallUnsignedTypes, 2,
294710037SARM gem5 Developers                       haddCode)
294810037SARM gem5 Developers    threeEqualRegInstX("uhadd", "UhaddQX", "SimdAddOp", smallUnsignedTypes, 4,
294910037SARM gem5 Developers                       haddCode)
295010037SARM gem5 Developers    # UHSUB
295110037SARM gem5 Developers    threeEqualRegInstX("uhsub", "UhsubDX", "SimdAddOp", smallUnsignedTypes, 2,
295210037SARM gem5 Developers                       hsubCode)
295310037SARM gem5 Developers    threeEqualRegInstX("uhsub", "UhsubQX", "SimdAddOp", smallUnsignedTypes, 4,
295410037SARM gem5 Developers                       hsubCode)
295510037SARM gem5 Developers    # UMAX
295610037SARM gem5 Developers    threeEqualRegInstX("umax", "UmaxDX", "SimdCmpOp", smallUnsignedTypes, 2,
295710037SARM gem5 Developers                       maxCode)
295810037SARM gem5 Developers    threeEqualRegInstX("umax", "UmaxQX", "SimdCmpOp", smallUnsignedTypes, 4,
295910037SARM gem5 Developers                       maxCode)
296010037SARM gem5 Developers    # UMAXP
296110037SARM gem5 Developers    threeEqualRegInstX("umaxp", "UmaxpDX", "SimdCmpOp", smallUnsignedTypes, 2,
296210037SARM gem5 Developers                       maxCode, pairwise=True)
296310037SARM gem5 Developers    threeEqualRegInstX("umaxp", "UmaxpQX", "SimdCmpOp", smallUnsignedTypes, 4,
296410037SARM gem5 Developers                       maxCode, pairwise=True)
296510037SARM gem5 Developers    # UMAXV
296610037SARM gem5 Developers    twoRegAcrossInstX("umaxv", "UmaxvDX", "SimdCmpOp", ("uint8_t", "uint16_t"),
296710037SARM gem5 Developers                      2, maxAcrossCode)
296810037SARM gem5 Developers    twoRegAcrossInstX("umaxv", "UmaxvQX", "SimdCmpOp", smallUnsignedTypes, 4,
296910037SARM gem5 Developers                      maxAcrossCode)
297010037SARM gem5 Developers    # UMIN
297110037SARM gem5 Developers    threeEqualRegInstX("umin", "UminDX", "SimdCmpOp", smallUnsignedTypes, 2,
297210037SARM gem5 Developers                       minCode)
297310037SARM gem5 Developers    threeEqualRegInstX("umin", "UminQX", "SimdCmpOp", smallUnsignedTypes, 4,
297410037SARM gem5 Developers                       minCode)
297510037SARM gem5 Developers    # UMINP
297610037SARM gem5 Developers    threeEqualRegInstX("uminp", "UminpDX", "SimdCmpOp", smallUnsignedTypes, 2,
297710037SARM gem5 Developers                       minCode, pairwise=True)
297810037SARM gem5 Developers    threeEqualRegInstX("uminp", "UminpQX", "SimdCmpOp", smallUnsignedTypes, 4,
297910037SARM gem5 Developers                       minCode, pairwise=True)
298010037SARM gem5 Developers    # UMINV
298110037SARM gem5 Developers    twoRegAcrossInstX("uminv", "UminvDX", "SimdCmpOp", ("uint8_t", "uint16_t"),
298210037SARM gem5 Developers                      2, minAcrossCode)
298310037SARM gem5 Developers    twoRegAcrossInstX("uminv", "UminvQX", "SimdCmpOp", smallUnsignedTypes, 4,
298410037SARM gem5 Developers                      minAcrossCode)
298510037SARM gem5 Developers    # UMLAL (by element)
298610037SARM gem5 Developers    threeRegLongInstX("umlal", "UmlalElemX", "SimdMultAccOp",
298710037SARM gem5 Developers                      smallUnsignedTypes, mlalCode, True, byElem=True)
298810037SARM gem5 Developers    threeRegLongInstX("umlal", "UmlalElem2X", "SimdMultAccOp",
298910037SARM gem5 Developers                      smallUnsignedTypes, mlalCode, True, byElem=True, hi=True)
299010037SARM gem5 Developers    # UMLAL (vector)
299110037SARM gem5 Developers    threeRegLongInstX("umlal", "UmlalX", "SimdMultAccOp", smallUnsignedTypes,
299210037SARM gem5 Developers                      mlalCode, True)
299310037SARM gem5 Developers    threeRegLongInstX("umlal", "Umlal2X", "SimdMultAccOp", smallUnsignedTypes,
299410037SARM gem5 Developers                      mlalCode, True, hi=True)
299510037SARM gem5 Developers    # UMLSL (by element)
299610037SARM gem5 Developers    threeRegLongInstX("umlsl", "UmlslElemX", "SimdMultAccOp",
299710037SARM gem5 Developers                      smallUnsignedTypes, mlslCode, True, byElem=True)
299810037SARM gem5 Developers    threeRegLongInstX("umlsl", "UmlslElem2X", "SimdMultAccOp",
299910037SARM gem5 Developers                      smallUnsignedTypes, mlslCode, True, byElem=True, hi=True)
300010037SARM gem5 Developers    # UMLSL (vector)
300110037SARM gem5 Developers    threeRegLongInstX("umlsl", "UmlslX", "SimdMultAccOp", smallUnsignedTypes,
300210037SARM gem5 Developers                      mlslCode, True)
300310037SARM gem5 Developers    threeRegLongInstX("umlsl", "Umlsl2X", "SimdMultAccOp", smallUnsignedTypes,
300410037SARM gem5 Developers                      mlslCode, True, hi=True)
300510037SARM gem5 Developers    # UMOV
300610037SARM gem5 Developers    insToGprInstX("umov", "UmovWX", "SimdMiscOp", smallUnsignedTypes, 4, 'W')
300710037SARM gem5 Developers    insToGprInstX("umov", "UmovXX", "SimdMiscOp", ("uint64_t",), 4, 'X')
300810037SARM gem5 Developers    # UMULL, UMULL2 (by element)
300910037SARM gem5 Developers    threeRegLongInstX("umull", "UmullElemX", "SimdMultOp", smallUnsignedTypes,
301010037SARM gem5 Developers                      mullCode, byElem=True)
301110037SARM gem5 Developers    threeRegLongInstX("umull", "UmullElem2X", "SimdMultOp", smallUnsignedTypes,
301210037SARM gem5 Developers                      mullCode, byElem=True, hi=True)
301310037SARM gem5 Developers    # UMULL, UMULL2 (vector)
301410037SARM gem5 Developers    threeRegLongInstX("umull", "UmullX", "SimdMultOp", smallUnsignedTypes,
301510037SARM gem5 Developers                      mullCode)
301610037SARM gem5 Developers    threeRegLongInstX("umull", "Umull2X", "SimdMultOp", smallUnsignedTypes,
301710037SARM gem5 Developers                      mullCode, hi=True)
301810037SARM gem5 Developers    # UQADD
301910037SARM gem5 Developers    uqaddCode = '''
302010037SARM gem5 Developers            destElem = srcElem1 + srcElem2;
302110037SARM gem5 Developers            FPSCR fpscr = (FPSCR) FpscrQc;
302210037SARM gem5 Developers            if (destElem < srcElem1 || destElem < srcElem2) {
302310037SARM gem5 Developers                destElem = (Element)(-1);
302410037SARM gem5 Developers                fpscr.qc = 1;
302510037SARM gem5 Developers            }
302610037SARM gem5 Developers            FpscrQc = fpscr;
302710037SARM gem5 Developers    '''
302810037SARM gem5 Developers    threeEqualRegInstX("uqadd", "UqaddDX", "SimdAddOp", smallUnsignedTypes, 2,
302910037SARM gem5 Developers                       uqaddCode)
303010037SARM gem5 Developers    threeEqualRegInstX("uqadd", "UqaddQX", "SimdAddOp", unsignedTypes, 4,
303110037SARM gem5 Developers                       uqaddCode)
303210037SARM gem5 Developers    threeEqualRegInstX("uqadd", "UqaddScX", "SimdAddOp", unsignedTypes, 4,
303310037SARM gem5 Developers                       uqaddCode, scalar=True)
303410037SARM gem5 Developers    # UQRSHL
303510037SARM gem5 Developers    uqrshlCode = '''
303610037SARM gem5 Developers            int16_t shiftAmt = (int8_t)srcElem2;
303710037SARM gem5 Developers            FPSCR fpscr = (FPSCR) FpscrQc;
303810037SARM gem5 Developers            if (shiftAmt < 0) {
303910037SARM gem5 Developers                shiftAmt = -shiftAmt;
304010037SARM gem5 Developers                Element rBit = 0;
304110037SARM gem5 Developers                if (shiftAmt <= sizeof(Element) * 8)
304210037SARM gem5 Developers                    rBit = bits(srcElem1, shiftAmt - 1);
304310037SARM gem5 Developers                if (shiftAmt >= sizeof(Element) * 8) {
304410037SARM gem5 Developers                    shiftAmt = sizeof(Element) * 8 - 1;
304510037SARM gem5 Developers                    destElem = 0;
304610037SARM gem5 Developers                } else {
304710037SARM gem5 Developers                    destElem = (srcElem1 >> shiftAmt);
304810037SARM gem5 Developers                }
304910037SARM gem5 Developers                destElem += rBit;
305010037SARM gem5 Developers            } else {
305110037SARM gem5 Developers                if (shiftAmt >= sizeof(Element) * 8) {
305210037SARM gem5 Developers                    if (srcElem1 != 0) {
305310037SARM gem5 Developers                        destElem = mask(sizeof(Element) * 8);
305410037SARM gem5 Developers                        fpscr.qc = 1;
305510037SARM gem5 Developers                    } else {
305610037SARM gem5 Developers                        destElem = 0;
305710037SARM gem5 Developers                    }
305810037SARM gem5 Developers                } else {
305910037SARM gem5 Developers                    if (bits(srcElem1, sizeof(Element) * 8 - 1,
306010037SARM gem5 Developers                                sizeof(Element) * 8 - shiftAmt)) {
306110037SARM gem5 Developers                        destElem = mask(sizeof(Element) * 8);
306210037SARM gem5 Developers                        fpscr.qc = 1;
306310037SARM gem5 Developers                    } else {
306410037SARM gem5 Developers                        destElem = srcElem1 << shiftAmt;
306510037SARM gem5 Developers                    }
306610037SARM gem5 Developers                }
306710037SARM gem5 Developers            }
306810037SARM gem5 Developers            FpscrQc = fpscr;
306910037SARM gem5 Developers    '''
307010037SARM gem5 Developers    threeEqualRegInstX("uqrshl", "UqrshlDX", "SimdCmpOp", smallUnsignedTypes,
307110037SARM gem5 Developers                       2, uqrshlCode)
307210037SARM gem5 Developers    threeEqualRegInstX("uqrshl", "UqrshlQX", "SimdCmpOp", unsignedTypes, 4,
307310037SARM gem5 Developers                       uqrshlCode)
307410037SARM gem5 Developers    threeEqualRegInstX("uqrshl", "UqrshlScX", "SimdCmpOp", unsignedTypes, 4,
307510037SARM gem5 Developers                       uqrshlCode, scalar=True)
307610037SARM gem5 Developers    # UQRSHRN
307710037SARM gem5 Developers    uqrshrnCode = '''
307810037SARM gem5 Developers            FPSCR fpscr = (FPSCR) FpscrQc;
307910037SARM gem5 Developers            if (imm > sizeof(srcElem1) * 8) {
308010037SARM gem5 Developers                if (srcElem1 != 0)
308110037SARM gem5 Developers                    fpscr.qc = 1;
308210037SARM gem5 Developers                destElem = 0;
308310037SARM gem5 Developers            } else if (imm) {
308410037SARM gem5 Developers                BigElement mid = (srcElem1 >> (imm - 1));
308510037SARM gem5 Developers                uint64_t rBit = mid & 0x1;
308610037SARM gem5 Developers                mid >>= 1;
308710037SARM gem5 Developers                mid += rBit;
308810037SARM gem5 Developers                if (mid != (Element)mid) {
308910037SARM gem5 Developers                    destElem = mask(sizeof(Element) * 8);
309010037SARM gem5 Developers                    fpscr.qc = 1;
309110037SARM gem5 Developers                } else {
309210037SARM gem5 Developers                    destElem = mid;
309310037SARM gem5 Developers                }
309410037SARM gem5 Developers            } else {
309510037SARM gem5 Developers                if (srcElem1 != (Element)srcElem1) {
309610037SARM gem5 Developers                    destElem = mask(sizeof(Element) * 8 - 1);
309710037SARM gem5 Developers                    fpscr.qc = 1;
309810037SARM gem5 Developers                } else {
309910037SARM gem5 Developers                    destElem = srcElem1;
310010037SARM gem5 Developers                }
310110037SARM gem5 Developers            }
310210037SARM gem5 Developers            FpscrQc = fpscr;
310310037SARM gem5 Developers    '''
310410037SARM gem5 Developers    twoRegNarrowInstX("uqrshrn", "UqrshrnX", "SimdShiftOp", smallUnsignedTypes,
310510037SARM gem5 Developers                      uqrshrnCode, hasImm=True)
310610037SARM gem5 Developers    twoRegNarrowInstX("uqrshrn2", "Uqrshrn2X", "SimdShiftOp",
310710037SARM gem5 Developers                      smallUnsignedTypes, uqrshrnCode, hasImm=True, hi=True)
310810037SARM gem5 Developers    twoRegNarrowInstX("uqrshrn", "UqrshrnScX", "SimdShiftOp",
310910037SARM gem5 Developers                      smallUnsignedTypes, uqrshrnCode, hasImm=True,
311010037SARM gem5 Developers                      scalar=True)
311110037SARM gem5 Developers    # UQSHL (immediate)
311210037SARM gem5 Developers    uqshlImmCode = '''
311310037SARM gem5 Developers            FPSCR fpscr = (FPSCR) FpscrQc;
311410037SARM gem5 Developers            if (imm >= sizeof(Element) * 8) {
311510037SARM gem5 Developers                if (srcElem1 != 0) {
311610037SARM gem5 Developers                    destElem = mask(sizeof(Element) * 8);
311710037SARM gem5 Developers                    fpscr.qc = 1;
311810037SARM gem5 Developers                } else {
311910037SARM gem5 Developers                    destElem = 0;
312010037SARM gem5 Developers                }
312110037SARM gem5 Developers            } else if (imm) {
312210037SARM gem5 Developers                destElem = (srcElem1 << imm);
312310037SARM gem5 Developers                uint64_t topBits = bits((uint64_t)srcElem1,
312410037SARM gem5 Developers                                        sizeof(Element) * 8 - 1,
312510037SARM gem5 Developers                                        sizeof(Element) * 8 - imm);
312610037SARM gem5 Developers                if (topBits != 0) {
312710037SARM gem5 Developers                    destElem = mask(sizeof(Element) * 8);
312810037SARM gem5 Developers                    fpscr.qc = 1;
312910037SARM gem5 Developers                }
313010037SARM gem5 Developers            } else {
313110037SARM gem5 Developers                destElem = srcElem1;
313210037SARM gem5 Developers            }
313310037SARM gem5 Developers            FpscrQc = fpscr;
313410037SARM gem5 Developers    '''
313510037SARM gem5 Developers    twoEqualRegInstX("uqshl", "UqshlImmDX", "SimdAluOp", smallUnsignedTypes, 2,
313610037SARM gem5 Developers                     uqshlImmCode, hasImm=True)
313710037SARM gem5 Developers    twoEqualRegInstX("uqshl", "UqshlImmQX", "SimdAluOp", unsignedTypes, 4,
313810037SARM gem5 Developers                     uqshlImmCode, hasImm=True)
313910037SARM gem5 Developers    twoEqualRegInstX("uqshl", "UqshlImmScX", "SimdAluOp", unsignedTypes, 4,
314010037SARM gem5 Developers                     uqshlImmCode, hasImm=True, scalar=True)
314110037SARM gem5 Developers    # UQSHL (register)
314210037SARM gem5 Developers    uqshlCode = '''
314310037SARM gem5 Developers            int16_t shiftAmt = (int8_t)srcElem2;
314410037SARM gem5 Developers            FPSCR fpscr = (FPSCR) FpscrQc;
314510037SARM gem5 Developers            if (shiftAmt < 0) {
314610037SARM gem5 Developers                shiftAmt = -shiftAmt;
314710037SARM gem5 Developers                if (shiftAmt >= sizeof(Element) * 8) {
314810037SARM gem5 Developers                    shiftAmt = sizeof(Element) * 8 - 1;
314910037SARM gem5 Developers                    destElem = 0;
315010037SARM gem5 Developers                } else {
315110037SARM gem5 Developers                    destElem = (srcElem1 >> shiftAmt);
315210037SARM gem5 Developers                }
315310037SARM gem5 Developers            } else if (shiftAmt > 0) {
315410037SARM gem5 Developers                if (shiftAmt >= sizeof(Element) * 8) {
315510037SARM gem5 Developers                    if (srcElem1 != 0) {
315610037SARM gem5 Developers                        destElem = mask(sizeof(Element) * 8);
315710037SARM gem5 Developers                        fpscr.qc = 1;
315810037SARM gem5 Developers                    } else {
315910037SARM gem5 Developers                        destElem = 0;
316010037SARM gem5 Developers                    }
316110037SARM gem5 Developers                } else {
316210037SARM gem5 Developers                    if (bits(srcElem1, sizeof(Element) * 8 - 1,
316310037SARM gem5 Developers                                sizeof(Element) * 8 - shiftAmt)) {
316410037SARM gem5 Developers                        destElem = mask(sizeof(Element) * 8);
316510037SARM gem5 Developers                        fpscr.qc = 1;
316610037SARM gem5 Developers                    } else {
316710037SARM gem5 Developers                        destElem = srcElem1 << shiftAmt;
316810037SARM gem5 Developers                    }
316910037SARM gem5 Developers                }
317010037SARM gem5 Developers            } else {
317110037SARM gem5 Developers                destElem = srcElem1;
317210037SARM gem5 Developers            }
317310037SARM gem5 Developers            FpscrQc = fpscr;
317410037SARM gem5 Developers    '''
317510037SARM gem5 Developers    threeEqualRegInstX("uqshl", "UqshlDX", "SimdAluOp", smallUnsignedTypes, 2,
317610037SARM gem5 Developers                       uqshlCode)
317710037SARM gem5 Developers    threeEqualRegInstX("uqshl", "UqshlQX", "SimdAluOp", unsignedTypes, 4,
317810037SARM gem5 Developers                       uqshlCode)
317910037SARM gem5 Developers    threeEqualRegInstX("uqshl", "UqshlScX", "SimdAluOp", unsignedTypes, 4,
318010037SARM gem5 Developers                       uqshlCode, scalar=True)
318110037SARM gem5 Developers    # UQSHRN, UQSHRN2
318210037SARM gem5 Developers    uqshrnCode = '''
318310037SARM gem5 Developers            FPSCR fpscr = (FPSCR) FpscrQc;
318410037SARM gem5 Developers            if (imm > sizeof(srcElem1) * 8) {
318510037SARM gem5 Developers                if (srcElem1 != 0)
318610037SARM gem5 Developers                    fpscr.qc = 1;
318710037SARM gem5 Developers                destElem = 0;
318810037SARM gem5 Developers            } else if (imm) {
318910037SARM gem5 Developers                BigElement mid = ((srcElem1 >> (imm - 1)) >> 1);
319010037SARM gem5 Developers                if (mid != (Element)mid) {
319110037SARM gem5 Developers                    destElem = mask(sizeof(Element) * 8);
319210037SARM gem5 Developers                    fpscr.qc = 1;
319310037SARM gem5 Developers                } else {
319410037SARM gem5 Developers                    destElem = mid;
319510037SARM gem5 Developers                }
319610037SARM gem5 Developers            } else {
319710037SARM gem5 Developers                destElem = srcElem1;
319810037SARM gem5 Developers            }
319910037SARM gem5 Developers            FpscrQc = fpscr;
320010037SARM gem5 Developers    '''
320110037SARM gem5 Developers    twoRegNarrowInstX("uqshrn", "UqshrnX", "SimdShiftOp", smallUnsignedTypes,
320210037SARM gem5 Developers                      uqshrnCode, hasImm=True)
320310037SARM gem5 Developers    twoRegNarrowInstX("uqshrn2", "Uqshrn2X", "SimdShiftOp", smallUnsignedTypes,
320410037SARM gem5 Developers                      uqshrnCode, hasImm=True, hi=True)
320510037SARM gem5 Developers    twoRegNarrowInstX("uqshrn", "UqshrnScX", "SimdShiftOp", smallUnsignedTypes,
320610037SARM gem5 Developers                      uqshrnCode, hasImm=True, scalar=True)
320710037SARM gem5 Developers    # UQSUB
320810037SARM gem5 Developers    uqsubCode = '''
320910037SARM gem5 Developers            destElem = srcElem1 - srcElem2;
321010037SARM gem5 Developers            FPSCR fpscr = (FPSCR) FpscrQc;
321110037SARM gem5 Developers            if (destElem > srcElem1) {
321210037SARM gem5 Developers                destElem = 0;
321310037SARM gem5 Developers                fpscr.qc = 1;
321410037SARM gem5 Developers            }
321510037SARM gem5 Developers            FpscrQc = fpscr;
321610037SARM gem5 Developers    '''
321710037SARM gem5 Developers    threeEqualRegInstX("uqsub", "UqsubDX", "SimdAddOp", smallUnsignedTypes, 2,
321810037SARM gem5 Developers                       uqsubCode)
321910037SARM gem5 Developers    threeEqualRegInstX("uqsub", "UqsubQX", "SimdAddOp", unsignedTypes, 4,
322010037SARM gem5 Developers                       uqsubCode)
322110037SARM gem5 Developers    threeEqualRegInstX("uqsub", "UqsubScX", "SimdAddOp", unsignedTypes, 4,
322210037SARM gem5 Developers                       uqsubCode, scalar=True)
322310037SARM gem5 Developers    # UQXTN
322410037SARM gem5 Developers    uqxtnCode = '''
322510037SARM gem5 Developers            FPSCR fpscr = (FPSCR) FpscrQc;
322610037SARM gem5 Developers            destElem = srcElem1;
322710037SARM gem5 Developers            if ((BigElement)destElem != srcElem1) {
322810037SARM gem5 Developers                fpscr.qc = 1;
322910037SARM gem5 Developers                destElem = mask(sizeof(Element) * 8);
323010037SARM gem5 Developers            }
323110037SARM gem5 Developers            FpscrQc = fpscr;
323210037SARM gem5 Developers    '''
323310037SARM gem5 Developers    twoRegNarrowInstX("uqxtn", "UqxtnX", "SimdMiscOp", smallUnsignedTypes,
323410037SARM gem5 Developers                      uqxtnCode)
323510037SARM gem5 Developers    twoRegNarrowInstX("uqxtn", "Uqxtn2X", "SimdMiscOp", smallUnsignedTypes,
323610037SARM gem5 Developers                      uqxtnCode, hi=True)
323710037SARM gem5 Developers    twoRegNarrowInstX("uqxtn", "UqxtnScX", "SimdMiscOp", smallUnsignedTypes,
323810037SARM gem5 Developers                      uqxtnCode, scalar=True)
323910037SARM gem5 Developers    # URECPE
324010037SARM gem5 Developers    urecpeCode = "destElem = unsignedRecipEstimate(srcElem1);"
324110037SARM gem5 Developers    twoEqualRegInstX("urecpe", "UrecpeDX", "SimdMultAccOp", ("uint32_t",), 2,
324210037SARM gem5 Developers                     urecpeCode)
324310037SARM gem5 Developers    twoEqualRegInstX("urecpe", "UrecpeQX", "SimdMultAccOp", ("uint32_t",), 4,
324410037SARM gem5 Developers                     urecpeCode)
324510037SARM gem5 Developers    # URHADD
324610037SARM gem5 Developers    threeEqualRegInstX("urhadd", "UrhaddDX", "SimdAddOp", smallUnsignedTypes,
324710037SARM gem5 Developers                       2, rhaddCode)
324810037SARM gem5 Developers    threeEqualRegInstX("urhadd", "UrhaddQX", "SimdAddOp", smallUnsignedTypes,
324910037SARM gem5 Developers                       4, rhaddCode)
325010037SARM gem5 Developers    # URSHL
325110037SARM gem5 Developers    threeEqualRegInstX("urshl", "UrshlDX", "SimdShiftOp", unsignedTypes, 2,
325210037SARM gem5 Developers                       rshlCode)
325310037SARM gem5 Developers    threeEqualRegInstX("urshl", "UrshlQX", "SimdShiftOp", unsignedTypes, 4,
325410037SARM gem5 Developers                       rshlCode)
325510037SARM gem5 Developers    # URSHR
325610037SARM gem5 Developers    twoEqualRegInstX("urshr", "UrshrDX", "SimdShiftOp", unsignedTypes, 2,
325710037SARM gem5 Developers                     rshrCode, hasImm=True)
325810037SARM gem5 Developers    twoEqualRegInstX("urshr", "UrshrQX", "SimdShiftOp", unsignedTypes, 4,
325910037SARM gem5 Developers                     rshrCode, hasImm=True)
326010037SARM gem5 Developers    # URSQRTE
326110037SARM gem5 Developers    ursqrteCode = "destElem = unsignedRSqrtEstimate(srcElem1);"
326210037SARM gem5 Developers    twoEqualRegInstX("ursqrte", "UrsqrteDX", "SimdSqrtOp", ("uint32_t",), 2,
326310037SARM gem5 Developers                     ursqrteCode)
326410037SARM gem5 Developers    twoEqualRegInstX("ursqrte", "UrsqrteQX", "SimdSqrtOp", ("uint32_t",), 4,
326510037SARM gem5 Developers                     ursqrteCode)
326610037SARM gem5 Developers    # URSRA
326710037SARM gem5 Developers    twoEqualRegInstX("ursra", "UrsraDX", "SimdShiftOp", unsignedTypes, 2,
326810037SARM gem5 Developers                     rsraCode, True, hasImm=True)
326910037SARM gem5 Developers    twoEqualRegInstX("ursra", "UrsraQX", "SimdShiftOp", unsignedTypes, 4,
327010037SARM gem5 Developers                     rsraCode, True, hasImm=True)
327110037SARM gem5 Developers    # USHL
327210037SARM gem5 Developers    threeEqualRegInstX("ushl", "UshlDX", "SimdShiftOp", unsignedTypes, 2,
327310037SARM gem5 Developers                       shlCode)
327410037SARM gem5 Developers    threeEqualRegInstX("ushl", "UshlQX", "SimdShiftOp", unsignedTypes, 4,
327510037SARM gem5 Developers                       shlCode)
327610037SARM gem5 Developers    # USHLL, USHLL2
327710037SARM gem5 Developers    twoRegLongInstX("ushll", "UshllX", "SimdShiftOp", smallUnsignedTypes,
327810037SARM gem5 Developers                    shllCode, hasImm=True)
327910037SARM gem5 Developers    twoRegLongInstX("ushll", "Ushll2X", "SimdShiftOp", smallUnsignedTypes,
328010037SARM gem5 Developers                    shllCode, hi=True, hasImm=True)
328110037SARM gem5 Developers    # USHR
328210037SARM gem5 Developers    twoEqualRegInstX("ushr", "UshrDX", "SimdShiftOp", unsignedTypes, 2,
328310037SARM gem5 Developers                     shrCode, hasImm=True)
328410037SARM gem5 Developers    twoEqualRegInstX("ushr", "UshrQX", "SimdShiftOp", unsignedTypes, 4,
328510037SARM gem5 Developers                     shrCode, hasImm=True)
328610037SARM gem5 Developers    # USQADD
328710037SARM gem5 Developers    usqaddCode = '''
328810037SARM gem5 Developers            FPSCR fpscr = (FPSCR) FpscrQc;
328910037SARM gem5 Developers            Element tmp = destElem + srcElem1;
329010037SARM gem5 Developers            if (bits(srcElem1, sizeof(Element) * 8 - 1) == 0) {
329110037SARM gem5 Developers                if (tmp < srcElem1 || tmp < destElem) {
329210037SARM gem5 Developers                    destElem = (Element)(-1);
329310037SARM gem5 Developers                    fpscr.qc = 1;
329410037SARM gem5 Developers                } else {
329510037SARM gem5 Developers                    destElem = tmp;
329610037SARM gem5 Developers                }
329710037SARM gem5 Developers            } else {
329810037SARM gem5 Developers                Element absSrcElem1 = (~srcElem1) + 1;
329910037SARM gem5 Developers                if (absSrcElem1 > destElem) {
330010037SARM gem5 Developers                    destElem = 0;
330110037SARM gem5 Developers                    fpscr.qc = 1;
330210037SARM gem5 Developers                } else {
330310037SARM gem5 Developers                    destElem = tmp;
330410037SARM gem5 Developers                }
330510037SARM gem5 Developers            }
330610037SARM gem5 Developers            FpscrQc = fpscr;
330710037SARM gem5 Developers    '''
330810037SARM gem5 Developers    twoEqualRegInstX("usqadd", "UsqaddDX", "SimdAddOp", smallUnsignedTypes, 2,
330910037SARM gem5 Developers                     usqaddCode, True)
331010037SARM gem5 Developers    twoEqualRegInstX("usqadd", "UsqaddQX", "SimdAddOp", unsignedTypes, 4,
331110037SARM gem5 Developers                     usqaddCode, True)
331210037SARM gem5 Developers    twoEqualRegInstX("usqadd", "UsqaddScX", "SimdAddOp", unsignedTypes, 4,
331310037SARM gem5 Developers                     usqaddCode, True, scalar=True)
331410037SARM gem5 Developers    # USRA
331510037SARM gem5 Developers    twoEqualRegInstX("usra", "UsraDX", "SimdShiftOp", unsignedTypes, 2,
331610037SARM gem5 Developers                     sraCode, True, hasImm=True)
331710037SARM gem5 Developers    twoEqualRegInstX("usra", "UsraQX", "SimdShiftOp", unsignedTypes, 4,
331810037SARM gem5 Developers                     sraCode, True, hasImm=True)
331910037SARM gem5 Developers    # USUBL
332010037SARM gem5 Developers    threeRegLongInstX("usubl", "UsublX", "SimdAddOp", smallUnsignedTypes,
332110037SARM gem5 Developers                      sublwCode)
332210037SARM gem5 Developers    threeRegLongInstX("usubl2", "Usubl2X", "SimdAddOp", smallUnsignedTypes,
332310037SARM gem5 Developers                      sublwCode, hi=True)
332410037SARM gem5 Developers    # USUBW
332510037SARM gem5 Developers    threeRegWideInstX("usubw", "UsubwX", "SimdAddOp", smallUnsignedTypes,
332610037SARM gem5 Developers                      sublwCode)
332710037SARM gem5 Developers    threeRegWideInstX("usubw2", "Usubw2X", "SimdAddOp", smallUnsignedTypes,
332810037SARM gem5 Developers                      sublwCode, hi=True)
332910037SARM gem5 Developers    # UXTL -> alias to USHLL
333010037SARM gem5 Developers    # UZP1
333110037SARM gem5 Developers    uzpCode = '''
333210037SARM gem5 Developers        unsigned part = %s;
333310037SARM gem5 Developers        for (unsigned i = 0; i < eCount / 2; i++) {
333410037SARM gem5 Developers            destReg.elements[i] = srcReg1.elements[2 * i + part];
333510037SARM gem5 Developers            destReg.elements[eCount / 2 + i] = srcReg2.elements[2 * i + part];
333610037SARM gem5 Developers        }
333710037SARM gem5 Developers    '''
333810037SARM gem5 Developers    threeRegScrambleInstX("Uzp1", "Uzp1DX", "SimdAluOp", smallUnsignedTypes, 2,
333910037SARM gem5 Developers                          uzpCode % "0")
334010037SARM gem5 Developers    threeRegScrambleInstX("Uzp1", "Uzp1QX", "SimdAluOp", unsignedTypes, 4,
334110037SARM gem5 Developers                          uzpCode % "0")
334210037SARM gem5 Developers    # UZP2
334310037SARM gem5 Developers    threeRegScrambleInstX("Uzp2", "Uzp2DX", "SimdAluOp", smallUnsignedTypes, 2,
334410037SARM gem5 Developers                          uzpCode % "1")
334510037SARM gem5 Developers    threeRegScrambleInstX("Uzp2", "Uzp2QX", "SimdAluOp", unsignedTypes, 4,
334610037SARM gem5 Developers                          uzpCode % "1")
334710037SARM gem5 Developers    # XTN, XTN2
334810037SARM gem5 Developers    xtnCode = "destElem = srcElem1;"
334910037SARM gem5 Developers    twoRegNarrowInstX("Xtn", "XtnX", "SimdMiscOp", smallUnsignedTypes, xtnCode)
335010037SARM gem5 Developers    twoRegNarrowInstX("Xtn", "Xtn2X", "SimdMiscOp", smallUnsignedTypes,
335110037SARM gem5 Developers                      xtnCode, hi=True)
335210037SARM gem5 Developers    # ZIP1
335310037SARM gem5 Developers    zipCode = '''
335410037SARM gem5 Developers        unsigned base = %s;
335510037SARM gem5 Developers        for (unsigned i = 0; i < eCount / 2; i++) {
335610037SARM gem5 Developers            destReg.elements[2 * i] = srcReg1.elements[base + i];
335710037SARM gem5 Developers            destReg.elements[2 * i + 1] = srcReg2.elements[base + i];
335810037SARM gem5 Developers        }
335910037SARM gem5 Developers    '''
336010037SARM gem5 Developers    threeRegScrambleInstX("zip1", "Zip1DX", "SimdAluOp", smallUnsignedTypes, 2,
336110037SARM gem5 Developers                          zipCode % "0")
336210037SARM gem5 Developers    threeRegScrambleInstX("zip1", "Zip1QX", "SimdAluOp", unsignedTypes, 4,
336310037SARM gem5 Developers                          zipCode % "0")
336410037SARM gem5 Developers    # ZIP2
336510037SARM gem5 Developers    threeRegScrambleInstX("zip2", "Zip2DX", "SimdAluOp", smallUnsignedTypes, 2,
336610037SARM gem5 Developers                          zipCode % "eCount / 2")
336710037SARM gem5 Developers    threeRegScrambleInstX("zip2", "Zip2QX", "SimdAluOp", unsignedTypes, 4,
336810037SARM gem5 Developers                          zipCode % "eCount / 2")
336910037SARM gem5 Developers
337011165SRekai.GonzalezAlberquilla@arm.com    for decoderFlavour, type_dict in decoders.iteritems():
337111165SRekai.GonzalezAlberquilla@arm.com        header_output += '''
337211165SRekai.GonzalezAlberquilla@arm.com        class %(decoder_flavour)sDecoder {
337311165SRekai.GonzalezAlberquilla@arm.com        public:
337411165SRekai.GonzalezAlberquilla@arm.com        ''' % { "decoder_flavour" : decoderFlavour }
337511165SRekai.GonzalezAlberquilla@arm.com        for type,name in type_dict.iteritems():
337611165SRekai.GonzalezAlberquilla@arm.com            header_output += '''
337711165SRekai.GonzalezAlberquilla@arm.com            template<typename Elem> using %(type)s = %(new_name)s<Elem>;''' % {
337811165SRekai.GonzalezAlberquilla@arm.com               "type" : type, "new_name" : name
337911165SRekai.GonzalezAlberquilla@arm.com            }
338011165SRekai.GonzalezAlberquilla@arm.com        header_output += '''
338111165SRekai.GonzalezAlberquilla@arm.com        };'''
338210037SARM gem5 Developers}};
3383