blob: 0aece5b282188561d4363c35a7287bbd6c5d6ebb [file] [log] [blame]
sewardj2019a972011-03-07 16:04:07 +00001/* -*- mode: C; c-basic-offset: 3; -*- */
2
3/*---------------------------------------------------------------*/
4/*--- begin guest_s390_toIR.c ---*/
5/*---------------------------------------------------------------*/
6
7/*
8 This file is part of Valgrind, a dynamic binary instrumentation
9 framework.
10
florian61f23c12012-08-06 18:33:21 +000011 Copyright IBM Corp. 2010-2012
sewardj2019a972011-03-07 16:04:07 +000012
13 This program is free software; you can redistribute it and/or
14 modify it under the terms of the GNU General Public License as
15 published by the Free Software Foundation; either version 2 of the
16 License, or (at your option) any later version.
17
18 This program is distributed in the hope that it will be useful, but
19 WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 General Public License for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
26 02110-1301, USA.
27
28 The GNU General Public License is contained in the file COPYING.
29*/
30
31/* Contributed by Florian Krohm and Christian Borntraeger */
32
33/* Translates s390 code to IR. */
34
35#include "libvex_basictypes.h"
36#include "libvex_ir.h"
sewardj2019a972011-03-07 16:04:07 +000037#include "libvex.h" /* needed for bb_to_IR.h */
florian933065d2011-07-11 01:48:02 +000038#include "libvex_s390x_common.h"
sewardj2019a972011-03-07 16:04:07 +000039#include "main_util.h" /* vassert */
40#include "main_globals.h" /* vex_traceflags */
41#include "guest_generic_bb_to_IR.h" /* DisResult */
42#include "guest_s390_defs.h" /* prototypes for this file's functions */
43#include "host_s390_disasm.h"
44#include "host_s390_defs.h" /* S390_ROUND_xyzzy */
45
sewardj2019a972011-03-07 16:04:07 +000046
47/*------------------------------------------------------------*/
florianb4df7682011-07-05 02:09:01 +000048/*--- Forward declarations ---*/
49/*------------------------------------------------------------*/
50static UInt s390_decode_and_irgen(UChar *, UInt, DisResult *);
florianb0bf6602012-05-05 00:01:16 +000051static void s390_irgen_xonc(IROp, IRTemp, IRTemp, IRTemp);
florian79e839e2012-05-05 02:20:30 +000052static void s390_irgen_CLC_EX(IRTemp, IRTemp, IRTemp);
florianb4df7682011-07-05 02:09:01 +000053
54
55/*------------------------------------------------------------*/
sewardj2019a972011-03-07 16:04:07 +000056/*--- Globals ---*/
57/*------------------------------------------------------------*/
58
59/* The IRSB* into which we're generating code. */
60static IRSB *irsb;
61
62/* The guest address for the instruction currently being
63 translated. */
64static Addr64 guest_IA_curr_instr;
65
66/* The guest address for the instruction following the current instruction. */
67static Addr64 guest_IA_next_instr;
68
69/* Result of disassembly step. */
70static DisResult *dis_res;
71
floriana64c2432011-07-16 02:11:50 +000072/* Resteer function and callback data */
73static Bool (*resteer_fn)(void *, Addr64);
74static void *resteer_data;
75
sewardj2019a972011-03-07 16:04:07 +000076/* The last seen execute target instruction */
77ULong last_execute_target;
78
79/* The possible outcomes of a decoding operation */
80typedef enum {
81 S390_DECODE_OK,
82 S390_DECODE_UNKNOWN_INSN,
83 S390_DECODE_UNIMPLEMENTED_INSN,
84 S390_DECODE_UNKNOWN_SPECIAL_INSN,
85 S390_DECODE_ERROR
86} s390_decode_t;
87
florian428dfdd2012-03-27 03:09:49 +000088
sewardj2019a972011-03-07 16:04:07 +000089/*------------------------------------------------------------*/
90/*--- Helpers for constructing IR. ---*/
91/*------------------------------------------------------------*/
92
93/* Sign extend a value with the given number of bits. This is a
94 macro because it allows us to overload the type of the value.
95 Note that VALUE must have a signed type! */
96#undef sign_extend
97#define sign_extend(value,num_bits) \
98(((value) << (sizeof(__typeof__(value)) * 8 - (num_bits))) >> \
99 (sizeof(__typeof__(value)) * 8 - (num_bits)))
100
101
102/* Add a statement to the current irsb. */
103static __inline__ void
104stmt(IRStmt *st)
105{
106 addStmtToIRSB(irsb, st);
107}
108
109/* Allocate a new temporary of the given type. */
110static __inline__ IRTemp
111newTemp(IRType type)
112{
113 vassert(isPlausibleIRType(type));
114
115 return newIRTemp(irsb->tyenv, type);
116}
117
118/* Create an expression node for a temporary */
119static __inline__ IRExpr *
120mkexpr(IRTemp tmp)
121{
122 return IRExpr_RdTmp(tmp);
123}
124
florian8844a632012-04-13 04:04:06 +0000125/* Generate an expression node for an address. */
126static __inline__ IRExpr *
127mkaddr_expr(Addr64 addr)
128{
129 return IRExpr_Const(IRConst_U64(addr));
130}
131
sewardj2019a972011-03-07 16:04:07 +0000132/* Add a statement that assigns to a temporary */
133static __inline__ void
134assign(IRTemp dst, IRExpr *expr)
135{
136 stmt(IRStmt_WrTmp(dst, expr));
137}
138
florian8844a632012-04-13 04:04:06 +0000139/* Write an address into the guest_IA */
140static __inline__ void
141put_IA(IRExpr *address)
142{
143 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_IA), address));
144}
145
sewardj2019a972011-03-07 16:04:07 +0000146/* Create a temporary of the given type and assign the expression to it */
147static __inline__ IRTemp
148mktemp(IRType type, IRExpr *expr)
149{
150 IRTemp temp = newTemp(type);
151
152 assign(temp, expr);
153
154 return temp;
155}
156
157/* Create a unary expression */
158static __inline__ IRExpr *
159unop(IROp kind, IRExpr *op)
160{
161 return IRExpr_Unop(kind, op);
162}
163
164/* Create a binary expression */
165static __inline__ IRExpr *
166binop(IROp kind, IRExpr *op1, IRExpr *op2)
167{
168 return IRExpr_Binop(kind, op1, op2);
169}
170
171/* Create a ternary expression */
172static __inline__ IRExpr *
173triop(IROp kind, IRExpr *op1, IRExpr *op2, IRExpr *op3)
174{
175 return IRExpr_Triop(kind, op1, op2, op3);
176}
177
178/* Create a quaternary expression */
179static __inline__ IRExpr *
180qop(IROp kind, IRExpr *op1, IRExpr *op2, IRExpr *op3, IRExpr *op4)
181{
182 return IRExpr_Qop(kind, op1, op2, op3, op4);
183}
184
185/* Create an expression node for an 8-bit integer constant */
186static __inline__ IRExpr *
187mkU8(UInt value)
188{
189 vassert(value < 256);
190
191 return IRExpr_Const(IRConst_U8((UChar)value));
192}
193
194/* Create an expression node for a 16-bit integer constant */
195static __inline__ IRExpr *
196mkU16(UInt value)
197{
198 vassert(value < 65536);
199
200 return IRExpr_Const(IRConst_U16((UShort)value));
201}
202
203/* Create an expression node for a 32-bit integer constant */
204static __inline__ IRExpr *
205mkU32(UInt value)
206{
207 return IRExpr_Const(IRConst_U32(value));
208}
209
210/* Create an expression node for a 64-bit integer constant */
211static __inline__ IRExpr *
212mkU64(ULong value)
213{
214 return IRExpr_Const(IRConst_U64(value));
215}
216
217/* Create an expression node for a 32-bit floating point constant
218 whose value is given by a bit pattern. */
219static __inline__ IRExpr *
220mkF32i(UInt value)
221{
222 return IRExpr_Const(IRConst_F32i(value));
223}
224
225/* Create an expression node for a 32-bit floating point constant
226 whose value is given by a bit pattern. */
227static __inline__ IRExpr *
228mkF64i(ULong value)
229{
230 return IRExpr_Const(IRConst_F64i(value));
231}
232
233/* Little helper function for my sanity. ITE = if-then-else */
234static IRExpr *
235mkite(IRExpr *condition, IRExpr *iftrue, IRExpr *iffalse)
236{
237 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
238
239 return IRExpr_Mux0X(unop(Iop_1Uto8, condition), iffalse, iftrue);
240}
241
242/* Add a statement that stores DATA at ADDR. This is a big-endian machine. */
243static void __inline__
244store(IRExpr *addr, IRExpr *data)
245{
246 stmt(IRStmt_Store(Iend_BE, addr, data));
247}
248
249/* Create an expression that loads a TYPE sized value from ADDR.
250 This is a big-endian machine. */
251static __inline__ IRExpr *
252load(IRType type, IRExpr *addr)
253{
254 return IRExpr_Load(Iend_BE, type, addr);
255}
256
257/* Function call */
258static void
259call_function(IRExpr *callee_address)
260{
florian8844a632012-04-13 04:04:06 +0000261 put_IA(callee_address);
sewardj2019a972011-03-07 16:04:07 +0000262
florian8844a632012-04-13 04:04:06 +0000263 dis_res->whatNext = Dis_StopHere;
264 dis_res->jk_StopHere = Ijk_Call;
sewardj2019a972011-03-07 16:04:07 +0000265}
266
floriana64c2432011-07-16 02:11:50 +0000267/* Function call with known target. */
268static void
269call_function_and_chase(Addr64 callee_address)
270{
271 if (resteer_fn(resteer_data, callee_address)) {
272 dis_res->whatNext = Dis_ResteerU;
273 dis_res->continueAt = callee_address;
274 } else {
florian8844a632012-04-13 04:04:06 +0000275 put_IA(mkaddr_expr(callee_address));
276
floriana64c2432011-07-16 02:11:50 +0000277 dis_res->whatNext = Dis_StopHere;
florian8844a632012-04-13 04:04:06 +0000278 dis_res->jk_StopHere = Ijk_Call;
floriana64c2432011-07-16 02:11:50 +0000279 }
280}
281
sewardj2019a972011-03-07 16:04:07 +0000282/* Function return sequence */
283static void
284return_from_function(IRExpr *return_address)
285{
florian8844a632012-04-13 04:04:06 +0000286 put_IA(return_address);
sewardj2019a972011-03-07 16:04:07 +0000287
florian8844a632012-04-13 04:04:06 +0000288 dis_res->whatNext = Dis_StopHere;
289 dis_res->jk_StopHere = Ijk_Ret;
sewardj2019a972011-03-07 16:04:07 +0000290}
291
292/* A conditional branch whose target is not known at instrumentation time.
293
294 if (condition) goto computed_target;
295
296 Needs to be represented as:
297
298 if (! condition) goto next_instruction;
299 goto computed_target;
sewardj2019a972011-03-07 16:04:07 +0000300*/
301static void
florianf321da72012-07-21 20:32:57 +0000302if_condition_goto_computed(IRExpr *condition, IRExpr *target)
sewardj2019a972011-03-07 16:04:07 +0000303{
304 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
305
florianf321da72012-07-21 20:32:57 +0000306 condition = unop(Iop_Not1, condition);
307
florian8844a632012-04-13 04:04:06 +0000308 stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(guest_IA_next_instr),
309 S390X_GUEST_OFFSET(guest_IA)));
sewardj2019a972011-03-07 16:04:07 +0000310
florian8844a632012-04-13 04:04:06 +0000311 put_IA(target);
sewardj2019a972011-03-07 16:04:07 +0000312
florian8844a632012-04-13 04:04:06 +0000313 dis_res->whatNext = Dis_StopHere;
314 dis_res->jk_StopHere = Ijk_Boring;
sewardj2019a972011-03-07 16:04:07 +0000315}
316
317/* A conditional branch whose target is known at instrumentation time. */
318static void
319if_condition_goto(IRExpr *condition, Addr64 target)
320{
321 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
322
florian8844a632012-04-13 04:04:06 +0000323 stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(target),
324 S390X_GUEST_OFFSET(guest_IA)));
325
florian7346c7a2012-04-13 21:14:24 +0000326 put_IA(mkaddr_expr(guest_IA_next_instr));
florian8844a632012-04-13 04:04:06 +0000327
328 dis_res->whatNext = Dis_StopHere;
329 dis_res->jk_StopHere = Ijk_Boring;
sewardj2019a972011-03-07 16:04:07 +0000330}
331
332/* An unconditional branch. Target may or may not be known at instrumentation
333 time. */
334static void
335always_goto(IRExpr *target)
336{
florian8844a632012-04-13 04:04:06 +0000337 put_IA(target);
sewardj2019a972011-03-07 16:04:07 +0000338
florian8844a632012-04-13 04:04:06 +0000339 dis_res->whatNext = Dis_StopHere;
340 dis_res->jk_StopHere = Ijk_Boring;
sewardj2019a972011-03-07 16:04:07 +0000341}
342
florian8844a632012-04-13 04:04:06 +0000343
floriana64c2432011-07-16 02:11:50 +0000344/* An unconditional branch to a known target. */
345static void
346always_goto_and_chase(Addr64 target)
347{
348 if (resteer_fn(resteer_data, target)) {
florian8844a632012-04-13 04:04:06 +0000349 /* Follow into the target */
floriana64c2432011-07-16 02:11:50 +0000350 dis_res->whatNext = Dis_ResteerU;
351 dis_res->continueAt = target;
352 } else {
florian8844a632012-04-13 04:04:06 +0000353 put_IA(mkaddr_expr(target));
354
355 dis_res->whatNext = Dis_StopHere;
356 dis_res->jk_StopHere = Ijk_Boring;
floriana64c2432011-07-16 02:11:50 +0000357 }
358}
359
sewardj2019a972011-03-07 16:04:07 +0000360/* A system call */
361static void
362system_call(IRExpr *sysno)
363{
364 /* Store the system call number in the pseudo register. */
florian428dfdd2012-03-27 03:09:49 +0000365 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_SYSNO), sysno));
sewardj2019a972011-03-07 16:04:07 +0000366
sewardj69007022011-04-28 20:13:45 +0000367 /* Store the current IA into guest_IP_AT_SYSCALL. libvex_ir.h says so. */
florian428dfdd2012-03-27 03:09:49 +0000368 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_IP_AT_SYSCALL),
369 mkU64(guest_IA_curr_instr)));
sewardj2019a972011-03-07 16:04:07 +0000370
florian8844a632012-04-13 04:04:06 +0000371 put_IA(mkaddr_expr(guest_IA_next_instr));
372
sewardj2019a972011-03-07 16:04:07 +0000373 /* It's important that all ArchRegs carry their up-to-date value
374 at this point. So we declare an end-of-block here, which
375 forces any TempRegs caching ArchRegs to be flushed. */
florian8844a632012-04-13 04:04:06 +0000376 dis_res->whatNext = Dis_StopHere;
377 dis_res->jk_StopHere = Ijk_Sys_syscall;
sewardj2019a972011-03-07 16:04:07 +0000378}
379
florian6820ba52012-07-26 02:01:50 +0000380/* A side exit that branches back to the current insn if CONDITION is
381 true. Does not set DisResult. */
382static void
383iterate_if(IRExpr *condition)
384{
385 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
386
387 stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(guest_IA_curr_instr),
388 S390X_GUEST_OFFSET(guest_IA)));
389}
390
391/* A side exit that branches back to the current insn.
392 Does not set DisResult. */
393static __inline__ void
394iterate(void)
395{
396 iterate_if(IRExpr_Const(IRConst_U1(True)));
397}
398
399/* A side exit that branches back to the insn immediately following the
400 current insn if CONDITION is true. Does not set DisResult. */
401static void
402next_insn_if(IRExpr *condition)
403{
404 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
405
406 stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(guest_IA_next_instr),
407 S390X_GUEST_OFFSET(guest_IA)));
408}
409
410/* Convenience function to restart the current insn */
411static void
412restart_if(IRExpr *condition)
413{
414 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
415
416 stmt(IRStmt_Exit(condition, Ijk_TInval, IRConst_U64(guest_IA_curr_instr),
417 S390X_GUEST_OFFSET(guest_IA)));
418}
419
420/* Convenience function to yield to thread scheduler */
421static void
422yield_if(IRExpr *condition)
423{
424 stmt(IRStmt_Exit(condition, Ijk_Yield, IRConst_U64(guest_IA_next_instr),
425 S390X_GUEST_OFFSET(guest_IA)));
426}
427
sewardj2019a972011-03-07 16:04:07 +0000428/* Encode the s390 rounding mode as it appears in the m3/m4 fields of certain
429 instructions to VEX's IRRoundingMode. */
430static IRRoundingMode
431encode_rounding_mode(UChar mode)
432{
433 switch (mode) {
434 case S390_ROUND_NEAREST_EVEN: return Irrm_NEAREST;
435 case S390_ROUND_ZERO: return Irrm_ZERO;
436 case S390_ROUND_POSINF: return Irrm_PosINF;
437 case S390_ROUND_NEGINF: return Irrm_NegINF;
438 }
439 vpanic("encode_rounding_mode");
440}
441
442static __inline__ IRExpr *get_fpr_dw0(UInt);
443static __inline__ void put_fpr_dw0(UInt, IRExpr *);
444
445/* Read a floating point register pair and combine their contents into a
446 128-bit value */
447static IRExpr *
448get_fpr_pair(UInt archreg)
449{
450 IRExpr *high = get_fpr_dw0(archreg);
451 IRExpr *low = get_fpr_dw0(archreg + 2);
452
453 return binop(Iop_F64HLtoF128, high, low);
454}
455
456/* Write a 128-bit floating point value into a register pair. */
457static void
458put_fpr_pair(UInt archreg, IRExpr *expr)
459{
460 IRExpr *high = unop(Iop_F128HItoF64, expr);
461 IRExpr *low = unop(Iop_F128LOtoF64, expr);
462
463 put_fpr_dw0(archreg, high);
464 put_fpr_dw0(archreg + 2, low);
465}
466
467
sewardj2019a972011-03-07 16:04:07 +0000468/*------------------------------------------------------------*/
florianf3410f92012-08-03 18:41:58 +0000469/*--- IR Debugging aids. ---*/
470/*------------------------------------------------------------*/
471#if 0
472
473static ULong
474s390_do_print(HChar *text, ULong value)
475{
476 vex_printf("%s %llu\n", text, value);
477 return 0;
478}
479
480static void
481s390_print(HChar *text, IRExpr *value)
482{
483 IRDirty *d;
484
485 d = unsafeIRDirty_0_N(0 /* regparms */, "s390_do_print", &s390_do_print,
486 mkIRExprVec_2(mkU64((ULong)text), value));
487 stmt(IRStmt_Dirty(d));
488}
489#endif
490
491
492/*------------------------------------------------------------*/
sewardj2019a972011-03-07 16:04:07 +0000493/*--- Build the flags thunk. ---*/
494/*------------------------------------------------------------*/
495
496/* Completely fill the flags thunk. We're always filling all fields.
497 Apparently, that is better for redundant PUT elimination. */
498static void
499s390_cc_thunk_fill(IRExpr *op, IRExpr *dep1, IRExpr *dep2, IRExpr *ndep)
500{
501 UInt op_off, dep1_off, dep2_off, ndep_off;
502
florian428dfdd2012-03-27 03:09:49 +0000503 op_off = S390X_GUEST_OFFSET(guest_CC_OP);
504 dep1_off = S390X_GUEST_OFFSET(guest_CC_DEP1);
505 dep2_off = S390X_GUEST_OFFSET(guest_CC_DEP2);
506 ndep_off = S390X_GUEST_OFFSET(guest_CC_NDEP);
sewardj2019a972011-03-07 16:04:07 +0000507
508 stmt(IRStmt_Put(op_off, op));
509 stmt(IRStmt_Put(dep1_off, dep1));
510 stmt(IRStmt_Put(dep2_off, dep2));
511 stmt(IRStmt_Put(ndep_off, ndep));
512}
513
514
515/* Create an expression for V and widen the result to 64 bit. */
516static IRExpr *
517s390_cc_widen(IRTemp v, Bool sign_extend)
518{
519 IRExpr *expr;
520
521 expr = mkexpr(v);
522
523 switch (typeOfIRTemp(irsb->tyenv, v)) {
524 case Ity_I64:
525 break;
526 case Ity_I32:
527 expr = unop(sign_extend ? Iop_32Sto64 : Iop_32Uto64, expr);
528 break;
529 case Ity_I16:
530 expr = unop(sign_extend ? Iop_16Sto64 : Iop_16Uto64, expr);
531 break;
532 case Ity_I8:
533 expr = unop(sign_extend ? Iop_8Sto64 : Iop_8Uto64, expr);
534 break;
535 default:
536 vpanic("s390_cc_widen");
537 }
538
539 return expr;
540}
541
542static void
543s390_cc_thunk_put1(UInt opc, IRTemp d1, Bool sign_extend)
544{
545 IRExpr *op, *dep1, *dep2, *ndep;
546
547 op = mkU64(opc);
548 dep1 = s390_cc_widen(d1, sign_extend);
549 dep2 = mkU64(0);
550 ndep = mkU64(0);
551
552 s390_cc_thunk_fill(op, dep1, dep2, ndep);
553}
554
555
556static void
557s390_cc_thunk_put2(UInt opc, IRTemp d1, IRTemp d2, Bool sign_extend)
558{
559 IRExpr *op, *dep1, *dep2, *ndep;
560
561 op = mkU64(opc);
562 dep1 = s390_cc_widen(d1, sign_extend);
563 dep2 = s390_cc_widen(d2, sign_extend);
564 ndep = mkU64(0);
565
566 s390_cc_thunk_fill(op, dep1, dep2, ndep);
567}
568
569
570/* memcheck believes that the NDEP field in the flags thunk is always
571 defined. But for some flag computations (e.g. add with carry) that is
572 just not true. We therefore need to convey to memcheck that the value
573 of the ndep field does matter and therefore we make the DEP2 field
574 depend on it:
575
576 DEP2 = original_DEP2 ^ NDEP
577
578 In s390_calculate_cc we exploit that (a^b)^b == a
579 I.e. we xor the DEP2 value with the NDEP value to recover the
580 original_DEP2 value. */
581static void
582s390_cc_thunk_put3(UInt opc, IRTemp d1, IRTemp d2, IRTemp nd, Bool sign_extend)
583{
584 IRExpr *op, *dep1, *dep2, *ndep, *dep2x;
585
586 op = mkU64(opc);
587 dep1 = s390_cc_widen(d1, sign_extend);
588 dep2 = s390_cc_widen(d2, sign_extend);
589 ndep = s390_cc_widen(nd, sign_extend);
590
591 dep2x = binop(Iop_Xor64, dep2, ndep);
592
593 s390_cc_thunk_fill(op, dep1, dep2x, ndep);
594}
595
596
597/* Write one floating point value into the flags thunk */
598static void
599s390_cc_thunk_put1f(UInt opc, IRTemp d1)
600{
601 IRExpr *op, *dep1, *dep2, *ndep;
602
603 op = mkU64(opc);
604 dep1 = mkexpr(d1);
605 dep2 = mkU64(0);
606 ndep = mkU64(0);
607
608 s390_cc_thunk_fill(op, dep1, dep2, ndep);
609}
610
611
612/* Write a floating point value and an integer into the flags thunk. The
613 integer value is zero-extended first. */
614static void
615s390_cc_thunk_putFZ(UInt opc, IRTemp d1, IRTemp d2)
616{
617 IRExpr *op, *dep1, *dep2, *ndep;
618
619 op = mkU64(opc);
620 dep1 = mkexpr(d1);
621 dep2 = s390_cc_widen(d2, False);
622 ndep = mkU64(0);
623
624 s390_cc_thunk_fill(op, dep1, dep2, ndep);
625}
626
627
628/* Write a 128-bit floating point value into the flags thunk. This is
629 done by splitting the value into two 64-bits values. */
630static void
631s390_cc_thunk_put1f128(UInt opc, IRTemp d1)
632{
633 IRExpr *op, *hi, *lo, *ndep;
634
635 op = mkU64(opc);
636 hi = unop(Iop_F128HItoF64, mkexpr(d1));
637 lo = unop(Iop_F128LOtoF64, mkexpr(d1));
638 ndep = mkU64(0);
639
640 s390_cc_thunk_fill(op, hi, lo, ndep);
641}
642
643
644/* Write a 128-bit floating point value and an integer into the flags thunk.
645 The integer value is zero-extended first. */
646static void
647s390_cc_thunk_put1f128Z(UInt opc, IRTemp d1, IRTemp nd)
648{
649 IRExpr *op, *hi, *lo, *lox, *ndep;
650
651 op = mkU64(opc);
652 hi = unop(Iop_F128HItoF64, mkexpr(d1));
653 lo = unop(Iop_ReinterpF64asI64, unop(Iop_F128LOtoF64, mkexpr(d1)));
654 ndep = s390_cc_widen(nd, False);
655
656 lox = binop(Iop_Xor64, lo, ndep); /* convey dependency */
657
658 s390_cc_thunk_fill(op, hi, lox, ndep);
659}
660
661
662static void
663s390_cc_set(UInt val)
664{
665 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
666 mkU64(val), mkU64(0), mkU64(0));
667}
668
669/* Build IR to calculate the condition code from flags thunk.
670 Returns an expression of type Ity_I32 */
671static IRExpr *
672s390_call_calculate_cc(void)
673{
674 IRExpr **args, *call, *op, *dep1, *dep2, *ndep;
675
florian428dfdd2012-03-27 03:09:49 +0000676 op = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_OP), Ity_I64);
677 dep1 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP1), Ity_I64);
678 dep2 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP2), Ity_I64);
679 ndep = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_NDEP), Ity_I64);
sewardj2019a972011-03-07 16:04:07 +0000680
681 args = mkIRExprVec_4(op, dep1, dep2, ndep);
682 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
683 "s390_calculate_cc", &s390_calculate_cc, args);
684
685 /* Exclude OP and NDEP from definedness checking. We're only
686 interested in DEP1 and DEP2. */
687 call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<3);
688
689 return call;
690}
691
692/* Build IR to calculate the internal condition code for a "compare and branch"
693 insn. Returns an expression of type Ity_I32 */
694static IRExpr *
florianff9613f2012-05-12 15:26:44 +0000695s390_call_calculate_icc(UInt m, UInt opc, IRTemp op1, IRTemp op2)
sewardj2019a972011-03-07 16:04:07 +0000696{
florianff9613f2012-05-12 15:26:44 +0000697 IRExpr **args, *call, *op, *dep1, *dep2, *mask;
sewardj2019a972011-03-07 16:04:07 +0000698
florianff9613f2012-05-12 15:26:44 +0000699 switch (opc) {
700 case S390_CC_OP_SIGNED_COMPARE:
701 dep1 = s390_cc_widen(op1, True);
702 dep2 = s390_cc_widen(op2, True);
703 break;
704
705 case S390_CC_OP_UNSIGNED_COMPARE:
706 dep1 = s390_cc_widen(op1, False);
707 dep2 = s390_cc_widen(op2, False);
708 break;
709
710 default:
711 vpanic("s390_call_calculate_icc");
712 }
713
714 mask = mkU64(m);
sewardj2019a972011-03-07 16:04:07 +0000715 op = mkU64(opc);
sewardj2019a972011-03-07 16:04:07 +0000716
florianff9613f2012-05-12 15:26:44 +0000717 args = mkIRExprVec_5(mask, op, dep1, dep2, mkU64(0) /* unused */);
sewardj2019a972011-03-07 16:04:07 +0000718 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
florianff9613f2012-05-12 15:26:44 +0000719 "s390_calculate_cond", &s390_calculate_cond, args);
sewardj2019a972011-03-07 16:04:07 +0000720
florianff9613f2012-05-12 15:26:44 +0000721 /* Exclude the requested condition, OP and NDEP from definedness
722 checking. We're only interested in DEP1 and DEP2. */
723 call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<1) | (1<<4);
sewardj2019a972011-03-07 16:04:07 +0000724
725 return call;
726}
727
728/* Build IR to calculate the condition code from flags thunk.
729 Returns an expression of type Ity_I32 */
730static IRExpr *
731s390_call_calculate_cond(UInt m)
732{
733 IRExpr **args, *call, *op, *dep1, *dep2, *ndep, *mask;
734
735 mask = mkU64(m);
florian428dfdd2012-03-27 03:09:49 +0000736 op = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_OP), Ity_I64);
737 dep1 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP1), Ity_I64);
738 dep2 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP2), Ity_I64);
739 ndep = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_NDEP), Ity_I64);
sewardj2019a972011-03-07 16:04:07 +0000740
741 args = mkIRExprVec_5(mask, op, dep1, dep2, ndep);
742 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
743 "s390_calculate_cond", &s390_calculate_cond, args);
744
745 /* Exclude the requested condition, OP and NDEP from definedness
746 checking. We're only interested in DEP1 and DEP2. */
747 call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<1) | (1<<4);
748
749 return call;
750}
751
752#define s390_cc_thunk_putZ(op,dep1) s390_cc_thunk_put1(op,dep1,False)
753#define s390_cc_thunk_putS(op,dep1) s390_cc_thunk_put1(op,dep1,True)
754#define s390_cc_thunk_putF(op,dep1) s390_cc_thunk_put1f(op,dep1)
755#define s390_cc_thunk_putZZ(op,dep1,dep2) s390_cc_thunk_put2(op,dep1,dep2,False)
756#define s390_cc_thunk_putSS(op,dep1,dep2) s390_cc_thunk_put2(op,dep1,dep2,True)
757#define s390_cc_thunk_putFF(op,dep1,dep2) s390_cc_thunk_put2f(op,dep1,dep2)
758#define s390_cc_thunk_putZZZ(op,dep1,dep2,ndep) \
759 s390_cc_thunk_put3(op,dep1,dep2,ndep,False)
760#define s390_cc_thunk_putSSS(op,dep1,dep2,ndep) \
761 s390_cc_thunk_put3(op,dep1,dep2,ndep,True)
sewardj2019a972011-03-07 16:04:07 +0000762
763
sewardj2019a972011-03-07 16:04:07 +0000764
765
766/*------------------------------------------------------------*/
767/*--- Guest register access ---*/
768/*------------------------------------------------------------*/
769
770
771/*------------------------------------------------------------*/
772/*--- ar registers ---*/
773/*------------------------------------------------------------*/
774
775/* Return the guest state offset of a ar register. */
776static UInt
777ar_offset(UInt archreg)
778{
779 static const UInt offset[16] = {
floriane88b3c92011-07-05 02:48:39 +0000780 S390X_GUEST_OFFSET(guest_a0),
781 S390X_GUEST_OFFSET(guest_a1),
782 S390X_GUEST_OFFSET(guest_a2),
783 S390X_GUEST_OFFSET(guest_a3),
784 S390X_GUEST_OFFSET(guest_a4),
785 S390X_GUEST_OFFSET(guest_a5),
786 S390X_GUEST_OFFSET(guest_a6),
787 S390X_GUEST_OFFSET(guest_a7),
788 S390X_GUEST_OFFSET(guest_a8),
789 S390X_GUEST_OFFSET(guest_a9),
790 S390X_GUEST_OFFSET(guest_a10),
791 S390X_GUEST_OFFSET(guest_a11),
792 S390X_GUEST_OFFSET(guest_a12),
793 S390X_GUEST_OFFSET(guest_a13),
794 S390X_GUEST_OFFSET(guest_a14),
795 S390X_GUEST_OFFSET(guest_a15),
sewardj2019a972011-03-07 16:04:07 +0000796 };
797
798 vassert(archreg < 16);
799
800 return offset[archreg];
801}
802
803
804/* Return the guest state offset of word #0 of a ar register. */
805static __inline__ UInt
806ar_w0_offset(UInt archreg)
807{
808 return ar_offset(archreg) + 0;
809}
810
811/* Write word #0 of a ar to the guest state. */
812static __inline__ void
813put_ar_w0(UInt archreg, IRExpr *expr)
814{
815 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
816
817 stmt(IRStmt_Put(ar_w0_offset(archreg), expr));
818}
819
820/* Read word #0 of a ar register. */
821static __inline__ IRExpr *
822get_ar_w0(UInt archreg)
823{
824 return IRExpr_Get(ar_w0_offset(archreg), Ity_I32);
825}
826
827
828/*------------------------------------------------------------*/
829/*--- fpr registers ---*/
830/*------------------------------------------------------------*/
831
832/* Return the guest state offset of a fpr register. */
833static UInt
834fpr_offset(UInt archreg)
835{
836 static const UInt offset[16] = {
floriane88b3c92011-07-05 02:48:39 +0000837 S390X_GUEST_OFFSET(guest_f0),
838 S390X_GUEST_OFFSET(guest_f1),
839 S390X_GUEST_OFFSET(guest_f2),
840 S390X_GUEST_OFFSET(guest_f3),
841 S390X_GUEST_OFFSET(guest_f4),
842 S390X_GUEST_OFFSET(guest_f5),
843 S390X_GUEST_OFFSET(guest_f6),
844 S390X_GUEST_OFFSET(guest_f7),
845 S390X_GUEST_OFFSET(guest_f8),
846 S390X_GUEST_OFFSET(guest_f9),
847 S390X_GUEST_OFFSET(guest_f10),
848 S390X_GUEST_OFFSET(guest_f11),
849 S390X_GUEST_OFFSET(guest_f12),
850 S390X_GUEST_OFFSET(guest_f13),
851 S390X_GUEST_OFFSET(guest_f14),
852 S390X_GUEST_OFFSET(guest_f15),
sewardj2019a972011-03-07 16:04:07 +0000853 };
854
855 vassert(archreg < 16);
856
857 return offset[archreg];
858}
859
860
861/* Return the guest state offset of word #0 of a fpr register. */
862static __inline__ UInt
863fpr_w0_offset(UInt archreg)
864{
865 return fpr_offset(archreg) + 0;
866}
867
868/* Write word #0 of a fpr to the guest state. */
869static __inline__ void
870put_fpr_w0(UInt archreg, IRExpr *expr)
871{
872 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_F32);
873
874 stmt(IRStmt_Put(fpr_w0_offset(archreg), expr));
875}
876
877/* Read word #0 of a fpr register. */
878static __inline__ IRExpr *
879get_fpr_w0(UInt archreg)
880{
881 return IRExpr_Get(fpr_w0_offset(archreg), Ity_F32);
882}
883
884/* Return the guest state offset of double word #0 of a fpr register. */
885static __inline__ UInt
886fpr_dw0_offset(UInt archreg)
887{
888 return fpr_offset(archreg) + 0;
889}
890
891/* Write double word #0 of a fpr to the guest state. */
892static __inline__ void
893put_fpr_dw0(UInt archreg, IRExpr *expr)
894{
895 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_F64);
896
897 stmt(IRStmt_Put(fpr_dw0_offset(archreg), expr));
898}
899
900/* Read double word #0 of a fpr register. */
901static __inline__ IRExpr *
902get_fpr_dw0(UInt archreg)
903{
904 return IRExpr_Get(fpr_dw0_offset(archreg), Ity_F64);
905}
906
907
908/*------------------------------------------------------------*/
909/*--- gpr registers ---*/
910/*------------------------------------------------------------*/
911
912/* Return the guest state offset of a gpr register. */
913static UInt
914gpr_offset(UInt archreg)
915{
916 static const UInt offset[16] = {
floriane88b3c92011-07-05 02:48:39 +0000917 S390X_GUEST_OFFSET(guest_r0),
918 S390X_GUEST_OFFSET(guest_r1),
919 S390X_GUEST_OFFSET(guest_r2),
920 S390X_GUEST_OFFSET(guest_r3),
921 S390X_GUEST_OFFSET(guest_r4),
922 S390X_GUEST_OFFSET(guest_r5),
923 S390X_GUEST_OFFSET(guest_r6),
924 S390X_GUEST_OFFSET(guest_r7),
925 S390X_GUEST_OFFSET(guest_r8),
926 S390X_GUEST_OFFSET(guest_r9),
927 S390X_GUEST_OFFSET(guest_r10),
928 S390X_GUEST_OFFSET(guest_r11),
929 S390X_GUEST_OFFSET(guest_r12),
930 S390X_GUEST_OFFSET(guest_r13),
931 S390X_GUEST_OFFSET(guest_r14),
932 S390X_GUEST_OFFSET(guest_r15),
sewardj2019a972011-03-07 16:04:07 +0000933 };
934
935 vassert(archreg < 16);
936
937 return offset[archreg];
938}
939
940
941/* Return the guest state offset of word #0 of a gpr register. */
942static __inline__ UInt
943gpr_w0_offset(UInt archreg)
944{
945 return gpr_offset(archreg) + 0;
946}
947
948/* Write word #0 of a gpr to the guest state. */
949static __inline__ void
950put_gpr_w0(UInt archreg, IRExpr *expr)
951{
952 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
953
954 stmt(IRStmt_Put(gpr_w0_offset(archreg), expr));
955}
956
957/* Read word #0 of a gpr register. */
958static __inline__ IRExpr *
959get_gpr_w0(UInt archreg)
960{
961 return IRExpr_Get(gpr_w0_offset(archreg), Ity_I32);
962}
963
964/* Return the guest state offset of double word #0 of a gpr register. */
965static __inline__ UInt
966gpr_dw0_offset(UInt archreg)
967{
968 return gpr_offset(archreg) + 0;
969}
970
971/* Write double word #0 of a gpr to the guest state. */
972static __inline__ void
973put_gpr_dw0(UInt archreg, IRExpr *expr)
974{
975 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I64);
976
977 stmt(IRStmt_Put(gpr_dw0_offset(archreg), expr));
978}
979
980/* Read double word #0 of a gpr register. */
981static __inline__ IRExpr *
982get_gpr_dw0(UInt archreg)
983{
984 return IRExpr_Get(gpr_dw0_offset(archreg), Ity_I64);
985}
986
987/* Return the guest state offset of half word #1 of a gpr register. */
988static __inline__ UInt
989gpr_hw1_offset(UInt archreg)
990{
991 return gpr_offset(archreg) + 2;
992}
993
994/* Write half word #1 of a gpr to the guest state. */
995static __inline__ void
996put_gpr_hw1(UInt archreg, IRExpr *expr)
997{
998 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
999
1000 stmt(IRStmt_Put(gpr_hw1_offset(archreg), expr));
1001}
1002
1003/* Read half word #1 of a gpr register. */
1004static __inline__ IRExpr *
1005get_gpr_hw1(UInt archreg)
1006{
1007 return IRExpr_Get(gpr_hw1_offset(archreg), Ity_I16);
1008}
1009
1010/* Return the guest state offset of byte #6 of a gpr register. */
1011static __inline__ UInt
1012gpr_b6_offset(UInt archreg)
1013{
1014 return gpr_offset(archreg) + 6;
1015}
1016
1017/* Write byte #6 of a gpr to the guest state. */
1018static __inline__ void
1019put_gpr_b6(UInt archreg, IRExpr *expr)
1020{
1021 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1022
1023 stmt(IRStmt_Put(gpr_b6_offset(archreg), expr));
1024}
1025
1026/* Read byte #6 of a gpr register. */
1027static __inline__ IRExpr *
1028get_gpr_b6(UInt archreg)
1029{
1030 return IRExpr_Get(gpr_b6_offset(archreg), Ity_I8);
1031}
1032
1033/* Return the guest state offset of byte #3 of a gpr register. */
1034static __inline__ UInt
1035gpr_b3_offset(UInt archreg)
1036{
1037 return gpr_offset(archreg) + 3;
1038}
1039
1040/* Write byte #3 of a gpr to the guest state. */
1041static __inline__ void
1042put_gpr_b3(UInt archreg, IRExpr *expr)
1043{
1044 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1045
1046 stmt(IRStmt_Put(gpr_b3_offset(archreg), expr));
1047}
1048
1049/* Read byte #3 of a gpr register. */
1050static __inline__ IRExpr *
1051get_gpr_b3(UInt archreg)
1052{
1053 return IRExpr_Get(gpr_b3_offset(archreg), Ity_I8);
1054}
1055
1056/* Return the guest state offset of byte #0 of a gpr register. */
1057static __inline__ UInt
1058gpr_b0_offset(UInt archreg)
1059{
1060 return gpr_offset(archreg) + 0;
1061}
1062
1063/* Write byte #0 of a gpr to the guest state. */
1064static __inline__ void
1065put_gpr_b0(UInt archreg, IRExpr *expr)
1066{
1067 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1068
1069 stmt(IRStmt_Put(gpr_b0_offset(archreg), expr));
1070}
1071
1072/* Read byte #0 of a gpr register. */
1073static __inline__ IRExpr *
1074get_gpr_b0(UInt archreg)
1075{
1076 return IRExpr_Get(gpr_b0_offset(archreg), Ity_I8);
1077}
1078
1079/* Return the guest state offset of word #1 of a gpr register. */
1080static __inline__ UInt
1081gpr_w1_offset(UInt archreg)
1082{
1083 return gpr_offset(archreg) + 4;
1084}
1085
1086/* Write word #1 of a gpr to the guest state. */
1087static __inline__ void
1088put_gpr_w1(UInt archreg, IRExpr *expr)
1089{
1090 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1091
1092 stmt(IRStmt_Put(gpr_w1_offset(archreg), expr));
1093}
1094
1095/* Read word #1 of a gpr register. */
1096static __inline__ IRExpr *
1097get_gpr_w1(UInt archreg)
1098{
1099 return IRExpr_Get(gpr_w1_offset(archreg), Ity_I32);
1100}
1101
1102/* Return the guest state offset of half word #3 of a gpr register. */
1103static __inline__ UInt
1104gpr_hw3_offset(UInt archreg)
1105{
1106 return gpr_offset(archreg) + 6;
1107}
1108
1109/* Write half word #3 of a gpr to the guest state. */
1110static __inline__ void
1111put_gpr_hw3(UInt archreg, IRExpr *expr)
1112{
1113 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1114
1115 stmt(IRStmt_Put(gpr_hw3_offset(archreg), expr));
1116}
1117
1118/* Read half word #3 of a gpr register. */
1119static __inline__ IRExpr *
1120get_gpr_hw3(UInt archreg)
1121{
1122 return IRExpr_Get(gpr_hw3_offset(archreg), Ity_I16);
1123}
1124
1125/* Return the guest state offset of byte #7 of a gpr register. */
1126static __inline__ UInt
1127gpr_b7_offset(UInt archreg)
1128{
1129 return gpr_offset(archreg) + 7;
1130}
1131
1132/* Write byte #7 of a gpr to the guest state. */
1133static __inline__ void
1134put_gpr_b7(UInt archreg, IRExpr *expr)
1135{
1136 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1137
1138 stmt(IRStmt_Put(gpr_b7_offset(archreg), expr));
1139}
1140
1141/* Read byte #7 of a gpr register. */
1142static __inline__ IRExpr *
1143get_gpr_b7(UInt archreg)
1144{
1145 return IRExpr_Get(gpr_b7_offset(archreg), Ity_I8);
1146}
1147
1148/* Return the guest state offset of half word #0 of a gpr register. */
1149static __inline__ UInt
1150gpr_hw0_offset(UInt archreg)
1151{
1152 return gpr_offset(archreg) + 0;
1153}
1154
1155/* Write half word #0 of a gpr to the guest state. */
1156static __inline__ void
1157put_gpr_hw0(UInt archreg, IRExpr *expr)
1158{
1159 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1160
1161 stmt(IRStmt_Put(gpr_hw0_offset(archreg), expr));
1162}
1163
1164/* Read half word #0 of a gpr register. */
1165static __inline__ IRExpr *
1166get_gpr_hw0(UInt archreg)
1167{
1168 return IRExpr_Get(gpr_hw0_offset(archreg), Ity_I16);
1169}
1170
1171/* Return the guest state offset of byte #4 of a gpr register. */
1172static __inline__ UInt
1173gpr_b4_offset(UInt archreg)
1174{
1175 return gpr_offset(archreg) + 4;
1176}
1177
1178/* Write byte #4 of a gpr to the guest state. */
1179static __inline__ void
1180put_gpr_b4(UInt archreg, IRExpr *expr)
1181{
1182 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1183
1184 stmt(IRStmt_Put(gpr_b4_offset(archreg), expr));
1185}
1186
1187/* Read byte #4 of a gpr register. */
1188static __inline__ IRExpr *
1189get_gpr_b4(UInt archreg)
1190{
1191 return IRExpr_Get(gpr_b4_offset(archreg), Ity_I8);
1192}
1193
1194/* Return the guest state offset of byte #1 of a gpr register. */
1195static __inline__ UInt
1196gpr_b1_offset(UInt archreg)
1197{
1198 return gpr_offset(archreg) + 1;
1199}
1200
1201/* Write byte #1 of a gpr to the guest state. */
1202static __inline__ void
1203put_gpr_b1(UInt archreg, IRExpr *expr)
1204{
1205 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1206
1207 stmt(IRStmt_Put(gpr_b1_offset(archreg), expr));
1208}
1209
1210/* Read byte #1 of a gpr register. */
1211static __inline__ IRExpr *
1212get_gpr_b1(UInt archreg)
1213{
1214 return IRExpr_Get(gpr_b1_offset(archreg), Ity_I8);
1215}
1216
1217/* Return the guest state offset of half word #2 of a gpr register. */
1218static __inline__ UInt
1219gpr_hw2_offset(UInt archreg)
1220{
1221 return gpr_offset(archreg) + 4;
1222}
1223
1224/* Write half word #2 of a gpr to the guest state. */
1225static __inline__ void
1226put_gpr_hw2(UInt archreg, IRExpr *expr)
1227{
1228 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1229
1230 stmt(IRStmt_Put(gpr_hw2_offset(archreg), expr));
1231}
1232
1233/* Read half word #2 of a gpr register. */
1234static __inline__ IRExpr *
1235get_gpr_hw2(UInt archreg)
1236{
1237 return IRExpr_Get(gpr_hw2_offset(archreg), Ity_I16);
1238}
1239
1240/* Return the guest state offset of byte #5 of a gpr register. */
1241static __inline__ UInt
1242gpr_b5_offset(UInt archreg)
1243{
1244 return gpr_offset(archreg) + 5;
1245}
1246
1247/* Write byte #5 of a gpr to the guest state. */
1248static __inline__ void
1249put_gpr_b5(UInt archreg, IRExpr *expr)
1250{
1251 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1252
1253 stmt(IRStmt_Put(gpr_b5_offset(archreg), expr));
1254}
1255
1256/* Read byte #5 of a gpr register. */
1257static __inline__ IRExpr *
1258get_gpr_b5(UInt archreg)
1259{
1260 return IRExpr_Get(gpr_b5_offset(archreg), Ity_I8);
1261}
1262
1263/* Return the guest state offset of byte #2 of a gpr register. */
1264static __inline__ UInt
1265gpr_b2_offset(UInt archreg)
1266{
1267 return gpr_offset(archreg) + 2;
1268}
1269
1270/* Write byte #2 of a gpr to the guest state. */
1271static __inline__ void
1272put_gpr_b2(UInt archreg, IRExpr *expr)
1273{
1274 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1275
1276 stmt(IRStmt_Put(gpr_b2_offset(archreg), expr));
1277}
1278
1279/* Read byte #2 of a gpr register. */
1280static __inline__ IRExpr *
1281get_gpr_b2(UInt archreg)
1282{
1283 return IRExpr_Get(gpr_b2_offset(archreg), Ity_I8);
1284}
1285
1286/* Return the guest state offset of the counter register. */
1287static UInt
1288counter_offset(void)
1289{
floriane88b3c92011-07-05 02:48:39 +00001290 return S390X_GUEST_OFFSET(guest_counter);
sewardj2019a972011-03-07 16:04:07 +00001291}
1292
1293/* Return the guest state offset of double word #0 of the counter register. */
1294static __inline__ UInt
1295counter_dw0_offset(void)
1296{
1297 return counter_offset() + 0;
1298}
1299
1300/* Write double word #0 of the counter to the guest state. */
1301static __inline__ void
1302put_counter_dw0(IRExpr *expr)
1303{
1304 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I64);
1305
1306 stmt(IRStmt_Put(counter_dw0_offset(), expr));
1307}
1308
1309/* Read double word #0 of the counter register. */
1310static __inline__ IRExpr *
1311get_counter_dw0(void)
1312{
1313 return IRExpr_Get(counter_dw0_offset(), Ity_I64);
1314}
1315
1316/* Return the guest state offset of word #0 of the counter register. */
1317static __inline__ UInt
1318counter_w0_offset(void)
1319{
1320 return counter_offset() + 0;
1321}
1322
1323/* Return the guest state offset of word #1 of the counter register. */
1324static __inline__ UInt
1325counter_w1_offset(void)
1326{
1327 return counter_offset() + 4;
1328}
1329
1330/* Write word #0 of the counter to the guest state. */
1331static __inline__ void
1332put_counter_w0(IRExpr *expr)
1333{
1334 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1335
1336 stmt(IRStmt_Put(counter_w0_offset(), expr));
1337}
1338
1339/* Read word #0 of the counter register. */
1340static __inline__ IRExpr *
1341get_counter_w0(void)
1342{
1343 return IRExpr_Get(counter_w0_offset(), Ity_I32);
1344}
1345
1346/* Write word #1 of the counter to the guest state. */
1347static __inline__ void
1348put_counter_w1(IRExpr *expr)
1349{
1350 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1351
1352 stmt(IRStmt_Put(counter_w1_offset(), expr));
1353}
1354
1355/* Read word #1 of the counter register. */
1356static __inline__ IRExpr *
1357get_counter_w1(void)
1358{
1359 return IRExpr_Get(counter_w1_offset(), Ity_I32);
1360}
1361
1362/* Return the guest state offset of the fpc register. */
1363static UInt
1364fpc_offset(void)
1365{
floriane88b3c92011-07-05 02:48:39 +00001366 return S390X_GUEST_OFFSET(guest_fpc);
sewardj2019a972011-03-07 16:04:07 +00001367}
1368
1369/* Return the guest state offset of word #0 of the fpc register. */
1370static __inline__ UInt
1371fpc_w0_offset(void)
1372{
1373 return fpc_offset() + 0;
1374}
1375
1376/* Write word #0 of the fpc to the guest state. */
1377static __inline__ void
1378put_fpc_w0(IRExpr *expr)
1379{
1380 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1381
1382 stmt(IRStmt_Put(fpc_w0_offset(), expr));
1383}
1384
1385/* Read word #0 of the fpc register. */
1386static __inline__ IRExpr *
1387get_fpc_w0(void)
1388{
1389 return IRExpr_Get(fpc_w0_offset(), Ity_I32);
1390}
1391
1392
1393/*------------------------------------------------------------*/
1394/*--- Build IR for formats ---*/
1395/*------------------------------------------------------------*/
1396static void
1397s390_format_I(HChar *(*irgen)(UChar i),
1398 UChar i)
1399{
1400 HChar *mnm = irgen(i);
1401
sewardj7ee97522011-05-09 21:45:04 +00001402 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001403 s390_disasm(ENC2(MNM, UINT), mnm, i);
1404}
1405
1406static void
1407s390_format_RI(HChar *(*irgen)(UChar r1, UShort i2),
1408 UChar r1, UShort i2)
1409{
1410 irgen(r1, i2);
1411}
1412
1413static void
1414s390_format_RI_RU(HChar *(*irgen)(UChar r1, UShort i2),
1415 UChar r1, UShort i2)
1416{
1417 HChar *mnm = irgen(r1, i2);
1418
sewardj7ee97522011-05-09 21:45:04 +00001419 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001420 s390_disasm(ENC3(MNM, GPR, UINT), mnm, r1, i2);
1421}
1422
1423static void
1424s390_format_RI_RI(HChar *(*irgen)(UChar r1, UShort i2),
1425 UChar r1, UShort i2)
1426{
1427 HChar *mnm = irgen(r1, i2);
1428
sewardj7ee97522011-05-09 21:45:04 +00001429 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001430 s390_disasm(ENC3(MNM, GPR, INT), mnm, r1, (Int)(Short)i2);
1431}
1432
1433static void
1434s390_format_RI_RP(HChar *(*irgen)(UChar r1, UShort i2),
1435 UChar r1, UShort i2)
1436{
1437 HChar *mnm = irgen(r1, i2);
1438
sewardj7ee97522011-05-09 21:45:04 +00001439 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001440 s390_disasm(ENC3(MNM, GPR, PCREL), mnm, r1, (Int)(Short)i2);
1441}
1442
1443static void
1444s390_format_RIE_RRP(HChar *(*irgen)(UChar r1, UChar r3, UShort i2),
1445 UChar r1, UChar r3, UShort i2)
1446{
1447 HChar *mnm = irgen(r1, r3, i2);
1448
sewardj7ee97522011-05-09 21:45:04 +00001449 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001450 s390_disasm(ENC4(MNM, GPR, GPR, PCREL), mnm, r1, r3, (Int)(Short)i2);
1451}
1452
1453static void
1454s390_format_RIE_RRI0(HChar *(*irgen)(UChar r1, UChar r3, UShort i2),
1455 UChar r1, UChar r3, UShort i2)
1456{
1457 HChar *mnm = irgen(r1, r3, i2);
1458
sewardj7ee97522011-05-09 21:45:04 +00001459 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001460 s390_disasm(ENC4(MNM, GPR, GPR, INT), mnm, r1, r3, (Int)(Short)i2);
1461}
1462
1463static void
1464s390_format_RIE_RRUUU(HChar *(*irgen)(UChar r1, UChar r2, UChar i3, UChar i4,
1465 UChar i5),
1466 UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
1467{
1468 HChar *mnm = irgen(r1, r2, i3, i4, i5);
1469
sewardj7ee97522011-05-09 21:45:04 +00001470 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001471 s390_disasm(ENC6(MNM, GPR, GPR, UINT, UINT, UINT), mnm, r1, r2, i3, i4,
1472 i5);
1473}
1474
1475static void
1476s390_format_RIE_RRPU(HChar *(*irgen)(UChar r1, UChar r2, UShort i4, UChar m3),
1477 UChar r1, UChar r2, UShort i4, UChar m3)
1478{
1479 HChar *mnm = irgen(r1, r2, i4, m3);
1480
sewardj7ee97522011-05-09 21:45:04 +00001481 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001482 s390_disasm(ENC5(XMNM, GPR, GPR, CABM, PCREL), S390_XMNM_CAB, mnm, m3, r1,
1483 r2, m3, (Int)(Short)i4);
1484}
1485
1486static void
1487s390_format_RIE_RUPU(HChar *(*irgen)(UChar r1, UChar m3, UShort i4, UChar i2),
1488 UChar r1, UChar m3, UShort i4, UChar i2)
1489{
1490 HChar *mnm = irgen(r1, m3, i4, i2);
1491
sewardj7ee97522011-05-09 21:45:04 +00001492 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001493 s390_disasm(ENC5(XMNM, GPR, UINT, CABM, PCREL), S390_XMNM_CAB, mnm, m3,
1494 r1, i2, m3, (Int)(Short)i4);
1495}
1496
1497static void
1498s390_format_RIE_RUPI(HChar *(*irgen)(UChar r1, UChar m3, UShort i4, UChar i2),
1499 UChar r1, UChar m3, UShort i4, UChar i2)
1500{
1501 HChar *mnm = irgen(r1, m3, i4, i2);
1502
sewardj7ee97522011-05-09 21:45:04 +00001503 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001504 s390_disasm(ENC5(XMNM, GPR, INT, CABM, PCREL), S390_XMNM_CAB, mnm, m3, r1,
1505 (Int)(Char)i2, m3, (Int)(Short)i4);
1506}
1507
1508static void
1509s390_format_RIL(HChar *(*irgen)(UChar r1, UInt i2),
1510 UChar r1, UInt i2)
1511{
1512 irgen(r1, i2);
1513}
1514
1515static void
1516s390_format_RIL_RU(HChar *(*irgen)(UChar r1, UInt i2),
1517 UChar r1, UInt i2)
1518{
1519 HChar *mnm = irgen(r1, i2);
1520
sewardj7ee97522011-05-09 21:45:04 +00001521 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001522 s390_disasm(ENC3(MNM, GPR, UINT), mnm, r1, i2);
1523}
1524
1525static void
1526s390_format_RIL_RI(HChar *(*irgen)(UChar r1, UInt i2),
1527 UChar r1, UInt i2)
1528{
1529 HChar *mnm = irgen(r1, i2);
1530
sewardj7ee97522011-05-09 21:45:04 +00001531 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001532 s390_disasm(ENC3(MNM, GPR, INT), mnm, r1, i2);
1533}
1534
1535static void
1536s390_format_RIL_RP(HChar *(*irgen)(UChar r1, UInt i2),
1537 UChar r1, UInt i2)
1538{
1539 HChar *mnm = irgen(r1, i2);
1540
sewardj7ee97522011-05-09 21:45:04 +00001541 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001542 s390_disasm(ENC3(MNM, GPR, PCREL), mnm, r1, i2);
1543}
1544
1545static void
1546s390_format_RIL_UP(HChar *(*irgen)(void),
1547 UChar r1, UInt i2)
1548{
1549 HChar *mnm = irgen();
1550
sewardj7ee97522011-05-09 21:45:04 +00001551 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001552 s390_disasm(ENC3(MNM, UINT, PCREL), mnm, r1, i2);
1553}
1554
1555static void
1556s390_format_RIS_RURDI(HChar *(*irgen)(UChar r1, UChar m3, UChar i2,
1557 IRTemp op4addr),
1558 UChar r1, UChar m3, UChar b4, UShort d4, UChar i2)
1559{
1560 HChar *mnm;
1561 IRTemp op4addr = newTemp(Ity_I64);
1562
1563 assign(op4addr, binop(Iop_Add64, mkU64(d4), b4 != 0 ? get_gpr_dw0(b4) :
1564 mkU64(0)));
1565
1566 mnm = irgen(r1, m3, i2, op4addr);
1567
sewardj7ee97522011-05-09 21:45:04 +00001568 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001569 s390_disasm(ENC5(XMNM, GPR, INT, CABM, UDXB), S390_XMNM_CAB, mnm, m3, r1,
1570 (Int)(Char)i2, m3, d4, 0, b4);
1571}
1572
1573static void
1574s390_format_RIS_RURDU(HChar *(*irgen)(UChar r1, UChar m3, UChar i2,
1575 IRTemp op4addr),
1576 UChar r1, UChar m3, UChar b4, UShort d4, UChar i2)
1577{
1578 HChar *mnm;
1579 IRTemp op4addr = newTemp(Ity_I64);
1580
1581 assign(op4addr, binop(Iop_Add64, mkU64(d4), b4 != 0 ? get_gpr_dw0(b4) :
1582 mkU64(0)));
1583
1584 mnm = irgen(r1, m3, i2, op4addr);
1585
sewardj7ee97522011-05-09 21:45:04 +00001586 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001587 s390_disasm(ENC5(XMNM, GPR, UINT, CABM, UDXB), S390_XMNM_CAB, mnm, m3, r1,
1588 i2, m3, d4, 0, b4);
1589}
1590
1591static void
1592s390_format_RR(HChar *(*irgen)(UChar r1, UChar r2),
1593 UChar r1, UChar r2)
1594{
1595 irgen(r1, r2);
1596}
1597
1598static void
1599s390_format_RR_RR(HChar *(*irgen)(UChar r1, UChar r2),
1600 UChar r1, UChar r2)
1601{
1602 HChar *mnm = irgen(r1, r2);
1603
sewardj7ee97522011-05-09 21:45:04 +00001604 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001605 s390_disasm(ENC3(MNM, GPR, GPR), mnm, r1, r2);
1606}
1607
1608static void
1609s390_format_RR_FF(HChar *(*irgen)(UChar r1, UChar r2),
1610 UChar r1, UChar r2)
1611{
1612 HChar *mnm = irgen(r1, r2);
1613
sewardj7ee97522011-05-09 21:45:04 +00001614 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001615 s390_disasm(ENC3(MNM, FPR, FPR), mnm, r1, r2);
1616}
1617
1618static void
1619s390_format_RRE(HChar *(*irgen)(UChar r1, UChar r2),
1620 UChar r1, UChar r2)
1621{
1622 irgen(r1, r2);
1623}
1624
1625static void
1626s390_format_RRE_RR(HChar *(*irgen)(UChar r1, UChar r2),
1627 UChar r1, UChar r2)
1628{
1629 HChar *mnm = irgen(r1, r2);
1630
sewardj7ee97522011-05-09 21:45:04 +00001631 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001632 s390_disasm(ENC3(MNM, GPR, GPR), mnm, r1, r2);
1633}
1634
1635static void
1636s390_format_RRE_FF(HChar *(*irgen)(UChar r1, UChar r2),
1637 UChar r1, UChar r2)
1638{
1639 HChar *mnm = irgen(r1, r2);
1640
sewardj7ee97522011-05-09 21:45:04 +00001641 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001642 s390_disasm(ENC3(MNM, FPR, FPR), mnm, r1, r2);
1643}
1644
1645static void
1646s390_format_RRE_RF(HChar *(*irgen)(UChar, UChar),
1647 UChar r1, UChar r2)
1648{
1649 HChar *mnm = irgen(r1, r2);
1650
sewardj7ee97522011-05-09 21:45:04 +00001651 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001652 s390_disasm(ENC3(MNM, GPR, FPR), mnm, r1, r2);
1653}
1654
1655static void
1656s390_format_RRE_FR(HChar *(*irgen)(UChar r1, UChar r2),
1657 UChar r1, UChar r2)
1658{
1659 HChar *mnm = irgen(r1, r2);
1660
sewardj7ee97522011-05-09 21:45:04 +00001661 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001662 s390_disasm(ENC3(MNM, FPR, GPR), mnm, r1, r2);
1663}
1664
1665static void
1666s390_format_RRE_R0(HChar *(*irgen)(UChar r1),
1667 UChar r1)
1668{
1669 HChar *mnm = irgen(r1);
1670
sewardj7ee97522011-05-09 21:45:04 +00001671 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001672 s390_disasm(ENC2(MNM, GPR), mnm, r1);
1673}
1674
1675static void
1676s390_format_RRE_F0(HChar *(*irgen)(UChar r1),
1677 UChar r1)
1678{
1679 HChar *mnm = irgen(r1);
1680
sewardj7ee97522011-05-09 21:45:04 +00001681 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001682 s390_disasm(ENC2(MNM, FPR), mnm, r1);
1683}
1684
1685static void
florian9af37692012-01-15 21:01:16 +00001686s390_format_RRF_M0RERE(HChar *(*irgen)(UChar m3, UChar r1, UChar r2),
1687 UChar m3, UChar r1, UChar r2)
1688{
florianfed3ea32012-07-19 14:54:03 +00001689 HChar *mnm = irgen(m3, r1, r2);
florian9af37692012-01-15 21:01:16 +00001690
1691 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
florianfed3ea32012-07-19 14:54:03 +00001692 s390_disasm(ENC4(MNM, GPR, GPR, UINT), mnm, r1, r2, m3);
florian9af37692012-01-15 21:01:16 +00001693}
1694
1695static void
sewardj2019a972011-03-07 16:04:07 +00001696s390_format_RRF_F0FF(HChar *(*irgen)(UChar, UChar, UChar),
1697 UChar r1, UChar r3, UChar r2)
1698{
1699 HChar *mnm = irgen(r1, r3, r2);
1700
sewardj7ee97522011-05-09 21:45:04 +00001701 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001702 s390_disasm(ENC4(MNM, FPR, FPR, FPR), mnm, r1, r3, r2);
1703}
1704
1705static void
florian1c8f7ff2012-09-01 00:12:11 +00001706s390_format_RRF_UUFR(HChar *(*irgen)(UChar m3, UChar m4, UChar r1, UChar r2),
1707 UChar m3, UChar m4, UChar r1, UChar r2)
1708{
1709 HChar *mnm = irgen(m3, m4, r1, r2);
1710
1711 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1712 s390_disasm(ENC5(MNM, FPR, UINT, GPR, UINT), mnm, r1, m3, r2, m4);
1713}
1714
1715static void
1716s390_format_RRF_UURF(HChar *(*irgen)(UChar m3, UChar m4, UChar r1, UChar r2),
1717 UChar m3, UChar m4, UChar r1, UChar r2)
1718{
1719 HChar *mnm = irgen(m3, m4, r1, r2);
1720
1721 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1722 s390_disasm(ENC5(MNM, GPR, UINT, FPR, UINT), mnm, r1, m3, r2, m4);
1723}
1724
1725
1726static void
sewardjd7bde722011-04-05 13:19:33 +00001727s390_format_RRF_U0RR(HChar *(*irgen)(UChar m3, UChar r1, UChar r2),
1728 UChar m3, UChar r1, UChar r2, Int xmnm_kind)
1729{
1730 irgen(m3, r1, r2);
1731
sewardj7ee97522011-05-09 21:45:04 +00001732 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardjd7bde722011-04-05 13:19:33 +00001733 s390_disasm(ENC3(XMNM, GPR, GPR), xmnm_kind, m3, r1, r2);
1734}
1735
1736static void
sewardj2019a972011-03-07 16:04:07 +00001737s390_format_RRF_U0RF(HChar *(*irgen)(UChar r3, UChar r1, UChar r2),
1738 UChar r3, UChar r1, UChar r2)
1739{
1740 HChar *mnm = irgen(r3, r1, r2);
1741
sewardj7ee97522011-05-09 21:45:04 +00001742 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001743 s390_disasm(ENC4(MNM, GPR, UINT, FPR), mnm, r1, r3, r2);
1744}
1745
1746static void
1747s390_format_RRF_F0FF2(HChar *(*irgen)(UChar, UChar, UChar),
1748 UChar r3, UChar r1, UChar r2)
1749{
1750 HChar *mnm = irgen(r3, r1, r2);
1751
sewardj7ee97522011-05-09 21:45:04 +00001752 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001753 s390_disasm(ENC4(MNM, FPR, FPR, FPR), mnm, r1, r3, r2);
1754}
1755
1756static void
1757s390_format_RRF_R0RR2(HChar *(*irgen)(UChar r3, UChar r1, UChar r2),
1758 UChar r3, UChar r1, UChar r2)
1759{
1760 HChar *mnm = irgen(r3, r1, r2);
1761
sewardj7ee97522011-05-09 21:45:04 +00001762 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001763 s390_disasm(ENC4(MNM, GPR, GPR, GPR), mnm, r1, r2, r3);
1764}
1765
1766static void
1767s390_format_RRS(HChar *(*irgen)(UChar r1, UChar r2, UChar m3, IRTemp op4addr),
1768 UChar r1, UChar r2, UChar b4, UShort d4, UChar m3)
1769{
1770 HChar *mnm;
1771 IRTemp op4addr = newTemp(Ity_I64);
1772
1773 assign(op4addr, binop(Iop_Add64, mkU64(d4), b4 != 0 ? get_gpr_dw0(b4) :
1774 mkU64(0)));
1775
1776 mnm = irgen(r1, r2, m3, op4addr);
1777
sewardj7ee97522011-05-09 21:45:04 +00001778 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001779 s390_disasm(ENC5(XMNM, GPR, GPR, CABM, UDXB), S390_XMNM_CAB, mnm, m3, r1,
1780 r2, m3, d4, 0, b4);
1781}
1782
1783static void
1784s390_format_RS_R0RD(HChar *(*irgen)(UChar r1, IRTemp op2addr),
1785 UChar r1, UChar b2, UShort d2)
1786{
1787 HChar *mnm;
1788 IRTemp op2addr = newTemp(Ity_I64);
1789
1790 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
1791 mkU64(0)));
1792
1793 mnm = irgen(r1, op2addr);
1794
sewardj7ee97522011-05-09 21:45:04 +00001795 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001796 s390_disasm(ENC3(MNM, GPR, UDXB), mnm, r1, d2, 0, b2);
1797}
1798
1799static void
1800s390_format_RS_RRRD(HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
1801 UChar r1, UChar r3, UChar b2, UShort d2)
1802{
1803 HChar *mnm;
1804 IRTemp op2addr = newTemp(Ity_I64);
1805
1806 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
1807 mkU64(0)));
1808
1809 mnm = irgen(r1, r3, op2addr);
1810
sewardj7ee97522011-05-09 21:45:04 +00001811 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001812 s390_disasm(ENC4(MNM, GPR, GPR, UDXB), mnm, r1, r3, d2, 0, b2);
1813}
1814
1815static void
1816s390_format_RS_RURD(HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
1817 UChar r1, UChar r3, UChar b2, UShort d2)
1818{
1819 HChar *mnm;
1820 IRTemp op2addr = newTemp(Ity_I64);
1821
1822 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
1823 mkU64(0)));
1824
1825 mnm = irgen(r1, r3, op2addr);
1826
sewardj7ee97522011-05-09 21:45:04 +00001827 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001828 s390_disasm(ENC4(MNM, GPR, UINT, UDXB), mnm, r1, r3, d2, 0, b2);
1829}
1830
1831static void
1832s390_format_RS_AARD(HChar *(*irgen)(UChar, UChar, IRTemp),
1833 UChar r1, UChar r3, UChar b2, UShort d2)
1834{
1835 HChar *mnm;
1836 IRTemp op2addr = newTemp(Ity_I64);
1837
1838 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
1839 mkU64(0)));
1840
1841 mnm = irgen(r1, r3, op2addr);
1842
sewardj7ee97522011-05-09 21:45:04 +00001843 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001844 s390_disasm(ENC4(MNM, AR, AR, UDXB), mnm, r1, r3, d2, 0, b2);
1845}
1846
1847static void
1848s390_format_RSI_RRP(HChar *(*irgen)(UChar r1, UChar r3, UShort i2),
1849 UChar r1, UChar r3, UShort i2)
1850{
1851 HChar *mnm = irgen(r1, r3, i2);
1852
sewardj7ee97522011-05-09 21:45:04 +00001853 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001854 s390_disasm(ENC4(MNM, GPR, GPR, PCREL), mnm, r1, r3, (Int)(Short)i2);
1855}
1856
1857static void
1858s390_format_RSY_RRRD(HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
1859 UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
1860{
1861 HChar *mnm;
1862 IRTemp op2addr = newTemp(Ity_I64);
1863 IRTemp d2 = newTemp(Ity_I64);
1864
1865 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
1866 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
1867 mkU64(0)));
1868
1869 mnm = irgen(r1, r3, op2addr);
1870
sewardj7ee97522011-05-09 21:45:04 +00001871 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001872 s390_disasm(ENC4(MNM, GPR, GPR, SDXB), mnm, r1, r3, dh2, dl2, 0, b2);
1873}
1874
1875static void
1876s390_format_RSY_AARD(HChar *(*irgen)(UChar, UChar, IRTemp),
1877 UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
1878{
1879 HChar *mnm;
1880 IRTemp op2addr = newTemp(Ity_I64);
1881 IRTemp d2 = newTemp(Ity_I64);
1882
1883 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
1884 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
1885 mkU64(0)));
1886
1887 mnm = irgen(r1, r3, op2addr);
1888
sewardj7ee97522011-05-09 21:45:04 +00001889 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001890 s390_disasm(ENC4(MNM, AR, AR, SDXB), mnm, r1, r3, dh2, dl2, 0, b2);
1891}
1892
1893static void
1894s390_format_RSY_RURD(HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
1895 UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
1896{
1897 HChar *mnm;
1898 IRTemp op2addr = newTemp(Ity_I64);
1899 IRTemp d2 = newTemp(Ity_I64);
1900
1901 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
1902 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
1903 mkU64(0)));
1904
1905 mnm = irgen(r1, r3, op2addr);
1906
sewardj7ee97522011-05-09 21:45:04 +00001907 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001908 s390_disasm(ENC4(MNM, GPR, UINT, SDXB), mnm, r1, r3, dh2, dl2, 0, b2);
1909}
1910
1911static void
sewardjd7bde722011-04-05 13:19:33 +00001912s390_format_RSY_RDRM(HChar *(*irgen)(UChar r1, IRTemp op2addr),
1913 UChar r1, UChar m3, UChar b2, UShort dl2, UChar dh2,
1914 Int xmnm_kind)
1915{
1916 IRTemp op2addr = newTemp(Ity_I64);
1917 IRTemp d2 = newTemp(Ity_I64);
1918
florian6820ba52012-07-26 02:01:50 +00001919 next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
1920
sewardjd7bde722011-04-05 13:19:33 +00001921 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
1922 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
1923 mkU64(0)));
1924
1925 irgen(r1, op2addr);
florian6820ba52012-07-26 02:01:50 +00001926
1927 vassert(dis_res->whatNext == Dis_Continue);
sewardjd7bde722011-04-05 13:19:33 +00001928
sewardj7ee97522011-05-09 21:45:04 +00001929 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardjd7bde722011-04-05 13:19:33 +00001930 s390_disasm(ENC3(XMNM, GPR, SDXB), xmnm_kind, m3, r1, dh2, dl2, 0, b2);
1931}
1932
1933static void
sewardj2019a972011-03-07 16:04:07 +00001934s390_format_RX(HChar *(*irgen)(UChar r1, UChar x2, UChar b2, UShort d2,
1935 IRTemp op2addr),
1936 UChar r1, UChar x2, UChar b2, UShort d2)
1937{
1938 IRTemp op2addr = newTemp(Ity_I64);
1939
1940 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
1941 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
1942 mkU64(0)));
1943
1944 irgen(r1, x2, b2, d2, op2addr);
1945}
1946
1947static void
1948s390_format_RX_RRRD(HChar *(*irgen)(UChar r1, IRTemp op2addr),
1949 UChar r1, UChar x2, UChar b2, UShort d2)
1950{
1951 HChar *mnm;
1952 IRTemp op2addr = newTemp(Ity_I64);
1953
1954 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
1955 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
1956 mkU64(0)));
1957
1958 mnm = irgen(r1, op2addr);
1959
sewardj7ee97522011-05-09 21:45:04 +00001960 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001961 s390_disasm(ENC3(MNM, GPR, UDXB), mnm, r1, d2, x2, b2);
1962}
1963
1964static void
1965s390_format_RX_FRRD(HChar *(*irgen)(UChar r1, IRTemp op2addr),
1966 UChar r1, UChar x2, UChar b2, UShort d2)
1967{
1968 HChar *mnm;
1969 IRTemp op2addr = newTemp(Ity_I64);
1970
1971 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
1972 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
1973 mkU64(0)));
1974
1975 mnm = irgen(r1, op2addr);
1976
sewardj7ee97522011-05-09 21:45:04 +00001977 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001978 s390_disasm(ENC3(MNM, FPR, UDXB), mnm, r1, d2, x2, b2);
1979}
1980
1981static void
1982s390_format_RXE_FRRD(HChar *(*irgen)(UChar r1, IRTemp op2addr),
1983 UChar r1, UChar x2, UChar b2, UShort d2)
1984{
1985 HChar *mnm;
1986 IRTemp op2addr = newTemp(Ity_I64);
1987
1988 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
1989 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
1990 mkU64(0)));
1991
1992 mnm = irgen(r1, op2addr);
1993
sewardj7ee97522011-05-09 21:45:04 +00001994 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001995 s390_disasm(ENC3(MNM, FPR, UDXB), mnm, r1, d2, x2, b2);
1996}
1997
1998static void
1999s390_format_RXF_FRRDF(HChar *(*irgen)(UChar, IRTemp, UChar),
2000 UChar r3, UChar x2, UChar b2, UShort d2, UChar r1)
2001{
2002 HChar *mnm;
2003 IRTemp op2addr = newTemp(Ity_I64);
2004
2005 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2006 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2007 mkU64(0)));
2008
2009 mnm = irgen(r3, op2addr, r1);
2010
sewardj7ee97522011-05-09 21:45:04 +00002011 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002012 s390_disasm(ENC4(MNM, FPR, FPR, UDXB), mnm, r1, r3, d2, x2, b2);
2013}
2014
2015static void
2016s390_format_RXY_RRRD(HChar *(*irgen)(UChar r1, IRTemp op2addr),
2017 UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
2018{
2019 HChar *mnm;
2020 IRTemp op2addr = newTemp(Ity_I64);
2021 IRTemp d2 = newTemp(Ity_I64);
2022
2023 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2024 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkexpr(d2),
2025 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2026 mkU64(0)));
2027
2028 mnm = irgen(r1, op2addr);
2029
sewardj7ee97522011-05-09 21:45:04 +00002030 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002031 s390_disasm(ENC3(MNM, GPR, SDXB), mnm, r1, dh2, dl2, x2, b2);
2032}
2033
2034static void
2035s390_format_RXY_FRRD(HChar *(*irgen)(UChar r1, IRTemp op2addr),
2036 UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
2037{
2038 HChar *mnm;
2039 IRTemp op2addr = newTemp(Ity_I64);
2040 IRTemp d2 = newTemp(Ity_I64);
2041
2042 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2043 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkexpr(d2),
2044 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2045 mkU64(0)));
2046
2047 mnm = irgen(r1, op2addr);
2048
sewardj7ee97522011-05-09 21:45:04 +00002049 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002050 s390_disasm(ENC3(MNM, FPR, SDXB), mnm, r1, dh2, dl2, x2, b2);
2051}
2052
2053static void
2054s390_format_RXY_URRD(HChar *(*irgen)(void),
2055 UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
2056{
2057 HChar *mnm;
2058 IRTemp op2addr = newTemp(Ity_I64);
2059 IRTemp d2 = newTemp(Ity_I64);
2060
2061 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2062 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkexpr(d2),
2063 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2064 mkU64(0)));
2065
2066 mnm = irgen();
2067
sewardj7ee97522011-05-09 21:45:04 +00002068 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002069 s390_disasm(ENC3(MNM, UINT, SDXB), mnm, r1, dh2, dl2, x2, b2);
2070}
2071
2072static void
2073s390_format_S_RD(HChar *(*irgen)(IRTemp op2addr),
2074 UChar b2, UShort d2)
2075{
2076 HChar *mnm;
2077 IRTemp op2addr = newTemp(Ity_I64);
2078
2079 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2080 mkU64(0)));
2081
2082 mnm = irgen(op2addr);
2083
sewardj7ee97522011-05-09 21:45:04 +00002084 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002085 s390_disasm(ENC2(MNM, UDXB), mnm, d2, 0, b2);
2086}
2087
2088static void
2089s390_format_SI_URD(HChar *(*irgen)(UChar i2, IRTemp op1addr),
2090 UChar i2, UChar b1, UShort d1)
2091{
2092 HChar *mnm;
2093 IRTemp op1addr = newTemp(Ity_I64);
2094
2095 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2096 mkU64(0)));
2097
2098 mnm = irgen(i2, op1addr);
2099
sewardj7ee97522011-05-09 21:45:04 +00002100 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002101 s390_disasm(ENC3(MNM, UDXB, UINT), mnm, d1, 0, b1, i2);
2102}
2103
2104static void
2105s390_format_SIY_URD(HChar *(*irgen)(UChar i2, IRTemp op1addr),
2106 UChar i2, UChar b1, UShort dl1, UChar dh1)
2107{
2108 HChar *mnm;
2109 IRTemp op1addr = newTemp(Ity_I64);
2110 IRTemp d1 = newTemp(Ity_I64);
2111
2112 assign(d1, mkU64(((ULong)(Long)(Char)dh1 << 12) | ((ULong)dl1)));
2113 assign(op1addr, binop(Iop_Add64, mkexpr(d1), b1 != 0 ? get_gpr_dw0(b1) :
2114 mkU64(0)));
2115
2116 mnm = irgen(i2, op1addr);
2117
sewardj7ee97522011-05-09 21:45:04 +00002118 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002119 s390_disasm(ENC3(MNM, SDXB, UINT), mnm, dh1, dl1, 0, b1, i2);
2120}
2121
2122static void
2123s390_format_SIY_IRD(HChar *(*irgen)(UChar i2, IRTemp op1addr),
2124 UChar i2, UChar b1, UShort dl1, UChar dh1)
2125{
2126 HChar *mnm;
2127 IRTemp op1addr = newTemp(Ity_I64);
2128 IRTemp d1 = newTemp(Ity_I64);
2129
2130 assign(d1, mkU64(((ULong)(Long)(Char)dh1 << 12) | ((ULong)dl1)));
2131 assign(op1addr, binop(Iop_Add64, mkexpr(d1), b1 != 0 ? get_gpr_dw0(b1) :
2132 mkU64(0)));
2133
2134 mnm = irgen(i2, op1addr);
2135
sewardj7ee97522011-05-09 21:45:04 +00002136 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002137 s390_disasm(ENC3(MNM, SDXB, INT), mnm, dh1, dl1, 0, b1, (Int)(Char)i2);
2138}
2139
2140static void
2141s390_format_SS_L0RDRD(HChar *(*irgen)(UChar, IRTemp, IRTemp),
2142 UChar l, UChar b1, UShort d1, UChar b2, UShort d2)
2143{
2144 HChar *mnm;
2145 IRTemp op1addr = newTemp(Ity_I64);
2146 IRTemp op2addr = newTemp(Ity_I64);
2147
2148 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2149 mkU64(0)));
2150 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2151 mkU64(0)));
2152
2153 mnm = irgen(l, op1addr, op2addr);
2154
sewardj7ee97522011-05-09 21:45:04 +00002155 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002156 s390_disasm(ENC3(MNM, UDLB, UDXB), mnm, d1, l, b1, d2, 0, b2);
2157}
2158
2159static void
2160s390_format_SIL_RDI(HChar *(*irgen)(UShort i2, IRTemp op1addr),
2161 UChar b1, UShort d1, UShort i2)
2162{
2163 HChar *mnm;
2164 IRTemp op1addr = newTemp(Ity_I64);
2165
2166 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2167 mkU64(0)));
2168
2169 mnm = irgen(i2, op1addr);
2170
sewardj7ee97522011-05-09 21:45:04 +00002171 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002172 s390_disasm(ENC3(MNM, UDXB, INT), mnm, d1, 0, b1, (Int)(Short)i2);
2173}
2174
2175static void
2176s390_format_SIL_RDU(HChar *(*irgen)(UShort i2, IRTemp op1addr),
2177 UChar b1, UShort d1, UShort i2)
2178{
2179 HChar *mnm;
2180 IRTemp op1addr = newTemp(Ity_I64);
2181
2182 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2183 mkU64(0)));
2184
2185 mnm = irgen(i2, op1addr);
2186
sewardj7ee97522011-05-09 21:45:04 +00002187 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002188 s390_disasm(ENC3(MNM, UDXB, UINT), mnm, d1, 0, b1, i2);
2189}
2190
2191
2192
2193/*------------------------------------------------------------*/
2194/*--- Build IR for opcodes ---*/
2195/*------------------------------------------------------------*/
2196
2197static HChar *
2198s390_irgen_AR(UChar r1, UChar r2)
2199{
2200 IRTemp op1 = newTemp(Ity_I32);
2201 IRTemp op2 = newTemp(Ity_I32);
2202 IRTemp result = newTemp(Ity_I32);
2203
2204 assign(op1, get_gpr_w1(r1));
2205 assign(op2, get_gpr_w1(r2));
2206 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2207 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2208 put_gpr_w1(r1, mkexpr(result));
2209
2210 return "ar";
2211}
2212
2213static HChar *
2214s390_irgen_AGR(UChar r1, UChar r2)
2215{
2216 IRTemp op1 = newTemp(Ity_I64);
2217 IRTemp op2 = newTemp(Ity_I64);
2218 IRTemp result = newTemp(Ity_I64);
2219
2220 assign(op1, get_gpr_dw0(r1));
2221 assign(op2, get_gpr_dw0(r2));
2222 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2223 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2224 put_gpr_dw0(r1, mkexpr(result));
2225
2226 return "agr";
2227}
2228
2229static HChar *
2230s390_irgen_AGFR(UChar r1, UChar r2)
2231{
2232 IRTemp op1 = newTemp(Ity_I64);
2233 IRTemp op2 = newTemp(Ity_I64);
2234 IRTemp result = newTemp(Ity_I64);
2235
2236 assign(op1, get_gpr_dw0(r1));
2237 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
2238 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2239 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2240 put_gpr_dw0(r1, mkexpr(result));
2241
2242 return "agfr";
2243}
2244
2245static HChar *
2246s390_irgen_ARK(UChar r3, UChar r1, UChar r2)
2247{
2248 IRTemp op2 = newTemp(Ity_I32);
2249 IRTemp op3 = newTemp(Ity_I32);
2250 IRTemp result = newTemp(Ity_I32);
2251
2252 assign(op2, get_gpr_w1(r2));
2253 assign(op3, get_gpr_w1(r3));
2254 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2255 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
2256 put_gpr_w1(r1, mkexpr(result));
2257
2258 return "ark";
2259}
2260
2261static HChar *
2262s390_irgen_AGRK(UChar r3, UChar r1, UChar r2)
2263{
2264 IRTemp op2 = newTemp(Ity_I64);
2265 IRTemp op3 = newTemp(Ity_I64);
2266 IRTemp result = newTemp(Ity_I64);
2267
2268 assign(op2, get_gpr_dw0(r2));
2269 assign(op3, get_gpr_dw0(r3));
2270 assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
2271 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op2, op3);
2272 put_gpr_dw0(r1, mkexpr(result));
2273
2274 return "agrk";
2275}
2276
2277static HChar *
2278s390_irgen_A(UChar r1, IRTemp op2addr)
2279{
2280 IRTemp op1 = newTemp(Ity_I32);
2281 IRTemp op2 = newTemp(Ity_I32);
2282 IRTemp result = newTemp(Ity_I32);
2283
2284 assign(op1, get_gpr_w1(r1));
2285 assign(op2, load(Ity_I32, mkexpr(op2addr)));
2286 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2287 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2288 put_gpr_w1(r1, mkexpr(result));
2289
2290 return "a";
2291}
2292
2293static HChar *
2294s390_irgen_AY(UChar r1, IRTemp op2addr)
2295{
2296 IRTemp op1 = newTemp(Ity_I32);
2297 IRTemp op2 = newTemp(Ity_I32);
2298 IRTemp result = newTemp(Ity_I32);
2299
2300 assign(op1, get_gpr_w1(r1));
2301 assign(op2, load(Ity_I32, mkexpr(op2addr)));
2302 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2303 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2304 put_gpr_w1(r1, mkexpr(result));
2305
2306 return "ay";
2307}
2308
2309static HChar *
2310s390_irgen_AG(UChar r1, IRTemp op2addr)
2311{
2312 IRTemp op1 = newTemp(Ity_I64);
2313 IRTemp op2 = newTemp(Ity_I64);
2314 IRTemp result = newTemp(Ity_I64);
2315
2316 assign(op1, get_gpr_dw0(r1));
2317 assign(op2, load(Ity_I64, mkexpr(op2addr)));
2318 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2319 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2320 put_gpr_dw0(r1, mkexpr(result));
2321
2322 return "ag";
2323}
2324
2325static HChar *
2326s390_irgen_AGF(UChar r1, IRTemp op2addr)
2327{
2328 IRTemp op1 = newTemp(Ity_I64);
2329 IRTemp op2 = newTemp(Ity_I64);
2330 IRTemp result = newTemp(Ity_I64);
2331
2332 assign(op1, get_gpr_dw0(r1));
2333 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
2334 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2335 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2336 put_gpr_dw0(r1, mkexpr(result));
2337
2338 return "agf";
2339}
2340
2341static HChar *
2342s390_irgen_AFI(UChar r1, UInt i2)
2343{
2344 IRTemp op1 = newTemp(Ity_I32);
2345 Int op2;
2346 IRTemp result = newTemp(Ity_I32);
2347
2348 assign(op1, get_gpr_w1(r1));
2349 op2 = (Int)i2;
2350 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2351 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2352 mkU32((UInt)op2)));
2353 put_gpr_w1(r1, mkexpr(result));
2354
2355 return "afi";
2356}
2357
2358static HChar *
2359s390_irgen_AGFI(UChar r1, UInt i2)
2360{
2361 IRTemp op1 = newTemp(Ity_I64);
2362 Long op2;
2363 IRTemp result = newTemp(Ity_I64);
2364
2365 assign(op1, get_gpr_dw0(r1));
2366 op2 = (Long)(Int)i2;
2367 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64((ULong)op2)));
2368 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, mktemp(Ity_I64,
2369 mkU64((ULong)op2)));
2370 put_gpr_dw0(r1, mkexpr(result));
2371
2372 return "agfi";
2373}
2374
2375static HChar *
2376s390_irgen_AHIK(UChar r1, UChar r3, UShort i2)
2377{
2378 Int op2;
2379 IRTemp op3 = newTemp(Ity_I32);
2380 IRTemp result = newTemp(Ity_I32);
2381
2382 op2 = (Int)(Short)i2;
2383 assign(op3, get_gpr_w1(r3));
2384 assign(result, binop(Iop_Add32, mkU32((UInt)op2), mkexpr(op3)));
2385 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, mktemp(Ity_I32, mkU32((UInt)
2386 op2)), op3);
2387 put_gpr_w1(r1, mkexpr(result));
2388
2389 return "ahik";
2390}
2391
2392static HChar *
2393s390_irgen_AGHIK(UChar r1, UChar r3, UShort i2)
2394{
2395 Long op2;
2396 IRTemp op3 = newTemp(Ity_I64);
2397 IRTemp result = newTemp(Ity_I64);
2398
2399 op2 = (Long)(Short)i2;
2400 assign(op3, get_gpr_dw0(r3));
2401 assign(result, binop(Iop_Add64, mkU64((ULong)op2), mkexpr(op3)));
2402 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, mktemp(Ity_I64, mkU64((ULong)
2403 op2)), op3);
2404 put_gpr_dw0(r1, mkexpr(result));
2405
2406 return "aghik";
2407}
2408
2409static HChar *
2410s390_irgen_ASI(UChar i2, IRTemp op1addr)
2411{
2412 IRTemp op1 = newTemp(Ity_I32);
2413 Int op2;
2414 IRTemp result = newTemp(Ity_I32);
2415
2416 assign(op1, load(Ity_I32, mkexpr(op1addr)));
2417 op2 = (Int)(Char)i2;
2418 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2419 store(mkexpr(op1addr), mkexpr(result));
2420 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2421 mkU32((UInt)op2)));
2422
2423 return "asi";
2424}
2425
2426static HChar *
2427s390_irgen_AGSI(UChar i2, IRTemp op1addr)
2428{
2429 IRTemp op1 = newTemp(Ity_I64);
2430 Long op2;
2431 IRTemp result = newTemp(Ity_I64);
2432
2433 assign(op1, load(Ity_I64, mkexpr(op1addr)));
2434 op2 = (Long)(Char)i2;
2435 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64((ULong)op2)));
2436 store(mkexpr(op1addr), mkexpr(result));
2437 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, mktemp(Ity_I64,
2438 mkU64((ULong)op2)));
2439
2440 return "agsi";
2441}
2442
2443static HChar *
2444s390_irgen_AH(UChar r1, IRTemp op2addr)
2445{
2446 IRTemp op1 = newTemp(Ity_I32);
2447 IRTemp op2 = newTemp(Ity_I32);
2448 IRTemp result = newTemp(Ity_I32);
2449
2450 assign(op1, get_gpr_w1(r1));
2451 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
2452 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2453 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2454 put_gpr_w1(r1, mkexpr(result));
2455
2456 return "ah";
2457}
2458
2459static HChar *
2460s390_irgen_AHY(UChar r1, IRTemp op2addr)
2461{
2462 IRTemp op1 = newTemp(Ity_I32);
2463 IRTemp op2 = newTemp(Ity_I32);
2464 IRTemp result = newTemp(Ity_I32);
2465
2466 assign(op1, get_gpr_w1(r1));
2467 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
2468 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2469 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2470 put_gpr_w1(r1, mkexpr(result));
2471
2472 return "ahy";
2473}
2474
2475static HChar *
2476s390_irgen_AHI(UChar r1, UShort i2)
2477{
2478 IRTemp op1 = newTemp(Ity_I32);
2479 Int op2;
2480 IRTemp result = newTemp(Ity_I32);
2481
2482 assign(op1, get_gpr_w1(r1));
2483 op2 = (Int)(Short)i2;
2484 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2485 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2486 mkU32((UInt)op2)));
2487 put_gpr_w1(r1, mkexpr(result));
2488
2489 return "ahi";
2490}
2491
2492static HChar *
2493s390_irgen_AGHI(UChar r1, UShort i2)
2494{
2495 IRTemp op1 = newTemp(Ity_I64);
2496 Long op2;
2497 IRTemp result = newTemp(Ity_I64);
2498
2499 assign(op1, get_gpr_dw0(r1));
2500 op2 = (Long)(Short)i2;
2501 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64((ULong)op2)));
2502 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, mktemp(Ity_I64,
2503 mkU64((ULong)op2)));
2504 put_gpr_dw0(r1, mkexpr(result));
2505
2506 return "aghi";
2507}
2508
2509static HChar *
2510s390_irgen_AHHHR(UChar r3, UChar r1, UChar r2)
2511{
2512 IRTemp op2 = newTemp(Ity_I32);
2513 IRTemp op3 = newTemp(Ity_I32);
2514 IRTemp result = newTemp(Ity_I32);
2515
2516 assign(op2, get_gpr_w0(r2));
2517 assign(op3, get_gpr_w0(r3));
2518 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2519 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
2520 put_gpr_w0(r1, mkexpr(result));
2521
2522 return "ahhhr";
2523}
2524
2525static HChar *
2526s390_irgen_AHHLR(UChar r3, UChar r1, UChar r2)
2527{
2528 IRTemp op2 = newTemp(Ity_I32);
2529 IRTemp op3 = newTemp(Ity_I32);
2530 IRTemp result = newTemp(Ity_I32);
2531
2532 assign(op2, get_gpr_w0(r2));
2533 assign(op3, get_gpr_w1(r3));
2534 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2535 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
2536 put_gpr_w0(r1, mkexpr(result));
2537
2538 return "ahhlr";
2539}
2540
2541static HChar *
2542s390_irgen_AIH(UChar r1, UInt i2)
2543{
2544 IRTemp op1 = newTemp(Ity_I32);
2545 Int op2;
2546 IRTemp result = newTemp(Ity_I32);
2547
2548 assign(op1, get_gpr_w0(r1));
2549 op2 = (Int)i2;
2550 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2551 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2552 mkU32((UInt)op2)));
2553 put_gpr_w0(r1, mkexpr(result));
2554
2555 return "aih";
2556}
2557
2558static HChar *
2559s390_irgen_ALR(UChar r1, UChar r2)
2560{
2561 IRTemp op1 = newTemp(Ity_I32);
2562 IRTemp op2 = newTemp(Ity_I32);
2563 IRTemp result = newTemp(Ity_I32);
2564
2565 assign(op1, get_gpr_w1(r1));
2566 assign(op2, get_gpr_w1(r2));
2567 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2568 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, op2);
2569 put_gpr_w1(r1, mkexpr(result));
2570
2571 return "alr";
2572}
2573
2574static HChar *
2575s390_irgen_ALGR(UChar r1, UChar r2)
2576{
2577 IRTemp op1 = newTemp(Ity_I64);
2578 IRTemp op2 = newTemp(Ity_I64);
2579 IRTemp result = newTemp(Ity_I64);
2580
2581 assign(op1, get_gpr_dw0(r1));
2582 assign(op2, get_gpr_dw0(r2));
2583 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2584 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
2585 put_gpr_dw0(r1, mkexpr(result));
2586
2587 return "algr";
2588}
2589
2590static HChar *
2591s390_irgen_ALGFR(UChar r1, UChar r2)
2592{
2593 IRTemp op1 = newTemp(Ity_I64);
2594 IRTemp op2 = newTemp(Ity_I64);
2595 IRTemp result = newTemp(Ity_I64);
2596
2597 assign(op1, get_gpr_dw0(r1));
2598 assign(op2, unop(Iop_32Uto64, get_gpr_w1(r2)));
2599 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2600 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
2601 put_gpr_dw0(r1, mkexpr(result));
2602
2603 return "algfr";
2604}
2605
2606static HChar *
2607s390_irgen_ALRK(UChar r3, UChar r1, UChar r2)
2608{
2609 IRTemp op2 = newTemp(Ity_I32);
2610 IRTemp op3 = newTemp(Ity_I32);
2611 IRTemp result = newTemp(Ity_I32);
2612
2613 assign(op2, get_gpr_w1(r2));
2614 assign(op3, get_gpr_w1(r3));
2615 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2616 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
2617 put_gpr_w1(r1, mkexpr(result));
2618
2619 return "alrk";
2620}
2621
2622static HChar *
2623s390_irgen_ALGRK(UChar r3, UChar r1, UChar r2)
2624{
2625 IRTemp op2 = newTemp(Ity_I64);
2626 IRTemp op3 = newTemp(Ity_I64);
2627 IRTemp result = newTemp(Ity_I64);
2628
2629 assign(op2, get_gpr_dw0(r2));
2630 assign(op3, get_gpr_dw0(r3));
2631 assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
2632 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op2, op3);
2633 put_gpr_dw0(r1, mkexpr(result));
2634
2635 return "algrk";
2636}
2637
2638static HChar *
2639s390_irgen_AL(UChar r1, IRTemp op2addr)
2640{
2641 IRTemp op1 = newTemp(Ity_I32);
2642 IRTemp op2 = newTemp(Ity_I32);
2643 IRTemp result = newTemp(Ity_I32);
2644
2645 assign(op1, get_gpr_w1(r1));
2646 assign(op2, load(Ity_I32, mkexpr(op2addr)));
2647 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2648 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, op2);
2649 put_gpr_w1(r1, mkexpr(result));
2650
2651 return "al";
2652}
2653
2654static HChar *
2655s390_irgen_ALY(UChar r1, IRTemp op2addr)
2656{
2657 IRTemp op1 = newTemp(Ity_I32);
2658 IRTemp op2 = newTemp(Ity_I32);
2659 IRTemp result = newTemp(Ity_I32);
2660
2661 assign(op1, get_gpr_w1(r1));
2662 assign(op2, load(Ity_I32, mkexpr(op2addr)));
2663 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2664 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, op2);
2665 put_gpr_w1(r1, mkexpr(result));
2666
2667 return "aly";
2668}
2669
2670static HChar *
2671s390_irgen_ALG(UChar r1, IRTemp op2addr)
2672{
2673 IRTemp op1 = newTemp(Ity_I64);
2674 IRTemp op2 = newTemp(Ity_I64);
2675 IRTemp result = newTemp(Ity_I64);
2676
2677 assign(op1, get_gpr_dw0(r1));
2678 assign(op2, load(Ity_I64, mkexpr(op2addr)));
2679 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2680 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
2681 put_gpr_dw0(r1, mkexpr(result));
2682
2683 return "alg";
2684}
2685
2686static HChar *
2687s390_irgen_ALGF(UChar r1, IRTemp op2addr)
2688{
2689 IRTemp op1 = newTemp(Ity_I64);
2690 IRTemp op2 = newTemp(Ity_I64);
2691 IRTemp result = newTemp(Ity_I64);
2692
2693 assign(op1, get_gpr_dw0(r1));
2694 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
2695 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2696 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
2697 put_gpr_dw0(r1, mkexpr(result));
2698
2699 return "algf";
2700}
2701
2702static HChar *
2703s390_irgen_ALFI(UChar r1, UInt i2)
2704{
2705 IRTemp op1 = newTemp(Ity_I32);
2706 UInt op2;
2707 IRTemp result = newTemp(Ity_I32);
2708
2709 assign(op1, get_gpr_w1(r1));
2710 op2 = i2;
2711 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
2712 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, mktemp(Ity_I32,
2713 mkU32(op2)));
2714 put_gpr_w1(r1, mkexpr(result));
2715
2716 return "alfi";
2717}
2718
2719static HChar *
2720s390_irgen_ALGFI(UChar r1, UInt i2)
2721{
2722 IRTemp op1 = newTemp(Ity_I64);
2723 ULong op2;
2724 IRTemp result = newTemp(Ity_I64);
2725
2726 assign(op1, get_gpr_dw0(r1));
2727 op2 = (ULong)i2;
2728 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64(op2)));
2729 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, mktemp(Ity_I64,
2730 mkU64(op2)));
2731 put_gpr_dw0(r1, mkexpr(result));
2732
2733 return "algfi";
2734}
2735
2736static HChar *
2737s390_irgen_ALHHHR(UChar r3, UChar r1, UChar r2)
2738{
2739 IRTemp op2 = newTemp(Ity_I32);
2740 IRTemp op3 = newTemp(Ity_I32);
2741 IRTemp result = newTemp(Ity_I32);
2742
2743 assign(op2, get_gpr_w0(r2));
2744 assign(op3, get_gpr_w0(r3));
2745 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2746 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
2747 put_gpr_w0(r1, mkexpr(result));
2748
2749 return "alhhhr";
2750}
2751
2752static HChar *
2753s390_irgen_ALHHLR(UChar r3, UChar r1, UChar r2)
2754{
2755 IRTemp op2 = newTemp(Ity_I32);
2756 IRTemp op3 = newTemp(Ity_I32);
2757 IRTemp result = newTemp(Ity_I32);
2758
2759 assign(op2, get_gpr_w0(r2));
2760 assign(op3, get_gpr_w1(r3));
2761 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2762 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
2763 put_gpr_w0(r1, mkexpr(result));
2764
2765 return "alhhlr";
2766}
2767
2768static HChar *
2769s390_irgen_ALCR(UChar r1, UChar r2)
2770{
2771 IRTemp op1 = newTemp(Ity_I32);
2772 IRTemp op2 = newTemp(Ity_I32);
2773 IRTemp result = newTemp(Ity_I32);
2774 IRTemp carry_in = newTemp(Ity_I32);
2775
2776 assign(op1, get_gpr_w1(r1));
2777 assign(op2, get_gpr_w1(r2));
2778 assign(carry_in, binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)));
2779 assign(result, binop(Iop_Add32, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)),
2780 mkexpr(carry_in)));
2781 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_32, op1, op2, carry_in);
2782 put_gpr_w1(r1, mkexpr(result));
2783
2784 return "alcr";
2785}
2786
2787static HChar *
2788s390_irgen_ALCGR(UChar r1, UChar r2)
2789{
2790 IRTemp op1 = newTemp(Ity_I64);
2791 IRTemp op2 = newTemp(Ity_I64);
2792 IRTemp result = newTemp(Ity_I64);
2793 IRTemp carry_in = newTemp(Ity_I64);
2794
2795 assign(op1, get_gpr_dw0(r1));
2796 assign(op2, get_gpr_dw0(r2));
2797 assign(carry_in, unop(Iop_32Uto64, binop(Iop_Shr32, s390_call_calculate_cc(),
2798 mkU8(1))));
2799 assign(result, binop(Iop_Add64, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)),
2800 mkexpr(carry_in)));
2801 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_64, op1, op2, carry_in);
2802 put_gpr_dw0(r1, mkexpr(result));
2803
2804 return "alcgr";
2805}
2806
2807static HChar *
2808s390_irgen_ALC(UChar r1, IRTemp op2addr)
2809{
2810 IRTemp op1 = newTemp(Ity_I32);
2811 IRTemp op2 = newTemp(Ity_I32);
2812 IRTemp result = newTemp(Ity_I32);
2813 IRTemp carry_in = newTemp(Ity_I32);
2814
2815 assign(op1, get_gpr_w1(r1));
2816 assign(op2, load(Ity_I32, mkexpr(op2addr)));
2817 assign(carry_in, binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)));
2818 assign(result, binop(Iop_Add32, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)),
2819 mkexpr(carry_in)));
2820 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_32, op1, op2, carry_in);
2821 put_gpr_w1(r1, mkexpr(result));
2822
2823 return "alc";
2824}
2825
2826static HChar *
2827s390_irgen_ALCG(UChar r1, IRTemp op2addr)
2828{
2829 IRTemp op1 = newTemp(Ity_I64);
2830 IRTemp op2 = newTemp(Ity_I64);
2831 IRTemp result = newTemp(Ity_I64);
2832 IRTemp carry_in = newTemp(Ity_I64);
2833
2834 assign(op1, get_gpr_dw0(r1));
2835 assign(op2, load(Ity_I64, mkexpr(op2addr)));
2836 assign(carry_in, unop(Iop_32Uto64, binop(Iop_Shr32, s390_call_calculate_cc(),
2837 mkU8(1))));
2838 assign(result, binop(Iop_Add64, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)),
2839 mkexpr(carry_in)));
2840 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_64, op1, op2, carry_in);
2841 put_gpr_dw0(r1, mkexpr(result));
2842
2843 return "alcg";
2844}
2845
2846static HChar *
2847s390_irgen_ALSI(UChar i2, IRTemp op1addr)
2848{
2849 IRTemp op1 = newTemp(Ity_I32);
2850 UInt op2;
2851 IRTemp result = newTemp(Ity_I32);
2852
2853 assign(op1, load(Ity_I32, mkexpr(op1addr)));
2854 op2 = (UInt)(Int)(Char)i2;
2855 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
2856 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, mktemp(Ity_I32,
2857 mkU32(op2)));
2858 store(mkexpr(op1addr), mkexpr(result));
2859
2860 return "alsi";
2861}
2862
2863static HChar *
2864s390_irgen_ALGSI(UChar i2, IRTemp op1addr)
2865{
2866 IRTemp op1 = newTemp(Ity_I64);
2867 ULong op2;
2868 IRTemp result = newTemp(Ity_I64);
2869
2870 assign(op1, load(Ity_I64, mkexpr(op1addr)));
2871 op2 = (ULong)(Long)(Char)i2;
2872 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64(op2)));
2873 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, mktemp(Ity_I64,
2874 mkU64(op2)));
2875 store(mkexpr(op1addr), mkexpr(result));
2876
2877 return "algsi";
2878}
2879
2880static HChar *
2881s390_irgen_ALHSIK(UChar r1, UChar r3, UShort i2)
2882{
2883 UInt op2;
2884 IRTemp op3 = newTemp(Ity_I32);
2885 IRTemp result = newTemp(Ity_I32);
2886
2887 op2 = (UInt)(Int)(Short)i2;
2888 assign(op3, get_gpr_w1(r3));
2889 assign(result, binop(Iop_Add32, mkU32(op2), mkexpr(op3)));
2890 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, mktemp(Ity_I32, mkU32(op2)),
2891 op3);
2892 put_gpr_w1(r1, mkexpr(result));
2893
2894 return "alhsik";
2895}
2896
2897static HChar *
2898s390_irgen_ALGHSIK(UChar r1, UChar r3, UShort i2)
2899{
2900 ULong op2;
2901 IRTemp op3 = newTemp(Ity_I64);
2902 IRTemp result = newTemp(Ity_I64);
2903
2904 op2 = (ULong)(Long)(Short)i2;
2905 assign(op3, get_gpr_dw0(r3));
2906 assign(result, binop(Iop_Add64, mkU64(op2), mkexpr(op3)));
2907 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, mktemp(Ity_I64, mkU64(op2)),
2908 op3);
2909 put_gpr_dw0(r1, mkexpr(result));
2910
2911 return "alghsik";
2912}
2913
2914static HChar *
2915s390_irgen_ALSIH(UChar r1, UInt i2)
2916{
2917 IRTemp op1 = newTemp(Ity_I32);
2918 UInt op2;
2919 IRTemp result = newTemp(Ity_I32);
2920
2921 assign(op1, get_gpr_w0(r1));
2922 op2 = i2;
2923 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
2924 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, mktemp(Ity_I32,
2925 mkU32(op2)));
2926 put_gpr_w0(r1, mkexpr(result));
2927
2928 return "alsih";
2929}
2930
2931static HChar *
2932s390_irgen_ALSIHN(UChar r1, UInt i2)
2933{
2934 IRTemp op1 = newTemp(Ity_I32);
2935 UInt op2;
2936 IRTemp result = newTemp(Ity_I32);
2937
2938 assign(op1, get_gpr_w0(r1));
2939 op2 = i2;
2940 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
2941 put_gpr_w0(r1, mkexpr(result));
2942
2943 return "alsihn";
2944}
2945
2946static HChar *
2947s390_irgen_NR(UChar r1, UChar r2)
2948{
2949 IRTemp op1 = newTemp(Ity_I32);
2950 IRTemp op2 = newTemp(Ity_I32);
2951 IRTemp result = newTemp(Ity_I32);
2952
2953 assign(op1, get_gpr_w1(r1));
2954 assign(op2, get_gpr_w1(r2));
2955 assign(result, binop(Iop_And32, mkexpr(op1), mkexpr(op2)));
2956 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
2957 put_gpr_w1(r1, mkexpr(result));
2958
2959 return "nr";
2960}
2961
2962static HChar *
2963s390_irgen_NGR(UChar r1, UChar r2)
2964{
2965 IRTemp op1 = newTemp(Ity_I64);
2966 IRTemp op2 = newTemp(Ity_I64);
2967 IRTemp result = newTemp(Ity_I64);
2968
2969 assign(op1, get_gpr_dw0(r1));
2970 assign(op2, get_gpr_dw0(r2));
2971 assign(result, binop(Iop_And64, mkexpr(op1), mkexpr(op2)));
2972 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
2973 put_gpr_dw0(r1, mkexpr(result));
2974
2975 return "ngr";
2976}
2977
2978static HChar *
2979s390_irgen_NRK(UChar r3, UChar r1, UChar r2)
2980{
2981 IRTemp op2 = newTemp(Ity_I32);
2982 IRTemp op3 = newTemp(Ity_I32);
2983 IRTemp result = newTemp(Ity_I32);
2984
2985 assign(op2, get_gpr_w1(r2));
2986 assign(op3, get_gpr_w1(r3));
2987 assign(result, binop(Iop_And32, mkexpr(op2), mkexpr(op3)));
2988 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
2989 put_gpr_w1(r1, mkexpr(result));
2990
2991 return "nrk";
2992}
2993
2994static HChar *
2995s390_irgen_NGRK(UChar r3, UChar r1, UChar r2)
2996{
2997 IRTemp op2 = newTemp(Ity_I64);
2998 IRTemp op3 = newTemp(Ity_I64);
2999 IRTemp result = newTemp(Ity_I64);
3000
3001 assign(op2, get_gpr_dw0(r2));
3002 assign(op3, get_gpr_dw0(r3));
3003 assign(result, binop(Iop_And64, mkexpr(op2), mkexpr(op3)));
3004 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3005 put_gpr_dw0(r1, mkexpr(result));
3006
3007 return "ngrk";
3008}
3009
3010static HChar *
3011s390_irgen_N(UChar r1, IRTemp op2addr)
3012{
3013 IRTemp op1 = newTemp(Ity_I32);
3014 IRTemp op2 = newTemp(Ity_I32);
3015 IRTemp result = newTemp(Ity_I32);
3016
3017 assign(op1, get_gpr_w1(r1));
3018 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3019 assign(result, binop(Iop_And32, mkexpr(op1), mkexpr(op2)));
3020 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3021 put_gpr_w1(r1, mkexpr(result));
3022
3023 return "n";
3024}
3025
3026static HChar *
3027s390_irgen_NY(UChar r1, IRTemp op2addr)
3028{
3029 IRTemp op1 = newTemp(Ity_I32);
3030 IRTemp op2 = newTemp(Ity_I32);
3031 IRTemp result = newTemp(Ity_I32);
3032
3033 assign(op1, get_gpr_w1(r1));
3034 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3035 assign(result, binop(Iop_And32, mkexpr(op1), mkexpr(op2)));
3036 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3037 put_gpr_w1(r1, mkexpr(result));
3038
3039 return "ny";
3040}
3041
3042static HChar *
3043s390_irgen_NG(UChar r1, IRTemp op2addr)
3044{
3045 IRTemp op1 = newTemp(Ity_I64);
3046 IRTemp op2 = newTemp(Ity_I64);
3047 IRTemp result = newTemp(Ity_I64);
3048
3049 assign(op1, get_gpr_dw0(r1));
3050 assign(op2, load(Ity_I64, mkexpr(op2addr)));
3051 assign(result, binop(Iop_And64, mkexpr(op1), mkexpr(op2)));
3052 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3053 put_gpr_dw0(r1, mkexpr(result));
3054
3055 return "ng";
3056}
3057
3058static HChar *
3059s390_irgen_NI(UChar i2, IRTemp op1addr)
3060{
3061 IRTemp op1 = newTemp(Ity_I8);
3062 UChar op2;
3063 IRTemp result = newTemp(Ity_I8);
3064
3065 assign(op1, load(Ity_I8, mkexpr(op1addr)));
3066 op2 = i2;
3067 assign(result, binop(Iop_And8, mkexpr(op1), mkU8(op2)));
3068 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3069 store(mkexpr(op1addr), mkexpr(result));
3070
3071 return "ni";
3072}
3073
3074static HChar *
3075s390_irgen_NIY(UChar i2, IRTemp op1addr)
3076{
3077 IRTemp op1 = newTemp(Ity_I8);
3078 UChar op2;
3079 IRTemp result = newTemp(Ity_I8);
3080
3081 assign(op1, load(Ity_I8, mkexpr(op1addr)));
3082 op2 = i2;
3083 assign(result, binop(Iop_And8, mkexpr(op1), mkU8(op2)));
3084 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3085 store(mkexpr(op1addr), mkexpr(result));
3086
3087 return "niy";
3088}
3089
3090static HChar *
3091s390_irgen_NIHF(UChar r1, UInt i2)
3092{
3093 IRTemp op1 = newTemp(Ity_I32);
3094 UInt op2;
3095 IRTemp result = newTemp(Ity_I32);
3096
3097 assign(op1, get_gpr_w0(r1));
3098 op2 = i2;
3099 assign(result, binop(Iop_And32, mkexpr(op1), mkU32(op2)));
3100 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3101 put_gpr_w0(r1, mkexpr(result));
3102
3103 return "nihf";
3104}
3105
3106static HChar *
3107s390_irgen_NIHH(UChar r1, UShort i2)
3108{
3109 IRTemp op1 = newTemp(Ity_I16);
3110 UShort op2;
3111 IRTemp result = newTemp(Ity_I16);
3112
3113 assign(op1, get_gpr_hw0(r1));
3114 op2 = i2;
3115 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3116 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3117 put_gpr_hw0(r1, mkexpr(result));
3118
3119 return "nihh";
3120}
3121
3122static HChar *
3123s390_irgen_NIHL(UChar r1, UShort i2)
3124{
3125 IRTemp op1 = newTemp(Ity_I16);
3126 UShort op2;
3127 IRTemp result = newTemp(Ity_I16);
3128
3129 assign(op1, get_gpr_hw1(r1));
3130 op2 = i2;
3131 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3132 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3133 put_gpr_hw1(r1, mkexpr(result));
3134
3135 return "nihl";
3136}
3137
3138static HChar *
3139s390_irgen_NILF(UChar r1, UInt i2)
3140{
3141 IRTemp op1 = newTemp(Ity_I32);
3142 UInt op2;
3143 IRTemp result = newTemp(Ity_I32);
3144
3145 assign(op1, get_gpr_w1(r1));
3146 op2 = i2;
3147 assign(result, binop(Iop_And32, mkexpr(op1), mkU32(op2)));
3148 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3149 put_gpr_w1(r1, mkexpr(result));
3150
3151 return "nilf";
3152}
3153
3154static HChar *
3155s390_irgen_NILH(UChar r1, UShort i2)
3156{
3157 IRTemp op1 = newTemp(Ity_I16);
3158 UShort op2;
3159 IRTemp result = newTemp(Ity_I16);
3160
3161 assign(op1, get_gpr_hw2(r1));
3162 op2 = i2;
3163 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3164 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3165 put_gpr_hw2(r1, mkexpr(result));
3166
3167 return "nilh";
3168}
3169
3170static HChar *
3171s390_irgen_NILL(UChar r1, UShort i2)
3172{
3173 IRTemp op1 = newTemp(Ity_I16);
3174 UShort op2;
3175 IRTemp result = newTemp(Ity_I16);
3176
3177 assign(op1, get_gpr_hw3(r1));
3178 op2 = i2;
3179 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3180 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3181 put_gpr_hw3(r1, mkexpr(result));
3182
3183 return "nill";
3184}
3185
3186static HChar *
3187s390_irgen_BASR(UChar r1, UChar r2)
3188{
3189 IRTemp target = newTemp(Ity_I64);
3190
3191 if (r2 == 0) {
3192 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 2ULL));
3193 } else {
3194 if (r1 != r2) {
3195 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 2ULL));
3196 call_function(get_gpr_dw0(r2));
3197 } else {
3198 assign(target, get_gpr_dw0(r2));
3199 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 2ULL));
3200 call_function(mkexpr(target));
3201 }
3202 }
3203
3204 return "basr";
3205}
3206
3207static HChar *
3208s390_irgen_BAS(UChar r1, IRTemp op2addr)
3209{
3210 IRTemp target = newTemp(Ity_I64);
3211
3212 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 4ULL));
3213 assign(target, mkexpr(op2addr));
3214 call_function(mkexpr(target));
3215
3216 return "bas";
3217}
3218
3219static HChar *
3220s390_irgen_BCR(UChar r1, UChar r2)
3221{
3222 IRTemp cond = newTemp(Ity_I32);
3223
sewardja52e37e2011-04-28 18:48:06 +00003224 if (r2 == 0 && (r1 >= 14)) { /* serialization */
3225 stmt(IRStmt_MBE(Imbe_Fence));
3226 }
3227
sewardj2019a972011-03-07 16:04:07 +00003228 if ((r2 == 0) || (r1 == 0)) {
3229 } else {
3230 if (r1 == 15) {
3231 return_from_function(get_gpr_dw0(r2));
3232 } else {
3233 assign(cond, s390_call_calculate_cond(r1));
florianf321da72012-07-21 20:32:57 +00003234 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3235 get_gpr_dw0(r2));
sewardj2019a972011-03-07 16:04:07 +00003236 }
3237 }
sewardj7ee97522011-05-09 21:45:04 +00003238 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003239 s390_disasm(ENC2(XMNM, GPR), S390_XMNM_BCR, r1, r2);
3240
3241 return "bcr";
3242}
3243
3244static HChar *
3245s390_irgen_BC(UChar r1, UChar x2, UChar b2, UShort d2, IRTemp op2addr)
3246{
3247 IRTemp cond = newTemp(Ity_I32);
3248
3249 if (r1 == 0) {
3250 } else {
3251 if (r1 == 15) {
3252 always_goto(mkexpr(op2addr));
3253 } else {
3254 assign(cond, s390_call_calculate_cond(r1));
florianf321da72012-07-21 20:32:57 +00003255 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3256 mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003257 }
3258 }
sewardj7ee97522011-05-09 21:45:04 +00003259 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003260 s390_disasm(ENC2(XMNM, UDXB), S390_XMNM_BC, r1, d2, x2, b2);
3261
3262 return "bc";
3263}
3264
3265static HChar *
3266s390_irgen_BCTR(UChar r1, UChar r2)
3267{
3268 put_gpr_w1(r1, binop(Iop_Sub32, get_gpr_w1(r1), mkU32(1)));
3269 if (r2 != 0) {
florianf321da72012-07-21 20:32:57 +00003270 if_condition_goto_computed(binop(Iop_CmpNE32, get_gpr_w1(r1), mkU32(0)),
3271 get_gpr_dw0(r2));
sewardj2019a972011-03-07 16:04:07 +00003272 }
3273
3274 return "bctr";
3275}
3276
3277static HChar *
3278s390_irgen_BCTGR(UChar r1, UChar r2)
3279{
3280 put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1)));
3281 if (r2 != 0) {
florianf321da72012-07-21 20:32:57 +00003282 if_condition_goto_computed(binop(Iop_CmpNE64, get_gpr_dw0(r1), mkU64(0)),
3283 get_gpr_dw0(r2));
sewardj2019a972011-03-07 16:04:07 +00003284 }
3285
3286 return "bctgr";
3287}
3288
3289static HChar *
3290s390_irgen_BCT(UChar r1, IRTemp op2addr)
3291{
3292 put_gpr_w1(r1, binop(Iop_Sub32, get_gpr_w1(r1), mkU32(1)));
florianf321da72012-07-21 20:32:57 +00003293 if_condition_goto_computed(binop(Iop_CmpNE32, get_gpr_w1(r1), mkU32(0)),
3294 mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003295
3296 return "bct";
3297}
3298
3299static HChar *
3300s390_irgen_BCTG(UChar r1, IRTemp op2addr)
3301{
3302 put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1)));
florianf321da72012-07-21 20:32:57 +00003303 if_condition_goto_computed(binop(Iop_CmpNE64, get_gpr_dw0(r1), mkU64(0)),
3304 mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003305
3306 return "bctg";
3307}
3308
3309static HChar *
3310s390_irgen_BXH(UChar r1, UChar r3, IRTemp op2addr)
3311{
3312 IRTemp value = newTemp(Ity_I32);
3313
3314 assign(value, get_gpr_w1(r3 | 1));
3315 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
florianf321da72012-07-21 20:32:57 +00003316 if_condition_goto_computed(binop(Iop_CmpLT32S, mkexpr(value),
3317 get_gpr_w1(r1)), mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003318
3319 return "bxh";
3320}
3321
3322static HChar *
3323s390_irgen_BXHG(UChar r1, UChar r3, IRTemp op2addr)
3324{
3325 IRTemp value = newTemp(Ity_I64);
3326
3327 assign(value, get_gpr_dw0(r3 | 1));
3328 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
florianf321da72012-07-21 20:32:57 +00003329 if_condition_goto_computed(binop(Iop_CmpLT64S, mkexpr(value),
3330 get_gpr_dw0(r1)), mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003331
3332 return "bxhg";
3333}
3334
3335static HChar *
3336s390_irgen_BXLE(UChar r1, UChar r3, IRTemp op2addr)
3337{
3338 IRTemp value = newTemp(Ity_I32);
3339
3340 assign(value, get_gpr_w1(r3 | 1));
3341 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
florianf321da72012-07-21 20:32:57 +00003342 if_condition_goto_computed(binop(Iop_CmpLE32S, get_gpr_w1(r1),
3343 mkexpr(value)), mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003344
3345 return "bxle";
3346}
3347
3348static HChar *
3349s390_irgen_BXLEG(UChar r1, UChar r3, IRTemp op2addr)
3350{
3351 IRTemp value = newTemp(Ity_I64);
3352
3353 assign(value, get_gpr_dw0(r3 | 1));
3354 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
florianf321da72012-07-21 20:32:57 +00003355 if_condition_goto_computed(binop(Iop_CmpLE64S, get_gpr_dw0(r1),
3356 mkexpr(value)), mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003357
3358 return "bxleg";
3359}
3360
3361static HChar *
3362s390_irgen_BRAS(UChar r1, UShort i2)
3363{
3364 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 4ULL));
floriana64c2432011-07-16 02:11:50 +00003365 call_function_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003366
3367 return "bras";
3368}
3369
3370static HChar *
3371s390_irgen_BRASL(UChar r1, UInt i2)
3372{
3373 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 6ULL));
floriana64c2432011-07-16 02:11:50 +00003374 call_function_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003375
3376 return "brasl";
3377}
3378
3379static HChar *
3380s390_irgen_BRC(UChar r1, UShort i2)
3381{
3382 IRTemp cond = newTemp(Ity_I32);
3383
3384 if (r1 == 0) {
3385 } else {
3386 if (r1 == 15) {
floriana64c2432011-07-16 02:11:50 +00003387 always_goto_and_chase(
3388 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003389 } else {
3390 assign(cond, s390_call_calculate_cond(r1));
3391 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3392 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3393
3394 }
3395 }
sewardj7ee97522011-05-09 21:45:04 +00003396 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003397 s390_disasm(ENC2(XMNM, PCREL), S390_XMNM_BRC, r1, (Int)(Short)i2);
3398
3399 return "brc";
3400}
3401
3402static HChar *
3403s390_irgen_BRCL(UChar r1, UInt i2)
3404{
3405 IRTemp cond = newTemp(Ity_I32);
3406
3407 if (r1 == 0) {
3408 } else {
3409 if (r1 == 15) {
floriana64c2432011-07-16 02:11:50 +00003410 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003411 } else {
3412 assign(cond, s390_call_calculate_cond(r1));
3413 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3414 guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1));
3415 }
3416 }
sewardj7ee97522011-05-09 21:45:04 +00003417 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003418 s390_disasm(ENC2(XMNM, PCREL), S390_XMNM_BRCL, r1, i2);
3419
3420 return "brcl";
3421}
3422
3423static HChar *
3424s390_irgen_BRCT(UChar r1, UShort i2)
3425{
3426 put_gpr_w1(r1, binop(Iop_Sub32, get_gpr_w1(r1), mkU32(1)));
3427 if_condition_goto(binop(Iop_CmpNE32, get_gpr_w1(r1), mkU32(0)),
3428 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3429
3430 return "brct";
3431}
3432
3433static HChar *
3434s390_irgen_BRCTG(UChar r1, UShort i2)
3435{
3436 put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1)));
3437 if_condition_goto(binop(Iop_CmpNE64, get_gpr_dw0(r1), mkU64(0)),
3438 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3439
3440 return "brctg";
3441}
3442
3443static HChar *
3444s390_irgen_BRXH(UChar r1, UChar r3, UShort i2)
3445{
3446 IRTemp value = newTemp(Ity_I32);
3447
3448 assign(value, get_gpr_w1(r3 | 1));
3449 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
3450 if_condition_goto(binop(Iop_CmpLT32S, mkexpr(value), get_gpr_w1(r1)),
3451 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3452
3453 return "brxh";
3454}
3455
3456static HChar *
3457s390_irgen_BRXHG(UChar r1, UChar r3, UShort i2)
3458{
3459 IRTemp value = newTemp(Ity_I64);
3460
3461 assign(value, get_gpr_dw0(r3 | 1));
3462 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
3463 if_condition_goto(binop(Iop_CmpLT64S, mkexpr(value), get_gpr_dw0(r1)),
3464 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3465
3466 return "brxhg";
3467}
3468
3469static HChar *
3470s390_irgen_BRXLE(UChar r1, UChar r3, UShort i2)
3471{
3472 IRTemp value = newTemp(Ity_I32);
3473
3474 assign(value, get_gpr_w1(r3 | 1));
3475 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
3476 if_condition_goto(binop(Iop_CmpLE32S, get_gpr_w1(r1), mkexpr(value)),
3477 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3478
3479 return "brxle";
3480}
3481
3482static HChar *
3483s390_irgen_BRXLG(UChar r1, UChar r3, UShort i2)
3484{
3485 IRTemp value = newTemp(Ity_I64);
3486
3487 assign(value, get_gpr_dw0(r3 | 1));
3488 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
3489 if_condition_goto(binop(Iop_CmpLE64S, get_gpr_dw0(r1), mkexpr(value)),
3490 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3491
3492 return "brxlg";
3493}
3494
3495static HChar *
3496s390_irgen_CR(UChar r1, UChar r2)
3497{
3498 IRTemp op1 = newTemp(Ity_I32);
3499 IRTemp op2 = newTemp(Ity_I32);
3500
3501 assign(op1, get_gpr_w1(r1));
3502 assign(op2, get_gpr_w1(r2));
3503 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3504
3505 return "cr";
3506}
3507
3508static HChar *
3509s390_irgen_CGR(UChar r1, UChar r2)
3510{
3511 IRTemp op1 = newTemp(Ity_I64);
3512 IRTemp op2 = newTemp(Ity_I64);
3513
3514 assign(op1, get_gpr_dw0(r1));
3515 assign(op2, get_gpr_dw0(r2));
3516 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3517
3518 return "cgr";
3519}
3520
3521static HChar *
3522s390_irgen_CGFR(UChar r1, UChar r2)
3523{
3524 IRTemp op1 = newTemp(Ity_I64);
3525 IRTemp op2 = newTemp(Ity_I64);
3526
3527 assign(op1, get_gpr_dw0(r1));
3528 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
3529 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3530
3531 return "cgfr";
3532}
3533
3534static HChar *
3535s390_irgen_C(UChar r1, IRTemp op2addr)
3536{
3537 IRTemp op1 = newTemp(Ity_I32);
3538 IRTemp op2 = newTemp(Ity_I32);
3539
3540 assign(op1, get_gpr_w1(r1));
3541 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3542 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3543
3544 return "c";
3545}
3546
3547static HChar *
3548s390_irgen_CY(UChar r1, IRTemp op2addr)
3549{
3550 IRTemp op1 = newTemp(Ity_I32);
3551 IRTemp op2 = newTemp(Ity_I32);
3552
3553 assign(op1, get_gpr_w1(r1));
3554 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3555 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3556
3557 return "cy";
3558}
3559
3560static HChar *
3561s390_irgen_CG(UChar r1, IRTemp op2addr)
3562{
3563 IRTemp op1 = newTemp(Ity_I64);
3564 IRTemp op2 = newTemp(Ity_I64);
3565
3566 assign(op1, get_gpr_dw0(r1));
3567 assign(op2, load(Ity_I64, mkexpr(op2addr)));
3568 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3569
3570 return "cg";
3571}
3572
3573static HChar *
3574s390_irgen_CGF(UChar r1, IRTemp op2addr)
3575{
3576 IRTemp op1 = newTemp(Ity_I64);
3577 IRTemp op2 = newTemp(Ity_I64);
3578
3579 assign(op1, get_gpr_dw0(r1));
3580 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
3581 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3582
3583 return "cgf";
3584}
3585
3586static HChar *
3587s390_irgen_CFI(UChar r1, UInt i2)
3588{
3589 IRTemp op1 = newTemp(Ity_I32);
3590 Int op2;
3591
3592 assign(op1, get_gpr_w1(r1));
3593 op2 = (Int)i2;
3594 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
3595 mkU32((UInt)op2)));
3596
3597 return "cfi";
3598}
3599
3600static HChar *
3601s390_irgen_CGFI(UChar r1, UInt i2)
3602{
3603 IRTemp op1 = newTemp(Ity_I64);
3604 Long op2;
3605
3606 assign(op1, get_gpr_dw0(r1));
3607 op2 = (Long)(Int)i2;
3608 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
3609 mkU64((ULong)op2)));
3610
3611 return "cgfi";
3612}
3613
3614static HChar *
3615s390_irgen_CRL(UChar r1, UInt i2)
3616{
3617 IRTemp op1 = newTemp(Ity_I32);
3618 IRTemp op2 = newTemp(Ity_I32);
3619
3620 assign(op1, get_gpr_w1(r1));
3621 assign(op2, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
3622 i2 << 1))));
3623 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3624
3625 return "crl";
3626}
3627
3628static HChar *
3629s390_irgen_CGRL(UChar r1, UInt i2)
3630{
3631 IRTemp op1 = newTemp(Ity_I64);
3632 IRTemp op2 = newTemp(Ity_I64);
3633
3634 assign(op1, get_gpr_dw0(r1));
3635 assign(op2, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
3636 i2 << 1))));
3637 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3638
3639 return "cgrl";
3640}
3641
3642static HChar *
3643s390_irgen_CGFRL(UChar r1, UInt i2)
3644{
3645 IRTemp op1 = newTemp(Ity_I64);
3646 IRTemp op2 = newTemp(Ity_I64);
3647
3648 assign(op1, get_gpr_dw0(r1));
3649 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
3650 ((ULong)(Long)(Int)i2 << 1)))));
3651 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3652
3653 return "cgfrl";
3654}
3655
3656static HChar *
3657s390_irgen_CRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
3658{
3659 IRTemp op1 = newTemp(Ity_I32);
3660 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00003661 IRTemp cond = newTemp(Ity_I32);
3662
3663 if (m3 == 0) {
3664 } else {
3665 if (m3 == 14) {
3666 always_goto(mkexpr(op4addr));
3667 } else {
3668 assign(op1, get_gpr_w1(r1));
3669 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00003670 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
3671 op1, op2));
florianf321da72012-07-21 20:32:57 +00003672 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond),
3673 mkU32(0)), mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00003674 }
3675 }
3676
3677 return "crb";
3678}
3679
3680static HChar *
3681s390_irgen_CGRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
3682{
3683 IRTemp op1 = newTemp(Ity_I64);
3684 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00003685 IRTemp cond = newTemp(Ity_I32);
3686
3687 if (m3 == 0) {
3688 } else {
3689 if (m3 == 14) {
3690 always_goto(mkexpr(op4addr));
3691 } else {
3692 assign(op1, get_gpr_dw0(r1));
3693 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00003694 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
3695 op1, op2));
florianf321da72012-07-21 20:32:57 +00003696 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond),
3697 mkU32(0)), mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00003698 }
3699 }
3700
3701 return "cgrb";
3702}
3703
3704static HChar *
3705s390_irgen_CRJ(UChar r1, UChar r2, UShort i4, UChar m3)
3706{
3707 IRTemp op1 = newTemp(Ity_I32);
3708 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00003709 IRTemp cond = newTemp(Ity_I32);
3710
3711 if (m3 == 0) {
3712 } else {
3713 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00003714 always_goto_and_chase(
3715 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00003716 } else {
3717 assign(op1, get_gpr_w1(r1));
3718 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00003719 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
3720 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00003721 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3722 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
3723
3724 }
3725 }
3726
3727 return "crj";
3728}
3729
3730static HChar *
3731s390_irgen_CGRJ(UChar r1, UChar r2, UShort i4, UChar m3)
3732{
3733 IRTemp op1 = newTemp(Ity_I64);
3734 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00003735 IRTemp cond = newTemp(Ity_I32);
3736
3737 if (m3 == 0) {
3738 } else {
3739 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00003740 always_goto_and_chase(
3741 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00003742 } else {
3743 assign(op1, get_gpr_dw0(r1));
3744 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00003745 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
3746 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00003747 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3748 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
3749
3750 }
3751 }
3752
3753 return "cgrj";
3754}
3755
3756static HChar *
3757s390_irgen_CIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
3758{
3759 IRTemp op1 = newTemp(Ity_I32);
3760 Int op2;
sewardj2019a972011-03-07 16:04:07 +00003761 IRTemp cond = newTemp(Ity_I32);
3762
3763 if (m3 == 0) {
3764 } else {
3765 if (m3 == 14) {
3766 always_goto(mkexpr(op4addr));
3767 } else {
3768 assign(op1, get_gpr_w1(r1));
3769 op2 = (Int)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00003770 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
3771 mktemp(Ity_I32, mkU32((UInt)op2))));
florianf321da72012-07-21 20:32:57 +00003772 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3773 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00003774 }
3775 }
3776
3777 return "cib";
3778}
3779
3780static HChar *
3781s390_irgen_CGIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
3782{
3783 IRTemp op1 = newTemp(Ity_I64);
3784 Long op2;
sewardj2019a972011-03-07 16:04:07 +00003785 IRTemp cond = newTemp(Ity_I32);
3786
3787 if (m3 == 0) {
3788 } else {
3789 if (m3 == 14) {
3790 always_goto(mkexpr(op4addr));
3791 } else {
3792 assign(op1, get_gpr_dw0(r1));
3793 op2 = (Long)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00003794 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
3795 mktemp(Ity_I64, mkU64((ULong)op2))));
florianf321da72012-07-21 20:32:57 +00003796 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3797 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00003798 }
3799 }
3800
3801 return "cgib";
3802}
3803
3804static HChar *
3805s390_irgen_CIJ(UChar r1, UChar m3, UShort i4, UChar i2)
3806{
3807 IRTemp op1 = newTemp(Ity_I32);
3808 Int op2;
sewardj2019a972011-03-07 16:04:07 +00003809 IRTemp cond = newTemp(Ity_I32);
3810
3811 if (m3 == 0) {
3812 } else {
3813 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00003814 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00003815 } else {
3816 assign(op1, get_gpr_w1(r1));
3817 op2 = (Int)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00003818 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
3819 mktemp(Ity_I32, mkU32((UInt)op2))));
sewardj2019a972011-03-07 16:04:07 +00003820 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3821 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
3822
3823 }
3824 }
3825
3826 return "cij";
3827}
3828
3829static HChar *
3830s390_irgen_CGIJ(UChar r1, UChar m3, UShort i4, UChar i2)
3831{
3832 IRTemp op1 = newTemp(Ity_I64);
3833 Long op2;
sewardj2019a972011-03-07 16:04:07 +00003834 IRTemp cond = newTemp(Ity_I32);
3835
3836 if (m3 == 0) {
3837 } else {
3838 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00003839 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00003840 } else {
3841 assign(op1, get_gpr_dw0(r1));
3842 op2 = (Long)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00003843 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
3844 mktemp(Ity_I64, mkU64((ULong)op2))));
sewardj2019a972011-03-07 16:04:07 +00003845 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3846 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
3847
3848 }
3849 }
3850
3851 return "cgij";
3852}
3853
3854static HChar *
3855s390_irgen_CH(UChar r1, IRTemp op2addr)
3856{
3857 IRTemp op1 = newTemp(Ity_I32);
3858 IRTemp op2 = newTemp(Ity_I32);
3859
3860 assign(op1, get_gpr_w1(r1));
3861 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
3862 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3863
3864 return "ch";
3865}
3866
3867static HChar *
3868s390_irgen_CHY(UChar r1, IRTemp op2addr)
3869{
3870 IRTemp op1 = newTemp(Ity_I32);
3871 IRTemp op2 = newTemp(Ity_I32);
3872
3873 assign(op1, get_gpr_w1(r1));
3874 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
3875 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3876
3877 return "chy";
3878}
3879
3880static HChar *
3881s390_irgen_CGH(UChar r1, IRTemp op2addr)
3882{
3883 IRTemp op1 = newTemp(Ity_I64);
3884 IRTemp op2 = newTemp(Ity_I64);
3885
3886 assign(op1, get_gpr_dw0(r1));
3887 assign(op2, unop(Iop_16Sto64, load(Ity_I16, mkexpr(op2addr))));
3888 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3889
3890 return "cgh";
3891}
3892
3893static HChar *
3894s390_irgen_CHI(UChar r1, UShort i2)
3895{
3896 IRTemp op1 = newTemp(Ity_I32);
3897 Int op2;
3898
3899 assign(op1, get_gpr_w1(r1));
3900 op2 = (Int)(Short)i2;
3901 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
3902 mkU32((UInt)op2)));
3903
3904 return "chi";
3905}
3906
3907static HChar *
3908s390_irgen_CGHI(UChar r1, UShort i2)
3909{
3910 IRTemp op1 = newTemp(Ity_I64);
3911 Long op2;
3912
3913 assign(op1, get_gpr_dw0(r1));
3914 op2 = (Long)(Short)i2;
3915 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
3916 mkU64((ULong)op2)));
3917
3918 return "cghi";
3919}
3920
3921static HChar *
3922s390_irgen_CHHSI(UShort i2, IRTemp op1addr)
3923{
3924 IRTemp op1 = newTemp(Ity_I16);
3925 Short op2;
3926
3927 assign(op1, load(Ity_I16, mkexpr(op1addr)));
3928 op2 = (Short)i2;
3929 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I16,
3930 mkU16((UShort)op2)));
3931
3932 return "chhsi";
3933}
3934
3935static HChar *
3936s390_irgen_CHSI(UShort i2, IRTemp op1addr)
3937{
3938 IRTemp op1 = newTemp(Ity_I32);
3939 Int op2;
3940
3941 assign(op1, load(Ity_I32, mkexpr(op1addr)));
3942 op2 = (Int)(Short)i2;
3943 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
3944 mkU32((UInt)op2)));
3945
3946 return "chsi";
3947}
3948
3949static HChar *
3950s390_irgen_CGHSI(UShort i2, IRTemp op1addr)
3951{
3952 IRTemp op1 = newTemp(Ity_I64);
3953 Long op2;
3954
3955 assign(op1, load(Ity_I64, mkexpr(op1addr)));
3956 op2 = (Long)(Short)i2;
3957 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
3958 mkU64((ULong)op2)));
3959
3960 return "cghsi";
3961}
3962
3963static HChar *
3964s390_irgen_CHRL(UChar r1, UInt i2)
3965{
3966 IRTemp op1 = newTemp(Ity_I32);
3967 IRTemp op2 = newTemp(Ity_I32);
3968
3969 assign(op1, get_gpr_w1(r1));
3970 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
3971 ((ULong)(Long)(Int)i2 << 1)))));
3972 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3973
3974 return "chrl";
3975}
3976
3977static HChar *
3978s390_irgen_CGHRL(UChar r1, UInt i2)
3979{
3980 IRTemp op1 = newTemp(Ity_I64);
3981 IRTemp op2 = newTemp(Ity_I64);
3982
3983 assign(op1, get_gpr_dw0(r1));
3984 assign(op2, unop(Iop_16Sto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
3985 ((ULong)(Long)(Int)i2 << 1)))));
3986 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3987
3988 return "cghrl";
3989}
3990
3991static HChar *
3992s390_irgen_CHHR(UChar r1, UChar r2)
3993{
3994 IRTemp op1 = newTemp(Ity_I32);
3995 IRTemp op2 = newTemp(Ity_I32);
3996
3997 assign(op1, get_gpr_w0(r1));
3998 assign(op2, get_gpr_w0(r2));
3999 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4000
4001 return "chhr";
4002}
4003
4004static HChar *
4005s390_irgen_CHLR(UChar r1, UChar r2)
4006{
4007 IRTemp op1 = newTemp(Ity_I32);
4008 IRTemp op2 = newTemp(Ity_I32);
4009
4010 assign(op1, get_gpr_w0(r1));
4011 assign(op2, get_gpr_w1(r2));
4012 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4013
4014 return "chlr";
4015}
4016
4017static HChar *
4018s390_irgen_CHF(UChar r1, IRTemp op2addr)
4019{
4020 IRTemp op1 = newTemp(Ity_I32);
4021 IRTemp op2 = newTemp(Ity_I32);
4022
4023 assign(op1, get_gpr_w0(r1));
4024 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4025 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4026
4027 return "chf";
4028}
4029
4030static HChar *
4031s390_irgen_CIH(UChar r1, UInt i2)
4032{
4033 IRTemp op1 = newTemp(Ity_I32);
4034 Int op2;
4035
4036 assign(op1, get_gpr_w0(r1));
4037 op2 = (Int)i2;
4038 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
4039 mkU32((UInt)op2)));
4040
4041 return "cih";
4042}
4043
4044static HChar *
4045s390_irgen_CLR(UChar r1, UChar r2)
4046{
4047 IRTemp op1 = newTemp(Ity_I32);
4048 IRTemp op2 = newTemp(Ity_I32);
4049
4050 assign(op1, get_gpr_w1(r1));
4051 assign(op2, get_gpr_w1(r2));
4052 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4053
4054 return "clr";
4055}
4056
4057static HChar *
4058s390_irgen_CLGR(UChar r1, UChar r2)
4059{
4060 IRTemp op1 = newTemp(Ity_I64);
4061 IRTemp op2 = newTemp(Ity_I64);
4062
4063 assign(op1, get_gpr_dw0(r1));
4064 assign(op2, get_gpr_dw0(r2));
4065 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4066
4067 return "clgr";
4068}
4069
4070static HChar *
4071s390_irgen_CLGFR(UChar r1, UChar r2)
4072{
4073 IRTemp op1 = newTemp(Ity_I64);
4074 IRTemp op2 = newTemp(Ity_I64);
4075
4076 assign(op1, get_gpr_dw0(r1));
4077 assign(op2, unop(Iop_32Uto64, get_gpr_w1(r2)));
4078 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4079
4080 return "clgfr";
4081}
4082
4083static HChar *
4084s390_irgen_CL(UChar r1, IRTemp op2addr)
4085{
4086 IRTemp op1 = newTemp(Ity_I32);
4087 IRTemp op2 = newTemp(Ity_I32);
4088
4089 assign(op1, get_gpr_w1(r1));
4090 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4091 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4092
4093 return "cl";
4094}
4095
4096static HChar *
4097s390_irgen_CLY(UChar r1, IRTemp op2addr)
4098{
4099 IRTemp op1 = newTemp(Ity_I32);
4100 IRTemp op2 = newTemp(Ity_I32);
4101
4102 assign(op1, get_gpr_w1(r1));
4103 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4104 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4105
4106 return "cly";
4107}
4108
4109static HChar *
4110s390_irgen_CLG(UChar r1, IRTemp op2addr)
4111{
4112 IRTemp op1 = newTemp(Ity_I64);
4113 IRTemp op2 = newTemp(Ity_I64);
4114
4115 assign(op1, get_gpr_dw0(r1));
4116 assign(op2, load(Ity_I64, mkexpr(op2addr)));
4117 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4118
4119 return "clg";
4120}
4121
4122static HChar *
4123s390_irgen_CLGF(UChar r1, IRTemp op2addr)
4124{
4125 IRTemp op1 = newTemp(Ity_I64);
4126 IRTemp op2 = newTemp(Ity_I64);
4127
4128 assign(op1, get_gpr_dw0(r1));
4129 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
4130 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4131
4132 return "clgf";
4133}
4134
4135static HChar *
4136s390_irgen_CLFI(UChar r1, UInt i2)
4137{
4138 IRTemp op1 = newTemp(Ity_I32);
4139 UInt op2;
4140
4141 assign(op1, get_gpr_w1(r1));
4142 op2 = i2;
4143 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
4144 mkU32(op2)));
4145
4146 return "clfi";
4147}
4148
4149static HChar *
4150s390_irgen_CLGFI(UChar r1, UInt i2)
4151{
4152 IRTemp op1 = newTemp(Ity_I64);
4153 ULong op2;
4154
4155 assign(op1, get_gpr_dw0(r1));
4156 op2 = (ULong)i2;
4157 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I64,
4158 mkU64(op2)));
4159
4160 return "clgfi";
4161}
4162
4163static HChar *
4164s390_irgen_CLI(UChar i2, IRTemp op1addr)
4165{
4166 IRTemp op1 = newTemp(Ity_I8);
4167 UChar op2;
4168
4169 assign(op1, load(Ity_I8, mkexpr(op1addr)));
4170 op2 = i2;
4171 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I8,
4172 mkU8(op2)));
4173
4174 return "cli";
4175}
4176
4177static HChar *
4178s390_irgen_CLIY(UChar i2, IRTemp op1addr)
4179{
4180 IRTemp op1 = newTemp(Ity_I8);
4181 UChar op2;
4182
4183 assign(op1, load(Ity_I8, mkexpr(op1addr)));
4184 op2 = i2;
4185 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I8,
4186 mkU8(op2)));
4187
4188 return "cliy";
4189}
4190
4191static HChar *
4192s390_irgen_CLFHSI(UShort i2, IRTemp op1addr)
4193{
4194 IRTemp op1 = newTemp(Ity_I32);
4195 UInt op2;
4196
4197 assign(op1, load(Ity_I32, mkexpr(op1addr)));
4198 op2 = (UInt)i2;
4199 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
4200 mkU32(op2)));
4201
4202 return "clfhsi";
4203}
4204
4205static HChar *
4206s390_irgen_CLGHSI(UShort i2, IRTemp op1addr)
4207{
4208 IRTemp op1 = newTemp(Ity_I64);
4209 ULong op2;
4210
4211 assign(op1, load(Ity_I64, mkexpr(op1addr)));
4212 op2 = (ULong)i2;
4213 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I64,
4214 mkU64(op2)));
4215
4216 return "clghsi";
4217}
4218
4219static HChar *
4220s390_irgen_CLHHSI(UShort i2, IRTemp op1addr)
4221{
4222 IRTemp op1 = newTemp(Ity_I16);
4223 UShort op2;
4224
4225 assign(op1, load(Ity_I16, mkexpr(op1addr)));
4226 op2 = i2;
4227 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I16,
4228 mkU16(op2)));
4229
4230 return "clhhsi";
4231}
4232
4233static HChar *
4234s390_irgen_CLRL(UChar r1, UInt i2)
4235{
4236 IRTemp op1 = newTemp(Ity_I32);
4237 IRTemp op2 = newTemp(Ity_I32);
4238
4239 assign(op1, get_gpr_w1(r1));
4240 assign(op2, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
4241 i2 << 1))));
4242 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4243
4244 return "clrl";
4245}
4246
4247static HChar *
4248s390_irgen_CLGRL(UChar r1, UInt i2)
4249{
4250 IRTemp op1 = newTemp(Ity_I64);
4251 IRTemp op2 = newTemp(Ity_I64);
4252
4253 assign(op1, get_gpr_dw0(r1));
4254 assign(op2, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
4255 i2 << 1))));
4256 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4257
4258 return "clgrl";
4259}
4260
4261static HChar *
4262s390_irgen_CLGFRL(UChar r1, UInt i2)
4263{
4264 IRTemp op1 = newTemp(Ity_I64);
4265 IRTemp op2 = newTemp(Ity_I64);
4266
4267 assign(op1, get_gpr_dw0(r1));
4268 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
4269 ((ULong)(Long)(Int)i2 << 1)))));
4270 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4271
4272 return "clgfrl";
4273}
4274
4275static HChar *
4276s390_irgen_CLHRL(UChar r1, UInt i2)
4277{
4278 IRTemp op1 = newTemp(Ity_I32);
4279 IRTemp op2 = newTemp(Ity_I32);
4280
4281 assign(op1, get_gpr_w1(r1));
4282 assign(op2, unop(Iop_16Uto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
4283 ((ULong)(Long)(Int)i2 << 1)))));
4284 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4285
4286 return "clhrl";
4287}
4288
4289static HChar *
4290s390_irgen_CLGHRL(UChar r1, UInt i2)
4291{
4292 IRTemp op1 = newTemp(Ity_I64);
4293 IRTemp op2 = newTemp(Ity_I64);
4294
4295 assign(op1, get_gpr_dw0(r1));
4296 assign(op2, unop(Iop_16Uto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
4297 ((ULong)(Long)(Int)i2 << 1)))));
4298 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4299
4300 return "clghrl";
4301}
4302
4303static HChar *
4304s390_irgen_CLRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
4305{
4306 IRTemp op1 = newTemp(Ity_I32);
4307 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00004308 IRTemp cond = newTemp(Ity_I32);
4309
4310 if (m3 == 0) {
4311 } else {
4312 if (m3 == 14) {
4313 always_goto(mkexpr(op4addr));
4314 } else {
4315 assign(op1, get_gpr_w1(r1));
4316 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00004317 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4318 op1, op2));
florianf321da72012-07-21 20:32:57 +00004319 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4320 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004321 }
4322 }
4323
4324 return "clrb";
4325}
4326
4327static HChar *
4328s390_irgen_CLGRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
4329{
4330 IRTemp op1 = newTemp(Ity_I64);
4331 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00004332 IRTemp cond = newTemp(Ity_I32);
4333
4334 if (m3 == 0) {
4335 } else {
4336 if (m3 == 14) {
4337 always_goto(mkexpr(op4addr));
4338 } else {
4339 assign(op1, get_gpr_dw0(r1));
4340 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00004341 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4342 op1, op2));
florianf321da72012-07-21 20:32:57 +00004343 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4344 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004345 }
4346 }
4347
4348 return "clgrb";
4349}
4350
4351static HChar *
4352s390_irgen_CLRJ(UChar r1, UChar r2, UShort i4, UChar m3)
4353{
4354 IRTemp op1 = newTemp(Ity_I32);
4355 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00004356 IRTemp cond = newTemp(Ity_I32);
4357
4358 if (m3 == 0) {
4359 } else {
4360 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004361 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004362 } else {
4363 assign(op1, get_gpr_w1(r1));
4364 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00004365 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4366 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00004367 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4368 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4369
4370 }
4371 }
4372
4373 return "clrj";
4374}
4375
4376static HChar *
4377s390_irgen_CLGRJ(UChar r1, UChar r2, UShort i4, UChar m3)
4378{
4379 IRTemp op1 = newTemp(Ity_I64);
4380 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00004381 IRTemp cond = newTemp(Ity_I32);
4382
4383 if (m3 == 0) {
4384 } else {
4385 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004386 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004387 } else {
4388 assign(op1, get_gpr_dw0(r1));
4389 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00004390 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4391 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00004392 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4393 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4394
4395 }
4396 }
4397
4398 return "clgrj";
4399}
4400
4401static HChar *
4402s390_irgen_CLIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
4403{
4404 IRTemp op1 = newTemp(Ity_I32);
4405 UInt op2;
sewardj2019a972011-03-07 16:04:07 +00004406 IRTemp cond = newTemp(Ity_I32);
4407
4408 if (m3 == 0) {
4409 } else {
4410 if (m3 == 14) {
4411 always_goto(mkexpr(op4addr));
4412 } else {
4413 assign(op1, get_gpr_w1(r1));
4414 op2 = (UInt)i2;
florianff9613f2012-05-12 15:26:44 +00004415 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4416 mktemp(Ity_I32, mkU32(op2))));
florianf321da72012-07-21 20:32:57 +00004417 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4418 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004419 }
4420 }
4421
4422 return "clib";
4423}
4424
4425static HChar *
4426s390_irgen_CLGIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
4427{
4428 IRTemp op1 = newTemp(Ity_I64);
4429 ULong op2;
sewardj2019a972011-03-07 16:04:07 +00004430 IRTemp cond = newTemp(Ity_I32);
4431
4432 if (m3 == 0) {
4433 } else {
4434 if (m3 == 14) {
4435 always_goto(mkexpr(op4addr));
4436 } else {
4437 assign(op1, get_gpr_dw0(r1));
4438 op2 = (ULong)i2;
florianff9613f2012-05-12 15:26:44 +00004439 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4440 mktemp(Ity_I64, mkU64(op2))));
florianf321da72012-07-21 20:32:57 +00004441 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4442 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004443 }
4444 }
4445
4446 return "clgib";
4447}
4448
4449static HChar *
4450s390_irgen_CLIJ(UChar r1, UChar m3, UShort i4, UChar i2)
4451{
4452 IRTemp op1 = newTemp(Ity_I32);
4453 UInt op2;
sewardj2019a972011-03-07 16:04:07 +00004454 IRTemp cond = newTemp(Ity_I32);
4455
4456 if (m3 == 0) {
4457 } else {
4458 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004459 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004460 } else {
4461 assign(op1, get_gpr_w1(r1));
4462 op2 = (UInt)i2;
florianff9613f2012-05-12 15:26:44 +00004463 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4464 mktemp(Ity_I32, mkU32(op2))));
sewardj2019a972011-03-07 16:04:07 +00004465 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4466 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4467
4468 }
4469 }
4470
4471 return "clij";
4472}
4473
4474static HChar *
4475s390_irgen_CLGIJ(UChar r1, UChar m3, UShort i4, UChar i2)
4476{
4477 IRTemp op1 = newTemp(Ity_I64);
4478 ULong op2;
sewardj2019a972011-03-07 16:04:07 +00004479 IRTemp cond = newTemp(Ity_I32);
4480
4481 if (m3 == 0) {
4482 } else {
4483 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004484 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004485 } else {
4486 assign(op1, get_gpr_dw0(r1));
4487 op2 = (ULong)i2;
florianff9613f2012-05-12 15:26:44 +00004488 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4489 mktemp(Ity_I64, mkU64(op2))));
sewardj2019a972011-03-07 16:04:07 +00004490 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4491 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4492
4493 }
4494 }
4495
4496 return "clgij";
4497}
4498
4499static HChar *
4500s390_irgen_CLM(UChar r1, UChar r3, IRTemp op2addr)
4501{
4502 IRTemp op1 = newTemp(Ity_I32);
4503 IRTemp op2 = newTemp(Ity_I32);
4504 IRTemp b0 = newTemp(Ity_I32);
4505 IRTemp b1 = newTemp(Ity_I32);
4506 IRTemp b2 = newTemp(Ity_I32);
4507 IRTemp b3 = newTemp(Ity_I32);
4508 IRTemp c0 = newTemp(Ity_I32);
4509 IRTemp c1 = newTemp(Ity_I32);
4510 IRTemp c2 = newTemp(Ity_I32);
4511 IRTemp c3 = newTemp(Ity_I32);
4512 UChar n;
4513
4514 n = 0;
4515 if ((r3 & 8) != 0) {
4516 assign(b0, unop(Iop_8Uto32, get_gpr_b4(r1)));
4517 assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
4518 n = n + 1;
4519 } else {
4520 assign(b0, mkU32(0));
4521 assign(c0, mkU32(0));
4522 }
4523 if ((r3 & 4) != 0) {
4524 assign(b1, unop(Iop_8Uto32, get_gpr_b5(r1)));
4525 assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4526 mkU64(n)))));
4527 n = n + 1;
4528 } else {
4529 assign(b1, mkU32(0));
4530 assign(c1, mkU32(0));
4531 }
4532 if ((r3 & 2) != 0) {
4533 assign(b2, unop(Iop_8Uto32, get_gpr_b6(r1)));
4534 assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4535 mkU64(n)))));
4536 n = n + 1;
4537 } else {
4538 assign(b2, mkU32(0));
4539 assign(c2, mkU32(0));
4540 }
4541 if ((r3 & 1) != 0) {
4542 assign(b3, unop(Iop_8Uto32, get_gpr_b7(r1)));
4543 assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4544 mkU64(n)))));
4545 n = n + 1;
4546 } else {
4547 assign(b3, mkU32(0));
4548 assign(c3, mkU32(0));
4549 }
4550 assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4551 mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
4552 binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
4553 assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4554 mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
4555 binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
4556 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4557
4558 return "clm";
4559}
4560
4561static HChar *
4562s390_irgen_CLMY(UChar r1, UChar r3, IRTemp op2addr)
4563{
4564 IRTemp op1 = newTemp(Ity_I32);
4565 IRTemp op2 = newTemp(Ity_I32);
4566 IRTemp b0 = newTemp(Ity_I32);
4567 IRTemp b1 = newTemp(Ity_I32);
4568 IRTemp b2 = newTemp(Ity_I32);
4569 IRTemp b3 = newTemp(Ity_I32);
4570 IRTemp c0 = newTemp(Ity_I32);
4571 IRTemp c1 = newTemp(Ity_I32);
4572 IRTemp c2 = newTemp(Ity_I32);
4573 IRTemp c3 = newTemp(Ity_I32);
4574 UChar n;
4575
4576 n = 0;
4577 if ((r3 & 8) != 0) {
4578 assign(b0, unop(Iop_8Uto32, get_gpr_b4(r1)));
4579 assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
4580 n = n + 1;
4581 } else {
4582 assign(b0, mkU32(0));
4583 assign(c0, mkU32(0));
4584 }
4585 if ((r3 & 4) != 0) {
4586 assign(b1, unop(Iop_8Uto32, get_gpr_b5(r1)));
4587 assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4588 mkU64(n)))));
4589 n = n + 1;
4590 } else {
4591 assign(b1, mkU32(0));
4592 assign(c1, mkU32(0));
4593 }
4594 if ((r3 & 2) != 0) {
4595 assign(b2, unop(Iop_8Uto32, get_gpr_b6(r1)));
4596 assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4597 mkU64(n)))));
4598 n = n + 1;
4599 } else {
4600 assign(b2, mkU32(0));
4601 assign(c2, mkU32(0));
4602 }
4603 if ((r3 & 1) != 0) {
4604 assign(b3, unop(Iop_8Uto32, get_gpr_b7(r1)));
4605 assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4606 mkU64(n)))));
4607 n = n + 1;
4608 } else {
4609 assign(b3, mkU32(0));
4610 assign(c3, mkU32(0));
4611 }
4612 assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4613 mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
4614 binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
4615 assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4616 mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
4617 binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
4618 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4619
4620 return "clmy";
4621}
4622
4623static HChar *
4624s390_irgen_CLMH(UChar r1, UChar r3, IRTemp op2addr)
4625{
4626 IRTemp op1 = newTemp(Ity_I32);
4627 IRTemp op2 = newTemp(Ity_I32);
4628 IRTemp b0 = newTemp(Ity_I32);
4629 IRTemp b1 = newTemp(Ity_I32);
4630 IRTemp b2 = newTemp(Ity_I32);
4631 IRTemp b3 = newTemp(Ity_I32);
4632 IRTemp c0 = newTemp(Ity_I32);
4633 IRTemp c1 = newTemp(Ity_I32);
4634 IRTemp c2 = newTemp(Ity_I32);
4635 IRTemp c3 = newTemp(Ity_I32);
4636 UChar n;
4637
4638 n = 0;
4639 if ((r3 & 8) != 0) {
4640 assign(b0, unop(Iop_8Uto32, get_gpr_b0(r1)));
4641 assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
4642 n = n + 1;
4643 } else {
4644 assign(b0, mkU32(0));
4645 assign(c0, mkU32(0));
4646 }
4647 if ((r3 & 4) != 0) {
4648 assign(b1, unop(Iop_8Uto32, get_gpr_b1(r1)));
4649 assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4650 mkU64(n)))));
4651 n = n + 1;
4652 } else {
4653 assign(b1, mkU32(0));
4654 assign(c1, mkU32(0));
4655 }
4656 if ((r3 & 2) != 0) {
4657 assign(b2, unop(Iop_8Uto32, get_gpr_b2(r1)));
4658 assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4659 mkU64(n)))));
4660 n = n + 1;
4661 } else {
4662 assign(b2, mkU32(0));
4663 assign(c2, mkU32(0));
4664 }
4665 if ((r3 & 1) != 0) {
4666 assign(b3, unop(Iop_8Uto32, get_gpr_b3(r1)));
4667 assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4668 mkU64(n)))));
4669 n = n + 1;
4670 } else {
4671 assign(b3, mkU32(0));
4672 assign(c3, mkU32(0));
4673 }
4674 assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4675 mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
4676 binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
4677 assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4678 mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
4679 binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
4680 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4681
4682 return "clmh";
4683}
4684
4685static HChar *
4686s390_irgen_CLHHR(UChar r1, UChar r2)
4687{
4688 IRTemp op1 = newTemp(Ity_I32);
4689 IRTemp op2 = newTemp(Ity_I32);
4690
4691 assign(op1, get_gpr_w0(r1));
4692 assign(op2, get_gpr_w0(r2));
4693 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4694
4695 return "clhhr";
4696}
4697
4698static HChar *
4699s390_irgen_CLHLR(UChar r1, UChar r2)
4700{
4701 IRTemp op1 = newTemp(Ity_I32);
4702 IRTemp op2 = newTemp(Ity_I32);
4703
4704 assign(op1, get_gpr_w0(r1));
4705 assign(op2, get_gpr_w1(r2));
4706 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4707
4708 return "clhlr";
4709}
4710
4711static HChar *
4712s390_irgen_CLHF(UChar r1, IRTemp op2addr)
4713{
4714 IRTemp op1 = newTemp(Ity_I32);
4715 IRTemp op2 = newTemp(Ity_I32);
4716
4717 assign(op1, get_gpr_w0(r1));
4718 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4719 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4720
4721 return "clhf";
4722}
4723
4724static HChar *
4725s390_irgen_CLIH(UChar r1, UInt i2)
4726{
4727 IRTemp op1 = newTemp(Ity_I32);
4728 UInt op2;
4729
4730 assign(op1, get_gpr_w0(r1));
4731 op2 = i2;
4732 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
4733 mkU32(op2)));
4734
4735 return "clih";
4736}
4737
4738static HChar *
4739s390_irgen_CPYA(UChar r1, UChar r2)
4740{
4741 put_ar_w0(r1, get_ar_w0(r2));
sewardj7ee97522011-05-09 21:45:04 +00004742 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00004743 s390_disasm(ENC3(MNM, AR, AR), "cpya", r1, r2);
4744
4745 return "cpya";
4746}
4747
4748static HChar *
4749s390_irgen_XR(UChar r1, UChar r2)
4750{
4751 IRTemp op1 = newTemp(Ity_I32);
4752 IRTemp op2 = newTemp(Ity_I32);
4753 IRTemp result = newTemp(Ity_I32);
4754
4755 if (r1 == r2) {
4756 assign(result, mkU32(0));
4757 } else {
4758 assign(op1, get_gpr_w1(r1));
4759 assign(op2, get_gpr_w1(r2));
4760 assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2)));
4761 }
4762 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4763 put_gpr_w1(r1, mkexpr(result));
4764
4765 return "xr";
4766}
4767
4768static HChar *
4769s390_irgen_XGR(UChar r1, UChar r2)
4770{
4771 IRTemp op1 = newTemp(Ity_I64);
4772 IRTemp op2 = newTemp(Ity_I64);
4773 IRTemp result = newTemp(Ity_I64);
4774
4775 if (r1 == r2) {
4776 assign(result, mkU64(0));
4777 } else {
4778 assign(op1, get_gpr_dw0(r1));
4779 assign(op2, get_gpr_dw0(r2));
4780 assign(result, binop(Iop_Xor64, mkexpr(op1), mkexpr(op2)));
4781 }
4782 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4783 put_gpr_dw0(r1, mkexpr(result));
4784
4785 return "xgr";
4786}
4787
4788static HChar *
4789s390_irgen_XRK(UChar r3, UChar r1, UChar r2)
4790{
4791 IRTemp op2 = newTemp(Ity_I32);
4792 IRTemp op3 = newTemp(Ity_I32);
4793 IRTemp result = newTemp(Ity_I32);
4794
4795 assign(op2, get_gpr_w1(r2));
4796 assign(op3, get_gpr_w1(r3));
4797 assign(result, binop(Iop_Xor32, mkexpr(op2), mkexpr(op3)));
4798 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4799 put_gpr_w1(r1, mkexpr(result));
4800
4801 return "xrk";
4802}
4803
4804static HChar *
4805s390_irgen_XGRK(UChar r3, UChar r1, UChar r2)
4806{
4807 IRTemp op2 = newTemp(Ity_I64);
4808 IRTemp op3 = newTemp(Ity_I64);
4809 IRTemp result = newTemp(Ity_I64);
4810
4811 assign(op2, get_gpr_dw0(r2));
4812 assign(op3, get_gpr_dw0(r3));
4813 assign(result, binop(Iop_Xor64, mkexpr(op2), mkexpr(op3)));
4814 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4815 put_gpr_dw0(r1, mkexpr(result));
4816
4817 return "xgrk";
4818}
4819
4820static HChar *
4821s390_irgen_X(UChar r1, IRTemp op2addr)
4822{
4823 IRTemp op1 = newTemp(Ity_I32);
4824 IRTemp op2 = newTemp(Ity_I32);
4825 IRTemp result = newTemp(Ity_I32);
4826
4827 assign(op1, get_gpr_w1(r1));
4828 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4829 assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2)));
4830 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4831 put_gpr_w1(r1, mkexpr(result));
4832
4833 return "x";
4834}
4835
4836static HChar *
4837s390_irgen_XY(UChar r1, IRTemp op2addr)
4838{
4839 IRTemp op1 = newTemp(Ity_I32);
4840 IRTemp op2 = newTemp(Ity_I32);
4841 IRTemp result = newTemp(Ity_I32);
4842
4843 assign(op1, get_gpr_w1(r1));
4844 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4845 assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2)));
4846 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4847 put_gpr_w1(r1, mkexpr(result));
4848
4849 return "xy";
4850}
4851
4852static HChar *
4853s390_irgen_XG(UChar r1, IRTemp op2addr)
4854{
4855 IRTemp op1 = newTemp(Ity_I64);
4856 IRTemp op2 = newTemp(Ity_I64);
4857 IRTemp result = newTemp(Ity_I64);
4858
4859 assign(op1, get_gpr_dw0(r1));
4860 assign(op2, load(Ity_I64, mkexpr(op2addr)));
4861 assign(result, binop(Iop_Xor64, mkexpr(op1), mkexpr(op2)));
4862 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4863 put_gpr_dw0(r1, mkexpr(result));
4864
4865 return "xg";
4866}
4867
4868static HChar *
4869s390_irgen_XI(UChar i2, IRTemp op1addr)
4870{
4871 IRTemp op1 = newTemp(Ity_I8);
4872 UChar op2;
4873 IRTemp result = newTemp(Ity_I8);
4874
4875 assign(op1, load(Ity_I8, mkexpr(op1addr)));
4876 op2 = i2;
4877 assign(result, binop(Iop_Xor8, mkexpr(op1), mkU8(op2)));
4878 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4879 store(mkexpr(op1addr), mkexpr(result));
4880
4881 return "xi";
4882}
4883
4884static HChar *
4885s390_irgen_XIY(UChar i2, IRTemp op1addr)
4886{
4887 IRTemp op1 = newTemp(Ity_I8);
4888 UChar op2;
4889 IRTemp result = newTemp(Ity_I8);
4890
4891 assign(op1, load(Ity_I8, mkexpr(op1addr)));
4892 op2 = i2;
4893 assign(result, binop(Iop_Xor8, mkexpr(op1), mkU8(op2)));
4894 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4895 store(mkexpr(op1addr), mkexpr(result));
4896
4897 return "xiy";
4898}
4899
4900static HChar *
4901s390_irgen_XIHF(UChar r1, UInt i2)
4902{
4903 IRTemp op1 = newTemp(Ity_I32);
4904 UInt op2;
4905 IRTemp result = newTemp(Ity_I32);
4906
4907 assign(op1, get_gpr_w0(r1));
4908 op2 = i2;
4909 assign(result, binop(Iop_Xor32, mkexpr(op1), mkU32(op2)));
4910 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4911 put_gpr_w0(r1, mkexpr(result));
4912
4913 return "xihf";
4914}
4915
4916static HChar *
4917s390_irgen_XILF(UChar r1, UInt i2)
4918{
4919 IRTemp op1 = newTemp(Ity_I32);
4920 UInt op2;
4921 IRTemp result = newTemp(Ity_I32);
4922
4923 assign(op1, get_gpr_w1(r1));
4924 op2 = i2;
4925 assign(result, binop(Iop_Xor32, mkexpr(op1), mkU32(op2)));
4926 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4927 put_gpr_w1(r1, mkexpr(result));
4928
4929 return "xilf";
4930}
4931
4932static HChar *
4933s390_irgen_EAR(UChar r1, UChar r2)
4934{
4935 put_gpr_w1(r1, get_ar_w0(r2));
sewardj7ee97522011-05-09 21:45:04 +00004936 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00004937 s390_disasm(ENC3(MNM, GPR, AR), "ear", r1, r2);
4938
4939 return "ear";
4940}
4941
4942static HChar *
4943s390_irgen_IC(UChar r1, IRTemp op2addr)
4944{
4945 put_gpr_b7(r1, load(Ity_I8, mkexpr(op2addr)));
4946
4947 return "ic";
4948}
4949
4950static HChar *
4951s390_irgen_ICY(UChar r1, IRTemp op2addr)
4952{
4953 put_gpr_b7(r1, load(Ity_I8, mkexpr(op2addr)));
4954
4955 return "icy";
4956}
4957
4958static HChar *
4959s390_irgen_ICM(UChar r1, UChar r3, IRTemp op2addr)
4960{
4961 UChar n;
4962 IRTemp result = newTemp(Ity_I32);
4963 UInt mask;
4964
4965 n = 0;
4966 mask = (UInt)r3;
4967 if ((mask & 8) != 0) {
4968 put_gpr_b4(r1, load(Ity_I8, mkexpr(op2addr)));
4969 n = n + 1;
4970 }
4971 if ((mask & 4) != 0) {
4972 put_gpr_b5(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
4973
4974 n = n + 1;
4975 }
4976 if ((mask & 2) != 0) {
4977 put_gpr_b6(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
4978
4979 n = n + 1;
4980 }
4981 if ((mask & 1) != 0) {
4982 put_gpr_b7(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
4983
4984 n = n + 1;
4985 }
4986 assign(result, get_gpr_w1(r1));
4987 s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
4988 mkU32(mask)));
4989
4990 return "icm";
4991}
4992
4993static HChar *
4994s390_irgen_ICMY(UChar r1, UChar r3, IRTemp op2addr)
4995{
4996 UChar n;
4997 IRTemp result = newTemp(Ity_I32);
4998 UInt mask;
4999
5000 n = 0;
5001 mask = (UInt)r3;
5002 if ((mask & 8) != 0) {
5003 put_gpr_b4(r1, load(Ity_I8, mkexpr(op2addr)));
5004 n = n + 1;
5005 }
5006 if ((mask & 4) != 0) {
5007 put_gpr_b5(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5008
5009 n = n + 1;
5010 }
5011 if ((mask & 2) != 0) {
5012 put_gpr_b6(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5013
5014 n = n + 1;
5015 }
5016 if ((mask & 1) != 0) {
5017 put_gpr_b7(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5018
5019 n = n + 1;
5020 }
5021 assign(result, get_gpr_w1(r1));
5022 s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
5023 mkU32(mask)));
5024
5025 return "icmy";
5026}
5027
5028static HChar *
5029s390_irgen_ICMH(UChar r1, UChar r3, IRTemp op2addr)
5030{
5031 UChar n;
5032 IRTemp result = newTemp(Ity_I32);
5033 UInt mask;
5034
5035 n = 0;
5036 mask = (UInt)r3;
5037 if ((mask & 8) != 0) {
5038 put_gpr_b0(r1, load(Ity_I8, mkexpr(op2addr)));
5039 n = n + 1;
5040 }
5041 if ((mask & 4) != 0) {
5042 put_gpr_b1(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5043
5044 n = n + 1;
5045 }
5046 if ((mask & 2) != 0) {
5047 put_gpr_b2(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5048
5049 n = n + 1;
5050 }
5051 if ((mask & 1) != 0) {
5052 put_gpr_b3(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5053
5054 n = n + 1;
5055 }
5056 assign(result, get_gpr_w0(r1));
5057 s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
5058 mkU32(mask)));
5059
5060 return "icmh";
5061}
5062
5063static HChar *
5064s390_irgen_IIHF(UChar r1, UInt i2)
5065{
5066 put_gpr_w0(r1, mkU32(i2));
5067
5068 return "iihf";
5069}
5070
5071static HChar *
5072s390_irgen_IIHH(UChar r1, UShort i2)
5073{
5074 put_gpr_hw0(r1, mkU16(i2));
5075
5076 return "iihh";
5077}
5078
5079static HChar *
5080s390_irgen_IIHL(UChar r1, UShort i2)
5081{
5082 put_gpr_hw1(r1, mkU16(i2));
5083
5084 return "iihl";
5085}
5086
5087static HChar *
5088s390_irgen_IILF(UChar r1, UInt i2)
5089{
5090 put_gpr_w1(r1, mkU32(i2));
5091
5092 return "iilf";
5093}
5094
5095static HChar *
5096s390_irgen_IILH(UChar r1, UShort i2)
5097{
5098 put_gpr_hw2(r1, mkU16(i2));
5099
5100 return "iilh";
5101}
5102
5103static HChar *
5104s390_irgen_IILL(UChar r1, UShort i2)
5105{
5106 put_gpr_hw3(r1, mkU16(i2));
5107
5108 return "iill";
5109}
5110
5111static HChar *
5112s390_irgen_LR(UChar r1, UChar r2)
5113{
5114 put_gpr_w1(r1, get_gpr_w1(r2));
5115
5116 return "lr";
5117}
5118
5119static HChar *
5120s390_irgen_LGR(UChar r1, UChar r2)
5121{
5122 put_gpr_dw0(r1, get_gpr_dw0(r2));
5123
5124 return "lgr";
5125}
5126
5127static HChar *
5128s390_irgen_LGFR(UChar r1, UChar r2)
5129{
5130 put_gpr_dw0(r1, unop(Iop_32Sto64, get_gpr_w1(r2)));
5131
5132 return "lgfr";
5133}
5134
5135static HChar *
5136s390_irgen_L(UChar r1, IRTemp op2addr)
5137{
5138 put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
5139
5140 return "l";
5141}
5142
5143static HChar *
5144s390_irgen_LY(UChar r1, IRTemp op2addr)
5145{
5146 put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
5147
5148 return "ly";
5149}
5150
5151static HChar *
5152s390_irgen_LG(UChar r1, IRTemp op2addr)
5153{
5154 put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
5155
5156 return "lg";
5157}
5158
5159static HChar *
5160s390_irgen_LGF(UChar r1, IRTemp op2addr)
5161{
5162 put_gpr_dw0(r1, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
5163
5164 return "lgf";
5165}
5166
5167static HChar *
5168s390_irgen_LGFI(UChar r1, UInt i2)
5169{
5170 put_gpr_dw0(r1, mkU64((ULong)(Long)(Int)i2));
5171
5172 return "lgfi";
5173}
5174
5175static HChar *
5176s390_irgen_LRL(UChar r1, UInt i2)
5177{
5178 put_gpr_w1(r1, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
5179 i2 << 1))));
5180
5181 return "lrl";
5182}
5183
5184static HChar *
5185s390_irgen_LGRL(UChar r1, UInt i2)
5186{
5187 put_gpr_dw0(r1, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
5188 i2 << 1))));
5189
5190 return "lgrl";
5191}
5192
5193static HChar *
5194s390_irgen_LGFRL(UChar r1, UInt i2)
5195{
5196 put_gpr_dw0(r1, unop(Iop_32Sto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
5197 ((ULong)(Long)(Int)i2 << 1)))));
5198
5199 return "lgfrl";
5200}
5201
5202static HChar *
5203s390_irgen_LA(UChar r1, IRTemp op2addr)
5204{
5205 put_gpr_dw0(r1, mkexpr(op2addr));
5206
5207 return "la";
5208}
5209
5210static HChar *
5211s390_irgen_LAY(UChar r1, IRTemp op2addr)
5212{
5213 put_gpr_dw0(r1, mkexpr(op2addr));
5214
5215 return "lay";
5216}
5217
5218static HChar *
5219s390_irgen_LAE(UChar r1, IRTemp op2addr)
5220{
5221 put_gpr_dw0(r1, mkexpr(op2addr));
5222
5223 return "lae";
5224}
5225
5226static HChar *
5227s390_irgen_LAEY(UChar r1, IRTemp op2addr)
5228{
5229 put_gpr_dw0(r1, mkexpr(op2addr));
5230
5231 return "laey";
5232}
5233
5234static HChar *
5235s390_irgen_LARL(UChar r1, UInt i2)
5236{
5237 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)));
5238
5239 return "larl";
5240}
5241
5242static HChar *
5243s390_irgen_LAA(UChar r1, UChar r3, IRTemp op2addr)
5244{
5245 IRTemp op2 = newTemp(Ity_I32);
5246 IRTemp op3 = newTemp(Ity_I32);
5247 IRTemp result = newTemp(Ity_I32);
5248
5249 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5250 assign(op3, get_gpr_w1(r3));
5251 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
5252 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
5253 store(mkexpr(op2addr), mkexpr(result));
5254 put_gpr_w1(r1, mkexpr(op2));
5255
5256 return "laa";
5257}
5258
5259static HChar *
5260s390_irgen_LAAG(UChar r1, UChar r3, IRTemp op2addr)
5261{
5262 IRTemp op2 = newTemp(Ity_I64);
5263 IRTemp op3 = newTemp(Ity_I64);
5264 IRTemp result = newTemp(Ity_I64);
5265
5266 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5267 assign(op3, get_gpr_dw0(r3));
5268 assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
5269 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op2, op3);
5270 store(mkexpr(op2addr), mkexpr(result));
5271 put_gpr_dw0(r1, mkexpr(op2));
5272
5273 return "laag";
5274}
5275
5276static HChar *
5277s390_irgen_LAAL(UChar r1, UChar r3, IRTemp op2addr)
5278{
5279 IRTemp op2 = newTemp(Ity_I32);
5280 IRTemp op3 = newTemp(Ity_I32);
5281 IRTemp result = newTemp(Ity_I32);
5282
5283 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5284 assign(op3, get_gpr_w1(r3));
5285 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
5286 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
5287 store(mkexpr(op2addr), mkexpr(result));
5288 put_gpr_w1(r1, mkexpr(op2));
5289
5290 return "laal";
5291}
5292
5293static HChar *
5294s390_irgen_LAALG(UChar r1, UChar r3, IRTemp op2addr)
5295{
5296 IRTemp op2 = newTemp(Ity_I64);
5297 IRTemp op3 = newTemp(Ity_I64);
5298 IRTemp result = newTemp(Ity_I64);
5299
5300 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5301 assign(op3, get_gpr_dw0(r3));
5302 assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
5303 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op2, op3);
5304 store(mkexpr(op2addr), mkexpr(result));
5305 put_gpr_dw0(r1, mkexpr(op2));
5306
5307 return "laalg";
5308}
5309
5310static HChar *
5311s390_irgen_LAN(UChar r1, UChar r3, IRTemp op2addr)
5312{
5313 IRTemp op2 = newTemp(Ity_I32);
5314 IRTemp op3 = newTemp(Ity_I32);
5315 IRTemp result = newTemp(Ity_I32);
5316
5317 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5318 assign(op3, get_gpr_w1(r3));
5319 assign(result, binop(Iop_And32, mkexpr(op2), mkexpr(op3)));
5320 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5321 store(mkexpr(op2addr), mkexpr(result));
5322 put_gpr_w1(r1, mkexpr(op2));
5323
5324 return "lan";
5325}
5326
5327static HChar *
5328s390_irgen_LANG(UChar r1, UChar r3, IRTemp op2addr)
5329{
5330 IRTemp op2 = newTemp(Ity_I64);
5331 IRTemp op3 = newTemp(Ity_I64);
5332 IRTemp result = newTemp(Ity_I64);
5333
5334 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5335 assign(op3, get_gpr_dw0(r3));
5336 assign(result, binop(Iop_And64, mkexpr(op2), mkexpr(op3)));
5337 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5338 store(mkexpr(op2addr), mkexpr(result));
5339 put_gpr_dw0(r1, mkexpr(op2));
5340
5341 return "lang";
5342}
5343
5344static HChar *
5345s390_irgen_LAX(UChar r1, UChar r3, IRTemp op2addr)
5346{
5347 IRTemp op2 = newTemp(Ity_I32);
5348 IRTemp op3 = newTemp(Ity_I32);
5349 IRTemp result = newTemp(Ity_I32);
5350
5351 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5352 assign(op3, get_gpr_w1(r3));
5353 assign(result, binop(Iop_Xor32, mkexpr(op2), mkexpr(op3)));
5354 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5355 store(mkexpr(op2addr), mkexpr(result));
5356 put_gpr_w1(r1, mkexpr(op2));
5357
5358 return "lax";
5359}
5360
5361static HChar *
5362s390_irgen_LAXG(UChar r1, UChar r3, IRTemp op2addr)
5363{
5364 IRTemp op2 = newTemp(Ity_I64);
5365 IRTemp op3 = newTemp(Ity_I64);
5366 IRTemp result = newTemp(Ity_I64);
5367
5368 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5369 assign(op3, get_gpr_dw0(r3));
5370 assign(result, binop(Iop_Xor64, mkexpr(op2), mkexpr(op3)));
5371 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5372 store(mkexpr(op2addr), mkexpr(result));
5373 put_gpr_dw0(r1, mkexpr(op2));
5374
5375 return "laxg";
5376}
5377
5378static HChar *
5379s390_irgen_LAO(UChar r1, UChar r3, IRTemp op2addr)
5380{
5381 IRTemp op2 = newTemp(Ity_I32);
5382 IRTemp op3 = newTemp(Ity_I32);
5383 IRTemp result = newTemp(Ity_I32);
5384
5385 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5386 assign(op3, get_gpr_w1(r3));
5387 assign(result, binop(Iop_Or32, mkexpr(op2), mkexpr(op3)));
5388 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5389 store(mkexpr(op2addr), mkexpr(result));
5390 put_gpr_w1(r1, mkexpr(op2));
5391
5392 return "lao";
5393}
5394
5395static HChar *
5396s390_irgen_LAOG(UChar r1, UChar r3, IRTemp op2addr)
5397{
5398 IRTemp op2 = newTemp(Ity_I64);
5399 IRTemp op3 = newTemp(Ity_I64);
5400 IRTemp result = newTemp(Ity_I64);
5401
5402 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5403 assign(op3, get_gpr_dw0(r3));
5404 assign(result, binop(Iop_Or64, mkexpr(op2), mkexpr(op3)));
5405 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5406 store(mkexpr(op2addr), mkexpr(result));
5407 put_gpr_dw0(r1, mkexpr(op2));
5408
5409 return "laog";
5410}
5411
5412static HChar *
5413s390_irgen_LTR(UChar r1, UChar r2)
5414{
5415 IRTemp op2 = newTemp(Ity_I32);
5416
5417 assign(op2, get_gpr_w1(r2));
5418 put_gpr_w1(r1, mkexpr(op2));
5419 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5420
5421 return "ltr";
5422}
5423
5424static HChar *
5425s390_irgen_LTGR(UChar r1, UChar r2)
5426{
5427 IRTemp op2 = newTemp(Ity_I64);
5428
5429 assign(op2, get_gpr_dw0(r2));
5430 put_gpr_dw0(r1, mkexpr(op2));
5431 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5432
5433 return "ltgr";
5434}
5435
5436static HChar *
5437s390_irgen_LTGFR(UChar r1, UChar r2)
5438{
5439 IRTemp op2 = newTemp(Ity_I64);
5440
5441 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
5442 put_gpr_dw0(r1, mkexpr(op2));
5443 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5444
5445 return "ltgfr";
5446}
5447
5448static HChar *
5449s390_irgen_LT(UChar r1, IRTemp op2addr)
5450{
5451 IRTemp op2 = newTemp(Ity_I32);
5452
5453 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5454 put_gpr_w1(r1, mkexpr(op2));
5455 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5456
5457 return "lt";
5458}
5459
5460static HChar *
5461s390_irgen_LTG(UChar r1, IRTemp op2addr)
5462{
5463 IRTemp op2 = newTemp(Ity_I64);
5464
5465 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5466 put_gpr_dw0(r1, mkexpr(op2));
5467 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5468
5469 return "ltg";
5470}
5471
5472static HChar *
5473s390_irgen_LTGF(UChar r1, IRTemp op2addr)
5474{
5475 IRTemp op2 = newTemp(Ity_I64);
5476
5477 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
5478 put_gpr_dw0(r1, mkexpr(op2));
5479 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5480
5481 return "ltgf";
5482}
5483
5484static HChar *
5485s390_irgen_LBR(UChar r1, UChar r2)
5486{
5487 put_gpr_w1(r1, unop(Iop_8Sto32, get_gpr_b7(r2)));
5488
5489 return "lbr";
5490}
5491
5492static HChar *
5493s390_irgen_LGBR(UChar r1, UChar r2)
5494{
5495 put_gpr_dw0(r1, unop(Iop_8Sto64, get_gpr_b7(r2)));
5496
5497 return "lgbr";
5498}
5499
5500static HChar *
5501s390_irgen_LB(UChar r1, IRTemp op2addr)
5502{
5503 put_gpr_w1(r1, unop(Iop_8Sto32, load(Ity_I8, mkexpr(op2addr))));
5504
5505 return "lb";
5506}
5507
5508static HChar *
5509s390_irgen_LGB(UChar r1, IRTemp op2addr)
5510{
5511 put_gpr_dw0(r1, unop(Iop_8Sto64, load(Ity_I8, mkexpr(op2addr))));
5512
5513 return "lgb";
5514}
5515
5516static HChar *
5517s390_irgen_LBH(UChar r1, IRTemp op2addr)
5518{
5519 put_gpr_w0(r1, unop(Iop_8Sto32, load(Ity_I8, mkexpr(op2addr))));
5520
5521 return "lbh";
5522}
5523
5524static HChar *
5525s390_irgen_LCR(UChar r1, UChar r2)
5526{
5527 Int op1;
5528 IRTemp op2 = newTemp(Ity_I32);
5529 IRTemp result = newTemp(Ity_I32);
5530
5531 op1 = 0;
5532 assign(op2, get_gpr_w1(r2));
5533 assign(result, binop(Iop_Sub32, mkU32((UInt)op1), mkexpr(op2)));
5534 put_gpr_w1(r1, mkexpr(result));
5535 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, mktemp(Ity_I32, mkU32((UInt)
5536 op1)), op2);
5537
5538 return "lcr";
5539}
5540
5541static HChar *
5542s390_irgen_LCGR(UChar r1, UChar r2)
5543{
5544 Long op1;
5545 IRTemp op2 = newTemp(Ity_I64);
5546 IRTemp result = newTemp(Ity_I64);
5547
5548 op1 = 0ULL;
5549 assign(op2, get_gpr_dw0(r2));
5550 assign(result, binop(Iop_Sub64, mkU64((ULong)op1), mkexpr(op2)));
5551 put_gpr_dw0(r1, mkexpr(result));
5552 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, mktemp(Ity_I64, mkU64((ULong)
5553 op1)), op2);
5554
5555 return "lcgr";
5556}
5557
5558static HChar *
5559s390_irgen_LCGFR(UChar r1, UChar r2)
5560{
5561 Long op1;
5562 IRTemp op2 = newTemp(Ity_I64);
5563 IRTemp result = newTemp(Ity_I64);
5564
5565 op1 = 0ULL;
5566 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
5567 assign(result, binop(Iop_Sub64, mkU64((ULong)op1), mkexpr(op2)));
5568 put_gpr_dw0(r1, mkexpr(result));
5569 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, mktemp(Ity_I64, mkU64((ULong)
5570 op1)), op2);
5571
5572 return "lcgfr";
5573}
5574
5575static HChar *
5576s390_irgen_LHR(UChar r1, UChar r2)
5577{
5578 put_gpr_w1(r1, unop(Iop_16Sto32, get_gpr_hw3(r2)));
5579
5580 return "lhr";
5581}
5582
5583static HChar *
5584s390_irgen_LGHR(UChar r1, UChar r2)
5585{
5586 put_gpr_dw0(r1, unop(Iop_16Sto64, get_gpr_hw3(r2)));
5587
5588 return "lghr";
5589}
5590
5591static HChar *
5592s390_irgen_LH(UChar r1, IRTemp op2addr)
5593{
5594 put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
5595
5596 return "lh";
5597}
5598
5599static HChar *
5600s390_irgen_LHY(UChar r1, IRTemp op2addr)
5601{
5602 put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
5603
5604 return "lhy";
5605}
5606
5607static HChar *
5608s390_irgen_LGH(UChar r1, IRTemp op2addr)
5609{
5610 put_gpr_dw0(r1, unop(Iop_16Sto64, load(Ity_I16, mkexpr(op2addr))));
5611
5612 return "lgh";
5613}
5614
5615static HChar *
5616s390_irgen_LHI(UChar r1, UShort i2)
5617{
5618 put_gpr_w1(r1, mkU32((UInt)(Int)(Short)i2));
5619
5620 return "lhi";
5621}
5622
5623static HChar *
5624s390_irgen_LGHI(UChar r1, UShort i2)
5625{
5626 put_gpr_dw0(r1, mkU64((ULong)(Long)(Short)i2));
5627
5628 return "lghi";
5629}
5630
5631static HChar *
5632s390_irgen_LHRL(UChar r1, UInt i2)
5633{
5634 put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
5635 ((ULong)(Long)(Int)i2 << 1)))));
5636
5637 return "lhrl";
5638}
5639
5640static HChar *
5641s390_irgen_LGHRL(UChar r1, UInt i2)
5642{
5643 put_gpr_dw0(r1, unop(Iop_16Sto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
5644 ((ULong)(Long)(Int)i2 << 1)))));
5645
5646 return "lghrl";
5647}
5648
5649static HChar *
5650s390_irgen_LHH(UChar r1, IRTemp op2addr)
5651{
5652 put_gpr_w0(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
5653
5654 return "lhh";
5655}
5656
5657static HChar *
5658s390_irgen_LFH(UChar r1, IRTemp op2addr)
5659{
5660 put_gpr_w0(r1, load(Ity_I32, mkexpr(op2addr)));
5661
5662 return "lfh";
5663}
5664
5665static HChar *
5666s390_irgen_LLGFR(UChar r1, UChar r2)
5667{
5668 put_gpr_dw0(r1, unop(Iop_32Uto64, get_gpr_w1(r2)));
5669
5670 return "llgfr";
5671}
5672
5673static HChar *
5674s390_irgen_LLGF(UChar r1, IRTemp op2addr)
5675{
5676 put_gpr_dw0(r1, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
5677
5678 return "llgf";
5679}
5680
5681static HChar *
5682s390_irgen_LLGFRL(UChar r1, UInt i2)
5683{
5684 put_gpr_dw0(r1, unop(Iop_32Uto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
5685 ((ULong)(Long)(Int)i2 << 1)))));
5686
5687 return "llgfrl";
5688}
5689
5690static HChar *
5691s390_irgen_LLCR(UChar r1, UChar r2)
5692{
5693 put_gpr_w1(r1, unop(Iop_8Uto32, get_gpr_b7(r2)));
5694
5695 return "llcr";
5696}
5697
5698static HChar *
5699s390_irgen_LLGCR(UChar r1, UChar r2)
5700{
5701 put_gpr_dw0(r1, unop(Iop_8Uto64, get_gpr_b7(r2)));
5702
5703 return "llgcr";
5704}
5705
5706static HChar *
5707s390_irgen_LLC(UChar r1, IRTemp op2addr)
5708{
5709 put_gpr_w1(r1, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
5710
5711 return "llc";
5712}
5713
5714static HChar *
5715s390_irgen_LLGC(UChar r1, IRTemp op2addr)
5716{
5717 put_gpr_dw0(r1, unop(Iop_8Uto64, load(Ity_I8, mkexpr(op2addr))));
5718
5719 return "llgc";
5720}
5721
5722static HChar *
5723s390_irgen_LLCH(UChar r1, IRTemp op2addr)
5724{
5725 put_gpr_w0(r1, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
5726
5727 return "llch";
5728}
5729
5730static HChar *
5731s390_irgen_LLHR(UChar r1, UChar r2)
5732{
5733 put_gpr_w1(r1, unop(Iop_16Uto32, get_gpr_hw3(r2)));
5734
5735 return "llhr";
5736}
5737
5738static HChar *
5739s390_irgen_LLGHR(UChar r1, UChar r2)
5740{
5741 put_gpr_dw0(r1, unop(Iop_16Uto64, get_gpr_hw3(r2)));
5742
5743 return "llghr";
5744}
5745
5746static HChar *
5747s390_irgen_LLH(UChar r1, IRTemp op2addr)
5748{
5749 put_gpr_w1(r1, unop(Iop_16Uto32, load(Ity_I16, mkexpr(op2addr))));
5750
5751 return "llh";
5752}
5753
5754static HChar *
5755s390_irgen_LLGH(UChar r1, IRTemp op2addr)
5756{
5757 put_gpr_dw0(r1, unop(Iop_16Uto64, load(Ity_I16, mkexpr(op2addr))));
5758
5759 return "llgh";
5760}
5761
5762static HChar *
5763s390_irgen_LLHRL(UChar r1, UInt i2)
5764{
5765 put_gpr_w1(r1, unop(Iop_16Uto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
5766 ((ULong)(Long)(Int)i2 << 1)))));
5767
5768 return "llhrl";
5769}
5770
5771static HChar *
5772s390_irgen_LLGHRL(UChar r1, UInt i2)
5773{
5774 put_gpr_dw0(r1, unop(Iop_16Uto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
5775 ((ULong)(Long)(Int)i2 << 1)))));
5776
5777 return "llghrl";
5778}
5779
5780static HChar *
5781s390_irgen_LLHH(UChar r1, IRTemp op2addr)
5782{
5783 put_gpr_w0(r1, unop(Iop_16Uto32, load(Ity_I16, mkexpr(op2addr))));
5784
5785 return "llhh";
5786}
5787
5788static HChar *
5789s390_irgen_LLIHF(UChar r1, UInt i2)
5790{
5791 put_gpr_dw0(r1, mkU64(((ULong)i2) << 32));
5792
5793 return "llihf";
5794}
5795
5796static HChar *
5797s390_irgen_LLIHH(UChar r1, UShort i2)
5798{
5799 put_gpr_dw0(r1, mkU64(((ULong)i2) << 48));
5800
5801 return "llihh";
5802}
5803
5804static HChar *
5805s390_irgen_LLIHL(UChar r1, UShort i2)
5806{
5807 put_gpr_dw0(r1, mkU64(((ULong)i2) << 32));
5808
5809 return "llihl";
5810}
5811
5812static HChar *
5813s390_irgen_LLILF(UChar r1, UInt i2)
5814{
5815 put_gpr_dw0(r1, mkU64(i2));
5816
5817 return "llilf";
5818}
5819
5820static HChar *
5821s390_irgen_LLILH(UChar r1, UShort i2)
5822{
5823 put_gpr_dw0(r1, mkU64(((ULong)i2) << 16));
5824
5825 return "llilh";
5826}
5827
5828static HChar *
5829s390_irgen_LLILL(UChar r1, UShort i2)
5830{
5831 put_gpr_dw0(r1, mkU64(i2));
5832
5833 return "llill";
5834}
5835
5836static HChar *
5837s390_irgen_LLGTR(UChar r1, UChar r2)
5838{
5839 put_gpr_dw0(r1, unop(Iop_32Uto64, binop(Iop_And32, get_gpr_w1(r2),
5840 mkU32(2147483647))));
5841
5842 return "llgtr";
5843}
5844
5845static HChar *
5846s390_irgen_LLGT(UChar r1, IRTemp op2addr)
5847{
5848 put_gpr_dw0(r1, unop(Iop_32Uto64, binop(Iop_And32, load(Ity_I32,
5849 mkexpr(op2addr)), mkU32(2147483647))));
5850
5851 return "llgt";
5852}
5853
5854static HChar *
5855s390_irgen_LNR(UChar r1, UChar r2)
5856{
5857 IRTemp op2 = newTemp(Ity_I32);
5858 IRTemp result = newTemp(Ity_I32);
5859
5860 assign(op2, get_gpr_w1(r2));
5861 assign(result, mkite(binop(Iop_CmpLE32S, mkexpr(op2), mkU32(0)), mkexpr(op2),
5862 binop(Iop_Sub32, mkU32(0), mkexpr(op2))));
5863 put_gpr_w1(r1, mkexpr(result));
5864 s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
5865
5866 return "lnr";
5867}
5868
5869static HChar *
5870s390_irgen_LNGR(UChar r1, UChar r2)
5871{
5872 IRTemp op2 = newTemp(Ity_I64);
5873 IRTemp result = newTemp(Ity_I64);
5874
5875 assign(op2, get_gpr_dw0(r2));
5876 assign(result, mkite(binop(Iop_CmpLE64S, mkexpr(op2), mkU64(0)), mkexpr(op2),
5877 binop(Iop_Sub64, mkU64(0), mkexpr(op2))));
5878 put_gpr_dw0(r1, mkexpr(result));
5879 s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
5880
5881 return "lngr";
5882}
5883
5884static HChar *
5885s390_irgen_LNGFR(UChar r1, UChar r2 __attribute__((unused)))
5886{
5887 IRTemp op2 = newTemp(Ity_I64);
5888 IRTemp result = newTemp(Ity_I64);
5889
5890 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r1)));
5891 assign(result, mkite(binop(Iop_CmpLE64S, mkexpr(op2), mkU64(0)), mkexpr(op2),
5892 binop(Iop_Sub64, mkU64(0), mkexpr(op2))));
5893 put_gpr_dw0(r1, mkexpr(result));
5894 s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
5895
5896 return "lngfr";
5897}
5898
5899static HChar *
sewardjd7bde722011-04-05 13:19:33 +00005900s390_irgen_LOCR(UChar m3, UChar r1, UChar r2)
5901{
florian6820ba52012-07-26 02:01:50 +00005902 next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
sewardjd7bde722011-04-05 13:19:33 +00005903 put_gpr_w1(r1, get_gpr_w1(r2));
5904
5905 return "locr";
5906}
5907
5908static HChar *
5909s390_irgen_LOCGR(UChar m3, UChar r1, UChar r2)
5910{
florian6820ba52012-07-26 02:01:50 +00005911 next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
sewardjd7bde722011-04-05 13:19:33 +00005912 put_gpr_dw0(r1, get_gpr_dw0(r2));
5913
5914 return "locgr";
5915}
5916
5917static HChar *
5918s390_irgen_LOC(UChar r1, IRTemp op2addr)
5919{
5920 /* condition is checked in format handler */
5921 put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
5922
5923 return "loc";
5924}
5925
5926static HChar *
5927s390_irgen_LOCG(UChar r1, IRTemp op2addr)
5928{
5929 /* condition is checked in format handler */
5930 put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
5931
5932 return "locg";
5933}
5934
5935static HChar *
sewardj2019a972011-03-07 16:04:07 +00005936s390_irgen_LPQ(UChar r1, IRTemp op2addr)
5937{
5938 put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
5939 put_gpr_dw0(r1 + 1, load(Ity_I64, binop(Iop_Add64, mkexpr(op2addr), mkU64(8))
5940 ));
5941
5942 return "lpq";
5943}
5944
5945static HChar *
5946s390_irgen_LPR(UChar r1, UChar r2)
5947{
5948 IRTemp op2 = newTemp(Ity_I32);
5949 IRTemp result = newTemp(Ity_I32);
5950
5951 assign(op2, get_gpr_w1(r2));
5952 assign(result, mkite(binop(Iop_CmpLT32S, mkexpr(op2), mkU32(0)),
5953 binop(Iop_Sub32, mkU32(0), mkexpr(op2)), mkexpr(op2)));
5954 put_gpr_w1(r1, mkexpr(result));
5955 s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_32, op2);
5956
5957 return "lpr";
5958}
5959
5960static HChar *
5961s390_irgen_LPGR(UChar r1, UChar r2)
5962{
5963 IRTemp op2 = newTemp(Ity_I64);
5964 IRTemp result = newTemp(Ity_I64);
5965
5966 assign(op2, get_gpr_dw0(r2));
5967 assign(result, mkite(binop(Iop_CmpLT64S, mkexpr(op2), mkU64(0)),
5968 binop(Iop_Sub64, mkU64(0), mkexpr(op2)), mkexpr(op2)));
5969 put_gpr_dw0(r1, mkexpr(result));
5970 s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_64, op2);
5971
5972 return "lpgr";
5973}
5974
5975static HChar *
5976s390_irgen_LPGFR(UChar r1, UChar r2)
5977{
5978 IRTemp op2 = newTemp(Ity_I64);
5979 IRTemp result = newTemp(Ity_I64);
5980
5981 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
5982 assign(result, mkite(binop(Iop_CmpLT64S, mkexpr(op2), mkU64(0)),
5983 binop(Iop_Sub64, mkU64(0), mkexpr(op2)), mkexpr(op2)));
5984 put_gpr_dw0(r1, mkexpr(result));
5985 s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_64, op2);
5986
5987 return "lpgfr";
5988}
5989
5990static HChar *
5991s390_irgen_LRVR(UChar r1, UChar r2)
5992{
5993 IRTemp b0 = newTemp(Ity_I8);
5994 IRTemp b1 = newTemp(Ity_I8);
5995 IRTemp b2 = newTemp(Ity_I8);
5996 IRTemp b3 = newTemp(Ity_I8);
5997
5998 assign(b3, get_gpr_b7(r2));
5999 assign(b2, get_gpr_b6(r2));
6000 assign(b1, get_gpr_b5(r2));
6001 assign(b0, get_gpr_b4(r2));
6002 put_gpr_b4(r1, mkexpr(b3));
6003 put_gpr_b5(r1, mkexpr(b2));
6004 put_gpr_b6(r1, mkexpr(b1));
6005 put_gpr_b7(r1, mkexpr(b0));
6006
6007 return "lrvr";
6008}
6009
6010static HChar *
6011s390_irgen_LRVGR(UChar r1, UChar r2)
6012{
6013 IRTemp b0 = newTemp(Ity_I8);
6014 IRTemp b1 = newTemp(Ity_I8);
6015 IRTemp b2 = newTemp(Ity_I8);
6016 IRTemp b3 = newTemp(Ity_I8);
6017 IRTemp b4 = newTemp(Ity_I8);
6018 IRTemp b5 = newTemp(Ity_I8);
6019 IRTemp b6 = newTemp(Ity_I8);
6020 IRTemp b7 = newTemp(Ity_I8);
6021
6022 assign(b7, get_gpr_b7(r2));
6023 assign(b6, get_gpr_b6(r2));
6024 assign(b5, get_gpr_b5(r2));
6025 assign(b4, get_gpr_b4(r2));
6026 assign(b3, get_gpr_b3(r2));
6027 assign(b2, get_gpr_b2(r2));
6028 assign(b1, get_gpr_b1(r2));
6029 assign(b0, get_gpr_b0(r2));
6030 put_gpr_b0(r1, mkexpr(b7));
6031 put_gpr_b1(r1, mkexpr(b6));
6032 put_gpr_b2(r1, mkexpr(b5));
6033 put_gpr_b3(r1, mkexpr(b4));
6034 put_gpr_b4(r1, mkexpr(b3));
6035 put_gpr_b5(r1, mkexpr(b2));
6036 put_gpr_b6(r1, mkexpr(b1));
6037 put_gpr_b7(r1, mkexpr(b0));
6038
6039 return "lrvgr";
6040}
6041
6042static HChar *
6043s390_irgen_LRVH(UChar r1, IRTemp op2addr)
6044{
6045 IRTemp op2 = newTemp(Ity_I16);
6046
6047 assign(op2, load(Ity_I16, mkexpr(op2addr)));
6048 put_gpr_b6(r1, unop(Iop_16to8, mkexpr(op2)));
6049 put_gpr_b7(r1, unop(Iop_16HIto8, mkexpr(op2)));
6050
6051 return "lrvh";
6052}
6053
6054static HChar *
6055s390_irgen_LRV(UChar r1, IRTemp op2addr)
6056{
6057 IRTemp op2 = newTemp(Ity_I32);
6058
6059 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6060 put_gpr_b4(r1, unop(Iop_32to8, binop(Iop_And32, mkexpr(op2), mkU32(255))));
6061 put_gpr_b5(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
6062 mkU8(8)), mkU32(255))));
6063 put_gpr_b6(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
6064 mkU8(16)), mkU32(255))));
6065 put_gpr_b7(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
6066 mkU8(24)), mkU32(255))));
6067
6068 return "lrv";
6069}
6070
6071static HChar *
6072s390_irgen_LRVG(UChar r1, IRTemp op2addr)
6073{
6074 IRTemp op2 = newTemp(Ity_I64);
6075
6076 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6077 put_gpr_b0(r1, unop(Iop_64to8, binop(Iop_And64, mkexpr(op2), mkU64(255))));
6078 put_gpr_b1(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6079 mkU8(8)), mkU64(255))));
6080 put_gpr_b2(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6081 mkU8(16)), mkU64(255))));
6082 put_gpr_b3(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6083 mkU8(24)), mkU64(255))));
6084 put_gpr_b4(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6085 mkU8(32)), mkU64(255))));
6086 put_gpr_b5(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6087 mkU8(40)), mkU64(255))));
6088 put_gpr_b6(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6089 mkU8(48)), mkU64(255))));
6090 put_gpr_b7(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6091 mkU8(56)), mkU64(255))));
6092
6093 return "lrvg";
6094}
6095
6096static HChar *
6097s390_irgen_MVHHI(UShort i2, IRTemp op1addr)
6098{
6099 store(mkexpr(op1addr), mkU16(i2));
6100
6101 return "mvhhi";
6102}
6103
6104static HChar *
6105s390_irgen_MVHI(UShort i2, IRTemp op1addr)
6106{
6107 store(mkexpr(op1addr), mkU32((UInt)(Int)(Short)i2));
6108
6109 return "mvhi";
6110}
6111
6112static HChar *
6113s390_irgen_MVGHI(UShort i2, IRTemp op1addr)
6114{
6115 store(mkexpr(op1addr), mkU64((ULong)(Long)(Short)i2));
6116
6117 return "mvghi";
6118}
6119
6120static HChar *
6121s390_irgen_MVI(UChar i2, IRTemp op1addr)
6122{
6123 store(mkexpr(op1addr), mkU8(i2));
6124
6125 return "mvi";
6126}
6127
6128static HChar *
6129s390_irgen_MVIY(UChar i2, IRTemp op1addr)
6130{
6131 store(mkexpr(op1addr), mkU8(i2));
6132
6133 return "mviy";
6134}
6135
6136static HChar *
6137s390_irgen_MR(UChar r1, UChar r2)
6138{
6139 IRTemp op1 = newTemp(Ity_I32);
6140 IRTemp op2 = newTemp(Ity_I32);
6141 IRTemp result = newTemp(Ity_I64);
6142
6143 assign(op1, get_gpr_w1(r1 + 1));
6144 assign(op2, get_gpr_w1(r2));
6145 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6146 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6147 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6148
6149 return "mr";
6150}
6151
6152static HChar *
6153s390_irgen_M(UChar r1, IRTemp op2addr)
6154{
6155 IRTemp op1 = newTemp(Ity_I32);
6156 IRTemp op2 = newTemp(Ity_I32);
6157 IRTemp result = newTemp(Ity_I64);
6158
6159 assign(op1, get_gpr_w1(r1 + 1));
6160 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6161 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6162 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6163 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6164
6165 return "m";
6166}
6167
6168static HChar *
6169s390_irgen_MFY(UChar r1, IRTemp op2addr)
6170{
6171 IRTemp op1 = newTemp(Ity_I32);
6172 IRTemp op2 = newTemp(Ity_I32);
6173 IRTemp result = newTemp(Ity_I64);
6174
6175 assign(op1, get_gpr_w1(r1 + 1));
6176 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6177 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6178 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6179 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6180
6181 return "mfy";
6182}
6183
6184static HChar *
6185s390_irgen_MH(UChar r1, IRTemp op2addr)
6186{
6187 IRTemp op1 = newTemp(Ity_I32);
6188 IRTemp op2 = newTemp(Ity_I16);
6189 IRTemp result = newTemp(Ity_I64);
6190
6191 assign(op1, get_gpr_w1(r1));
6192 assign(op2, load(Ity_I16, mkexpr(op2addr)));
6193 assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32, mkexpr(op2))
6194 ));
6195 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6196
6197 return "mh";
6198}
6199
6200static HChar *
6201s390_irgen_MHY(UChar r1, IRTemp op2addr)
6202{
6203 IRTemp op1 = newTemp(Ity_I32);
6204 IRTemp op2 = newTemp(Ity_I16);
6205 IRTemp result = newTemp(Ity_I64);
6206
6207 assign(op1, get_gpr_w1(r1));
6208 assign(op2, load(Ity_I16, mkexpr(op2addr)));
6209 assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32, mkexpr(op2))
6210 ));
6211 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6212
6213 return "mhy";
6214}
6215
6216static HChar *
6217s390_irgen_MHI(UChar r1, UShort i2)
6218{
6219 IRTemp op1 = newTemp(Ity_I32);
6220 Short op2;
6221 IRTemp result = newTemp(Ity_I64);
6222
6223 assign(op1, get_gpr_w1(r1));
6224 op2 = (Short)i2;
6225 assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32,
6226 mkU16((UShort)op2))));
6227 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6228
6229 return "mhi";
6230}
6231
6232static HChar *
6233s390_irgen_MGHI(UChar r1, UShort i2)
6234{
6235 IRTemp op1 = newTemp(Ity_I64);
6236 Short op2;
6237 IRTemp result = newTemp(Ity_I128);
6238
6239 assign(op1, get_gpr_dw0(r1));
6240 op2 = (Short)i2;
6241 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_16Sto64,
6242 mkU16((UShort)op2))));
6243 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6244
6245 return "mghi";
6246}
6247
6248static HChar *
6249s390_irgen_MLR(UChar r1, UChar r2)
6250{
6251 IRTemp op1 = newTemp(Ity_I32);
6252 IRTemp op2 = newTemp(Ity_I32);
6253 IRTemp result = newTemp(Ity_I64);
6254
6255 assign(op1, get_gpr_w1(r1 + 1));
6256 assign(op2, get_gpr_w1(r2));
6257 assign(result, binop(Iop_MullU32, mkexpr(op1), mkexpr(op2)));
6258 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6259 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6260
6261 return "mlr";
6262}
6263
6264static HChar *
6265s390_irgen_MLGR(UChar r1, UChar r2)
6266{
6267 IRTemp op1 = newTemp(Ity_I64);
6268 IRTemp op2 = newTemp(Ity_I64);
6269 IRTemp result = newTemp(Ity_I128);
6270
6271 assign(op1, get_gpr_dw0(r1 + 1));
6272 assign(op2, get_gpr_dw0(r2));
6273 assign(result, binop(Iop_MullU64, mkexpr(op1), mkexpr(op2)));
6274 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result)));
6275 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result)));
6276
6277 return "mlgr";
6278}
6279
6280static HChar *
6281s390_irgen_ML(UChar r1, IRTemp op2addr)
6282{
6283 IRTemp op1 = newTemp(Ity_I32);
6284 IRTemp op2 = newTemp(Ity_I32);
6285 IRTemp result = newTemp(Ity_I64);
6286
6287 assign(op1, get_gpr_w1(r1 + 1));
6288 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6289 assign(result, binop(Iop_MullU32, mkexpr(op1), mkexpr(op2)));
6290 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6291 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6292
6293 return "ml";
6294}
6295
6296static HChar *
6297s390_irgen_MLG(UChar r1, IRTemp op2addr)
6298{
6299 IRTemp op1 = newTemp(Ity_I64);
6300 IRTemp op2 = newTemp(Ity_I64);
6301 IRTemp result = newTemp(Ity_I128);
6302
6303 assign(op1, get_gpr_dw0(r1 + 1));
6304 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6305 assign(result, binop(Iop_MullU64, mkexpr(op1), mkexpr(op2)));
6306 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result)));
6307 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result)));
6308
6309 return "mlg";
6310}
6311
6312static HChar *
6313s390_irgen_MSR(UChar r1, UChar r2)
6314{
6315 IRTemp op1 = newTemp(Ity_I32);
6316 IRTemp op2 = newTemp(Ity_I32);
6317 IRTemp result = newTemp(Ity_I64);
6318
6319 assign(op1, get_gpr_w1(r1));
6320 assign(op2, get_gpr_w1(r2));
6321 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6322 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6323
6324 return "msr";
6325}
6326
6327static HChar *
6328s390_irgen_MSGR(UChar r1, UChar r2)
6329{
6330 IRTemp op1 = newTemp(Ity_I64);
6331 IRTemp op2 = newTemp(Ity_I64);
6332 IRTemp result = newTemp(Ity_I128);
6333
6334 assign(op1, get_gpr_dw0(r1));
6335 assign(op2, get_gpr_dw0(r2));
6336 assign(result, binop(Iop_MullS64, mkexpr(op1), mkexpr(op2)));
6337 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6338
6339 return "msgr";
6340}
6341
6342static HChar *
6343s390_irgen_MSGFR(UChar r1, UChar r2)
6344{
6345 IRTemp op1 = newTemp(Ity_I64);
6346 IRTemp op2 = newTemp(Ity_I32);
6347 IRTemp result = newTemp(Ity_I128);
6348
6349 assign(op1, get_gpr_dw0(r1));
6350 assign(op2, get_gpr_w1(r2));
6351 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkexpr(op2))
6352 ));
6353 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6354
6355 return "msgfr";
6356}
6357
6358static HChar *
6359s390_irgen_MS(UChar r1, IRTemp op2addr)
6360{
6361 IRTemp op1 = newTemp(Ity_I32);
6362 IRTemp op2 = newTemp(Ity_I32);
6363 IRTemp result = newTemp(Ity_I64);
6364
6365 assign(op1, get_gpr_w1(r1));
6366 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6367 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6368 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6369
6370 return "ms";
6371}
6372
6373static HChar *
6374s390_irgen_MSY(UChar r1, IRTemp op2addr)
6375{
6376 IRTemp op1 = newTemp(Ity_I32);
6377 IRTemp op2 = newTemp(Ity_I32);
6378 IRTemp result = newTemp(Ity_I64);
6379
6380 assign(op1, get_gpr_w1(r1));
6381 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6382 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6383 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6384
6385 return "msy";
6386}
6387
6388static HChar *
6389s390_irgen_MSG(UChar r1, IRTemp op2addr)
6390{
6391 IRTemp op1 = newTemp(Ity_I64);
6392 IRTemp op2 = newTemp(Ity_I64);
6393 IRTemp result = newTemp(Ity_I128);
6394
6395 assign(op1, get_gpr_dw0(r1));
6396 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6397 assign(result, binop(Iop_MullS64, mkexpr(op1), mkexpr(op2)));
6398 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6399
6400 return "msg";
6401}
6402
6403static HChar *
6404s390_irgen_MSGF(UChar r1, IRTemp op2addr)
6405{
6406 IRTemp op1 = newTemp(Ity_I64);
6407 IRTemp op2 = newTemp(Ity_I32);
6408 IRTemp result = newTemp(Ity_I128);
6409
6410 assign(op1, get_gpr_dw0(r1));
6411 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6412 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkexpr(op2))
6413 ));
6414 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6415
6416 return "msgf";
6417}
6418
6419static HChar *
6420s390_irgen_MSFI(UChar r1, UInt i2)
6421{
6422 IRTemp op1 = newTemp(Ity_I32);
6423 Int op2;
6424 IRTemp result = newTemp(Ity_I64);
6425
6426 assign(op1, get_gpr_w1(r1));
6427 op2 = (Int)i2;
6428 assign(result, binop(Iop_MullS32, mkexpr(op1), mkU32((UInt)op2)));
6429 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6430
6431 return "msfi";
6432}
6433
6434static HChar *
6435s390_irgen_MSGFI(UChar r1, UInt i2)
6436{
6437 IRTemp op1 = newTemp(Ity_I64);
6438 Int op2;
6439 IRTemp result = newTemp(Ity_I128);
6440
6441 assign(op1, get_gpr_dw0(r1));
6442 op2 = (Int)i2;
6443 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkU32((UInt)
6444 op2))));
6445 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6446
6447 return "msgfi";
6448}
6449
6450static HChar *
6451s390_irgen_OR(UChar r1, UChar r2)
6452{
6453 IRTemp op1 = newTemp(Ity_I32);
6454 IRTemp op2 = newTemp(Ity_I32);
6455 IRTemp result = newTemp(Ity_I32);
6456
6457 assign(op1, get_gpr_w1(r1));
6458 assign(op2, get_gpr_w1(r2));
6459 assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
6460 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6461 put_gpr_w1(r1, mkexpr(result));
6462
6463 return "or";
6464}
6465
6466static HChar *
6467s390_irgen_OGR(UChar r1, UChar r2)
6468{
6469 IRTemp op1 = newTemp(Ity_I64);
6470 IRTemp op2 = newTemp(Ity_I64);
6471 IRTemp result = newTemp(Ity_I64);
6472
6473 assign(op1, get_gpr_dw0(r1));
6474 assign(op2, get_gpr_dw0(r2));
6475 assign(result, binop(Iop_Or64, mkexpr(op1), mkexpr(op2)));
6476 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6477 put_gpr_dw0(r1, mkexpr(result));
6478
6479 return "ogr";
6480}
6481
6482static HChar *
6483s390_irgen_ORK(UChar r3, UChar r1, UChar r2)
6484{
6485 IRTemp op2 = newTemp(Ity_I32);
6486 IRTemp op3 = newTemp(Ity_I32);
6487 IRTemp result = newTemp(Ity_I32);
6488
6489 assign(op2, get_gpr_w1(r2));
6490 assign(op3, get_gpr_w1(r3));
6491 assign(result, binop(Iop_Or32, mkexpr(op2), mkexpr(op3)));
6492 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6493 put_gpr_w1(r1, mkexpr(result));
6494
6495 return "ork";
6496}
6497
6498static HChar *
6499s390_irgen_OGRK(UChar r3, UChar r1, UChar r2)
6500{
6501 IRTemp op2 = newTemp(Ity_I64);
6502 IRTemp op3 = newTemp(Ity_I64);
6503 IRTemp result = newTemp(Ity_I64);
6504
6505 assign(op2, get_gpr_dw0(r2));
6506 assign(op3, get_gpr_dw0(r3));
6507 assign(result, binop(Iop_Or64, mkexpr(op2), mkexpr(op3)));
6508 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6509 put_gpr_dw0(r1, mkexpr(result));
6510
6511 return "ogrk";
6512}
6513
6514static HChar *
6515s390_irgen_O(UChar r1, IRTemp op2addr)
6516{
6517 IRTemp op1 = newTemp(Ity_I32);
6518 IRTemp op2 = newTemp(Ity_I32);
6519 IRTemp result = newTemp(Ity_I32);
6520
6521 assign(op1, get_gpr_w1(r1));
6522 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6523 assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
6524 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6525 put_gpr_w1(r1, mkexpr(result));
6526
6527 return "o";
6528}
6529
6530static HChar *
6531s390_irgen_OY(UChar r1, IRTemp op2addr)
6532{
6533 IRTemp op1 = newTemp(Ity_I32);
6534 IRTemp op2 = newTemp(Ity_I32);
6535 IRTemp result = newTemp(Ity_I32);
6536
6537 assign(op1, get_gpr_w1(r1));
6538 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6539 assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
6540 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6541 put_gpr_w1(r1, mkexpr(result));
6542
6543 return "oy";
6544}
6545
6546static HChar *
6547s390_irgen_OG(UChar r1, IRTemp op2addr)
6548{
6549 IRTemp op1 = newTemp(Ity_I64);
6550 IRTemp op2 = newTemp(Ity_I64);
6551 IRTemp result = newTemp(Ity_I64);
6552
6553 assign(op1, get_gpr_dw0(r1));
6554 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6555 assign(result, binop(Iop_Or64, mkexpr(op1), mkexpr(op2)));
6556 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6557 put_gpr_dw0(r1, mkexpr(result));
6558
6559 return "og";
6560}
6561
6562static HChar *
6563s390_irgen_OI(UChar i2, IRTemp op1addr)
6564{
6565 IRTemp op1 = newTemp(Ity_I8);
6566 UChar op2;
6567 IRTemp result = newTemp(Ity_I8);
6568
6569 assign(op1, load(Ity_I8, mkexpr(op1addr)));
6570 op2 = i2;
6571 assign(result, binop(Iop_Or8, mkexpr(op1), mkU8(op2)));
6572 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6573 store(mkexpr(op1addr), mkexpr(result));
6574
6575 return "oi";
6576}
6577
6578static HChar *
6579s390_irgen_OIY(UChar i2, IRTemp op1addr)
6580{
6581 IRTemp op1 = newTemp(Ity_I8);
6582 UChar op2;
6583 IRTemp result = newTemp(Ity_I8);
6584
6585 assign(op1, load(Ity_I8, mkexpr(op1addr)));
6586 op2 = i2;
6587 assign(result, binop(Iop_Or8, mkexpr(op1), mkU8(op2)));
6588 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6589 store(mkexpr(op1addr), mkexpr(result));
6590
6591 return "oiy";
6592}
6593
6594static HChar *
6595s390_irgen_OIHF(UChar r1, UInt i2)
6596{
6597 IRTemp op1 = newTemp(Ity_I32);
6598 UInt op2;
6599 IRTemp result = newTemp(Ity_I32);
6600
6601 assign(op1, get_gpr_w0(r1));
6602 op2 = i2;
6603 assign(result, binop(Iop_Or32, mkexpr(op1), mkU32(op2)));
6604 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6605 put_gpr_w0(r1, mkexpr(result));
6606
6607 return "oihf";
6608}
6609
6610static HChar *
6611s390_irgen_OIHH(UChar r1, UShort i2)
6612{
6613 IRTemp op1 = newTemp(Ity_I16);
6614 UShort op2;
6615 IRTemp result = newTemp(Ity_I16);
6616
6617 assign(op1, get_gpr_hw0(r1));
6618 op2 = i2;
6619 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
6620 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6621 put_gpr_hw0(r1, mkexpr(result));
6622
6623 return "oihh";
6624}
6625
6626static HChar *
6627s390_irgen_OIHL(UChar r1, UShort i2)
6628{
6629 IRTemp op1 = newTemp(Ity_I16);
6630 UShort op2;
6631 IRTemp result = newTemp(Ity_I16);
6632
6633 assign(op1, get_gpr_hw1(r1));
6634 op2 = i2;
6635 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
6636 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6637 put_gpr_hw1(r1, mkexpr(result));
6638
6639 return "oihl";
6640}
6641
6642static HChar *
6643s390_irgen_OILF(UChar r1, UInt i2)
6644{
6645 IRTemp op1 = newTemp(Ity_I32);
6646 UInt op2;
6647 IRTemp result = newTemp(Ity_I32);
6648
6649 assign(op1, get_gpr_w1(r1));
6650 op2 = i2;
6651 assign(result, binop(Iop_Or32, mkexpr(op1), mkU32(op2)));
6652 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6653 put_gpr_w1(r1, mkexpr(result));
6654
6655 return "oilf";
6656}
6657
6658static HChar *
6659s390_irgen_OILH(UChar r1, UShort i2)
6660{
6661 IRTemp op1 = newTemp(Ity_I16);
6662 UShort op2;
6663 IRTemp result = newTemp(Ity_I16);
6664
6665 assign(op1, get_gpr_hw2(r1));
6666 op2 = i2;
6667 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
6668 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6669 put_gpr_hw2(r1, mkexpr(result));
6670
6671 return "oilh";
6672}
6673
6674static HChar *
6675s390_irgen_OILL(UChar r1, UShort i2)
6676{
6677 IRTemp op1 = newTemp(Ity_I16);
6678 UShort op2;
6679 IRTemp result = newTemp(Ity_I16);
6680
6681 assign(op1, get_gpr_hw3(r1));
6682 op2 = i2;
6683 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
6684 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6685 put_gpr_hw3(r1, mkexpr(result));
6686
6687 return "oill";
6688}
6689
6690static HChar *
6691s390_irgen_PFD(void)
6692{
6693
6694 return "pfd";
6695}
6696
6697static HChar *
6698s390_irgen_PFDRL(void)
6699{
6700
6701 return "pfdrl";
6702}
6703
6704static HChar *
6705s390_irgen_RLL(UChar r1, UChar r3, IRTemp op2addr)
6706{
6707 IRTemp amount = newTemp(Ity_I64);
6708 IRTemp op = newTemp(Ity_I32);
6709
6710 assign(amount, binop(Iop_And64, mkexpr(op2addr), mkU64(31)));
6711 assign(op, get_gpr_w1(r3));
6712 put_gpr_w1(r1, binop(Iop_Or32, binop(Iop_Shl32, mkexpr(op), unop(Iop_64to8,
6713 mkexpr(amount))), binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8,
6714 binop(Iop_Sub64, mkU64(32), mkexpr(amount))))));
6715
6716 return "rll";
6717}
6718
6719static HChar *
6720s390_irgen_RLLG(UChar r1, UChar r3, IRTemp op2addr)
6721{
6722 IRTemp amount = newTemp(Ity_I64);
6723 IRTemp op = newTemp(Ity_I64);
6724
6725 assign(amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
6726 assign(op, get_gpr_dw0(r3));
6727 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(op), unop(Iop_64to8,
6728 mkexpr(amount))), binop(Iop_Shr64, mkexpr(op), unop(Iop_64to8,
6729 binop(Iop_Sub64, mkU64(64), mkexpr(amount))))));
6730
6731 return "rllg";
6732}
6733
6734static HChar *
6735s390_irgen_RNSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
6736{
6737 UChar from;
6738 UChar to;
6739 UChar rot;
6740 UChar t_bit;
6741 ULong mask;
6742 ULong maskc;
6743 IRTemp result = newTemp(Ity_I64);
6744 IRTemp op2 = newTemp(Ity_I64);
6745
6746 from = i3 & 63;
6747 to = i4 & 63;
6748 rot = i5 & 63;
6749 t_bit = i3 & 128;
6750 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
6751 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
6752 mkU8(64 - rot))));
6753 if (from <= to) {
6754 mask = ~0ULL;
6755 mask = (mask >> from) & (mask << (63 - to));
6756 maskc = ~mask;
6757 } else {
6758 maskc = ~0ULL;
6759 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
6760 mask = ~maskc;
6761 }
6762 assign(result, binop(Iop_And64, binop(Iop_And64, get_gpr_dw0(r1), mkexpr(op2)
6763 ), mkU64(mask)));
6764 if (t_bit == 0) {
6765 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
6766 mkU64(maskc)), mkexpr(result)));
6767 }
6768 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6769
6770 return "rnsbg";
6771}
6772
6773static HChar *
6774s390_irgen_RXSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
6775{
6776 UChar from;
6777 UChar to;
6778 UChar rot;
6779 UChar t_bit;
6780 ULong mask;
6781 ULong maskc;
6782 IRTemp result = newTemp(Ity_I64);
6783 IRTemp op2 = newTemp(Ity_I64);
6784
6785 from = i3 & 63;
6786 to = i4 & 63;
6787 rot = i5 & 63;
6788 t_bit = i3 & 128;
6789 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
6790 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
6791 mkU8(64 - rot))));
6792 if (from <= to) {
6793 mask = ~0ULL;
6794 mask = (mask >> from) & (mask << (63 - to));
6795 maskc = ~mask;
6796 } else {
6797 maskc = ~0ULL;
6798 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
6799 mask = ~maskc;
6800 }
6801 assign(result, binop(Iop_And64, binop(Iop_Xor64, get_gpr_dw0(r1), mkexpr(op2)
6802 ), mkU64(mask)));
6803 if (t_bit == 0) {
6804 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
6805 mkU64(maskc)), mkexpr(result)));
6806 }
6807 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6808
6809 return "rxsbg";
6810}
6811
6812static HChar *
6813s390_irgen_ROSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
6814{
6815 UChar from;
6816 UChar to;
6817 UChar rot;
6818 UChar t_bit;
6819 ULong mask;
6820 ULong maskc;
6821 IRTemp result = newTemp(Ity_I64);
6822 IRTemp op2 = newTemp(Ity_I64);
6823
6824 from = i3 & 63;
6825 to = i4 & 63;
6826 rot = i5 & 63;
6827 t_bit = i3 & 128;
6828 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
6829 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
6830 mkU8(64 - rot))));
6831 if (from <= to) {
6832 mask = ~0ULL;
6833 mask = (mask >> from) & (mask << (63 - to));
6834 maskc = ~mask;
6835 } else {
6836 maskc = ~0ULL;
6837 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
6838 mask = ~maskc;
6839 }
6840 assign(result, binop(Iop_And64, binop(Iop_Or64, get_gpr_dw0(r1), mkexpr(op2)
6841 ), mkU64(mask)));
6842 if (t_bit == 0) {
6843 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
6844 mkU64(maskc)), mkexpr(result)));
6845 }
6846 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6847
6848 return "rosbg";
6849}
6850
6851static HChar *
6852s390_irgen_RISBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
6853{
6854 UChar from;
6855 UChar to;
6856 UChar rot;
6857 UChar z_bit;
6858 ULong mask;
6859 ULong maskc;
6860 IRTemp op2 = newTemp(Ity_I64);
6861 IRTemp result = newTemp(Ity_I64);
6862
6863 from = i3 & 63;
6864 to = i4 & 63;
6865 rot = i5 & 63;
6866 z_bit = i4 & 128;
6867 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
6868 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
6869 mkU8(64 - rot))));
6870 if (from <= to) {
6871 mask = ~0ULL;
6872 mask = (mask >> from) & (mask << (63 - to));
6873 maskc = ~mask;
6874 } else {
6875 maskc = ~0ULL;
6876 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
6877 mask = ~maskc;
6878 }
6879 if (z_bit == 0) {
6880 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
6881 mkU64(maskc)), binop(Iop_And64, mkexpr(op2), mkU64(mask))));
6882 } else {
6883 put_gpr_dw0(r1, binop(Iop_And64, mkexpr(op2), mkU64(mask)));
6884 }
6885 assign(result, get_gpr_dw0(r1));
6886 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
6887
6888 return "risbg";
6889}
6890
6891static HChar *
6892s390_irgen_SAR(UChar r1, UChar r2)
6893{
6894 put_ar_w0(r1, get_gpr_w1(r2));
sewardj7ee97522011-05-09 21:45:04 +00006895 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00006896 s390_disasm(ENC3(MNM, AR, GPR), "sar", r1, r2);
6897
6898 return "sar";
6899}
6900
6901static HChar *
6902s390_irgen_SLDA(UChar r1, IRTemp op2addr)
6903{
6904 IRTemp p1 = newTemp(Ity_I64);
6905 IRTemp p2 = newTemp(Ity_I64);
6906 IRTemp op = newTemp(Ity_I64);
6907 IRTemp result = newTemp(Ity_I64);
florian417b22d2012-07-13 13:41:41 +00006908 ULong sign_mask;
sewardj2019a972011-03-07 16:04:07 +00006909 IRTemp shift_amount = newTemp(Ity_I64);
6910
6911 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
6912 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
6913 assign(op, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1), mkU8(32)), mkexpr(p2)
6914 ));
6915 sign_mask = 1ULL << 63;
6916 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
6917 assign(result, binop(Iop_Or64, binop(Iop_And64, binop(Iop_Shl64, mkexpr(op),
florian417b22d2012-07-13 13:41:41 +00006918 unop(Iop_64to8, mkexpr(shift_amount))), mkU64(~sign_mask)),
6919 binop(Iop_And64, mkexpr(op), mkU64(sign_mask))));
sewardj2019a972011-03-07 16:04:07 +00006920 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6921 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6922 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_64, op, shift_amount);
6923
6924 return "slda";
6925}
6926
6927static HChar *
6928s390_irgen_SLDL(UChar r1, IRTemp op2addr)
6929{
6930 IRTemp p1 = newTemp(Ity_I64);
6931 IRTemp p2 = newTemp(Ity_I64);
6932 IRTemp result = newTemp(Ity_I64);
6933
6934 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
6935 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
6936 assign(result, binop(Iop_Shl64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
6937 mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
6938 mkexpr(op2addr), mkU64(63)))));
6939 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6940 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6941
6942 return "sldl";
6943}
6944
6945static HChar *
6946s390_irgen_SLA(UChar r1, IRTemp op2addr)
6947{
6948 IRTemp uop = newTemp(Ity_I32);
6949 IRTemp result = newTemp(Ity_I32);
6950 UInt sign_mask;
6951 IRTemp shift_amount = newTemp(Ity_I64);
6952 IRTemp op = newTemp(Ity_I32);
6953
6954 assign(op, get_gpr_w1(r1));
6955 assign(uop, get_gpr_w1(r1));
6956 sign_mask = 2147483648U;
6957 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
6958 assign(result, binop(Iop_Or32, binop(Iop_And32, binop(Iop_Shl32, mkexpr(uop),
6959 unop(Iop_64to8, mkexpr(shift_amount))), mkU32(~sign_mask)),
6960 binop(Iop_And32, mkexpr(uop), mkU32(sign_mask))));
6961 put_gpr_w1(r1, mkexpr(result));
6962 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_32, op, shift_amount);
6963
6964 return "sla";
6965}
6966
6967static HChar *
6968s390_irgen_SLAK(UChar r1, UChar r3, IRTemp op2addr)
6969{
6970 IRTemp uop = newTemp(Ity_I32);
6971 IRTemp result = newTemp(Ity_I32);
6972 UInt sign_mask;
6973 IRTemp shift_amount = newTemp(Ity_I64);
6974 IRTemp op = newTemp(Ity_I32);
6975
6976 assign(op, get_gpr_w1(r3));
6977 assign(uop, get_gpr_w1(r3));
6978 sign_mask = 2147483648U;
6979 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
6980 assign(result, binop(Iop_Or32, binop(Iop_And32, binop(Iop_Shl32, mkexpr(uop),
6981 unop(Iop_64to8, mkexpr(shift_amount))), mkU32(~sign_mask)),
6982 binop(Iop_And32, mkexpr(uop), mkU32(sign_mask))));
6983 put_gpr_w1(r1, mkexpr(result));
6984 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_32, op, shift_amount);
6985
6986 return "slak";
6987}
6988
6989static HChar *
6990s390_irgen_SLAG(UChar r1, UChar r3, IRTemp op2addr)
6991{
6992 IRTemp uop = newTemp(Ity_I64);
6993 IRTemp result = newTemp(Ity_I64);
6994 ULong sign_mask;
6995 IRTemp shift_amount = newTemp(Ity_I64);
6996 IRTemp op = newTemp(Ity_I64);
6997
6998 assign(op, get_gpr_dw0(r3));
6999 assign(uop, get_gpr_dw0(r3));
7000 sign_mask = 9223372036854775808ULL;
7001 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7002 assign(result, binop(Iop_Or64, binop(Iop_And64, binop(Iop_Shl64, mkexpr(uop),
7003 unop(Iop_64to8, mkexpr(shift_amount))), mkU64(~sign_mask)),
7004 binop(Iop_And64, mkexpr(uop), mkU64(sign_mask))));
7005 put_gpr_dw0(r1, mkexpr(result));
7006 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_64, op, shift_amount);
7007
7008 return "slag";
7009}
7010
7011static HChar *
7012s390_irgen_SLL(UChar r1, IRTemp op2addr)
7013{
7014 put_gpr_w1(r1, binop(Iop_Shl32, get_gpr_w1(r1), unop(Iop_64to8,
7015 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
7016
7017 return "sll";
7018}
7019
7020static HChar *
7021s390_irgen_SLLK(UChar r1, UChar r3, IRTemp op2addr)
7022{
7023 put_gpr_w1(r1, binop(Iop_Shl32, get_gpr_w1(r3), unop(Iop_64to8,
7024 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
7025
7026 return "sllk";
7027}
7028
7029static HChar *
7030s390_irgen_SLLG(UChar r1, UChar r3, IRTemp op2addr)
7031{
7032 put_gpr_dw0(r1, binop(Iop_Shl64, get_gpr_dw0(r3), unop(Iop_64to8,
7033 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
7034
7035 return "sllg";
7036}
7037
7038static HChar *
7039s390_irgen_SRDA(UChar r1, IRTemp op2addr)
7040{
7041 IRTemp p1 = newTemp(Ity_I64);
7042 IRTemp p2 = newTemp(Ity_I64);
7043 IRTemp result = newTemp(Ity_I64);
7044
7045 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7046 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7047 assign(result, binop(Iop_Sar64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
7048 mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
7049 mkexpr(op2addr), mkU64(63)))));
7050 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7051 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7052 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7053
7054 return "srda";
7055}
7056
7057static HChar *
7058s390_irgen_SRDL(UChar r1, IRTemp op2addr)
7059{
7060 IRTemp p1 = newTemp(Ity_I64);
7061 IRTemp p2 = newTemp(Ity_I64);
7062 IRTemp result = newTemp(Ity_I64);
7063
7064 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7065 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7066 assign(result, binop(Iop_Shr64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
7067 mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
7068 mkexpr(op2addr), mkU64(63)))));
7069 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7070 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7071
7072 return "srdl";
7073}
7074
7075static HChar *
7076s390_irgen_SRA(UChar r1, IRTemp op2addr)
7077{
7078 IRTemp result = newTemp(Ity_I32);
7079 IRTemp op = newTemp(Ity_I32);
7080
7081 assign(op, get_gpr_w1(r1));
7082 assign(result, binop(Iop_Sar32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7083 mkexpr(op2addr), mkU64(63)))));
7084 put_gpr_w1(r1, mkexpr(result));
7085 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7086
7087 return "sra";
7088}
7089
7090static HChar *
7091s390_irgen_SRAK(UChar r1, UChar r3, IRTemp op2addr)
7092{
7093 IRTemp result = newTemp(Ity_I32);
7094 IRTemp op = newTemp(Ity_I32);
7095
7096 assign(op, get_gpr_w1(r3));
7097 assign(result, binop(Iop_Sar32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7098 mkexpr(op2addr), mkU64(63)))));
7099 put_gpr_w1(r1, mkexpr(result));
7100 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7101
7102 return "srak";
7103}
7104
7105static HChar *
7106s390_irgen_SRAG(UChar r1, UChar r3, IRTemp op2addr)
7107{
7108 IRTemp result = newTemp(Ity_I64);
7109 IRTemp op = newTemp(Ity_I64);
7110
7111 assign(op, get_gpr_dw0(r3));
7112 assign(result, binop(Iop_Sar64, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7113 mkexpr(op2addr), mkU64(63)))));
7114 put_gpr_dw0(r1, mkexpr(result));
7115 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7116
7117 return "srag";
7118}
7119
7120static HChar *
7121s390_irgen_SRL(UChar r1, IRTemp op2addr)
7122{
7123 IRTemp op = newTemp(Ity_I32);
7124
7125 assign(op, get_gpr_w1(r1));
7126 put_gpr_w1(r1, binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7127 mkexpr(op2addr), mkU64(63)))));
7128
7129 return "srl";
7130}
7131
7132static HChar *
7133s390_irgen_SRLK(UChar r1, UChar r3, IRTemp op2addr)
7134{
7135 IRTemp op = newTemp(Ity_I32);
7136
7137 assign(op, get_gpr_w1(r3));
7138 put_gpr_w1(r1, binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7139 mkexpr(op2addr), mkU64(63)))));
7140
7141 return "srlk";
7142}
7143
7144static HChar *
7145s390_irgen_SRLG(UChar r1, UChar r3, IRTemp op2addr)
7146{
7147 IRTemp op = newTemp(Ity_I64);
7148
7149 assign(op, get_gpr_dw0(r3));
7150 put_gpr_dw0(r1, binop(Iop_Shr64, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7151 mkexpr(op2addr), mkU64(63)))));
7152
7153 return "srlg";
7154}
7155
7156static HChar *
7157s390_irgen_ST(UChar r1, IRTemp op2addr)
7158{
7159 store(mkexpr(op2addr), get_gpr_w1(r1));
7160
7161 return "st";
7162}
7163
7164static HChar *
7165s390_irgen_STY(UChar r1, IRTemp op2addr)
7166{
7167 store(mkexpr(op2addr), get_gpr_w1(r1));
7168
7169 return "sty";
7170}
7171
7172static HChar *
7173s390_irgen_STG(UChar r1, IRTemp op2addr)
7174{
7175 store(mkexpr(op2addr), get_gpr_dw0(r1));
7176
7177 return "stg";
7178}
7179
7180static HChar *
7181s390_irgen_STRL(UChar r1, UInt i2)
7182{
7183 store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
7184 get_gpr_w1(r1));
7185
7186 return "strl";
7187}
7188
7189static HChar *
7190s390_irgen_STGRL(UChar r1, UInt i2)
7191{
7192 store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
7193 get_gpr_dw0(r1));
7194
7195 return "stgrl";
7196}
7197
7198static HChar *
7199s390_irgen_STC(UChar r1, IRTemp op2addr)
7200{
7201 store(mkexpr(op2addr), get_gpr_b7(r1));
7202
7203 return "stc";
7204}
7205
7206static HChar *
7207s390_irgen_STCY(UChar r1, IRTemp op2addr)
7208{
7209 store(mkexpr(op2addr), get_gpr_b7(r1));
7210
7211 return "stcy";
7212}
7213
7214static HChar *
7215s390_irgen_STCH(UChar r1, IRTemp op2addr)
7216{
7217 store(mkexpr(op2addr), get_gpr_b3(r1));
7218
7219 return "stch";
7220}
7221
7222static HChar *
7223s390_irgen_STCM(UChar r1, UChar r3, IRTemp op2addr)
7224{
7225 UChar mask;
7226 UChar n;
7227
7228 mask = (UChar)r3;
7229 n = 0;
7230 if ((mask & 8) != 0) {
7231 store(mkexpr(op2addr), get_gpr_b4(r1));
7232 n = n + 1;
7233 }
7234 if ((mask & 4) != 0) {
7235 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b5(r1));
7236 n = n + 1;
7237 }
7238 if ((mask & 2) != 0) {
7239 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b6(r1));
7240 n = n + 1;
7241 }
7242 if ((mask & 1) != 0) {
7243 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b7(r1));
7244 }
7245
7246 return "stcm";
7247}
7248
7249static HChar *
7250s390_irgen_STCMY(UChar r1, UChar r3, IRTemp op2addr)
7251{
7252 UChar mask;
7253 UChar n;
7254
7255 mask = (UChar)r3;
7256 n = 0;
7257 if ((mask & 8) != 0) {
7258 store(mkexpr(op2addr), get_gpr_b4(r1));
7259 n = n + 1;
7260 }
7261 if ((mask & 4) != 0) {
7262 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b5(r1));
7263 n = n + 1;
7264 }
7265 if ((mask & 2) != 0) {
7266 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b6(r1));
7267 n = n + 1;
7268 }
7269 if ((mask & 1) != 0) {
7270 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b7(r1));
7271 }
7272
7273 return "stcmy";
7274}
7275
7276static HChar *
7277s390_irgen_STCMH(UChar r1, UChar r3, IRTemp op2addr)
7278{
7279 UChar mask;
7280 UChar n;
7281
7282 mask = (UChar)r3;
7283 n = 0;
7284 if ((mask & 8) != 0) {
7285 store(mkexpr(op2addr), get_gpr_b0(r1));
7286 n = n + 1;
7287 }
7288 if ((mask & 4) != 0) {
7289 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b1(r1));
7290 n = n + 1;
7291 }
7292 if ((mask & 2) != 0) {
7293 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b2(r1));
7294 n = n + 1;
7295 }
7296 if ((mask & 1) != 0) {
7297 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b3(r1));
7298 }
7299
7300 return "stcmh";
7301}
7302
7303static HChar *
7304s390_irgen_STH(UChar r1, IRTemp op2addr)
7305{
7306 store(mkexpr(op2addr), get_gpr_hw3(r1));
7307
7308 return "sth";
7309}
7310
7311static HChar *
7312s390_irgen_STHY(UChar r1, IRTemp op2addr)
7313{
7314 store(mkexpr(op2addr), get_gpr_hw3(r1));
7315
7316 return "sthy";
7317}
7318
7319static HChar *
7320s390_irgen_STHRL(UChar r1, UInt i2)
7321{
7322 store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
7323 get_gpr_hw3(r1));
7324
7325 return "sthrl";
7326}
7327
7328static HChar *
7329s390_irgen_STHH(UChar r1, IRTemp op2addr)
7330{
7331 store(mkexpr(op2addr), get_gpr_hw1(r1));
7332
7333 return "sthh";
7334}
7335
7336static HChar *
7337s390_irgen_STFH(UChar r1, IRTemp op2addr)
7338{
7339 store(mkexpr(op2addr), get_gpr_w0(r1));
7340
7341 return "stfh";
7342}
7343
7344static HChar *
sewardjd7bde722011-04-05 13:19:33 +00007345s390_irgen_STOC(UChar r1, IRTemp op2addr)
7346{
7347 /* condition is checked in format handler */
7348 store(mkexpr(op2addr), get_gpr_w1(r1));
7349
7350 return "stoc";
7351}
7352
7353static HChar *
7354s390_irgen_STOCG(UChar r1, IRTemp op2addr)
7355{
7356 /* condition is checked in format handler */
7357 store(mkexpr(op2addr), get_gpr_dw0(r1));
7358
7359 return "stocg";
7360}
7361
7362static HChar *
sewardj2019a972011-03-07 16:04:07 +00007363s390_irgen_STPQ(UChar r1, IRTemp op2addr)
7364{
7365 store(mkexpr(op2addr), get_gpr_dw0(r1));
7366 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(8)), get_gpr_dw0(r1 + 1));
7367
7368 return "stpq";
7369}
7370
7371static HChar *
7372s390_irgen_STRVH(UChar r1, IRTemp op2addr)
7373{
7374 store(mkexpr(op2addr), get_gpr_b7(r1));
7375 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
7376
7377 return "strvh";
7378}
7379
7380static HChar *
7381s390_irgen_STRV(UChar r1, IRTemp op2addr)
7382{
7383 store(mkexpr(op2addr), get_gpr_b7(r1));
7384 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
7385 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(2)), get_gpr_b5(r1));
7386 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(3)), get_gpr_b4(r1));
7387
7388 return "strv";
7389}
7390
7391static HChar *
7392s390_irgen_STRVG(UChar r1, IRTemp op2addr)
7393{
7394 store(mkexpr(op2addr), get_gpr_b7(r1));
7395 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
7396 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(2)), get_gpr_b5(r1));
7397 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(3)), get_gpr_b4(r1));
7398 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(4)), get_gpr_b3(r1));
7399 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(5)), get_gpr_b2(r1));
7400 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(6)), get_gpr_b1(r1));
7401 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(7)), get_gpr_b0(r1));
7402
7403 return "strvg";
7404}
7405
7406static HChar *
7407s390_irgen_SR(UChar r1, UChar r2)
7408{
7409 IRTemp op1 = newTemp(Ity_I32);
7410 IRTemp op2 = newTemp(Ity_I32);
7411 IRTemp result = newTemp(Ity_I32);
7412
7413 assign(op1, get_gpr_w1(r1));
7414 assign(op2, get_gpr_w1(r2));
7415 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7416 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7417 put_gpr_w1(r1, mkexpr(result));
7418
7419 return "sr";
7420}
7421
7422static HChar *
7423s390_irgen_SGR(UChar r1, UChar r2)
7424{
7425 IRTemp op1 = newTemp(Ity_I64);
7426 IRTemp op2 = newTemp(Ity_I64);
7427 IRTemp result = newTemp(Ity_I64);
7428
7429 assign(op1, get_gpr_dw0(r1));
7430 assign(op2, get_gpr_dw0(r2));
7431 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7432 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
7433 put_gpr_dw0(r1, mkexpr(result));
7434
7435 return "sgr";
7436}
7437
7438static HChar *
7439s390_irgen_SGFR(UChar r1, UChar r2)
7440{
7441 IRTemp op1 = newTemp(Ity_I64);
7442 IRTemp op2 = newTemp(Ity_I64);
7443 IRTemp result = newTemp(Ity_I64);
7444
7445 assign(op1, get_gpr_dw0(r1));
7446 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
7447 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7448 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
7449 put_gpr_dw0(r1, mkexpr(result));
7450
7451 return "sgfr";
7452}
7453
7454static HChar *
7455s390_irgen_SRK(UChar r3, UChar r1, UChar r2)
7456{
7457 IRTemp op2 = newTemp(Ity_I32);
7458 IRTemp op3 = newTemp(Ity_I32);
7459 IRTemp result = newTemp(Ity_I32);
7460
7461 assign(op2, get_gpr_w1(r2));
7462 assign(op3, get_gpr_w1(r3));
7463 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
7464 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
7465 put_gpr_w1(r1, mkexpr(result));
7466
7467 return "srk";
7468}
7469
7470static HChar *
7471s390_irgen_SGRK(UChar r3, UChar r1, UChar r2)
7472{
7473 IRTemp op2 = newTemp(Ity_I64);
7474 IRTemp op3 = newTemp(Ity_I64);
7475 IRTemp result = newTemp(Ity_I64);
7476
7477 assign(op2, get_gpr_dw0(r2));
7478 assign(op3, get_gpr_dw0(r3));
7479 assign(result, binop(Iop_Sub64, mkexpr(op2), mkexpr(op3)));
7480 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op2, op3);
7481 put_gpr_dw0(r1, mkexpr(result));
7482
7483 return "sgrk";
7484}
7485
7486static HChar *
7487s390_irgen_S(UChar r1, IRTemp op2addr)
7488{
7489 IRTemp op1 = newTemp(Ity_I32);
7490 IRTemp op2 = newTemp(Ity_I32);
7491 IRTemp result = newTemp(Ity_I32);
7492
7493 assign(op1, get_gpr_w1(r1));
7494 assign(op2, load(Ity_I32, mkexpr(op2addr)));
7495 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7496 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7497 put_gpr_w1(r1, mkexpr(result));
7498
7499 return "s";
7500}
7501
7502static HChar *
7503s390_irgen_SY(UChar r1, IRTemp op2addr)
7504{
7505 IRTemp op1 = newTemp(Ity_I32);
7506 IRTemp op2 = newTemp(Ity_I32);
7507 IRTemp result = newTemp(Ity_I32);
7508
7509 assign(op1, get_gpr_w1(r1));
7510 assign(op2, load(Ity_I32, mkexpr(op2addr)));
7511 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7512 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7513 put_gpr_w1(r1, mkexpr(result));
7514
7515 return "sy";
7516}
7517
7518static HChar *
7519s390_irgen_SG(UChar r1, IRTemp op2addr)
7520{
7521 IRTemp op1 = newTemp(Ity_I64);
7522 IRTemp op2 = newTemp(Ity_I64);
7523 IRTemp result = newTemp(Ity_I64);
7524
7525 assign(op1, get_gpr_dw0(r1));
7526 assign(op2, load(Ity_I64, mkexpr(op2addr)));
7527 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7528 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
7529 put_gpr_dw0(r1, mkexpr(result));
7530
7531 return "sg";
7532}
7533
7534static HChar *
7535s390_irgen_SGF(UChar r1, IRTemp op2addr)
7536{
7537 IRTemp op1 = newTemp(Ity_I64);
7538 IRTemp op2 = newTemp(Ity_I64);
7539 IRTemp result = newTemp(Ity_I64);
7540
7541 assign(op1, get_gpr_dw0(r1));
7542 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
7543 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7544 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
7545 put_gpr_dw0(r1, mkexpr(result));
7546
7547 return "sgf";
7548}
7549
7550static HChar *
7551s390_irgen_SH(UChar r1, IRTemp op2addr)
7552{
7553 IRTemp op1 = newTemp(Ity_I32);
7554 IRTemp op2 = newTemp(Ity_I32);
7555 IRTemp result = newTemp(Ity_I32);
7556
7557 assign(op1, get_gpr_w1(r1));
7558 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
7559 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7560 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7561 put_gpr_w1(r1, mkexpr(result));
7562
7563 return "sh";
7564}
7565
7566static HChar *
7567s390_irgen_SHY(UChar r1, IRTemp op2addr)
7568{
7569 IRTemp op1 = newTemp(Ity_I32);
7570 IRTemp op2 = newTemp(Ity_I32);
7571 IRTemp result = newTemp(Ity_I32);
7572
7573 assign(op1, get_gpr_w1(r1));
7574 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
7575 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7576 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7577 put_gpr_w1(r1, mkexpr(result));
7578
7579 return "shy";
7580}
7581
7582static HChar *
7583s390_irgen_SHHHR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
7584{
7585 IRTemp op2 = newTemp(Ity_I32);
7586 IRTemp op3 = newTemp(Ity_I32);
7587 IRTemp result = newTemp(Ity_I32);
7588
7589 assign(op2, get_gpr_w0(r1));
7590 assign(op3, get_gpr_w0(r2));
7591 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
7592 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
7593 put_gpr_w0(r1, mkexpr(result));
7594
7595 return "shhhr";
7596}
7597
7598static HChar *
7599s390_irgen_SHHLR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
7600{
7601 IRTemp op2 = newTemp(Ity_I32);
7602 IRTemp op3 = newTemp(Ity_I32);
7603 IRTemp result = newTemp(Ity_I32);
7604
7605 assign(op2, get_gpr_w0(r1));
7606 assign(op3, get_gpr_w1(r2));
7607 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
7608 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
7609 put_gpr_w0(r1, mkexpr(result));
7610
7611 return "shhlr";
7612}
7613
7614static HChar *
7615s390_irgen_SLR(UChar r1, UChar r2)
7616{
7617 IRTemp op1 = newTemp(Ity_I32);
7618 IRTemp op2 = newTemp(Ity_I32);
7619 IRTemp result = newTemp(Ity_I32);
7620
7621 assign(op1, get_gpr_w1(r1));
7622 assign(op2, get_gpr_w1(r2));
7623 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7624 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
7625 put_gpr_w1(r1, mkexpr(result));
7626
7627 return "slr";
7628}
7629
7630static HChar *
7631s390_irgen_SLGR(UChar r1, UChar r2)
7632{
7633 IRTemp op1 = newTemp(Ity_I64);
7634 IRTemp op2 = newTemp(Ity_I64);
7635 IRTemp result = newTemp(Ity_I64);
7636
7637 assign(op1, get_gpr_dw0(r1));
7638 assign(op2, get_gpr_dw0(r2));
7639 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7640 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
7641 put_gpr_dw0(r1, mkexpr(result));
7642
7643 return "slgr";
7644}
7645
7646static HChar *
7647s390_irgen_SLGFR(UChar r1, UChar r2)
7648{
7649 IRTemp op1 = newTemp(Ity_I64);
7650 IRTemp op2 = newTemp(Ity_I64);
7651 IRTemp result = newTemp(Ity_I64);
7652
7653 assign(op1, get_gpr_dw0(r1));
7654 assign(op2, unop(Iop_32Uto64, get_gpr_w1(r2)));
7655 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7656 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
7657 put_gpr_dw0(r1, mkexpr(result));
7658
7659 return "slgfr";
7660}
7661
7662static HChar *
7663s390_irgen_SLRK(UChar r3, UChar r1, UChar r2)
7664{
7665 IRTemp op2 = newTemp(Ity_I32);
7666 IRTemp op3 = newTemp(Ity_I32);
7667 IRTemp result = newTemp(Ity_I32);
7668
7669 assign(op2, get_gpr_w1(r2));
7670 assign(op3, get_gpr_w1(r3));
7671 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
7672 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
7673 put_gpr_w1(r1, mkexpr(result));
7674
7675 return "slrk";
7676}
7677
7678static HChar *
7679s390_irgen_SLGRK(UChar r3, UChar r1, UChar r2)
7680{
7681 IRTemp op2 = newTemp(Ity_I64);
7682 IRTemp op3 = newTemp(Ity_I64);
7683 IRTemp result = newTemp(Ity_I64);
7684
7685 assign(op2, get_gpr_dw0(r2));
7686 assign(op3, get_gpr_dw0(r3));
7687 assign(result, binop(Iop_Sub64, mkexpr(op2), mkexpr(op3)));
7688 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op2, op3);
7689 put_gpr_dw0(r1, mkexpr(result));
7690
7691 return "slgrk";
7692}
7693
7694static HChar *
7695s390_irgen_SL(UChar r1, IRTemp op2addr)
7696{
7697 IRTemp op1 = newTemp(Ity_I32);
7698 IRTemp op2 = newTemp(Ity_I32);
7699 IRTemp result = newTemp(Ity_I32);
7700
7701 assign(op1, get_gpr_w1(r1));
7702 assign(op2, load(Ity_I32, mkexpr(op2addr)));
7703 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7704 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
7705 put_gpr_w1(r1, mkexpr(result));
7706
7707 return "sl";
7708}
7709
7710static HChar *
7711s390_irgen_SLY(UChar r1, IRTemp op2addr)
7712{
7713 IRTemp op1 = newTemp(Ity_I32);
7714 IRTemp op2 = newTemp(Ity_I32);
7715 IRTemp result = newTemp(Ity_I32);
7716
7717 assign(op1, get_gpr_w1(r1));
7718 assign(op2, load(Ity_I32, mkexpr(op2addr)));
7719 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7720 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
7721 put_gpr_w1(r1, mkexpr(result));
7722
7723 return "sly";
7724}
7725
7726static HChar *
7727s390_irgen_SLG(UChar r1, IRTemp op2addr)
7728{
7729 IRTemp op1 = newTemp(Ity_I64);
7730 IRTemp op2 = newTemp(Ity_I64);
7731 IRTemp result = newTemp(Ity_I64);
7732
7733 assign(op1, get_gpr_dw0(r1));
7734 assign(op2, load(Ity_I64, mkexpr(op2addr)));
7735 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7736 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
7737 put_gpr_dw0(r1, mkexpr(result));
7738
7739 return "slg";
7740}
7741
7742static HChar *
7743s390_irgen_SLGF(UChar r1, IRTemp op2addr)
7744{
7745 IRTemp op1 = newTemp(Ity_I64);
7746 IRTemp op2 = newTemp(Ity_I64);
7747 IRTemp result = newTemp(Ity_I64);
7748
7749 assign(op1, get_gpr_dw0(r1));
7750 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
7751 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7752 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
7753 put_gpr_dw0(r1, mkexpr(result));
7754
7755 return "slgf";
7756}
7757
7758static HChar *
7759s390_irgen_SLFI(UChar r1, UInt i2)
7760{
7761 IRTemp op1 = newTemp(Ity_I32);
7762 UInt op2;
7763 IRTemp result = newTemp(Ity_I32);
7764
7765 assign(op1, get_gpr_w1(r1));
7766 op2 = i2;
7767 assign(result, binop(Iop_Sub32, mkexpr(op1), mkU32(op2)));
7768 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, mktemp(Ity_I32,
7769 mkU32(op2)));
7770 put_gpr_w1(r1, mkexpr(result));
7771
7772 return "slfi";
7773}
7774
7775static HChar *
7776s390_irgen_SLGFI(UChar r1, UInt i2)
7777{
7778 IRTemp op1 = newTemp(Ity_I64);
7779 ULong op2;
7780 IRTemp result = newTemp(Ity_I64);
7781
7782 assign(op1, get_gpr_dw0(r1));
7783 op2 = (ULong)i2;
7784 assign(result, binop(Iop_Sub64, mkexpr(op1), mkU64(op2)));
7785 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, mktemp(Ity_I64,
7786 mkU64(op2)));
7787 put_gpr_dw0(r1, mkexpr(result));
7788
7789 return "slgfi";
7790}
7791
7792static HChar *
7793s390_irgen_SLHHHR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
7794{
7795 IRTemp op2 = newTemp(Ity_I32);
7796 IRTemp op3 = newTemp(Ity_I32);
7797 IRTemp result = newTemp(Ity_I32);
7798
7799 assign(op2, get_gpr_w0(r1));
7800 assign(op3, get_gpr_w0(r2));
7801 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
7802 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
7803 put_gpr_w0(r1, mkexpr(result));
7804
7805 return "slhhhr";
7806}
7807
7808static HChar *
7809s390_irgen_SLHHLR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
7810{
7811 IRTemp op2 = newTemp(Ity_I32);
7812 IRTemp op3 = newTemp(Ity_I32);
7813 IRTemp result = newTemp(Ity_I32);
7814
7815 assign(op2, get_gpr_w0(r1));
7816 assign(op3, get_gpr_w1(r2));
7817 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
7818 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
7819 put_gpr_w0(r1, mkexpr(result));
7820
7821 return "slhhlr";
7822}
7823
7824static HChar *
7825s390_irgen_SLBR(UChar r1, UChar r2)
7826{
7827 IRTemp op1 = newTemp(Ity_I32);
7828 IRTemp op2 = newTemp(Ity_I32);
7829 IRTemp result = newTemp(Ity_I32);
7830 IRTemp borrow_in = newTemp(Ity_I32);
7831
7832 assign(op1, get_gpr_w1(r1));
7833 assign(op2, get_gpr_w1(r2));
7834 assign(borrow_in, binop(Iop_Sub32, mkU32(1), binop(Iop_Shr32,
7835 s390_call_calculate_cc(), mkU8(1))));
7836 assign(result, binop(Iop_Sub32, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)),
7837 mkexpr(borrow_in)));
7838 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_32, op1, op2, borrow_in);
7839 put_gpr_w1(r1, mkexpr(result));
7840
7841 return "slbr";
7842}
7843
7844static HChar *
7845s390_irgen_SLBGR(UChar r1, UChar r2)
7846{
7847 IRTemp op1 = newTemp(Ity_I64);
7848 IRTemp op2 = newTemp(Ity_I64);
7849 IRTemp result = newTemp(Ity_I64);
7850 IRTemp borrow_in = newTemp(Ity_I64);
7851
7852 assign(op1, get_gpr_dw0(r1));
7853 assign(op2, get_gpr_dw0(r2));
7854 assign(borrow_in, unop(Iop_32Uto64, binop(Iop_Sub32, mkU32(1),
7855 binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)))));
7856 assign(result, binop(Iop_Sub64, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)),
7857 mkexpr(borrow_in)));
7858 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_64, op1, op2, borrow_in);
7859 put_gpr_dw0(r1, mkexpr(result));
7860
7861 return "slbgr";
7862}
7863
7864static HChar *
7865s390_irgen_SLB(UChar r1, IRTemp op2addr)
7866{
7867 IRTemp op1 = newTemp(Ity_I32);
7868 IRTemp op2 = newTemp(Ity_I32);
7869 IRTemp result = newTemp(Ity_I32);
7870 IRTemp borrow_in = newTemp(Ity_I32);
7871
7872 assign(op1, get_gpr_w1(r1));
7873 assign(op2, load(Ity_I32, mkexpr(op2addr)));
7874 assign(borrow_in, binop(Iop_Sub32, mkU32(1), binop(Iop_Shr32,
7875 s390_call_calculate_cc(), mkU8(1))));
7876 assign(result, binop(Iop_Sub32, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)),
7877 mkexpr(borrow_in)));
7878 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_32, op1, op2, borrow_in);
7879 put_gpr_w1(r1, mkexpr(result));
7880
7881 return "slb";
7882}
7883
7884static HChar *
7885s390_irgen_SLBG(UChar r1, IRTemp op2addr)
7886{
7887 IRTemp op1 = newTemp(Ity_I64);
7888 IRTemp op2 = newTemp(Ity_I64);
7889 IRTemp result = newTemp(Ity_I64);
7890 IRTemp borrow_in = newTemp(Ity_I64);
7891
7892 assign(op1, get_gpr_dw0(r1));
7893 assign(op2, load(Ity_I64, mkexpr(op2addr)));
7894 assign(borrow_in, unop(Iop_32Uto64, binop(Iop_Sub32, mkU32(1),
7895 binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)))));
7896 assign(result, binop(Iop_Sub64, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)),
7897 mkexpr(borrow_in)));
7898 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_64, op1, op2, borrow_in);
7899 put_gpr_dw0(r1, mkexpr(result));
7900
7901 return "slbg";
7902}
7903
7904static HChar *
7905s390_irgen_SVC(UChar i)
7906{
7907 IRTemp sysno = newTemp(Ity_I64);
7908
7909 if (i != 0) {
7910 assign(sysno, mkU64(i));
7911 } else {
7912 assign(sysno, unop(Iop_32Uto64, get_gpr_w1(1)));
7913 }
7914 system_call(mkexpr(sysno));
7915
7916 return "svc";
7917}
7918
7919static HChar *
sewardj2019a972011-03-07 16:04:07 +00007920s390_irgen_TM(UChar i2, IRTemp op1addr)
7921{
7922 UChar mask;
7923 IRTemp value = newTemp(Ity_I8);
7924
7925 mask = i2;
7926 assign(value, load(Ity_I8, mkexpr(op1addr)));
7927 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_8, value, mktemp(Ity_I8,
7928 mkU8(mask)));
7929
7930 return "tm";
7931}
7932
7933static HChar *
7934s390_irgen_TMY(UChar i2, IRTemp op1addr)
7935{
7936 UChar mask;
7937 IRTemp value = newTemp(Ity_I8);
7938
7939 mask = i2;
7940 assign(value, load(Ity_I8, mkexpr(op1addr)));
7941 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_8, value, mktemp(Ity_I8,
7942 mkU8(mask)));
7943
7944 return "tmy";
7945}
7946
7947static HChar *
7948s390_irgen_TMHH(UChar r1, UShort i2)
7949{
7950 UShort mask;
7951 IRTemp value = newTemp(Ity_I16);
7952
7953 mask = i2;
7954 assign(value, get_gpr_hw0(r1));
7955 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
7956 mkU16(mask)));
7957
7958 return "tmhh";
7959}
7960
7961static HChar *
7962s390_irgen_TMHL(UChar r1, UShort i2)
7963{
7964 UShort mask;
7965 IRTemp value = newTemp(Ity_I16);
7966
7967 mask = i2;
7968 assign(value, get_gpr_hw1(r1));
7969 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
7970 mkU16(mask)));
7971
7972 return "tmhl";
7973}
7974
7975static HChar *
7976s390_irgen_TMLH(UChar r1, UShort i2)
7977{
7978 UShort mask;
7979 IRTemp value = newTemp(Ity_I16);
7980
7981 mask = i2;
7982 assign(value, get_gpr_hw2(r1));
7983 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
7984 mkU16(mask)));
7985
7986 return "tmlh";
7987}
7988
7989static HChar *
7990s390_irgen_TMLL(UChar r1, UShort i2)
7991{
7992 UShort mask;
7993 IRTemp value = newTemp(Ity_I16);
7994
7995 mask = i2;
7996 assign(value, get_gpr_hw3(r1));
7997 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
7998 mkU16(mask)));
7999
8000 return "tmll";
8001}
8002
8003static HChar *
8004s390_irgen_EFPC(UChar r1)
8005{
8006 put_gpr_w1(r1, get_fpc_w0());
8007
8008 return "efpc";
8009}
8010
8011static HChar *
8012s390_irgen_LER(UChar r1, UChar r2)
8013{
8014 put_fpr_w0(r1, get_fpr_w0(r2));
8015
8016 return "ler";
8017}
8018
8019static HChar *
8020s390_irgen_LDR(UChar r1, UChar r2)
8021{
8022 put_fpr_dw0(r1, get_fpr_dw0(r2));
8023
8024 return "ldr";
8025}
8026
8027static HChar *
8028s390_irgen_LXR(UChar r1, UChar r2)
8029{
8030 put_fpr_dw0(r1, get_fpr_dw0(r2));
8031 put_fpr_dw0(r1 + 2, get_fpr_dw0(r2 + 2));
8032
8033 return "lxr";
8034}
8035
8036static HChar *
8037s390_irgen_LE(UChar r1, IRTemp op2addr)
8038{
8039 put_fpr_w0(r1, load(Ity_F32, mkexpr(op2addr)));
8040
8041 return "le";
8042}
8043
8044static HChar *
8045s390_irgen_LD(UChar r1, IRTemp op2addr)
8046{
8047 put_fpr_dw0(r1, load(Ity_F64, mkexpr(op2addr)));
8048
8049 return "ld";
8050}
8051
8052static HChar *
8053s390_irgen_LEY(UChar r1, IRTemp op2addr)
8054{
8055 put_fpr_w0(r1, load(Ity_F32, mkexpr(op2addr)));
8056
8057 return "ley";
8058}
8059
8060static HChar *
8061s390_irgen_LDY(UChar r1, IRTemp op2addr)
8062{
8063 put_fpr_dw0(r1, load(Ity_F64, mkexpr(op2addr)));
8064
8065 return "ldy";
8066}
8067
8068static HChar *
8069s390_irgen_LFPC(IRTemp op2addr)
8070{
8071 put_fpc_w0(load(Ity_I32, mkexpr(op2addr)));
8072
8073 return "lfpc";
8074}
8075
8076static HChar *
8077s390_irgen_LZER(UChar r1)
8078{
8079 put_fpr_w0(r1, mkF32i(0x0));
8080
8081 return "lzer";
8082}
8083
8084static HChar *
8085s390_irgen_LZDR(UChar r1)
8086{
8087 put_fpr_dw0(r1, mkF64i(0x0));
8088
8089 return "lzdr";
8090}
8091
8092static HChar *
8093s390_irgen_LZXR(UChar r1)
8094{
8095 put_fpr_dw0(r1, mkF64i(0x0));
8096 put_fpr_dw0(r1 + 2, mkF64i(0x0));
8097
8098 return "lzxr";
8099}
8100
8101static HChar *
8102s390_irgen_SRNM(IRTemp op2addr)
8103{
8104 UInt mask;
8105
8106 mask = 3;
8107 put_fpc_w0(binop(Iop_Or32, binop(Iop_And32, get_fpc_w0(), mkU32(~mask)),
8108 binop(Iop_And32, unop(Iop_64to32, mkexpr(op2addr)), mkU32(mask)))
8109 );
8110
8111 return "srnm";
8112}
8113
8114static HChar *
8115s390_irgen_SFPC(UChar r1)
8116{
8117 put_fpc_w0(get_gpr_w1(r1));
8118
8119 return "sfpc";
8120}
8121
8122static HChar *
8123s390_irgen_STE(UChar r1, IRTemp op2addr)
8124{
8125 store(mkexpr(op2addr), get_fpr_w0(r1));
8126
8127 return "ste";
8128}
8129
8130static HChar *
8131s390_irgen_STD(UChar r1, IRTemp op2addr)
8132{
8133 store(mkexpr(op2addr), get_fpr_dw0(r1));
8134
8135 return "std";
8136}
8137
8138static HChar *
8139s390_irgen_STEY(UChar r1, IRTemp op2addr)
8140{
8141 store(mkexpr(op2addr), get_fpr_w0(r1));
8142
8143 return "stey";
8144}
8145
8146static HChar *
8147s390_irgen_STDY(UChar r1, IRTemp op2addr)
8148{
8149 store(mkexpr(op2addr), get_fpr_dw0(r1));
8150
8151 return "stdy";
8152}
8153
8154static HChar *
8155s390_irgen_STFPC(IRTemp op2addr)
8156{
8157 store(mkexpr(op2addr), get_fpc_w0());
8158
8159 return "stfpc";
8160}
8161
8162static HChar *
8163s390_irgen_AEBR(UChar r1, UChar r2)
8164{
8165 IRTemp op1 = newTemp(Ity_F32);
8166 IRTemp op2 = newTemp(Ity_F32);
8167 IRTemp result = newTemp(Ity_F32);
8168
8169 assign(op1, get_fpr_w0(r1));
8170 assign(op2, get_fpr_w0(r2));
8171 assign(result, triop(Iop_AddF32, mkU32(Irrm_NEAREST), mkexpr(op1),
8172 mkexpr(op2)));
8173 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8174 put_fpr_w0(r1, mkexpr(result));
8175
8176 return "aebr";
8177}
8178
8179static HChar *
8180s390_irgen_ADBR(UChar r1, UChar r2)
8181{
8182 IRTemp op1 = newTemp(Ity_F64);
8183 IRTemp op2 = newTemp(Ity_F64);
8184 IRTemp result = newTemp(Ity_F64);
8185
8186 assign(op1, get_fpr_dw0(r1));
8187 assign(op2, get_fpr_dw0(r2));
8188 assign(result, triop(Iop_AddF64, mkU32(Irrm_NEAREST), mkexpr(op1),
8189 mkexpr(op2)));
8190 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8191 put_fpr_dw0(r1, mkexpr(result));
8192
8193 return "adbr";
8194}
8195
8196static HChar *
8197s390_irgen_AEB(UChar r1, IRTemp op2addr)
8198{
8199 IRTemp op1 = newTemp(Ity_F32);
8200 IRTemp op2 = newTemp(Ity_F32);
8201 IRTemp result = newTemp(Ity_F32);
8202
8203 assign(op1, get_fpr_w0(r1));
8204 assign(op2, load(Ity_F32, mkexpr(op2addr)));
8205 assign(result, triop(Iop_AddF32, mkU32(Irrm_NEAREST), mkexpr(op1),
8206 mkexpr(op2)));
8207 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8208 put_fpr_w0(r1, mkexpr(result));
8209
8210 return "aeb";
8211}
8212
8213static HChar *
8214s390_irgen_ADB(UChar r1, IRTemp op2addr)
8215{
8216 IRTemp op1 = newTemp(Ity_F64);
8217 IRTemp op2 = newTemp(Ity_F64);
8218 IRTemp result = newTemp(Ity_F64);
8219
8220 assign(op1, get_fpr_dw0(r1));
8221 assign(op2, load(Ity_F64, mkexpr(op2addr)));
8222 assign(result, triop(Iop_AddF64, mkU32(Irrm_NEAREST), mkexpr(op1),
8223 mkexpr(op2)));
8224 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8225 put_fpr_dw0(r1, mkexpr(result));
8226
8227 return "adb";
8228}
8229
8230static HChar *
8231s390_irgen_CEFBR(UChar r1, UChar r2)
8232{
8233 IRTemp op2 = newTemp(Ity_I32);
8234
8235 assign(op2, get_gpr_w1(r2));
8236 put_fpr_w0(r1, binop(Iop_I32StoF32, mkU32(Irrm_NEAREST), mkexpr(op2)));
8237
8238 return "cefbr";
8239}
8240
8241static HChar *
8242s390_irgen_CDFBR(UChar r1, UChar r2)
8243{
8244 IRTemp op2 = newTemp(Ity_I32);
8245
8246 assign(op2, get_gpr_w1(r2));
8247 put_fpr_dw0(r1, unop(Iop_I32StoF64, mkexpr(op2)));
8248
8249 return "cdfbr";
8250}
8251
8252static HChar *
8253s390_irgen_CEGBR(UChar r1, UChar r2)
8254{
8255 IRTemp op2 = newTemp(Ity_I64);
8256
8257 assign(op2, get_gpr_dw0(r2));
8258 put_fpr_w0(r1, binop(Iop_I64StoF32, mkU32(Irrm_NEAREST), mkexpr(op2)));
8259
8260 return "cegbr";
8261}
8262
8263static HChar *
8264s390_irgen_CDGBR(UChar r1, UChar r2)
8265{
8266 IRTemp op2 = newTemp(Ity_I64);
8267
8268 assign(op2, get_gpr_dw0(r2));
8269 put_fpr_dw0(r1, binop(Iop_I64StoF64, mkU32(Irrm_NEAREST), mkexpr(op2)));
8270
8271 return "cdgbr";
8272}
8273
8274static HChar *
florian1c8f7ff2012-09-01 00:12:11 +00008275s390_irgen_CELFBR(UChar m3, UChar m4 __attribute__((unused)),
8276 UChar r1, UChar r2)
8277{
8278 IRTemp op2 = newTemp(Ity_I32);
8279
8280 assign(op2, get_gpr_w1(r2));
8281 put_fpr_w0(r1, binop(Iop_I32UtoF32, mkU32(encode_rounding_mode(m3)),
8282 mkexpr(op2)));
8283
8284 return "celfbr";
8285}
8286
8287static HChar *
8288s390_irgen_CDLFBR(UChar m3, UChar m4 __attribute__((unused)),
8289 UChar r1, UChar r2)
8290{
8291 IRTemp op2 = newTemp(Ity_I32);
8292
8293 assign(op2, get_gpr_w1(r2));
8294 put_fpr_dw0(r1, unop(Iop_I32UtoF64, mkexpr(op2)));
8295
8296 return "cdlfbr";
8297}
8298
8299static HChar *
8300s390_irgen_CELGBR(UChar m3, UChar m4 __attribute__((unused)),
8301 UChar r1, UChar r2)
8302{
8303 IRTemp op2 = newTemp(Ity_I64);
8304
8305 assign(op2, get_gpr_dw0(r2));
8306 put_fpr_w0(r1, binop(Iop_I64UtoF32, mkU32(encode_rounding_mode(m3)),
8307 mkexpr(op2)));
8308
8309 return "celgbr";
8310}
8311
8312static HChar *
8313s390_irgen_CDLGBR(UChar m3, UChar m4 __attribute__((unused)),
8314 UChar r1, UChar r2)
8315{
8316 IRTemp op2 = newTemp(Ity_I64);
8317
8318 assign(op2, get_gpr_dw0(r2));
8319 put_fpr_dw0(r1, binop(Iop_I64UtoF64, mkU32(encode_rounding_mode(m3)),
8320 mkexpr(op2)));
8321
8322 return "cdlgbr";
8323}
8324
8325static HChar *
8326s390_irgen_CLFEBR(UChar m3, UChar m4 __attribute__((unused)),
8327 UChar r1, UChar r2)
8328{
8329 IRTemp op = newTemp(Ity_F32);
8330 IRTemp result = newTemp(Ity_I32);
8331
8332 assign(op, get_fpr_w0(r2));
8333 assign(result, binop(Iop_F32toI32U, mkU32(encode_rounding_mode(m3)),
8334 mkexpr(op)));
8335 put_gpr_w1(r1, mkexpr(result));
8336 s390_cc_thunk_putF(S390_CC_OP_BFP_32_TO_UINT_32, op);
8337
8338 return "clfebr";
8339}
8340
8341static HChar *
8342s390_irgen_CLFDBR(UChar m3, UChar m4 __attribute__((unused)),
8343 UChar r1, UChar r2)
8344{
8345 IRTemp op = newTemp(Ity_F64);
8346 IRTemp result = newTemp(Ity_I32);
8347
8348 assign(op, get_fpr_dw0(r2));
8349 assign(result, binop(Iop_F64toI32U, mkU32(encode_rounding_mode(m3)),
8350 mkexpr(op)));
8351 put_gpr_w1(r1, mkexpr(result));
8352 s390_cc_thunk_putF(S390_CC_OP_BFP_64_TO_UINT_32, op);
8353
8354 return "clfdbr";
8355}
8356
8357static HChar *
8358s390_irgen_CLGEBR(UChar m3, UChar m4 __attribute__((unused)),
8359 UChar r1, UChar r2)
8360{
8361 IRTemp op = newTemp(Ity_F32);
8362 IRTemp result = newTemp(Ity_I64);
8363
8364 assign(op, get_fpr_w0(r2));
8365 assign(result, binop(Iop_F32toI64U, mkU32(encode_rounding_mode(m3)),
8366 mkexpr(op)));
8367 put_gpr_dw0(r1, mkexpr(result));
8368 s390_cc_thunk_putF(S390_CC_OP_BFP_32_TO_UINT_64, op);
8369
8370 return "clgebr";
8371}
8372
8373static HChar *
8374s390_irgen_CLGDBR(UChar m3, UChar m4 __attribute__((unused)),
8375 UChar r1, UChar r2)
8376{
8377 IRTemp op = newTemp(Ity_F64);
8378 IRTemp result = newTemp(Ity_I64);
8379
8380 assign(op, get_fpr_dw0(r2));
8381 assign(result, binop(Iop_F64toI64U, mkU32(encode_rounding_mode(m3)),
8382 mkexpr(op)));
8383 put_gpr_dw0(r1, mkexpr(result));
8384 s390_cc_thunk_putF(S390_CC_OP_BFP_64_TO_UINT_64, op);
8385
8386 return "clgdbr";
8387}
8388
8389static HChar *
sewardj2019a972011-03-07 16:04:07 +00008390s390_irgen_CFEBR(UChar r3, UChar r1, UChar r2)
8391{
8392 IRTemp op = newTemp(Ity_F32);
8393 IRTemp result = newTemp(Ity_I32);
8394
8395 assign(op, get_fpr_w0(r2));
8396 assign(result, binop(Iop_F32toI32S, mkU32(encode_rounding_mode(r3)),
8397 mkexpr(op)));
8398 put_gpr_w1(r1, mkexpr(result));
8399 s390_cc_thunk_putF(S390_CC_OP_BFP_32_TO_INT_32, op);
8400
8401 return "cfebr";
8402}
8403
8404static HChar *
8405s390_irgen_CFDBR(UChar r3, UChar r1, UChar r2)
8406{
8407 IRTemp op = newTemp(Ity_F64);
8408 IRTemp result = newTemp(Ity_I32);
8409
8410 assign(op, get_fpr_dw0(r2));
8411 assign(result, binop(Iop_F64toI32S, mkU32(encode_rounding_mode(r3)),
8412 mkexpr(op)));
8413 put_gpr_w1(r1, mkexpr(result));
8414 s390_cc_thunk_putF(S390_CC_OP_BFP_64_TO_INT_32, op);
8415
8416 return "cfdbr";
8417}
8418
8419static HChar *
8420s390_irgen_CGEBR(UChar r3, UChar r1, UChar r2)
8421{
8422 IRTemp op = newTemp(Ity_F32);
8423 IRTemp result = newTemp(Ity_I64);
8424
8425 assign(op, get_fpr_w0(r2));
8426 assign(result, binop(Iop_F32toI64S, mkU32(encode_rounding_mode(r3)),
8427 mkexpr(op)));
8428 put_gpr_dw0(r1, mkexpr(result));
8429 s390_cc_thunk_putF(S390_CC_OP_BFP_32_TO_INT_64, op);
8430
8431 return "cgebr";
8432}
8433
8434static HChar *
8435s390_irgen_CGDBR(UChar r3, UChar r1, UChar r2)
8436{
8437 IRTemp op = newTemp(Ity_F64);
8438 IRTemp result = newTemp(Ity_I64);
8439
8440 assign(op, get_fpr_dw0(r2));
8441 assign(result, binop(Iop_F64toI64S, mkU32(encode_rounding_mode(r3)),
8442 mkexpr(op)));
8443 put_gpr_dw0(r1, mkexpr(result));
8444 s390_cc_thunk_putF(S390_CC_OP_BFP_64_TO_INT_64, op);
8445
8446 return "cgdbr";
8447}
8448
8449static HChar *
8450s390_irgen_DEBR(UChar r1, UChar r2)
8451{
8452 IRTemp op1 = newTemp(Ity_F32);
8453 IRTemp op2 = newTemp(Ity_F32);
8454 IRTemp result = newTemp(Ity_F32);
8455
8456 assign(op1, get_fpr_w0(r1));
8457 assign(op2, get_fpr_w0(r2));
8458 assign(result, triop(Iop_DivF32, mkU32(Irrm_NEAREST), mkexpr(op1),
8459 mkexpr(op2)));
8460 put_fpr_w0(r1, mkexpr(result));
8461
8462 return "debr";
8463}
8464
8465static HChar *
8466s390_irgen_DDBR(UChar r1, UChar r2)
8467{
8468 IRTemp op1 = newTemp(Ity_F64);
8469 IRTemp op2 = newTemp(Ity_F64);
8470 IRTemp result = newTemp(Ity_F64);
8471
8472 assign(op1, get_fpr_dw0(r1));
8473 assign(op2, get_fpr_dw0(r2));
8474 assign(result, triop(Iop_DivF64, mkU32(Irrm_NEAREST), mkexpr(op1),
8475 mkexpr(op2)));
8476 put_fpr_dw0(r1, mkexpr(result));
8477
8478 return "ddbr";
8479}
8480
8481static HChar *
8482s390_irgen_DEB(UChar r1, IRTemp op2addr)
8483{
8484 IRTemp op1 = newTemp(Ity_F32);
8485 IRTemp op2 = newTemp(Ity_F32);
8486 IRTemp result = newTemp(Ity_F32);
8487
8488 assign(op1, get_fpr_w0(r1));
8489 assign(op2, load(Ity_F32, mkexpr(op2addr)));
8490 assign(result, triop(Iop_DivF32, mkU32(Irrm_NEAREST), mkexpr(op1),
8491 mkexpr(op2)));
8492 put_fpr_w0(r1, mkexpr(result));
8493
8494 return "deb";
8495}
8496
8497static HChar *
8498s390_irgen_DDB(UChar r1, IRTemp op2addr)
8499{
8500 IRTemp op1 = newTemp(Ity_F64);
8501 IRTemp op2 = newTemp(Ity_F64);
8502 IRTemp result = newTemp(Ity_F64);
8503
8504 assign(op1, get_fpr_dw0(r1));
8505 assign(op2, load(Ity_F64, mkexpr(op2addr)));
8506 assign(result, triop(Iop_DivF64, mkU32(Irrm_NEAREST), mkexpr(op1),
8507 mkexpr(op2)));
8508 put_fpr_dw0(r1, mkexpr(result));
8509
8510 return "ddb";
8511}
8512
8513static HChar *
8514s390_irgen_LTEBR(UChar r1, UChar r2)
8515{
8516 IRTemp result = newTemp(Ity_F32);
8517
8518 assign(result, get_fpr_w0(r2));
8519 put_fpr_w0(r1, mkexpr(result));
8520 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8521
8522 return "ltebr";
8523}
8524
8525static HChar *
8526s390_irgen_LTDBR(UChar r1, UChar r2)
8527{
8528 IRTemp result = newTemp(Ity_F64);
8529
8530 assign(result, get_fpr_dw0(r2));
8531 put_fpr_dw0(r1, mkexpr(result));
8532 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8533
8534 return "ltdbr";
8535}
8536
8537static HChar *
8538s390_irgen_LCEBR(UChar r1, UChar r2)
8539{
8540 IRTemp result = newTemp(Ity_F32);
8541
8542 assign(result, unop(Iop_NegF32, get_fpr_w0(r2)));
8543 put_fpr_w0(r1, mkexpr(result));
8544 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8545
8546 return "lcebr";
8547}
8548
8549static HChar *
8550s390_irgen_LCDBR(UChar r1, UChar r2)
8551{
8552 IRTemp result = newTemp(Ity_F64);
8553
8554 assign(result, unop(Iop_NegF64, get_fpr_dw0(r2)));
8555 put_fpr_dw0(r1, mkexpr(result));
8556 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8557
8558 return "lcdbr";
8559}
8560
8561static HChar *
8562s390_irgen_LDEBR(UChar r1, UChar r2)
8563{
8564 IRTemp op = newTemp(Ity_F32);
8565
8566 assign(op, get_fpr_w0(r2));
8567 put_fpr_dw0(r1, unop(Iop_F32toF64, mkexpr(op)));
8568
8569 return "ldebr";
8570}
8571
8572static HChar *
8573s390_irgen_LDEB(UChar r1, IRTemp op2addr)
8574{
8575 IRTemp op = newTemp(Ity_F32);
8576
8577 assign(op, load(Ity_F32, mkexpr(op2addr)));
8578 put_fpr_dw0(r1, unop(Iop_F32toF64, mkexpr(op)));
8579
8580 return "ldeb";
8581}
8582
8583static HChar *
8584s390_irgen_LEDBR(UChar r1, UChar r2)
8585{
8586 IRTemp op = newTemp(Ity_F64);
8587
8588 assign(op, get_fpr_dw0(r2));
8589 put_fpr_w0(r1, binop(Iop_F64toF32, mkU32(Irrm_NEAREST), mkexpr(op)));
8590
8591 return "ledbr";
8592}
8593
8594static HChar *
8595s390_irgen_MEEBR(UChar r1, UChar r2)
8596{
8597 IRTemp op1 = newTemp(Ity_F32);
8598 IRTemp op2 = newTemp(Ity_F32);
8599 IRTemp result = newTemp(Ity_F32);
8600
8601 assign(op1, get_fpr_w0(r1));
8602 assign(op2, get_fpr_w0(r2));
8603 assign(result, triop(Iop_MulF32, mkU32(Irrm_NEAREST), mkexpr(op1),
8604 mkexpr(op2)));
8605 put_fpr_w0(r1, mkexpr(result));
8606
8607 return "meebr";
8608}
8609
8610static HChar *
8611s390_irgen_MDBR(UChar r1, UChar r2)
8612{
8613 IRTemp op1 = newTemp(Ity_F64);
8614 IRTemp op2 = newTemp(Ity_F64);
8615 IRTemp result = newTemp(Ity_F64);
8616
8617 assign(op1, get_fpr_dw0(r1));
8618 assign(op2, get_fpr_dw0(r2));
8619 assign(result, triop(Iop_MulF64, mkU32(Irrm_NEAREST), mkexpr(op1),
8620 mkexpr(op2)));
8621 put_fpr_dw0(r1, mkexpr(result));
8622
8623 return "mdbr";
8624}
8625
8626static HChar *
8627s390_irgen_MEEB(UChar r1, IRTemp op2addr)
8628{
8629 IRTemp op1 = newTemp(Ity_F32);
8630 IRTemp op2 = newTemp(Ity_F32);
8631 IRTemp result = newTemp(Ity_F32);
8632
8633 assign(op1, get_fpr_w0(r1));
8634 assign(op2, load(Ity_F32, mkexpr(op2addr)));
8635 assign(result, triop(Iop_MulF32, mkU32(Irrm_NEAREST), mkexpr(op1),
8636 mkexpr(op2)));
8637 put_fpr_w0(r1, mkexpr(result));
8638
8639 return "meeb";
8640}
8641
8642static HChar *
8643s390_irgen_MDB(UChar r1, IRTemp op2addr)
8644{
8645 IRTemp op1 = newTemp(Ity_F64);
8646 IRTemp op2 = newTemp(Ity_F64);
8647 IRTemp result = newTemp(Ity_F64);
8648
8649 assign(op1, get_fpr_dw0(r1));
8650 assign(op2, load(Ity_F64, mkexpr(op2addr)));
8651 assign(result, triop(Iop_MulF64, mkU32(Irrm_NEAREST), mkexpr(op1),
8652 mkexpr(op2)));
8653 put_fpr_dw0(r1, mkexpr(result));
8654
8655 return "mdb";
8656}
8657
8658static HChar *
8659s390_irgen_SEBR(UChar r1, UChar r2)
8660{
8661 IRTemp op1 = newTemp(Ity_F32);
8662 IRTemp op2 = newTemp(Ity_F32);
8663 IRTemp result = newTemp(Ity_F32);
8664
8665 assign(op1, get_fpr_w0(r1));
8666 assign(op2, get_fpr_w0(r2));
8667 assign(result, triop(Iop_SubF32, mkU32(Irrm_NEAREST), mkexpr(op1),
8668 mkexpr(op2)));
8669 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8670 put_fpr_w0(r1, mkexpr(result));
8671
8672 return "sebr";
8673}
8674
8675static HChar *
8676s390_irgen_SDBR(UChar r1, UChar r2)
8677{
8678 IRTemp op1 = newTemp(Ity_F64);
8679 IRTemp op2 = newTemp(Ity_F64);
8680 IRTemp result = newTemp(Ity_F64);
8681
8682 assign(op1, get_fpr_dw0(r1));
8683 assign(op2, get_fpr_dw0(r2));
8684 assign(result, triop(Iop_SubF64, mkU32(Irrm_NEAREST), mkexpr(op1),
8685 mkexpr(op2)));
8686 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8687 put_fpr_dw0(r1, mkexpr(result));
8688
8689 return "sdbr";
8690}
8691
8692static HChar *
8693s390_irgen_SEB(UChar r1, IRTemp op2addr)
8694{
8695 IRTemp op1 = newTemp(Ity_F32);
8696 IRTemp op2 = newTemp(Ity_F32);
8697 IRTemp result = newTemp(Ity_F32);
8698
8699 assign(op1, get_fpr_w0(r1));
8700 assign(op2, load(Ity_F32, mkexpr(op2addr)));
8701 assign(result, triop(Iop_SubF32, mkU32(Irrm_NEAREST), mkexpr(op1),
8702 mkexpr(op2)));
8703 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8704 put_fpr_w0(r1, mkexpr(result));
8705
8706 return "seb";
8707}
8708
8709static HChar *
8710s390_irgen_SDB(UChar r1, IRTemp op2addr)
8711{
8712 IRTemp op1 = newTemp(Ity_F64);
8713 IRTemp op2 = newTemp(Ity_F64);
8714 IRTemp result = newTemp(Ity_F64);
8715
8716 assign(op1, get_fpr_dw0(r1));
8717 assign(op2, load(Ity_F64, mkexpr(op2addr)));
8718 assign(result, triop(Iop_SubF64, mkU32(Irrm_NEAREST), mkexpr(op1),
8719 mkexpr(op2)));
8720 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8721 put_fpr_dw0(r1, mkexpr(result));
8722
8723 return "sdb";
8724}
8725
8726
8727static HChar *
8728s390_irgen_CLC(UChar length, IRTemp start1, IRTemp start2)
8729{
florian79e839e2012-05-05 02:20:30 +00008730 IRTemp len = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00008731
florian79e839e2012-05-05 02:20:30 +00008732 assign(len, mkU64(length));
8733 s390_irgen_CLC_EX(len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +00008734
8735 return "clc";
8736}
8737
8738static HChar *
florianb0c9a132011-09-08 15:37:39 +00008739s390_irgen_CLCL(UChar r1, UChar r2)
8740{
8741 IRTemp addr1 = newTemp(Ity_I64);
8742 IRTemp addr2 = newTemp(Ity_I64);
8743 IRTemp addr1_load = newTemp(Ity_I64);
8744 IRTemp addr2_load = newTemp(Ity_I64);
8745 IRTemp len1 = newTemp(Ity_I32);
8746 IRTemp len2 = newTemp(Ity_I32);
8747 IRTemp r1p1 = newTemp(Ity_I32); /* contents of r1 + 1 */
8748 IRTemp r2p1 = newTemp(Ity_I32); /* contents of r2 + 1 */
8749 IRTemp single1 = newTemp(Ity_I8);
8750 IRTemp single2 = newTemp(Ity_I8);
8751 IRTemp pad = newTemp(Ity_I8);
8752
8753 assign(addr1, get_gpr_dw0(r1));
8754 assign(r1p1, get_gpr_w1(r1 + 1));
8755 assign(len1, binop(Iop_And32, mkexpr(r1p1), mkU32(0x00ffffff)));
8756 assign(addr2, get_gpr_dw0(r2));
8757 assign(r2p1, get_gpr_w1(r2 + 1));
8758 assign(len2, binop(Iop_And32, mkexpr(r2p1), mkU32(0x00ffffff)));
8759 assign(pad, get_gpr_b4(r2 + 1));
8760
8761 /* len1 == 0 and len2 == 0? Exit */
8762 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +00008763 next_insn_if(binop(Iop_CmpEQ32, binop(Iop_Or32, mkexpr(len1),
8764 mkexpr(len2)), mkU32(0)));
florianb0c9a132011-09-08 15:37:39 +00008765
8766 /* Because mkite evaluates both the then-clause and the else-clause
8767 we cannot load directly from addr1 here. If len1 is 0, then adddr1
8768 may be NULL and loading from there would segfault. So we provide a
8769 valid dummy address in that case. Loading from there does no harm and
8770 the value will be discarded at runtime. */
8771 assign(addr1_load,
8772 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
8773 mkU64(guest_IA_curr_instr), mkexpr(addr1)));
8774 assign(single1,
8775 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
8776 mkexpr(pad), load(Ity_I8, mkexpr(addr1_load))));
8777
8778 assign(addr2_load,
8779 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
8780 mkU64(guest_IA_curr_instr), mkexpr(addr2)));
8781 assign(single2,
8782 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
8783 mkexpr(pad), load(Ity_I8, mkexpr(addr2_load))));
8784
8785 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, single1, single2, False);
8786 /* Fields differ ? */
florian6820ba52012-07-26 02:01:50 +00008787 next_insn_if(binop(Iop_CmpNE8, mkexpr(single1), mkexpr(single2)));
florianb0c9a132011-09-08 15:37:39 +00008788
8789 /* Update len1 and addr1, unless len1 == 0. */
8790 put_gpr_dw0(r1,
8791 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
8792 mkexpr(addr1),
8793 binop(Iop_Add64, mkexpr(addr1), mkU64(1))));
8794
8795 /* When updating len1 we must not modify bits (r1+1)[0:39] */
8796 put_gpr_w1(r1 + 1,
8797 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
8798 binop(Iop_And32, mkexpr(r1p1), mkU32(0xFF000000u)),
8799 binop(Iop_Sub32, mkexpr(r1p1), mkU32(1))));
8800
8801 /* Update len2 and addr2, unless len2 == 0. */
8802 put_gpr_dw0(r2,
8803 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
8804 mkexpr(addr2),
8805 binop(Iop_Add64, mkexpr(addr2), mkU64(1))));
8806
8807 /* When updating len2 we must not modify bits (r2+1)[0:39] */
8808 put_gpr_w1(r2 + 1,
8809 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
8810 binop(Iop_And32, mkexpr(r2p1), mkU32(0xFF000000u)),
8811 binop(Iop_Sub32, mkexpr(r2p1), mkU32(1))));
8812
florian6820ba52012-07-26 02:01:50 +00008813 iterate();
florianb0c9a132011-09-08 15:37:39 +00008814
8815 return "clcl";
8816}
8817
8818static HChar *
sewardj2019a972011-03-07 16:04:07 +00008819s390_irgen_CLCLE(UChar r1, UChar r3, IRTemp pad2)
8820{
8821 IRTemp addr1, addr3, addr1_load, addr3_load, len1, len3, single1, single3;
8822
8823 addr1 = newTemp(Ity_I64);
8824 addr3 = newTemp(Ity_I64);
8825 addr1_load = newTemp(Ity_I64);
8826 addr3_load = newTemp(Ity_I64);
8827 len1 = newTemp(Ity_I64);
8828 len3 = newTemp(Ity_I64);
8829 single1 = newTemp(Ity_I8);
8830 single3 = newTemp(Ity_I8);
8831
8832 assign(addr1, get_gpr_dw0(r1));
8833 assign(len1, get_gpr_dw0(r1 + 1));
8834 assign(addr3, get_gpr_dw0(r3));
8835 assign(len3, get_gpr_dw0(r3 + 1));
8836
8837 /* len1 == 0 and len3 == 0? Exit */
8838 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +00008839 next_insn_if(binop(Iop_CmpEQ64,binop(Iop_Or64, mkexpr(len1),
8840 mkexpr(len3)), mkU64(0)));
sewardj2019a972011-03-07 16:04:07 +00008841
8842 /* A mux requires both ways to be possible. This is a way to prevent clcle
8843 from reading from addr1 if it should read from the pad. Since the pad
8844 has no address, just read from the instruction, we discard that anyway */
8845 assign(addr1_load,
florian6ad49522011-09-09 02:38:55 +00008846 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
8847 mkU64(guest_IA_curr_instr), mkexpr(addr1)));
sewardj2019a972011-03-07 16:04:07 +00008848
8849 /* same for addr3 */
8850 assign(addr3_load,
florian6ad49522011-09-09 02:38:55 +00008851 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
8852 mkU64(guest_IA_curr_instr), mkexpr(addr3)));
sewardj2019a972011-03-07 16:04:07 +00008853
8854 assign(single1,
florian6ad49522011-09-09 02:38:55 +00008855 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
8856 unop(Iop_64to8, mkexpr(pad2)),
8857 load(Ity_I8, mkexpr(addr1_load))));
sewardj2019a972011-03-07 16:04:07 +00008858
8859 assign(single3,
florian6ad49522011-09-09 02:38:55 +00008860 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
8861 unop(Iop_64to8, mkexpr(pad2)),
8862 load(Ity_I8, mkexpr(addr3_load))));
sewardj2019a972011-03-07 16:04:07 +00008863
8864 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, single1, single3, False);
8865 /* Both fields differ ? */
florian6820ba52012-07-26 02:01:50 +00008866 next_insn_if(binop(Iop_CmpNE8, mkexpr(single1), mkexpr(single3)));
sewardj2019a972011-03-07 16:04:07 +00008867
8868 /* If a length in 0 we must not change this length and the address */
8869 put_gpr_dw0(r1,
florian6ad49522011-09-09 02:38:55 +00008870 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
8871 mkexpr(addr1),
8872 binop(Iop_Add64, mkexpr(addr1), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +00008873
8874 put_gpr_dw0(r1 + 1,
florian6ad49522011-09-09 02:38:55 +00008875 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
8876 mkU64(0), binop(Iop_Sub64, mkexpr(len1), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +00008877
8878 put_gpr_dw0(r3,
florian6ad49522011-09-09 02:38:55 +00008879 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
8880 mkexpr(addr3),
8881 binop(Iop_Add64, mkexpr(addr3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +00008882
8883 put_gpr_dw0(r3 + 1,
florian6ad49522011-09-09 02:38:55 +00008884 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
8885 mkU64(0), binop(Iop_Sub64, mkexpr(len3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +00008886
florian6820ba52012-07-26 02:01:50 +00008887 iterate();
sewardj2019a972011-03-07 16:04:07 +00008888
8889 return "clcle";
8890}
floriana64c2432011-07-16 02:11:50 +00008891
florianb0bf6602012-05-05 00:01:16 +00008892
sewardj2019a972011-03-07 16:04:07 +00008893static void
8894s390_irgen_XC_EX(IRTemp length, IRTemp start1, IRTemp start2)
8895{
florianb0bf6602012-05-05 00:01:16 +00008896 s390_irgen_xonc(Iop_Xor8, length, start1, start2);
8897}
sewardj2019a972011-03-07 16:04:07 +00008898
sewardj2019a972011-03-07 16:04:07 +00008899
florianb0bf6602012-05-05 00:01:16 +00008900static void
8901s390_irgen_NC_EX(IRTemp length, IRTemp start1, IRTemp start2)
8902{
8903 s390_irgen_xonc(Iop_And8, length, start1, start2);
8904}
sewardj2019a972011-03-07 16:04:07 +00008905
sewardj2019a972011-03-07 16:04:07 +00008906
florianb0bf6602012-05-05 00:01:16 +00008907static void
8908s390_irgen_OC_EX(IRTemp length, IRTemp start1, IRTemp start2)
8909{
8910 s390_irgen_xonc(Iop_Or8, length, start1, start2);
sewardj2019a972011-03-07 16:04:07 +00008911}
8912
8913
8914static void
8915s390_irgen_CLC_EX(IRTemp length, IRTemp start1, IRTemp start2)
8916{
8917 IRTemp current1 = newTemp(Ity_I8);
8918 IRTemp current2 = newTemp(Ity_I8);
8919 IRTemp counter = newTemp(Ity_I64);
8920
8921 assign(counter, get_counter_dw0());
8922 put_counter_dw0(mkU64(0));
8923
8924 assign(current1, load(Ity_I8, binop(Iop_Add64, mkexpr(start1),
8925 mkexpr(counter))));
8926 assign(current2, load(Ity_I8, binop(Iop_Add64, mkexpr(start2),
8927 mkexpr(counter))));
8928 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, current1, current2,
8929 False);
8930
8931 /* Both fields differ ? */
florian6820ba52012-07-26 02:01:50 +00008932 next_insn_if(binop(Iop_CmpNE8, mkexpr(current1), mkexpr(current2)));
sewardj2019a972011-03-07 16:04:07 +00008933
8934 /* Check for end of field */
8935 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +00008936 iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
sewardj2019a972011-03-07 16:04:07 +00008937 put_counter_dw0(mkU64(0));
8938}
8939
8940static void
8941s390_irgen_MVC_EX(IRTemp length, IRTemp start1, IRTemp start2)
8942{
8943 IRTemp counter = newTemp(Ity_I64);
8944
8945 assign(counter, get_counter_dw0());
8946
8947 store(binop(Iop_Add64, mkexpr(start1), mkexpr(counter)),
8948 load(Ity_I8, binop(Iop_Add64, mkexpr(start2), mkexpr(counter))));
8949
8950 /* Check for end of field */
8951 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +00008952 iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
sewardj2019a972011-03-07 16:04:07 +00008953 put_counter_dw0(mkU64(0));
8954}
8955
florianf87d4fb2012-05-05 02:55:24 +00008956static void
8957s390_irgen_TR_EX(IRTemp length, IRTemp start1, IRTemp start2)
8958{
8959 IRTemp op = newTemp(Ity_I8);
8960 IRTemp op1 = newTemp(Ity_I8);
8961 IRTemp result = newTemp(Ity_I64);
8962 IRTemp counter = newTemp(Ity_I64);
8963
8964 assign(counter, get_counter_dw0());
8965
8966 assign(op, load(Ity_I8, binop(Iop_Add64, mkexpr(start1), mkexpr(counter))));
8967
8968 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)), mkexpr(start2)));
8969
8970 assign(op1, load(Ity_I8, mkexpr(result)));
8971 store(binop(Iop_Add64, mkexpr(start1), mkexpr(counter)), mkexpr(op1));
8972
8973 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +00008974 iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
florianf87d4fb2012-05-05 02:55:24 +00008975 put_counter_dw0(mkU64(0));
8976}
sewardj2019a972011-03-07 16:04:07 +00008977
8978
8979static void
8980s390_irgen_EX_SS(UChar r, IRTemp addr2,
florian6820ba52012-07-26 02:01:50 +00008981 void (*irgen)(IRTemp length, IRTemp start1, IRTemp start2),
8982 int lensize)
sewardj2019a972011-03-07 16:04:07 +00008983{
8984 struct SS {
8985 unsigned int op : 8;
8986 unsigned int l : 8;
8987 unsigned int b1 : 4;
8988 unsigned int d1 : 12;
8989 unsigned int b2 : 4;
8990 unsigned int d2 : 12;
8991 };
8992 union {
8993 struct SS dec;
8994 unsigned long bytes;
8995 } ss;
8996 IRTemp cond;
8997 IRDirty *d;
8998 IRTemp torun;
8999
9000 IRTemp start1 = newTemp(Ity_I64);
9001 IRTemp start2 = newTemp(Ity_I64);
9002 IRTemp len = newTemp(lensize == 64 ? Ity_I64 : Ity_I32);
9003 cond = newTemp(Ity_I1);
9004 torun = newTemp(Ity_I64);
9005
9006 assign(torun, load(Ity_I64, mkexpr(addr2)));
9007 /* Start with a check that the saved code is still correct */
9008 assign(cond, binop(Iop_CmpNE64, mkexpr(torun), mkU64(last_execute_target)));
9009 /* If not, save the new value */
9010 d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
9011 mkIRExprVec_1(mkexpr(torun)));
9012 d->guard = mkexpr(cond);
9013 stmt(IRStmt_Dirty(d));
9014
9015 /* and restart */
florian428dfdd2012-03-27 03:09:49 +00009016 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART),
9017 mkU64(guest_IA_curr_instr)));
9018 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN), mkU64(4)));
florian6820ba52012-07-26 02:01:50 +00009019 restart_if(mkexpr(cond));
sewardj2019a972011-03-07 16:04:07 +00009020
9021 ss.bytes = last_execute_target;
9022 assign(start1, binop(Iop_Add64, mkU64(ss.dec.d1),
9023 ss.dec.b1 != 0 ? get_gpr_dw0(ss.dec.b1) : mkU64(0)));
9024 assign(start2, binop(Iop_Add64, mkU64(ss.dec.d2),
9025 ss.dec.b2 != 0 ? get_gpr_dw0(ss.dec.b2) : mkU64(0)));
9026 assign(len, unop(lensize == 64 ? Iop_8Uto64 : Iop_8Uto32, binop(Iop_Or8,
9027 r != 0 ? get_gpr_b7(r): mkU8(0), mkU8(ss.dec.l))));
9028 irgen(len, start1, start2);
florian8844a632012-04-13 04:04:06 +00009029
sewardj2019a972011-03-07 16:04:07 +00009030 last_execute_target = 0;
9031}
9032
9033static HChar *
9034s390_irgen_EX(UChar r1, IRTemp addr2)
9035{
9036 switch(last_execute_target & 0xff00000000000000ULL) {
9037 case 0:
9038 {
9039 /* no code information yet */
9040 IRDirty *d;
9041
9042 /* so safe the code... */
9043 d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
9044 mkIRExprVec_1(load(Ity_I64, mkexpr(addr2))));
9045 stmt(IRStmt_Dirty(d));
9046 /* and restart */
florian428dfdd2012-03-27 03:09:49 +00009047 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART),
9048 mkU64(guest_IA_curr_instr)));
9049 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN), mkU64(4)));
florian6820ba52012-07-26 02:01:50 +00009050 restart_if(IRExpr_Const(IRConst_U1(True)));
9051
sewardj2019a972011-03-07 16:04:07 +00009052 /* we know that this will be invalidated */
florianf9e1ed72012-04-17 02:41:56 +00009053 put_IA(mkaddr_expr(guest_IA_next_instr));
sewardj2019a972011-03-07 16:04:07 +00009054 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +00009055 dis_res->jk_StopHere = Ijk_TInval;
sewardj2019a972011-03-07 16:04:07 +00009056 break;
9057 }
9058
9059 case 0xd200000000000000ULL:
9060 /* special case MVC */
9061 s390_irgen_EX_SS(r1, addr2, s390_irgen_MVC_EX, 64);
9062 return "mvc via ex";
9063
9064 case 0xd500000000000000ULL:
9065 /* special case CLC */
9066 s390_irgen_EX_SS(r1, addr2, s390_irgen_CLC_EX, 64);
9067 return "clc via ex";
9068
9069 case 0xd700000000000000ULL:
9070 /* special case XC */
9071 s390_irgen_EX_SS(r1, addr2, s390_irgen_XC_EX, 32);
9072 return "xc via ex";
9073
florianb0bf6602012-05-05 00:01:16 +00009074 case 0xd600000000000000ULL:
9075 /* special case OC */
9076 s390_irgen_EX_SS(r1, addr2, s390_irgen_OC_EX, 32);
9077 return "oc via ex";
9078
9079 case 0xd400000000000000ULL:
9080 /* special case NC */
9081 s390_irgen_EX_SS(r1, addr2, s390_irgen_NC_EX, 32);
9082 return "nc via ex";
sewardj2019a972011-03-07 16:04:07 +00009083
florianf87d4fb2012-05-05 02:55:24 +00009084 case 0xdc00000000000000ULL:
9085 /* special case TR */
9086 s390_irgen_EX_SS(r1, addr2, s390_irgen_TR_EX, 64);
9087 return "tr via ex";
9088
sewardj2019a972011-03-07 16:04:07 +00009089 default:
9090 {
9091 /* everything else will get a self checking prefix that also checks the
9092 register content */
9093 IRDirty *d;
9094 UChar *bytes;
9095 IRTemp cond;
9096 IRTemp orperand;
9097 IRTemp torun;
9098
9099 cond = newTemp(Ity_I1);
9100 orperand = newTemp(Ity_I64);
9101 torun = newTemp(Ity_I64);
9102
9103 if (r1 == 0)
9104 assign(orperand, mkU64(0));
9105 else
9106 assign(orperand, unop(Iop_8Uto64,get_gpr_b7(r1)));
9107 /* This code is going to be translated */
9108 assign(torun, binop(Iop_Or64, load(Ity_I64, mkexpr(addr2)),
9109 binop(Iop_Shl64, mkexpr(orperand), mkU8(48))));
9110
9111 /* Start with a check that saved code is still correct */
9112 assign(cond, binop(Iop_CmpNE64, mkexpr(torun),
9113 mkU64(last_execute_target)));
9114 /* If not, save the new value */
9115 d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
9116 mkIRExprVec_1(mkexpr(torun)));
9117 d->guard = mkexpr(cond);
9118 stmt(IRStmt_Dirty(d));
9119
9120 /* and restart */
florian428dfdd2012-03-27 03:09:49 +00009121 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART), mkU64(guest_IA_curr_instr)));
9122 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN), mkU64(4)));
florian6820ba52012-07-26 02:01:50 +00009123 restart_if(mkexpr(cond));
sewardj2019a972011-03-07 16:04:07 +00009124
9125 /* Now comes the actual translation */
9126 bytes = (UChar *) &last_execute_target;
9127 s390_decode_and_irgen(bytes, ((((bytes[0] >> 6) + 1) >> 1) + 1) << 1,
9128 dis_res);
sewardj7ee97522011-05-09 21:45:04 +00009129 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00009130 vex_printf(" which was executed by\n");
9131 /* dont make useless translations in the next execute */
9132 last_execute_target = 0;
9133 }
9134 }
9135 return "ex";
9136}
9137
9138static HChar *
9139s390_irgen_EXRL(UChar r1, UInt offset)
9140{
9141 IRTemp addr = newTemp(Ity_I64);
9142 /* we might save one round trip because we know the target */
9143 if (!last_execute_target)
9144 last_execute_target = *(ULong *)(HWord)
9145 (guest_IA_curr_instr + offset * 2UL);
9146 assign(addr, mkU64(guest_IA_curr_instr + offset * 2UL));
9147 s390_irgen_EX(r1, addr);
9148 return "exrl";
9149}
9150
9151static HChar *
9152s390_irgen_IPM(UChar r1)
9153{
9154 // As long as we dont support SPM, lets just assume 0 as program mask
9155 put_gpr_b4(r1, unop(Iop_32to8, binop(Iop_Or32, mkU32(0 /* program mask */),
9156 binop(Iop_Shl32, s390_call_calculate_cc(), mkU8(4)))));
9157
9158 return "ipm";
9159}
9160
9161
9162static HChar *
9163s390_irgen_SRST(UChar r1, UChar r2)
9164{
9165 IRTemp address = newTemp(Ity_I64);
9166 IRTemp next = newTemp(Ity_I64);
9167 IRTemp delim = newTemp(Ity_I8);
9168 IRTemp counter = newTemp(Ity_I64);
9169 IRTemp byte = newTemp(Ity_I8);
9170
9171 assign(address, get_gpr_dw0(r2));
9172 assign(next, get_gpr_dw0(r1));
9173
9174 assign(counter, get_counter_dw0());
9175 put_counter_dw0(mkU64(0));
9176
9177 // start = next? CC=2 and out r1 and r2 unchanged
9178 s390_cc_set(2);
9179 put_gpr_dw0(r2, binop(Iop_Sub64, mkexpr(address), mkexpr(counter)));
florian6820ba52012-07-26 02:01:50 +00009180 next_insn_if(binop(Iop_CmpEQ64, mkexpr(address), mkexpr(next)));
sewardj2019a972011-03-07 16:04:07 +00009181
9182 assign(byte, load(Ity_I8, mkexpr(address)));
9183 assign(delim, get_gpr_b7(0));
9184
9185 // byte = delim? CC=1, R1=address
9186 s390_cc_set(1);
9187 put_gpr_dw0(r1, mkexpr(address));
florian6820ba52012-07-26 02:01:50 +00009188 next_insn_if(binop(Iop_CmpEQ8, mkexpr(delim), mkexpr(byte)));
sewardj2019a972011-03-07 16:04:07 +00009189
9190 // else: all equal, no end yet, loop
9191 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
9192 put_gpr_dw0(r1, mkexpr(next));
9193 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(address), mkU64(1)));
floriancf87c942012-07-25 00:52:21 +00009194
florian6820ba52012-07-26 02:01:50 +00009195 iterate();
sewardj2019a972011-03-07 16:04:07 +00009196
9197 return "srst";
9198}
9199
9200static HChar *
9201s390_irgen_CLST(UChar r1, UChar r2)
9202{
9203 IRTemp address1 = newTemp(Ity_I64);
9204 IRTemp address2 = newTemp(Ity_I64);
9205 IRTemp end = newTemp(Ity_I8);
9206 IRTemp counter = newTemp(Ity_I64);
9207 IRTemp byte1 = newTemp(Ity_I8);
9208 IRTemp byte2 = newTemp(Ity_I8);
9209
9210 assign(address1, get_gpr_dw0(r1));
9211 assign(address2, get_gpr_dw0(r2));
9212 assign(end, get_gpr_b7(0));
9213 assign(counter, get_counter_dw0());
9214 put_counter_dw0(mkU64(0));
9215 assign(byte1, load(Ity_I8, mkexpr(address1)));
9216 assign(byte2, load(Ity_I8, mkexpr(address2)));
9217
9218 // end in both? all equal, reset r1 and r2 to start values
9219 s390_cc_set(0);
9220 put_gpr_dw0(r1, binop(Iop_Sub64, mkexpr(address1), mkexpr(counter)));
9221 put_gpr_dw0(r2, binop(Iop_Sub64, mkexpr(address2), mkexpr(counter)));
florian6820ba52012-07-26 02:01:50 +00009222 next_insn_if(binop(Iop_CmpEQ8, mkU8(0),
9223 binop(Iop_Or8,
9224 binop(Iop_Xor8, mkexpr(byte1), mkexpr(end)),
9225 binop(Iop_Xor8, mkexpr(byte2), mkexpr(end)))));
sewardj2019a972011-03-07 16:04:07 +00009226
9227 put_gpr_dw0(r1, mkexpr(address1));
9228 put_gpr_dw0(r2, mkexpr(address2));
9229
9230 // End found in string1
9231 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +00009232 next_insn_if(binop(Iop_CmpEQ8, mkexpr(end), mkexpr(byte1)));
sewardj2019a972011-03-07 16:04:07 +00009233
9234 // End found in string2
9235 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +00009236 next_insn_if(binop(Iop_CmpEQ8, mkexpr(end), mkexpr(byte2)));
sewardj2019a972011-03-07 16:04:07 +00009237
9238 // string1 < string2
9239 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +00009240 next_insn_if(binop(Iop_CmpLT32U, unop(Iop_8Uto32, mkexpr(byte1)),
9241 unop(Iop_8Uto32, mkexpr(byte2))));
sewardj2019a972011-03-07 16:04:07 +00009242
9243 // string2 < string1
9244 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +00009245 next_insn_if(binop(Iop_CmpLT32U, unop(Iop_8Uto32, mkexpr(byte2)),
9246 unop(Iop_8Uto32, mkexpr(byte1))));
sewardj2019a972011-03-07 16:04:07 +00009247
9248 // else: all equal, no end yet, loop
9249 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
9250 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), mkU64(1)));
9251 put_gpr_dw0(r2, binop(Iop_Add64, get_gpr_dw0(r2), mkU64(1)));
floriancf87c942012-07-25 00:52:21 +00009252
florian6820ba52012-07-26 02:01:50 +00009253 iterate();
sewardj2019a972011-03-07 16:04:07 +00009254
9255 return "clst";
9256}
9257
9258static void
9259s390_irgen_load_multiple_32bit(UChar r1, UChar r3, IRTemp op2addr)
9260{
9261 UChar reg;
9262 IRTemp addr = newTemp(Ity_I64);
9263
9264 assign(addr, mkexpr(op2addr));
9265 reg = r1;
9266 do {
9267 IRTemp old = addr;
9268
9269 reg %= 16;
9270 put_gpr_w1(reg, load(Ity_I32, mkexpr(addr)));
9271 addr = newTemp(Ity_I64);
9272 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
9273 reg++;
9274 } while (reg != (r3 + 1));
9275}
9276
9277static HChar *
9278s390_irgen_LM(UChar r1, UChar r3, IRTemp op2addr)
9279{
9280 s390_irgen_load_multiple_32bit(r1, r3, op2addr);
9281
9282 return "lm";
9283}
9284
9285static HChar *
9286s390_irgen_LMY(UChar r1, UChar r3, IRTemp op2addr)
9287{
9288 s390_irgen_load_multiple_32bit(r1, r3, op2addr);
9289
9290 return "lmy";
9291}
9292
9293static HChar *
9294s390_irgen_LMH(UChar r1, UChar r3, IRTemp op2addr)
9295{
9296 UChar reg;
9297 IRTemp addr = newTemp(Ity_I64);
9298
9299 assign(addr, mkexpr(op2addr));
9300 reg = r1;
9301 do {
9302 IRTemp old = addr;
9303
9304 reg %= 16;
9305 put_gpr_w0(reg, load(Ity_I32, mkexpr(addr)));
9306 addr = newTemp(Ity_I64);
9307 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
9308 reg++;
9309 } while (reg != (r3 + 1));
9310
9311 return "lmh";
9312}
9313
9314static HChar *
9315s390_irgen_LMG(UChar r1, UChar r3, IRTemp op2addr)
9316{
9317 UChar reg;
9318 IRTemp addr = newTemp(Ity_I64);
9319
9320 assign(addr, mkexpr(op2addr));
9321 reg = r1;
9322 do {
9323 IRTemp old = addr;
9324
9325 reg %= 16;
9326 put_gpr_dw0(reg, load(Ity_I64, mkexpr(addr)));
9327 addr = newTemp(Ity_I64);
9328 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(8)));
9329 reg++;
9330 } while (reg != (r3 + 1));
9331
9332 return "lmg";
9333}
9334
9335static void
9336s390_irgen_store_multiple_32bit(UChar r1, UChar r3, IRTemp op2addr)
9337{
9338 UChar reg;
9339 IRTemp addr = newTemp(Ity_I64);
9340
9341 assign(addr, mkexpr(op2addr));
9342 reg = r1;
9343 do {
9344 IRTemp old = addr;
9345
9346 reg %= 16;
9347 store(mkexpr(addr), get_gpr_w1(reg));
9348 addr = newTemp(Ity_I64);
9349 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
9350 reg++;
9351 } while( reg != (r3 + 1));
9352}
9353
9354static HChar *
9355s390_irgen_STM(UChar r1, UChar r3, IRTemp op2addr)
9356{
9357 s390_irgen_store_multiple_32bit(r1, r3, op2addr);
9358
9359 return "stm";
9360}
9361
9362static HChar *
9363s390_irgen_STMY(UChar r1, UChar r3, IRTemp op2addr)
9364{
9365 s390_irgen_store_multiple_32bit(r1, r3, op2addr);
9366
9367 return "stmy";
9368}
9369
9370static HChar *
9371s390_irgen_STMH(UChar r1, UChar r3, IRTemp op2addr)
9372{
9373 UChar reg;
9374 IRTemp addr = newTemp(Ity_I64);
9375
9376 assign(addr, mkexpr(op2addr));
9377 reg = r1;
9378 do {
9379 IRTemp old = addr;
9380
9381 reg %= 16;
9382 store(mkexpr(addr), get_gpr_w0(reg));
9383 addr = newTemp(Ity_I64);
9384 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
9385 reg++;
9386 } while( reg != (r3 + 1));
9387
9388 return "stmh";
9389}
9390
9391static HChar *
9392s390_irgen_STMG(UChar r1, UChar r3, IRTemp op2addr)
9393{
9394 UChar reg;
9395 IRTemp addr = newTemp(Ity_I64);
9396
9397 assign(addr, mkexpr(op2addr));
9398 reg = r1;
9399 do {
9400 IRTemp old = addr;
9401
9402 reg %= 16;
9403 store(mkexpr(addr), get_gpr_dw0(reg));
9404 addr = newTemp(Ity_I64);
9405 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(8)));
9406 reg++;
9407 } while( reg != (r3 + 1));
9408
9409 return "stmg";
9410}
9411
9412static void
florianb0bf6602012-05-05 00:01:16 +00009413s390_irgen_xonc(IROp op, IRTemp length, IRTemp start1, IRTemp start2)
sewardj2019a972011-03-07 16:04:07 +00009414{
9415 IRTemp old1 = newTemp(Ity_I8);
9416 IRTemp old2 = newTemp(Ity_I8);
9417 IRTemp new1 = newTemp(Ity_I8);
9418 IRTemp counter = newTemp(Ity_I32);
9419 IRTemp addr1 = newTemp(Ity_I64);
9420
9421 assign(counter, get_counter_w0());
9422
9423 assign(addr1, binop(Iop_Add64, mkexpr(start1),
9424 unop(Iop_32Uto64, mkexpr(counter))));
9425
9426 assign(old1, load(Ity_I8, mkexpr(addr1)));
9427 assign(old2, load(Ity_I8, binop(Iop_Add64, mkexpr(start2),
9428 unop(Iop_32Uto64,mkexpr(counter)))));
9429 assign(new1, binop(op, mkexpr(old1), mkexpr(old2)));
9430
9431 /* Special case: xc is used to zero memory */
sewardj2019a972011-03-07 16:04:07 +00009432 if (op == Iop_Xor8) {
9433 store(mkexpr(addr1),
florian6ad49522011-09-09 02:38:55 +00009434 mkite(binop(Iop_CmpEQ64, mkexpr(start1), mkexpr(start2)),
9435 mkU8(0), mkexpr(new1)));
sewardj2019a972011-03-07 16:04:07 +00009436 } else
9437 store(mkexpr(addr1), mkexpr(new1));
9438 put_counter_w1(binop(Iop_Or32, unop(Iop_8Uto32, mkexpr(new1)),
9439 get_counter_w1()));
9440
9441 /* Check for end of field */
9442 put_counter_w0(binop(Iop_Add32, mkexpr(counter), mkU32(1)));
florian6820ba52012-07-26 02:01:50 +00009443 iterate_if(binop(Iop_CmpNE32, mkexpr(counter), mkexpr(length)));
sewardj2019a972011-03-07 16:04:07 +00009444 s390_cc_thunk_put1(S390_CC_OP_BITWISE, mktemp(Ity_I32, get_counter_w1()),
9445 False);
9446 put_counter_dw0(mkU64(0));
9447}
9448
9449static HChar *
9450s390_irgen_XC(UChar length, IRTemp start1, IRTemp start2)
9451{
florianb0bf6602012-05-05 00:01:16 +00009452 IRTemp len = newTemp(Ity_I32);
9453
9454 assign(len, mkU32(length));
9455 s390_irgen_xonc(Iop_Xor8, len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +00009456
9457 return "xc";
9458}
9459
sewardjb63967e2011-03-24 08:50:04 +00009460static void
9461s390_irgen_XC_sameloc(UChar length, UChar b, UShort d)
9462{
9463 IRTemp counter = newTemp(Ity_I32);
9464 IRTemp start = newTemp(Ity_I64);
9465 IRTemp addr = newTemp(Ity_I64);
9466
9467 assign(start,
9468 binop(Iop_Add64, mkU64(d), b != 0 ? get_gpr_dw0(b) : mkU64(0)));
9469
9470 if (length < 8) {
9471 UInt i;
9472
9473 for (i = 0; i <= length; ++i) {
9474 store(binop(Iop_Add64, mkexpr(start), mkU64(i)), mkU8(0));
9475 }
9476 } else {
9477 assign(counter, get_counter_w0());
9478
9479 assign(addr, binop(Iop_Add64, mkexpr(start),
9480 unop(Iop_32Uto64, mkexpr(counter))));
9481
9482 store(mkexpr(addr), mkU8(0));
9483
9484 /* Check for end of field */
9485 put_counter_w0(binop(Iop_Add32, mkexpr(counter), mkU32(1)));
florian6820ba52012-07-26 02:01:50 +00009486 iterate_if(binop(Iop_CmpNE32, mkexpr(counter), mkU32(length)));
sewardjb63967e2011-03-24 08:50:04 +00009487
9488 /* Reset counter */
9489 put_counter_dw0(mkU64(0));
9490 }
9491
9492 s390_cc_thunk_put1(S390_CC_OP_BITWISE, mktemp(Ity_I32, mkU32(0)), False);
9493
sewardj7ee97522011-05-09 21:45:04 +00009494 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardjb63967e2011-03-24 08:50:04 +00009495 s390_disasm(ENC3(MNM, UDLB, UDXB), "xc", d, length, b, d, 0, b);
9496}
9497
sewardj2019a972011-03-07 16:04:07 +00009498static HChar *
9499s390_irgen_NC(UChar length, IRTemp start1, IRTemp start2)
9500{
florianb0bf6602012-05-05 00:01:16 +00009501 IRTemp len = newTemp(Ity_I32);
9502
9503 assign(len, mkU32(length));
9504 s390_irgen_xonc(Iop_And8, len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +00009505
9506 return "nc";
9507}
9508
9509static HChar *
9510s390_irgen_OC(UChar length, IRTemp start1, IRTemp start2)
9511{
florianb0bf6602012-05-05 00:01:16 +00009512 IRTemp len = newTemp(Ity_I32);
9513
9514 assign(len, mkU32(length));
9515 s390_irgen_xonc(Iop_Or8, len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +00009516
9517 return "oc";
9518}
9519
9520
9521static HChar *
9522s390_irgen_MVC(UChar length, IRTemp start1, IRTemp start2)
9523{
florian79e839e2012-05-05 02:20:30 +00009524 IRTemp len = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00009525
florian79e839e2012-05-05 02:20:30 +00009526 assign(len, mkU64(length));
9527 s390_irgen_MVC_EX(len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +00009528
9529 return "mvc";
9530}
9531
9532static HChar *
florianb0c9a132011-09-08 15:37:39 +00009533s390_irgen_MVCL(UChar r1, UChar r2)
9534{
9535 IRTemp addr1 = newTemp(Ity_I64);
9536 IRTemp addr2 = newTemp(Ity_I64);
9537 IRTemp addr2_load = newTemp(Ity_I64);
9538 IRTemp r1p1 = newTemp(Ity_I32); /* contents of r1 + 1 */
9539 IRTemp r2p1 = newTemp(Ity_I32); /* contents of r2 + 1 */
9540 IRTemp len1 = newTemp(Ity_I32);
9541 IRTemp len2 = newTemp(Ity_I32);
9542 IRTemp pad = newTemp(Ity_I8);
9543 IRTemp single = newTemp(Ity_I8);
9544
9545 assign(addr1, get_gpr_dw0(r1));
9546 assign(r1p1, get_gpr_w1(r1 + 1));
9547 assign(len1, binop(Iop_And32, mkexpr(r1p1), mkU32(0x00ffffff)));
9548 assign(addr2, get_gpr_dw0(r2));
9549 assign(r2p1, get_gpr_w1(r2 + 1));
9550 assign(len2, binop(Iop_And32, mkexpr(r2p1), mkU32(0x00ffffff)));
9551 assign(pad, get_gpr_b4(r2 + 1));
9552
9553 /* len1 == 0 ? */
9554 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len2, False);
florian6820ba52012-07-26 02:01:50 +00009555 next_insn_if(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)));
florianb0c9a132011-09-08 15:37:39 +00009556
9557 /* Check for destructive overlap:
9558 addr1 > addr2 && addr2 + len1 > addr1 && (addr2 + len2) > addr1 */
9559 s390_cc_set(3);
9560 IRTemp cond1 = newTemp(Ity_I32);
9561 assign(cond1, unop(Iop_1Uto32,
9562 binop(Iop_CmpLT64U, mkexpr(addr2), mkexpr(addr1))));
9563 IRTemp cond2 = newTemp(Ity_I32);
9564 assign(cond2, unop(Iop_1Uto32,
9565 binop(Iop_CmpLT64U, mkexpr(addr1),
9566 binop(Iop_Add64, mkexpr(addr2),
9567 unop(Iop_32Uto64, mkexpr(len1))))));
9568 IRTemp cond3 = newTemp(Ity_I32);
9569 assign(cond3, unop(Iop_1Uto32,
9570 binop(Iop_CmpLT64U,
9571 mkexpr(addr1),
9572 binop(Iop_Add64, mkexpr(addr2),
9573 unop(Iop_32Uto64, mkexpr(len2))))));
9574
florian6820ba52012-07-26 02:01:50 +00009575 next_insn_if(binop(Iop_CmpEQ32,
9576 binop(Iop_And32,
9577 binop(Iop_And32, mkexpr(cond1), mkexpr(cond2)),
9578 mkexpr(cond3)),
9579 mkU32(1)));
florianb0c9a132011-09-08 15:37:39 +00009580
9581 /* See s390_irgen_CLCL for explanation why we cannot load directly
9582 and need two steps. */
9583 assign(addr2_load,
9584 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
9585 mkU64(guest_IA_curr_instr), mkexpr(addr2)));
9586 assign(single,
9587 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
9588 mkexpr(pad), load(Ity_I8, mkexpr(addr2_load))));
9589
9590 store(mkexpr(addr1), mkexpr(single));
9591
9592 /* Update addr1 and len1 */
9593 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(1)));
9594 put_gpr_w1(r1 + 1, binop(Iop_Sub32, mkexpr(r1p1), mkU32(1)));
9595
9596 /* Update addr2 and len2 */
9597 put_gpr_dw0(r2,
9598 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
9599 mkexpr(addr2),
9600 binop(Iop_Add64, mkexpr(addr2), mkU64(1))));
9601
9602 /* When updating len2 we must not modify bits (r2+1)[0:39] */
9603 put_gpr_w1(r2 + 1,
9604 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
9605 binop(Iop_And32, mkexpr(r2p1), mkU32(0xFF000000u)),
9606 binop(Iop_Sub32, mkexpr(r2p1), mkU32(1))));
9607
9608 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len2, False);
florian6820ba52012-07-26 02:01:50 +00009609 iterate_if(binop(Iop_CmpNE32, mkexpr(len1), mkU32(1)));
florianb0c9a132011-09-08 15:37:39 +00009610
9611 return "mvcl";
9612}
9613
9614
9615static HChar *
sewardj2019a972011-03-07 16:04:07 +00009616s390_irgen_MVCLE(UChar r1, UChar r3, IRTemp pad2)
9617{
9618 IRTemp addr1, addr3, addr3_load, len1, len3, single;
9619
9620 addr1 = newTemp(Ity_I64);
9621 addr3 = newTemp(Ity_I64);
9622 addr3_load = newTemp(Ity_I64);
9623 len1 = newTemp(Ity_I64);
9624 len3 = newTemp(Ity_I64);
9625 single = newTemp(Ity_I8);
9626
9627 assign(addr1, get_gpr_dw0(r1));
9628 assign(len1, get_gpr_dw0(r1 + 1));
9629 assign(addr3, get_gpr_dw0(r3));
9630 assign(len3, get_gpr_dw0(r3 + 1));
9631
9632 // len1 == 0 ?
9633 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len3, False);
florian6820ba52012-07-26 02:01:50 +00009634 next_insn_if(binop(Iop_CmpEQ64,mkexpr(len1), mkU64(0)));
sewardj2019a972011-03-07 16:04:07 +00009635
9636 /* This is a hack to prevent mvcle from reading from addr3 if it
9637 should read from the pad. Since the pad has no address, just
9638 read from the instruction, we discard that anyway */
9639 assign(addr3_load,
florian6ad49522011-09-09 02:38:55 +00009640 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
9641 mkU64(guest_IA_curr_instr), mkexpr(addr3)));
sewardj2019a972011-03-07 16:04:07 +00009642
9643 assign(single,
florian6ad49522011-09-09 02:38:55 +00009644 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
9645 unop(Iop_64to8, mkexpr(pad2)),
9646 load(Ity_I8, mkexpr(addr3_load))));
sewardj2019a972011-03-07 16:04:07 +00009647 store(mkexpr(addr1), mkexpr(single));
9648
9649 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(1)));
9650
9651 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkU64(1)));
9652
9653 put_gpr_dw0(r3,
florian6ad49522011-09-09 02:38:55 +00009654 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
9655 mkexpr(addr3),
9656 binop(Iop_Add64, mkexpr(addr3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +00009657
9658 put_gpr_dw0(r3 + 1,
florian6ad49522011-09-09 02:38:55 +00009659 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
9660 mkU64(0), binop(Iop_Sub64, mkexpr(len3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +00009661
sewardj2019a972011-03-07 16:04:07 +00009662 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len3, False);
florian6820ba52012-07-26 02:01:50 +00009663 iterate_if(binop(Iop_CmpNE64, mkexpr(len1), mkU64(1)));
sewardj2019a972011-03-07 16:04:07 +00009664
9665 return "mvcle";
9666}
9667
9668static HChar *
9669s390_irgen_MVST(UChar r1, UChar r2)
9670{
9671 IRTemp addr1 = newTemp(Ity_I64);
9672 IRTemp addr2 = newTemp(Ity_I64);
9673 IRTemp end = newTemp(Ity_I8);
9674 IRTemp byte = newTemp(Ity_I8);
9675 IRTemp counter = newTemp(Ity_I64);
9676
9677 assign(addr1, get_gpr_dw0(r1));
9678 assign(addr2, get_gpr_dw0(r2));
9679 assign(counter, get_counter_dw0());
9680 assign(end, get_gpr_b7(0));
9681 assign(byte, load(Ity_I8, binop(Iop_Add64, mkexpr(addr2),mkexpr(counter))));
9682 store(binop(Iop_Add64,mkexpr(addr1),mkexpr(counter)), mkexpr(byte));
9683
9684 // We use unlimited as cpu-determined number
9685 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +00009686 iterate_if(binop(Iop_CmpNE8, mkexpr(end), mkexpr(byte)));
sewardj2019a972011-03-07 16:04:07 +00009687
9688 // and always set cc=1 at the end + update r1
9689 s390_cc_set(1);
9690 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(counter)));
9691 put_counter_dw0(mkU64(0));
9692
9693 return "mvst";
9694}
9695
9696static void
9697s390_irgen_divide_64to32(IROp op, UChar r1, IRTemp op2)
9698{
9699 IRTemp op1 = newTemp(Ity_I64);
9700 IRTemp result = newTemp(Ity_I64);
9701
9702 assign(op1, binop(Iop_32HLto64,
9703 get_gpr_w1(r1), // high 32 bits
9704 get_gpr_w1(r1 + 1))); // low 32 bits
9705 assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
9706 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result))); // remainder
9707 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result))); // quotient
9708}
9709
9710static void
9711s390_irgen_divide_128to64(IROp op, UChar r1, IRTemp op2)
9712{
9713 IRTemp op1 = newTemp(Ity_I128);
9714 IRTemp result = newTemp(Ity_I128);
9715
9716 assign(op1, binop(Iop_64HLto128,
9717 get_gpr_dw0(r1), // high 64 bits
9718 get_gpr_dw0(r1 + 1))); // low 64 bits
9719 assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
9720 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result))); // remainder
9721 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result))); // quotient
9722}
9723
9724static void
9725s390_irgen_divide_64to64(IROp op, UChar r1, IRTemp op2)
9726{
9727 IRTemp op1 = newTemp(Ity_I64);
9728 IRTemp result = newTemp(Ity_I128);
9729
9730 assign(op1, get_gpr_dw0(r1 + 1));
9731 assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
9732 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result))); // remainder
9733 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result))); // quotient
9734}
9735
9736static HChar *
9737s390_irgen_DR(UChar r1, UChar r2)
9738{
9739 IRTemp op2 = newTemp(Ity_I32);
9740
9741 assign(op2, get_gpr_w1(r2));
9742
9743 s390_irgen_divide_64to32(Iop_DivModS64to32, r1, op2);
9744
9745 return "dr";
9746}
9747
9748static HChar *
9749s390_irgen_D(UChar r1, IRTemp op2addr)
9750{
9751 IRTemp op2 = newTemp(Ity_I32);
9752
9753 assign(op2, load(Ity_I32, mkexpr(op2addr)));
9754
9755 s390_irgen_divide_64to32(Iop_DivModS64to32, r1, op2);
9756
9757 return "d";
9758}
9759
9760static HChar *
9761s390_irgen_DLR(UChar r1, UChar r2)
9762{
9763 IRTemp op2 = newTemp(Ity_I32);
9764
9765 assign(op2, get_gpr_w1(r2));
9766
9767 s390_irgen_divide_64to32(Iop_DivModU64to32, r1, op2);
9768
florian7cd1cde2012-08-16 23:57:43 +00009769 return "dlr";
sewardj2019a972011-03-07 16:04:07 +00009770}
9771
9772static HChar *
9773s390_irgen_DL(UChar r1, IRTemp op2addr)
9774{
9775 IRTemp op2 = newTemp(Ity_I32);
9776
9777 assign(op2, load(Ity_I32, mkexpr(op2addr)));
9778
9779 s390_irgen_divide_64to32(Iop_DivModU64to32, r1, op2);
9780
9781 return "dl";
9782}
9783
9784static HChar *
9785s390_irgen_DLG(UChar r1, IRTemp op2addr)
9786{
9787 IRTemp op2 = newTemp(Ity_I64);
9788
9789 assign(op2, load(Ity_I64, mkexpr(op2addr)));
9790
9791 s390_irgen_divide_128to64(Iop_DivModU128to64, r1, op2);
9792
9793 return "dlg";
9794}
9795
9796static HChar *
9797s390_irgen_DLGR(UChar r1, UChar r2)
9798{
9799 IRTemp op2 = newTemp(Ity_I64);
9800
9801 assign(op2, get_gpr_dw0(r2));
9802
9803 s390_irgen_divide_128to64(Iop_DivModU128to64, r1, op2);
9804
9805 return "dlgr";
9806}
9807
9808static HChar *
9809s390_irgen_DSGR(UChar r1, UChar r2)
9810{
9811 IRTemp op2 = newTemp(Ity_I64);
9812
9813 assign(op2, get_gpr_dw0(r2));
9814
9815 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
9816
9817 return "dsgr";
9818}
9819
9820static HChar *
9821s390_irgen_DSG(UChar r1, IRTemp op2addr)
9822{
9823 IRTemp op2 = newTemp(Ity_I64);
9824
9825 assign(op2, load(Ity_I64, mkexpr(op2addr)));
9826
9827 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
9828
9829 return "dsg";
9830}
9831
9832static HChar *
9833s390_irgen_DSGFR(UChar r1, UChar r2)
9834{
9835 IRTemp op2 = newTemp(Ity_I64);
9836
9837 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
9838
9839 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
9840
9841 return "dsgfr";
9842}
9843
9844static HChar *
9845s390_irgen_DSGF(UChar r1, IRTemp op2addr)
9846{
9847 IRTemp op2 = newTemp(Ity_I64);
9848
9849 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
9850
9851 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
9852
9853 return "dsgf";
9854}
9855
9856static void
9857s390_irgen_load_ar_multiple(UChar r1, UChar r3, IRTemp op2addr)
9858{
9859 UChar reg;
9860 IRTemp addr = newTemp(Ity_I64);
9861
9862 assign(addr, mkexpr(op2addr));
9863 reg = r1;
9864 do {
9865 IRTemp old = addr;
9866
9867 reg %= 16;
9868 put_ar_w0(reg, load(Ity_I32, mkexpr(addr)));
9869 addr = newTemp(Ity_I64);
9870 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
9871 reg++;
9872 } while (reg != (r3 + 1));
9873}
9874
9875static HChar *
9876s390_irgen_LAM(UChar r1, UChar r3, IRTemp op2addr)
9877{
9878 s390_irgen_load_ar_multiple(r1, r3, op2addr);
9879
9880 return "lam";
9881}
9882
9883static HChar *
9884s390_irgen_LAMY(UChar r1, UChar r3, IRTemp op2addr)
9885{
9886 s390_irgen_load_ar_multiple(r1, r3, op2addr);
9887
9888 return "lamy";
9889}
9890
9891static void
9892s390_irgen_store_ar_multiple(UChar r1, UChar r3, IRTemp op2addr)
9893{
9894 UChar reg;
9895 IRTemp addr = newTemp(Ity_I64);
9896
9897 assign(addr, mkexpr(op2addr));
9898 reg = r1;
9899 do {
9900 IRTemp old = addr;
9901
9902 reg %= 16;
9903 store(mkexpr(addr), get_ar_w0(reg));
9904 addr = newTemp(Ity_I64);
9905 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
9906 reg++;
9907 } while (reg != (r3 + 1));
9908}
9909
9910static HChar *
9911s390_irgen_STAM(UChar r1, UChar r3, IRTemp op2addr)
9912{
9913 s390_irgen_store_ar_multiple(r1, r3, op2addr);
9914
9915 return "stam";
9916}
9917
9918static HChar *
9919s390_irgen_STAMY(UChar r1, UChar r3, IRTemp op2addr)
9920{
9921 s390_irgen_store_ar_multiple(r1, r3, op2addr);
9922
9923 return "stamy";
9924}
9925
9926
9927/* Implementation for 32-bit compare-and-swap */
9928static void
9929s390_irgen_cas_32(UChar r1, UChar r3, IRTemp op2addr)
9930{
9931 IRCAS *cas;
9932 IRTemp op1 = newTemp(Ity_I32);
9933 IRTemp old_mem = newTemp(Ity_I32);
9934 IRTemp op3 = newTemp(Ity_I32);
9935 IRTemp result = newTemp(Ity_I32);
9936 IRTemp nequal = newTemp(Ity_I1);
9937
9938 assign(op1, get_gpr_w1(r1));
9939 assign(op3, get_gpr_w1(r3));
9940
9941 /* The first and second operands are compared. If they are equal,
9942 the third operand is stored at the second- operand location. */
9943 cas = mkIRCAS(IRTemp_INVALID, old_mem,
9944 Iend_BE, mkexpr(op2addr),
9945 NULL, mkexpr(op1), /* expected value */
9946 NULL, mkexpr(op3) /* new value */);
9947 stmt(IRStmt_CAS(cas));
9948
9949 /* Set CC. Operands compared equal -> 0, else 1. */
9950 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(old_mem)));
9951 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
9952
9953 /* If operands were equal (cc == 0) just store the old value op1 in r1.
9954 Otherwise, store the old_value from memory in r1 and yield. */
9955 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
9956 put_gpr_w1(r1, mkite(mkexpr(nequal), mkexpr(old_mem), mkexpr(op1)));
florian6820ba52012-07-26 02:01:50 +00009957 yield_if(mkexpr(nequal));
sewardj2019a972011-03-07 16:04:07 +00009958}
9959
9960static HChar *
9961s390_irgen_CS(UChar r1, UChar r3, IRTemp op2addr)
9962{
9963 s390_irgen_cas_32(r1, r3, op2addr);
9964
9965 return "cs";
9966}
9967
9968static HChar *
9969s390_irgen_CSY(UChar r1, UChar r3, IRTemp op2addr)
9970{
9971 s390_irgen_cas_32(r1, r3, op2addr);
9972
9973 return "csy";
9974}
9975
9976static HChar *
9977s390_irgen_CSG(UChar r1, UChar r3, IRTemp op2addr)
9978{
9979 IRCAS *cas;
9980 IRTemp op1 = newTemp(Ity_I64);
9981 IRTemp old_mem = newTemp(Ity_I64);
9982 IRTemp op3 = newTemp(Ity_I64);
9983 IRTemp result = newTemp(Ity_I64);
9984 IRTemp nequal = newTemp(Ity_I1);
9985
9986 assign(op1, get_gpr_dw0(r1));
9987 assign(op3, get_gpr_dw0(r3));
9988
9989 /* The first and second operands are compared. If they are equal,
9990 the third operand is stored at the second- operand location. */
9991 cas = mkIRCAS(IRTemp_INVALID, old_mem,
9992 Iend_BE, mkexpr(op2addr),
9993 NULL, mkexpr(op1), /* expected value */
9994 NULL, mkexpr(op3) /* new value */);
9995 stmt(IRStmt_CAS(cas));
9996
9997 /* Set CC. Operands compared equal -> 0, else 1. */
9998 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(old_mem)));
9999 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
10000
10001 /* If operands were equal (cc == 0) just store the old value op1 in r1.
10002 Otherwise, store the old_value from memory in r1 and yield. */
10003 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
10004 put_gpr_dw0(r1, mkite(mkexpr(nequal), mkexpr(old_mem), mkexpr(op1)));
florian6820ba52012-07-26 02:01:50 +000010005 yield_if(mkexpr(nequal));
sewardj2019a972011-03-07 16:04:07 +000010006
10007 return "csg";
10008}
10009
florian448cbba2012-06-06 02:26:01 +000010010/* Implementation for 32-bit compare-double-and-swap */
10011static void
10012s390_irgen_cdas_32(UChar r1, UChar r3, IRTemp op2addr)
10013{
10014 IRCAS *cas;
10015 IRTemp op1_high = newTemp(Ity_I32);
10016 IRTemp op1_low = newTemp(Ity_I32);
10017 IRTemp old_mem_high = newTemp(Ity_I32);
10018 IRTemp old_mem_low = newTemp(Ity_I32);
10019 IRTemp op3_high = newTemp(Ity_I32);
10020 IRTemp op3_low = newTemp(Ity_I32);
10021 IRTemp result = newTemp(Ity_I32);
10022 IRTemp nequal = newTemp(Ity_I1);
10023
10024 assign(op1_high, get_gpr_w1(r1));
10025 assign(op1_low, get_gpr_w1(r1+1));
10026 assign(op3_high, get_gpr_w1(r3));
10027 assign(op3_low, get_gpr_w1(r3+1));
10028
10029 /* The first and second operands are compared. If they are equal,
10030 the third operand is stored at the second-operand location. */
10031 cas = mkIRCAS(old_mem_high, old_mem_low,
10032 Iend_BE, mkexpr(op2addr),
10033 mkexpr(op1_high), mkexpr(op1_low), /* expected value */
10034 mkexpr(op3_high), mkexpr(op3_low) /* new value */);
10035 stmt(IRStmt_CAS(cas));
10036
10037 /* Set CC. Operands compared equal -> 0, else 1. */
10038 assign(result, unop(Iop_1Uto32,
10039 binop(Iop_CmpNE32,
10040 binop(Iop_Or32,
10041 binop(Iop_Xor32, mkexpr(op1_high), mkexpr(old_mem_high)),
10042 binop(Iop_Xor32, mkexpr(op1_low), mkexpr(old_mem_low))),
10043 mkU32(0))));
10044
10045 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
10046
10047 /* If operands were equal (cc == 0) just store the old value op1 in r1.
10048 Otherwise, store the old_value from memory in r1 and yield. */
10049 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
10050 put_gpr_w1(r1, mkite(mkexpr(nequal), mkexpr(old_mem_high), mkexpr(op1_high)));
10051 put_gpr_w1(r1+1, mkite(mkexpr(nequal), mkexpr(old_mem_low), mkexpr(op1_low)));
florian6820ba52012-07-26 02:01:50 +000010052 yield_if(mkexpr(nequal));
florian448cbba2012-06-06 02:26:01 +000010053}
10054
10055static HChar *
10056s390_irgen_CDS(UChar r1, UChar r3, IRTemp op2addr)
10057{
10058 s390_irgen_cdas_32(r1, r3, op2addr);
10059
10060 return "cds";
10061}
10062
10063static HChar *
10064s390_irgen_CDSY(UChar r1, UChar r3, IRTemp op2addr)
10065{
10066 s390_irgen_cdas_32(r1, r3, op2addr);
10067
10068 return "cdsy";
10069}
10070
10071static HChar *
10072s390_irgen_CDSG(UChar r1, UChar r3, IRTemp op2addr)
10073{
10074 IRCAS *cas;
10075 IRTemp op1_high = newTemp(Ity_I64);
10076 IRTemp op1_low = newTemp(Ity_I64);
10077 IRTemp old_mem_high = newTemp(Ity_I64);
10078 IRTemp old_mem_low = newTemp(Ity_I64);
10079 IRTemp op3_high = newTemp(Ity_I64);
10080 IRTemp op3_low = newTemp(Ity_I64);
10081 IRTemp result = newTemp(Ity_I64);
10082 IRTemp nequal = newTemp(Ity_I1);
10083
10084 assign(op1_high, get_gpr_dw0(r1));
10085 assign(op1_low, get_gpr_dw0(r1+1));
10086 assign(op3_high, get_gpr_dw0(r3));
10087 assign(op3_low, get_gpr_dw0(r3+1));
10088
10089 /* The first and second operands are compared. If they are equal,
10090 the third operand is stored at the second-operand location. */
10091 cas = mkIRCAS(old_mem_high, old_mem_low,
10092 Iend_BE, mkexpr(op2addr),
10093 mkexpr(op1_high), mkexpr(op1_low), /* expected value */
10094 mkexpr(op3_high), mkexpr(op3_low) /* new value */);
10095 stmt(IRStmt_CAS(cas));
10096
10097 /* Set CC. Operands compared equal -> 0, else 1. */
10098 assign(result, unop(Iop_1Uto64,
10099 binop(Iop_CmpNE64,
10100 binop(Iop_Or64,
10101 binop(Iop_Xor64, mkexpr(op1_high), mkexpr(old_mem_high)),
10102 binop(Iop_Xor64, mkexpr(op1_low), mkexpr(old_mem_low))),
10103 mkU64(0))));
10104
10105 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
10106
10107 /* If operands were equal (cc == 0) just store the old value op1 in r1.
10108 Otherwise, store the old_value from memory in r1 and yield. */
10109 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
10110 put_gpr_dw0(r1, mkite(mkexpr(nequal), mkexpr(old_mem_high), mkexpr(op1_high)));
10111 put_gpr_dw0(r1+1, mkite(mkexpr(nequal), mkexpr(old_mem_low), mkexpr(op1_low)));
florian6820ba52012-07-26 02:01:50 +000010112 yield_if(mkexpr(nequal));
10113
florian448cbba2012-06-06 02:26:01 +000010114 return "cdsg";
10115}
10116
sewardj2019a972011-03-07 16:04:07 +000010117
10118/* Binary floating point */
10119
10120static HChar *
10121s390_irgen_AXBR(UChar r1, UChar r2)
10122{
10123 IRTemp op1 = newTemp(Ity_F128);
10124 IRTemp op2 = newTemp(Ity_F128);
10125 IRTemp result = newTemp(Ity_F128);
10126
10127 assign(op1, get_fpr_pair(r1));
10128 assign(op2, get_fpr_pair(r2));
10129 assign(result, triop(Iop_AddF128, mkU32(Irrm_NEAREST), mkexpr(op1),
10130 mkexpr(op2)));
10131 put_fpr_pair(r1, mkexpr(result));
10132
10133 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
10134
10135 return "axbr";
10136}
10137
10138/* The result of a Iop_CmdFxx operation is a condition code. It is
10139 encoded using the values defined in type IRCmpFxxResult.
10140 Before we can store the condition code into the guest state (or do
10141 anything else with it for that matter) we need to convert it to
10142 the encoding that s390 uses. This is what this function does.
10143
10144 s390 VEX b6 b2 b0 cc.1 cc.0
10145 0 0x40 EQ 1 0 0 0 0
10146 1 0x01 LT 0 0 1 0 1
10147 2 0x00 GT 0 0 0 1 0
10148 3 0x45 Unordered 1 1 1 1 1
10149
10150 The following bits from the VEX encoding are interesting:
10151 b0, b2, b6 with b0 being the LSB. We observe:
10152
10153 cc.0 = b0;
10154 cc.1 = b2 | (~b0 & ~b6)
10155
10156 with cc being the s390 condition code.
10157*/
10158static IRExpr *
10159convert_vex_fpcc_to_s390(IRTemp vex_cc)
10160{
10161 IRTemp cc0 = newTemp(Ity_I32);
10162 IRTemp cc1 = newTemp(Ity_I32);
10163 IRTemp b0 = newTemp(Ity_I32);
10164 IRTemp b2 = newTemp(Ity_I32);
10165 IRTemp b6 = newTemp(Ity_I32);
10166
10167 assign(b0, binop(Iop_And32, mkexpr(vex_cc), mkU32(1)));
10168 assign(b2, binop(Iop_And32, binop(Iop_Shr32, mkexpr(vex_cc), mkU8(2)),
10169 mkU32(1)));
10170 assign(b6, binop(Iop_And32, binop(Iop_Shr32, mkexpr(vex_cc), mkU8(6)),
10171 mkU32(1)));
10172
10173 assign(cc0, mkexpr(b0));
10174 assign(cc1, binop(Iop_Or32, mkexpr(b2),
10175 binop(Iop_And32,
10176 binop(Iop_Sub32, mkU32(1), mkexpr(b0)), /* ~b0 */
10177 binop(Iop_Sub32, mkU32(1), mkexpr(b6)) /* ~b6 */
10178 )));
10179
10180 return binop(Iop_Or32, mkexpr(cc0), binop(Iop_Shl32, mkexpr(cc1), mkU8(1)));
10181}
10182
10183static HChar *
10184s390_irgen_CEBR(UChar r1, UChar r2)
10185{
10186 IRTemp op1 = newTemp(Ity_F32);
10187 IRTemp op2 = newTemp(Ity_F32);
10188 IRTemp cc_vex = newTemp(Ity_I32);
10189 IRTemp cc_s390 = newTemp(Ity_I32);
10190
10191 assign(op1, get_fpr_w0(r1));
10192 assign(op2, get_fpr_w0(r2));
10193 assign(cc_vex, binop(Iop_CmpF32, mkexpr(op1), mkexpr(op2)));
10194
10195 assign(cc_s390, convert_vex_fpcc_to_s390(cc_vex));
10196 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
10197
10198 return "cebr";
10199}
10200
10201static HChar *
10202s390_irgen_CDBR(UChar r1, UChar r2)
10203{
10204 IRTemp op1 = newTemp(Ity_F64);
10205 IRTemp op2 = newTemp(Ity_F64);
10206 IRTemp cc_vex = newTemp(Ity_I32);
10207 IRTemp cc_s390 = newTemp(Ity_I32);
10208
10209 assign(op1, get_fpr_dw0(r1));
10210 assign(op2, get_fpr_dw0(r2));
10211 assign(cc_vex, binop(Iop_CmpF64, mkexpr(op1), mkexpr(op2)));
10212
10213 assign(cc_s390, convert_vex_fpcc_to_s390(cc_vex));
10214 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
10215
10216 return "cdbr";
10217}
10218
10219static HChar *
10220s390_irgen_CXBR(UChar r1, UChar r2)
10221{
10222 IRTemp op1 = newTemp(Ity_F128);
10223 IRTemp op2 = newTemp(Ity_F128);
10224 IRTemp cc_vex = newTemp(Ity_I32);
10225 IRTemp cc_s390 = newTemp(Ity_I32);
10226
10227 assign(op1, get_fpr_pair(r1));
10228 assign(op2, get_fpr_pair(r2));
10229 assign(cc_vex, binop(Iop_CmpF128, mkexpr(op1), mkexpr(op2)));
10230
10231 assign(cc_s390, convert_vex_fpcc_to_s390(cc_vex));
10232 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
10233
10234 return "cxbr";
10235}
10236
10237static HChar *
10238s390_irgen_CEB(UChar r1, IRTemp op2addr)
10239{
10240 IRTemp op1 = newTemp(Ity_F32);
10241 IRTemp op2 = newTemp(Ity_F32);
10242 IRTemp cc_vex = newTemp(Ity_I32);
10243 IRTemp cc_s390 = newTemp(Ity_I32);
10244
10245 assign(op1, get_fpr_w0(r1));
10246 assign(op2, load(Ity_F32, mkexpr(op2addr)));
10247 assign(cc_vex, binop(Iop_CmpF32, mkexpr(op1), mkexpr(op2)));
10248
10249 assign(cc_s390, convert_vex_fpcc_to_s390(cc_vex));
10250 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
10251
10252 return "ceb";
10253}
10254
10255static HChar *
10256s390_irgen_CDB(UChar r1, IRTemp op2addr)
10257{
10258 IRTemp op1 = newTemp(Ity_F64);
10259 IRTemp op2 = newTemp(Ity_F64);
10260 IRTemp cc_vex = newTemp(Ity_I32);
10261 IRTemp cc_s390 = newTemp(Ity_I32);
10262
10263 assign(op1, get_fpr_dw0(r1));
10264 assign(op2, load(Ity_F64, mkexpr(op2addr)));
10265 assign(cc_vex, binop(Iop_CmpF64, mkexpr(op1), mkexpr(op2)));
10266
10267 assign(cc_s390, convert_vex_fpcc_to_s390(cc_vex));
10268 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
10269
10270 return "cdb";
10271}
10272
10273static HChar *
10274s390_irgen_CXFBR(UChar r1, UChar r2)
10275{
10276 IRTemp op2 = newTemp(Ity_I32);
10277
10278 assign(op2, get_gpr_w1(r2));
10279 put_fpr_pair(r1, unop(Iop_I32StoF128, mkexpr(op2)));
10280
10281 return "cxfbr";
10282}
10283
10284static HChar *
florian1c8f7ff2012-09-01 00:12:11 +000010285s390_irgen_CXLFBR(UChar m3, UChar m4 __attribute__((unused)),
10286 UChar r1, UChar r2)
10287{
10288 IRTemp op2 = newTemp(Ity_I32);
10289
10290 assign(op2, get_gpr_w1(r2));
10291 put_fpr_pair(r1, unop(Iop_I32UtoF128, mkexpr(op2)));
10292
10293 return "cxlfbr";
10294}
10295
10296
10297static HChar *
sewardj2019a972011-03-07 16:04:07 +000010298s390_irgen_CXGBR(UChar r1, UChar r2)
10299{
10300 IRTemp op2 = newTemp(Ity_I64);
10301
10302 assign(op2, get_gpr_dw0(r2));
10303 put_fpr_pair(r1, unop(Iop_I64StoF128, mkexpr(op2)));
10304
10305 return "cxgbr";
10306}
10307
10308static HChar *
florian1c8f7ff2012-09-01 00:12:11 +000010309s390_irgen_CXLGBR(UChar m3, UChar m4 __attribute__((unused)),
10310 UChar r1, UChar r2)
10311{
10312 IRTemp op2 = newTemp(Ity_I64);
10313
10314 assign(op2, get_gpr_dw0(r2));
10315 put_fpr_pair(r1, unop(Iop_I64UtoF128, mkexpr(op2)));
10316
10317 return "cxlgbr";
10318}
10319
10320static HChar *
sewardj2019a972011-03-07 16:04:07 +000010321s390_irgen_CFXBR(UChar r3, UChar r1, UChar r2)
10322{
10323 IRTemp op = newTemp(Ity_F128);
10324 IRTemp result = newTemp(Ity_I32);
10325
10326 assign(op, get_fpr_pair(r2));
10327 assign(result, binop(Iop_F128toI32S, mkU32(encode_rounding_mode(r3)),
10328 mkexpr(op)));
10329 put_gpr_w1(r1, mkexpr(result));
10330 s390_cc_thunk_put1f128(S390_CC_OP_BFP_128_TO_INT_32, op);
10331
10332 return "cfxbr";
10333}
10334
10335static HChar *
florian1c8f7ff2012-09-01 00:12:11 +000010336s390_irgen_CLFXBR(UChar m3, UChar m4 __attribute__((unused)),
10337 UChar r1, UChar r2)
10338{
10339 IRTemp op = newTemp(Ity_F128);
10340 IRTemp result = newTemp(Ity_I32);
10341
10342 assign(op, get_fpr_pair(r2));
10343 assign(result, binop(Iop_F128toI32U, mkU32(encode_rounding_mode(m3)),
10344 mkexpr(op)));
10345 put_gpr_w1(r1, mkexpr(result));
10346 s390_cc_thunk_put1f128(S390_CC_OP_BFP_128_TO_UINT_32, op);
10347
10348 return "clfxbr";
10349}
10350
10351
10352static HChar *
sewardj2019a972011-03-07 16:04:07 +000010353s390_irgen_CGXBR(UChar r3, UChar r1, UChar r2)
10354{
10355 IRTemp op = newTemp(Ity_F128);
10356 IRTemp result = newTemp(Ity_I64);
10357
10358 assign(op, get_fpr_pair(r2));
10359 assign(result, binop(Iop_F128toI64S, mkU32(encode_rounding_mode(r3)),
10360 mkexpr(op)));
10361 put_gpr_dw0(r1, mkexpr(result));
10362 s390_cc_thunk_put1f128(S390_CC_OP_BFP_128_TO_INT_64, op);
10363
10364 return "cgxbr";
10365}
10366
10367static HChar *
florian1c8f7ff2012-09-01 00:12:11 +000010368s390_irgen_CLGXBR(UChar m3, UChar m4 __attribute__((unused)),
10369 UChar r1, UChar r2)
10370{
10371 IRTemp op = newTemp(Ity_F128);
10372 IRTemp result = newTemp(Ity_I64);
10373
10374 assign(op, get_fpr_pair(r2));
10375 assign(result, binop(Iop_F128toI64U, mkU32(encode_rounding_mode(m3)),
10376 mkexpr(op)));
10377 put_gpr_dw0(r1, mkexpr(result));
10378 s390_cc_thunk_put1f128(S390_CC_OP_BFP_128_TO_UINT_64, op);
10379
10380 return "clgxbr";
10381}
10382
10383static HChar *
sewardj2019a972011-03-07 16:04:07 +000010384s390_irgen_DXBR(UChar r1, UChar r2)
10385{
10386 IRTemp op1 = newTemp(Ity_F128);
10387 IRTemp op2 = newTemp(Ity_F128);
10388 IRTemp result = newTemp(Ity_F128);
10389
10390 assign(op1, get_fpr_pair(r1));
10391 assign(op2, get_fpr_pair(r2));
10392 assign(result, triop(Iop_DivF128, mkU32(Irrm_NEAREST), mkexpr(op1),
10393 mkexpr(op2)));
10394 put_fpr_pair(r1, mkexpr(result));
10395
10396 return "dxbr";
10397}
10398
10399static HChar *
10400s390_irgen_LTXBR(UChar r1, UChar r2)
10401{
10402 IRTemp result = newTemp(Ity_F128);
10403
10404 assign(result, get_fpr_pair(r2));
10405 put_fpr_pair(r1, mkexpr(result));
10406 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
10407
10408 return "ltxbr";
10409}
10410
10411static HChar *
10412s390_irgen_LCXBR(UChar r1, UChar r2)
10413{
10414 IRTemp result = newTemp(Ity_F128);
10415
10416 assign(result, unop(Iop_NegF128, get_fpr_pair(r2)));
10417 put_fpr_pair(r1, mkexpr(result));
10418 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
10419
10420 return "lcxbr";
10421}
10422
10423static HChar *
10424s390_irgen_LXDBR(UChar r1, UChar r2)
10425{
10426 IRTemp op = newTemp(Ity_F64);
10427
10428 assign(op, get_fpr_dw0(r2));
10429 put_fpr_pair(r1, unop(Iop_F64toF128, mkexpr(op)));
10430
10431 return "lxdbr";
10432}
10433
10434static HChar *
10435s390_irgen_LXEBR(UChar r1, UChar r2)
10436{
10437 IRTemp op = newTemp(Ity_F32);
10438
10439 assign(op, get_fpr_w0(r2));
10440 put_fpr_pair(r1, unop(Iop_F32toF128, mkexpr(op)));
10441
10442 return "lxebr";
10443}
10444
10445static HChar *
10446s390_irgen_LXDB(UChar r1, IRTemp op2addr)
10447{
10448 IRTemp op = newTemp(Ity_F64);
10449
10450 assign(op, load(Ity_F64, mkexpr(op2addr)));
10451 put_fpr_pair(r1, unop(Iop_F64toF128, mkexpr(op)));
10452
10453 return "lxdb";
10454}
10455
10456static HChar *
10457s390_irgen_LXEB(UChar r1, IRTemp op2addr)
10458{
10459 IRTemp op = newTemp(Ity_F32);
10460
10461 assign(op, load(Ity_F32, mkexpr(op2addr)));
10462 put_fpr_pair(r1, unop(Iop_F32toF128, mkexpr(op)));
10463
10464 return "lxeb";
10465}
10466
10467static HChar *
10468s390_irgen_LNEBR(UChar r1, UChar r2)
10469{
10470 IRTemp result = newTemp(Ity_F32);
10471
10472 assign(result, unop(Iop_NegF32, unop(Iop_AbsF32, get_fpr_w0(r2))));
10473 put_fpr_w0(r1, mkexpr(result));
10474 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_32, result);
10475
10476 return "lnebr";
10477}
10478
10479static HChar *
10480s390_irgen_LNDBR(UChar r1, UChar r2)
10481{
10482 IRTemp result = newTemp(Ity_F64);
10483
10484 assign(result, unop(Iop_NegF64, unop(Iop_AbsF64, get_fpr_dw0(r2))));
10485 put_fpr_dw0(r1, mkexpr(result));
10486 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_64, result);
10487
10488 return "lndbr";
10489}
10490
10491static HChar *
10492s390_irgen_LNXBR(UChar r1, UChar r2)
10493{
10494 IRTemp result = newTemp(Ity_F128);
10495
10496 assign(result, unop(Iop_NegF128, unop(Iop_AbsF128, get_fpr_pair(r2))));
10497 put_fpr_pair(r1, mkexpr(result));
10498 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
10499
10500 return "lnxbr";
10501}
10502
10503static HChar *
10504s390_irgen_LPEBR(UChar r1, UChar r2)
10505{
10506 IRTemp result = newTemp(Ity_F32);
10507
10508 assign(result, unop(Iop_AbsF32, get_fpr_w0(r2)));
10509 put_fpr_w0(r1, mkexpr(result));
10510 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_32, result);
10511
10512 return "lpebr";
10513}
10514
10515static HChar *
10516s390_irgen_LPDBR(UChar r1, UChar r2)
10517{
10518 IRTemp result = newTemp(Ity_F64);
10519
10520 assign(result, unop(Iop_AbsF64, get_fpr_dw0(r2)));
10521 put_fpr_dw0(r1, mkexpr(result));
10522 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_64, result);
10523
10524 return "lpdbr";
10525}
10526
10527static HChar *
10528s390_irgen_LPXBR(UChar r1, UChar r2)
10529{
10530 IRTemp result = newTemp(Ity_F128);
10531
10532 assign(result, unop(Iop_AbsF128, get_fpr_pair(r2)));
10533 put_fpr_pair(r1, mkexpr(result));
10534 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
10535
10536 return "lpxbr";
10537}
10538
10539static HChar *
10540s390_irgen_LDXBR(UChar r1, UChar r2)
10541{
10542 IRTemp result = newTemp(Ity_F64);
10543
10544 assign(result, binop(Iop_F128toF64, mkU32(Irrm_NEAREST), get_fpr_pair(r2)));
10545 put_fpr_dw0(r1, mkexpr(result));
10546
10547 return "ldxbr";
10548}
10549
10550static HChar *
10551s390_irgen_LEXBR(UChar r1, UChar r2)
10552{
10553 IRTemp result = newTemp(Ity_F32);
10554
10555 assign(result, binop(Iop_F128toF32, mkU32(Irrm_NEAREST), get_fpr_pair(r2)));
10556 put_fpr_w0(r1, mkexpr(result));
10557
10558 return "lexbr";
10559}
10560
10561static HChar *
10562s390_irgen_MXBR(UChar r1, UChar r2)
10563{
10564 IRTemp op1 = newTemp(Ity_F128);
10565 IRTemp op2 = newTemp(Ity_F128);
10566 IRTemp result = newTemp(Ity_F128);
10567
10568 assign(op1, get_fpr_pair(r1));
10569 assign(op2, get_fpr_pair(r2));
10570 assign(result, triop(Iop_MulF128, mkU32(Irrm_NEAREST), mkexpr(op1),
10571 mkexpr(op2)));
10572 put_fpr_pair(r1, mkexpr(result));
10573
10574 return "mxbr";
10575}
10576
10577static HChar *
10578s390_irgen_MAEBR(UChar r1, UChar r3, UChar r2)
10579{
10580 put_fpr_w0(r1, qop(Iop_MAddF32, mkU32(Irrm_NEAREST),
10581 get_fpr_w0(r1), get_fpr_w0(r2), get_fpr_w0(r3)));
10582
10583 return "maebr";
10584}
10585
10586static HChar *
10587s390_irgen_MADBR(UChar r1, UChar r3, UChar r2)
10588{
10589 put_fpr_dw0(r1, qop(Iop_MAddF64, mkU32(Irrm_NEAREST),
10590 get_fpr_dw0(r1), get_fpr_dw0(r2), get_fpr_dw0(r3)));
10591
10592 return "madbr";
10593}
10594
10595static HChar *
10596s390_irgen_MAEB(UChar r3, IRTemp op2addr, UChar r1)
10597{
10598 IRExpr *op2 = load(Ity_F32, mkexpr(op2addr));
10599
10600 put_fpr_w0(r1, qop(Iop_MAddF32, mkU32(Irrm_NEAREST),
10601 get_fpr_w0(r1), op2, get_fpr_w0(r3)));
10602
10603 return "maeb";
10604}
10605
10606static HChar *
10607s390_irgen_MADB(UChar r3, IRTemp op2addr, UChar r1)
10608{
10609 IRExpr *op2 = load(Ity_F64, mkexpr(op2addr));
10610
10611 put_fpr_dw0(r1, qop(Iop_MAddF64, mkU32(Irrm_NEAREST),
10612 get_fpr_dw0(r1), op2, get_fpr_dw0(r3)));
10613
10614 return "madb";
10615}
10616
10617static HChar *
10618s390_irgen_MSEBR(UChar r1, UChar r3, UChar r2)
10619{
10620 put_fpr_w0(r1, qop(Iop_MSubF32, mkU32(Irrm_NEAREST),
10621 get_fpr_w0(r1), get_fpr_w0(r2), get_fpr_w0(r3)));
10622
10623 return "msebr";
10624}
10625
10626static HChar *
10627s390_irgen_MSDBR(UChar r1, UChar r3, UChar r2)
10628{
10629 put_fpr_dw0(r1, qop(Iop_MSubF64, mkU32(Irrm_NEAREST),
10630 get_fpr_dw0(r1), get_fpr_dw0(r2), get_fpr_dw0(r3)));
10631
10632 return "msdbr";
10633}
10634
10635static HChar *
10636s390_irgen_MSEB(UChar r3, IRTemp op2addr, UChar r1)
10637{
10638 IRExpr *op2 = load(Ity_F32, mkexpr(op2addr));
10639
10640 put_fpr_w0(r1, qop(Iop_MSubF32, mkU32(Irrm_NEAREST),
10641 get_fpr_w0(r1), op2, get_fpr_w0(r3)));
10642
10643 return "mseb";
10644}
10645
10646static HChar *
10647s390_irgen_MSDB(UChar r3, IRTemp op2addr, UChar r1)
10648{
10649 IRExpr *op2 = load(Ity_F64, mkexpr(op2addr));
10650
10651 put_fpr_dw0(r1, qop(Iop_MSubF64, mkU32(Irrm_NEAREST),
10652 get_fpr_dw0(r1), op2, get_fpr_dw0(r3)));
10653
10654 return "msdb";
10655}
10656
10657static HChar *
10658s390_irgen_SQEBR(UChar r1, UChar r2)
10659{
10660 IRTemp result = newTemp(Ity_F32);
10661
10662 assign(result, binop(Iop_SqrtF32, mkU32(Irrm_NEAREST), get_fpr_w0(r2)));
10663 put_fpr_w0(r1, mkexpr(result));
10664
10665 return "sqebr";
10666}
10667
10668static HChar *
10669s390_irgen_SQDBR(UChar r1, UChar r2)
10670{
10671 IRTemp result = newTemp(Ity_F64);
10672
10673 assign(result, binop(Iop_SqrtF64, mkU32(Irrm_NEAREST), get_fpr_dw0(r2)));
10674 put_fpr_dw0(r1, mkexpr(result));
10675
10676 return "sqdbr";
10677}
10678
10679static HChar *
10680s390_irgen_SQXBR(UChar r1, UChar r2)
10681{
10682 IRTemp result = newTemp(Ity_F128);
10683
10684 assign(result, binop(Iop_SqrtF128, mkU32(Irrm_NEAREST), get_fpr_pair(r2)));
10685 put_fpr_pair(r1, mkexpr(result));
10686
10687 return "sqxbr";
10688}
10689
10690static HChar *
10691s390_irgen_SQEB(UChar r1, IRTemp op2addr)
10692{
10693 IRTemp op = newTemp(Ity_F32);
10694
10695 assign(op, load(Ity_F32, mkexpr(op2addr)));
10696 put_fpr_w0(r1, binop(Iop_SqrtF32, mkU32(Irrm_NEAREST), mkexpr(op)));
10697
10698 return "sqeb";
10699}
10700
10701static HChar *
10702s390_irgen_SQDB(UChar r1, IRTemp op2addr)
10703{
10704 IRTemp op = newTemp(Ity_F64);
10705
10706 assign(op, load(Ity_F64, mkexpr(op2addr)));
10707 put_fpr_dw0(r1, binop(Iop_SqrtF64, mkU32(Irrm_NEAREST), mkexpr(op)));
10708
10709 return "sqdb";
10710}
10711
10712static HChar *
10713s390_irgen_SXBR(UChar r1, UChar r2)
10714{
10715 IRTemp op1 = newTemp(Ity_F128);
10716 IRTemp op2 = newTemp(Ity_F128);
10717 IRTemp result = newTemp(Ity_F128);
10718
10719 assign(op1, get_fpr_pair(r1));
10720 assign(op2, get_fpr_pair(r2));
10721 assign(result, triop(Iop_SubF128, mkU32(Irrm_NEAREST), mkexpr(op1),
10722 mkexpr(op2)));
10723 put_fpr_pair(r1, mkexpr(result));
10724 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
10725
10726 return "sxbr";
10727}
10728
10729static HChar *
10730s390_irgen_TCEB(UChar r1, IRTemp op2addr)
10731{
10732 IRTemp value = newTemp(Ity_F32);
10733
10734 assign(value, get_fpr_w0(r1));
10735
10736 s390_cc_thunk_putFZ(S390_CC_OP_BFP_TDC_32, value, op2addr);
10737
10738 return "tceb";
10739}
10740
10741static HChar *
10742s390_irgen_TCDB(UChar r1, IRTemp op2addr)
10743{
10744 IRTemp value = newTemp(Ity_F64);
10745
10746 assign(value, get_fpr_dw0(r1));
10747
10748 s390_cc_thunk_putFZ(S390_CC_OP_BFP_TDC_64, value, op2addr);
10749
10750 return "tcdb";
10751}
10752
10753static HChar *
10754s390_irgen_TCXB(UChar r1, IRTemp op2addr)
10755{
10756 IRTemp value = newTemp(Ity_F128);
10757
10758 assign(value, get_fpr_pair(r1));
10759
10760 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_TDC_128, value, op2addr);
10761
10762 return "tcxb";
10763}
10764
10765static HChar *
10766s390_irgen_LCDFR(UChar r1, UChar r2)
10767{
10768 IRTemp result = newTemp(Ity_F64);
10769
10770 assign(result, unop(Iop_NegF64, get_fpr_dw0(r2)));
10771 put_fpr_dw0(r1, mkexpr(result));
10772
10773 return "lcdfr";
10774}
10775
10776static HChar *
10777s390_irgen_LNDFR(UChar r1, UChar r2)
10778{
10779 IRTemp result = newTemp(Ity_F64);
10780
10781 assign(result, unop(Iop_NegF64, unop(Iop_AbsF64, get_fpr_dw0(r2))));
10782 put_fpr_dw0(r1, mkexpr(result));
10783
10784 return "lndfr";
10785}
10786
10787static HChar *
10788s390_irgen_LPDFR(UChar r1, UChar r2)
10789{
10790 IRTemp result = newTemp(Ity_F64);
10791
10792 assign(result, unop(Iop_AbsF64, get_fpr_dw0(r2)));
10793 put_fpr_dw0(r1, mkexpr(result));
10794
10795 return "lpdfr";
10796}
10797
10798static HChar *
10799s390_irgen_LDGR(UChar r1, UChar r2)
10800{
10801 put_fpr_dw0(r1, unop(Iop_ReinterpI64asF64, get_gpr_dw0(r2)));
10802
10803 return "ldgr";
10804}
10805
10806static HChar *
10807s390_irgen_LGDR(UChar r1, UChar r2)
10808{
10809 put_gpr_dw0(r1, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r2)));
10810
10811 return "lgdr";
10812}
10813
10814
10815static HChar *
10816s390_irgen_CPSDR(UChar r3, UChar r1, UChar r2)
10817{
10818 IRTemp sign = newTemp(Ity_I64);
10819 IRTemp value = newTemp(Ity_I64);
10820
10821 assign(sign, binop(Iop_And64, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r3)),
10822 mkU64(1ULL << 63)));
10823 assign(value, binop(Iop_And64, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r2)),
10824 mkU64((1ULL << 63) - 1)));
10825 put_fpr_dw0(r1, unop(Iop_ReinterpI64asF64, binop(Iop_Or64, mkexpr(value),
10826 mkexpr(sign))));
10827
10828 return "cpsdr";
10829}
10830
10831
sewardj2019a972011-03-07 16:04:07 +000010832static IRExpr *
10833s390_call_cvb(IRExpr *in)
10834{
10835 IRExpr **args, *call;
10836
10837 args = mkIRExprVec_1(in);
10838 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
10839 "s390_do_cvb", &s390_do_cvb, args);
10840
10841 /* Nothing is excluded from definedness checking. */
10842 call->Iex.CCall.cee->mcx_mask = 0;
10843
10844 return call;
10845}
10846
10847static HChar *
10848s390_irgen_CVB(UChar r1, IRTemp op2addr)
10849{
10850 put_gpr_w1(r1, s390_call_cvb(load(Ity_I64, mkexpr(op2addr))));
10851
10852 return "cvb";
10853}
10854
10855static HChar *
10856s390_irgen_CVBY(UChar r1, IRTemp op2addr)
10857{
10858 put_gpr_w1(r1, s390_call_cvb(load(Ity_I64, mkexpr(op2addr))));
10859
10860 return "cvby";
10861}
10862
10863
sewardj2019a972011-03-07 16:04:07 +000010864static IRExpr *
10865s390_call_cvd(IRExpr *in)
10866{
10867 IRExpr **args, *call;
10868
10869 args = mkIRExprVec_1(in);
10870 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
10871 "s390_do_cvd", &s390_do_cvd, args);
10872
10873 /* Nothing is excluded from definedness checking. */
10874 call->Iex.CCall.cee->mcx_mask = 0;
10875
10876 return call;
10877}
10878
10879static HChar *
10880s390_irgen_CVD(UChar r1, IRTemp op2addr)
10881{
florian11b8ee82012-08-06 13:35:33 +000010882 store(mkexpr(op2addr), s390_call_cvd(unop(Iop_32Uto64, get_gpr_w1(r1))));
sewardj2019a972011-03-07 16:04:07 +000010883
10884 return "cvd";
10885}
10886
10887static HChar *
10888s390_irgen_CVDY(UChar r1, IRTemp op2addr)
10889{
10890 store(mkexpr(op2addr), s390_call_cvd(get_gpr_w1(r1)));
10891
10892 return "cvdy";
10893}
10894
10895static HChar *
10896s390_irgen_FLOGR(UChar r1, UChar r2)
10897{
10898 IRTemp input = newTemp(Ity_I64);
10899 IRTemp not_zero = newTemp(Ity_I64);
10900 IRTemp tmpnum = newTemp(Ity_I64);
10901 IRTemp num = newTemp(Ity_I64);
10902 IRTemp shift_amount = newTemp(Ity_I8);
10903
10904 /* We use the "count leading zeroes" operator because the number of
10905 leading zeroes is identical with the bit position of the first '1' bit.
10906 However, that operator does not work when the input value is zero.
10907 Therefore, we set the LSB of the input value to 1 and use Clz64 on
10908 the modified value. If input == 0, then the result is 64. Otherwise,
10909 the result of Clz64 is what we want. */
10910
10911 assign(input, get_gpr_dw0(r2));
10912 assign(not_zero, binop(Iop_Or64, mkexpr(input), mkU64(1)));
10913 assign(tmpnum, unop(Iop_Clz64, mkexpr(not_zero)));
10914
10915 /* num = (input == 0) ? 64 : tmpnum */
10916 assign(num, mkite(binop(Iop_CmpEQ64, mkexpr(input), mkU64(0)),
10917 /* == 0 */ mkU64(64),
10918 /* != 0 */ mkexpr(tmpnum)));
10919
10920 put_gpr_dw0(r1, mkexpr(num));
10921
10922 /* Set the leftmost '1' bit of the input value to zero. The general scheme
10923 is to first shift the input value by NUM + 1 bits to the left which
10924 causes the leftmost '1' bit to disappear. Then we shift logically to
10925 the right by NUM + 1 bits. Because the semantics of Iop_Shl64 and
10926 Iop_Shr64 are undefined if the shift-amount is greater than or equal to
10927 the width of the value-to-be-shifted, we need to special case
10928 NUM + 1 >= 64. This is equivalent to INPUT != 0 && INPUT != 1.
10929 For both such INPUT values the result will be 0. */
10930
10931 assign(shift_amount, unop(Iop_64to8, binop(Iop_Add64, mkexpr(num),
10932 mkU64(1))));
10933
10934 put_gpr_dw0(r1 + 1,
florian6ad49522011-09-09 02:38:55 +000010935 mkite(binop(Iop_CmpLE64U, mkexpr(input), mkU64(1)),
10936 /* == 0 || == 1*/ mkU64(0),
10937 /* otherwise */
10938 binop(Iop_Shr64,
10939 binop(Iop_Shl64, mkexpr(input),
10940 mkexpr(shift_amount)),
10941 mkexpr(shift_amount))));
sewardj2019a972011-03-07 16:04:07 +000010942
10943 /* Compare the original value as an unsigned integer with 0. */
10944 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, input,
10945 mktemp(Ity_I64, mkU64(0)), False);
10946
10947 return "flogr";
10948}
10949
sewardj1e5fea62011-05-17 16:18:36 +000010950static HChar *
10951s390_irgen_STCK(IRTemp op2addr)
10952{
10953 IRDirty *d;
10954 IRTemp cc = newTemp(Ity_I64);
10955
10956 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCK",
10957 &s390x_dirtyhelper_STCK,
10958 mkIRExprVec_1(mkexpr(op2addr)));
10959 d->mFx = Ifx_Write;
10960 d->mAddr = mkexpr(op2addr);
10961 d->mSize = 8;
10962 stmt(IRStmt_Dirty(d));
10963 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
10964 mkexpr(cc), mkU64(0), mkU64(0));
10965 return "stck";
10966}
10967
10968static HChar *
10969s390_irgen_STCKF(IRTemp op2addr)
10970{
florianc5c669b2012-08-26 14:32:28 +000010971 if (! s390_host_has_stckf) {
10972 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_EMNOTE),
10973 mkU32(EmFail_S390X_stckf)));
10974 put_IA(mkaddr_expr(guest_IA_next_instr));
10975 dis_res->whatNext = Dis_StopHere;
10976 dis_res->jk_StopHere = Ijk_EmFail;
10977 } else {
10978 IRTemp cc = newTemp(Ity_I64);
sewardj1e5fea62011-05-17 16:18:36 +000010979
florianc5c669b2012-08-26 14:32:28 +000010980 IRDirty *d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCKF",
10981 &s390x_dirtyhelper_STCKF,
10982 mkIRExprVec_1(mkexpr(op2addr)));
10983 d->mFx = Ifx_Write;
10984 d->mAddr = mkexpr(op2addr);
10985 d->mSize = 8;
10986 stmt(IRStmt_Dirty(d));
10987 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
10988 mkexpr(cc), mkU64(0), mkU64(0));
10989 }
sewardj1e5fea62011-05-17 16:18:36 +000010990 return "stckf";
10991}
10992
10993static HChar *
10994s390_irgen_STCKE(IRTemp op2addr)
10995{
10996 IRDirty *d;
10997 IRTemp cc = newTemp(Ity_I64);
10998
10999 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCKE",
11000 &s390x_dirtyhelper_STCKE,
11001 mkIRExprVec_1(mkexpr(op2addr)));
11002 d->mFx = Ifx_Write;
11003 d->mAddr = mkexpr(op2addr);
11004 d->mSize = 16;
11005 stmt(IRStmt_Dirty(d));
11006 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
11007 mkexpr(cc), mkU64(0), mkU64(0));
11008 return "stcke";
11009}
11010
florian933065d2011-07-11 01:48:02 +000011011static HChar *
11012s390_irgen_STFLE(IRTemp op2addr)
11013{
florian4e0083e2012-08-26 03:41:56 +000011014 if (! s390_host_has_stfle) {
11015 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_EMNOTE),
11016 mkU32(EmFail_S390X_stfle)));
11017 put_IA(mkaddr_expr(guest_IA_next_instr));
11018 dis_res->whatNext = Dis_StopHere;
11019 dis_res->jk_StopHere = Ijk_EmFail;
11020 return "stfle";
11021 }
11022
florian933065d2011-07-11 01:48:02 +000011023 IRDirty *d;
11024 IRTemp cc = newTemp(Ity_I64);
11025
11026 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STFLE",
11027 &s390x_dirtyhelper_STFLE,
11028 mkIRExprVec_1(mkexpr(op2addr)));
11029
11030 d->needsBBP = 1; /* Need to pass pointer to guest state to helper */
11031
sewardjc9069f22012-06-01 16:09:50 +000011032 d->nFxState = 1;
11033 vex_bzero(&d->fxState, sizeof(d->fxState));
11034
florian933065d2011-07-11 01:48:02 +000011035 d->fxState[0].fx = Ifx_Modify; /* read then write */
11036 d->fxState[0].offset = S390X_GUEST_OFFSET(guest_r0);
11037 d->fxState[0].size = sizeof(ULong);
florian933065d2011-07-11 01:48:02 +000011038
11039 d->mAddr = mkexpr(op2addr);
11040 /* Pretend all double words are written */
11041 d->mSize = S390_NUM_FACILITY_DW * sizeof(ULong);
11042 d->mFx = Ifx_Write;
11043
11044 stmt(IRStmt_Dirty(d));
11045
11046 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET), mkexpr(cc), mkU64(0), mkU64(0));
11047
11048 return "stfle";
11049}
11050
floriana4384a32011-08-11 16:58:45 +000011051static HChar *
11052s390_irgen_CKSM(UChar r1,UChar r2)
11053{
11054 IRTemp addr = newTemp(Ity_I64);
11055 IRTemp op = newTemp(Ity_I32);
11056 IRTemp len = newTemp(Ity_I64);
11057 IRTemp oldval = newTemp(Ity_I32);
11058 IRTemp mask = newTemp(Ity_I32);
11059 IRTemp newop = newTemp(Ity_I32);
11060 IRTemp result = newTemp(Ity_I32);
11061 IRTemp result1 = newTemp(Ity_I32);
11062 IRTemp inc = newTemp(Ity_I64);
11063
11064 assign(oldval, get_gpr_w1(r1));
11065 assign(addr, get_gpr_dw0(r2));
11066 assign(len, get_gpr_dw0(r2+1));
11067
11068 /* Condition code is always zero. */
11069 s390_cc_set(0);
11070
11071 /* If length is zero, there is no need to calculate the checksum */
florian6820ba52012-07-26 02:01:50 +000011072 next_insn_if(binop(Iop_CmpEQ64, mkexpr(len), mkU64(0)));
floriana4384a32011-08-11 16:58:45 +000011073
11074 /* Assiging the increment variable to adjust address and length
11075 later on. */
11076 assign(inc, mkite(binop(Iop_CmpLT64U, mkexpr(len), mkU64(4)),
11077 mkexpr(len), mkU64(4)));
11078
11079 /* If length < 4 the final 4-byte 2nd operand value is computed by
11080 appending the remaining bytes to the right with 0. This is done
11081 by AND'ing the 4 bytes loaded from memory with an appropriate
11082 mask. If length >= 4, that mask is simply 0xffffffff. */
11083
11084 assign(mask, mkite(binop(Iop_CmpLT64U, mkexpr(len), mkU64(4)),
11085 /* Mask computation when len < 4:
11086 0xffffffff << (32 - (len % 4)*8) */
11087 binop(Iop_Shl32, mkU32(0xffffffff),
11088 unop(Iop_32to8,
11089 binop(Iop_Sub32, mkU32(32),
11090 binop(Iop_Shl32,
11091 unop(Iop_64to32,
11092 binop(Iop_And64,
11093 mkexpr(len), mkU64(3))),
11094 mkU8(3))))),
11095 mkU32(0xffffffff)));
11096
11097 assign(op, load(Ity_I32, mkexpr(addr)));
11098 assign(newop, binop(Iop_And32, mkexpr(op), mkexpr(mask)));
11099 assign(result, binop(Iop_Add32, mkexpr(newop), mkexpr(oldval)));
11100
11101 /* Checking for carry */
11102 assign(result1, mkite(binop(Iop_CmpLT32U, mkexpr(result), mkexpr(newop)),
11103 binop(Iop_Add32, mkexpr(result), mkU32(1)),
11104 mkexpr(result)));
11105
11106 put_gpr_w1(r1, mkexpr(result1));
11107 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr), mkexpr(inc)));
11108 put_gpr_dw0(r2+1, binop(Iop_Sub64, mkexpr(len), mkexpr(inc)));
11109
florian6820ba52012-07-26 02:01:50 +000011110 iterate_if(binop(Iop_CmpNE64, mkexpr(len), mkU64(0)));
floriana4384a32011-08-11 16:58:45 +000011111
11112 return "cksm";
11113}
11114
florian9af37692012-01-15 21:01:16 +000011115static HChar *
11116s390_irgen_TROO(UChar m3, UChar r1, UChar r2)
11117{
11118 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
11119 src_addr = newTemp(Ity_I64);
11120 des_addr = newTemp(Ity_I64);
11121 tab_addr = newTemp(Ity_I64);
11122 test_byte = newTemp(Ity_I8);
11123 src_len = newTemp(Ity_I64);
11124
11125 assign(src_addr, get_gpr_dw0(r2));
11126 assign(des_addr, get_gpr_dw0(r1));
11127 assign(tab_addr, get_gpr_dw0(1));
florian53518532012-01-18 14:00:31 +000011128 assign(src_len, get_gpr_dw0(r1+1));
florian9af37692012-01-15 21:01:16 +000011129 assign(test_byte, get_gpr_b7(0));
11130
11131 IRTemp op = newTemp(Ity_I8);
11132 IRTemp op1 = newTemp(Ity_I8);
11133 IRTemp result = newTemp(Ity_I64);
11134
11135 /* End of source string? We're done; proceed to next insn */
11136 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000011137 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian9af37692012-01-15 21:01:16 +000011138
11139 /* Load character from source string, index translation table and
11140 store translated character in op1. */
11141 assign(op, load(Ity_I8, mkexpr(src_addr)));
11142
11143 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
11144 mkexpr(tab_addr)));
11145 assign(op1, load(Ity_I8, mkexpr(result)));
11146
11147 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
11148 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011149 next_insn_if(binop(Iop_CmpEQ8, mkexpr(op1), mkexpr(test_byte)));
florian9af37692012-01-15 21:01:16 +000011150 }
11151 store(get_gpr_dw0(r1), mkexpr(op1));
11152
11153 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(1)));
11154 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
11155 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
11156
florian6820ba52012-07-26 02:01:50 +000011157 iterate();
florian9af37692012-01-15 21:01:16 +000011158
11159 return "troo";
11160}
11161
florian730448f2012-02-04 17:07:07 +000011162static HChar *
11163s390_irgen_TRTO(UChar m3, UChar r1, UChar r2)
11164{
11165 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
11166 src_addr = newTemp(Ity_I64);
11167 des_addr = newTemp(Ity_I64);
11168 tab_addr = newTemp(Ity_I64);
11169 test_byte = newTemp(Ity_I8);
11170 src_len = newTemp(Ity_I64);
11171
11172 assign(src_addr, get_gpr_dw0(r2));
11173 assign(des_addr, get_gpr_dw0(r1));
11174 assign(tab_addr, get_gpr_dw0(1));
11175 assign(src_len, get_gpr_dw0(r1+1));
11176 assign(test_byte, get_gpr_b7(0));
11177
11178 IRTemp op = newTemp(Ity_I16);
11179 IRTemp op1 = newTemp(Ity_I8);
11180 IRTemp result = newTemp(Ity_I64);
11181
11182 /* End of source string? We're done; proceed to next insn */
11183 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000011184 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000011185
11186 /* Load character from source string, index translation table and
11187 store translated character in op1. */
11188 assign(op, load(Ity_I16, mkexpr(src_addr)));
11189
11190 assign(result, binop(Iop_Add64, unop(Iop_16Uto64, mkexpr(op)),
11191 mkexpr(tab_addr)));
11192
11193 assign(op1, load(Ity_I8, mkexpr(result)));
11194
11195 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
11196 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011197 next_insn_if(binop(Iop_CmpEQ8, mkexpr(op1), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000011198 }
11199 store(get_gpr_dw0(r1), mkexpr(op1));
11200
11201 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(2)));
11202 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(1)));
11203 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(2)));
11204
florian6820ba52012-07-26 02:01:50 +000011205 iterate();
florian730448f2012-02-04 17:07:07 +000011206
11207 return "trto";
11208}
11209
11210static HChar *
11211s390_irgen_TROT(UChar m3, UChar r1, UChar r2)
11212{
11213 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
11214 src_addr = newTemp(Ity_I64);
11215 des_addr = newTemp(Ity_I64);
11216 tab_addr = newTemp(Ity_I64);
11217 test_byte = newTemp(Ity_I16);
11218 src_len = newTemp(Ity_I64);
11219
11220 assign(src_addr, get_gpr_dw0(r2));
11221 assign(des_addr, get_gpr_dw0(r1));
11222 assign(tab_addr, get_gpr_dw0(1));
11223 assign(src_len, get_gpr_dw0(r1+1));
11224 assign(test_byte, get_gpr_hw3(0));
11225
11226 IRTemp op = newTemp(Ity_I8);
11227 IRTemp op1 = newTemp(Ity_I16);
11228 IRTemp result = newTemp(Ity_I64);
11229
11230 /* End of source string? We're done; proceed to next insn */
11231 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000011232 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000011233
11234 /* Load character from source string, index translation table and
11235 store translated character in op1. */
11236 assign(op, binop(Iop_Shl8, load(Ity_I8, mkexpr(src_addr)), mkU8(1)));
11237
11238 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
11239 mkexpr(tab_addr)));
11240 assign(op1, load(Ity_I16, mkexpr(result)));
11241
11242 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
11243 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011244 next_insn_if(binop(Iop_CmpEQ16, mkexpr(op1), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000011245 }
11246 store(get_gpr_dw0(r1), mkexpr(op1));
11247
11248 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
11249 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(2)));
11250 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
11251
florian6820ba52012-07-26 02:01:50 +000011252 iterate();
florian730448f2012-02-04 17:07:07 +000011253
11254 return "trot";
11255}
11256
11257static HChar *
11258s390_irgen_TRTT(UChar m3, UChar r1, UChar r2)
11259{
11260 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
11261 src_addr = newTemp(Ity_I64);
11262 des_addr = newTemp(Ity_I64);
11263 tab_addr = newTemp(Ity_I64);
11264 test_byte = newTemp(Ity_I16);
11265 src_len = newTemp(Ity_I64);
11266
11267 assign(src_addr, get_gpr_dw0(r2));
11268 assign(des_addr, get_gpr_dw0(r1));
11269 assign(tab_addr, get_gpr_dw0(1));
11270 assign(src_len, get_gpr_dw0(r1+1));
11271 assign(test_byte, get_gpr_hw3(0));
11272
11273 IRTemp op = newTemp(Ity_I16);
11274 IRTemp op1 = newTemp(Ity_I16);
11275 IRTemp result = newTemp(Ity_I64);
11276
11277 /* End of source string? We're done; proceed to next insn */
11278 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000011279 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000011280
11281 /* Load character from source string, index translation table and
11282 store translated character in op1. */
11283 assign(op, binop(Iop_Shl16, load(Ity_I16, mkexpr(src_addr)), mkU8(1)));
11284
11285 assign(result, binop(Iop_Add64, unop(Iop_16Uto64, mkexpr(op)),
11286 mkexpr(tab_addr)));
11287 assign(op1, load(Ity_I16, mkexpr(result)));
11288
11289 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
11290 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011291 next_insn_if(binop(Iop_CmpEQ16, mkexpr(op1), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000011292 }
11293
11294 store(get_gpr_dw0(r1), mkexpr(op1));
11295
11296 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(2)));
11297 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(2)));
11298 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(2)));
11299
florian6820ba52012-07-26 02:01:50 +000011300 iterate();
florian730448f2012-02-04 17:07:07 +000011301
11302 return "trtt";
11303}
11304
11305static HChar *
11306s390_irgen_TR(UChar length, IRTemp start1, IRTemp start2)
11307{
florianf87d4fb2012-05-05 02:55:24 +000011308 IRTemp len = newTemp(Ity_I64);
florian730448f2012-02-04 17:07:07 +000011309
florianf87d4fb2012-05-05 02:55:24 +000011310 assign(len, mkU64(length));
11311 s390_irgen_TR_EX(len, start1, start2);
florian730448f2012-02-04 17:07:07 +000011312
11313 return "tr";
11314}
11315
11316static HChar *
11317s390_irgen_TRE(UChar r1,UChar r2)
11318{
11319 IRTemp src_addr, tab_addr, src_len, test_byte;
11320 src_addr = newTemp(Ity_I64);
11321 tab_addr = newTemp(Ity_I64);
11322 src_len = newTemp(Ity_I64);
11323 test_byte = newTemp(Ity_I8);
11324
11325 assign(src_addr, get_gpr_dw0(r1));
11326 assign(src_len, get_gpr_dw0(r1+1));
11327 assign(tab_addr, get_gpr_dw0(r2));
11328 assign(test_byte, get_gpr_b7(0));
11329
11330 IRTemp op = newTemp(Ity_I8);
11331 IRTemp op1 = newTemp(Ity_I8);
11332 IRTemp result = newTemp(Ity_I64);
11333
11334 /* End of source string? We're done; proceed to next insn */
11335 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000011336 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000011337
11338 /* Load character from source string and compare with test byte */
11339 assign(op, load(Ity_I8, mkexpr(src_addr)));
11340
11341 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011342 next_insn_if(binop(Iop_CmpEQ8, mkexpr(op), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000011343
11344 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
11345 mkexpr(tab_addr)));
11346
11347 assign(op1, load(Ity_I8, mkexpr(result)));
11348
11349 store(get_gpr_dw0(r1), mkexpr(op1));
11350 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
11351 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
11352
florian6820ba52012-07-26 02:01:50 +000011353 iterate();
florian730448f2012-02-04 17:07:07 +000011354
11355 return "tre";
11356}
11357
floriana0100c92012-07-20 00:06:35 +000011358static IRExpr *
11359s390_call_cu21(IRExpr *srcval, IRExpr *low_surrogate)
11360{
11361 IRExpr **args, *call;
11362 args = mkIRExprVec_2(srcval, low_surrogate);
11363 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
11364 "s390_do_cu21", &s390_do_cu21, args);
11365
11366 /* Nothing is excluded from definedness checking. */
11367 call->Iex.CCall.cee->mcx_mask = 0;
11368
11369 return call;
11370}
11371
11372static HChar *
11373s390_irgen_CU21(UChar m3, UChar r1, UChar r2)
11374{
11375 IRTemp addr1 = newTemp(Ity_I64);
11376 IRTemp addr2 = newTemp(Ity_I64);
11377 IRTemp len1 = newTemp(Ity_I64);
11378 IRTemp len2 = newTemp(Ity_I64);
11379
11380 assign(addr1, get_gpr_dw0(r1));
11381 assign(addr2, get_gpr_dw0(r2));
11382 assign(len1, get_gpr_dw0(r1 + 1));
11383 assign(len2, get_gpr_dw0(r2 + 1));
11384
11385 /* We're processing the 2nd operand 2 bytes at a time. Therefore, if
11386 there are less than 2 bytes left, then the 2nd operand is exhausted
11387 and we're done here. cc = 0 */
11388 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000011389 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(2)));
floriana0100c92012-07-20 00:06:35 +000011390
11391 /* There are at least two bytes there. Read them. */
11392 IRTemp srcval = newTemp(Ity_I32);
11393 assign(srcval, unop(Iop_16Uto32, load(Ity_I16, mkexpr(addr2))));
11394
11395 /* Find out whether this is a high surrogate. I.e. SRCVAL lies
11396 inside the interval [0xd800 - 0xdbff] */
11397 IRTemp is_high_surrogate = newTemp(Ity_I32);
11398 IRExpr *flag1 = mkite(binop(Iop_CmpLE32U, mkU32(0xd800), mkexpr(srcval)),
11399 mkU32(1), mkU32(0));
11400 IRExpr *flag2 = mkite(binop(Iop_CmpLE32U, mkexpr(srcval), mkU32(0xdbff)),
11401 mkU32(1), mkU32(0));
11402 assign(is_high_surrogate, binop(Iop_And32, flag1, flag2));
11403
11404 /* If SRCVAL is a high surrogate and there are less than 4 bytes left,
11405 then the 2nd operand is exhausted and we're done here. cc = 0 */
11406 IRExpr *not_enough_bytes =
11407 mkite(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)), mkU32(1), mkU32(0));
11408
florian6820ba52012-07-26 02:01:50 +000011409 next_insn_if(binop(Iop_CmpEQ32,
11410 binop(Iop_And32, mkexpr(is_high_surrogate),
11411 not_enough_bytes), mkU32(1)));
floriana0100c92012-07-20 00:06:35 +000011412
11413 /* The 2nd operand is not exhausted. If the first 2 bytes are a high
11414 surrogate, read the next two bytes (low surrogate). */
11415 IRTemp low_surrogate = newTemp(Ity_I32);
11416 IRExpr *low_surrogate_addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
11417
11418 assign(low_surrogate,
11419 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
11420 unop(Iop_16Uto32, load(Ity_I16, low_surrogate_addr)),
11421 mkU32(0))); // any value is fine; it will not be used
11422
11423 /* Call the helper */
11424 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000011425 assign(retval, s390_call_cu21(unop(Iop_32Uto64, mkexpr(srcval)),
11426 unop(Iop_32Uto64, mkexpr(low_surrogate))));
floriana0100c92012-07-20 00:06:35 +000011427
11428 /* Before we can test whether the 1st operand is exhausted we need to
11429 test for an invalid low surrogate. Because cc=2 outranks cc=1. */
11430 if (s390_host_has_etf3 && (m3 & 0x1) == 1) {
11431 IRExpr *invalid_low_surrogate =
11432 binop(Iop_And64, mkexpr(retval), mkU64(0xff));
11433
11434 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +000011435 next_insn_if(binop(Iop_CmpEQ64, invalid_low_surrogate, mkU64(1)));
floriana0100c92012-07-20 00:06:35 +000011436 }
11437
11438 /* Now test whether the 1st operand is exhausted */
11439 IRTemp num_bytes = newTemp(Ity_I64);
11440 assign(num_bytes, binop(Iop_And64,
11441 binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
11442 mkU64(0xff)));
11443 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011444 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
floriana0100c92012-07-20 00:06:35 +000011445
11446 /* Extract the bytes to be stored at addr1 */
11447 IRTemp data = newTemp(Ity_I64);
11448 assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
11449
11450 /* To store the bytes construct 4 dirty helper calls. The helper calls
11451 are guarded (num_bytes == 1, num_bytes == 2, etc) such that only
11452 one of them will be called at runtime. */
11453 int i;
11454 for (i = 1; i <= 4; ++i) {
11455 IRDirty *d;
11456
11457 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
11458 &s390x_dirtyhelper_CUxy,
11459 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
11460 mkexpr(num_bytes)));
11461 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
11462 d->mFx = Ifx_Write;
11463 d->mAddr = mkexpr(addr1);
11464 d->mSize = i;
11465 stmt(IRStmt_Dirty(d));
11466 }
11467
11468 /* Update source address and length */
11469 IRTemp num_src_bytes = newTemp(Ity_I64);
11470 assign(num_src_bytes,
11471 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
11472 mkU64(4), mkU64(2)));
11473 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
11474 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkexpr(num_src_bytes)));
11475
11476 /* Update destination address and length */
11477 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
11478 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
11479
florian6820ba52012-07-26 02:01:50 +000011480 iterate();
floriana0100c92012-07-20 00:06:35 +000011481
11482 return "cu21";
11483}
11484
florian2a415a12012-07-21 17:41:36 +000011485static IRExpr *
11486s390_call_cu24(IRExpr *srcval, IRExpr *low_surrogate)
11487{
11488 IRExpr **args, *call;
11489 args = mkIRExprVec_2(srcval, low_surrogate);
11490 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
11491 "s390_do_cu24", &s390_do_cu24, args);
11492
11493 /* Nothing is excluded from definedness checking. */
11494 call->Iex.CCall.cee->mcx_mask = 0;
11495
11496 return call;
11497}
11498
11499static HChar *
11500s390_irgen_CU24(UChar m3, UChar r1, UChar r2)
11501{
11502 IRTemp addr1 = newTemp(Ity_I64);
11503 IRTemp addr2 = newTemp(Ity_I64);
11504 IRTemp len1 = newTemp(Ity_I64);
11505 IRTemp len2 = newTemp(Ity_I64);
11506
11507 assign(addr1, get_gpr_dw0(r1));
11508 assign(addr2, get_gpr_dw0(r2));
11509 assign(len1, get_gpr_dw0(r1 + 1));
11510 assign(len2, get_gpr_dw0(r2 + 1));
11511
11512 /* We're processing the 2nd operand 2 bytes at a time. Therefore, if
11513 there are less than 2 bytes left, then the 2nd operand is exhausted
11514 and we're done here. cc = 0 */
11515 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000011516 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(2)));
florian2a415a12012-07-21 17:41:36 +000011517
11518 /* There are at least two bytes there. Read them. */
11519 IRTemp srcval = newTemp(Ity_I32);
11520 assign(srcval, unop(Iop_16Uto32, load(Ity_I16, mkexpr(addr2))));
11521
11522 /* Find out whether this is a high surrogate. I.e. SRCVAL lies
11523 inside the interval [0xd800 - 0xdbff] */
11524 IRTemp is_high_surrogate = newTemp(Ity_I32);
11525 IRExpr *flag1 = mkite(binop(Iop_CmpLE32U, mkU32(0xd800), mkexpr(srcval)),
11526 mkU32(1), mkU32(0));
11527 IRExpr *flag2 = mkite(binop(Iop_CmpLE32U, mkexpr(srcval), mkU32(0xdbff)),
11528 mkU32(1), mkU32(0));
11529 assign(is_high_surrogate, binop(Iop_And32, flag1, flag2));
11530
11531 /* If SRCVAL is a high surrogate and there are less than 4 bytes left,
11532 then the 2nd operand is exhausted and we're done here. cc = 0 */
11533 IRExpr *not_enough_bytes =
11534 mkite(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)), mkU32(1), mkU32(0));
11535
florian6820ba52012-07-26 02:01:50 +000011536 next_insn_if(binop(Iop_CmpEQ32,
11537 binop(Iop_And32, mkexpr(is_high_surrogate),
11538 not_enough_bytes),
11539 mkU32(1)));
florian2a415a12012-07-21 17:41:36 +000011540
11541 /* The 2nd operand is not exhausted. If the first 2 bytes are a high
11542 surrogate, read the next two bytes (low surrogate). */
11543 IRTemp low_surrogate = newTemp(Ity_I32);
11544 IRExpr *low_surrogate_addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
11545
11546 assign(low_surrogate,
11547 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
11548 unop(Iop_16Uto32, load(Ity_I16, low_surrogate_addr)),
11549 mkU32(0))); // any value is fine; it will not be used
11550
11551 /* Call the helper */
11552 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000011553 assign(retval, s390_call_cu24(unop(Iop_32Uto64, mkexpr(srcval)),
11554 unop(Iop_32Uto64, mkexpr(low_surrogate))));
florian2a415a12012-07-21 17:41:36 +000011555
11556 /* Before we can test whether the 1st operand is exhausted we need to
11557 test for an invalid low surrogate. Because cc=2 outranks cc=1. */
11558 if (s390_host_has_etf3 && (m3 & 0x1) == 1) {
11559 IRExpr *invalid_low_surrogate =
11560 binop(Iop_And64, mkexpr(retval), mkU64(0xff));
11561
11562 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +000011563 next_insn_if(binop(Iop_CmpEQ64, invalid_low_surrogate, mkU64(1)));
florian2a415a12012-07-21 17:41:36 +000011564 }
11565
11566 /* Now test whether the 1st operand is exhausted */
11567 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011568 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkU64(4)));
florian2a415a12012-07-21 17:41:36 +000011569
11570 /* Extract the bytes to be stored at addr1 */
11571 IRExpr *data = unop(Iop_64to32, binop(Iop_Shr64, mkexpr(retval), mkU8(8)));
11572
11573 store(mkexpr(addr1), data);
11574
11575 /* Update source address and length */
11576 IRTemp num_src_bytes = newTemp(Ity_I64);
11577 assign(num_src_bytes,
11578 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
11579 mkU64(4), mkU64(2)));
11580 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
11581 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkexpr(num_src_bytes)));
11582
11583 /* Update destination address and length */
11584 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(4)));
11585 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkU64(4)));
11586
florian6820ba52012-07-26 02:01:50 +000011587 iterate();
florian2a415a12012-07-21 17:41:36 +000011588
11589 return "cu24";
11590}
floriana4384a32011-08-11 16:58:45 +000011591
florian956194b2012-07-28 22:18:32 +000011592static IRExpr *
11593s390_call_cu42(IRExpr *srcval)
11594{
11595 IRExpr **args, *call;
11596 args = mkIRExprVec_1(srcval);
11597 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
11598 "s390_do_cu42", &s390_do_cu42, args);
11599
11600 /* Nothing is excluded from definedness checking. */
11601 call->Iex.CCall.cee->mcx_mask = 0;
11602
11603 return call;
11604}
11605
11606static HChar *
11607s390_irgen_CU42(UChar r1, UChar r2)
11608{
11609 IRTemp addr1 = newTemp(Ity_I64);
11610 IRTemp addr2 = newTemp(Ity_I64);
11611 IRTemp len1 = newTemp(Ity_I64);
11612 IRTemp len2 = newTemp(Ity_I64);
11613
11614 assign(addr1, get_gpr_dw0(r1));
11615 assign(addr2, get_gpr_dw0(r2));
11616 assign(len1, get_gpr_dw0(r1 + 1));
11617 assign(len2, get_gpr_dw0(r2 + 1));
11618
11619 /* We're processing the 2nd operand 4 bytes at a time. Therefore, if
11620 there are less than 4 bytes left, then the 2nd operand is exhausted
11621 and we're done here. cc = 0 */
11622 s390_cc_set(0);
11623 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)));
11624
11625 /* Read the 2nd operand. */
11626 IRTemp srcval = newTemp(Ity_I32);
11627 assign(srcval, load(Ity_I32, mkexpr(addr2)));
11628
11629 /* Call the helper */
11630 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000011631 assign(retval, s390_call_cu42(unop(Iop_32Uto64, mkexpr(srcval))));
florian956194b2012-07-28 22:18:32 +000011632
11633 /* If the UTF-32 character was invalid, set cc=2 and we're done.
11634 cc=2 outranks cc=1 (1st operand exhausted) */
11635 IRExpr *invalid_character = binop(Iop_And64, mkexpr(retval), mkU64(0xff));
11636
11637 s390_cc_set(2);
11638 next_insn_if(binop(Iop_CmpEQ64, invalid_character, mkU64(1)));
11639
11640 /* Now test whether the 1st operand is exhausted */
11641 IRTemp num_bytes = newTemp(Ity_I64);
11642 assign(num_bytes, binop(Iop_And64,
11643 binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
11644 mkU64(0xff)));
11645 s390_cc_set(1);
11646 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
11647
11648 /* Extract the bytes to be stored at addr1 */
11649 IRTemp data = newTemp(Ity_I64);
11650 assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
11651
11652 /* To store the bytes construct 2 dirty helper calls. The helper calls
11653 are guarded (num_bytes == 2 and num_bytes == 4, respectively) such
11654 that only one of them will be called at runtime. */
11655
11656 Int i;
11657 for (i = 2; i <= 4; ++i) {
11658 IRDirty *d;
11659
11660 if (i == 3) continue; // skip this one
11661
11662 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
11663 &s390x_dirtyhelper_CUxy,
11664 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
11665 mkexpr(num_bytes)));
11666 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
11667 d->mFx = Ifx_Write;
11668 d->mAddr = mkexpr(addr1);
11669 d->mSize = i;
11670 stmt(IRStmt_Dirty(d));
11671 }
11672
11673 /* Update source address and length */
11674 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkU64(4)));
11675 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkU64(4)));
11676
11677 /* Update destination address and length */
11678 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
11679 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
11680
11681 iterate();
11682
11683 return "cu42";
11684}
11685
florian6d9b9b22012-08-03 18:35:39 +000011686static IRExpr *
florianaf2194f2012-08-06 00:07:54 +000011687s390_call_cu41(IRExpr *srcval)
11688{
11689 IRExpr **args, *call;
11690 args = mkIRExprVec_1(srcval);
11691 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
11692 "s390_do_cu41", &s390_do_cu41, args);
11693
11694 /* Nothing is excluded from definedness checking. */
11695 call->Iex.CCall.cee->mcx_mask = 0;
11696
11697 return call;
11698}
11699
11700static HChar *
11701s390_irgen_CU41(UChar r1, UChar r2)
11702{
11703 IRTemp addr1 = newTemp(Ity_I64);
11704 IRTemp addr2 = newTemp(Ity_I64);
11705 IRTemp len1 = newTemp(Ity_I64);
11706 IRTemp len2 = newTemp(Ity_I64);
11707
11708 assign(addr1, get_gpr_dw0(r1));
11709 assign(addr2, get_gpr_dw0(r2));
11710 assign(len1, get_gpr_dw0(r1 + 1));
11711 assign(len2, get_gpr_dw0(r2 + 1));
11712
11713 /* We're processing the 2nd operand 4 bytes at a time. Therefore, if
11714 there are less than 4 bytes left, then the 2nd operand is exhausted
11715 and we're done here. cc = 0 */
11716 s390_cc_set(0);
11717 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)));
11718
11719 /* Read the 2nd operand. */
11720 IRTemp srcval = newTemp(Ity_I32);
11721 assign(srcval, load(Ity_I32, mkexpr(addr2)));
11722
11723 /* Call the helper */
11724 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000011725 assign(retval, s390_call_cu41(unop(Iop_32Uto64, mkexpr(srcval))));
florianaf2194f2012-08-06 00:07:54 +000011726
11727 /* If the UTF-32 character was invalid, set cc=2 and we're done.
11728 cc=2 outranks cc=1 (1st operand exhausted) */
11729 IRExpr *invalid_character = binop(Iop_And64, mkexpr(retval), mkU64(0xff));
11730
11731 s390_cc_set(2);
11732 next_insn_if(binop(Iop_CmpEQ64, invalid_character, mkU64(1)));
11733
11734 /* Now test whether the 1st operand is exhausted */
11735 IRTemp num_bytes = newTemp(Ity_I64);
11736 assign(num_bytes, binop(Iop_And64,
11737 binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
11738 mkU64(0xff)));
11739 s390_cc_set(1);
11740 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
11741
11742 /* Extract the bytes to be stored at addr1 */
11743 IRTemp data = newTemp(Ity_I64);
11744 assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
11745
11746 /* To store the bytes construct 4 dirty helper calls. The helper calls
11747 are guarded (num_bytes == 1, num_bytes == 2, etc) such that only
11748 one of them will be called at runtime. */
11749 int i;
11750 for (i = 1; i <= 4; ++i) {
11751 IRDirty *d;
11752
11753 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
11754 &s390x_dirtyhelper_CUxy,
11755 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
11756 mkexpr(num_bytes)));
11757 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
11758 d->mFx = Ifx_Write;
11759 d->mAddr = mkexpr(addr1);
11760 d->mSize = i;
11761 stmt(IRStmt_Dirty(d));
11762 }
11763
11764 /* Update source address and length */
11765 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkU64(4)));
11766 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkU64(4)));
11767
11768 /* Update destination address and length */
11769 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
11770 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
11771
11772 iterate();
11773
11774 return "cu41";
11775}
11776
11777static IRExpr *
florian3f8a96a2012-08-05 02:59:55 +000011778s390_call_cu12_cu14_helper1(IRExpr *byte1, IRExpr *etf3_and_m3_is_1)
florian6d9b9b22012-08-03 18:35:39 +000011779{
11780 IRExpr **args, *call;
11781 args = mkIRExprVec_2(byte1, etf3_and_m3_is_1);
florian3f8a96a2012-08-05 02:59:55 +000011782 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/, "s390_do_cu12_cu14_helper1",
11783 &s390_do_cu12_cu14_helper1, args);
florian6d9b9b22012-08-03 18:35:39 +000011784
11785 /* Nothing is excluded from definedness checking. */
11786 call->Iex.CCall.cee->mcx_mask = 0;
11787
11788 return call;
11789}
11790
11791static IRExpr *
11792s390_call_cu12_helper2(IRExpr *byte1, IRExpr *byte2, IRExpr *byte3,
11793 IRExpr *byte4, IRExpr *stuff)
11794{
11795 IRExpr **args, *call;
11796 args = mkIRExprVec_5(byte1, byte2, byte3, byte4, stuff);
11797 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
11798 "s390_do_cu12_helper2", &s390_do_cu12_helper2, args);
11799
11800 /* Nothing is excluded from definedness checking. */
11801 call->Iex.CCall.cee->mcx_mask = 0;
11802
11803 return call;
11804}
11805
florian3f8a96a2012-08-05 02:59:55 +000011806static IRExpr *
11807s390_call_cu14_helper2(IRExpr *byte1, IRExpr *byte2, IRExpr *byte3,
11808 IRExpr *byte4, IRExpr *stuff)
11809{
11810 IRExpr **args, *call;
11811 args = mkIRExprVec_5(byte1, byte2, byte3, byte4, stuff);
11812 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
11813 "s390_do_cu14_helper2", &s390_do_cu14_helper2, args);
11814
11815 /* Nothing is excluded from definedness checking. */
11816 call->Iex.CCall.cee->mcx_mask = 0;
11817
11818 return call;
11819}
11820
11821static void
11822s390_irgen_cu12_cu14(UChar m3, UChar r1, UChar r2, Bool is_cu12)
florian6d9b9b22012-08-03 18:35:39 +000011823{
11824 IRTemp addr1 = newTemp(Ity_I64);
11825 IRTemp addr2 = newTemp(Ity_I64);
11826 IRTemp len1 = newTemp(Ity_I64);
11827 IRTemp len2 = newTemp(Ity_I64);
11828
11829 assign(addr1, get_gpr_dw0(r1));
11830 assign(addr2, get_gpr_dw0(r2));
11831 assign(len1, get_gpr_dw0(r1 + 1));
11832 assign(len2, get_gpr_dw0(r2 + 1));
11833
11834 UInt extended_checking = s390_host_has_etf3 && (m3 & 0x1) == 1;
11835
11836 /* We're processing the 2nd operand 1 byte at a time. Therefore, if
11837 there is less than 1 byte left, then the 2nd operand is exhausted
11838 and we're done here. cc = 0 */
11839 s390_cc_set(0);
11840 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(1)));
11841
11842 /* There is at least one byte there. Read it. */
florian11b8ee82012-08-06 13:35:33 +000011843 IRTemp byte1 = newTemp(Ity_I64);
11844 assign(byte1, unop(Iop_8Uto64, load(Ity_I8, mkexpr(addr2))));
florian6d9b9b22012-08-03 18:35:39 +000011845
11846 /* Call the helper to get number of bytes and invalid byte indicator */
11847 IRTemp retval1 = newTemp(Ity_I64);
florian3f8a96a2012-08-05 02:59:55 +000011848 assign(retval1, s390_call_cu12_cu14_helper1(mkexpr(byte1),
florian11b8ee82012-08-06 13:35:33 +000011849 mkU64(extended_checking)));
florian6d9b9b22012-08-03 18:35:39 +000011850
11851 /* Check for invalid 1st byte */
11852 IRExpr *is_invalid = unop(Iop_64to1, mkexpr(retval1));
11853 s390_cc_set(2);
11854 next_insn_if(is_invalid);
11855
11856 /* How many bytes do we have to read? */
11857 IRTemp num_src_bytes = newTemp(Ity_I64);
11858 assign(num_src_bytes, binop(Iop_Shr64, mkexpr(retval1), mkU8(8)));
11859
11860 /* Now test whether the 2nd operand is exhausted */
11861 s390_cc_set(0);
11862 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkexpr(num_src_bytes)));
11863
11864 /* Read the remaining bytes */
11865 IRExpr *cond, *addr, *byte2, *byte3, *byte4;
11866
11867 cond = binop(Iop_CmpLE64U, mkU64(2), mkexpr(num_src_bytes));
11868 addr = binop(Iop_Add64, mkexpr(addr2), mkU64(1));
florian11b8ee82012-08-06 13:35:33 +000011869 byte2 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
florian6d9b9b22012-08-03 18:35:39 +000011870 cond = binop(Iop_CmpLE64U, mkU64(3), mkexpr(num_src_bytes));
11871 addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
florian11b8ee82012-08-06 13:35:33 +000011872 byte3 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
florian6d9b9b22012-08-03 18:35:39 +000011873 cond = binop(Iop_CmpLE64U, mkU64(4), mkexpr(num_src_bytes));
11874 addr = binop(Iop_Add64, mkexpr(addr2), mkU64(3));
florian11b8ee82012-08-06 13:35:33 +000011875 byte4 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
florian6d9b9b22012-08-03 18:35:39 +000011876
11877 /* Call the helper to get the converted value and invalid byte indicator.
11878 We can pass at most 5 arguments; therefore some encoding is needed
11879 here */
11880 IRExpr *stuff = binop(Iop_Or64,
11881 binop(Iop_Shl64, mkexpr(num_src_bytes), mkU8(1)),
11882 mkU64(extended_checking));
11883 IRTemp retval2 = newTemp(Ity_I64);
florian3f8a96a2012-08-05 02:59:55 +000011884
11885 if (is_cu12) {
11886 assign(retval2, s390_call_cu12_helper2(mkexpr(byte1), byte2, byte3,
11887 byte4, stuff));
11888 } else {
11889 assign(retval2, s390_call_cu14_helper2(mkexpr(byte1), byte2, byte3,
11890 byte4, stuff));
11891 }
florian6d9b9b22012-08-03 18:35:39 +000011892
11893 /* Check for invalid character */
11894 s390_cc_set(2);
11895 is_invalid = unop(Iop_64to1, mkexpr(retval2));
11896 next_insn_if(is_invalid);
11897
11898 /* Now test whether the 1st operand is exhausted */
11899 IRTemp num_bytes = newTemp(Ity_I64);
11900 assign(num_bytes, binop(Iop_And64,
11901 binop(Iop_Shr64, mkexpr(retval2), mkU8(8)),
11902 mkU64(0xff)));
11903 s390_cc_set(1);
11904 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
11905
11906 /* Extract the bytes to be stored at addr1 */
11907 IRTemp data = newTemp(Ity_I64);
11908 assign(data, binop(Iop_Shr64, mkexpr(retval2), mkU8(16)));
11909
florian3f8a96a2012-08-05 02:59:55 +000011910 if (is_cu12) {
11911 /* To store the bytes construct 2 dirty helper calls. The helper calls
11912 are guarded (num_bytes == 2 and num_bytes == 4, respectively) such
11913 that only one of them will be called at runtime. */
florian6d9b9b22012-08-03 18:35:39 +000011914
florian3f8a96a2012-08-05 02:59:55 +000011915 Int i;
11916 for (i = 2; i <= 4; ++i) {
11917 IRDirty *d;
florian6d9b9b22012-08-03 18:35:39 +000011918
florian3f8a96a2012-08-05 02:59:55 +000011919 if (i == 3) continue; // skip this one
florian6d9b9b22012-08-03 18:35:39 +000011920
florian3f8a96a2012-08-05 02:59:55 +000011921 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
11922 &s390x_dirtyhelper_CUxy,
11923 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
11924 mkexpr(num_bytes)));
11925 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
11926 d->mFx = Ifx_Write;
11927 d->mAddr = mkexpr(addr1);
11928 d->mSize = i;
11929 stmt(IRStmt_Dirty(d));
11930 }
11931 } else {
11932 // cu14
11933 store(mkexpr(addr1), unop(Iop_64to32, mkexpr(data)));
florian6d9b9b22012-08-03 18:35:39 +000011934 }
11935
11936 /* Update source address and length */
11937 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
11938 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkexpr(num_src_bytes)));
11939
11940 /* Update destination address and length */
11941 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
11942 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
11943
11944 iterate();
florian3f8a96a2012-08-05 02:59:55 +000011945}
11946
11947static HChar *
11948s390_irgen_CU12(UChar m3, UChar r1, UChar r2)
11949{
11950 s390_irgen_cu12_cu14(m3, r1, r2, /* is_cu12 = */ 1);
florian6d9b9b22012-08-03 18:35:39 +000011951
11952 return "cu12";
11953}
11954
florian3f8a96a2012-08-05 02:59:55 +000011955static HChar *
11956s390_irgen_CU14(UChar m3, UChar r1, UChar r2)
11957{
11958 s390_irgen_cu12_cu14(m3, r1, r2, /* is_cu12 = */ 0);
11959
11960 return "cu14";
11961}
11962
florian8c88cb62012-08-26 18:58:13 +000011963static IRExpr *
11964s390_call_ecag(IRExpr *op2addr)
11965{
11966 IRExpr **args, *call;
11967
11968 args = mkIRExprVec_1(op2addr);
11969 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
11970 "s390_do_ecag", &s390_do_ecag, args);
11971
11972 /* Nothing is excluded from definedness checking. */
11973 call->Iex.CCall.cee->mcx_mask = 0;
11974
11975 return call;
11976}
11977
11978static HChar *
11979s390_irgen_ECAG(UChar r1, UChar r3, IRTemp op2addr)
11980{
11981 if (! s390_host_has_gie) {
11982 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_EMNOTE),
11983 mkU32(EmFail_S390X_ecag)));
11984 put_IA(mkaddr_expr(guest_IA_next_instr));
11985 dis_res->whatNext = Dis_StopHere;
11986 dis_res->jk_StopHere = Ijk_EmFail;
11987 } else {
11988 put_gpr_dw0(r1, s390_call_ecag(mkexpr(op2addr)));
11989 }
11990
11991 return "ecag";
11992}
11993
11994
sewardj2019a972011-03-07 16:04:07 +000011995/*------------------------------------------------------------*/
11996/*--- Build IR for special instructions ---*/
11997/*------------------------------------------------------------*/
11998
florianb4df7682011-07-05 02:09:01 +000011999static void
sewardj2019a972011-03-07 16:04:07 +000012000s390_irgen_client_request(void)
12001{
12002 if (0)
12003 vex_printf("%%R3 = client_request ( %%R2 )\n");
12004
florianf9e1ed72012-04-17 02:41:56 +000012005 Addr64 next = guest_IA_curr_instr + S390_SPECIAL_OP_PREAMBLE_SIZE
12006 + S390_SPECIAL_OP_SIZE;
sewardj2019a972011-03-07 16:04:07 +000012007
florianf9e1ed72012-04-17 02:41:56 +000012008 dis_res->jk_StopHere = Ijk_ClientReq;
sewardj2019a972011-03-07 16:04:07 +000012009 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +000012010
12011 put_IA(mkaddr_expr(next));
sewardj2019a972011-03-07 16:04:07 +000012012}
12013
florianb4df7682011-07-05 02:09:01 +000012014static void
sewardj2019a972011-03-07 16:04:07 +000012015s390_irgen_guest_NRADDR(void)
12016{
12017 if (0)
12018 vex_printf("%%R3 = guest_NRADDR\n");
12019
floriane88b3c92011-07-05 02:48:39 +000012020 put_gpr_dw0(3, IRExpr_Get(S390X_GUEST_OFFSET(guest_NRADDR), Ity_I64));
sewardj2019a972011-03-07 16:04:07 +000012021}
12022
florianb4df7682011-07-05 02:09:01 +000012023static void
sewardj2019a972011-03-07 16:04:07 +000012024s390_irgen_call_noredir(void)
12025{
florianf9e1ed72012-04-17 02:41:56 +000012026 Addr64 next = guest_IA_curr_instr + S390_SPECIAL_OP_PREAMBLE_SIZE
12027 + S390_SPECIAL_OP_SIZE;
12028
sewardj2019a972011-03-07 16:04:07 +000012029 /* Continue after special op */
florianf9e1ed72012-04-17 02:41:56 +000012030 put_gpr_dw0(14, mkaddr_expr(next));
sewardj2019a972011-03-07 16:04:07 +000012031
12032 /* The address is in REG1, all parameters are in the right (guest) places */
florianf9e1ed72012-04-17 02:41:56 +000012033 put_IA(get_gpr_dw0(1));
sewardj2019a972011-03-07 16:04:07 +000012034
12035 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +000012036 dis_res->jk_StopHere = Ijk_NoRedir;
sewardj2019a972011-03-07 16:04:07 +000012037}
12038
12039/* Force proper alignment for the structures below. */
12040#pragma pack(1)
12041
12042
12043static s390_decode_t
12044s390_decode_2byte_and_irgen(UChar *bytes)
12045{
12046 typedef union {
12047 struct {
12048 unsigned int op : 16;
12049 } E;
12050 struct {
12051 unsigned int op : 8;
12052 unsigned int i : 8;
12053 } I;
12054 struct {
12055 unsigned int op : 8;
12056 unsigned int r1 : 4;
12057 unsigned int r2 : 4;
12058 } RR;
12059 } formats;
12060 union {
12061 formats fmt;
12062 UShort value;
12063 } ovl;
12064
12065 vassert(sizeof(formats) == 2);
12066
12067 ((char *)(&ovl.value))[0] = bytes[0];
12068 ((char *)(&ovl.value))[1] = bytes[1];
12069
12070 switch (ovl.value & 0xffff) {
12071 case 0x0101: /* PR */ goto unimplemented;
12072 case 0x0102: /* UPT */ goto unimplemented;
12073 case 0x0104: /* PTFF */ goto unimplemented;
12074 case 0x0107: /* SCKPF */ goto unimplemented;
12075 case 0x010a: /* PFPO */ goto unimplemented;
12076 case 0x010b: /* TAM */ goto unimplemented;
12077 case 0x010c: /* SAM24 */ goto unimplemented;
12078 case 0x010d: /* SAM31 */ goto unimplemented;
12079 case 0x010e: /* SAM64 */ goto unimplemented;
12080 case 0x01ff: /* TRAP2 */ goto unimplemented;
12081 }
12082
12083 switch ((ovl.value & 0xff00) >> 8) {
12084 case 0x04: /* SPM */ goto unimplemented;
12085 case 0x05: /* BALR */ goto unimplemented;
12086 case 0x06: s390_format_RR_RR(s390_irgen_BCTR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12087 goto ok;
12088 case 0x07: s390_format_RR(s390_irgen_BCR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12089 goto ok;
12090 case 0x0a: s390_format_I(s390_irgen_SVC, ovl.fmt.I.i); goto ok;
12091 case 0x0b: /* BSM */ goto unimplemented;
12092 case 0x0c: /* BASSM */ goto unimplemented;
12093 case 0x0d: s390_format_RR_RR(s390_irgen_BASR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12094 goto ok;
florianb0c9a132011-09-08 15:37:39 +000012095 case 0x0e: s390_format_RR(s390_irgen_MVCL, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12096 goto ok;
12097 case 0x0f: s390_format_RR(s390_irgen_CLCL, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12098 goto ok;
sewardj2019a972011-03-07 16:04:07 +000012099 case 0x10: s390_format_RR_RR(s390_irgen_LPR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12100 goto ok;
12101 case 0x11: s390_format_RR_RR(s390_irgen_LNR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12102 goto ok;
12103 case 0x12: s390_format_RR_RR(s390_irgen_LTR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12104 goto ok;
12105 case 0x13: s390_format_RR_RR(s390_irgen_LCR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12106 goto ok;
12107 case 0x14: s390_format_RR_RR(s390_irgen_NR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12108 goto ok;
12109 case 0x15: s390_format_RR_RR(s390_irgen_CLR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12110 goto ok;
12111 case 0x16: s390_format_RR_RR(s390_irgen_OR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12112 goto ok;
12113 case 0x17: s390_format_RR_RR(s390_irgen_XR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12114 goto ok;
12115 case 0x18: s390_format_RR_RR(s390_irgen_LR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12116 goto ok;
12117 case 0x19: s390_format_RR_RR(s390_irgen_CR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12118 goto ok;
12119 case 0x1a: s390_format_RR_RR(s390_irgen_AR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12120 goto ok;
12121 case 0x1b: s390_format_RR_RR(s390_irgen_SR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12122 goto ok;
12123 case 0x1c: s390_format_RR_RR(s390_irgen_MR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12124 goto ok;
12125 case 0x1d: s390_format_RR_RR(s390_irgen_DR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12126 goto ok;
12127 case 0x1e: s390_format_RR_RR(s390_irgen_ALR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12128 goto ok;
12129 case 0x1f: s390_format_RR_RR(s390_irgen_SLR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12130 goto ok;
12131 case 0x20: /* LPDR */ goto unimplemented;
12132 case 0x21: /* LNDR */ goto unimplemented;
12133 case 0x22: /* LTDR */ goto unimplemented;
12134 case 0x23: /* LCDR */ goto unimplemented;
12135 case 0x24: /* HDR */ goto unimplemented;
12136 case 0x25: /* LDXR */ goto unimplemented;
12137 case 0x26: /* MXR */ goto unimplemented;
12138 case 0x27: /* MXDR */ goto unimplemented;
12139 case 0x28: s390_format_RR_FF(s390_irgen_LDR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12140 goto ok;
12141 case 0x29: /* CDR */ goto unimplemented;
12142 case 0x2a: /* ADR */ goto unimplemented;
12143 case 0x2b: /* SDR */ goto unimplemented;
12144 case 0x2c: /* MDR */ goto unimplemented;
12145 case 0x2d: /* DDR */ goto unimplemented;
12146 case 0x2e: /* AWR */ goto unimplemented;
12147 case 0x2f: /* SWR */ goto unimplemented;
12148 case 0x30: /* LPER */ goto unimplemented;
12149 case 0x31: /* LNER */ goto unimplemented;
12150 case 0x32: /* LTER */ goto unimplemented;
12151 case 0x33: /* LCER */ goto unimplemented;
12152 case 0x34: /* HER */ goto unimplemented;
12153 case 0x35: /* LEDR */ goto unimplemented;
12154 case 0x36: /* AXR */ goto unimplemented;
12155 case 0x37: /* SXR */ goto unimplemented;
12156 case 0x38: s390_format_RR_FF(s390_irgen_LER, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12157 goto ok;
12158 case 0x39: /* CER */ goto unimplemented;
12159 case 0x3a: /* AER */ goto unimplemented;
12160 case 0x3b: /* SER */ goto unimplemented;
12161 case 0x3c: /* MDER */ goto unimplemented;
12162 case 0x3d: /* DER */ goto unimplemented;
12163 case 0x3e: /* AUR */ goto unimplemented;
12164 case 0x3f: /* SUR */ goto unimplemented;
12165 }
12166
12167 return S390_DECODE_UNKNOWN_INSN;
12168
12169ok:
12170 return S390_DECODE_OK;
12171
12172unimplemented:
12173 return S390_DECODE_UNIMPLEMENTED_INSN;
12174}
12175
12176static s390_decode_t
12177s390_decode_4byte_and_irgen(UChar *bytes)
12178{
12179 typedef union {
12180 struct {
12181 unsigned int op1 : 8;
12182 unsigned int r1 : 4;
12183 unsigned int op2 : 4;
12184 unsigned int i2 : 16;
12185 } RI;
12186 struct {
12187 unsigned int op : 16;
12188 unsigned int : 8;
12189 unsigned int r1 : 4;
12190 unsigned int r2 : 4;
12191 } RRE;
12192 struct {
12193 unsigned int op : 16;
12194 unsigned int r1 : 4;
12195 unsigned int : 4;
12196 unsigned int r3 : 4;
12197 unsigned int r2 : 4;
12198 } RRF;
12199 struct {
12200 unsigned int op : 16;
florian1c8f7ff2012-09-01 00:12:11 +000012201 unsigned int m3 : 4;
sewardj2019a972011-03-07 16:04:07 +000012202 unsigned int m4 : 4;
12203 unsigned int r1 : 4;
12204 unsigned int r2 : 4;
12205 } RRF2;
12206 struct {
12207 unsigned int op : 16;
12208 unsigned int r3 : 4;
12209 unsigned int : 4;
12210 unsigned int r1 : 4;
12211 unsigned int r2 : 4;
12212 } RRF3;
12213 struct {
12214 unsigned int op : 16;
12215 unsigned int r3 : 4;
12216 unsigned int : 4;
12217 unsigned int r1 : 4;
12218 unsigned int r2 : 4;
12219 } RRR;
12220 struct {
12221 unsigned int op : 16;
12222 unsigned int r3 : 4;
12223 unsigned int : 4;
12224 unsigned int r1 : 4;
12225 unsigned int r2 : 4;
12226 } RRF4;
12227 struct {
12228 unsigned int op : 8;
12229 unsigned int r1 : 4;
12230 unsigned int r3 : 4;
12231 unsigned int b2 : 4;
12232 unsigned int d2 : 12;
12233 } RS;
12234 struct {
12235 unsigned int op : 8;
12236 unsigned int r1 : 4;
12237 unsigned int r3 : 4;
12238 unsigned int i2 : 16;
12239 } RSI;
12240 struct {
12241 unsigned int op : 8;
12242 unsigned int r1 : 4;
12243 unsigned int x2 : 4;
12244 unsigned int b2 : 4;
12245 unsigned int d2 : 12;
12246 } RX;
12247 struct {
12248 unsigned int op : 16;
12249 unsigned int b2 : 4;
12250 unsigned int d2 : 12;
12251 } S;
12252 struct {
12253 unsigned int op : 8;
12254 unsigned int i2 : 8;
12255 unsigned int b1 : 4;
12256 unsigned int d1 : 12;
12257 } SI;
12258 } formats;
12259 union {
12260 formats fmt;
12261 UInt value;
12262 } ovl;
12263
12264 vassert(sizeof(formats) == 4);
12265
12266 ((char *)(&ovl.value))[0] = bytes[0];
12267 ((char *)(&ovl.value))[1] = bytes[1];
12268 ((char *)(&ovl.value))[2] = bytes[2];
12269 ((char *)(&ovl.value))[3] = bytes[3];
12270
12271 switch ((ovl.value & 0xff0f0000) >> 16) {
12272 case 0xa500: s390_format_RI_RU(s390_irgen_IIHH, ovl.fmt.RI.r1,
12273 ovl.fmt.RI.i2); goto ok;
12274 case 0xa501: s390_format_RI_RU(s390_irgen_IIHL, ovl.fmt.RI.r1,
12275 ovl.fmt.RI.i2); goto ok;
12276 case 0xa502: s390_format_RI_RU(s390_irgen_IILH, ovl.fmt.RI.r1,
12277 ovl.fmt.RI.i2); goto ok;
12278 case 0xa503: s390_format_RI_RU(s390_irgen_IILL, ovl.fmt.RI.r1,
12279 ovl.fmt.RI.i2); goto ok;
12280 case 0xa504: s390_format_RI_RU(s390_irgen_NIHH, ovl.fmt.RI.r1,
12281 ovl.fmt.RI.i2); goto ok;
12282 case 0xa505: s390_format_RI_RU(s390_irgen_NIHL, ovl.fmt.RI.r1,
12283 ovl.fmt.RI.i2); goto ok;
12284 case 0xa506: s390_format_RI_RU(s390_irgen_NILH, ovl.fmt.RI.r1,
12285 ovl.fmt.RI.i2); goto ok;
12286 case 0xa507: s390_format_RI_RU(s390_irgen_NILL, ovl.fmt.RI.r1,
12287 ovl.fmt.RI.i2); goto ok;
12288 case 0xa508: s390_format_RI_RU(s390_irgen_OIHH, ovl.fmt.RI.r1,
12289 ovl.fmt.RI.i2); goto ok;
12290 case 0xa509: s390_format_RI_RU(s390_irgen_OIHL, ovl.fmt.RI.r1,
12291 ovl.fmt.RI.i2); goto ok;
12292 case 0xa50a: s390_format_RI_RU(s390_irgen_OILH, ovl.fmt.RI.r1,
12293 ovl.fmt.RI.i2); goto ok;
12294 case 0xa50b: s390_format_RI_RU(s390_irgen_OILL, ovl.fmt.RI.r1,
12295 ovl.fmt.RI.i2); goto ok;
12296 case 0xa50c: s390_format_RI_RU(s390_irgen_LLIHH, ovl.fmt.RI.r1,
12297 ovl.fmt.RI.i2); goto ok;
12298 case 0xa50d: s390_format_RI_RU(s390_irgen_LLIHL, ovl.fmt.RI.r1,
12299 ovl.fmt.RI.i2); goto ok;
12300 case 0xa50e: s390_format_RI_RU(s390_irgen_LLILH, ovl.fmt.RI.r1,
12301 ovl.fmt.RI.i2); goto ok;
12302 case 0xa50f: s390_format_RI_RU(s390_irgen_LLILL, ovl.fmt.RI.r1,
12303 ovl.fmt.RI.i2); goto ok;
12304 case 0xa700: s390_format_RI_RU(s390_irgen_TMLH, ovl.fmt.RI.r1,
12305 ovl.fmt.RI.i2); goto ok;
12306 case 0xa701: s390_format_RI_RU(s390_irgen_TMLL, ovl.fmt.RI.r1,
12307 ovl.fmt.RI.i2); goto ok;
12308 case 0xa702: s390_format_RI_RU(s390_irgen_TMHH, ovl.fmt.RI.r1,
12309 ovl.fmt.RI.i2); goto ok;
12310 case 0xa703: s390_format_RI_RU(s390_irgen_TMHL, ovl.fmt.RI.r1,
12311 ovl.fmt.RI.i2); goto ok;
12312 case 0xa704: s390_format_RI(s390_irgen_BRC, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
12313 goto ok;
12314 case 0xa705: s390_format_RI_RP(s390_irgen_BRAS, ovl.fmt.RI.r1,
12315 ovl.fmt.RI.i2); goto ok;
12316 case 0xa706: s390_format_RI_RP(s390_irgen_BRCT, ovl.fmt.RI.r1,
12317 ovl.fmt.RI.i2); goto ok;
12318 case 0xa707: s390_format_RI_RP(s390_irgen_BRCTG, ovl.fmt.RI.r1,
12319 ovl.fmt.RI.i2); goto ok;
12320 case 0xa708: s390_format_RI_RI(s390_irgen_LHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
12321 goto ok;
12322 case 0xa709: s390_format_RI_RI(s390_irgen_LGHI, ovl.fmt.RI.r1,
12323 ovl.fmt.RI.i2); goto ok;
12324 case 0xa70a: s390_format_RI_RI(s390_irgen_AHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
12325 goto ok;
12326 case 0xa70b: s390_format_RI_RI(s390_irgen_AGHI, ovl.fmt.RI.r1,
12327 ovl.fmt.RI.i2); goto ok;
12328 case 0xa70c: s390_format_RI_RI(s390_irgen_MHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
12329 goto ok;
12330 case 0xa70d: s390_format_RI_RI(s390_irgen_MGHI, ovl.fmt.RI.r1,
12331 ovl.fmt.RI.i2); goto ok;
12332 case 0xa70e: s390_format_RI_RI(s390_irgen_CHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
12333 goto ok;
12334 case 0xa70f: s390_format_RI_RI(s390_irgen_CGHI, ovl.fmt.RI.r1,
12335 ovl.fmt.RI.i2); goto ok;
12336 }
12337
12338 switch ((ovl.value & 0xffff0000) >> 16) {
12339 case 0x8000: /* SSM */ goto unimplemented;
12340 case 0x8200: /* LPSW */ goto unimplemented;
florian7700fc92012-01-16 17:25:55 +000012341 case 0x9300: /* TS */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000012342 case 0xb202: /* STIDP */ goto unimplemented;
12343 case 0xb204: /* SCK */ goto unimplemented;
florian7700fc92012-01-16 17:25:55 +000012344 case 0xb205: s390_format_S_RD(s390_irgen_STCK, ovl.fmt.S.b2, ovl.fmt.S.d2);
12345 goto ok;
sewardj2019a972011-03-07 16:04:07 +000012346 case 0xb206: /* SCKC */ goto unimplemented;
12347 case 0xb207: /* STCKC */ goto unimplemented;
12348 case 0xb208: /* SPT */ goto unimplemented;
12349 case 0xb209: /* STPT */ goto unimplemented;
12350 case 0xb20a: /* SPKA */ goto unimplemented;
12351 case 0xb20b: /* IPK */ goto unimplemented;
12352 case 0xb20d: /* PTLB */ goto unimplemented;
12353 case 0xb210: /* SPX */ goto unimplemented;
12354 case 0xb211: /* STPX */ goto unimplemented;
12355 case 0xb212: /* STAP */ goto unimplemented;
12356 case 0xb214: /* SIE */ goto unimplemented;
12357 case 0xb218: /* PC */ goto unimplemented;
12358 case 0xb219: /* SAC */ goto unimplemented;
12359 case 0xb21a: /* CFC */ goto unimplemented;
12360 case 0xb221: /* IPTE */ goto unimplemented;
12361 case 0xb222: s390_format_RRE_R0(s390_irgen_IPM, ovl.fmt.RRE.r1); goto ok;
12362 case 0xb223: /* IVSK */ goto unimplemented;
12363 case 0xb224: /* IAC */ goto unimplemented;
12364 case 0xb225: /* SSAR */ goto unimplemented;
12365 case 0xb226: /* EPAR */ goto unimplemented;
12366 case 0xb227: /* ESAR */ goto unimplemented;
12367 case 0xb228: /* PT */ goto unimplemented;
12368 case 0xb229: /* ISKE */ goto unimplemented;
12369 case 0xb22a: /* RRBE */ goto unimplemented;
12370 case 0xb22b: /* SSKE */ goto unimplemented;
12371 case 0xb22c: /* TB */ goto unimplemented;
12372 case 0xb22d: /* DXR */ goto unimplemented;
12373 case 0xb22e: /* PGIN */ goto unimplemented;
12374 case 0xb22f: /* PGOUT */ goto unimplemented;
12375 case 0xb230: /* CSCH */ goto unimplemented;
12376 case 0xb231: /* HSCH */ goto unimplemented;
12377 case 0xb232: /* MSCH */ goto unimplemented;
12378 case 0xb233: /* SSCH */ goto unimplemented;
12379 case 0xb234: /* STSCH */ goto unimplemented;
12380 case 0xb235: /* TSCH */ goto unimplemented;
12381 case 0xb236: /* TPI */ goto unimplemented;
12382 case 0xb237: /* SAL */ goto unimplemented;
12383 case 0xb238: /* RSCH */ goto unimplemented;
12384 case 0xb239: /* STCRW */ goto unimplemented;
12385 case 0xb23a: /* STCPS */ goto unimplemented;
12386 case 0xb23b: /* RCHP */ goto unimplemented;
12387 case 0xb23c: /* SCHM */ goto unimplemented;
12388 case 0xb240: /* BAKR */ goto unimplemented;
floriana4384a32011-08-11 16:58:45 +000012389 case 0xb241: s390_format_RRE(s390_irgen_CKSM, ovl.fmt.RRE.r1,
12390 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000012391 case 0xb244: /* SQDR */ goto unimplemented;
12392 case 0xb245: /* SQER */ goto unimplemented;
12393 case 0xb246: /* STURA */ goto unimplemented;
12394 case 0xb247: /* MSTA */ goto unimplemented;
12395 case 0xb248: /* PALB */ goto unimplemented;
12396 case 0xb249: /* EREG */ goto unimplemented;
12397 case 0xb24a: /* ESTA */ goto unimplemented;
12398 case 0xb24b: /* LURA */ goto unimplemented;
12399 case 0xb24c: /* TAR */ goto unimplemented;
12400 case 0xb24d: s390_format_RRE(s390_irgen_CPYA, ovl.fmt.RRE.r1,
12401 ovl.fmt.RRE.r2); goto ok;
12402 case 0xb24e: s390_format_RRE(s390_irgen_SAR, ovl.fmt.RRE.r1, ovl.fmt.RRE.r2);
12403 goto ok;
12404 case 0xb24f: s390_format_RRE(s390_irgen_EAR, ovl.fmt.RRE.r1, ovl.fmt.RRE.r2);
12405 goto ok;
12406 case 0xb250: /* CSP */ goto unimplemented;
12407 case 0xb252: s390_format_RRE_RR(s390_irgen_MSR, ovl.fmt.RRE.r1,
12408 ovl.fmt.RRE.r2); goto ok;
12409 case 0xb254: /* MVPG */ goto unimplemented;
12410 case 0xb255: s390_format_RRE_RR(s390_irgen_MVST, ovl.fmt.RRE.r1,
12411 ovl.fmt.RRE.r2); goto ok;
12412 case 0xb257: /* CUSE */ goto unimplemented;
12413 case 0xb258: /* BSG */ goto unimplemented;
12414 case 0xb25a: /* BSA */ goto unimplemented;
12415 case 0xb25d: s390_format_RRE_RR(s390_irgen_CLST, ovl.fmt.RRE.r1,
12416 ovl.fmt.RRE.r2); goto ok;
12417 case 0xb25e: s390_format_RRE_RR(s390_irgen_SRST, ovl.fmt.RRE.r1,
12418 ovl.fmt.RRE.r2); goto ok;
12419 case 0xb263: /* CMPSC */ goto unimplemented;
12420 case 0xb274: /* SIGA */ goto unimplemented;
12421 case 0xb276: /* XSCH */ goto unimplemented;
12422 case 0xb277: /* RP */ goto unimplemented;
sewardj1e5fea62011-05-17 16:18:36 +000012423 case 0xb278: s390_format_S_RD(s390_irgen_STCKE, ovl.fmt.S.b2, ovl.fmt.S.d2);goto ok;
sewardj2019a972011-03-07 16:04:07 +000012424 case 0xb279: /* SACF */ goto unimplemented;
sewardj1e5fea62011-05-17 16:18:36 +000012425 case 0xb27c: s390_format_S_RD(s390_irgen_STCKF, ovl.fmt.S.b2, ovl.fmt.S.d2);goto ok;
sewardj2019a972011-03-07 16:04:07 +000012426 case 0xb27d: /* STSI */ goto unimplemented;
12427 case 0xb299: s390_format_S_RD(s390_irgen_SRNM, ovl.fmt.S.b2, ovl.fmt.S.d2);
12428 goto ok;
12429 case 0xb29c: s390_format_S_RD(s390_irgen_STFPC, ovl.fmt.S.b2, ovl.fmt.S.d2);
12430 goto ok;
12431 case 0xb29d: s390_format_S_RD(s390_irgen_LFPC, ovl.fmt.S.b2, ovl.fmt.S.d2);
12432 goto ok;
florian730448f2012-02-04 17:07:07 +000012433 case 0xb2a5: s390_format_RRE_FF(s390_irgen_TRE, ovl.fmt.RRE.r1, ovl.fmt.RRE.r2); goto ok;
floriana0100c92012-07-20 00:06:35 +000012434 case 0xb2a6: s390_format_RRF_M0RERE(s390_irgen_CU21, ovl.fmt.RRF3.r3,
12435 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
12436 goto ok;
florian6d9b9b22012-08-03 18:35:39 +000012437 case 0xb2a7: s390_format_RRF_M0RERE(s390_irgen_CU12, ovl.fmt.RRF3.r3,
12438 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
12439 goto ok;
florian933065d2011-07-11 01:48:02 +000012440 case 0xb2b0: s390_format_S_RD(s390_irgen_STFLE, ovl.fmt.S.b2, ovl.fmt.S.d2);
12441 goto ok;
sewardj2019a972011-03-07 16:04:07 +000012442 case 0xb2b1: /* STFL */ goto unimplemented;
12443 case 0xb2b2: /* LPSWE */ goto unimplemented;
12444 case 0xb2b8: /* SRNMB */ goto unimplemented;
12445 case 0xb2b9: /* SRNMT */ goto unimplemented;
12446 case 0xb2bd: /* LFAS */ goto unimplemented;
12447 case 0xb2ff: /* TRAP4 */ goto unimplemented;
12448 case 0xb300: s390_format_RRE_FF(s390_irgen_LPEBR, ovl.fmt.RRE.r1,
12449 ovl.fmt.RRE.r2); goto ok;
12450 case 0xb301: s390_format_RRE_FF(s390_irgen_LNEBR, ovl.fmt.RRE.r1,
12451 ovl.fmt.RRE.r2); goto ok;
12452 case 0xb302: s390_format_RRE_FF(s390_irgen_LTEBR, ovl.fmt.RRE.r1,
12453 ovl.fmt.RRE.r2); goto ok;
12454 case 0xb303: s390_format_RRE_FF(s390_irgen_LCEBR, ovl.fmt.RRE.r1,
12455 ovl.fmt.RRE.r2); goto ok;
12456 case 0xb304: s390_format_RRE_FF(s390_irgen_LDEBR, ovl.fmt.RRE.r1,
12457 ovl.fmt.RRE.r2); goto ok;
12458 case 0xb305: s390_format_RRE_FF(s390_irgen_LXDBR, ovl.fmt.RRE.r1,
12459 ovl.fmt.RRE.r2); goto ok;
12460 case 0xb306: s390_format_RRE_FF(s390_irgen_LXEBR, ovl.fmt.RRE.r1,
12461 ovl.fmt.RRE.r2); goto ok;
12462 case 0xb307: /* MXDBR */ goto unimplemented;
12463 case 0xb308: /* KEBR */ goto unimplemented;
12464 case 0xb309: s390_format_RRE_FF(s390_irgen_CEBR, ovl.fmt.RRE.r1,
12465 ovl.fmt.RRE.r2); goto ok;
12466 case 0xb30a: s390_format_RRE_FF(s390_irgen_AEBR, ovl.fmt.RRE.r1,
12467 ovl.fmt.RRE.r2); goto ok;
12468 case 0xb30b: s390_format_RRE_FF(s390_irgen_SEBR, ovl.fmt.RRE.r1,
12469 ovl.fmt.RRE.r2); goto ok;
12470 case 0xb30c: /* MDEBR */ goto unimplemented;
12471 case 0xb30d: s390_format_RRE_FF(s390_irgen_DEBR, ovl.fmt.RRE.r1,
12472 ovl.fmt.RRE.r2); goto ok;
12473 case 0xb30e: s390_format_RRF_F0FF(s390_irgen_MAEBR, ovl.fmt.RRF.r1,
12474 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
12475 case 0xb30f: s390_format_RRF_F0FF(s390_irgen_MSEBR, ovl.fmt.RRF.r1,
12476 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
12477 case 0xb310: s390_format_RRE_FF(s390_irgen_LPDBR, ovl.fmt.RRE.r1,
12478 ovl.fmt.RRE.r2); goto ok;
12479 case 0xb311: s390_format_RRE_FF(s390_irgen_LNDBR, ovl.fmt.RRE.r1,
12480 ovl.fmt.RRE.r2); goto ok;
12481 case 0xb312: s390_format_RRE_FF(s390_irgen_LTDBR, ovl.fmt.RRE.r1,
12482 ovl.fmt.RRE.r2); goto ok;
12483 case 0xb313: s390_format_RRE_FF(s390_irgen_LCDBR, ovl.fmt.RRE.r1,
12484 ovl.fmt.RRE.r2); goto ok;
12485 case 0xb314: s390_format_RRE_FF(s390_irgen_SQEBR, ovl.fmt.RRE.r1,
12486 ovl.fmt.RRE.r2); goto ok;
12487 case 0xb315: s390_format_RRE_FF(s390_irgen_SQDBR, ovl.fmt.RRE.r1,
12488 ovl.fmt.RRE.r2); goto ok;
12489 case 0xb316: s390_format_RRE_FF(s390_irgen_SQXBR, ovl.fmt.RRE.r1,
12490 ovl.fmt.RRE.r2); goto ok;
12491 case 0xb317: s390_format_RRE_FF(s390_irgen_MEEBR, ovl.fmt.RRE.r1,
12492 ovl.fmt.RRE.r2); goto ok;
12493 case 0xb318: /* KDBR */ goto unimplemented;
12494 case 0xb319: s390_format_RRE_FF(s390_irgen_CDBR, ovl.fmt.RRE.r1,
12495 ovl.fmt.RRE.r2); goto ok;
12496 case 0xb31a: s390_format_RRE_FF(s390_irgen_ADBR, ovl.fmt.RRE.r1,
12497 ovl.fmt.RRE.r2); goto ok;
12498 case 0xb31b: s390_format_RRE_FF(s390_irgen_SDBR, ovl.fmt.RRE.r1,
12499 ovl.fmt.RRE.r2); goto ok;
12500 case 0xb31c: s390_format_RRE_FF(s390_irgen_MDBR, ovl.fmt.RRE.r1,
12501 ovl.fmt.RRE.r2); goto ok;
12502 case 0xb31d: s390_format_RRE_FF(s390_irgen_DDBR, ovl.fmt.RRE.r1,
12503 ovl.fmt.RRE.r2); goto ok;
12504 case 0xb31e: s390_format_RRF_F0FF(s390_irgen_MADBR, ovl.fmt.RRF.r1,
12505 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
12506 case 0xb31f: s390_format_RRF_F0FF(s390_irgen_MSDBR, ovl.fmt.RRF.r1,
12507 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
12508 case 0xb324: /* LDER */ goto unimplemented;
12509 case 0xb325: /* LXDR */ goto unimplemented;
12510 case 0xb326: /* LXER */ goto unimplemented;
12511 case 0xb32e: /* MAER */ goto unimplemented;
12512 case 0xb32f: /* MSER */ goto unimplemented;
12513 case 0xb336: /* SQXR */ goto unimplemented;
12514 case 0xb337: /* MEER */ goto unimplemented;
12515 case 0xb338: /* MAYLR */ goto unimplemented;
12516 case 0xb339: /* MYLR */ goto unimplemented;
12517 case 0xb33a: /* MAYR */ goto unimplemented;
12518 case 0xb33b: /* MYR */ goto unimplemented;
12519 case 0xb33c: /* MAYHR */ goto unimplemented;
12520 case 0xb33d: /* MYHR */ goto unimplemented;
12521 case 0xb33e: /* MADR */ goto unimplemented;
12522 case 0xb33f: /* MSDR */ goto unimplemented;
12523 case 0xb340: s390_format_RRE_FF(s390_irgen_LPXBR, ovl.fmt.RRE.r1,
12524 ovl.fmt.RRE.r2); goto ok;
12525 case 0xb341: s390_format_RRE_FF(s390_irgen_LNXBR, ovl.fmt.RRE.r1,
12526 ovl.fmt.RRE.r2); goto ok;
12527 case 0xb342: s390_format_RRE_FF(s390_irgen_LTXBR, ovl.fmt.RRE.r1,
12528 ovl.fmt.RRE.r2); goto ok;
12529 case 0xb343: s390_format_RRE_FF(s390_irgen_LCXBR, ovl.fmt.RRE.r1,
12530 ovl.fmt.RRE.r2); goto ok;
12531 case 0xb344: s390_format_RRE_FF(s390_irgen_LEDBR, ovl.fmt.RRE.r1,
12532 ovl.fmt.RRE.r2); goto ok;
12533 case 0xb345: s390_format_RRE_FF(s390_irgen_LDXBR, ovl.fmt.RRE.r1,
12534 ovl.fmt.RRE.r2); goto ok;
12535 case 0xb346: s390_format_RRE_FF(s390_irgen_LEXBR, ovl.fmt.RRE.r1,
12536 ovl.fmt.RRE.r2); goto ok;
12537 case 0xb347: /* FIXBR */ goto unimplemented;
12538 case 0xb348: /* KXBR */ goto unimplemented;
12539 case 0xb349: s390_format_RRE_FF(s390_irgen_CXBR, ovl.fmt.RRE.r1,
12540 ovl.fmt.RRE.r2); goto ok;
12541 case 0xb34a: s390_format_RRE_FF(s390_irgen_AXBR, ovl.fmt.RRE.r1,
12542 ovl.fmt.RRE.r2); goto ok;
12543 case 0xb34b: s390_format_RRE_FF(s390_irgen_SXBR, ovl.fmt.RRE.r1,
12544 ovl.fmt.RRE.r2); goto ok;
12545 case 0xb34c: s390_format_RRE_FF(s390_irgen_MXBR, ovl.fmt.RRE.r1,
12546 ovl.fmt.RRE.r2); goto ok;
12547 case 0xb34d: s390_format_RRE_FF(s390_irgen_DXBR, ovl.fmt.RRE.r1,
12548 ovl.fmt.RRE.r2); goto ok;
12549 case 0xb350: /* TBEDR */ goto unimplemented;
12550 case 0xb351: /* TBDR */ goto unimplemented;
12551 case 0xb353: /* DIEBR */ goto unimplemented;
12552 case 0xb357: /* FIEBR */ goto unimplemented;
12553 case 0xb358: /* THDER */ goto unimplemented;
12554 case 0xb359: /* THDR */ goto unimplemented;
12555 case 0xb35b: /* DIDBR */ goto unimplemented;
12556 case 0xb35f: /* FIDBR */ goto unimplemented;
12557 case 0xb360: /* LPXR */ goto unimplemented;
12558 case 0xb361: /* LNXR */ goto unimplemented;
12559 case 0xb362: /* LTXR */ goto unimplemented;
12560 case 0xb363: /* LCXR */ goto unimplemented;
12561 case 0xb365: s390_format_RRE_FF(s390_irgen_LXR, ovl.fmt.RRE.r1,
12562 ovl.fmt.RRE.r2); goto ok;
12563 case 0xb366: /* LEXR */ goto unimplemented;
12564 case 0xb367: /* FIXR */ goto unimplemented;
12565 case 0xb369: /* CXR */ goto unimplemented;
12566 case 0xb370: s390_format_RRE_FF(s390_irgen_LPDFR, ovl.fmt.RRE.r1,
12567 ovl.fmt.RRE.r2); goto ok;
12568 case 0xb371: s390_format_RRE_FF(s390_irgen_LNDFR, ovl.fmt.RRE.r1,
12569 ovl.fmt.RRE.r2); goto ok;
12570 case 0xb372: s390_format_RRF_F0FF2(s390_irgen_CPSDR, ovl.fmt.RRF3.r3,
12571 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
12572 goto ok;
12573 case 0xb373: s390_format_RRE_FF(s390_irgen_LCDFR, ovl.fmt.RRE.r1,
12574 ovl.fmt.RRE.r2); goto ok;
12575 case 0xb374: s390_format_RRE_F0(s390_irgen_LZER, ovl.fmt.RRE.r1); goto ok;
12576 case 0xb375: s390_format_RRE_F0(s390_irgen_LZDR, ovl.fmt.RRE.r1); goto ok;
12577 case 0xb376: s390_format_RRE_F0(s390_irgen_LZXR, ovl.fmt.RRE.r1); goto ok;
12578 case 0xb377: /* FIER */ goto unimplemented;
12579 case 0xb37f: /* FIDR */ goto unimplemented;
12580 case 0xb384: s390_format_RRE_R0(s390_irgen_SFPC, ovl.fmt.RRE.r1); goto ok;
12581 case 0xb385: /* SFASR */ goto unimplemented;
12582 case 0xb38c: s390_format_RRE_R0(s390_irgen_EFPC, ovl.fmt.RRE.r1); goto ok;
florian1c8f7ff2012-09-01 00:12:11 +000012583 case 0xb390: s390_format_RRF_UUFR(s390_irgen_CELFBR, ovl.fmt.RRF2.m3,
12584 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12585 ovl.fmt.RRF2.r2); goto ok;
12586 case 0xb391: s390_format_RRF_UUFR(s390_irgen_CDLFBR, ovl.fmt.RRF2.m3,
12587 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12588 ovl.fmt.RRF2.r2); goto ok;
12589 case 0xb392: s390_format_RRF_UUFR(s390_irgen_CXLFBR, ovl.fmt.RRF2.m3,
12590 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12591 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000012592 case 0xb394: s390_format_RRE_FR(s390_irgen_CEFBR, ovl.fmt.RRE.r1,
12593 ovl.fmt.RRE.r2); goto ok;
12594 case 0xb395: s390_format_RRE_FR(s390_irgen_CDFBR, ovl.fmt.RRE.r1,
12595 ovl.fmt.RRE.r2); goto ok;
12596 case 0xb396: s390_format_RRE_FR(s390_irgen_CXFBR, ovl.fmt.RRE.r1,
12597 ovl.fmt.RRE.r2); goto ok;
12598 case 0xb398: s390_format_RRF_U0RF(s390_irgen_CFEBR, ovl.fmt.RRF3.r3,
12599 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
12600 goto ok;
12601 case 0xb399: s390_format_RRF_U0RF(s390_irgen_CFDBR, ovl.fmt.RRF3.r3,
12602 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
12603 goto ok;
12604 case 0xb39a: s390_format_RRF_U0RF(s390_irgen_CFXBR, ovl.fmt.RRF3.r3,
12605 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
12606 goto ok;
florian1c8f7ff2012-09-01 00:12:11 +000012607 case 0xb39c: s390_format_RRF_UURF(s390_irgen_CLFEBR, ovl.fmt.RRF2.m3,
12608 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12609 ovl.fmt.RRF2.r2); goto ok;
12610 case 0xb39d: s390_format_RRF_UURF(s390_irgen_CLFDBR, ovl.fmt.RRF2.m3,
12611 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12612 ovl.fmt.RRF2.r2); goto ok;
12613 case 0xb39e: s390_format_RRF_UURF(s390_irgen_CLFXBR, ovl.fmt.RRF2.m3,
12614 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12615 ovl.fmt.RRF2.r2); goto ok;
12616 case 0xb3a0: s390_format_RRF_UUFR(s390_irgen_CELGBR, ovl.fmt.RRF2.m3,
12617 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12618 ovl.fmt.RRF2.r2); goto ok;
12619 case 0xb3a1: s390_format_RRF_UUFR(s390_irgen_CDLGBR, ovl.fmt.RRF2.m3,
12620 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12621 ovl.fmt.RRF2.r2); goto ok;
12622 case 0xb3a2: s390_format_RRF_UUFR(s390_irgen_CXLGBR, ovl.fmt.RRF2.m3,
12623 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12624 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000012625 case 0xb3a4: s390_format_RRE_FR(s390_irgen_CEGBR, ovl.fmt.RRE.r1,
12626 ovl.fmt.RRE.r2); goto ok;
12627 case 0xb3a5: s390_format_RRE_FR(s390_irgen_CDGBR, ovl.fmt.RRE.r1,
12628 ovl.fmt.RRE.r2); goto ok;
12629 case 0xb3a6: s390_format_RRE_FR(s390_irgen_CXGBR, ovl.fmt.RRE.r1,
12630 ovl.fmt.RRE.r2); goto ok;
12631 case 0xb3a8: s390_format_RRF_U0RF(s390_irgen_CGEBR, ovl.fmt.RRF3.r3,
12632 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
12633 goto ok;
12634 case 0xb3a9: s390_format_RRF_U0RF(s390_irgen_CGDBR, ovl.fmt.RRF3.r3,
12635 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
12636 goto ok;
12637 case 0xb3aa: s390_format_RRF_U0RF(s390_irgen_CGXBR, ovl.fmt.RRF3.r3,
12638 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
12639 goto ok;
florian1c8f7ff2012-09-01 00:12:11 +000012640 case 0xb3ac: s390_format_RRF_UURF(s390_irgen_CLGEBR, ovl.fmt.RRF2.m3,
12641 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12642 ovl.fmt.RRF2.r2); goto ok;
12643 case 0xb3ad: s390_format_RRF_UURF(s390_irgen_CLGDBR, ovl.fmt.RRF2.m3,
12644 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12645 ovl.fmt.RRF2.r2); goto ok;
12646 case 0xb3ae: s390_format_RRF_UURF(s390_irgen_CLGXBR, ovl.fmt.RRF2.m3,
12647 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12648 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000012649 case 0xb3b4: /* CEFR */ goto unimplemented;
12650 case 0xb3b5: /* CDFR */ goto unimplemented;
12651 case 0xb3b6: /* CXFR */ goto unimplemented;
12652 case 0xb3b8: /* CFER */ goto unimplemented;
12653 case 0xb3b9: /* CFDR */ goto unimplemented;
12654 case 0xb3ba: /* CFXR */ goto unimplemented;
12655 case 0xb3c1: s390_format_RRE_FR(s390_irgen_LDGR, ovl.fmt.RRE.r1,
12656 ovl.fmt.RRE.r2); goto ok;
12657 case 0xb3c4: /* CEGR */ goto unimplemented;
12658 case 0xb3c5: /* CDGR */ goto unimplemented;
12659 case 0xb3c6: /* CXGR */ goto unimplemented;
12660 case 0xb3c8: /* CGER */ goto unimplemented;
12661 case 0xb3c9: /* CGDR */ goto unimplemented;
12662 case 0xb3ca: /* CGXR */ goto unimplemented;
12663 case 0xb3cd: s390_format_RRE_RF(s390_irgen_LGDR, ovl.fmt.RRE.r1,
12664 ovl.fmt.RRE.r2); goto ok;
12665 case 0xb3d0: /* MDTR */ goto unimplemented;
12666 case 0xb3d1: /* DDTR */ goto unimplemented;
12667 case 0xb3d2: /* ADTR */ goto unimplemented;
12668 case 0xb3d3: /* SDTR */ goto unimplemented;
12669 case 0xb3d4: /* LDETR */ goto unimplemented;
12670 case 0xb3d5: /* LEDTR */ goto unimplemented;
12671 case 0xb3d6: /* LTDTR */ goto unimplemented;
12672 case 0xb3d7: /* FIDTR */ goto unimplemented;
12673 case 0xb3d8: /* MXTR */ goto unimplemented;
12674 case 0xb3d9: /* DXTR */ goto unimplemented;
12675 case 0xb3da: /* AXTR */ goto unimplemented;
12676 case 0xb3db: /* SXTR */ goto unimplemented;
12677 case 0xb3dc: /* LXDTR */ goto unimplemented;
12678 case 0xb3dd: /* LDXTR */ goto unimplemented;
12679 case 0xb3de: /* LTXTR */ goto unimplemented;
12680 case 0xb3df: /* FIXTR */ goto unimplemented;
12681 case 0xb3e0: /* KDTR */ goto unimplemented;
12682 case 0xb3e1: /* CGDTR */ goto unimplemented;
12683 case 0xb3e2: /* CUDTR */ goto unimplemented;
12684 case 0xb3e3: /* CSDTR */ goto unimplemented;
12685 case 0xb3e4: /* CDTR */ goto unimplemented;
12686 case 0xb3e5: /* EEDTR */ goto unimplemented;
12687 case 0xb3e7: /* ESDTR */ goto unimplemented;
12688 case 0xb3e8: /* KXTR */ goto unimplemented;
12689 case 0xb3e9: /* CGXTR */ goto unimplemented;
12690 case 0xb3ea: /* CUXTR */ goto unimplemented;
12691 case 0xb3eb: /* CSXTR */ goto unimplemented;
12692 case 0xb3ec: /* CXTR */ goto unimplemented;
12693 case 0xb3ed: /* EEXTR */ goto unimplemented;
12694 case 0xb3ef: /* ESXTR */ goto unimplemented;
12695 case 0xb3f1: /* CDGTR */ goto unimplemented;
12696 case 0xb3f2: /* CDUTR */ goto unimplemented;
12697 case 0xb3f3: /* CDSTR */ goto unimplemented;
12698 case 0xb3f4: /* CEDTR */ goto unimplemented;
12699 case 0xb3f5: /* QADTR */ goto unimplemented;
12700 case 0xb3f6: /* IEDTR */ goto unimplemented;
12701 case 0xb3f7: /* RRDTR */ goto unimplemented;
12702 case 0xb3f9: /* CXGTR */ goto unimplemented;
12703 case 0xb3fa: /* CXUTR */ goto unimplemented;
12704 case 0xb3fb: /* CXSTR */ goto unimplemented;
12705 case 0xb3fc: /* CEXTR */ goto unimplemented;
12706 case 0xb3fd: /* QAXTR */ goto unimplemented;
12707 case 0xb3fe: /* IEXTR */ goto unimplemented;
12708 case 0xb3ff: /* RRXTR */ goto unimplemented;
12709 case 0xb900: s390_format_RRE_RR(s390_irgen_LPGR, ovl.fmt.RRE.r1,
12710 ovl.fmt.RRE.r2); goto ok;
12711 case 0xb901: s390_format_RRE_RR(s390_irgen_LNGR, ovl.fmt.RRE.r1,
12712 ovl.fmt.RRE.r2); goto ok;
12713 case 0xb902: s390_format_RRE_RR(s390_irgen_LTGR, ovl.fmt.RRE.r1,
12714 ovl.fmt.RRE.r2); goto ok;
12715 case 0xb903: s390_format_RRE_RR(s390_irgen_LCGR, ovl.fmt.RRE.r1,
12716 ovl.fmt.RRE.r2); goto ok;
12717 case 0xb904: s390_format_RRE_RR(s390_irgen_LGR, ovl.fmt.RRE.r1,
12718 ovl.fmt.RRE.r2); goto ok;
12719 case 0xb905: /* LURAG */ goto unimplemented;
12720 case 0xb906: s390_format_RRE_RR(s390_irgen_LGBR, ovl.fmt.RRE.r1,
12721 ovl.fmt.RRE.r2); goto ok;
12722 case 0xb907: s390_format_RRE_RR(s390_irgen_LGHR, ovl.fmt.RRE.r1,
12723 ovl.fmt.RRE.r2); goto ok;
12724 case 0xb908: s390_format_RRE_RR(s390_irgen_AGR, ovl.fmt.RRE.r1,
12725 ovl.fmt.RRE.r2); goto ok;
12726 case 0xb909: s390_format_RRE_RR(s390_irgen_SGR, ovl.fmt.RRE.r1,
12727 ovl.fmt.RRE.r2); goto ok;
12728 case 0xb90a: s390_format_RRE_RR(s390_irgen_ALGR, ovl.fmt.RRE.r1,
12729 ovl.fmt.RRE.r2); goto ok;
12730 case 0xb90b: s390_format_RRE_RR(s390_irgen_SLGR, ovl.fmt.RRE.r1,
12731 ovl.fmt.RRE.r2); goto ok;
12732 case 0xb90c: s390_format_RRE_RR(s390_irgen_MSGR, ovl.fmt.RRE.r1,
12733 ovl.fmt.RRE.r2); goto ok;
12734 case 0xb90d: s390_format_RRE_RR(s390_irgen_DSGR, ovl.fmt.RRE.r1,
12735 ovl.fmt.RRE.r2); goto ok;
12736 case 0xb90e: /* EREGG */ goto unimplemented;
12737 case 0xb90f: s390_format_RRE_RR(s390_irgen_LRVGR, ovl.fmt.RRE.r1,
12738 ovl.fmt.RRE.r2); goto ok;
12739 case 0xb910: s390_format_RRE_RR(s390_irgen_LPGFR, ovl.fmt.RRE.r1,
12740 ovl.fmt.RRE.r2); goto ok;
12741 case 0xb911: s390_format_RRE_RR(s390_irgen_LNGFR, ovl.fmt.RRE.r1,
12742 ovl.fmt.RRE.r2); goto ok;
12743 case 0xb912: s390_format_RRE_RR(s390_irgen_LTGFR, ovl.fmt.RRE.r1,
12744 ovl.fmt.RRE.r2); goto ok;
12745 case 0xb913: s390_format_RRE_RR(s390_irgen_LCGFR, ovl.fmt.RRE.r1,
12746 ovl.fmt.RRE.r2); goto ok;
12747 case 0xb914: s390_format_RRE_RR(s390_irgen_LGFR, ovl.fmt.RRE.r1,
12748 ovl.fmt.RRE.r2); goto ok;
12749 case 0xb916: s390_format_RRE_RR(s390_irgen_LLGFR, ovl.fmt.RRE.r1,
12750 ovl.fmt.RRE.r2); goto ok;
12751 case 0xb917: s390_format_RRE_RR(s390_irgen_LLGTR, ovl.fmt.RRE.r1,
12752 ovl.fmt.RRE.r2); goto ok;
12753 case 0xb918: s390_format_RRE_RR(s390_irgen_AGFR, ovl.fmt.RRE.r1,
12754 ovl.fmt.RRE.r2); goto ok;
12755 case 0xb919: s390_format_RRE_RR(s390_irgen_SGFR, ovl.fmt.RRE.r1,
12756 ovl.fmt.RRE.r2); goto ok;
12757 case 0xb91a: s390_format_RRE_RR(s390_irgen_ALGFR, ovl.fmt.RRE.r1,
12758 ovl.fmt.RRE.r2); goto ok;
12759 case 0xb91b: s390_format_RRE_RR(s390_irgen_SLGFR, ovl.fmt.RRE.r1,
12760 ovl.fmt.RRE.r2); goto ok;
12761 case 0xb91c: s390_format_RRE_RR(s390_irgen_MSGFR, ovl.fmt.RRE.r1,
12762 ovl.fmt.RRE.r2); goto ok;
12763 case 0xb91d: s390_format_RRE_RR(s390_irgen_DSGFR, ovl.fmt.RRE.r1,
12764 ovl.fmt.RRE.r2); goto ok;
12765 case 0xb91e: /* KMAC */ goto unimplemented;
12766 case 0xb91f: s390_format_RRE_RR(s390_irgen_LRVR, ovl.fmt.RRE.r1,
12767 ovl.fmt.RRE.r2); goto ok;
12768 case 0xb920: s390_format_RRE_RR(s390_irgen_CGR, ovl.fmt.RRE.r1,
12769 ovl.fmt.RRE.r2); goto ok;
12770 case 0xb921: s390_format_RRE_RR(s390_irgen_CLGR, ovl.fmt.RRE.r1,
12771 ovl.fmt.RRE.r2); goto ok;
12772 case 0xb925: /* STURG */ goto unimplemented;
12773 case 0xb926: s390_format_RRE_RR(s390_irgen_LBR, ovl.fmt.RRE.r1,
12774 ovl.fmt.RRE.r2); goto ok;
12775 case 0xb927: s390_format_RRE_RR(s390_irgen_LHR, ovl.fmt.RRE.r1,
12776 ovl.fmt.RRE.r2); goto ok;
12777 case 0xb928: /* PCKMO */ goto unimplemented;
12778 case 0xb92b: /* KMO */ goto unimplemented;
12779 case 0xb92c: /* PCC */ goto unimplemented;
12780 case 0xb92d: /* KMCTR */ goto unimplemented;
12781 case 0xb92e: /* KM */ goto unimplemented;
12782 case 0xb92f: /* KMC */ goto unimplemented;
12783 case 0xb930: s390_format_RRE_RR(s390_irgen_CGFR, ovl.fmt.RRE.r1,
12784 ovl.fmt.RRE.r2); goto ok;
12785 case 0xb931: s390_format_RRE_RR(s390_irgen_CLGFR, ovl.fmt.RRE.r1,
12786 ovl.fmt.RRE.r2); goto ok;
12787 case 0xb93e: /* KIMD */ goto unimplemented;
12788 case 0xb93f: /* KLMD */ goto unimplemented;
12789 case 0xb941: /* CFDTR */ goto unimplemented;
12790 case 0xb942: /* CLGDTR */ goto unimplemented;
12791 case 0xb943: /* CLFDTR */ goto unimplemented;
12792 case 0xb946: s390_format_RRE_RR(s390_irgen_BCTGR, ovl.fmt.RRE.r1,
12793 ovl.fmt.RRE.r2); goto ok;
12794 case 0xb949: /* CFXTR */ goto unimplemented;
12795 case 0xb94a: /* CLGXTR */ goto unimplemented;
12796 case 0xb94b: /* CLFXTR */ goto unimplemented;
12797 case 0xb951: /* CDFTR */ goto unimplemented;
12798 case 0xb952: /* CDLGTR */ goto unimplemented;
12799 case 0xb953: /* CDLFTR */ goto unimplemented;
12800 case 0xb959: /* CXFTR */ goto unimplemented;
12801 case 0xb95a: /* CXLGTR */ goto unimplemented;
12802 case 0xb95b: /* CXLFTR */ goto unimplemented;
12803 case 0xb960: /* CGRT */ goto unimplemented;
12804 case 0xb961: /* CLGRT */ goto unimplemented;
12805 case 0xb972: /* CRT */ goto unimplemented;
12806 case 0xb973: /* CLRT */ goto unimplemented;
12807 case 0xb980: s390_format_RRE_RR(s390_irgen_NGR, ovl.fmt.RRE.r1,
12808 ovl.fmt.RRE.r2); goto ok;
12809 case 0xb981: s390_format_RRE_RR(s390_irgen_OGR, ovl.fmt.RRE.r1,
12810 ovl.fmt.RRE.r2); goto ok;
12811 case 0xb982: s390_format_RRE_RR(s390_irgen_XGR, ovl.fmt.RRE.r1,
12812 ovl.fmt.RRE.r2); goto ok;
12813 case 0xb983: s390_format_RRE_RR(s390_irgen_FLOGR, ovl.fmt.RRE.r1,
12814 ovl.fmt.RRE.r2); goto ok;
12815 case 0xb984: s390_format_RRE_RR(s390_irgen_LLGCR, ovl.fmt.RRE.r1,
12816 ovl.fmt.RRE.r2); goto ok;
12817 case 0xb985: s390_format_RRE_RR(s390_irgen_LLGHR, ovl.fmt.RRE.r1,
12818 ovl.fmt.RRE.r2); goto ok;
12819 case 0xb986: s390_format_RRE_RR(s390_irgen_MLGR, ovl.fmt.RRE.r1,
12820 ovl.fmt.RRE.r2); goto ok;
12821 case 0xb987: s390_format_RRE_RR(s390_irgen_DLGR, ovl.fmt.RRE.r1,
12822 ovl.fmt.RRE.r2); goto ok;
12823 case 0xb988: s390_format_RRE_RR(s390_irgen_ALCGR, ovl.fmt.RRE.r1,
12824 ovl.fmt.RRE.r2); goto ok;
12825 case 0xb989: s390_format_RRE_RR(s390_irgen_SLBGR, ovl.fmt.RRE.r1,
12826 ovl.fmt.RRE.r2); goto ok;
12827 case 0xb98a: /* CSPG */ goto unimplemented;
12828 case 0xb98d: /* EPSW */ goto unimplemented;
12829 case 0xb98e: /* IDTE */ goto unimplemented;
florian730448f2012-02-04 17:07:07 +000012830 case 0xb990: s390_format_RRF_M0RERE(s390_irgen_TRTT, ovl.fmt.RRF3.r3,
12831 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
12832 case 0xb991: s390_format_RRF_M0RERE(s390_irgen_TRTO, ovl.fmt.RRF3.r3,
12833 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
12834 case 0xb992: s390_format_RRF_M0RERE(s390_irgen_TROT, ovl.fmt.RRF3.r3,
12835 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
florian9af37692012-01-15 21:01:16 +000012836 case 0xb993: s390_format_RRF_M0RERE(s390_irgen_TROO, ovl.fmt.RRF3.r3,
12837 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000012838 case 0xb994: s390_format_RRE_RR(s390_irgen_LLCR, ovl.fmt.RRE.r1,
12839 ovl.fmt.RRE.r2); goto ok;
12840 case 0xb995: s390_format_RRE_RR(s390_irgen_LLHR, ovl.fmt.RRE.r1,
12841 ovl.fmt.RRE.r2); goto ok;
12842 case 0xb996: s390_format_RRE_RR(s390_irgen_MLR, ovl.fmt.RRE.r1,
12843 ovl.fmt.RRE.r2); goto ok;
12844 case 0xb997: s390_format_RRE_RR(s390_irgen_DLR, ovl.fmt.RRE.r1,
12845 ovl.fmt.RRE.r2); goto ok;
12846 case 0xb998: s390_format_RRE_RR(s390_irgen_ALCR, ovl.fmt.RRE.r1,
12847 ovl.fmt.RRE.r2); goto ok;
12848 case 0xb999: s390_format_RRE_RR(s390_irgen_SLBR, ovl.fmt.RRE.r1,
12849 ovl.fmt.RRE.r2); goto ok;
12850 case 0xb99a: /* EPAIR */ goto unimplemented;
12851 case 0xb99b: /* ESAIR */ goto unimplemented;
12852 case 0xb99d: /* ESEA */ goto unimplemented;
12853 case 0xb99e: /* PTI */ goto unimplemented;
12854 case 0xb99f: /* SSAIR */ goto unimplemented;
12855 case 0xb9a2: /* PTF */ goto unimplemented;
12856 case 0xb9aa: /* LPTEA */ goto unimplemented;
12857 case 0xb9ae: /* RRBM */ goto unimplemented;
12858 case 0xb9af: /* PFMF */ goto unimplemented;
florian3f8a96a2012-08-05 02:59:55 +000012859 case 0xb9b0: s390_format_RRF_M0RERE(s390_irgen_CU14, ovl.fmt.RRF3.r3,
12860 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
12861 goto ok;
florian2a415a12012-07-21 17:41:36 +000012862 case 0xb9b1: s390_format_RRF_M0RERE(s390_irgen_CU24, ovl.fmt.RRF3.r3,
12863 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
12864 goto ok;
florianaf2194f2012-08-06 00:07:54 +000012865 case 0xb9b2: s390_format_RRE_RR(s390_irgen_CU41, ovl.fmt.RRE.r1,
12866 ovl.fmt.RRE.r2); goto ok;
florian956194b2012-07-28 22:18:32 +000012867 case 0xb9b3: s390_format_RRE_RR(s390_irgen_CU42, ovl.fmt.RRE.r1,
12868 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000012869 case 0xb9bd: /* TRTRE */ goto unimplemented;
12870 case 0xb9be: /* SRSTU */ goto unimplemented;
12871 case 0xb9bf: /* TRTE */ goto unimplemented;
12872 case 0xb9c8: s390_format_RRF_R0RR2(s390_irgen_AHHHR, ovl.fmt.RRF4.r3,
12873 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12874 goto ok;
12875 case 0xb9c9: s390_format_RRF_R0RR2(s390_irgen_SHHHR, ovl.fmt.RRF4.r3,
12876 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12877 goto ok;
12878 case 0xb9ca: s390_format_RRF_R0RR2(s390_irgen_ALHHHR, ovl.fmt.RRF4.r3,
12879 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12880 goto ok;
12881 case 0xb9cb: s390_format_RRF_R0RR2(s390_irgen_SLHHHR, ovl.fmt.RRF4.r3,
12882 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12883 goto ok;
12884 case 0xb9cd: s390_format_RRE_RR(s390_irgen_CHHR, ovl.fmt.RRE.r1,
12885 ovl.fmt.RRE.r2); goto ok;
12886 case 0xb9cf: s390_format_RRE_RR(s390_irgen_CLHHR, ovl.fmt.RRE.r1,
12887 ovl.fmt.RRE.r2); goto ok;
12888 case 0xb9d8: s390_format_RRF_R0RR2(s390_irgen_AHHLR, ovl.fmt.RRF4.r3,
12889 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12890 goto ok;
12891 case 0xb9d9: s390_format_RRF_R0RR2(s390_irgen_SHHLR, ovl.fmt.RRF4.r3,
12892 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12893 goto ok;
12894 case 0xb9da: s390_format_RRF_R0RR2(s390_irgen_ALHHLR, ovl.fmt.RRF4.r3,
12895 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12896 goto ok;
12897 case 0xb9db: s390_format_RRF_R0RR2(s390_irgen_SLHHLR, ovl.fmt.RRF4.r3,
12898 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12899 goto ok;
12900 case 0xb9dd: s390_format_RRE_RR(s390_irgen_CHLR, ovl.fmt.RRE.r1,
12901 ovl.fmt.RRE.r2); goto ok;
12902 case 0xb9df: s390_format_RRE_RR(s390_irgen_CLHLR, ovl.fmt.RRE.r1,
12903 ovl.fmt.RRE.r2); goto ok;
12904 case 0xb9e1: /* POPCNT */ goto unimplemented;
sewardjd7bde722011-04-05 13:19:33 +000012905 case 0xb9e2: s390_format_RRF_U0RR(s390_irgen_LOCGR, ovl.fmt.RRF3.r3,
12906 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2,
12907 S390_XMNM_LOCGR); goto ok;
sewardj2019a972011-03-07 16:04:07 +000012908 case 0xb9e4: s390_format_RRF_R0RR2(s390_irgen_NGRK, ovl.fmt.RRF4.r3,
12909 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12910 goto ok;
12911 case 0xb9e6: s390_format_RRF_R0RR2(s390_irgen_OGRK, ovl.fmt.RRF4.r3,
12912 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12913 goto ok;
12914 case 0xb9e7: s390_format_RRF_R0RR2(s390_irgen_XGRK, ovl.fmt.RRF4.r3,
12915 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12916 goto ok;
12917 case 0xb9e8: s390_format_RRF_R0RR2(s390_irgen_AGRK, ovl.fmt.RRF4.r3,
12918 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12919 goto ok;
12920 case 0xb9e9: s390_format_RRF_R0RR2(s390_irgen_SGRK, ovl.fmt.RRF4.r3,
12921 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12922 goto ok;
12923 case 0xb9ea: s390_format_RRF_R0RR2(s390_irgen_ALGRK, ovl.fmt.RRF4.r3,
12924 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12925 goto ok;
12926 case 0xb9eb: s390_format_RRF_R0RR2(s390_irgen_SLGRK, ovl.fmt.RRF4.r3,
12927 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12928 goto ok;
sewardjd7bde722011-04-05 13:19:33 +000012929 case 0xb9f2: s390_format_RRF_U0RR(s390_irgen_LOCR, ovl.fmt.RRF3.r3,
12930 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2,
12931 S390_XMNM_LOCR); goto ok;
sewardj2019a972011-03-07 16:04:07 +000012932 case 0xb9f4: s390_format_RRF_R0RR2(s390_irgen_NRK, ovl.fmt.RRF4.r3,
12933 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12934 goto ok;
12935 case 0xb9f6: s390_format_RRF_R0RR2(s390_irgen_ORK, ovl.fmt.RRF4.r3,
12936 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12937 goto ok;
12938 case 0xb9f7: s390_format_RRF_R0RR2(s390_irgen_XRK, ovl.fmt.RRF4.r3,
12939 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12940 goto ok;
12941 case 0xb9f8: s390_format_RRF_R0RR2(s390_irgen_ARK, ovl.fmt.RRF4.r3,
12942 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12943 goto ok;
12944 case 0xb9f9: s390_format_RRF_R0RR2(s390_irgen_SRK, ovl.fmt.RRF4.r3,
12945 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12946 goto ok;
12947 case 0xb9fa: s390_format_RRF_R0RR2(s390_irgen_ALRK, ovl.fmt.RRF4.r3,
12948 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12949 goto ok;
12950 case 0xb9fb: s390_format_RRF_R0RR2(s390_irgen_SLRK, ovl.fmt.RRF4.r3,
12951 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12952 goto ok;
12953 }
12954
12955 switch ((ovl.value & 0xff000000) >> 24) {
12956 case 0x40: s390_format_RX_RRRD(s390_irgen_STH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12957 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12958 case 0x41: s390_format_RX_RRRD(s390_irgen_LA, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12959 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12960 case 0x42: s390_format_RX_RRRD(s390_irgen_STC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12961 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12962 case 0x43: s390_format_RX_RRRD(s390_irgen_IC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12963 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12964 case 0x44: s390_format_RX_RRRD(s390_irgen_EX, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12965 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12966 case 0x45: /* BAL */ goto unimplemented;
12967 case 0x46: s390_format_RX_RRRD(s390_irgen_BCT, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12968 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12969 case 0x47: s390_format_RX(s390_irgen_BC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12970 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12971 case 0x48: s390_format_RX_RRRD(s390_irgen_LH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12972 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12973 case 0x49: s390_format_RX_RRRD(s390_irgen_CH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12974 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12975 case 0x4a: s390_format_RX_RRRD(s390_irgen_AH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12976 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12977 case 0x4b: s390_format_RX_RRRD(s390_irgen_SH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12978 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12979 case 0x4c: s390_format_RX_RRRD(s390_irgen_MH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12980 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12981 case 0x4d: s390_format_RX_RRRD(s390_irgen_BAS, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12982 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12983 case 0x4e: s390_format_RX_RRRD(s390_irgen_CVD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12984 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12985 case 0x4f: s390_format_RX_RRRD(s390_irgen_CVB, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12986 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12987 case 0x50: s390_format_RX_RRRD(s390_irgen_ST, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12988 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12989 case 0x51: s390_format_RX_RRRD(s390_irgen_LAE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12990 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12991 case 0x54: s390_format_RX_RRRD(s390_irgen_N, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12992 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12993 case 0x55: s390_format_RX_RRRD(s390_irgen_CL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12994 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12995 case 0x56: s390_format_RX_RRRD(s390_irgen_O, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12996 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12997 case 0x57: s390_format_RX_RRRD(s390_irgen_X, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12998 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12999 case 0x58: s390_format_RX_RRRD(s390_irgen_L, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13000 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13001 case 0x59: s390_format_RX_RRRD(s390_irgen_C, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13002 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13003 case 0x5a: s390_format_RX_RRRD(s390_irgen_A, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13004 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13005 case 0x5b: s390_format_RX_RRRD(s390_irgen_S, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13006 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13007 case 0x5c: s390_format_RX_RRRD(s390_irgen_M, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13008 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13009 case 0x5d: s390_format_RX_RRRD(s390_irgen_D, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13010 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13011 case 0x5e: s390_format_RX_RRRD(s390_irgen_AL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13012 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13013 case 0x5f: s390_format_RX_RRRD(s390_irgen_SL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13014 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13015 case 0x60: s390_format_RX_FRRD(s390_irgen_STD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13016 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13017 case 0x67: /* MXD */ goto unimplemented;
13018 case 0x68: s390_format_RX_FRRD(s390_irgen_LD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13019 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13020 case 0x69: /* CD */ goto unimplemented;
13021 case 0x6a: /* AD */ goto unimplemented;
13022 case 0x6b: /* SD */ goto unimplemented;
13023 case 0x6c: /* MD */ goto unimplemented;
13024 case 0x6d: /* DD */ goto unimplemented;
13025 case 0x6e: /* AW */ goto unimplemented;
13026 case 0x6f: /* SW */ goto unimplemented;
13027 case 0x70: s390_format_RX_FRRD(s390_irgen_STE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13028 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13029 case 0x71: s390_format_RX_RRRD(s390_irgen_MS, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13030 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13031 case 0x78: s390_format_RX_FRRD(s390_irgen_LE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13032 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13033 case 0x79: /* CE */ goto unimplemented;
13034 case 0x7a: /* AE */ goto unimplemented;
13035 case 0x7b: /* SE */ goto unimplemented;
13036 case 0x7c: /* MDE */ goto unimplemented;
13037 case 0x7d: /* DE */ goto unimplemented;
13038 case 0x7e: /* AU */ goto unimplemented;
13039 case 0x7f: /* SU */ goto unimplemented;
13040 case 0x83: /* DIAG */ goto unimplemented;
13041 case 0x84: s390_format_RSI_RRP(s390_irgen_BRXH, ovl.fmt.RSI.r1,
13042 ovl.fmt.RSI.r3, ovl.fmt.RSI.i2); goto ok;
13043 case 0x85: s390_format_RSI_RRP(s390_irgen_BRXLE, ovl.fmt.RSI.r1,
13044 ovl.fmt.RSI.r3, ovl.fmt.RSI.i2); goto ok;
13045 case 0x86: s390_format_RS_RRRD(s390_irgen_BXH, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13046 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13047 case 0x87: s390_format_RS_RRRD(s390_irgen_BXLE, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13048 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13049 case 0x88: s390_format_RS_R0RD(s390_irgen_SRL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13050 ovl.fmt.RS.d2); goto ok;
13051 case 0x89: s390_format_RS_R0RD(s390_irgen_SLL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13052 ovl.fmt.RS.d2); goto ok;
13053 case 0x8a: s390_format_RS_R0RD(s390_irgen_SRA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13054 ovl.fmt.RS.d2); goto ok;
13055 case 0x8b: s390_format_RS_R0RD(s390_irgen_SLA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13056 ovl.fmt.RS.d2); goto ok;
13057 case 0x8c: s390_format_RS_R0RD(s390_irgen_SRDL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13058 ovl.fmt.RS.d2); goto ok;
13059 case 0x8d: s390_format_RS_R0RD(s390_irgen_SLDL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13060 ovl.fmt.RS.d2); goto ok;
13061 case 0x8e: s390_format_RS_R0RD(s390_irgen_SRDA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13062 ovl.fmt.RS.d2); goto ok;
13063 case 0x8f: s390_format_RS_R0RD(s390_irgen_SLDA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13064 ovl.fmt.RS.d2); goto ok;
13065 case 0x90: s390_format_RS_RRRD(s390_irgen_STM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13066 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13067 case 0x91: s390_format_SI_URD(s390_irgen_TM, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
13068 ovl.fmt.SI.d1); goto ok;
13069 case 0x92: s390_format_SI_URD(s390_irgen_MVI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
13070 ovl.fmt.SI.d1); goto ok;
13071 case 0x94: s390_format_SI_URD(s390_irgen_NI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
13072 ovl.fmt.SI.d1); goto ok;
13073 case 0x95: s390_format_SI_URD(s390_irgen_CLI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
13074 ovl.fmt.SI.d1); goto ok;
13075 case 0x96: s390_format_SI_URD(s390_irgen_OI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
13076 ovl.fmt.SI.d1); goto ok;
13077 case 0x97: s390_format_SI_URD(s390_irgen_XI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
13078 ovl.fmt.SI.d1); goto ok;
13079 case 0x98: s390_format_RS_RRRD(s390_irgen_LM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13080 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13081 case 0x99: /* TRACE */ goto unimplemented;
13082 case 0x9a: s390_format_RS_AARD(s390_irgen_LAM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13083 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13084 case 0x9b: s390_format_RS_AARD(s390_irgen_STAM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13085 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13086 case 0xa8: s390_format_RS_RRRD(s390_irgen_MVCLE, ovl.fmt.RS.r1,
13087 ovl.fmt.RS.r3, ovl.fmt.RS.b2, ovl.fmt.RS.d2);
13088 goto ok;
13089 case 0xa9: s390_format_RS_RRRD(s390_irgen_CLCLE, ovl.fmt.RS.r1,
13090 ovl.fmt.RS.r3, ovl.fmt.RS.b2, ovl.fmt.RS.d2);
13091 goto ok;
13092 case 0xac: /* STNSM */ goto unimplemented;
13093 case 0xad: /* STOSM */ goto unimplemented;
13094 case 0xae: /* SIGP */ goto unimplemented;
13095 case 0xaf: /* MC */ goto unimplemented;
13096 case 0xb1: /* LRA */ goto unimplemented;
13097 case 0xb6: /* STCTL */ goto unimplemented;
13098 case 0xb7: /* LCTL */ goto unimplemented;
13099 case 0xba: s390_format_RS_RRRD(s390_irgen_CS, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13100 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
florian448cbba2012-06-06 02:26:01 +000013101 case 0xbb: s390_format_RS_RRRD(s390_irgen_CDS, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13102 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013103 case 0xbd: s390_format_RS_RURD(s390_irgen_CLM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13104 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13105 case 0xbe: s390_format_RS_RURD(s390_irgen_STCM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13106 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13107 case 0xbf: s390_format_RS_RURD(s390_irgen_ICM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13108 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13109 }
13110
13111 return S390_DECODE_UNKNOWN_INSN;
13112
13113ok:
13114 return S390_DECODE_OK;
13115
13116unimplemented:
13117 return S390_DECODE_UNIMPLEMENTED_INSN;
13118}
13119
13120static s390_decode_t
13121s390_decode_6byte_and_irgen(UChar *bytes)
13122{
13123 typedef union {
13124 struct {
13125 unsigned int op1 : 8;
13126 unsigned int r1 : 4;
13127 unsigned int r3 : 4;
13128 unsigned int i2 : 16;
13129 unsigned int : 8;
13130 unsigned int op2 : 8;
13131 } RIE;
13132 struct {
13133 unsigned int op1 : 8;
13134 unsigned int r1 : 4;
13135 unsigned int r2 : 4;
13136 unsigned int i3 : 8;
13137 unsigned int i4 : 8;
13138 unsigned int i5 : 8;
13139 unsigned int op2 : 8;
13140 } RIE_RRUUU;
13141 struct {
13142 unsigned int op1 : 8;
13143 unsigned int r1 : 4;
13144 unsigned int : 4;
13145 unsigned int i2 : 16;
13146 unsigned int m3 : 4;
13147 unsigned int : 4;
13148 unsigned int op2 : 8;
13149 } RIEv1;
13150 struct {
13151 unsigned int op1 : 8;
13152 unsigned int r1 : 4;
13153 unsigned int r2 : 4;
13154 unsigned int i4 : 16;
13155 unsigned int m3 : 4;
13156 unsigned int : 4;
13157 unsigned int op2 : 8;
13158 } RIE_RRPU;
13159 struct {
13160 unsigned int op1 : 8;
13161 unsigned int r1 : 4;
13162 unsigned int m3 : 4;
13163 unsigned int i4 : 16;
13164 unsigned int i2 : 8;
13165 unsigned int op2 : 8;
13166 } RIEv3;
13167 struct {
13168 unsigned int op1 : 8;
13169 unsigned int r1 : 4;
13170 unsigned int op2 : 4;
13171 unsigned int i2 : 32;
13172 } RIL;
13173 struct {
13174 unsigned int op1 : 8;
13175 unsigned int r1 : 4;
13176 unsigned int m3 : 4;
13177 unsigned int b4 : 4;
13178 unsigned int d4 : 12;
13179 unsigned int i2 : 8;
13180 unsigned int op2 : 8;
13181 } RIS;
13182 struct {
13183 unsigned int op1 : 8;
13184 unsigned int r1 : 4;
13185 unsigned int r2 : 4;
13186 unsigned int b4 : 4;
13187 unsigned int d4 : 12;
13188 unsigned int m3 : 4;
13189 unsigned int : 4;
13190 unsigned int op2 : 8;
13191 } RRS;
13192 struct {
13193 unsigned int op1 : 8;
13194 unsigned int l1 : 4;
13195 unsigned int : 4;
13196 unsigned int b1 : 4;
13197 unsigned int d1 : 12;
13198 unsigned int : 8;
13199 unsigned int op2 : 8;
13200 } RSL;
13201 struct {
13202 unsigned int op1 : 8;
13203 unsigned int r1 : 4;
13204 unsigned int r3 : 4;
13205 unsigned int b2 : 4;
13206 unsigned int dl2 : 12;
13207 unsigned int dh2 : 8;
13208 unsigned int op2 : 8;
13209 } RSY;
13210 struct {
13211 unsigned int op1 : 8;
13212 unsigned int r1 : 4;
13213 unsigned int x2 : 4;
13214 unsigned int b2 : 4;
13215 unsigned int d2 : 12;
13216 unsigned int : 8;
13217 unsigned int op2 : 8;
13218 } RXE;
13219 struct {
13220 unsigned int op1 : 8;
13221 unsigned int r3 : 4;
13222 unsigned int x2 : 4;
13223 unsigned int b2 : 4;
13224 unsigned int d2 : 12;
13225 unsigned int r1 : 4;
13226 unsigned int : 4;
13227 unsigned int op2 : 8;
13228 } RXF;
13229 struct {
13230 unsigned int op1 : 8;
13231 unsigned int r1 : 4;
13232 unsigned int x2 : 4;
13233 unsigned int b2 : 4;
13234 unsigned int dl2 : 12;
13235 unsigned int dh2 : 8;
13236 unsigned int op2 : 8;
13237 } RXY;
13238 struct {
13239 unsigned int op1 : 8;
13240 unsigned int i2 : 8;
13241 unsigned int b1 : 4;
13242 unsigned int dl1 : 12;
13243 unsigned int dh1 : 8;
13244 unsigned int op2 : 8;
13245 } SIY;
13246 struct {
13247 unsigned int op : 8;
13248 unsigned int l : 8;
13249 unsigned int b1 : 4;
13250 unsigned int d1 : 12;
13251 unsigned int b2 : 4;
13252 unsigned int d2 : 12;
13253 } SS;
13254 struct {
13255 unsigned int op : 8;
13256 unsigned int l1 : 4;
13257 unsigned int l2 : 4;
13258 unsigned int b1 : 4;
13259 unsigned int d1 : 12;
13260 unsigned int b2 : 4;
13261 unsigned int d2 : 12;
13262 } SS_LLRDRD;
13263 struct {
13264 unsigned int op : 8;
13265 unsigned int r1 : 4;
13266 unsigned int r3 : 4;
13267 unsigned int b2 : 4;
13268 unsigned int d2 : 12;
13269 unsigned int b4 : 4;
13270 unsigned int d4 : 12;
13271 } SS_RRRDRD2;
13272 struct {
13273 unsigned int op : 16;
13274 unsigned int b1 : 4;
13275 unsigned int d1 : 12;
13276 unsigned int b2 : 4;
13277 unsigned int d2 : 12;
13278 } SSE;
13279 struct {
13280 unsigned int op1 : 8;
13281 unsigned int r3 : 4;
13282 unsigned int op2 : 4;
13283 unsigned int b1 : 4;
13284 unsigned int d1 : 12;
13285 unsigned int b2 : 4;
13286 unsigned int d2 : 12;
13287 } SSF;
13288 struct {
13289 unsigned int op : 16;
13290 unsigned int b1 : 4;
13291 unsigned int d1 : 12;
13292 unsigned int i2 : 16;
13293 } SIL;
13294 } formats;
13295 union {
13296 formats fmt;
13297 ULong value;
13298 } ovl;
13299
13300 vassert(sizeof(formats) == 6);
13301
13302 ((char *)(&ovl.value))[0] = bytes[0];
13303 ((char *)(&ovl.value))[1] = bytes[1];
13304 ((char *)(&ovl.value))[2] = bytes[2];
13305 ((char *)(&ovl.value))[3] = bytes[3];
13306 ((char *)(&ovl.value))[4] = bytes[4];
13307 ((char *)(&ovl.value))[5] = bytes[5];
13308 ((char *)(&ovl.value))[6] = 0x0;
13309 ((char *)(&ovl.value))[7] = 0x0;
13310
13311 switch ((ovl.value >> 16) & 0xff00000000ffULL) {
13312 case 0xe30000000002ULL: s390_format_RXY_RRRD(s390_irgen_LTG, ovl.fmt.RXY.r1,
13313 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13314 ovl.fmt.RXY.dl2,
13315 ovl.fmt.RXY.dh2); goto ok;
13316 case 0xe30000000003ULL: /* LRAG */ goto unimplemented;
13317 case 0xe30000000004ULL: s390_format_RXY_RRRD(s390_irgen_LG, ovl.fmt.RXY.r1,
13318 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13319 ovl.fmt.RXY.dl2,
13320 ovl.fmt.RXY.dh2); goto ok;
13321 case 0xe30000000006ULL: s390_format_RXY_RRRD(s390_irgen_CVBY, ovl.fmt.RXY.r1,
13322 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13323 ovl.fmt.RXY.dl2,
13324 ovl.fmt.RXY.dh2); goto ok;
13325 case 0xe30000000008ULL: s390_format_RXY_RRRD(s390_irgen_AG, ovl.fmt.RXY.r1,
13326 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13327 ovl.fmt.RXY.dl2,
13328 ovl.fmt.RXY.dh2); goto ok;
13329 case 0xe30000000009ULL: s390_format_RXY_RRRD(s390_irgen_SG, ovl.fmt.RXY.r1,
13330 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13331 ovl.fmt.RXY.dl2,
13332 ovl.fmt.RXY.dh2); goto ok;
13333 case 0xe3000000000aULL: s390_format_RXY_RRRD(s390_irgen_ALG, ovl.fmt.RXY.r1,
13334 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13335 ovl.fmt.RXY.dl2,
13336 ovl.fmt.RXY.dh2); goto ok;
13337 case 0xe3000000000bULL: s390_format_RXY_RRRD(s390_irgen_SLG, ovl.fmt.RXY.r1,
13338 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13339 ovl.fmt.RXY.dl2,
13340 ovl.fmt.RXY.dh2); goto ok;
13341 case 0xe3000000000cULL: s390_format_RXY_RRRD(s390_irgen_MSG, ovl.fmt.RXY.r1,
13342 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13343 ovl.fmt.RXY.dl2,
13344 ovl.fmt.RXY.dh2); goto ok;
13345 case 0xe3000000000dULL: s390_format_RXY_RRRD(s390_irgen_DSG, ovl.fmt.RXY.r1,
13346 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13347 ovl.fmt.RXY.dl2,
13348 ovl.fmt.RXY.dh2); goto ok;
13349 case 0xe3000000000eULL: /* CVBG */ goto unimplemented;
13350 case 0xe3000000000fULL: s390_format_RXY_RRRD(s390_irgen_LRVG, ovl.fmt.RXY.r1,
13351 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13352 ovl.fmt.RXY.dl2,
13353 ovl.fmt.RXY.dh2); goto ok;
13354 case 0xe30000000012ULL: s390_format_RXY_RRRD(s390_irgen_LT, ovl.fmt.RXY.r1,
13355 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13356 ovl.fmt.RXY.dl2,
13357 ovl.fmt.RXY.dh2); goto ok;
13358 case 0xe30000000013ULL: /* LRAY */ goto unimplemented;
13359 case 0xe30000000014ULL: s390_format_RXY_RRRD(s390_irgen_LGF, ovl.fmt.RXY.r1,
13360 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13361 ovl.fmt.RXY.dl2,
13362 ovl.fmt.RXY.dh2); goto ok;
13363 case 0xe30000000015ULL: s390_format_RXY_RRRD(s390_irgen_LGH, ovl.fmt.RXY.r1,
13364 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13365 ovl.fmt.RXY.dl2,
13366 ovl.fmt.RXY.dh2); goto ok;
13367 case 0xe30000000016ULL: s390_format_RXY_RRRD(s390_irgen_LLGF, ovl.fmt.RXY.r1,
13368 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13369 ovl.fmt.RXY.dl2,
13370 ovl.fmt.RXY.dh2); goto ok;
13371 case 0xe30000000017ULL: s390_format_RXY_RRRD(s390_irgen_LLGT, ovl.fmt.RXY.r1,
13372 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13373 ovl.fmt.RXY.dl2,
13374 ovl.fmt.RXY.dh2); goto ok;
13375 case 0xe30000000018ULL: s390_format_RXY_RRRD(s390_irgen_AGF, ovl.fmt.RXY.r1,
13376 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13377 ovl.fmt.RXY.dl2,
13378 ovl.fmt.RXY.dh2); goto ok;
13379 case 0xe30000000019ULL: s390_format_RXY_RRRD(s390_irgen_SGF, ovl.fmt.RXY.r1,
13380 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13381 ovl.fmt.RXY.dl2,
13382 ovl.fmt.RXY.dh2); goto ok;
13383 case 0xe3000000001aULL: s390_format_RXY_RRRD(s390_irgen_ALGF, ovl.fmt.RXY.r1,
13384 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13385 ovl.fmt.RXY.dl2,
13386 ovl.fmt.RXY.dh2); goto ok;
13387 case 0xe3000000001bULL: s390_format_RXY_RRRD(s390_irgen_SLGF, ovl.fmt.RXY.r1,
13388 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13389 ovl.fmt.RXY.dl2,
13390 ovl.fmt.RXY.dh2); goto ok;
13391 case 0xe3000000001cULL: s390_format_RXY_RRRD(s390_irgen_MSGF, ovl.fmt.RXY.r1,
13392 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13393 ovl.fmt.RXY.dl2,
13394 ovl.fmt.RXY.dh2); goto ok;
13395 case 0xe3000000001dULL: s390_format_RXY_RRRD(s390_irgen_DSGF, ovl.fmt.RXY.r1,
13396 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13397 ovl.fmt.RXY.dl2,
13398 ovl.fmt.RXY.dh2); goto ok;
13399 case 0xe3000000001eULL: s390_format_RXY_RRRD(s390_irgen_LRV, ovl.fmt.RXY.r1,
13400 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13401 ovl.fmt.RXY.dl2,
13402 ovl.fmt.RXY.dh2); goto ok;
13403 case 0xe3000000001fULL: s390_format_RXY_RRRD(s390_irgen_LRVH, ovl.fmt.RXY.r1,
13404 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13405 ovl.fmt.RXY.dl2,
13406 ovl.fmt.RXY.dh2); goto ok;
13407 case 0xe30000000020ULL: s390_format_RXY_RRRD(s390_irgen_CG, ovl.fmt.RXY.r1,
13408 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13409 ovl.fmt.RXY.dl2,
13410 ovl.fmt.RXY.dh2); goto ok;
13411 case 0xe30000000021ULL: s390_format_RXY_RRRD(s390_irgen_CLG, ovl.fmt.RXY.r1,
13412 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13413 ovl.fmt.RXY.dl2,
13414 ovl.fmt.RXY.dh2); goto ok;
13415 case 0xe30000000024ULL: s390_format_RXY_RRRD(s390_irgen_STG, ovl.fmt.RXY.r1,
13416 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13417 ovl.fmt.RXY.dl2,
13418 ovl.fmt.RXY.dh2); goto ok;
13419 case 0xe30000000026ULL: s390_format_RXY_RRRD(s390_irgen_CVDY, ovl.fmt.RXY.r1,
13420 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13421 ovl.fmt.RXY.dl2,
13422 ovl.fmt.RXY.dh2); goto ok;
13423 case 0xe3000000002eULL: /* CVDG */ goto unimplemented;
13424 case 0xe3000000002fULL: s390_format_RXY_RRRD(s390_irgen_STRVG,
13425 ovl.fmt.RXY.r1, ovl.fmt.RXY.x2,
13426 ovl.fmt.RXY.b2, ovl.fmt.RXY.dl2,
13427 ovl.fmt.RXY.dh2); goto ok;
13428 case 0xe30000000030ULL: s390_format_RXY_RRRD(s390_irgen_CGF, ovl.fmt.RXY.r1,
13429 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13430 ovl.fmt.RXY.dl2,
13431 ovl.fmt.RXY.dh2); goto ok;
13432 case 0xe30000000031ULL: s390_format_RXY_RRRD(s390_irgen_CLGF, ovl.fmt.RXY.r1,
13433 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13434 ovl.fmt.RXY.dl2,
13435 ovl.fmt.RXY.dh2); goto ok;
13436 case 0xe30000000032ULL: s390_format_RXY_RRRD(s390_irgen_LTGF, ovl.fmt.RXY.r1,
13437 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13438 ovl.fmt.RXY.dl2,
13439 ovl.fmt.RXY.dh2); goto ok;
13440 case 0xe30000000034ULL: s390_format_RXY_RRRD(s390_irgen_CGH, ovl.fmt.RXY.r1,
13441 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13442 ovl.fmt.RXY.dl2,
13443 ovl.fmt.RXY.dh2); goto ok;
13444 case 0xe30000000036ULL: s390_format_RXY_URRD(s390_irgen_PFD, ovl.fmt.RXY.r1,
13445 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13446 ovl.fmt.RXY.dl2,
13447 ovl.fmt.RXY.dh2); goto ok;
13448 case 0xe3000000003eULL: s390_format_RXY_RRRD(s390_irgen_STRV, ovl.fmt.RXY.r1,
13449 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13450 ovl.fmt.RXY.dl2,
13451 ovl.fmt.RXY.dh2); goto ok;
13452 case 0xe3000000003fULL: s390_format_RXY_RRRD(s390_irgen_STRVH,
13453 ovl.fmt.RXY.r1, ovl.fmt.RXY.x2,
13454 ovl.fmt.RXY.b2, ovl.fmt.RXY.dl2,
13455 ovl.fmt.RXY.dh2); goto ok;
13456 case 0xe30000000046ULL: s390_format_RXY_RRRD(s390_irgen_BCTG, ovl.fmt.RXY.r1,
13457 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13458 ovl.fmt.RXY.dl2,
13459 ovl.fmt.RXY.dh2); goto ok;
13460 case 0xe30000000050ULL: s390_format_RXY_RRRD(s390_irgen_STY, ovl.fmt.RXY.r1,
13461 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13462 ovl.fmt.RXY.dl2,
13463 ovl.fmt.RXY.dh2); goto ok;
13464 case 0xe30000000051ULL: s390_format_RXY_RRRD(s390_irgen_MSY, ovl.fmt.RXY.r1,
13465 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13466 ovl.fmt.RXY.dl2,
13467 ovl.fmt.RXY.dh2); goto ok;
13468 case 0xe30000000054ULL: s390_format_RXY_RRRD(s390_irgen_NY, ovl.fmt.RXY.r1,
13469 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13470 ovl.fmt.RXY.dl2,
13471 ovl.fmt.RXY.dh2); goto ok;
13472 case 0xe30000000055ULL: s390_format_RXY_RRRD(s390_irgen_CLY, ovl.fmt.RXY.r1,
13473 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13474 ovl.fmt.RXY.dl2,
13475 ovl.fmt.RXY.dh2); goto ok;
13476 case 0xe30000000056ULL: s390_format_RXY_RRRD(s390_irgen_OY, ovl.fmt.RXY.r1,
13477 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13478 ovl.fmt.RXY.dl2,
13479 ovl.fmt.RXY.dh2); goto ok;
13480 case 0xe30000000057ULL: s390_format_RXY_RRRD(s390_irgen_XY, ovl.fmt.RXY.r1,
13481 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13482 ovl.fmt.RXY.dl2,
13483 ovl.fmt.RXY.dh2); goto ok;
13484 case 0xe30000000058ULL: s390_format_RXY_RRRD(s390_irgen_LY, ovl.fmt.RXY.r1,
13485 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13486 ovl.fmt.RXY.dl2,
13487 ovl.fmt.RXY.dh2); goto ok;
13488 case 0xe30000000059ULL: s390_format_RXY_RRRD(s390_irgen_CY, ovl.fmt.RXY.r1,
13489 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13490 ovl.fmt.RXY.dl2,
13491 ovl.fmt.RXY.dh2); goto ok;
13492 case 0xe3000000005aULL: s390_format_RXY_RRRD(s390_irgen_AY, ovl.fmt.RXY.r1,
13493 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13494 ovl.fmt.RXY.dl2,
13495 ovl.fmt.RXY.dh2); goto ok;
13496 case 0xe3000000005bULL: s390_format_RXY_RRRD(s390_irgen_SY, ovl.fmt.RXY.r1,
13497 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13498 ovl.fmt.RXY.dl2,
13499 ovl.fmt.RXY.dh2); goto ok;
13500 case 0xe3000000005cULL: s390_format_RXY_RRRD(s390_irgen_MFY, ovl.fmt.RXY.r1,
13501 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13502 ovl.fmt.RXY.dl2,
13503 ovl.fmt.RXY.dh2); goto ok;
13504 case 0xe3000000005eULL: s390_format_RXY_RRRD(s390_irgen_ALY, ovl.fmt.RXY.r1,
13505 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13506 ovl.fmt.RXY.dl2,
13507 ovl.fmt.RXY.dh2); goto ok;
13508 case 0xe3000000005fULL: s390_format_RXY_RRRD(s390_irgen_SLY, ovl.fmt.RXY.r1,
13509 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13510 ovl.fmt.RXY.dl2,
13511 ovl.fmt.RXY.dh2); goto ok;
13512 case 0xe30000000070ULL: s390_format_RXY_RRRD(s390_irgen_STHY, ovl.fmt.RXY.r1,
13513 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13514 ovl.fmt.RXY.dl2,
13515 ovl.fmt.RXY.dh2); goto ok;
13516 case 0xe30000000071ULL: s390_format_RXY_RRRD(s390_irgen_LAY, ovl.fmt.RXY.r1,
13517 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13518 ovl.fmt.RXY.dl2,
13519 ovl.fmt.RXY.dh2); goto ok;
13520 case 0xe30000000072ULL: s390_format_RXY_RRRD(s390_irgen_STCY, ovl.fmt.RXY.r1,
13521 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13522 ovl.fmt.RXY.dl2,
13523 ovl.fmt.RXY.dh2); goto ok;
13524 case 0xe30000000073ULL: s390_format_RXY_RRRD(s390_irgen_ICY, ovl.fmt.RXY.r1,
13525 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13526 ovl.fmt.RXY.dl2,
13527 ovl.fmt.RXY.dh2); goto ok;
13528 case 0xe30000000075ULL: s390_format_RXY_RRRD(s390_irgen_LAEY, ovl.fmt.RXY.r1,
13529 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13530 ovl.fmt.RXY.dl2,
13531 ovl.fmt.RXY.dh2); goto ok;
13532 case 0xe30000000076ULL: s390_format_RXY_RRRD(s390_irgen_LB, ovl.fmt.RXY.r1,
13533 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13534 ovl.fmt.RXY.dl2,
13535 ovl.fmt.RXY.dh2); goto ok;
13536 case 0xe30000000077ULL: s390_format_RXY_RRRD(s390_irgen_LGB, ovl.fmt.RXY.r1,
13537 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13538 ovl.fmt.RXY.dl2,
13539 ovl.fmt.RXY.dh2); goto ok;
13540 case 0xe30000000078ULL: s390_format_RXY_RRRD(s390_irgen_LHY, ovl.fmt.RXY.r1,
13541 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13542 ovl.fmt.RXY.dl2,
13543 ovl.fmt.RXY.dh2); goto ok;
13544 case 0xe30000000079ULL: s390_format_RXY_RRRD(s390_irgen_CHY, ovl.fmt.RXY.r1,
13545 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13546 ovl.fmt.RXY.dl2,
13547 ovl.fmt.RXY.dh2); goto ok;
13548 case 0xe3000000007aULL: s390_format_RXY_RRRD(s390_irgen_AHY, ovl.fmt.RXY.r1,
13549 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13550 ovl.fmt.RXY.dl2,
13551 ovl.fmt.RXY.dh2); goto ok;
13552 case 0xe3000000007bULL: s390_format_RXY_RRRD(s390_irgen_SHY, ovl.fmt.RXY.r1,
13553 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13554 ovl.fmt.RXY.dl2,
13555 ovl.fmt.RXY.dh2); goto ok;
13556 case 0xe3000000007cULL: s390_format_RXY_RRRD(s390_irgen_MHY, ovl.fmt.RXY.r1,
13557 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13558 ovl.fmt.RXY.dl2,
13559 ovl.fmt.RXY.dh2); goto ok;
13560 case 0xe30000000080ULL: s390_format_RXY_RRRD(s390_irgen_NG, ovl.fmt.RXY.r1,
13561 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13562 ovl.fmt.RXY.dl2,
13563 ovl.fmt.RXY.dh2); goto ok;
13564 case 0xe30000000081ULL: s390_format_RXY_RRRD(s390_irgen_OG, ovl.fmt.RXY.r1,
13565 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13566 ovl.fmt.RXY.dl2,
13567 ovl.fmt.RXY.dh2); goto ok;
13568 case 0xe30000000082ULL: s390_format_RXY_RRRD(s390_irgen_XG, ovl.fmt.RXY.r1,
13569 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13570 ovl.fmt.RXY.dl2,
13571 ovl.fmt.RXY.dh2); goto ok;
13572 case 0xe30000000086ULL: s390_format_RXY_RRRD(s390_irgen_MLG, ovl.fmt.RXY.r1,
13573 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13574 ovl.fmt.RXY.dl2,
13575 ovl.fmt.RXY.dh2); goto ok;
13576 case 0xe30000000087ULL: s390_format_RXY_RRRD(s390_irgen_DLG, ovl.fmt.RXY.r1,
13577 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13578 ovl.fmt.RXY.dl2,
13579 ovl.fmt.RXY.dh2); goto ok;
13580 case 0xe30000000088ULL: s390_format_RXY_RRRD(s390_irgen_ALCG, ovl.fmt.RXY.r1,
13581 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13582 ovl.fmt.RXY.dl2,
13583 ovl.fmt.RXY.dh2); goto ok;
13584 case 0xe30000000089ULL: s390_format_RXY_RRRD(s390_irgen_SLBG, ovl.fmt.RXY.r1,
13585 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13586 ovl.fmt.RXY.dl2,
13587 ovl.fmt.RXY.dh2); goto ok;
13588 case 0xe3000000008eULL: s390_format_RXY_RRRD(s390_irgen_STPQ, ovl.fmt.RXY.r1,
13589 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13590 ovl.fmt.RXY.dl2,
13591 ovl.fmt.RXY.dh2); goto ok;
13592 case 0xe3000000008fULL: s390_format_RXY_RRRD(s390_irgen_LPQ, ovl.fmt.RXY.r1,
13593 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13594 ovl.fmt.RXY.dl2,
13595 ovl.fmt.RXY.dh2); goto ok;
13596 case 0xe30000000090ULL: s390_format_RXY_RRRD(s390_irgen_LLGC, ovl.fmt.RXY.r1,
13597 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13598 ovl.fmt.RXY.dl2,
13599 ovl.fmt.RXY.dh2); goto ok;
13600 case 0xe30000000091ULL: s390_format_RXY_RRRD(s390_irgen_LLGH, ovl.fmt.RXY.r1,
13601 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13602 ovl.fmt.RXY.dl2,
13603 ovl.fmt.RXY.dh2); goto ok;
13604 case 0xe30000000094ULL: s390_format_RXY_RRRD(s390_irgen_LLC, ovl.fmt.RXY.r1,
13605 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13606 ovl.fmt.RXY.dl2,
13607 ovl.fmt.RXY.dh2); goto ok;
13608 case 0xe30000000095ULL: s390_format_RXY_RRRD(s390_irgen_LLH, ovl.fmt.RXY.r1,
13609 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13610 ovl.fmt.RXY.dl2,
13611 ovl.fmt.RXY.dh2); goto ok;
13612 case 0xe30000000096ULL: s390_format_RXY_RRRD(s390_irgen_ML, ovl.fmt.RXY.r1,
13613 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13614 ovl.fmt.RXY.dl2,
13615 ovl.fmt.RXY.dh2); goto ok;
13616 case 0xe30000000097ULL: s390_format_RXY_RRRD(s390_irgen_DL, ovl.fmt.RXY.r1,
13617 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13618 ovl.fmt.RXY.dl2,
13619 ovl.fmt.RXY.dh2); goto ok;
13620 case 0xe30000000098ULL: s390_format_RXY_RRRD(s390_irgen_ALC, ovl.fmt.RXY.r1,
13621 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13622 ovl.fmt.RXY.dl2,
13623 ovl.fmt.RXY.dh2); goto ok;
13624 case 0xe30000000099ULL: s390_format_RXY_RRRD(s390_irgen_SLB, ovl.fmt.RXY.r1,
13625 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13626 ovl.fmt.RXY.dl2,
13627 ovl.fmt.RXY.dh2); goto ok;
13628 case 0xe300000000c0ULL: s390_format_RXY_RRRD(s390_irgen_LBH, ovl.fmt.RXY.r1,
13629 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13630 ovl.fmt.RXY.dl2,
13631 ovl.fmt.RXY.dh2); goto ok;
13632 case 0xe300000000c2ULL: s390_format_RXY_RRRD(s390_irgen_LLCH, ovl.fmt.RXY.r1,
13633 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13634 ovl.fmt.RXY.dl2,
13635 ovl.fmt.RXY.dh2); goto ok;
13636 case 0xe300000000c3ULL: s390_format_RXY_RRRD(s390_irgen_STCH, ovl.fmt.RXY.r1,
13637 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13638 ovl.fmt.RXY.dl2,
13639 ovl.fmt.RXY.dh2); goto ok;
13640 case 0xe300000000c4ULL: s390_format_RXY_RRRD(s390_irgen_LHH, ovl.fmt.RXY.r1,
13641 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13642 ovl.fmt.RXY.dl2,
13643 ovl.fmt.RXY.dh2); goto ok;
13644 case 0xe300000000c6ULL: s390_format_RXY_RRRD(s390_irgen_LLHH, ovl.fmt.RXY.r1,
13645 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13646 ovl.fmt.RXY.dl2,
13647 ovl.fmt.RXY.dh2); goto ok;
13648 case 0xe300000000c7ULL: s390_format_RXY_RRRD(s390_irgen_STHH, ovl.fmt.RXY.r1,
13649 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13650 ovl.fmt.RXY.dl2,
13651 ovl.fmt.RXY.dh2); goto ok;
13652 case 0xe300000000caULL: s390_format_RXY_RRRD(s390_irgen_LFH, ovl.fmt.RXY.r1,
13653 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13654 ovl.fmt.RXY.dl2,
13655 ovl.fmt.RXY.dh2); goto ok;
13656 case 0xe300000000cbULL: s390_format_RXY_RRRD(s390_irgen_STFH, ovl.fmt.RXY.r1,
13657 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13658 ovl.fmt.RXY.dl2,
13659 ovl.fmt.RXY.dh2); goto ok;
13660 case 0xe300000000cdULL: s390_format_RXY_RRRD(s390_irgen_CHF, ovl.fmt.RXY.r1,
13661 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13662 ovl.fmt.RXY.dl2,
13663 ovl.fmt.RXY.dh2); goto ok;
13664 case 0xe300000000cfULL: s390_format_RXY_RRRD(s390_irgen_CLHF, ovl.fmt.RXY.r1,
13665 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13666 ovl.fmt.RXY.dl2,
13667 ovl.fmt.RXY.dh2); goto ok;
13668 case 0xeb0000000004ULL: s390_format_RSY_RRRD(s390_irgen_LMG, ovl.fmt.RSY.r1,
13669 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13670 ovl.fmt.RSY.dl2,
13671 ovl.fmt.RSY.dh2); goto ok;
13672 case 0xeb000000000aULL: s390_format_RSY_RRRD(s390_irgen_SRAG, ovl.fmt.RSY.r1,
13673 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13674 ovl.fmt.RSY.dl2,
13675 ovl.fmt.RSY.dh2); goto ok;
13676 case 0xeb000000000bULL: s390_format_RSY_RRRD(s390_irgen_SLAG, ovl.fmt.RSY.r1,
13677 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13678 ovl.fmt.RSY.dl2,
13679 ovl.fmt.RSY.dh2); goto ok;
13680 case 0xeb000000000cULL: s390_format_RSY_RRRD(s390_irgen_SRLG, ovl.fmt.RSY.r1,
13681 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13682 ovl.fmt.RSY.dl2,
13683 ovl.fmt.RSY.dh2); goto ok;
13684 case 0xeb000000000dULL: s390_format_RSY_RRRD(s390_irgen_SLLG, ovl.fmt.RSY.r1,
13685 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13686 ovl.fmt.RSY.dl2,
13687 ovl.fmt.RSY.dh2); goto ok;
13688 case 0xeb000000000fULL: /* TRACG */ goto unimplemented;
13689 case 0xeb0000000014ULL: s390_format_RSY_RRRD(s390_irgen_CSY, ovl.fmt.RSY.r1,
13690 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13691 ovl.fmt.RSY.dl2,
13692 ovl.fmt.RSY.dh2); goto ok;
13693 case 0xeb000000001cULL: s390_format_RSY_RRRD(s390_irgen_RLLG, ovl.fmt.RSY.r1,
13694 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13695 ovl.fmt.RSY.dl2,
13696 ovl.fmt.RSY.dh2); goto ok;
13697 case 0xeb000000001dULL: s390_format_RSY_RRRD(s390_irgen_RLL, ovl.fmt.RSY.r1,
13698 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13699 ovl.fmt.RSY.dl2,
13700 ovl.fmt.RSY.dh2); goto ok;
13701 case 0xeb0000000020ULL: s390_format_RSY_RURD(s390_irgen_CLMH, ovl.fmt.RSY.r1,
13702 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13703 ovl.fmt.RSY.dl2,
13704 ovl.fmt.RSY.dh2); goto ok;
13705 case 0xeb0000000021ULL: s390_format_RSY_RURD(s390_irgen_CLMY, ovl.fmt.RSY.r1,
13706 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13707 ovl.fmt.RSY.dl2,
13708 ovl.fmt.RSY.dh2); goto ok;
13709 case 0xeb0000000024ULL: s390_format_RSY_RRRD(s390_irgen_STMG, ovl.fmt.RSY.r1,
13710 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13711 ovl.fmt.RSY.dl2,
13712 ovl.fmt.RSY.dh2); goto ok;
13713 case 0xeb0000000025ULL: /* STCTG */ goto unimplemented;
13714 case 0xeb0000000026ULL: s390_format_RSY_RRRD(s390_irgen_STMH, ovl.fmt.RSY.r1,
13715 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13716 ovl.fmt.RSY.dl2,
13717 ovl.fmt.RSY.dh2); goto ok;
13718 case 0xeb000000002cULL: s390_format_RSY_RURD(s390_irgen_STCMH,
13719 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
13720 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
13721 ovl.fmt.RSY.dh2); goto ok;
13722 case 0xeb000000002dULL: s390_format_RSY_RURD(s390_irgen_STCMY,
13723 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
13724 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
13725 ovl.fmt.RSY.dh2); goto ok;
13726 case 0xeb000000002fULL: /* LCTLG */ goto unimplemented;
13727 case 0xeb0000000030ULL: s390_format_RSY_RRRD(s390_irgen_CSG, ovl.fmt.RSY.r1,
13728 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13729 ovl.fmt.RSY.dl2,
13730 ovl.fmt.RSY.dh2); goto ok;
florian448cbba2012-06-06 02:26:01 +000013731 case 0xeb0000000031ULL: s390_format_RSY_RRRD(s390_irgen_CDSY, ovl.fmt.RSY.r1,
13732 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13733 ovl.fmt.RSY.dl2,
13734 ovl.fmt.RSY.dh2); goto ok;
13735 case 0xeb000000003eULL: s390_format_RSY_RRRD(s390_irgen_CDSG, ovl.fmt.RSY.r1,
13736 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13737 ovl.fmt.RSY.dl2,
13738 ovl.fmt.RSY.dh2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013739 case 0xeb0000000044ULL: s390_format_RSY_RRRD(s390_irgen_BXHG, ovl.fmt.RSY.r1,
13740 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13741 ovl.fmt.RSY.dl2,
13742 ovl.fmt.RSY.dh2); goto ok;
13743 case 0xeb0000000045ULL: s390_format_RSY_RRRD(s390_irgen_BXLEG,
13744 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
13745 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
13746 ovl.fmt.RSY.dh2); goto ok;
florian8c88cb62012-08-26 18:58:13 +000013747 case 0xeb000000004cULL: s390_format_RSY_RRRD(s390_irgen_ECAG, ovl.fmt.RSY.r1,
13748 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13749 ovl.fmt.RSY.dl2,
13750 ovl.fmt.RSY.dh2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013751 case 0xeb0000000051ULL: s390_format_SIY_URD(s390_irgen_TMY, ovl.fmt.SIY.i2,
13752 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
13753 ovl.fmt.SIY.dh1); goto ok;
13754 case 0xeb0000000052ULL: s390_format_SIY_URD(s390_irgen_MVIY, ovl.fmt.SIY.i2,
13755 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
13756 ovl.fmt.SIY.dh1); goto ok;
13757 case 0xeb0000000054ULL: s390_format_SIY_URD(s390_irgen_NIY, ovl.fmt.SIY.i2,
13758 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
13759 ovl.fmt.SIY.dh1); goto ok;
13760 case 0xeb0000000055ULL: s390_format_SIY_URD(s390_irgen_CLIY, ovl.fmt.SIY.i2,
13761 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
13762 ovl.fmt.SIY.dh1); goto ok;
13763 case 0xeb0000000056ULL: s390_format_SIY_URD(s390_irgen_OIY, ovl.fmt.SIY.i2,
13764 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
13765 ovl.fmt.SIY.dh1); goto ok;
13766 case 0xeb0000000057ULL: s390_format_SIY_URD(s390_irgen_XIY, ovl.fmt.SIY.i2,
13767 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
13768 ovl.fmt.SIY.dh1); goto ok;
13769 case 0xeb000000006aULL: s390_format_SIY_IRD(s390_irgen_ASI, ovl.fmt.SIY.i2,
13770 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
13771 ovl.fmt.SIY.dh1); goto ok;
13772 case 0xeb000000006eULL: s390_format_SIY_IRD(s390_irgen_ALSI, ovl.fmt.SIY.i2,
13773 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
13774 ovl.fmt.SIY.dh1); goto ok;
13775 case 0xeb000000007aULL: s390_format_SIY_IRD(s390_irgen_AGSI, ovl.fmt.SIY.i2,
13776 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
13777 ovl.fmt.SIY.dh1); goto ok;
13778 case 0xeb000000007eULL: s390_format_SIY_IRD(s390_irgen_ALGSI, ovl.fmt.SIY.i2,
13779 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
13780 ovl.fmt.SIY.dh1); goto ok;
13781 case 0xeb0000000080ULL: s390_format_RSY_RURD(s390_irgen_ICMH, ovl.fmt.RSY.r1,
13782 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13783 ovl.fmt.RSY.dl2,
13784 ovl.fmt.RSY.dh2); goto ok;
13785 case 0xeb0000000081ULL: s390_format_RSY_RURD(s390_irgen_ICMY, ovl.fmt.RSY.r1,
13786 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13787 ovl.fmt.RSY.dl2,
13788 ovl.fmt.RSY.dh2); goto ok;
13789 case 0xeb000000008eULL: /* MVCLU */ goto unimplemented;
13790 case 0xeb000000008fULL: /* CLCLU */ goto unimplemented;
13791 case 0xeb0000000090ULL: s390_format_RSY_RRRD(s390_irgen_STMY, ovl.fmt.RSY.r1,
13792 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13793 ovl.fmt.RSY.dl2,
13794 ovl.fmt.RSY.dh2); goto ok;
13795 case 0xeb0000000096ULL: s390_format_RSY_RRRD(s390_irgen_LMH, ovl.fmt.RSY.r1,
13796 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13797 ovl.fmt.RSY.dl2,
13798 ovl.fmt.RSY.dh2); goto ok;
13799 case 0xeb0000000098ULL: s390_format_RSY_RRRD(s390_irgen_LMY, ovl.fmt.RSY.r1,
13800 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13801 ovl.fmt.RSY.dl2,
13802 ovl.fmt.RSY.dh2); goto ok;
13803 case 0xeb000000009aULL: s390_format_RSY_AARD(s390_irgen_LAMY, ovl.fmt.RSY.r1,
13804 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13805 ovl.fmt.RSY.dl2,
13806 ovl.fmt.RSY.dh2); goto ok;
13807 case 0xeb000000009bULL: s390_format_RSY_AARD(s390_irgen_STAMY,
13808 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
13809 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
13810 ovl.fmt.RSY.dh2); goto ok;
13811 case 0xeb00000000c0ULL: /* TP */ goto unimplemented;
13812 case 0xeb00000000dcULL: s390_format_RSY_RRRD(s390_irgen_SRAK, ovl.fmt.RSY.r1,
13813 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13814 ovl.fmt.RSY.dl2,
13815 ovl.fmt.RSY.dh2); goto ok;
13816 case 0xeb00000000ddULL: s390_format_RSY_RRRD(s390_irgen_SLAK, ovl.fmt.RSY.r1,
13817 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13818 ovl.fmt.RSY.dl2,
13819 ovl.fmt.RSY.dh2); goto ok;
13820 case 0xeb00000000deULL: s390_format_RSY_RRRD(s390_irgen_SRLK, ovl.fmt.RSY.r1,
13821 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13822 ovl.fmt.RSY.dl2,
13823 ovl.fmt.RSY.dh2); goto ok;
13824 case 0xeb00000000dfULL: s390_format_RSY_RRRD(s390_irgen_SLLK, ovl.fmt.RSY.r1,
13825 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13826 ovl.fmt.RSY.dl2,
13827 ovl.fmt.RSY.dh2); goto ok;
sewardjd7bde722011-04-05 13:19:33 +000013828 case 0xeb00000000e2ULL: s390_format_RSY_RDRM(s390_irgen_LOCG, ovl.fmt.RSY.r1,
13829 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13830 ovl.fmt.RSY.dl2,
13831 ovl.fmt.RSY.dh2,
13832 S390_XMNM_LOCG); goto ok;
13833 case 0xeb00000000e3ULL: s390_format_RSY_RDRM(s390_irgen_STOCG,
13834 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
13835 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
13836 ovl.fmt.RSY.dh2,
13837 S390_XMNM_STOCG); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013838 case 0xeb00000000e4ULL: s390_format_RSY_RRRD(s390_irgen_LANG, ovl.fmt.RSY.r1,
13839 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13840 ovl.fmt.RSY.dl2,
13841 ovl.fmt.RSY.dh2); goto ok;
13842 case 0xeb00000000e6ULL: s390_format_RSY_RRRD(s390_irgen_LAOG, ovl.fmt.RSY.r1,
13843 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13844 ovl.fmt.RSY.dl2,
13845 ovl.fmt.RSY.dh2); goto ok;
13846 case 0xeb00000000e7ULL: s390_format_RSY_RRRD(s390_irgen_LAXG, ovl.fmt.RSY.r1,
13847 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13848 ovl.fmt.RSY.dl2,
13849 ovl.fmt.RSY.dh2); goto ok;
13850 case 0xeb00000000e8ULL: s390_format_RSY_RRRD(s390_irgen_LAAG, ovl.fmt.RSY.r1,
13851 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13852 ovl.fmt.RSY.dl2,
13853 ovl.fmt.RSY.dh2); goto ok;
13854 case 0xeb00000000eaULL: s390_format_RSY_RRRD(s390_irgen_LAALG,
13855 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
13856 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
13857 ovl.fmt.RSY.dh2); goto ok;
sewardjd7bde722011-04-05 13:19:33 +000013858 case 0xeb00000000f2ULL: s390_format_RSY_RDRM(s390_irgen_LOC, ovl.fmt.RSY.r1,
13859 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13860 ovl.fmt.RSY.dl2,
13861 ovl.fmt.RSY.dh2, S390_XMNM_LOC);
13862 goto ok;
13863 case 0xeb00000000f3ULL: s390_format_RSY_RDRM(s390_irgen_STOC, ovl.fmt.RSY.r1,
13864 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13865 ovl.fmt.RSY.dl2,
13866 ovl.fmt.RSY.dh2,
13867 S390_XMNM_STOC); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013868 case 0xeb00000000f4ULL: s390_format_RSY_RRRD(s390_irgen_LAN, ovl.fmt.RSY.r1,
13869 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13870 ovl.fmt.RSY.dl2,
13871 ovl.fmt.RSY.dh2); goto ok;
13872 case 0xeb00000000f6ULL: s390_format_RSY_RRRD(s390_irgen_LAO, ovl.fmt.RSY.r1,
13873 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13874 ovl.fmt.RSY.dl2,
13875 ovl.fmt.RSY.dh2); goto ok;
13876 case 0xeb00000000f7ULL: s390_format_RSY_RRRD(s390_irgen_LAX, ovl.fmt.RSY.r1,
13877 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13878 ovl.fmt.RSY.dl2,
13879 ovl.fmt.RSY.dh2); goto ok;
13880 case 0xeb00000000f8ULL: s390_format_RSY_RRRD(s390_irgen_LAA, ovl.fmt.RSY.r1,
13881 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13882 ovl.fmt.RSY.dl2,
13883 ovl.fmt.RSY.dh2); goto ok;
13884 case 0xeb00000000faULL: s390_format_RSY_RRRD(s390_irgen_LAAL, ovl.fmt.RSY.r1,
13885 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13886 ovl.fmt.RSY.dl2,
13887 ovl.fmt.RSY.dh2); goto ok;
13888 case 0xec0000000044ULL: s390_format_RIE_RRP(s390_irgen_BRXHG, ovl.fmt.RIE.r1,
13889 ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
13890 goto ok;
13891 case 0xec0000000045ULL: s390_format_RIE_RRP(s390_irgen_BRXLG, ovl.fmt.RIE.r1,
13892 ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
13893 goto ok;
13894 case 0xec0000000051ULL: /* RISBLG */ goto unimplemented;
13895 case 0xec0000000054ULL: s390_format_RIE_RRUUU(s390_irgen_RNSBG,
13896 ovl.fmt.RIE_RRUUU.r1,
13897 ovl.fmt.RIE_RRUUU.r2,
13898 ovl.fmt.RIE_RRUUU.i3,
13899 ovl.fmt.RIE_RRUUU.i4,
13900 ovl.fmt.RIE_RRUUU.i5);
13901 goto ok;
13902 case 0xec0000000055ULL: s390_format_RIE_RRUUU(s390_irgen_RISBG,
13903 ovl.fmt.RIE_RRUUU.r1,
13904 ovl.fmt.RIE_RRUUU.r2,
13905 ovl.fmt.RIE_RRUUU.i3,
13906 ovl.fmt.RIE_RRUUU.i4,
13907 ovl.fmt.RIE_RRUUU.i5);
13908 goto ok;
13909 case 0xec0000000056ULL: s390_format_RIE_RRUUU(s390_irgen_ROSBG,
13910 ovl.fmt.RIE_RRUUU.r1,
13911 ovl.fmt.RIE_RRUUU.r2,
13912 ovl.fmt.RIE_RRUUU.i3,
13913 ovl.fmt.RIE_RRUUU.i4,
13914 ovl.fmt.RIE_RRUUU.i5);
13915 goto ok;
13916 case 0xec0000000057ULL: s390_format_RIE_RRUUU(s390_irgen_RXSBG,
13917 ovl.fmt.RIE_RRUUU.r1,
13918 ovl.fmt.RIE_RRUUU.r2,
13919 ovl.fmt.RIE_RRUUU.i3,
13920 ovl.fmt.RIE_RRUUU.i4,
13921 ovl.fmt.RIE_RRUUU.i5);
13922 goto ok;
13923 case 0xec000000005dULL: /* RISBHG */ goto unimplemented;
13924 case 0xec0000000064ULL: s390_format_RIE_RRPU(s390_irgen_CGRJ,
13925 ovl.fmt.RIE_RRPU.r1,
13926 ovl.fmt.RIE_RRPU.r2,
13927 ovl.fmt.RIE_RRPU.i4,
13928 ovl.fmt.RIE_RRPU.m3); goto ok;
13929 case 0xec0000000065ULL: s390_format_RIE_RRPU(s390_irgen_CLGRJ,
13930 ovl.fmt.RIE_RRPU.r1,
13931 ovl.fmt.RIE_RRPU.r2,
13932 ovl.fmt.RIE_RRPU.i4,
13933 ovl.fmt.RIE_RRPU.m3); goto ok;
13934 case 0xec0000000070ULL: /* CGIT */ goto unimplemented;
13935 case 0xec0000000071ULL: /* CLGIT */ goto unimplemented;
13936 case 0xec0000000072ULL: /* CIT */ goto unimplemented;
13937 case 0xec0000000073ULL: /* CLFIT */ goto unimplemented;
13938 case 0xec0000000076ULL: s390_format_RIE_RRPU(s390_irgen_CRJ,
13939 ovl.fmt.RIE_RRPU.r1,
13940 ovl.fmt.RIE_RRPU.r2,
13941 ovl.fmt.RIE_RRPU.i4,
13942 ovl.fmt.RIE_RRPU.m3); goto ok;
13943 case 0xec0000000077ULL: s390_format_RIE_RRPU(s390_irgen_CLRJ,
13944 ovl.fmt.RIE_RRPU.r1,
13945 ovl.fmt.RIE_RRPU.r2,
13946 ovl.fmt.RIE_RRPU.i4,
13947 ovl.fmt.RIE_RRPU.m3); goto ok;
13948 case 0xec000000007cULL: s390_format_RIE_RUPI(s390_irgen_CGIJ,
13949 ovl.fmt.RIEv3.r1,
13950 ovl.fmt.RIEv3.m3,
13951 ovl.fmt.RIEv3.i4,
13952 ovl.fmt.RIEv3.i2); goto ok;
13953 case 0xec000000007dULL: s390_format_RIE_RUPU(s390_irgen_CLGIJ,
13954 ovl.fmt.RIEv3.r1,
13955 ovl.fmt.RIEv3.m3,
13956 ovl.fmt.RIEv3.i4,
13957 ovl.fmt.RIEv3.i2); goto ok;
13958 case 0xec000000007eULL: s390_format_RIE_RUPI(s390_irgen_CIJ,
13959 ovl.fmt.RIEv3.r1,
13960 ovl.fmt.RIEv3.m3,
13961 ovl.fmt.RIEv3.i4,
13962 ovl.fmt.RIEv3.i2); goto ok;
13963 case 0xec000000007fULL: s390_format_RIE_RUPU(s390_irgen_CLIJ,
13964 ovl.fmt.RIEv3.r1,
13965 ovl.fmt.RIEv3.m3,
13966 ovl.fmt.RIEv3.i4,
13967 ovl.fmt.RIEv3.i2); goto ok;
13968 case 0xec00000000d8ULL: s390_format_RIE_RRI0(s390_irgen_AHIK, ovl.fmt.RIE.r1,
13969 ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
13970 goto ok;
13971 case 0xec00000000d9ULL: s390_format_RIE_RRI0(s390_irgen_AGHIK,
13972 ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
13973 ovl.fmt.RIE.i2); goto ok;
13974 case 0xec00000000daULL: s390_format_RIE_RRI0(s390_irgen_ALHSIK,
13975 ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
13976 ovl.fmt.RIE.i2); goto ok;
13977 case 0xec00000000dbULL: s390_format_RIE_RRI0(s390_irgen_ALGHSIK,
13978 ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
13979 ovl.fmt.RIE.i2); goto ok;
13980 case 0xec00000000e4ULL: s390_format_RRS(s390_irgen_CGRB, ovl.fmt.RRS.r1,
13981 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
13982 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
13983 goto ok;
13984 case 0xec00000000e5ULL: s390_format_RRS(s390_irgen_CLGRB, ovl.fmt.RRS.r1,
13985 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
13986 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
13987 goto ok;
13988 case 0xec00000000f6ULL: s390_format_RRS(s390_irgen_CRB, ovl.fmt.RRS.r1,
13989 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
13990 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
13991 goto ok;
13992 case 0xec00000000f7ULL: s390_format_RRS(s390_irgen_CLRB, ovl.fmt.RRS.r1,
13993 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
13994 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
13995 goto ok;
13996 case 0xec00000000fcULL: s390_format_RIS_RURDI(s390_irgen_CGIB,
13997 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
13998 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
13999 ovl.fmt.RIS.i2); goto ok;
14000 case 0xec00000000fdULL: s390_format_RIS_RURDU(s390_irgen_CLGIB,
14001 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
14002 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
14003 ovl.fmt.RIS.i2); goto ok;
14004 case 0xec00000000feULL: s390_format_RIS_RURDI(s390_irgen_CIB, ovl.fmt.RIS.r1,
14005 ovl.fmt.RIS.m3, ovl.fmt.RIS.b4,
14006 ovl.fmt.RIS.d4,
14007 ovl.fmt.RIS.i2); goto ok;
14008 case 0xec00000000ffULL: s390_format_RIS_RURDU(s390_irgen_CLIB,
14009 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
14010 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
14011 ovl.fmt.RIS.i2); goto ok;
14012 case 0xed0000000004ULL: s390_format_RXE_FRRD(s390_irgen_LDEB, ovl.fmt.RXE.r1,
14013 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14014 ovl.fmt.RXE.d2); goto ok;
14015 case 0xed0000000005ULL: s390_format_RXE_FRRD(s390_irgen_LXDB, ovl.fmt.RXE.r1,
14016 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14017 ovl.fmt.RXE.d2); goto ok;
14018 case 0xed0000000006ULL: s390_format_RXE_FRRD(s390_irgen_LXEB, ovl.fmt.RXE.r1,
14019 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14020 ovl.fmt.RXE.d2); goto ok;
14021 case 0xed0000000007ULL: /* MXDB */ goto unimplemented;
14022 case 0xed0000000008ULL: /* KEB */ goto unimplemented;
14023 case 0xed0000000009ULL: s390_format_RXE_FRRD(s390_irgen_CEB, ovl.fmt.RXE.r1,
14024 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14025 ovl.fmt.RXE.d2); goto ok;
14026 case 0xed000000000aULL: s390_format_RXE_FRRD(s390_irgen_AEB, ovl.fmt.RXE.r1,
14027 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14028 ovl.fmt.RXE.d2); goto ok;
14029 case 0xed000000000bULL: s390_format_RXE_FRRD(s390_irgen_SEB, ovl.fmt.RXE.r1,
14030 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14031 ovl.fmt.RXE.d2); goto ok;
14032 case 0xed000000000cULL: /* MDEB */ goto unimplemented;
14033 case 0xed000000000dULL: s390_format_RXE_FRRD(s390_irgen_DEB, ovl.fmt.RXE.r1,
14034 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14035 ovl.fmt.RXE.d2); goto ok;
14036 case 0xed000000000eULL: s390_format_RXF_FRRDF(s390_irgen_MAEB,
14037 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
14038 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
14039 ovl.fmt.RXF.r1); goto ok;
14040 case 0xed000000000fULL: s390_format_RXF_FRRDF(s390_irgen_MSEB,
14041 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
14042 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
14043 ovl.fmt.RXF.r1); goto ok;
14044 case 0xed0000000010ULL: s390_format_RXE_FRRD(s390_irgen_TCEB, ovl.fmt.RXE.r1,
14045 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14046 ovl.fmt.RXE.d2); goto ok;
14047 case 0xed0000000011ULL: s390_format_RXE_FRRD(s390_irgen_TCDB, ovl.fmt.RXE.r1,
14048 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14049 ovl.fmt.RXE.d2); goto ok;
14050 case 0xed0000000012ULL: s390_format_RXE_FRRD(s390_irgen_TCXB, ovl.fmt.RXE.r1,
14051 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14052 ovl.fmt.RXE.d2); goto ok;
14053 case 0xed0000000014ULL: s390_format_RXE_FRRD(s390_irgen_SQEB, ovl.fmt.RXE.r1,
14054 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14055 ovl.fmt.RXE.d2); goto ok;
14056 case 0xed0000000015ULL: s390_format_RXE_FRRD(s390_irgen_SQDB, ovl.fmt.RXE.r1,
14057 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14058 ovl.fmt.RXE.d2); goto ok;
14059 case 0xed0000000017ULL: s390_format_RXE_FRRD(s390_irgen_MEEB, ovl.fmt.RXE.r1,
14060 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14061 ovl.fmt.RXE.d2); goto ok;
14062 case 0xed0000000018ULL: /* KDB */ goto unimplemented;
14063 case 0xed0000000019ULL: s390_format_RXE_FRRD(s390_irgen_CDB, ovl.fmt.RXE.r1,
14064 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14065 ovl.fmt.RXE.d2); goto ok;
14066 case 0xed000000001aULL: s390_format_RXE_FRRD(s390_irgen_ADB, ovl.fmt.RXE.r1,
14067 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14068 ovl.fmt.RXE.d2); goto ok;
14069 case 0xed000000001bULL: s390_format_RXE_FRRD(s390_irgen_SDB, ovl.fmt.RXE.r1,
14070 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14071 ovl.fmt.RXE.d2); goto ok;
14072 case 0xed000000001cULL: s390_format_RXE_FRRD(s390_irgen_MDB, ovl.fmt.RXE.r1,
14073 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14074 ovl.fmt.RXE.d2); goto ok;
14075 case 0xed000000001dULL: s390_format_RXE_FRRD(s390_irgen_DDB, ovl.fmt.RXE.r1,
14076 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14077 ovl.fmt.RXE.d2); goto ok;
14078 case 0xed000000001eULL: s390_format_RXF_FRRDF(s390_irgen_MADB,
14079 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
14080 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
14081 ovl.fmt.RXF.r1); goto ok;
14082 case 0xed000000001fULL: s390_format_RXF_FRRDF(s390_irgen_MSDB,
14083 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
14084 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
14085 ovl.fmt.RXF.r1); goto ok;
14086 case 0xed0000000024ULL: /* LDE */ goto unimplemented;
14087 case 0xed0000000025ULL: /* LXD */ goto unimplemented;
14088 case 0xed0000000026ULL: /* LXE */ goto unimplemented;
14089 case 0xed000000002eULL: /* MAE */ goto unimplemented;
14090 case 0xed000000002fULL: /* MSE */ goto unimplemented;
14091 case 0xed0000000034ULL: /* SQE */ goto unimplemented;
14092 case 0xed0000000035ULL: /* SQD */ goto unimplemented;
14093 case 0xed0000000037ULL: /* MEE */ goto unimplemented;
14094 case 0xed0000000038ULL: /* MAYL */ goto unimplemented;
14095 case 0xed0000000039ULL: /* MYL */ goto unimplemented;
14096 case 0xed000000003aULL: /* MAY */ goto unimplemented;
14097 case 0xed000000003bULL: /* MY */ goto unimplemented;
14098 case 0xed000000003cULL: /* MAYH */ goto unimplemented;
14099 case 0xed000000003dULL: /* MYH */ goto unimplemented;
14100 case 0xed000000003eULL: /* MAD */ goto unimplemented;
14101 case 0xed000000003fULL: /* MSD */ goto unimplemented;
14102 case 0xed0000000040ULL: /* SLDT */ goto unimplemented;
14103 case 0xed0000000041ULL: /* SRDT */ goto unimplemented;
14104 case 0xed0000000048ULL: /* SLXT */ goto unimplemented;
14105 case 0xed0000000049ULL: /* SRXT */ goto unimplemented;
14106 case 0xed0000000050ULL: /* TDCET */ goto unimplemented;
14107 case 0xed0000000051ULL: /* TDGET */ goto unimplemented;
14108 case 0xed0000000054ULL: /* TDCDT */ goto unimplemented;
14109 case 0xed0000000055ULL: /* TDGDT */ goto unimplemented;
14110 case 0xed0000000058ULL: /* TDCXT */ goto unimplemented;
14111 case 0xed0000000059ULL: /* TDGXT */ goto unimplemented;
14112 case 0xed0000000064ULL: s390_format_RXY_FRRD(s390_irgen_LEY, ovl.fmt.RXY.r1,
14113 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14114 ovl.fmt.RXY.dl2,
14115 ovl.fmt.RXY.dh2); goto ok;
14116 case 0xed0000000065ULL: s390_format_RXY_FRRD(s390_irgen_LDY, ovl.fmt.RXY.r1,
14117 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14118 ovl.fmt.RXY.dl2,
14119 ovl.fmt.RXY.dh2); goto ok;
14120 case 0xed0000000066ULL: s390_format_RXY_FRRD(s390_irgen_STEY, ovl.fmt.RXY.r1,
14121 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14122 ovl.fmt.RXY.dl2,
14123 ovl.fmt.RXY.dh2); goto ok;
14124 case 0xed0000000067ULL: s390_format_RXY_FRRD(s390_irgen_STDY, ovl.fmt.RXY.r1,
14125 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14126 ovl.fmt.RXY.dl2,
14127 ovl.fmt.RXY.dh2); goto ok;
14128 }
14129
14130 switch (((ovl.value >> 16) & 0xff0f00000000ULL) >> 32) {
14131 case 0xc000ULL: s390_format_RIL_RP(s390_irgen_LARL, ovl.fmt.RIL.r1,
14132 ovl.fmt.RIL.i2); goto ok;
14133 case 0xc001ULL: s390_format_RIL_RI(s390_irgen_LGFI, ovl.fmt.RIL.r1,
14134 ovl.fmt.RIL.i2); goto ok;
14135 case 0xc004ULL: s390_format_RIL(s390_irgen_BRCL, ovl.fmt.RIL.r1,
14136 ovl.fmt.RIL.i2); goto ok;
14137 case 0xc005ULL: s390_format_RIL_RP(s390_irgen_BRASL, ovl.fmt.RIL.r1,
14138 ovl.fmt.RIL.i2); goto ok;
14139 case 0xc006ULL: s390_format_RIL_RU(s390_irgen_XIHF, ovl.fmt.RIL.r1,
14140 ovl.fmt.RIL.i2); goto ok;
14141 case 0xc007ULL: s390_format_RIL_RU(s390_irgen_XILF, ovl.fmt.RIL.r1,
14142 ovl.fmt.RIL.i2); goto ok;
14143 case 0xc008ULL: s390_format_RIL_RU(s390_irgen_IIHF, ovl.fmt.RIL.r1,
14144 ovl.fmt.RIL.i2); goto ok;
14145 case 0xc009ULL: s390_format_RIL_RU(s390_irgen_IILF, ovl.fmt.RIL.r1,
14146 ovl.fmt.RIL.i2); goto ok;
14147 case 0xc00aULL: s390_format_RIL_RU(s390_irgen_NIHF, ovl.fmt.RIL.r1,
14148 ovl.fmt.RIL.i2); goto ok;
14149 case 0xc00bULL: s390_format_RIL_RU(s390_irgen_NILF, ovl.fmt.RIL.r1,
14150 ovl.fmt.RIL.i2); goto ok;
14151 case 0xc00cULL: s390_format_RIL_RU(s390_irgen_OIHF, ovl.fmt.RIL.r1,
14152 ovl.fmt.RIL.i2); goto ok;
14153 case 0xc00dULL: s390_format_RIL_RU(s390_irgen_OILF, ovl.fmt.RIL.r1,
14154 ovl.fmt.RIL.i2); goto ok;
14155 case 0xc00eULL: s390_format_RIL_RU(s390_irgen_LLIHF, ovl.fmt.RIL.r1,
14156 ovl.fmt.RIL.i2); goto ok;
14157 case 0xc00fULL: s390_format_RIL_RU(s390_irgen_LLILF, ovl.fmt.RIL.r1,
14158 ovl.fmt.RIL.i2); goto ok;
14159 case 0xc200ULL: s390_format_RIL_RI(s390_irgen_MSGFI, ovl.fmt.RIL.r1,
14160 ovl.fmt.RIL.i2); goto ok;
14161 case 0xc201ULL: s390_format_RIL_RI(s390_irgen_MSFI, ovl.fmt.RIL.r1,
14162 ovl.fmt.RIL.i2); goto ok;
14163 case 0xc204ULL: s390_format_RIL_RU(s390_irgen_SLGFI, ovl.fmt.RIL.r1,
14164 ovl.fmt.RIL.i2); goto ok;
14165 case 0xc205ULL: s390_format_RIL_RU(s390_irgen_SLFI, ovl.fmt.RIL.r1,
14166 ovl.fmt.RIL.i2); goto ok;
14167 case 0xc208ULL: s390_format_RIL_RI(s390_irgen_AGFI, ovl.fmt.RIL.r1,
14168 ovl.fmt.RIL.i2); goto ok;
14169 case 0xc209ULL: s390_format_RIL_RI(s390_irgen_AFI, ovl.fmt.RIL.r1,
14170 ovl.fmt.RIL.i2); goto ok;
14171 case 0xc20aULL: s390_format_RIL_RU(s390_irgen_ALGFI, ovl.fmt.RIL.r1,
14172 ovl.fmt.RIL.i2); goto ok;
14173 case 0xc20bULL: s390_format_RIL_RU(s390_irgen_ALFI, ovl.fmt.RIL.r1,
14174 ovl.fmt.RIL.i2); goto ok;
14175 case 0xc20cULL: s390_format_RIL_RI(s390_irgen_CGFI, ovl.fmt.RIL.r1,
14176 ovl.fmt.RIL.i2); goto ok;
14177 case 0xc20dULL: s390_format_RIL_RI(s390_irgen_CFI, ovl.fmt.RIL.r1,
14178 ovl.fmt.RIL.i2); goto ok;
14179 case 0xc20eULL: s390_format_RIL_RU(s390_irgen_CLGFI, ovl.fmt.RIL.r1,
14180 ovl.fmt.RIL.i2); goto ok;
14181 case 0xc20fULL: s390_format_RIL_RU(s390_irgen_CLFI, ovl.fmt.RIL.r1,
14182 ovl.fmt.RIL.i2); goto ok;
14183 case 0xc402ULL: s390_format_RIL_RP(s390_irgen_LLHRL, ovl.fmt.RIL.r1,
14184 ovl.fmt.RIL.i2); goto ok;
14185 case 0xc404ULL: s390_format_RIL_RP(s390_irgen_LGHRL, ovl.fmt.RIL.r1,
14186 ovl.fmt.RIL.i2); goto ok;
14187 case 0xc405ULL: s390_format_RIL_RP(s390_irgen_LHRL, ovl.fmt.RIL.r1,
14188 ovl.fmt.RIL.i2); goto ok;
14189 case 0xc406ULL: s390_format_RIL_RP(s390_irgen_LLGHRL, ovl.fmt.RIL.r1,
14190 ovl.fmt.RIL.i2); goto ok;
14191 case 0xc407ULL: s390_format_RIL_RP(s390_irgen_STHRL, ovl.fmt.RIL.r1,
14192 ovl.fmt.RIL.i2); goto ok;
14193 case 0xc408ULL: s390_format_RIL_RP(s390_irgen_LGRL, ovl.fmt.RIL.r1,
14194 ovl.fmt.RIL.i2); goto ok;
14195 case 0xc40bULL: s390_format_RIL_RP(s390_irgen_STGRL, ovl.fmt.RIL.r1,
14196 ovl.fmt.RIL.i2); goto ok;
14197 case 0xc40cULL: s390_format_RIL_RP(s390_irgen_LGFRL, ovl.fmt.RIL.r1,
14198 ovl.fmt.RIL.i2); goto ok;
14199 case 0xc40dULL: s390_format_RIL_RP(s390_irgen_LRL, ovl.fmt.RIL.r1,
14200 ovl.fmt.RIL.i2); goto ok;
14201 case 0xc40eULL: s390_format_RIL_RP(s390_irgen_LLGFRL, ovl.fmt.RIL.r1,
14202 ovl.fmt.RIL.i2); goto ok;
14203 case 0xc40fULL: s390_format_RIL_RP(s390_irgen_STRL, ovl.fmt.RIL.r1,
14204 ovl.fmt.RIL.i2); goto ok;
14205 case 0xc600ULL: s390_format_RIL_RP(s390_irgen_EXRL, ovl.fmt.RIL.r1,
14206 ovl.fmt.RIL.i2); goto ok;
14207 case 0xc602ULL: s390_format_RIL_UP(s390_irgen_PFDRL, ovl.fmt.RIL.r1,
14208 ovl.fmt.RIL.i2); goto ok;
14209 case 0xc604ULL: s390_format_RIL_RP(s390_irgen_CGHRL, ovl.fmt.RIL.r1,
14210 ovl.fmt.RIL.i2); goto ok;
14211 case 0xc605ULL: s390_format_RIL_RP(s390_irgen_CHRL, ovl.fmt.RIL.r1,
14212 ovl.fmt.RIL.i2); goto ok;
14213 case 0xc606ULL: s390_format_RIL_RP(s390_irgen_CLGHRL, ovl.fmt.RIL.r1,
14214 ovl.fmt.RIL.i2); goto ok;
14215 case 0xc607ULL: s390_format_RIL_RP(s390_irgen_CLHRL, ovl.fmt.RIL.r1,
14216 ovl.fmt.RIL.i2); goto ok;
14217 case 0xc608ULL: s390_format_RIL_RP(s390_irgen_CGRL, ovl.fmt.RIL.r1,
14218 ovl.fmt.RIL.i2); goto ok;
14219 case 0xc60aULL: s390_format_RIL_RP(s390_irgen_CLGRL, ovl.fmt.RIL.r1,
14220 ovl.fmt.RIL.i2); goto ok;
14221 case 0xc60cULL: s390_format_RIL_RP(s390_irgen_CGFRL, ovl.fmt.RIL.r1,
14222 ovl.fmt.RIL.i2); goto ok;
14223 case 0xc60dULL: s390_format_RIL_RP(s390_irgen_CRL, ovl.fmt.RIL.r1,
14224 ovl.fmt.RIL.i2); goto ok;
14225 case 0xc60eULL: s390_format_RIL_RP(s390_irgen_CLGFRL, ovl.fmt.RIL.r1,
14226 ovl.fmt.RIL.i2); goto ok;
14227 case 0xc60fULL: s390_format_RIL_RP(s390_irgen_CLRL, ovl.fmt.RIL.r1,
14228 ovl.fmt.RIL.i2); goto ok;
14229 case 0xc800ULL: /* MVCOS */ goto unimplemented;
14230 case 0xc801ULL: /* ECTG */ goto unimplemented;
14231 case 0xc802ULL: /* CSST */ goto unimplemented;
14232 case 0xc804ULL: /* LPD */ goto unimplemented;
14233 case 0xc805ULL: /* LPDG */ goto unimplemented;
14234 case 0xcc06ULL: /* BRCTH */ goto unimplemented;
14235 case 0xcc08ULL: s390_format_RIL_RI(s390_irgen_AIH, ovl.fmt.RIL.r1,
14236 ovl.fmt.RIL.i2); goto ok;
14237 case 0xcc0aULL: s390_format_RIL_RI(s390_irgen_ALSIH, ovl.fmt.RIL.r1,
14238 ovl.fmt.RIL.i2); goto ok;
14239 case 0xcc0bULL: s390_format_RIL_RI(s390_irgen_ALSIHN, ovl.fmt.RIL.r1,
14240 ovl.fmt.RIL.i2); goto ok;
14241 case 0xcc0dULL: s390_format_RIL_RI(s390_irgen_CIH, ovl.fmt.RIL.r1,
14242 ovl.fmt.RIL.i2); goto ok;
14243 case 0xcc0fULL: s390_format_RIL_RU(s390_irgen_CLIH, ovl.fmt.RIL.r1,
14244 ovl.fmt.RIL.i2); goto ok;
14245 }
14246
14247 switch (((ovl.value >> 16) & 0xff0000000000ULL) >> 40) {
14248 case 0xd0ULL: /* TRTR */ goto unimplemented;
14249 case 0xd1ULL: /* MVN */ goto unimplemented;
14250 case 0xd2ULL: s390_format_SS_L0RDRD(s390_irgen_MVC, ovl.fmt.SS.l,
14251 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
14252 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
14253 case 0xd3ULL: /* MVZ */ goto unimplemented;
14254 case 0xd4ULL: s390_format_SS_L0RDRD(s390_irgen_NC, ovl.fmt.SS.l,
14255 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
14256 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
14257 case 0xd5ULL: s390_format_SS_L0RDRD(s390_irgen_CLC, ovl.fmt.SS.l,
14258 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
14259 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
14260 case 0xd6ULL: s390_format_SS_L0RDRD(s390_irgen_OC, ovl.fmt.SS.l,
14261 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
14262 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
sewardjb63967e2011-03-24 08:50:04 +000014263 case 0xd7ULL:
14264 if (ovl.fmt.SS.b1 == ovl.fmt.SS.b2 && ovl.fmt.SS.d1 == ovl.fmt.SS.d2)
14265 s390_irgen_XC_sameloc(ovl.fmt.SS.l, ovl.fmt.SS.b1, ovl.fmt.SS.d1);
14266 else
14267 s390_format_SS_L0RDRD(s390_irgen_XC, ovl.fmt.SS.l,
14268 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
14269 ovl.fmt.SS.b2, ovl.fmt.SS.d2);
14270 goto ok;
sewardj2019a972011-03-07 16:04:07 +000014271 case 0xd9ULL: /* MVCK */ goto unimplemented;
14272 case 0xdaULL: /* MVCP */ goto unimplemented;
14273 case 0xdbULL: /* MVCS */ goto unimplemented;
florian730448f2012-02-04 17:07:07 +000014274 case 0xdcULL: s390_format_SS_L0RDRD(s390_irgen_TR, ovl.fmt.SS.l,
14275 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
14276 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014277 case 0xddULL: /* TRT */ goto unimplemented;
14278 case 0xdeULL: /* ED */ goto unimplemented;
14279 case 0xdfULL: /* EDMK */ goto unimplemented;
14280 case 0xe1ULL: /* PKU */ goto unimplemented;
14281 case 0xe2ULL: /* UNPKU */ goto unimplemented;
14282 case 0xe8ULL: /* MVCIN */ goto unimplemented;
14283 case 0xe9ULL: /* PKA */ goto unimplemented;
14284 case 0xeaULL: /* UNPKA */ goto unimplemented;
14285 case 0xeeULL: /* PLO */ goto unimplemented;
14286 case 0xefULL: /* LMD */ goto unimplemented;
14287 case 0xf0ULL: /* SRP */ goto unimplemented;
14288 case 0xf1ULL: /* MVO */ goto unimplemented;
14289 case 0xf2ULL: /* PACK */ goto unimplemented;
14290 case 0xf3ULL: /* UNPK */ goto unimplemented;
14291 case 0xf8ULL: /* ZAP */ goto unimplemented;
14292 case 0xf9ULL: /* CP */ goto unimplemented;
14293 case 0xfaULL: /* AP */ goto unimplemented;
14294 case 0xfbULL: /* SP */ goto unimplemented;
14295 case 0xfcULL: /* MP */ goto unimplemented;
14296 case 0xfdULL: /* DP */ goto unimplemented;
14297 }
14298
14299 switch (((ovl.value >> 16) & 0xffff00000000ULL) >> 32) {
14300 case 0xe500ULL: /* LASP */ goto unimplemented;
14301 case 0xe501ULL: /* TPROT */ goto unimplemented;
14302 case 0xe502ULL: /* STRAG */ goto unimplemented;
14303 case 0xe50eULL: /* MVCSK */ goto unimplemented;
14304 case 0xe50fULL: /* MVCDK */ goto unimplemented;
14305 case 0xe544ULL: s390_format_SIL_RDI(s390_irgen_MVHHI, ovl.fmt.SIL.b1,
14306 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14307 goto ok;
14308 case 0xe548ULL: s390_format_SIL_RDI(s390_irgen_MVGHI, ovl.fmt.SIL.b1,
14309 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14310 goto ok;
14311 case 0xe54cULL: s390_format_SIL_RDI(s390_irgen_MVHI, ovl.fmt.SIL.b1,
14312 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14313 goto ok;
14314 case 0xe554ULL: s390_format_SIL_RDI(s390_irgen_CHHSI, ovl.fmt.SIL.b1,
14315 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14316 goto ok;
14317 case 0xe555ULL: s390_format_SIL_RDU(s390_irgen_CLHHSI, ovl.fmt.SIL.b1,
14318 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14319 goto ok;
14320 case 0xe558ULL: s390_format_SIL_RDI(s390_irgen_CGHSI, ovl.fmt.SIL.b1,
14321 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14322 goto ok;
14323 case 0xe559ULL: s390_format_SIL_RDU(s390_irgen_CLGHSI, ovl.fmt.SIL.b1,
14324 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14325 goto ok;
14326 case 0xe55cULL: s390_format_SIL_RDI(s390_irgen_CHSI, ovl.fmt.SIL.b1,
14327 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14328 goto ok;
14329 case 0xe55dULL: s390_format_SIL_RDU(s390_irgen_CLFHSI, ovl.fmt.SIL.b1,
14330 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14331 goto ok;
14332 }
14333
14334 return S390_DECODE_UNKNOWN_INSN;
14335
14336ok:
14337 return S390_DECODE_OK;
14338
14339unimplemented:
14340 return S390_DECODE_UNIMPLEMENTED_INSN;
14341}
14342
14343/* Handle "special" instructions. */
14344static s390_decode_t
14345s390_decode_special_and_irgen(UChar *bytes)
14346{
14347 s390_decode_t status = S390_DECODE_OK;
14348
14349 /* Got a "Special" instruction preamble. Which one is it? */
14350 if (bytes[0] == 0x18 && bytes[1] == 0x22 /* lr %r2, %r2 */) {
14351 s390_irgen_client_request();
14352 } else if (bytes[0] == 0x18 && bytes[1] == 0x33 /* lr %r3, %r3 */) {
14353 s390_irgen_guest_NRADDR();
14354 } else if (bytes[0] == 0x18 && bytes[1] == 0x44 /* lr %r4, %r4 */) {
14355 s390_irgen_call_noredir();
florian2245ce92012-08-28 16:49:30 +000014356 } else if (bytes[0] == 0x18 && bytes[1] == 0x55 /* lr %r5, %r5 */) {
14357 vex_inject_ir(irsb, Iend_BE);
14358
14359 /* Invalidate the current insn. The reason is that the IRop we're
14360 injecting here can change. In which case the translation has to
14361 be redone. For ease of handling, we simply invalidate all the
14362 time. */
14363 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART),
14364 mkU64(guest_IA_curr_instr)));
14365 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN),
14366 mkU64(guest_IA_next_instr - guest_IA_curr_instr)));
14367 vassert(guest_IA_next_instr - guest_IA_curr_instr ==
14368 S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE);
14369
14370 put_IA(mkaddr_expr(guest_IA_next_instr));
14371 dis_res->whatNext = Dis_StopHere;
14372 dis_res->jk_StopHere = Ijk_TInval;
sewardj2019a972011-03-07 16:04:07 +000014373 } else {
14374 /* We don't know what it is. */
14375 return S390_DECODE_UNKNOWN_SPECIAL_INSN;
14376 }
14377
14378 dis_res->len = S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE;
14379
14380 return status;
14381}
14382
14383
14384/* Function returns # bytes that were decoded or 0 in case of failure */
florianb4df7682011-07-05 02:09:01 +000014385static UInt
sewardj2019a972011-03-07 16:04:07 +000014386s390_decode_and_irgen(UChar *bytes, UInt insn_length, DisResult *dres)
14387{
14388 s390_decode_t status;
14389
14390 dis_res = dres;
14391
14392 /* Spot the 8-byte preamble: 18ff lr r15,r15
14393 1811 lr r1,r1
14394 1822 lr r2,r2
14395 1833 lr r3,r3 */
14396 if (bytes[ 0] == 0x18 && bytes[ 1] == 0xff && bytes[ 2] == 0x18 &&
14397 bytes[ 3] == 0x11 && bytes[ 4] == 0x18 && bytes[ 5] == 0x22 &&
14398 bytes[ 6] == 0x18 && bytes[ 7] == 0x33) {
14399
14400 /* Handle special instruction that follows that preamble. */
14401 if (0) vex_printf("special function handling...\n");
florian2c8ed942011-08-01 22:07:51 +000014402
14403 insn_length = S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE;
14404 guest_IA_next_instr = guest_IA_curr_instr + insn_length;
14405
14406 status =
14407 s390_decode_special_and_irgen(bytes + S390_SPECIAL_OP_PREAMBLE_SIZE);
sewardj2019a972011-03-07 16:04:07 +000014408 } else {
14409 /* Handle normal instructions. */
14410 switch (insn_length) {
14411 case 2:
14412 status = s390_decode_2byte_and_irgen(bytes);
14413 break;
14414
14415 case 4:
14416 status = s390_decode_4byte_and_irgen(bytes);
14417 break;
14418
14419 case 6:
14420 status = s390_decode_6byte_and_irgen(bytes);
14421 break;
14422
14423 default:
14424 status = S390_DECODE_ERROR;
14425 break;
14426 }
14427 }
florian5fcbba22011-07-27 20:40:22 +000014428 /* If next instruction is execute, stop here */
florianf9e1ed72012-04-17 02:41:56 +000014429 if (dis_res->whatNext == Dis_Continue && bytes[insn_length] == 0x44) {
14430 put_IA(mkaddr_expr(guest_IA_next_instr));
sewardj2019a972011-03-07 16:04:07 +000014431 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +000014432 dis_res->jk_StopHere = Ijk_Boring;
sewardj2019a972011-03-07 16:04:07 +000014433 }
14434
14435 if (status == S390_DECODE_OK) return insn_length; /* OK */
14436
14437 /* Decoding failed somehow */
14438 vex_printf("vex s390->IR: ");
14439 switch (status) {
14440 case S390_DECODE_UNKNOWN_INSN:
14441 vex_printf("unknown insn: ");
14442 break;
14443
14444 case S390_DECODE_UNIMPLEMENTED_INSN:
14445 vex_printf("unimplemented insn: ");
14446 break;
14447
14448 case S390_DECODE_UNKNOWN_SPECIAL_INSN:
14449 vex_printf("unimplemented special insn: ");
14450 break;
14451
14452 default:
14453 case S390_DECODE_ERROR:
14454 vex_printf("decoding error: ");
14455 break;
14456 }
14457
14458 vex_printf("%02x%02x", bytes[0], bytes[1]);
14459 if (insn_length > 2) {
14460 vex_printf(" %02x%02x", bytes[2], bytes[3]);
14461 }
14462 if (insn_length > 4) {
14463 vex_printf(" %02x%02x", bytes[4], bytes[5]);
14464 }
14465 vex_printf("\n");
14466
14467 return 0; /* Failed */
14468}
14469
14470
sewardj2019a972011-03-07 16:04:07 +000014471/* Disassemble a single instruction INSN into IR. */
14472static DisResult
florian420c5012011-07-22 02:12:28 +000014473disInstr_S390_WRK(UChar *insn)
sewardj2019a972011-03-07 16:04:07 +000014474{
14475 UChar byte;
14476 UInt insn_length;
14477 DisResult dres;
14478
14479 /* ---------------------------------------------------- */
14480 /* --- Compute instruction length -- */
14481 /* ---------------------------------------------------- */
14482
14483 /* Get the first byte of the insn. */
14484 byte = insn[0];
14485
14486 /* The leftmost two bits (0:1) encode the length of the insn in bytes.
14487 00 -> 2 bytes, 01 -> 4 bytes, 10 -> 4 bytes, 11 -> 6 bytes. */
14488 insn_length = ((((byte >> 6) + 1) >> 1) + 1) << 1;
14489
14490 guest_IA_next_instr = guest_IA_curr_instr + insn_length;
14491
14492 /* ---------------------------------------------------- */
14493 /* --- Initialise the DisResult data -- */
14494 /* ---------------------------------------------------- */
14495 dres.whatNext = Dis_Continue;
14496 dres.len = insn_length;
14497 dres.continueAt = 0;
florian8844a632012-04-13 04:04:06 +000014498 dres.jk_StopHere = Ijk_INVALID;
sewardj2019a972011-03-07 16:04:07 +000014499
floriana99f20e2011-07-17 14:16:41 +000014500 /* fixs390: consider chasing of conditional jumps */
14501
sewardj2019a972011-03-07 16:04:07 +000014502 /* Normal and special instruction handling starts here. */
14503 if (s390_decode_and_irgen(insn, insn_length, &dres) == 0) {
14504 /* All decode failures end up here. The decoder has already issued an
14505 error message.
14506 Tell the dispatcher that this insn cannot be decoded, and so has
florian342e01a2012-07-26 02:37:49 +000014507 not been executed, and (is currently) the next to be executed.
14508 The insn address in the guest state needs to be set to
14509 guest_IA_curr_instr, otherwise the complaint will report an
14510 incorrect address. */
14511 put_IA(mkaddr_expr(guest_IA_curr_instr));
sewardj2019a972011-03-07 16:04:07 +000014512
florian8844a632012-04-13 04:04:06 +000014513 dres.whatNext = Dis_StopHere;
14514 dres.jk_StopHere = Ijk_NoDecode;
14515 dres.continueAt = 0;
14516 dres.len = 0;
14517 } else {
14518 /* Decode success */
14519 switch (dres.whatNext) {
14520 case Dis_Continue:
florian8559e412012-04-19 14:23:48 +000014521 put_IA(mkaddr_expr(guest_IA_next_instr));
florian8844a632012-04-13 04:04:06 +000014522 break;
14523 case Dis_ResteerU:
14524 case Dis_ResteerC:
14525 put_IA(mkaddr_expr(dres.continueAt));
14526 break;
14527 case Dis_StopHere:
14528 break;
14529 default:
14530 vassert(0);
14531 }
sewardj2019a972011-03-07 16:04:07 +000014532 }
14533
14534 return dres;
14535}
14536
14537
14538/*------------------------------------------------------------*/
14539/*--- Top-level fn ---*/
14540/*------------------------------------------------------------*/
14541
14542/* Disassemble a single instruction into IR. The instruction
14543 is located in host memory at &guest_code[delta]. */
14544
14545DisResult
14546disInstr_S390(IRSB *irsb_IN,
sewardj2019a972011-03-07 16:04:07 +000014547 Bool (*resteerOkFn)(void *, Addr64),
14548 Bool resteerCisOk,
14549 void *callback_opaque,
14550 UChar *guest_code,
14551 Long delta,
14552 Addr64 guest_IP,
14553 VexArch guest_arch,
14554 VexArchInfo *archinfo,
14555 VexAbiInfo *abiinfo,
14556 Bool host_bigendian)
14557{
14558 vassert(guest_arch == VexArchS390X);
14559
14560 /* The instruction decoder requires a big-endian machine. */
14561 vassert(host_bigendian == True);
14562
14563 /* Set globals (see top of this file) */
14564 guest_IA_curr_instr = guest_IP;
sewardj2019a972011-03-07 16:04:07 +000014565 irsb = irsb_IN;
florian420c5012011-07-22 02:12:28 +000014566 resteer_fn = resteerOkFn;
14567 resteer_data = callback_opaque;
sewardj2019a972011-03-07 16:04:07 +000014568
florian420c5012011-07-22 02:12:28 +000014569 return disInstr_S390_WRK(guest_code + delta);
sewardj2019a972011-03-07 16:04:07 +000014570}
14571
14572/*---------------------------------------------------------------*/
14573/*--- end guest_s390_toIR.c ---*/
14574/*---------------------------------------------------------------*/