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