1 /* GENERAL1.C (c) Copyright Roger Bowler, 1994-2009 */
2 /* ESA/390 CPU Emulator */
3 /* Instructions A-M */
4
5 /* (c) Copyright Peter Kuschnerus, 1999-2009 (UPT & CFC)*/
6
7 /* Interpretive Execution - (c) Copyright Jan Jaeger, 1999-2009 */
8 /* z/Architecture support - (c) Copyright Jan Jaeger, 1999-2009 */
9
10 /*-------------------------------------------------------------------*/
11 /* This module implements general instructions A-M of the */
12 /* S/370 and ESA/390 architectures, as described in the manuals */
13 /* GA22-7000-03 System/370 Principles of Operation */
14 /* SA22-7201-06 ESA/390 Principles of Operation */
15 /*-------------------------------------------------------------------*/
16
17 /*-------------------------------------------------------------------*/
18 /* Additional credits: */
19 /* Corrections to shift instructions by Jay Maynard, Jan Jaeger */
20 /* Branch tracing by Jan Jaeger */
21 /* Instruction decode by macros - Jan Jaeger */
22 /* Prevent TOD from going backwards in time - Jan Jaeger */
23 /* Fix STCKE instruction - Bernard van der Helm */
24 /* Instruction decode rework - Jan Jaeger */
25 /* Make STCK update the TOD clock - Jay Maynard */
26 /* Fix address wraparound in MVO - Jan Jaeger */
27 /* PLO instruction - Jan Jaeger */
28 /* Modifications for Interpretive Execution (SIE) by Jan Jaeger */
29 /* Clear TEA on data exception - Peter Kuschnerus v209*/
30 /*-------------------------------------------------------------------*/
31
32 #include "hstdinc.h"
33
34 #if !defined(_HENGINE_DLL_)
35 #define _HENGINE_DLL_
36 #endif
37
38 #if !defined(_GENERAL1_C_)
39 #define _GENERAL1_C_
40 #endif
41
42 #include "hercules.h"
43 #include "opcode.h"
44 #include "inline.h"
45 #include "clock.h"
46
47
48 /*-------------------------------------------------------------------*/
49 /* 1A AR - Add Register [RR] */
50 /*-------------------------------------------------------------------*/
DEF_INST(add_register)51 DEF_INST(add_register)
52 {
53 int r1, r2; /* Values of R fields */
54
55 RR(inst, regs, r1, r2);
56
57 /* Add signed operands and set condition code */
58 regs->psw.cc =
59 add_signed (&(regs->GR_L(r1)),
60 regs->GR_L(r1),
61 regs->GR_L(r2));
62
63 /* Program check if fixed-point overflow */
64 if ( regs->psw.cc == 3 && FOMASK(®s->psw) )
65 regs->program_interrupt (regs, PGM_FIXED_POINT_OVERFLOW_EXCEPTION);
66 }
67
68
69 /*-------------------------------------------------------------------*/
70 /* 5A A - Add [RX] */
71 /*-------------------------------------------------------------------*/
DEF_INST(add)72 DEF_INST(add)
73 {
74 int r1; /* Values of R fields */
75 int b2; /* Base of effective addr */
76 VADR effective_addr2; /* Effective address */
77 U32 n; /* 32-bit operand values */
78
79 RX(inst, regs, r1, b2, effective_addr2);
80
81 /* Load second operand from operand address */
82 n = ARCH_DEP(vfetch4) ( effective_addr2, b2, regs );
83
84 /* Add signed operands and set condition code */
85 regs->psw.cc =
86 add_signed (&(regs->GR_L(r1)),
87 regs->GR_L(r1),
88 n);
89
90 /* Program check if fixed-point overflow */
91 if ( regs->psw.cc == 3 && FOMASK(®s->psw) )
92 regs->program_interrupt (regs, PGM_FIXED_POINT_OVERFLOW_EXCEPTION);
93
94 }
95
96
97 /*-------------------------------------------------------------------*/
98 /* 4A AH - Add Halfword [RX] */
99 /*-------------------------------------------------------------------*/
DEF_INST(add_halfword)100 DEF_INST(add_halfword)
101 {
102 int r1; /* Value of R field */
103 int b2; /* Base of effective addr */
104 VADR effective_addr2; /* Effective address */
105 S32 n; /* 32-bit operand values */
106
107 RX(inst, regs, r1, b2, effective_addr2);
108
109 /* Load 2 bytes from operand address */
110 n = (S16)ARCH_DEP(vfetch2) ( effective_addr2, b2, regs );
111
112 /* Add signed operands and set condition code */
113 regs->psw.cc =
114 add_signed (&(regs->GR_L(r1)),
115 regs->GR_L(r1),
116 (U32)n);
117
118 /* Program check if fixed-point overflow */
119 if ( regs->psw.cc == 3 && FOMASK(®s->psw) )
120 regs->program_interrupt (regs, PGM_FIXED_POINT_OVERFLOW_EXCEPTION);
121
122 }
123
124
125 #if defined(FEATURE_IMMEDIATE_AND_RELATIVE)
126 /*-------------------------------------------------------------------*/
127 /* A7xA AHI - Add Halfword Immediate [RI] */
128 /*-------------------------------------------------------------------*/
DEF_INST(add_halfword_immediate)129 DEF_INST(add_halfword_immediate)
130 {
131 int r1; /* Register number */
132 U16 i2; /* 16-bit immediate op */
133
134 RI(inst, regs, r1, i2);
135
136 /* Add signed operands and set condition code */
137 regs->psw.cc =
138 add_signed (&(regs->GR_L(r1)),
139 regs->GR_L(r1),
140 (S16)i2);
141
142 /* Program check if fixed-point overflow */
143 if ( regs->psw.cc == 3 && FOMASK(®s->psw) )
144 regs->program_interrupt (regs, PGM_FIXED_POINT_OVERFLOW_EXCEPTION);
145
146 }
147 #endif /*defined(FEATURE_IMMEDIATE_AND_RELATIVE)*/
148
149
150 /*-------------------------------------------------------------------*/
151 /* 1E ALR - Add Logical Register [RR] */
152 /*-------------------------------------------------------------------*/
DEF_INST(add_logical_register)153 DEF_INST(add_logical_register)
154 {
155 int r1, r2; /* Values of R fields */
156
157 RR0(inst, regs, r1, r2);
158
159 /* Add signed operands and set condition code */
160 regs->psw.cc =
161 add_logical (&(regs->GR_L(r1)),
162 regs->GR_L(r1),
163 regs->GR_L(r2));
164 }
165
166
167 /*-------------------------------------------------------------------*/
168 /* 5E AL - Add Logical [RX] */
169 /*-------------------------------------------------------------------*/
DEF_INST(add_logical)170 DEF_INST(add_logical)
171 {
172 int r1; /* Value of R field */
173 int b2; /* Base of effective addr */
174 VADR effective_addr2; /* Effective address */
175 U32 n; /* 32-bit operand values */
176
177 RX(inst, regs, r1, b2, effective_addr2);
178
179 /* Load second operand from operand address */
180 n = ARCH_DEP(vfetch4) ( effective_addr2, b2, regs );
181
182 /* Add signed operands and set condition code */
183 regs->psw.cc =
184 add_logical (&(regs->GR_L(r1)),
185 regs->GR_L(r1),
186 n);
187 }
188
189
190 /*-------------------------------------------------------------------*/
191 /* 14 NR - And Register [RR] */
192 /*-------------------------------------------------------------------*/
DEF_INST(and_register)193 DEF_INST(and_register)
194 {
195 int r1, r2; /* Values of R fields */
196
197 RR0(inst, regs, r1, r2);
198
199 /* AND second operand with first and set condition code */
200 regs->psw.cc = ( regs->GR_L(r1) &= regs->GR_L(r2) ) ? 1 : 0;
201 }
202
203
204 /*-------------------------------------------------------------------*/
205 /* 54 N - And [RX] */
206 /*-------------------------------------------------------------------*/
DEF_INST(and)207 DEF_INST(and)
208 {
209 int r1; /* Value of R field */
210 int b2; /* Base of effective addr */
211 VADR effective_addr2; /* Effective address */
212 U32 n; /* 32-bit operand values */
213
214 RX(inst, regs, r1, b2, effective_addr2);
215
216 /* Load second operand from operand address */
217 n = ARCH_DEP(vfetch4) ( effective_addr2, b2, regs );
218
219 /* AND second operand with first and set condition code */
220 regs->psw.cc = ( regs->GR_L(r1) &= n ) ? 1 : 0;
221 }
222
223
224 /*-------------------------------------------------------------------*/
225 /* 94 NI - And Immediate [SI] */
226 /*-------------------------------------------------------------------*/
DEF_INST(and_immediate)227 DEF_INST(and_immediate)
228 {
229 BYTE i2; /* Immediate byte of opcode */
230 int b1; /* Base of effective addr */
231 VADR effective_addr1; /* Effective address */
232 BYTE *dest; /* Pointer to target byte */
233
234 SI(inst, regs, i2, b1, effective_addr1);
235
236 /* Get byte mainstor address */
237 dest = MADDR (effective_addr1, b1, regs, ACCTYPE_WRITE, regs->psw.pkey );
238
239 /* AND byte with immediate operand, setting condition code */
240 regs->psw.cc = ((*dest &= i2) != 0);
241
242 /* Update interval timer if necessary */
243 ITIMER_UPDATE(effective_addr1,4-1,regs);
244 }
245
246
247 /*-------------------------------------------------------------------*/
248 /* D4 NC - And Character [SS] */
249 /*-------------------------------------------------------------------*/
DEF_INST(and_character)250 DEF_INST(and_character)
251 {
252 int len, len2, len3; /* Lengths to copy */
253 int b1, b2; /* Base register numbers */
254 VADR addr1, addr2; /* Virtual addresses */
255 BYTE *dest1, *dest2; /* Destination addresses */
256 BYTE *source1, *source2; /* Source addresses */
257 BYTE *sk1, *sk2; /* Storage key addresses */
258 int i; /* Loop counter */
259 int cc = 0; /* Condition code */
260
261 SS_L(inst, regs, len, b1, addr1, b2, addr2);
262
263 ITIMER_SYNC(addr2,len,regs);
264 ITIMER_SYNC(addr1,len,regs);
265
266 /* Quick out for 1 byte (no boundary crossed) */
267 if (unlikely(len == 0))
268 {
269 source1 = MADDR (addr2, b2, regs, ACCTYPE_READ, regs->psw.pkey);
270 dest1 = MADDR (addr1, b1, regs, ACCTYPE_WRITE, regs->psw.pkey);
271 *dest1 &= *source1;
272 regs->psw.cc = (*dest1 != 0);
273 ITIMER_UPDATE(addr1,0,regs);
274 return;
275 }
276
277 /* There are several scenarios (in optimal order):
278 * (1) dest boundary and source boundary not crossed
279 * (2) dest boundary not crossed and source boundary crossed
280 * (3) dest boundary crossed and source boundary not crossed
281 * (4) dest boundary and source boundary are crossed
282 * (a) dest and source boundary cross at the same time
283 * (b) dest boundary crossed first
284 * (c) source boundary crossed first
285 */
286
287 /* Translate addresses of leftmost operand bytes */
288 dest1 = MADDRL (addr1, len+1, b1, regs, ACCTYPE_WRITE_SKP, regs->psw.pkey);
289 sk1 = regs->dat.storkey;
290 source1 = MADDR (addr2, b2, regs, ACCTYPE_READ, regs->psw.pkey);
291
292 if ( NOCROSS2K(addr1,len ) )
293 {
294 if ( NOCROSS2K(addr2,len) )
295 {
296 /* (1) - No boundaries are crossed */
297 for (i = 0; i <= len; i++)
298 if (*dest1++ &= *source1++) cc = 1;
299
300 }
301 else
302 {
303 /* (2) - Second operand crosses a boundary */
304 len2 = 0x800 - (addr2 & 0x7FF);
305 source2 = MADDR ((addr2 + len2) & ADDRESS_MAXWRAP(regs),
306 b2, regs, ACCTYPE_READ, regs->psw.pkey);
307 for ( i = 0; i < len2; i++)
308 if (*dest1++ &= *source1++) cc = 1;
309 len2 = len - len2;
310 for ( i = 0; i <= len2; i++)
311 if (*dest1++ &= *source2++) cc = 1;
312 }
313 *sk1 |= (STORKEY_REF | STORKEY_CHANGE);
314 }
315 else
316 {
317 /* First operand crosses a boundary */
318 len2 = 0x800 - (addr1 & 0x7FF);
319 dest2 = MADDR ((addr1 + len2) & ADDRESS_MAXWRAP(regs),
320 b1, regs, ACCTYPE_WRITE_SKP, regs->psw.pkey);
321 sk2 = regs->dat.storkey;
322
323 if ( NOCROSS2K(addr2,len ))
324 {
325 /* (3) - First operand crosses a boundary */
326 for ( i = 0; i < len2; i++)
327 if (*dest1++ &= *source1++) cc = 1;
328 len2 = len - len2;
329 for ( i = 0; i <= len2; i++)
330 if (*dest2++ &= *source1++) cc = 1;
331 }
332 else
333 {
334 /* (4) - Both operands cross a boundary */
335 len3 = 0x800 - (addr2 & 0x7FF);
336 source2 = MADDR ((addr2 + len3) & ADDRESS_MAXWRAP(regs),
337 b2, regs, ACCTYPE_READ, regs->psw.pkey);
338 if (len2 == len3)
339 {
340 /* (4a) - Both operands cross at the same time */
341 for ( i = 0; i < len2; i++)
342 if (*dest1++ &= *source1++) cc = 1;
343 len2 = len - len2;
344 for ( i = 0; i <= len2; i++)
345 if (*dest2++ &= *source2++) cc = 1;
346 }
347 else if (len2 < len3)
348 {
349 /* (4b) - First operand crosses first */
350 for ( i = 0; i < len2; i++)
351 if (*dest1++ &= *source1++) cc = 1;
352 len2 = len3 - len2;
353 for ( i = 0; i < len2; i++)
354 if (*dest2++ &= *source1++) cc = 1;
355 len2 = len - len3;
356 for ( i = 0; i <= len2; i++)
357 if (*dest2++ &= *source2++) cc = 1;
358 }
359 else
360 {
361 /* (4c) - Second operand crosses first */
362 for ( i = 0; i < len3; i++)
363 if (*dest1++ &= *source1++) cc = 1;
364 len3 = len2 - len3;
365 for ( i = 0; i < len3; i++)
366 if (*dest1++ &= *source2++) cc = 1;
367 len3 = len - len2;
368 for ( i = 0; i <= len3; i++)
369 if (*dest2++ &= *source2++) cc = 1;
370 }
371 }
372 *sk1 |= (STORKEY_REF | STORKEY_CHANGE);
373 *sk2 |= (STORKEY_REF | STORKEY_CHANGE);
374 }
375 ITIMER_UPDATE(addr1,len,regs);
376
377 regs->psw.cc = cc;
378
379 }
380
381
382 /*-------------------------------------------------------------------*/
383 /* 05 BALR - Branch and Link Register [RR] */
384 /*-------------------------------------------------------------------*/
DEF_INST(branch_and_link_register)385 DEF_INST(branch_and_link_register)
386 {
387 int r1, r2; /* Values of R fields */
388 VADR newia; /* New instruction address */
389
390 RR_B(inst, regs, r1, r2);
391
392 #if defined(FEATURE_TRACING)
393 /* Add a branch trace entry to the trace table */
394 if ((regs->CR(12) & CR12_BRTRACE) && (r2 != 0))
395 {
396 regs->psw.ilc = 0; // indicates regs->ip not updated
397 regs->CR(12) = ((ARCH_DEP(trace_br_func))regs->trace_br)
398 (regs->psw.amode, regs->GR_L(r2), regs);
399 regs->psw.ilc = 2; // reset if trace didn't pgm check
400 }
401 #endif /*defined(FEATURE_TRACING)*/
402
403 /* Compute the branch address from the R2 operand */
404 newia = regs->GR(r2);
405
406 /* Save the link information in the R1 operand */
407 #if defined(FEATURE_ESAME)
408 if( regs->psw.amode64 )
409 regs->GR_G(r1) = PSW_IA64(regs, 2);
410 else
411 #endif
412 regs->GR_L(r1) =
413 ( regs->psw.amode )
414 ? (0x80000000 | PSW_IA31(regs, 2))
415 : (((!regs->execflag ? 2 : regs->exrl ? 6 : 4) << 29)
416 | (regs->psw.cc << 28) | (regs->psw.progmask << 24)
417 | PSW_IA24(regs, 2));
418
419 /* Execute the branch unless R2 specifies register 0 */
420 if ( r2 != 0 )
421 SUCCESSFUL_BRANCH(regs, newia, 2);
422 else
423 INST_UPDATE_PSW(regs, 2, 0);
424
425 } /* end DEF_INST(branch_and_link_register) */
426
427
428 /*-------------------------------------------------------------------*/
429 /* 45 BAL - Branch and Link [RX] */
430 /*-------------------------------------------------------------------*/
DEF_INST(branch_and_link)431 DEF_INST(branch_and_link)
432 {
433 int r1; /* Value of R field */
434 int b2; /* Base of effective addr */
435 VADR effective_addr2; /* Effective address */
436
437 RX_B(inst, regs, r1, b2, effective_addr2);
438
439 /* Save the link information in the R1 operand */
440 #if defined(FEATURE_ESAME)
441 if( regs->psw.amode64 )
442 regs->GR_G(r1) = PSW_IA64(regs, 4);
443 else
444 #endif
445 regs->GR_L(r1) =
446 ( regs->psw.amode )
447 ? (0x80000000 | PSW_IA31(regs, 4))
448 : ((4 << 29) | (regs->psw.cc << 28)
449 | (regs->psw.progmask << 24) | PSW_IA24(regs, 4));
450
451 SUCCESSFUL_BRANCH(regs, effective_addr2, 4);
452
453 } /* end DEF_INST(branch_and_link) */
454
455 /*-------------------------------------------------------------------*/
456 /* 0D BASR - Branch and Save Register [RR] */
457 /*-------------------------------------------------------------------*/
DEF_INST(branch_and_save_register)458 DEF_INST(branch_and_save_register)
459 {
460 int r1, r2; /* Values of R fields */
461 VADR newia; /* New instruction address */
462
463 RR_B(inst, regs, r1, r2);
464
465 #if defined(FEATURE_TRACING)
466 /* Add a branch trace entry to the trace table */
467 if ((regs->CR(12) & CR12_BRTRACE) && (r2 != 0))
468 {
469 regs->psw.ilc = 0; // indcates regs->ip not updated
470 regs->CR(12) = ((ARCH_DEP(trace_br_func))regs->trace_br)
471 (regs->psw.amode, regs->GR_L(r2), regs);
472 regs->psw.ilc = 2; // reset if trace didn't pgm check
473 }
474 #endif /*defined(FEATURE_TRACING)*/
475
476 /* Compute the branch address from the R2 operand */
477 newia = regs->GR(r2);
478
479 /* Save the link information in the R1 operand */
480 #if defined(FEATURE_ESAME)
481 if ( regs->psw.amode64 )
482 regs->GR_G(r1) = PSW_IA64(regs, 2);
483 else
484 #endif
485 if ( regs->psw.amode )
486 regs->GR_L(r1) = 0x80000000 | PSW_IA31(regs, 2);
487 else
488 regs->GR_L(r1) = PSW_IA24(regs, 2);
489
490 /* Execute the branch unless R2 specifies register 0 */
491 if ( r2 != 0 )
492 SUCCESSFUL_BRANCH(regs, newia, 2);
493 else
494 INST_UPDATE_PSW(regs, 2, 0);
495
496 } /* end DEF_INST(branch_and_save_register) */
497
498
499 /*-------------------------------------------------------------------*/
500 /* 4D BAS - Branch and Save [RX] */
501 /*-------------------------------------------------------------------*/
DEF_INST(branch_and_save)502 DEF_INST(branch_and_save)
503 {
504 int r1; /* Value of R field */
505 int b2; /* Base of effective addr */
506 VADR effective_addr2; /* Effective address */
507
508 RX_B(inst, regs, r1, b2, effective_addr2);
509
510 /* Save the link information in the R1 register */
511 #if defined(FEATURE_ESAME)
512 if ( regs->psw.amode64 )
513 regs->GR_G(r1) = PSW_IA64(regs, 4);
514 else
515 #endif
516 if ( regs->psw.amode )
517 regs->GR_L(r1) = 0x80000000 | PSW_IA31(regs, 4);
518 else
519 regs->GR_L(r1) = PSW_IA24(regs, 4);
520
521 SUCCESSFUL_BRANCH(regs, effective_addr2, 4);
522
523 } /* end DEF_INST(branch_and_save) */
524
525
526 #if defined(FEATURE_BIMODAL_ADDRESSING)
527 /*-------------------------------------------------------------------*/
528 /* 0C BASSM - Branch and Save and Set Mode [RR] */
529 /*-------------------------------------------------------------------*/
DEF_INST(branch_and_save_and_set_mode)530 DEF_INST(branch_and_save_and_set_mode)
531 {
532 int r1, r2; /* Values of R fields */
533 VADR newia; /* New instruction address */
534 int xmode; /* 64 or 31 mode of target */
535 #if defined(FEATURE_ESAME)
536 BYTE *ipsav; /* save for ip */
537 #endif /*defined(FEATURE_ESAME)*/
538
539 RR_B(inst, regs, r1, r2);
540
541 /* Compute the branch address from the R2 operand */
542 newia = regs->GR(r2);
543
544 #if defined(FEATURE_TRACING)
545 #if defined(FEATURE_ESAME)
546 /* Add a mode trace entry when switching in/out of 64 bit mode */
547 if((regs->CR(12) & CR12_MTRACE) && (r2 != 0) && (regs->psw.amode64 != (newia & 1)))
548 {
549 /* save ip and update it for mode switch trace */
550 ipsav = regs->ip;
551 INST_UPDATE_PSW(regs, 2, 0);
552 regs->psw.ilc = 2;
553 regs->CR(12) = ARCH_DEP(trace_ms) (regs->CR(12) & CR12_BRTRACE ? 1 : 0,
554 newia & ~0x01, regs);
555 regs->ip = ipsav;
556 }
557 else
558 #endif /*defined(FEATURE_ESAME)*/
559 /* Add a branch trace entry to the trace table */
560 if ((regs->CR(12) & CR12_BRTRACE) && (r2 != 0))
561 {
562 regs->psw.ilc = 0; // indicates regs->ip not updated
563 #if defined(FEATURE_ESAME)
564 if (newia & 0x01)
565 xmode = 1;
566 else
567 #endif /*defined(FEATURE_ESAME)*/
568 xmode = newia & 0x80000000 ? 1 : 0;
569 regs->CR(12) = ARCH_DEP(trace_br) (xmode, newia & ~0x01, regs);
570 regs->psw.ilc = 2; // reset if trace didn't pgm check
571 }
572 #endif /*defined(FEATURE_TRACING)*/
573
574 /* Save the link information in the R1 operand */
575 #if defined(FEATURE_ESAME)
576 if ( regs->psw.amode64 )
577 regs->GR_G(r1) = PSW_IA64(regs, 3); // low bit on
578 else
579 #endif /*defined(FEATURE_ESAME)*/
580 if ( regs->psw.amode )
581 regs->GR_L(r1) = 0x80000000 | PSW_IA31(regs, 2);
582 else
583 regs->GR_L(r1) = PSW_IA24(regs, 2);
584
585 /* Set mode and branch to address specified by R2 operand */
586 if ( r2 != 0 )
587 {
588 SET_ADDRESSING_MODE(regs, newia);
589 SUCCESSFUL_BRANCH(regs, newia, 2);
590 }
591 else
592 INST_UPDATE_PSW(regs, 2, 0);
593
594 } /* end DEF_INST(branch_and_save_and_set_mode) */
595 #endif /*defined(FEATURE_BIMODAL_ADDRESSING)*/
596
597
598 #if defined(FEATURE_BIMODAL_ADDRESSING)
599 /*-------------------------------------------------------------------*/
600 /* 0B BSM - Branch and Set Mode [RR] */
601 /*-------------------------------------------------------------------*/
DEF_INST(branch_and_set_mode)602 DEF_INST(branch_and_set_mode)
603 {
604 int r1, r2; /* Values of R fields */
605 VADR newia; /* New instruction address */
606
607 RR_B(inst, regs, r1, r2);
608
609 /* Compute the branch address from the R2 operand */
610 newia = regs->GR(r2);
611
612 #if defined(FEATURE_TRACING)
613 #if defined(FEATURE_ESAME)
614 /* Add a mode trace entry when switching in/out of 64 bit mode */
615 if((regs->CR(12) & CR12_MTRACE) && (r2 != 0) && (regs->psw.amode64 != (newia & 1)))
616 {
617 INST_UPDATE_PSW(regs, 2, 0);
618 regs->psw.ilc = 2;
619 regs->CR(12) = ARCH_DEP(trace_ms) (0, 0, regs);
620 }
621 #endif /*defined(FEATURE_ESAME)*/
622 #endif /*defined(FEATURE_TRACING)*/
623
624 /* Insert addressing mode into bit 0 of R1 operand */
625 if ( r1 != 0 )
626 {
627 #if defined(FEATURE_ESAME)
628 /* Z/Pops seems to be in error about this */
629 // regs->GR_LHLCL(r1) &= 0xFE;
630 if ( regs->psw.amode64 )
631 regs->GR_LHLCL(r1) |= 0x01;
632 else
633 #endif
634 {
635 if ( regs->psw.amode )
636 regs->GR_L(r1) |= 0x80000000;
637 else
638 regs->GR_L(r1) &= 0x7FFFFFFF;
639 }
640 }
641
642 /* Set mode and branch to address specified by R2 operand */
643 if ( r2 != 0 )
644 {
645 SET_ADDRESSING_MODE(regs, newia);
646 SUCCESSFUL_BRANCH(regs, newia, 2);
647 }
648 else
649 INST_UPDATE_PSW(regs, 2, 0);
650
651 } /* end DEF_INST(branch_and_set_mode) */
652 #endif /*defined(FEATURE_BIMODAL_ADDRESSING)*/
653
654
655 /*-------------------------------------------------------------------*/
656 /* 07 BCR - Branch on Condition Register [RR] */
657 /*-------------------------------------------------------------------*/
DEF_INST(branch_on_condition_register)658 DEF_INST(branch_on_condition_register)
659 {
660 //int r1, r2; /* Values of R fields */
661
662 // RR(inst, regs, r1, r2);
663
664 /* Branch if R1 mask bit is set and R2 is not register 0 */
665 if ((inst[1] & 0x0F) != 0 && (inst[1] & (0x80 >> regs->psw.cc)))
666 SUCCESSFUL_BRANCH(regs, regs->GR(inst[1] & 0x0F), 2);
667 else
668 {
669 INST_UPDATE_PSW(regs, 2, 0);
670 /* Perform serialization and checkpoint synchronization if
671 the mask is all ones and R2 is register 0 */
672 if ( inst[1] == 0xF0 )
673 {
674 PERFORM_SERIALIZATION (regs);
675 PERFORM_CHKPT_SYNC (regs);
676 }
677 #if defined(FEATURE_FAST_BCR_SERIALIZATION_FACILITY) /*810*/
678 /* Perform serialization without checkpoint synchronization
679 the mask is B'1110' and R2 is register 0 */
680 else if (inst[1] == 0xE0)
681 {
682 PERFORM_SERIALIZATION (regs);
683 }
684 #endif /*defined(FEATURE_FAST_BCR_SERIALIZATION_FACILITY)*/
685 }
686
687 } /* end DEF_INST(branch_on_condition_register) */
688
689
690 /*-------------------------------------------------------------------*/
691 /* 47 BC - Branch on Condition [RX] */
692 /*-------------------------------------------------------------------*/
DEF_INST(branch_on_condition)693 DEF_INST(branch_on_condition)
694 {
695 int b2; /* Base of effective addr */
696 VADR effective_addr2; /* Effective address */
697
698 /* Branch to operand address if r1 mask bit is set */
699 if ((0x80 >> regs->psw.cc) & inst[1])
700 {
701 RX_BC(inst, regs, b2, effective_addr2);
702 SUCCESSFUL_BRANCH(regs, effective_addr2, 4);
703 }
704 else
705 INST_UPDATE_PSW(regs, 4, 0);
706
707 } /* end DEF_INST(branch_on_condition) */
708
709
710 /*-------------------------------------------------------------------*/
711 /* 06 BCTR - Branch on Count Register [RR] */
712 /*-------------------------------------------------------------------*/
DEF_INST(branch_on_count_register)713 DEF_INST(branch_on_count_register)
714 {
715 int r1, r2; /* Values of R fields */
716 VADR newia; /* New instruction address */
717
718 RR_B(inst, regs, r1, r2);
719
720 /* Compute the branch address from the R2 operand */
721 newia = regs->GR(r2);
722
723 /* Subtract 1 from the R1 operand and branch if result
724 is non-zero and R2 operand is not register zero */
725 if ( --(regs->GR_L(r1)) && r2 != 0 )
726 SUCCESSFUL_BRANCH(regs, newia, 2);
727 else
728 INST_UPDATE_PSW(regs, 2, 0);
729
730 } /* end DEF_INST(branch_on_count_register) */
731
732
733 /*-------------------------------------------------------------------*/
734 /* 46 BCT - Branch on Count [RX] */
735 /*-------------------------------------------------------------------*/
DEF_INST(branch_on_count)736 DEF_INST(branch_on_count)
737 {
738 int r1; /* Value of R field */
739 int b2; /* Base of effective addr */
740 VADR effective_addr2; /* Effective address */
741
742 RX_B(inst, regs, r1, b2, effective_addr2);
743
744 /* Subtract 1 from the R1 operand and branch if non-zero */
745 if ( --(regs->GR_L(r1)) )
746 SUCCESSFUL_BRANCH(regs, effective_addr2, 4);
747 else
748 INST_UPDATE_PSW(regs, 4, 0);
749
750 } /* end DEF_INST(branch_on_count) */
751
752
753 /*-------------------------------------------------------------------*/
754 /* 86 BXH - Branch on Index High [RS] */
755 /*-------------------------------------------------------------------*/
DEF_INST(branch_on_index_high)756 DEF_INST(branch_on_index_high)
757 {
758 int r1, r3; /* Register numbers */
759 int b2; /* effective address base */
760 VADR effective_addr2; /* effective address */
761 S32 i, j; /* Integer work areas */
762
763 RS_B(inst, regs, r1, r3, b2, effective_addr2);
764
765 /* Load the increment value from the R3 register */
766 i = (S32)regs->GR_L(r3);
767
768 /* Load compare value from R3 (if R3 odd), or R3+1 (if even) */
769 j = (r3 & 1) ? (S32)regs->GR_L(r3) : (S32)regs->GR_L(r3+1);
770
771 /* Add the increment value to the R1 register */
772 regs->GR_L(r1) = (S32)regs->GR_L(r1) + i;
773
774 /* Branch if result compares high */
775 if ( (S32)regs->GR_L(r1) > j )
776 SUCCESSFUL_BRANCH(regs, effective_addr2, 4);
777 else
778 INST_UPDATE_PSW(regs, 4, 0);
779
780 } /* end DEF_INST(branch_on_index_high) */
781
782
783 /*-------------------------------------------------------------------*/
784 /* 87 BXLE - Branch on Index Low or Equal [RS] */
785 /*-------------------------------------------------------------------*/
DEF_INST(branch_on_index_low_or_equal)786 DEF_INST(branch_on_index_low_or_equal)
787 {
788 int r1, r3; /* Register numbers */
789 int b2; /* effective address base */
790 VADR effective_addr2; /* effective address */
791 S32 i, j; /* Integer work areas */
792
793 RS_B(inst, regs, r1, r3, b2, effective_addr2);
794
795 /* Load the increment value from the R3 register */
796 i = regs->GR_L(r3);
797
798 /* Load compare value from R3 (if R3 odd), or R3+1 (if even) */
799 j = (r3 & 1) ? (S32)regs->GR_L(r3) : (S32)regs->GR_L(r3+1);
800
801 /* Add the increment value to the R1 register */
802 regs->GR_L(r1) = (S32)regs->GR_L(r1) + i;
803
804 /* Branch if result compares low or equal */
805 if ( (S32)regs->GR_L(r1) <= j )
806 SUCCESSFUL_BRANCH(regs, effective_addr2, 4);
807 else
808 INST_UPDATE_PSW(regs, 4, 0);
809
810 } /* end DEF_INST(branch_on_index_low_or_equal) */
811
812
813 #if defined(FEATURE_IMMEDIATE_AND_RELATIVE)
814 /*-------------------------------------------------------------------*/
815 /* A7x4 BRC - Branch Relative on Condition [RI] */
816 /*-------------------------------------------------------------------*/
DEF_INST(branch_relative_on_condition)817 DEF_INST(branch_relative_on_condition)
818 {
819 //int r1; /* Register number */
820 U16 i2; /* 16-bit operand values */
821
822 // RI(inst, regs, r1, i2);
823
824 /* Branch if R1 mask bit is set */
825 if (inst[1] & (0x80 >> regs->psw.cc))
826 {
827 i2 = fetch_fw(inst) & 0xFFFF;
828 SUCCESSFUL_RELATIVE_BRANCH(regs, 2*(S16)i2, 4);
829 }
830 else
831 INST_UPDATE_PSW(regs, 4, 0);
832
833 } /* end DEF_INST(branch_relative_on_condition) */
834 #endif /*defined(FEATURE_IMMEDIATE_AND_RELATIVE)*/
835
836
837 #if defined(FEATURE_IMMEDIATE_AND_RELATIVE)
838 /*-------------------------------------------------------------------*/
839 /* A7x5 BRAS - Branch Relative And Save [RI] */
840 /*-------------------------------------------------------------------*/
DEF_INST(branch_relative_and_save)841 DEF_INST(branch_relative_and_save)
842 {
843 int r1; /* Register number */
844 U16 i2; /* 16-bit operand values */
845
846 RI_B(inst, regs, r1, i2);
847
848 /* Save the link information in the R1 operand */
849 #if defined(FEATURE_ESAME)
850 if ( regs->psw.amode64 )
851 regs->GR_G(r1) = PSW_IA64(regs, 4);
852 else
853 #endif
854 if ( regs->psw.amode )
855 regs->GR_L(r1) = 0x80000000 | PSW_IA31(regs, 4);
856 else
857 regs->GR_L(r1) = PSW_IA24(regs, 4);
858
859 SUCCESSFUL_RELATIVE_BRANCH(regs, 2*(S16)i2, 4);
860
861 } /* end DEF_INST(branch_relative_and_save) */
862 #endif /*defined(FEATURE_IMMEDIATE_AND_RELATIVE)*/
863
864
865 #if defined(FEATURE_IMMEDIATE_AND_RELATIVE)
866 /*-------------------------------------------------------------------*/
867 /* A7x6 BRCT - Branch Relative on Count [RI] */
868 /*-------------------------------------------------------------------*/
DEF_INST(branch_relative_on_count)869 DEF_INST(branch_relative_on_count)
870 {
871 int r1; /* Register number */
872 U16 i2; /* 16-bit operand values */
873
874 RI_B(inst, regs, r1, i2);
875
876 /* Subtract 1 from the R1 operand and branch if non-zero */
877 if ( --(regs->GR_L(r1)) )
878 SUCCESSFUL_RELATIVE_BRANCH(regs, 2*(S16)i2, 4);
879 else
880 INST_UPDATE_PSW(regs, 4, 0);
881
882 } /* end DEF_INST(branch_relative_on_count) */
883 #endif /*defined(FEATURE_IMMEDIATE_AND_RELATIVE)*/
884
885
886 #if defined(FEATURE_IMMEDIATE_AND_RELATIVE)
887 /*-------------------------------------------------------------------*/
888 /* 84 BRXH - Branch Relative on Index High [RSI] */
889 /*-------------------------------------------------------------------*/
DEF_INST(branch_relative_on_index_high)890 DEF_INST(branch_relative_on_index_high)
891 {
892 int r1, r3; /* Register numbers */
893 U16 i2; /* 16-bit operand */
894 S32 i,j; /* Integer workareas */
895
896 RSI_B(inst, regs, r1, r3, i2);
897
898 /* Load the increment value from the R3 register */
899 i = (S32)regs->GR_L(r3);
900
901 /* Load compare value from R3 (if R3 odd), or R3+1 (if even) */
902 j = (r3 & 1) ? (S32)regs->GR_L(r3) : (S32)regs->GR_L(r3+1);
903
904 /* Add the increment value to the R1 register */
905 regs->GR_L(r1) = (S32)regs->GR_L(r1) + i;
906
907 /* Branch if result compares high */
908 if ( (S32)regs->GR_L(r1) > j )
909 SUCCESSFUL_RELATIVE_BRANCH(regs, 2*(S16)i2, 4);
910 else
911 INST_UPDATE_PSW(regs, 4, 0);
912
913 } /* end DEF_INST(branch_relative_on_index_high) */
914 #endif /*defined(FEATURE_IMMEDIATE_AND_RELATIVE)*/
915
916
917 #if defined(FEATURE_IMMEDIATE_AND_RELATIVE)
918 /*-------------------------------------------------------------------*/
919 /* 85 BRXLE - Branch Relative on Index Low or Equal [RSI] */
920 /*-------------------------------------------------------------------*/
DEF_INST(branch_relative_on_index_low_or_equal)921 DEF_INST(branch_relative_on_index_low_or_equal)
922 {
923 int r1, r3; /* Register numbers */
924 U16 i2; /* 16-bit operand */
925 S32 i,j; /* Integer workareas */
926
927 RSI_B(inst, regs, r1, r3, i2);
928
929 /* Load the increment value from the R3 register */
930 i = (S32)regs->GR_L(r3);
931
932 /* Load compare value from R3 (if R3 odd), or R3+1 (if even) */
933 j = (r3 & 1) ? (S32)regs->GR_L(r3) : (S32)regs->GR_L(r3+1);
934
935 /* Add the increment value to the R1 register */
936 regs->GR_L(r1) = (S32)regs->GR_L(r1) + i;
937
938 /* Branch if result compares low or equal */
939 if ( (S32)regs->GR_L(r1) <= j )
940 SUCCESSFUL_RELATIVE_BRANCH(regs, 2*(S16)i2, 4);
941 else
942 INST_UPDATE_PSW(regs, 4, 0);
943
944 } /* end DEF_INST(branch_relative_on_index_low_or_equal) */
945 #endif /*defined(FEATURE_IMMEDIATE_AND_RELATIVE)*/
946
947
948 #if defined(FEATURE_CHECKSUM_INSTRUCTION)
949 /*-------------------------------------------------------------------*/
950 /* B241 CKSM - Checksum [RRE] */
951 /*-------------------------------------------------------------------*/
DEF_INST(checksum)952 DEF_INST(checksum)
953 {
954 int r1, r2; /* Values of R fields */
955 VADR addr2; /* Address of second operand */
956 GREG len; /* Operand length */
957 int i, j; /* Loop counters */
958 int cc = 0; /* Condition code */
959 U32 n; /* Word loaded from operand */
960 U64 dreg; /* Checksum accumulator */
961
962 RRE(inst, regs, r1, r2);
963
964 ODD_CHECK(r2, regs);
965
966 /* Obtain the second operand address and length from R2, R2+1 */
967 addr2 = regs->GR(r2) & ADDRESS_MAXWRAP(regs);
968 len = GR_A(r2+1, regs);
969
970 /* Initialize the checksum from the first operand register */
971 dreg = regs->GR_L(r1);
972
973 /* Process each fullword of second operand */
974 for ( i = 0; len > 0 ; i++ )
975 {
976 /* If 1024 words have been processed, exit with cc=3 */
977 if ( i >= 1024 )
978 {
979 cc = 3;
980 break;
981 }
982
983 /* Fetch fullword from second operand */
984 if (len >= 4)
985 {
986 n = ARCH_DEP(vfetch4) ( addr2, r2, regs );
987 addr2 += 4;
988 addr2 &= ADDRESS_MAXWRAP(regs);
989 len -= 4;
990 }
991 else
992 {
993 /* Fetch final 1, 2, or 3 bytes and pad with zeroes */
994 for (j = 0, n = 0; j < 4; j++)
995 {
996 n <<= 8;
997 if (len > 0)
998 {
999 n |= ARCH_DEP(vfetchb) ( addr2, r2, regs );
1000 addr2++;
1001 addr2 &= ADDRESS_MAXWRAP(regs);
1002 len--;
1003 }
1004 } /* end for(j) */
1005 }
1006
1007 /* Accumulate the fullword into the checksum */
1008 dreg += n;
1009
1010 /* Carry 32 bit overflow into bit 31 */
1011 if (dreg > 0xFFFFFFFFULL)
1012 {
1013 dreg &= 0xFFFFFFFFULL;
1014 dreg++;
1015 }
1016 } /* end for(i) */
1017
1018 /* Load the updated checksum into the R1 register */
1019 regs->GR_L(r1) = dreg;
1020
1021 /* Update the operand address and length registers */
1022 SET_GR_A(r2, regs,addr2);
1023 SET_GR_A(r2+1, regs,len);
1024
1025 /* Set condition code 0 or 3 */
1026 regs->psw.cc = cc;
1027
1028 }
1029 #endif /*defined(FEATURE_CHECKSUM_INSTRUCTION)*/
1030
1031
1032 /*-------------------------------------------------------------------*/
1033 /* 19 CR - Compare Register [RR] */
1034 /*-------------------------------------------------------------------*/
DEF_INST(compare_register)1035 DEF_INST(compare_register)
1036 {
1037 int r1, r2; /* Values of R fields */
1038
1039 RR0(inst, regs, r1, r2);
1040
1041 /* Compare signed operands and set condition code */
1042 regs->psw.cc =
1043 (S32)regs->GR_L(r1) < (S32)regs->GR_L(r2) ? 1 :
1044 (S32)regs->GR_L(r1) > (S32)regs->GR_L(r2) ? 2 : 0;
1045 }
1046
1047
1048 /*-------------------------------------------------------------------*/
1049 /* 59 C - Compare [RX] */
1050 /*-------------------------------------------------------------------*/
DEF_INST(compare)1051 DEF_INST(compare)
1052 {
1053 int r1; /* Values of R fields */
1054 int b2; /* Base of effective addr */
1055 VADR effective_addr2; /* Effective address */
1056 U32 n; /* 32-bit operand values */
1057
1058 RX(inst, regs, r1, b2, effective_addr2);
1059
1060 /* Load second operand from operand address */
1061 n = ARCH_DEP(vfetch4) ( effective_addr2, b2, regs );
1062
1063 /* Compare signed operands and set condition code */
1064 regs->psw.cc =
1065 (S32)regs->GR_L(r1) < (S32)n ? 1 :
1066 (S32)regs->GR_L(r1) > (S32)n ? 2 : 0;
1067 }
1068
1069
1070 /*-------------------------------------------------------------------*/
1071 /* B21A CFC - Compare and Form Codeword [S] */
1072 /* (c) Copyright Peter Kuschnerus, 1999-2009 */
1073 /* (c) Copyright "Fish" (David B. Trout), 2005-2009 */
1074 /*-------------------------------------------------------------------*/
1075
DEF_INST(compare_and_form_codeword)1076 DEF_INST(compare_and_form_codeword)
1077 {
1078 int b2; /* Base of effective addr */
1079 int rc; /* memcmp() return code */
1080 int i; /* (work var) */
1081 VADR op2_effective_addr; /* (op2 effective address) */
1082 VADR op1_addr, op3_addr; /* (op1 & op3 fetch addr) */
1083 GREG work_reg; /* (register work area) */
1084 U16 index, max_index; /* (operand index values) */
1085 BYTE op1[CFC_MAX_OPSIZE]; /* (work field) */
1086 BYTE op3[CFC_MAX_OPSIZE]; /* (work field) */
1087 BYTE tmp[CFC_MAX_OPSIZE]; /* (work field) */
1088 BYTE descending; /* (sort-order control bit) */
1089 #if defined(FEATURE_ESAME)
1090 BYTE a64 = regs->psw.amode64; /* ("64-bit mode" flag) */
1091 #endif
1092 BYTE op_size = CFC_OPSIZE; /* (work constant; uses a64) */
1093 BYTE gr2_shift = CFC_GR2_SHIFT; /* (work constant; uses a64) */
1094 GREG gr2_high_bit = CFC_HIGH_BIT; /* (work constant; uses a64) */
1095
1096 S(inst, regs, b2, op2_effective_addr);
1097
1098 /* All operands must be halfword aligned */
1099 if (0
1100 || GR_A(1,regs) & 1
1101 || GR_A(2,regs) & 1
1102 || GR_A(3,regs) & 1
1103 )
1104 regs->program_interrupt (regs, PGM_SPECIFICATION_EXCEPTION);
1105
1106 /* Initialize "end-of-operand-data" index value... */
1107 max_index = op2_effective_addr & 0x7FFE;
1108
1109 /* Loop until we either locate where the two operands
1110 differ from one another or until we reach the end of
1111 the operand data... */
1112 do
1113 {
1114 /* Exit w/cc0 (op1==op3) when end of operands are reached */
1115
1116 index = GR_A(2,regs) & 0xFFFF;
1117
1118 if ( index > max_index )
1119 {
1120 regs->psw.cc = 0; // (operands are equal to each other)
1121 SET_GR_A( 2, regs, GR_A(3,regs) | gr2_high_bit );
1122 return;
1123 }
1124
1125 /* Fetch next chunk of operand data... */
1126
1127 op1_addr = ( regs->GR(1) + index ) & ADDRESS_MAXWRAP(regs);
1128 op3_addr = ( regs->GR(3) + index ) & ADDRESS_MAXWRAP(regs);
1129
1130 ARCH_DEP( vfetchc )( op1, op_size - 1, op1_addr, AR1, regs );
1131 ARCH_DEP( vfetchc )( op3, op_size - 1, op3_addr, AR1, regs );
1132
1133 /* Update GR2 operand index value... (Note: we must do this AFTER
1134 we fetch the operand data in case of storage access exceptions) */
1135
1136 SET_GR_A( 2, regs, GR_A(2,regs) + op_size );
1137
1138 /* Compare operands; continue while still equal... */
1139 }
1140 while ( !( rc = memcmp( op1, op3, op_size ) ) );
1141
1142 /* Operands are NOT equal (we found an inequality). Set
1143 the condition code, form our codeword, and then exit */
1144
1145 ASSERT( rc != 0 ); // (we shouldn't be here unless this is true!)
1146
1147 /* Check to see which sequence the operands should be sorted into so
1148 we can know whether or not we need to form our codeword using either
1149 the inverse of the higher operand's data (if doing an ascending sort),
1150 or the lower operand's data AS-IS (if doing a descending sort). This
1151 thus causes either the lower (or higher) operand values (depending on
1152 which type of sort we're doing, ascending or descending) to bubble to
1153 the top (beginning) of the tree that the UPT (Update Tree) instruction
1154 ultimately/eventually updates (which gets built from our codewords).
1155 */
1156
1157 descending = op2_effective_addr & 1; // (0==ascending, 1==descending)
1158
1159 if ( rc < 0 ) // (operand-1 < operand-3)
1160 {
1161 if ( !descending ) // (ascending; in sequence)
1162 {
1163 regs->psw.cc = 1; // (cc1 == in sequence)
1164
1165 /* Ascending sort: use inverse of higher operand's data */
1166
1167 for ( i=0; i < op_size; i++ )
1168 tmp[i] = ~op3[i];
1169 }
1170 else // (descending; out-of-sequence)
1171 {
1172 regs->psw.cc = 2; // (cc2 == out-of-sequence)
1173
1174 /* Descending sort: use lower operand's data as-is */
1175
1176 memcpy( tmp, op1, op_size );
1177
1178 /* Swap GR1 & GR3 because out-of-sequence */
1179
1180 work_reg = GR_A(1,regs);
1181 SET_GR_A( 1, regs, GR_A(3,regs) );
1182 SET_GR_A( 3, regs, work_reg );
1183 }
1184 }
1185 else // (operand-1 > operand-3)
1186 {
1187 if ( !descending ) // (ascending; out-of-sequence)
1188 {
1189 regs->psw.cc = 2; // (cc2 == out-of-sequence)
1190
1191 /* Ascending sort: use inverse of higher operand's data */
1192
1193 for ( i=0; i < op_size; i++ )
1194 tmp[i] = ~op1[i];
1195
1196 /* Swap GR1 & GR3 because out-of-sequence */
1197
1198 work_reg = GR_A(1,regs);
1199 SET_GR_A( 1, regs, GR_A(3,regs) );
1200 SET_GR_A( 3, regs, work_reg );
1201 }
1202 else // (descending; in sequence)
1203 {
1204 regs->psw.cc = 1; // (cc1 == in sequence)
1205
1206 /* Descending sort: use lower operand's data as-is */
1207
1208 memcpy( tmp, op3, op_size );
1209 }
1210 }
1211
1212 /* Form a sort/merge codeword to be used to sort the two operands
1213 into their proper sequence consisting of a combination of both
1214 the index position where the inequality was found (current GR2
1215 value) and either the one's complement inverse of the higher
1216 operand's data (if doing an ascending sort) or the lower oper-
1217 and's data as-is (if doing a descending sort)...
1218 */
1219
1220 for ( work_reg=0, i=0; i < op_size; i++ )
1221 work_reg = ( work_reg << 8 ) | tmp[i];
1222
1223 SET_GR_A( 2, regs, ( GR_A(2,regs) << gr2_shift ) | work_reg );
1224 }
1225
1226
1227 /*-------------------------------------------------------------------*/
1228 /* BA CS - Compare and Swap [RS] */
1229 /*-------------------------------------------------------------------*/
DEF_INST(compare_and_swap)1230 DEF_INST(compare_and_swap)
1231 {
1232 int r1, r3; /* Register numbers */
1233 int b2; /* effective address base */
1234 VADR addr2; /* effective address */
1235 BYTE *main2; /* mainstor address */
1236 U32 old; /* old value */
1237
1238 RS(inst, regs, r1, r3, b2, addr2);
1239
1240 FW_CHECK(addr2, regs);
1241
1242 ITIMER_SYNC(addr2,4-1,regs);
1243
1244 /* Perform serialization before starting operation */
1245 PERFORM_SERIALIZATION (regs);
1246
1247 /* Get mainstor address */
1248 main2 = MADDRL (addr2, 4, b2, regs, ACCTYPE_WRITE, regs->psw.pkey);
1249
1250 old = CSWAP32(regs->GR_L(r1));
1251
1252 /* Obtain main-storage access lock */
1253 OBTAIN_MAINLOCK(regs);
1254
1255 /* Attempt to exchange the values */
1256 regs->psw.cc = cmpxchg4 (&old, CSWAP32(regs->GR_L(r3)), main2);
1257
1258 /* Release main-storage access lock */
1259 RELEASE_MAINLOCK(regs);
1260
1261 /* Perform serialization after completing operation */
1262 PERFORM_SERIALIZATION (regs);
1263
1264 if (regs->psw.cc == 1)
1265 {
1266 PTT(PTT_CL_CSF,"*CS",regs->GR_L(r1),regs->GR_L(r3),(U32)(addr2 & 0xffffffff));
1267 regs->GR_L(r1) = CSWAP32(old);
1268 #if defined(_FEATURE_SIE)
1269 if(SIE_STATB(regs, IC0, CS1))
1270 {
1271 if( !OPEN_IC_PER(regs) )
1272 longjmp(regs->progjmp, SIE_INTERCEPT_INST);
1273 else
1274 longjmp(regs->progjmp, SIE_INTERCEPT_INSTCOMP);
1275 }
1276 else
1277 #endif /*defined(_FEATURE_SIE)*/
1278 if (sysblk.cpus > 1)
1279 sched_yield();
1280 }
1281 else
1282 {
1283 ITIMER_UPDATE(addr2,4-1,regs);
1284 }
1285 }
1286
1287 /*-------------------------------------------------------------------*/
1288 /* BB CDS - Compare Double and Swap [RS] */
1289 /*-------------------------------------------------------------------*/
DEF_INST(compare_double_and_swap)1290 DEF_INST(compare_double_and_swap)
1291 {
1292 int r1, r3; /* Register numbers */
1293 int b2; /* effective address base */
1294 VADR addr2; /* effective address */
1295 BYTE *main2; /* mainstor address */
1296 U64 old, new; /* old, new values */
1297
1298 RS(inst, regs, r1, r3, b2, addr2);
1299
1300 ODD2_CHECK(r1, r3, regs);
1301
1302 DW_CHECK(addr2, regs);
1303
1304 ITIMER_SYNC(addr2,8-1,regs);
1305
1306 /* Perform serialization before starting operation */
1307 PERFORM_SERIALIZATION (regs);
1308
1309 /* Get operand absolute address */
1310 main2 = MADDRL (addr2, 8, b2, regs, ACCTYPE_WRITE, regs->psw.pkey);
1311
1312 /* Get old, new values */
1313 old = CSWAP64(((U64)(regs->GR_L(r1)) << 32) | regs->GR_L(r1+1));
1314 new = CSWAP64(((U64)(regs->GR_L(r3)) << 32) | regs->GR_L(r3+1));
1315
1316 /* Obtain main-storage access lock */
1317 OBTAIN_MAINLOCK(regs);
1318
1319 /* Attempt to exchange the values */
1320 regs->psw.cc = cmpxchg8 (&old, new, main2);
1321
1322 /* Release main-storage access lock */
1323 RELEASE_MAINLOCK(regs);
1324
1325 /* Perform serialization after completing operation */
1326 PERFORM_SERIALIZATION (regs);
1327
1328 if (regs->psw.cc == 1)
1329 {
1330 PTT(PTT_CL_CSF,"*CDS",regs->GR_L(r1),regs->GR_L(r3),(U32)(addr2 & 0xffffffff));
1331 regs->GR_L(r1) = CSWAP64(old) >> 32;
1332 regs->GR_L(r1+1) = CSWAP64(old) & 0xffffffff;
1333 #if defined(_FEATURE_SIE)
1334 if(SIE_STATB(regs, IC0, CS1))
1335 {
1336 if( !OPEN_IC_PER(regs) )
1337 longjmp(regs->progjmp, SIE_INTERCEPT_INST);
1338 else
1339 longjmp(regs->progjmp, SIE_INTERCEPT_INSTCOMP);
1340 }
1341 else
1342 #endif /*defined(_FEATURE_SIE)*/
1343 if (sysblk.cpus > 1)
1344 sched_yield();
1345 }
1346 else
1347 {
1348 ITIMER_UPDATE(addr2,8-1,regs);
1349 }
1350 }
1351
1352
1353 #if defined(FEATURE_COMPARE_AND_SWAP_AND_STORE)
1354
1355 #if defined(FEATURE_COMPARE_AND_SWAP_AND_STORE_FACILITY_2)
1356 #ifndef MAX_CSST_FC
1357 #define MAX_CSST_FC 2
1358 #endif /*#ifndef MAX_CSST_FC*/
1359 #ifndef MAX_CSST_SC
1360 #define MAX_CSST_SC 4
1361 #endif /*#ifndef MAX_CSST_SC*/
1362 #else
1363 #ifndef MAX_CSST_FC
1364 #define MAX_CSST_FC 1
1365 #endif /*#ifndef MAX_CSST_FC*/
1366 #ifndef MAX_CSST_SC
1367 #define MAX_CSST_SC 3
1368 #endif /*#ifndef MAX_CSST_SC*/
1369 #endif
1370
1371 /*-------------------------------------------------------------------*/
1372 /* C8x2 CSST - Compare and Swap and Store [SSF] */
1373 /*-------------------------------------------------------------------*/
DEF_INST(compare_and_swap_and_store)1374 DEF_INST(compare_and_swap_and_store)
1375 {
1376 int r3; /* Value of R3 field */
1377 int b1, b2; /* Base registers */
1378 const int rp=1; /* Parameter list register */
1379 VADR addr1, addr2; /* Effective addresses */
1380 VADR addrp; /* Parameter list address */
1381 BYTE *main1; /* Mainstor address of op1 */
1382 int ln2; /* Second operand length - 1 */
1383 #if defined(FEATURE_COMPARE_AND_SWAP_AND_STORE_FACILITY_2)
1384 U64 old16l=0, old16h=0,
1385 new16l=0, new16h=0, /* swap values for cmpxchg16 */
1386 stv16h=0,stv16l=0; /* 16-byte store value pair */
1387 #endif /*#if defined(FEATURE_COMPARE_AND_SWAP_AND_STORE_FACILITY_2)*/
1388 U64 old8=0, new8=0; /* Swap values for cmpxchg8 */
1389 U32 old4=0, new4=0; /* Swap values for cmpxchg4 */
1390 U64 stv8=0; /* 8-byte store value */
1391 U32 stv4=0; /* 4-byte store value */
1392 U16 stv2=0; /* 2-byte store value */
1393 BYTE stv1=0; /* 1-byte store value */
1394 BYTE fc; /* Function code */
1395 BYTE sc; /* Store characteristic */
1396
1397 SSF(inst, regs, b1, addr1, b2, addr2, r3);
1398
1399 /* Extract function code from register 0 bits 56-63 */
1400 fc = regs->GR_LHLCL(0);
1401
1402 /* Extract store characteristic from register 0 bits 48-55 */
1403 sc = regs->GR_LHLCH(0);
1404
1405 /* Program check if function code is not 0 or 1 */
1406 if (fc > MAX_CSST_FC)
1407 regs->program_interrupt (regs, PGM_SPECIFICATION_EXCEPTION);
1408
1409 /* Program check if store characteristic is not 0, 1, 2, or 3 */
1410 if (sc > MAX_CSST_SC)
1411 regs->program_interrupt (regs, PGM_SPECIFICATION_EXCEPTION);
1412
1413 /* Calculate length minus 1 of second operand */
1414 ln2 = (1 << sc) - 1;
1415
1416 /* Program check if first operand is not on correct boundary */
1417 switch(fc)
1418 {
1419 case 0:
1420 FW_CHECK(addr1, regs);
1421 break;
1422 case 1:
1423 DW_CHECK(addr1, regs);
1424 break;
1425 #if defined(FEATURE_COMPARE_AND_SWAP_AND_STORE_FACILITY_2)
1426 case 2:
1427 QW_CHECK(addr1, regs);
1428 break;
1429 #endif
1430 }
1431
1432 #if defined(FEATURE_COMPARE_AND_SWAP_AND_STORE_FACILITY_2)
1433 if((r3 & 1) && (fc == 2))
1434 {
1435 regs->program_interrupt (regs, PGM_SPECIFICATION_EXCEPTION);
1436 }
1437 #endif
1438
1439 /* Program check if second operand is not on correct boundary */
1440 switch(sc)
1441 {
1442 case 1:
1443 HW_CHECK(addr2, regs);
1444 break;
1445 case 2:
1446 FW_CHECK(addr2, regs);
1447 break;
1448 case 3:
1449 DW_CHECK(addr2, regs);
1450 break;
1451 #if defined(FEATURE_COMPARE_AND_SWAP_AND_STORE_FACILITY_2)
1452 case 4:
1453 QW_CHECK(addr2, regs);
1454 break;
1455 #endif
1456 }
1457
1458 /* Perform serialization before starting operation */
1459 PERFORM_SERIALIZATION (regs);
1460
1461 /* Obtain parameter list address from register 1 bits 0-59 */
1462 addrp = regs->GR(rp) & 0xFFFFFFFFFFFFFFF0ULL & ADDRESS_MAXWRAP(regs);
1463
1464 /* Obtain main storage address of first operand */
1465 main1 = MADDRL (addr1, 4, b1, regs, ACCTYPE_WRITE, regs->psw.pkey);
1466
1467 /* Ensure second operand storage is writable */
1468 ARCH_DEP(validate_operand) (addr2, b2, ln2, ACCTYPE_WRITE_SKP, regs);
1469
1470 /* Obtain main-storage access lock */
1471 OBTAIN_MAINLOCK(regs);
1472
1473 /* Load the compare value from the r3 register and also */
1474 /* load replacement value from bytes 0-3, 0-7 or 0-15 of parameter list */
1475 switch(fc)
1476 {
1477 case 0:
1478 old4 = CSWAP32(regs->GR_L(r3));
1479 new4 = ARCH_DEP(vfetch4) (addrp, rp, regs);
1480 new4 = CSWAP32(new4);
1481 break;
1482 case 1:
1483 old8 = CSWAP64(regs->GR_G(r3));
1484 new8 = ARCH_DEP(vfetch8) (addrp, rp, regs);
1485 new8 = CSWAP64(new8);
1486 break;
1487 #if defined(FEATURE_COMPARE_AND_SWAP_AND_STORE_FACILITY_2)
1488 case 2:
1489 old16h = CSWAP64(regs->GR_G(r3));
1490 old16l = CSWAP64(regs->GR_G(r3+1));
1491 new16h = ARCH_DEP(vfetch8) (addrp, rp, regs);
1492 new16l = ARCH_DEP(vfetch8) (addrp+8, rp, regs);
1493 new16h = CSWAP64(new16h);
1494 new16l = CSWAP64(new16l);
1495 break;
1496 #endif
1497 }
1498
1499 /* Load the store value from bytes 16-23 of parameter list */
1500 addrp += 16;
1501 addrp = addrp & ADDRESS_MAXWRAP(regs);
1502
1503 switch(sc)
1504 {
1505 case 0:
1506 stv1 = ARCH_DEP(vfetchb) (addrp, rp, regs);
1507 break;
1508 case 1:
1509 stv2 = ARCH_DEP(vfetch2) (addrp, rp, regs);
1510 break;
1511 case 2:
1512 stv4 = ARCH_DEP(vfetch4) (addrp, rp, regs);
1513 break;
1514 case 3:
1515 stv8 = ARCH_DEP(vfetch8) (addrp, rp, regs);
1516 break;
1517 #if defined(FEATURE_COMPARE_AND_SWAP_AND_STORE_FACILITY_2)
1518 case 4:
1519 stv16h = ARCH_DEP(vfetch8) (addrp, rp, regs);
1520 stv16l = ARCH_DEP(vfetch8) (addrp+8, rp, regs);
1521 break;
1522 #endif
1523 }
1524
1525 switch(fc)
1526 {
1527 case 0:
1528 regs->psw.cc = cmpxchg4 (&old4, new4, main1);
1529 break;
1530 case 1:
1531 regs->psw.cc = cmpxchg8 (&old8, new8, main1);
1532 break;
1533 #if defined(FEATURE_COMPARE_AND_SWAP_AND_STORE_FACILITY_2)
1534 case 2:
1535 regs->psw.cc = cmpxchg16 (&old16h, &old16l, new16h, new16l, main1);
1536 break;
1537 #endif
1538 }
1539 if (regs->psw.cc == 0)
1540 {
1541 /* Store the store value into the second operand location */
1542 switch(sc)
1543 {
1544 case 0:
1545 ARCH_DEP(vstoreb) (stv1, addr2, b2, regs);
1546 break;
1547 case 1:
1548 ARCH_DEP(vstore2) (stv2, addr2, b2, regs);
1549 break;
1550 case 2:
1551 ARCH_DEP(vstore4) (stv4, addr2, b2, regs);
1552 break;
1553 case 3:
1554 ARCH_DEP(vstore8) (stv8, addr2, b2, regs);
1555 break;
1556 #if defined(FEATURE_COMPARE_AND_SWAP_AND_STORE_FACILITY_2)
1557 case 4:
1558 ARCH_DEP(vstore8) (stv16h, addr2, b2, regs);
1559 ARCH_DEP(vstore8) (stv16l, addr2+8, b2, regs);
1560 break;
1561 #endif
1562 }
1563 }
1564 else
1565 {
1566 switch(fc)
1567 {
1568 case 0:
1569 regs->GR_L(r3) = CSWAP32(old4);
1570 break;
1571 case 1:
1572 regs->GR_G(r3) = CSWAP64(old8);
1573 break;
1574 #if defined(FEATURE_COMPARE_AND_SWAP_AND_STORE_FACILITY_2)
1575 case 2:
1576 regs->GR_G(r3) = CSWAP64(old16h);
1577 regs->GR_G(r3+1) = CSWAP64(old16l);
1578 break;
1579 #endif
1580 }
1581 }
1582
1583 /* Release main-storage access lock */
1584 RELEASE_MAINLOCK(regs);
1585
1586 /* Perform serialization after completing operation */
1587 PERFORM_SERIALIZATION (regs);
1588
1589 } /* end DEF_INST(compare_and_swap_and_store) */
1590 #endif /*defined(FEATURE_COMPARE_AND_SWAP_AND_STORE)*/
1591
1592
1593 /*-------------------------------------------------------------------*/
1594 /* 49 CH - Compare Halfword [RX] */
1595 /*-------------------------------------------------------------------*/
DEF_INST(compare_halfword)1596 DEF_INST(compare_halfword)
1597 {
1598 int r1; /* Values of R fields */
1599 int b2; /* Base of effective addr */
1600 VADR effective_addr2; /* Effective address */
1601 S32 n; /* 32-bit operand values */
1602
1603 RX(inst, regs, r1, b2, effective_addr2);
1604
1605 /* Load rightmost 2 bytes of comparand from operand address */
1606 n = (S16)ARCH_DEP(vfetch2) ( effective_addr2, b2, regs );
1607
1608 /* Compare signed operands and set condition code */
1609 regs->psw.cc =
1610 (S32)regs->GR_L(r1) < n ? 1 :
1611 (S32)regs->GR_L(r1) > n ? 2 : 0;
1612 }
1613
1614
1615 #if defined(FEATURE_IMMEDIATE_AND_RELATIVE)
1616 /*-------------------------------------------------------------------*/
1617 /* A7xE CHI - Compare Halfword Immediate [RI] */
1618 /*-------------------------------------------------------------------*/
DEF_INST(compare_halfword_immediate)1619 DEF_INST(compare_halfword_immediate)
1620 {
1621 int r1; /* Register number */
1622 U16 i2; /* 16-bit operand */
1623
1624 RI0(inst, regs, r1, i2);
1625
1626 /* Compare signed operands and set condition code */
1627 regs->psw.cc =
1628 (S32)regs->GR_L(r1) < (S16)i2 ? 1 :
1629 (S32)regs->GR_L(r1) > (S16)i2 ? 2 : 0;
1630
1631 }
1632 #endif /*defined(FEATURE_IMMEDIATE_AND_RELATIVE)*/
1633
1634
1635 /*-------------------------------------------------------------------*/
1636 /* 15 CLR - Compare Logical Register [RR] */
1637 /*-------------------------------------------------------------------*/
DEF_INST(compare_logical_register)1638 DEF_INST(compare_logical_register)
1639 {
1640 int r1, r2; /* Values of R fields */
1641
1642 RR0(inst, regs, r1, r2);
1643
1644 /* Compare unsigned operands and set condition code */
1645 regs->psw.cc = regs->GR_L(r1) < regs->GR_L(r2) ? 1 :
1646 regs->GR_L(r1) > regs->GR_L(r2) ? 2 : 0;
1647 }
1648
1649
1650 /*-------------------------------------------------------------------*/
1651 /* 55 CL - Compare Logical [RX] */
1652 /*-------------------------------------------------------------------*/
DEF_INST(compare_logical)1653 DEF_INST(compare_logical)
1654 {
1655 int r1; /* Values of R fields */
1656 int b2; /* Base of effective addr */
1657 VADR effective_addr2; /* Effective address */
1658 U32 n; /* 32-bit operand values */
1659
1660 RX(inst, regs, r1, b2, effective_addr2);
1661
1662 /* Load second operand from operand address */
1663 n = ARCH_DEP(vfetch4) ( effective_addr2, b2, regs );
1664
1665 /* Compare unsigned operands and set condition code */
1666 regs->psw.cc = regs->GR_L(r1) < n ? 1 :
1667 regs->GR_L(r1) > n ? 2 : 0;
1668 }
1669
1670
1671 /*-------------------------------------------------------------------*/
1672 /* 95 CLI - Compare Logical Immediate [SI] */
1673 /*-------------------------------------------------------------------*/
DEF_INST(compare_logical_immediate)1674 DEF_INST(compare_logical_immediate)
1675 {
1676 BYTE i2; /* Immediate byte */
1677 int b1; /* Base of effective addr */
1678 VADR effective_addr1; /* Effective address */
1679 BYTE cbyte; /* Compare byte */
1680
1681 SI(inst, regs, i2, b1, effective_addr1);
1682
1683 /* Fetch byte from operand address */
1684 cbyte = ARCH_DEP(vfetchb) ( effective_addr1, b1, regs );
1685
1686 /* Compare with immediate operand and set condition code */
1687 regs->psw.cc = (cbyte < i2) ? 1 :
1688 (cbyte > i2) ? 2 : 0;
1689 }
1690
1691
1692 /*-------------------------------------------------------------------*/
1693 /* D5 CLC - Compare Logical Character [SS] */
1694 /*-------------------------------------------------------------------*/
DEF_INST(compare_logical_character)1695 DEF_INST(compare_logical_character)
1696 {
1697 unsigned int len, len1, len2; /* Lengths */
1698 int rc; /* memcmp() return code */
1699 int b1, b2; /* Base registers */
1700 VADR ea1, ea2; /* Effective addresses */
1701 BYTE *m1, *m2; /* Mainstor addresses */
1702
1703 SS_L(inst, regs, len, b1, ea1, b2, ea2);
1704
1705 ITIMER_SYNC(ea1,len,regs);
1706 ITIMER_SYNC(ea2,len,regs);
1707
1708 /* Translate addresses of leftmost operand bytes */
1709 m1 = MADDR (ea1, b1, regs, ACCTYPE_READ, regs->psw.pkey);
1710 m2 = MADDR (ea2, b2, regs, ACCTYPE_READ, regs->psw.pkey);
1711
1712 /* Quick out if comparing just 1 byte */
1713 if (unlikely(len == 0))
1714 {
1715 rc = *m1 - *m2;
1716 regs->psw.cc = ( rc == 0 ? 0 : ( rc < 0 ? 1 : 2 ) );
1717 return;
1718 }
1719
1720 /* There are several scenarios (in optimal order):
1721 * (1) dest boundary and source boundary not crossed
1722 * (a) halfword compare
1723 * (b) fullword compare
1724 * (c) doubleword compare (64-bit machines)
1725 * (d) other
1726 * (2) dest boundary not crossed and source boundary crossed
1727 * (3) dest boundary crossed and source boundary not crossed
1728 * (4) dest boundary and source boundary are crossed
1729 * (a) dest and source boundary cross at the same time
1730 * (b) dest boundary crossed first
1731 * (c) source boundary crossed first
1732 */
1733
1734 if ( (ea1 & 0x7FF) <= 0x7FF - len )
1735 {
1736 if ( (ea2 & 0x7FF) <= 0x7FF - len )
1737 {
1738 /* (1) - No boundaries are crossed */
1739 switch(len) {
1740
1741 case 1:
1742 /* (1a) - halfword compare */
1743 {
1744 U16 v1, v2;
1745 v1 = fetch_hw(m1);
1746 v2 = fetch_hw(m2);
1747 regs->psw.cc = ( v1 == v2 ? 0 : ( v1 < v2 ? 1 : 2 ) );
1748 return;
1749 }
1750 break;
1751
1752 case 3:
1753 /* (1b) - fullword compare */
1754 {
1755 U32 v1, v2;
1756 v1 = fetch_fw(m1);
1757 v2 = fetch_fw(m2);
1758 regs->psw.cc = ( v1 == v2 ? 0 : ( v1 < v2 ? 1 : 2 ) );
1759 return;
1760 }
1761 break;
1762
1763 case 7:
1764 /* (1c) - doubleword compare (64-bit machines) */
1765 if (sizeof(unsigned int) >= 8)
1766 {
1767 U64 v1, v2;
1768 v1 = fetch_dw(m1);
1769 v2 = fetch_dw(m2);
1770 regs->psw.cc = ( v1 == v2 ? 0 : ( v1 < v2 ? 1 : 2 ) );
1771 return;
1772 }
1773
1774 default:
1775 /* (1d) - other compare */
1776 rc = memcmp(m1, m2, len + 1);
1777 break;
1778 }
1779 }
1780 else
1781 {
1782 /* (2) - Second operand crosses a boundary */
1783 len2 = 0x800 - (ea2 & 0x7FF);
1784 rc = memcmp(m1, m2, len2);
1785 if (rc == 0)
1786 {
1787 m2 = MADDR ((ea2 + len2) & ADDRESS_MAXWRAP(regs),
1788 b2, regs, ACCTYPE_READ, regs->psw.pkey);
1789 rc = memcmp(m1 + len2, m2, len - len2 + 1);
1790 }
1791 }
1792 }
1793 else
1794 {
1795 /* First operand crosses a boundary */
1796 len1 = 0x800 - (ea1 & 0x7FF);
1797 if ( (ea2 & 0x7FF) <= 0x7FF - len )
1798 {
1799 /* (3) - First operand crosses a boundary */
1800 rc = memcmp(m1, m2, len1);
1801 if (rc == 0)
1802 {
1803 m1 = MADDR ((ea1 + len1) & ADDRESS_MAXWRAP(regs),
1804 b1, regs, ACCTYPE_READ, regs->psw.pkey);
1805 rc = memcmp(m1, m2 + len1, len - len1 + 1);
1806 }
1807 }
1808 else
1809 {
1810 /* (4) - Both operands cross a boundary */
1811 len2 = 0x800 - (ea2 & 0x7FF);
1812 if (len1 == len2)
1813 {
1814 /* (4a) - Both operands cross at the same time */
1815 rc = memcmp(m1, m2, len1);
1816 if (rc == 0)
1817 {
1818 m1 = MADDR ((ea1 + len1) & ADDRESS_MAXWRAP(regs),
1819 b1, regs, ACCTYPE_READ, regs->psw.pkey);
1820 m2 = MADDR ((ea2 + len1) & ADDRESS_MAXWRAP(regs),
1821 b2, regs, ACCTYPE_READ, regs->psw.pkey);
1822 rc = memcmp(m1, m2, len - len1 +1);
1823 }
1824 }
1825 else if (len1 < len2)
1826 {
1827 /* (4b) - First operand crosses first */
1828 rc = memcmp(m1, m2, len1);
1829 if (rc == 0)
1830 {
1831 m1 = MADDR ((ea1 + len1) & ADDRESS_MAXWRAP(regs),
1832 b1, regs, ACCTYPE_READ, regs->psw.pkey);
1833 rc = memcmp (m1, m2 + len1, len2 - len1);
1834 }
1835 if (rc == 0)
1836 {
1837 m2 = MADDR ((ea2 + len2) & ADDRESS_MAXWRAP(regs),
1838 b2, regs, ACCTYPE_READ, regs->psw.pkey);
1839 rc = memcmp (m1 + len2 - len1, m2, len - len2 + 1);
1840 }
1841 }
1842 else
1843 {
1844 /* (4c) - Second operand crosses first */
1845 rc = memcmp(m1, m2, len2);
1846 if (rc == 0)
1847 {
1848 m2 = MADDR ((ea2 + len2) & ADDRESS_MAXWRAP(regs),
1849 b2, regs, ACCTYPE_READ, regs->psw.pkey);
1850 rc = memcmp (m1 + len2, m2, len1 - len2);
1851 }
1852 if (rc == 0)
1853 {
1854 m1 = MADDR ((ea1 + len1) & ADDRESS_MAXWRAP(regs),
1855 b1, regs, ACCTYPE_READ, regs->psw.pkey);
1856 rc = memcmp (m1, m2 + len1 - len2, len - len1 + 1);
1857 }
1858 }
1859 }
1860 }
1861 regs->psw.cc = ( rc == 0 ? 0 : ( rc < 0 ? 1 : 2 ) );
1862 }
1863
1864
1865 /*-------------------------------------------------------------------*/
1866 /* BD CLM - Compare Logical Characters under Mask [RS] */
1867 /*-------------------------------------------------------------------*/
DEF_INST(compare_logical_characters_under_mask)1868 DEF_INST(compare_logical_characters_under_mask)
1869 {
1870 int r1, r3; /* Register numbers */
1871 int b2; /* effective address base */
1872 VADR effective_addr2; /* effective address */
1873 int i, j; /* Integer work areas */
1874 int cc = 0; /* Condition code */
1875 BYTE rbyte[4], /* Register bytes */
1876 vbyte; /* Virtual storage byte */
1877
1878 RS(inst, regs, r1, r3, b2, effective_addr2);
1879
1880 /* Set register bytes by mask */
1881 i = 0;
1882 if (r3 & 0x8) rbyte[i++] = (regs->GR_L(r1) >> 24) & 0xFF;
1883 if (r3 & 0x4) rbyte[i++] = (regs->GR_L(r1) >> 16) & 0xFF;
1884 if (r3 & 0x2) rbyte[i++] = (regs->GR_L(r1) >> 8) & 0xFF;
1885 if (r3 & 0x1) rbyte[i++] = (regs->GR_L(r1) ) & 0xFF;
1886
1887 /* Perform access check if mask is 0 */
1888 if (!r3) ARCH_DEP(vfetchb) (effective_addr2, b2, regs);
1889
1890 /* Compare byte by byte */
1891 for (j = 0; j < i && !cc; j++)
1892 {
1893 effective_addr2 &= ADDRESS_MAXWRAP(regs);
1894 vbyte = ARCH_DEP(vfetchb) (effective_addr2++, b2, regs);
1895 if (rbyte[j] != vbyte)
1896 cc = rbyte[j] < vbyte ? 1 : 2;
1897 }
1898
1899 regs->psw.cc = cc;
1900
1901 }
1902
1903
1904 /*-------------------------------------------------------------------*/
1905 /* 0F CLCL - Compare Logical Long [RR] */
1906 /*-------------------------------------------------------------------*/
DEF_INST(compare_logical_character_long)1907 DEF_INST(compare_logical_character_long)
1908 {
1909 int r1, r2; /* Values of R fields */
1910 int cc = 0; /* Condition code */
1911 VADR addr1, addr2; /* Operand addresses */
1912 U32 len1, len2; /* Operand lengths */
1913 BYTE byte1, byte2; /* Operand bytes */
1914 BYTE pad; /* Padding byte */
1915
1916 RR(inst, regs, r1, r2);
1917
1918 ODD2_CHECK(r1, r2, regs);
1919
1920 /* Determine the destination and source addresses */
1921 addr1 = regs->GR(r1) & ADDRESS_MAXWRAP(regs);
1922 addr2 = regs->GR(r2) & ADDRESS_MAXWRAP(regs);
1923
1924 /* Load padding byte from bits 0-7 of R2+1 register */
1925 pad = regs->GR_LHHCH(r2+1);
1926
1927 /* Load operand lengths from bits 8-31 of R1+1 and R2+1 */
1928 len1 = regs->GR_LA24(r1+1);
1929 len2 = regs->GR_LA24(r2+1);
1930
1931 /* Process operands from left to right */
1932 while (len1 > 0 || len2 > 0)
1933 {
1934 /* Fetch a byte from each operand, or use padding byte */
1935 byte1 = (len1 > 0) ? ARCH_DEP(vfetchb) (addr1, r1, regs) : pad;
1936 byte2 = (len2 > 0) ? ARCH_DEP(vfetchb) (addr2, r2, regs) : pad;
1937
1938 /* Compare operand bytes, set condition code if unequal */
1939 if (byte1 != byte2)
1940 {
1941 cc = (byte1 < byte2) ? 1 : 2;
1942 break;
1943 } /* end if */
1944
1945 /* Update the first operand address and length */
1946 if (len1 > 0)
1947 {
1948 addr1++;
1949 addr1 &= ADDRESS_MAXWRAP(regs);
1950 len1--;
1951 }
1952
1953 /* Update the second operand address and length */
1954 if (len2 > 0)
1955 {
1956 addr2++;
1957 addr2 &= ADDRESS_MAXWRAP(regs);
1958 len2--;
1959 }
1960
1961 /* Update Regs if cross half page - may get access rupt */
1962 if ((addr1 & 0x7ff) == 0 || (addr2 & 0x7ff) == 0)
1963 {
1964 SET_GR_A(r1, regs, addr1);
1965 SET_GR_A(r2, regs, addr2);
1966
1967 regs->GR_LA24(r1+1) = len1;
1968 regs->GR_LA24(r2+1) = len2;
1969 }
1970
1971 /* The instruction can be interrupted when a CPU determined
1972 number of bytes have been processed. The instruction
1973 address will be backed up, and the instruction will
1974 be re-executed. This is consistent with operation
1975 under a hypervisor such as LPAR or VM. *JJ */
1976 if ((len1 + len2 > 255) && !((addr1 - len2) & 0xFFF))
1977 {
1978 UPD_PSW_IA (regs, PSW_IA(regs, -REAL_ILC(regs)));
1979 break;
1980 }
1981
1982 } /* end while(len1||len2) */
1983
1984 /* Update the registers */
1985 SET_GR_A(r1, regs,addr1);
1986 SET_GR_A(r2, regs,addr2);
1987
1988 regs->GR_LA24(r1+1) = len1;
1989 regs->GR_LA24(r2+1) = len2;
1990
1991 regs->psw.cc = cc;
1992
1993 }
1994
1995
1996 #if defined(FEATURE_COMPARE_AND_MOVE_EXTENDED)
1997 /*-------------------------------------------------------------------*/
1998 /* A9 CLCLE - Compare Logical Long Extended [RS] */
1999 /*-------------------------------------------------------------------*/
DEF_INST(compare_logical_long_extended)2000 DEF_INST(compare_logical_long_extended)
2001 {
2002 int r1, r3; /* Register numbers */
2003 int b2; /* effective address base */
2004 VADR effective_addr2; /* effective address */
2005 int i; /* Loop counter */
2006 int cc = 0; /* Condition code */
2007 VADR addr1, addr2; /* Operand addresses */
2008 GREG len1, len2; /* Operand lengths */
2009 BYTE byte1, byte2; /* Operand bytes */
2010 BYTE pad; /* Padding byte */
2011
2012 RS(inst, regs, r1, r3, b2, effective_addr2);
2013
2014 ODD2_CHECK(r1, r3, regs);
2015
2016 /* Load padding byte from bits 24-31 of effective address */
2017 pad = effective_addr2 & 0xFF;
2018
2019 /* Determine the destination and source addresses */
2020 addr1 = regs->GR(r1) & ADDRESS_MAXWRAP(regs);
2021 addr2 = regs->GR(r3) & ADDRESS_MAXWRAP(regs);
2022
2023 /* Load operand lengths from bits 0-31 of R1+1 and R3+1 */
2024 len1 = GR_A(r1+1, regs);
2025 len2 = GR_A(r3+1, regs);
2026
2027 /* Process operands from left to right */
2028 for (i = 0; len1 > 0 || len2 > 0 ; i++)
2029 {
2030 /* If 4096 bytes have been compared, exit with cc=3 */
2031 if (i >= 4096)
2032 {
2033 cc = 3;
2034 break;
2035 }
2036
2037 /* Fetch a byte from each operand, or use padding byte */
2038 byte1 = (len1 > 0) ? ARCH_DEP(vfetchb) (addr1, r1, regs) : pad;
2039 byte2 = (len2 > 0) ? ARCH_DEP(vfetchb) (addr2, r3, regs) : pad;
2040
2041 /* Compare operand bytes, set condition code if unequal */
2042 if (byte1 != byte2)
2043 {
2044 cc = (byte1 < byte2) ? 1 : 2;
2045 break;
2046 } /* end if */
2047
2048 /* Update the first operand address and length */
2049 if (len1 > 0)
2050 {
2051 addr1++;
2052 addr1 &= ADDRESS_MAXWRAP(regs);
2053 len1--;
2054 }
2055
2056 /* Update the second operand address and length */
2057 if (len2 > 0)
2058 {
2059 addr2++;
2060 addr2 &= ADDRESS_MAXWRAP(regs);
2061 len2--;
2062 }
2063
2064 } /* end for(i) */
2065
2066 /* Update the registers */
2067 SET_GR_A(r1, regs,addr1);
2068 SET_GR_A(r1+1, regs,len1);
2069 SET_GR_A(r3, regs,addr2);
2070 SET_GR_A(r3+1, regs,len2);
2071
2072 regs->psw.cc = cc;
2073
2074 }
2075 #endif /*defined(FEATURE_COMPARE_AND_MOVE_EXTENDED)*/
2076
2077
2078 #if defined(FEATURE_STRING_INSTRUCTION)
2079 /*-------------------------------------------------------------------*/
2080 /* B25D CLST - Compare Logical String [RRE] */
2081 /*-------------------------------------------------------------------*/
DEF_INST(compare_logical_string)2082 DEF_INST(compare_logical_string)
2083 {
2084 int r1, r2; /* Values of R fields */
2085 int i; /* Loop counter */
2086 int cc; /* Condition code */
2087 VADR addr1, addr2; /* Operand addresses */
2088 BYTE byte1, byte2; /* Operand bytes */
2089 BYTE termchar; /* Terminating character */
2090
2091 RRE(inst, regs, r1, r2);
2092
2093 /* Program check if bits 0-23 of register 0 not zero */
2094 if ((regs->GR_L(0) & 0xFFFFFF00) != 0)
2095 regs->program_interrupt (regs, PGM_SPECIFICATION_EXCEPTION);
2096
2097 /* Load string terminating character from register 0 bits 24-31 */
2098 termchar = regs->GR_LHLCL(0);
2099
2100 /* Determine the operand addresses */
2101 addr1 = regs->GR(r1) & ADDRESS_MAXWRAP(regs);
2102 addr2 = regs->GR(r2) & ADDRESS_MAXWRAP(regs);
2103
2104 /* Initialize the condition code to 3 */
2105 cc = 3;
2106
2107 /* Compare up to 4096 bytes until terminating character */
2108 for (i = 0; i < 4096; i++)
2109 {
2110 /* Fetch a byte from each operand */
2111 byte1 = ARCH_DEP(vfetchb) ( addr1, r1, regs );
2112 byte2 = ARCH_DEP(vfetchb) ( addr2, r2, regs );
2113
2114 /* If both bytes are the terminating character then the
2115 strings are equal so return condition code 0
2116 and leave the R1 and R2 registers unchanged */
2117 if (byte1 == termchar && byte2 == termchar)
2118 {
2119 regs->psw.cc = 0;
2120 return;
2121 }
2122
2123 /* If first operand byte is the terminating character,
2124 or if the first operand byte is lower than the
2125 second operand byte, then return condition code 1 */
2126 if (byte1 == termchar || ((byte1 < byte2) && (byte2 != termchar)))
2127 {
2128 cc = 1;
2129 break;
2130 }
2131
2132 /* If second operand byte is the terminating character,
2133 or if the first operand byte is higher than the
2134 second operand byte, then return condition code 2 */
2135 if (byte2 == termchar || byte1 > byte2)
2136 {
2137 cc = 2;
2138 break;
2139 }
2140
2141 /* Increment operand addresses */
2142 addr1++;
2143 addr1 &= ADDRESS_MAXWRAP(regs);
2144 addr2++;
2145 addr2 &= ADDRESS_MAXWRAP(regs);
2146
2147 } /* end for(i) */
2148
2149 /* Set R1 and R2 to point to current character of each operand */
2150 SET_GR_A(r1, regs,addr1);
2151 SET_GR_A(r2, regs,addr2);
2152
2153 /* Set condition code */
2154 regs->psw.cc = cc;
2155
2156 } /* end DEF_INST(compare_logical_string) */
2157 #endif /*defined(FEATURE_STRING_INSTRUCTION)*/
2158
2159
2160 #if defined(FEATURE_STRING_INSTRUCTION)
2161 /*-------------------------------------------------------------------*/
2162 /* B257 CUSE - Compare Until Substring Equal [RRE] */
2163 /*-------------------------------------------------------------------*/
DEF_INST(compare_until_substring_equal)2164 DEF_INST(compare_until_substring_equal)
2165 {
2166 int r1, r2; /* Values of R fields */
2167 int i; /* Loop counter */
2168 int cc = 0; /* Condition code */
2169 VADR addr1, addr2; /* Operand addresses */
2170 BYTE byte1, byte2; /* Operand bytes */
2171 BYTE pad; /* Padding byte */
2172 BYTE sublen; /* Substring length */
2173 BYTE equlen = 0; /* Equal byte counter */
2174 VADR eqaddr1, eqaddr2; /* Address of equal substring*/
2175 #if defined(FEATURE_ESAME)
2176 S64 len1, len2; /* Operand lengths */
2177 S64 remlen1, remlen2; /* Lengths remaining */
2178 #else /*!defined(FEATURE_ESAME)*/
2179 S32 len1, len2; /* Operand lengths */
2180 S32 remlen1, remlen2; /* Lengths remaining */
2181 #endif /*!defined(FEATURE_ESAME)*/
2182
2183 RRE(inst, regs, r1, r2);
2184
2185 ODD2_CHECK(r1, r2, regs);
2186
2187 /* Load substring length from bits 24-31 of register 0 */
2188 sublen = regs->GR_LHLCL(0);
2189
2190 /* Load padding byte from bits 24-31 of register 1 */
2191 pad = regs->GR_LHLCL(1);
2192
2193 /* Determine the destination and source addresses */
2194 addr1 = regs->GR(r1) & ADDRESS_MAXWRAP(regs);
2195 addr2 = regs->GR(r2) & ADDRESS_MAXWRAP(regs);
2196
2197 /* update regs so unused bits zeroed */
2198 SET_GR_A(r1, regs,addr1);
2199 SET_GR_A(r2, regs,addr2);
2200
2201 /* Load signed operand lengths from R1+1 and R2+1 */
2202 len1 =
2203 #if defined(FEATURE_ESAME)
2204 regs->psw.amode64 ? (S64)(regs->GR_G(r1+1)) :
2205 #endif /*defined(FEATURE_ESAME)*/
2206 (S32)(regs->GR_L(r1+1));
2207 len2 =
2208 #if defined(FEATURE_ESAME)
2209 regs->psw.amode64 ? (S64)(regs->GR_G(r2+1)) :
2210 #endif /*defined(FEATURE_ESAME)*/
2211 (S32)(regs->GR_L(r2+1));
2212
2213 /* Initialize equal string addresses and lengths */
2214 eqaddr1 = addr1;
2215 eqaddr2 = addr2;
2216 remlen1 = len1;
2217 remlen2 = len2;
2218
2219 /* If substring length is zero, exit with condition code 0 */
2220 if (sublen == 0)
2221 {
2222 regs->psw.cc = 0;
2223 return;
2224 }
2225
2226 /* If both operand lengths are zero, exit with condition code 2 */
2227 if (len1 <= 0 && len2 <= 0)
2228 {
2229 regs->psw.cc = 2;
2230 return;
2231 }
2232
2233 /* If r1=r2, exit with condition code 0 or 1*/
2234 if (r1 == r2)
2235 {
2236 regs->psw.cc = (len1 < sublen) ? 1 : 0;
2237 return;
2238 }
2239
2240 /* Process operands from left to right */
2241 for (i = 0; len1 > 0 || len2 > 0 ; i++)
2242 {
2243
2244 /* If 4096 bytes have been compared, and the last bytes
2245 compared were unequal, exit with condition code 3 */
2246 if (equlen == 0 && i >= 4096)
2247 {
2248 cc = 3;
2249 break;
2250 }
2251
2252 /* Fetch byte from first operand, or use padding byte */
2253 if (len1 > 0)
2254 byte1 = ARCH_DEP(vfetchb) ( addr1, r1, regs );
2255 else
2256 byte1 = pad;
2257
2258 /* Fetch byte from second operand, or use padding byte */
2259 if (len2 > 0)
2260 byte2 = ARCH_DEP(vfetchb) ( addr2, r2, regs );
2261 else
2262 byte2 = pad;
2263
2264 /* Test if bytes compare equal */
2265 if (byte1 == byte2)
2266 {
2267 /* If this is the first equal byte, save the start of
2268 substring addresses and remaining lengths */
2269 if (equlen == 0)
2270 {
2271 eqaddr1 = addr1;
2272 eqaddr2 = addr2;
2273 remlen1 = len1;
2274 remlen2 = len2;
2275 }
2276
2277 /* Count the number of equal bytes */
2278 equlen++;
2279
2280 /* Set condition code 1 */
2281 cc = 1;
2282 }
2283 else
2284 {
2285 /* Reset equal byte count and set condition code 2 */
2286 equlen = 0;
2287 cc = 2;
2288 }
2289
2290 /* Update the first operand address and length */
2291 if (len1 > 0)
2292 {
2293 addr1++;
2294 addr1 &= ADDRESS_MAXWRAP(regs);
2295 len1--;
2296 }
2297
2298 /* Update the second operand address and length */
2299 if (len2 > 0)
2300 {
2301 addr2++;
2302 addr2 &= ADDRESS_MAXWRAP(regs);
2303 len2--;
2304 }
2305
2306
2307 /* update GPRs if we just crossed half page - could get rupt */
2308 if ((addr1 & 0x7FF) == 0 || (addr2 & 0x7FF) == 0)
2309 {
2310 /* Update R1 and R2 to point to next bytes to compare */
2311 SET_GR_A(r1, regs,addr1);
2312 SET_GR_A(r2, regs,addr2);
2313
2314 /* Set R1+1 and R2+1 to remaining operand lengths */
2315 SET_GR_A(r1+1, regs,len1);
2316 SET_GR_A(r2+1, regs,len2);
2317 }
2318
2319 /* If equal byte count has reached substring length
2320 exit with condition code zero */
2321 if (equlen == sublen)
2322 {
2323 cc = 0;
2324 break;
2325 }
2326
2327 } /* end for(i) */
2328
2329 /* Update the registers */
2330 if (cc < 2)
2331 {
2332 /* Update R1 and R2 to point to the equal substring */
2333 SET_GR_A(r1, regs,eqaddr1);
2334 SET_GR_A(r2, regs,eqaddr2);
2335
2336 /* Set R1+1 and R2+1 to length remaining in each
2337 operand after the start of the substring */
2338 SET_GR_A(r1+1, regs,remlen1);
2339 SET_GR_A(r2+1, regs,remlen2);
2340 }
2341 else
2342 {
2343 /* Update R1 and R2 to point to next bytes to compare */
2344 SET_GR_A(r1, regs,addr1);
2345 SET_GR_A(r2, regs,addr2);
2346
2347 /* Set R1+1 and R2+1 to remaining operand lengths */
2348 SET_GR_A(r1+1, regs,len1);
2349 SET_GR_A(r2+1, regs,len2);
2350 }
2351
2352 /* Set condition code */
2353 regs->psw.cc = cc;
2354
2355 } /* end DEF_INST(compare_until_substring_equal) */
2356 #endif /*defined(FEATURE_STRING_INSTRUCTION)*/
2357
2358
2359 #ifdef FEATURE_EXTENDED_TRANSLATION
2360 /*-------------------------------------------------------------------*/
2361 /* B2A6 CU21 (CUUTF) - Convert Unicode to UTF-8 [RRF] */
2362 /*-------------------------------------------------------------------*/
DEF_INST(convert_utf16_to_utf8)2363 DEF_INST(convert_utf16_to_utf8)
2364 {
2365 int r1, r2; /* Register numbers */
2366 int i; /* Loop counter */
2367 int cc = 0; /* Condition code */
2368 VADR addr1, addr2; /* Operand addresses */
2369 GREG len1, len2; /* Operand lengths */
2370 VADR naddr2; /* Next operand 2 addr */
2371 GREG nlen2; /* Next operand 2 length */
2372 U16 uvwxy; /* Unicode work area */
2373 U16 unicode1; /* Unicode character */
2374 U16 unicode2; /* Unicode low surrogate */
2375 GREG n; /* Number of UTF-8 bytes - 1 */
2376 BYTE utf[4]; /* UTF-8 bytes */
2377 #if defined(FEATURE_ETF3_ENHANCEMENT)
2378 int wfc; /* Well-Formedness-Checking */
2379 #endif /*defined(FEATURE_ETF3_ENHANCEMENT)*/
2380
2381 // NOTE: it's faster to decode with RRE format
2382 // and then to handle the 'wfc' flag separately...
2383
2384 // RRF_M(inst, regs, r1, r2, wfc);
2385 RRE(inst, regs, r1, r2);
2386
2387 ODD2_CHECK(r1, r2, regs);
2388
2389 #if defined(FEATURE_ETF3_ENHANCEMENT)
2390 /* Set WellFormednessChecking */
2391 if(inst[2] & 0x10)
2392 wfc = 1;
2393 else
2394 wfc = 0;
2395 #endif /*defined(FEATURE_ETF3_ENHANCEMENT)*/
2396
2397 /* Determine the destination and source addresses */
2398 addr1 = regs->GR(r1) & ADDRESS_MAXWRAP(regs);
2399 addr2 = regs->GR(r2) & ADDRESS_MAXWRAP(regs);
2400
2401 /* Load operand lengths from bits 0-31 of R1+1 and R2+1 */
2402 len1 = GR_A(r1+1, regs);
2403 len2 = GR_A(r2+1, regs);
2404
2405 if (len1 == 0 && len2 > 1)
2406 cc = 1;
2407
2408 /* Process operands from left to right */
2409 for (i = 0; len1 > 0 && len2 > 0; i++)
2410 {
2411 /* If 4096 characters have been converted, exit with cc=3 */
2412 if (i >= 4096)
2413 {
2414 cc = 3;
2415 break;
2416 }
2417
2418 /* Exit if fewer than 2 bytes remain in source operand */
2419 if (len2 < 2) break;
2420
2421 /* Fetch two bytes from source operand */
2422 unicode1 = ARCH_DEP(vfetch2) ( addr2, r2, regs );
2423 naddr2 = addr2 + 2;
2424 naddr2 &= ADDRESS_MAXWRAP(regs);
2425 nlen2 = len2 - 2;
2426
2427 /* Convert Unicode to UTF-8 */
2428 if (unicode1 < 0x0080)
2429 {
2430 /* Convert Unicode 0000-007F to one UTF-8 byte */
2431 utf[0] = (BYTE)unicode1;
2432 n = 0;
2433 }
2434 else if (unicode1 < 0x0800)
2435 {
2436 /* Convert Unicode 0080-07FF to two UTF-8 bytes */
2437 utf[0] = (BYTE)0xC0 | (BYTE)(unicode1 >> 6);
2438 utf[1] = (BYTE)0x80 | (BYTE)(unicode1 & 0x003F);
2439 n = 1;
2440 }
2441 else if (unicode1 < 0xD800 || unicode1 >= 0xDC00)
2442 {
2443 /* Convert Unicode 0800-D7FF or DC00-FFFF
2444 to three UTF-8 bytes */
2445 utf[0] = (BYTE)0xE0 | (BYTE)(unicode1 >> 12);
2446 utf[1] = (BYTE)0x80 | (BYTE)((unicode1 & 0x0FC0) >> 6);
2447 utf[2] = (BYTE)0x80 | (BYTE)(unicode1 & 0x003F);
2448 n = 2;
2449 }
2450 else
2451 {
2452 /* Exit if fewer than 2 bytes remain in source operand */
2453 if (nlen2 < 2) break;
2454
2455 /* Fetch the Unicode low surrogate */
2456 unicode2 = ARCH_DEP(vfetch2) ( naddr2, r2, regs );
2457 naddr2 += 2;
2458 naddr2 &= ADDRESS_MAXWRAP(regs);
2459 nlen2 -= 2;
2460
2461 #if defined(FEATURE_ETF3_ENHANCEMENT)
2462 /* WellFormdnessChecking */
2463 if(wfc)
2464 {
2465 if(unicode2 < 0xdc00 || unicode2 > 0xdf00)
2466 {
2467 regs->psw.cc = 2;
2468 return;
2469 }
2470 }
2471 #endif /*defined(FEATURE_ETF3_ENHANCEMENT)*/
2472
2473 /* Convert Unicode surrogate pair to four UTF-8 bytes */
2474 uvwxy = ((unicode1 & 0x03C0) >> 6) + 1;
2475 utf[0] = (BYTE)0xF0 | (BYTE)(uvwxy >> 2);
2476 utf[1] = (BYTE)0x80 | (BYTE)((uvwxy & 0x0003) << 4)
2477 | (BYTE)((unicode1 & 0x003C) >> 2);
2478 utf[2] = (BYTE)0x80 | (BYTE)((unicode1 & 0x0003) << 4)
2479 | (BYTE)((unicode2 & 0x03C0) >> 6);
2480 utf[3] = (BYTE)0x80 | (BYTE)(unicode2 & 0x003F);
2481 n = 3;
2482 }
2483
2484 /* Exit cc=1 if too few bytes remain in destination operand */
2485 if (len1 <= n)
2486 {
2487 cc = 1;
2488 break;
2489 }
2490
2491 /* Store the result bytes in the destination operand */
2492 ARCH_DEP(vstorec) ( utf, n, addr1, r1, regs );
2493 addr1 += n + 1;
2494 addr1 &= ADDRESS_MAXWRAP(regs);
2495 len1 -= n + 1;
2496
2497 /* Update operand 2 address and length */
2498 addr2 = naddr2;
2499 len2 = nlen2;
2500
2501 /* Update the registers */
2502 SET_GR_A(r1, regs,addr1);
2503 SET_GR_A(r1+1, regs,len1);
2504 SET_GR_A(r2, regs,addr2);
2505 SET_GR_A(r2+1, regs,len2);
2506
2507 if (len1 == 0 && len2 != 0)
2508 cc = 1;
2509
2510 } /* end for(i) */
2511
2512 regs->psw.cc = cc;
2513
2514 } /* end convert_utf16_to_utf8 */
2515
2516
2517 /*-------------------------------------------------------------------*/
2518 /* B2A7 CU12 (CUTFU) - Convert UTF-8 to Unicode [RRF] */
2519 /*-------------------------------------------------------------------*/
DEF_INST(convert_utf8_to_utf16)2520 DEF_INST(convert_utf8_to_utf16)
2521 {
2522 int r1, r2; /* Register numbers */
2523 int i; /* Loop counter */
2524 int cc = 0; /* Condition code */
2525 VADR addr1, addr2; /* Operand addresses */
2526 GREG len1, len2; /* Operand lengths */
2527 int pair; /* 1=Store Unicode pair */
2528 U16 uvwxy; /* Unicode work area */
2529 U16 unicode1; /* Unicode character */
2530 U16 unicode2 = 0; /* Unicode low surrogate */
2531 GREG n; /* Number of UTF-8 bytes - 1 */
2532 BYTE utf[4]; /* UTF-8 bytes */
2533 #if defined(FEATURE_ETF3_ENHANCEMENT)
2534 int wfc; /* WellFormednessChecking */
2535 #endif /*defined(FEATURE_ETF3_ENHANCEMENT)*/
2536
2537 // NOTE: it's faster to decode with RRE format
2538 // and then to handle the 'wfc' flag separately...
2539
2540 // RRF_M(inst, regs, r1, r2, wfc);
2541 RRE(inst, regs, r1, r2);
2542
2543 ODD2_CHECK(r1, r2, regs);
2544
2545 #if defined(FEATURE_ETF3_ENHANCEMENT)
2546 /* Set WellFormednessChecking */
2547 if(inst[2] & 0x10)
2548 wfc = 1;
2549 else
2550 wfc = 0;
2551 #endif /*defined(FEATURE_ETF3_ENHANCEMENT)*/
2552
2553 /* Determine the destination and source addresses */
2554 addr1 = regs->GR(r1) & ADDRESS_MAXWRAP(regs);
2555 addr2 = regs->GR(r2) & ADDRESS_MAXWRAP(regs);
2556
2557 /* Load operand lengths from bits 0-31 of R1+1 and R2+1 */
2558 len1 = GR_A(r1+1, regs);
2559 len2 = GR_A(r2+1, regs);
2560
2561 if (len1 == 0 && len2 > 0)
2562 cc = 1;
2563
2564 /* Process operands from left to right */
2565 for (i = 0; len1 > 0 && len2 > 0; i++)
2566 {
2567 /* If 4096 characters have been converted, exit with cc=3 */
2568 if (i >= 4096)
2569 {
2570 cc = 3;
2571 break;
2572 }
2573
2574 /* Fetch first UTF-8 byte from source operand */
2575 utf[0] = ARCH_DEP(vfetchb) ( addr2, r2, regs );
2576
2577 /* Convert UTF-8 to Unicode */
2578 if (utf[0] < (BYTE)0x80)
2579 {
2580 /* Convert 00-7F to Unicode 0000-007F */
2581 n = 0;
2582 unicode1 = utf[0];
2583 pair = 0;
2584 }
2585 else if ((utf[0] & 0xE0) == 0xC0)
2586 {
2587 #if defined(FEATURE_ETF3_ENHANCEMENT)
2588 /* WellFormdnessChecking */
2589 if(wfc)
2590 {
2591 if(utf[0] <= 0xc1)
2592 {
2593 regs->psw.cc = 2;
2594 return;
2595 }
2596 }
2597 #endif /*defined(FEATURE_ETF3_ENHANCEMENT)*/
2598
2599 /* Exit if fewer than 2 bytes remain in source operand */
2600 n = 1;
2601 if (len2 <= n) break;
2602
2603 /* Fetch two UTF-8 bytes from source operand */
2604 ARCH_DEP(vfetchc) ( utf, n, addr2, r2, regs );
2605
2606 #if defined(FEATURE_ETF3_ENHANCEMENT)
2607 /* WellFormednessChecking */
2608 if(wfc)
2609 {
2610 if(utf[1] < 0x80 || utf[1] > 0xbf)
2611 {
2612 regs->psw.cc = 2;
2613 return;
2614 }
2615 }
2616 #endif /*defined(FEATURE_ETF3_ENHANCEMENT)*/
2617
2618 /* Convert C0xx-DFxx to Unicode */
2619 unicode1 = ((U16)(utf[0] & 0x1F) << 6)
2620 | ((U16)(utf[1] & 0x3F));
2621 pair = 0;
2622 }
2623 else if ((utf[0] & 0xF0) == 0xE0)
2624 {
2625 /* Exit if fewer than 3 bytes remain in source operand */
2626 n = 2;
2627 if (len2 <= n) break;
2628
2629 /* Fetch three UTF-8 bytes from source operand */
2630 ARCH_DEP(vfetchc) ( utf, n, addr2, r2, regs );
2631
2632 #if defined(FEATURE_ETF3_ENHANCEMENT)
2633 /* WellFormdnessChecking */
2634 if(wfc)
2635 {
2636 if(utf[0] == 0xe0)
2637 {
2638 if(utf[1] < 0xa0 || utf[1] > 0xbf || utf[2] < 0x80 || utf[2] > 0xbf)
2639 {
2640 regs->psw.cc = 2;
2641 return;
2642 }
2643 }
2644 if((utf[0] >= 0xe1 && utf[0] <= 0xec) || (utf[0] >= 0xee && utf[0] < 0xef))
2645 {
2646 if(utf[1] < 0x80 || utf[1] > 0xbf || utf[2] < 0x80 || utf[2] > 0xbf)
2647 {
2648 regs->psw.cc = 2;
2649 return;
2650 }
2651 }
2652 if(utf[0] == 0xed)
2653 {
2654 if(utf[1] < 0x80 || utf[1] > 0x9f || utf[2] < 0x80 || utf[2] > 0xbf)
2655 {
2656 regs->psw.cc = 2;
2657 return;
2658 }
2659 }
2660 }
2661 #endif /*defined(FEATURE_ETF3_ENHANCEMENT)*/
2662
2663 /* Convert E0xxxx-EFxxxx to Unicode */
2664 unicode1 = ((U16)(utf[0]) << 12)
2665 | ((U16)(utf[1] & 0x3F) << 6)
2666 | ((U16)(utf[2] & 0x3F));
2667 pair = 0;
2668 }
2669 else if ((utf[0] & 0xF8) == 0xF0)
2670 {
2671 /* Exit if fewer than 4 bytes remain in source operand */
2672 n = 3;
2673 if (len2 <= n) break;
2674
2675 /* Fetch four UTF-8 bytes from source operand */
2676 ARCH_DEP(vfetchc) ( utf, n, addr2, r2, regs );
2677
2678 #if defined(FEATURE_ETF3_ENHANCEMENT)
2679 /* WellFormdnessChecking */
2680 if(wfc)
2681 {
2682 if(utf[0] == 0xf0)
2683 {
2684 if(utf[1] < 0x90 || utf[1] > 0xbf || utf[2] < 0x80 || utf[2] > 0xbf || utf[3] < 0x80 || utf[3] > 0xbf)
2685 {
2686 regs->psw.cc = 2;
2687 return;
2688 }
2689 }
2690 if(utf[0] >= 0xf1 && utf[0] <= 0xf3)
2691 {
2692 if(utf[1] < 0x80 || utf[1] > 0xbf || utf[2] < 0x80 || utf[2] > 0xbf || utf[3] < 0x80 || utf[3] > 0xbf)
2693 {
2694 regs->psw.cc = 2;
2695 return;
2696 }
2697 }
2698 if(utf[0] == 0xf4)
2699 {
2700 if(utf[1] < 0x80 || utf[1] > 0x8f || utf[2] < 0x80 || utf[2] > 0xbf || utf[3] < 0x80 || utf[3] > 0xbf)
2701 {
2702 regs->psw.cc = 2;
2703 return;
2704 }
2705 }
2706 }
2707 #endif /*defined(FEATURE_ETF3_ENHANCEMENT)*/
2708
2709 /* Convert F0xxxxxx-F7xxxxxx to Unicode surrogate pair */
2710 uvwxy = ((((U16)(utf[0] & 0x07) << 2)
2711 | ((U16)(utf[1] & 0x30) >> 4)) - 1) & 0x0F;
2712 unicode1 = 0xD800 | (uvwxy << 6) | ((U16)(utf[1] & 0x0F) << 2)
2713 | ((U16)(utf[2] & 0x30) >> 4);
2714 unicode2 = 0xDC00 | ((U16)(utf[2] & 0x0F) << 6)
2715 | ((U16)(utf[3] & 0x3F));
2716 pair = 1;
2717 }
2718 else
2719 {
2720 /* Invalid UTF-8 byte 80-BF or F8-FF, exit with cc=2 */
2721 cc = 2;
2722 break;
2723 }
2724
2725 /* Store the result bytes in the destination operand */
2726 if (pair)
2727 {
2728 /* Exit if fewer than 4 bytes remain in destination */
2729 if (len1 < 4)
2730 {
2731 cc = 1;
2732 break;
2733 }
2734
2735 /* Store Unicode surrogate pair in destination */
2736 ARCH_DEP(vstore4) ( ((U32)unicode1 << 16) | (U32)unicode2,
2737 addr1, r1, regs );
2738 addr1 += 4;
2739 addr1 &= ADDRESS_MAXWRAP(regs);
2740 len1 -= 4;
2741 }
2742 else
2743 {
2744 /* Exit if fewer than 2 bytes remain in destination */
2745 if (len1 < 2)
2746 {
2747 cc = 1;
2748 break;
2749 }
2750
2751 /* Store Unicode character in destination */
2752 ARCH_DEP(vstore2) ( unicode1, addr1, r1, regs );
2753 addr1 += 2;
2754 addr1 &= ADDRESS_MAXWRAP(regs);
2755 len1 -= 2;
2756 }
2757
2758 /* Update operand 2 address and length */
2759 addr2 += n + 1;
2760 addr2 &= ADDRESS_MAXWRAP(regs);
2761 len2 -= n + 1;
2762
2763 /* Update the registers */
2764 SET_GR_A(r1, regs,addr1);
2765 SET_GR_A(r1+1, regs,len1);
2766 SET_GR_A(r2, regs,addr2);
2767 SET_GR_A(r2+1, regs,len2);
2768
2769 if (len1 == 0 && len2 != 0)
2770 cc = 1;
2771
2772 } /* end for(i) */
2773
2774 regs->psw.cc = cc;
2775
2776 } /* end convert_utf8_to_utf16 */
2777 #endif /*FEATURE_EXTENDED_TRANSLATION*/
2778
2779
2780 /*-------------------------------------------------------------------*/
2781 /* 4F CVB - Convert to Binary [RX] */
2782 /*-------------------------------------------------------------------*/
DEF_INST(convert_to_binary)2783 DEF_INST(convert_to_binary)
2784 {
2785 U64 dreg; /* 64-bit result accumulator */
2786 int r1; /* Value of R1 field */
2787 int b2; /* Base of effective addr */
2788 VADR effective_addr2; /* Effective address */
2789 int ovf; /* 1=overflow */
2790 int dxf; /* 1=data exception */
2791 BYTE dec[8]; /* Packed decimal operand */
2792
2793 RX(inst, regs, r1, b2, effective_addr2);
2794
2795 /* Fetch 8-byte packed decimal operand */
2796 ARCH_DEP(vfetchc) (dec, 8-1, effective_addr2, b2, regs);
2797
2798 /* Convert 8-byte packed decimal to 64-bit signed binary */
2799 packed_to_binary (dec, 8-1, &dreg, &ovf, &dxf);
2800
2801 /* Data exception if invalid digits or sign */
2802 if (dxf)
2803 {
2804 regs->dxc = DXC_DECIMAL;
2805 regs->program_interrupt (regs, PGM_DATA_EXCEPTION);
2806 }
2807
2808 /* Overflow if result exceeds 31 bits plus sign */
2809 if ((S64)dreg < -2147483648LL || (S64)dreg > 2147483647LL)
2810 ovf = 1;
2811
2812 /* Store low-order 32 bits of result into R1 register */
2813 regs->GR_L(r1) = dreg & 0xFFFFFFFF;
2814
2815 /* Program check if overflow (R1 contains rightmost 32 bits) */
2816 if (ovf)
2817 regs->program_interrupt (regs, PGM_FIXED_POINT_DIVIDE_EXCEPTION);
2818
2819 } /* end DEF_INST(convert_to_binary) */
2820
2821
2822 /*-------------------------------------------------------------------*/
2823 /* 4E CVD - Convert to Decimal [RX] */
2824 /*-------------------------------------------------------------------*/
DEF_INST(convert_to_decimal)2825 DEF_INST(convert_to_decimal)
2826 {
2827 S64 bin; /* 64-bit signed binary value*/
2828 int r1; /* Value of R1 field */
2829 int b2; /* Base of effective addr */
2830 VADR effective_addr2; /* Effective address */
2831 BYTE dec[16]; /* Packed decimal result */
2832
2833 RX(inst, regs, r1, b2, effective_addr2);
2834
2835 /* Load value of register and sign-extend to 64 bits */
2836 bin = (S64)((S32)(regs->GR_L(r1)));
2837
2838 /* Convert to 16-byte packed decimal number */
2839 binary_to_packed (bin, dec);
2840
2841 /* Store low 8 bytes of result at operand address */
2842 ARCH_DEP(vstorec) ( dec+8, 8-1, effective_addr2, b2, regs );
2843
2844 } /* end DEF_INST(convert_to_decimal) */
2845
2846
2847 #if defined(FEATURE_ACCESS_REGISTERS)
2848 /*-------------------------------------------------------------------*/
2849 /* B24D CPYA - Copy Access [RRE] */
2850 /*-------------------------------------------------------------------*/
DEF_INST(copy_access)2851 DEF_INST(copy_access)
2852 {
2853 int r1, r2; /* Values of R fields */
2854
2855 RRE0(inst, regs, r1, r2);
2856
2857 /* Copy R2 access register to R1 access register */
2858 regs->AR(r1) = regs->AR(r2);
2859 SET_AEA_AR(regs, r1);
2860 }
2861 #endif /*defined(FEATURE_ACCESS_REGISTERS)*/
2862
2863
2864 /*-------------------------------------------------------------------*/
2865 /* 1D DR - Divide Register [RR] */
2866 /*-------------------------------------------------------------------*/
DEF_INST(divide_register)2867 DEF_INST(divide_register)
2868 {
2869 int r1; /* Values of R fields */
2870 int r2; /* Values of R fields */
2871 int divide_overflow; /* 1=divide overflow */
2872
2873 RR(inst, regs, r1, r2);
2874
2875 ODD_CHECK(r1, regs);
2876
2877 /* Divide r1::r1+1 by r2, remainder in r1, quotient in r1+1 */
2878 divide_overflow =
2879 div_signed (&(regs->GR_L(r1)),&(regs->GR_L(r1+1)),
2880 regs->GR_L(r1),
2881 regs->GR_L(r1+1),
2882 regs->GR_L(r2));
2883
2884 /* Program check if overflow */
2885 if ( divide_overflow )
2886 regs->program_interrupt (regs, PGM_FIXED_POINT_DIVIDE_EXCEPTION);
2887 }
2888
2889
2890 /*-------------------------------------------------------------------*/
2891 /* 5D D - Divide [RX] */
2892 /*-------------------------------------------------------------------*/
DEF_INST(divide)2893 DEF_INST(divide)
2894 {
2895 int r1; /* Values of R fields */
2896 int b2; /* Base of effective addr */
2897 VADR effective_addr2; /* Effective address */
2898 U32 n; /* 32-bit operand values */
2899 int divide_overflow; /* 1=divide overflow */
2900
2901 RX(inst, regs, r1, b2, effective_addr2);
2902
2903 ODD_CHECK(r1, regs);
2904
2905 /* Load second operand from operand address */
2906 n = ARCH_DEP(vfetch4) ( effective_addr2, b2, regs );
2907
2908 /* Divide r1::r1+1 by n, remainder in r1, quotient in r1+1 */
2909 divide_overflow =
2910 div_signed (&(regs->GR_L(r1)), &(regs->GR_L(r1+1)),
2911 regs->GR_L(r1),
2912 regs->GR_L(r1+1),
2913 n);
2914
2915 /* Program check if overflow */
2916 if ( divide_overflow )
2917 regs->program_interrupt (regs, PGM_FIXED_POINT_DIVIDE_EXCEPTION);
2918
2919 }
2920
2921
2922 /*-------------------------------------------------------------------*/
2923 /* 17 XR - Exclusive Or Register [RR] */
2924 /*-------------------------------------------------------------------*/
DEF_INST(exclusive_or_register)2925 DEF_INST(exclusive_or_register)
2926 {
2927 int r1, r2; /* Values of R fields */
2928
2929 RR0(inst, regs, r1, r2);
2930
2931 /* XOR second operand with first and set condition code */
2932 regs->psw.cc = ( regs->GR_L(r1) ^= regs->GR_L(r2) ) ? 1 : 0;
2933 }
2934
2935
2936 /*-------------------------------------------------------------------*/
2937 /* 57 X - Exclusive Or [RX] */
2938 /*-------------------------------------------------------------------*/
DEF_INST(exclusive_or)2939 DEF_INST(exclusive_or)
2940 {
2941 int r1; /* Values of R fields */
2942 int b2; /* Base of effective addr */
2943 VADR effective_addr2; /* Effective address */
2944 U32 n; /* 32-bit operand values */
2945
2946 RX(inst, regs, r1, b2, effective_addr2);
2947
2948 /* Load second operand from operand address */
2949 n = ARCH_DEP(vfetch4) ( effective_addr2, b2, regs );
2950
2951 /* XOR second operand with first and set condition code */
2952 regs->psw.cc = ( regs->GR_L(r1) ^= n ) ? 1 : 0;
2953 }
2954
2955
2956 /*-------------------------------------------------------------------*/
2957 /* 97 XI - Exclusive Or Immediate [SI] */
2958 /*-------------------------------------------------------------------*/
DEF_INST(exclusive_or_immediate)2959 DEF_INST(exclusive_or_immediate)
2960 {
2961 BYTE i2; /* Immediate operand */
2962 int b1; /* Base of effective addr */
2963 VADR effective_addr1; /* Effective address */
2964 BYTE *dest; /* Pointer to target byte */
2965
2966 SI(inst, regs, i2, b1, effective_addr1);
2967
2968 ITIMER_SYNC(effective_addr1,1,regs);
2969
2970 /* Get byte mainstor address */
2971 dest = MADDR (effective_addr1, b1, regs, ACCTYPE_WRITE, regs->psw.pkey );
2972
2973 /* XOR byte with immediate operand, setting condition code */
2974 regs->psw.cc = ((*dest ^= i2) != 0);
2975
2976 ITIMER_UPDATE(effective_addr1,0,regs);
2977 }
2978
2979
2980 /*-------------------------------------------------------------------*/
2981 /* D7 XC - Exclusive Or Character [SS] */
2982 /*-------------------------------------------------------------------*/
DEF_INST(exclusive_or_character)2983 DEF_INST(exclusive_or_character)
2984 {
2985 int len, len2, len3; /* Lengths to copy */
2986 int b1, b2; /* Base register numbers */
2987 VADR addr1, addr2; /* Virtual addresses */
2988 BYTE *dest1, *dest2; /* Destination addresses */
2989 BYTE *source1, *source2; /* Source addresses */
2990 BYTE *sk1, *sk2; /* Storage key addresses */
2991 int i; /* Loop counter */
2992 int cc = 0; /* Condition code */
2993
2994 SS_L(inst, regs, len, b1, addr1, b2, addr2);
2995
2996 ITIMER_SYNC(addr1,len,regs);
2997 ITIMER_SYNC(addr2,len,regs);
2998
2999 /* Quick out for 1 byte (no boundary crossed) */
3000 if (unlikely(len == 0))
3001 {
3002 source1 = MADDR (addr2, b2, regs, ACCTYPE_READ, regs->psw.pkey);
3003 dest1 = MADDR (addr1, b1, regs, ACCTYPE_WRITE, regs->psw.pkey);
3004 if (*dest1 ^= *source1) cc = 1;
3005 regs->psw.cc = cc;
3006 return;
3007 }
3008
3009 /* There are several scenarios (in optimal order):
3010 * (1) dest boundary and source boundary not crossed
3011 * (a) dest and source are the same, set dest to zeroes
3012 * (b) dest and source are not the same
3013 * (2) dest boundary not crossed and source boundary crossed
3014 * (3) dest boundary crossed and source boundary not crossed
3015 * (4) dest boundary and source boundary are crossed
3016 * (a) dest and source boundary cross at the same time
3017 * (b) dest boundary crossed first
3018 * (c) source boundary crossed first
3019 */
3020
3021 /* Translate addresses of leftmost operand bytes */
3022 dest1 = MADDRL (addr1, len, b1, regs, ACCTYPE_WRITE_SKP, regs->psw.pkey);
3023 sk1 = regs->dat.storkey;
3024 source1 = MADDR (addr2, b2, regs, ACCTYPE_READ, regs->psw.pkey);
3025
3026 if ( NOCROSS2K(addr1,len))
3027 {
3028 if ( NOCROSS2K(addr2,len))
3029 {
3030 /* (1) - No boundaries are crossed */
3031 if (dest1 == source1)
3032 {
3033 /* (1a) - Dest and source are the same */
3034 memset(dest1, 0, len + 1);
3035 }
3036 else
3037 {
3038 /* (1b) - Dest and source are not the sam */
3039 for (i = 0; i <= len; i++)
3040 if (*dest1++ ^= *source1++) cc = 1;
3041 }
3042 }
3043 else
3044 {
3045 /* (2) - Second operand crosses a boundary */
3046 len2 = 0x800 - (addr2 & 0x7FF);
3047 source2 = MADDR ((addr2 + len2) & ADDRESS_MAXWRAP(regs),
3048 b2, regs, ACCTYPE_READ, regs->psw.pkey);
3049 for ( i = 0; i < len2; i++)
3050 if (*dest1++ ^= *source1++) cc = 1;
3051 len2 = len - len2;
3052 for ( i = 0; i <= len2; i++)
3053 if (*dest1++ ^= *source2++) cc = 1;
3054 }
3055 *sk1 |= (STORKEY_REF | STORKEY_CHANGE);
3056 }
3057 else
3058 {
3059 /* First operand crosses a boundary */
3060 len2 = 0x800 - (addr1 & 0x7FF);
3061 dest2 = MADDR ((addr1 + len2) & ADDRESS_MAXWRAP(regs),
3062 b1, regs, ACCTYPE_WRITE_SKP, regs->psw.pkey);
3063 sk2 = regs->dat.storkey;
3064
3065 if ( NOCROSS2K(addr2,len))
3066 {
3067 /* (3) - First operand crosses a boundary */
3068 for ( i = 0; i < len2; i++)
3069 if (*dest1++ ^= *source1++) cc = 1;
3070 len2 = len - len2;
3071 for ( i = 0; i <= len2; i++)
3072 if (*dest2++ ^= *source1++) cc = 1;
3073 }
3074 else
3075 {
3076 /* (4) - Both operands cross a boundary */
3077 len3 = 0x800 - (addr2 & 0x7FF);
3078 source2 = MADDR ((addr2 + len3) & ADDRESS_MAXWRAP(regs),
3079 b2, regs, ACCTYPE_READ, regs->psw.pkey);
3080 if (len2 == len3)
3081 {
3082 /* (4a) - Both operands cross at the same time */
3083 for ( i = 0; i < len2; i++)
3084 if (*dest1++ ^= *source1++) cc = 1;
3085 len2 = len - len2;
3086 for ( i = 0; i <= len2; i++)
3087 if (*dest2++ ^= *source2++) cc = 1;
3088 }
3089 else if (len2 < len3)
3090 {
3091 /* (4b) - First operand crosses first */
3092 for ( i = 0; i < len2; i++)
3093 if (*dest1++ ^= *source1++) cc = 1;
3094 len2 = len3 - len2;
3095 for ( i = 0; i < len2; i++)
3096 if (*dest2++ ^= *source1++) cc = 1;
3097 len2 = len - len3;
3098 for ( i = 0; i <= len2; i++)
3099 if (*dest2++ ^= *source2++) cc = 1;
3100 }
3101 else
3102 {
3103 /* (4c) - Second operand crosses first */
3104 for ( i = 0; i < len3; i++)
3105 if (*dest1++ ^= *source1++) cc = 1;
3106 len3 = len2 - len3;
3107 for ( i = 0; i < len3; i++)
3108 if (*dest1++ ^= *source2++) cc = 1;
3109 len3 = len - len2;
3110 for ( i = 0; i <= len3; i++)
3111 if (*dest2++ ^= *source2++) cc = 1;
3112 }
3113 }
3114 *sk1 |= (STORKEY_REF | STORKEY_CHANGE);
3115 *sk2 |= (STORKEY_REF | STORKEY_CHANGE);
3116 }
3117
3118 regs->psw.cc = cc;
3119
3120 ITIMER_UPDATE(addr1,len,regs);
3121
3122 }
3123
3124
3125 /*-------------------------------------------------------------------*/
3126 /* 44 EX - Execute [RX] */
3127 /*-------------------------------------------------------------------*/
DEF_INST(execute)3128 DEF_INST(execute)
3129 {
3130 int r1; /* Value of R field */
3131 int b2; /* Base of effective addr */
3132 BYTE *ip; /* -> executed instruction */
3133
3134 RX(inst, regs, r1, b2, regs->ET);
3135
3136 ODD_CHECK(regs->ET, regs);
3137
3138 #if defined(_FEATURE_SIE)
3139 /* Ensure that the instruction field is zero, such that
3140 zeros are stored in the interception parm field, if
3141 the interrupt is intercepted */
3142 memset(regs->exinst, 0, 8);
3143 #endif /*defined(_FEATURE_SIE)*/
3144
3145 /* Fetch target instruction from operand address */
3146 ip = INSTRUCTION_FETCH(regs, 1);
3147 if (ip != regs->exinst)
3148 memcpy (regs->exinst, ip, 8);
3149
3150 /* Program check if recursive execute */
3151 if ( regs->exinst[0] == 0x44
3152 #if defined(FEATURE_EXECUTE_EXTENSIONS_FACILITY)
3153 || (regs->exinst[0] == 0xc6 && !(regs->exinst[1] & 0x0f))
3154 #endif /*defined(FEATURE_EXECUTE_EXTENSIONS_FACILITY)*/
3155 )
3156 regs->program_interrupt (regs, PGM_EXECUTE_EXCEPTION);
3157
3158 /* Or 2nd byte of instruction with low-order byte of R1 */
3159 regs->exinst[1] |= r1 ? regs->GR_LHLCL(r1) : 0;
3160
3161 /*
3162 * Turn execflag on indicating this instruction is EXecuted.
3163 * psw.ip is backed up by the EXecuted instruction length to
3164 * be incremented back by the instruction decoder.
3165 */
3166 regs->execflag = 1;
3167 regs->exrl = 0;
3168 regs->ip -= ILC(regs->exinst[0]);
3169
3170 EXECUTE_INSTRUCTION (regs->exinst, regs);
3171
3172 /* Leave execflag on if pending PER so ILC will reflect EX */
3173 if (!OPEN_IC_PER(regs))
3174 regs->execflag = 0;
3175 }
3176
3177
3178 #if defined(FEATURE_EXECUTE_EXTENSIONS_FACILITY)
3179 /*-------------------------------------------------------------------*/
3180 /* C6x0 EXRL - Execute Relative Long [RIL] */
3181 /*-------------------------------------------------------------------*/
DEF_INST(execute_relative_long)3182 DEF_INST(execute_relative_long)
3183 {
3184 int r1; /* Register number */
3185 BYTE *ip; /* -> executed instruction */
3186
3187 RIL_A(inst, regs, r1, regs->ET);
3188
3189 #if defined(_FEATURE_SIE)
3190 /* Ensure that the instruction field is zero, such that
3191 zeros are stored in the interception parm field, if
3192 the interrupt is intercepted */
3193 memset(regs->exinst, 0, 8);
3194 #endif /*defined(_FEATURE_SIE)*/
3195
3196 /* Fetch target instruction from operand address */
3197 ip = INSTRUCTION_FETCH(regs, 1);
3198 if (ip != regs->exinst)
3199 memcpy (regs->exinst, ip, 8);
3200
3201 #if 1
3202 /* Display target instruction if stepping or tracing */
3203 if (CPU_STEPPING_OR_TRACING(regs, 6))
3204 {
3205 int n, ilc;
3206 char buf[256];
3207 #if defined(FEATURE_ESAME)
3208 n = sprintf (buf, "EXRL target ADDR="F_VADR" ", regs->ET);
3209 #else
3210 n = sprintf (buf, "EXRL ADDR="F_VADR" ", regs->ET);
3211 #endif
3212 ilc = ILC(ip[0]);
3213 n += sprintf (buf+n, " INST=%2.2X%2.2X", ip[0], ip[1]);
3214 if (ilc > 2) n += sprintf (buf+n, "%2.2X%2.2X", ip[2], ip[3]);
3215 if (ilc > 4) n += sprintf (buf+n, "%2.2X%2.2X", ip[4], ip[5]);
3216 logmsg ("%s %s", buf,(ilc<4) ? " " : (ilc<6) ? " " : "");
3217 DISASM_INSTRUCTION(ip,buf);
3218 logmsg ("%s\n", buf);
3219 }
3220 #endif
3221
3222 /* Program check if recursive execute */
3223 if ( regs->exinst[0] == 0x44 ||
3224 (regs->exinst[0] == 0xc6 && !(regs->exinst[1] & 0x0f)) )
3225 regs->program_interrupt (regs, PGM_EXECUTE_EXCEPTION);
3226
3227 /* Or 2nd byte of instruction with low-order byte of R1 */
3228 regs->exinst[1] |= r1 ? regs->GR_LHLCL(r1) : 0;
3229
3230 /*
3231 * Turn execflag on indicating this instruction is EXecuted.
3232 * psw.ip is backed up by the EXecuted instruction length to
3233 * be incremented back by the instruction decoder.
3234 */
3235 regs->execflag = 1;
3236 regs->exrl = 1;
3237 regs->ip -= ILC(regs->exinst[0]);
3238
3239 EXECUTE_INSTRUCTION (regs->exinst, regs);
3240
3241 /* Leave execflag on if pending PER so ILC will reflect EXRL */
3242 if (!OPEN_IC_PER(regs))
3243 regs->execflag = 0;
3244 }
3245 #endif /*defined(FEATURE_EXECUTE_EXTENSIONS_FACILITY)*/
3246
3247
3248 #if defined(FEATURE_ACCESS_REGISTERS)
3249 /*-------------------------------------------------------------------*/
3250 /* B24F EAR - Extract Access Register [RRE] */
3251 /*-------------------------------------------------------------------*/
DEF_INST(extract_access_register)3252 DEF_INST(extract_access_register)
3253 {
3254 int r1, r2; /* Values of R fields */
3255
3256 RRE0(inst, regs, r1, r2);
3257
3258 /* Copy R2 access register to R1 general register */
3259 regs->GR_L(r1) = regs->AR(r2);
3260 }
3261 #endif /*defined(FEATURE_ACCESS_REGISTERS)*/
3262
3263
3264 /*-------------------------------------------------------------------*/
3265 /* 43 IC - Insert Character [RX] */
3266 /*-------------------------------------------------------------------*/
DEF_INST(insert_character)3267 DEF_INST(insert_character)
3268 {
3269 int r1; /* Value of R field */
3270 int b2; /* Base of effective addr */
3271 VADR effective_addr2; /* Effective address */
3272
3273 RX(inst, regs, r1, b2, effective_addr2);
3274
3275 /* Insert character in r1 register */
3276 regs->GR_LHLCL(r1) = ARCH_DEP(vfetchb) ( effective_addr2, b2, regs );
3277
3278 }
3279
3280
3281 /*-------------------------------------------------------------------*/
3282 /* BF ICM - Insert Characters under Mask [RS] */
3283 /*-------------------------------------------------------------------*/
DEF_INST(insert_characters_under_mask)3284 DEF_INST(insert_characters_under_mask)
3285 {
3286 int r1, r3; /* Register numbers */
3287 int b2; /* effective address base */
3288 VADR effective_addr2; /* effective address */
3289 int i; /* Integer work area */
3290 BYTE vbyte[4]; /* Fetched storage bytes */
3291 U32 n; /* Fetched value */
3292 static const int /* Length-1 to fetch by mask */
3293 icmlen[16] = {0, 0, 0, 1, 0, 1, 1, 2, 0, 1, 1, 2, 1, 2, 2, 3};
3294 static const unsigned int /* Turn reg bytes off by mask*/
3295 icmmask[16] = {0xFFFFFFFF, 0xFFFFFF00, 0xFFFF00FF, 0xFFFF0000,
3296 0xFF00FFFF, 0xFF00FF00, 0xFF0000FF, 0xFF000000,
3297 0x00FFFFFF, 0x00FFFF00, 0x00FF00FF, 0x00FF0000,
3298 0x0000FFFF, 0x0000FF00, 0x000000FF, 0x00000000};
3299
3300 RS(inst, regs, r1, r3, b2, effective_addr2);
3301
3302 switch (r3) {
3303
3304 case 7:
3305 /* Optimized case */
3306 vbyte[0] = 0;
3307 ARCH_DEP(vfetchc) (vbyte + 1, 2, effective_addr2, b2, regs);
3308 n = fetch_fw (vbyte);
3309 regs->GR_L(r1) = (regs->GR_L(r1) & 0xFF000000) | n;
3310 regs->psw.cc = n ? n & 0x00800000 ?
3311 1 : 2 : 0;
3312 break;
3313
3314 case 15:
3315 /* Optimized case */
3316 regs->GR_L(r1) = ARCH_DEP(vfetch4) (effective_addr2, b2, regs);
3317 regs->psw.cc = regs->GR_L(r1) ? regs->GR_L(r1) & 0x80000000 ?
3318 1 : 2 : 0;
3319 break;
3320
3321 default:
3322 memset (vbyte, 0, 4);
3323 ARCH_DEP(vfetchc)(vbyte, icmlen[r3], effective_addr2, b2, regs);
3324
3325 /* If mask was 0 then we still had to fetch, according to POP.
3326 If so, set the fetched byte to 0 to force zero cc */
3327 if (!r3) vbyte[0] = 0;
3328
3329 n = fetch_fw (vbyte);
3330 regs->psw.cc = n ? n & 0x80000000 ?
3331 1 : 2 : 0;
3332
3333 /* Turn off the reg bytes we are going to set */
3334 regs->GR_L(r1) &= icmmask[r3];
3335
3336 /* Set bytes one at a time according to the mask */
3337 i = 0;
3338 if (r3 & 0x8) regs->GR_L(r1) |= vbyte[i++] << 24;
3339 if (r3 & 0x4) regs->GR_L(r1) |= vbyte[i++] << 16;
3340 if (r3 & 0x2) regs->GR_L(r1) |= vbyte[i++] << 8;
3341 if (r3 & 0x1) regs->GR_L(r1) |= vbyte[i];
3342 break;
3343
3344 } /* switch (r3) */
3345
3346 }
3347
3348
3349 /*-------------------------------------------------------------------*/
3350 /* B222 IPM - Insert Program Mask [RRE] */
3351 /*-------------------------------------------------------------------*/
DEF_INST(insert_program_mask)3352 DEF_INST(insert_program_mask)
3353 {
3354 int r1, unused; /* Value of R field */
3355
3356 RRE0(inst, regs, r1, unused);
3357
3358 /* Insert condition code in R1 bits 2-3, program mask
3359 in R1 bits 4-7, and set R1 bits 0-1 to zero */
3360 regs->GR_LHHCH(r1) = (regs->psw.cc << 4) | regs->psw.progmask;
3361 }
3362
3363
3364 /*-------------------------------------------------------------------*/
3365 /* 58 L - Load [RX] */
3366 /*-------------------------------------------------------------------*/
DEF_INST(load)3367 DEF_INST(load)
3368 {
3369 int r1; /* Value of R field */
3370 int b2; /* Base of effective addr */
3371 VADR effective_addr2; /* Effective address */
3372 #if 0
3373 U32 *p; /* Mainstor pointer */
3374 #endif
3375
3376 RX(inst, regs, r1, b2, effective_addr2);
3377
3378 /* Load R1 register from second operand */
3379
3380 regs->GR_L(r1) = ARCH_DEP(vfetch4) ( effective_addr2, b2, regs );
3381
3382 } /* end DEF_INST(load) */
3383
3384
3385 /*-------------------------------------------------------------------*/
3386 /* 18 LR - Load Register [RR] */
3387 /*-------------------------------------------------------------------*/
DEF_INST(load_register)3388 DEF_INST(load_register)
3389 {
3390 int r1, r2; /* Values of R fields */
3391
3392 RR0(inst, regs, r1, r2);
3393
3394 /* Copy second operand to first operand */
3395 regs->GR_L(r1) = regs->GR_L(r2);
3396 }
3397
3398
3399 #if defined(FEATURE_ACCESS_REGISTERS)
3400 /*-------------------------------------------------------------------*/
3401 /* 9A LAM - Load Access Multiple [RS] */
3402 /*-------------------------------------------------------------------*/
DEF_INST(load_access_multiple)3403 DEF_INST(load_access_multiple)
3404 {
3405 int r1, r3; /* Register numbers */
3406 int b2; /* effective address base */
3407 VADR effective_addr2; /* effective address */
3408 int i, m, n; /* Integer work areas */
3409 U32 *p1, *p2 = NULL; /* Mainstor pointers */
3410
3411 RS(inst, regs, r1, r3, b2, effective_addr2);
3412
3413 FW_CHECK(effective_addr2, regs);
3414
3415 /* Calculate number of regs to fetch */
3416 n = ((r3 - r1) & 0xF) + 1;
3417
3418 /* Calculate number of words to next boundary */
3419 m = (0x800 - (effective_addr2 & 0x7ff)) >> 2;
3420
3421 /* Address of operand beginning */
3422 p1 = (U32*)MADDR(effective_addr2, b2, regs, ACCTYPE_READ, regs->psw.pkey);
3423
3424 /* Get address of next page if boundary crossed */
3425 if (unlikely (m < n))
3426 p2 = (U32*)MADDR(effective_addr2 + (m*4), b2, regs, ACCTYPE_READ, regs->psw.pkey);
3427 else
3428 m = n;
3429
3430 /* Copy from operand beginning */
3431 for (i = 0; i < m; i++, p1++)
3432 {
3433 regs->AR((r1 + i) & 0xF) = fetch_fw (p1);
3434 SET_AEA_AR (regs, (r1 + i) & 0xF);
3435 }
3436
3437 /* Copy from next page */
3438 for ( ; i < n; i++, p2++)
3439 {
3440 regs->AR((r1 + i) & 0xF) = fetch_fw (p2);
3441 SET_AEA_AR (regs, (r1 + i) & 0xF);
3442 }
3443
3444 }
3445 #endif /*defined(FEATURE_ACCESS_REGISTERS)*/
3446
3447
3448 /*-------------------------------------------------------------------*/
3449 /* 41 LA - Load Address [RX] */
3450 /*-------------------------------------------------------------------*/
DEF_INST(load_address)3451 DEF_INST(load_address)
3452 {
3453 int r1; /* Value of R field */
3454 int b2; /* Base of effective addr */
3455 VADR effective_addr2; /* Effective address */
3456
3457 RX0(inst, regs, r1, b2, effective_addr2);
3458
3459 /* Load operand address into register */
3460 SET_GR_A(r1, regs, effective_addr2);
3461 }
3462
3463
3464 #if defined(FEATURE_ACCESS_REGISTERS)
3465 /*-------------------------------------------------------------------*/
3466 /* 51 LAE - Load Address Extended [RX] */
3467 /*-------------------------------------------------------------------*/
DEF_INST(load_address_extended)3468 DEF_INST(load_address_extended)
3469 {
3470 int r1; /* Value of R field */
3471 int b2; /* Base of effective addr */
3472 VADR effective_addr2; /* Effective address */
3473
3474 RX0(inst, regs, r1, b2, effective_addr2);
3475
3476 /* Load operand address into register */
3477 SET_GR_A(r1, regs,effective_addr2);
3478
3479 /* Load corresponding value into access register */
3480 if ( PRIMARY_SPACE_MODE(&(regs->psw)) )
3481 regs->AR(r1) = ALET_PRIMARY;
3482 else if ( SECONDARY_SPACE_MODE(&(regs->psw)) )
3483 regs->AR(r1) = ALET_SECONDARY;
3484 else if ( HOME_SPACE_MODE(&(regs->psw)) )
3485 regs->AR(r1) = ALET_HOME;
3486 else /* ACCESS_REGISTER_MODE(&(regs->psw)) */
3487 regs->AR(r1) = (b2 == 0) ? 0 : regs->AR(b2);
3488 SET_AEA_AR(regs, r1);
3489 }
3490 #endif /*defined(FEATURE_ACCESS_REGISTERS)*/
3491
3492
3493 /*-------------------------------------------------------------------*/
3494 /* 12 LTR - Load and Test Register [RR] */
3495 /*-------------------------------------------------------------------*/
DEF_INST(load_and_test_register)3496 DEF_INST(load_and_test_register)
3497 {
3498 int r1, r2; /* Values of R fields */
3499
3500 RR0(inst, regs, r1, r2);
3501
3502 /* Copy second operand and set condition code */
3503 regs->GR_L(r1) = regs->GR_L(r2);
3504
3505 regs->psw.cc = (S32)regs->GR_L(r1) < 0 ? 1 :
3506 (S32)regs->GR_L(r1) > 0 ? 2 : 0;
3507 }
3508
3509
3510 /*-------------------------------------------------------------------*/
3511 /* 13 LCR - Load Complement Register [RR] */
3512 /*-------------------------------------------------------------------*/
DEF_INST(load_complement_register)3513 DEF_INST(load_complement_register)
3514 {
3515 int r1, r2; /* Values of R fields */
3516
3517 RR(inst, regs, r1, r2);
3518
3519 /* Condition code 3 and program check if overflow */
3520 if ( regs->GR_L(r2) == 0x80000000 )
3521 {
3522 regs->GR_L(r1) = regs->GR_L(r2);
3523 regs->psw.cc = 3;
3524 if ( FOMASK(®s->psw) )
3525 regs->program_interrupt (regs, PGM_FIXED_POINT_OVERFLOW_EXCEPTION);
3526 return;
3527 }
3528
3529 /* Load complement of second operand and set condition code */
3530 regs->GR_L(r1) = -((S32)regs->GR_L(r2));
3531
3532 regs->psw.cc = (S32)regs->GR_L(r1) < 0 ? 1 :
3533 (S32)regs->GR_L(r1) > 0 ? 2 : 0;
3534 }
3535
3536
3537 /*-------------------------------------------------------------------*/
3538 /* 48 LH - Load Halfword [RX] */
3539 /*-------------------------------------------------------------------*/
DEF_INST(load_halfword)3540 DEF_INST(load_halfword)
3541 {
3542 int r1; /* Value of R field */
3543 int b2; /* Base of effective addr */
3544 VADR effective_addr2; /* Effective address */
3545
3546 RX(inst, regs, r1, b2, effective_addr2);
3547
3548 /* Load rightmost 2 bytes of register from operand address */
3549 regs->GR_L(r1) = (S16)ARCH_DEP(vfetch2) ( effective_addr2, b2, regs );
3550 }
3551
3552
3553 #if defined(FEATURE_IMMEDIATE_AND_RELATIVE)
3554 /*-------------------------------------------------------------------*/
3555 /* A7x8 LHI - Load Halfword Immediate [RI] */
3556 /*-------------------------------------------------------------------*/
DEF_INST(load_halfword_immediate)3557 DEF_INST(load_halfword_immediate)
3558 {
3559 int r1; /* Register number */
3560 U16 i2; /* 16-bit operand values */
3561
3562 RI0(inst, regs, r1, i2);
3563
3564 /* Load operand into register */
3565 regs->GR_L(r1) = (S16)i2;
3566
3567 }
3568 #endif /*defined(FEATURE_IMMEDIATE_AND_RELATIVE)*/
3569
3570
3571 /*-------------------------------------------------------------------*/
3572 /* 98 LM - Load Multiple [RS] */
3573 /*-------------------------------------------------------------------*/
DEF_INST(load_multiple)3574 DEF_INST(load_multiple)
3575 {
3576 int r1, r3; /* Register numbers */
3577 int b2; /* effective address base */
3578 VADR effective_addr2; /* effective address */
3579 int i, m, n; /* Integer work areas */
3580 U32 *p1, *p2; /* Mainstor pointers */
3581 BYTE *bp1; /* Unaligned maintstor ptr */
3582
3583 RS(inst, regs, r1, r3, b2, effective_addr2);
3584
3585 /* Calculate number of bytes to load */
3586 n = (((r3 - r1) & 0xF) + 1) << 2;
3587
3588 /* Calculate number of bytes to next boundary */
3589 m = 0x800 - ((VADR_L)effective_addr2 & 0x7ff);
3590
3591 /* Address of operand beginning */
3592 bp1 = (BYTE*)MADDR(effective_addr2, b2, regs, ACCTYPE_READ, regs->psw.pkey);
3593 p1=(U32*)bp1;
3594
3595 if (likely(n <= m))
3596 {
3597 /* Boundary not crossed */
3598 n >>= 2;
3599 #if defined(OPTION_STRICT_ALIGNMENT)
3600 if(likely(!(((uintptr_t)effective_addr2)&0x03)))
3601 {
3602 #endif
3603 for (i = 0; i < n; i++, p1++)
3604 regs->GR_L((r1 + i) & 0xF) = fetch_fw (p1);
3605 #if defined(OPTION_STRICT_ALIGNMENT)
3606 }
3607 else
3608 {
3609 for (i = 0; i < n; i++, bp1+=4)
3610 regs->GR_L((r1 + i) & 0xF) = fetch_fw (bp1);
3611 }
3612 #endif
3613 }
3614 else
3615 {
3616 /* Boundary crossed, get 2nd page address */
3617 effective_addr2 += m;
3618 effective_addr2 &= ADDRESS_MAXWRAP(regs);
3619 p2 = (U32*)MADDR(effective_addr2, b2, regs, ACCTYPE_READ, regs->psw.pkey);
3620
3621 if (likely((m & 0x3) == 0))
3622 {
3623 /* Addresses are word aligned */
3624 m >>= 2;
3625 for (i = 0; i < m; i++, p1++)
3626 regs->GR_L((r1 + i) & 0xF) = fetch_fw (p1);
3627 n >>= 2;
3628 for ( ; i < n; i++, p2++)
3629 regs->GR_L((r1 + i) & 0xF) = fetch_fw (p2);
3630 }
3631 else
3632 {
3633 /* Worst case */
3634 U32 rwork[16];
3635 BYTE *b1, *b2;
3636
3637 b1 = (BYTE *)&rwork[0];
3638 b2 = (BYTE *)p1;
3639 for (i = 0; i < m; i++)
3640 *b1++ = *b2++;
3641 b2 = (BYTE *)p2;
3642 for ( ; i < n; i++)
3643 *b1++ = *b2++;
3644
3645 n >>= 2;
3646 for (i = 0; i < n; i++)
3647 regs->GR_L((r1 + i) & 0xF) = CSWAP32(rwork[i]);
3648 }
3649 }
3650
3651 } /* end DEF_INST(load_multiple) */
3652
3653
3654 /*-------------------------------------------------------------------*/
3655 /* 11 LNR - Load Negative Register [RR] */
3656 /*-------------------------------------------------------------------*/
DEF_INST(load_negative_register)3657 DEF_INST(load_negative_register)
3658 {
3659 int r1, r2; /* Values of R fields */
3660
3661 RR0(inst, regs, r1, r2);
3662
3663 /* Load negative value of second operand and set cc */
3664 regs->GR_L(r1) = (S32)regs->GR_L(r2) > 0 ?
3665 -((S32)regs->GR_L(r2)) :
3666 (S32)regs->GR_L(r2);
3667
3668 regs->psw.cc = (S32)regs->GR_L(r1) == 0 ? 0 : 1;
3669 }
3670
3671
3672 /*-------------------------------------------------------------------*/
3673 /* 10 LPR - Load Positive Register [RR] */
3674 /*-------------------------------------------------------------------*/
DEF_INST(load_positive_register)3675 DEF_INST(load_positive_register)
3676 {
3677 int r1, r2; /* Values of R fields */
3678
3679 RR(inst, regs, r1, r2);
3680
3681 /* Condition code 3 and program check if overflow */
3682 if ( regs->GR_L(r2) == 0x80000000 )
3683 {
3684 regs->GR_L(r1) = regs->GR_L(r2);
3685 regs->psw.cc = 3;
3686 if ( FOMASK(®s->psw) )
3687 regs->program_interrupt (regs, PGM_FIXED_POINT_OVERFLOW_EXCEPTION);
3688 return;
3689 }
3690
3691 /* Load positive value of second operand and set cc */
3692 regs->GR_L(r1) = (S32)regs->GR_L(r2) < 0 ?
3693 -((S32)regs->GR_L(r2)) :
3694 (S32)regs->GR_L(r2);
3695
3696 regs->psw.cc = (S32)regs->GR_L(r1) == 0 ? 0 : 2;
3697 }
3698
3699
3700 /*-------------------------------------------------------------------*/
3701 /* AF MC - Monitor Call [SI] */
3702 /*-------------------------------------------------------------------*/
DEF_INST(monitor_call)3703 DEF_INST(monitor_call)
3704 {
3705 BYTE i2; /* Monitor class */
3706 int b1; /* Base of effective addr */
3707 VADR effective_addr1; /* Effective address */
3708 CREG n; /* Work */
3709
3710 SI(inst, regs, i2, b1, effective_addr1);
3711
3712 /* Program check if monitor class exceeds 15 */
3713 if ( i2 > 0x0F )
3714 regs->program_interrupt (regs, PGM_SPECIFICATION_EXCEPTION);
3715
3716 /* Ignore if monitor mask in control register 8 is zero */
3717 n = (regs->CR(8) & CR8_MCMASK) << i2;
3718 if ((n & 0x00008000) == 0)
3719 return;
3720
3721 #if defined(FEATURE_ENHANCED_MONITOR_FACILITY)
3722 /* Perform Monitor Event Counting Operation if enabled */
3723 if (((regs->CR_H(8) & CR8_MCMASK) << i2) & 0x00008000)
3724 {
3725 PSA *psa; /* -> Prefixed storage area */
3726 RADR cao; /* Enhanced Monitor Counter Array Origin */
3727 U32 cal; /* Enhanced Monitor Counter Array Length */
3728 U32 ec; /* Enhanced Montior Counter Exception Count */
3729 RADR ceh; /* HW Counter Entry address */
3730 RADR cew; /* FW Counter Entry address */
3731 RADR px;
3732 int unavailable;
3733 U16 hwc;
3734 U32 fwc;
3735
3736 px = regs->PX;
3737 SIE_TRANSLATE(&px, ACCTYPE_WRITE, regs);
3738
3739 /* Point to PSA in main storage */
3740 psa = (void*)(regs->mainstor + px);
3741
3742 /* Set the main storage reference bit */
3743 STORAGE_KEY(px, regs) |= STORKEY_REF;
3744
3745 /* Fetch Counter Array Origin and Size from PSA */
3746 FETCH_DW(cao, psa->cao);
3747 FETCH_W(cal, psa->cal);
3748
3749 /* DW boundary, ignore last 3 bits */
3750 cao &= ~7ULL;
3751
3752 if(!(unavailable = (effective_addr1 >= cal)))
3753 {
3754 /* Point to the virtual address of the HW entry */
3755 ceh = cao + (effective_addr1 << 1);
3756 if(!(unavailable = ARCH_DEP(translate_addr) (ceh, USE_HOME_SPACE, regs, ACCTYPE_EMC)))
3757 {
3758 /* Convert real address to absolute address */
3759 ceh = APPLY_PREFIXING (regs->dat.raddr, regs->PX);
3760
3761 /* Ensure absolute address is available */
3762 if (!(unavailable = (ceh >= regs->mainlim )))
3763 {
3764 SIE_TRANSLATE(&ceh, ACCTYPE_WRITE, regs);
3765
3766 /* Update counter */
3767 FETCH_HW(hwc, ceh + regs->mainstor);
3768 STORAGE_KEY(ceh, regs) |= STORKEY_REF;
3769 if(++hwc)
3770 {
3771 STORE_HW(ceh + regs->mainstor, hwc);
3772 STORAGE_KEY(ceh, regs) |= (STORKEY_REF | STORKEY_CHANGE);
3773 }
3774 else
3775 {
3776 /* Point to the virtual address of the FW entry */
3777 cew = cao + (cal << 1) + (effective_addr1 << 2);
3778 if(!(unavailable = ARCH_DEP(translate_addr) (cew, USE_HOME_SPACE, regs, ACCTYPE_EMC)))
3779 {
3780 /* Convert real address to absolute address */
3781 cew = APPLY_PREFIXING (regs->dat.raddr, regs->PX);
3782
3783 /* Ensure absolute address is available */
3784 if (!(unavailable = (cew >= regs->mainlim )))
3785 {
3786 SIE_TRANSLATE(&cew, ACCTYPE_WRITE, regs);
3787
3788 /* Update both counters */
3789 FETCH_W(fwc, cew + regs->mainstor);
3790 fwc++;
3791
3792 STORE_W(cew + regs->mainstor, fwc);
3793 STORAGE_KEY(cew, regs) |= (STORKEY_REF | STORKEY_CHANGE);
3794
3795 STORE_HW(ceh + regs->mainstor, hwc);
3796 STORAGE_KEY(ceh, regs) |= (STORKEY_REF | STORKEY_CHANGE);
3797 }
3798 }
3799 }
3800 }
3801 }
3802 }
3803
3804 /* Update the Enhance Monitor Exception Counter if the array could not be updated */
3805 if(unavailable)
3806 {
3807 FETCH_W(ec,psa->ec);
3808 ec++;
3809 /* Set the main storage reference and change bits */
3810 STORAGE_KEY(px, regs) |= (STORKEY_REF | STORKEY_CHANGE);
3811 STORE_W(psa->ec,ec);
3812 }
3813
3814 return;
3815
3816 }
3817 #endif /*defined(FEATURE_ENHANCED_MONITOR_FACILITY)*/
3818
3819 regs->monclass = i2;
3820 regs->MONCODE = effective_addr1;
3821
3822 /* Generate a monitor event program interruption */
3823 regs->program_interrupt (regs, PGM_MONITOR_EVENT);
3824
3825 }
3826
3827
3828 /*-------------------------------------------------------------------*/
3829 /* 92 MVI - Move Immediate [SI] */
3830 /*-------------------------------------------------------------------*/
DEF_INST(move_immediate)3831 DEF_INST(move_immediate)
3832 {
3833 BYTE i2; /* Immediate operand */
3834 int b1; /* Base of effective addr */
3835 VADR effective_addr1; /* Effective address */
3836
3837 SI(inst, regs, i2, b1, effective_addr1);
3838
3839 /* Store immediate operand at operand address */
3840 ARCH_DEP(vstoreb) ( i2, effective_addr1, b1, regs );
3841 }
3842
3843
3844 /*-------------------------------------------------------------------*/
3845 /* D2 MVC - Move Character [SS] */
3846 /*-------------------------------------------------------------------*/
DEF_INST(move_character)3847 DEF_INST(move_character)
3848 {
3849 BYTE l; /* Length byte */
3850 int b1, b2; /* Values of base fields */
3851 VADR effective_addr1,
3852 effective_addr2; /* Effective addresses */
3853
3854 SS_L(inst, regs, l, b1, effective_addr1,
3855 b2, effective_addr2);
3856
3857 /* Move characters using current addressing mode and key */
3858 ARCH_DEP(move_chars) (effective_addr1, b1, regs->psw.pkey,
3859 effective_addr2, b2, regs->psw.pkey, l, regs);
3860 }
3861
3862
3863 /*-------------------------------------------------------------------*/
3864 /* E8 MVCIN - Move Inverse [SS] */
3865 /*-------------------------------------------------------------------*/
DEF_INST(move_inverse)3866 DEF_INST(move_inverse)
3867 {
3868 BYTE l; /* Lenght byte */
3869 int b1, b2; /* Base registers */
3870 VADR effective_addr1,
3871 effective_addr2; /* Effective addresses */
3872 VADR n; /* 32-bit operand values */
3873 BYTE tbyte; /* Byte work areas */
3874 int i; /* Integer work areas */
3875
3876 SS_L(inst, regs, l, b1, effective_addr1,
3877 b2, effective_addr2);
3878
3879 /* If operand 1 crosses a page, make sure both pages are accessable */
3880 if((effective_addr1 & PAGEFRAME_PAGEMASK) !=
3881 ((effective_addr1 + l) & PAGEFRAME_PAGEMASK))
3882 ARCH_DEP(validate_operand) (effective_addr1, b1, l, ACCTYPE_WRITE_SKP, regs);
3883
3884 /* If operand 2 crosses a page, make sure both pages are accessable */
3885 n = (effective_addr2 - l) & ADDRESS_MAXWRAP(regs);
3886 if((n & PAGEFRAME_PAGEMASK) !=
3887 ((n + l) & PAGEFRAME_PAGEMASK))
3888 ARCH_DEP(validate_operand) (n, b2, l, ACCTYPE_READ, regs);
3889
3890 /* Process the destination operand from left to right,
3891 and the source operand from right to left */
3892 for ( i = 0; i <= l; i++ )
3893 {
3894 /* Fetch a byte from the source operand */
3895 tbyte = ARCH_DEP(vfetchb) ( effective_addr2, b2, regs );
3896
3897 /* Store the byte in the destination operand */
3898 ARCH_DEP(vstoreb) ( tbyte, effective_addr1, b1, regs );
3899
3900 /* Increment destination operand address */
3901 effective_addr1++;
3902 effective_addr1 &= ADDRESS_MAXWRAP(regs);
3903
3904 /* Decrement source operand address */
3905 effective_addr2--;
3906 effective_addr2 &= ADDRESS_MAXWRAP(regs);
3907
3908 } /* end for(i) */
3909 }
3910
3911
3912 /*-------------------------------------------------------------------*/
3913 /* 0E MVCL - Move Long [RR] */
3914 /*-------------------------------------------------------------------*/
DEF_INST(move_long)3915 DEF_INST(move_long)
3916 {
3917 int r1, r2; /* Values of R fields */
3918 VADR addr1, addr2; /* Operand addresses */
3919 int len1, len2; /* Operand lengths */
3920 int len, len3, len4; /* Work lengths */
3921 VADR n; /* Work area */
3922 BYTE *dest, *source; /* Mainstor addresses */
3923 BYTE pad; /* Padding byte */
3924 #if defined(FEATURE_INTERVAL_TIMER)
3925 int orglen1; /* Original dest length */
3926 #endif
3927
3928 RR(inst, regs, r1, r2);
3929
3930 ODD2_CHECK(r1, r2, regs);
3931
3932 /* Determine the destination and source addresses */
3933 addr1 = regs->GR(r1) & ADDRESS_MAXWRAP(regs);
3934 addr2 = regs->GR(r2) & ADDRESS_MAXWRAP(regs);
3935
3936
3937 /* Load padding byte from bits 0-7 of R2+1 register */
3938 pad = regs->GR_LHHCH(r2+1);
3939
3940 /* Load operand lengths from bits 8-31 of R1+1 and R2+1 */
3941 len1 = regs->GR_LA24(r1+1);
3942 len2 = regs->GR_LA24(r2+1);
3943
3944 #if defined(FEATURE_INTERVAL_TIMER)
3945 orglen1=len1;
3946 #endif
3947
3948 ITIMER_SYNC(addr2,len2,regs);
3949
3950 /* Test for destructive overlap */
3951 if ( len2 > 1 && len1 > 1
3952 && (!ACCESS_REGISTER_MODE(&(regs->psw))
3953 || (r1 == 0 ? 0 : regs->AR(r1))
3954 == (r2 == 0 ? 0 : regs->AR(r2))))
3955 {
3956 n = addr2 + ((len2 < len1) ? len2 : len1) - 1;
3957 n &= ADDRESS_MAXWRAP(regs);
3958 if ((n > addr2
3959 && (addr1 > addr2 && addr1 <= n))
3960 || (n <= addr2
3961 && (addr1 > addr2 || addr1 <= n)))
3962 {
3963 SET_GR_A(r1, regs,addr1);
3964 SET_GR_A(r2, regs,addr2);
3965 regs->psw.cc = 3;
3966 #if 0
3967 logmsg (_("MVCL destructive overlap: "));
3968 ARCH_DEP(display_inst) (regs, inst);
3969 #endif
3970 return;
3971 }
3972 }
3973
3974 /* Initialize source and dest addresses */
3975 if (len1)
3976 {
3977 if (len2)
3978 {
3979 source = MADDR (addr2, r2, regs, ACCTYPE_READ, regs->psw.pkey);
3980 }
3981 else
3982 {
3983 source=NULL;
3984 }
3985 dest = MADDRL (addr1, len1, r1, regs, ACCTYPE_WRITE, regs->psw.pkey);
3986 }
3987 else
3988 {
3989 /* FIXME : We shouldn't have to do that - just to prevent potentially
3990 uninitialized variable warning in GCC.. Can't see where it is getting
3991 this diagnostic from. ISW 2009/02/04 */
3992 source=NULL;
3993 dest=NULL;
3994 }
3995
3996 /* Set the condition code according to the lengths */
3997 regs->psw.cc = (len1 < len2) ? 1 : (len1 > len2) ? 2 : 0;
3998
3999 /* Set the registers *after* translating - so that the instruction is properly
4000 nullified when there is an access exception on the 1st unit of operation */
4001 SET_GR_A(r1, regs,addr1);
4002 SET_GR_A(r2, regs,addr2);
4003
4004 while (len1)
4005 {
4006 /* Clear or copy memory */
4007 if (len2 == 0)
4008 {
4009 len = NOCROSS2KL(addr1,len1) ? len1 : (int)(0x800 - (addr1 & 0x7FF));
4010 memset (dest, pad, len);
4011 }
4012 else
4013 {
4014 len3 = NOCROSS2KL(addr1,len1) ? len1 : (int)(0x800 - (addr1 & 0x7FF));
4015 len4 = NOCROSS2KL(addr2,len2) ? len2 : (int)(0x800 - (addr2 & 0x7FF));
4016 len = len3 < len4 ? len3 : len4;
4017 /* Use concpy to ensure Concurrent block update consistency */
4018 concpy (regs, dest, source, len);
4019 }
4020
4021 /* No longer required because it is handled during MADDRL */
4022 #if 0
4023 /* Check for storage alteration PER event */
4024 #if defined(FEATURE_PER)
4025 if ( EN_IC_PER_SA(regs)
4026 #if defined(FEATURE_PER2)
4027 && ( REAL_MODE(®s->psw)
4028 || ARCH_DEP(check_sa_per2) (r1, ACCTYPE_WRITE, regs)
4029 )
4030 #endif /*defined(FEATURE_PER2)*/
4031 && PER_RANGE_CHECK2(addr1, addr1+len, regs->CR(10), regs->CR(11)) )
4032 ON_IC_PER_SA(regs);
4033 #endif /*defined(FEATURE_PER)*/
4034 #endif
4035
4036 /* Adjust lengths and virtual addresses */
4037 len1 -= len;
4038 addr1 = (addr1 + len) & ADDRESS_MAXWRAP(regs);
4039 if (len2)
4040 {
4041 len2 -= len;
4042 addr2 = (addr2 + len) & ADDRESS_MAXWRAP(regs);
4043 }
4044
4045 /* Update regs (since interrupt may occur) */
4046 SET_GR_A(r1, regs,addr1);
4047 SET_GR_A(r2, regs,addr2);
4048 regs->GR_LA24(r1+1) = len1;
4049 regs->GR_LA24(r2+1) = len2;
4050
4051 /* Check for pending interrupt */
4052 if ( len1 > 256
4053 && (OPEN_IC_EXTPENDING(regs) || OPEN_IC_IOPENDING(regs)) )
4054 {
4055 UPD_PSW_IA (regs, PSW_IA(regs, -REAL_ILC(regs)));
4056 break;
4057 }
4058
4059 /* Translate next source and dest addresses */
4060 if (len1)
4061 {
4062 if (len2)
4063 {
4064 if (addr2 & 0x7FF)
4065 source += len;
4066 else
4067 source = MADDR (addr2, r2, regs, ACCTYPE_READ, regs->psw.pkey);
4068 }
4069 if (addr1 & 0x7FF)
4070 dest += len;
4071 else
4072 dest = MADDRL (addr1, len1, r1, regs, ACCTYPE_WRITE, regs->psw.pkey);
4073 }
4074
4075 } /* while (len1) */
4076
4077 ITIMER_UPDATE(addr1,orglen1,regs);
4078
4079 /* If len1 is non-zero then we were interrupted */
4080 if (len1)
4081 RETURN_INTCHECK(regs);
4082
4083 }
4084
4085
4086 #if defined(FEATURE_COMPARE_AND_MOVE_EXTENDED)
4087 /*-------------------------------------------------------------------*/
4088 /* A8 MVCLE - Move Long Extended [RS] */
4089 /*-------------------------------------------------------------------*/
DEF_INST(move_long_extended)4090 DEF_INST(move_long_extended)
4091 {
4092 int r1, r3; /* Register numbers */
4093 int b2; /* effective address base */
4094 VADR effective_addr2; /* effective address */
4095 int cc; /* Condition code */
4096 VADR addr1, addr2; /* Operand addresses */
4097 GREG len1, len2; /* Operand lengths */
4098 BYTE pad; /* Padding byte */
4099 size_t cpu_length; /* cpu determined length */
4100 size_t copylen; /* Length to copy */
4101 BYTE *dest; /* Maint storage pointers */
4102 size_t dstlen,srclen; /* Page wide src/dst lengths */
4103
4104 RS(inst, regs, r1, r3, b2, effective_addr2);
4105
4106 ODD2_CHECK(r1, r3, regs);
4107
4108 /* Load padding byte from bits 24-31 of effective address */
4109 pad = effective_addr2 & 0xFF;
4110
4111 /* Determine the destination and source addresses */
4112 addr1 = regs->GR(r1) & ADDRESS_MAXWRAP(regs);
4113 addr2 = regs->GR(r3) & ADDRESS_MAXWRAP(regs);
4114
4115 /* Load operand lengths from bits 0-31 of R1+1 and R3+1 */
4116 len1 = GR_A(r1+1, regs);
4117 len2 = GR_A(r3+1, regs);
4118
4119 /* set cpu_length as shortest distance to new page */
4120 if ((addr1 & 0xFFF) > (addr2 & 0xFFF))
4121 cpu_length = 0x1000 - (addr1 & 0xFFF);
4122 else
4123 cpu_length = 0x1000 - (addr2 & 0xFFF);
4124
4125 dstlen=MIN(cpu_length,len1);
4126 srclen=MIN(cpu_length,len2);
4127 copylen=MIN(dstlen,srclen);
4128
4129 /* Set the condition code according to the lengths */
4130 cc = (len1 < len2) ? 1 : (len1 > len2) ? 2 : 0;
4131
4132 /* Obtain destination pointer */
4133 if(len1==0)
4134 {
4135 /* bail out if nothing to do */
4136 regs->psw.cc = cc;
4137 return;
4138 }
4139
4140 dest = MADDRL (addr1, len1, r1, regs, ACCTYPE_WRITE, regs->psw.pkey);
4141 if(copylen!=0)
4142 {
4143 /* here if we need to copy data */
4144 BYTE *source;
4145 /* get source frame and copy concurrently */
4146 source = MADDR (addr2, r3, regs, ACCTYPE_READ, regs->psw.pkey);
4147 concpy(regs,dest,source,copylen);
4148 /* Adjust operands */
4149 addr2+=copylen;
4150 len2-=copylen;
4151 addr1+=copylen;
4152 len1-=copylen;
4153
4154 /* Adjust length & pointers for this cycle */
4155 dest+=copylen;
4156 dstlen-=copylen;
4157 srclen-=copylen;
4158 }
4159 if(srclen==0 && dstlen!=0)
4160 {
4161 /* here if we need to pad the destination */
4162 memset(dest,pad,dstlen);
4163
4164 /* Adjust destination operands */
4165 addr1+=dstlen;
4166 len1-=dstlen;
4167 }
4168
4169 /* Update the registers */
4170 SET_GR_A(r1, regs,addr1);
4171 SET_GR_A(r1+1, regs,len1);
4172 SET_GR_A(r3, regs,addr2);
4173 SET_GR_A(r3+1, regs,len2);
4174 /* if len1 != 0 then set CC to 3 to indicate
4175 we have reached end of CPU dependent length */
4176 if(len1>0) cc=3;
4177
4178 regs->psw.cc = cc;
4179
4180 }
4181 #endif /*defined(FEATURE_COMPARE_AND_MOVE_EXTENDED)*/
4182
4183
4184 #define MOVE_NUMERIC_BUMP(_d,_s) \
4185 do { \
4186 *(_d)=( *(_d) & 0xF0) | ( *(_s) & 0x0F); \
4187 _d++; \
4188 _s++; \
4189 } while(0)
4190
4191 /*-------------------------------------------------------------------*/
4192 /* D1 MVN - Move Numerics [SS] */
4193 /*-------------------------------------------------------------------*/
DEF_INST(move_numerics)4194 DEF_INST(move_numerics)
4195 {
4196 VADR addr1, addr2; /* Operand virtual addresses */
4197 int len, arn1, arn2; /* Operand values */
4198 BYTE *dest1, *dest2; /* Destination addresses */
4199 BYTE *source1, *source2; /* Source addresses */
4200 BYTE *sk1, *sk2; /* Storage key addresses */
4201 int len2, len3; /* Lengths to copy */
4202 int i; /* Loop counter */
4203
4204 SS_L(inst, regs, len, arn1, addr1, arn2, addr2);
4205
4206 ITIMER_SYNC(addr2,len,regs);
4207
4208 /* Translate addresses of leftmost operand bytes */
4209 dest1 = MADDRL (addr1, len+1, arn1, regs, ACCTYPE_WRITE_SKP, regs->psw.pkey);
4210 sk1 = regs->dat.storkey;
4211 source1 = MADDR (addr2, arn2, regs, ACCTYPE_READ, regs->psw.pkey);
4212
4213 /* There are several scenarios (in optimal order):
4214 * (1) dest boundary and source boundary not crossed
4215 * (2) dest boundary not crossed and source boundary crossed
4216 * (3) dest boundary crossed and source boundary not crossed
4217 * (4) dest boundary and source boundary are crossed
4218 * (a) dest and source boundary cross at the same time
4219 * (b) dest boundary crossed first
4220 * (c) source boundary crossed first
4221 */
4222
4223 if ( NOCROSS2K(addr1,len))
4224 {
4225 if ( NOCROSS2K(addr2,len))
4226 {
4227 /* (1) - No boundaries are crossed */
4228 for ( i = 0; i <= len; i++)
4229 MOVE_NUMERIC_BUMP(dest1,source1);
4230 }
4231 else
4232 {
4233 /* (2) - Second operand crosses a boundary */
4234 len2 = 0x800 - (addr2 & 0x7FF);
4235 source2 = MADDR ((addr2 + len2) & ADDRESS_MAXWRAP(regs),
4236 arn2, regs, ACCTYPE_READ, regs->psw.pkey);
4237 for ( i = 0; i < len2; i++)
4238 MOVE_NUMERIC_BUMP(dest1,source1);
4239 len2 = len - len2;
4240 for ( i = 0; i <= len2; i++)
4241 MOVE_NUMERIC_BUMP(dest1,source2);
4242 }
4243 *sk1 |= (STORKEY_REF | STORKEY_CHANGE);
4244 }
4245 else
4246 {
4247 /* First operand crosses a boundary */
4248 len2 = 0x800 - (addr1 & 0x7FF);
4249 dest2 = MADDR ((addr1 + len2) & ADDRESS_MAXWRAP(regs),
4250 arn1, regs, ACCTYPE_WRITE_SKP, regs->psw.pkey);
4251 sk2 = regs->dat.storkey;
4252
4253 if ( NOCROSS2K(addr2,len) )
4254 {
4255 /* (3) - First operand crosses a boundary */
4256 for ( i = 0; i < len2; i++)
4257 MOVE_NUMERIC_BUMP(dest1,source1);
4258 len2 = len - len2;
4259 for ( i = 0; i <= len2; i++)
4260 MOVE_NUMERIC_BUMP(dest2,source1);
4261 }
4262 else
4263 {
4264 /* (4) - Both operands cross a boundary */
4265 len3 = 0x800 - (addr2 & 0x7FF);
4266 source2 = MADDR ((addr2 + len3) & ADDRESS_MAXWRAP(regs),
4267 arn2, regs, ACCTYPE_READ, regs->psw.pkey);
4268 if (len2 == len3)
4269 {
4270 /* (4a) - Both operands cross at the same time */
4271 for ( i = 0; i < len2; i++)
4272 MOVE_NUMERIC_BUMP(dest1,source1);
4273 len2 = len - len2;
4274 for ( i = 0; i <= len2; i++)
4275 MOVE_NUMERIC_BUMP(dest2,source2);
4276 }
4277 else if (len2 < len3)
4278 {
4279 /* (4b) - First operand crosses first */
4280 for ( i = 0; i < len2; i++)
4281 MOVE_NUMERIC_BUMP(dest1,source1);
4282 len2 = len3 - len2;
4283 for ( i = 0; i < len2; i++)
4284 MOVE_NUMERIC_BUMP(dest2,source1);
4285 len2 = len - len3;
4286 for ( i = 0; i <= len2; i++)
4287 MOVE_NUMERIC_BUMP(dest2,source2);
4288 }
4289 else
4290 {
4291 /* (4c) - Second operand crosses first */
4292 for ( i = 0; i < len3; i++)
4293 MOVE_NUMERIC_BUMP(dest1,source1);
4294 len3 = len2 - len3;
4295 for ( i = 0; i < len3; i++)
4296 MOVE_NUMERIC_BUMP(dest1,source2);
4297 len3 = len - len2;
4298 for ( i = 0; i <= len3; i++)
4299 MOVE_NUMERIC_BUMP(dest2,source2);
4300 }
4301 }
4302 *sk1 |= (STORKEY_REF | STORKEY_CHANGE);
4303 *sk2 |= (STORKEY_REF | STORKEY_CHANGE);
4304 }
4305 ITIMER_UPDATE(addr1,len,regs);
4306 }
4307
4308
4309 #if defined(FEATURE_STRING_INSTRUCTION)
4310 /*-------------------------------------------------------------------*/
4311 /* B255 MVST - Move String [RRE] */
4312 /*-------------------------------------------------------------------*/
DEF_INST(move_string)4313 DEF_INST(move_string)
4314 {
4315 int r1, r2; /* Values of R fields */
4316 int i; /* Loop counter */
4317 VADR addr1, addr2; /* Operand addresses */
4318 BYTE sbyte; /* String character */
4319 BYTE termchar; /* Terminating character */
4320 int cpu_length; /* length to next page */
4321
4322 RRE(inst, regs, r1, r2);
4323
4324 /* Program check if bits 0-23 of register 0 not zero */
4325 if ((regs->GR_L(0) & 0xFFFFFF00) != 0)
4326 regs->program_interrupt (regs, PGM_SPECIFICATION_EXCEPTION);
4327
4328 /* Load string terminating character from register 0 bits 24-31 */
4329 termchar = regs->GR_LHLCL(0);
4330
4331 /* Determine the destination and source addresses */
4332 addr1 = regs->GR(r1) & ADDRESS_MAXWRAP(regs);
4333 addr2 = regs->GR(r2) & ADDRESS_MAXWRAP(regs);
4334
4335 /* set cpu_length as shortest distance to new page */
4336 if ((addr1 & 0xFFF) > (addr2 & 0xFFF))
4337 cpu_length = 0x1000 - (addr1 & 0xFFF);
4338 else
4339 cpu_length = 0x1000 - (addr2 & 0xFFF);
4340
4341 /* Move up to 4096 bytes until terminating character */
4342 for (i = 0; i < cpu_length; i++)
4343 {
4344 /* Fetch a byte from the source operand */
4345 sbyte = ARCH_DEP(vfetchb) ( addr2, r2, regs );
4346
4347 /* Store the byte in the destination operand */
4348 ARCH_DEP(vstoreb) ( sbyte, addr1, r1, regs );
4349
4350 /* Check if string terminating character was moved */
4351 if (sbyte == termchar)
4352 {
4353 /* Set r1 to point to terminating character */
4354 SET_GR_A(r1, regs,addr1);
4355
4356 /* Set condition code 1 */
4357 regs->psw.cc = 1;
4358 return;
4359 }
4360
4361 /* Increment operand addresses */
4362 addr1++;
4363 addr1 &= ADDRESS_MAXWRAP(regs);
4364 addr2++;
4365 addr2 &= ADDRESS_MAXWRAP(regs);
4366
4367 } /* end for(i) */
4368
4369 /* Set R1 and R2 to point to next character of each operand */
4370 SET_GR_A(r1, regs,addr1);
4371 SET_GR_A(r2, regs,addr2);
4372
4373 /* Set condition code 3 */
4374 regs->psw.cc = 3;
4375
4376 } /* end DEF_INST(move_string) */
4377 #endif /*defined(FEATURE_STRING_INSTRUCTION)*/
4378
4379
4380 /*-------------------------------------------------------------------*/
4381 /* F1 MVO - Move with Offset [SS] */
4382 /*-------------------------------------------------------------------*/
DEF_INST(move_with_offset)4383 DEF_INST(move_with_offset)
4384 {
4385 int l1, l2; /* Lenght values */
4386 int b1, b2; /* Values of base registers */
4387 VADR effective_addr1,
4388 effective_addr2; /* Effective addresses */
4389 int i, j; /* Loop counters */
4390 BYTE sbyte; /* Source operand byte */
4391 BYTE dbyte; /* Destination operand byte */
4392
4393 SS(inst, regs, l1, l2, b1, effective_addr1,
4394 b2, effective_addr2);
4395
4396 /* If operand 1 crosses a page, make sure both pages are accessable */
4397 if((effective_addr1 & PAGEFRAME_PAGEMASK) !=
4398 ((effective_addr1 + l1) & PAGEFRAME_PAGEMASK))
4399 ARCH_DEP(validate_operand) (effective_addr1, b1, l1, ACCTYPE_WRITE_SKP, regs);
4400
4401 /* If operand 2 crosses a page, make sure both pages are accessable */
4402 if((effective_addr2 & PAGEFRAME_PAGEMASK) !=
4403 ((effective_addr2 + l2) & PAGEFRAME_PAGEMASK))
4404 ARCH_DEP(validate_operand) (effective_addr2, b2, l2, ACCTYPE_READ, regs);
4405
4406 /* Fetch the rightmost byte from the source operand */
4407 effective_addr2 += l2;
4408 effective_addr2 &= ADDRESS_MAXWRAP(regs);
4409 sbyte = ARCH_DEP(vfetchb) ( effective_addr2--, b2, regs );
4410
4411 /* Fetch the rightmost byte from the destination operand */
4412 effective_addr1 += l1;
4413 effective_addr1 &= ADDRESS_MAXWRAP(regs);
4414 dbyte = ARCH_DEP(vfetchb) ( effective_addr1, b1, regs );
4415
4416 /* Move low digit of source byte to high digit of destination */
4417 dbyte &= 0x0F;
4418 dbyte |= sbyte << 4;
4419 ARCH_DEP(vstoreb) ( dbyte, effective_addr1--, b1, regs );
4420
4421 /* Process remaining bytes from right to left */
4422 for (i = l1, j = l2; i > 0; i--)
4423 {
4424 /* Move previous high digit to destination low digit */
4425 dbyte = sbyte >> 4;
4426
4427 /* Fetch next byte from second operand */
4428 if ( j-- > 0 ) {
4429 effective_addr2 &= ADDRESS_MAXWRAP(regs);
4430 sbyte = ARCH_DEP(vfetchb) ( effective_addr2--, b2, regs );
4431 }
4432 else
4433 sbyte = 0x00;
4434
4435 /* Move low digit to destination high digit */
4436 dbyte |= sbyte << 4;
4437 effective_addr1 &= ADDRESS_MAXWRAP(regs);
4438 ARCH_DEP(vstoreb) ( dbyte, effective_addr1--, b1, regs );
4439
4440 } /* end for(i) */
4441
4442 }
4443
4444 #define MOVE_ZONE_BUMP(_d,_s) \
4445 do { \
4446 *(_d)=( *(_d) & 0x0F) | ( *(_s) & 0xF0); \
4447 _d++; \
4448 _s++; \
4449 } while(0)
4450
4451 /*-------------------------------------------------------------------*/
4452 /* D3 MVZ - Move Zones [SS] */
4453 /*-------------------------------------------------------------------*/
DEF_INST(move_zones)4454 DEF_INST(move_zones)
4455 {
4456 VADR addr1, addr2; /* Operand virtual addresses */
4457 int len, arn1, arn2; /* Operand values */
4458 BYTE *dest1, *dest2; /* Destination addresses */
4459 BYTE *source1, *source2; /* Source addresses */
4460 BYTE *sk1, *sk2; /* Storage key addresses */
4461 int len2, len3; /* Lengths to copy */
4462 int i; /* Loop counter */
4463
4464 SS_L(inst, regs, len, arn1, addr1, arn2, addr2);
4465
4466 ITIMER_SYNC(addr2,len,regs);
4467
4468 /* Translate addresses of leftmost operand bytes */
4469 dest1 = MADDRL (addr1, len+1, arn1, regs, ACCTYPE_WRITE_SKP, regs->psw.pkey);
4470 sk1 = regs->dat.storkey;
4471 source1 = MADDR (addr2, arn2, regs, ACCTYPE_READ, regs->psw.pkey);
4472
4473 /* There are several scenarios (in optimal order):
4474 * (1) dest boundary and source boundary not crossed
4475 * (2) dest boundary not crossed and source boundary crossed
4476 * (3) dest boundary crossed and source boundary not crossed
4477 * (4) dest boundary and source boundary are crossed
4478 * (a) dest and source boundary cross at the same time
4479 * (b) dest boundary crossed first
4480 * (c) source boundary crossed first
4481 */
4482
4483 if ( NOCROSS2K(addr1,len) )
4484 {
4485 if ( NOCROSS2K(addr2,len) )
4486 {
4487 /* (1) - No boundaries are crossed */
4488 for ( i = 0; i <= len; i++)
4489 MOVE_ZONE_BUMP(dest1,source1);
4490 }
4491 else
4492 {
4493 /* (2) - Second operand crosses a boundary */
4494 len2 = 0x800 - (addr2 & 0x7FF);
4495 source2 = MADDR ((addr2 + len2) & ADDRESS_MAXWRAP(regs),
4496 arn2, regs, ACCTYPE_READ, regs->psw.pkey);
4497 for ( i = 0; i < len2; i++)
4498 MOVE_ZONE_BUMP(dest1,source1);
4499 len2 = len - len2;
4500 for ( i = 0; i <= len2; i++)
4501 MOVE_ZONE_BUMP(dest1,source2);
4502 }
4503 *sk1 |= (STORKEY_REF | STORKEY_CHANGE);
4504 }
4505 else
4506 {
4507 /* First operand crosses a boundary */
4508 len2 = 0x800 - (addr1 & 0x7FF);
4509 dest2 = MADDR ((addr1 + len2) & ADDRESS_MAXWRAP(regs),
4510 arn1, regs, ACCTYPE_WRITE_SKP, regs->psw.pkey);
4511 sk2 = regs->dat.storkey;
4512
4513 if ( NOCROSS2K(addr2,len) )
4514 {
4515 /* (3) - First operand crosses a boundary */
4516 for ( i = 0; i < len2; i++)
4517 MOVE_ZONE_BUMP(dest1,source1);
4518 len2 = len - len2;
4519 for ( i = 0; i <= len2; i++)
4520 MOVE_ZONE_BUMP(dest2,source1);
4521 }
4522 else
4523 {
4524 /* (4) - Both operands cross a boundary */
4525 len3 = 0x800 - (addr2 & 0x7FF);
4526 source2 = MADDR ((addr2 + len3) & ADDRESS_MAXWRAP(regs),
4527 arn2, regs, ACCTYPE_READ, regs->psw.pkey);
4528 if (len2 == len3)
4529 {
4530 /* (4a) - Both operands cross at the same time */
4531 for ( i = 0; i < len2; i++)
4532 MOVE_ZONE_BUMP(dest1,source1);
4533 len2 = len - len2;
4534 for ( i = 0; i <= len2; i++)
4535 MOVE_ZONE_BUMP(dest2,source2);
4536 }
4537 else if (len2 < len3)
4538 {
4539 /* (4b) - First operand crosses first */
4540 for ( i = 0; i < len2; i++)
4541 MOVE_ZONE_BUMP(dest1,source1);
4542 len2 = len3 - len2;
4543 for ( i = 0; i < len2; i++)
4544 MOVE_ZONE_BUMP(dest2,source1);
4545 len2 = len - len3;
4546 for ( i = 0; i <= len2; i++)
4547 MOVE_ZONE_BUMP(dest2,source2);
4548 }
4549 else
4550 {
4551 /* (4c) - Second operand crosses first */
4552 for ( i = 0; i < len3; i++)
4553 MOVE_ZONE_BUMP(dest1,source1);
4554 len3 = len2 - len3;
4555 for ( i = 0; i < len3; i++)
4556 MOVE_ZONE_BUMP(dest1,source2);
4557 len3 = len - len2;
4558 for ( i = 0; i <= len3; i++)
4559 MOVE_ZONE_BUMP(dest2,source2);
4560 }
4561 }
4562 *sk1 |= (STORKEY_REF | STORKEY_CHANGE);
4563 *sk2 |= (STORKEY_REF | STORKEY_CHANGE);
4564 }
4565 ITIMER_UPDATE(addr1,len,regs);
4566 }
4567
4568
4569 /*-------------------------------------------------------------------*/
4570 /* 1C MR - Multiply Register [RR] */
4571 /*-------------------------------------------------------------------*/
DEF_INST(multiply_register)4572 DEF_INST(multiply_register)
4573 {
4574 int r1, r2; /* Values of R fields */
4575
4576 RR(inst, regs, r1, r2);
4577
4578 ODD_CHECK(r1, regs);
4579
4580 /* Multiply r1+1 by r2 and place result in r1 and r1+1 */
4581 mul_signed (&(regs->GR_L(r1)),&(regs->GR_L(r1+1)),
4582 regs->GR_L(r1+1),
4583 regs->GR_L(r2));
4584 }
4585
4586
4587 /*-------------------------------------------------------------------*/
4588 /* 5C M - Multiply [RX] */
4589 /*-------------------------------------------------------------------*/
DEF_INST(multiply)4590 DEF_INST(multiply)
4591 {
4592 int r1; /* Value of R field */
4593 int b2; /* Base of effective addr */
4594 VADR effective_addr2; /* Effective address */
4595 U32 n; /* 32-bit operand values */
4596
4597 RX(inst, regs, r1, b2, effective_addr2);
4598
4599 ODD_CHECK(r1, regs);
4600
4601 /* Load second operand from operand address */
4602 n = ARCH_DEP(vfetch4) ( effective_addr2, b2, regs );
4603
4604 /* Multiply r1+1 by n and place result in r1 and r1+1 */
4605 mul_signed (&(regs->GR_L(r1)), &(regs->GR_L(r1+1)),
4606 regs->GR_L(r1+1),
4607 n);
4608
4609 }
4610
4611
4612 /*-------------------------------------------------------------------*/
4613 /* 4C MH - Multiply Halfword [RX] */
4614 /*-------------------------------------------------------------------*/
DEF_INST(multiply_halfword)4615 DEF_INST(multiply_halfword)
4616 {
4617 int r1; /* Value of R field */
4618 int b2; /* Base of effective addr */
4619 VADR effective_addr2; /* Effective address */
4620 S32 n; /* 32-bit operand values */
4621
4622 RX(inst, regs, r1, b2, effective_addr2);
4623
4624 /* Load 2 bytes from operand address */
4625 n = (S16)ARCH_DEP(vfetch2) ( effective_addr2, b2, regs );
4626
4627 /* Multiply R1 register by n, ignore leftmost 32 bits of
4628 result, and place rightmost 32 bits in R1 register */
4629 mul_signed ((U32 *)&n, &(regs->GR_L(r1)), regs->GR_L(r1), n);
4630
4631 }
4632
4633
4634 #if defined(FEATURE_IMMEDIATE_AND_RELATIVE)
4635 /*-------------------------------------------------------------------*/
4636 /* A7xC MHI - Multiply Halfword Immediate [RI] */
4637 /*-------------------------------------------------------------------*/
DEF_INST(multiply_halfword_immediate)4638 DEF_INST(multiply_halfword_immediate)
4639 {
4640 int r1; /* Register number */
4641 U16 i2; /* 16-bit operand */
4642
4643 RI0(inst, regs, r1, i2);
4644
4645 /* Multiply register by operand ignoring overflow */
4646 regs->GR_L(r1) = (S32)regs->GR_L(r1) * (S16)i2;
4647
4648 } /* end DEF_INST(multiply_halfword_immediate) */
4649
4650
4651 /*-------------------------------------------------------------------*/
4652 /* B252 MSR - Multiply Single Register [RRE] */
4653 /*-------------------------------------------------------------------*/
DEF_INST(multiply_single_register)4654 DEF_INST(multiply_single_register)
4655 {
4656 int r1, r2; /* Values of R fields */
4657
4658 RRE0(inst, regs, r1, r2);
4659
4660 /* Multiply signed registers ignoring overflow */
4661 regs->GR_L(r1) = (S32)regs->GR_L(r1) * (S32)regs->GR_L(r2);
4662
4663 } /* end DEF_INST(multiply_single_register) */
4664
4665
4666 /*-------------------------------------------------------------------*/
4667 /* 71 MS - Multiply Single [RX] */
4668 /*-------------------------------------------------------------------*/
DEF_INST(multiply_single)4669 DEF_INST(multiply_single)
4670 {
4671 int r1; /* Value of R field */
4672 int b2; /* Base of effective addr */
4673 VADR effective_addr2; /* Effective address */
4674 U32 n; /* 32-bit operand values */
4675
4676 RX(inst, regs, r1, b2, effective_addr2);
4677
4678 /* Load second operand from operand address */
4679 n = ARCH_DEP(vfetch4) ( effective_addr2, b2, regs );
4680
4681 /* Multiply signed operands ignoring overflow */
4682 regs->GR_L(r1) = (S32)regs->GR_L(r1) * (S32)n;
4683
4684 } /* end DEF_INST(multiply_single) */
4685 #endif /*defined(FEATURE_IMMEDIATE_AND_RELATIVE)*/
4686
4687
4688 #if !defined(_GEN_ARCH)
4689
4690 #if defined(_ARCHMODE2)
4691 #define _GEN_ARCH _ARCHMODE2
4692 #include "general1.c"
4693 #endif
4694
4695 #if defined(_ARCHMODE3)
4696 #undef _GEN_ARCH
4697 #define _GEN_ARCH _ARCHMODE3
4698 #include "general1.c"
4699 #endif
4700
4701 #endif /*!defined(_GEN_ARCH)*/
4702