fp.isa (11671:520509f3e66c) fp.isa (12032:d218c2fe9440)
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
40output header {{
41
42template <class Micro>
43class VfpMacroRegRegOp : public VfpMacroOp
44{
45 public:
46 VfpMacroRegRegOp(ExtMachInst _machInst, IntRegIndex _dest,
47 IntRegIndex _op1, bool _wide) :
48 VfpMacroOp("VfpMacroRegRegOp", _machInst, No_OpClass, _wide)
49 {
50 numMicroops = machInst.fpscrLen + 1;
51 assert(numMicroops > 1);
52 microOps = new StaticInstPtr[numMicroops];
53 for (unsigned i = 0; i < numMicroops; i++) {
54 VfpMicroMode mode = VfpMicroop;
55 if (i == 0)
56 mode = VfpFirstMicroop;
57 else if (i == numMicroops - 1)
58 mode = VfpLastMicroop;
59 microOps[i] = new Micro(_machInst, _dest, _op1, mode);
60 nextIdxs(_dest, _op1);
61 }
62 }
63
64 %(BasicExecPanic)s
65};
66
67template <class VfpOp>
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
40output header {{
41
42template <class Micro>
43class VfpMacroRegRegOp : public VfpMacroOp
44{
45 public:
46 VfpMacroRegRegOp(ExtMachInst _machInst, IntRegIndex _dest,
47 IntRegIndex _op1, bool _wide) :
48 VfpMacroOp("VfpMacroRegRegOp", _machInst, No_OpClass, _wide)
49 {
50 numMicroops = machInst.fpscrLen + 1;
51 assert(numMicroops > 1);
52 microOps = new StaticInstPtr[numMicroops];
53 for (unsigned i = 0; i < numMicroops; i++) {
54 VfpMicroMode mode = VfpMicroop;
55 if (i == 0)
56 mode = VfpFirstMicroop;
57 else if (i == numMicroops - 1)
58 mode = VfpLastMicroop;
59 microOps[i] = new Micro(_machInst, _dest, _op1, mode);
60 nextIdxs(_dest, _op1);
61 }
62 }
63
64 %(BasicExecPanic)s
65};
66
67template <class VfpOp>
68static StaticInstPtr
68StaticInstPtr
69decodeVfpRegRegOp(ExtMachInst machInst,
70 IntRegIndex dest, IntRegIndex op1, bool wide)
71{
72 if (machInst.fpscrLen == 0 || VfpMacroOp::inScalarBank(dest)) {
73 return new VfpOp(machInst, dest, op1);
74 } else {
75 return new VfpMacroRegRegOp<VfpOp>(machInst, dest, op1, wide);
76 }
77}
78
79template <class Micro>
80class VfpMacroRegImmOp : public VfpMacroOp
81{
82 public:
83 VfpMacroRegImmOp(ExtMachInst _machInst, IntRegIndex _dest, uint64_t _imm,
84 bool _wide) :
85 VfpMacroOp("VfpMacroRegImmOp", _machInst, No_OpClass, _wide)
86 {
87 numMicroops = machInst.fpscrLen + 1;
88 microOps = new StaticInstPtr[numMicroops];
89 for (unsigned i = 0; i < numMicroops; i++) {
90 VfpMicroMode mode = VfpMicroop;
91 if (i == 0)
92 mode = VfpFirstMicroop;
93 else if (i == numMicroops - 1)
94 mode = VfpLastMicroop;
95 microOps[i] = new Micro(_machInst, _dest, _imm, mode);
96 nextIdxs(_dest);
97 }
98 }
99
100 %(BasicExecPanic)s
101};
102
103template <class VfpOp>
69decodeVfpRegRegOp(ExtMachInst machInst,
70 IntRegIndex dest, IntRegIndex op1, bool wide)
71{
72 if (machInst.fpscrLen == 0 || VfpMacroOp::inScalarBank(dest)) {
73 return new VfpOp(machInst, dest, op1);
74 } else {
75 return new VfpMacroRegRegOp<VfpOp>(machInst, dest, op1, wide);
76 }
77}
78
79template <class Micro>
80class VfpMacroRegImmOp : public VfpMacroOp
81{
82 public:
83 VfpMacroRegImmOp(ExtMachInst _machInst, IntRegIndex _dest, uint64_t _imm,
84 bool _wide) :
85 VfpMacroOp("VfpMacroRegImmOp", _machInst, No_OpClass, _wide)
86 {
87 numMicroops = machInst.fpscrLen + 1;
88 microOps = new StaticInstPtr[numMicroops];
89 for (unsigned i = 0; i < numMicroops; i++) {
90 VfpMicroMode mode = VfpMicroop;
91 if (i == 0)
92 mode = VfpFirstMicroop;
93 else if (i == numMicroops - 1)
94 mode = VfpLastMicroop;
95 microOps[i] = new Micro(_machInst, _dest, _imm, mode);
96 nextIdxs(_dest);
97 }
98 }
99
100 %(BasicExecPanic)s
101};
102
103template <class VfpOp>
104static StaticInstPtr
104StaticInstPtr
105decodeVfpRegImmOp(ExtMachInst machInst,
106 IntRegIndex dest, uint64_t imm, bool wide)
107{
108 if (machInst.fpscrLen == 0 || VfpMacroOp::inScalarBank(dest)) {
109 return new VfpOp(machInst, dest, imm);
110 } else {
111 return new VfpMacroRegImmOp<VfpOp>(machInst, dest, imm, wide);
112 }
113}
114
115template <class Micro>
116class VfpMacroRegRegImmOp : public VfpMacroOp
117{
118 public:
119 VfpMacroRegRegImmOp(ExtMachInst _machInst, IntRegIndex _dest,
120 IntRegIndex _op1, uint64_t _imm, bool _wide) :
121 VfpMacroOp("VfpMacroRegRegImmOp", _machInst, No_OpClass, _wide)
122 {
123 numMicroops = machInst.fpscrLen + 1;
124 microOps = new StaticInstPtr[numMicroops];
125 for (unsigned i = 0; i < numMicroops; i++) {
126 VfpMicroMode mode = VfpMicroop;
127 if (i == 0)
128 mode = VfpFirstMicroop;
129 else if (i == numMicroops - 1)
130 mode = VfpLastMicroop;
131 microOps[i] = new Micro(_machInst, _dest, _op1, _imm, mode);
132 nextIdxs(_dest, _op1);
133 }
134 }
135
136 %(BasicExecPanic)s
137};
138
139template <class VfpOp>
105decodeVfpRegImmOp(ExtMachInst machInst,
106 IntRegIndex dest, uint64_t imm, bool wide)
107{
108 if (machInst.fpscrLen == 0 || VfpMacroOp::inScalarBank(dest)) {
109 return new VfpOp(machInst, dest, imm);
110 } else {
111 return new VfpMacroRegImmOp<VfpOp>(machInst, dest, imm, wide);
112 }
113}
114
115template <class Micro>
116class VfpMacroRegRegImmOp : public VfpMacroOp
117{
118 public:
119 VfpMacroRegRegImmOp(ExtMachInst _machInst, IntRegIndex _dest,
120 IntRegIndex _op1, uint64_t _imm, bool _wide) :
121 VfpMacroOp("VfpMacroRegRegImmOp", _machInst, No_OpClass, _wide)
122 {
123 numMicroops = machInst.fpscrLen + 1;
124 microOps = new StaticInstPtr[numMicroops];
125 for (unsigned i = 0; i < numMicroops; i++) {
126 VfpMicroMode mode = VfpMicroop;
127 if (i == 0)
128 mode = VfpFirstMicroop;
129 else if (i == numMicroops - 1)
130 mode = VfpLastMicroop;
131 microOps[i] = new Micro(_machInst, _dest, _op1, _imm, mode);
132 nextIdxs(_dest, _op1);
133 }
134 }
135
136 %(BasicExecPanic)s
137};
138
139template <class VfpOp>
140static StaticInstPtr
140StaticInstPtr
141decodeVfpRegRegImmOp(ExtMachInst machInst, IntRegIndex dest,
142 IntRegIndex op1, uint64_t imm, bool wide)
143{
144 if (machInst.fpscrLen == 0 || VfpMacroOp::inScalarBank(dest)) {
145 return new VfpOp(machInst, dest, op1, imm);
146 } else {
147 return new VfpMacroRegRegImmOp<VfpOp>(machInst, dest, op1, imm, wide);
148 }
149}
150
151template <class Micro>
152class VfpMacroRegRegRegOp : public VfpMacroOp
153{
154 public:
155 VfpMacroRegRegRegOp(ExtMachInst _machInst, IntRegIndex _dest,
156 IntRegIndex _op1, IntRegIndex _op2, bool _wide) :
157 VfpMacroOp("VfpMacroRegRegRegOp", _machInst, No_OpClass, _wide)
158 {
159 numMicroops = machInst.fpscrLen + 1;
160 microOps = new StaticInstPtr[numMicroops];
161 for (unsigned i = 0; i < numMicroops; i++) {
162 VfpMicroMode mode = VfpMicroop;
163 if (i == 0)
164 mode = VfpFirstMicroop;
165 else if (i == numMicroops - 1)
166 mode = VfpLastMicroop;
167 microOps[i] = new Micro(_machInst, _dest, _op1, _op2, mode);
168 nextIdxs(_dest, _op1, _op2);
169 }
170 }
171
172 %(BasicExecPanic)s
173};
174
175template <class VfpOp>
141decodeVfpRegRegImmOp(ExtMachInst machInst, IntRegIndex dest,
142 IntRegIndex op1, uint64_t imm, bool wide)
143{
144 if (machInst.fpscrLen == 0 || VfpMacroOp::inScalarBank(dest)) {
145 return new VfpOp(machInst, dest, op1, imm);
146 } else {
147 return new VfpMacroRegRegImmOp<VfpOp>(machInst, dest, op1, imm, wide);
148 }
149}
150
151template <class Micro>
152class VfpMacroRegRegRegOp : public VfpMacroOp
153{
154 public:
155 VfpMacroRegRegRegOp(ExtMachInst _machInst, IntRegIndex _dest,
156 IntRegIndex _op1, IntRegIndex _op2, bool _wide) :
157 VfpMacroOp("VfpMacroRegRegRegOp", _machInst, No_OpClass, _wide)
158 {
159 numMicroops = machInst.fpscrLen + 1;
160 microOps = new StaticInstPtr[numMicroops];
161 for (unsigned i = 0; i < numMicroops; i++) {
162 VfpMicroMode mode = VfpMicroop;
163 if (i == 0)
164 mode = VfpFirstMicroop;
165 else if (i == numMicroops - 1)
166 mode = VfpLastMicroop;
167 microOps[i] = new Micro(_machInst, _dest, _op1, _op2, mode);
168 nextIdxs(_dest, _op1, _op2);
169 }
170 }
171
172 %(BasicExecPanic)s
173};
174
175template <class VfpOp>
176static StaticInstPtr
176StaticInstPtr
177decodeVfpRegRegRegOp(ExtMachInst machInst, IntRegIndex dest,
178 IntRegIndex op1, IntRegIndex op2, bool wide)
179{
180 if (machInst.fpscrLen == 0 || VfpMacroOp::inScalarBank(dest)) {
181 return new VfpOp(machInst, dest, op1, op2);
182 } else {
183 return new VfpMacroRegRegRegOp<VfpOp>(machInst, dest, op1, op2, wide);
184 }
185}
186}};
187
188let {{
189
190 header_output = ""
191 decoder_output = ""
192 exec_output = ""
193
194 vmsrCode = vmsrEnabledCheckCode + '''
195 MiscDest = Op1;
196 '''
197
198 vmsrIop = InstObjParams("vmsr", "Vmsr", "FpRegRegImmOp",
199 { "code": vmsrCode,
200 "predicate_test": predicateTest,
201 "op_class": "SimdFloatMiscOp" },
202 ["IsSerializeAfter","IsNonSpeculative"])
203 header_output += FpRegRegImmOpDeclare.subst(vmsrIop);
204 decoder_output += FpRegRegImmOpConstructor.subst(vmsrIop);
205 exec_output += PredOpExecute.subst(vmsrIop);
206
207 vmsrFpscrCode = vmsrEnabledCheckCode + '''
208 Fpscr = Op1 & ~FpCondCodesMask;
209 FpCondCodes = Op1 & FpCondCodesMask;
210 '''
211 vmsrFpscrIop = InstObjParams("vmsr", "VmsrFpscr", "FpRegRegOp",
212 { "code": vmsrFpscrCode,
213 "predicate_test": predicateTest,
214 "op_class": "SimdFloatMiscOp" },
215 ["IsSerializeAfter","IsNonSpeculative",
216 "IsSquashAfter"])
217 header_output += FpRegRegOpDeclare.subst(vmsrFpscrIop);
218 decoder_output += FpRegRegOpConstructor.subst(vmsrFpscrIop);
219 exec_output += PredOpExecute.subst(vmsrFpscrIop);
220
221 vmrsCode = vmrsEnabledCheckCode + '''
222 CPSR cpsr = Cpsr;
223 SCR scr = Scr;
224 if (!inSecureState(scr, cpsr) && (cpsr.mode != MODE_HYP)) {
225 HCR hcr = Hcr;
226 bool hypTrap = false;
227 switch(xc->tcBase()->flattenMiscIndex(op1)) {
228 case MISCREG_FPSID:
229 hypTrap = hcr.tid0;
230 break;
231 case MISCREG_MVFR0:
232 case MISCREG_MVFR1:
233 hypTrap = hcr.tid3;
234 break;
235 }
236 if (hypTrap) {
237 return std::make_shared<HypervisorTrap>(machInst, imm,
238 EC_TRAPPED_CP10_MRC_VMRS);
239 }
240 }
241 Dest = MiscOp1;
242 '''
243
244 vmrsIop = InstObjParams("vmrs", "Vmrs", "FpRegRegImmOp",
245 { "code": vmrsCode,
246 "predicate_test": predicateTest,
247 "op_class": "SimdFloatMiscOp" },
248 ["IsSerializeBefore"])
249 header_output += FpRegRegImmOpDeclare.subst(vmrsIop);
250 decoder_output += FpRegRegImmOpConstructor.subst(vmrsIop);
251 exec_output += PredOpExecute.subst(vmrsIop);
252
253 vmrsFpscrIop = InstObjParams("vmrs", "VmrsFpscr", "FpRegRegOp",
254 { "code": vmrsEnabledCheckCode + \
255 "Dest = Fpscr | FpCondCodes;",
256 "predicate_test": predicateTest,
257 "op_class": "SimdFloatMiscOp" },
258 ["IsSerializeBefore"])
259 header_output += FpRegRegOpDeclare.subst(vmrsFpscrIop);
260 decoder_output += FpRegRegOpConstructor.subst(vmrsFpscrIop);
261 exec_output += PredOpExecute.subst(vmrsFpscrIop);
262
263 vmrsApsrFpscrCode = vfpEnabledCheckCode + '''
264 FPSCR fpscr = FpCondCodes;
265 CondCodesNZ = (fpscr.n << 1) | fpscr.z;
266 CondCodesC = fpscr.c;
267 CondCodesV = fpscr.v;
268 '''
269 vmrsApsrFpscrIop = InstObjParams("vmrs", "VmrsApsrFpscr", "PredOp",
270 { "code": vmrsApsrFpscrCode,
271 "predicate_test": predicateTest,
272 "op_class": "SimdFloatMiscOp" })
273 header_output += BasicDeclare.subst(vmrsApsrFpscrIop);
274 decoder_output += BasicConstructor.subst(vmrsApsrFpscrIop);
275 exec_output += PredOpExecute.subst(vmrsApsrFpscrIop);
276
277 vmovImmSCode = vfpEnabledCheckCode + '''
278 FpDest_uw = bits(imm, 31, 0);
279 '''
280 vmovImmSIop = InstObjParams("vmov", "VmovImmS", "FpRegImmOp",
281 { "code": vmovImmSCode,
282 "predicate_test": predicateTest,
283 "op_class": "SimdFloatMiscOp" }, [])
284 header_output += FpRegImmOpDeclare.subst(vmovImmSIop);
285 decoder_output += FpRegImmOpConstructor.subst(vmovImmSIop);
286 exec_output += PredOpExecute.subst(vmovImmSIop);
287
288 vmovImmDCode = vfpEnabledCheckCode + '''
289 FpDestP0_uw = bits(imm, 31, 0);
290 FpDestP1_uw = bits(imm, 63, 32);
291 '''
292 vmovImmDIop = InstObjParams("vmov", "VmovImmD", "FpRegImmOp",
293 { "code": vmovImmDCode,
294 "predicate_test": predicateTest,
295 "op_class": "SimdFloatMiscOp" }, [])
296 header_output += FpRegImmOpDeclare.subst(vmovImmDIop);
297 decoder_output += FpRegImmOpConstructor.subst(vmovImmDIop);
298 exec_output += PredOpExecute.subst(vmovImmDIop);
299
300 vmovImmQCode = vfpEnabledCheckCode + '''
301 FpDestP0_uw = bits(imm, 31, 0);
302 FpDestP1_uw = bits(imm, 63, 32);
303 FpDestP2_uw = bits(imm, 31, 0);
304 FpDestP3_uw = bits(imm, 63, 32);
305 '''
306 vmovImmQIop = InstObjParams("vmov", "VmovImmQ", "FpRegImmOp",
307 { "code": vmovImmQCode,
308 "predicate_test": predicateTest,
309 "op_class": "SimdFloatMiscOp" }, [])
310 header_output += FpRegImmOpDeclare.subst(vmovImmQIop);
311 decoder_output += FpRegImmOpConstructor.subst(vmovImmQIop);
312 exec_output += PredOpExecute.subst(vmovImmQIop);
313
314 vmovRegSCode = vfpEnabledCheckCode + '''
315 FpDest_uw = FpOp1_uw;
316 '''
317 vmovRegSIop = InstObjParams("vmov", "VmovRegS", "FpRegRegOp",
318 { "code": vmovRegSCode,
319 "predicate_test": predicateTest,
320 "op_class": "SimdFloatMiscOp" }, [])
321 header_output += FpRegRegOpDeclare.subst(vmovRegSIop);
322 decoder_output += FpRegRegOpConstructor.subst(vmovRegSIop);
323 exec_output += PredOpExecute.subst(vmovRegSIop);
324
325 vmovRegDCode = vfpEnabledCheckCode + '''
326 FpDestP0_uw = FpOp1P0_uw;
327 FpDestP1_uw = FpOp1P1_uw;
328 '''
329 vmovRegDIop = InstObjParams("vmov", "VmovRegD", "FpRegRegOp",
330 { "code": vmovRegDCode,
331 "predicate_test": predicateTest,
332 "op_class": "SimdFloatMiscOp" }, [])
333 header_output += FpRegRegOpDeclare.subst(vmovRegDIop);
334 decoder_output += FpRegRegOpConstructor.subst(vmovRegDIop);
335 exec_output += PredOpExecute.subst(vmovRegDIop);
336
337 vmovRegQCode = vfpEnabledCheckCode + '''
338 FpDestP0_uw = FpOp1P0_uw;
339 FpDestP1_uw = FpOp1P1_uw;
340 FpDestP2_uw = FpOp1P2_uw;
341 FpDestP3_uw = FpOp1P3_uw;
342 '''
343 vmovRegQIop = InstObjParams("vmov", "VmovRegQ", "FpRegRegOp",
344 { "code": vmovRegQCode,
345 "predicate_test": predicateTest,
346 "op_class": "SimdFloatMiscOp" }, [])
347 header_output += FpRegRegOpDeclare.subst(vmovRegQIop);
348 decoder_output += FpRegRegOpConstructor.subst(vmovRegQIop);
349 exec_output += PredOpExecute.subst(vmovRegQIop);
350
351 vmovCoreRegBCode = simdEnabledCheckCode + '''
352 FpDest_uw = insertBits(FpDest_uw, imm * 8 + 7, imm * 8, Op1_ub);
353 '''
354 vmovCoreRegBIop = InstObjParams("vmov", "VmovCoreRegB", "FpRegRegImmOp",
355 { "code": vmovCoreRegBCode,
356 "predicate_test": predicateTest,
357 "op_class": "SimdFloatMiscOp" }, [])
358 header_output += FpRegRegImmOpDeclare.subst(vmovCoreRegBIop);
359 decoder_output += FpRegRegImmOpConstructor.subst(vmovCoreRegBIop);
360 exec_output += PredOpExecute.subst(vmovCoreRegBIop);
361
362 vmovCoreRegHCode = simdEnabledCheckCode + '''
363 FpDest_uw = insertBits(FpDest_uw, imm * 16 + 15, imm * 16, Op1_uh);
364 '''
365 vmovCoreRegHIop = InstObjParams("vmov", "VmovCoreRegH", "FpRegRegImmOp",
366 { "code": vmovCoreRegHCode,
367 "predicate_test": predicateTest,
368 "op_class": "SimdFloatMiscOp" }, [])
369 header_output += FpRegRegImmOpDeclare.subst(vmovCoreRegHIop);
370 decoder_output += FpRegRegImmOpConstructor.subst(vmovCoreRegHIop);
371 exec_output += PredOpExecute.subst(vmovCoreRegHIop);
372
373 vmovCoreRegWCode = vfpEnabledCheckCode + '''
374 FpDest_uw = Op1_uw;
375 '''
376 vmovCoreRegWIop = InstObjParams("vmov", "VmovCoreRegW", "FpRegRegOp",
377 { "code": vmovCoreRegWCode,
378 "predicate_test": predicateTest,
379 "op_class": "SimdFloatMiscOp" }, [])
380 header_output += FpRegRegOpDeclare.subst(vmovCoreRegWIop);
381 decoder_output += FpRegRegOpConstructor.subst(vmovCoreRegWIop);
382 exec_output += PredOpExecute.subst(vmovCoreRegWIop);
383
384 vmovRegCoreUBCode = vfpEnabledCheckCode + '''
385 assert(imm < 4);
386 Dest = bits(FpOp1_uw, imm * 8 + 7, imm * 8);
387 '''
388 vmovRegCoreUBIop = InstObjParams("vmov", "VmovRegCoreUB", "FpRegRegImmOp",
389 { "code": vmovRegCoreUBCode,
390 "predicate_test": predicateTest,
391 "op_class": "SimdFloatMiscOp" }, [])
392 header_output += FpRegRegImmOpDeclare.subst(vmovRegCoreUBIop);
393 decoder_output += FpRegRegImmOpConstructor.subst(vmovRegCoreUBIop);
394 exec_output += PredOpExecute.subst(vmovRegCoreUBIop);
395
396 vmovRegCoreUHCode = vfpEnabledCheckCode + '''
397 assert(imm < 2);
398 Dest = bits(FpOp1_uw, imm * 16 + 15, imm * 16);
399 '''
400 vmovRegCoreUHIop = InstObjParams("vmov", "VmovRegCoreUH", "FpRegRegImmOp",
401 { "code": vmovRegCoreUHCode,
402 "predicate_test": predicateTest,
403 "op_class": "SimdFloatMiscOp" }, [])
404 header_output += FpRegRegImmOpDeclare.subst(vmovRegCoreUHIop);
405 decoder_output += FpRegRegImmOpConstructor.subst(vmovRegCoreUHIop);
406 exec_output += PredOpExecute.subst(vmovRegCoreUHIop);
407
408 vmovRegCoreSBCode = vfpEnabledCheckCode + '''
409 assert(imm < 4);
410 Dest = sext<8>(bits(FpOp1_uw, imm * 8 + 7, imm * 8));
411 '''
412 vmovRegCoreSBIop = InstObjParams("vmov", "VmovRegCoreSB", "FpRegRegImmOp",
413 { "code": vmovRegCoreSBCode,
414 "predicate_test": predicateTest,
415 "op_class": "SimdFloatMiscOp" }, [])
416 header_output += FpRegRegImmOpDeclare.subst(vmovRegCoreSBIop);
417 decoder_output += FpRegRegImmOpConstructor.subst(vmovRegCoreSBIop);
418 exec_output += PredOpExecute.subst(vmovRegCoreSBIop);
419
420 vmovRegCoreSHCode = vfpEnabledCheckCode + '''
421 assert(imm < 2);
422 Dest = sext<16>(bits(FpOp1_uw, imm * 16 + 15, imm * 16));
423 '''
424 vmovRegCoreSHIop = InstObjParams("vmov", "VmovRegCoreSH", "FpRegRegImmOp",
425 { "code": vmovRegCoreSHCode,
426 "predicate_test": predicateTest,
427 "op_class": "SimdFloatMiscOp" }, [])
428 header_output += FpRegRegImmOpDeclare.subst(vmovRegCoreSHIop);
429 decoder_output += FpRegRegImmOpConstructor.subst(vmovRegCoreSHIop);
430 exec_output += PredOpExecute.subst(vmovRegCoreSHIop);
431
432 vmovRegCoreWCode = vfpEnabledCheckCode + '''
433 Dest = FpOp1_uw;
434 '''
435 vmovRegCoreWIop = InstObjParams("vmov", "VmovRegCoreW", "FpRegRegOp",
436 { "code": vmovRegCoreWCode,
437 "predicate_test": predicateTest,
438 "op_class": "SimdFloatMiscOp" }, [])
439 header_output += FpRegRegOpDeclare.subst(vmovRegCoreWIop);
440 decoder_output += FpRegRegOpConstructor.subst(vmovRegCoreWIop);
441 exec_output += PredOpExecute.subst(vmovRegCoreWIop);
442
443 vmov2Reg2CoreCode = vfpEnabledCheckCode + '''
444 FpDestP0_uw = Op1_uw;
445 FpDestP1_uw = Op2_uw;
446 '''
447 vmov2Reg2CoreIop = InstObjParams("vmov", "Vmov2Reg2Core", "FpRegRegRegOp",
448 { "code": vmov2Reg2CoreCode,
449 "predicate_test": predicateTest,
450 "op_class": "SimdFloatMiscOp" }, [])
451 header_output += FpRegRegRegOpDeclare.subst(vmov2Reg2CoreIop);
452 decoder_output += FpRegRegRegOpConstructor.subst(vmov2Reg2CoreIop);
453 exec_output += PredOpExecute.subst(vmov2Reg2CoreIop);
454
455 vmov2Core2RegCode = vfpEnabledCheckCode + '''
456 Dest_uw = FpOp2P0_uw;
457 Op1_uw = FpOp2P1_uw;
458 '''
459 vmov2Core2RegIop = InstObjParams("vmov", "Vmov2Core2Reg", "FpRegRegRegOp",
460 { "code": vmov2Core2RegCode,
461 "predicate_test": predicateTest,
462 "op_class": "SimdFloatMiscOp" }, [])
463 header_output += FpRegRegRegOpDeclare.subst(vmov2Core2RegIop);
464 decoder_output += FpRegRegRegOpConstructor.subst(vmov2Core2RegIop);
465 exec_output += PredOpExecute.subst(vmov2Core2RegIop);
466}};
467
468let {{
469
470 header_output = ""
471 decoder_output = ""
472 exec_output = ""
473
474 singleSimpleCode = vfpEnabledCheckCode + '''
475 FPSCR fpscr M5_VAR_USED = (FPSCR) FpscrExc;
476 FpDest = %(op)s;
477 '''
478 singleCode = singleSimpleCode + '''
479 FpscrExc = fpscr;
480 '''
481 singleTernOp = vfpEnabledCheckCode + '''
482 FPSCR fpscr = (FPSCR) FpscrExc;
483 VfpSavedState state = prepFpState(fpscr.rMode);
484 float cOp1 = FpOp1;
485 float cOp2 = FpOp2;
486 float cOp3 = FpDestP0;
487 FpDestP0 = ternaryOp(fpscr, %(palam)s, %(op)s,
488 fpscr.fz, fpscr.dn, fpscr.rMode);
489 finishVfp(fpscr, state, fpscr.fz);
490 FpscrExc = fpscr;
491 '''
492 singleBinOp = "binaryOp(fpscr, FpOp1, FpOp2," + \
493 "%(func)s, fpscr.fz, fpscr.dn, fpscr.rMode)"
494 singleUnaryOp = "unaryOp(fpscr, FpOp1, %(func)s, fpscr.fz, fpscr.rMode)"
495 doubleCode = vfpEnabledCheckCode + '''
496 FPSCR fpscr M5_VAR_USED = (FPSCR) FpscrExc;
497 double dest = %(op)s;
498 FpDestP0_uw = dblLow(dest);
499 FpDestP1_uw = dblHi(dest);
500 FpscrExc = fpscr;
501 '''
502 doubleTernOp = vfpEnabledCheckCode + '''
503 FPSCR fpscr = (FPSCR) FpscrExc;
504 VfpSavedState state = prepFpState(fpscr.rMode);
505 double cOp1 = dbl(FpOp1P0_uw, FpOp1P1_uw);
506 double cOp2 = dbl(FpOp2P0_uw, FpOp2P1_uw);
507 double cOp3 = dbl(FpDestP0_uw, FpDestP1_uw);
508 double cDest = ternaryOp(fpscr, %(palam)s, %(op)s,
509 fpscr.fz, fpscr.dn, fpscr.rMode);
510 FpDestP0_uw = dblLow(cDest);
511 FpDestP1_uw = dblHi(cDest);
512 finishVfp(fpscr, state, fpscr.fz);
513 FpscrExc = fpscr;
514 '''
515 doubleBinOp = '''
516 binaryOp(fpscr, dbl(FpOp1P0_uw, FpOp1P1_uw),
517 dbl(FpOp2P0_uw, FpOp2P1_uw),
518 %(func)s, fpscr.fz, fpscr.dn, fpscr.rMode);
519 '''
520 doubleUnaryOp = '''
521 unaryOp(fpscr, dbl(FpOp1P0_uw, FpOp1P1_uw), %(func)s,
522 fpscr.fz, fpscr.rMode)
523 '''
524
525 def buildTernaryFpOp(Name, base, opClass, singleOp, doubleOp, paramStr):
526 global header_output, decoder_output, exec_output
527
528 code = singleTernOp % { "op": singleOp, "palam": paramStr }
529 sIop = InstObjParams(Name.lower() + "s", Name + "S", base,
530 { "code": code,
531 "predicate_test": predicateTest,
532 "op_class": opClass }, [])
533 code = doubleTernOp % { "op": doubleOp, "palam": paramStr }
534 dIop = InstObjParams(Name.lower() + "d", Name + "D", base,
535 { "code": code,
536 "predicate_test": predicateTest,
537 "op_class": opClass }, [])
538
539 declareTempl = eval(base + "Declare");
540 constructorTempl = eval(base + "Constructor");
541
542 for iop in sIop, dIop:
543 header_output += declareTempl.subst(iop)
544 decoder_output += constructorTempl.subst(iop)
545 exec_output += PredOpExecute.subst(iop)
546
547 buildTernaryFpOp("Vfma", "FpRegRegRegOp", "SimdFloatMultAccOp",
548 "fpMulAdd<float>", "fpMulAdd<double>", " cOp1, cOp2, cOp3" )
549 buildTernaryFpOp("Vfms", "FpRegRegRegOp", "SimdFloatMultAccOp",
550 "fpMulAdd<float>", "fpMulAdd<double>", "-cOp1, cOp2, cOp3" )
551 buildTernaryFpOp("Vfnma", "FpRegRegRegOp", "SimdFloatMultAccOp",
552 "fpMulAdd<float>", "fpMulAdd<double>", "-cOp1, cOp2, -cOp3" )
553 buildTernaryFpOp("Vfnms", "FpRegRegRegOp", "SimdFloatMultAccOp",
554 "fpMulAdd<float>", "fpMulAdd<double>", " cOp1, cOp2, -cOp3" )
555
556 def buildBinFpOp(name, Name, base, opClass, singleOp, doubleOp):
557 global header_output, decoder_output, exec_output
558
559 code = singleCode % { "op": singleBinOp }
560 code = code % { "func": singleOp }
561 sIop = InstObjParams(name + "s", Name + "S", base,
562 { "code": code,
563 "predicate_test": predicateTest,
564 "op_class": opClass }, [])
565 code = doubleCode % { "op": doubleBinOp }
566 code = code % { "func": doubleOp }
567 dIop = InstObjParams(name + "d", Name + "D", base,
568 { "code": code,
569 "predicate_test": predicateTest,
570 "op_class": opClass }, [])
571
572 declareTempl = eval(base + "Declare");
573 constructorTempl = eval(base + "Constructor");
574
575 for iop in sIop, dIop:
576 header_output += declareTempl.subst(iop)
577 decoder_output += constructorTempl.subst(iop)
578 exec_output += PredOpExecute.subst(iop)
579
580 buildBinFpOp("vadd", "Vadd", "FpRegRegRegOp", "SimdFloatAddOp", "fpAddS",
581 "fpAddD")
582 buildBinFpOp("vsub", "Vsub", "FpRegRegRegOp", "SimdFloatAddOp", "fpSubS",
583 "fpSubD")
584 buildBinFpOp("vdiv", "Vdiv", "FpRegRegRegOp", "SimdFloatDivOp", "fpDivS",
585 "fpDivD")
586 buildBinFpOp("vmul", "Vmul", "FpRegRegRegOp", "SimdFloatMultOp", "fpMulS",
587 "fpMulD")
588
589 def buildUnaryFpOp(name, Name, base, opClass, singleOp, doubleOp = None):
590 if doubleOp is None:
591 doubleOp = singleOp
592 global header_output, decoder_output, exec_output
593
594 code = singleCode % { "op": singleUnaryOp }
595 code = code % { "func": singleOp }
596 sIop = InstObjParams(name + "s", Name + "S", base,
597 { "code": code,
598 "predicate_test": predicateTest,
599 "op_class": opClass }, [])
600 code = doubleCode % { "op": doubleUnaryOp }
601 code = code % { "func": doubleOp }
602 dIop = InstObjParams(name + "d", Name + "D", base,
603 { "code": code,
604 "predicate_test": predicateTest,
605 "op_class": opClass }, [])
606
607 declareTempl = eval(base + "Declare");
608 constructorTempl = eval(base + "Constructor");
609
610 for iop in sIop, dIop:
611 header_output += declareTempl.subst(iop)
612 decoder_output += constructorTempl.subst(iop)
613 exec_output += PredOpExecute.subst(iop)
614
615 buildUnaryFpOp("vsqrt", "Vsqrt", "FpRegRegOp", "SimdFloatSqrtOp", "sqrtf",
616 "sqrt")
617
618 def buildSimpleUnaryFpOp(name, Name, base, opClass, singleOp,
619 doubleOp = None):
620 if doubleOp is None:
621 doubleOp = singleOp
622 global header_output, decoder_output, exec_output
623
624 sIop = InstObjParams(name + "s", Name + "S", base,
625 { "code": singleSimpleCode % { "op": singleOp },
626 "predicate_test": predicateTest,
627 "op_class": opClass }, [])
628 dIop = InstObjParams(name + "d", Name + "D", base,
629 { "code": doubleCode % { "op": doubleOp },
630 "predicate_test": predicateTest,
631 "op_class": opClass }, [])
632
633 declareTempl = eval(base + "Declare");
634 constructorTempl = eval(base + "Constructor");
635
636 for iop in sIop, dIop:
637 header_output += declareTempl.subst(iop)
638 decoder_output += constructorTempl.subst(iop)
639 exec_output += PredOpExecute.subst(iop)
640
641 buildSimpleUnaryFpOp("vneg", "Vneg", "FpRegRegOp", "SimdFloatMiscOp",
642 "-FpOp1", "-dbl(FpOp1P0_uw, FpOp1P1_uw)")
643 buildSimpleUnaryFpOp("vabs", "Vabs", "FpRegRegOp", "SimdFloatMiscOp",
644 "fabsf(FpOp1)", "fabs(dbl(FpOp1P0_uw, FpOp1P1_uw))")
645 buildSimpleUnaryFpOp("vrintp", "VRIntP", "FpRegRegOp", "SimdFloatMiscOp",
646 "fplibRoundInt<uint32_t>(FpOp1, FPRounding_POSINF, false, fpscr)",
647 "fplibRoundInt<uint64_t>(dbl(FpOp1P0_uw, FpOp1P1_uw), " \
648 "FPRounding_POSINF, false, fpscr)"
649 )
650 buildSimpleUnaryFpOp("vrintm", "VRIntM", "FpRegRegOp", "SimdFloatMiscOp",
651 "fplibRoundInt<uint32_t>(FpOp1, FPRounding_NEGINF, false, fpscr)",
652 "fplibRoundInt<uint64_t>(dbl(FpOp1P0_uw, FpOp1P1_uw), " \
653 "FPRounding_NEGINF, false, fpscr)"
654 )
655 buildSimpleUnaryFpOp("vrinta", "VRIntA", "FpRegRegOp", "SimdFloatMiscOp",
656 "fplibRoundInt<uint32_t>(FpOp1, FPRounding_TIEAWAY, false, fpscr)",
657 "fplibRoundInt<uint64_t>(dbl(FpOp1P0_uw, FpOp1P1_uw), " \
658 "FPRounding_TIEAWAY, false, fpscr)"
659 )
660 buildSimpleUnaryFpOp("vrintn", "VRIntN", "FpRegRegOp", "SimdFloatMiscOp",
661 "fplibRoundInt<uint32_t>(FpOp1, FPRounding_TIEEVEN, false, fpscr)",
662 "fplibRoundInt<uint64_t>(dbl(FpOp1P0_uw, FpOp1P1_uw), " \
663 "FPRounding_TIEEVEN, false, fpscr)"
664 )
665}};
666
667let {{
668
669 header_output = ""
670 decoder_output = ""
671 exec_output = ""
672
673 vmlaSCode = vfpEnabledCheckCode + '''
674 FPSCR fpscr = (FPSCR) FpscrExc;
675 float mid = binaryOp(fpscr, FpOp1, FpOp2,
676 fpMulS, fpscr.fz, fpscr.dn, fpscr.rMode);
677 FpDest = binaryOp(fpscr, FpDest, mid, fpAddS,
678 fpscr.fz, fpscr.dn, fpscr.rMode);
679 FpscrExc = fpscr;
680 '''
681 vmlaSIop = InstObjParams("vmlas", "VmlaS", "FpRegRegRegOp",
682 { "code": vmlaSCode,
683 "predicate_test": predicateTest,
684 "op_class": "SimdFloatMultAccOp" }, [])
685 header_output += FpRegRegRegOpDeclare.subst(vmlaSIop);
686 decoder_output += FpRegRegRegOpConstructor.subst(vmlaSIop);
687 exec_output += PredOpExecute.subst(vmlaSIop);
688
689 vmlaDCode = vfpEnabledCheckCode + '''
690 FPSCR fpscr = (FPSCR) FpscrExc;
691 double mid = binaryOp(fpscr, dbl(FpOp1P0_uw, FpOp1P1_uw),
692 dbl(FpOp2P0_uw, FpOp2P1_uw),
693 fpMulD, fpscr.fz, fpscr.dn, fpscr.rMode);
694 double dest = binaryOp(fpscr, dbl(FpDestP0_uw, FpDestP1_uw),
695 mid, fpAddD, fpscr.fz,
696 fpscr.dn, fpscr.rMode);
697 FpDestP0_uw = dblLow(dest);
698 FpDestP1_uw = dblHi(dest);
699 FpscrExc = fpscr;
700 '''
701 vmlaDIop = InstObjParams("vmlad", "VmlaD", "FpRegRegRegOp",
702 { "code": vmlaDCode,
703 "predicate_test": predicateTest,
704 "op_class": "SimdFloatMultAccOp" }, [])
705 header_output += FpRegRegRegOpDeclare.subst(vmlaDIop);
706 decoder_output += FpRegRegRegOpConstructor.subst(vmlaDIop);
707 exec_output += PredOpExecute.subst(vmlaDIop);
708
709 vmlsSCode = vfpEnabledCheckCode + '''
710 FPSCR fpscr = (FPSCR) FpscrExc;
711 float mid = binaryOp(fpscr, FpOp1, FpOp2,
712 fpMulS, fpscr.fz, fpscr.dn, fpscr.rMode);
713 FpDest = binaryOp(fpscr, FpDest, -mid, fpAddS,
714 fpscr.fz, fpscr.dn, fpscr.rMode);
715 FpscrExc = fpscr;
716 '''
717 vmlsSIop = InstObjParams("vmlss", "VmlsS", "FpRegRegRegOp",
718 { "code": vmlsSCode,
719 "predicate_test": predicateTest,
720 "op_class": "SimdFloatMultAccOp" }, [])
721 header_output += FpRegRegRegOpDeclare.subst(vmlsSIop);
722 decoder_output += FpRegRegRegOpConstructor.subst(vmlsSIop);
723 exec_output += PredOpExecute.subst(vmlsSIop);
724
725 vmlsDCode = vfpEnabledCheckCode + '''
726 FPSCR fpscr = (FPSCR) FpscrExc;
727 double mid = binaryOp(fpscr, dbl(FpOp1P0_uw, FpOp1P1_uw),
728 dbl(FpOp2P0_uw, FpOp2P1_uw),
729 fpMulD, fpscr.fz, fpscr.dn, fpscr.rMode);
730 double dest = binaryOp(fpscr, dbl(FpDestP0_uw, FpDestP1_uw),
731 -mid, fpAddD, fpscr.fz,
732 fpscr.dn, fpscr.rMode);
733 FpDestP0_uw = dblLow(dest);
734 FpDestP1_uw = dblHi(dest);
735 FpscrExc = fpscr;
736 '''
737 vmlsDIop = InstObjParams("vmlsd", "VmlsD", "FpRegRegRegOp",
738 { "code": vmlsDCode,
739 "predicate_test": predicateTest,
740 "op_class": "SimdFloatMultAccOp" }, [])
741 header_output += FpRegRegRegOpDeclare.subst(vmlsDIop);
742 decoder_output += FpRegRegRegOpConstructor.subst(vmlsDIop);
743 exec_output += PredOpExecute.subst(vmlsDIop);
744
745 vnmlaSCode = vfpEnabledCheckCode + '''
746 FPSCR fpscr = (FPSCR) FpscrExc;
747 float mid = binaryOp(fpscr, FpOp1, FpOp2,
748 fpMulS, fpscr.fz, fpscr.dn, fpscr.rMode);
749 FpDest = binaryOp(fpscr, -FpDest, -mid, fpAddS,
750 fpscr.fz, fpscr.dn, fpscr.rMode);
751 FpscrExc = fpscr;
752 '''
753 vnmlaSIop = InstObjParams("vnmlas", "VnmlaS", "FpRegRegRegOp",
754 { "code": vnmlaSCode,
755 "predicate_test": predicateTest,
756 "op_class": "SimdFloatMultAccOp" }, [])
757 header_output += FpRegRegRegOpDeclare.subst(vnmlaSIop);
758 decoder_output += FpRegRegRegOpConstructor.subst(vnmlaSIop);
759 exec_output += PredOpExecute.subst(vnmlaSIop);
760
761 vnmlaDCode = vfpEnabledCheckCode + '''
762 FPSCR fpscr = (FPSCR) FpscrExc;
763 double mid = binaryOp(fpscr, dbl(FpOp1P0_uw, FpOp1P1_uw),
764 dbl(FpOp2P0_uw, FpOp2P1_uw),
765 fpMulD, fpscr.fz, fpscr.dn, fpscr.rMode);
766 double dest = binaryOp(fpscr, -dbl(FpDestP0_uw, FpDestP1_uw),
767 -mid, fpAddD, fpscr.fz,
768 fpscr.dn, fpscr.rMode);
769 FpDestP0_uw = dblLow(dest);
770 FpDestP1_uw = dblHi(dest);
771 FpscrExc = fpscr;
772 '''
773 vnmlaDIop = InstObjParams("vnmlad", "VnmlaD", "FpRegRegRegOp",
774 { "code": vnmlaDCode,
775 "predicate_test": predicateTest,
776 "op_class": "SimdFloatMultAccOp" }, [])
777 header_output += FpRegRegRegOpDeclare.subst(vnmlaDIop);
778 decoder_output += FpRegRegRegOpConstructor.subst(vnmlaDIop);
779 exec_output += PredOpExecute.subst(vnmlaDIop);
780
781 vnmlsSCode = vfpEnabledCheckCode + '''
782 FPSCR fpscr = (FPSCR) FpscrExc;
783 float mid = binaryOp(fpscr, FpOp1, FpOp2,
784 fpMulS, fpscr.fz, fpscr.dn, fpscr.rMode);
785 FpDest = binaryOp(fpscr, -FpDest, mid, fpAddS,
786 fpscr.fz, fpscr.dn, fpscr.rMode);
787 FpscrExc = fpscr;
788 '''
789 vnmlsSIop = InstObjParams("vnmlss", "VnmlsS", "FpRegRegRegOp",
790 { "code": vnmlsSCode,
791 "predicate_test": predicateTest,
792 "op_class": "SimdFloatMultAccOp" }, [])
793 header_output += FpRegRegRegOpDeclare.subst(vnmlsSIop);
794 decoder_output += FpRegRegRegOpConstructor.subst(vnmlsSIop);
795 exec_output += PredOpExecute.subst(vnmlsSIop);
796
797 vnmlsDCode = vfpEnabledCheckCode + '''
798 FPSCR fpscr = (FPSCR) FpscrExc;
799 double mid = binaryOp(fpscr, dbl(FpOp1P0_uw, FpOp1P1_uw),
800 dbl(FpOp2P0_uw, FpOp2P1_uw),
801 fpMulD, fpscr.fz, fpscr.dn, fpscr.rMode);
802 double dest = binaryOp(fpscr, -dbl(FpDestP0_uw, FpDestP1_uw),
803 mid, fpAddD, fpscr.fz,
804 fpscr.dn, fpscr.rMode);
805 FpDestP0_uw = dblLow(dest);
806 FpDestP1_uw = dblHi(dest);
807 FpscrExc = fpscr;
808 '''
809 vnmlsDIop = InstObjParams("vnmlsd", "VnmlsD", "FpRegRegRegOp",
810 { "code": vnmlsDCode,
811 "predicate_test": predicateTest,
812 "op_class": "SimdFloatMultAccOp" }, [])
813 header_output += FpRegRegRegOpDeclare.subst(vnmlsDIop);
814 decoder_output += FpRegRegRegOpConstructor.subst(vnmlsDIop);
815 exec_output += PredOpExecute.subst(vnmlsDIop);
816
817 vnmulSCode = vfpEnabledCheckCode + '''
818 FPSCR fpscr = (FPSCR) FpscrExc;
819 FpDest = -binaryOp(fpscr, FpOp1, FpOp2, fpMulS,
820 fpscr.fz, fpscr.dn, fpscr.rMode);
821 FpscrExc = fpscr;
822 '''
823 vnmulSIop = InstObjParams("vnmuls", "VnmulS", "FpRegRegRegOp",
824 { "code": vnmulSCode,
825 "predicate_test": predicateTest,
826 "op_class": "SimdFloatMultOp" }, [])
827 header_output += FpRegRegRegOpDeclare.subst(vnmulSIop);
828 decoder_output += FpRegRegRegOpConstructor.subst(vnmulSIop);
829 exec_output += PredOpExecute.subst(vnmulSIop);
830
831 vnmulDCode = vfpEnabledCheckCode + '''
832 FPSCR fpscr = (FPSCR) FpscrExc;
833 double dest = -binaryOp(fpscr, dbl(FpOp1P0_uw, FpOp1P1_uw),
834 dbl(FpOp2P0_uw, FpOp2P1_uw),
835 fpMulD, fpscr.fz, fpscr.dn,
836 fpscr.rMode);
837 FpDestP0_uw = dblLow(dest);
838 FpDestP1_uw = dblHi(dest);
839 FpscrExc = fpscr;
840 '''
841 vnmulDIop = InstObjParams("vnmuld", "VnmulD", "FpRegRegRegOp",
842 { "code": vnmulDCode,
843 "predicate_test": predicateTest,
844 "op_class": "SimdFloatMultOp" }, [])
845 header_output += FpRegRegRegOpDeclare.subst(vnmulDIop);
846 decoder_output += FpRegRegRegOpConstructor.subst(vnmulDIop);
847 exec_output += PredOpExecute.subst(vnmulDIop);
848}};
849
850let {{
851
852 header_output = ""
853 decoder_output = ""
854 exec_output = ""
855
856 vcvtUIntFpSCode = vfpEnabledCheckCode + '''
857 FPSCR fpscr = (FPSCR) FpscrExc;
858 VfpSavedState state = prepFpState(fpscr.rMode);
859 __asm__ __volatile__("" : "=m" (FpOp1_uw) : "m" (FpOp1_uw));
860 FpDest = FpOp1_uw;
861 __asm__ __volatile__("" :: "m" (FpDest));
862 finishVfp(fpscr, state, fpscr.fz);
863 FpscrExc = fpscr;
864 '''
865 vcvtUIntFpSIop = InstObjParams("vcvt", "VcvtUIntFpS", "FpRegRegOp",
866 { "code": vcvtUIntFpSCode,
867 "predicate_test": predicateTest,
868 "op_class": "SimdFloatCvtOp" }, [])
869 header_output += FpRegRegOpDeclare.subst(vcvtUIntFpSIop);
870 decoder_output += FpRegRegOpConstructor.subst(vcvtUIntFpSIop);
871 exec_output += PredOpExecute.subst(vcvtUIntFpSIop);
872
873 vcvtUIntFpDCode = vfpEnabledCheckCode + '''
874 FPSCR fpscr = (FPSCR) FpscrExc;
875 VfpSavedState state = prepFpState(fpscr.rMode);
876 __asm__ __volatile__("" : "=m" (FpOp1P0_uw) : "m" (FpOp1P0_uw));
877 double cDest = (uint64_t)FpOp1P0_uw;
878 __asm__ __volatile__("" :: "m" (cDest));
879 finishVfp(fpscr, state, fpscr.fz);
880 FpDestP0_uw = dblLow(cDest);
881 FpDestP1_uw = dblHi(cDest);
882 FpscrExc = fpscr;
883 '''
884 vcvtUIntFpDIop = InstObjParams("vcvt", "VcvtUIntFpD", "FpRegRegOp",
885 { "code": vcvtUIntFpDCode,
886 "predicate_test": predicateTest,
887 "op_class": "SimdFloatCvtOp" }, [])
888 header_output += FpRegRegOpDeclare.subst(vcvtUIntFpDIop);
889 decoder_output += FpRegRegOpConstructor.subst(vcvtUIntFpDIop);
890 exec_output += PredOpExecute.subst(vcvtUIntFpDIop);
891
892 vcvtSIntFpSCode = vfpEnabledCheckCode + '''
893 FPSCR fpscr = (FPSCR) FpscrExc;
894 VfpSavedState state = prepFpState(fpscr.rMode);
895 __asm__ __volatile__("" : "=m" (FpOp1_sw) : "m" (FpOp1_sw));
896 FpDest = FpOp1_sw;
897 __asm__ __volatile__("" :: "m" (FpDest));
898 finishVfp(fpscr, state, fpscr.fz);
899 FpscrExc = fpscr;
900 '''
901 vcvtSIntFpSIop = InstObjParams("vcvt", "VcvtSIntFpS", "FpRegRegOp",
902 { "code": vcvtSIntFpSCode,
903 "predicate_test": predicateTest,
904 "op_class": "SimdFloatCvtOp" }, [])
905 header_output += FpRegRegOpDeclare.subst(vcvtSIntFpSIop);
906 decoder_output += FpRegRegOpConstructor.subst(vcvtSIntFpSIop);
907 exec_output += PredOpExecute.subst(vcvtSIntFpSIop);
908
909 vcvtSIntFpDCode = vfpEnabledCheckCode + '''
910 FPSCR fpscr = (FPSCR) FpscrExc;
911 VfpSavedState state = prepFpState(fpscr.rMode);
912 __asm__ __volatile__("" : "=m" (FpOp1P0_sw) : "m" (FpOp1P0_sw));
913 double cDest = FpOp1P0_sw;
914 __asm__ __volatile__("" :: "m" (cDest));
915 finishVfp(fpscr, state, fpscr.fz);
916 FpDestP0_uw = dblLow(cDest);
917 FpDestP1_uw = dblHi(cDest);
918 FpscrExc = fpscr;
919 '''
920 vcvtSIntFpDIop = InstObjParams("vcvt", "VcvtSIntFpD", "FpRegRegOp",
921 { "code": vcvtSIntFpDCode,
922 "predicate_test": predicateTest,
923 "op_class": "SimdFloatCvtOp" }, [])
924 header_output += FpRegRegOpDeclare.subst(vcvtSIntFpDIop);
925 decoder_output += FpRegRegOpConstructor.subst(vcvtSIntFpDIop);
926 exec_output += PredOpExecute.subst(vcvtSIntFpDIop);
927
928 vcvtFpUIntSRCode = vfpEnabledCheckCode + '''
929 FPSCR fpscr = (FPSCR) FpscrExc;
930 VfpSavedState state = prepFpState(fpscr.rMode);
931 vfpFlushToZero(fpscr, FpOp1);
932 __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
933 FpDest_uw = vfpFpToFixed<float>(FpOp1, false, 32, 0, false);
934 __asm__ __volatile__("" :: "m" (FpDest_uw));
935 finishVfp(fpscr, state, fpscr.fz);
936 FpscrExc = fpscr;
937 '''
938 vcvtFpUIntSRIop = InstObjParams("vcvt", "VcvtFpUIntSR", "FpRegRegOp",
939 { "code": vcvtFpUIntSRCode,
940 "predicate_test": predicateTest,
941 "op_class": "SimdFloatCvtOp" }, [])
942 header_output += FpRegRegOpDeclare.subst(vcvtFpUIntSRIop);
943 decoder_output += FpRegRegOpConstructor.subst(vcvtFpUIntSRIop);
944 exec_output += PredOpExecute.subst(vcvtFpUIntSRIop);
945
946 vcvtFpUIntDRCode = vfpEnabledCheckCode + '''
947 FPSCR fpscr = (FPSCR) FpscrExc;
948 double cOp1 = dbl(FpOp1P0_uw, FpOp1P1_uw);
949 vfpFlushToZero(fpscr, cOp1);
950 VfpSavedState state = prepFpState(fpscr.rMode);
951 __asm__ __volatile__("" : "=m" (cOp1) : "m" (cOp1));
952 uint64_t result = vfpFpToFixed<double>(cOp1, false, 32, 0, false);
953 __asm__ __volatile__("" :: "m" (result));
954 finishVfp(fpscr, state, fpscr.fz);
955 FpDestP0_uw = result;
956 FpscrExc = fpscr;
957 '''
958 vcvtFpUIntDRIop = InstObjParams("vcvtr", "VcvtFpUIntDR", "FpRegRegOp",
959 { "code": vcvtFpUIntDRCode,
960 "predicate_test": predicateTest,
961 "op_class": "SimdFloatCvtOp" }, [])
962 header_output += FpRegRegOpDeclare.subst(vcvtFpUIntDRIop);
963 decoder_output += FpRegRegOpConstructor.subst(vcvtFpUIntDRIop);
964 exec_output += PredOpExecute.subst(vcvtFpUIntDRIop);
965
966 vcvtFpSIntSRCode = vfpEnabledCheckCode + '''
967 FPSCR fpscr = (FPSCR) FpscrExc;
968 VfpSavedState state = prepFpState(fpscr.rMode);
969 vfpFlushToZero(fpscr, FpOp1);
970 __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
971 FpDest_sw = vfpFpToFixed<float>(FpOp1, true, 32, 0, false);
972 __asm__ __volatile__("" :: "m" (FpDest_sw));
973 finishVfp(fpscr, state, fpscr.fz);
974 FpscrExc = fpscr;
975 '''
976 vcvtFpSIntSRIop = InstObjParams("vcvtr", "VcvtFpSIntSR", "FpRegRegOp",
977 { "code": vcvtFpSIntSRCode,
978 "predicate_test": predicateTest,
979 "op_class": "SimdFloatCvtOp" }, [])
980 header_output += FpRegRegOpDeclare.subst(vcvtFpSIntSRIop);
981 decoder_output += FpRegRegOpConstructor.subst(vcvtFpSIntSRIop);
982 exec_output += PredOpExecute.subst(vcvtFpSIntSRIop);
983
984 vcvtFpSIntDRCode = vfpEnabledCheckCode + '''
985 FPSCR fpscr = (FPSCR) FpscrExc;
986 double cOp1 = dbl(FpOp1P0_uw, FpOp1P1_uw);
987 vfpFlushToZero(fpscr, cOp1);
988 VfpSavedState state = prepFpState(fpscr.rMode);
989 __asm__ __volatile__("" : "=m" (cOp1) : "m" (cOp1));
990 int64_t result = vfpFpToFixed<double>(cOp1, true, 32, 0, false);
991 __asm__ __volatile__("" :: "m" (result));
992 finishVfp(fpscr, state, fpscr.fz);
993 FpDestP0_uw = result;
994 FpscrExc = fpscr;
995 '''
996 vcvtFpSIntDRIop = InstObjParams("vcvtr", "VcvtFpSIntDR", "FpRegRegOp",
997 { "code": vcvtFpSIntDRCode,
998 "predicate_test": predicateTest,
999 "op_class": "SimdFloatCvtOp" }, [])
1000 header_output += FpRegRegOpDeclare.subst(vcvtFpSIntDRIop);
1001 decoder_output += FpRegRegOpConstructor.subst(vcvtFpSIntDRIop);
1002 exec_output += PredOpExecute.subst(vcvtFpSIntDRIop);
1003
1004 vcvtFpUIntSCode = vfpEnabledCheckCode + '''
1005 FPSCR fpscr = (FPSCR) FpscrExc;
1006 vfpFlushToZero(fpscr, FpOp1);
1007 VfpSavedState state = prepFpState(fpscr.rMode);
1008 fesetround(FeRoundZero);
1009 __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
1010 FpDest_uw = vfpFpToFixed<float>(FpOp1, false, 32, 0);
1011 __asm__ __volatile__("" :: "m" (FpDest_uw));
1012 finishVfp(fpscr, state, fpscr.fz);
1013 FpscrExc = fpscr;
1014 '''
1015 vcvtFpUIntSIop = InstObjParams("vcvt", "VcvtFpUIntS", "FpRegRegOp",
1016 { "code": vcvtFpUIntSCode,
1017 "predicate_test": predicateTest,
1018 "op_class": "SimdFloatCvtOp" }, [])
1019 header_output += FpRegRegOpDeclare.subst(vcvtFpUIntSIop);
1020 decoder_output += FpRegRegOpConstructor.subst(vcvtFpUIntSIop);
1021 exec_output += PredOpExecute.subst(vcvtFpUIntSIop);
1022
1023 vcvtFpUIntDCode = vfpEnabledCheckCode + '''
1024 FPSCR fpscr = (FPSCR) FpscrExc;
1025 double cOp1 = dbl(FpOp1P0_uw, FpOp1P1_uw);
1026 vfpFlushToZero(fpscr, cOp1);
1027 VfpSavedState state = prepFpState(fpscr.rMode);
1028 fesetround(FeRoundZero);
1029 __asm__ __volatile__("" : "=m" (cOp1) : "m" (cOp1));
1030 uint64_t result = vfpFpToFixed<double>(cOp1, false, 32, 0);
1031 __asm__ __volatile__("" :: "m" (result));
1032 finishVfp(fpscr, state, fpscr.fz);
1033 FpDestP0_uw = result;
1034 FpscrExc = fpscr;
1035 '''
1036 vcvtFpUIntDIop = InstObjParams("vcvt", "VcvtFpUIntD", "FpRegRegOp",
1037 { "code": vcvtFpUIntDCode,
1038 "predicate_test": predicateTest,
1039 "op_class": "SimdFloatCvtOp" }, [])
1040 header_output += FpRegRegOpDeclare.subst(vcvtFpUIntDIop);
1041 decoder_output += FpRegRegOpConstructor.subst(vcvtFpUIntDIop);
1042 exec_output += PredOpExecute.subst(vcvtFpUIntDIop);
1043
1044 vcvtFpSIntSCode = vfpEnabledCheckCode + '''
1045 FPSCR fpscr = (FPSCR) FpscrExc;
1046 vfpFlushToZero(fpscr, FpOp1);
1047 VfpSavedState state = prepFpState(fpscr.rMode);
1048 fesetround(FeRoundZero);
1049 __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
1050 FpDest_sw = vfpFpToFixed<float>(FpOp1, true, 32, 0);
1051 __asm__ __volatile__("" :: "m" (FpDest_sw));
1052 finishVfp(fpscr, state, fpscr.fz);
1053 FpscrExc = fpscr;
1054 '''
1055 vcvtFpSIntSIop = InstObjParams("vcvt", "VcvtFpSIntS", "FpRegRegOp",
1056 { "code": vcvtFpSIntSCode,
1057 "predicate_test": predicateTest,
1058 "op_class": "SimdFloatCvtOp" }, [])
1059 header_output += FpRegRegOpDeclare.subst(vcvtFpSIntSIop);
1060 decoder_output += FpRegRegOpConstructor.subst(vcvtFpSIntSIop);
1061 exec_output += PredOpExecute.subst(vcvtFpSIntSIop);
1062
1063 vcvtFpSIntDCode = vfpEnabledCheckCode + '''
1064 FPSCR fpscr = (FPSCR) FpscrExc;
1065 double cOp1 = dbl(FpOp1P0_uw, FpOp1P1_uw);
1066 vfpFlushToZero(fpscr, cOp1);
1067 VfpSavedState state = prepFpState(fpscr.rMode);
1068 fesetround(FeRoundZero);
1069 __asm__ __volatile__("" : "=m" (cOp1) : "m" (cOp1));
1070 int64_t result = vfpFpToFixed<double>(cOp1, true, 32, 0);
1071 __asm__ __volatile__("" :: "m" (result));
1072 finishVfp(fpscr, state, fpscr.fz);
1073 FpDestP0_uw = result;
1074 FpscrExc = fpscr;
1075 '''
1076 vcvtFpSIntDIop = InstObjParams("vcvt", "VcvtFpSIntD", "FpRegRegOp",
1077 { "code": vcvtFpSIntDCode,
1078 "predicate_test": predicateTest,
1079 "op_class": "SimdFloatCvtOp" }, [])
1080 header_output += FpRegRegOpDeclare.subst(vcvtFpSIntDIop);
1081 decoder_output += FpRegRegOpConstructor.subst(vcvtFpSIntDIop);
1082 exec_output += PredOpExecute.subst(vcvtFpSIntDIop);
1083
1084 vcvtFpSFpDCode = vfpEnabledCheckCode + '''
1085 FPSCR fpscr = (FPSCR) FpscrExc;
1086 vfpFlushToZero(fpscr, FpOp1);
1087 VfpSavedState state = prepFpState(fpscr.rMode);
1088 __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
1089 double cDest = fixFpSFpDDest(FpscrExc, FpOp1);
1090 __asm__ __volatile__("" :: "m" (cDest));
1091 finishVfp(fpscr, state, fpscr.fz);
1092 FpDestP0_uw = dblLow(cDest);
1093 FpDestP1_uw = dblHi(cDest);
1094 FpscrExc = fpscr;
1095 '''
1096 vcvtFpSFpDIop = InstObjParams("vcvt", "VcvtFpSFpD", "FpRegRegOp",
1097 { "code": vcvtFpSFpDCode,
1098 "predicate_test": predicateTest,
1099 "op_class": "SimdFloatCvtOp" }, [])
1100 header_output += FpRegRegOpDeclare.subst(vcvtFpSFpDIop);
1101 decoder_output += FpRegRegOpConstructor.subst(vcvtFpSFpDIop);
1102 exec_output += PredOpExecute.subst(vcvtFpSFpDIop);
1103
1104 vcvtFpDFpSCode = vfpEnabledCheckCode + '''
1105 FPSCR fpscr = (FPSCR) FpscrExc;
1106 double cOp1 = dbl(FpOp1P0_uw, FpOp1P1_uw);
1107 vfpFlushToZero(fpscr, cOp1);
1108 VfpSavedState state = prepFpState(fpscr.rMode);
1109 __asm__ __volatile__("" : "=m" (cOp1) : "m" (cOp1));
1110 FpDest = fixFpDFpSDest(FpscrExc, cOp1);
1111 __asm__ __volatile__("" :: "m" (FpDest));
1112 finishVfp(fpscr, state, fpscr.fz);
1113 FpscrExc = fpscr;
1114 '''
1115 vcvtFpDFpSIop = InstObjParams("vcvt", "VcvtFpDFpS", "FpRegRegOp",
1116 { "code": vcvtFpDFpSCode,
1117 "predicate_test": predicateTest,
1118 "op_class": "SimdFloatCvtOp" }, [])
1119 header_output += FpRegRegOpDeclare.subst(vcvtFpDFpSIop);
1120 decoder_output += FpRegRegOpConstructor.subst(vcvtFpDFpSIop);
1121 exec_output += PredOpExecute.subst(vcvtFpDFpSIop);
1122
1123 vcvtFpHTFpSCode = vfpEnabledCheckCode + '''
1124 FPSCR fpscr = (FPSCR) FpscrExc;
1125 vfpFlushToZero(fpscr, FpOp1);
1126 VfpSavedState state = prepFpState(fpscr.rMode);
1127 __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
1128 FpDest = vcvtFpHFpS(fpscr, fpscr.dn, fpscr.ahp,
1129 bits(fpToBits(FpOp1), 31, 16));
1130 __asm__ __volatile__("" :: "m" (FpDest));
1131 finishVfp(fpscr, state, fpscr.fz);
1132 FpscrExc = fpscr;
1133 '''
1134 vcvtFpHTFpSIop = InstObjParams("vcvtt", "VcvtFpHTFpS", "FpRegRegOp",
1135 { "code": vcvtFpHTFpSCode,
1136 "predicate_test": predicateTest,
1137 "op_class": "SimdFloatCvtOp" }, [])
1138 header_output += FpRegRegOpDeclare.subst(vcvtFpHTFpSIop);
1139 decoder_output += FpRegRegOpConstructor.subst(vcvtFpHTFpSIop);
1140 exec_output += PredOpExecute.subst(vcvtFpHTFpSIop);
1141
1142 vcvtFpHBFpSCode = vfpEnabledCheckCode + '''
1143 FPSCR fpscr = (FPSCR) FpscrExc;
1144 VfpSavedState state = prepFpState(fpscr.rMode);
1145 __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
1146 FpDest = vcvtFpHFpS(fpscr, fpscr.dn, fpscr.ahp,
1147 bits(fpToBits(FpOp1), 15, 0));
1148 __asm__ __volatile__("" :: "m" (FpDest));
1149 finishVfp(fpscr, state, fpscr.fz);
1150 FpscrExc = fpscr;
1151 '''
1152 vcvtFpHBFpSIop = InstObjParams("vcvtb", "VcvtFpHBFpS", "FpRegRegOp",
1153 { "code": vcvtFpHBFpSCode,
1154 "predicate_test": predicateTest,
1155 "op_class": "SimdFloatCvtOp" }, [])
1156 header_output += FpRegRegOpDeclare.subst(vcvtFpHBFpSIop);
1157 decoder_output += FpRegRegOpConstructor.subst(vcvtFpHBFpSIop);
1158 exec_output += PredOpExecute.subst(vcvtFpHBFpSIop);
1159
1160 vcvtFpSFpHTCode = vfpEnabledCheckCode + '''
1161 FPSCR fpscr = (FPSCR) FpscrExc;
1162 vfpFlushToZero(fpscr, FpOp1);
1163 VfpSavedState state = prepFpState(fpscr.rMode);
1164 __asm__ __volatile__("" : "=m" (FpOp1), "=m" (FpDest_uw)
1165 : "m" (FpOp1), "m" (FpDest_uw));
1166 FpDest_uw = insertBits(FpDest_uw, 31, 16,,
1167 vcvtFpSFpH(fpscr, fpscr.fz, fpscr.dn,
1168 fpscr.rMode, fpscr.ahp, FpOp1));
1169 __asm__ __volatile__("" :: "m" (FpDest_uw));
1170 finishVfp(fpscr, state, fpscr.fz);
1171 FpscrExc = fpscr;
1172 '''
1173 vcvtFpSFpHTIop = InstObjParams("vcvtt", "VcvtFpSFpHT", "FpRegRegOp",
1174 { "code": vcvtFpHTFpSCode,
1175 "predicate_test": predicateTest,
1176 "op_class": "SimdFloatCvtOp" }, [])
1177 header_output += FpRegRegOpDeclare.subst(vcvtFpSFpHTIop);
1178 decoder_output += FpRegRegOpConstructor.subst(vcvtFpSFpHTIop);
1179 exec_output += PredOpExecute.subst(vcvtFpSFpHTIop);
1180
1181 vcvtFpSFpHBCode = vfpEnabledCheckCode + '''
1182 FPSCR fpscr = (FPSCR) FpscrExc;
1183 vfpFlushToZero(fpscr, FpOp1);
1184 VfpSavedState state = prepFpState(fpscr.rMode);
1185 __asm__ __volatile__("" : "=m" (FpOp1), "=m" (FpDest_uw)
1186 : "m" (FpOp1), "m" (FpDest_uw));
1187 FpDest_uw = insertBits(FpDest_uw, 15, 0,
1188 vcvtFpSFpH(fpscr, fpscr.fz, fpscr.dn,
1189 fpscr.rMode, fpscr.ahp, FpOp1));
1190 __asm__ __volatile__("" :: "m" (FpDest_uw));
1191 finishVfp(fpscr, state, fpscr.fz);
1192 FpscrExc = fpscr;
1193 '''
1194 vcvtFpSFpHBIop = InstObjParams("vcvtb", "VcvtFpSFpHB", "FpRegRegOp",
1195 { "code": vcvtFpSFpHBCode,
1196 "predicate_test": predicateTest,
1197 "op_class": "SimdFloatCvtOp" }, [])
1198 header_output += FpRegRegOpDeclare.subst(vcvtFpSFpHBIop);
1199 decoder_output += FpRegRegOpConstructor.subst(vcvtFpSFpHBIop);
1200 exec_output += PredOpExecute.subst(vcvtFpSFpHBIop);
1201
1202 vcmpSCode = vfpEnabledCheckCode + '''
1203 FPSCR fpscr = (FPSCR) FpscrExc;
1204 vfpFlushToZero(fpscr, FpDest, FpOp1);
1205 if (FpDest == FpOp1) {
1206 fpscr.n = 0; fpscr.z = 1; fpscr.c = 1; fpscr.v = 0;
1207 } else if (FpDest < FpOp1) {
1208 fpscr.n = 1; fpscr.z = 0; fpscr.c = 0; fpscr.v = 0;
1209 } else if (FpDest > FpOp1) {
1210 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 0;
1211 } else {
1212 const uint32_t qnan = 0x7fc00000;
1213 const bool nan1 = std::isnan(FpDest);
1214 const bool signal1 = nan1 && ((fpToBits(FpDest) & qnan) != qnan);
1215 const bool nan2 = std::isnan(FpOp1);
1216 const bool signal2 = nan2 && ((fpToBits(FpOp1) & qnan) != qnan);
1217 if (signal1 || signal2)
1218 fpscr.ioc = 1;
1219 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 1;
1220 }
1221 FpCondCodes = fpscr & FpCondCodesMask;
1222 FpscrExc = fpscr;
1223 '''
1224 vcmpSIop = InstObjParams("vcmps", "VcmpS", "FpRegRegOp",
1225 { "code": vcmpSCode,
1226 "predicate_test": predicateTest,
1227 "op_class": "SimdFloatCmpOp" }, [])
1228 header_output += FpRegRegOpDeclare.subst(vcmpSIop);
1229 decoder_output += FpRegRegOpConstructor.subst(vcmpSIop);
1230 exec_output += PredOpExecute.subst(vcmpSIop);
1231
1232 vcmpDCode = vfpEnabledCheckCode + '''
1233 double cOp1 = dbl(FpOp1P0_uw, FpOp1P1_uw);
1234 double cDest = dbl(FpDestP0_uw, FpDestP1_uw);
1235 FPSCR fpscr = (FPSCR) FpscrExc;
1236 vfpFlushToZero(fpscr, cDest, cOp1);
1237 if (cDest == cOp1) {
1238 fpscr.n = 0; fpscr.z = 1; fpscr.c = 1; fpscr.v = 0;
1239 } else if (cDest < cOp1) {
1240 fpscr.n = 1; fpscr.z = 0; fpscr.c = 0; fpscr.v = 0;
1241 } else if (cDest > cOp1) {
1242 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 0;
1243 } else {
1244 const uint64_t qnan = ULL(0x7ff8000000000000);
1245 const bool nan1 = std::isnan(cDest);
1246 const bool signal1 = nan1 && ((fpToBits(cDest) & qnan) != qnan);
1247 const bool nan2 = std::isnan(cOp1);
1248 const bool signal2 = nan2 && ((fpToBits(cOp1) & qnan) != qnan);
1249 if (signal1 || signal2)
1250 fpscr.ioc = 1;
1251 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 1;
1252 }
1253 FpCondCodes = fpscr & FpCondCodesMask;
1254 FpscrExc = fpscr;
1255 '''
1256 vcmpDIop = InstObjParams("vcmpd", "VcmpD", "FpRegRegOp",
1257 { "code": vcmpDCode,
1258 "predicate_test": predicateTest,
1259 "op_class": "SimdFloatCmpOp" }, [])
1260 header_output += FpRegRegOpDeclare.subst(vcmpDIop);
1261 decoder_output += FpRegRegOpConstructor.subst(vcmpDIop);
1262 exec_output += PredOpExecute.subst(vcmpDIop);
1263
1264 vcmpZeroSCode = vfpEnabledCheckCode + '''
1265 FPSCR fpscr = (FPSCR) FpscrExc;
1266 vfpFlushToZero(fpscr, FpDest);
1267 // This only handles imm == 0 for now.
1268 assert(imm == 0);
1269 if (FpDest == imm) {
1270 fpscr.n = 0; fpscr.z = 1; fpscr.c = 1; fpscr.v = 0;
1271 } else if (FpDest < imm) {
1272 fpscr.n = 1; fpscr.z = 0; fpscr.c = 0; fpscr.v = 0;
1273 } else if (FpDest > imm) {
1274 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 0;
1275 } else {
1276 const uint32_t qnan = 0x7fc00000;
1277 const bool nan = std::isnan(FpDest);
1278 const bool signal = nan && ((fpToBits(FpDest) & qnan) != qnan);
1279 if (signal)
1280 fpscr.ioc = 1;
1281 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 1;
1282 }
1283 FpCondCodes = fpscr & FpCondCodesMask;
1284 FpscrExc = fpscr;
1285 '''
1286 vcmpZeroSIop = InstObjParams("vcmpZeros", "VcmpZeroS", "FpRegImmOp",
1287 { "code": vcmpZeroSCode,
1288 "predicate_test": predicateTest,
1289 "op_class": "SimdFloatCmpOp" }, [])
1290 header_output += FpRegImmOpDeclare.subst(vcmpZeroSIop);
1291 decoder_output += FpRegImmOpConstructor.subst(vcmpZeroSIop);
1292 exec_output += PredOpExecute.subst(vcmpZeroSIop);
1293
1294 vcmpZeroDCode = vfpEnabledCheckCode + '''
1295 // This only handles imm == 0 for now.
1296 assert(imm == 0);
1297 double cDest = dbl(FpDestP0_uw, FpDestP1_uw);
1298 FPSCR fpscr = (FPSCR) FpscrExc;
1299 vfpFlushToZero(fpscr, cDest);
1300 if (cDest == imm) {
1301 fpscr.n = 0; fpscr.z = 1; fpscr.c = 1; fpscr.v = 0;
1302 } else if (cDest < imm) {
1303 fpscr.n = 1; fpscr.z = 0; fpscr.c = 0; fpscr.v = 0;
1304 } else if (cDest > imm) {
1305 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 0;
1306 } else {
1307 const uint64_t qnan = ULL(0x7ff8000000000000);
1308 const bool nan = std::isnan(cDest);
1309 const bool signal = nan && ((fpToBits(cDest) & qnan) != qnan);
1310 if (signal)
1311 fpscr.ioc = 1;
1312 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 1;
1313 }
1314 FpCondCodes = fpscr & FpCondCodesMask;
1315 FpscrExc = fpscr;
1316 '''
1317 vcmpZeroDIop = InstObjParams("vcmpZerod", "VcmpZeroD", "FpRegImmOp",
1318 { "code": vcmpZeroDCode,
1319 "predicate_test": predicateTest,
1320 "op_class": "SimdFloatCmpOp" }, [])
1321 header_output += FpRegImmOpDeclare.subst(vcmpZeroDIop);
1322 decoder_output += FpRegImmOpConstructor.subst(vcmpZeroDIop);
1323 exec_output += PredOpExecute.subst(vcmpZeroDIop);
1324
1325 vcmpeSCode = vfpEnabledCheckCode + '''
1326 FPSCR fpscr = (FPSCR) FpscrExc;
1327 vfpFlushToZero(fpscr, FpDest, FpOp1);
1328 if (FpDest == FpOp1) {
1329 fpscr.n = 0; fpscr.z = 1; fpscr.c = 1; fpscr.v = 0;
1330 } else if (FpDest < FpOp1) {
1331 fpscr.n = 1; fpscr.z = 0; fpscr.c = 0; fpscr.v = 0;
1332 } else if (FpDest > FpOp1) {
1333 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 0;
1334 } else {
1335 fpscr.ioc = 1;
1336 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 1;
1337 }
1338 FpCondCodes = fpscr & FpCondCodesMask;
1339 FpscrExc = fpscr;
1340 '''
1341 vcmpeSIop = InstObjParams("vcmpes", "VcmpeS", "FpRegRegOp",
1342 { "code": vcmpeSCode,
1343 "predicate_test": predicateTest,
1344 "op_class": "SimdFloatCmpOp" }, [])
1345 header_output += FpRegRegOpDeclare.subst(vcmpeSIop);
1346 decoder_output += FpRegRegOpConstructor.subst(vcmpeSIop);
1347 exec_output += PredOpExecute.subst(vcmpeSIop);
1348
1349 vcmpeDCode = vfpEnabledCheckCode + '''
1350 double cOp1 = dbl(FpOp1P0_uw, FpOp1P1_uw);
1351 double cDest = dbl(FpDestP0_uw, FpDestP1_uw);
1352 FPSCR fpscr = (FPSCR) FpscrExc;
1353 vfpFlushToZero(fpscr, cDest, cOp1);
1354 if (cDest == cOp1) {
1355 fpscr.n = 0; fpscr.z = 1; fpscr.c = 1; fpscr.v = 0;
1356 } else if (cDest < cOp1) {
1357 fpscr.n = 1; fpscr.z = 0; fpscr.c = 0; fpscr.v = 0;
1358 } else if (cDest > cOp1) {
1359 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 0;
1360 } else {
1361 fpscr.ioc = 1;
1362 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 1;
1363 }
1364 FpCondCodes = fpscr & FpCondCodesMask;
1365 FpscrExc = fpscr;
1366 '''
1367 vcmpeDIop = InstObjParams("vcmped", "VcmpeD", "FpRegRegOp",
1368 { "code": vcmpeDCode,
1369 "predicate_test": predicateTest,
1370 "op_class": "SimdFloatCmpOp" }, [])
1371 header_output += FpRegRegOpDeclare.subst(vcmpeDIop);
1372 decoder_output += FpRegRegOpConstructor.subst(vcmpeDIop);
1373 exec_output += PredOpExecute.subst(vcmpeDIop);
1374
1375 vcmpeZeroSCode = vfpEnabledCheckCode + '''
1376 FPSCR fpscr = (FPSCR) FpscrExc;
1377 vfpFlushToZero(fpscr, FpDest);
1378 if (FpDest == imm) {
1379 fpscr.n = 0; fpscr.z = 1; fpscr.c = 1; fpscr.v = 0;
1380 } else if (FpDest < imm) {
1381 fpscr.n = 1; fpscr.z = 0; fpscr.c = 0; fpscr.v = 0;
1382 } else if (FpDest > imm) {
1383 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 0;
1384 } else {
1385 fpscr.ioc = 1;
1386 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 1;
1387 }
1388 FpCondCodes = fpscr & FpCondCodesMask;
1389 FpscrExc = fpscr;
1390 '''
1391 vcmpeZeroSIop = InstObjParams("vcmpeZeros", "VcmpeZeroS", "FpRegImmOp",
1392 { "code": vcmpeZeroSCode,
1393 "predicate_test": predicateTest,
1394 "op_class": "SimdFloatCmpOp" }, [])
1395 header_output += FpRegImmOpDeclare.subst(vcmpeZeroSIop);
1396 decoder_output += FpRegImmOpConstructor.subst(vcmpeZeroSIop);
1397 exec_output += PredOpExecute.subst(vcmpeZeroSIop);
1398
1399 vcmpeZeroDCode = vfpEnabledCheckCode + '''
1400 double cDest = dbl(FpDestP0_uw, FpDestP1_uw);
1401 FPSCR fpscr = (FPSCR) FpscrExc;
1402 vfpFlushToZero(fpscr, cDest);
1403 if (cDest == imm) {
1404 fpscr.n = 0; fpscr.z = 1; fpscr.c = 1; fpscr.v = 0;
1405 } else if (cDest < imm) {
1406 fpscr.n = 1; fpscr.z = 0; fpscr.c = 0; fpscr.v = 0;
1407 } else if (cDest > imm) {
1408 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 0;
1409 } else {
1410 fpscr.ioc = 1;
1411 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 1;
1412 }
1413 FpCondCodes = fpscr & FpCondCodesMask;
1414 FpscrExc = fpscr;
1415 '''
1416 vcmpeZeroDIop = InstObjParams("vcmpeZerod", "VcmpeZeroD", "FpRegImmOp",
1417 { "code": vcmpeZeroDCode,
1418 "predicate_test": predicateTest,
1419 "op_class": "SimdFloatCmpOp" }, [])
1420 header_output += FpRegImmOpDeclare.subst(vcmpeZeroDIop);
1421 decoder_output += FpRegImmOpConstructor.subst(vcmpeZeroDIop);
1422 exec_output += PredOpExecute.subst(vcmpeZeroDIop);
1423}};
1424
1425let {{
1426
1427 header_output = ""
1428 decoder_output = ""
1429 exec_output = ""
1430
1431 vselSCode = vfpEnabledCheckCode + '''
1432 if (testPredicate(CondCodesNZ, CondCodesC, CondCodesV, cond)) {
1433 FpDest = FpOp1;
1434 } else {
1435 FpDest = FpOp2;
1436 } '''
1437
1438 vselSIop = InstObjParams("vsels", "VselS", "FpRegRegRegCondOp",
1439 { "code" : vselSCode,
1440 "predicate_test" : predicateTest,
1441 "op_class" : "SimdFloatCmpOp" }, [] )
1442 header_output += FpRegRegRegCondOpDeclare.subst(vselSIop);
1443 decoder_output += FpRegRegRegCondOpConstructor.subst(vselSIop);
1444 exec_output += PredOpExecute.subst(vselSIop);
1445
1446 vselDCode = vfpEnabledCheckCode + '''
1447 if (testPredicate(CondCodesNZ, CondCodesC, CondCodesV, cond)) {
1448 FpDestP0_uw = FpOp1P0_uw;
1449 FpDestP1_uw = FpOp1P1_uw;
1450 } else {
1451 FpDestP0_uw = FpOp2P0_uw;
1452 FpDestP1_uw = FpOp2P1_uw;
1453 } '''
1454
1455 vselDIop = InstObjParams("vseld", "VselD", "FpRegRegRegCondOp",
1456 { "code" : vselDCode,
1457 "predicate_test" : predicateTest,
1458 "op_class" : "SimdFloatCmpOp" }, [] )
1459 header_output += FpRegRegRegCondOpDeclare.subst(vselDIop);
1460 decoder_output += FpRegRegRegCondOpConstructor.subst(vselDIop);
1461 exec_output += PredOpExecute.subst(vselDIop);
1462}};
1463
1464
1465let {{
1466
1467 header_output = ""
1468 decoder_output = ""
1469 exec_output = ""
1470
1471 vcvtFpSFixedSCode = vfpEnabledCheckCode + '''
1472 FPSCR fpscr = (FPSCR) FpscrExc;
1473 vfpFlushToZero(fpscr, FpOp1);
1474 VfpSavedState state = prepFpState(fpscr.rMode);
1475 __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
1476 FpDest_sw = vfpFpToFixed<float>(FpOp1, true, 32, imm);
1477 __asm__ __volatile__("" :: "m" (FpDest_sw));
1478 finishVfp(fpscr, state, fpscr.fz);
1479 FpscrExc = fpscr;
1480 '''
1481 vcvtFpSFixedSIop = InstObjParams("vcvt", "VcvtFpSFixedS", "FpRegRegImmOp",
1482 { "code": vcvtFpSFixedSCode,
1483 "predicate_test": predicateTest,
1484 "op_class": "SimdFloatCvtOp" }, [])
1485 header_output += FpRegRegImmOpDeclare.subst(vcvtFpSFixedSIop);
1486 decoder_output += FpRegRegImmOpConstructor.subst(vcvtFpSFixedSIop);
1487 exec_output += PredOpExecute.subst(vcvtFpSFixedSIop);
1488
1489 vcvtFpSFixedDCode = vfpEnabledCheckCode + '''
1490 FPSCR fpscr = (FPSCR) FpscrExc;
1491 double cOp1 = dbl(FpOp1P0_uw, FpOp1P1_uw);
1492 vfpFlushToZero(fpscr, cOp1);
1493 VfpSavedState state = prepFpState(fpscr.rMode);
1494 __asm__ __volatile__("" : "=m" (cOp1) : "m" (cOp1));
1495 uint64_t mid = vfpFpToFixed<double>(cOp1, true, 32, imm);
1496 __asm__ __volatile__("" :: "m" (mid));
1497 finishVfp(fpscr, state, fpscr.fz);
1498 FpDestP0_uw = mid;
1499 FpDestP1_uw = mid >> 32;
1500 FpscrExc = fpscr;
1501 '''
1502 vcvtFpSFixedDIop = InstObjParams("vcvt", "VcvtFpSFixedD", "FpRegRegImmOp",
1503 { "code": vcvtFpSFixedDCode,
1504 "predicate_test": predicateTest,
1505 "op_class": "SimdFloatCvtOp" }, [])
1506 header_output += FpRegRegImmOpDeclare.subst(vcvtFpSFixedDIop);
1507 decoder_output += FpRegRegImmOpConstructor.subst(vcvtFpSFixedDIop);
1508 exec_output += PredOpExecute.subst(vcvtFpSFixedDIop);
1509
1510 vcvtFpUFixedSCode = vfpEnabledCheckCode + '''
1511 FPSCR fpscr = (FPSCR) FpscrExc;
1512 vfpFlushToZero(fpscr, FpOp1);
1513 VfpSavedState state = prepFpState(fpscr.rMode);
1514 __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
1515 FpDest_uw = vfpFpToFixed<float>(FpOp1, false, 32, imm);
1516 __asm__ __volatile__("" :: "m" (FpDest_uw));
1517 finishVfp(fpscr, state, fpscr.fz);
1518 FpscrExc = fpscr;
1519 '''
1520 vcvtFpUFixedSIop = InstObjParams("vcvt", "VcvtFpUFixedS", "FpRegRegImmOp",
1521 { "code": vcvtFpUFixedSCode,
1522 "predicate_test": predicateTest,
1523 "op_class": "SimdFloatCvtOp" }, [])
1524 header_output += FpRegRegImmOpDeclare.subst(vcvtFpUFixedSIop);
1525 decoder_output += FpRegRegImmOpConstructor.subst(vcvtFpUFixedSIop);
1526 exec_output += PredOpExecute.subst(vcvtFpUFixedSIop);
1527
1528 vcvtFpUFixedDCode = vfpEnabledCheckCode + '''
1529 FPSCR fpscr = (FPSCR) FpscrExc;
1530 double cOp1 = dbl(FpOp1P0_uw, FpOp1P1_uw);
1531 vfpFlushToZero(fpscr, cOp1);
1532 VfpSavedState state = prepFpState(fpscr.rMode);
1533 __asm__ __volatile__("" : "=m" (cOp1) : "m" (cOp1));
1534 uint64_t mid = vfpFpToFixed<double>(cOp1, false, 32, imm);
1535 __asm__ __volatile__("" :: "m" (mid));
1536 finishVfp(fpscr, state, fpscr.fz);
1537 FpDestP0_uw = mid;
1538 FpDestP1_uw = mid >> 32;
1539 FpscrExc = fpscr;
1540 '''
1541 vcvtFpUFixedDIop = InstObjParams("vcvt", "VcvtFpUFixedD", "FpRegRegImmOp",
1542 { "code": vcvtFpUFixedDCode,
1543 "predicate_test": predicateTest,
1544 "op_class": "SimdFloatCvtOp" }, [])
1545 header_output += FpRegRegImmOpDeclare.subst(vcvtFpUFixedDIop);
1546 decoder_output += FpRegRegImmOpConstructor.subst(vcvtFpUFixedDIop);
1547 exec_output += PredOpExecute.subst(vcvtFpUFixedDIop);
1548
1549 vcvtSFixedFpSCode = vfpEnabledCheckCode + '''
1550 FPSCR fpscr = (FPSCR) FpscrExc;
1551 VfpSavedState state = prepFpState(fpscr.rMode);
1552 __asm__ __volatile__("" : "=m" (FpOp1_sw) : "m" (FpOp1_sw));
1553 FpDest = vfpSFixedToFpS(fpscr.fz, fpscr.dn, FpOp1_sw, 32, imm);
1554 __asm__ __volatile__("" :: "m" (FpDest));
1555 finishVfp(fpscr, state, fpscr.fz);
1556 FpscrExc = fpscr;
1557 '''
1558 vcvtSFixedFpSIop = InstObjParams("vcvt", "VcvtSFixedFpS", "FpRegRegImmOp",
1559 { "code": vcvtSFixedFpSCode,
1560 "predicate_test": predicateTest,
1561 "op_class": "SimdFloatCvtOp" }, [])
1562 header_output += FpRegRegImmOpDeclare.subst(vcvtSFixedFpSIop);
1563 decoder_output += FpRegRegImmOpConstructor.subst(vcvtSFixedFpSIop);
1564 exec_output += PredOpExecute.subst(vcvtSFixedFpSIop);
1565
1566 vcvtSFixedFpDCode = vfpEnabledCheckCode + '''
1567 FPSCR fpscr = (FPSCR) FpscrExc;
1568 uint64_t mid = ((uint64_t)FpOp1P0_uw | ((uint64_t)FpOp1P1_uw << 32));
1569 VfpSavedState state = prepFpState(fpscr.rMode);
1570 __asm__ __volatile__("" : "=m" (mid) : "m" (mid));
1571 double cDest = vfpSFixedToFpD(fpscr.fz, fpscr.dn, mid, 32, imm);
1572 __asm__ __volatile__("" :: "m" (cDest));
1573 finishVfp(fpscr, state, fpscr.fz);
1574 FpDestP0_uw = dblLow(cDest);
1575 FpDestP1_uw = dblHi(cDest);
1576 FpscrExc = fpscr;
1577 '''
1578 vcvtSFixedFpDIop = InstObjParams("vcvt", "VcvtSFixedFpD", "FpRegRegImmOp",
1579 { "code": vcvtSFixedFpDCode,
1580 "predicate_test": predicateTest,
1581 "op_class": "SimdFloatCvtOp" }, [])
1582 header_output += FpRegRegImmOpDeclare.subst(vcvtSFixedFpDIop);
1583 decoder_output += FpRegRegImmOpConstructor.subst(vcvtSFixedFpDIop);
1584 exec_output += PredOpExecute.subst(vcvtSFixedFpDIop);
1585
1586 vcvtUFixedFpSCode = vfpEnabledCheckCode + '''
1587 FPSCR fpscr = (FPSCR) FpscrExc;
1588 VfpSavedState state = prepFpState(fpscr.rMode);
1589 __asm__ __volatile__("" : "=m" (FpOp1_uw) : "m" (FpOp1_uw));
1590 FpDest = vfpUFixedToFpS(fpscr.fz, fpscr.dn, FpOp1_uw, 32, imm);
1591 __asm__ __volatile__("" :: "m" (FpDest));
1592 finishVfp(fpscr, state, fpscr.fz);
1593 FpscrExc = fpscr;
1594 '''
1595 vcvtUFixedFpSIop = InstObjParams("vcvt", "VcvtUFixedFpS", "FpRegRegImmOp",
1596 { "code": vcvtUFixedFpSCode,
1597 "predicate_test": predicateTest,
1598 "op_class": "SimdFloatCvtOp" }, [])
1599 header_output += FpRegRegImmOpDeclare.subst(vcvtUFixedFpSIop);
1600 decoder_output += FpRegRegImmOpConstructor.subst(vcvtUFixedFpSIop);
1601 exec_output += PredOpExecute.subst(vcvtUFixedFpSIop);
1602
1603 vcvtUFixedFpDCode = vfpEnabledCheckCode + '''
1604 FPSCR fpscr = (FPSCR) FpscrExc;
1605 uint64_t mid = ((uint64_t)FpOp1P0_uw | ((uint64_t)FpOp1P1_uw << 32));
1606 VfpSavedState state = prepFpState(fpscr.rMode);
1607 __asm__ __volatile__("" : "=m" (mid) : "m" (mid));
1608 double cDest = vfpUFixedToFpD(fpscr.fz, fpscr.dn, mid, 32, imm);
1609 __asm__ __volatile__("" :: "m" (cDest));
1610 finishVfp(fpscr, state, fpscr.fz);
1611 FpDestP0_uw = dblLow(cDest);
1612 FpDestP1_uw = dblHi(cDest);
1613 FpscrExc = fpscr;
1614 '''
1615 vcvtUFixedFpDIop = InstObjParams("vcvt", "VcvtUFixedFpD", "FpRegRegImmOp",
1616 { "code": vcvtUFixedFpDCode,
1617 "predicate_test": predicateTest,
1618 "op_class": "SimdFloatCvtOp" }, [])
1619 header_output += FpRegRegImmOpDeclare.subst(vcvtUFixedFpDIop);
1620 decoder_output += FpRegRegImmOpConstructor.subst(vcvtUFixedFpDIop);
1621 exec_output += PredOpExecute.subst(vcvtUFixedFpDIop);
1622
1623 vcvtFpSHFixedSCode = vfpEnabledCheckCode + '''
1624 FPSCR fpscr = (FPSCR) FpscrExc;
1625 vfpFlushToZero(fpscr, FpOp1);
1626 VfpSavedState state = prepFpState(fpscr.rMode);
1627 __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
1628 FpDest_sh = vfpFpToFixed<float>(FpOp1, true, 16, imm);
1629 __asm__ __volatile__("" :: "m" (FpDest_sh));
1630 finishVfp(fpscr, state, fpscr.fz);
1631 FpscrExc = fpscr;
1632 '''
1633 vcvtFpSHFixedSIop = InstObjParams("vcvt", "VcvtFpSHFixedS",
1634 "FpRegRegImmOp",
1635 { "code": vcvtFpSHFixedSCode,
1636 "predicate_test": predicateTest,
1637 "op_class": "SimdFloatCvtOp" }, [])
1638 header_output += FpRegRegImmOpDeclare.subst(vcvtFpSHFixedSIop);
1639 decoder_output += FpRegRegImmOpConstructor.subst(vcvtFpSHFixedSIop);
1640 exec_output += PredOpExecute.subst(vcvtFpSHFixedSIop);
1641
1642 vcvtFpSHFixedDCode = vfpEnabledCheckCode + '''
1643 FPSCR fpscr = (FPSCR) FpscrExc;
1644 double cOp1 = dbl(FpOp1P0_uw, FpOp1P1_uw);
1645 vfpFlushToZero(fpscr, cOp1);
1646 VfpSavedState state = prepFpState(fpscr.rMode);
1647 __asm__ __volatile__("" : "=m" (cOp1) : "m" (cOp1));
1648 uint64_t result = vfpFpToFixed<double>(cOp1, true, 16, imm);
1649 __asm__ __volatile__("" :: "m" (result));
1650 finishVfp(fpscr, state, fpscr.fz);
1651 FpDestP0_uw = result;
1652 FpDestP1_uw = result >> 32;
1653 FpscrExc = fpscr;
1654 '''
1655 vcvtFpSHFixedDIop = InstObjParams("vcvt", "VcvtFpSHFixedD",
1656 "FpRegRegImmOp",
1657 { "code": vcvtFpSHFixedDCode,
1658 "predicate_test": predicateTest,
1659 "op_class": "SimdFloatCvtOp" }, [])
1660 header_output += FpRegRegImmOpDeclare.subst(vcvtFpSHFixedDIop);
1661 decoder_output += FpRegRegImmOpConstructor.subst(vcvtFpSHFixedDIop);
1662 exec_output += PredOpExecute.subst(vcvtFpSHFixedDIop);
1663
1664 vcvtFpUHFixedSCode = vfpEnabledCheckCode + '''
1665 FPSCR fpscr = (FPSCR) FpscrExc;
1666 vfpFlushToZero(fpscr, FpOp1);
1667 VfpSavedState state = prepFpState(fpscr.rMode);
1668 __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
1669 FpDest_uh = vfpFpToFixed<float>(FpOp1, false, 16, imm);
1670 __asm__ __volatile__("" :: "m" (FpDest_uh));
1671 finishVfp(fpscr, state, fpscr.fz);
1672 FpscrExc = fpscr;
1673 '''
1674 vcvtFpUHFixedSIop = InstObjParams("vcvt", "VcvtFpUHFixedS",
1675 "FpRegRegImmOp",
1676 { "code": vcvtFpUHFixedSCode,
1677 "predicate_test": predicateTest,
1678 "op_class": "SimdFloatCvtOp" }, [])
1679 header_output += FpRegRegImmOpDeclare.subst(vcvtFpUHFixedSIop);
1680 decoder_output += FpRegRegImmOpConstructor.subst(vcvtFpUHFixedSIop);
1681 exec_output += PredOpExecute.subst(vcvtFpUHFixedSIop);
1682
1683 vcvtFpUHFixedDCode = vfpEnabledCheckCode + '''
1684 FPSCR fpscr = (FPSCR) FpscrExc;
1685 double cOp1 = dbl(FpOp1P0_uw, FpOp1P1_uw);
1686 vfpFlushToZero(fpscr, cOp1);
1687 VfpSavedState state = prepFpState(fpscr.rMode);
1688 __asm__ __volatile__("" : "=m" (cOp1) : "m" (cOp1));
1689 uint64_t mid = vfpFpToFixed<double>(cOp1, false, 16, imm);
1690 __asm__ __volatile__("" :: "m" (mid));
1691 finishVfp(fpscr, state, fpscr.fz);
1692 FpDestP0_uw = mid;
1693 FpDestP1_uw = mid >> 32;
1694 FpscrExc = fpscr;
1695 '''
1696 vcvtFpUHFixedDIop = InstObjParams("vcvt", "VcvtFpUHFixedD",
1697 "FpRegRegImmOp",
1698 { "code": vcvtFpUHFixedDCode,
1699 "predicate_test": predicateTest,
1700 "op_class": "SimdFloatCvtOp" }, [])
1701 header_output += FpRegRegImmOpDeclare.subst(vcvtFpUHFixedDIop);
1702 decoder_output += FpRegRegImmOpConstructor.subst(vcvtFpUHFixedDIop);
1703 exec_output += PredOpExecute.subst(vcvtFpUHFixedDIop);
1704
1705 vcvtSHFixedFpSCode = vfpEnabledCheckCode + '''
1706 FPSCR fpscr = (FPSCR) FpscrExc;
1707 VfpSavedState state = prepFpState(fpscr.rMode);
1708 __asm__ __volatile__("" : "=m" (FpOp1_sh) : "m" (FpOp1_sh));
1709 FpDest = vfpSFixedToFpS(fpscr.fz, fpscr.dn, FpOp1_sh, 16, imm);
1710 __asm__ __volatile__("" :: "m" (FpDest));
1711 finishVfp(fpscr, state, fpscr.fz);
1712 FpscrExc = fpscr;
1713 '''
1714 vcvtSHFixedFpSIop = InstObjParams("vcvt", "VcvtSHFixedFpS",
1715 "FpRegRegImmOp",
1716 { "code": vcvtSHFixedFpSCode,
1717 "predicate_test": predicateTest,
1718 "op_class": "SimdFloatCvtOp" }, [])
1719 header_output += FpRegRegImmOpDeclare.subst(vcvtSHFixedFpSIop);
1720 decoder_output += FpRegRegImmOpConstructor.subst(vcvtSHFixedFpSIop);
1721 exec_output += PredOpExecute.subst(vcvtSHFixedFpSIop);
1722
1723 vcvtSHFixedFpDCode = vfpEnabledCheckCode + '''
1724 FPSCR fpscr = (FPSCR) FpscrExc;
1725 uint64_t mid = ((uint64_t)FpOp1P0_uw | ((uint64_t)FpOp1P1_uw << 32));
1726 VfpSavedState state = prepFpState(fpscr.rMode);
1727 __asm__ __volatile__("" : "=m" (mid) : "m" (mid));
1728 double cDest = vfpSFixedToFpD(fpscr.fz, fpscr.dn, mid, 16, imm);
1729 __asm__ __volatile__("" :: "m" (cDest));
1730 finishVfp(fpscr, state, fpscr.fz);
1731 FpDestP0_uw = dblLow(cDest);
1732 FpDestP1_uw = dblHi(cDest);
1733 FpscrExc = fpscr;
1734 '''
1735 vcvtSHFixedFpDIop = InstObjParams("vcvt", "VcvtSHFixedFpD",
1736 "FpRegRegImmOp",
1737 { "code": vcvtSHFixedFpDCode,
1738 "predicate_test": predicateTest,
1739 "op_class": "SimdFloatCvtOp" }, [])
1740 header_output += FpRegRegImmOpDeclare.subst(vcvtSHFixedFpDIop);
1741 decoder_output += FpRegRegImmOpConstructor.subst(vcvtSHFixedFpDIop);
1742 exec_output += PredOpExecute.subst(vcvtSHFixedFpDIop);
1743
1744 vcvtUHFixedFpSCode = vfpEnabledCheckCode + '''
1745 FPSCR fpscr = (FPSCR) FpscrExc;
1746 VfpSavedState state = prepFpState(fpscr.rMode);
1747 __asm__ __volatile__("" : "=m" (FpOp1_uh) : "m" (FpOp1_uh));
1748 FpDest = vfpUFixedToFpS(fpscr.fz, fpscr.dn, FpOp1_uh, 16, imm);
1749 __asm__ __volatile__("" :: "m" (FpDest));
1750 finishVfp(fpscr, state, fpscr.fz);
1751 FpscrExc = fpscr;
1752 '''
1753 vcvtUHFixedFpSIop = InstObjParams("vcvt", "VcvtUHFixedFpS",
1754 "FpRegRegImmOp",
1755 { "code": vcvtUHFixedFpSCode,
1756 "predicate_test": predicateTest,
1757 "op_class": "SimdFloatCvtOp" }, [])
1758 header_output += FpRegRegImmOpDeclare.subst(vcvtUHFixedFpSIop);
1759 decoder_output += FpRegRegImmOpConstructor.subst(vcvtUHFixedFpSIop);
1760 exec_output += PredOpExecute.subst(vcvtUHFixedFpSIop);
1761
1762 vcvtUHFixedFpDCode = vfpEnabledCheckCode + '''
1763 FPSCR fpscr = (FPSCR) FpscrExc;
1764 uint64_t mid = ((uint64_t)FpOp1P0_uw | ((uint64_t)FpOp1P1_uw << 32));
1765 VfpSavedState state = prepFpState(fpscr.rMode);
1766 __asm__ __volatile__("" : "=m" (mid) : "m" (mid));
1767 double cDest = vfpUFixedToFpD(fpscr.fz, fpscr.dn, mid, 16, imm);
1768 __asm__ __volatile__("" :: "m" (cDest));
1769 finishVfp(fpscr, state, fpscr.fz);
1770 FpDestP0_uw = dblLow(cDest);
1771 FpDestP1_uw = dblHi(cDest);
1772 FpscrExc = fpscr;
1773 '''
1774 vcvtUHFixedFpDIop = InstObjParams("vcvt", "VcvtUHFixedFpD",
1775 "FpRegRegImmOp",
1776 { "code": vcvtUHFixedFpDCode,
1777 "predicate_test": predicateTest,
1778 "op_class": "SimdFloatCvtOp" }, [])
1779 header_output += FpRegRegImmOpDeclare.subst(vcvtUHFixedFpDIop);
1780 decoder_output += FpRegRegImmOpConstructor.subst(vcvtUHFixedFpDIop);
1781 exec_output += PredOpExecute.subst(vcvtUHFixedFpDIop);
1782}};
177decodeVfpRegRegRegOp(ExtMachInst machInst, IntRegIndex dest,
178 IntRegIndex op1, IntRegIndex op2, bool wide)
179{
180 if (machInst.fpscrLen == 0 || VfpMacroOp::inScalarBank(dest)) {
181 return new VfpOp(machInst, dest, op1, op2);
182 } else {
183 return new VfpMacroRegRegRegOp<VfpOp>(machInst, dest, op1, op2, wide);
184 }
185}
186}};
187
188let {{
189
190 header_output = ""
191 decoder_output = ""
192 exec_output = ""
193
194 vmsrCode = vmsrEnabledCheckCode + '''
195 MiscDest = Op1;
196 '''
197
198 vmsrIop = InstObjParams("vmsr", "Vmsr", "FpRegRegImmOp",
199 { "code": vmsrCode,
200 "predicate_test": predicateTest,
201 "op_class": "SimdFloatMiscOp" },
202 ["IsSerializeAfter","IsNonSpeculative"])
203 header_output += FpRegRegImmOpDeclare.subst(vmsrIop);
204 decoder_output += FpRegRegImmOpConstructor.subst(vmsrIop);
205 exec_output += PredOpExecute.subst(vmsrIop);
206
207 vmsrFpscrCode = vmsrEnabledCheckCode + '''
208 Fpscr = Op1 & ~FpCondCodesMask;
209 FpCondCodes = Op1 & FpCondCodesMask;
210 '''
211 vmsrFpscrIop = InstObjParams("vmsr", "VmsrFpscr", "FpRegRegOp",
212 { "code": vmsrFpscrCode,
213 "predicate_test": predicateTest,
214 "op_class": "SimdFloatMiscOp" },
215 ["IsSerializeAfter","IsNonSpeculative",
216 "IsSquashAfter"])
217 header_output += FpRegRegOpDeclare.subst(vmsrFpscrIop);
218 decoder_output += FpRegRegOpConstructor.subst(vmsrFpscrIop);
219 exec_output += PredOpExecute.subst(vmsrFpscrIop);
220
221 vmrsCode = vmrsEnabledCheckCode + '''
222 CPSR cpsr = Cpsr;
223 SCR scr = Scr;
224 if (!inSecureState(scr, cpsr) && (cpsr.mode != MODE_HYP)) {
225 HCR hcr = Hcr;
226 bool hypTrap = false;
227 switch(xc->tcBase()->flattenMiscIndex(op1)) {
228 case MISCREG_FPSID:
229 hypTrap = hcr.tid0;
230 break;
231 case MISCREG_MVFR0:
232 case MISCREG_MVFR1:
233 hypTrap = hcr.tid3;
234 break;
235 }
236 if (hypTrap) {
237 return std::make_shared<HypervisorTrap>(machInst, imm,
238 EC_TRAPPED_CP10_MRC_VMRS);
239 }
240 }
241 Dest = MiscOp1;
242 '''
243
244 vmrsIop = InstObjParams("vmrs", "Vmrs", "FpRegRegImmOp",
245 { "code": vmrsCode,
246 "predicate_test": predicateTest,
247 "op_class": "SimdFloatMiscOp" },
248 ["IsSerializeBefore"])
249 header_output += FpRegRegImmOpDeclare.subst(vmrsIop);
250 decoder_output += FpRegRegImmOpConstructor.subst(vmrsIop);
251 exec_output += PredOpExecute.subst(vmrsIop);
252
253 vmrsFpscrIop = InstObjParams("vmrs", "VmrsFpscr", "FpRegRegOp",
254 { "code": vmrsEnabledCheckCode + \
255 "Dest = Fpscr | FpCondCodes;",
256 "predicate_test": predicateTest,
257 "op_class": "SimdFloatMiscOp" },
258 ["IsSerializeBefore"])
259 header_output += FpRegRegOpDeclare.subst(vmrsFpscrIop);
260 decoder_output += FpRegRegOpConstructor.subst(vmrsFpscrIop);
261 exec_output += PredOpExecute.subst(vmrsFpscrIop);
262
263 vmrsApsrFpscrCode = vfpEnabledCheckCode + '''
264 FPSCR fpscr = FpCondCodes;
265 CondCodesNZ = (fpscr.n << 1) | fpscr.z;
266 CondCodesC = fpscr.c;
267 CondCodesV = fpscr.v;
268 '''
269 vmrsApsrFpscrIop = InstObjParams("vmrs", "VmrsApsrFpscr", "PredOp",
270 { "code": vmrsApsrFpscrCode,
271 "predicate_test": predicateTest,
272 "op_class": "SimdFloatMiscOp" })
273 header_output += BasicDeclare.subst(vmrsApsrFpscrIop);
274 decoder_output += BasicConstructor.subst(vmrsApsrFpscrIop);
275 exec_output += PredOpExecute.subst(vmrsApsrFpscrIop);
276
277 vmovImmSCode = vfpEnabledCheckCode + '''
278 FpDest_uw = bits(imm, 31, 0);
279 '''
280 vmovImmSIop = InstObjParams("vmov", "VmovImmS", "FpRegImmOp",
281 { "code": vmovImmSCode,
282 "predicate_test": predicateTest,
283 "op_class": "SimdFloatMiscOp" }, [])
284 header_output += FpRegImmOpDeclare.subst(vmovImmSIop);
285 decoder_output += FpRegImmOpConstructor.subst(vmovImmSIop);
286 exec_output += PredOpExecute.subst(vmovImmSIop);
287
288 vmovImmDCode = vfpEnabledCheckCode + '''
289 FpDestP0_uw = bits(imm, 31, 0);
290 FpDestP1_uw = bits(imm, 63, 32);
291 '''
292 vmovImmDIop = InstObjParams("vmov", "VmovImmD", "FpRegImmOp",
293 { "code": vmovImmDCode,
294 "predicate_test": predicateTest,
295 "op_class": "SimdFloatMiscOp" }, [])
296 header_output += FpRegImmOpDeclare.subst(vmovImmDIop);
297 decoder_output += FpRegImmOpConstructor.subst(vmovImmDIop);
298 exec_output += PredOpExecute.subst(vmovImmDIop);
299
300 vmovImmQCode = vfpEnabledCheckCode + '''
301 FpDestP0_uw = bits(imm, 31, 0);
302 FpDestP1_uw = bits(imm, 63, 32);
303 FpDestP2_uw = bits(imm, 31, 0);
304 FpDestP3_uw = bits(imm, 63, 32);
305 '''
306 vmovImmQIop = InstObjParams("vmov", "VmovImmQ", "FpRegImmOp",
307 { "code": vmovImmQCode,
308 "predicate_test": predicateTest,
309 "op_class": "SimdFloatMiscOp" }, [])
310 header_output += FpRegImmOpDeclare.subst(vmovImmQIop);
311 decoder_output += FpRegImmOpConstructor.subst(vmovImmQIop);
312 exec_output += PredOpExecute.subst(vmovImmQIop);
313
314 vmovRegSCode = vfpEnabledCheckCode + '''
315 FpDest_uw = FpOp1_uw;
316 '''
317 vmovRegSIop = InstObjParams("vmov", "VmovRegS", "FpRegRegOp",
318 { "code": vmovRegSCode,
319 "predicate_test": predicateTest,
320 "op_class": "SimdFloatMiscOp" }, [])
321 header_output += FpRegRegOpDeclare.subst(vmovRegSIop);
322 decoder_output += FpRegRegOpConstructor.subst(vmovRegSIop);
323 exec_output += PredOpExecute.subst(vmovRegSIop);
324
325 vmovRegDCode = vfpEnabledCheckCode + '''
326 FpDestP0_uw = FpOp1P0_uw;
327 FpDestP1_uw = FpOp1P1_uw;
328 '''
329 vmovRegDIop = InstObjParams("vmov", "VmovRegD", "FpRegRegOp",
330 { "code": vmovRegDCode,
331 "predicate_test": predicateTest,
332 "op_class": "SimdFloatMiscOp" }, [])
333 header_output += FpRegRegOpDeclare.subst(vmovRegDIop);
334 decoder_output += FpRegRegOpConstructor.subst(vmovRegDIop);
335 exec_output += PredOpExecute.subst(vmovRegDIop);
336
337 vmovRegQCode = vfpEnabledCheckCode + '''
338 FpDestP0_uw = FpOp1P0_uw;
339 FpDestP1_uw = FpOp1P1_uw;
340 FpDestP2_uw = FpOp1P2_uw;
341 FpDestP3_uw = FpOp1P3_uw;
342 '''
343 vmovRegQIop = InstObjParams("vmov", "VmovRegQ", "FpRegRegOp",
344 { "code": vmovRegQCode,
345 "predicate_test": predicateTest,
346 "op_class": "SimdFloatMiscOp" }, [])
347 header_output += FpRegRegOpDeclare.subst(vmovRegQIop);
348 decoder_output += FpRegRegOpConstructor.subst(vmovRegQIop);
349 exec_output += PredOpExecute.subst(vmovRegQIop);
350
351 vmovCoreRegBCode = simdEnabledCheckCode + '''
352 FpDest_uw = insertBits(FpDest_uw, imm * 8 + 7, imm * 8, Op1_ub);
353 '''
354 vmovCoreRegBIop = InstObjParams("vmov", "VmovCoreRegB", "FpRegRegImmOp",
355 { "code": vmovCoreRegBCode,
356 "predicate_test": predicateTest,
357 "op_class": "SimdFloatMiscOp" }, [])
358 header_output += FpRegRegImmOpDeclare.subst(vmovCoreRegBIop);
359 decoder_output += FpRegRegImmOpConstructor.subst(vmovCoreRegBIop);
360 exec_output += PredOpExecute.subst(vmovCoreRegBIop);
361
362 vmovCoreRegHCode = simdEnabledCheckCode + '''
363 FpDest_uw = insertBits(FpDest_uw, imm * 16 + 15, imm * 16, Op1_uh);
364 '''
365 vmovCoreRegHIop = InstObjParams("vmov", "VmovCoreRegH", "FpRegRegImmOp",
366 { "code": vmovCoreRegHCode,
367 "predicate_test": predicateTest,
368 "op_class": "SimdFloatMiscOp" }, [])
369 header_output += FpRegRegImmOpDeclare.subst(vmovCoreRegHIop);
370 decoder_output += FpRegRegImmOpConstructor.subst(vmovCoreRegHIop);
371 exec_output += PredOpExecute.subst(vmovCoreRegHIop);
372
373 vmovCoreRegWCode = vfpEnabledCheckCode + '''
374 FpDest_uw = Op1_uw;
375 '''
376 vmovCoreRegWIop = InstObjParams("vmov", "VmovCoreRegW", "FpRegRegOp",
377 { "code": vmovCoreRegWCode,
378 "predicate_test": predicateTest,
379 "op_class": "SimdFloatMiscOp" }, [])
380 header_output += FpRegRegOpDeclare.subst(vmovCoreRegWIop);
381 decoder_output += FpRegRegOpConstructor.subst(vmovCoreRegWIop);
382 exec_output += PredOpExecute.subst(vmovCoreRegWIop);
383
384 vmovRegCoreUBCode = vfpEnabledCheckCode + '''
385 assert(imm < 4);
386 Dest = bits(FpOp1_uw, imm * 8 + 7, imm * 8);
387 '''
388 vmovRegCoreUBIop = InstObjParams("vmov", "VmovRegCoreUB", "FpRegRegImmOp",
389 { "code": vmovRegCoreUBCode,
390 "predicate_test": predicateTest,
391 "op_class": "SimdFloatMiscOp" }, [])
392 header_output += FpRegRegImmOpDeclare.subst(vmovRegCoreUBIop);
393 decoder_output += FpRegRegImmOpConstructor.subst(vmovRegCoreUBIop);
394 exec_output += PredOpExecute.subst(vmovRegCoreUBIop);
395
396 vmovRegCoreUHCode = vfpEnabledCheckCode + '''
397 assert(imm < 2);
398 Dest = bits(FpOp1_uw, imm * 16 + 15, imm * 16);
399 '''
400 vmovRegCoreUHIop = InstObjParams("vmov", "VmovRegCoreUH", "FpRegRegImmOp",
401 { "code": vmovRegCoreUHCode,
402 "predicate_test": predicateTest,
403 "op_class": "SimdFloatMiscOp" }, [])
404 header_output += FpRegRegImmOpDeclare.subst(vmovRegCoreUHIop);
405 decoder_output += FpRegRegImmOpConstructor.subst(vmovRegCoreUHIop);
406 exec_output += PredOpExecute.subst(vmovRegCoreUHIop);
407
408 vmovRegCoreSBCode = vfpEnabledCheckCode + '''
409 assert(imm < 4);
410 Dest = sext<8>(bits(FpOp1_uw, imm * 8 + 7, imm * 8));
411 '''
412 vmovRegCoreSBIop = InstObjParams("vmov", "VmovRegCoreSB", "FpRegRegImmOp",
413 { "code": vmovRegCoreSBCode,
414 "predicate_test": predicateTest,
415 "op_class": "SimdFloatMiscOp" }, [])
416 header_output += FpRegRegImmOpDeclare.subst(vmovRegCoreSBIop);
417 decoder_output += FpRegRegImmOpConstructor.subst(vmovRegCoreSBIop);
418 exec_output += PredOpExecute.subst(vmovRegCoreSBIop);
419
420 vmovRegCoreSHCode = vfpEnabledCheckCode + '''
421 assert(imm < 2);
422 Dest = sext<16>(bits(FpOp1_uw, imm * 16 + 15, imm * 16));
423 '''
424 vmovRegCoreSHIop = InstObjParams("vmov", "VmovRegCoreSH", "FpRegRegImmOp",
425 { "code": vmovRegCoreSHCode,
426 "predicate_test": predicateTest,
427 "op_class": "SimdFloatMiscOp" }, [])
428 header_output += FpRegRegImmOpDeclare.subst(vmovRegCoreSHIop);
429 decoder_output += FpRegRegImmOpConstructor.subst(vmovRegCoreSHIop);
430 exec_output += PredOpExecute.subst(vmovRegCoreSHIop);
431
432 vmovRegCoreWCode = vfpEnabledCheckCode + '''
433 Dest = FpOp1_uw;
434 '''
435 vmovRegCoreWIop = InstObjParams("vmov", "VmovRegCoreW", "FpRegRegOp",
436 { "code": vmovRegCoreWCode,
437 "predicate_test": predicateTest,
438 "op_class": "SimdFloatMiscOp" }, [])
439 header_output += FpRegRegOpDeclare.subst(vmovRegCoreWIop);
440 decoder_output += FpRegRegOpConstructor.subst(vmovRegCoreWIop);
441 exec_output += PredOpExecute.subst(vmovRegCoreWIop);
442
443 vmov2Reg2CoreCode = vfpEnabledCheckCode + '''
444 FpDestP0_uw = Op1_uw;
445 FpDestP1_uw = Op2_uw;
446 '''
447 vmov2Reg2CoreIop = InstObjParams("vmov", "Vmov2Reg2Core", "FpRegRegRegOp",
448 { "code": vmov2Reg2CoreCode,
449 "predicate_test": predicateTest,
450 "op_class": "SimdFloatMiscOp" }, [])
451 header_output += FpRegRegRegOpDeclare.subst(vmov2Reg2CoreIop);
452 decoder_output += FpRegRegRegOpConstructor.subst(vmov2Reg2CoreIop);
453 exec_output += PredOpExecute.subst(vmov2Reg2CoreIop);
454
455 vmov2Core2RegCode = vfpEnabledCheckCode + '''
456 Dest_uw = FpOp2P0_uw;
457 Op1_uw = FpOp2P1_uw;
458 '''
459 vmov2Core2RegIop = InstObjParams("vmov", "Vmov2Core2Reg", "FpRegRegRegOp",
460 { "code": vmov2Core2RegCode,
461 "predicate_test": predicateTest,
462 "op_class": "SimdFloatMiscOp" }, [])
463 header_output += FpRegRegRegOpDeclare.subst(vmov2Core2RegIop);
464 decoder_output += FpRegRegRegOpConstructor.subst(vmov2Core2RegIop);
465 exec_output += PredOpExecute.subst(vmov2Core2RegIop);
466}};
467
468let {{
469
470 header_output = ""
471 decoder_output = ""
472 exec_output = ""
473
474 singleSimpleCode = vfpEnabledCheckCode + '''
475 FPSCR fpscr M5_VAR_USED = (FPSCR) FpscrExc;
476 FpDest = %(op)s;
477 '''
478 singleCode = singleSimpleCode + '''
479 FpscrExc = fpscr;
480 '''
481 singleTernOp = vfpEnabledCheckCode + '''
482 FPSCR fpscr = (FPSCR) FpscrExc;
483 VfpSavedState state = prepFpState(fpscr.rMode);
484 float cOp1 = FpOp1;
485 float cOp2 = FpOp2;
486 float cOp3 = FpDestP0;
487 FpDestP0 = ternaryOp(fpscr, %(palam)s, %(op)s,
488 fpscr.fz, fpscr.dn, fpscr.rMode);
489 finishVfp(fpscr, state, fpscr.fz);
490 FpscrExc = fpscr;
491 '''
492 singleBinOp = "binaryOp(fpscr, FpOp1, FpOp2," + \
493 "%(func)s, fpscr.fz, fpscr.dn, fpscr.rMode)"
494 singleUnaryOp = "unaryOp(fpscr, FpOp1, %(func)s, fpscr.fz, fpscr.rMode)"
495 doubleCode = vfpEnabledCheckCode + '''
496 FPSCR fpscr M5_VAR_USED = (FPSCR) FpscrExc;
497 double dest = %(op)s;
498 FpDestP0_uw = dblLow(dest);
499 FpDestP1_uw = dblHi(dest);
500 FpscrExc = fpscr;
501 '''
502 doubleTernOp = vfpEnabledCheckCode + '''
503 FPSCR fpscr = (FPSCR) FpscrExc;
504 VfpSavedState state = prepFpState(fpscr.rMode);
505 double cOp1 = dbl(FpOp1P0_uw, FpOp1P1_uw);
506 double cOp2 = dbl(FpOp2P0_uw, FpOp2P1_uw);
507 double cOp3 = dbl(FpDestP0_uw, FpDestP1_uw);
508 double cDest = ternaryOp(fpscr, %(palam)s, %(op)s,
509 fpscr.fz, fpscr.dn, fpscr.rMode);
510 FpDestP0_uw = dblLow(cDest);
511 FpDestP1_uw = dblHi(cDest);
512 finishVfp(fpscr, state, fpscr.fz);
513 FpscrExc = fpscr;
514 '''
515 doubleBinOp = '''
516 binaryOp(fpscr, dbl(FpOp1P0_uw, FpOp1P1_uw),
517 dbl(FpOp2P0_uw, FpOp2P1_uw),
518 %(func)s, fpscr.fz, fpscr.dn, fpscr.rMode);
519 '''
520 doubleUnaryOp = '''
521 unaryOp(fpscr, dbl(FpOp1P0_uw, FpOp1P1_uw), %(func)s,
522 fpscr.fz, fpscr.rMode)
523 '''
524
525 def buildTernaryFpOp(Name, base, opClass, singleOp, doubleOp, paramStr):
526 global header_output, decoder_output, exec_output
527
528 code = singleTernOp % { "op": singleOp, "palam": paramStr }
529 sIop = InstObjParams(Name.lower() + "s", Name + "S", base,
530 { "code": code,
531 "predicate_test": predicateTest,
532 "op_class": opClass }, [])
533 code = doubleTernOp % { "op": doubleOp, "palam": paramStr }
534 dIop = InstObjParams(Name.lower() + "d", Name + "D", base,
535 { "code": code,
536 "predicate_test": predicateTest,
537 "op_class": opClass }, [])
538
539 declareTempl = eval(base + "Declare");
540 constructorTempl = eval(base + "Constructor");
541
542 for iop in sIop, dIop:
543 header_output += declareTempl.subst(iop)
544 decoder_output += constructorTempl.subst(iop)
545 exec_output += PredOpExecute.subst(iop)
546
547 buildTernaryFpOp("Vfma", "FpRegRegRegOp", "SimdFloatMultAccOp",
548 "fpMulAdd<float>", "fpMulAdd<double>", " cOp1, cOp2, cOp3" )
549 buildTernaryFpOp("Vfms", "FpRegRegRegOp", "SimdFloatMultAccOp",
550 "fpMulAdd<float>", "fpMulAdd<double>", "-cOp1, cOp2, cOp3" )
551 buildTernaryFpOp("Vfnma", "FpRegRegRegOp", "SimdFloatMultAccOp",
552 "fpMulAdd<float>", "fpMulAdd<double>", "-cOp1, cOp2, -cOp3" )
553 buildTernaryFpOp("Vfnms", "FpRegRegRegOp", "SimdFloatMultAccOp",
554 "fpMulAdd<float>", "fpMulAdd<double>", " cOp1, cOp2, -cOp3" )
555
556 def buildBinFpOp(name, Name, base, opClass, singleOp, doubleOp):
557 global header_output, decoder_output, exec_output
558
559 code = singleCode % { "op": singleBinOp }
560 code = code % { "func": singleOp }
561 sIop = InstObjParams(name + "s", Name + "S", base,
562 { "code": code,
563 "predicate_test": predicateTest,
564 "op_class": opClass }, [])
565 code = doubleCode % { "op": doubleBinOp }
566 code = code % { "func": doubleOp }
567 dIop = InstObjParams(name + "d", Name + "D", base,
568 { "code": code,
569 "predicate_test": predicateTest,
570 "op_class": opClass }, [])
571
572 declareTempl = eval(base + "Declare");
573 constructorTempl = eval(base + "Constructor");
574
575 for iop in sIop, dIop:
576 header_output += declareTempl.subst(iop)
577 decoder_output += constructorTempl.subst(iop)
578 exec_output += PredOpExecute.subst(iop)
579
580 buildBinFpOp("vadd", "Vadd", "FpRegRegRegOp", "SimdFloatAddOp", "fpAddS",
581 "fpAddD")
582 buildBinFpOp("vsub", "Vsub", "FpRegRegRegOp", "SimdFloatAddOp", "fpSubS",
583 "fpSubD")
584 buildBinFpOp("vdiv", "Vdiv", "FpRegRegRegOp", "SimdFloatDivOp", "fpDivS",
585 "fpDivD")
586 buildBinFpOp("vmul", "Vmul", "FpRegRegRegOp", "SimdFloatMultOp", "fpMulS",
587 "fpMulD")
588
589 def buildUnaryFpOp(name, Name, base, opClass, singleOp, doubleOp = None):
590 if doubleOp is None:
591 doubleOp = singleOp
592 global header_output, decoder_output, exec_output
593
594 code = singleCode % { "op": singleUnaryOp }
595 code = code % { "func": singleOp }
596 sIop = InstObjParams(name + "s", Name + "S", base,
597 { "code": code,
598 "predicate_test": predicateTest,
599 "op_class": opClass }, [])
600 code = doubleCode % { "op": doubleUnaryOp }
601 code = code % { "func": doubleOp }
602 dIop = InstObjParams(name + "d", Name + "D", base,
603 { "code": code,
604 "predicate_test": predicateTest,
605 "op_class": opClass }, [])
606
607 declareTempl = eval(base + "Declare");
608 constructorTempl = eval(base + "Constructor");
609
610 for iop in sIop, dIop:
611 header_output += declareTempl.subst(iop)
612 decoder_output += constructorTempl.subst(iop)
613 exec_output += PredOpExecute.subst(iop)
614
615 buildUnaryFpOp("vsqrt", "Vsqrt", "FpRegRegOp", "SimdFloatSqrtOp", "sqrtf",
616 "sqrt")
617
618 def buildSimpleUnaryFpOp(name, Name, base, opClass, singleOp,
619 doubleOp = None):
620 if doubleOp is None:
621 doubleOp = singleOp
622 global header_output, decoder_output, exec_output
623
624 sIop = InstObjParams(name + "s", Name + "S", base,
625 { "code": singleSimpleCode % { "op": singleOp },
626 "predicate_test": predicateTest,
627 "op_class": opClass }, [])
628 dIop = InstObjParams(name + "d", Name + "D", base,
629 { "code": doubleCode % { "op": doubleOp },
630 "predicate_test": predicateTest,
631 "op_class": opClass }, [])
632
633 declareTempl = eval(base + "Declare");
634 constructorTempl = eval(base + "Constructor");
635
636 for iop in sIop, dIop:
637 header_output += declareTempl.subst(iop)
638 decoder_output += constructorTempl.subst(iop)
639 exec_output += PredOpExecute.subst(iop)
640
641 buildSimpleUnaryFpOp("vneg", "Vneg", "FpRegRegOp", "SimdFloatMiscOp",
642 "-FpOp1", "-dbl(FpOp1P0_uw, FpOp1P1_uw)")
643 buildSimpleUnaryFpOp("vabs", "Vabs", "FpRegRegOp", "SimdFloatMiscOp",
644 "fabsf(FpOp1)", "fabs(dbl(FpOp1P0_uw, FpOp1P1_uw))")
645 buildSimpleUnaryFpOp("vrintp", "VRIntP", "FpRegRegOp", "SimdFloatMiscOp",
646 "fplibRoundInt<uint32_t>(FpOp1, FPRounding_POSINF, false, fpscr)",
647 "fplibRoundInt<uint64_t>(dbl(FpOp1P0_uw, FpOp1P1_uw), " \
648 "FPRounding_POSINF, false, fpscr)"
649 )
650 buildSimpleUnaryFpOp("vrintm", "VRIntM", "FpRegRegOp", "SimdFloatMiscOp",
651 "fplibRoundInt<uint32_t>(FpOp1, FPRounding_NEGINF, false, fpscr)",
652 "fplibRoundInt<uint64_t>(dbl(FpOp1P0_uw, FpOp1P1_uw), " \
653 "FPRounding_NEGINF, false, fpscr)"
654 )
655 buildSimpleUnaryFpOp("vrinta", "VRIntA", "FpRegRegOp", "SimdFloatMiscOp",
656 "fplibRoundInt<uint32_t>(FpOp1, FPRounding_TIEAWAY, false, fpscr)",
657 "fplibRoundInt<uint64_t>(dbl(FpOp1P0_uw, FpOp1P1_uw), " \
658 "FPRounding_TIEAWAY, false, fpscr)"
659 )
660 buildSimpleUnaryFpOp("vrintn", "VRIntN", "FpRegRegOp", "SimdFloatMiscOp",
661 "fplibRoundInt<uint32_t>(FpOp1, FPRounding_TIEEVEN, false, fpscr)",
662 "fplibRoundInt<uint64_t>(dbl(FpOp1P0_uw, FpOp1P1_uw), " \
663 "FPRounding_TIEEVEN, false, fpscr)"
664 )
665}};
666
667let {{
668
669 header_output = ""
670 decoder_output = ""
671 exec_output = ""
672
673 vmlaSCode = vfpEnabledCheckCode + '''
674 FPSCR fpscr = (FPSCR) FpscrExc;
675 float mid = binaryOp(fpscr, FpOp1, FpOp2,
676 fpMulS, fpscr.fz, fpscr.dn, fpscr.rMode);
677 FpDest = binaryOp(fpscr, FpDest, mid, fpAddS,
678 fpscr.fz, fpscr.dn, fpscr.rMode);
679 FpscrExc = fpscr;
680 '''
681 vmlaSIop = InstObjParams("vmlas", "VmlaS", "FpRegRegRegOp",
682 { "code": vmlaSCode,
683 "predicate_test": predicateTest,
684 "op_class": "SimdFloatMultAccOp" }, [])
685 header_output += FpRegRegRegOpDeclare.subst(vmlaSIop);
686 decoder_output += FpRegRegRegOpConstructor.subst(vmlaSIop);
687 exec_output += PredOpExecute.subst(vmlaSIop);
688
689 vmlaDCode = vfpEnabledCheckCode + '''
690 FPSCR fpscr = (FPSCR) FpscrExc;
691 double mid = binaryOp(fpscr, dbl(FpOp1P0_uw, FpOp1P1_uw),
692 dbl(FpOp2P0_uw, FpOp2P1_uw),
693 fpMulD, fpscr.fz, fpscr.dn, fpscr.rMode);
694 double dest = binaryOp(fpscr, dbl(FpDestP0_uw, FpDestP1_uw),
695 mid, fpAddD, fpscr.fz,
696 fpscr.dn, fpscr.rMode);
697 FpDestP0_uw = dblLow(dest);
698 FpDestP1_uw = dblHi(dest);
699 FpscrExc = fpscr;
700 '''
701 vmlaDIop = InstObjParams("vmlad", "VmlaD", "FpRegRegRegOp",
702 { "code": vmlaDCode,
703 "predicate_test": predicateTest,
704 "op_class": "SimdFloatMultAccOp" }, [])
705 header_output += FpRegRegRegOpDeclare.subst(vmlaDIop);
706 decoder_output += FpRegRegRegOpConstructor.subst(vmlaDIop);
707 exec_output += PredOpExecute.subst(vmlaDIop);
708
709 vmlsSCode = vfpEnabledCheckCode + '''
710 FPSCR fpscr = (FPSCR) FpscrExc;
711 float mid = binaryOp(fpscr, FpOp1, FpOp2,
712 fpMulS, fpscr.fz, fpscr.dn, fpscr.rMode);
713 FpDest = binaryOp(fpscr, FpDest, -mid, fpAddS,
714 fpscr.fz, fpscr.dn, fpscr.rMode);
715 FpscrExc = fpscr;
716 '''
717 vmlsSIop = InstObjParams("vmlss", "VmlsS", "FpRegRegRegOp",
718 { "code": vmlsSCode,
719 "predicate_test": predicateTest,
720 "op_class": "SimdFloatMultAccOp" }, [])
721 header_output += FpRegRegRegOpDeclare.subst(vmlsSIop);
722 decoder_output += FpRegRegRegOpConstructor.subst(vmlsSIop);
723 exec_output += PredOpExecute.subst(vmlsSIop);
724
725 vmlsDCode = vfpEnabledCheckCode + '''
726 FPSCR fpscr = (FPSCR) FpscrExc;
727 double mid = binaryOp(fpscr, dbl(FpOp1P0_uw, FpOp1P1_uw),
728 dbl(FpOp2P0_uw, FpOp2P1_uw),
729 fpMulD, fpscr.fz, fpscr.dn, fpscr.rMode);
730 double dest = binaryOp(fpscr, dbl(FpDestP0_uw, FpDestP1_uw),
731 -mid, fpAddD, fpscr.fz,
732 fpscr.dn, fpscr.rMode);
733 FpDestP0_uw = dblLow(dest);
734 FpDestP1_uw = dblHi(dest);
735 FpscrExc = fpscr;
736 '''
737 vmlsDIop = InstObjParams("vmlsd", "VmlsD", "FpRegRegRegOp",
738 { "code": vmlsDCode,
739 "predicate_test": predicateTest,
740 "op_class": "SimdFloatMultAccOp" }, [])
741 header_output += FpRegRegRegOpDeclare.subst(vmlsDIop);
742 decoder_output += FpRegRegRegOpConstructor.subst(vmlsDIop);
743 exec_output += PredOpExecute.subst(vmlsDIop);
744
745 vnmlaSCode = vfpEnabledCheckCode + '''
746 FPSCR fpscr = (FPSCR) FpscrExc;
747 float mid = binaryOp(fpscr, FpOp1, FpOp2,
748 fpMulS, fpscr.fz, fpscr.dn, fpscr.rMode);
749 FpDest = binaryOp(fpscr, -FpDest, -mid, fpAddS,
750 fpscr.fz, fpscr.dn, fpscr.rMode);
751 FpscrExc = fpscr;
752 '''
753 vnmlaSIop = InstObjParams("vnmlas", "VnmlaS", "FpRegRegRegOp",
754 { "code": vnmlaSCode,
755 "predicate_test": predicateTest,
756 "op_class": "SimdFloatMultAccOp" }, [])
757 header_output += FpRegRegRegOpDeclare.subst(vnmlaSIop);
758 decoder_output += FpRegRegRegOpConstructor.subst(vnmlaSIop);
759 exec_output += PredOpExecute.subst(vnmlaSIop);
760
761 vnmlaDCode = vfpEnabledCheckCode + '''
762 FPSCR fpscr = (FPSCR) FpscrExc;
763 double mid = binaryOp(fpscr, dbl(FpOp1P0_uw, FpOp1P1_uw),
764 dbl(FpOp2P0_uw, FpOp2P1_uw),
765 fpMulD, fpscr.fz, fpscr.dn, fpscr.rMode);
766 double dest = binaryOp(fpscr, -dbl(FpDestP0_uw, FpDestP1_uw),
767 -mid, fpAddD, fpscr.fz,
768 fpscr.dn, fpscr.rMode);
769 FpDestP0_uw = dblLow(dest);
770 FpDestP1_uw = dblHi(dest);
771 FpscrExc = fpscr;
772 '''
773 vnmlaDIop = InstObjParams("vnmlad", "VnmlaD", "FpRegRegRegOp",
774 { "code": vnmlaDCode,
775 "predicate_test": predicateTest,
776 "op_class": "SimdFloatMultAccOp" }, [])
777 header_output += FpRegRegRegOpDeclare.subst(vnmlaDIop);
778 decoder_output += FpRegRegRegOpConstructor.subst(vnmlaDIop);
779 exec_output += PredOpExecute.subst(vnmlaDIop);
780
781 vnmlsSCode = vfpEnabledCheckCode + '''
782 FPSCR fpscr = (FPSCR) FpscrExc;
783 float mid = binaryOp(fpscr, FpOp1, FpOp2,
784 fpMulS, fpscr.fz, fpscr.dn, fpscr.rMode);
785 FpDest = binaryOp(fpscr, -FpDest, mid, fpAddS,
786 fpscr.fz, fpscr.dn, fpscr.rMode);
787 FpscrExc = fpscr;
788 '''
789 vnmlsSIop = InstObjParams("vnmlss", "VnmlsS", "FpRegRegRegOp",
790 { "code": vnmlsSCode,
791 "predicate_test": predicateTest,
792 "op_class": "SimdFloatMultAccOp" }, [])
793 header_output += FpRegRegRegOpDeclare.subst(vnmlsSIop);
794 decoder_output += FpRegRegRegOpConstructor.subst(vnmlsSIop);
795 exec_output += PredOpExecute.subst(vnmlsSIop);
796
797 vnmlsDCode = vfpEnabledCheckCode + '''
798 FPSCR fpscr = (FPSCR) FpscrExc;
799 double mid = binaryOp(fpscr, dbl(FpOp1P0_uw, FpOp1P1_uw),
800 dbl(FpOp2P0_uw, FpOp2P1_uw),
801 fpMulD, fpscr.fz, fpscr.dn, fpscr.rMode);
802 double dest = binaryOp(fpscr, -dbl(FpDestP0_uw, FpDestP1_uw),
803 mid, fpAddD, fpscr.fz,
804 fpscr.dn, fpscr.rMode);
805 FpDestP0_uw = dblLow(dest);
806 FpDestP1_uw = dblHi(dest);
807 FpscrExc = fpscr;
808 '''
809 vnmlsDIop = InstObjParams("vnmlsd", "VnmlsD", "FpRegRegRegOp",
810 { "code": vnmlsDCode,
811 "predicate_test": predicateTest,
812 "op_class": "SimdFloatMultAccOp" }, [])
813 header_output += FpRegRegRegOpDeclare.subst(vnmlsDIop);
814 decoder_output += FpRegRegRegOpConstructor.subst(vnmlsDIop);
815 exec_output += PredOpExecute.subst(vnmlsDIop);
816
817 vnmulSCode = vfpEnabledCheckCode + '''
818 FPSCR fpscr = (FPSCR) FpscrExc;
819 FpDest = -binaryOp(fpscr, FpOp1, FpOp2, fpMulS,
820 fpscr.fz, fpscr.dn, fpscr.rMode);
821 FpscrExc = fpscr;
822 '''
823 vnmulSIop = InstObjParams("vnmuls", "VnmulS", "FpRegRegRegOp",
824 { "code": vnmulSCode,
825 "predicate_test": predicateTest,
826 "op_class": "SimdFloatMultOp" }, [])
827 header_output += FpRegRegRegOpDeclare.subst(vnmulSIop);
828 decoder_output += FpRegRegRegOpConstructor.subst(vnmulSIop);
829 exec_output += PredOpExecute.subst(vnmulSIop);
830
831 vnmulDCode = vfpEnabledCheckCode + '''
832 FPSCR fpscr = (FPSCR) FpscrExc;
833 double dest = -binaryOp(fpscr, dbl(FpOp1P0_uw, FpOp1P1_uw),
834 dbl(FpOp2P0_uw, FpOp2P1_uw),
835 fpMulD, fpscr.fz, fpscr.dn,
836 fpscr.rMode);
837 FpDestP0_uw = dblLow(dest);
838 FpDestP1_uw = dblHi(dest);
839 FpscrExc = fpscr;
840 '''
841 vnmulDIop = InstObjParams("vnmuld", "VnmulD", "FpRegRegRegOp",
842 { "code": vnmulDCode,
843 "predicate_test": predicateTest,
844 "op_class": "SimdFloatMultOp" }, [])
845 header_output += FpRegRegRegOpDeclare.subst(vnmulDIop);
846 decoder_output += FpRegRegRegOpConstructor.subst(vnmulDIop);
847 exec_output += PredOpExecute.subst(vnmulDIop);
848}};
849
850let {{
851
852 header_output = ""
853 decoder_output = ""
854 exec_output = ""
855
856 vcvtUIntFpSCode = vfpEnabledCheckCode + '''
857 FPSCR fpscr = (FPSCR) FpscrExc;
858 VfpSavedState state = prepFpState(fpscr.rMode);
859 __asm__ __volatile__("" : "=m" (FpOp1_uw) : "m" (FpOp1_uw));
860 FpDest = FpOp1_uw;
861 __asm__ __volatile__("" :: "m" (FpDest));
862 finishVfp(fpscr, state, fpscr.fz);
863 FpscrExc = fpscr;
864 '''
865 vcvtUIntFpSIop = InstObjParams("vcvt", "VcvtUIntFpS", "FpRegRegOp",
866 { "code": vcvtUIntFpSCode,
867 "predicate_test": predicateTest,
868 "op_class": "SimdFloatCvtOp" }, [])
869 header_output += FpRegRegOpDeclare.subst(vcvtUIntFpSIop);
870 decoder_output += FpRegRegOpConstructor.subst(vcvtUIntFpSIop);
871 exec_output += PredOpExecute.subst(vcvtUIntFpSIop);
872
873 vcvtUIntFpDCode = vfpEnabledCheckCode + '''
874 FPSCR fpscr = (FPSCR) FpscrExc;
875 VfpSavedState state = prepFpState(fpscr.rMode);
876 __asm__ __volatile__("" : "=m" (FpOp1P0_uw) : "m" (FpOp1P0_uw));
877 double cDest = (uint64_t)FpOp1P0_uw;
878 __asm__ __volatile__("" :: "m" (cDest));
879 finishVfp(fpscr, state, fpscr.fz);
880 FpDestP0_uw = dblLow(cDest);
881 FpDestP1_uw = dblHi(cDest);
882 FpscrExc = fpscr;
883 '''
884 vcvtUIntFpDIop = InstObjParams("vcvt", "VcvtUIntFpD", "FpRegRegOp",
885 { "code": vcvtUIntFpDCode,
886 "predicate_test": predicateTest,
887 "op_class": "SimdFloatCvtOp" }, [])
888 header_output += FpRegRegOpDeclare.subst(vcvtUIntFpDIop);
889 decoder_output += FpRegRegOpConstructor.subst(vcvtUIntFpDIop);
890 exec_output += PredOpExecute.subst(vcvtUIntFpDIop);
891
892 vcvtSIntFpSCode = vfpEnabledCheckCode + '''
893 FPSCR fpscr = (FPSCR) FpscrExc;
894 VfpSavedState state = prepFpState(fpscr.rMode);
895 __asm__ __volatile__("" : "=m" (FpOp1_sw) : "m" (FpOp1_sw));
896 FpDest = FpOp1_sw;
897 __asm__ __volatile__("" :: "m" (FpDest));
898 finishVfp(fpscr, state, fpscr.fz);
899 FpscrExc = fpscr;
900 '''
901 vcvtSIntFpSIop = InstObjParams("vcvt", "VcvtSIntFpS", "FpRegRegOp",
902 { "code": vcvtSIntFpSCode,
903 "predicate_test": predicateTest,
904 "op_class": "SimdFloatCvtOp" }, [])
905 header_output += FpRegRegOpDeclare.subst(vcvtSIntFpSIop);
906 decoder_output += FpRegRegOpConstructor.subst(vcvtSIntFpSIop);
907 exec_output += PredOpExecute.subst(vcvtSIntFpSIop);
908
909 vcvtSIntFpDCode = vfpEnabledCheckCode + '''
910 FPSCR fpscr = (FPSCR) FpscrExc;
911 VfpSavedState state = prepFpState(fpscr.rMode);
912 __asm__ __volatile__("" : "=m" (FpOp1P0_sw) : "m" (FpOp1P0_sw));
913 double cDest = FpOp1P0_sw;
914 __asm__ __volatile__("" :: "m" (cDest));
915 finishVfp(fpscr, state, fpscr.fz);
916 FpDestP0_uw = dblLow(cDest);
917 FpDestP1_uw = dblHi(cDest);
918 FpscrExc = fpscr;
919 '''
920 vcvtSIntFpDIop = InstObjParams("vcvt", "VcvtSIntFpD", "FpRegRegOp",
921 { "code": vcvtSIntFpDCode,
922 "predicate_test": predicateTest,
923 "op_class": "SimdFloatCvtOp" }, [])
924 header_output += FpRegRegOpDeclare.subst(vcvtSIntFpDIop);
925 decoder_output += FpRegRegOpConstructor.subst(vcvtSIntFpDIop);
926 exec_output += PredOpExecute.subst(vcvtSIntFpDIop);
927
928 vcvtFpUIntSRCode = vfpEnabledCheckCode + '''
929 FPSCR fpscr = (FPSCR) FpscrExc;
930 VfpSavedState state = prepFpState(fpscr.rMode);
931 vfpFlushToZero(fpscr, FpOp1);
932 __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
933 FpDest_uw = vfpFpToFixed<float>(FpOp1, false, 32, 0, false);
934 __asm__ __volatile__("" :: "m" (FpDest_uw));
935 finishVfp(fpscr, state, fpscr.fz);
936 FpscrExc = fpscr;
937 '''
938 vcvtFpUIntSRIop = InstObjParams("vcvt", "VcvtFpUIntSR", "FpRegRegOp",
939 { "code": vcvtFpUIntSRCode,
940 "predicate_test": predicateTest,
941 "op_class": "SimdFloatCvtOp" }, [])
942 header_output += FpRegRegOpDeclare.subst(vcvtFpUIntSRIop);
943 decoder_output += FpRegRegOpConstructor.subst(vcvtFpUIntSRIop);
944 exec_output += PredOpExecute.subst(vcvtFpUIntSRIop);
945
946 vcvtFpUIntDRCode = vfpEnabledCheckCode + '''
947 FPSCR fpscr = (FPSCR) FpscrExc;
948 double cOp1 = dbl(FpOp1P0_uw, FpOp1P1_uw);
949 vfpFlushToZero(fpscr, cOp1);
950 VfpSavedState state = prepFpState(fpscr.rMode);
951 __asm__ __volatile__("" : "=m" (cOp1) : "m" (cOp1));
952 uint64_t result = vfpFpToFixed<double>(cOp1, false, 32, 0, false);
953 __asm__ __volatile__("" :: "m" (result));
954 finishVfp(fpscr, state, fpscr.fz);
955 FpDestP0_uw = result;
956 FpscrExc = fpscr;
957 '''
958 vcvtFpUIntDRIop = InstObjParams("vcvtr", "VcvtFpUIntDR", "FpRegRegOp",
959 { "code": vcvtFpUIntDRCode,
960 "predicate_test": predicateTest,
961 "op_class": "SimdFloatCvtOp" }, [])
962 header_output += FpRegRegOpDeclare.subst(vcvtFpUIntDRIop);
963 decoder_output += FpRegRegOpConstructor.subst(vcvtFpUIntDRIop);
964 exec_output += PredOpExecute.subst(vcvtFpUIntDRIop);
965
966 vcvtFpSIntSRCode = vfpEnabledCheckCode + '''
967 FPSCR fpscr = (FPSCR) FpscrExc;
968 VfpSavedState state = prepFpState(fpscr.rMode);
969 vfpFlushToZero(fpscr, FpOp1);
970 __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
971 FpDest_sw = vfpFpToFixed<float>(FpOp1, true, 32, 0, false);
972 __asm__ __volatile__("" :: "m" (FpDest_sw));
973 finishVfp(fpscr, state, fpscr.fz);
974 FpscrExc = fpscr;
975 '''
976 vcvtFpSIntSRIop = InstObjParams("vcvtr", "VcvtFpSIntSR", "FpRegRegOp",
977 { "code": vcvtFpSIntSRCode,
978 "predicate_test": predicateTest,
979 "op_class": "SimdFloatCvtOp" }, [])
980 header_output += FpRegRegOpDeclare.subst(vcvtFpSIntSRIop);
981 decoder_output += FpRegRegOpConstructor.subst(vcvtFpSIntSRIop);
982 exec_output += PredOpExecute.subst(vcvtFpSIntSRIop);
983
984 vcvtFpSIntDRCode = vfpEnabledCheckCode + '''
985 FPSCR fpscr = (FPSCR) FpscrExc;
986 double cOp1 = dbl(FpOp1P0_uw, FpOp1P1_uw);
987 vfpFlushToZero(fpscr, cOp1);
988 VfpSavedState state = prepFpState(fpscr.rMode);
989 __asm__ __volatile__("" : "=m" (cOp1) : "m" (cOp1));
990 int64_t result = vfpFpToFixed<double>(cOp1, true, 32, 0, false);
991 __asm__ __volatile__("" :: "m" (result));
992 finishVfp(fpscr, state, fpscr.fz);
993 FpDestP0_uw = result;
994 FpscrExc = fpscr;
995 '''
996 vcvtFpSIntDRIop = InstObjParams("vcvtr", "VcvtFpSIntDR", "FpRegRegOp",
997 { "code": vcvtFpSIntDRCode,
998 "predicate_test": predicateTest,
999 "op_class": "SimdFloatCvtOp" }, [])
1000 header_output += FpRegRegOpDeclare.subst(vcvtFpSIntDRIop);
1001 decoder_output += FpRegRegOpConstructor.subst(vcvtFpSIntDRIop);
1002 exec_output += PredOpExecute.subst(vcvtFpSIntDRIop);
1003
1004 vcvtFpUIntSCode = vfpEnabledCheckCode + '''
1005 FPSCR fpscr = (FPSCR) FpscrExc;
1006 vfpFlushToZero(fpscr, FpOp1);
1007 VfpSavedState state = prepFpState(fpscr.rMode);
1008 fesetround(FeRoundZero);
1009 __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
1010 FpDest_uw = vfpFpToFixed<float>(FpOp1, false, 32, 0);
1011 __asm__ __volatile__("" :: "m" (FpDest_uw));
1012 finishVfp(fpscr, state, fpscr.fz);
1013 FpscrExc = fpscr;
1014 '''
1015 vcvtFpUIntSIop = InstObjParams("vcvt", "VcvtFpUIntS", "FpRegRegOp",
1016 { "code": vcvtFpUIntSCode,
1017 "predicate_test": predicateTest,
1018 "op_class": "SimdFloatCvtOp" }, [])
1019 header_output += FpRegRegOpDeclare.subst(vcvtFpUIntSIop);
1020 decoder_output += FpRegRegOpConstructor.subst(vcvtFpUIntSIop);
1021 exec_output += PredOpExecute.subst(vcvtFpUIntSIop);
1022
1023 vcvtFpUIntDCode = vfpEnabledCheckCode + '''
1024 FPSCR fpscr = (FPSCR) FpscrExc;
1025 double cOp1 = dbl(FpOp1P0_uw, FpOp1P1_uw);
1026 vfpFlushToZero(fpscr, cOp1);
1027 VfpSavedState state = prepFpState(fpscr.rMode);
1028 fesetround(FeRoundZero);
1029 __asm__ __volatile__("" : "=m" (cOp1) : "m" (cOp1));
1030 uint64_t result = vfpFpToFixed<double>(cOp1, false, 32, 0);
1031 __asm__ __volatile__("" :: "m" (result));
1032 finishVfp(fpscr, state, fpscr.fz);
1033 FpDestP0_uw = result;
1034 FpscrExc = fpscr;
1035 '''
1036 vcvtFpUIntDIop = InstObjParams("vcvt", "VcvtFpUIntD", "FpRegRegOp",
1037 { "code": vcvtFpUIntDCode,
1038 "predicate_test": predicateTest,
1039 "op_class": "SimdFloatCvtOp" }, [])
1040 header_output += FpRegRegOpDeclare.subst(vcvtFpUIntDIop);
1041 decoder_output += FpRegRegOpConstructor.subst(vcvtFpUIntDIop);
1042 exec_output += PredOpExecute.subst(vcvtFpUIntDIop);
1043
1044 vcvtFpSIntSCode = vfpEnabledCheckCode + '''
1045 FPSCR fpscr = (FPSCR) FpscrExc;
1046 vfpFlushToZero(fpscr, FpOp1);
1047 VfpSavedState state = prepFpState(fpscr.rMode);
1048 fesetround(FeRoundZero);
1049 __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
1050 FpDest_sw = vfpFpToFixed<float>(FpOp1, true, 32, 0);
1051 __asm__ __volatile__("" :: "m" (FpDest_sw));
1052 finishVfp(fpscr, state, fpscr.fz);
1053 FpscrExc = fpscr;
1054 '''
1055 vcvtFpSIntSIop = InstObjParams("vcvt", "VcvtFpSIntS", "FpRegRegOp",
1056 { "code": vcvtFpSIntSCode,
1057 "predicate_test": predicateTest,
1058 "op_class": "SimdFloatCvtOp" }, [])
1059 header_output += FpRegRegOpDeclare.subst(vcvtFpSIntSIop);
1060 decoder_output += FpRegRegOpConstructor.subst(vcvtFpSIntSIop);
1061 exec_output += PredOpExecute.subst(vcvtFpSIntSIop);
1062
1063 vcvtFpSIntDCode = vfpEnabledCheckCode + '''
1064 FPSCR fpscr = (FPSCR) FpscrExc;
1065 double cOp1 = dbl(FpOp1P0_uw, FpOp1P1_uw);
1066 vfpFlushToZero(fpscr, cOp1);
1067 VfpSavedState state = prepFpState(fpscr.rMode);
1068 fesetround(FeRoundZero);
1069 __asm__ __volatile__("" : "=m" (cOp1) : "m" (cOp1));
1070 int64_t result = vfpFpToFixed<double>(cOp1, true, 32, 0);
1071 __asm__ __volatile__("" :: "m" (result));
1072 finishVfp(fpscr, state, fpscr.fz);
1073 FpDestP0_uw = result;
1074 FpscrExc = fpscr;
1075 '''
1076 vcvtFpSIntDIop = InstObjParams("vcvt", "VcvtFpSIntD", "FpRegRegOp",
1077 { "code": vcvtFpSIntDCode,
1078 "predicate_test": predicateTest,
1079 "op_class": "SimdFloatCvtOp" }, [])
1080 header_output += FpRegRegOpDeclare.subst(vcvtFpSIntDIop);
1081 decoder_output += FpRegRegOpConstructor.subst(vcvtFpSIntDIop);
1082 exec_output += PredOpExecute.subst(vcvtFpSIntDIop);
1083
1084 vcvtFpSFpDCode = vfpEnabledCheckCode + '''
1085 FPSCR fpscr = (FPSCR) FpscrExc;
1086 vfpFlushToZero(fpscr, FpOp1);
1087 VfpSavedState state = prepFpState(fpscr.rMode);
1088 __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
1089 double cDest = fixFpSFpDDest(FpscrExc, FpOp1);
1090 __asm__ __volatile__("" :: "m" (cDest));
1091 finishVfp(fpscr, state, fpscr.fz);
1092 FpDestP0_uw = dblLow(cDest);
1093 FpDestP1_uw = dblHi(cDest);
1094 FpscrExc = fpscr;
1095 '''
1096 vcvtFpSFpDIop = InstObjParams("vcvt", "VcvtFpSFpD", "FpRegRegOp",
1097 { "code": vcvtFpSFpDCode,
1098 "predicate_test": predicateTest,
1099 "op_class": "SimdFloatCvtOp" }, [])
1100 header_output += FpRegRegOpDeclare.subst(vcvtFpSFpDIop);
1101 decoder_output += FpRegRegOpConstructor.subst(vcvtFpSFpDIop);
1102 exec_output += PredOpExecute.subst(vcvtFpSFpDIop);
1103
1104 vcvtFpDFpSCode = vfpEnabledCheckCode + '''
1105 FPSCR fpscr = (FPSCR) FpscrExc;
1106 double cOp1 = dbl(FpOp1P0_uw, FpOp1P1_uw);
1107 vfpFlushToZero(fpscr, cOp1);
1108 VfpSavedState state = prepFpState(fpscr.rMode);
1109 __asm__ __volatile__("" : "=m" (cOp1) : "m" (cOp1));
1110 FpDest = fixFpDFpSDest(FpscrExc, cOp1);
1111 __asm__ __volatile__("" :: "m" (FpDest));
1112 finishVfp(fpscr, state, fpscr.fz);
1113 FpscrExc = fpscr;
1114 '''
1115 vcvtFpDFpSIop = InstObjParams("vcvt", "VcvtFpDFpS", "FpRegRegOp",
1116 { "code": vcvtFpDFpSCode,
1117 "predicate_test": predicateTest,
1118 "op_class": "SimdFloatCvtOp" }, [])
1119 header_output += FpRegRegOpDeclare.subst(vcvtFpDFpSIop);
1120 decoder_output += FpRegRegOpConstructor.subst(vcvtFpDFpSIop);
1121 exec_output += PredOpExecute.subst(vcvtFpDFpSIop);
1122
1123 vcvtFpHTFpSCode = vfpEnabledCheckCode + '''
1124 FPSCR fpscr = (FPSCR) FpscrExc;
1125 vfpFlushToZero(fpscr, FpOp1);
1126 VfpSavedState state = prepFpState(fpscr.rMode);
1127 __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
1128 FpDest = vcvtFpHFpS(fpscr, fpscr.dn, fpscr.ahp,
1129 bits(fpToBits(FpOp1), 31, 16));
1130 __asm__ __volatile__("" :: "m" (FpDest));
1131 finishVfp(fpscr, state, fpscr.fz);
1132 FpscrExc = fpscr;
1133 '''
1134 vcvtFpHTFpSIop = InstObjParams("vcvtt", "VcvtFpHTFpS", "FpRegRegOp",
1135 { "code": vcvtFpHTFpSCode,
1136 "predicate_test": predicateTest,
1137 "op_class": "SimdFloatCvtOp" }, [])
1138 header_output += FpRegRegOpDeclare.subst(vcvtFpHTFpSIop);
1139 decoder_output += FpRegRegOpConstructor.subst(vcvtFpHTFpSIop);
1140 exec_output += PredOpExecute.subst(vcvtFpHTFpSIop);
1141
1142 vcvtFpHBFpSCode = vfpEnabledCheckCode + '''
1143 FPSCR fpscr = (FPSCR) FpscrExc;
1144 VfpSavedState state = prepFpState(fpscr.rMode);
1145 __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
1146 FpDest = vcvtFpHFpS(fpscr, fpscr.dn, fpscr.ahp,
1147 bits(fpToBits(FpOp1), 15, 0));
1148 __asm__ __volatile__("" :: "m" (FpDest));
1149 finishVfp(fpscr, state, fpscr.fz);
1150 FpscrExc = fpscr;
1151 '''
1152 vcvtFpHBFpSIop = InstObjParams("vcvtb", "VcvtFpHBFpS", "FpRegRegOp",
1153 { "code": vcvtFpHBFpSCode,
1154 "predicate_test": predicateTest,
1155 "op_class": "SimdFloatCvtOp" }, [])
1156 header_output += FpRegRegOpDeclare.subst(vcvtFpHBFpSIop);
1157 decoder_output += FpRegRegOpConstructor.subst(vcvtFpHBFpSIop);
1158 exec_output += PredOpExecute.subst(vcvtFpHBFpSIop);
1159
1160 vcvtFpSFpHTCode = vfpEnabledCheckCode + '''
1161 FPSCR fpscr = (FPSCR) FpscrExc;
1162 vfpFlushToZero(fpscr, FpOp1);
1163 VfpSavedState state = prepFpState(fpscr.rMode);
1164 __asm__ __volatile__("" : "=m" (FpOp1), "=m" (FpDest_uw)
1165 : "m" (FpOp1), "m" (FpDest_uw));
1166 FpDest_uw = insertBits(FpDest_uw, 31, 16,,
1167 vcvtFpSFpH(fpscr, fpscr.fz, fpscr.dn,
1168 fpscr.rMode, fpscr.ahp, FpOp1));
1169 __asm__ __volatile__("" :: "m" (FpDest_uw));
1170 finishVfp(fpscr, state, fpscr.fz);
1171 FpscrExc = fpscr;
1172 '''
1173 vcvtFpSFpHTIop = InstObjParams("vcvtt", "VcvtFpSFpHT", "FpRegRegOp",
1174 { "code": vcvtFpHTFpSCode,
1175 "predicate_test": predicateTest,
1176 "op_class": "SimdFloatCvtOp" }, [])
1177 header_output += FpRegRegOpDeclare.subst(vcvtFpSFpHTIop);
1178 decoder_output += FpRegRegOpConstructor.subst(vcvtFpSFpHTIop);
1179 exec_output += PredOpExecute.subst(vcvtFpSFpHTIop);
1180
1181 vcvtFpSFpHBCode = vfpEnabledCheckCode + '''
1182 FPSCR fpscr = (FPSCR) FpscrExc;
1183 vfpFlushToZero(fpscr, FpOp1);
1184 VfpSavedState state = prepFpState(fpscr.rMode);
1185 __asm__ __volatile__("" : "=m" (FpOp1), "=m" (FpDest_uw)
1186 : "m" (FpOp1), "m" (FpDest_uw));
1187 FpDest_uw = insertBits(FpDest_uw, 15, 0,
1188 vcvtFpSFpH(fpscr, fpscr.fz, fpscr.dn,
1189 fpscr.rMode, fpscr.ahp, FpOp1));
1190 __asm__ __volatile__("" :: "m" (FpDest_uw));
1191 finishVfp(fpscr, state, fpscr.fz);
1192 FpscrExc = fpscr;
1193 '''
1194 vcvtFpSFpHBIop = InstObjParams("vcvtb", "VcvtFpSFpHB", "FpRegRegOp",
1195 { "code": vcvtFpSFpHBCode,
1196 "predicate_test": predicateTest,
1197 "op_class": "SimdFloatCvtOp" }, [])
1198 header_output += FpRegRegOpDeclare.subst(vcvtFpSFpHBIop);
1199 decoder_output += FpRegRegOpConstructor.subst(vcvtFpSFpHBIop);
1200 exec_output += PredOpExecute.subst(vcvtFpSFpHBIop);
1201
1202 vcmpSCode = vfpEnabledCheckCode + '''
1203 FPSCR fpscr = (FPSCR) FpscrExc;
1204 vfpFlushToZero(fpscr, FpDest, FpOp1);
1205 if (FpDest == FpOp1) {
1206 fpscr.n = 0; fpscr.z = 1; fpscr.c = 1; fpscr.v = 0;
1207 } else if (FpDest < FpOp1) {
1208 fpscr.n = 1; fpscr.z = 0; fpscr.c = 0; fpscr.v = 0;
1209 } else if (FpDest > FpOp1) {
1210 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 0;
1211 } else {
1212 const uint32_t qnan = 0x7fc00000;
1213 const bool nan1 = std::isnan(FpDest);
1214 const bool signal1 = nan1 && ((fpToBits(FpDest) & qnan) != qnan);
1215 const bool nan2 = std::isnan(FpOp1);
1216 const bool signal2 = nan2 && ((fpToBits(FpOp1) & qnan) != qnan);
1217 if (signal1 || signal2)
1218 fpscr.ioc = 1;
1219 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 1;
1220 }
1221 FpCondCodes = fpscr & FpCondCodesMask;
1222 FpscrExc = fpscr;
1223 '''
1224 vcmpSIop = InstObjParams("vcmps", "VcmpS", "FpRegRegOp",
1225 { "code": vcmpSCode,
1226 "predicate_test": predicateTest,
1227 "op_class": "SimdFloatCmpOp" }, [])
1228 header_output += FpRegRegOpDeclare.subst(vcmpSIop);
1229 decoder_output += FpRegRegOpConstructor.subst(vcmpSIop);
1230 exec_output += PredOpExecute.subst(vcmpSIop);
1231
1232 vcmpDCode = vfpEnabledCheckCode + '''
1233 double cOp1 = dbl(FpOp1P0_uw, FpOp1P1_uw);
1234 double cDest = dbl(FpDestP0_uw, FpDestP1_uw);
1235 FPSCR fpscr = (FPSCR) FpscrExc;
1236 vfpFlushToZero(fpscr, cDest, cOp1);
1237 if (cDest == cOp1) {
1238 fpscr.n = 0; fpscr.z = 1; fpscr.c = 1; fpscr.v = 0;
1239 } else if (cDest < cOp1) {
1240 fpscr.n = 1; fpscr.z = 0; fpscr.c = 0; fpscr.v = 0;
1241 } else if (cDest > cOp1) {
1242 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 0;
1243 } else {
1244 const uint64_t qnan = ULL(0x7ff8000000000000);
1245 const bool nan1 = std::isnan(cDest);
1246 const bool signal1 = nan1 && ((fpToBits(cDest) & qnan) != qnan);
1247 const bool nan2 = std::isnan(cOp1);
1248 const bool signal2 = nan2 && ((fpToBits(cOp1) & qnan) != qnan);
1249 if (signal1 || signal2)
1250 fpscr.ioc = 1;
1251 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 1;
1252 }
1253 FpCondCodes = fpscr & FpCondCodesMask;
1254 FpscrExc = fpscr;
1255 '''
1256 vcmpDIop = InstObjParams("vcmpd", "VcmpD", "FpRegRegOp",
1257 { "code": vcmpDCode,
1258 "predicate_test": predicateTest,
1259 "op_class": "SimdFloatCmpOp" }, [])
1260 header_output += FpRegRegOpDeclare.subst(vcmpDIop);
1261 decoder_output += FpRegRegOpConstructor.subst(vcmpDIop);
1262 exec_output += PredOpExecute.subst(vcmpDIop);
1263
1264 vcmpZeroSCode = vfpEnabledCheckCode + '''
1265 FPSCR fpscr = (FPSCR) FpscrExc;
1266 vfpFlushToZero(fpscr, FpDest);
1267 // This only handles imm == 0 for now.
1268 assert(imm == 0);
1269 if (FpDest == imm) {
1270 fpscr.n = 0; fpscr.z = 1; fpscr.c = 1; fpscr.v = 0;
1271 } else if (FpDest < imm) {
1272 fpscr.n = 1; fpscr.z = 0; fpscr.c = 0; fpscr.v = 0;
1273 } else if (FpDest > imm) {
1274 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 0;
1275 } else {
1276 const uint32_t qnan = 0x7fc00000;
1277 const bool nan = std::isnan(FpDest);
1278 const bool signal = nan && ((fpToBits(FpDest) & qnan) != qnan);
1279 if (signal)
1280 fpscr.ioc = 1;
1281 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 1;
1282 }
1283 FpCondCodes = fpscr & FpCondCodesMask;
1284 FpscrExc = fpscr;
1285 '''
1286 vcmpZeroSIop = InstObjParams("vcmpZeros", "VcmpZeroS", "FpRegImmOp",
1287 { "code": vcmpZeroSCode,
1288 "predicate_test": predicateTest,
1289 "op_class": "SimdFloatCmpOp" }, [])
1290 header_output += FpRegImmOpDeclare.subst(vcmpZeroSIop);
1291 decoder_output += FpRegImmOpConstructor.subst(vcmpZeroSIop);
1292 exec_output += PredOpExecute.subst(vcmpZeroSIop);
1293
1294 vcmpZeroDCode = vfpEnabledCheckCode + '''
1295 // This only handles imm == 0 for now.
1296 assert(imm == 0);
1297 double cDest = dbl(FpDestP0_uw, FpDestP1_uw);
1298 FPSCR fpscr = (FPSCR) FpscrExc;
1299 vfpFlushToZero(fpscr, cDest);
1300 if (cDest == imm) {
1301 fpscr.n = 0; fpscr.z = 1; fpscr.c = 1; fpscr.v = 0;
1302 } else if (cDest < imm) {
1303 fpscr.n = 1; fpscr.z = 0; fpscr.c = 0; fpscr.v = 0;
1304 } else if (cDest > imm) {
1305 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 0;
1306 } else {
1307 const uint64_t qnan = ULL(0x7ff8000000000000);
1308 const bool nan = std::isnan(cDest);
1309 const bool signal = nan && ((fpToBits(cDest) & qnan) != qnan);
1310 if (signal)
1311 fpscr.ioc = 1;
1312 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 1;
1313 }
1314 FpCondCodes = fpscr & FpCondCodesMask;
1315 FpscrExc = fpscr;
1316 '''
1317 vcmpZeroDIop = InstObjParams("vcmpZerod", "VcmpZeroD", "FpRegImmOp",
1318 { "code": vcmpZeroDCode,
1319 "predicate_test": predicateTest,
1320 "op_class": "SimdFloatCmpOp" }, [])
1321 header_output += FpRegImmOpDeclare.subst(vcmpZeroDIop);
1322 decoder_output += FpRegImmOpConstructor.subst(vcmpZeroDIop);
1323 exec_output += PredOpExecute.subst(vcmpZeroDIop);
1324
1325 vcmpeSCode = vfpEnabledCheckCode + '''
1326 FPSCR fpscr = (FPSCR) FpscrExc;
1327 vfpFlushToZero(fpscr, FpDest, FpOp1);
1328 if (FpDest == FpOp1) {
1329 fpscr.n = 0; fpscr.z = 1; fpscr.c = 1; fpscr.v = 0;
1330 } else if (FpDest < FpOp1) {
1331 fpscr.n = 1; fpscr.z = 0; fpscr.c = 0; fpscr.v = 0;
1332 } else if (FpDest > FpOp1) {
1333 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 0;
1334 } else {
1335 fpscr.ioc = 1;
1336 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 1;
1337 }
1338 FpCondCodes = fpscr & FpCondCodesMask;
1339 FpscrExc = fpscr;
1340 '''
1341 vcmpeSIop = InstObjParams("vcmpes", "VcmpeS", "FpRegRegOp",
1342 { "code": vcmpeSCode,
1343 "predicate_test": predicateTest,
1344 "op_class": "SimdFloatCmpOp" }, [])
1345 header_output += FpRegRegOpDeclare.subst(vcmpeSIop);
1346 decoder_output += FpRegRegOpConstructor.subst(vcmpeSIop);
1347 exec_output += PredOpExecute.subst(vcmpeSIop);
1348
1349 vcmpeDCode = vfpEnabledCheckCode + '''
1350 double cOp1 = dbl(FpOp1P0_uw, FpOp1P1_uw);
1351 double cDest = dbl(FpDestP0_uw, FpDestP1_uw);
1352 FPSCR fpscr = (FPSCR) FpscrExc;
1353 vfpFlushToZero(fpscr, cDest, cOp1);
1354 if (cDest == cOp1) {
1355 fpscr.n = 0; fpscr.z = 1; fpscr.c = 1; fpscr.v = 0;
1356 } else if (cDest < cOp1) {
1357 fpscr.n = 1; fpscr.z = 0; fpscr.c = 0; fpscr.v = 0;
1358 } else if (cDest > cOp1) {
1359 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 0;
1360 } else {
1361 fpscr.ioc = 1;
1362 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 1;
1363 }
1364 FpCondCodes = fpscr & FpCondCodesMask;
1365 FpscrExc = fpscr;
1366 '''
1367 vcmpeDIop = InstObjParams("vcmped", "VcmpeD", "FpRegRegOp",
1368 { "code": vcmpeDCode,
1369 "predicate_test": predicateTest,
1370 "op_class": "SimdFloatCmpOp" }, [])
1371 header_output += FpRegRegOpDeclare.subst(vcmpeDIop);
1372 decoder_output += FpRegRegOpConstructor.subst(vcmpeDIop);
1373 exec_output += PredOpExecute.subst(vcmpeDIop);
1374
1375 vcmpeZeroSCode = vfpEnabledCheckCode + '''
1376 FPSCR fpscr = (FPSCR) FpscrExc;
1377 vfpFlushToZero(fpscr, FpDest);
1378 if (FpDest == imm) {
1379 fpscr.n = 0; fpscr.z = 1; fpscr.c = 1; fpscr.v = 0;
1380 } else if (FpDest < imm) {
1381 fpscr.n = 1; fpscr.z = 0; fpscr.c = 0; fpscr.v = 0;
1382 } else if (FpDest > imm) {
1383 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 0;
1384 } else {
1385 fpscr.ioc = 1;
1386 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 1;
1387 }
1388 FpCondCodes = fpscr & FpCondCodesMask;
1389 FpscrExc = fpscr;
1390 '''
1391 vcmpeZeroSIop = InstObjParams("vcmpeZeros", "VcmpeZeroS", "FpRegImmOp",
1392 { "code": vcmpeZeroSCode,
1393 "predicate_test": predicateTest,
1394 "op_class": "SimdFloatCmpOp" }, [])
1395 header_output += FpRegImmOpDeclare.subst(vcmpeZeroSIop);
1396 decoder_output += FpRegImmOpConstructor.subst(vcmpeZeroSIop);
1397 exec_output += PredOpExecute.subst(vcmpeZeroSIop);
1398
1399 vcmpeZeroDCode = vfpEnabledCheckCode + '''
1400 double cDest = dbl(FpDestP0_uw, FpDestP1_uw);
1401 FPSCR fpscr = (FPSCR) FpscrExc;
1402 vfpFlushToZero(fpscr, cDest);
1403 if (cDest == imm) {
1404 fpscr.n = 0; fpscr.z = 1; fpscr.c = 1; fpscr.v = 0;
1405 } else if (cDest < imm) {
1406 fpscr.n = 1; fpscr.z = 0; fpscr.c = 0; fpscr.v = 0;
1407 } else if (cDest > imm) {
1408 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 0;
1409 } else {
1410 fpscr.ioc = 1;
1411 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 1;
1412 }
1413 FpCondCodes = fpscr & FpCondCodesMask;
1414 FpscrExc = fpscr;
1415 '''
1416 vcmpeZeroDIop = InstObjParams("vcmpeZerod", "VcmpeZeroD", "FpRegImmOp",
1417 { "code": vcmpeZeroDCode,
1418 "predicate_test": predicateTest,
1419 "op_class": "SimdFloatCmpOp" }, [])
1420 header_output += FpRegImmOpDeclare.subst(vcmpeZeroDIop);
1421 decoder_output += FpRegImmOpConstructor.subst(vcmpeZeroDIop);
1422 exec_output += PredOpExecute.subst(vcmpeZeroDIop);
1423}};
1424
1425let {{
1426
1427 header_output = ""
1428 decoder_output = ""
1429 exec_output = ""
1430
1431 vselSCode = vfpEnabledCheckCode + '''
1432 if (testPredicate(CondCodesNZ, CondCodesC, CondCodesV, cond)) {
1433 FpDest = FpOp1;
1434 } else {
1435 FpDest = FpOp2;
1436 } '''
1437
1438 vselSIop = InstObjParams("vsels", "VselS", "FpRegRegRegCondOp",
1439 { "code" : vselSCode,
1440 "predicate_test" : predicateTest,
1441 "op_class" : "SimdFloatCmpOp" }, [] )
1442 header_output += FpRegRegRegCondOpDeclare.subst(vselSIop);
1443 decoder_output += FpRegRegRegCondOpConstructor.subst(vselSIop);
1444 exec_output += PredOpExecute.subst(vselSIop);
1445
1446 vselDCode = vfpEnabledCheckCode + '''
1447 if (testPredicate(CondCodesNZ, CondCodesC, CondCodesV, cond)) {
1448 FpDestP0_uw = FpOp1P0_uw;
1449 FpDestP1_uw = FpOp1P1_uw;
1450 } else {
1451 FpDestP0_uw = FpOp2P0_uw;
1452 FpDestP1_uw = FpOp2P1_uw;
1453 } '''
1454
1455 vselDIop = InstObjParams("vseld", "VselD", "FpRegRegRegCondOp",
1456 { "code" : vselDCode,
1457 "predicate_test" : predicateTest,
1458 "op_class" : "SimdFloatCmpOp" }, [] )
1459 header_output += FpRegRegRegCondOpDeclare.subst(vselDIop);
1460 decoder_output += FpRegRegRegCondOpConstructor.subst(vselDIop);
1461 exec_output += PredOpExecute.subst(vselDIop);
1462}};
1463
1464
1465let {{
1466
1467 header_output = ""
1468 decoder_output = ""
1469 exec_output = ""
1470
1471 vcvtFpSFixedSCode = vfpEnabledCheckCode + '''
1472 FPSCR fpscr = (FPSCR) FpscrExc;
1473 vfpFlushToZero(fpscr, FpOp1);
1474 VfpSavedState state = prepFpState(fpscr.rMode);
1475 __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
1476 FpDest_sw = vfpFpToFixed<float>(FpOp1, true, 32, imm);
1477 __asm__ __volatile__("" :: "m" (FpDest_sw));
1478 finishVfp(fpscr, state, fpscr.fz);
1479 FpscrExc = fpscr;
1480 '''
1481 vcvtFpSFixedSIop = InstObjParams("vcvt", "VcvtFpSFixedS", "FpRegRegImmOp",
1482 { "code": vcvtFpSFixedSCode,
1483 "predicate_test": predicateTest,
1484 "op_class": "SimdFloatCvtOp" }, [])
1485 header_output += FpRegRegImmOpDeclare.subst(vcvtFpSFixedSIop);
1486 decoder_output += FpRegRegImmOpConstructor.subst(vcvtFpSFixedSIop);
1487 exec_output += PredOpExecute.subst(vcvtFpSFixedSIop);
1488
1489 vcvtFpSFixedDCode = vfpEnabledCheckCode + '''
1490 FPSCR fpscr = (FPSCR) FpscrExc;
1491 double cOp1 = dbl(FpOp1P0_uw, FpOp1P1_uw);
1492 vfpFlushToZero(fpscr, cOp1);
1493 VfpSavedState state = prepFpState(fpscr.rMode);
1494 __asm__ __volatile__("" : "=m" (cOp1) : "m" (cOp1));
1495 uint64_t mid = vfpFpToFixed<double>(cOp1, true, 32, imm);
1496 __asm__ __volatile__("" :: "m" (mid));
1497 finishVfp(fpscr, state, fpscr.fz);
1498 FpDestP0_uw = mid;
1499 FpDestP1_uw = mid >> 32;
1500 FpscrExc = fpscr;
1501 '''
1502 vcvtFpSFixedDIop = InstObjParams("vcvt", "VcvtFpSFixedD", "FpRegRegImmOp",
1503 { "code": vcvtFpSFixedDCode,
1504 "predicate_test": predicateTest,
1505 "op_class": "SimdFloatCvtOp" }, [])
1506 header_output += FpRegRegImmOpDeclare.subst(vcvtFpSFixedDIop);
1507 decoder_output += FpRegRegImmOpConstructor.subst(vcvtFpSFixedDIop);
1508 exec_output += PredOpExecute.subst(vcvtFpSFixedDIop);
1509
1510 vcvtFpUFixedSCode = vfpEnabledCheckCode + '''
1511 FPSCR fpscr = (FPSCR) FpscrExc;
1512 vfpFlushToZero(fpscr, FpOp1);
1513 VfpSavedState state = prepFpState(fpscr.rMode);
1514 __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
1515 FpDest_uw = vfpFpToFixed<float>(FpOp1, false, 32, imm);
1516 __asm__ __volatile__("" :: "m" (FpDest_uw));
1517 finishVfp(fpscr, state, fpscr.fz);
1518 FpscrExc = fpscr;
1519 '''
1520 vcvtFpUFixedSIop = InstObjParams("vcvt", "VcvtFpUFixedS", "FpRegRegImmOp",
1521 { "code": vcvtFpUFixedSCode,
1522 "predicate_test": predicateTest,
1523 "op_class": "SimdFloatCvtOp" }, [])
1524 header_output += FpRegRegImmOpDeclare.subst(vcvtFpUFixedSIop);
1525 decoder_output += FpRegRegImmOpConstructor.subst(vcvtFpUFixedSIop);
1526 exec_output += PredOpExecute.subst(vcvtFpUFixedSIop);
1527
1528 vcvtFpUFixedDCode = vfpEnabledCheckCode + '''
1529 FPSCR fpscr = (FPSCR) FpscrExc;
1530 double cOp1 = dbl(FpOp1P0_uw, FpOp1P1_uw);
1531 vfpFlushToZero(fpscr, cOp1);
1532 VfpSavedState state = prepFpState(fpscr.rMode);
1533 __asm__ __volatile__("" : "=m" (cOp1) : "m" (cOp1));
1534 uint64_t mid = vfpFpToFixed<double>(cOp1, false, 32, imm);
1535 __asm__ __volatile__("" :: "m" (mid));
1536 finishVfp(fpscr, state, fpscr.fz);
1537 FpDestP0_uw = mid;
1538 FpDestP1_uw = mid >> 32;
1539 FpscrExc = fpscr;
1540 '''
1541 vcvtFpUFixedDIop = InstObjParams("vcvt", "VcvtFpUFixedD", "FpRegRegImmOp",
1542 { "code": vcvtFpUFixedDCode,
1543 "predicate_test": predicateTest,
1544 "op_class": "SimdFloatCvtOp" }, [])
1545 header_output += FpRegRegImmOpDeclare.subst(vcvtFpUFixedDIop);
1546 decoder_output += FpRegRegImmOpConstructor.subst(vcvtFpUFixedDIop);
1547 exec_output += PredOpExecute.subst(vcvtFpUFixedDIop);
1548
1549 vcvtSFixedFpSCode = vfpEnabledCheckCode + '''
1550 FPSCR fpscr = (FPSCR) FpscrExc;
1551 VfpSavedState state = prepFpState(fpscr.rMode);
1552 __asm__ __volatile__("" : "=m" (FpOp1_sw) : "m" (FpOp1_sw));
1553 FpDest = vfpSFixedToFpS(fpscr.fz, fpscr.dn, FpOp1_sw, 32, imm);
1554 __asm__ __volatile__("" :: "m" (FpDest));
1555 finishVfp(fpscr, state, fpscr.fz);
1556 FpscrExc = fpscr;
1557 '''
1558 vcvtSFixedFpSIop = InstObjParams("vcvt", "VcvtSFixedFpS", "FpRegRegImmOp",
1559 { "code": vcvtSFixedFpSCode,
1560 "predicate_test": predicateTest,
1561 "op_class": "SimdFloatCvtOp" }, [])
1562 header_output += FpRegRegImmOpDeclare.subst(vcvtSFixedFpSIop);
1563 decoder_output += FpRegRegImmOpConstructor.subst(vcvtSFixedFpSIop);
1564 exec_output += PredOpExecute.subst(vcvtSFixedFpSIop);
1565
1566 vcvtSFixedFpDCode = vfpEnabledCheckCode + '''
1567 FPSCR fpscr = (FPSCR) FpscrExc;
1568 uint64_t mid = ((uint64_t)FpOp1P0_uw | ((uint64_t)FpOp1P1_uw << 32));
1569 VfpSavedState state = prepFpState(fpscr.rMode);
1570 __asm__ __volatile__("" : "=m" (mid) : "m" (mid));
1571 double cDest = vfpSFixedToFpD(fpscr.fz, fpscr.dn, mid, 32, imm);
1572 __asm__ __volatile__("" :: "m" (cDest));
1573 finishVfp(fpscr, state, fpscr.fz);
1574 FpDestP0_uw = dblLow(cDest);
1575 FpDestP1_uw = dblHi(cDest);
1576 FpscrExc = fpscr;
1577 '''
1578 vcvtSFixedFpDIop = InstObjParams("vcvt", "VcvtSFixedFpD", "FpRegRegImmOp",
1579 { "code": vcvtSFixedFpDCode,
1580 "predicate_test": predicateTest,
1581 "op_class": "SimdFloatCvtOp" }, [])
1582 header_output += FpRegRegImmOpDeclare.subst(vcvtSFixedFpDIop);
1583 decoder_output += FpRegRegImmOpConstructor.subst(vcvtSFixedFpDIop);
1584 exec_output += PredOpExecute.subst(vcvtSFixedFpDIop);
1585
1586 vcvtUFixedFpSCode = vfpEnabledCheckCode + '''
1587 FPSCR fpscr = (FPSCR) FpscrExc;
1588 VfpSavedState state = prepFpState(fpscr.rMode);
1589 __asm__ __volatile__("" : "=m" (FpOp1_uw) : "m" (FpOp1_uw));
1590 FpDest = vfpUFixedToFpS(fpscr.fz, fpscr.dn, FpOp1_uw, 32, imm);
1591 __asm__ __volatile__("" :: "m" (FpDest));
1592 finishVfp(fpscr, state, fpscr.fz);
1593 FpscrExc = fpscr;
1594 '''
1595 vcvtUFixedFpSIop = InstObjParams("vcvt", "VcvtUFixedFpS", "FpRegRegImmOp",
1596 { "code": vcvtUFixedFpSCode,
1597 "predicate_test": predicateTest,
1598 "op_class": "SimdFloatCvtOp" }, [])
1599 header_output += FpRegRegImmOpDeclare.subst(vcvtUFixedFpSIop);
1600 decoder_output += FpRegRegImmOpConstructor.subst(vcvtUFixedFpSIop);
1601 exec_output += PredOpExecute.subst(vcvtUFixedFpSIop);
1602
1603 vcvtUFixedFpDCode = vfpEnabledCheckCode + '''
1604 FPSCR fpscr = (FPSCR) FpscrExc;
1605 uint64_t mid = ((uint64_t)FpOp1P0_uw | ((uint64_t)FpOp1P1_uw << 32));
1606 VfpSavedState state = prepFpState(fpscr.rMode);
1607 __asm__ __volatile__("" : "=m" (mid) : "m" (mid));
1608 double cDest = vfpUFixedToFpD(fpscr.fz, fpscr.dn, mid, 32, imm);
1609 __asm__ __volatile__("" :: "m" (cDest));
1610 finishVfp(fpscr, state, fpscr.fz);
1611 FpDestP0_uw = dblLow(cDest);
1612 FpDestP1_uw = dblHi(cDest);
1613 FpscrExc = fpscr;
1614 '''
1615 vcvtUFixedFpDIop = InstObjParams("vcvt", "VcvtUFixedFpD", "FpRegRegImmOp",
1616 { "code": vcvtUFixedFpDCode,
1617 "predicate_test": predicateTest,
1618 "op_class": "SimdFloatCvtOp" }, [])
1619 header_output += FpRegRegImmOpDeclare.subst(vcvtUFixedFpDIop);
1620 decoder_output += FpRegRegImmOpConstructor.subst(vcvtUFixedFpDIop);
1621 exec_output += PredOpExecute.subst(vcvtUFixedFpDIop);
1622
1623 vcvtFpSHFixedSCode = vfpEnabledCheckCode + '''
1624 FPSCR fpscr = (FPSCR) FpscrExc;
1625 vfpFlushToZero(fpscr, FpOp1);
1626 VfpSavedState state = prepFpState(fpscr.rMode);
1627 __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
1628 FpDest_sh = vfpFpToFixed<float>(FpOp1, true, 16, imm);
1629 __asm__ __volatile__("" :: "m" (FpDest_sh));
1630 finishVfp(fpscr, state, fpscr.fz);
1631 FpscrExc = fpscr;
1632 '''
1633 vcvtFpSHFixedSIop = InstObjParams("vcvt", "VcvtFpSHFixedS",
1634 "FpRegRegImmOp",
1635 { "code": vcvtFpSHFixedSCode,
1636 "predicate_test": predicateTest,
1637 "op_class": "SimdFloatCvtOp" }, [])
1638 header_output += FpRegRegImmOpDeclare.subst(vcvtFpSHFixedSIop);
1639 decoder_output += FpRegRegImmOpConstructor.subst(vcvtFpSHFixedSIop);
1640 exec_output += PredOpExecute.subst(vcvtFpSHFixedSIop);
1641
1642 vcvtFpSHFixedDCode = vfpEnabledCheckCode + '''
1643 FPSCR fpscr = (FPSCR) FpscrExc;
1644 double cOp1 = dbl(FpOp1P0_uw, FpOp1P1_uw);
1645 vfpFlushToZero(fpscr, cOp1);
1646 VfpSavedState state = prepFpState(fpscr.rMode);
1647 __asm__ __volatile__("" : "=m" (cOp1) : "m" (cOp1));
1648 uint64_t result = vfpFpToFixed<double>(cOp1, true, 16, imm);
1649 __asm__ __volatile__("" :: "m" (result));
1650 finishVfp(fpscr, state, fpscr.fz);
1651 FpDestP0_uw = result;
1652 FpDestP1_uw = result >> 32;
1653 FpscrExc = fpscr;
1654 '''
1655 vcvtFpSHFixedDIop = InstObjParams("vcvt", "VcvtFpSHFixedD",
1656 "FpRegRegImmOp",
1657 { "code": vcvtFpSHFixedDCode,
1658 "predicate_test": predicateTest,
1659 "op_class": "SimdFloatCvtOp" }, [])
1660 header_output += FpRegRegImmOpDeclare.subst(vcvtFpSHFixedDIop);
1661 decoder_output += FpRegRegImmOpConstructor.subst(vcvtFpSHFixedDIop);
1662 exec_output += PredOpExecute.subst(vcvtFpSHFixedDIop);
1663
1664 vcvtFpUHFixedSCode = vfpEnabledCheckCode + '''
1665 FPSCR fpscr = (FPSCR) FpscrExc;
1666 vfpFlushToZero(fpscr, FpOp1);
1667 VfpSavedState state = prepFpState(fpscr.rMode);
1668 __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
1669 FpDest_uh = vfpFpToFixed<float>(FpOp1, false, 16, imm);
1670 __asm__ __volatile__("" :: "m" (FpDest_uh));
1671 finishVfp(fpscr, state, fpscr.fz);
1672 FpscrExc = fpscr;
1673 '''
1674 vcvtFpUHFixedSIop = InstObjParams("vcvt", "VcvtFpUHFixedS",
1675 "FpRegRegImmOp",
1676 { "code": vcvtFpUHFixedSCode,
1677 "predicate_test": predicateTest,
1678 "op_class": "SimdFloatCvtOp" }, [])
1679 header_output += FpRegRegImmOpDeclare.subst(vcvtFpUHFixedSIop);
1680 decoder_output += FpRegRegImmOpConstructor.subst(vcvtFpUHFixedSIop);
1681 exec_output += PredOpExecute.subst(vcvtFpUHFixedSIop);
1682
1683 vcvtFpUHFixedDCode = vfpEnabledCheckCode + '''
1684 FPSCR fpscr = (FPSCR) FpscrExc;
1685 double cOp1 = dbl(FpOp1P0_uw, FpOp1P1_uw);
1686 vfpFlushToZero(fpscr, cOp1);
1687 VfpSavedState state = prepFpState(fpscr.rMode);
1688 __asm__ __volatile__("" : "=m" (cOp1) : "m" (cOp1));
1689 uint64_t mid = vfpFpToFixed<double>(cOp1, false, 16, imm);
1690 __asm__ __volatile__("" :: "m" (mid));
1691 finishVfp(fpscr, state, fpscr.fz);
1692 FpDestP0_uw = mid;
1693 FpDestP1_uw = mid >> 32;
1694 FpscrExc = fpscr;
1695 '''
1696 vcvtFpUHFixedDIop = InstObjParams("vcvt", "VcvtFpUHFixedD",
1697 "FpRegRegImmOp",
1698 { "code": vcvtFpUHFixedDCode,
1699 "predicate_test": predicateTest,
1700 "op_class": "SimdFloatCvtOp" }, [])
1701 header_output += FpRegRegImmOpDeclare.subst(vcvtFpUHFixedDIop);
1702 decoder_output += FpRegRegImmOpConstructor.subst(vcvtFpUHFixedDIop);
1703 exec_output += PredOpExecute.subst(vcvtFpUHFixedDIop);
1704
1705 vcvtSHFixedFpSCode = vfpEnabledCheckCode + '''
1706 FPSCR fpscr = (FPSCR) FpscrExc;
1707 VfpSavedState state = prepFpState(fpscr.rMode);
1708 __asm__ __volatile__("" : "=m" (FpOp1_sh) : "m" (FpOp1_sh));
1709 FpDest = vfpSFixedToFpS(fpscr.fz, fpscr.dn, FpOp1_sh, 16, imm);
1710 __asm__ __volatile__("" :: "m" (FpDest));
1711 finishVfp(fpscr, state, fpscr.fz);
1712 FpscrExc = fpscr;
1713 '''
1714 vcvtSHFixedFpSIop = InstObjParams("vcvt", "VcvtSHFixedFpS",
1715 "FpRegRegImmOp",
1716 { "code": vcvtSHFixedFpSCode,
1717 "predicate_test": predicateTest,
1718 "op_class": "SimdFloatCvtOp" }, [])
1719 header_output += FpRegRegImmOpDeclare.subst(vcvtSHFixedFpSIop);
1720 decoder_output += FpRegRegImmOpConstructor.subst(vcvtSHFixedFpSIop);
1721 exec_output += PredOpExecute.subst(vcvtSHFixedFpSIop);
1722
1723 vcvtSHFixedFpDCode = vfpEnabledCheckCode + '''
1724 FPSCR fpscr = (FPSCR) FpscrExc;
1725 uint64_t mid = ((uint64_t)FpOp1P0_uw | ((uint64_t)FpOp1P1_uw << 32));
1726 VfpSavedState state = prepFpState(fpscr.rMode);
1727 __asm__ __volatile__("" : "=m" (mid) : "m" (mid));
1728 double cDest = vfpSFixedToFpD(fpscr.fz, fpscr.dn, mid, 16, imm);
1729 __asm__ __volatile__("" :: "m" (cDest));
1730 finishVfp(fpscr, state, fpscr.fz);
1731 FpDestP0_uw = dblLow(cDest);
1732 FpDestP1_uw = dblHi(cDest);
1733 FpscrExc = fpscr;
1734 '''
1735 vcvtSHFixedFpDIop = InstObjParams("vcvt", "VcvtSHFixedFpD",
1736 "FpRegRegImmOp",
1737 { "code": vcvtSHFixedFpDCode,
1738 "predicate_test": predicateTest,
1739 "op_class": "SimdFloatCvtOp" }, [])
1740 header_output += FpRegRegImmOpDeclare.subst(vcvtSHFixedFpDIop);
1741 decoder_output += FpRegRegImmOpConstructor.subst(vcvtSHFixedFpDIop);
1742 exec_output += PredOpExecute.subst(vcvtSHFixedFpDIop);
1743
1744 vcvtUHFixedFpSCode = vfpEnabledCheckCode + '''
1745 FPSCR fpscr = (FPSCR) FpscrExc;
1746 VfpSavedState state = prepFpState(fpscr.rMode);
1747 __asm__ __volatile__("" : "=m" (FpOp1_uh) : "m" (FpOp1_uh));
1748 FpDest = vfpUFixedToFpS(fpscr.fz, fpscr.dn, FpOp1_uh, 16, imm);
1749 __asm__ __volatile__("" :: "m" (FpDest));
1750 finishVfp(fpscr, state, fpscr.fz);
1751 FpscrExc = fpscr;
1752 '''
1753 vcvtUHFixedFpSIop = InstObjParams("vcvt", "VcvtUHFixedFpS",
1754 "FpRegRegImmOp",
1755 { "code": vcvtUHFixedFpSCode,
1756 "predicate_test": predicateTest,
1757 "op_class": "SimdFloatCvtOp" }, [])
1758 header_output += FpRegRegImmOpDeclare.subst(vcvtUHFixedFpSIop);
1759 decoder_output += FpRegRegImmOpConstructor.subst(vcvtUHFixedFpSIop);
1760 exec_output += PredOpExecute.subst(vcvtUHFixedFpSIop);
1761
1762 vcvtUHFixedFpDCode = vfpEnabledCheckCode + '''
1763 FPSCR fpscr = (FPSCR) FpscrExc;
1764 uint64_t mid = ((uint64_t)FpOp1P0_uw | ((uint64_t)FpOp1P1_uw << 32));
1765 VfpSavedState state = prepFpState(fpscr.rMode);
1766 __asm__ __volatile__("" : "=m" (mid) : "m" (mid));
1767 double cDest = vfpUFixedToFpD(fpscr.fz, fpscr.dn, mid, 16, imm);
1768 __asm__ __volatile__("" :: "m" (cDest));
1769 finishVfp(fpscr, state, fpscr.fz);
1770 FpDestP0_uw = dblLow(cDest);
1771 FpDestP1_uw = dblHi(cDest);
1772 FpscrExc = fpscr;
1773 '''
1774 vcvtUHFixedFpDIop = InstObjParams("vcvt", "VcvtUHFixedFpD",
1775 "FpRegRegImmOp",
1776 { "code": vcvtUHFixedFpDCode,
1777 "predicate_test": predicateTest,
1778 "op_class": "SimdFloatCvtOp" }, [])
1779 header_output += FpRegRegImmOpDeclare.subst(vcvtUHFixedFpDIop);
1780 decoder_output += FpRegRegImmOpConstructor.subst(vcvtUHFixedFpDIop);
1781 exec_output += PredOpExecute.subst(vcvtUHFixedFpDIop);
1782}};