Merge branch 's390-next' of git://repo.or.cz/qemu/agraf

* 's390-next' of git://repo.or.cz/qemu/agraf:
  s390x: implement lrvgr
  s390x: fix cksm instruction
  s390x: free tmp explicitly in every opcode for disas_a5()
  target-s390x: Add missing tcg_temp_free_i32()
  target-s390x: Add missing tcg_temp_free_i64() in disas_s390_insn(), opc == 0x90
  target-s390x: Add missing tcg_temp_free_i64() in disas_s390_insn(), opc == 0x8e
  target-s390x: Add missing tcg_temp_free_i64() in disas_b2()
  target-s390x: Add missing tcg_temp_free_i64() in do_mh()
  target-s390x: Add missing tcg_temp_free_i64() in gen_jcc()
  target-s390x: Fix duplicate call of tcg_temp_new_i64
  target-s390x: Fix wrong argument in call of tcg_gen_shl_i64()
  target-s390x: Fix build for non-linux hosts
  s390x: update zipl rom
This commit is contained in:
Aurelien Jarno 2011-06-03 17:47:04 +02:00
commit 47ba198454
4 changed files with 35 additions and 29 deletions

Binary file not shown.

View File

@ -28,11 +28,6 @@
#include "qemu-common.h" #include "qemu-common.h"
#include "qemu-timer.h" #include "qemu-timer.h"
#if !defined(CONFIG_USER_ONLY)
#include <linux/kvm.h>
#include "kvm.h"
#endif
//#define DEBUG_S390 //#define DEBUG_S390
//#define DEBUG_S390_PTE //#define DEBUG_S390_PTE
//#define DEBUG_S390_STDOUT //#define DEBUG_S390_STDOUT

View File

@ -1731,25 +1731,15 @@ void HELPER(sqdbr)(uint32_t f1, uint32_t f2)
env->fregs[f1].d = float64_sqrt(env->fregs[f2].d, &env->fpu_status); env->fregs[f1].d = float64_sqrt(env->fregs[f2].d, &env->fpu_status);
} }
static inline uint64_t cksm_overflow(uint64_t cksm)
{
if (cksm > 0xffffffffULL) {
cksm &= 0xffffffffULL;
cksm++;
}
return cksm;
}
/* checksum */ /* checksum */
void HELPER(cksm)(uint32_t r1, uint32_t r2) void HELPER(cksm)(uint32_t r1, uint32_t r2)
{ {
uint64_t src = get_address_31fix(r2); uint64_t src = get_address_31fix(r2);
uint64_t src_len = env->regs[(r2 + 1) & 15]; uint64_t src_len = env->regs[(r2 + 1) & 15];
uint64_t cksm = 0; uint64_t cksm = (uint32_t)env->regs[r1];
while (src_len >= 4) { while (src_len >= 4) {
cksm += ldl(src); cksm += ldl(src);
cksm = cksm_overflow(cksm);
/* move to next word */ /* move to next word */
src_len -= 4; src_len -= 4;
@ -1760,26 +1750,24 @@ void HELPER(cksm)(uint32_t r1, uint32_t r2)
case 0: case 0:
break; break;
case 1: case 1:
cksm += ldub(src); cksm += ldub(src) << 24;
cksm = cksm_overflow(cksm);
break; break;
case 2: case 2:
cksm += lduw(src); cksm += lduw(src) << 16;
cksm = cksm_overflow(cksm);
break; break;
case 3: case 3:
/* XXX check if this really is correct */ cksm += lduw(src) << 16;
cksm += lduw(src) << 8; cksm += ldub(src + 2) << 8;
cksm += ldub(src + 2);
cksm = cksm_overflow(cksm);
break; break;
} }
/* indicate we've processed everything */ /* indicate we've processed everything */
env->regs[r2] = src + src_len;
env->regs[(r2 + 1) & 15] = 0; env->regs[(r2 + 1) & 15] = 0;
/* store result */ /* store result */
env->regs[r1] = (env->regs[r1] & 0xffffffff00000000ULL) | (uint32_t)cksm; env->regs[r1] = (env->regs[r1] & 0xffffffff00000000ULL) |
((uint32_t)cksm + (cksm >> 32));
} }
static inline uint32_t cc_calc_ltgt_32(CPUState *env, int32_t src, static inline uint32_t cc_calc_ltgt_32(CPUState *env, int32_t src,

View File

@ -1078,9 +1078,12 @@ static void gen_jcc(DisasContext *s, uint32_t mask, int skip)
tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, skip); tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, skip);
break; break;
default: default:
tcg_temp_free_i32(tmp);
tcg_temp_free_i32(tmp2);
goto do_dynamic; goto do_dynamic;
} }
tcg_temp_free_i32(tmp); tcg_temp_free_i32(tmp);
tcg_temp_free_i32(tmp2);
account_inline_branch(s); account_inline_branch(s);
break; break;
case CC_OP_TM_64: case CC_OP_TM_64:
@ -1095,6 +1098,7 @@ static void gen_jcc(DisasContext *s, uint32_t mask, int skip)
tcg_gen_brcondi_i64(TCG_COND_EQ, tmp64, 0, skip); tcg_gen_brcondi_i64(TCG_COND_EQ, tmp64, 0, skip);
break; break;
default: default:
tcg_temp_free_i64(tmp64);
goto do_dynamic; goto do_dynamic;
} }
tcg_temp_free_i64(tmp64); tcg_temp_free_i64(tmp64);
@ -2056,7 +2060,7 @@ do_mh:
even for very long ones... */ even for very long ones... */
tmp = get_address(s, 0, b2, d2); tmp = get_address(s, 0, b2, d2);
tmp3 = tcg_const_i64(stm_len); tmp3 = tcg_const_i64(stm_len);
tmp4 = tcg_const_i64(32); tmp4 = tcg_const_i64(op == 0x26 ? 32 : 4);
for (i = r1;; i = (i + 1) % 16) { for (i = r1;; i = (i + 1) % 16) {
switch (op) { switch (op) {
case 0x4: case 0x4:
@ -2068,9 +2072,8 @@ do_mh:
tcg_gen_qemu_ld32u(tmp2, tmp, get_mem_index(s)); tcg_gen_qemu_ld32u(tmp2, tmp, get_mem_index(s));
tcg_gen_trunc_i64_i32(TCGV_HIGH(regs[i]), tmp2); tcg_gen_trunc_i64_i32(TCGV_HIGH(regs[i]), tmp2);
#else #else
tmp2 = tcg_temp_new_i64();
tcg_gen_qemu_ld32u(tmp2, tmp, get_mem_index(s)); tcg_gen_qemu_ld32u(tmp2, tmp, get_mem_index(s));
tcg_gen_shl_i64(tmp2, tmp2, 4); tcg_gen_shl_i64(tmp2, tmp2, tmp4);
tcg_gen_ext32u_i64(regs[i], regs[i]); tcg_gen_ext32u_i64(regs[i], regs[i]);
tcg_gen_or_i64(regs[i], regs[i], tmp2); tcg_gen_or_i64(regs[i], regs[i], tmp2);
#endif #endif
@ -2094,6 +2097,7 @@ do_mh:
tcg_gen_add_i64(tmp, tmp, tmp3); tcg_gen_add_i64(tmp, tmp, tmp3);
} }
tcg_temp_free_i64(tmp); tcg_temp_free_i64(tmp);
tcg_temp_free_i64(tmp3);
tcg_temp_free_i64(tmp4); tcg_temp_free_i64(tmp4);
break; break;
case 0x2c: /* STCMH R1,M3,D2(B2) [RSY] */ case 0x2c: /* STCMH R1,M3,D2(B2) [RSY] */
@ -2330,18 +2334,22 @@ static void disas_a5(DisasContext *s, int op, int r1, int i2)
case 0x0: /* IIHH R1,I2 [RI] */ case 0x0: /* IIHH R1,I2 [RI] */
tmp = tcg_const_i64(i2); tmp = tcg_const_i64(i2);
tcg_gen_deposit_i64(regs[r1], regs[r1], tmp, 48, 16); tcg_gen_deposit_i64(regs[r1], regs[r1], tmp, 48, 16);
tcg_temp_free_i64(tmp);
break; break;
case 0x1: /* IIHL R1,I2 [RI] */ case 0x1: /* IIHL R1,I2 [RI] */
tmp = tcg_const_i64(i2); tmp = tcg_const_i64(i2);
tcg_gen_deposit_i64(regs[r1], regs[r1], tmp, 32, 16); tcg_gen_deposit_i64(regs[r1], regs[r1], tmp, 32, 16);
tcg_temp_free_i64(tmp);
break; break;
case 0x2: /* IILH R1,I2 [RI] */ case 0x2: /* IILH R1,I2 [RI] */
tmp = tcg_const_i64(i2); tmp = tcg_const_i64(i2);
tcg_gen_deposit_i64(regs[r1], regs[r1], tmp, 16, 16); tcg_gen_deposit_i64(regs[r1], regs[r1], tmp, 16, 16);
tcg_temp_free_i64(tmp);
break; break;
case 0x3: /* IILL R1,I2 [RI] */ case 0x3: /* IILL R1,I2 [RI] */
tmp = tcg_const_i64(i2); tmp = tcg_const_i64(i2);
tcg_gen_deposit_i64(regs[r1], regs[r1], tmp, 0, 16); tcg_gen_deposit_i64(regs[r1], regs[r1], tmp, 0, 16);
tcg_temp_free_i64(tmp);
break; break;
case 0x4: /* NIHH R1,I2 [RI] */ case 0x4: /* NIHH R1,I2 [RI] */
case 0x8: /* OIHH R1,I2 [RI] */ case 0x8: /* OIHH R1,I2 [RI] */
@ -2366,6 +2374,7 @@ static void disas_a5(DisasContext *s, int op, int r1, int i2)
set_cc_nz_u32(s, tmp32); set_cc_nz_u32(s, tmp32);
tcg_temp_free_i64(tmp2); tcg_temp_free_i64(tmp2);
tcg_temp_free_i32(tmp32); tcg_temp_free_i32(tmp32);
tcg_temp_free_i64(tmp);
break; break;
case 0x5: /* NIHL R1,I2 [RI] */ case 0x5: /* NIHL R1,I2 [RI] */
case 0x9: /* OIHL R1,I2 [RI] */ case 0x9: /* OIHL R1,I2 [RI] */
@ -2391,6 +2400,7 @@ static void disas_a5(DisasContext *s, int op, int r1, int i2)
set_cc_nz_u32(s, tmp32); set_cc_nz_u32(s, tmp32);
tcg_temp_free_i64(tmp2); tcg_temp_free_i64(tmp2);
tcg_temp_free_i32(tmp32); tcg_temp_free_i32(tmp32);
tcg_temp_free_i64(tmp);
break; break;
case 0x6: /* NILH R1,I2 [RI] */ case 0x6: /* NILH R1,I2 [RI] */
case 0xa: /* OILH R1,I2 [RI] */ case 0xa: /* OILH R1,I2 [RI] */
@ -2416,6 +2426,7 @@ static void disas_a5(DisasContext *s, int op, int r1, int i2)
set_cc_nz_u32(s, tmp32); set_cc_nz_u32(s, tmp32);
tcg_temp_free_i64(tmp2); tcg_temp_free_i64(tmp2);
tcg_temp_free_i32(tmp32); tcg_temp_free_i32(tmp32);
tcg_temp_free_i64(tmp);
break; break;
case 0x7: /* NILL R1,I2 [RI] */ case 0x7: /* NILL R1,I2 [RI] */
case 0xb: /* OILL R1,I2 [RI] */ case 0xb: /* OILL R1,I2 [RI] */
@ -2439,29 +2450,33 @@ static void disas_a5(DisasContext *s, int op, int r1, int i2)
set_cc_nz_u32(s, tmp32); /* signedness should not matter here */ set_cc_nz_u32(s, tmp32); /* signedness should not matter here */
tcg_temp_free_i64(tmp2); tcg_temp_free_i64(tmp2);
tcg_temp_free_i32(tmp32); tcg_temp_free_i32(tmp32);
tcg_temp_free_i64(tmp);
break; break;
case 0xc: /* LLIHH R1,I2 [RI] */ case 0xc: /* LLIHH R1,I2 [RI] */
tmp = tcg_const_i64( ((uint64_t)i2) << 48 ); tmp = tcg_const_i64( ((uint64_t)i2) << 48 );
store_reg(r1, tmp); store_reg(r1, tmp);
tcg_temp_free_i64(tmp);
break; break;
case 0xd: /* LLIHL R1,I2 [RI] */ case 0xd: /* LLIHL R1,I2 [RI] */
tmp = tcg_const_i64( ((uint64_t)i2) << 32 ); tmp = tcg_const_i64( ((uint64_t)i2) << 32 );
store_reg(r1, tmp); store_reg(r1, tmp);
tcg_temp_free_i64(tmp);
break; break;
case 0xe: /* LLILH R1,I2 [RI] */ case 0xe: /* LLILH R1,I2 [RI] */
tmp = tcg_const_i64( ((uint64_t)i2) << 16 ); tmp = tcg_const_i64( ((uint64_t)i2) << 16 );
store_reg(r1, tmp); store_reg(r1, tmp);
tcg_temp_free_i64(tmp);
break; break;
case 0xf: /* LLILL R1,I2 [RI] */ case 0xf: /* LLILL R1,I2 [RI] */
tmp = tcg_const_i64(i2); tmp = tcg_const_i64(i2);
store_reg(r1, tmp); store_reg(r1, tmp);
tcg_temp_free_i64(tmp);
break; break;
default: default:
LOG_DISAS("illegal a5 operation 0x%x\n", op); LOG_DISAS("illegal a5 operation 0x%x\n", op);
gen_illegal_opcode(s, 2); gen_illegal_opcode(s, 2);
return; return;
} }
tcg_temp_free_i64(tmp);
} }
static void disas_a7(DisasContext *s, int op, int r1, int i2) static void disas_a7(DisasContext *s, int op, int r1, int i2)
@ -2963,6 +2978,8 @@ static void disas_b2(DisasContext *s, int op, uint32_t insn)
/* we need to keep cc_op intact */ /* we need to keep cc_op intact */
s->is_jmp = DISAS_JUMP; s->is_jmp = DISAS_JUMP;
tcg_temp_free_i64(tmp); tcg_temp_free_i64(tmp);
tcg_temp_free_i64(tmp2);
tcg_temp_free_i64(tmp3);
break; break;
case 0x20: /* SERVC R1,R2 [RRE] */ case 0x20: /* SERVC R1,R2 [RRE] */
/* SCLP Service call (PV hypercall) */ /* SCLP Service call (PV hypercall) */
@ -3456,6 +3473,9 @@ static void disas_b9(DisasContext *s, int op, int r1, int r2)
tcg_temp_free_i64(tmp2); tcg_temp_free_i64(tmp2);
tcg_temp_free_i64(tmp3); tcg_temp_free_i64(tmp3);
break; break;
case 0x0f: /* LRVGR R1,R2 [RRE] */
tcg_gen_bswap64_i64(regs[r1], regs[r2]);
break;
case 0x1f: /* LRVR R1,R2 [RRE] */ case 0x1f: /* LRVR R1,R2 [RRE] */
tmp32_1 = load_reg32(r2); tmp32_1 = load_reg32(r2);
tcg_gen_bswap32_i32(tmp32_1, tmp32_1); tcg_gen_bswap32_i32(tmp32_1, tmp32_1);
@ -4593,6 +4613,8 @@ static void disas_s390_insn(DisasContext *s)
store_reg32(r1, tmp32_1); store_reg32(r1, tmp32_1);
tcg_gen_trunc_i64_i32(tmp32_2, tmp2); tcg_gen_trunc_i64_i32(tmp32_2, tmp2);
store_reg32(r1 + 1, tmp32_2); store_reg32(r1 + 1, tmp32_2);
tcg_temp_free_i64(tmp);
tcg_temp_free_i64(tmp2);
break; break;
case 0x98: /* LM R1,R3,D2(B2) [RS] */ case 0x98: /* LM R1,R3,D2(B2) [RS] */
case 0x90: /* STM R1,R3,D2(B2) [RS] */ case 0x90: /* STM R1,R3,D2(B2) [RS] */
@ -4616,6 +4638,7 @@ static void disas_s390_insn(DisasContext *s)
} }
tcg_gen_add_i64(tmp, tmp, tmp3); tcg_gen_add_i64(tmp, tmp, tmp3);
} }
tcg_temp_free_i64(tmp);
tcg_temp_free_i64(tmp2); tcg_temp_free_i64(tmp2);
tcg_temp_free_i64(tmp3); tcg_temp_free_i64(tmp3);
tcg_temp_free_i64(tmp4); tcg_temp_free_i64(tmp4);