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(&regs->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(&regs->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(&regs->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(&regs->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(&regs->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(&regs->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(&regs->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