vfp.isa revision 10205:3ca67d0e0e7e
1// -*- mode:c++ -*-
2
3// Copyright (c) 2010-2013 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        uint32_t issEnCheck;
43        bool trapEnCheck;
44        uint32_t seq;
45        if (!vfpNeonEnabled(seq,Hcptr, Nsacr, Cpacr, Cpsr, issEnCheck,
46                            trapEnCheck, xc->tcBase(), Fpexc))
47            {return disabledFault();}
48        if (trapEnCheck) {
49            CPSR cpsrEnCheck = Cpsr;
50            if (cpsrEnCheck.mode == MODE_HYP) {
51                return new UndefinedInstruction(machInst, issEnCheck,
52                                                EC_TRAPPED_HCPTR, mnemonic);
53            } else {
54                if (!inSecureState(Scr, Cpsr)) {
55                    return new HypervisorTrap(machInst, issEnCheck,
56                                              EC_TRAPPED_HCPTR);
57                }
58            }
59        }
60    '''
61
62    vfp64EnabledCheckCode = '''
63        CPSR cpsrEnCheck = Cpsr;
64        ExceptionLevel el = (ExceptionLevel) (uint8_t) cpsrEnCheck.el;
65        if (!vfpNeon64Enabled(Cpacr64, el))
66             return new SupervisorTrap(machInst, 0x1E00000,
67                                       EC_TRAPPED_SIMD_FP);
68
69        if (ArmSystem::haveVirtualization(xc->tcBase()) && el <= EL2) {
70            HCPTR cptrEnCheck = xc->tcBase()->readMiscReg(MISCREG_CPTR_EL2);
71            if (cptrEnCheck.tfp)
72                return new HypervisorTrap(machInst, 0x1E00000,
73                                          EC_TRAPPED_SIMD_FP);
74        }
75
76        if (ArmSystem::haveSecurity(xc->tcBase())) {
77            HCPTR cptrEnCheck = xc->tcBase()->readMiscReg(MISCREG_CPTR_EL3);
78            if (cptrEnCheck.tfp)
79                return new SecureMonitorTrap(machInst, 0x1E00000,
80                                             EC_TRAPPED_SIMD_FP);
81        }
82    '''
83
84    vmsrEnabledCheckCode = '''
85        uint32_t issEnCheck;
86        bool trapEnCheck;
87        uint32_t seq;
88        if (!vfpNeonEnabled(seq,Hcptr, Nsacr, Cpacr, Cpsr, issEnCheck,
89                            trapEnCheck, xc->tcBase()))
90            if (dest != (int)MISCREG_FPEXC && dest != (int)MISCREG_FPSID)
91                {return disabledFault();}
92        if (!inPrivilegedMode(Cpsr))
93            if (dest != (int)MISCREG_FPSCR)
94                return disabledFault();
95        if (trapEnCheck) {
96            CPSR cpsrEnCheck = Cpsr;
97            if (cpsrEnCheck.mode == MODE_HYP) {
98                return new UndefinedInstruction(machInst, issEnCheck,
99                                                EC_TRAPPED_HCPTR, mnemonic);
100            } else {
101                if (!inSecureState(Scr, Cpsr)) {
102                    return new HypervisorTrap(machInst, issEnCheck,
103                                              EC_TRAPPED_HCPTR);
104                }
105            }
106        }
107    '''
108
109    vmrsEnabledCheckCode = '''
110        uint32_t issEnCheck;
111        bool trapEnCheck;
112        uint32_t seq;
113        if (!vfpNeonEnabled(seq,Hcptr, Nsacr, Cpacr, Cpsr, issEnCheck,
114                            trapEnCheck, xc->tcBase()))
115            if (op1 != (int)MISCREG_FPEXC && op1 != (int)MISCREG_FPSID &&
116                op1 != (int)MISCREG_MVFR0 && op1 != (int)MISCREG_MVFR1)
117                {return disabledFault();}
118        if (!inPrivilegedMode(Cpsr))
119            if (op1 != (int)MISCREG_FPSCR)
120                return disabledFault();
121        if (trapEnCheck) {
122            CPSR cpsrEnCheck = Cpsr;
123            if (cpsrEnCheck.mode == MODE_HYP) {
124                return new UndefinedInstruction(machInst, issEnCheck,
125                                                EC_TRAPPED_HCPTR, mnemonic);
126            } else {
127                if (!inSecureState(Scr, Cpsr)) {
128                    return new HypervisorTrap(machInst, issEnCheck,
129                                              EC_TRAPPED_HCPTR);
130                }
131            }
132        }
133    '''
134    vmrsApsrEnabledCheckCode = '''
135        uint32_t issEnCheck;
136        bool trapEnCheck;
137        uint32_t seq;
138        if (!vfpNeonEnabled(seq,Hcptr, Nsacr, Cpacr, Cpsr, issEnCheck,
139                            trapEnCheck, xc->tcBase()))
140            {return disabledFault();}
141        if (trapEnCheck) {
142            CPSR cpsrEnCheck = Cpsr;
143            if (cpsrEnCheck.mode == MODE_HYP) {
144                return new UndefinedInstruction(machInst, issEnCheck,
145                                                EC_TRAPPED_HCPTR, mnemonic);
146            } else {
147                if (!inSecureState(Scr, Cpsr)) {
148                    return new HypervisorTrap(machInst, issEnCheck,
149                                              EC_TRAPPED_HCPTR);
150                }
151            }
152        }
153    '''
154}};
155
156def template FpRegRegOpDeclare {{
157class %(class_name)s : public %(base_class)s
158{
159  public:
160    // Constructor
161    %(class_name)s(ExtMachInst machInst,
162                   IntRegIndex _dest, IntRegIndex _op1,
163                   VfpMicroMode mode = VfpNotAMicroop);
164    %(BasicExecDeclare)s
165};
166}};
167
168def template FpRegRegOpConstructor {{
169    %(class_name)s::%(class_name)s(ExtMachInst machInst,
170                                          IntRegIndex _dest, IntRegIndex _op1,
171                                          VfpMicroMode mode)
172        : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
173                _dest, _op1, 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 FpRegImmOpDeclare {{
185class %(class_name)s : public %(base_class)s
186{
187  public:
188    // Constructor
189    %(class_name)s(ExtMachInst machInst, IntRegIndex _dest,
190            uint64_t _imm, VfpMicroMode mode = VfpNotAMicroop);
191    %(BasicExecDeclare)s
192};
193}};
194
195def template FpRegImmOpConstructor {{
196    %(class_name)s::%(class_name)s(ExtMachInst machInst,
197            IntRegIndex _dest, uint64_t _imm, VfpMicroMode mode)
198        : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
199                _dest, _imm, mode)
200    {
201        %(constructor)s;
202        if (!(condCode == COND_AL || condCode == COND_UC)) {
203            for (int x = 0; x < _numDestRegs; x++) {
204                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
205            }
206        }
207    }
208}};
209
210def template FpRegRegImmOpDeclare {{
211class %(class_name)s : public %(base_class)s
212{
213  public:
214    // Constructor
215    %(class_name)s(ExtMachInst machInst,
216                   IntRegIndex _dest, IntRegIndex _op1,
217                   uint64_t _imm, VfpMicroMode mode = VfpNotAMicroop);
218    %(BasicExecDeclare)s
219};
220}};
221
222def template FpRegRegImmOpConstructor {{
223    %(class_name)s::%(class_name)s(ExtMachInst machInst,
224                                          IntRegIndex _dest,
225                                          IntRegIndex _op1,
226                                          uint64_t _imm,
227                                          VfpMicroMode mode)
228        : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
229                         _dest, _op1, _imm, mode)
230    {
231        %(constructor)s;
232        if (!(condCode == COND_AL || condCode == COND_UC)) {
233            for (int x = 0; x < _numDestRegs; x++) {
234                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
235            }
236        }
237    }
238}};
239
240def template FpRegRegRegOpDeclare {{
241class %(class_name)s : public %(base_class)s
242{
243  public:
244    // Constructor
245    %(class_name)s(ExtMachInst machInst,
246                   IntRegIndex _dest, IntRegIndex _op1, IntRegIndex _op2,
247                   VfpMicroMode mode = VfpNotAMicroop);
248    %(BasicExecDeclare)s
249};
250}};
251
252def template FpRegRegRegOpConstructor {{
253    %(class_name)s::%(class_name)s(ExtMachInst machInst,
254                                          IntRegIndex _dest,
255                                          IntRegIndex _op1,
256                                          IntRegIndex _op2,
257                                          VfpMicroMode mode)
258        : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
259                         _dest, _op1, _op2, mode)
260    {
261        %(constructor)s;
262        if (!(condCode == COND_AL || condCode == COND_UC)) {
263            for (int x = 0; x < _numDestRegs; x++) {
264                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
265            }
266        }
267    }
268}};
269