Statistics
| Branch: | Revision:

root / target-s390x / translate.c @ 6ac1b45f

History | View | Annotate | Download (116.3 kB)

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 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 "cpu.h"
32
#include "disas/disas.h"
33
#include "tcg-op.h"
34
#include "qemu/log.h"
35
#include "qemu/host-utils.h"
36

    
37
/* global register indexes */
38
static TCGv_ptr cpu_env;
39

    
40
#include "exec/gen-icount.h"
41
#include "helper.h"
42
#define GEN_HELPER 1
43
#include "helper.h"
44

    
45

    
46
/* Information that (most) every instruction needs to manipulate.  */
47
typedef struct DisasContext DisasContext;
48
typedef struct DisasInsn DisasInsn;
49
typedef struct DisasFields DisasFields;
50

    
51
struct DisasContext {
52
    struct TranslationBlock *tb;
53
    const DisasInsn *insn;
54
    DisasFields *fields;
55
    uint64_t pc, next_pc;
56
    enum cc_op cc_op;
57
    bool singlestep_enabled;
58
};
59

    
60
/* Information carried about a condition to be evaluated.  */
61
typedef struct {
62
    TCGCond cond:8;
63
    bool is_64;
64
    bool g1;
65
    bool g2;
66
    union {
67
        struct { TCGv_i64 a, b; } s64;
68
        struct { TCGv_i32 a, b; } s32;
69
    } u;
70
} DisasCompare;
71

    
72
#define DISAS_EXCP 4
73

    
74
#ifdef DEBUG_INLINE_BRANCHES
75
static uint64_t inline_branch_hit[CC_OP_MAX];
76
static uint64_t inline_branch_miss[CC_OP_MAX];
77
#endif
78

    
79
static uint64_t pc_to_link_info(DisasContext *s, uint64_t pc)
80
{
81
    if (!(s->tb->flags & FLAG_MASK_64)) {
82
        if (s->tb->flags & FLAG_MASK_32) {
83
            return pc | 0x80000000;
84
        }
85
    }
86
    return pc;
87
}
88

    
89
void cpu_dump_state(CPUS390XState *env, FILE *f, fprintf_function cpu_fprintf,
90
                    int flags)
91
{
92
    int i;
93

    
94
    if (env->cc_op > 3) {
95
        cpu_fprintf(f, "PSW=mask %016" PRIx64 " addr %016" PRIx64 " cc %15s\n",
96
                    env->psw.mask, env->psw.addr, cc_name(env->cc_op));
97
    } else {
98
        cpu_fprintf(f, "PSW=mask %016" PRIx64 " addr %016" PRIx64 " cc %02x\n",
99
                    env->psw.mask, env->psw.addr, env->cc_op);
100
    }
101

    
102
    for (i = 0; i < 16; i++) {
103
        cpu_fprintf(f, "R%02d=%016" PRIx64, i, env->regs[i]);
104
        if ((i % 4) == 3) {
105
            cpu_fprintf(f, "\n");
106
        } else {
107
            cpu_fprintf(f, " ");
108
        }
109
    }
110

    
111
    for (i = 0; i < 16; i++) {
112
        cpu_fprintf(f, "F%02d=%016" PRIx64, i, env->fregs[i].ll);
113
        if ((i % 4) == 3) {
114
            cpu_fprintf(f, "\n");
115
        } else {
116
            cpu_fprintf(f, " ");
117
        }
118
    }
119

    
120
#ifndef CONFIG_USER_ONLY
121
    for (i = 0; i < 16; i++) {
122
        cpu_fprintf(f, "C%02d=%016" PRIx64, i, env->cregs[i]);
123
        if ((i % 4) == 3) {
124
            cpu_fprintf(f, "\n");
125
        } else {
126
            cpu_fprintf(f, " ");
127
        }
128
    }
129
#endif
130

    
131
#ifdef DEBUG_INLINE_BRANCHES
132
    for (i = 0; i < CC_OP_MAX; i++) {
133
        cpu_fprintf(f, "  %15s = %10ld\t%10ld\n", cc_name(i),
134
                    inline_branch_miss[i], inline_branch_hit[i]);
135
    }
136
#endif
137

    
138
    cpu_fprintf(f, "\n");
139
}
140

    
141
static TCGv_i64 psw_addr;
142
static TCGv_i64 psw_mask;
143

    
144
static TCGv_i32 cc_op;
145
static TCGv_i64 cc_src;
146
static TCGv_i64 cc_dst;
147
static TCGv_i64 cc_vr;
148

    
149
static char cpu_reg_names[32][4];
150
static TCGv_i64 regs[16];
151
static TCGv_i64 fregs[16];
152

    
153
static uint8_t gen_opc_cc_op[OPC_BUF_SIZE];
154

    
155
void s390x_translate_init(void)
156
{
157
    int i;
158

    
159
    cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
160
    psw_addr = tcg_global_mem_new_i64(TCG_AREG0,
161
                                      offsetof(CPUS390XState, psw.addr),
162
                                      "psw_addr");
163
    psw_mask = tcg_global_mem_new_i64(TCG_AREG0,
164
                                      offsetof(CPUS390XState, psw.mask),
165
                                      "psw_mask");
166

    
167
    cc_op = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUS390XState, cc_op),
168
                                   "cc_op");
169
    cc_src = tcg_global_mem_new_i64(TCG_AREG0, offsetof(CPUS390XState, cc_src),
170
                                    "cc_src");
171
    cc_dst = tcg_global_mem_new_i64(TCG_AREG0, offsetof(CPUS390XState, cc_dst),
172
                                    "cc_dst");
173
    cc_vr = tcg_global_mem_new_i64(TCG_AREG0, offsetof(CPUS390XState, cc_vr),
174
                                   "cc_vr");
175

    
176
    for (i = 0; i < 16; i++) {
177
        snprintf(cpu_reg_names[i], sizeof(cpu_reg_names[0]), "r%d", i);
178
        regs[i] = tcg_global_mem_new(TCG_AREG0,
179
                                     offsetof(CPUS390XState, regs[i]),
180
                                     cpu_reg_names[i]);
181
    }
182

    
183
    for (i = 0; i < 16; i++) {
184
        snprintf(cpu_reg_names[i + 16], sizeof(cpu_reg_names[0]), "f%d", i);
185
        fregs[i] = tcg_global_mem_new(TCG_AREG0,
186
                                      offsetof(CPUS390XState, fregs[i].d),
187
                                      cpu_reg_names[i + 16]);
188
    }
189

    
190
    /* register helpers */
191
#define GEN_HELPER 2
192
#include "helper.h"
193
}
194

    
195
static TCGv_i64 load_reg(int reg)
196
{
197
    TCGv_i64 r = tcg_temp_new_i64();
198
    tcg_gen_mov_i64(r, regs[reg]);
199
    return r;
200
}
201

    
202
static TCGv_i64 load_freg32_i64(int reg)
203
{
204
    TCGv_i64 r = tcg_temp_new_i64();
205
    tcg_gen_shri_i64(r, fregs[reg], 32);
206
    return r;
207
}
208

    
209
static void store_reg(int reg, TCGv_i64 v)
210
{
211
    tcg_gen_mov_i64(regs[reg], v);
212
}
213

    
214
static void store_freg(int reg, TCGv_i64 v)
215
{
216
    tcg_gen_mov_i64(fregs[reg], v);
217
}
218

    
219
static void store_reg32_i64(int reg, TCGv_i64 v)
220
{
221
    /* 32 bit register writes keep the upper half */
222
    tcg_gen_deposit_i64(regs[reg], regs[reg], v, 0, 32);
223
}
224

    
225
static void store_reg32h_i64(int reg, TCGv_i64 v)
226
{
227
    tcg_gen_deposit_i64(regs[reg], regs[reg], v, 32, 32);
228
}
229

    
230
static void store_freg32_i64(int reg, TCGv_i64 v)
231
{
232
    tcg_gen_deposit_i64(fregs[reg], fregs[reg], v, 32, 32);
233
}
234

    
235
static void return_low128(TCGv_i64 dest)
236
{
237
    tcg_gen_ld_i64(dest, cpu_env, offsetof(CPUS390XState, retxl));
238
}
239

    
240
static void update_psw_addr(DisasContext *s)
241
{
242
    /* psw.addr */
243
    tcg_gen_movi_i64(psw_addr, s->pc);
244
}
245

    
246
static void update_cc_op(DisasContext *s)
247
{
248
    if (s->cc_op != CC_OP_DYNAMIC && s->cc_op != CC_OP_STATIC) {
249
        tcg_gen_movi_i32(cc_op, s->cc_op);
250
    }
251
}
252

    
253
static void potential_page_fault(DisasContext *s)
254
{
255
    update_psw_addr(s);
256
    update_cc_op(s);
257
}
258

    
259
static inline uint64_t ld_code2(CPUS390XState *env, uint64_t pc)
260
{
261
    return (uint64_t)cpu_lduw_code(env, pc);
262
}
263

    
264
static inline uint64_t ld_code4(CPUS390XState *env, uint64_t pc)
265
{
266
    return (uint64_t)(uint32_t)cpu_ldl_code(env, pc);
267
}
268

    
269
static inline uint64_t ld_code6(CPUS390XState *env, uint64_t pc)
270
{
271
    return (ld_code2(env, pc) << 32) | ld_code4(env, pc + 2);
272
}
273

    
274
static int get_mem_index(DisasContext *s)
275
{
276
    switch (s->tb->flags & FLAG_MASK_ASC) {
277
    case PSW_ASC_PRIMARY >> 32:
278
        return 0;
279
    case PSW_ASC_SECONDARY >> 32:
280
        return 1;
281
    case PSW_ASC_HOME >> 32:
282
        return 2;
283
    default:
284
        tcg_abort();
285
        break;
286
    }
287
}
288

    
289
static void gen_exception(int excp)
290
{
291
    TCGv_i32 tmp = tcg_const_i32(excp);
292
    gen_helper_exception(cpu_env, tmp);
293
    tcg_temp_free_i32(tmp);
294
}
295

    
296
static void gen_program_exception(DisasContext *s, int code)
297
{
298
    TCGv_i32 tmp;
299

    
300
    /* Remember what pgm exeption this was.  */
301
    tmp = tcg_const_i32(code);
302
    tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUS390XState, int_pgm_code));
303
    tcg_temp_free_i32(tmp);
304

    
305
    tmp = tcg_const_i32(s->next_pc - s->pc);
306
    tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUS390XState, int_pgm_ilen));
307
    tcg_temp_free_i32(tmp);
308

    
309
    /* Advance past instruction.  */
310
    s->pc = s->next_pc;
311
    update_psw_addr(s);
312

    
313
    /* Save off cc.  */
314
    update_cc_op(s);
315

    
316
    /* Trigger exception.  */
317
    gen_exception(EXCP_PGM);
318
}
319

    
320
static inline void gen_illegal_opcode(DisasContext *s)
321
{
322
    gen_program_exception(s, PGM_SPECIFICATION);
323
}
324

    
325
static inline void check_privileged(DisasContext *s)
326
{
327
    if (s->tb->flags & (PSW_MASK_PSTATE >> 32)) {
328
        gen_program_exception(s, PGM_PRIVILEGED);
329
    }
330
}
331

    
332
static TCGv_i64 get_address(DisasContext *s, int x2, int b2, int d2)
333
{
334
    TCGv_i64 tmp;
335

    
336
    /* 31-bitify the immediate part; register contents are dealt with below */
337
    if (!(s->tb->flags & FLAG_MASK_64)) {
338
        d2 &= 0x7fffffffUL;
339
    }
340

    
341
    if (x2) {
342
        if (d2) {
343
            tmp = tcg_const_i64(d2);
344
            tcg_gen_add_i64(tmp, tmp, regs[x2]);
345
        } else {
346
            tmp = load_reg(x2);
347
        }
348
        if (b2) {
349
            tcg_gen_add_i64(tmp, tmp, regs[b2]);
350
        }
351
    } else if (b2) {
352
        if (d2) {
353
            tmp = tcg_const_i64(d2);
354
            tcg_gen_add_i64(tmp, tmp, regs[b2]);
355
        } else {
356
            tmp = load_reg(b2);
357
        }
358
    } else {
359
        tmp = tcg_const_i64(d2);
360
    }
361

    
362
    /* 31-bit mode mask if there are values loaded from registers */
363
    if (!(s->tb->flags & FLAG_MASK_64) && (x2 || b2)) {
364
        tcg_gen_andi_i64(tmp, tmp, 0x7fffffffUL);
365
    }
366

    
367
    return tmp;
368
}
369

    
370
static inline void gen_op_movi_cc(DisasContext *s, uint32_t val)
371
{
372
    s->cc_op = CC_OP_CONST0 + val;
373
}
374

    
375
static void gen_op_update1_cc_i64(DisasContext *s, enum cc_op op, TCGv_i64 dst)
376
{
377
    tcg_gen_discard_i64(cc_src);
378
    tcg_gen_mov_i64(cc_dst, dst);
379
    tcg_gen_discard_i64(cc_vr);
380
    s->cc_op = op;
381
}
382

    
383
static void gen_op_update2_cc_i64(DisasContext *s, enum cc_op op, TCGv_i64 src,
384
                                  TCGv_i64 dst)
385
{
386
    tcg_gen_mov_i64(cc_src, src);
387
    tcg_gen_mov_i64(cc_dst, dst);
388
    tcg_gen_discard_i64(cc_vr);
389
    s->cc_op = op;
390
}
391

    
392
static void gen_op_update3_cc_i64(DisasContext *s, enum cc_op op, TCGv_i64 src,
393
                                  TCGv_i64 dst, TCGv_i64 vr)
394
{
395
    tcg_gen_mov_i64(cc_src, src);
396
    tcg_gen_mov_i64(cc_dst, dst);
397
    tcg_gen_mov_i64(cc_vr, vr);
398
    s->cc_op = op;
399
}
400

    
401
static void set_cc_nz_u64(DisasContext *s, TCGv_i64 val)
402
{
403
    gen_op_update1_cc_i64(s, CC_OP_NZ, val);
404
}
405

    
406
static void gen_set_cc_nz_f32(DisasContext *s, TCGv_i64 val)
407
{
408
    gen_op_update1_cc_i64(s, CC_OP_NZ_F32, val);
409
}
410

    
411
static void gen_set_cc_nz_f64(DisasContext *s, TCGv_i64 val)
412
{
413
    gen_op_update1_cc_i64(s, CC_OP_NZ_F64, val);
414
}
415

    
416
static void gen_set_cc_nz_f128(DisasContext *s, TCGv_i64 vh, TCGv_i64 vl)
417
{
418
    gen_op_update2_cc_i64(s, CC_OP_NZ_F128, vh, vl);
419
}
420

    
421
/* CC value is in env->cc_op */
422
static void set_cc_static(DisasContext *s)
423
{
424
    tcg_gen_discard_i64(cc_src);
425
    tcg_gen_discard_i64(cc_dst);
426
    tcg_gen_discard_i64(cc_vr);
427
    s->cc_op = CC_OP_STATIC;
428
}
429

    
430
/* calculates cc into cc_op */
431
static void gen_op_calc_cc(DisasContext *s)
432
{
433
    TCGv_i32 local_cc_op;
434
    TCGv_i64 dummy;
435

    
436
    TCGV_UNUSED_I32(local_cc_op);
437
    TCGV_UNUSED_I64(dummy);
438
    switch (s->cc_op) {
439
    default:
440
        dummy = tcg_const_i64(0);
441
        /* FALLTHRU */
442
    case CC_OP_ADD_64:
443
    case CC_OP_ADDU_64:
444
    case CC_OP_ADDC_64:
445
    case CC_OP_SUB_64:
446
    case CC_OP_SUBU_64:
447
    case CC_OP_SUBB_64:
448
    case CC_OP_ADD_32:
449
    case CC_OP_ADDU_32:
450
    case CC_OP_ADDC_32:
451
    case CC_OP_SUB_32:
452
    case CC_OP_SUBU_32:
453
    case CC_OP_SUBB_32:
454
        local_cc_op = tcg_const_i32(s->cc_op);
455
        break;
456
    case CC_OP_CONST0:
457
    case CC_OP_CONST1:
458
    case CC_OP_CONST2:
459
    case CC_OP_CONST3:
460
    case CC_OP_STATIC:
461
    case CC_OP_DYNAMIC:
462
        break;
463
    }
464

    
465
    switch (s->cc_op) {
466
    case CC_OP_CONST0:
467
    case CC_OP_CONST1:
468
    case CC_OP_CONST2:
469
    case CC_OP_CONST3:
470
        /* s->cc_op is the cc value */
471
        tcg_gen_movi_i32(cc_op, s->cc_op - CC_OP_CONST0);
472
        break;
473
    case CC_OP_STATIC:
474
        /* env->cc_op already is the cc value */
475
        break;
476
    case CC_OP_NZ:
477
    case CC_OP_ABS_64:
478
    case CC_OP_NABS_64:
479
    case CC_OP_ABS_32:
480
    case CC_OP_NABS_32:
481
    case CC_OP_LTGT0_32:
482
    case CC_OP_LTGT0_64:
483
    case CC_OP_COMP_32:
484
    case CC_OP_COMP_64:
485
    case CC_OP_NZ_F32:
486
    case CC_OP_NZ_F64:
487
    case CC_OP_FLOGR:
488
        /* 1 argument */
489
        gen_helper_calc_cc(cc_op, cpu_env, local_cc_op, dummy, cc_dst, dummy);
490
        break;
491
    case CC_OP_ICM:
492
    case CC_OP_LTGT_32:
493
    case CC_OP_LTGT_64:
494
    case CC_OP_LTUGTU_32:
495
    case CC_OP_LTUGTU_64:
496
    case CC_OP_TM_32:
497
    case CC_OP_TM_64:
498
    case CC_OP_SLA_32:
499
    case CC_OP_SLA_64:
500
    case CC_OP_NZ_F128:
501
        /* 2 arguments */
502
        gen_helper_calc_cc(cc_op, cpu_env, local_cc_op, cc_src, cc_dst, dummy);
503
        break;
504
    case CC_OP_ADD_64:
505
    case CC_OP_ADDU_64:
506
    case CC_OP_ADDC_64:
507
    case CC_OP_SUB_64:
508
    case CC_OP_SUBU_64:
509
    case CC_OP_SUBB_64:
510
    case CC_OP_ADD_32:
511
    case CC_OP_ADDU_32:
512
    case CC_OP_ADDC_32:
513
    case CC_OP_SUB_32:
514
    case CC_OP_SUBU_32:
515
    case CC_OP_SUBB_32:
516
        /* 3 arguments */
517
        gen_helper_calc_cc(cc_op, cpu_env, local_cc_op, cc_src, cc_dst, cc_vr);
518
        break;
519
    case CC_OP_DYNAMIC:
520
        /* unknown operation - assume 3 arguments and cc_op in env */
521
        gen_helper_calc_cc(cc_op, cpu_env, cc_op, cc_src, cc_dst, cc_vr);
522
        break;
523
    default:
524
        tcg_abort();
525
    }
526

    
527
    if (!TCGV_IS_UNUSED_I32(local_cc_op)) {
528
        tcg_temp_free_i32(local_cc_op);
529
    }
530
    if (!TCGV_IS_UNUSED_I64(dummy)) {
531
        tcg_temp_free_i64(dummy);
532
    }
533

    
534
    /* We now have cc in cc_op as constant */
535
    set_cc_static(s);
536
}
537

    
538
static int use_goto_tb(DisasContext *s, uint64_t dest)
539
{
540
    /* NOTE: we handle the case where the TB spans two pages here */
541
    return (((dest & TARGET_PAGE_MASK) == (s->tb->pc & TARGET_PAGE_MASK)
542
             || (dest & TARGET_PAGE_MASK) == ((s->pc - 1) & TARGET_PAGE_MASK))
543
            && !s->singlestep_enabled
544
            && !(s->tb->cflags & CF_LAST_IO));
545
}
546

    
547
static void account_noninline_branch(DisasContext *s, int cc_op)
548
{
549
#ifdef DEBUG_INLINE_BRANCHES
550
    inline_branch_miss[cc_op]++;
551
#endif
552
}
553

    
554
static void account_inline_branch(DisasContext *s, int cc_op)
555
{
556
#ifdef DEBUG_INLINE_BRANCHES
557
    inline_branch_hit[cc_op]++;
558
#endif
559
}
560

    
561
/* Table of mask values to comparison codes, given a comparison as input.
562
   For a true comparison CC=3 will never be set, but we treat this
563
   conservatively for possible use when CC=3 indicates overflow.  */
564
static const TCGCond ltgt_cond[16] = {
565
    TCG_COND_NEVER,  TCG_COND_NEVER,     /*    |    |    | x */
566
    TCG_COND_GT,     TCG_COND_NEVER,     /*    |    | GT | x */
567
    TCG_COND_LT,     TCG_COND_NEVER,     /*    | LT |    | x */
568
    TCG_COND_NE,     TCG_COND_NEVER,     /*    | LT | GT | x */
569
    TCG_COND_EQ,     TCG_COND_NEVER,     /* EQ |    |    | x */
570
    TCG_COND_GE,     TCG_COND_NEVER,     /* EQ |    | GT | x */
571
    TCG_COND_LE,     TCG_COND_NEVER,     /* EQ | LT |    | x */
572
    TCG_COND_ALWAYS, TCG_COND_ALWAYS,    /* EQ | LT | GT | x */
573
};
574

    
575
/* Table of mask values to comparison codes, given a logic op as input.
576
   For such, only CC=0 and CC=1 should be possible.  */
577
static const TCGCond nz_cond[16] = {
578
    /*    |    | x | x */
579
    TCG_COND_NEVER, TCG_COND_NEVER, TCG_COND_NEVER, TCG_COND_NEVER,
580
    /*    | NE | x | x */
581
    TCG_COND_NE, TCG_COND_NE, TCG_COND_NE, TCG_COND_NE,
582
    /* EQ |    | x | x */
583
    TCG_COND_EQ, TCG_COND_EQ, TCG_COND_EQ, TCG_COND_EQ,
584
    /* EQ | NE | x | x */
585
    TCG_COND_ALWAYS, TCG_COND_ALWAYS, TCG_COND_ALWAYS, TCG_COND_ALWAYS,
586
};
587

    
588
/* Interpret MASK in terms of S->CC_OP, and fill in C with all the
589
   details required to generate a TCG comparison.  */
590
static void disas_jcc(DisasContext *s, DisasCompare *c, uint32_t mask)
591
{
592
    TCGCond cond;
593
    enum cc_op old_cc_op = s->cc_op;
594

    
595
    if (mask == 15 || mask == 0) {
596
        c->cond = (mask ? TCG_COND_ALWAYS : TCG_COND_NEVER);
597
        c->u.s32.a = cc_op;
598
        c->u.s32.b = cc_op;
599
        c->g1 = c->g2 = true;
600
        c->is_64 = false;
601
        return;
602
    }
603

    
604
    /* Find the TCG condition for the mask + cc op.  */
605
    switch (old_cc_op) {
606
    case CC_OP_LTGT0_32:
607
    case CC_OP_LTGT0_64:
608
    case CC_OP_LTGT_32:
609
    case CC_OP_LTGT_64:
610
        cond = ltgt_cond[mask];
611
        if (cond == TCG_COND_NEVER) {
612
            goto do_dynamic;
613
        }
614
        account_inline_branch(s, old_cc_op);
615
        break;
616

    
617
    case CC_OP_LTUGTU_32:
618
    case CC_OP_LTUGTU_64:
619
        cond = tcg_unsigned_cond(ltgt_cond[mask]);
620
        if (cond == TCG_COND_NEVER) {
621
            goto do_dynamic;
622
        }
623
        account_inline_branch(s, old_cc_op);
624
        break;
625

    
626
    case CC_OP_NZ:
627
        cond = nz_cond[mask];
628
        if (cond == TCG_COND_NEVER) {
629
            goto do_dynamic;
630
        }
631
        account_inline_branch(s, old_cc_op);
632
        break;
633

    
634
    case CC_OP_TM_32:
635
    case CC_OP_TM_64:
636
        switch (mask) {
637
        case 8:
638
            cond = TCG_COND_EQ;
639
            break;
640
        case 4 | 2 | 1:
641
            cond = TCG_COND_NE;
642
            break;
643
        default:
644
            goto do_dynamic;
645
        }
646
        account_inline_branch(s, old_cc_op);
647
        break;
648

    
649
    case CC_OP_ICM:
650
        switch (mask) {
651
        case 8:
652
            cond = TCG_COND_EQ;
653
            break;
654
        case 4 | 2 | 1:
655
        case 4 | 2:
656
            cond = TCG_COND_NE;
657
            break;
658
        default:
659
            goto do_dynamic;
660
        }
661
        account_inline_branch(s, old_cc_op);
662
        break;
663

    
664
    case CC_OP_FLOGR:
665
        switch (mask & 0xa) {
666
        case 8: /* src == 0 -> no one bit found */
667
            cond = TCG_COND_EQ;
668
            break;
669
        case 2: /* src != 0 -> one bit found */
670
            cond = TCG_COND_NE;
671
            break;
672
        default:
673
            goto do_dynamic;
674
        }
675
        account_inline_branch(s, old_cc_op);
676
        break;
677

    
678
    default:
679
    do_dynamic:
680
        /* Calculate cc value.  */
681
        gen_op_calc_cc(s);
682
        /* FALLTHRU */
683

    
684
    case CC_OP_STATIC:
685
        /* Jump based on CC.  We'll load up the real cond below;
686
           the assignment here merely avoids a compiler warning.  */
687
        account_noninline_branch(s, old_cc_op);
688
        old_cc_op = CC_OP_STATIC;
689
        cond = TCG_COND_NEVER;
690
        break;
691
    }
692

    
693
    /* Load up the arguments of the comparison.  */
694
    c->is_64 = true;
695
    c->g1 = c->g2 = false;
696
    switch (old_cc_op) {
697
    case CC_OP_LTGT0_32:
698
        c->is_64 = false;
699
        c->u.s32.a = tcg_temp_new_i32();
700
        tcg_gen_trunc_i64_i32(c->u.s32.a, cc_dst);
701
        c->u.s32.b = tcg_const_i32(0);
702
        break;
703
    case CC_OP_LTGT_32:
704
    case CC_OP_LTUGTU_32:
705
        c->is_64 = false;
706
        c->u.s32.a = tcg_temp_new_i32();
707
        tcg_gen_trunc_i64_i32(c->u.s32.a, cc_src);
708
        c->u.s32.b = tcg_temp_new_i32();
709
        tcg_gen_trunc_i64_i32(c->u.s32.b, cc_dst);
710
        break;
711

    
712
    case CC_OP_LTGT0_64:
713
    case CC_OP_NZ:
714
    case CC_OP_FLOGR:
715
        c->u.s64.a = cc_dst;
716
        c->u.s64.b = tcg_const_i64(0);
717
        c->g1 = true;
718
        break;
719
    case CC_OP_LTGT_64:
720
    case CC_OP_LTUGTU_64:
721
        c->u.s64.a = cc_src;
722
        c->u.s64.b = cc_dst;
723
        c->g1 = c->g2 = true;
724
        break;
725

    
726
    case CC_OP_TM_32:
727
    case CC_OP_TM_64:
728
    case CC_OP_ICM:
729
        c->u.s64.a = tcg_temp_new_i64();
730
        c->u.s64.b = tcg_const_i64(0);
731
        tcg_gen_and_i64(c->u.s64.a, cc_src, cc_dst);
732
        break;
733

    
734
    case CC_OP_STATIC:
735
        c->is_64 = false;
736
        c->u.s32.a = cc_op;
737
        c->g1 = true;
738
        switch (mask) {
739
        case 0x8 | 0x4 | 0x2: /* cc != 3 */
740
            cond = TCG_COND_NE;
741
            c->u.s32.b = tcg_const_i32(3);
742
            break;
743
        case 0x8 | 0x4 | 0x1: /* cc != 2 */
744
            cond = TCG_COND_NE;
745
            c->u.s32.b = tcg_const_i32(2);
746
            break;
747
        case 0x8 | 0x2 | 0x1: /* cc != 1 */
748
            cond = TCG_COND_NE;
749
            c->u.s32.b = tcg_const_i32(1);
750
            break;
751
        case 0x8 | 0x2: /* cc == 0 ||ย cc == 2 => (cc & 1) == 0 */
752
            cond = TCG_COND_EQ;
753
            c->g1 = false;
754
            c->u.s32.a = tcg_temp_new_i32();
755
            c->u.s32.b = tcg_const_i32(0);
756
            tcg_gen_andi_i32(c->u.s32.a, cc_op, 1);
757
            break;
758
        case 0x8 | 0x4: /* cc < 2 */
759
            cond = TCG_COND_LTU;
760
            c->u.s32.b = tcg_const_i32(2);
761
            break;
762
        case 0x8: /* cc == 0 */
763
            cond = TCG_COND_EQ;
764
            c->u.s32.b = tcg_const_i32(0);
765
            break;
766
        case 0x4 | 0x2 | 0x1: /* cc != 0 */
767
            cond = TCG_COND_NE;
768
            c->u.s32.b = tcg_const_i32(0);
769
            break;
770
        case 0x4 | 0x1: /* cc == 1 ||ย cc == 3 => (cc & 1) != 0 */
771
            cond = TCG_COND_NE;
772
            c->g1 = false;
773
            c->u.s32.a = tcg_temp_new_i32();
774
            c->u.s32.b = tcg_const_i32(0);
775
            tcg_gen_andi_i32(c->u.s32.a, cc_op, 1);
776
            break;
777
        case 0x4: /* cc == 1 */
778
            cond = TCG_COND_EQ;
779
            c->u.s32.b = tcg_const_i32(1);
780
            break;
781
        case 0x2 | 0x1: /* cc > 1 */
782
            cond = TCG_COND_GTU;
783
            c->u.s32.b = tcg_const_i32(1);
784
            break;
785
        case 0x2: /* cc == 2 */
786
            cond = TCG_COND_EQ;
787
            c->u.s32.b = tcg_const_i32(2);
788
            break;
789
        case 0x1: /* cc == 3 */
790
            cond = TCG_COND_EQ;
791
            c->u.s32.b = tcg_const_i32(3);
792
            break;
793
        default:
794
            /* CC is masked by something else: (8 >> cc) & mask.  */
795
            cond = TCG_COND_NE;
796
            c->g1 = false;
797
            c->u.s32.a = tcg_const_i32(8);
798
            c->u.s32.b = tcg_const_i32(0);
799
            tcg_gen_shr_i32(c->u.s32.a, c->u.s32.a, cc_op);
800
            tcg_gen_andi_i32(c->u.s32.a, c->u.s32.a, mask);
801
            break;
802
        }
803
        break;
804

    
805
    default:
806
        abort();
807
    }
808
    c->cond = cond;
809
}
810

    
811
static void free_compare(DisasCompare *c)
812
{
813
    if (!c->g1) {
814
        if (c->is_64) {
815
            tcg_temp_free_i64(c->u.s64.a);
816
        } else {
817
            tcg_temp_free_i32(c->u.s32.a);
818
        }
819
    }
820
    if (!c->g2) {
821
        if (c->is_64) {
822
            tcg_temp_free_i64(c->u.s64.b);
823
        } else {
824
            tcg_temp_free_i32(c->u.s32.b);
825
        }
826
    }
827
}
828

    
829
/* ====================================================================== */
830
/* Define the insn format enumeration.  */
831
#define F0(N)                         FMT_##N,
832
#define F1(N, X1)                     F0(N)
833
#define F2(N, X1, X2)                 F0(N)
834
#define F3(N, X1, X2, X3)             F0(N)
835
#define F4(N, X1, X2, X3, X4)         F0(N)
836
#define F5(N, X1, X2, X3, X4, X5)     F0(N)
837

    
838
typedef enum {
839
#include "insn-format.def"
840
} DisasFormat;
841

    
842
#undef F0
843
#undef F1
844
#undef F2
845
#undef F3
846
#undef F4
847
#undef F5
848

    
849
/* Define a structure to hold the decoded fields.  We'll store each inside
850
   an array indexed by an enum.  In order to conserve memory, we'll arrange
851
   for fields that do not exist at the same time to overlap, thus the "C"
852
   for compact.  For checking purposes there is an "O" for original index
853
   as well that will be applied to availability bitmaps.  */
854

    
855
enum DisasFieldIndexO {
856
    FLD_O_r1,
857
    FLD_O_r2,
858
    FLD_O_r3,
859
    FLD_O_m1,
860
    FLD_O_m3,
861
    FLD_O_m4,
862
    FLD_O_b1,
863
    FLD_O_b2,
864
    FLD_O_b4,
865
    FLD_O_d1,
866
    FLD_O_d2,
867
    FLD_O_d4,
868
    FLD_O_x2,
869
    FLD_O_l1,
870
    FLD_O_l2,
871
    FLD_O_i1,
872
    FLD_O_i2,
873
    FLD_O_i3,
874
    FLD_O_i4,
875
    FLD_O_i5
876
};
877

    
878
enum DisasFieldIndexC {
879
    FLD_C_r1 = 0,
880
    FLD_C_m1 = 0,
881
    FLD_C_b1 = 0,
882
    FLD_C_i1 = 0,
883

    
884
    FLD_C_r2 = 1,
885
    FLD_C_b2 = 1,
886
    FLD_C_i2 = 1,
887

    
888
    FLD_C_r3 = 2,
889
    FLD_C_m3 = 2,
890
    FLD_C_i3 = 2,
891

    
892
    FLD_C_m4 = 3,
893
    FLD_C_b4 = 3,
894
    FLD_C_i4 = 3,
895
    FLD_C_l1 = 3,
896

    
897
    FLD_C_i5 = 4,
898
    FLD_C_d1 = 4,
899

    
900
    FLD_C_d2 = 5,
901

    
902
    FLD_C_d4 = 6,
903
    FLD_C_x2 = 6,
904
    FLD_C_l2 = 6,
905

    
906
    NUM_C_FIELD = 7
907
};
908

    
909
struct DisasFields {
910
    unsigned op:8;
911
    unsigned op2:8;
912
    unsigned presentC:16;
913
    unsigned int presentO;
914
    int c[NUM_C_FIELD];
915
};
916

    
917
/* This is the way fields are to be accessed out of DisasFields.  */
918
#define have_field(S, F)  have_field1((S), FLD_O_##F)
919
#define get_field(S, F)   get_field1((S), FLD_O_##F, FLD_C_##F)
920

    
921
static bool have_field1(const DisasFields *f, enum DisasFieldIndexO c)
922
{
923
    return (f->presentO >> c) & 1;
924
}
925

    
926
static int get_field1(const DisasFields *f, enum DisasFieldIndexO o,
927
                      enum DisasFieldIndexC c)
928
{
929
    assert(have_field1(f, o));
930
    return f->c[c];
931
}
932

    
933
/* Describe the layout of each field in each format.  */
934
typedef struct DisasField {
935
    unsigned int beg:8;
936
    unsigned int size:8;
937
    unsigned int type:2;
938
    unsigned int indexC:6;
939
    enum DisasFieldIndexO indexO:8;
940
} DisasField;
941

    
942
typedef struct DisasFormatInfo {
943
    DisasField op[NUM_C_FIELD];
944
} DisasFormatInfo;
945

    
946
#define R(N, B)       {  B,  4, 0, FLD_C_r##N, FLD_O_r##N }
947
#define M(N, B)       {  B,  4, 0, FLD_C_m##N, FLD_O_m##N }
948
#define BD(N, BB, BD) { BB,  4, 0, FLD_C_b##N, FLD_O_b##N }, \
949
                      { BD, 12, 0, FLD_C_d##N, FLD_O_d##N }
950
#define BXD(N)        { 16,  4, 0, FLD_C_b##N, FLD_O_b##N }, \
951
                      { 12,  4, 0, FLD_C_x##N, FLD_O_x##N }, \
952
                      { 20, 12, 0, FLD_C_d##N, FLD_O_d##N }
953
#define BDL(N)        { 16,  4, 0, FLD_C_b##N, FLD_O_b##N }, \
954
                      { 20, 20, 2, FLD_C_d##N, FLD_O_d##N }
955
#define BXDL(N)       { 16,  4, 0, FLD_C_b##N, FLD_O_b##N }, \
956
                      { 12,  4, 0, FLD_C_x##N, FLD_O_x##N }, \
957
                      { 20, 20, 2, FLD_C_d##N, FLD_O_d##N }
958
#define I(N, B, S)    {  B,  S, 1, FLD_C_i##N, FLD_O_i##N }
959
#define L(N, B, S)    {  B,  S, 0, FLD_C_l##N, FLD_O_l##N }
960

    
961
#define F0(N)                     { { } },
962
#define F1(N, X1)                 { { X1 } },
963
#define F2(N, X1, X2)             { { X1, X2 } },
964
#define F3(N, X1, X2, X3)         { { X1, X2, X3 } },
965
#define F4(N, X1, X2, X3, X4)     { { X1, X2, X3, X4 } },
966
#define F5(N, X1, X2, X3, X4, X5) { { X1, X2, X3, X4, X5 } },
967

    
968
static const DisasFormatInfo format_info[] = {
969
#include "insn-format.def"
970
};
971

    
972
#undef F0
973
#undef F1
974
#undef F2
975
#undef F3
976
#undef F4
977
#undef F5
978
#undef R
979
#undef M
980
#undef BD
981
#undef BXD
982
#undef BDL
983
#undef BXDL
984
#undef I
985
#undef L
986

    
987
/* Generally, we'll extract operands into this structures, operate upon
988
   them, and store them back.  See the "in1", "in2", "prep", "wout" sets
989
   of routines below for more details.  */
990
typedef struct {
991
    bool g_out, g_out2, g_in1, g_in2;
992
    TCGv_i64 out, out2, in1, in2;
993
    TCGv_i64 addr1;
994
} DisasOps;
995

    
996
/* Return values from translate_one, indicating the state of the TB.  */
997
typedef enum {
998
    /* Continue the TB.  */
999
    NO_EXIT,
1000
    /* We have emitted one or more goto_tb.  No fixup required.  */
1001
    EXIT_GOTO_TB,
1002
    /* We are not using a goto_tb (for whatever reason), but have updated
1003
       the PC (for whatever reason), so there's no need to do it again on
1004
       exiting the TB.  */
1005
    EXIT_PC_UPDATED,
1006
    /* We are exiting the TB, but have neither emitted a goto_tb, nor
1007
       updated the PC for the next instruction to be executed.  */
1008
    EXIT_PC_STALE,
1009
    /* We are ending the TB with a noreturn function call, e.g. longjmp.
1010
       No following code will be executed.  */
1011
    EXIT_NORETURN,
1012
} ExitStatus;
1013

    
1014
typedef enum DisasFacility {
1015
    FAC_Z,                  /* zarch (default) */
1016
    FAC_CASS,               /* compare and swap and store */
1017
    FAC_CASS2,              /* compare and swap and store 2*/
1018
    FAC_DFP,                /* decimal floating point */
1019
    FAC_DFPR,               /* decimal floating point rounding */
1020
    FAC_DO,                 /* distinct operands */
1021
    FAC_EE,                 /* execute extensions */
1022
    FAC_EI,                 /* extended immediate */
1023
    FAC_FPE,                /* floating point extension */
1024
    FAC_FPSSH,              /* floating point support sign handling */
1025
    FAC_FPRGR,              /* FPR-GR transfer */
1026
    FAC_GIE,                /* general instructions extension */
1027
    FAC_HFP_MA,             /* HFP multiply-and-add/subtract */
1028
    FAC_HW,                 /* high-word */
1029
    FAC_IEEEE_SIM,          /* IEEE exception sumilation */
1030
    FAC_LOC,                /* load/store on condition */
1031
    FAC_LD,                 /* long displacement */
1032
    FAC_PC,                 /* population count */
1033
    FAC_SCF,                /* store clock fast */
1034
    FAC_SFLE,               /* store facility list extended */
1035
} DisasFacility;
1036

    
1037
struct DisasInsn {
1038
    unsigned opc:16;
1039
    DisasFormat fmt:6;
1040
    DisasFacility fac:6;
1041

    
1042
    const char *name;
1043

    
1044
    void (*help_in1)(DisasContext *, DisasFields *, DisasOps *);
1045
    void (*help_in2)(DisasContext *, DisasFields *, DisasOps *);
1046
    void (*help_prep)(DisasContext *, DisasFields *, DisasOps *);
1047
    void (*help_wout)(DisasContext *, DisasFields *, DisasOps *);
1048
    void (*help_cout)(DisasContext *, DisasOps *);
1049
    ExitStatus (*help_op)(DisasContext *, DisasOps *);
1050

    
1051
    uint64_t data;
1052
};
1053

    
1054
/* ====================================================================== */
1055
/* Miscelaneous helpers, used by several operations.  */
1056

    
1057
static void help_l2_shift(DisasContext *s, DisasFields *f,
1058
                          DisasOps *o, int mask)
1059
{
1060
    int b2 = get_field(f, b2);
1061
    int d2 = get_field(f, d2);
1062

    
1063
    if (b2 == 0) {
1064
        o->in2 = tcg_const_i64(d2 & mask);
1065
    } else {
1066
        o->in2 = get_address(s, 0, b2, d2);
1067
        tcg_gen_andi_i64(o->in2, o->in2, mask);
1068
    }
1069
}
1070

    
1071
static ExitStatus help_goto_direct(DisasContext *s, uint64_t dest)
1072
{
1073
    if (dest == s->next_pc) {
1074
        return NO_EXIT;
1075
    }
1076
    if (use_goto_tb(s, dest)) {
1077
        update_cc_op(s);
1078
        tcg_gen_goto_tb(0);
1079
        tcg_gen_movi_i64(psw_addr, dest);
1080
        tcg_gen_exit_tb((tcg_target_long)s->tb);
1081
        return EXIT_GOTO_TB;
1082
    } else {
1083
        tcg_gen_movi_i64(psw_addr, dest);
1084
        return EXIT_PC_UPDATED;
1085
    }
1086
}
1087

    
1088
static ExitStatus help_branch(DisasContext *s, DisasCompare *c,
1089
                              bool is_imm, int imm, TCGv_i64 cdest)
1090
{
1091
    ExitStatus ret;
1092
    uint64_t dest = s->pc + 2 * imm;
1093
    int lab;
1094

    
1095
    /* Take care of the special cases first.  */
1096
    if (c->cond == TCG_COND_NEVER) {
1097
        ret = NO_EXIT;
1098
        goto egress;
1099
    }
1100
    if (is_imm) {
1101
        if (dest == s->next_pc) {
1102
            /* Branch to next.  */
1103
            ret = NO_EXIT;
1104
            goto egress;
1105
        }
1106
        if (c->cond == TCG_COND_ALWAYS) {
1107
            ret = help_goto_direct(s, dest);
1108
            goto egress;
1109
        }
1110
    } else {
1111
        if (TCGV_IS_UNUSED_I64(cdest)) {
1112
            /* E.g. bcr %r0 -> no branch.  */
1113
            ret = NO_EXIT;
1114
            goto egress;
1115
        }
1116
        if (c->cond == TCG_COND_ALWAYS) {
1117
            tcg_gen_mov_i64(psw_addr, cdest);
1118
            ret = EXIT_PC_UPDATED;
1119
            goto egress;
1120
        }
1121
    }
1122

    
1123
    if (use_goto_tb(s, s->next_pc)) {
1124
        if (is_imm && use_goto_tb(s, dest)) {
1125
            /* Both exits can use goto_tb.  */
1126
            update_cc_op(s);
1127

    
1128
            lab = gen_new_label();
1129
            if (c->is_64) {
1130
                tcg_gen_brcond_i64(c->cond, c->u.s64.a, c->u.s64.b, lab);
1131
            } else {
1132
                tcg_gen_brcond_i32(c->cond, c->u.s32.a, c->u.s32.b, lab);
1133
            }
1134

    
1135
            /* Branch not taken.  */
1136
            tcg_gen_goto_tb(0);
1137
            tcg_gen_movi_i64(psw_addr, s->next_pc);
1138
            tcg_gen_exit_tb((tcg_target_long)s->tb + 0);
1139

    
1140
            /* Branch taken.  */
1141
            gen_set_label(lab);
1142
            tcg_gen_goto_tb(1);
1143
            tcg_gen_movi_i64(psw_addr, dest);
1144
            tcg_gen_exit_tb((tcg_target_long)s->tb + 1);
1145

    
1146
            ret = EXIT_GOTO_TB;
1147
        } else {
1148
            /* Fallthru can use goto_tb, but taken branch cannot.  */
1149
            /* Store taken branch destination before the brcond.  This
1150
               avoids having to allocate a new local temp to hold it.
1151
               We'll overwrite this in the not taken case anyway.  */
1152
            if (!is_imm) {
1153
                tcg_gen_mov_i64(psw_addr, cdest);
1154
            }
1155

    
1156
            lab = gen_new_label();
1157
            if (c->is_64) {
1158
                tcg_gen_brcond_i64(c->cond, c->u.s64.a, c->u.s64.b, lab);
1159
            } else {
1160
                tcg_gen_brcond_i32(c->cond, c->u.s32.a, c->u.s32.b, lab);
1161
            }
1162

    
1163
            /* Branch not taken.  */
1164
            update_cc_op(s);
1165
            tcg_gen_goto_tb(0);
1166
            tcg_gen_movi_i64(psw_addr, s->next_pc);
1167
            tcg_gen_exit_tb((tcg_target_long)s->tb + 0);
1168

    
1169
            gen_set_label(lab);
1170
            if (is_imm) {
1171
                tcg_gen_movi_i64(psw_addr, dest);
1172
            }
1173
            ret = EXIT_PC_UPDATED;
1174
        }
1175
    } else {
1176
        /* Fallthru cannot use goto_tb.  This by itself is vanishingly rare.
1177
           Most commonly we're single-stepping or some other condition that
1178
           disables all use of goto_tb.  Just update the PC and exit.  */
1179

    
1180
        TCGv_i64 next = tcg_const_i64(s->next_pc);
1181
        if (is_imm) {
1182
            cdest = tcg_const_i64(dest);
1183
        }
1184

    
1185
        if (c->is_64) {
1186
            tcg_gen_movcond_i64(c->cond, psw_addr, c->u.s64.a, c->u.s64.b,
1187
                                cdest, next);
1188
        } else {
1189
            TCGv_i32 t0 = tcg_temp_new_i32();
1190
            TCGv_i64 t1 = tcg_temp_new_i64();
1191
            TCGv_i64 z = tcg_const_i64(0);
1192
            tcg_gen_setcond_i32(c->cond, t0, c->u.s32.a, c->u.s32.b);
1193
            tcg_gen_extu_i32_i64(t1, t0);
1194
            tcg_temp_free_i32(t0);
1195
            tcg_gen_movcond_i64(TCG_COND_NE, psw_addr, t1, z, cdest, next);
1196
            tcg_temp_free_i64(t1);
1197
            tcg_temp_free_i64(z);
1198
        }
1199

    
1200
        if (is_imm) {
1201
            tcg_temp_free_i64(cdest);
1202
        }
1203
        tcg_temp_free_i64(next);
1204

    
1205
        ret = EXIT_PC_UPDATED;
1206
    }
1207

    
1208
 egress:
1209
    free_compare(c);
1210
    return ret;
1211
}
1212

    
1213
/* ====================================================================== */
1214
/* The operations.  These perform the bulk of the work for any insn,
1215
   usually after the operands have been loaded and output initialized.  */
1216

    
1217
static ExitStatus op_abs(DisasContext *s, DisasOps *o)
1218
{
1219
    gen_helper_abs_i64(o->out, o->in2);
1220
    return NO_EXIT;
1221
}
1222

    
1223
static ExitStatus op_absf32(DisasContext *s, DisasOps *o)
1224
{
1225
    tcg_gen_andi_i64(o->out, o->in2, 0x7fffffffull);
1226
    return NO_EXIT;
1227
}
1228

    
1229
static ExitStatus op_absf64(DisasContext *s, DisasOps *o)
1230
{
1231
    tcg_gen_andi_i64(o->out, o->in2, 0x7fffffffffffffffull);
1232
    return NO_EXIT;
1233
}
1234

    
1235
static ExitStatus op_absf128(DisasContext *s, DisasOps *o)
1236
{
1237
    tcg_gen_andi_i64(o->out, o->in1, 0x7fffffffffffffffull);
1238
    tcg_gen_mov_i64(o->out2, o->in2);
1239
    return NO_EXIT;
1240
}
1241

    
1242
static ExitStatus op_add(DisasContext *s, DisasOps *o)
1243
{
1244
    tcg_gen_add_i64(o->out, o->in1, o->in2);
1245
    return NO_EXIT;
1246
}
1247

    
1248
static ExitStatus op_addc(DisasContext *s, DisasOps *o)
1249
{
1250
    TCGv_i64 cc;
1251

    
1252
    tcg_gen_add_i64(o->out, o->in1, o->in2);
1253

    
1254
    /* XXX possible optimization point */
1255
    gen_op_calc_cc(s);
1256
    cc = tcg_temp_new_i64();
1257
    tcg_gen_extu_i32_i64(cc, cc_op);
1258
    tcg_gen_shri_i64(cc, cc, 1);
1259

    
1260
    tcg_gen_add_i64(o->out, o->out, cc);
1261
    tcg_temp_free_i64(cc);
1262
    return NO_EXIT;
1263
}
1264

    
1265
static ExitStatus op_aeb(DisasContext *s, DisasOps *o)
1266
{
1267
    gen_helper_aeb(o->out, cpu_env, o->in1, o->in2);
1268
    return NO_EXIT;
1269
}
1270

    
1271
static ExitStatus op_adb(DisasContext *s, DisasOps *o)
1272
{
1273
    gen_helper_adb(o->out, cpu_env, o->in1, o->in2);
1274
    return NO_EXIT;
1275
}
1276

    
1277
static ExitStatus op_axb(DisasContext *s, DisasOps *o)
1278
{
1279
    gen_helper_axb(o->out, cpu_env, o->out, o->out2, o->in1, o->in2);
1280
    return_low128(o->out2);
1281
    return NO_EXIT;
1282
}
1283

    
1284
static ExitStatus op_and(DisasContext *s, DisasOps *o)
1285
{
1286
    tcg_gen_and_i64(o->out, o->in1, o->in2);
1287
    return NO_EXIT;
1288
}
1289

    
1290
static ExitStatus op_andi(DisasContext *s, DisasOps *o)
1291
{
1292
    int shift = s->insn->data & 0xff;
1293
    int size = s->insn->data >> 8;
1294
    uint64_t mask = ((1ull << size) - 1) << shift;
1295

    
1296
    assert(!o->g_in2);
1297
    tcg_gen_shli_i64(o->in2, o->in2, shift);
1298
    tcg_gen_ori_i64(o->in2, o->in2, ~mask);
1299
    tcg_gen_and_i64(o->out, o->in1, o->in2);
1300

    
1301
    /* Produce the CC from only the bits manipulated.  */
1302
    tcg_gen_andi_i64(cc_dst, o->out, mask);
1303
    set_cc_nz_u64(s, cc_dst);
1304
    return NO_EXIT;
1305
}
1306

    
1307
static ExitStatus op_bas(DisasContext *s, DisasOps *o)
1308
{
1309
    tcg_gen_movi_i64(o->out, pc_to_link_info(s, s->next_pc));
1310
    if (!TCGV_IS_UNUSED_I64(o->in2)) {
1311
        tcg_gen_mov_i64(psw_addr, o->in2);
1312
        return EXIT_PC_UPDATED;
1313
    } else {
1314
        return NO_EXIT;
1315
    }
1316
}
1317

    
1318
static ExitStatus op_basi(DisasContext *s, DisasOps *o)
1319
{
1320
    tcg_gen_movi_i64(o->out, pc_to_link_info(s, s->next_pc));
1321
    return help_goto_direct(s, s->pc + 2 * get_field(s->fields, i2));
1322
}
1323

    
1324
static ExitStatus op_bc(DisasContext *s, DisasOps *o)
1325
{
1326
    int m1 = get_field(s->fields, m1);
1327
    bool is_imm = have_field(s->fields, i2);
1328
    int imm = is_imm ? get_field(s->fields, i2) : 0;
1329
    DisasCompare c;
1330

    
1331
    disas_jcc(s, &c, m1);
1332
    return help_branch(s, &c, is_imm, imm, o->in2);
1333
}
1334

    
1335
static ExitStatus op_bct32(DisasContext *s, DisasOps *o)
1336
{
1337
    int r1 = get_field(s->fields, r1);
1338
    bool is_imm = have_field(s->fields, i2);
1339
    int imm = is_imm ? get_field(s->fields, i2) : 0;
1340
    DisasCompare c;
1341
    TCGv_i64 t;
1342

    
1343
    c.cond = TCG_COND_NE;
1344
    c.is_64 = false;
1345
    c.g1 = false;
1346
    c.g2 = false;
1347

    
1348
    t = tcg_temp_new_i64();
1349
    tcg_gen_subi_i64(t, regs[r1], 1);
1350
    store_reg32_i64(r1, t);
1351
    c.u.s32.a = tcg_temp_new_i32();
1352
    c.u.s32.b = tcg_const_i32(0);
1353
    tcg_gen_trunc_i64_i32(c.u.s32.a, t);
1354
    tcg_temp_free_i64(t);
1355

    
1356
    return help_branch(s, &c, is_imm, imm, o->in2);
1357
}
1358

    
1359
static ExitStatus op_bct64(DisasContext *s, DisasOps *o)
1360
{
1361
    int r1 = get_field(s->fields, r1);
1362
    bool is_imm = have_field(s->fields, i2);
1363
    int imm = is_imm ? get_field(s->fields, i2) : 0;
1364
    DisasCompare c;
1365

    
1366
    c.cond = TCG_COND_NE;
1367
    c.is_64 = true;
1368
    c.g1 = true;
1369
    c.g2 = false;
1370

    
1371
    tcg_gen_subi_i64(regs[r1], regs[r1], 1);
1372
    c.u.s64.a = regs[r1];
1373
    c.u.s64.b = tcg_const_i64(0);
1374

    
1375
    return help_branch(s, &c, is_imm, imm, o->in2);
1376
}
1377

    
1378
static ExitStatus op_bx32(DisasContext *s, DisasOps *o)
1379
{
1380
    int r1 = get_field(s->fields, r1);
1381
    int r3 = get_field(s->fields, r3);
1382
    bool is_imm = have_field(s->fields, i2);
1383
    int imm = is_imm ? get_field(s->fields, i2) : 0;
1384
    DisasCompare c;
1385
    TCGv_i64 t;
1386

    
1387
    c.cond = (s->insn->data ? TCG_COND_LE : TCG_COND_GT);
1388
    c.is_64 = false;
1389
    c.g1 = false;
1390
    c.g2 = false;
1391

    
1392
    t = tcg_temp_new_i64();
1393
    tcg_gen_add_i64(t, regs[r1], regs[r3]);
1394
    c.u.s32.a = tcg_temp_new_i32();
1395
    c.u.s32.b = tcg_temp_new_i32();
1396
    tcg_gen_trunc_i64_i32(c.u.s32.a, t);
1397
    tcg_gen_trunc_i64_i32(c.u.s32.b, regs[r3 | 1]);
1398
    store_reg32_i64(r1, t);
1399
    tcg_temp_free_i64(t);
1400

    
1401
    return help_branch(s, &c, is_imm, imm, o->in2);
1402
}
1403

    
1404
static ExitStatus op_bx64(DisasContext *s, DisasOps *o)
1405
{
1406
    int r1 = get_field(s->fields, r1);
1407
    int r3 = get_field(s->fields, r3);
1408
    bool is_imm = have_field(s->fields, i2);
1409
    int imm = is_imm ? get_field(s->fields, i2) : 0;
1410
    DisasCompare c;
1411

    
1412
    c.cond = (s->insn->data ? TCG_COND_LE : TCG_COND_GT);
1413
    c.is_64 = true;
1414

    
1415
    if (r1 == (r3 | 1)) {
1416
        c.u.s64.b = load_reg(r3 | 1);
1417
        c.g2 = false;
1418
    } else {
1419
        c.u.s64.b = regs[r3 | 1];
1420
        c.g2 = true;
1421
    }
1422

    
1423
    tcg_gen_add_i64(regs[r1], regs[r1], regs[r3]);
1424
    c.u.s64.a = regs[r1];
1425
    c.g1 = true;
1426

    
1427
    return help_branch(s, &c, is_imm, imm, o->in2);
1428
}
1429

    
1430
static ExitStatus op_cj(DisasContext *s, DisasOps *o)
1431
{
1432
    int imm, m3 = get_field(s->fields, m3);
1433
    bool is_imm;
1434
    DisasCompare c;
1435

    
1436
    /* Bit 3 of the m3 field is reserved and should be zero.
1437
       Choose to ignore it wrt the ltgt_cond table above.  */
1438
    c.cond = ltgt_cond[m3 & 14];
1439
    if (s->insn->data) {
1440
        c.cond = tcg_unsigned_cond(c.cond);
1441
    }
1442
    c.is_64 = c.g1 = c.g2 = true;
1443
    c.u.s64.a = o->in1;
1444
    c.u.s64.b = o->in2;
1445

    
1446
    is_imm = have_field(s->fields, i4);
1447
    if (is_imm) {
1448
        imm = get_field(s->fields, i4);
1449
    } else {
1450
        imm = 0;
1451
        o->out = get_address(s, 0, get_field(s->fields, b4),
1452
                             get_field(s->fields, d4));
1453
    }
1454

    
1455
    return help_branch(s, &c, is_imm, imm, o->out);
1456
}
1457

    
1458
static ExitStatus op_ceb(DisasContext *s, DisasOps *o)
1459
{
1460
    gen_helper_ceb(cc_op, cpu_env, o->in1, o->in2);
1461
    set_cc_static(s);
1462
    return NO_EXIT;
1463
}
1464

    
1465
static ExitStatus op_cdb(DisasContext *s, DisasOps *o)
1466
{
1467
    gen_helper_cdb(cc_op, cpu_env, o->in1, o->in2);
1468
    set_cc_static(s);
1469
    return NO_EXIT;
1470
}
1471

    
1472
static ExitStatus op_cxb(DisasContext *s, DisasOps *o)
1473
{
1474
    gen_helper_cxb(cc_op, cpu_env, o->out, o->out2, o->in1, o->in2);
1475
    set_cc_static(s);
1476
    return NO_EXIT;
1477
}
1478

    
1479
static ExitStatus op_cfeb(DisasContext *s, DisasOps *o)
1480
{
1481
    TCGv_i32 m3 = tcg_const_i32(get_field(s->fields, m3));
1482
    gen_helper_cfeb(o->out, cpu_env, o->in2, m3);
1483
    tcg_temp_free_i32(m3);
1484
    gen_set_cc_nz_f32(s, o->in2);
1485
    return NO_EXIT;
1486
}
1487

    
1488
static ExitStatus op_cfdb(DisasContext *s, DisasOps *o)
1489
{
1490
    TCGv_i32 m3 = tcg_const_i32(get_field(s->fields, m3));
1491
    gen_helper_cfdb(o->out, cpu_env, o->in2, m3);
1492
    tcg_temp_free_i32(m3);
1493
    gen_set_cc_nz_f64(s, o->in2);
1494
    return NO_EXIT;
1495
}
1496

    
1497
static ExitStatus op_cfxb(DisasContext *s, DisasOps *o)
1498
{
1499
    TCGv_i32 m3 = tcg_const_i32(get_field(s->fields, m3));
1500
    gen_helper_cfxb(o->out, cpu_env, o->in1, o->in2, m3);
1501
    tcg_temp_free_i32(m3);
1502
    gen_set_cc_nz_f128(s, o->in1, o->in2);
1503
    return NO_EXIT;
1504
}
1505

    
1506
static ExitStatus op_cgeb(DisasContext *s, DisasOps *o)
1507
{
1508
    TCGv_i32 m3 = tcg_const_i32(get_field(s->fields, m3));
1509
    gen_helper_cgeb(o->out, cpu_env, o->in2, m3);
1510
    tcg_temp_free_i32(m3);
1511
    gen_set_cc_nz_f32(s, o->in2);
1512
    return NO_EXIT;
1513
}
1514

    
1515
static ExitStatus op_cgdb(DisasContext *s, DisasOps *o)
1516
{
1517
    TCGv_i32 m3 = tcg_const_i32(get_field(s->fields, m3));
1518
    gen_helper_cgdb(o->out, cpu_env, o->in2, m3);
1519
    tcg_temp_free_i32(m3);
1520
    gen_set_cc_nz_f64(s, o->in2);
1521
    return NO_EXIT;
1522
}
1523

    
1524
static ExitStatus op_cgxb(DisasContext *s, DisasOps *o)
1525
{
1526
    TCGv_i32 m3 = tcg_const_i32(get_field(s->fields, m3));
1527
    gen_helper_cgxb(o->out, cpu_env, o->in1, o->in2, m3);
1528
    tcg_temp_free_i32(m3);
1529
    gen_set_cc_nz_f128(s, o->in1, o->in2);
1530
    return NO_EXIT;
1531
}
1532

    
1533
static ExitStatus op_clfeb(DisasContext *s, DisasOps *o)
1534
{
1535
    TCGv_i32 m3 = tcg_const_i32(get_field(s->fields, m3));
1536
    gen_helper_clfeb(o->out, cpu_env, o->in2, m3);
1537
    tcg_temp_free_i32(m3);
1538
    gen_set_cc_nz_f32(s, o->in2);
1539
    return NO_EXIT;
1540
}
1541

    
1542
static ExitStatus op_clfdb(DisasContext *s, DisasOps *o)
1543
{
1544
    TCGv_i32 m3 = tcg_const_i32(get_field(s->fields, m3));
1545
    gen_helper_clfdb(o->out, cpu_env, o->in2, m3);
1546
    tcg_temp_free_i32(m3);
1547
    gen_set_cc_nz_f64(s, o->in2);
1548
    return NO_EXIT;
1549
}
1550

    
1551
static ExitStatus op_clfxb(DisasContext *s, DisasOps *o)
1552
{
1553
    TCGv_i32 m3 = tcg_const_i32(get_field(s->fields, m3));
1554
    gen_helper_clfxb(o->out, cpu_env, o->in1, o->in2, m3);
1555
    tcg_temp_free_i32(m3);
1556
    gen_set_cc_nz_f128(s, o->in1, o->in2);
1557
    return NO_EXIT;
1558
}
1559

    
1560
static ExitStatus op_clgeb(DisasContext *s, DisasOps *o)
1561
{
1562
    TCGv_i32 m3 = tcg_const_i32(get_field(s->fields, m3));
1563
    gen_helper_clgeb(o->out, cpu_env, o->in2, m3);
1564
    tcg_temp_free_i32(m3);
1565
    gen_set_cc_nz_f32(s, o->in2);
1566
    return NO_EXIT;
1567
}
1568

    
1569
static ExitStatus op_clgdb(DisasContext *s, DisasOps *o)
1570
{
1571
    TCGv_i32 m3 = tcg_const_i32(get_field(s->fields, m3));
1572
    gen_helper_clgdb(o->out, cpu_env, o->in2, m3);
1573
    tcg_temp_free_i32(m3);
1574
    gen_set_cc_nz_f64(s, o->in2);
1575
    return NO_EXIT;
1576
}
1577

    
1578
static ExitStatus op_clgxb(DisasContext *s, DisasOps *o)
1579
{
1580
    TCGv_i32 m3 = tcg_const_i32(get_field(s->fields, m3));
1581
    gen_helper_clgxb(o->out, cpu_env, o->in1, o->in2, m3);
1582
    tcg_temp_free_i32(m3);
1583
    gen_set_cc_nz_f128(s, o->in1, o->in2);
1584
    return NO_EXIT;
1585
}
1586

    
1587
static ExitStatus op_cegb(DisasContext *s, DisasOps *o)
1588
{
1589
    TCGv_i32 m3 = tcg_const_i32(get_field(s->fields, m3));
1590
    gen_helper_cegb(o->out, cpu_env, o->in2, m3);
1591
    tcg_temp_free_i32(m3);
1592
    return NO_EXIT;
1593
}
1594

    
1595
static ExitStatus op_cdgb(DisasContext *s, DisasOps *o)
1596
{
1597
    TCGv_i32 m3 = tcg_const_i32(get_field(s->fields, m3));
1598
    gen_helper_cdgb(o->out, cpu_env, o->in2, m3);
1599
    tcg_temp_free_i32(m3);
1600
    return NO_EXIT;
1601
}
1602

    
1603
static ExitStatus op_cxgb(DisasContext *s, DisasOps *o)
1604
{
1605
    TCGv_i32 m3 = tcg_const_i32(get_field(s->fields, m3));
1606
    gen_helper_cxgb(o->out, cpu_env, o->in2, m3);
1607
    tcg_temp_free_i32(m3);
1608
    return_low128(o->out2);
1609
    return NO_EXIT;
1610
}
1611

    
1612
static ExitStatus op_cksm(DisasContext *s, DisasOps *o)
1613
{
1614
    int r2 = get_field(s->fields, r2);
1615
    TCGv_i64 len = tcg_temp_new_i64();
1616

    
1617
    potential_page_fault(s);
1618
    gen_helper_cksm(len, cpu_env, o->in1, o->in2, regs[r2 + 1]);
1619
    set_cc_static(s);
1620
    return_low128(o->out);
1621

    
1622
    tcg_gen_add_i64(regs[r2], regs[r2], len);
1623
    tcg_gen_sub_i64(regs[r2 + 1], regs[r2 + 1], len);
1624
    tcg_temp_free_i64(len);
1625

    
1626
    return NO_EXIT;
1627
}
1628

    
1629
static ExitStatus op_clc(DisasContext *s, DisasOps *o)
1630
{
1631
    int l = get_field(s->fields, l1);
1632
    TCGv_i32 vl;
1633

    
1634
    switch (l + 1) {
1635
    case 1:
1636
        tcg_gen_qemu_ld8u(cc_src, o->addr1, get_mem_index(s));
1637
        tcg_gen_qemu_ld8u(cc_dst, o->in2, get_mem_index(s));
1638
        break;
1639
    case 2:
1640
        tcg_gen_qemu_ld16u(cc_src, o->addr1, get_mem_index(s));
1641
        tcg_gen_qemu_ld16u(cc_dst, o->in2, get_mem_index(s));
1642
        break;
1643
    case 4:
1644
        tcg_gen_qemu_ld32u(cc_src, o->addr1, get_mem_index(s));
1645
        tcg_gen_qemu_ld32u(cc_dst, o->in2, get_mem_index(s));
1646
        break;
1647
    case 8:
1648
        tcg_gen_qemu_ld64(cc_src, o->addr1, get_mem_index(s));
1649
        tcg_gen_qemu_ld64(cc_dst, o->in2, get_mem_index(s));
1650
        break;
1651
    default:
1652
        potential_page_fault(s);
1653
        vl = tcg_const_i32(l);
1654
        gen_helper_clc(cc_op, cpu_env, vl, o->addr1, o->in2);
1655
        tcg_temp_free_i32(vl);
1656
        set_cc_static(s);
1657
        return NO_EXIT;
1658
    }
1659
    gen_op_update2_cc_i64(s, CC_OP_LTUGTU_64, cc_src, cc_dst);
1660
    return NO_EXIT;
1661
}
1662

    
1663
static ExitStatus op_clcle(DisasContext *s, DisasOps *o)
1664
{
1665
    TCGv_i32 r1 = tcg_const_i32(get_field(s->fields, r1));
1666
    TCGv_i32 r3 = tcg_const_i32(get_field(s->fields, r3));
1667
    potential_page_fault(s);
1668
    gen_helper_clcle(cc_op, cpu_env, r1, o->in2, r3);
1669
    tcg_temp_free_i32(r1);
1670
    tcg_temp_free_i32(r3);
1671
    set_cc_static(s);
1672
    return NO_EXIT;
1673
}
1674

    
1675
static ExitStatus op_clm(DisasContext *s, DisasOps *o)
1676
{
1677
    TCGv_i32 m3 = tcg_const_i32(get_field(s->fields, m3));
1678
    TCGv_i32 t1 = tcg_temp_new_i32();
1679
    tcg_gen_trunc_i64_i32(t1, o->in1);
1680
    potential_page_fault(s);
1681
    gen_helper_clm(cc_op, cpu_env, t1, m3, o->in2);
1682
    set_cc_static(s);
1683
    tcg_temp_free_i32(t1);
1684
    tcg_temp_free_i32(m3);
1685
    return NO_EXIT;
1686
}
1687

    
1688
static ExitStatus op_clst(DisasContext *s, DisasOps *o)
1689
{
1690
    potential_page_fault(s);
1691
    gen_helper_clst(o->in1, cpu_env, regs[0], o->in1, o->in2);
1692
    set_cc_static(s);
1693
    return_low128(o->in2);
1694
    return NO_EXIT;
1695
}
1696

    
1697
static ExitStatus op_cs(DisasContext *s, DisasOps *o)
1698
{
1699
    int r3 = get_field(s->fields, r3);
1700
    potential_page_fault(s);
1701
    gen_helper_cs(o->out, cpu_env, o->in1, o->in2, regs[r3]);
1702
    set_cc_static(s);
1703
    return NO_EXIT;
1704
}
1705

    
1706
static ExitStatus op_csg(DisasContext *s, DisasOps *o)
1707
{
1708
    int r3 = get_field(s->fields, r3);
1709
    potential_page_fault(s);
1710
    gen_helper_csg(o->out, cpu_env, o->in1, o->in2, regs[r3]);
1711
    set_cc_static(s);
1712
    return NO_EXIT;
1713
}
1714

    
1715
#ifndef CONFIG_USER_ONLY
1716
static ExitStatus op_csp(DisasContext *s, DisasOps *o)
1717
{
1718
    TCGv_i32 r1 = tcg_const_i32(get_field(s->fields, r1));
1719
    check_privileged(s);
1720
    gen_helper_csp(cc_op, cpu_env, r1, o->in2);
1721
    tcg_temp_free_i32(r1);
1722
    set_cc_static(s);
1723
    return NO_EXIT;
1724
}
1725
#endif
1726

    
1727
static ExitStatus op_cds(DisasContext *s, DisasOps *o)
1728
{
1729
    int r3 = get_field(s->fields, r3);
1730
    TCGv_i64 in3 = tcg_temp_new_i64();
1731
    tcg_gen_deposit_i64(in3, regs[r3 + 1], regs[r3], 32, 32);
1732
    potential_page_fault(s);
1733
    gen_helper_csg(o->out, cpu_env, o->in1, o->in2, in3);
1734
    tcg_temp_free_i64(in3);
1735
    set_cc_static(s);
1736
    return NO_EXIT;
1737
}
1738

    
1739
static ExitStatus op_cdsg(DisasContext *s, DisasOps *o)
1740
{
1741
    TCGv_i32 r1 = tcg_const_i32(get_field(s->fields, r1));
1742
    TCGv_i32 r3 = tcg_const_i32(get_field(s->fields, r3));
1743
    potential_page_fault(s);
1744
    /* XXX rewrite in tcg */
1745
    gen_helper_cdsg(cc_op, cpu_env, r1, o->in2, r3);
1746
    set_cc_static(s);
1747
    return NO_EXIT;
1748
}
1749

    
1750
static ExitStatus op_cvd(DisasContext *s, DisasOps *o)
1751
{
1752
    TCGv_i64 t1 = tcg_temp_new_i64();
1753
    TCGv_i32 t2 = tcg_temp_new_i32();
1754
    tcg_gen_trunc_i64_i32(t2, o->in1);
1755
    gen_helper_cvd(t1, t2);
1756
    tcg_temp_free_i32(t2);
1757
    tcg_gen_qemu_st64(t1, o->in2, get_mem_index(s));
1758
    tcg_temp_free_i64(t1);
1759
    return NO_EXIT;
1760
}
1761

    
1762
static ExitStatus op_ct(DisasContext *s, DisasOps *o)
1763
{
1764
    int m3 = get_field(s->fields, m3);
1765
    int lab = gen_new_label();
1766
    TCGv_i32 t;
1767
    TCGCond c;
1768

    
1769
    /* Bit 3 of the m3 field is reserved and should be zero.
1770
       Choose to ignore it wrt the ltgt_cond table above.  */
1771
    c = tcg_invert_cond(ltgt_cond[m3 & 14]);
1772
    if (s->insn->data) {
1773
        c = tcg_unsigned_cond(c);
1774
    }
1775
    tcg_gen_brcond_i64(c, o->in1, o->in2, lab);
1776

    
1777
    /* Set DXC to 0xff.  */
1778
    t = tcg_temp_new_i32();
1779
    tcg_gen_ld_i32(t, cpu_env, offsetof(CPUS390XState, fpc));
1780
    tcg_gen_ori_i32(t, t, 0xff00);
1781
    tcg_gen_st_i32(t, cpu_env, offsetof(CPUS390XState, fpc));
1782
    tcg_temp_free_i32(t);
1783

    
1784
    /* Trap.  */
1785
    gen_program_exception(s, PGM_DATA);
1786

    
1787
    gen_set_label(lab);
1788
    return NO_EXIT;
1789
}
1790

    
1791
#ifndef CONFIG_USER_ONLY
1792
static ExitStatus op_diag(DisasContext *s, DisasOps *o)
1793
{
1794
    TCGv_i32 tmp;
1795

    
1796
    check_privileged(s);
1797
    potential_page_fault(s);
1798

    
1799
    /* We pretend the format is RX_a so that D2 is the field we want.  */
1800
    tmp = tcg_const_i32(get_field(s->fields, d2) & 0xfff);
1801
    gen_helper_diag(regs[2], cpu_env, tmp, regs[2], regs[1]);
1802
    tcg_temp_free_i32(tmp);
1803
    return NO_EXIT;
1804
}
1805
#endif
1806

    
1807
static ExitStatus op_divs32(DisasContext *s, DisasOps *o)
1808
{
1809
    gen_helper_divs32(o->out2, cpu_env, o->in1, o->in2);
1810
    return_low128(o->out);
1811
    return NO_EXIT;
1812
}
1813

    
1814
static ExitStatus op_divu32(DisasContext *s, DisasOps *o)
1815
{
1816
    gen_helper_divu32(o->out2, cpu_env, o->in1, o->in2);
1817
    return_low128(o->out);
1818
    return NO_EXIT;
1819
}
1820

    
1821
static ExitStatus op_divs64(DisasContext *s, DisasOps *o)
1822
{
1823
    gen_helper_divs64(o->out2, cpu_env, o->in1, o->in2);
1824
    return_low128(o->out);
1825
    return NO_EXIT;
1826
}
1827

    
1828
static ExitStatus op_divu64(DisasContext *s, DisasOps *o)
1829
{
1830
    gen_helper_divu64(o->out2, cpu_env, o->out, o->out2, o->in2);
1831
    return_low128(o->out);
1832
    return NO_EXIT;
1833
}
1834

    
1835
static ExitStatus op_deb(DisasContext *s, DisasOps *o)
1836
{
1837
    gen_helper_deb(o->out, cpu_env, o->in1, o->in2);
1838
    return NO_EXIT;
1839
}
1840

    
1841
static ExitStatus op_ddb(DisasContext *s, DisasOps *o)
1842
{
1843
    gen_helper_ddb(o->out, cpu_env, o->in1, o->in2);
1844
    return NO_EXIT;
1845
}
1846

    
1847
static ExitStatus op_dxb(DisasContext *s, DisasOps *o)
1848
{
1849
    gen_helper_dxb(o->out, cpu_env, o->out, o->out2, o->in1, o->in2);
1850
    return_low128(o->out2);
1851
    return NO_EXIT;
1852
}
1853

    
1854
static ExitStatus op_ear(DisasContext *s, DisasOps *o)
1855
{
1856
    int r2 = get_field(s->fields, r2);
1857
    tcg_gen_ld32u_i64(o->out, cpu_env, offsetof(CPUS390XState, aregs[r2]));
1858
    return NO_EXIT;
1859
}
1860

    
1861
static ExitStatus op_efpc(DisasContext *s, DisasOps *o)
1862
{
1863
    tcg_gen_ld32u_i64(o->out, cpu_env, offsetof(CPUS390XState, fpc));
1864
    return NO_EXIT;
1865
}
1866

    
1867
static ExitStatus op_ex(DisasContext *s, DisasOps *o)
1868
{
1869
    /* ??? Perhaps a better way to implement EXECUTE is to set a bit in
1870
       tb->flags, (ab)use the tb->cs_base field as the address of
1871
       the template in memory, and grab 8 bits of tb->flags/cflags for
1872
       the contents of the register.  We would then recognize all this
1873
       in gen_intermediate_code_internal, generating code for exactly
1874
       one instruction.  This new TB then gets executed normally.
1875

1876
       On the other hand, this seems to be mostly used for modifying
1877
       MVC inside of memcpy, which needs a helper call anyway.  So
1878
       perhaps this doesn't bear thinking about any further.  */
1879

    
1880
    TCGv_i64 tmp;
1881

    
1882
    update_psw_addr(s);
1883
    update_cc_op(s);
1884

    
1885
    tmp = tcg_const_i64(s->next_pc);
1886
    gen_helper_ex(cc_op, cpu_env, cc_op, o->in1, o->in2, tmp);
1887
    tcg_temp_free_i64(tmp);
1888

    
1889
    set_cc_static(s);
1890
    return NO_EXIT;
1891
}
1892

    
1893
static ExitStatus op_flogr(DisasContext *s, DisasOps *o)
1894
{
1895
    /* We'll use the original input for cc computation, since we get to
1896
       compare that against 0, which ought to be better than comparing
1897
       the real output against 64.  It also lets cc_dst be a convenient
1898
       temporary during our computation.  */
1899
    gen_op_update1_cc_i64(s, CC_OP_FLOGR, o->in2);
1900

    
1901
    /* R1 = IN ? CLZ(IN) : 64.  */
1902
    gen_helper_clz(o->out, o->in2);
1903

    
1904
    /* R1+1 = IN & ~(found bit).  Note that we may attempt to shift this
1905
       value by 64, which is undefined.  But since the shift is 64 iff the
1906
       input is zero, we still get the correct result after and'ing.  */
1907
    tcg_gen_movi_i64(o->out2, 0x8000000000000000ull);
1908
    tcg_gen_shr_i64(o->out2, o->out2, o->out);
1909
    tcg_gen_andc_i64(o->out2, cc_dst, o->out2);
1910
    return NO_EXIT;
1911
}
1912

    
1913
static ExitStatus op_icm(DisasContext *s, DisasOps *o)
1914
{
1915
    int m3 = get_field(s->fields, m3);
1916
    int pos, len, base = s->insn->data;
1917
    TCGv_i64 tmp = tcg_temp_new_i64();
1918
    uint64_t ccm;
1919

    
1920
    switch (m3) {
1921
    case 0xf:
1922
        /* Effectively a 32-bit load.  */
1923
        tcg_gen_qemu_ld32u(tmp, o->in2, get_mem_index(s));
1924
        len = 32;
1925
        goto one_insert;
1926

    
1927
    case 0xc:
1928
    case 0x6:
1929
    case 0x3:
1930
        /* Effectively a 16-bit load.  */
1931
        tcg_gen_qemu_ld16u(tmp, o->in2, get_mem_index(s));
1932
        len = 16;
1933
        goto one_insert;
1934

    
1935
    case 0x8:
1936
    case 0x4:
1937
    case 0x2:
1938
    case 0x1:
1939
        /* Effectively an 8-bit load.  */
1940
        tcg_gen_qemu_ld8u(tmp, o->in2, get_mem_index(s));
1941
        len = 8;
1942
        goto one_insert;
1943

    
1944
    one_insert:
1945
        pos = base + ctz32(m3) * 8;
1946
        tcg_gen_deposit_i64(o->out, o->out, tmp, pos, len);
1947
        ccm = ((1ull << len) - 1) << pos;
1948
        break;
1949

    
1950
    default:
1951
        /* This is going to be a sequence of loads and inserts.  */
1952
        pos = base + 32 - 8;
1953
        ccm = 0;
1954
        while (m3) {
1955
            if (m3 & 0x8) {
1956
                tcg_gen_qemu_ld8u(tmp, o->in2, get_mem_index(s));
1957
                tcg_gen_addi_i64(o->in2, o->in2, 1);
1958
                tcg_gen_deposit_i64(o->out, o->out, tmp, pos, 8);
1959
                ccm |= 0xff << pos;
1960
            }
1961
            m3 = (m3 << 1) & 0xf;
1962
            pos -= 8;
1963
        }
1964
        break;
1965
    }
1966

    
1967
    tcg_gen_movi_i64(tmp, ccm);
1968
    gen_op_update2_cc_i64(s, CC_OP_ICM, tmp, o->out);
1969
    tcg_temp_free_i64(tmp);
1970
    return NO_EXIT;
1971
}
1972

    
1973
static ExitStatus op_insi(DisasContext *s, DisasOps *o)
1974
{
1975
    int shift = s->insn->data & 0xff;
1976
    int size = s->insn->data >> 8;
1977
    tcg_gen_deposit_i64(o->out, o->in1, o->in2, shift, size);
1978
    return NO_EXIT;
1979
}
1980

    
1981
static ExitStatus op_ipm(DisasContext *s, DisasOps *o)
1982
{
1983
    TCGv_i64 t1;
1984

    
1985
    gen_op_calc_cc(s);
1986
    tcg_gen_andi_i64(o->out, o->out, ~0xff000000ull);
1987

    
1988
    t1 = tcg_temp_new_i64();
1989
    tcg_gen_shli_i64(t1, psw_mask, 20);
1990
    tcg_gen_shri_i64(t1, t1, 36);
1991
    tcg_gen_or_i64(o->out, o->out, t1);
1992

    
1993
    tcg_gen_extu_i32_i64(t1, cc_op);
1994
    tcg_gen_shli_i64(t1, t1, 28);
1995
    tcg_gen_or_i64(o->out, o->out, t1);
1996
    tcg_temp_free_i64(t1);
1997
    return NO_EXIT;
1998
}
1999

    
2000
#ifndef CONFIG_USER_ONLY
2001
static ExitStatus op_ipte(DisasContext *s, DisasOps *o)
2002
{
2003
    check_privileged(s);
2004
    gen_helper_ipte(cpu_env, o->in1, o->in2);
2005
    return NO_EXIT;
2006
}
2007

    
2008
static ExitStatus op_iske(DisasContext *s, DisasOps *o)
2009
{
2010
    check_privileged(s);
2011
    gen_helper_iske(o->out, cpu_env, o->in2);
2012
    return NO_EXIT;
2013
}
2014
#endif
2015

    
2016
static ExitStatus op_ldeb(DisasContext *s, DisasOps *o)
2017
{
2018
    gen_helper_ldeb(o->out, cpu_env, o->in2);
2019
    return NO_EXIT;
2020
}
2021

    
2022
static ExitStatus op_ledb(DisasContext *s, DisasOps *o)
2023
{
2024
    gen_helper_ledb(o->out, cpu_env, o->in2);
2025
    return NO_EXIT;
2026
}
2027

    
2028
static ExitStatus op_ldxb(DisasContext *s, DisasOps *o)
2029
{
2030
    gen_helper_ldxb(o->out, cpu_env, o->in1, o->in2);
2031
    return NO_EXIT;
2032
}
2033

    
2034
static ExitStatus op_lexb(DisasContext *s, DisasOps *o)
2035
{
2036
    gen_helper_lexb(o->out, cpu_env, o->in1, o->in2);
2037
    return NO_EXIT;
2038
}
2039

    
2040
static ExitStatus op_lxdb(DisasContext *s, DisasOps *o)
2041
{
2042
    gen_helper_lxdb(o->out, cpu_env, o->in2);
2043
    return_low128(o->out2);
2044
    return NO_EXIT;
2045
}
2046

    
2047
static ExitStatus op_lxeb(DisasContext *s, DisasOps *o)
2048
{
2049
    gen_helper_lxeb(o->out, cpu_env, o->in2);
2050
    return_low128(o->out2);
2051
    return NO_EXIT;
2052
}
2053

    
2054
static ExitStatus op_llgt(DisasContext *s, DisasOps *o)
2055
{
2056
    tcg_gen_andi_i64(o->out, o->in2, 0x7fffffff);
2057
    return NO_EXIT;
2058
}
2059

    
2060
static ExitStatus op_ld8s(DisasContext *s, DisasOps *o)
2061
{
2062
    tcg_gen_qemu_ld8s(o->out, o->in2, get_mem_index(s));
2063
    return NO_EXIT;
2064
}
2065

    
2066
static ExitStatus op_ld8u(DisasContext *s, DisasOps *o)
2067
{
2068
    tcg_gen_qemu_ld8u(o->out, o->in2, get_mem_index(s));
2069
    return NO_EXIT;
2070
}
2071

    
2072
static ExitStatus op_ld16s(DisasContext *s, DisasOps *o)
2073
{
2074
    tcg_gen_qemu_ld16s(o->out, o->in2, get_mem_index(s));
2075
    return NO_EXIT;
2076
}
2077

    
2078
static ExitStatus op_ld16u(DisasContext *s, DisasOps *o)
2079
{
2080
    tcg_gen_qemu_ld16u(o->out, o->in2, get_mem_index(s));
2081
    return NO_EXIT;
2082
}
2083

    
2084
static ExitStatus op_ld32s(DisasContext *s, DisasOps *o)
2085
{
2086
    tcg_gen_qemu_ld32s(o->out, o->in2, get_mem_index(s));
2087
    return NO_EXIT;
2088
}
2089

    
2090
static ExitStatus op_ld32u(DisasContext *s, DisasOps *o)
2091
{
2092
    tcg_gen_qemu_ld32u(o->out, o->in2, get_mem_index(s));
2093
    return NO_EXIT;
2094
}
2095

    
2096
static ExitStatus op_ld64(DisasContext *s, DisasOps *o)
2097
{
2098
    tcg_gen_qemu_ld64(o->out, o->in2, get_mem_index(s));
2099
    return NO_EXIT;
2100
}
2101

    
2102
static ExitStatus op_loc(DisasContext *s, DisasOps *o)
2103
{
2104
    DisasCompare c;
2105

    
2106
    disas_jcc(s, &c, get_field(s->fields, m3));
2107

    
2108
    if (c.is_64) {
2109
        tcg_gen_movcond_i64(c.cond, o->out, c.u.s64.a, c.u.s64.b,
2110
                            o->in2, o->in1);
2111
        free_compare(&c);
2112
    } else {
2113
        TCGv_i32 t32 = tcg_temp_new_i32();
2114
        TCGv_i64 t, z;
2115

    
2116
        tcg_gen_setcond_i32(c.cond, t32, c.u.s32.a, c.u.s32.b);
2117
        free_compare(&c);
2118

    
2119
        t = tcg_temp_new_i64();
2120
        tcg_gen_extu_i32_i64(t, t32);
2121
        tcg_temp_free_i32(t32);
2122

    
2123
        z = tcg_const_i64(0);
2124
        tcg_gen_movcond_i64(TCG_COND_NE, o->out, t, z, o->in2, o->in1);
2125
        tcg_temp_free_i64(t);
2126
        tcg_temp_free_i64(z);
2127
    }
2128

    
2129
    return NO_EXIT;
2130
}
2131

    
2132
#ifndef CONFIG_USER_ONLY
2133
static ExitStatus op_lctl(DisasContext *s, DisasOps *o)
2134
{
2135
    TCGv_i32 r1 = tcg_const_i32(get_field(s->fields, r1));
2136
    TCGv_i32 r3 = tcg_const_i32(get_field(s->fields, r3));
2137
    check_privileged(s);
2138
    potential_page_fault(s);
2139
    gen_helper_lctl(cpu_env, r1, o->in2, r3);
2140
    tcg_temp_free_i32(r1);
2141
    tcg_temp_free_i32(r3);
2142
    return NO_EXIT;
2143
}
2144

    
2145
static ExitStatus op_lctlg(DisasContext *s, DisasOps *o)
2146
{
2147
    TCGv_i32 r1 = tcg_const_i32(get_field(s->fields, r1));
2148
    TCGv_i32 r3 = tcg_const_i32(get_field(s->fields, r3));
2149
    check_privileged(s);
2150
    potential_page_fault(s);
2151
    gen_helper_lctlg(cpu_env, r1, o->in2, r3);
2152
    tcg_temp_free_i32(r1);
2153
    tcg_temp_free_i32(r3);
2154
    return NO_EXIT;
2155
}
2156
static ExitStatus op_lra(DisasContext *s, DisasOps *o)
2157
{
2158
    check_privileged(s);
2159
    potential_page_fault(s);
2160
    gen_helper_lra(o->out, cpu_env, o->in2);
2161
    set_cc_static(s);
2162
    return NO_EXIT;
2163
}
2164

    
2165
static ExitStatus op_lpsw(DisasContext *s, DisasOps *o)
2166
{
2167
    TCGv_i64 t1, t2;
2168

    
2169
    check_privileged(s);
2170

    
2171
    t1 = tcg_temp_new_i64();
2172
    t2 = tcg_temp_new_i64();
2173
    tcg_gen_qemu_ld32u(t1, o->in2, get_mem_index(s));
2174
    tcg_gen_addi_i64(o->in2, o->in2, 4);
2175
    tcg_gen_qemu_ld32u(t2, o->in2, get_mem_index(s));
2176
    /* Convert the 32-bit PSW_MASK into the 64-bit PSW_MASK.  */
2177
    tcg_gen_shli_i64(t1, t1, 32);
2178
    gen_helper_load_psw(cpu_env, t1, t2);
2179
    tcg_temp_free_i64(t1);
2180
    tcg_temp_free_i64(t2);
2181
    return EXIT_NORETURN;
2182
}
2183

    
2184
static ExitStatus op_lpswe(DisasContext *s, DisasOps *o)
2185
{
2186
    TCGv_i64 t1, t2;
2187

    
2188
    check_privileged(s);
2189

    
2190
    t1 = tcg_temp_new_i64();
2191
    t2 = tcg_temp_new_i64();
2192
    tcg_gen_qemu_ld64(t1, o->in2, get_mem_index(s));
2193
    tcg_gen_addi_i64(o->in2, o->in2, 8);
2194
    tcg_gen_qemu_ld64(t2, o->in2, get_mem_index(s));
2195
    gen_helper_load_psw(cpu_env, t1, t2);
2196
    tcg_temp_free_i64(t1);
2197
    tcg_temp_free_i64(t2);
2198
    return EXIT_NORETURN;
2199
}
2200
#endif
2201

    
2202
static ExitStatus op_lam(DisasContext *s, DisasOps *o)
2203
{
2204
    TCGv_i32 r1 = tcg_const_i32(get_field(s->fields, r1));
2205
    TCGv_i32 r3 = tcg_const_i32(get_field(s->fields, r3));
2206
    potential_page_fault(s);
2207
    gen_helper_lam(cpu_env, r1, o->in2, r3);
2208
    tcg_temp_free_i32(r1);
2209
    tcg_temp_free_i32(r3);
2210
    return NO_EXIT;
2211
}
2212

    
2213
static ExitStatus op_lm32(DisasContext *s, DisasOps *o)
2214
{
2215
    int r1 = get_field(s->fields, r1);
2216
    int r3 = get_field(s->fields, r3);
2217
    TCGv_i64 t = tcg_temp_new_i64();
2218
    TCGv_i64 t4 = tcg_const_i64(4);
2219

    
2220
    while (1) {
2221
        tcg_gen_qemu_ld32u(t, o->in2, get_mem_index(s));
2222
        store_reg32_i64(r1, t);
2223
        if (r1 == r3) {
2224
            break;
2225
        }
2226
        tcg_gen_add_i64(o->in2, o->in2, t4);
2227
        r1 = (r1 + 1) & 15;
2228
    }
2229

    
2230
    tcg_temp_free_i64(t);
2231
    tcg_temp_free_i64(t4);
2232
    return NO_EXIT;
2233
}
2234

    
2235
static ExitStatus op_lmh(DisasContext *s, DisasOps *o)
2236
{
2237
    int r1 = get_field(s->fields, r1);
2238
    int r3 = get_field(s->fields, r3);
2239
    TCGv_i64 t = tcg_temp_new_i64();
2240
    TCGv_i64 t4 = tcg_const_i64(4);
2241

    
2242
    while (1) {
2243
        tcg_gen_qemu_ld32u(t, o->in2, get_mem_index(s));
2244
        store_reg32h_i64(r1, t);
2245
        if (r1 == r3) {
2246
            break;
2247
        }
2248
        tcg_gen_add_i64(o->in2, o->in2, t4);
2249
        r1 = (r1 + 1) & 15;
2250
    }
2251

    
2252
    tcg_temp_free_i64(t);
2253
    tcg_temp_free_i64(t4);
2254
    return NO_EXIT;
2255
}
2256

    
2257
static ExitStatus op_lm64(DisasContext *s, DisasOps *o)
2258
{
2259
    int r1 = get_field(s->fields, r1);
2260
    int r3 = get_field(s->fields, r3);
2261
    TCGv_i64 t8 = tcg_const_i64(8);
2262

    
2263
    while (1) {
2264
        tcg_gen_qemu_ld64(regs[r1], o->in2, get_mem_index(s));
2265
        if (r1 == r3) {
2266
            break;
2267
        }
2268
        tcg_gen_add_i64(o->in2, o->in2, t8);
2269
        r1 = (r1 + 1) & 15;
2270
    }
2271

    
2272
    tcg_temp_free_i64(t8);
2273
    return NO_EXIT;
2274
}
2275

    
2276
static ExitStatus op_mov2(DisasContext *s, DisasOps *o)
2277
{
2278
    o->out = o->in2;
2279
    o->g_out = o->g_in2;
2280
    TCGV_UNUSED_I64(o->in2);
2281
    o->g_in2 = false;
2282
    return NO_EXIT;
2283
}
2284

    
2285
static ExitStatus op_movx(DisasContext *s, DisasOps *o)
2286
{
2287
    o->out = o->in1;
2288
    o->out2 = o->in2;
2289
    o->g_out = o->g_in1;
2290
    o->g_out2 = o->g_in2;
2291
    TCGV_UNUSED_I64(o->in1);
2292
    TCGV_UNUSED_I64(o->in2);
2293
    o->g_in1 = o->g_in2 = false;
2294
    return NO_EXIT;
2295
}
2296

    
2297
static ExitStatus op_mvc(DisasContext *s, DisasOps *o)
2298
{
2299
    TCGv_i32 l = tcg_const_i32(get_field(s->fields, l1));
2300
    potential_page_fault(s);
2301
    gen_helper_mvc(cpu_env, l, o->addr1, o->in2);
2302
    tcg_temp_free_i32(l);
2303
    return NO_EXIT;
2304
}
2305

    
2306
static ExitStatus op_mvcl(DisasContext *s, DisasOps *o)
2307
{
2308
    TCGv_i32 r1 = tcg_const_i32(get_field(s->fields, r1));
2309
    TCGv_i32 r2 = tcg_const_i32(get_field(s->fields, r2));
2310
    potential_page_fault(s);
2311
    gen_helper_mvcl(cc_op, cpu_env, r1, r2);
2312
    tcg_temp_free_i32(r1);
2313
    tcg_temp_free_i32(r2);
2314
    set_cc_static(s);
2315
    return NO_EXIT;
2316
}
2317

    
2318
static ExitStatus op_mvcle(DisasContext *s, DisasOps *o)
2319
{
2320
    TCGv_i32 r1 = tcg_const_i32(get_field(s->fields, r1));
2321
    TCGv_i32 r3 = tcg_const_i32(get_field(s->fields, r3));
2322
    potential_page_fault(s);
2323
    gen_helper_mvcle(cc_op, cpu_env, r1, o->in2, r3);
2324
    tcg_temp_free_i32(r1);
2325
    tcg_temp_free_i32(r3);
2326
    set_cc_static(s);
2327
    return NO_EXIT;
2328
}
2329

    
2330
#ifndef CONFIG_USER_ONLY
2331
static ExitStatus op_mvcp(DisasContext *s, DisasOps *o)
2332
{
2333
    int r1 = get_field(s->fields, l1);
2334
    check_privileged(s);
2335
    potential_page_fault(s);
2336
    gen_helper_mvcp(cc_op, cpu_env, regs[r1], o->addr1, o->in2);
2337
    set_cc_static(s);
2338
    return NO_EXIT;
2339
}
2340

    
2341
static ExitStatus op_mvcs(DisasContext *s, DisasOps *o)
2342
{
2343
    int r1 = get_field(s->fields, l1);
2344
    check_privileged(s);
2345
    potential_page_fault(s);
2346
    gen_helper_mvcs(cc_op, cpu_env, regs[r1], o->addr1, o->in2);
2347
    set_cc_static(s);
2348
    return NO_EXIT;
2349
}
2350
#endif
2351

    
2352
static ExitStatus op_mvpg(DisasContext *s, DisasOps *o)
2353
{
2354
    potential_page_fault(s);
2355
    gen_helper_mvpg(cpu_env, regs[0], o->in1, o->in2);
2356
    set_cc_static(s);
2357
    return NO_EXIT;
2358
}
2359

    
2360
static ExitStatus op_mvst(DisasContext *s, DisasOps *o)
2361
{
2362
    potential_page_fault(s);
2363
    gen_helper_mvst(o->in1, cpu_env, regs[0], o->in1, o->in2);
2364
    set_cc_static(s);
2365
    return_low128(o->in2);
2366
    return NO_EXIT;
2367
}
2368

    
2369
static ExitStatus op_mul(DisasContext *s, DisasOps *o)
2370
{
2371
    tcg_gen_mul_i64(o->out, o->in1, o->in2);
2372
    return NO_EXIT;
2373
}
2374

    
2375
static ExitStatus op_mul128(DisasContext *s, DisasOps *o)
2376
{
2377
    gen_helper_mul128(o->out, cpu_env, o->in1, o->in2);
2378
    return_low128(o->out2);
2379
    return NO_EXIT;
2380
}
2381

    
2382
static ExitStatus op_meeb(DisasContext *s, DisasOps *o)
2383
{
2384
    gen_helper_meeb(o->out, cpu_env, o->in1, o->in2);
2385
    return NO_EXIT;
2386
}
2387

    
2388
static ExitStatus op_mdeb(DisasContext *s, DisasOps *o)
2389
{
2390
    gen_helper_mdeb(o->out, cpu_env, o->in1, o->in2);
2391
    return NO_EXIT;
2392
}
2393

    
2394
static ExitStatus op_mdb(DisasContext *s, DisasOps *o)
2395
{
2396
    gen_helper_mdb(o->out, cpu_env, o->in1, o->in2);
2397
    return NO_EXIT;
2398
}
2399

    
2400
static ExitStatus op_mxb(DisasContext *s, DisasOps *o)
2401
{
2402
    gen_helper_mxb(o->out, cpu_env, o->out, o->out2, o->in1, o->in2);
2403
    return_low128(o->out2);
2404
    return NO_EXIT;
2405
}
2406

    
2407
static ExitStatus op_mxdb(DisasContext *s, DisasOps *o)
2408
{
2409
    gen_helper_mxdb(o->out, cpu_env, o->out, o->out2, o->in2);
2410
    return_low128(o->out2);
2411
    return NO_EXIT;
2412
}
2413

    
2414
static ExitStatus op_maeb(DisasContext *s, DisasOps *o)
2415
{
2416
    TCGv_i64 r3 = load_freg32_i64(get_field(s->fields, r3));
2417
    gen_helper_maeb(o->out, cpu_env, o->in1, o->in2, r3);
2418
    tcg_temp_free_i64(r3);
2419
    return NO_EXIT;
2420
}
2421

    
2422
static ExitStatus op_madb(DisasContext *s, DisasOps *o)
2423
{
2424
    int r3 = get_field(s->fields, r3);
2425
    gen_helper_madb(o->out, cpu_env, o->in1, o->in2, fregs[r3]);
2426
    return NO_EXIT;
2427
}
2428

    
2429
static ExitStatus op_mseb(DisasContext *s, DisasOps *o)
2430
{
2431
    TCGv_i64 r3 = load_freg32_i64(get_field(s->fields, r3));
2432
    gen_helper_mseb(o->out, cpu_env, o->in1, o->in2, r3);
2433
    tcg_temp_free_i64(r3);
2434
    return NO_EXIT;
2435
}
2436

    
2437
static ExitStatus op_msdb(DisasContext *s, DisasOps *o)
2438
{
2439
    int r3 = get_field(s->fields, r3);
2440
    gen_helper_msdb(o->out, cpu_env, o->in1, o->in2, fregs[r3]);
2441
    return NO_EXIT;
2442
}
2443

    
2444
static ExitStatus op_nabs(DisasContext *s, DisasOps *o)
2445
{
2446
    gen_helper_nabs_i64(o->out, o->in2);
2447
    return NO_EXIT;
2448
}
2449

    
2450
static ExitStatus op_nabsf32(DisasContext *s, DisasOps *o)
2451
{
2452
    tcg_gen_ori_i64(o->out, o->in2, 0x80000000ull);
2453
    return NO_EXIT;
2454
}
2455

    
2456
static ExitStatus op_nabsf64(DisasContext *s, DisasOps *o)
2457
{
2458
    tcg_gen_ori_i64(o->out, o->in2, 0x8000000000000000ull);
2459
    return NO_EXIT;
2460
}
2461

    
2462
static ExitStatus op_nabsf128(DisasContext *s, DisasOps *o)
2463
{
2464
    tcg_gen_ori_i64(o->out, o->in1, 0x8000000000000000ull);
2465
    tcg_gen_mov_i64(o->out2, o->in2);
2466
    return NO_EXIT;
2467
}
2468

    
2469
static ExitStatus op_nc(DisasContext *s, DisasOps *o)
2470
{
2471
    TCGv_i32 l = tcg_const_i32(get_field(s->fields, l1));
2472
    potential_page_fault(s);
2473
    gen_helper_nc(cc_op, cpu_env, l, o->addr1, o->in2);
2474
    tcg_temp_free_i32(l);
2475
    set_cc_static(s);
2476
    return NO_EXIT;
2477
}
2478

    
2479
static ExitStatus op_neg(DisasContext *s, DisasOps *o)
2480
{
2481
    tcg_gen_neg_i64(o->out, o->in2);
2482
    return NO_EXIT;
2483
}
2484

    
2485
static ExitStatus op_negf32(DisasContext *s, DisasOps *o)
2486
{
2487
    tcg_gen_xori_i64(o->out, o->in2, 0x80000000ull);
2488
    return NO_EXIT;
2489
}
2490

    
2491
static ExitStatus op_negf64(DisasContext *s, DisasOps *o)
2492
{
2493
    tcg_gen_xori_i64(o->out, o->in2, 0x8000000000000000ull);
2494
    return NO_EXIT;
2495
}
2496

    
2497
static ExitStatus op_negf128(DisasContext *s, DisasOps *o)
2498
{
2499
    tcg_gen_xori_i64(o->out, o->in1, 0x8000000000000000ull);
2500
    tcg_gen_mov_i64(o->out2, o->in2);
2501
    return NO_EXIT;
2502
}
2503

    
2504
static ExitStatus op_oc(DisasContext *s, DisasOps *o)
2505
{
2506
    TCGv_i32 l = tcg_const_i32(get_field(s->fields, l1));
2507
    potential_page_fault(s);
2508
    gen_helper_oc(cc_op, cpu_env, l, o->addr1, o->in2);
2509
    tcg_temp_free_i32(l);
2510
    set_cc_static(s);
2511
    return NO_EXIT;
2512
}
2513

    
2514
static ExitStatus op_or(DisasContext *s, DisasOps *o)
2515
{
2516
    tcg_gen_or_i64(o->out, o->in1, o->in2);
2517
    return NO_EXIT;
2518
}
2519

    
2520
static ExitStatus op_ori(DisasContext *s, DisasOps *o)
2521
{
2522
    int shift = s->insn->data & 0xff;
2523
    int size = s->insn->data >> 8;
2524
    uint64_t mask = ((1ull << size) - 1) << shift;
2525

    
2526
    assert(!o->g_in2);
2527
    tcg_gen_shli_i64(o->in2, o->in2, shift);
2528
    tcg_gen_or_i64(o->out, o->in1, o->in2);
2529

    
2530
    /* Produce the CC from only the bits manipulated.  */
2531
    tcg_gen_andi_i64(cc_dst, o->out, mask);
2532
    set_cc_nz_u64(s, cc_dst);
2533
    return NO_EXIT;
2534
}
2535

    
2536
#ifndef CONFIG_USER_ONLY
2537
static ExitStatus op_ptlb(DisasContext *s, DisasOps *o)
2538
{
2539
    check_privileged(s);
2540
    gen_helper_ptlb(cpu_env);
2541
    return NO_EXIT;
2542
}
2543
#endif
2544

    
2545
static ExitStatus op_risbg(DisasContext *s, DisasOps *o)
2546
{
2547
    int i3 = get_field(s->fields, i3);
2548
    int i4 = get_field(s->fields, i4);
2549
    int i5 = get_field(s->fields, i5);
2550
    int do_zero = i4 & 0x80;
2551
    uint64_t mask, imask, pmask;
2552
    int pos, len, rot;
2553

    
2554
    /* Adjust the arguments for the specific insn.  */
2555
    switch (s->fields->op2) {
2556
    case 0x55: /* risbg */
2557
        i3 &= 63;
2558
        i4 &= 63;
2559
        pmask = ~0;
2560
        break;
2561
    case 0x5d: /* risbhg */
2562
        i3 &= 31;
2563
        i4 &= 31;
2564
        pmask = 0xffffffff00000000ull;
2565
        break;
2566
    case 0x51: /* risblg */
2567
        i3 &= 31;
2568
        i4 &= 31;
2569
        pmask = 0x00000000ffffffffull;
2570
        break;
2571
    default:
2572
        abort();
2573
    }
2574

    
2575
    /* MASK is the set of bits to be inserted from R2.
2576
       Take care for I3/I4 wraparound.  */
2577
    mask = pmask >> i3;
2578
    if (i3 <= i4) {
2579
        mask ^= pmask >> i4 >> 1;
2580
    } else {
2581
        mask |= ~(pmask >> i4 >> 1);
2582
    }
2583
    mask &= pmask;
2584

    
2585
    /* IMASK is the set of bits to be kept from R1.  In the case of the high/low
2586
       insns, we need to keep the other half of the register.  */
2587
    imask = ~mask | ~pmask;
2588
    if (do_zero) {
2589
        if (s->fields->op2 == 0x55) {
2590
            imask = 0;
2591
        } else {
2592
            imask = ~pmask;
2593
        }
2594
    }
2595

    
2596
    /* In some cases we can implement this with deposit, which can be more
2597
       efficient on some hosts.  */
2598
    if (~mask == imask && i3 <= i4) {
2599
        if (s->fields->op2 == 0x5d) {
2600
            i3 += 32, i4 += 32;
2601
        }
2602
        /* Note that we rotate the bits to be inserted to the lsb, not to
2603
           the position as described in the PoO.  */
2604
        len = i4 - i3 + 1;
2605
        pos = 63 - i4;
2606
        rot = (i5 - pos) & 63;
2607
    } else {
2608
        pos = len = -1;
2609
        rot = i5 & 63;
2610
    }
2611

    
2612
    /* Rotate the input as necessary.  */
2613
    tcg_gen_rotli_i64(o->in2, o->in2, rot);
2614

    
2615
    /* Insert the selected bits into the output.  */
2616
    if (pos >= 0) {
2617
        tcg_gen_deposit_i64(o->out, o->out, o->in2, pos, len);
2618
    } else if (imask == 0) {
2619
        tcg_gen_andi_i64(o->out, o->in2, mask);
2620
    } else {
2621
        tcg_gen_andi_i64(o->in2, o->in2, mask);
2622
        tcg_gen_andi_i64(o->out, o->out, imask);
2623
        tcg_gen_or_i64(o->out, o->out, o->in2);
2624
    }
2625
    return NO_EXIT;
2626
}
2627

    
2628
static ExitStatus op_rosbg(DisasContext *s, DisasOps *o)
2629
{
2630
    int i3 = get_field(s->fields, i3);
2631
    int i4 = get_field(s->fields, i4);
2632
    int i5 = get_field(s->fields, i5);
2633
    uint64_t mask;
2634

    
2635
    /* If this is a test-only form, arrange to discard the result.  */
2636
    if (i3 & 0x80) {
2637
        o->out = tcg_temp_new_i64();
2638
        o->g_out = false;
2639
    }
2640

    
2641
    i3 &= 63;
2642
    i4 &= 63;
2643
    i5 &= 63;
2644

    
2645
    /* MASK is the set of bits to be operated on from R2.
2646
       Take care for I3/I4 wraparound.  */
2647
    mask = ~0ull >> i3;
2648
    if (i3 <= i4) {
2649
        mask ^= ~0ull >> i4 >> 1;
2650
    } else {
2651
        mask |= ~(~0ull >> i4 >> 1);
2652
    }
2653

    
2654
    /* Rotate the input as necessary.  */
2655
    tcg_gen_rotli_i64(o->in2, o->in2, i5);
2656

    
2657
    /* Operate.  */
2658
    switch (s->fields->op2) {
2659
    case 0x55: /* AND */
2660
        tcg_gen_ori_i64(o->in2, o->in2, ~mask);
2661
        tcg_gen_and_i64(o->out, o->out, o->in2);
2662
        break;
2663
    case 0x56: /* OR */
2664
        tcg_gen_andi_i64(o->in2, o->in2, mask);
2665
        tcg_gen_or_i64(o->out, o->out, o->in2);
2666
        break;
2667
    case 0x57: /* XOR */
2668
        tcg_gen_andi_i64(o->in2, o->in2, mask);
2669
        tcg_gen_xor_i64(o->out, o->out, o->in2);
2670
        break;
2671
    default:
2672
        abort();
2673
    }
2674

    
2675
    /* Set the CC.  */
2676
    tcg_gen_andi_i64(cc_dst, o->out, mask);
2677
    set_cc_nz_u64(s, cc_dst);
2678
    return NO_EXIT;
2679
}
2680

    
2681
static ExitStatus op_rev16(DisasContext *s, DisasOps *o)
2682
{
2683
    tcg_gen_bswap16_i64(o->out, o->in2);
2684
    return NO_EXIT;
2685
}
2686

    
2687
static ExitStatus op_rev32(DisasContext *s, DisasOps *o)
2688
{
2689
    tcg_gen_bswap32_i64(o->out, o->in2);
2690
    return NO_EXIT;
2691
}
2692

    
2693
static ExitStatus op_rev64(DisasContext *s, DisasOps *o)
2694
{
2695
    tcg_gen_bswap64_i64(o->out, o->in2);
2696
    return NO_EXIT;
2697
}
2698

    
2699
static ExitStatus op_rll32(DisasContext *s, DisasOps *o)
2700
{
2701
    TCGv_i32 t1 = tcg_temp_new_i32();
2702
    TCGv_i32 t2 = tcg_temp_new_i32();
2703
    TCGv_i32 to = tcg_temp_new_i32();
2704
    tcg_gen_trunc_i64_i32(t1, o->in1);
2705
    tcg_gen_trunc_i64_i32(t2, o->in2);
2706
    tcg_gen_rotl_i32(to, t1, t2);
2707
    tcg_gen_extu_i32_i64(o->out, to);
2708
    tcg_temp_free_i32(t1);
2709
    tcg_temp_free_i32(t2);
2710
    tcg_temp_free_i32(to);
2711
    return NO_EXIT;
2712
}
2713

    
2714
static ExitStatus op_rll64(DisasContext *s, DisasOps *o)
2715
{
2716
    tcg_gen_rotl_i64(o->out, o->in1, o->in2);
2717
    return NO_EXIT;
2718
}
2719

    
2720
#ifndef CONFIG_USER_ONLY
2721
static ExitStatus op_rrbe(DisasContext *s, DisasOps *o)
2722
{
2723
    check_privileged(s);
2724
    gen_helper_rrbe(cc_op, cpu_env, o->in2);
2725
    set_cc_static(s);
2726
    return NO_EXIT;
2727
}
2728

    
2729
static ExitStatus op_sacf(DisasContext *s, DisasOps *o)
2730
{
2731
    check_privileged(s);
2732
    gen_helper_sacf(cpu_env, o->in2);
2733
    /* Addressing mode has changed, so end the block.  */
2734
    return EXIT_PC_STALE;
2735
}
2736
#endif
2737

    
2738
static ExitStatus op_sar(DisasContext *s, DisasOps *o)
2739
{
2740
    int r1 = get_field(s->fields, r1);
2741
    tcg_gen_st32_i64(o->in2, cpu_env, offsetof(CPUS390XState, aregs[r1]));
2742
    return NO_EXIT;
2743
}
2744

    
2745
static ExitStatus op_seb(DisasContext *s, DisasOps *o)
2746
{
2747
    gen_helper_seb(o->out, cpu_env, o->in1, o->in2);
2748
    return NO_EXIT;
2749
}
2750

    
2751
static ExitStatus op_sdb(DisasContext *s, DisasOps *o)
2752
{
2753
    gen_helper_sdb(o->out, cpu_env, o->in1, o->in2);
2754
    return NO_EXIT;
2755
}
2756

    
2757
static ExitStatus op_sxb(DisasContext *s, DisasOps *o)
2758
{
2759
    gen_helper_sxb(o->out, cpu_env, o->out, o->out2, o->in1, o->in2);
2760
    return_low128(o->out2);
2761
    return NO_EXIT;
2762
}
2763

    
2764
static ExitStatus op_sqeb(DisasContext *s, DisasOps *o)
2765
{
2766
    gen_helper_sqeb(o->out, cpu_env, o->in2);
2767
    return NO_EXIT;
2768
}
2769

    
2770
static ExitStatus op_sqdb(DisasContext *s, DisasOps *o)
2771
{
2772
    gen_helper_sqdb(o->out, cpu_env, o->in2);
2773
    return NO_EXIT;
2774
}
2775

    
2776
static ExitStatus op_sqxb(DisasContext *s, DisasOps *o)
2777
{
2778
    gen_helper_sqxb(o->out, cpu_env, o->in1, o->in2);
2779
    return_low128(o->out2);
2780
    return NO_EXIT;
2781
}
2782

    
2783
#ifndef CONFIG_USER_ONLY
2784
static ExitStatus op_servc(DisasContext *s, DisasOps *o)
2785
{
2786
    check_privileged(s);
2787
    potential_page_fault(s);
2788
    gen_helper_servc(cc_op, cpu_env, o->in2, o->in1);
2789
    set_cc_static(s);
2790
    return NO_EXIT;
2791
}
2792

    
2793
static ExitStatus op_sigp(DisasContext *s, DisasOps *o)
2794
{
2795
    TCGv_i32 r1 = tcg_const_i32(get_field(s->fields, r1));
2796
    check_privileged(s);
2797
    potential_page_fault(s);
2798
    gen_helper_sigp(cc_op, cpu_env, o->in2, r1, o->in1);
2799
    tcg_temp_free_i32(r1);
2800
    return NO_EXIT;
2801
}
2802
#endif
2803

    
2804
static ExitStatus op_soc(DisasContext *s, DisasOps *o)
2805
{
2806
    DisasCompare c;
2807
    TCGv_i64 a;
2808
    int lab, r1;
2809

    
2810
    disas_jcc(s, &c, get_field(s->fields, m3));
2811

    
2812
    lab = gen_new_label();
2813
    if (c.is_64) {
2814
        tcg_gen_brcond_i64(c.cond, c.u.s64.a, c.u.s64.b, lab);
2815
    } else {
2816
        tcg_gen_brcond_i32(c.cond, c.u.s32.a, c.u.s32.b, lab);
2817
    }
2818
    free_compare(&c);
2819

    
2820
    r1 = get_field(s->fields, r1);
2821
    a = get_address(s, 0, get_field(s->fields, b2), get_field(s->fields, d2));
2822
    if (s->insn->data) {
2823
        tcg_gen_qemu_st64(regs[r1], a, get_mem_index(s));
2824
    } else {
2825
        tcg_gen_qemu_st32(regs[r1], a, get_mem_index(s));
2826
    }
2827
    tcg_temp_free_i64(a);
2828

    
2829
    gen_set_label(lab);
2830
    return NO_EXIT;
2831
}
2832

    
2833
static ExitStatus op_sla(DisasContext *s, DisasOps *o)
2834
{
2835
    uint64_t sign = 1ull << s->insn->data;
2836
    enum cc_op cco = s->insn->data == 31 ? CC_OP_SLA_32 : CC_OP_SLA_64;
2837
    gen_op_update2_cc_i64(s, cco, o->in1, o->in2);
2838
    tcg_gen_shl_i64(o->out, o->in1, o->in2);
2839
    /* The arithmetic left shift is curious in that it does not affect
2840
       the sign bit.  Copy that over from the source unchanged.  */
2841
    tcg_gen_andi_i64(o->out, o->out, ~sign);
2842
    tcg_gen_andi_i64(o->in1, o->in1, sign);
2843
    tcg_gen_or_i64(o->out, o->out, o->in1);
2844
    return NO_EXIT;
2845
}
2846

    
2847
static ExitStatus op_sll(DisasContext *s, DisasOps *o)
2848
{
2849
    tcg_gen_shl_i64(o->out, o->in1, o->in2);
2850
    return NO_EXIT;
2851
}
2852

    
2853
static ExitStatus op_sra(DisasContext *s, DisasOps *o)
2854
{
2855
    tcg_gen_sar_i64(o->out, o->in1, o->in2);
2856
    return NO_EXIT;
2857
}
2858

    
2859
static ExitStatus op_srl(DisasContext *s, DisasOps *o)
2860
{
2861
    tcg_gen_shr_i64(o->out, o->in1, o->in2);
2862
    return NO_EXIT;
2863
}
2864

    
2865
static ExitStatus op_sfpc(DisasContext *s, DisasOps *o)
2866
{
2867
    gen_helper_sfpc(cpu_env, o->in2);
2868
    return NO_EXIT;
2869
}
2870

    
2871
#ifndef CONFIG_USER_ONLY
2872
static ExitStatus op_spka(DisasContext *s, DisasOps *o)
2873
{
2874
    check_privileged(s);
2875
    tcg_gen_shri_i64(o->in2, o->in2, 4);
2876
    tcg_gen_deposit_i64(psw_mask, psw_mask, o->in2, PSW_SHIFT_KEY - 4, 4);
2877
    return NO_EXIT;
2878
}
2879

    
2880
static ExitStatus op_sske(DisasContext *s, DisasOps *o)
2881
{
2882
    check_privileged(s);
2883
    gen_helper_sske(cpu_env, o->in1, o->in2);
2884
    return NO_EXIT;
2885
}
2886

    
2887
static ExitStatus op_ssm(DisasContext *s, DisasOps *o)
2888
{
2889
    check_privileged(s);
2890
    tcg_gen_deposit_i64(psw_mask, psw_mask, o->in2, 56, 8);
2891
    return NO_EXIT;
2892
}
2893

    
2894
static ExitStatus op_stap(DisasContext *s, DisasOps *o)
2895
{
2896
    check_privileged(s);
2897
    /* ??? Surely cpu address != cpu number.  In any case the previous
2898
       version of this stored more than the required half-word, so it
2899
       is unlikely this has ever been tested.  */
2900
    tcg_gen_ld32u_i64(o->out, cpu_env, offsetof(CPUS390XState, cpu_num));
2901
    return NO_EXIT;
2902
}
2903

    
2904
static ExitStatus op_stck(DisasContext *s, DisasOps *o)
2905
{
2906
    gen_helper_stck(o->out, cpu_env);
2907
    /* ??? We don't implement clock states.  */
2908
    gen_op_movi_cc(s, 0);
2909
    return NO_EXIT;
2910
}
2911

    
2912
static ExitStatus op_stcke(DisasContext *s, DisasOps *o)
2913
{
2914
    TCGv_i64 c1 = tcg_temp_new_i64();
2915
    TCGv_i64 c2 = tcg_temp_new_i64();
2916
    gen_helper_stck(c1, cpu_env);
2917
    /* Shift the 64-bit value into its place as a zero-extended
2918
       104-bit value.  Note that "bit positions 64-103 are always
2919
       non-zero so that they compare differently to STCK"; we set
2920
       the least significant bit to 1.  */
2921
    tcg_gen_shli_i64(c2, c1, 56);
2922
    tcg_gen_shri_i64(c1, c1, 8);
2923
    tcg_gen_ori_i64(c2, c2, 0x10000);
2924
    tcg_gen_qemu_st64(c1, o->in2, get_mem_index(s));
2925
    tcg_gen_addi_i64(o->in2, o->in2, 8);
2926
    tcg_gen_qemu_st64(c2, o->in2, get_mem_index(s));
2927
    tcg_temp_free_i64(c1);
2928
    tcg_temp_free_i64(c2);
2929
    /* ??? We don't implement clock states.  */
2930
    gen_op_movi_cc(s, 0);
2931
    return NO_EXIT;
2932
}
2933

    
2934
static ExitStatus op_sckc(DisasContext *s, DisasOps *o)
2935
{
2936
    check_privileged(s);
2937
    gen_helper_sckc(cpu_env, o->in2);
2938
    return NO_EXIT;
2939
}
2940

    
2941
static ExitStatus op_stckc(DisasContext *s, DisasOps *o)
2942
{
2943
    check_privileged(s);
2944
    gen_helper_stckc(o->out, cpu_env);
2945
    return NO_EXIT;
2946
}
2947

    
2948
static ExitStatus op_stctg(DisasContext *s, DisasOps *o)
2949
{
2950
    TCGv_i32 r1 = tcg_const_i32(get_field(s->fields, r1));
2951
    TCGv_i32 r3 = tcg_const_i32(get_field(s->fields, r3));
2952
    check_privileged(s);
2953
    potential_page_fault(s);
2954
    gen_helper_stctg(cpu_env, r1, o->in2, r3);
2955
    tcg_temp_free_i32(r1);
2956
    tcg_temp_free_i32(r3);
2957
    return NO_EXIT;
2958
}
2959

    
2960
static ExitStatus op_stctl(DisasContext *s, DisasOps *o)
2961
{
2962
    TCGv_i32 r1 = tcg_const_i32(get_field(s->fields, r1));
2963
    TCGv_i32 r3 = tcg_const_i32(get_field(s->fields, r3));
2964
    check_privileged(s);
2965
    potential_page_fault(s);
2966
    gen_helper_stctl(cpu_env, r1, o->in2, r3);
2967
    tcg_temp_free_i32(r1);
2968
    tcg_temp_free_i32(r3);
2969
    return NO_EXIT;
2970
}
2971

    
2972
static ExitStatus op_stidp(DisasContext *s, DisasOps *o)
2973
{
2974
    check_privileged(s);
2975
    tcg_gen_ld32u_i64(o->out, cpu_env, offsetof(CPUS390XState, cpu_num));
2976
    return NO_EXIT;
2977
}
2978

    
2979
static ExitStatus op_spt(DisasContext *s, DisasOps *o)
2980
{
2981
    check_privileged(s);
2982
    gen_helper_spt(cpu_env, o->in2);
2983
    return NO_EXIT;
2984
}
2985

    
2986
static ExitStatus op_stfl(DisasContext *s, DisasOps *o)
2987
{
2988
    TCGv_i64 f, a;
2989
    /* We really ought to have more complete indication of facilities
2990
       that we implement.  Address this when STFLE is implemented.  */
2991
    check_privileged(s);
2992
    f = tcg_const_i64(0xc0000000);
2993
    a = tcg_const_i64(200);
2994
    tcg_gen_qemu_st32(f, a, get_mem_index(s));
2995
    tcg_temp_free_i64(f);
2996
    tcg_temp_free_i64(a);
2997
    return NO_EXIT;
2998
}
2999

    
3000
static ExitStatus op_stpt(DisasContext *s, DisasOps *o)
3001
{
3002
    check_privileged(s);
3003
    gen_helper_stpt(o->out, cpu_env);
3004
    return NO_EXIT;
3005
}
3006

    
3007
static ExitStatus op_stsi(DisasContext *s, DisasOps *o)
3008
{
3009
    check_privileged(s);
3010
    potential_page_fault(s);
3011
    gen_helper_stsi(cc_op, cpu_env, o->in2, regs[0], regs[1]);
3012
    set_cc_static(s);
3013
    return NO_EXIT;
3014
}
3015

    
3016
static ExitStatus op_spx(DisasContext *s, DisasOps *o)
3017
{
3018
    check_privileged(s);
3019
    gen_helper_spx(cpu_env, o->in2);
3020
    return NO_EXIT;
3021
}
3022

    
3023
static ExitStatus op_subchannel(DisasContext *s, DisasOps *o)
3024
{
3025
    check_privileged(s);
3026
    /* Not operational.  */
3027
    gen_op_movi_cc(s, 3);
3028
    return NO_EXIT;
3029
}
3030

    
3031
static ExitStatus op_stpx(DisasContext *s, DisasOps *o)
3032
{
3033
    check_privileged(s);
3034
    tcg_gen_ld_i64(o->out, cpu_env, offsetof(CPUS390XState, psa));
3035
    tcg_gen_andi_i64(o->out, o->out, 0x7fffe000);
3036
    return NO_EXIT;
3037
}
3038

    
3039
static ExitStatus op_stnosm(DisasContext *s, DisasOps *o)
3040
{
3041
    uint64_t i2 = get_field(s->fields, i2);
3042
    TCGv_i64 t;
3043

    
3044
    check_privileged(s);
3045

    
3046
    /* It is important to do what the instruction name says: STORE THEN.
3047
       If we let the output hook perform the store then if we fault and
3048
       restart, we'll have the wrong SYSTEM MASK in place.  */
3049
    t = tcg_temp_new_i64();
3050
    tcg_gen_shri_i64(t, psw_mask, 56);
3051
    tcg_gen_qemu_st8(t, o->addr1, get_mem_index(s));
3052
    tcg_temp_free_i64(t);
3053

    
3054
    if (s->fields->op == 0xac) {
3055
        tcg_gen_andi_i64(psw_mask, psw_mask,
3056
                         (i2 << 56) | 0x00ffffffffffffffull);
3057
    } else {
3058
        tcg_gen_ori_i64(psw_mask, psw_mask, i2 << 56);
3059
    }
3060
    return NO_EXIT;
3061
}
3062

    
3063
static ExitStatus op_stura(DisasContext *s, DisasOps *o)
3064
{
3065
    check_privileged(s);
3066
    potential_page_fault(s);
3067
    gen_helper_stura(cpu_env, o->in2, o->in1);
3068
    return NO_EXIT;
3069
}
3070
#endif
3071

    
3072
static ExitStatus op_st8(DisasContext *s, DisasOps *o)
3073
{
3074
    tcg_gen_qemu_st8(o->in1, o->in2, get_mem_index(s));
3075
    return NO_EXIT;
3076
}
3077

    
3078
static ExitStatus op_st16(DisasContext *s, DisasOps *o)
3079
{
3080
    tcg_gen_qemu_st16(o->in1, o->in2, get_mem_index(s));
3081
    return NO_EXIT;
3082
}
3083

    
3084
static ExitStatus op_st32(DisasContext *s, DisasOps *o)
3085
{
3086
    tcg_gen_qemu_st32(o->in1, o->in2, get_mem_index(s));
3087
    return NO_EXIT;
3088
}
3089

    
3090
static ExitStatus op_st64(DisasContext *s, DisasOps *o)
3091
{
3092
    tcg_gen_qemu_st64(o->in1, o->in2, get_mem_index(s));
3093
    return NO_EXIT;
3094
}
3095

    
3096
static ExitStatus op_stam(DisasContext *s, DisasOps *o)
3097
{
3098
    TCGv_i32 r1 = tcg_const_i32(get_field(s->fields, r1));
3099
    TCGv_i32 r3 = tcg_const_i32(get_field(s->fields, r3));
3100
    potential_page_fault(s);
3101
    gen_helper_stam(cpu_env, r1, o->in2, r3);
3102
    tcg_temp_free_i32(r1);
3103
    tcg_temp_free_i32(r3);
3104
    return NO_EXIT;
3105
}
3106

    
3107
static ExitStatus op_stcm(DisasContext *s, DisasOps *o)
3108
{
3109
    int m3 = get_field(s->fields, m3);
3110
    int pos, base = s->insn->data;
3111
    TCGv_i64 tmp = tcg_temp_new_i64();
3112

    
3113
    pos = base + ctz32(m3) * 8;
3114
    switch (m3) {
3115
    case 0xf:
3116
        /* Effectively a 32-bit store.  */
3117
        tcg_gen_shri_i64(tmp, o->in1, pos);
3118
        tcg_gen_qemu_st32(tmp, o->in2, get_mem_index(s));
3119
        break;
3120

    
3121
    case 0xc:
3122
    case 0x6:
3123
    case 0x3:
3124
        /* Effectively a 16-bit store.  */
3125
        tcg_gen_shri_i64(tmp, o->in1, pos);
3126
        tcg_gen_qemu_st16(tmp, o->in2, get_mem_index(s));
3127
        break;
3128

    
3129
    case 0x8:
3130
    case 0x4:
3131
    case 0x2:
3132
    case 0x1:
3133
        /* Effectively an 8-bit store.  */
3134
        tcg_gen_shri_i64(tmp, o->in1, pos);
3135
        tcg_gen_qemu_st8(tmp, o->in2, get_mem_index(s));
3136
        break;
3137

    
3138
    default:
3139
        /* This is going to be a sequence of shifts and stores.  */
3140
        pos = base + 32 - 8;
3141
        while (m3) {
3142
            if (m3 & 0x8) {
3143
                tcg_gen_shri_i64(tmp, o->in1, pos);
3144
                tcg_gen_qemu_st8(tmp, o->in2, get_mem_index(s));
3145
                tcg_gen_addi_i64(o->in2, o->in2, 1);
3146
            }
3147
            m3 = (m3 << 1) & 0xf;
3148
            pos -= 8;
3149
        }
3150
        break;
3151
    }
3152
    tcg_temp_free_i64(tmp);
3153
    return NO_EXIT;
3154
}
3155

    
3156
static ExitStatus op_stm(DisasContext *s, DisasOps *o)
3157
{
3158
    int r1 = get_field(s->fields, r1);
3159
    int r3 = get_field(s->fields, r3);
3160
    int size = s->insn->data;
3161
    TCGv_i64 tsize = tcg_const_i64(size);
3162

    
3163
    while (1) {
3164
        if (size == 8) {
3165
            tcg_gen_qemu_st64(regs[r1], o->in2, get_mem_index(s));
3166
        } else {
3167
            tcg_gen_qemu_st32(regs[r1], o->in2, get_mem_index(s));
3168
        }
3169
        if (r1 == r3) {
3170
            break;
3171
        }
3172
        tcg_gen_add_i64(o->in2, o->in2, tsize);
3173
        r1 = (r1 + 1) & 15;
3174
    }
3175

    
3176
    tcg_temp_free_i64(tsize);
3177
    return NO_EXIT;
3178
}
3179

    
3180
static ExitStatus op_stmh(DisasContext *s, DisasOps *o)
3181
{
3182
    int r1 = get_field(s->fields, r1);
3183
    int r3 = get_field(s->fields, r3);
3184
    TCGv_i64 t = tcg_temp_new_i64();
3185
    TCGv_i64 t4 = tcg_const_i64(4);
3186
    TCGv_i64 t32 = tcg_const_i64(32);
3187

    
3188
    while (1) {
3189
        tcg_gen_shl_i64(t, regs[r1], t32);
3190
        tcg_gen_qemu_st32(t, o->in2, get_mem_index(s));
3191
        if (r1 == r3) {
3192
            break;
3193
        }
3194
        tcg_gen_add_i64(o->in2, o->in2, t4);
3195
        r1 = (r1 + 1) & 15;
3196
    }
3197

    
3198
    tcg_temp_free_i64(t);
3199
    tcg_temp_free_i64(t4);
3200
    tcg_temp_free_i64(t32);
3201
    return NO_EXIT;
3202
}
3203

    
3204
static ExitStatus op_srst(DisasContext *s, DisasOps *o)
3205
{
3206
    potential_page_fault(s);
3207
    gen_helper_srst(o->in1, cpu_env, regs[0], o->in1, o->in2);
3208
    set_cc_static(s);
3209
    return_low128(o->in2);
3210
    return NO_EXIT;
3211
}
3212

    
3213
static ExitStatus op_sub(DisasContext *s, DisasOps *o)
3214
{
3215
    tcg_gen_sub_i64(o->out, o->in1, o->in2);
3216
    return NO_EXIT;
3217
}
3218

    
3219
static ExitStatus op_subb(DisasContext *s, DisasOps *o)
3220
{
3221
    TCGv_i64 cc;
3222

    
3223
    assert(!o->g_in2);
3224
    tcg_gen_not_i64(o->in2, o->in2);
3225
    tcg_gen_add_i64(o->out, o->in1, o->in2);
3226

    
3227
    /* XXX possible optimization point */
3228
    gen_op_calc_cc(s);
3229
    cc = tcg_temp_new_i64();
3230
    tcg_gen_extu_i32_i64(cc, cc_op);
3231
    tcg_gen_shri_i64(cc, cc, 1);
3232
    tcg_gen_add_i64(o->out, o->out, cc);
3233
    tcg_temp_free_i64(cc);
3234
    return NO_EXIT;
3235
}
3236

    
3237
static ExitStatus op_svc(DisasContext *s, DisasOps *o)
3238
{
3239
    TCGv_i32 t;
3240

    
3241
    update_psw_addr(s);
3242
    update_cc_op(s);
3243

    
3244
    t = tcg_const_i32(get_field(s->fields, i1) & 0xff);
3245
    tcg_gen_st_i32(t, cpu_env, offsetof(CPUS390XState, int_svc_code));
3246
    tcg_temp_free_i32(t);
3247

    
3248
    t = tcg_const_i32(s->next_pc - s->pc);
3249
    tcg_gen_st_i32(t, cpu_env, offsetof(CPUS390XState, int_svc_ilen));
3250
    tcg_temp_free_i32(t);
3251

    
3252
    gen_exception(EXCP_SVC);
3253
    return EXIT_NORETURN;
3254
}
3255

    
3256
static ExitStatus op_tceb(DisasContext *s, DisasOps *o)
3257
{
3258
    gen_helper_tceb(cc_op, o->in1, o->in2);
3259
    set_cc_static(s);
3260
    return NO_EXIT;
3261
}
3262

    
3263
static ExitStatus op_tcdb(DisasContext *s, DisasOps *o)
3264
{
3265
    gen_helper_tcdb(cc_op, o->in1, o->in2);
3266
    set_cc_static(s);
3267
    return NO_EXIT;
3268
}
3269

    
3270
static ExitStatus op_tcxb(DisasContext *s, DisasOps *o)
3271
{
3272
    gen_helper_tcxb(cc_op, o->out, o->out2, o->in2);
3273
    set_cc_static(s);
3274
    return NO_EXIT;
3275
}
3276

    
3277
#ifndef CONFIG_USER_ONLY
3278
static ExitStatus op_tprot(DisasContext *s, DisasOps *o)
3279
{
3280
    potential_page_fault(s);
3281
    gen_helper_tprot(cc_op, o->addr1, o->in2);
3282
    set_cc_static(s);
3283
    return NO_EXIT;
3284
}
3285
#endif
3286

    
3287
static ExitStatus op_tr(DisasContext *s, DisasOps *o)
3288
{
3289
    TCGv_i32 l = tcg_const_i32(get_field(s->fields, l1));
3290
    potential_page_fault(s);
3291
    gen_helper_tr(cpu_env, l, o->addr1, o->in2);
3292
    tcg_temp_free_i32(l);
3293
    set_cc_static(s);
3294
    return NO_EXIT;
3295
}
3296

    
3297
static ExitStatus op_unpk(DisasContext *s, DisasOps *o)
3298
{
3299
    TCGv_i32 l = tcg_const_i32(get_field(s->fields, l1));
3300
    potential_page_fault(s);
3301
    gen_helper_unpk(cpu_env, l, o->addr1, o->in2);
3302
    tcg_temp_free_i32(l);
3303
    return NO_EXIT;
3304
}
3305

    
3306
static ExitStatus op_xc(DisasContext *s, DisasOps *o)
3307
{
3308
    TCGv_i32 l = tcg_const_i32(get_field(s->fields, l1));
3309
    potential_page_fault(s);
3310
    gen_helper_xc(cc_op, cpu_env, l, o->addr1, o->in2);
3311
    tcg_temp_free_i32(l);
3312
    set_cc_static(s);
3313
    return NO_EXIT;
3314
}
3315

    
3316
static ExitStatus op_xor(DisasContext *s, DisasOps *o)
3317
{
3318
    tcg_gen_xor_i64(o->out, o->in1, o->in2);
3319
    return NO_EXIT;
3320
}
3321

    
3322
static ExitStatus op_xori(DisasContext *s, DisasOps *o)
3323
{
3324
    int shift = s->insn->data & 0xff;
3325
    int size = s->insn->data >> 8;
3326
    uint64_t mask = ((1ull << size) - 1) << shift;
3327

    
3328
    assert(!o->g_in2);
3329
    tcg_gen_shli_i64(o->in2, o->in2, shift);
3330
    tcg_gen_xor_i64(o->out, o->in1, o->in2);
3331

    
3332
    /* Produce the CC from only the bits manipulated.  */
3333
    tcg_gen_andi_i64(cc_dst, o->out, mask);
3334
    set_cc_nz_u64(s, cc_dst);
3335
    return NO_EXIT;
3336
}
3337

    
3338
static ExitStatus op_zero(DisasContext *s, DisasOps *o)
3339
{
3340
    o->out = tcg_const_i64(0);
3341
    return NO_EXIT;
3342
}
3343

    
3344
static ExitStatus op_zero2(DisasContext *s, DisasOps *o)
3345
{
3346
    o->out = tcg_const_i64(0);
3347
    o->out2 = o->out;
3348
    o->g_out2 = true;
3349
    return NO_EXIT;
3350
}
3351

    
3352
/* ====================================================================== */
3353
/* The "Cc OUTput" generators.  Given the generated output (and in some cases
3354
   the original inputs), update the various cc data structures in order to
3355
   be able to compute the new condition code.  */
3356

    
3357
static void cout_abs32(DisasContext *s, DisasOps *o)
3358
{
3359
    gen_op_update1_cc_i64(s, CC_OP_ABS_32, o->out);
3360
}
3361

    
3362
static void cout_abs64(DisasContext *s, DisasOps *o)
3363
{
3364
    gen_op_update1_cc_i64(s, CC_OP_ABS_64, o->out);
3365
}
3366

    
3367
static void cout_adds32(DisasContext *s, DisasOps *o)
3368
{
3369
    gen_op_update3_cc_i64(s, CC_OP_ADD_32, o->in1, o->in2, o->out);
3370
}
3371

    
3372
static void cout_adds64(DisasContext *s, DisasOps *o)
3373
{
3374
    gen_op_update3_cc_i64(s, CC_OP_ADD_64, o->in1, o->in2, o->out);
3375
}
3376

    
3377
static void cout_addu32(DisasContext *s, DisasOps *o)
3378
{
3379
    gen_op_update3_cc_i64(s, CC_OP_ADDU_32, o->in1, o->in2, o->out);
3380
}
3381

    
3382
static void cout_addu64(DisasContext *s, DisasOps *o)
3383
{
3384
    gen_op_update3_cc_i64(s, CC_OP_ADDU_64, o->in1, o->in2, o->out);
3385
}
3386

    
3387
static void cout_addc32(DisasContext *s, DisasOps *o)
3388
{
3389
    gen_op_update3_cc_i64(s, CC_OP_ADDC_32, o->in1, o->in2, o->out);
3390
}
3391

    
3392
static void cout_addc64(DisasContext *s, DisasOps *o)
3393
{
3394
    gen_op_update3_cc_i64(s, CC_OP_ADDC_64, o->in1, o->in2, o->out);
3395
}
3396

    
3397
static void cout_cmps32(DisasContext *s, DisasOps *o)
3398
{
3399
    gen_op_update2_cc_i64(s, CC_OP_LTGT_32, o->in1, o->in2);
3400
}
3401

    
3402
static void cout_cmps64(DisasContext *s, DisasOps *o)
3403
{
3404
    gen_op_update2_cc_i64(s, CC_OP_LTGT_64, o->in1, o->in2);
3405
}
3406

    
3407
static void cout_cmpu32(DisasContext *s, DisasOps *o)
3408
{
3409
    gen_op_update2_cc_i64(s, CC_OP_LTUGTU_32, o->in1, o->in2);
3410
}
3411

    
3412
static void cout_cmpu64(DisasContext *s, DisasOps *o)
3413
{
3414
    gen_op_update2_cc_i64(s, CC_OP_LTUGTU_64, o->in1, o->in2);
3415
}
3416

    
3417
static void cout_f32(DisasContext *s, DisasOps *o)
3418
{
3419
    gen_op_update1_cc_i64(s, CC_OP_NZ_F32, o->out);
3420
}
3421

    
3422
static void cout_f64(DisasContext *s, DisasOps *o)
3423
{
3424
    gen_op_update1_cc_i64(s, CC_OP_NZ_F64, o->out);
3425
}
3426

    
3427
static void cout_f128(DisasContext *s, DisasOps *o)
3428
{
3429
    gen_op_update2_cc_i64(s, CC_OP_NZ_F128, o->out, o->out2);
3430
}
3431

    
3432
static void cout_nabs32(DisasContext *s, DisasOps *o)
3433
{
3434
    gen_op_update1_cc_i64(s, CC_OP_NABS_32, o->out);
3435
}
3436

    
3437
static void cout_nabs64(DisasContext *s, DisasOps *o)
3438
{
3439
    gen_op_update1_cc_i64(s, CC_OP_NABS_64, o->out);
3440
}
3441

    
3442
static void cout_neg32(DisasContext *s, DisasOps *o)
3443
{
3444
    gen_op_update1_cc_i64(s, CC_OP_COMP_32, o->out);
3445
}
3446

    
3447
static void cout_neg64(DisasContext *s, DisasOps *o)
3448
{
3449
    gen_op_update1_cc_i64(s, CC_OP_COMP_64, o->out);
3450
}
3451

    
3452
static void cout_nz32(DisasContext *s, DisasOps *o)
3453
{
3454
    tcg_gen_ext32u_i64(cc_dst, o->out);
3455
    gen_op_update1_cc_i64(s, CC_OP_NZ, cc_dst);
3456
}
3457

    
3458
static void cout_nz64(DisasContext *s, DisasOps *o)
3459
{
3460
    gen_op_update1_cc_i64(s, CC_OP_NZ, o->out);
3461
}
3462

    
3463
static void cout_s32(DisasContext *s, DisasOps *o)
3464
{
3465
    gen_op_update1_cc_i64(s, CC_OP_LTGT0_32, o->out);
3466
}
3467

    
3468
static void cout_s64(DisasContext *s, DisasOps *o)
3469
{
3470
    gen_op_update1_cc_i64(s, CC_OP_LTGT0_64, o->out);
3471
}
3472

    
3473
static void cout_subs32(DisasContext *s, DisasOps *o)
3474
{
3475
    gen_op_update3_cc_i64(s, CC_OP_SUB_32, o->in1, o->in2, o->out);
3476
}
3477

    
3478
static void cout_subs64(DisasContext *s, DisasOps *o)
3479
{
3480
    gen_op_update3_cc_i64(s, CC_OP_SUB_64, o->in1, o->in2, o->out);
3481
}
3482

    
3483
static void cout_subu32(DisasContext *s, DisasOps *o)
3484
{
3485
    gen_op_update3_cc_i64(s, CC_OP_SUBU_32, o->in1, o->in2, o->out);
3486
}
3487

    
3488
static void cout_subu64(DisasContext *s, DisasOps *o)
3489
{
3490
    gen_op_update3_cc_i64(s, CC_OP_SUBU_64, o->in1, o->in2, o->out);
3491
}
3492

    
3493
static void cout_subb32(DisasContext *s, DisasOps *o)
3494
{
3495
    gen_op_update3_cc_i64(s, CC_OP_SUBB_32, o->in1, o->in2, o->out);
3496
}
3497

    
3498
static void cout_subb64(DisasContext *s, DisasOps *o)
3499
{
3500
    gen_op_update3_cc_i64(s, CC_OP_SUBB_64, o->in1, o->in2, o->out);
3501
}
3502

    
3503
static void cout_tm32(DisasContext *s, DisasOps *o)
3504
{
3505
    gen_op_update2_cc_i64(s, CC_OP_TM_32, o->in1, o->in2);
3506
}
3507

    
3508
static void cout_tm64(DisasContext *s, DisasOps *o)
3509
{
3510
    gen_op_update2_cc_i64(s, CC_OP_TM_64, o->in1, o->in2);
3511
}
3512

    
3513
/* ====================================================================== */
3514
/* The "PREPeration" generators.  These initialize the DisasOps.OUT fields
3515
   with the TCG register to which we will write.  Used in combination with
3516
   the "wout" generators, in some cases we need a new temporary, and in
3517
   some cases we can write to a TCG global.  */
3518

    
3519
static void prep_new(DisasContext *s, DisasFields *f, DisasOps *o)
3520
{
3521
    o->out = tcg_temp_new_i64();
3522
}
3523

    
3524
static void prep_new_P(DisasContext *s, DisasFields *f, DisasOps *o)
3525
{
3526
    o->out = tcg_temp_new_i64();
3527
    o->out2 = tcg_temp_new_i64();
3528
}
3529

    
3530
static void prep_r1(DisasContext *s, DisasFields *f, DisasOps *o)
3531
{
3532
    o->out = regs[get_field(f, r1)];
3533
    o->g_out = true;
3534
}
3535

    
3536
static void prep_r1_P(DisasContext *s, DisasFields *f, DisasOps *o)
3537
{
3538
    /* ??? Specification exception: r1 must be even.  */
3539
    int r1 = get_field(f, r1);
3540
    o->out = regs[r1];
3541
    o->out2 = regs[(r1 + 1) & 15];
3542
    o->g_out = o->g_out2 = true;
3543
}
3544

    
3545
static void prep_f1(DisasContext *s, DisasFields *f, DisasOps *o)
3546
{
3547
    o->out = fregs[get_field(f, r1)];
3548
    o->g_out = true;
3549
}
3550

    
3551
static void prep_x1(DisasContext *s, DisasFields *f, DisasOps *o)
3552
{
3553
    /* ??? Specification exception: r1 must be < 14.  */
3554
    int r1 = get_field(f, r1);
3555
    o->out = fregs[r1];
3556
    o->out2 = fregs[(r1 + 2) & 15];
3557
    o->g_out = o->g_out2 = true;
3558
}
3559

    
3560
/* ====================================================================== */
3561
/* The "Write OUTput" generators.  These generally perform some non-trivial
3562
   copy of data to TCG globals, or to main memory.  The trivial cases are
3563
   generally handled by having a "prep" generator install the TCG global
3564
   as the destination of the operation.  */
3565

    
3566
static void wout_r1(DisasContext *s, DisasFields *f, DisasOps *o)
3567
{
3568
    store_reg(get_field(f, r1), o->out);
3569
}
3570

    
3571
static void wout_r1_8(DisasContext *s, DisasFields *f, DisasOps *o)
3572
{
3573
    int r1 = get_field(f, r1);
3574
    tcg_gen_deposit_i64(regs[r1], regs[r1], o->out, 0, 8);
3575
}
3576

    
3577
static void wout_r1_16(DisasContext *s, DisasFields *f, DisasOps *o)
3578
{
3579
    int r1 = get_field(f, r1);
3580
    tcg_gen_deposit_i64(regs[r1], regs[r1], o->out, 0, 16);
3581
}
3582

    
3583
static void wout_r1_32(DisasContext *s, DisasFields *f, DisasOps *o)
3584
{
3585
    store_reg32_i64(get_field(f, r1), o->out);
3586
}
3587

    
3588
static void wout_r1_P32(DisasContext *s, DisasFields *f, DisasOps *o)
3589
{
3590
    /* ??? Specification exception: r1 must be even.  */
3591
    int r1 = get_field(f, r1);
3592
    store_reg32_i64(r1, o->out);
3593
    store_reg32_i64((r1 + 1) & 15, o->out2);
3594
}
3595

    
3596
static void wout_r1_D32(DisasContext *s, DisasFields *f, DisasOps *o)
3597
{
3598
    /* ??? Specification exception: r1 must be even.  */
3599
    int r1 = get_field(f, r1);
3600
    store_reg32_i64((r1 + 1) & 15, o->out);
3601
    tcg_gen_shri_i64(o->out, o->out, 32);
3602
    store_reg32_i64(r1, o->out);
3603
}
3604

    
3605
static void wout_e1(DisasContext *s, DisasFields *f, DisasOps *o)
3606
{
3607
    store_freg32_i64(get_field(f, r1), o->out);
3608
}
3609

    
3610
static void wout_f1(DisasContext *s, DisasFields *f, DisasOps *o)
3611
{
3612
    store_freg(get_field(f, r1), o->out);
3613
}
3614

    
3615
static void wout_x1(DisasContext *s, DisasFields *f, DisasOps *o)
3616
{
3617
    /* ??? Specification exception: r1 must be < 14.  */
3618
    int f1 = get_field(s->fields, r1);
3619
    store_freg(f1, o->out);
3620
    store_freg((f1 + 2) & 15, o->out2);
3621
}
3622

    
3623
static void wout_cond_r1r2_32(DisasContext *s, DisasFields *f, DisasOps *o)
3624
{
3625
    if (get_field(f, r1) != get_field(f, r2)) {
3626
        store_reg32_i64(get_field(f, r1), o->out);
3627
    }
3628
}
3629

    
3630
static void wout_cond_e1e2(DisasContext *s, DisasFields *f, DisasOps *o)
3631
{
3632
    if (get_field(f, r1) != get_field(f, r2)) {
3633
        store_freg32_i64(get_field(f, r1), o->out);
3634
    }
3635
}
3636

    
3637
static void wout_m1_8(DisasContext *s, DisasFields *f, DisasOps *o)
3638
{
3639
    tcg_gen_qemu_st8(o->out, o->addr1, get_mem_index(s));
3640
}
3641

    
3642
static void wout_m1_16(DisasContext *s, DisasFields *f, DisasOps *o)
3643
{
3644
    tcg_gen_qemu_st16(o->out, o->addr1, get_mem_index(s));
3645
}
3646

    
3647
static void wout_m1_32(DisasContext *s, DisasFields *f, DisasOps *o)
3648
{
3649
    tcg_gen_qemu_st32(o->out, o->addr1, get_mem_index(s));
3650
}
3651

    
3652
static void wout_m1_64(DisasContext *s, DisasFields *f, DisasOps *o)
3653
{
3654
    tcg_gen_qemu_st64(o->out, o->addr1, get_mem_index(s));
3655
}
3656

    
3657
static void wout_m2_32(DisasContext *s, DisasFields *f, DisasOps *o)
3658
{
3659
    tcg_gen_qemu_st32(o->out, o->in2, get_mem_index(s));
3660
}
3661

    
3662
/* ====================================================================== */
3663
/* The "INput 1" generators.  These load the first operand to an insn.  */
3664

    
3665
static void in1_r1(DisasContext *s, DisasFields *f, DisasOps *o)
3666
{
3667
    o->in1 = load_reg(get_field(f, r1));
3668
}
3669

    
3670
static void in1_r1_o(DisasContext *s, DisasFields *f, DisasOps *o)
3671
{
3672
    o->in1 = regs[get_field(f, r1)];
3673
    o->g_in1 = true;
3674
}
3675

    
3676
static void in1_r1_32s(DisasContext *s, DisasFields *f, DisasOps *o)
3677
{
3678
    o->in1 = tcg_temp_new_i64();
3679
    tcg_gen_ext32s_i64(o->in1, regs[get_field(f, r1)]);
3680
}
3681

    
3682
static void in1_r1_32u(DisasContext *s, DisasFields *f, DisasOps *o)
3683
{
3684
    o->in1 = tcg_temp_new_i64();
3685
    tcg_gen_ext32u_i64(o->in1, regs[get_field(f, r1)]);
3686
}
3687

    
3688
static void in1_r1_sr32(DisasContext *s, DisasFields *f, DisasOps *o)
3689
{
3690
    o->in1 = tcg_temp_new_i64();
3691
    tcg_gen_shri_i64(o->in1, regs[get_field(f, r1)], 32);
3692
}
3693

    
3694
static void in1_r1p1(DisasContext *s, DisasFields *f, DisasOps *o)
3695
{
3696
    /* ??? Specification exception: r1 must be even.  */
3697
    int r1 = get_field(f, r1);
3698
    o->in1 = load_reg((r1 + 1) & 15);
3699
}
3700

    
3701
static void in1_r1p1_32s(DisasContext *s, DisasFields *f, DisasOps *o)
3702
{
3703
    /* ??? Specification exception: r1 must be even.  */
3704
    int r1 = get_field(f, r1);
3705
    o->in1 = tcg_temp_new_i64();
3706
    tcg_gen_ext32s_i64(o->in1, regs[(r1 + 1) & 15]);
3707
}
3708

    
3709
static void in1_r1p1_32u(DisasContext *s, DisasFields *f, DisasOps *o)
3710
{
3711
    /* ??? Specification exception: r1 must be even.  */
3712
    int r1 = get_field(f, r1);
3713
    o->in1 = tcg_temp_new_i64();
3714
    tcg_gen_ext32u_i64(o->in1, regs[(r1 + 1) & 15]);
3715
}
3716

    
3717
static void in1_r1_D32(DisasContext *s, DisasFields *f, DisasOps *o)
3718
{
3719
    /* ??? Specification exception: r1 must be even.  */
3720
    int r1 = get_field(f, r1);
3721
    o->in1 = tcg_temp_new_i64();
3722
    tcg_gen_concat32_i64(o->in1, regs[r1 + 1], regs[r1]);
3723
}
3724

    
3725
static void in1_r2(DisasContext *s, DisasFields *f, DisasOps *o)
3726
{
3727
    o->in1 = load_reg(get_field(f, r2));
3728
}
3729

    
3730
static void in1_r3(DisasContext *s, DisasFields *f, DisasOps *o)
3731
{
3732
    o->in1 = load_reg(get_field(f, r3));
3733
}
3734

    
3735
static void in1_r3_o(DisasContext *s, DisasFields *f, DisasOps *o)
3736
{
3737
    o->in1 = regs[get_field(f, r3)];
3738
    o->g_in1 = true;
3739
}
3740

    
3741
static void in1_r3_32s(DisasContext *s, DisasFields *f, DisasOps *o)
3742
{
3743
    o->in1 = tcg_temp_new_i64();
3744
    tcg_gen_ext32s_i64(o->in1, regs[get_field(f, r3)]);
3745
}
3746

    
3747
static void in1_r3_32u(DisasContext *s, DisasFields *f, DisasOps *o)
3748
{
3749
    o->in1 = tcg_temp_new_i64();
3750
    tcg_gen_ext32u_i64(o->in1, regs[get_field(f, r3)]);
3751
}
3752

    
3753
static void in1_e1(DisasContext *s, DisasFields *f, DisasOps *o)
3754
{
3755
    o->in1 = load_freg32_i64(get_field(f, r1));
3756
}
3757

    
3758
static void in1_f1_o(DisasContext *s, DisasFields *f, DisasOps *o)
3759
{
3760
    o->in1 = fregs[get_field(f, r1)];
3761
    o->g_in1 = true;
3762
}
3763

    
3764
static void in1_x1_o(DisasContext *s, DisasFields *f, DisasOps *o)
3765
{
3766
    /* ??? Specification exception: r1 must be < 14.  */
3767
    int r1 = get_field(f, r1);
3768
    o->out = fregs[r1];
3769
    o->out2 = fregs[(r1 + 2) & 15];
3770
    o->g_out = o->g_out2 = true;
3771
}
3772

    
3773
static void in1_la1(DisasContext *s, DisasFields *f, DisasOps *o)
3774
{
3775
    o->addr1 = get_address(s, 0, get_field(f, b1), get_field(f, d1));
3776
}
3777

    
3778
static void in1_la2(DisasContext *s, DisasFields *f, DisasOps *o)
3779
{
3780
    int x2 = have_field(f, x2) ? get_field(f, x2) : 0;
3781
    o->addr1 = get_address(s, x2, get_field(f, b2), get_field(f, d2));
3782
}
3783

    
3784
static void in1_m1_8u(DisasContext *s, DisasFields *f, DisasOps *o)
3785
{
3786
    in1_la1(s, f, o);
3787
    o->in1 = tcg_temp_new_i64();
3788
    tcg_gen_qemu_ld8u(o->in1, o->addr1, get_mem_index(s));
3789
}
3790

    
3791
static void in1_m1_16s(DisasContext *s, DisasFields *f, DisasOps *o)
3792
{
3793
    in1_la1(s, f, o);
3794
    o->in1 = tcg_temp_new_i64();
3795
    tcg_gen_qemu_ld16s(o->in1, o->addr1, get_mem_index(s));
3796
}
3797

    
3798
static void in1_m1_16u(DisasContext *s, DisasFields *f, DisasOps *o)
3799
{
3800
    in1_la1(s, f, o);
3801
    o->in1 = tcg_temp_new_i64();
3802
    tcg_gen_qemu_ld16u(o->in1, o->addr1, get_mem_index(s));
3803
}
3804

    
3805
static void in1_m1_32s(DisasContext *s, DisasFields *f, DisasOps *o)
3806
{
3807
    in1_la1(s, f, o);
3808
    o->in1 = tcg_temp_new_i64();
3809
    tcg_gen_qemu_ld32s(o->in1, o->addr1, get_mem_index(s));
3810
}
3811

    
3812
static void in1_m1_32u(DisasContext *s, DisasFields *f, DisasOps *o)
3813
{
3814
    in1_la1(s, f, o);
3815
    o->in1 = tcg_temp_new_i64();
3816
    tcg_gen_qemu_ld32u(o->in1, o->addr1, get_mem_index(s));
3817
}
3818

    
3819
static void in1_m1_64(DisasContext *s, DisasFields *f, DisasOps *o)
3820
{
3821
    in1_la1(s, f, o);
3822
    o->in1 = tcg_temp_new_i64();
3823
    tcg_gen_qemu_ld64(o->in1, o->addr1, get_mem_index(s));
3824
}
3825

    
3826
/* ====================================================================== */
3827
/* The "INput 2" generators.  These load the second operand to an insn.  */
3828

    
3829
static void in2_r1_o(DisasContext *s, DisasFields *f, DisasOps *o)
3830
{
3831
    o->in2 = regs[get_field(f, r1)];
3832
    o->g_in2 = true;
3833
}
3834

    
3835
static void in2_r1_16u(DisasContext *s, DisasFields *f, DisasOps *o)
3836
{
3837
    o->in2 = tcg_temp_new_i64();
3838
    tcg_gen_ext16u_i64(o->in2, regs[get_field(f, r1)]);
3839
}
3840

    
3841
static void in2_r1_32u(DisasContext *s, DisasFields *f, DisasOps *o)
3842
{
3843
    o->in2 = tcg_temp_new_i64();
3844
    tcg_gen_ext32u_i64(o->in2, regs[get_field(f, r1)]);
3845
}
3846

    
3847
static void in2_r2(DisasContext *s, DisasFields *f, DisasOps *o)
3848
{
3849
    o->in2 = load_reg(get_field(f, r2));
3850
}
3851

    
3852
static void in2_r2_o(DisasContext *s, DisasFields *f, DisasOps *o)
3853
{
3854
    o->in2 = regs[get_field(f, r2)];
3855
    o->g_in2 = true;
3856
}
3857

    
3858
static void in2_r2_nz(DisasContext *s, DisasFields *f, DisasOps *o)
3859
{
3860
    int r2 = get_field(f, r2);
3861
    if (r2 != 0) {
3862
        o->in2 = load_reg(r2);
3863
    }
3864
}
3865

    
3866
static void in2_r2_8s(DisasContext *s, DisasFields *f, DisasOps *o)
3867
{
3868
    o->in2 = tcg_temp_new_i64();
3869
    tcg_gen_ext8s_i64(o->in2, regs[get_field(f, r2)]);
3870
}
3871

    
3872
static void in2_r2_8u(DisasContext *s, DisasFields *f, DisasOps *o)
3873
{
3874
    o->in2 = tcg_temp_new_i64();
3875
    tcg_gen_ext8u_i64(o->in2, regs[get_field(f, r2)]);
3876
}
3877

    
3878
static void in2_r2_16s(DisasContext *s, DisasFields *f, DisasOps *o)
3879
{
3880
    o->in2 = tcg_temp_new_i64();
3881
    tcg_gen_ext16s_i64(o->in2, regs[get_field(f, r2)]);
3882
}
3883

    
3884
static void in2_r2_16u(DisasContext *s, DisasFields *f, DisasOps *o)
3885
{
3886
    o->in2 = tcg_temp_new_i64();
3887
    tcg_gen_ext16u_i64(o->in2, regs[get_field(f, r2)]);
3888
}
3889

    
3890
static void in2_r3(DisasContext *s, DisasFields *f, DisasOps *o)
3891
{
3892
    o->in2 = load_reg(get_field(f, r3));
3893
}
3894

    
3895
static void in2_r2_32s(DisasContext *s, DisasFields *f, DisasOps *o)
3896
{
3897
    o->in2 = tcg_temp_new_i64();
3898
    tcg_gen_ext32s_i64(o->in2, regs[get_field(f, r2)]);
3899
}
3900

    
3901
static void in2_r2_32u(DisasContext *s, DisasFields *f, DisasOps *o)
3902
{
3903
    o->in2 = tcg_temp_new_i64();
3904
    tcg_gen_ext32u_i64(o->in2, regs[get_field(f, r2)]);
3905
}
3906

    
3907
static void in2_e2(DisasContext *s, DisasFields *f, DisasOps *o)
3908
{
3909
    o->in2 = load_freg32_i64(get_field(f, r2));
3910
}
3911

    
3912
static void in2_f2_o(DisasContext *s, DisasFields *f, DisasOps *o)
3913
{
3914
    o->in2 = fregs[get_field(f, r2)];
3915
    o->g_in2 = true;
3916
}
3917

    
3918
static void in2_x2_o(DisasContext *s, DisasFields *f, DisasOps *o)
3919
{
3920
    /* ??? Specification exception: r1 must be < 14.  */
3921
    int r2 = get_field(f, r2);
3922
    o->in1 = fregs[r2];
3923
    o->in2 = fregs[(r2 + 2) & 15];
3924
    o->g_in1 = o->g_in2 = true;
3925
}
3926

    
3927
static void in2_ra2(DisasContext *s, DisasFields *f, DisasOps *o)
3928
{
3929
    o->in2 = get_address(s, 0, get_field(f, r2), 0);
3930
}
3931

    
3932
static void in2_a2(DisasContext *s, DisasFields *f, DisasOps *o)
3933
{
3934
    int x2 = have_field(f, x2) ? get_field(f, x2) : 0;
3935
    o->in2 = get_address(s, x2, get_field(f, b2), get_field(f, d2));
3936
}
3937

    
3938
static void in2_ri2(DisasContext *s, DisasFields *f, DisasOps *o)
3939
{
3940
    o->in2 = tcg_const_i64(s->pc + (int64_t)get_field(f, i2) * 2);
3941
}
3942

    
3943
static void in2_sh32(DisasContext *s, DisasFields *f, DisasOps *o)
3944
{
3945
    help_l2_shift(s, f, o, 31);
3946
}
3947

    
3948
static void in2_sh64(DisasContext *s, DisasFields *f, DisasOps *o)
3949
{
3950
    help_l2_shift(s, f, o, 63);
3951
}
3952

    
3953
static void in2_m2_8u(DisasContext *s, DisasFields *f, DisasOps *o)
3954
{
3955
    in2_a2(s, f, o);
3956
    tcg_gen_qemu_ld8u(o->in2, o->in2, get_mem_index(s));
3957
}
3958

    
3959
static void in2_m2_16s(DisasContext *s, DisasFields *f, DisasOps *o)
3960
{
3961
    in2_a2(s, f, o);
3962
    tcg_gen_qemu_ld16s(o->in2, o->in2, get_mem_index(s));
3963
}
3964

    
3965
static void in2_m2_16u(DisasContext *s, DisasFields *f, DisasOps *o)
3966
{
3967
    in2_a2(s, f, o);
3968
    tcg_gen_qemu_ld16u(o->in2, o->in2, get_mem_index(s));
3969
}
3970

    
3971
static void in2_m2_32s(DisasContext *s, DisasFields *f, DisasOps *o)
3972
{
3973
    in2_a2(s, f, o);
3974
    tcg_gen_qemu_ld32s(o->in2, o->in2, get_mem_index(s));
3975
}
3976

    
3977
static void in2_m2_32u(DisasContext *s, DisasFields *f, DisasOps *o)
3978
{
3979
    in2_a2(s, f, o);
3980
    tcg_gen_qemu_ld32u(o->in2, o->in2, get_mem_index(s));
3981
}
3982

    
3983
static void in2_m2_64(DisasContext *s, DisasFields *f, DisasOps *o)
3984
{
3985
    in2_a2(s, f, o);
3986
    tcg_gen_qemu_ld64(o->in2, o->in2, get_mem_index(s));
3987
}
3988

    
3989
static void in2_mri2_16u(DisasContext *s, DisasFields *f, DisasOps *o)
3990
{
3991
    in2_ri2(s, f, o);
3992
    tcg_gen_qemu_ld16u(o->in2, o->in2, get_mem_index(s));
3993
}
3994

    
3995
static void in2_mri2_32s(DisasContext *s, DisasFields *f, DisasOps *o)
3996
{
3997
    in2_ri2(s, f, o);
3998
    tcg_gen_qemu_ld32s(o->in2, o->in2, get_mem_index(s));
3999
}
4000

    
4001
static void in2_mri2_32u(DisasContext *s, DisasFields *f, DisasOps *o)
4002
{
4003
    in2_ri2(s, f, o);
4004
    tcg_gen_qemu_ld32u(o->in2, o->in2, get_mem_index(s));
4005
}
4006

    
4007
static void in2_mri2_64(DisasContext *s, DisasFields *f, DisasOps *o)
4008
{
4009
    in2_ri2(s, f, o);
4010
    tcg_gen_qemu_ld64(o->in2, o->in2, get_mem_index(s));
4011
}
4012

    
4013
static void in2_i2(DisasContext *s, DisasFields *f, DisasOps *o)
4014
{
4015
    o->in2 = tcg_const_i64(get_field(f, i2));
4016
}
4017

    
4018
static void in2_i2_8u(DisasContext *s, DisasFields *f, DisasOps *o)
4019
{
4020
    o->in2 = tcg_const_i64((uint8_t)get_field(f, i2));
4021
}
4022

    
4023
static void in2_i2_16u(DisasContext *s, DisasFields *f, DisasOps *o)
4024
{
4025
    o->in2 = tcg_const_i64((uint16_t)get_field(f, i2));
4026
}
4027

    
4028
static void in2_i2_32u(DisasContext *s, DisasFields *f, DisasOps *o)
4029
{
4030
    o->in2 = tcg_const_i64((uint32_t)get_field(f, i2));
4031
}
4032

    
4033
static void in2_i2_16u_shl(DisasContext *s, DisasFields *f, DisasOps *o)
4034
{
4035
    uint64_t i2 = (uint16_t)get_field(f, i2);
4036
    o->in2 = tcg_const_i64(i2 << s->insn->data);
4037
}
4038

    
4039
static void in2_i2_32u_shl(DisasContext *s, DisasFields *f, DisasOps *o)
4040
{
4041
    uint64_t i2 = (uint32_t)get_field(f, i2);
4042
    o->in2 = tcg_const_i64(i2 << s->insn->data);
4043
}
4044

    
4045
/* ====================================================================== */
4046

    
4047
/* Find opc within the table of insns.  This is formulated as a switch
4048
   statement so that (1) we get compile-time notice of cut-paste errors
4049
   for duplicated opcodes, and (2) the compiler generates the binary
4050
   search tree, rather than us having to post-process the table.  */
4051

    
4052
#define C(OPC, NM, FT, FC, I1, I2, P, W, OP, CC) \
4053
    D(OPC, NM, FT, FC, I1, I2, P, W, OP, CC, 0)
4054

    
4055
#define D(OPC, NM, FT, FC, I1, I2, P, W, OP, CC, D) insn_ ## NM,
4056

    
4057
enum DisasInsnEnum {
4058
#include "insn-data.def"
4059
};
4060

    
4061
#undef D
4062
#define D(OPC, NM, FT, FC, I1, I2, P, W, OP, CC, D) { \
4063
    .opc = OPC,                           \
4064
    .fmt = FMT_##FT,                      \
4065
    .fac = FAC_##FC,                      \
4066
    .name = #NM,                          \
4067
    .help_in1 = in1_##I1,                 \
4068
    .help_in2 = in2_##I2,                 \
4069
    .help_prep = prep_##P,                \
4070
    .help_wout = wout_##W,                \
4071
    .help_cout = cout_##CC,               \
4072
    .help_op = op_##OP,                   \
4073
    .data = D                             \
4074
 },
4075

    
4076
/* Allow 0 to be used for NULL in the table below.  */
4077
#define in1_0  NULL
4078
#define in2_0  NULL
4079
#define prep_0  NULL
4080
#define wout_0  NULL
4081
#define cout_0  NULL
4082
#define op_0  NULL
4083

    
4084
static const DisasInsn insn_info[] = {
4085
#include "insn-data.def"
4086
};
4087

    
4088
#undef D
4089
#define D(OPC, NM, FT, FC, I1, I2, P, W, OP, CC, D) \
4090
    case OPC: return &insn_info[insn_ ## NM];
4091

    
4092
static const DisasInsn *lookup_opc(uint16_t opc)
4093
{
4094
    switch (opc) {
4095
#include "insn-data.def"
4096
    default:
4097
        return NULL;
4098
    }
4099
}
4100

    
4101
#undef D
4102
#undef C
4103

    
4104
/* Extract a field from the insn.  The INSN should be left-aligned in
4105
   the uint64_t so that we can more easily utilize the big-bit-endian
4106
   definitions we extract from the Principals of Operation.  */
4107

    
4108
static void extract_field(DisasFields *o, const DisasField *f, uint64_t insn)
4109
{
4110
    uint32_t r, m;
4111

    
4112
    if (f->size == 0) {
4113
        return;
4114
    }
4115

    
4116
    /* Zero extract the field from the insn.  */
4117
    r = (insn << f->beg) >> (64 - f->size);
4118

    
4119
    /* Sign-extend, or un-swap the field as necessary.  */
4120
    switch (f->type) {
4121
    case 0: /* unsigned */
4122
        break;
4123
    case 1: /* signed */
4124
        assert(f->size <= 32);
4125
        m = 1u << (f->size - 1);
4126
        r = (r ^ m) - m;
4127
        break;
4128
    case 2: /* dl+dh split, signed 20 bit. */
4129
        r = ((int8_t)r << 12) | (r >> 8);
4130
        break;
4131
    default:
4132
        abort();
4133
    }
4134

    
4135
    /* Validate that the "compressed" encoding we selected above is valid.
4136
       I.e. we havn't make two different original fields overlap.  */
4137
    assert(((o->presentC >> f->indexC) & 1) == 0);
4138
    o->presentC |= 1 << f->indexC;
4139
    o->presentO |= 1 << f->indexO;
4140

    
4141
    o->c[f->indexC] = r;
4142
}
4143

    
4144
/* Lookup the insn at the current PC, extracting the operands into O and
4145
   returning the info struct for the insn.  Returns NULL for invalid insn.  */
4146

    
4147
static const DisasInsn *extract_insn(CPUS390XState *env, DisasContext *s,
4148
                                     DisasFields *f)
4149
{
4150
    uint64_t insn, pc = s->pc;
4151
    int op, op2, ilen;
4152
    const DisasInsn *info;
4153

    
4154
    insn = ld_code2(env, pc);
4155
    op = (insn >> 8) & 0xff;
4156
    ilen = get_ilen(op);
4157
    s->next_pc = s->pc + ilen;
4158

    
4159
    switch (ilen) {
4160
    case 2:
4161
        insn = insn << 48;
4162
        break;
4163
    case 4:
4164
        insn = ld_code4(env, pc) << 32;
4165
        break;
4166
    case 6:
4167
        insn = (insn << 48) | (ld_code4(env, pc + 2) << 16);
4168
        break;
4169
    default:
4170
        abort();
4171
    }
4172

    
4173
    /* We can't actually determine the insn format until we've looked up
4174
       the full insn opcode.  Which we can't do without locating the
4175
       secondary opcode.  Assume by default that OP2 is at bit 40; for
4176
       those smaller insns that don't actually have a secondary opcode
4177
       this will correctly result in OP2 = 0. */
4178
    switch (op) {
4179
    case 0x01: /* E */
4180
    case 0x80: /* S */
4181
    case 0x82: /* S */
4182
    case 0x93: /* S */
4183
    case 0xb2: /* S, RRF, RRE */
4184
    case 0xb3: /* RRE, RRD, RRF */
4185
    case 0xb9: /* RRE, RRF */
4186
    case 0xe5: /* SSE, SIL */
4187
        op2 = (insn << 8) >> 56;
4188
        break;
4189
    case 0xa5: /* RI */
4190
    case 0xa7: /* RI */
4191
    case 0xc0: /* RIL */
4192
    case 0xc2: /* RIL */
4193
    case 0xc4: /* RIL */
4194
    case 0xc6: /* RIL */
4195
    case 0xc8: /* SSF */
4196
    case 0xcc: /* RIL */
4197
        op2 = (insn << 12) >> 60;
4198
        break;
4199
    case 0xd0 ... 0xdf: /* SS */
4200
    case 0xe1: /* SS */
4201
    case 0xe2: /* SS */
4202
    case 0xe8: /* SS */
4203
    case 0xe9: /* SS */
4204
    case 0xea: /* SS */
4205
    case 0xee ... 0xf3: /* SS */
4206
    case 0xf8 ... 0xfd: /* SS */
4207
        op2 = 0;
4208
        break;
4209
    default:
4210
        op2 = (insn << 40) >> 56;
4211
        break;
4212
    }
4213

    
4214
    memset(f, 0, sizeof(*f));
4215
    f->op = op;
4216
    f->op2 = op2;
4217

    
4218
    /* Lookup the instruction.  */
4219
    info = lookup_opc(op << 8 | op2);
4220

    
4221
    /* If we found it, extract the operands.  */
4222
    if (info != NULL) {
4223
        DisasFormat fmt = info->fmt;
4224
        int i;
4225

    
4226
        for (i = 0; i < NUM_C_FIELD; ++i) {
4227
            extract_field(f, &format_info[fmt].op[i], insn);
4228
        }
4229
    }
4230
    return info;
4231
}
4232

    
4233
static ExitStatus translate_one(CPUS390XState *env, DisasContext *s)
4234
{
4235
    const DisasInsn *insn;
4236
    ExitStatus ret = NO_EXIT;
4237
    DisasFields f;
4238
    DisasOps o;
4239

    
4240
    /* Search for the insn in the table.  */
4241
    insn = extract_insn(env, s, &f);
4242

    
4243
    /* Not found means unimplemented/illegal opcode.  */
4244
    if (insn == NULL) {
4245
        qemu_log_mask(LOG_UNIMP, "unimplemented opcode 0x%02x%02x\n",
4246
                      f.op, f.op2);
4247
        gen_illegal_opcode(s);
4248
        return EXIT_NORETURN;
4249
    }
4250

    
4251
    /* Set up the strutures we use to communicate with the helpers. */
4252
    s->insn = insn;
4253
    s->fields = &f;
4254
    o.g_out = o.g_out2 = o.g_in1 = o.g_in2 = false;
4255
    TCGV_UNUSED_I64(o.out);
4256
    TCGV_UNUSED_I64(o.out2);
4257
    TCGV_UNUSED_I64(o.in1);
4258
    TCGV_UNUSED_I64(o.in2);
4259
    TCGV_UNUSED_I64(o.addr1);
4260

    
4261
    /* Implement the instruction.  */
4262
    if (insn->help_in1) {
4263
        insn->help_in1(s, &f, &o);
4264
    }
4265
    if (insn->help_in2) {
4266
        insn->help_in2(s, &f, &o);
4267
    }
4268
    if (insn->help_prep) {
4269
        insn->help_prep(s, &f, &o);
4270
    }
4271
    if (insn->help_op) {
4272
        ret = insn->help_op(s, &o);
4273
    }
4274
    if (insn->help_wout) {
4275
        insn->help_wout(s, &f, &o);
4276
    }
4277
    if (insn->help_cout) {
4278
        insn->help_cout(s, &o);
4279
    }
4280

    
4281
    /* Free any temporaries created by the helpers.  */
4282
    if (!TCGV_IS_UNUSED_I64(o.out) && !o.g_out) {
4283
        tcg_temp_free_i64(o.out);
4284
    }
4285
    if (!TCGV_IS_UNUSED_I64(o.out2) && !o.g_out2) {
4286
        tcg_temp_free_i64(o.out2);
4287
    }
4288
    if (!TCGV_IS_UNUSED_I64(o.in1) && !o.g_in1) {
4289
        tcg_temp_free_i64(o.in1);
4290
    }
4291
    if (!TCGV_IS_UNUSED_I64(o.in2) && !o.g_in2) {
4292
        tcg_temp_free_i64(o.in2);
4293
    }
4294
    if (!TCGV_IS_UNUSED_I64(o.addr1)) {
4295
        tcg_temp_free_i64(o.addr1);
4296
    }
4297

    
4298
    /* Advance to the next instruction.  */
4299
    s->pc = s->next_pc;
4300
    return ret;
4301
}
4302

    
4303
static inline void gen_intermediate_code_internal(CPUS390XState *env,
4304
                                                  TranslationBlock *tb,
4305
                                                  int search_pc)
4306
{
4307
    DisasContext dc;
4308
    target_ulong pc_start;
4309
    uint64_t next_page_start;
4310
    uint16_t *gen_opc_end;
4311
    int j, lj = -1;
4312
    int num_insns, max_insns;
4313
    CPUBreakpoint *bp;
4314
    ExitStatus status;
4315
    bool do_debug;
4316

    
4317
    pc_start = tb->pc;
4318

    
4319
    /* 31-bit mode */
4320
    if (!(tb->flags & FLAG_MASK_64)) {
4321
        pc_start &= 0x7fffffff;
4322
    }
4323

    
4324
    dc.tb = tb;
4325
    dc.pc = pc_start;
4326
    dc.cc_op = CC_OP_DYNAMIC;
4327
    do_debug = dc.singlestep_enabled = env->singlestep_enabled;
4328

    
4329
    gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
4330

    
4331
    next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
4332

    
4333
    num_insns = 0;
4334
    max_insns = tb->cflags & CF_COUNT_MASK;
4335
    if (max_insns == 0) {
4336
        max_insns = CF_COUNT_MASK;
4337
    }
4338

    
4339
    gen_icount_start();
4340

    
4341
    do {
4342
        if (search_pc) {
4343
            j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
4344
            if (lj < j) {
4345
                lj++;
4346
                while (lj < j) {
4347
                    tcg_ctx.gen_opc_instr_start[lj++] = 0;
4348
                }
4349
            }
4350
            tcg_ctx.gen_opc_pc[lj] = dc.pc;
4351
            gen_opc_cc_op[lj] = dc.cc_op;
4352
            tcg_ctx.gen_opc_instr_start[lj] = 1;
4353
            tcg_ctx.gen_opc_icount[lj] = num_insns;
4354
        }
4355
        if (++num_insns == max_insns && (tb->cflags & CF_LAST_IO)) {
4356
            gen_io_start();
4357
        }
4358

    
4359
        if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
4360
            tcg_gen_debug_insn_start(dc.pc);
4361
        }
4362

    
4363
        status = NO_EXIT;
4364
        if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
4365
            QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
4366
                if (bp->pc == dc.pc) {
4367
                    status = EXIT_PC_STALE;
4368
                    do_debug = true;
4369
                    break;
4370
                }
4371
            }
4372
        }
4373
        if (status == NO_EXIT) {
4374
            status = translate_one(env, &dc);
4375
        }
4376

    
4377
        /* If we reach a page boundary, are single stepping,
4378
           or exhaust instruction count, stop generation.  */
4379
        if (status == NO_EXIT
4380
            && (dc.pc >= next_page_start
4381
                || tcg_ctx.gen_opc_ptr >= gen_opc_end
4382
                || num_insns >= max_insns
4383
                || singlestep
4384
                || env->singlestep_enabled)) {
4385
            status = EXIT_PC_STALE;
4386
        }
4387
    } while (status == NO_EXIT);
4388

    
4389
    if (tb->cflags & CF_LAST_IO) {
4390
        gen_io_end();
4391
    }
4392

    
4393
    switch (status) {
4394
    case EXIT_GOTO_TB:
4395
    case EXIT_NORETURN:
4396
        break;
4397
    case EXIT_PC_STALE:
4398
        update_psw_addr(&dc);
4399
        /* FALLTHRU */
4400
    case EXIT_PC_UPDATED:
4401
        /* Next TB starts off with CC_OP_DYNAMIC, so make sure the
4402
           cc op type is in env */
4403
        update_cc_op(&dc);
4404
        /* Exit the TB, either by raising a debug exception or by return.  */
4405
        if (do_debug) {
4406
            gen_exception(EXCP_DEBUG);
4407
        } else {
4408
            tcg_gen_exit_tb(0);
4409
        }
4410
        break;
4411
    default:
4412
        abort();
4413
    }
4414

    
4415
    gen_icount_end(tb, num_insns);
4416
    *tcg_ctx.gen_opc_ptr = INDEX_op_end;
4417
    if (search_pc) {
4418
        j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
4419
        lj++;
4420
        while (lj <= j) {
4421
            tcg_ctx.gen_opc_instr_start[lj++] = 0;
4422
        }
4423
    } else {
4424
        tb->size = dc.pc - pc_start;
4425
        tb->icount = num_insns;
4426
    }
4427

    
4428
#if defined(S390X_DEBUG_DISAS)
4429
    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
4430
        qemu_log("IN: %s\n", lookup_symbol(pc_start));
4431
        log_target_disas(env, pc_start, dc.pc - pc_start, 1);
4432
        qemu_log("\n");
4433
    }
4434
#endif
4435
}
4436

    
4437
void gen_intermediate_code (CPUS390XState *env, struct TranslationBlock *tb)
4438
{
4439
    gen_intermediate_code_internal(env, tb, 0);
4440
}
4441

    
4442
void gen_intermediate_code_pc (CPUS390XState *env, struct TranslationBlock *tb)
4443
{
4444
    gen_intermediate_code_internal(env, tb, 1);
4445
}
4446

    
4447
void restore_state_to_opc(CPUS390XState *env, TranslationBlock *tb, int pc_pos)
4448
{
4449
    int cc_op;
4450
    env->psw.addr = tcg_ctx.gen_opc_pc[pc_pos];
4451
    cc_op = gen_opc_cc_op[pc_pos];
4452
    if ((cc_op != CC_OP_DYNAMIC) && (cc_op != CC_OP_STATIC)) {
4453
        env->cc_op = cc_op;
4454
    }
4455
}