1
2/*--------------------------------------------------------------------*/
3/*--- begin                                    guest_tilegx_toIR.c ---*/
4/*--------------------------------------------------------------------*/
5
6/*
7  This file is part of Valgrind, a dynamic binary instrumentation
8  framework.
9
10  Copyright (C) 2010-2015  Tilera Corp.
11
12  This program is free software; you can redistribute it and/or
13  modify it under the terms of the GNU General Public License as
14  published by the Free Software Foundation; either version 2 of the
15  License, or (at your option) any later version.
16
17  This program is distributed in the hope that it will be useful, but
18  WITHOUT ANY WARRANTY; without even the implied warranty of
19  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
20  General Public License for more details.
21
22  You should have received a copy of the GNU General Public License
23  along with this program; if not, write to the Free Software
24  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
25  02111-1307, USA.
26
27  The GNU General Public License is contained in the file COPYING.
28*/
29
30/* Contributed by Zhi-Gang Liu <zliu at tilera dot com> */
31
32/* Translates TILEGX code to IR. */
33
34#include "libvex_basictypes.h"
35#include "libvex_ir.h"
36#include "libvex.h"
37#include "libvex_guest_tilegx.h"
38
39#include "main_util.h"
40#include "main_globals.h"
41#include "guest_generic_bb_to_IR.h"
42#include "guest_tilegx_defs.h"
43#include "tilegx_disasm.h"
44
45/*------------------------------------------------------------*/
46/*--- Globals                                              ---*/
47/*------------------------------------------------------------*/
48
49/* These are set at the start of the translation of a instruction, so
50   that we don't have to pass them around endlessly.  CONST means does
51   not change during translation of the instruction.
52*/
53
54/* CONST: is the host bigendian?  This has to do with float vs double
55   register accesses on VFP, but it's complex and not properly thought
56   out. */
57static VexEndness host_endness;
58
59/* Pointer to the guest code area. */
60static UChar *guest_code;
61
62/* The guest address corresponding to guest_code[0]. */
63static Addr64 guest_PC_bbstart;
64
65/* CONST: The guest address for the instruction currently being
66   translated. */
67static Addr64 guest_PC_curr_instr;
68
69/* MOD: The IRSB* into which we're generating code. */
70static IRSB *irsb;
71
72/*------------------------------------------------------------*/
73/*--- Debugging output                                     ---*/
74/*------------------------------------------------------------*/
75
76#define DIP(format, args...)                    \
77  if (vex_traceflags & VEX_TRACE_FE)            \
78    vex_printf(format, ## args)
79
80/*------------------------------------------------------------*/
81/*--- Helper bits and pieces for deconstructing the        ---*/
82/*--- tilegx insn stream.                                  ---*/
83/*------------------------------------------------------------*/
84
85static Int integerGuestRegOffset ( UInt iregNo )
86{
87  return 8 * (iregNo);
88}
89
90/*------------------------------------------------------------*/
91/*---                           Field helpers              ---*/
92/*------------------------------------------------------------*/
93
94/*------------------------------------------------------------*/
95/*--- Helper bits and pieces for creating IR fragments.    ---*/
96/*------------------------------------------------------------*/
97
98static IRExpr *mkU8 ( UInt i )
99{
100  return IRExpr_Const(IRConst_U8((UChar) i));
101}
102
103/* Create an expression node for a 32-bit integer constant */
104static IRExpr *mkU32 ( UInt i )
105{
106  return IRExpr_Const(IRConst_U32(i));
107}
108
109/* Create an expression node for a 64-bit integer constant */
110static IRExpr *mkU64 ( ULong i )
111{
112  return IRExpr_Const(IRConst_U64(i));
113}
114
115static IRExpr *mkexpr ( IRTemp tmp )
116{
117  return IRExpr_RdTmp(tmp);
118}
119
120static IRExpr *unop ( IROp op, IRExpr * a )
121{
122  return IRExpr_Unop(op, a);
123}
124
125static IRExpr *binop ( IROp op, IRExpr * a1, IRExpr * a2 )
126{
127  return IRExpr_Binop(op, a1, a2);
128}
129
130static IRExpr *load ( IRType ty, IRExpr * addr )
131{
132  IRExpr *load1 = NULL;
133
134  load1 = IRExpr_Load(Iend_LE, ty, addr);
135  return load1;
136}
137
138/* Add a statement to the list held by "irsb". */
139static void stmt ( IRStmt * st )
140{
141  addStmtToIRSB(irsb, st);
142}
143
144#define OFFB_PC     offsetof(VexGuestTILEGXState, guest_pc)
145
146static void putPC ( IRExpr * e )
147{
148  stmt(IRStmt_Put(OFFB_PC, e));
149}
150
151static void assign ( IRTemp dst, IRExpr * e )
152{
153  stmt(IRStmt_WrTmp(dst, e));
154}
155
156static void store ( IRExpr * addr, IRExpr * data )
157{
158  stmt(IRStmt_Store(Iend_LE, addr, data));
159}
160
161/* Generate a new temporary of the given type. */
162static IRTemp newTemp ( IRType ty )
163{
164  vassert(isPlausibleIRType(ty));
165  return newIRTemp(irsb->tyenv, ty);
166}
167
168static ULong extend_s_16to64 ( UInt x )
169{
170  return (ULong) ((((Long) x) << 48) >> 48);
171}
172
173static ULong extend_s_8to64 ( UInt x )
174{
175  return (ULong) ((((Long) x) << 56) >> 56);
176}
177
178static IRExpr *getIReg ( UInt iregNo )
179{
180  IRType ty = Ity_I64;
181  if(!(iregNo < 56 || iregNo == 63 ||
182       (iregNo >= 70 && iregNo <= 73))) {
183    vex_printf("iregNo=%u\n", iregNo);
184    vassert(0);
185  }
186  return IRExpr_Get(integerGuestRegOffset(iregNo), ty);
187}
188
189static void putIReg ( UInt archreg, IRExpr * e )
190{
191  IRType ty = Ity_I64;
192  if(!(archreg < 56 || archreg == 63 || archreg == 70 ||
193       archreg == 72 || archreg == 73)) {
194    vex_printf("archreg=%u\n", archreg);
195    vassert(0);
196  }
197  vassert(typeOfIRExpr(irsb->tyenv, e) == ty);
198  if (archreg != 63)
199    stmt(IRStmt_Put(integerGuestRegOffset(archreg), e));
200}
201
202/* Narrow 8/16/32 bit int expr to 8/16/32.  Clearly only some
203   of these combinations make sense. */
204static IRExpr *narrowTo ( IRType dst_ty, IRExpr * e )
205{
206  IRType src_ty = typeOfIRExpr(irsb->tyenv, e);
207  if (src_ty == dst_ty)
208    return e;
209  if (src_ty == Ity_I32 && dst_ty == Ity_I16)
210    return unop(Iop_32to16, e);
211  if (src_ty == Ity_I32 && dst_ty == Ity_I8)
212    return unop(Iop_32to8, e);
213
214  if (src_ty == Ity_I64 && dst_ty == Ity_I8) {
215    return unop(Iop_64to8, e);
216  }
217  if (src_ty == Ity_I64 && dst_ty == Ity_I16) {
218    return unop(Iop_64to16, e);
219  }
220  if (src_ty == Ity_I64 && dst_ty == Ity_I32) {
221    return unop(Iop_64to32, e);
222  }
223
224  if (vex_traceflags & VEX_TRACE_FE) {
225    vex_printf("\nsrc, dst tys are: ");
226    ppIRType(src_ty);
227    vex_printf(", ");
228    ppIRType(dst_ty);
229    vex_printf("\n");
230  }
231  vpanic("narrowTo(tilegx)");
232  return e;
233}
234
235#define signExtend(_e, _n)                                              \
236  ((_n == 32) ?                                                         \
237   unop(Iop_32Sto64, _e) :                                              \
238   ((_n == 16) ?                                                        \
239    unop(Iop_16Sto64, _e) :						\
240    (binop(Iop_Sar64, binop(Iop_Shl64, _e, mkU8(63 - (_n))), mkU8(63 - (_n))))))
241
242static IRStmt* dis_branch ( IRExpr* guard, ULong imm )
243{
244  IRTemp t0;
245
246  t0 = newTemp(Ity_I1);
247  assign(t0, guard);
248  return IRStmt_Exit(mkexpr(t0), Ijk_Boring,
249                     IRConst_U64(imm), OFFB_PC);
250}
251
252#define  MARK_REG_WB(_rd, _td)                  \
253  do {                                          \
254    vassert(rd_wb_index < 6);                   \
255    rd_wb_temp[rd_wb_index] = _td;              \
256    rd_wb_reg[rd_wb_index] = _rd;               \
257    rd_wb_index++;                              \
258  } while(0)
259
260
261/* Expand/repeat byte _X 8 times to a 64-bit value */
262#define  V1EXP(_X)                                     \
263  ({                                                   \
264    _X = ((((UChar)(_X)) << 8) | ((UChar)(_X)));       \
265    _X = (((_X) << 16) | (_X));                        \
266    (((_X) << 32) | (_X));                             \
267  })
268
269/* Expand/repeat byte _X 4 times to a 64-bit value */
270#define  V2EXP(_X)                                 \
271  ({                                               \
272    _X = ((((UChar)(_X)) << 16) | ((UChar)(_X)));  \
273    (((_X) << 32) | (_X));                         \
274  })
275
276/*------------------------------------------------------------*/
277/*--- Disassemble a single instruction                     ---*/
278/*------------------------------------------------------------*/
279
280/* Disassemble a single instruction bundle into IR.  The bundle is
281   located in host memory at guest_instr, and has guest IP of
282   guest_PC_curr_instr, which will have been set before the call
283   here. */
284static DisResult disInstr_TILEGX_WRK ( Bool(*resteerOkFn) (void *, Addr),
285                                       Bool resteerCisOk,
286                                       void *callback_opaque,
287                                       Long delta64,
288                                       const VexArchInfo * archinfo,
289                                       const VexAbiInfo * abiinfo,
290                                       Bool sigill_diag )
291{
292  struct tilegx_decoded_instruction
293    decoded[TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE];
294  ULong  cins, opcode = -1, rd, ra, rb, imm = 0;
295  ULong  opd[4];
296  ULong  opd_src_map, opd_dst_map, opd_imm_map;
297  Int    use_dirty_helper;
298  IRTemp t0, t1, t2, t3, t4;
299  IRTemp tb[4];
300  IRTemp rd_wb_temp[6];
301  ULong  rd_wb_reg[6];
302  /* Tilegx is a VLIW processor, we have to commit register write after read.*/
303  Int    rd_wb_index;
304  Int    n = 0, nr_insn;
305  DisResult dres;
306
307  /* The running delta */
308  Long delta = delta64;
309
310  /* Holds pc at the start of the insn, so that we can print
311     consistent error messages for unimplemented insns. */
312  //Long delta_start = delta;
313
314  UChar *code = (UChar *) (guest_code + delta);
315
316  IRStmt *bstmt = NULL;  /* Branch statement. */
317  IRExpr *next = NULL; /* Next bundle expr. */
318  ULong  jumpkind =  Ijk_Boring;
319  ULong  steering_pc;
320
321  /* Set result defaults. */
322  dres.whatNext = Dis_Continue;
323  dres.len = 0;
324  dres.continueAt = 0;
325  dres.jk_StopHere = Ijk_INVALID;
326
327  /* Verify the code addr is 8-byte aligned. */
328  vassert((((Addr)code) & 7) == 0);
329
330  /* Get the instruction bundle. */
331  cins = *((ULong *)(Addr) code);
332
333  /* "Special" instructions. */
334  /* Spot the 16-byte preamble:   ****tilegx****
335     0:02b3c7ff91234fff { moveli zero, 4660 ; moveli zero, 22136 }
336     8:0091a7ff95678fff { moveli zero, 22136 ; moveli zero, 4660 }
337  */
338#define CL_W0 0x02b3c7ff91234fffULL
339#define CL_W1 0x0091a7ff95678fffULL
340
341  if (*((ULong*)(Addr)(code)) == CL_W0 &&
342      *((ULong*)(Addr)(code + 8)) == CL_W1) {
343    /* Got a "Special" instruction preamble.  Which one is it? */
344    if (*((ULong*)(Addr)(code + 16)) ==
345        0x283a69a6d1483000ULL /* or r13, r13, r13 */ ) {
346      /* r0 = client_request ( r12 ) */
347      DIP("r0 = client_request ( r12 )\n");
348
349      putPC(mkU64(guest_PC_curr_instr + 24));
350
351      dres.jk_StopHere = Ijk_ClientReq;
352      dres.whatNext = Dis_StopHere;
353      dres.len = 24;
354      goto decode_success;
355
356    } else if (*((ULong*)(Addr)(code + 16)) ==
357               0x283a71c751483000ULL /* or r14, r14, r14 */ ) {
358      /* r11 = guest_NRADDR */
359      DIP("r11 = guest_NRADDR\n");
360      dres.len = 24;
361      putIReg(11, IRExpr_Get(offsetof(VexGuestTILEGXState, guest_NRADDR),
362                             Ity_I64));
363      putPC(mkU64(guest_PC_curr_instr + 8));
364      goto decode_success;
365
366    } else if (*((ULong*)(Addr)(code + 16)) ==
367               0x283a79e7d1483000ULL  /* or r15, r15, r15 */ ) {
368      /*  branch-and-link-to-noredir r12 */
369      DIP("branch-and-link-to-noredir r12\n");
370      dres.len = 24;
371      putIReg(55, mkU64(guest_PC_curr_instr + 24));
372
373      putPC(getIReg(12));
374
375      dres.jk_StopHere = Ijk_NoRedir;
376      dres.whatNext = Dis_StopHere;
377      goto decode_success;
378
379    }  else if (*((ULong*)(Addr)(code + 16)) ==
380                0x283a5965d1483000ULL  /* or r11, r11, r11 */ ) {
381      /*  vex-inject-ir */
382      DIP("vex-inject-ir\n");
383      dres.len = 24;
384
385      vex_inject_ir(irsb, Iend_LE);
386
387      stmt(IRStmt_Put(offsetof(VexGuestTILEGXState, guest_CMSTART),
388                      mkU64(guest_PC_curr_instr)));
389      stmt(IRStmt_Put(offsetof(VexGuestTILEGXState, guest_CMLEN),
390                      mkU64(24)));
391
392      /* 2 + 1 = 3 bundles. 24 bytes. */
393      putPC(mkU64(guest_PC_curr_instr + 24));
394
395      dres.jk_StopHere = Ijk_InvalICache;
396      dres.whatNext = Dis_StopHere;
397      goto decode_success;
398    }
399
400    /* We don't expect this. */
401    vex_printf("%s: unexpect special bundles at %lx\n",
402               __func__, (Addr)guest_PC_curr_instr);
403    delta += 16;
404    goto decode_failure;
405    /*NOTREACHED*/
406  }
407
408  /* To decode the given instruction bundle. */
409  nr_insn = parse_insn_tilegx((tilegx_bundle_bits)cins,
410                              (ULong)(Addr)code,
411                              decoded);
412
413  if (vex_traceflags & VEX_TRACE_FE)
414    decode_and_display(&cins, 1, (ULong)(Addr)code);
415
416  /* Init. rb_wb_index */
417  rd_wb_index = 0;
418
419  steering_pc = -1ULL;
420
421  for (n = 0; n < nr_insn; n++) {
422    opcode = decoded[n].opcode->mnemonic;
423    Int opi;
424
425    rd = ra = rb = -1;
426    opd[0] = opd[1] = opd[2] = opd[3] = -1;
427    opd_dst_map = 0;
428    opd_src_map = 0;
429    opd_imm_map = 0;
430
431    for (opi = 0; opi < decoded[n].opcode->num_operands; opi++) {
432      const struct tilegx_operand *op = decoded[n].operands[opi];
433      opd[opi] = decoded[n].operand_values[opi];
434
435      /* Set the operands. rd, ra, rb and imm. */
436      if (opi < 3) {
437        if (op->is_dest_reg) {
438          if (rd == -1)
439            rd =  decoded[n].operand_values[opi];
440          else if (ra == -1)
441            ra =  decoded[n].operand_values[opi];
442        } else if (op->is_src_reg) {
443          if (ra == -1) {
444            ra = decoded[n].operand_values[opi];
445          } else if(rb == -1) {
446            rb = decoded[n].operand_values[opi];
447          } else {
448            vassert(0);
449          }
450        } else {
451          imm = decoded[n].operand_values[opi];
452        }
453      }
454
455      /* Build bit maps of used dest, source registers
456         and immediate. */
457      if (op->is_dest_reg) {
458        opd_dst_map |= 1ULL << opi;
459        if(op->is_src_reg)
460          opd_src_map |= 1ULL << opi;
461      } else if(op->is_src_reg) {
462        opd_src_map |= 1ULL << opi;
463      } else {
464        opd_imm_map |= 1ULL << opi;
465      }
466    }
467
468    use_dirty_helper = 0;
469
470    switch (opcode) {
471    case 0:  /* "bpt" */  /* "raise" */
472      /* "bpt" pseudo instruction is an illegal instruction */
473      opd_imm_map |= (1 << 0);
474      opd[0] = cins;
475      use_dirty_helper = 1;
476      break;
477    case 1:  /* "info" */   /* Ignore this instruction. */
478      break;
479    case 2:  /* "infol" */   /* Ignore this instruction. */
480      break;
481    case 3:  /* "ld4s_tls" */   /* Ignore this instruction. */
482      break;
483    case 4:  /* "ld_tls" */    /* Ignore this instruction. */
484      break;
485    case 5:  /* "move" */
486      t2 = newTemp(Ity_I64);
487      assign(t2, getIReg(ra));
488      MARK_REG_WB(rd, t2);
489      break;
490    case 6:  /* "movei" */
491      t2 = newTemp(Ity_I64);
492      assign(t2, mkU64(extend_s_8to64(imm)));
493      MARK_REG_WB(rd, t2);
494      break;
495    case 7:  /* "moveli" */
496      t2 = newTemp(Ity_I64);
497      assign(t2, mkU64(extend_s_16to64(imm)));
498      MARK_REG_WB(rd, t2);
499      break;
500    case 8:  /* "prefetch" */   /* Ignore. */
501      break;
502    case 9:  /* "prefetch_add_l1" */   /* Ignore. */
503      break;
504    case 10: /* "prefetch_add_l1_fault" */   /* Ignore. */
505      break;
506    case 11: /* "prefetch_add_l2" */   /* Ignore. */
507      break;
508    case 12: /* "prefetch_add_l2_fault" */   /* Ignore. */
509      break;
510    case 13: /* "prefetch_add_l3" */   /* Ignore. */
511      break;
512    case 14: /* "prefetch_add_l3_fault" */   /* Ignore. */
513      break;
514    case 15: /* "prefetch_l1" */  /* Ignore. */
515      break;
516    case 16: /* "prefetch_l1_fault" */   /* Ignore. */
517      break;
518    case 17: /* "prefetch_l2" */   /* Ignore. */
519      break;
520    case 18: /* "prefetch_l2_fault" */   /* Ignore. */
521      break;
522    case 19: /* "prefetch_l3" */   /* Ignore. */
523      break;
524    case 20: /* "prefetch_l3_fault" */   /* Ignore. */
525      break;
526    case 21: /* "raise" */
527      /* "raise" pseudo instruction is an illegal instruction plusing
528         a "moveli zero, <sig>", so we need save whole bundle in the
529         opd[0], which will be used in the dirty helper. */
530      opd_imm_map |= (1 << 0);
531      opd[0] = cins;
532      use_dirty_helper = 1;
533      break;
534    case 22: /* "add" */
535      t2 = newTemp(Ity_I64);
536      assign(t2, binop(Iop_Add64, getIReg(ra), getIReg(rb)));
537      MARK_REG_WB(rd, t2);
538      break;
539    case 23: /* "addi" */
540      t2 = newTemp(Ity_I64);
541      assign(t2, binop(Iop_Add64, getIReg(ra),
542                       mkU64(extend_s_8to64(imm))));
543      MARK_REG_WB(rd, t2);
544      break;
545    case 24: /* "addli" */
546      t2 = newTemp(Ity_I64);
547      assign(t2, binop(Iop_Add64, getIReg(ra),
548                       mkU64(extend_s_16to64(imm))));
549      MARK_REG_WB(rd, t2);
550      break;
551    case 25: /* "addx" */
552      t2 = newTemp(Ity_I64);
553      assign(t2, signExtend(binop(Iop_Add32,
554                                  narrowTo(Ity_I32, getIReg(ra)),
555                                  narrowTo(Ity_I32, getIReg(rb))),
556                            32));
557      MARK_REG_WB(rd, t2);
558      break;
559    case 26: /* "addxi" */
560      t2 = newTemp(Ity_I64);
561      assign(t2, signExtend(binop(Iop_Add32,
562                                  narrowTo(Ity_I32, getIReg(ra)),
563                                  mkU32(imm)), 32));
564      MARK_REG_WB(rd, t2);
565      break;
566    case 27: /* "addxli" */
567      t2 = newTemp(Ity_I64);
568      assign(t2, signExtend(binop(Iop_Add32,
569                                  narrowTo(Ity_I32, getIReg(ra)),
570                                  mkU32(imm)), 32));
571
572      MARK_REG_WB(rd, t2);
573      break;
574    case 28: /* "addxsc" */
575      use_dirty_helper = 1;
576      break;
577    case 29: /* "and" */
578      t2 = newTemp(Ity_I64);
579      assign(t2, binop(Iop_And64, getIReg(ra), getIReg(rb)));
580      MARK_REG_WB(rd, t2);
581      break;
582    case 30: /* "andi" */
583      t2 = newTemp(Ity_I64);
584      assign(t2, binop(Iop_And64, getIReg(ra),
585                       mkU64(extend_s_8to64(imm))));
586      MARK_REG_WB(rd, t2);
587      break;
588    case 31: /* "beqz" */
589      /* Fall-through */
590    case 32:
591      /* "beqzt" */
592      bstmt = dis_branch(binop(Iop_CmpEQ64, getIReg(ra), mkU64(0)),
593                         imm);
594      break;
595    case 33: /* "bfexts" */
596      {
597        ULong imm0 = decoded[n].operand_values[3];
598        ULong mask = ((-1ULL) ^ ((-1ULL << ((imm0 - imm) & 63)) << 1));
599        t0 = newTemp(Ity_I64);
600        t2 = newTemp(Ity_I64);
601        assign(t0, binop(Iop_Xor64,
602                         binop(Iop_Sub64,
603                               binop(Iop_And64,
604                                     binop(Iop_Shr64,
605                                           getIReg(ra),
606                                           mkU8(imm0)),
607                                     mkU64(1)),
608                               mkU64(1)),
609                         mkU64(-1ULL)));
610        assign(t2,
611               binop(Iop_Or64,
612                     binop(Iop_And64,
613                           binop(Iop_Or64,
614                                 binop(Iop_Shr64,
615                                       getIReg(ra),
616                                       mkU8(imm)),
617                                 binop(Iop_Shl64,
618                                       getIReg(ra),
619                                       mkU8(64 - imm))),
620                           mkU64(mask)),
621                     binop(Iop_And64,
622                           mkexpr(t0),
623                           mkU64(~mask))));
624
625        MARK_REG_WB(rd, t2);
626      }
627      break;
628    case 34:  /* "bfextu" */
629      {
630        ULong imm0 = decoded[n].operand_values[3];
631        ULong mask = 0;
632        t2 = newTemp(Ity_I64);
633        mask = ((-1ULL) ^ ((-1ULL << ((imm0 - imm) & 63)) << 1));
634
635        assign(t2,
636               binop(Iop_And64,
637                     binop(Iop_Or64,
638                           binop(Iop_Shr64,
639                                 getIReg(ra),
640                                 mkU8(imm)),
641                           binop(Iop_Shl64,
642                                 getIReg(ra),
643                                 mkU8(64 - imm))),
644                     mkU64(mask)));
645        MARK_REG_WB(rd, t2);
646      }
647      break;
648    case 35:  /* "bfins" */
649      {
650        ULong mask;
651        ULong imm0 = decoded[n].operand_values[3];
652        t0 = newTemp(Ity_I64);
653        t2 = newTemp(Ity_I64);
654        if (imm <= imm0)
655        {
656          mask = ((-1ULL << imm) ^ ((-1ULL << imm0) << 1));
657        }
658        else
659        {
660          mask = ((-1ULL << imm) | (-1ULL >> (63 - imm0)));
661        }
662
663        assign(t0, binop(Iop_Or64,
664                         binop(Iop_Shl64,
665                               getIReg(ra),
666                               mkU8(imm)),
667                         binop(Iop_Shr64,
668                               getIReg(ra),
669                               mkU8(64 - imm))));
670
671        assign(t2, binop(Iop_Or64,
672                         binop(Iop_And64,
673                               mkexpr(t0),
674                               mkU64(mask)),
675                         binop(Iop_And64,
676                               getIReg(rd),
677                               mkU64(~mask))));
678
679        MARK_REG_WB(rd, t2);
680      }
681      break;
682    case 36:  /* "bgez" */
683      /* Fall-through */
684    case 37:  /* "bgezt" */
685      bstmt = dis_branch(binop(Iop_CmpEQ64,
686                               binop(Iop_And64,
687                                     getIReg(ra),
688                                     mkU64(0x8000000000000000ULL)),
689                               mkU64(0x0)),
690                         imm);
691      break;
692    case 38:  /* "bgtz" */
693      /* Fall-through */
694    case 39:
695      /* "bgtzt" */
696      bstmt = dis_branch(unop(Iop_Not1,
697                              binop(Iop_CmpLE64S,
698                                    getIReg(ra),
699                                    mkU64(0))),
700                         imm);
701      break;
702    case 40:  /* "blbc" */
703      /* Fall-through */
704    case 41:  /* "blbct" */
705      bstmt = dis_branch(unop(Iop_64to1,
706                              unop(Iop_Not64, getIReg(ra))),
707                         imm);
708
709      break;
710    case 42:  /* "blbs" */
711      /* Fall-through */
712    case 43:
713      /* "blbst" */
714      bstmt = dis_branch(unop(Iop_64to1,
715                              getIReg(ra)),
716                         imm);
717      break;
718    case 44:  /* "blez" */
719      bstmt = dis_branch(binop(Iop_CmpLE64S, getIReg(ra),
720                               mkU64(0)),
721                         imm);
722      break;
723    case 45:  /* "blezt" */
724      bstmt = dis_branch(binop(Iop_CmpLE64S, getIReg(ra),
725                               mkU64(0)),
726                         imm);
727      break;
728    case 46:  /* "bltz" */
729      bstmt = dis_branch(binop(Iop_CmpLT64S, getIReg(ra),
730                               mkU64(0)),
731                         imm);
732      break;
733    case 47:  /* "bltzt" */
734      bstmt = dis_branch(binop(Iop_CmpLT64S, getIReg(ra),
735                               mkU64(0)),
736                         imm);
737      break;
738    case 48:  /* "bnez" */
739      /* Fall-through */
740    case 49:
741      /* "bnezt" */
742      bstmt = dis_branch(binop(Iop_CmpNE64, getIReg(ra),
743                               mkU64(0)),
744                         imm);
745      break;
746    case 50:  /* "clz" */
747      t2 = newTemp(Ity_I64);
748      assign(t2, unop(Iop_Clz64, getIReg(ra)));
749
750      MARK_REG_WB(rd, t2);
751      break;
752    case 51:  /* "cmoveqz rd, ra, rb" */
753      t2 = newTemp(Ity_I64);
754      assign(t2, IRExpr_ITE(binop(Iop_CmpEQ64, getIReg(ra), mkU64(0)),
755                            getIReg(rb), getIReg(rd)));
756      MARK_REG_WB(rd, t2);
757      break;
758    case 52:  /* "cmovnez" */
759      t2 = newTemp(Ity_I64);
760      assign(t2, IRExpr_ITE(binop(Iop_CmpEQ64, getIReg(ra), mkU64(0)),
761                            getIReg(rd), getIReg(rb)));
762      MARK_REG_WB(rd, t2);
763      break;
764    case 53:  /* "cmpeq" */
765      t2 = newTemp(Ity_I64);
766      assign(t2,  unop(Iop_1Uto64, binop(Iop_CmpEQ64,
767                                         getIReg(ra), getIReg(rb))));
768      MARK_REG_WB(rd, t2);
769      break;
770
771    case 54:  /* "cmpeqi" */
772      t2 = newTemp(Ity_I64);
773      assign(t2, unop(Iop_1Uto64, binop(Iop_CmpEQ64,
774                                        getIReg(ra),
775                                        mkU64(extend_s_8to64(imm)))));
776      MARK_REG_WB(rd, t2);
777      break;
778    case 55:  /* "cmpexch" */
779      t1 = newTemp(Ity_I64);
780      t2 = newTemp(Ity_I64);
781
782      assign(t1, getIReg(rb));
783      stmt( IRStmt_CAS(mkIRCAS(IRTemp_INVALID, t2, Iend_LE,
784                               getIReg(ra),
785                               NULL, binop(Iop_Add64,
786                                           getIReg(70),
787                                           getIReg(71)),
788                               NULL, mkexpr(t1))));
789      MARK_REG_WB(rd, t2);
790      break;
791    case 56:  /* "cmpexch4" */
792      t1 = newTemp(Ity_I32);
793      t2 = newTemp(Ity_I64);
794      t3 = newTemp(Ity_I32);
795
796      assign(t1, narrowTo(Ity_I32, getIReg(rb)));
797      stmt( IRStmt_CAS(mkIRCAS(IRTemp_INVALID, t3, Iend_LE,
798                               getIReg(ra),
799                               NULL,
800                               narrowTo(Ity_I32, binop(Iop_Add64,
801                                                       getIReg(70),
802                                                       getIReg(71))),
803                               NULL,
804                               mkexpr(t1))));
805      assign(t2, unop(Iop_32Uto64, mkexpr(t3)));
806      MARK_REG_WB(rd, t2);
807      break;
808    case 57:  /* "cmples" */
809      t2 = newTemp(Ity_I64);
810      assign(t2, unop(Iop_1Uto64,
811                      binop(Iop_CmpLE64S, getIReg(ra), getIReg(rb))));
812      MARK_REG_WB(rd, t2);
813      break;
814    case 58:  /* "cmpleu" */
815      t2 = newTemp(Ity_I64);
816      assign(t2,  unop(Iop_1Uto64,
817                       binop(Iop_CmpLE64U, getIReg(ra), getIReg(rb))));
818      MARK_REG_WB(rd, t2);
819      break;
820    case 59:  /* "cmplts" */
821      t2 = newTemp(Ity_I64);
822      assign(t2, unop(Iop_1Uto64,
823                      binop(Iop_CmpLT64S, getIReg(ra), getIReg(rb))));
824      MARK_REG_WB(rd, t2);
825      break;
826    case 60:  /* "cmpltsi" */
827      t2 = newTemp(Ity_I64);
828      assign(t2, unop(Iop_1Uto64,
829                      binop(Iop_CmpLT64S,
830                            getIReg(ra),
831                            mkU64(extend_s_8to64(imm)))));
832      MARK_REG_WB(rd, t2);
833      break;
834    case 61:
835
836      /* "cmpltu" */
837      t2 = newTemp(Ity_I64);
838      assign(t2, unop(Iop_1Uto64,
839                      binop(Iop_CmpLT64U, getIReg(ra), getIReg(rb))));
840      MARK_REG_WB(rd, t2);
841
842
843      break;
844    case 62:  /* "cmpltui" */
845      t2 = newTemp(Ity_I64);
846      assign(t2,  unop(Iop_1Uto64,
847                       binop(Iop_CmpLT64U,
848                             getIReg(ra),
849                             mkU64(imm))));
850      MARK_REG_WB(rd, t2);
851
852
853      break;
854    case 63:  /* "cmpne" */
855      t2 = newTemp(Ity_I64);
856      assign(t2, unop(Iop_1Uto64,
857                      binop(Iop_CmpNE64, getIReg(ra), getIReg(rb))));
858      MARK_REG_WB(rd, t2);
859
860
861      break;
862    case 64:
863      /* Fall-through */
864    case 65:
865      /* Fall-through */
866    case 66:
867      /* Fall-through */
868    case 67:
869      /* Fall-through */
870    case 68:
871      /* Fall-through */
872    case 69:
873      /* Fall-through */
874    case 70:
875      /* Fall-through */
876    case 71:
877      /* Fall-through */
878    case 72:
879      use_dirty_helper = 1;
880      break;
881    case 73:  /* "ctz" */
882      t2 = newTemp(Ity_I64);
883      assign(t2, unop(Iop_Ctz64, getIReg(ra)));
884
885      MARK_REG_WB(rd, t2);
886
887
888      break;
889    case 74:  /* "dblalign" */
890      t0 = newTemp(Ity_I64);
891      t1 = newTemp(Ity_I64);
892      t2 = newTemp(Ity_I64);
893
894      /* t0 is the bit shift amount */
895      assign(t0, binop(Iop_Shl64,
896                       binop(Iop_And64,
897                             getIReg(rb),
898                             mkU64(7)),
899                       mkU8(3)));
900      assign(t1, binop(Iop_Sub64,
901                       mkU64(64),
902                       mkexpr(t0)));
903
904      assign(t2, binop(Iop_Or64,
905                       binop(Iop_Shl64,
906                             getIReg(ra),
907                             unop(Iop_64to8, mkexpr(t1))),
908                       binop(Iop_Shr64,
909                             getIReg(rd),
910                             unop(Iop_64to8, mkexpr(t0)))));
911
912      MARK_REG_WB(rd, t2);
913      break;
914    case 75:
915      /* Fall-through */
916    case 76:
917      /* Fall-through */
918    case 77:
919      /* Fall-through */
920    case 78:
921      /* Fall-through */
922    case 79:
923      use_dirty_helper = 1;
924      break;
925    case 80:  /* "exch" */
926      t2 = newTemp(Ity_I64);
927      stmt( IRStmt_CAS(
928              mkIRCAS(IRTemp_INVALID,
929                      t2,
930                      Iend_LE,
931                      getIReg(ra),
932                      NULL,
933                      mkU64(0x0),
934                      NULL,
935                      getIReg(rb))));
936      MARK_REG_WB(rd, t2);
937      break;
938    case 81:  /* "exch4 rd, ra, rb" */
939      t0 = newTemp(Ity_I32);
940      t2 = newTemp(Ity_I64);
941      stmt( IRStmt_CAS(
942              mkIRCAS(IRTemp_INVALID,
943                      t0,
944                      Iend_LE,
945                      getIReg(ra),
946                      NULL,
947                      mkU32(0x0),
948                      NULL,
949                      narrowTo(Ity_I32,
950                               getIReg(rb)))));
951      assign(t2, unop(Iop_32Sto64, mkexpr(t0)));
952      MARK_REG_WB(rd, t2);
953      break;
954    case 82:
955      /* Fall-through */
956    case 83:
957      /* Fall-through */
958    case 84:
959      /* Fall-through */
960    case 85:
961      /* Fall-through */
962    case 86:
963      /* Fall-through */
964    case 87:
965      /* Fall-through */
966    case 88:
967      /* Fall-through */
968    case 89:
969      use_dirty_helper = 1;
970      break;
971    case 90:  /* "fetchadd" */
972      t2 = newTemp(Ity_I64);
973      stmt( IRStmt_CAS(
974              mkIRCAS(IRTemp_INVALID,
975                      t2,
976                      Iend_LE,
977                      getIReg(ra),
978                      NULL,
979                      // fetchadd=3
980                      mkU64(0x3),
981                      NULL,
982                      getIReg(rb))));
983      MARK_REG_WB(rd, t2);
984      break;
985    case 91:  /* "fetchadd4" */
986      t0 = newTemp(Ity_I32);
987      t2 = newTemp(Ity_I64);
988      stmt( IRStmt_CAS(
989              mkIRCAS(IRTemp_INVALID,
990                      t0,
991                      Iend_LE,
992                      getIReg(ra),
993                      NULL,
994                      // fetchadd=3
995                      mkU32(0x3),
996                      NULL,
997                      narrowTo(Ity_I32,
998                               getIReg(rb)))));
999      assign(t2, unop(Iop_32Sto64, mkexpr(t0)));
1000      MARK_REG_WB(rd, t2);
1001
1002      break;
1003    case 92:  /* "fetchaddgez" */
1004      t2 = newTemp(Ity_I64);
1005      stmt( IRStmt_CAS(
1006              mkIRCAS(IRTemp_INVALID,
1007                      t2,
1008                      Iend_LE,
1009                      getIReg(ra),
1010                      NULL,
1011                      // fetchaddgez=5
1012                      mkU64(0x5),
1013                      NULL,
1014                      getIReg(rb))));
1015      MARK_REG_WB(rd, t2);
1016      break;
1017    case 93:  /* "fetchaddgez4" */
1018      t0 = newTemp(Ity_I32);
1019      t2 = newTemp(Ity_I64);
1020      stmt( IRStmt_CAS(
1021              mkIRCAS(IRTemp_INVALID,
1022                      t0,
1023                      Iend_LE,
1024                      getIReg(ra),
1025                      NULL,
1026                      // fetchaddgez=5
1027                      mkU32(0x5),
1028                      NULL,
1029                      narrowTo(Ity_I32,
1030                               getIReg(rb)))));
1031      assign(t2, unop(Iop_32Sto64, mkexpr(t0)));
1032      MARK_REG_WB(rd, t2);
1033      break;
1034    case 94:  /* "fetchand\n") */
1035      t2 = newTemp(Ity_I64);
1036      stmt( IRStmt_CAS(
1037              mkIRCAS(IRTemp_INVALID,
1038                      t2,
1039                      Iend_LE,
1040                      getIReg(ra),
1041                      NULL,
1042                      mkU64(0x2),
1043                      NULL,
1044                      getIReg(rb))));
1045      MARK_REG_WB(rd, t2);
1046      break;
1047    case 95:
1048      /* mkIRCAS.
1049         0: xch###      1: cmpexch###,
1050         2: fetchand##  3: fetchadd##
1051         4: fetchor##   5: fetchaddgez
1052      */
1053      /* "fetchand4" */
1054      t0 = newTemp(Ity_I32);
1055      t2 = newTemp(Ity_I64);
1056      stmt( IRStmt_CAS(
1057              mkIRCAS(IRTemp_INVALID,
1058                      t0,
1059                      Iend_LE,
1060                      getIReg(ra),
1061                      NULL,
1062                      mkU32(0x2),
1063                      NULL,
1064                      narrowTo(Ity_I32,
1065                               getIReg(rb)))));
1066      assign(t2, unop(Iop_32Sto64, mkexpr(t0)));
1067      MARK_REG_WB(rd, t2);
1068      break;
1069    case 96:  /* "fetchor" */
1070      t2 = newTemp(Ity_I64);
1071      stmt( IRStmt_CAS(
1072              mkIRCAS(IRTemp_INVALID,
1073                      t2,
1074                      Iend_LE,
1075                      getIReg(ra),
1076                      NULL,
1077                      mkU64(0x4),
1078                      NULL,
1079                      getIReg(rb))));
1080      MARK_REG_WB(rd, t2);
1081      break;
1082    case 97:  /* "fetchor4" */
1083      t0 = newTemp(Ity_I32);
1084      t2 = newTemp(Ity_I64);
1085      stmt( IRStmt_CAS(
1086              mkIRCAS(IRTemp_INVALID,
1087                      t0,
1088                      Iend_LE,
1089                      getIReg(ra),
1090                      NULL,
1091                      mkU32(0x4),
1092                      NULL,
1093                      narrowTo(Ity_I32,
1094                               getIReg(rb)))));
1095      assign(t2, unop(Iop_32Sto64, mkexpr(t0)));
1096      MARK_REG_WB(rd, t2);
1097      break;
1098    case 98:
1099      /* Fall-through */
1100    case 99:
1101      /* Fall-through */
1102    case 100:
1103      use_dirty_helper = 1;
1104      break;
1105    case 101: /* "fnop"  Ignore */
1106      break;
1107    case 102:
1108      /* Fall-through */
1109    case 103:
1110      /* Fall-through */
1111    case 104:
1112      /* Fall-through */
1113    case 105:
1114      /* Fall-through */
1115    case 106:
1116      /* Fall-through */
1117    case 107:
1118      /* Fall-through */
1119    case 108:
1120      use_dirty_helper = 1;
1121      break;
1122    case 109:
1123      /* Fall-through */
1124    case 110:
1125      /* Fall-through */
1126    case 111:
1127      use_dirty_helper = 1;
1128      break;
1129    case 112:  /* "iret" */
1130      next = mkU64(guest_PC_curr_instr + 8);
1131      jumpkind = Ijk_Ret;
1132      break;
1133    case 113:  /* "j" */
1134      next = mkU64(imm);
1135      /* set steering address. */
1136      steering_pc = imm;
1137      jumpkind = Ijk_Boring;
1138      break;
1139    case 114:
1140      t2 = newTemp(Ity_I64);
1141      assign(t2, mkU64(guest_PC_curr_instr + 8));
1142      /* set steering address. */
1143      steering_pc = imm;
1144      next = mkU64(imm);
1145      jumpkind = Ijk_Call;
1146      MARK_REG_WB(55, t2);
1147      break;
1148    case 115:  /* "jalr" */
1149      /* Fall-through */
1150    case 116:  /* "jalrp" */
1151      t1 = newTemp(Ity_I64);
1152      t2 = newTemp(Ity_I64);
1153      assign(t1, getIReg(ra));
1154      assign(t2, mkU64(guest_PC_curr_instr + 8));
1155      next = mkexpr(t1);
1156      jumpkind = Ijk_Call;
1157      MARK_REG_WB(55, t2);
1158      break;
1159    case 117:  /* "jr" */
1160      /* Fall-through */
1161    case 118:  /* "jrp" */
1162      next = getIReg(ra);
1163      jumpkind = Ijk_Boring;
1164      break;
1165    case 119:  /* "ld" */
1166      t2 = newTemp(Ity_I64);
1167      assign(t2, load(Ity_I64, (getIReg(ra))));
1168      MARK_REG_WB(rd, t2);
1169      break;
1170    case 120:  /* "ld1s" */
1171      t2 = newTemp(Ity_I64);
1172      assign(t2,  unop(Iop_8Sto64,
1173                       load(Ity_I8, (getIReg(ra)))));
1174      MARK_REG_WB(rd, t2);
1175      break;
1176    case 121:  /* "ld1s_add" */
1177      t1 = newTemp(Ity_I64);
1178      t2 = newTemp(Ity_I64);
1179      assign(t1, binop(Iop_Add64, getIReg(ra), mkU64(imm)));
1180      assign(t2,  unop(Iop_8Sto64,
1181                       load(Ity_I8, (getIReg(ra)))));
1182      MARK_REG_WB(ra, t1);
1183      MARK_REG_WB(rd, t2);
1184      break;
1185    case 122:  /* "ld1u" */
1186      t2 = newTemp(Ity_I64);
1187      assign(t2,  unop(Iop_8Uto64,
1188                       load(Ity_I8, (getIReg(ra)))));
1189      MARK_REG_WB(rd, t2);
1190
1191      break;
1192    case 123:  /* "ld1u_add" */
1193      t1 = newTemp(Ity_I64);
1194      t2 = newTemp(Ity_I64);
1195      assign(t1,  binop(Iop_Add64, getIReg(ra), mkU64(imm)));
1196      assign(t2,  unop(Iop_8Uto64,
1197                       load(Ity_I8, (getIReg(ra)))));
1198      MARK_REG_WB(ra, t1);
1199      MARK_REG_WB(rd, t2);
1200      break;
1201    case 124:  /* "ld2s" */
1202      t2 = newTemp(Ity_I64);
1203      assign(t2,  unop(Iop_16Sto64,
1204                       load(Ity_I16, getIReg(ra))));
1205      MARK_REG_WB(rd, t2);
1206      break;
1207    case 125:  /* "ld2s_add" */
1208      t1 = newTemp(Ity_I64);
1209      t2 = newTemp(Ity_I64);
1210      assign(t1,  binop(Iop_Add64, getIReg(ra), mkU64(imm)));
1211      assign(t2,  unop(Iop_16Sto64,
1212                       load(Ity_I16, getIReg(ra))));
1213      MARK_REG_WB(rd, t2);
1214      MARK_REG_WB(ra, t1);
1215      break;
1216    case 126: /* "ld2u" */
1217      t2 = newTemp(Ity_I64);
1218      assign(t2,  unop(Iop_16Uto64,
1219                       load(Ity_I16, getIReg(ra))));
1220      MARK_REG_WB(rd, t2);
1221      break;
1222    case 127: /* "ld2u_add" */
1223      t1 = newTemp(Ity_I64);
1224      t2 = newTemp(Ity_I64);
1225      assign(t1,  binop(Iop_Add64, getIReg(ra), mkU64(imm)));
1226      assign(t2,  unop(Iop_16Uto64,
1227                       load(Ity_I16, getIReg(ra))));
1228      MARK_REG_WB(rd, t2);
1229      MARK_REG_WB(ra, t1);
1230      break;
1231    case 128: /* "ld4s" */
1232      t2 = newTemp(Ity_I64);
1233      assign(t2,  unop(Iop_32Sto64,
1234                       load(Ity_I32, (getIReg(ra)))));
1235      MARK_REG_WB(rd, t2);
1236      break;
1237    case 129: /* "ld4s_add" */
1238      t2 = newTemp(Ity_I64);
1239      t1 = newTemp(Ity_I64);
1240      assign(t1,  binop(Iop_Add64, getIReg(ra), mkU64(imm)));
1241      assign(t2,  unop(Iop_32Sto64,
1242                       load(Ity_I32, (getIReg(ra)))));
1243      MARK_REG_WB(rd, t2);
1244      MARK_REG_WB(ra, t1);
1245      break;
1246    case 130:  /* "ld4u" */
1247      t2 = newTemp(Ity_I64);
1248      assign(t2,  unop(Iop_32Uto64,
1249                       load(Ity_I32, getIReg(ra))));
1250      MARK_REG_WB(rd, t2);
1251      break;
1252    case 131:  /* "ld4u_add" */
1253      t1 = newTemp(Ity_I64);
1254      t2 = newTemp(Ity_I64);
1255      assign(t1, binop(Iop_Add64, getIReg(ra), mkU64(imm)));
1256      assign(t2,  unop(Iop_32Uto64,
1257                       load(Ity_I32, getIReg(ra))));
1258      MARK_REG_WB(ra, t1);
1259      MARK_REG_WB(rd, t2);
1260      break;
1261    case 132:  /* "ld_add" */
1262      t1 = newTemp(Ity_I64);
1263      t2 = newTemp(Ity_I64);
1264      assign(t1, load(Ity_I64, getIReg(ra)));
1265      assign(t2, binop(Iop_Add64, getIReg(ra), mkU64(imm)));
1266      MARK_REG_WB(ra, t2);
1267      MARK_REG_WB(rd, t1);
1268      break;
1269    case 133:  /* "ldna" */
1270      t2 = newTemp(Ity_I64);
1271      assign(t2, load(Ity_I64,
1272                      binop(Iop_And64,
1273                            getIReg(ra),
1274                            unop(Iop_Not64,
1275                                 mkU64(7)))));
1276      MARK_REG_WB(rd, t2);
1277      break;
1278    case 134:  /* "ldna_add" */
1279      t1 = newTemp(Ity_I64);
1280      t2 = newTemp(Ity_I64);
1281
1282      assign(t1, binop(Iop_Add64, getIReg(ra), mkU64(imm)));
1283      assign(t2, load(Ity_I64,
1284                      binop(Iop_And64,
1285                            getIReg(ra),
1286                            unop(Iop_Not64,
1287                                 mkU64(7)))));
1288      MARK_REG_WB(ra, t1);
1289      MARK_REG_WB(rd, t2);
1290      break;
1291    case 135:  /* "ldnt" */
1292      /* Valgrind IR has no Non-Temp load. Use normal load. */
1293      t2 = newTemp(Ity_I64);
1294      assign(t2, load(Ity_I64, (getIReg(ra))));
1295      MARK_REG_WB(rd, t2);
1296      break;
1297    case 136:  /* "ldnt1s" */
1298      t2 = newTemp(Ity_I64);
1299      assign(t2,  unop(Iop_8Sto64,
1300                       load(Ity_I8, (getIReg(ra)))));
1301      MARK_REG_WB(rd, t2);
1302      break;
1303    case 137:  /* "ldnt1s_add" */
1304      t1 = newTemp(Ity_I64);
1305      t2 = newTemp(Ity_I64);
1306      assign(t2,  unop(Iop_8Sto64,
1307                       load(Ity_I8, (getIReg(ra)))));
1308      assign(t1, binop(Iop_Add64, getIReg(ra), mkU64(imm)));
1309      MARK_REG_WB(ra, t1);
1310      MARK_REG_WB(rd, t2);
1311      break;
1312    case 138:  /* "ldnt1u" */
1313      t2 = newTemp(Ity_I64);
1314      assign(t2,  unop(Iop_8Uto64,
1315                       load(Ity_I8, (getIReg(ra)))));
1316      MARK_REG_WB(rd, t2);
1317      break;
1318    case 139:  /* "ldnt1u_add" */
1319      t1 = newTemp(Ity_I64);
1320      t2 = newTemp(Ity_I64);
1321
1322      assign(t1, binop(Iop_Add64, getIReg(ra), mkU64(imm)));
1323      assign(t2,  unop(Iop_8Uto64,
1324                       load(Ity_I8, (getIReg(ra)))));
1325
1326      MARK_REG_WB(ra, t1);
1327      MARK_REG_WB(rd, t2);
1328      break;
1329    case 140:  /* "ldnt2s" */
1330      t2 = newTemp(Ity_I64);
1331      assign(t2,  unop(Iop_16Sto64,
1332                       load(Ity_I16, getIReg(ra))));
1333      MARK_REG_WB(rd, t2);
1334      break;
1335    case 141:  /* "ldnt2s_add" */
1336      t1 = newTemp(Ity_I64);
1337      t2 = newTemp(Ity_I64);
1338      assign(t2,  unop(Iop_16Sto64,
1339                       load(Ity_I16, getIReg(ra))));
1340      assign(t1, binop(Iop_Add64, getIReg(ra), mkU64(imm)));
1341      MARK_REG_WB(ra, t1);
1342      MARK_REG_WB(rd, t2);
1343      break;
1344    case 142:  /* "ldnt2u" */
1345      t2 = newTemp(Ity_I64);
1346      assign(t2,  unop(Iop_16Uto64,
1347                       load(Ity_I16, getIReg(ra))));
1348      MARK_REG_WB(rd, t2);
1349      break;
1350    case 143:  /* "ldnt2u_add" */
1351      t1 = newTemp(Ity_I64);
1352      t2 = newTemp(Ity_I64);
1353      assign(t2,  unop(Iop_16Uto64,
1354                       load(Ity_I16, getIReg(ra))));
1355      assign(t1, binop(Iop_Add64, getIReg(ra), mkU64(imm)));
1356      MARK_REG_WB(ra, t1);
1357      MARK_REG_WB(rd, t2);
1358      break;
1359    case 144:  /* "ldnt4s" */
1360      t2 = newTemp(Ity_I64);
1361      assign(t2,  unop(Iop_32Sto64,
1362                       load(Ity_I32, (getIReg(ra)))));
1363      MARK_REG_WB(rd, t2);
1364      break;
1365    case 145:  /* "ldnt4s_add" */
1366      t1 = newTemp(Ity_I64);
1367      t2 = newTemp(Ity_I64);
1368      assign(t2,  unop(Iop_32Sto64,
1369                       load(Ity_I32, (getIReg(ra)))));
1370      assign(t1, binop(Iop_Add64, getIReg(ra), mkU64(imm)));
1371      MARK_REG_WB(rd, t2);
1372      MARK_REG_WB(ra, t1);
1373      break;
1374    case 146:  /* "ldnt4u" */
1375      t2 = newTemp(Ity_I64);
1376      assign(t2,  unop(Iop_32Uto64,
1377                       load(Ity_I32, getIReg(ra))));
1378      MARK_REG_WB(rd, t2);
1379      break;
1380    case 147:  /* "ldnt4u_add" */
1381      t1 = newTemp(Ity_I64);
1382      t2 = newTemp(Ity_I64);
1383      assign(t2,  unop(Iop_32Uto64,
1384                       load(Ity_I32, getIReg(ra))));
1385      assign(t1, binop(Iop_Add64, getIReg(ra), mkU64(imm)));
1386      MARK_REG_WB(rd, t2);
1387      MARK_REG_WB(ra, t1);
1388      break;
1389    case 148:  /* "ldnt_add" */
1390      t1 = newTemp(Ity_I64);
1391      t2 = newTemp(Ity_I64);
1392      assign(t1, load(Ity_I64, getIReg(ra)));
1393      assign(t2, binop(Iop_Add64, getIReg(ra), mkU64(imm)));
1394      MARK_REG_WB(rd, t1);
1395      MARK_REG_WB(ra, t2);
1396      break;
1397    case 149:  /* "lnk" */
1398      t2 = newTemp(Ity_I64);
1399      assign(t2,  mkU64(guest_PC_curr_instr + 8));
1400      MARK_REG_WB(rd, t2);
1401      break;
1402    case 150:  /* "mf" */
1403      use_dirty_helper = 1;
1404      break;
1405    case 151:  /* "mfspr" */
1406      t2 = newTemp(Ity_I64);
1407      if (imm == 0x2780) { // Get Cmpexch value
1408	 assign(t2, getIReg(70));
1409	 MARK_REG_WB(rd, t2);
1410      } else if (imm == 0x2580) { // Get EX_CONTEXT_0_0
1411         assign(t2, getIReg(576 / 8));
1412         MARK_REG_WB(rd, t2);
1413      } else if (imm == 0x2581) { // Get EX_CONTEXT_0_1
1414         assign(t2, getIReg(584 / 8));
1415         MARK_REG_WB(rd, t2);
1416      } else
1417        use_dirty_helper = 1;
1418      break;
1419    case 152:  /* "mm" */
1420      use_dirty_helper = 1;
1421      break;
1422    case 153:  /* "mnz" */
1423      t2 = newTemp(Ity_I64);
1424      assign(t2, binop(Iop_And64,
1425                       unop(Iop_1Sto64, binop(Iop_CmpNE64,
1426                                              getIReg(ra),
1427                                              mkU64(0))),
1428                       getIReg(rb)));
1429      MARK_REG_WB(rd, t2);
1430      break;
1431    case 154:  /* "mtspr imm, ra" */
1432      if (imm == 0x2780) // Set Cmpexch value
1433        putIReg(70, getIReg(ra));
1434      else if (imm == 0x2580) // set EX_CONTEXT_0_0
1435        putIReg(576/8, getIReg(ra));
1436      else if (imm == 0x2581) // set EX_CONTEXT_0_1
1437        putIReg(584/8, getIReg(ra));
1438      else
1439        use_dirty_helper = 1;
1440      break;
1441    case 155:  /* "mul_hs_hs" */
1442      t2 = newTemp(Ity_I64);
1443      assign(t2, binop(Iop_MullS32,
1444                       unop(Iop_64to32,
1445                            binop(Iop_Shr64,
1446                                  getIReg(ra),
1447                                  mkU8(32))),
1448                       unop(Iop_64to32,
1449                            binop(Iop_Shr64,
1450                                  getIReg(rb),
1451                                  mkU8(32)))));
1452      MARK_REG_WB(rd, t2);
1453      break;
1454    case 156:  /* "mul_hs_hu" */
1455      t0 = newTemp(Ity_I64);
1456      t1 = newTemp(Ity_I64);
1457      t2 = newTemp(Ity_I64);
1458      t3 = newTemp(Ity_I64);
1459
1460      assign(t0, unop(Iop_32Sto64,
1461                      unop(Iop_64to32,
1462                           binop(Iop_Shr64, getIReg(ra), mkU8(32)))));
1463      assign(t1, binop(Iop_MullU32,
1464                       unop(Iop_64to32, mkexpr(t0)),
1465                       unop(Iop_64to32, binop(Iop_Shr64, getIReg(rb), mkU8(32)))));
1466      assign(t3, binop(Iop_MullU32,
1467                       unop(Iop_64to32, binop(Iop_Shr64,
1468                                              mkexpr(t0),
1469                                              mkU8(32))),
1470                       unop(Iop_64to32, binop(Iop_Shr64, getIReg(rb), mkU8(32)))));
1471      assign(t2, binop(Iop_Add64,
1472                       mkexpr(t1),
1473                       binop(Iop_Shl64,
1474                             mkexpr(t3),
1475                             mkU8(32))));
1476      MARK_REG_WB(rd, t2);
1477      break;
1478    case 157:  /* "mul_hs_ls" */
1479      t2 = newTemp(Ity_I64);
1480      assign(t2, binop(Iop_MullS32,
1481                       unop(Iop_64to32,
1482                            binop(Iop_Shr64,
1483                                  getIReg(ra),
1484                                  mkU8(32))),
1485                       unop(Iop_64to32,
1486                            getIReg(rb))));
1487      MARK_REG_WB(rd, t2);
1488      break;
1489    case 158:  /* "mul_hs_lu" */
1490      t0 = newTemp(Ity_I64);
1491      t1 = newTemp(Ity_I64);
1492      t2 = newTemp(Ity_I64);
1493      t3 = newTemp(Ity_I64);
1494
1495      assign(t0, unop(Iop_32Sto64,
1496                      unop(Iop_64to32,
1497                           binop(Iop_Shr64, getIReg(ra), mkU8(32)))));
1498      assign(t1, binop(Iop_MullU32,
1499                       unop(Iop_64to32, mkexpr(t0)),
1500                       unop(Iop_64to32, getIReg(rb))));
1501      assign(t3, binop(Iop_MullU32,
1502                       unop(Iop_64to32, binop(Iop_Shr64,
1503                                              mkexpr(t0),
1504                                              mkU8(32))),
1505                       unop(Iop_64to32, getIReg(rb))));
1506      assign(t2, binop(Iop_Add64,
1507                       mkexpr(t1),
1508                       binop(Iop_Shl64,
1509                             mkexpr(t3),
1510                             mkU8(32))));
1511      MARK_REG_WB(rd, t2);
1512      break;
1513    case 159:  /* "mul_hu_hu" */
1514      t2 = newTemp(Ity_I64);
1515      assign(t2, binop(Iop_MullU32,
1516                       unop(Iop_64to32,
1517                            binop(Iop_Shr64,
1518                                  getIReg(ra),
1519                                  mkU8(32))),
1520                       unop(Iop_64to32,
1521                            binop(Iop_Shr64,
1522                                  getIReg(rb),
1523                                  mkU8(32)))));
1524      MARK_REG_WB(rd, t2);
1525      break;
1526    case 160:  /* "mul_hu_ls" */
1527      t0 = newTemp(Ity_I64);
1528      t1 = newTemp(Ity_I64);
1529      t2 = newTemp(Ity_I64);
1530      t3 = newTemp(Ity_I64);
1531
1532      assign(t0, unop(Iop_32Sto64,
1533                      unop(Iop_64to32,
1534                           getIReg(ra))));
1535
1536      assign(t1, binop(Iop_MullU32,
1537                       unop(Iop_64to32, mkexpr(t0)),
1538                       unop(Iop_64to32, binop(Iop_Shr64, getIReg(rb), mkU8(32)))));
1539      assign(t3, binop(Iop_MullU32,
1540                       unop(Iop_64to32, binop(Iop_Shr64,
1541                                              mkexpr(t0),
1542                                              mkU8(32))),
1543                       unop(Iop_64to32, binop(Iop_Shr64, getIReg(rb), mkU8(32)))));
1544      assign(t2, binop(Iop_Add64,
1545                       mkexpr(t1),
1546                       binop(Iop_Shl64,
1547                             mkexpr(t3),
1548                             mkU8(32))));
1549      MARK_REG_WB(rd, t2);
1550      break;
1551    case 161:  /* "mul_hu_lu" */
1552      t2 = newTemp(Ity_I64);
1553      assign(t2, binop(Iop_MullU32,
1554                       unop(Iop_64to32,
1555                            binop(Iop_Shr64,
1556                                  getIReg(ra),
1557                                  mkU8(32))),
1558                       unop(Iop_64to32,
1559                            getIReg(rb))));
1560      MARK_REG_WB(rd, t2);
1561      break;
1562    case 162:  /* "mul_ls_ls" */
1563      t2 = newTemp(Ity_I64);
1564      assign(t2, binop(Iop_MullS32,
1565                       unop(Iop_64to32, getIReg(ra)),
1566                       unop(Iop_64to32, getIReg(rb))));
1567      MARK_REG_WB(rd, t2);
1568      break;
1569    case 163:  /* "mul_ls_lu" */
1570      t0 = newTemp(Ity_I64);
1571      t1 = newTemp(Ity_I64);
1572      t2 = newTemp(Ity_I64);
1573      t3 = newTemp(Ity_I64);
1574
1575      assign(t0, unop(Iop_32Sto64,
1576                      unop(Iop_64to32, getIReg(ra))));
1577      assign(t1, binop(Iop_MullU32,
1578                       unop(Iop_64to32, mkexpr(t0)),
1579                       unop(Iop_64to32, getIReg(rb))));
1580      assign(t3, binop(Iop_MullU32,
1581                       unop(Iop_64to32, binop(Iop_Shr64,
1582                                              mkexpr(t0),
1583                                              mkU8(32))),
1584                       unop(Iop_64to32, getIReg(rb))));
1585      assign(t2, binop(Iop_Add64,
1586                       mkexpr(t1),
1587                       binop(Iop_Shl64,
1588                             mkexpr(t3),
1589                             mkU8(32))));
1590      MARK_REG_WB(rd, t2);
1591      break;
1592    case 164:   /* "mul_lu_lu" */
1593      t2 = newTemp(Ity_I64);
1594      assign(t2, binop(Iop_MullU32,
1595                       unop(Iop_64to32, getIReg(ra)),
1596                       unop(Iop_64to32, getIReg(rb))));
1597      MARK_REG_WB(rd, t2);
1598      break;
1599    case 165:   /* "mula_hs_hs" */
1600      t0 = newTemp(Ity_I64);
1601      t2 = newTemp(Ity_I64);
1602
1603      assign(t0, binop(Iop_MullS32,
1604                       unop(Iop_64to32, binop(Iop_Shr64,
1605                                              getIReg(ra), mkU8(32))),
1606                       unop(Iop_64to32, binop(Iop_Shr64,
1607                                              getIReg(rb), mkU8(32)))));
1608      assign(t2, binop(Iop_Add64, getIReg(rd), mkexpr(t0)));
1609      MARK_REG_WB(rd, t2);
1610      break;
1611    case 166:   /* "mula_hs_hu" */
1612      t0 = newTemp(Ity_I64);
1613      t1 = newTemp(Ity_I64);
1614      t2 = newTemp(Ity_I64);
1615      t3 = newTemp(Ity_I64);
1616      t4 = newTemp(Ity_I64);
1617      assign(t0, unop(Iop_32Sto64,
1618                      unop(Iop_64to32,
1619                           binop(Iop_Shr64, getIReg(ra), mkU8(32)))));
1620      assign(t1, binop(Iop_MullU32,
1621                       unop(Iop_64to32, mkexpr(t0)),
1622                       unop(Iop_64to32, binop(Iop_Shr64,
1623                                              getIReg(rb), mkU8(32)))));
1624      assign(t3, binop(Iop_MullU32,
1625                       unop(Iop_64to32, binop(Iop_Shr64,
1626                                              mkexpr(t0),
1627                                              mkU8(32))),
1628                       unop(Iop_64to32, binop(Iop_Shr64,
1629                                              getIReg(rb), mkU8(32)))));
1630      assign(t2, binop(Iop_Add64,
1631                       mkexpr(t1),
1632                       binop(Iop_Shl64,
1633                             mkexpr(t3),
1634                             mkU8(32))));
1635      assign(t4, binop(Iop_Add64, getIReg(rd), mkexpr(t2)));
1636      MARK_REG_WB(rd, t4);
1637      break;
1638    case 167:   /* "mula_hs_ls" */
1639      t2 = newTemp(Ity_I64);
1640      t4 = newTemp(Ity_I64);
1641      assign(t2, binop(Iop_MullS32,
1642                       unop(Iop_64to32,
1643                            binop(Iop_Shr64,
1644                                  getIReg(ra),
1645                                  mkU8(32))),
1646                       unop(Iop_64to32,
1647                            getIReg(rb))));
1648      assign(t4, binop(Iop_Add64, getIReg(rd), mkexpr(t2)));
1649      MARK_REG_WB(rd, t4);
1650      break;
1651    case 168:   /* "mula_hs_lu" */
1652      t0 = newTemp(Ity_I64);
1653      t1 = newTemp(Ity_I64);
1654      t2 = newTemp(Ity_I64);
1655      t3 = newTemp(Ity_I64);
1656      t4 = newTemp(Ity_I64);
1657      assign(t0, unop(Iop_32Sto64,
1658                      unop(Iop_64to32,
1659                           binop(Iop_Shr64, getIReg(ra), mkU8(32)))));
1660      assign(t1, binop(Iop_MullU32,
1661                       unop(Iop_64to32, mkexpr(t0)),
1662                       unop(Iop_64to32, getIReg(rb))));
1663      assign(t3, binop(Iop_MullU32,
1664                       unop(Iop_64to32, binop(Iop_Shr64,
1665                                              mkexpr(t0),
1666                                              mkU8(32))),
1667                       unop(Iop_64to32, getIReg(rb))));
1668      assign(t2, binop(Iop_Add64,
1669                       mkexpr(t1),
1670                       binop(Iop_Shl64,
1671                             mkexpr(t3),
1672                             mkU8(32))));
1673      assign(t4, binop(Iop_Add64, getIReg(rd), mkexpr(t2)));
1674      MARK_REG_WB(rd, t4);
1675      break;
1676    case 169:   /* "mula_hu_hu" */
1677      use_dirty_helper = 1;
1678      break;
1679    case 170:   /* "mula_hu_ls" */
1680      use_dirty_helper = 1;
1681      break;
1682    case 171:   /* "mula_hu_lu" */
1683      t2 = newTemp(Ity_I64);
1684      assign(t2, binop(Iop_Add64,
1685                       binop(Iop_MullU32,
1686                             unop(Iop_64to32,
1687                                  binop(Iop_Shr64,
1688                                        getIReg(ra),
1689                                        mkU8(32))),
1690                             unop(Iop_64to32,
1691                                  getIReg(rb))),
1692                       getIReg(rd)));
1693      MARK_REG_WB(rd, t2);
1694      break;
1695    case 172:  /* "mula_ls_ls" */
1696      t2 = newTemp(Ity_I64);
1697      assign(t2, binop(Iop_Add64,
1698                       getIReg(rd),
1699                       binop(Iop_MullS32,
1700                             unop(Iop_64to32, getIReg(ra)),
1701                             unop(Iop_64to32, getIReg(rb)))));
1702      MARK_REG_WB(rd, t2);
1703      break;
1704    case 173:  /* "mula_ls_lu" */
1705      t0 = newTemp(Ity_I64);
1706      t1 = newTemp(Ity_I64);
1707      t2 = newTemp(Ity_I64);
1708      t3 = newTemp(Ity_I64);
1709
1710      assign(t0, unop(Iop_32Sto64,
1711                      unop(Iop_64to32, getIReg(ra))));
1712      assign(t1, binop(Iop_MullU32,
1713                       unop(Iop_64to32, mkexpr(t0)),
1714                       unop(Iop_64to32, getIReg(rb))));
1715      assign(t3, binop(Iop_MullU32,
1716                       unop(Iop_64to32, binop(Iop_Shr64,
1717                                              mkexpr(t0),
1718                                              mkU8(32))),
1719                       unop(Iop_64to32, getIReg(rb))));
1720      assign(t2, binop(Iop_Add64,
1721                       getIReg(rd),
1722                       binop(Iop_Add64,
1723                             mkexpr(t1),
1724                             binop(Iop_Shl64,
1725                                   mkexpr(t3),
1726                                   mkU8(32)))));
1727      MARK_REG_WB(rd, t2);
1728      break;
1729    case 174:  /* "mula_lu_lu" */
1730      t2 = newTemp(Ity_I64);
1731      assign(t2, binop(Iop_Add64,
1732                       binop(Iop_MullU32,
1733                             unop(Iop_64to32,
1734                                  getIReg(ra)),
1735                             unop(Iop_64to32,
1736                                  getIReg(rb))),
1737                       getIReg(rd)));
1738      MARK_REG_WB(rd, t2);
1739      break;
1740    case 175:   /* "mulax" */
1741      t2 = newTemp(Ity_I64);
1742      assign(t2, unop(Iop_32Sto64,
1743                      unop(Iop_64to32,
1744                           binop(Iop_Add64,
1745                                 getIReg(rd),
1746                                 binop(Iop_MullU32,
1747                                       narrowTo(Ity_I32, getIReg(ra)),
1748                                       narrowTo(Ity_I32, getIReg(rb)))))));
1749      MARK_REG_WB(rd, t2);
1750      break;
1751    case 176:   /* "mulx" */
1752      t2 = newTemp(Ity_I64);
1753      assign(t2, unop(Iop_32Sto64,
1754                      unop(Iop_64to32,
1755                           binop(Iop_MullU32,
1756                                 narrowTo(Ity_I32, getIReg(ra)),
1757                                 narrowTo(Ity_I32, getIReg(rb))))));
1758      MARK_REG_WB(rd, t2);
1759      break;
1760    case 177:   /* "mz" */
1761      t2 = newTemp(Ity_I64);
1762      assign(t2, binop(Iop_And64,
1763                       unop(Iop_1Sto64, binop(Iop_CmpEQ64,
1764                                              getIReg(ra),
1765                                              mkU64(0))),
1766                       getIReg(rb)));
1767      MARK_REG_WB(rd, t2);
1768      break;
1769    case 178:  /* "nap" */
1770      break;
1771    case 179:  /* "nop" */
1772      break;
1773    case 180:  /* "nor" */
1774      t2 = newTemp(Ity_I64);
1775      assign(t2, unop(Iop_Not64,
1776                      binop(Iop_Or64,
1777                            getIReg(ra),
1778                            getIReg(rb))));
1779      MARK_REG_WB(rd, t2);
1780      break;
1781    case 181:  /* "or" */
1782      t2 = newTemp(Ity_I64);
1783      assign(t2, binop(Iop_Or64,
1784                       getIReg(ra),
1785                       getIReg(rb)));
1786      MARK_REG_WB(rd, t2);
1787      break;
1788    case 182:  /* "ori" */
1789      t2 = newTemp(Ity_I64);
1790      assign(t2, binop(Iop_Or64,
1791                       getIReg(ra),
1792                       mkU64(imm)));
1793      MARK_REG_WB(rd, t2);
1794      break;
1795    case 183:
1796      /* Fall-through */
1797    case 184:
1798      /* Fall-through */
1799    case 185:
1800      use_dirty_helper = 1;
1801      break;
1802    case 186:  /* "rotl" */
1803      t0 = newTemp(Ity_I64);
1804      t1 = newTemp(Ity_I64);
1805      t2 = newTemp(Ity_I64);
1806      assign(t0, binop(Iop_Shl64,
1807                       getIReg(ra),
1808                       unop(Iop_64to8, getIReg(rb))));
1809      assign(t1, binop(Iop_Shr64,
1810                       getIReg(ra),
1811                       unop(Iop_64to8, binop(Iop_Sub64,
1812                                             mkU64(0),
1813                                             getIReg(rb)))));
1814      assign(t2, binop(Iop_Or64, mkexpr(t0), mkexpr(t1)));
1815      MARK_REG_WB(rd, t2);
1816      break;
1817    case 187:  /* "rotli" */
1818      t0 = newTemp(Ity_I64);
1819      t1 = newTemp(Ity_I64);
1820      t2 = newTemp(Ity_I64);
1821      assign(t0, binop(Iop_Shl64,
1822                       getIReg(ra),
1823                       mkU8(imm)));
1824      assign(t1, binop(Iop_Shr64,
1825                       getIReg(ra),
1826                       mkU8(0 - imm)));
1827      assign(t2, binop(Iop_Or64, mkexpr(t0), mkexpr(t1)));
1828      MARK_REG_WB(rd, t2);
1829      break;
1830    case 188:   /* "shl" */
1831      t2 = newTemp(Ity_I64);
1832      assign(t2, binop(Iop_Shl64,
1833                       getIReg(ra),
1834                       unop(Iop_64to8, getIReg(rb))));
1835      MARK_REG_WB(rd, t2);
1836
1837      break;
1838    case 189:   /* "shl16insli" */
1839      t2 = newTemp(Ity_I64);
1840      t3 = newTemp(Ity_I64);
1841      assign(t3, binop(Iop_Shl64, getIReg(ra), mkU8(16)));
1842      imm &= 0xFFFFULL;
1843      if (imm & 0x8000)
1844      {
1845        t4 = newTemp(Ity_I64);
1846        assign(t4, mkU64(imm));
1847        assign(t2, binop(Iop_Add64, mkexpr(t3), mkexpr(t4)));
1848      }
1849      else
1850      {
1851        assign(t2, binop(Iop_Add64, mkexpr(t3), mkU64(imm)));
1852      }
1853      MARK_REG_WB(rd, t2);
1854
1855      break;
1856    case 190:   /* "shl1add" */
1857      t2 = newTemp(Ity_I64);
1858      assign(t2, binop(Iop_Add64,
1859                       binop(Iop_Shl64,
1860                             getIReg(ra), mkU8(1)),
1861                       getIReg(rb)));
1862
1863      MARK_REG_WB(rd, t2);
1864      break;
1865    case 191:   /* "shl1addx" */
1866      t2 = newTemp(Ity_I64);
1867      assign(t2,
1868             unop(Iop_32Sto64,
1869                  unop(Iop_64to32,
1870                       binop(Iop_Add64,
1871                             binop(Iop_Shl64,
1872                                   getIReg(ra), mkU8(1)),
1873                             getIReg(rb)))));
1874      MARK_REG_WB(rd, t2);
1875      break;
1876    case 192:   /* "shl2add" */
1877      t2 = newTemp(Ity_I64);
1878      assign(t2, binop(Iop_Add64,
1879                       binop(Iop_Shl64,
1880                             getIReg(ra), mkU8(2)),
1881                       getIReg(rb)));
1882
1883      MARK_REG_WB(rd, t2);
1884
1885      break;
1886    case 193:   /* "shl2addx" */
1887      t2 = newTemp(Ity_I64);
1888      assign(t2,
1889             unop(Iop_32Sto64,
1890                  unop(Iop_64to32,
1891                       binop(Iop_Add64,
1892                             binop(Iop_Shl64,
1893                                   getIReg(ra), mkU8(2)),
1894                             getIReg(rb)))));
1895      MARK_REG_WB(rd, t2);
1896
1897      break;
1898    case 194:   /* "shl3add" */
1899      t2 = newTemp(Ity_I64);
1900      assign(t2, binop(Iop_Add64,
1901                       binop(Iop_Shl64,
1902                             getIReg(ra), mkU8(3)),
1903                       getIReg(rb)));
1904
1905      MARK_REG_WB(rd, t2);
1906      break;
1907    case 195:   /* "shl3addx" */
1908      t2 = newTemp(Ity_I64);
1909      assign(t2,
1910             unop(Iop_32Sto64,
1911                  unop(Iop_64to32,
1912                       binop(Iop_Add64,
1913                             binop(Iop_Shl64,
1914                                   getIReg(ra), mkU8(3)),
1915                             getIReg(rb)))));
1916      MARK_REG_WB(rd, t2);
1917      break;
1918    case 196:   /* "shli" */
1919      t2 = newTemp(Ity_I64);
1920      assign(t2, binop(Iop_Shl64, getIReg(ra),
1921                       mkU8(imm)));
1922      MARK_REG_WB(rd, t2);
1923      break;
1924    case 197:   /* "shlx" */
1925      t2 = newTemp(Ity_I64);
1926      assign(t2, unop(Iop_32Sto64,
1927                      binop(Iop_Shl32,
1928                            narrowTo(Ity_I32, getIReg(ra)),
1929                            narrowTo(Ity_I8, getIReg(rb)))));
1930      MARK_REG_WB(rd, t2);
1931      break;
1932    case 198:   /* "shlxi" */
1933      t2 = newTemp(Ity_I64);
1934      assign(t2, signExtend(binop(Iop_Shl32,
1935                                  narrowTo(Ity_I32, getIReg(ra)),
1936                                  mkU8(imm)),
1937                            32));
1938      MARK_REG_WB(rd, t2);
1939      break;
1940    case 199:  /* "shrs" */
1941      t2 = newTemp(Ity_I64);
1942      assign(t2, binop(Iop_Sar64, getIReg(ra),
1943                       narrowTo(Ity_I8, getIReg(rb))));
1944
1945      MARK_REG_WB(rd, t2);
1946      break;
1947    case 200:  /* "shrsi" */
1948      t2 = newTemp(Ity_I64);
1949      assign(t2, binop(Iop_Sar64, getIReg(ra),
1950                       mkU8(imm)));
1951
1952      MARK_REG_WB(rd, t2);
1953      break;
1954    case 201:  /* "shru" */
1955      t2 = newTemp(Ity_I64);
1956      assign(t2, binop(Iop_Shr64,
1957                       getIReg(ra),
1958                       narrowTo(Ity_I8, (getIReg(rb)))));
1959
1960      MARK_REG_WB(rd, t2);
1961      break;
1962    case 202:  /* "shrui" */
1963      t2 = newTemp(Ity_I64);
1964      assign(t2, binop(Iop_Shr64, getIReg(ra), mkU8(imm)));
1965
1966      MARK_REG_WB(rd, t2);
1967      break;
1968    case 203:  /* "shrux" */
1969      t2 = newTemp(Ity_I64);
1970      assign(t2, unop(Iop_32Sto64,
1971                      (binop(Iop_Shr32,
1972                             narrowTo(Ity_I32, getIReg(ra)),
1973                             narrowTo(Ity_I8, getIReg(rb))))));
1974      MARK_REG_WB(rd, t2);
1975      break;
1976    case 204:  /* "shruxi" */
1977      t2 = newTemp(Ity_I64);
1978      assign(t2, unop(Iop_32Sto64,
1979                      (binop(Iop_Shr32,
1980                             narrowTo(Ity_I32, getIReg(ra)),
1981                             mkU8(imm)))));
1982      MARK_REG_WB(rd, t2);
1983      break;
1984    case 205:  /* "shufflebytes" */
1985      use_dirty_helper = 1;
1986      break;
1987    case 206:  /* "st" */
1988      store(getIReg(ra),  getIReg(rb));
1989      break;
1990    case 207:  /* "st1" */
1991      store(getIReg(ra),  narrowTo(Ity_I8, getIReg(rb)));
1992      break;
1993    case 208:  /* "st1_add" */
1994      t2 = newTemp(Ity_I64);
1995      store(getIReg(opd[0]),  narrowTo(Ity_I8, getIReg(opd[1])));
1996      assign(t2, binop(Iop_Add64, getIReg(opd[0]), mkU64(opd[2])));
1997      MARK_REG_WB(opd[0], t2);
1998      break;
1999    case 209:  /* "st2" */
2000      store(getIReg(ra),  narrowTo(Ity_I16, getIReg(rb)));
2001      break;
2002    case 210:  /* "st2_add" */
2003      t2 = newTemp(Ity_I64);
2004      store(getIReg(opd[0]),  narrowTo(Ity_I16, getIReg(opd[1])));
2005      assign(t2, binop(Iop_Add64, getIReg(opd[0]), mkU64(opd[2])));
2006      MARK_REG_WB(opd[0], t2);
2007      break;
2008    case 211:  /* "st4" */
2009      store(getIReg(ra),  narrowTo(Ity_I32, getIReg(rb)));
2010      break;
2011    case 212:  /* "st4_add" */
2012      t2 = newTemp(Ity_I64);
2013      store(getIReg(opd[0]),  narrowTo(Ity_I32, getIReg(opd[1])));
2014      assign(t2, binop(Iop_Add64, getIReg(opd[0]), mkU64(opd[2])));
2015      MARK_REG_WB(opd[0], t2);
2016      break;
2017    case 213:  /* "st_add" */
2018      t2 = newTemp(Ity_I64);
2019      store(getIReg(opd[0]),  getIReg(opd[1]));
2020      assign(t2, binop(Iop_Add64, getIReg(opd[0]), mkU64(opd[2])));
2021      MARK_REG_WB(opd[0], t2);
2022      break;
2023    case 214:  /* "stnt" */
2024      store(getIReg(ra),  getIReg(rb));
2025      break;
2026    case 215:  /* "stnt1" */
2027      store(getIReg(ra),  narrowTo(Ity_I8, getIReg(rb)));
2028      break;
2029    case 216:  /* "stnt1_add" */
2030      t2 = newTemp(Ity_I64);
2031      store(getIReg(opd[0]),  narrowTo(Ity_I8, getIReg(opd[1])));
2032      assign(t2, binop(Iop_Add64, getIReg(opd[0]), mkU64(opd[2])));
2033      MARK_REG_WB(opd[0], t2);
2034      break;
2035    case 217:  /* "stnt2" */
2036      store(getIReg(ra),  narrowTo(Ity_I16, getIReg(rb)));
2037      break;
2038    case 218:  /* "stnt2_add" */
2039      t2 = newTemp(Ity_I64);
2040      store(getIReg(opd[0]),  narrowTo(Ity_I16, getIReg(opd[1])));
2041      assign(t2, binop(Iop_Add64, getIReg(opd[0]), mkU64(opd[2])));
2042      MARK_REG_WB(opd[0], t2);
2043      break;
2044    case 219:  /* "stnt4" */
2045      store(getIReg(ra),  narrowTo(Ity_I32, getIReg(rb)));
2046      break;
2047    case 220:  /* "stnt4_add" */
2048      t2 = newTemp(Ity_I64);
2049      store(getIReg(opd[0]),  narrowTo(Ity_I32, getIReg(opd[1])));
2050      assign(t2, binop(Iop_Add64, getIReg(opd[0]), mkU64(opd[2])));
2051      MARK_REG_WB(opd[0], t2);
2052      break;
2053    case 221:  /* "stnt_add" */
2054      t2 = newTemp(Ity_I64);
2055      store(getIReg(opd[0]),  getIReg(opd[1]));
2056      assign(t2, binop(Iop_Add64, getIReg(opd[0]), mkU64(opd[2])));
2057      MARK_REG_WB(opd[0], t2);
2058      break;
2059    case 222:  /* "sub" */
2060      t2 = newTemp(Ity_I64);
2061      assign(t2, binop(Iop_Sub64, getIReg(ra),
2062                       getIReg(rb)));
2063      MARK_REG_WB(rd, t2);
2064      break;
2065    case 223:  /* "subx" */
2066      t2 = newTemp(Ity_I64);
2067      assign(t2,  unop(Iop_32Sto64,
2068                       binop(Iop_Sub32,
2069                             narrowTo(Ity_I32, getIReg(ra)),
2070                             narrowTo(Ity_I32, getIReg(rb)))));
2071      MARK_REG_WB(rd, t2);
2072      break;
2073    case 224:  /* "subxsc" */
2074      use_dirty_helper = 1;
2075      break;
2076    case 225:  /* "swint0" */
2077      vex_printf( "\n *** swint0 ***\n");
2078      vassert(0);
2079      break;
2080    case 226:  /* "swint1" */
2081      next = mkU64(guest_PC_curr_instr + 8);
2082      jumpkind = Ijk_Sys_syscall;
2083      break;
2084    case 227:  /* "swint2" */
2085      vex_printf( "\n *** swint2 ***\n");
2086      vassert(0);
2087      break;
2088    case 228:  /* "swint3" */
2089      vex_printf( "\n *** swint3 ***\n");
2090      vassert(0);
2091      break;
2092    case 229:
2093      /* Fall-through */
2094    case 230:
2095      /* Fall-through */
2096    case 231:
2097      /* Fall-through */
2098    case 232:
2099      /* Fall-through */
2100    case 233:
2101      use_dirty_helper = 1;
2102      break;
2103    case 234:
2104      opd[3] = V1EXP(opd[3]);
2105      use_dirty_helper = 1;
2106      break;
2107    case 235:
2108      /* Fall-through */
2109    case 236:
2110      /* Fall-through */
2111    case 237:
2112      use_dirty_helper = 1;
2113      break;
2114    case 238:  /* "v1cmpeq" */
2115      t2 = newTemp(Ity_I64);
2116      assign(t2, binop(Iop_CmpEQ8x8, getIReg(ra),
2117                       getIReg(rb)));
2118      MARK_REG_WB(rd, t2);
2119      break;
2120    case 239:  /* "v1cmpeqi" */
2121      t2 = newTemp(Ity_I64);
2122      assign(t2, binop(Iop_CmpEQ8x8, getIReg(ra),
2123                       mkU64(imm)));
2124
2125      MARK_REG_WB(rd, t2);
2126      break;
2127    case 240:
2128      /* Fall-through */
2129    case 241:
2130      /* Fall-through */
2131    case 242:
2132      use_dirty_helper = 1;
2133      break;
2134    case 243:
2135      opd[3] = V1EXP(opd[3]);
2136      use_dirty_helper = 1;
2137      break;
2138      /* Fall-through */
2139    case 244:
2140      use_dirty_helper = 1;
2141      break;
2142    case 245:
2143      opd[3] = V1EXP(opd[3]);
2144      use_dirty_helper = 1;
2145      break;
2146    case 246:  /* "v1cmpne" */
2147      t2 = newTemp(Ity_I64);
2148      assign(t2, binop(Iop_CmpEQ8x8,
2149                       binop(Iop_CmpEQ8x8, getIReg(ra),
2150                             getIReg(rb)),
2151                       getIReg(63)));
2152      MARK_REG_WB(rd, t2);
2153      break;
2154    case 247:
2155      /* Fall-through */
2156    case 248:
2157      /* Fall-through */
2158    case 249:
2159      /* Fall-through */
2160    case 250:
2161      /* Fall-through */
2162    case 251:
2163      /* Fall-through */
2164    case 252:
2165      /* Fall-through */
2166    case 253:
2167      /* Fall-through */
2168    case 254:
2169      /* Fall-through */
2170    case 255:
2171      /* Fall-through */
2172    case 256:
2173      /* Fall-through */
2174    case 257:
2175      /* Fall-through */
2176    case 258:
2177      /* Fall-through */
2178    case 259:
2179      use_dirty_helper = 1;
2180      break;
2181    case 260:
2182      opd[3] = V1EXP(opd[3]);
2183      use_dirty_helper = 1;
2184      break;
2185    case 261:
2186      use_dirty_helper = 1;
2187      break;
2188    case 262:
2189      opd[3] = V1EXP(opd[3]);
2190      use_dirty_helper = 1;
2191      break;
2192    case 263:
2193      /* Fall-through */
2194    case 264:
2195      /* Fall-through */
2196    case 265:
2197      /* Fall-through */
2198    case 266:
2199      /* Fall-through */
2200    case 267:
2201      /* Fall-through */
2202    case 268:
2203      /* Fall-through */
2204    case 269:
2205      /* Fall-through */
2206    case 270:
2207      use_dirty_helper = 1;
2208      break;
2209    case 271:
2210      opd[3] = V1EXP(opd[3]);
2211      use_dirty_helper = 1;
2212      break;
2213    case 272:
2214      use_dirty_helper = 1;
2215      break;
2216    case 273:
2217      opd[3] = V1EXP(opd[3]);
2218      use_dirty_helper = 1;
2219      break;
2220    case 274:
2221      use_dirty_helper = 1;
2222      break;
2223    case 275:  /* "v1shrui" */
2224      t2 = newTemp(Ity_I64);
2225      assign(t2, binop(Iop_Shr8x8,
2226                       getIReg(ra),
2227                       mkU64(imm)));
2228      MARK_REG_WB(rd, t2);
2229      break;
2230    case 276:
2231      /* Fall-through */
2232    case 277:
2233      /* Fall-through */
2234    case 278:
2235      use_dirty_helper = 1;
2236      break;
2237    case 279:
2238      opd[3] = V2EXP(opd[3]);
2239      use_dirty_helper = 1;
2240      break;
2241    case 280:
2242      /* Fall-through */
2243    case 281:
2244      /* Fall-through */
2245    case 282:
2246      /* Fall-through */
2247    case 283:
2248      use_dirty_helper = 1;
2249      break;
2250    case 284:
2251      opd[3] = V2EXP(opd[3]);
2252      use_dirty_helper = 1;
2253      break;
2254    case 285:
2255      /* Fall-through */
2256    case 286:
2257      /* Fall-through */
2258    case 287:
2259      use_dirty_helper = 1;
2260      break;
2261    case 288:
2262      opd[3] = V2EXP(opd[3]);
2263      use_dirty_helper = 1;
2264      break;
2265    case 289:
2266      use_dirty_helper = 1;
2267      break;
2268    case 290:
2269      opd[3] = V2EXP(opd[3]);
2270      use_dirty_helper = 1;
2271      break;
2272    case 291:
2273      /* Fall-through */
2274    case 292:
2275      /* Fall-through */
2276    case 293:
2277      /* Fall-through */
2278    case 294:
2279      /* Fall-through */
2280    case 295:
2281      /* Fall-through */
2282    case 296:
2283      use_dirty_helper = 1;
2284      break;
2285    case 297:
2286      opd[3] = V2EXP(opd[3]);
2287      use_dirty_helper = 1;
2288      break;
2289    case 298:
2290      use_dirty_helper = 1;
2291      break;
2292    case 299:
2293      opd[3] = V2EXP(opd[3]);
2294      use_dirty_helper = 1;
2295      break;
2296    case 300:
2297      /* Fall-through */
2298    case 301:
2299      /* Fall-through */
2300    case 302:
2301      /* Fall-through */
2302    case 303:
2303      /* Fall-through */
2304    case 304:
2305      /* Fall-through */
2306    case 305:
2307      /* Fall-through */
2308    case 306:
2309      /* Fall-through */
2310    case 307:
2311      /* Fall-through */
2312    case 308:
2313      /* Fall-through */
2314    case 309:
2315      /* Fall-through */
2316    case 310:
2317      /* Fall-through */
2318    case 311:
2319      /* Fall-through */
2320    case 312:
2321      use_dirty_helper = 1;
2322      break;
2323    case 313:
2324      opd[3] = V2EXP(opd[3]);
2325      use_dirty_helper = 1;
2326      break;
2327    case 314:
2328      /* Fall-through */
2329    case 315:
2330      use_dirty_helper = 1;
2331      break;
2332    case 316:
2333      opd[3] = V2EXP(opd[3]);
2334      use_dirty_helper = 1;
2335      break;
2336    case 317:
2337      use_dirty_helper = 1;
2338      break;
2339    case 318:
2340      opd[3] = V2EXP(opd[3]);
2341      use_dirty_helper = 1;
2342      break;
2343    case 319:
2344      /* Fall-through */
2345    case 320:
2346      /* Fall-through */
2347    case 321:
2348      /* Fall-through */
2349    case 322:
2350      /* Fall-through */
2351    case 323:
2352      use_dirty_helper = 1;
2353      break;
2354    case 324:   /* "v4int_l" */
2355      t2 = newTemp(Ity_I64);
2356      assign(t2, binop(Iop_Or64,
2357                       binop(Iop_Shl64,
2358                             getIReg(ra),
2359                             mkU8(32)),
2360                       binop(Iop_And64,
2361                             getIReg(rb),
2362                             mkU64(0xFFFFFFFF))));
2363      MARK_REG_WB(rd, t2);
2364      break;
2365    case 325:
2366      /* Fall-through */
2367    case 326:
2368      /* Fall-through */
2369    case 327:
2370      /* Fall-through */
2371    case 328:
2372      /* Fall-through */
2373    case 329:
2374      /* Fall-through */
2375    case 330:
2376      /* Fall-through */
2377    case 331:
2378      use_dirty_helper = 1;
2379      break;
2380    case 332:   /* "wh64" */     /* Ignore store hint */
2381      break;
2382    case 333:   /* "xor" */
2383      t2 = newTemp(Ity_I64);
2384      assign(t2, binop(Iop_Xor64,
2385                       getIReg(ra),
2386                       getIReg(rb)));
2387      MARK_REG_WB(rd, t2);
2388      break;
2389    case 334:   /* "xori" */
2390      t2 = newTemp(Ity_I64);
2391      assign(t2, binop(Iop_Xor64,
2392                       getIReg(ra),
2393                       mkU64(imm)));
2394      MARK_REG_WB(rd, t2);
2395      break;
2396    case 335:  /* "(null)" */   /* ignore */
2397      break;
2398    default:
2399
2400    decode_failure:
2401      vex_printf("error: %d\n",  (Int)opcode);
2402
2403      /* All decode failures end up here. */
2404      vex_printf("vex tilegx->IR: unhandled instruction: "
2405                 "%s 0x%llx 0x%llx 0x%llx 0x%llx\n",
2406                 decoded[n].opcode->name,
2407                 opd[0], opd[1], opd[2], opd[3]);
2408
2409      /* Tell the dispatcher that this insn cannot be decoded, and so has
2410         not been executed, and (is currently) the next to be executed. */
2411      stmt(IRStmt_Put(offsetof(VexGuestTILEGXState, guest_pc),
2412                      mkU64(guest_PC_curr_instr)));
2413      dres.whatNext = Dis_StopHere;
2414      dres.len = 0;
2415      return dres;
2416    }
2417
2418    /* Hook the dirty helper for rare instruxtions. */
2419    if (use_dirty_helper)
2420    {
2421      Int i = 0;
2422      Int wbc = 0;
2423      IRExpr *opc_oprand[5];
2424
2425      opc_oprand[0] = mkU64(opcode);
2426
2427      /* Get the operand registers or immediate. */
2428      for (i = 0 ; i < 4; i++)
2429      {
2430        opc_oprand[i + 1] = NULL;
2431
2432        if (opd_dst_map & (1ULL << i))
2433        {
2434          tb[wbc] = newTemp(Ity_I64);
2435          wbc++;
2436          opc_oprand[i + 1] = getIReg(opd[i]);
2437        }
2438        else if (opd_imm_map & (1ULL << i))
2439          opc_oprand[i + 1] = mkU64(opd[i]);
2440        else if (opd_src_map & (1ULL << i))
2441          opc_oprand[i + 1] = getIReg(opd[i]);
2442        else
2443          opc_oprand[i + 1] = mkU64(0xfeee);
2444      }
2445
2446      IRExpr **args = mkIRExprVec_5(opc_oprand[0], opc_oprand[1],
2447                                    opc_oprand[2], opc_oprand[3],
2448                                    opc_oprand[4]);
2449      IRDirty *genIR = NULL;
2450
2451      switch (wbc) {
2452      case 0:
2453        {
2454          genIR = unsafeIRDirty_0_N (0/*regparms*/,
2455                                     "tilegx_dirtyhelper_gen",
2456                                     &tilegx_dirtyhelper_gen,
2457                                     args);
2458        }
2459        break;
2460      case 1:
2461        {
2462          genIR = unsafeIRDirty_1_N (tb[0],
2463                                     0/*regparms*/,
2464                                     "tilegx_dirtyhelper_gen",
2465                                     &tilegx_dirtyhelper_gen,
2466                                     args);
2467        }
2468        break;
2469      default:
2470        vex_printf("opc = %d\n", (Int)opcode);
2471        vassert(0);
2472      }
2473
2474      stmt(IRStmt_Dirty(genIR));
2475
2476      wbc = 0;
2477      for (i = 0 ; i < 4; i++)
2478      {
2479        if(opd_dst_map & (1 << i))
2480        {
2481          /* Queue the writeback destination registers. */
2482          MARK_REG_WB(opd[i], tb[wbc]);
2483          wbc++;
2484        }
2485      }
2486    }
2487  }
2488
2489  /* Write back registers for a bundle. Note have to get all source registers
2490     for all instructions in a bundle before write the destinations b/c this is
2491     an VLIW processor. */
2492  for (n = 0; n < rd_wb_index; n++)
2493    putIReg(rd_wb_reg[n], mkexpr(rd_wb_temp[n]));
2494
2495  /* Add branch IR if apply finally, only upto one branch per bundle. */
2496  if (bstmt) {
2497    stmt(bstmt);
2498    dres.whatNext = Dis_StopHere;
2499
2500    dres.jk_StopHere = jumpkind;
2501    stmt(IRStmt_Put(offsetof(VexGuestTILEGXState, guest_pc),
2502                    mkU64(guest_PC_curr_instr + 8)));
2503  } else if (next) {
2504    if (steering_pc != -1ULL) {
2505      if (resteerOkFn(callback_opaque, steering_pc)) {
2506        dres.whatNext   = Dis_ResteerU;
2507        dres.continueAt = steering_pc;
2508        stmt(IRStmt_Put(offsetof(VexGuestTILEGXState, guest_pc),
2509                        mkU64(steering_pc)));
2510      } else {
2511        dres.whatNext = Dis_StopHere;
2512        dres.jk_StopHere = jumpkind;
2513        stmt(IRStmt_Put(offsetof(VexGuestTILEGXState, guest_pc),
2514                        mkU64(steering_pc)));
2515      }
2516    } else {
2517      dres.whatNext = Dis_StopHere;
2518      dres.jk_StopHere = jumpkind;
2519      stmt(IRStmt_Put(offsetof(VexGuestTILEGXState, guest_pc), next));
2520    }
2521  } else {
2522    /* As dafault dres.whatNext = Dis_Continue. */
2523    stmt(IRStmt_Put(offsetof(VexGuestTILEGXState, guest_pc),
2524                    mkU64(guest_PC_curr_instr + 8)));
2525  }
2526
2527  irsb->jumpkind = Ijk_Boring;
2528  irsb->next = NULL;
2529  dres.len = 8;
2530
2531 decode_success:
2532
2533  return dres;
2534}
2535
2536/*------------------------------------------------------------*/
2537/*--- Top-level fn                                         ---*/
2538/*------------------------------------------------------------*/
2539
2540/* Disassemble a single instruction into IR.  The instruction
2541   is located in host memory at &guest_code[delta]. */
2542
2543DisResult
2544disInstr_TILEGX ( IRSB* irsb_IN,
2545                  Bool (*resteerOkFn) (void *, Addr),
2546                  Bool resteerCisOk,
2547                  void* callback_opaque,
2548                  const UChar* guest_code_IN,
2549                  Long delta,
2550                  Addr guest_IP,
2551                  VexArch guest_arch,
2552                  const VexArchInfo* archinfo,
2553                  const VexAbiInfo* abiinfo,
2554                  VexEndness host_endness_IN,
2555                  Bool sigill_diag_IN )
2556{
2557  DisResult dres;
2558
2559  /* Set globals (see top of this file) */
2560  vassert(guest_arch == VexArchTILEGX);
2561
2562  guest_code = (UChar*)(Addr)guest_code_IN;
2563  irsb = irsb_IN;
2564  host_endness = host_endness_IN;
2565  guest_PC_curr_instr = (Addr64) guest_IP;
2566  guest_PC_bbstart = (Addr64) toUInt(guest_IP - delta);
2567
2568  dres = disInstr_TILEGX_WRK(resteerOkFn, resteerCisOk,
2569                             callback_opaque,
2570                             delta, archinfo, abiinfo, sigill_diag_IN);
2571
2572  return dres;
2573}
2574
2575/*--------------------------------------------------------------------*/
2576/*--- end                                      guest_tilegx_toIR.c ---*/
2577/*--------------------------------------------------------------------*/
2578