]> git.proxmox.com Git - qemu.git/blobdiff - target-s390x/cc_helper.c
Merge remote-tracking branch 'kraxel/usb.82' into staging
[qemu.git] / target-s390x / cc_helper.c
index 575f7c3e757c0c35e88be17bc448eb28d5919f06..a6d60bf8851c22ab9a693f64930f4d36e630467c 100644 (file)
@@ -345,34 +345,64 @@ static uint32_t cc_calc_icm(uint64_t mask, uint64_t val)
     }
 }
 
-static uint32_t cc_calc_slag(uint64_t src, uint64_t shift)
+static uint32_t cc_calc_sla_32(uint32_t src, int shift)
 {
-    uint64_t mask = ((1ULL << shift) - 1ULL) << (64 - shift);
-    uint64_t match, r;
+    uint32_t mask = ((1U << shift) - 1U) << (32 - shift);
+    uint32_t sign = 1U << 31;
+    uint32_t match;
+    int32_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_sla_64(uint64_t src, int shift)
+{
+    uint64_t mask = ((1ULL << shift) - 1ULL) << (64 - shift);
+    uint64_t sign = 1ULL << 63;
+    uint64_t match;
+    int64_t r;
+
+    /* Check if the sign bit stays the same.  */
+    if (src & sign) {
+        match = mask;
+    } else {
+        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 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)
@@ -473,22 +503,25 @@ static uint32_t do_calc_cc(CPUS390XState *env, uint32_t cc_op,
     case CC_OP_ICM:
         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));
@@ -511,18 +544,6 @@ uint32_t HELPER(calc_cc)(CPUS390XState *env, uint32_t cc_op, uint64_t src,
     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)
 {