master
def 842 lines 18.8 KB
Raw
1 /*
2 * Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, see <http://www.gnu.org/licenses/>.
16 */
17
18 DEF_MACRO(fDUMPQ,
19 do {
20 printf(STR ":" #REG ": 0x%016llx\n",REG.ud[0]);
21 } while (0),
22 ()
23 )
24
25 DEF_MACRO(fUSE_LOOKUP_ADDRESS_BY_REV,
26 PROC->arch_proc_options->mmvec_use_full_va_for_lookup,
27 ()
28 )
29
30 DEF_MACRO(fUSE_LOOKUP_ADDRESS,
31 1,
32 ()
33 )
34
35 DEF_MACRO(fNOTQ,
36 ({mmqreg_t _ret = {0}; int _i_; for (_i_ = 0; _i_ < fVECSIZE()/64; _i_++) _ret.ud[_i_] = ~VAL.ud[_i_]; _ret;}),
37 ()
38 )
39
40 DEF_MACRO(fGETQBITS,
41 ((MASK) & (REG.w[(BITNO)>>5] >> ((BITNO) & 0x1f))),
42 ()
43 )
44
45 DEF_MACRO(fGETQBIT,
46 fGETQBITS(REG,1,1,BITNO),
47 ()
48 )
49
50 DEF_MACRO(fGENMASKW,
51 (((fGETQBIT(QREG,(IDX*4+0)) ? 0xFF : 0x0) << 0)
52 |((fGETQBIT(QREG,(IDX*4+1)) ? 0xFF : 0x0) << 8)
53 |((fGETQBIT(QREG,(IDX*4+2)) ? 0xFF : 0x0) << 16)
54 |((fGETQBIT(QREG,(IDX*4+3)) ? 0xFF : 0x0) << 24)),
55 ()
56 )
57 DEF_MACRO(fGET10BIT,
58 {
59 COE = (((((fGETUBYTE(3,VAL) >> (2 * POS)) & 3) << 8) | fGETUBYTE(POS,VAL)) << 6);
60 COE >>= 6;
61 },
62 ()
63 )
64
65 DEF_MACRO(fVMAX,
66 (X>Y) ? X : Y,
67 ()
68 )
69
70
71 DEF_MACRO(fGETNIBBLE,
72 ( fSXTN(4,8,(SRC >> (4*IDX)) & 0xF) ),
73 ()
74 )
75
76 DEF_MACRO(fGETCRUMB,
77 ( fSXTN(2,8,(SRC >> (2*IDX)) & 0x3) ),
78 ()
79 )
80
81 DEF_MACRO(fGETCRUMB_SYMMETRIC,
82 ( (fGETCRUMB(IDX,SRC)>=0 ? (2-fGETCRUMB(IDX,SRC)) : fGETCRUMB(IDX,SRC) ) ),
83 ()
84 )
85
86 #define ZERO_OFFSET_2B +
87
88 DEF_MACRO(fGENMASKH,
89 (((fGETQBIT(QREG,(IDX*2+0)) ? 0xFF : 0x0) << 0)
90 |((fGETQBIT(QREG,(IDX*2+1)) ? 0xFF : 0x0) << 8)),
91 ()
92 )
93
94 DEF_MACRO(fGETMASKW,
95 (VREG.w[IDX] & fGENMASKW((QREG),IDX)),
96 ()
97 )
98
99 DEF_MACRO(fGETMASKH,
100 (VREG.h[IDX] & fGENMASKH((QREG),IDX)),
101 ()
102 )
103
104 DEF_MACRO(fCONDMASK8,
105 (fGETQBIT(QREG,IDX) ? (YESVAL) : (NOVAL)),
106 ()
107 )
108
109 DEF_MACRO(fCONDMASK16,
110 ((fGENMASKH(QREG,IDX) & (YESVAL)) | (fGENMASKH(fNOTQ(QREG),IDX) & (NOVAL))),
111 ()
112 )
113
114 DEF_MACRO(fCONDMASK32,
115 ((fGENMASKW(QREG,IDX) & (YESVAL)) | (fGENMASKW(fNOTQ(QREG),IDX) & (NOVAL))),
116 ()
117 )
118
119
120 DEF_MACRO(fSETQBITS,
121 do {
122 size4u_t __TMP = (VAL);
123 REG.w[(BITNO)>>5] &= ~((MASK) << ((BITNO) & 0x1f));
124 REG.w[(BITNO)>>5] |= (((__TMP) & (MASK)) << ((BITNO) & 0x1f));
125 } while (0),
126 ()
127 )
128
129 DEF_MACRO(fSETQBIT,
130 fSETQBITS(REG,1,1,BITNO,VAL),
131 ()
132 )
133
134 DEF_MACRO(fVBYTES,
135 (fVECSIZE()),
136 ()
137 )
138
139 DEF_MACRO(fVHALVES,
140 (fVECSIZE()/2),
141 ()
142 )
143
144 DEF_MACRO(fVWORDS,
145 (fVECSIZE()/4),
146 ()
147 )
148
149 DEF_MACRO(fVDWORDS,
150 (fVECSIZE()/8),
151 ()
152 )
153
154 DEF_MACRO(fVALIGN,
155 ( ADDR = ADDR & ~(LOG2_ALIGNMENT-1)),
156 ()
157 )
158
159 DEF_MACRO(fVLASTBYTE,
160 ( ADDR = ADDR | (LOG2_ALIGNMENT-1)),
161 ()
162 )
163
164
165 DEF_MACRO(fVELEM,
166 ((fVECSIZE()*8)/WIDTH),
167 ()
168 )
169
170 DEF_MACRO(fVECLOGSIZE,
171 (mmvec_current_veclogsize(thread)),
172 ()
173 )
174
175 DEF_MACRO(fVECSIZE,
176 (1<<fVECLOGSIZE()),
177 ()
178 )
179
180 DEF_MACRO(fSWAPB,
181 {
182 size1u_t tmp = A;
183 A = B;
184 B = tmp;
185 },
186 /* NOTHING */
187 )
188
189 DEF_MACRO(
190 fVZERO,
191 mmvec_zero_vector(),
192 ()
193 )
194
195 DEF_MACRO(
196 fNEWVREG,
197 ((THREAD2STRUCT->VRegs_updated & (((VRegMask)1)<<VNUM)) ? THREAD2STRUCT->future_VRegs[VNUM] : mmvec_zero_vector()),
198 (A_DOTNEWVALUE,A_RESTRICT_SLOT0ONLY)
199 )
200
201 DEF_MACRO(
202 fV_AL_CHECK,
203 if ((EA) & (MASK)) {
204 warn("aligning misaligned vector. PC=%08x EA=%08x",thread->Regs[REG_PC],(EA));
205 },
206 ()
207 )
208 DEF_MACRO(fSCATTER_INIT,
209 {
210 mem_vector_scatter_init(thread, insn, REGION_START, LENGTH, ELEMENT_SIZE);
211 if (EXCEPTION_DETECTED) return;
212 },
213 (A_STORE,A_MEMLIKE,A_RESTRICT_SLOT0ONLY)
214 )
215
216 DEF_MACRO(fGATHER_INIT,
217 {
218 mem_vector_gather_init(thread, insn, REGION_START, LENGTH, ELEMENT_SIZE);
219 if (EXCEPTION_DETECTED) return;
220 },
221 (A_LOAD,A_MEMLIKE,A_RESTRICT_SLOT1ONLY)
222 )
223
224 DEF_MACRO(fSCATTER_FINISH,
225 {
226 if (EXCEPTION_DETECTED) return;
227 mem_vector_scatter_finish(thread, insn, OP);
228 },
229 ()
230 )
231
232 DEF_MACRO(fGATHER_FINISH,
233 {
234 if (EXCEPTION_DETECTED) return;
235 mem_vector_gather_finish(thread, insn);
236 },
237 ()
238 )
239
240
241 DEF_MACRO(CHECK_VTCM_PAGE,
242 {
243 int slot = insn->slot;
244 paddr_t pa = thread->mem_access[slot].paddr+OFFSET;
245 pa = pa & ~(ALIGNMENT-1);
246 FLAG = (pa < (thread->mem_access[slot].paddr+LENGTH));
247 },
248 ()
249 )
250 DEF_MACRO(COUNT_OUT_OF_BOUNDS,
251 {
252 if (!FLAG)
253 {
254 THREAD2STRUCT->vtcm_log.oob_access += SIZE;
255 warn("Scatter/Gather out of bounds of region");
256 }
257 },
258 ()
259 )
260
261 DEF_MACRO(fLOG_SCATTER_OP,
262 {
263 // Log the size and indicate that the extension ext.c file needs to increment right before memory write
264 THREAD2STRUCT->vtcm_log.op = 1;
265 THREAD2STRUCT->vtcm_log.op_size = SIZE;
266 },
267 ()
268 )
269
270
271
272 DEF_MACRO(fVLOG_VTCM_WORD_INCREMENT,
273 {
274 int slot = insn->slot;
275 int log_bank = 0;
276 int log_byte =0;
277 paddr_t pa = thread->mem_access[slot].paddr+(OFFSET & ~(ALIGNMENT-1));
278 paddr_t pa_high = thread->mem_access[slot].paddr+LEN;
279 for(int i0 = 0; i0 < 4; i0++)
280 {
281 log_byte = ((OFFSET>=0)&&((pa+i0)<=pa_high));
282 log_bank |= (log_byte<<i0);
283 LOG_VTCM_BYTE(pa+i0,log_byte,INC.ub[4*IDX+i0],4*IDX+i0);
284 }
285 { LOG_VTCM_BANK(pa, log_bank, IDX); }
286 },
287 ()
288 )
289
290 DEF_MACRO(fVLOG_VTCM_HALFWORD_INCREMENT,
291 {
292 int slot = insn->slot;
293 int log_bank = 0;
294 int log_byte = 0;
295 paddr_t pa = thread->mem_access[slot].paddr+(OFFSET & ~(ALIGNMENT-1));
296 paddr_t pa_high = thread->mem_access[slot].paddr+LEN;
297 for(int i0 = 0; i0 < 2; i0++) {
298 log_byte = ((OFFSET>=0)&&((pa+i0)<=pa_high));
299 log_bank |= (log_byte<<i0);
300 LOG_VTCM_BYTE(pa+i0,log_byte,INC.ub[2*IDX+i0],2*IDX+i0);
301 }
302 { LOG_VTCM_BANK(pa, log_bank,IDX); }
303 },
304 ()
305 )
306
307 DEF_MACRO(fVLOG_VTCM_HALFWORD_INCREMENT_DV,
308 {
309 int slot = insn->slot;
310 int log_bank = 0;
311 int log_byte = 0;
312 paddr_t pa = thread->mem_access[slot].paddr+(OFFSET & ~(ALIGNMENT-1));
313 paddr_t pa_high = thread->mem_access[slot].paddr+LEN;
314 for(int i0 = 0; i0 < 2; i0++) {
315 log_byte = ((OFFSET>=0)&&((pa+i0)<=pa_high));
316 log_bank |= (log_byte<<i0);
317 LOG_VTCM_BYTE(pa+i0,log_byte,INC.ub[2*IDX+i0],2*IDX+i0);
318 }
319 { LOG_VTCM_BANK(pa, log_bank,(2*IDX2+IDX_H));}
320 },
321 ()
322 )
323
324
325
326 DEF_MACRO(GATHER_FUNCTION,
327 {
328 int slot = insn->slot;
329 int i0;
330 paddr_t pa = thread->mem_access[slot].paddr+OFFSET;
331 paddr_t pa_high = thread->mem_access[slot].paddr+LEN;
332 int log_bank = 0;
333 int log_byte = 0;
334 for(i0 = 0; i0 < ELEMENT_SIZE; i0++)
335 {
336 log_byte = ((OFFSET>=0)&&((pa+i0)<=pa_high)) && QVAL;
337 log_bank |= (log_byte<<i0);
338 size1u_t B = sim_mem_read1(thread->system_ptr, thread->threadId, thread->mem_access[slot].paddr+OFFSET+i0);
339 THREAD2STRUCT->tmp_VRegs[0].ub[ELEMENT_SIZE*IDX+i0] = B;
340 LOG_VTCM_BYTE(pa+i0,log_byte,B,ELEMENT_SIZE*IDX+i0);
341 }
342 LOG_VTCM_BANK(pa, log_bank,BANK_IDX);
343 },
344 ()
345 )
346
347
348
349 DEF_MACRO(fVLOG_VTCM_GATHER_WORD,
350 {
351 GATHER_FUNCTION(EA,OFFSET,IDX, LEN, 4, IDX, 1);
352 },
353 ()
354 )
355 DEF_MACRO(fVLOG_VTCM_GATHER_HALFWORD,
356 {
357 GATHER_FUNCTION(EA,OFFSET,IDX, LEN, 2, IDX, 1);
358 },
359 ()
360 )
361 DEF_MACRO(fVLOG_VTCM_GATHER_HALFWORD_DV,
362 {
363 GATHER_FUNCTION(EA,OFFSET,IDX, LEN, 2, (2*IDX2+IDX_H), 1);
364 },
365 ()
366 )
367 DEF_MACRO(fVLOG_VTCM_GATHER_WORDQ,
368 {
369 GATHER_FUNCTION(EA,OFFSET,IDX, LEN, 4, IDX, fGETQBIT(QsV,4*IDX+i0));
370 },
371 ()
372 )
373 DEF_MACRO(fVLOG_VTCM_GATHER_HALFWORDQ,
374 {
375 GATHER_FUNCTION(EA,OFFSET,IDX, LEN, 2, IDX, fGETQBIT(QsV,2*IDX+i0));
376 },
377 ()
378 )
379
380 DEF_MACRO(fVLOG_VTCM_GATHER_HALFWORDQ_DV,
381 {
382 GATHER_FUNCTION(EA,OFFSET,IDX, LEN, 2, (2*IDX2+IDX_H), fGETQBIT(QsV,2*IDX+i0));
383 },
384 ()
385 )
386
387
388 DEF_MACRO(DEBUG_LOG_ADDR,
389 {
390
391 if (thread->processor_ptr->arch_proc_options->mmvec_network_addr_log2)
392 {
393
394 int slot = insn->slot;
395 paddr_t pa = thread->mem_access[slot].paddr+OFFSET;
396 }
397 },
398 ()
399 )
400
401
402
403
404
405
406
407 DEF_MACRO(SCATTER_OP_WRITE_TO_MEM,
408 {
409 for (int i = 0; i < mmvecx->vtcm_log.size; i+=sizeof(TYPE))
410 {
411 if ( mmvecx->vtcm_log.mask.ub[i] != 0) {
412 TYPE dst = 0;
413 TYPE inc = 0;
414 for(int j = 0; j < sizeof(TYPE); j++) {
415 dst |= (sim_mem_read1(thread->system_ptr, thread->threadId, mmvecx->vtcm_log.pa[i+j]) << (8*j));
416 inc |= mmvecx->vtcm_log.data.ub[j+i] << (8*j);
417
418 mmvecx->vtcm_log.mask.ub[j+i] = 0;
419 mmvecx->vtcm_log.data.ub[j+i] = 0;
420 mmvecx->vtcm_log.offsets.ub[j+i] = 0;
421 }
422 dst += inc;
423 for(int j = 0; j < sizeof(TYPE); j++) {
424 sim_mem_write1(thread->system_ptr,thread->threadId, mmvecx->vtcm_log.pa[i+j], (dst >> (8*j))& 0xFF );
425 }
426 }
427
428 }
429 },
430 ()
431 )
432
433 DEF_MACRO(SCATTER_FUNCTION,
434 {
435 int slot = insn->slot;
436 int i0;
437 paddr_t pa = thread->mem_access[slot].paddr+OFFSET;
438 paddr_t pa_high = thread->mem_access[slot].paddr+LEN;
439 int log_bank = 0;
440 int log_byte = 0;
441 for(i0 = 0; i0 < ELEMENT_SIZE; i0++) {
442 log_byte = ((OFFSET>=0)&&((pa+i0)<=pa_high)) && QVAL;
443 log_bank |= (log_byte<<i0);
444 LOG_VTCM_BYTE(pa+i0,log_byte,IN.ub[ELEMENT_SIZE*IDX+i0],ELEMENT_SIZE*IDX+i0);
445 }
446 LOG_VTCM_BANK(pa, log_bank,BANK_IDX);
447
448 },
449 ()
450 )
451
452 DEF_MACRO(fVLOG_VTCM_HALFWORD,
453 {
454 SCATTER_FUNCTION (EA,OFFSET,IDX, LEN, 2, IDX, 1, IN);
455 },
456 ()
457 )
458 DEF_MACRO(fVLOG_VTCM_WORD,
459 {
460 SCATTER_FUNCTION (EA,OFFSET,IDX, LEN, 4, IDX, 1, IN);
461 },
462 ()
463 )
464
465 DEF_MACRO(fVLOG_VTCM_HALFWORDQ,
466 {
467 SCATTER_FUNCTION (EA,OFFSET,IDX, LEN, 2, IDX, fGETQBIT(QsV,2*IDX+i0), IN);
468 },
469 ()
470 )
471 DEF_MACRO(fVLOG_VTCM_WORDQ,
472 {
473 SCATTER_FUNCTION (EA,OFFSET,IDX, LEN, 4, IDX, fGETQBIT(QsV,4*IDX+i0), IN);
474 },
475 ()
476 )
477
478
479
480
481
482 DEF_MACRO(fVLOG_VTCM_HALFWORD_DV,
483 {
484 SCATTER_FUNCTION (EA,OFFSET,IDX, LEN, 2, (2*IDX2+IDX_H), 1, IN);
485 },
486 ()
487 )
488
489 DEF_MACRO(fVLOG_VTCM_HALFWORDQ_DV,
490 {
491 SCATTER_FUNCTION (EA,OFFSET,IDX, LEN, 2, (2*IDX2+IDX_H), fGETQBIT(QsV,2*IDX+i0), IN);
492 },
493 ()
494 )
495
496
497
498
499
500
501 DEF_MACRO(fSTORERELEASE,
502 {
503 fV_AL_CHECK(EA,fVECSIZE()-1);
504
505 mem_store_release(thread, insn, fVECSIZE(), EA&~(fVECSIZE()-1), EA, TYPE, fUSE_LOOKUP_ADDRESS_BY_REV(thread->processor_ptr));
506 },
507 (A_STORE,A_MEMLIKE)
508 )
509
510 DEF_MACRO(fVFETCH_AL,
511 {
512 fV_AL_CHECK(EA,fVECSIZE()-1);
513 mem_fetch_vector(thread, insn, EA&~(fVECSIZE()-1), insn->slot, fVECSIZE());
514 },
515 (A_LOAD,A_MEMLIKE)
516 )
517
518
519 DEF_MACRO(fLOADMMV_AL,
520 {
521 fV_AL_CHECK(EA,ALIGNMENT-1);
522 thread->last_pkt->double_access_vec = 0;
523 mem_load_vector_oddva(thread, insn, EA&~(ALIGNMENT-1), EA, insn->slot, LEN, &DST.ub[0], LEN, fUSE_LOOKUP_ADDRESS_BY_REV(thread->processor_ptr));
524 },
525 (A_LOAD,A_MEMLIKE)
526 )
527
528 DEF_MACRO(fLOADMMV,
529 fLOADMMV_AL(EA,fVECSIZE(),fVECSIZE(),DST),
530 ()
531 )
532
533 DEF_MACRO(fLOADMMVQ,
534 do {
535 int __i;
536 fLOADMMV_AL(EA,fVECSIZE(),fVECSIZE(),DST);
537 fVFOREACH(8,__i) if (!fGETQBIT(QVAL,__i)) DST.b[__i] = 0;
538 } while (0),
539 ()
540 )
541
542 DEF_MACRO(fLOADMMVNQ,
543 do {
544 int __i;
545 fLOADMMV_AL(EA,fVECSIZE(),fVECSIZE(),DST);
546 fVFOREACH(8,__i) if (fGETQBIT(QVAL,__i)) DST.b[__i] = 0;
547 } while (0),
548 ()
549 )
550
551 DEF_MACRO(fLOADMMVU_AL,
552 {
553 size4u_t size2 = (EA)&(ALIGNMENT-1);
554 size4u_t size1 = LEN-size2;
555 thread->last_pkt->double_access_vec = 1;
556 mem_load_vector_oddva(thread, insn, EA+size1, EA+fVECSIZE(), /* slot */ 1, size2, &DST.ub[size1], size2, fUSE_LOOKUP_ADDRESS());
557 mem_load_vector_oddva(thread, insn, EA, EA,/* slot */ 0, size1, &DST.ub[0], size1, fUSE_LOOKUP_ADDRESS_BY_REV(thread->processor_ptr));
558 },
559 (A_LOAD,A_MEMLIKE)
560 )
561
562 DEF_MACRO(fLOADMMVU,
563 {
564 /* if address happens to be aligned, only do aligned load */
565 thread->last_pkt->pkt_has_vtcm_access = 0;
566 thread->last_pkt->pkt_access_count = 0;
567 if ( (EA & (fVECSIZE()-1)) == 0) {
568 thread->last_pkt->pkt_has_vmemu_access = 0;
569 thread->last_pkt->double_access = 0;
570
571 fLOADMMV_AL(EA,fVECSIZE(),fVECSIZE(),DST);
572 } else {
573 thread->last_pkt->pkt_has_vmemu_access = 1;
574 thread->last_pkt->double_access = 1;
575
576 fLOADMMVU_AL(EA,fVECSIZE(),fVECSIZE(),DST);
577 }
578 },
579 ()
580 )
581
582 DEF_MACRO(fSTOREMMV_AL,
583 {
584 fV_AL_CHECK(EA,ALIGNMENT-1);
585 mem_store_vector_oddva(thread, insn, EA&~(ALIGNMENT-1), EA, insn->slot, LEN, &SRC.ub[0], 0, 0, fUSE_LOOKUP_ADDRESS_BY_REV(thread->processor_ptr));
586 },
587 (A_STORE,A_MEMLIKE)
588 )
589
590 DEF_MACRO(fSTOREMMV,
591 fSTOREMMV_AL(EA,fVECSIZE(),fVECSIZE(),SRC),
592 ()
593 )
594
595 DEF_MACRO(fSTOREMMVQ_AL,
596 do {
597 mmvector_t maskvec;
598 int i;
599 for (i = 0; i < fVECSIZE(); i++) maskvec.ub[i] = fGETQBIT(MASK,i);
600 mem_store_vector_oddva(thread, insn, EA&~(ALIGNMENT-1), EA, insn->slot, LEN, &SRC.ub[0], &maskvec.ub[0], 0, fUSE_LOOKUP_ADDRESS_BY_REV(thread->processor_ptr));
601 } while (0),
602 (A_STORE,A_MEMLIKE)
603 )
604
605 DEF_MACRO(fSTOREMMVQ,
606 fSTOREMMVQ_AL(EA,fVECSIZE(),fVECSIZE(),SRC,MASK),
607 ()
608 )
609
610 DEF_MACRO(fSTOREMMVNQ_AL,
611 {
612 mmvector_t maskvec;
613 int i;
614 for (i = 0; i < fVECSIZE(); i++) maskvec.ub[i] = fGETQBIT(MASK,i);
615 fV_AL_CHECK(EA,ALIGNMENT-1);
616 mem_store_vector_oddva(thread, insn, EA&~(ALIGNMENT-1), EA, insn->slot, LEN, &SRC.ub[0], &maskvec.ub[0], 1, fUSE_LOOKUP_ADDRESS_BY_REV(thread->processor_ptr));
617 },
618 (A_STORE,A_MEMLIKE)
619 )
620
621 DEF_MACRO(fSTOREMMVNQ,
622 fSTOREMMVNQ_AL(EA,fVECSIZE(),fVECSIZE(),SRC,MASK),
623 ()
624 )
625
626 DEF_MACRO(fSTOREMMVU_AL,
627 {
628 size4u_t size1 = ALIGNMENT-((EA)&(ALIGNMENT-1));
629 size4u_t size2;
630 if (size1>LEN) size1 = LEN;
631 size2 = LEN-size1;
632 mem_store_vector_oddva(thread, insn, EA+size1, EA+fVECSIZE(), /* slot */ 1, size2, &SRC.ub[size1], 0, 0, fUSE_LOOKUP_ADDRESS());
633 mem_store_vector_oddva(thread, insn, EA, EA, /* slot */ 0, size1, &SRC.ub[0], 0, 0, fUSE_LOOKUP_ADDRESS_BY_REV(thread->processor_ptr));
634 },
635 (A_STORE,A_MEMLIKE)
636 )
637
638 DEF_MACRO(fSTOREMMVU,
639 {
640 thread->last_pkt->pkt_has_vtcm_access = 0;
641 thread->last_pkt->pkt_access_count = 0;
642 if ( (EA & (fVECSIZE()-1)) == 0) {
643 thread->last_pkt->double_access = 0;
644 fSTOREMMV_AL(EA,fVECSIZE(),fVECSIZE(),SRC);
645 } else {
646 thread->last_pkt->double_access = 1;
647 thread->last_pkt->pkt_has_vmemu_access = 1;
648 fSTOREMMVU_AL(EA,fVECSIZE(),fVECSIZE(),SRC);
649 }
650 },
651 ()
652 )
653
654 DEF_MACRO(fSTOREMMVQU_AL,
655 {
656 size4u_t size1 = ALIGNMENT-((EA)&(ALIGNMENT-1));
657 size4u_t size2;
658 mmvector_t maskvec;
659 int i;
660 for (i = 0; i < fVECSIZE(); i++) maskvec.ub[i] = fGETQBIT(MASK,i);
661 if (size1>LEN) size1 = LEN;
662 size2 = LEN-size1;
663 mem_store_vector_oddva(thread, insn, EA+size1, EA+fVECSIZE(),/* slot */ 1, size2, &SRC.ub[size1], &maskvec.ub[size1], 0, fUSE_LOOKUP_ADDRESS());
664 mem_store_vector_oddva(thread, insn, EA, /* slot */ 0, size1, &SRC.ub[0], &maskvec.ub[0], 0, fUSE_LOOKUP_ADDRESS_BY_REV(thread->processor_ptr));
665 },
666 (A_STORE,A_MEMLIKE)
667 )
668
669 DEF_MACRO(fSTOREMMVQU,
670 {
671 thread->last_pkt->pkt_has_vtcm_access = 0;
672 thread->last_pkt->pkt_access_count = 0;
673 if ( (EA & (fVECSIZE()-1)) == 0) {
674 thread->last_pkt->double_access = 0;
675 fSTOREMMVQ_AL(EA,fVECSIZE(),fVECSIZE(),SRC,MASK);
676 } else {
677 thread->last_pkt->double_access = 1;
678 thread->last_pkt->pkt_has_vmemu_access = 1;
679 fSTOREMMVQU_AL(EA,fVECSIZE(),fVECSIZE(),SRC,MASK);
680 }
681 },
682 ()
683 )
684
685 DEF_MACRO(fSTOREMMVNQU_AL,
686 {
687 size4u_t size1 = ALIGNMENT-((EA)&(ALIGNMENT-1));
688 size4u_t size2;
689 mmvector_t maskvec;
690 int i;
691 for (i = 0; i < fVECSIZE(); i++) maskvec.ub[i] = fGETQBIT(MASK,i);
692 if (size1>LEN) size1 = LEN;
693 size2 = LEN-size1;
694 mem_store_vector_oddva(thread, insn, EA+size1, EA+fVECSIZE(), /* slot */ 1, size2, &SRC.ub[size1], &maskvec.ub[size1], 1, fUSE_LOOKUP_ADDRESS());
695 mem_store_vector_oddva(thread, insn, EA, EA, /* slot */ 0, size1, &SRC.ub[0], &maskvec.ub[0], 1, fUSE_LOOKUP_ADDRESS_BY_REV(thread->processor_ptr));
696 },
697 (A_STORE,A_MEMLIKE)
698 )
699
700 DEF_MACRO(fSTOREMMVNQU,
701 {
702 thread->last_pkt->pkt_has_vtcm_access = 0;
703 thread->last_pkt->pkt_access_count = 0;
704 if ( (EA & (fVECSIZE()-1)) == 0) {
705 thread->last_pkt->double_access = 0;
706 fSTOREMMVNQ_AL(EA,fVECSIZE(),fVECSIZE(),SRC,MASK);
707 } else {
708 thread->last_pkt->double_access = 1;
709 thread->last_pkt->pkt_has_vmemu_access = 1;
710 fSTOREMMVNQU_AL(EA,fVECSIZE(),fVECSIZE(),SRC,MASK);
711 }
712 },
713 ()
714 )
715
716
717
718
719 DEF_MACRO(fVFOREACH,
720 for (VAR = 0; VAR < fVELEM(WIDTH); VAR++),
721 /* NOTHING */
722 )
723
724 DEF_MACRO(fVARRAY_ELEMENT_ACCESS,
725 ARRAY.v[(INDEX) / (fVECSIZE()/(sizeof(ARRAY.TYPE[0])))].TYPE[(INDEX) % (fVECSIZE()/(sizeof(ARRAY.TYPE[0])))],
726 ()
727 )
728
729 DEF_MACRO(fVNEWCANCEL,
730 do { THREAD2STRUCT->VRegs_select &= ~(1<<(REGNUM)); } while (0),
731 ()
732 )
733
734 DEF_MACRO(fTMPVDATA,
735 mmvec_vtmp_data(thread),
736 (A_CVI)
737 )
738
739 DEF_MACRO(fVSATDW,
740 fVSATW( ( ( ((long long)U)<<32 ) | fZXTN(32,64,V) ) ),
741 /* attribs */
742 )
743
744 DEF_MACRO(fVASL_SATHI,
745 fVSATW(((U)<<1) | ((V)>>31)),
746 /* attribs */
747 )
748
749 DEF_MACRO(fVUADDSAT,
750 fVSATUN( WIDTH, fZXTN(WIDTH, 2*WIDTH, U) + fZXTN(WIDTH, 2*WIDTH, V)),
751 /* attribs */
752 )
753
754 DEF_MACRO(fVSADDSAT,
755 fVSATN( WIDTH, fSXTN(WIDTH, 2*WIDTH, U) + fSXTN(WIDTH, 2*WIDTH, V)),
756 /* attribs */
757 )
758
759 DEF_MACRO(fVUSUBSAT,
760 fVSATUN( WIDTH, fZXTN(WIDTH, 2*WIDTH, U) - fZXTN(WIDTH, 2*WIDTH, V)),
761 /* attribs */
762 )
763
764 DEF_MACRO(fVSSUBSAT,
765 fVSATN( WIDTH, fSXTN(WIDTH, 2*WIDTH, U) - fSXTN(WIDTH, 2*WIDTH, V)),
766 /* attribs */
767 )
768
769 DEF_MACRO(fVAVGU,
770 ((fZXTN(WIDTH, 2*WIDTH, U) + fZXTN(WIDTH, 2*WIDTH, V))>>1),
771 /* attribs */
772 )
773
774 DEF_MACRO(fVAVGURND,
775 ((fZXTN(WIDTH, 2*WIDTH, U) + fZXTN(WIDTH, 2*WIDTH, V)+1)>>1),
776 /* attribs */
777 )
778
779 DEF_MACRO(fVNAVGU,
780 ((fZXTN(WIDTH, 2*WIDTH, U) - fZXTN(WIDTH, 2*WIDTH, V))>>1),
781 /* attribs */
782 )
783
784 DEF_MACRO(fVNAVGURNDSAT,
785 fVSATUN(WIDTH,((fZXTN(WIDTH, 2*WIDTH, U) - fZXTN(WIDTH, 2*WIDTH, V)+1)>>1)),
786 /* attribs */
787 )
788
789 DEF_MACRO(fVAVGS,
790 ((fSXTN(WIDTH, 2*WIDTH, U) + fSXTN(WIDTH, 2*WIDTH, V))>>1),
791 /* attribs */
792 )
793
794 DEF_MACRO(fVAVGSRND,
795 ((fSXTN(WIDTH, 2*WIDTH, U) + fSXTN(WIDTH, 2*WIDTH, V)+1)>>1),
796 /* attribs */
797 )
798
799 DEF_MACRO(fVNAVGS,
800 ((fSXTN(WIDTH, 2*WIDTH, U) - fSXTN(WIDTH, 2*WIDTH, V))>>1),
801 /* attribs */
802 )
803
804 DEF_MACRO(fVNAVGSRND,
805 ((fSXTN(WIDTH, 2*WIDTH, U) - fSXTN(WIDTH, 2*WIDTH, V)+1)>>1),
806 /* attribs */
807 )
808
809 DEF_MACRO(fVNAVGSRNDSAT,
810 fVSATN(WIDTH,((fSXTN(WIDTH, 2*WIDTH, U) - fSXTN(WIDTH, 2*WIDTH, V)+1)>>1)),
811 /* attribs */
812 )
813
814
815 DEF_MACRO(fVNOROUND,
816 VAL,
817 /* NOTHING */
818 )
819 DEF_MACRO(fVNOSAT,
820 VAL,
821 /* NOTHING */
822 )
823
824 DEF_MACRO(fVROUND,
825 ((VAL) + (((SHAMT)>0)?(1LL<<((SHAMT)-1)):0)),
826 /* NOTHING */
827 )
828
829 DEF_MACRO(fCARRY_FROM_ADD32,
830 (((fZXTN(32,64,A)+fZXTN(32,64,B)+C) >> 32) & 1),
831 /* NOTHING */
832 )
833
834 DEF_MACRO(fUARCH_NOTE_PUMP_4X,
835 ,
836 ()
837 )
838
839 DEF_MACRO(fUARCH_NOTE_PUMP_2X,
840 ,
841 ()
842 )