cpu. arch: add initiateMemRead() to ExecContext interface
[gem5.git] / src / arch / arm / isa / templates / neon64.isa
1 // -*- mode: c++ -*-
2
3 // Copyright (c) 2012-2013 ARM Limited
4 // All rights reserved
5 //
6 // The license below extends only to copyright in the software and shall
7 // not be construed as granting a license to any other intellectual
8 // property including but not limited to intellectual property relating
9 // to a hardware implementation of the functionality of the software
10 // licensed hereunder. You may use the software subject to the license
11 // terms below provided that you ensure that this notice is replicated
12 // unmodified and in its entirety in all distributions of the software,
13 // modified or unmodified, in source code or in binary form.
14 //
15 // Redistribution and use in source and binary forms, with or without
16 // modification, are permitted provided that the following conditions are
17 // met: redistributions of source code must retain the above copyright
18 // notice, this list of conditions and the following disclaimer;
19 // redistributions in binary form must reproduce the above copyright
20 // notice, this list of conditions and the following disclaimer in the
21 // documentation and/or other materials provided with the distribution;
22 // neither the name of the copyright holders nor the names of its
23 // contributors may be used to endorse or promote products derived from
24 // this software without specific prior written permission.
25 //
26 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
27 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
28 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
29 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
30 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
31 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
32 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
33 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
34 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
35 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
36 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37 //
38 // Authors: Mbou Eyole
39 // Giacomo Gabrielli
40
41 let {{
42 simd64EnabledCheckCode = vfp64EnabledCheckCode
43 }};
44
45 def template NeonX2RegOpDeclare {{
46 template <class _Element>
47 class %(class_name)s : public %(base_class)s
48 {
49 protected:
50 typedef _Element Element;
51 public:
52 // Constructor
53 %(class_name)s(ExtMachInst machInst,
54 IntRegIndex _dest, IntRegIndex _op1, IntRegIndex _op2)
55 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
56 _dest, _op1, _op2)
57 {
58 %(constructor)s;
59 }
60
61 %(BasicExecDeclare)s
62 };
63 }};
64
65 def template NeonX2RegImmOpDeclare {{
66 template <class _Element>
67 class %(class_name)s : public %(base_class)s
68 {
69 protected:
70 typedef _Element Element;
71 public:
72 // Constructor
73 %(class_name)s(ExtMachInst machInst,
74 IntRegIndex _dest, IntRegIndex _op1, IntRegIndex _op2,
75 uint64_t _imm)
76 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
77 _dest, _op1, _op2, _imm)
78 {
79 %(constructor)s;
80 }
81
82 %(BasicExecDeclare)s
83 };
84 }};
85
86 def template NeonX1RegOpDeclare {{
87 template <class _Element>
88 class %(class_name)s : public %(base_class)s
89 {
90 protected:
91 typedef _Element Element;
92 public:
93 // Constructor
94 %(class_name)s(ExtMachInst machInst,
95 IntRegIndex _dest, IntRegIndex _op1)
96 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
97 _dest, _op1)
98 {
99 %(constructor)s;
100 }
101
102 %(BasicExecDeclare)s
103 };
104 }};
105
106 def template NeonX1RegImmOpDeclare {{
107 template <class _Element>
108 class %(class_name)s : public %(base_class)s
109 {
110 protected:
111 typedef _Element Element;
112 public:
113 // Constructor
114 %(class_name)s(ExtMachInst machInst,
115 IntRegIndex _dest, IntRegIndex _op1, uint64_t _imm)
116 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
117 _dest, _op1, _imm)
118 {
119 %(constructor)s;
120 }
121
122 %(BasicExecDeclare)s
123 };
124 }};
125
126 def template NeonX1Reg2ImmOpDeclare {{
127 template <class _Element>
128 class %(class_name)s : public %(base_class)s
129 {
130 protected:
131 typedef _Element Element;
132 public:
133 // Constructor
134 %(class_name)s(ExtMachInst machInst,
135 IntRegIndex _dest, IntRegIndex _op1, uint64_t _imm1,
136 uint64_t _imm2)
137 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
138 _dest, _op1, _imm1, _imm2)
139 {
140 %(constructor)s;
141 }
142
143 %(BasicExecDeclare)s
144 };
145 }};
146
147 def template NeonX1RegImmOnlyOpDeclare {{
148 template <class _Element>
149 class %(class_name)s : public %(base_class)s
150 {
151 protected:
152 typedef _Element Element;
153 public:
154 // Constructor
155 %(class_name)s(ExtMachInst machInst,
156 IntRegIndex _dest, uint64_t _imm)
157 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
158 _dest, _imm)
159 {
160 %(constructor)s;
161 }
162
163 %(BasicExecDeclare)s
164 };
165 }};
166
167 def template NeonXExecDeclare {{
168 template
169 Fault %(class_name)s<%(targs)s>::execute(
170 CPU_EXEC_CONTEXT *, Trace::InstRecord *) const;
171 }};
172
173 def template NeonXEqualRegOpExecute {{
174 template <class Element>
175 Fault %(class_name)s<Element>::execute(CPU_EXEC_CONTEXT *xc,
176 Trace::InstRecord *traceData) const
177 {
178 Fault fault = NoFault;
179 %(op_decl)s;
180 %(op_rd)s;
181
182 const unsigned rCount = %(r_count)d;
183 const unsigned eCount = rCount * sizeof(FloatRegBits) / sizeof(Element);
184 const unsigned eCountFull = 4 * sizeof(FloatRegBits) / sizeof(Element);
185
186 union RegVect {
187 FloatRegBits regs[rCount];
188 Element elements[eCount];
189 };
190
191 union FullRegVect {
192 FloatRegBits regs[4];
193 Element elements[eCountFull];
194 };
195
196 %(code)s;
197 if (fault == NoFault)
198 {
199 %(op_wb)s;
200 }
201
202 return fault;
203 }
204 }};
205
206 def template NeonXUnequalRegOpExecute {{
207 template <class Element>
208 Fault %(class_name)s<Element>::execute(CPU_EXEC_CONTEXT *xc,
209 Trace::InstRecord *traceData) const
210 {
211 typedef typename bigger_type_t<Element>::type BigElement;
212 Fault fault = NoFault;
213 %(op_decl)s;
214 %(op_rd)s;
215
216 const unsigned rCount = %(r_count)d;
217 const unsigned eCount = rCount * sizeof(FloatRegBits) / sizeof(Element);
218 const unsigned eCountFull = 4 * sizeof(FloatRegBits) / sizeof(Element);
219
220 union RegVect {
221 FloatRegBits regs[rCount];
222 Element elements[eCount];
223 BigElement bigElements[eCount / 2];
224 };
225
226 union BigRegVect {
227 FloatRegBits regs[2 * rCount];
228 BigElement elements[eCount];
229 };
230
231 union FullRegVect {
232 FloatRegBits regs[4];
233 Element elements[eCountFull];
234 };
235
236 %(code)s;
237 if (fault == NoFault)
238 {
239 %(op_wb)s;
240 }
241
242 return fault;
243 }
244 }};
245
246 def template MicroNeonMemDeclare64 {{
247 class %(class_name)s : public %(base_class)s
248 {
249 protected:
250 // True if the base register is SP (used for SP alignment checking)
251 bool baseIsSP;
252 // Access size in bytes
253 uint8_t accSize;
254 // Vector element size (0 -> 8-bit, 1 -> 16-bit, 2 -> 32-bit,
255 // 3 -> 64-bit)
256 uint8_t eSize;
257
258 public:
259 %(class_name)s(ExtMachInst machInst, RegIndex _dest, RegIndex _ura,
260 uint32_t _imm, unsigned extraMemFlags, bool _baseIsSP,
261 uint8_t _accSize, uint8_t _eSize)
262 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, _dest,
263 _ura, _imm),
264 baseIsSP(_baseIsSP), accSize(_accSize), eSize(_eSize)
265 {
266 memAccessFlags |= extraMemFlags;
267 %(constructor)s;
268 }
269
270 %(BasicExecDeclare)s
271 %(InitiateAccDeclare)s
272 %(CompleteAccDeclare)s
273 };
274 }};
275
276 def template NeonLoadExecute64 {{
277 Fault %(class_name)s::execute(
278 CPU_EXEC_CONTEXT *xc, Trace::InstRecord *traceData) const
279 {
280 Addr EA;
281 Fault fault = NoFault;
282
283 %(op_decl)s;
284 %(mem_decl)s;
285 %(op_rd)s;
286 %(ea_code)s;
287
288 MemUnion memUnion;
289 uint8_t *dataPtr = memUnion.bytes;
290
291 if (fault == NoFault) {
292 fault = xc->readMem(EA, dataPtr, accSize, memAccessFlags);
293 %(memacc_code)s;
294 }
295
296 if (fault == NoFault) {
297 %(op_wb)s;
298 }
299
300 return fault;
301 }
302 }};
303
304 def template NeonLoadInitiateAcc64 {{
305 Fault %(class_name)s::initiateAcc(
306 CPU_EXEC_CONTEXT *xc, Trace::InstRecord *traceData) const
307 {
308 Addr EA;
309 Fault fault = NoFault;
310
311 %(op_decl)s;
312 %(mem_decl)s;
313 %(op_rd)s;
314 %(ea_code)s;
315
316 if (fault == NoFault) {
317 fault = xc->initiateMemRead(EA, accSize, memAccessFlags);
318 }
319
320 return fault;
321 }
322 }};
323
324 def template NeonLoadCompleteAcc64 {{
325 Fault %(class_name)s::completeAcc(
326 PacketPtr pkt, CPU_EXEC_CONTEXT *xc,
327 Trace::InstRecord *traceData) const
328 {
329 Fault fault = NoFault;
330
331 %(mem_decl)s;
332 %(op_decl)s;
333 %(op_rd)s;
334
335 MemUnion &memUnion = *(MemUnion *)pkt->getPtr<uint8_t>();
336
337 if (fault == NoFault) {
338 %(memacc_code)s;
339 }
340
341 if (fault == NoFault) {
342 %(op_wb)s;
343 }
344
345 return fault;
346 }
347 }};
348
349 def template NeonStoreExecute64 {{
350 Fault %(class_name)s::execute(
351 CPU_EXEC_CONTEXT *xc, Trace::InstRecord *traceData) const
352 {
353 Addr EA;
354 Fault fault = NoFault;
355
356 %(op_decl)s;
357 %(mem_decl)s;
358 %(op_rd)s;
359 %(ea_code)s;
360
361 MemUnion memUnion;
362 uint8_t *dataPtr = memUnion.bytes;
363
364 if (fault == NoFault) {
365 %(memacc_code)s;
366 }
367
368 if (fault == NoFault) {
369 fault = xc->writeMem(dataPtr, accSize, EA, memAccessFlags,
370 NULL);
371 }
372
373 if (fault == NoFault) {
374 %(op_wb)s;
375 }
376
377 return fault;
378 }
379 }};
380
381 def template NeonStoreInitiateAcc64 {{
382 Fault %(class_name)s::initiateAcc(
383 CPU_EXEC_CONTEXT *xc, Trace::InstRecord *traceData) const
384 {
385 Addr EA;
386 Fault fault = NoFault;
387
388 %(op_decl)s;
389 %(mem_decl)s;
390 %(op_rd)s;
391 %(ea_code)s;
392
393 MemUnion memUnion;
394 if (fault == NoFault) {
395 %(memacc_code)s;
396 }
397
398 if (fault == NoFault) {
399 fault = xc->writeMem(memUnion.bytes, accSize, EA, memAccessFlags,
400 NULL);
401 }
402
403 return fault;
404 }
405 }};
406
407 def template NeonStoreCompleteAcc64 {{
408 Fault %(class_name)s::completeAcc(
409 PacketPtr pkt, CPU_EXEC_CONTEXT *xc,
410 Trace::InstRecord *traceData) const
411 {
412 return NoFault;
413 }
414 }};
415
416 def template VMemMultDeclare64 {{
417 class %(class_name)s : public %(base_class)s
418 {
419 public:
420 // Constructor
421 %(class_name)s(ExtMachInst machInst, RegIndex rn, RegIndex vd,
422 RegIndex rm, uint8_t eSize, uint8_t dataSize,
423 uint8_t numStructElems, uint8_t numRegs, bool wb);
424 %(BasicExecPanic)s
425 };
426 }};
427
428 def template VMemSingleDeclare64 {{
429 class %(class_name)s : public %(base_class)s
430 {
431 public:
432 // Constructor
433 %(class_name)s(ExtMachInst machInst, RegIndex rn, RegIndex vd,
434 RegIndex rm, uint8_t eSize, uint8_t dataSize,
435 uint8_t numStructElems, uint8_t index, bool wb,
436 bool replicate = false);
437 %(BasicExecPanic)s
438 };
439 }};
440
441 def template VMemMultConstructor64 {{
442 %(class_name)s::%(class_name)s(
443 ExtMachInst machInst, RegIndex rn, RegIndex vd, RegIndex rm,
444 uint8_t _eSize, uint8_t _dataSize, uint8_t _numStructElems,
445 uint8_t _numRegs, bool _wb) :
446 %(base_class)s(
447 "%(mnemonic)s", machInst, %(op_class)s, rn, vd, rm,
448 _eSize, _dataSize, _numStructElems, _numRegs, _wb)
449 {
450 %(constructor)s;
451 }
452 }};
453
454 def template VMemSingleConstructor64 {{
455 %(class_name)s::%(class_name)s(
456 ExtMachInst machInst, RegIndex rn, RegIndex vd, RegIndex rm,
457 uint8_t _eSize, uint8_t _dataSize, uint8_t _numStructElems,
458 uint8_t _index, bool _wb, bool _replicate) :
459 %(base_class)s(
460 "%(mnemonic)s", machInst, %(op_class)s, rn, vd, rm,
461 _eSize, _dataSize, _numStructElems, _index, _wb,
462 _replicate)
463 {
464 %(constructor)s;
465 }
466 }};
467
468 def template MicroNeonMixDeclare64 {{
469 class %(class_name)s : public %(base_class)s
470 {
471 public:
472 %(class_name)s(ExtMachInst machInst, RegIndex _dest, RegIndex _op1,
473 uint8_t _eSize, uint8_t _dataSize,
474 uint8_t _numStructElems, uint8_t _numRegs,
475 uint8_t _step) :
476 %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
477 _dest, _op1, _eSize, _dataSize, _numStructElems,
478 _numRegs, _step)
479 {
480 %(constructor)s;
481 }
482
483 %(BasicExecDeclare)s
484 };
485 }};
486
487 def template MicroNeonMixLaneDeclare64 {{
488 class %(class_name)s : public %(base_class)s
489 {
490 public:
491 %(class_name)s(ExtMachInst machInst, RegIndex _dest, RegIndex _op1,
492 uint8_t _eSize, uint8_t _dataSize,
493 uint8_t _numStructElems, uint8_t _lane, uint8_t _step,
494 bool _replicate = false) :
495 %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
496 _dest, _op1, _eSize, _dataSize, _numStructElems,
497 _lane, _step, _replicate)
498 {
499 %(constructor)s;
500 }
501
502 %(BasicExecDeclare)s
503 };
504 }};
505
506 def template MicroNeonMixExecute64 {{
507 Fault %(class_name)s::execute(CPU_EXEC_CONTEXT *xc,
508 Trace::InstRecord *traceData) const
509 {
510 Fault fault = NoFault;
511 uint64_t resTemp = 0;
512 resTemp = resTemp;
513 %(op_decl)s;
514 %(op_rd)s;
515
516 %(code)s;
517 if (fault == NoFault)
518 {
519 %(op_wb)s;
520 }
521
522 return fault;
523 }
524 }};