data.isa revision 8304
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, OptShiftRmCondCodesC)"
107    regRegOp2 = "shift_rm_rs(Op2, Shift<7:0>, shiftType, 0)"
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": pickPredicate(immCode)}, instFlags)
130        immIopCc = InstObjParams(mnem + "s", mnem.capitalize() + suffix + "Cc",
131             "DataImmOp",
132             {"code" : immCode + immCcCode,
133              "predicate_test": pickPredicate(immCode + immCcCode)}, 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": pickPredicate(regCode)}, instFlags)
169        regIopCc = InstObjParams(mnem + "s", mnem.capitalize() + suffix + "Cc",
170                         "DataRegOp",
171                         {"code" : regCode + regCcCode,
172                          "predicate_test": pickPredicate(regCode + regCcCode),
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": pickPredicate(regRegCode)})
210        regRegIopCc = InstObjParams(mnem + "s",
211                mnem.capitalize() + suffix + "Cc",
212                "DataRegRegOp",
213                {"code" : regRegCode + regRegCcCode,
214                 "predicate_test": pickPredicate(regRegCode + regRegCcCode)})
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
245            CPSR new_cpsr =
246                cpsrWriteByInstr(old_cpsr, Spsr, 0xF, true, sctlr.nmfi);
247            Cpsr = ~CondCodesMask & new_cpsr;
248            CondCodesNZ = new_cpsr.nz;
249            CondCodesC = new_cpsr.c;
250            CondCodesV = new_cpsr.v;
251            CondCodesGE = new_cpsr.ge;
252
253            NextThumb = (new_cpsr).t;
254            NextJazelle = (new_cpsr).j;
255            NextItState = (((new_cpsr).it2 << 2) & 0xFC)
256                | ((new_cpsr).it1 & 0x3);
257            SevMailbox = 1;
258            '''
259            buildImmDataInst(mnem + 's', code, flagType,
260                             suffix = "ImmPclr", buildCc = False,
261                             instFlags = ["IsSerializeAfter","IsNonSpeculative"])
262            buildRegDataInst(mnem + 's', code, flagType,
263                             suffix = "RegPclr", buildCc = False,
264                             instFlags = ["IsSerializeAfter","IsNonSpeculative"])
265
266    buildDataInst("and", "Dest = resTemp = Op1 & secondOp;")
267    buildDataInst("eor", "Dest = resTemp = Op1 ^ secondOp;")
268    buildDataInst("sub", "Dest = resTemp = Op1 - secondOp;", "sub")
269    buildDataInst("rsb", "Dest = resTemp = secondOp - Op1;", "rsb")
270    buildDataInst("add", "Dest = resTemp = Op1 + secondOp;", "add")
271    buildImmDataInst("adr", '''
272                               Dest = resTemp = (PC & ~0x3) +
273                               (op1 ? secondOp : -secondOp);
274                            ''')
275    buildDataInst("adc", "Dest = resTemp = Op1 + secondOp + %s;" % oldC, "add")
276    buildDataInst("sbc", "Dest = resTemp = Op1 - secondOp - !%s;" % oldC, "sub")
277    buildDataInst("rsc", "Dest = resTemp = secondOp - Op1 - !%s;" % oldC, "rsb")
278    buildDataInst("tst", "resTemp = Op1 & secondOp;", aiw = False)
279    buildDataInst("teq", "resTemp = Op1 ^ secondOp;", aiw = False)
280    buildDataInst("cmp", "resTemp = Op1 - secondOp;", "sub", aiw = False)
281    buildDataInst("cmn", "resTemp = Op1 + secondOp;", "add", aiw = False)
282    buildDataInst("orr", "Dest = resTemp = Op1 | secondOp;")
283    buildDataInst("orn", "Dest = resTemp = Op1 | ~secondOp;", aiw = False)
284    buildDataInst("mov", "Dest = resTemp = secondOp;", regRegAiw = False,
285                  isRasPop = "op1 == INTREG_LR", isBranch = "dest == INTREG_PC")
286    buildDataInst("bic", "Dest = resTemp = Op1 & ~secondOp;")
287    buildDataInst("mvn", "Dest = resTemp = ~secondOp;")
288    buildDataInst("movt",
289                  "Dest = resTemp = insertBits(Op1, 31, 16, secondOp);",
290                  aiw = False)
291
292    buildRegDataInst("qadd", '''
293            int32_t midRes;
294            resTemp = saturateOp<32>(midRes, Op1.sw, Op2.sw);
295                                     Dest = midRes;
296        ''', flagType="saturate", buildNonCc=False)
297    buildRegDataInst("qadd16", '''
298            int32_t midRes;
299            for (unsigned i = 0; i < 2; i++) {
300                int high = (i + 1) * 16 - 1;
301                int low = i * 16;
302                int64_t arg1 = sext<16>(bits(Op1.sw, high, low));
303                int64_t arg2 = sext<16>(bits(Op2.sw, high, low));
304                saturateOp<16>(midRes, arg1, arg2);
305                replaceBits(resTemp, high, low, midRes);
306            }
307            Dest = resTemp;
308        ''', flagType="none", buildCc=False)
309    buildRegDataInst("qadd8", '''
310            int32_t midRes;
311            for (unsigned i = 0; i < 4; i++) {
312                int high = (i + 1) * 8 - 1;
313                int low = i * 8;
314                int64_t arg1 = sext<8>(bits(Op1.sw, high, low));
315                int64_t arg2 = sext<8>(bits(Op2.sw, high, low));
316                saturateOp<8>(midRes, arg1, arg2);
317                replaceBits(resTemp, high, low, midRes);
318            }
319            Dest = resTemp;
320        ''', flagType="none", buildCc=False)
321    buildRegDataInst("qdadd", '''
322            int32_t midRes;
323            resTemp = saturateOp<32>(midRes, Op2.sw, Op2.sw) |
324                      saturateOp<32>(midRes, Op1.sw, midRes);
325            Dest = midRes;
326        ''', flagType="saturate", buildNonCc=False)
327    buildRegDataInst("qsub", '''
328            int32_t midRes;
329            resTemp = saturateOp<32>(midRes, Op1.sw, Op2.sw, true);
330            Dest = midRes;
331        ''', flagType="saturate")
332    buildRegDataInst("qsub16", '''
333            int32_t midRes;
334            for (unsigned i = 0; i < 2; i++) {
335                 int high = (i + 1) * 16 - 1;
336                 int low = i * 16;
337                 int64_t arg1 = sext<16>(bits(Op1.sw, high, low));
338                 int64_t arg2 = sext<16>(bits(Op2.sw, high, low));
339                 saturateOp<16>(midRes, arg1, arg2, true);
340                 replaceBits(resTemp, high, low, midRes);
341            }
342            Dest = resTemp;
343        ''', flagType="none", buildCc=False)
344    buildRegDataInst("qsub8", '''
345            int32_t midRes;
346            for (unsigned i = 0; i < 4; i++) {
347                 int high = (i + 1) * 8 - 1;
348                 int low = i * 8;
349                 int64_t arg1 = sext<8>(bits(Op1.sw, high, low));
350                 int64_t arg2 = sext<8>(bits(Op2.sw, high, low));
351                 saturateOp<8>(midRes, arg1, arg2, true);
352                 replaceBits(resTemp, high, low, midRes);
353            }
354            Dest = resTemp;
355        ''', flagType="none", buildCc=False)
356    buildRegDataInst("qdsub", '''
357            int32_t midRes;
358            resTemp = saturateOp<32>(midRes, Op2.sw, Op2.sw) |
359                      saturateOp<32>(midRes, Op1.sw, midRes, true);
360            Dest = midRes;
361        ''', flagType="saturate", buildNonCc=False)
362    buildRegDataInst("qasx", '''
363            int32_t midRes;
364            int64_t arg1Low = sext<16>(bits(Op1.sw, 15, 0));
365            int64_t arg1High = sext<16>(bits(Op1.sw, 31, 16));
366            int64_t arg2Low = sext<16>(bits(Op2.sw, 15, 0));
367            int64_t arg2High = sext<16>(bits(Op2.sw, 31, 16));
368            saturateOp<16>(midRes, arg1Low, arg2High, true);
369            replaceBits(resTemp, 15, 0, midRes);
370            saturateOp<16>(midRes, arg1High, arg2Low);
371            replaceBits(resTemp, 31, 16, midRes);
372            Dest = resTemp;
373        ''', flagType="none", buildCc=False)
374    buildRegDataInst("qsax", '''
375            int32_t midRes;
376            int64_t arg1Low = sext<16>(bits(Op1.sw, 15, 0));
377            int64_t arg1High = sext<16>(bits(Op1.sw, 31, 16));
378            int64_t arg2Low = sext<16>(bits(Op2.sw, 15, 0));
379            int64_t arg2High = sext<16>(bits(Op2.sw, 31, 16));
380            saturateOp<16>(midRes, arg1Low, arg2High);
381            replaceBits(resTemp, 15, 0, midRes);
382            saturateOp<16>(midRes, arg1High, arg2Low, true);
383            replaceBits(resTemp, 31, 16, midRes);
384            Dest = resTemp;
385        ''', flagType="none", buildCc=False)
386
387    buildRegDataInst("sadd8", '''
388            uint32_t geBits = 0;
389            resTemp = 0;
390            for (unsigned i = 0; i < 4; i++) {
391                int high = (i + 1) * 8 - 1;
392                int low = i * 8;
393                int32_t midRes = sext<8>(bits(Op1.sw, high, low)) +
394                                 sext<8>(bits(Op2.sw, high, low));
395                replaceBits(resTemp, high, low, midRes);
396                if (midRes >= 0) {
397                    geBits = geBits | (1 << i);
398                }
399            }
400            Dest = resTemp;
401            resTemp = geBits;
402        ''', flagType="ge", buildNonCc=False)
403    buildRegDataInst("sadd16", '''
404            uint32_t geBits = 0;
405            resTemp = 0;
406            for (unsigned i = 0; i < 2; i++) {
407                int high = (i + 1) * 16 - 1;
408                int low = i * 16;
409                int32_t midRes = sext<16>(bits(Op1.sw, high, low)) +
410                                 sext<16>(bits(Op2.sw, high, low));
411                replaceBits(resTemp, high, low, midRes);
412                if (midRes >= 0) {
413                    geBits = geBits | (0x3 << (i * 2));
414                }
415            }
416            Dest = resTemp;
417            resTemp = geBits;
418        ''', flagType="ge", buildNonCc=False)
419
420    buildRegDataInst("ssub8", '''
421            uint32_t geBits = 0;
422            resTemp = 0;
423            for (unsigned i = 0; i < 4; i++) {
424                int high = (i + 1) * 8 - 1;
425                int low = i * 8;
426                int32_t midRes = sext<8>(bits(Op1.sw, high, low)) -
427                                 sext<8>(bits(Op2.sw, high, low));
428                replaceBits(resTemp, high, low, midRes);
429                if (midRes >= 0) {
430                    geBits = geBits | (1 << i);
431                }
432            }
433            Dest = resTemp;
434            resTemp = geBits;
435        ''', flagType="ge", buildNonCc=False)
436    buildRegDataInst("ssub16", '''
437            uint32_t geBits = 0;
438            resTemp = 0;
439            for (unsigned i = 0; i < 2; i++) {
440                int high = (i + 1) * 16 - 1;
441                int low = i * 16;
442                int32_t midRes = sext<16>(bits(Op1.sw, high, low)) -
443                                 sext<16>(bits(Op2.sw, high, low));
444                replaceBits(resTemp, high, low, midRes);
445                if (midRes >= 0) {
446                    geBits = geBits | (0x3 << (i * 2));
447                }
448            }
449            Dest = resTemp;
450            resTemp = geBits;
451        ''', flagType="ge", buildNonCc=False)
452    buildRegDataInst("sasx", '''
453            int32_t midRes, geBits = 0;
454            resTemp = 0;
455            int64_t arg1Low = sext<16>(bits(Op1.sw, 15, 0));
456            int64_t arg1High = sext<16>(bits(Op1.sw, 31, 16));
457            int64_t arg2Low = sext<16>(bits(Op2.sw, 15, 0));
458            int64_t arg2High = sext<16>(bits(Op2.sw, 31, 16));
459            midRes = arg1Low - arg2High;
460            if (midRes >= 0) {
461                geBits = geBits | 0x3;
462            }
463            replaceBits(resTemp, 15, 0, midRes);
464            midRes = arg1High + arg2Low;
465            if (midRes >= 0) {
466                geBits = geBits | 0xc;
467            }
468            replaceBits(resTemp, 31, 16, midRes);
469            Dest = resTemp;
470            resTemp = geBits;
471        ''', flagType="ge", buildNonCc=True)
472    buildRegDataInst("ssax", '''
473            int32_t midRes, geBits = 0;
474            resTemp = 0;
475            int64_t arg1Low = sext<16>(bits(Op1.sw, 15, 0));
476            int64_t arg1High = sext<16>(bits(Op1.sw, 31, 16));
477            int64_t arg2Low = sext<16>(bits(Op2.sw, 15, 0));
478            int64_t arg2High = sext<16>(bits(Op2.sw, 31, 16));
479            midRes = arg1Low + arg2High;
480            if (midRes >= 0) {
481                geBits = geBits | 0x3;
482            }
483            replaceBits(resTemp, 15, 0, midRes);
484            midRes = arg1High - arg2Low;
485            if (midRes >= 0) {
486                geBits = geBits | 0xc;
487            }
488            replaceBits(resTemp, 31, 16, midRes);
489            Dest = resTemp;
490            resTemp = geBits;
491        ''', flagType="ge", buildNonCc=True)
492
493    buildRegDataInst("shadd8", '''
494            resTemp = 0;
495            for (unsigned i = 0; i < 4; i++) {
496                int high = (i + 1) * 8 - 1;
497                int low = i * 8;
498                int32_t midRes =
499                    (uint64_t)(sext<8>(bits(Op1.sw, high, low)) +
500                               sext<8>(bits(Op2.sw, high, low))) >> 1;
501                replaceBits(resTemp, high, low, midRes);
502            }
503            Dest = resTemp;
504        ''', flagType="none", buildCc=False)
505    buildRegDataInst("shadd16", '''
506            resTemp = 0;
507            for (unsigned i = 0; i < 2; i++) {
508                int high = (i + 1) * 16 - 1;
509                int low = i * 16;
510                int32_t midRes =
511                    (uint64_t)(sext<16>(bits(Op1.sw, high, low)) +
512                               sext<16>(bits(Op2.sw, high, low))) >> 1;
513                replaceBits(resTemp, high, low, midRes);
514            }
515            Dest = resTemp;
516        ''', flagType="none", buildCc=False)
517    buildRegDataInst("shsub8", '''
518            resTemp = 0;
519            for (unsigned i = 0; i < 4; i++) {
520                int high = (i + 1) * 8 - 1;
521                int low = i * 8;
522                int32_t midRes =
523                    (uint64_t)(sext<8>(bits(Op1.sw, high, low)) -
524                               sext<8>(bits(Op2.sw, high, low))) >> 1;
525                replaceBits(resTemp, high, low, midRes);
526            }
527            Dest = resTemp;
528        ''', flagType="none", buildCc=False)
529    buildRegDataInst("shsub16", '''
530            resTemp = 0;
531            for (unsigned i = 0; i < 2; i++) {
532                int high = (i + 1) * 16 - 1;
533                int low = i * 16;
534                int32_t midRes =
535                    (uint64_t)(sext<16>(bits(Op1.sw, high, low)) -
536                               sext<16>(bits(Op2.sw, high, low))) >> 1;
537                replaceBits(resTemp, high, low, midRes);
538            }
539            Dest = resTemp;
540        ''', flagType="none", buildCc=False)
541    buildRegDataInst("shasx", '''
542            int32_t midRes;
543            resTemp = 0;
544            int64_t arg1Low = sext<16>(bits(Op1.sw, 15, 0));
545            int64_t arg1High = sext<16>(bits(Op1.sw, 31, 16));
546            int64_t arg2Low = sext<16>(bits(Op2.sw, 15, 0));
547            int64_t arg2High = sext<16>(bits(Op2.sw, 31, 16));
548            midRes = (uint64_t)(arg1Low - arg2High) >> 1;
549            replaceBits(resTemp, 15, 0, midRes);
550            midRes = (arg1High + arg2Low) >> 1;
551            replaceBits(resTemp, 31, 16, midRes);
552            Dest = resTemp;
553        ''', flagType="none", buildCc=True)
554    buildRegDataInst("shsax", '''
555            int32_t midRes;
556            resTemp = 0;
557            int64_t arg1Low = sext<16>(bits(Op1.sw, 15, 0));
558            int64_t arg1High = sext<16>(bits(Op1.sw, 31, 16));
559            int64_t arg2Low = sext<16>(bits(Op2.sw, 15, 0));
560            int64_t arg2High = sext<16>(bits(Op2.sw, 31, 16));
561            midRes = (uint64_t)(arg1Low + arg2High) >> 1;
562            replaceBits(resTemp, 15, 0, midRes);
563            midRes = (uint64_t)(arg1High - arg2Low) >> 1;
564            replaceBits(resTemp, 31, 16, midRes);
565            Dest = resTemp;
566        ''', flagType="none", buildCc=True)
567
568    buildRegDataInst("uqadd16", '''
569            uint32_t midRes;
570            for (unsigned i = 0; i < 2; i++) {
571                int high = (i + 1) * 16 - 1;
572                int low = i * 16;
573                uint64_t arg1 = bits(Op1, high, low);
574                uint64_t arg2 = bits(Op2, high, low);
575                uSaturateOp<16>(midRes, arg1, arg2);
576                replaceBits(resTemp, high, low, midRes);
577            }
578            Dest = resTemp;
579        ''', flagType="none", buildCc=False)
580    buildRegDataInst("uqadd8", '''
581            uint32_t midRes;
582            for (unsigned i = 0; i < 4; i++) {
583                int high = (i + 1) * 8 - 1;
584                int low = i * 8;
585                uint64_t arg1 = bits(Op1, high, low);
586                uint64_t arg2 = bits(Op2, high, low);
587                uSaturateOp<8>(midRes, arg1, arg2);
588                replaceBits(resTemp, high, low, midRes);
589            }
590            Dest = resTemp;
591        ''', flagType="none", buildCc=False)
592    buildRegDataInst("uqsub16", '''
593            uint32_t midRes;
594            for (unsigned i = 0; i < 2; i++) {
595                 int high = (i + 1) * 16 - 1;
596                 int low = i * 16;
597                 uint64_t arg1 = bits(Op1, high, low);
598                 uint64_t arg2 = bits(Op2, high, low);
599                 uSaturateOp<16>(midRes, arg1, arg2, true);
600                 replaceBits(resTemp, high, low, midRes);
601            }
602            Dest = resTemp;
603        ''', flagType="none", buildCc=False)
604    buildRegDataInst("uqsub8", '''
605            uint32_t midRes;
606            for (unsigned i = 0; i < 4; i++) {
607                 int high = (i + 1) * 8 - 1;
608                 int low = i * 8;
609                 uint64_t arg1 = bits(Op1, high, low);
610                 uint64_t arg2 = bits(Op2, high, low);
611                 uSaturateOp<8>(midRes, arg1, arg2, true);
612                 replaceBits(resTemp, high, low, midRes);
613            }
614            Dest = resTemp;
615        ''', flagType="none", buildCc=False)
616    buildRegDataInst("uqasx", '''
617            uint32_t midRes;
618            uint64_t arg1Low = bits(Op1.sw, 15, 0);
619            uint64_t arg1High = bits(Op1.sw, 31, 16);
620            uint64_t arg2Low = bits(Op2.sw, 15, 0);
621            uint64_t arg2High = bits(Op2.sw, 31, 16);
622            uSaturateOp<16>(midRes, arg1Low, arg2High, true);
623            replaceBits(resTemp, 15, 0, midRes);
624            uSaturateOp<16>(midRes, arg1High, arg2Low);
625            replaceBits(resTemp, 31, 16, midRes);
626            Dest = resTemp;
627        ''', flagType="none", buildCc=False)
628    buildRegDataInst("uqsax", '''
629            uint32_t midRes;
630            uint64_t arg1Low = bits(Op1.sw, 15, 0);
631            uint64_t arg1High = bits(Op1.sw, 31, 16);
632            uint64_t arg2Low = bits(Op2.sw, 15, 0);
633            uint64_t arg2High = bits(Op2.sw, 31, 16);
634            uSaturateOp<16>(midRes, arg1Low, arg2High);
635            replaceBits(resTemp, 15, 0, midRes);
636            uSaturateOp<16>(midRes, arg1High, arg2Low, true);
637            replaceBits(resTemp, 31, 16, midRes);
638            Dest = resTemp;
639        ''', flagType="none", buildCc=False)
640
641    buildRegDataInst("uadd16", '''
642            uint32_t geBits = 0;
643            resTemp = 0;
644            for (unsigned i = 0; i < 2; i++) {
645                int high = (i + 1) * 16 - 1;
646                int low = i * 16;
647                int32_t midRes = bits(Op1, high, low) +
648                                 bits(Op2, high, low);
649                if (midRes >= 0x10000) {
650                    geBits = geBits | (0x3 << (i * 2));
651                }
652                replaceBits(resTemp, high, low, midRes);
653            }
654            Dest = resTemp;
655            resTemp = geBits;
656        ''', flagType="ge", buildNonCc=False)
657    buildRegDataInst("uadd8", '''
658            uint32_t geBits = 0;
659            resTemp = 0;
660            for (unsigned i = 0; i < 4; i++) {
661                int high = (i + 1) * 8 - 1;
662                int low = i * 8;
663                int32_t midRes = bits(Op1, high, low) +
664                                 bits(Op2, high, low);
665                if (midRes >= 0x100) {
666                    geBits = geBits | (1 << i);
667                }
668                replaceBits(resTemp, high, low, midRes);
669            }
670            Dest = resTemp;
671            resTemp = geBits;
672        ''', flagType="ge", buildNonCc=False)
673    buildRegDataInst("usub16", '''
674            uint32_t geBits = 0;
675            resTemp = 0;
676            for (unsigned i = 0; i < 2; i++) {
677                int high = (i + 1) * 16 - 1;
678                int low = i * 16;
679                int32_t midRes = bits(Op1, high, low) -
680                                 bits(Op2, high, low);
681                if (midRes >= 0) {
682                    geBits = geBits | (0x3 << (i * 2));
683                }
684                replaceBits(resTemp, high, low, midRes);
685            }
686            Dest = resTemp;
687            resTemp = geBits;
688        ''', flagType="ge", buildNonCc=False)
689    buildRegDataInst("usub8", '''
690            uint32_t geBits = 0;
691            resTemp = 0;
692            for (unsigned i = 0; i < 4; i++) {
693                int high = (i + 1) * 8 - 1;
694                int low = i * 8;
695                int32_t midRes = bits(Op1, high, low) -
696                                 bits(Op2, high, low);
697                if (midRes >= 0) {
698                    geBits = geBits | (1 << i);
699                }
700                replaceBits(resTemp, high, low, midRes);
701            }
702            Dest = resTemp;
703            resTemp = geBits;
704        ''', flagType="ge", buildNonCc=False)
705    buildRegDataInst("uasx", '''
706            int32_t midRes, geBits = 0;
707            resTemp = 0;
708            int64_t arg1Low = bits(Op1.sw, 15, 0);
709            int64_t arg1High = bits(Op1.sw, 31, 16);
710            int64_t arg2Low = bits(Op2.sw, 15, 0);
711            int64_t arg2High = bits(Op2.sw, 31, 16);
712            midRes = arg1Low - arg2High;
713            if (midRes >= 0) {
714                geBits = geBits | 0x3;
715            }
716            replaceBits(resTemp, 15, 0, midRes);
717            midRes = arg1High + arg2Low;
718            if (midRes >= 0x10000) {
719                geBits = geBits | 0xc;
720            }
721            replaceBits(resTemp, 31, 16, midRes);
722            Dest = resTemp;
723            resTemp = geBits;
724        ''', flagType="ge", buildNonCc=False)
725    buildRegDataInst("usax", '''
726            int32_t midRes, geBits = 0;
727            resTemp = 0;
728            int64_t arg1Low = bits(Op1.sw, 15, 0);
729            int64_t arg1High = bits(Op1.sw, 31, 16);
730            int64_t arg2Low = bits(Op2.sw, 15, 0);
731            int64_t arg2High = bits(Op2.sw, 31, 16);
732            midRes = arg1Low + arg2High;
733            if (midRes >= 0x10000) {
734                geBits = geBits | 0x3;
735            }
736            replaceBits(resTemp, 15, 0, midRes);
737            midRes = arg1High - arg2Low;
738            if (midRes >= 0) {
739                geBits = geBits | 0xc;
740            }
741            replaceBits(resTemp, 31, 16, midRes);
742            Dest = resTemp;
743            resTemp = geBits;
744        ''', flagType="ge", buildNonCc=False)
745
746    buildRegDataInst("uhadd16", '''
747            resTemp = 0;
748            for (unsigned i = 0; i < 2; i++) {
749                int high = (i + 1) * 16 - 1;
750                int low = i * 16;
751                int32_t midRes = (bits(Op1, high, low) +
752                                  bits(Op2, high, low)) >> 1;
753                replaceBits(resTemp, high, low, midRes);
754            }
755            Dest = resTemp;
756        ''', flagType="none", buildCc=False)
757    buildRegDataInst("uhadd8", '''
758            resTemp = 0;
759            for (unsigned i = 0; i < 4; i++) {
760                int high = (i + 1) * 8 - 1;
761                int low = i * 8;
762                int32_t midRes = (bits(Op1, high, low) +
763                                  bits(Op2, high, low)) >> 1;
764                replaceBits(resTemp, high, low, midRes);
765            }
766            Dest = resTemp;
767        ''', flagType="none", buildCc=False)
768    buildRegDataInst("uhsub16", '''
769            resTemp = 0;
770            for (unsigned i = 0; i < 2; i++) {
771                int high = (i + 1) * 16 - 1;
772                int low = i * 16;
773                int32_t midRes = (bits(Op1, high, low) -
774                                  bits(Op2, high, low)) >> 1;
775                replaceBits(resTemp, high, low, midRes);
776            }
777            Dest = resTemp;
778        ''', flagType="none", buildCc=False)
779    buildRegDataInst("uhsub8", '''
780            resTemp = 0;
781            for (unsigned i = 0; i < 4; i++) {
782                int high = (i + 1) * 8 - 1;
783                int low = i * 8;
784                int32_t midRes = (bits(Op1, high, low) -
785                                  bits(Op2, high, low)) >> 1;
786                replaceBits(resTemp, high, low, midRes);
787            }
788            Dest = resTemp;
789        ''', flagType="none", buildCc=False)
790    buildRegDataInst("uhasx", '''
791            int32_t midRes;
792            resTemp = 0;
793            int64_t arg1Low = bits(Op1.sw, 15, 0);
794            int64_t arg1High = bits(Op1.sw, 31, 16);
795            int64_t arg2Low = bits(Op2.sw, 15, 0);
796            int64_t arg2High = bits(Op2.sw, 31, 16);
797            midRes = (arg1Low - arg2High) >> 1;
798            replaceBits(resTemp, 15, 0, midRes);
799            midRes = (arg1High + arg2Low) >> 1;
800            replaceBits(resTemp, 31, 16, midRes);
801            Dest = resTemp;
802        ''', flagType="none", buildCc=False)
803    buildRegDataInst("uhsax", '''
804            int32_t midRes;
805            resTemp = 0;
806            int64_t arg1Low = bits(Op1.sw, 15, 0);
807            int64_t arg1High = bits(Op1.sw, 31, 16);
808            int64_t arg2Low = bits(Op2.sw, 15, 0);
809            int64_t arg2High = bits(Op2.sw, 31, 16);
810            midRes = (arg1Low + arg2High) >> 1;
811            replaceBits(resTemp, 15, 0, midRes);
812            midRes = (arg1High - arg2Low) >> 1;
813            replaceBits(resTemp, 31, 16, midRes);
814            Dest = resTemp;
815        ''', flagType="none", buildCc=False)
816
817    buildRegDataInst("pkhbt", '''
818            uint32_t resTemp = 0;
819            uint16_t arg1Low = bits(Op1, 15, 0);
820            uint16_t arg2High = bits(secondOp, 31, 16);
821            replaceBits(resTemp, 15, 0, arg1Low);
822            replaceBits(resTemp, 31, 16, arg2High);
823            Dest = resTemp;
824        ''', flagType="none", buildCc=False)
825    buildRegDataInst("pkhtb", '''
826            uint32_t resTemp = 0;
827            uint16_t arg1High = bits(Op1, 31, 16);
828            uint16_t arg2Low = bits(secondOp, 15, 0);
829            replaceBits(resTemp, 15, 0, arg2Low);
830            replaceBits(resTemp, 31, 16, arg1High);
831            Dest = resTemp;
832        ''', flagType="none", buildCc=False)
833}};
834