blob: 3ca5cb0581a8645339c3d2043657e8ad35faa5f7 [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"
florian58a637b2012-09-30 20:30:17 +000037#include "libvex_emnote.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 */
florian79af5752012-09-20 01:22:10 +000043#include "s390_disasm.h"
sewardj2019a972011-03-07 16:04:07 +000044#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 +0000428static __inline__ IRExpr *get_fpr_dw0(UInt);
429static __inline__ void put_fpr_dw0(UInt, IRExpr *);
florian12390202012-11-10 22:34:14 +0000430static __inline__ IRExpr *get_dpr_dw0(UInt);
431static __inline__ void put_dpr_dw0(UInt, IRExpr *);
sewardj2019a972011-03-07 16:04:07 +0000432
433/* Read a floating point register pair and combine their contents into a
434 128-bit value */
435static IRExpr *
436get_fpr_pair(UInt archreg)
437{
438 IRExpr *high = get_fpr_dw0(archreg);
439 IRExpr *low = get_fpr_dw0(archreg + 2);
440
441 return binop(Iop_F64HLtoF128, high, low);
442}
443
444/* Write a 128-bit floating point value into a register pair. */
445static void
446put_fpr_pair(UInt archreg, IRExpr *expr)
447{
448 IRExpr *high = unop(Iop_F128HItoF64, expr);
449 IRExpr *low = unop(Iop_F128LOtoF64, expr);
450
451 put_fpr_dw0(archreg, high);
452 put_fpr_dw0(archreg + 2, low);
453}
454
floriane75dafa2012-09-01 17:54:09 +0000455/* Terminate the current IRSB with an emulation failure. */
456static void
457emulation_failure(VexEmNote fail_kind)
458{
459 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_EMNOTE), mkU32(fail_kind)));
floriane75dafa2012-09-01 17:54:09 +0000460 dis_res->whatNext = Dis_StopHere;
461 dis_res->jk_StopHere = Ijk_EmFail;
462}
sewardj2019a972011-03-07 16:04:07 +0000463
florian4b8efad2012-09-02 18:07:08 +0000464/* Terminate the current IRSB with an emulation warning. */
465static void
466emulation_warning(VexEmNote warn_kind)
467{
468 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_EMNOTE), mkU32(warn_kind)));
469 dis_res->whatNext = Dis_StopHere;
470 dis_res->jk_StopHere = Ijk_EmWarn;
471}
472
sewardj2019a972011-03-07 16:04:07 +0000473/*------------------------------------------------------------*/
florianf3410f92012-08-03 18:41:58 +0000474/*--- IR Debugging aids. ---*/
475/*------------------------------------------------------------*/
476#if 0
477
478static ULong
479s390_do_print(HChar *text, ULong value)
480{
481 vex_printf("%s %llu\n", text, value);
482 return 0;
483}
484
485static void
486s390_print(HChar *text, IRExpr *value)
487{
488 IRDirty *d;
489
490 d = unsafeIRDirty_0_N(0 /* regparms */, "s390_do_print", &s390_do_print,
491 mkIRExprVec_2(mkU64((ULong)text), value));
492 stmt(IRStmt_Dirty(d));
493}
494#endif
495
496
497/*------------------------------------------------------------*/
sewardj2019a972011-03-07 16:04:07 +0000498/*--- Build the flags thunk. ---*/
499/*------------------------------------------------------------*/
500
501/* Completely fill the flags thunk. We're always filling all fields.
502 Apparently, that is better for redundant PUT elimination. */
503static void
504s390_cc_thunk_fill(IRExpr *op, IRExpr *dep1, IRExpr *dep2, IRExpr *ndep)
505{
506 UInt op_off, dep1_off, dep2_off, ndep_off;
507
florian428dfdd2012-03-27 03:09:49 +0000508 op_off = S390X_GUEST_OFFSET(guest_CC_OP);
509 dep1_off = S390X_GUEST_OFFSET(guest_CC_DEP1);
510 dep2_off = S390X_GUEST_OFFSET(guest_CC_DEP2);
511 ndep_off = S390X_GUEST_OFFSET(guest_CC_NDEP);
sewardj2019a972011-03-07 16:04:07 +0000512
513 stmt(IRStmt_Put(op_off, op));
514 stmt(IRStmt_Put(dep1_off, dep1));
515 stmt(IRStmt_Put(dep2_off, dep2));
516 stmt(IRStmt_Put(ndep_off, ndep));
517}
518
519
520/* Create an expression for V and widen the result to 64 bit. */
521static IRExpr *
522s390_cc_widen(IRTemp v, Bool sign_extend)
523{
524 IRExpr *expr;
525
526 expr = mkexpr(v);
527
528 switch (typeOfIRTemp(irsb->tyenv, v)) {
529 case Ity_I64:
530 break;
531 case Ity_I32:
532 expr = unop(sign_extend ? Iop_32Sto64 : Iop_32Uto64, expr);
533 break;
534 case Ity_I16:
535 expr = unop(sign_extend ? Iop_16Sto64 : Iop_16Uto64, expr);
536 break;
537 case Ity_I8:
538 expr = unop(sign_extend ? Iop_8Sto64 : Iop_8Uto64, expr);
539 break;
540 default:
541 vpanic("s390_cc_widen");
542 }
543
544 return expr;
545}
546
547static void
548s390_cc_thunk_put1(UInt opc, IRTemp d1, Bool sign_extend)
549{
550 IRExpr *op, *dep1, *dep2, *ndep;
551
552 op = mkU64(opc);
553 dep1 = s390_cc_widen(d1, sign_extend);
554 dep2 = mkU64(0);
555 ndep = mkU64(0);
556
557 s390_cc_thunk_fill(op, dep1, dep2, ndep);
558}
559
560
561static void
562s390_cc_thunk_put2(UInt opc, IRTemp d1, IRTemp d2, Bool sign_extend)
563{
564 IRExpr *op, *dep1, *dep2, *ndep;
565
566 op = mkU64(opc);
567 dep1 = s390_cc_widen(d1, sign_extend);
568 dep2 = s390_cc_widen(d2, sign_extend);
569 ndep = mkU64(0);
570
571 s390_cc_thunk_fill(op, dep1, dep2, ndep);
572}
573
574
575/* memcheck believes that the NDEP field in the flags thunk is always
576 defined. But for some flag computations (e.g. add with carry) that is
577 just not true. We therefore need to convey to memcheck that the value
578 of the ndep field does matter and therefore we make the DEP2 field
579 depend on it:
580
581 DEP2 = original_DEP2 ^ NDEP
582
583 In s390_calculate_cc we exploit that (a^b)^b == a
584 I.e. we xor the DEP2 value with the NDEP value to recover the
585 original_DEP2 value. */
586static void
587s390_cc_thunk_put3(UInt opc, IRTemp d1, IRTemp d2, IRTemp nd, Bool sign_extend)
588{
589 IRExpr *op, *dep1, *dep2, *ndep, *dep2x;
590
591 op = mkU64(opc);
592 dep1 = s390_cc_widen(d1, sign_extend);
593 dep2 = s390_cc_widen(d2, sign_extend);
594 ndep = s390_cc_widen(nd, sign_extend);
595
596 dep2x = binop(Iop_Xor64, dep2, ndep);
597
598 s390_cc_thunk_fill(op, dep1, dep2x, ndep);
599}
600
601
602/* Write one floating point value into the flags thunk */
603static void
604s390_cc_thunk_put1f(UInt opc, IRTemp d1)
605{
606 IRExpr *op, *dep1, *dep2, *ndep;
607
608 op = mkU64(opc);
609 dep1 = mkexpr(d1);
610 dep2 = mkU64(0);
611 ndep = mkU64(0);
612
613 s390_cc_thunk_fill(op, dep1, dep2, ndep);
614}
615
616
617/* Write a floating point value and an integer into the flags thunk. The
618 integer value is zero-extended first. */
619static void
620s390_cc_thunk_putFZ(UInt opc, IRTemp d1, IRTemp d2)
621{
622 IRExpr *op, *dep1, *dep2, *ndep;
623
624 op = mkU64(opc);
625 dep1 = mkexpr(d1);
626 dep2 = s390_cc_widen(d2, False);
627 ndep = mkU64(0);
628
629 s390_cc_thunk_fill(op, dep1, dep2, ndep);
630}
631
632
633/* Write a 128-bit floating point value into the flags thunk. This is
634 done by splitting the value into two 64-bits values. */
635static void
636s390_cc_thunk_put1f128(UInt opc, IRTemp d1)
637{
638 IRExpr *op, *hi, *lo, *ndep;
639
640 op = mkU64(opc);
641 hi = unop(Iop_F128HItoF64, mkexpr(d1));
642 lo = unop(Iop_F128LOtoF64, mkexpr(d1));
643 ndep = mkU64(0);
644
645 s390_cc_thunk_fill(op, hi, lo, ndep);
646}
647
648
649/* Write a 128-bit floating point value and an integer into the flags thunk.
650 The integer value is zero-extended first. */
651static void
652s390_cc_thunk_put1f128Z(UInt opc, IRTemp d1, IRTemp nd)
653{
654 IRExpr *op, *hi, *lo, *lox, *ndep;
655
656 op = mkU64(opc);
657 hi = unop(Iop_F128HItoF64, mkexpr(d1));
658 lo = unop(Iop_ReinterpF64asI64, unop(Iop_F128LOtoF64, mkexpr(d1)));
659 ndep = s390_cc_widen(nd, False);
660
661 lox = binop(Iop_Xor64, lo, ndep); /* convey dependency */
662
663 s390_cc_thunk_fill(op, hi, lox, ndep);
664}
665
666
667static void
668s390_cc_set(UInt val)
669{
670 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
671 mkU64(val), mkU64(0), mkU64(0));
672}
673
674/* Build IR to calculate the condition code from flags thunk.
675 Returns an expression of type Ity_I32 */
676static IRExpr *
677s390_call_calculate_cc(void)
678{
679 IRExpr **args, *call, *op, *dep1, *dep2, *ndep;
680
florian428dfdd2012-03-27 03:09:49 +0000681 op = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_OP), Ity_I64);
682 dep1 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP1), Ity_I64);
683 dep2 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP2), Ity_I64);
684 ndep = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_NDEP), Ity_I64);
sewardj2019a972011-03-07 16:04:07 +0000685
686 args = mkIRExprVec_4(op, dep1, dep2, ndep);
687 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
688 "s390_calculate_cc", &s390_calculate_cc, args);
689
690 /* Exclude OP and NDEP from definedness checking. We're only
691 interested in DEP1 and DEP2. */
692 call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<3);
693
694 return call;
695}
696
697/* Build IR to calculate the internal condition code for a "compare and branch"
698 insn. Returns an expression of type Ity_I32 */
699static IRExpr *
florianff9613f2012-05-12 15:26:44 +0000700s390_call_calculate_icc(UInt m, UInt opc, IRTemp op1, IRTemp op2)
sewardj2019a972011-03-07 16:04:07 +0000701{
florianff9613f2012-05-12 15:26:44 +0000702 IRExpr **args, *call, *op, *dep1, *dep2, *mask;
sewardj2019a972011-03-07 16:04:07 +0000703
florianff9613f2012-05-12 15:26:44 +0000704 switch (opc) {
705 case S390_CC_OP_SIGNED_COMPARE:
706 dep1 = s390_cc_widen(op1, True);
707 dep2 = s390_cc_widen(op2, True);
708 break;
709
710 case S390_CC_OP_UNSIGNED_COMPARE:
711 dep1 = s390_cc_widen(op1, False);
712 dep2 = s390_cc_widen(op2, False);
713 break;
714
715 default:
716 vpanic("s390_call_calculate_icc");
717 }
718
719 mask = mkU64(m);
sewardj2019a972011-03-07 16:04:07 +0000720 op = mkU64(opc);
sewardj2019a972011-03-07 16:04:07 +0000721
florianff9613f2012-05-12 15:26:44 +0000722 args = mkIRExprVec_5(mask, op, dep1, dep2, mkU64(0) /* unused */);
sewardj2019a972011-03-07 16:04:07 +0000723 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
florianff9613f2012-05-12 15:26:44 +0000724 "s390_calculate_cond", &s390_calculate_cond, args);
sewardj2019a972011-03-07 16:04:07 +0000725
florianff9613f2012-05-12 15:26:44 +0000726 /* Exclude the requested condition, OP and NDEP from definedness
727 checking. We're only interested in DEP1 and DEP2. */
728 call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<1) | (1<<4);
sewardj2019a972011-03-07 16:04:07 +0000729
730 return call;
731}
732
733/* Build IR to calculate the condition code from flags thunk.
734 Returns an expression of type Ity_I32 */
735static IRExpr *
736s390_call_calculate_cond(UInt m)
737{
738 IRExpr **args, *call, *op, *dep1, *dep2, *ndep, *mask;
739
740 mask = mkU64(m);
florian428dfdd2012-03-27 03:09:49 +0000741 op = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_OP), Ity_I64);
742 dep1 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP1), Ity_I64);
743 dep2 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP2), Ity_I64);
744 ndep = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_NDEP), Ity_I64);
sewardj2019a972011-03-07 16:04:07 +0000745
746 args = mkIRExprVec_5(mask, op, dep1, dep2, ndep);
747 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
748 "s390_calculate_cond", &s390_calculate_cond, args);
749
750 /* Exclude the requested condition, OP and NDEP from definedness
751 checking. We're only interested in DEP1 and DEP2. */
752 call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<1) | (1<<4);
753
754 return call;
755}
756
757#define s390_cc_thunk_putZ(op,dep1) s390_cc_thunk_put1(op,dep1,False)
758#define s390_cc_thunk_putS(op,dep1) s390_cc_thunk_put1(op,dep1,True)
759#define s390_cc_thunk_putF(op,dep1) s390_cc_thunk_put1f(op,dep1)
760#define s390_cc_thunk_putZZ(op,dep1,dep2) s390_cc_thunk_put2(op,dep1,dep2,False)
761#define s390_cc_thunk_putSS(op,dep1,dep2) s390_cc_thunk_put2(op,dep1,dep2,True)
762#define s390_cc_thunk_putFF(op,dep1,dep2) s390_cc_thunk_put2f(op,dep1,dep2)
763#define s390_cc_thunk_putZZZ(op,dep1,dep2,ndep) \
764 s390_cc_thunk_put3(op,dep1,dep2,ndep,False)
765#define s390_cc_thunk_putSSS(op,dep1,dep2,ndep) \
766 s390_cc_thunk_put3(op,dep1,dep2,ndep,True)
sewardj2019a972011-03-07 16:04:07 +0000767
768
sewardj2019a972011-03-07 16:04:07 +0000769
770
771/*------------------------------------------------------------*/
772/*--- Guest register access ---*/
773/*------------------------------------------------------------*/
774
775
776/*------------------------------------------------------------*/
777/*--- ar registers ---*/
778/*------------------------------------------------------------*/
779
780/* Return the guest state offset of a ar register. */
781static UInt
782ar_offset(UInt archreg)
783{
784 static const UInt offset[16] = {
floriane88b3c92011-07-05 02:48:39 +0000785 S390X_GUEST_OFFSET(guest_a0),
786 S390X_GUEST_OFFSET(guest_a1),
787 S390X_GUEST_OFFSET(guest_a2),
788 S390X_GUEST_OFFSET(guest_a3),
789 S390X_GUEST_OFFSET(guest_a4),
790 S390X_GUEST_OFFSET(guest_a5),
791 S390X_GUEST_OFFSET(guest_a6),
792 S390X_GUEST_OFFSET(guest_a7),
793 S390X_GUEST_OFFSET(guest_a8),
794 S390X_GUEST_OFFSET(guest_a9),
795 S390X_GUEST_OFFSET(guest_a10),
796 S390X_GUEST_OFFSET(guest_a11),
797 S390X_GUEST_OFFSET(guest_a12),
798 S390X_GUEST_OFFSET(guest_a13),
799 S390X_GUEST_OFFSET(guest_a14),
800 S390X_GUEST_OFFSET(guest_a15),
sewardj2019a972011-03-07 16:04:07 +0000801 };
802
803 vassert(archreg < 16);
804
805 return offset[archreg];
806}
807
808
809/* Return the guest state offset of word #0 of a ar register. */
810static __inline__ UInt
811ar_w0_offset(UInt archreg)
812{
813 return ar_offset(archreg) + 0;
814}
815
816/* Write word #0 of a ar to the guest state. */
817static __inline__ void
818put_ar_w0(UInt archreg, IRExpr *expr)
819{
820 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
821
822 stmt(IRStmt_Put(ar_w0_offset(archreg), expr));
823}
824
825/* Read word #0 of a ar register. */
826static __inline__ IRExpr *
827get_ar_w0(UInt archreg)
828{
829 return IRExpr_Get(ar_w0_offset(archreg), Ity_I32);
830}
831
832
833/*------------------------------------------------------------*/
834/*--- fpr registers ---*/
835/*------------------------------------------------------------*/
836
837/* Return the guest state offset of a fpr register. */
838static UInt
839fpr_offset(UInt archreg)
840{
841 static const UInt offset[16] = {
floriane88b3c92011-07-05 02:48:39 +0000842 S390X_GUEST_OFFSET(guest_f0),
843 S390X_GUEST_OFFSET(guest_f1),
844 S390X_GUEST_OFFSET(guest_f2),
845 S390X_GUEST_OFFSET(guest_f3),
846 S390X_GUEST_OFFSET(guest_f4),
847 S390X_GUEST_OFFSET(guest_f5),
848 S390X_GUEST_OFFSET(guest_f6),
849 S390X_GUEST_OFFSET(guest_f7),
850 S390X_GUEST_OFFSET(guest_f8),
851 S390X_GUEST_OFFSET(guest_f9),
852 S390X_GUEST_OFFSET(guest_f10),
853 S390X_GUEST_OFFSET(guest_f11),
854 S390X_GUEST_OFFSET(guest_f12),
855 S390X_GUEST_OFFSET(guest_f13),
856 S390X_GUEST_OFFSET(guest_f14),
857 S390X_GUEST_OFFSET(guest_f15),
sewardj2019a972011-03-07 16:04:07 +0000858 };
859
860 vassert(archreg < 16);
861
862 return offset[archreg];
863}
864
865
866/* Return the guest state offset of word #0 of a fpr register. */
867static __inline__ UInt
868fpr_w0_offset(UInt archreg)
869{
870 return fpr_offset(archreg) + 0;
871}
872
873/* Write word #0 of a fpr to the guest state. */
874static __inline__ void
875put_fpr_w0(UInt archreg, IRExpr *expr)
876{
877 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_F32);
878
879 stmt(IRStmt_Put(fpr_w0_offset(archreg), expr));
880}
881
882/* Read word #0 of a fpr register. */
883static __inline__ IRExpr *
884get_fpr_w0(UInt archreg)
885{
886 return IRExpr_Get(fpr_w0_offset(archreg), Ity_F32);
887}
888
889/* Return the guest state offset of double word #0 of a fpr register. */
890static __inline__ UInt
891fpr_dw0_offset(UInt archreg)
892{
893 return fpr_offset(archreg) + 0;
894}
895
896/* Write double word #0 of a fpr to the guest state. */
897static __inline__ void
898put_fpr_dw0(UInt archreg, IRExpr *expr)
899{
900 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_F64);
901
902 stmt(IRStmt_Put(fpr_dw0_offset(archreg), expr));
903}
904
905/* Read double word #0 of a fpr register. */
906static __inline__ IRExpr *
907get_fpr_dw0(UInt archreg)
908{
909 return IRExpr_Get(fpr_dw0_offset(archreg), Ity_F64);
910}
911
florian12390202012-11-10 22:34:14 +0000912/* Write double word #0 of a fpr containg DFP value to the guest state. */
913static __inline__ void
914put_dpr_dw0(UInt archreg, IRExpr *expr)
915{
916 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_D64);
917
918 stmt(IRStmt_Put(fpr_dw0_offset(archreg), expr));
919}
920
921/* Read double word #0 of a fpr register containing DFP value. */
922static __inline__ IRExpr *
923get_dpr_dw0(UInt archreg)
924{
925 return IRExpr_Get(fpr_dw0_offset(archreg), Ity_D64);
926}
sewardj2019a972011-03-07 16:04:07 +0000927
928/*------------------------------------------------------------*/
929/*--- gpr registers ---*/
930/*------------------------------------------------------------*/
931
932/* Return the guest state offset of a gpr register. */
933static UInt
934gpr_offset(UInt archreg)
935{
936 static const UInt offset[16] = {
floriane88b3c92011-07-05 02:48:39 +0000937 S390X_GUEST_OFFSET(guest_r0),
938 S390X_GUEST_OFFSET(guest_r1),
939 S390X_GUEST_OFFSET(guest_r2),
940 S390X_GUEST_OFFSET(guest_r3),
941 S390X_GUEST_OFFSET(guest_r4),
942 S390X_GUEST_OFFSET(guest_r5),
943 S390X_GUEST_OFFSET(guest_r6),
944 S390X_GUEST_OFFSET(guest_r7),
945 S390X_GUEST_OFFSET(guest_r8),
946 S390X_GUEST_OFFSET(guest_r9),
947 S390X_GUEST_OFFSET(guest_r10),
948 S390X_GUEST_OFFSET(guest_r11),
949 S390X_GUEST_OFFSET(guest_r12),
950 S390X_GUEST_OFFSET(guest_r13),
951 S390X_GUEST_OFFSET(guest_r14),
952 S390X_GUEST_OFFSET(guest_r15),
sewardj2019a972011-03-07 16:04:07 +0000953 };
954
955 vassert(archreg < 16);
956
957 return offset[archreg];
958}
959
960
961/* Return the guest state offset of word #0 of a gpr register. */
962static __inline__ UInt
963gpr_w0_offset(UInt archreg)
964{
965 return gpr_offset(archreg) + 0;
966}
967
968/* Write word #0 of a gpr to the guest state. */
969static __inline__ void
970put_gpr_w0(UInt archreg, IRExpr *expr)
971{
972 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
973
974 stmt(IRStmt_Put(gpr_w0_offset(archreg), expr));
975}
976
977/* Read word #0 of a gpr register. */
978static __inline__ IRExpr *
979get_gpr_w0(UInt archreg)
980{
981 return IRExpr_Get(gpr_w0_offset(archreg), Ity_I32);
982}
983
984/* Return the guest state offset of double word #0 of a gpr register. */
985static __inline__ UInt
986gpr_dw0_offset(UInt archreg)
987{
988 return gpr_offset(archreg) + 0;
989}
990
991/* Write double word #0 of a gpr to the guest state. */
992static __inline__ void
993put_gpr_dw0(UInt archreg, IRExpr *expr)
994{
995 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I64);
996
997 stmt(IRStmt_Put(gpr_dw0_offset(archreg), expr));
998}
999
1000/* Read double word #0 of a gpr register. */
1001static __inline__ IRExpr *
1002get_gpr_dw0(UInt archreg)
1003{
1004 return IRExpr_Get(gpr_dw0_offset(archreg), Ity_I64);
1005}
1006
1007/* Return the guest state offset of half word #1 of a gpr register. */
1008static __inline__ UInt
1009gpr_hw1_offset(UInt archreg)
1010{
1011 return gpr_offset(archreg) + 2;
1012}
1013
1014/* Write half word #1 of a gpr to the guest state. */
1015static __inline__ void
1016put_gpr_hw1(UInt archreg, IRExpr *expr)
1017{
1018 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1019
1020 stmt(IRStmt_Put(gpr_hw1_offset(archreg), expr));
1021}
1022
1023/* Read half word #1 of a gpr register. */
1024static __inline__ IRExpr *
1025get_gpr_hw1(UInt archreg)
1026{
1027 return IRExpr_Get(gpr_hw1_offset(archreg), Ity_I16);
1028}
1029
1030/* Return the guest state offset of byte #6 of a gpr register. */
1031static __inline__ UInt
1032gpr_b6_offset(UInt archreg)
1033{
1034 return gpr_offset(archreg) + 6;
1035}
1036
1037/* Write byte #6 of a gpr to the guest state. */
1038static __inline__ void
1039put_gpr_b6(UInt archreg, IRExpr *expr)
1040{
1041 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1042
1043 stmt(IRStmt_Put(gpr_b6_offset(archreg), expr));
1044}
1045
1046/* Read byte #6 of a gpr register. */
1047static __inline__ IRExpr *
1048get_gpr_b6(UInt archreg)
1049{
1050 return IRExpr_Get(gpr_b6_offset(archreg), Ity_I8);
1051}
1052
1053/* Return the guest state offset of byte #3 of a gpr register. */
1054static __inline__ UInt
1055gpr_b3_offset(UInt archreg)
1056{
1057 return gpr_offset(archreg) + 3;
1058}
1059
1060/* Write byte #3 of a gpr to the guest state. */
1061static __inline__ void
1062put_gpr_b3(UInt archreg, IRExpr *expr)
1063{
1064 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1065
1066 stmt(IRStmt_Put(gpr_b3_offset(archreg), expr));
1067}
1068
1069/* Read byte #3 of a gpr register. */
1070static __inline__ IRExpr *
1071get_gpr_b3(UInt archreg)
1072{
1073 return IRExpr_Get(gpr_b3_offset(archreg), Ity_I8);
1074}
1075
1076/* Return the guest state offset of byte #0 of a gpr register. */
1077static __inline__ UInt
1078gpr_b0_offset(UInt archreg)
1079{
1080 return gpr_offset(archreg) + 0;
1081}
1082
1083/* Write byte #0 of a gpr to the guest state. */
1084static __inline__ void
1085put_gpr_b0(UInt archreg, IRExpr *expr)
1086{
1087 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1088
1089 stmt(IRStmt_Put(gpr_b0_offset(archreg), expr));
1090}
1091
1092/* Read byte #0 of a gpr register. */
1093static __inline__ IRExpr *
1094get_gpr_b0(UInt archreg)
1095{
1096 return IRExpr_Get(gpr_b0_offset(archreg), Ity_I8);
1097}
1098
1099/* Return the guest state offset of word #1 of a gpr register. */
1100static __inline__ UInt
1101gpr_w1_offset(UInt archreg)
1102{
1103 return gpr_offset(archreg) + 4;
1104}
1105
1106/* Write word #1 of a gpr to the guest state. */
1107static __inline__ void
1108put_gpr_w1(UInt archreg, IRExpr *expr)
1109{
1110 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1111
1112 stmt(IRStmt_Put(gpr_w1_offset(archreg), expr));
1113}
1114
1115/* Read word #1 of a gpr register. */
1116static __inline__ IRExpr *
1117get_gpr_w1(UInt archreg)
1118{
1119 return IRExpr_Get(gpr_w1_offset(archreg), Ity_I32);
1120}
1121
1122/* Return the guest state offset of half word #3 of a gpr register. */
1123static __inline__ UInt
1124gpr_hw3_offset(UInt archreg)
1125{
1126 return gpr_offset(archreg) + 6;
1127}
1128
1129/* Write half word #3 of a gpr to the guest state. */
1130static __inline__ void
1131put_gpr_hw3(UInt archreg, IRExpr *expr)
1132{
1133 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1134
1135 stmt(IRStmt_Put(gpr_hw3_offset(archreg), expr));
1136}
1137
1138/* Read half word #3 of a gpr register. */
1139static __inline__ IRExpr *
1140get_gpr_hw3(UInt archreg)
1141{
1142 return IRExpr_Get(gpr_hw3_offset(archreg), Ity_I16);
1143}
1144
1145/* Return the guest state offset of byte #7 of a gpr register. */
1146static __inline__ UInt
1147gpr_b7_offset(UInt archreg)
1148{
1149 return gpr_offset(archreg) + 7;
1150}
1151
1152/* Write byte #7 of a gpr to the guest state. */
1153static __inline__ void
1154put_gpr_b7(UInt archreg, IRExpr *expr)
1155{
1156 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1157
1158 stmt(IRStmt_Put(gpr_b7_offset(archreg), expr));
1159}
1160
1161/* Read byte #7 of a gpr register. */
1162static __inline__ IRExpr *
1163get_gpr_b7(UInt archreg)
1164{
1165 return IRExpr_Get(gpr_b7_offset(archreg), Ity_I8);
1166}
1167
1168/* Return the guest state offset of half word #0 of a gpr register. */
1169static __inline__ UInt
1170gpr_hw0_offset(UInt archreg)
1171{
1172 return gpr_offset(archreg) + 0;
1173}
1174
1175/* Write half word #0 of a gpr to the guest state. */
1176static __inline__ void
1177put_gpr_hw0(UInt archreg, IRExpr *expr)
1178{
1179 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1180
1181 stmt(IRStmt_Put(gpr_hw0_offset(archreg), expr));
1182}
1183
1184/* Read half word #0 of a gpr register. */
1185static __inline__ IRExpr *
1186get_gpr_hw0(UInt archreg)
1187{
1188 return IRExpr_Get(gpr_hw0_offset(archreg), Ity_I16);
1189}
1190
1191/* Return the guest state offset of byte #4 of a gpr register. */
1192static __inline__ UInt
1193gpr_b4_offset(UInt archreg)
1194{
1195 return gpr_offset(archreg) + 4;
1196}
1197
1198/* Write byte #4 of a gpr to the guest state. */
1199static __inline__ void
1200put_gpr_b4(UInt archreg, IRExpr *expr)
1201{
1202 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1203
1204 stmt(IRStmt_Put(gpr_b4_offset(archreg), expr));
1205}
1206
1207/* Read byte #4 of a gpr register. */
1208static __inline__ IRExpr *
1209get_gpr_b4(UInt archreg)
1210{
1211 return IRExpr_Get(gpr_b4_offset(archreg), Ity_I8);
1212}
1213
1214/* Return the guest state offset of byte #1 of a gpr register. */
1215static __inline__ UInt
1216gpr_b1_offset(UInt archreg)
1217{
1218 return gpr_offset(archreg) + 1;
1219}
1220
1221/* Write byte #1 of a gpr to the guest state. */
1222static __inline__ void
1223put_gpr_b1(UInt archreg, IRExpr *expr)
1224{
1225 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1226
1227 stmt(IRStmt_Put(gpr_b1_offset(archreg), expr));
1228}
1229
1230/* Read byte #1 of a gpr register. */
1231static __inline__ IRExpr *
1232get_gpr_b1(UInt archreg)
1233{
1234 return IRExpr_Get(gpr_b1_offset(archreg), Ity_I8);
1235}
1236
1237/* Return the guest state offset of half word #2 of a gpr register. */
1238static __inline__ UInt
1239gpr_hw2_offset(UInt archreg)
1240{
1241 return gpr_offset(archreg) + 4;
1242}
1243
1244/* Write half word #2 of a gpr to the guest state. */
1245static __inline__ void
1246put_gpr_hw2(UInt archreg, IRExpr *expr)
1247{
1248 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1249
1250 stmt(IRStmt_Put(gpr_hw2_offset(archreg), expr));
1251}
1252
1253/* Read half word #2 of a gpr register. */
1254static __inline__ IRExpr *
1255get_gpr_hw2(UInt archreg)
1256{
1257 return IRExpr_Get(gpr_hw2_offset(archreg), Ity_I16);
1258}
1259
1260/* Return the guest state offset of byte #5 of a gpr register. */
1261static __inline__ UInt
1262gpr_b5_offset(UInt archreg)
1263{
1264 return gpr_offset(archreg) + 5;
1265}
1266
1267/* Write byte #5 of a gpr to the guest state. */
1268static __inline__ void
1269put_gpr_b5(UInt archreg, IRExpr *expr)
1270{
1271 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1272
1273 stmt(IRStmt_Put(gpr_b5_offset(archreg), expr));
1274}
1275
1276/* Read byte #5 of a gpr register. */
1277static __inline__ IRExpr *
1278get_gpr_b5(UInt archreg)
1279{
1280 return IRExpr_Get(gpr_b5_offset(archreg), Ity_I8);
1281}
1282
1283/* Return the guest state offset of byte #2 of a gpr register. */
1284static __inline__ UInt
1285gpr_b2_offset(UInt archreg)
1286{
1287 return gpr_offset(archreg) + 2;
1288}
1289
1290/* Write byte #2 of a gpr to the guest state. */
1291static __inline__ void
1292put_gpr_b2(UInt archreg, IRExpr *expr)
1293{
1294 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1295
1296 stmt(IRStmt_Put(gpr_b2_offset(archreg), expr));
1297}
1298
1299/* Read byte #2 of a gpr register. */
1300static __inline__ IRExpr *
1301get_gpr_b2(UInt archreg)
1302{
1303 return IRExpr_Get(gpr_b2_offset(archreg), Ity_I8);
1304}
1305
1306/* Return the guest state offset of the counter register. */
1307static UInt
1308counter_offset(void)
1309{
floriane88b3c92011-07-05 02:48:39 +00001310 return S390X_GUEST_OFFSET(guest_counter);
sewardj2019a972011-03-07 16:04:07 +00001311}
1312
1313/* Return the guest state offset of double word #0 of the counter register. */
1314static __inline__ UInt
1315counter_dw0_offset(void)
1316{
1317 return counter_offset() + 0;
1318}
1319
1320/* Write double word #0 of the counter to the guest state. */
1321static __inline__ void
1322put_counter_dw0(IRExpr *expr)
1323{
1324 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I64);
1325
1326 stmt(IRStmt_Put(counter_dw0_offset(), expr));
1327}
1328
1329/* Read double word #0 of the counter register. */
1330static __inline__ IRExpr *
1331get_counter_dw0(void)
1332{
1333 return IRExpr_Get(counter_dw0_offset(), Ity_I64);
1334}
1335
1336/* Return the guest state offset of word #0 of the counter register. */
1337static __inline__ UInt
1338counter_w0_offset(void)
1339{
1340 return counter_offset() + 0;
1341}
1342
1343/* Return the guest state offset of word #1 of the counter register. */
1344static __inline__ UInt
1345counter_w1_offset(void)
1346{
1347 return counter_offset() + 4;
1348}
1349
1350/* Write word #0 of the counter to the guest state. */
1351static __inline__ void
1352put_counter_w0(IRExpr *expr)
1353{
1354 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1355
1356 stmt(IRStmt_Put(counter_w0_offset(), expr));
1357}
1358
1359/* Read word #0 of the counter register. */
1360static __inline__ IRExpr *
1361get_counter_w0(void)
1362{
1363 return IRExpr_Get(counter_w0_offset(), Ity_I32);
1364}
1365
1366/* Write word #1 of the counter to the guest state. */
1367static __inline__ void
1368put_counter_w1(IRExpr *expr)
1369{
1370 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1371
1372 stmt(IRStmt_Put(counter_w1_offset(), expr));
1373}
1374
1375/* Read word #1 of the counter register. */
1376static __inline__ IRExpr *
1377get_counter_w1(void)
1378{
1379 return IRExpr_Get(counter_w1_offset(), Ity_I32);
1380}
1381
1382/* Return the guest state offset of the fpc register. */
1383static UInt
1384fpc_offset(void)
1385{
floriane88b3c92011-07-05 02:48:39 +00001386 return S390X_GUEST_OFFSET(guest_fpc);
sewardj2019a972011-03-07 16:04:07 +00001387}
1388
1389/* Return the guest state offset of word #0 of the fpc register. */
1390static __inline__ UInt
1391fpc_w0_offset(void)
1392{
1393 return fpc_offset() + 0;
1394}
1395
1396/* Write word #0 of the fpc to the guest state. */
1397static __inline__ void
1398put_fpc_w0(IRExpr *expr)
1399{
1400 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1401
1402 stmt(IRStmt_Put(fpc_w0_offset(), expr));
1403}
1404
1405/* Read word #0 of the fpc register. */
1406static __inline__ IRExpr *
1407get_fpc_w0(void)
1408{
1409 return IRExpr_Get(fpc_w0_offset(), Ity_I32);
1410}
1411
1412
1413/*------------------------------------------------------------*/
florian2c74d242012-09-12 19:38:42 +00001414/*--- Rounding modes ---*/
1415/*------------------------------------------------------------*/
1416
florian125e20d2012-10-07 15:42:37 +00001417/* Extract the bfp rounding mode from the guest FPC reg and encode it as an
florian2c74d242012-09-12 19:38:42 +00001418 IRRoundingMode:
1419
1420 rounding mode | s390 | IR
1421 -------------------------
1422 to nearest | 00 | 00
1423 to zero | 01 | 11
1424 to +infinity | 10 | 10
1425 to -infinity | 11 | 01
1426
1427 So: IR = (4 - s390) & 3
1428*/
1429static IRExpr *
florian125e20d2012-10-07 15:42:37 +00001430get_bfp_rounding_mode_from_fpc(void)
florian2c74d242012-09-12 19:38:42 +00001431{
1432 IRTemp fpc_bits = newTemp(Ity_I32);
1433
1434 /* For z196 and later the bfp rounding mode is stored in bits [29:31].
1435 Prior to that bits [30:31] contained the bfp rounding mode with
1436 bit 29 being unused and having a value of 0. So we can always
1437 extract the least significant 3 bits. */
1438 assign(fpc_bits, binop(Iop_And32, get_fpc_w0(), mkU32(7)));
1439
1440 /* fixs390:
1441
1442
1443 if (! s390_host_has_fpext && rounding_mode > 3) {
1444 emulation warning @ runtime and
1445 set fpc to round nearest
1446 }
1447 */
1448
1449 /* For now silently adjust an unsupported rounding mode to "nearest" */
1450 IRExpr *rm_s390 = mkite(binop(Iop_CmpLE32S, mkexpr(fpc_bits), mkU32(3)),
1451 mkexpr(fpc_bits),
florian125e20d2012-10-07 15:42:37 +00001452 mkU32(S390_FPC_BFP_ROUND_NEAREST_EVEN));
florian2c74d242012-09-12 19:38:42 +00001453
1454 // rm_IR = (4 - rm_s390) & 3;
1455 return binop(Iop_And32, binop(Iop_Sub32, mkU32(4), rm_s390), mkU32(3));
1456}
1457
1458/* Encode the s390 rounding mode as it appears in the m3 field of certain
1459 instructions to VEX's IRRoundingMode. Rounding modes that cannot be
1460 represented in VEX are converted to Irrm_NEAREST. The rationale is, that
1461 Irrm_NEAREST refers to IEEE 754's roundTiesToEven which the standard
1462 considers the default rounding mode (4.3.3). */
1463static IRTemp
1464encode_bfp_rounding_mode(UChar mode)
1465{
1466 IRExpr *rm;
1467
1468 switch (mode) {
florian125e20d2012-10-07 15:42:37 +00001469 case S390_BFP_ROUND_PER_FPC:
1470 rm = get_bfp_rounding_mode_from_fpc();
1471 break;
1472 case S390_BFP_ROUND_NEAREST_AWAY: /* not supported */
1473 case S390_BFP_ROUND_PREPARE_SHORT: /* not supported */
1474 case S390_BFP_ROUND_NEAREST_EVEN: rm = mkU32(Irrm_NEAREST); break;
1475 case S390_BFP_ROUND_ZERO: rm = mkU32(Irrm_ZERO); break;
1476 case S390_BFP_ROUND_POSINF: rm = mkU32(Irrm_PosINF); break;
1477 case S390_BFP_ROUND_NEGINF: rm = mkU32(Irrm_NegINF); break;
florian2c74d242012-09-12 19:38:42 +00001478 default:
1479 vpanic("encode_bfp_rounding_mode");
1480 }
1481
1482 return mktemp(Ity_I32, rm);
1483}
1484
florianc8e4f562012-10-27 16:19:31 +00001485/* Extract the DFP rounding mode from the guest FPC reg and encode it as an
1486 IRRoundingMode:
1487
1488 rounding mode | s390 | IR
1489 ------------------------------------------------
1490 to nearest, ties to even | 000 | 000
1491 to zero | 001 | 011
1492 to +infinity | 010 | 010
1493 to -infinity | 011 | 001
1494 to nearest, ties away from 0 | 100 | 100
1495 to nearest, ties toward 0 | 101 | 111
1496 to away from 0 | 110 | 110
1497 to prepare for shorter precision | 111 | 101
1498
1499 So: IR = (s390 ^ ((s390 << 1) & 2))
1500*/
florianc8e4f562012-10-27 16:19:31 +00001501static IRExpr *
1502get_dfp_rounding_mode_from_fpc(void)
1503{
1504 IRTemp fpc_bits = newTemp(Ity_I32);
1505
1506 /* The dfp rounding mode is stored in bits [25:27].
1507 extract the bits at 25:27 and right shift 4 times. */
1508 assign(fpc_bits, binop(Iop_Shr32,
1509 binop(Iop_And32, get_fpc_w0(), mkU32(0x70)),
1510 mkU8(4)));
1511
1512 IRExpr *rm_s390 = mkexpr(fpc_bits);
1513 // rm_IR = (rm_s390 ^ ((rm_s390 << 1) & 2));
1514
1515 return binop(Iop_Xor32, rm_s390,
1516 binop( Iop_And32,
1517 binop(Iop_Shl32, rm_s390, mkU8(1)),
1518 mkU32(2)));
1519}
1520
1521/* Encode the s390 rounding mode as it appears in the m3 field of certain
1522 instructions to VEX's IRRoundingMode. */
1523static IRTemp
1524encode_dfp_rounding_mode(UChar mode)
1525{
1526 IRExpr *rm;
1527
1528 switch (mode) {
1529 case S390_DFP_ROUND_PER_FPC_0:
1530 case S390_DFP_ROUND_PER_FPC_2:
1531 rm = get_dfp_rounding_mode_from_fpc(); break;
1532 case S390_DFP_ROUND_NEAREST_EVEN_4:
1533 case S390_DFP_ROUND_NEAREST_EVEN_8:
1534 rm = mkU32(Irrm_DFP_NEAREST); break;
1535 case S390_DFP_ROUND_NEAREST_TIE_AWAY_0_1:
1536 case S390_DFP_ROUND_NEAREST_TIE_AWAY_0_12:
1537 rm = mkU32(Irrm_DFP_NEAREST_TIE_AWAY_0); break;
1538 case S390_DFP_ROUND_PREPARE_SHORT_3:
1539 case S390_DFP_ROUND_PREPARE_SHORT_15:
1540 rm = mkU32(Irrm_DFP_PREPARE_SHORTER); break;
1541 case S390_DFP_ROUND_ZERO_5:
1542 case S390_DFP_ROUND_ZERO_9:
1543 rm = mkU32(Irrm_DFP_ZERO ); break;
1544 case S390_DFP_ROUND_POSINF_6:
1545 case S390_DFP_ROUND_POSINF_10:
1546 rm = mkU32(Irrm_DFP_PosINF); break;
1547 case S390_DFP_ROUND_NEGINF_7:
1548 case S390_DFP_ROUND_NEGINF_11:
1549 rm = mkU32(Irrm_DFP_NegINF); break;
1550 case S390_DFP_ROUND_NEAREST_TIE_TOWARD_0:
1551 rm = mkU32(Irrm_DFP_NEAREST_TIE_TOWARD_0); break;
1552 case S390_DFP_ROUND_AWAY_0:
1553 rm = mkU32(Irrm_DFP_AWAY_FROM_ZERO); break;
1554 default:
1555 vpanic("encode_dfp_rounding_mode");
1556 }
1557
1558 return mktemp(Ity_I32, rm);
1559}
florian12390202012-11-10 22:34:14 +00001560
florianc8e4f562012-10-27 16:19:31 +00001561
florian2c74d242012-09-12 19:38:42 +00001562/*------------------------------------------------------------*/
sewardj2019a972011-03-07 16:04:07 +00001563/*--- Build IR for formats ---*/
1564/*------------------------------------------------------------*/
1565static void
florian55085f82012-11-21 00:36:55 +00001566s390_format_I(const HChar *(*irgen)(UChar i),
sewardj2019a972011-03-07 16:04:07 +00001567 UChar i)
1568{
florian55085f82012-11-21 00:36:55 +00001569 const HChar *mnm = irgen(i);
sewardj2019a972011-03-07 16:04:07 +00001570
sewardj7ee97522011-05-09 21:45:04 +00001571 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001572 s390_disasm(ENC2(MNM, UINT), mnm, i);
1573}
1574
1575static void
florian55085f82012-11-21 00:36:55 +00001576s390_format_RI(const HChar *(*irgen)(UChar r1, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00001577 UChar r1, UShort i2)
1578{
1579 irgen(r1, i2);
1580}
1581
1582static void
florian55085f82012-11-21 00:36:55 +00001583s390_format_RI_RU(const HChar *(*irgen)(UChar r1, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00001584 UChar r1, UShort i2)
1585{
florian55085f82012-11-21 00:36:55 +00001586 const HChar *mnm = irgen(r1, i2);
sewardj2019a972011-03-07 16:04:07 +00001587
sewardj7ee97522011-05-09 21:45:04 +00001588 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001589 s390_disasm(ENC3(MNM, GPR, UINT), mnm, r1, i2);
1590}
1591
1592static void
florian55085f82012-11-21 00:36:55 +00001593s390_format_RI_RI(const HChar *(*irgen)(UChar r1, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00001594 UChar r1, UShort i2)
1595{
florian55085f82012-11-21 00:36:55 +00001596 const HChar *mnm = irgen(r1, i2);
sewardj2019a972011-03-07 16:04:07 +00001597
sewardj7ee97522011-05-09 21:45:04 +00001598 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001599 s390_disasm(ENC3(MNM, GPR, INT), mnm, r1, (Int)(Short)i2);
1600}
1601
1602static void
florian55085f82012-11-21 00:36:55 +00001603s390_format_RI_RP(const HChar *(*irgen)(UChar r1, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00001604 UChar r1, UShort i2)
1605{
florian55085f82012-11-21 00:36:55 +00001606 const HChar *mnm = irgen(r1, i2);
sewardj2019a972011-03-07 16:04:07 +00001607
sewardj7ee97522011-05-09 21:45:04 +00001608 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001609 s390_disasm(ENC3(MNM, GPR, PCREL), mnm, r1, (Int)(Short)i2);
1610}
1611
1612static void
florian55085f82012-11-21 00:36:55 +00001613s390_format_RIE_RRP(const HChar *(*irgen)(UChar r1, UChar r3, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00001614 UChar r1, UChar r3, UShort i2)
1615{
florian55085f82012-11-21 00:36:55 +00001616 const HChar *mnm = irgen(r1, r3, i2);
sewardj2019a972011-03-07 16:04:07 +00001617
sewardj7ee97522011-05-09 21:45:04 +00001618 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001619 s390_disasm(ENC4(MNM, GPR, GPR, PCREL), mnm, r1, r3, (Int)(Short)i2);
1620}
1621
1622static void
florian55085f82012-11-21 00:36:55 +00001623s390_format_RIE_RRI0(const HChar *(*irgen)(UChar r1, UChar r3, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00001624 UChar r1, UChar r3, UShort i2)
1625{
florian55085f82012-11-21 00:36:55 +00001626 const HChar *mnm = irgen(r1, r3, i2);
sewardj2019a972011-03-07 16:04:07 +00001627
sewardj7ee97522011-05-09 21:45:04 +00001628 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001629 s390_disasm(ENC4(MNM, GPR, GPR, INT), mnm, r1, r3, (Int)(Short)i2);
1630}
1631
1632static void
florian55085f82012-11-21 00:36:55 +00001633s390_format_RIE_RRUUU(const HChar *(*irgen)(UChar r1, UChar r2, UChar i3,
1634 UChar i4, UChar i5),
sewardj2019a972011-03-07 16:04:07 +00001635 UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
1636{
florian55085f82012-11-21 00:36:55 +00001637 const HChar *mnm = irgen(r1, r2, i3, i4, i5);
sewardj2019a972011-03-07 16:04:07 +00001638
sewardj7ee97522011-05-09 21:45:04 +00001639 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001640 s390_disasm(ENC6(MNM, GPR, GPR, UINT, UINT, UINT), mnm, r1, r2, i3, i4,
1641 i5);
1642}
1643
1644static void
florian55085f82012-11-21 00:36:55 +00001645s390_format_RIE_RRPU(const HChar *(*irgen)(UChar r1, UChar r2, UShort i4,
1646 UChar m3),
sewardj2019a972011-03-07 16:04:07 +00001647 UChar r1, UChar r2, UShort i4, UChar m3)
1648{
florian55085f82012-11-21 00:36:55 +00001649 const HChar *mnm = irgen(r1, r2, i4, m3);
sewardj2019a972011-03-07 16:04:07 +00001650
sewardj7ee97522011-05-09 21:45:04 +00001651 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001652 s390_disasm(ENC5(XMNM, GPR, GPR, CABM, PCREL), S390_XMNM_CAB, mnm, m3, r1,
1653 r2, m3, (Int)(Short)i4);
1654}
1655
1656static void
florian55085f82012-11-21 00:36:55 +00001657s390_format_RIE_RUPU(const HChar *(*irgen)(UChar r1, UChar m3, UShort i4,
1658 UChar i2),
sewardj2019a972011-03-07 16:04:07 +00001659 UChar r1, UChar m3, UShort i4, UChar i2)
1660{
florian55085f82012-11-21 00:36:55 +00001661 const HChar *mnm = irgen(r1, m3, i4, i2);
sewardj2019a972011-03-07 16:04:07 +00001662
sewardj7ee97522011-05-09 21:45:04 +00001663 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001664 s390_disasm(ENC5(XMNM, GPR, UINT, CABM, PCREL), S390_XMNM_CAB, mnm, m3,
1665 r1, i2, m3, (Int)(Short)i4);
1666}
1667
1668static void
florian55085f82012-11-21 00:36:55 +00001669s390_format_RIE_RUPI(const HChar *(*irgen)(UChar r1, UChar m3, UShort i4,
1670 UChar i2),
sewardj2019a972011-03-07 16:04:07 +00001671 UChar r1, UChar m3, UShort i4, UChar i2)
1672{
florian55085f82012-11-21 00:36:55 +00001673 const HChar *mnm = irgen(r1, m3, i4, i2);
sewardj2019a972011-03-07 16:04:07 +00001674
sewardj7ee97522011-05-09 21:45:04 +00001675 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001676 s390_disasm(ENC5(XMNM, GPR, INT, CABM, PCREL), S390_XMNM_CAB, mnm, m3, r1,
1677 (Int)(Char)i2, m3, (Int)(Short)i4);
1678}
1679
1680static void
florian55085f82012-11-21 00:36:55 +00001681s390_format_RIL(const HChar *(*irgen)(UChar r1, UInt i2),
sewardj2019a972011-03-07 16:04:07 +00001682 UChar r1, UInt i2)
1683{
1684 irgen(r1, i2);
1685}
1686
1687static void
florian55085f82012-11-21 00:36:55 +00001688s390_format_RIL_RU(const HChar *(*irgen)(UChar r1, UInt i2),
sewardj2019a972011-03-07 16:04:07 +00001689 UChar r1, UInt i2)
1690{
florian55085f82012-11-21 00:36:55 +00001691 const HChar *mnm = irgen(r1, i2);
sewardj2019a972011-03-07 16:04:07 +00001692
sewardj7ee97522011-05-09 21:45:04 +00001693 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001694 s390_disasm(ENC3(MNM, GPR, UINT), mnm, r1, i2);
1695}
1696
1697static void
florian55085f82012-11-21 00:36:55 +00001698s390_format_RIL_RI(const HChar *(*irgen)(UChar r1, UInt i2),
sewardj2019a972011-03-07 16:04:07 +00001699 UChar r1, UInt i2)
1700{
florian55085f82012-11-21 00:36:55 +00001701 const HChar *mnm = irgen(r1, i2);
sewardj2019a972011-03-07 16:04:07 +00001702
sewardj7ee97522011-05-09 21:45:04 +00001703 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001704 s390_disasm(ENC3(MNM, GPR, INT), mnm, r1, i2);
1705}
1706
1707static void
florian55085f82012-11-21 00:36:55 +00001708s390_format_RIL_RP(const HChar *(*irgen)(UChar r1, UInt i2),
sewardj2019a972011-03-07 16:04:07 +00001709 UChar r1, UInt i2)
1710{
florian55085f82012-11-21 00:36:55 +00001711 const HChar *mnm = irgen(r1, i2);
sewardj2019a972011-03-07 16:04:07 +00001712
sewardj7ee97522011-05-09 21:45:04 +00001713 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001714 s390_disasm(ENC3(MNM, GPR, PCREL), mnm, r1, i2);
1715}
1716
1717static void
florian55085f82012-11-21 00:36:55 +00001718s390_format_RIL_UP(const HChar *(*irgen)(void),
sewardj2019a972011-03-07 16:04:07 +00001719 UChar r1, UInt i2)
1720{
florian55085f82012-11-21 00:36:55 +00001721 const HChar *mnm = irgen();
sewardj2019a972011-03-07 16:04:07 +00001722
sewardj7ee97522011-05-09 21:45:04 +00001723 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001724 s390_disasm(ENC3(MNM, UINT, PCREL), mnm, r1, i2);
1725}
1726
1727static void
florian55085f82012-11-21 00:36:55 +00001728s390_format_RIS_RURDI(const HChar *(*irgen)(UChar r1, UChar m3, UChar i2,
sewardj2019a972011-03-07 16:04:07 +00001729 IRTemp op4addr),
1730 UChar r1, UChar m3, UChar b4, UShort d4, UChar i2)
1731{
florian55085f82012-11-21 00:36:55 +00001732 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00001733 IRTemp op4addr = newTemp(Ity_I64);
1734
1735 assign(op4addr, binop(Iop_Add64, mkU64(d4), b4 != 0 ? get_gpr_dw0(b4) :
1736 mkU64(0)));
1737
1738 mnm = irgen(r1, m3, i2, op4addr);
1739
sewardj7ee97522011-05-09 21:45:04 +00001740 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001741 s390_disasm(ENC5(XMNM, GPR, INT, CABM, UDXB), S390_XMNM_CAB, mnm, m3, r1,
1742 (Int)(Char)i2, m3, d4, 0, b4);
1743}
1744
1745static void
florian55085f82012-11-21 00:36:55 +00001746s390_format_RIS_RURDU(const HChar *(*irgen)(UChar r1, UChar m3, UChar i2,
sewardj2019a972011-03-07 16:04:07 +00001747 IRTemp op4addr),
1748 UChar r1, UChar m3, UChar b4, UShort d4, UChar i2)
1749{
florian55085f82012-11-21 00:36:55 +00001750 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00001751 IRTemp op4addr = newTemp(Ity_I64);
1752
1753 assign(op4addr, binop(Iop_Add64, mkU64(d4), b4 != 0 ? get_gpr_dw0(b4) :
1754 mkU64(0)));
1755
1756 mnm = irgen(r1, m3, i2, op4addr);
1757
sewardj7ee97522011-05-09 21:45:04 +00001758 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001759 s390_disasm(ENC5(XMNM, GPR, UINT, CABM, UDXB), S390_XMNM_CAB, mnm, m3, r1,
1760 i2, m3, d4, 0, b4);
1761}
1762
1763static void
florian55085f82012-11-21 00:36:55 +00001764s390_format_RR(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001765 UChar r1, UChar r2)
1766{
1767 irgen(r1, r2);
1768}
1769
1770static void
florian55085f82012-11-21 00:36:55 +00001771s390_format_RR_RR(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001772 UChar r1, UChar r2)
1773{
florian55085f82012-11-21 00:36:55 +00001774 const HChar *mnm = irgen(r1, r2);
sewardj2019a972011-03-07 16:04:07 +00001775
sewardj7ee97522011-05-09 21:45:04 +00001776 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001777 s390_disasm(ENC3(MNM, GPR, GPR), mnm, r1, r2);
1778}
1779
1780static void
florian55085f82012-11-21 00:36:55 +00001781s390_format_RR_FF(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001782 UChar r1, UChar r2)
1783{
florian55085f82012-11-21 00:36:55 +00001784 const HChar *mnm = irgen(r1, r2);
sewardj2019a972011-03-07 16:04:07 +00001785
sewardj7ee97522011-05-09 21:45:04 +00001786 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001787 s390_disasm(ENC3(MNM, FPR, FPR), mnm, r1, r2);
1788}
1789
1790static void
florian55085f82012-11-21 00:36:55 +00001791s390_format_RRE(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001792 UChar r1, UChar r2)
1793{
1794 irgen(r1, r2);
1795}
1796
1797static void
florian55085f82012-11-21 00:36:55 +00001798s390_format_RRE_RR(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001799 UChar r1, UChar r2)
1800{
florian55085f82012-11-21 00:36:55 +00001801 const HChar *mnm = irgen(r1, r2);
sewardj2019a972011-03-07 16:04:07 +00001802
sewardj7ee97522011-05-09 21:45:04 +00001803 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001804 s390_disasm(ENC3(MNM, GPR, GPR), mnm, r1, r2);
1805}
1806
1807static void
florian55085f82012-11-21 00:36:55 +00001808s390_format_RRE_FF(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001809 UChar r1, UChar r2)
1810{
florian55085f82012-11-21 00:36:55 +00001811 const HChar *mnm = irgen(r1, r2);
sewardj2019a972011-03-07 16:04:07 +00001812
sewardj7ee97522011-05-09 21:45:04 +00001813 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001814 s390_disasm(ENC3(MNM, FPR, FPR), mnm, r1, r2);
1815}
1816
1817static void
florian55085f82012-11-21 00:36:55 +00001818s390_format_RRE_RF(const HChar *(*irgen)(UChar, UChar),
sewardj2019a972011-03-07 16:04:07 +00001819 UChar r1, UChar r2)
1820{
florian55085f82012-11-21 00:36:55 +00001821 const HChar *mnm = irgen(r1, r2);
sewardj2019a972011-03-07 16:04:07 +00001822
sewardj7ee97522011-05-09 21:45:04 +00001823 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001824 s390_disasm(ENC3(MNM, GPR, FPR), mnm, r1, r2);
1825}
1826
1827static void
florian55085f82012-11-21 00:36:55 +00001828s390_format_RRE_FR(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001829 UChar r1, UChar r2)
1830{
florian55085f82012-11-21 00:36:55 +00001831 const HChar *mnm = irgen(r1, r2);
sewardj2019a972011-03-07 16:04:07 +00001832
sewardj7ee97522011-05-09 21:45:04 +00001833 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001834 s390_disasm(ENC3(MNM, FPR, GPR), mnm, r1, r2);
1835}
1836
1837static void
florian55085f82012-11-21 00:36:55 +00001838s390_format_RRE_R0(const HChar *(*irgen)(UChar r1),
sewardj2019a972011-03-07 16:04:07 +00001839 UChar r1)
1840{
florian55085f82012-11-21 00:36:55 +00001841 const HChar *mnm = irgen(r1);
sewardj2019a972011-03-07 16:04:07 +00001842
sewardj7ee97522011-05-09 21:45:04 +00001843 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001844 s390_disasm(ENC2(MNM, GPR), mnm, r1);
1845}
1846
1847static void
florian55085f82012-11-21 00:36:55 +00001848s390_format_RRE_F0(const HChar *(*irgen)(UChar r1),
sewardj2019a972011-03-07 16:04:07 +00001849 UChar r1)
1850{
florian55085f82012-11-21 00:36:55 +00001851 const HChar *mnm = irgen(r1);
sewardj2019a972011-03-07 16:04:07 +00001852
sewardj7ee97522011-05-09 21:45:04 +00001853 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001854 s390_disasm(ENC2(MNM, FPR), mnm, r1);
1855}
1856
1857static void
florian55085f82012-11-21 00:36:55 +00001858s390_format_RRF_M0RERE(const HChar *(*irgen)(UChar m3, UChar r1, UChar r2),
florian9af37692012-01-15 21:01:16 +00001859 UChar m3, UChar r1, UChar r2)
1860{
florian55085f82012-11-21 00:36:55 +00001861 const HChar *mnm = irgen(m3, r1, r2);
florian9af37692012-01-15 21:01:16 +00001862
1863 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
florianfed3ea32012-07-19 14:54:03 +00001864 s390_disasm(ENC4(MNM, GPR, GPR, UINT), mnm, r1, r2, m3);
florian9af37692012-01-15 21:01:16 +00001865}
1866
1867static void
florian55085f82012-11-21 00:36:55 +00001868s390_format_RRF_F0FF(const HChar *(*irgen)(UChar, UChar, UChar),
sewardj2019a972011-03-07 16:04:07 +00001869 UChar r1, UChar r3, UChar r2)
1870{
florian55085f82012-11-21 00:36:55 +00001871 const HChar *mnm = irgen(r1, r3, r2);
sewardj2019a972011-03-07 16:04:07 +00001872
sewardj7ee97522011-05-09 21:45:04 +00001873 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001874 s390_disasm(ENC4(MNM, FPR, FPR, FPR), mnm, r1, r3, r2);
1875}
1876
1877static void
florian55085f82012-11-21 00:36:55 +00001878s390_format_RRF_UUFF(const HChar *(*irgen)(UChar m3, UChar m4, UChar r1,
1879 UChar r2),
florian4b8efad2012-09-02 18:07:08 +00001880 UChar m3, UChar m4, UChar r1, UChar r2)
1881{
florian55085f82012-11-21 00:36:55 +00001882 const HChar *mnm = irgen(m3, m4, r1, r2);
florian4b8efad2012-09-02 18:07:08 +00001883
1884 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1885 s390_disasm(ENC5(MNM, FPR, UINT, FPR, UINT), mnm, r1, m3, r2, m4);
1886}
1887
1888static void
florian55085f82012-11-21 00:36:55 +00001889s390_format_RRF_UUFR(const HChar *(*irgen)(UChar m3, UChar m4, UChar r1,
1890 UChar r2),
florian1c8f7ff2012-09-01 00:12:11 +00001891 UChar m3, UChar m4, UChar r1, UChar r2)
1892{
florian55085f82012-11-21 00:36:55 +00001893 const HChar *mnm = irgen(m3, m4, r1, r2);
florian1c8f7ff2012-09-01 00:12:11 +00001894
1895 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1896 s390_disasm(ENC5(MNM, FPR, UINT, GPR, UINT), mnm, r1, m3, r2, m4);
1897}
1898
1899static void
florian55085f82012-11-21 00:36:55 +00001900s390_format_RRF_UURF(const HChar *(*irgen)(UChar m3, UChar m4, UChar r1,
1901 UChar r2),
florian1c8f7ff2012-09-01 00:12:11 +00001902 UChar m3, UChar m4, UChar r1, UChar r2)
1903{
florian55085f82012-11-21 00:36:55 +00001904 const HChar *mnm = irgen(m3, m4, r1, r2);
florian1c8f7ff2012-09-01 00:12:11 +00001905
1906 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1907 s390_disasm(ENC5(MNM, GPR, UINT, FPR, UINT), mnm, r1, m3, r2, m4);
1908}
1909
1910
1911static void
florian55085f82012-11-21 00:36:55 +00001912s390_format_RRF_U0RR(const HChar *(*irgen)(UChar m3, UChar r1, UChar r2),
sewardjd7bde722011-04-05 13:19:33 +00001913 UChar m3, UChar r1, UChar r2, Int xmnm_kind)
1914{
1915 irgen(m3, r1, r2);
1916
sewardj7ee97522011-05-09 21:45:04 +00001917 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardjd7bde722011-04-05 13:19:33 +00001918 s390_disasm(ENC3(XMNM, GPR, GPR), xmnm_kind, m3, r1, r2);
1919}
1920
1921static void
florian55085f82012-11-21 00:36:55 +00001922s390_format_RRF_F0FF2(const HChar *(*irgen)(UChar, UChar, UChar),
sewardj2019a972011-03-07 16:04:07 +00001923 UChar r3, UChar r1, UChar r2)
1924{
florian55085f82012-11-21 00:36:55 +00001925 const HChar *mnm = irgen(r3, r1, r2);
sewardj2019a972011-03-07 16:04:07 +00001926
sewardj7ee97522011-05-09 21:45:04 +00001927 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001928 s390_disasm(ENC4(MNM, FPR, FPR, FPR), mnm, r1, r3, r2);
1929}
1930
1931static void
florian55085f82012-11-21 00:36:55 +00001932s390_format_RRF_FUFF2(const HChar *(*irgen)(UChar, UChar, UChar, UChar),
florian12390202012-11-10 22:34:14 +00001933 UChar r3, UChar m4, UChar r1, UChar r2)
1934{
florian55085f82012-11-21 00:36:55 +00001935 const HChar *mnm = irgen(r3, m4, r1, r2);
florian12390202012-11-10 22:34:14 +00001936
1937 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1938 s390_disasm(ENC5(MNM, FPR, FPR, FPR, UINT), mnm, r1, r2, r3, m4);
1939}
1940
1941static void
florian55085f82012-11-21 00:36:55 +00001942s390_format_RRF_R0RR2(const HChar *(*irgen)(UChar r3, UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001943 UChar r3, UChar r1, UChar r2)
1944{
florian55085f82012-11-21 00:36:55 +00001945 const HChar *mnm = irgen(r3, r1, r2);
sewardj2019a972011-03-07 16:04:07 +00001946
sewardj7ee97522011-05-09 21:45:04 +00001947 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001948 s390_disasm(ENC4(MNM, GPR, GPR, GPR), mnm, r1, r2, r3);
1949}
1950
1951static void
florian55085f82012-11-21 00:36:55 +00001952s390_format_RRS(const HChar *(*irgen)(UChar r1, UChar r2, UChar m3,
1953 IRTemp op4addr),
sewardj2019a972011-03-07 16:04:07 +00001954 UChar r1, UChar r2, UChar b4, UShort d4, UChar m3)
1955{
florian55085f82012-11-21 00:36:55 +00001956 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00001957 IRTemp op4addr = newTemp(Ity_I64);
1958
1959 assign(op4addr, binop(Iop_Add64, mkU64(d4), b4 != 0 ? get_gpr_dw0(b4) :
1960 mkU64(0)));
1961
1962 mnm = irgen(r1, r2, m3, op4addr);
1963
sewardj7ee97522011-05-09 21:45:04 +00001964 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001965 s390_disasm(ENC5(XMNM, GPR, GPR, CABM, UDXB), S390_XMNM_CAB, mnm, m3, r1,
1966 r2, m3, d4, 0, b4);
1967}
1968
1969static void
florian55085f82012-11-21 00:36:55 +00001970s390_format_RS_R0RD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00001971 UChar r1, UChar b2, UShort d2)
1972{
florian55085f82012-11-21 00:36:55 +00001973 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00001974 IRTemp op2addr = newTemp(Ity_I64);
1975
1976 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
1977 mkU64(0)));
1978
1979 mnm = irgen(r1, op2addr);
1980
sewardj7ee97522011-05-09 21:45:04 +00001981 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001982 s390_disasm(ENC3(MNM, GPR, UDXB), mnm, r1, d2, 0, b2);
1983}
1984
1985static void
florian55085f82012-11-21 00:36:55 +00001986s390_format_RS_RRRD(const HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00001987 UChar r1, UChar r3, UChar b2, UShort d2)
1988{
florian55085f82012-11-21 00:36:55 +00001989 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00001990 IRTemp op2addr = newTemp(Ity_I64);
1991
1992 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
1993 mkU64(0)));
1994
1995 mnm = irgen(r1, r3, op2addr);
1996
sewardj7ee97522011-05-09 21:45:04 +00001997 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001998 s390_disasm(ENC4(MNM, GPR, GPR, UDXB), mnm, r1, r3, d2, 0, b2);
1999}
2000
2001static void
florian55085f82012-11-21 00:36:55 +00002002s390_format_RS_RURD(const HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002003 UChar r1, UChar r3, UChar b2, UShort d2)
2004{
florian55085f82012-11-21 00:36:55 +00002005 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002006 IRTemp op2addr = newTemp(Ity_I64);
2007
2008 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2009 mkU64(0)));
2010
2011 mnm = irgen(r1, r3, op2addr);
2012
sewardj7ee97522011-05-09 21:45:04 +00002013 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002014 s390_disasm(ENC4(MNM, GPR, UINT, UDXB), mnm, r1, r3, d2, 0, b2);
2015}
2016
2017static void
florian55085f82012-11-21 00:36:55 +00002018s390_format_RS_AARD(const HChar *(*irgen)(UChar, UChar, IRTemp),
sewardj2019a972011-03-07 16:04:07 +00002019 UChar r1, UChar r3, UChar b2, UShort d2)
2020{
florian55085f82012-11-21 00:36:55 +00002021 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002022 IRTemp op2addr = newTemp(Ity_I64);
2023
2024 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2025 mkU64(0)));
2026
2027 mnm = irgen(r1, r3, op2addr);
2028
sewardj7ee97522011-05-09 21:45:04 +00002029 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002030 s390_disasm(ENC4(MNM, AR, AR, UDXB), mnm, r1, r3, d2, 0, b2);
2031}
2032
2033static void
florian55085f82012-11-21 00:36:55 +00002034s390_format_RSI_RRP(const HChar *(*irgen)(UChar r1, UChar r3, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00002035 UChar r1, UChar r3, UShort i2)
2036{
florian55085f82012-11-21 00:36:55 +00002037 const HChar *mnm = irgen(r1, r3, i2);
sewardj2019a972011-03-07 16:04:07 +00002038
sewardj7ee97522011-05-09 21:45:04 +00002039 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002040 s390_disasm(ENC4(MNM, GPR, GPR, PCREL), mnm, r1, r3, (Int)(Short)i2);
2041}
2042
2043static void
florian55085f82012-11-21 00:36:55 +00002044s390_format_RSY_RRRD(const HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002045 UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
2046{
florian55085f82012-11-21 00:36:55 +00002047 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002048 IRTemp op2addr = newTemp(Ity_I64);
2049 IRTemp d2 = newTemp(Ity_I64);
2050
2051 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2052 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
2053 mkU64(0)));
2054
2055 mnm = irgen(r1, r3, op2addr);
2056
sewardj7ee97522011-05-09 21:45:04 +00002057 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002058 s390_disasm(ENC4(MNM, GPR, GPR, SDXB), mnm, r1, r3, dh2, dl2, 0, b2);
2059}
2060
2061static void
florian55085f82012-11-21 00:36:55 +00002062s390_format_RSY_AARD(const HChar *(*irgen)(UChar, UChar, IRTemp),
sewardj2019a972011-03-07 16:04:07 +00002063 UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
2064{
florian55085f82012-11-21 00:36:55 +00002065 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002066 IRTemp op2addr = newTemp(Ity_I64);
2067 IRTemp d2 = newTemp(Ity_I64);
2068
2069 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2070 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
2071 mkU64(0)));
2072
2073 mnm = irgen(r1, r3, op2addr);
2074
sewardj7ee97522011-05-09 21:45:04 +00002075 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002076 s390_disasm(ENC4(MNM, AR, AR, SDXB), mnm, r1, r3, dh2, dl2, 0, b2);
2077}
2078
2079static void
florian55085f82012-11-21 00:36:55 +00002080s390_format_RSY_RURD(const HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002081 UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
2082{
florian55085f82012-11-21 00:36:55 +00002083 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002084 IRTemp op2addr = newTemp(Ity_I64);
2085 IRTemp d2 = newTemp(Ity_I64);
2086
2087 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2088 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
2089 mkU64(0)));
2090
2091 mnm = irgen(r1, r3, op2addr);
2092
sewardj7ee97522011-05-09 21:45:04 +00002093 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002094 s390_disasm(ENC4(MNM, GPR, UINT, SDXB), mnm, r1, r3, dh2, dl2, 0, b2);
2095}
2096
2097static void
florian55085f82012-11-21 00:36:55 +00002098s390_format_RSY_RDRM(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardjd7bde722011-04-05 13:19:33 +00002099 UChar r1, UChar m3, UChar b2, UShort dl2, UChar dh2,
2100 Int xmnm_kind)
2101{
2102 IRTemp op2addr = newTemp(Ity_I64);
2103 IRTemp d2 = newTemp(Ity_I64);
2104
florian6820ba52012-07-26 02:01:50 +00002105 next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
2106
sewardjd7bde722011-04-05 13:19:33 +00002107 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2108 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
2109 mkU64(0)));
2110
2111 irgen(r1, op2addr);
florian6820ba52012-07-26 02:01:50 +00002112
2113 vassert(dis_res->whatNext == Dis_Continue);
sewardjd7bde722011-04-05 13:19:33 +00002114
sewardj7ee97522011-05-09 21:45:04 +00002115 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardjd7bde722011-04-05 13:19:33 +00002116 s390_disasm(ENC3(XMNM, GPR, SDXB), xmnm_kind, m3, r1, dh2, dl2, 0, b2);
2117}
2118
2119static void
florian55085f82012-11-21 00:36:55 +00002120s390_format_RX(const HChar *(*irgen)(UChar r1, UChar x2, UChar b2, UShort d2,
sewardj2019a972011-03-07 16:04:07 +00002121 IRTemp op2addr),
2122 UChar r1, UChar x2, UChar b2, UShort d2)
2123{
2124 IRTemp op2addr = newTemp(Ity_I64);
2125
2126 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2127 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2128 mkU64(0)));
2129
2130 irgen(r1, x2, b2, d2, op2addr);
2131}
2132
2133static void
florian55085f82012-11-21 00:36:55 +00002134s390_format_RX_RRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002135 UChar r1, UChar x2, UChar b2, UShort d2)
2136{
florian55085f82012-11-21 00:36:55 +00002137 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002138 IRTemp op2addr = newTemp(Ity_I64);
2139
2140 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2141 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2142 mkU64(0)));
2143
2144 mnm = irgen(r1, op2addr);
2145
sewardj7ee97522011-05-09 21:45:04 +00002146 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002147 s390_disasm(ENC3(MNM, GPR, UDXB), mnm, r1, d2, x2, b2);
2148}
2149
2150static void
florian55085f82012-11-21 00:36:55 +00002151s390_format_RX_FRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002152 UChar r1, UChar x2, UChar b2, UShort d2)
2153{
florian55085f82012-11-21 00:36:55 +00002154 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002155 IRTemp op2addr = newTemp(Ity_I64);
2156
2157 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2158 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2159 mkU64(0)));
2160
2161 mnm = irgen(r1, op2addr);
2162
sewardj7ee97522011-05-09 21:45:04 +00002163 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002164 s390_disasm(ENC3(MNM, FPR, UDXB), mnm, r1, d2, x2, b2);
2165}
2166
2167static void
florian55085f82012-11-21 00:36:55 +00002168s390_format_RXE_FRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002169 UChar r1, UChar x2, UChar b2, UShort d2)
2170{
florian55085f82012-11-21 00:36:55 +00002171 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002172 IRTemp op2addr = newTemp(Ity_I64);
2173
2174 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2175 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2176 mkU64(0)));
2177
2178 mnm = irgen(r1, op2addr);
2179
sewardj7ee97522011-05-09 21:45:04 +00002180 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002181 s390_disasm(ENC3(MNM, FPR, UDXB), mnm, r1, d2, x2, b2);
2182}
2183
2184static void
florian55085f82012-11-21 00:36:55 +00002185s390_format_RXF_FRRDF(const HChar *(*irgen)(UChar, IRTemp, UChar),
sewardj2019a972011-03-07 16:04:07 +00002186 UChar r3, UChar x2, UChar b2, UShort d2, UChar r1)
2187{
florian55085f82012-11-21 00:36:55 +00002188 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002189 IRTemp op2addr = newTemp(Ity_I64);
2190
2191 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2192 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2193 mkU64(0)));
2194
2195 mnm = irgen(r3, op2addr, r1);
2196
sewardj7ee97522011-05-09 21:45:04 +00002197 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002198 s390_disasm(ENC4(MNM, FPR, FPR, UDXB), mnm, r1, r3, d2, x2, b2);
2199}
2200
2201static void
florian55085f82012-11-21 00:36:55 +00002202s390_format_RXY_RRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002203 UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
2204{
florian55085f82012-11-21 00:36:55 +00002205 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002206 IRTemp op2addr = newTemp(Ity_I64);
2207 IRTemp d2 = newTemp(Ity_I64);
2208
2209 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2210 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkexpr(d2),
2211 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2212 mkU64(0)));
2213
2214 mnm = irgen(r1, op2addr);
2215
sewardj7ee97522011-05-09 21:45:04 +00002216 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002217 s390_disasm(ENC3(MNM, GPR, SDXB), mnm, r1, dh2, dl2, x2, b2);
2218}
2219
2220static void
florian55085f82012-11-21 00:36:55 +00002221s390_format_RXY_FRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002222 UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
2223{
florian55085f82012-11-21 00:36:55 +00002224 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002225 IRTemp op2addr = newTemp(Ity_I64);
2226 IRTemp d2 = newTemp(Ity_I64);
2227
2228 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2229 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkexpr(d2),
2230 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2231 mkU64(0)));
2232
2233 mnm = irgen(r1, op2addr);
2234
sewardj7ee97522011-05-09 21:45:04 +00002235 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002236 s390_disasm(ENC3(MNM, FPR, SDXB), mnm, r1, dh2, dl2, x2, b2);
2237}
2238
2239static void
florian55085f82012-11-21 00:36:55 +00002240s390_format_RXY_URRD(const HChar *(*irgen)(void),
sewardj2019a972011-03-07 16:04:07 +00002241 UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
2242{
florian55085f82012-11-21 00:36:55 +00002243 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002244 IRTemp op2addr = newTemp(Ity_I64);
2245 IRTemp d2 = newTemp(Ity_I64);
2246
2247 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2248 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkexpr(d2),
2249 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2250 mkU64(0)));
2251
2252 mnm = irgen();
2253
sewardj7ee97522011-05-09 21:45:04 +00002254 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002255 s390_disasm(ENC3(MNM, UINT, SDXB), mnm, r1, dh2, dl2, x2, b2);
2256}
2257
2258static void
florian55085f82012-11-21 00:36:55 +00002259s390_format_S_RD(const HChar *(*irgen)(IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002260 UChar b2, UShort d2)
2261{
florian55085f82012-11-21 00:36:55 +00002262 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002263 IRTemp op2addr = newTemp(Ity_I64);
2264
2265 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2266 mkU64(0)));
2267
2268 mnm = irgen(op2addr);
2269
sewardj7ee97522011-05-09 21:45:04 +00002270 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002271 s390_disasm(ENC2(MNM, UDXB), mnm, d2, 0, b2);
2272}
2273
2274static void
florian55085f82012-11-21 00:36:55 +00002275s390_format_SI_URD(const HChar *(*irgen)(UChar i2, IRTemp op1addr),
sewardj2019a972011-03-07 16:04:07 +00002276 UChar i2, UChar b1, UShort d1)
2277{
florian55085f82012-11-21 00:36:55 +00002278 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002279 IRTemp op1addr = newTemp(Ity_I64);
2280
2281 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2282 mkU64(0)));
2283
2284 mnm = irgen(i2, op1addr);
2285
sewardj7ee97522011-05-09 21:45:04 +00002286 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002287 s390_disasm(ENC3(MNM, UDXB, UINT), mnm, d1, 0, b1, i2);
2288}
2289
2290static void
florian55085f82012-11-21 00:36:55 +00002291s390_format_SIY_URD(const HChar *(*irgen)(UChar i2, IRTemp op1addr),
sewardj2019a972011-03-07 16:04:07 +00002292 UChar i2, UChar b1, UShort dl1, UChar dh1)
2293{
florian55085f82012-11-21 00:36:55 +00002294 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002295 IRTemp op1addr = newTemp(Ity_I64);
2296 IRTemp d1 = newTemp(Ity_I64);
2297
2298 assign(d1, mkU64(((ULong)(Long)(Char)dh1 << 12) | ((ULong)dl1)));
2299 assign(op1addr, binop(Iop_Add64, mkexpr(d1), b1 != 0 ? get_gpr_dw0(b1) :
2300 mkU64(0)));
2301
2302 mnm = irgen(i2, op1addr);
2303
sewardj7ee97522011-05-09 21:45:04 +00002304 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002305 s390_disasm(ENC3(MNM, SDXB, UINT), mnm, dh1, dl1, 0, b1, i2);
2306}
2307
2308static void
florian55085f82012-11-21 00:36:55 +00002309s390_format_SIY_IRD(const HChar *(*irgen)(UChar i2, IRTemp op1addr),
sewardj2019a972011-03-07 16:04:07 +00002310 UChar i2, UChar b1, UShort dl1, UChar dh1)
2311{
florian55085f82012-11-21 00:36:55 +00002312 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002313 IRTemp op1addr = newTemp(Ity_I64);
2314 IRTemp d1 = newTemp(Ity_I64);
2315
2316 assign(d1, mkU64(((ULong)(Long)(Char)dh1 << 12) | ((ULong)dl1)));
2317 assign(op1addr, binop(Iop_Add64, mkexpr(d1), b1 != 0 ? get_gpr_dw0(b1) :
2318 mkU64(0)));
2319
2320 mnm = irgen(i2, op1addr);
2321
sewardj7ee97522011-05-09 21:45:04 +00002322 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002323 s390_disasm(ENC3(MNM, SDXB, INT), mnm, dh1, dl1, 0, b1, (Int)(Char)i2);
2324}
2325
2326static void
florian55085f82012-11-21 00:36:55 +00002327s390_format_SS_L0RDRD(const HChar *(*irgen)(UChar, IRTemp, IRTemp),
sewardj2019a972011-03-07 16:04:07 +00002328 UChar l, UChar b1, UShort d1, UChar b2, UShort d2)
2329{
florian55085f82012-11-21 00:36:55 +00002330 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002331 IRTemp op1addr = newTemp(Ity_I64);
2332 IRTemp op2addr = newTemp(Ity_I64);
2333
2334 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2335 mkU64(0)));
2336 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2337 mkU64(0)));
2338
2339 mnm = irgen(l, op1addr, op2addr);
2340
sewardj7ee97522011-05-09 21:45:04 +00002341 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002342 s390_disasm(ENC3(MNM, UDLB, UDXB), mnm, d1, l, b1, d2, 0, b2);
2343}
2344
2345static void
florian55085f82012-11-21 00:36:55 +00002346s390_format_SIL_RDI(const HChar *(*irgen)(UShort i2, IRTemp op1addr),
sewardj2019a972011-03-07 16:04:07 +00002347 UChar b1, UShort d1, UShort i2)
2348{
florian55085f82012-11-21 00:36:55 +00002349 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002350 IRTemp op1addr = newTemp(Ity_I64);
2351
2352 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2353 mkU64(0)));
2354
2355 mnm = irgen(i2, op1addr);
2356
sewardj7ee97522011-05-09 21:45:04 +00002357 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002358 s390_disasm(ENC3(MNM, UDXB, INT), mnm, d1, 0, b1, (Int)(Short)i2);
2359}
2360
2361static void
florian55085f82012-11-21 00:36:55 +00002362s390_format_SIL_RDU(const HChar *(*irgen)(UShort i2, IRTemp op1addr),
sewardj2019a972011-03-07 16:04:07 +00002363 UChar b1, UShort d1, UShort i2)
2364{
florian55085f82012-11-21 00:36:55 +00002365 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002366 IRTemp op1addr = newTemp(Ity_I64);
2367
2368 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2369 mkU64(0)));
2370
2371 mnm = irgen(i2, op1addr);
2372
sewardj7ee97522011-05-09 21:45:04 +00002373 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002374 s390_disasm(ENC3(MNM, UDXB, UINT), mnm, d1, 0, b1, i2);
2375}
2376
2377
2378
2379/*------------------------------------------------------------*/
2380/*--- Build IR for opcodes ---*/
2381/*------------------------------------------------------------*/
2382
florian55085f82012-11-21 00:36:55 +00002383static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002384s390_irgen_AR(UChar r1, UChar r2)
2385{
2386 IRTemp op1 = newTemp(Ity_I32);
2387 IRTemp op2 = newTemp(Ity_I32);
2388 IRTemp result = newTemp(Ity_I32);
2389
2390 assign(op1, get_gpr_w1(r1));
2391 assign(op2, get_gpr_w1(r2));
2392 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2393 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2394 put_gpr_w1(r1, mkexpr(result));
2395
2396 return "ar";
2397}
2398
florian55085f82012-11-21 00:36:55 +00002399static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002400s390_irgen_AGR(UChar r1, UChar r2)
2401{
2402 IRTemp op1 = newTemp(Ity_I64);
2403 IRTemp op2 = newTemp(Ity_I64);
2404 IRTemp result = newTemp(Ity_I64);
2405
2406 assign(op1, get_gpr_dw0(r1));
2407 assign(op2, get_gpr_dw0(r2));
2408 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2409 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2410 put_gpr_dw0(r1, mkexpr(result));
2411
2412 return "agr";
2413}
2414
florian55085f82012-11-21 00:36:55 +00002415static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002416s390_irgen_AGFR(UChar r1, UChar r2)
2417{
2418 IRTemp op1 = newTemp(Ity_I64);
2419 IRTemp op2 = newTemp(Ity_I64);
2420 IRTemp result = newTemp(Ity_I64);
2421
2422 assign(op1, get_gpr_dw0(r1));
2423 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
2424 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2425 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2426 put_gpr_dw0(r1, mkexpr(result));
2427
2428 return "agfr";
2429}
2430
florian55085f82012-11-21 00:36:55 +00002431static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002432s390_irgen_ARK(UChar r3, UChar r1, UChar r2)
2433{
2434 IRTemp op2 = newTemp(Ity_I32);
2435 IRTemp op3 = newTemp(Ity_I32);
2436 IRTemp result = newTemp(Ity_I32);
2437
2438 assign(op2, get_gpr_w1(r2));
2439 assign(op3, get_gpr_w1(r3));
2440 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2441 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
2442 put_gpr_w1(r1, mkexpr(result));
2443
2444 return "ark";
2445}
2446
florian55085f82012-11-21 00:36:55 +00002447static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002448s390_irgen_AGRK(UChar r3, UChar r1, UChar r2)
2449{
2450 IRTemp op2 = newTemp(Ity_I64);
2451 IRTemp op3 = newTemp(Ity_I64);
2452 IRTemp result = newTemp(Ity_I64);
2453
2454 assign(op2, get_gpr_dw0(r2));
2455 assign(op3, get_gpr_dw0(r3));
2456 assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
2457 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op2, op3);
2458 put_gpr_dw0(r1, mkexpr(result));
2459
2460 return "agrk";
2461}
2462
florian55085f82012-11-21 00:36:55 +00002463static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002464s390_irgen_A(UChar r1, IRTemp op2addr)
2465{
2466 IRTemp op1 = newTemp(Ity_I32);
2467 IRTemp op2 = newTemp(Ity_I32);
2468 IRTemp result = newTemp(Ity_I32);
2469
2470 assign(op1, get_gpr_w1(r1));
2471 assign(op2, load(Ity_I32, mkexpr(op2addr)));
2472 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2473 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2474 put_gpr_w1(r1, mkexpr(result));
2475
2476 return "a";
2477}
2478
florian55085f82012-11-21 00:36:55 +00002479static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002480s390_irgen_AY(UChar r1, IRTemp op2addr)
2481{
2482 IRTemp op1 = newTemp(Ity_I32);
2483 IRTemp op2 = newTemp(Ity_I32);
2484 IRTemp result = newTemp(Ity_I32);
2485
2486 assign(op1, get_gpr_w1(r1));
2487 assign(op2, load(Ity_I32, mkexpr(op2addr)));
2488 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2489 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2490 put_gpr_w1(r1, mkexpr(result));
2491
2492 return "ay";
2493}
2494
florian55085f82012-11-21 00:36:55 +00002495static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002496s390_irgen_AG(UChar r1, IRTemp op2addr)
2497{
2498 IRTemp op1 = newTemp(Ity_I64);
2499 IRTemp op2 = newTemp(Ity_I64);
2500 IRTemp result = newTemp(Ity_I64);
2501
2502 assign(op1, get_gpr_dw0(r1));
2503 assign(op2, load(Ity_I64, mkexpr(op2addr)));
2504 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2505 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2506 put_gpr_dw0(r1, mkexpr(result));
2507
2508 return "ag";
2509}
2510
florian55085f82012-11-21 00:36:55 +00002511static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002512s390_irgen_AGF(UChar r1, IRTemp op2addr)
2513{
2514 IRTemp op1 = newTemp(Ity_I64);
2515 IRTemp op2 = newTemp(Ity_I64);
2516 IRTemp result = newTemp(Ity_I64);
2517
2518 assign(op1, get_gpr_dw0(r1));
2519 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
2520 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2521 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2522 put_gpr_dw0(r1, mkexpr(result));
2523
2524 return "agf";
2525}
2526
florian55085f82012-11-21 00:36:55 +00002527static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002528s390_irgen_AFI(UChar r1, UInt i2)
2529{
2530 IRTemp op1 = newTemp(Ity_I32);
2531 Int op2;
2532 IRTemp result = newTemp(Ity_I32);
2533
2534 assign(op1, get_gpr_w1(r1));
2535 op2 = (Int)i2;
2536 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2537 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2538 mkU32((UInt)op2)));
2539 put_gpr_w1(r1, mkexpr(result));
2540
2541 return "afi";
2542}
2543
florian55085f82012-11-21 00:36:55 +00002544static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002545s390_irgen_AGFI(UChar r1, UInt i2)
2546{
2547 IRTemp op1 = newTemp(Ity_I64);
2548 Long op2;
2549 IRTemp result = newTemp(Ity_I64);
2550
2551 assign(op1, get_gpr_dw0(r1));
2552 op2 = (Long)(Int)i2;
2553 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64((ULong)op2)));
2554 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, mktemp(Ity_I64,
2555 mkU64((ULong)op2)));
2556 put_gpr_dw0(r1, mkexpr(result));
2557
2558 return "agfi";
2559}
2560
florian55085f82012-11-21 00:36:55 +00002561static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002562s390_irgen_AHIK(UChar r1, UChar r3, UShort i2)
2563{
2564 Int op2;
2565 IRTemp op3 = newTemp(Ity_I32);
2566 IRTemp result = newTemp(Ity_I32);
2567
2568 op2 = (Int)(Short)i2;
2569 assign(op3, get_gpr_w1(r3));
2570 assign(result, binop(Iop_Add32, mkU32((UInt)op2), mkexpr(op3)));
2571 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, mktemp(Ity_I32, mkU32((UInt)
2572 op2)), op3);
2573 put_gpr_w1(r1, mkexpr(result));
2574
2575 return "ahik";
2576}
2577
florian55085f82012-11-21 00:36:55 +00002578static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002579s390_irgen_AGHIK(UChar r1, UChar r3, UShort i2)
2580{
2581 Long op2;
2582 IRTemp op3 = newTemp(Ity_I64);
2583 IRTemp result = newTemp(Ity_I64);
2584
2585 op2 = (Long)(Short)i2;
2586 assign(op3, get_gpr_dw0(r3));
2587 assign(result, binop(Iop_Add64, mkU64((ULong)op2), mkexpr(op3)));
2588 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, mktemp(Ity_I64, mkU64((ULong)
2589 op2)), op3);
2590 put_gpr_dw0(r1, mkexpr(result));
2591
2592 return "aghik";
2593}
2594
florian55085f82012-11-21 00:36:55 +00002595static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002596s390_irgen_ASI(UChar i2, IRTemp op1addr)
2597{
2598 IRTemp op1 = newTemp(Ity_I32);
2599 Int op2;
2600 IRTemp result = newTemp(Ity_I32);
2601
2602 assign(op1, load(Ity_I32, mkexpr(op1addr)));
2603 op2 = (Int)(Char)i2;
2604 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2605 store(mkexpr(op1addr), mkexpr(result));
2606 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2607 mkU32((UInt)op2)));
2608
2609 return "asi";
2610}
2611
florian55085f82012-11-21 00:36:55 +00002612static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002613s390_irgen_AGSI(UChar i2, IRTemp op1addr)
2614{
2615 IRTemp op1 = newTemp(Ity_I64);
2616 Long op2;
2617 IRTemp result = newTemp(Ity_I64);
2618
2619 assign(op1, load(Ity_I64, mkexpr(op1addr)));
2620 op2 = (Long)(Char)i2;
2621 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64((ULong)op2)));
2622 store(mkexpr(op1addr), mkexpr(result));
2623 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, mktemp(Ity_I64,
2624 mkU64((ULong)op2)));
2625
2626 return "agsi";
2627}
2628
florian55085f82012-11-21 00:36:55 +00002629static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002630s390_irgen_AH(UChar r1, IRTemp op2addr)
2631{
2632 IRTemp op1 = newTemp(Ity_I32);
2633 IRTemp op2 = newTemp(Ity_I32);
2634 IRTemp result = newTemp(Ity_I32);
2635
2636 assign(op1, get_gpr_w1(r1));
2637 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
2638 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2639 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2640 put_gpr_w1(r1, mkexpr(result));
2641
2642 return "ah";
2643}
2644
florian55085f82012-11-21 00:36:55 +00002645static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002646s390_irgen_AHY(UChar r1, IRTemp op2addr)
2647{
2648 IRTemp op1 = newTemp(Ity_I32);
2649 IRTemp op2 = newTemp(Ity_I32);
2650 IRTemp result = newTemp(Ity_I32);
2651
2652 assign(op1, get_gpr_w1(r1));
2653 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
2654 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2655 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2656 put_gpr_w1(r1, mkexpr(result));
2657
2658 return "ahy";
2659}
2660
florian55085f82012-11-21 00:36:55 +00002661static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002662s390_irgen_AHI(UChar r1, UShort i2)
2663{
2664 IRTemp op1 = newTemp(Ity_I32);
2665 Int op2;
2666 IRTemp result = newTemp(Ity_I32);
2667
2668 assign(op1, get_gpr_w1(r1));
2669 op2 = (Int)(Short)i2;
2670 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2671 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2672 mkU32((UInt)op2)));
2673 put_gpr_w1(r1, mkexpr(result));
2674
2675 return "ahi";
2676}
2677
florian55085f82012-11-21 00:36:55 +00002678static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002679s390_irgen_AGHI(UChar r1, UShort i2)
2680{
2681 IRTemp op1 = newTemp(Ity_I64);
2682 Long op2;
2683 IRTemp result = newTemp(Ity_I64);
2684
2685 assign(op1, get_gpr_dw0(r1));
2686 op2 = (Long)(Short)i2;
2687 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64((ULong)op2)));
2688 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, mktemp(Ity_I64,
2689 mkU64((ULong)op2)));
2690 put_gpr_dw0(r1, mkexpr(result));
2691
2692 return "aghi";
2693}
2694
florian55085f82012-11-21 00:36:55 +00002695static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002696s390_irgen_AHHHR(UChar r3, UChar r1, UChar r2)
2697{
2698 IRTemp op2 = newTemp(Ity_I32);
2699 IRTemp op3 = newTemp(Ity_I32);
2700 IRTemp result = newTemp(Ity_I32);
2701
2702 assign(op2, get_gpr_w0(r2));
2703 assign(op3, get_gpr_w0(r3));
2704 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2705 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
2706 put_gpr_w0(r1, mkexpr(result));
2707
2708 return "ahhhr";
2709}
2710
florian55085f82012-11-21 00:36:55 +00002711static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002712s390_irgen_AHHLR(UChar r3, UChar r1, UChar r2)
2713{
2714 IRTemp op2 = newTemp(Ity_I32);
2715 IRTemp op3 = newTemp(Ity_I32);
2716 IRTemp result = newTemp(Ity_I32);
2717
2718 assign(op2, get_gpr_w0(r2));
2719 assign(op3, get_gpr_w1(r3));
2720 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2721 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
2722 put_gpr_w0(r1, mkexpr(result));
2723
2724 return "ahhlr";
2725}
2726
florian55085f82012-11-21 00:36:55 +00002727static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002728s390_irgen_AIH(UChar r1, UInt i2)
2729{
2730 IRTemp op1 = newTemp(Ity_I32);
2731 Int op2;
2732 IRTemp result = newTemp(Ity_I32);
2733
2734 assign(op1, get_gpr_w0(r1));
2735 op2 = (Int)i2;
2736 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2737 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2738 mkU32((UInt)op2)));
2739 put_gpr_w0(r1, mkexpr(result));
2740
2741 return "aih";
2742}
2743
florian55085f82012-11-21 00:36:55 +00002744static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002745s390_irgen_ALR(UChar r1, UChar r2)
2746{
2747 IRTemp op1 = newTemp(Ity_I32);
2748 IRTemp op2 = newTemp(Ity_I32);
2749 IRTemp result = newTemp(Ity_I32);
2750
2751 assign(op1, get_gpr_w1(r1));
2752 assign(op2, get_gpr_w1(r2));
2753 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2754 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, op2);
2755 put_gpr_w1(r1, mkexpr(result));
2756
2757 return "alr";
2758}
2759
florian55085f82012-11-21 00:36:55 +00002760static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002761s390_irgen_ALGR(UChar r1, UChar r2)
2762{
2763 IRTemp op1 = newTemp(Ity_I64);
2764 IRTemp op2 = newTemp(Ity_I64);
2765 IRTemp result = newTemp(Ity_I64);
2766
2767 assign(op1, get_gpr_dw0(r1));
2768 assign(op2, get_gpr_dw0(r2));
2769 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2770 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
2771 put_gpr_dw0(r1, mkexpr(result));
2772
2773 return "algr";
2774}
2775
florian55085f82012-11-21 00:36:55 +00002776static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002777s390_irgen_ALGFR(UChar r1, UChar r2)
2778{
2779 IRTemp op1 = newTemp(Ity_I64);
2780 IRTemp op2 = newTemp(Ity_I64);
2781 IRTemp result = newTemp(Ity_I64);
2782
2783 assign(op1, get_gpr_dw0(r1));
2784 assign(op2, unop(Iop_32Uto64, get_gpr_w1(r2)));
2785 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2786 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
2787 put_gpr_dw0(r1, mkexpr(result));
2788
2789 return "algfr";
2790}
2791
florian55085f82012-11-21 00:36:55 +00002792static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002793s390_irgen_ALRK(UChar r3, UChar r1, UChar r2)
2794{
2795 IRTemp op2 = newTemp(Ity_I32);
2796 IRTemp op3 = newTemp(Ity_I32);
2797 IRTemp result = newTemp(Ity_I32);
2798
2799 assign(op2, get_gpr_w1(r2));
2800 assign(op3, get_gpr_w1(r3));
2801 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2802 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
2803 put_gpr_w1(r1, mkexpr(result));
2804
2805 return "alrk";
2806}
2807
florian55085f82012-11-21 00:36:55 +00002808static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002809s390_irgen_ALGRK(UChar r3, UChar r1, UChar r2)
2810{
2811 IRTemp op2 = newTemp(Ity_I64);
2812 IRTemp op3 = newTemp(Ity_I64);
2813 IRTemp result = newTemp(Ity_I64);
2814
2815 assign(op2, get_gpr_dw0(r2));
2816 assign(op3, get_gpr_dw0(r3));
2817 assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
2818 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op2, op3);
2819 put_gpr_dw0(r1, mkexpr(result));
2820
2821 return "algrk";
2822}
2823
florian55085f82012-11-21 00:36:55 +00002824static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002825s390_irgen_AL(UChar r1, IRTemp op2addr)
2826{
2827 IRTemp op1 = newTemp(Ity_I32);
2828 IRTemp op2 = newTemp(Ity_I32);
2829 IRTemp result = newTemp(Ity_I32);
2830
2831 assign(op1, get_gpr_w1(r1));
2832 assign(op2, load(Ity_I32, mkexpr(op2addr)));
2833 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2834 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, op2);
2835 put_gpr_w1(r1, mkexpr(result));
2836
2837 return "al";
2838}
2839
florian55085f82012-11-21 00:36:55 +00002840static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002841s390_irgen_ALY(UChar r1, IRTemp op2addr)
2842{
2843 IRTemp op1 = newTemp(Ity_I32);
2844 IRTemp op2 = newTemp(Ity_I32);
2845 IRTemp result = newTemp(Ity_I32);
2846
2847 assign(op1, get_gpr_w1(r1));
2848 assign(op2, load(Ity_I32, mkexpr(op2addr)));
2849 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2850 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, op2);
2851 put_gpr_w1(r1, mkexpr(result));
2852
2853 return "aly";
2854}
2855
florian55085f82012-11-21 00:36:55 +00002856static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002857s390_irgen_ALG(UChar r1, IRTemp op2addr)
2858{
2859 IRTemp op1 = newTemp(Ity_I64);
2860 IRTemp op2 = newTemp(Ity_I64);
2861 IRTemp result = newTemp(Ity_I64);
2862
2863 assign(op1, get_gpr_dw0(r1));
2864 assign(op2, load(Ity_I64, mkexpr(op2addr)));
2865 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2866 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
2867 put_gpr_dw0(r1, mkexpr(result));
2868
2869 return "alg";
2870}
2871
florian55085f82012-11-21 00:36:55 +00002872static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002873s390_irgen_ALGF(UChar r1, IRTemp op2addr)
2874{
2875 IRTemp op1 = newTemp(Ity_I64);
2876 IRTemp op2 = newTemp(Ity_I64);
2877 IRTemp result = newTemp(Ity_I64);
2878
2879 assign(op1, get_gpr_dw0(r1));
2880 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
2881 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2882 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
2883 put_gpr_dw0(r1, mkexpr(result));
2884
2885 return "algf";
2886}
2887
florian55085f82012-11-21 00:36:55 +00002888static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002889s390_irgen_ALFI(UChar r1, UInt i2)
2890{
2891 IRTemp op1 = newTemp(Ity_I32);
2892 UInt op2;
2893 IRTemp result = newTemp(Ity_I32);
2894
2895 assign(op1, get_gpr_w1(r1));
2896 op2 = i2;
2897 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
2898 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, mktemp(Ity_I32,
2899 mkU32(op2)));
2900 put_gpr_w1(r1, mkexpr(result));
2901
2902 return "alfi";
2903}
2904
florian55085f82012-11-21 00:36:55 +00002905static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002906s390_irgen_ALGFI(UChar r1, UInt i2)
2907{
2908 IRTemp op1 = newTemp(Ity_I64);
2909 ULong op2;
2910 IRTemp result = newTemp(Ity_I64);
2911
2912 assign(op1, get_gpr_dw0(r1));
2913 op2 = (ULong)i2;
2914 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64(op2)));
2915 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, mktemp(Ity_I64,
2916 mkU64(op2)));
2917 put_gpr_dw0(r1, mkexpr(result));
2918
2919 return "algfi";
2920}
2921
florian55085f82012-11-21 00:36:55 +00002922static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002923s390_irgen_ALHHHR(UChar r3, UChar r1, UChar r2)
2924{
2925 IRTemp op2 = newTemp(Ity_I32);
2926 IRTemp op3 = newTemp(Ity_I32);
2927 IRTemp result = newTemp(Ity_I32);
2928
2929 assign(op2, get_gpr_w0(r2));
2930 assign(op3, get_gpr_w0(r3));
2931 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2932 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
2933 put_gpr_w0(r1, mkexpr(result));
2934
2935 return "alhhhr";
2936}
2937
florian55085f82012-11-21 00:36:55 +00002938static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002939s390_irgen_ALHHLR(UChar r3, UChar r1, UChar r2)
2940{
2941 IRTemp op2 = newTemp(Ity_I32);
2942 IRTemp op3 = newTemp(Ity_I32);
2943 IRTemp result = newTemp(Ity_I32);
2944
2945 assign(op2, get_gpr_w0(r2));
2946 assign(op3, get_gpr_w1(r3));
2947 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2948 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
2949 put_gpr_w0(r1, mkexpr(result));
2950
2951 return "alhhlr";
2952}
2953
florian55085f82012-11-21 00:36:55 +00002954static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002955s390_irgen_ALCR(UChar r1, UChar r2)
2956{
2957 IRTemp op1 = newTemp(Ity_I32);
2958 IRTemp op2 = newTemp(Ity_I32);
2959 IRTemp result = newTemp(Ity_I32);
2960 IRTemp carry_in = newTemp(Ity_I32);
2961
2962 assign(op1, get_gpr_w1(r1));
2963 assign(op2, get_gpr_w1(r2));
2964 assign(carry_in, binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)));
2965 assign(result, binop(Iop_Add32, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)),
2966 mkexpr(carry_in)));
2967 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_32, op1, op2, carry_in);
2968 put_gpr_w1(r1, mkexpr(result));
2969
2970 return "alcr";
2971}
2972
florian55085f82012-11-21 00:36:55 +00002973static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002974s390_irgen_ALCGR(UChar r1, UChar r2)
2975{
2976 IRTemp op1 = newTemp(Ity_I64);
2977 IRTemp op2 = newTemp(Ity_I64);
2978 IRTemp result = newTemp(Ity_I64);
2979 IRTemp carry_in = newTemp(Ity_I64);
2980
2981 assign(op1, get_gpr_dw0(r1));
2982 assign(op2, get_gpr_dw0(r2));
2983 assign(carry_in, unop(Iop_32Uto64, binop(Iop_Shr32, s390_call_calculate_cc(),
2984 mkU8(1))));
2985 assign(result, binop(Iop_Add64, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)),
2986 mkexpr(carry_in)));
2987 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_64, op1, op2, carry_in);
2988 put_gpr_dw0(r1, mkexpr(result));
2989
2990 return "alcgr";
2991}
2992
florian55085f82012-11-21 00:36:55 +00002993static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002994s390_irgen_ALC(UChar r1, IRTemp op2addr)
2995{
2996 IRTemp op1 = newTemp(Ity_I32);
2997 IRTemp op2 = newTemp(Ity_I32);
2998 IRTemp result = newTemp(Ity_I32);
2999 IRTemp carry_in = newTemp(Ity_I32);
3000
3001 assign(op1, get_gpr_w1(r1));
3002 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3003 assign(carry_in, binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)));
3004 assign(result, binop(Iop_Add32, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)),
3005 mkexpr(carry_in)));
3006 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_32, op1, op2, carry_in);
3007 put_gpr_w1(r1, mkexpr(result));
3008
3009 return "alc";
3010}
3011
florian55085f82012-11-21 00:36:55 +00003012static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003013s390_irgen_ALCG(UChar r1, IRTemp op2addr)
3014{
3015 IRTemp op1 = newTemp(Ity_I64);
3016 IRTemp op2 = newTemp(Ity_I64);
3017 IRTemp result = newTemp(Ity_I64);
3018 IRTemp carry_in = newTemp(Ity_I64);
3019
3020 assign(op1, get_gpr_dw0(r1));
3021 assign(op2, load(Ity_I64, mkexpr(op2addr)));
3022 assign(carry_in, unop(Iop_32Uto64, binop(Iop_Shr32, s390_call_calculate_cc(),
3023 mkU8(1))));
3024 assign(result, binop(Iop_Add64, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)),
3025 mkexpr(carry_in)));
3026 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_64, op1, op2, carry_in);
3027 put_gpr_dw0(r1, mkexpr(result));
3028
3029 return "alcg";
3030}
3031
florian55085f82012-11-21 00:36:55 +00003032static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003033s390_irgen_ALSI(UChar i2, IRTemp op1addr)
3034{
3035 IRTemp op1 = newTemp(Ity_I32);
3036 UInt op2;
3037 IRTemp result = newTemp(Ity_I32);
3038
3039 assign(op1, load(Ity_I32, mkexpr(op1addr)));
3040 op2 = (UInt)(Int)(Char)i2;
3041 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
3042 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, mktemp(Ity_I32,
3043 mkU32(op2)));
3044 store(mkexpr(op1addr), mkexpr(result));
3045
3046 return "alsi";
3047}
3048
florian55085f82012-11-21 00:36:55 +00003049static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003050s390_irgen_ALGSI(UChar i2, IRTemp op1addr)
3051{
3052 IRTemp op1 = newTemp(Ity_I64);
3053 ULong op2;
3054 IRTemp result = newTemp(Ity_I64);
3055
3056 assign(op1, load(Ity_I64, mkexpr(op1addr)));
3057 op2 = (ULong)(Long)(Char)i2;
3058 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64(op2)));
3059 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, mktemp(Ity_I64,
3060 mkU64(op2)));
3061 store(mkexpr(op1addr), mkexpr(result));
3062
3063 return "algsi";
3064}
3065
florian55085f82012-11-21 00:36:55 +00003066static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003067s390_irgen_ALHSIK(UChar r1, UChar r3, UShort i2)
3068{
3069 UInt op2;
3070 IRTemp op3 = newTemp(Ity_I32);
3071 IRTemp result = newTemp(Ity_I32);
3072
3073 op2 = (UInt)(Int)(Short)i2;
3074 assign(op3, get_gpr_w1(r3));
3075 assign(result, binop(Iop_Add32, mkU32(op2), mkexpr(op3)));
3076 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, mktemp(Ity_I32, mkU32(op2)),
3077 op3);
3078 put_gpr_w1(r1, mkexpr(result));
3079
3080 return "alhsik";
3081}
3082
florian55085f82012-11-21 00:36:55 +00003083static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003084s390_irgen_ALGHSIK(UChar r1, UChar r3, UShort i2)
3085{
3086 ULong op2;
3087 IRTemp op3 = newTemp(Ity_I64);
3088 IRTemp result = newTemp(Ity_I64);
3089
3090 op2 = (ULong)(Long)(Short)i2;
3091 assign(op3, get_gpr_dw0(r3));
3092 assign(result, binop(Iop_Add64, mkU64(op2), mkexpr(op3)));
3093 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, mktemp(Ity_I64, mkU64(op2)),
3094 op3);
3095 put_gpr_dw0(r1, mkexpr(result));
3096
3097 return "alghsik";
3098}
3099
florian55085f82012-11-21 00:36:55 +00003100static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003101s390_irgen_ALSIH(UChar r1, UInt i2)
3102{
3103 IRTemp op1 = newTemp(Ity_I32);
3104 UInt op2;
3105 IRTemp result = newTemp(Ity_I32);
3106
3107 assign(op1, get_gpr_w0(r1));
3108 op2 = i2;
3109 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
3110 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, mktemp(Ity_I32,
3111 mkU32(op2)));
3112 put_gpr_w0(r1, mkexpr(result));
3113
3114 return "alsih";
3115}
3116
florian55085f82012-11-21 00:36:55 +00003117static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003118s390_irgen_ALSIHN(UChar r1, UInt i2)
3119{
3120 IRTemp op1 = newTemp(Ity_I32);
3121 UInt op2;
3122 IRTemp result = newTemp(Ity_I32);
3123
3124 assign(op1, get_gpr_w0(r1));
3125 op2 = i2;
3126 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
3127 put_gpr_w0(r1, mkexpr(result));
3128
3129 return "alsihn";
3130}
3131
florian55085f82012-11-21 00:36:55 +00003132static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003133s390_irgen_NR(UChar r1, UChar r2)
3134{
3135 IRTemp op1 = newTemp(Ity_I32);
3136 IRTemp op2 = newTemp(Ity_I32);
3137 IRTemp result = newTemp(Ity_I32);
3138
3139 assign(op1, get_gpr_w1(r1));
3140 assign(op2, get_gpr_w1(r2));
3141 assign(result, binop(Iop_And32, mkexpr(op1), mkexpr(op2)));
3142 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3143 put_gpr_w1(r1, mkexpr(result));
3144
3145 return "nr";
3146}
3147
florian55085f82012-11-21 00:36:55 +00003148static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003149s390_irgen_NGR(UChar r1, UChar r2)
3150{
3151 IRTemp op1 = newTemp(Ity_I64);
3152 IRTemp op2 = newTemp(Ity_I64);
3153 IRTemp result = newTemp(Ity_I64);
3154
3155 assign(op1, get_gpr_dw0(r1));
3156 assign(op2, get_gpr_dw0(r2));
3157 assign(result, binop(Iop_And64, mkexpr(op1), mkexpr(op2)));
3158 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3159 put_gpr_dw0(r1, mkexpr(result));
3160
3161 return "ngr";
3162}
3163
florian55085f82012-11-21 00:36:55 +00003164static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003165s390_irgen_NRK(UChar r3, UChar r1, UChar r2)
3166{
3167 IRTemp op2 = newTemp(Ity_I32);
3168 IRTemp op3 = newTemp(Ity_I32);
3169 IRTemp result = newTemp(Ity_I32);
3170
3171 assign(op2, get_gpr_w1(r2));
3172 assign(op3, get_gpr_w1(r3));
3173 assign(result, binop(Iop_And32, mkexpr(op2), mkexpr(op3)));
3174 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3175 put_gpr_w1(r1, mkexpr(result));
3176
3177 return "nrk";
3178}
3179
florian55085f82012-11-21 00:36:55 +00003180static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003181s390_irgen_NGRK(UChar r3, UChar r1, UChar r2)
3182{
3183 IRTemp op2 = newTemp(Ity_I64);
3184 IRTemp op3 = newTemp(Ity_I64);
3185 IRTemp result = newTemp(Ity_I64);
3186
3187 assign(op2, get_gpr_dw0(r2));
3188 assign(op3, get_gpr_dw0(r3));
3189 assign(result, binop(Iop_And64, mkexpr(op2), mkexpr(op3)));
3190 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3191 put_gpr_dw0(r1, mkexpr(result));
3192
3193 return "ngrk";
3194}
3195
florian55085f82012-11-21 00:36:55 +00003196static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003197s390_irgen_N(UChar r1, IRTemp op2addr)
3198{
3199 IRTemp op1 = newTemp(Ity_I32);
3200 IRTemp op2 = newTemp(Ity_I32);
3201 IRTemp result = newTemp(Ity_I32);
3202
3203 assign(op1, get_gpr_w1(r1));
3204 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3205 assign(result, binop(Iop_And32, mkexpr(op1), mkexpr(op2)));
3206 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3207 put_gpr_w1(r1, mkexpr(result));
3208
3209 return "n";
3210}
3211
florian55085f82012-11-21 00:36:55 +00003212static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003213s390_irgen_NY(UChar r1, IRTemp op2addr)
3214{
3215 IRTemp op1 = newTemp(Ity_I32);
3216 IRTemp op2 = newTemp(Ity_I32);
3217 IRTemp result = newTemp(Ity_I32);
3218
3219 assign(op1, get_gpr_w1(r1));
3220 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3221 assign(result, binop(Iop_And32, mkexpr(op1), mkexpr(op2)));
3222 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3223 put_gpr_w1(r1, mkexpr(result));
3224
3225 return "ny";
3226}
3227
florian55085f82012-11-21 00:36:55 +00003228static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003229s390_irgen_NG(UChar r1, IRTemp op2addr)
3230{
3231 IRTemp op1 = newTemp(Ity_I64);
3232 IRTemp op2 = newTemp(Ity_I64);
3233 IRTemp result = newTemp(Ity_I64);
3234
3235 assign(op1, get_gpr_dw0(r1));
3236 assign(op2, load(Ity_I64, mkexpr(op2addr)));
3237 assign(result, binop(Iop_And64, mkexpr(op1), mkexpr(op2)));
3238 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3239 put_gpr_dw0(r1, mkexpr(result));
3240
3241 return "ng";
3242}
3243
florian55085f82012-11-21 00:36:55 +00003244static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003245s390_irgen_NI(UChar i2, IRTemp op1addr)
3246{
3247 IRTemp op1 = newTemp(Ity_I8);
3248 UChar op2;
3249 IRTemp result = newTemp(Ity_I8);
3250
3251 assign(op1, load(Ity_I8, mkexpr(op1addr)));
3252 op2 = i2;
3253 assign(result, binop(Iop_And8, mkexpr(op1), mkU8(op2)));
3254 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3255 store(mkexpr(op1addr), mkexpr(result));
3256
3257 return "ni";
3258}
3259
florian55085f82012-11-21 00:36:55 +00003260static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003261s390_irgen_NIY(UChar i2, IRTemp op1addr)
3262{
3263 IRTemp op1 = newTemp(Ity_I8);
3264 UChar op2;
3265 IRTemp result = newTemp(Ity_I8);
3266
3267 assign(op1, load(Ity_I8, mkexpr(op1addr)));
3268 op2 = i2;
3269 assign(result, binop(Iop_And8, mkexpr(op1), mkU8(op2)));
3270 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3271 store(mkexpr(op1addr), mkexpr(result));
3272
3273 return "niy";
3274}
3275
florian55085f82012-11-21 00:36:55 +00003276static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003277s390_irgen_NIHF(UChar r1, UInt i2)
3278{
3279 IRTemp op1 = newTemp(Ity_I32);
3280 UInt op2;
3281 IRTemp result = newTemp(Ity_I32);
3282
3283 assign(op1, get_gpr_w0(r1));
3284 op2 = i2;
3285 assign(result, binop(Iop_And32, mkexpr(op1), mkU32(op2)));
3286 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3287 put_gpr_w0(r1, mkexpr(result));
3288
3289 return "nihf";
3290}
3291
florian55085f82012-11-21 00:36:55 +00003292static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003293s390_irgen_NIHH(UChar r1, UShort i2)
3294{
3295 IRTemp op1 = newTemp(Ity_I16);
3296 UShort op2;
3297 IRTemp result = newTemp(Ity_I16);
3298
3299 assign(op1, get_gpr_hw0(r1));
3300 op2 = i2;
3301 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3302 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3303 put_gpr_hw0(r1, mkexpr(result));
3304
3305 return "nihh";
3306}
3307
florian55085f82012-11-21 00:36:55 +00003308static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003309s390_irgen_NIHL(UChar r1, UShort i2)
3310{
3311 IRTemp op1 = newTemp(Ity_I16);
3312 UShort op2;
3313 IRTemp result = newTemp(Ity_I16);
3314
3315 assign(op1, get_gpr_hw1(r1));
3316 op2 = i2;
3317 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3318 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3319 put_gpr_hw1(r1, mkexpr(result));
3320
3321 return "nihl";
3322}
3323
florian55085f82012-11-21 00:36:55 +00003324static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003325s390_irgen_NILF(UChar r1, UInt i2)
3326{
3327 IRTemp op1 = newTemp(Ity_I32);
3328 UInt op2;
3329 IRTemp result = newTemp(Ity_I32);
3330
3331 assign(op1, get_gpr_w1(r1));
3332 op2 = i2;
3333 assign(result, binop(Iop_And32, mkexpr(op1), mkU32(op2)));
3334 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3335 put_gpr_w1(r1, mkexpr(result));
3336
3337 return "nilf";
3338}
3339
florian55085f82012-11-21 00:36:55 +00003340static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003341s390_irgen_NILH(UChar r1, UShort i2)
3342{
3343 IRTemp op1 = newTemp(Ity_I16);
3344 UShort op2;
3345 IRTemp result = newTemp(Ity_I16);
3346
3347 assign(op1, get_gpr_hw2(r1));
3348 op2 = i2;
3349 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3350 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3351 put_gpr_hw2(r1, mkexpr(result));
3352
3353 return "nilh";
3354}
3355
florian55085f82012-11-21 00:36:55 +00003356static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003357s390_irgen_NILL(UChar r1, UShort i2)
3358{
3359 IRTemp op1 = newTemp(Ity_I16);
3360 UShort op2;
3361 IRTemp result = newTemp(Ity_I16);
3362
3363 assign(op1, get_gpr_hw3(r1));
3364 op2 = i2;
3365 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3366 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3367 put_gpr_hw3(r1, mkexpr(result));
3368
3369 return "nill";
3370}
3371
florian55085f82012-11-21 00:36:55 +00003372static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003373s390_irgen_BASR(UChar r1, UChar r2)
3374{
3375 IRTemp target = newTemp(Ity_I64);
3376
3377 if (r2 == 0) {
3378 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 2ULL));
3379 } else {
3380 if (r1 != r2) {
3381 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 2ULL));
3382 call_function(get_gpr_dw0(r2));
3383 } else {
3384 assign(target, get_gpr_dw0(r2));
3385 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 2ULL));
3386 call_function(mkexpr(target));
3387 }
3388 }
3389
3390 return "basr";
3391}
3392
florian55085f82012-11-21 00:36:55 +00003393static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003394s390_irgen_BAS(UChar r1, IRTemp op2addr)
3395{
3396 IRTemp target = newTemp(Ity_I64);
3397
3398 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 4ULL));
3399 assign(target, mkexpr(op2addr));
3400 call_function(mkexpr(target));
3401
3402 return "bas";
3403}
3404
florian55085f82012-11-21 00:36:55 +00003405static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003406s390_irgen_BCR(UChar r1, UChar r2)
3407{
3408 IRTemp cond = newTemp(Ity_I32);
3409
sewardja52e37e2011-04-28 18:48:06 +00003410 if (r2 == 0 && (r1 >= 14)) { /* serialization */
3411 stmt(IRStmt_MBE(Imbe_Fence));
3412 }
3413
sewardj2019a972011-03-07 16:04:07 +00003414 if ((r2 == 0) || (r1 == 0)) {
3415 } else {
3416 if (r1 == 15) {
3417 return_from_function(get_gpr_dw0(r2));
3418 } else {
3419 assign(cond, s390_call_calculate_cond(r1));
florianf321da72012-07-21 20:32:57 +00003420 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3421 get_gpr_dw0(r2));
sewardj2019a972011-03-07 16:04:07 +00003422 }
3423 }
sewardj7ee97522011-05-09 21:45:04 +00003424 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003425 s390_disasm(ENC2(XMNM, GPR), S390_XMNM_BCR, r1, r2);
3426
3427 return "bcr";
3428}
3429
florian55085f82012-11-21 00:36:55 +00003430static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003431s390_irgen_BC(UChar r1, UChar x2, UChar b2, UShort d2, IRTemp op2addr)
3432{
3433 IRTemp cond = newTemp(Ity_I32);
3434
3435 if (r1 == 0) {
3436 } else {
3437 if (r1 == 15) {
3438 always_goto(mkexpr(op2addr));
3439 } else {
3440 assign(cond, s390_call_calculate_cond(r1));
florianf321da72012-07-21 20:32:57 +00003441 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3442 mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003443 }
3444 }
sewardj7ee97522011-05-09 21:45:04 +00003445 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003446 s390_disasm(ENC2(XMNM, UDXB), S390_XMNM_BC, r1, d2, x2, b2);
3447
3448 return "bc";
3449}
3450
florian55085f82012-11-21 00:36:55 +00003451static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003452s390_irgen_BCTR(UChar r1, UChar r2)
3453{
3454 put_gpr_w1(r1, binop(Iop_Sub32, get_gpr_w1(r1), mkU32(1)));
3455 if (r2 != 0) {
florianf321da72012-07-21 20:32:57 +00003456 if_condition_goto_computed(binop(Iop_CmpNE32, get_gpr_w1(r1), mkU32(0)),
3457 get_gpr_dw0(r2));
sewardj2019a972011-03-07 16:04:07 +00003458 }
3459
3460 return "bctr";
3461}
3462
florian55085f82012-11-21 00:36:55 +00003463static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003464s390_irgen_BCTGR(UChar r1, UChar r2)
3465{
3466 put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1)));
3467 if (r2 != 0) {
florianf321da72012-07-21 20:32:57 +00003468 if_condition_goto_computed(binop(Iop_CmpNE64, get_gpr_dw0(r1), mkU64(0)),
3469 get_gpr_dw0(r2));
sewardj2019a972011-03-07 16:04:07 +00003470 }
3471
3472 return "bctgr";
3473}
3474
florian55085f82012-11-21 00:36:55 +00003475static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003476s390_irgen_BCT(UChar r1, IRTemp op2addr)
3477{
3478 put_gpr_w1(r1, binop(Iop_Sub32, get_gpr_w1(r1), mkU32(1)));
florianf321da72012-07-21 20:32:57 +00003479 if_condition_goto_computed(binop(Iop_CmpNE32, get_gpr_w1(r1), mkU32(0)),
3480 mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003481
3482 return "bct";
3483}
3484
florian55085f82012-11-21 00:36:55 +00003485static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003486s390_irgen_BCTG(UChar r1, IRTemp op2addr)
3487{
3488 put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1)));
florianf321da72012-07-21 20:32:57 +00003489 if_condition_goto_computed(binop(Iop_CmpNE64, get_gpr_dw0(r1), mkU64(0)),
3490 mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003491
3492 return "bctg";
3493}
3494
florian55085f82012-11-21 00:36:55 +00003495static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003496s390_irgen_BXH(UChar r1, UChar r3, IRTemp op2addr)
3497{
3498 IRTemp value = newTemp(Ity_I32);
3499
3500 assign(value, get_gpr_w1(r3 | 1));
3501 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
florianf321da72012-07-21 20:32:57 +00003502 if_condition_goto_computed(binop(Iop_CmpLT32S, mkexpr(value),
3503 get_gpr_w1(r1)), mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003504
3505 return "bxh";
3506}
3507
florian55085f82012-11-21 00:36:55 +00003508static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003509s390_irgen_BXHG(UChar r1, UChar r3, IRTemp op2addr)
3510{
3511 IRTemp value = newTemp(Ity_I64);
3512
3513 assign(value, get_gpr_dw0(r3 | 1));
3514 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
florianf321da72012-07-21 20:32:57 +00003515 if_condition_goto_computed(binop(Iop_CmpLT64S, mkexpr(value),
3516 get_gpr_dw0(r1)), mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003517
3518 return "bxhg";
3519}
3520
florian55085f82012-11-21 00:36:55 +00003521static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003522s390_irgen_BXLE(UChar r1, UChar r3, IRTemp op2addr)
3523{
3524 IRTemp value = newTemp(Ity_I32);
3525
3526 assign(value, get_gpr_w1(r3 | 1));
3527 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
florianf321da72012-07-21 20:32:57 +00003528 if_condition_goto_computed(binop(Iop_CmpLE32S, get_gpr_w1(r1),
3529 mkexpr(value)), mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003530
3531 return "bxle";
3532}
3533
florian55085f82012-11-21 00:36:55 +00003534static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003535s390_irgen_BXLEG(UChar r1, UChar r3, IRTemp op2addr)
3536{
3537 IRTemp value = newTemp(Ity_I64);
3538
3539 assign(value, get_gpr_dw0(r3 | 1));
3540 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
florianf321da72012-07-21 20:32:57 +00003541 if_condition_goto_computed(binop(Iop_CmpLE64S, get_gpr_dw0(r1),
3542 mkexpr(value)), mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003543
3544 return "bxleg";
3545}
3546
florian55085f82012-11-21 00:36:55 +00003547static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003548s390_irgen_BRAS(UChar r1, UShort i2)
3549{
3550 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 4ULL));
floriana64c2432011-07-16 02:11:50 +00003551 call_function_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003552
3553 return "bras";
3554}
3555
florian55085f82012-11-21 00:36:55 +00003556static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003557s390_irgen_BRASL(UChar r1, UInt i2)
3558{
3559 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 6ULL));
floriana64c2432011-07-16 02:11:50 +00003560 call_function_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003561
3562 return "brasl";
3563}
3564
florian55085f82012-11-21 00:36:55 +00003565static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003566s390_irgen_BRC(UChar r1, UShort i2)
3567{
3568 IRTemp cond = newTemp(Ity_I32);
3569
3570 if (r1 == 0) {
3571 } else {
3572 if (r1 == 15) {
floriana64c2432011-07-16 02:11:50 +00003573 always_goto_and_chase(
3574 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003575 } else {
3576 assign(cond, s390_call_calculate_cond(r1));
3577 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3578 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3579
3580 }
3581 }
sewardj7ee97522011-05-09 21:45:04 +00003582 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003583 s390_disasm(ENC2(XMNM, PCREL), S390_XMNM_BRC, r1, (Int)(Short)i2);
3584
3585 return "brc";
3586}
3587
florian55085f82012-11-21 00:36:55 +00003588static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003589s390_irgen_BRCL(UChar r1, UInt i2)
3590{
3591 IRTemp cond = newTemp(Ity_I32);
3592
3593 if (r1 == 0) {
3594 } else {
3595 if (r1 == 15) {
floriana64c2432011-07-16 02:11:50 +00003596 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003597 } else {
3598 assign(cond, s390_call_calculate_cond(r1));
3599 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3600 guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1));
3601 }
3602 }
sewardj7ee97522011-05-09 21:45:04 +00003603 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003604 s390_disasm(ENC2(XMNM, PCREL), S390_XMNM_BRCL, r1, i2);
3605
3606 return "brcl";
3607}
3608
florian55085f82012-11-21 00:36:55 +00003609static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003610s390_irgen_BRCT(UChar r1, UShort i2)
3611{
3612 put_gpr_w1(r1, binop(Iop_Sub32, get_gpr_w1(r1), mkU32(1)));
3613 if_condition_goto(binop(Iop_CmpNE32, get_gpr_w1(r1), mkU32(0)),
3614 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3615
3616 return "brct";
3617}
3618
florian55085f82012-11-21 00:36:55 +00003619static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003620s390_irgen_BRCTG(UChar r1, UShort i2)
3621{
3622 put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1)));
3623 if_condition_goto(binop(Iop_CmpNE64, get_gpr_dw0(r1), mkU64(0)),
3624 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3625
3626 return "brctg";
3627}
3628
florian55085f82012-11-21 00:36:55 +00003629static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003630s390_irgen_BRXH(UChar r1, UChar r3, UShort i2)
3631{
3632 IRTemp value = newTemp(Ity_I32);
3633
3634 assign(value, get_gpr_w1(r3 | 1));
3635 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
3636 if_condition_goto(binop(Iop_CmpLT32S, mkexpr(value), get_gpr_w1(r1)),
3637 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3638
3639 return "brxh";
3640}
3641
florian55085f82012-11-21 00:36:55 +00003642static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003643s390_irgen_BRXHG(UChar r1, UChar r3, UShort i2)
3644{
3645 IRTemp value = newTemp(Ity_I64);
3646
3647 assign(value, get_gpr_dw0(r3 | 1));
3648 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
3649 if_condition_goto(binop(Iop_CmpLT64S, mkexpr(value), get_gpr_dw0(r1)),
3650 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3651
3652 return "brxhg";
3653}
3654
florian55085f82012-11-21 00:36:55 +00003655static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003656s390_irgen_BRXLE(UChar r1, UChar r3, UShort i2)
3657{
3658 IRTemp value = newTemp(Ity_I32);
3659
3660 assign(value, get_gpr_w1(r3 | 1));
3661 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
3662 if_condition_goto(binop(Iop_CmpLE32S, get_gpr_w1(r1), mkexpr(value)),
3663 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3664
3665 return "brxle";
3666}
3667
florian55085f82012-11-21 00:36:55 +00003668static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003669s390_irgen_BRXLG(UChar r1, UChar r3, UShort i2)
3670{
3671 IRTemp value = newTemp(Ity_I64);
3672
3673 assign(value, get_gpr_dw0(r3 | 1));
3674 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
3675 if_condition_goto(binop(Iop_CmpLE64S, get_gpr_dw0(r1), mkexpr(value)),
3676 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3677
3678 return "brxlg";
3679}
3680
florian55085f82012-11-21 00:36:55 +00003681static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003682s390_irgen_CR(UChar r1, UChar r2)
3683{
3684 IRTemp op1 = newTemp(Ity_I32);
3685 IRTemp op2 = newTemp(Ity_I32);
3686
3687 assign(op1, get_gpr_w1(r1));
3688 assign(op2, get_gpr_w1(r2));
3689 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3690
3691 return "cr";
3692}
3693
florian55085f82012-11-21 00:36:55 +00003694static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003695s390_irgen_CGR(UChar r1, UChar r2)
3696{
3697 IRTemp op1 = newTemp(Ity_I64);
3698 IRTemp op2 = newTemp(Ity_I64);
3699
3700 assign(op1, get_gpr_dw0(r1));
3701 assign(op2, get_gpr_dw0(r2));
3702 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3703
3704 return "cgr";
3705}
3706
florian55085f82012-11-21 00:36:55 +00003707static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003708s390_irgen_CGFR(UChar r1, UChar r2)
3709{
3710 IRTemp op1 = newTemp(Ity_I64);
3711 IRTemp op2 = newTemp(Ity_I64);
3712
3713 assign(op1, get_gpr_dw0(r1));
3714 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
3715 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3716
3717 return "cgfr";
3718}
3719
florian55085f82012-11-21 00:36:55 +00003720static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003721s390_irgen_C(UChar r1, IRTemp op2addr)
3722{
3723 IRTemp op1 = newTemp(Ity_I32);
3724 IRTemp op2 = newTemp(Ity_I32);
3725
3726 assign(op1, get_gpr_w1(r1));
3727 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3728 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3729
3730 return "c";
3731}
3732
florian55085f82012-11-21 00:36:55 +00003733static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003734s390_irgen_CY(UChar r1, IRTemp op2addr)
3735{
3736 IRTemp op1 = newTemp(Ity_I32);
3737 IRTemp op2 = newTemp(Ity_I32);
3738
3739 assign(op1, get_gpr_w1(r1));
3740 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3741 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3742
3743 return "cy";
3744}
3745
florian55085f82012-11-21 00:36:55 +00003746static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003747s390_irgen_CG(UChar r1, IRTemp op2addr)
3748{
3749 IRTemp op1 = newTemp(Ity_I64);
3750 IRTemp op2 = newTemp(Ity_I64);
3751
3752 assign(op1, get_gpr_dw0(r1));
3753 assign(op2, load(Ity_I64, mkexpr(op2addr)));
3754 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3755
3756 return "cg";
3757}
3758
florian55085f82012-11-21 00:36:55 +00003759static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003760s390_irgen_CGF(UChar r1, IRTemp op2addr)
3761{
3762 IRTemp op1 = newTemp(Ity_I64);
3763 IRTemp op2 = newTemp(Ity_I64);
3764
3765 assign(op1, get_gpr_dw0(r1));
3766 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
3767 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3768
3769 return "cgf";
3770}
3771
florian55085f82012-11-21 00:36:55 +00003772static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003773s390_irgen_CFI(UChar r1, UInt i2)
3774{
3775 IRTemp op1 = newTemp(Ity_I32);
3776 Int op2;
3777
3778 assign(op1, get_gpr_w1(r1));
3779 op2 = (Int)i2;
3780 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
3781 mkU32((UInt)op2)));
3782
3783 return "cfi";
3784}
3785
florian55085f82012-11-21 00:36:55 +00003786static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003787s390_irgen_CGFI(UChar r1, UInt i2)
3788{
3789 IRTemp op1 = newTemp(Ity_I64);
3790 Long op2;
3791
3792 assign(op1, get_gpr_dw0(r1));
3793 op2 = (Long)(Int)i2;
3794 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
3795 mkU64((ULong)op2)));
3796
3797 return "cgfi";
3798}
3799
florian55085f82012-11-21 00:36:55 +00003800static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003801s390_irgen_CRL(UChar r1, UInt i2)
3802{
3803 IRTemp op1 = newTemp(Ity_I32);
3804 IRTemp op2 = newTemp(Ity_I32);
3805
3806 assign(op1, get_gpr_w1(r1));
3807 assign(op2, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
3808 i2 << 1))));
3809 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3810
3811 return "crl";
3812}
3813
florian55085f82012-11-21 00:36:55 +00003814static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003815s390_irgen_CGRL(UChar r1, UInt i2)
3816{
3817 IRTemp op1 = newTemp(Ity_I64);
3818 IRTemp op2 = newTemp(Ity_I64);
3819
3820 assign(op1, get_gpr_dw0(r1));
3821 assign(op2, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
3822 i2 << 1))));
3823 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3824
3825 return "cgrl";
3826}
3827
florian55085f82012-11-21 00:36:55 +00003828static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003829s390_irgen_CGFRL(UChar r1, UInt i2)
3830{
3831 IRTemp op1 = newTemp(Ity_I64);
3832 IRTemp op2 = newTemp(Ity_I64);
3833
3834 assign(op1, get_gpr_dw0(r1));
3835 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
3836 ((ULong)(Long)(Int)i2 << 1)))));
3837 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3838
3839 return "cgfrl";
3840}
3841
florian55085f82012-11-21 00:36:55 +00003842static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003843s390_irgen_CRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
3844{
3845 IRTemp op1 = newTemp(Ity_I32);
3846 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00003847 IRTemp cond = newTemp(Ity_I32);
3848
3849 if (m3 == 0) {
3850 } else {
3851 if (m3 == 14) {
3852 always_goto(mkexpr(op4addr));
3853 } else {
3854 assign(op1, get_gpr_w1(r1));
3855 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00003856 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
3857 op1, op2));
florianf321da72012-07-21 20:32:57 +00003858 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond),
3859 mkU32(0)), mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00003860 }
3861 }
3862
3863 return "crb";
3864}
3865
florian55085f82012-11-21 00:36:55 +00003866static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003867s390_irgen_CGRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
3868{
3869 IRTemp op1 = newTemp(Ity_I64);
3870 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00003871 IRTemp cond = newTemp(Ity_I32);
3872
3873 if (m3 == 0) {
3874 } else {
3875 if (m3 == 14) {
3876 always_goto(mkexpr(op4addr));
3877 } else {
3878 assign(op1, get_gpr_dw0(r1));
3879 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00003880 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
3881 op1, op2));
florianf321da72012-07-21 20:32:57 +00003882 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond),
3883 mkU32(0)), mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00003884 }
3885 }
3886
3887 return "cgrb";
3888}
3889
florian55085f82012-11-21 00:36:55 +00003890static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003891s390_irgen_CRJ(UChar r1, UChar r2, UShort i4, UChar m3)
3892{
3893 IRTemp op1 = newTemp(Ity_I32);
3894 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00003895 IRTemp cond = newTemp(Ity_I32);
3896
3897 if (m3 == 0) {
3898 } else {
3899 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00003900 always_goto_and_chase(
3901 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00003902 } else {
3903 assign(op1, get_gpr_w1(r1));
3904 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00003905 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
3906 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00003907 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3908 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
3909
3910 }
3911 }
3912
3913 return "crj";
3914}
3915
florian55085f82012-11-21 00:36:55 +00003916static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003917s390_irgen_CGRJ(UChar r1, UChar r2, UShort i4, UChar m3)
3918{
3919 IRTemp op1 = newTemp(Ity_I64);
3920 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00003921 IRTemp cond = newTemp(Ity_I32);
3922
3923 if (m3 == 0) {
3924 } else {
3925 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00003926 always_goto_and_chase(
3927 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00003928 } else {
3929 assign(op1, get_gpr_dw0(r1));
3930 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00003931 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
3932 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00003933 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3934 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
3935
3936 }
3937 }
3938
3939 return "cgrj";
3940}
3941
florian55085f82012-11-21 00:36:55 +00003942static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003943s390_irgen_CIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
3944{
3945 IRTemp op1 = newTemp(Ity_I32);
3946 Int op2;
sewardj2019a972011-03-07 16:04:07 +00003947 IRTemp cond = newTemp(Ity_I32);
3948
3949 if (m3 == 0) {
3950 } else {
3951 if (m3 == 14) {
3952 always_goto(mkexpr(op4addr));
3953 } else {
3954 assign(op1, get_gpr_w1(r1));
3955 op2 = (Int)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00003956 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
3957 mktemp(Ity_I32, mkU32((UInt)op2))));
florianf321da72012-07-21 20:32:57 +00003958 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3959 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00003960 }
3961 }
3962
3963 return "cib";
3964}
3965
florian55085f82012-11-21 00:36:55 +00003966static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003967s390_irgen_CGIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
3968{
3969 IRTemp op1 = newTemp(Ity_I64);
3970 Long op2;
sewardj2019a972011-03-07 16:04:07 +00003971 IRTemp cond = newTemp(Ity_I32);
3972
3973 if (m3 == 0) {
3974 } else {
3975 if (m3 == 14) {
3976 always_goto(mkexpr(op4addr));
3977 } else {
3978 assign(op1, get_gpr_dw0(r1));
3979 op2 = (Long)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00003980 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
3981 mktemp(Ity_I64, mkU64((ULong)op2))));
florianf321da72012-07-21 20:32:57 +00003982 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3983 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00003984 }
3985 }
3986
3987 return "cgib";
3988}
3989
florian55085f82012-11-21 00:36:55 +00003990static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003991s390_irgen_CIJ(UChar r1, UChar m3, UShort i4, UChar i2)
3992{
3993 IRTemp op1 = newTemp(Ity_I32);
3994 Int op2;
sewardj2019a972011-03-07 16:04:07 +00003995 IRTemp cond = newTemp(Ity_I32);
3996
3997 if (m3 == 0) {
3998 } else {
3999 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004000 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004001 } else {
4002 assign(op1, get_gpr_w1(r1));
4003 op2 = (Int)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00004004 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
4005 mktemp(Ity_I32, mkU32((UInt)op2))));
sewardj2019a972011-03-07 16:04:07 +00004006 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4007 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4008
4009 }
4010 }
4011
4012 return "cij";
4013}
4014
florian55085f82012-11-21 00:36:55 +00004015static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004016s390_irgen_CGIJ(UChar r1, UChar m3, UShort i4, UChar i2)
4017{
4018 IRTemp op1 = newTemp(Ity_I64);
4019 Long op2;
sewardj2019a972011-03-07 16:04:07 +00004020 IRTemp cond = newTemp(Ity_I32);
4021
4022 if (m3 == 0) {
4023 } else {
4024 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004025 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004026 } else {
4027 assign(op1, get_gpr_dw0(r1));
4028 op2 = (Long)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00004029 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
4030 mktemp(Ity_I64, mkU64((ULong)op2))));
sewardj2019a972011-03-07 16:04:07 +00004031 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4032 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4033
4034 }
4035 }
4036
4037 return "cgij";
4038}
4039
florian55085f82012-11-21 00:36:55 +00004040static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004041s390_irgen_CH(UChar r1, IRTemp op2addr)
4042{
4043 IRTemp op1 = newTemp(Ity_I32);
4044 IRTemp op2 = newTemp(Ity_I32);
4045
4046 assign(op1, get_gpr_w1(r1));
4047 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
4048 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4049
4050 return "ch";
4051}
4052
florian55085f82012-11-21 00:36:55 +00004053static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004054s390_irgen_CHY(UChar r1, IRTemp op2addr)
4055{
4056 IRTemp op1 = newTemp(Ity_I32);
4057 IRTemp op2 = newTemp(Ity_I32);
4058
4059 assign(op1, get_gpr_w1(r1));
4060 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
4061 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4062
4063 return "chy";
4064}
4065
florian55085f82012-11-21 00:36:55 +00004066static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004067s390_irgen_CGH(UChar r1, IRTemp op2addr)
4068{
4069 IRTemp op1 = newTemp(Ity_I64);
4070 IRTemp op2 = newTemp(Ity_I64);
4071
4072 assign(op1, get_gpr_dw0(r1));
4073 assign(op2, unop(Iop_16Sto64, load(Ity_I16, mkexpr(op2addr))));
4074 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4075
4076 return "cgh";
4077}
4078
florian55085f82012-11-21 00:36:55 +00004079static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004080s390_irgen_CHI(UChar r1, UShort i2)
4081{
4082 IRTemp op1 = newTemp(Ity_I32);
4083 Int op2;
4084
4085 assign(op1, get_gpr_w1(r1));
4086 op2 = (Int)(Short)i2;
4087 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
4088 mkU32((UInt)op2)));
4089
4090 return "chi";
4091}
4092
florian55085f82012-11-21 00:36:55 +00004093static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004094s390_irgen_CGHI(UChar r1, UShort i2)
4095{
4096 IRTemp op1 = newTemp(Ity_I64);
4097 Long op2;
4098
4099 assign(op1, get_gpr_dw0(r1));
4100 op2 = (Long)(Short)i2;
4101 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
4102 mkU64((ULong)op2)));
4103
4104 return "cghi";
4105}
4106
florian55085f82012-11-21 00:36:55 +00004107static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004108s390_irgen_CHHSI(UShort i2, IRTemp op1addr)
4109{
4110 IRTemp op1 = newTemp(Ity_I16);
4111 Short op2;
4112
4113 assign(op1, load(Ity_I16, mkexpr(op1addr)));
4114 op2 = (Short)i2;
4115 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I16,
4116 mkU16((UShort)op2)));
4117
4118 return "chhsi";
4119}
4120
florian55085f82012-11-21 00:36:55 +00004121static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004122s390_irgen_CHSI(UShort i2, IRTemp op1addr)
4123{
4124 IRTemp op1 = newTemp(Ity_I32);
4125 Int op2;
4126
4127 assign(op1, load(Ity_I32, mkexpr(op1addr)));
4128 op2 = (Int)(Short)i2;
4129 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
4130 mkU32((UInt)op2)));
4131
4132 return "chsi";
4133}
4134
florian55085f82012-11-21 00:36:55 +00004135static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004136s390_irgen_CGHSI(UShort i2, IRTemp op1addr)
4137{
4138 IRTemp op1 = newTemp(Ity_I64);
4139 Long op2;
4140
4141 assign(op1, load(Ity_I64, mkexpr(op1addr)));
4142 op2 = (Long)(Short)i2;
4143 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
4144 mkU64((ULong)op2)));
4145
4146 return "cghsi";
4147}
4148
florian55085f82012-11-21 00:36:55 +00004149static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004150s390_irgen_CHRL(UChar r1, UInt i2)
4151{
4152 IRTemp op1 = newTemp(Ity_I32);
4153 IRTemp op2 = newTemp(Ity_I32);
4154
4155 assign(op1, get_gpr_w1(r1));
4156 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
4157 ((ULong)(Long)(Int)i2 << 1)))));
4158 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4159
4160 return "chrl";
4161}
4162
florian55085f82012-11-21 00:36:55 +00004163static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004164s390_irgen_CGHRL(UChar r1, UInt i2)
4165{
4166 IRTemp op1 = newTemp(Ity_I64);
4167 IRTemp op2 = newTemp(Ity_I64);
4168
4169 assign(op1, get_gpr_dw0(r1));
4170 assign(op2, unop(Iop_16Sto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
4171 ((ULong)(Long)(Int)i2 << 1)))));
4172 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4173
4174 return "cghrl";
4175}
4176
florian55085f82012-11-21 00:36:55 +00004177static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004178s390_irgen_CHHR(UChar r1, UChar r2)
4179{
4180 IRTemp op1 = newTemp(Ity_I32);
4181 IRTemp op2 = newTemp(Ity_I32);
4182
4183 assign(op1, get_gpr_w0(r1));
4184 assign(op2, get_gpr_w0(r2));
4185 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4186
4187 return "chhr";
4188}
4189
florian55085f82012-11-21 00:36:55 +00004190static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004191s390_irgen_CHLR(UChar r1, UChar r2)
4192{
4193 IRTemp op1 = newTemp(Ity_I32);
4194 IRTemp op2 = newTemp(Ity_I32);
4195
4196 assign(op1, get_gpr_w0(r1));
4197 assign(op2, get_gpr_w1(r2));
4198 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4199
4200 return "chlr";
4201}
4202
florian55085f82012-11-21 00:36:55 +00004203static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004204s390_irgen_CHF(UChar r1, IRTemp op2addr)
4205{
4206 IRTemp op1 = newTemp(Ity_I32);
4207 IRTemp op2 = newTemp(Ity_I32);
4208
4209 assign(op1, get_gpr_w0(r1));
4210 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4211 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4212
4213 return "chf";
4214}
4215
florian55085f82012-11-21 00:36:55 +00004216static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004217s390_irgen_CIH(UChar r1, UInt i2)
4218{
4219 IRTemp op1 = newTemp(Ity_I32);
4220 Int op2;
4221
4222 assign(op1, get_gpr_w0(r1));
4223 op2 = (Int)i2;
4224 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
4225 mkU32((UInt)op2)));
4226
4227 return "cih";
4228}
4229
florian55085f82012-11-21 00:36:55 +00004230static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004231s390_irgen_CLR(UChar r1, UChar r2)
4232{
4233 IRTemp op1 = newTemp(Ity_I32);
4234 IRTemp op2 = newTemp(Ity_I32);
4235
4236 assign(op1, get_gpr_w1(r1));
4237 assign(op2, get_gpr_w1(r2));
4238 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4239
4240 return "clr";
4241}
4242
florian55085f82012-11-21 00:36:55 +00004243static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004244s390_irgen_CLGR(UChar r1, UChar r2)
4245{
4246 IRTemp op1 = newTemp(Ity_I64);
4247 IRTemp op2 = newTemp(Ity_I64);
4248
4249 assign(op1, get_gpr_dw0(r1));
4250 assign(op2, get_gpr_dw0(r2));
4251 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4252
4253 return "clgr";
4254}
4255
florian55085f82012-11-21 00:36:55 +00004256static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004257s390_irgen_CLGFR(UChar r1, UChar r2)
4258{
4259 IRTemp op1 = newTemp(Ity_I64);
4260 IRTemp op2 = newTemp(Ity_I64);
4261
4262 assign(op1, get_gpr_dw0(r1));
4263 assign(op2, unop(Iop_32Uto64, get_gpr_w1(r2)));
4264 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4265
4266 return "clgfr";
4267}
4268
florian55085f82012-11-21 00:36:55 +00004269static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004270s390_irgen_CL(UChar r1, IRTemp op2addr)
4271{
4272 IRTemp op1 = newTemp(Ity_I32);
4273 IRTemp op2 = newTemp(Ity_I32);
4274
4275 assign(op1, get_gpr_w1(r1));
4276 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4277 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4278
4279 return "cl";
4280}
4281
florian55085f82012-11-21 00:36:55 +00004282static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004283s390_irgen_CLY(UChar r1, IRTemp op2addr)
4284{
4285 IRTemp op1 = newTemp(Ity_I32);
4286 IRTemp op2 = newTemp(Ity_I32);
4287
4288 assign(op1, get_gpr_w1(r1));
4289 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4290 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4291
4292 return "cly";
4293}
4294
florian55085f82012-11-21 00:36:55 +00004295static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004296s390_irgen_CLG(UChar r1, IRTemp op2addr)
4297{
4298 IRTemp op1 = newTemp(Ity_I64);
4299 IRTemp op2 = newTemp(Ity_I64);
4300
4301 assign(op1, get_gpr_dw0(r1));
4302 assign(op2, load(Ity_I64, mkexpr(op2addr)));
4303 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4304
4305 return "clg";
4306}
4307
florian55085f82012-11-21 00:36:55 +00004308static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004309s390_irgen_CLGF(UChar r1, IRTemp op2addr)
4310{
4311 IRTemp op1 = newTemp(Ity_I64);
4312 IRTemp op2 = newTemp(Ity_I64);
4313
4314 assign(op1, get_gpr_dw0(r1));
4315 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
4316 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4317
4318 return "clgf";
4319}
4320
florian55085f82012-11-21 00:36:55 +00004321static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004322s390_irgen_CLFI(UChar r1, UInt i2)
4323{
4324 IRTemp op1 = newTemp(Ity_I32);
4325 UInt op2;
4326
4327 assign(op1, get_gpr_w1(r1));
4328 op2 = i2;
4329 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
4330 mkU32(op2)));
4331
4332 return "clfi";
4333}
4334
florian55085f82012-11-21 00:36:55 +00004335static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004336s390_irgen_CLGFI(UChar r1, UInt i2)
4337{
4338 IRTemp op1 = newTemp(Ity_I64);
4339 ULong op2;
4340
4341 assign(op1, get_gpr_dw0(r1));
4342 op2 = (ULong)i2;
4343 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I64,
4344 mkU64(op2)));
4345
4346 return "clgfi";
4347}
4348
florian55085f82012-11-21 00:36:55 +00004349static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004350s390_irgen_CLI(UChar i2, IRTemp op1addr)
4351{
4352 IRTemp op1 = newTemp(Ity_I8);
4353 UChar op2;
4354
4355 assign(op1, load(Ity_I8, mkexpr(op1addr)));
4356 op2 = i2;
4357 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I8,
4358 mkU8(op2)));
4359
4360 return "cli";
4361}
4362
florian55085f82012-11-21 00:36:55 +00004363static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004364s390_irgen_CLIY(UChar i2, IRTemp op1addr)
4365{
4366 IRTemp op1 = newTemp(Ity_I8);
4367 UChar op2;
4368
4369 assign(op1, load(Ity_I8, mkexpr(op1addr)));
4370 op2 = i2;
4371 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I8,
4372 mkU8(op2)));
4373
4374 return "cliy";
4375}
4376
florian55085f82012-11-21 00:36:55 +00004377static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004378s390_irgen_CLFHSI(UShort i2, IRTemp op1addr)
4379{
4380 IRTemp op1 = newTemp(Ity_I32);
4381 UInt op2;
4382
4383 assign(op1, load(Ity_I32, mkexpr(op1addr)));
4384 op2 = (UInt)i2;
4385 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
4386 mkU32(op2)));
4387
4388 return "clfhsi";
4389}
4390
florian55085f82012-11-21 00:36:55 +00004391static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004392s390_irgen_CLGHSI(UShort i2, IRTemp op1addr)
4393{
4394 IRTemp op1 = newTemp(Ity_I64);
4395 ULong op2;
4396
4397 assign(op1, load(Ity_I64, mkexpr(op1addr)));
4398 op2 = (ULong)i2;
4399 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I64,
4400 mkU64(op2)));
4401
4402 return "clghsi";
4403}
4404
florian55085f82012-11-21 00:36:55 +00004405static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004406s390_irgen_CLHHSI(UShort i2, IRTemp op1addr)
4407{
4408 IRTemp op1 = newTemp(Ity_I16);
4409 UShort op2;
4410
4411 assign(op1, load(Ity_I16, mkexpr(op1addr)));
4412 op2 = i2;
4413 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I16,
4414 mkU16(op2)));
4415
4416 return "clhhsi";
4417}
4418
florian55085f82012-11-21 00:36:55 +00004419static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004420s390_irgen_CLRL(UChar r1, UInt i2)
4421{
4422 IRTemp op1 = newTemp(Ity_I32);
4423 IRTemp op2 = newTemp(Ity_I32);
4424
4425 assign(op1, get_gpr_w1(r1));
4426 assign(op2, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
4427 i2 << 1))));
4428 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4429
4430 return "clrl";
4431}
4432
florian55085f82012-11-21 00:36:55 +00004433static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004434s390_irgen_CLGRL(UChar r1, UInt i2)
4435{
4436 IRTemp op1 = newTemp(Ity_I64);
4437 IRTemp op2 = newTemp(Ity_I64);
4438
4439 assign(op1, get_gpr_dw0(r1));
4440 assign(op2, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
4441 i2 << 1))));
4442 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4443
4444 return "clgrl";
4445}
4446
florian55085f82012-11-21 00:36:55 +00004447static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004448s390_irgen_CLGFRL(UChar r1, UInt i2)
4449{
4450 IRTemp op1 = newTemp(Ity_I64);
4451 IRTemp op2 = newTemp(Ity_I64);
4452
4453 assign(op1, get_gpr_dw0(r1));
4454 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
4455 ((ULong)(Long)(Int)i2 << 1)))));
4456 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4457
4458 return "clgfrl";
4459}
4460
florian55085f82012-11-21 00:36:55 +00004461static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004462s390_irgen_CLHRL(UChar r1, UInt i2)
4463{
4464 IRTemp op1 = newTemp(Ity_I32);
4465 IRTemp op2 = newTemp(Ity_I32);
4466
4467 assign(op1, get_gpr_w1(r1));
4468 assign(op2, unop(Iop_16Uto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
4469 ((ULong)(Long)(Int)i2 << 1)))));
4470 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4471
4472 return "clhrl";
4473}
4474
florian55085f82012-11-21 00:36:55 +00004475static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004476s390_irgen_CLGHRL(UChar r1, UInt i2)
4477{
4478 IRTemp op1 = newTemp(Ity_I64);
4479 IRTemp op2 = newTemp(Ity_I64);
4480
4481 assign(op1, get_gpr_dw0(r1));
4482 assign(op2, unop(Iop_16Uto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
4483 ((ULong)(Long)(Int)i2 << 1)))));
4484 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4485
4486 return "clghrl";
4487}
4488
florian55085f82012-11-21 00:36:55 +00004489static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004490s390_irgen_CLRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
4491{
4492 IRTemp op1 = newTemp(Ity_I32);
4493 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00004494 IRTemp cond = newTemp(Ity_I32);
4495
4496 if (m3 == 0) {
4497 } else {
4498 if (m3 == 14) {
4499 always_goto(mkexpr(op4addr));
4500 } else {
4501 assign(op1, get_gpr_w1(r1));
4502 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00004503 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4504 op1, op2));
florianf321da72012-07-21 20:32:57 +00004505 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4506 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004507 }
4508 }
4509
4510 return "clrb";
4511}
4512
florian55085f82012-11-21 00:36:55 +00004513static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004514s390_irgen_CLGRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
4515{
4516 IRTemp op1 = newTemp(Ity_I64);
4517 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00004518 IRTemp cond = newTemp(Ity_I32);
4519
4520 if (m3 == 0) {
4521 } else {
4522 if (m3 == 14) {
4523 always_goto(mkexpr(op4addr));
4524 } else {
4525 assign(op1, get_gpr_dw0(r1));
4526 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00004527 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4528 op1, op2));
florianf321da72012-07-21 20:32:57 +00004529 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4530 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004531 }
4532 }
4533
4534 return "clgrb";
4535}
4536
florian55085f82012-11-21 00:36:55 +00004537static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004538s390_irgen_CLRJ(UChar r1, UChar r2, UShort i4, UChar m3)
4539{
4540 IRTemp op1 = newTemp(Ity_I32);
4541 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00004542 IRTemp cond = newTemp(Ity_I32);
4543
4544 if (m3 == 0) {
4545 } else {
4546 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004547 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004548 } else {
4549 assign(op1, get_gpr_w1(r1));
4550 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00004551 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4552 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00004553 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4554 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4555
4556 }
4557 }
4558
4559 return "clrj";
4560}
4561
florian55085f82012-11-21 00:36:55 +00004562static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004563s390_irgen_CLGRJ(UChar r1, UChar r2, UShort i4, UChar m3)
4564{
4565 IRTemp op1 = newTemp(Ity_I64);
4566 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00004567 IRTemp cond = newTemp(Ity_I32);
4568
4569 if (m3 == 0) {
4570 } else {
4571 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004572 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004573 } else {
4574 assign(op1, get_gpr_dw0(r1));
4575 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00004576 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4577 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00004578 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4579 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4580
4581 }
4582 }
4583
4584 return "clgrj";
4585}
4586
florian55085f82012-11-21 00:36:55 +00004587static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004588s390_irgen_CLIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
4589{
4590 IRTemp op1 = newTemp(Ity_I32);
4591 UInt op2;
sewardj2019a972011-03-07 16:04:07 +00004592 IRTemp cond = newTemp(Ity_I32);
4593
4594 if (m3 == 0) {
4595 } else {
4596 if (m3 == 14) {
4597 always_goto(mkexpr(op4addr));
4598 } else {
4599 assign(op1, get_gpr_w1(r1));
4600 op2 = (UInt)i2;
florianff9613f2012-05-12 15:26:44 +00004601 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4602 mktemp(Ity_I32, mkU32(op2))));
florianf321da72012-07-21 20:32:57 +00004603 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4604 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004605 }
4606 }
4607
4608 return "clib";
4609}
4610
florian55085f82012-11-21 00:36:55 +00004611static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004612s390_irgen_CLGIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
4613{
4614 IRTemp op1 = newTemp(Ity_I64);
4615 ULong op2;
sewardj2019a972011-03-07 16:04:07 +00004616 IRTemp cond = newTemp(Ity_I32);
4617
4618 if (m3 == 0) {
4619 } else {
4620 if (m3 == 14) {
4621 always_goto(mkexpr(op4addr));
4622 } else {
4623 assign(op1, get_gpr_dw0(r1));
4624 op2 = (ULong)i2;
florianff9613f2012-05-12 15:26:44 +00004625 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4626 mktemp(Ity_I64, mkU64(op2))));
florianf321da72012-07-21 20:32:57 +00004627 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4628 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004629 }
4630 }
4631
4632 return "clgib";
4633}
4634
florian55085f82012-11-21 00:36:55 +00004635static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004636s390_irgen_CLIJ(UChar r1, UChar m3, UShort i4, UChar i2)
4637{
4638 IRTemp op1 = newTemp(Ity_I32);
4639 UInt op2;
sewardj2019a972011-03-07 16:04:07 +00004640 IRTemp cond = newTemp(Ity_I32);
4641
4642 if (m3 == 0) {
4643 } else {
4644 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004645 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004646 } else {
4647 assign(op1, get_gpr_w1(r1));
4648 op2 = (UInt)i2;
florianff9613f2012-05-12 15:26:44 +00004649 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4650 mktemp(Ity_I32, mkU32(op2))));
sewardj2019a972011-03-07 16:04:07 +00004651 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4652 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4653
4654 }
4655 }
4656
4657 return "clij";
4658}
4659
florian55085f82012-11-21 00:36:55 +00004660static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004661s390_irgen_CLGIJ(UChar r1, UChar m3, UShort i4, UChar i2)
4662{
4663 IRTemp op1 = newTemp(Ity_I64);
4664 ULong op2;
sewardj2019a972011-03-07 16:04:07 +00004665 IRTemp cond = newTemp(Ity_I32);
4666
4667 if (m3 == 0) {
4668 } else {
4669 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004670 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004671 } else {
4672 assign(op1, get_gpr_dw0(r1));
4673 op2 = (ULong)i2;
florianff9613f2012-05-12 15:26:44 +00004674 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4675 mktemp(Ity_I64, mkU64(op2))));
sewardj2019a972011-03-07 16:04:07 +00004676 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4677 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4678
4679 }
4680 }
4681
4682 return "clgij";
4683}
4684
florian55085f82012-11-21 00:36:55 +00004685static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004686s390_irgen_CLM(UChar r1, UChar r3, IRTemp op2addr)
4687{
4688 IRTemp op1 = newTemp(Ity_I32);
4689 IRTemp op2 = newTemp(Ity_I32);
4690 IRTemp b0 = newTemp(Ity_I32);
4691 IRTemp b1 = newTemp(Ity_I32);
4692 IRTemp b2 = newTemp(Ity_I32);
4693 IRTemp b3 = newTemp(Ity_I32);
4694 IRTemp c0 = newTemp(Ity_I32);
4695 IRTemp c1 = newTemp(Ity_I32);
4696 IRTemp c2 = newTemp(Ity_I32);
4697 IRTemp c3 = newTemp(Ity_I32);
4698 UChar n;
4699
4700 n = 0;
4701 if ((r3 & 8) != 0) {
4702 assign(b0, unop(Iop_8Uto32, get_gpr_b4(r1)));
4703 assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
4704 n = n + 1;
4705 } else {
4706 assign(b0, mkU32(0));
4707 assign(c0, mkU32(0));
4708 }
4709 if ((r3 & 4) != 0) {
4710 assign(b1, unop(Iop_8Uto32, get_gpr_b5(r1)));
4711 assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4712 mkU64(n)))));
4713 n = n + 1;
4714 } else {
4715 assign(b1, mkU32(0));
4716 assign(c1, mkU32(0));
4717 }
4718 if ((r3 & 2) != 0) {
4719 assign(b2, unop(Iop_8Uto32, get_gpr_b6(r1)));
4720 assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4721 mkU64(n)))));
4722 n = n + 1;
4723 } else {
4724 assign(b2, mkU32(0));
4725 assign(c2, mkU32(0));
4726 }
4727 if ((r3 & 1) != 0) {
4728 assign(b3, unop(Iop_8Uto32, get_gpr_b7(r1)));
4729 assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4730 mkU64(n)))));
4731 n = n + 1;
4732 } else {
4733 assign(b3, mkU32(0));
4734 assign(c3, mkU32(0));
4735 }
4736 assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4737 mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
4738 binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
4739 assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4740 mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
4741 binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
4742 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4743
4744 return "clm";
4745}
4746
florian55085f82012-11-21 00:36:55 +00004747static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004748s390_irgen_CLMY(UChar r1, UChar r3, IRTemp op2addr)
4749{
4750 IRTemp op1 = newTemp(Ity_I32);
4751 IRTemp op2 = newTemp(Ity_I32);
4752 IRTemp b0 = newTemp(Ity_I32);
4753 IRTemp b1 = newTemp(Ity_I32);
4754 IRTemp b2 = newTemp(Ity_I32);
4755 IRTemp b3 = newTemp(Ity_I32);
4756 IRTemp c0 = newTemp(Ity_I32);
4757 IRTemp c1 = newTemp(Ity_I32);
4758 IRTemp c2 = newTemp(Ity_I32);
4759 IRTemp c3 = newTemp(Ity_I32);
4760 UChar n;
4761
4762 n = 0;
4763 if ((r3 & 8) != 0) {
4764 assign(b0, unop(Iop_8Uto32, get_gpr_b4(r1)));
4765 assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
4766 n = n + 1;
4767 } else {
4768 assign(b0, mkU32(0));
4769 assign(c0, mkU32(0));
4770 }
4771 if ((r3 & 4) != 0) {
4772 assign(b1, unop(Iop_8Uto32, get_gpr_b5(r1)));
4773 assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4774 mkU64(n)))));
4775 n = n + 1;
4776 } else {
4777 assign(b1, mkU32(0));
4778 assign(c1, mkU32(0));
4779 }
4780 if ((r3 & 2) != 0) {
4781 assign(b2, unop(Iop_8Uto32, get_gpr_b6(r1)));
4782 assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4783 mkU64(n)))));
4784 n = n + 1;
4785 } else {
4786 assign(b2, mkU32(0));
4787 assign(c2, mkU32(0));
4788 }
4789 if ((r3 & 1) != 0) {
4790 assign(b3, unop(Iop_8Uto32, get_gpr_b7(r1)));
4791 assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4792 mkU64(n)))));
4793 n = n + 1;
4794 } else {
4795 assign(b3, mkU32(0));
4796 assign(c3, mkU32(0));
4797 }
4798 assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4799 mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
4800 binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
4801 assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4802 mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
4803 binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
4804 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4805
4806 return "clmy";
4807}
4808
florian55085f82012-11-21 00:36:55 +00004809static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004810s390_irgen_CLMH(UChar r1, UChar r3, IRTemp op2addr)
4811{
4812 IRTemp op1 = newTemp(Ity_I32);
4813 IRTemp op2 = newTemp(Ity_I32);
4814 IRTemp b0 = newTemp(Ity_I32);
4815 IRTemp b1 = newTemp(Ity_I32);
4816 IRTemp b2 = newTemp(Ity_I32);
4817 IRTemp b3 = newTemp(Ity_I32);
4818 IRTemp c0 = newTemp(Ity_I32);
4819 IRTemp c1 = newTemp(Ity_I32);
4820 IRTemp c2 = newTemp(Ity_I32);
4821 IRTemp c3 = newTemp(Ity_I32);
4822 UChar n;
4823
4824 n = 0;
4825 if ((r3 & 8) != 0) {
4826 assign(b0, unop(Iop_8Uto32, get_gpr_b0(r1)));
4827 assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
4828 n = n + 1;
4829 } else {
4830 assign(b0, mkU32(0));
4831 assign(c0, mkU32(0));
4832 }
4833 if ((r3 & 4) != 0) {
4834 assign(b1, unop(Iop_8Uto32, get_gpr_b1(r1)));
4835 assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4836 mkU64(n)))));
4837 n = n + 1;
4838 } else {
4839 assign(b1, mkU32(0));
4840 assign(c1, mkU32(0));
4841 }
4842 if ((r3 & 2) != 0) {
4843 assign(b2, unop(Iop_8Uto32, get_gpr_b2(r1)));
4844 assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4845 mkU64(n)))));
4846 n = n + 1;
4847 } else {
4848 assign(b2, mkU32(0));
4849 assign(c2, mkU32(0));
4850 }
4851 if ((r3 & 1) != 0) {
4852 assign(b3, unop(Iop_8Uto32, get_gpr_b3(r1)));
4853 assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4854 mkU64(n)))));
4855 n = n + 1;
4856 } else {
4857 assign(b3, mkU32(0));
4858 assign(c3, mkU32(0));
4859 }
4860 assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4861 mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
4862 binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
4863 assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4864 mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
4865 binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
4866 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4867
4868 return "clmh";
4869}
4870
florian55085f82012-11-21 00:36:55 +00004871static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004872s390_irgen_CLHHR(UChar r1, UChar r2)
4873{
4874 IRTemp op1 = newTemp(Ity_I32);
4875 IRTemp op2 = newTemp(Ity_I32);
4876
4877 assign(op1, get_gpr_w0(r1));
4878 assign(op2, get_gpr_w0(r2));
4879 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4880
4881 return "clhhr";
4882}
4883
florian55085f82012-11-21 00:36:55 +00004884static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004885s390_irgen_CLHLR(UChar r1, UChar r2)
4886{
4887 IRTemp op1 = newTemp(Ity_I32);
4888 IRTemp op2 = newTemp(Ity_I32);
4889
4890 assign(op1, get_gpr_w0(r1));
4891 assign(op2, get_gpr_w1(r2));
4892 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4893
4894 return "clhlr";
4895}
4896
florian55085f82012-11-21 00:36:55 +00004897static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004898s390_irgen_CLHF(UChar r1, IRTemp op2addr)
4899{
4900 IRTemp op1 = newTemp(Ity_I32);
4901 IRTemp op2 = newTemp(Ity_I32);
4902
4903 assign(op1, get_gpr_w0(r1));
4904 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4905 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4906
4907 return "clhf";
4908}
4909
florian55085f82012-11-21 00:36:55 +00004910static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004911s390_irgen_CLIH(UChar r1, UInt i2)
4912{
4913 IRTemp op1 = newTemp(Ity_I32);
4914 UInt op2;
4915
4916 assign(op1, get_gpr_w0(r1));
4917 op2 = i2;
4918 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
4919 mkU32(op2)));
4920
4921 return "clih";
4922}
4923
florian55085f82012-11-21 00:36:55 +00004924static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004925s390_irgen_CPYA(UChar r1, UChar r2)
4926{
4927 put_ar_w0(r1, get_ar_w0(r2));
sewardj7ee97522011-05-09 21:45:04 +00004928 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00004929 s390_disasm(ENC3(MNM, AR, AR), "cpya", r1, r2);
4930
4931 return "cpya";
4932}
4933
florian55085f82012-11-21 00:36:55 +00004934static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004935s390_irgen_XR(UChar r1, UChar r2)
4936{
4937 IRTemp op1 = newTemp(Ity_I32);
4938 IRTemp op2 = newTemp(Ity_I32);
4939 IRTemp result = newTemp(Ity_I32);
4940
4941 if (r1 == r2) {
4942 assign(result, mkU32(0));
4943 } else {
4944 assign(op1, get_gpr_w1(r1));
4945 assign(op2, get_gpr_w1(r2));
4946 assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2)));
4947 }
4948 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4949 put_gpr_w1(r1, mkexpr(result));
4950
4951 return "xr";
4952}
4953
florian55085f82012-11-21 00:36:55 +00004954static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004955s390_irgen_XGR(UChar r1, UChar r2)
4956{
4957 IRTemp op1 = newTemp(Ity_I64);
4958 IRTemp op2 = newTemp(Ity_I64);
4959 IRTemp result = newTemp(Ity_I64);
4960
4961 if (r1 == r2) {
4962 assign(result, mkU64(0));
4963 } else {
4964 assign(op1, get_gpr_dw0(r1));
4965 assign(op2, get_gpr_dw0(r2));
4966 assign(result, binop(Iop_Xor64, mkexpr(op1), mkexpr(op2)));
4967 }
4968 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4969 put_gpr_dw0(r1, mkexpr(result));
4970
4971 return "xgr";
4972}
4973
florian55085f82012-11-21 00:36:55 +00004974static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004975s390_irgen_XRK(UChar r3, UChar r1, UChar r2)
4976{
4977 IRTemp op2 = newTemp(Ity_I32);
4978 IRTemp op3 = newTemp(Ity_I32);
4979 IRTemp result = newTemp(Ity_I32);
4980
4981 assign(op2, get_gpr_w1(r2));
4982 assign(op3, get_gpr_w1(r3));
4983 assign(result, binop(Iop_Xor32, mkexpr(op2), mkexpr(op3)));
4984 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4985 put_gpr_w1(r1, mkexpr(result));
4986
4987 return "xrk";
4988}
4989
florian55085f82012-11-21 00:36:55 +00004990static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004991s390_irgen_XGRK(UChar r3, UChar r1, UChar r2)
4992{
4993 IRTemp op2 = newTemp(Ity_I64);
4994 IRTemp op3 = newTemp(Ity_I64);
4995 IRTemp result = newTemp(Ity_I64);
4996
4997 assign(op2, get_gpr_dw0(r2));
4998 assign(op3, get_gpr_dw0(r3));
4999 assign(result, binop(Iop_Xor64, mkexpr(op2), mkexpr(op3)));
5000 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5001 put_gpr_dw0(r1, mkexpr(result));
5002
5003 return "xgrk";
5004}
5005
florian55085f82012-11-21 00:36:55 +00005006static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005007s390_irgen_X(UChar r1, IRTemp op2addr)
5008{
5009 IRTemp op1 = newTemp(Ity_I32);
5010 IRTemp op2 = newTemp(Ity_I32);
5011 IRTemp result = newTemp(Ity_I32);
5012
5013 assign(op1, get_gpr_w1(r1));
5014 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5015 assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2)));
5016 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5017 put_gpr_w1(r1, mkexpr(result));
5018
5019 return "x";
5020}
5021
florian55085f82012-11-21 00:36:55 +00005022static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005023s390_irgen_XY(UChar r1, IRTemp op2addr)
5024{
5025 IRTemp op1 = newTemp(Ity_I32);
5026 IRTemp op2 = newTemp(Ity_I32);
5027 IRTemp result = newTemp(Ity_I32);
5028
5029 assign(op1, get_gpr_w1(r1));
5030 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5031 assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2)));
5032 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5033 put_gpr_w1(r1, mkexpr(result));
5034
5035 return "xy";
5036}
5037
florian55085f82012-11-21 00:36:55 +00005038static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005039s390_irgen_XG(UChar r1, IRTemp op2addr)
5040{
5041 IRTemp op1 = newTemp(Ity_I64);
5042 IRTemp op2 = newTemp(Ity_I64);
5043 IRTemp result = newTemp(Ity_I64);
5044
5045 assign(op1, get_gpr_dw0(r1));
5046 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5047 assign(result, binop(Iop_Xor64, mkexpr(op1), mkexpr(op2)));
5048 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5049 put_gpr_dw0(r1, mkexpr(result));
5050
5051 return "xg";
5052}
5053
florian55085f82012-11-21 00:36:55 +00005054static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005055s390_irgen_XI(UChar i2, IRTemp op1addr)
5056{
5057 IRTemp op1 = newTemp(Ity_I8);
5058 UChar op2;
5059 IRTemp result = newTemp(Ity_I8);
5060
5061 assign(op1, load(Ity_I8, mkexpr(op1addr)));
5062 op2 = i2;
5063 assign(result, binop(Iop_Xor8, mkexpr(op1), mkU8(op2)));
5064 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5065 store(mkexpr(op1addr), mkexpr(result));
5066
5067 return "xi";
5068}
5069
florian55085f82012-11-21 00:36:55 +00005070static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005071s390_irgen_XIY(UChar i2, IRTemp op1addr)
5072{
5073 IRTemp op1 = newTemp(Ity_I8);
5074 UChar op2;
5075 IRTemp result = newTemp(Ity_I8);
5076
5077 assign(op1, load(Ity_I8, mkexpr(op1addr)));
5078 op2 = i2;
5079 assign(result, binop(Iop_Xor8, mkexpr(op1), mkU8(op2)));
5080 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5081 store(mkexpr(op1addr), mkexpr(result));
5082
5083 return "xiy";
5084}
5085
florian55085f82012-11-21 00:36:55 +00005086static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005087s390_irgen_XIHF(UChar r1, UInt i2)
5088{
5089 IRTemp op1 = newTemp(Ity_I32);
5090 UInt op2;
5091 IRTemp result = newTemp(Ity_I32);
5092
5093 assign(op1, get_gpr_w0(r1));
5094 op2 = i2;
5095 assign(result, binop(Iop_Xor32, mkexpr(op1), mkU32(op2)));
5096 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5097 put_gpr_w0(r1, mkexpr(result));
5098
5099 return "xihf";
5100}
5101
florian55085f82012-11-21 00:36:55 +00005102static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005103s390_irgen_XILF(UChar r1, UInt i2)
5104{
5105 IRTemp op1 = newTemp(Ity_I32);
5106 UInt op2;
5107 IRTemp result = newTemp(Ity_I32);
5108
5109 assign(op1, get_gpr_w1(r1));
5110 op2 = i2;
5111 assign(result, binop(Iop_Xor32, mkexpr(op1), mkU32(op2)));
5112 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5113 put_gpr_w1(r1, mkexpr(result));
5114
5115 return "xilf";
5116}
5117
florian55085f82012-11-21 00:36:55 +00005118static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005119s390_irgen_EAR(UChar r1, UChar r2)
5120{
5121 put_gpr_w1(r1, get_ar_w0(r2));
sewardj7ee97522011-05-09 21:45:04 +00005122 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00005123 s390_disasm(ENC3(MNM, GPR, AR), "ear", r1, r2);
5124
5125 return "ear";
5126}
5127
florian55085f82012-11-21 00:36:55 +00005128static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005129s390_irgen_IC(UChar r1, IRTemp op2addr)
5130{
5131 put_gpr_b7(r1, load(Ity_I8, mkexpr(op2addr)));
5132
5133 return "ic";
5134}
5135
florian55085f82012-11-21 00:36:55 +00005136static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005137s390_irgen_ICY(UChar r1, IRTemp op2addr)
5138{
5139 put_gpr_b7(r1, load(Ity_I8, mkexpr(op2addr)));
5140
5141 return "icy";
5142}
5143
florian55085f82012-11-21 00:36:55 +00005144static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005145s390_irgen_ICM(UChar r1, UChar r3, IRTemp op2addr)
5146{
5147 UChar n;
5148 IRTemp result = newTemp(Ity_I32);
5149 UInt mask;
5150
5151 n = 0;
5152 mask = (UInt)r3;
5153 if ((mask & 8) != 0) {
5154 put_gpr_b4(r1, load(Ity_I8, mkexpr(op2addr)));
5155 n = n + 1;
5156 }
5157 if ((mask & 4) != 0) {
5158 put_gpr_b5(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5159
5160 n = n + 1;
5161 }
5162 if ((mask & 2) != 0) {
5163 put_gpr_b6(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5164
5165 n = n + 1;
5166 }
5167 if ((mask & 1) != 0) {
5168 put_gpr_b7(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5169
5170 n = n + 1;
5171 }
5172 assign(result, get_gpr_w1(r1));
5173 s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
5174 mkU32(mask)));
5175
5176 return "icm";
5177}
5178
florian55085f82012-11-21 00:36:55 +00005179static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005180s390_irgen_ICMY(UChar r1, UChar r3, IRTemp op2addr)
5181{
5182 UChar n;
5183 IRTemp result = newTemp(Ity_I32);
5184 UInt mask;
5185
5186 n = 0;
5187 mask = (UInt)r3;
5188 if ((mask & 8) != 0) {
5189 put_gpr_b4(r1, load(Ity_I8, mkexpr(op2addr)));
5190 n = n + 1;
5191 }
5192 if ((mask & 4) != 0) {
5193 put_gpr_b5(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5194
5195 n = n + 1;
5196 }
5197 if ((mask & 2) != 0) {
5198 put_gpr_b6(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5199
5200 n = n + 1;
5201 }
5202 if ((mask & 1) != 0) {
5203 put_gpr_b7(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5204
5205 n = n + 1;
5206 }
5207 assign(result, get_gpr_w1(r1));
5208 s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
5209 mkU32(mask)));
5210
5211 return "icmy";
5212}
5213
florian55085f82012-11-21 00:36:55 +00005214static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005215s390_irgen_ICMH(UChar r1, UChar r3, IRTemp op2addr)
5216{
5217 UChar n;
5218 IRTemp result = newTemp(Ity_I32);
5219 UInt mask;
5220
5221 n = 0;
5222 mask = (UInt)r3;
5223 if ((mask & 8) != 0) {
5224 put_gpr_b0(r1, load(Ity_I8, mkexpr(op2addr)));
5225 n = n + 1;
5226 }
5227 if ((mask & 4) != 0) {
5228 put_gpr_b1(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5229
5230 n = n + 1;
5231 }
5232 if ((mask & 2) != 0) {
5233 put_gpr_b2(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5234
5235 n = n + 1;
5236 }
5237 if ((mask & 1) != 0) {
5238 put_gpr_b3(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5239
5240 n = n + 1;
5241 }
5242 assign(result, get_gpr_w0(r1));
5243 s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
5244 mkU32(mask)));
5245
5246 return "icmh";
5247}
5248
florian55085f82012-11-21 00:36:55 +00005249static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005250s390_irgen_IIHF(UChar r1, UInt i2)
5251{
5252 put_gpr_w0(r1, mkU32(i2));
5253
5254 return "iihf";
5255}
5256
florian55085f82012-11-21 00:36:55 +00005257static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005258s390_irgen_IIHH(UChar r1, UShort i2)
5259{
5260 put_gpr_hw0(r1, mkU16(i2));
5261
5262 return "iihh";
5263}
5264
florian55085f82012-11-21 00:36:55 +00005265static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005266s390_irgen_IIHL(UChar r1, UShort i2)
5267{
5268 put_gpr_hw1(r1, mkU16(i2));
5269
5270 return "iihl";
5271}
5272
florian55085f82012-11-21 00:36:55 +00005273static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005274s390_irgen_IILF(UChar r1, UInt i2)
5275{
5276 put_gpr_w1(r1, mkU32(i2));
5277
5278 return "iilf";
5279}
5280
florian55085f82012-11-21 00:36:55 +00005281static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005282s390_irgen_IILH(UChar r1, UShort i2)
5283{
5284 put_gpr_hw2(r1, mkU16(i2));
5285
5286 return "iilh";
5287}
5288
florian55085f82012-11-21 00:36:55 +00005289static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005290s390_irgen_IILL(UChar r1, UShort i2)
5291{
5292 put_gpr_hw3(r1, mkU16(i2));
5293
5294 return "iill";
5295}
5296
florian55085f82012-11-21 00:36:55 +00005297static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005298s390_irgen_LR(UChar r1, UChar r2)
5299{
5300 put_gpr_w1(r1, get_gpr_w1(r2));
5301
5302 return "lr";
5303}
5304
florian55085f82012-11-21 00:36:55 +00005305static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005306s390_irgen_LGR(UChar r1, UChar r2)
5307{
5308 put_gpr_dw0(r1, get_gpr_dw0(r2));
5309
5310 return "lgr";
5311}
5312
florian55085f82012-11-21 00:36:55 +00005313static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005314s390_irgen_LGFR(UChar r1, UChar r2)
5315{
5316 put_gpr_dw0(r1, unop(Iop_32Sto64, get_gpr_w1(r2)));
5317
5318 return "lgfr";
5319}
5320
florian55085f82012-11-21 00:36:55 +00005321static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005322s390_irgen_L(UChar r1, IRTemp op2addr)
5323{
5324 put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
5325
5326 return "l";
5327}
5328
florian55085f82012-11-21 00:36:55 +00005329static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005330s390_irgen_LY(UChar r1, IRTemp op2addr)
5331{
5332 put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
5333
5334 return "ly";
5335}
5336
florian55085f82012-11-21 00:36:55 +00005337static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005338s390_irgen_LG(UChar r1, IRTemp op2addr)
5339{
5340 put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
5341
5342 return "lg";
5343}
5344
florian55085f82012-11-21 00:36:55 +00005345static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005346s390_irgen_LGF(UChar r1, IRTemp op2addr)
5347{
5348 put_gpr_dw0(r1, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
5349
5350 return "lgf";
5351}
5352
florian55085f82012-11-21 00:36:55 +00005353static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005354s390_irgen_LGFI(UChar r1, UInt i2)
5355{
5356 put_gpr_dw0(r1, mkU64((ULong)(Long)(Int)i2));
5357
5358 return "lgfi";
5359}
5360
florian55085f82012-11-21 00:36:55 +00005361static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005362s390_irgen_LRL(UChar r1, UInt i2)
5363{
5364 put_gpr_w1(r1, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
5365 i2 << 1))));
5366
5367 return "lrl";
5368}
5369
florian55085f82012-11-21 00:36:55 +00005370static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005371s390_irgen_LGRL(UChar r1, UInt i2)
5372{
5373 put_gpr_dw0(r1, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
5374 i2 << 1))));
5375
5376 return "lgrl";
5377}
5378
florian55085f82012-11-21 00:36:55 +00005379static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005380s390_irgen_LGFRL(UChar r1, UInt i2)
5381{
5382 put_gpr_dw0(r1, unop(Iop_32Sto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
5383 ((ULong)(Long)(Int)i2 << 1)))));
5384
5385 return "lgfrl";
5386}
5387
florian55085f82012-11-21 00:36:55 +00005388static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005389s390_irgen_LA(UChar r1, IRTemp op2addr)
5390{
5391 put_gpr_dw0(r1, mkexpr(op2addr));
5392
5393 return "la";
5394}
5395
florian55085f82012-11-21 00:36:55 +00005396static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005397s390_irgen_LAY(UChar r1, IRTemp op2addr)
5398{
5399 put_gpr_dw0(r1, mkexpr(op2addr));
5400
5401 return "lay";
5402}
5403
florian55085f82012-11-21 00:36:55 +00005404static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005405s390_irgen_LAE(UChar r1, IRTemp op2addr)
5406{
5407 put_gpr_dw0(r1, mkexpr(op2addr));
5408
5409 return "lae";
5410}
5411
florian55085f82012-11-21 00:36:55 +00005412static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005413s390_irgen_LAEY(UChar r1, IRTemp op2addr)
5414{
5415 put_gpr_dw0(r1, mkexpr(op2addr));
5416
5417 return "laey";
5418}
5419
florian55085f82012-11-21 00:36:55 +00005420static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005421s390_irgen_LARL(UChar r1, UInt i2)
5422{
5423 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)));
5424
5425 return "larl";
5426}
5427
floriana265ee72012-12-02 20:58:17 +00005428/* The IR representation of LAA and friends is an approximation of what
5429 happens natively. Essentially a loop containing a compare-and-swap is
5430 constructed which will iterate until the CAS succeeds. As a consequence,
5431 instrumenters may see more memory accesses than happen natively. See also
5432 discussion here: https://bugs.kde.org/show_bug.cgi?id=306035 */
florianffc94012012-12-02 21:31:15 +00005433static void
5434s390_irgen_load_and_add32(UChar r1, UChar r3, IRTemp op2addr, Bool is_signed)
sewardj2019a972011-03-07 16:04:07 +00005435{
floriana265ee72012-12-02 20:58:17 +00005436 IRCAS *cas;
5437 IRTemp old_mem = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00005438 IRTemp op2 = newTemp(Ity_I32);
5439 IRTemp op3 = newTemp(Ity_I32);
5440 IRTemp result = newTemp(Ity_I32);
5441
5442 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5443 assign(op3, get_gpr_w1(r3));
5444 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
floriana265ee72012-12-02 20:58:17 +00005445
5446 /* Place the addition of second operand and third operand at the
5447 second-operand location everytime */
5448 cas = mkIRCAS(IRTemp_INVALID, old_mem,
5449 Iend_BE, mkexpr(op2addr),
5450 NULL, mkexpr(op2), /* expected value */
5451 NULL, mkexpr(result) /* new value */);
5452 stmt(IRStmt_CAS(cas));
5453
florianffc94012012-12-02 21:31:15 +00005454 /* Set CC according to 32-bit addition */
5455 if (is_signed) {
5456 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
5457 } else {
5458 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
5459 }
floriana265ee72012-12-02 20:58:17 +00005460
5461 /* If old_mem contains the expected value, then the CAS succeeded.
5462 Otherwise, it did not */
5463 yield_if(binop(Iop_CmpNE32, mkexpr(old_mem), mkexpr(op2)));
5464 put_gpr_w1(r1, mkexpr(old_mem));
florianffc94012012-12-02 21:31:15 +00005465}
5466
5467static void
5468s390_irgen_load_and_add64(UChar r1, UChar r3, IRTemp op2addr, Bool is_signed)
5469{
5470 IRCAS *cas;
5471 IRTemp old_mem = newTemp(Ity_I64);
5472 IRTemp op2 = newTemp(Ity_I64);
5473 IRTemp op3 = newTemp(Ity_I64);
5474 IRTemp result = newTemp(Ity_I64);
5475
5476 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5477 assign(op3, get_gpr_dw0(r3));
5478 assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
5479
5480 /* Place the addition of second operand and third operand at the
5481 second-operand location everytime */
5482 cas = mkIRCAS(IRTemp_INVALID, old_mem,
5483 Iend_BE, mkexpr(op2addr),
5484 NULL, mkexpr(op2), /* expected value */
5485 NULL, mkexpr(result) /* new value */);
5486 stmt(IRStmt_CAS(cas));
5487
5488 /* Set CC according to 64-bit addition */
5489 if (is_signed) {
5490 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op2, op3);
5491 } else {
5492 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op2, op3);
5493 }
5494
5495 /* If old_mem contains the expected value, then the CAS succeeded.
5496 Otherwise, it did not */
5497 yield_if(binop(Iop_CmpNE64, mkexpr(old_mem), mkexpr(op2)));
5498 put_gpr_dw0(r1, mkexpr(old_mem));
5499}
5500
5501static void
5502s390_irgen_load_and_bitwise32(UChar r1, UChar r3, IRTemp op2addr, IROp op)
5503{
5504 IRCAS *cas;
5505 IRTemp old_mem = newTemp(Ity_I32);
5506 IRTemp op2 = newTemp(Ity_I32);
5507 IRTemp op3 = newTemp(Ity_I32);
5508 IRTemp result = newTemp(Ity_I32);
5509
5510 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5511 assign(op3, get_gpr_w1(r3));
5512 assign(result, binop(op, mkexpr(op2), mkexpr(op3)));
5513
5514 /* Place the addition of second operand and third operand at the
5515 second-operand location everytime */
5516 cas = mkIRCAS(IRTemp_INVALID, old_mem,
5517 Iend_BE, mkexpr(op2addr),
5518 NULL, mkexpr(op2), /* expected value */
5519 NULL, mkexpr(result) /* new value */);
5520 stmt(IRStmt_CAS(cas));
5521
5522 /* Set CC according to bitwise operation */
5523 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5524
5525 /* If old_mem contains the expected value, then the CAS succeeded.
5526 Otherwise, it did not */
5527 yield_if(binop(Iop_CmpNE32, mkexpr(old_mem), mkexpr(op2)));
5528 put_gpr_w1(r1, mkexpr(old_mem));
5529}
5530
5531static void
5532s390_irgen_load_and_bitwise64(UChar r1, UChar r3, IRTemp op2addr, IROp op)
5533{
5534 IRCAS *cas;
5535 IRTemp old_mem = newTemp(Ity_I64);
5536 IRTemp op2 = newTemp(Ity_I64);
5537 IRTemp op3 = newTemp(Ity_I64);
5538 IRTemp result = newTemp(Ity_I64);
5539
5540 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5541 assign(op3, get_gpr_dw0(r3));
5542 assign(result, binop(op, mkexpr(op2), mkexpr(op3)));
5543
5544 /* Place the addition of second operand and third operand at the
5545 second-operand location everytime */
5546 cas = mkIRCAS(IRTemp_INVALID, old_mem,
5547 Iend_BE, mkexpr(op2addr),
5548 NULL, mkexpr(op2), /* expected value */
5549 NULL, mkexpr(result) /* new value */);
5550 stmt(IRStmt_CAS(cas));
5551
5552 /* Set CC according to bitwise operation */
5553 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5554
5555 /* If old_mem contains the expected value, then the CAS succeeded.
5556 Otherwise, it did not */
5557 yield_if(binop(Iop_CmpNE64, mkexpr(old_mem), mkexpr(op2)));
5558 put_gpr_dw0(r1, mkexpr(old_mem));
5559}
5560
5561static const HChar *
5562s390_irgen_LAA(UChar r1, UChar r3, IRTemp op2addr)
5563{
5564 s390_irgen_load_and_add32(r1, r3, op2addr, True /* is_signed */);
sewardj2019a972011-03-07 16:04:07 +00005565
5566 return "laa";
5567}
5568
florian55085f82012-11-21 00:36:55 +00005569static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005570s390_irgen_LAAG(UChar r1, UChar r3, IRTemp op2addr)
5571{
florianffc94012012-12-02 21:31:15 +00005572 s390_irgen_load_and_add64(r1, r3, op2addr, True /* is_signed */);
sewardj2019a972011-03-07 16:04:07 +00005573
5574 return "laag";
5575}
5576
florian55085f82012-11-21 00:36:55 +00005577static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005578s390_irgen_LAAL(UChar r1, UChar r3, IRTemp op2addr)
5579{
florianffc94012012-12-02 21:31:15 +00005580 s390_irgen_load_and_add32(r1, r3, op2addr, False /* is_signed */);
sewardj2019a972011-03-07 16:04:07 +00005581
5582 return "laal";
5583}
5584
florian55085f82012-11-21 00:36:55 +00005585static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005586s390_irgen_LAALG(UChar r1, UChar r3, IRTemp op2addr)
5587{
florianffc94012012-12-02 21:31:15 +00005588 s390_irgen_load_and_add64(r1, r3, op2addr, False /* is_signed */);
sewardj2019a972011-03-07 16:04:07 +00005589
5590 return "laalg";
5591}
5592
florian55085f82012-11-21 00:36:55 +00005593static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005594s390_irgen_LAN(UChar r1, UChar r3, IRTemp op2addr)
5595{
florianffc94012012-12-02 21:31:15 +00005596 s390_irgen_load_and_bitwise32(r1, r3, op2addr, Iop_And32);
sewardj2019a972011-03-07 16:04:07 +00005597
5598 return "lan";
5599}
5600
florian55085f82012-11-21 00:36:55 +00005601static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005602s390_irgen_LANG(UChar r1, UChar r3, IRTemp op2addr)
5603{
florianffc94012012-12-02 21:31:15 +00005604 s390_irgen_load_and_bitwise64(r1, r3, op2addr, Iop_And64);
sewardj2019a972011-03-07 16:04:07 +00005605
5606 return "lang";
5607}
5608
florian55085f82012-11-21 00:36:55 +00005609static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005610s390_irgen_LAX(UChar r1, UChar r3, IRTemp op2addr)
5611{
florianffc94012012-12-02 21:31:15 +00005612 s390_irgen_load_and_bitwise32(r1, r3, op2addr, Iop_Xor32);
sewardj2019a972011-03-07 16:04:07 +00005613
5614 return "lax";
5615}
5616
florian55085f82012-11-21 00:36:55 +00005617static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005618s390_irgen_LAXG(UChar r1, UChar r3, IRTemp op2addr)
5619{
florianffc94012012-12-02 21:31:15 +00005620 s390_irgen_load_and_bitwise64(r1, r3, op2addr, Iop_Xor64);
sewardj2019a972011-03-07 16:04:07 +00005621
5622 return "laxg";
5623}
5624
florian55085f82012-11-21 00:36:55 +00005625static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005626s390_irgen_LAO(UChar r1, UChar r3, IRTemp op2addr)
5627{
florianffc94012012-12-02 21:31:15 +00005628 s390_irgen_load_and_bitwise32(r1, r3, op2addr, Iop_Or32);
sewardj2019a972011-03-07 16:04:07 +00005629
5630 return "lao";
5631}
5632
florian55085f82012-11-21 00:36:55 +00005633static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005634s390_irgen_LAOG(UChar r1, UChar r3, IRTemp op2addr)
5635{
florianffc94012012-12-02 21:31:15 +00005636 s390_irgen_load_and_bitwise64(r1, r3, op2addr, Iop_Or64);
sewardj2019a972011-03-07 16:04:07 +00005637
5638 return "laog";
5639}
5640
florian55085f82012-11-21 00:36:55 +00005641static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005642s390_irgen_LTR(UChar r1, UChar r2)
5643{
5644 IRTemp op2 = newTemp(Ity_I32);
5645
5646 assign(op2, get_gpr_w1(r2));
5647 put_gpr_w1(r1, mkexpr(op2));
5648 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5649
5650 return "ltr";
5651}
5652
florian55085f82012-11-21 00:36:55 +00005653static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005654s390_irgen_LTGR(UChar r1, UChar r2)
5655{
5656 IRTemp op2 = newTemp(Ity_I64);
5657
5658 assign(op2, get_gpr_dw0(r2));
5659 put_gpr_dw0(r1, mkexpr(op2));
5660 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5661
5662 return "ltgr";
5663}
5664
florian55085f82012-11-21 00:36:55 +00005665static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005666s390_irgen_LTGFR(UChar r1, UChar r2)
5667{
5668 IRTemp op2 = newTemp(Ity_I64);
5669
5670 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
5671 put_gpr_dw0(r1, mkexpr(op2));
5672 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5673
5674 return "ltgfr";
5675}
5676
florian55085f82012-11-21 00:36:55 +00005677static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005678s390_irgen_LT(UChar r1, IRTemp op2addr)
5679{
5680 IRTemp op2 = newTemp(Ity_I32);
5681
5682 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5683 put_gpr_w1(r1, mkexpr(op2));
5684 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5685
5686 return "lt";
5687}
5688
florian55085f82012-11-21 00:36:55 +00005689static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005690s390_irgen_LTG(UChar r1, IRTemp op2addr)
5691{
5692 IRTemp op2 = newTemp(Ity_I64);
5693
5694 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5695 put_gpr_dw0(r1, mkexpr(op2));
5696 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5697
5698 return "ltg";
5699}
5700
florian55085f82012-11-21 00:36:55 +00005701static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005702s390_irgen_LTGF(UChar r1, IRTemp op2addr)
5703{
5704 IRTemp op2 = newTemp(Ity_I64);
5705
5706 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
5707 put_gpr_dw0(r1, mkexpr(op2));
5708 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5709
5710 return "ltgf";
5711}
5712
florian55085f82012-11-21 00:36:55 +00005713static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005714s390_irgen_LBR(UChar r1, UChar r2)
5715{
5716 put_gpr_w1(r1, unop(Iop_8Sto32, get_gpr_b7(r2)));
5717
5718 return "lbr";
5719}
5720
florian55085f82012-11-21 00:36:55 +00005721static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005722s390_irgen_LGBR(UChar r1, UChar r2)
5723{
5724 put_gpr_dw0(r1, unop(Iop_8Sto64, get_gpr_b7(r2)));
5725
5726 return "lgbr";
5727}
5728
florian55085f82012-11-21 00:36:55 +00005729static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005730s390_irgen_LB(UChar r1, IRTemp op2addr)
5731{
5732 put_gpr_w1(r1, unop(Iop_8Sto32, load(Ity_I8, mkexpr(op2addr))));
5733
5734 return "lb";
5735}
5736
florian55085f82012-11-21 00:36:55 +00005737static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005738s390_irgen_LGB(UChar r1, IRTemp op2addr)
5739{
5740 put_gpr_dw0(r1, unop(Iop_8Sto64, load(Ity_I8, mkexpr(op2addr))));
5741
5742 return "lgb";
5743}
5744
florian55085f82012-11-21 00:36:55 +00005745static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005746s390_irgen_LBH(UChar r1, IRTemp op2addr)
5747{
5748 put_gpr_w0(r1, unop(Iop_8Sto32, load(Ity_I8, mkexpr(op2addr))));
5749
5750 return "lbh";
5751}
5752
florian55085f82012-11-21 00:36:55 +00005753static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005754s390_irgen_LCR(UChar r1, UChar r2)
5755{
5756 Int op1;
5757 IRTemp op2 = newTemp(Ity_I32);
5758 IRTemp result = newTemp(Ity_I32);
5759
5760 op1 = 0;
5761 assign(op2, get_gpr_w1(r2));
5762 assign(result, binop(Iop_Sub32, mkU32((UInt)op1), mkexpr(op2)));
5763 put_gpr_w1(r1, mkexpr(result));
5764 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, mktemp(Ity_I32, mkU32((UInt)
5765 op1)), op2);
5766
5767 return "lcr";
5768}
5769
florian55085f82012-11-21 00:36:55 +00005770static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005771s390_irgen_LCGR(UChar r1, UChar r2)
5772{
5773 Long op1;
5774 IRTemp op2 = newTemp(Ity_I64);
5775 IRTemp result = newTemp(Ity_I64);
5776
5777 op1 = 0ULL;
5778 assign(op2, get_gpr_dw0(r2));
5779 assign(result, binop(Iop_Sub64, mkU64((ULong)op1), mkexpr(op2)));
5780 put_gpr_dw0(r1, mkexpr(result));
5781 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, mktemp(Ity_I64, mkU64((ULong)
5782 op1)), op2);
5783
5784 return "lcgr";
5785}
5786
florian55085f82012-11-21 00:36:55 +00005787static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005788s390_irgen_LCGFR(UChar r1, UChar r2)
5789{
5790 Long op1;
5791 IRTemp op2 = newTemp(Ity_I64);
5792 IRTemp result = newTemp(Ity_I64);
5793
5794 op1 = 0ULL;
5795 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
5796 assign(result, binop(Iop_Sub64, mkU64((ULong)op1), mkexpr(op2)));
5797 put_gpr_dw0(r1, mkexpr(result));
5798 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, mktemp(Ity_I64, mkU64((ULong)
5799 op1)), op2);
5800
5801 return "lcgfr";
5802}
5803
florian55085f82012-11-21 00:36:55 +00005804static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005805s390_irgen_LHR(UChar r1, UChar r2)
5806{
5807 put_gpr_w1(r1, unop(Iop_16Sto32, get_gpr_hw3(r2)));
5808
5809 return "lhr";
5810}
5811
florian55085f82012-11-21 00:36:55 +00005812static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005813s390_irgen_LGHR(UChar r1, UChar r2)
5814{
5815 put_gpr_dw0(r1, unop(Iop_16Sto64, get_gpr_hw3(r2)));
5816
5817 return "lghr";
5818}
5819
florian55085f82012-11-21 00:36:55 +00005820static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005821s390_irgen_LH(UChar r1, IRTemp op2addr)
5822{
5823 put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
5824
5825 return "lh";
5826}
5827
florian55085f82012-11-21 00:36:55 +00005828static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005829s390_irgen_LHY(UChar r1, IRTemp op2addr)
5830{
5831 put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
5832
5833 return "lhy";
5834}
5835
florian55085f82012-11-21 00:36:55 +00005836static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005837s390_irgen_LGH(UChar r1, IRTemp op2addr)
5838{
5839 put_gpr_dw0(r1, unop(Iop_16Sto64, load(Ity_I16, mkexpr(op2addr))));
5840
5841 return "lgh";
5842}
5843
florian55085f82012-11-21 00:36:55 +00005844static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005845s390_irgen_LHI(UChar r1, UShort i2)
5846{
5847 put_gpr_w1(r1, mkU32((UInt)(Int)(Short)i2));
5848
5849 return "lhi";
5850}
5851
florian55085f82012-11-21 00:36:55 +00005852static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005853s390_irgen_LGHI(UChar r1, UShort i2)
5854{
5855 put_gpr_dw0(r1, mkU64((ULong)(Long)(Short)i2));
5856
5857 return "lghi";
5858}
5859
florian55085f82012-11-21 00:36:55 +00005860static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005861s390_irgen_LHRL(UChar r1, UInt i2)
5862{
5863 put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
5864 ((ULong)(Long)(Int)i2 << 1)))));
5865
5866 return "lhrl";
5867}
5868
florian55085f82012-11-21 00:36:55 +00005869static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005870s390_irgen_LGHRL(UChar r1, UInt i2)
5871{
5872 put_gpr_dw0(r1, unop(Iop_16Sto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
5873 ((ULong)(Long)(Int)i2 << 1)))));
5874
5875 return "lghrl";
5876}
5877
florian55085f82012-11-21 00:36:55 +00005878static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005879s390_irgen_LHH(UChar r1, IRTemp op2addr)
5880{
5881 put_gpr_w0(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
5882
5883 return "lhh";
5884}
5885
florian55085f82012-11-21 00:36:55 +00005886static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005887s390_irgen_LFH(UChar r1, IRTemp op2addr)
5888{
5889 put_gpr_w0(r1, load(Ity_I32, mkexpr(op2addr)));
5890
5891 return "lfh";
5892}
5893
florian55085f82012-11-21 00:36:55 +00005894static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005895s390_irgen_LLGFR(UChar r1, UChar r2)
5896{
5897 put_gpr_dw0(r1, unop(Iop_32Uto64, get_gpr_w1(r2)));
5898
5899 return "llgfr";
5900}
5901
florian55085f82012-11-21 00:36:55 +00005902static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005903s390_irgen_LLGF(UChar r1, IRTemp op2addr)
5904{
5905 put_gpr_dw0(r1, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
5906
5907 return "llgf";
5908}
5909
florian55085f82012-11-21 00:36:55 +00005910static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005911s390_irgen_LLGFRL(UChar r1, UInt i2)
5912{
5913 put_gpr_dw0(r1, unop(Iop_32Uto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
5914 ((ULong)(Long)(Int)i2 << 1)))));
5915
5916 return "llgfrl";
5917}
5918
florian55085f82012-11-21 00:36:55 +00005919static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005920s390_irgen_LLCR(UChar r1, UChar r2)
5921{
5922 put_gpr_w1(r1, unop(Iop_8Uto32, get_gpr_b7(r2)));
5923
5924 return "llcr";
5925}
5926
florian55085f82012-11-21 00:36:55 +00005927static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005928s390_irgen_LLGCR(UChar r1, UChar r2)
5929{
5930 put_gpr_dw0(r1, unop(Iop_8Uto64, get_gpr_b7(r2)));
5931
5932 return "llgcr";
5933}
5934
florian55085f82012-11-21 00:36:55 +00005935static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005936s390_irgen_LLC(UChar r1, IRTemp op2addr)
5937{
5938 put_gpr_w1(r1, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
5939
5940 return "llc";
5941}
5942
florian55085f82012-11-21 00:36:55 +00005943static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005944s390_irgen_LLGC(UChar r1, IRTemp op2addr)
5945{
5946 put_gpr_dw0(r1, unop(Iop_8Uto64, load(Ity_I8, mkexpr(op2addr))));
5947
5948 return "llgc";
5949}
5950
florian55085f82012-11-21 00:36:55 +00005951static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005952s390_irgen_LLCH(UChar r1, IRTemp op2addr)
5953{
5954 put_gpr_w0(r1, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
5955
5956 return "llch";
5957}
5958
florian55085f82012-11-21 00:36:55 +00005959static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005960s390_irgen_LLHR(UChar r1, UChar r2)
5961{
5962 put_gpr_w1(r1, unop(Iop_16Uto32, get_gpr_hw3(r2)));
5963
5964 return "llhr";
5965}
5966
florian55085f82012-11-21 00:36:55 +00005967static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005968s390_irgen_LLGHR(UChar r1, UChar r2)
5969{
5970 put_gpr_dw0(r1, unop(Iop_16Uto64, get_gpr_hw3(r2)));
5971
5972 return "llghr";
5973}
5974
florian55085f82012-11-21 00:36:55 +00005975static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005976s390_irgen_LLH(UChar r1, IRTemp op2addr)
5977{
5978 put_gpr_w1(r1, unop(Iop_16Uto32, load(Ity_I16, mkexpr(op2addr))));
5979
5980 return "llh";
5981}
5982
florian55085f82012-11-21 00:36:55 +00005983static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005984s390_irgen_LLGH(UChar r1, IRTemp op2addr)
5985{
5986 put_gpr_dw0(r1, unop(Iop_16Uto64, load(Ity_I16, mkexpr(op2addr))));
5987
5988 return "llgh";
5989}
5990
florian55085f82012-11-21 00:36:55 +00005991static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005992s390_irgen_LLHRL(UChar r1, UInt i2)
5993{
5994 put_gpr_w1(r1, unop(Iop_16Uto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
5995 ((ULong)(Long)(Int)i2 << 1)))));
5996
5997 return "llhrl";
5998}
5999
florian55085f82012-11-21 00:36:55 +00006000static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006001s390_irgen_LLGHRL(UChar r1, UInt i2)
6002{
6003 put_gpr_dw0(r1, unop(Iop_16Uto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
6004 ((ULong)(Long)(Int)i2 << 1)))));
6005
6006 return "llghrl";
6007}
6008
florian55085f82012-11-21 00:36:55 +00006009static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006010s390_irgen_LLHH(UChar r1, IRTemp op2addr)
6011{
6012 put_gpr_w0(r1, unop(Iop_16Uto32, load(Ity_I16, mkexpr(op2addr))));
6013
6014 return "llhh";
6015}
6016
florian55085f82012-11-21 00:36:55 +00006017static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006018s390_irgen_LLIHF(UChar r1, UInt i2)
6019{
6020 put_gpr_dw0(r1, mkU64(((ULong)i2) << 32));
6021
6022 return "llihf";
6023}
6024
florian55085f82012-11-21 00:36:55 +00006025static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006026s390_irgen_LLIHH(UChar r1, UShort i2)
6027{
6028 put_gpr_dw0(r1, mkU64(((ULong)i2) << 48));
6029
6030 return "llihh";
6031}
6032
florian55085f82012-11-21 00:36:55 +00006033static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006034s390_irgen_LLIHL(UChar r1, UShort i2)
6035{
6036 put_gpr_dw0(r1, mkU64(((ULong)i2) << 32));
6037
6038 return "llihl";
6039}
6040
florian55085f82012-11-21 00:36:55 +00006041static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006042s390_irgen_LLILF(UChar r1, UInt i2)
6043{
6044 put_gpr_dw0(r1, mkU64(i2));
6045
6046 return "llilf";
6047}
6048
florian55085f82012-11-21 00:36:55 +00006049static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006050s390_irgen_LLILH(UChar r1, UShort i2)
6051{
6052 put_gpr_dw0(r1, mkU64(((ULong)i2) << 16));
6053
6054 return "llilh";
6055}
6056
florian55085f82012-11-21 00:36:55 +00006057static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006058s390_irgen_LLILL(UChar r1, UShort i2)
6059{
6060 put_gpr_dw0(r1, mkU64(i2));
6061
6062 return "llill";
6063}
6064
florian55085f82012-11-21 00:36:55 +00006065static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006066s390_irgen_LLGTR(UChar r1, UChar r2)
6067{
6068 put_gpr_dw0(r1, unop(Iop_32Uto64, binop(Iop_And32, get_gpr_w1(r2),
6069 mkU32(2147483647))));
6070
6071 return "llgtr";
6072}
6073
florian55085f82012-11-21 00:36:55 +00006074static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006075s390_irgen_LLGT(UChar r1, IRTemp op2addr)
6076{
6077 put_gpr_dw0(r1, unop(Iop_32Uto64, binop(Iop_And32, load(Ity_I32,
6078 mkexpr(op2addr)), mkU32(2147483647))));
6079
6080 return "llgt";
6081}
6082
florian55085f82012-11-21 00:36:55 +00006083static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006084s390_irgen_LNR(UChar r1, UChar r2)
6085{
6086 IRTemp op2 = newTemp(Ity_I32);
6087 IRTemp result = newTemp(Ity_I32);
6088
6089 assign(op2, get_gpr_w1(r2));
6090 assign(result, mkite(binop(Iop_CmpLE32S, mkexpr(op2), mkU32(0)), mkexpr(op2),
6091 binop(Iop_Sub32, mkU32(0), mkexpr(op2))));
6092 put_gpr_w1(r1, mkexpr(result));
6093 s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
6094
6095 return "lnr";
6096}
6097
florian55085f82012-11-21 00:36:55 +00006098static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006099s390_irgen_LNGR(UChar r1, UChar r2)
6100{
6101 IRTemp op2 = newTemp(Ity_I64);
6102 IRTemp result = newTemp(Ity_I64);
6103
6104 assign(op2, get_gpr_dw0(r2));
6105 assign(result, mkite(binop(Iop_CmpLE64S, mkexpr(op2), mkU64(0)), mkexpr(op2),
6106 binop(Iop_Sub64, mkU64(0), mkexpr(op2))));
6107 put_gpr_dw0(r1, mkexpr(result));
6108 s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
6109
6110 return "lngr";
6111}
6112
florian55085f82012-11-21 00:36:55 +00006113static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006114s390_irgen_LNGFR(UChar r1, UChar r2 __attribute__((unused)))
6115{
6116 IRTemp op2 = newTemp(Ity_I64);
6117 IRTemp result = newTemp(Ity_I64);
6118
6119 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r1)));
6120 assign(result, mkite(binop(Iop_CmpLE64S, mkexpr(op2), mkU64(0)), mkexpr(op2),
6121 binop(Iop_Sub64, mkU64(0), mkexpr(op2))));
6122 put_gpr_dw0(r1, mkexpr(result));
6123 s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
6124
6125 return "lngfr";
6126}
6127
florian55085f82012-11-21 00:36:55 +00006128static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00006129s390_irgen_LOCR(UChar m3, UChar r1, UChar r2)
6130{
florian6820ba52012-07-26 02:01:50 +00006131 next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
sewardjd7bde722011-04-05 13:19:33 +00006132 put_gpr_w1(r1, get_gpr_w1(r2));
6133
6134 return "locr";
6135}
6136
florian55085f82012-11-21 00:36:55 +00006137static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00006138s390_irgen_LOCGR(UChar m3, UChar r1, UChar r2)
6139{
florian6820ba52012-07-26 02:01:50 +00006140 next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
sewardjd7bde722011-04-05 13:19:33 +00006141 put_gpr_dw0(r1, get_gpr_dw0(r2));
6142
6143 return "locgr";
6144}
6145
florian55085f82012-11-21 00:36:55 +00006146static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00006147s390_irgen_LOC(UChar r1, IRTemp op2addr)
6148{
6149 /* condition is checked in format handler */
6150 put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
6151
6152 return "loc";
6153}
6154
florian55085f82012-11-21 00:36:55 +00006155static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00006156s390_irgen_LOCG(UChar r1, IRTemp op2addr)
6157{
6158 /* condition is checked in format handler */
6159 put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
6160
6161 return "locg";
6162}
6163
florian55085f82012-11-21 00:36:55 +00006164static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006165s390_irgen_LPQ(UChar r1, IRTemp op2addr)
6166{
6167 put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
6168 put_gpr_dw0(r1 + 1, load(Ity_I64, binop(Iop_Add64, mkexpr(op2addr), mkU64(8))
6169 ));
6170
6171 return "lpq";
6172}
6173
florian55085f82012-11-21 00:36:55 +00006174static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006175s390_irgen_LPR(UChar r1, UChar r2)
6176{
6177 IRTemp op2 = newTemp(Ity_I32);
6178 IRTemp result = newTemp(Ity_I32);
6179
6180 assign(op2, get_gpr_w1(r2));
6181 assign(result, mkite(binop(Iop_CmpLT32S, mkexpr(op2), mkU32(0)),
6182 binop(Iop_Sub32, mkU32(0), mkexpr(op2)), mkexpr(op2)));
6183 put_gpr_w1(r1, mkexpr(result));
6184 s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_32, op2);
6185
6186 return "lpr";
6187}
6188
florian55085f82012-11-21 00:36:55 +00006189static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006190s390_irgen_LPGR(UChar r1, UChar r2)
6191{
6192 IRTemp op2 = newTemp(Ity_I64);
6193 IRTemp result = newTemp(Ity_I64);
6194
6195 assign(op2, get_gpr_dw0(r2));
6196 assign(result, mkite(binop(Iop_CmpLT64S, mkexpr(op2), mkU64(0)),
6197 binop(Iop_Sub64, mkU64(0), mkexpr(op2)), mkexpr(op2)));
6198 put_gpr_dw0(r1, mkexpr(result));
6199 s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_64, op2);
6200
6201 return "lpgr";
6202}
6203
florian55085f82012-11-21 00:36:55 +00006204static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006205s390_irgen_LPGFR(UChar r1, UChar r2)
6206{
6207 IRTemp op2 = newTemp(Ity_I64);
6208 IRTemp result = newTemp(Ity_I64);
6209
6210 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
6211 assign(result, mkite(binop(Iop_CmpLT64S, mkexpr(op2), mkU64(0)),
6212 binop(Iop_Sub64, mkU64(0), mkexpr(op2)), mkexpr(op2)));
6213 put_gpr_dw0(r1, mkexpr(result));
6214 s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_64, op2);
6215
6216 return "lpgfr";
6217}
6218
florian55085f82012-11-21 00:36:55 +00006219static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006220s390_irgen_LRVR(UChar r1, UChar r2)
6221{
6222 IRTemp b0 = newTemp(Ity_I8);
6223 IRTemp b1 = newTemp(Ity_I8);
6224 IRTemp b2 = newTemp(Ity_I8);
6225 IRTemp b3 = newTemp(Ity_I8);
6226
6227 assign(b3, get_gpr_b7(r2));
6228 assign(b2, get_gpr_b6(r2));
6229 assign(b1, get_gpr_b5(r2));
6230 assign(b0, get_gpr_b4(r2));
6231 put_gpr_b4(r1, mkexpr(b3));
6232 put_gpr_b5(r1, mkexpr(b2));
6233 put_gpr_b6(r1, mkexpr(b1));
6234 put_gpr_b7(r1, mkexpr(b0));
6235
6236 return "lrvr";
6237}
6238
florian55085f82012-11-21 00:36:55 +00006239static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006240s390_irgen_LRVGR(UChar r1, UChar r2)
6241{
6242 IRTemp b0 = newTemp(Ity_I8);
6243 IRTemp b1 = newTemp(Ity_I8);
6244 IRTemp b2 = newTemp(Ity_I8);
6245 IRTemp b3 = newTemp(Ity_I8);
6246 IRTemp b4 = newTemp(Ity_I8);
6247 IRTemp b5 = newTemp(Ity_I8);
6248 IRTemp b6 = newTemp(Ity_I8);
6249 IRTemp b7 = newTemp(Ity_I8);
6250
6251 assign(b7, get_gpr_b7(r2));
6252 assign(b6, get_gpr_b6(r2));
6253 assign(b5, get_gpr_b5(r2));
6254 assign(b4, get_gpr_b4(r2));
6255 assign(b3, get_gpr_b3(r2));
6256 assign(b2, get_gpr_b2(r2));
6257 assign(b1, get_gpr_b1(r2));
6258 assign(b0, get_gpr_b0(r2));
6259 put_gpr_b0(r1, mkexpr(b7));
6260 put_gpr_b1(r1, mkexpr(b6));
6261 put_gpr_b2(r1, mkexpr(b5));
6262 put_gpr_b3(r1, mkexpr(b4));
6263 put_gpr_b4(r1, mkexpr(b3));
6264 put_gpr_b5(r1, mkexpr(b2));
6265 put_gpr_b6(r1, mkexpr(b1));
6266 put_gpr_b7(r1, mkexpr(b0));
6267
6268 return "lrvgr";
6269}
6270
florian55085f82012-11-21 00:36:55 +00006271static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006272s390_irgen_LRVH(UChar r1, IRTemp op2addr)
6273{
6274 IRTemp op2 = newTemp(Ity_I16);
6275
6276 assign(op2, load(Ity_I16, mkexpr(op2addr)));
6277 put_gpr_b6(r1, unop(Iop_16to8, mkexpr(op2)));
6278 put_gpr_b7(r1, unop(Iop_16HIto8, mkexpr(op2)));
6279
6280 return "lrvh";
6281}
6282
florian55085f82012-11-21 00:36:55 +00006283static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006284s390_irgen_LRV(UChar r1, IRTemp op2addr)
6285{
6286 IRTemp op2 = newTemp(Ity_I32);
6287
6288 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6289 put_gpr_b4(r1, unop(Iop_32to8, binop(Iop_And32, mkexpr(op2), mkU32(255))));
6290 put_gpr_b5(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
6291 mkU8(8)), mkU32(255))));
6292 put_gpr_b6(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
6293 mkU8(16)), mkU32(255))));
6294 put_gpr_b7(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
6295 mkU8(24)), mkU32(255))));
6296
6297 return "lrv";
6298}
6299
florian55085f82012-11-21 00:36:55 +00006300static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006301s390_irgen_LRVG(UChar r1, IRTemp op2addr)
6302{
6303 IRTemp op2 = newTemp(Ity_I64);
6304
6305 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6306 put_gpr_b0(r1, unop(Iop_64to8, binop(Iop_And64, mkexpr(op2), mkU64(255))));
6307 put_gpr_b1(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6308 mkU8(8)), mkU64(255))));
6309 put_gpr_b2(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6310 mkU8(16)), mkU64(255))));
6311 put_gpr_b3(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6312 mkU8(24)), mkU64(255))));
6313 put_gpr_b4(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6314 mkU8(32)), mkU64(255))));
6315 put_gpr_b5(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6316 mkU8(40)), mkU64(255))));
6317 put_gpr_b6(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6318 mkU8(48)), mkU64(255))));
6319 put_gpr_b7(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6320 mkU8(56)), mkU64(255))));
6321
6322 return "lrvg";
6323}
6324
florian55085f82012-11-21 00:36:55 +00006325static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006326s390_irgen_MVHHI(UShort i2, IRTemp op1addr)
6327{
6328 store(mkexpr(op1addr), mkU16(i2));
6329
6330 return "mvhhi";
6331}
6332
florian55085f82012-11-21 00:36:55 +00006333static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006334s390_irgen_MVHI(UShort i2, IRTemp op1addr)
6335{
6336 store(mkexpr(op1addr), mkU32((UInt)(Int)(Short)i2));
6337
6338 return "mvhi";
6339}
6340
florian55085f82012-11-21 00:36:55 +00006341static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006342s390_irgen_MVGHI(UShort i2, IRTemp op1addr)
6343{
6344 store(mkexpr(op1addr), mkU64((ULong)(Long)(Short)i2));
6345
6346 return "mvghi";
6347}
6348
florian55085f82012-11-21 00:36:55 +00006349static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006350s390_irgen_MVI(UChar i2, IRTemp op1addr)
6351{
6352 store(mkexpr(op1addr), mkU8(i2));
6353
6354 return "mvi";
6355}
6356
florian55085f82012-11-21 00:36:55 +00006357static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006358s390_irgen_MVIY(UChar i2, IRTemp op1addr)
6359{
6360 store(mkexpr(op1addr), mkU8(i2));
6361
6362 return "mviy";
6363}
6364
florian55085f82012-11-21 00:36:55 +00006365static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006366s390_irgen_MR(UChar r1, UChar r2)
6367{
6368 IRTemp op1 = newTemp(Ity_I32);
6369 IRTemp op2 = newTemp(Ity_I32);
6370 IRTemp result = newTemp(Ity_I64);
6371
6372 assign(op1, get_gpr_w1(r1 + 1));
6373 assign(op2, get_gpr_w1(r2));
6374 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6375 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6376 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6377
6378 return "mr";
6379}
6380
florian55085f82012-11-21 00:36:55 +00006381static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006382s390_irgen_M(UChar r1, IRTemp op2addr)
6383{
6384 IRTemp op1 = newTemp(Ity_I32);
6385 IRTemp op2 = newTemp(Ity_I32);
6386 IRTemp result = newTemp(Ity_I64);
6387
6388 assign(op1, get_gpr_w1(r1 + 1));
6389 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6390 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6391 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6392 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6393
6394 return "m";
6395}
6396
florian55085f82012-11-21 00:36:55 +00006397static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006398s390_irgen_MFY(UChar r1, IRTemp op2addr)
6399{
6400 IRTemp op1 = newTemp(Ity_I32);
6401 IRTemp op2 = newTemp(Ity_I32);
6402 IRTemp result = newTemp(Ity_I64);
6403
6404 assign(op1, get_gpr_w1(r1 + 1));
6405 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6406 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6407 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6408 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6409
6410 return "mfy";
6411}
6412
florian55085f82012-11-21 00:36:55 +00006413static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006414s390_irgen_MH(UChar r1, IRTemp op2addr)
6415{
6416 IRTemp op1 = newTemp(Ity_I32);
6417 IRTemp op2 = newTemp(Ity_I16);
6418 IRTemp result = newTemp(Ity_I64);
6419
6420 assign(op1, get_gpr_w1(r1));
6421 assign(op2, load(Ity_I16, mkexpr(op2addr)));
6422 assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32, mkexpr(op2))
6423 ));
6424 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6425
6426 return "mh";
6427}
6428
florian55085f82012-11-21 00:36:55 +00006429static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006430s390_irgen_MHY(UChar r1, IRTemp op2addr)
6431{
6432 IRTemp op1 = newTemp(Ity_I32);
6433 IRTemp op2 = newTemp(Ity_I16);
6434 IRTemp result = newTemp(Ity_I64);
6435
6436 assign(op1, get_gpr_w1(r1));
6437 assign(op2, load(Ity_I16, mkexpr(op2addr)));
6438 assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32, mkexpr(op2))
6439 ));
6440 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6441
6442 return "mhy";
6443}
6444
florian55085f82012-11-21 00:36:55 +00006445static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006446s390_irgen_MHI(UChar r1, UShort i2)
6447{
6448 IRTemp op1 = newTemp(Ity_I32);
6449 Short op2;
6450 IRTemp result = newTemp(Ity_I64);
6451
6452 assign(op1, get_gpr_w1(r1));
6453 op2 = (Short)i2;
6454 assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32,
6455 mkU16((UShort)op2))));
6456 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6457
6458 return "mhi";
6459}
6460
florian55085f82012-11-21 00:36:55 +00006461static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006462s390_irgen_MGHI(UChar r1, UShort i2)
6463{
6464 IRTemp op1 = newTemp(Ity_I64);
6465 Short op2;
6466 IRTemp result = newTemp(Ity_I128);
6467
6468 assign(op1, get_gpr_dw0(r1));
6469 op2 = (Short)i2;
6470 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_16Sto64,
6471 mkU16((UShort)op2))));
6472 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6473
6474 return "mghi";
6475}
6476
florian55085f82012-11-21 00:36:55 +00006477static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006478s390_irgen_MLR(UChar r1, UChar r2)
6479{
6480 IRTemp op1 = newTemp(Ity_I32);
6481 IRTemp op2 = newTemp(Ity_I32);
6482 IRTemp result = newTemp(Ity_I64);
6483
6484 assign(op1, get_gpr_w1(r1 + 1));
6485 assign(op2, get_gpr_w1(r2));
6486 assign(result, binop(Iop_MullU32, mkexpr(op1), mkexpr(op2)));
6487 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6488 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6489
6490 return "mlr";
6491}
6492
florian55085f82012-11-21 00:36:55 +00006493static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006494s390_irgen_MLGR(UChar r1, UChar r2)
6495{
6496 IRTemp op1 = newTemp(Ity_I64);
6497 IRTemp op2 = newTemp(Ity_I64);
6498 IRTemp result = newTemp(Ity_I128);
6499
6500 assign(op1, get_gpr_dw0(r1 + 1));
6501 assign(op2, get_gpr_dw0(r2));
6502 assign(result, binop(Iop_MullU64, mkexpr(op1), mkexpr(op2)));
6503 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result)));
6504 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result)));
6505
6506 return "mlgr";
6507}
6508
florian55085f82012-11-21 00:36:55 +00006509static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006510s390_irgen_ML(UChar r1, IRTemp op2addr)
6511{
6512 IRTemp op1 = newTemp(Ity_I32);
6513 IRTemp op2 = newTemp(Ity_I32);
6514 IRTemp result = newTemp(Ity_I64);
6515
6516 assign(op1, get_gpr_w1(r1 + 1));
6517 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6518 assign(result, binop(Iop_MullU32, mkexpr(op1), mkexpr(op2)));
6519 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6520 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6521
6522 return "ml";
6523}
6524
florian55085f82012-11-21 00:36:55 +00006525static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006526s390_irgen_MLG(UChar r1, IRTemp op2addr)
6527{
6528 IRTemp op1 = newTemp(Ity_I64);
6529 IRTemp op2 = newTemp(Ity_I64);
6530 IRTemp result = newTemp(Ity_I128);
6531
6532 assign(op1, get_gpr_dw0(r1 + 1));
6533 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6534 assign(result, binop(Iop_MullU64, mkexpr(op1), mkexpr(op2)));
6535 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result)));
6536 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result)));
6537
6538 return "mlg";
6539}
6540
florian55085f82012-11-21 00:36:55 +00006541static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006542s390_irgen_MSR(UChar r1, UChar r2)
6543{
6544 IRTemp op1 = newTemp(Ity_I32);
6545 IRTemp op2 = newTemp(Ity_I32);
6546 IRTemp result = newTemp(Ity_I64);
6547
6548 assign(op1, get_gpr_w1(r1));
6549 assign(op2, get_gpr_w1(r2));
6550 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6551 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6552
6553 return "msr";
6554}
6555
florian55085f82012-11-21 00:36:55 +00006556static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006557s390_irgen_MSGR(UChar r1, UChar r2)
6558{
6559 IRTemp op1 = newTemp(Ity_I64);
6560 IRTemp op2 = newTemp(Ity_I64);
6561 IRTemp result = newTemp(Ity_I128);
6562
6563 assign(op1, get_gpr_dw0(r1));
6564 assign(op2, get_gpr_dw0(r2));
6565 assign(result, binop(Iop_MullS64, mkexpr(op1), mkexpr(op2)));
6566 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6567
6568 return "msgr";
6569}
6570
florian55085f82012-11-21 00:36:55 +00006571static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006572s390_irgen_MSGFR(UChar r1, UChar r2)
6573{
6574 IRTemp op1 = newTemp(Ity_I64);
6575 IRTemp op2 = newTemp(Ity_I32);
6576 IRTemp result = newTemp(Ity_I128);
6577
6578 assign(op1, get_gpr_dw0(r1));
6579 assign(op2, get_gpr_w1(r2));
6580 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkexpr(op2))
6581 ));
6582 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6583
6584 return "msgfr";
6585}
6586
florian55085f82012-11-21 00:36:55 +00006587static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006588s390_irgen_MS(UChar r1, IRTemp op2addr)
6589{
6590 IRTemp op1 = newTemp(Ity_I32);
6591 IRTemp op2 = newTemp(Ity_I32);
6592 IRTemp result = newTemp(Ity_I64);
6593
6594 assign(op1, get_gpr_w1(r1));
6595 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6596 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6597 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6598
6599 return "ms";
6600}
6601
florian55085f82012-11-21 00:36:55 +00006602static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006603s390_irgen_MSY(UChar r1, IRTemp op2addr)
6604{
6605 IRTemp op1 = newTemp(Ity_I32);
6606 IRTemp op2 = newTemp(Ity_I32);
6607 IRTemp result = newTemp(Ity_I64);
6608
6609 assign(op1, get_gpr_w1(r1));
6610 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6611 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6612 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6613
6614 return "msy";
6615}
6616
florian55085f82012-11-21 00:36:55 +00006617static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006618s390_irgen_MSG(UChar r1, IRTemp op2addr)
6619{
6620 IRTemp op1 = newTemp(Ity_I64);
6621 IRTemp op2 = newTemp(Ity_I64);
6622 IRTemp result = newTemp(Ity_I128);
6623
6624 assign(op1, get_gpr_dw0(r1));
6625 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6626 assign(result, binop(Iop_MullS64, mkexpr(op1), mkexpr(op2)));
6627 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6628
6629 return "msg";
6630}
6631
florian55085f82012-11-21 00:36:55 +00006632static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006633s390_irgen_MSGF(UChar r1, IRTemp op2addr)
6634{
6635 IRTemp op1 = newTemp(Ity_I64);
6636 IRTemp op2 = newTemp(Ity_I32);
6637 IRTemp result = newTemp(Ity_I128);
6638
6639 assign(op1, get_gpr_dw0(r1));
6640 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6641 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkexpr(op2))
6642 ));
6643 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6644
6645 return "msgf";
6646}
6647
florian55085f82012-11-21 00:36:55 +00006648static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006649s390_irgen_MSFI(UChar r1, UInt i2)
6650{
6651 IRTemp op1 = newTemp(Ity_I32);
6652 Int op2;
6653 IRTemp result = newTemp(Ity_I64);
6654
6655 assign(op1, get_gpr_w1(r1));
6656 op2 = (Int)i2;
6657 assign(result, binop(Iop_MullS32, mkexpr(op1), mkU32((UInt)op2)));
6658 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6659
6660 return "msfi";
6661}
6662
florian55085f82012-11-21 00:36:55 +00006663static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006664s390_irgen_MSGFI(UChar r1, UInt i2)
6665{
6666 IRTemp op1 = newTemp(Ity_I64);
6667 Int op2;
6668 IRTemp result = newTemp(Ity_I128);
6669
6670 assign(op1, get_gpr_dw0(r1));
6671 op2 = (Int)i2;
6672 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkU32((UInt)
6673 op2))));
6674 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6675
6676 return "msgfi";
6677}
6678
florian55085f82012-11-21 00:36:55 +00006679static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006680s390_irgen_OR(UChar r1, UChar r2)
6681{
6682 IRTemp op1 = newTemp(Ity_I32);
6683 IRTemp op2 = newTemp(Ity_I32);
6684 IRTemp result = newTemp(Ity_I32);
6685
6686 assign(op1, get_gpr_w1(r1));
6687 assign(op2, get_gpr_w1(r2));
6688 assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
6689 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6690 put_gpr_w1(r1, mkexpr(result));
6691
6692 return "or";
6693}
6694
florian55085f82012-11-21 00:36:55 +00006695static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006696s390_irgen_OGR(UChar r1, UChar r2)
6697{
6698 IRTemp op1 = newTemp(Ity_I64);
6699 IRTemp op2 = newTemp(Ity_I64);
6700 IRTemp result = newTemp(Ity_I64);
6701
6702 assign(op1, get_gpr_dw0(r1));
6703 assign(op2, get_gpr_dw0(r2));
6704 assign(result, binop(Iop_Or64, mkexpr(op1), mkexpr(op2)));
6705 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6706 put_gpr_dw0(r1, mkexpr(result));
6707
6708 return "ogr";
6709}
6710
florian55085f82012-11-21 00:36:55 +00006711static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006712s390_irgen_ORK(UChar r3, UChar r1, UChar r2)
6713{
6714 IRTemp op2 = newTemp(Ity_I32);
6715 IRTemp op3 = newTemp(Ity_I32);
6716 IRTemp result = newTemp(Ity_I32);
6717
6718 assign(op2, get_gpr_w1(r2));
6719 assign(op3, get_gpr_w1(r3));
6720 assign(result, binop(Iop_Or32, mkexpr(op2), mkexpr(op3)));
6721 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6722 put_gpr_w1(r1, mkexpr(result));
6723
6724 return "ork";
6725}
6726
florian55085f82012-11-21 00:36:55 +00006727static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006728s390_irgen_OGRK(UChar r3, UChar r1, UChar r2)
6729{
6730 IRTemp op2 = newTemp(Ity_I64);
6731 IRTemp op3 = newTemp(Ity_I64);
6732 IRTemp result = newTemp(Ity_I64);
6733
6734 assign(op2, get_gpr_dw0(r2));
6735 assign(op3, get_gpr_dw0(r3));
6736 assign(result, binop(Iop_Or64, mkexpr(op2), mkexpr(op3)));
6737 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6738 put_gpr_dw0(r1, mkexpr(result));
6739
6740 return "ogrk";
6741}
6742
florian55085f82012-11-21 00:36:55 +00006743static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006744s390_irgen_O(UChar r1, IRTemp op2addr)
6745{
6746 IRTemp op1 = newTemp(Ity_I32);
6747 IRTemp op2 = newTemp(Ity_I32);
6748 IRTemp result = newTemp(Ity_I32);
6749
6750 assign(op1, get_gpr_w1(r1));
6751 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6752 assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
6753 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6754 put_gpr_w1(r1, mkexpr(result));
6755
6756 return "o";
6757}
6758
florian55085f82012-11-21 00:36:55 +00006759static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006760s390_irgen_OY(UChar r1, IRTemp op2addr)
6761{
6762 IRTemp op1 = newTemp(Ity_I32);
6763 IRTemp op2 = newTemp(Ity_I32);
6764 IRTemp result = newTemp(Ity_I32);
6765
6766 assign(op1, get_gpr_w1(r1));
6767 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6768 assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
6769 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6770 put_gpr_w1(r1, mkexpr(result));
6771
6772 return "oy";
6773}
6774
florian55085f82012-11-21 00:36:55 +00006775static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006776s390_irgen_OG(UChar r1, IRTemp op2addr)
6777{
6778 IRTemp op1 = newTemp(Ity_I64);
6779 IRTemp op2 = newTemp(Ity_I64);
6780 IRTemp result = newTemp(Ity_I64);
6781
6782 assign(op1, get_gpr_dw0(r1));
6783 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6784 assign(result, binop(Iop_Or64, mkexpr(op1), mkexpr(op2)));
6785 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6786 put_gpr_dw0(r1, mkexpr(result));
6787
6788 return "og";
6789}
6790
florian55085f82012-11-21 00:36:55 +00006791static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006792s390_irgen_OI(UChar i2, IRTemp op1addr)
6793{
6794 IRTemp op1 = newTemp(Ity_I8);
6795 UChar op2;
6796 IRTemp result = newTemp(Ity_I8);
6797
6798 assign(op1, load(Ity_I8, mkexpr(op1addr)));
6799 op2 = i2;
6800 assign(result, binop(Iop_Or8, mkexpr(op1), mkU8(op2)));
6801 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6802 store(mkexpr(op1addr), mkexpr(result));
6803
6804 return "oi";
6805}
6806
florian55085f82012-11-21 00:36:55 +00006807static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006808s390_irgen_OIY(UChar i2, IRTemp op1addr)
6809{
6810 IRTemp op1 = newTemp(Ity_I8);
6811 UChar op2;
6812 IRTemp result = newTemp(Ity_I8);
6813
6814 assign(op1, load(Ity_I8, mkexpr(op1addr)));
6815 op2 = i2;
6816 assign(result, binop(Iop_Or8, mkexpr(op1), mkU8(op2)));
6817 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6818 store(mkexpr(op1addr), mkexpr(result));
6819
6820 return "oiy";
6821}
6822
florian55085f82012-11-21 00:36:55 +00006823static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006824s390_irgen_OIHF(UChar r1, UInt i2)
6825{
6826 IRTemp op1 = newTemp(Ity_I32);
6827 UInt op2;
6828 IRTemp result = newTemp(Ity_I32);
6829
6830 assign(op1, get_gpr_w0(r1));
6831 op2 = i2;
6832 assign(result, binop(Iop_Or32, mkexpr(op1), mkU32(op2)));
6833 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6834 put_gpr_w0(r1, mkexpr(result));
6835
6836 return "oihf";
6837}
6838
florian55085f82012-11-21 00:36:55 +00006839static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006840s390_irgen_OIHH(UChar r1, UShort i2)
6841{
6842 IRTemp op1 = newTemp(Ity_I16);
6843 UShort op2;
6844 IRTemp result = newTemp(Ity_I16);
6845
6846 assign(op1, get_gpr_hw0(r1));
6847 op2 = i2;
6848 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
6849 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6850 put_gpr_hw0(r1, mkexpr(result));
6851
6852 return "oihh";
6853}
6854
florian55085f82012-11-21 00:36:55 +00006855static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006856s390_irgen_OIHL(UChar r1, UShort i2)
6857{
6858 IRTemp op1 = newTemp(Ity_I16);
6859 UShort op2;
6860 IRTemp result = newTemp(Ity_I16);
6861
6862 assign(op1, get_gpr_hw1(r1));
6863 op2 = i2;
6864 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
6865 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6866 put_gpr_hw1(r1, mkexpr(result));
6867
6868 return "oihl";
6869}
6870
florian55085f82012-11-21 00:36:55 +00006871static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006872s390_irgen_OILF(UChar r1, UInt i2)
6873{
6874 IRTemp op1 = newTemp(Ity_I32);
6875 UInt op2;
6876 IRTemp result = newTemp(Ity_I32);
6877
6878 assign(op1, get_gpr_w1(r1));
6879 op2 = i2;
6880 assign(result, binop(Iop_Or32, mkexpr(op1), mkU32(op2)));
6881 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6882 put_gpr_w1(r1, mkexpr(result));
6883
6884 return "oilf";
6885}
6886
florian55085f82012-11-21 00:36:55 +00006887static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006888s390_irgen_OILH(UChar r1, UShort i2)
6889{
6890 IRTemp op1 = newTemp(Ity_I16);
6891 UShort op2;
6892 IRTemp result = newTemp(Ity_I16);
6893
6894 assign(op1, get_gpr_hw2(r1));
6895 op2 = i2;
6896 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
6897 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6898 put_gpr_hw2(r1, mkexpr(result));
6899
6900 return "oilh";
6901}
6902
florian55085f82012-11-21 00:36:55 +00006903static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006904s390_irgen_OILL(UChar r1, UShort i2)
6905{
6906 IRTemp op1 = newTemp(Ity_I16);
6907 UShort op2;
6908 IRTemp result = newTemp(Ity_I16);
6909
6910 assign(op1, get_gpr_hw3(r1));
6911 op2 = i2;
6912 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
6913 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6914 put_gpr_hw3(r1, mkexpr(result));
6915
6916 return "oill";
6917}
6918
florian55085f82012-11-21 00:36:55 +00006919static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006920s390_irgen_PFD(void)
6921{
6922
6923 return "pfd";
6924}
6925
florian55085f82012-11-21 00:36:55 +00006926static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006927s390_irgen_PFDRL(void)
6928{
6929
6930 return "pfdrl";
6931}
6932
florian55085f82012-11-21 00:36:55 +00006933static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006934s390_irgen_RLL(UChar r1, UChar r3, IRTemp op2addr)
6935{
6936 IRTemp amount = newTemp(Ity_I64);
6937 IRTemp op = newTemp(Ity_I32);
6938
6939 assign(amount, binop(Iop_And64, mkexpr(op2addr), mkU64(31)));
6940 assign(op, get_gpr_w1(r3));
6941 put_gpr_w1(r1, binop(Iop_Or32, binop(Iop_Shl32, mkexpr(op), unop(Iop_64to8,
6942 mkexpr(amount))), binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8,
6943 binop(Iop_Sub64, mkU64(32), mkexpr(amount))))));
6944
6945 return "rll";
6946}
6947
florian55085f82012-11-21 00:36:55 +00006948static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006949s390_irgen_RLLG(UChar r1, UChar r3, IRTemp op2addr)
6950{
6951 IRTemp amount = newTemp(Ity_I64);
6952 IRTemp op = newTemp(Ity_I64);
6953
6954 assign(amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
6955 assign(op, get_gpr_dw0(r3));
6956 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(op), unop(Iop_64to8,
6957 mkexpr(amount))), binop(Iop_Shr64, mkexpr(op), unop(Iop_64to8,
6958 binop(Iop_Sub64, mkU64(64), mkexpr(amount))))));
6959
6960 return "rllg";
6961}
6962
florian55085f82012-11-21 00:36:55 +00006963static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006964s390_irgen_RNSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
6965{
6966 UChar from;
6967 UChar to;
6968 UChar rot;
6969 UChar t_bit;
6970 ULong mask;
6971 ULong maskc;
6972 IRTemp result = newTemp(Ity_I64);
6973 IRTemp op2 = newTemp(Ity_I64);
6974
6975 from = i3 & 63;
6976 to = i4 & 63;
6977 rot = i5 & 63;
6978 t_bit = i3 & 128;
6979 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
6980 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
6981 mkU8(64 - rot))));
6982 if (from <= to) {
6983 mask = ~0ULL;
6984 mask = (mask >> from) & (mask << (63 - to));
6985 maskc = ~mask;
6986 } else {
6987 maskc = ~0ULL;
6988 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
6989 mask = ~maskc;
6990 }
6991 assign(result, binop(Iop_And64, binop(Iop_And64, get_gpr_dw0(r1), mkexpr(op2)
6992 ), mkU64(mask)));
6993 if (t_bit == 0) {
6994 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
6995 mkU64(maskc)), mkexpr(result)));
6996 }
6997 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6998
6999 return "rnsbg";
7000}
7001
florian55085f82012-11-21 00:36:55 +00007002static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007003s390_irgen_RXSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
7004{
7005 UChar from;
7006 UChar to;
7007 UChar rot;
7008 UChar t_bit;
7009 ULong mask;
7010 ULong maskc;
7011 IRTemp result = newTemp(Ity_I64);
7012 IRTemp op2 = newTemp(Ity_I64);
7013
7014 from = i3 & 63;
7015 to = i4 & 63;
7016 rot = i5 & 63;
7017 t_bit = i3 & 128;
7018 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
7019 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
7020 mkU8(64 - rot))));
7021 if (from <= to) {
7022 mask = ~0ULL;
7023 mask = (mask >> from) & (mask << (63 - to));
7024 maskc = ~mask;
7025 } else {
7026 maskc = ~0ULL;
7027 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
7028 mask = ~maskc;
7029 }
7030 assign(result, binop(Iop_And64, binop(Iop_Xor64, get_gpr_dw0(r1), mkexpr(op2)
7031 ), mkU64(mask)));
7032 if (t_bit == 0) {
7033 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
7034 mkU64(maskc)), mkexpr(result)));
7035 }
7036 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7037
7038 return "rxsbg";
7039}
7040
florian55085f82012-11-21 00:36:55 +00007041static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007042s390_irgen_ROSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
7043{
7044 UChar from;
7045 UChar to;
7046 UChar rot;
7047 UChar t_bit;
7048 ULong mask;
7049 ULong maskc;
7050 IRTemp result = newTemp(Ity_I64);
7051 IRTemp op2 = newTemp(Ity_I64);
7052
7053 from = i3 & 63;
7054 to = i4 & 63;
7055 rot = i5 & 63;
7056 t_bit = i3 & 128;
7057 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
7058 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
7059 mkU8(64 - rot))));
7060 if (from <= to) {
7061 mask = ~0ULL;
7062 mask = (mask >> from) & (mask << (63 - to));
7063 maskc = ~mask;
7064 } else {
7065 maskc = ~0ULL;
7066 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
7067 mask = ~maskc;
7068 }
7069 assign(result, binop(Iop_And64, binop(Iop_Or64, get_gpr_dw0(r1), mkexpr(op2)
7070 ), mkU64(mask)));
7071 if (t_bit == 0) {
7072 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
7073 mkU64(maskc)), mkexpr(result)));
7074 }
7075 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7076
7077 return "rosbg";
7078}
7079
florian55085f82012-11-21 00:36:55 +00007080static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007081s390_irgen_RISBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
7082{
7083 UChar from;
7084 UChar to;
7085 UChar rot;
7086 UChar z_bit;
7087 ULong mask;
7088 ULong maskc;
7089 IRTemp op2 = newTemp(Ity_I64);
7090 IRTemp result = newTemp(Ity_I64);
7091
7092 from = i3 & 63;
7093 to = i4 & 63;
7094 rot = i5 & 63;
7095 z_bit = i4 & 128;
7096 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
7097 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
7098 mkU8(64 - rot))));
7099 if (from <= to) {
7100 mask = ~0ULL;
7101 mask = (mask >> from) & (mask << (63 - to));
7102 maskc = ~mask;
7103 } else {
7104 maskc = ~0ULL;
7105 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
7106 mask = ~maskc;
7107 }
7108 if (z_bit == 0) {
7109 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
7110 mkU64(maskc)), binop(Iop_And64, mkexpr(op2), mkU64(mask))));
7111 } else {
7112 put_gpr_dw0(r1, binop(Iop_And64, mkexpr(op2), mkU64(mask)));
7113 }
7114 assign(result, get_gpr_dw0(r1));
7115 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
7116
7117 return "risbg";
7118}
7119
florian55085f82012-11-21 00:36:55 +00007120static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007121s390_irgen_SAR(UChar r1, UChar r2)
7122{
7123 put_ar_w0(r1, get_gpr_w1(r2));
sewardj7ee97522011-05-09 21:45:04 +00007124 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00007125 s390_disasm(ENC3(MNM, AR, GPR), "sar", r1, r2);
7126
7127 return "sar";
7128}
7129
florian55085f82012-11-21 00:36:55 +00007130static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007131s390_irgen_SLDA(UChar r1, IRTemp op2addr)
7132{
7133 IRTemp p1 = newTemp(Ity_I64);
7134 IRTemp p2 = newTemp(Ity_I64);
7135 IRTemp op = newTemp(Ity_I64);
7136 IRTemp result = newTemp(Ity_I64);
florian417b22d2012-07-13 13:41:41 +00007137 ULong sign_mask;
sewardj2019a972011-03-07 16:04:07 +00007138 IRTemp shift_amount = newTemp(Ity_I64);
7139
7140 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7141 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7142 assign(op, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1), mkU8(32)), mkexpr(p2)
7143 ));
7144 sign_mask = 1ULL << 63;
7145 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7146 assign(result, binop(Iop_Or64, binop(Iop_And64, binop(Iop_Shl64, mkexpr(op),
florian417b22d2012-07-13 13:41:41 +00007147 unop(Iop_64to8, mkexpr(shift_amount))), mkU64(~sign_mask)),
7148 binop(Iop_And64, mkexpr(op), mkU64(sign_mask))));
sewardj2019a972011-03-07 16:04:07 +00007149 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7150 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7151 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_64, op, shift_amount);
7152
7153 return "slda";
7154}
7155
florian55085f82012-11-21 00:36:55 +00007156static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007157s390_irgen_SLDL(UChar r1, IRTemp op2addr)
7158{
7159 IRTemp p1 = newTemp(Ity_I64);
7160 IRTemp p2 = newTemp(Ity_I64);
7161 IRTemp result = newTemp(Ity_I64);
7162
7163 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7164 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7165 assign(result, binop(Iop_Shl64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
7166 mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
7167 mkexpr(op2addr), mkU64(63)))));
7168 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7169 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7170
7171 return "sldl";
7172}
7173
florian55085f82012-11-21 00:36:55 +00007174static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007175s390_irgen_SLA(UChar r1, IRTemp op2addr)
7176{
7177 IRTemp uop = newTemp(Ity_I32);
7178 IRTemp result = newTemp(Ity_I32);
7179 UInt sign_mask;
7180 IRTemp shift_amount = newTemp(Ity_I64);
7181 IRTemp op = newTemp(Ity_I32);
7182
7183 assign(op, get_gpr_w1(r1));
7184 assign(uop, get_gpr_w1(r1));
7185 sign_mask = 2147483648U;
7186 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7187 assign(result, binop(Iop_Or32, binop(Iop_And32, binop(Iop_Shl32, mkexpr(uop),
7188 unop(Iop_64to8, mkexpr(shift_amount))), mkU32(~sign_mask)),
7189 binop(Iop_And32, mkexpr(uop), mkU32(sign_mask))));
7190 put_gpr_w1(r1, mkexpr(result));
7191 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_32, op, shift_amount);
7192
7193 return "sla";
7194}
7195
florian55085f82012-11-21 00:36:55 +00007196static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007197s390_irgen_SLAK(UChar r1, UChar r3, IRTemp op2addr)
7198{
7199 IRTemp uop = newTemp(Ity_I32);
7200 IRTemp result = newTemp(Ity_I32);
7201 UInt sign_mask;
7202 IRTemp shift_amount = newTemp(Ity_I64);
7203 IRTemp op = newTemp(Ity_I32);
7204
7205 assign(op, get_gpr_w1(r3));
7206 assign(uop, get_gpr_w1(r3));
7207 sign_mask = 2147483648U;
7208 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7209 assign(result, binop(Iop_Or32, binop(Iop_And32, binop(Iop_Shl32, mkexpr(uop),
7210 unop(Iop_64to8, mkexpr(shift_amount))), mkU32(~sign_mask)),
7211 binop(Iop_And32, mkexpr(uop), mkU32(sign_mask))));
7212 put_gpr_w1(r1, mkexpr(result));
7213 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_32, op, shift_amount);
7214
7215 return "slak";
7216}
7217
florian55085f82012-11-21 00:36:55 +00007218static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007219s390_irgen_SLAG(UChar r1, UChar r3, IRTemp op2addr)
7220{
7221 IRTemp uop = newTemp(Ity_I64);
7222 IRTemp result = newTemp(Ity_I64);
7223 ULong sign_mask;
7224 IRTemp shift_amount = newTemp(Ity_I64);
7225 IRTemp op = newTemp(Ity_I64);
7226
7227 assign(op, get_gpr_dw0(r3));
7228 assign(uop, get_gpr_dw0(r3));
7229 sign_mask = 9223372036854775808ULL;
7230 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7231 assign(result, binop(Iop_Or64, binop(Iop_And64, binop(Iop_Shl64, mkexpr(uop),
7232 unop(Iop_64to8, mkexpr(shift_amount))), mkU64(~sign_mask)),
7233 binop(Iop_And64, mkexpr(uop), mkU64(sign_mask))));
7234 put_gpr_dw0(r1, mkexpr(result));
7235 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_64, op, shift_amount);
7236
7237 return "slag";
7238}
7239
florian55085f82012-11-21 00:36:55 +00007240static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007241s390_irgen_SLL(UChar r1, IRTemp op2addr)
7242{
7243 put_gpr_w1(r1, binop(Iop_Shl32, get_gpr_w1(r1), unop(Iop_64to8,
7244 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
7245
7246 return "sll";
7247}
7248
florian55085f82012-11-21 00:36:55 +00007249static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007250s390_irgen_SLLK(UChar r1, UChar r3, IRTemp op2addr)
7251{
7252 put_gpr_w1(r1, binop(Iop_Shl32, get_gpr_w1(r3), unop(Iop_64to8,
7253 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
7254
7255 return "sllk";
7256}
7257
florian55085f82012-11-21 00:36:55 +00007258static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007259s390_irgen_SLLG(UChar r1, UChar r3, IRTemp op2addr)
7260{
7261 put_gpr_dw0(r1, binop(Iop_Shl64, get_gpr_dw0(r3), unop(Iop_64to8,
7262 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
7263
7264 return "sllg";
7265}
7266
florian55085f82012-11-21 00:36:55 +00007267static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007268s390_irgen_SRDA(UChar r1, IRTemp op2addr)
7269{
7270 IRTemp p1 = newTemp(Ity_I64);
7271 IRTemp p2 = newTemp(Ity_I64);
7272 IRTemp result = newTemp(Ity_I64);
7273
7274 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7275 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7276 assign(result, binop(Iop_Sar64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
7277 mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
7278 mkexpr(op2addr), mkU64(63)))));
7279 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7280 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7281 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7282
7283 return "srda";
7284}
7285
florian55085f82012-11-21 00:36:55 +00007286static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007287s390_irgen_SRDL(UChar r1, IRTemp op2addr)
7288{
7289 IRTemp p1 = newTemp(Ity_I64);
7290 IRTemp p2 = newTemp(Ity_I64);
7291 IRTemp result = newTemp(Ity_I64);
7292
7293 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7294 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7295 assign(result, binop(Iop_Shr64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
7296 mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
7297 mkexpr(op2addr), mkU64(63)))));
7298 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7299 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7300
7301 return "srdl";
7302}
7303
florian55085f82012-11-21 00:36:55 +00007304static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007305s390_irgen_SRA(UChar r1, IRTemp op2addr)
7306{
7307 IRTemp result = newTemp(Ity_I32);
7308 IRTemp op = newTemp(Ity_I32);
7309
7310 assign(op, get_gpr_w1(r1));
7311 assign(result, binop(Iop_Sar32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7312 mkexpr(op2addr), mkU64(63)))));
7313 put_gpr_w1(r1, mkexpr(result));
7314 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7315
7316 return "sra";
7317}
7318
florian55085f82012-11-21 00:36:55 +00007319static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007320s390_irgen_SRAK(UChar r1, UChar r3, IRTemp op2addr)
7321{
7322 IRTemp result = newTemp(Ity_I32);
7323 IRTemp op = newTemp(Ity_I32);
7324
7325 assign(op, get_gpr_w1(r3));
7326 assign(result, binop(Iop_Sar32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7327 mkexpr(op2addr), mkU64(63)))));
7328 put_gpr_w1(r1, mkexpr(result));
7329 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7330
7331 return "srak";
7332}
7333
florian55085f82012-11-21 00:36:55 +00007334static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007335s390_irgen_SRAG(UChar r1, UChar r3, IRTemp op2addr)
7336{
7337 IRTemp result = newTemp(Ity_I64);
7338 IRTemp op = newTemp(Ity_I64);
7339
7340 assign(op, get_gpr_dw0(r3));
7341 assign(result, binop(Iop_Sar64, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7342 mkexpr(op2addr), mkU64(63)))));
7343 put_gpr_dw0(r1, mkexpr(result));
7344 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7345
7346 return "srag";
7347}
7348
florian55085f82012-11-21 00:36:55 +00007349static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007350s390_irgen_SRL(UChar r1, IRTemp op2addr)
7351{
7352 IRTemp op = newTemp(Ity_I32);
7353
7354 assign(op, get_gpr_w1(r1));
7355 put_gpr_w1(r1, binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7356 mkexpr(op2addr), mkU64(63)))));
7357
7358 return "srl";
7359}
7360
florian55085f82012-11-21 00:36:55 +00007361static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007362s390_irgen_SRLK(UChar r1, UChar r3, IRTemp op2addr)
7363{
7364 IRTemp op = newTemp(Ity_I32);
7365
7366 assign(op, get_gpr_w1(r3));
7367 put_gpr_w1(r1, binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7368 mkexpr(op2addr), mkU64(63)))));
7369
7370 return "srlk";
7371}
7372
florian55085f82012-11-21 00:36:55 +00007373static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007374s390_irgen_SRLG(UChar r1, UChar r3, IRTemp op2addr)
7375{
7376 IRTemp op = newTemp(Ity_I64);
7377
7378 assign(op, get_gpr_dw0(r3));
7379 put_gpr_dw0(r1, binop(Iop_Shr64, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7380 mkexpr(op2addr), mkU64(63)))));
7381
7382 return "srlg";
7383}
7384
florian55085f82012-11-21 00:36:55 +00007385static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007386s390_irgen_ST(UChar r1, IRTemp op2addr)
7387{
7388 store(mkexpr(op2addr), get_gpr_w1(r1));
7389
7390 return "st";
7391}
7392
florian55085f82012-11-21 00:36:55 +00007393static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007394s390_irgen_STY(UChar r1, IRTemp op2addr)
7395{
7396 store(mkexpr(op2addr), get_gpr_w1(r1));
7397
7398 return "sty";
7399}
7400
florian55085f82012-11-21 00:36:55 +00007401static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007402s390_irgen_STG(UChar r1, IRTemp op2addr)
7403{
7404 store(mkexpr(op2addr), get_gpr_dw0(r1));
7405
7406 return "stg";
7407}
7408
florian55085f82012-11-21 00:36:55 +00007409static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007410s390_irgen_STRL(UChar r1, UInt i2)
7411{
7412 store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
7413 get_gpr_w1(r1));
7414
7415 return "strl";
7416}
7417
florian55085f82012-11-21 00:36:55 +00007418static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007419s390_irgen_STGRL(UChar r1, UInt i2)
7420{
7421 store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
7422 get_gpr_dw0(r1));
7423
7424 return "stgrl";
7425}
7426
florian55085f82012-11-21 00:36:55 +00007427static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007428s390_irgen_STC(UChar r1, IRTemp op2addr)
7429{
7430 store(mkexpr(op2addr), get_gpr_b7(r1));
7431
7432 return "stc";
7433}
7434
florian55085f82012-11-21 00:36:55 +00007435static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007436s390_irgen_STCY(UChar r1, IRTemp op2addr)
7437{
7438 store(mkexpr(op2addr), get_gpr_b7(r1));
7439
7440 return "stcy";
7441}
7442
florian55085f82012-11-21 00:36:55 +00007443static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007444s390_irgen_STCH(UChar r1, IRTemp op2addr)
7445{
7446 store(mkexpr(op2addr), get_gpr_b3(r1));
7447
7448 return "stch";
7449}
7450
florian55085f82012-11-21 00:36:55 +00007451static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007452s390_irgen_STCM(UChar r1, UChar r3, IRTemp op2addr)
7453{
7454 UChar mask;
7455 UChar n;
7456
7457 mask = (UChar)r3;
7458 n = 0;
7459 if ((mask & 8) != 0) {
7460 store(mkexpr(op2addr), get_gpr_b4(r1));
7461 n = n + 1;
7462 }
7463 if ((mask & 4) != 0) {
7464 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b5(r1));
7465 n = n + 1;
7466 }
7467 if ((mask & 2) != 0) {
7468 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b6(r1));
7469 n = n + 1;
7470 }
7471 if ((mask & 1) != 0) {
7472 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b7(r1));
7473 }
7474
7475 return "stcm";
7476}
7477
florian55085f82012-11-21 00:36:55 +00007478static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007479s390_irgen_STCMY(UChar r1, UChar r3, IRTemp op2addr)
7480{
7481 UChar mask;
7482 UChar n;
7483
7484 mask = (UChar)r3;
7485 n = 0;
7486 if ((mask & 8) != 0) {
7487 store(mkexpr(op2addr), get_gpr_b4(r1));
7488 n = n + 1;
7489 }
7490 if ((mask & 4) != 0) {
7491 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b5(r1));
7492 n = n + 1;
7493 }
7494 if ((mask & 2) != 0) {
7495 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b6(r1));
7496 n = n + 1;
7497 }
7498 if ((mask & 1) != 0) {
7499 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b7(r1));
7500 }
7501
7502 return "stcmy";
7503}
7504
florian55085f82012-11-21 00:36:55 +00007505static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007506s390_irgen_STCMH(UChar r1, UChar r3, IRTemp op2addr)
7507{
7508 UChar mask;
7509 UChar n;
7510
7511 mask = (UChar)r3;
7512 n = 0;
7513 if ((mask & 8) != 0) {
7514 store(mkexpr(op2addr), get_gpr_b0(r1));
7515 n = n + 1;
7516 }
7517 if ((mask & 4) != 0) {
7518 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b1(r1));
7519 n = n + 1;
7520 }
7521 if ((mask & 2) != 0) {
7522 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b2(r1));
7523 n = n + 1;
7524 }
7525 if ((mask & 1) != 0) {
7526 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b3(r1));
7527 }
7528
7529 return "stcmh";
7530}
7531
florian55085f82012-11-21 00:36:55 +00007532static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007533s390_irgen_STH(UChar r1, IRTemp op2addr)
7534{
7535 store(mkexpr(op2addr), get_gpr_hw3(r1));
7536
7537 return "sth";
7538}
7539
florian55085f82012-11-21 00:36:55 +00007540static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007541s390_irgen_STHY(UChar r1, IRTemp op2addr)
7542{
7543 store(mkexpr(op2addr), get_gpr_hw3(r1));
7544
7545 return "sthy";
7546}
7547
florian55085f82012-11-21 00:36:55 +00007548static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007549s390_irgen_STHRL(UChar r1, UInt i2)
7550{
7551 store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
7552 get_gpr_hw3(r1));
7553
7554 return "sthrl";
7555}
7556
florian55085f82012-11-21 00:36:55 +00007557static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007558s390_irgen_STHH(UChar r1, IRTemp op2addr)
7559{
7560 store(mkexpr(op2addr), get_gpr_hw1(r1));
7561
7562 return "sthh";
7563}
7564
florian55085f82012-11-21 00:36:55 +00007565static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007566s390_irgen_STFH(UChar r1, IRTemp op2addr)
7567{
7568 store(mkexpr(op2addr), get_gpr_w0(r1));
7569
7570 return "stfh";
7571}
7572
florian55085f82012-11-21 00:36:55 +00007573static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00007574s390_irgen_STOC(UChar r1, IRTemp op2addr)
7575{
7576 /* condition is checked in format handler */
7577 store(mkexpr(op2addr), get_gpr_w1(r1));
7578
7579 return "stoc";
7580}
7581
florian55085f82012-11-21 00:36:55 +00007582static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00007583s390_irgen_STOCG(UChar r1, IRTemp op2addr)
7584{
7585 /* condition is checked in format handler */
7586 store(mkexpr(op2addr), get_gpr_dw0(r1));
7587
7588 return "stocg";
7589}
7590
florian55085f82012-11-21 00:36:55 +00007591static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007592s390_irgen_STPQ(UChar r1, IRTemp op2addr)
7593{
7594 store(mkexpr(op2addr), get_gpr_dw0(r1));
7595 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(8)), get_gpr_dw0(r1 + 1));
7596
7597 return "stpq";
7598}
7599
florian55085f82012-11-21 00:36:55 +00007600static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007601s390_irgen_STRVH(UChar r1, IRTemp op2addr)
7602{
7603 store(mkexpr(op2addr), get_gpr_b7(r1));
7604 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
7605
7606 return "strvh";
7607}
7608
florian55085f82012-11-21 00:36:55 +00007609static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007610s390_irgen_STRV(UChar r1, IRTemp op2addr)
7611{
7612 store(mkexpr(op2addr), get_gpr_b7(r1));
7613 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
7614 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(2)), get_gpr_b5(r1));
7615 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(3)), get_gpr_b4(r1));
7616
7617 return "strv";
7618}
7619
florian55085f82012-11-21 00:36:55 +00007620static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007621s390_irgen_STRVG(UChar r1, IRTemp op2addr)
7622{
7623 store(mkexpr(op2addr), get_gpr_b7(r1));
7624 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
7625 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(2)), get_gpr_b5(r1));
7626 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(3)), get_gpr_b4(r1));
7627 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(4)), get_gpr_b3(r1));
7628 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(5)), get_gpr_b2(r1));
7629 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(6)), get_gpr_b1(r1));
7630 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(7)), get_gpr_b0(r1));
7631
7632 return "strvg";
7633}
7634
florian55085f82012-11-21 00:36:55 +00007635static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007636s390_irgen_SR(UChar r1, UChar r2)
7637{
7638 IRTemp op1 = newTemp(Ity_I32);
7639 IRTemp op2 = newTemp(Ity_I32);
7640 IRTemp result = newTemp(Ity_I32);
7641
7642 assign(op1, get_gpr_w1(r1));
7643 assign(op2, get_gpr_w1(r2));
7644 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7645 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7646 put_gpr_w1(r1, mkexpr(result));
7647
7648 return "sr";
7649}
7650
florian55085f82012-11-21 00:36:55 +00007651static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007652s390_irgen_SGR(UChar r1, UChar r2)
7653{
7654 IRTemp op1 = newTemp(Ity_I64);
7655 IRTemp op2 = newTemp(Ity_I64);
7656 IRTemp result = newTemp(Ity_I64);
7657
7658 assign(op1, get_gpr_dw0(r1));
7659 assign(op2, get_gpr_dw0(r2));
7660 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7661 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
7662 put_gpr_dw0(r1, mkexpr(result));
7663
7664 return "sgr";
7665}
7666
florian55085f82012-11-21 00:36:55 +00007667static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007668s390_irgen_SGFR(UChar r1, UChar r2)
7669{
7670 IRTemp op1 = newTemp(Ity_I64);
7671 IRTemp op2 = newTemp(Ity_I64);
7672 IRTemp result = newTemp(Ity_I64);
7673
7674 assign(op1, get_gpr_dw0(r1));
7675 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
7676 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7677 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
7678 put_gpr_dw0(r1, mkexpr(result));
7679
7680 return "sgfr";
7681}
7682
florian55085f82012-11-21 00:36:55 +00007683static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007684s390_irgen_SRK(UChar r3, UChar r1, UChar r2)
7685{
7686 IRTemp op2 = newTemp(Ity_I32);
7687 IRTemp op3 = newTemp(Ity_I32);
7688 IRTemp result = newTemp(Ity_I32);
7689
7690 assign(op2, get_gpr_w1(r2));
7691 assign(op3, get_gpr_w1(r3));
7692 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
7693 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
7694 put_gpr_w1(r1, mkexpr(result));
7695
7696 return "srk";
7697}
7698
florian55085f82012-11-21 00:36:55 +00007699static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007700s390_irgen_SGRK(UChar r3, UChar r1, UChar r2)
7701{
7702 IRTemp op2 = newTemp(Ity_I64);
7703 IRTemp op3 = newTemp(Ity_I64);
7704 IRTemp result = newTemp(Ity_I64);
7705
7706 assign(op2, get_gpr_dw0(r2));
7707 assign(op3, get_gpr_dw0(r3));
7708 assign(result, binop(Iop_Sub64, mkexpr(op2), mkexpr(op3)));
7709 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op2, op3);
7710 put_gpr_dw0(r1, mkexpr(result));
7711
7712 return "sgrk";
7713}
7714
florian55085f82012-11-21 00:36:55 +00007715static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007716s390_irgen_S(UChar r1, IRTemp op2addr)
7717{
7718 IRTemp op1 = newTemp(Ity_I32);
7719 IRTemp op2 = newTemp(Ity_I32);
7720 IRTemp result = newTemp(Ity_I32);
7721
7722 assign(op1, get_gpr_w1(r1));
7723 assign(op2, load(Ity_I32, mkexpr(op2addr)));
7724 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7725 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7726 put_gpr_w1(r1, mkexpr(result));
7727
7728 return "s";
7729}
7730
florian55085f82012-11-21 00:36:55 +00007731static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007732s390_irgen_SY(UChar r1, IRTemp op2addr)
7733{
7734 IRTemp op1 = newTemp(Ity_I32);
7735 IRTemp op2 = newTemp(Ity_I32);
7736 IRTemp result = newTemp(Ity_I32);
7737
7738 assign(op1, get_gpr_w1(r1));
7739 assign(op2, load(Ity_I32, mkexpr(op2addr)));
7740 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7741 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7742 put_gpr_w1(r1, mkexpr(result));
7743
7744 return "sy";
7745}
7746
florian55085f82012-11-21 00:36:55 +00007747static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007748s390_irgen_SG(UChar r1, IRTemp op2addr)
7749{
7750 IRTemp op1 = newTemp(Ity_I64);
7751 IRTemp op2 = newTemp(Ity_I64);
7752 IRTemp result = newTemp(Ity_I64);
7753
7754 assign(op1, get_gpr_dw0(r1));
7755 assign(op2, load(Ity_I64, mkexpr(op2addr)));
7756 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7757 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
7758 put_gpr_dw0(r1, mkexpr(result));
7759
7760 return "sg";
7761}
7762
florian55085f82012-11-21 00:36:55 +00007763static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007764s390_irgen_SGF(UChar r1, IRTemp op2addr)
7765{
7766 IRTemp op1 = newTemp(Ity_I64);
7767 IRTemp op2 = newTemp(Ity_I64);
7768 IRTemp result = newTemp(Ity_I64);
7769
7770 assign(op1, get_gpr_dw0(r1));
7771 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
7772 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7773 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
7774 put_gpr_dw0(r1, mkexpr(result));
7775
7776 return "sgf";
7777}
7778
florian55085f82012-11-21 00:36:55 +00007779static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007780s390_irgen_SH(UChar r1, IRTemp op2addr)
7781{
7782 IRTemp op1 = newTemp(Ity_I32);
7783 IRTemp op2 = newTemp(Ity_I32);
7784 IRTemp result = newTemp(Ity_I32);
7785
7786 assign(op1, get_gpr_w1(r1));
7787 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
7788 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7789 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7790 put_gpr_w1(r1, mkexpr(result));
7791
7792 return "sh";
7793}
7794
florian55085f82012-11-21 00:36:55 +00007795static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007796s390_irgen_SHY(UChar r1, IRTemp op2addr)
7797{
7798 IRTemp op1 = newTemp(Ity_I32);
7799 IRTemp op2 = newTemp(Ity_I32);
7800 IRTemp result = newTemp(Ity_I32);
7801
7802 assign(op1, get_gpr_w1(r1));
7803 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
7804 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7805 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7806 put_gpr_w1(r1, mkexpr(result));
7807
7808 return "shy";
7809}
7810
florian55085f82012-11-21 00:36:55 +00007811static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007812s390_irgen_SHHHR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
7813{
7814 IRTemp op2 = newTemp(Ity_I32);
7815 IRTemp op3 = newTemp(Ity_I32);
7816 IRTemp result = newTemp(Ity_I32);
7817
7818 assign(op2, get_gpr_w0(r1));
7819 assign(op3, get_gpr_w0(r2));
7820 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
7821 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
7822 put_gpr_w0(r1, mkexpr(result));
7823
7824 return "shhhr";
7825}
7826
florian55085f82012-11-21 00:36:55 +00007827static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007828s390_irgen_SHHLR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
7829{
7830 IRTemp op2 = newTemp(Ity_I32);
7831 IRTemp op3 = newTemp(Ity_I32);
7832 IRTemp result = newTemp(Ity_I32);
7833
7834 assign(op2, get_gpr_w0(r1));
7835 assign(op3, get_gpr_w1(r2));
7836 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
7837 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
7838 put_gpr_w0(r1, mkexpr(result));
7839
7840 return "shhlr";
7841}
7842
florian55085f82012-11-21 00:36:55 +00007843static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007844s390_irgen_SLR(UChar r1, UChar r2)
7845{
7846 IRTemp op1 = newTemp(Ity_I32);
7847 IRTemp op2 = newTemp(Ity_I32);
7848 IRTemp result = newTemp(Ity_I32);
7849
7850 assign(op1, get_gpr_w1(r1));
7851 assign(op2, get_gpr_w1(r2));
7852 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7853 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
7854 put_gpr_w1(r1, mkexpr(result));
7855
7856 return "slr";
7857}
7858
florian55085f82012-11-21 00:36:55 +00007859static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007860s390_irgen_SLGR(UChar r1, UChar r2)
7861{
7862 IRTemp op1 = newTemp(Ity_I64);
7863 IRTemp op2 = newTemp(Ity_I64);
7864 IRTemp result = newTemp(Ity_I64);
7865
7866 assign(op1, get_gpr_dw0(r1));
7867 assign(op2, get_gpr_dw0(r2));
7868 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7869 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
7870 put_gpr_dw0(r1, mkexpr(result));
7871
7872 return "slgr";
7873}
7874
florian55085f82012-11-21 00:36:55 +00007875static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007876s390_irgen_SLGFR(UChar r1, UChar r2)
7877{
7878 IRTemp op1 = newTemp(Ity_I64);
7879 IRTemp op2 = newTemp(Ity_I64);
7880 IRTemp result = newTemp(Ity_I64);
7881
7882 assign(op1, get_gpr_dw0(r1));
7883 assign(op2, unop(Iop_32Uto64, get_gpr_w1(r2)));
7884 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7885 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
7886 put_gpr_dw0(r1, mkexpr(result));
7887
7888 return "slgfr";
7889}
7890
florian55085f82012-11-21 00:36:55 +00007891static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007892s390_irgen_SLRK(UChar r3, UChar r1, UChar r2)
7893{
7894 IRTemp op2 = newTemp(Ity_I32);
7895 IRTemp op3 = newTemp(Ity_I32);
7896 IRTemp result = newTemp(Ity_I32);
7897
7898 assign(op2, get_gpr_w1(r2));
7899 assign(op3, get_gpr_w1(r3));
7900 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
7901 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
7902 put_gpr_w1(r1, mkexpr(result));
7903
7904 return "slrk";
7905}
7906
florian55085f82012-11-21 00:36:55 +00007907static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007908s390_irgen_SLGRK(UChar r3, UChar r1, UChar r2)
7909{
7910 IRTemp op2 = newTemp(Ity_I64);
7911 IRTemp op3 = newTemp(Ity_I64);
7912 IRTemp result = newTemp(Ity_I64);
7913
7914 assign(op2, get_gpr_dw0(r2));
7915 assign(op3, get_gpr_dw0(r3));
7916 assign(result, binop(Iop_Sub64, mkexpr(op2), mkexpr(op3)));
7917 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op2, op3);
7918 put_gpr_dw0(r1, mkexpr(result));
7919
7920 return "slgrk";
7921}
7922
florian55085f82012-11-21 00:36:55 +00007923static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007924s390_irgen_SL(UChar r1, IRTemp op2addr)
7925{
7926 IRTemp op1 = newTemp(Ity_I32);
7927 IRTemp op2 = newTemp(Ity_I32);
7928 IRTemp result = newTemp(Ity_I32);
7929
7930 assign(op1, get_gpr_w1(r1));
7931 assign(op2, load(Ity_I32, mkexpr(op2addr)));
7932 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7933 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
7934 put_gpr_w1(r1, mkexpr(result));
7935
7936 return "sl";
7937}
7938
florian55085f82012-11-21 00:36:55 +00007939static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007940s390_irgen_SLY(UChar r1, IRTemp op2addr)
7941{
7942 IRTemp op1 = newTemp(Ity_I32);
7943 IRTemp op2 = newTemp(Ity_I32);
7944 IRTemp result = newTemp(Ity_I32);
7945
7946 assign(op1, get_gpr_w1(r1));
7947 assign(op2, load(Ity_I32, mkexpr(op2addr)));
7948 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7949 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
7950 put_gpr_w1(r1, mkexpr(result));
7951
7952 return "sly";
7953}
7954
florian55085f82012-11-21 00:36:55 +00007955static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007956s390_irgen_SLG(UChar r1, IRTemp op2addr)
7957{
7958 IRTemp op1 = newTemp(Ity_I64);
7959 IRTemp op2 = newTemp(Ity_I64);
7960 IRTemp result = newTemp(Ity_I64);
7961
7962 assign(op1, get_gpr_dw0(r1));
7963 assign(op2, load(Ity_I64, mkexpr(op2addr)));
7964 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7965 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
7966 put_gpr_dw0(r1, mkexpr(result));
7967
7968 return "slg";
7969}
7970
florian55085f82012-11-21 00:36:55 +00007971static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007972s390_irgen_SLGF(UChar r1, IRTemp op2addr)
7973{
7974 IRTemp op1 = newTemp(Ity_I64);
7975 IRTemp op2 = newTemp(Ity_I64);
7976 IRTemp result = newTemp(Ity_I64);
7977
7978 assign(op1, get_gpr_dw0(r1));
7979 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
7980 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7981 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
7982 put_gpr_dw0(r1, mkexpr(result));
7983
7984 return "slgf";
7985}
7986
florian55085f82012-11-21 00:36:55 +00007987static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007988s390_irgen_SLFI(UChar r1, UInt i2)
7989{
7990 IRTemp op1 = newTemp(Ity_I32);
7991 UInt op2;
7992 IRTemp result = newTemp(Ity_I32);
7993
7994 assign(op1, get_gpr_w1(r1));
7995 op2 = i2;
7996 assign(result, binop(Iop_Sub32, mkexpr(op1), mkU32(op2)));
7997 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, mktemp(Ity_I32,
7998 mkU32(op2)));
7999 put_gpr_w1(r1, mkexpr(result));
8000
8001 return "slfi";
8002}
8003
florian55085f82012-11-21 00:36:55 +00008004static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008005s390_irgen_SLGFI(UChar r1, UInt i2)
8006{
8007 IRTemp op1 = newTemp(Ity_I64);
8008 ULong op2;
8009 IRTemp result = newTemp(Ity_I64);
8010
8011 assign(op1, get_gpr_dw0(r1));
8012 op2 = (ULong)i2;
8013 assign(result, binop(Iop_Sub64, mkexpr(op1), mkU64(op2)));
8014 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, mktemp(Ity_I64,
8015 mkU64(op2)));
8016 put_gpr_dw0(r1, mkexpr(result));
8017
8018 return "slgfi";
8019}
8020
florian55085f82012-11-21 00:36:55 +00008021static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008022s390_irgen_SLHHHR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
8023{
8024 IRTemp op2 = newTemp(Ity_I32);
8025 IRTemp op3 = newTemp(Ity_I32);
8026 IRTemp result = newTemp(Ity_I32);
8027
8028 assign(op2, get_gpr_w0(r1));
8029 assign(op3, get_gpr_w0(r2));
8030 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
8031 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
8032 put_gpr_w0(r1, mkexpr(result));
8033
8034 return "slhhhr";
8035}
8036
florian55085f82012-11-21 00:36:55 +00008037static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008038s390_irgen_SLHHLR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
8039{
8040 IRTemp op2 = newTemp(Ity_I32);
8041 IRTemp op3 = newTemp(Ity_I32);
8042 IRTemp result = newTemp(Ity_I32);
8043
8044 assign(op2, get_gpr_w0(r1));
8045 assign(op3, get_gpr_w1(r2));
8046 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
8047 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
8048 put_gpr_w0(r1, mkexpr(result));
8049
8050 return "slhhlr";
8051}
8052
florian55085f82012-11-21 00:36:55 +00008053static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008054s390_irgen_SLBR(UChar r1, UChar r2)
8055{
8056 IRTemp op1 = newTemp(Ity_I32);
8057 IRTemp op2 = newTemp(Ity_I32);
8058 IRTemp result = newTemp(Ity_I32);
8059 IRTemp borrow_in = newTemp(Ity_I32);
8060
8061 assign(op1, get_gpr_w1(r1));
8062 assign(op2, get_gpr_w1(r2));
8063 assign(borrow_in, binop(Iop_Sub32, mkU32(1), binop(Iop_Shr32,
8064 s390_call_calculate_cc(), mkU8(1))));
8065 assign(result, binop(Iop_Sub32, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)),
8066 mkexpr(borrow_in)));
8067 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_32, op1, op2, borrow_in);
8068 put_gpr_w1(r1, mkexpr(result));
8069
8070 return "slbr";
8071}
8072
florian55085f82012-11-21 00:36:55 +00008073static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008074s390_irgen_SLBGR(UChar r1, UChar r2)
8075{
8076 IRTemp op1 = newTemp(Ity_I64);
8077 IRTemp op2 = newTemp(Ity_I64);
8078 IRTemp result = newTemp(Ity_I64);
8079 IRTemp borrow_in = newTemp(Ity_I64);
8080
8081 assign(op1, get_gpr_dw0(r1));
8082 assign(op2, get_gpr_dw0(r2));
8083 assign(borrow_in, unop(Iop_32Uto64, binop(Iop_Sub32, mkU32(1),
8084 binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)))));
8085 assign(result, binop(Iop_Sub64, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)),
8086 mkexpr(borrow_in)));
8087 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_64, op1, op2, borrow_in);
8088 put_gpr_dw0(r1, mkexpr(result));
8089
8090 return "slbgr";
8091}
8092
florian55085f82012-11-21 00:36:55 +00008093static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008094s390_irgen_SLB(UChar r1, IRTemp op2addr)
8095{
8096 IRTemp op1 = newTemp(Ity_I32);
8097 IRTemp op2 = newTemp(Ity_I32);
8098 IRTemp result = newTemp(Ity_I32);
8099 IRTemp borrow_in = newTemp(Ity_I32);
8100
8101 assign(op1, get_gpr_w1(r1));
8102 assign(op2, load(Ity_I32, mkexpr(op2addr)));
8103 assign(borrow_in, binop(Iop_Sub32, mkU32(1), binop(Iop_Shr32,
8104 s390_call_calculate_cc(), mkU8(1))));
8105 assign(result, binop(Iop_Sub32, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)),
8106 mkexpr(borrow_in)));
8107 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_32, op1, op2, borrow_in);
8108 put_gpr_w1(r1, mkexpr(result));
8109
8110 return "slb";
8111}
8112
florian55085f82012-11-21 00:36:55 +00008113static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008114s390_irgen_SLBG(UChar r1, IRTemp op2addr)
8115{
8116 IRTemp op1 = newTemp(Ity_I64);
8117 IRTemp op2 = newTemp(Ity_I64);
8118 IRTemp result = newTemp(Ity_I64);
8119 IRTemp borrow_in = newTemp(Ity_I64);
8120
8121 assign(op1, get_gpr_dw0(r1));
8122 assign(op2, load(Ity_I64, mkexpr(op2addr)));
8123 assign(borrow_in, unop(Iop_32Uto64, binop(Iop_Sub32, mkU32(1),
8124 binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)))));
8125 assign(result, binop(Iop_Sub64, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)),
8126 mkexpr(borrow_in)));
8127 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_64, op1, op2, borrow_in);
8128 put_gpr_dw0(r1, mkexpr(result));
8129
8130 return "slbg";
8131}
8132
florian55085f82012-11-21 00:36:55 +00008133static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008134s390_irgen_SVC(UChar i)
8135{
8136 IRTemp sysno = newTemp(Ity_I64);
8137
8138 if (i != 0) {
8139 assign(sysno, mkU64(i));
8140 } else {
8141 assign(sysno, unop(Iop_32Uto64, get_gpr_w1(1)));
8142 }
8143 system_call(mkexpr(sysno));
8144
8145 return "svc";
8146}
8147
florian55085f82012-11-21 00:36:55 +00008148static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008149s390_irgen_TM(UChar i2, IRTemp op1addr)
8150{
8151 UChar mask;
8152 IRTemp value = newTemp(Ity_I8);
8153
8154 mask = i2;
8155 assign(value, load(Ity_I8, mkexpr(op1addr)));
8156 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_8, value, mktemp(Ity_I8,
8157 mkU8(mask)));
8158
8159 return "tm";
8160}
8161
florian55085f82012-11-21 00:36:55 +00008162static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008163s390_irgen_TMY(UChar i2, IRTemp op1addr)
8164{
8165 UChar mask;
8166 IRTemp value = newTemp(Ity_I8);
8167
8168 mask = i2;
8169 assign(value, load(Ity_I8, mkexpr(op1addr)));
8170 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_8, value, mktemp(Ity_I8,
8171 mkU8(mask)));
8172
8173 return "tmy";
8174}
8175
florian55085f82012-11-21 00:36:55 +00008176static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008177s390_irgen_TMHH(UChar r1, UShort i2)
8178{
8179 UShort mask;
8180 IRTemp value = newTemp(Ity_I16);
8181
8182 mask = i2;
8183 assign(value, get_gpr_hw0(r1));
8184 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
8185 mkU16(mask)));
8186
8187 return "tmhh";
8188}
8189
florian55085f82012-11-21 00:36:55 +00008190static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008191s390_irgen_TMHL(UChar r1, UShort i2)
8192{
8193 UShort mask;
8194 IRTemp value = newTemp(Ity_I16);
8195
8196 mask = i2;
8197 assign(value, get_gpr_hw1(r1));
8198 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
8199 mkU16(mask)));
8200
8201 return "tmhl";
8202}
8203
florian55085f82012-11-21 00:36:55 +00008204static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008205s390_irgen_TMLH(UChar r1, UShort i2)
8206{
8207 UShort mask;
8208 IRTemp value = newTemp(Ity_I16);
8209
8210 mask = i2;
8211 assign(value, get_gpr_hw2(r1));
8212 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
8213 mkU16(mask)));
8214
8215 return "tmlh";
8216}
8217
florian55085f82012-11-21 00:36:55 +00008218static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008219s390_irgen_TMLL(UChar r1, UShort i2)
8220{
8221 UShort mask;
8222 IRTemp value = newTemp(Ity_I16);
8223
8224 mask = i2;
8225 assign(value, get_gpr_hw3(r1));
8226 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
8227 mkU16(mask)));
8228
8229 return "tmll";
8230}
8231
florian55085f82012-11-21 00:36:55 +00008232static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008233s390_irgen_EFPC(UChar r1)
8234{
8235 put_gpr_w1(r1, get_fpc_w0());
8236
8237 return "efpc";
8238}
8239
florian55085f82012-11-21 00:36:55 +00008240static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008241s390_irgen_LER(UChar r1, UChar r2)
8242{
8243 put_fpr_w0(r1, get_fpr_w0(r2));
8244
8245 return "ler";
8246}
8247
florian55085f82012-11-21 00:36:55 +00008248static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008249s390_irgen_LDR(UChar r1, UChar r2)
8250{
8251 put_fpr_dw0(r1, get_fpr_dw0(r2));
8252
8253 return "ldr";
8254}
8255
florian55085f82012-11-21 00:36:55 +00008256static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008257s390_irgen_LXR(UChar r1, UChar r2)
8258{
8259 put_fpr_dw0(r1, get_fpr_dw0(r2));
8260 put_fpr_dw0(r1 + 2, get_fpr_dw0(r2 + 2));
8261
8262 return "lxr";
8263}
8264
florian55085f82012-11-21 00:36:55 +00008265static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008266s390_irgen_LE(UChar r1, IRTemp op2addr)
8267{
8268 put_fpr_w0(r1, load(Ity_F32, mkexpr(op2addr)));
8269
8270 return "le";
8271}
8272
florian55085f82012-11-21 00:36:55 +00008273static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008274s390_irgen_LD(UChar r1, IRTemp op2addr)
8275{
8276 put_fpr_dw0(r1, load(Ity_F64, mkexpr(op2addr)));
8277
8278 return "ld";
8279}
8280
florian55085f82012-11-21 00:36:55 +00008281static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008282s390_irgen_LEY(UChar r1, IRTemp op2addr)
8283{
8284 put_fpr_w0(r1, load(Ity_F32, mkexpr(op2addr)));
8285
8286 return "ley";
8287}
8288
florian55085f82012-11-21 00:36:55 +00008289static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008290s390_irgen_LDY(UChar r1, IRTemp op2addr)
8291{
8292 put_fpr_dw0(r1, load(Ity_F64, mkexpr(op2addr)));
8293
8294 return "ldy";
8295}
8296
florian55085f82012-11-21 00:36:55 +00008297static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008298s390_irgen_LFPC(IRTemp op2addr)
8299{
8300 put_fpc_w0(load(Ity_I32, mkexpr(op2addr)));
8301
8302 return "lfpc";
8303}
8304
florian55085f82012-11-21 00:36:55 +00008305static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008306s390_irgen_LZER(UChar r1)
8307{
8308 put_fpr_w0(r1, mkF32i(0x0));
8309
8310 return "lzer";
8311}
8312
florian55085f82012-11-21 00:36:55 +00008313static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008314s390_irgen_LZDR(UChar r1)
8315{
8316 put_fpr_dw0(r1, mkF64i(0x0));
8317
8318 return "lzdr";
8319}
8320
florian55085f82012-11-21 00:36:55 +00008321static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008322s390_irgen_LZXR(UChar r1)
8323{
8324 put_fpr_dw0(r1, mkF64i(0x0));
8325 put_fpr_dw0(r1 + 2, mkF64i(0x0));
8326
8327 return "lzxr";
8328}
8329
florian55085f82012-11-21 00:36:55 +00008330static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008331s390_irgen_SRNM(IRTemp op2addr)
8332{
florianf0fa1be2012-09-18 20:24:38 +00008333 UInt input_mask, fpc_mask;
sewardj2019a972011-03-07 16:04:07 +00008334
florianf0fa1be2012-09-18 20:24:38 +00008335 input_mask = 3;
8336 fpc_mask = s390_host_has_fpext ? 7 : 3;
sewardj2019a972011-03-07 16:04:07 +00008337
florianf0fa1be2012-09-18 20:24:38 +00008338 put_fpc_w0(binop(Iop_Or32,
8339 binop(Iop_And32, get_fpc_w0(), mkU32(~fpc_mask)),
8340 binop(Iop_And32, unop(Iop_64to32, mkexpr(op2addr)),
8341 mkU32(input_mask))));
sewardj2019a972011-03-07 16:04:07 +00008342 return "srnm";
8343}
8344
florian55085f82012-11-21 00:36:55 +00008345static const HChar *
florianf0fa1be2012-09-18 20:24:38 +00008346s390_irgen_SRNMB(IRTemp op2addr)
8347{
8348 UInt input_mask, fpc_mask;
8349
8350 input_mask = 7;
8351 fpc_mask = 7;
8352
8353 put_fpc_w0(binop(Iop_Or32,
8354 binop(Iop_And32, get_fpc_w0(), mkU32(~fpc_mask)),
8355 binop(Iop_And32, unop(Iop_64to32, mkexpr(op2addr)),
8356 mkU32(input_mask))));
8357 return "srnmb";
8358}
8359
florian81a4bfe2012-09-20 01:25:28 +00008360static void
florianf0fa1be2012-09-18 20:24:38 +00008361s390_irgen_srnmb_wrapper(UChar b2, UShort d2)
8362{
8363 if (b2 == 0) { /* This is the typical case */
8364 if (d2 > 3) {
8365 if (s390_host_has_fpext && d2 == 7) {
8366 /* ok */
8367 } else {
8368 emulation_warning(EmWarn_S390X_invalid_rounding);
florian125e20d2012-10-07 15:42:37 +00008369 d2 = S390_FPC_BFP_ROUND_NEAREST_EVEN;
florianf0fa1be2012-09-18 20:24:38 +00008370 }
8371 }
8372 }
8373
8374 s390_format_S_RD(s390_irgen_SRNMB, b2, d2);
8375}
8376
8377
florian55085f82012-11-21 00:36:55 +00008378static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008379s390_irgen_SFPC(UChar r1)
8380{
8381 put_fpc_w0(get_gpr_w1(r1));
8382
8383 return "sfpc";
8384}
8385
florian55085f82012-11-21 00:36:55 +00008386static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008387s390_irgen_STE(UChar r1, IRTemp op2addr)
8388{
8389 store(mkexpr(op2addr), get_fpr_w0(r1));
8390
8391 return "ste";
8392}
8393
florian55085f82012-11-21 00:36:55 +00008394static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008395s390_irgen_STD(UChar r1, IRTemp op2addr)
8396{
8397 store(mkexpr(op2addr), get_fpr_dw0(r1));
8398
8399 return "std";
8400}
8401
florian55085f82012-11-21 00:36:55 +00008402static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008403s390_irgen_STEY(UChar r1, IRTemp op2addr)
8404{
8405 store(mkexpr(op2addr), get_fpr_w0(r1));
8406
8407 return "stey";
8408}
8409
florian55085f82012-11-21 00:36:55 +00008410static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008411s390_irgen_STDY(UChar r1, IRTemp op2addr)
8412{
8413 store(mkexpr(op2addr), get_fpr_dw0(r1));
8414
8415 return "stdy";
8416}
8417
florian55085f82012-11-21 00:36:55 +00008418static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008419s390_irgen_STFPC(IRTemp op2addr)
8420{
8421 store(mkexpr(op2addr), get_fpc_w0());
8422
8423 return "stfpc";
8424}
8425
florian55085f82012-11-21 00:36:55 +00008426static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008427s390_irgen_AEBR(UChar r1, UChar r2)
8428{
8429 IRTemp op1 = newTemp(Ity_F32);
8430 IRTemp op2 = newTemp(Ity_F32);
8431 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00008432 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008433
8434 assign(op1, get_fpr_w0(r1));
8435 assign(op2, get_fpr_w0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008436 assign(result, triop(Iop_AddF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008437 mkexpr(op2)));
8438 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8439 put_fpr_w0(r1, mkexpr(result));
8440
8441 return "aebr";
8442}
8443
florian55085f82012-11-21 00:36:55 +00008444static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008445s390_irgen_ADBR(UChar r1, UChar r2)
8446{
8447 IRTemp op1 = newTemp(Ity_F64);
8448 IRTemp op2 = newTemp(Ity_F64);
8449 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00008450 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008451
8452 assign(op1, get_fpr_dw0(r1));
8453 assign(op2, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008454 assign(result, triop(Iop_AddF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008455 mkexpr(op2)));
8456 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8457 put_fpr_dw0(r1, mkexpr(result));
8458
8459 return "adbr";
8460}
8461
florian55085f82012-11-21 00:36:55 +00008462static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008463s390_irgen_AEB(UChar r1, IRTemp op2addr)
8464{
8465 IRTemp op1 = newTemp(Ity_F32);
8466 IRTemp op2 = newTemp(Ity_F32);
8467 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00008468 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008469
8470 assign(op1, get_fpr_w0(r1));
8471 assign(op2, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00008472 assign(result, triop(Iop_AddF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008473 mkexpr(op2)));
8474 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8475 put_fpr_w0(r1, mkexpr(result));
8476
8477 return "aeb";
8478}
8479
florian55085f82012-11-21 00:36:55 +00008480static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008481s390_irgen_ADB(UChar r1, IRTemp op2addr)
8482{
8483 IRTemp op1 = newTemp(Ity_F64);
8484 IRTemp op2 = newTemp(Ity_F64);
8485 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00008486 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008487
8488 assign(op1, get_fpr_dw0(r1));
8489 assign(op2, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00008490 assign(result, triop(Iop_AddF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008491 mkexpr(op2)));
8492 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8493 put_fpr_dw0(r1, mkexpr(result));
8494
8495 return "adb";
8496}
8497
florian55085f82012-11-21 00:36:55 +00008498static const HChar *
florian4b8efad2012-09-02 18:07:08 +00008499s390_irgen_CEFBR(UChar m3, UChar m4 __attribute__((unused)),
8500 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008501{
florian125e20d2012-10-07 15:42:37 +00008502 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian4b8efad2012-09-02 18:07:08 +00008503 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +00008504 m3 = S390_BFP_ROUND_PER_FPC;
florian4b8efad2012-09-02 18:07:08 +00008505 }
sewardj2019a972011-03-07 16:04:07 +00008506 IRTemp op2 = newTemp(Ity_I32);
8507
8508 assign(op2, get_gpr_w1(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008509 put_fpr_w0(r1, binop(Iop_I32StoF32, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +00008510 mkexpr(op2)));
sewardj2019a972011-03-07 16:04:07 +00008511
8512 return "cefbr";
8513}
8514
florian55085f82012-11-21 00:36:55 +00008515static const HChar *
florian4b8efad2012-09-02 18:07:08 +00008516s390_irgen_CDFBR(UChar m3 __attribute__((unused)),
8517 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008518{
8519 IRTemp op2 = newTemp(Ity_I32);
8520
8521 assign(op2, get_gpr_w1(r2));
8522 put_fpr_dw0(r1, unop(Iop_I32StoF64, mkexpr(op2)));
8523
8524 return "cdfbr";
8525}
8526
florian55085f82012-11-21 00:36:55 +00008527static const HChar *
florian4b8efad2012-09-02 18:07:08 +00008528s390_irgen_CEGBR(UChar m3, UChar m4 __attribute__((unused)),
8529 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008530{
florian125e20d2012-10-07 15:42:37 +00008531 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian4b8efad2012-09-02 18:07:08 +00008532 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +00008533 m3 = S390_BFP_ROUND_PER_FPC;
florian4b8efad2012-09-02 18:07:08 +00008534 }
sewardj2019a972011-03-07 16:04:07 +00008535 IRTemp op2 = newTemp(Ity_I64);
8536
8537 assign(op2, get_gpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008538 put_fpr_w0(r1, binop(Iop_I64StoF32, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +00008539 mkexpr(op2)));
sewardj2019a972011-03-07 16:04:07 +00008540
8541 return "cegbr";
8542}
8543
florian55085f82012-11-21 00:36:55 +00008544static const HChar *
florian4b8efad2012-09-02 18:07:08 +00008545s390_irgen_CDGBR(UChar m3, UChar m4 __attribute__((unused)),
8546 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008547{
florian125e20d2012-10-07 15:42:37 +00008548 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian4b8efad2012-09-02 18:07:08 +00008549 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +00008550 m3 = S390_BFP_ROUND_PER_FPC;
florian4b8efad2012-09-02 18:07:08 +00008551 }
sewardj2019a972011-03-07 16:04:07 +00008552 IRTemp op2 = newTemp(Ity_I64);
8553
8554 assign(op2, get_gpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008555 put_fpr_dw0(r1, binop(Iop_I64StoF64, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +00008556 mkexpr(op2)));
sewardj2019a972011-03-07 16:04:07 +00008557
8558 return "cdgbr";
8559}
8560
florian55085f82012-11-21 00:36:55 +00008561static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00008562s390_irgen_CELFBR(UChar m3, UChar m4 __attribute__((unused)),
8563 UChar r1, UChar r2)
8564{
floriane75dafa2012-09-01 17:54:09 +00008565 if (! s390_host_has_fpext) {
8566 emulation_failure(EmFail_S390X_fpext);
8567 } else {
8568 IRTemp op2 = newTemp(Ity_I32);
florian1c8f7ff2012-09-01 00:12:11 +00008569
floriane75dafa2012-09-01 17:54:09 +00008570 assign(op2, get_gpr_w1(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008571 put_fpr_w0(r1, binop(Iop_I32UtoF32, mkexpr(encode_bfp_rounding_mode(m3)),
floriane75dafa2012-09-01 17:54:09 +00008572 mkexpr(op2)));
8573 }
florian1c8f7ff2012-09-01 00:12:11 +00008574 return "celfbr";
8575}
8576
florian55085f82012-11-21 00:36:55 +00008577static const HChar *
floriand2129202012-09-01 20:01:39 +00008578s390_irgen_CDLFBR(UChar m3 __attribute__((unused)),
8579 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
florian1c8f7ff2012-09-01 00:12:11 +00008580{
floriane75dafa2012-09-01 17:54:09 +00008581 if (! s390_host_has_fpext) {
8582 emulation_failure(EmFail_S390X_fpext);
8583 } else {
8584 IRTemp op2 = newTemp(Ity_I32);
florian1c8f7ff2012-09-01 00:12:11 +00008585
floriane75dafa2012-09-01 17:54:09 +00008586 assign(op2, get_gpr_w1(r2));
8587 put_fpr_dw0(r1, unop(Iop_I32UtoF64, mkexpr(op2)));
8588 }
florian1c8f7ff2012-09-01 00:12:11 +00008589 return "cdlfbr";
8590}
8591
florian55085f82012-11-21 00:36:55 +00008592static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00008593s390_irgen_CELGBR(UChar m3, UChar m4 __attribute__((unused)),
8594 UChar r1, UChar r2)
8595{
floriane75dafa2012-09-01 17:54:09 +00008596 if (! s390_host_has_fpext) {
8597 emulation_failure(EmFail_S390X_fpext);
8598 } else {
8599 IRTemp op2 = newTemp(Ity_I64);
florian1c8f7ff2012-09-01 00:12:11 +00008600
floriane75dafa2012-09-01 17:54:09 +00008601 assign(op2, get_gpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008602 put_fpr_w0(r1, binop(Iop_I64UtoF32, mkexpr(encode_bfp_rounding_mode(m3)),
floriane75dafa2012-09-01 17:54:09 +00008603 mkexpr(op2)));
8604 }
florian1c8f7ff2012-09-01 00:12:11 +00008605 return "celgbr";
8606}
8607
florian55085f82012-11-21 00:36:55 +00008608static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00008609s390_irgen_CDLGBR(UChar m3, UChar m4 __attribute__((unused)),
8610 UChar r1, UChar r2)
8611{
floriane75dafa2012-09-01 17:54:09 +00008612 if (! s390_host_has_fpext) {
8613 emulation_failure(EmFail_S390X_fpext);
8614 } else {
8615 IRTemp op2 = newTemp(Ity_I64);
florian1c8f7ff2012-09-01 00:12:11 +00008616
floriane75dafa2012-09-01 17:54:09 +00008617 assign(op2, get_gpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008618 put_fpr_dw0(r1, binop(Iop_I64UtoF64,
8619 mkexpr(encode_bfp_rounding_mode(m3)),
floriane75dafa2012-09-01 17:54:09 +00008620 mkexpr(op2)));
8621 }
florian1c8f7ff2012-09-01 00:12:11 +00008622 return "cdlgbr";
8623}
8624
florian55085f82012-11-21 00:36:55 +00008625static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00008626s390_irgen_CLFEBR(UChar m3, UChar m4 __attribute__((unused)),
8627 UChar r1, UChar r2)
8628{
floriane75dafa2012-09-01 17:54:09 +00008629 if (! s390_host_has_fpext) {
8630 emulation_failure(EmFail_S390X_fpext);
8631 } else {
8632 IRTemp op = newTemp(Ity_F32);
8633 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +00008634 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +00008635
floriane75dafa2012-09-01 17:54:09 +00008636 assign(op, get_fpr_w0(r2));
florian19e00772012-09-06 03:13:22 +00008637 assign(result, binop(Iop_F32toI32U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +00008638 mkexpr(op)));
8639 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008640 s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_UINT_32, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +00008641 }
florian1c8f7ff2012-09-01 00:12:11 +00008642 return "clfebr";
8643}
8644
florian55085f82012-11-21 00:36:55 +00008645static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00008646s390_irgen_CLFDBR(UChar m3, UChar m4 __attribute__((unused)),
8647 UChar r1, UChar r2)
8648{
floriane75dafa2012-09-01 17:54:09 +00008649 if (! s390_host_has_fpext) {
8650 emulation_failure(EmFail_S390X_fpext);
8651 } else {
8652 IRTemp op = newTemp(Ity_F64);
8653 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +00008654 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +00008655
floriane75dafa2012-09-01 17:54:09 +00008656 assign(op, get_fpr_dw0(r2));
florian19e00772012-09-06 03:13:22 +00008657 assign(result, binop(Iop_F64toI32U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +00008658 mkexpr(op)));
8659 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008660 s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_UINT_32, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +00008661 }
florian1c8f7ff2012-09-01 00:12:11 +00008662 return "clfdbr";
8663}
8664
florian55085f82012-11-21 00:36:55 +00008665static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00008666s390_irgen_CLGEBR(UChar m3, UChar m4 __attribute__((unused)),
8667 UChar r1, UChar r2)
8668{
floriane75dafa2012-09-01 17:54:09 +00008669 if (! s390_host_has_fpext) {
8670 emulation_failure(EmFail_S390X_fpext);
8671 } else {
8672 IRTemp op = newTemp(Ity_F32);
8673 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +00008674 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +00008675
floriane75dafa2012-09-01 17:54:09 +00008676 assign(op, get_fpr_w0(r2));
florian19e00772012-09-06 03:13:22 +00008677 assign(result, binop(Iop_F32toI64U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +00008678 mkexpr(op)));
8679 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008680 s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_UINT_64, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +00008681 }
florian1c8f7ff2012-09-01 00:12:11 +00008682 return "clgebr";
8683}
8684
florian55085f82012-11-21 00:36:55 +00008685static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00008686s390_irgen_CLGDBR(UChar m3, UChar m4 __attribute__((unused)),
8687 UChar r1, UChar r2)
8688{
floriane75dafa2012-09-01 17:54:09 +00008689 if (! s390_host_has_fpext) {
8690 emulation_failure(EmFail_S390X_fpext);
8691 } else {
8692 IRTemp op = newTemp(Ity_F64);
8693 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +00008694 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +00008695
floriane75dafa2012-09-01 17:54:09 +00008696 assign(op, get_fpr_dw0(r2));
florian19e00772012-09-06 03:13:22 +00008697 assign(result, binop(Iop_F64toI64U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +00008698 mkexpr(op)));
8699 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008700 s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_UINT_64, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +00008701 }
florian1c8f7ff2012-09-01 00:12:11 +00008702 return "clgdbr";
8703}
8704
florian55085f82012-11-21 00:36:55 +00008705static const HChar *
florian4b8efad2012-09-02 18:07:08 +00008706s390_irgen_CFEBR(UChar m3, UChar m4 __attribute__((unused)),
8707 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008708{
8709 IRTemp op = newTemp(Ity_F32);
8710 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +00008711 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +00008712
8713 assign(op, get_fpr_w0(r2));
florian19e00772012-09-06 03:13:22 +00008714 assign(result, binop(Iop_F32toI32S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +00008715 mkexpr(op)));
8716 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008717 s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_INT_32, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +00008718
8719 return "cfebr";
8720}
8721
florian55085f82012-11-21 00:36:55 +00008722static const HChar *
florian4b8efad2012-09-02 18:07:08 +00008723s390_irgen_CFDBR(UChar m3, UChar m4 __attribute__((unused)),
8724 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008725{
8726 IRTemp op = newTemp(Ity_F64);
8727 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +00008728 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +00008729
8730 assign(op, get_fpr_dw0(r2));
florian19e00772012-09-06 03:13:22 +00008731 assign(result, binop(Iop_F64toI32S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +00008732 mkexpr(op)));
8733 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008734 s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_INT_32, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +00008735
8736 return "cfdbr";
8737}
8738
florian55085f82012-11-21 00:36:55 +00008739static const HChar *
florian4b8efad2012-09-02 18:07:08 +00008740s390_irgen_CGEBR(UChar m3, UChar m4 __attribute__((unused)),
8741 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008742{
8743 IRTemp op = newTemp(Ity_F32);
8744 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +00008745 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +00008746
8747 assign(op, get_fpr_w0(r2));
florian19e00772012-09-06 03:13:22 +00008748 assign(result, binop(Iop_F32toI64S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +00008749 mkexpr(op)));
8750 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008751 s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_INT_64, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +00008752
8753 return "cgebr";
8754}
8755
florian55085f82012-11-21 00:36:55 +00008756static const HChar *
florian4b8efad2012-09-02 18:07:08 +00008757s390_irgen_CGDBR(UChar m3, UChar m4 __attribute__((unused)),
8758 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008759{
8760 IRTemp op = newTemp(Ity_F64);
8761 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +00008762 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +00008763
8764 assign(op, get_fpr_dw0(r2));
florian19e00772012-09-06 03:13:22 +00008765 assign(result, binop(Iop_F64toI64S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +00008766 mkexpr(op)));
8767 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008768 s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_INT_64, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +00008769
8770 return "cgdbr";
8771}
8772
florian55085f82012-11-21 00:36:55 +00008773static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008774s390_irgen_DEBR(UChar r1, UChar r2)
8775{
8776 IRTemp op1 = newTemp(Ity_F32);
8777 IRTemp op2 = newTemp(Ity_F32);
8778 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00008779 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008780
8781 assign(op1, get_fpr_w0(r1));
8782 assign(op2, get_fpr_w0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008783 assign(result, triop(Iop_DivF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008784 mkexpr(op2)));
8785 put_fpr_w0(r1, mkexpr(result));
8786
8787 return "debr";
8788}
8789
florian55085f82012-11-21 00:36:55 +00008790static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008791s390_irgen_DDBR(UChar r1, UChar r2)
8792{
8793 IRTemp op1 = newTemp(Ity_F64);
8794 IRTemp op2 = newTemp(Ity_F64);
8795 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00008796 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008797
8798 assign(op1, get_fpr_dw0(r1));
8799 assign(op2, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008800 assign(result, triop(Iop_DivF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008801 mkexpr(op2)));
8802 put_fpr_dw0(r1, mkexpr(result));
8803
8804 return "ddbr";
8805}
8806
florian55085f82012-11-21 00:36:55 +00008807static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008808s390_irgen_DEB(UChar r1, IRTemp op2addr)
8809{
8810 IRTemp op1 = newTemp(Ity_F32);
8811 IRTemp op2 = newTemp(Ity_F32);
8812 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00008813 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008814
8815 assign(op1, get_fpr_w0(r1));
8816 assign(op2, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00008817 assign(result, triop(Iop_DivF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008818 mkexpr(op2)));
8819 put_fpr_w0(r1, mkexpr(result));
8820
8821 return "deb";
8822}
8823
florian55085f82012-11-21 00:36:55 +00008824static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008825s390_irgen_DDB(UChar r1, IRTemp op2addr)
8826{
8827 IRTemp op1 = newTemp(Ity_F64);
8828 IRTemp op2 = newTemp(Ity_F64);
8829 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00008830 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008831
8832 assign(op1, get_fpr_dw0(r1));
8833 assign(op2, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00008834 assign(result, triop(Iop_DivF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008835 mkexpr(op2)));
8836 put_fpr_dw0(r1, mkexpr(result));
8837
8838 return "ddb";
8839}
8840
florian55085f82012-11-21 00:36:55 +00008841static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008842s390_irgen_LTEBR(UChar r1, UChar r2)
8843{
8844 IRTemp result = newTemp(Ity_F32);
8845
8846 assign(result, get_fpr_w0(r2));
8847 put_fpr_w0(r1, mkexpr(result));
8848 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8849
8850 return "ltebr";
8851}
8852
florian55085f82012-11-21 00:36:55 +00008853static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008854s390_irgen_LTDBR(UChar r1, UChar r2)
8855{
8856 IRTemp result = newTemp(Ity_F64);
8857
8858 assign(result, get_fpr_dw0(r2));
8859 put_fpr_dw0(r1, mkexpr(result));
8860 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8861
8862 return "ltdbr";
8863}
8864
florian55085f82012-11-21 00:36:55 +00008865static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008866s390_irgen_LCEBR(UChar r1, UChar r2)
8867{
8868 IRTemp result = newTemp(Ity_F32);
8869
8870 assign(result, unop(Iop_NegF32, get_fpr_w0(r2)));
8871 put_fpr_w0(r1, mkexpr(result));
8872 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8873
8874 return "lcebr";
8875}
8876
florian55085f82012-11-21 00:36:55 +00008877static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008878s390_irgen_LCDBR(UChar r1, UChar r2)
8879{
8880 IRTemp result = newTemp(Ity_F64);
8881
8882 assign(result, unop(Iop_NegF64, get_fpr_dw0(r2)));
8883 put_fpr_dw0(r1, mkexpr(result));
8884 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8885
8886 return "lcdbr";
8887}
8888
florian55085f82012-11-21 00:36:55 +00008889static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008890s390_irgen_LDEBR(UChar r1, UChar r2)
8891{
8892 IRTemp op = newTemp(Ity_F32);
8893
8894 assign(op, get_fpr_w0(r2));
8895 put_fpr_dw0(r1, unop(Iop_F32toF64, mkexpr(op)));
8896
8897 return "ldebr";
8898}
8899
florian55085f82012-11-21 00:36:55 +00008900static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008901s390_irgen_LDEB(UChar r1, IRTemp op2addr)
8902{
8903 IRTemp op = newTemp(Ity_F32);
8904
8905 assign(op, load(Ity_F32, mkexpr(op2addr)));
8906 put_fpr_dw0(r1, unop(Iop_F32toF64, mkexpr(op)));
8907
8908 return "ldeb";
8909}
8910
florian55085f82012-11-21 00:36:55 +00008911static const HChar *
florian4b8efad2012-09-02 18:07:08 +00008912s390_irgen_LEDBR(UChar m3, UChar m4 __attribute__((unused)),
8913 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008914{
florian125e20d2012-10-07 15:42:37 +00008915 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian12b0bca2012-09-05 20:05:20 +00008916 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +00008917 m3 = S390_BFP_ROUND_PER_FPC;
florian12b0bca2012-09-05 20:05:20 +00008918 }
sewardj2019a972011-03-07 16:04:07 +00008919 IRTemp op = newTemp(Ity_F64);
8920
8921 assign(op, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008922 put_fpr_w0(r1, binop(Iop_F64toF32, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +00008923 mkexpr(op)));
sewardj2019a972011-03-07 16:04:07 +00008924
8925 return "ledbr";
8926}
8927
florian55085f82012-11-21 00:36:55 +00008928static const HChar *
florian12390202012-11-10 22:34:14 +00008929s390_irgen_LTDTR(UChar r1, UChar r2)
8930{
8931 IRTemp result = newTemp(Ity_D64);
8932
8933 assign(result, get_dpr_dw0(r2));
8934 put_dpr_dw0(r1, mkexpr(result));
8935 s390_cc_thunk_putF(S390_CC_OP_DFP_RESULT_64, result);
8936
8937 return "ltdtr";
8938}
8939
florian55085f82012-11-21 00:36:55 +00008940static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008941s390_irgen_MEEBR(UChar r1, UChar r2)
8942{
8943 IRTemp op1 = newTemp(Ity_F32);
8944 IRTemp op2 = newTemp(Ity_F32);
8945 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00008946 IRRoundingMode rounding_mode =
8947 encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008948
8949 assign(op1, get_fpr_w0(r1));
8950 assign(op2, get_fpr_w0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008951 assign(result, triop(Iop_MulF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008952 mkexpr(op2)));
8953 put_fpr_w0(r1, mkexpr(result));
8954
8955 return "meebr";
8956}
8957
florian55085f82012-11-21 00:36:55 +00008958static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008959s390_irgen_MDBR(UChar r1, UChar r2)
8960{
8961 IRTemp op1 = newTemp(Ity_F64);
8962 IRTemp op2 = newTemp(Ity_F64);
8963 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00008964 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008965
8966 assign(op1, get_fpr_dw0(r1));
8967 assign(op2, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008968 assign(result, triop(Iop_MulF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008969 mkexpr(op2)));
8970 put_fpr_dw0(r1, mkexpr(result));
8971
8972 return "mdbr";
8973}
8974
florian55085f82012-11-21 00:36:55 +00008975static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008976s390_irgen_MEEB(UChar r1, IRTemp op2addr)
8977{
8978 IRTemp op1 = newTemp(Ity_F32);
8979 IRTemp op2 = newTemp(Ity_F32);
8980 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00008981 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008982
8983 assign(op1, get_fpr_w0(r1));
8984 assign(op2, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00008985 assign(result, triop(Iop_MulF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008986 mkexpr(op2)));
8987 put_fpr_w0(r1, mkexpr(result));
8988
8989 return "meeb";
8990}
8991
florian55085f82012-11-21 00:36:55 +00008992static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008993s390_irgen_MDB(UChar r1, IRTemp op2addr)
8994{
8995 IRTemp op1 = newTemp(Ity_F64);
8996 IRTemp op2 = newTemp(Ity_F64);
8997 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00008998 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008999
9000 assign(op1, get_fpr_dw0(r1));
9001 assign(op2, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00009002 assign(result, triop(Iop_MulF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009003 mkexpr(op2)));
9004 put_fpr_dw0(r1, mkexpr(result));
9005
9006 return "mdb";
9007}
9008
florian55085f82012-11-21 00:36:55 +00009009static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009010s390_irgen_SEBR(UChar r1, UChar r2)
9011{
9012 IRTemp op1 = newTemp(Ity_F32);
9013 IRTemp op2 = newTemp(Ity_F32);
9014 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00009015 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009016
9017 assign(op1, get_fpr_w0(r1));
9018 assign(op2, get_fpr_w0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009019 assign(result, triop(Iop_SubF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009020 mkexpr(op2)));
9021 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
9022 put_fpr_w0(r1, mkexpr(result));
9023
9024 return "sebr";
9025}
9026
florian55085f82012-11-21 00:36:55 +00009027static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009028s390_irgen_SDBR(UChar r1, UChar r2)
9029{
9030 IRTemp op1 = newTemp(Ity_F64);
9031 IRTemp op2 = newTemp(Ity_F64);
9032 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00009033 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009034
9035 assign(op1, get_fpr_dw0(r1));
9036 assign(op2, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009037 assign(result, triop(Iop_SubF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009038 mkexpr(op2)));
9039 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
9040 put_fpr_dw0(r1, mkexpr(result));
9041
9042 return "sdbr";
9043}
9044
florian55085f82012-11-21 00:36:55 +00009045static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009046s390_irgen_SEB(UChar r1, IRTemp op2addr)
9047{
9048 IRTemp op1 = newTemp(Ity_F32);
9049 IRTemp op2 = newTemp(Ity_F32);
9050 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00009051 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009052
9053 assign(op1, get_fpr_w0(r1));
9054 assign(op2, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00009055 assign(result, triop(Iop_SubF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009056 mkexpr(op2)));
9057 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
9058 put_fpr_w0(r1, mkexpr(result));
9059
9060 return "seb";
9061}
9062
florian55085f82012-11-21 00:36:55 +00009063static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009064s390_irgen_SDB(UChar r1, IRTemp op2addr)
9065{
9066 IRTemp op1 = newTemp(Ity_F64);
9067 IRTemp op2 = newTemp(Ity_F64);
9068 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00009069 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009070
9071 assign(op1, get_fpr_dw0(r1));
9072 assign(op2, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00009073 assign(result, triop(Iop_SubF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009074 mkexpr(op2)));
9075 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
9076 put_fpr_dw0(r1, mkexpr(result));
9077
9078 return "sdb";
9079}
9080
florian55085f82012-11-21 00:36:55 +00009081static const HChar *
florian12390202012-11-10 22:34:14 +00009082s390_irgen_ADTRA(UChar r3, UChar m4, UChar r1, UChar r2)
9083{
9084 IRTemp op1 = newTemp(Ity_D64);
9085 IRTemp op2 = newTemp(Ity_D64);
9086 IRTemp result = newTemp(Ity_D64);
9087 IRTemp rounding_mode;
9088
9089 vassert(s390_host_has_dfp);
9090 vassert(m4 == 0 || s390_host_has_fpext);
9091 /* when m4 = 0, S390_DFP_ROUND_PER_FPC_0 should be set.
9092 since S390_DFP_ROUND_PER_FPC_0 is also 0, passing m4 is sufficient */
9093 rounding_mode = encode_dfp_rounding_mode(m4);
9094 assign(op1, get_dpr_dw0(r2));
9095 assign(op2, get_dpr_dw0(r3));
9096 assign(result, triop(Iop_AddD64, mkexpr(rounding_mode), mkexpr(op1),
9097 mkexpr(op2)));
9098 s390_cc_thunk_putF(S390_CC_OP_DFP_RESULT_64, result);
9099 put_dpr_dw0(r1, mkexpr(result));
9100
9101 return (m4 == 0) ? "adtr" : "adtra";
9102}
9103
florian55085f82012-11-21 00:36:55 +00009104static const HChar *
florian12390202012-11-10 22:34:14 +00009105s390_irgen_DDTRA(UChar r3, UChar m4, UChar r1, UChar r2)
9106{
9107 IRTemp op1 = newTemp(Ity_D64);
9108 IRTemp op2 = newTemp(Ity_D64);
9109 IRTemp result = newTemp(Ity_D64);
9110 IRTemp rounding_mode;
9111
9112 vassert(s390_host_has_dfp);
9113 vassert(m4 == 0 || s390_host_has_fpext);
9114 /* when m4 = 0, S390_DFP_ROUND_PER_FPC_0 should be set.
9115 since S390_DFP_ROUND_PER_FPC_0 is also 0, passing m4 is sufficient */
9116 rounding_mode = encode_dfp_rounding_mode(m4);
9117 assign(op1, get_dpr_dw0(r2));
9118 assign(op2, get_dpr_dw0(r3));
9119 assign(result, triop(Iop_DivD64, mkexpr(rounding_mode), mkexpr(op1),
9120 mkexpr(op2)));
9121 s390_cc_thunk_putF(S390_CC_OP_DFP_RESULT_64, result);
9122 put_dpr_dw0(r1, mkexpr(result));
9123
9124 return (m4 == 0) ? "ddtr" : "ddtra";
9125}
9126
florian55085f82012-11-21 00:36:55 +00009127static const HChar *
florian12390202012-11-10 22:34:14 +00009128s390_irgen_MDTRA(UChar r3, UChar m4, UChar r1, UChar r2)
9129{
9130 IRTemp op1 = newTemp(Ity_D64);
9131 IRTemp op2 = newTemp(Ity_D64);
9132 IRTemp result = newTemp(Ity_D64);
9133 IRTemp rounding_mode;
9134
9135 vassert(s390_host_has_dfp);
9136 vassert(m4 == 0 || s390_host_has_fpext);
9137 /* when m4 = 0, S390_DFP_ROUND_PER_FPC_0 should be set.
9138 since S390_DFP_ROUND_PER_FPC_0 is also 0, passing m4 is sufficient */
9139 rounding_mode = encode_dfp_rounding_mode(m4);
9140 assign(op1, get_dpr_dw0(r2));
9141 assign(op2, get_dpr_dw0(r3));
9142 assign(result, triop(Iop_MulD64, mkexpr(rounding_mode), mkexpr(op1),
9143 mkexpr(op2)));
9144 s390_cc_thunk_putF(S390_CC_OP_DFP_RESULT_64, result);
9145 put_dpr_dw0(r1, mkexpr(result));
9146
9147 return (m4 == 0) ? "mdtr" : "mdtra";
9148}
9149
florian55085f82012-11-21 00:36:55 +00009150static const HChar *
florian12390202012-11-10 22:34:14 +00009151s390_irgen_SDTRA(UChar r3, UChar m4, UChar r1, UChar r2)
9152{
9153 IRTemp op1 = newTemp(Ity_D64);
9154 IRTemp op2 = newTemp(Ity_D64);
9155 IRTemp result = newTemp(Ity_D64);
9156 IRTemp rounding_mode;
9157
9158 vassert(s390_host_has_dfp);
9159 vassert(m4 == 0 || s390_host_has_fpext);
9160 /* when m4 = 0, S390_DFP_ROUND_PER_FPC_0 should be set.
9161 since S390_DFP_ROUND_PER_FPC_0 is also 0, passing m4 is sufficient */
9162 rounding_mode = encode_dfp_rounding_mode(m4);
9163 assign(op1, get_dpr_dw0(r2));
9164 assign(op2, get_dpr_dw0(r3));
9165 assign(result, triop(Iop_SubD64, mkexpr(rounding_mode), mkexpr(op1),
9166 mkexpr(op2)));
9167 s390_cc_thunk_putF(S390_CC_OP_DFP_RESULT_64, result);
9168 put_dpr_dw0(r1, mkexpr(result));
9169
9170 return (m4 == 0) ? "sdtr" : "sdtra";
9171}
9172
sewardj2019a972011-03-07 16:04:07 +00009173
florian55085f82012-11-21 00:36:55 +00009174static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009175s390_irgen_CLC(UChar length, IRTemp start1, IRTemp start2)
9176{
florian79e839e2012-05-05 02:20:30 +00009177 IRTemp len = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00009178
florian79e839e2012-05-05 02:20:30 +00009179 assign(len, mkU64(length));
9180 s390_irgen_CLC_EX(len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +00009181
9182 return "clc";
9183}
9184
florian55085f82012-11-21 00:36:55 +00009185static const HChar *
florianb0c9a132011-09-08 15:37:39 +00009186s390_irgen_CLCL(UChar r1, UChar r2)
9187{
9188 IRTemp addr1 = newTemp(Ity_I64);
9189 IRTemp addr2 = newTemp(Ity_I64);
9190 IRTemp addr1_load = newTemp(Ity_I64);
9191 IRTemp addr2_load = newTemp(Ity_I64);
9192 IRTemp len1 = newTemp(Ity_I32);
9193 IRTemp len2 = newTemp(Ity_I32);
9194 IRTemp r1p1 = newTemp(Ity_I32); /* contents of r1 + 1 */
9195 IRTemp r2p1 = newTemp(Ity_I32); /* contents of r2 + 1 */
9196 IRTemp single1 = newTemp(Ity_I8);
9197 IRTemp single2 = newTemp(Ity_I8);
9198 IRTemp pad = newTemp(Ity_I8);
9199
9200 assign(addr1, get_gpr_dw0(r1));
9201 assign(r1p1, get_gpr_w1(r1 + 1));
9202 assign(len1, binop(Iop_And32, mkexpr(r1p1), mkU32(0x00ffffff)));
9203 assign(addr2, get_gpr_dw0(r2));
9204 assign(r2p1, get_gpr_w1(r2 + 1));
9205 assign(len2, binop(Iop_And32, mkexpr(r2p1), mkU32(0x00ffffff)));
9206 assign(pad, get_gpr_b4(r2 + 1));
9207
9208 /* len1 == 0 and len2 == 0? Exit */
9209 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +00009210 next_insn_if(binop(Iop_CmpEQ32, binop(Iop_Or32, mkexpr(len1),
9211 mkexpr(len2)), mkU32(0)));
florianb0c9a132011-09-08 15:37:39 +00009212
9213 /* Because mkite evaluates both the then-clause and the else-clause
9214 we cannot load directly from addr1 here. If len1 is 0, then adddr1
9215 may be NULL and loading from there would segfault. So we provide a
9216 valid dummy address in that case. Loading from there does no harm and
9217 the value will be discarded at runtime. */
9218 assign(addr1_load,
9219 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
9220 mkU64(guest_IA_curr_instr), mkexpr(addr1)));
9221 assign(single1,
9222 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
9223 mkexpr(pad), load(Ity_I8, mkexpr(addr1_load))));
9224
9225 assign(addr2_load,
9226 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
9227 mkU64(guest_IA_curr_instr), mkexpr(addr2)));
9228 assign(single2,
9229 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
9230 mkexpr(pad), load(Ity_I8, mkexpr(addr2_load))));
9231
9232 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, single1, single2, False);
9233 /* Fields differ ? */
florian6820ba52012-07-26 02:01:50 +00009234 next_insn_if(binop(Iop_CmpNE8, mkexpr(single1), mkexpr(single2)));
florianb0c9a132011-09-08 15:37:39 +00009235
9236 /* Update len1 and addr1, unless len1 == 0. */
9237 put_gpr_dw0(r1,
9238 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
9239 mkexpr(addr1),
9240 binop(Iop_Add64, mkexpr(addr1), mkU64(1))));
9241
9242 /* When updating len1 we must not modify bits (r1+1)[0:39] */
9243 put_gpr_w1(r1 + 1,
9244 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
9245 binop(Iop_And32, mkexpr(r1p1), mkU32(0xFF000000u)),
9246 binop(Iop_Sub32, mkexpr(r1p1), mkU32(1))));
9247
9248 /* Update len2 and addr2, unless len2 == 0. */
9249 put_gpr_dw0(r2,
9250 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
9251 mkexpr(addr2),
9252 binop(Iop_Add64, mkexpr(addr2), mkU64(1))));
9253
9254 /* When updating len2 we must not modify bits (r2+1)[0:39] */
9255 put_gpr_w1(r2 + 1,
9256 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
9257 binop(Iop_And32, mkexpr(r2p1), mkU32(0xFF000000u)),
9258 binop(Iop_Sub32, mkexpr(r2p1), mkU32(1))));
9259
florian6820ba52012-07-26 02:01:50 +00009260 iterate();
florianb0c9a132011-09-08 15:37:39 +00009261
9262 return "clcl";
9263}
9264
florian55085f82012-11-21 00:36:55 +00009265static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009266s390_irgen_CLCLE(UChar r1, UChar r3, IRTemp pad2)
9267{
9268 IRTemp addr1, addr3, addr1_load, addr3_load, len1, len3, single1, single3;
9269
9270 addr1 = newTemp(Ity_I64);
9271 addr3 = newTemp(Ity_I64);
9272 addr1_load = newTemp(Ity_I64);
9273 addr3_load = newTemp(Ity_I64);
9274 len1 = newTemp(Ity_I64);
9275 len3 = newTemp(Ity_I64);
9276 single1 = newTemp(Ity_I8);
9277 single3 = newTemp(Ity_I8);
9278
9279 assign(addr1, get_gpr_dw0(r1));
9280 assign(len1, get_gpr_dw0(r1 + 1));
9281 assign(addr3, get_gpr_dw0(r3));
9282 assign(len3, get_gpr_dw0(r3 + 1));
9283
9284 /* len1 == 0 and len3 == 0? Exit */
9285 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +00009286 next_insn_if(binop(Iop_CmpEQ64,binop(Iop_Or64, mkexpr(len1),
9287 mkexpr(len3)), mkU64(0)));
sewardj2019a972011-03-07 16:04:07 +00009288
9289 /* A mux requires both ways to be possible. This is a way to prevent clcle
9290 from reading from addr1 if it should read from the pad. Since the pad
9291 has no address, just read from the instruction, we discard that anyway */
9292 assign(addr1_load,
florian6ad49522011-09-09 02:38:55 +00009293 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
9294 mkU64(guest_IA_curr_instr), mkexpr(addr1)));
sewardj2019a972011-03-07 16:04:07 +00009295
9296 /* same for addr3 */
9297 assign(addr3_load,
florian6ad49522011-09-09 02:38:55 +00009298 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
9299 mkU64(guest_IA_curr_instr), mkexpr(addr3)));
sewardj2019a972011-03-07 16:04:07 +00009300
9301 assign(single1,
florian6ad49522011-09-09 02:38:55 +00009302 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
9303 unop(Iop_64to8, mkexpr(pad2)),
9304 load(Ity_I8, mkexpr(addr1_load))));
sewardj2019a972011-03-07 16:04:07 +00009305
9306 assign(single3,
florian6ad49522011-09-09 02:38:55 +00009307 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
9308 unop(Iop_64to8, mkexpr(pad2)),
9309 load(Ity_I8, mkexpr(addr3_load))));
sewardj2019a972011-03-07 16:04:07 +00009310
9311 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, single1, single3, False);
9312 /* Both fields differ ? */
florian6820ba52012-07-26 02:01:50 +00009313 next_insn_if(binop(Iop_CmpNE8, mkexpr(single1), mkexpr(single3)));
sewardj2019a972011-03-07 16:04:07 +00009314
9315 /* If a length in 0 we must not change this length and the address */
9316 put_gpr_dw0(r1,
florian6ad49522011-09-09 02:38:55 +00009317 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
9318 mkexpr(addr1),
9319 binop(Iop_Add64, mkexpr(addr1), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +00009320
9321 put_gpr_dw0(r1 + 1,
florian6ad49522011-09-09 02:38:55 +00009322 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
9323 mkU64(0), binop(Iop_Sub64, mkexpr(len1), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +00009324
9325 put_gpr_dw0(r3,
florian6ad49522011-09-09 02:38:55 +00009326 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
9327 mkexpr(addr3),
9328 binop(Iop_Add64, mkexpr(addr3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +00009329
9330 put_gpr_dw0(r3 + 1,
florian6ad49522011-09-09 02:38:55 +00009331 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
9332 mkU64(0), binop(Iop_Sub64, mkexpr(len3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +00009333
florian6820ba52012-07-26 02:01:50 +00009334 iterate();
sewardj2019a972011-03-07 16:04:07 +00009335
9336 return "clcle";
9337}
floriana64c2432011-07-16 02:11:50 +00009338
florianb0bf6602012-05-05 00:01:16 +00009339
sewardj2019a972011-03-07 16:04:07 +00009340static void
9341s390_irgen_XC_EX(IRTemp length, IRTemp start1, IRTemp start2)
9342{
florianb0bf6602012-05-05 00:01:16 +00009343 s390_irgen_xonc(Iop_Xor8, length, start1, start2);
9344}
sewardj2019a972011-03-07 16:04:07 +00009345
sewardj2019a972011-03-07 16:04:07 +00009346
florianb0bf6602012-05-05 00:01:16 +00009347static void
9348s390_irgen_NC_EX(IRTemp length, IRTemp start1, IRTemp start2)
9349{
9350 s390_irgen_xonc(Iop_And8, length, start1, start2);
9351}
sewardj2019a972011-03-07 16:04:07 +00009352
sewardj2019a972011-03-07 16:04:07 +00009353
florianb0bf6602012-05-05 00:01:16 +00009354static void
9355s390_irgen_OC_EX(IRTemp length, IRTemp start1, IRTemp start2)
9356{
9357 s390_irgen_xonc(Iop_Or8, length, start1, start2);
sewardj2019a972011-03-07 16:04:07 +00009358}
9359
9360
9361static void
9362s390_irgen_CLC_EX(IRTemp length, IRTemp start1, IRTemp start2)
9363{
9364 IRTemp current1 = newTemp(Ity_I8);
9365 IRTemp current2 = newTemp(Ity_I8);
9366 IRTemp counter = newTemp(Ity_I64);
9367
9368 assign(counter, get_counter_dw0());
9369 put_counter_dw0(mkU64(0));
9370
9371 assign(current1, load(Ity_I8, binop(Iop_Add64, mkexpr(start1),
9372 mkexpr(counter))));
9373 assign(current2, load(Ity_I8, binop(Iop_Add64, mkexpr(start2),
9374 mkexpr(counter))));
9375 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, current1, current2,
9376 False);
9377
9378 /* Both fields differ ? */
florian6820ba52012-07-26 02:01:50 +00009379 next_insn_if(binop(Iop_CmpNE8, mkexpr(current1), mkexpr(current2)));
sewardj2019a972011-03-07 16:04:07 +00009380
9381 /* Check for end of field */
9382 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +00009383 iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
sewardj2019a972011-03-07 16:04:07 +00009384 put_counter_dw0(mkU64(0));
9385}
9386
9387static void
9388s390_irgen_MVC_EX(IRTemp length, IRTemp start1, IRTemp start2)
9389{
9390 IRTemp counter = newTemp(Ity_I64);
9391
9392 assign(counter, get_counter_dw0());
9393
9394 store(binop(Iop_Add64, mkexpr(start1), mkexpr(counter)),
9395 load(Ity_I8, binop(Iop_Add64, mkexpr(start2), mkexpr(counter))));
9396
9397 /* Check for end of field */
9398 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +00009399 iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
sewardj2019a972011-03-07 16:04:07 +00009400 put_counter_dw0(mkU64(0));
9401}
9402
florianf87d4fb2012-05-05 02:55:24 +00009403static void
9404s390_irgen_TR_EX(IRTemp length, IRTemp start1, IRTemp start2)
9405{
9406 IRTemp op = newTemp(Ity_I8);
9407 IRTemp op1 = newTemp(Ity_I8);
9408 IRTemp result = newTemp(Ity_I64);
9409 IRTemp counter = newTemp(Ity_I64);
9410
9411 assign(counter, get_counter_dw0());
9412
9413 assign(op, load(Ity_I8, binop(Iop_Add64, mkexpr(start1), mkexpr(counter))));
9414
9415 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)), mkexpr(start2)));
9416
9417 assign(op1, load(Ity_I8, mkexpr(result)));
9418 store(binop(Iop_Add64, mkexpr(start1), mkexpr(counter)), mkexpr(op1));
9419
9420 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +00009421 iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
florianf87d4fb2012-05-05 02:55:24 +00009422 put_counter_dw0(mkU64(0));
9423}
sewardj2019a972011-03-07 16:04:07 +00009424
9425
9426static void
9427s390_irgen_EX_SS(UChar r, IRTemp addr2,
florian6820ba52012-07-26 02:01:50 +00009428 void (*irgen)(IRTemp length, IRTemp start1, IRTemp start2),
9429 int lensize)
sewardj2019a972011-03-07 16:04:07 +00009430{
9431 struct SS {
9432 unsigned int op : 8;
9433 unsigned int l : 8;
9434 unsigned int b1 : 4;
9435 unsigned int d1 : 12;
9436 unsigned int b2 : 4;
9437 unsigned int d2 : 12;
9438 };
9439 union {
9440 struct SS dec;
9441 unsigned long bytes;
9442 } ss;
9443 IRTemp cond;
9444 IRDirty *d;
9445 IRTemp torun;
9446
9447 IRTemp start1 = newTemp(Ity_I64);
9448 IRTemp start2 = newTemp(Ity_I64);
9449 IRTemp len = newTemp(lensize == 64 ? Ity_I64 : Ity_I32);
9450 cond = newTemp(Ity_I1);
9451 torun = newTemp(Ity_I64);
9452
9453 assign(torun, load(Ity_I64, mkexpr(addr2)));
9454 /* Start with a check that the saved code is still correct */
9455 assign(cond, binop(Iop_CmpNE64, mkexpr(torun), mkU64(last_execute_target)));
9456 /* If not, save the new value */
9457 d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
9458 mkIRExprVec_1(mkexpr(torun)));
9459 d->guard = mkexpr(cond);
9460 stmt(IRStmt_Dirty(d));
9461
9462 /* and restart */
florian428dfdd2012-03-27 03:09:49 +00009463 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART),
9464 mkU64(guest_IA_curr_instr)));
9465 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN), mkU64(4)));
florian6820ba52012-07-26 02:01:50 +00009466 restart_if(mkexpr(cond));
sewardj2019a972011-03-07 16:04:07 +00009467
9468 ss.bytes = last_execute_target;
9469 assign(start1, binop(Iop_Add64, mkU64(ss.dec.d1),
9470 ss.dec.b1 != 0 ? get_gpr_dw0(ss.dec.b1) : mkU64(0)));
9471 assign(start2, binop(Iop_Add64, mkU64(ss.dec.d2),
9472 ss.dec.b2 != 0 ? get_gpr_dw0(ss.dec.b2) : mkU64(0)));
9473 assign(len, unop(lensize == 64 ? Iop_8Uto64 : Iop_8Uto32, binop(Iop_Or8,
9474 r != 0 ? get_gpr_b7(r): mkU8(0), mkU8(ss.dec.l))));
9475 irgen(len, start1, start2);
florian8844a632012-04-13 04:04:06 +00009476
sewardj2019a972011-03-07 16:04:07 +00009477 last_execute_target = 0;
9478}
9479
florian55085f82012-11-21 00:36:55 +00009480static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009481s390_irgen_EX(UChar r1, IRTemp addr2)
9482{
9483 switch(last_execute_target & 0xff00000000000000ULL) {
9484 case 0:
9485 {
9486 /* no code information yet */
9487 IRDirty *d;
9488
9489 /* so safe the code... */
9490 d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
9491 mkIRExprVec_1(load(Ity_I64, mkexpr(addr2))));
9492 stmt(IRStmt_Dirty(d));
9493 /* and restart */
florian428dfdd2012-03-27 03:09:49 +00009494 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART),
9495 mkU64(guest_IA_curr_instr)));
9496 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN), mkU64(4)));
florian6820ba52012-07-26 02:01:50 +00009497 restart_if(IRExpr_Const(IRConst_U1(True)));
9498
sewardj2019a972011-03-07 16:04:07 +00009499 /* we know that this will be invalidated */
florianf9e1ed72012-04-17 02:41:56 +00009500 put_IA(mkaddr_expr(guest_IA_next_instr));
sewardj2019a972011-03-07 16:04:07 +00009501 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +00009502 dis_res->jk_StopHere = Ijk_TInval;
sewardj2019a972011-03-07 16:04:07 +00009503 break;
9504 }
9505
9506 case 0xd200000000000000ULL:
9507 /* special case MVC */
9508 s390_irgen_EX_SS(r1, addr2, s390_irgen_MVC_EX, 64);
9509 return "mvc via ex";
9510
9511 case 0xd500000000000000ULL:
9512 /* special case CLC */
9513 s390_irgen_EX_SS(r1, addr2, s390_irgen_CLC_EX, 64);
9514 return "clc via ex";
9515
9516 case 0xd700000000000000ULL:
9517 /* special case XC */
9518 s390_irgen_EX_SS(r1, addr2, s390_irgen_XC_EX, 32);
9519 return "xc via ex";
9520
florianb0bf6602012-05-05 00:01:16 +00009521 case 0xd600000000000000ULL:
9522 /* special case OC */
9523 s390_irgen_EX_SS(r1, addr2, s390_irgen_OC_EX, 32);
9524 return "oc via ex";
9525
9526 case 0xd400000000000000ULL:
9527 /* special case NC */
9528 s390_irgen_EX_SS(r1, addr2, s390_irgen_NC_EX, 32);
9529 return "nc via ex";
sewardj2019a972011-03-07 16:04:07 +00009530
florianf87d4fb2012-05-05 02:55:24 +00009531 case 0xdc00000000000000ULL:
9532 /* special case TR */
9533 s390_irgen_EX_SS(r1, addr2, s390_irgen_TR_EX, 64);
9534 return "tr via ex";
9535
sewardj2019a972011-03-07 16:04:07 +00009536 default:
9537 {
9538 /* everything else will get a self checking prefix that also checks the
9539 register content */
9540 IRDirty *d;
9541 UChar *bytes;
9542 IRTemp cond;
9543 IRTemp orperand;
9544 IRTemp torun;
9545
9546 cond = newTemp(Ity_I1);
9547 orperand = newTemp(Ity_I64);
9548 torun = newTemp(Ity_I64);
9549
9550 if (r1 == 0)
9551 assign(orperand, mkU64(0));
9552 else
9553 assign(orperand, unop(Iop_8Uto64,get_gpr_b7(r1)));
9554 /* This code is going to be translated */
9555 assign(torun, binop(Iop_Or64, load(Ity_I64, mkexpr(addr2)),
9556 binop(Iop_Shl64, mkexpr(orperand), mkU8(48))));
9557
9558 /* Start with a check that saved code is still correct */
9559 assign(cond, binop(Iop_CmpNE64, mkexpr(torun),
9560 mkU64(last_execute_target)));
9561 /* If not, save the new value */
9562 d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
9563 mkIRExprVec_1(mkexpr(torun)));
9564 d->guard = mkexpr(cond);
9565 stmt(IRStmt_Dirty(d));
9566
9567 /* and restart */
florian428dfdd2012-03-27 03:09:49 +00009568 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART), mkU64(guest_IA_curr_instr)));
9569 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN), mkU64(4)));
florian6820ba52012-07-26 02:01:50 +00009570 restart_if(mkexpr(cond));
sewardj2019a972011-03-07 16:04:07 +00009571
9572 /* Now comes the actual translation */
9573 bytes = (UChar *) &last_execute_target;
9574 s390_decode_and_irgen(bytes, ((((bytes[0] >> 6) + 1) >> 1) + 1) << 1,
9575 dis_res);
sewardj7ee97522011-05-09 21:45:04 +00009576 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00009577 vex_printf(" which was executed by\n");
9578 /* dont make useless translations in the next execute */
9579 last_execute_target = 0;
9580 }
9581 }
9582 return "ex";
9583}
9584
florian55085f82012-11-21 00:36:55 +00009585static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009586s390_irgen_EXRL(UChar r1, UInt offset)
9587{
9588 IRTemp addr = newTemp(Ity_I64);
9589 /* we might save one round trip because we know the target */
9590 if (!last_execute_target)
9591 last_execute_target = *(ULong *)(HWord)
9592 (guest_IA_curr_instr + offset * 2UL);
9593 assign(addr, mkU64(guest_IA_curr_instr + offset * 2UL));
9594 s390_irgen_EX(r1, addr);
9595 return "exrl";
9596}
9597
florian55085f82012-11-21 00:36:55 +00009598static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009599s390_irgen_IPM(UChar r1)
9600{
9601 // As long as we dont support SPM, lets just assume 0 as program mask
9602 put_gpr_b4(r1, unop(Iop_32to8, binop(Iop_Or32, mkU32(0 /* program mask */),
9603 binop(Iop_Shl32, s390_call_calculate_cc(), mkU8(4)))));
9604
9605 return "ipm";
9606}
9607
9608
florian55085f82012-11-21 00:36:55 +00009609static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009610s390_irgen_SRST(UChar r1, UChar r2)
9611{
9612 IRTemp address = newTemp(Ity_I64);
9613 IRTemp next = newTemp(Ity_I64);
9614 IRTemp delim = newTemp(Ity_I8);
9615 IRTemp counter = newTemp(Ity_I64);
9616 IRTemp byte = newTemp(Ity_I8);
9617
9618 assign(address, get_gpr_dw0(r2));
9619 assign(next, get_gpr_dw0(r1));
9620
9621 assign(counter, get_counter_dw0());
9622 put_counter_dw0(mkU64(0));
9623
9624 // start = next? CC=2 and out r1 and r2 unchanged
9625 s390_cc_set(2);
9626 put_gpr_dw0(r2, binop(Iop_Sub64, mkexpr(address), mkexpr(counter)));
florian6820ba52012-07-26 02:01:50 +00009627 next_insn_if(binop(Iop_CmpEQ64, mkexpr(address), mkexpr(next)));
sewardj2019a972011-03-07 16:04:07 +00009628
9629 assign(byte, load(Ity_I8, mkexpr(address)));
9630 assign(delim, get_gpr_b7(0));
9631
9632 // byte = delim? CC=1, R1=address
9633 s390_cc_set(1);
9634 put_gpr_dw0(r1, mkexpr(address));
florian6820ba52012-07-26 02:01:50 +00009635 next_insn_if(binop(Iop_CmpEQ8, mkexpr(delim), mkexpr(byte)));
sewardj2019a972011-03-07 16:04:07 +00009636
9637 // else: all equal, no end yet, loop
9638 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
9639 put_gpr_dw0(r1, mkexpr(next));
9640 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(address), mkU64(1)));
floriancf87c942012-07-25 00:52:21 +00009641
florian6820ba52012-07-26 02:01:50 +00009642 iterate();
sewardj2019a972011-03-07 16:04:07 +00009643
9644 return "srst";
9645}
9646
florian55085f82012-11-21 00:36:55 +00009647static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009648s390_irgen_CLST(UChar r1, UChar r2)
9649{
9650 IRTemp address1 = newTemp(Ity_I64);
9651 IRTemp address2 = newTemp(Ity_I64);
9652 IRTemp end = newTemp(Ity_I8);
9653 IRTemp counter = newTemp(Ity_I64);
9654 IRTemp byte1 = newTemp(Ity_I8);
9655 IRTemp byte2 = newTemp(Ity_I8);
9656
9657 assign(address1, get_gpr_dw0(r1));
9658 assign(address2, get_gpr_dw0(r2));
9659 assign(end, get_gpr_b7(0));
9660 assign(counter, get_counter_dw0());
9661 put_counter_dw0(mkU64(0));
9662 assign(byte1, load(Ity_I8, mkexpr(address1)));
9663 assign(byte2, load(Ity_I8, mkexpr(address2)));
9664
9665 // end in both? all equal, reset r1 and r2 to start values
9666 s390_cc_set(0);
9667 put_gpr_dw0(r1, binop(Iop_Sub64, mkexpr(address1), mkexpr(counter)));
9668 put_gpr_dw0(r2, binop(Iop_Sub64, mkexpr(address2), mkexpr(counter)));
florian6820ba52012-07-26 02:01:50 +00009669 next_insn_if(binop(Iop_CmpEQ8, mkU8(0),
9670 binop(Iop_Or8,
9671 binop(Iop_Xor8, mkexpr(byte1), mkexpr(end)),
9672 binop(Iop_Xor8, mkexpr(byte2), mkexpr(end)))));
sewardj2019a972011-03-07 16:04:07 +00009673
9674 put_gpr_dw0(r1, mkexpr(address1));
9675 put_gpr_dw0(r2, mkexpr(address2));
9676
9677 // End found in string1
9678 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +00009679 next_insn_if(binop(Iop_CmpEQ8, mkexpr(end), mkexpr(byte1)));
sewardj2019a972011-03-07 16:04:07 +00009680
9681 // End found in string2
9682 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +00009683 next_insn_if(binop(Iop_CmpEQ8, mkexpr(end), mkexpr(byte2)));
sewardj2019a972011-03-07 16:04:07 +00009684
9685 // string1 < string2
9686 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +00009687 next_insn_if(binop(Iop_CmpLT32U, unop(Iop_8Uto32, mkexpr(byte1)),
9688 unop(Iop_8Uto32, mkexpr(byte2))));
sewardj2019a972011-03-07 16:04:07 +00009689
9690 // string2 < string1
9691 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +00009692 next_insn_if(binop(Iop_CmpLT32U, unop(Iop_8Uto32, mkexpr(byte2)),
9693 unop(Iop_8Uto32, mkexpr(byte1))));
sewardj2019a972011-03-07 16:04:07 +00009694
9695 // else: all equal, no end yet, loop
9696 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
9697 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), mkU64(1)));
9698 put_gpr_dw0(r2, binop(Iop_Add64, get_gpr_dw0(r2), mkU64(1)));
floriancf87c942012-07-25 00:52:21 +00009699
florian6820ba52012-07-26 02:01:50 +00009700 iterate();
sewardj2019a972011-03-07 16:04:07 +00009701
9702 return "clst";
9703}
9704
9705static void
9706s390_irgen_load_multiple_32bit(UChar r1, UChar r3, IRTemp op2addr)
9707{
9708 UChar reg;
9709 IRTemp addr = newTemp(Ity_I64);
9710
9711 assign(addr, mkexpr(op2addr));
9712 reg = r1;
9713 do {
9714 IRTemp old = addr;
9715
9716 reg %= 16;
9717 put_gpr_w1(reg, load(Ity_I32, mkexpr(addr)));
9718 addr = newTemp(Ity_I64);
9719 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
9720 reg++;
9721 } while (reg != (r3 + 1));
9722}
9723
florian55085f82012-11-21 00:36:55 +00009724static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009725s390_irgen_LM(UChar r1, UChar r3, IRTemp op2addr)
9726{
9727 s390_irgen_load_multiple_32bit(r1, r3, op2addr);
9728
9729 return "lm";
9730}
9731
florian55085f82012-11-21 00:36:55 +00009732static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009733s390_irgen_LMY(UChar r1, UChar r3, IRTemp op2addr)
9734{
9735 s390_irgen_load_multiple_32bit(r1, r3, op2addr);
9736
9737 return "lmy";
9738}
9739
florian55085f82012-11-21 00:36:55 +00009740static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009741s390_irgen_LMH(UChar r1, UChar r3, IRTemp op2addr)
9742{
9743 UChar reg;
9744 IRTemp addr = newTemp(Ity_I64);
9745
9746 assign(addr, mkexpr(op2addr));
9747 reg = r1;
9748 do {
9749 IRTemp old = addr;
9750
9751 reg %= 16;
9752 put_gpr_w0(reg, load(Ity_I32, mkexpr(addr)));
9753 addr = newTemp(Ity_I64);
9754 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
9755 reg++;
9756 } while (reg != (r3 + 1));
9757
9758 return "lmh";
9759}
9760
florian55085f82012-11-21 00:36:55 +00009761static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009762s390_irgen_LMG(UChar r1, UChar r3, IRTemp op2addr)
9763{
9764 UChar reg;
9765 IRTemp addr = newTemp(Ity_I64);
9766
9767 assign(addr, mkexpr(op2addr));
9768 reg = r1;
9769 do {
9770 IRTemp old = addr;
9771
9772 reg %= 16;
9773 put_gpr_dw0(reg, load(Ity_I64, mkexpr(addr)));
9774 addr = newTemp(Ity_I64);
9775 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(8)));
9776 reg++;
9777 } while (reg != (r3 + 1));
9778
9779 return "lmg";
9780}
9781
9782static void
9783s390_irgen_store_multiple_32bit(UChar r1, UChar r3, IRTemp op2addr)
9784{
9785 UChar reg;
9786 IRTemp addr = newTemp(Ity_I64);
9787
9788 assign(addr, mkexpr(op2addr));
9789 reg = r1;
9790 do {
9791 IRTemp old = addr;
9792
9793 reg %= 16;
9794 store(mkexpr(addr), get_gpr_w1(reg));
9795 addr = newTemp(Ity_I64);
9796 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
9797 reg++;
9798 } while( reg != (r3 + 1));
9799}
9800
florian55085f82012-11-21 00:36:55 +00009801static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009802s390_irgen_STM(UChar r1, UChar r3, IRTemp op2addr)
9803{
9804 s390_irgen_store_multiple_32bit(r1, r3, op2addr);
9805
9806 return "stm";
9807}
9808
florian55085f82012-11-21 00:36:55 +00009809static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009810s390_irgen_STMY(UChar r1, UChar r3, IRTemp op2addr)
9811{
9812 s390_irgen_store_multiple_32bit(r1, r3, op2addr);
9813
9814 return "stmy";
9815}
9816
florian55085f82012-11-21 00:36:55 +00009817static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009818s390_irgen_STMH(UChar r1, UChar r3, IRTemp op2addr)
9819{
9820 UChar reg;
9821 IRTemp addr = newTemp(Ity_I64);
9822
9823 assign(addr, mkexpr(op2addr));
9824 reg = r1;
9825 do {
9826 IRTemp old = addr;
9827
9828 reg %= 16;
9829 store(mkexpr(addr), get_gpr_w0(reg));
9830 addr = newTemp(Ity_I64);
9831 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
9832 reg++;
9833 } while( reg != (r3 + 1));
9834
9835 return "stmh";
9836}
9837
florian55085f82012-11-21 00:36:55 +00009838static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009839s390_irgen_STMG(UChar r1, UChar r3, IRTemp op2addr)
9840{
9841 UChar reg;
9842 IRTemp addr = newTemp(Ity_I64);
9843
9844 assign(addr, mkexpr(op2addr));
9845 reg = r1;
9846 do {
9847 IRTemp old = addr;
9848
9849 reg %= 16;
9850 store(mkexpr(addr), get_gpr_dw0(reg));
9851 addr = newTemp(Ity_I64);
9852 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(8)));
9853 reg++;
9854 } while( reg != (r3 + 1));
9855
9856 return "stmg";
9857}
9858
9859static void
florianb0bf6602012-05-05 00:01:16 +00009860s390_irgen_xonc(IROp op, IRTemp length, IRTemp start1, IRTemp start2)
sewardj2019a972011-03-07 16:04:07 +00009861{
9862 IRTemp old1 = newTemp(Ity_I8);
9863 IRTemp old2 = newTemp(Ity_I8);
9864 IRTemp new1 = newTemp(Ity_I8);
9865 IRTemp counter = newTemp(Ity_I32);
9866 IRTemp addr1 = newTemp(Ity_I64);
9867
9868 assign(counter, get_counter_w0());
9869
9870 assign(addr1, binop(Iop_Add64, mkexpr(start1),
9871 unop(Iop_32Uto64, mkexpr(counter))));
9872
9873 assign(old1, load(Ity_I8, mkexpr(addr1)));
9874 assign(old2, load(Ity_I8, binop(Iop_Add64, mkexpr(start2),
9875 unop(Iop_32Uto64,mkexpr(counter)))));
9876 assign(new1, binop(op, mkexpr(old1), mkexpr(old2)));
9877
9878 /* Special case: xc is used to zero memory */
sewardj2019a972011-03-07 16:04:07 +00009879 if (op == Iop_Xor8) {
9880 store(mkexpr(addr1),
florian6ad49522011-09-09 02:38:55 +00009881 mkite(binop(Iop_CmpEQ64, mkexpr(start1), mkexpr(start2)),
9882 mkU8(0), mkexpr(new1)));
sewardj2019a972011-03-07 16:04:07 +00009883 } else
9884 store(mkexpr(addr1), mkexpr(new1));
9885 put_counter_w1(binop(Iop_Or32, unop(Iop_8Uto32, mkexpr(new1)),
9886 get_counter_w1()));
9887
9888 /* Check for end of field */
9889 put_counter_w0(binop(Iop_Add32, mkexpr(counter), mkU32(1)));
florian6820ba52012-07-26 02:01:50 +00009890 iterate_if(binop(Iop_CmpNE32, mkexpr(counter), mkexpr(length)));
sewardj2019a972011-03-07 16:04:07 +00009891 s390_cc_thunk_put1(S390_CC_OP_BITWISE, mktemp(Ity_I32, get_counter_w1()),
9892 False);
9893 put_counter_dw0(mkU64(0));
9894}
9895
florian55085f82012-11-21 00:36:55 +00009896static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009897s390_irgen_XC(UChar length, IRTemp start1, IRTemp start2)
9898{
florianb0bf6602012-05-05 00:01:16 +00009899 IRTemp len = newTemp(Ity_I32);
9900
9901 assign(len, mkU32(length));
9902 s390_irgen_xonc(Iop_Xor8, len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +00009903
9904 return "xc";
9905}
9906
sewardjb63967e2011-03-24 08:50:04 +00009907static void
9908s390_irgen_XC_sameloc(UChar length, UChar b, UShort d)
9909{
9910 IRTemp counter = newTemp(Ity_I32);
9911 IRTemp start = newTemp(Ity_I64);
9912 IRTemp addr = newTemp(Ity_I64);
9913
9914 assign(start,
9915 binop(Iop_Add64, mkU64(d), b != 0 ? get_gpr_dw0(b) : mkU64(0)));
9916
9917 if (length < 8) {
9918 UInt i;
9919
9920 for (i = 0; i <= length; ++i) {
9921 store(binop(Iop_Add64, mkexpr(start), mkU64(i)), mkU8(0));
9922 }
9923 } else {
9924 assign(counter, get_counter_w0());
9925
9926 assign(addr, binop(Iop_Add64, mkexpr(start),
9927 unop(Iop_32Uto64, mkexpr(counter))));
9928
9929 store(mkexpr(addr), mkU8(0));
9930
9931 /* Check for end of field */
9932 put_counter_w0(binop(Iop_Add32, mkexpr(counter), mkU32(1)));
florian6820ba52012-07-26 02:01:50 +00009933 iterate_if(binop(Iop_CmpNE32, mkexpr(counter), mkU32(length)));
sewardjb63967e2011-03-24 08:50:04 +00009934
9935 /* Reset counter */
9936 put_counter_dw0(mkU64(0));
9937 }
9938
9939 s390_cc_thunk_put1(S390_CC_OP_BITWISE, mktemp(Ity_I32, mkU32(0)), False);
9940
sewardj7ee97522011-05-09 21:45:04 +00009941 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardjb63967e2011-03-24 08:50:04 +00009942 s390_disasm(ENC3(MNM, UDLB, UDXB), "xc", d, length, b, d, 0, b);
9943}
9944
florian55085f82012-11-21 00:36:55 +00009945static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009946s390_irgen_NC(UChar length, IRTemp start1, IRTemp start2)
9947{
florianb0bf6602012-05-05 00:01:16 +00009948 IRTemp len = newTemp(Ity_I32);
9949
9950 assign(len, mkU32(length));
9951 s390_irgen_xonc(Iop_And8, len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +00009952
9953 return "nc";
9954}
9955
florian55085f82012-11-21 00:36:55 +00009956static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009957s390_irgen_OC(UChar length, IRTemp start1, IRTemp start2)
9958{
florianb0bf6602012-05-05 00:01:16 +00009959 IRTemp len = newTemp(Ity_I32);
9960
9961 assign(len, mkU32(length));
9962 s390_irgen_xonc(Iop_Or8, len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +00009963
9964 return "oc";
9965}
9966
9967
florian55085f82012-11-21 00:36:55 +00009968static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009969s390_irgen_MVC(UChar length, IRTemp start1, IRTemp start2)
9970{
florian79e839e2012-05-05 02:20:30 +00009971 IRTemp len = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00009972
florian79e839e2012-05-05 02:20:30 +00009973 assign(len, mkU64(length));
9974 s390_irgen_MVC_EX(len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +00009975
9976 return "mvc";
9977}
9978
florian55085f82012-11-21 00:36:55 +00009979static const HChar *
florianb0c9a132011-09-08 15:37:39 +00009980s390_irgen_MVCL(UChar r1, UChar r2)
9981{
9982 IRTemp addr1 = newTemp(Ity_I64);
9983 IRTemp addr2 = newTemp(Ity_I64);
9984 IRTemp addr2_load = newTemp(Ity_I64);
9985 IRTemp r1p1 = newTemp(Ity_I32); /* contents of r1 + 1 */
9986 IRTemp r2p1 = newTemp(Ity_I32); /* contents of r2 + 1 */
9987 IRTemp len1 = newTemp(Ity_I32);
9988 IRTemp len2 = newTemp(Ity_I32);
9989 IRTemp pad = newTemp(Ity_I8);
9990 IRTemp single = newTemp(Ity_I8);
9991
9992 assign(addr1, get_gpr_dw0(r1));
9993 assign(r1p1, get_gpr_w1(r1 + 1));
9994 assign(len1, binop(Iop_And32, mkexpr(r1p1), mkU32(0x00ffffff)));
9995 assign(addr2, get_gpr_dw0(r2));
9996 assign(r2p1, get_gpr_w1(r2 + 1));
9997 assign(len2, binop(Iop_And32, mkexpr(r2p1), mkU32(0x00ffffff)));
9998 assign(pad, get_gpr_b4(r2 + 1));
9999
10000 /* len1 == 0 ? */
10001 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len2, False);
florian6820ba52012-07-26 02:01:50 +000010002 next_insn_if(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)));
florianb0c9a132011-09-08 15:37:39 +000010003
10004 /* Check for destructive overlap:
10005 addr1 > addr2 && addr2 + len1 > addr1 && (addr2 + len2) > addr1 */
10006 s390_cc_set(3);
10007 IRTemp cond1 = newTemp(Ity_I32);
10008 assign(cond1, unop(Iop_1Uto32,
10009 binop(Iop_CmpLT64U, mkexpr(addr2), mkexpr(addr1))));
10010 IRTemp cond2 = newTemp(Ity_I32);
10011 assign(cond2, unop(Iop_1Uto32,
10012 binop(Iop_CmpLT64U, mkexpr(addr1),
10013 binop(Iop_Add64, mkexpr(addr2),
10014 unop(Iop_32Uto64, mkexpr(len1))))));
10015 IRTemp cond3 = newTemp(Ity_I32);
10016 assign(cond3, unop(Iop_1Uto32,
10017 binop(Iop_CmpLT64U,
10018 mkexpr(addr1),
10019 binop(Iop_Add64, mkexpr(addr2),
10020 unop(Iop_32Uto64, mkexpr(len2))))));
10021
florian6820ba52012-07-26 02:01:50 +000010022 next_insn_if(binop(Iop_CmpEQ32,
10023 binop(Iop_And32,
10024 binop(Iop_And32, mkexpr(cond1), mkexpr(cond2)),
10025 mkexpr(cond3)),
10026 mkU32(1)));
florianb0c9a132011-09-08 15:37:39 +000010027
10028 /* See s390_irgen_CLCL for explanation why we cannot load directly
10029 and need two steps. */
10030 assign(addr2_load,
10031 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
10032 mkU64(guest_IA_curr_instr), mkexpr(addr2)));
10033 assign(single,
10034 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
10035 mkexpr(pad), load(Ity_I8, mkexpr(addr2_load))));
10036
10037 store(mkexpr(addr1), mkexpr(single));
10038
10039 /* Update addr1 and len1 */
10040 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(1)));
10041 put_gpr_w1(r1 + 1, binop(Iop_Sub32, mkexpr(r1p1), mkU32(1)));
10042
10043 /* Update addr2 and len2 */
10044 put_gpr_dw0(r2,
10045 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
10046 mkexpr(addr2),
10047 binop(Iop_Add64, mkexpr(addr2), mkU64(1))));
10048
10049 /* When updating len2 we must not modify bits (r2+1)[0:39] */
10050 put_gpr_w1(r2 + 1,
10051 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
10052 binop(Iop_And32, mkexpr(r2p1), mkU32(0xFF000000u)),
10053 binop(Iop_Sub32, mkexpr(r2p1), mkU32(1))));
10054
10055 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len2, False);
florian6820ba52012-07-26 02:01:50 +000010056 iterate_if(binop(Iop_CmpNE32, mkexpr(len1), mkU32(1)));
florianb0c9a132011-09-08 15:37:39 +000010057
10058 return "mvcl";
10059}
10060
10061
florian55085f82012-11-21 00:36:55 +000010062static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010063s390_irgen_MVCLE(UChar r1, UChar r3, IRTemp pad2)
10064{
10065 IRTemp addr1, addr3, addr3_load, len1, len3, single;
10066
10067 addr1 = newTemp(Ity_I64);
10068 addr3 = newTemp(Ity_I64);
10069 addr3_load = newTemp(Ity_I64);
10070 len1 = newTemp(Ity_I64);
10071 len3 = newTemp(Ity_I64);
10072 single = newTemp(Ity_I8);
10073
10074 assign(addr1, get_gpr_dw0(r1));
10075 assign(len1, get_gpr_dw0(r1 + 1));
10076 assign(addr3, get_gpr_dw0(r3));
10077 assign(len3, get_gpr_dw0(r3 + 1));
10078
10079 // len1 == 0 ?
10080 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len3, False);
florian6820ba52012-07-26 02:01:50 +000010081 next_insn_if(binop(Iop_CmpEQ64,mkexpr(len1), mkU64(0)));
sewardj2019a972011-03-07 16:04:07 +000010082
10083 /* This is a hack to prevent mvcle from reading from addr3 if it
10084 should read from the pad. Since the pad has no address, just
10085 read from the instruction, we discard that anyway */
10086 assign(addr3_load,
florian6ad49522011-09-09 02:38:55 +000010087 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
10088 mkU64(guest_IA_curr_instr), mkexpr(addr3)));
sewardj2019a972011-03-07 16:04:07 +000010089
10090 assign(single,
florian6ad49522011-09-09 02:38:55 +000010091 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
10092 unop(Iop_64to8, mkexpr(pad2)),
10093 load(Ity_I8, mkexpr(addr3_load))));
sewardj2019a972011-03-07 16:04:07 +000010094 store(mkexpr(addr1), mkexpr(single));
10095
10096 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(1)));
10097
10098 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkU64(1)));
10099
10100 put_gpr_dw0(r3,
florian6ad49522011-09-09 02:38:55 +000010101 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
10102 mkexpr(addr3),
10103 binop(Iop_Add64, mkexpr(addr3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +000010104
10105 put_gpr_dw0(r3 + 1,
florian6ad49522011-09-09 02:38:55 +000010106 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
10107 mkU64(0), binop(Iop_Sub64, mkexpr(len3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +000010108
sewardj2019a972011-03-07 16:04:07 +000010109 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len3, False);
florian6820ba52012-07-26 02:01:50 +000010110 iterate_if(binop(Iop_CmpNE64, mkexpr(len1), mkU64(1)));
sewardj2019a972011-03-07 16:04:07 +000010111
10112 return "mvcle";
10113}
10114
florian55085f82012-11-21 00:36:55 +000010115static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010116s390_irgen_MVST(UChar r1, UChar r2)
10117{
10118 IRTemp addr1 = newTemp(Ity_I64);
10119 IRTemp addr2 = newTemp(Ity_I64);
10120 IRTemp end = newTemp(Ity_I8);
10121 IRTemp byte = newTemp(Ity_I8);
10122 IRTemp counter = newTemp(Ity_I64);
10123
10124 assign(addr1, get_gpr_dw0(r1));
10125 assign(addr2, get_gpr_dw0(r2));
10126 assign(counter, get_counter_dw0());
10127 assign(end, get_gpr_b7(0));
10128 assign(byte, load(Ity_I8, binop(Iop_Add64, mkexpr(addr2),mkexpr(counter))));
10129 store(binop(Iop_Add64,mkexpr(addr1),mkexpr(counter)), mkexpr(byte));
10130
10131 // We use unlimited as cpu-determined number
10132 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +000010133 iterate_if(binop(Iop_CmpNE8, mkexpr(end), mkexpr(byte)));
sewardj2019a972011-03-07 16:04:07 +000010134
10135 // and always set cc=1 at the end + update r1
10136 s390_cc_set(1);
10137 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(counter)));
10138 put_counter_dw0(mkU64(0));
10139
10140 return "mvst";
10141}
10142
10143static void
10144s390_irgen_divide_64to32(IROp op, UChar r1, IRTemp op2)
10145{
10146 IRTemp op1 = newTemp(Ity_I64);
10147 IRTemp result = newTemp(Ity_I64);
10148
10149 assign(op1, binop(Iop_32HLto64,
10150 get_gpr_w1(r1), // high 32 bits
10151 get_gpr_w1(r1 + 1))); // low 32 bits
10152 assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
10153 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result))); // remainder
10154 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result))); // quotient
10155}
10156
10157static void
10158s390_irgen_divide_128to64(IROp op, UChar r1, IRTemp op2)
10159{
10160 IRTemp op1 = newTemp(Ity_I128);
10161 IRTemp result = newTemp(Ity_I128);
10162
10163 assign(op1, binop(Iop_64HLto128,
10164 get_gpr_dw0(r1), // high 64 bits
10165 get_gpr_dw0(r1 + 1))); // low 64 bits
10166 assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
10167 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result))); // remainder
10168 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result))); // quotient
10169}
10170
10171static void
10172s390_irgen_divide_64to64(IROp op, UChar r1, IRTemp op2)
10173{
10174 IRTemp op1 = newTemp(Ity_I64);
10175 IRTemp result = newTemp(Ity_I128);
10176
10177 assign(op1, get_gpr_dw0(r1 + 1));
10178 assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
10179 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result))); // remainder
10180 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result))); // quotient
10181}
10182
florian55085f82012-11-21 00:36:55 +000010183static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010184s390_irgen_DR(UChar r1, UChar r2)
10185{
10186 IRTemp op2 = newTemp(Ity_I32);
10187
10188 assign(op2, get_gpr_w1(r2));
10189
10190 s390_irgen_divide_64to32(Iop_DivModS64to32, r1, op2);
10191
10192 return "dr";
10193}
10194
florian55085f82012-11-21 00:36:55 +000010195static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010196s390_irgen_D(UChar r1, IRTemp op2addr)
10197{
10198 IRTemp op2 = newTemp(Ity_I32);
10199
10200 assign(op2, load(Ity_I32, mkexpr(op2addr)));
10201
10202 s390_irgen_divide_64to32(Iop_DivModS64to32, r1, op2);
10203
10204 return "d";
10205}
10206
florian55085f82012-11-21 00:36:55 +000010207static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010208s390_irgen_DLR(UChar r1, UChar r2)
10209{
10210 IRTemp op2 = newTemp(Ity_I32);
10211
10212 assign(op2, get_gpr_w1(r2));
10213
10214 s390_irgen_divide_64to32(Iop_DivModU64to32, r1, op2);
10215
florian7cd1cde2012-08-16 23:57:43 +000010216 return "dlr";
sewardj2019a972011-03-07 16:04:07 +000010217}
10218
florian55085f82012-11-21 00:36:55 +000010219static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010220s390_irgen_DL(UChar r1, IRTemp op2addr)
10221{
10222 IRTemp op2 = newTemp(Ity_I32);
10223
10224 assign(op2, load(Ity_I32, mkexpr(op2addr)));
10225
10226 s390_irgen_divide_64to32(Iop_DivModU64to32, r1, op2);
10227
10228 return "dl";
10229}
10230
florian55085f82012-11-21 00:36:55 +000010231static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010232s390_irgen_DLG(UChar r1, IRTemp op2addr)
10233{
10234 IRTemp op2 = newTemp(Ity_I64);
10235
10236 assign(op2, load(Ity_I64, mkexpr(op2addr)));
10237
10238 s390_irgen_divide_128to64(Iop_DivModU128to64, r1, op2);
10239
10240 return "dlg";
10241}
10242
florian55085f82012-11-21 00:36:55 +000010243static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010244s390_irgen_DLGR(UChar r1, UChar r2)
10245{
10246 IRTemp op2 = newTemp(Ity_I64);
10247
10248 assign(op2, get_gpr_dw0(r2));
10249
10250 s390_irgen_divide_128to64(Iop_DivModU128to64, r1, op2);
10251
10252 return "dlgr";
10253}
10254
florian55085f82012-11-21 00:36:55 +000010255static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010256s390_irgen_DSGR(UChar r1, UChar r2)
10257{
10258 IRTemp op2 = newTemp(Ity_I64);
10259
10260 assign(op2, get_gpr_dw0(r2));
10261
10262 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
10263
10264 return "dsgr";
10265}
10266
florian55085f82012-11-21 00:36:55 +000010267static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010268s390_irgen_DSG(UChar r1, IRTemp op2addr)
10269{
10270 IRTemp op2 = newTemp(Ity_I64);
10271
10272 assign(op2, load(Ity_I64, mkexpr(op2addr)));
10273
10274 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
10275
10276 return "dsg";
10277}
10278
florian55085f82012-11-21 00:36:55 +000010279static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010280s390_irgen_DSGFR(UChar r1, UChar r2)
10281{
10282 IRTemp op2 = newTemp(Ity_I64);
10283
10284 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
10285
10286 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
10287
10288 return "dsgfr";
10289}
10290
florian55085f82012-11-21 00:36:55 +000010291static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010292s390_irgen_DSGF(UChar r1, IRTemp op2addr)
10293{
10294 IRTemp op2 = newTemp(Ity_I64);
10295
10296 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
10297
10298 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
10299
10300 return "dsgf";
10301}
10302
10303static void
10304s390_irgen_load_ar_multiple(UChar r1, UChar r3, IRTemp op2addr)
10305{
10306 UChar reg;
10307 IRTemp addr = newTemp(Ity_I64);
10308
10309 assign(addr, mkexpr(op2addr));
10310 reg = r1;
10311 do {
10312 IRTemp old = addr;
10313
10314 reg %= 16;
10315 put_ar_w0(reg, load(Ity_I32, mkexpr(addr)));
10316 addr = newTemp(Ity_I64);
10317 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
10318 reg++;
10319 } while (reg != (r3 + 1));
10320}
10321
florian55085f82012-11-21 00:36:55 +000010322static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010323s390_irgen_LAM(UChar r1, UChar r3, IRTemp op2addr)
10324{
10325 s390_irgen_load_ar_multiple(r1, r3, op2addr);
10326
10327 return "lam";
10328}
10329
florian55085f82012-11-21 00:36:55 +000010330static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010331s390_irgen_LAMY(UChar r1, UChar r3, IRTemp op2addr)
10332{
10333 s390_irgen_load_ar_multiple(r1, r3, op2addr);
10334
10335 return "lamy";
10336}
10337
10338static void
10339s390_irgen_store_ar_multiple(UChar r1, UChar r3, IRTemp op2addr)
10340{
10341 UChar reg;
10342 IRTemp addr = newTemp(Ity_I64);
10343
10344 assign(addr, mkexpr(op2addr));
10345 reg = r1;
10346 do {
10347 IRTemp old = addr;
10348
10349 reg %= 16;
10350 store(mkexpr(addr), get_ar_w0(reg));
10351 addr = newTemp(Ity_I64);
10352 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
10353 reg++;
10354 } while (reg != (r3 + 1));
10355}
10356
florian55085f82012-11-21 00:36:55 +000010357static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010358s390_irgen_STAM(UChar r1, UChar r3, IRTemp op2addr)
10359{
10360 s390_irgen_store_ar_multiple(r1, r3, op2addr);
10361
10362 return "stam";
10363}
10364
florian55085f82012-11-21 00:36:55 +000010365static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010366s390_irgen_STAMY(UChar r1, UChar r3, IRTemp op2addr)
10367{
10368 s390_irgen_store_ar_multiple(r1, r3, op2addr);
10369
10370 return "stamy";
10371}
10372
10373
10374/* Implementation for 32-bit compare-and-swap */
10375static void
10376s390_irgen_cas_32(UChar r1, UChar r3, IRTemp op2addr)
10377{
10378 IRCAS *cas;
10379 IRTemp op1 = newTemp(Ity_I32);
10380 IRTemp old_mem = newTemp(Ity_I32);
10381 IRTemp op3 = newTemp(Ity_I32);
10382 IRTemp result = newTemp(Ity_I32);
10383 IRTemp nequal = newTemp(Ity_I1);
10384
10385 assign(op1, get_gpr_w1(r1));
10386 assign(op3, get_gpr_w1(r3));
10387
10388 /* The first and second operands are compared. If they are equal,
10389 the third operand is stored at the second- operand location. */
10390 cas = mkIRCAS(IRTemp_INVALID, old_mem,
10391 Iend_BE, mkexpr(op2addr),
10392 NULL, mkexpr(op1), /* expected value */
10393 NULL, mkexpr(op3) /* new value */);
10394 stmt(IRStmt_CAS(cas));
10395
10396 /* Set CC. Operands compared equal -> 0, else 1. */
10397 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(old_mem)));
10398 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
10399
10400 /* If operands were equal (cc == 0) just store the old value op1 in r1.
10401 Otherwise, store the old_value from memory in r1 and yield. */
10402 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
10403 put_gpr_w1(r1, mkite(mkexpr(nequal), mkexpr(old_mem), mkexpr(op1)));
florian6820ba52012-07-26 02:01:50 +000010404 yield_if(mkexpr(nequal));
sewardj2019a972011-03-07 16:04:07 +000010405}
10406
florian55085f82012-11-21 00:36:55 +000010407static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010408s390_irgen_CS(UChar r1, UChar r3, IRTemp op2addr)
10409{
10410 s390_irgen_cas_32(r1, r3, op2addr);
10411
10412 return "cs";
10413}
10414
florian55085f82012-11-21 00:36:55 +000010415static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010416s390_irgen_CSY(UChar r1, UChar r3, IRTemp op2addr)
10417{
10418 s390_irgen_cas_32(r1, r3, op2addr);
10419
10420 return "csy";
10421}
10422
florian55085f82012-11-21 00:36:55 +000010423static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010424s390_irgen_CSG(UChar r1, UChar r3, IRTemp op2addr)
10425{
10426 IRCAS *cas;
10427 IRTemp op1 = newTemp(Ity_I64);
10428 IRTemp old_mem = newTemp(Ity_I64);
10429 IRTemp op3 = newTemp(Ity_I64);
10430 IRTemp result = newTemp(Ity_I64);
10431 IRTemp nequal = newTemp(Ity_I1);
10432
10433 assign(op1, get_gpr_dw0(r1));
10434 assign(op3, get_gpr_dw0(r3));
10435
10436 /* The first and second operands are compared. If they are equal,
10437 the third operand is stored at the second- operand location. */
10438 cas = mkIRCAS(IRTemp_INVALID, old_mem,
10439 Iend_BE, mkexpr(op2addr),
10440 NULL, mkexpr(op1), /* expected value */
10441 NULL, mkexpr(op3) /* new value */);
10442 stmt(IRStmt_CAS(cas));
10443
10444 /* Set CC. Operands compared equal -> 0, else 1. */
10445 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(old_mem)));
10446 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
10447
10448 /* If operands were equal (cc == 0) just store the old value op1 in r1.
10449 Otherwise, store the old_value from memory in r1 and yield. */
10450 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
10451 put_gpr_dw0(r1, mkite(mkexpr(nequal), mkexpr(old_mem), mkexpr(op1)));
florian6820ba52012-07-26 02:01:50 +000010452 yield_if(mkexpr(nequal));
sewardj2019a972011-03-07 16:04:07 +000010453
10454 return "csg";
10455}
10456
florian448cbba2012-06-06 02:26:01 +000010457/* Implementation for 32-bit compare-double-and-swap */
10458static void
10459s390_irgen_cdas_32(UChar r1, UChar r3, IRTemp op2addr)
10460{
10461 IRCAS *cas;
10462 IRTemp op1_high = newTemp(Ity_I32);
10463 IRTemp op1_low = newTemp(Ity_I32);
10464 IRTemp old_mem_high = newTemp(Ity_I32);
10465 IRTemp old_mem_low = newTemp(Ity_I32);
10466 IRTemp op3_high = newTemp(Ity_I32);
10467 IRTemp op3_low = newTemp(Ity_I32);
10468 IRTemp result = newTemp(Ity_I32);
10469 IRTemp nequal = newTemp(Ity_I1);
10470
10471 assign(op1_high, get_gpr_w1(r1));
10472 assign(op1_low, get_gpr_w1(r1+1));
10473 assign(op3_high, get_gpr_w1(r3));
10474 assign(op3_low, get_gpr_w1(r3+1));
10475
10476 /* The first and second operands are compared. If they are equal,
10477 the third operand is stored at the second-operand location. */
10478 cas = mkIRCAS(old_mem_high, old_mem_low,
10479 Iend_BE, mkexpr(op2addr),
10480 mkexpr(op1_high), mkexpr(op1_low), /* expected value */
10481 mkexpr(op3_high), mkexpr(op3_low) /* new value */);
10482 stmt(IRStmt_CAS(cas));
10483
10484 /* Set CC. Operands compared equal -> 0, else 1. */
10485 assign(result, unop(Iop_1Uto32,
10486 binop(Iop_CmpNE32,
10487 binop(Iop_Or32,
10488 binop(Iop_Xor32, mkexpr(op1_high), mkexpr(old_mem_high)),
10489 binop(Iop_Xor32, mkexpr(op1_low), mkexpr(old_mem_low))),
10490 mkU32(0))));
10491
10492 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
10493
10494 /* If operands were equal (cc == 0) just store the old value op1 in r1.
10495 Otherwise, store the old_value from memory in r1 and yield. */
10496 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
10497 put_gpr_w1(r1, mkite(mkexpr(nequal), mkexpr(old_mem_high), mkexpr(op1_high)));
10498 put_gpr_w1(r1+1, mkite(mkexpr(nequal), mkexpr(old_mem_low), mkexpr(op1_low)));
florian6820ba52012-07-26 02:01:50 +000010499 yield_if(mkexpr(nequal));
florian448cbba2012-06-06 02:26:01 +000010500}
10501
florian55085f82012-11-21 00:36:55 +000010502static const HChar *
florian448cbba2012-06-06 02:26:01 +000010503s390_irgen_CDS(UChar r1, UChar r3, IRTemp op2addr)
10504{
10505 s390_irgen_cdas_32(r1, r3, op2addr);
10506
10507 return "cds";
10508}
10509
florian55085f82012-11-21 00:36:55 +000010510static const HChar *
florian448cbba2012-06-06 02:26:01 +000010511s390_irgen_CDSY(UChar r1, UChar r3, IRTemp op2addr)
10512{
10513 s390_irgen_cdas_32(r1, r3, op2addr);
10514
10515 return "cdsy";
10516}
10517
florian55085f82012-11-21 00:36:55 +000010518static const HChar *
florian448cbba2012-06-06 02:26:01 +000010519s390_irgen_CDSG(UChar r1, UChar r3, IRTemp op2addr)
10520{
10521 IRCAS *cas;
10522 IRTemp op1_high = newTemp(Ity_I64);
10523 IRTemp op1_low = newTemp(Ity_I64);
10524 IRTemp old_mem_high = newTemp(Ity_I64);
10525 IRTemp old_mem_low = newTemp(Ity_I64);
10526 IRTemp op3_high = newTemp(Ity_I64);
10527 IRTemp op3_low = newTemp(Ity_I64);
10528 IRTemp result = newTemp(Ity_I64);
10529 IRTemp nequal = newTemp(Ity_I1);
10530
10531 assign(op1_high, get_gpr_dw0(r1));
10532 assign(op1_low, get_gpr_dw0(r1+1));
10533 assign(op3_high, get_gpr_dw0(r3));
10534 assign(op3_low, get_gpr_dw0(r3+1));
10535
10536 /* The first and second operands are compared. If they are equal,
10537 the third operand is stored at the second-operand location. */
10538 cas = mkIRCAS(old_mem_high, old_mem_low,
10539 Iend_BE, mkexpr(op2addr),
10540 mkexpr(op1_high), mkexpr(op1_low), /* expected value */
10541 mkexpr(op3_high), mkexpr(op3_low) /* new value */);
10542 stmt(IRStmt_CAS(cas));
10543
10544 /* Set CC. Operands compared equal -> 0, else 1. */
10545 assign(result, unop(Iop_1Uto64,
10546 binop(Iop_CmpNE64,
10547 binop(Iop_Or64,
10548 binop(Iop_Xor64, mkexpr(op1_high), mkexpr(old_mem_high)),
10549 binop(Iop_Xor64, mkexpr(op1_low), mkexpr(old_mem_low))),
10550 mkU64(0))));
10551
10552 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
10553
10554 /* If operands were equal (cc == 0) just store the old value op1 in r1.
10555 Otherwise, store the old_value from memory in r1 and yield. */
10556 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
10557 put_gpr_dw0(r1, mkite(mkexpr(nequal), mkexpr(old_mem_high), mkexpr(op1_high)));
10558 put_gpr_dw0(r1+1, mkite(mkexpr(nequal), mkexpr(old_mem_low), mkexpr(op1_low)));
florian6820ba52012-07-26 02:01:50 +000010559 yield_if(mkexpr(nequal));
10560
florian448cbba2012-06-06 02:26:01 +000010561 return "cdsg";
10562}
10563
sewardj2019a972011-03-07 16:04:07 +000010564
10565/* Binary floating point */
10566
florian55085f82012-11-21 00:36:55 +000010567static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010568s390_irgen_AXBR(UChar r1, UChar r2)
10569{
10570 IRTemp op1 = newTemp(Ity_F128);
10571 IRTemp op2 = newTemp(Ity_F128);
10572 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000010573 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000010574
10575 assign(op1, get_fpr_pair(r1));
10576 assign(op2, get_fpr_pair(r2));
floriandb4fcaa2012-09-05 19:54:08 +000010577 assign(result, triop(Iop_AddF128, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +000010578 mkexpr(op2)));
10579 put_fpr_pair(r1, mkexpr(result));
10580
10581 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
10582
10583 return "axbr";
10584}
10585
10586/* The result of a Iop_CmdFxx operation is a condition code. It is
10587 encoded using the values defined in type IRCmpFxxResult.
10588 Before we can store the condition code into the guest state (or do
10589 anything else with it for that matter) we need to convert it to
10590 the encoding that s390 uses. This is what this function does.
10591
10592 s390 VEX b6 b2 b0 cc.1 cc.0
10593 0 0x40 EQ 1 0 0 0 0
10594 1 0x01 LT 0 0 1 0 1
10595 2 0x00 GT 0 0 0 1 0
10596 3 0x45 Unordered 1 1 1 1 1
10597
10598 The following bits from the VEX encoding are interesting:
10599 b0, b2, b6 with b0 being the LSB. We observe:
10600
10601 cc.0 = b0;
10602 cc.1 = b2 | (~b0 & ~b6)
10603
10604 with cc being the s390 condition code.
10605*/
10606static IRExpr *
10607convert_vex_fpcc_to_s390(IRTemp vex_cc)
10608{
10609 IRTemp cc0 = newTemp(Ity_I32);
10610 IRTemp cc1 = newTemp(Ity_I32);
10611 IRTemp b0 = newTemp(Ity_I32);
10612 IRTemp b2 = newTemp(Ity_I32);
10613 IRTemp b6 = newTemp(Ity_I32);
10614
10615 assign(b0, binop(Iop_And32, mkexpr(vex_cc), mkU32(1)));
10616 assign(b2, binop(Iop_And32, binop(Iop_Shr32, mkexpr(vex_cc), mkU8(2)),
10617 mkU32(1)));
10618 assign(b6, binop(Iop_And32, binop(Iop_Shr32, mkexpr(vex_cc), mkU8(6)),
10619 mkU32(1)));
10620
10621 assign(cc0, mkexpr(b0));
10622 assign(cc1, binop(Iop_Or32, mkexpr(b2),
10623 binop(Iop_And32,
10624 binop(Iop_Sub32, mkU32(1), mkexpr(b0)), /* ~b0 */
10625 binop(Iop_Sub32, mkU32(1), mkexpr(b6)) /* ~b6 */
10626 )));
10627
10628 return binop(Iop_Or32, mkexpr(cc0), binop(Iop_Shl32, mkexpr(cc1), mkU8(1)));
10629}
10630
florian55085f82012-11-21 00:36:55 +000010631static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010632s390_irgen_CEBR(UChar r1, UChar r2)
10633{
10634 IRTemp op1 = newTemp(Ity_F32);
10635 IRTemp op2 = newTemp(Ity_F32);
10636 IRTemp cc_vex = newTemp(Ity_I32);
10637 IRTemp cc_s390 = newTemp(Ity_I32);
10638
10639 assign(op1, get_fpr_w0(r1));
10640 assign(op2, get_fpr_w0(r2));
10641 assign(cc_vex, binop(Iop_CmpF32, mkexpr(op1), mkexpr(op2)));
10642
10643 assign(cc_s390, convert_vex_fpcc_to_s390(cc_vex));
10644 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
10645
10646 return "cebr";
10647}
10648
florian55085f82012-11-21 00:36:55 +000010649static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010650s390_irgen_CDBR(UChar r1, UChar r2)
10651{
10652 IRTemp op1 = newTemp(Ity_F64);
10653 IRTemp op2 = newTemp(Ity_F64);
10654 IRTemp cc_vex = newTemp(Ity_I32);
10655 IRTemp cc_s390 = newTemp(Ity_I32);
10656
10657 assign(op1, get_fpr_dw0(r1));
10658 assign(op2, get_fpr_dw0(r2));
10659 assign(cc_vex, binop(Iop_CmpF64, mkexpr(op1), mkexpr(op2)));
10660
10661 assign(cc_s390, convert_vex_fpcc_to_s390(cc_vex));
10662 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
10663
10664 return "cdbr";
10665}
10666
florian55085f82012-11-21 00:36:55 +000010667static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010668s390_irgen_CXBR(UChar r1, UChar r2)
10669{
10670 IRTemp op1 = newTemp(Ity_F128);
10671 IRTemp op2 = newTemp(Ity_F128);
10672 IRTemp cc_vex = newTemp(Ity_I32);
10673 IRTemp cc_s390 = newTemp(Ity_I32);
10674
10675 assign(op1, get_fpr_pair(r1));
10676 assign(op2, get_fpr_pair(r2));
10677 assign(cc_vex, binop(Iop_CmpF128, mkexpr(op1), mkexpr(op2)));
10678
10679 assign(cc_s390, convert_vex_fpcc_to_s390(cc_vex));
10680 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
10681
10682 return "cxbr";
10683}
10684
florian55085f82012-11-21 00:36:55 +000010685static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010686s390_irgen_CEB(UChar r1, IRTemp op2addr)
10687{
10688 IRTemp op1 = newTemp(Ity_F32);
10689 IRTemp op2 = newTemp(Ity_F32);
10690 IRTemp cc_vex = newTemp(Ity_I32);
10691 IRTemp cc_s390 = newTemp(Ity_I32);
10692
10693 assign(op1, get_fpr_w0(r1));
10694 assign(op2, load(Ity_F32, mkexpr(op2addr)));
10695 assign(cc_vex, binop(Iop_CmpF32, mkexpr(op1), mkexpr(op2)));
10696
10697 assign(cc_s390, convert_vex_fpcc_to_s390(cc_vex));
10698 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
10699
10700 return "ceb";
10701}
10702
florian55085f82012-11-21 00:36:55 +000010703static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010704s390_irgen_CDB(UChar r1, IRTemp op2addr)
10705{
10706 IRTemp op1 = newTemp(Ity_F64);
10707 IRTemp op2 = newTemp(Ity_F64);
10708 IRTemp cc_vex = newTemp(Ity_I32);
10709 IRTemp cc_s390 = newTemp(Ity_I32);
10710
10711 assign(op1, get_fpr_dw0(r1));
10712 assign(op2, load(Ity_F64, mkexpr(op2addr)));
10713 assign(cc_vex, binop(Iop_CmpF64, mkexpr(op1), mkexpr(op2)));
10714
10715 assign(cc_s390, convert_vex_fpcc_to_s390(cc_vex));
10716 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
10717
10718 return "cdb";
10719}
10720
florian55085f82012-11-21 00:36:55 +000010721static const HChar *
florian4b8efad2012-09-02 18:07:08 +000010722s390_irgen_CXFBR(UChar m3 __attribute__((unused)),
10723 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000010724{
10725 IRTemp op2 = newTemp(Ity_I32);
10726
10727 assign(op2, get_gpr_w1(r2));
10728 put_fpr_pair(r1, unop(Iop_I32StoF128, mkexpr(op2)));
10729
10730 return "cxfbr";
10731}
10732
florian55085f82012-11-21 00:36:55 +000010733static const HChar *
floriand2129202012-09-01 20:01:39 +000010734s390_irgen_CXLFBR(UChar m3 __attribute__((unused)),
10735 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
florian1c8f7ff2012-09-01 00:12:11 +000010736{
floriane75dafa2012-09-01 17:54:09 +000010737 if (! s390_host_has_fpext) {
10738 emulation_failure(EmFail_S390X_fpext);
10739 } else {
10740 IRTemp op2 = newTemp(Ity_I32);
florian1c8f7ff2012-09-01 00:12:11 +000010741
floriane75dafa2012-09-01 17:54:09 +000010742 assign(op2, get_gpr_w1(r2));
10743 put_fpr_pair(r1, unop(Iop_I32UtoF128, mkexpr(op2)));
10744 }
florian1c8f7ff2012-09-01 00:12:11 +000010745 return "cxlfbr";
10746}
10747
10748
florian55085f82012-11-21 00:36:55 +000010749static const HChar *
florian4b8efad2012-09-02 18:07:08 +000010750s390_irgen_CXGBR(UChar m3 __attribute__((unused)),
10751 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000010752{
10753 IRTemp op2 = newTemp(Ity_I64);
10754
10755 assign(op2, get_gpr_dw0(r2));
10756 put_fpr_pair(r1, unop(Iop_I64StoF128, mkexpr(op2)));
10757
10758 return "cxgbr";
10759}
10760
florian55085f82012-11-21 00:36:55 +000010761static const HChar *
floriand2129202012-09-01 20:01:39 +000010762s390_irgen_CXLGBR(UChar m3 __attribute__((unused)),
10763 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
florian1c8f7ff2012-09-01 00:12:11 +000010764{
floriane75dafa2012-09-01 17:54:09 +000010765 if (! s390_host_has_fpext) {
10766 emulation_failure(EmFail_S390X_fpext);
10767 } else {
10768 IRTemp op2 = newTemp(Ity_I64);
florian1c8f7ff2012-09-01 00:12:11 +000010769
floriane75dafa2012-09-01 17:54:09 +000010770 assign(op2, get_gpr_dw0(r2));
10771 put_fpr_pair(r1, unop(Iop_I64UtoF128, mkexpr(op2)));
10772 }
florian1c8f7ff2012-09-01 00:12:11 +000010773 return "cxlgbr";
10774}
10775
florian55085f82012-11-21 00:36:55 +000010776static const HChar *
florian4b8efad2012-09-02 18:07:08 +000010777s390_irgen_CFXBR(UChar m3, UChar m4 __attribute__((unused)),
10778 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000010779{
10780 IRTemp op = newTemp(Ity_F128);
10781 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +000010782 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +000010783
10784 assign(op, get_fpr_pair(r2));
florian19e00772012-09-06 03:13:22 +000010785 assign(result, binop(Iop_F128toI32S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +000010786 mkexpr(op)));
10787 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +000010788 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_INT_32, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +000010789
10790 return "cfxbr";
10791}
10792
florian55085f82012-11-21 00:36:55 +000010793static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +000010794s390_irgen_CLFXBR(UChar m3, UChar m4 __attribute__((unused)),
10795 UChar r1, UChar r2)
10796{
floriane75dafa2012-09-01 17:54:09 +000010797 if (! s390_host_has_fpext) {
10798 emulation_failure(EmFail_S390X_fpext);
10799 } else {
10800 IRTemp op = newTemp(Ity_F128);
10801 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +000010802 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +000010803
floriane75dafa2012-09-01 17:54:09 +000010804 assign(op, get_fpr_pair(r2));
florian19e00772012-09-06 03:13:22 +000010805 assign(result, binop(Iop_F128toI32U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +000010806 mkexpr(op)));
10807 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +000010808 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_UINT_32, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +000010809 }
florian1c8f7ff2012-09-01 00:12:11 +000010810 return "clfxbr";
10811}
10812
10813
florian55085f82012-11-21 00:36:55 +000010814static const HChar *
florian4b8efad2012-09-02 18:07:08 +000010815s390_irgen_CGXBR(UChar m3, UChar m4 __attribute__((unused)),
10816 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000010817{
10818 IRTemp op = newTemp(Ity_F128);
10819 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +000010820 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +000010821
10822 assign(op, get_fpr_pair(r2));
florian19e00772012-09-06 03:13:22 +000010823 assign(result, binop(Iop_F128toI64S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +000010824 mkexpr(op)));
10825 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +000010826 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_INT_64, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +000010827
10828 return "cgxbr";
10829}
10830
florian55085f82012-11-21 00:36:55 +000010831static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +000010832s390_irgen_CLGXBR(UChar m3, UChar m4 __attribute__((unused)),
10833 UChar r1, UChar r2)
10834{
floriane75dafa2012-09-01 17:54:09 +000010835 if (! s390_host_has_fpext) {
10836 emulation_failure(EmFail_S390X_fpext);
10837 } else {
10838 IRTemp op = newTemp(Ity_F128);
10839 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +000010840 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +000010841
floriane75dafa2012-09-01 17:54:09 +000010842 assign(op, get_fpr_pair(r2));
florian19e00772012-09-06 03:13:22 +000010843 assign(result, binop(Iop_F128toI64U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +000010844 mkexpr(op)));
10845 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +000010846 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_UINT_64, op,
10847 rounding_mode);
floriane75dafa2012-09-01 17:54:09 +000010848 }
florian1c8f7ff2012-09-01 00:12:11 +000010849 return "clgxbr";
10850}
10851
florian55085f82012-11-21 00:36:55 +000010852static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010853s390_irgen_DXBR(UChar r1, UChar r2)
10854{
10855 IRTemp op1 = newTemp(Ity_F128);
10856 IRTemp op2 = newTemp(Ity_F128);
10857 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000010858 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000010859
10860 assign(op1, get_fpr_pair(r1));
10861 assign(op2, get_fpr_pair(r2));
floriandb4fcaa2012-09-05 19:54:08 +000010862 assign(result, triop(Iop_DivF128, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +000010863 mkexpr(op2)));
10864 put_fpr_pair(r1, mkexpr(result));
10865
10866 return "dxbr";
10867}
10868
florian55085f82012-11-21 00:36:55 +000010869static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010870s390_irgen_LTXBR(UChar r1, UChar r2)
10871{
10872 IRTemp result = newTemp(Ity_F128);
10873
10874 assign(result, get_fpr_pair(r2));
10875 put_fpr_pair(r1, mkexpr(result));
10876 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
10877
10878 return "ltxbr";
10879}
10880
florian55085f82012-11-21 00:36:55 +000010881static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010882s390_irgen_LCXBR(UChar r1, UChar r2)
10883{
10884 IRTemp result = newTemp(Ity_F128);
10885
10886 assign(result, unop(Iop_NegF128, get_fpr_pair(r2)));
10887 put_fpr_pair(r1, mkexpr(result));
10888 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
10889
10890 return "lcxbr";
10891}
10892
florian55085f82012-11-21 00:36:55 +000010893static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010894s390_irgen_LXDBR(UChar r1, UChar r2)
10895{
10896 IRTemp op = newTemp(Ity_F64);
10897
10898 assign(op, get_fpr_dw0(r2));
10899 put_fpr_pair(r1, unop(Iop_F64toF128, mkexpr(op)));
10900
10901 return "lxdbr";
10902}
10903
florian55085f82012-11-21 00:36:55 +000010904static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010905s390_irgen_LXEBR(UChar r1, UChar r2)
10906{
10907 IRTemp op = newTemp(Ity_F32);
10908
10909 assign(op, get_fpr_w0(r2));
10910 put_fpr_pair(r1, unop(Iop_F32toF128, mkexpr(op)));
10911
10912 return "lxebr";
10913}
10914
florian55085f82012-11-21 00:36:55 +000010915static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010916s390_irgen_LXDB(UChar r1, IRTemp op2addr)
10917{
10918 IRTemp op = newTemp(Ity_F64);
10919
10920 assign(op, load(Ity_F64, mkexpr(op2addr)));
10921 put_fpr_pair(r1, unop(Iop_F64toF128, mkexpr(op)));
10922
10923 return "lxdb";
10924}
10925
florian55085f82012-11-21 00:36:55 +000010926static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010927s390_irgen_LXEB(UChar r1, IRTemp op2addr)
10928{
10929 IRTemp op = newTemp(Ity_F32);
10930
10931 assign(op, load(Ity_F32, mkexpr(op2addr)));
10932 put_fpr_pair(r1, unop(Iop_F32toF128, mkexpr(op)));
10933
10934 return "lxeb";
10935}
10936
florian55085f82012-11-21 00:36:55 +000010937static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010938s390_irgen_LNEBR(UChar r1, UChar r2)
10939{
10940 IRTemp result = newTemp(Ity_F32);
10941
10942 assign(result, unop(Iop_NegF32, unop(Iop_AbsF32, get_fpr_w0(r2))));
10943 put_fpr_w0(r1, mkexpr(result));
10944 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_32, result);
10945
10946 return "lnebr";
10947}
10948
florian55085f82012-11-21 00:36:55 +000010949static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010950s390_irgen_LNDBR(UChar r1, UChar r2)
10951{
10952 IRTemp result = newTemp(Ity_F64);
10953
10954 assign(result, unop(Iop_NegF64, unop(Iop_AbsF64, get_fpr_dw0(r2))));
10955 put_fpr_dw0(r1, mkexpr(result));
10956 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_64, result);
10957
10958 return "lndbr";
10959}
10960
florian55085f82012-11-21 00:36:55 +000010961static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010962s390_irgen_LNXBR(UChar r1, UChar r2)
10963{
10964 IRTemp result = newTemp(Ity_F128);
10965
10966 assign(result, unop(Iop_NegF128, unop(Iop_AbsF128, get_fpr_pair(r2))));
10967 put_fpr_pair(r1, mkexpr(result));
10968 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
10969
10970 return "lnxbr";
10971}
10972
florian55085f82012-11-21 00:36:55 +000010973static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010974s390_irgen_LPEBR(UChar r1, UChar r2)
10975{
10976 IRTemp result = newTemp(Ity_F32);
10977
10978 assign(result, unop(Iop_AbsF32, get_fpr_w0(r2)));
10979 put_fpr_w0(r1, mkexpr(result));
10980 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_32, result);
10981
10982 return "lpebr";
10983}
10984
florian55085f82012-11-21 00:36:55 +000010985static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010986s390_irgen_LPDBR(UChar r1, UChar r2)
10987{
10988 IRTemp result = newTemp(Ity_F64);
10989
10990 assign(result, unop(Iop_AbsF64, get_fpr_dw0(r2)));
10991 put_fpr_dw0(r1, mkexpr(result));
10992 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_64, result);
10993
10994 return "lpdbr";
10995}
10996
florian55085f82012-11-21 00:36:55 +000010997static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010998s390_irgen_LPXBR(UChar r1, UChar r2)
10999{
11000 IRTemp result = newTemp(Ity_F128);
11001
11002 assign(result, unop(Iop_AbsF128, get_fpr_pair(r2)));
11003 put_fpr_pair(r1, mkexpr(result));
11004 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
11005
11006 return "lpxbr";
11007}
11008
florian55085f82012-11-21 00:36:55 +000011009static const HChar *
florian4b8efad2012-09-02 18:07:08 +000011010s390_irgen_LDXBR(UChar m3, UChar m4 __attribute__((unused)),
11011 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000011012{
florian125e20d2012-10-07 15:42:37 +000011013 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian12b0bca2012-09-05 20:05:20 +000011014 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +000011015 m3 = S390_BFP_ROUND_PER_FPC;
florian12b0bca2012-09-05 20:05:20 +000011016 }
sewardj2019a972011-03-07 16:04:07 +000011017 IRTemp result = newTemp(Ity_F64);
11018
floriandb4fcaa2012-09-05 19:54:08 +000011019 assign(result, binop(Iop_F128toF64, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +000011020 get_fpr_pair(r2)));
sewardj2019a972011-03-07 16:04:07 +000011021 put_fpr_dw0(r1, mkexpr(result));
11022
11023 return "ldxbr";
11024}
11025
florian55085f82012-11-21 00:36:55 +000011026static const HChar *
florian4b8efad2012-09-02 18:07:08 +000011027s390_irgen_LEXBR(UChar m3, UChar m4 __attribute__((unused)),
11028 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000011029{
florian125e20d2012-10-07 15:42:37 +000011030 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian12b0bca2012-09-05 20:05:20 +000011031 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +000011032 m3 = S390_BFP_ROUND_PER_FPC;
florian12b0bca2012-09-05 20:05:20 +000011033 }
sewardj2019a972011-03-07 16:04:07 +000011034 IRTemp result = newTemp(Ity_F32);
11035
floriandb4fcaa2012-09-05 19:54:08 +000011036 assign(result, binop(Iop_F128toF32, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +000011037 get_fpr_pair(r2)));
sewardj2019a972011-03-07 16:04:07 +000011038 put_fpr_w0(r1, mkexpr(result));
11039
11040 return "lexbr";
11041}
11042
florian55085f82012-11-21 00:36:55 +000011043static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011044s390_irgen_MXBR(UChar r1, UChar r2)
11045{
11046 IRTemp op1 = newTemp(Ity_F128);
11047 IRTemp op2 = newTemp(Ity_F128);
11048 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000011049 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011050
11051 assign(op1, get_fpr_pair(r1));
11052 assign(op2, get_fpr_pair(r2));
floriandb4fcaa2012-09-05 19:54:08 +000011053 assign(result, triop(Iop_MulF128, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +000011054 mkexpr(op2)));
11055 put_fpr_pair(r1, mkexpr(result));
11056
11057 return "mxbr";
11058}
11059
florian55085f82012-11-21 00:36:55 +000011060static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011061s390_irgen_MAEBR(UChar r1, UChar r3, UChar r2)
11062{
florian125e20d2012-10-07 15:42:37 +000011063 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
florian847684d2012-09-05 04:19:09 +000011064
floriandb4fcaa2012-09-05 19:54:08 +000011065 put_fpr_w0(r1, qop(Iop_MAddF32, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000011066 get_fpr_w0(r3), get_fpr_w0(r2), get_fpr_w0(r1)));
sewardj2019a972011-03-07 16:04:07 +000011067
11068 return "maebr";
11069}
11070
florian55085f82012-11-21 00:36:55 +000011071static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011072s390_irgen_MADBR(UChar r1, UChar r3, UChar r2)
11073{
florian125e20d2012-10-07 15:42:37 +000011074 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
florian847684d2012-09-05 04:19:09 +000011075
floriandb4fcaa2012-09-05 19:54:08 +000011076 put_fpr_dw0(r1, qop(Iop_MAddF64, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000011077 get_fpr_dw0(r3), get_fpr_dw0(r2), get_fpr_dw0(r1)));
sewardj2019a972011-03-07 16:04:07 +000011078
11079 return "madbr";
11080}
11081
florian55085f82012-11-21 00:36:55 +000011082static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011083s390_irgen_MAEB(UChar r3, IRTemp op2addr, UChar r1)
11084{
11085 IRExpr *op2 = load(Ity_F32, mkexpr(op2addr));
florian125e20d2012-10-07 15:42:37 +000011086 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011087
floriandb4fcaa2012-09-05 19:54:08 +000011088 put_fpr_w0(r1, qop(Iop_MAddF32, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000011089 get_fpr_w0(r3), op2, get_fpr_w0(r1)));
sewardj2019a972011-03-07 16:04:07 +000011090
11091 return "maeb";
11092}
11093
florian55085f82012-11-21 00:36:55 +000011094static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011095s390_irgen_MADB(UChar r3, IRTemp op2addr, UChar r1)
11096{
11097 IRExpr *op2 = load(Ity_F64, mkexpr(op2addr));
florian125e20d2012-10-07 15:42:37 +000011098 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011099
floriandb4fcaa2012-09-05 19:54:08 +000011100 put_fpr_dw0(r1, qop(Iop_MAddF64, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000011101 get_fpr_dw0(r3), op2, get_fpr_dw0(r1)));
sewardj2019a972011-03-07 16:04:07 +000011102
11103 return "madb";
11104}
11105
florian55085f82012-11-21 00:36:55 +000011106static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011107s390_irgen_MSEBR(UChar r1, UChar r3, UChar r2)
11108{
florian125e20d2012-10-07 15:42:37 +000011109 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
florian847684d2012-09-05 04:19:09 +000011110
floriandb4fcaa2012-09-05 19:54:08 +000011111 put_fpr_w0(r1, qop(Iop_MSubF32, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000011112 get_fpr_w0(r3), get_fpr_w0(r2), get_fpr_w0(r1)));
sewardj2019a972011-03-07 16:04:07 +000011113
11114 return "msebr";
11115}
11116
florian55085f82012-11-21 00:36:55 +000011117static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011118s390_irgen_MSDBR(UChar r1, UChar r3, UChar r2)
11119{
florian125e20d2012-10-07 15:42:37 +000011120 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
florian847684d2012-09-05 04:19:09 +000011121
floriandb4fcaa2012-09-05 19:54:08 +000011122 put_fpr_dw0(r1, qop(Iop_MSubF64, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000011123 get_fpr_dw0(r3), get_fpr_dw0(r2), get_fpr_dw0(r1)));
sewardj2019a972011-03-07 16:04:07 +000011124
11125 return "msdbr";
11126}
11127
florian55085f82012-11-21 00:36:55 +000011128static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011129s390_irgen_MSEB(UChar r3, IRTemp op2addr, UChar r1)
11130{
11131 IRExpr *op2 = load(Ity_F32, mkexpr(op2addr));
florian125e20d2012-10-07 15:42:37 +000011132 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011133
floriandb4fcaa2012-09-05 19:54:08 +000011134 put_fpr_w0(r1, qop(Iop_MSubF32, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000011135 get_fpr_w0(r3), op2, get_fpr_w0(r1)));
sewardj2019a972011-03-07 16:04:07 +000011136
11137 return "mseb";
11138}
11139
florian55085f82012-11-21 00:36:55 +000011140static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011141s390_irgen_MSDB(UChar r3, IRTemp op2addr, UChar r1)
11142{
11143 IRExpr *op2 = load(Ity_F64, mkexpr(op2addr));
florian125e20d2012-10-07 15:42:37 +000011144 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011145
floriandb4fcaa2012-09-05 19:54:08 +000011146 put_fpr_dw0(r1, qop(Iop_MSubF64, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000011147 get_fpr_dw0(r3), op2, get_fpr_dw0(r1)));
sewardj2019a972011-03-07 16:04:07 +000011148
11149 return "msdb";
11150}
11151
florian55085f82012-11-21 00:36:55 +000011152static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011153s390_irgen_SQEBR(UChar r1, UChar r2)
11154{
11155 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +000011156 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011157
floriandb4fcaa2012-09-05 19:54:08 +000011158 assign(result, binop(Iop_SqrtF32, mkexpr(rounding_mode), get_fpr_w0(r2)));
sewardj2019a972011-03-07 16:04:07 +000011159 put_fpr_w0(r1, mkexpr(result));
11160
11161 return "sqebr";
11162}
11163
florian55085f82012-11-21 00:36:55 +000011164static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011165s390_irgen_SQDBR(UChar r1, UChar r2)
11166{
11167 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +000011168 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011169
floriandb4fcaa2012-09-05 19:54:08 +000011170 assign(result, binop(Iop_SqrtF64, mkexpr(rounding_mode), get_fpr_dw0(r2)));
sewardj2019a972011-03-07 16:04:07 +000011171 put_fpr_dw0(r1, mkexpr(result));
11172
11173 return "sqdbr";
11174}
11175
florian55085f82012-11-21 00:36:55 +000011176static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011177s390_irgen_SQXBR(UChar r1, UChar r2)
11178{
11179 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000011180 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011181
floriandb4fcaa2012-09-05 19:54:08 +000011182 assign(result, binop(Iop_SqrtF128, mkexpr(rounding_mode),
11183 get_fpr_pair(r2)));
sewardj2019a972011-03-07 16:04:07 +000011184 put_fpr_pair(r1, mkexpr(result));
11185
11186 return "sqxbr";
11187}
11188
florian55085f82012-11-21 00:36:55 +000011189static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011190s390_irgen_SQEB(UChar r1, IRTemp op2addr)
11191{
11192 IRTemp op = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +000011193 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011194
11195 assign(op, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +000011196 put_fpr_w0(r1, binop(Iop_SqrtF32, mkexpr(rounding_mode), mkexpr(op)));
sewardj2019a972011-03-07 16:04:07 +000011197
11198 return "sqeb";
11199}
11200
florian55085f82012-11-21 00:36:55 +000011201static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011202s390_irgen_SQDB(UChar r1, IRTemp op2addr)
11203{
11204 IRTemp op = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +000011205 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011206
11207 assign(op, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +000011208 put_fpr_dw0(r1, binop(Iop_SqrtF64, mkexpr(rounding_mode), mkexpr(op)));
sewardj2019a972011-03-07 16:04:07 +000011209
11210 return "sqdb";
11211}
11212
florian55085f82012-11-21 00:36:55 +000011213static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011214s390_irgen_SXBR(UChar r1, UChar r2)
11215{
11216 IRTemp op1 = newTemp(Ity_F128);
11217 IRTemp op2 = newTemp(Ity_F128);
11218 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000011219 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011220
11221 assign(op1, get_fpr_pair(r1));
11222 assign(op2, get_fpr_pair(r2));
floriandb4fcaa2012-09-05 19:54:08 +000011223 assign(result, triop(Iop_SubF128, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +000011224 mkexpr(op2)));
11225 put_fpr_pair(r1, mkexpr(result));
11226 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
11227
11228 return "sxbr";
11229}
11230
florian55085f82012-11-21 00:36:55 +000011231static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011232s390_irgen_TCEB(UChar r1, IRTemp op2addr)
11233{
11234 IRTemp value = newTemp(Ity_F32);
11235
11236 assign(value, get_fpr_w0(r1));
11237
11238 s390_cc_thunk_putFZ(S390_CC_OP_BFP_TDC_32, value, op2addr);
11239
11240 return "tceb";
11241}
11242
florian55085f82012-11-21 00:36:55 +000011243static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011244s390_irgen_TCDB(UChar r1, IRTemp op2addr)
11245{
11246 IRTemp value = newTemp(Ity_F64);
11247
11248 assign(value, get_fpr_dw0(r1));
11249
11250 s390_cc_thunk_putFZ(S390_CC_OP_BFP_TDC_64, value, op2addr);
11251
11252 return "tcdb";
11253}
11254
florian55085f82012-11-21 00:36:55 +000011255static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011256s390_irgen_TCXB(UChar r1, IRTemp op2addr)
11257{
11258 IRTemp value = newTemp(Ity_F128);
11259
11260 assign(value, get_fpr_pair(r1));
11261
11262 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_TDC_128, value, op2addr);
11263
11264 return "tcxb";
11265}
11266
florian55085f82012-11-21 00:36:55 +000011267static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011268s390_irgen_LCDFR(UChar r1, UChar r2)
11269{
11270 IRTemp result = newTemp(Ity_F64);
11271
11272 assign(result, unop(Iop_NegF64, get_fpr_dw0(r2)));
11273 put_fpr_dw0(r1, mkexpr(result));
11274
11275 return "lcdfr";
11276}
11277
florian55085f82012-11-21 00:36:55 +000011278static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011279s390_irgen_LNDFR(UChar r1, UChar r2)
11280{
11281 IRTemp result = newTemp(Ity_F64);
11282
11283 assign(result, unop(Iop_NegF64, unop(Iop_AbsF64, get_fpr_dw0(r2))));
11284 put_fpr_dw0(r1, mkexpr(result));
11285
11286 return "lndfr";
11287}
11288
florian55085f82012-11-21 00:36:55 +000011289static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011290s390_irgen_LPDFR(UChar r1, UChar r2)
11291{
11292 IRTemp result = newTemp(Ity_F64);
11293
11294 assign(result, unop(Iop_AbsF64, get_fpr_dw0(r2)));
11295 put_fpr_dw0(r1, mkexpr(result));
11296
11297 return "lpdfr";
11298}
11299
florian55085f82012-11-21 00:36:55 +000011300static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011301s390_irgen_LDGR(UChar r1, UChar r2)
11302{
11303 put_fpr_dw0(r1, unop(Iop_ReinterpI64asF64, get_gpr_dw0(r2)));
11304
11305 return "ldgr";
11306}
11307
florian55085f82012-11-21 00:36:55 +000011308static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011309s390_irgen_LGDR(UChar r1, UChar r2)
11310{
11311 put_gpr_dw0(r1, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r2)));
11312
11313 return "lgdr";
11314}
11315
11316
florian55085f82012-11-21 00:36:55 +000011317static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011318s390_irgen_CPSDR(UChar r3, UChar r1, UChar r2)
11319{
11320 IRTemp sign = newTemp(Ity_I64);
11321 IRTemp value = newTemp(Ity_I64);
11322
11323 assign(sign, binop(Iop_And64, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r3)),
11324 mkU64(1ULL << 63)));
11325 assign(value, binop(Iop_And64, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r2)),
11326 mkU64((1ULL << 63) - 1)));
11327 put_fpr_dw0(r1, unop(Iop_ReinterpI64asF64, binop(Iop_Or64, mkexpr(value),
11328 mkexpr(sign))));
11329
11330 return "cpsdr";
11331}
11332
11333
sewardj2019a972011-03-07 16:04:07 +000011334static IRExpr *
11335s390_call_cvb(IRExpr *in)
11336{
11337 IRExpr **args, *call;
11338
11339 args = mkIRExprVec_1(in);
11340 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
11341 "s390_do_cvb", &s390_do_cvb, args);
11342
11343 /* Nothing is excluded from definedness checking. */
11344 call->Iex.CCall.cee->mcx_mask = 0;
11345
11346 return call;
11347}
11348
florian55085f82012-11-21 00:36:55 +000011349static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011350s390_irgen_CVB(UChar r1, IRTemp op2addr)
11351{
11352 put_gpr_w1(r1, s390_call_cvb(load(Ity_I64, mkexpr(op2addr))));
11353
11354 return "cvb";
11355}
11356
florian55085f82012-11-21 00:36:55 +000011357static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011358s390_irgen_CVBY(UChar r1, IRTemp op2addr)
11359{
11360 put_gpr_w1(r1, s390_call_cvb(load(Ity_I64, mkexpr(op2addr))));
11361
11362 return "cvby";
11363}
11364
11365
sewardj2019a972011-03-07 16:04:07 +000011366static IRExpr *
11367s390_call_cvd(IRExpr *in)
11368{
11369 IRExpr **args, *call;
11370
11371 args = mkIRExprVec_1(in);
11372 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
11373 "s390_do_cvd", &s390_do_cvd, args);
11374
11375 /* Nothing is excluded from definedness checking. */
11376 call->Iex.CCall.cee->mcx_mask = 0;
11377
11378 return call;
11379}
11380
florian55085f82012-11-21 00:36:55 +000011381static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011382s390_irgen_CVD(UChar r1, IRTemp op2addr)
11383{
florian11b8ee82012-08-06 13:35:33 +000011384 store(mkexpr(op2addr), s390_call_cvd(unop(Iop_32Uto64, get_gpr_w1(r1))));
sewardj2019a972011-03-07 16:04:07 +000011385
11386 return "cvd";
11387}
11388
florian55085f82012-11-21 00:36:55 +000011389static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011390s390_irgen_CVDY(UChar r1, IRTemp op2addr)
11391{
11392 store(mkexpr(op2addr), s390_call_cvd(get_gpr_w1(r1)));
11393
11394 return "cvdy";
11395}
11396
florian55085f82012-11-21 00:36:55 +000011397static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011398s390_irgen_FLOGR(UChar r1, UChar r2)
11399{
11400 IRTemp input = newTemp(Ity_I64);
11401 IRTemp not_zero = newTemp(Ity_I64);
11402 IRTemp tmpnum = newTemp(Ity_I64);
11403 IRTemp num = newTemp(Ity_I64);
11404 IRTemp shift_amount = newTemp(Ity_I8);
11405
11406 /* We use the "count leading zeroes" operator because the number of
11407 leading zeroes is identical with the bit position of the first '1' bit.
11408 However, that operator does not work when the input value is zero.
11409 Therefore, we set the LSB of the input value to 1 and use Clz64 on
11410 the modified value. If input == 0, then the result is 64. Otherwise,
11411 the result of Clz64 is what we want. */
11412
11413 assign(input, get_gpr_dw0(r2));
11414 assign(not_zero, binop(Iop_Or64, mkexpr(input), mkU64(1)));
11415 assign(tmpnum, unop(Iop_Clz64, mkexpr(not_zero)));
11416
11417 /* num = (input == 0) ? 64 : tmpnum */
11418 assign(num, mkite(binop(Iop_CmpEQ64, mkexpr(input), mkU64(0)),
11419 /* == 0 */ mkU64(64),
11420 /* != 0 */ mkexpr(tmpnum)));
11421
11422 put_gpr_dw0(r1, mkexpr(num));
11423
11424 /* Set the leftmost '1' bit of the input value to zero. The general scheme
11425 is to first shift the input value by NUM + 1 bits to the left which
11426 causes the leftmost '1' bit to disappear. Then we shift logically to
11427 the right by NUM + 1 bits. Because the semantics of Iop_Shl64 and
11428 Iop_Shr64 are undefined if the shift-amount is greater than or equal to
11429 the width of the value-to-be-shifted, we need to special case
11430 NUM + 1 >= 64. This is equivalent to INPUT != 0 && INPUT != 1.
11431 For both such INPUT values the result will be 0. */
11432
11433 assign(shift_amount, unop(Iop_64to8, binop(Iop_Add64, mkexpr(num),
11434 mkU64(1))));
11435
11436 put_gpr_dw0(r1 + 1,
florian6ad49522011-09-09 02:38:55 +000011437 mkite(binop(Iop_CmpLE64U, mkexpr(input), mkU64(1)),
11438 /* == 0 || == 1*/ mkU64(0),
11439 /* otherwise */
11440 binop(Iop_Shr64,
11441 binop(Iop_Shl64, mkexpr(input),
11442 mkexpr(shift_amount)),
11443 mkexpr(shift_amount))));
sewardj2019a972011-03-07 16:04:07 +000011444
11445 /* Compare the original value as an unsigned integer with 0. */
11446 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, input,
11447 mktemp(Ity_I64, mkU64(0)), False);
11448
11449 return "flogr";
11450}
11451
florian55085f82012-11-21 00:36:55 +000011452static const HChar *
sewardj1e5fea62011-05-17 16:18:36 +000011453s390_irgen_STCK(IRTemp op2addr)
11454{
11455 IRDirty *d;
11456 IRTemp cc = newTemp(Ity_I64);
11457
11458 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCK",
11459 &s390x_dirtyhelper_STCK,
11460 mkIRExprVec_1(mkexpr(op2addr)));
11461 d->mFx = Ifx_Write;
11462 d->mAddr = mkexpr(op2addr);
11463 d->mSize = 8;
11464 stmt(IRStmt_Dirty(d));
11465 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
11466 mkexpr(cc), mkU64(0), mkU64(0));
11467 return "stck";
11468}
11469
florian55085f82012-11-21 00:36:55 +000011470static const HChar *
sewardj1e5fea62011-05-17 16:18:36 +000011471s390_irgen_STCKF(IRTemp op2addr)
11472{
florianc5c669b2012-08-26 14:32:28 +000011473 if (! s390_host_has_stckf) {
floriane75dafa2012-09-01 17:54:09 +000011474 emulation_failure(EmFail_S390X_stckf);
florianc5c669b2012-08-26 14:32:28 +000011475 } else {
11476 IRTemp cc = newTemp(Ity_I64);
sewardj1e5fea62011-05-17 16:18:36 +000011477
florianc5c669b2012-08-26 14:32:28 +000011478 IRDirty *d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCKF",
11479 &s390x_dirtyhelper_STCKF,
11480 mkIRExprVec_1(mkexpr(op2addr)));
11481 d->mFx = Ifx_Write;
11482 d->mAddr = mkexpr(op2addr);
11483 d->mSize = 8;
11484 stmt(IRStmt_Dirty(d));
11485 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
11486 mkexpr(cc), mkU64(0), mkU64(0));
11487 }
sewardj1e5fea62011-05-17 16:18:36 +000011488 return "stckf";
11489}
11490
florian55085f82012-11-21 00:36:55 +000011491static const HChar *
sewardj1e5fea62011-05-17 16:18:36 +000011492s390_irgen_STCKE(IRTemp op2addr)
11493{
11494 IRDirty *d;
11495 IRTemp cc = newTemp(Ity_I64);
11496
11497 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCKE",
11498 &s390x_dirtyhelper_STCKE,
11499 mkIRExprVec_1(mkexpr(op2addr)));
11500 d->mFx = Ifx_Write;
11501 d->mAddr = mkexpr(op2addr);
11502 d->mSize = 16;
11503 stmt(IRStmt_Dirty(d));
11504 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
11505 mkexpr(cc), mkU64(0), mkU64(0));
11506 return "stcke";
11507}
11508
florian55085f82012-11-21 00:36:55 +000011509static const HChar *
florian933065d2011-07-11 01:48:02 +000011510s390_irgen_STFLE(IRTemp op2addr)
11511{
florian4e0083e2012-08-26 03:41:56 +000011512 if (! s390_host_has_stfle) {
floriane75dafa2012-09-01 17:54:09 +000011513 emulation_failure(EmFail_S390X_stfle);
florian4e0083e2012-08-26 03:41:56 +000011514 return "stfle";
11515 }
11516
florian933065d2011-07-11 01:48:02 +000011517 IRDirty *d;
11518 IRTemp cc = newTemp(Ity_I64);
11519
11520 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STFLE",
11521 &s390x_dirtyhelper_STFLE,
11522 mkIRExprVec_1(mkexpr(op2addr)));
11523
11524 d->needsBBP = 1; /* Need to pass pointer to guest state to helper */
11525
sewardjc9069f22012-06-01 16:09:50 +000011526 d->nFxState = 1;
11527 vex_bzero(&d->fxState, sizeof(d->fxState));
11528
florian933065d2011-07-11 01:48:02 +000011529 d->fxState[0].fx = Ifx_Modify; /* read then write */
11530 d->fxState[0].offset = S390X_GUEST_OFFSET(guest_r0);
11531 d->fxState[0].size = sizeof(ULong);
florian933065d2011-07-11 01:48:02 +000011532
11533 d->mAddr = mkexpr(op2addr);
11534 /* Pretend all double words are written */
11535 d->mSize = S390_NUM_FACILITY_DW * sizeof(ULong);
11536 d->mFx = Ifx_Write;
11537
11538 stmt(IRStmt_Dirty(d));
11539
11540 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET), mkexpr(cc), mkU64(0), mkU64(0));
11541
11542 return "stfle";
11543}
11544
florian55085f82012-11-21 00:36:55 +000011545static const HChar *
floriana4384a32011-08-11 16:58:45 +000011546s390_irgen_CKSM(UChar r1,UChar r2)
11547{
11548 IRTemp addr = newTemp(Ity_I64);
11549 IRTemp op = newTemp(Ity_I32);
11550 IRTemp len = newTemp(Ity_I64);
11551 IRTemp oldval = newTemp(Ity_I32);
11552 IRTemp mask = newTemp(Ity_I32);
11553 IRTemp newop = newTemp(Ity_I32);
11554 IRTemp result = newTemp(Ity_I32);
11555 IRTemp result1 = newTemp(Ity_I32);
11556 IRTemp inc = newTemp(Ity_I64);
11557
11558 assign(oldval, get_gpr_w1(r1));
11559 assign(addr, get_gpr_dw0(r2));
11560 assign(len, get_gpr_dw0(r2+1));
11561
11562 /* Condition code is always zero. */
11563 s390_cc_set(0);
11564
11565 /* If length is zero, there is no need to calculate the checksum */
florian6820ba52012-07-26 02:01:50 +000011566 next_insn_if(binop(Iop_CmpEQ64, mkexpr(len), mkU64(0)));
floriana4384a32011-08-11 16:58:45 +000011567
11568 /* Assiging the increment variable to adjust address and length
11569 later on. */
11570 assign(inc, mkite(binop(Iop_CmpLT64U, mkexpr(len), mkU64(4)),
11571 mkexpr(len), mkU64(4)));
11572
11573 /* If length < 4 the final 4-byte 2nd operand value is computed by
11574 appending the remaining bytes to the right with 0. This is done
11575 by AND'ing the 4 bytes loaded from memory with an appropriate
11576 mask. If length >= 4, that mask is simply 0xffffffff. */
11577
11578 assign(mask, mkite(binop(Iop_CmpLT64U, mkexpr(len), mkU64(4)),
11579 /* Mask computation when len < 4:
11580 0xffffffff << (32 - (len % 4)*8) */
11581 binop(Iop_Shl32, mkU32(0xffffffff),
11582 unop(Iop_32to8,
11583 binop(Iop_Sub32, mkU32(32),
11584 binop(Iop_Shl32,
11585 unop(Iop_64to32,
11586 binop(Iop_And64,
11587 mkexpr(len), mkU64(3))),
11588 mkU8(3))))),
11589 mkU32(0xffffffff)));
11590
11591 assign(op, load(Ity_I32, mkexpr(addr)));
11592 assign(newop, binop(Iop_And32, mkexpr(op), mkexpr(mask)));
11593 assign(result, binop(Iop_Add32, mkexpr(newop), mkexpr(oldval)));
11594
11595 /* Checking for carry */
11596 assign(result1, mkite(binop(Iop_CmpLT32U, mkexpr(result), mkexpr(newop)),
11597 binop(Iop_Add32, mkexpr(result), mkU32(1)),
11598 mkexpr(result)));
11599
11600 put_gpr_w1(r1, mkexpr(result1));
11601 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr), mkexpr(inc)));
11602 put_gpr_dw0(r2+1, binop(Iop_Sub64, mkexpr(len), mkexpr(inc)));
11603
florian6820ba52012-07-26 02:01:50 +000011604 iterate_if(binop(Iop_CmpNE64, mkexpr(len), mkU64(0)));
floriana4384a32011-08-11 16:58:45 +000011605
11606 return "cksm";
11607}
11608
florian55085f82012-11-21 00:36:55 +000011609static const HChar *
florian9af37692012-01-15 21:01:16 +000011610s390_irgen_TROO(UChar m3, UChar r1, UChar r2)
11611{
11612 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
11613 src_addr = newTemp(Ity_I64);
11614 des_addr = newTemp(Ity_I64);
11615 tab_addr = newTemp(Ity_I64);
11616 test_byte = newTemp(Ity_I8);
11617 src_len = newTemp(Ity_I64);
11618
11619 assign(src_addr, get_gpr_dw0(r2));
11620 assign(des_addr, get_gpr_dw0(r1));
11621 assign(tab_addr, get_gpr_dw0(1));
florian53518532012-01-18 14:00:31 +000011622 assign(src_len, get_gpr_dw0(r1+1));
florian9af37692012-01-15 21:01:16 +000011623 assign(test_byte, get_gpr_b7(0));
11624
11625 IRTemp op = newTemp(Ity_I8);
11626 IRTemp op1 = newTemp(Ity_I8);
11627 IRTemp result = newTemp(Ity_I64);
11628
11629 /* End of source string? We're done; proceed to next insn */
11630 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000011631 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian9af37692012-01-15 21:01:16 +000011632
11633 /* Load character from source string, index translation table and
11634 store translated character in op1. */
11635 assign(op, load(Ity_I8, mkexpr(src_addr)));
11636
11637 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
11638 mkexpr(tab_addr)));
11639 assign(op1, load(Ity_I8, mkexpr(result)));
11640
11641 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
11642 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011643 next_insn_if(binop(Iop_CmpEQ8, mkexpr(op1), mkexpr(test_byte)));
florian9af37692012-01-15 21:01:16 +000011644 }
11645 store(get_gpr_dw0(r1), mkexpr(op1));
11646
11647 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(1)));
11648 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
11649 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
11650
florian6820ba52012-07-26 02:01:50 +000011651 iterate();
florian9af37692012-01-15 21:01:16 +000011652
11653 return "troo";
11654}
11655
florian55085f82012-11-21 00:36:55 +000011656static const HChar *
florian730448f2012-02-04 17:07:07 +000011657s390_irgen_TRTO(UChar m3, UChar r1, UChar r2)
11658{
11659 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
11660 src_addr = newTemp(Ity_I64);
11661 des_addr = newTemp(Ity_I64);
11662 tab_addr = newTemp(Ity_I64);
11663 test_byte = newTemp(Ity_I8);
11664 src_len = newTemp(Ity_I64);
11665
11666 assign(src_addr, get_gpr_dw0(r2));
11667 assign(des_addr, get_gpr_dw0(r1));
11668 assign(tab_addr, get_gpr_dw0(1));
11669 assign(src_len, get_gpr_dw0(r1+1));
11670 assign(test_byte, get_gpr_b7(0));
11671
11672 IRTemp op = newTemp(Ity_I16);
11673 IRTemp op1 = newTemp(Ity_I8);
11674 IRTemp result = newTemp(Ity_I64);
11675
11676 /* End of source string? We're done; proceed to next insn */
11677 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000011678 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000011679
11680 /* Load character from source string, index translation table and
11681 store translated character in op1. */
11682 assign(op, load(Ity_I16, mkexpr(src_addr)));
11683
11684 assign(result, binop(Iop_Add64, unop(Iop_16Uto64, mkexpr(op)),
11685 mkexpr(tab_addr)));
11686
11687 assign(op1, load(Ity_I8, mkexpr(result)));
11688
11689 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
11690 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011691 next_insn_if(binop(Iop_CmpEQ8, mkexpr(op1), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000011692 }
11693 store(get_gpr_dw0(r1), mkexpr(op1));
11694
11695 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(2)));
11696 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(1)));
11697 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(2)));
11698
florian6820ba52012-07-26 02:01:50 +000011699 iterate();
florian730448f2012-02-04 17:07:07 +000011700
11701 return "trto";
11702}
11703
florian55085f82012-11-21 00:36:55 +000011704static const HChar *
florian730448f2012-02-04 17:07:07 +000011705s390_irgen_TROT(UChar m3, UChar r1, UChar r2)
11706{
11707 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
11708 src_addr = newTemp(Ity_I64);
11709 des_addr = newTemp(Ity_I64);
11710 tab_addr = newTemp(Ity_I64);
11711 test_byte = newTemp(Ity_I16);
11712 src_len = newTemp(Ity_I64);
11713
11714 assign(src_addr, get_gpr_dw0(r2));
11715 assign(des_addr, get_gpr_dw0(r1));
11716 assign(tab_addr, get_gpr_dw0(1));
11717 assign(src_len, get_gpr_dw0(r1+1));
11718 assign(test_byte, get_gpr_hw3(0));
11719
11720 IRTemp op = newTemp(Ity_I8);
11721 IRTemp op1 = newTemp(Ity_I16);
11722 IRTemp result = newTemp(Ity_I64);
11723
11724 /* End of source string? We're done; proceed to next insn */
11725 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000011726 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000011727
11728 /* Load character from source string, index translation table and
11729 store translated character in op1. */
11730 assign(op, binop(Iop_Shl8, load(Ity_I8, mkexpr(src_addr)), mkU8(1)));
11731
11732 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
11733 mkexpr(tab_addr)));
11734 assign(op1, load(Ity_I16, mkexpr(result)));
11735
11736 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
11737 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011738 next_insn_if(binop(Iop_CmpEQ16, mkexpr(op1), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000011739 }
11740 store(get_gpr_dw0(r1), mkexpr(op1));
11741
11742 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
11743 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(2)));
11744 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
11745
florian6820ba52012-07-26 02:01:50 +000011746 iterate();
florian730448f2012-02-04 17:07:07 +000011747
11748 return "trot";
11749}
11750
florian55085f82012-11-21 00:36:55 +000011751static const HChar *
florian730448f2012-02-04 17:07:07 +000011752s390_irgen_TRTT(UChar m3, UChar r1, UChar r2)
11753{
11754 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
11755 src_addr = newTemp(Ity_I64);
11756 des_addr = newTemp(Ity_I64);
11757 tab_addr = newTemp(Ity_I64);
11758 test_byte = newTemp(Ity_I16);
11759 src_len = newTemp(Ity_I64);
11760
11761 assign(src_addr, get_gpr_dw0(r2));
11762 assign(des_addr, get_gpr_dw0(r1));
11763 assign(tab_addr, get_gpr_dw0(1));
11764 assign(src_len, get_gpr_dw0(r1+1));
11765 assign(test_byte, get_gpr_hw3(0));
11766
11767 IRTemp op = newTemp(Ity_I16);
11768 IRTemp op1 = newTemp(Ity_I16);
11769 IRTemp result = newTemp(Ity_I64);
11770
11771 /* End of source string? We're done; proceed to next insn */
11772 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000011773 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000011774
11775 /* Load character from source string, index translation table and
11776 store translated character in op1. */
11777 assign(op, binop(Iop_Shl16, load(Ity_I16, mkexpr(src_addr)), mkU8(1)));
11778
11779 assign(result, binop(Iop_Add64, unop(Iop_16Uto64, mkexpr(op)),
11780 mkexpr(tab_addr)));
11781 assign(op1, load(Ity_I16, mkexpr(result)));
11782
11783 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
11784 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011785 next_insn_if(binop(Iop_CmpEQ16, mkexpr(op1), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000011786 }
11787
11788 store(get_gpr_dw0(r1), mkexpr(op1));
11789
11790 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(2)));
11791 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(2)));
11792 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(2)));
11793
florian6820ba52012-07-26 02:01:50 +000011794 iterate();
florian730448f2012-02-04 17:07:07 +000011795
11796 return "trtt";
11797}
11798
florian55085f82012-11-21 00:36:55 +000011799static const HChar *
florian730448f2012-02-04 17:07:07 +000011800s390_irgen_TR(UChar length, IRTemp start1, IRTemp start2)
11801{
florianf87d4fb2012-05-05 02:55:24 +000011802 IRTemp len = newTemp(Ity_I64);
florian730448f2012-02-04 17:07:07 +000011803
florianf87d4fb2012-05-05 02:55:24 +000011804 assign(len, mkU64(length));
11805 s390_irgen_TR_EX(len, start1, start2);
florian730448f2012-02-04 17:07:07 +000011806
11807 return "tr";
11808}
11809
florian55085f82012-11-21 00:36:55 +000011810static const HChar *
florian730448f2012-02-04 17:07:07 +000011811s390_irgen_TRE(UChar r1,UChar r2)
11812{
11813 IRTemp src_addr, tab_addr, src_len, test_byte;
11814 src_addr = newTemp(Ity_I64);
11815 tab_addr = newTemp(Ity_I64);
11816 src_len = newTemp(Ity_I64);
11817 test_byte = newTemp(Ity_I8);
11818
11819 assign(src_addr, get_gpr_dw0(r1));
11820 assign(src_len, get_gpr_dw0(r1+1));
11821 assign(tab_addr, get_gpr_dw0(r2));
11822 assign(test_byte, get_gpr_b7(0));
11823
11824 IRTemp op = newTemp(Ity_I8);
11825 IRTemp op1 = newTemp(Ity_I8);
11826 IRTemp result = newTemp(Ity_I64);
11827
11828 /* End of source string? We're done; proceed to next insn */
11829 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000011830 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000011831
11832 /* Load character from source string and compare with test byte */
11833 assign(op, load(Ity_I8, mkexpr(src_addr)));
11834
11835 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011836 next_insn_if(binop(Iop_CmpEQ8, mkexpr(op), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000011837
11838 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
11839 mkexpr(tab_addr)));
11840
11841 assign(op1, load(Ity_I8, mkexpr(result)));
11842
11843 store(get_gpr_dw0(r1), mkexpr(op1));
11844 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
11845 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
11846
florian6820ba52012-07-26 02:01:50 +000011847 iterate();
florian730448f2012-02-04 17:07:07 +000011848
11849 return "tre";
11850}
11851
floriana0100c92012-07-20 00:06:35 +000011852static IRExpr *
11853s390_call_cu21(IRExpr *srcval, IRExpr *low_surrogate)
11854{
11855 IRExpr **args, *call;
11856 args = mkIRExprVec_2(srcval, low_surrogate);
11857 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
11858 "s390_do_cu21", &s390_do_cu21, args);
11859
11860 /* Nothing is excluded from definedness checking. */
11861 call->Iex.CCall.cee->mcx_mask = 0;
11862
11863 return call;
11864}
11865
florian55085f82012-11-21 00:36:55 +000011866static const HChar *
floriana0100c92012-07-20 00:06:35 +000011867s390_irgen_CU21(UChar m3, UChar r1, UChar r2)
11868{
11869 IRTemp addr1 = newTemp(Ity_I64);
11870 IRTemp addr2 = newTemp(Ity_I64);
11871 IRTemp len1 = newTemp(Ity_I64);
11872 IRTemp len2 = newTemp(Ity_I64);
11873
11874 assign(addr1, get_gpr_dw0(r1));
11875 assign(addr2, get_gpr_dw0(r2));
11876 assign(len1, get_gpr_dw0(r1 + 1));
11877 assign(len2, get_gpr_dw0(r2 + 1));
11878
11879 /* We're processing the 2nd operand 2 bytes at a time. Therefore, if
11880 there are less than 2 bytes left, then the 2nd operand is exhausted
11881 and we're done here. cc = 0 */
11882 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000011883 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(2)));
floriana0100c92012-07-20 00:06:35 +000011884
11885 /* There are at least two bytes there. Read them. */
11886 IRTemp srcval = newTemp(Ity_I32);
11887 assign(srcval, unop(Iop_16Uto32, load(Ity_I16, mkexpr(addr2))));
11888
11889 /* Find out whether this is a high surrogate. I.e. SRCVAL lies
11890 inside the interval [0xd800 - 0xdbff] */
11891 IRTemp is_high_surrogate = newTemp(Ity_I32);
11892 IRExpr *flag1 = mkite(binop(Iop_CmpLE32U, mkU32(0xd800), mkexpr(srcval)),
11893 mkU32(1), mkU32(0));
11894 IRExpr *flag2 = mkite(binop(Iop_CmpLE32U, mkexpr(srcval), mkU32(0xdbff)),
11895 mkU32(1), mkU32(0));
11896 assign(is_high_surrogate, binop(Iop_And32, flag1, flag2));
11897
11898 /* If SRCVAL is a high surrogate and there are less than 4 bytes left,
11899 then the 2nd operand is exhausted and we're done here. cc = 0 */
11900 IRExpr *not_enough_bytes =
11901 mkite(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)), mkU32(1), mkU32(0));
11902
florian6820ba52012-07-26 02:01:50 +000011903 next_insn_if(binop(Iop_CmpEQ32,
11904 binop(Iop_And32, mkexpr(is_high_surrogate),
11905 not_enough_bytes), mkU32(1)));
floriana0100c92012-07-20 00:06:35 +000011906
11907 /* The 2nd operand is not exhausted. If the first 2 bytes are a high
11908 surrogate, read the next two bytes (low surrogate). */
11909 IRTemp low_surrogate = newTemp(Ity_I32);
11910 IRExpr *low_surrogate_addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
11911
11912 assign(low_surrogate,
11913 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
11914 unop(Iop_16Uto32, load(Ity_I16, low_surrogate_addr)),
11915 mkU32(0))); // any value is fine; it will not be used
11916
11917 /* Call the helper */
11918 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000011919 assign(retval, s390_call_cu21(unop(Iop_32Uto64, mkexpr(srcval)),
11920 unop(Iop_32Uto64, mkexpr(low_surrogate))));
floriana0100c92012-07-20 00:06:35 +000011921
11922 /* Before we can test whether the 1st operand is exhausted we need to
11923 test for an invalid low surrogate. Because cc=2 outranks cc=1. */
11924 if (s390_host_has_etf3 && (m3 & 0x1) == 1) {
11925 IRExpr *invalid_low_surrogate =
11926 binop(Iop_And64, mkexpr(retval), mkU64(0xff));
11927
11928 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +000011929 next_insn_if(binop(Iop_CmpEQ64, invalid_low_surrogate, mkU64(1)));
floriana0100c92012-07-20 00:06:35 +000011930 }
11931
11932 /* Now test whether the 1st operand is exhausted */
11933 IRTemp num_bytes = newTemp(Ity_I64);
11934 assign(num_bytes, binop(Iop_And64,
11935 binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
11936 mkU64(0xff)));
11937 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011938 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
floriana0100c92012-07-20 00:06:35 +000011939
11940 /* Extract the bytes to be stored at addr1 */
11941 IRTemp data = newTemp(Ity_I64);
11942 assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
11943
11944 /* To store the bytes construct 4 dirty helper calls. The helper calls
11945 are guarded (num_bytes == 1, num_bytes == 2, etc) such that only
11946 one of them will be called at runtime. */
11947 int i;
11948 for (i = 1; i <= 4; ++i) {
11949 IRDirty *d;
11950
11951 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
11952 &s390x_dirtyhelper_CUxy,
11953 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
11954 mkexpr(num_bytes)));
11955 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
11956 d->mFx = Ifx_Write;
11957 d->mAddr = mkexpr(addr1);
11958 d->mSize = i;
11959 stmt(IRStmt_Dirty(d));
11960 }
11961
11962 /* Update source address and length */
11963 IRTemp num_src_bytes = newTemp(Ity_I64);
11964 assign(num_src_bytes,
11965 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
11966 mkU64(4), mkU64(2)));
11967 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
11968 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkexpr(num_src_bytes)));
11969
11970 /* Update destination address and length */
11971 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
11972 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
11973
florian6820ba52012-07-26 02:01:50 +000011974 iterate();
floriana0100c92012-07-20 00:06:35 +000011975
11976 return "cu21";
11977}
11978
florian2a415a12012-07-21 17:41:36 +000011979static IRExpr *
11980s390_call_cu24(IRExpr *srcval, IRExpr *low_surrogate)
11981{
11982 IRExpr **args, *call;
11983 args = mkIRExprVec_2(srcval, low_surrogate);
11984 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
11985 "s390_do_cu24", &s390_do_cu24, args);
11986
11987 /* Nothing is excluded from definedness checking. */
11988 call->Iex.CCall.cee->mcx_mask = 0;
11989
11990 return call;
11991}
11992
florian55085f82012-11-21 00:36:55 +000011993static const HChar *
florian2a415a12012-07-21 17:41:36 +000011994s390_irgen_CU24(UChar m3, UChar r1, UChar r2)
11995{
11996 IRTemp addr1 = newTemp(Ity_I64);
11997 IRTemp addr2 = newTemp(Ity_I64);
11998 IRTemp len1 = newTemp(Ity_I64);
11999 IRTemp len2 = newTemp(Ity_I64);
12000
12001 assign(addr1, get_gpr_dw0(r1));
12002 assign(addr2, get_gpr_dw0(r2));
12003 assign(len1, get_gpr_dw0(r1 + 1));
12004 assign(len2, get_gpr_dw0(r2 + 1));
12005
12006 /* We're processing the 2nd operand 2 bytes at a time. Therefore, if
12007 there are less than 2 bytes left, then the 2nd operand is exhausted
12008 and we're done here. cc = 0 */
12009 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000012010 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(2)));
florian2a415a12012-07-21 17:41:36 +000012011
12012 /* There are at least two bytes there. Read them. */
12013 IRTemp srcval = newTemp(Ity_I32);
12014 assign(srcval, unop(Iop_16Uto32, load(Ity_I16, mkexpr(addr2))));
12015
12016 /* Find out whether this is a high surrogate. I.e. SRCVAL lies
12017 inside the interval [0xd800 - 0xdbff] */
12018 IRTemp is_high_surrogate = newTemp(Ity_I32);
12019 IRExpr *flag1 = mkite(binop(Iop_CmpLE32U, mkU32(0xd800), mkexpr(srcval)),
12020 mkU32(1), mkU32(0));
12021 IRExpr *flag2 = mkite(binop(Iop_CmpLE32U, mkexpr(srcval), mkU32(0xdbff)),
12022 mkU32(1), mkU32(0));
12023 assign(is_high_surrogate, binop(Iop_And32, flag1, flag2));
12024
12025 /* If SRCVAL is a high surrogate and there are less than 4 bytes left,
12026 then the 2nd operand is exhausted and we're done here. cc = 0 */
12027 IRExpr *not_enough_bytes =
12028 mkite(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)), mkU32(1), mkU32(0));
12029
florian6820ba52012-07-26 02:01:50 +000012030 next_insn_if(binop(Iop_CmpEQ32,
12031 binop(Iop_And32, mkexpr(is_high_surrogate),
12032 not_enough_bytes),
12033 mkU32(1)));
florian2a415a12012-07-21 17:41:36 +000012034
12035 /* The 2nd operand is not exhausted. If the first 2 bytes are a high
12036 surrogate, read the next two bytes (low surrogate). */
12037 IRTemp low_surrogate = newTemp(Ity_I32);
12038 IRExpr *low_surrogate_addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
12039
12040 assign(low_surrogate,
12041 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
12042 unop(Iop_16Uto32, load(Ity_I16, low_surrogate_addr)),
12043 mkU32(0))); // any value is fine; it will not be used
12044
12045 /* Call the helper */
12046 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000012047 assign(retval, s390_call_cu24(unop(Iop_32Uto64, mkexpr(srcval)),
12048 unop(Iop_32Uto64, mkexpr(low_surrogate))));
florian2a415a12012-07-21 17:41:36 +000012049
12050 /* Before we can test whether the 1st operand is exhausted we need to
12051 test for an invalid low surrogate. Because cc=2 outranks cc=1. */
12052 if (s390_host_has_etf3 && (m3 & 0x1) == 1) {
12053 IRExpr *invalid_low_surrogate =
12054 binop(Iop_And64, mkexpr(retval), mkU64(0xff));
12055
12056 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +000012057 next_insn_if(binop(Iop_CmpEQ64, invalid_low_surrogate, mkU64(1)));
florian2a415a12012-07-21 17:41:36 +000012058 }
12059
12060 /* Now test whether the 1st operand is exhausted */
12061 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000012062 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkU64(4)));
florian2a415a12012-07-21 17:41:36 +000012063
12064 /* Extract the bytes to be stored at addr1 */
12065 IRExpr *data = unop(Iop_64to32, binop(Iop_Shr64, mkexpr(retval), mkU8(8)));
12066
12067 store(mkexpr(addr1), data);
12068
12069 /* Update source address and length */
12070 IRTemp num_src_bytes = newTemp(Ity_I64);
12071 assign(num_src_bytes,
12072 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
12073 mkU64(4), mkU64(2)));
12074 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
12075 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkexpr(num_src_bytes)));
12076
12077 /* Update destination address and length */
12078 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(4)));
12079 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkU64(4)));
12080
florian6820ba52012-07-26 02:01:50 +000012081 iterate();
florian2a415a12012-07-21 17:41:36 +000012082
12083 return "cu24";
12084}
floriana4384a32011-08-11 16:58:45 +000012085
florian956194b2012-07-28 22:18:32 +000012086static IRExpr *
12087s390_call_cu42(IRExpr *srcval)
12088{
12089 IRExpr **args, *call;
12090 args = mkIRExprVec_1(srcval);
12091 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
12092 "s390_do_cu42", &s390_do_cu42, args);
12093
12094 /* Nothing is excluded from definedness checking. */
12095 call->Iex.CCall.cee->mcx_mask = 0;
12096
12097 return call;
12098}
12099
florian55085f82012-11-21 00:36:55 +000012100static const HChar *
florian956194b2012-07-28 22:18:32 +000012101s390_irgen_CU42(UChar r1, UChar r2)
12102{
12103 IRTemp addr1 = newTemp(Ity_I64);
12104 IRTemp addr2 = newTemp(Ity_I64);
12105 IRTemp len1 = newTemp(Ity_I64);
12106 IRTemp len2 = newTemp(Ity_I64);
12107
12108 assign(addr1, get_gpr_dw0(r1));
12109 assign(addr2, get_gpr_dw0(r2));
12110 assign(len1, get_gpr_dw0(r1 + 1));
12111 assign(len2, get_gpr_dw0(r2 + 1));
12112
12113 /* We're processing the 2nd operand 4 bytes at a time. Therefore, if
12114 there are less than 4 bytes left, then the 2nd operand is exhausted
12115 and we're done here. cc = 0 */
12116 s390_cc_set(0);
12117 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)));
12118
12119 /* Read the 2nd operand. */
12120 IRTemp srcval = newTemp(Ity_I32);
12121 assign(srcval, load(Ity_I32, mkexpr(addr2)));
12122
12123 /* Call the helper */
12124 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000012125 assign(retval, s390_call_cu42(unop(Iop_32Uto64, mkexpr(srcval))));
florian956194b2012-07-28 22:18:32 +000012126
12127 /* If the UTF-32 character was invalid, set cc=2 and we're done.
12128 cc=2 outranks cc=1 (1st operand exhausted) */
12129 IRExpr *invalid_character = binop(Iop_And64, mkexpr(retval), mkU64(0xff));
12130
12131 s390_cc_set(2);
12132 next_insn_if(binop(Iop_CmpEQ64, invalid_character, mkU64(1)));
12133
12134 /* Now test whether the 1st operand is exhausted */
12135 IRTemp num_bytes = newTemp(Ity_I64);
12136 assign(num_bytes, binop(Iop_And64,
12137 binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
12138 mkU64(0xff)));
12139 s390_cc_set(1);
12140 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
12141
12142 /* Extract the bytes to be stored at addr1 */
12143 IRTemp data = newTemp(Ity_I64);
12144 assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
12145
12146 /* To store the bytes construct 2 dirty helper calls. The helper calls
12147 are guarded (num_bytes == 2 and num_bytes == 4, respectively) such
12148 that only one of them will be called at runtime. */
12149
12150 Int i;
12151 for (i = 2; i <= 4; ++i) {
12152 IRDirty *d;
12153
12154 if (i == 3) continue; // skip this one
12155
12156 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
12157 &s390x_dirtyhelper_CUxy,
12158 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
12159 mkexpr(num_bytes)));
12160 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
12161 d->mFx = Ifx_Write;
12162 d->mAddr = mkexpr(addr1);
12163 d->mSize = i;
12164 stmt(IRStmt_Dirty(d));
12165 }
12166
12167 /* Update source address and length */
12168 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkU64(4)));
12169 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkU64(4)));
12170
12171 /* Update destination address and length */
12172 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
12173 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
12174
12175 iterate();
12176
12177 return "cu42";
12178}
12179
florian6d9b9b22012-08-03 18:35:39 +000012180static IRExpr *
florianaf2194f2012-08-06 00:07:54 +000012181s390_call_cu41(IRExpr *srcval)
12182{
12183 IRExpr **args, *call;
12184 args = mkIRExprVec_1(srcval);
12185 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
12186 "s390_do_cu41", &s390_do_cu41, args);
12187
12188 /* Nothing is excluded from definedness checking. */
12189 call->Iex.CCall.cee->mcx_mask = 0;
12190
12191 return call;
12192}
12193
florian55085f82012-11-21 00:36:55 +000012194static const HChar *
florianaf2194f2012-08-06 00:07:54 +000012195s390_irgen_CU41(UChar r1, UChar r2)
12196{
12197 IRTemp addr1 = newTemp(Ity_I64);
12198 IRTemp addr2 = newTemp(Ity_I64);
12199 IRTemp len1 = newTemp(Ity_I64);
12200 IRTemp len2 = newTemp(Ity_I64);
12201
12202 assign(addr1, get_gpr_dw0(r1));
12203 assign(addr2, get_gpr_dw0(r2));
12204 assign(len1, get_gpr_dw0(r1 + 1));
12205 assign(len2, get_gpr_dw0(r2 + 1));
12206
12207 /* We're processing the 2nd operand 4 bytes at a time. Therefore, if
12208 there are less than 4 bytes left, then the 2nd operand is exhausted
12209 and we're done here. cc = 0 */
12210 s390_cc_set(0);
12211 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)));
12212
12213 /* Read the 2nd operand. */
12214 IRTemp srcval = newTemp(Ity_I32);
12215 assign(srcval, load(Ity_I32, mkexpr(addr2)));
12216
12217 /* Call the helper */
12218 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000012219 assign(retval, s390_call_cu41(unop(Iop_32Uto64, mkexpr(srcval))));
florianaf2194f2012-08-06 00:07:54 +000012220
12221 /* If the UTF-32 character was invalid, set cc=2 and we're done.
12222 cc=2 outranks cc=1 (1st operand exhausted) */
12223 IRExpr *invalid_character = binop(Iop_And64, mkexpr(retval), mkU64(0xff));
12224
12225 s390_cc_set(2);
12226 next_insn_if(binop(Iop_CmpEQ64, invalid_character, mkU64(1)));
12227
12228 /* Now test whether the 1st operand is exhausted */
12229 IRTemp num_bytes = newTemp(Ity_I64);
12230 assign(num_bytes, binop(Iop_And64,
12231 binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
12232 mkU64(0xff)));
12233 s390_cc_set(1);
12234 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
12235
12236 /* Extract the bytes to be stored at addr1 */
12237 IRTemp data = newTemp(Ity_I64);
12238 assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
12239
12240 /* To store the bytes construct 4 dirty helper calls. The helper calls
12241 are guarded (num_bytes == 1, num_bytes == 2, etc) such that only
12242 one of them will be called at runtime. */
12243 int i;
12244 for (i = 1; i <= 4; ++i) {
12245 IRDirty *d;
12246
12247 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
12248 &s390x_dirtyhelper_CUxy,
12249 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
12250 mkexpr(num_bytes)));
12251 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
12252 d->mFx = Ifx_Write;
12253 d->mAddr = mkexpr(addr1);
12254 d->mSize = i;
12255 stmt(IRStmt_Dirty(d));
12256 }
12257
12258 /* Update source address and length */
12259 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkU64(4)));
12260 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkU64(4)));
12261
12262 /* Update destination address and length */
12263 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
12264 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
12265
12266 iterate();
12267
12268 return "cu41";
12269}
12270
12271static IRExpr *
florian3f8a96a2012-08-05 02:59:55 +000012272s390_call_cu12_cu14_helper1(IRExpr *byte1, IRExpr *etf3_and_m3_is_1)
florian6d9b9b22012-08-03 18:35:39 +000012273{
12274 IRExpr **args, *call;
12275 args = mkIRExprVec_2(byte1, etf3_and_m3_is_1);
florian3f8a96a2012-08-05 02:59:55 +000012276 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/, "s390_do_cu12_cu14_helper1",
12277 &s390_do_cu12_cu14_helper1, args);
florian6d9b9b22012-08-03 18:35:39 +000012278
12279 /* Nothing is excluded from definedness checking. */
12280 call->Iex.CCall.cee->mcx_mask = 0;
12281
12282 return call;
12283}
12284
12285static IRExpr *
12286s390_call_cu12_helper2(IRExpr *byte1, IRExpr *byte2, IRExpr *byte3,
12287 IRExpr *byte4, IRExpr *stuff)
12288{
12289 IRExpr **args, *call;
12290 args = mkIRExprVec_5(byte1, byte2, byte3, byte4, stuff);
12291 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
12292 "s390_do_cu12_helper2", &s390_do_cu12_helper2, args);
12293
12294 /* Nothing is excluded from definedness checking. */
12295 call->Iex.CCall.cee->mcx_mask = 0;
12296
12297 return call;
12298}
12299
florian3f8a96a2012-08-05 02:59:55 +000012300static IRExpr *
12301s390_call_cu14_helper2(IRExpr *byte1, IRExpr *byte2, IRExpr *byte3,
12302 IRExpr *byte4, IRExpr *stuff)
12303{
12304 IRExpr **args, *call;
12305 args = mkIRExprVec_5(byte1, byte2, byte3, byte4, stuff);
12306 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
12307 "s390_do_cu14_helper2", &s390_do_cu14_helper2, args);
12308
12309 /* Nothing is excluded from definedness checking. */
12310 call->Iex.CCall.cee->mcx_mask = 0;
12311
12312 return call;
12313}
12314
12315static void
12316s390_irgen_cu12_cu14(UChar m3, UChar r1, UChar r2, Bool is_cu12)
florian6d9b9b22012-08-03 18:35:39 +000012317{
12318 IRTemp addr1 = newTemp(Ity_I64);
12319 IRTemp addr2 = newTemp(Ity_I64);
12320 IRTemp len1 = newTemp(Ity_I64);
12321 IRTemp len2 = newTemp(Ity_I64);
12322
12323 assign(addr1, get_gpr_dw0(r1));
12324 assign(addr2, get_gpr_dw0(r2));
12325 assign(len1, get_gpr_dw0(r1 + 1));
12326 assign(len2, get_gpr_dw0(r2 + 1));
12327
12328 UInt extended_checking = s390_host_has_etf3 && (m3 & 0x1) == 1;
12329
12330 /* We're processing the 2nd operand 1 byte at a time. Therefore, if
12331 there is less than 1 byte left, then the 2nd operand is exhausted
12332 and we're done here. cc = 0 */
12333 s390_cc_set(0);
12334 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(1)));
12335
12336 /* There is at least one byte there. Read it. */
florian11b8ee82012-08-06 13:35:33 +000012337 IRTemp byte1 = newTemp(Ity_I64);
12338 assign(byte1, unop(Iop_8Uto64, load(Ity_I8, mkexpr(addr2))));
florian6d9b9b22012-08-03 18:35:39 +000012339
12340 /* Call the helper to get number of bytes and invalid byte indicator */
12341 IRTemp retval1 = newTemp(Ity_I64);
florian3f8a96a2012-08-05 02:59:55 +000012342 assign(retval1, s390_call_cu12_cu14_helper1(mkexpr(byte1),
florian11b8ee82012-08-06 13:35:33 +000012343 mkU64(extended_checking)));
florian6d9b9b22012-08-03 18:35:39 +000012344
12345 /* Check for invalid 1st byte */
12346 IRExpr *is_invalid = unop(Iop_64to1, mkexpr(retval1));
12347 s390_cc_set(2);
12348 next_insn_if(is_invalid);
12349
12350 /* How many bytes do we have to read? */
12351 IRTemp num_src_bytes = newTemp(Ity_I64);
12352 assign(num_src_bytes, binop(Iop_Shr64, mkexpr(retval1), mkU8(8)));
12353
12354 /* Now test whether the 2nd operand is exhausted */
12355 s390_cc_set(0);
12356 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkexpr(num_src_bytes)));
12357
12358 /* Read the remaining bytes */
12359 IRExpr *cond, *addr, *byte2, *byte3, *byte4;
12360
12361 cond = binop(Iop_CmpLE64U, mkU64(2), mkexpr(num_src_bytes));
12362 addr = binop(Iop_Add64, mkexpr(addr2), mkU64(1));
florian11b8ee82012-08-06 13:35:33 +000012363 byte2 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
florian6d9b9b22012-08-03 18:35:39 +000012364 cond = binop(Iop_CmpLE64U, mkU64(3), mkexpr(num_src_bytes));
12365 addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
florian11b8ee82012-08-06 13:35:33 +000012366 byte3 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
florian6d9b9b22012-08-03 18:35:39 +000012367 cond = binop(Iop_CmpLE64U, mkU64(4), mkexpr(num_src_bytes));
12368 addr = binop(Iop_Add64, mkexpr(addr2), mkU64(3));
florian11b8ee82012-08-06 13:35:33 +000012369 byte4 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
florian6d9b9b22012-08-03 18:35:39 +000012370
12371 /* Call the helper to get the converted value and invalid byte indicator.
12372 We can pass at most 5 arguments; therefore some encoding is needed
12373 here */
12374 IRExpr *stuff = binop(Iop_Or64,
12375 binop(Iop_Shl64, mkexpr(num_src_bytes), mkU8(1)),
12376 mkU64(extended_checking));
12377 IRTemp retval2 = newTemp(Ity_I64);
florian3f8a96a2012-08-05 02:59:55 +000012378
12379 if (is_cu12) {
12380 assign(retval2, s390_call_cu12_helper2(mkexpr(byte1), byte2, byte3,
12381 byte4, stuff));
12382 } else {
12383 assign(retval2, s390_call_cu14_helper2(mkexpr(byte1), byte2, byte3,
12384 byte4, stuff));
12385 }
florian6d9b9b22012-08-03 18:35:39 +000012386
12387 /* Check for invalid character */
12388 s390_cc_set(2);
12389 is_invalid = unop(Iop_64to1, mkexpr(retval2));
12390 next_insn_if(is_invalid);
12391
12392 /* Now test whether the 1st operand is exhausted */
12393 IRTemp num_bytes = newTemp(Ity_I64);
12394 assign(num_bytes, binop(Iop_And64,
12395 binop(Iop_Shr64, mkexpr(retval2), mkU8(8)),
12396 mkU64(0xff)));
12397 s390_cc_set(1);
12398 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
12399
12400 /* Extract the bytes to be stored at addr1 */
12401 IRTemp data = newTemp(Ity_I64);
12402 assign(data, binop(Iop_Shr64, mkexpr(retval2), mkU8(16)));
12403
florian3f8a96a2012-08-05 02:59:55 +000012404 if (is_cu12) {
12405 /* To store the bytes construct 2 dirty helper calls. The helper calls
12406 are guarded (num_bytes == 2 and num_bytes == 4, respectively) such
12407 that only one of them will be called at runtime. */
florian6d9b9b22012-08-03 18:35:39 +000012408
florian3f8a96a2012-08-05 02:59:55 +000012409 Int i;
12410 for (i = 2; i <= 4; ++i) {
12411 IRDirty *d;
florian6d9b9b22012-08-03 18:35:39 +000012412
florian3f8a96a2012-08-05 02:59:55 +000012413 if (i == 3) continue; // skip this one
florian6d9b9b22012-08-03 18:35:39 +000012414
florian3f8a96a2012-08-05 02:59:55 +000012415 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
12416 &s390x_dirtyhelper_CUxy,
12417 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
12418 mkexpr(num_bytes)));
12419 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
12420 d->mFx = Ifx_Write;
12421 d->mAddr = mkexpr(addr1);
12422 d->mSize = i;
12423 stmt(IRStmt_Dirty(d));
12424 }
12425 } else {
12426 // cu14
12427 store(mkexpr(addr1), unop(Iop_64to32, mkexpr(data)));
florian6d9b9b22012-08-03 18:35:39 +000012428 }
12429
12430 /* Update source address and length */
12431 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
12432 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkexpr(num_src_bytes)));
12433
12434 /* Update destination address and length */
12435 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
12436 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
12437
12438 iterate();
florian3f8a96a2012-08-05 02:59:55 +000012439}
12440
florian55085f82012-11-21 00:36:55 +000012441static const HChar *
florian3f8a96a2012-08-05 02:59:55 +000012442s390_irgen_CU12(UChar m3, UChar r1, UChar r2)
12443{
12444 s390_irgen_cu12_cu14(m3, r1, r2, /* is_cu12 = */ 1);
florian6d9b9b22012-08-03 18:35:39 +000012445
12446 return "cu12";
12447}
12448
florian55085f82012-11-21 00:36:55 +000012449static const HChar *
florian3f8a96a2012-08-05 02:59:55 +000012450s390_irgen_CU14(UChar m3, UChar r1, UChar r2)
12451{
12452 s390_irgen_cu12_cu14(m3, r1, r2, /* is_cu12 = */ 0);
12453
12454 return "cu14";
12455}
12456
florian8c88cb62012-08-26 18:58:13 +000012457static IRExpr *
12458s390_call_ecag(IRExpr *op2addr)
12459{
12460 IRExpr **args, *call;
12461
12462 args = mkIRExprVec_1(op2addr);
12463 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
12464 "s390_do_ecag", &s390_do_ecag, args);
12465
12466 /* Nothing is excluded from definedness checking. */
12467 call->Iex.CCall.cee->mcx_mask = 0;
12468
12469 return call;
12470}
12471
florian55085f82012-11-21 00:36:55 +000012472static const HChar *
floriand2129202012-09-01 20:01:39 +000012473s390_irgen_ECAG(UChar r1, UChar r3 __attribute__((unused)), IRTemp op2addr)
florian8c88cb62012-08-26 18:58:13 +000012474{
12475 if (! s390_host_has_gie) {
floriane75dafa2012-09-01 17:54:09 +000012476 emulation_failure(EmFail_S390X_ecag);
florian8c88cb62012-08-26 18:58:13 +000012477 } else {
12478 put_gpr_dw0(r1, s390_call_ecag(mkexpr(op2addr)));
12479 }
12480
12481 return "ecag";
12482}
12483
12484
florianb7def222012-12-04 04:45:32 +000012485/* New insns are added here.
12486 If an insn is contingent on a facility being installed also
12487 check whether the list of supported facilities in function
12488 s390x_dirtyhelper_STFLE needs updating */
12489
sewardj2019a972011-03-07 16:04:07 +000012490/*------------------------------------------------------------*/
12491/*--- Build IR for special instructions ---*/
12492/*------------------------------------------------------------*/
12493
florianb4df7682011-07-05 02:09:01 +000012494static void
sewardj2019a972011-03-07 16:04:07 +000012495s390_irgen_client_request(void)
12496{
12497 if (0)
12498 vex_printf("%%R3 = client_request ( %%R2 )\n");
12499
florianf9e1ed72012-04-17 02:41:56 +000012500 Addr64 next = guest_IA_curr_instr + S390_SPECIAL_OP_PREAMBLE_SIZE
12501 + S390_SPECIAL_OP_SIZE;
sewardj2019a972011-03-07 16:04:07 +000012502
florianf9e1ed72012-04-17 02:41:56 +000012503 dis_res->jk_StopHere = Ijk_ClientReq;
sewardj2019a972011-03-07 16:04:07 +000012504 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +000012505
12506 put_IA(mkaddr_expr(next));
sewardj2019a972011-03-07 16:04:07 +000012507}
12508
florianb4df7682011-07-05 02:09:01 +000012509static void
sewardj2019a972011-03-07 16:04:07 +000012510s390_irgen_guest_NRADDR(void)
12511{
12512 if (0)
12513 vex_printf("%%R3 = guest_NRADDR\n");
12514
floriane88b3c92011-07-05 02:48:39 +000012515 put_gpr_dw0(3, IRExpr_Get(S390X_GUEST_OFFSET(guest_NRADDR), Ity_I64));
sewardj2019a972011-03-07 16:04:07 +000012516}
12517
florianb4df7682011-07-05 02:09:01 +000012518static void
sewardj2019a972011-03-07 16:04:07 +000012519s390_irgen_call_noredir(void)
12520{
florianf9e1ed72012-04-17 02:41:56 +000012521 Addr64 next = guest_IA_curr_instr + S390_SPECIAL_OP_PREAMBLE_SIZE
12522 + S390_SPECIAL_OP_SIZE;
12523
sewardj2019a972011-03-07 16:04:07 +000012524 /* Continue after special op */
florianf9e1ed72012-04-17 02:41:56 +000012525 put_gpr_dw0(14, mkaddr_expr(next));
sewardj2019a972011-03-07 16:04:07 +000012526
12527 /* The address is in REG1, all parameters are in the right (guest) places */
florianf9e1ed72012-04-17 02:41:56 +000012528 put_IA(get_gpr_dw0(1));
sewardj2019a972011-03-07 16:04:07 +000012529
12530 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +000012531 dis_res->jk_StopHere = Ijk_NoRedir;
sewardj2019a972011-03-07 16:04:07 +000012532}
12533
12534/* Force proper alignment for the structures below. */
12535#pragma pack(1)
12536
12537
12538static s390_decode_t
12539s390_decode_2byte_and_irgen(UChar *bytes)
12540{
12541 typedef union {
12542 struct {
12543 unsigned int op : 16;
12544 } E;
12545 struct {
12546 unsigned int op : 8;
12547 unsigned int i : 8;
12548 } I;
12549 struct {
12550 unsigned int op : 8;
12551 unsigned int r1 : 4;
12552 unsigned int r2 : 4;
12553 } RR;
12554 } formats;
12555 union {
12556 formats fmt;
12557 UShort value;
12558 } ovl;
12559
12560 vassert(sizeof(formats) == 2);
12561
12562 ((char *)(&ovl.value))[0] = bytes[0];
12563 ((char *)(&ovl.value))[1] = bytes[1];
12564
12565 switch (ovl.value & 0xffff) {
12566 case 0x0101: /* PR */ goto unimplemented;
12567 case 0x0102: /* UPT */ goto unimplemented;
12568 case 0x0104: /* PTFF */ goto unimplemented;
12569 case 0x0107: /* SCKPF */ goto unimplemented;
12570 case 0x010a: /* PFPO */ goto unimplemented;
12571 case 0x010b: /* TAM */ goto unimplemented;
12572 case 0x010c: /* SAM24 */ goto unimplemented;
12573 case 0x010d: /* SAM31 */ goto unimplemented;
12574 case 0x010e: /* SAM64 */ goto unimplemented;
12575 case 0x01ff: /* TRAP2 */ goto unimplemented;
12576 }
12577
12578 switch ((ovl.value & 0xff00) >> 8) {
12579 case 0x04: /* SPM */ goto unimplemented;
12580 case 0x05: /* BALR */ goto unimplemented;
12581 case 0x06: s390_format_RR_RR(s390_irgen_BCTR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12582 goto ok;
12583 case 0x07: s390_format_RR(s390_irgen_BCR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12584 goto ok;
12585 case 0x0a: s390_format_I(s390_irgen_SVC, ovl.fmt.I.i); goto ok;
12586 case 0x0b: /* BSM */ goto unimplemented;
12587 case 0x0c: /* BASSM */ goto unimplemented;
12588 case 0x0d: s390_format_RR_RR(s390_irgen_BASR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12589 goto ok;
florianb0c9a132011-09-08 15:37:39 +000012590 case 0x0e: s390_format_RR(s390_irgen_MVCL, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12591 goto ok;
12592 case 0x0f: s390_format_RR(s390_irgen_CLCL, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12593 goto ok;
sewardj2019a972011-03-07 16:04:07 +000012594 case 0x10: s390_format_RR_RR(s390_irgen_LPR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12595 goto ok;
12596 case 0x11: s390_format_RR_RR(s390_irgen_LNR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12597 goto ok;
12598 case 0x12: s390_format_RR_RR(s390_irgen_LTR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12599 goto ok;
12600 case 0x13: s390_format_RR_RR(s390_irgen_LCR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12601 goto ok;
12602 case 0x14: s390_format_RR_RR(s390_irgen_NR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12603 goto ok;
12604 case 0x15: s390_format_RR_RR(s390_irgen_CLR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12605 goto ok;
12606 case 0x16: s390_format_RR_RR(s390_irgen_OR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12607 goto ok;
12608 case 0x17: s390_format_RR_RR(s390_irgen_XR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12609 goto ok;
12610 case 0x18: s390_format_RR_RR(s390_irgen_LR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12611 goto ok;
12612 case 0x19: s390_format_RR_RR(s390_irgen_CR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12613 goto ok;
12614 case 0x1a: s390_format_RR_RR(s390_irgen_AR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12615 goto ok;
12616 case 0x1b: s390_format_RR_RR(s390_irgen_SR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12617 goto ok;
12618 case 0x1c: s390_format_RR_RR(s390_irgen_MR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12619 goto ok;
12620 case 0x1d: s390_format_RR_RR(s390_irgen_DR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12621 goto ok;
12622 case 0x1e: s390_format_RR_RR(s390_irgen_ALR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12623 goto ok;
12624 case 0x1f: s390_format_RR_RR(s390_irgen_SLR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12625 goto ok;
12626 case 0x20: /* LPDR */ goto unimplemented;
12627 case 0x21: /* LNDR */ goto unimplemented;
12628 case 0x22: /* LTDR */ goto unimplemented;
12629 case 0x23: /* LCDR */ goto unimplemented;
12630 case 0x24: /* HDR */ goto unimplemented;
12631 case 0x25: /* LDXR */ goto unimplemented;
12632 case 0x26: /* MXR */ goto unimplemented;
12633 case 0x27: /* MXDR */ goto unimplemented;
12634 case 0x28: s390_format_RR_FF(s390_irgen_LDR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12635 goto ok;
12636 case 0x29: /* CDR */ goto unimplemented;
12637 case 0x2a: /* ADR */ goto unimplemented;
12638 case 0x2b: /* SDR */ goto unimplemented;
12639 case 0x2c: /* MDR */ goto unimplemented;
12640 case 0x2d: /* DDR */ goto unimplemented;
12641 case 0x2e: /* AWR */ goto unimplemented;
12642 case 0x2f: /* SWR */ goto unimplemented;
12643 case 0x30: /* LPER */ goto unimplemented;
12644 case 0x31: /* LNER */ goto unimplemented;
12645 case 0x32: /* LTER */ goto unimplemented;
12646 case 0x33: /* LCER */ goto unimplemented;
12647 case 0x34: /* HER */ goto unimplemented;
12648 case 0x35: /* LEDR */ goto unimplemented;
12649 case 0x36: /* AXR */ goto unimplemented;
12650 case 0x37: /* SXR */ goto unimplemented;
12651 case 0x38: s390_format_RR_FF(s390_irgen_LER, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12652 goto ok;
12653 case 0x39: /* CER */ goto unimplemented;
12654 case 0x3a: /* AER */ goto unimplemented;
12655 case 0x3b: /* SER */ goto unimplemented;
12656 case 0x3c: /* MDER */ goto unimplemented;
12657 case 0x3d: /* DER */ goto unimplemented;
12658 case 0x3e: /* AUR */ goto unimplemented;
12659 case 0x3f: /* SUR */ goto unimplemented;
12660 }
12661
12662 return S390_DECODE_UNKNOWN_INSN;
12663
12664ok:
12665 return S390_DECODE_OK;
12666
12667unimplemented:
12668 return S390_DECODE_UNIMPLEMENTED_INSN;
12669}
12670
12671static s390_decode_t
12672s390_decode_4byte_and_irgen(UChar *bytes)
12673{
12674 typedef union {
12675 struct {
12676 unsigned int op1 : 8;
12677 unsigned int r1 : 4;
12678 unsigned int op2 : 4;
12679 unsigned int i2 : 16;
12680 } RI;
12681 struct {
12682 unsigned int op : 16;
12683 unsigned int : 8;
12684 unsigned int r1 : 4;
12685 unsigned int r2 : 4;
12686 } RRE;
12687 struct {
12688 unsigned int op : 16;
12689 unsigned int r1 : 4;
12690 unsigned int : 4;
12691 unsigned int r3 : 4;
12692 unsigned int r2 : 4;
12693 } RRF;
12694 struct {
12695 unsigned int op : 16;
florian1c8f7ff2012-09-01 00:12:11 +000012696 unsigned int m3 : 4;
sewardj2019a972011-03-07 16:04:07 +000012697 unsigned int m4 : 4;
12698 unsigned int r1 : 4;
12699 unsigned int r2 : 4;
12700 } RRF2;
12701 struct {
12702 unsigned int op : 16;
12703 unsigned int r3 : 4;
12704 unsigned int : 4;
12705 unsigned int r1 : 4;
12706 unsigned int r2 : 4;
12707 } RRF3;
12708 struct {
12709 unsigned int op : 16;
12710 unsigned int r3 : 4;
12711 unsigned int : 4;
12712 unsigned int r1 : 4;
12713 unsigned int r2 : 4;
12714 } RRR;
12715 struct {
12716 unsigned int op : 16;
12717 unsigned int r3 : 4;
florian12390202012-11-10 22:34:14 +000012718 unsigned int m4 : 4;
sewardj2019a972011-03-07 16:04:07 +000012719 unsigned int r1 : 4;
12720 unsigned int r2 : 4;
12721 } RRF4;
12722 struct {
12723 unsigned int op : 8;
12724 unsigned int r1 : 4;
12725 unsigned int r3 : 4;
12726 unsigned int b2 : 4;
12727 unsigned int d2 : 12;
12728 } RS;
12729 struct {
12730 unsigned int op : 8;
12731 unsigned int r1 : 4;
12732 unsigned int r3 : 4;
12733 unsigned int i2 : 16;
12734 } RSI;
12735 struct {
12736 unsigned int op : 8;
12737 unsigned int r1 : 4;
12738 unsigned int x2 : 4;
12739 unsigned int b2 : 4;
12740 unsigned int d2 : 12;
12741 } RX;
12742 struct {
12743 unsigned int op : 16;
12744 unsigned int b2 : 4;
12745 unsigned int d2 : 12;
12746 } S;
12747 struct {
12748 unsigned int op : 8;
12749 unsigned int i2 : 8;
12750 unsigned int b1 : 4;
12751 unsigned int d1 : 12;
12752 } SI;
12753 } formats;
12754 union {
12755 formats fmt;
12756 UInt value;
12757 } ovl;
12758
12759 vassert(sizeof(formats) == 4);
12760
12761 ((char *)(&ovl.value))[0] = bytes[0];
12762 ((char *)(&ovl.value))[1] = bytes[1];
12763 ((char *)(&ovl.value))[2] = bytes[2];
12764 ((char *)(&ovl.value))[3] = bytes[3];
12765
12766 switch ((ovl.value & 0xff0f0000) >> 16) {
12767 case 0xa500: s390_format_RI_RU(s390_irgen_IIHH, ovl.fmt.RI.r1,
12768 ovl.fmt.RI.i2); goto ok;
12769 case 0xa501: s390_format_RI_RU(s390_irgen_IIHL, ovl.fmt.RI.r1,
12770 ovl.fmt.RI.i2); goto ok;
12771 case 0xa502: s390_format_RI_RU(s390_irgen_IILH, ovl.fmt.RI.r1,
12772 ovl.fmt.RI.i2); goto ok;
12773 case 0xa503: s390_format_RI_RU(s390_irgen_IILL, ovl.fmt.RI.r1,
12774 ovl.fmt.RI.i2); goto ok;
12775 case 0xa504: s390_format_RI_RU(s390_irgen_NIHH, ovl.fmt.RI.r1,
12776 ovl.fmt.RI.i2); goto ok;
12777 case 0xa505: s390_format_RI_RU(s390_irgen_NIHL, ovl.fmt.RI.r1,
12778 ovl.fmt.RI.i2); goto ok;
12779 case 0xa506: s390_format_RI_RU(s390_irgen_NILH, ovl.fmt.RI.r1,
12780 ovl.fmt.RI.i2); goto ok;
12781 case 0xa507: s390_format_RI_RU(s390_irgen_NILL, ovl.fmt.RI.r1,
12782 ovl.fmt.RI.i2); goto ok;
12783 case 0xa508: s390_format_RI_RU(s390_irgen_OIHH, ovl.fmt.RI.r1,
12784 ovl.fmt.RI.i2); goto ok;
12785 case 0xa509: s390_format_RI_RU(s390_irgen_OIHL, ovl.fmt.RI.r1,
12786 ovl.fmt.RI.i2); goto ok;
12787 case 0xa50a: s390_format_RI_RU(s390_irgen_OILH, ovl.fmt.RI.r1,
12788 ovl.fmt.RI.i2); goto ok;
12789 case 0xa50b: s390_format_RI_RU(s390_irgen_OILL, ovl.fmt.RI.r1,
12790 ovl.fmt.RI.i2); goto ok;
12791 case 0xa50c: s390_format_RI_RU(s390_irgen_LLIHH, ovl.fmt.RI.r1,
12792 ovl.fmt.RI.i2); goto ok;
12793 case 0xa50d: s390_format_RI_RU(s390_irgen_LLIHL, ovl.fmt.RI.r1,
12794 ovl.fmt.RI.i2); goto ok;
12795 case 0xa50e: s390_format_RI_RU(s390_irgen_LLILH, ovl.fmt.RI.r1,
12796 ovl.fmt.RI.i2); goto ok;
12797 case 0xa50f: s390_format_RI_RU(s390_irgen_LLILL, ovl.fmt.RI.r1,
12798 ovl.fmt.RI.i2); goto ok;
12799 case 0xa700: s390_format_RI_RU(s390_irgen_TMLH, ovl.fmt.RI.r1,
12800 ovl.fmt.RI.i2); goto ok;
12801 case 0xa701: s390_format_RI_RU(s390_irgen_TMLL, ovl.fmt.RI.r1,
12802 ovl.fmt.RI.i2); goto ok;
12803 case 0xa702: s390_format_RI_RU(s390_irgen_TMHH, ovl.fmt.RI.r1,
12804 ovl.fmt.RI.i2); goto ok;
12805 case 0xa703: s390_format_RI_RU(s390_irgen_TMHL, ovl.fmt.RI.r1,
12806 ovl.fmt.RI.i2); goto ok;
12807 case 0xa704: s390_format_RI(s390_irgen_BRC, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
12808 goto ok;
12809 case 0xa705: s390_format_RI_RP(s390_irgen_BRAS, ovl.fmt.RI.r1,
12810 ovl.fmt.RI.i2); goto ok;
12811 case 0xa706: s390_format_RI_RP(s390_irgen_BRCT, ovl.fmt.RI.r1,
12812 ovl.fmt.RI.i2); goto ok;
12813 case 0xa707: s390_format_RI_RP(s390_irgen_BRCTG, ovl.fmt.RI.r1,
12814 ovl.fmt.RI.i2); goto ok;
12815 case 0xa708: s390_format_RI_RI(s390_irgen_LHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
12816 goto ok;
12817 case 0xa709: s390_format_RI_RI(s390_irgen_LGHI, ovl.fmt.RI.r1,
12818 ovl.fmt.RI.i2); goto ok;
12819 case 0xa70a: s390_format_RI_RI(s390_irgen_AHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
12820 goto ok;
12821 case 0xa70b: s390_format_RI_RI(s390_irgen_AGHI, ovl.fmt.RI.r1,
12822 ovl.fmt.RI.i2); goto ok;
12823 case 0xa70c: s390_format_RI_RI(s390_irgen_MHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
12824 goto ok;
12825 case 0xa70d: s390_format_RI_RI(s390_irgen_MGHI, ovl.fmt.RI.r1,
12826 ovl.fmt.RI.i2); goto ok;
12827 case 0xa70e: s390_format_RI_RI(s390_irgen_CHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
12828 goto ok;
12829 case 0xa70f: s390_format_RI_RI(s390_irgen_CGHI, ovl.fmt.RI.r1,
12830 ovl.fmt.RI.i2); goto ok;
12831 }
12832
12833 switch ((ovl.value & 0xffff0000) >> 16) {
12834 case 0x8000: /* SSM */ goto unimplemented;
12835 case 0x8200: /* LPSW */ goto unimplemented;
florian7700fc92012-01-16 17:25:55 +000012836 case 0x9300: /* TS */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000012837 case 0xb202: /* STIDP */ goto unimplemented;
12838 case 0xb204: /* SCK */ goto unimplemented;
florian7700fc92012-01-16 17:25:55 +000012839 case 0xb205: s390_format_S_RD(s390_irgen_STCK, ovl.fmt.S.b2, ovl.fmt.S.d2);
12840 goto ok;
sewardj2019a972011-03-07 16:04:07 +000012841 case 0xb206: /* SCKC */ goto unimplemented;
12842 case 0xb207: /* STCKC */ goto unimplemented;
12843 case 0xb208: /* SPT */ goto unimplemented;
12844 case 0xb209: /* STPT */ goto unimplemented;
12845 case 0xb20a: /* SPKA */ goto unimplemented;
12846 case 0xb20b: /* IPK */ goto unimplemented;
12847 case 0xb20d: /* PTLB */ goto unimplemented;
12848 case 0xb210: /* SPX */ goto unimplemented;
12849 case 0xb211: /* STPX */ goto unimplemented;
12850 case 0xb212: /* STAP */ goto unimplemented;
12851 case 0xb214: /* SIE */ goto unimplemented;
12852 case 0xb218: /* PC */ goto unimplemented;
12853 case 0xb219: /* SAC */ goto unimplemented;
12854 case 0xb21a: /* CFC */ goto unimplemented;
12855 case 0xb221: /* IPTE */ goto unimplemented;
12856 case 0xb222: s390_format_RRE_R0(s390_irgen_IPM, ovl.fmt.RRE.r1); goto ok;
12857 case 0xb223: /* IVSK */ goto unimplemented;
12858 case 0xb224: /* IAC */ goto unimplemented;
12859 case 0xb225: /* SSAR */ goto unimplemented;
12860 case 0xb226: /* EPAR */ goto unimplemented;
12861 case 0xb227: /* ESAR */ goto unimplemented;
12862 case 0xb228: /* PT */ goto unimplemented;
12863 case 0xb229: /* ISKE */ goto unimplemented;
12864 case 0xb22a: /* RRBE */ goto unimplemented;
12865 case 0xb22b: /* SSKE */ goto unimplemented;
12866 case 0xb22c: /* TB */ goto unimplemented;
12867 case 0xb22d: /* DXR */ goto unimplemented;
12868 case 0xb22e: /* PGIN */ goto unimplemented;
12869 case 0xb22f: /* PGOUT */ goto unimplemented;
12870 case 0xb230: /* CSCH */ goto unimplemented;
12871 case 0xb231: /* HSCH */ goto unimplemented;
12872 case 0xb232: /* MSCH */ goto unimplemented;
12873 case 0xb233: /* SSCH */ goto unimplemented;
12874 case 0xb234: /* STSCH */ goto unimplemented;
12875 case 0xb235: /* TSCH */ goto unimplemented;
12876 case 0xb236: /* TPI */ goto unimplemented;
12877 case 0xb237: /* SAL */ goto unimplemented;
12878 case 0xb238: /* RSCH */ goto unimplemented;
12879 case 0xb239: /* STCRW */ goto unimplemented;
12880 case 0xb23a: /* STCPS */ goto unimplemented;
12881 case 0xb23b: /* RCHP */ goto unimplemented;
12882 case 0xb23c: /* SCHM */ goto unimplemented;
12883 case 0xb240: /* BAKR */ goto unimplemented;
floriana4384a32011-08-11 16:58:45 +000012884 case 0xb241: s390_format_RRE(s390_irgen_CKSM, ovl.fmt.RRE.r1,
12885 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000012886 case 0xb244: /* SQDR */ goto unimplemented;
12887 case 0xb245: /* SQER */ goto unimplemented;
12888 case 0xb246: /* STURA */ goto unimplemented;
12889 case 0xb247: /* MSTA */ goto unimplemented;
12890 case 0xb248: /* PALB */ goto unimplemented;
12891 case 0xb249: /* EREG */ goto unimplemented;
12892 case 0xb24a: /* ESTA */ goto unimplemented;
12893 case 0xb24b: /* LURA */ goto unimplemented;
12894 case 0xb24c: /* TAR */ goto unimplemented;
12895 case 0xb24d: s390_format_RRE(s390_irgen_CPYA, ovl.fmt.RRE.r1,
12896 ovl.fmt.RRE.r2); goto ok;
12897 case 0xb24e: s390_format_RRE(s390_irgen_SAR, ovl.fmt.RRE.r1, ovl.fmt.RRE.r2);
12898 goto ok;
12899 case 0xb24f: s390_format_RRE(s390_irgen_EAR, ovl.fmt.RRE.r1, ovl.fmt.RRE.r2);
12900 goto ok;
12901 case 0xb250: /* CSP */ goto unimplemented;
12902 case 0xb252: s390_format_RRE_RR(s390_irgen_MSR, ovl.fmt.RRE.r1,
12903 ovl.fmt.RRE.r2); goto ok;
12904 case 0xb254: /* MVPG */ goto unimplemented;
12905 case 0xb255: s390_format_RRE_RR(s390_irgen_MVST, ovl.fmt.RRE.r1,
12906 ovl.fmt.RRE.r2); goto ok;
12907 case 0xb257: /* CUSE */ goto unimplemented;
12908 case 0xb258: /* BSG */ goto unimplemented;
12909 case 0xb25a: /* BSA */ goto unimplemented;
12910 case 0xb25d: s390_format_RRE_RR(s390_irgen_CLST, ovl.fmt.RRE.r1,
12911 ovl.fmt.RRE.r2); goto ok;
12912 case 0xb25e: s390_format_RRE_RR(s390_irgen_SRST, ovl.fmt.RRE.r1,
12913 ovl.fmt.RRE.r2); goto ok;
12914 case 0xb263: /* CMPSC */ goto unimplemented;
12915 case 0xb274: /* SIGA */ goto unimplemented;
12916 case 0xb276: /* XSCH */ goto unimplemented;
12917 case 0xb277: /* RP */ goto unimplemented;
sewardj1e5fea62011-05-17 16:18:36 +000012918 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 +000012919 case 0xb279: /* SACF */ goto unimplemented;
sewardj1e5fea62011-05-17 16:18:36 +000012920 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 +000012921 case 0xb27d: /* STSI */ goto unimplemented;
12922 case 0xb299: s390_format_S_RD(s390_irgen_SRNM, ovl.fmt.S.b2, ovl.fmt.S.d2);
12923 goto ok;
12924 case 0xb29c: s390_format_S_RD(s390_irgen_STFPC, ovl.fmt.S.b2, ovl.fmt.S.d2);
12925 goto ok;
12926 case 0xb29d: s390_format_S_RD(s390_irgen_LFPC, ovl.fmt.S.b2, ovl.fmt.S.d2);
12927 goto ok;
florian730448f2012-02-04 17:07:07 +000012928 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 +000012929 case 0xb2a6: s390_format_RRF_M0RERE(s390_irgen_CU21, ovl.fmt.RRF3.r3,
12930 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
12931 goto ok;
florian6d9b9b22012-08-03 18:35:39 +000012932 case 0xb2a7: s390_format_RRF_M0RERE(s390_irgen_CU12, ovl.fmt.RRF3.r3,
12933 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
12934 goto ok;
florian933065d2011-07-11 01:48:02 +000012935 case 0xb2b0: s390_format_S_RD(s390_irgen_STFLE, ovl.fmt.S.b2, ovl.fmt.S.d2);
12936 goto ok;
sewardj2019a972011-03-07 16:04:07 +000012937 case 0xb2b1: /* STFL */ goto unimplemented;
12938 case 0xb2b2: /* LPSWE */ goto unimplemented;
florianf0fa1be2012-09-18 20:24:38 +000012939 case 0xb2b8: s390_irgen_srnmb_wrapper(ovl.fmt.S.b2, ovl.fmt.S.d2);
12940 goto ok;
sewardj2019a972011-03-07 16:04:07 +000012941 case 0xb2b9: /* SRNMT */ goto unimplemented;
12942 case 0xb2bd: /* LFAS */ goto unimplemented;
florian2289cd42012-12-05 04:23:42 +000012943 case 0xb2e8: /* PPA */ goto unimplemented;
12944 case 0xb2ec: /* ETND */ goto unimplemented;
12945 case 0xb2f8: /* TEND */ goto unimplemented;
12946 case 0xb2fa: /* NIAI */ goto unimplemented;
12947 case 0xb2fc: /* TABORT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000012948 case 0xb2ff: /* TRAP4 */ goto unimplemented;
12949 case 0xb300: s390_format_RRE_FF(s390_irgen_LPEBR, ovl.fmt.RRE.r1,
12950 ovl.fmt.RRE.r2); goto ok;
12951 case 0xb301: s390_format_RRE_FF(s390_irgen_LNEBR, ovl.fmt.RRE.r1,
12952 ovl.fmt.RRE.r2); goto ok;
12953 case 0xb302: s390_format_RRE_FF(s390_irgen_LTEBR, ovl.fmt.RRE.r1,
12954 ovl.fmt.RRE.r2); goto ok;
12955 case 0xb303: s390_format_RRE_FF(s390_irgen_LCEBR, ovl.fmt.RRE.r1,
12956 ovl.fmt.RRE.r2); goto ok;
12957 case 0xb304: s390_format_RRE_FF(s390_irgen_LDEBR, ovl.fmt.RRE.r1,
12958 ovl.fmt.RRE.r2); goto ok;
12959 case 0xb305: s390_format_RRE_FF(s390_irgen_LXDBR, ovl.fmt.RRE.r1,
12960 ovl.fmt.RRE.r2); goto ok;
12961 case 0xb306: s390_format_RRE_FF(s390_irgen_LXEBR, ovl.fmt.RRE.r1,
12962 ovl.fmt.RRE.r2); goto ok;
12963 case 0xb307: /* MXDBR */ goto unimplemented;
12964 case 0xb308: /* KEBR */ goto unimplemented;
12965 case 0xb309: s390_format_RRE_FF(s390_irgen_CEBR, ovl.fmt.RRE.r1,
12966 ovl.fmt.RRE.r2); goto ok;
12967 case 0xb30a: s390_format_RRE_FF(s390_irgen_AEBR, ovl.fmt.RRE.r1,
12968 ovl.fmt.RRE.r2); goto ok;
12969 case 0xb30b: s390_format_RRE_FF(s390_irgen_SEBR, ovl.fmt.RRE.r1,
12970 ovl.fmt.RRE.r2); goto ok;
12971 case 0xb30c: /* MDEBR */ goto unimplemented;
12972 case 0xb30d: s390_format_RRE_FF(s390_irgen_DEBR, ovl.fmt.RRE.r1,
12973 ovl.fmt.RRE.r2); goto ok;
12974 case 0xb30e: s390_format_RRF_F0FF(s390_irgen_MAEBR, ovl.fmt.RRF.r1,
12975 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
12976 case 0xb30f: s390_format_RRF_F0FF(s390_irgen_MSEBR, ovl.fmt.RRF.r1,
12977 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
12978 case 0xb310: s390_format_RRE_FF(s390_irgen_LPDBR, ovl.fmt.RRE.r1,
12979 ovl.fmt.RRE.r2); goto ok;
12980 case 0xb311: s390_format_RRE_FF(s390_irgen_LNDBR, ovl.fmt.RRE.r1,
12981 ovl.fmt.RRE.r2); goto ok;
12982 case 0xb312: s390_format_RRE_FF(s390_irgen_LTDBR, ovl.fmt.RRE.r1,
12983 ovl.fmt.RRE.r2); goto ok;
12984 case 0xb313: s390_format_RRE_FF(s390_irgen_LCDBR, ovl.fmt.RRE.r1,
12985 ovl.fmt.RRE.r2); goto ok;
12986 case 0xb314: s390_format_RRE_FF(s390_irgen_SQEBR, ovl.fmt.RRE.r1,
12987 ovl.fmt.RRE.r2); goto ok;
12988 case 0xb315: s390_format_RRE_FF(s390_irgen_SQDBR, ovl.fmt.RRE.r1,
12989 ovl.fmt.RRE.r2); goto ok;
12990 case 0xb316: s390_format_RRE_FF(s390_irgen_SQXBR, ovl.fmt.RRE.r1,
12991 ovl.fmt.RRE.r2); goto ok;
12992 case 0xb317: s390_format_RRE_FF(s390_irgen_MEEBR, ovl.fmt.RRE.r1,
12993 ovl.fmt.RRE.r2); goto ok;
12994 case 0xb318: /* KDBR */ goto unimplemented;
12995 case 0xb319: s390_format_RRE_FF(s390_irgen_CDBR, ovl.fmt.RRE.r1,
12996 ovl.fmt.RRE.r2); goto ok;
12997 case 0xb31a: s390_format_RRE_FF(s390_irgen_ADBR, ovl.fmt.RRE.r1,
12998 ovl.fmt.RRE.r2); goto ok;
12999 case 0xb31b: s390_format_RRE_FF(s390_irgen_SDBR, ovl.fmt.RRE.r1,
13000 ovl.fmt.RRE.r2); goto ok;
13001 case 0xb31c: s390_format_RRE_FF(s390_irgen_MDBR, ovl.fmt.RRE.r1,
13002 ovl.fmt.RRE.r2); goto ok;
13003 case 0xb31d: s390_format_RRE_FF(s390_irgen_DDBR, ovl.fmt.RRE.r1,
13004 ovl.fmt.RRE.r2); goto ok;
13005 case 0xb31e: s390_format_RRF_F0FF(s390_irgen_MADBR, ovl.fmt.RRF.r1,
13006 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
13007 case 0xb31f: s390_format_RRF_F0FF(s390_irgen_MSDBR, ovl.fmt.RRF.r1,
13008 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
13009 case 0xb324: /* LDER */ goto unimplemented;
13010 case 0xb325: /* LXDR */ goto unimplemented;
13011 case 0xb326: /* LXER */ goto unimplemented;
13012 case 0xb32e: /* MAER */ goto unimplemented;
13013 case 0xb32f: /* MSER */ goto unimplemented;
13014 case 0xb336: /* SQXR */ goto unimplemented;
13015 case 0xb337: /* MEER */ goto unimplemented;
13016 case 0xb338: /* MAYLR */ goto unimplemented;
13017 case 0xb339: /* MYLR */ goto unimplemented;
13018 case 0xb33a: /* MAYR */ goto unimplemented;
13019 case 0xb33b: /* MYR */ goto unimplemented;
13020 case 0xb33c: /* MAYHR */ goto unimplemented;
13021 case 0xb33d: /* MYHR */ goto unimplemented;
13022 case 0xb33e: /* MADR */ goto unimplemented;
13023 case 0xb33f: /* MSDR */ goto unimplemented;
13024 case 0xb340: s390_format_RRE_FF(s390_irgen_LPXBR, ovl.fmt.RRE.r1,
13025 ovl.fmt.RRE.r2); goto ok;
13026 case 0xb341: s390_format_RRE_FF(s390_irgen_LNXBR, ovl.fmt.RRE.r1,
13027 ovl.fmt.RRE.r2); goto ok;
13028 case 0xb342: s390_format_RRE_FF(s390_irgen_LTXBR, ovl.fmt.RRE.r1,
13029 ovl.fmt.RRE.r2); goto ok;
13030 case 0xb343: s390_format_RRE_FF(s390_irgen_LCXBR, ovl.fmt.RRE.r1,
13031 ovl.fmt.RRE.r2); goto ok;
florian4b8efad2012-09-02 18:07:08 +000013032 case 0xb344: s390_format_RRF_UUFF(s390_irgen_LEDBR, ovl.fmt.RRF2.m3,
13033 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13034 ovl.fmt.RRF2.r2); goto ok;
13035 case 0xb345: s390_format_RRF_UUFF(s390_irgen_LDXBR, ovl.fmt.RRF2.m3,
13036 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13037 ovl.fmt.RRF2.r2); goto ok;
13038 case 0xb346: s390_format_RRF_UUFF(s390_irgen_LEXBR, ovl.fmt.RRF2.m3,
13039 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13040 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013041 case 0xb347: /* FIXBR */ goto unimplemented;
13042 case 0xb348: /* KXBR */ goto unimplemented;
13043 case 0xb349: s390_format_RRE_FF(s390_irgen_CXBR, ovl.fmt.RRE.r1,
13044 ovl.fmt.RRE.r2); goto ok;
13045 case 0xb34a: s390_format_RRE_FF(s390_irgen_AXBR, ovl.fmt.RRE.r1,
13046 ovl.fmt.RRE.r2); goto ok;
13047 case 0xb34b: s390_format_RRE_FF(s390_irgen_SXBR, ovl.fmt.RRE.r1,
13048 ovl.fmt.RRE.r2); goto ok;
13049 case 0xb34c: s390_format_RRE_FF(s390_irgen_MXBR, ovl.fmt.RRE.r1,
13050 ovl.fmt.RRE.r2); goto ok;
13051 case 0xb34d: s390_format_RRE_FF(s390_irgen_DXBR, ovl.fmt.RRE.r1,
13052 ovl.fmt.RRE.r2); goto ok;
13053 case 0xb350: /* TBEDR */ goto unimplemented;
13054 case 0xb351: /* TBDR */ goto unimplemented;
13055 case 0xb353: /* DIEBR */ goto unimplemented;
13056 case 0xb357: /* FIEBR */ goto unimplemented;
13057 case 0xb358: /* THDER */ goto unimplemented;
13058 case 0xb359: /* THDR */ goto unimplemented;
13059 case 0xb35b: /* DIDBR */ goto unimplemented;
13060 case 0xb35f: /* FIDBR */ goto unimplemented;
13061 case 0xb360: /* LPXR */ goto unimplemented;
13062 case 0xb361: /* LNXR */ goto unimplemented;
13063 case 0xb362: /* LTXR */ goto unimplemented;
13064 case 0xb363: /* LCXR */ goto unimplemented;
13065 case 0xb365: s390_format_RRE_FF(s390_irgen_LXR, ovl.fmt.RRE.r1,
13066 ovl.fmt.RRE.r2); goto ok;
13067 case 0xb366: /* LEXR */ goto unimplemented;
13068 case 0xb367: /* FIXR */ goto unimplemented;
13069 case 0xb369: /* CXR */ goto unimplemented;
13070 case 0xb370: s390_format_RRE_FF(s390_irgen_LPDFR, ovl.fmt.RRE.r1,
13071 ovl.fmt.RRE.r2); goto ok;
13072 case 0xb371: s390_format_RRE_FF(s390_irgen_LNDFR, ovl.fmt.RRE.r1,
13073 ovl.fmt.RRE.r2); goto ok;
13074 case 0xb372: s390_format_RRF_F0FF2(s390_irgen_CPSDR, ovl.fmt.RRF3.r3,
13075 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
13076 goto ok;
13077 case 0xb373: s390_format_RRE_FF(s390_irgen_LCDFR, ovl.fmt.RRE.r1,
13078 ovl.fmt.RRE.r2); goto ok;
13079 case 0xb374: s390_format_RRE_F0(s390_irgen_LZER, ovl.fmt.RRE.r1); goto ok;
13080 case 0xb375: s390_format_RRE_F0(s390_irgen_LZDR, ovl.fmt.RRE.r1); goto ok;
13081 case 0xb376: s390_format_RRE_F0(s390_irgen_LZXR, ovl.fmt.RRE.r1); goto ok;
13082 case 0xb377: /* FIER */ goto unimplemented;
13083 case 0xb37f: /* FIDR */ goto unimplemented;
13084 case 0xb384: s390_format_RRE_R0(s390_irgen_SFPC, ovl.fmt.RRE.r1); goto ok;
13085 case 0xb385: /* SFASR */ goto unimplemented;
13086 case 0xb38c: s390_format_RRE_R0(s390_irgen_EFPC, ovl.fmt.RRE.r1); goto ok;
florian1c8f7ff2012-09-01 00:12:11 +000013087 case 0xb390: s390_format_RRF_UUFR(s390_irgen_CELFBR, ovl.fmt.RRF2.m3,
13088 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13089 ovl.fmt.RRF2.r2); goto ok;
13090 case 0xb391: s390_format_RRF_UUFR(s390_irgen_CDLFBR, ovl.fmt.RRF2.m3,
13091 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13092 ovl.fmt.RRF2.r2); goto ok;
13093 case 0xb392: s390_format_RRF_UUFR(s390_irgen_CXLFBR, ovl.fmt.RRF2.m3,
13094 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13095 ovl.fmt.RRF2.r2); goto ok;
florian4b8efad2012-09-02 18:07:08 +000013096 case 0xb394: s390_format_RRF_UUFR(s390_irgen_CEFBR, ovl.fmt.RRF2.m3,
13097 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13098 ovl.fmt.RRF2.r2); goto ok;
13099 case 0xb395: s390_format_RRF_UUFR(s390_irgen_CDFBR, ovl.fmt.RRF2.m3,
13100 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13101 ovl.fmt.RRF2.r2); goto ok;
13102 case 0xb396: s390_format_RRF_UUFR(s390_irgen_CXFBR, ovl.fmt.RRF2.m3,
13103 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13104 ovl.fmt.RRF2.r2); goto ok;
13105 case 0xb398: s390_format_RRF_UURF(s390_irgen_CFEBR, ovl.fmt.RRF2.m3,
13106 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13107 ovl.fmt.RRF2.r2); goto ok;
13108 case 0xb399: s390_format_RRF_UURF(s390_irgen_CFDBR, ovl.fmt.RRF2.m3,
13109 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13110 ovl.fmt.RRF2.r2); goto ok;
13111 case 0xb39a: s390_format_RRF_UURF(s390_irgen_CFXBR, ovl.fmt.RRF2.m3,
13112 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13113 ovl.fmt.RRF2.r2); goto ok;
florian1c8f7ff2012-09-01 00:12:11 +000013114 case 0xb39c: s390_format_RRF_UURF(s390_irgen_CLFEBR, ovl.fmt.RRF2.m3,
13115 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13116 ovl.fmt.RRF2.r2); goto ok;
13117 case 0xb39d: s390_format_RRF_UURF(s390_irgen_CLFDBR, ovl.fmt.RRF2.m3,
13118 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13119 ovl.fmt.RRF2.r2); goto ok;
13120 case 0xb39e: s390_format_RRF_UURF(s390_irgen_CLFXBR, ovl.fmt.RRF2.m3,
13121 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13122 ovl.fmt.RRF2.r2); goto ok;
13123 case 0xb3a0: s390_format_RRF_UUFR(s390_irgen_CELGBR, ovl.fmt.RRF2.m3,
13124 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13125 ovl.fmt.RRF2.r2); goto ok;
13126 case 0xb3a1: s390_format_RRF_UUFR(s390_irgen_CDLGBR, ovl.fmt.RRF2.m3,
13127 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13128 ovl.fmt.RRF2.r2); goto ok;
13129 case 0xb3a2: s390_format_RRF_UUFR(s390_irgen_CXLGBR, ovl.fmt.RRF2.m3,
13130 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13131 ovl.fmt.RRF2.r2); goto ok;
florian4b8efad2012-09-02 18:07:08 +000013132 case 0xb3a4: s390_format_RRF_UUFR(s390_irgen_CEGBR, ovl.fmt.RRF2.m3,
13133 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13134 ovl.fmt.RRF2.r2); goto ok;
13135 case 0xb3a5: s390_format_RRF_UUFR(s390_irgen_CDGBR, ovl.fmt.RRF2.m3,
13136 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13137 ovl.fmt.RRF2.r2); goto ok;
13138 case 0xb3a6: s390_format_RRF_UUFR(s390_irgen_CXGBR, ovl.fmt.RRF2.m3,
13139 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13140 ovl.fmt.RRF2.r2); goto ok;
13141 case 0xb3a8: s390_format_RRF_UURF(s390_irgen_CGEBR, ovl.fmt.RRF2.m3,
13142 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13143 ovl.fmt.RRF2.r2); goto ok;
13144 case 0xb3a9: s390_format_RRF_UURF(s390_irgen_CGDBR, ovl.fmt.RRF2.m3,
13145 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13146 ovl.fmt.RRF2.r2); goto ok;
13147 case 0xb3aa: s390_format_RRF_UURF(s390_irgen_CGXBR, ovl.fmt.RRF2.m3,
13148 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13149 ovl.fmt.RRF2.r2); goto ok;
florian1c8f7ff2012-09-01 00:12:11 +000013150 case 0xb3ac: s390_format_RRF_UURF(s390_irgen_CLGEBR, ovl.fmt.RRF2.m3,
13151 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13152 ovl.fmt.RRF2.r2); goto ok;
13153 case 0xb3ad: s390_format_RRF_UURF(s390_irgen_CLGDBR, ovl.fmt.RRF2.m3,
13154 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13155 ovl.fmt.RRF2.r2); goto ok;
13156 case 0xb3ae: s390_format_RRF_UURF(s390_irgen_CLGXBR, ovl.fmt.RRF2.m3,
13157 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13158 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013159 case 0xb3b4: /* CEFR */ goto unimplemented;
13160 case 0xb3b5: /* CDFR */ goto unimplemented;
13161 case 0xb3b6: /* CXFR */ goto unimplemented;
13162 case 0xb3b8: /* CFER */ goto unimplemented;
13163 case 0xb3b9: /* CFDR */ goto unimplemented;
13164 case 0xb3ba: /* CFXR */ goto unimplemented;
13165 case 0xb3c1: s390_format_RRE_FR(s390_irgen_LDGR, ovl.fmt.RRE.r1,
13166 ovl.fmt.RRE.r2); goto ok;
13167 case 0xb3c4: /* CEGR */ goto unimplemented;
13168 case 0xb3c5: /* CDGR */ goto unimplemented;
13169 case 0xb3c6: /* CXGR */ goto unimplemented;
13170 case 0xb3c8: /* CGER */ goto unimplemented;
13171 case 0xb3c9: /* CGDR */ goto unimplemented;
13172 case 0xb3ca: /* CGXR */ goto unimplemented;
13173 case 0xb3cd: s390_format_RRE_RF(s390_irgen_LGDR, ovl.fmt.RRE.r1,
13174 ovl.fmt.RRE.r2); goto ok;
florian12390202012-11-10 22:34:14 +000013175 case 0xb3d0: s390_format_RRF_FUFF2(s390_irgen_MDTRA, ovl.fmt.RRF4.r3,
13176 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
13177 ovl.fmt.RRF4.r2); goto ok;
13178 case 0xb3d1: s390_format_RRF_FUFF2(s390_irgen_DDTRA, ovl.fmt.RRF4.r3,
13179 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
13180 ovl.fmt.RRF4.r2); goto ok;
13181 case 0xb3d2: s390_format_RRF_FUFF2(s390_irgen_ADTRA, ovl.fmt.RRF4.r3,
13182 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
13183 ovl.fmt.RRF4.r2); goto ok;
13184 case 0xb3d3: s390_format_RRF_FUFF2(s390_irgen_SDTRA, ovl.fmt.RRF4.r3,
13185 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
13186 ovl.fmt.RRF4.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013187 case 0xb3d4: /* LDETR */ goto unimplemented;
13188 case 0xb3d5: /* LEDTR */ goto unimplemented;
florian12390202012-11-10 22:34:14 +000013189 case 0xb3d6: s390_format_RRE_FF(s390_irgen_LTDTR, ovl.fmt.RRE.r1,
13190 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013191 case 0xb3d7: /* FIDTR */ goto unimplemented;
13192 case 0xb3d8: /* MXTR */ goto unimplemented;
13193 case 0xb3d9: /* DXTR */ goto unimplemented;
13194 case 0xb3da: /* AXTR */ goto unimplemented;
13195 case 0xb3db: /* SXTR */ goto unimplemented;
13196 case 0xb3dc: /* LXDTR */ goto unimplemented;
13197 case 0xb3dd: /* LDXTR */ goto unimplemented;
13198 case 0xb3de: /* LTXTR */ goto unimplemented;
13199 case 0xb3df: /* FIXTR */ goto unimplemented;
13200 case 0xb3e0: /* KDTR */ goto unimplemented;
13201 case 0xb3e1: /* CGDTR */ goto unimplemented;
13202 case 0xb3e2: /* CUDTR */ goto unimplemented;
13203 case 0xb3e3: /* CSDTR */ goto unimplemented;
13204 case 0xb3e4: /* CDTR */ goto unimplemented;
13205 case 0xb3e5: /* EEDTR */ goto unimplemented;
13206 case 0xb3e7: /* ESDTR */ goto unimplemented;
13207 case 0xb3e8: /* KXTR */ goto unimplemented;
13208 case 0xb3e9: /* CGXTR */ goto unimplemented;
13209 case 0xb3ea: /* CUXTR */ goto unimplemented;
13210 case 0xb3eb: /* CSXTR */ goto unimplemented;
13211 case 0xb3ec: /* CXTR */ goto unimplemented;
13212 case 0xb3ed: /* EEXTR */ goto unimplemented;
13213 case 0xb3ef: /* ESXTR */ goto unimplemented;
13214 case 0xb3f1: /* CDGTR */ goto unimplemented;
13215 case 0xb3f2: /* CDUTR */ goto unimplemented;
13216 case 0xb3f3: /* CDSTR */ goto unimplemented;
13217 case 0xb3f4: /* CEDTR */ goto unimplemented;
13218 case 0xb3f5: /* QADTR */ goto unimplemented;
13219 case 0xb3f6: /* IEDTR */ goto unimplemented;
13220 case 0xb3f7: /* RRDTR */ goto unimplemented;
13221 case 0xb3f9: /* CXGTR */ goto unimplemented;
13222 case 0xb3fa: /* CXUTR */ goto unimplemented;
13223 case 0xb3fb: /* CXSTR */ goto unimplemented;
13224 case 0xb3fc: /* CEXTR */ goto unimplemented;
13225 case 0xb3fd: /* QAXTR */ goto unimplemented;
13226 case 0xb3fe: /* IEXTR */ goto unimplemented;
13227 case 0xb3ff: /* RRXTR */ goto unimplemented;
13228 case 0xb900: s390_format_RRE_RR(s390_irgen_LPGR, ovl.fmt.RRE.r1,
13229 ovl.fmt.RRE.r2); goto ok;
13230 case 0xb901: s390_format_RRE_RR(s390_irgen_LNGR, ovl.fmt.RRE.r1,
13231 ovl.fmt.RRE.r2); goto ok;
13232 case 0xb902: s390_format_RRE_RR(s390_irgen_LTGR, ovl.fmt.RRE.r1,
13233 ovl.fmt.RRE.r2); goto ok;
13234 case 0xb903: s390_format_RRE_RR(s390_irgen_LCGR, ovl.fmt.RRE.r1,
13235 ovl.fmt.RRE.r2); goto ok;
13236 case 0xb904: s390_format_RRE_RR(s390_irgen_LGR, ovl.fmt.RRE.r1,
13237 ovl.fmt.RRE.r2); goto ok;
13238 case 0xb905: /* LURAG */ goto unimplemented;
13239 case 0xb906: s390_format_RRE_RR(s390_irgen_LGBR, ovl.fmt.RRE.r1,
13240 ovl.fmt.RRE.r2); goto ok;
13241 case 0xb907: s390_format_RRE_RR(s390_irgen_LGHR, ovl.fmt.RRE.r1,
13242 ovl.fmt.RRE.r2); goto ok;
13243 case 0xb908: s390_format_RRE_RR(s390_irgen_AGR, ovl.fmt.RRE.r1,
13244 ovl.fmt.RRE.r2); goto ok;
13245 case 0xb909: s390_format_RRE_RR(s390_irgen_SGR, ovl.fmt.RRE.r1,
13246 ovl.fmt.RRE.r2); goto ok;
13247 case 0xb90a: s390_format_RRE_RR(s390_irgen_ALGR, ovl.fmt.RRE.r1,
13248 ovl.fmt.RRE.r2); goto ok;
13249 case 0xb90b: s390_format_RRE_RR(s390_irgen_SLGR, ovl.fmt.RRE.r1,
13250 ovl.fmt.RRE.r2); goto ok;
13251 case 0xb90c: s390_format_RRE_RR(s390_irgen_MSGR, ovl.fmt.RRE.r1,
13252 ovl.fmt.RRE.r2); goto ok;
13253 case 0xb90d: s390_format_RRE_RR(s390_irgen_DSGR, ovl.fmt.RRE.r1,
13254 ovl.fmt.RRE.r2); goto ok;
13255 case 0xb90e: /* EREGG */ goto unimplemented;
13256 case 0xb90f: s390_format_RRE_RR(s390_irgen_LRVGR, ovl.fmt.RRE.r1,
13257 ovl.fmt.RRE.r2); goto ok;
13258 case 0xb910: s390_format_RRE_RR(s390_irgen_LPGFR, ovl.fmt.RRE.r1,
13259 ovl.fmt.RRE.r2); goto ok;
13260 case 0xb911: s390_format_RRE_RR(s390_irgen_LNGFR, ovl.fmt.RRE.r1,
13261 ovl.fmt.RRE.r2); goto ok;
13262 case 0xb912: s390_format_RRE_RR(s390_irgen_LTGFR, ovl.fmt.RRE.r1,
13263 ovl.fmt.RRE.r2); goto ok;
13264 case 0xb913: s390_format_RRE_RR(s390_irgen_LCGFR, ovl.fmt.RRE.r1,
13265 ovl.fmt.RRE.r2); goto ok;
13266 case 0xb914: s390_format_RRE_RR(s390_irgen_LGFR, ovl.fmt.RRE.r1,
13267 ovl.fmt.RRE.r2); goto ok;
13268 case 0xb916: s390_format_RRE_RR(s390_irgen_LLGFR, ovl.fmt.RRE.r1,
13269 ovl.fmt.RRE.r2); goto ok;
13270 case 0xb917: s390_format_RRE_RR(s390_irgen_LLGTR, ovl.fmt.RRE.r1,
13271 ovl.fmt.RRE.r2); goto ok;
13272 case 0xb918: s390_format_RRE_RR(s390_irgen_AGFR, ovl.fmt.RRE.r1,
13273 ovl.fmt.RRE.r2); goto ok;
13274 case 0xb919: s390_format_RRE_RR(s390_irgen_SGFR, ovl.fmt.RRE.r1,
13275 ovl.fmt.RRE.r2); goto ok;
13276 case 0xb91a: s390_format_RRE_RR(s390_irgen_ALGFR, ovl.fmt.RRE.r1,
13277 ovl.fmt.RRE.r2); goto ok;
13278 case 0xb91b: s390_format_RRE_RR(s390_irgen_SLGFR, ovl.fmt.RRE.r1,
13279 ovl.fmt.RRE.r2); goto ok;
13280 case 0xb91c: s390_format_RRE_RR(s390_irgen_MSGFR, ovl.fmt.RRE.r1,
13281 ovl.fmt.RRE.r2); goto ok;
13282 case 0xb91d: s390_format_RRE_RR(s390_irgen_DSGFR, ovl.fmt.RRE.r1,
13283 ovl.fmt.RRE.r2); goto ok;
13284 case 0xb91e: /* KMAC */ goto unimplemented;
13285 case 0xb91f: s390_format_RRE_RR(s390_irgen_LRVR, ovl.fmt.RRE.r1,
13286 ovl.fmt.RRE.r2); goto ok;
13287 case 0xb920: s390_format_RRE_RR(s390_irgen_CGR, ovl.fmt.RRE.r1,
13288 ovl.fmt.RRE.r2); goto ok;
13289 case 0xb921: s390_format_RRE_RR(s390_irgen_CLGR, ovl.fmt.RRE.r1,
13290 ovl.fmt.RRE.r2); goto ok;
13291 case 0xb925: /* STURG */ goto unimplemented;
13292 case 0xb926: s390_format_RRE_RR(s390_irgen_LBR, ovl.fmt.RRE.r1,
13293 ovl.fmt.RRE.r2); goto ok;
13294 case 0xb927: s390_format_RRE_RR(s390_irgen_LHR, ovl.fmt.RRE.r1,
13295 ovl.fmt.RRE.r2); goto ok;
13296 case 0xb928: /* PCKMO */ goto unimplemented;
13297 case 0xb92b: /* KMO */ goto unimplemented;
13298 case 0xb92c: /* PCC */ goto unimplemented;
13299 case 0xb92d: /* KMCTR */ goto unimplemented;
13300 case 0xb92e: /* KM */ goto unimplemented;
13301 case 0xb92f: /* KMC */ goto unimplemented;
13302 case 0xb930: s390_format_RRE_RR(s390_irgen_CGFR, ovl.fmt.RRE.r1,
13303 ovl.fmt.RRE.r2); goto ok;
13304 case 0xb931: s390_format_RRE_RR(s390_irgen_CLGFR, ovl.fmt.RRE.r1,
13305 ovl.fmt.RRE.r2); goto ok;
13306 case 0xb93e: /* KIMD */ goto unimplemented;
13307 case 0xb93f: /* KLMD */ goto unimplemented;
13308 case 0xb941: /* CFDTR */ goto unimplemented;
13309 case 0xb942: /* CLGDTR */ goto unimplemented;
13310 case 0xb943: /* CLFDTR */ goto unimplemented;
13311 case 0xb946: s390_format_RRE_RR(s390_irgen_BCTGR, ovl.fmt.RRE.r1,
13312 ovl.fmt.RRE.r2); goto ok;
13313 case 0xb949: /* CFXTR */ goto unimplemented;
13314 case 0xb94a: /* CLGXTR */ goto unimplemented;
13315 case 0xb94b: /* CLFXTR */ goto unimplemented;
13316 case 0xb951: /* CDFTR */ goto unimplemented;
13317 case 0xb952: /* CDLGTR */ goto unimplemented;
13318 case 0xb953: /* CDLFTR */ goto unimplemented;
13319 case 0xb959: /* CXFTR */ goto unimplemented;
13320 case 0xb95a: /* CXLGTR */ goto unimplemented;
13321 case 0xb95b: /* CXLFTR */ goto unimplemented;
13322 case 0xb960: /* CGRT */ goto unimplemented;
13323 case 0xb961: /* CLGRT */ goto unimplemented;
13324 case 0xb972: /* CRT */ goto unimplemented;
13325 case 0xb973: /* CLRT */ goto unimplemented;
13326 case 0xb980: s390_format_RRE_RR(s390_irgen_NGR, ovl.fmt.RRE.r1,
13327 ovl.fmt.RRE.r2); goto ok;
13328 case 0xb981: s390_format_RRE_RR(s390_irgen_OGR, ovl.fmt.RRE.r1,
13329 ovl.fmt.RRE.r2); goto ok;
13330 case 0xb982: s390_format_RRE_RR(s390_irgen_XGR, ovl.fmt.RRE.r1,
13331 ovl.fmt.RRE.r2); goto ok;
13332 case 0xb983: s390_format_RRE_RR(s390_irgen_FLOGR, ovl.fmt.RRE.r1,
13333 ovl.fmt.RRE.r2); goto ok;
13334 case 0xb984: s390_format_RRE_RR(s390_irgen_LLGCR, ovl.fmt.RRE.r1,
13335 ovl.fmt.RRE.r2); goto ok;
13336 case 0xb985: s390_format_RRE_RR(s390_irgen_LLGHR, ovl.fmt.RRE.r1,
13337 ovl.fmt.RRE.r2); goto ok;
13338 case 0xb986: s390_format_RRE_RR(s390_irgen_MLGR, ovl.fmt.RRE.r1,
13339 ovl.fmt.RRE.r2); goto ok;
13340 case 0xb987: s390_format_RRE_RR(s390_irgen_DLGR, ovl.fmt.RRE.r1,
13341 ovl.fmt.RRE.r2); goto ok;
13342 case 0xb988: s390_format_RRE_RR(s390_irgen_ALCGR, ovl.fmt.RRE.r1,
13343 ovl.fmt.RRE.r2); goto ok;
13344 case 0xb989: s390_format_RRE_RR(s390_irgen_SLBGR, ovl.fmt.RRE.r1,
13345 ovl.fmt.RRE.r2); goto ok;
13346 case 0xb98a: /* CSPG */ goto unimplemented;
13347 case 0xb98d: /* EPSW */ goto unimplemented;
13348 case 0xb98e: /* IDTE */ goto unimplemented;
florian2289cd42012-12-05 04:23:42 +000013349 case 0xb98f: /* CRDTE */ goto unimplemented;
florian730448f2012-02-04 17:07:07 +000013350 case 0xb990: s390_format_RRF_M0RERE(s390_irgen_TRTT, ovl.fmt.RRF3.r3,
13351 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
13352 case 0xb991: s390_format_RRF_M0RERE(s390_irgen_TRTO, ovl.fmt.RRF3.r3,
13353 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
13354 case 0xb992: s390_format_RRF_M0RERE(s390_irgen_TROT, ovl.fmt.RRF3.r3,
13355 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
florian9af37692012-01-15 21:01:16 +000013356 case 0xb993: s390_format_RRF_M0RERE(s390_irgen_TROO, ovl.fmt.RRF3.r3,
13357 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013358 case 0xb994: s390_format_RRE_RR(s390_irgen_LLCR, ovl.fmt.RRE.r1,
13359 ovl.fmt.RRE.r2); goto ok;
13360 case 0xb995: s390_format_RRE_RR(s390_irgen_LLHR, ovl.fmt.RRE.r1,
13361 ovl.fmt.RRE.r2); goto ok;
13362 case 0xb996: s390_format_RRE_RR(s390_irgen_MLR, ovl.fmt.RRE.r1,
13363 ovl.fmt.RRE.r2); goto ok;
13364 case 0xb997: s390_format_RRE_RR(s390_irgen_DLR, ovl.fmt.RRE.r1,
13365 ovl.fmt.RRE.r2); goto ok;
13366 case 0xb998: s390_format_RRE_RR(s390_irgen_ALCR, ovl.fmt.RRE.r1,
13367 ovl.fmt.RRE.r2); goto ok;
13368 case 0xb999: s390_format_RRE_RR(s390_irgen_SLBR, ovl.fmt.RRE.r1,
13369 ovl.fmt.RRE.r2); goto ok;
13370 case 0xb99a: /* EPAIR */ goto unimplemented;
13371 case 0xb99b: /* ESAIR */ goto unimplemented;
13372 case 0xb99d: /* ESEA */ goto unimplemented;
13373 case 0xb99e: /* PTI */ goto unimplemented;
13374 case 0xb99f: /* SSAIR */ goto unimplemented;
13375 case 0xb9a2: /* PTF */ goto unimplemented;
13376 case 0xb9aa: /* LPTEA */ goto unimplemented;
13377 case 0xb9ae: /* RRBM */ goto unimplemented;
13378 case 0xb9af: /* PFMF */ goto unimplemented;
florian3f8a96a2012-08-05 02:59:55 +000013379 case 0xb9b0: s390_format_RRF_M0RERE(s390_irgen_CU14, ovl.fmt.RRF3.r3,
13380 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
13381 goto ok;
florian2a415a12012-07-21 17:41:36 +000013382 case 0xb9b1: s390_format_RRF_M0RERE(s390_irgen_CU24, ovl.fmt.RRF3.r3,
13383 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
13384 goto ok;
florianaf2194f2012-08-06 00:07:54 +000013385 case 0xb9b2: s390_format_RRE_RR(s390_irgen_CU41, ovl.fmt.RRE.r1,
13386 ovl.fmt.RRE.r2); goto ok;
florian956194b2012-07-28 22:18:32 +000013387 case 0xb9b3: s390_format_RRE_RR(s390_irgen_CU42, ovl.fmt.RRE.r1,
13388 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013389 case 0xb9bd: /* TRTRE */ goto unimplemented;
13390 case 0xb9be: /* SRSTU */ goto unimplemented;
13391 case 0xb9bf: /* TRTE */ goto unimplemented;
13392 case 0xb9c8: s390_format_RRF_R0RR2(s390_irgen_AHHHR, ovl.fmt.RRF4.r3,
13393 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13394 goto ok;
13395 case 0xb9c9: s390_format_RRF_R0RR2(s390_irgen_SHHHR, ovl.fmt.RRF4.r3,
13396 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13397 goto ok;
13398 case 0xb9ca: s390_format_RRF_R0RR2(s390_irgen_ALHHHR, ovl.fmt.RRF4.r3,
13399 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13400 goto ok;
13401 case 0xb9cb: s390_format_RRF_R0RR2(s390_irgen_SLHHHR, ovl.fmt.RRF4.r3,
13402 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13403 goto ok;
13404 case 0xb9cd: s390_format_RRE_RR(s390_irgen_CHHR, ovl.fmt.RRE.r1,
13405 ovl.fmt.RRE.r2); goto ok;
13406 case 0xb9cf: s390_format_RRE_RR(s390_irgen_CLHHR, ovl.fmt.RRE.r1,
13407 ovl.fmt.RRE.r2); goto ok;
13408 case 0xb9d8: s390_format_RRF_R0RR2(s390_irgen_AHHLR, ovl.fmt.RRF4.r3,
13409 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13410 goto ok;
13411 case 0xb9d9: s390_format_RRF_R0RR2(s390_irgen_SHHLR, ovl.fmt.RRF4.r3,
13412 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13413 goto ok;
13414 case 0xb9da: s390_format_RRF_R0RR2(s390_irgen_ALHHLR, ovl.fmt.RRF4.r3,
13415 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13416 goto ok;
13417 case 0xb9db: s390_format_RRF_R0RR2(s390_irgen_SLHHLR, ovl.fmt.RRF4.r3,
13418 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13419 goto ok;
13420 case 0xb9dd: s390_format_RRE_RR(s390_irgen_CHLR, ovl.fmt.RRE.r1,
13421 ovl.fmt.RRE.r2); goto ok;
13422 case 0xb9df: s390_format_RRE_RR(s390_irgen_CLHLR, ovl.fmt.RRE.r1,
13423 ovl.fmt.RRE.r2); goto ok;
13424 case 0xb9e1: /* POPCNT */ goto unimplemented;
sewardjd7bde722011-04-05 13:19:33 +000013425 case 0xb9e2: s390_format_RRF_U0RR(s390_irgen_LOCGR, ovl.fmt.RRF3.r3,
13426 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2,
13427 S390_XMNM_LOCGR); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013428 case 0xb9e4: s390_format_RRF_R0RR2(s390_irgen_NGRK, ovl.fmt.RRF4.r3,
13429 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13430 goto ok;
13431 case 0xb9e6: s390_format_RRF_R0RR2(s390_irgen_OGRK, ovl.fmt.RRF4.r3,
13432 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13433 goto ok;
13434 case 0xb9e7: s390_format_RRF_R0RR2(s390_irgen_XGRK, ovl.fmt.RRF4.r3,
13435 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13436 goto ok;
13437 case 0xb9e8: s390_format_RRF_R0RR2(s390_irgen_AGRK, ovl.fmt.RRF4.r3,
13438 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13439 goto ok;
13440 case 0xb9e9: s390_format_RRF_R0RR2(s390_irgen_SGRK, ovl.fmt.RRF4.r3,
13441 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13442 goto ok;
13443 case 0xb9ea: s390_format_RRF_R0RR2(s390_irgen_ALGRK, ovl.fmt.RRF4.r3,
13444 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13445 goto ok;
13446 case 0xb9eb: s390_format_RRF_R0RR2(s390_irgen_SLGRK, ovl.fmt.RRF4.r3,
13447 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13448 goto ok;
sewardjd7bde722011-04-05 13:19:33 +000013449 case 0xb9f2: s390_format_RRF_U0RR(s390_irgen_LOCR, ovl.fmt.RRF3.r3,
13450 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2,
13451 S390_XMNM_LOCR); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013452 case 0xb9f4: s390_format_RRF_R0RR2(s390_irgen_NRK, ovl.fmt.RRF4.r3,
13453 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13454 goto ok;
13455 case 0xb9f6: s390_format_RRF_R0RR2(s390_irgen_ORK, ovl.fmt.RRF4.r3,
13456 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13457 goto ok;
13458 case 0xb9f7: s390_format_RRF_R0RR2(s390_irgen_XRK, ovl.fmt.RRF4.r3,
13459 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13460 goto ok;
13461 case 0xb9f8: s390_format_RRF_R0RR2(s390_irgen_ARK, ovl.fmt.RRF4.r3,
13462 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13463 goto ok;
13464 case 0xb9f9: s390_format_RRF_R0RR2(s390_irgen_SRK, ovl.fmt.RRF4.r3,
13465 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13466 goto ok;
13467 case 0xb9fa: s390_format_RRF_R0RR2(s390_irgen_ALRK, ovl.fmt.RRF4.r3,
13468 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13469 goto ok;
13470 case 0xb9fb: s390_format_RRF_R0RR2(s390_irgen_SLRK, ovl.fmt.RRF4.r3,
13471 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13472 goto ok;
13473 }
13474
13475 switch ((ovl.value & 0xff000000) >> 24) {
13476 case 0x40: s390_format_RX_RRRD(s390_irgen_STH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13477 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13478 case 0x41: s390_format_RX_RRRD(s390_irgen_LA, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13479 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13480 case 0x42: s390_format_RX_RRRD(s390_irgen_STC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13481 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13482 case 0x43: s390_format_RX_RRRD(s390_irgen_IC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13483 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13484 case 0x44: s390_format_RX_RRRD(s390_irgen_EX, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13485 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13486 case 0x45: /* BAL */ goto unimplemented;
13487 case 0x46: s390_format_RX_RRRD(s390_irgen_BCT, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13488 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13489 case 0x47: s390_format_RX(s390_irgen_BC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13490 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13491 case 0x48: s390_format_RX_RRRD(s390_irgen_LH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13492 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13493 case 0x49: s390_format_RX_RRRD(s390_irgen_CH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13494 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13495 case 0x4a: s390_format_RX_RRRD(s390_irgen_AH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13496 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13497 case 0x4b: s390_format_RX_RRRD(s390_irgen_SH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13498 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13499 case 0x4c: s390_format_RX_RRRD(s390_irgen_MH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13500 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13501 case 0x4d: s390_format_RX_RRRD(s390_irgen_BAS, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13502 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13503 case 0x4e: s390_format_RX_RRRD(s390_irgen_CVD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13504 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13505 case 0x4f: s390_format_RX_RRRD(s390_irgen_CVB, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13506 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13507 case 0x50: s390_format_RX_RRRD(s390_irgen_ST, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13508 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13509 case 0x51: s390_format_RX_RRRD(s390_irgen_LAE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13510 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13511 case 0x54: s390_format_RX_RRRD(s390_irgen_N, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13512 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13513 case 0x55: s390_format_RX_RRRD(s390_irgen_CL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13514 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13515 case 0x56: s390_format_RX_RRRD(s390_irgen_O, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13516 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13517 case 0x57: s390_format_RX_RRRD(s390_irgen_X, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13518 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13519 case 0x58: s390_format_RX_RRRD(s390_irgen_L, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13520 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13521 case 0x59: s390_format_RX_RRRD(s390_irgen_C, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13522 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13523 case 0x5a: s390_format_RX_RRRD(s390_irgen_A, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13524 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13525 case 0x5b: s390_format_RX_RRRD(s390_irgen_S, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13526 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13527 case 0x5c: s390_format_RX_RRRD(s390_irgen_M, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13528 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13529 case 0x5d: s390_format_RX_RRRD(s390_irgen_D, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13530 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13531 case 0x5e: s390_format_RX_RRRD(s390_irgen_AL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13532 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13533 case 0x5f: s390_format_RX_RRRD(s390_irgen_SL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13534 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13535 case 0x60: s390_format_RX_FRRD(s390_irgen_STD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13536 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13537 case 0x67: /* MXD */ goto unimplemented;
13538 case 0x68: s390_format_RX_FRRD(s390_irgen_LD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13539 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13540 case 0x69: /* CD */ goto unimplemented;
13541 case 0x6a: /* AD */ goto unimplemented;
13542 case 0x6b: /* SD */ goto unimplemented;
13543 case 0x6c: /* MD */ goto unimplemented;
13544 case 0x6d: /* DD */ goto unimplemented;
13545 case 0x6e: /* AW */ goto unimplemented;
13546 case 0x6f: /* SW */ goto unimplemented;
13547 case 0x70: s390_format_RX_FRRD(s390_irgen_STE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13548 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13549 case 0x71: s390_format_RX_RRRD(s390_irgen_MS, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13550 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13551 case 0x78: s390_format_RX_FRRD(s390_irgen_LE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13552 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13553 case 0x79: /* CE */ goto unimplemented;
13554 case 0x7a: /* AE */ goto unimplemented;
13555 case 0x7b: /* SE */ goto unimplemented;
13556 case 0x7c: /* MDE */ goto unimplemented;
13557 case 0x7d: /* DE */ goto unimplemented;
13558 case 0x7e: /* AU */ goto unimplemented;
13559 case 0x7f: /* SU */ goto unimplemented;
13560 case 0x83: /* DIAG */ goto unimplemented;
13561 case 0x84: s390_format_RSI_RRP(s390_irgen_BRXH, ovl.fmt.RSI.r1,
13562 ovl.fmt.RSI.r3, ovl.fmt.RSI.i2); goto ok;
13563 case 0x85: s390_format_RSI_RRP(s390_irgen_BRXLE, ovl.fmt.RSI.r1,
13564 ovl.fmt.RSI.r3, ovl.fmt.RSI.i2); goto ok;
13565 case 0x86: s390_format_RS_RRRD(s390_irgen_BXH, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13566 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13567 case 0x87: s390_format_RS_RRRD(s390_irgen_BXLE, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13568 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13569 case 0x88: s390_format_RS_R0RD(s390_irgen_SRL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13570 ovl.fmt.RS.d2); goto ok;
13571 case 0x89: s390_format_RS_R0RD(s390_irgen_SLL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13572 ovl.fmt.RS.d2); goto ok;
13573 case 0x8a: s390_format_RS_R0RD(s390_irgen_SRA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13574 ovl.fmt.RS.d2); goto ok;
13575 case 0x8b: s390_format_RS_R0RD(s390_irgen_SLA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13576 ovl.fmt.RS.d2); goto ok;
13577 case 0x8c: s390_format_RS_R0RD(s390_irgen_SRDL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13578 ovl.fmt.RS.d2); goto ok;
13579 case 0x8d: s390_format_RS_R0RD(s390_irgen_SLDL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13580 ovl.fmt.RS.d2); goto ok;
13581 case 0x8e: s390_format_RS_R0RD(s390_irgen_SRDA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13582 ovl.fmt.RS.d2); goto ok;
13583 case 0x8f: s390_format_RS_R0RD(s390_irgen_SLDA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13584 ovl.fmt.RS.d2); goto ok;
13585 case 0x90: s390_format_RS_RRRD(s390_irgen_STM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13586 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13587 case 0x91: s390_format_SI_URD(s390_irgen_TM, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
13588 ovl.fmt.SI.d1); goto ok;
13589 case 0x92: s390_format_SI_URD(s390_irgen_MVI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
13590 ovl.fmt.SI.d1); goto ok;
13591 case 0x94: s390_format_SI_URD(s390_irgen_NI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
13592 ovl.fmt.SI.d1); goto ok;
13593 case 0x95: s390_format_SI_URD(s390_irgen_CLI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
13594 ovl.fmt.SI.d1); goto ok;
13595 case 0x96: s390_format_SI_URD(s390_irgen_OI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
13596 ovl.fmt.SI.d1); goto ok;
13597 case 0x97: s390_format_SI_URD(s390_irgen_XI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
13598 ovl.fmt.SI.d1); goto ok;
13599 case 0x98: s390_format_RS_RRRD(s390_irgen_LM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13600 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13601 case 0x99: /* TRACE */ goto unimplemented;
13602 case 0x9a: s390_format_RS_AARD(s390_irgen_LAM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13603 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13604 case 0x9b: s390_format_RS_AARD(s390_irgen_STAM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13605 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13606 case 0xa8: s390_format_RS_RRRD(s390_irgen_MVCLE, ovl.fmt.RS.r1,
13607 ovl.fmt.RS.r3, ovl.fmt.RS.b2, ovl.fmt.RS.d2);
13608 goto ok;
13609 case 0xa9: s390_format_RS_RRRD(s390_irgen_CLCLE, ovl.fmt.RS.r1,
13610 ovl.fmt.RS.r3, ovl.fmt.RS.b2, ovl.fmt.RS.d2);
13611 goto ok;
13612 case 0xac: /* STNSM */ goto unimplemented;
13613 case 0xad: /* STOSM */ goto unimplemented;
13614 case 0xae: /* SIGP */ goto unimplemented;
13615 case 0xaf: /* MC */ goto unimplemented;
13616 case 0xb1: /* LRA */ goto unimplemented;
13617 case 0xb6: /* STCTL */ goto unimplemented;
13618 case 0xb7: /* LCTL */ goto unimplemented;
13619 case 0xba: s390_format_RS_RRRD(s390_irgen_CS, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13620 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
florian448cbba2012-06-06 02:26:01 +000013621 case 0xbb: s390_format_RS_RRRD(s390_irgen_CDS, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13622 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013623 case 0xbd: s390_format_RS_RURD(s390_irgen_CLM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13624 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13625 case 0xbe: s390_format_RS_RURD(s390_irgen_STCM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13626 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13627 case 0xbf: s390_format_RS_RURD(s390_irgen_ICM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13628 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13629 }
13630
13631 return S390_DECODE_UNKNOWN_INSN;
13632
13633ok:
13634 return S390_DECODE_OK;
13635
13636unimplemented:
13637 return S390_DECODE_UNIMPLEMENTED_INSN;
13638}
13639
13640static s390_decode_t
13641s390_decode_6byte_and_irgen(UChar *bytes)
13642{
13643 typedef union {
13644 struct {
13645 unsigned int op1 : 8;
13646 unsigned int r1 : 4;
13647 unsigned int r3 : 4;
13648 unsigned int i2 : 16;
13649 unsigned int : 8;
13650 unsigned int op2 : 8;
13651 } RIE;
13652 struct {
13653 unsigned int op1 : 8;
13654 unsigned int r1 : 4;
13655 unsigned int r2 : 4;
13656 unsigned int i3 : 8;
13657 unsigned int i4 : 8;
13658 unsigned int i5 : 8;
13659 unsigned int op2 : 8;
13660 } RIE_RRUUU;
13661 struct {
13662 unsigned int op1 : 8;
13663 unsigned int r1 : 4;
13664 unsigned int : 4;
13665 unsigned int i2 : 16;
13666 unsigned int m3 : 4;
13667 unsigned int : 4;
13668 unsigned int op2 : 8;
13669 } RIEv1;
13670 struct {
13671 unsigned int op1 : 8;
13672 unsigned int r1 : 4;
13673 unsigned int r2 : 4;
13674 unsigned int i4 : 16;
13675 unsigned int m3 : 4;
13676 unsigned int : 4;
13677 unsigned int op2 : 8;
13678 } RIE_RRPU;
13679 struct {
13680 unsigned int op1 : 8;
13681 unsigned int r1 : 4;
13682 unsigned int m3 : 4;
13683 unsigned int i4 : 16;
13684 unsigned int i2 : 8;
13685 unsigned int op2 : 8;
13686 } RIEv3;
13687 struct {
13688 unsigned int op1 : 8;
13689 unsigned int r1 : 4;
13690 unsigned int op2 : 4;
13691 unsigned int i2 : 32;
13692 } RIL;
13693 struct {
13694 unsigned int op1 : 8;
13695 unsigned int r1 : 4;
13696 unsigned int m3 : 4;
13697 unsigned int b4 : 4;
13698 unsigned int d4 : 12;
13699 unsigned int i2 : 8;
13700 unsigned int op2 : 8;
13701 } RIS;
13702 struct {
13703 unsigned int op1 : 8;
13704 unsigned int r1 : 4;
13705 unsigned int r2 : 4;
13706 unsigned int b4 : 4;
13707 unsigned int d4 : 12;
13708 unsigned int m3 : 4;
13709 unsigned int : 4;
13710 unsigned int op2 : 8;
13711 } RRS;
13712 struct {
13713 unsigned int op1 : 8;
13714 unsigned int l1 : 4;
13715 unsigned int : 4;
13716 unsigned int b1 : 4;
13717 unsigned int d1 : 12;
13718 unsigned int : 8;
13719 unsigned int op2 : 8;
13720 } RSL;
13721 struct {
13722 unsigned int op1 : 8;
13723 unsigned int r1 : 4;
13724 unsigned int r3 : 4;
13725 unsigned int b2 : 4;
13726 unsigned int dl2 : 12;
13727 unsigned int dh2 : 8;
13728 unsigned int op2 : 8;
13729 } RSY;
13730 struct {
13731 unsigned int op1 : 8;
13732 unsigned int r1 : 4;
13733 unsigned int x2 : 4;
13734 unsigned int b2 : 4;
13735 unsigned int d2 : 12;
13736 unsigned int : 8;
13737 unsigned int op2 : 8;
13738 } RXE;
13739 struct {
13740 unsigned int op1 : 8;
13741 unsigned int r3 : 4;
13742 unsigned int x2 : 4;
13743 unsigned int b2 : 4;
13744 unsigned int d2 : 12;
13745 unsigned int r1 : 4;
13746 unsigned int : 4;
13747 unsigned int op2 : 8;
13748 } RXF;
13749 struct {
13750 unsigned int op1 : 8;
13751 unsigned int r1 : 4;
13752 unsigned int x2 : 4;
13753 unsigned int b2 : 4;
13754 unsigned int dl2 : 12;
13755 unsigned int dh2 : 8;
13756 unsigned int op2 : 8;
13757 } RXY;
13758 struct {
13759 unsigned int op1 : 8;
13760 unsigned int i2 : 8;
13761 unsigned int b1 : 4;
13762 unsigned int dl1 : 12;
13763 unsigned int dh1 : 8;
13764 unsigned int op2 : 8;
13765 } SIY;
13766 struct {
13767 unsigned int op : 8;
13768 unsigned int l : 8;
13769 unsigned int b1 : 4;
13770 unsigned int d1 : 12;
13771 unsigned int b2 : 4;
13772 unsigned int d2 : 12;
13773 } SS;
13774 struct {
13775 unsigned int op : 8;
13776 unsigned int l1 : 4;
13777 unsigned int l2 : 4;
13778 unsigned int b1 : 4;
13779 unsigned int d1 : 12;
13780 unsigned int b2 : 4;
13781 unsigned int d2 : 12;
13782 } SS_LLRDRD;
13783 struct {
13784 unsigned int op : 8;
13785 unsigned int r1 : 4;
13786 unsigned int r3 : 4;
13787 unsigned int b2 : 4;
13788 unsigned int d2 : 12;
13789 unsigned int b4 : 4;
13790 unsigned int d4 : 12;
13791 } SS_RRRDRD2;
13792 struct {
13793 unsigned int op : 16;
13794 unsigned int b1 : 4;
13795 unsigned int d1 : 12;
13796 unsigned int b2 : 4;
13797 unsigned int d2 : 12;
13798 } SSE;
13799 struct {
13800 unsigned int op1 : 8;
13801 unsigned int r3 : 4;
13802 unsigned int op2 : 4;
13803 unsigned int b1 : 4;
13804 unsigned int d1 : 12;
13805 unsigned int b2 : 4;
13806 unsigned int d2 : 12;
13807 } SSF;
13808 struct {
13809 unsigned int op : 16;
13810 unsigned int b1 : 4;
13811 unsigned int d1 : 12;
13812 unsigned int i2 : 16;
13813 } SIL;
13814 } formats;
13815 union {
13816 formats fmt;
13817 ULong value;
13818 } ovl;
13819
13820 vassert(sizeof(formats) == 6);
13821
13822 ((char *)(&ovl.value))[0] = bytes[0];
13823 ((char *)(&ovl.value))[1] = bytes[1];
13824 ((char *)(&ovl.value))[2] = bytes[2];
13825 ((char *)(&ovl.value))[3] = bytes[3];
13826 ((char *)(&ovl.value))[4] = bytes[4];
13827 ((char *)(&ovl.value))[5] = bytes[5];
13828 ((char *)(&ovl.value))[6] = 0x0;
13829 ((char *)(&ovl.value))[7] = 0x0;
13830
13831 switch ((ovl.value >> 16) & 0xff00000000ffULL) {
13832 case 0xe30000000002ULL: s390_format_RXY_RRRD(s390_irgen_LTG, ovl.fmt.RXY.r1,
13833 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13834 ovl.fmt.RXY.dl2,
13835 ovl.fmt.RXY.dh2); goto ok;
13836 case 0xe30000000003ULL: /* LRAG */ goto unimplemented;
13837 case 0xe30000000004ULL: s390_format_RXY_RRRD(s390_irgen_LG, ovl.fmt.RXY.r1,
13838 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13839 ovl.fmt.RXY.dl2,
13840 ovl.fmt.RXY.dh2); goto ok;
13841 case 0xe30000000006ULL: s390_format_RXY_RRRD(s390_irgen_CVBY, ovl.fmt.RXY.r1,
13842 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13843 ovl.fmt.RXY.dl2,
13844 ovl.fmt.RXY.dh2); goto ok;
13845 case 0xe30000000008ULL: s390_format_RXY_RRRD(s390_irgen_AG, ovl.fmt.RXY.r1,
13846 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13847 ovl.fmt.RXY.dl2,
13848 ovl.fmt.RXY.dh2); goto ok;
13849 case 0xe30000000009ULL: s390_format_RXY_RRRD(s390_irgen_SG, ovl.fmt.RXY.r1,
13850 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13851 ovl.fmt.RXY.dl2,
13852 ovl.fmt.RXY.dh2); goto ok;
13853 case 0xe3000000000aULL: s390_format_RXY_RRRD(s390_irgen_ALG, ovl.fmt.RXY.r1,
13854 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13855 ovl.fmt.RXY.dl2,
13856 ovl.fmt.RXY.dh2); goto ok;
13857 case 0xe3000000000bULL: s390_format_RXY_RRRD(s390_irgen_SLG, ovl.fmt.RXY.r1,
13858 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13859 ovl.fmt.RXY.dl2,
13860 ovl.fmt.RXY.dh2); goto ok;
13861 case 0xe3000000000cULL: s390_format_RXY_RRRD(s390_irgen_MSG, ovl.fmt.RXY.r1,
13862 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13863 ovl.fmt.RXY.dl2,
13864 ovl.fmt.RXY.dh2); goto ok;
13865 case 0xe3000000000dULL: s390_format_RXY_RRRD(s390_irgen_DSG, ovl.fmt.RXY.r1,
13866 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13867 ovl.fmt.RXY.dl2,
13868 ovl.fmt.RXY.dh2); goto ok;
13869 case 0xe3000000000eULL: /* CVBG */ goto unimplemented;
13870 case 0xe3000000000fULL: s390_format_RXY_RRRD(s390_irgen_LRVG, ovl.fmt.RXY.r1,
13871 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13872 ovl.fmt.RXY.dl2,
13873 ovl.fmt.RXY.dh2); goto ok;
13874 case 0xe30000000012ULL: s390_format_RXY_RRRD(s390_irgen_LT, ovl.fmt.RXY.r1,
13875 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13876 ovl.fmt.RXY.dl2,
13877 ovl.fmt.RXY.dh2); goto ok;
13878 case 0xe30000000013ULL: /* LRAY */ goto unimplemented;
13879 case 0xe30000000014ULL: s390_format_RXY_RRRD(s390_irgen_LGF, ovl.fmt.RXY.r1,
13880 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13881 ovl.fmt.RXY.dl2,
13882 ovl.fmt.RXY.dh2); goto ok;
13883 case 0xe30000000015ULL: s390_format_RXY_RRRD(s390_irgen_LGH, ovl.fmt.RXY.r1,
13884 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13885 ovl.fmt.RXY.dl2,
13886 ovl.fmt.RXY.dh2); goto ok;
13887 case 0xe30000000016ULL: s390_format_RXY_RRRD(s390_irgen_LLGF, ovl.fmt.RXY.r1,
13888 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13889 ovl.fmt.RXY.dl2,
13890 ovl.fmt.RXY.dh2); goto ok;
13891 case 0xe30000000017ULL: s390_format_RXY_RRRD(s390_irgen_LLGT, ovl.fmt.RXY.r1,
13892 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13893 ovl.fmt.RXY.dl2,
13894 ovl.fmt.RXY.dh2); goto ok;
13895 case 0xe30000000018ULL: s390_format_RXY_RRRD(s390_irgen_AGF, ovl.fmt.RXY.r1,
13896 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13897 ovl.fmt.RXY.dl2,
13898 ovl.fmt.RXY.dh2); goto ok;
13899 case 0xe30000000019ULL: s390_format_RXY_RRRD(s390_irgen_SGF, ovl.fmt.RXY.r1,
13900 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13901 ovl.fmt.RXY.dl2,
13902 ovl.fmt.RXY.dh2); goto ok;
13903 case 0xe3000000001aULL: s390_format_RXY_RRRD(s390_irgen_ALGF, ovl.fmt.RXY.r1,
13904 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13905 ovl.fmt.RXY.dl2,
13906 ovl.fmt.RXY.dh2); goto ok;
13907 case 0xe3000000001bULL: s390_format_RXY_RRRD(s390_irgen_SLGF, ovl.fmt.RXY.r1,
13908 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13909 ovl.fmt.RXY.dl2,
13910 ovl.fmt.RXY.dh2); goto ok;
13911 case 0xe3000000001cULL: s390_format_RXY_RRRD(s390_irgen_MSGF, ovl.fmt.RXY.r1,
13912 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13913 ovl.fmt.RXY.dl2,
13914 ovl.fmt.RXY.dh2); goto ok;
13915 case 0xe3000000001dULL: s390_format_RXY_RRRD(s390_irgen_DSGF, ovl.fmt.RXY.r1,
13916 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13917 ovl.fmt.RXY.dl2,
13918 ovl.fmt.RXY.dh2); goto ok;
13919 case 0xe3000000001eULL: s390_format_RXY_RRRD(s390_irgen_LRV, ovl.fmt.RXY.r1,
13920 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13921 ovl.fmt.RXY.dl2,
13922 ovl.fmt.RXY.dh2); goto ok;
13923 case 0xe3000000001fULL: s390_format_RXY_RRRD(s390_irgen_LRVH, ovl.fmt.RXY.r1,
13924 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13925 ovl.fmt.RXY.dl2,
13926 ovl.fmt.RXY.dh2); goto ok;
13927 case 0xe30000000020ULL: s390_format_RXY_RRRD(s390_irgen_CG, ovl.fmt.RXY.r1,
13928 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13929 ovl.fmt.RXY.dl2,
13930 ovl.fmt.RXY.dh2); goto ok;
13931 case 0xe30000000021ULL: s390_format_RXY_RRRD(s390_irgen_CLG, ovl.fmt.RXY.r1,
13932 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13933 ovl.fmt.RXY.dl2,
13934 ovl.fmt.RXY.dh2); goto ok;
13935 case 0xe30000000024ULL: s390_format_RXY_RRRD(s390_irgen_STG, ovl.fmt.RXY.r1,
13936 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13937 ovl.fmt.RXY.dl2,
13938 ovl.fmt.RXY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000013939 case 0xe30000000025ULL: /* NTSTG */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000013940 case 0xe30000000026ULL: s390_format_RXY_RRRD(s390_irgen_CVDY, ovl.fmt.RXY.r1,
13941 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13942 ovl.fmt.RXY.dl2,
13943 ovl.fmt.RXY.dh2); goto ok;
13944 case 0xe3000000002eULL: /* CVDG */ goto unimplemented;
13945 case 0xe3000000002fULL: s390_format_RXY_RRRD(s390_irgen_STRVG,
13946 ovl.fmt.RXY.r1, ovl.fmt.RXY.x2,
13947 ovl.fmt.RXY.b2, ovl.fmt.RXY.dl2,
13948 ovl.fmt.RXY.dh2); goto ok;
13949 case 0xe30000000030ULL: s390_format_RXY_RRRD(s390_irgen_CGF, ovl.fmt.RXY.r1,
13950 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13951 ovl.fmt.RXY.dl2,
13952 ovl.fmt.RXY.dh2); goto ok;
13953 case 0xe30000000031ULL: s390_format_RXY_RRRD(s390_irgen_CLGF, ovl.fmt.RXY.r1,
13954 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13955 ovl.fmt.RXY.dl2,
13956 ovl.fmt.RXY.dh2); goto ok;
13957 case 0xe30000000032ULL: s390_format_RXY_RRRD(s390_irgen_LTGF, ovl.fmt.RXY.r1,
13958 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13959 ovl.fmt.RXY.dl2,
13960 ovl.fmt.RXY.dh2); goto ok;
13961 case 0xe30000000034ULL: s390_format_RXY_RRRD(s390_irgen_CGH, ovl.fmt.RXY.r1,
13962 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13963 ovl.fmt.RXY.dl2,
13964 ovl.fmt.RXY.dh2); goto ok;
13965 case 0xe30000000036ULL: s390_format_RXY_URRD(s390_irgen_PFD, ovl.fmt.RXY.r1,
13966 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13967 ovl.fmt.RXY.dl2,
13968 ovl.fmt.RXY.dh2); goto ok;
13969 case 0xe3000000003eULL: s390_format_RXY_RRRD(s390_irgen_STRV, ovl.fmt.RXY.r1,
13970 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13971 ovl.fmt.RXY.dl2,
13972 ovl.fmt.RXY.dh2); goto ok;
13973 case 0xe3000000003fULL: s390_format_RXY_RRRD(s390_irgen_STRVH,
13974 ovl.fmt.RXY.r1, ovl.fmt.RXY.x2,
13975 ovl.fmt.RXY.b2, ovl.fmt.RXY.dl2,
13976 ovl.fmt.RXY.dh2); goto ok;
13977 case 0xe30000000046ULL: s390_format_RXY_RRRD(s390_irgen_BCTG, ovl.fmt.RXY.r1,
13978 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13979 ovl.fmt.RXY.dl2,
13980 ovl.fmt.RXY.dh2); goto ok;
13981 case 0xe30000000050ULL: s390_format_RXY_RRRD(s390_irgen_STY, ovl.fmt.RXY.r1,
13982 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13983 ovl.fmt.RXY.dl2,
13984 ovl.fmt.RXY.dh2); goto ok;
13985 case 0xe30000000051ULL: s390_format_RXY_RRRD(s390_irgen_MSY, ovl.fmt.RXY.r1,
13986 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13987 ovl.fmt.RXY.dl2,
13988 ovl.fmt.RXY.dh2); goto ok;
13989 case 0xe30000000054ULL: s390_format_RXY_RRRD(s390_irgen_NY, ovl.fmt.RXY.r1,
13990 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13991 ovl.fmt.RXY.dl2,
13992 ovl.fmt.RXY.dh2); goto ok;
13993 case 0xe30000000055ULL: s390_format_RXY_RRRD(s390_irgen_CLY, ovl.fmt.RXY.r1,
13994 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13995 ovl.fmt.RXY.dl2,
13996 ovl.fmt.RXY.dh2); goto ok;
13997 case 0xe30000000056ULL: s390_format_RXY_RRRD(s390_irgen_OY, ovl.fmt.RXY.r1,
13998 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13999 ovl.fmt.RXY.dl2,
14000 ovl.fmt.RXY.dh2); goto ok;
14001 case 0xe30000000057ULL: s390_format_RXY_RRRD(s390_irgen_XY, ovl.fmt.RXY.r1,
14002 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14003 ovl.fmt.RXY.dl2,
14004 ovl.fmt.RXY.dh2); goto ok;
14005 case 0xe30000000058ULL: s390_format_RXY_RRRD(s390_irgen_LY, ovl.fmt.RXY.r1,
14006 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14007 ovl.fmt.RXY.dl2,
14008 ovl.fmt.RXY.dh2); goto ok;
14009 case 0xe30000000059ULL: s390_format_RXY_RRRD(s390_irgen_CY, ovl.fmt.RXY.r1,
14010 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14011 ovl.fmt.RXY.dl2,
14012 ovl.fmt.RXY.dh2); goto ok;
14013 case 0xe3000000005aULL: s390_format_RXY_RRRD(s390_irgen_AY, ovl.fmt.RXY.r1,
14014 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14015 ovl.fmt.RXY.dl2,
14016 ovl.fmt.RXY.dh2); goto ok;
14017 case 0xe3000000005bULL: s390_format_RXY_RRRD(s390_irgen_SY, ovl.fmt.RXY.r1,
14018 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14019 ovl.fmt.RXY.dl2,
14020 ovl.fmt.RXY.dh2); goto ok;
14021 case 0xe3000000005cULL: s390_format_RXY_RRRD(s390_irgen_MFY, ovl.fmt.RXY.r1,
14022 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14023 ovl.fmt.RXY.dl2,
14024 ovl.fmt.RXY.dh2); goto ok;
14025 case 0xe3000000005eULL: s390_format_RXY_RRRD(s390_irgen_ALY, ovl.fmt.RXY.r1,
14026 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14027 ovl.fmt.RXY.dl2,
14028 ovl.fmt.RXY.dh2); goto ok;
14029 case 0xe3000000005fULL: s390_format_RXY_RRRD(s390_irgen_SLY, ovl.fmt.RXY.r1,
14030 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14031 ovl.fmt.RXY.dl2,
14032 ovl.fmt.RXY.dh2); goto ok;
14033 case 0xe30000000070ULL: s390_format_RXY_RRRD(s390_irgen_STHY, ovl.fmt.RXY.r1,
14034 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14035 ovl.fmt.RXY.dl2,
14036 ovl.fmt.RXY.dh2); goto ok;
14037 case 0xe30000000071ULL: s390_format_RXY_RRRD(s390_irgen_LAY, ovl.fmt.RXY.r1,
14038 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14039 ovl.fmt.RXY.dl2,
14040 ovl.fmt.RXY.dh2); goto ok;
14041 case 0xe30000000072ULL: s390_format_RXY_RRRD(s390_irgen_STCY, ovl.fmt.RXY.r1,
14042 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14043 ovl.fmt.RXY.dl2,
14044 ovl.fmt.RXY.dh2); goto ok;
14045 case 0xe30000000073ULL: s390_format_RXY_RRRD(s390_irgen_ICY, ovl.fmt.RXY.r1,
14046 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14047 ovl.fmt.RXY.dl2,
14048 ovl.fmt.RXY.dh2); goto ok;
14049 case 0xe30000000075ULL: s390_format_RXY_RRRD(s390_irgen_LAEY, ovl.fmt.RXY.r1,
14050 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14051 ovl.fmt.RXY.dl2,
14052 ovl.fmt.RXY.dh2); goto ok;
14053 case 0xe30000000076ULL: s390_format_RXY_RRRD(s390_irgen_LB, ovl.fmt.RXY.r1,
14054 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14055 ovl.fmt.RXY.dl2,
14056 ovl.fmt.RXY.dh2); goto ok;
14057 case 0xe30000000077ULL: s390_format_RXY_RRRD(s390_irgen_LGB, ovl.fmt.RXY.r1,
14058 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14059 ovl.fmt.RXY.dl2,
14060 ovl.fmt.RXY.dh2); goto ok;
14061 case 0xe30000000078ULL: s390_format_RXY_RRRD(s390_irgen_LHY, ovl.fmt.RXY.r1,
14062 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14063 ovl.fmt.RXY.dl2,
14064 ovl.fmt.RXY.dh2); goto ok;
14065 case 0xe30000000079ULL: s390_format_RXY_RRRD(s390_irgen_CHY, ovl.fmt.RXY.r1,
14066 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14067 ovl.fmt.RXY.dl2,
14068 ovl.fmt.RXY.dh2); goto ok;
14069 case 0xe3000000007aULL: s390_format_RXY_RRRD(s390_irgen_AHY, ovl.fmt.RXY.r1,
14070 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14071 ovl.fmt.RXY.dl2,
14072 ovl.fmt.RXY.dh2); goto ok;
14073 case 0xe3000000007bULL: s390_format_RXY_RRRD(s390_irgen_SHY, ovl.fmt.RXY.r1,
14074 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14075 ovl.fmt.RXY.dl2,
14076 ovl.fmt.RXY.dh2); goto ok;
14077 case 0xe3000000007cULL: s390_format_RXY_RRRD(s390_irgen_MHY, ovl.fmt.RXY.r1,
14078 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14079 ovl.fmt.RXY.dl2,
14080 ovl.fmt.RXY.dh2); goto ok;
14081 case 0xe30000000080ULL: s390_format_RXY_RRRD(s390_irgen_NG, ovl.fmt.RXY.r1,
14082 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14083 ovl.fmt.RXY.dl2,
14084 ovl.fmt.RXY.dh2); goto ok;
14085 case 0xe30000000081ULL: s390_format_RXY_RRRD(s390_irgen_OG, ovl.fmt.RXY.r1,
14086 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14087 ovl.fmt.RXY.dl2,
14088 ovl.fmt.RXY.dh2); goto ok;
14089 case 0xe30000000082ULL: s390_format_RXY_RRRD(s390_irgen_XG, ovl.fmt.RXY.r1,
14090 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14091 ovl.fmt.RXY.dl2,
14092 ovl.fmt.RXY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000014093 case 0xe30000000085ULL: /* LGAT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000014094 case 0xe30000000086ULL: s390_format_RXY_RRRD(s390_irgen_MLG, ovl.fmt.RXY.r1,
14095 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14096 ovl.fmt.RXY.dl2,
14097 ovl.fmt.RXY.dh2); goto ok;
14098 case 0xe30000000087ULL: s390_format_RXY_RRRD(s390_irgen_DLG, ovl.fmt.RXY.r1,
14099 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14100 ovl.fmt.RXY.dl2,
14101 ovl.fmt.RXY.dh2); goto ok;
14102 case 0xe30000000088ULL: s390_format_RXY_RRRD(s390_irgen_ALCG, ovl.fmt.RXY.r1,
14103 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14104 ovl.fmt.RXY.dl2,
14105 ovl.fmt.RXY.dh2); goto ok;
14106 case 0xe30000000089ULL: s390_format_RXY_RRRD(s390_irgen_SLBG, ovl.fmt.RXY.r1,
14107 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14108 ovl.fmt.RXY.dl2,
14109 ovl.fmt.RXY.dh2); goto ok;
14110 case 0xe3000000008eULL: s390_format_RXY_RRRD(s390_irgen_STPQ, ovl.fmt.RXY.r1,
14111 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14112 ovl.fmt.RXY.dl2,
14113 ovl.fmt.RXY.dh2); goto ok;
14114 case 0xe3000000008fULL: s390_format_RXY_RRRD(s390_irgen_LPQ, ovl.fmt.RXY.r1,
14115 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14116 ovl.fmt.RXY.dl2,
14117 ovl.fmt.RXY.dh2); goto ok;
14118 case 0xe30000000090ULL: s390_format_RXY_RRRD(s390_irgen_LLGC, ovl.fmt.RXY.r1,
14119 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14120 ovl.fmt.RXY.dl2,
14121 ovl.fmt.RXY.dh2); goto ok;
14122 case 0xe30000000091ULL: s390_format_RXY_RRRD(s390_irgen_LLGH, ovl.fmt.RXY.r1,
14123 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14124 ovl.fmt.RXY.dl2,
14125 ovl.fmt.RXY.dh2); goto ok;
14126 case 0xe30000000094ULL: s390_format_RXY_RRRD(s390_irgen_LLC, ovl.fmt.RXY.r1,
14127 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14128 ovl.fmt.RXY.dl2,
14129 ovl.fmt.RXY.dh2); goto ok;
14130 case 0xe30000000095ULL: s390_format_RXY_RRRD(s390_irgen_LLH, ovl.fmt.RXY.r1,
14131 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14132 ovl.fmt.RXY.dl2,
14133 ovl.fmt.RXY.dh2); goto ok;
14134 case 0xe30000000096ULL: s390_format_RXY_RRRD(s390_irgen_ML, ovl.fmt.RXY.r1,
14135 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14136 ovl.fmt.RXY.dl2,
14137 ovl.fmt.RXY.dh2); goto ok;
14138 case 0xe30000000097ULL: s390_format_RXY_RRRD(s390_irgen_DL, ovl.fmt.RXY.r1,
14139 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14140 ovl.fmt.RXY.dl2,
14141 ovl.fmt.RXY.dh2); goto ok;
14142 case 0xe30000000098ULL: s390_format_RXY_RRRD(s390_irgen_ALC, ovl.fmt.RXY.r1,
14143 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14144 ovl.fmt.RXY.dl2,
14145 ovl.fmt.RXY.dh2); goto ok;
14146 case 0xe30000000099ULL: s390_format_RXY_RRRD(s390_irgen_SLB, ovl.fmt.RXY.r1,
14147 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14148 ovl.fmt.RXY.dl2,
14149 ovl.fmt.RXY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000014150 case 0xe3000000009cULL: /* LLGTAT */ goto unimplemented;
14151 case 0xe3000000009dULL: /* LLGFAT */ goto unimplemented;
14152 case 0xe3000000009fULL: /* LAT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000014153 case 0xe300000000c0ULL: s390_format_RXY_RRRD(s390_irgen_LBH, ovl.fmt.RXY.r1,
14154 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14155 ovl.fmt.RXY.dl2,
14156 ovl.fmt.RXY.dh2); goto ok;
14157 case 0xe300000000c2ULL: s390_format_RXY_RRRD(s390_irgen_LLCH, ovl.fmt.RXY.r1,
14158 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14159 ovl.fmt.RXY.dl2,
14160 ovl.fmt.RXY.dh2); goto ok;
14161 case 0xe300000000c3ULL: s390_format_RXY_RRRD(s390_irgen_STCH, ovl.fmt.RXY.r1,
14162 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14163 ovl.fmt.RXY.dl2,
14164 ovl.fmt.RXY.dh2); goto ok;
14165 case 0xe300000000c4ULL: s390_format_RXY_RRRD(s390_irgen_LHH, ovl.fmt.RXY.r1,
14166 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14167 ovl.fmt.RXY.dl2,
14168 ovl.fmt.RXY.dh2); goto ok;
14169 case 0xe300000000c6ULL: s390_format_RXY_RRRD(s390_irgen_LLHH, ovl.fmt.RXY.r1,
14170 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14171 ovl.fmt.RXY.dl2,
14172 ovl.fmt.RXY.dh2); goto ok;
14173 case 0xe300000000c7ULL: s390_format_RXY_RRRD(s390_irgen_STHH, ovl.fmt.RXY.r1,
14174 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14175 ovl.fmt.RXY.dl2,
14176 ovl.fmt.RXY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000014177 case 0xe300000000c8ULL: /* LFHAT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000014178 case 0xe300000000caULL: s390_format_RXY_RRRD(s390_irgen_LFH, ovl.fmt.RXY.r1,
14179 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14180 ovl.fmt.RXY.dl2,
14181 ovl.fmt.RXY.dh2); goto ok;
14182 case 0xe300000000cbULL: s390_format_RXY_RRRD(s390_irgen_STFH, ovl.fmt.RXY.r1,
14183 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14184 ovl.fmt.RXY.dl2,
14185 ovl.fmt.RXY.dh2); goto ok;
14186 case 0xe300000000cdULL: s390_format_RXY_RRRD(s390_irgen_CHF, ovl.fmt.RXY.r1,
14187 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14188 ovl.fmt.RXY.dl2,
14189 ovl.fmt.RXY.dh2); goto ok;
14190 case 0xe300000000cfULL: s390_format_RXY_RRRD(s390_irgen_CLHF, ovl.fmt.RXY.r1,
14191 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14192 ovl.fmt.RXY.dl2,
14193 ovl.fmt.RXY.dh2); goto ok;
14194 case 0xeb0000000004ULL: s390_format_RSY_RRRD(s390_irgen_LMG, ovl.fmt.RSY.r1,
14195 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14196 ovl.fmt.RSY.dl2,
14197 ovl.fmt.RSY.dh2); goto ok;
14198 case 0xeb000000000aULL: s390_format_RSY_RRRD(s390_irgen_SRAG, ovl.fmt.RSY.r1,
14199 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14200 ovl.fmt.RSY.dl2,
14201 ovl.fmt.RSY.dh2); goto ok;
14202 case 0xeb000000000bULL: s390_format_RSY_RRRD(s390_irgen_SLAG, ovl.fmt.RSY.r1,
14203 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14204 ovl.fmt.RSY.dl2,
14205 ovl.fmt.RSY.dh2); goto ok;
14206 case 0xeb000000000cULL: s390_format_RSY_RRRD(s390_irgen_SRLG, ovl.fmt.RSY.r1,
14207 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14208 ovl.fmt.RSY.dl2,
14209 ovl.fmt.RSY.dh2); goto ok;
14210 case 0xeb000000000dULL: s390_format_RSY_RRRD(s390_irgen_SLLG, ovl.fmt.RSY.r1,
14211 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14212 ovl.fmt.RSY.dl2,
14213 ovl.fmt.RSY.dh2); goto ok;
14214 case 0xeb000000000fULL: /* TRACG */ goto unimplemented;
14215 case 0xeb0000000014ULL: s390_format_RSY_RRRD(s390_irgen_CSY, ovl.fmt.RSY.r1,
14216 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14217 ovl.fmt.RSY.dl2,
14218 ovl.fmt.RSY.dh2); goto ok;
14219 case 0xeb000000001cULL: s390_format_RSY_RRRD(s390_irgen_RLLG, ovl.fmt.RSY.r1,
14220 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14221 ovl.fmt.RSY.dl2,
14222 ovl.fmt.RSY.dh2); goto ok;
14223 case 0xeb000000001dULL: s390_format_RSY_RRRD(s390_irgen_RLL, ovl.fmt.RSY.r1,
14224 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14225 ovl.fmt.RSY.dl2,
14226 ovl.fmt.RSY.dh2); goto ok;
14227 case 0xeb0000000020ULL: s390_format_RSY_RURD(s390_irgen_CLMH, ovl.fmt.RSY.r1,
14228 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14229 ovl.fmt.RSY.dl2,
14230 ovl.fmt.RSY.dh2); goto ok;
14231 case 0xeb0000000021ULL: s390_format_RSY_RURD(s390_irgen_CLMY, ovl.fmt.RSY.r1,
14232 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14233 ovl.fmt.RSY.dl2,
14234 ovl.fmt.RSY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000014235 case 0xeb0000000023ULL: /* CLT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000014236 case 0xeb0000000024ULL: s390_format_RSY_RRRD(s390_irgen_STMG, ovl.fmt.RSY.r1,
14237 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14238 ovl.fmt.RSY.dl2,
14239 ovl.fmt.RSY.dh2); goto ok;
14240 case 0xeb0000000025ULL: /* STCTG */ goto unimplemented;
14241 case 0xeb0000000026ULL: s390_format_RSY_RRRD(s390_irgen_STMH, ovl.fmt.RSY.r1,
14242 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14243 ovl.fmt.RSY.dl2,
14244 ovl.fmt.RSY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000014245 case 0xeb000000002bULL: /* CLGT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000014246 case 0xeb000000002cULL: s390_format_RSY_RURD(s390_irgen_STCMH,
14247 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
14248 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
14249 ovl.fmt.RSY.dh2); goto ok;
14250 case 0xeb000000002dULL: s390_format_RSY_RURD(s390_irgen_STCMY,
14251 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
14252 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
14253 ovl.fmt.RSY.dh2); goto ok;
14254 case 0xeb000000002fULL: /* LCTLG */ goto unimplemented;
14255 case 0xeb0000000030ULL: s390_format_RSY_RRRD(s390_irgen_CSG, ovl.fmt.RSY.r1,
14256 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14257 ovl.fmt.RSY.dl2,
14258 ovl.fmt.RSY.dh2); goto ok;
florian448cbba2012-06-06 02:26:01 +000014259 case 0xeb0000000031ULL: s390_format_RSY_RRRD(s390_irgen_CDSY, ovl.fmt.RSY.r1,
14260 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14261 ovl.fmt.RSY.dl2,
14262 ovl.fmt.RSY.dh2); goto ok;
14263 case 0xeb000000003eULL: s390_format_RSY_RRRD(s390_irgen_CDSG, ovl.fmt.RSY.r1,
14264 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14265 ovl.fmt.RSY.dl2,
14266 ovl.fmt.RSY.dh2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014267 case 0xeb0000000044ULL: s390_format_RSY_RRRD(s390_irgen_BXHG, ovl.fmt.RSY.r1,
14268 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14269 ovl.fmt.RSY.dl2,
14270 ovl.fmt.RSY.dh2); goto ok;
14271 case 0xeb0000000045ULL: s390_format_RSY_RRRD(s390_irgen_BXLEG,
14272 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
14273 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
14274 ovl.fmt.RSY.dh2); goto ok;
florian8c88cb62012-08-26 18:58:13 +000014275 case 0xeb000000004cULL: s390_format_RSY_RRRD(s390_irgen_ECAG, ovl.fmt.RSY.r1,
14276 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14277 ovl.fmt.RSY.dl2,
14278 ovl.fmt.RSY.dh2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014279 case 0xeb0000000051ULL: s390_format_SIY_URD(s390_irgen_TMY, ovl.fmt.SIY.i2,
14280 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
14281 ovl.fmt.SIY.dh1); goto ok;
14282 case 0xeb0000000052ULL: s390_format_SIY_URD(s390_irgen_MVIY, ovl.fmt.SIY.i2,
14283 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
14284 ovl.fmt.SIY.dh1); goto ok;
14285 case 0xeb0000000054ULL: s390_format_SIY_URD(s390_irgen_NIY, ovl.fmt.SIY.i2,
14286 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
14287 ovl.fmt.SIY.dh1); goto ok;
14288 case 0xeb0000000055ULL: s390_format_SIY_URD(s390_irgen_CLIY, ovl.fmt.SIY.i2,
14289 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
14290 ovl.fmt.SIY.dh1); goto ok;
14291 case 0xeb0000000056ULL: s390_format_SIY_URD(s390_irgen_OIY, ovl.fmt.SIY.i2,
14292 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
14293 ovl.fmt.SIY.dh1); goto ok;
14294 case 0xeb0000000057ULL: s390_format_SIY_URD(s390_irgen_XIY, ovl.fmt.SIY.i2,
14295 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
14296 ovl.fmt.SIY.dh1); goto ok;
14297 case 0xeb000000006aULL: s390_format_SIY_IRD(s390_irgen_ASI, ovl.fmt.SIY.i2,
14298 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
14299 ovl.fmt.SIY.dh1); goto ok;
14300 case 0xeb000000006eULL: s390_format_SIY_IRD(s390_irgen_ALSI, ovl.fmt.SIY.i2,
14301 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
14302 ovl.fmt.SIY.dh1); goto ok;
14303 case 0xeb000000007aULL: s390_format_SIY_IRD(s390_irgen_AGSI, ovl.fmt.SIY.i2,
14304 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
14305 ovl.fmt.SIY.dh1); goto ok;
14306 case 0xeb000000007eULL: s390_format_SIY_IRD(s390_irgen_ALGSI, ovl.fmt.SIY.i2,
14307 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
14308 ovl.fmt.SIY.dh1); goto ok;
14309 case 0xeb0000000080ULL: s390_format_RSY_RURD(s390_irgen_ICMH, ovl.fmt.RSY.r1,
14310 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14311 ovl.fmt.RSY.dl2,
14312 ovl.fmt.RSY.dh2); goto ok;
14313 case 0xeb0000000081ULL: s390_format_RSY_RURD(s390_irgen_ICMY, ovl.fmt.RSY.r1,
14314 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14315 ovl.fmt.RSY.dl2,
14316 ovl.fmt.RSY.dh2); goto ok;
14317 case 0xeb000000008eULL: /* MVCLU */ goto unimplemented;
14318 case 0xeb000000008fULL: /* CLCLU */ goto unimplemented;
14319 case 0xeb0000000090ULL: s390_format_RSY_RRRD(s390_irgen_STMY, ovl.fmt.RSY.r1,
14320 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14321 ovl.fmt.RSY.dl2,
14322 ovl.fmt.RSY.dh2); goto ok;
14323 case 0xeb0000000096ULL: s390_format_RSY_RRRD(s390_irgen_LMH, ovl.fmt.RSY.r1,
14324 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14325 ovl.fmt.RSY.dl2,
14326 ovl.fmt.RSY.dh2); goto ok;
14327 case 0xeb0000000098ULL: s390_format_RSY_RRRD(s390_irgen_LMY, ovl.fmt.RSY.r1,
14328 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14329 ovl.fmt.RSY.dl2,
14330 ovl.fmt.RSY.dh2); goto ok;
14331 case 0xeb000000009aULL: s390_format_RSY_AARD(s390_irgen_LAMY, ovl.fmt.RSY.r1,
14332 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14333 ovl.fmt.RSY.dl2,
14334 ovl.fmt.RSY.dh2); goto ok;
14335 case 0xeb000000009bULL: s390_format_RSY_AARD(s390_irgen_STAMY,
14336 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
14337 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
14338 ovl.fmt.RSY.dh2); goto ok;
14339 case 0xeb00000000c0ULL: /* TP */ goto unimplemented;
14340 case 0xeb00000000dcULL: s390_format_RSY_RRRD(s390_irgen_SRAK, ovl.fmt.RSY.r1,
14341 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14342 ovl.fmt.RSY.dl2,
14343 ovl.fmt.RSY.dh2); goto ok;
14344 case 0xeb00000000ddULL: s390_format_RSY_RRRD(s390_irgen_SLAK, ovl.fmt.RSY.r1,
14345 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14346 ovl.fmt.RSY.dl2,
14347 ovl.fmt.RSY.dh2); goto ok;
14348 case 0xeb00000000deULL: s390_format_RSY_RRRD(s390_irgen_SRLK, ovl.fmt.RSY.r1,
14349 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14350 ovl.fmt.RSY.dl2,
14351 ovl.fmt.RSY.dh2); goto ok;
14352 case 0xeb00000000dfULL: s390_format_RSY_RRRD(s390_irgen_SLLK, ovl.fmt.RSY.r1,
14353 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14354 ovl.fmt.RSY.dl2,
14355 ovl.fmt.RSY.dh2); goto ok;
sewardjd7bde722011-04-05 13:19:33 +000014356 case 0xeb00000000e2ULL: s390_format_RSY_RDRM(s390_irgen_LOCG, ovl.fmt.RSY.r1,
14357 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14358 ovl.fmt.RSY.dl2,
14359 ovl.fmt.RSY.dh2,
14360 S390_XMNM_LOCG); goto ok;
14361 case 0xeb00000000e3ULL: s390_format_RSY_RDRM(s390_irgen_STOCG,
14362 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
14363 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
14364 ovl.fmt.RSY.dh2,
14365 S390_XMNM_STOCG); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014366 case 0xeb00000000e4ULL: s390_format_RSY_RRRD(s390_irgen_LANG, ovl.fmt.RSY.r1,
14367 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14368 ovl.fmt.RSY.dl2,
14369 ovl.fmt.RSY.dh2); goto ok;
14370 case 0xeb00000000e6ULL: s390_format_RSY_RRRD(s390_irgen_LAOG, ovl.fmt.RSY.r1,
14371 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14372 ovl.fmt.RSY.dl2,
14373 ovl.fmt.RSY.dh2); goto ok;
14374 case 0xeb00000000e7ULL: s390_format_RSY_RRRD(s390_irgen_LAXG, ovl.fmt.RSY.r1,
14375 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14376 ovl.fmt.RSY.dl2,
14377 ovl.fmt.RSY.dh2); goto ok;
14378 case 0xeb00000000e8ULL: s390_format_RSY_RRRD(s390_irgen_LAAG, ovl.fmt.RSY.r1,
14379 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14380 ovl.fmt.RSY.dl2,
14381 ovl.fmt.RSY.dh2); goto ok;
14382 case 0xeb00000000eaULL: s390_format_RSY_RRRD(s390_irgen_LAALG,
14383 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
14384 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
14385 ovl.fmt.RSY.dh2); goto ok;
sewardjd7bde722011-04-05 13:19:33 +000014386 case 0xeb00000000f2ULL: s390_format_RSY_RDRM(s390_irgen_LOC, ovl.fmt.RSY.r1,
14387 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14388 ovl.fmt.RSY.dl2,
14389 ovl.fmt.RSY.dh2, S390_XMNM_LOC);
14390 goto ok;
14391 case 0xeb00000000f3ULL: s390_format_RSY_RDRM(s390_irgen_STOC, ovl.fmt.RSY.r1,
14392 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14393 ovl.fmt.RSY.dl2,
14394 ovl.fmt.RSY.dh2,
14395 S390_XMNM_STOC); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014396 case 0xeb00000000f4ULL: s390_format_RSY_RRRD(s390_irgen_LAN, ovl.fmt.RSY.r1,
14397 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14398 ovl.fmt.RSY.dl2,
14399 ovl.fmt.RSY.dh2); goto ok;
14400 case 0xeb00000000f6ULL: s390_format_RSY_RRRD(s390_irgen_LAO, ovl.fmt.RSY.r1,
14401 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14402 ovl.fmt.RSY.dl2,
14403 ovl.fmt.RSY.dh2); goto ok;
14404 case 0xeb00000000f7ULL: s390_format_RSY_RRRD(s390_irgen_LAX, ovl.fmt.RSY.r1,
14405 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14406 ovl.fmt.RSY.dl2,
14407 ovl.fmt.RSY.dh2); goto ok;
14408 case 0xeb00000000f8ULL: s390_format_RSY_RRRD(s390_irgen_LAA, ovl.fmt.RSY.r1,
14409 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14410 ovl.fmt.RSY.dl2,
14411 ovl.fmt.RSY.dh2); goto ok;
14412 case 0xeb00000000faULL: s390_format_RSY_RRRD(s390_irgen_LAAL, ovl.fmt.RSY.r1,
14413 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14414 ovl.fmt.RSY.dl2,
14415 ovl.fmt.RSY.dh2); goto ok;
14416 case 0xec0000000044ULL: s390_format_RIE_RRP(s390_irgen_BRXHG, ovl.fmt.RIE.r1,
14417 ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
14418 goto ok;
14419 case 0xec0000000045ULL: s390_format_RIE_RRP(s390_irgen_BRXLG, ovl.fmt.RIE.r1,
14420 ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
14421 goto ok;
14422 case 0xec0000000051ULL: /* RISBLG */ goto unimplemented;
14423 case 0xec0000000054ULL: s390_format_RIE_RRUUU(s390_irgen_RNSBG,
14424 ovl.fmt.RIE_RRUUU.r1,
14425 ovl.fmt.RIE_RRUUU.r2,
14426 ovl.fmt.RIE_RRUUU.i3,
14427 ovl.fmt.RIE_RRUUU.i4,
14428 ovl.fmt.RIE_RRUUU.i5);
14429 goto ok;
14430 case 0xec0000000055ULL: s390_format_RIE_RRUUU(s390_irgen_RISBG,
14431 ovl.fmt.RIE_RRUUU.r1,
14432 ovl.fmt.RIE_RRUUU.r2,
14433 ovl.fmt.RIE_RRUUU.i3,
14434 ovl.fmt.RIE_RRUUU.i4,
14435 ovl.fmt.RIE_RRUUU.i5);
14436 goto ok;
14437 case 0xec0000000056ULL: s390_format_RIE_RRUUU(s390_irgen_ROSBG,
14438 ovl.fmt.RIE_RRUUU.r1,
14439 ovl.fmt.RIE_RRUUU.r2,
14440 ovl.fmt.RIE_RRUUU.i3,
14441 ovl.fmt.RIE_RRUUU.i4,
14442 ovl.fmt.RIE_RRUUU.i5);
14443 goto ok;
14444 case 0xec0000000057ULL: s390_format_RIE_RRUUU(s390_irgen_RXSBG,
14445 ovl.fmt.RIE_RRUUU.r1,
14446 ovl.fmt.RIE_RRUUU.r2,
14447 ovl.fmt.RIE_RRUUU.i3,
14448 ovl.fmt.RIE_RRUUU.i4,
14449 ovl.fmt.RIE_RRUUU.i5);
14450 goto ok;
florian2289cd42012-12-05 04:23:42 +000014451 case 0xec0000000059ULL: /* RISBGN */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000014452 case 0xec000000005dULL: /* RISBHG */ goto unimplemented;
14453 case 0xec0000000064ULL: s390_format_RIE_RRPU(s390_irgen_CGRJ,
14454 ovl.fmt.RIE_RRPU.r1,
14455 ovl.fmt.RIE_RRPU.r2,
14456 ovl.fmt.RIE_RRPU.i4,
14457 ovl.fmt.RIE_RRPU.m3); goto ok;
14458 case 0xec0000000065ULL: s390_format_RIE_RRPU(s390_irgen_CLGRJ,
14459 ovl.fmt.RIE_RRPU.r1,
14460 ovl.fmt.RIE_RRPU.r2,
14461 ovl.fmt.RIE_RRPU.i4,
14462 ovl.fmt.RIE_RRPU.m3); goto ok;
14463 case 0xec0000000070ULL: /* CGIT */ goto unimplemented;
14464 case 0xec0000000071ULL: /* CLGIT */ goto unimplemented;
14465 case 0xec0000000072ULL: /* CIT */ goto unimplemented;
14466 case 0xec0000000073ULL: /* CLFIT */ goto unimplemented;
14467 case 0xec0000000076ULL: s390_format_RIE_RRPU(s390_irgen_CRJ,
14468 ovl.fmt.RIE_RRPU.r1,
14469 ovl.fmt.RIE_RRPU.r2,
14470 ovl.fmt.RIE_RRPU.i4,
14471 ovl.fmt.RIE_RRPU.m3); goto ok;
14472 case 0xec0000000077ULL: s390_format_RIE_RRPU(s390_irgen_CLRJ,
14473 ovl.fmt.RIE_RRPU.r1,
14474 ovl.fmt.RIE_RRPU.r2,
14475 ovl.fmt.RIE_RRPU.i4,
14476 ovl.fmt.RIE_RRPU.m3); goto ok;
14477 case 0xec000000007cULL: s390_format_RIE_RUPI(s390_irgen_CGIJ,
14478 ovl.fmt.RIEv3.r1,
14479 ovl.fmt.RIEv3.m3,
14480 ovl.fmt.RIEv3.i4,
14481 ovl.fmt.RIEv3.i2); goto ok;
14482 case 0xec000000007dULL: s390_format_RIE_RUPU(s390_irgen_CLGIJ,
14483 ovl.fmt.RIEv3.r1,
14484 ovl.fmt.RIEv3.m3,
14485 ovl.fmt.RIEv3.i4,
14486 ovl.fmt.RIEv3.i2); goto ok;
14487 case 0xec000000007eULL: s390_format_RIE_RUPI(s390_irgen_CIJ,
14488 ovl.fmt.RIEv3.r1,
14489 ovl.fmt.RIEv3.m3,
14490 ovl.fmt.RIEv3.i4,
14491 ovl.fmt.RIEv3.i2); goto ok;
14492 case 0xec000000007fULL: s390_format_RIE_RUPU(s390_irgen_CLIJ,
14493 ovl.fmt.RIEv3.r1,
14494 ovl.fmt.RIEv3.m3,
14495 ovl.fmt.RIEv3.i4,
14496 ovl.fmt.RIEv3.i2); goto ok;
14497 case 0xec00000000d8ULL: s390_format_RIE_RRI0(s390_irgen_AHIK, ovl.fmt.RIE.r1,
14498 ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
14499 goto ok;
14500 case 0xec00000000d9ULL: s390_format_RIE_RRI0(s390_irgen_AGHIK,
14501 ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
14502 ovl.fmt.RIE.i2); goto ok;
14503 case 0xec00000000daULL: s390_format_RIE_RRI0(s390_irgen_ALHSIK,
14504 ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
14505 ovl.fmt.RIE.i2); goto ok;
14506 case 0xec00000000dbULL: s390_format_RIE_RRI0(s390_irgen_ALGHSIK,
14507 ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
14508 ovl.fmt.RIE.i2); goto ok;
14509 case 0xec00000000e4ULL: s390_format_RRS(s390_irgen_CGRB, ovl.fmt.RRS.r1,
14510 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
14511 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
14512 goto ok;
14513 case 0xec00000000e5ULL: s390_format_RRS(s390_irgen_CLGRB, ovl.fmt.RRS.r1,
14514 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
14515 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
14516 goto ok;
14517 case 0xec00000000f6ULL: s390_format_RRS(s390_irgen_CRB, ovl.fmt.RRS.r1,
14518 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
14519 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
14520 goto ok;
14521 case 0xec00000000f7ULL: s390_format_RRS(s390_irgen_CLRB, ovl.fmt.RRS.r1,
14522 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
14523 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
14524 goto ok;
14525 case 0xec00000000fcULL: s390_format_RIS_RURDI(s390_irgen_CGIB,
14526 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
14527 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
14528 ovl.fmt.RIS.i2); goto ok;
14529 case 0xec00000000fdULL: s390_format_RIS_RURDU(s390_irgen_CLGIB,
14530 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
14531 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
14532 ovl.fmt.RIS.i2); goto ok;
14533 case 0xec00000000feULL: s390_format_RIS_RURDI(s390_irgen_CIB, ovl.fmt.RIS.r1,
14534 ovl.fmt.RIS.m3, ovl.fmt.RIS.b4,
14535 ovl.fmt.RIS.d4,
14536 ovl.fmt.RIS.i2); goto ok;
14537 case 0xec00000000ffULL: s390_format_RIS_RURDU(s390_irgen_CLIB,
14538 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
14539 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
14540 ovl.fmt.RIS.i2); goto ok;
14541 case 0xed0000000004ULL: s390_format_RXE_FRRD(s390_irgen_LDEB, ovl.fmt.RXE.r1,
14542 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14543 ovl.fmt.RXE.d2); goto ok;
14544 case 0xed0000000005ULL: s390_format_RXE_FRRD(s390_irgen_LXDB, ovl.fmt.RXE.r1,
14545 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14546 ovl.fmt.RXE.d2); goto ok;
14547 case 0xed0000000006ULL: s390_format_RXE_FRRD(s390_irgen_LXEB, ovl.fmt.RXE.r1,
14548 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14549 ovl.fmt.RXE.d2); goto ok;
14550 case 0xed0000000007ULL: /* MXDB */ goto unimplemented;
14551 case 0xed0000000008ULL: /* KEB */ goto unimplemented;
14552 case 0xed0000000009ULL: s390_format_RXE_FRRD(s390_irgen_CEB, ovl.fmt.RXE.r1,
14553 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14554 ovl.fmt.RXE.d2); goto ok;
14555 case 0xed000000000aULL: s390_format_RXE_FRRD(s390_irgen_AEB, ovl.fmt.RXE.r1,
14556 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14557 ovl.fmt.RXE.d2); goto ok;
14558 case 0xed000000000bULL: s390_format_RXE_FRRD(s390_irgen_SEB, ovl.fmt.RXE.r1,
14559 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14560 ovl.fmt.RXE.d2); goto ok;
14561 case 0xed000000000cULL: /* MDEB */ goto unimplemented;
14562 case 0xed000000000dULL: s390_format_RXE_FRRD(s390_irgen_DEB, ovl.fmt.RXE.r1,
14563 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14564 ovl.fmt.RXE.d2); goto ok;
14565 case 0xed000000000eULL: s390_format_RXF_FRRDF(s390_irgen_MAEB,
14566 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
14567 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
14568 ovl.fmt.RXF.r1); goto ok;
14569 case 0xed000000000fULL: s390_format_RXF_FRRDF(s390_irgen_MSEB,
14570 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
14571 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
14572 ovl.fmt.RXF.r1); goto ok;
14573 case 0xed0000000010ULL: s390_format_RXE_FRRD(s390_irgen_TCEB, ovl.fmt.RXE.r1,
14574 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14575 ovl.fmt.RXE.d2); goto ok;
14576 case 0xed0000000011ULL: s390_format_RXE_FRRD(s390_irgen_TCDB, ovl.fmt.RXE.r1,
14577 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14578 ovl.fmt.RXE.d2); goto ok;
14579 case 0xed0000000012ULL: s390_format_RXE_FRRD(s390_irgen_TCXB, ovl.fmt.RXE.r1,
14580 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14581 ovl.fmt.RXE.d2); goto ok;
14582 case 0xed0000000014ULL: s390_format_RXE_FRRD(s390_irgen_SQEB, ovl.fmt.RXE.r1,
14583 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14584 ovl.fmt.RXE.d2); goto ok;
14585 case 0xed0000000015ULL: s390_format_RXE_FRRD(s390_irgen_SQDB, ovl.fmt.RXE.r1,
14586 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14587 ovl.fmt.RXE.d2); goto ok;
14588 case 0xed0000000017ULL: s390_format_RXE_FRRD(s390_irgen_MEEB, ovl.fmt.RXE.r1,
14589 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14590 ovl.fmt.RXE.d2); goto ok;
14591 case 0xed0000000018ULL: /* KDB */ goto unimplemented;
14592 case 0xed0000000019ULL: s390_format_RXE_FRRD(s390_irgen_CDB, ovl.fmt.RXE.r1,
14593 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14594 ovl.fmt.RXE.d2); goto ok;
14595 case 0xed000000001aULL: s390_format_RXE_FRRD(s390_irgen_ADB, ovl.fmt.RXE.r1,
14596 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14597 ovl.fmt.RXE.d2); goto ok;
14598 case 0xed000000001bULL: s390_format_RXE_FRRD(s390_irgen_SDB, ovl.fmt.RXE.r1,
14599 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14600 ovl.fmt.RXE.d2); goto ok;
14601 case 0xed000000001cULL: s390_format_RXE_FRRD(s390_irgen_MDB, ovl.fmt.RXE.r1,
14602 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14603 ovl.fmt.RXE.d2); goto ok;
14604 case 0xed000000001dULL: s390_format_RXE_FRRD(s390_irgen_DDB, ovl.fmt.RXE.r1,
14605 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14606 ovl.fmt.RXE.d2); goto ok;
14607 case 0xed000000001eULL: s390_format_RXF_FRRDF(s390_irgen_MADB,
14608 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
14609 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
14610 ovl.fmt.RXF.r1); goto ok;
14611 case 0xed000000001fULL: s390_format_RXF_FRRDF(s390_irgen_MSDB,
14612 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
14613 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
14614 ovl.fmt.RXF.r1); goto ok;
14615 case 0xed0000000024ULL: /* LDE */ goto unimplemented;
14616 case 0xed0000000025ULL: /* LXD */ goto unimplemented;
14617 case 0xed0000000026ULL: /* LXE */ goto unimplemented;
14618 case 0xed000000002eULL: /* MAE */ goto unimplemented;
14619 case 0xed000000002fULL: /* MSE */ goto unimplemented;
14620 case 0xed0000000034ULL: /* SQE */ goto unimplemented;
14621 case 0xed0000000035ULL: /* SQD */ goto unimplemented;
14622 case 0xed0000000037ULL: /* MEE */ goto unimplemented;
14623 case 0xed0000000038ULL: /* MAYL */ goto unimplemented;
14624 case 0xed0000000039ULL: /* MYL */ goto unimplemented;
14625 case 0xed000000003aULL: /* MAY */ goto unimplemented;
14626 case 0xed000000003bULL: /* MY */ goto unimplemented;
14627 case 0xed000000003cULL: /* MAYH */ goto unimplemented;
14628 case 0xed000000003dULL: /* MYH */ goto unimplemented;
14629 case 0xed000000003eULL: /* MAD */ goto unimplemented;
14630 case 0xed000000003fULL: /* MSD */ goto unimplemented;
14631 case 0xed0000000040ULL: /* SLDT */ goto unimplemented;
14632 case 0xed0000000041ULL: /* SRDT */ goto unimplemented;
14633 case 0xed0000000048ULL: /* SLXT */ goto unimplemented;
14634 case 0xed0000000049ULL: /* SRXT */ goto unimplemented;
14635 case 0xed0000000050ULL: /* TDCET */ goto unimplemented;
14636 case 0xed0000000051ULL: /* TDGET */ goto unimplemented;
14637 case 0xed0000000054ULL: /* TDCDT */ goto unimplemented;
14638 case 0xed0000000055ULL: /* TDGDT */ goto unimplemented;
14639 case 0xed0000000058ULL: /* TDCXT */ goto unimplemented;
14640 case 0xed0000000059ULL: /* TDGXT */ goto unimplemented;
14641 case 0xed0000000064ULL: s390_format_RXY_FRRD(s390_irgen_LEY, ovl.fmt.RXY.r1,
14642 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14643 ovl.fmt.RXY.dl2,
14644 ovl.fmt.RXY.dh2); goto ok;
14645 case 0xed0000000065ULL: s390_format_RXY_FRRD(s390_irgen_LDY, ovl.fmt.RXY.r1,
14646 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14647 ovl.fmt.RXY.dl2,
14648 ovl.fmt.RXY.dh2); goto ok;
14649 case 0xed0000000066ULL: s390_format_RXY_FRRD(s390_irgen_STEY, ovl.fmt.RXY.r1,
14650 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14651 ovl.fmt.RXY.dl2,
14652 ovl.fmt.RXY.dh2); goto ok;
14653 case 0xed0000000067ULL: s390_format_RXY_FRRD(s390_irgen_STDY, ovl.fmt.RXY.r1,
14654 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14655 ovl.fmt.RXY.dl2,
14656 ovl.fmt.RXY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000014657 case 0xed00000000a8ULL: /* CZDT */ goto unimplemented;
14658 case 0xed00000000a9ULL: /* CZXT */ goto unimplemented;
14659 case 0xed00000000aaULL: /* CDZT */ goto unimplemented;
14660 case 0xed00000000abULL: /* CXZT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000014661 }
14662
14663 switch (((ovl.value >> 16) & 0xff0f00000000ULL) >> 32) {
14664 case 0xc000ULL: s390_format_RIL_RP(s390_irgen_LARL, ovl.fmt.RIL.r1,
14665 ovl.fmt.RIL.i2); goto ok;
14666 case 0xc001ULL: s390_format_RIL_RI(s390_irgen_LGFI, ovl.fmt.RIL.r1,
14667 ovl.fmt.RIL.i2); goto ok;
14668 case 0xc004ULL: s390_format_RIL(s390_irgen_BRCL, ovl.fmt.RIL.r1,
14669 ovl.fmt.RIL.i2); goto ok;
14670 case 0xc005ULL: s390_format_RIL_RP(s390_irgen_BRASL, ovl.fmt.RIL.r1,
14671 ovl.fmt.RIL.i2); goto ok;
14672 case 0xc006ULL: s390_format_RIL_RU(s390_irgen_XIHF, ovl.fmt.RIL.r1,
14673 ovl.fmt.RIL.i2); goto ok;
14674 case 0xc007ULL: s390_format_RIL_RU(s390_irgen_XILF, ovl.fmt.RIL.r1,
14675 ovl.fmt.RIL.i2); goto ok;
14676 case 0xc008ULL: s390_format_RIL_RU(s390_irgen_IIHF, ovl.fmt.RIL.r1,
14677 ovl.fmt.RIL.i2); goto ok;
14678 case 0xc009ULL: s390_format_RIL_RU(s390_irgen_IILF, ovl.fmt.RIL.r1,
14679 ovl.fmt.RIL.i2); goto ok;
14680 case 0xc00aULL: s390_format_RIL_RU(s390_irgen_NIHF, ovl.fmt.RIL.r1,
14681 ovl.fmt.RIL.i2); goto ok;
14682 case 0xc00bULL: s390_format_RIL_RU(s390_irgen_NILF, ovl.fmt.RIL.r1,
14683 ovl.fmt.RIL.i2); goto ok;
14684 case 0xc00cULL: s390_format_RIL_RU(s390_irgen_OIHF, ovl.fmt.RIL.r1,
14685 ovl.fmt.RIL.i2); goto ok;
14686 case 0xc00dULL: s390_format_RIL_RU(s390_irgen_OILF, ovl.fmt.RIL.r1,
14687 ovl.fmt.RIL.i2); goto ok;
14688 case 0xc00eULL: s390_format_RIL_RU(s390_irgen_LLIHF, ovl.fmt.RIL.r1,
14689 ovl.fmt.RIL.i2); goto ok;
14690 case 0xc00fULL: s390_format_RIL_RU(s390_irgen_LLILF, ovl.fmt.RIL.r1,
14691 ovl.fmt.RIL.i2); goto ok;
14692 case 0xc200ULL: s390_format_RIL_RI(s390_irgen_MSGFI, ovl.fmt.RIL.r1,
14693 ovl.fmt.RIL.i2); goto ok;
14694 case 0xc201ULL: s390_format_RIL_RI(s390_irgen_MSFI, ovl.fmt.RIL.r1,
14695 ovl.fmt.RIL.i2); goto ok;
14696 case 0xc204ULL: s390_format_RIL_RU(s390_irgen_SLGFI, ovl.fmt.RIL.r1,
14697 ovl.fmt.RIL.i2); goto ok;
14698 case 0xc205ULL: s390_format_RIL_RU(s390_irgen_SLFI, ovl.fmt.RIL.r1,
14699 ovl.fmt.RIL.i2); goto ok;
14700 case 0xc208ULL: s390_format_RIL_RI(s390_irgen_AGFI, ovl.fmt.RIL.r1,
14701 ovl.fmt.RIL.i2); goto ok;
14702 case 0xc209ULL: s390_format_RIL_RI(s390_irgen_AFI, ovl.fmt.RIL.r1,
14703 ovl.fmt.RIL.i2); goto ok;
14704 case 0xc20aULL: s390_format_RIL_RU(s390_irgen_ALGFI, ovl.fmt.RIL.r1,
14705 ovl.fmt.RIL.i2); goto ok;
14706 case 0xc20bULL: s390_format_RIL_RU(s390_irgen_ALFI, ovl.fmt.RIL.r1,
14707 ovl.fmt.RIL.i2); goto ok;
14708 case 0xc20cULL: s390_format_RIL_RI(s390_irgen_CGFI, ovl.fmt.RIL.r1,
14709 ovl.fmt.RIL.i2); goto ok;
14710 case 0xc20dULL: s390_format_RIL_RI(s390_irgen_CFI, ovl.fmt.RIL.r1,
14711 ovl.fmt.RIL.i2); goto ok;
14712 case 0xc20eULL: s390_format_RIL_RU(s390_irgen_CLGFI, ovl.fmt.RIL.r1,
14713 ovl.fmt.RIL.i2); goto ok;
14714 case 0xc20fULL: s390_format_RIL_RU(s390_irgen_CLFI, ovl.fmt.RIL.r1,
14715 ovl.fmt.RIL.i2); goto ok;
14716 case 0xc402ULL: s390_format_RIL_RP(s390_irgen_LLHRL, ovl.fmt.RIL.r1,
14717 ovl.fmt.RIL.i2); goto ok;
14718 case 0xc404ULL: s390_format_RIL_RP(s390_irgen_LGHRL, ovl.fmt.RIL.r1,
14719 ovl.fmt.RIL.i2); goto ok;
14720 case 0xc405ULL: s390_format_RIL_RP(s390_irgen_LHRL, ovl.fmt.RIL.r1,
14721 ovl.fmt.RIL.i2); goto ok;
14722 case 0xc406ULL: s390_format_RIL_RP(s390_irgen_LLGHRL, ovl.fmt.RIL.r1,
14723 ovl.fmt.RIL.i2); goto ok;
14724 case 0xc407ULL: s390_format_RIL_RP(s390_irgen_STHRL, ovl.fmt.RIL.r1,
14725 ovl.fmt.RIL.i2); goto ok;
14726 case 0xc408ULL: s390_format_RIL_RP(s390_irgen_LGRL, ovl.fmt.RIL.r1,
14727 ovl.fmt.RIL.i2); goto ok;
14728 case 0xc40bULL: s390_format_RIL_RP(s390_irgen_STGRL, ovl.fmt.RIL.r1,
14729 ovl.fmt.RIL.i2); goto ok;
14730 case 0xc40cULL: s390_format_RIL_RP(s390_irgen_LGFRL, ovl.fmt.RIL.r1,
14731 ovl.fmt.RIL.i2); goto ok;
14732 case 0xc40dULL: s390_format_RIL_RP(s390_irgen_LRL, ovl.fmt.RIL.r1,
14733 ovl.fmt.RIL.i2); goto ok;
14734 case 0xc40eULL: s390_format_RIL_RP(s390_irgen_LLGFRL, ovl.fmt.RIL.r1,
14735 ovl.fmt.RIL.i2); goto ok;
14736 case 0xc40fULL: s390_format_RIL_RP(s390_irgen_STRL, ovl.fmt.RIL.r1,
14737 ovl.fmt.RIL.i2); goto ok;
14738 case 0xc600ULL: s390_format_RIL_RP(s390_irgen_EXRL, ovl.fmt.RIL.r1,
14739 ovl.fmt.RIL.i2); goto ok;
14740 case 0xc602ULL: s390_format_RIL_UP(s390_irgen_PFDRL, ovl.fmt.RIL.r1,
14741 ovl.fmt.RIL.i2); goto ok;
14742 case 0xc604ULL: s390_format_RIL_RP(s390_irgen_CGHRL, ovl.fmt.RIL.r1,
14743 ovl.fmt.RIL.i2); goto ok;
14744 case 0xc605ULL: s390_format_RIL_RP(s390_irgen_CHRL, ovl.fmt.RIL.r1,
14745 ovl.fmt.RIL.i2); goto ok;
14746 case 0xc606ULL: s390_format_RIL_RP(s390_irgen_CLGHRL, ovl.fmt.RIL.r1,
14747 ovl.fmt.RIL.i2); goto ok;
14748 case 0xc607ULL: s390_format_RIL_RP(s390_irgen_CLHRL, ovl.fmt.RIL.r1,
14749 ovl.fmt.RIL.i2); goto ok;
14750 case 0xc608ULL: s390_format_RIL_RP(s390_irgen_CGRL, ovl.fmt.RIL.r1,
14751 ovl.fmt.RIL.i2); goto ok;
14752 case 0xc60aULL: s390_format_RIL_RP(s390_irgen_CLGRL, ovl.fmt.RIL.r1,
14753 ovl.fmt.RIL.i2); goto ok;
14754 case 0xc60cULL: s390_format_RIL_RP(s390_irgen_CGFRL, ovl.fmt.RIL.r1,
14755 ovl.fmt.RIL.i2); goto ok;
14756 case 0xc60dULL: s390_format_RIL_RP(s390_irgen_CRL, ovl.fmt.RIL.r1,
14757 ovl.fmt.RIL.i2); goto ok;
14758 case 0xc60eULL: s390_format_RIL_RP(s390_irgen_CLGFRL, ovl.fmt.RIL.r1,
14759 ovl.fmt.RIL.i2); goto ok;
14760 case 0xc60fULL: s390_format_RIL_RP(s390_irgen_CLRL, ovl.fmt.RIL.r1,
14761 ovl.fmt.RIL.i2); goto ok;
14762 case 0xc800ULL: /* MVCOS */ goto unimplemented;
14763 case 0xc801ULL: /* ECTG */ goto unimplemented;
14764 case 0xc802ULL: /* CSST */ goto unimplemented;
14765 case 0xc804ULL: /* LPD */ goto unimplemented;
14766 case 0xc805ULL: /* LPDG */ goto unimplemented;
14767 case 0xcc06ULL: /* BRCTH */ goto unimplemented;
14768 case 0xcc08ULL: s390_format_RIL_RI(s390_irgen_AIH, ovl.fmt.RIL.r1,
14769 ovl.fmt.RIL.i2); goto ok;
14770 case 0xcc0aULL: s390_format_RIL_RI(s390_irgen_ALSIH, ovl.fmt.RIL.r1,
14771 ovl.fmt.RIL.i2); goto ok;
14772 case 0xcc0bULL: s390_format_RIL_RI(s390_irgen_ALSIHN, ovl.fmt.RIL.r1,
14773 ovl.fmt.RIL.i2); goto ok;
14774 case 0xcc0dULL: s390_format_RIL_RI(s390_irgen_CIH, ovl.fmt.RIL.r1,
14775 ovl.fmt.RIL.i2); goto ok;
14776 case 0xcc0fULL: s390_format_RIL_RU(s390_irgen_CLIH, ovl.fmt.RIL.r1,
14777 ovl.fmt.RIL.i2); goto ok;
14778 }
14779
14780 switch (((ovl.value >> 16) & 0xff0000000000ULL) >> 40) {
florian2289cd42012-12-05 04:23:42 +000014781 case 0xc5ULL: /* BPRP */ goto unimplemented;
14782 case 0xc7ULL: /* BPP */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000014783 case 0xd0ULL: /* TRTR */ goto unimplemented;
14784 case 0xd1ULL: /* MVN */ goto unimplemented;
14785 case 0xd2ULL: s390_format_SS_L0RDRD(s390_irgen_MVC, ovl.fmt.SS.l,
14786 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
14787 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
14788 case 0xd3ULL: /* MVZ */ goto unimplemented;
14789 case 0xd4ULL: s390_format_SS_L0RDRD(s390_irgen_NC, ovl.fmt.SS.l,
14790 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
14791 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
14792 case 0xd5ULL: s390_format_SS_L0RDRD(s390_irgen_CLC, ovl.fmt.SS.l,
14793 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
14794 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
14795 case 0xd6ULL: s390_format_SS_L0RDRD(s390_irgen_OC, ovl.fmt.SS.l,
14796 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
14797 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
sewardjb63967e2011-03-24 08:50:04 +000014798 case 0xd7ULL:
14799 if (ovl.fmt.SS.b1 == ovl.fmt.SS.b2 && ovl.fmt.SS.d1 == ovl.fmt.SS.d2)
14800 s390_irgen_XC_sameloc(ovl.fmt.SS.l, ovl.fmt.SS.b1, ovl.fmt.SS.d1);
14801 else
14802 s390_format_SS_L0RDRD(s390_irgen_XC, ovl.fmt.SS.l,
14803 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
14804 ovl.fmt.SS.b2, ovl.fmt.SS.d2);
14805 goto ok;
sewardj2019a972011-03-07 16:04:07 +000014806 case 0xd9ULL: /* MVCK */ goto unimplemented;
14807 case 0xdaULL: /* MVCP */ goto unimplemented;
14808 case 0xdbULL: /* MVCS */ goto unimplemented;
florian730448f2012-02-04 17:07:07 +000014809 case 0xdcULL: s390_format_SS_L0RDRD(s390_irgen_TR, ovl.fmt.SS.l,
14810 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
14811 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014812 case 0xddULL: /* TRT */ goto unimplemented;
14813 case 0xdeULL: /* ED */ goto unimplemented;
14814 case 0xdfULL: /* EDMK */ goto unimplemented;
14815 case 0xe1ULL: /* PKU */ goto unimplemented;
14816 case 0xe2ULL: /* UNPKU */ goto unimplemented;
14817 case 0xe8ULL: /* MVCIN */ goto unimplemented;
14818 case 0xe9ULL: /* PKA */ goto unimplemented;
14819 case 0xeaULL: /* UNPKA */ goto unimplemented;
14820 case 0xeeULL: /* PLO */ goto unimplemented;
14821 case 0xefULL: /* LMD */ goto unimplemented;
14822 case 0xf0ULL: /* SRP */ goto unimplemented;
14823 case 0xf1ULL: /* MVO */ goto unimplemented;
14824 case 0xf2ULL: /* PACK */ goto unimplemented;
14825 case 0xf3ULL: /* UNPK */ goto unimplemented;
14826 case 0xf8ULL: /* ZAP */ goto unimplemented;
14827 case 0xf9ULL: /* CP */ goto unimplemented;
14828 case 0xfaULL: /* AP */ goto unimplemented;
14829 case 0xfbULL: /* SP */ goto unimplemented;
14830 case 0xfcULL: /* MP */ goto unimplemented;
14831 case 0xfdULL: /* DP */ goto unimplemented;
14832 }
14833
14834 switch (((ovl.value >> 16) & 0xffff00000000ULL) >> 32) {
14835 case 0xe500ULL: /* LASP */ goto unimplemented;
14836 case 0xe501ULL: /* TPROT */ goto unimplemented;
14837 case 0xe502ULL: /* STRAG */ goto unimplemented;
14838 case 0xe50eULL: /* MVCSK */ goto unimplemented;
14839 case 0xe50fULL: /* MVCDK */ goto unimplemented;
14840 case 0xe544ULL: s390_format_SIL_RDI(s390_irgen_MVHHI, ovl.fmt.SIL.b1,
14841 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14842 goto ok;
14843 case 0xe548ULL: s390_format_SIL_RDI(s390_irgen_MVGHI, ovl.fmt.SIL.b1,
14844 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14845 goto ok;
14846 case 0xe54cULL: s390_format_SIL_RDI(s390_irgen_MVHI, ovl.fmt.SIL.b1,
14847 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14848 goto ok;
14849 case 0xe554ULL: s390_format_SIL_RDI(s390_irgen_CHHSI, ovl.fmt.SIL.b1,
14850 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14851 goto ok;
14852 case 0xe555ULL: s390_format_SIL_RDU(s390_irgen_CLHHSI, ovl.fmt.SIL.b1,
14853 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14854 goto ok;
14855 case 0xe558ULL: s390_format_SIL_RDI(s390_irgen_CGHSI, ovl.fmt.SIL.b1,
14856 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14857 goto ok;
14858 case 0xe559ULL: s390_format_SIL_RDU(s390_irgen_CLGHSI, ovl.fmt.SIL.b1,
14859 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14860 goto ok;
14861 case 0xe55cULL: s390_format_SIL_RDI(s390_irgen_CHSI, ovl.fmt.SIL.b1,
14862 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14863 goto ok;
14864 case 0xe55dULL: s390_format_SIL_RDU(s390_irgen_CLFHSI, ovl.fmt.SIL.b1,
14865 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14866 goto ok;
florian2289cd42012-12-05 04:23:42 +000014867 case 0xe560ULL: /* TBEGIN */ goto unimplemented;
14868 case 0xe561ULL: /* TBEGINC */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000014869 }
14870
14871 return S390_DECODE_UNKNOWN_INSN;
14872
14873ok:
14874 return S390_DECODE_OK;
14875
14876unimplemented:
14877 return S390_DECODE_UNIMPLEMENTED_INSN;
14878}
14879
14880/* Handle "special" instructions. */
14881static s390_decode_t
14882s390_decode_special_and_irgen(UChar *bytes)
14883{
14884 s390_decode_t status = S390_DECODE_OK;
14885
14886 /* Got a "Special" instruction preamble. Which one is it? */
14887 if (bytes[0] == 0x18 && bytes[1] == 0x22 /* lr %r2, %r2 */) {
14888 s390_irgen_client_request();
14889 } else if (bytes[0] == 0x18 && bytes[1] == 0x33 /* lr %r3, %r3 */) {
14890 s390_irgen_guest_NRADDR();
14891 } else if (bytes[0] == 0x18 && bytes[1] == 0x44 /* lr %r4, %r4 */) {
14892 s390_irgen_call_noredir();
florian2245ce92012-08-28 16:49:30 +000014893 } else if (bytes[0] == 0x18 && bytes[1] == 0x55 /* lr %r5, %r5 */) {
14894 vex_inject_ir(irsb, Iend_BE);
14895
14896 /* Invalidate the current insn. The reason is that the IRop we're
14897 injecting here can change. In which case the translation has to
14898 be redone. For ease of handling, we simply invalidate all the
14899 time. */
14900 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART),
14901 mkU64(guest_IA_curr_instr)));
14902 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN),
14903 mkU64(guest_IA_next_instr - guest_IA_curr_instr)));
14904 vassert(guest_IA_next_instr - guest_IA_curr_instr ==
14905 S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE);
14906
14907 put_IA(mkaddr_expr(guest_IA_next_instr));
14908 dis_res->whatNext = Dis_StopHere;
14909 dis_res->jk_StopHere = Ijk_TInval;
sewardj2019a972011-03-07 16:04:07 +000014910 } else {
14911 /* We don't know what it is. */
14912 return S390_DECODE_UNKNOWN_SPECIAL_INSN;
14913 }
14914
14915 dis_res->len = S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE;
14916
14917 return status;
14918}
14919
14920
14921/* Function returns # bytes that were decoded or 0 in case of failure */
florianb4df7682011-07-05 02:09:01 +000014922static UInt
sewardj2019a972011-03-07 16:04:07 +000014923s390_decode_and_irgen(UChar *bytes, UInt insn_length, DisResult *dres)
14924{
14925 s390_decode_t status;
14926
14927 dis_res = dres;
14928
14929 /* Spot the 8-byte preamble: 18ff lr r15,r15
14930 1811 lr r1,r1
14931 1822 lr r2,r2
14932 1833 lr r3,r3 */
14933 if (bytes[ 0] == 0x18 && bytes[ 1] == 0xff && bytes[ 2] == 0x18 &&
14934 bytes[ 3] == 0x11 && bytes[ 4] == 0x18 && bytes[ 5] == 0x22 &&
14935 bytes[ 6] == 0x18 && bytes[ 7] == 0x33) {
14936
14937 /* Handle special instruction that follows that preamble. */
14938 if (0) vex_printf("special function handling...\n");
florian2c8ed942011-08-01 22:07:51 +000014939
14940 insn_length = S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE;
14941 guest_IA_next_instr = guest_IA_curr_instr + insn_length;
14942
14943 status =
14944 s390_decode_special_and_irgen(bytes + S390_SPECIAL_OP_PREAMBLE_SIZE);
sewardj2019a972011-03-07 16:04:07 +000014945 } else {
14946 /* Handle normal instructions. */
14947 switch (insn_length) {
14948 case 2:
14949 status = s390_decode_2byte_and_irgen(bytes);
14950 break;
14951
14952 case 4:
14953 status = s390_decode_4byte_and_irgen(bytes);
14954 break;
14955
14956 case 6:
14957 status = s390_decode_6byte_and_irgen(bytes);
14958 break;
14959
14960 default:
14961 status = S390_DECODE_ERROR;
14962 break;
14963 }
14964 }
florian5fcbba22011-07-27 20:40:22 +000014965 /* If next instruction is execute, stop here */
florianf9e1ed72012-04-17 02:41:56 +000014966 if (dis_res->whatNext == Dis_Continue && bytes[insn_length] == 0x44) {
14967 put_IA(mkaddr_expr(guest_IA_next_instr));
sewardj2019a972011-03-07 16:04:07 +000014968 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +000014969 dis_res->jk_StopHere = Ijk_Boring;
sewardj2019a972011-03-07 16:04:07 +000014970 }
14971
14972 if (status == S390_DECODE_OK) return insn_length; /* OK */
14973
14974 /* Decoding failed somehow */
14975 vex_printf("vex s390->IR: ");
14976 switch (status) {
14977 case S390_DECODE_UNKNOWN_INSN:
14978 vex_printf("unknown insn: ");
14979 break;
14980
14981 case S390_DECODE_UNIMPLEMENTED_INSN:
14982 vex_printf("unimplemented insn: ");
14983 break;
14984
14985 case S390_DECODE_UNKNOWN_SPECIAL_INSN:
14986 vex_printf("unimplemented special insn: ");
14987 break;
14988
14989 default:
14990 case S390_DECODE_ERROR:
14991 vex_printf("decoding error: ");
14992 break;
14993 }
14994
14995 vex_printf("%02x%02x", bytes[0], bytes[1]);
14996 if (insn_length > 2) {
14997 vex_printf(" %02x%02x", bytes[2], bytes[3]);
14998 }
14999 if (insn_length > 4) {
15000 vex_printf(" %02x%02x", bytes[4], bytes[5]);
15001 }
15002 vex_printf("\n");
15003
15004 return 0; /* Failed */
15005}
15006
15007
sewardj2019a972011-03-07 16:04:07 +000015008/* Disassemble a single instruction INSN into IR. */
15009static DisResult
florian420c5012011-07-22 02:12:28 +000015010disInstr_S390_WRK(UChar *insn)
sewardj2019a972011-03-07 16:04:07 +000015011{
15012 UChar byte;
15013 UInt insn_length;
15014 DisResult dres;
15015
15016 /* ---------------------------------------------------- */
15017 /* --- Compute instruction length -- */
15018 /* ---------------------------------------------------- */
15019
15020 /* Get the first byte of the insn. */
15021 byte = insn[0];
15022
15023 /* The leftmost two bits (0:1) encode the length of the insn in bytes.
15024 00 -> 2 bytes, 01 -> 4 bytes, 10 -> 4 bytes, 11 -> 6 bytes. */
15025 insn_length = ((((byte >> 6) + 1) >> 1) + 1) << 1;
15026
15027 guest_IA_next_instr = guest_IA_curr_instr + insn_length;
15028
15029 /* ---------------------------------------------------- */
15030 /* --- Initialise the DisResult data -- */
15031 /* ---------------------------------------------------- */
15032 dres.whatNext = Dis_Continue;
15033 dres.len = insn_length;
15034 dres.continueAt = 0;
florian8844a632012-04-13 04:04:06 +000015035 dres.jk_StopHere = Ijk_INVALID;
sewardj2019a972011-03-07 16:04:07 +000015036
floriana99f20e2011-07-17 14:16:41 +000015037 /* fixs390: consider chasing of conditional jumps */
15038
sewardj2019a972011-03-07 16:04:07 +000015039 /* Normal and special instruction handling starts here. */
15040 if (s390_decode_and_irgen(insn, insn_length, &dres) == 0) {
15041 /* All decode failures end up here. The decoder has already issued an
15042 error message.
15043 Tell the dispatcher that this insn cannot be decoded, and so has
florian342e01a2012-07-26 02:37:49 +000015044 not been executed, and (is currently) the next to be executed.
15045 The insn address in the guest state needs to be set to
15046 guest_IA_curr_instr, otherwise the complaint will report an
15047 incorrect address. */
15048 put_IA(mkaddr_expr(guest_IA_curr_instr));
sewardj2019a972011-03-07 16:04:07 +000015049
florian8844a632012-04-13 04:04:06 +000015050 dres.whatNext = Dis_StopHere;
15051 dres.jk_StopHere = Ijk_NoDecode;
15052 dres.continueAt = 0;
15053 dres.len = 0;
15054 } else {
15055 /* Decode success */
15056 switch (dres.whatNext) {
15057 case Dis_Continue:
florian8559e412012-04-19 14:23:48 +000015058 put_IA(mkaddr_expr(guest_IA_next_instr));
florian8844a632012-04-13 04:04:06 +000015059 break;
15060 case Dis_ResteerU:
15061 case Dis_ResteerC:
15062 put_IA(mkaddr_expr(dres.continueAt));
15063 break;
15064 case Dis_StopHere:
florian4b8efad2012-09-02 18:07:08 +000015065 if (dres.jk_StopHere == Ijk_EmWarn ||
15066 dres.jk_StopHere == Ijk_EmFail) {
15067 /* We assume here, that emulation warnings are not given for
15068 insns that transfer control. There is no good way to
15069 do that. */
15070 put_IA(mkaddr_expr(guest_IA_next_instr));
15071 }
florian8844a632012-04-13 04:04:06 +000015072 break;
15073 default:
15074 vassert(0);
15075 }
sewardj2019a972011-03-07 16:04:07 +000015076 }
15077
15078 return dres;
15079}
15080
15081
15082/*------------------------------------------------------------*/
15083/*--- Top-level fn ---*/
15084/*------------------------------------------------------------*/
15085
15086/* Disassemble a single instruction into IR. The instruction
15087 is located in host memory at &guest_code[delta]. */
15088
15089DisResult
15090disInstr_S390(IRSB *irsb_IN,
sewardj2019a972011-03-07 16:04:07 +000015091 Bool (*resteerOkFn)(void *, Addr64),
15092 Bool resteerCisOk,
15093 void *callback_opaque,
15094 UChar *guest_code,
15095 Long delta,
15096 Addr64 guest_IP,
15097 VexArch guest_arch,
15098 VexArchInfo *archinfo,
15099 VexAbiInfo *abiinfo,
15100 Bool host_bigendian)
15101{
15102 vassert(guest_arch == VexArchS390X);
15103
15104 /* The instruction decoder requires a big-endian machine. */
15105 vassert(host_bigendian == True);
15106
15107 /* Set globals (see top of this file) */
15108 guest_IA_curr_instr = guest_IP;
sewardj2019a972011-03-07 16:04:07 +000015109 irsb = irsb_IN;
florian420c5012011-07-22 02:12:28 +000015110 resteer_fn = resteerOkFn;
15111 resteer_data = callback_opaque;
sewardj2019a972011-03-07 16:04:07 +000015112
florian420c5012011-07-22 02:12:28 +000015113 return disInstr_S390_WRK(guest_code + delta);
sewardj2019a972011-03-07 16:04:07 +000015114}
15115
15116/*---------------------------------------------------------------*/
15117/*--- end guest_s390_toIR.c ---*/
15118/*---------------------------------------------------------------*/