data.isa revision 8303:5a95f1d2494e
1// -*- mode:c++ -*-
2
3// Copyright (c) 2010 ARM Limited
4// All rights reserved
5//
6// The license below extends only to copyright in the software and shall
7// not be construed as granting a license to any other intellectual
8// property including but not limited to intellectual property relating
9// to a hardware implementation of the functionality of the software
10// licensed hereunder.  You may use the software subject to the license
11// terms below provided that you ensure that this notice is replicated
12// unmodified and in its entirety in all distributions of the software,
13// modified or unmodified, in source code or in binary form.
14//
15// Redistribution and use in source and binary forms, with or without
16// modification, are permitted provided that the following conditions are
17// met: redistributions of source code must retain the above copyright
18// notice, this list of conditions and the following disclaimer;
19// redistributions in binary form must reproduce the above copyright
20// notice, this list of conditions and the following disclaimer in the
21// documentation and/or other materials provided with the distribution;
22// neither the name of the copyright holders nor the names of its
23// contributors may be used to endorse or promote products derived from
24// this software without specific prior written permission.
25//
26// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
27// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
28// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
29// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
30// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
31// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
32// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
33// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
34// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
35// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
36// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37//
38// Authors: Gabe Black
39
40let {{
41
42    header_output = ""
43    decoder_output = ""
44    exec_output = ""
45
46    calcGECode = '''
47        CondCodesGE = resTemp;
48    '''
49
50    calcQCode = '''
51        CpsrQ = (resTemp & 1) << 27;
52    '''
53
54    calcCcCode = '''
55        uint16_t _ic, _iv, _iz, _in;
56        _in = (resTemp >> %(negBit)d) & 1;
57        _iz = (resTemp == 0);
58        _iv = %(ivValue)s & 1;
59        _ic = %(icValue)s & 1;
60
61        CondCodesNZ = (_in << 1) | _iz;
62        CondCodesC =  _ic;
63        CondCodesV =  _iv;
64
65        DPRINTF(Arm, "(in, iz, ic, iv) = (%%d, %%d, %%d, %%d)\\n",
66                     _in, _iz, _ic, _iv);
67       '''
68
69    # Dict of code to set the carry flag. (imm, reg, reg-reg)
70    oldC = 'CondCodesC'
71    oldV = 'CondCodesV'
72    carryCode = {
73        "none": (oldC, oldC, oldC),
74        "llbit": (oldC, oldC, oldC),
75        "saturate": ('0', '0', '0'),
76        "overflow": ('0', '0', '0'),
77        "ge": ('0', '0', '0'),
78        "add": ('findCarry(32, resTemp, Op1, secondOp)',
79                'findCarry(32, resTemp, Op1, secondOp)',
80                'findCarry(32, resTemp, Op1, secondOp)'),
81        "sub": ('findCarry(32, resTemp, Op1, ~secondOp)',
82                'findCarry(32, resTemp, Op1, ~secondOp)',
83                'findCarry(32, resTemp, Op1, ~secondOp)'),
84        "rsb": ('findCarry(32, resTemp, secondOp, ~Op1)',
85                'findCarry(32, resTemp, secondOp, ~Op1)',
86                'findCarry(32, resTemp, secondOp, ~Op1)'),
87        "logic": ('(rotC ? bits(secondOp, 31) : %s)' % oldC,
88                  'shift_carry_imm(Op2, shiftAmt, shiftType, %s)' % oldC,
89                  'shift_carry_rs(Op2, Shift<7:0>, shiftType, %s)' % oldC)
90    }
91    # Dict of code to set the overflow flag.
92    overflowCode = {
93        "none": oldV,
94        "llbit": oldV,
95        "saturate": '0',
96        "overflow": '0',
97        "ge": '0',
98        "add": 'findOverflow(32, resTemp, Op1, secondOp)',
99        "sub": 'findOverflow(32, resTemp, Op1, ~secondOp)',
100        "rsb": 'findOverflow(32, resTemp, secondOp, ~Op1)',
101        "logic": oldV
102    }
103
104    secondOpRe = re.compile("secondOp")
105    immOp2 = "imm"
106    regOp2 = "shift_rm_imm(Op2, shiftAmt, shiftType, CondCodesC)"
107    regRegOp2 = "shift_rm_rs(Op2, Shift<7:0>, shiftType, CondCodesC)"
108
109    def buildImmDataInst(mnem, code, flagType = "logic", suffix = "Imm", \
110                         buildCc = True, buildNonCc = True, instFlags = []):
111        cCode = carryCode[flagType]
112        vCode = overflowCode[flagType]
113        negBit = 31
114        if flagType == "llbit":
115            negBit = 63
116        if flagType == "saturate":
117            immCcCode = calcQCode
118        elif flagType == "ge":
119            immCcCode = calcGECode
120        else:
121            immCcCode = calcCcCode % {
122                "icValue": secondOpRe.sub(immOp2, cCode[0]),
123                "ivValue": secondOpRe.sub(immOp2, vCode),
124                "negBit": negBit
125            }
126        immCode = secondOpRe.sub(immOp2, code)
127        immIop = InstObjParams(mnem, mnem.capitalize() + suffix, "DataImmOp",
128                               {"code" : immCode,
129                                "predicate_test": predicateTest}, instFlags)
130        immIopCc = InstObjParams(mnem + "s", mnem.capitalize() + suffix + "Cc",
131                                 "DataImmOp",
132                                 {"code" : immCode + immCcCode,
133                                  "predicate_test": condPredicateTest}, instFlags)
134
135        def subst(iop):
136            global header_output, decoder_output, exec_output
137            header_output += DataImmDeclare.subst(iop)
138            decoder_output += DataImmConstructor.subst(iop)
139            exec_output += PredOpExecute.subst(iop)
140
141        if buildNonCc:
142            subst(immIop)
143        if buildCc:
144            subst(immIopCc)
145
146    def buildRegDataInst(mnem, code, flagType = "logic", suffix = "Reg", \
147                         buildCc = True, buildNonCc = True, isRasPop = "0", \
148                         isBranch = "0", instFlags = []):
149        cCode = carryCode[flagType]
150        vCode = overflowCode[flagType]
151        negBit = 31
152        if flagType == "llbit":
153            negBit = 63
154        if flagType == "saturate":
155            regCcCode = calcQCode
156        elif flagType == "ge":
157            regCcCode = calcGECode
158        else:
159            regCcCode = calcCcCode % {
160                "icValue": secondOpRe.sub(regOp2, cCode[1]),
161                "ivValue": secondOpRe.sub(regOp2, vCode),
162                "negBit": negBit
163            }
164        regCode = secondOpRe.sub(regOp2, code)
165        regIop = InstObjParams(mnem, mnem.capitalize() + suffix, "DataRegOp",
166                               {"code" : regCode, "is_ras_pop" : isRasPop,
167                                "is_branch" : isBranch,
168                                "predicate_test": predicateTest}, instFlags)
169        regIopCc = InstObjParams(mnem + "s", mnem.capitalize() + suffix + "Cc",
170                                 "DataRegOp",
171                                 {"code" : regCode + regCcCode,
172                                  "predicate_test": condPredicateTest,
173                                  "is_ras_pop" : isRasPop,
174                                  "is_branch" : isBranch}, instFlags)
175
176        def subst(iop):
177            global header_output, decoder_output, exec_output
178            header_output += DataRegDeclare.subst(iop)
179            decoder_output += DataRegConstructor.subst(iop)
180            exec_output += PredOpExecute.subst(iop)
181
182        if buildNonCc:
183            subst(regIop)
184        if buildCc:
185            subst(regIopCc)
186
187    def buildRegRegDataInst(mnem, code, flagType = "logic", \
188                            suffix = "RegReg", \
189                            buildCc = True, buildNonCc = True):
190        cCode = carryCode[flagType]
191        vCode = overflowCode[flagType]
192        negBit = 31
193        if flagType == "llbit":
194            negBit = 63
195        if flagType == "saturate":
196            regRegCcCode = calcQCode
197        elif flagType == "ge":
198            regRegCcCode = calcGECode
199        else:
200            regRegCcCode = calcCcCode % {
201                "icValue": secondOpRe.sub(regRegOp2, cCode[2]),
202                "ivValue": secondOpRe.sub(regRegOp2, vCode),
203                "negBit": negBit
204            }
205        regRegCode = secondOpRe.sub(regRegOp2, code)
206        regRegIop = InstObjParams(mnem, mnem.capitalize() + suffix,
207                                  "DataRegRegOp",
208                                  {"code" : regRegCode,
209                                   "predicate_test": predicateTest})
210        regRegIopCc = InstObjParams(mnem + "s",
211                                    mnem.capitalize() + suffix + "Cc",
212                                    "DataRegRegOp",
213                                    {"code" : regRegCode + regRegCcCode,
214                                     "predicate_test": condPredicateTest})
215
216        def subst(iop):
217            global header_output, decoder_output, exec_output
218            header_output += DataRegRegDeclare.subst(iop)
219            decoder_output += DataRegRegConstructor.subst(iop)
220            exec_output += PredOpExecute.subst(iop)
221
222        if buildNonCc:
223            subst(regRegIop)
224        if buildCc:
225            subst(regRegIopCc)
226
227    def buildDataInst(mnem, code, flagType = "logic", \
228                      aiw = True, regRegAiw = True,
229                      subsPcLr = True, isRasPop = "0", isBranch = "0"):
230        regRegCode = instCode = code
231        if aiw:
232            instCode = "AIW" + instCode
233            if regRegAiw:
234                regRegCode = "AIW" + regRegCode
235
236        buildImmDataInst(mnem, instCode, flagType)
237        buildRegDataInst(mnem, instCode, flagType,
238                         isRasPop = isRasPop, isBranch = isBranch)
239        buildRegRegDataInst(mnem, regRegCode, flagType)
240        if subsPcLr:
241            code += '''
242            SCTLR sctlr = Sctlr;
243            CPSR old_cpsr = Cpsr;
244            old_cpsr.nz = CondCodesNZ;
245            old_cpsr.c = CondCodesC;
246            old_cpsr.v = CondCodesV;
247            old_cpsr.ge = CondCodesGE;
248
249            CPSR new_cpsr =
250                cpsrWriteByInstr(old_cpsr, Spsr, 0xF, true, sctlr.nmfi);
251            Cpsr = ~CondCodesMask & new_cpsr;
252            CondCodesNZ = new_cpsr.nz;
253            CondCodesC = new_cpsr.c;
254            CondCodesV = new_cpsr.v;
255            CondCodesGE = new_cpsr.ge;
256
257            NextThumb = (new_cpsr).t;
258            NextJazelle = (new_cpsr).j;
259            NextItState = (((new_cpsr).it2 << 2) & 0xFC)
260                | ((new_cpsr).it1 & 0x3);
261            SevMailbox = 1;
262            '''
263            buildImmDataInst(mnem + 's', code, flagType,
264                             suffix = "ImmPclr", buildCc = False,
265                             instFlags = ["IsSerializeAfter","IsNonSpeculative"])
266            buildRegDataInst(mnem + 's', code, flagType,
267                             suffix = "RegPclr", buildCc = False,
268                             instFlags = ["IsSerializeAfter","IsNonSpeculative"])
269
270    buildDataInst("and", "Dest = resTemp = Op1 & secondOp;")
271    buildDataInst("eor", "Dest = resTemp = Op1 ^ secondOp;")
272    buildDataInst("sub", "Dest = resTemp = Op1 - secondOp;", "sub")
273    buildDataInst("rsb", "Dest = resTemp = secondOp - Op1;", "rsb")
274    buildDataInst("add", "Dest = resTemp = Op1 + secondOp;", "add")
275    buildImmDataInst("adr", '''
276                               Dest = resTemp = (PC & ~0x3) +
277                               (op1 ? secondOp : -secondOp);
278                            ''')
279    buildDataInst("adc", "Dest = resTemp = Op1 + secondOp + %s;" % oldC, "add")
280    buildDataInst("sbc", "Dest = resTemp = Op1 - secondOp - !%s;" % oldC, "sub")
281    buildDataInst("rsc", "Dest = resTemp = secondOp - Op1 - !%s;" % oldC, "rsb")
282    buildDataInst("tst", "resTemp = Op1 & secondOp;", aiw = False)
283    buildDataInst("teq", "resTemp = Op1 ^ secondOp;", aiw = False)
284    buildDataInst("cmp", "resTemp = Op1 - secondOp;", "sub", aiw = False)
285    buildDataInst("cmn", "resTemp = Op1 + secondOp;", "add", aiw = False)
286    buildDataInst("orr", "Dest = resTemp = Op1 | secondOp;")
287    buildDataInst("orn", "Dest = resTemp = Op1 | ~secondOp;", aiw = False)
288    buildDataInst("mov", "Dest = resTemp = secondOp;", regRegAiw = False,
289                  isRasPop = "op1 == INTREG_LR", isBranch = "dest == INTREG_PC")
290    buildDataInst("bic", "Dest = resTemp = Op1 & ~secondOp;")
291    buildDataInst("mvn", "Dest = resTemp = ~secondOp;")
292    buildDataInst("movt",
293                  "Dest = resTemp = insertBits(Op1, 31, 16, secondOp);",
294                  aiw = False)
295
296    buildRegDataInst("qadd", '''
297            int32_t midRes;
298            resTemp = saturateOp<32>(midRes, Op1.sw, Op2.sw);
299                                     Dest = midRes;
300        ''', flagType="saturate", buildNonCc=False)
301    buildRegDataInst("qadd16", '''
302            int32_t midRes;
303            for (unsigned i = 0; i < 2; i++) {
304                int high = (i + 1) * 16 - 1;
305                int low = i * 16;
306                int64_t arg1 = sext<16>(bits(Op1.sw, high, low));
307                int64_t arg2 = sext<16>(bits(Op2.sw, high, low));
308                saturateOp<16>(midRes, arg1, arg2);
309                replaceBits(resTemp, high, low, midRes);
310            }
311            Dest = resTemp;
312        ''', flagType="none", buildCc=False)
313    buildRegDataInst("qadd8", '''
314            int32_t midRes;
315            for (unsigned i = 0; i < 4; i++) {
316                int high = (i + 1) * 8 - 1;
317                int low = i * 8;
318                int64_t arg1 = sext<8>(bits(Op1.sw, high, low));
319                int64_t arg2 = sext<8>(bits(Op2.sw, high, low));
320                saturateOp<8>(midRes, arg1, arg2);
321                replaceBits(resTemp, high, low, midRes);
322            }
323            Dest = resTemp;
324        ''', flagType="none", buildCc=False)
325    buildRegDataInst("qdadd", '''
326            int32_t midRes;
327            resTemp = saturateOp<32>(midRes, Op2.sw, Op2.sw) |
328                      saturateOp<32>(midRes, Op1.sw, midRes);
329            Dest = midRes;
330        ''', flagType="saturate", buildNonCc=False)
331    buildRegDataInst("qsub", '''
332            int32_t midRes;
333            resTemp = saturateOp<32>(midRes, Op1.sw, Op2.sw, true);
334            Dest = midRes;
335        ''', flagType="saturate")
336    buildRegDataInst("qsub16", '''
337            int32_t midRes;
338            for (unsigned i = 0; i < 2; i++) {
339                 int high = (i + 1) * 16 - 1;
340                 int low = i * 16;
341                 int64_t arg1 = sext<16>(bits(Op1.sw, high, low));
342                 int64_t arg2 = sext<16>(bits(Op2.sw, high, low));
343                 saturateOp<16>(midRes, arg1, arg2, true);
344                 replaceBits(resTemp, high, low, midRes);
345            }
346            Dest = resTemp;
347        ''', flagType="none", buildCc=False)
348    buildRegDataInst("qsub8", '''
349            int32_t midRes;
350            for (unsigned i = 0; i < 4; i++) {
351                 int high = (i + 1) * 8 - 1;
352                 int low = i * 8;
353                 int64_t arg1 = sext<8>(bits(Op1.sw, high, low));
354                 int64_t arg2 = sext<8>(bits(Op2.sw, high, low));
355                 saturateOp<8>(midRes, arg1, arg2, true);
356                 replaceBits(resTemp, high, low, midRes);
357            }
358            Dest = resTemp;
359        ''', flagType="none", buildCc=False)
360    buildRegDataInst("qdsub", '''
361            int32_t midRes;
362            resTemp = saturateOp<32>(midRes, Op2.sw, Op2.sw) |
363                      saturateOp<32>(midRes, Op1.sw, midRes, true);
364            Dest = midRes;
365        ''', flagType="saturate", buildNonCc=False)
366    buildRegDataInst("qasx", '''
367            int32_t midRes;
368            int64_t arg1Low = sext<16>(bits(Op1.sw, 15, 0));
369            int64_t arg1High = sext<16>(bits(Op1.sw, 31, 16));
370            int64_t arg2Low = sext<16>(bits(Op2.sw, 15, 0));
371            int64_t arg2High = sext<16>(bits(Op2.sw, 31, 16));
372            saturateOp<16>(midRes, arg1Low, arg2High, true);
373            replaceBits(resTemp, 15, 0, midRes);
374            saturateOp<16>(midRes, arg1High, arg2Low);
375            replaceBits(resTemp, 31, 16, midRes);
376            Dest = resTemp;
377        ''', flagType="none", buildCc=False)
378    buildRegDataInst("qsax", '''
379            int32_t midRes;
380            int64_t arg1Low = sext<16>(bits(Op1.sw, 15, 0));
381            int64_t arg1High = sext<16>(bits(Op1.sw, 31, 16));
382            int64_t arg2Low = sext<16>(bits(Op2.sw, 15, 0));
383            int64_t arg2High = sext<16>(bits(Op2.sw, 31, 16));
384            saturateOp<16>(midRes, arg1Low, arg2High);
385            replaceBits(resTemp, 15, 0, midRes);
386            saturateOp<16>(midRes, arg1High, arg2Low, true);
387            replaceBits(resTemp, 31, 16, midRes);
388            Dest = resTemp;
389        ''', flagType="none", buildCc=False)
390
391    buildRegDataInst("sadd8", '''
392            uint32_t geBits = 0;
393            resTemp = 0;
394            for (unsigned i = 0; i < 4; i++) {
395                int high = (i + 1) * 8 - 1;
396                int low = i * 8;
397                int32_t midRes = sext<8>(bits(Op1.sw, high, low)) +
398                                 sext<8>(bits(Op2.sw, high, low));
399                replaceBits(resTemp, high, low, midRes);
400                if (midRes >= 0) {
401                    geBits = geBits | (1 << i);
402                }
403            }
404            Dest = resTemp;
405            resTemp = geBits;
406        ''', flagType="ge", buildNonCc=False)
407    buildRegDataInst("sadd16", '''
408            uint32_t geBits = 0;
409            resTemp = 0;
410            for (unsigned i = 0; i < 2; i++) {
411                int high = (i + 1) * 16 - 1;
412                int low = i * 16;
413                int32_t midRes = sext<16>(bits(Op1.sw, high, low)) +
414                                 sext<16>(bits(Op2.sw, high, low));
415                replaceBits(resTemp, high, low, midRes);
416                if (midRes >= 0) {
417                    geBits = geBits | (0x3 << (i * 2));
418                }
419            }
420            Dest = resTemp;
421            resTemp = geBits;
422        ''', flagType="ge", buildNonCc=False)
423
424    buildRegDataInst("ssub8", '''
425            uint32_t geBits = 0;
426            resTemp = 0;
427            for (unsigned i = 0; i < 4; i++) {
428                int high = (i + 1) * 8 - 1;
429                int low = i * 8;
430                int32_t midRes = sext<8>(bits(Op1.sw, high, low)) -
431                                 sext<8>(bits(Op2.sw, high, low));
432                replaceBits(resTemp, high, low, midRes);
433                if (midRes >= 0) {
434                    geBits = geBits | (1 << i);
435                }
436            }
437            Dest = resTemp;
438            resTemp = geBits;
439        ''', flagType="ge", buildNonCc=False)
440    buildRegDataInst("ssub16", '''
441            uint32_t geBits = 0;
442            resTemp = 0;
443            for (unsigned i = 0; i < 2; i++) {
444                int high = (i + 1) * 16 - 1;
445                int low = i * 16;
446                int32_t midRes = sext<16>(bits(Op1.sw, high, low)) -
447                                 sext<16>(bits(Op2.sw, high, low));
448                replaceBits(resTemp, high, low, midRes);
449                if (midRes >= 0) {
450                    geBits = geBits | (0x3 << (i * 2));
451                }
452            }
453            Dest = resTemp;
454            resTemp = geBits;
455        ''', flagType="ge", buildNonCc=False)
456    buildRegDataInst("sasx", '''
457            int32_t midRes, geBits = 0;
458            resTemp = 0;
459            int64_t arg1Low = sext<16>(bits(Op1.sw, 15, 0));
460            int64_t arg1High = sext<16>(bits(Op1.sw, 31, 16));
461            int64_t arg2Low = sext<16>(bits(Op2.sw, 15, 0));
462            int64_t arg2High = sext<16>(bits(Op2.sw, 31, 16));
463            midRes = arg1Low - arg2High;
464            if (midRes >= 0) {
465                geBits = geBits | 0x3;
466            }
467            replaceBits(resTemp, 15, 0, midRes);
468            midRes = arg1High + arg2Low;
469            if (midRes >= 0) {
470                geBits = geBits | 0xc;
471            }
472            replaceBits(resTemp, 31, 16, midRes);
473            Dest = resTemp;
474            resTemp = geBits;
475        ''', flagType="ge", buildNonCc=True)
476    buildRegDataInst("ssax", '''
477            int32_t midRes, geBits = 0;
478            resTemp = 0;
479            int64_t arg1Low = sext<16>(bits(Op1.sw, 15, 0));
480            int64_t arg1High = sext<16>(bits(Op1.sw, 31, 16));
481            int64_t arg2Low = sext<16>(bits(Op2.sw, 15, 0));
482            int64_t arg2High = sext<16>(bits(Op2.sw, 31, 16));
483            midRes = arg1Low + arg2High;
484            if (midRes >= 0) {
485                geBits = geBits | 0x3;
486            }
487            replaceBits(resTemp, 15, 0, midRes);
488            midRes = arg1High - arg2Low;
489            if (midRes >= 0) {
490                geBits = geBits | 0xc;
491            }
492            replaceBits(resTemp, 31, 16, midRes);
493            Dest = resTemp;
494            resTemp = geBits;
495        ''', flagType="ge", buildNonCc=True)
496
497    buildRegDataInst("shadd8", '''
498            resTemp = 0;
499            for (unsigned i = 0; i < 4; i++) {
500                int high = (i + 1) * 8 - 1;
501                int low = i * 8;
502                int32_t midRes =
503                    (uint64_t)(sext<8>(bits(Op1.sw, high, low)) +
504                               sext<8>(bits(Op2.sw, high, low))) >> 1;
505                replaceBits(resTemp, high, low, midRes);
506            }
507            Dest = resTemp;
508        ''', flagType="none", buildCc=False)
509    buildRegDataInst("shadd16", '''
510            resTemp = 0;
511            for (unsigned i = 0; i < 2; i++) {
512                int high = (i + 1) * 16 - 1;
513                int low = i * 16;
514                int32_t midRes =
515                    (uint64_t)(sext<16>(bits(Op1.sw, high, low)) +
516                               sext<16>(bits(Op2.sw, high, low))) >> 1;
517                replaceBits(resTemp, high, low, midRes);
518            }
519            Dest = resTemp;
520        ''', flagType="none", buildCc=False)
521    buildRegDataInst("shsub8", '''
522            resTemp = 0;
523            for (unsigned i = 0; i < 4; i++) {
524                int high = (i + 1) * 8 - 1;
525                int low = i * 8;
526                int32_t midRes =
527                    (uint64_t)(sext<8>(bits(Op1.sw, high, low)) -
528                               sext<8>(bits(Op2.sw, high, low))) >> 1;
529                replaceBits(resTemp, high, low, midRes);
530            }
531            Dest = resTemp;
532        ''', flagType="none", buildCc=False)
533    buildRegDataInst("shsub16", '''
534            resTemp = 0;
535            for (unsigned i = 0; i < 2; i++) {
536                int high = (i + 1) * 16 - 1;
537                int low = i * 16;
538                int32_t midRes =
539                    (uint64_t)(sext<16>(bits(Op1.sw, high, low)) -
540                               sext<16>(bits(Op2.sw, high, low))) >> 1;
541                replaceBits(resTemp, high, low, midRes);
542            }
543            Dest = resTemp;
544        ''', flagType="none", buildCc=False)
545    buildRegDataInst("shasx", '''
546            int32_t midRes;
547            resTemp = 0;
548            int64_t arg1Low = sext<16>(bits(Op1.sw, 15, 0));
549            int64_t arg1High = sext<16>(bits(Op1.sw, 31, 16));
550            int64_t arg2Low = sext<16>(bits(Op2.sw, 15, 0));
551            int64_t arg2High = sext<16>(bits(Op2.sw, 31, 16));
552            midRes = (uint64_t)(arg1Low - arg2High) >> 1;
553            replaceBits(resTemp, 15, 0, midRes);
554            midRes = (arg1High + arg2Low) >> 1;
555            replaceBits(resTemp, 31, 16, midRes);
556            Dest = resTemp;
557        ''', flagType="none", buildCc=True)
558    buildRegDataInst("shsax", '''
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 = (uint64_t)(arg1High - arg2Low) >> 1;
568            replaceBits(resTemp, 31, 16, midRes);
569            Dest = resTemp;
570        ''', flagType="none", buildCc=True)
571
572    buildRegDataInst("uqadd16", '''
573            uint32_t midRes;
574            for (unsigned i = 0; i < 2; i++) {
575                int high = (i + 1) * 16 - 1;
576                int low = i * 16;
577                uint64_t arg1 = bits(Op1, high, low);
578                uint64_t arg2 = bits(Op2, high, low);
579                uSaturateOp<16>(midRes, arg1, arg2);
580                replaceBits(resTemp, high, low, midRes);
581            }
582            Dest = resTemp;
583        ''', flagType="none", buildCc=False)
584    buildRegDataInst("uqadd8", '''
585            uint32_t midRes;
586            for (unsigned i = 0; i < 4; i++) {
587                int high = (i + 1) * 8 - 1;
588                int low = i * 8;
589                uint64_t arg1 = bits(Op1, high, low);
590                uint64_t arg2 = bits(Op2, high, low);
591                uSaturateOp<8>(midRes, arg1, arg2);
592                replaceBits(resTemp, high, low, midRes);
593            }
594            Dest = resTemp;
595        ''', flagType="none", buildCc=False)
596    buildRegDataInst("uqsub16", '''
597            uint32_t midRes;
598            for (unsigned i = 0; i < 2; i++) {
599                 int high = (i + 1) * 16 - 1;
600                 int low = i * 16;
601                 uint64_t arg1 = bits(Op1, high, low);
602                 uint64_t arg2 = bits(Op2, high, low);
603                 uSaturateOp<16>(midRes, arg1, arg2, true);
604                 replaceBits(resTemp, high, low, midRes);
605            }
606            Dest = resTemp;
607        ''', flagType="none", buildCc=False)
608    buildRegDataInst("uqsub8", '''
609            uint32_t midRes;
610            for (unsigned i = 0; i < 4; i++) {
611                 int high = (i + 1) * 8 - 1;
612                 int low = i * 8;
613                 uint64_t arg1 = bits(Op1, high, low);
614                 uint64_t arg2 = bits(Op2, high, low);
615                 uSaturateOp<8>(midRes, arg1, arg2, true);
616                 replaceBits(resTemp, high, low, midRes);
617            }
618            Dest = resTemp;
619        ''', flagType="none", buildCc=False)
620    buildRegDataInst("uqasx", '''
621            uint32_t midRes;
622            uint64_t arg1Low = bits(Op1.sw, 15, 0);
623            uint64_t arg1High = bits(Op1.sw, 31, 16);
624            uint64_t arg2Low = bits(Op2.sw, 15, 0);
625            uint64_t arg2High = bits(Op2.sw, 31, 16);
626            uSaturateOp<16>(midRes, arg1Low, arg2High, true);
627            replaceBits(resTemp, 15, 0, midRes);
628            uSaturateOp<16>(midRes, arg1High, arg2Low);
629            replaceBits(resTemp, 31, 16, midRes);
630            Dest = resTemp;
631        ''', flagType="none", buildCc=False)
632    buildRegDataInst("uqsax", '''
633            uint32_t midRes;
634            uint64_t arg1Low = bits(Op1.sw, 15, 0);
635            uint64_t arg1High = bits(Op1.sw, 31, 16);
636            uint64_t arg2Low = bits(Op2.sw, 15, 0);
637            uint64_t arg2High = bits(Op2.sw, 31, 16);
638            uSaturateOp<16>(midRes, arg1Low, arg2High);
639            replaceBits(resTemp, 15, 0, midRes);
640            uSaturateOp<16>(midRes, arg1High, arg2Low, true);
641            replaceBits(resTemp, 31, 16, midRes);
642            Dest = resTemp;
643        ''', flagType="none", buildCc=False)
644
645    buildRegDataInst("uadd16", '''
646            uint32_t geBits = 0;
647            resTemp = 0;
648            for (unsigned i = 0; i < 2; i++) {
649                int high = (i + 1) * 16 - 1;
650                int low = i * 16;
651                int32_t midRes = bits(Op1, high, low) +
652                                 bits(Op2, high, low);
653                if (midRes >= 0x10000) {
654                    geBits = geBits | (0x3 << (i * 2));
655                }
656                replaceBits(resTemp, high, low, midRes);
657            }
658            Dest = resTemp;
659            resTemp = geBits;
660        ''', flagType="ge", buildNonCc=False)
661    buildRegDataInst("uadd8", '''
662            uint32_t geBits = 0;
663            resTemp = 0;
664            for (unsigned i = 0; i < 4; i++) {
665                int high = (i + 1) * 8 - 1;
666                int low = i * 8;
667                int32_t midRes = bits(Op1, high, low) +
668                                 bits(Op2, high, low);
669                if (midRes >= 0x100) {
670                    geBits = geBits | (1 << i);
671                }
672                replaceBits(resTemp, high, low, midRes);
673            }
674            Dest = resTemp;
675            resTemp = geBits;
676        ''', flagType="ge", buildNonCc=False)
677    buildRegDataInst("usub16", '''
678            uint32_t geBits = 0;
679            resTemp = 0;
680            for (unsigned i = 0; i < 2; i++) {
681                int high = (i + 1) * 16 - 1;
682                int low = i * 16;
683                int32_t midRes = bits(Op1, high, low) -
684                                 bits(Op2, high, low);
685                if (midRes >= 0) {
686                    geBits = geBits | (0x3 << (i * 2));
687                }
688                replaceBits(resTemp, high, low, midRes);
689            }
690            Dest = resTemp;
691            resTemp = geBits;
692        ''', flagType="ge", buildNonCc=False)
693    buildRegDataInst("usub8", '''
694            uint32_t geBits = 0;
695            resTemp = 0;
696            for (unsigned i = 0; i < 4; i++) {
697                int high = (i + 1) * 8 - 1;
698                int low = i * 8;
699                int32_t midRes = bits(Op1, high, low) -
700                                 bits(Op2, high, low);
701                if (midRes >= 0) {
702                    geBits = geBits | (1 << i);
703                }
704                replaceBits(resTemp, high, low, midRes);
705            }
706            Dest = resTemp;
707            resTemp = geBits;
708        ''', flagType="ge", buildNonCc=False)
709    buildRegDataInst("uasx", '''
710            int32_t midRes, geBits = 0;
711            resTemp = 0;
712            int64_t arg1Low = bits(Op1.sw, 15, 0);
713            int64_t arg1High = bits(Op1.sw, 31, 16);
714            int64_t arg2Low = bits(Op2.sw, 15, 0);
715            int64_t arg2High = bits(Op2.sw, 31, 16);
716            midRes = arg1Low - arg2High;
717            if (midRes >= 0) {
718                geBits = geBits | 0x3;
719            }
720            replaceBits(resTemp, 15, 0, midRes);
721            midRes = arg1High + arg2Low;
722            if (midRes >= 0x10000) {
723                geBits = geBits | 0xc;
724            }
725            replaceBits(resTemp, 31, 16, midRes);
726            Dest = resTemp;
727            resTemp = geBits;
728        ''', flagType="ge", buildNonCc=False)
729    buildRegDataInst("usax", '''
730            int32_t midRes, geBits = 0;
731            resTemp = 0;
732            int64_t arg1Low = bits(Op1.sw, 15, 0);
733            int64_t arg1High = bits(Op1.sw, 31, 16);
734            int64_t arg2Low = bits(Op2.sw, 15, 0);
735            int64_t arg2High = bits(Op2.sw, 31, 16);
736            midRes = arg1Low + arg2High;
737            if (midRes >= 0x10000) {
738                geBits = geBits | 0x3;
739            }
740            replaceBits(resTemp, 15, 0, midRes);
741            midRes = arg1High - arg2Low;
742            if (midRes >= 0) {
743                geBits = geBits | 0xc;
744            }
745            replaceBits(resTemp, 31, 16, midRes);
746            Dest = resTemp;
747            resTemp = geBits;
748        ''', flagType="ge", buildNonCc=False)
749
750    buildRegDataInst("uhadd16", '''
751            resTemp = 0;
752            for (unsigned i = 0; i < 2; i++) {
753                int high = (i + 1) * 16 - 1;
754                int low = i * 16;
755                int32_t midRes = (bits(Op1, high, low) +
756                                  bits(Op2, high, low)) >> 1;
757                replaceBits(resTemp, high, low, midRes);
758            }
759            Dest = resTemp;
760        ''', flagType="none", buildCc=False)
761    buildRegDataInst("uhadd8", '''
762            resTemp = 0;
763            for (unsigned i = 0; i < 4; i++) {
764                int high = (i + 1) * 8 - 1;
765                int low = i * 8;
766                int32_t midRes = (bits(Op1, high, low) +
767                                  bits(Op2, high, low)) >> 1;
768                replaceBits(resTemp, high, low, midRes);
769            }
770            Dest = resTemp;
771        ''', flagType="none", buildCc=False)
772    buildRegDataInst("uhsub16", '''
773            resTemp = 0;
774            for (unsigned i = 0; i < 2; i++) {
775                int high = (i + 1) * 16 - 1;
776                int low = i * 16;
777                int32_t midRes = (bits(Op1, high, low) -
778                                  bits(Op2, high, low)) >> 1;
779                replaceBits(resTemp, high, low, midRes);
780            }
781            Dest = resTemp;
782        ''', flagType="none", buildCc=False)
783    buildRegDataInst("uhsub8", '''
784            resTemp = 0;
785            for (unsigned i = 0; i < 4; i++) {
786                int high = (i + 1) * 8 - 1;
787                int low = i * 8;
788                int32_t midRes = (bits(Op1, high, low) -
789                                  bits(Op2, high, low)) >> 1;
790                replaceBits(resTemp, high, low, midRes);
791            }
792            Dest = resTemp;
793        ''', flagType="none", buildCc=False)
794    buildRegDataInst("uhasx", '''
795            int32_t midRes;
796            resTemp = 0;
797            int64_t arg1Low = bits(Op1.sw, 15, 0);
798            int64_t arg1High = bits(Op1.sw, 31, 16);
799            int64_t arg2Low = bits(Op2.sw, 15, 0);
800            int64_t arg2High = bits(Op2.sw, 31, 16);
801            midRes = (arg1Low - arg2High) >> 1;
802            replaceBits(resTemp, 15, 0, midRes);
803            midRes = (arg1High + arg2Low) >> 1;
804            replaceBits(resTemp, 31, 16, midRes);
805            Dest = resTemp;
806        ''', flagType="none", buildCc=False)
807    buildRegDataInst("uhsax", '''
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
821    buildRegDataInst("pkhbt", '''
822            uint32_t resTemp = 0;
823            uint16_t arg1Low = bits(Op1, 15, 0);
824            uint16_t arg2High = bits(secondOp, 31, 16);
825            replaceBits(resTemp, 15, 0, arg1Low);
826            replaceBits(resTemp, 31, 16, arg2High);
827            Dest = resTemp;
828        ''', flagType="none", buildCc=False)
829    buildRegDataInst("pkhtb", '''
830            uint32_t resTemp = 0;
831            uint16_t arg1High = bits(Op1, 31, 16);
832            uint16_t arg2Low = bits(secondOp, 15, 0);
833            replaceBits(resTemp, 15, 0, arg2Low);
834            replaceBits(resTemp, 31, 16, arg1High);
835            Dest = resTemp;
836        ''', flagType="none", buildCc=False)
837}};
838