Revision 2ae68059

b/target-s390x/helper.h
8 8
DEF_HELPER_4(clc, i32, env, i32, i64, i64)
9 9
DEF_HELPER_3(mvcl, i32, env, i32, i32)
10 10
DEF_HELPER_4(clm, i32, env, i32, i32, i64)
11
DEF_HELPER_4(stcm, void, env, i32, i32, i64)
12 11
DEF_HELPER_FLAGS_3(mul128, TCG_CALL_NO_RWG, i64, env, i64, i64)
13 12
DEF_HELPER_3(divs32, s64, env, s64, s64)
14 13
DEF_HELPER_3(divu32, i64, env, i64, i64)
......
26 25
DEF_HELPER_FLAGS_1(nabs_i32, TCG_CALL_NO_RWG_SE, s32, s32)
27 26
DEF_HELPER_FLAGS_1(abs_i64, TCG_CALL_NO_RWG_SE, i64, s64)
28 27
DEF_HELPER_FLAGS_1(nabs_i64, TCG_CALL_NO_RWG_SE, s64, s64)
29
DEF_HELPER_4(stcmh, void, env, i32, i64, i32)
30 28
DEF_HELPER_3(ipm, void, env, i32, i32)
31 29
DEF_HELPER_4(stam, void, env, i32, i64, i32)
32 30
DEF_HELPER_4(lam, void, env, i32, i64, i32)
b/target-s390x/insn-data.def
405 405
/* STORE CHARACTER */
406 406
    C(0x4200, STC,     RX_a,  Z,   r1_o, a2, 0, 0, st8, 0)
407 407
    C(0xe372, STCY,    RXY_a, LD,  r1_o, a2, 0, 0, st8, 0)
408
/* STORE CHARACTERS UNDER MASK */
409
    D(0xbe00, STCM,    RS_b,  Z,   r1_o, a2, 0, 0, stcm, 0, 0)
410
    D(0xeb2d, STCMY,   RSY_b, LD,  r1_o, a2, 0, 0, stcm, 0, 0)
411
    D(0xeb2c, STCMH,   RSY_b, LD,  r1_o, a2, 0, 0, stcm, 0, 32)
408 412
/* STORE HALFWORD */
409 413
    C(0x4000, STH,     RX_a,  Z,   r1_o, a2, 0, 0, st16, 0)
410 414
    C(0xe370, STHY,    RXY_a, LD,  r1_o, a2, 0, 0, st16, 0)
b/target-s390x/mem_helper.c
304 304
    return cc;
305 305
}
306 306

  
307
/* store character under mask */
308
void HELPER(stcm)(CPUS390XState *env, uint32_t r1, uint32_t mask,
309
                  uint64_t addr)
310
{
311
    uint8_t r;
312

  
313
    HELPER_LOG("%s: r1 0x%x mask 0x%x addr 0x%lx\n", __func__, r1, mask,
314
               addr);
315
    while (mask) {
316
        if (mask & 8) {
317
            r = (r1 & 0xff000000UL) >> 24;
318
            cpu_stb_data(env, addr, r);
319
            HELPER_LOG("mask 0x%x %02x (0x%lx) ", mask, r, addr);
320
            addr++;
321
        }
322
        mask = (mask << 1) & 0xf;
323
        r1 <<= 8;
324
    }
325
    HELPER_LOG("\n");
326
}
327

  
328 307
static inline uint64_t get_address(CPUS390XState *env, int x2, int b2, int d2)
329 308
{
330 309
    uint64_t r = d2;
......
608 587
    return cc;
609 588
}
610 589

  
611
/* store character under mask high operates on the upper half of r1 */
612
void HELPER(stcmh)(CPUS390XState *env, uint32_t r1, uint64_t address,
613
                   uint32_t mask)
614
{
615
    int pos = 56; /* top of the upper half of r1 */
616

  
617
    while (mask) {
618
        if (mask & 8) {
619
            cpu_stb_data(env, address, (env->regs[r1] >> pos) & 0xff);
620
            address++;
621
        }
622
        mask = (mask << 1) & 0xf;
623
        pos -= 8;
624
    }
625
}
626

  
627 590
/* load access registers r1 to r3 from memory at a2 */
628 591
void HELPER(lam)(CPUS390XState *env, uint32_t r1, uint64_t a2, uint32_t r3)
629 592
{
b/target-s390x/translate.c
1110 1110
    LOG_DISAS("disas_eb: op 0x%x r1 %d r3 %d b2 %d d2 0x%x\n",
1111 1111
              op, r1, r3, b2, d2);
1112 1112
    switch (op) {
1113
    case 0x2c: /* STCMH R1,M3,D2(B2) [RSY] */
1114
        tmp = get_address(s, 0, b2, d2);
1115
        tmp32_1 = tcg_const_i32(r1);
1116
        tmp32_2 = tcg_const_i32(r3);
1117
        potential_page_fault(s);
1118
        gen_helper_stcmh(cpu_env, tmp32_1, tmp, tmp32_2);
1119
        tcg_temp_free_i64(tmp);
1120
        tcg_temp_free_i32(tmp32_1);
1121
        tcg_temp_free_i32(tmp32_2);
1122
        break;
1123 1113
#ifndef CONFIG_USER_ONLY
1124 1114
    case 0x2f: /* LCTLG     R1,R3,D2(B2)     [RSE] */
1125 1115
        /* Load Control */
......
1967 1957

  
1968 1958
static void disas_s390_insn(CPUS390XState *env, DisasContext *s)
1969 1959
{
1970
    TCGv_i64 tmp;
1971
    TCGv_i32 tmp32_1, tmp32_2;
1972 1960
    unsigned char opc;
1973 1961
    uint64_t insn;
1974 1962
    int op, r1, r2, r3, d2, x2, b2, r1b;
......
1997 1985
        op = (insn >> 16) & 0xff;
1998 1986
        disas_b9(env, s, op, r1, r2);
1999 1987
        break;
2000
    case 0xbe: /* STCM R1,M3,D2(B2) [RS] */
2001
        insn = ld_code4(env, s->pc);
2002
        decode_rs(s, insn, &r1, &r3, &b2, &d2);
2003
        tmp = get_address(s, 0, b2, d2);
2004
        tmp32_1 = load_reg32(r1);
2005
        tmp32_2 = tcg_const_i32(r3);
2006
        potential_page_fault(s);
2007
        gen_helper_stcm(cpu_env, tmp32_1, tmp32_2, tmp);
2008
        tcg_temp_free_i64(tmp);
2009
        tcg_temp_free_i32(tmp32_1);
2010
        tcg_temp_free_i32(tmp32_2);
2011
        break;
2012 1988
    case 0xe3:
2013 1989
        insn = ld_code6(env, s->pc);
2014 1990
        debug_insn(insn);
......
3271 3247
    return NO_EXIT;
3272 3248
}
3273 3249

  
3250
static ExitStatus op_stcm(DisasContext *s, DisasOps *o)
3251
{
3252
    int m3 = get_field(s->fields, m3);
3253
    int pos, base = s->insn->data;
3254
    TCGv_i64 tmp = tcg_temp_new_i64();
3255

  
3256
    pos = base + ctz32(m3) * 8;
3257
    switch (m3) {
3258
    case 0xf:
3259
        /* Effectively a 32-bit store.  */
3260
        tcg_gen_shri_i64(tmp, o->in1, pos);
3261
        tcg_gen_qemu_st32(tmp, o->in2, get_mem_index(s));
3262
        break;
3263

  
3264
    case 0xc:
3265
    case 0x6:
3266
    case 0x3:
3267
        /* Effectively a 16-bit store.  */
3268
        tcg_gen_shri_i64(tmp, o->in1, pos);
3269
        tcg_gen_qemu_st16(tmp, o->in2, get_mem_index(s));
3270
        break;
3271

  
3272
    case 0x8:
3273
    case 0x4:
3274
    case 0x2:
3275
    case 0x1:
3276
        /* Effectively an 8-bit store.  */
3277
        tcg_gen_shri_i64(tmp, o->in1, pos);
3278
        tcg_gen_qemu_st8(tmp, o->in2, get_mem_index(s));
3279
        break;
3280

  
3281
    default:
3282
        /* This is going to be a sequence of shifts and stores.  */
3283
        pos = base + 32 - 8;
3284
        while (m3) {
3285
            if (m3 & 0x8) {
3286
                tcg_gen_shri_i64(tmp, o->in1, pos);
3287
                tcg_gen_qemu_st8(tmp, o->in2, get_mem_index(s));
3288
                tcg_gen_addi_i64(o->in2, o->in2, 1);
3289
            }
3290
            m3 = (m3 << 1) & 0xf;
3291
            pos -= 8;
3292
        }
3293
        break;
3294
    }
3295
    tcg_temp_free_i64(tmp);
3296
    return NO_EXIT;
3297
}
3298

  
3274 3299
static ExitStatus op_stm(DisasContext *s, DisasOps *o)
3275 3300
{
3276 3301
    int r1 = get_field(s->fields, r1);

Also available in: Unified diff