data.isa revision 10037
1// -*- mode:c++ -*-
2
3// Copyright (c) 2010, 2013 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    def createCcCode(negBit, carry, overflow):
55        code = ""
56        code += '''
57            uint16_t _iz, _in;
58            _in = (resTemp >> %d) & 1;
59            _iz = (resTemp == 0);
60            CondCodesNZ = (_in << 1) | _iz;
61            DPRINTF(Arm, "(in, iz) = (%%d, %%d)\\n", _in, _iz);
62        ''' % negBit
63        if overflow and overflow != "none":
64            code +=  '''
65                uint16_t _iv;
66                _iv = %s & 1;
67                CondCodesV =  _iv;
68                DPRINTF(Arm, "(iv) = (%%d)\\n", _iv);
69            ''' % overflow
70        if carry and carry != "none":
71            code += '''
72                uint16_t _ic;
73                _ic = %s & 1;
74                CondCodesC =  _ic;
75                DPRINTF(Arm, "(ic) = (%%d)\\n", _ic);
76            ''' % carry
77        return code
78
79    # Dict of code to set the carry flag. (imm, reg, reg-reg)
80    oldC = 'CondCodesC'
81    carryCode = {
82        "none": ("none", "none", "none"),
83        "llbit": ("none", "none", "none"),
84        "saturate": ('0', '0', '0'),
85        "overflow": ('0', '0', '0'),
86        "ge": ('0', '0', '0'),
87        "add": ('findCarry(32, resTemp, Op1, secondOp)',
88                'findCarry(32, resTemp, Op1, secondOp)',
89                'findCarry(32, resTemp, Op1, secondOp)'),
90        "sub": ('findCarry(32, resTemp, Op1, ~secondOp)',
91                'findCarry(32, resTemp, Op1, ~secondOp)',
92                'findCarry(32, resTemp, Op1, ~secondOp)'),
93        "rsb": ('findCarry(32, resTemp, secondOp, ~Op1)',
94                'findCarry(32, resTemp, secondOp, ~Op1)',
95                'findCarry(32, resTemp, secondOp, ~Op1)'),
96        "logic": ('(rotC ? bits(secondOp, 31) : %s)' % oldC,
97                  'shift_carry_imm(Op2, shiftAmt, shiftType, %s)' % oldC,
98                  'shift_carry_rs(Op2, Shift<7:0>, shiftType, %s)' % oldC)
99    }
100    # Dict of code to set the overflow flag.
101    overflowCode = {
102        "none": "none",
103        "llbit": "none",
104        "saturate": '0',
105        "overflow": '0',
106        "ge": '0',
107        "add": 'findOverflow(32, resTemp, Op1, secondOp)',
108        "sub": 'findOverflow(32, resTemp, Op1, ~secondOp)',
109        "rsb": 'findOverflow(32, resTemp, secondOp, ~Op1)',
110        "logic": "none"
111    }
112
113    secondOpRe = re.compile("secondOp")
114    immOp2 = "imm"
115    regOp2 = "shift_rm_imm(Op2, shiftAmt, shiftType, OptShiftRmCondCodesC)"
116    regRegOp2 = "shift_rm_rs(Op2, Shift<7:0>, shiftType, 0)"
117
118    def buildImmDataInst(mnem, code, flagType = "logic", suffix = "Imm", \
119                         buildCc = True, buildNonCc = True, isBranch = "0", \
120                         instFlags = []):
121        cCode = carryCode[flagType]
122        vCode = overflowCode[flagType]
123        negBit = 31
124        if flagType == "llbit":
125            negBit = 63
126        if flagType == "saturate":
127            immCcCode = calcQCode
128        elif flagType == "ge":
129            immCcCode = calcGECode
130        else:
131            immCcCode = createCcCode(negBit, secondOpRe.sub(immOp2, cCode[0]),
132                                     secondOpRe.sub(immOp2, vCode))
133
134        immCode = secondOpRe.sub(immOp2, code)
135        immIop = InstObjParams(mnem, mnem.capitalize() + suffix, "DataImmOp",
136                       {"code" : immCode,
137                        "is_branch" : isBranch,
138                        "predicate_test": pickPredicate(immCode)}, instFlags)
139        immIopCc = InstObjParams(mnem + "s", mnem.capitalize() + suffix + "Cc",
140             "DataImmOp",
141             {"code" : immCode + immCcCode,
142              "is_branch" : isBranch,
143              "predicate_test": pickPredicate(immCode + immCcCode)}, instFlags)
144
145        def subst(iop):
146            global header_output, decoder_output, exec_output
147            header_output += DataImmDeclare.subst(iop)
148            decoder_output += DataImmConstructor.subst(iop)
149            exec_output += PredOpExecute.subst(iop)
150
151        if buildNonCc:
152            subst(immIop)
153        if buildCc:
154            subst(immIopCc)
155
156    def buildRegDataInst(mnem, code, flagType = "logic", suffix = "Reg", \
157                         buildCc = True, buildNonCc = True, isRasPop = "0", \
158                         isBranch = "0", instFlags = []):
159        cCode = carryCode[flagType]
160        vCode = overflowCode[flagType]
161        negBit = 31
162        regCcCode = ""
163        if flagType == "llbit":
164            negBit = 63
165        if flagType == "saturate":
166            regCcCode = calcQCode
167        elif flagType == "ge":
168            regCcCode = calcGECode
169        else:
170            regCcCode = createCcCode(negBit,secondOpRe.sub(regOp2, cCode[1]),
171                                     secondOpRe.sub(regOp2, vCode))
172
173        regCode = secondOpRe.sub(regOp2, code)
174
175        # If we end up needing CondCodesC then remove any trace of the OptShift
176        if re.search('(?<!OptShiftRm)CondCodesC(?!.*=)', regCode + regCcCode):
177            regCode = re.sub('OptShiftRmCondCodesC', 'CondCodesC', regCode)
178            regCcCode = re.sub('OptShiftRmCondCodesC', 'CondCodesC', regCcCode)
179
180        regIop = InstObjParams(mnem, mnem.capitalize() + suffix, "DataRegOp",
181                       {"code" : regCode, "is_ras_pop" : isRasPop,
182                        "is_branch" : isBranch,
183                        "predicate_test": pickPredicate(regCode)}, instFlags)
184        regIopCc = InstObjParams(mnem + "s", mnem.capitalize() + suffix + "Cc",
185                         "DataRegOp",
186                         {"code" : regCode + regCcCode,
187                          "predicate_test": pickPredicate(regCode + regCcCode),
188                          "is_ras_pop" : isRasPop,
189                          "is_branch" : isBranch}, instFlags)
190
191        def subst(iop):
192            global header_output, decoder_output, exec_output
193            header_output += DataRegDeclare.subst(iop)
194            decoder_output += DataRegConstructor.subst(iop)
195            exec_output += PredOpExecute.subst(iop)
196
197        if buildNonCc:
198            subst(regIop)
199        if buildCc:
200            subst(regIopCc)
201
202    def buildRegRegDataInst(mnem, code, flagType = "logic", \
203                            suffix = "RegReg", \
204                            buildCc = True, buildNonCc = True):
205        cCode = carryCode[flagType]
206        vCode = overflowCode[flagType]
207        negBit = 31
208        if flagType == "llbit":
209            negBit = 63
210        if flagType == "saturate":
211            regRegCcCode = calcQCode
212        elif flagType == "ge":
213            regRegCcCode = calcGECode
214        else:
215            regRegCcCode = createCcCode(negBit,
216                                        secondOpRe.sub(regRegOp2, cCode[2]),
217                                        secondOpRe.sub(regRegOp2, vCode))
218
219        regRegCode = secondOpRe.sub(regRegOp2, code)
220        regRegIop = InstObjParams(mnem, mnem.capitalize() + suffix,
221                          "DataRegRegOp",
222                          {"code" : regRegCode,
223                           "predicate_test": pickPredicate(regRegCode)})
224        regRegIopCc = InstObjParams(mnem + "s",
225                mnem.capitalize() + suffix + "Cc",
226                "DataRegRegOp",
227                {"code" : regRegCode + regRegCcCode,
228                 "predicate_test": pickPredicate(regRegCode + regRegCcCode)})
229
230        def subst(iop):
231            global header_output, decoder_output, exec_output
232            header_output += DataRegRegDeclare.subst(iop)
233            decoder_output += DataRegRegConstructor.subst(iop)
234            exec_output += PredOpExecute.subst(iop)
235
236        if buildNonCc:
237            subst(regRegIop)
238        if buildCc:
239            subst(regRegIopCc)
240
241    def buildDataInst(mnem, code, flagType = "logic", \
242                      aiw = True, regRegAiw = True,
243                      subsPcLr = True, isRasPop = "0", isBranch = "0"):
244        regRegCode = instCode = code
245        if aiw:
246            instCode = "AIW" + instCode
247            if regRegAiw:
248                regRegCode = "AIW" + regRegCode
249
250        buildImmDataInst(mnem, instCode, flagType, isBranch = isBranch)
251        buildRegDataInst(mnem, instCode, flagType,
252                         isRasPop = isRasPop, isBranch = isBranch)
253        buildRegRegDataInst(mnem, regRegCode, flagType)
254        if subsPcLr:
255            code += '''
256            SCTLR sctlr = Sctlr;
257            CPSR old_cpsr = Cpsr;
258
259            CPSR new_cpsr =
260                cpsrWriteByInstr(old_cpsr, Spsr, Scr, Nsacr, 0xF, true,
261                                 sctlr.nmfi, xc->tcBase());
262            Cpsr = ~CondCodesMask & new_cpsr;
263            CondCodesNZ = new_cpsr.nz;
264            CondCodesC = new_cpsr.c;
265            CondCodesV = new_cpsr.v;
266            CondCodesGE = new_cpsr.ge;
267
268            NextThumb = (new_cpsr).t;
269            NextJazelle = (new_cpsr).j;
270            NextItState = (((new_cpsr).it2 << 2) & 0xFC)
271                | ((new_cpsr).it1 & 0x3);
272            SevMailbox = 1;
273            '''
274            buildImmDataInst(mnem + 's', code, flagType,
275                             suffix = "ImmPclr", buildCc = False,
276                             instFlags = ["IsSerializeAfter","IsNonSpeculative"])
277            buildRegDataInst(mnem + 's', code, flagType,
278                             suffix = "RegPclr", buildCc = False,
279                             instFlags = ["IsSerializeAfter","IsNonSpeculative"])
280
281    buildDataInst("and", "Dest = resTemp = Op1 & secondOp;")
282    buildDataInst("eor", "Dest = resTemp = Op1 ^ secondOp;")
283    buildDataInst("sub", "Dest = resTemp = Op1 - secondOp;", "sub",
284                  isBranch = "dest == INTREG_PC")
285    buildDataInst("rsb", "Dest = resTemp = secondOp - Op1;", "rsb")
286    buildDataInst("add", "Dest = resTemp = Op1 + secondOp;", "add",
287                  isBranch = "dest == INTREG_PC")
288    buildImmDataInst("adr", '''
289                               Dest = resTemp = (PC & ~0x3) +
290                               (op1 ? secondOp : -secondOp);
291                            ''', isBranch = "dest == INTREG_PC")
292    buildDataInst("adc", "Dest = resTemp = Op1 + secondOp + %s;" % oldC, "add")
293    buildDataInst("sbc", "Dest = resTemp = Op1 - secondOp - !%s;" % oldC, "sub")
294    buildDataInst("rsc", "Dest = resTemp = secondOp - Op1 - !%s;" % oldC, "rsb")
295    buildDataInst("tst", "resTemp = Op1 & secondOp;", aiw = False)
296    buildDataInst("teq", "resTemp = Op1 ^ secondOp;", aiw = False)
297    buildDataInst("cmp", "resTemp = Op1 - secondOp;", "sub", aiw = False)
298    buildDataInst("cmn", "resTemp = Op1 + secondOp;", "add", aiw = False)
299    buildDataInst("orr", "Dest = resTemp = Op1 | secondOp;")
300    buildDataInst("orn", "Dest = resTemp = Op1 | ~secondOp;", aiw = False)
301    buildDataInst("mov", "Dest = resTemp = secondOp;", regRegAiw = False,
302                  isRasPop = "op2 == INTREG_LR", isBranch = "dest == INTREG_PC")
303    buildDataInst("bic", "Dest = resTemp = Op1 & ~secondOp;")
304    buildDataInst("mvn", "Dest = resTemp = ~secondOp;")
305    buildDataInst("movt",
306                  "Dest = resTemp = insertBits(Op1, 31, 16, secondOp);",
307                  aiw = False)
308
309    buildRegDataInst("qadd", '''
310            int32_t midRes;
311            resTemp = saturateOp<32>(midRes, Op1_sw, Op2_sw);
312                                     Dest = midRes;
313        ''', flagType="saturate", buildNonCc=False)
314    buildRegDataInst("qadd16", '''
315            int32_t midRes;
316            for (unsigned i = 0; i < 2; i++) {
317                int high = (i + 1) * 16 - 1;
318                int low = i * 16;
319                int64_t arg1 = sext<16>(bits(Op1_sw, high, low));
320                int64_t arg2 = sext<16>(bits(Op2_sw, high, low));
321                saturateOp<16>(midRes, arg1, arg2);
322                replaceBits(resTemp, high, low, midRes);
323            }
324            Dest = resTemp;
325        ''', flagType="none", buildCc=False)
326    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