1// -*- mode:c++ -*-
2
3// Copyright (c) 2009 The University of Edinburgh
4// All rights reserved.
5//
6// Redistribution and use in source and binary forms, with or without
7// modification, are permitted provided that the following conditions are
8// met: redistributions of source code must retain the above copyright
9// notice, this list of conditions and the following disclaimer;
10// redistributions in binary form must reproduce the above copyright
11// notice, this list of conditions and the following disclaimer in the
12// documentation and/or other materials provided with the distribution;
13// neither the name of the copyright holders nor the names of its
14// contributors may be used to endorse or promote products derived from
15// this software without specific prior written permission.
16//
17// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28//
29// Authors: Timothy M. Jones
30
31////////////////////////////////////////////////////////////////////
32//
33// Floating Point operate instructions
34//
35
36
37let {{
38
39    readFPSCRCode = 'Fpscr fpscr = FPSCR;'
40
41    computeCR1Code = '''
42        Cr cr = CR;
43        cr.cr1 = (fpscr.fx << 3) | (fpscr.fex << 2) |
44                 (fpscr.vx << 1) | fpscr.ox;
45        CR = cr;
46    '''
47
48}};
49
50// Primary format for floating point operate instructions:
51def format FloatOp(code, inst_flags = []) {{
52    iop = InstObjParams(name, Name, 'FloatOp',
53                        {"code": code},
54                        inst_flags)
55    header_output = BasicDeclare.subst(iop)
56    decoder_output = BasicConstructor.subst(iop)
57    decode_block = BasicDecode.subst(iop)
58    exec_output = BasicExecute.subst(iop)
59}};
60
61// Floating point operations that compute the CR1 code if RC is set. No other
62// special registers are touched using these operations.
63def format FloatRCCheckOp(code, inst_flags = []) {{
64
65    # Code when Rc is set
66    code_rc1 = code + readFPSCRCode + computeCR1Code
67
68    # Generate the first class
69    (header_output, decoder_output, decode_block, exec_output) = \
70        GenAluOp(name, Name, 'FloatOp', code, inst_flags,
71                 CheckRcDecode, BasicConstructor)
72
73    # Generate the second class
74    (header_output_rc1, decoder_output_rc1, _, exec_output_rc1) = \
75        GenAluOp(name, Name + 'RcSet', 'FloatOp', code_rc1, inst_flags,
76                 CheckRcDecode, IntRcConstructor)
77
78    # Finally, add to the other outputs
79    header_output += header_output_rc1
80    decoder_output += decoder_output_rc1
81    exec_output += exec_output_rc1
82}};
83
84// Floating point elementary arithmetic operations. Besides having two
85// versions of each instruction for when Rc is set or not, we also have
86// to alter lots of special registers depending on the result of the
87// operation. The result is always in Ft_sf.
88def format FloatArithOp(code, inst_flags = []) {{
89
90    # Code when Rc is set
91    code_rc1 = code + readFPSCRCode + computeCR1Code
92
93    # Generate the first class
94    (header_output, decoder_output, decode_block, exec_output) = \
95        GenAluOp(name, Name, 'FloatOp', code, inst_flags,
96                 CheckRcDecode, BasicConstructor)
97
98    # Generate the second class
99    (header_output_rc1, decoder_output_rc1, _, exec_output_rc1) = \
100        GenAluOp(name, Name + 'RcSet', 'FloatOp', code_rc1, inst_flags,
101                 CheckRcDecode, IntRcConstructor)
102
103    # Finally, add to the other outputs
104    header_output += header_output_rc1
105    decoder_output += decoder_output_rc1
106    exec_output += exec_output_rc1
107}};
108
109// Floating point rounding and conversion operations. Besides having two
110// versions of each instruction for when Rc is set or not, we also have
111// to alter lots of special registers depending on the result of the
112// operation. The result is always in Ft_sf.
113def format FloatConvertOp(code, inst_flags = []) {{
114
115    # Code when Rc is set
116    code_rc1 = code + readFPSCRCode + computeCR1Code
117
118    # Generate the first class
119    (header_output, decoder_output, decode_block, exec_output) = \
120        GenAluOp(name, Name, 'FloatOp', code, inst_flags,
121                 CheckRcDecode, BasicConstructor)
122
123    # Generate the second class
124    (header_output_rc1, decoder_output_rc1, _, exec_output_rc1) = \
125        GenAluOp(name, Name + 'RcSet', 'FloatOp', code_rc1, inst_flags,
126                 CheckRcDecode, IntRcConstructor)
127
128    # Finally, add to the other outputs
129    header_output += header_output_rc1
130    decoder_output += decoder_output_rc1
131    exec_output += exec_output_rc1
132}};
133