16691Stjones1@inf.ed.ac.uk// -*- mode:c++ -*-
26691Stjones1@inf.ed.ac.uk
36691Stjones1@inf.ed.ac.uk// Copyright (c) 2009 The University of Edinburgh
46691Stjones1@inf.ed.ac.uk// All rights reserved.
56691Stjones1@inf.ed.ac.uk//
66691Stjones1@inf.ed.ac.uk// Redistribution and use in source and binary forms, with or without
76691Stjones1@inf.ed.ac.uk// modification, are permitted provided that the following conditions are
86691Stjones1@inf.ed.ac.uk// met: redistributions of source code must retain the above copyright
96691Stjones1@inf.ed.ac.uk// notice, this list of conditions and the following disclaimer;
106691Stjones1@inf.ed.ac.uk// redistributions in binary form must reproduce the above copyright
116691Stjones1@inf.ed.ac.uk// notice, this list of conditions and the following disclaimer in the
126691Stjones1@inf.ed.ac.uk// documentation and/or other materials provided with the distribution;
136691Stjones1@inf.ed.ac.uk// neither the name of the copyright holders nor the names of its
146691Stjones1@inf.ed.ac.uk// contributors may be used to endorse or promote products derived from
156691Stjones1@inf.ed.ac.uk// this software without specific prior written permission.
166691Stjones1@inf.ed.ac.uk//
176691Stjones1@inf.ed.ac.uk// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
186691Stjones1@inf.ed.ac.uk// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
196691Stjones1@inf.ed.ac.uk// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
206691Stjones1@inf.ed.ac.uk// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
216691Stjones1@inf.ed.ac.uk// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
226691Stjones1@inf.ed.ac.uk// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
236691Stjones1@inf.ed.ac.uk// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
246691Stjones1@inf.ed.ac.uk// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
256691Stjones1@inf.ed.ac.uk// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
266691Stjones1@inf.ed.ac.uk// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
276691Stjones1@inf.ed.ac.uk// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
286691Stjones1@inf.ed.ac.uk//
296691Stjones1@inf.ed.ac.uk// Authors: Timothy M. Jones
306691Stjones1@inf.ed.ac.uk
316691Stjones1@inf.ed.ac.uk////////////////////////////////////////////////////////////////////
326691Stjones1@inf.ed.ac.uk//
336691Stjones1@inf.ed.ac.uk// Integer ALU instructions
346691Stjones1@inf.ed.ac.uk//
356691Stjones1@inf.ed.ac.uk
366691Stjones1@inf.ed.ac.uk
376691Stjones1@inf.ed.ac.uk// Instruction class constructor template when Rc is set.
386691Stjones1@inf.ed.ac.ukdef template IntRcConstructor {{
3910184SCurtis.Dunham@arm.com        %(class_name)s::%(class_name)s(ExtMachInst machInst)  : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
406691Stjones1@inf.ed.ac.uk        {
416691Stjones1@inf.ed.ac.uk                %(constructor)s;
426691Stjones1@inf.ed.ac.uk                rcSet = true;
436691Stjones1@inf.ed.ac.uk        }
446691Stjones1@inf.ed.ac.uk}};
456691Stjones1@inf.ed.ac.uk
466691Stjones1@inf.ed.ac.uk
476691Stjones1@inf.ed.ac.uk// Instruction class constructor template when OE is set.
486691Stjones1@inf.ed.ac.ukdef template IntOeConstructor {{
4910184SCurtis.Dunham@arm.com        %(class_name)s::%(class_name)s(ExtMachInst machInst)  : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
506691Stjones1@inf.ed.ac.uk        {
516691Stjones1@inf.ed.ac.uk                %(constructor)s;
526691Stjones1@inf.ed.ac.uk                oeSet = true;
536691Stjones1@inf.ed.ac.uk        }
546691Stjones1@inf.ed.ac.uk}};
556691Stjones1@inf.ed.ac.uk
566691Stjones1@inf.ed.ac.uk
576691Stjones1@inf.ed.ac.uk// Instruction class constructor template when both Rc and OE are set.
586691Stjones1@inf.ed.ac.ukdef template IntRcOeConstructor {{
5910184SCurtis.Dunham@arm.com        %(class_name)s::%(class_name)s(ExtMachInst machInst)  : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
606691Stjones1@inf.ed.ac.uk        {
616691Stjones1@inf.ed.ac.uk                %(constructor)s;
626691Stjones1@inf.ed.ac.uk                rcSet = true;
636691Stjones1@inf.ed.ac.uk                oeSet = true;
646691Stjones1@inf.ed.ac.uk        }
656691Stjones1@inf.ed.ac.uk}};
666691Stjones1@inf.ed.ac.uk
676691Stjones1@inf.ed.ac.uk
686691Stjones1@inf.ed.ac.uklet {{
696691Stjones1@inf.ed.ac.uk
706691Stjones1@inf.ed.ac.ukreadXERCode = 'Xer xer = XER;'
716691Stjones1@inf.ed.ac.uk
726691Stjones1@inf.ed.ac.uksetXERCode = 'XER = xer;'
736691Stjones1@inf.ed.ac.uk
746691Stjones1@inf.ed.ac.ukcomputeCR0Code = '''
756691Stjones1@inf.ed.ac.uk    Cr cr = CR;
766691Stjones1@inf.ed.ac.uk    cr.cr0 = makeCRField((int32_t)%(result)s, (int32_t)0, xer.so);
776691Stjones1@inf.ed.ac.uk    CR = cr;
786691Stjones1@inf.ed.ac.uk'''
796691Stjones1@inf.ed.ac.uk
806691Stjones1@inf.ed.ac.ukcomputeCACode = '''
816691Stjones1@inf.ed.ac.uk    if (findCarry(32, %(result)s, %(inputa)s, %(inputb)s)) {
826691Stjones1@inf.ed.ac.uk        xer.ca = 1;
836691Stjones1@inf.ed.ac.uk    } else {
846691Stjones1@inf.ed.ac.uk        xer.ca = 0;
856691Stjones1@inf.ed.ac.uk    }
866691Stjones1@inf.ed.ac.uk'''
876691Stjones1@inf.ed.ac.uk
886691Stjones1@inf.ed.ac.ukcomputeOVCode = '''
896691Stjones1@inf.ed.ac.uk    if (findOverflow(32, %(result)s, %(inputa)s, %(inputb)s)) {
906691Stjones1@inf.ed.ac.uk        xer.ov = 1;
916691Stjones1@inf.ed.ac.uk        xer.so = 1;
926691Stjones1@inf.ed.ac.uk    } else {
936691Stjones1@inf.ed.ac.uk        xer.ov = 0;
946691Stjones1@inf.ed.ac.uk    }
956691Stjones1@inf.ed.ac.uk'''
966691Stjones1@inf.ed.ac.uk
976691Stjones1@inf.ed.ac.ukcomputeDivOVCode = '''
986691Stjones1@inf.ed.ac.uk    if (divSetOV) {
996691Stjones1@inf.ed.ac.uk        xer.ov = 1;
1006691Stjones1@inf.ed.ac.uk        xer.so = 1;
1016691Stjones1@inf.ed.ac.uk    } else {
1026691Stjones1@inf.ed.ac.uk        if (findOverflow(32, %(result)s, %(inputa)s, %(inputb)s)) {
1036691Stjones1@inf.ed.ac.uk            xer.ov = 1;
1046691Stjones1@inf.ed.ac.uk            xer.so = 1;
1056691Stjones1@inf.ed.ac.uk        } else {
1066691Stjones1@inf.ed.ac.uk            xer.ov = 0;
1076691Stjones1@inf.ed.ac.uk        }
1086691Stjones1@inf.ed.ac.uk    }
1096691Stjones1@inf.ed.ac.uk'''
1106691Stjones1@inf.ed.ac.uk
1116691Stjones1@inf.ed.ac.uk}};
1126691Stjones1@inf.ed.ac.uk
1136691Stjones1@inf.ed.ac.uk
1146691Stjones1@inf.ed.ac.uk// A basic integer instruction.
1156691Stjones1@inf.ed.ac.ukdef format IntOp(code, inst_flags = []) {{
1166691Stjones1@inf.ed.ac.uk    (header_output, decoder_output, decode_block, exec_output) = \
1176691Stjones1@inf.ed.ac.uk        GenAluOp(name, Name, 'IntOp', code, inst_flags, BasicDecode,
1186691Stjones1@inf.ed.ac.uk                 BasicConstructor)
1196691Stjones1@inf.ed.ac.uk}};
1206691Stjones1@inf.ed.ac.uk
1216691Stjones1@inf.ed.ac.uk
1226691Stjones1@inf.ed.ac.uk// Integer instructions with immediate (signed or unsigned).
1236691Stjones1@inf.ed.ac.ukdef format IntImmOp(code, inst_flags = []) {{
1246691Stjones1@inf.ed.ac.uk    (header_output, decoder_output, decode_block, exec_output) = \
1256691Stjones1@inf.ed.ac.uk        GenAluOp(name, Name, 'IntImmOp', code, inst_flags, BasicDecode,
1266691Stjones1@inf.ed.ac.uk                 BasicConstructor)
1276691Stjones1@inf.ed.ac.uk}};
1286691Stjones1@inf.ed.ac.uk
1296691Stjones1@inf.ed.ac.uk
1306691Stjones1@inf.ed.ac.uk// Integer instructions with immediate that perform arithmetic.
1316691Stjones1@inf.ed.ac.uk// These instructions all write to Rt and use an altered form of the
1326691Stjones1@inf.ed.ac.uk// value in source register Ra, hence the use of src to hold the actual
1336691Stjones1@inf.ed.ac.uk// value. The control flags include the use of code to compute the
1346691Stjones1@inf.ed.ac.uk// carry bit or the CR0 code.
1356691Stjones1@inf.ed.ac.ukdef format IntImmArithOp(code, ctrl_flags = [], inst_flags = []) {{
1366691Stjones1@inf.ed.ac.uk
1376691Stjones1@inf.ed.ac.uk    # Set up the dictionary and deal with control flags
1386691Stjones1@inf.ed.ac.uk    dict = {'result':'Rt', 'inputa':'src', 'inputb':'imm'}
1396691Stjones1@inf.ed.ac.uk    if ctrl_flags:
1406691Stjones1@inf.ed.ac.uk        code += readXERCode
1416691Stjones1@inf.ed.ac.uk        for val in ctrl_flags:
1426691Stjones1@inf.ed.ac.uk            if val == 'computeCA':
1436691Stjones1@inf.ed.ac.uk                code += computeCACode % dict + setXERCode
1446691Stjones1@inf.ed.ac.uk            elif val == 'computeCR0':
1456691Stjones1@inf.ed.ac.uk                code += computeCR0Code % dict
1466691Stjones1@inf.ed.ac.uk
1476691Stjones1@inf.ed.ac.uk    # Generate the class
1486691Stjones1@inf.ed.ac.uk    (header_output, decoder_output, decode_block, exec_output) = \
1496691Stjones1@inf.ed.ac.uk        GenAluOp(name, Name, 'IntImmOp', code, inst_flags, BasicDecode,
1506691Stjones1@inf.ed.ac.uk                 BasicConstructor)
1516691Stjones1@inf.ed.ac.uk}};
1526691Stjones1@inf.ed.ac.uk
1536691Stjones1@inf.ed.ac.uk
1546691Stjones1@inf.ed.ac.uk// Integer instructions with immediate that perform arithmetic but use
1556691Stjones1@inf.ed.ac.uk// the value 0 when Ra == 0. We generate two versions of each instruction
1566691Stjones1@inf.ed.ac.uk// corresponding to these two different scenarios. The correct version is
1576691Stjones1@inf.ed.ac.uk// determined at decode (see the CheckRaDecode template).
1586691Stjones1@inf.ed.ac.ukdef format IntImmArithCheckRaOp(code, code_ra0, inst_flags = []) {{
1596691Stjones1@inf.ed.ac.uk
1606691Stjones1@inf.ed.ac.uk    # First the version where Ra is non-zero
1616691Stjones1@inf.ed.ac.uk    (header_output, decoder_output, decode_block, exec_output) = \
1626691Stjones1@inf.ed.ac.uk        GenAluOp(name, Name, 'IntImmOp', code, inst_flags,
1636691Stjones1@inf.ed.ac.uk                 CheckRaDecode, BasicConstructor)
1646691Stjones1@inf.ed.ac.uk
1656691Stjones1@inf.ed.ac.uk    # Now another version where Ra == 0
1666691Stjones1@inf.ed.ac.uk    (header_output_ra0, decoder_output_ra0, _, exec_output_ra0) = \
1676691Stjones1@inf.ed.ac.uk        GenAluOp(name, Name + 'RaZero', 'IntImmOp', code_ra0, inst_flags,
1686691Stjones1@inf.ed.ac.uk                 CheckRaDecode, BasicConstructor)
1696691Stjones1@inf.ed.ac.uk
1706691Stjones1@inf.ed.ac.uk    # Finally, add to the other outputs
1716691Stjones1@inf.ed.ac.uk    header_output += header_output_ra0
1726691Stjones1@inf.ed.ac.uk    decoder_output += decoder_output_ra0
1736691Stjones1@inf.ed.ac.uk    exec_output += exec_output_ra0
1746691Stjones1@inf.ed.ac.uk}};
1756691Stjones1@inf.ed.ac.uk
1766691Stjones1@inf.ed.ac.uk
1776691Stjones1@inf.ed.ac.uk// Integer instructions with immediate that perform logic operations.
1786691Stjones1@inf.ed.ac.uk// All instructions write to Ra and use Rs as a source register. Some
1796691Stjones1@inf.ed.ac.uk// also compute the CR0 code too.
1806691Stjones1@inf.ed.ac.ukdef format IntImmLogicOp(code, computeCR0 = 0, inst_flags = []) {{
1816691Stjones1@inf.ed.ac.uk
1826691Stjones1@inf.ed.ac.uk    # Set up the dictionary and deal with computing CR0
1836691Stjones1@inf.ed.ac.uk    dict = {'result':'Ra'}
1846691Stjones1@inf.ed.ac.uk    if computeCR0:
1856691Stjones1@inf.ed.ac.uk        code += readXERCode + computeCR0Code % dict
1866691Stjones1@inf.ed.ac.uk
1876691Stjones1@inf.ed.ac.uk    # Generate the class
1886691Stjones1@inf.ed.ac.uk    (header_output, decoder_output, decode_block, exec_output) = \
1896691Stjones1@inf.ed.ac.uk        GenAluOp(name, Name, 'IntImmOp', code, inst_flags, BasicDecode,
1906691Stjones1@inf.ed.ac.uk                 BasicConstructor)
1916691Stjones1@inf.ed.ac.uk}};
1926691Stjones1@inf.ed.ac.uk
1936691Stjones1@inf.ed.ac.uk
1946691Stjones1@inf.ed.ac.uk// Integer instructions that perform logic operations. The result is
1956691Stjones1@inf.ed.ac.uk// always written into Ra. All instructions have 2 versions depending on
1966691Stjones1@inf.ed.ac.uk// whether the Rc bit is set to compute the CR0 code. This is determined
1976691Stjones1@inf.ed.ac.uk// at decode as before.
1986691Stjones1@inf.ed.ac.ukdef format IntLogicOp(code, inst_flags = []) {{
1996691Stjones1@inf.ed.ac.uk    dict = {'result':'Ra'}
2006691Stjones1@inf.ed.ac.uk
2016691Stjones1@inf.ed.ac.uk    # Code when Rc is set
2026691Stjones1@inf.ed.ac.uk    code_rc1 = code + readXERCode + computeCR0Code % dict
2036691Stjones1@inf.ed.ac.uk
2046691Stjones1@inf.ed.ac.uk    # Generate the first class
2056691Stjones1@inf.ed.ac.uk    (header_output, decoder_output, decode_block, exec_output) = \
2066691Stjones1@inf.ed.ac.uk        GenAluOp(name, Name, 'IntOp', code, inst_flags,
2076691Stjones1@inf.ed.ac.uk                 CheckRcDecode, BasicConstructor)
2086691Stjones1@inf.ed.ac.uk
2096691Stjones1@inf.ed.ac.uk    # Generate the second class
2106691Stjones1@inf.ed.ac.uk    (header_output_rc1, decoder_output_rc1, _, exec_output_rc1) = \
2116691Stjones1@inf.ed.ac.uk        GenAluOp(name, Name + 'RcSet', 'IntOp', code_rc1, inst_flags,
2126691Stjones1@inf.ed.ac.uk                 CheckRcDecode, IntRcConstructor)
2136691Stjones1@inf.ed.ac.uk
2146691Stjones1@inf.ed.ac.uk    # Finally, add to the other outputs
2156691Stjones1@inf.ed.ac.uk    header_output += header_output_rc1
2166691Stjones1@inf.ed.ac.uk    decoder_output += decoder_output_rc1
2176691Stjones1@inf.ed.ac.uk    exec_output += exec_output_rc1
2186691Stjones1@inf.ed.ac.uk}};
2196691Stjones1@inf.ed.ac.uk
2206691Stjones1@inf.ed.ac.uk
2216691Stjones1@inf.ed.ac.uk// Integer instructions with a shift amount. As above, except inheriting
2226691Stjones1@inf.ed.ac.uk// from the IntShiftOp class.
2236691Stjones1@inf.ed.ac.ukdef format IntShiftOp(code, inst_flags = []) {{
2246691Stjones1@inf.ed.ac.uk    dict = {'result':'Ra'}
2256691Stjones1@inf.ed.ac.uk
2266691Stjones1@inf.ed.ac.uk    # Code when Rc is set
2276691Stjones1@inf.ed.ac.uk    code_rc1 = code + readXERCode + computeCR0Code % dict
2286691Stjones1@inf.ed.ac.uk
2296691Stjones1@inf.ed.ac.uk    # Generate the first class
2306691Stjones1@inf.ed.ac.uk    (header_output, decoder_output, decode_block, exec_output) = \
2316691Stjones1@inf.ed.ac.uk        GenAluOp(name, Name, 'IntShiftOp', code, inst_flags,
2326691Stjones1@inf.ed.ac.uk                 CheckRcDecode, BasicConstructor)
2336691Stjones1@inf.ed.ac.uk
2346691Stjones1@inf.ed.ac.uk    # Generate the second class
2356691Stjones1@inf.ed.ac.uk    (header_output_rc1, decoder_output_rc1, _, exec_output_rc1) = \
2366691Stjones1@inf.ed.ac.uk        GenAluOp(name, Name + 'RcSet', 'IntShiftOp', code_rc1, inst_flags,
2376691Stjones1@inf.ed.ac.uk                 CheckRcDecode, IntRcConstructor)
2386691Stjones1@inf.ed.ac.uk
2396691Stjones1@inf.ed.ac.uk    # Finally, add to the other outputs
2406691Stjones1@inf.ed.ac.uk    header_output += header_output_rc1
2416691Stjones1@inf.ed.ac.uk    decoder_output += decoder_output_rc1
2426691Stjones1@inf.ed.ac.uk    exec_output += exec_output_rc1
2436691Stjones1@inf.ed.ac.uk}};
2446691Stjones1@inf.ed.ac.uk
2456691Stjones1@inf.ed.ac.uk
2466691Stjones1@inf.ed.ac.uk// Instructions in this format are all reduced to the form Rt = src1 + src2,
2476691Stjones1@inf.ed.ac.uk// therefore we just give src1 and src2 definitions. In working out the
2486691Stjones1@inf.ed.ac.uk// template we first put in the definitions of the variables and then
2496691Stjones1@inf.ed.ac.uk// the code for the addition. We also deal with computing the carry flag
2506691Stjones1@inf.ed.ac.uk// if required.
2516691Stjones1@inf.ed.ac.uk//
2526691Stjones1@inf.ed.ac.uk// We generate 4 versions of each instruction. This correspond to the
2536691Stjones1@inf.ed.ac.uk// different combinations of having the OE bit set or unset (which controls
2546691Stjones1@inf.ed.ac.uk// whether the overflow flag is computed) and the Rc bit set or unset too
2556691Stjones1@inf.ed.ac.uk// (which controls whether the CR0 code is computed).
2566691Stjones1@inf.ed.ac.ukdef format IntSumOp(src1, src2, ca = {{ 0 }}, computeCA = 0,
2576691Stjones1@inf.ed.ac.uk                    inst_flags = []) {{
2586691Stjones1@inf.ed.ac.uk
2596691Stjones1@inf.ed.ac.uk    # The result is always in Rt, but the source values vary
2606691Stjones1@inf.ed.ac.uk    dict = {'result':'Rt', 'inputa':'src1', 'inputb':'src2'}
2616691Stjones1@inf.ed.ac.uk
2626691Stjones1@inf.ed.ac.uk    # Add code to set up variables and do the sum
2636691Stjones1@inf.ed.ac.uk    code  = 'uint32_t src1 = ' + src1 + ';\n'
2646691Stjones1@inf.ed.ac.uk    code += 'uint32_t src2 = ' + src2 + ';\n'
2656691Stjones1@inf.ed.ac.uk    code += 'uint32_t ca = ' + ca + ';\n'
2666691Stjones1@inf.ed.ac.uk    code += 'Rt = src1 + src2 + ca;\n'
2676691Stjones1@inf.ed.ac.uk
2686691Stjones1@inf.ed.ac.uk    # Add code for calculating the carry, if needed
2696691Stjones1@inf.ed.ac.uk    if computeCA:
2706691Stjones1@inf.ed.ac.uk        code += computeCACode % dict + setXERCode
2716691Stjones1@inf.ed.ac.uk
2726691Stjones1@inf.ed.ac.uk    # Setup the 4 code versions and add code to access XER if necessary
2736691Stjones1@inf.ed.ac.uk    code_rc1 = readXERCode + code
2746691Stjones1@inf.ed.ac.uk    code_oe1 = readXERCode + code + computeOVCode % dict + setXERCode
2756691Stjones1@inf.ed.ac.uk    code_rc1_oe1 = readXERCode + code + computeOVCode % dict + setXERCode
2766691Stjones1@inf.ed.ac.uk    if (computeCA or ca == 'xer.ca'):
2776691Stjones1@inf.ed.ac.uk        code = readXERCode + code
2786691Stjones1@inf.ed.ac.uk    code_rc1 += computeCR0Code % dict
2796691Stjones1@inf.ed.ac.uk    code_rc1_oe1 += computeCR0Code % dict
2806691Stjones1@inf.ed.ac.uk
2816691Stjones1@inf.ed.ac.uk    # Generate the classes
2826691Stjones1@inf.ed.ac.uk    (header_output, decoder_output, decode_block, exec_output) = \
2836691Stjones1@inf.ed.ac.uk        GenAluOp(name, Name, 'IntOp', code, inst_flags,
2846691Stjones1@inf.ed.ac.uk                 CheckRcOeDecode, BasicConstructor)
2856691Stjones1@inf.ed.ac.uk    (header_output_rc1, decoder_output_rc1, _, exec_output_rc1) = \
2866691Stjones1@inf.ed.ac.uk        GenAluOp(name, Name + 'RcSet', 'IntOp', code_rc1, inst_flags,
2876691Stjones1@inf.ed.ac.uk                 CheckRcOeDecode, IntRcConstructor)
2886691Stjones1@inf.ed.ac.uk    (header_output_oe1, decoder_output_oe1, _, exec_output_oe1) = \
2896691Stjones1@inf.ed.ac.uk        GenAluOp(name, Name + 'OeSet', 'IntOp', code_oe1, inst_flags,
2906691Stjones1@inf.ed.ac.uk                 CheckRcOeDecode, IntOeConstructor)
2916691Stjones1@inf.ed.ac.uk    (header_output_rc1_oe1, decoder_output_rc1_oe1, _, exec_output_rc1_oe1) = \
2926691Stjones1@inf.ed.ac.uk        GenAluOp(name, Name + 'RcSetOeSet', 'IntOp', code_rc1_oe1,
2936691Stjones1@inf.ed.ac.uk                 inst_flags, CheckRcOeDecode, IntRcOeConstructor)
2946691Stjones1@inf.ed.ac.uk
2956691Stjones1@inf.ed.ac.uk    # Finally, add to the other outputs
2966691Stjones1@inf.ed.ac.uk    header_output += \
2976691Stjones1@inf.ed.ac.uk        header_output_rc1 + header_output_oe1 + header_output_rc1_oe1
2986691Stjones1@inf.ed.ac.uk    decoder_output += \
2996691Stjones1@inf.ed.ac.uk        decoder_output_rc1 + decoder_output_oe1 + decoder_output_rc1_oe1
3006691Stjones1@inf.ed.ac.uk    exec_output += \
3016691Stjones1@inf.ed.ac.uk        exec_output_rc1 + exec_output_oe1 + exec_output_rc1_oe1
3026691Stjones1@inf.ed.ac.uk
3036691Stjones1@inf.ed.ac.uk}};
3046691Stjones1@inf.ed.ac.uk
3056691Stjones1@inf.ed.ac.uk
3066691Stjones1@inf.ed.ac.uk// Instructions that use source registers Ra and Rb, with the result
3076691Stjones1@inf.ed.ac.uk// placed into Rt. Basically multiply and divide instructions. The
3086691Stjones1@inf.ed.ac.uk// carry bit is never set, but overflow can be calculated. Division
3096691Stjones1@inf.ed.ac.uk// explicitly sets the overflow bit in certain situations and this is
3106691Stjones1@inf.ed.ac.uk// dealt with using the 'divSetOV' boolean in decoder.isa. We generate
3116691Stjones1@inf.ed.ac.uk// two versions of each instruction to deal with the Rc bit.
3126691Stjones1@inf.ed.ac.ukdef format IntArithOp(code, computeOV = 0, inst_flags = []) {{
3136691Stjones1@inf.ed.ac.uk
3146691Stjones1@inf.ed.ac.uk    # The result is always in Rt, but the source values vary
3156691Stjones1@inf.ed.ac.uk    dict = {'result':'Rt', 'inputa':'src1', 'inputb':'src2'}
3166691Stjones1@inf.ed.ac.uk
3176691Stjones1@inf.ed.ac.uk    # Deal with setting the overflow flag
3186691Stjones1@inf.ed.ac.uk    if computeOV:
3196691Stjones1@inf.ed.ac.uk        code = 'bool divSetOV = false;\n' + code
3206691Stjones1@inf.ed.ac.uk        code += computeDivOVCode % dict + setXERCode
3216691Stjones1@inf.ed.ac.uk
3226691Stjones1@inf.ed.ac.uk    # Setup the 2 code versions and add code to access XER if necessary
3236691Stjones1@inf.ed.ac.uk    code_rc1 = readXERCode + code + computeCR0Code % dict
3246691Stjones1@inf.ed.ac.uk    if computeOV:
3256691Stjones1@inf.ed.ac.uk        code = readXERCode + code
3266691Stjones1@inf.ed.ac.uk
3276691Stjones1@inf.ed.ac.uk    # Generate the classes
3286691Stjones1@inf.ed.ac.uk    (header_output, decoder_output, decode_block, exec_output) = \
3296691Stjones1@inf.ed.ac.uk        GenAluOp(name, Name, 'IntOp', code, inst_flags,
3306691Stjones1@inf.ed.ac.uk                 CheckRcDecode, BasicConstructor)
3316691Stjones1@inf.ed.ac.uk
3326691Stjones1@inf.ed.ac.uk    # Generate the second class
3336691Stjones1@inf.ed.ac.uk    (header_output_rc1, decoder_output_rc1, _, exec_output_rc1) = \
3346691Stjones1@inf.ed.ac.uk        GenAluOp(name, Name + 'RcSet', 'IntOp', code_rc1, inst_flags,
3356691Stjones1@inf.ed.ac.uk                 CheckRcDecode, IntRcConstructor)
3366691Stjones1@inf.ed.ac.uk
3376691Stjones1@inf.ed.ac.uk    # Finally, add to the other outputs
3386691Stjones1@inf.ed.ac.uk    header_output += header_output_rc1
3396691Stjones1@inf.ed.ac.uk    decoder_output += decoder_output_rc1
3406691Stjones1@inf.ed.ac.uk    exec_output += exec_output_rc1
3416691Stjones1@inf.ed.ac.uk}};
3426691Stjones1@inf.ed.ac.uk
3436691Stjones1@inf.ed.ac.uk
3446691Stjones1@inf.ed.ac.uk// A special format for rotate instructions which use certain fields
3456691Stjones1@inf.ed.ac.uk// from the instruction's binary encoding. We need two versions for each
3466691Stjones1@inf.ed.ac.uk// instruction to deal with the Rc bit.
3476691Stjones1@inf.ed.ac.ukdef format IntRotateOp(code, inst_flags = []) {{
3486691Stjones1@inf.ed.ac.uk
3496691Stjones1@inf.ed.ac.uk    # The result is always in Ra
3506691Stjones1@inf.ed.ac.uk    dict = {'result':'Ra'}
3516691Stjones1@inf.ed.ac.uk
3526691Stjones1@inf.ed.ac.uk    # Setup the code for when Rc is set
3536691Stjones1@inf.ed.ac.uk    code_rc1 = readXERCode + code + computeCR0Code % dict
3546691Stjones1@inf.ed.ac.uk
3556691Stjones1@inf.ed.ac.uk    # Generate the first class
3566691Stjones1@inf.ed.ac.uk    (header_output, decoder_output, decode_block, exec_output) = \
3576691Stjones1@inf.ed.ac.uk        GenAluOp(name, Name, 'IntRotateOp', code, inst_flags,
3586691Stjones1@inf.ed.ac.uk                 CheckRcDecode, BasicConstructor)
3596691Stjones1@inf.ed.ac.uk
3606691Stjones1@inf.ed.ac.uk    # Generate the second class
3616691Stjones1@inf.ed.ac.uk    (header_output_rc1, decoder_output_rc1, _, exec_output_rc1) = \
3626691Stjones1@inf.ed.ac.uk        GenAluOp(name, Name + 'RcSet', 'IntRotateOp', code_rc1, inst_flags,
3636691Stjones1@inf.ed.ac.uk                 CheckRcDecode, IntRcConstructor)
3646691Stjones1@inf.ed.ac.uk
3656691Stjones1@inf.ed.ac.uk    # Finally, add to the other outputs
3666691Stjones1@inf.ed.ac.uk    header_output += header_output_rc1
3676691Stjones1@inf.ed.ac.uk    decoder_output += decoder_output_rc1
3686691Stjones1@inf.ed.ac.uk    exec_output += exec_output_rc1
3696691Stjones1@inf.ed.ac.uk}};
370