1// -*- mode:c++ -*-
2
3// Copyright (c) 2010-2013, 2016 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    vfpEnabledCheckCode = '''
42    {
43        Fault fault = checkAdvSIMDOrFPEnabled32(xc->tcBase(),
44                                                Cpsr, Cpacr, Nsacr, Fpexc,
45                                                true, false);
46        if (fault != NoFault)
47            return fault;
48    }
49    '''
50
51    vfp64EnabledCheckCode = '''
52    {
53        Fault fault = checkFPAdvSIMDEnabled64(xc->tcBase(), Cpsr, Cpacr64);
54        if (fault != NoFault)
55             return fault;
56    }
57    '''
58
59    vmsrEnabledCheckCode = '''
60    {
61        Fault fault = NoFault;
62        if (dest == (int)MISCREG_FPSCR) {
63            fault = checkAdvSIMDOrFPEnabled32(xc->tcBase(),
64                                              Cpsr, Cpacr, Nsacr, Fpexc,
65                                              true, false);
66        } else if (!inPrivilegedMode(Cpsr)) {
67            fault = disabledFault();
68        } else {
69            fault = checkAdvSIMDOrFPEnabled32(xc->tcBase(),
70                                              Cpsr, Cpacr, Nsacr, Fpexc,
71                                              false, false);
72        }
73
74        if (fault != NoFault)
75            return fault;
76    }
77    '''
78
79    vmrsEnabledCheckCode = '''
80    {
81        Fault fault = NoFault;
82        if (op1 == (int)MISCREG_FPSCR) {
83            fault = checkAdvSIMDOrFPEnabled32(xc->tcBase(),
84                                              Cpsr, Cpacr, Nsacr, Fpexc,
85                                              true, false);
86        } else if (!inPrivilegedMode(Cpsr)) {
87            fault = disabledFault();
88        } else {
89            fault = checkAdvSIMDOrFPEnabled32(xc->tcBase(),
90                                              Cpsr, Cpacr, Nsacr, Fpexc,
91                                              false, false);
92        }
93
94        if (fault != NoFault)
95            return fault;
96    }
97    '''
98}};
99
100def template FpRegRegOpDeclare {{
101class %(class_name)s : public %(base_class)s
102{
103  public:
104    // Constructor
105    %(class_name)s(ExtMachInst machInst,
106                   IntRegIndex _dest, IntRegIndex _op1,
107                   VfpMicroMode mode = VfpNotAMicroop);
108    Fault execute(ExecContext *, Trace::InstRecord *) const override;
109};
110}};
111
112def template FpRegRegOpConstructor {{
113    %(class_name)s::%(class_name)s(ExtMachInst machInst,
114                                          IntRegIndex _dest, IntRegIndex _op1,
115                                          VfpMicroMode mode)
116        : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
117                _dest, _op1, mode)
118    {
119        %(constructor)s;
120        if (!(condCode == COND_AL || condCode == COND_UC)) {
121            for (int x = 0; x < _numDestRegs; x++) {
122                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
123            }
124        }
125    }
126}};
127
128def template FpRegImmOpDeclare {{
129class %(class_name)s : public %(base_class)s
130{
131  public:
132    // Constructor
133    %(class_name)s(ExtMachInst machInst, IntRegIndex _dest,
134            uint64_t _imm, VfpMicroMode mode = VfpNotAMicroop);
135    Fault execute(ExecContext *, Trace::InstRecord *) const override;
136};
137}};
138
139def template FpRegImmOpConstructor {{
140    %(class_name)s::%(class_name)s(ExtMachInst machInst,
141            IntRegIndex _dest, uint64_t _imm, VfpMicroMode mode)
142        : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
143                _dest, _imm, mode)
144    {
145        %(constructor)s;
146        if (!(condCode == COND_AL || condCode == COND_UC)) {
147            for (int x = 0; x < _numDestRegs; x++) {
148                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
149            }
150        }
151    }
152}};
153
154def template FpRegRegImmOpDeclare {{
155class %(class_name)s : public %(base_class)s
156{
157  public:
158    // Constructor
159    %(class_name)s(ExtMachInst machInst,
160                   IntRegIndex _dest, IntRegIndex _op1,
161                   uint64_t _imm, VfpMicroMode mode = VfpNotAMicroop);
162    Fault execute(ExecContext *, Trace::InstRecord *) const override;
163};
164}};
165
166def template FpRegRegImmOpConstructor {{
167    %(class_name)s::%(class_name)s(ExtMachInst machInst,
168                                          IntRegIndex _dest,
169                                          IntRegIndex _op1,
170                                          uint64_t _imm,
171                                          VfpMicroMode mode)
172        : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
173                         _dest, _op1, _imm, mode)
174    {
175        %(constructor)s;
176        if (!(condCode == COND_AL || condCode == COND_UC)) {
177            for (int x = 0; x < _numDestRegs; x++) {
178                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
179            }
180        }
181    }
182}};
183
184def template FpRegRegRegOpDeclare {{
185class %(class_name)s : public %(base_class)s
186{
187  public:
188    // Constructor
189    %(class_name)s(ExtMachInst machInst,
190                   IntRegIndex _dest, IntRegIndex _op1, IntRegIndex _op2,
191                   VfpMicroMode mode = VfpNotAMicroop);
192    Fault execute(ExecContext *, Trace::InstRecord *) const override;
193};
194}};
195
196def template FpRegRegRegOpConstructor {{
197    %(class_name)s::%(class_name)s(ExtMachInst machInst,
198                                          IntRegIndex _dest,
199                                          IntRegIndex _op1,
200                                          IntRegIndex _op2,
201                                          VfpMicroMode mode)
202        : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
203                         _dest, _op1, _op2, mode)
204    {
205        %(constructor)s;
206        if (!(condCode == COND_AL || condCode == COND_UC)) {
207            for (int x = 0; x < _numDestRegs; x++) {
208                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
209            }
210        }
211    }
212}};
213
214def template FpRegRegRegCondOpDeclare {{
215class %(class_name)s : public %(base_class)s
216{
217  public:
218    // Constructor
219    %(class_name)s(ExtMachInst machInst,
220                   IntRegIndex _dest, IntRegIndex _op1, IntRegIndex _op2,
221                  ConditionCode _cond,
222                   VfpMicroMode mode = VfpNotAMicroop);
223    Fault execute(ExecContext *, Trace::InstRecord *) const override;
224};
225}};
226
227def template FpRegRegRegCondOpConstructor {{
228    %(class_name)s::%(class_name)s(ExtMachInst machInst,
229                                          IntRegIndex _dest,
230                                          IntRegIndex _op1,
231                                          IntRegIndex _op2,
232                                          ConditionCode _cond,
233                                          VfpMicroMode mode)
234        : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
235                         _dest, _op1, _op2, _cond, mode)
236    {
237        %(constructor)s;
238    }
239}};
240