fp64.isa (12110:c24ee249b8ba) fp64.isa (13120:690a0db8e58b)
1// -*- mode:c++ -*-
2
1// -*- mode:c++ -*-
2
3// Copyright (c) 2012-2013, 2016 ARM Limited
3// Copyright (c) 2012-2013, 2016-2018 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: Thomas Grocutt
39// Edmund Grimley Evans
40
41let {{
42
43 header_output = ""
44 decoder_output = ""
45 exec_output = ""
46
47 fmovImmSCode = vfp64EnabledCheckCode + '''
48 AA64FpDestP0_uw = bits(imm, 31, 0);
49 AA64FpDestP1_uw = 0;
50 AA64FpDestP2_uw = 0;
51 AA64FpDestP3_uw = 0;
52 '''
53 fmovImmSIop = InstObjParams("fmov", "FmovImmS", "FpRegImmOp",
54 { "code": fmovImmSCode,
55 "op_class": "FloatMiscOp" }, [])
56 header_output += FpRegImmOpDeclare.subst(fmovImmSIop);
57 decoder_output += FpRegImmOpConstructor.subst(fmovImmSIop);
58 exec_output += BasicExecute.subst(fmovImmSIop);
59
60 fmovImmDCode = vfp64EnabledCheckCode + '''
61 AA64FpDestP0_uw = bits(imm, 31, 0);
62 AA64FpDestP1_uw = bits(imm, 63, 32);
63 AA64FpDestP2_uw = 0;
64 AA64FpDestP3_uw = 0;
65 '''
66 fmovImmDIop = InstObjParams("fmov", "FmovImmD", "FpRegImmOp",
67 { "code": fmovImmDCode,
68 "op_class": "FloatMiscOp" }, [])
69 header_output += FpRegImmOpDeclare.subst(fmovImmDIop);
70 decoder_output += AA64FpRegImmOpConstructor.subst(fmovImmDIop);
71 exec_output += BasicExecute.subst(fmovImmDIop);
72
73 fmovRegSCode = vfp64EnabledCheckCode + '''
74 AA64FpDestP0_uw = AA64FpOp1P0_uw;
75 AA64FpDestP1_uw = 0;
76 AA64FpDestP2_uw = 0;
77 AA64FpDestP3_uw = 0;
78 '''
79 fmovRegSIop = InstObjParams("fmov", "FmovRegS", "FpRegRegOp",
80 { "code": fmovRegSCode,
81 "op_class": "FloatMiscOp" }, [])
82 header_output += FpRegRegOpDeclare.subst(fmovRegSIop);
83 decoder_output += AA64FpRegRegOpConstructor.subst(fmovRegSIop);
84 exec_output += BasicExecute.subst(fmovRegSIop);
85
86 fmovRegDCode = vfp64EnabledCheckCode + '''
87 AA64FpDestP0_uw = AA64FpOp1P0_uw;
88 AA64FpDestP1_uw = AA64FpOp1P1_uw;
89 AA64FpDestP2_uw = 0;
90 AA64FpDestP3_uw = 0;
91 '''
92 fmovRegDIop = InstObjParams("fmov", "FmovRegD", "FpRegRegOp",
93 { "code": fmovRegDCode,
94 "op_class": "FloatMiscOp" }, [])
95 header_output += FpRegRegOpDeclare.subst(fmovRegDIop);
96 decoder_output += AA64FpRegRegOpConstructor.subst(fmovRegDIop);
97 exec_output += BasicExecute.subst(fmovRegDIop);
98
99 fmovCoreRegWCode = vfp64EnabledCheckCode + '''
100 AA64FpDestP0_uw = WOp1_uw;
101 AA64FpDestP1_uw = 0;
102 AA64FpDestP2_uw = 0;
103 AA64FpDestP3_uw = 0;
104 '''
105 fmovCoreRegWIop = InstObjParams("fmov", "FmovCoreRegW", "FpRegRegOp",
106 { "code": fmovCoreRegWCode,
107 "op_class": "FloatMiscOp" }, [])
108 header_output += FpRegRegOpDeclare.subst(fmovCoreRegWIop);
109 decoder_output += AA64FpRegRegOpConstructor.subst(fmovCoreRegWIop);
110 exec_output += BasicExecute.subst(fmovCoreRegWIop);
111
112 fmovCoreRegXCode = vfp64EnabledCheckCode + '''
113 AA64FpDestP0_uw = XOp1_ud;
114 AA64FpDestP1_uw = XOp1_ud >> 32;
115 AA64FpDestP2_uw = 0;
116 AA64FpDestP3_uw = 0;
117 '''
118 fmovCoreRegXIop = InstObjParams("fmov", "FmovCoreRegX", "FpRegRegOp",
119 { "code": fmovCoreRegXCode,
120 "op_class": "FloatMiscOp" }, [])
121 header_output += FpRegRegOpDeclare.subst(fmovCoreRegXIop);
122 decoder_output += AA64FpRegRegOpConstructor.subst(fmovCoreRegXIop);
123 exec_output += BasicExecute.subst(fmovCoreRegXIop);
124
125 fmovUCoreRegXCode = vfp64EnabledCheckCode + '''
126 /* Explicitly merge with previous value */
127 AA64FpDestP0_uw = AA64FpDestP0_uw;
128 AA64FpDestP1_uw = AA64FpDestP1_uw;
129 AA64FpDestP2_uw = XOp1_ud;
130 AA64FpDestP3_uw = XOp1_ud >> 32;'''
131 fmovUCoreRegXIop = InstObjParams("fmov", "FmovUCoreRegX", "FpRegRegOp",
132 { "code": fmovUCoreRegXCode,
133 "op_class": "FloatMiscOp" }, [])
134 header_output += FpRegRegOpDeclare.subst(fmovUCoreRegXIop);
135 decoder_output += AA64FpRegRegOpConstructor.subst(fmovUCoreRegXIop);
136 exec_output += BasicExecute.subst(fmovUCoreRegXIop);
137
138 fmovRegCoreWCode = vfp64EnabledCheckCode + '''
139 WDest = AA64FpOp1P0_uw;
140 '''
141 fmovRegCoreWIop = InstObjParams("fmov", "FmovRegCoreW", "FpRegRegOp",
142 { "code": fmovRegCoreWCode,
143 "op_class": "FloatMiscOp" }, [])
144 header_output += FpRegRegOpDeclare.subst(fmovRegCoreWIop);
145 decoder_output += AA64FpRegRegOpConstructor.subst(fmovRegCoreWIop);
146 exec_output += BasicExecute.subst(fmovRegCoreWIop);
147
148 fmovRegCoreXCode = vfp64EnabledCheckCode + '''
149 XDest = ( ((uint64_t) AA64FpOp1P1_uw) << 32) | AA64FpOp1P0_uw;
150 '''
151 fmovRegCoreXIop = InstObjParams("fmov", "FmovRegCoreX", "FpRegRegOp",
152 { "code": fmovRegCoreXCode,
153 "op_class": "FloatMiscOp" }, [])
154 header_output += FpRegRegOpDeclare.subst(fmovRegCoreXIop);
155 decoder_output += AA64FpRegRegOpConstructor.subst(fmovRegCoreXIop);
156 exec_output += BasicExecute.subst(fmovRegCoreXIop);
157
158 fmovURegCoreXCode = vfp64EnabledCheckCode + '''
159 XDest = ( ((uint64_t) AA64FpOp1P3_uw) << 32) | AA64FpOp1P2_uw;
160 '''
161 fmovURegCoreXIop = InstObjParams("fmov", "FmovURegCoreX", "FpRegRegOp",
162 { "code": fmovURegCoreXCode,
163 "op_class": "FloatMiscOp" }, [])
164 header_output += FpRegRegOpDeclare.subst(fmovURegCoreXIop);
165 decoder_output += AA64FpRegRegOpConstructor.subst(fmovURegCoreXIop);
166 exec_output += BasicExecute.subst(fmovURegCoreXIop);
167}};
168
169let {{
170
171 header_output = ""
172 decoder_output = ""
173 exec_output = ""
174
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: Thomas Grocutt
39// Edmund Grimley Evans
40
41let {{
42
43 header_output = ""
44 decoder_output = ""
45 exec_output = ""
46
47 fmovImmSCode = vfp64EnabledCheckCode + '''
48 AA64FpDestP0_uw = bits(imm, 31, 0);
49 AA64FpDestP1_uw = 0;
50 AA64FpDestP2_uw = 0;
51 AA64FpDestP3_uw = 0;
52 '''
53 fmovImmSIop = InstObjParams("fmov", "FmovImmS", "FpRegImmOp",
54 { "code": fmovImmSCode,
55 "op_class": "FloatMiscOp" }, [])
56 header_output += FpRegImmOpDeclare.subst(fmovImmSIop);
57 decoder_output += FpRegImmOpConstructor.subst(fmovImmSIop);
58 exec_output += BasicExecute.subst(fmovImmSIop);
59
60 fmovImmDCode = vfp64EnabledCheckCode + '''
61 AA64FpDestP0_uw = bits(imm, 31, 0);
62 AA64FpDestP1_uw = bits(imm, 63, 32);
63 AA64FpDestP2_uw = 0;
64 AA64FpDestP3_uw = 0;
65 '''
66 fmovImmDIop = InstObjParams("fmov", "FmovImmD", "FpRegImmOp",
67 { "code": fmovImmDCode,
68 "op_class": "FloatMiscOp" }, [])
69 header_output += FpRegImmOpDeclare.subst(fmovImmDIop);
70 decoder_output += AA64FpRegImmOpConstructor.subst(fmovImmDIop);
71 exec_output += BasicExecute.subst(fmovImmDIop);
72
73 fmovRegSCode = vfp64EnabledCheckCode + '''
74 AA64FpDestP0_uw = AA64FpOp1P0_uw;
75 AA64FpDestP1_uw = 0;
76 AA64FpDestP2_uw = 0;
77 AA64FpDestP3_uw = 0;
78 '''
79 fmovRegSIop = InstObjParams("fmov", "FmovRegS", "FpRegRegOp",
80 { "code": fmovRegSCode,
81 "op_class": "FloatMiscOp" }, [])
82 header_output += FpRegRegOpDeclare.subst(fmovRegSIop);
83 decoder_output += AA64FpRegRegOpConstructor.subst(fmovRegSIop);
84 exec_output += BasicExecute.subst(fmovRegSIop);
85
86 fmovRegDCode = vfp64EnabledCheckCode + '''
87 AA64FpDestP0_uw = AA64FpOp1P0_uw;
88 AA64FpDestP1_uw = AA64FpOp1P1_uw;
89 AA64FpDestP2_uw = 0;
90 AA64FpDestP3_uw = 0;
91 '''
92 fmovRegDIop = InstObjParams("fmov", "FmovRegD", "FpRegRegOp",
93 { "code": fmovRegDCode,
94 "op_class": "FloatMiscOp" }, [])
95 header_output += FpRegRegOpDeclare.subst(fmovRegDIop);
96 decoder_output += AA64FpRegRegOpConstructor.subst(fmovRegDIop);
97 exec_output += BasicExecute.subst(fmovRegDIop);
98
99 fmovCoreRegWCode = vfp64EnabledCheckCode + '''
100 AA64FpDestP0_uw = WOp1_uw;
101 AA64FpDestP1_uw = 0;
102 AA64FpDestP2_uw = 0;
103 AA64FpDestP3_uw = 0;
104 '''
105 fmovCoreRegWIop = InstObjParams("fmov", "FmovCoreRegW", "FpRegRegOp",
106 { "code": fmovCoreRegWCode,
107 "op_class": "FloatMiscOp" }, [])
108 header_output += FpRegRegOpDeclare.subst(fmovCoreRegWIop);
109 decoder_output += AA64FpRegRegOpConstructor.subst(fmovCoreRegWIop);
110 exec_output += BasicExecute.subst(fmovCoreRegWIop);
111
112 fmovCoreRegXCode = vfp64EnabledCheckCode + '''
113 AA64FpDestP0_uw = XOp1_ud;
114 AA64FpDestP1_uw = XOp1_ud >> 32;
115 AA64FpDestP2_uw = 0;
116 AA64FpDestP3_uw = 0;
117 '''
118 fmovCoreRegXIop = InstObjParams("fmov", "FmovCoreRegX", "FpRegRegOp",
119 { "code": fmovCoreRegXCode,
120 "op_class": "FloatMiscOp" }, [])
121 header_output += FpRegRegOpDeclare.subst(fmovCoreRegXIop);
122 decoder_output += AA64FpRegRegOpConstructor.subst(fmovCoreRegXIop);
123 exec_output += BasicExecute.subst(fmovCoreRegXIop);
124
125 fmovUCoreRegXCode = vfp64EnabledCheckCode + '''
126 /* Explicitly merge with previous value */
127 AA64FpDestP0_uw = AA64FpDestP0_uw;
128 AA64FpDestP1_uw = AA64FpDestP1_uw;
129 AA64FpDestP2_uw = XOp1_ud;
130 AA64FpDestP3_uw = XOp1_ud >> 32;'''
131 fmovUCoreRegXIop = InstObjParams("fmov", "FmovUCoreRegX", "FpRegRegOp",
132 { "code": fmovUCoreRegXCode,
133 "op_class": "FloatMiscOp" }, [])
134 header_output += FpRegRegOpDeclare.subst(fmovUCoreRegXIop);
135 decoder_output += AA64FpRegRegOpConstructor.subst(fmovUCoreRegXIop);
136 exec_output += BasicExecute.subst(fmovUCoreRegXIop);
137
138 fmovRegCoreWCode = vfp64EnabledCheckCode + '''
139 WDest = AA64FpOp1P0_uw;
140 '''
141 fmovRegCoreWIop = InstObjParams("fmov", "FmovRegCoreW", "FpRegRegOp",
142 { "code": fmovRegCoreWCode,
143 "op_class": "FloatMiscOp" }, [])
144 header_output += FpRegRegOpDeclare.subst(fmovRegCoreWIop);
145 decoder_output += AA64FpRegRegOpConstructor.subst(fmovRegCoreWIop);
146 exec_output += BasicExecute.subst(fmovRegCoreWIop);
147
148 fmovRegCoreXCode = vfp64EnabledCheckCode + '''
149 XDest = ( ((uint64_t) AA64FpOp1P1_uw) << 32) | AA64FpOp1P0_uw;
150 '''
151 fmovRegCoreXIop = InstObjParams("fmov", "FmovRegCoreX", "FpRegRegOp",
152 { "code": fmovRegCoreXCode,
153 "op_class": "FloatMiscOp" }, [])
154 header_output += FpRegRegOpDeclare.subst(fmovRegCoreXIop);
155 decoder_output += AA64FpRegRegOpConstructor.subst(fmovRegCoreXIop);
156 exec_output += BasicExecute.subst(fmovRegCoreXIop);
157
158 fmovURegCoreXCode = vfp64EnabledCheckCode + '''
159 XDest = ( ((uint64_t) AA64FpOp1P3_uw) << 32) | AA64FpOp1P2_uw;
160 '''
161 fmovURegCoreXIop = InstObjParams("fmov", "FmovURegCoreX", "FpRegRegOp",
162 { "code": fmovURegCoreXCode,
163 "op_class": "FloatMiscOp" }, [])
164 header_output += FpRegRegOpDeclare.subst(fmovURegCoreXIop);
165 decoder_output += AA64FpRegRegOpConstructor.subst(fmovURegCoreXIop);
166 exec_output += BasicExecute.subst(fmovURegCoreXIop);
167}};
168
169let {{
170
171 header_output = ""
172 decoder_output = ""
173 exec_output = ""
174
175 halfIntConvCode = vfp64EnabledCheckCode + '''
176 FPSCR fpscr = (FPSCR) FpscrExc;
177 uint16_t cOp1 = AA64FpOp1P0_uw;
178 uint16_t cDest = %(op)s;
179 AA64FpDestP0_uw = cDest;
180 AA64FpDestP1_uw = 0;
181 AA64FpDestP2_uw = 0;
182 AA64FpDestP3_uw = 0;
183 FpscrExc = fpscr;
184 '''
185
186 halfIntConvCode2 = vfp64EnabledCheckCode + '''
187 FPSCR fpscr = (FPSCR) FpscrExc;
188 uint16_t cOp1 = AA64FpOp1P0_uw;
189 uint16_t cOp2 = AA64FpOp2P0_uw;
190 uint16_t cDest = %(op)s;
191 AA64FpDestP0_uw = cDest;
192 AA64FpDestP1_uw = 0;
193 AA64FpDestP2_uw = 0;
194 AA64FpDestP3_uw = 0;
195 FpscrExc = fpscr;
196 '''
197
198 halfBinOp = "binaryOp(fpscr, AA64FpOp1P0, AA64FpOp2P0," + \
199 "%(func)s, fpscr.fz, fpscr.dn, fpscr.rMode)"
200 halfUnaryOp = "unaryOp(fpscr, AA64FpOp1P0," + \
201 "%(func)s, fpscr.fz, fpscr.rMode)"
202
175 singleIntConvCode = vfp64EnabledCheckCode + '''
176 FPSCR fpscr = (FPSCR) FpscrExc;
177 uint32_t cOp1 = AA64FpOp1P0_uw;
178 uint32_t cDest = %(op)s;
179 AA64FpDestP0_uw = cDest;
180 AA64FpDestP1_uw = 0;
181 AA64FpDestP2_uw = 0;
182 AA64FpDestP3_uw = 0;
183 FpscrExc = fpscr;
184 '''
185
186 singleIntConvCode2 = vfp64EnabledCheckCode + '''
187 FPSCR fpscr = (FPSCR) FpscrExc;
188 uint32_t cOp1 = AA64FpOp1P0_uw;
189 uint32_t cOp2 = AA64FpOp2P0_uw;
190 uint32_t cDest = %(op)s;
191 AA64FpDestP0_uw = cDest;
192 AA64FpDestP1_uw = 0;
193 AA64FpDestP2_uw = 0;
194 AA64FpDestP3_uw = 0;
195 FpscrExc = fpscr;
196 '''
197
198 singleBinOp = "binaryOp(fpscr, AA64FpOp1P0, AA64FpOp2P0," + \
199 "%(func)s, fpscr.fz, fpscr.dn, fpscr.rMode)"
200 singleUnaryOp = "unaryOp(fpscr, AA64FpOp1P0, %(func)s, fpscr.fz, fpscr.rMode)"
201
202 doubleIntConvCode = vfp64EnabledCheckCode + '''
203 FPSCR fpscr = (FPSCR) FpscrExc;
204 uint64_t cOp1 = ((uint64_t) AA64FpOp1P1_uw) << 32 | AA64FpOp1P0_uw;
205 uint64_t cDest = %(op)s;
206 AA64FpDestP0_uw = cDest & 0xFFFFFFFF;
207 AA64FpDestP1_uw = cDest >> 32;
208 AA64FpDestP2_uw = 0;
209 AA64FpDestP3_uw = 0;
210 FpscrExc = fpscr;
211 '''
212
213 doubleIntConvCode2 = vfp64EnabledCheckCode + '''
214 FPSCR fpscr = (FPSCR) FpscrExc;
215 uint64_t cOp1 = ((uint64_t) AA64FpOp1P1_uw) << 32 | AA64FpOp1P0_uw;
216 uint64_t cOp2 = ((uint64_t) AA64FpOp2P1_uw) << 32 | AA64FpOp2P0_uw;
217 uint64_t cDest = %(op)s;
218 AA64FpDestP0_uw = cDest & 0xFFFFFFFF;
219 AA64FpDestP1_uw = cDest >> 32;
220 AA64FpDestP2_uw = 0;
221 AA64FpDestP3_uw = 0;
222 FpscrExc = fpscr;
223 '''
224
225 doubleBinOp = '''
226 binaryOp(fpscr, dbl(AA64FpOp1P0_uw, AA64FpOp1P1_uw),
227 dbl(AA64FpOp2P0_uw, AA64FpOp2P1_uw),
228 %(func)s, fpscr.fz, fpscr.dn, fpscr.rMode);
229 '''
230 doubleUnaryOp = '''
231 unaryOp(fpscr, dbl(AA64FpOp1P0_uw, AA64FpOp1P1_uw), %(func)s,
232 fpscr.fz, fpscr.rMode)
233 '''
234
203 singleIntConvCode = vfp64EnabledCheckCode + '''
204 FPSCR fpscr = (FPSCR) FpscrExc;
205 uint32_t cOp1 = AA64FpOp1P0_uw;
206 uint32_t cDest = %(op)s;
207 AA64FpDestP0_uw = cDest;
208 AA64FpDestP1_uw = 0;
209 AA64FpDestP2_uw = 0;
210 AA64FpDestP3_uw = 0;
211 FpscrExc = fpscr;
212 '''
213
214 singleIntConvCode2 = vfp64EnabledCheckCode + '''
215 FPSCR fpscr = (FPSCR) FpscrExc;
216 uint32_t cOp1 = AA64FpOp1P0_uw;
217 uint32_t cOp2 = AA64FpOp2P0_uw;
218 uint32_t cDest = %(op)s;
219 AA64FpDestP0_uw = cDest;
220 AA64FpDestP1_uw = 0;
221 AA64FpDestP2_uw = 0;
222 AA64FpDestP3_uw = 0;
223 FpscrExc = fpscr;
224 '''
225
226 singleBinOp = "binaryOp(fpscr, AA64FpOp1P0, AA64FpOp2P0," + \
227 "%(func)s, fpscr.fz, fpscr.dn, fpscr.rMode)"
228 singleUnaryOp = "unaryOp(fpscr, AA64FpOp1P0, %(func)s, fpscr.fz, fpscr.rMode)"
229
230 doubleIntConvCode = vfp64EnabledCheckCode + '''
231 FPSCR fpscr = (FPSCR) FpscrExc;
232 uint64_t cOp1 = ((uint64_t) AA64FpOp1P1_uw) << 32 | AA64FpOp1P0_uw;
233 uint64_t cDest = %(op)s;
234 AA64FpDestP0_uw = cDest & 0xFFFFFFFF;
235 AA64FpDestP1_uw = cDest >> 32;
236 AA64FpDestP2_uw = 0;
237 AA64FpDestP3_uw = 0;
238 FpscrExc = fpscr;
239 '''
240
241 doubleIntConvCode2 = vfp64EnabledCheckCode + '''
242 FPSCR fpscr = (FPSCR) FpscrExc;
243 uint64_t cOp1 = ((uint64_t) AA64FpOp1P1_uw) << 32 | AA64FpOp1P0_uw;
244 uint64_t cOp2 = ((uint64_t) AA64FpOp2P1_uw) << 32 | AA64FpOp2P0_uw;
245 uint64_t cDest = %(op)s;
246 AA64FpDestP0_uw = cDest & 0xFFFFFFFF;
247 AA64FpDestP1_uw = cDest >> 32;
248 AA64FpDestP2_uw = 0;
249 AA64FpDestP3_uw = 0;
250 FpscrExc = fpscr;
251 '''
252
253 doubleBinOp = '''
254 binaryOp(fpscr, dbl(AA64FpOp1P0_uw, AA64FpOp1P1_uw),
255 dbl(AA64FpOp2P0_uw, AA64FpOp2P1_uw),
256 %(func)s, fpscr.fz, fpscr.dn, fpscr.rMode);
257 '''
258 doubleUnaryOp = '''
259 unaryOp(fpscr, dbl(AA64FpOp1P0_uw, AA64FpOp1P1_uw), %(func)s,
260 fpscr.fz, fpscr.rMode)
261 '''
262
235 def buildTernaryFpOp(name, opClass, sOp, dOp):
263 def buildTernaryFpOp(name, opClass, hOp, sOp, dOp):
236 global header_output, decoder_output, exec_output
264 global header_output, decoder_output, exec_output
237 for isDouble in True, False:
265 for suffix in "D", "S", "H":
238 code = vfp64EnabledCheckCode + '''
239 FPSCR fpscr = (FPSCR) FpscrExc;
240 '''
266 code = vfp64EnabledCheckCode + '''
267 FPSCR fpscr = (FPSCR) FpscrExc;
268 '''
241 if isDouble:
269 if suffix == "H":
242 code += '''
270 code += '''
243 uint64_t cOp1 = AA64FpOp1P0_uw | (uint64_t)AA64FpOp1P1_uw << 32;
244 uint64_t cOp2 = AA64FpOp2P0_uw | (uint64_t)AA64FpOp2P1_uw << 32;
245 uint64_t cOp3 = AA64FpOp3P0_uw | (uint64_t)AA64FpOp3P1_uw << 32;
246 uint64_t cDest;
247 ''' "cDest = " + dOp + ";" + '''
271 uint16_t cOp1 = AA64FpOp1P0_uw;
272 uint16_t cOp2 = AA64FpOp2P0_uw;
273 uint16_t cOp3 = AA64FpOp3P0_uw;
274 uint16_t cDest;
275 ''' "cDest = " + hOp + ";" + '''
248 AA64FpDestP0_uw = cDest;
276 AA64FpDestP0_uw = cDest;
249 AA64FpDestP1_uw = cDest >> 32;
277 AA64FpDestP1_uw = 0;
250 '''
278 '''
251 else:
279 elif suffix == "S":
252 code += '''
253 uint32_t cOp1 = AA64FpOp1P0_uw;
254 uint32_t cOp2 = AA64FpOp2P0_uw;
255 uint32_t cOp3 = AA64FpOp3P0_uw;
256 uint32_t cDest;
257 ''' "cDest = " + sOp + ";" + '''
258 AA64FpDestP0_uw = cDest;
259 AA64FpDestP1_uw = 0;
260 '''
280 code += '''
281 uint32_t cOp1 = AA64FpOp1P0_uw;
282 uint32_t cOp2 = AA64FpOp2P0_uw;
283 uint32_t cOp3 = AA64FpOp3P0_uw;
284 uint32_t cDest;
285 ''' "cDest = " + sOp + ";" + '''
286 AA64FpDestP0_uw = cDest;
287 AA64FpDestP1_uw = 0;
288 '''
289 elif suffix == "D":
290 code += '''
291 uint64_t cOp1 = AA64FpOp1P0_uw | (uint64_t)AA64FpOp1P1_uw << 32;
292 uint64_t cOp2 = AA64FpOp2P0_uw | (uint64_t)AA64FpOp2P1_uw << 32;
293 uint64_t cOp3 = AA64FpOp3P0_uw | (uint64_t)AA64FpOp3P1_uw << 32;
294 uint64_t cDest;
295 ''' "cDest = " + dOp + ";" + '''
296 AA64FpDestP0_uw = cDest;
297 AA64FpDestP1_uw = cDest >> 32;
298 '''
261 code += '''
262 AA64FpDestP2_uw = 0;
263 AA64FpDestP3_uw = 0;
264 FpscrExc = fpscr;
265 '''
266
299 code += '''
300 AA64FpDestP2_uw = 0;
301 AA64FpDestP3_uw = 0;
302 FpscrExc = fpscr;
303 '''
304
267 iop = InstObjParams(name.lower(), name + ("D" if isDouble else "S"),
305 iop = InstObjParams(name.lower(), name + suffix,
268 "FpRegRegRegRegOp",
269 { "code": code, "op_class": opClass }, [])
270
271 header_output += AA64FpRegRegRegRegOpDeclare.subst(iop)
272 decoder_output += AA64FpRegRegRegRegOpConstructor.subst(iop)
273 exec_output += BasicExecute.subst(iop)
274
275 buildTernaryFpOp("FMAdd", "FloatMultAccOp",
306 "FpRegRegRegRegOp",
307 { "code": code, "op_class": opClass }, [])
308
309 header_output += AA64FpRegRegRegRegOpDeclare.subst(iop)
310 decoder_output += AA64FpRegRegRegRegOpConstructor.subst(iop)
311 exec_output += BasicExecute.subst(iop)
312
313 buildTernaryFpOp("FMAdd", "FloatMultAccOp",
314 "fplibMulAdd<uint16_t>(cOp3, cOp1, cOp2, fpscr)",
276 "fplibMulAdd<uint32_t>(cOp3, cOp1, cOp2, fpscr)",
277 "fplibMulAdd<uint64_t>(cOp3, cOp1, cOp2, fpscr)" )
278 buildTernaryFpOp("FMSub", "FloatMultAccOp",
315 "fplibMulAdd<uint32_t>(cOp3, cOp1, cOp2, fpscr)",
316 "fplibMulAdd<uint64_t>(cOp3, cOp1, cOp2, fpscr)" )
317 buildTernaryFpOp("FMSub", "FloatMultAccOp",
279 "fplibMulAdd<uint32_t>(cOp3, fplibNeg<uint32_t>(cOp1), cOp2, fpscr)",
280 "fplibMulAdd<uint64_t>(cOp3, fplibNeg<uint64_t>(cOp1), cOp2, fpscr)" )
318 "fplibMulAdd<uint16_t>(cOp3, fplibNeg<uint32_t>(cOp1), cOp2, fpscr)",
319 "fplibMulAdd<uint32_t>(cOp3, fplibNeg<uint32_t>(cOp1), cOp2, fpscr)",
320 "fplibMulAdd<uint64_t>(cOp3, fplibNeg<uint64_t>(cOp1), cOp2, fpscr)" )
281 buildTernaryFpOp("FNMAdd", "FloatMultAccOp",
321 buildTernaryFpOp("FNMAdd", "FloatMultAccOp",
282 "fplibMulAdd<uint32_t>(fplibNeg<uint32_t>(cOp3), fplibNeg<uint32_t>(cOp1), cOp2, fpscr)",
283 "fplibMulAdd<uint64_t>(fplibNeg<uint64_t>(cOp3), fplibNeg<uint64_t>(cOp1), cOp2, fpscr)" )
322 "fplibMulAdd<uint16_t>(fplibNeg<uint16_t>(cOp3), " +
323 "fplibNeg<uint16_t>(cOp1), cOp2, fpscr)",
324 "fplibMulAdd<uint32_t>(fplibNeg<uint32_t>(cOp3), " +
325 "fplibNeg<uint32_t>(cOp1), cOp2, fpscr)",
326 "fplibMulAdd<uint64_t>(fplibNeg<uint64_t>(cOp3), " +
327 "fplibNeg<uint64_t>(cOp1), cOp2, fpscr)" )
284 buildTernaryFpOp("FNMSub", "FloatMultAccOp",
328 buildTernaryFpOp("FNMSub", "FloatMultAccOp",
285 "fplibMulAdd<uint32_t>(fplibNeg<uint32_t>(cOp3), cOp1, cOp2, fpscr)",
286 "fplibMulAdd<uint64_t>(fplibNeg<uint64_t>(cOp3), cOp1, cOp2, fpscr)" )
329 "fplibMulAdd<uint16_t>(fplibNeg<uint32_t>(cOp3), cOp1, cOp2, fpscr)",
330 "fplibMulAdd<uint32_t>(fplibNeg<uint32_t>(cOp3), cOp1, cOp2, fpscr)",
331 "fplibMulAdd<uint64_t>(fplibNeg<uint64_t>(cOp3), cOp1, cOp2, fpscr)" )
287
332
288 def buildBinFpOp(name, Name, base, opClass, singleOp, doubleOp):
333 def buildBinFpOp(name, Name, base, opClass, halfOp, singleOp, doubleOp):
289 global header_output, decoder_output, exec_output
290
334 global header_output, decoder_output, exec_output
335
336 code = halfIntConvCode2 % { "op": halfOp }
337 hIop = InstObjParams(name, Name + "H", base,
338 { "code": code,
339 "op_class": opClass }, [])
340
291 code = singleIntConvCode2 % { "op": singleOp }
292 sIop = InstObjParams(name, Name + "S", base,
293 { "code": code,
294 "op_class": opClass }, [])
295
296 code = doubleIntConvCode2 % { "op": doubleOp }
297 dIop = InstObjParams(name, Name + "D", base,
298 { "code": code,
299 "op_class": opClass }, [])
300
301 declareTempl = eval( base + "Declare");
302 constructorTempl = eval("AA64" + base + "Constructor");
303
341 code = singleIntConvCode2 % { "op": singleOp }
342 sIop = InstObjParams(name, Name + "S", base,
343 { "code": code,
344 "op_class": opClass }, [])
345
346 code = doubleIntConvCode2 % { "op": doubleOp }
347 dIop = InstObjParams(name, Name + "D", base,
348 { "code": code,
349 "op_class": opClass }, [])
350
351 declareTempl = eval( base + "Declare");
352 constructorTempl = eval("AA64" + base + "Constructor");
353
304 for iop in sIop, dIop:
354 for iop in hIop, sIop, dIop:
305 header_output += declareTempl.subst(iop)
306 decoder_output += constructorTempl.subst(iop)
307 exec_output += BasicExecute.subst(iop)
308
309 buildBinFpOp("fadd", "FAdd", "FpRegRegRegOp", "FloatAddOp",
355 header_output += declareTempl.subst(iop)
356 decoder_output += constructorTempl.subst(iop)
357 exec_output += BasicExecute.subst(iop)
358
359 buildBinFpOp("fadd", "FAdd", "FpRegRegRegOp", "FloatAddOp",
360 "fplibAdd<uint16_t>(cOp1, cOp2, fpscr)",
310 "fplibAdd<uint32_t>(cOp1, cOp2, fpscr)",
311 "fplibAdd<uint64_t>(cOp1, cOp2, fpscr)")
312 buildBinFpOp("fsub", "FSub", "FpRegRegRegOp", "FloatAddOp",
361 "fplibAdd<uint32_t>(cOp1, cOp2, fpscr)",
362 "fplibAdd<uint64_t>(cOp1, cOp2, fpscr)")
363 buildBinFpOp("fsub", "FSub", "FpRegRegRegOp", "FloatAddOp",
364 "fplibSub<uint16_t>(cOp1, cOp2, fpscr)",
313 "fplibSub<uint32_t>(cOp1, cOp2, fpscr)",
314 "fplibSub<uint64_t>(cOp1, cOp2, fpscr)")
315 buildBinFpOp("fdiv", "FDiv", "FpRegRegRegOp", "FloatDivOp",
365 "fplibSub<uint32_t>(cOp1, cOp2, fpscr)",
366 "fplibSub<uint64_t>(cOp1, cOp2, fpscr)")
367 buildBinFpOp("fdiv", "FDiv", "FpRegRegRegOp", "FloatDivOp",
368 "fplibDiv<uint16_t>(cOp1, cOp2, fpscr)",
316 "fplibDiv<uint32_t>(cOp1, cOp2, fpscr)",
317 "fplibDiv<uint64_t>(cOp1, cOp2, fpscr)")
318 buildBinFpOp("fmul", "FMul", "FpRegRegRegOp", "FloatMultOp",
369 "fplibDiv<uint32_t>(cOp1, cOp2, fpscr)",
370 "fplibDiv<uint64_t>(cOp1, cOp2, fpscr)")
371 buildBinFpOp("fmul", "FMul", "FpRegRegRegOp", "FloatMultOp",
372 "fplibMul<uint16_t>(cOp1, cOp2, fpscr)",
319 "fplibMul<uint32_t>(cOp1, cOp2, fpscr)",
320 "fplibMul<uint64_t>(cOp1, cOp2, fpscr)")
321 buildBinFpOp("fnmul", "FNMul", "FpRegRegRegOp", "FloatMultOp",
373 "fplibMul<uint32_t>(cOp1, cOp2, fpscr)",
374 "fplibMul<uint64_t>(cOp1, cOp2, fpscr)")
375 buildBinFpOp("fnmul", "FNMul", "FpRegRegRegOp", "FloatMultOp",
376 "fplibNeg<uint16_t>(fplibMul<uint32_t>(cOp1, cOp2, fpscr))",
322 "fplibNeg<uint32_t>(fplibMul<uint32_t>(cOp1, cOp2, fpscr))",
323 "fplibNeg<uint64_t>(fplibMul<uint64_t>(cOp1, cOp2, fpscr))")
324 buildBinFpOp("fmin", "FMin", "FpRegRegRegOp", "FloatCmpOp",
377 "fplibNeg<uint32_t>(fplibMul<uint32_t>(cOp1, cOp2, fpscr))",
378 "fplibNeg<uint64_t>(fplibMul<uint64_t>(cOp1, cOp2, fpscr))")
379 buildBinFpOp("fmin", "FMin", "FpRegRegRegOp", "FloatCmpOp",
380 "fplibMin<uint16_t>(cOp1, cOp2, fpscr)",
325 "fplibMin<uint32_t>(cOp1, cOp2, fpscr)",
326 "fplibMin<uint64_t>(cOp1, cOp2, fpscr)")
327 buildBinFpOp("fmax", "FMax", "FpRegRegRegOp", "FloatCmpOp",
381 "fplibMin<uint32_t>(cOp1, cOp2, fpscr)",
382 "fplibMin<uint64_t>(cOp1, cOp2, fpscr)")
383 buildBinFpOp("fmax", "FMax", "FpRegRegRegOp", "FloatCmpOp",
384 "fplibMax<uint16_t>(cOp1, cOp2, fpscr)",
328 "fplibMax<uint32_t>(cOp1, cOp2, fpscr)",
329 "fplibMax<uint64_t>(cOp1, cOp2, fpscr)")
330 buildBinFpOp("fminnm", "FMinNM", "FpRegRegRegOp", "FloatCmpOp",
385 "fplibMax<uint32_t>(cOp1, cOp2, fpscr)",
386 "fplibMax<uint64_t>(cOp1, cOp2, fpscr)")
387 buildBinFpOp("fminnm", "FMinNM", "FpRegRegRegOp", "FloatCmpOp",
388 "fplibMinNum<uint16_t>(cOp1, cOp2, fpscr)",
331 "fplibMinNum<uint32_t>(cOp1, cOp2, fpscr)",
332 "fplibMinNum<uint64_t>(cOp1, cOp2, fpscr)")
333 buildBinFpOp("fmaxnm", "FMaxNM", "FpRegRegRegOp", "FloatCmpOp",
389 "fplibMinNum<uint32_t>(cOp1, cOp2, fpscr)",
390 "fplibMinNum<uint64_t>(cOp1, cOp2, fpscr)")
391 buildBinFpOp("fmaxnm", "FMaxNM", "FpRegRegRegOp", "FloatCmpOp",
392 "fplibMaxNum<uint16_t>(cOp1, cOp2, fpscr)",
334 "fplibMaxNum<uint32_t>(cOp1, cOp2, fpscr)",
335 "fplibMaxNum<uint64_t>(cOp1, cOp2, fpscr)")
336
393 "fplibMaxNum<uint32_t>(cOp1, cOp2, fpscr)",
394 "fplibMaxNum<uint64_t>(cOp1, cOp2, fpscr)")
395
337 def buildUnaryFpOp(name, Name, base, opClass, singleOp, doubleOp = None):
396 def buildUnaryFpOp(name, Name, base, opClass,
397 halfOp, singleOp, doubleOp = None):
338 if doubleOp is None:
339 doubleOp = singleOp
340 global header_output, decoder_output, exec_output
341
398 if doubleOp is None:
399 doubleOp = singleOp
400 global header_output, decoder_output, exec_output
401
402 code = halfIntConvCode % { "op": halfOp }
403 hIop = InstObjParams(name, Name + "H", base,
404 { "code": code,
405 "op_class": opClass }, [])
342 code = singleIntConvCode % { "op": singleOp }
343 sIop = InstObjParams(name, Name + "S", base,
344 { "code": code,
345 "op_class": opClass }, [])
346 code = doubleIntConvCode % { "op": doubleOp }
347 dIop = InstObjParams(name, Name + "D", base,
348 { "code": code,
349 "op_class": opClass }, [])
350
351 declareTempl = eval( base + "Declare");
352 constructorTempl = eval("AA64" + base + "Constructor");
353
406 code = singleIntConvCode % { "op": singleOp }
407 sIop = InstObjParams(name, Name + "S", base,
408 { "code": code,
409 "op_class": opClass }, [])
410 code = doubleIntConvCode % { "op": doubleOp }
411 dIop = InstObjParams(name, Name + "D", base,
412 { "code": code,
413 "op_class": opClass }, [])
414
415 declareTempl = eval( base + "Declare");
416 constructorTempl = eval("AA64" + base + "Constructor");
417
354 for iop in sIop, dIop:
418 for iop in hIop, sIop, dIop:
355 header_output += declareTempl.subst(iop)
356 decoder_output += constructorTempl.subst(iop)
357 exec_output += BasicExecute.subst(iop)
358
359 buildUnaryFpOp("fsqrt", "FSqrt", "FpRegRegOp", "FloatSqrtOp",
419 header_output += declareTempl.subst(iop)
420 decoder_output += constructorTempl.subst(iop)
421 exec_output += BasicExecute.subst(iop)
422
423 buildUnaryFpOp("fsqrt", "FSqrt", "FpRegRegOp", "FloatSqrtOp",
360 "fplibSqrt<uint32_t>(cOp1, fpscr)", "fplibSqrt<uint64_t>(cOp1, fpscr)")
424 "fplibSqrt<uint16_t>(cOp1, fpscr)",
425 "fplibSqrt<uint32_t>(cOp1, fpscr)",
426 "fplibSqrt<uint64_t>(cOp1, fpscr)")
361
427
362 def buildSimpleUnaryFpOp(name, Name, base, opClass, singleOp,
428 def buildSimpleUnaryFpOp(name, Name, base, opClass, halfOp, singleOp,
363 doubleOp = None, isIntConv = True):
364 if doubleOp is None:
365 doubleOp = singleOp
366 global header_output, decoder_output, exec_output
367
368 if isIntConv:
429 doubleOp = None, isIntConv = True):
430 if doubleOp is None:
431 doubleOp = singleOp
432 global header_output, decoder_output, exec_output
433
434 if isIntConv:
435 hCode = halfIntConvCode
369 sCode = singleIntConvCode
370 dCode = doubleIntConvCode
371 else:
436 sCode = singleIntConvCode
437 dCode = doubleIntConvCode
438 else:
439 hCode = halfCode
372 sCode = singleCode
373 dCode = doubleCode
374
440 sCode = singleCode
441 dCode = doubleCode
442
375 for code, op, suffix in [[sCode, singleOp, "S"],
443 for code, op, suffix in [[hCode, halfOp, "H"],
444 [sCode, singleOp, "S"],
376 [dCode, doubleOp, "D"]]:
377 iop = InstObjParams(name, Name + suffix, base,
378 { "code": code % { "op": op },
379 "op_class": opClass }, [])
380
381 declareTempl = eval( base + "Declare");
382 constructorTempl = eval("AA64" + base + "Constructor");
383
384 header_output += declareTempl.subst(iop)
385 decoder_output += constructorTempl.subst(iop)
386 exec_output += BasicExecute.subst(iop)
387
388 buildSimpleUnaryFpOp("fneg", "FNeg", "FpRegRegOp", "FloatMiscOp",
445 [dCode, doubleOp, "D"]]:
446 iop = InstObjParams(name, Name + suffix, base,
447 { "code": code % { "op": op },
448 "op_class": opClass }, [])
449
450 declareTempl = eval( base + "Declare");
451 constructorTempl = eval("AA64" + base + "Constructor");
452
453 header_output += declareTempl.subst(iop)
454 decoder_output += constructorTempl.subst(iop)
455 exec_output += BasicExecute.subst(iop)
456
457 buildSimpleUnaryFpOp("fneg", "FNeg", "FpRegRegOp", "FloatMiscOp",
389 "fplibNeg<uint32_t>(cOp1)", "fplibNeg<uint64_t>(cOp1)")
458 "fplibNeg<uint16_t>(cOp1)",
459 "fplibNeg<uint32_t>(cOp1)",
460 "fplibNeg<uint64_t>(cOp1)")
390 buildSimpleUnaryFpOp("fabs", "FAbs", "FpRegRegOp", "FloatMiscOp",
461 buildSimpleUnaryFpOp("fabs", "FAbs", "FpRegRegOp", "FloatMiscOp",
391 "fplibAbs<uint32_t>(cOp1)", "fplibAbs<uint64_t>(cOp1)")
462 "fplibAbs<uint16_t>(cOp1)",
463 "fplibAbs<uint32_t>(cOp1)",
464 "fplibAbs<uint64_t>(cOp1)")
392 buildSimpleUnaryFpOp("frintn", "FRIntN", "FpRegRegOp", "FloatMiscOp",
465 buildSimpleUnaryFpOp("frintn", "FRIntN", "FpRegRegOp", "FloatMiscOp",
393 "fplibRoundInt<uint32_t>(cOp1, FPRounding_TIEEVEN, false, fpscr)",
394 "fplibRoundInt<uint64_t>(cOp1, FPRounding_TIEEVEN, false, fpscr)")
466 "fplibRoundInt<uint16_t>(cOp1, FPRounding_TIEEVEN, false, fpscr)",
467 "fplibRoundInt<uint32_t>(cOp1, FPRounding_TIEEVEN, false, fpscr)",
468 "fplibRoundInt<uint64_t>(cOp1, FPRounding_TIEEVEN, false, fpscr)")
395 buildSimpleUnaryFpOp("frintp", "FRIntP", "FpRegRegOp", "FloatMiscOp",
469 buildSimpleUnaryFpOp("frintp", "FRIntP", "FpRegRegOp", "FloatMiscOp",
396 "fplibRoundInt<uint32_t>(cOp1, FPRounding_POSINF, false, fpscr)",
397 "fplibRoundInt<uint64_t>(cOp1, FPRounding_POSINF, false, fpscr)")
470 "fplibRoundInt<uint16_t>(cOp1, FPRounding_POSINF, false, fpscr)",
471 "fplibRoundInt<uint32_t>(cOp1, FPRounding_POSINF, false, fpscr)",
472 "fplibRoundInt<uint64_t>(cOp1, FPRounding_POSINF, false, fpscr)")
398 buildSimpleUnaryFpOp("frintm", "FRIntM", "FpRegRegOp", "FloatMiscOp",
473 buildSimpleUnaryFpOp("frintm", "FRIntM", "FpRegRegOp", "FloatMiscOp",
399 "fplibRoundInt<uint32_t>(cOp1, FPRounding_NEGINF, false, fpscr)",
400 "fplibRoundInt<uint64_t>(cOp1, FPRounding_NEGINF, false, fpscr)")
474 "fplibRoundInt<uint16_t>(cOp1, FPRounding_NEGINF, false, fpscr)",
475 "fplibRoundInt<uint32_t>(cOp1, FPRounding_NEGINF, false, fpscr)",
476 "fplibRoundInt<uint64_t>(cOp1, FPRounding_NEGINF, false, fpscr)")
401 buildSimpleUnaryFpOp("frintz", "FRIntZ", "FpRegRegOp", "FloatMiscOp",
477 buildSimpleUnaryFpOp("frintz", "FRIntZ", "FpRegRegOp", "FloatMiscOp",
402 "fplibRoundInt<uint32_t>(cOp1, FPRounding_ZERO, false, fpscr)",
403 "fplibRoundInt<uint64_t>(cOp1, FPRounding_ZERO, false, fpscr)")
478 "fplibRoundInt<uint16_t>(cOp1, FPRounding_ZERO, false, fpscr)",
479 "fplibRoundInt<uint32_t>(cOp1, FPRounding_ZERO, false, fpscr)",
480 "fplibRoundInt<uint64_t>(cOp1, FPRounding_ZERO, false, fpscr)")
404 buildSimpleUnaryFpOp("frinta", "FRIntA", "FpRegRegOp", "FloatMiscOp",
481 buildSimpleUnaryFpOp("frinta", "FRIntA", "FpRegRegOp", "FloatMiscOp",
405 "fplibRoundInt<uint32_t>(cOp1, FPRounding_TIEAWAY, false, fpscr)",
406 "fplibRoundInt<uint64_t>(cOp1, FPRounding_TIEAWAY, false, fpscr)")
482 "fplibRoundInt<uint16_t>(cOp1, FPRounding_TIEAWAY, false, fpscr)",
483 "fplibRoundInt<uint32_t>(cOp1, FPRounding_TIEAWAY, false, fpscr)",
484 "fplibRoundInt<uint64_t>(cOp1, FPRounding_TIEAWAY, false, fpscr)")
407 buildSimpleUnaryFpOp("frinti", "FRIntI", "FpRegRegOp", "FloatMiscOp",
485 buildSimpleUnaryFpOp("frinti", "FRIntI", "FpRegRegOp", "FloatMiscOp",
408 "fplibRoundInt<uint32_t>(cOp1, FPCRRounding(fpscr), false, fpscr)",
409 "fplibRoundInt<uint64_t>(cOp1, FPCRRounding(fpscr), false, fpscr)")
486 "fplibRoundInt<uint16_t>(cOp1, FPCRRounding(fpscr), false, fpscr)",
487 "fplibRoundInt<uint32_t>(cOp1, FPCRRounding(fpscr), false, fpscr)",
488 "fplibRoundInt<uint64_t>(cOp1, FPCRRounding(fpscr), false, fpscr)")
410 buildSimpleUnaryFpOp("frintx", "FRIntX", "FpRegRegOp", "FloatMiscOp",
489 buildSimpleUnaryFpOp("frintx", "FRIntX", "FpRegRegOp", "FloatMiscOp",
411 "fplibRoundInt<uint32_t>(cOp1, FPCRRounding(fpscr), true, fpscr)",
412 "fplibRoundInt<uint64_t>(cOp1, FPCRRounding(fpscr), true, fpscr)")
490 "fplibRoundInt<uint16_t>(cOp1, FPCRRounding(fpscr), true, fpscr)",
491 "fplibRoundInt<uint32_t>(cOp1, FPCRRounding(fpscr), true, fpscr)",
492 "fplibRoundInt<uint64_t>(cOp1, FPCRRounding(fpscr), true, fpscr)")
413}};
414
415let {{
416
417 header_output = ""
418 decoder_output = ""
419 exec_output = ""
420
421 # Creates the integer to floating point instructions, including variants for
422 # signed/unsigned, float/double, etc
423 for regL, regOpL, width in [["W", "w", 32],
424 ["X", "d", 64]]:
425 for isDouble in True, False:
426 for us, usCode in [["U", "uint%d_t cSrc = %sOp1_u%s;" %(width, regL, regOpL)],
427 ["S", "int%d_t cSrc = %sOp1_u%s;" %(width, regL, regOpL)]]:
428 fcvtIntFpDCode = vfp64EnabledCheckCode + '''
429 FPSCR fpscr = (FPSCR) FpscrExc;
430 %s
431 ''' %(usCode)
432
433 if isDouble:
434 fcvtIntFpDCode += '''
435 uint64_t cDest = fplibFixedToFP<uint64_t>(cSrc, 0,
436 %s, FPCRRounding(fpscr), fpscr);
437 AA64FpDestP0_uw = cDest;
438 AA64FpDestP1_uw = cDest >> 32;
439 ''' % ("true" if us == "U" else "false")
440 else:
441 fcvtIntFpDCode += '''
442 uint32_t cDest = fplibFixedToFP<uint32_t>(cSrc, 0,
443 %s, FPCRRounding(fpscr), fpscr);
444 AA64FpDestP0_uw = cDest;
445 AA64FpDestP1_uw = 0;
446 ''' % ("true" if us == "U" else "false")
447 fcvtIntFpDCode += '''
448 AA64FpDestP2_uw = 0;
449 AA64FpDestP3_uw = 0;
450 FpscrExc = fpscr;
451 '''
452
453 instName = "Fcvt%s%sIntFp%s" %(regL, us, "D" if isDouble else "S")
454 mnem = "%scvtf" %(us.lower())
455 fcvtIntFpDIop = InstObjParams(mnem, instName, "FpRegRegOp",
456 { "code": fcvtIntFpDCode,
457 "op_class": "FloatCvtOp" }, [])
458 header_output += FpRegRegOpDeclare.subst(fcvtIntFpDIop);
459 decoder_output += AA64FpRegRegOpConstructor.subst(fcvtIntFpDIop);
460 exec_output += BasicExecute.subst(fcvtIntFpDIop);
461
462 # Generates the floating point to integer conversion instructions in various
463 # variants, eg signed/unsigned
464 def buildFpCvtIntOp(isDouble, isSigned, isXReg):
465 global header_output, decoder_output, exec_output
466
467 for rmode, roundingMode in [["N", "FPRounding_TIEEVEN"],
468 ["P", "FPRounding_POSINF"],
469 ["M", "FPRounding_NEGINF"],
470 ["Z", "FPRounding_ZERO"],
471 ["A", "FPRounding_TIEAWAY"]]:
472 fcvtFpIntCode = vfp64EnabledCheckCode + '''
473 FPSCR fpscr = (FPSCR) FpscrExc;'''
474 if isDouble:
475 fcvtFpIntCode += '''
476 uint64_t cOp1 = AA64FpOp1P0_uw | (uint64_t)AA64FpOp1P1_uw << 32;
477 '''
478 else:
479 fcvtFpIntCode += "uint32_t cOp1 = AA64FpOp1P0_uw;"
480
481 fcvtFpIntCode += '''
482 %sDest = fplibFPToFixed<uint%s_t, uint%s_t>(cOp1, 0, %s, %s, fpscr);
483 FpscrExc = fpscr;
484 ''' %("X" if isXReg else "W",
485 "64" if isDouble else "32",
486 "64" if isXReg else "32",
487 "false" if isSigned else "true",
488 roundingMode)
489
490 instName = "FcvtFp%sInt%s%s%s" %("S" if isSigned else "U",
491 "X" if isXReg else "W",
492 "D" if isDouble else "S", rmode)
493 mnem = "fcvt%s%s" %(rmode, "s" if isSigned else "u")
494 fcvtFpIntIop = InstObjParams(mnem, instName, "FpRegRegOp",
495 { "code": fcvtFpIntCode,
496 "op_class": "FloatCvtOp" }, [])
497 header_output += FpRegRegOpDeclare.subst(fcvtFpIntIop);
498 decoder_output += FpRegRegOpConstructor.subst(fcvtFpIntIop);
499 exec_output += BasicExecute.subst(fcvtFpIntIop);
500
501 # Now actually do the building with the different variants
502 for isDouble in True, False:
503 for isSigned in True, False:
504 for isXReg in True, False:
505 buildFpCvtIntOp(isDouble, isSigned, isXReg)
506
507 fcvtFpSFpDCode = vfp64EnabledCheckCode + '''
508 FPSCR fpscr = (FPSCR) FpscrExc;
509 uint64_t cDest = fplibConvert<uint32_t, uint64_t>(AA64FpOp1P0_uw,
510 FPCRRounding(fpscr), fpscr);
511 AA64FpDestP0_uw = cDest;
512 AA64FpDestP1_uw = cDest >> 32;
513 AA64FpDestP2_uw = 0;
514 AA64FpDestP3_uw = 0;
515 FpscrExc = fpscr;
516 '''
517 fcvtFpSFpDIop = InstObjParams("fcvt", "FCvtFpSFpD", "FpRegRegOp",
518 { "code": fcvtFpSFpDCode,
519 "op_class": "FloatCvtOp" }, [])
520 header_output += FpRegRegOpDeclare.subst(fcvtFpSFpDIop);
521 decoder_output += AA64FpRegRegOpConstructor.subst(fcvtFpSFpDIop);
522 exec_output += BasicExecute.subst(fcvtFpSFpDIop);
523
524 fcvtFpDFpSCode = vfp64EnabledCheckCode + '''
525 FPSCR fpscr = (FPSCR) FpscrExc;
526 uint64_t cOp1 = AA64FpOp1P0_uw | (uint64_t)AA64FpOp1P1_uw << 32;
527 AA64FpDestP0_uw = fplibConvert<uint64_t, uint32_t>(cOp1,
528 FPCRRounding(fpscr), fpscr);
529 AA64FpDestP1_uw = 0;
530 AA64FpDestP2_uw = 0;
531 AA64FpDestP3_uw = 0;
532 FpscrExc = fpscr;
533 '''
534 fcvtFpDFpSIop = InstObjParams("fcvt", "FcvtFpDFpS", "FpRegRegOp",
535 {"code": fcvtFpDFpSCode,
536 "op_class": "FloatCvtOp" }, [])
537 header_output += FpRegRegOpDeclare.subst(fcvtFpDFpSIop);
538 decoder_output += AA64FpRegRegOpConstructor.subst(fcvtFpDFpSIop);
539 exec_output += BasicExecute.subst(fcvtFpDFpSIop);
540
541 # Half precision to single or double precision conversion
542 for isDouble in True, False:
543 code = vfp64EnabledCheckCode + '''
544 FPSCR fpscr = (FPSCR) FpscrExc;
545 %s cDest = fplibConvert<uint16_t, uint%s_t>(AA64FpOp1P0_uw,
546 FPCRRounding(fpscr), fpscr);
547 ''' % ("uint64_t" if isDouble else "uint32_t",
548 "64" if isDouble else "32")
549 if isDouble:
550 code += '''
551 AA64FpDestP0_uw = cDest;
552 AA64FpDestP1_uw = cDest >> 32;
553 '''
554 else:
555 code += '''
556 AA64FpDestP0_uw = cDest;
557 AA64FpDestP1_uw = 0;
558 '''
559 code += '''
560 AA64FpDestP2_uw = 0;
561 AA64FpDestP3_uw = 0;
562 FpscrExc = fpscr;
563 '''
564
565 instName = "FcvtFpHFp%s" %("D" if isDouble else "S")
566 fcvtFpHFpIop = InstObjParams("fcvt", instName, "FpRegRegOp",
567 { "code": code,
568 "op_class": "FloatCvtOp" }, [])
569 header_output += FpRegRegOpDeclare.subst(fcvtFpHFpIop);
570 decoder_output += AA64FpRegRegOpConstructor.subst(fcvtFpHFpIop);
571 exec_output += BasicExecute.subst(fcvtFpHFpIop);
572
573 # single or double precision to Half precision conversion
574 for isDouble in True, False:
575 code = vfp64EnabledCheckCode + '''
576 FPSCR fpscr = (FPSCR) FpscrExc;
577 %s;
578 AA64FpDestP0_uw = fplibConvert<uint%s_t, uint16_t>(cOp1,
579 FPCRRounding(fpscr), fpscr);
580 AA64FpDestP1_uw = 0;
581 AA64FpDestP2_uw = 0;
582 AA64FpDestP3_uw = 0;
583 FpscrExc = fpscr;
584 ''' % ("uint64_t cOp1 = AA64FpOp1P0_uw | (uint64_t)AA64FpOp1P1_uw << 32"
585 if isDouble else "uint32_t cOp1 = AA64FpOp1P0_uw",
586 "64" if isDouble else "32")
587
588 instName = "FcvtFp%sFpH" %("D" if isDouble else "S")
589 fcvtFpFpHIop = InstObjParams("fcvt", instName, "FpRegRegOp",
590 { "code": code,
591 "op_class": "FloatCvtOp" }, [])
592 header_output += FpRegRegOpDeclare.subst(fcvtFpFpHIop);
593 decoder_output += AA64FpRegRegOpConstructor.subst(fcvtFpFpHIop);
594 exec_output += BasicExecute.subst(fcvtFpFpHIop);
595
596 # Build the various versions of the floating point compare instructions
597 def buildFCmpOp(isQuiet, isDouble, isImm):
598 global header_output, decoder_output, exec_output
599
600 fcmpCode = vfp64EnabledCheckCode + '''
601 FPSCR fpscr = (FPSCR) FpscrExc;
602 %s cOp1 = %s;
603 ''' % ("uint64_t" if isDouble else "uint32_t",
604 "AA64FpDestP0_uw | (uint64_t)AA64FpDestP1_uw << 32"
605 if isDouble else "AA64FpDestP0_uw")
606 if isImm:
607 fcmpCode += '''
608 %s cOp2 = imm;
609 ''' % ("uint64_t" if isDouble else "uint32_t")
610 else:
611 fcmpCode += '''
612 %s cOp2 = %s;
613 ''' % ("uint64_t" if isDouble else "uint32_t",
614 "AA64FpOp1P0_uw | (uint64_t)AA64FpOp1P1_uw << 32"
615 if isDouble else "AA64FpOp1P0_uw")
616 fcmpCode += '''
617 int cc = fplibCompare<uint%s_t>(cOp1, cOp2, %s, fpscr);
618 CondCodesNZ = cc >> 2 & 3;
619 CondCodesC = cc >> 1 & 1;
620 CondCodesV = cc & 1;
621 FpCondCodes = fpscr & FpCondCodesMask;
622 FpscrExc = fpscr;
623 ''' % ("64" if isDouble else "32", "false" if isQuiet else "true")
624
625 typeName = "Imm" if isImm else "Reg"
626 instName = "FCmp%s%s%s" %("" if isQuiet else "E", typeName,
627 "D" if isDouble else "S")
628 fcmpIop = InstObjParams("fcmp%s" %("" if isQuiet else "e"), instName,
629 "FpReg%sOp" %(typeName),
630 {"code": fcmpCode,
631 "op_class": "FloatCmpOp"}, [])
632
633 declareTemp = eval("FpReg%sOpDeclare" %(typeName));
634 constructorTemp = eval("AA64FpReg%sOpConstructor" %(typeName));
635 header_output += declareTemp.subst(fcmpIop);
636 decoder_output += constructorTemp.subst(fcmpIop);
637 exec_output += BasicExecute.subst(fcmpIop);
638
639 for isQuiet in True, False:
640 for isDouble in True, False:
641 for isImm in True, False:
642 buildFCmpOp(isQuiet, isDouble, isImm)
643
644 # Build the various versions of the conditional floating point compare
645 # instructions
646 def buildFCCmpOp(isQuiet, isDouble):
647 global header_output, decoder_output, exec_output
648
649 fccmpCode = vfp64EnabledCheckCode + '''
650 FPSCR fpscr = (FPSCR) FpscrExc;
651 if (testPredicate(CondCodesNZ, CondCodesC, CondCodesV, condCode)) {
652 %s cOp1 = %s;
653 %s cOp2 = %s;
654 int cc = fplibCompare<uint%s_t>(cOp1, cOp2, %s, fpscr);
655 CondCodesNZ = cc >> 2 & 3;
656 CondCodesC = cc >> 1 & 1;
657 CondCodesV = cc & 1;
658 } else {
659 CondCodesNZ = (defCc >> 2) & 0x3;
660 CondCodesC = (defCc >> 1) & 0x1;
661 CondCodesV = defCc & 0x1;
662 }
663 FpCondCodes = fpscr & FpCondCodesMask;
664 FpscrExc = fpscr;
665 ''' % ("uint64_t" if isDouble else "uint32_t",
666 "AA64FpOp1P0_uw | (uint64_t)AA64FpOp1P1_uw << 32"
667 if isDouble else "AA64FpOp1P0_uw",
668 "uint64_t" if isDouble else "uint32_t",
669 "AA64FpOp2P0_uw | (uint64_t)AA64FpOp2P1_uw << 32"
670 if isDouble else "AA64FpOp2P0_uw",
671 "64" if isDouble else "32", "false" if isQuiet else "true")
672
673 instName = "FCCmp%sReg%s" %("" if isQuiet else "E",
674 "D" if isDouble else "S")
675 fccmpIop = InstObjParams("fccmp%s" %("" if isQuiet else "e"),
676 instName, "FpCondCompRegOp",
677 {"code": fccmpCode,
678 "op_class": "FloatCmpOp"}, [])
679 header_output += DataXCondCompRegDeclare.subst(fccmpIop);
680 decoder_output += DataXCondCompRegConstructor.subst(fccmpIop);
681 exec_output += BasicExecute.subst(fccmpIop);
682
683 for isQuiet in True, False:
684 for isDouble in True, False:
685 buildFCCmpOp(isQuiet, isDouble)
686
687}};
688
689let {{
690
691 header_output = ""
692 decoder_output = ""
693 exec_output = ""
694
695 # Generates the variants of the floating to fixed point instructions
696 def buildFpCvtFixedOp(isSigned, isDouble, isXReg):
697 global header_output, decoder_output, exec_output
698
699 fcvtFpFixedCode = vfp64EnabledCheckCode + '''
700 FPSCR fpscr = (FPSCR) FpscrExc;
701 '''
702 if isDouble:
703 fcvtFpFixedCode += '''
704 uint64_t cOp1 = AA64FpOp1P0_uw | (uint64_t)AA64FpOp1P1_uw << 32;
705 '''
706 else:
707 fcvtFpFixedCode += "uint32_t cOp1 = AA64FpOp1P0_uw;"
708 fcvtFpFixedCode += '''
709 %sDest = fplibFPToFixed<uint%s_t, uint%s_t>(cOp1, 64 - imm, %s,
710 FPRounding_ZERO, fpscr);
711 FpscrExc = fpscr;
712 ''' %("X" if isXReg else "W",
713 "64" if isDouble else "32",
714 "64" if isXReg else "32",
715 "false" if isSigned else "true")
716
717 instName = "FcvtFp%sFixed%s%s" %("S" if isSigned else "U",
718 "D" if isDouble else "S",
719 "X" if isXReg else "W")
720 mnem = "fcvtz%s" %("s" if isSigned else "u")
721 fcvtFpFixedIop = InstObjParams(mnem, instName, "FpRegRegImmOp",
722 { "code": fcvtFpFixedCode,
723 "op_class": "FloatCvtOp" }, [])
724 header_output += FpRegRegImmOpDeclare.subst(fcvtFpFixedIop);
725 decoder_output += AA64FpRegRegImmOpConstructor.subst(fcvtFpFixedIop);
726 exec_output += BasicExecute.subst(fcvtFpFixedIop);
727
728 # Generates the variants of the fixed to floating point instructions
729 def buildFixedCvtFpOp(isSigned, isDouble, isXReg):
730 global header_output, decoder_output, exec_output
731
732 srcRegType = "X" if isXReg else "W"
733 fcvtFixedFpCode = vfp64EnabledCheckCode + '''
734 FPSCR fpscr = (FPSCR) FpscrExc;
735 %s result = fplibFixedToFP<uint%s_t>((%s%s_t)%sOp1, 64 - imm,
736 %s, FPCRRounding(fpscr), fpscr);
737 ''' %("uint64_t" if isDouble else "uint32_t",
738 "64" if isDouble else "32",
739 "int" if isSigned else "uint", "64" if isXReg else "32",
740 srcRegType,
741 "false" if isSigned else "true")
742 if isDouble:
743 fcvtFixedFpCode += '''
744 AA64FpDestP0_uw = result;
745 AA64FpDestP1_uw = result >> 32;
746 '''
747 else:
748 fcvtFixedFpCode += '''
749 AA64FpDestP0_uw = result;
750 AA64FpDestP1_uw = 0;
751 '''
752 fcvtFixedFpCode += '''
753 AA64FpDestP2_uw = 0;
754 AA64FpDestP3_uw = 0;
755 FpscrExc = fpscr;
756 '''
757
758 instName = "Fcvt%sFixedFp%s%s" %("S" if isSigned else "U",
759 "D" if isDouble else "S",
760 srcRegType)
761 mnem = "%scvtf" %("s" if isSigned else "u")
762 fcvtFixedFpIop = InstObjParams(mnem, instName, "FpRegRegImmOp",
763 { "code": fcvtFixedFpCode,
764 "op_class": "FloatCvtOp" }, [])
765 header_output += FpRegRegImmOpDeclare.subst(fcvtFixedFpIop);
766 decoder_output += FpRegRegImmOpConstructor.subst(fcvtFixedFpIop);
767 exec_output += BasicExecute.subst(fcvtFixedFpIop);
768
769 # loop over the variants building the instructions for each
770 for isXReg in True, False:
771 for isDouble in True, False:
772 for isSigned in True, False:
773 buildFpCvtFixedOp(isSigned, isDouble, isXReg)
774 buildFixedCvtFpOp(isSigned, isDouble, isXReg)
775}};
776
777let {{
778
779 header_output = ""
780 decoder_output = ""
781 exec_output = ""
782
783 for isDouble in True, False:
784 code = '''
785 if (testPredicate(CondCodesNZ, CondCodesC, CondCodesV, condCode)) {
786 AA64FpDestP0_uw = AA64FpOp1P0_uw;
787 '''
788 if isDouble:
789 code += '''
790 AA64FpDestP1_uw = AA64FpOp1P1_uw;
791 } else {
792 AA64FpDestP0_uw = AA64FpOp2P0_uw;
793 AA64FpDestP1_uw = AA64FpOp2P1_uw;
794 }
795 '''
796 else:
797 code += '''
798 } else {
799 AA64FpDestP0_uw = AA64FpOp2P0_uw;
800 }
801 AA64FpDestP1_uw = 0;
802 '''
803 code += '''
804 AA64FpDestP2_uw = 0;
805 AA64FpDestP3_uw = 0;
806 '''
807
808 iop = InstObjParams("fcsel", "FCSel%s" %("D" if isDouble else "S"),
809 "FpCondSelOp", { "code": code,
810 "op_class": "FloatCvtOp" })
811 header_output += DataXCondSelDeclare.subst(iop)
812 decoder_output += DataXCondSelConstructor.subst(iop)
813 exec_output += BasicExecute.subst(iop)
814}};
493}};
494
495let {{
496
497 header_output = ""
498 decoder_output = ""
499 exec_output = ""
500
501 # Creates the integer to floating point instructions, including variants for
502 # signed/unsigned, float/double, etc
503 for regL, regOpL, width in [["W", "w", 32],
504 ["X", "d", 64]]:
505 for isDouble in True, False:
506 for us, usCode in [["U", "uint%d_t cSrc = %sOp1_u%s;" %(width, regL, regOpL)],
507 ["S", "int%d_t cSrc = %sOp1_u%s;" %(width, regL, regOpL)]]:
508 fcvtIntFpDCode = vfp64EnabledCheckCode + '''
509 FPSCR fpscr = (FPSCR) FpscrExc;
510 %s
511 ''' %(usCode)
512
513 if isDouble:
514 fcvtIntFpDCode += '''
515 uint64_t cDest = fplibFixedToFP<uint64_t>(cSrc, 0,
516 %s, FPCRRounding(fpscr), fpscr);
517 AA64FpDestP0_uw = cDest;
518 AA64FpDestP1_uw = cDest >> 32;
519 ''' % ("true" if us == "U" else "false")
520 else:
521 fcvtIntFpDCode += '''
522 uint32_t cDest = fplibFixedToFP<uint32_t>(cSrc, 0,
523 %s, FPCRRounding(fpscr), fpscr);
524 AA64FpDestP0_uw = cDest;
525 AA64FpDestP1_uw = 0;
526 ''' % ("true" if us == "U" else "false")
527 fcvtIntFpDCode += '''
528 AA64FpDestP2_uw = 0;
529 AA64FpDestP3_uw = 0;
530 FpscrExc = fpscr;
531 '''
532
533 instName = "Fcvt%s%sIntFp%s" %(regL, us, "D" if isDouble else "S")
534 mnem = "%scvtf" %(us.lower())
535 fcvtIntFpDIop = InstObjParams(mnem, instName, "FpRegRegOp",
536 { "code": fcvtIntFpDCode,
537 "op_class": "FloatCvtOp" }, [])
538 header_output += FpRegRegOpDeclare.subst(fcvtIntFpDIop);
539 decoder_output += AA64FpRegRegOpConstructor.subst(fcvtIntFpDIop);
540 exec_output += BasicExecute.subst(fcvtIntFpDIop);
541
542 # Generates the floating point to integer conversion instructions in various
543 # variants, eg signed/unsigned
544 def buildFpCvtIntOp(isDouble, isSigned, isXReg):
545 global header_output, decoder_output, exec_output
546
547 for rmode, roundingMode in [["N", "FPRounding_TIEEVEN"],
548 ["P", "FPRounding_POSINF"],
549 ["M", "FPRounding_NEGINF"],
550 ["Z", "FPRounding_ZERO"],
551 ["A", "FPRounding_TIEAWAY"]]:
552 fcvtFpIntCode = vfp64EnabledCheckCode + '''
553 FPSCR fpscr = (FPSCR) FpscrExc;'''
554 if isDouble:
555 fcvtFpIntCode += '''
556 uint64_t cOp1 = AA64FpOp1P0_uw | (uint64_t)AA64FpOp1P1_uw << 32;
557 '''
558 else:
559 fcvtFpIntCode += "uint32_t cOp1 = AA64FpOp1P0_uw;"
560
561 fcvtFpIntCode += '''
562 %sDest = fplibFPToFixed<uint%s_t, uint%s_t>(cOp1, 0, %s, %s, fpscr);
563 FpscrExc = fpscr;
564 ''' %("X" if isXReg else "W",
565 "64" if isDouble else "32",
566 "64" if isXReg else "32",
567 "false" if isSigned else "true",
568 roundingMode)
569
570 instName = "FcvtFp%sInt%s%s%s" %("S" if isSigned else "U",
571 "X" if isXReg else "W",
572 "D" if isDouble else "S", rmode)
573 mnem = "fcvt%s%s" %(rmode, "s" if isSigned else "u")
574 fcvtFpIntIop = InstObjParams(mnem, instName, "FpRegRegOp",
575 { "code": fcvtFpIntCode,
576 "op_class": "FloatCvtOp" }, [])
577 header_output += FpRegRegOpDeclare.subst(fcvtFpIntIop);
578 decoder_output += FpRegRegOpConstructor.subst(fcvtFpIntIop);
579 exec_output += BasicExecute.subst(fcvtFpIntIop);
580
581 # Now actually do the building with the different variants
582 for isDouble in True, False:
583 for isSigned in True, False:
584 for isXReg in True, False:
585 buildFpCvtIntOp(isDouble, isSigned, isXReg)
586
587 fcvtFpSFpDCode = vfp64EnabledCheckCode + '''
588 FPSCR fpscr = (FPSCR) FpscrExc;
589 uint64_t cDest = fplibConvert<uint32_t, uint64_t>(AA64FpOp1P0_uw,
590 FPCRRounding(fpscr), fpscr);
591 AA64FpDestP0_uw = cDest;
592 AA64FpDestP1_uw = cDest >> 32;
593 AA64FpDestP2_uw = 0;
594 AA64FpDestP3_uw = 0;
595 FpscrExc = fpscr;
596 '''
597 fcvtFpSFpDIop = InstObjParams("fcvt", "FCvtFpSFpD", "FpRegRegOp",
598 { "code": fcvtFpSFpDCode,
599 "op_class": "FloatCvtOp" }, [])
600 header_output += FpRegRegOpDeclare.subst(fcvtFpSFpDIop);
601 decoder_output += AA64FpRegRegOpConstructor.subst(fcvtFpSFpDIop);
602 exec_output += BasicExecute.subst(fcvtFpSFpDIop);
603
604 fcvtFpDFpSCode = vfp64EnabledCheckCode + '''
605 FPSCR fpscr = (FPSCR) FpscrExc;
606 uint64_t cOp1 = AA64FpOp1P0_uw | (uint64_t)AA64FpOp1P1_uw << 32;
607 AA64FpDestP0_uw = fplibConvert<uint64_t, uint32_t>(cOp1,
608 FPCRRounding(fpscr), fpscr);
609 AA64FpDestP1_uw = 0;
610 AA64FpDestP2_uw = 0;
611 AA64FpDestP3_uw = 0;
612 FpscrExc = fpscr;
613 '''
614 fcvtFpDFpSIop = InstObjParams("fcvt", "FcvtFpDFpS", "FpRegRegOp",
615 {"code": fcvtFpDFpSCode,
616 "op_class": "FloatCvtOp" }, [])
617 header_output += FpRegRegOpDeclare.subst(fcvtFpDFpSIop);
618 decoder_output += AA64FpRegRegOpConstructor.subst(fcvtFpDFpSIop);
619 exec_output += BasicExecute.subst(fcvtFpDFpSIop);
620
621 # Half precision to single or double precision conversion
622 for isDouble in True, False:
623 code = vfp64EnabledCheckCode + '''
624 FPSCR fpscr = (FPSCR) FpscrExc;
625 %s cDest = fplibConvert<uint16_t, uint%s_t>(AA64FpOp1P0_uw,
626 FPCRRounding(fpscr), fpscr);
627 ''' % ("uint64_t" if isDouble else "uint32_t",
628 "64" if isDouble else "32")
629 if isDouble:
630 code += '''
631 AA64FpDestP0_uw = cDest;
632 AA64FpDestP1_uw = cDest >> 32;
633 '''
634 else:
635 code += '''
636 AA64FpDestP0_uw = cDest;
637 AA64FpDestP1_uw = 0;
638 '''
639 code += '''
640 AA64FpDestP2_uw = 0;
641 AA64FpDestP3_uw = 0;
642 FpscrExc = fpscr;
643 '''
644
645 instName = "FcvtFpHFp%s" %("D" if isDouble else "S")
646 fcvtFpHFpIop = InstObjParams("fcvt", instName, "FpRegRegOp",
647 { "code": code,
648 "op_class": "FloatCvtOp" }, [])
649 header_output += FpRegRegOpDeclare.subst(fcvtFpHFpIop);
650 decoder_output += AA64FpRegRegOpConstructor.subst(fcvtFpHFpIop);
651 exec_output += BasicExecute.subst(fcvtFpHFpIop);
652
653 # single or double precision to Half precision conversion
654 for isDouble in True, False:
655 code = vfp64EnabledCheckCode + '''
656 FPSCR fpscr = (FPSCR) FpscrExc;
657 %s;
658 AA64FpDestP0_uw = fplibConvert<uint%s_t, uint16_t>(cOp1,
659 FPCRRounding(fpscr), fpscr);
660 AA64FpDestP1_uw = 0;
661 AA64FpDestP2_uw = 0;
662 AA64FpDestP3_uw = 0;
663 FpscrExc = fpscr;
664 ''' % ("uint64_t cOp1 = AA64FpOp1P0_uw | (uint64_t)AA64FpOp1P1_uw << 32"
665 if isDouble else "uint32_t cOp1 = AA64FpOp1P0_uw",
666 "64" if isDouble else "32")
667
668 instName = "FcvtFp%sFpH" %("D" if isDouble else "S")
669 fcvtFpFpHIop = InstObjParams("fcvt", instName, "FpRegRegOp",
670 { "code": code,
671 "op_class": "FloatCvtOp" }, [])
672 header_output += FpRegRegOpDeclare.subst(fcvtFpFpHIop);
673 decoder_output += AA64FpRegRegOpConstructor.subst(fcvtFpFpHIop);
674 exec_output += BasicExecute.subst(fcvtFpFpHIop);
675
676 # Build the various versions of the floating point compare instructions
677 def buildFCmpOp(isQuiet, isDouble, isImm):
678 global header_output, decoder_output, exec_output
679
680 fcmpCode = vfp64EnabledCheckCode + '''
681 FPSCR fpscr = (FPSCR) FpscrExc;
682 %s cOp1 = %s;
683 ''' % ("uint64_t" if isDouble else "uint32_t",
684 "AA64FpDestP0_uw | (uint64_t)AA64FpDestP1_uw << 32"
685 if isDouble else "AA64FpDestP0_uw")
686 if isImm:
687 fcmpCode += '''
688 %s cOp2 = imm;
689 ''' % ("uint64_t" if isDouble else "uint32_t")
690 else:
691 fcmpCode += '''
692 %s cOp2 = %s;
693 ''' % ("uint64_t" if isDouble else "uint32_t",
694 "AA64FpOp1P0_uw | (uint64_t)AA64FpOp1P1_uw << 32"
695 if isDouble else "AA64FpOp1P0_uw")
696 fcmpCode += '''
697 int cc = fplibCompare<uint%s_t>(cOp1, cOp2, %s, fpscr);
698 CondCodesNZ = cc >> 2 & 3;
699 CondCodesC = cc >> 1 & 1;
700 CondCodesV = cc & 1;
701 FpCondCodes = fpscr & FpCondCodesMask;
702 FpscrExc = fpscr;
703 ''' % ("64" if isDouble else "32", "false" if isQuiet else "true")
704
705 typeName = "Imm" if isImm else "Reg"
706 instName = "FCmp%s%s%s" %("" if isQuiet else "E", typeName,
707 "D" if isDouble else "S")
708 fcmpIop = InstObjParams("fcmp%s" %("" if isQuiet else "e"), instName,
709 "FpReg%sOp" %(typeName),
710 {"code": fcmpCode,
711 "op_class": "FloatCmpOp"}, [])
712
713 declareTemp = eval("FpReg%sOpDeclare" %(typeName));
714 constructorTemp = eval("AA64FpReg%sOpConstructor" %(typeName));
715 header_output += declareTemp.subst(fcmpIop);
716 decoder_output += constructorTemp.subst(fcmpIop);
717 exec_output += BasicExecute.subst(fcmpIop);
718
719 for isQuiet in True, False:
720 for isDouble in True, False:
721 for isImm in True, False:
722 buildFCmpOp(isQuiet, isDouble, isImm)
723
724 # Build the various versions of the conditional floating point compare
725 # instructions
726 def buildFCCmpOp(isQuiet, isDouble):
727 global header_output, decoder_output, exec_output
728
729 fccmpCode = vfp64EnabledCheckCode + '''
730 FPSCR fpscr = (FPSCR) FpscrExc;
731 if (testPredicate(CondCodesNZ, CondCodesC, CondCodesV, condCode)) {
732 %s cOp1 = %s;
733 %s cOp2 = %s;
734 int cc = fplibCompare<uint%s_t>(cOp1, cOp2, %s, fpscr);
735 CondCodesNZ = cc >> 2 & 3;
736 CondCodesC = cc >> 1 & 1;
737 CondCodesV = cc & 1;
738 } else {
739 CondCodesNZ = (defCc >> 2) & 0x3;
740 CondCodesC = (defCc >> 1) & 0x1;
741 CondCodesV = defCc & 0x1;
742 }
743 FpCondCodes = fpscr & FpCondCodesMask;
744 FpscrExc = fpscr;
745 ''' % ("uint64_t" if isDouble else "uint32_t",
746 "AA64FpOp1P0_uw | (uint64_t)AA64FpOp1P1_uw << 32"
747 if isDouble else "AA64FpOp1P0_uw",
748 "uint64_t" if isDouble else "uint32_t",
749 "AA64FpOp2P0_uw | (uint64_t)AA64FpOp2P1_uw << 32"
750 if isDouble else "AA64FpOp2P0_uw",
751 "64" if isDouble else "32", "false" if isQuiet else "true")
752
753 instName = "FCCmp%sReg%s" %("" if isQuiet else "E",
754 "D" if isDouble else "S")
755 fccmpIop = InstObjParams("fccmp%s" %("" if isQuiet else "e"),
756 instName, "FpCondCompRegOp",
757 {"code": fccmpCode,
758 "op_class": "FloatCmpOp"}, [])
759 header_output += DataXCondCompRegDeclare.subst(fccmpIop);
760 decoder_output += DataXCondCompRegConstructor.subst(fccmpIop);
761 exec_output += BasicExecute.subst(fccmpIop);
762
763 for isQuiet in True, False:
764 for isDouble in True, False:
765 buildFCCmpOp(isQuiet, isDouble)
766
767}};
768
769let {{
770
771 header_output = ""
772 decoder_output = ""
773 exec_output = ""
774
775 # Generates the variants of the floating to fixed point instructions
776 def buildFpCvtFixedOp(isSigned, isDouble, isXReg):
777 global header_output, decoder_output, exec_output
778
779 fcvtFpFixedCode = vfp64EnabledCheckCode + '''
780 FPSCR fpscr = (FPSCR) FpscrExc;
781 '''
782 if isDouble:
783 fcvtFpFixedCode += '''
784 uint64_t cOp1 = AA64FpOp1P0_uw | (uint64_t)AA64FpOp1P1_uw << 32;
785 '''
786 else:
787 fcvtFpFixedCode += "uint32_t cOp1 = AA64FpOp1P0_uw;"
788 fcvtFpFixedCode += '''
789 %sDest = fplibFPToFixed<uint%s_t, uint%s_t>(cOp1, 64 - imm, %s,
790 FPRounding_ZERO, fpscr);
791 FpscrExc = fpscr;
792 ''' %("X" if isXReg else "W",
793 "64" if isDouble else "32",
794 "64" if isXReg else "32",
795 "false" if isSigned else "true")
796
797 instName = "FcvtFp%sFixed%s%s" %("S" if isSigned else "U",
798 "D" if isDouble else "S",
799 "X" if isXReg else "W")
800 mnem = "fcvtz%s" %("s" if isSigned else "u")
801 fcvtFpFixedIop = InstObjParams(mnem, instName, "FpRegRegImmOp",
802 { "code": fcvtFpFixedCode,
803 "op_class": "FloatCvtOp" }, [])
804 header_output += FpRegRegImmOpDeclare.subst(fcvtFpFixedIop);
805 decoder_output += AA64FpRegRegImmOpConstructor.subst(fcvtFpFixedIop);
806 exec_output += BasicExecute.subst(fcvtFpFixedIop);
807
808 # Generates the variants of the fixed to floating point instructions
809 def buildFixedCvtFpOp(isSigned, isDouble, isXReg):
810 global header_output, decoder_output, exec_output
811
812 srcRegType = "X" if isXReg else "W"
813 fcvtFixedFpCode = vfp64EnabledCheckCode + '''
814 FPSCR fpscr = (FPSCR) FpscrExc;
815 %s result = fplibFixedToFP<uint%s_t>((%s%s_t)%sOp1, 64 - imm,
816 %s, FPCRRounding(fpscr), fpscr);
817 ''' %("uint64_t" if isDouble else "uint32_t",
818 "64" if isDouble else "32",
819 "int" if isSigned else "uint", "64" if isXReg else "32",
820 srcRegType,
821 "false" if isSigned else "true")
822 if isDouble:
823 fcvtFixedFpCode += '''
824 AA64FpDestP0_uw = result;
825 AA64FpDestP1_uw = result >> 32;
826 '''
827 else:
828 fcvtFixedFpCode += '''
829 AA64FpDestP0_uw = result;
830 AA64FpDestP1_uw = 0;
831 '''
832 fcvtFixedFpCode += '''
833 AA64FpDestP2_uw = 0;
834 AA64FpDestP3_uw = 0;
835 FpscrExc = fpscr;
836 '''
837
838 instName = "Fcvt%sFixedFp%s%s" %("S" if isSigned else "U",
839 "D" if isDouble else "S",
840 srcRegType)
841 mnem = "%scvtf" %("s" if isSigned else "u")
842 fcvtFixedFpIop = InstObjParams(mnem, instName, "FpRegRegImmOp",
843 { "code": fcvtFixedFpCode,
844 "op_class": "FloatCvtOp" }, [])
845 header_output += FpRegRegImmOpDeclare.subst(fcvtFixedFpIop);
846 decoder_output += FpRegRegImmOpConstructor.subst(fcvtFixedFpIop);
847 exec_output += BasicExecute.subst(fcvtFixedFpIop);
848
849 # loop over the variants building the instructions for each
850 for isXReg in True, False:
851 for isDouble in True, False:
852 for isSigned in True, False:
853 buildFpCvtFixedOp(isSigned, isDouble, isXReg)
854 buildFixedCvtFpOp(isSigned, isDouble, isXReg)
855}};
856
857let {{
858
859 header_output = ""
860 decoder_output = ""
861 exec_output = ""
862
863 for isDouble in True, False:
864 code = '''
865 if (testPredicate(CondCodesNZ, CondCodesC, CondCodesV, condCode)) {
866 AA64FpDestP0_uw = AA64FpOp1P0_uw;
867 '''
868 if isDouble:
869 code += '''
870 AA64FpDestP1_uw = AA64FpOp1P1_uw;
871 } else {
872 AA64FpDestP0_uw = AA64FpOp2P0_uw;
873 AA64FpDestP1_uw = AA64FpOp2P1_uw;
874 }
875 '''
876 else:
877 code += '''
878 } else {
879 AA64FpDestP0_uw = AA64FpOp2P0_uw;
880 }
881 AA64FpDestP1_uw = 0;
882 '''
883 code += '''
884 AA64FpDestP2_uw = 0;
885 AA64FpDestP3_uw = 0;
886 '''
887
888 iop = InstObjParams("fcsel", "FCSel%s" %("D" if isDouble else "S"),
889 "FpCondSelOp", { "code": code,
890 "op_class": "FloatCvtOp" })
891 header_output += DataXCondSelDeclare.subst(iop)
892 decoder_output += DataXCondSelConstructor.subst(iop)
893 exec_output += BasicExecute.subst(iop)
894}};