data.isa revision 9077
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    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, instFlags = []):
120        cCode = carryCode[flagType]
121        vCode = overflowCode[flagType]
122        negBit = 31
123        if flagType == "llbit":
124            negBit = 63
125        if flagType == "saturate":
126            immCcCode = calcQCode
127        elif flagType == "ge":
128            immCcCode = calcGECode
129        else:
130            immCcCode = createCcCode(negBit, secondOpRe.sub(immOp2, cCode[0]),
131                                     secondOpRe.sub(immOp2, vCode))
132
133        immCode = secondOpRe.sub(immOp2, code)
134        immIop = InstObjParams(mnem, mnem.capitalize() + suffix, "DataImmOp",
135                       {"code" : immCode,
136                        "predicate_test": pickPredicate(immCode)}, instFlags)
137        immIopCc = InstObjParams(mnem + "s", mnem.capitalize() + suffix + "Cc",
138             "DataImmOp",
139             {"code" : immCode + immCcCode,
140              "predicate_test": pickPredicate(immCode + immCcCode)}, instFlags)
141
142        def subst(iop):
143            global header_output, decoder_output, exec_output
144            header_output += DataImmDeclare.subst(iop)
145            decoder_output += DataImmConstructor.subst(iop)
146            exec_output += PredOpExecute.subst(iop)
147
148        if buildNonCc:
149            subst(immIop)
150        if buildCc:
151            subst(immIopCc)
152
153    def buildRegDataInst(mnem, code, flagType = "logic", suffix = "Reg", \
154                         buildCc = True, buildNonCc = True, isRasPop = "0", \
155                         isBranch = "0", instFlags = []):
156        cCode = carryCode[flagType]
157        vCode = overflowCode[flagType]
158        negBit = 31
159        regCcCode = ""
160        if flagType == "llbit":
161            negBit = 63
162        if flagType == "saturate":
163            regCcCode = calcQCode
164        elif flagType == "ge":
165            regCcCode = calcGECode
166        else:
167            regCcCode = createCcCode(negBit,secondOpRe.sub(regOp2, cCode[1]),
168                                     secondOpRe.sub(regOp2, vCode))
169
170        regCode = secondOpRe.sub(regOp2, code)
171
172        # If we end up needing CondCodesC then remove any trace of the OptShift
173        if re.search('(?<!OptShiftRm)CondCodesC(?!.*=)', regCode + regCcCode):
174            regCode = re.sub('OptShiftRmCondCodesC', 'CondCodesC', regCode)
175            regCcCode = re.sub('OptShiftRmCondCodesC', 'CondCodesC', regCcCode)
176
177        regIop = InstObjParams(mnem, mnem.capitalize() + suffix, "DataRegOp",
178                       {"code" : regCode, "is_ras_pop" : isRasPop,
179                        "is_branch" : isBranch,
180                        "predicate_test": pickPredicate(regCode)}, instFlags)
181        regIopCc = InstObjParams(mnem + "s", mnem.capitalize() + suffix + "Cc",
182                         "DataRegOp",
183                         {"code" : regCode + regCcCode,
184                          "predicate_test": pickPredicate(regCode + regCcCode),
185                          "is_ras_pop" : isRasPop,
186                          "is_branch" : isBranch}, instFlags)
187
188        def subst(iop):
189            global header_output, decoder_output, exec_output
190            header_output += DataRegDeclare.subst(iop)
191            decoder_output += DataRegConstructor.subst(iop)
192            exec_output += PredOpExecute.subst(iop)
193
194        if buildNonCc:
195            subst(regIop)
196        if buildCc:
197            subst(regIopCc)
198
199    def buildRegRegDataInst(mnem, code, flagType = "logic", \
200                            suffix = "RegReg", \
201                            buildCc = True, buildNonCc = True):
202        cCode = carryCode[flagType]
203        vCode = overflowCode[flagType]
204        negBit = 31
205        if flagType == "llbit":
206            negBit = 63
207        if flagType == "saturate":
208            regRegCcCode = calcQCode
209        elif flagType == "ge":
210            regRegCcCode = calcGECode
211        else:
212            regRegCcCode = createCcCode(negBit,
213                                        secondOpRe.sub(regRegOp2, cCode[2]),
214                                        secondOpRe.sub(regRegOp2, vCode))
215
216        regRegCode = secondOpRe.sub(regRegOp2, code)
217        regRegIop = InstObjParams(mnem, mnem.capitalize() + suffix,
218                          "DataRegRegOp",
219                          {"code" : regRegCode,
220                           "predicate_test": pickPredicate(regRegCode)})
221        regRegIopCc = InstObjParams(mnem + "s",
222                mnem.capitalize() + suffix + "Cc",
223                "DataRegRegOp",
224                {"code" : regRegCode + regRegCcCode,
225                 "predicate_test": pickPredicate(regRegCode + regRegCcCode)})
226
227        def subst(iop):
228            global header_output, decoder_output, exec_output
229            header_output += DataRegRegDeclare.subst(iop)
230            decoder_output += DataRegRegConstructor.subst(iop)
231            exec_output += PredOpExecute.subst(iop)
232
233        if buildNonCc:
234            subst(regRegIop)
235        if buildCc:
236            subst(regRegIopCc)
237
238    def buildDataInst(mnem, code, flagType = "logic", \
239                      aiw = True, regRegAiw = True,
240                      subsPcLr = True, isRasPop = "0", isBranch = "0"):
241        regRegCode = instCode = code
242        if aiw:
243            instCode = "AIW" + instCode
244            if regRegAiw:
245                regRegCode = "AIW" + regRegCode
246
247        buildImmDataInst(mnem, instCode, flagType)
248        buildRegDataInst(mnem, instCode, flagType,
249                         isRasPop = isRasPop, isBranch = isBranch)
250        buildRegRegDataInst(mnem, regRegCode, flagType)
251        if subsPcLr:
252            code += '''
253            SCTLR sctlr = Sctlr;
254            CPSR old_cpsr = Cpsr;
255
256            CPSR new_cpsr =
257                cpsrWriteByInstr(old_cpsr, Spsr, 0xF, true, sctlr.nmfi);
258            Cpsr = ~CondCodesMask & new_cpsr;
259            CondCodesNZ = new_cpsr.nz;
260            CondCodesC = new_cpsr.c;
261            CondCodesV = new_cpsr.v;
262            CondCodesGE = new_cpsr.ge;
263
264            NextThumb = (new_cpsr).t;
265            NextJazelle = (new_cpsr).j;
266            NextItState = (((new_cpsr).it2 << 2) & 0xFC)
267                | ((new_cpsr).it1 & 0x3);
268            SevMailbox = 1;
269            '''
270            buildImmDataInst(mnem + 's', code, flagType,
271                             suffix = "ImmPclr", buildCc = False,
272                             instFlags = ["IsSerializeAfter","IsNonSpeculative"])
273            buildRegDataInst(mnem + 's', code, flagType,
274                             suffix = "RegPclr", buildCc = False,
275                             instFlags = ["IsSerializeAfter","IsNonSpeculative"])
276
277    buildDataInst("and", "Dest = resTemp = Op1 & secondOp;")
278    buildDataInst("eor", "Dest = resTemp = Op1 ^ secondOp;")
279    buildDataInst("sub", "Dest = resTemp = Op1 - secondOp;", "sub")
280    buildDataInst("rsb", "Dest = resTemp = secondOp - Op1;", "rsb")
281    buildDataInst("add", "Dest = resTemp = Op1 + secondOp;", "add")
282    buildImmDataInst("adr", '''
283                               Dest = resTemp = (PC & ~0x3) +
284                               (op1 ? secondOp : -secondOp);
285                            ''')
286    buildDataInst("adc", "Dest = resTemp = Op1 + secondOp + %s;" % oldC, "add")
287    buildDataInst("sbc", "Dest = resTemp = Op1 - secondOp - !%s;" % oldC, "sub")
288    buildDataInst("rsc", "Dest = resTemp = secondOp - Op1 - !%s;" % oldC, "rsb")
289    buildDataInst("tst", "resTemp = Op1 & secondOp;", aiw = False)
290    buildDataInst("teq", "resTemp = Op1 ^ secondOp;", aiw = False)
291    buildDataInst("cmp", "resTemp = Op1 - secondOp;", "sub", aiw = False)
292    buildDataInst("cmn", "resTemp = Op1 + secondOp;", "add", aiw = False)
293    buildDataInst("orr", "Dest = resTemp = Op1 | secondOp;")
294    buildDataInst("orn", "Dest = resTemp = Op1 | ~secondOp;", aiw = False)
295    buildDataInst("mov", "Dest = resTemp = secondOp;", regRegAiw = False,
296                  isRasPop = "op2 == INTREG_LR", isBranch = "dest == INTREG_PC")
297    buildDataInst("bic", "Dest = resTemp = Op1 & ~secondOp;")
298    buildDataInst("mvn", "Dest = resTemp = ~secondOp;")
299    buildDataInst("movt",
300                  "Dest = resTemp = insertBits(Op1, 31, 16, secondOp);",
301                  aiw = False)
302
303    buildRegDataInst("qadd", '''
304            int32_t midRes;
305            resTemp = saturateOp<32>(midRes, Op1_sw, Op2_sw);
306                                     Dest = midRes;
307        ''', flagType="saturate", buildNonCc=False)
308    buildRegDataInst("qadd16", '''
309            int32_t midRes;
310            for (unsigned i = 0; i < 2; i++) {
311                int high = (i + 1) * 16 - 1;
312                int low = i * 16;
313                int64_t arg1 = sext<16>(bits(Op1_sw, high, low));
314                int64_t arg2 = sext<16>(bits(Op2_sw, high, low));
315                saturateOp<16>(midRes, arg1, arg2);
316                replaceBits(resTemp, high, low, midRes);
317            }
318            Dest = resTemp;
319        ''', flagType="none", buildCc=False)
320    buildRegDataInst("qadd8", '''
321            int32_t midRes;
322            for (unsigned i = 0; i < 4; i++) {
323                int high = (i + 1) * 8 - 1;
324                int low = i * 8;
325                int64_t arg1 = sext<8>(bits(Op1_sw, high, low));
326                int64_t arg2 = sext<8>(bits(Op2_sw, high, low));
327                saturateOp<8>(midRes, arg1, arg2);
328                replaceBits(resTemp, high, low, midRes);
329            }
330            Dest = resTemp;
331        ''', flagType="none", buildCc=False)
332    buildRegDataInst("qdadd", '''
333            int32_t midRes;
334            resTemp = saturateOp<32>(midRes, Op2_sw, Op2_sw) |
335                      saturateOp<32>(midRes, Op1_sw, midRes);
336            Dest = midRes;
337        ''', flagType="saturate", buildNonCc=False)
338    buildRegDataInst("qsub", '''
339            int32_t midRes;
340            resTemp = saturateOp<32>(midRes, Op1_sw, Op2_sw, true);
341            Dest = midRes;
342        ''', flagType="saturate")
343    buildRegDataInst("qsub16", '''
344            int32_t midRes;
345            for (unsigned i = 0; i < 2; i++) {
346                 int high = (i + 1) * 16 - 1;
347                 int low = i * 16;
348                 int64_t arg1 = sext<16>(bits(Op1_sw, high, low));
349                 int64_t arg2 = sext<16>(bits(Op2_sw, high, low));
350                 saturateOp<16>(midRes, arg1, arg2, true);
351                 replaceBits(resTemp, high, low, midRes);
352            }
353            Dest = resTemp;
354        ''', flagType="none", buildCc=False)
355    buildRegDataInst("qsub8", '''
356            int32_t midRes;
357            for (unsigned i = 0; i < 4; i++) {
358                 int high = (i + 1) * 8 - 1;
359                 int low = i * 8;
360                 int64_t arg1 = sext<8>(bits(Op1_sw, high, low));
361                 int64_t arg2 = sext<8>(bits(Op2_sw, high, low));
362                 saturateOp<8>(midRes, arg1, arg2, true);
363                 replaceBits(resTemp, high, low, midRes);
364            }
365            Dest = resTemp;
366        ''', flagType="none", buildCc=False)
367    buildRegDataInst("qdsub", '''
368            int32_t midRes;
369            resTemp = saturateOp<32>(midRes, Op2_sw, Op2_sw) |
370                      saturateOp<32>(midRes, Op1_sw, midRes, true);
371            Dest = midRes;
372        ''', flagType="saturate", buildNonCc=False)
373    buildRegDataInst("qasx", '''
374            int32_t midRes;
375            int64_t arg1Low = sext<16>(bits(Op1_sw, 15, 0));
376            int64_t arg1High = sext<16>(bits(Op1_sw, 31, 16));
377            int64_t arg2Low = sext<16>(bits(Op2_sw, 15, 0));
378            int64_t arg2High = sext<16>(bits(Op2_sw, 31, 16));
379            saturateOp<16>(midRes, arg1Low, arg2High, true);
380            replaceBits(resTemp, 15, 0, midRes);
381            saturateOp<16>(midRes, arg1High, arg2Low);
382            replaceBits(resTemp, 31, 16, midRes);
383            Dest = resTemp;
384        ''', flagType="none", buildCc=False)
385    buildRegDataInst("qsax", '''
386            int32_t midRes;
387            int64_t arg1Low = sext<16>(bits(Op1_sw, 15, 0));
388            int64_t arg1High = sext<16>(bits(Op1_sw, 31, 16));
389            int64_t arg2Low = sext<16>(bits(Op2_sw, 15, 0));
390            int64_t arg2High = sext<16>(bits(Op2_sw, 31, 16));
391            saturateOp<16>(midRes, arg1Low, arg2High);
392            replaceBits(resTemp, 15, 0, midRes);
393            saturateOp<16>(midRes, arg1High, arg2Low, true);
394            replaceBits(resTemp, 31, 16, midRes);
395            Dest = resTemp;
396        ''', flagType="none", buildCc=False)
397
398    buildRegDataInst("sadd8", '''
399            uint32_t geBits = 0;
400            resTemp = 0;
401            for (unsigned i = 0; i < 4; i++) {
402                int high = (i + 1) * 8 - 1;
403                int low = i * 8;
404                int32_t midRes = sext<8>(bits(Op1_sw, high, low)) +
405                                 sext<8>(bits(Op2_sw, high, low));
406                replaceBits(resTemp, high, low, midRes);
407                if (midRes >= 0) {
408                    geBits = geBits | (1 << i);
409                }
410            }
411            Dest = resTemp;
412            resTemp = geBits;
413        ''', flagType="ge", buildNonCc=False)
414    buildRegDataInst("sadd16", '''
415            uint32_t geBits = 0;
416            resTemp = 0;
417            for (unsigned i = 0; i < 2; i++) {
418                int high = (i + 1) * 16 - 1;
419                int low = i * 16;
420                int32_t midRes = sext<16>(bits(Op1_sw, high, low)) +
421                                 sext<16>(bits(Op2_sw, high, low));
422                replaceBits(resTemp, high, low, midRes);
423                if (midRes >= 0) {
424                    geBits = geBits | (0x3 << (i * 2));
425                }
426            }
427            Dest = resTemp;
428            resTemp = geBits;
429        ''', flagType="ge", buildNonCc=False)
430
431    buildRegDataInst("ssub8", '''
432            uint32_t geBits = 0;
433            resTemp = 0;
434            for (unsigned i = 0; i < 4; i++) {
435                int high = (i + 1) * 8 - 1;
436                int low = i * 8;
437                int32_t midRes = sext<8>(bits(Op1_sw, high, low)) -
438                                 sext<8>(bits(Op2_sw, high, low));
439                replaceBits(resTemp, high, low, midRes);
440                if (midRes >= 0) {
441                    geBits = geBits | (1 << i);
442                }
443            }
444            Dest = resTemp;
445            resTemp = geBits;
446        ''', flagType="ge", buildNonCc=False)
447    buildRegDataInst("ssub16", '''
448            uint32_t geBits = 0;
449            resTemp = 0;
450            for (unsigned i = 0; i < 2; i++) {
451                int high = (i + 1) * 16 - 1;
452                int low = i * 16;
453                int32_t midRes = sext<16>(bits(Op1_sw, high, low)) -
454                                 sext<16>(bits(Op2_sw, high, low));
455                replaceBits(resTemp, high, low, midRes);
456                if (midRes >= 0) {
457                    geBits = geBits | (0x3 << (i * 2));
458                }
459            }
460            Dest = resTemp;
461            resTemp = geBits;
462        ''', flagType="ge", buildNonCc=False)
463    buildRegDataInst("sasx", '''
464            int32_t midRes, geBits = 0;
465            resTemp = 0;
466            int64_t arg1Low = sext<16>(bits(Op1_sw, 15, 0));
467            int64_t arg1High = sext<16>(bits(Op1_sw, 31, 16));
468            int64_t arg2Low = sext<16>(bits(Op2_sw, 15, 0));
469            int64_t arg2High = sext<16>(bits(Op2_sw, 31, 16));
470            midRes = arg1Low - arg2High;
471            if (midRes >= 0) {
472                geBits = geBits | 0x3;
473            }
474            replaceBits(resTemp, 15, 0, midRes);
475            midRes = arg1High + arg2Low;
476            if (midRes >= 0) {
477                geBits = geBits | 0xc;
478            }
479            replaceBits(resTemp, 31, 16, midRes);
480            Dest = resTemp;
481            resTemp = geBits;
482        ''', flagType="ge", buildNonCc=True)
483    buildRegDataInst("ssax", '''
484            int32_t midRes, geBits = 0;
485            resTemp = 0;
486            int64_t arg1Low = sext<16>(bits(Op1_sw, 15, 0));
487            int64_t arg1High = sext<16>(bits(Op1_sw, 31, 16));
488            int64_t arg2Low = sext<16>(bits(Op2_sw, 15, 0));
489            int64_t arg2High = sext<16>(bits(Op2_sw, 31, 16));
490            midRes = arg1Low + arg2High;
491            if (midRes >= 0) {
492                geBits = geBits | 0x3;
493            }
494            replaceBits(resTemp, 15, 0, midRes);
495            midRes = arg1High - arg2Low;
496            if (midRes >= 0) {
497                geBits = geBits | 0xc;
498            }
499            replaceBits(resTemp, 31, 16, midRes);
500            Dest = resTemp;
501            resTemp = geBits;
502        ''', flagType="ge", buildNonCc=True)
503
504    buildRegDataInst("shadd8", '''
505            resTemp = 0;
506            for (unsigned i = 0; i < 4; i++) {
507                int high = (i + 1) * 8 - 1;
508                int low = i * 8;
509                int32_t midRes =
510                    (uint64_t)(sext<8>(bits(Op1_sw, high, low)) +
511                               sext<8>(bits(Op2_sw, high, low))) >> 1;
512                replaceBits(resTemp, high, low, midRes);
513            }
514            Dest = resTemp;
515        ''', flagType="none", buildCc=False)
516    buildRegDataInst("shadd16", '''
517            resTemp = 0;
518            for (unsigned i = 0; i < 2; i++) {
519                int high = (i + 1) * 16 - 1;
520                int low = i * 16;
521                int32_t midRes =
522                    (uint64_t)(sext<16>(bits(Op1_sw, high, low)) +
523                               sext<16>(bits(Op2_sw, high, low))) >> 1;
524                replaceBits(resTemp, high, low, midRes);
525            }
526            Dest = resTemp;
527        ''', flagType="none", buildCc=False)
528    buildRegDataInst("shsub8", '''
529            resTemp = 0;
530            for (unsigned i = 0; i < 4; i++) {
531                int high = (i + 1) * 8 - 1;
532                int low = i * 8;
533                int32_t midRes =
534                    (uint64_t)(sext<8>(bits(Op1_sw, high, low)) -
535                               sext<8>(bits(Op2_sw, high, low))) >> 1;
536                replaceBits(resTemp, high, low, midRes);
537            }
538            Dest = resTemp;
539        ''', flagType="none", buildCc=False)
540    buildRegDataInst("shsub16", '''
541            resTemp = 0;
542            for (unsigned i = 0; i < 2; i++) {
543                int high = (i + 1) * 16 - 1;
544                int low = i * 16;
545                int32_t midRes =
546                    (uint64_t)(sext<16>(bits(Op1_sw, high, low)) -
547                               sext<16>(bits(Op2_sw, high, low))) >> 1;
548                replaceBits(resTemp, high, low, midRes);
549            }
550            Dest = resTemp;
551        ''', flagType="none", buildCc=False)
552    buildRegDataInst("shasx", '''
553            int32_t midRes;
554            resTemp = 0;
555            int64_t arg1Low = sext<16>(bits(Op1_sw, 15, 0));
556            int64_t arg1High = sext<16>(bits(Op1_sw, 31, 16));
557            int64_t arg2Low = sext<16>(bits(Op2_sw, 15, 0));
558            int64_t arg2High = sext<16>(bits(Op2_sw, 31, 16));
559            midRes = (uint64_t)(arg1Low - arg2High) >> 1;
560            replaceBits(resTemp, 15, 0, midRes);
561            midRes = (arg1High + arg2Low) >> 1;
562            replaceBits(resTemp, 31, 16, midRes);
563            Dest = resTemp;
564        ''', flagType="none", buildCc=True)
565    buildRegDataInst("shsax", '''
566            int32_t midRes;
567            resTemp = 0;
568            int64_t arg1Low = sext<16>(bits(Op1_sw, 15, 0));
569            int64_t arg1High = sext<16>(bits(Op1_sw, 31, 16));
570            int64_t arg2Low = sext<16>(bits(Op2_sw, 15, 0));
571            int64_t arg2High = sext<16>(bits(Op2_sw, 31, 16));
572            midRes = (uint64_t)(arg1Low + arg2High) >> 1;
573            replaceBits(resTemp, 15, 0, midRes);
574            midRes = (uint64_t)(arg1High - arg2Low) >> 1;
575            replaceBits(resTemp, 31, 16, midRes);
576            Dest = resTemp;
577        ''', flagType="none", buildCc=True)
578
579    buildRegDataInst("uqadd16", '''
580            uint32_t midRes;
581            for (unsigned i = 0; i < 2; i++) {
582                int high = (i + 1) * 16 - 1;
583                int low = i * 16;
584                uint64_t arg1 = bits(Op1, high, low);
585                uint64_t arg2 = bits(Op2, high, low);
586                uSaturateOp<16>(midRes, arg1, arg2);
587                replaceBits(resTemp, high, low, midRes);
588            }
589            Dest = resTemp;
590        ''', flagType="none", buildCc=False)
591    buildRegDataInst("uqadd8", '''
592            uint32_t midRes;
593            for (unsigned i = 0; i < 4; i++) {
594                int high = (i + 1) * 8 - 1;
595                int low = i * 8;
596                uint64_t arg1 = bits(Op1, high, low);
597                uint64_t arg2 = bits(Op2, high, low);
598                uSaturateOp<8>(midRes, arg1, arg2);
599                replaceBits(resTemp, high, low, midRes);
600            }
601            Dest = resTemp;
602        ''', flagType="none", buildCc=False)
603    buildRegDataInst("uqsub16", '''
604            uint32_t midRes;
605            for (unsigned i = 0; i < 2; i++) {
606                 int high = (i + 1) * 16 - 1;
607                 int low = i * 16;
608                 uint64_t arg1 = bits(Op1, high, low);
609                 uint64_t arg2 = bits(Op2, high, low);
610                 uSaturateOp<16>(midRes, arg1, arg2, true);
611                 replaceBits(resTemp, high, low, midRes);
612            }
613            Dest = resTemp;
614        ''', flagType="none", buildCc=False)
615    buildRegDataInst("uqsub8", '''
616            uint32_t midRes;
617            for (unsigned i = 0; i < 4; i++) {
618                 int high = (i + 1) * 8 - 1;
619                 int low = i * 8;
620                 uint64_t arg1 = bits(Op1, high, low);
621                 uint64_t arg2 = bits(Op2, high, low);
622                 uSaturateOp<8>(midRes, arg1, arg2, true);
623                 replaceBits(resTemp, high, low, midRes);
624            }
625            Dest = resTemp;
626        ''', flagType="none", buildCc=False)
627    buildRegDataInst("uqasx", '''
628            uint32_t midRes;
629            uint64_t arg1Low = bits(Op1_sw, 15, 0);
630            uint64_t arg1High = bits(Op1_sw, 31, 16);
631            uint64_t arg2Low = bits(Op2_sw, 15, 0);
632            uint64_t arg2High = bits(Op2_sw, 31, 16);
633            uSaturateOp<16>(midRes, arg1Low, arg2High, true);
634            replaceBits(resTemp, 15, 0, midRes);
635            uSaturateOp<16>(midRes, arg1High, arg2Low);
636            replaceBits(resTemp, 31, 16, midRes);
637            Dest = resTemp;
638        ''', flagType="none", buildCc=False)
639    buildRegDataInst("uqsax", '''
640            uint32_t midRes;
641            uint64_t arg1Low = bits(Op1_sw, 15, 0);
642            uint64_t arg1High = bits(Op1_sw, 31, 16);
643            uint64_t arg2Low = bits(Op2_sw, 15, 0);
644            uint64_t arg2High = bits(Op2_sw, 31, 16);
645            uSaturateOp<16>(midRes, arg1Low, arg2High);
646            replaceBits(resTemp, 15, 0, midRes);
647            uSaturateOp<16>(midRes, arg1High, arg2Low, true);
648            replaceBits(resTemp, 31, 16, midRes);
649            Dest = resTemp;
650        ''', flagType="none", buildCc=False)
651
652    buildRegDataInst("uadd16", '''
653            uint32_t geBits = 0;
654            resTemp = 0;
655            for (unsigned i = 0; i < 2; i++) {
656                int high = (i + 1) * 16 - 1;
657                int low = i * 16;
658                int32_t midRes = bits(Op1, high, low) +
659                                 bits(Op2, high, low);
660                if (midRes >= 0x10000) {
661                    geBits = geBits | (0x3 << (i * 2));
662                }
663                replaceBits(resTemp, high, low, midRes);
664            }
665            Dest = resTemp;
666            resTemp = geBits;
667        ''', flagType="ge", buildNonCc=False)
668    buildRegDataInst("uadd8", '''
669            uint32_t geBits = 0;
670            resTemp = 0;
671            for (unsigned i = 0; i < 4; i++) {
672                int high = (i + 1) * 8 - 1;
673                int low = i * 8;
674                int32_t midRes = bits(Op1, high, low) +
675                                 bits(Op2, high, low);
676                if (midRes >= 0x100) {
677                    geBits = geBits | (1 << i);
678                }
679                replaceBits(resTemp, high, low, midRes);
680            }
681            Dest = resTemp;
682            resTemp = geBits;
683        ''', flagType="ge", buildNonCc=False)
684    buildRegDataInst("usub16", '''
685            uint32_t geBits = 0;
686            resTemp = 0;
687            for (unsigned i = 0; i < 2; i++) {
688                int high = (i + 1) * 16 - 1;
689                int low = i * 16;
690                int32_t midRes = bits(Op1, high, low) -
691                                 bits(Op2, high, low);
692                if (midRes >= 0) {
693                    geBits = geBits | (0x3 << (i * 2));
694                }
695                replaceBits(resTemp, high, low, midRes);
696            }
697            Dest = resTemp;
698            resTemp = geBits;
699        ''', flagType="ge", buildNonCc=False)
700    buildRegDataInst("usub8", '''
701            uint32_t geBits = 0;
702            resTemp = 0;
703            for (unsigned i = 0; i < 4; i++) {
704                int high = (i + 1) * 8 - 1;
705                int low = i * 8;
706                int32_t midRes = bits(Op1, high, low) -
707                                 bits(Op2, high, low);
708                if (midRes >= 0) {
709                    geBits = geBits | (1 << i);
710                }
711                replaceBits(resTemp, high, low, midRes);
712            }
713            Dest = resTemp;
714            resTemp = geBits;
715        ''', flagType="ge", buildNonCc=False)
716    buildRegDataInst("uasx", '''
717            int32_t midRes, geBits = 0;
718            resTemp = 0;
719            int64_t arg1Low = bits(Op1_sw, 15, 0);
720            int64_t arg1High = bits(Op1_sw, 31, 16);
721            int64_t arg2Low = bits(Op2_sw, 15, 0);
722            int64_t arg2High = bits(Op2_sw, 31, 16);
723            midRes = arg1Low - arg2High;
724            if (midRes >= 0) {
725                geBits = geBits | 0x3;
726            }
727            replaceBits(resTemp, 15, 0, midRes);
728            midRes = arg1High + arg2Low;
729            if (midRes >= 0x10000) {
730                geBits = geBits | 0xc;
731            }
732            replaceBits(resTemp, 31, 16, midRes);
733            Dest = resTemp;
734            resTemp = geBits;
735        ''', flagType="ge", buildNonCc=False)
736    buildRegDataInst("usax", '''
737            int32_t midRes, geBits = 0;
738            resTemp = 0;
739            int64_t arg1Low = bits(Op1_sw, 15, 0);
740            int64_t arg1High = bits(Op1_sw, 31, 16);
741            int64_t arg2Low = bits(Op2_sw, 15, 0);
742            int64_t arg2High = bits(Op2_sw, 31, 16);
743            midRes = arg1Low + arg2High;
744            if (midRes >= 0x10000) {
745                geBits = geBits | 0x3;
746            }
747            replaceBits(resTemp, 15, 0, midRes);
748            midRes = arg1High - arg2Low;
749            if (midRes >= 0) {
750                geBits = geBits | 0xc;
751            }
752            replaceBits(resTemp, 31, 16, midRes);
753            Dest = resTemp;
754            resTemp = geBits;
755        ''', flagType="ge", buildNonCc=False)
756
757    buildRegDataInst("uhadd16", '''
758            resTemp = 0;
759            for (unsigned i = 0; i < 2; i++) {
760                int high = (i + 1) * 16 - 1;
761                int low = i * 16;
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("uhadd8", '''
769            resTemp = 0;
770            for (unsigned i = 0; i < 4; i++) {
771                int high = (i + 1) * 8 - 1;
772                int low = i * 8;
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("uhsub16", '''
780            resTemp = 0;
781            for (unsigned i = 0; i < 2; i++) {
782                int high = (i + 1) * 16 - 1;
783                int low = i * 16;
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("uhsub8", '''
791            resTemp = 0;
792            for (unsigned i = 0; i < 4; i++) {
793                int high = (i + 1) * 8 - 1;
794                int low = i * 8;
795                int32_t midRes = (bits(Op1, high, low) -
796                                  bits(Op2, high, low)) >> 1;
797                replaceBits(resTemp, high, low, midRes);
798            }
799            Dest = resTemp;
800        ''', flagType="none", buildCc=False)
801    buildRegDataInst("uhasx", '''
802            int32_t midRes;
803            resTemp = 0;
804            int64_t arg1Low = bits(Op1_sw, 15, 0);
805            int64_t arg1High = bits(Op1_sw, 31, 16);
806            int64_t arg2Low = bits(Op2_sw, 15, 0);
807            int64_t arg2High = bits(Op2_sw, 31, 16);
808            midRes = (arg1Low - arg2High) >> 1;
809            replaceBits(resTemp, 15, 0, midRes);
810            midRes = (arg1High + arg2Low) >> 1;
811            replaceBits(resTemp, 31, 16, midRes);
812            Dest = resTemp;
813        ''', flagType="none", buildCc=False)
814    buildRegDataInst("uhsax", '''
815            int32_t midRes;
816            resTemp = 0;
817            int64_t arg1Low = bits(Op1_sw, 15, 0);
818            int64_t arg1High = bits(Op1_sw, 31, 16);
819            int64_t arg2Low = bits(Op2_sw, 15, 0);
820            int64_t arg2High = bits(Op2_sw, 31, 16);
821            midRes = (arg1Low + arg2High) >> 1;
822            replaceBits(resTemp, 15, 0, midRes);
823            midRes = (arg1High - arg2Low) >> 1;
824            replaceBits(resTemp, 31, 16, midRes);
825            Dest = resTemp;
826        ''', flagType="none", buildCc=False)
827
828    buildRegDataInst("pkhbt", '''
829            uint32_t resTemp = 0;
830            uint16_t arg1Low = bits(Op1, 15, 0);
831            uint16_t arg2High = bits(secondOp, 31, 16);
832            replaceBits(resTemp, 15, 0, arg1Low);
833            replaceBits(resTemp, 31, 16, arg2High);
834            Dest = resTemp;
835        ''', flagType="none", buildCc=False)
836    buildRegDataInst("pkhtb", '''
837            uint32_t resTemp = 0;
838            uint16_t arg1High = bits(Op1, 31, 16);
839            uint16_t arg2Low = bits(secondOp, 15, 0);
840            replaceBits(resTemp, 15, 0, arg2Low);
841            replaceBits(resTemp, 31, 16, arg1High);
842            Dest = resTemp;
843        ''', flagType="none", buildCc=False)
844}};
845