1 /* VECTOR.C (c) Copyright Jan Jaeger, 1999-2009 */
2 /* S/370 and ESA/390 Vector Operations */
3
4 /*-------------------------------------------------------------------*/
5 /* This module implements the Vector Facility instruction execution */
6 /* function of the S/370 and ESA/390 architectures, as described in */
7 /* SA22-7125-03 Vector Operations (S/370 & ESA/370) */
8 /* SA22-7207-00 Vector Operations (ESA/390) */
9 /* 28/05/2000 Jan Jaeger */
10 /* */
11 /* Instruction decoding rework 09/07/2000 Jan Jaeger */
12 /* Interpretive Execution - (c) Copyright Jan Jaeger, 1999-2009 */
13 /* z/Architecture support - (c) Copyright Jan Jaeger, 1999-2009 */
14 /*-------------------------------------------------------------------*/
15
16 #include "hstdinc.h"
17
18 #include "hercules.h"
19
20 #include "opcode.h"
21
22 #include "inline.h"
23
24 #if defined(FEATURE_VECTOR_FACILITY)
25
26 /* The vector save area must be aligned on a boundary 8 times the
27 section size, however VM stores at 4 times the section size.
28 I do not know if the book or VM is wrong. *JJ */
29 #define VSA_ALIGN 4
30
31 /*-------------------------------------------------------------------*/
32 /* A640 VTVM - Test VMR [RRE] */
33 /*-------------------------------------------------------------------*/
DEF_INST(v_test_vmr)34 DEF_INST(v_test_vmr)
35 {
36 int unused1, unused2;
37 U32 n, n1;
38
39 RRE(inst, regs, unused1, unused2);
40
41 VOP_CHECK(regs);
42
43 /* Extract vector count (number of active bits in vmr) */
44 n = VECTOR_COUNT(regs);
45
46 /* cc0 when the vector count is zero */
47 if( n == 0)
48 {
49 regs->psw.cc = 0;
50 return;
51 }
52
53 /* Preset condition code according to first bit */
54 regs->psw.cc = VMR_SET(0, regs) ? 3 : 0;
55
56 /* Check VMR bit to be equal to the first,
57 exit with cc1 if an unequal bit found */
58 for(n1 = 1; n1 < n; n1++)
59 if((regs->psw.cc == 0) != (VMR_SET(n1, regs) == 0))
60 {
61 regs->psw.cc = 1;
62 return;
63 }
64
65 }
66
67
68 /*-------------------------------------------------------------------*/
69 /* A641 VCVM - Complement VMR [RRE] */
70 /*-------------------------------------------------------------------*/
DEF_INST(v_complement_vmr)71 DEF_INST(v_complement_vmr)
72 {
73 int unused1, unused2;
74 U32 n, n1, n2;
75
76 RRE(inst, regs, unused1, unused2);
77
78 VOP_CHECK(regs);
79
80 /* Extract vector count (number of active bits in vmr) */
81 n = VECTOR_COUNT(regs);
82
83 /* Bytes - 1 */
84 n1 = n >> 3;
85
86 /* Complement VMR */
87 for(n2 = 0; n2 <= n1; n2++)
88 regs->vf->vmr[n2] ^= 0xFF;
89
90 /* zeroize remainder */
91 regs->vf->vmr[n1] &= 0x7F00 >> (n & 7);
92 for(n1++; n1 < sizeof(regs->vf->vmr); n1++)
93 regs->vf->vmr[n1] = 0;
94
95 }
96
97
98 /*-------------------------------------------------------------------*/
99 /* A642 VCZVM - Count Left Zeros in VMR [RRE] */
100 /*-------------------------------------------------------------------*/
DEF_INST(v_count_left_zeros_in_vmr)101 DEF_INST(v_count_left_zeros_in_vmr)
102 {
103 int gr1, unused2;
104 U32 n, n1;
105
106 RRE(inst, regs, gr1, unused2);
107
108 VOP_CHECK(regs);
109
110 /* Extract vector count (number of active bits in vmr) */
111 n = VECTOR_COUNT(regs);
112
113 /* cc0 when the vector count is zero */
114 if( n == 0)
115 {
116 regs->psw.cc = 0;
117 return;
118 }
119
120 /* Preset condition code according to first bit */
121 regs->psw.cc = VMR_SET(0, regs) ? 3 : 0;
122
123 /* If the VCT is 1 and the first bit is one
124 then exit wirh gr1 set to zero */
125 regs->GR_L(gr1) = 0;
126 if(n == 1 && VMR_SET(0, regs))
127 return;
128
129 /* Count left zeros, set cc1 and exit if a one is found */
130 regs->GR_L(gr1) = 1;
131 for(n1 = 1; n1 < n; n1++)
132 {
133 if(!VMR_SET(n1, regs))
134 regs->GR_L(gr1)++;
135 else
136 {
137 regs->psw.cc = 1;
138 return;
139 }
140 }
141
142 }
143
144
145 /*-------------------------------------------------------------------*/
146 /* A643 VCOVM - Count Ones In VMR [RRE] */
147 /*-------------------------------------------------------------------*/
DEF_INST(v_count_ones_in_vmr)148 DEF_INST(v_count_ones_in_vmr)
149 {
150 int gr1, unused2;
151 U32 n, n1;
152
153 RRE(inst, regs, gr1, unused2);
154
155 VOP_CHECK(regs);
156
157 /* Extract vector count (number of active bits in vmr) */
158 n = VECTOR_COUNT(regs);
159
160 /* cc0 when the vector count is zero */
161 if( n == 0)
162 {
163 regs->psw.cc = 0;
164 return;
165 }
166
167 /* Preset condition code according to first bit */
168 regs->psw.cc = VMR_SET(0, regs) ? 3 : 0;
169
170 /* Check VMR bit to be equal to the first,
171 Count all ones, set cc1 if a bit is unequal */
172 regs->GR_L(gr1) = 0;
173 for(n1 = 0; n1 < n; n1++)
174 {
175 if(VMR_SET(n1, regs))
176 {
177 regs->GR_L(gr1)++;
178 if(!VMR_SET(0, regs))
179 regs->psw.cc = 1;
180 }
181 else
182 if(VMR_SET(0, regs))
183 regs->psw.cc = 1;
184 }
185
186 }
187
188
189 /*-------------------------------------------------------------------*/
190 /* A644 VXVC - Exctract VCT [RRE] */
191 /*-------------------------------------------------------------------*/
DEF_INST(v_extract_vct)192 DEF_INST(v_extract_vct)
193 {
194 int gr1, unused2;
195
196 RRE(inst, regs, gr1, unused2);
197
198 VOP_CHECK(regs);
199
200 regs->GR_L(gr1) = VECTOR_COUNT(regs);
201
202 }
203
204
205 /*-------------------------------------------------------------------*/
206 /* A646 VXVMM - Extract Vector Modes [RRE] */
207 /*-------------------------------------------------------------------*/
DEF_INST(v_extract_vector_modes)208 DEF_INST(v_extract_vector_modes)
209 {
210 int gr1, unused2;
211
212 RRE(inst, regs, gr1, unused2);
213
214 VOP_CHECK(regs);
215
216 regs->GR_L(gr1) = (regs->vf->vsr >> 48);
217
218 }
219
220
221 /*-------------------------------------------------------------------*/
222 /* A648 VRRS - Restore VR [RRE] */
223 /*-------------------------------------------------------------------*/
DEF_INST(v_restore_vr)224 DEF_INST(v_restore_vr)
225 {
226 int gr1, unused2;
227 U32 n, n1, n2;
228 U64 d;
229
230 RRE(inst, regs, gr1, unused2);
231
232 VOP_CHECK(regs);
233
234 ODD_CHECK(gr1, regs);
235
236 /* n contrains the current save area address */
237 n = regs->GR_L(gr1) & ADDRESS_MAXWRAP(regs);
238
239 /* n1 contains the starting element number */
240 if((n1 = regs->GR_L(gr1 + 1) >> 16) >= VECTOR_SECTION_SIZE)
241 ARCH_DEP(program_interrupt)(regs, PGM_SPECIFICATION_EXCEPTION);
242
243 /* Starting address must be eight times the section size aligned */
244 if((n - (8 * n1)) & ((VECTOR_SECTION_SIZE * VSA_ALIGN) - 1) )
245 ARCH_DEP(program_interrupt)(regs, PGM_SPECIFICATION_EXCEPTION);
246
247 /* n2 contains VR pair, which must be an even reg */
248 if((n2 = regs->GR_L(gr1 + 1) & 0x0000FFFF) & 0x0000FFF1)
249 ARCH_DEP(program_interrupt)(regs, PGM_SPECIFICATION_EXCEPTION);
250
251 if( VR_INUSE(n2, regs) )
252 {
253 /* Set the vector changed bit if in problem state */
254 if( PROBSTATE(®s->psw) )
255 SET_VR_CHANGED(n2, regs);
256
257 for(; n1 < VECTOR_SECTION_SIZE; n1++)
258 {
259 /* Fetch vr pair from central storage */
260 d = ARCH_DEP(vfetch8)(n, gr1, regs);
261 regs->vf->vr[n2][n1] = d >> 32;
262 regs->vf->vr[n2+1][n1] = d;
263
264 /* Increment element number */
265 n1++;
266 regs->GR_L(gr1 + 1) &= 0x0000FFFF;
267 regs->GR_L(gr1 + 1) |= n1 << 16;
268 /* Update savearea address */
269 regs->GR_L(gr1) += 8;
270 #if 0
271 /* This is where the instruction may be interrupted */
272 UPD_PSW_IA(regs, PSW_IA(regs, -4));
273 return;
274 #endif
275 }
276
277 /* Indicate vr pair restored */
278 regs->psw.cc = 2;
279 }
280 else
281 {
282 regs->GR_L(gr1) += 8 * (VECTOR_SECTION_SIZE - n1);
283 /* indicate v2 pair not restored */
284 regs->psw.cc = 0;
285 }
286
287 /* Set 2 if vr 14 is restored, 0 if not restored,
288 3 and 1 for other VR's respectively */
289 if(n2 != 14) regs->psw.cc++;
290
291 /* Update the vector pair number, and zero element number */
292 n2 += 2;
293 regs->GR_L(gr1 + 1) = n2;
294
295 }
296
297
298 /*-------------------------------------------------------------------*/
299 /* A649 VRSVC - Save Changed VR [RRE] */
300 /*-------------------------------------------------------------------*/
DEF_INST(v_save_changed_vr)301 DEF_INST(v_save_changed_vr)
302 {
303 int gr1, unused2;
304 U32 n, n1, n2;
305 U64 d;
306
307 RRE(inst, regs, gr1, unused2);
308
309 VOP_CHECK(regs);
310
311 PRIV_CHECK(regs);
312
313 ODD_CHECK(gr1, regs);
314
315 /* n contrains the current save area address */
316 n = regs->GR_L(gr1) & ADDRESS_MAXWRAP(regs);
317
318 /* n1 contains the starting element number */
319 if((n1 = regs->GR_L(gr1 + 1) >> 16) >= VECTOR_SECTION_SIZE)
320 ARCH_DEP(program_interrupt)(regs, PGM_SPECIFICATION_EXCEPTION);
321
322 /* Starting address must be eight times the section size aligned */
323 if((n - (8 * n1)) & ((VECTOR_SECTION_SIZE * VSA_ALIGN) - 1) )
324 ARCH_DEP(program_interrupt)(regs, PGM_SPECIFICATION_EXCEPTION);
325
326 /* n2 contains VR pair, which must be an even reg */
327 if((n2 = regs->GR_L(gr1 + 1) & 0x0000FFFF) & 0x0000FFF1)
328 ARCH_DEP(program_interrupt)(regs, PGM_SPECIFICATION_EXCEPTION);
329
330 if( VR_CHANGED(n2, regs) )
331 {
332 for(; n1 < VECTOR_SECTION_SIZE; n1++)
333 {
334 /* Store vr pair in savearea */
335 d = ((U64)regs->vf->vr[n2][n1] << 32)
336 | regs->vf->vr[n2+1][n1];
337 ARCH_DEP(vstore8)(d, n, gr1, regs);
338
339 /* Update element number */
340 n1++;
341 regs->GR_L(gr1 + 1) &= 0x0000FFFF;
342 regs->GR_L(gr1 + 1) |= n1 << 16;
343 regs->GR_L(gr1) += 8;
344 #if 0
345 /* This is where the instruction may be interrupted */
346 UPD_PSW_IA(regs, PSW_IA(regs, -4));
347 return;
348 #endif
349 }
350
351 /* Indicate vr pair saved */
352 regs->psw.cc = 2;
353
354 /* Reset the VR changed bit */
355 RESET_VR_CHANGED(n2, regs);
356 }
357 else
358 {
359 regs->GR_L(gr1) += 8 * (VECTOR_SECTION_SIZE - n1);
360 /* vr pair not saved */
361 regs->psw.cc = 0;
362 }
363
364 /* Set 2 if vr 14 is restored, 0 if not restored,
365 3 and 1 for other VR's respectively */
366 if(n2 != 14) regs->psw.cc++;
367
368 /* Update the vector pair number, and zero element number */
369 n2 += 2;
370 regs->GR_L(gr1 + 1) = n2;
371
372 }
373
374
375 /*-------------------------------------------------------------------*/
376 /* A64A VRSV - Save VR [RRE] */
377 /*-------------------------------------------------------------------*/
DEF_INST(v_save_vr)378 DEF_INST(v_save_vr)
379 {
380 int gr1, unused2;
381 U32 n, n1, n2;
382 U64 d;
383
384 RRE(inst, regs, gr1, unused2);
385
386 VOP_CHECK(regs);
387
388 ODD_CHECK(gr1, regs);
389
390 /* n contrains the current save area address */
391 n = regs->GR_L(gr1) & ADDRESS_MAXWRAP(regs);
392
393 /* n1 contains the starting element number */
394 if((n1 = regs->GR_L(gr1 + 1) >> 16) >= VECTOR_SECTION_SIZE)
395 ARCH_DEP(program_interrupt)(regs, PGM_SPECIFICATION_EXCEPTION);
396
397 /* Starting address must be eight times the section size aligned */
398 if((n - (8 * n1)) & ((VECTOR_SECTION_SIZE * VSA_ALIGN) - 1) )
399 ARCH_DEP(program_interrupt)(regs, PGM_SPECIFICATION_EXCEPTION);
400
401 /* n2 contains VR pair, which must be an even reg */
402 if((n2 = regs->GR_L(gr1 + 1) & 0x0000FFFF) & 0x0000FFF1)
403 ARCH_DEP(program_interrupt)(regs, PGM_SPECIFICATION_EXCEPTION);
404
405 if( VR_INUSE(n2, regs) )
406 {
407 for(; n1 < VECTOR_SECTION_SIZE; n1++)
408 {
409 /* Store vr pair in savearea */
410 d = ((U64)regs->vf->vr[n2][n1] << 32)
411 | regs->vf->vr[n2+1][n1];
412 ARCH_DEP(vstore8)(d, n, gr1, regs);
413
414 /* Update element number */
415 n1++;
416 regs->GR_L(gr1 + 1) &= 0x0000FFFF;
417 regs->GR_L(gr1 + 1) |= n1 << 16;
418 regs->GR_L(gr1) += 8;
419 #if 0
420 /* This is where the instruction may be interrupted */
421 UPD_PSW_IA(regs, PSW_IA(regs, -4));
422 return;
423 #endif
424 }
425
426 /* Indicate vr pair restored */
427 regs->psw.cc = 2;
428 }
429 else
430 {
431 regs->GR_L(gr1) += 8 * (VECTOR_SECTION_SIZE - n1);
432 /* Indicate vr pair not restored */
433 regs->psw.cc = 0;
434 }
435
436 /* Set 2 if vr 14 is restored, 0 if not restored,
437 3 and 1 for other VR's respectively */
438 if(n2 != 14) regs->psw.cc++;
439
440 /* Update the vector pair number, and zero element number */
441 n2 += 2;
442 regs->GR_L(gr1 + 1) = n2;
443
444 }
445
446
447 /*-------------------------------------------------------------------*/
448 /* A680 VLVM - Load VMR [VS] */
449 /*-------------------------------------------------------------------*/
DEF_INST(v_load_vmr)450 DEF_INST(v_load_vmr)
451 {
452 int rs2;
453 U32 n, n1;
454
455 VS(inst, regs, rs2);
456
457 VOP_CHECK(regs);
458
459 /* Extract vector count (number of active bits in vmr) */
460 n = VECTOR_COUNT(regs);
461 n1 = n >> 3;
462
463 ARCH_DEP(vfetchc)(regs->vf->vmr, n1,
464 regs->GR_L(rs2) & ADDRESS_MAXWRAP(regs), rs2, regs);
465
466 /* Set the inactive bits to zero */
467 regs->vf->vmr[n1] &= 0x7F00 >> (n & 7);
468 for(n1++; n1 < sizeof(regs->vf->vmr); n1++)
469 regs->vf->vmr[n1] = 0;
470
471 }
472
473
474 /*-------------------------------------------------------------------*/
475 /* A681 VLCVM - Load VMR Complement [VS] */
476 /*-------------------------------------------------------------------*/
DEF_INST(v_load_vmr_complement)477 DEF_INST(v_load_vmr_complement)
478 {
479 int rs2;
480 U32 n, n1, n2;
481
482 VS(inst, regs, rs2);
483
484 VOP_CHECK(regs);
485
486 /* Extract vector count (number of active bits in vmr) */
487 n = VECTOR_COUNT(regs);
488
489 /* Number of bytes - 1 */
490 n1 = n >> 3;
491
492 ARCH_DEP(vfetchc)(regs->vf->vmr, n1,
493 regs->GR_L(rs2) & ADDRESS_MAXWRAP(regs), rs2, regs);
494
495 /* Complement all bits loaded */
496 for(n2 = 0; n2 <= n1; n2++)
497 regs->vf->vmr[n2] ^= 0xFF;
498
499 /* Set the inactive bits to zero */
500 regs->vf->vmr[n1] &= 0x7F00 >> (n & 7);
501 for(n1++; n1 < sizeof(regs->vf->vmr); n1++)
502 regs->vf->vmr[n1] = 0;
503
504 }
505
506
507 /*-------------------------------------------------------------------*/
508 /* A682 VSTVM - Store VMR [VS] */
509 /*-------------------------------------------------------------------*/
DEF_INST(v_store_vmr)510 DEF_INST(v_store_vmr)
511 {
512 int rs2;
513 U32 n;
514
515 VS(inst, regs, rs2);
516
517 VOP_CHECK(regs);
518
519 /* Extract vector count (number of active bits in vmr) */
520 n = VECTOR_COUNT(regs);
521
522 ARCH_DEP(vstorec)(regs->vf->vmr, n >> 3,
523 regs->GR_L(rs2) & ADDRESS_MAXWRAP(regs), rs2, regs);
524
525 }
526
527
528 /*-------------------------------------------------------------------*/
529 /* A684 VNVM - AND To VMR [VS] */
530 /*-------------------------------------------------------------------*/
DEF_INST(v_and_to_vmr)531 DEF_INST(v_and_to_vmr)
532 {
533 int rs2;
534 U32 n, n1, n2;
535 BYTE workvmr[VECTOR_SECTION_SIZE/8];
536
537 VS(inst, regs, rs2);
538
539 VOP_CHECK(regs);
540
541 /* Extract vector count (number of active bits in vmr) */
542 n = VECTOR_COUNT(regs);
543
544 /* Number of bytes - 1 */
545 n1 = n >> 3;
546
547 ARCH_DEP(vfetchc)(workvmr, n1,
548 regs->GR_L(rs2) & ADDRESS_MAXWRAP(regs), rs2, regs);
549
550 /* And VMR with workvmr */
551 for(n2 = 0; n2 <= n1; n2++)
552 regs->vf->vmr[n2] &= workvmr[n2];
553
554 /* zeroize remainder */
555 regs->vf->vmr[n1] &= 0x7F00 >> (n & 7);
556 for(n1++; n1 < sizeof(regs->vf->vmr); n1++)
557 regs->vf->vmr[n1] = 0;
558
559 }
560
561
562 /*-------------------------------------------------------------------*/
563 /* A685 VOVM - OR To VMR [VS] */
564 /*-------------------------------------------------------------------*/
DEF_INST(v_or_to_vmr)565 DEF_INST(v_or_to_vmr)
566 {
567 int rs2;
568 U32 n, n1, n2;
569 BYTE workvmr[VECTOR_SECTION_SIZE/8];
570
571 VS(inst, regs, rs2);
572
573 VOP_CHECK(regs);
574
575 /* Extract vector count (number of active bits in vmr) */
576 n = VECTOR_COUNT(regs);
577
578 /* Number of bytes - 1 */
579 n1 = n >> 3;
580
581 ARCH_DEP(vfetchc)(workvmr, n1,
582 regs->GR_L(rs2) & ADDRESS_MAXWRAP(regs), rs2, regs);
583
584 /* OR VMR with workvmr */
585 for(n2 = 0; n2 <= n1; n2++)
586 regs->vf->vmr[n2] |= workvmr[n2];
587
588 /* zeroize remainder */
589 regs->vf->vmr[n1] &= 0x7F00 >> (n & 7);
590 for(n1++; n1 < sizeof(regs->vf->vmr); n1++)
591 regs->vf->vmr[n1] = 0;
592
593 }
594
595
596 /*-------------------------------------------------------------------*/
597 /* A686 VXVM - Exclusive OR To VMR [VS] */
598 /*-------------------------------------------------------------------*/
DEF_INST(v_exclusive_or_to_vmr)599 DEF_INST(v_exclusive_or_to_vmr)
600 {
601 int rs2;
602 U32 n, n1, n2;
603 BYTE workvmr[VECTOR_SECTION_SIZE/8];
604
605 VS(inst, regs, rs2);
606
607 VOP_CHECK(regs);
608
609 /* Extract vector count (number of active bits in vmr) */
610 n = VECTOR_COUNT(regs);
611
612 /* Number of bytes - 1 */
613 n1 = n >> 3;
614
615 ARCH_DEP(vfetchc)(workvmr, n1,
616 regs->GR_L(rs2) & ADDRESS_MAXWRAP(regs), rs2, regs);
617
618 /* OR VMR with workvmr */
619 for(n2 = 0; n2 <= n1; n2++)
620 regs->vf->vmr[n2] ^= workvmr[n2];
621
622 /* zeroize remainder */
623 regs->vf->vmr[n1] &= 0x7F00 >> (n & 7);
624 for(n1++; n1 < sizeof(regs->vf->vmr); n1++)
625 regs->vf->vmr[n1] = 0;
626
627 }
628
629
630 /*-------------------------------------------------------------------*/
631 /* A6C0 VSRSV - Save VSR [S] */
632 /*-------------------------------------------------------------------*/
DEF_INST(v_save_vsr)633 DEF_INST(v_save_vsr)
634 {
635 int b2; /* Base of effective addr */
636 VADR effective_addr2; /* Effective address */
637
638 S(inst, regs, b2, effective_addr2);
639
640 VOP_CHECK(regs);
641
642 DW_CHECK(effective_addr2, regs);
643
644 ARCH_DEP(vstore8)(regs->vf->vsr, effective_addr2, b2, regs);
645
646 }
647
648
649 /*-------------------------------------------------------------------*/
650 /* A6C1 VMRSV - Save VMR [S] */
651 /*-------------------------------------------------------------------*/
DEF_INST(v_save_vmr)652 DEF_INST(v_save_vmr)
653 {
654 int b2; /* Base of effective addr */
655 VADR effective_addr2; /* Effective address */
656
657 S(inst, regs, b2, effective_addr2);
658
659 VOP_CHECK(regs);
660
661 ARCH_DEP(vstorec)(regs->vf->vmr, sizeof(regs->vf->vmr) - 1,
662 effective_addr2, b2, regs);
663
664 }
665
666
667 /*-------------------------------------------------------------------*/
668 /* A6C2 VSRRS - Restore VSR [S] */
669 /*-------------------------------------------------------------------*/
DEF_INST(v_restore_vsr)670 DEF_INST(v_restore_vsr)
671 {
672 int b2; /* Base of effective addr */
673 VADR effective_addr2; /* Effective address */
674 U32 n1, n2;
675 U64 d;
676
677 S(inst, regs, b2, effective_addr2);
678
679 VOP_CHECK(regs);
680
681 DW_CHECK(effective_addr2, regs);
682
683 /* Fetch operand */
684 d = ARCH_DEP(vfetch8)(effective_addr2, b2, regs);
685
686 /* Check for reserved bits nonzero,
687 vector count not greater then section size and
688 vector interruption index not greater then section size */
689 if((d & VSR_RESV)
690 || ((d & VSR_VCT) >> 32) > VECTOR_SECTION_SIZE
691 || ((d & VSR_VIX) >> 16) >= VECTOR_SECTION_SIZE)
692 ARCH_DEP(program_interrupt)(regs, PGM_SPECIFICATION_EXCEPTION);
693
694 /* In problem state the change bit are set corresponding
695 the inuse bits */
696 if(PROBSTATE(®s->psw))
697 {
698 d &= ~VSR_VCH;
699 d |= (d & VSR_VIU) >> 8;
700 }
701
702 /* Clear any VRs whose inuse bits are being set to zero */
703 for(n1 = 0; n1 < 16; n1 += 2)
704 {
705 if( VR_INUSE(n1, regs)
706 && !((d & VSR_VIU) & (VSR_VCH0 >> (n1 >> 1))) )
707 for(n2 = 0; n2 < VECTOR_SECTION_SIZE; n2++)
708 {
709 regs->vf->vr[n1][n2] = 0;
710 regs->vf->vr[n1+1][n2] = 0;
711 }
712 }
713
714 /* Update the vector status register */
715 regs->vf->vsr = d;
716
717 }
718
719
720 /*-------------------------------------------------------------------*/
721 /* A6C3 VMRRS - Restore VMR [S] */
722 /*-------------------------------------------------------------------*/
DEF_INST(v_restore_vmr)723 DEF_INST(v_restore_vmr)
724 {
725 int b2; /* Base of effective addr */
726 VADR effective_addr2; /* Effective address */
727
728 S(inst, regs, b2, effective_addr2);
729
730 VOP_CHECK(regs);
731
732 ARCH_DEP(vfetchc)(regs->vf->vmr, sizeof(regs->vf->vmr) - 1,
733 effective_addr2, b2, regs);
734
735 }
736
737
738 /*-------------------------------------------------------------------*/
739 /* A6C4 VLVCA - Load VCT from Address [S] */
740 /*-------------------------------------------------------------------*/
DEF_INST(v_load_vct_from_address)741 DEF_INST(v_load_vct_from_address)
742 {
743 int b2; /* Base of effective addr */
744 VADR effective_addr2; /* Effective address */
745 U32 n;
746
747 S_NW(inst, regs, b2, effective_addr2);
748
749 VOP_CHECK(regs);
750
751 regs->psw.cc = ((S32)effective_addr2 == 0) ? 0 :
752 ((S32)effective_addr2 < 0) ? 1 :
753 ((S32)effective_addr2 > VECTOR_SECTION_SIZE) ? 2 : 3;
754
755 n = (S32)effective_addr2 < 0 ? 0 :
756 (S32)effective_addr2 > VECTOR_SECTION_SIZE ?
757 VECTOR_SECTION_SIZE : (S32)effective_addr2;
758
759 regs->vf->vsr &= ~VSR_VCT;
760 regs->vf->vsr |= (U64)n << 32;
761
762 }
763
764
765 /*-------------------------------------------------------------------*/
766 /* A6C5 VRCL - Clear VR [S] */
767 /*-------------------------------------------------------------------*/
DEF_INST(v_clear_vr)768 DEF_INST(v_clear_vr)
769 {
770 int b2; /* Base of effective addr */
771 VADR effective_addr2; /* Effective address */
772 U32 n, n1, n2;
773
774 S(inst, regs, b2, effective_addr2);
775
776 VOP_CHECK(regs);
777
778 /* Set vector interruption index to zero */
779 regs->vf->vsr &= ~VSR_VIX;
780
781 /* Clear vr's identified in the bit mask
782 n1 contains the vr number
783 n2 contains the bitmask identifying the vr number
784 n contains the element number */
785 for(n1 = 0, n2 = 0x80; n1 <= 14; n1 += 2, n2 >>= 1)
786 if(effective_addr2 & n2)
787 {
788 for(n = 0; n < VECTOR_SECTION_SIZE; n++)
789 {
790 regs->vf->vr[n1][n] = 0;
791 regs->vf->vr[n1+1][n] = 0;
792 }
793 RESET_VR_INUSE(n1, regs);
794 }
795
796 }
797
798
799 /*-------------------------------------------------------------------*/
800 /* A6C6 VSVMM - Set Vector Mask Mode [S] */
801 /*-------------------------------------------------------------------*/
DEF_INST(v_set_vector_mask_mode)802 DEF_INST(v_set_vector_mask_mode)
803 {
804 int b2; /* Base of effective addr */
805 VADR effective_addr2; /* Effective address */
806
807 S(inst, regs, b2, effective_addr2);
808
809 VOP_CHECK(regs);
810
811 if(effective_addr2 & 1)
812 regs->vf->vsr |= VSR_M;
813 else
814 regs->vf->vsr &= ~VSR_M;
815
816 }
817
818
819 /*-------------------------------------------------------------------*/
820 /* A6C7 VLVXA - Load VIX from Address [S] */
821 /*-------------------------------------------------------------------*/
DEF_INST(v_load_vix_from_address)822 DEF_INST(v_load_vix_from_address)
823 {
824 int b2; /* Base of effective addr */
825 VADR effective_addr2; /* Effective address */
826 U32 n;
827
828 S_NW(inst, regs, b2, effective_addr2);
829
830 VOP_CHECK(regs);
831
832 regs->psw.cc = ((S32)effective_addr2 == 0) ? 0 :
833 ((S32)effective_addr2 < 0) ? 1 :
834 ((S32)effective_addr2 < VECTOR_COUNT(regs)) ? 2 : 3;
835
836 n = (S32)effective_addr2 < 0 ? 0 :
837 (S32)effective_addr2 > VECTOR_SECTION_SIZE ?
838 VECTOR_SECTION_SIZE : (S32)effective_addr2;
839
840 regs->vf->vsr &= ~VSR_VIX;
841 regs->vf->vsr |= (U64)n << 16;
842
843 }
844
845
846 /*-------------------------------------------------------------------*/
847 /* A6C8 VSTVP - Store Vector Parameters [S] */
848 /*-------------------------------------------------------------------*/
DEF_INST(v_store_vector_parameters)849 DEF_INST(v_store_vector_parameters)
850 {
851 int b2; /* Base of effective addr */
852 VADR effective_addr2; /* Effective address */
853
854 S(inst, regs, b2, effective_addr2);
855
856 VOP_CHECK(regs);
857
858 FW_CHECK(effective_addr2, regs);
859
860 /* Store the section size and partial sum number */
861 ARCH_DEP(vstore4)(VECTOR_SECTION_SIZE << 16 | VECTOR_PARTIAL_SUM_NUMBER,
862 effective_addr2, b2, regs);
863
864 }
865
866
867 /*-------------------------------------------------------------------*/
868 /* A6CA VACSV - Save VAC [S] */
869 /*-------------------------------------------------------------------*/
DEF_INST(v_save_vac)870 DEF_INST(v_save_vac)
871 {
872 int b2; /* Base of effective addr */
873 VADR effective_addr2; /* Effective address */
874
875 S(inst, regs, b2, effective_addr2);
876
877 VOP_CHECK(regs);
878
879 PRIV_CHECK(regs);
880
881 DW_CHECK(effective_addr2, regs);
882
883 #if defined(_FEATURE_SIE)
884 if(SIE_STATB(regs, IC3, VACSV))
885 longjmp(regs->progjmp, SIE_INTERCEPT_INST);
886 #endif /*defined(_FEATURE_SIE)*/
887
888 ARCH_DEP(vstore8)(regs->vf->vac, effective_addr2, b2, regs);
889
890 }
891
892
893 /*-------------------------------------------------------------------*/
894 /* A6CB VACRS - Restore VAC [S] */
895 /*-------------------------------------------------------------------*/
DEF_INST(v_restore_vac)896 DEF_INST(v_restore_vac)
897 {
898 int b2; /* Base of effective addr */
899 VADR effective_addr2; /* Effective address */
900
901 S(inst, regs, b2, effective_addr2);
902
903 VOP_CHECK(regs);
904
905 PRIV_CHECK(regs);
906
907 DW_CHECK(effective_addr2, regs);
908
909 #if defined(_FEATURE_SIE)
910 if(SIE_STATB(regs, IC3, VACRS))
911 longjmp(regs->progjmp, SIE_INTERCEPT_INST);
912 #endif /*defined(_FEATURE_SIE)*/
913
914 regs->vf->vac = ARCH_DEP(vfetch8)(effective_addr2, b2, regs) & VAC_MASK;
915
916 }
917
918
919 #endif /*defined(FEATURE_VECTOR_FACILITY)*/
920
921
922 #if !defined(_GEN_ARCH)
923
924 #if defined(_ARCHMODE2)
925 #define _GEN_ARCH _ARCHMODE2
926 #include "vector.c"
927 #endif
928
929 #if defined(_ARCHMODE3)
930 #undef _GEN_ARCH
931 #define _GEN_ARCH _ARCHMODE3
932 #include "vector.c"
933 #endif
934
935 #endif /*!defined(_GEN_ARCH)*/
936