}
/* calculate condition code for insert character under mask insn */
-static uint32_t cc_calc_icm_32(uint32_t mask, uint32_t val)
+static uint32_t cc_calc_icm(uint64_t mask, uint64_t val)
{
- uint32_t cc;
-
- HELPER_LOG("%s: mask 0x%x val %d\n", __func__, mask, val);
- if (mask == 0xf) {
- if (!val) {
- return 0;
- } else if (val & 0x80000000) {
+ if ((val & mask) == 0) {
+ return 0;
+ } else {
+ int top = clz64(mask);
+ if ((int64_t)(val << top) < 0) {
return 1;
} else {
return 2;
}
}
+}
+
+static uint32_t cc_calc_sla_32(uint32_t src, int shift)
+{
+ uint32_t mask = ((1U << shift) - 1U) << (32 - shift);
+ uint32_t sign = 1U << 31;
+ uint32_t match;
+ int32_t r;
- if (!val || !mask) {
- cc = 0;
+ /* Check if the sign bit stays the same. */
+ if (src & sign) {
+ match = mask;
} else {
- while (mask != 1) {
- mask >>= 1;
- val >>= 8;
- }
- if (val & 0x80) {
- cc = 1;
- } else {
- cc = 2;
- }
+ match = 0;
+ }
+ if ((src & mask) != match) {
+ /* Overflow. */
+ return 3;
+ }
+
+ r = ((src << shift) & ~sign) | (src & sign);
+ if (r == 0) {
+ return 0;
+ } else if (r < 0) {
+ return 1;
}
- return cc;
+ return 2;
}
-static uint32_t cc_calc_slag(uint64_t src, uint64_t shift)
+static uint32_t cc_calc_sla_64(uint64_t src, int shift)
{
uint64_t mask = ((1ULL << shift) - 1ULL) << (64 - shift);
- uint64_t match, r;
+ uint64_t sign = 1ULL << 63;
+ uint64_t match;
+ int64_t r;
- /* check if the sign bit stays the same */
- if (src & (1ULL << 63)) {
+ /* Check if the sign bit stays the same. */
+ if (src & sign) {
match = mask;
} else {
match = 0;
}
-
if ((src & mask) != match) {
- /* overflow */
+ /* Overflow. */
return 3;
}
- r = ((src << shift) & ((1ULL << 63) - 1)) | (src & (1ULL << 63));
-
- if ((int64_t)r == 0) {
+ r = ((src << shift) & ~sign) | (src & sign);
+ if (r == 0) {
return 0;
- } else if ((int64_t)r < 0) {
+ } else if (r < 0) {
return 1;
}
-
return 2;
}
+static uint32_t cc_calc_flogr(uint64_t dst)
+{
+ return dst ? 2 : 0;
+}
static uint32_t do_calc_cc(CPUS390XState *env, uint32_t cc_op,
uint64_t src, uint64_t dst, uint64_t vr)
break;
case CC_OP_ICM:
- r = cc_calc_icm_32(src, dst);
+ r = cc_calc_icm(src, dst);
break;
- case CC_OP_SLAG:
- r = cc_calc_slag(src, dst);
+ case CC_OP_SLA_32:
+ r = cc_calc_sla_32(src, dst);
break;
-
- case CC_OP_LTGT_F32:
- r = set_cc_f32(env, src, dst);
+ case CC_OP_SLA_64:
+ r = cc_calc_sla_64(src, dst);
break;
- case CC_OP_LTGT_F64:
- r = set_cc_f64(env, src, dst);
+ case CC_OP_FLOGR:
+ r = cc_calc_flogr(dst);
break;
+
case CC_OP_NZ_F32:
r = set_cc_nz_f32(dst);
break;
case CC_OP_NZ_F64:
r = set_cc_nz_f64(dst);
break;
+ case CC_OP_NZ_F128:
+ r = set_cc_nz_f128(make_float128(src, dst));
+ break;
default:
cpu_abort(env, "Unknown CC operation: %s\n", cc_name(cc_op));
return do_calc_cc(env, cc_op, src, dst, vr);
}
-/* insert psw mask and condition code into r1 */
-void HELPER(ipm)(CPUS390XState *env, uint32_t cc, uint32_t r1)
-{
- uint64_t r = env->regs[r1];
-
- r &= 0xffffffff00ffffffULL;
- r |= (cc << 28) | ((env->psw.mask >> 40) & 0xf);
- env->regs[r1] = r;
- HELPER_LOG("%s: cc %d psw.mask 0x%lx r1 0x%lx\n", __func__,
- cc, env->psw.mask, r);
-}
-
#ifndef CONFIG_USER_ONLY
void HELPER(load_psw)(CPUS390XState *env, uint64_t mask, uint64_t addr)
{