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