xref: /openbmc/qemu/target/s390x/tcg/translate.c (revision ecdfa31beb1f7616091bedba79dfdf9ee525ed9d)
1  /*
2   *  S/390 translation
3   *
4   *  Copyright (c) 2009 Ulrich Hecht
5   *  Copyright (c) 2010 Alexander Graf
6   *
7   * This library is free software; you can redistribute it and/or
8   * modify it under the terms of the GNU Lesser General Public
9   * License as published by the Free Software Foundation; either
10   * version 2.1 of the License, or (at your option) any later version.
11   *
12   * This library is distributed in the hope that it will be useful,
13   * but WITHOUT ANY WARRANTY; without even the implied warranty of
14   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15   * Lesser General Public License for more details.
16   *
17   * You should have received a copy of the GNU Lesser General Public
18   * License along with this library; if not, see <http://www.gnu.org/licenses/>.
19   */
20  
21  /* #define DEBUG_INLINE_BRANCHES */
22  #define S390X_DEBUG_DISAS
23  /* #define S390X_DEBUG_DISAS_VERBOSE */
24  
25  #ifdef S390X_DEBUG_DISAS_VERBOSE
26  #  define LOG_DISAS(...) qemu_log(__VA_ARGS__)
27  #else
28  #  define LOG_DISAS(...) do { } while (0)
29  #endif
30  
31  #include "qemu/osdep.h"
32  #include "cpu.h"
33  #include "s390x-internal.h"
34  #include "exec/exec-all.h"
35  #include "tcg/tcg-op.h"
36  #include "tcg/tcg-op-gvec.h"
37  #include "qemu/log.h"
38  #include "qemu/host-utils.h"
39  #include "exec/helper-proto.h"
40  #include "exec/helper-gen.h"
41  
42  #include "exec/translator.h"
43  #include "exec/log.h"
44  #include "qemu/atomic128.h"
45  
46  #define HELPER_H "helper.h"
47  #include "exec/helper-info.c.inc"
48  #undef  HELPER_H
49  
50  
51  /* Information that (most) every instruction needs to manipulate.  */
52  typedef struct DisasContext DisasContext;
53  typedef struct DisasInsn DisasInsn;
54  typedef struct DisasFields DisasFields;
55  
56  /*
57   * Define a structure to hold the decoded fields.  We'll store each inside
58   * an array indexed by an enum.  In order to conserve memory, we'll arrange
59   * for fields that do not exist at the same time to overlap, thus the "C"
60   * for compact.  For checking purposes there is an "O" for original index
61   * as well that will be applied to availability bitmaps.
62   */
63  
64  enum DisasFieldIndexO {
65      FLD_O_r1,
66      FLD_O_r2,
67      FLD_O_r3,
68      FLD_O_m1,
69      FLD_O_m3,
70      FLD_O_m4,
71      FLD_O_m5,
72      FLD_O_m6,
73      FLD_O_b1,
74      FLD_O_b2,
75      FLD_O_b4,
76      FLD_O_d1,
77      FLD_O_d2,
78      FLD_O_d4,
79      FLD_O_x2,
80      FLD_O_l1,
81      FLD_O_l2,
82      FLD_O_i1,
83      FLD_O_i2,
84      FLD_O_i3,
85      FLD_O_i4,
86      FLD_O_i5,
87      FLD_O_v1,
88      FLD_O_v2,
89      FLD_O_v3,
90      FLD_O_v4,
91  };
92  
93  enum DisasFieldIndexC {
94      FLD_C_r1 = 0,
95      FLD_C_m1 = 0,
96      FLD_C_b1 = 0,
97      FLD_C_i1 = 0,
98      FLD_C_v1 = 0,
99  
100      FLD_C_r2 = 1,
101      FLD_C_b2 = 1,
102      FLD_C_i2 = 1,
103  
104      FLD_C_r3 = 2,
105      FLD_C_m3 = 2,
106      FLD_C_i3 = 2,
107      FLD_C_v3 = 2,
108  
109      FLD_C_m4 = 3,
110      FLD_C_b4 = 3,
111      FLD_C_i4 = 3,
112      FLD_C_l1 = 3,
113      FLD_C_v4 = 3,
114  
115      FLD_C_i5 = 4,
116      FLD_C_d1 = 4,
117      FLD_C_m5 = 4,
118  
119      FLD_C_d2 = 5,
120      FLD_C_m6 = 5,
121  
122      FLD_C_d4 = 6,
123      FLD_C_x2 = 6,
124      FLD_C_l2 = 6,
125      FLD_C_v2 = 6,
126  
127      NUM_C_FIELD = 7
128  };
129  
130  struct DisasFields {
131      uint64_t raw_insn;
132      unsigned op:8;
133      unsigned op2:8;
134      unsigned presentC:16;
135      unsigned int presentO;
136      int c[NUM_C_FIELD];
137  };
138  
139  struct DisasContext {
140      DisasContextBase base;
141      const DisasInsn *insn;
142      DisasFields fields;
143      uint64_t ex_value;
144      /*
145       * During translate_one(), pc_tmp is used to determine the instruction
146       * to be executed after base.pc_next - e.g. next sequential instruction
147       * or a branch target.
148       */
149      uint64_t pc_tmp;
150      uint32_t ilen;
151      enum cc_op cc_op;
152      bool exit_to_mainloop;
153  };
154  
155  /* Information carried about a condition to be evaluated.  */
156  typedef struct {
157      TCGCond cond:8;
158      bool is_64;
159      union {
160          struct { TCGv_i64 a, b; } s64;
161          struct { TCGv_i32 a, b; } s32;
162      } u;
163  } DisasCompare;
164  
165  #ifdef DEBUG_INLINE_BRANCHES
166  static uint64_t inline_branch_hit[CC_OP_MAX];
167  static uint64_t inline_branch_miss[CC_OP_MAX];
168  #endif
169  
pc_to_link_info(TCGv_i64 out,DisasContext * s,uint64_t pc)170  static void pc_to_link_info(TCGv_i64 out, DisasContext *s, uint64_t pc)
171  {
172      if (s->base.tb->flags & FLAG_MASK_32) {
173          if (s->base.tb->flags & FLAG_MASK_64) {
174              tcg_gen_movi_i64(out, pc);
175              return;
176          }
177          pc |= 0x80000000;
178      }
179      assert(!(s->base.tb->flags & FLAG_MASK_64));
180      tcg_gen_deposit_i64(out, out, tcg_constant_i64(pc), 0, 32);
181  }
182  
183  static TCGv_i64 psw_addr;
184  static TCGv_i64 psw_mask;
185  static TCGv_i64 gbea;
186  
187  static TCGv_i32 cc_op;
188  static TCGv_i64 cc_src;
189  static TCGv_i64 cc_dst;
190  static TCGv_i64 cc_vr;
191  
192  static char cpu_reg_names[16][4];
193  static TCGv_i64 regs[16];
194  
s390x_translate_init(void)195  void s390x_translate_init(void)
196  {
197      int i;
198  
199      psw_addr = tcg_global_mem_new_i64(tcg_env,
200                                        offsetof(CPUS390XState, psw.addr),
201                                        "psw_addr");
202      psw_mask = tcg_global_mem_new_i64(tcg_env,
203                                        offsetof(CPUS390XState, psw.mask),
204                                        "psw_mask");
205      gbea = tcg_global_mem_new_i64(tcg_env,
206                                    offsetof(CPUS390XState, gbea),
207                                    "gbea");
208  
209      cc_op = tcg_global_mem_new_i32(tcg_env, offsetof(CPUS390XState, cc_op),
210                                     "cc_op");
211      cc_src = tcg_global_mem_new_i64(tcg_env, offsetof(CPUS390XState, cc_src),
212                                      "cc_src");
213      cc_dst = tcg_global_mem_new_i64(tcg_env, offsetof(CPUS390XState, cc_dst),
214                                      "cc_dst");
215      cc_vr = tcg_global_mem_new_i64(tcg_env, offsetof(CPUS390XState, cc_vr),
216                                     "cc_vr");
217  
218      for (i = 0; i < 16; i++) {
219          snprintf(cpu_reg_names[i], sizeof(cpu_reg_names[0]), "r%d", i);
220          regs[i] = tcg_global_mem_new(tcg_env,
221                                       offsetof(CPUS390XState, regs[i]),
222                                       cpu_reg_names[i]);
223      }
224  }
225  
vec_full_reg_offset(uint8_t reg)226  static inline int vec_full_reg_offset(uint8_t reg)
227  {
228      g_assert(reg < 32);
229      return offsetof(CPUS390XState, vregs[reg][0]);
230  }
231  
vec_reg_offset(uint8_t reg,uint8_t enr,MemOp es)232  static inline int vec_reg_offset(uint8_t reg, uint8_t enr, MemOp es)
233  {
234      /* Convert element size (es) - e.g. MO_8 - to bytes */
235      const uint8_t bytes = 1 << es;
236      int offs = enr * bytes;
237  
238      /*
239       * vregs[n][0] is the lowest 8 byte and vregs[n][1] the highest 8 byte
240       * of the 16 byte vector, on both, little and big endian systems.
241       *
242       * Big Endian (target/possible host)
243       * B:  [ 0][ 1][ 2][ 3][ 4][ 5][ 6][ 7] - [ 8][ 9][10][11][12][13][14][15]
244       * HW: [     0][     1][     2][     3] - [     4][     5][     6][     7]
245       * W:  [             0][             1] - [             2][             3]
246       * DW: [                             0] - [                             1]
247       *
248       * Little Endian (possible host)
249       * B:  [ 7][ 6][ 5][ 4][ 3][ 2][ 1][ 0] - [15][14][13][12][11][10][ 9][ 8]
250       * HW: [     3][     2][     1][     0] - [     7][     6][     5][     4]
251       * W:  [             1][             0] - [             3][             2]
252       * DW: [                             0] - [                             1]
253       *
254       * For 16 byte elements, the two 8 byte halves will not form a host
255       * int128 if the host is little endian, since they're in the wrong order.
256       * Some operations (e.g. xor) do not care. For operations like addition,
257       * the two 8 byte elements have to be loaded separately. Let's force all
258       * 16 byte operations to handle it in a special way.
259       */
260      g_assert(es <= MO_64);
261  #if !HOST_BIG_ENDIAN
262      offs ^= (8 - bytes);
263  #endif
264      return offs + vec_full_reg_offset(reg);
265  }
266  
freg64_offset(uint8_t reg)267  static inline int freg64_offset(uint8_t reg)
268  {
269      g_assert(reg < 16);
270      return vec_reg_offset(reg, 0, MO_64);
271  }
272  
freg32_offset(uint8_t reg)273  static inline int freg32_offset(uint8_t reg)
274  {
275      g_assert(reg < 16);
276      return vec_reg_offset(reg, 0, MO_32);
277  }
278  
load_reg(int reg)279  static TCGv_i64 load_reg(int reg)
280  {
281      TCGv_i64 r = tcg_temp_new_i64();
282      tcg_gen_mov_i64(r, regs[reg]);
283      return r;
284  }
285  
load_freg(int reg)286  static TCGv_i64 load_freg(int reg)
287  {
288      TCGv_i64 r = tcg_temp_new_i64();
289  
290      tcg_gen_ld_i64(r, tcg_env, freg64_offset(reg));
291      return r;
292  }
293  
load_freg32_i64(int reg)294  static TCGv_i64 load_freg32_i64(int reg)
295  {
296      TCGv_i64 r = tcg_temp_new_i64();
297  
298      tcg_gen_ld32u_i64(r, tcg_env, freg32_offset(reg));
299      return r;
300  }
301  
load_freg_128(int reg)302  static TCGv_i128 load_freg_128(int reg)
303  {
304      TCGv_i64 h = load_freg(reg);
305      TCGv_i64 l = load_freg(reg + 2);
306      TCGv_i128 r = tcg_temp_new_i128();
307  
308      tcg_gen_concat_i64_i128(r, l, h);
309      return r;
310  }
311  
store_reg(int reg,TCGv_i64 v)312  static void store_reg(int reg, TCGv_i64 v)
313  {
314      tcg_gen_mov_i64(regs[reg], v);
315  }
316  
store_freg(int reg,TCGv_i64 v)317  static void store_freg(int reg, TCGv_i64 v)
318  {
319      tcg_gen_st_i64(v, tcg_env, freg64_offset(reg));
320  }
321  
store_reg32_i64(int reg,TCGv_i64 v)322  static void store_reg32_i64(int reg, TCGv_i64 v)
323  {
324      /* 32 bit register writes keep the upper half */
325      tcg_gen_deposit_i64(regs[reg], regs[reg], v, 0, 32);
326  }
327  
store_reg32h_i64(int reg,TCGv_i64 v)328  static void store_reg32h_i64(int reg, TCGv_i64 v)
329  {
330      tcg_gen_deposit_i64(regs[reg], regs[reg], v, 32, 32);
331  }
332  
store_freg32_i64(int reg,TCGv_i64 v)333  static void store_freg32_i64(int reg, TCGv_i64 v)
334  {
335      tcg_gen_st32_i64(v, tcg_env, freg32_offset(reg));
336  }
337  
update_psw_addr(DisasContext * s)338  static void update_psw_addr(DisasContext *s)
339  {
340      /* psw.addr */
341      tcg_gen_movi_i64(psw_addr, s->base.pc_next);
342  }
343  
per_branch(DisasContext * s,TCGv_i64 dest)344  static void per_branch(DisasContext *s, TCGv_i64 dest)
345  {
346  #ifndef CONFIG_USER_ONLY
347      if (s->base.tb->flags & FLAG_MASK_PER_BRANCH) {
348          gen_helper_per_branch(tcg_env, dest, tcg_constant_i32(s->ilen));
349      }
350  #endif
351  }
352  
per_breaking_event(DisasContext * s)353  static void per_breaking_event(DisasContext *s)
354  {
355      tcg_gen_movi_i64(gbea, s->base.pc_next);
356  }
357  
update_cc_op(DisasContext * s)358  static void update_cc_op(DisasContext *s)
359  {
360      if (s->cc_op != CC_OP_DYNAMIC && s->cc_op != CC_OP_STATIC) {
361          tcg_gen_movi_i32(cc_op, s->cc_op);
362      }
363  }
364  
ld_code2(CPUS390XState * env,DisasContext * s,uint64_t pc)365  static inline uint64_t ld_code2(CPUS390XState *env, DisasContext *s,
366                                  uint64_t pc)
367  {
368      return (uint64_t)translator_lduw(env, &s->base, pc);
369  }
370  
ld_code4(CPUS390XState * env,DisasContext * s,uint64_t pc)371  static inline uint64_t ld_code4(CPUS390XState *env, DisasContext *s,
372                                  uint64_t pc)
373  {
374      return (uint64_t)(uint32_t)translator_ldl(env, &s->base, pc);
375  }
376  
get_mem_index(DisasContext * s)377  static int get_mem_index(DisasContext *s)
378  {
379  #ifdef CONFIG_USER_ONLY
380      return MMU_USER_IDX;
381  #else
382      if (!(s->base.tb->flags & FLAG_MASK_DAT)) {
383          return MMU_REAL_IDX;
384      }
385  
386      switch (s->base.tb->flags & FLAG_MASK_ASC) {
387      case PSW_ASC_PRIMARY >> FLAG_MASK_PSW_SHIFT:
388          return MMU_PRIMARY_IDX;
389      case PSW_ASC_SECONDARY >> FLAG_MASK_PSW_SHIFT:
390          return MMU_SECONDARY_IDX;
391      case PSW_ASC_HOME >> FLAG_MASK_PSW_SHIFT:
392          return MMU_HOME_IDX;
393      default:
394          g_assert_not_reached();
395      }
396  #endif
397  }
398  
gen_exception(int excp)399  static void gen_exception(int excp)
400  {
401      gen_helper_exception(tcg_env, tcg_constant_i32(excp));
402  }
403  
gen_program_exception(DisasContext * s,int code)404  static void gen_program_exception(DisasContext *s, int code)
405  {
406      /* Remember what pgm exception this was.  */
407      tcg_gen_st_i32(tcg_constant_i32(code), tcg_env,
408                     offsetof(CPUS390XState, int_pgm_code));
409  
410      tcg_gen_st_i32(tcg_constant_i32(s->ilen), tcg_env,
411                     offsetof(CPUS390XState, int_pgm_ilen));
412  
413      /* update the psw */
414      update_psw_addr(s);
415  
416      /* Save off cc.  */
417      update_cc_op(s);
418  
419      /* Trigger exception.  */
420      gen_exception(EXCP_PGM);
421  }
422  
gen_illegal_opcode(DisasContext * s)423  static inline void gen_illegal_opcode(DisasContext *s)
424  {
425      gen_program_exception(s, PGM_OPERATION);
426  }
427  
gen_data_exception(uint8_t dxc)428  static inline void gen_data_exception(uint8_t dxc)
429  {
430      gen_helper_data_exception(tcg_env, tcg_constant_i32(dxc));
431  }
432  
gen_trap(DisasContext * s)433  static inline void gen_trap(DisasContext *s)
434  {
435      /* Set DXC to 0xff */
436      gen_data_exception(0xff);
437  }
438  
gen_addi_and_wrap_i64(DisasContext * s,TCGv_i64 dst,TCGv_i64 src,int64_t imm)439  static void gen_addi_and_wrap_i64(DisasContext *s, TCGv_i64 dst, TCGv_i64 src,
440                                    int64_t imm)
441  {
442      tcg_gen_addi_i64(dst, src, imm);
443      if (!(s->base.tb->flags & FLAG_MASK_64)) {
444          if (s->base.tb->flags & FLAG_MASK_32) {
445              tcg_gen_andi_i64(dst, dst, 0x7fffffff);
446          } else {
447              tcg_gen_andi_i64(dst, dst, 0x00ffffff);
448          }
449      }
450  }
451  
get_address(DisasContext * s,int x2,int b2,int d2)452  static TCGv_i64 get_address(DisasContext *s, int x2, int b2, int d2)
453  {
454      TCGv_i64 tmp = tcg_temp_new_i64();
455  
456      /*
457       * Note that d2 is limited to 20 bits, signed.  If we crop negative
458       * displacements early we create larger immediate addends.
459       */
460      if (b2 && x2) {
461          tcg_gen_add_i64(tmp, regs[b2], regs[x2]);
462          gen_addi_and_wrap_i64(s, tmp, tmp, d2);
463      } else if (b2) {
464          gen_addi_and_wrap_i64(s, tmp, regs[b2], d2);
465      } else if (x2) {
466          gen_addi_and_wrap_i64(s, tmp, regs[x2], d2);
467      } else if (!(s->base.tb->flags & FLAG_MASK_64)) {
468          if (s->base.tb->flags & FLAG_MASK_32) {
469              tcg_gen_movi_i64(tmp, d2 & 0x7fffffff);
470          } else {
471              tcg_gen_movi_i64(tmp, d2 & 0x00ffffff);
472          }
473      } else {
474          tcg_gen_movi_i64(tmp, d2);
475      }
476  
477      return tmp;
478  }
479  
live_cc_data(DisasContext * s)480  static inline bool live_cc_data(DisasContext *s)
481  {
482      return (s->cc_op != CC_OP_DYNAMIC
483              && s->cc_op != CC_OP_STATIC
484              && s->cc_op > 3);
485  }
486  
gen_op_movi_cc(DisasContext * s,uint32_t val)487  static inline void gen_op_movi_cc(DisasContext *s, uint32_t val)
488  {
489      if (live_cc_data(s)) {
490          tcg_gen_discard_i64(cc_src);
491          tcg_gen_discard_i64(cc_dst);
492          tcg_gen_discard_i64(cc_vr);
493      }
494      s->cc_op = CC_OP_CONST0 + val;
495  }
496  
gen_op_update1_cc_i64(DisasContext * s,enum cc_op op,TCGv_i64 dst)497  static void gen_op_update1_cc_i64(DisasContext *s, enum cc_op op, TCGv_i64 dst)
498  {
499      if (live_cc_data(s)) {
500          tcg_gen_discard_i64(cc_src);
501          tcg_gen_discard_i64(cc_vr);
502      }
503      tcg_gen_mov_i64(cc_dst, dst);
504      s->cc_op = op;
505  }
506  
gen_op_update2_cc_i64(DisasContext * s,enum cc_op op,TCGv_i64 src,TCGv_i64 dst)507  static void gen_op_update2_cc_i64(DisasContext *s, enum cc_op op, TCGv_i64 src,
508                                    TCGv_i64 dst)
509  {
510      if (live_cc_data(s)) {
511          tcg_gen_discard_i64(cc_vr);
512      }
513      tcg_gen_mov_i64(cc_src, src);
514      tcg_gen_mov_i64(cc_dst, dst);
515      s->cc_op = op;
516  }
517  
gen_op_update3_cc_i64(DisasContext * s,enum cc_op op,TCGv_i64 src,TCGv_i64 dst,TCGv_i64 vr)518  static void gen_op_update3_cc_i64(DisasContext *s, enum cc_op op, TCGv_i64 src,
519                                    TCGv_i64 dst, TCGv_i64 vr)
520  {
521      tcg_gen_mov_i64(cc_src, src);
522      tcg_gen_mov_i64(cc_dst, dst);
523      tcg_gen_mov_i64(cc_vr, vr);
524      s->cc_op = op;
525  }
526  
set_cc_nz_u64(DisasContext * s,TCGv_i64 val)527  static void set_cc_nz_u64(DisasContext *s, TCGv_i64 val)
528  {
529      gen_op_update1_cc_i64(s, CC_OP_NZ, val);
530  }
531  
532  /* CC value is in env->cc_op */
set_cc_static(DisasContext * s)533  static void set_cc_static(DisasContext *s)
534  {
535      if (live_cc_data(s)) {
536          tcg_gen_discard_i64(cc_src);
537          tcg_gen_discard_i64(cc_dst);
538          tcg_gen_discard_i64(cc_vr);
539      }
540      s->cc_op = CC_OP_STATIC;
541  }
542  
543  /* calculates cc into cc_op */
gen_op_calc_cc(DisasContext * s)544  static void gen_op_calc_cc(DisasContext *s)
545  {
546      TCGv_i32 local_cc_op = NULL;
547      TCGv_i64 dummy = NULL;
548  
549      switch (s->cc_op) {
550      default:
551          dummy = tcg_constant_i64(0);
552          /* FALLTHRU */
553      case CC_OP_ADD_64:
554      case CC_OP_SUB_64:
555      case CC_OP_ADD_32:
556      case CC_OP_SUB_32:
557          local_cc_op = tcg_constant_i32(s->cc_op);
558          break;
559      case CC_OP_CONST0:
560      case CC_OP_CONST1:
561      case CC_OP_CONST2:
562      case CC_OP_CONST3:
563      case CC_OP_STATIC:
564      case CC_OP_DYNAMIC:
565          break;
566      }
567  
568      switch (s->cc_op) {
569      case CC_OP_CONST0:
570      case CC_OP_CONST1:
571      case CC_OP_CONST2:
572      case CC_OP_CONST3:
573          /* s->cc_op is the cc value */
574          tcg_gen_movi_i32(cc_op, s->cc_op - CC_OP_CONST0);
575          break;
576      case CC_OP_STATIC:
577          /* env->cc_op already is the cc value */
578          break;
579      case CC_OP_NZ:
580          tcg_gen_setcondi_i64(TCG_COND_NE, cc_dst, cc_dst, 0);
581          tcg_gen_extrl_i64_i32(cc_op, cc_dst);
582          break;
583      case CC_OP_ABS_64:
584      case CC_OP_NABS_64:
585      case CC_OP_ABS_32:
586      case CC_OP_NABS_32:
587      case CC_OP_LTGT0_32:
588      case CC_OP_LTGT0_64:
589      case CC_OP_COMP_32:
590      case CC_OP_COMP_64:
591      case CC_OP_NZ_F32:
592      case CC_OP_NZ_F64:
593      case CC_OP_FLOGR:
594      case CC_OP_LCBB:
595      case CC_OP_MULS_32:
596          /* 1 argument */
597          gen_helper_calc_cc(cc_op, tcg_env, local_cc_op, dummy, cc_dst, dummy);
598          break;
599      case CC_OP_ADDU:
600      case CC_OP_ICM:
601      case CC_OP_LTGT_32:
602      case CC_OP_LTGT_64:
603      case CC_OP_LTUGTU_32:
604      case CC_OP_LTUGTU_64:
605      case CC_OP_TM_32:
606      case CC_OP_TM_64:
607      case CC_OP_SLA:
608      case CC_OP_SUBU:
609      case CC_OP_NZ_F128:
610      case CC_OP_VC:
611      case CC_OP_MULS_64:
612          /* 2 arguments */
613          gen_helper_calc_cc(cc_op, tcg_env, local_cc_op, cc_src, cc_dst, dummy);
614          break;
615      case CC_OP_ADD_64:
616      case CC_OP_SUB_64:
617      case CC_OP_ADD_32:
618      case CC_OP_SUB_32:
619          /* 3 arguments */
620          gen_helper_calc_cc(cc_op, tcg_env, local_cc_op, cc_src, cc_dst, cc_vr);
621          break;
622      case CC_OP_DYNAMIC:
623          /* unknown operation - assume 3 arguments and cc_op in env */
624          gen_helper_calc_cc(cc_op, tcg_env, cc_op, cc_src, cc_dst, cc_vr);
625          break;
626      default:
627          g_assert_not_reached();
628      }
629  
630      /* We now have cc in cc_op as constant */
631      set_cc_static(s);
632  }
633  
use_goto_tb(DisasContext * s,uint64_t dest)634  static bool use_goto_tb(DisasContext *s, uint64_t dest)
635  {
636      return translator_use_goto_tb(&s->base, dest);
637  }
638  
account_noninline_branch(DisasContext * s,int cc_op)639  static void account_noninline_branch(DisasContext *s, int cc_op)
640  {
641  #ifdef DEBUG_INLINE_BRANCHES
642      inline_branch_miss[cc_op]++;
643  #endif
644  }
645  
account_inline_branch(DisasContext * s,int cc_op)646  static void account_inline_branch(DisasContext *s, int cc_op)
647  {
648  #ifdef DEBUG_INLINE_BRANCHES
649      inline_branch_hit[cc_op]++;
650  #endif
651  }
652  
653  /* Table of mask values to comparison codes, given a comparison as input.
654     For such, CC=3 should not be possible.  */
655  static const TCGCond ltgt_cond[16] = {
656      TCG_COND_NEVER,  TCG_COND_NEVER,     /*    |    |    | x */
657      TCG_COND_GT,     TCG_COND_GT,        /*    |    | GT | x */
658      TCG_COND_LT,     TCG_COND_LT,        /*    | LT |    | x */
659      TCG_COND_NE,     TCG_COND_NE,        /*    | LT | GT | x */
660      TCG_COND_EQ,     TCG_COND_EQ,        /* EQ |    |    | x */
661      TCG_COND_GE,     TCG_COND_GE,        /* EQ |    | GT | x */
662      TCG_COND_LE,     TCG_COND_LE,        /* EQ | LT |    | x */
663      TCG_COND_ALWAYS, TCG_COND_ALWAYS,    /* EQ | LT | GT | x */
664  };
665  
666  /* Table of mask values to comparison codes, given a logic op as input.
667     For such, only CC=0 and CC=1 should be possible.  */
668  static const TCGCond nz_cond[16] = {
669      TCG_COND_NEVER, TCG_COND_NEVER,      /*    |    | x | x */
670      TCG_COND_NEVER, TCG_COND_NEVER,
671      TCG_COND_NE, TCG_COND_NE,            /*    | NE | x | x */
672      TCG_COND_NE, TCG_COND_NE,
673      TCG_COND_EQ, TCG_COND_EQ,            /* EQ |    | x | x */
674      TCG_COND_EQ, TCG_COND_EQ,
675      TCG_COND_ALWAYS, TCG_COND_ALWAYS,    /* EQ | NE | x | x */
676      TCG_COND_ALWAYS, TCG_COND_ALWAYS,
677  };
678  
679  /* Interpret MASK in terms of S->CC_OP, and fill in C with all the
680     details required to generate a TCG comparison.  */
disas_jcc(DisasContext * s,DisasCompare * c,uint32_t mask)681  static void disas_jcc(DisasContext *s, DisasCompare *c, uint32_t mask)
682  {
683      TCGCond cond;
684      enum cc_op old_cc_op = s->cc_op;
685  
686      if (mask == 15 || mask == 0) {
687          c->cond = (mask ? TCG_COND_ALWAYS : TCG_COND_NEVER);
688          c->u.s32.a = cc_op;
689          c->u.s32.b = cc_op;
690          c->is_64 = false;
691          return;
692      }
693  
694      /* Find the TCG condition for the mask + cc op.  */
695      switch (old_cc_op) {
696      case CC_OP_LTGT0_32:
697      case CC_OP_LTGT0_64:
698      case CC_OP_LTGT_32:
699      case CC_OP_LTGT_64:
700          cond = ltgt_cond[mask];
701          if (cond == TCG_COND_NEVER) {
702              goto do_dynamic;
703          }
704          account_inline_branch(s, old_cc_op);
705          break;
706  
707      case CC_OP_LTUGTU_32:
708      case CC_OP_LTUGTU_64:
709          cond = tcg_unsigned_cond(ltgt_cond[mask]);
710          if (cond == TCG_COND_NEVER) {
711              goto do_dynamic;
712          }
713          account_inline_branch(s, old_cc_op);
714          break;
715  
716      case CC_OP_NZ:
717          cond = nz_cond[mask];
718          if (cond == TCG_COND_NEVER) {
719              goto do_dynamic;
720          }
721          account_inline_branch(s, old_cc_op);
722          break;
723  
724      case CC_OP_TM_32:
725      case CC_OP_TM_64:
726          switch (mask) {
727          case 8:
728              cond = TCG_COND_TSTEQ;
729              break;
730          case 4 | 2 | 1:
731              cond = TCG_COND_TSTNE;
732              break;
733          default:
734              goto do_dynamic;
735          }
736          account_inline_branch(s, old_cc_op);
737          break;
738  
739      case CC_OP_ICM:
740          switch (mask) {
741          case 8:
742              cond = TCG_COND_TSTEQ;
743              break;
744          case 4 | 2 | 1:
745          case 4 | 2:
746              cond = TCG_COND_TSTNE;
747              break;
748          default:
749              goto do_dynamic;
750          }
751          account_inline_branch(s, old_cc_op);
752          break;
753  
754      case CC_OP_FLOGR:
755          switch (mask & 0xa) {
756          case 8: /* src == 0 -> no one bit found */
757              cond = TCG_COND_EQ;
758              break;
759          case 2: /* src != 0 -> one bit found */
760              cond = TCG_COND_NE;
761              break;
762          default:
763              goto do_dynamic;
764          }
765          account_inline_branch(s, old_cc_op);
766          break;
767  
768      case CC_OP_ADDU:
769      case CC_OP_SUBU:
770          switch (mask) {
771          case 8 | 2: /* result == 0 */
772              cond = TCG_COND_EQ;
773              break;
774          case 4 | 1: /* result != 0 */
775              cond = TCG_COND_NE;
776              break;
777          case 8 | 4: /* !carry (borrow) */
778              cond = old_cc_op == CC_OP_ADDU ? TCG_COND_EQ : TCG_COND_NE;
779              break;
780          case 2 | 1: /* carry (!borrow) */
781              cond = old_cc_op == CC_OP_ADDU ? TCG_COND_NE : TCG_COND_EQ;
782              break;
783          default:
784              goto do_dynamic;
785          }
786          account_inline_branch(s, old_cc_op);
787          break;
788  
789      default:
790      do_dynamic:
791          /* Calculate cc value.  */
792          gen_op_calc_cc(s);
793          /* FALLTHRU */
794  
795      case CC_OP_STATIC:
796          /* Jump based on CC.  We'll load up the real cond below;
797             the assignment here merely avoids a compiler warning.  */
798          account_noninline_branch(s, old_cc_op);
799          old_cc_op = CC_OP_STATIC;
800          cond = TCG_COND_NEVER;
801          break;
802      }
803  
804      /* Load up the arguments of the comparison.  */
805      c->is_64 = true;
806      switch (old_cc_op) {
807      case CC_OP_LTGT0_32:
808          c->is_64 = false;
809          c->u.s32.a = tcg_temp_new_i32();
810          tcg_gen_extrl_i64_i32(c->u.s32.a, cc_dst);
811          c->u.s32.b = tcg_constant_i32(0);
812          break;
813      case CC_OP_LTGT_32:
814      case CC_OP_LTUGTU_32:
815          c->is_64 = false;
816          c->u.s32.a = tcg_temp_new_i32();
817          tcg_gen_extrl_i64_i32(c->u.s32.a, cc_src);
818          c->u.s32.b = tcg_temp_new_i32();
819          tcg_gen_extrl_i64_i32(c->u.s32.b, cc_dst);
820          break;
821  
822      case CC_OP_LTGT0_64:
823      case CC_OP_NZ:
824      case CC_OP_FLOGR:
825          c->u.s64.a = cc_dst;
826          c->u.s64.b = tcg_constant_i64(0);
827          break;
828  
829      case CC_OP_LTGT_64:
830      case CC_OP_LTUGTU_64:
831      case CC_OP_TM_32:
832      case CC_OP_TM_64:
833      case CC_OP_ICM:
834          c->u.s64.a = cc_src;
835          c->u.s64.b = cc_dst;
836          break;
837  
838      case CC_OP_ADDU:
839      case CC_OP_SUBU:
840          c->is_64 = true;
841          c->u.s64.b = tcg_constant_i64(0);
842          switch (mask) {
843          case 8 | 2:
844          case 4 | 1: /* result */
845              c->u.s64.a = cc_dst;
846              break;
847          case 8 | 4:
848          case 2 | 1: /* carry */
849              c->u.s64.a = cc_src;
850              break;
851          default:
852              g_assert_not_reached();
853          }
854          break;
855  
856      case CC_OP_STATIC:
857          c->is_64 = false;
858          c->u.s32.a = cc_op;
859  
860          /* Fold half of the cases using bit 3 to invert. */
861          switch (mask & 8 ? mask ^ 0xf : mask) {
862          case 0x1: /* cc == 3 */
863              cond = TCG_COND_EQ;
864              c->u.s32.b = tcg_constant_i32(3);
865              break;
866          case 0x2: /* cc == 2 */
867              cond = TCG_COND_EQ;
868              c->u.s32.b = tcg_constant_i32(2);
869              break;
870          case 0x4: /* cc == 1 */
871              cond = TCG_COND_EQ;
872              c->u.s32.b = tcg_constant_i32(1);
873              break;
874          case 0x2 | 0x1: /* cc == 2 || cc == 3 => cc > 1 */
875              cond = TCG_COND_GTU;
876              c->u.s32.b = tcg_constant_i32(1);
877              break;
878          case 0x4 | 0x1: /* cc == 1 || cc == 3 => (cc & 1) != 0 */
879              cond = TCG_COND_TSTNE;
880              c->u.s32.b = tcg_constant_i32(1);
881              break;
882          case 0x4 | 0x2: /* cc == 1 || cc == 2 => (cc - 1) <= 1 */
883              cond = TCG_COND_LEU;
884              c->u.s32.a = tcg_temp_new_i32();
885              c->u.s32.b = tcg_constant_i32(1);
886              tcg_gen_addi_i32(c->u.s32.a, cc_op, -1);
887              break;
888          case 0x4 | 0x2 | 0x1: /* cc != 0 */
889              cond = TCG_COND_NE;
890              c->u.s32.b = tcg_constant_i32(0);
891              break;
892          default:
893              /* case 0: never, handled above. */
894              g_assert_not_reached();
895          }
896          if (mask & 8) {
897              cond = tcg_invert_cond(cond);
898          }
899          break;
900  
901      default:
902          abort();
903      }
904      c->cond = cond;
905  }
906  
907  /* ====================================================================== */
908  /* Define the insn format enumeration.  */
909  #define F0(N)                         FMT_##N,
910  #define F1(N, X1)                     F0(N)
911  #define F2(N, X1, X2)                 F0(N)
912  #define F3(N, X1, X2, X3)             F0(N)
913  #define F4(N, X1, X2, X3, X4)         F0(N)
914  #define F5(N, X1, X2, X3, X4, X5)     F0(N)
915  #define F6(N, X1, X2, X3, X4, X5, X6) F0(N)
916  
917  typedef enum {
918  #include "insn-format.h.inc"
919  } DisasFormat;
920  
921  #undef F0
922  #undef F1
923  #undef F2
924  #undef F3
925  #undef F4
926  #undef F5
927  #undef F6
928  
929  /* This is the way fields are to be accessed out of DisasFields.  */
930  #define have_field(S, F)  have_field1((S), FLD_O_##F)
931  #define get_field(S, F)   get_field1((S), FLD_O_##F, FLD_C_##F)
932  
have_field1(const DisasContext * s,enum DisasFieldIndexO c)933  static bool have_field1(const DisasContext *s, enum DisasFieldIndexO c)
934  {
935      return (s->fields.presentO >> c) & 1;
936  }
937  
get_field1(const DisasContext * s,enum DisasFieldIndexO o,enum DisasFieldIndexC c)938  static int get_field1(const DisasContext *s, enum DisasFieldIndexO o,
939                        enum DisasFieldIndexC c)
940  {
941      assert(have_field1(s, o));
942      return s->fields.c[c];
943  }
944  
945  /* Describe the layout of each field in each format.  */
946  typedef struct DisasField {
947      unsigned int beg:8;
948      unsigned int size:8;
949      unsigned int type:2;
950      unsigned int indexC:6;
951      enum DisasFieldIndexO indexO:8;
952  } DisasField;
953  
954  typedef struct DisasFormatInfo {
955      DisasField op[NUM_C_FIELD];
956  } DisasFormatInfo;
957  
958  #define R(N, B)       {  B,  4, 0, FLD_C_r##N, FLD_O_r##N }
959  #define M(N, B)       {  B,  4, 0, FLD_C_m##N, FLD_O_m##N }
960  #define V(N, B)       {  B,  4, 3, FLD_C_v##N, FLD_O_v##N }
961  #define BD(N, BB, BD) { BB,  4, 0, FLD_C_b##N, FLD_O_b##N }, \
962                        { BD, 12, 0, FLD_C_d##N, FLD_O_d##N }
963  #define BXD(N)        { 16,  4, 0, FLD_C_b##N, FLD_O_b##N }, \
964                        { 12,  4, 0, FLD_C_x##N, FLD_O_x##N }, \
965                        { 20, 12, 0, FLD_C_d##N, FLD_O_d##N }
966  #define BDL(N)        { 16,  4, 0, FLD_C_b##N, FLD_O_b##N }, \
967                        { 20, 20, 2, FLD_C_d##N, FLD_O_d##N }
968  #define BXDL(N)       { 16,  4, 0, FLD_C_b##N, FLD_O_b##N }, \
969                        { 12,  4, 0, FLD_C_x##N, FLD_O_x##N }, \
970                        { 20, 20, 2, FLD_C_d##N, FLD_O_d##N }
971  #define I(N, B, S)    {  B,  S, 1, FLD_C_i##N, FLD_O_i##N }
972  #define L(N, B, S)    {  B,  S, 0, FLD_C_l##N, FLD_O_l##N }
973  
974  #define F0(N)                     { { } },
975  #define F1(N, X1)                 { { X1 } },
976  #define F2(N, X1, X2)             { { X1, X2 } },
977  #define F3(N, X1, X2, X3)         { { X1, X2, X3 } },
978  #define F4(N, X1, X2, X3, X4)     { { X1, X2, X3, X4 } },
979  #define F5(N, X1, X2, X3, X4, X5) { { X1, X2, X3, X4, X5 } },
980  #define F6(N, X1, X2, X3, X4, X5, X6)       { { X1, X2, X3, X4, X5, X6 } },
981  
982  static const DisasFormatInfo format_info[] = {
983  #include "insn-format.h.inc"
984  };
985  
986  #undef F0
987  #undef F1
988  #undef F2
989  #undef F3
990  #undef F4
991  #undef F5
992  #undef F6
993  #undef R
994  #undef M
995  #undef V
996  #undef BD
997  #undef BXD
998  #undef BDL
999  #undef BXDL
1000  #undef I
1001  #undef L
1002  
1003  /* Generally, we'll extract operands into this structures, operate upon
1004     them, and store them back.  See the "in1", "in2", "prep", "wout" sets
1005     of routines below for more details.  */
1006  typedef struct {
1007      TCGv_i64 out, out2, in1, in2;
1008      TCGv_i64 addr1;
1009      TCGv_i128 out_128, in1_128, in2_128;
1010  } DisasOps;
1011  
1012  /* Instructions can place constraints on their operands, raising specification
1013     exceptions if they are violated.  To make this easy to automate, each "in1",
1014     "in2", "prep", "wout" helper will have a SPEC_<name> define that equals one
1015     of the following, or 0.  To make this easy to document, we'll put the
1016     SPEC_<name> defines next to <name>.  */
1017  
1018  #define SPEC_r1_even    1
1019  #define SPEC_r2_even    2
1020  #define SPEC_r3_even    4
1021  #define SPEC_r1_f128    8
1022  #define SPEC_r2_f128    16
1023  
1024  /* Return values from translate_one, indicating the state of the TB.  */
1025  
1026  /* We are not using a goto_tb (for whatever reason), but have updated
1027     the PC (for whatever reason), so there's no need to do it again on
1028     exiting the TB.  */
1029  #define DISAS_PC_UPDATED        DISAS_TARGET_0
1030  
1031  /* We have updated the PC and CC values.  */
1032  #define DISAS_PC_CC_UPDATED     DISAS_TARGET_2
1033  
1034  
1035  /* Instruction flags */
1036  #define IF_AFP1     0x0001      /* r1 is a fp reg for HFP/FPS instructions */
1037  #define IF_AFP2     0x0002      /* r2 is a fp reg for HFP/FPS instructions */
1038  #define IF_AFP3     0x0004      /* r3 is a fp reg for HFP/FPS instructions */
1039  #define IF_BFP      0x0008      /* binary floating point instruction */
1040  #define IF_DFP      0x0010      /* decimal floating point instruction */
1041  #define IF_PRIV     0x0020      /* privileged instruction */
1042  #define IF_VEC      0x0040      /* vector instruction */
1043  #define IF_IO       0x0080      /* input/output instruction */
1044  
1045  struct DisasInsn {
1046      unsigned opc:16;
1047      unsigned flags:16;
1048      DisasFormat fmt:8;
1049      unsigned fac:8;
1050      unsigned spec:8;
1051  
1052      const char *name;
1053  
1054      /* Pre-process arguments before HELP_OP.  */
1055      void (*help_in1)(DisasContext *, DisasOps *);
1056      void (*help_in2)(DisasContext *, DisasOps *);
1057      void (*help_prep)(DisasContext *, DisasOps *);
1058  
1059      /*
1060       * Post-process output after HELP_OP.
1061       * Note that these are not called if HELP_OP returns DISAS_NORETURN.
1062       */
1063      void (*help_wout)(DisasContext *, DisasOps *);
1064      void (*help_cout)(DisasContext *, DisasOps *);
1065  
1066      /* Implement the operation itself.  */
1067      DisasJumpType (*help_op)(DisasContext *, DisasOps *);
1068  
1069      uint64_t data;
1070  };
1071  
1072  /* ====================================================================== */
1073  /* Miscellaneous helpers, used by several operations.  */
1074  
help_goto_direct(DisasContext * s,uint64_t dest)1075  static DisasJumpType help_goto_direct(DisasContext *s, uint64_t dest)
1076  {
1077      update_cc_op(s);
1078      per_breaking_event(s);
1079      per_branch(s, tcg_constant_i64(dest));
1080  
1081      if (dest == s->pc_tmp) {
1082          return DISAS_NEXT;
1083      }
1084      if (use_goto_tb(s, dest)) {
1085          tcg_gen_goto_tb(0);
1086          tcg_gen_movi_i64(psw_addr, dest);
1087          tcg_gen_exit_tb(s->base.tb, 0);
1088          return DISAS_NORETURN;
1089      } else {
1090          tcg_gen_movi_i64(psw_addr, dest);
1091          return DISAS_PC_CC_UPDATED;
1092      }
1093  }
1094  
help_goto_indirect(DisasContext * s,TCGv_i64 dest)1095  static DisasJumpType help_goto_indirect(DisasContext *s, TCGv_i64 dest)
1096  {
1097      update_cc_op(s);
1098      per_breaking_event(s);
1099      tcg_gen_mov_i64(psw_addr, dest);
1100      per_branch(s, psw_addr);
1101      return DISAS_PC_CC_UPDATED;
1102  }
1103  
help_branch(DisasContext * s,DisasCompare * c,bool is_imm,int imm,TCGv_i64 cdest)1104  static DisasJumpType help_branch(DisasContext *s, DisasCompare *c,
1105                                   bool is_imm, int imm, TCGv_i64 cdest)
1106  {
1107      uint64_t dest = s->base.pc_next + (int64_t)imm * 2;
1108      TCGLabel *lab;
1109  
1110      /* Take care of the special cases first.  */
1111      if (c->cond == TCG_COND_NEVER) {
1112          return DISAS_NEXT;
1113      }
1114      if (is_imm) {
1115          /*
1116           * Do not optimize a conditional branch if PER enabled, because we
1117           * still need a conditional call to helper_per_branch.
1118           */
1119          if (c->cond == TCG_COND_ALWAYS
1120              || (dest == s->pc_tmp &&
1121                  !(s->base.tb->flags & FLAG_MASK_PER_BRANCH))) {
1122              return help_goto_direct(s, dest);
1123          }
1124      } else {
1125          if (!cdest) {
1126              /* E.g. bcr %r0 -> no branch.  */
1127              return DISAS_NEXT;
1128          }
1129          if (c->cond == TCG_COND_ALWAYS) {
1130              return help_goto_indirect(s, cdest);
1131          }
1132      }
1133  
1134      update_cc_op(s);
1135  
1136      /*
1137       * Ensure the taken branch is fall-through of the tcg branch.
1138       * This keeps @cdest usage within the extended basic block,
1139       * which avoids an otherwise unnecessary spill to the stack.
1140       */
1141      lab = gen_new_label();
1142      if (c->is_64) {
1143          tcg_gen_brcond_i64(tcg_invert_cond(c->cond),
1144                             c->u.s64.a, c->u.s64.b, lab);
1145      } else {
1146          tcg_gen_brcond_i32(tcg_invert_cond(c->cond),
1147                             c->u.s32.a, c->u.s32.b, lab);
1148      }
1149  
1150      /* Branch taken.  */
1151      per_breaking_event(s);
1152      if (is_imm) {
1153          tcg_gen_movi_i64(psw_addr, dest);
1154      } else {
1155          tcg_gen_mov_i64(psw_addr, cdest);
1156      }
1157      per_branch(s, psw_addr);
1158  
1159      if (is_imm && use_goto_tb(s, dest)) {
1160          tcg_gen_goto_tb(0);
1161          tcg_gen_exit_tb(s->base.tb, 0);
1162      } else {
1163          tcg_gen_lookup_and_goto_ptr();
1164      }
1165  
1166      gen_set_label(lab);
1167  
1168      /* Branch not taken.  */
1169      tcg_gen_movi_i64(psw_addr, s->pc_tmp);
1170      if (use_goto_tb(s, s->pc_tmp)) {
1171          tcg_gen_goto_tb(1);
1172          tcg_gen_exit_tb(s->base.tb, 1);
1173          return DISAS_NORETURN;
1174      }
1175      return DISAS_PC_CC_UPDATED;
1176  }
1177  
1178  /* ====================================================================== */
1179  /* The operations.  These perform the bulk of the work for any insn,
1180     usually after the operands have been loaded and output initialized.  */
1181  
op_abs(DisasContext * s,DisasOps * o)1182  static DisasJumpType op_abs(DisasContext *s, DisasOps *o)
1183  {
1184      tcg_gen_abs_i64(o->out, o->in2);
1185      return DISAS_NEXT;
1186  }
1187  
op_absf32(DisasContext * s,DisasOps * o)1188  static DisasJumpType op_absf32(DisasContext *s, DisasOps *o)
1189  {
1190      tcg_gen_andi_i64(o->out, o->in2, 0x7fffffffull);
1191      return DISAS_NEXT;
1192  }
1193  
op_absf64(DisasContext * s,DisasOps * o)1194  static DisasJumpType op_absf64(DisasContext *s, DisasOps *o)
1195  {
1196      tcg_gen_andi_i64(o->out, o->in2, 0x7fffffffffffffffull);
1197      return DISAS_NEXT;
1198  }
1199  
op_absf128(DisasContext * s,DisasOps * o)1200  static DisasJumpType op_absf128(DisasContext *s, DisasOps *o)
1201  {
1202      tcg_gen_andi_i64(o->out, o->in1, 0x7fffffffffffffffull);
1203      tcg_gen_mov_i64(o->out2, o->in2);
1204      return DISAS_NEXT;
1205  }
1206  
op_add(DisasContext * s,DisasOps * o)1207  static DisasJumpType op_add(DisasContext *s, DisasOps *o)
1208  {
1209      tcg_gen_add_i64(o->out, o->in1, o->in2);
1210      return DISAS_NEXT;
1211  }
1212  
op_addu64(DisasContext * s,DisasOps * o)1213  static DisasJumpType op_addu64(DisasContext *s, DisasOps *o)
1214  {
1215      tcg_gen_movi_i64(cc_src, 0);
1216      tcg_gen_add2_i64(o->out, cc_src, o->in1, cc_src, o->in2, cc_src);
1217      return DISAS_NEXT;
1218  }
1219  
1220  /* Compute carry into cc_src. */
compute_carry(DisasContext * s)1221  static void compute_carry(DisasContext *s)
1222  {
1223      switch (s->cc_op) {
1224      case CC_OP_ADDU:
1225          /* The carry value is already in cc_src (1,0). */
1226          break;
1227      case CC_OP_SUBU:
1228          tcg_gen_addi_i64(cc_src, cc_src, 1);
1229          break;
1230      default:
1231          gen_op_calc_cc(s);
1232          /* fall through */
1233      case CC_OP_STATIC:
1234          /* The carry flag is the msb of CC; compute into cc_src. */
1235          tcg_gen_extu_i32_i64(cc_src, cc_op);
1236          tcg_gen_shri_i64(cc_src, cc_src, 1);
1237          break;
1238      }
1239  }
1240  
op_addc32(DisasContext * s,DisasOps * o)1241  static DisasJumpType op_addc32(DisasContext *s, DisasOps *o)
1242  {
1243      compute_carry(s);
1244      tcg_gen_add_i64(o->out, o->in1, o->in2);
1245      tcg_gen_add_i64(o->out, o->out, cc_src);
1246      return DISAS_NEXT;
1247  }
1248  
op_addc64(DisasContext * s,DisasOps * o)1249  static DisasJumpType op_addc64(DisasContext *s, DisasOps *o)
1250  {
1251      compute_carry(s);
1252  
1253      TCGv_i64 zero = tcg_constant_i64(0);
1254      tcg_gen_add2_i64(o->out, cc_src, o->in1, zero, cc_src, zero);
1255      tcg_gen_add2_i64(o->out, cc_src, o->out, cc_src, o->in2, zero);
1256  
1257      return DISAS_NEXT;
1258  }
1259  
op_asi(DisasContext * s,DisasOps * o)1260  static DisasJumpType op_asi(DisasContext *s, DisasOps *o)
1261  {
1262      bool non_atomic = !s390_has_feat(S390_FEAT_STFLE_45);
1263  
1264      o->in1 = tcg_temp_new_i64();
1265      if (non_atomic) {
1266          tcg_gen_qemu_ld_tl(o->in1, o->addr1, get_mem_index(s), s->insn->data);
1267      } else {
1268          /* Perform the atomic addition in memory. */
1269          tcg_gen_atomic_fetch_add_i64(o->in1, o->addr1, o->in2, get_mem_index(s),
1270                                       s->insn->data);
1271      }
1272  
1273      /* Recompute also for atomic case: needed for setting CC. */
1274      tcg_gen_add_i64(o->out, o->in1, o->in2);
1275  
1276      if (non_atomic) {
1277          tcg_gen_qemu_st_tl(o->out, o->addr1, get_mem_index(s), s->insn->data);
1278      }
1279      return DISAS_NEXT;
1280  }
1281  
op_asiu64(DisasContext * s,DisasOps * o)1282  static DisasJumpType op_asiu64(DisasContext *s, DisasOps *o)
1283  {
1284      bool non_atomic = !s390_has_feat(S390_FEAT_STFLE_45);
1285  
1286      o->in1 = tcg_temp_new_i64();
1287      if (non_atomic) {
1288          tcg_gen_qemu_ld_tl(o->in1, o->addr1, get_mem_index(s), s->insn->data);
1289      } else {
1290          /* Perform the atomic addition in memory. */
1291          tcg_gen_atomic_fetch_add_i64(o->in1, o->addr1, o->in2, get_mem_index(s),
1292                                       s->insn->data);
1293      }
1294  
1295      /* Recompute also for atomic case: needed for setting CC. */
1296      tcg_gen_movi_i64(cc_src, 0);
1297      tcg_gen_add2_i64(o->out, cc_src, o->in1, cc_src, o->in2, cc_src);
1298  
1299      if (non_atomic) {
1300          tcg_gen_qemu_st_tl(o->out, o->addr1, get_mem_index(s), s->insn->data);
1301      }
1302      return DISAS_NEXT;
1303  }
1304  
op_aeb(DisasContext * s,DisasOps * o)1305  static DisasJumpType op_aeb(DisasContext *s, DisasOps *o)
1306  {
1307      gen_helper_aeb(o->out, tcg_env, o->in1, o->in2);
1308      return DISAS_NEXT;
1309  }
1310  
op_adb(DisasContext * s,DisasOps * o)1311  static DisasJumpType op_adb(DisasContext *s, DisasOps *o)
1312  {
1313      gen_helper_adb(o->out, tcg_env, o->in1, o->in2);
1314      return DISAS_NEXT;
1315  }
1316  
op_axb(DisasContext * s,DisasOps * o)1317  static DisasJumpType op_axb(DisasContext *s, DisasOps *o)
1318  {
1319      gen_helper_axb(o->out_128, tcg_env, o->in1_128, o->in2_128);
1320      return DISAS_NEXT;
1321  }
1322  
op_and(DisasContext * s,DisasOps * o)1323  static DisasJumpType op_and(DisasContext *s, DisasOps *o)
1324  {
1325      tcg_gen_and_i64(o->out, o->in1, o->in2);
1326      return DISAS_NEXT;
1327  }
1328  
op_andi(DisasContext * s,DisasOps * o)1329  static DisasJumpType op_andi(DisasContext *s, DisasOps *o)
1330  {
1331      int shift = s->insn->data & 0xff;
1332      int size = s->insn->data >> 8;
1333      uint64_t mask = ((1ull << size) - 1) << shift;
1334      TCGv_i64 t = tcg_temp_new_i64();
1335  
1336      tcg_gen_shli_i64(t, o->in2, shift);
1337      tcg_gen_ori_i64(t, t, ~mask);
1338      tcg_gen_and_i64(o->out, o->in1, t);
1339  
1340      /* Produce the CC from only the bits manipulated.  */
1341      tcg_gen_andi_i64(cc_dst, o->out, mask);
1342      set_cc_nz_u64(s, cc_dst);
1343      return DISAS_NEXT;
1344  }
1345  
op_andc(DisasContext * s,DisasOps * o)1346  static DisasJumpType op_andc(DisasContext *s, DisasOps *o)
1347  {
1348      tcg_gen_andc_i64(o->out, o->in1, o->in2);
1349      return DISAS_NEXT;
1350  }
1351  
op_orc(DisasContext * s,DisasOps * o)1352  static DisasJumpType op_orc(DisasContext *s, DisasOps *o)
1353  {
1354      tcg_gen_orc_i64(o->out, o->in1, o->in2);
1355      return DISAS_NEXT;
1356  }
1357  
op_nand(DisasContext * s,DisasOps * o)1358  static DisasJumpType op_nand(DisasContext *s, DisasOps *o)
1359  {
1360      tcg_gen_nand_i64(o->out, o->in1, o->in2);
1361      return DISAS_NEXT;
1362  }
1363  
op_nor(DisasContext * s,DisasOps * o)1364  static DisasJumpType op_nor(DisasContext *s, DisasOps *o)
1365  {
1366      tcg_gen_nor_i64(o->out, o->in1, o->in2);
1367      return DISAS_NEXT;
1368  }
1369  
op_nxor(DisasContext * s,DisasOps * o)1370  static DisasJumpType op_nxor(DisasContext *s, DisasOps *o)
1371  {
1372      tcg_gen_eqv_i64(o->out, o->in1, o->in2);
1373      return DISAS_NEXT;
1374  }
1375  
op_ni(DisasContext * s,DisasOps * o)1376  static DisasJumpType op_ni(DisasContext *s, DisasOps *o)
1377  {
1378      o->in1 = tcg_temp_new_i64();
1379  
1380      if (!s390_has_feat(S390_FEAT_INTERLOCKED_ACCESS_2)) {
1381          tcg_gen_qemu_ld_tl(o->in1, o->addr1, get_mem_index(s), s->insn->data);
1382      } else {
1383          /* Perform the atomic operation in memory. */
1384          tcg_gen_atomic_fetch_and_i64(o->in1, o->addr1, o->in2, get_mem_index(s),
1385                                       s->insn->data);
1386      }
1387  
1388      /* Recompute also for atomic case: needed for setting CC. */
1389      tcg_gen_and_i64(o->out, o->in1, o->in2);
1390  
1391      if (!s390_has_feat(S390_FEAT_INTERLOCKED_ACCESS_2)) {
1392          tcg_gen_qemu_st_tl(o->out, o->addr1, get_mem_index(s), s->insn->data);
1393      }
1394      return DISAS_NEXT;
1395  }
1396  
op_bas(DisasContext * s,DisasOps * o)1397  static DisasJumpType op_bas(DisasContext *s, DisasOps *o)
1398  {
1399      pc_to_link_info(o->out, s, s->pc_tmp);
1400      if (o->in2) {
1401          return help_goto_indirect(s, o->in2);
1402      } else {
1403          return DISAS_NEXT;
1404      }
1405  }
1406  
save_link_info(DisasContext * s,DisasOps * o)1407  static void save_link_info(DisasContext *s, DisasOps *o)
1408  {
1409      TCGv_i64 t;
1410  
1411      if (s->base.tb->flags & (FLAG_MASK_32 | FLAG_MASK_64)) {
1412          pc_to_link_info(o->out, s, s->pc_tmp);
1413          return;
1414      }
1415      gen_op_calc_cc(s);
1416      tcg_gen_andi_i64(o->out, o->out, 0xffffffff00000000ull);
1417      tcg_gen_ori_i64(o->out, o->out, ((s->ilen / 2) << 30) | s->pc_tmp);
1418      t = tcg_temp_new_i64();
1419      tcg_gen_shri_i64(t, psw_mask, 16);
1420      tcg_gen_andi_i64(t, t, 0x0f000000);
1421      tcg_gen_or_i64(o->out, o->out, t);
1422      tcg_gen_extu_i32_i64(t, cc_op);
1423      tcg_gen_shli_i64(t, t, 28);
1424      tcg_gen_or_i64(o->out, o->out, t);
1425  }
1426  
op_bal(DisasContext * s,DisasOps * o)1427  static DisasJumpType op_bal(DisasContext *s, DisasOps *o)
1428  {
1429      save_link_info(s, o);
1430      if (o->in2) {
1431          return help_goto_indirect(s, o->in2);
1432      } else {
1433          return DISAS_NEXT;
1434      }
1435  }
1436  
1437  /*
1438   * Disassemble the target of a branch. The results are returned in a form
1439   * suitable for passing into help_branch():
1440   *
1441   * - bool IS_IMM reflects whether the target is fixed or computed. Non-EXECUTEd
1442   *   branches, whose DisasContext *S contains the relative immediate field RI,
1443   *   are considered fixed. All the other branches are considered computed.
1444   * - int IMM is the value of RI.
1445   * - TCGv_i64 CDEST is the address of the computed target.
1446   */
1447  #define disas_jdest(s, ri, is_imm, imm, cdest) do {                            \
1448      if (have_field(s, ri)) {                                                   \
1449          if (unlikely(s->ex_value)) {                                           \
1450              cdest = tcg_temp_new_i64();                                        \
1451              tcg_gen_ld_i64(cdest, tcg_env, offsetof(CPUS390XState, ex_target));\
1452              tcg_gen_addi_i64(cdest, cdest, (int64_t)get_field(s, ri) * 2);     \
1453              is_imm = false;                                                    \
1454          } else {                                                               \
1455              is_imm = true;                                                     \
1456          }                                                                      \
1457      } else {                                                                   \
1458          is_imm = false;                                                        \
1459      }                                                                          \
1460      imm = is_imm ? get_field(s, ri) : 0;                                       \
1461  } while (false)
1462  
op_basi(DisasContext * s,DisasOps * o)1463  static DisasJumpType op_basi(DisasContext *s, DisasOps *o)
1464  {
1465      DisasCompare c;
1466      bool is_imm;
1467      int imm;
1468  
1469      pc_to_link_info(o->out, s, s->pc_tmp);
1470  
1471      disas_jdest(s, i2, is_imm, imm, o->in2);
1472      disas_jcc(s, &c, 0xf);
1473      return help_branch(s, &c, is_imm, imm, o->in2);
1474  }
1475  
op_bc(DisasContext * s,DisasOps * o)1476  static DisasJumpType op_bc(DisasContext *s, DisasOps *o)
1477  {
1478      int m1 = get_field(s, m1);
1479      DisasCompare c;
1480      bool is_imm;
1481      int imm;
1482  
1483      /* BCR with R2 = 0 causes no branching */
1484      if (have_field(s, r2) && get_field(s, r2) == 0) {
1485          if (m1 == 14) {
1486              /* Perform serialization */
1487              /* FIXME: check for fast-BCR-serialization facility */
1488              tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
1489          }
1490          if (m1 == 15) {
1491              /* Perform serialization */
1492              /* FIXME: perform checkpoint-synchronisation */
1493              tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
1494          }
1495          return DISAS_NEXT;
1496      }
1497  
1498      disas_jdest(s, i2, is_imm, imm, o->in2);
1499      disas_jcc(s, &c, m1);
1500      return help_branch(s, &c, is_imm, imm, o->in2);
1501  }
1502  
op_bct32(DisasContext * s,DisasOps * o)1503  static DisasJumpType op_bct32(DisasContext *s, DisasOps *o)
1504  {
1505      int r1 = get_field(s, r1);
1506      DisasCompare c;
1507      bool is_imm;
1508      TCGv_i64 t;
1509      int imm;
1510  
1511      c.cond = TCG_COND_NE;
1512      c.is_64 = false;
1513  
1514      t = tcg_temp_new_i64();
1515      tcg_gen_subi_i64(t, regs[r1], 1);
1516      store_reg32_i64(r1, t);
1517      c.u.s32.a = tcg_temp_new_i32();
1518      c.u.s32.b = tcg_constant_i32(0);
1519      tcg_gen_extrl_i64_i32(c.u.s32.a, t);
1520  
1521      disas_jdest(s, i2, is_imm, imm, o->in2);
1522      return help_branch(s, &c, is_imm, imm, o->in2);
1523  }
1524  
op_bcth(DisasContext * s,DisasOps * o)1525  static DisasJumpType op_bcth(DisasContext *s, DisasOps *o)
1526  {
1527      int r1 = get_field(s, r1);
1528      int imm = get_field(s, i2);
1529      DisasCompare c;
1530      TCGv_i64 t;
1531  
1532      c.cond = TCG_COND_NE;
1533      c.is_64 = false;
1534  
1535      t = tcg_temp_new_i64();
1536      tcg_gen_shri_i64(t, regs[r1], 32);
1537      tcg_gen_subi_i64(t, t, 1);
1538      store_reg32h_i64(r1, t);
1539      c.u.s32.a = tcg_temp_new_i32();
1540      c.u.s32.b = tcg_constant_i32(0);
1541      tcg_gen_extrl_i64_i32(c.u.s32.a, t);
1542  
1543      return help_branch(s, &c, 1, imm, o->in2);
1544  }
1545  
op_bct64(DisasContext * s,DisasOps * o)1546  static DisasJumpType op_bct64(DisasContext *s, DisasOps *o)
1547  {
1548      int r1 = get_field(s, r1);
1549      DisasCompare c;
1550      bool is_imm;
1551      int imm;
1552  
1553      c.cond = TCG_COND_NE;
1554      c.is_64 = true;
1555  
1556      tcg_gen_subi_i64(regs[r1], regs[r1], 1);
1557      c.u.s64.a = regs[r1];
1558      c.u.s64.b = tcg_constant_i64(0);
1559  
1560      disas_jdest(s, i2, is_imm, imm, o->in2);
1561      return help_branch(s, &c, is_imm, imm, o->in2);
1562  }
1563  
op_bx32(DisasContext * s,DisasOps * o)1564  static DisasJumpType op_bx32(DisasContext *s, DisasOps *o)
1565  {
1566      int r1 = get_field(s, r1);
1567      int r3 = get_field(s, r3);
1568      DisasCompare c;
1569      bool is_imm;
1570      TCGv_i64 t;
1571      int imm;
1572  
1573      c.cond = (s->insn->data ? TCG_COND_LE : TCG_COND_GT);
1574      c.is_64 = false;
1575  
1576      t = tcg_temp_new_i64();
1577      tcg_gen_add_i64(t, regs[r1], regs[r3]);
1578      c.u.s32.a = tcg_temp_new_i32();
1579      c.u.s32.b = tcg_temp_new_i32();
1580      tcg_gen_extrl_i64_i32(c.u.s32.a, t);
1581      tcg_gen_extrl_i64_i32(c.u.s32.b, regs[r3 | 1]);
1582      store_reg32_i64(r1, t);
1583  
1584      disas_jdest(s, i2, is_imm, imm, o->in2);
1585      return help_branch(s, &c, is_imm, imm, o->in2);
1586  }
1587  
op_bx64(DisasContext * s,DisasOps * o)1588  static DisasJumpType op_bx64(DisasContext *s, DisasOps *o)
1589  {
1590      int r1 = get_field(s, r1);
1591      int r3 = get_field(s, r3);
1592      DisasCompare c;
1593      bool is_imm;
1594      int imm;
1595  
1596      c.cond = (s->insn->data ? TCG_COND_LE : TCG_COND_GT);
1597      c.is_64 = true;
1598  
1599      if (r1 == (r3 | 1)) {
1600          c.u.s64.b = load_reg(r3 | 1);
1601      } else {
1602          c.u.s64.b = regs[r3 | 1];
1603      }
1604  
1605      tcg_gen_add_i64(regs[r1], regs[r1], regs[r3]);
1606      c.u.s64.a = regs[r1];
1607  
1608      disas_jdest(s, i2, is_imm, imm, o->in2);
1609      return help_branch(s, &c, is_imm, imm, o->in2);
1610  }
1611  
op_cj(DisasContext * s,DisasOps * o)1612  static DisasJumpType op_cj(DisasContext *s, DisasOps *o)
1613  {
1614      int imm, m3 = get_field(s, m3);
1615      bool is_imm;
1616      DisasCompare c;
1617  
1618      c.cond = ltgt_cond[m3];
1619      if (s->insn->data) {
1620          c.cond = tcg_unsigned_cond(c.cond);
1621      }
1622      c.is_64 = true;
1623      c.u.s64.a = o->in1;
1624      c.u.s64.b = o->in2;
1625  
1626      o->out = NULL;
1627      disas_jdest(s, i4, is_imm, imm, o->out);
1628      if (!is_imm && !o->out) {
1629          imm = 0;
1630          o->out = get_address(s, 0, get_field(s, b4),
1631                               get_field(s, d4));
1632      }
1633  
1634      return help_branch(s, &c, is_imm, imm, o->out);
1635  }
1636  
op_ceb(DisasContext * s,DisasOps * o)1637  static DisasJumpType op_ceb(DisasContext *s, DisasOps *o)
1638  {
1639      gen_helper_ceb(cc_op, tcg_env, o->in1, o->in2);
1640      set_cc_static(s);
1641      return DISAS_NEXT;
1642  }
1643  
op_cdb(DisasContext * s,DisasOps * o)1644  static DisasJumpType op_cdb(DisasContext *s, DisasOps *o)
1645  {
1646      gen_helper_cdb(cc_op, tcg_env, o->in1, o->in2);
1647      set_cc_static(s);
1648      return DISAS_NEXT;
1649  }
1650  
op_cxb(DisasContext * s,DisasOps * o)1651  static DisasJumpType op_cxb(DisasContext *s, DisasOps *o)
1652  {
1653      gen_helper_cxb(cc_op, tcg_env, o->in1_128, o->in2_128);
1654      set_cc_static(s);
1655      return DISAS_NEXT;
1656  }
1657  
fpinst_extract_m34(DisasContext * s,bool m3_with_fpe,bool m4_with_fpe)1658  static TCGv_i32 fpinst_extract_m34(DisasContext *s, bool m3_with_fpe,
1659                                     bool m4_with_fpe)
1660  {
1661      const bool fpe = s390_has_feat(S390_FEAT_FLOATING_POINT_EXT);
1662      uint8_t m3 = get_field(s, m3);
1663      uint8_t m4 = get_field(s, m4);
1664  
1665      /* m3 field was introduced with FPE */
1666      if (!fpe && m3_with_fpe) {
1667          m3 = 0;
1668      }
1669      /* m4 field was introduced with FPE */
1670      if (!fpe && m4_with_fpe) {
1671          m4 = 0;
1672      }
1673  
1674      /* Check for valid rounding modes. Mode 3 was introduced later. */
1675      if (m3 == 2 || m3 > 7 || (!fpe && m3 == 3)) {
1676          gen_program_exception(s, PGM_SPECIFICATION);
1677          return NULL;
1678      }
1679  
1680      return tcg_constant_i32(deposit32(m3, 4, 4, m4));
1681  }
1682  
op_cfeb(DisasContext * s,DisasOps * o)1683  static DisasJumpType op_cfeb(DisasContext *s, DisasOps *o)
1684  {
1685      TCGv_i32 m34 = fpinst_extract_m34(s, false, true);
1686  
1687      if (!m34) {
1688          return DISAS_NORETURN;
1689      }
1690      gen_helper_cfeb(o->out, tcg_env, o->in2, m34);
1691      set_cc_static(s);
1692      return DISAS_NEXT;
1693  }
1694  
op_cfdb(DisasContext * s,DisasOps * o)1695  static DisasJumpType op_cfdb(DisasContext *s, DisasOps *o)
1696  {
1697      TCGv_i32 m34 = fpinst_extract_m34(s, false, true);
1698  
1699      if (!m34) {
1700          return DISAS_NORETURN;
1701      }
1702      gen_helper_cfdb(o->out, tcg_env, o->in2, m34);
1703      set_cc_static(s);
1704      return DISAS_NEXT;
1705  }
1706  
op_cfxb(DisasContext * s,DisasOps * o)1707  static DisasJumpType op_cfxb(DisasContext *s, DisasOps *o)
1708  {
1709      TCGv_i32 m34 = fpinst_extract_m34(s, false, true);
1710  
1711      if (!m34) {
1712          return DISAS_NORETURN;
1713      }
1714      gen_helper_cfxb(o->out, tcg_env, o->in2_128, m34);
1715      set_cc_static(s);
1716      return DISAS_NEXT;
1717  }
1718  
op_cgeb(DisasContext * s,DisasOps * o)1719  static DisasJumpType op_cgeb(DisasContext *s, DisasOps *o)
1720  {
1721      TCGv_i32 m34 = fpinst_extract_m34(s, false, true);
1722  
1723      if (!m34) {
1724          return DISAS_NORETURN;
1725      }
1726      gen_helper_cgeb(o->out, tcg_env, o->in2, m34);
1727      set_cc_static(s);
1728      return DISAS_NEXT;
1729  }
1730  
op_cgdb(DisasContext * s,DisasOps * o)1731  static DisasJumpType op_cgdb(DisasContext *s, DisasOps *o)
1732  {
1733      TCGv_i32 m34 = fpinst_extract_m34(s, false, true);
1734  
1735      if (!m34) {
1736          return DISAS_NORETURN;
1737      }
1738      gen_helper_cgdb(o->out, tcg_env, o->in2, m34);
1739      set_cc_static(s);
1740      return DISAS_NEXT;
1741  }
1742  
op_cgxb(DisasContext * s,DisasOps * o)1743  static DisasJumpType op_cgxb(DisasContext *s, DisasOps *o)
1744  {
1745      TCGv_i32 m34 = fpinst_extract_m34(s, false, true);
1746  
1747      if (!m34) {
1748          return DISAS_NORETURN;
1749      }
1750      gen_helper_cgxb(o->out, tcg_env, o->in2_128, m34);
1751      set_cc_static(s);
1752      return DISAS_NEXT;
1753  }
1754  
op_clfeb(DisasContext * s,DisasOps * o)1755  static DisasJumpType op_clfeb(DisasContext *s, DisasOps *o)
1756  {
1757      TCGv_i32 m34 = fpinst_extract_m34(s, false, false);
1758  
1759      if (!m34) {
1760          return DISAS_NORETURN;
1761      }
1762      gen_helper_clfeb(o->out, tcg_env, o->in2, m34);
1763      set_cc_static(s);
1764      return DISAS_NEXT;
1765  }
1766  
op_clfdb(DisasContext * s,DisasOps * o)1767  static DisasJumpType op_clfdb(DisasContext *s, DisasOps *o)
1768  {
1769      TCGv_i32 m34 = fpinst_extract_m34(s, false, false);
1770  
1771      if (!m34) {
1772          return DISAS_NORETURN;
1773      }
1774      gen_helper_clfdb(o->out, tcg_env, o->in2, m34);
1775      set_cc_static(s);
1776      return DISAS_NEXT;
1777  }
1778  
op_clfxb(DisasContext * s,DisasOps * o)1779  static DisasJumpType op_clfxb(DisasContext *s, DisasOps *o)
1780  {
1781      TCGv_i32 m34 = fpinst_extract_m34(s, false, false);
1782  
1783      if (!m34) {
1784          return DISAS_NORETURN;
1785      }
1786      gen_helper_clfxb(o->out, tcg_env, o->in2_128, m34);
1787      set_cc_static(s);
1788      return DISAS_NEXT;
1789  }
1790  
op_clgeb(DisasContext * s,DisasOps * o)1791  static DisasJumpType op_clgeb(DisasContext *s, DisasOps *o)
1792  {
1793      TCGv_i32 m34 = fpinst_extract_m34(s, false, false);
1794  
1795      if (!m34) {
1796          return DISAS_NORETURN;
1797      }
1798      gen_helper_clgeb(o->out, tcg_env, o->in2, m34);
1799      set_cc_static(s);
1800      return DISAS_NEXT;
1801  }
1802  
op_clgdb(DisasContext * s,DisasOps * o)1803  static DisasJumpType op_clgdb(DisasContext *s, DisasOps *o)
1804  {
1805      TCGv_i32 m34 = fpinst_extract_m34(s, false, false);
1806  
1807      if (!m34) {
1808          return DISAS_NORETURN;
1809      }
1810      gen_helper_clgdb(o->out, tcg_env, o->in2, m34);
1811      set_cc_static(s);
1812      return DISAS_NEXT;
1813  }
1814  
op_clgxb(DisasContext * s,DisasOps * o)1815  static DisasJumpType op_clgxb(DisasContext *s, DisasOps *o)
1816  {
1817      TCGv_i32 m34 = fpinst_extract_m34(s, false, false);
1818  
1819      if (!m34) {
1820          return DISAS_NORETURN;
1821      }
1822      gen_helper_clgxb(o->out, tcg_env, o->in2_128, m34);
1823      set_cc_static(s);
1824      return DISAS_NEXT;
1825  }
1826  
op_cegb(DisasContext * s,DisasOps * o)1827  static DisasJumpType op_cegb(DisasContext *s, DisasOps *o)
1828  {
1829      TCGv_i32 m34 = fpinst_extract_m34(s, true, true);
1830  
1831      if (!m34) {
1832          return DISAS_NORETURN;
1833      }
1834      gen_helper_cegb(o->out, tcg_env, o->in2, m34);
1835      return DISAS_NEXT;
1836  }
1837  
op_cdgb(DisasContext * s,DisasOps * o)1838  static DisasJumpType op_cdgb(DisasContext *s, DisasOps *o)
1839  {
1840      TCGv_i32 m34 = fpinst_extract_m34(s, true, true);
1841  
1842      if (!m34) {
1843          return DISAS_NORETURN;
1844      }
1845      gen_helper_cdgb(o->out, tcg_env, o->in2, m34);
1846      return DISAS_NEXT;
1847  }
1848  
op_cxgb(DisasContext * s,DisasOps * o)1849  static DisasJumpType op_cxgb(DisasContext *s, DisasOps *o)
1850  {
1851      TCGv_i32 m34 = fpinst_extract_m34(s, true, true);
1852  
1853      if (!m34) {
1854          return DISAS_NORETURN;
1855      }
1856      gen_helper_cxgb(o->out_128, tcg_env, o->in2, m34);
1857      return DISAS_NEXT;
1858  }
1859  
op_celgb(DisasContext * s,DisasOps * o)1860  static DisasJumpType op_celgb(DisasContext *s, DisasOps *o)
1861  {
1862      TCGv_i32 m34 = fpinst_extract_m34(s, false, false);
1863  
1864      if (!m34) {
1865          return DISAS_NORETURN;
1866      }
1867      gen_helper_celgb(o->out, tcg_env, o->in2, m34);
1868      return DISAS_NEXT;
1869  }
1870  
op_cdlgb(DisasContext * s,DisasOps * o)1871  static DisasJumpType op_cdlgb(DisasContext *s, DisasOps *o)
1872  {
1873      TCGv_i32 m34 = fpinst_extract_m34(s, false, false);
1874  
1875      if (!m34) {
1876          return DISAS_NORETURN;
1877      }
1878      gen_helper_cdlgb(o->out, tcg_env, o->in2, m34);
1879      return DISAS_NEXT;
1880  }
1881  
op_cxlgb(DisasContext * s,DisasOps * o)1882  static DisasJumpType op_cxlgb(DisasContext *s, DisasOps *o)
1883  {
1884      TCGv_i32 m34 = fpinst_extract_m34(s, false, false);
1885  
1886      if (!m34) {
1887          return DISAS_NORETURN;
1888      }
1889      gen_helper_cxlgb(o->out_128, tcg_env, o->in2, m34);
1890      return DISAS_NEXT;
1891  }
1892  
op_cksm(DisasContext * s,DisasOps * o)1893  static DisasJumpType op_cksm(DisasContext *s, DisasOps *o)
1894  {
1895      int r2 = get_field(s, r2);
1896      TCGv_i128 pair = tcg_temp_new_i128();
1897      TCGv_i64 len = tcg_temp_new_i64();
1898  
1899      gen_helper_cksm(pair, tcg_env, o->in1, o->in2, regs[r2 + 1]);
1900      set_cc_static(s);
1901      tcg_gen_extr_i128_i64(o->out, len, pair);
1902  
1903      tcg_gen_add_i64(regs[r2], regs[r2], len);
1904      tcg_gen_sub_i64(regs[r2 + 1], regs[r2 + 1], len);
1905  
1906      return DISAS_NEXT;
1907  }
1908  
op_clc(DisasContext * s,DisasOps * o)1909  static DisasJumpType op_clc(DisasContext *s, DisasOps *o)
1910  {
1911      int l = get_field(s, l1);
1912      TCGv_i64 src;
1913      TCGv_i32 vl;
1914      MemOp mop;
1915  
1916      switch (l + 1) {
1917      case 1:
1918      case 2:
1919      case 4:
1920      case 8:
1921          mop = ctz32(l + 1) | MO_TE;
1922          /* Do not update cc_src yet: loading cc_dst may cause an exception. */
1923          src = tcg_temp_new_i64();
1924          tcg_gen_qemu_ld_tl(src, o->addr1, get_mem_index(s), mop);
1925          tcg_gen_qemu_ld_tl(cc_dst, o->in2, get_mem_index(s), mop);
1926          gen_op_update2_cc_i64(s, CC_OP_LTUGTU_64, src, cc_dst);
1927          return DISAS_NEXT;
1928      default:
1929          vl = tcg_constant_i32(l);
1930          gen_helper_clc(cc_op, tcg_env, vl, o->addr1, o->in2);
1931          set_cc_static(s);
1932          return DISAS_NEXT;
1933      }
1934  }
1935  
op_clcl(DisasContext * s,DisasOps * o)1936  static DisasJumpType op_clcl(DisasContext *s, DisasOps *o)
1937  {
1938      int r1 = get_field(s, r1);
1939      int r2 = get_field(s, r2);
1940      TCGv_i32 t1, t2;
1941  
1942      /* r1 and r2 must be even.  */
1943      if (r1 & 1 || r2 & 1) {
1944          gen_program_exception(s, PGM_SPECIFICATION);
1945          return DISAS_NORETURN;
1946      }
1947  
1948      t1 = tcg_constant_i32(r1);
1949      t2 = tcg_constant_i32(r2);
1950      gen_helper_clcl(cc_op, tcg_env, t1, t2);
1951      set_cc_static(s);
1952      return DISAS_NEXT;
1953  }
1954  
op_clcle(DisasContext * s,DisasOps * o)1955  static DisasJumpType op_clcle(DisasContext *s, DisasOps *o)
1956  {
1957      int r1 = get_field(s, r1);
1958      int r3 = get_field(s, r3);
1959      TCGv_i32 t1, t3;
1960  
1961      /* r1 and r3 must be even.  */
1962      if (r1 & 1 || r3 & 1) {
1963          gen_program_exception(s, PGM_SPECIFICATION);
1964          return DISAS_NORETURN;
1965      }
1966  
1967      t1 = tcg_constant_i32(r1);
1968      t3 = tcg_constant_i32(r3);
1969      gen_helper_clcle(cc_op, tcg_env, t1, o->in2, t3);
1970      set_cc_static(s);
1971      return DISAS_NEXT;
1972  }
1973  
op_clclu(DisasContext * s,DisasOps * o)1974  static DisasJumpType op_clclu(DisasContext *s, DisasOps *o)
1975  {
1976      int r1 = get_field(s, r1);
1977      int r3 = get_field(s, r3);
1978      TCGv_i32 t1, t3;
1979  
1980      /* r1 and r3 must be even.  */
1981      if (r1 & 1 || r3 & 1) {
1982          gen_program_exception(s, PGM_SPECIFICATION);
1983          return DISAS_NORETURN;
1984      }
1985  
1986      t1 = tcg_constant_i32(r1);
1987      t3 = tcg_constant_i32(r3);
1988      gen_helper_clclu(cc_op, tcg_env, t1, o->in2, t3);
1989      set_cc_static(s);
1990      return DISAS_NEXT;
1991  }
1992  
op_clm(DisasContext * s,DisasOps * o)1993  static DisasJumpType op_clm(DisasContext *s, DisasOps *o)
1994  {
1995      TCGv_i32 m3 = tcg_constant_i32(get_field(s, m3));
1996      TCGv_i32 t1 = tcg_temp_new_i32();
1997  
1998      tcg_gen_extrl_i64_i32(t1, o->in1);
1999      gen_helper_clm(cc_op, tcg_env, t1, m3, o->in2);
2000      set_cc_static(s);
2001      return DISAS_NEXT;
2002  }
2003  
op_clst(DisasContext * s,DisasOps * o)2004  static DisasJumpType op_clst(DisasContext *s, DisasOps *o)
2005  {
2006      TCGv_i128 pair = tcg_temp_new_i128();
2007  
2008      gen_helper_clst(pair, tcg_env, regs[0], o->in1, o->in2);
2009      tcg_gen_extr_i128_i64(o->in2, o->in1, pair);
2010  
2011      set_cc_static(s);
2012      return DISAS_NEXT;
2013  }
2014  
op_cps(DisasContext * s,DisasOps * o)2015  static DisasJumpType op_cps(DisasContext *s, DisasOps *o)
2016  {
2017      TCGv_i64 t = tcg_temp_new_i64();
2018      tcg_gen_andi_i64(t, o->in1, 0x8000000000000000ull);
2019      tcg_gen_andi_i64(o->out, o->in2, 0x7fffffffffffffffull);
2020      tcg_gen_or_i64(o->out, o->out, t);
2021      return DISAS_NEXT;
2022  }
2023  
op_cs(DisasContext * s,DisasOps * o)2024  static DisasJumpType op_cs(DisasContext *s, DisasOps *o)
2025  {
2026      int d2 = get_field(s, d2);
2027      int b2 = get_field(s, b2);
2028      TCGv_i64 addr, cc;
2029  
2030      /* Note that in1 = R3 (new value) and
2031         in2 = (zero-extended) R1 (expected value).  */
2032  
2033      addr = get_address(s, 0, b2, d2);
2034      tcg_gen_atomic_cmpxchg_i64(o->out, addr, o->in2, o->in1,
2035                                 get_mem_index(s), s->insn->data | MO_ALIGN);
2036  
2037      /* Are the memory and expected values (un)equal?  Note that this setcond
2038         produces the output CC value, thus the NE sense of the test.  */
2039      cc = tcg_temp_new_i64();
2040      tcg_gen_setcond_i64(TCG_COND_NE, cc, o->in2, o->out);
2041      tcg_gen_extrl_i64_i32(cc_op, cc);
2042      set_cc_static(s);
2043  
2044      return DISAS_NEXT;
2045  }
2046  
op_cdsg(DisasContext * s,DisasOps * o)2047  static DisasJumpType op_cdsg(DisasContext *s, DisasOps *o)
2048  {
2049      int r1 = get_field(s, r1);
2050  
2051      o->out_128 = tcg_temp_new_i128();
2052      tcg_gen_concat_i64_i128(o->out_128, regs[r1 + 1], regs[r1]);
2053  
2054      /* Note out (R1:R1+1) = expected value and in2 (R3:R3+1) = new value.  */
2055      tcg_gen_atomic_cmpxchg_i128(o->out_128, o->addr1, o->out_128, o->in2_128,
2056                                  get_mem_index(s), MO_BE | MO_128 | MO_ALIGN);
2057  
2058      /*
2059       * Extract result into cc_dst:cc_src, compare vs the expected value
2060       * in the as yet unmodified input registers, then update CC_OP.
2061       */
2062      tcg_gen_extr_i128_i64(cc_src, cc_dst, o->out_128);
2063      tcg_gen_xor_i64(cc_dst, cc_dst, regs[r1]);
2064      tcg_gen_xor_i64(cc_src, cc_src, regs[r1 + 1]);
2065      tcg_gen_or_i64(cc_dst, cc_dst, cc_src);
2066      set_cc_nz_u64(s, cc_dst);
2067  
2068      return DISAS_NEXT;
2069  }
2070  
op_csst(DisasContext * s,DisasOps * o)2071  static DisasJumpType op_csst(DisasContext *s, DisasOps *o)
2072  {
2073      int r3 = get_field(s, r3);
2074      TCGv_i32 t_r3 = tcg_constant_i32(r3);
2075  
2076      if (tb_cflags(s->base.tb) & CF_PARALLEL) {
2077          gen_helper_csst_parallel(cc_op, tcg_env, t_r3, o->addr1, o->in2);
2078      } else {
2079          gen_helper_csst(cc_op, tcg_env, t_r3, o->addr1, o->in2);
2080      }
2081  
2082      set_cc_static(s);
2083      return DISAS_NEXT;
2084  }
2085  
2086  #ifndef CONFIG_USER_ONLY
op_csp(DisasContext * s,DisasOps * o)2087  static DisasJumpType op_csp(DisasContext *s, DisasOps *o)
2088  {
2089      MemOp mop = s->insn->data;
2090      TCGv_i64 addr, old, cc;
2091      TCGLabel *lab = gen_new_label();
2092  
2093      /* Note that in1 = R1 (zero-extended expected value),
2094         out = R1 (original reg), out2 = R1+1 (new value).  */
2095  
2096      addr = tcg_temp_new_i64();
2097      old = tcg_temp_new_i64();
2098      tcg_gen_andi_i64(addr, o->in2, -1ULL << (mop & MO_SIZE));
2099      tcg_gen_atomic_cmpxchg_i64(old, addr, o->in1, o->out2,
2100                                 get_mem_index(s), mop | MO_ALIGN);
2101  
2102      /* Are the memory and expected values (un)equal?  */
2103      cc = tcg_temp_new_i64();
2104      tcg_gen_setcond_i64(TCG_COND_NE, cc, o->in1, old);
2105      tcg_gen_extrl_i64_i32(cc_op, cc);
2106  
2107      /* Write back the output now, so that it happens before the
2108         following branch, so that we don't need local temps.  */
2109      if ((mop & MO_SIZE) == MO_32) {
2110          tcg_gen_deposit_i64(o->out, o->out, old, 0, 32);
2111      } else {
2112          tcg_gen_mov_i64(o->out, old);
2113      }
2114  
2115      /* If the comparison was equal, and the LSB of R2 was set,
2116         then we need to flush the TLB (for all cpus).  */
2117      tcg_gen_xori_i64(cc, cc, 1);
2118      tcg_gen_and_i64(cc, cc, o->in2);
2119      tcg_gen_brcondi_i64(TCG_COND_EQ, cc, 0, lab);
2120  
2121      gen_helper_purge(tcg_env);
2122      gen_set_label(lab);
2123  
2124      return DISAS_NEXT;
2125  }
2126  #endif
2127  
op_cvb(DisasContext * s,DisasOps * o)2128  static DisasJumpType op_cvb(DisasContext *s, DisasOps *o)
2129  {
2130      TCGv_i64 t = tcg_temp_new_i64();
2131      tcg_gen_qemu_ld_i64(t, o->addr1, get_mem_index(s), MO_TEUQ);
2132      gen_helper_cvb(tcg_env, tcg_constant_i32(get_field(s, r1)), t);
2133      return DISAS_NEXT;
2134  }
2135  
op_cvbg(DisasContext * s,DisasOps * o)2136  static DisasJumpType op_cvbg(DisasContext *s, DisasOps *o)
2137  {
2138      TCGv_i128 t = tcg_temp_new_i128();
2139      tcg_gen_qemu_ld_i128(t, o->addr1, get_mem_index(s), MO_TE | MO_128);
2140      gen_helper_cvbg(o->out, tcg_env, t);
2141      return DISAS_NEXT;
2142  }
2143  
op_cvd(DisasContext * s,DisasOps * o)2144  static DisasJumpType op_cvd(DisasContext *s, DisasOps *o)
2145  {
2146      TCGv_i64 t1 = tcg_temp_new_i64();
2147      TCGv_i32 t2 = tcg_temp_new_i32();
2148      tcg_gen_extrl_i64_i32(t2, o->in1);
2149      gen_helper_cvd(t1, t2);
2150      tcg_gen_qemu_st_i64(t1, o->in2, get_mem_index(s), MO_TEUQ);
2151      return DISAS_NEXT;
2152  }
2153  
op_cvdg(DisasContext * s,DisasOps * o)2154  static DisasJumpType op_cvdg(DisasContext *s, DisasOps *o)
2155  {
2156      TCGv_i128 t = tcg_temp_new_i128();
2157      gen_helper_cvdg(t, o->in1);
2158      tcg_gen_qemu_st_i128(t, o->in2, get_mem_index(s), MO_TE | MO_128);
2159      return DISAS_NEXT;
2160  }
2161  
op_ct(DisasContext * s,DisasOps * o)2162  static DisasJumpType op_ct(DisasContext *s, DisasOps *o)
2163  {
2164      int m3 = get_field(s, m3);
2165      TCGLabel *lab = gen_new_label();
2166      TCGCond c;
2167  
2168      c = tcg_invert_cond(ltgt_cond[m3]);
2169      if (s->insn->data) {
2170          c = tcg_unsigned_cond(c);
2171      }
2172      tcg_gen_brcond_i64(c, o->in1, o->in2, lab);
2173  
2174      /* Trap.  */
2175      gen_trap(s);
2176  
2177      gen_set_label(lab);
2178      return DISAS_NEXT;
2179  }
2180  
op_cuXX(DisasContext * s,DisasOps * o)2181  static DisasJumpType op_cuXX(DisasContext *s, DisasOps *o)
2182  {
2183      int m3 = get_field(s, m3);
2184      int r1 = get_field(s, r1);
2185      int r2 = get_field(s, r2);
2186      TCGv_i32 tr1, tr2, chk;
2187  
2188      /* R1 and R2 must both be even.  */
2189      if ((r1 | r2) & 1) {
2190          gen_program_exception(s, PGM_SPECIFICATION);
2191          return DISAS_NORETURN;
2192      }
2193      if (!s390_has_feat(S390_FEAT_ETF3_ENH)) {
2194          m3 = 0;
2195      }
2196  
2197      tr1 = tcg_constant_i32(r1);
2198      tr2 = tcg_constant_i32(r2);
2199      chk = tcg_constant_i32(m3);
2200  
2201      switch (s->insn->data) {
2202      case 12:
2203          gen_helper_cu12(cc_op, tcg_env, tr1, tr2, chk);
2204          break;
2205      case 14:
2206          gen_helper_cu14(cc_op, tcg_env, tr1, tr2, chk);
2207          break;
2208      case 21:
2209          gen_helper_cu21(cc_op, tcg_env, tr1, tr2, chk);
2210          break;
2211      case 24:
2212          gen_helper_cu24(cc_op, tcg_env, tr1, tr2, chk);
2213          break;
2214      case 41:
2215          gen_helper_cu41(cc_op, tcg_env, tr1, tr2, chk);
2216          break;
2217      case 42:
2218          gen_helper_cu42(cc_op, tcg_env, tr1, tr2, chk);
2219          break;
2220      default:
2221          g_assert_not_reached();
2222      }
2223  
2224      set_cc_static(s);
2225      return DISAS_NEXT;
2226  }
2227  
2228  #ifndef CONFIG_USER_ONLY
op_diag(DisasContext * s,DisasOps * o)2229  static DisasJumpType op_diag(DisasContext *s, DisasOps *o)
2230  {
2231      TCGv_i32 r1 = tcg_constant_i32(get_field(s, r1));
2232      TCGv_i32 r3 = tcg_constant_i32(get_field(s, r3));
2233      TCGv_i32 func_code = tcg_constant_i32(get_field(s, i2));
2234  
2235      gen_helper_diag(tcg_env, r1, r3, func_code);
2236      return DISAS_NEXT;
2237  }
2238  #endif
2239  
op_divs32(DisasContext * s,DisasOps * o)2240  static DisasJumpType op_divs32(DisasContext *s, DisasOps *o)
2241  {
2242      gen_helper_divs32(o->out, tcg_env, o->in1, o->in2);
2243      tcg_gen_extr32_i64(o->out2, o->out, o->out);
2244      return DISAS_NEXT;
2245  }
2246  
op_divu32(DisasContext * s,DisasOps * o)2247  static DisasJumpType op_divu32(DisasContext *s, DisasOps *o)
2248  {
2249      gen_helper_divu32(o->out, tcg_env, o->in1, o->in2);
2250      tcg_gen_extr32_i64(o->out2, o->out, o->out);
2251      return DISAS_NEXT;
2252  }
2253  
op_divs64(DisasContext * s,DisasOps * o)2254  static DisasJumpType op_divs64(DisasContext *s, DisasOps *o)
2255  {
2256      TCGv_i128 t = tcg_temp_new_i128();
2257  
2258      gen_helper_divs64(t, tcg_env, o->in1, o->in2);
2259      tcg_gen_extr_i128_i64(o->out2, o->out, t);
2260      return DISAS_NEXT;
2261  }
2262  
op_divu64(DisasContext * s,DisasOps * o)2263  static DisasJumpType op_divu64(DisasContext *s, DisasOps *o)
2264  {
2265      TCGv_i128 t = tcg_temp_new_i128();
2266  
2267      gen_helper_divu64(t, tcg_env, o->out, o->out2, o->in2);
2268      tcg_gen_extr_i128_i64(o->out2, o->out, t);
2269      return DISAS_NEXT;
2270  }
2271  
op_deb(DisasContext * s,DisasOps * o)2272  static DisasJumpType op_deb(DisasContext *s, DisasOps *o)
2273  {
2274      gen_helper_deb(o->out, tcg_env, o->in1, o->in2);
2275      return DISAS_NEXT;
2276  }
2277  
op_ddb(DisasContext * s,DisasOps * o)2278  static DisasJumpType op_ddb(DisasContext *s, DisasOps *o)
2279  {
2280      gen_helper_ddb(o->out, tcg_env, o->in1, o->in2);
2281      return DISAS_NEXT;
2282  }
2283  
op_dxb(DisasContext * s,DisasOps * o)2284  static DisasJumpType op_dxb(DisasContext *s, DisasOps *o)
2285  {
2286      gen_helper_dxb(o->out_128, tcg_env, o->in1_128, o->in2_128);
2287      return DISAS_NEXT;
2288  }
2289  
op_ear(DisasContext * s,DisasOps * o)2290  static DisasJumpType op_ear(DisasContext *s, DisasOps *o)
2291  {
2292      int r2 = get_field(s, r2);
2293      tcg_gen_ld32u_i64(o->out, tcg_env, offsetof(CPUS390XState, aregs[r2]));
2294      return DISAS_NEXT;
2295  }
2296  
op_ecag(DisasContext * s,DisasOps * o)2297  static DisasJumpType op_ecag(DisasContext *s, DisasOps *o)
2298  {
2299      /* No cache information provided.  */
2300      tcg_gen_movi_i64(o->out, -1);
2301      return DISAS_NEXT;
2302  }
2303  
op_efpc(DisasContext * s,DisasOps * o)2304  static DisasJumpType op_efpc(DisasContext *s, DisasOps *o)
2305  {
2306      tcg_gen_ld32u_i64(o->out, tcg_env, offsetof(CPUS390XState, fpc));
2307      return DISAS_NEXT;
2308  }
2309  
op_epsw(DisasContext * s,DisasOps * o)2310  static DisasJumpType op_epsw(DisasContext *s, DisasOps *o)
2311  {
2312      int r1 = get_field(s, r1);
2313      int r2 = get_field(s, r2);
2314      TCGv_i64 t = tcg_temp_new_i64();
2315      TCGv_i64 t_cc = tcg_temp_new_i64();
2316  
2317      /* Note the "subsequently" in the PoO, which implies a defined result
2318         if r1 == r2.  Thus we cannot defer these writes to an output hook.  */
2319      gen_op_calc_cc(s);
2320      tcg_gen_extu_i32_i64(t_cc, cc_op);
2321      tcg_gen_shri_i64(t, psw_mask, 32);
2322      tcg_gen_deposit_i64(t, t, t_cc, 12, 2);
2323      store_reg32_i64(r1, t);
2324      if (r2 != 0) {
2325          store_reg32_i64(r2, psw_mask);
2326      }
2327      return DISAS_NEXT;
2328  }
2329  
op_ex(DisasContext * s,DisasOps * o)2330  static DisasJumpType op_ex(DisasContext *s, DisasOps *o)
2331  {
2332      int r1 = get_field(s, r1);
2333      TCGv_i32 ilen;
2334      TCGv_i64 v1;
2335  
2336      /* Nested EXECUTE is not allowed.  */
2337      if (unlikely(s->ex_value)) {
2338          gen_program_exception(s, PGM_EXECUTE);
2339          return DISAS_NORETURN;
2340      }
2341  
2342      update_psw_addr(s);
2343      update_cc_op(s);
2344  
2345      if (r1 == 0) {
2346          v1 = tcg_constant_i64(0);
2347      } else {
2348          v1 = regs[r1];
2349      }
2350  
2351      ilen = tcg_constant_i32(s->ilen);
2352      gen_helper_ex(tcg_env, ilen, v1, o->in2);
2353  
2354      return DISAS_PC_CC_UPDATED;
2355  }
2356  
op_fieb(DisasContext * s,DisasOps * o)2357  static DisasJumpType op_fieb(DisasContext *s, DisasOps *o)
2358  {
2359      TCGv_i32 m34 = fpinst_extract_m34(s, false, true);
2360  
2361      if (!m34) {
2362          return DISAS_NORETURN;
2363      }
2364      gen_helper_fieb(o->out, tcg_env, o->in2, m34);
2365      return DISAS_NEXT;
2366  }
2367  
op_fidb(DisasContext * s,DisasOps * o)2368  static DisasJumpType op_fidb(DisasContext *s, DisasOps *o)
2369  {
2370      TCGv_i32 m34 = fpinst_extract_m34(s, false, true);
2371  
2372      if (!m34) {
2373          return DISAS_NORETURN;
2374      }
2375      gen_helper_fidb(o->out, tcg_env, o->in2, m34);
2376      return DISAS_NEXT;
2377  }
2378  
op_fixb(DisasContext * s,DisasOps * o)2379  static DisasJumpType op_fixb(DisasContext *s, DisasOps *o)
2380  {
2381      TCGv_i32 m34 = fpinst_extract_m34(s, false, true);
2382  
2383      if (!m34) {
2384          return DISAS_NORETURN;
2385      }
2386      gen_helper_fixb(o->out_128, tcg_env, o->in2_128, m34);
2387      return DISAS_NEXT;
2388  }
2389  
op_flogr(DisasContext * s,DisasOps * o)2390  static DisasJumpType op_flogr(DisasContext *s, DisasOps *o)
2391  {
2392      /* We'll use the original input for cc computation, since we get to
2393         compare that against 0, which ought to be better than comparing
2394         the real output against 64.  It also lets cc_dst be a convenient
2395         temporary during our computation.  */
2396      gen_op_update1_cc_i64(s, CC_OP_FLOGR, o->in2);
2397  
2398      /* R1 = IN ? CLZ(IN) : 64.  */
2399      tcg_gen_clzi_i64(o->out, o->in2, 64);
2400  
2401      /* R1+1 = IN & ~(found bit).  Note that we may attempt to shift this
2402         value by 64, which is undefined.  But since the shift is 64 iff the
2403         input is zero, we still get the correct result after and'ing.  */
2404      tcg_gen_movi_i64(o->out2, 0x8000000000000000ull);
2405      tcg_gen_shr_i64(o->out2, o->out2, o->out);
2406      tcg_gen_andc_i64(o->out2, cc_dst, o->out2);
2407      return DISAS_NEXT;
2408  }
2409  
op_icm(DisasContext * s,DisasOps * o)2410  static DisasJumpType op_icm(DisasContext *s, DisasOps *o)
2411  {
2412      int m3 = get_field(s, m3);
2413      int pos, len, base = s->insn->data;
2414      TCGv_i64 tmp = tcg_temp_new_i64();
2415      uint64_t ccm;
2416  
2417      switch (m3) {
2418      case 0xf:
2419          /* Effectively a 32-bit load.  */
2420          tcg_gen_qemu_ld_i64(tmp, o->in2, get_mem_index(s), MO_TEUL);
2421          len = 32;
2422          goto one_insert;
2423  
2424      case 0xc:
2425      case 0x6:
2426      case 0x3:
2427          /* Effectively a 16-bit load.  */
2428          tcg_gen_qemu_ld_i64(tmp, o->in2, get_mem_index(s), MO_TEUW);
2429          len = 16;
2430          goto one_insert;
2431  
2432      case 0x8:
2433      case 0x4:
2434      case 0x2:
2435      case 0x1:
2436          /* Effectively an 8-bit load.  */
2437          tcg_gen_qemu_ld_i64(tmp, o->in2, get_mem_index(s), MO_UB);
2438          len = 8;
2439          goto one_insert;
2440  
2441      one_insert:
2442          pos = base + ctz32(m3) * 8;
2443          tcg_gen_deposit_i64(o->out, o->out, tmp, pos, len);
2444          ccm = ((1ull << len) - 1) << pos;
2445          break;
2446  
2447      case 0:
2448          /* Recognize access exceptions for the first byte.  */
2449          tcg_gen_qemu_ld_i64(tmp, o->in2, get_mem_index(s), MO_UB);
2450          gen_op_movi_cc(s, 0);
2451          return DISAS_NEXT;
2452  
2453      default:
2454          /* This is going to be a sequence of loads and inserts.  */
2455          pos = base + 32 - 8;
2456          ccm = 0;
2457          while (m3) {
2458              if (m3 & 0x8) {
2459                  tcg_gen_qemu_ld_i64(tmp, o->in2, get_mem_index(s), MO_UB);
2460                  tcg_gen_addi_i64(o->in2, o->in2, 1);
2461                  tcg_gen_deposit_i64(o->out, o->out, tmp, pos, 8);
2462                  ccm |= 0xffull << pos;
2463              }
2464              m3 = (m3 << 1) & 0xf;
2465              pos -= 8;
2466          }
2467          break;
2468      }
2469  
2470      tcg_gen_movi_i64(tmp, ccm);
2471      gen_op_update2_cc_i64(s, CC_OP_ICM, tmp, o->out);
2472      return DISAS_NEXT;
2473  }
2474  
op_insi(DisasContext * s,DisasOps * o)2475  static DisasJumpType op_insi(DisasContext *s, DisasOps *o)
2476  {
2477      int shift = s->insn->data & 0xff;
2478      int size = s->insn->data >> 8;
2479      tcg_gen_deposit_i64(o->out, o->in1, o->in2, shift, size);
2480      return DISAS_NEXT;
2481  }
2482  
op_ipm(DisasContext * s,DisasOps * o)2483  static DisasJumpType op_ipm(DisasContext *s, DisasOps *o)
2484  {
2485      TCGv_i64 t1, t2;
2486  
2487      gen_op_calc_cc(s);
2488      t1 = tcg_temp_new_i64();
2489      tcg_gen_extract_i64(t1, psw_mask, 40, 4);
2490      t2 = tcg_temp_new_i64();
2491      tcg_gen_extu_i32_i64(t2, cc_op);
2492      tcg_gen_deposit_i64(t1, t1, t2, 4, 60);
2493      tcg_gen_deposit_i64(o->out, o->out, t1, 24, 8);
2494      return DISAS_NEXT;
2495  }
2496  
2497  #ifndef CONFIG_USER_ONLY
op_idte(DisasContext * s,DisasOps * o)2498  static DisasJumpType op_idte(DisasContext *s, DisasOps *o)
2499  {
2500      TCGv_i32 m4;
2501  
2502      if (s390_has_feat(S390_FEAT_LOCAL_TLB_CLEARING)) {
2503          m4 = tcg_constant_i32(get_field(s, m4));
2504      } else {
2505          m4 = tcg_constant_i32(0);
2506      }
2507      gen_helper_idte(tcg_env, o->in1, o->in2, m4);
2508      return DISAS_NEXT;
2509  }
2510  
op_ipte(DisasContext * s,DisasOps * o)2511  static DisasJumpType op_ipte(DisasContext *s, DisasOps *o)
2512  {
2513      TCGv_i32 m4;
2514  
2515      if (s390_has_feat(S390_FEAT_LOCAL_TLB_CLEARING)) {
2516          m4 = tcg_constant_i32(get_field(s, m4));
2517      } else {
2518          m4 = tcg_constant_i32(0);
2519      }
2520      gen_helper_ipte(tcg_env, o->in1, o->in2, m4);
2521      return DISAS_NEXT;
2522  }
2523  
op_iske(DisasContext * s,DisasOps * o)2524  static DisasJumpType op_iske(DisasContext *s, DisasOps *o)
2525  {
2526      gen_helper_iske(o->out, tcg_env, o->in2);
2527      return DISAS_NEXT;
2528  }
2529  #endif
2530  
op_msa(DisasContext * s,DisasOps * o)2531  static DisasJumpType op_msa(DisasContext *s, DisasOps *o)
2532  {
2533      int r1 = have_field(s, r1) ? get_field(s, r1) : 0;
2534      int r2 = have_field(s, r2) ? get_field(s, r2) : 0;
2535      int r3 = have_field(s, r3) ? get_field(s, r3) : 0;
2536      TCGv_i32 t_r1, t_r2, t_r3, type;
2537  
2538      switch (s->insn->data) {
2539      case S390_FEAT_TYPE_KMA:
2540          if (r3 == r1 || r3 == r2) {
2541              gen_program_exception(s, PGM_SPECIFICATION);
2542              return DISAS_NORETURN;
2543          }
2544          /* FALL THROUGH */
2545      case S390_FEAT_TYPE_KMCTR:
2546          if (r3 & 1 || !r3) {
2547              gen_program_exception(s, PGM_SPECIFICATION);
2548              return DISAS_NORETURN;
2549          }
2550          /* FALL THROUGH */
2551      case S390_FEAT_TYPE_PPNO:
2552      case S390_FEAT_TYPE_KMF:
2553      case S390_FEAT_TYPE_KMC:
2554      case S390_FEAT_TYPE_KMO:
2555      case S390_FEAT_TYPE_KM:
2556          if (r1 & 1 || !r1) {
2557              gen_program_exception(s, PGM_SPECIFICATION);
2558              return DISAS_NORETURN;
2559          }
2560          /* FALL THROUGH */
2561      case S390_FEAT_TYPE_KMAC:
2562      case S390_FEAT_TYPE_KIMD:
2563      case S390_FEAT_TYPE_KLMD:
2564          if (r2 & 1 || !r2) {
2565              gen_program_exception(s, PGM_SPECIFICATION);
2566              return DISAS_NORETURN;
2567          }
2568          /* FALL THROUGH */
2569      case S390_FEAT_TYPE_PCKMO:
2570      case S390_FEAT_TYPE_PCC:
2571          break;
2572      default:
2573          g_assert_not_reached();
2574      };
2575  
2576      t_r1 = tcg_constant_i32(r1);
2577      t_r2 = tcg_constant_i32(r2);
2578      t_r3 = tcg_constant_i32(r3);
2579      type = tcg_constant_i32(s->insn->data);
2580      gen_helper_msa(cc_op, tcg_env, t_r1, t_r2, t_r3, type);
2581      set_cc_static(s);
2582      return DISAS_NEXT;
2583  }
2584  
op_keb(DisasContext * s,DisasOps * o)2585  static DisasJumpType op_keb(DisasContext *s, DisasOps *o)
2586  {
2587      gen_helper_keb(cc_op, tcg_env, o->in1, o->in2);
2588      set_cc_static(s);
2589      return DISAS_NEXT;
2590  }
2591  
op_kdb(DisasContext * s,DisasOps * o)2592  static DisasJumpType op_kdb(DisasContext *s, DisasOps *o)
2593  {
2594      gen_helper_kdb(cc_op, tcg_env, o->in1, o->in2);
2595      set_cc_static(s);
2596      return DISAS_NEXT;
2597  }
2598  
op_kxb(DisasContext * s,DisasOps * o)2599  static DisasJumpType op_kxb(DisasContext *s, DisasOps *o)
2600  {
2601      gen_helper_kxb(cc_op, tcg_env, o->in1_128, o->in2_128);
2602      set_cc_static(s);
2603      return DISAS_NEXT;
2604  }
2605  
help_laa(DisasContext * s,DisasOps * o,bool addu64)2606  static DisasJumpType help_laa(DisasContext *s, DisasOps *o, bool addu64)
2607  {
2608      /* The real output is indeed the original value in memory;
2609         recompute the addition for the computation of CC.  */
2610      tcg_gen_atomic_fetch_add_i64(o->in2, o->in2, o->in1, get_mem_index(s),
2611                                   s->insn->data | MO_ALIGN);
2612      /* However, we need to recompute the addition for setting CC.  */
2613      if (addu64) {
2614          tcg_gen_movi_i64(cc_src, 0);
2615          tcg_gen_add2_i64(o->out, cc_src, o->in1, cc_src, o->in2, cc_src);
2616      } else {
2617          tcg_gen_add_i64(o->out, o->in1, o->in2);
2618      }
2619      return DISAS_NEXT;
2620  }
2621  
op_laa(DisasContext * s,DisasOps * o)2622  static DisasJumpType op_laa(DisasContext *s, DisasOps *o)
2623  {
2624      return help_laa(s, o, false);
2625  }
2626  
op_laa_addu64(DisasContext * s,DisasOps * o)2627  static DisasJumpType op_laa_addu64(DisasContext *s, DisasOps *o)
2628  {
2629      return help_laa(s, o, true);
2630  }
2631  
op_lan(DisasContext * s,DisasOps * o)2632  static DisasJumpType op_lan(DisasContext *s, DisasOps *o)
2633  {
2634      /* The real output is indeed the original value in memory;
2635         recompute the addition for the computation of CC.  */
2636      tcg_gen_atomic_fetch_and_i64(o->in2, o->in2, o->in1, get_mem_index(s),
2637                                   s->insn->data | MO_ALIGN);
2638      /* However, we need to recompute the operation for setting CC.  */
2639      tcg_gen_and_i64(o->out, o->in1, o->in2);
2640      return DISAS_NEXT;
2641  }
2642  
op_lao(DisasContext * s,DisasOps * o)2643  static DisasJumpType op_lao(DisasContext *s, DisasOps *o)
2644  {
2645      /* The real output is indeed the original value in memory;
2646         recompute the addition for the computation of CC.  */
2647      tcg_gen_atomic_fetch_or_i64(o->in2, o->in2, o->in1, get_mem_index(s),
2648                                  s->insn->data | MO_ALIGN);
2649      /* However, we need to recompute the operation for setting CC.  */
2650      tcg_gen_or_i64(o->out, o->in1, o->in2);
2651      return DISAS_NEXT;
2652  }
2653  
op_lax(DisasContext * s,DisasOps * o)2654  static DisasJumpType op_lax(DisasContext *s, DisasOps *o)
2655  {
2656      /* The real output is indeed the original value in memory;
2657         recompute the addition for the computation of CC.  */
2658      tcg_gen_atomic_fetch_xor_i64(o->in2, o->in2, o->in1, get_mem_index(s),
2659                                   s->insn->data | MO_ALIGN);
2660      /* However, we need to recompute the operation for setting CC.  */
2661      tcg_gen_xor_i64(o->out, o->in1, o->in2);
2662      return DISAS_NEXT;
2663  }
2664  
op_ldeb(DisasContext * s,DisasOps * o)2665  static DisasJumpType op_ldeb(DisasContext *s, DisasOps *o)
2666  {
2667      gen_helper_ldeb(o->out, tcg_env, o->in2);
2668      return DISAS_NEXT;
2669  }
2670  
op_ledb(DisasContext * s,DisasOps * o)2671  static DisasJumpType op_ledb(DisasContext *s, DisasOps *o)
2672  {
2673      TCGv_i32 m34 = fpinst_extract_m34(s, true, true);
2674  
2675      if (!m34) {
2676          return DISAS_NORETURN;
2677      }
2678      gen_helper_ledb(o->out, tcg_env, o->in2, m34);
2679      return DISAS_NEXT;
2680  }
2681  
op_ldxb(DisasContext * s,DisasOps * o)2682  static DisasJumpType op_ldxb(DisasContext *s, DisasOps *o)
2683  {
2684      TCGv_i32 m34 = fpinst_extract_m34(s, true, true);
2685  
2686      if (!m34) {
2687          return DISAS_NORETURN;
2688      }
2689      gen_helper_ldxb(o->out, tcg_env, o->in2_128, m34);
2690      return DISAS_NEXT;
2691  }
2692  
op_lexb(DisasContext * s,DisasOps * o)2693  static DisasJumpType op_lexb(DisasContext *s, DisasOps *o)
2694  {
2695      TCGv_i32 m34 = fpinst_extract_m34(s, true, true);
2696  
2697      if (!m34) {
2698          return DISAS_NORETURN;
2699      }
2700      gen_helper_lexb(o->out, tcg_env, o->in2_128, m34);
2701      return DISAS_NEXT;
2702  }
2703  
op_lxdb(DisasContext * s,DisasOps * o)2704  static DisasJumpType op_lxdb(DisasContext *s, DisasOps *o)
2705  {
2706      gen_helper_lxdb(o->out_128, tcg_env, o->in2);
2707      return DISAS_NEXT;
2708  }
2709  
op_lxeb(DisasContext * s,DisasOps * o)2710  static DisasJumpType op_lxeb(DisasContext *s, DisasOps *o)
2711  {
2712      gen_helper_lxeb(o->out_128, tcg_env, o->in2);
2713      return DISAS_NEXT;
2714  }
2715  
op_lde(DisasContext * s,DisasOps * o)2716  static DisasJumpType op_lde(DisasContext *s, DisasOps *o)
2717  {
2718      tcg_gen_shli_i64(o->out, o->in2, 32);
2719      return DISAS_NEXT;
2720  }
2721  
op_llgt(DisasContext * s,DisasOps * o)2722  static DisasJumpType op_llgt(DisasContext *s, DisasOps *o)
2723  {
2724      tcg_gen_andi_i64(o->out, o->in2, 0x7fffffff);
2725      return DISAS_NEXT;
2726  }
2727  
op_ld8s(DisasContext * s,DisasOps * o)2728  static DisasJumpType op_ld8s(DisasContext *s, DisasOps *o)
2729  {
2730      tcg_gen_qemu_ld_i64(o->out, o->in2, get_mem_index(s), MO_SB);
2731      return DISAS_NEXT;
2732  }
2733  
op_ld8u(DisasContext * s,DisasOps * o)2734  static DisasJumpType op_ld8u(DisasContext *s, DisasOps *o)
2735  {
2736      tcg_gen_qemu_ld_i64(o->out, o->in2, get_mem_index(s), MO_UB);
2737      return DISAS_NEXT;
2738  }
2739  
op_ld16s(DisasContext * s,DisasOps * o)2740  static DisasJumpType op_ld16s(DisasContext *s, DisasOps *o)
2741  {
2742      tcg_gen_qemu_ld_i64(o->out, o->in2, get_mem_index(s), MO_TESW);
2743      return DISAS_NEXT;
2744  }
2745  
op_ld16u(DisasContext * s,DisasOps * o)2746  static DisasJumpType op_ld16u(DisasContext *s, DisasOps *o)
2747  {
2748      tcg_gen_qemu_ld_i64(o->out, o->in2, get_mem_index(s), MO_TEUW);
2749      return DISAS_NEXT;
2750  }
2751  
op_ld32s(DisasContext * s,DisasOps * o)2752  static DisasJumpType op_ld32s(DisasContext *s, DisasOps *o)
2753  {
2754      tcg_gen_qemu_ld_tl(o->out, o->in2, get_mem_index(s),
2755                         MO_TESL | s->insn->data);
2756      return DISAS_NEXT;
2757  }
2758  
op_ld32u(DisasContext * s,DisasOps * o)2759  static DisasJumpType op_ld32u(DisasContext *s, DisasOps *o)
2760  {
2761      tcg_gen_qemu_ld_tl(o->out, o->in2, get_mem_index(s),
2762                         MO_TEUL | s->insn->data);
2763      return DISAS_NEXT;
2764  }
2765  
op_ld64(DisasContext * s,DisasOps * o)2766  static DisasJumpType op_ld64(DisasContext *s, DisasOps *o)
2767  {
2768      tcg_gen_qemu_ld_i64(o->out, o->in2, get_mem_index(s),
2769                          MO_TEUQ | s->insn->data);
2770      return DISAS_NEXT;
2771  }
2772  
op_lat(DisasContext * s,DisasOps * o)2773  static DisasJumpType op_lat(DisasContext *s, DisasOps *o)
2774  {
2775      TCGLabel *lab = gen_new_label();
2776      store_reg32_i64(get_field(s, r1), o->in2);
2777      /* The value is stored even in case of trap. */
2778      tcg_gen_brcondi_i64(TCG_COND_NE, o->in2, 0, lab);
2779      gen_trap(s);
2780      gen_set_label(lab);
2781      return DISAS_NEXT;
2782  }
2783  
op_lgat(DisasContext * s,DisasOps * o)2784  static DisasJumpType op_lgat(DisasContext *s, DisasOps *o)
2785  {
2786      TCGLabel *lab = gen_new_label();
2787      tcg_gen_qemu_ld_i64(o->out, o->in2, get_mem_index(s), MO_TEUQ);
2788      /* The value is stored even in case of trap. */
2789      tcg_gen_brcondi_i64(TCG_COND_NE, o->out, 0, lab);
2790      gen_trap(s);
2791      gen_set_label(lab);
2792      return DISAS_NEXT;
2793  }
2794  
op_lfhat(DisasContext * s,DisasOps * o)2795  static DisasJumpType op_lfhat(DisasContext *s, DisasOps *o)
2796  {
2797      TCGLabel *lab = gen_new_label();
2798      store_reg32h_i64(get_field(s, r1), o->in2);
2799      /* The value is stored even in case of trap. */
2800      tcg_gen_brcondi_i64(TCG_COND_NE, o->in2, 0, lab);
2801      gen_trap(s);
2802      gen_set_label(lab);
2803      return DISAS_NEXT;
2804  }
2805  
op_llgfat(DisasContext * s,DisasOps * o)2806  static DisasJumpType op_llgfat(DisasContext *s, DisasOps *o)
2807  {
2808      TCGLabel *lab = gen_new_label();
2809  
2810      tcg_gen_qemu_ld_i64(o->out, o->in2, get_mem_index(s), MO_TEUL);
2811      /* The value is stored even in case of trap. */
2812      tcg_gen_brcondi_i64(TCG_COND_NE, o->out, 0, lab);
2813      gen_trap(s);
2814      gen_set_label(lab);
2815      return DISAS_NEXT;
2816  }
2817  
op_llgtat(DisasContext * s,DisasOps * o)2818  static DisasJumpType op_llgtat(DisasContext *s, DisasOps *o)
2819  {
2820      TCGLabel *lab = gen_new_label();
2821      tcg_gen_andi_i64(o->out, o->in2, 0x7fffffff);
2822      /* The value is stored even in case of trap. */
2823      tcg_gen_brcondi_i64(TCG_COND_NE, o->out, 0, lab);
2824      gen_trap(s);
2825      gen_set_label(lab);
2826      return DISAS_NEXT;
2827  }
2828  
op_loc(DisasContext * s,DisasOps * o)2829  static DisasJumpType op_loc(DisasContext *s, DisasOps *o)
2830  {
2831      DisasCompare c;
2832  
2833      if (have_field(s, m3)) {
2834          /* LOAD * ON CONDITION */
2835          disas_jcc(s, &c, get_field(s, m3));
2836      } else {
2837          /* SELECT */
2838          disas_jcc(s, &c, get_field(s, m4));
2839      }
2840  
2841      if (c.is_64) {
2842          tcg_gen_movcond_i64(c.cond, o->out, c.u.s64.a, c.u.s64.b,
2843                              o->in2, o->in1);
2844      } else {
2845          TCGv_i32 t32 = tcg_temp_new_i32();
2846          TCGv_i64 t, z;
2847  
2848          tcg_gen_setcond_i32(c.cond, t32, c.u.s32.a, c.u.s32.b);
2849  
2850          t = tcg_temp_new_i64();
2851          tcg_gen_extu_i32_i64(t, t32);
2852  
2853          z = tcg_constant_i64(0);
2854          tcg_gen_movcond_i64(TCG_COND_NE, o->out, t, z, o->in2, o->in1);
2855      }
2856  
2857      return DISAS_NEXT;
2858  }
2859  
2860  #ifndef CONFIG_USER_ONLY
op_lctl(DisasContext * s,DisasOps * o)2861  static DisasJumpType op_lctl(DisasContext *s, DisasOps *o)
2862  {
2863      TCGv_i32 r1 = tcg_constant_i32(get_field(s, r1));
2864      TCGv_i32 r3 = tcg_constant_i32(get_field(s, r3));
2865  
2866      gen_helper_lctl(tcg_env, r1, o->in2, r3);
2867      /* Exit to main loop to reevaluate s390_cpu_exec_interrupt.  */
2868      s->exit_to_mainloop = true;
2869      return DISAS_TOO_MANY;
2870  }
2871  
op_lctlg(DisasContext * s,DisasOps * o)2872  static DisasJumpType op_lctlg(DisasContext *s, DisasOps *o)
2873  {
2874      TCGv_i32 r1 = tcg_constant_i32(get_field(s, r1));
2875      TCGv_i32 r3 = tcg_constant_i32(get_field(s, r3));
2876  
2877      gen_helper_lctlg(tcg_env, r1, o->in2, r3);
2878      /* Exit to main loop to reevaluate s390_cpu_exec_interrupt.  */
2879      s->exit_to_mainloop = true;
2880      return DISAS_TOO_MANY;
2881  }
2882  
op_lra(DisasContext * s,DisasOps * o)2883  static DisasJumpType op_lra(DisasContext *s, DisasOps *o)
2884  {
2885      gen_helper_lra(o->out, tcg_env, o->out, o->in2);
2886      set_cc_static(s);
2887      return DISAS_NEXT;
2888  }
2889  
op_lpp(DisasContext * s,DisasOps * o)2890  static DisasJumpType op_lpp(DisasContext *s, DisasOps *o)
2891  {
2892      tcg_gen_st_i64(o->in2, tcg_env, offsetof(CPUS390XState, pp));
2893      return DISAS_NEXT;
2894  }
2895  
op_lpsw(DisasContext * s,DisasOps * o)2896  static DisasJumpType op_lpsw(DisasContext *s, DisasOps *o)
2897  {
2898      TCGv_i64 mask, addr;
2899  
2900      per_breaking_event(s);
2901  
2902      /*
2903       * Convert the short PSW into the normal PSW, similar to what
2904       * s390_cpu_load_normal() does.
2905       */
2906      mask = tcg_temp_new_i64();
2907      addr = tcg_temp_new_i64();
2908      tcg_gen_qemu_ld_i64(mask, o->in2, get_mem_index(s), MO_TEUQ | MO_ALIGN_8);
2909      tcg_gen_andi_i64(addr, mask, PSW_MASK_SHORT_ADDR);
2910      tcg_gen_andi_i64(mask, mask, PSW_MASK_SHORT_CTRL);
2911      tcg_gen_xori_i64(mask, mask, PSW_MASK_SHORTPSW);
2912      gen_helper_load_psw(tcg_env, mask, addr);
2913      return DISAS_NORETURN;
2914  }
2915  
op_lpswe(DisasContext * s,DisasOps * o)2916  static DisasJumpType op_lpswe(DisasContext *s, DisasOps *o)
2917  {
2918      TCGv_i64 t1, t2;
2919  
2920      per_breaking_event(s);
2921  
2922      t1 = tcg_temp_new_i64();
2923      t2 = tcg_temp_new_i64();
2924      tcg_gen_qemu_ld_i64(t1, o->in2, get_mem_index(s),
2925                          MO_TEUQ | MO_ALIGN_8);
2926      tcg_gen_addi_i64(o->in2, o->in2, 8);
2927      tcg_gen_qemu_ld_i64(t2, o->in2, get_mem_index(s), MO_TEUQ);
2928      gen_helper_load_psw(tcg_env, t1, t2);
2929      return DISAS_NORETURN;
2930  }
2931  #endif
2932  
op_lam(DisasContext * s,DisasOps * o)2933  static DisasJumpType op_lam(DisasContext *s, DisasOps *o)
2934  {
2935      TCGv_i32 r1 = tcg_constant_i32(get_field(s, r1));
2936      TCGv_i32 r3 = tcg_constant_i32(get_field(s, r3));
2937  
2938      gen_helper_lam(tcg_env, r1, o->in2, r3);
2939      return DISAS_NEXT;
2940  }
2941  
op_lm32(DisasContext * s,DisasOps * o)2942  static DisasJumpType op_lm32(DisasContext *s, DisasOps *o)
2943  {
2944      int r1 = get_field(s, r1);
2945      int r3 = get_field(s, r3);
2946      TCGv_i64 t1, t2;
2947  
2948      /* Only one register to read. */
2949      t1 = tcg_temp_new_i64();
2950      if (unlikely(r1 == r3)) {
2951          tcg_gen_qemu_ld_i64(t1, o->in2, get_mem_index(s), MO_TEUL);
2952          store_reg32_i64(r1, t1);
2953          return DISAS_NEXT;
2954      }
2955  
2956      /* First load the values of the first and last registers to trigger
2957         possible page faults. */
2958      t2 = tcg_temp_new_i64();
2959      tcg_gen_qemu_ld_i64(t1, o->in2, get_mem_index(s), MO_TEUL);
2960      tcg_gen_addi_i64(t2, o->in2, 4 * ((r3 - r1) & 15));
2961      tcg_gen_qemu_ld_i64(t2, t2, get_mem_index(s), MO_TEUL);
2962      store_reg32_i64(r1, t1);
2963      store_reg32_i64(r3, t2);
2964  
2965      /* Only two registers to read. */
2966      if (((r1 + 1) & 15) == r3) {
2967          return DISAS_NEXT;
2968      }
2969  
2970      /* Then load the remaining registers. Page fault can't occur. */
2971      r3 = (r3 - 1) & 15;
2972      tcg_gen_movi_i64(t2, 4);
2973      while (r1 != r3) {
2974          r1 = (r1 + 1) & 15;
2975          tcg_gen_add_i64(o->in2, o->in2, t2);
2976          tcg_gen_qemu_ld_i64(t1, o->in2, get_mem_index(s), MO_TEUL);
2977          store_reg32_i64(r1, t1);
2978      }
2979      return DISAS_NEXT;
2980  }
2981  
op_lmh(DisasContext * s,DisasOps * o)2982  static DisasJumpType op_lmh(DisasContext *s, DisasOps *o)
2983  {
2984      int r1 = get_field(s, r1);
2985      int r3 = get_field(s, r3);
2986      TCGv_i64 t1, t2;
2987  
2988      /* Only one register to read. */
2989      t1 = tcg_temp_new_i64();
2990      if (unlikely(r1 == r3)) {
2991          tcg_gen_qemu_ld_i64(t1, o->in2, get_mem_index(s), MO_TEUL);
2992          store_reg32h_i64(r1, t1);
2993          return DISAS_NEXT;
2994      }
2995  
2996      /* First load the values of the first and last registers to trigger
2997         possible page faults. */
2998      t2 = tcg_temp_new_i64();
2999      tcg_gen_qemu_ld_i64(t1, o->in2, get_mem_index(s), MO_TEUL);
3000      tcg_gen_addi_i64(t2, o->in2, 4 * ((r3 - r1) & 15));
3001      tcg_gen_qemu_ld_i64(t2, t2, get_mem_index(s), MO_TEUL);
3002      store_reg32h_i64(r1, t1);
3003      store_reg32h_i64(r3, t2);
3004  
3005      /* Only two registers to read. */
3006      if (((r1 + 1) & 15) == r3) {
3007          return DISAS_NEXT;
3008      }
3009  
3010      /* Then load the remaining registers. Page fault can't occur. */
3011      r3 = (r3 - 1) & 15;
3012      tcg_gen_movi_i64(t2, 4);
3013      while (r1 != r3) {
3014          r1 = (r1 + 1) & 15;
3015          tcg_gen_add_i64(o->in2, o->in2, t2);
3016          tcg_gen_qemu_ld_i64(t1, o->in2, get_mem_index(s), MO_TEUL);
3017          store_reg32h_i64(r1, t1);
3018      }
3019      return DISAS_NEXT;
3020  }
3021  
op_lm64(DisasContext * s,DisasOps * o)3022  static DisasJumpType op_lm64(DisasContext *s, DisasOps *o)
3023  {
3024      int r1 = get_field(s, r1);
3025      int r3 = get_field(s, r3);
3026      TCGv_i64 t1, t2;
3027  
3028      /* Only one register to read. */
3029      if (unlikely(r1 == r3)) {
3030          tcg_gen_qemu_ld_i64(regs[r1], o->in2, get_mem_index(s), MO_TEUQ);
3031          return DISAS_NEXT;
3032      }
3033  
3034      /* First load the values of the first and last registers to trigger
3035         possible page faults. */
3036      t1 = tcg_temp_new_i64();
3037      t2 = tcg_temp_new_i64();
3038      tcg_gen_qemu_ld_i64(t1, o->in2, get_mem_index(s), MO_TEUQ);
3039      tcg_gen_addi_i64(t2, o->in2, 8 * ((r3 - r1) & 15));
3040      tcg_gen_qemu_ld_i64(regs[r3], t2, get_mem_index(s), MO_TEUQ);
3041      tcg_gen_mov_i64(regs[r1], t1);
3042  
3043      /* Only two registers to read. */
3044      if (((r1 + 1) & 15) == r3) {
3045          return DISAS_NEXT;
3046      }
3047  
3048      /* Then load the remaining registers. Page fault can't occur. */
3049      r3 = (r3 - 1) & 15;
3050      tcg_gen_movi_i64(t1, 8);
3051      while (r1 != r3) {
3052          r1 = (r1 + 1) & 15;
3053          tcg_gen_add_i64(o->in2, o->in2, t1);
3054          tcg_gen_qemu_ld_i64(regs[r1], o->in2, get_mem_index(s), MO_TEUQ);
3055      }
3056      return DISAS_NEXT;
3057  }
3058  
op_lpd(DisasContext * s,DisasOps * o)3059  static DisasJumpType op_lpd(DisasContext *s, DisasOps *o)
3060  {
3061      TCGv_i64 a1, a2;
3062      MemOp mop = s->insn->data;
3063  
3064      /* In a parallel context, stop the world and single step.  */
3065      if (tb_cflags(s->base.tb) & CF_PARALLEL) {
3066          update_psw_addr(s);
3067          update_cc_op(s);
3068          gen_exception(EXCP_ATOMIC);
3069          return DISAS_NORETURN;
3070      }
3071  
3072      /* In a serial context, perform the two loads ... */
3073      a1 = get_address(s, 0, get_field(s, b1), get_field(s, d1));
3074      a2 = get_address(s, 0, get_field(s, b2), get_field(s, d2));
3075      tcg_gen_qemu_ld_i64(o->out, a1, get_mem_index(s), mop | MO_ALIGN);
3076      tcg_gen_qemu_ld_i64(o->out2, a2, get_mem_index(s), mop | MO_ALIGN);
3077  
3078      /* ... and indicate that we performed them while interlocked.  */
3079      gen_op_movi_cc(s, 0);
3080      return DISAS_NEXT;
3081  }
3082  
op_lpq(DisasContext * s,DisasOps * o)3083  static DisasJumpType op_lpq(DisasContext *s, DisasOps *o)
3084  {
3085      o->out_128 = tcg_temp_new_i128();
3086      tcg_gen_qemu_ld_i128(o->out_128, o->in2, get_mem_index(s),
3087                           MO_TE | MO_128 | MO_ALIGN);
3088      return DISAS_NEXT;
3089  }
3090  
3091  #ifndef CONFIG_USER_ONLY
op_lura(DisasContext * s,DisasOps * o)3092  static DisasJumpType op_lura(DisasContext *s, DisasOps *o)
3093  {
3094      tcg_gen_qemu_ld_tl(o->out, o->in2, MMU_REAL_IDX, s->insn->data);
3095      return DISAS_NEXT;
3096  }
3097  #endif
3098  
op_lzrb(DisasContext * s,DisasOps * o)3099  static DisasJumpType op_lzrb(DisasContext *s, DisasOps *o)
3100  {
3101      tcg_gen_andi_i64(o->out, o->in2, -256);
3102      return DISAS_NEXT;
3103  }
3104  
op_lcbb(DisasContext * s,DisasOps * o)3105  static DisasJumpType op_lcbb(DisasContext *s, DisasOps *o)
3106  {
3107      const int64_t block_size = (1ull << (get_field(s, m3) + 6));
3108  
3109      if (get_field(s, m3) > 6) {
3110          gen_program_exception(s, PGM_SPECIFICATION);
3111          return DISAS_NORETURN;
3112      }
3113  
3114      tcg_gen_ori_i64(o->addr1, o->addr1, -block_size);
3115      tcg_gen_neg_i64(o->addr1, o->addr1);
3116      tcg_gen_movi_i64(o->out, 16);
3117      tcg_gen_umin_i64(o->out, o->out, o->addr1);
3118      gen_op_update1_cc_i64(s, CC_OP_LCBB, o->out);
3119      return DISAS_NEXT;
3120  }
3121  
op_mc(DisasContext * s,DisasOps * o)3122  static DisasJumpType op_mc(DisasContext *s, DisasOps *o)
3123  {
3124      const uint8_t monitor_class = get_field(s, i2);
3125  
3126      if (monitor_class & 0xf0) {
3127          gen_program_exception(s, PGM_SPECIFICATION);
3128          return DISAS_NORETURN;
3129      }
3130  
3131  #if !defined(CONFIG_USER_ONLY)
3132      gen_helper_monitor_call(tcg_env, o->addr1,
3133                              tcg_constant_i32(monitor_class));
3134  #endif
3135      /* Defaults to a NOP. */
3136      return DISAS_NEXT;
3137  }
3138  
op_mov2(DisasContext * s,DisasOps * o)3139  static DisasJumpType op_mov2(DisasContext *s, DisasOps *o)
3140  {
3141      o->out = o->in2;
3142      o->in2 = NULL;
3143      return DISAS_NEXT;
3144  }
3145  
op_mov2e(DisasContext * s,DisasOps * o)3146  static DisasJumpType op_mov2e(DisasContext *s, DisasOps *o)
3147  {
3148      int b2 = get_field(s, b2);
3149      TCGv ar1 = tcg_temp_new_i64();
3150      int r1 = get_field(s, r1);
3151  
3152      o->out = o->in2;
3153      o->in2 = NULL;
3154  
3155      switch (s->base.tb->flags & FLAG_MASK_ASC) {
3156      case PSW_ASC_PRIMARY >> FLAG_MASK_PSW_SHIFT:
3157          tcg_gen_movi_i64(ar1, 0);
3158          break;
3159      case PSW_ASC_ACCREG >> FLAG_MASK_PSW_SHIFT:
3160          tcg_gen_movi_i64(ar1, 1);
3161          break;
3162      case PSW_ASC_SECONDARY >> FLAG_MASK_PSW_SHIFT:
3163          if (b2) {
3164              tcg_gen_ld32u_i64(ar1, tcg_env, offsetof(CPUS390XState, aregs[b2]));
3165          } else {
3166              tcg_gen_movi_i64(ar1, 0);
3167          }
3168          break;
3169      case PSW_ASC_HOME >> FLAG_MASK_PSW_SHIFT:
3170          tcg_gen_movi_i64(ar1, 2);
3171          break;
3172      }
3173  
3174      tcg_gen_st32_i64(ar1, tcg_env, offsetof(CPUS390XState, aregs[r1]));
3175      return DISAS_NEXT;
3176  }
3177  
op_movx(DisasContext * s,DisasOps * o)3178  static DisasJumpType op_movx(DisasContext *s, DisasOps *o)
3179  {
3180      o->out = o->in1;
3181      o->out2 = o->in2;
3182      o->in1 = NULL;
3183      o->in2 = NULL;
3184      return DISAS_NEXT;
3185  }
3186  
op_mvc(DisasContext * s,DisasOps * o)3187  static DisasJumpType op_mvc(DisasContext *s, DisasOps *o)
3188  {
3189      TCGv_i32 l = tcg_constant_i32(get_field(s, l1));
3190  
3191      gen_helper_mvc(tcg_env, l, o->addr1, o->in2);
3192      return DISAS_NEXT;
3193  }
3194  
op_mvcrl(DisasContext * s,DisasOps * o)3195  static DisasJumpType op_mvcrl(DisasContext *s, DisasOps *o)
3196  {
3197      gen_helper_mvcrl(tcg_env, regs[0], o->addr1, o->in2);
3198      return DISAS_NEXT;
3199  }
3200  
op_mvcin(DisasContext * s,DisasOps * o)3201  static DisasJumpType op_mvcin(DisasContext *s, DisasOps *o)
3202  {
3203      TCGv_i32 l = tcg_constant_i32(get_field(s, l1));
3204  
3205      gen_helper_mvcin(tcg_env, l, o->addr1, o->in2);
3206      return DISAS_NEXT;
3207  }
3208  
op_mvcl(DisasContext * s,DisasOps * o)3209  static DisasJumpType op_mvcl(DisasContext *s, DisasOps *o)
3210  {
3211      int r1 = get_field(s, r1);
3212      int r2 = get_field(s, r2);
3213      TCGv_i32 t1, t2;
3214  
3215      /* r1 and r2 must be even.  */
3216      if (r1 & 1 || r2 & 1) {
3217          gen_program_exception(s, PGM_SPECIFICATION);
3218          return DISAS_NORETURN;
3219      }
3220  
3221      t1 = tcg_constant_i32(r1);
3222      t2 = tcg_constant_i32(r2);
3223      gen_helper_mvcl(cc_op, tcg_env, t1, t2);
3224      set_cc_static(s);
3225      return DISAS_NEXT;
3226  }
3227  
op_mvcle(DisasContext * s,DisasOps * o)3228  static DisasJumpType op_mvcle(DisasContext *s, DisasOps *o)
3229  {
3230      int r1 = get_field(s, r1);
3231      int r3 = get_field(s, r3);
3232      TCGv_i32 t1, t3;
3233  
3234      /* r1 and r3 must be even.  */
3235      if (r1 & 1 || r3 & 1) {
3236          gen_program_exception(s, PGM_SPECIFICATION);
3237          return DISAS_NORETURN;
3238      }
3239  
3240      t1 = tcg_constant_i32(r1);
3241      t3 = tcg_constant_i32(r3);
3242      gen_helper_mvcle(cc_op, tcg_env, t1, o->in2, t3);
3243      set_cc_static(s);
3244      return DISAS_NEXT;
3245  }
3246  
op_mvclu(DisasContext * s,DisasOps * o)3247  static DisasJumpType op_mvclu(DisasContext *s, DisasOps *o)
3248  {
3249      int r1 = get_field(s, r1);
3250      int r3 = get_field(s, r3);
3251      TCGv_i32 t1, t3;
3252  
3253      /* r1 and r3 must be even.  */
3254      if (r1 & 1 || r3 & 1) {
3255          gen_program_exception(s, PGM_SPECIFICATION);
3256          return DISAS_NORETURN;
3257      }
3258  
3259      t1 = tcg_constant_i32(r1);
3260      t3 = tcg_constant_i32(r3);
3261      gen_helper_mvclu(cc_op, tcg_env, t1, o->in2, t3);
3262      set_cc_static(s);
3263      return DISAS_NEXT;
3264  }
3265  
op_mvcos(DisasContext * s,DisasOps * o)3266  static DisasJumpType op_mvcos(DisasContext *s, DisasOps *o)
3267  {
3268      int r3 = get_field(s, r3);
3269      gen_helper_mvcos(cc_op, tcg_env, o->addr1, o->in2, regs[r3]);
3270      set_cc_static(s);
3271      return DISAS_NEXT;
3272  }
3273  
3274  #ifndef CONFIG_USER_ONLY
op_mvcp(DisasContext * s,DisasOps * o)3275  static DisasJumpType op_mvcp(DisasContext *s, DisasOps *o)
3276  {
3277      int r1 = get_field(s, l1);
3278      int r3 = get_field(s, r3);
3279      gen_helper_mvcp(cc_op, tcg_env, regs[r1], o->addr1, o->in2, regs[r3]);
3280      set_cc_static(s);
3281      return DISAS_NEXT;
3282  }
3283  
op_mvcs(DisasContext * s,DisasOps * o)3284  static DisasJumpType op_mvcs(DisasContext *s, DisasOps *o)
3285  {
3286      int r1 = get_field(s, l1);
3287      int r3 = get_field(s, r3);
3288      gen_helper_mvcs(cc_op, tcg_env, regs[r1], o->addr1, o->in2, regs[r3]);
3289      set_cc_static(s);
3290      return DISAS_NEXT;
3291  }
3292  #endif
3293  
op_mvn(DisasContext * s,DisasOps * o)3294  static DisasJumpType op_mvn(DisasContext *s, DisasOps *o)
3295  {
3296      TCGv_i32 l = tcg_constant_i32(get_field(s, l1));
3297  
3298      gen_helper_mvn(tcg_env, l, o->addr1, o->in2);
3299      return DISAS_NEXT;
3300  }
3301  
op_mvo(DisasContext * s,DisasOps * o)3302  static DisasJumpType op_mvo(DisasContext *s, DisasOps *o)
3303  {
3304      TCGv_i32 l = tcg_constant_i32(get_field(s, l1));
3305  
3306      gen_helper_mvo(tcg_env, l, o->addr1, o->in2);
3307      return DISAS_NEXT;
3308  }
3309  
op_mvpg(DisasContext * s,DisasOps * o)3310  static DisasJumpType op_mvpg(DisasContext *s, DisasOps *o)
3311  {
3312      TCGv_i32 t1 = tcg_constant_i32(get_field(s, r1));
3313      TCGv_i32 t2 = tcg_constant_i32(get_field(s, r2));
3314  
3315      gen_helper_mvpg(cc_op, tcg_env, regs[0], t1, t2);
3316      set_cc_static(s);
3317      return DISAS_NEXT;
3318  }
3319  
op_mvst(DisasContext * s,DisasOps * o)3320  static DisasJumpType op_mvst(DisasContext *s, DisasOps *o)
3321  {
3322      TCGv_i32 t1 = tcg_constant_i32(get_field(s, r1));
3323      TCGv_i32 t2 = tcg_constant_i32(get_field(s, r2));
3324  
3325      gen_helper_mvst(cc_op, tcg_env, t1, t2);
3326      set_cc_static(s);
3327      return DISAS_NEXT;
3328  }
3329  
op_mvz(DisasContext * s,DisasOps * o)3330  static DisasJumpType op_mvz(DisasContext *s, DisasOps *o)
3331  {
3332      TCGv_i32 l = tcg_constant_i32(get_field(s, l1));
3333  
3334      gen_helper_mvz(tcg_env, l, o->addr1, o->in2);
3335      return DISAS_NEXT;
3336  }
3337  
op_mul(DisasContext * s,DisasOps * o)3338  static DisasJumpType op_mul(DisasContext *s, DisasOps *o)
3339  {
3340      tcg_gen_mul_i64(o->out, o->in1, o->in2);
3341      return DISAS_NEXT;
3342  }
3343  
op_mul128(DisasContext * s,DisasOps * o)3344  static DisasJumpType op_mul128(DisasContext *s, DisasOps *o)
3345  {
3346      tcg_gen_mulu2_i64(o->out2, o->out, o->in1, o->in2);
3347      return DISAS_NEXT;
3348  }
3349  
op_muls128(DisasContext * s,DisasOps * o)3350  static DisasJumpType op_muls128(DisasContext *s, DisasOps *o)
3351  {
3352      tcg_gen_muls2_i64(o->out2, o->out, o->in1, o->in2);
3353      return DISAS_NEXT;
3354  }
3355  
op_meeb(DisasContext * s,DisasOps * o)3356  static DisasJumpType op_meeb(DisasContext *s, DisasOps *o)
3357  {
3358      gen_helper_meeb(o->out, tcg_env, o->in1, o->in2);
3359      return DISAS_NEXT;
3360  }
3361  
op_mdeb(DisasContext * s,DisasOps * o)3362  static DisasJumpType op_mdeb(DisasContext *s, DisasOps *o)
3363  {
3364      gen_helper_mdeb(o->out, tcg_env, o->in1, o->in2);
3365      return DISAS_NEXT;
3366  }
3367  
op_mdb(DisasContext * s,DisasOps * o)3368  static DisasJumpType op_mdb(DisasContext *s, DisasOps *o)
3369  {
3370      gen_helper_mdb(o->out, tcg_env, o->in1, o->in2);
3371      return DISAS_NEXT;
3372  }
3373  
op_mxb(DisasContext * s,DisasOps * o)3374  static DisasJumpType op_mxb(DisasContext *s, DisasOps *o)
3375  {
3376      gen_helper_mxb(o->out_128, tcg_env, o->in1_128, o->in2_128);
3377      return DISAS_NEXT;
3378  }
3379  
op_mxdb(DisasContext * s,DisasOps * o)3380  static DisasJumpType op_mxdb(DisasContext *s, DisasOps *o)
3381  {
3382      gen_helper_mxdb(o->out_128, tcg_env, o->in1, o->in2);
3383      return DISAS_NEXT;
3384  }
3385  
op_maeb(DisasContext * s,DisasOps * o)3386  static DisasJumpType op_maeb(DisasContext *s, DisasOps *o)
3387  {
3388      TCGv_i64 r3 = load_freg32_i64(get_field(s, r3));
3389      gen_helper_maeb(o->out, tcg_env, o->in1, o->in2, r3);
3390      return DISAS_NEXT;
3391  }
3392  
op_madb(DisasContext * s,DisasOps * o)3393  static DisasJumpType op_madb(DisasContext *s, DisasOps *o)
3394  {
3395      TCGv_i64 r3 = load_freg(get_field(s, r3));
3396      gen_helper_madb(o->out, tcg_env, o->in1, o->in2, r3);
3397      return DISAS_NEXT;
3398  }
3399  
op_mseb(DisasContext * s,DisasOps * o)3400  static DisasJumpType op_mseb(DisasContext *s, DisasOps *o)
3401  {
3402      TCGv_i64 r3 = load_freg32_i64(get_field(s, r3));
3403      gen_helper_mseb(o->out, tcg_env, o->in1, o->in2, r3);
3404      return DISAS_NEXT;
3405  }
3406  
op_msdb(DisasContext * s,DisasOps * o)3407  static DisasJumpType op_msdb(DisasContext *s, DisasOps *o)
3408  {
3409      TCGv_i64 r3 = load_freg(get_field(s, r3));
3410      gen_helper_msdb(o->out, tcg_env, o->in1, o->in2, r3);
3411      return DISAS_NEXT;
3412  }
3413  
op_nabs(DisasContext * s,DisasOps * o)3414  static DisasJumpType op_nabs(DisasContext *s, DisasOps *o)
3415  {
3416      TCGv_i64 z = tcg_constant_i64(0);
3417      TCGv_i64 n = tcg_temp_new_i64();
3418  
3419      tcg_gen_neg_i64(n, o->in2);
3420      tcg_gen_movcond_i64(TCG_COND_GE, o->out, o->in2, z, n, o->in2);
3421      return DISAS_NEXT;
3422  }
3423  
op_nabsf32(DisasContext * s,DisasOps * o)3424  static DisasJumpType op_nabsf32(DisasContext *s, DisasOps *o)
3425  {
3426      tcg_gen_ori_i64(o->out, o->in2, 0x80000000ull);
3427      return DISAS_NEXT;
3428  }
3429  
op_nabsf64(DisasContext * s,DisasOps * o)3430  static DisasJumpType op_nabsf64(DisasContext *s, DisasOps *o)
3431  {
3432      tcg_gen_ori_i64(o->out, o->in2, 0x8000000000000000ull);
3433      return DISAS_NEXT;
3434  }
3435  
op_nabsf128(DisasContext * s,DisasOps * o)3436  static DisasJumpType op_nabsf128(DisasContext *s, DisasOps *o)
3437  {
3438      tcg_gen_ori_i64(o->out, o->in1, 0x8000000000000000ull);
3439      tcg_gen_mov_i64(o->out2, o->in2);
3440      return DISAS_NEXT;
3441  }
3442  
op_nc(DisasContext * s,DisasOps * o)3443  static DisasJumpType op_nc(DisasContext *s, DisasOps *o)
3444  {
3445      TCGv_i32 l = tcg_constant_i32(get_field(s, l1));
3446  
3447      gen_helper_nc(cc_op, tcg_env, l, o->addr1, o->in2);
3448      set_cc_static(s);
3449      return DISAS_NEXT;
3450  }
3451  
op_neg(DisasContext * s,DisasOps * o)3452  static DisasJumpType op_neg(DisasContext *s, DisasOps *o)
3453  {
3454      tcg_gen_neg_i64(o->out, o->in2);
3455      return DISAS_NEXT;
3456  }
3457  
op_negf32(DisasContext * s,DisasOps * o)3458  static DisasJumpType op_negf32(DisasContext *s, DisasOps *o)
3459  {
3460      tcg_gen_xori_i64(o->out, o->in2, 0x80000000ull);
3461      return DISAS_NEXT;
3462  }
3463  
op_negf64(DisasContext * s,DisasOps * o)3464  static DisasJumpType op_negf64(DisasContext *s, DisasOps *o)
3465  {
3466      tcg_gen_xori_i64(o->out, o->in2, 0x8000000000000000ull);
3467      return DISAS_NEXT;
3468  }
3469  
op_negf128(DisasContext * s,DisasOps * o)3470  static DisasJumpType op_negf128(DisasContext *s, DisasOps *o)
3471  {
3472      tcg_gen_xori_i64(o->out, o->in1, 0x8000000000000000ull);
3473      tcg_gen_mov_i64(o->out2, o->in2);
3474      return DISAS_NEXT;
3475  }
3476  
op_oc(DisasContext * s,DisasOps * o)3477  static DisasJumpType op_oc(DisasContext *s, DisasOps *o)
3478  {
3479      TCGv_i32 l = tcg_constant_i32(get_field(s, l1));
3480  
3481      gen_helper_oc(cc_op, tcg_env, l, o->addr1, o->in2);
3482      set_cc_static(s);
3483      return DISAS_NEXT;
3484  }
3485  
op_or(DisasContext * s,DisasOps * o)3486  static DisasJumpType op_or(DisasContext *s, DisasOps *o)
3487  {
3488      tcg_gen_or_i64(o->out, o->in1, o->in2);
3489      return DISAS_NEXT;
3490  }
3491  
op_ori(DisasContext * s,DisasOps * o)3492  static DisasJumpType op_ori(DisasContext *s, DisasOps *o)
3493  {
3494      int shift = s->insn->data & 0xff;
3495      int size = s->insn->data >> 8;
3496      uint64_t mask = ((1ull << size) - 1) << shift;
3497      TCGv_i64 t = tcg_temp_new_i64();
3498  
3499      tcg_gen_shli_i64(t, o->in2, shift);
3500      tcg_gen_or_i64(o->out, o->in1, t);
3501  
3502      /* Produce the CC from only the bits manipulated.  */
3503      tcg_gen_andi_i64(cc_dst, o->out, mask);
3504      set_cc_nz_u64(s, cc_dst);
3505      return DISAS_NEXT;
3506  }
3507  
op_oi(DisasContext * s,DisasOps * o)3508  static DisasJumpType op_oi(DisasContext *s, DisasOps *o)
3509  {
3510      o->in1 = tcg_temp_new_i64();
3511  
3512      if (!s390_has_feat(S390_FEAT_INTERLOCKED_ACCESS_2)) {
3513          tcg_gen_qemu_ld_tl(o->in1, o->addr1, get_mem_index(s), s->insn->data);
3514      } else {
3515          /* Perform the atomic operation in memory. */
3516          tcg_gen_atomic_fetch_or_i64(o->in1, o->addr1, o->in2, get_mem_index(s),
3517                                      s->insn->data);
3518      }
3519  
3520      /* Recompute also for atomic case: needed for setting CC. */
3521      tcg_gen_or_i64(o->out, o->in1, o->in2);
3522  
3523      if (!s390_has_feat(S390_FEAT_INTERLOCKED_ACCESS_2)) {
3524          tcg_gen_qemu_st_tl(o->out, o->addr1, get_mem_index(s), s->insn->data);
3525      }
3526      return DISAS_NEXT;
3527  }
3528  
op_pack(DisasContext * s,DisasOps * o)3529  static DisasJumpType op_pack(DisasContext *s, DisasOps *o)
3530  {
3531      TCGv_i32 l = tcg_constant_i32(get_field(s, l1));
3532  
3533      gen_helper_pack(tcg_env, l, o->addr1, o->in2);
3534      return DISAS_NEXT;
3535  }
3536  
op_pka(DisasContext * s,DisasOps * o)3537  static DisasJumpType op_pka(DisasContext *s, DisasOps *o)
3538  {
3539      int l2 = get_field(s, l2) + 1;
3540      TCGv_i32 l;
3541  
3542      /* The length must not exceed 32 bytes.  */
3543      if (l2 > 32) {
3544          gen_program_exception(s, PGM_SPECIFICATION);
3545          return DISAS_NORETURN;
3546      }
3547      l = tcg_constant_i32(l2);
3548      gen_helper_pka(tcg_env, o->addr1, o->in2, l);
3549      return DISAS_NEXT;
3550  }
3551  
op_pku(DisasContext * s,DisasOps * o)3552  static DisasJumpType op_pku(DisasContext *s, DisasOps *o)
3553  {
3554      int l2 = get_field(s, l2) + 1;
3555      TCGv_i32 l;
3556  
3557      /* The length must be even and should not exceed 64 bytes.  */
3558      if ((l2 & 1) || (l2 > 64)) {
3559          gen_program_exception(s, PGM_SPECIFICATION);
3560          return DISAS_NORETURN;
3561      }
3562      l = tcg_constant_i32(l2);
3563      gen_helper_pku(tcg_env, o->addr1, o->in2, l);
3564      return DISAS_NEXT;
3565  }
3566  
op_popcnt(DisasContext * s,DisasOps * o)3567  static DisasJumpType op_popcnt(DisasContext *s, DisasOps *o)
3568  {
3569      const uint8_t m3 = get_field(s, m3);
3570  
3571      if ((m3 & 8) && s390_has_feat(S390_FEAT_MISC_INSTRUCTION_EXT3)) {
3572          tcg_gen_ctpop_i64(o->out, o->in2);
3573      } else {
3574          gen_helper_popcnt(o->out, o->in2);
3575      }
3576      return DISAS_NEXT;
3577  }
3578  
3579  #ifndef CONFIG_USER_ONLY
op_ptlb(DisasContext * s,DisasOps * o)3580  static DisasJumpType op_ptlb(DisasContext *s, DisasOps *o)
3581  {
3582      gen_helper_ptlb(tcg_env);
3583      return DISAS_NEXT;
3584  }
3585  #endif
3586  
op_risbg(DisasContext * s,DisasOps * o)3587  static DisasJumpType op_risbg(DisasContext *s, DisasOps *o)
3588  {
3589      int i3 = get_field(s, i3);
3590      int i4 = get_field(s, i4);
3591      int i5 = get_field(s, i5);
3592      int do_zero = i4 & 0x80;
3593      uint64_t mask, imask, pmask;
3594      int pos, len, rot;
3595  
3596      /* Adjust the arguments for the specific insn.  */
3597      switch (s->fields.op2) {
3598      case 0x55: /* risbg */
3599      case 0x59: /* risbgn */
3600          i3 &= 63;
3601          i4 &= 63;
3602          pmask = ~0;
3603          break;
3604      case 0x5d: /* risbhg */
3605          i3 &= 31;
3606          i4 &= 31;
3607          pmask = 0xffffffff00000000ull;
3608          break;
3609      case 0x51: /* risblg */
3610          i3 = (i3 & 31) + 32;
3611          i4 = (i4 & 31) + 32;
3612          pmask = 0x00000000ffffffffull;
3613          break;
3614      default:
3615          g_assert_not_reached();
3616      }
3617  
3618      /* MASK is the set of bits to be inserted from R2. */
3619      if (i3 <= i4) {
3620          /* [0...i3---i4...63] */
3621          mask = (-1ull >> i3) & (-1ull << (63 - i4));
3622      } else {
3623          /* [0---i4...i3---63] */
3624          mask = (-1ull >> i3) | (-1ull << (63 - i4));
3625      }
3626      /* For RISBLG/RISBHG, the wrapping is limited to the high/low doubleword. */
3627      mask &= pmask;
3628  
3629      /* IMASK is the set of bits to be kept from R1.  In the case of the high/low
3630         insns, we need to keep the other half of the register.  */
3631      imask = ~mask | ~pmask;
3632      if (do_zero) {
3633          imask = ~pmask;
3634      }
3635  
3636      len = i4 - i3 + 1;
3637      pos = 63 - i4;
3638      rot = i5 & 63;
3639  
3640      /* In some cases we can implement this with extract.  */
3641      if (imask == 0 && pos == 0 && len > 0 && len <= rot) {
3642          tcg_gen_extract_i64(o->out, o->in2, 64 - rot, len);
3643          return DISAS_NEXT;
3644      }
3645  
3646      /* In some cases we can implement this with deposit.  */
3647      if (len > 0 && (imask == 0 || ~mask == imask)) {
3648          /* Note that we rotate the bits to be inserted to the lsb, not to
3649             the position as described in the PoO.  */
3650          rot = (rot - pos) & 63;
3651      } else {
3652          pos = -1;
3653      }
3654  
3655      /* Rotate the input as necessary.  */
3656      tcg_gen_rotli_i64(o->in2, o->in2, rot);
3657  
3658      /* Insert the selected bits into the output.  */
3659      if (pos >= 0) {
3660          if (imask == 0) {
3661              tcg_gen_deposit_z_i64(o->out, o->in2, pos, len);
3662          } else {
3663              tcg_gen_deposit_i64(o->out, o->out, o->in2, pos, len);
3664          }
3665      } else if (imask == 0) {
3666          tcg_gen_andi_i64(o->out, o->in2, mask);
3667      } else {
3668          tcg_gen_andi_i64(o->in2, o->in2, mask);
3669          tcg_gen_andi_i64(o->out, o->out, imask);
3670          tcg_gen_or_i64(o->out, o->out, o->in2);
3671      }
3672      return DISAS_NEXT;
3673  }
3674  
op_rosbg(DisasContext * s,DisasOps * o)3675  static DisasJumpType op_rosbg(DisasContext *s, DisasOps *o)
3676  {
3677      int i3 = get_field(s, i3);
3678      int i4 = get_field(s, i4);
3679      int i5 = get_field(s, i5);
3680      TCGv_i64 orig_out;
3681      uint64_t mask;
3682  
3683      /* If this is a test-only form, arrange to discard the result.  */
3684      if (i3 & 0x80) {
3685          tcg_debug_assert(o->out != NULL);
3686          orig_out = o->out;
3687          o->out = tcg_temp_new_i64();
3688          tcg_gen_mov_i64(o->out, orig_out);
3689      }
3690  
3691      i3 &= 63;
3692      i4 &= 63;
3693      i5 &= 63;
3694  
3695      /* MASK is the set of bits to be operated on from R2.
3696         Take care for I3/I4 wraparound.  */
3697      mask = ~0ull >> i3;
3698      if (i3 <= i4) {
3699          mask ^= ~0ull >> i4 >> 1;
3700      } else {
3701          mask |= ~(~0ull >> i4 >> 1);
3702      }
3703  
3704      /* Rotate the input as necessary.  */
3705      tcg_gen_rotli_i64(o->in2, o->in2, i5);
3706  
3707      /* Operate.  */
3708      switch (s->fields.op2) {
3709      case 0x54: /* AND */
3710          tcg_gen_ori_i64(o->in2, o->in2, ~mask);
3711          tcg_gen_and_i64(o->out, o->out, o->in2);
3712          break;
3713      case 0x56: /* OR */
3714          tcg_gen_andi_i64(o->in2, o->in2, mask);
3715          tcg_gen_or_i64(o->out, o->out, o->in2);
3716          break;
3717      case 0x57: /* XOR */
3718          tcg_gen_andi_i64(o->in2, o->in2, mask);
3719          tcg_gen_xor_i64(o->out, o->out, o->in2);
3720          break;
3721      default:
3722          abort();
3723      }
3724  
3725      /* Set the CC.  */
3726      tcg_gen_andi_i64(cc_dst, o->out, mask);
3727      set_cc_nz_u64(s, cc_dst);
3728      return DISAS_NEXT;
3729  }
3730  
op_rev16(DisasContext * s,DisasOps * o)3731  static DisasJumpType op_rev16(DisasContext *s, DisasOps *o)
3732  {
3733      tcg_gen_bswap16_i64(o->out, o->in2, TCG_BSWAP_IZ | TCG_BSWAP_OZ);
3734      return DISAS_NEXT;
3735  }
3736  
op_rev32(DisasContext * s,DisasOps * o)3737  static DisasJumpType op_rev32(DisasContext *s, DisasOps *o)
3738  {
3739      tcg_gen_bswap32_i64(o->out, o->in2, TCG_BSWAP_IZ | TCG_BSWAP_OZ);
3740      return DISAS_NEXT;
3741  }
3742  
op_rev64(DisasContext * s,DisasOps * o)3743  static DisasJumpType op_rev64(DisasContext *s, DisasOps *o)
3744  {
3745      tcg_gen_bswap64_i64(o->out, o->in2);
3746      return DISAS_NEXT;
3747  }
3748  
op_rll32(DisasContext * s,DisasOps * o)3749  static DisasJumpType op_rll32(DisasContext *s, DisasOps *o)
3750  {
3751      TCGv_i32 t1 = tcg_temp_new_i32();
3752      TCGv_i32 t2 = tcg_temp_new_i32();
3753      TCGv_i32 to = tcg_temp_new_i32();
3754      tcg_gen_extrl_i64_i32(t1, o->in1);
3755      tcg_gen_extrl_i64_i32(t2, o->in2);
3756      tcg_gen_rotl_i32(to, t1, t2);
3757      tcg_gen_extu_i32_i64(o->out, to);
3758      return DISAS_NEXT;
3759  }
3760  
op_rll64(DisasContext * s,DisasOps * o)3761  static DisasJumpType op_rll64(DisasContext *s, DisasOps *o)
3762  {
3763      tcg_gen_rotl_i64(o->out, o->in1, o->in2);
3764      return DISAS_NEXT;
3765  }
3766  
3767  #ifndef CONFIG_USER_ONLY
op_rrbe(DisasContext * s,DisasOps * o)3768  static DisasJumpType op_rrbe(DisasContext *s, DisasOps *o)
3769  {
3770      gen_helper_rrbe(cc_op, tcg_env, o->in2);
3771      set_cc_static(s);
3772      return DISAS_NEXT;
3773  }
3774  
op_sacf(DisasContext * s,DisasOps * o)3775  static DisasJumpType op_sacf(DisasContext *s, DisasOps *o)
3776  {
3777      gen_helper_sacf(tcg_env, o->in2);
3778      /* Addressing mode has changed, so end the block.  */
3779      return DISAS_TOO_MANY;
3780  }
3781  #endif
3782  
op_sam(DisasContext * s,DisasOps * o)3783  static DisasJumpType op_sam(DisasContext *s, DisasOps *o)
3784  {
3785      int sam = s->insn->data;
3786      TCGv_i64 tsam;
3787      uint64_t mask;
3788  
3789      switch (sam) {
3790      case 0:
3791          mask = 0xffffff;
3792          break;
3793      case 1:
3794          mask = 0x7fffffff;
3795          break;
3796      default:
3797          mask = -1;
3798          break;
3799      }
3800  
3801      /* Bizarre but true, we check the address of the current insn for the
3802         specification exception, not the next to be executed.  Thus the PoO
3803         documents that Bad Things Happen two bytes before the end.  */
3804      if (s->base.pc_next & ~mask) {
3805          gen_program_exception(s, PGM_SPECIFICATION);
3806          return DISAS_NORETURN;
3807      }
3808      s->pc_tmp &= mask;
3809  
3810      tsam = tcg_constant_i64(sam);
3811      tcg_gen_deposit_i64(psw_mask, psw_mask, tsam, 31, 2);
3812  
3813      /* Always exit the TB, since we (may have) changed execution mode.  */
3814      return DISAS_TOO_MANY;
3815  }
3816  
op_sar(DisasContext * s,DisasOps * o)3817  static DisasJumpType op_sar(DisasContext *s, DisasOps *o)
3818  {
3819      int r1 = get_field(s, r1);
3820      tcg_gen_st32_i64(o->in2, tcg_env, offsetof(CPUS390XState, aregs[r1]));
3821      return DISAS_NEXT;
3822  }
3823  
op_seb(DisasContext * s,DisasOps * o)3824  static DisasJumpType op_seb(DisasContext *s, DisasOps *o)
3825  {
3826      gen_helper_seb(o->out, tcg_env, o->in1, o->in2);
3827      return DISAS_NEXT;
3828  }
3829  
op_sdb(DisasContext * s,DisasOps * o)3830  static DisasJumpType op_sdb(DisasContext *s, DisasOps *o)
3831  {
3832      gen_helper_sdb(o->out, tcg_env, o->in1, o->in2);
3833      return DISAS_NEXT;
3834  }
3835  
op_sxb(DisasContext * s,DisasOps * o)3836  static DisasJumpType op_sxb(DisasContext *s, DisasOps *o)
3837  {
3838      gen_helper_sxb(o->out_128, tcg_env, o->in1_128, o->in2_128);
3839      return DISAS_NEXT;
3840  }
3841  
op_sqeb(DisasContext * s,DisasOps * o)3842  static DisasJumpType op_sqeb(DisasContext *s, DisasOps *o)
3843  {
3844      gen_helper_sqeb(o->out, tcg_env, o->in2);
3845      return DISAS_NEXT;
3846  }
3847  
op_sqdb(DisasContext * s,DisasOps * o)3848  static DisasJumpType op_sqdb(DisasContext *s, DisasOps *o)
3849  {
3850      gen_helper_sqdb(o->out, tcg_env, o->in2);
3851      return DISAS_NEXT;
3852  }
3853  
op_sqxb(DisasContext * s,DisasOps * o)3854  static DisasJumpType op_sqxb(DisasContext *s, DisasOps *o)
3855  {
3856      gen_helper_sqxb(o->out_128, tcg_env, o->in2_128);
3857      return DISAS_NEXT;
3858  }
3859  
3860  #ifndef CONFIG_USER_ONLY
op_servc(DisasContext * s,DisasOps * o)3861  static DisasJumpType op_servc(DisasContext *s, DisasOps *o)
3862  {
3863      gen_helper_servc(cc_op, tcg_env, o->in2, o->in1);
3864      set_cc_static(s);
3865      return DISAS_NEXT;
3866  }
3867  
op_sigp(DisasContext * s,DisasOps * o)3868  static DisasJumpType op_sigp(DisasContext *s, DisasOps *o)
3869  {
3870      TCGv_i32 r1 = tcg_constant_i32(get_field(s, r1));
3871      TCGv_i32 r3 = tcg_constant_i32(get_field(s, r3));
3872  
3873      gen_helper_sigp(cc_op, tcg_env, o->in2, r1, r3);
3874      set_cc_static(s);
3875      return DISAS_NEXT;
3876  }
3877  #endif
3878  
op_soc(DisasContext * s,DisasOps * o)3879  static DisasJumpType op_soc(DisasContext *s, DisasOps *o)
3880  {
3881      DisasCompare c;
3882      TCGv_i64 a, h;
3883      TCGLabel *lab;
3884      int r1;
3885  
3886      disas_jcc(s, &c, get_field(s, m3));
3887  
3888      /* We want to store when the condition is fulfilled, so branch
3889         out when it's not */
3890      c.cond = tcg_invert_cond(c.cond);
3891  
3892      lab = gen_new_label();
3893      if (c.is_64) {
3894          tcg_gen_brcond_i64(c.cond, c.u.s64.a, c.u.s64.b, lab);
3895      } else {
3896          tcg_gen_brcond_i32(c.cond, c.u.s32.a, c.u.s32.b, lab);
3897      }
3898  
3899      r1 = get_field(s, r1);
3900      a = get_address(s, 0, get_field(s, b2), get_field(s, d2));
3901      switch (s->insn->data) {
3902      case 1: /* STOCG */
3903          tcg_gen_qemu_st_i64(regs[r1], a, get_mem_index(s), MO_TEUQ);
3904          break;
3905      case 0: /* STOC */
3906          tcg_gen_qemu_st_i64(regs[r1], a, get_mem_index(s), MO_TEUL);
3907          break;
3908      case 2: /* STOCFH */
3909          h = tcg_temp_new_i64();
3910          tcg_gen_shri_i64(h, regs[r1], 32);
3911          tcg_gen_qemu_st_i64(h, a, get_mem_index(s), MO_TEUL);
3912          break;
3913      default:
3914          g_assert_not_reached();
3915      }
3916  
3917      gen_set_label(lab);
3918      return DISAS_NEXT;
3919  }
3920  
op_sla(DisasContext * s,DisasOps * o)3921  static DisasJumpType op_sla(DisasContext *s, DisasOps *o)
3922  {
3923      TCGv_i64 t;
3924      uint64_t sign = 1ull << s->insn->data;
3925      if (s->insn->data == 31) {
3926          t = tcg_temp_new_i64();
3927          tcg_gen_shli_i64(t, o->in1, 32);
3928      } else {
3929          t = o->in1;
3930      }
3931      gen_op_update2_cc_i64(s, CC_OP_SLA, t, o->in2);
3932      tcg_gen_shl_i64(o->out, o->in1, o->in2);
3933      /* The arithmetic left shift is curious in that it does not affect
3934         the sign bit.  Copy that over from the source unchanged.  */
3935      tcg_gen_andi_i64(o->out, o->out, ~sign);
3936      tcg_gen_andi_i64(o->in1, o->in1, sign);
3937      tcg_gen_or_i64(o->out, o->out, o->in1);
3938      return DISAS_NEXT;
3939  }
3940  
op_sll(DisasContext * s,DisasOps * o)3941  static DisasJumpType op_sll(DisasContext *s, DisasOps *o)
3942  {
3943      tcg_gen_shl_i64(o->out, o->in1, o->in2);
3944      return DISAS_NEXT;
3945  }
3946  
op_sra(DisasContext * s,DisasOps * o)3947  static DisasJumpType op_sra(DisasContext *s, DisasOps *o)
3948  {
3949      tcg_gen_sar_i64(o->out, o->in1, o->in2);
3950      return DISAS_NEXT;
3951  }
3952  
op_srl(DisasContext * s,DisasOps * o)3953  static DisasJumpType op_srl(DisasContext *s, DisasOps *o)
3954  {
3955      tcg_gen_shr_i64(o->out, o->in1, o->in2);
3956      return DISAS_NEXT;
3957  }
3958  
op_sfpc(DisasContext * s,DisasOps * o)3959  static DisasJumpType op_sfpc(DisasContext *s, DisasOps *o)
3960  {
3961      gen_helper_sfpc(tcg_env, o->in2);
3962      return DISAS_NEXT;
3963  }
3964  
op_sfas(DisasContext * s,DisasOps * o)3965  static DisasJumpType op_sfas(DisasContext *s, DisasOps *o)
3966  {
3967      gen_helper_sfas(tcg_env, o->in2);
3968      return DISAS_NEXT;
3969  }
3970  
op_srnm(DisasContext * s,DisasOps * o)3971  static DisasJumpType op_srnm(DisasContext *s, DisasOps *o)
3972  {
3973      /* Bits other than 62 and 63 are ignored. Bit 29 is set to zero. */
3974      tcg_gen_andi_i64(o->addr1, o->addr1, 0x3ull);
3975      gen_helper_srnm(tcg_env, o->addr1);
3976      return DISAS_NEXT;
3977  }
3978  
op_srnmb(DisasContext * s,DisasOps * o)3979  static DisasJumpType op_srnmb(DisasContext *s, DisasOps *o)
3980  {
3981      /* Bits 0-55 are are ignored. */
3982      tcg_gen_andi_i64(o->addr1, o->addr1, 0xffull);
3983      gen_helper_srnm(tcg_env, o->addr1);
3984      return DISAS_NEXT;
3985  }
3986  
op_srnmt(DisasContext * s,DisasOps * o)3987  static DisasJumpType op_srnmt(DisasContext *s, DisasOps *o)
3988  {
3989      TCGv_i64 tmp = tcg_temp_new_i64();
3990  
3991      /* Bits other than 61-63 are ignored. */
3992      tcg_gen_andi_i64(o->addr1, o->addr1, 0x7ull);
3993  
3994      /* No need to call a helper, we don't implement dfp */
3995      tcg_gen_ld32u_i64(tmp, tcg_env, offsetof(CPUS390XState, fpc));
3996      tcg_gen_deposit_i64(tmp, tmp, o->addr1, 4, 3);
3997      tcg_gen_st32_i64(tmp, tcg_env, offsetof(CPUS390XState, fpc));
3998      return DISAS_NEXT;
3999  }
4000  
op_spm(DisasContext * s,DisasOps * o)4001  static DisasJumpType op_spm(DisasContext *s, DisasOps *o)
4002  {
4003      tcg_gen_extrl_i64_i32(cc_op, o->in1);
4004      tcg_gen_extract_i32(cc_op, cc_op, 28, 2);
4005      set_cc_static(s);
4006  
4007      tcg_gen_shri_i64(o->in1, o->in1, 24);
4008      tcg_gen_deposit_i64(psw_mask, psw_mask, o->in1, PSW_SHIFT_MASK_PM, 4);
4009      return DISAS_NEXT;
4010  }
4011  
op_ectg(DisasContext * s,DisasOps * o)4012  static DisasJumpType op_ectg(DisasContext *s, DisasOps *o)
4013  {
4014      int b1 = get_field(s, b1);
4015      int d1 = get_field(s, d1);
4016      int b2 = get_field(s, b2);
4017      int d2 = get_field(s, d2);
4018      int r3 = get_field(s, r3);
4019      TCGv_i64 tmp = tcg_temp_new_i64();
4020  
4021      /* fetch all operands first */
4022      o->in1 = tcg_temp_new_i64();
4023      tcg_gen_addi_i64(o->in1, regs[b1], d1);
4024      o->in2 = tcg_temp_new_i64();
4025      tcg_gen_addi_i64(o->in2, regs[b2], d2);
4026      o->addr1 = tcg_temp_new_i64();
4027      gen_addi_and_wrap_i64(s, o->addr1, regs[r3], 0);
4028  
4029      /* load the third operand into r3 before modifying anything */
4030      tcg_gen_qemu_ld_i64(regs[r3], o->addr1, get_mem_index(s), MO_TEUQ);
4031  
4032      /* subtract CPU timer from first operand and store in GR0 */
4033      gen_helper_stpt(tmp, tcg_env);
4034      tcg_gen_sub_i64(regs[0], o->in1, tmp);
4035  
4036      /* store second operand in GR1 */
4037      tcg_gen_mov_i64(regs[1], o->in2);
4038      return DISAS_NEXT;
4039  }
4040  
4041  #ifndef CONFIG_USER_ONLY
op_spka(DisasContext * s,DisasOps * o)4042  static DisasJumpType op_spka(DisasContext *s, DisasOps *o)
4043  {
4044      tcg_gen_shri_i64(o->in2, o->in2, 4);
4045      tcg_gen_deposit_i64(psw_mask, psw_mask, o->in2, PSW_SHIFT_KEY, 4);
4046      return DISAS_NEXT;
4047  }
4048  
op_sske(DisasContext * s,DisasOps * o)4049  static DisasJumpType op_sske(DisasContext *s, DisasOps *o)
4050  {
4051      gen_helper_sske(tcg_env, o->in1, o->in2);
4052      return DISAS_NEXT;
4053  }
4054  
gen_check_psw_mask(DisasContext * s)4055  static void gen_check_psw_mask(DisasContext *s)
4056  {
4057      TCGv_i64 reserved = tcg_temp_new_i64();
4058      TCGLabel *ok = gen_new_label();
4059  
4060      tcg_gen_andi_i64(reserved, psw_mask, PSW_MASK_RESERVED);
4061      tcg_gen_brcondi_i64(TCG_COND_EQ, reserved, 0, ok);
4062      gen_program_exception(s, PGM_SPECIFICATION);
4063      gen_set_label(ok);
4064  }
4065  
op_ssm(DisasContext * s,DisasOps * o)4066  static DisasJumpType op_ssm(DisasContext *s, DisasOps *o)
4067  {
4068      tcg_gen_deposit_i64(psw_mask, psw_mask, o->in2, 56, 8);
4069  
4070      gen_check_psw_mask(s);
4071  
4072      /* Exit to main loop to reevaluate s390_cpu_exec_interrupt.  */
4073      s->exit_to_mainloop = true;
4074      return DISAS_TOO_MANY;
4075  }
4076  
op_stap(DisasContext * s,DisasOps * o)4077  static DisasJumpType op_stap(DisasContext *s, DisasOps *o)
4078  {
4079      tcg_gen_ld32u_i64(o->out, tcg_env, offsetof(CPUS390XState, core_id));
4080      return DISAS_NEXT;
4081  }
4082  #endif
4083  
op_stck(DisasContext * s,DisasOps * o)4084  static DisasJumpType op_stck(DisasContext *s, DisasOps *o)
4085  {
4086      gen_helper_stck(o->out, tcg_env);
4087      /* ??? We don't implement clock states.  */
4088      gen_op_movi_cc(s, 0);
4089      return DISAS_NEXT;
4090  }
4091  
op_stcke(DisasContext * s,DisasOps * o)4092  static DisasJumpType op_stcke(DisasContext *s, DisasOps *o)
4093  {
4094      TCGv_i64 c1 = tcg_temp_new_i64();
4095      TCGv_i64 c2 = tcg_temp_new_i64();
4096      TCGv_i64 todpr = tcg_temp_new_i64();
4097      gen_helper_stck(c1, tcg_env);
4098      /* 16 bit value store in an uint32_t (only valid bits set) */
4099      tcg_gen_ld32u_i64(todpr, tcg_env, offsetof(CPUS390XState, todpr));
4100      /* Shift the 64-bit value into its place as a zero-extended
4101         104-bit value.  Note that "bit positions 64-103 are always
4102         non-zero so that they compare differently to STCK"; we set
4103         the least significant bit to 1.  */
4104      tcg_gen_shli_i64(c2, c1, 56);
4105      tcg_gen_shri_i64(c1, c1, 8);
4106      tcg_gen_ori_i64(c2, c2, 0x10000);
4107      tcg_gen_or_i64(c2, c2, todpr);
4108      tcg_gen_qemu_st_i64(c1, o->in2, get_mem_index(s), MO_TEUQ);
4109      tcg_gen_addi_i64(o->in2, o->in2, 8);
4110      tcg_gen_qemu_st_i64(c2, o->in2, get_mem_index(s), MO_TEUQ);
4111      /* ??? We don't implement clock states.  */
4112      gen_op_movi_cc(s, 0);
4113      return DISAS_NEXT;
4114  }
4115  
4116  #ifndef CONFIG_USER_ONLY
op_sck(DisasContext * s,DisasOps * o)4117  static DisasJumpType op_sck(DisasContext *s, DisasOps *o)
4118  {
4119      gen_helper_sck(cc_op, tcg_env, o->in2);
4120      set_cc_static(s);
4121      return DISAS_NEXT;
4122  }
4123  
op_sckc(DisasContext * s,DisasOps * o)4124  static DisasJumpType op_sckc(DisasContext *s, DisasOps *o)
4125  {
4126      gen_helper_sckc(tcg_env, o->in2);
4127      return DISAS_NEXT;
4128  }
4129  
op_sckpf(DisasContext * s,DisasOps * o)4130  static DisasJumpType op_sckpf(DisasContext *s, DisasOps *o)
4131  {
4132      gen_helper_sckpf(tcg_env, regs[0]);
4133      return DISAS_NEXT;
4134  }
4135  
op_stckc(DisasContext * s,DisasOps * o)4136  static DisasJumpType op_stckc(DisasContext *s, DisasOps *o)
4137  {
4138      gen_helper_stckc(o->out, tcg_env);
4139      return DISAS_NEXT;
4140  }
4141  
op_stctg(DisasContext * s,DisasOps * o)4142  static DisasJumpType op_stctg(DisasContext *s, DisasOps *o)
4143  {
4144      TCGv_i32 r1 = tcg_constant_i32(get_field(s, r1));
4145      TCGv_i32 r3 = tcg_constant_i32(get_field(s, r3));
4146  
4147      gen_helper_stctg(tcg_env, r1, o->in2, r3);
4148      return DISAS_NEXT;
4149  }
4150  
op_stctl(DisasContext * s,DisasOps * o)4151  static DisasJumpType op_stctl(DisasContext *s, DisasOps *o)
4152  {
4153      TCGv_i32 r1 = tcg_constant_i32(get_field(s, r1));
4154      TCGv_i32 r3 = tcg_constant_i32(get_field(s, r3));
4155  
4156      gen_helper_stctl(tcg_env, r1, o->in2, r3);
4157      return DISAS_NEXT;
4158  }
4159  
op_stidp(DisasContext * s,DisasOps * o)4160  static DisasJumpType op_stidp(DisasContext *s, DisasOps *o)
4161  {
4162      tcg_gen_ld_i64(o->out, tcg_env, offsetof(CPUS390XState, cpuid));
4163      return DISAS_NEXT;
4164  }
4165  
op_spt(DisasContext * s,DisasOps * o)4166  static DisasJumpType op_spt(DisasContext *s, DisasOps *o)
4167  {
4168      gen_helper_spt(tcg_env, o->in2);
4169      return DISAS_NEXT;
4170  }
4171  
op_stfl(DisasContext * s,DisasOps * o)4172  static DisasJumpType op_stfl(DisasContext *s, DisasOps *o)
4173  {
4174      gen_helper_stfl(tcg_env);
4175      return DISAS_NEXT;
4176  }
4177  
op_stpt(DisasContext * s,DisasOps * o)4178  static DisasJumpType op_stpt(DisasContext *s, DisasOps *o)
4179  {
4180      gen_helper_stpt(o->out, tcg_env);
4181      return DISAS_NEXT;
4182  }
4183  
op_stsi(DisasContext * s,DisasOps * o)4184  static DisasJumpType op_stsi(DisasContext *s, DisasOps *o)
4185  {
4186      gen_helper_stsi(cc_op, tcg_env, o->in2, regs[0], regs[1]);
4187      set_cc_static(s);
4188      return DISAS_NEXT;
4189  }
4190  
op_spx(DisasContext * s,DisasOps * o)4191  static DisasJumpType op_spx(DisasContext *s, DisasOps *o)
4192  {
4193      gen_helper_spx(tcg_env, o->in2);
4194      return DISAS_NEXT;
4195  }
4196  
op_xsch(DisasContext * s,DisasOps * o)4197  static DisasJumpType op_xsch(DisasContext *s, DisasOps *o)
4198  {
4199      gen_helper_xsch(tcg_env, regs[1]);
4200      set_cc_static(s);
4201      return DISAS_NEXT;
4202  }
4203  
op_csch(DisasContext * s,DisasOps * o)4204  static DisasJumpType op_csch(DisasContext *s, DisasOps *o)
4205  {
4206      gen_helper_csch(tcg_env, regs[1]);
4207      set_cc_static(s);
4208      return DISAS_NEXT;
4209  }
4210  
op_hsch(DisasContext * s,DisasOps * o)4211  static DisasJumpType op_hsch(DisasContext *s, DisasOps *o)
4212  {
4213      gen_helper_hsch(tcg_env, regs[1]);
4214      set_cc_static(s);
4215      return DISAS_NEXT;
4216  }
4217  
op_msch(DisasContext * s,DisasOps * o)4218  static DisasJumpType op_msch(DisasContext *s, DisasOps *o)
4219  {
4220      gen_helper_msch(tcg_env, regs[1], o->in2);
4221      set_cc_static(s);
4222      return DISAS_NEXT;
4223  }
4224  
op_rchp(DisasContext * s,DisasOps * o)4225  static DisasJumpType op_rchp(DisasContext *s, DisasOps *o)
4226  {
4227      gen_helper_rchp(tcg_env, regs[1]);
4228      set_cc_static(s);
4229      return DISAS_NEXT;
4230  }
4231  
op_rsch(DisasContext * s,DisasOps * o)4232  static DisasJumpType op_rsch(DisasContext *s, DisasOps *o)
4233  {
4234      gen_helper_rsch(tcg_env, regs[1]);
4235      set_cc_static(s);
4236      return DISAS_NEXT;
4237  }
4238  
op_sal(DisasContext * s,DisasOps * o)4239  static DisasJumpType op_sal(DisasContext *s, DisasOps *o)
4240  {
4241      gen_helper_sal(tcg_env, regs[1]);
4242      return DISAS_NEXT;
4243  }
4244  
op_schm(DisasContext * s,DisasOps * o)4245  static DisasJumpType op_schm(DisasContext *s, DisasOps *o)
4246  {
4247      gen_helper_schm(tcg_env, regs[1], regs[2], o->in2);
4248      return DISAS_NEXT;
4249  }
4250  
op_siga(DisasContext * s,DisasOps * o)4251  static DisasJumpType op_siga(DisasContext *s, DisasOps *o)
4252  {
4253      /* From KVM code: Not provided, set CC = 3 for subchannel not operational */
4254      gen_op_movi_cc(s, 3);
4255      return DISAS_NEXT;
4256  }
4257  
op_stcps(DisasContext * s,DisasOps * o)4258  static DisasJumpType op_stcps(DisasContext *s, DisasOps *o)
4259  {
4260      /* The instruction is suppressed if not provided. */
4261      return DISAS_NEXT;
4262  }
4263  
op_ssch(DisasContext * s,DisasOps * o)4264  static DisasJumpType op_ssch(DisasContext *s, DisasOps *o)
4265  {
4266      gen_helper_ssch(tcg_env, regs[1], o->in2);
4267      set_cc_static(s);
4268      return DISAS_NEXT;
4269  }
4270  
op_stsch(DisasContext * s,DisasOps * o)4271  static DisasJumpType op_stsch(DisasContext *s, DisasOps *o)
4272  {
4273      gen_helper_stsch(tcg_env, regs[1], o->in2);
4274      set_cc_static(s);
4275      return DISAS_NEXT;
4276  }
4277  
op_stcrw(DisasContext * s,DisasOps * o)4278  static DisasJumpType op_stcrw(DisasContext *s, DisasOps *o)
4279  {
4280      gen_helper_stcrw(tcg_env, o->in2);
4281      set_cc_static(s);
4282      return DISAS_NEXT;
4283  }
4284  
op_tpi(DisasContext * s,DisasOps * o)4285  static DisasJumpType op_tpi(DisasContext *s, DisasOps *o)
4286  {
4287      gen_helper_tpi(cc_op, tcg_env, o->addr1);
4288      set_cc_static(s);
4289      return DISAS_NEXT;
4290  }
4291  
op_tsch(DisasContext * s,DisasOps * o)4292  static DisasJumpType op_tsch(DisasContext *s, DisasOps *o)
4293  {
4294      gen_helper_tsch(tcg_env, regs[1], o->in2);
4295      set_cc_static(s);
4296      return DISAS_NEXT;
4297  }
4298  
op_chsc(DisasContext * s,DisasOps * o)4299  static DisasJumpType op_chsc(DisasContext *s, DisasOps *o)
4300  {
4301      gen_helper_chsc(tcg_env, o->in2);
4302      set_cc_static(s);
4303      return DISAS_NEXT;
4304  }
4305  
op_stpx(DisasContext * s,DisasOps * o)4306  static DisasJumpType op_stpx(DisasContext *s, DisasOps *o)
4307  {
4308      tcg_gen_ld_i64(o->out, tcg_env, offsetof(CPUS390XState, psa));
4309      tcg_gen_andi_i64(o->out, o->out, 0x7fffe000);
4310      return DISAS_NEXT;
4311  }
4312  
op_stnosm(DisasContext * s,DisasOps * o)4313  static DisasJumpType op_stnosm(DisasContext *s, DisasOps *o)
4314  {
4315      uint64_t i2 = get_field(s, i2);
4316      TCGv_i64 t;
4317  
4318      /* It is important to do what the instruction name says: STORE THEN.
4319         If we let the output hook perform the store then if we fault and
4320         restart, we'll have the wrong SYSTEM MASK in place.  */
4321      t = tcg_temp_new_i64();
4322      tcg_gen_shri_i64(t, psw_mask, 56);
4323      tcg_gen_qemu_st_i64(t, o->addr1, get_mem_index(s), MO_UB);
4324  
4325      if (s->fields.op == 0xac) {
4326          tcg_gen_andi_i64(psw_mask, psw_mask,
4327                           (i2 << 56) | 0x00ffffffffffffffull);
4328      } else {
4329          tcg_gen_ori_i64(psw_mask, psw_mask, i2 << 56);
4330      }
4331  
4332      gen_check_psw_mask(s);
4333  
4334      /* Exit to main loop to reevaluate s390_cpu_exec_interrupt.  */
4335      s->exit_to_mainloop = true;
4336      return DISAS_TOO_MANY;
4337  }
4338  
op_stura(DisasContext * s,DisasOps * o)4339  static DisasJumpType op_stura(DisasContext *s, DisasOps *o)
4340  {
4341      tcg_gen_qemu_st_tl(o->in1, o->in2, MMU_REAL_IDX, s->insn->data);
4342  
4343      if (s->base.tb->flags & FLAG_MASK_PER_STORE_REAL) {
4344          update_cc_op(s);
4345          update_psw_addr(s);
4346          gen_helper_per_store_real(tcg_env, tcg_constant_i32(s->ilen));
4347          return DISAS_NORETURN;
4348      }
4349      return DISAS_NEXT;
4350  }
4351  #endif
4352  
op_stfle(DisasContext * s,DisasOps * o)4353  static DisasJumpType op_stfle(DisasContext *s, DisasOps *o)
4354  {
4355      gen_helper_stfle(cc_op, tcg_env, o->in2);
4356      set_cc_static(s);
4357      return DISAS_NEXT;
4358  }
4359  
op_st8(DisasContext * s,DisasOps * o)4360  static DisasJumpType op_st8(DisasContext *s, DisasOps *o)
4361  {
4362      tcg_gen_qemu_st_i64(o->in1, o->in2, get_mem_index(s), MO_UB);
4363      return DISAS_NEXT;
4364  }
4365  
op_st16(DisasContext * s,DisasOps * o)4366  static DisasJumpType op_st16(DisasContext *s, DisasOps *o)
4367  {
4368      tcg_gen_qemu_st_i64(o->in1, o->in2, get_mem_index(s), MO_TEUW);
4369      return DISAS_NEXT;
4370  }
4371  
op_st32(DisasContext * s,DisasOps * o)4372  static DisasJumpType op_st32(DisasContext *s, DisasOps *o)
4373  {
4374      tcg_gen_qemu_st_tl(o->in1, o->in2, get_mem_index(s),
4375                         MO_TEUL | s->insn->data);
4376      return DISAS_NEXT;
4377  }
4378  
op_st64(DisasContext * s,DisasOps * o)4379  static DisasJumpType op_st64(DisasContext *s, DisasOps *o)
4380  {
4381      tcg_gen_qemu_st_i64(o->in1, o->in2, get_mem_index(s),
4382                          MO_TEUQ | s->insn->data);
4383      return DISAS_NEXT;
4384  }
4385  
op_stam(DisasContext * s,DisasOps * o)4386  static DisasJumpType op_stam(DisasContext *s, DisasOps *o)
4387  {
4388      TCGv_i32 r1 = tcg_constant_i32(get_field(s, r1));
4389      TCGv_i32 r3 = tcg_constant_i32(get_field(s, r3));
4390  
4391      gen_helper_stam(tcg_env, r1, o->in2, r3);
4392      return DISAS_NEXT;
4393  }
4394  
op_stcm(DisasContext * s,DisasOps * o)4395  static DisasJumpType op_stcm(DisasContext *s, DisasOps *o)
4396  {
4397      int m3 = get_field(s, m3);
4398      int pos, base = s->insn->data;
4399      TCGv_i64 tmp = tcg_temp_new_i64();
4400  
4401      pos = base + ctz32(m3) * 8;
4402      switch (m3) {
4403      case 0xf:
4404          /* Effectively a 32-bit store.  */
4405          tcg_gen_shri_i64(tmp, o->in1, pos);
4406          tcg_gen_qemu_st_i64(tmp, o->in2, get_mem_index(s), MO_TEUL);
4407          break;
4408  
4409      case 0xc:
4410      case 0x6:
4411      case 0x3:
4412          /* Effectively a 16-bit store.  */
4413          tcg_gen_shri_i64(tmp, o->in1, pos);
4414          tcg_gen_qemu_st_i64(tmp, o->in2, get_mem_index(s), MO_TEUW);
4415          break;
4416  
4417      case 0x8:
4418      case 0x4:
4419      case 0x2:
4420      case 0x1:
4421          /* Effectively an 8-bit store.  */
4422          tcg_gen_shri_i64(tmp, o->in1, pos);
4423          tcg_gen_qemu_st_i64(tmp, o->in2, get_mem_index(s), MO_UB);
4424          break;
4425  
4426      default:
4427          /* This is going to be a sequence of shifts and stores.  */
4428          pos = base + 32 - 8;
4429          while (m3) {
4430              if (m3 & 0x8) {
4431                  tcg_gen_shri_i64(tmp, o->in1, pos);
4432                  tcg_gen_qemu_st_i64(tmp, o->in2, get_mem_index(s), MO_UB);
4433                  tcg_gen_addi_i64(o->in2, o->in2, 1);
4434              }
4435              m3 = (m3 << 1) & 0xf;
4436              pos -= 8;
4437          }
4438          break;
4439      }
4440      return DISAS_NEXT;
4441  }
4442  
op_stm(DisasContext * s,DisasOps * o)4443  static DisasJumpType op_stm(DisasContext *s, DisasOps *o)
4444  {
4445      int r1 = get_field(s, r1);
4446      int r3 = get_field(s, r3);
4447      int size = s->insn->data;
4448      TCGv_i64 tsize = tcg_constant_i64(size);
4449  
4450      while (1) {
4451          tcg_gen_qemu_st_i64(regs[r1], o->in2, get_mem_index(s),
4452                              size == 8 ? MO_TEUQ : MO_TEUL);
4453          if (r1 == r3) {
4454              break;
4455          }
4456          tcg_gen_add_i64(o->in2, o->in2, tsize);
4457          r1 = (r1 + 1) & 15;
4458      }
4459  
4460      return DISAS_NEXT;
4461  }
4462  
op_stmh(DisasContext * s,DisasOps * o)4463  static DisasJumpType op_stmh(DisasContext *s, DisasOps *o)
4464  {
4465      int r1 = get_field(s, r1);
4466      int r3 = get_field(s, r3);
4467      TCGv_i64 t = tcg_temp_new_i64();
4468      TCGv_i64 t4 = tcg_constant_i64(4);
4469      TCGv_i64 t32 = tcg_constant_i64(32);
4470  
4471      while (1) {
4472          tcg_gen_shl_i64(t, regs[r1], t32);
4473          tcg_gen_qemu_st_i64(t, o->in2, get_mem_index(s), MO_TEUL);
4474          if (r1 == r3) {
4475              break;
4476          }
4477          tcg_gen_add_i64(o->in2, o->in2, t4);
4478          r1 = (r1 + 1) & 15;
4479      }
4480      return DISAS_NEXT;
4481  }
4482  
op_stpq(DisasContext * s,DisasOps * o)4483  static DisasJumpType op_stpq(DisasContext *s, DisasOps *o)
4484  {
4485      TCGv_i128 t16 = tcg_temp_new_i128();
4486  
4487      tcg_gen_concat_i64_i128(t16, o->out2, o->out);
4488      tcg_gen_qemu_st_i128(t16, o->in2, get_mem_index(s),
4489                           MO_TE | MO_128 | MO_ALIGN);
4490      return DISAS_NEXT;
4491  }
4492  
op_srst(DisasContext * s,DisasOps * o)4493  static DisasJumpType op_srst(DisasContext *s, DisasOps *o)
4494  {
4495      TCGv_i32 r1 = tcg_constant_i32(get_field(s, r1));
4496      TCGv_i32 r2 = tcg_constant_i32(get_field(s, r2));
4497  
4498      gen_helper_srst(tcg_env, r1, r2);
4499      set_cc_static(s);
4500      return DISAS_NEXT;
4501  }
4502  
op_srstu(DisasContext * s,DisasOps * o)4503  static DisasJumpType op_srstu(DisasContext *s, DisasOps *o)
4504  {
4505      TCGv_i32 r1 = tcg_constant_i32(get_field(s, r1));
4506      TCGv_i32 r2 = tcg_constant_i32(get_field(s, r2));
4507  
4508      gen_helper_srstu(tcg_env, r1, r2);
4509      set_cc_static(s);
4510      return DISAS_NEXT;
4511  }
4512  
op_sub(DisasContext * s,DisasOps * o)4513  static DisasJumpType op_sub(DisasContext *s, DisasOps *o)
4514  {
4515      tcg_gen_sub_i64(o->out, o->in1, o->in2);
4516      return DISAS_NEXT;
4517  }
4518  
op_subu64(DisasContext * s,DisasOps * o)4519  static DisasJumpType op_subu64(DisasContext *s, DisasOps *o)
4520  {
4521      tcg_gen_movi_i64(cc_src, 0);
4522      tcg_gen_sub2_i64(o->out, cc_src, o->in1, cc_src, o->in2, cc_src);
4523      return DISAS_NEXT;
4524  }
4525  
4526  /* Compute borrow (0, -1) into cc_src. */
compute_borrow(DisasContext * s)4527  static void compute_borrow(DisasContext *s)
4528  {
4529      switch (s->cc_op) {
4530      case CC_OP_SUBU:
4531          /* The borrow value is already in cc_src (0,-1). */
4532          break;
4533      default:
4534          gen_op_calc_cc(s);
4535          /* fall through */
4536      case CC_OP_STATIC:
4537          /* The carry flag is the msb of CC; compute into cc_src. */
4538          tcg_gen_extu_i32_i64(cc_src, cc_op);
4539          tcg_gen_shri_i64(cc_src, cc_src, 1);
4540          /* fall through */
4541      case CC_OP_ADDU:
4542          /* Convert carry (1,0) to borrow (0,-1). */
4543          tcg_gen_subi_i64(cc_src, cc_src, 1);
4544          break;
4545      }
4546  }
4547  
op_subb32(DisasContext * s,DisasOps * o)4548  static DisasJumpType op_subb32(DisasContext *s, DisasOps *o)
4549  {
4550      compute_borrow(s);
4551  
4552      /* Borrow is {0, -1}, so add to subtract. */
4553      tcg_gen_add_i64(o->out, o->in1, cc_src);
4554      tcg_gen_sub_i64(o->out, o->out, o->in2);
4555      return DISAS_NEXT;
4556  }
4557  
op_subb64(DisasContext * s,DisasOps * o)4558  static DisasJumpType op_subb64(DisasContext *s, DisasOps *o)
4559  {
4560      compute_borrow(s);
4561  
4562      /*
4563       * Borrow is {0, -1}, so add to subtract; replicate the
4564       * borrow input to produce 128-bit -1 for the addition.
4565       */
4566      TCGv_i64 zero = tcg_constant_i64(0);
4567      tcg_gen_add2_i64(o->out, cc_src, o->in1, zero, cc_src, cc_src);
4568      tcg_gen_sub2_i64(o->out, cc_src, o->out, cc_src, o->in2, zero);
4569  
4570      return DISAS_NEXT;
4571  }
4572  
op_svc(DisasContext * s,DisasOps * o)4573  static DisasJumpType op_svc(DisasContext *s, DisasOps *o)
4574  {
4575      TCGv_i32 t;
4576  
4577      update_psw_addr(s);
4578      update_cc_op(s);
4579  
4580      t = tcg_constant_i32(get_field(s, i1) & 0xff);
4581      tcg_gen_st_i32(t, tcg_env, offsetof(CPUS390XState, int_svc_code));
4582  
4583      t = tcg_constant_i32(s->ilen);
4584      tcg_gen_st_i32(t, tcg_env, offsetof(CPUS390XState, int_svc_ilen));
4585  
4586      gen_exception(EXCP_SVC);
4587      return DISAS_NORETURN;
4588  }
4589  
op_tam(DisasContext * s,DisasOps * o)4590  static DisasJumpType op_tam(DisasContext *s, DisasOps *o)
4591  {
4592      int cc = 0;
4593  
4594      cc |= (s->base.tb->flags & FLAG_MASK_64) ? 2 : 0;
4595      cc |= (s->base.tb->flags & FLAG_MASK_32) ? 1 : 0;
4596      gen_op_movi_cc(s, cc);
4597      return DISAS_NEXT;
4598  }
4599  
op_tceb(DisasContext * s,DisasOps * o)4600  static DisasJumpType op_tceb(DisasContext *s, DisasOps *o)
4601  {
4602      gen_helper_tceb(cc_op, tcg_env, o->in1, o->in2);
4603      set_cc_static(s);
4604      return DISAS_NEXT;
4605  }
4606  
op_tcdb(DisasContext * s,DisasOps * o)4607  static DisasJumpType op_tcdb(DisasContext *s, DisasOps *o)
4608  {
4609      gen_helper_tcdb(cc_op, tcg_env, o->in1, o->in2);
4610      set_cc_static(s);
4611      return DISAS_NEXT;
4612  }
4613  
op_tcxb(DisasContext * s,DisasOps * o)4614  static DisasJumpType op_tcxb(DisasContext *s, DisasOps *o)
4615  {
4616      gen_helper_tcxb(cc_op, tcg_env, o->in1_128, o->in2);
4617      set_cc_static(s);
4618      return DISAS_NEXT;
4619  }
4620  
4621  #ifndef CONFIG_USER_ONLY
4622  
op_testblock(DisasContext * s,DisasOps * o)4623  static DisasJumpType op_testblock(DisasContext *s, DisasOps *o)
4624  {
4625      gen_helper_testblock(cc_op, tcg_env, o->in2);
4626      set_cc_static(s);
4627      return DISAS_NEXT;
4628  }
4629  
op_tprot(DisasContext * s,DisasOps * o)4630  static DisasJumpType op_tprot(DisasContext *s, DisasOps *o)
4631  {
4632      gen_helper_tprot(cc_op, tcg_env, o->addr1, o->in2);
4633      set_cc_static(s);
4634      return DISAS_NEXT;
4635  }
4636  
4637  #endif
4638  
op_tp(DisasContext * s,DisasOps * o)4639  static DisasJumpType op_tp(DisasContext *s, DisasOps *o)
4640  {
4641      TCGv_i32 l1 = tcg_constant_i32(get_field(s, l1) + 1);
4642  
4643      gen_helper_tp(cc_op, tcg_env, o->addr1, l1);
4644      set_cc_static(s);
4645      return DISAS_NEXT;
4646  }
4647  
op_tr(DisasContext * s,DisasOps * o)4648  static DisasJumpType op_tr(DisasContext *s, DisasOps *o)
4649  {
4650      TCGv_i32 l = tcg_constant_i32(get_field(s, l1));
4651  
4652      gen_helper_tr(tcg_env, l, o->addr1, o->in2);
4653      set_cc_static(s);
4654      return DISAS_NEXT;
4655  }
4656  
op_tre(DisasContext * s,DisasOps * o)4657  static DisasJumpType op_tre(DisasContext *s, DisasOps *o)
4658  {
4659      TCGv_i128 pair = tcg_temp_new_i128();
4660  
4661      gen_helper_tre(pair, tcg_env, o->out, o->out2, o->in2);
4662      tcg_gen_extr_i128_i64(o->out2, o->out, pair);
4663      set_cc_static(s);
4664      return DISAS_NEXT;
4665  }
4666  
op_trt(DisasContext * s,DisasOps * o)4667  static DisasJumpType op_trt(DisasContext *s, DisasOps *o)
4668  {
4669      TCGv_i32 l = tcg_constant_i32(get_field(s, l1));
4670  
4671      gen_helper_trt(cc_op, tcg_env, l, o->addr1, o->in2);
4672      set_cc_static(s);
4673      return DISAS_NEXT;
4674  }
4675  
op_trtr(DisasContext * s,DisasOps * o)4676  static DisasJumpType op_trtr(DisasContext *s, DisasOps *o)
4677  {
4678      TCGv_i32 l = tcg_constant_i32(get_field(s, l1));
4679  
4680      gen_helper_trtr(cc_op, tcg_env, l, o->addr1, o->in2);
4681      set_cc_static(s);
4682      return DISAS_NEXT;
4683  }
4684  
op_trXX(DisasContext * s,DisasOps * o)4685  static DisasJumpType op_trXX(DisasContext *s, DisasOps *o)
4686  {
4687      TCGv_i32 r1 = tcg_constant_i32(get_field(s, r1));
4688      TCGv_i32 r2 = tcg_constant_i32(get_field(s, r2));
4689      TCGv_i32 sizes = tcg_constant_i32(s->insn->opc & 3);
4690      TCGv_i32 tst = tcg_temp_new_i32();
4691      int m3 = get_field(s, m3);
4692  
4693      if (!s390_has_feat(S390_FEAT_ETF2_ENH)) {
4694          m3 = 0;
4695      }
4696      if (m3 & 1) {
4697          tcg_gen_movi_i32(tst, -1);
4698      } else {
4699          tcg_gen_extrl_i64_i32(tst, regs[0]);
4700          if (s->insn->opc & 3) {
4701              tcg_gen_ext8u_i32(tst, tst);
4702          } else {
4703              tcg_gen_ext16u_i32(tst, tst);
4704          }
4705      }
4706      gen_helper_trXX(cc_op, tcg_env, r1, r2, tst, sizes);
4707  
4708      set_cc_static(s);
4709      return DISAS_NEXT;
4710  }
4711  
op_ts(DisasContext * s,DisasOps * o)4712  static DisasJumpType op_ts(DisasContext *s, DisasOps *o)
4713  {
4714      TCGv_i32 ff = tcg_constant_i32(0xff);
4715      TCGv_i32 t1 = tcg_temp_new_i32();
4716  
4717      tcg_gen_atomic_xchg_i32(t1, o->in2, ff, get_mem_index(s), MO_UB);
4718      tcg_gen_extract_i32(cc_op, t1, 7, 1);
4719      set_cc_static(s);
4720      return DISAS_NEXT;
4721  }
4722  
op_unpk(DisasContext * s,DisasOps * o)4723  static DisasJumpType op_unpk(DisasContext *s, DisasOps *o)
4724  {
4725      TCGv_i32 l = tcg_constant_i32(get_field(s, l1));
4726  
4727      gen_helper_unpk(tcg_env, l, o->addr1, o->in2);
4728      return DISAS_NEXT;
4729  }
4730  
op_unpka(DisasContext * s,DisasOps * o)4731  static DisasJumpType op_unpka(DisasContext *s, DisasOps *o)
4732  {
4733      int l1 = get_field(s, l1) + 1;
4734      TCGv_i32 l;
4735  
4736      /* The length must not exceed 32 bytes.  */
4737      if (l1 > 32) {
4738          gen_program_exception(s, PGM_SPECIFICATION);
4739          return DISAS_NORETURN;
4740      }
4741      l = tcg_constant_i32(l1);
4742      gen_helper_unpka(cc_op, tcg_env, o->addr1, l, o->in2);
4743      set_cc_static(s);
4744      return DISAS_NEXT;
4745  }
4746  
op_unpku(DisasContext * s,DisasOps * o)4747  static DisasJumpType op_unpku(DisasContext *s, DisasOps *o)
4748  {
4749      int l1 = get_field(s, l1) + 1;
4750      TCGv_i32 l;
4751  
4752      /* The length must be even and should not exceed 64 bytes.  */
4753      if ((l1 & 1) || (l1 > 64)) {
4754          gen_program_exception(s, PGM_SPECIFICATION);
4755          return DISAS_NORETURN;
4756      }
4757      l = tcg_constant_i32(l1);
4758      gen_helper_unpku(cc_op, tcg_env, o->addr1, l, o->in2);
4759      set_cc_static(s);
4760      return DISAS_NEXT;
4761  }
4762  
4763  
op_xc(DisasContext * s,DisasOps * o)4764  static DisasJumpType op_xc(DisasContext *s, DisasOps *o)
4765  {
4766      int d1 = get_field(s, d1);
4767      int d2 = get_field(s, d2);
4768      int b1 = get_field(s, b1);
4769      int b2 = get_field(s, b2);
4770      int l = get_field(s, l1);
4771      TCGv_i32 t32;
4772  
4773      o->addr1 = get_address(s, 0, b1, d1);
4774  
4775      /* If the addresses are identical, this is a store/memset of zero.  */
4776      if (b1 == b2 && d1 == d2 && (l + 1) <= 32) {
4777          o->in2 = tcg_constant_i64(0);
4778  
4779          l++;
4780          while (l >= 8) {
4781              tcg_gen_qemu_st_i64(o->in2, o->addr1, get_mem_index(s), MO_UQ);
4782              l -= 8;
4783              if (l > 0) {
4784                  tcg_gen_addi_i64(o->addr1, o->addr1, 8);
4785              }
4786          }
4787          if (l >= 4) {
4788              tcg_gen_qemu_st_i64(o->in2, o->addr1, get_mem_index(s), MO_UL);
4789              l -= 4;
4790              if (l > 0) {
4791                  tcg_gen_addi_i64(o->addr1, o->addr1, 4);
4792              }
4793          }
4794          if (l >= 2) {
4795              tcg_gen_qemu_st_i64(o->in2, o->addr1, get_mem_index(s), MO_UW);
4796              l -= 2;
4797              if (l > 0) {
4798                  tcg_gen_addi_i64(o->addr1, o->addr1, 2);
4799              }
4800          }
4801          if (l) {
4802              tcg_gen_qemu_st_i64(o->in2, o->addr1, get_mem_index(s), MO_UB);
4803          }
4804          gen_op_movi_cc(s, 0);
4805          return DISAS_NEXT;
4806      }
4807  
4808      /* But in general we'll defer to a helper.  */
4809      o->in2 = get_address(s, 0, b2, d2);
4810      t32 = tcg_constant_i32(l);
4811      gen_helper_xc(cc_op, tcg_env, t32, o->addr1, o->in2);
4812      set_cc_static(s);
4813      return DISAS_NEXT;
4814  }
4815  
op_xor(DisasContext * s,DisasOps * o)4816  static DisasJumpType op_xor(DisasContext *s, DisasOps *o)
4817  {
4818      tcg_gen_xor_i64(o->out, o->in1, o->in2);
4819      return DISAS_NEXT;
4820  }
4821  
op_xori(DisasContext * s,DisasOps * o)4822  static DisasJumpType op_xori(DisasContext *s, DisasOps *o)
4823  {
4824      int shift = s->insn->data & 0xff;
4825      int size = s->insn->data >> 8;
4826      uint64_t mask = ((1ull << size) - 1) << shift;
4827      TCGv_i64 t = tcg_temp_new_i64();
4828  
4829      tcg_gen_shli_i64(t, o->in2, shift);
4830      tcg_gen_xor_i64(o->out, o->in1, t);
4831  
4832      /* Produce the CC from only the bits manipulated.  */
4833      tcg_gen_andi_i64(cc_dst, o->out, mask);
4834      set_cc_nz_u64(s, cc_dst);
4835      return DISAS_NEXT;
4836  }
4837  
op_xi(DisasContext * s,DisasOps * o)4838  static DisasJumpType op_xi(DisasContext *s, DisasOps *o)
4839  {
4840      o->in1 = tcg_temp_new_i64();
4841  
4842      if (!s390_has_feat(S390_FEAT_INTERLOCKED_ACCESS_2)) {
4843          tcg_gen_qemu_ld_tl(o->in1, o->addr1, get_mem_index(s), s->insn->data);
4844      } else {
4845          /* Perform the atomic operation in memory. */
4846          tcg_gen_atomic_fetch_xor_i64(o->in1, o->addr1, o->in2, get_mem_index(s),
4847                                       s->insn->data);
4848      }
4849  
4850      /* Recompute also for atomic case: needed for setting CC. */
4851      tcg_gen_xor_i64(o->out, o->in1, o->in2);
4852  
4853      if (!s390_has_feat(S390_FEAT_INTERLOCKED_ACCESS_2)) {
4854          tcg_gen_qemu_st_tl(o->out, o->addr1, get_mem_index(s), s->insn->data);
4855      }
4856      return DISAS_NEXT;
4857  }
4858  
op_zero(DisasContext * s,DisasOps * o)4859  static DisasJumpType op_zero(DisasContext *s, DisasOps *o)
4860  {
4861      o->out = tcg_constant_i64(0);
4862      return DISAS_NEXT;
4863  }
4864  
op_zero2(DisasContext * s,DisasOps * o)4865  static DisasJumpType op_zero2(DisasContext *s, DisasOps *o)
4866  {
4867      o->out = tcg_constant_i64(0);
4868      o->out2 = o->out;
4869      return DISAS_NEXT;
4870  }
4871  
4872  #ifndef CONFIG_USER_ONLY
op_clp(DisasContext * s,DisasOps * o)4873  static DisasJumpType op_clp(DisasContext *s, DisasOps *o)
4874  {
4875      TCGv_i32 r2 = tcg_constant_i32(get_field(s, r2));
4876  
4877      gen_helper_clp(tcg_env, r2);
4878      set_cc_static(s);
4879      return DISAS_NEXT;
4880  }
4881  
op_pcilg(DisasContext * s,DisasOps * o)4882  static DisasJumpType op_pcilg(DisasContext *s, DisasOps *o)
4883  {
4884      TCGv_i32 r1 = tcg_constant_i32(get_field(s, r1));
4885      TCGv_i32 r2 = tcg_constant_i32(get_field(s, r2));
4886  
4887      gen_helper_pcilg(tcg_env, r1, r2);
4888      set_cc_static(s);
4889      return DISAS_NEXT;
4890  }
4891  
op_pcistg(DisasContext * s,DisasOps * o)4892  static DisasJumpType op_pcistg(DisasContext *s, DisasOps *o)
4893  {
4894      TCGv_i32 r1 = tcg_constant_i32(get_field(s, r1));
4895      TCGv_i32 r2 = tcg_constant_i32(get_field(s, r2));
4896  
4897      gen_helper_pcistg(tcg_env, r1, r2);
4898      set_cc_static(s);
4899      return DISAS_NEXT;
4900  }
4901  
op_stpcifc(DisasContext * s,DisasOps * o)4902  static DisasJumpType op_stpcifc(DisasContext *s, DisasOps *o)
4903  {
4904      TCGv_i32 r1 = tcg_constant_i32(get_field(s, r1));
4905      TCGv_i32 ar = tcg_constant_i32(get_field(s, b2));
4906  
4907      gen_helper_stpcifc(tcg_env, r1, o->addr1, ar);
4908      set_cc_static(s);
4909      return DISAS_NEXT;
4910  }
4911  
op_sic(DisasContext * s,DisasOps * o)4912  static DisasJumpType op_sic(DisasContext *s, DisasOps *o)
4913  {
4914      gen_helper_sic(tcg_env, o->in1, o->in2);
4915      return DISAS_NEXT;
4916  }
4917  
op_rpcit(DisasContext * s,DisasOps * o)4918  static DisasJumpType op_rpcit(DisasContext *s, DisasOps *o)
4919  {
4920      TCGv_i32 r1 = tcg_constant_i32(get_field(s, r1));
4921      TCGv_i32 r2 = tcg_constant_i32(get_field(s, r2));
4922  
4923      gen_helper_rpcit(tcg_env, r1, r2);
4924      set_cc_static(s);
4925      return DISAS_NEXT;
4926  }
4927  
op_pcistb(DisasContext * s,DisasOps * o)4928  static DisasJumpType op_pcistb(DisasContext *s, DisasOps *o)
4929  {
4930      TCGv_i32 r1 = tcg_constant_i32(get_field(s, r1));
4931      TCGv_i32 r3 = tcg_constant_i32(get_field(s, r3));
4932      TCGv_i32 ar = tcg_constant_i32(get_field(s, b2));
4933  
4934      gen_helper_pcistb(tcg_env, r1, r3, o->addr1, ar);
4935      set_cc_static(s);
4936      return DISAS_NEXT;
4937  }
4938  
op_mpcifc(DisasContext * s,DisasOps * o)4939  static DisasJumpType op_mpcifc(DisasContext *s, DisasOps *o)
4940  {
4941      TCGv_i32 r1 = tcg_constant_i32(get_field(s, r1));
4942      TCGv_i32 ar = tcg_constant_i32(get_field(s, b2));
4943  
4944      gen_helper_mpcifc(tcg_env, r1, o->addr1, ar);
4945      set_cc_static(s);
4946      return DISAS_NEXT;
4947  }
4948  #endif
4949  
4950  #include "translate_vx.c.inc"
4951  
4952  /* ====================================================================== */
4953  /* The "Cc OUTput" generators.  Given the generated output (and in some cases
4954     the original inputs), update the various cc data structures in order to
4955     be able to compute the new condition code.  */
4956  
cout_abs32(DisasContext * s,DisasOps * o)4957  static void cout_abs32(DisasContext *s, DisasOps *o)
4958  {
4959      gen_op_update1_cc_i64(s, CC_OP_ABS_32, o->out);
4960  }
4961  
cout_abs64(DisasContext * s,DisasOps * o)4962  static void cout_abs64(DisasContext *s, DisasOps *o)
4963  {
4964      gen_op_update1_cc_i64(s, CC_OP_ABS_64, o->out);
4965  }
4966  
cout_adds32(DisasContext * s,DisasOps * o)4967  static void cout_adds32(DisasContext *s, DisasOps *o)
4968  {
4969      gen_op_update3_cc_i64(s, CC_OP_ADD_32, o->in1, o->in2, o->out);
4970  }
4971  
cout_adds64(DisasContext * s,DisasOps * o)4972  static void cout_adds64(DisasContext *s, DisasOps *o)
4973  {
4974      gen_op_update3_cc_i64(s, CC_OP_ADD_64, o->in1, o->in2, o->out);
4975  }
4976  
cout_addu32(DisasContext * s,DisasOps * o)4977  static void cout_addu32(DisasContext *s, DisasOps *o)
4978  {
4979      tcg_gen_shri_i64(cc_src, o->out, 32);
4980      tcg_gen_ext32u_i64(cc_dst, o->out);
4981      gen_op_update2_cc_i64(s, CC_OP_ADDU, cc_src, cc_dst);
4982  }
4983  
cout_addu64(DisasContext * s,DisasOps * o)4984  static void cout_addu64(DisasContext *s, DisasOps *o)
4985  {
4986      gen_op_update2_cc_i64(s, CC_OP_ADDU, cc_src, o->out);
4987  }
4988  
cout_cmps32(DisasContext * s,DisasOps * o)4989  static void cout_cmps32(DisasContext *s, DisasOps *o)
4990  {
4991      gen_op_update2_cc_i64(s, CC_OP_LTGT_32, o->in1, o->in2);
4992  }
4993  
cout_cmps64(DisasContext * s,DisasOps * o)4994  static void cout_cmps64(DisasContext *s, DisasOps *o)
4995  {
4996      gen_op_update2_cc_i64(s, CC_OP_LTGT_64, o->in1, o->in2);
4997  }
4998  
cout_cmpu32(DisasContext * s,DisasOps * o)4999  static void cout_cmpu32(DisasContext *s, DisasOps *o)
5000  {
5001      gen_op_update2_cc_i64(s, CC_OP_LTUGTU_32, o->in1, o->in2);
5002  }
5003  
cout_cmpu64(DisasContext * s,DisasOps * o)5004  static void cout_cmpu64(DisasContext *s, DisasOps *o)
5005  {
5006      gen_op_update2_cc_i64(s, CC_OP_LTUGTU_64, o->in1, o->in2);
5007  }
5008  
cout_f32(DisasContext * s,DisasOps * o)5009  static void cout_f32(DisasContext *s, DisasOps *o)
5010  {
5011      gen_op_update1_cc_i64(s, CC_OP_NZ_F32, o->out);
5012  }
5013  
cout_f64(DisasContext * s,DisasOps * o)5014  static void cout_f64(DisasContext *s, DisasOps *o)
5015  {
5016      gen_op_update1_cc_i64(s, CC_OP_NZ_F64, o->out);
5017  }
5018  
cout_f128(DisasContext * s,DisasOps * o)5019  static void cout_f128(DisasContext *s, DisasOps *o)
5020  {
5021      gen_op_update2_cc_i64(s, CC_OP_NZ_F128, o->out, o->out2);
5022  }
5023  
cout_nabs32(DisasContext * s,DisasOps * o)5024  static void cout_nabs32(DisasContext *s, DisasOps *o)
5025  {
5026      gen_op_update1_cc_i64(s, CC_OP_NABS_32, o->out);
5027  }
5028  
cout_nabs64(DisasContext * s,DisasOps * o)5029  static void cout_nabs64(DisasContext *s, DisasOps *o)
5030  {
5031      gen_op_update1_cc_i64(s, CC_OP_NABS_64, o->out);
5032  }
5033  
cout_neg32(DisasContext * s,DisasOps * o)5034  static void cout_neg32(DisasContext *s, DisasOps *o)
5035  {
5036      gen_op_update1_cc_i64(s, CC_OP_COMP_32, o->out);
5037  }
5038  
cout_neg64(DisasContext * s,DisasOps * o)5039  static void cout_neg64(DisasContext *s, DisasOps *o)
5040  {
5041      gen_op_update1_cc_i64(s, CC_OP_COMP_64, o->out);
5042  }
5043  
cout_nz32(DisasContext * s,DisasOps * o)5044  static void cout_nz32(DisasContext *s, DisasOps *o)
5045  {
5046      tcg_gen_ext32u_i64(cc_dst, o->out);
5047      gen_op_update1_cc_i64(s, CC_OP_NZ, cc_dst);
5048  }
5049  
cout_nz64(DisasContext * s,DisasOps * o)5050  static void cout_nz64(DisasContext *s, DisasOps *o)
5051  {
5052      gen_op_update1_cc_i64(s, CC_OP_NZ, o->out);
5053  }
5054  
cout_s32(DisasContext * s,DisasOps * o)5055  static void cout_s32(DisasContext *s, DisasOps *o)
5056  {
5057      gen_op_update1_cc_i64(s, CC_OP_LTGT0_32, o->out);
5058  }
5059  
cout_s64(DisasContext * s,DisasOps * o)5060  static void cout_s64(DisasContext *s, DisasOps *o)
5061  {
5062      gen_op_update1_cc_i64(s, CC_OP_LTGT0_64, o->out);
5063  }
5064  
cout_subs32(DisasContext * s,DisasOps * o)5065  static void cout_subs32(DisasContext *s, DisasOps *o)
5066  {
5067      gen_op_update3_cc_i64(s, CC_OP_SUB_32, o->in1, o->in2, o->out);
5068  }
5069  
cout_subs64(DisasContext * s,DisasOps * o)5070  static void cout_subs64(DisasContext *s, DisasOps *o)
5071  {
5072      gen_op_update3_cc_i64(s, CC_OP_SUB_64, o->in1, o->in2, o->out);
5073  }
5074  
cout_subu32(DisasContext * s,DisasOps * o)5075  static void cout_subu32(DisasContext *s, DisasOps *o)
5076  {
5077      tcg_gen_sari_i64(cc_src, o->out, 32);
5078      tcg_gen_ext32u_i64(cc_dst, o->out);
5079      gen_op_update2_cc_i64(s, CC_OP_SUBU, cc_src, cc_dst);
5080  }
5081  
cout_subu64(DisasContext * s,DisasOps * o)5082  static void cout_subu64(DisasContext *s, DisasOps *o)
5083  {
5084      gen_op_update2_cc_i64(s, CC_OP_SUBU, cc_src, o->out);
5085  }
5086  
cout_tm32(DisasContext * s,DisasOps * o)5087  static void cout_tm32(DisasContext *s, DisasOps *o)
5088  {
5089      gen_op_update2_cc_i64(s, CC_OP_TM_32, o->in1, o->in2);
5090  }
5091  
cout_tm64(DisasContext * s,DisasOps * o)5092  static void cout_tm64(DisasContext *s, DisasOps *o)
5093  {
5094      gen_op_update2_cc_i64(s, CC_OP_TM_64, o->in1, o->in2);
5095  }
5096  
cout_muls32(DisasContext * s,DisasOps * o)5097  static void cout_muls32(DisasContext *s, DisasOps *o)
5098  {
5099      gen_op_update1_cc_i64(s, CC_OP_MULS_32, o->out);
5100  }
5101  
cout_muls64(DisasContext * s,DisasOps * o)5102  static void cout_muls64(DisasContext *s, DisasOps *o)
5103  {
5104      /* out contains "high" part, out2 contains "low" part of 128 bit result */
5105      gen_op_update2_cc_i64(s, CC_OP_MULS_64, o->out, o->out2);
5106  }
5107  
5108  /* ====================================================================== */
5109  /* The "PREParation" generators.  These initialize the DisasOps.OUT fields
5110     with the TCG register to which we will write.  Used in combination with
5111     the "wout" generators, in some cases we need a new temporary, and in
5112     some cases we can write to a TCG global.  */
5113  
prep_new(DisasContext * s,DisasOps * o)5114  static void prep_new(DisasContext *s, DisasOps *o)
5115  {
5116      o->out = tcg_temp_new_i64();
5117  }
5118  #define SPEC_prep_new 0
5119  
prep_new_P(DisasContext * s,DisasOps * o)5120  static void prep_new_P(DisasContext *s, DisasOps *o)
5121  {
5122      o->out = tcg_temp_new_i64();
5123      o->out2 = tcg_temp_new_i64();
5124  }
5125  #define SPEC_prep_new_P 0
5126  
prep_new_x(DisasContext * s,DisasOps * o)5127  static void prep_new_x(DisasContext *s, DisasOps *o)
5128  {
5129      o->out_128 = tcg_temp_new_i128();
5130  }
5131  #define SPEC_prep_new_x 0
5132  
prep_r1(DisasContext * s,DisasOps * o)5133  static void prep_r1(DisasContext *s, DisasOps *o)
5134  {
5135      o->out = regs[get_field(s, r1)];
5136  }
5137  #define SPEC_prep_r1 0
5138  
prep_r1_P(DisasContext * s,DisasOps * o)5139  static void prep_r1_P(DisasContext *s, DisasOps *o)
5140  {
5141      int r1 = get_field(s, r1);
5142      o->out = regs[r1];
5143      o->out2 = regs[r1 + 1];
5144  }
5145  #define SPEC_prep_r1_P SPEC_r1_even
5146  
5147  /* ====================================================================== */
5148  /* The "Write OUTput" generators.  These generally perform some non-trivial
5149     copy of data to TCG globals, or to main memory.  The trivial cases are
5150     generally handled by having a "prep" generator install the TCG global
5151     as the destination of the operation.  */
5152  
wout_r1(DisasContext * s,DisasOps * o)5153  static void wout_r1(DisasContext *s, DisasOps *o)
5154  {
5155      store_reg(get_field(s, r1), o->out);
5156  }
5157  #define SPEC_wout_r1 0
5158  
wout_out2_r1(DisasContext * s,DisasOps * o)5159  static void wout_out2_r1(DisasContext *s, DisasOps *o)
5160  {
5161      store_reg(get_field(s, r1), o->out2);
5162  }
5163  #define SPEC_wout_out2_r1 0
5164  
wout_r1_8(DisasContext * s,DisasOps * o)5165  static void wout_r1_8(DisasContext *s, DisasOps *o)
5166  {
5167      int r1 = get_field(s, r1);
5168      tcg_gen_deposit_i64(regs[r1], regs[r1], o->out, 0, 8);
5169  }
5170  #define SPEC_wout_r1_8 0
5171  
wout_r1_16(DisasContext * s,DisasOps * o)5172  static void wout_r1_16(DisasContext *s, DisasOps *o)
5173  {
5174      int r1 = get_field(s, r1);
5175      tcg_gen_deposit_i64(regs[r1], regs[r1], o->out, 0, 16);
5176  }
5177  #define SPEC_wout_r1_16 0
5178  
wout_r1_32(DisasContext * s,DisasOps * o)5179  static void wout_r1_32(DisasContext *s, DisasOps *o)
5180  {
5181      store_reg32_i64(get_field(s, r1), o->out);
5182  }
5183  #define SPEC_wout_r1_32 0
5184  
wout_r1_32h(DisasContext * s,DisasOps * o)5185  static void wout_r1_32h(DisasContext *s, DisasOps *o)
5186  {
5187      store_reg32h_i64(get_field(s, r1), o->out);
5188  }
5189  #define SPEC_wout_r1_32h 0
5190  
wout_r1_P32(DisasContext * s,DisasOps * o)5191  static void wout_r1_P32(DisasContext *s, DisasOps *o)
5192  {
5193      int r1 = get_field(s, r1);
5194      store_reg32_i64(r1, o->out);
5195      store_reg32_i64(r1 + 1, o->out2);
5196  }
5197  #define SPEC_wout_r1_P32 SPEC_r1_even
5198  
wout_r1_D32(DisasContext * s,DisasOps * o)5199  static void wout_r1_D32(DisasContext *s, DisasOps *o)
5200  {
5201      int r1 = get_field(s, r1);
5202      TCGv_i64 t = tcg_temp_new_i64();
5203      store_reg32_i64(r1 + 1, o->out);
5204      tcg_gen_shri_i64(t, o->out, 32);
5205      store_reg32_i64(r1, t);
5206  }
5207  #define SPEC_wout_r1_D32 SPEC_r1_even
5208  
wout_r1_D64(DisasContext * s,DisasOps * o)5209  static void wout_r1_D64(DisasContext *s, DisasOps *o)
5210  {
5211      int r1 = get_field(s, r1);
5212      tcg_gen_extr_i128_i64(regs[r1 + 1], regs[r1], o->out_128);
5213  }
5214  #define SPEC_wout_r1_D64 SPEC_r1_even
5215  
wout_r3_P32(DisasContext * s,DisasOps * o)5216  static void wout_r3_P32(DisasContext *s, DisasOps *o)
5217  {
5218      int r3 = get_field(s, r3);
5219      store_reg32_i64(r3, o->out);
5220      store_reg32_i64(r3 + 1, o->out2);
5221  }
5222  #define SPEC_wout_r3_P32 SPEC_r3_even
5223  
wout_r3_P64(DisasContext * s,DisasOps * o)5224  static void wout_r3_P64(DisasContext *s, DisasOps *o)
5225  {
5226      int r3 = get_field(s, r3);
5227      store_reg(r3, o->out);
5228      store_reg(r3 + 1, o->out2);
5229  }
5230  #define SPEC_wout_r3_P64 SPEC_r3_even
5231  
wout_e1(DisasContext * s,DisasOps * o)5232  static void wout_e1(DisasContext *s, DisasOps *o)
5233  {
5234      store_freg32_i64(get_field(s, r1), o->out);
5235  }
5236  #define SPEC_wout_e1 0
5237  
wout_f1(DisasContext * s,DisasOps * o)5238  static void wout_f1(DisasContext *s, DisasOps *o)
5239  {
5240      store_freg(get_field(s, r1), o->out);
5241  }
5242  #define SPEC_wout_f1 0
5243  
wout_x1(DisasContext * s,DisasOps * o)5244  static void wout_x1(DisasContext *s, DisasOps *o)
5245  {
5246      int f1 = get_field(s, r1);
5247  
5248      /* Split out_128 into out+out2 for cout_f128. */
5249      tcg_debug_assert(o->out == NULL);
5250      o->out = tcg_temp_new_i64();
5251      o->out2 = tcg_temp_new_i64();
5252  
5253      tcg_gen_extr_i128_i64(o->out2, o->out, o->out_128);
5254      store_freg(f1, o->out);
5255      store_freg(f1 + 2, o->out2);
5256  }
5257  #define SPEC_wout_x1 SPEC_r1_f128
5258  
wout_x1_P(DisasContext * s,DisasOps * o)5259  static void wout_x1_P(DisasContext *s, DisasOps *o)
5260  {
5261      int f1 = get_field(s, r1);
5262      store_freg(f1, o->out);
5263      store_freg(f1 + 2, o->out2);
5264  }
5265  #define SPEC_wout_x1_P SPEC_r1_f128
5266  
wout_cond_r1r2_32(DisasContext * s,DisasOps * o)5267  static void wout_cond_r1r2_32(DisasContext *s, DisasOps *o)
5268  {
5269      if (get_field(s, r1) != get_field(s, r2)) {
5270          store_reg32_i64(get_field(s, r1), o->out);
5271      }
5272  }
5273  #define SPEC_wout_cond_r1r2_32 0
5274  
wout_cond_e1e2(DisasContext * s,DisasOps * o)5275  static void wout_cond_e1e2(DisasContext *s, DisasOps *o)
5276  {
5277      if (get_field(s, r1) != get_field(s, r2)) {
5278          store_freg32_i64(get_field(s, r1), o->out);
5279      }
5280  }
5281  #define SPEC_wout_cond_e1e2 0
5282  
wout_m1_8(DisasContext * s,DisasOps * o)5283  static void wout_m1_8(DisasContext *s, DisasOps *o)
5284  {
5285      tcg_gen_qemu_st_i64(o->out, o->addr1, get_mem_index(s), MO_UB);
5286  }
5287  #define SPEC_wout_m1_8 0
5288  
wout_m1_16(DisasContext * s,DisasOps * o)5289  static void wout_m1_16(DisasContext *s, DisasOps *o)
5290  {
5291      tcg_gen_qemu_st_i64(o->out, o->addr1, get_mem_index(s), MO_TEUW);
5292  }
5293  #define SPEC_wout_m1_16 0
5294  
5295  #ifndef CONFIG_USER_ONLY
wout_m1_16a(DisasContext * s,DisasOps * o)5296  static void wout_m1_16a(DisasContext *s, DisasOps *o)
5297  {
5298      tcg_gen_qemu_st_tl(o->out, o->addr1, get_mem_index(s), MO_TEUW | MO_ALIGN);
5299  }
5300  #define SPEC_wout_m1_16a 0
5301  #endif
5302  
wout_m1_32(DisasContext * s,DisasOps * o)5303  static void wout_m1_32(DisasContext *s, DisasOps *o)
5304  {
5305      tcg_gen_qemu_st_i64(o->out, o->addr1, get_mem_index(s), MO_TEUL);
5306  }
5307  #define SPEC_wout_m1_32 0
5308  
5309  #ifndef CONFIG_USER_ONLY
wout_m1_32a(DisasContext * s,DisasOps * o)5310  static void wout_m1_32a(DisasContext *s, DisasOps *o)
5311  {
5312      tcg_gen_qemu_st_tl(o->out, o->addr1, get_mem_index(s), MO_TEUL | MO_ALIGN);
5313  }
5314  #define SPEC_wout_m1_32a 0
5315  #endif
5316  
wout_m1_64(DisasContext * s,DisasOps * o)5317  static void wout_m1_64(DisasContext *s, DisasOps *o)
5318  {
5319      tcg_gen_qemu_st_i64(o->out, o->addr1, get_mem_index(s), MO_TEUQ);
5320  }
5321  #define SPEC_wout_m1_64 0
5322  
5323  #ifndef CONFIG_USER_ONLY
wout_m1_64a(DisasContext * s,DisasOps * o)5324  static void wout_m1_64a(DisasContext *s, DisasOps *o)
5325  {
5326      tcg_gen_qemu_st_i64(o->out, o->addr1, get_mem_index(s), MO_TEUQ | MO_ALIGN);
5327  }
5328  #define SPEC_wout_m1_64a 0
5329  #endif
5330  
wout_m2_32(DisasContext * s,DisasOps * o)5331  static void wout_m2_32(DisasContext *s, DisasOps *o)
5332  {
5333      tcg_gen_qemu_st_i64(o->out, o->in2, get_mem_index(s), MO_TEUL);
5334  }
5335  #define SPEC_wout_m2_32 0
5336  
wout_in2_r1(DisasContext * s,DisasOps * o)5337  static void wout_in2_r1(DisasContext *s, DisasOps *o)
5338  {
5339      store_reg(get_field(s, r1), o->in2);
5340  }
5341  #define SPEC_wout_in2_r1 0
5342  
wout_in2_r1_32(DisasContext * s,DisasOps * o)5343  static void wout_in2_r1_32(DisasContext *s, DisasOps *o)
5344  {
5345      store_reg32_i64(get_field(s, r1), o->in2);
5346  }
5347  #define SPEC_wout_in2_r1_32 0
5348  
5349  /* ====================================================================== */
5350  /* The "INput 1" generators.  These load the first operand to an insn.  */
5351  
in1_r1(DisasContext * s,DisasOps * o)5352  static void in1_r1(DisasContext *s, DisasOps *o)
5353  {
5354      o->in1 = load_reg(get_field(s, r1));
5355  }
5356  #define SPEC_in1_r1 0
5357  
in1_r1_o(DisasContext * s,DisasOps * o)5358  static void in1_r1_o(DisasContext *s, DisasOps *o)
5359  {
5360      o->in1 = regs[get_field(s, r1)];
5361  }
5362  #define SPEC_in1_r1_o 0
5363  
in1_r1_32s(DisasContext * s,DisasOps * o)5364  static void in1_r1_32s(DisasContext *s, DisasOps *o)
5365  {
5366      o->in1 = tcg_temp_new_i64();
5367      tcg_gen_ext32s_i64(o->in1, regs[get_field(s, r1)]);
5368  }
5369  #define SPEC_in1_r1_32s 0
5370  
in1_r1_32u(DisasContext * s,DisasOps * o)5371  static void in1_r1_32u(DisasContext *s, DisasOps *o)
5372  {
5373      o->in1 = tcg_temp_new_i64();
5374      tcg_gen_ext32u_i64(o->in1, regs[get_field(s, r1)]);
5375  }
5376  #define SPEC_in1_r1_32u 0
5377  
in1_r1_sr32(DisasContext * s,DisasOps * o)5378  static void in1_r1_sr32(DisasContext *s, DisasOps *o)
5379  {
5380      o->in1 = tcg_temp_new_i64();
5381      tcg_gen_shri_i64(o->in1, regs[get_field(s, r1)], 32);
5382  }
5383  #define SPEC_in1_r1_sr32 0
5384  
in1_r1p1(DisasContext * s,DisasOps * o)5385  static void in1_r1p1(DisasContext *s, DisasOps *o)
5386  {
5387      o->in1 = load_reg(get_field(s, r1) + 1);
5388  }
5389  #define SPEC_in1_r1p1 SPEC_r1_even
5390  
in1_r1p1_o(DisasContext * s,DisasOps * o)5391  static void in1_r1p1_o(DisasContext *s, DisasOps *o)
5392  {
5393      o->in1 = regs[get_field(s, r1) + 1];
5394  }
5395  #define SPEC_in1_r1p1_o SPEC_r1_even
5396  
in1_r1p1_32s(DisasContext * s,DisasOps * o)5397  static void in1_r1p1_32s(DisasContext *s, DisasOps *o)
5398  {
5399      o->in1 = tcg_temp_new_i64();
5400      tcg_gen_ext32s_i64(o->in1, regs[get_field(s, r1) + 1]);
5401  }
5402  #define SPEC_in1_r1p1_32s SPEC_r1_even
5403  
in1_r1p1_32u(DisasContext * s,DisasOps * o)5404  static void in1_r1p1_32u(DisasContext *s, DisasOps *o)
5405  {
5406      o->in1 = tcg_temp_new_i64();
5407      tcg_gen_ext32u_i64(o->in1, regs[get_field(s, r1) + 1]);
5408  }
5409  #define SPEC_in1_r1p1_32u SPEC_r1_even
5410  
in1_r1_D32(DisasContext * s,DisasOps * o)5411  static void in1_r1_D32(DisasContext *s, DisasOps *o)
5412  {
5413      int r1 = get_field(s, r1);
5414      o->in1 = tcg_temp_new_i64();
5415      tcg_gen_concat32_i64(o->in1, regs[r1 + 1], regs[r1]);
5416  }
5417  #define SPEC_in1_r1_D32 SPEC_r1_even
5418  
in1_r2(DisasContext * s,DisasOps * o)5419  static void in1_r2(DisasContext *s, DisasOps *o)
5420  {
5421      o->in1 = load_reg(get_field(s, r2));
5422  }
5423  #define SPEC_in1_r2 0
5424  
in1_r2_sr32(DisasContext * s,DisasOps * o)5425  static void in1_r2_sr32(DisasContext *s, DisasOps *o)
5426  {
5427      o->in1 = tcg_temp_new_i64();
5428      tcg_gen_shri_i64(o->in1, regs[get_field(s, r2)], 32);
5429  }
5430  #define SPEC_in1_r2_sr32 0
5431  
in1_r2_32u(DisasContext * s,DisasOps * o)5432  static void in1_r2_32u(DisasContext *s, DisasOps *o)
5433  {
5434      o->in1 = tcg_temp_new_i64();
5435      tcg_gen_ext32u_i64(o->in1, regs[get_field(s, r2)]);
5436  }
5437  #define SPEC_in1_r2_32u 0
5438  
in1_r3(DisasContext * s,DisasOps * o)5439  static void in1_r3(DisasContext *s, DisasOps *o)
5440  {
5441      o->in1 = load_reg(get_field(s, r3));
5442  }
5443  #define SPEC_in1_r3 0
5444  
in1_r3_o(DisasContext * s,DisasOps * o)5445  static void in1_r3_o(DisasContext *s, DisasOps *o)
5446  {
5447      o->in1 = regs[get_field(s, r3)];
5448  }
5449  #define SPEC_in1_r3_o 0
5450  
in1_r3_32s(DisasContext * s,DisasOps * o)5451  static void in1_r3_32s(DisasContext *s, DisasOps *o)
5452  {
5453      o->in1 = tcg_temp_new_i64();
5454      tcg_gen_ext32s_i64(o->in1, regs[get_field(s, r3)]);
5455  }
5456  #define SPEC_in1_r3_32s 0
5457  
in1_r3_32u(DisasContext * s,DisasOps * o)5458  static void in1_r3_32u(DisasContext *s, DisasOps *o)
5459  {
5460      o->in1 = tcg_temp_new_i64();
5461      tcg_gen_ext32u_i64(o->in1, regs[get_field(s, r3)]);
5462  }
5463  #define SPEC_in1_r3_32u 0
5464  
in1_r3_D32(DisasContext * s,DisasOps * o)5465  static void in1_r3_D32(DisasContext *s, DisasOps *o)
5466  {
5467      int r3 = get_field(s, r3);
5468      o->in1 = tcg_temp_new_i64();
5469      tcg_gen_concat32_i64(o->in1, regs[r3 + 1], regs[r3]);
5470  }
5471  #define SPEC_in1_r3_D32 SPEC_r3_even
5472  
in1_r3_sr32(DisasContext * s,DisasOps * o)5473  static void in1_r3_sr32(DisasContext *s, DisasOps *o)
5474  {
5475      o->in1 = tcg_temp_new_i64();
5476      tcg_gen_shri_i64(o->in1, regs[get_field(s, r3)], 32);
5477  }
5478  #define SPEC_in1_r3_sr32 0
5479  
in1_e1(DisasContext * s,DisasOps * o)5480  static void in1_e1(DisasContext *s, DisasOps *o)
5481  {
5482      o->in1 = load_freg32_i64(get_field(s, r1));
5483  }
5484  #define SPEC_in1_e1 0
5485  
in1_f1(DisasContext * s,DisasOps * o)5486  static void in1_f1(DisasContext *s, DisasOps *o)
5487  {
5488      o->in1 = load_freg(get_field(s, r1));
5489  }
5490  #define SPEC_in1_f1 0
5491  
in1_x1(DisasContext * s,DisasOps * o)5492  static void in1_x1(DisasContext *s, DisasOps *o)
5493  {
5494      o->in1_128 = load_freg_128(get_field(s, r1));
5495  }
5496  #define SPEC_in1_x1 SPEC_r1_f128
5497  
5498  /* Load the high double word of an extended (128-bit) format FP number */
in1_x2h(DisasContext * s,DisasOps * o)5499  static void in1_x2h(DisasContext *s, DisasOps *o)
5500  {
5501      o->in1 = load_freg(get_field(s, r2));
5502  }
5503  #define SPEC_in1_x2h SPEC_r2_f128
5504  
in1_f3(DisasContext * s,DisasOps * o)5505  static void in1_f3(DisasContext *s, DisasOps *o)
5506  {
5507      o->in1 = load_freg(get_field(s, r3));
5508  }
5509  #define SPEC_in1_f3 0
5510  
in1_la1(DisasContext * s,DisasOps * o)5511  static void in1_la1(DisasContext *s, DisasOps *o)
5512  {
5513      o->addr1 = get_address(s, 0, get_field(s, b1), get_field(s, d1));
5514  }
5515  #define SPEC_in1_la1 0
5516  
in1_la2(DisasContext * s,DisasOps * o)5517  static void in1_la2(DisasContext *s, DisasOps *o)
5518  {
5519      int x2 = have_field(s, x2) ? get_field(s, x2) : 0;
5520      o->addr1 = get_address(s, x2, get_field(s, b2), get_field(s, d2));
5521  }
5522  #define SPEC_in1_la2 0
5523  
in1_m1_8u(DisasContext * s,DisasOps * o)5524  static void in1_m1_8u(DisasContext *s, DisasOps *o)
5525  {
5526      in1_la1(s, o);
5527      o->in1 = tcg_temp_new_i64();
5528      tcg_gen_qemu_ld_i64(o->in1, o->addr1, get_mem_index(s), MO_UB);
5529  }
5530  #define SPEC_in1_m1_8u 0
5531  
in1_m1_16s(DisasContext * s,DisasOps * o)5532  static void in1_m1_16s(DisasContext *s, DisasOps *o)
5533  {
5534      in1_la1(s, o);
5535      o->in1 = tcg_temp_new_i64();
5536      tcg_gen_qemu_ld_i64(o->in1, o->addr1, get_mem_index(s), MO_TESW);
5537  }
5538  #define SPEC_in1_m1_16s 0
5539  
in1_m1_16u(DisasContext * s,DisasOps * o)5540  static void in1_m1_16u(DisasContext *s, DisasOps *o)
5541  {
5542      in1_la1(s, o);
5543      o->in1 = tcg_temp_new_i64();
5544      tcg_gen_qemu_ld_i64(o->in1, o->addr1, get_mem_index(s), MO_TEUW);
5545  }
5546  #define SPEC_in1_m1_16u 0
5547  
in1_m1_32s(DisasContext * s,DisasOps * o)5548  static void in1_m1_32s(DisasContext *s, DisasOps *o)
5549  {
5550      in1_la1(s, o);
5551      o->in1 = tcg_temp_new_i64();
5552      tcg_gen_qemu_ld_i64(o->in1, o->addr1, get_mem_index(s), MO_TESL);
5553  }
5554  #define SPEC_in1_m1_32s 0
5555  
in1_m1_32u(DisasContext * s,DisasOps * o)5556  static void in1_m1_32u(DisasContext *s, DisasOps *o)
5557  {
5558      in1_la1(s, o);
5559      o->in1 = tcg_temp_new_i64();
5560      tcg_gen_qemu_ld_i64(o->in1, o->addr1, get_mem_index(s), MO_TEUL);
5561  }
5562  #define SPEC_in1_m1_32u 0
5563  
in1_m1_64(DisasContext * s,DisasOps * o)5564  static void in1_m1_64(DisasContext *s, DisasOps *o)
5565  {
5566      in1_la1(s, o);
5567      o->in1 = tcg_temp_new_i64();
5568      tcg_gen_qemu_ld_i64(o->in1, o->addr1, get_mem_index(s), MO_TEUQ);
5569  }
5570  #define SPEC_in1_m1_64 0
5571  
5572  /* ====================================================================== */
5573  /* The "INput 2" generators.  These load the second operand to an insn.  */
5574  
in2_r1_o(DisasContext * s,DisasOps * o)5575  static void in2_r1_o(DisasContext *s, DisasOps *o)
5576  {
5577      o->in2 = regs[get_field(s, r1)];
5578  }
5579  #define SPEC_in2_r1_o 0
5580  
in2_r1_16u(DisasContext * s,DisasOps * o)5581  static void in2_r1_16u(DisasContext *s, DisasOps *o)
5582  {
5583      o->in2 = tcg_temp_new_i64();
5584      tcg_gen_ext16u_i64(o->in2, regs[get_field(s, r1)]);
5585  }
5586  #define SPEC_in2_r1_16u 0
5587  
in2_r1_32u(DisasContext * s,DisasOps * o)5588  static void in2_r1_32u(DisasContext *s, DisasOps *o)
5589  {
5590      o->in2 = tcg_temp_new_i64();
5591      tcg_gen_ext32u_i64(o->in2, regs[get_field(s, r1)]);
5592  }
5593  #define SPEC_in2_r1_32u 0
5594  
in2_r1_D32(DisasContext * s,DisasOps * o)5595  static void in2_r1_D32(DisasContext *s, DisasOps *o)
5596  {
5597      int r1 = get_field(s, r1);
5598      o->in2 = tcg_temp_new_i64();
5599      tcg_gen_concat32_i64(o->in2, regs[r1 + 1], regs[r1]);
5600  }
5601  #define SPEC_in2_r1_D32 SPEC_r1_even
5602  
in2_r2(DisasContext * s,DisasOps * o)5603  static void in2_r2(DisasContext *s, DisasOps *o)
5604  {
5605      o->in2 = load_reg(get_field(s, r2));
5606  }
5607  #define SPEC_in2_r2 0
5608  
in2_r2_o(DisasContext * s,DisasOps * o)5609  static void in2_r2_o(DisasContext *s, DisasOps *o)
5610  {
5611      o->in2 = regs[get_field(s, r2)];
5612  }
5613  #define SPEC_in2_r2_o 0
5614  
in2_r2_nz(DisasContext * s,DisasOps * o)5615  static void in2_r2_nz(DisasContext *s, DisasOps *o)
5616  {
5617      int r2 = get_field(s, r2);
5618      if (r2 != 0) {
5619          o->in2 = load_reg(r2);
5620      }
5621  }
5622  #define SPEC_in2_r2_nz 0
5623  
in2_r2_8s(DisasContext * s,DisasOps * o)5624  static void in2_r2_8s(DisasContext *s, DisasOps *o)
5625  {
5626      o->in2 = tcg_temp_new_i64();
5627      tcg_gen_ext8s_i64(o->in2, regs[get_field(s, r2)]);
5628  }
5629  #define SPEC_in2_r2_8s 0
5630  
in2_r2_8u(DisasContext * s,DisasOps * o)5631  static void in2_r2_8u(DisasContext *s, DisasOps *o)
5632  {
5633      o->in2 = tcg_temp_new_i64();
5634      tcg_gen_ext8u_i64(o->in2, regs[get_field(s, r2)]);
5635  }
5636  #define SPEC_in2_r2_8u 0
5637  
in2_r2_16s(DisasContext * s,DisasOps * o)5638  static void in2_r2_16s(DisasContext *s, DisasOps *o)
5639  {
5640      o->in2 = tcg_temp_new_i64();
5641      tcg_gen_ext16s_i64(o->in2, regs[get_field(s, r2)]);
5642  }
5643  #define SPEC_in2_r2_16s 0
5644  
in2_r2_16u(DisasContext * s,DisasOps * o)5645  static void in2_r2_16u(DisasContext *s, DisasOps *o)
5646  {
5647      o->in2 = tcg_temp_new_i64();
5648      tcg_gen_ext16u_i64(o->in2, regs[get_field(s, r2)]);
5649  }
5650  #define SPEC_in2_r2_16u 0
5651  
in2_r3(DisasContext * s,DisasOps * o)5652  static void in2_r3(DisasContext *s, DisasOps *o)
5653  {
5654      o->in2 = load_reg(get_field(s, r3));
5655  }
5656  #define SPEC_in2_r3 0
5657  
in2_r3_D64(DisasContext * s,DisasOps * o)5658  static void in2_r3_D64(DisasContext *s, DisasOps *o)
5659  {
5660      int r3 = get_field(s, r3);
5661      o->in2_128 = tcg_temp_new_i128();
5662      tcg_gen_concat_i64_i128(o->in2_128, regs[r3 + 1], regs[r3]);
5663  }
5664  #define SPEC_in2_r3_D64 SPEC_r3_even
5665  
in2_r3_sr32(DisasContext * s,DisasOps * o)5666  static void in2_r3_sr32(DisasContext *s, DisasOps *o)
5667  {
5668      o->in2 = tcg_temp_new_i64();
5669      tcg_gen_shri_i64(o->in2, regs[get_field(s, r3)], 32);
5670  }
5671  #define SPEC_in2_r3_sr32 0
5672  
in2_r3_32u(DisasContext * s,DisasOps * o)5673  static void in2_r3_32u(DisasContext *s, DisasOps *o)
5674  {
5675      o->in2 = tcg_temp_new_i64();
5676      tcg_gen_ext32u_i64(o->in2, regs[get_field(s, r3)]);
5677  }
5678  #define SPEC_in2_r3_32u 0
5679  
in2_r2_32s(DisasContext * s,DisasOps * o)5680  static void in2_r2_32s(DisasContext *s, DisasOps *o)
5681  {
5682      o->in2 = tcg_temp_new_i64();
5683      tcg_gen_ext32s_i64(o->in2, regs[get_field(s, r2)]);
5684  }
5685  #define SPEC_in2_r2_32s 0
5686  
in2_r2_32u(DisasContext * s,DisasOps * o)5687  static void in2_r2_32u(DisasContext *s, DisasOps *o)
5688  {
5689      o->in2 = tcg_temp_new_i64();
5690      tcg_gen_ext32u_i64(o->in2, regs[get_field(s, r2)]);
5691  }
5692  #define SPEC_in2_r2_32u 0
5693  
in2_r2_sr32(DisasContext * s,DisasOps * o)5694  static void in2_r2_sr32(DisasContext *s, DisasOps *o)
5695  {
5696      o->in2 = tcg_temp_new_i64();
5697      tcg_gen_shri_i64(o->in2, regs[get_field(s, r2)], 32);
5698  }
5699  #define SPEC_in2_r2_sr32 0
5700  
in2_e2(DisasContext * s,DisasOps * o)5701  static void in2_e2(DisasContext *s, DisasOps *o)
5702  {
5703      o->in2 = load_freg32_i64(get_field(s, r2));
5704  }
5705  #define SPEC_in2_e2 0
5706  
in2_f2(DisasContext * s,DisasOps * o)5707  static void in2_f2(DisasContext *s, DisasOps *o)
5708  {
5709      o->in2 = load_freg(get_field(s, r2));
5710  }
5711  #define SPEC_in2_f2 0
5712  
in2_x2(DisasContext * s,DisasOps * o)5713  static void in2_x2(DisasContext *s, DisasOps *o)
5714  {
5715      o->in2_128 = load_freg_128(get_field(s, r2));
5716  }
5717  #define SPEC_in2_x2 SPEC_r2_f128
5718  
5719  /* Load the low double word of an extended (128-bit) format FP number */
in2_x2l(DisasContext * s,DisasOps * o)5720  static void in2_x2l(DisasContext *s, DisasOps *o)
5721  {
5722      o->in2 = load_freg(get_field(s, r2) + 2);
5723  }
5724  #define SPEC_in2_x2l SPEC_r2_f128
5725  
in2_ra2(DisasContext * s,DisasOps * o)5726  static void in2_ra2(DisasContext *s, DisasOps *o)
5727  {
5728      int r2 = get_field(s, r2);
5729  
5730      /* Note: *don't* treat !r2 as 0, use the reg value. */
5731      o->in2 = tcg_temp_new_i64();
5732      gen_addi_and_wrap_i64(s, o->in2, regs[r2], 0);
5733  }
5734  #define SPEC_in2_ra2 0
5735  
in2_ra2_E(DisasContext * s,DisasOps * o)5736  static void in2_ra2_E(DisasContext *s, DisasOps *o)
5737  {
5738      return in2_ra2(s, o);
5739  }
5740  #define SPEC_in2_ra2_E SPEC_r2_even
5741  
in2_a2(DisasContext * s,DisasOps * o)5742  static void in2_a2(DisasContext *s, DisasOps *o)
5743  {
5744      int x2 = have_field(s, x2) ? get_field(s, x2) : 0;
5745      o->in2 = get_address(s, x2, get_field(s, b2), get_field(s, d2));
5746  }
5747  #define SPEC_in2_a2 0
5748  
gen_ri2(DisasContext * s)5749  static TCGv gen_ri2(DisasContext *s)
5750  {
5751      TCGv ri2 = NULL;
5752      bool is_imm;
5753      int imm;
5754  
5755      disas_jdest(s, i2, is_imm, imm, ri2);
5756      if (is_imm) {
5757          ri2 = tcg_constant_i64(s->base.pc_next + (int64_t)imm * 2);
5758      }
5759  
5760      return ri2;
5761  }
5762  
in2_ri2(DisasContext * s,DisasOps * o)5763  static void in2_ri2(DisasContext *s, DisasOps *o)
5764  {
5765      o->in2 = gen_ri2(s);
5766  }
5767  #define SPEC_in2_ri2 0
5768  
in2_sh(DisasContext * s,DisasOps * o)5769  static void in2_sh(DisasContext *s, DisasOps *o)
5770  {
5771      int b2 = get_field(s, b2);
5772      int d2 = get_field(s, d2);
5773  
5774      if (b2 == 0) {
5775          o->in2 = tcg_constant_i64(d2 & 0x3f);
5776      } else {
5777          o->in2 = get_address(s, 0, b2, d2);
5778          tcg_gen_andi_i64(o->in2, o->in2, 0x3f);
5779      }
5780  }
5781  #define SPEC_in2_sh 0
5782  
in2_m2_8u(DisasContext * s,DisasOps * o)5783  static void in2_m2_8u(DisasContext *s, DisasOps *o)
5784  {
5785      in2_a2(s, o);
5786      tcg_gen_qemu_ld_i64(o->in2, o->in2, get_mem_index(s), MO_UB);
5787  }
5788  #define SPEC_in2_m2_8u 0
5789  
in2_m2_16s(DisasContext * s,DisasOps * o)5790  static void in2_m2_16s(DisasContext *s, DisasOps *o)
5791  {
5792      in2_a2(s, o);
5793      tcg_gen_qemu_ld_i64(o->in2, o->in2, get_mem_index(s), MO_TESW);
5794  }
5795  #define SPEC_in2_m2_16s 0
5796  
in2_m2_16u(DisasContext * s,DisasOps * o)5797  static void in2_m2_16u(DisasContext *s, DisasOps *o)
5798  {
5799      in2_a2(s, o);
5800      tcg_gen_qemu_ld_i64(o->in2, o->in2, get_mem_index(s), MO_TEUW);
5801  }
5802  #define SPEC_in2_m2_16u 0
5803  
in2_m2_32s(DisasContext * s,DisasOps * o)5804  static void in2_m2_32s(DisasContext *s, DisasOps *o)
5805  {
5806      in2_a2(s, o);
5807      tcg_gen_qemu_ld_i64(o->in2, o->in2, get_mem_index(s), MO_TESL);
5808  }
5809  #define SPEC_in2_m2_32s 0
5810  
in2_m2_32u(DisasContext * s,DisasOps * o)5811  static void in2_m2_32u(DisasContext *s, DisasOps *o)
5812  {
5813      in2_a2(s, o);
5814      tcg_gen_qemu_ld_i64(o->in2, o->in2, get_mem_index(s), MO_TEUL);
5815  }
5816  #define SPEC_in2_m2_32u 0
5817  
5818  #ifndef CONFIG_USER_ONLY
in2_m2_32ua(DisasContext * s,DisasOps * o)5819  static void in2_m2_32ua(DisasContext *s, DisasOps *o)
5820  {
5821      in2_a2(s, o);
5822      tcg_gen_qemu_ld_tl(o->in2, o->in2, get_mem_index(s), MO_TEUL | MO_ALIGN);
5823  }
5824  #define SPEC_in2_m2_32ua 0
5825  #endif
5826  
in2_m2_64(DisasContext * s,DisasOps * o)5827  static void in2_m2_64(DisasContext *s, DisasOps *o)
5828  {
5829      in2_a2(s, o);
5830      tcg_gen_qemu_ld_i64(o->in2, o->in2, get_mem_index(s), MO_TEUQ);
5831  }
5832  #define SPEC_in2_m2_64 0
5833  
in2_m2_64w(DisasContext * s,DisasOps * o)5834  static void in2_m2_64w(DisasContext *s, DisasOps *o)
5835  {
5836      in2_a2(s, o);
5837      tcg_gen_qemu_ld_i64(o->in2, o->in2, get_mem_index(s), MO_TEUQ);
5838      gen_addi_and_wrap_i64(s, o->in2, o->in2, 0);
5839  }
5840  #define SPEC_in2_m2_64w 0
5841  
5842  #ifndef CONFIG_USER_ONLY
in2_m2_64a(DisasContext * s,DisasOps * o)5843  static void in2_m2_64a(DisasContext *s, DisasOps *o)
5844  {
5845      in2_a2(s, o);
5846      tcg_gen_qemu_ld_i64(o->in2, o->in2, get_mem_index(s), MO_TEUQ | MO_ALIGN);
5847  }
5848  #define SPEC_in2_m2_64a 0
5849  #endif
5850  
in2_mri2_16s(DisasContext * s,DisasOps * o)5851  static void in2_mri2_16s(DisasContext *s, DisasOps *o)
5852  {
5853      o->in2 = tcg_temp_new_i64();
5854      tcg_gen_qemu_ld_i64(o->in2, gen_ri2(s), get_mem_index(s), MO_TESW);
5855  }
5856  #define SPEC_in2_mri2_16s 0
5857  
in2_mri2_16u(DisasContext * s,DisasOps * o)5858  static void in2_mri2_16u(DisasContext *s, DisasOps *o)
5859  {
5860      o->in2 = tcg_temp_new_i64();
5861      tcg_gen_qemu_ld_i64(o->in2, gen_ri2(s), get_mem_index(s), MO_TEUW);
5862  }
5863  #define SPEC_in2_mri2_16u 0
5864  
in2_mri2_32s(DisasContext * s,DisasOps * o)5865  static void in2_mri2_32s(DisasContext *s, DisasOps *o)
5866  {
5867      o->in2 = tcg_temp_new_i64();
5868      tcg_gen_qemu_ld_tl(o->in2, gen_ri2(s), get_mem_index(s),
5869                         MO_TESL | MO_ALIGN);
5870  }
5871  #define SPEC_in2_mri2_32s 0
5872  
in2_mri2_32u(DisasContext * s,DisasOps * o)5873  static void in2_mri2_32u(DisasContext *s, DisasOps *o)
5874  {
5875      o->in2 = tcg_temp_new_i64();
5876      tcg_gen_qemu_ld_tl(o->in2, gen_ri2(s), get_mem_index(s),
5877                         MO_TEUL | MO_ALIGN);
5878  }
5879  #define SPEC_in2_mri2_32u 0
5880  
in2_mri2_64(DisasContext * s,DisasOps * o)5881  static void in2_mri2_64(DisasContext *s, DisasOps *o)
5882  {
5883      o->in2 = tcg_temp_new_i64();
5884      tcg_gen_qemu_ld_i64(o->in2, gen_ri2(s), get_mem_index(s),
5885                          MO_TEUQ | MO_ALIGN);
5886  }
5887  #define SPEC_in2_mri2_64 0
5888  
in2_i2(DisasContext * s,DisasOps * o)5889  static void in2_i2(DisasContext *s, DisasOps *o)
5890  {
5891      o->in2 = tcg_constant_i64(get_field(s, i2));
5892  }
5893  #define SPEC_in2_i2 0
5894  
in2_i2_8u(DisasContext * s,DisasOps * o)5895  static void in2_i2_8u(DisasContext *s, DisasOps *o)
5896  {
5897      o->in2 = tcg_constant_i64((uint8_t)get_field(s, i2));
5898  }
5899  #define SPEC_in2_i2_8u 0
5900  
in2_i2_16u(DisasContext * s,DisasOps * o)5901  static void in2_i2_16u(DisasContext *s, DisasOps *o)
5902  {
5903      o->in2 = tcg_constant_i64((uint16_t)get_field(s, i2));
5904  }
5905  #define SPEC_in2_i2_16u 0
5906  
in2_i2_32u(DisasContext * s,DisasOps * o)5907  static void in2_i2_32u(DisasContext *s, DisasOps *o)
5908  {
5909      o->in2 = tcg_constant_i64((uint32_t)get_field(s, i2));
5910  }
5911  #define SPEC_in2_i2_32u 0
5912  
in2_i2_16u_shl(DisasContext * s,DisasOps * o)5913  static void in2_i2_16u_shl(DisasContext *s, DisasOps *o)
5914  {
5915      uint64_t i2 = (uint16_t)get_field(s, i2);
5916      o->in2 = tcg_constant_i64(i2 << s->insn->data);
5917  }
5918  #define SPEC_in2_i2_16u_shl 0
5919  
in2_i2_32u_shl(DisasContext * s,DisasOps * o)5920  static void in2_i2_32u_shl(DisasContext *s, DisasOps *o)
5921  {
5922      uint64_t i2 = (uint32_t)get_field(s, i2);
5923      o->in2 = tcg_constant_i64(i2 << s->insn->data);
5924  }
5925  #define SPEC_in2_i2_32u_shl 0
5926  
5927  #ifndef CONFIG_USER_ONLY
in2_insn(DisasContext * s,DisasOps * o)5928  static void in2_insn(DisasContext *s, DisasOps *o)
5929  {
5930      o->in2 = tcg_constant_i64(s->fields.raw_insn);
5931  }
5932  #define SPEC_in2_insn 0
5933  #endif
5934  
5935  /* ====================================================================== */
5936  
5937  /* Find opc within the table of insns.  This is formulated as a switch
5938     statement so that (1) we get compile-time notice of cut-paste errors
5939     for duplicated opcodes, and (2) the compiler generates the binary
5940     search tree, rather than us having to post-process the table.  */
5941  
5942  #define C(OPC, NM, FT, FC, I1, I2, P, W, OP, CC) \
5943      E(OPC, NM, FT, FC, I1, I2, P, W, OP, CC, 0, 0)
5944  
5945  #define D(OPC, NM, FT, FC, I1, I2, P, W, OP, CC, D) \
5946      E(OPC, NM, FT, FC, I1, I2, P, W, OP, CC, D, 0)
5947  
5948  #define F(OPC, NM, FT, FC, I1, I2, P, W, OP, CC, FL) \
5949      E(OPC, NM, FT, FC, I1, I2, P, W, OP, CC, 0, FL)
5950  
5951  #define E(OPC, NM, FT, FC, I1, I2, P, W, OP, CC, D, FL) insn_ ## NM,
5952  
5953  enum DisasInsnEnum {
5954  #include "insn-data.h.inc"
5955  };
5956  
5957  #undef E
5958  #define E(OPC, NM, FT, FC, I1, I2, P, W, OP, CC, D, FL) {                   \
5959      .opc = OPC,                                                             \
5960      .flags = FL,                                                            \
5961      .fmt = FMT_##FT,                                                        \
5962      .fac = FAC_##FC,                                                        \
5963      .spec = SPEC_in1_##I1 | SPEC_in2_##I2 | SPEC_prep_##P | SPEC_wout_##W,  \
5964      .name = #NM,                                                            \
5965      .help_in1 = in1_##I1,                                                   \
5966      .help_in2 = in2_##I2,                                                   \
5967      .help_prep = prep_##P,                                                  \
5968      .help_wout = wout_##W,                                                  \
5969      .help_cout = cout_##CC,                                                 \
5970      .help_op = op_##OP,                                                     \
5971      .data = D                                                               \
5972   },
5973  
5974  /* Allow 0 to be used for NULL in the table below.  */
5975  #define in1_0  NULL
5976  #define in2_0  NULL
5977  #define prep_0  NULL
5978  #define wout_0  NULL
5979  #define cout_0  NULL
5980  #define op_0  NULL
5981  
5982  #define SPEC_in1_0 0
5983  #define SPEC_in2_0 0
5984  #define SPEC_prep_0 0
5985  #define SPEC_wout_0 0
5986  
5987  /* Give smaller names to the various facilities.  */
5988  #define FAC_Z           S390_FEAT_ZARCH
5989  #define FAC_CASS        S390_FEAT_COMPARE_AND_SWAP_AND_STORE
5990  #define FAC_DFP         S390_FEAT_DFP
5991  #define FAC_DFPR        S390_FEAT_FLOATING_POINT_SUPPORT_ENH /* DFP-rounding */
5992  #define FAC_DO          S390_FEAT_STFLE_45 /* distinct-operands */
5993  #define FAC_EE          S390_FEAT_EXECUTE_EXT
5994  #define FAC_EI          S390_FEAT_EXTENDED_IMMEDIATE
5995  #define FAC_FPE         S390_FEAT_FLOATING_POINT_EXT
5996  #define FAC_FPSSH       S390_FEAT_FLOATING_POINT_SUPPORT_ENH /* FPS-sign-handling */
5997  #define FAC_FPRGR       S390_FEAT_FLOATING_POINT_SUPPORT_ENH /* FPR-GR-transfer */
5998  #define FAC_GIE         S390_FEAT_GENERAL_INSTRUCTIONS_EXT
5999  #define FAC_HFP_MA      S390_FEAT_HFP_MADDSUB
6000  #define FAC_HW          S390_FEAT_STFLE_45 /* high-word */
6001  #define FAC_IEEEE_SIM   S390_FEAT_FLOATING_POINT_SUPPORT_ENH /* IEEE-exception-simulation */
6002  #define FAC_MIE         S390_FEAT_STFLE_49 /* misc-instruction-extensions */
6003  #define FAC_LAT         S390_FEAT_STFLE_49 /* load-and-trap */
6004  #define FAC_LOC         S390_FEAT_STFLE_45 /* load/store on condition 1 */
6005  #define FAC_LOC2        S390_FEAT_STFLE_53 /* load/store on condition 2 */
6006  #define FAC_LD          S390_FEAT_LONG_DISPLACEMENT
6007  #define FAC_PC          S390_FEAT_STFLE_45 /* population count */
6008  #define FAC_SCF         S390_FEAT_STORE_CLOCK_FAST
6009  #define FAC_SFLE        S390_FEAT_STFLE
6010  #define FAC_ILA         S390_FEAT_STFLE_45 /* interlocked-access-facility 1 */
6011  #define FAC_MVCOS       S390_FEAT_MOVE_WITH_OPTIONAL_SPEC
6012  #define FAC_LPP         S390_FEAT_SET_PROGRAM_PARAMETERS /* load-program-parameter */
6013  #define FAC_DAT_ENH     S390_FEAT_DAT_ENH
6014  #define FAC_E2          S390_FEAT_EXTENDED_TRANSLATION_2
6015  #define FAC_EH          S390_FEAT_STFLE_49 /* execution-hint */
6016  #define FAC_PPA         S390_FEAT_STFLE_49 /* processor-assist */
6017  #define FAC_LZRB        S390_FEAT_STFLE_53 /* load-and-zero-rightmost-byte */
6018  #define FAC_ETF3        S390_FEAT_EXTENDED_TRANSLATION_3
6019  #define FAC_MSA         S390_FEAT_MSA /* message-security-assist facility */
6020  #define FAC_MSA3        S390_FEAT_MSA_EXT_3 /* msa-extension-3 facility */
6021  #define FAC_MSA4        S390_FEAT_MSA_EXT_4 /* msa-extension-4 facility */
6022  #define FAC_MSA5        S390_FEAT_MSA_EXT_5 /* msa-extension-5 facility */
6023  #define FAC_MSA8        S390_FEAT_MSA_EXT_8 /* msa-extension-8 facility */
6024  #define FAC_ECT         S390_FEAT_EXTRACT_CPU_TIME
6025  #define FAC_PCI         S390_FEAT_ZPCI /* z/PCI facility */
6026  #define FAC_AIS         S390_FEAT_ADAPTER_INT_SUPPRESSION
6027  #define FAC_V           S390_FEAT_VECTOR /* vector facility */
6028  #define FAC_VE          S390_FEAT_VECTOR_ENH  /* vector enhancements facility 1 */
6029  #define FAC_VE2         S390_FEAT_VECTOR_ENH2 /* vector enhancements facility 2 */
6030  #define FAC_MIE2        S390_FEAT_MISC_INSTRUCTION_EXT2 /* miscellaneous-instruction-extensions facility 2 */
6031  #define FAC_MIE3        S390_FEAT_MISC_INSTRUCTION_EXT3 /* miscellaneous-instruction-extensions facility 3 */
6032  
6033  static const DisasInsn insn_info[] = {
6034  #include "insn-data.h.inc"
6035  };
6036  
6037  #undef E
6038  #define E(OPC, NM, FT, FC, I1, I2, P, W, OP, CC, D, FL) \
6039      case OPC: return &insn_info[insn_ ## NM];
6040  
lookup_opc(uint16_t opc)6041  static const DisasInsn *lookup_opc(uint16_t opc)
6042  {
6043      switch (opc) {
6044  #include "insn-data.h.inc"
6045      default:
6046          return NULL;
6047      }
6048  }
6049  
6050  #undef F
6051  #undef E
6052  #undef D
6053  #undef C
6054  
6055  /* Extract a field from the insn.  The INSN should be left-aligned in
6056     the uint64_t so that we can more easily utilize the big-bit-endian
6057     definitions we extract from the Principals of Operation.  */
6058  
extract_field(DisasFields * o,const DisasField * f,uint64_t insn)6059  static void extract_field(DisasFields *o, const DisasField *f, uint64_t insn)
6060  {
6061      uint32_t r, m;
6062  
6063      if (f->size == 0) {
6064          return;
6065      }
6066  
6067      /* Zero extract the field from the insn.  */
6068      r = (insn << f->beg) >> (64 - f->size);
6069  
6070      /* Sign-extend, or un-swap the field as necessary.  */
6071      switch (f->type) {
6072      case 0: /* unsigned */
6073          break;
6074      case 1: /* signed */
6075          assert(f->size <= 32);
6076          m = 1u << (f->size - 1);
6077          r = (r ^ m) - m;
6078          break;
6079      case 2: /* dl+dh split, signed 20 bit. */
6080          r = ((int8_t)r << 12) | (r >> 8);
6081          break;
6082      case 3: /* MSB stored in RXB */
6083          g_assert(f->size == 4);
6084          switch (f->beg) {
6085          case 8:
6086              r |= extract64(insn, 63 - 36, 1) << 4;
6087              break;
6088          case 12:
6089              r |= extract64(insn, 63 - 37, 1) << 4;
6090              break;
6091          case 16:
6092              r |= extract64(insn, 63 - 38, 1) << 4;
6093              break;
6094          case 32:
6095              r |= extract64(insn, 63 - 39, 1) << 4;
6096              break;
6097          default:
6098              g_assert_not_reached();
6099          }
6100          break;
6101      default:
6102          abort();
6103      }
6104  
6105      /*
6106       * Validate that the "compressed" encoding we selected above is valid.
6107       * I.e. we haven't made two different original fields overlap.
6108       */
6109      assert(((o->presentC >> f->indexC) & 1) == 0);
6110      o->presentC |= 1 << f->indexC;
6111      o->presentO |= 1 << f->indexO;
6112  
6113      o->c[f->indexC] = r;
6114  }
6115  
6116  /* Lookup the insn at the current PC, extracting the operands into O and
6117     returning the info struct for the insn.  Returns NULL for invalid insn.  */
6118  
extract_insn(CPUS390XState * env,DisasContext * s)6119  static const DisasInsn *extract_insn(CPUS390XState *env, DisasContext *s)
6120  {
6121      uint64_t insn, pc = s->base.pc_next;
6122      int op, op2, ilen;
6123      const DisasInsn *info;
6124  
6125      if (unlikely(s->ex_value)) {
6126          uint64_t be_insn;
6127  
6128          /* Drop the EX data now, so that it's clear on exception paths.  */
6129          tcg_gen_st_i64(tcg_constant_i64(0), tcg_env,
6130                         offsetof(CPUS390XState, ex_value));
6131  
6132          /* Extract the values saved by EXECUTE.  */
6133          insn = s->ex_value & 0xffffffffffff0000ull;
6134          ilen = s->ex_value & 0xf;
6135          op = insn >> 56;
6136  
6137          /* Register insn bytes with translator so plugins work. */
6138          be_insn = cpu_to_be64(insn);
6139          translator_fake_ld(&s->base, &be_insn, get_ilen(op));
6140      } else {
6141          insn = ld_code2(env, s, pc);
6142          op = (insn >> 8) & 0xff;
6143          ilen = get_ilen(op);
6144          switch (ilen) {
6145          case 2:
6146              insn = insn << 48;
6147              break;
6148          case 4:
6149              insn = ld_code4(env, s, pc) << 32;
6150              break;
6151          case 6:
6152              insn = (insn << 48) | (ld_code4(env, s, pc + 2) << 16);
6153              break;
6154          default:
6155              g_assert_not_reached();
6156          }
6157      }
6158      s->pc_tmp = s->base.pc_next + ilen;
6159      s->ilen = ilen;
6160  
6161      /* We can't actually determine the insn format until we've looked up
6162         the full insn opcode.  Which we can't do without locating the
6163         secondary opcode.  Assume by default that OP2 is at bit 40; for
6164         those smaller insns that don't actually have a secondary opcode
6165         this will correctly result in OP2 = 0. */
6166      switch (op) {
6167      case 0x01: /* E */
6168      case 0x80: /* S */
6169      case 0x82: /* S */
6170      case 0x93: /* S */
6171      case 0xb2: /* S, RRF, RRE, IE */
6172      case 0xb3: /* RRE, RRD, RRF */
6173      case 0xb9: /* RRE, RRF */
6174      case 0xe5: /* SSE, SIL */
6175          op2 = (insn << 8) >> 56;
6176          break;
6177      case 0xa5: /* RI */
6178      case 0xa7: /* RI */
6179      case 0xc0: /* RIL */
6180      case 0xc2: /* RIL */
6181      case 0xc4: /* RIL */
6182      case 0xc6: /* RIL */
6183      case 0xc8: /* SSF */
6184      case 0xcc: /* RIL */
6185          op2 = (insn << 12) >> 60;
6186          break;
6187      case 0xc5: /* MII */
6188      case 0xc7: /* SMI */
6189      case 0xd0 ... 0xdf: /* SS */
6190      case 0xe1: /* SS */
6191      case 0xe2: /* SS */
6192      case 0xe8: /* SS */
6193      case 0xe9: /* SS */
6194      case 0xea: /* SS */
6195      case 0xee ... 0xf3: /* SS */
6196      case 0xf8 ... 0xfd: /* SS */
6197          op2 = 0;
6198          break;
6199      default:
6200          op2 = (insn << 40) >> 56;
6201          break;
6202      }
6203  
6204      memset(&s->fields, 0, sizeof(s->fields));
6205      s->fields.raw_insn = insn;
6206      s->fields.op = op;
6207      s->fields.op2 = op2;
6208  
6209      /* Lookup the instruction.  */
6210      info = lookup_opc(op << 8 | op2);
6211      s->insn = info;
6212  
6213      /* If we found it, extract the operands.  */
6214      if (info != NULL) {
6215          DisasFormat fmt = info->fmt;
6216          int i;
6217  
6218          for (i = 0; i < NUM_C_FIELD; ++i) {
6219              extract_field(&s->fields, &format_info[fmt].op[i], insn);
6220          }
6221      }
6222      return info;
6223  }
6224  
is_afp_reg(int reg)6225  static bool is_afp_reg(int reg)
6226  {
6227      return reg % 2 || reg > 6;
6228  }
6229  
is_fp_pair(int reg)6230  static bool is_fp_pair(int reg)
6231  {
6232      /* 0,1,4,5,8,9,12,13: to exclude the others, check for single bit */
6233      return !(reg & 0x2);
6234  }
6235  
translate_one(CPUS390XState * env,DisasContext * s)6236  static DisasJumpType translate_one(CPUS390XState *env, DisasContext *s)
6237  {
6238      const DisasInsn *insn;
6239      DisasJumpType ret = DISAS_NEXT;
6240      DisasOps o = {};
6241      bool icount = false;
6242  
6243      /* Search for the insn in the table.  */
6244      insn = extract_insn(env, s);
6245  
6246      /* Update insn_start now that we know the ILEN.  */
6247      tcg_set_insn_start_param(s->base.insn_start, 2, s->ilen);
6248  
6249      /* Not found means unimplemented/illegal opcode.  */
6250      if (insn == NULL) {
6251          qemu_log_mask(LOG_UNIMP, "unimplemented opcode 0x%02x%02x\n",
6252                        s->fields.op, s->fields.op2);
6253          gen_illegal_opcode(s);
6254          ret = DISAS_NORETURN;
6255          goto out;
6256      }
6257  
6258  #ifndef CONFIG_USER_ONLY
6259      if (s->base.tb->flags & FLAG_MASK_PER_IFETCH) {
6260          /* With ifetch set, psw_addr and cc_op are always up-to-date. */
6261          gen_helper_per_ifetch(tcg_env, tcg_constant_i32(s->ilen));
6262      }
6263  #endif
6264  
6265      /* process flags */
6266      if (insn->flags) {
6267          /* privileged instruction */
6268          if ((s->base.tb->flags & FLAG_MASK_PSTATE) && (insn->flags & IF_PRIV)) {
6269              gen_program_exception(s, PGM_PRIVILEGED);
6270              ret = DISAS_NORETURN;
6271              goto out;
6272          }
6273  
6274          /* if AFP is not enabled, instructions and registers are forbidden */
6275          if (!(s->base.tb->flags & FLAG_MASK_AFP)) {
6276              uint8_t dxc = 0;
6277  
6278              if ((insn->flags & IF_AFP1) && is_afp_reg(get_field(s, r1))) {
6279                  dxc = 1;
6280              }
6281              if ((insn->flags & IF_AFP2) && is_afp_reg(get_field(s, r2))) {
6282                  dxc = 1;
6283              }
6284              if ((insn->flags & IF_AFP3) && is_afp_reg(get_field(s, r3))) {
6285                  dxc = 1;
6286              }
6287              if (insn->flags & IF_BFP) {
6288                  dxc = 2;
6289              }
6290              if (insn->flags & IF_DFP) {
6291                  dxc = 3;
6292              }
6293              if (insn->flags & IF_VEC) {
6294                  dxc = 0xfe;
6295              }
6296              if (dxc) {
6297                  gen_data_exception(dxc);
6298                  ret = DISAS_NORETURN;
6299                  goto out;
6300              }
6301          }
6302  
6303          /* if vector instructions not enabled, executing them is forbidden */
6304          if (insn->flags & IF_VEC) {
6305              if (!((s->base.tb->flags & FLAG_MASK_VECTOR))) {
6306                  gen_data_exception(0xfe);
6307                  ret = DISAS_NORETURN;
6308                  goto out;
6309              }
6310          }
6311  
6312          /* input/output is the special case for icount mode */
6313          if (unlikely(insn->flags & IF_IO)) {
6314              icount = translator_io_start(&s->base);
6315          }
6316      }
6317  
6318      /* Check for insn specification exceptions.  */
6319      if (insn->spec) {
6320          if ((insn->spec & SPEC_r1_even && get_field(s, r1) & 1) ||
6321              (insn->spec & SPEC_r2_even && get_field(s, r2) & 1) ||
6322              (insn->spec & SPEC_r3_even && get_field(s, r3) & 1) ||
6323              (insn->spec & SPEC_r1_f128 && !is_fp_pair(get_field(s, r1))) ||
6324              (insn->spec & SPEC_r2_f128 && !is_fp_pair(get_field(s, r2)))) {
6325              gen_program_exception(s, PGM_SPECIFICATION);
6326              ret = DISAS_NORETURN;
6327              goto out;
6328          }
6329      }
6330  
6331      /* Implement the instruction.  */
6332      if (insn->help_in1) {
6333          insn->help_in1(s, &o);
6334      }
6335      if (insn->help_in2) {
6336          insn->help_in2(s, &o);
6337      }
6338      if (insn->help_prep) {
6339          insn->help_prep(s, &o);
6340      }
6341      if (insn->help_op) {
6342          ret = insn->help_op(s, &o);
6343          if (ret == DISAS_NORETURN) {
6344              goto out;
6345          }
6346      }
6347      if (insn->help_wout) {
6348          insn->help_wout(s, &o);
6349      }
6350      if (insn->help_cout) {
6351          insn->help_cout(s, &o);
6352      }
6353  
6354      /* io should be the last instruction in tb when icount is enabled */
6355      if (unlikely(icount && ret == DISAS_NEXT)) {
6356          ret = DISAS_TOO_MANY;
6357      }
6358  
6359  #ifndef CONFIG_USER_ONLY
6360      if (s->base.tb->flags & FLAG_MASK_PER_IFETCH) {
6361          switch (ret) {
6362          case DISAS_TOO_MANY:
6363              s->base.is_jmp = DISAS_PC_CC_UPDATED;
6364              /* fall through */
6365          case DISAS_NEXT:
6366              tcg_gen_movi_i64(psw_addr, s->pc_tmp);
6367              break;
6368          default:
6369              break;
6370          }
6371          update_cc_op(s);
6372          gen_helper_per_check_exception(tcg_env);
6373      }
6374  #endif
6375  
6376  out:
6377      /* Advance to the next instruction.  */
6378      s->base.pc_next = s->pc_tmp;
6379      return ret;
6380  }
6381  
s390x_tr_init_disas_context(DisasContextBase * dcbase,CPUState * cs)6382  static void s390x_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
6383  {
6384      DisasContext *dc = container_of(dcbase, DisasContext, base);
6385  
6386      /* 31-bit mode */
6387      if (!(dc->base.tb->flags & FLAG_MASK_64)) {
6388          dc->base.pc_first &= 0x7fffffff;
6389          dc->base.pc_next = dc->base.pc_first;
6390      }
6391  
6392      dc->cc_op = CC_OP_DYNAMIC;
6393      dc->ex_value = dc->base.tb->cs_base;
6394      dc->exit_to_mainloop = dc->ex_value;
6395  }
6396  
s390x_tr_tb_start(DisasContextBase * db,CPUState * cs)6397  static void s390x_tr_tb_start(DisasContextBase *db, CPUState *cs)
6398  {
6399  }
6400  
s390x_tr_insn_start(DisasContextBase * dcbase,CPUState * cs)6401  static void s390x_tr_insn_start(DisasContextBase *dcbase, CPUState *cs)
6402  {
6403      DisasContext *dc = container_of(dcbase, DisasContext, base);
6404  
6405      /* Delay the set of ilen until we've read the insn. */
6406      tcg_gen_insn_start(dc->base.pc_next, dc->cc_op, 0);
6407  }
6408  
get_next_pc(CPUS390XState * env,DisasContext * s,uint64_t pc)6409  static target_ulong get_next_pc(CPUS390XState *env, DisasContext *s,
6410                                  uint64_t pc)
6411  {
6412      uint64_t insn = translator_lduw(env, &s->base, pc);
6413  
6414      return pc + get_ilen((insn >> 8) & 0xff);
6415  }
6416  
s390x_tr_translate_insn(DisasContextBase * dcbase,CPUState * cs)6417  static void s390x_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
6418  {
6419      CPUS390XState *env = cpu_env(cs);
6420      DisasContext *dc = container_of(dcbase, DisasContext, base);
6421  
6422      dc->base.is_jmp = translate_one(env, dc);
6423      if (dc->base.is_jmp == DISAS_NEXT) {
6424          if (dc->ex_value ||
6425              !is_same_page(dcbase, dc->base.pc_next) ||
6426              !is_same_page(dcbase, get_next_pc(env, dc, dc->base.pc_next))) {
6427              dc->base.is_jmp = DISAS_TOO_MANY;
6428          }
6429      }
6430  }
6431  
s390x_tr_tb_stop(DisasContextBase * dcbase,CPUState * cs)6432  static void s390x_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
6433  {
6434      DisasContext *dc = container_of(dcbase, DisasContext, base);
6435  
6436      switch (dc->base.is_jmp) {
6437      case DISAS_NORETURN:
6438          break;
6439      case DISAS_TOO_MANY:
6440          update_psw_addr(dc);
6441          /* FALLTHRU */
6442      case DISAS_PC_UPDATED:
6443          /* Next TB starts off with CC_OP_DYNAMIC, so make sure the
6444             cc op type is in env */
6445          update_cc_op(dc);
6446          /* FALLTHRU */
6447      case DISAS_PC_CC_UPDATED:
6448          /* Exit the TB, either by raising a debug exception or by return.  */
6449          if (dc->exit_to_mainloop) {
6450              tcg_gen_exit_tb(NULL, 0);
6451          } else {
6452              tcg_gen_lookup_and_goto_ptr();
6453          }
6454          break;
6455      default:
6456          g_assert_not_reached();
6457      }
6458  }
6459  
s390x_tr_disas_log(const DisasContextBase * dcbase,CPUState * cs,FILE * logfile)6460  static bool s390x_tr_disas_log(const DisasContextBase *dcbase,
6461                                 CPUState *cs, FILE *logfile)
6462  {
6463      DisasContext *dc = container_of(dcbase, DisasContext, base);
6464  
6465      if (unlikely(dc->ex_value)) {
6466          /* The ex_value has been recorded with translator_fake_ld. */
6467          fprintf(logfile, "IN: EXECUTE\n");
6468          target_disas(logfile, cs, &dc->base);
6469          return true;
6470      }
6471      return false;
6472  }
6473  
6474  static const TranslatorOps s390x_tr_ops = {
6475      .init_disas_context = s390x_tr_init_disas_context,
6476      .tb_start           = s390x_tr_tb_start,
6477      .insn_start         = s390x_tr_insn_start,
6478      .translate_insn     = s390x_tr_translate_insn,
6479      .tb_stop            = s390x_tr_tb_stop,
6480      .disas_log          = s390x_tr_disas_log,
6481  };
6482  
gen_intermediate_code(CPUState * cs,TranslationBlock * tb,int * max_insns,vaddr pc,void * host_pc)6483  void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int *max_insns,
6484                             vaddr pc, void *host_pc)
6485  {
6486      DisasContext dc;
6487  
6488      translator_loop(cs, tb, max_insns, pc, host_pc, &s390x_tr_ops, &dc.base);
6489  }
6490  
s390x_restore_state_to_opc(CPUState * cs,const TranslationBlock * tb,const uint64_t * data)6491  void s390x_restore_state_to_opc(CPUState *cs,
6492                                  const TranslationBlock *tb,
6493                                  const uint64_t *data)
6494  {
6495      CPUS390XState *env = cpu_env(cs);
6496      int cc_op = data[1];
6497  
6498      env->psw.addr = data[0];
6499  
6500      /* Update the CC opcode if it is not already up-to-date.  */
6501      if ((cc_op != CC_OP_DYNAMIC) && (cc_op != CC_OP_STATIC)) {
6502          env->cc_op = cc_op;
6503      }
6504  
6505      /* Record ILEN.  */
6506      env->int_pgm_ilen = data[2];
6507  }
6508