data.isa revision 10037
110860Sandreas.sandberg@arm.com// -*- mode:c++ -*-
210860Sandreas.sandberg@arm.com
310860Sandreas.sandberg@arm.com// Copyright (c) 2010, 2013 ARM Limited
410860Sandreas.sandberg@arm.com// All rights reserved
510860Sandreas.sandberg@arm.com//
610860Sandreas.sandberg@arm.com// The license below extends only to copyright in the software and shall
710860Sandreas.sandberg@arm.com// not be construed as granting a license to any other intellectual
810860Sandreas.sandberg@arm.com// property including but not limited to intellectual property relating
910860Sandreas.sandberg@arm.com// to a hardware implementation of the functionality of the software
1010860Sandreas.sandberg@arm.com// licensed hereunder.  You may use the software subject to the license
1110860Sandreas.sandberg@arm.com// terms below provided that you ensure that this notice is replicated
1210860Sandreas.sandberg@arm.com// unmodified and in its entirety in all distributions of the software,
1310860Sandreas.sandberg@arm.com// modified or unmodified, in source code or in binary form.
1410860Sandreas.sandberg@arm.com//
1510860Sandreas.sandberg@arm.com// Redistribution and use in source and binary forms, with or without
1610860Sandreas.sandberg@arm.com// modification, are permitted provided that the following conditions are
1710860Sandreas.sandberg@arm.com// met: redistributions of source code must retain the above copyright
1810860Sandreas.sandberg@arm.com// notice, this list of conditions and the following disclaimer;
1910860Sandreas.sandberg@arm.com// redistributions in binary form must reproduce the above copyright
2010860Sandreas.sandberg@arm.com// notice, this list of conditions and the following disclaimer in the
2110860Sandreas.sandberg@arm.com// documentation and/or other materials provided with the distribution;
2210860Sandreas.sandberg@arm.com// neither the name of the copyright holders nor the names of its
2310860Sandreas.sandberg@arm.com// contributors may be used to endorse or promote products derived from
2410860Sandreas.sandberg@arm.com// this software without specific prior written permission.
2510860Sandreas.sandberg@arm.com//
2610860Sandreas.sandberg@arm.com// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2710860Sandreas.sandberg@arm.com// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2810860Sandreas.sandberg@arm.com// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2910860Sandreas.sandberg@arm.com// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
3010860Sandreas.sandberg@arm.com// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
3110860Sandreas.sandberg@arm.com// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
3210860Sandreas.sandberg@arm.com// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
3310860Sandreas.sandberg@arm.com// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
3410860Sandreas.sandberg@arm.com// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3510860Sandreas.sandberg@arm.com// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
3610860Sandreas.sandberg@arm.com// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3710860Sandreas.sandberg@arm.com//
3810860Sandreas.sandberg@arm.com// Authors: Gabe Black
3910860Sandreas.sandberg@arm.com
4010860Sandreas.sandberg@arm.comlet {{
4110860Sandreas.sandberg@arm.com
4210860Sandreas.sandberg@arm.com    header_output = ""
4310860Sandreas.sandberg@arm.com    decoder_output = ""
4410860Sandreas.sandberg@arm.com    exec_output = ""
4510860Sandreas.sandberg@arm.com
4610860Sandreas.sandberg@arm.com    calcGECode = '''
4710860Sandreas.sandberg@arm.com        CondCodesGE = resTemp;
4810860Sandreas.sandberg@arm.com    '''
4910860Sandreas.sandberg@arm.com
5010860Sandreas.sandberg@arm.com    calcQCode = '''
5110860Sandreas.sandberg@arm.com        CpsrQ = (resTemp & 1) << 27;
5210860Sandreas.sandberg@arm.com    '''
5310860Sandreas.sandberg@arm.com
5410860Sandreas.sandberg@arm.com    def createCcCode(negBit, carry, overflow):
5510860Sandreas.sandberg@arm.com        code = ""
5610860Sandreas.sandberg@arm.com        code += '''
5710860Sandreas.sandberg@arm.com            uint16_t _iz, _in;
5810860Sandreas.sandberg@arm.com            _in = (resTemp >> %d) & 1;
5910860Sandreas.sandberg@arm.com            _iz = (resTemp == 0);
6010860Sandreas.sandberg@arm.com            CondCodesNZ = (_in << 1) | _iz;
6110860Sandreas.sandberg@arm.com            DPRINTF(Arm, "(in, iz) = (%%d, %%d)\\n", _in, _iz);
6210860Sandreas.sandberg@arm.com        ''' % negBit
6310860Sandreas.sandberg@arm.com        if overflow and overflow != "none":
6410860Sandreas.sandberg@arm.com            code +=  '''
6510860Sandreas.sandberg@arm.com                uint16_t _iv;
6610860Sandreas.sandberg@arm.com                _iv = %s & 1;
6710860Sandreas.sandberg@arm.com                CondCodesV =  _iv;
6810860Sandreas.sandberg@arm.com                DPRINTF(Arm, "(iv) = (%%d)\\n", _iv);
6910860Sandreas.sandberg@arm.com            ''' % overflow
7010860Sandreas.sandberg@arm.com        if carry and carry != "none":
7110860Sandreas.sandberg@arm.com            code += '''
7210860Sandreas.sandberg@arm.com                uint16_t _ic;
7310860Sandreas.sandberg@arm.com                _ic = %s & 1;
7410860Sandreas.sandberg@arm.com                CondCodesC =  _ic;
7510860Sandreas.sandberg@arm.com                DPRINTF(Arm, "(ic) = (%%d)\\n", _ic);
7610860Sandreas.sandberg@arm.com            ''' % carry
7710860Sandreas.sandberg@arm.com        return code
7810860Sandreas.sandberg@arm.com
7910860Sandreas.sandberg@arm.com    # Dict of code to set the carry flag. (imm, reg, reg-reg)
8010860Sandreas.sandberg@arm.com    oldC = 'CondCodesC'
8110860Sandreas.sandberg@arm.com    carryCode = {
8210860Sandreas.sandberg@arm.com        "none": ("none", "none", "none"),
8310860Sandreas.sandberg@arm.com        "llbit": ("none", "none", "none"),
8410860Sandreas.sandberg@arm.com        "saturate": ('0', '0', '0'),
8510860Sandreas.sandberg@arm.com        "overflow": ('0', '0', '0'),
8610860Sandreas.sandberg@arm.com        "ge": ('0', '0', '0'),
8710860Sandreas.sandberg@arm.com        "add": ('findCarry(32, resTemp, Op1, secondOp)',
8810860Sandreas.sandberg@arm.com                'findCarry(32, resTemp, Op1, secondOp)',
8910860Sandreas.sandberg@arm.com                'findCarry(32, resTemp, Op1, secondOp)'),
9010860Sandreas.sandberg@arm.com        "sub": ('findCarry(32, resTemp, Op1, ~secondOp)',
9110860Sandreas.sandberg@arm.com                'findCarry(32, resTemp, Op1, ~secondOp)',
9210860Sandreas.sandberg@arm.com                'findCarry(32, resTemp, Op1, ~secondOp)'),
9310860Sandreas.sandberg@arm.com        "rsb": ('findCarry(32, resTemp, secondOp, ~Op1)',
9410860Sandreas.sandberg@arm.com                'findCarry(32, resTemp, secondOp, ~Op1)',
9510860Sandreas.sandberg@arm.com                'findCarry(32, resTemp, secondOp, ~Op1)'),
9610860Sandreas.sandberg@arm.com        "logic": ('(rotC ? bits(secondOp, 31) : %s)' % oldC,
9710860Sandreas.sandberg@arm.com                  'shift_carry_imm(Op2, shiftAmt, shiftType, %s)' % oldC,
9810860Sandreas.sandberg@arm.com                  'shift_carry_rs(Op2, Shift<7:0>, shiftType, %s)' % oldC)
9910860Sandreas.sandberg@arm.com    }
10010860Sandreas.sandberg@arm.com    # Dict of code to set the overflow flag.
10110860Sandreas.sandberg@arm.com    overflowCode = {
10210860Sandreas.sandberg@arm.com        "none": "none",
10310860Sandreas.sandberg@arm.com        "llbit": "none",
10410860Sandreas.sandberg@arm.com        "saturate": '0',
10510860Sandreas.sandberg@arm.com        "overflow": '0',
10610860Sandreas.sandberg@arm.com        "ge": '0',
10710860Sandreas.sandberg@arm.com        "add": 'findOverflow(32, resTemp, Op1, secondOp)',
10810860Sandreas.sandberg@arm.com        "sub": 'findOverflow(32, resTemp, Op1, ~secondOp)',
10910860Sandreas.sandberg@arm.com        "rsb": 'findOverflow(32, resTemp, secondOp, ~Op1)',
11010860Sandreas.sandberg@arm.com        "logic": "none"
11110860Sandreas.sandberg@arm.com    }
11210860Sandreas.sandberg@arm.com
11310860Sandreas.sandberg@arm.com    secondOpRe = re.compile("secondOp")
11410860Sandreas.sandberg@arm.com    immOp2 = "imm"
11510860Sandreas.sandberg@arm.com    regOp2 = "shift_rm_imm(Op2, shiftAmt, shiftType, OptShiftRmCondCodesC)"
11610860Sandreas.sandberg@arm.com    regRegOp2 = "shift_rm_rs(Op2, Shift<7:0>, shiftType, 0)"
11710860Sandreas.sandberg@arm.com
11810860Sandreas.sandberg@arm.com    def buildImmDataInst(mnem, code, flagType = "logic", suffix = "Imm", \
11910860Sandreas.sandberg@arm.com                         buildCc = True, buildNonCc = True, isBranch = "0", \
12010860Sandreas.sandberg@arm.com                         instFlags = []):
12110860Sandreas.sandberg@arm.com        cCode = carryCode[flagType]
12210860Sandreas.sandberg@arm.com        vCode = overflowCode[flagType]
12310860Sandreas.sandberg@arm.com        negBit = 31
12410860Sandreas.sandberg@arm.com        if flagType == "llbit":
12510860Sandreas.sandberg@arm.com            negBit = 63
12611178Svictor.garcia@arm.com        if flagType == "saturate":
12710860Sandreas.sandberg@arm.com            immCcCode = calcQCode
12810860Sandreas.sandberg@arm.com        elif flagType == "ge":
12910860Sandreas.sandberg@arm.com            immCcCode = calcGECode
13010860Sandreas.sandberg@arm.com        else:
13110860Sandreas.sandberg@arm.com            immCcCode = createCcCode(negBit, secondOpRe.sub(immOp2, cCode[0]),
13210860Sandreas.sandberg@arm.com                                     secondOpRe.sub(immOp2, vCode))
13310860Sandreas.sandberg@arm.com
13410860Sandreas.sandberg@arm.com        immCode = secondOpRe.sub(immOp2, code)
13510860Sandreas.sandberg@arm.com        immIop = InstObjParams(mnem, mnem.capitalize() + suffix, "DataImmOp",
13610860Sandreas.sandberg@arm.com                       {"code" : immCode,
13710860Sandreas.sandberg@arm.com                        "is_branch" : isBranch,
13810860Sandreas.sandberg@arm.com                        "predicate_test": pickPredicate(immCode)}, instFlags)
13910860Sandreas.sandberg@arm.com        immIopCc = InstObjParams(mnem + "s", mnem.capitalize() + suffix + "Cc",
14010860Sandreas.sandberg@arm.com             "DataImmOp",
14110860Sandreas.sandberg@arm.com             {"code" : immCode + immCcCode,
14210860Sandreas.sandberg@arm.com              "is_branch" : isBranch,
14310860Sandreas.sandberg@arm.com              "predicate_test": pickPredicate(immCode + immCcCode)}, instFlags)
14410860Sandreas.sandberg@arm.com
14510860Sandreas.sandberg@arm.com        def subst(iop):
14610860Sandreas.sandberg@arm.com            global header_output, decoder_output, exec_output
14710860Sandreas.sandberg@arm.com            header_output += DataImmDeclare.subst(iop)
14810860Sandreas.sandberg@arm.com            decoder_output += DataImmConstructor.subst(iop)
14910860Sandreas.sandberg@arm.com            exec_output += PredOpExecute.subst(iop)
15010860Sandreas.sandberg@arm.com
15110860Sandreas.sandberg@arm.com        if buildNonCc:
15210860Sandreas.sandberg@arm.com            subst(immIop)
15310860Sandreas.sandberg@arm.com        if buildCc:
15410860Sandreas.sandberg@arm.com            subst(immIopCc)
15510860Sandreas.sandberg@arm.com
15610860Sandreas.sandberg@arm.com    def buildRegDataInst(mnem, code, flagType = "logic", suffix = "Reg", \
15710860Sandreas.sandberg@arm.com                         buildCc = True, buildNonCc = True, isRasPop = "0", \
15810860Sandreas.sandberg@arm.com                         isBranch = "0", instFlags = []):
15910860Sandreas.sandberg@arm.com        cCode = carryCode[flagType]
16010860Sandreas.sandberg@arm.com        vCode = overflowCode[flagType]
16110860Sandreas.sandberg@arm.com        negBit = 31
16210860Sandreas.sandberg@arm.com        regCcCode = ""
16310860Sandreas.sandberg@arm.com        if flagType == "llbit":
16410860Sandreas.sandberg@arm.com            negBit = 63
16510860Sandreas.sandberg@arm.com        if flagType == "saturate":
16610860Sandreas.sandberg@arm.com            regCcCode = calcQCode
16710860Sandreas.sandberg@arm.com        elif flagType == "ge":
16810860Sandreas.sandberg@arm.com            regCcCode = calcGECode
16910860Sandreas.sandberg@arm.com        else:
17010860Sandreas.sandberg@arm.com            regCcCode = createCcCode(negBit,secondOpRe.sub(regOp2, cCode[1]),
17110860Sandreas.sandberg@arm.com                                     secondOpRe.sub(regOp2, vCode))
17210860Sandreas.sandberg@arm.com
17310860Sandreas.sandberg@arm.com        regCode = secondOpRe.sub(regOp2, code)
17410860Sandreas.sandberg@arm.com
17510860Sandreas.sandberg@arm.com        # If we end up needing CondCodesC then remove any trace of the OptShift
17610860Sandreas.sandberg@arm.com        if re.search('(?<!OptShiftRm)CondCodesC(?!.*=)', regCode + regCcCode):
17710860Sandreas.sandberg@arm.com            regCode = re.sub('OptShiftRmCondCodesC', 'CondCodesC', regCode)
17810860Sandreas.sandberg@arm.com            regCcCode = re.sub('OptShiftRmCondCodesC', 'CondCodesC', regCcCode)
17910860Sandreas.sandberg@arm.com
18010860Sandreas.sandberg@arm.com        regIop = InstObjParams(mnem, mnem.capitalize() + suffix, "DataRegOp",
18110860Sandreas.sandberg@arm.com                       {"code" : regCode, "is_ras_pop" : isRasPop,
18210860Sandreas.sandberg@arm.com                        "is_branch" : isBranch,
18310860Sandreas.sandberg@arm.com                        "predicate_test": pickPredicate(regCode)}, instFlags)
18410860Sandreas.sandberg@arm.com        regIopCc = InstObjParams(mnem + "s", mnem.capitalize() + suffix + "Cc",
18510860Sandreas.sandberg@arm.com                         "DataRegOp",
18610860Sandreas.sandberg@arm.com                         {"code" : regCode + regCcCode,
18710860Sandreas.sandberg@arm.com                          "predicate_test": pickPredicate(regCode + regCcCode),
18810860Sandreas.sandberg@arm.com                          "is_ras_pop" : isRasPop,
18910860Sandreas.sandberg@arm.com                          "is_branch" : isBranch}, instFlags)
19010860Sandreas.sandberg@arm.com
19110860Sandreas.sandberg@arm.com        def subst(iop):
19210860Sandreas.sandberg@arm.com            global header_output, decoder_output, exec_output
19310860Sandreas.sandberg@arm.com            header_output += DataRegDeclare.subst(iop)
19410860Sandreas.sandberg@arm.com            decoder_output += DataRegConstructor.subst(iop)
19510860Sandreas.sandberg@arm.com            exec_output += PredOpExecute.subst(iop)
19610860Sandreas.sandberg@arm.com
19710860Sandreas.sandberg@arm.com        if buildNonCc:
19810860Sandreas.sandberg@arm.com            subst(regIop)
19910860Sandreas.sandberg@arm.com        if buildCc:
20010860Sandreas.sandberg@arm.com            subst(regIopCc)
20110860Sandreas.sandberg@arm.com
20210860Sandreas.sandberg@arm.com    def buildRegRegDataInst(mnem, code, flagType = "logic", \
20310860Sandreas.sandberg@arm.com                            suffix = "RegReg", \
20410860Sandreas.sandberg@arm.com                            buildCc = True, buildNonCc = True):
20510860Sandreas.sandberg@arm.com        cCode = carryCode[flagType]
20610860Sandreas.sandberg@arm.com        vCode = overflowCode[flagType]
20710860Sandreas.sandberg@arm.com        negBit = 31
20810860Sandreas.sandberg@arm.com        if flagType == "llbit":
20910860Sandreas.sandberg@arm.com            negBit = 63
21010860Sandreas.sandberg@arm.com        if flagType == "saturate":
21110860Sandreas.sandberg@arm.com            regRegCcCode = calcQCode
21210860Sandreas.sandberg@arm.com        elif flagType == "ge":
21310860Sandreas.sandberg@arm.com            regRegCcCode = calcGECode
21410860Sandreas.sandberg@arm.com        else:
21510860Sandreas.sandberg@arm.com            regRegCcCode = createCcCode(negBit,
21610860Sandreas.sandberg@arm.com                                        secondOpRe.sub(regRegOp2, cCode[2]),
21710860Sandreas.sandberg@arm.com                                        secondOpRe.sub(regRegOp2, vCode))
21810860Sandreas.sandberg@arm.com
21910860Sandreas.sandberg@arm.com        regRegCode = secondOpRe.sub(regRegOp2, code)
22010860Sandreas.sandberg@arm.com        regRegIop = InstObjParams(mnem, mnem.capitalize() + suffix,
22110860Sandreas.sandberg@arm.com                          "DataRegRegOp",
22210860Sandreas.sandberg@arm.com                          {"code" : regRegCode,
22310860Sandreas.sandberg@arm.com                           "predicate_test": pickPredicate(regRegCode)})
22410860Sandreas.sandberg@arm.com        regRegIopCc = InstObjParams(mnem + "s",
22510860Sandreas.sandberg@arm.com                mnem.capitalize() + suffix + "Cc",
22610860Sandreas.sandberg@arm.com                "DataRegRegOp",
22710860Sandreas.sandberg@arm.com                {"code" : regRegCode + regRegCcCode,
22810860Sandreas.sandberg@arm.com                 "predicate_test": pickPredicate(regRegCode + regRegCcCode)})
22910860Sandreas.sandberg@arm.com
23010860Sandreas.sandberg@arm.com        def subst(iop):
23110860Sandreas.sandberg@arm.com            global header_output, decoder_output, exec_output
23210860Sandreas.sandberg@arm.com            header_output += DataRegRegDeclare.subst(iop)
23310860Sandreas.sandberg@arm.com            decoder_output += DataRegRegConstructor.subst(iop)
23410860Sandreas.sandberg@arm.com            exec_output += PredOpExecute.subst(iop)
23510860Sandreas.sandberg@arm.com
23610860Sandreas.sandberg@arm.com        if buildNonCc:
23710860Sandreas.sandberg@arm.com            subst(regRegIop)
23810860Sandreas.sandberg@arm.com        if buildCc:
23910860Sandreas.sandberg@arm.com            subst(regRegIopCc)
24010860Sandreas.sandberg@arm.com
24110860Sandreas.sandberg@arm.com    def buildDataInst(mnem, code, flagType = "logic", \
24210860Sandreas.sandberg@arm.com                      aiw = True, regRegAiw = True,
24310860Sandreas.sandberg@arm.com                      subsPcLr = True, isRasPop = "0", isBranch = "0"):
24410860Sandreas.sandberg@arm.com        regRegCode = instCode = code
24510860Sandreas.sandberg@arm.com        if aiw:
24610860Sandreas.sandberg@arm.com            instCode = "AIW" + instCode
24710860Sandreas.sandberg@arm.com            if regRegAiw:
24810860Sandreas.sandberg@arm.com                regRegCode = "AIW" + regRegCode
24910860Sandreas.sandberg@arm.com
25010860Sandreas.sandberg@arm.com        buildImmDataInst(mnem, instCode, flagType, isBranch = isBranch)
25110860Sandreas.sandberg@arm.com        buildRegDataInst(mnem, instCode, flagType,
25210860Sandreas.sandberg@arm.com                         isRasPop = isRasPop, isBranch = isBranch)
25310860Sandreas.sandberg@arm.com        buildRegRegDataInst(mnem, regRegCode, flagType)
25410860Sandreas.sandberg@arm.com        if subsPcLr:
25510860Sandreas.sandberg@arm.com            code += '''
25610860Sandreas.sandberg@arm.com            SCTLR sctlr = Sctlr;
25710860Sandreas.sandberg@arm.com            CPSR old_cpsr = Cpsr;
25810860Sandreas.sandberg@arm.com
25910860Sandreas.sandberg@arm.com            CPSR new_cpsr =
26010860Sandreas.sandberg@arm.com                cpsrWriteByInstr(old_cpsr, Spsr, Scr, Nsacr, 0xF, true,
26110860Sandreas.sandberg@arm.com                                 sctlr.nmfi, xc->tcBase());
26210860Sandreas.sandberg@arm.com            Cpsr = ~CondCodesMask & new_cpsr;
26310860Sandreas.sandberg@arm.com            CondCodesNZ = new_cpsr.nz;
26410860Sandreas.sandberg@arm.com            CondCodesC = new_cpsr.c;
26510860Sandreas.sandberg@arm.com            CondCodesV = new_cpsr.v;
26610860Sandreas.sandberg@arm.com            CondCodesGE = new_cpsr.ge;
26710860Sandreas.sandberg@arm.com
26810860Sandreas.sandberg@arm.com            NextThumb = (new_cpsr).t;
26910860Sandreas.sandberg@arm.com            NextJazelle = (new_cpsr).j;
27010860Sandreas.sandberg@arm.com            NextItState = (((new_cpsr).it2 << 2) & 0xFC)
27110860Sandreas.sandberg@arm.com                | ((new_cpsr).it1 & 0x3);
27210860Sandreas.sandberg@arm.com            SevMailbox = 1;
27310860Sandreas.sandberg@arm.com            '''
27410860Sandreas.sandberg@arm.com            buildImmDataInst(mnem + 's', code, flagType,
27510860Sandreas.sandberg@arm.com                             suffix = "ImmPclr", buildCc = False,
27610860Sandreas.sandberg@arm.com                             instFlags = ["IsSerializeAfter","IsNonSpeculative"])
27710860Sandreas.sandberg@arm.com            buildRegDataInst(mnem + 's', code, flagType,
27810860Sandreas.sandberg@arm.com                             suffix = "RegPclr", buildCc = False,
27910860Sandreas.sandberg@arm.com                             instFlags = ["IsSerializeAfter","IsNonSpeculative"])
28010860Sandreas.sandberg@arm.com
28110860Sandreas.sandberg@arm.com    buildDataInst("and", "Dest = resTemp = Op1 & secondOp;")
28210860Sandreas.sandberg@arm.com    buildDataInst("eor", "Dest = resTemp = Op1 ^ secondOp;")
28310860Sandreas.sandberg@arm.com    buildDataInst("sub", "Dest = resTemp = Op1 - secondOp;", "sub",
28410860Sandreas.sandberg@arm.com                  isBranch = "dest == INTREG_PC")
28510860Sandreas.sandberg@arm.com    buildDataInst("rsb", "Dest = resTemp = secondOp - Op1;", "rsb")
28610860Sandreas.sandberg@arm.com    buildDataInst("add", "Dest = resTemp = Op1 + secondOp;", "add",
28710860Sandreas.sandberg@arm.com                  isBranch = "dest == INTREG_PC")
28810860Sandreas.sandberg@arm.com    buildImmDataInst("adr", '''
28910860Sandreas.sandberg@arm.com                               Dest = resTemp = (PC & ~0x3) +
29010860Sandreas.sandberg@arm.com                               (op1 ? secondOp : -secondOp);
29110860Sandreas.sandberg@arm.com                            ''', isBranch = "dest == INTREG_PC")
29210860Sandreas.sandberg@arm.com    buildDataInst("adc", "Dest = resTemp = Op1 + secondOp + %s;" % oldC, "add")
29310860Sandreas.sandberg@arm.com    buildDataInst("sbc", "Dest = resTemp = Op1 - secondOp - !%s;" % oldC, "sub")
29410860Sandreas.sandberg@arm.com    buildDataInst("rsc", "Dest = resTemp = secondOp - Op1 - !%s;" % oldC, "rsb")
29510860Sandreas.sandberg@arm.com    buildDataInst("tst", "resTemp = Op1 & secondOp;", aiw = False)
29610860Sandreas.sandberg@arm.com    buildDataInst("teq", "resTemp = Op1 ^ secondOp;", aiw = False)
29710860Sandreas.sandberg@arm.com    buildDataInst("cmp", "resTemp = Op1 - secondOp;", "sub", aiw = False)
29810860Sandreas.sandberg@arm.com    buildDataInst("cmn", "resTemp = Op1 + secondOp;", "add", aiw = False)
29910860Sandreas.sandberg@arm.com    buildDataInst("orr", "Dest = resTemp = Op1 | secondOp;")
30010860Sandreas.sandberg@arm.com    buildDataInst("orn", "Dest = resTemp = Op1 | ~secondOp;", aiw = False)
30110860Sandreas.sandberg@arm.com    buildDataInst("mov", "Dest = resTemp = secondOp;", regRegAiw = False,
30210860Sandreas.sandberg@arm.com                  isRasPop = "op2 == INTREG_LR", isBranch = "dest == INTREG_PC")
30310860Sandreas.sandberg@arm.com    buildDataInst("bic", "Dest = resTemp = Op1 & ~secondOp;")
30410860Sandreas.sandberg@arm.com    buildDataInst("mvn", "Dest = resTemp = ~secondOp;")
30510860Sandreas.sandberg@arm.com    buildDataInst("movt",
30610860Sandreas.sandberg@arm.com                  "Dest = resTemp = insertBits(Op1, 31, 16, secondOp);",
30710860Sandreas.sandberg@arm.com                  aiw = False)
30810860Sandreas.sandberg@arm.com
30910860Sandreas.sandberg@arm.com    buildRegDataInst("qadd", '''
31010860Sandreas.sandberg@arm.com            int32_t midRes;
31110860Sandreas.sandberg@arm.com            resTemp = saturateOp<32>(midRes, Op1_sw, Op2_sw);
31210860Sandreas.sandberg@arm.com                                     Dest = midRes;
31310860Sandreas.sandberg@arm.com        ''', flagType="saturate", buildNonCc=False)
31410860Sandreas.sandberg@arm.com    buildRegDataInst("qadd16", '''
31510860Sandreas.sandberg@arm.com            int32_t midRes;
31610860Sandreas.sandberg@arm.com            for (unsigned i = 0; i < 2; i++) {
31710860Sandreas.sandberg@arm.com                int high = (i + 1) * 16 - 1;
31810860Sandreas.sandberg@arm.com                int low = i * 16;
31910860Sandreas.sandberg@arm.com                int64_t arg1 = sext<16>(bits(Op1_sw, high, low));
32010860Sandreas.sandberg@arm.com                int64_t arg2 = sext<16>(bits(Op2_sw, high, low));
32110860Sandreas.sandberg@arm.com                saturateOp<16>(midRes, arg1, arg2);
32210860Sandreas.sandberg@arm.com                replaceBits(resTemp, high, low, midRes);
32310860Sandreas.sandberg@arm.com            }
32410860Sandreas.sandberg@arm.com            Dest = resTemp;
32510860Sandreas.sandberg@arm.com        ''', flagType="none", buildCc=False)
32610860Sandreas.sandberg@arm.com    buildRegDataInst("qadd8", '''
327            int32_t midRes;
328            for (unsigned i = 0; i < 4; i++) {
329                int high = (i + 1) * 8 - 1;
330                int low = i * 8;
331                int64_t arg1 = sext<8>(bits(Op1_sw, high, low));
332                int64_t arg2 = sext<8>(bits(Op2_sw, high, low));
333                saturateOp<8>(midRes, arg1, arg2);
334                replaceBits(resTemp, high, low, midRes);
335            }
336            Dest = resTemp;
337        ''', flagType="none", buildCc=False)
338    buildRegDataInst("qdadd", '''
339            int32_t midRes;
340            resTemp = saturateOp<32>(midRes, Op2_sw, Op2_sw) |
341                      saturateOp<32>(midRes, Op1_sw, midRes);
342            Dest = midRes;
343        ''', flagType="saturate", buildNonCc=False)
344    buildRegDataInst("qsub", '''
345            int32_t midRes;
346            resTemp = saturateOp<32>(midRes, Op1_sw, Op2_sw, true);
347            Dest = midRes;
348        ''', flagType="saturate")
349    buildRegDataInst("qsub16", '''
350            int32_t midRes;
351            for (unsigned i = 0; i < 2; i++) {
352                 int high = (i + 1) * 16 - 1;
353                 int low = i * 16;
354                 int64_t arg1 = sext<16>(bits(Op1_sw, high, low));
355                 int64_t arg2 = sext<16>(bits(Op2_sw, high, low));
356                 saturateOp<16>(midRes, arg1, arg2, true);
357                 replaceBits(resTemp, high, low, midRes);
358            }
359            Dest = resTemp;
360        ''', flagType="none", buildCc=False)
361    buildRegDataInst("qsub8", '''
362            int32_t midRes;
363            for (unsigned i = 0; i < 4; i++) {
364                 int high = (i + 1) * 8 - 1;
365                 int low = i * 8;
366                 int64_t arg1 = sext<8>(bits(Op1_sw, high, low));
367                 int64_t arg2 = sext<8>(bits(Op2_sw, high, low));
368                 saturateOp<8>(midRes, arg1, arg2, true);
369                 replaceBits(resTemp, high, low, midRes);
370            }
371            Dest = resTemp;
372        ''', flagType="none", buildCc=False)
373    buildRegDataInst("qdsub", '''
374            int32_t midRes;
375            resTemp = saturateOp<32>(midRes, Op2_sw, Op2_sw) |
376                      saturateOp<32>(midRes, Op1_sw, midRes, true);
377            Dest = midRes;
378        ''', flagType="saturate", buildNonCc=False)
379    buildRegDataInst("qasx", '''
380            int32_t midRes;
381            int64_t arg1Low = sext<16>(bits(Op1_sw, 15, 0));
382            int64_t arg1High = sext<16>(bits(Op1_sw, 31, 16));
383            int64_t arg2Low = sext<16>(bits(Op2_sw, 15, 0));
384            int64_t arg2High = sext<16>(bits(Op2_sw, 31, 16));
385            saturateOp<16>(midRes, arg1Low, arg2High, true);
386            replaceBits(resTemp, 15, 0, midRes);
387            saturateOp<16>(midRes, arg1High, arg2Low);
388            replaceBits(resTemp, 31, 16, midRes);
389            Dest = resTemp;
390        ''', flagType="none", buildCc=False)
391    buildRegDataInst("qsax", '''
392            int32_t midRes;
393            int64_t arg1Low = sext<16>(bits(Op1_sw, 15, 0));
394            int64_t arg1High = sext<16>(bits(Op1_sw, 31, 16));
395            int64_t arg2Low = sext<16>(bits(Op2_sw, 15, 0));
396            int64_t arg2High = sext<16>(bits(Op2_sw, 31, 16));
397            saturateOp<16>(midRes, arg1Low, arg2High);
398            replaceBits(resTemp, 15, 0, midRes);
399            saturateOp<16>(midRes, arg1High, arg2Low, true);
400            replaceBits(resTemp, 31, 16, midRes);
401            Dest = resTemp;
402        ''', flagType="none", buildCc=False)
403
404    buildRegDataInst("sadd8", '''
405            uint32_t geBits = 0;
406            resTemp = 0;
407            for (unsigned i = 0; i < 4; i++) {
408                int high = (i + 1) * 8 - 1;
409                int low = i * 8;
410                int32_t midRes = sext<8>(bits(Op1_sw, high, low)) +
411                                 sext<8>(bits(Op2_sw, high, low));
412                replaceBits(resTemp, high, low, midRes);
413                if (midRes >= 0) {
414                    geBits = geBits | (1 << i);
415                }
416            }
417            Dest = resTemp;
418            resTemp = geBits;
419        ''', flagType="ge", buildNonCc=False)
420    buildRegDataInst("sadd16", '''
421            uint32_t geBits = 0;
422            resTemp = 0;
423            for (unsigned i = 0; i < 2; i++) {
424                int high = (i + 1) * 16 - 1;
425                int low = i * 16;
426                int32_t midRes = sext<16>(bits(Op1_sw, high, low)) +
427                                 sext<16>(bits(Op2_sw, high, low));
428                replaceBits(resTemp, high, low, midRes);
429                if (midRes >= 0) {
430                    geBits = geBits | (0x3 << (i * 2));
431                }
432            }
433            Dest = resTemp;
434            resTemp = geBits;
435        ''', flagType="ge", buildNonCc=False)
436
437    buildRegDataInst("ssub8", '''
438            uint32_t geBits = 0;
439            resTemp = 0;
440            for (unsigned i = 0; i < 4; i++) {
441                int high = (i + 1) * 8 - 1;
442                int low = i * 8;
443                int32_t midRes = sext<8>(bits(Op1_sw, high, low)) -
444                                 sext<8>(bits(Op2_sw, high, low));
445                replaceBits(resTemp, high, low, midRes);
446                if (midRes >= 0) {
447                    geBits = geBits | (1 << i);
448                }
449            }
450            Dest = resTemp;
451            resTemp = geBits;
452        ''', flagType="ge", buildNonCc=False)
453    buildRegDataInst("ssub16", '''
454            uint32_t geBits = 0;
455            resTemp = 0;
456            for (unsigned i = 0; i < 2; i++) {
457                int high = (i + 1) * 16 - 1;
458                int low = i * 16;
459                int32_t midRes = sext<16>(bits(Op1_sw, high, low)) -
460                                 sext<16>(bits(Op2_sw, high, low));
461                replaceBits(resTemp, high, low, midRes);
462                if (midRes >= 0) {
463                    geBits = geBits | (0x3 << (i * 2));
464                }
465            }
466            Dest = resTemp;
467            resTemp = geBits;
468        ''', flagType="ge", buildNonCc=False)
469    buildRegDataInst("sasx", '''
470            int32_t midRes, geBits = 0;
471            resTemp = 0;
472            int64_t arg1Low = sext<16>(bits(Op1_sw, 15, 0));
473            int64_t arg1High = sext<16>(bits(Op1_sw, 31, 16));
474            int64_t arg2Low = sext<16>(bits(Op2_sw, 15, 0));
475            int64_t arg2High = sext<16>(bits(Op2_sw, 31, 16));
476            midRes = arg1Low - arg2High;
477            if (midRes >= 0) {
478                geBits = geBits | 0x3;
479            }
480            replaceBits(resTemp, 15, 0, midRes);
481            midRes = arg1High + arg2Low;
482            if (midRes >= 0) {
483                geBits = geBits | 0xc;
484            }
485            replaceBits(resTemp, 31, 16, midRes);
486            Dest = resTemp;
487            resTemp = geBits;
488        ''', flagType="ge", buildNonCc=True)
489    buildRegDataInst("ssax", '''
490            int32_t midRes, geBits = 0;
491            resTemp = 0;
492            int64_t arg1Low = sext<16>(bits(Op1_sw, 15, 0));
493            int64_t arg1High = sext<16>(bits(Op1_sw, 31, 16));
494            int64_t arg2Low = sext<16>(bits(Op2_sw, 15, 0));
495            int64_t arg2High = sext<16>(bits(Op2_sw, 31, 16));
496            midRes = arg1Low + arg2High;
497            if (midRes >= 0) {
498                geBits = geBits | 0x3;
499            }
500            replaceBits(resTemp, 15, 0, midRes);
501            midRes = arg1High - arg2Low;
502            if (midRes >= 0) {
503                geBits = geBits | 0xc;
504            }
505            replaceBits(resTemp, 31, 16, midRes);
506            Dest = resTemp;
507            resTemp = geBits;
508        ''', flagType="ge", buildNonCc=True)
509
510    buildRegDataInst("shadd8", '''
511            resTemp = 0;
512            for (unsigned i = 0; i < 4; i++) {
513                int high = (i + 1) * 8 - 1;
514                int low = i * 8;
515                int32_t midRes =
516                    (uint64_t)(sext<8>(bits(Op1_sw, high, low)) +
517                               sext<8>(bits(Op2_sw, high, low))) >> 1;
518                replaceBits(resTemp, high, low, midRes);
519            }
520            Dest = resTemp;
521        ''', flagType="none", buildCc=False)
522    buildRegDataInst("shadd16", '''
523            resTemp = 0;
524            for (unsigned i = 0; i < 2; i++) {
525                int high = (i + 1) * 16 - 1;
526                int low = i * 16;
527                int32_t midRes =
528                    (uint64_t)(sext<16>(bits(Op1_sw, high, low)) +
529                               sext<16>(bits(Op2_sw, high, low))) >> 1;
530                replaceBits(resTemp, high, low, midRes);
531            }
532            Dest = resTemp;
533        ''', flagType="none", buildCc=False)
534    buildRegDataInst("shsub8", '''
535            resTemp = 0;
536            for (unsigned i = 0; i < 4; i++) {
537                int high = (i + 1) * 8 - 1;
538                int low = i * 8;
539                int32_t midRes =
540                    (uint64_t)(sext<8>(bits(Op1_sw, high, low)) -
541                               sext<8>(bits(Op2_sw, high, low))) >> 1;
542                replaceBits(resTemp, high, low, midRes);
543            }
544            Dest = resTemp;
545        ''', flagType="none", buildCc=False)
546    buildRegDataInst("shsub16", '''
547            resTemp = 0;
548            for (unsigned i = 0; i < 2; i++) {
549                int high = (i + 1) * 16 - 1;
550                int low = i * 16;
551                int32_t midRes =
552                    (uint64_t)(sext<16>(bits(Op1_sw, high, low)) -
553                               sext<16>(bits(Op2_sw, high, low))) >> 1;
554                replaceBits(resTemp, high, low, midRes);
555            }
556            Dest = resTemp;
557        ''', flagType="none", buildCc=False)
558    buildRegDataInst("shasx", '''
559            int32_t midRes;
560            resTemp = 0;
561            int64_t arg1Low = sext<16>(bits(Op1_sw, 15, 0));
562            int64_t arg1High = sext<16>(bits(Op1_sw, 31, 16));
563            int64_t arg2Low = sext<16>(bits(Op2_sw, 15, 0));
564            int64_t arg2High = sext<16>(bits(Op2_sw, 31, 16));
565            midRes = (uint64_t)(arg1Low - arg2High) >> 1;
566            replaceBits(resTemp, 15, 0, midRes);
567            midRes = (arg1High + arg2Low) >> 1;
568            replaceBits(resTemp, 31, 16, midRes);
569            Dest = resTemp;
570        ''', flagType="none", buildCc=True)
571    buildRegDataInst("shsax", '''
572            int32_t midRes;
573            resTemp = 0;
574            int64_t arg1Low = sext<16>(bits(Op1_sw, 15, 0));
575            int64_t arg1High = sext<16>(bits(Op1_sw, 31, 16));
576            int64_t arg2Low = sext<16>(bits(Op2_sw, 15, 0));
577            int64_t arg2High = sext<16>(bits(Op2_sw, 31, 16));
578            midRes = (uint64_t)(arg1Low + arg2High) >> 1;
579            replaceBits(resTemp, 15, 0, midRes);
580            midRes = (uint64_t)(arg1High - arg2Low) >> 1;
581            replaceBits(resTemp, 31, 16, midRes);
582            Dest = resTemp;
583        ''', flagType="none", buildCc=True)
584
585    buildRegDataInst("uqadd16", '''
586            uint32_t midRes;
587            for (unsigned i = 0; i < 2; i++) {
588                int high = (i + 1) * 16 - 1;
589                int low = i * 16;
590                uint64_t arg1 = bits(Op1, high, low);
591                uint64_t arg2 = bits(Op2, high, low);
592                uSaturateOp<16>(midRes, arg1, arg2);
593                replaceBits(resTemp, high, low, midRes);
594            }
595            Dest = resTemp;
596        ''', flagType="none", buildCc=False)
597    buildRegDataInst("uqadd8", '''
598            uint32_t midRes;
599            for (unsigned i = 0; i < 4; i++) {
600                int high = (i + 1) * 8 - 1;
601                int low = i * 8;
602                uint64_t arg1 = bits(Op1, high, low);
603                uint64_t arg2 = bits(Op2, high, low);
604                uSaturateOp<8>(midRes, arg1, arg2);
605                replaceBits(resTemp, high, low, midRes);
606            }
607            Dest = resTemp;
608        ''', flagType="none", buildCc=False)
609    buildRegDataInst("uqsub16", '''
610            uint32_t midRes;
611            for (unsigned i = 0; i < 2; i++) {
612                 int high = (i + 1) * 16 - 1;
613                 int low = i * 16;
614                 uint64_t arg1 = bits(Op1, high, low);
615                 uint64_t arg2 = bits(Op2, high, low);
616                 uSaturateOp<16>(midRes, arg1, arg2, true);
617                 replaceBits(resTemp, high, low, midRes);
618            }
619            Dest = resTemp;
620        ''', flagType="none", buildCc=False)
621    buildRegDataInst("uqsub8", '''
622            uint32_t midRes;
623            for (unsigned i = 0; i < 4; i++) {
624                 int high = (i + 1) * 8 - 1;
625                 int low = i * 8;
626                 uint64_t arg1 = bits(Op1, high, low);
627                 uint64_t arg2 = bits(Op2, high, low);
628                 uSaturateOp<8>(midRes, arg1, arg2, true);
629                 replaceBits(resTemp, high, low, midRes);
630            }
631            Dest = resTemp;
632        ''', flagType="none", buildCc=False)
633    buildRegDataInst("uqasx", '''
634            uint32_t midRes;
635            uint64_t arg1Low = bits(Op1_sw, 15, 0);
636            uint64_t arg1High = bits(Op1_sw, 31, 16);
637            uint64_t arg2Low = bits(Op2_sw, 15, 0);
638            uint64_t arg2High = bits(Op2_sw, 31, 16);
639            uSaturateOp<16>(midRes, arg1Low, arg2High, true);
640            replaceBits(resTemp, 15, 0, midRes);
641            uSaturateOp<16>(midRes, arg1High, arg2Low);
642            replaceBits(resTemp, 31, 16, midRes);
643            Dest = resTemp;
644        ''', flagType="none", buildCc=False)
645    buildRegDataInst("uqsax", '''
646            uint32_t midRes;
647            uint64_t arg1Low = bits(Op1_sw, 15, 0);
648            uint64_t arg1High = bits(Op1_sw, 31, 16);
649            uint64_t arg2Low = bits(Op2_sw, 15, 0);
650            uint64_t arg2High = bits(Op2_sw, 31, 16);
651            uSaturateOp<16>(midRes, arg1Low, arg2High);
652            replaceBits(resTemp, 15, 0, midRes);
653            uSaturateOp<16>(midRes, arg1High, arg2Low, true);
654            replaceBits(resTemp, 31, 16, midRes);
655            Dest = resTemp;
656        ''', flagType="none", buildCc=False)
657
658    buildRegDataInst("uadd16", '''
659            uint32_t geBits = 0;
660            resTemp = 0;
661            for (unsigned i = 0; i < 2; i++) {
662                int high = (i + 1) * 16 - 1;
663                int low = i * 16;
664                int32_t midRes = bits(Op1, high, low) +
665                                 bits(Op2, high, low);
666                if (midRes >= 0x10000) {
667                    geBits = geBits | (0x3 << (i * 2));
668                }
669                replaceBits(resTemp, high, low, midRes);
670            }
671            Dest = resTemp;
672            resTemp = geBits;
673        ''', flagType="ge", buildNonCc=False)
674    buildRegDataInst("uadd8", '''
675            uint32_t geBits = 0;
676            resTemp = 0;
677            for (unsigned i = 0; i < 4; i++) {
678                int high = (i + 1) * 8 - 1;
679                int low = i * 8;
680                int32_t midRes = bits(Op1, high, low) +
681                                 bits(Op2, high, low);
682                if (midRes >= 0x100) {
683                    geBits = geBits | (1 << i);
684                }
685                replaceBits(resTemp, high, low, midRes);
686            }
687            Dest = resTemp;
688            resTemp = geBits;
689        ''', flagType="ge", buildNonCc=False)
690    buildRegDataInst("usub16", '''
691            uint32_t geBits = 0;
692            resTemp = 0;
693            for (unsigned i = 0; i < 2; i++) {
694                int high = (i + 1) * 16 - 1;
695                int low = i * 16;
696                int32_t midRes = bits(Op1, high, low) -
697                                 bits(Op2, high, low);
698                if (midRes >= 0) {
699                    geBits = geBits | (0x3 << (i * 2));
700                }
701                replaceBits(resTemp, high, low, midRes);
702            }
703            Dest = resTemp;
704            resTemp = geBits;
705        ''', flagType="ge", buildNonCc=False)
706    buildRegDataInst("usub8", '''
707            uint32_t geBits = 0;
708            resTemp = 0;
709            for (unsigned i = 0; i < 4; i++) {
710                int high = (i + 1) * 8 - 1;
711                int low = i * 8;
712                int32_t midRes = bits(Op1, high, low) -
713                                 bits(Op2, high, low);
714                if (midRes >= 0) {
715                    geBits = geBits | (1 << i);
716                }
717                replaceBits(resTemp, high, low, midRes);
718            }
719            Dest = resTemp;
720            resTemp = geBits;
721        ''', flagType="ge", buildNonCc=False)
722    buildRegDataInst("uasx", '''
723            int32_t midRes, geBits = 0;
724            resTemp = 0;
725            int64_t arg1Low = bits(Op1_sw, 15, 0);
726            int64_t arg1High = bits(Op1_sw, 31, 16);
727            int64_t arg2Low = bits(Op2_sw, 15, 0);
728            int64_t arg2High = bits(Op2_sw, 31, 16);
729            midRes = arg1Low - arg2High;
730            if (midRes >= 0) {
731                geBits = geBits | 0x3;
732            }
733            replaceBits(resTemp, 15, 0, midRes);
734            midRes = arg1High + arg2Low;
735            if (midRes >= 0x10000) {
736                geBits = geBits | 0xc;
737            }
738            replaceBits(resTemp, 31, 16, midRes);
739            Dest = resTemp;
740            resTemp = geBits;
741        ''', flagType="ge", buildNonCc=False)
742    buildRegDataInst("usax", '''
743            int32_t midRes, geBits = 0;
744            resTemp = 0;
745            int64_t arg1Low = bits(Op1_sw, 15, 0);
746            int64_t arg1High = bits(Op1_sw, 31, 16);
747            int64_t arg2Low = bits(Op2_sw, 15, 0);
748            int64_t arg2High = bits(Op2_sw, 31, 16);
749            midRes = arg1Low + arg2High;
750            if (midRes >= 0x10000) {
751                geBits = geBits | 0x3;
752            }
753            replaceBits(resTemp, 15, 0, midRes);
754            midRes = arg1High - arg2Low;
755            if (midRes >= 0) {
756                geBits = geBits | 0xc;
757            }
758            replaceBits(resTemp, 31, 16, midRes);
759            Dest = resTemp;
760            resTemp = geBits;
761        ''', flagType="ge", buildNonCc=False)
762
763    buildRegDataInst("uhadd16", '''
764            resTemp = 0;
765            for (unsigned i = 0; i < 2; i++) {
766                int high = (i + 1) * 16 - 1;
767                int low = i * 16;
768                int32_t midRes = (bits(Op1, high, low) +
769                                  bits(Op2, high, low)) >> 1;
770                replaceBits(resTemp, high, low, midRes);
771            }
772            Dest = resTemp;
773        ''', flagType="none", buildCc=False)
774    buildRegDataInst("uhadd8", '''
775            resTemp = 0;
776            for (unsigned i = 0; i < 4; i++) {
777                int high = (i + 1) * 8 - 1;
778                int low = i * 8;
779                int32_t midRes = (bits(Op1, high, low) +
780                                  bits(Op2, high, low)) >> 1;
781                replaceBits(resTemp, high, low, midRes);
782            }
783            Dest = resTemp;
784        ''', flagType="none", buildCc=False)
785    buildRegDataInst("uhsub16", '''
786            resTemp = 0;
787            for (unsigned i = 0; i < 2; i++) {
788                int high = (i + 1) * 16 - 1;
789                int low = i * 16;
790                int32_t midRes = (bits(Op1, high, low) -
791                                  bits(Op2, high, low)) >> 1;
792                replaceBits(resTemp, high, low, midRes);
793            }
794            Dest = resTemp;
795        ''', flagType="none", buildCc=False)
796    buildRegDataInst("uhsub8", '''
797            resTemp = 0;
798            for (unsigned i = 0; i < 4; i++) {
799                int high = (i + 1) * 8 - 1;
800                int low = i * 8;
801                int32_t midRes = (bits(Op1, high, low) -
802                                  bits(Op2, high, low)) >> 1;
803                replaceBits(resTemp, high, low, midRes);
804            }
805            Dest = resTemp;
806        ''', flagType="none", buildCc=False)
807    buildRegDataInst("uhasx", '''
808            int32_t midRes;
809            resTemp = 0;
810            int64_t arg1Low = bits(Op1_sw, 15, 0);
811            int64_t arg1High = bits(Op1_sw, 31, 16);
812            int64_t arg2Low = bits(Op2_sw, 15, 0);
813            int64_t arg2High = bits(Op2_sw, 31, 16);
814            midRes = (arg1Low - arg2High) >> 1;
815            replaceBits(resTemp, 15, 0, midRes);
816            midRes = (arg1High + arg2Low) >> 1;
817            replaceBits(resTemp, 31, 16, midRes);
818            Dest = resTemp;
819        ''', flagType="none", buildCc=False)
820    buildRegDataInst("uhsax", '''
821            int32_t midRes;
822            resTemp = 0;
823            int64_t arg1Low = bits(Op1_sw, 15, 0);
824            int64_t arg1High = bits(Op1_sw, 31, 16);
825            int64_t arg2Low = bits(Op2_sw, 15, 0);
826            int64_t arg2High = bits(Op2_sw, 31, 16);
827            midRes = (arg1Low + arg2High) >> 1;
828            replaceBits(resTemp, 15, 0, midRes);
829            midRes = (arg1High - arg2Low) >> 1;
830            replaceBits(resTemp, 31, 16, midRes);
831            Dest = resTemp;
832        ''', flagType="none", buildCc=False)
833
834    buildRegDataInst("pkhbt", '''
835            uint32_t resTemp = 0;
836            uint16_t arg1Low = bits(Op1, 15, 0);
837            uint16_t arg2High = bits(secondOp, 31, 16);
838            replaceBits(resTemp, 15, 0, arg1Low);
839            replaceBits(resTemp, 31, 16, arg2High);
840            Dest = resTemp;
841        ''', flagType="none", buildCc=False)
842    buildRegDataInst("pkhtb", '''
843            uint32_t resTemp = 0;
844            uint16_t arg1High = bits(Op1, 31, 16);
845            uint16_t arg2Low = bits(secondOp, 15, 0);
846            replaceBits(resTemp, 15, 0, arg2Low);
847            replaceBits(resTemp, 31, 16, arg1High);
848            Dest = resTemp;
849        ''', flagType="none", buildCc=False)
850}};
851