integer.isa revision 10184
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