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// Floating Point operate instructions
346691Stjones1@inf.ed.ac.uk//
356691Stjones1@inf.ed.ac.uk
366691Stjones1@inf.ed.ac.uk
376691Stjones1@inf.ed.ac.uklet {{
386691Stjones1@inf.ed.ac.uk
396691Stjones1@inf.ed.ac.uk    readFPSCRCode = 'Fpscr fpscr = FPSCR;'
406691Stjones1@inf.ed.ac.uk
416691Stjones1@inf.ed.ac.uk    computeCR1Code = '''
426691Stjones1@inf.ed.ac.uk        Cr cr = CR;
436691Stjones1@inf.ed.ac.uk        cr.cr1 = (fpscr.fx << 3) | (fpscr.fex << 2) |
446691Stjones1@inf.ed.ac.uk                 (fpscr.vx << 1) | fpscr.ox;
456691Stjones1@inf.ed.ac.uk        CR = cr;
466691Stjones1@inf.ed.ac.uk    '''
476691Stjones1@inf.ed.ac.uk
486691Stjones1@inf.ed.ac.uk}};
496691Stjones1@inf.ed.ac.uk
506691Stjones1@inf.ed.ac.uk// Primary format for floating point operate instructions:
516691Stjones1@inf.ed.ac.ukdef format FloatOp(code, inst_flags = []) {{
526691Stjones1@inf.ed.ac.uk    iop = InstObjParams(name, Name, 'FloatOp',
536691Stjones1@inf.ed.ac.uk                        {"code": code},
546691Stjones1@inf.ed.ac.uk                        inst_flags)
556691Stjones1@inf.ed.ac.uk    header_output = BasicDeclare.subst(iop)
566691Stjones1@inf.ed.ac.uk    decoder_output = BasicConstructor.subst(iop)
576691Stjones1@inf.ed.ac.uk    decode_block = BasicDecode.subst(iop)
586691Stjones1@inf.ed.ac.uk    exec_output = BasicExecute.subst(iop)
596691Stjones1@inf.ed.ac.uk}};
606691Stjones1@inf.ed.ac.uk
616691Stjones1@inf.ed.ac.uk// Floating point operations that compute the CR1 code if RC is set. No other
626691Stjones1@inf.ed.ac.uk// special registers are touched using these operations.
636691Stjones1@inf.ed.ac.ukdef format FloatRCCheckOp(code, inst_flags = []) {{
646691Stjones1@inf.ed.ac.uk
656691Stjones1@inf.ed.ac.uk    # Code when Rc is set
666691Stjones1@inf.ed.ac.uk    code_rc1 = code + readFPSCRCode + computeCR1Code
676691Stjones1@inf.ed.ac.uk
686691Stjones1@inf.ed.ac.uk    # Generate the first class
696691Stjones1@inf.ed.ac.uk    (header_output, decoder_output, decode_block, exec_output) = \
706691Stjones1@inf.ed.ac.uk        GenAluOp(name, Name, 'FloatOp', code, inst_flags,
716691Stjones1@inf.ed.ac.uk                 CheckRcDecode, BasicConstructor)
726691Stjones1@inf.ed.ac.uk
736691Stjones1@inf.ed.ac.uk    # Generate the second class
746691Stjones1@inf.ed.ac.uk    (header_output_rc1, decoder_output_rc1, _, exec_output_rc1) = \
756691Stjones1@inf.ed.ac.uk        GenAluOp(name, Name + 'RcSet', 'FloatOp', code_rc1, inst_flags,
766691Stjones1@inf.ed.ac.uk                 CheckRcDecode, IntRcConstructor)
776691Stjones1@inf.ed.ac.uk
786691Stjones1@inf.ed.ac.uk    # Finally, add to the other outputs
796691Stjones1@inf.ed.ac.uk    header_output += header_output_rc1
806691Stjones1@inf.ed.ac.uk    decoder_output += decoder_output_rc1
816691Stjones1@inf.ed.ac.uk    exec_output += exec_output_rc1
826691Stjones1@inf.ed.ac.uk}};
836691Stjones1@inf.ed.ac.uk
846691Stjones1@inf.ed.ac.uk// Floating point elementary arithmetic operations. Besides having two
856691Stjones1@inf.ed.ac.uk// versions of each instruction for when Rc is set or not, we also have
866691Stjones1@inf.ed.ac.uk// to alter lots of special registers depending on the result of the
878588Sgblack@eecs.umich.edu// operation. The result is always in Ft_sf.
886691Stjones1@inf.ed.ac.ukdef format FloatArithOp(code, inst_flags = []) {{
896691Stjones1@inf.ed.ac.uk
906691Stjones1@inf.ed.ac.uk    # Code when Rc is set
916691Stjones1@inf.ed.ac.uk    code_rc1 = code + readFPSCRCode + computeCR1Code
926691Stjones1@inf.ed.ac.uk
936691Stjones1@inf.ed.ac.uk    # Generate the first class
946691Stjones1@inf.ed.ac.uk    (header_output, decoder_output, decode_block, exec_output) = \
956691Stjones1@inf.ed.ac.uk        GenAluOp(name, Name, 'FloatOp', code, inst_flags,
966691Stjones1@inf.ed.ac.uk                 CheckRcDecode, BasicConstructor)
976691Stjones1@inf.ed.ac.uk
986691Stjones1@inf.ed.ac.uk    # Generate the second class
996691Stjones1@inf.ed.ac.uk    (header_output_rc1, decoder_output_rc1, _, exec_output_rc1) = \
1006691Stjones1@inf.ed.ac.uk        GenAluOp(name, Name + 'RcSet', 'FloatOp', code_rc1, inst_flags,
1016691Stjones1@inf.ed.ac.uk                 CheckRcDecode, IntRcConstructor)
1026691Stjones1@inf.ed.ac.uk
1036691Stjones1@inf.ed.ac.uk    # Finally, add to the other outputs
1046691Stjones1@inf.ed.ac.uk    header_output += header_output_rc1
1056691Stjones1@inf.ed.ac.uk    decoder_output += decoder_output_rc1
1066691Stjones1@inf.ed.ac.uk    exec_output += exec_output_rc1
1076691Stjones1@inf.ed.ac.uk}};
1086691Stjones1@inf.ed.ac.uk
1096691Stjones1@inf.ed.ac.uk// Floating point rounding and conversion operations. Besides having two
1106691Stjones1@inf.ed.ac.uk// versions of each instruction for when Rc is set or not, we also have
1116691Stjones1@inf.ed.ac.uk// to alter lots of special registers depending on the result of the
1128588Sgblack@eecs.umich.edu// operation. The result is always in Ft_sf.
1136691Stjones1@inf.ed.ac.ukdef format FloatConvertOp(code, inst_flags = []) {{
1146691Stjones1@inf.ed.ac.uk
1156691Stjones1@inf.ed.ac.uk    # Code when Rc is set
1166691Stjones1@inf.ed.ac.uk    code_rc1 = code + readFPSCRCode + computeCR1Code
1176691Stjones1@inf.ed.ac.uk
1186691Stjones1@inf.ed.ac.uk    # Generate the first class
1196691Stjones1@inf.ed.ac.uk    (header_output, decoder_output, decode_block, exec_output) = \
1206691Stjones1@inf.ed.ac.uk        GenAluOp(name, Name, 'FloatOp', code, inst_flags,
1216691Stjones1@inf.ed.ac.uk                 CheckRcDecode, BasicConstructor)
1226691Stjones1@inf.ed.ac.uk
1236691Stjones1@inf.ed.ac.uk    # Generate the second class
1246691Stjones1@inf.ed.ac.uk    (header_output_rc1, decoder_output_rc1, _, exec_output_rc1) = \
1256691Stjones1@inf.ed.ac.uk        GenAluOp(name, Name + 'RcSet', 'FloatOp', code_rc1, inst_flags,
1266691Stjones1@inf.ed.ac.uk                 CheckRcDecode, IntRcConstructor)
1276691Stjones1@inf.ed.ac.uk
1286691Stjones1@inf.ed.ac.uk    # Finally, add to the other outputs
1296691Stjones1@inf.ed.ac.uk    header_output += header_output_rc1
1306691Stjones1@inf.ed.ac.uk    decoder_output += decoder_output_rc1
1316691Stjones1@inf.ed.ac.uk    exec_output += exec_output_rc1
1326691Stjones1@inf.ed.ac.uk}};
133