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