qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH v2 1/2] target-i386/seg_helper: refactor 4 helper fu


From: liguang
Subject: [Qemu-devel] [PATCH v2 1/2] target-i386/seg_helper: refactor 4 helper functions
Date: Mon, 6 May 2013 13:55:06 +0800

for helper_{lsl, lar, verr, verw}, there are
common parts, so move them outside, and then
call this new helper-helper function.

Signed-off-by: liguang <address@hidden>
---
v2: change misc_check_helper to privilege_check
---
 target-i386/seg_helper.c |  179 ++++++++++++++-------------------------------
 1 files changed, 56 insertions(+), 123 deletions(-)

diff --git a/target-i386/seg_helper.c b/target-i386/seg_helper.c
index ff93374..eb9dc04 100644
--- a/target-i386/seg_helper.c
+++ b/target-i386/seg_helper.c
@@ -2288,9 +2288,10 @@ void helper_sysexit(CPUX86State *env, int dflag)
     EIP = EDX;
 }
 
-target_ulong helper_lsl(CPUX86State *env, target_ulong selector1)
+
+static target_ulong privilege_check(CPUX86State *env, target_ulong selector1,
+                                      int inst)
 {
-    unsigned int limit;
     uint32_t e1, e2, eflags, selector;
     int rpl, dpl, cpl, type;
 
@@ -2302,14 +2303,30 @@ target_ulong helper_lsl(CPUX86State *env, target_ulong 
selector1)
     if (load_segment(env, &e1, &e2, selector) != 0) {
         goto fail;
     }
+
+    CC_SRC = eflags & ~CC_Z;
+
     rpl = selector & 3;
     dpl = (e2 >> DESC_DPL_SHIFT) & 3;
     cpl = env->hflags & HF_CPL_MASK;
+
     if (e2 & DESC_S_MASK) {
-        if ((e2 & DESC_CS_MASK) && (e2 & DESC_C_MASK)) {
-            /* conforming */
-        } else {
-            if (dpl < cpl || dpl < rpl) {
+        if (e2 & DESC_CS_MASK) {
+            switch (inst) {
+            case 1:
+                goto fail;
+            case 2:
+                if (!(e2 & (DESC_R_MASK | DESC_C_MASK))) {
+                    goto fail;
+                }
+                break;
+            case 3:
+            case 4:
+                if (!(e2 & DESC_C_MASK)) {
+                    goto check_pl;
+                }
+                break;
+            default:
                 goto fail;
             }
         }
@@ -2321,140 +2338,56 @@ target_ulong helper_lsl(CPUX86State *env, target_ulong 
selector1)
         case 3:
         case 9:
         case 11:
-            break;
+            if (inst == 3) {
+                break;
+            }
+        case 5:
+        case 12:
+            if (inst == 4) {
+                break;
+            }
         default:
             goto fail;
         }
-        if (dpl < cpl || dpl < rpl) {
-        fail:
-            CC_SRC = eflags & ~CC_Z;
-            return 0;
-        }
+        goto check_pl;
+    }
+
+    if (inst == 3) {
+        e2 &= 0x00f0ff00;
     }
-    limit = get_seg_limit(e1, e2);
+    if (inst == 4) {
+        e2 = get_seg_limit(e1, e2);
+    }
+
     CC_SRC = eflags | CC_Z;
-    return limit;
+
+check_pl:
+    if (dpl < cpl || dpl < rpl) {
+        goto fail;
+    }
+
+fail:
+    return e2;
 }
 
-target_ulong helper_lar(CPUX86State *env, target_ulong selector1)
+target_ulong helper_lsl(CPUX86State *env, target_ulong selector1)
 {
-    uint32_t e1, e2, eflags, selector;
-    int rpl, dpl, cpl, type;
+    return privilege_check(env, selector1, 4);
+}
 
-    selector = selector1 & 0xffff;
-    eflags = cpu_cc_compute_all(env, CC_OP);
-    if ((selector & 0xfffc) == 0) {
-        goto fail;
-    }
-    if (load_segment(env, &e1, &e2, selector) != 0) {
-        goto fail;
-    }
-    rpl = selector & 3;
-    dpl = (e2 >> DESC_DPL_SHIFT) & 3;
-    cpl = env->hflags & HF_CPL_MASK;
-    if (e2 & DESC_S_MASK) {
-        if ((e2 & DESC_CS_MASK) && (e2 & DESC_C_MASK)) {
-            /* conforming */
-        } else {
-            if (dpl < cpl || dpl < rpl) {
-                goto fail;
-            }
-        }
-    } else {
-        type = (e2 >> DESC_TYPE_SHIFT) & 0xf;
-        switch (type) {
-        case 1:
-        case 2:
-        case 3:
-        case 4:
-        case 5:
-        case 9:
-        case 11:
-        case 12:
-            break;
-        default:
-            goto fail;
-        }
-        if (dpl < cpl || dpl < rpl) {
-        fail:
-            CC_SRC = eflags & ~CC_Z;
-            return 0;
-        }
-    }
-    CC_SRC = eflags | CC_Z;
-    return e2 & 0x00f0ff00;
+target_ulong helper_lar(CPUX86State *env, target_ulong selector1)
+{
+    return privilege_check(env, selector1, 3);
 }
 
 void helper_verr(CPUX86State *env, target_ulong selector1)
 {
-    uint32_t e1, e2, eflags, selector;
-    int rpl, dpl, cpl;
-
-    selector = selector1 & 0xffff;
-    eflags = cpu_cc_compute_all(env, CC_OP);
-    if ((selector & 0xfffc) == 0) {
-        goto fail;
-    }
-    if (load_segment(env, &e1, &e2, selector) != 0) {
-        goto fail;
-    }
-    if (!(e2 & DESC_S_MASK)) {
-        goto fail;
-    }
-    rpl = selector & 3;
-    dpl = (e2 >> DESC_DPL_SHIFT) & 3;
-    cpl = env->hflags & HF_CPL_MASK;
-    if (e2 & DESC_CS_MASK) {
-        if (!(e2 & DESC_R_MASK)) {
-            goto fail;
-        }
-        if (!(e2 & DESC_C_MASK)) {
-            if (dpl < cpl || dpl < rpl) {
-                goto fail;
-            }
-        }
-    } else {
-        if (dpl < cpl || dpl < rpl) {
-        fail:
-            CC_SRC = eflags & ~CC_Z;
-            return;
-        }
-    }
-    CC_SRC = eflags | CC_Z;
+    privilege_check(env, selector1, 2);
 }
 
 void helper_verw(CPUX86State *env, target_ulong selector1)
 {
-    uint32_t e1, e2, eflags, selector;
-    int rpl, dpl, cpl;
-
-    selector = selector1 & 0xffff;
-    eflags = cpu_cc_compute_all(env, CC_OP);
-    if ((selector & 0xfffc) == 0) {
-        goto fail;
-    }
-    if (load_segment(env, &e1, &e2, selector) != 0) {
-        goto fail;
-    }
-    if (!(e2 & DESC_S_MASK)) {
-        goto fail;
-    }
-    rpl = selector & 3;
-    dpl = (e2 >> DESC_DPL_SHIFT) & 3;
-    cpl = env->hflags & HF_CPL_MASK;
-    if (e2 & DESC_CS_MASK) {
-        goto fail;
-    } else {
-        if (dpl < cpl || dpl < rpl) {
-            goto fail;
-        }
-        if (!(e2 & DESC_W_MASK)) {
-        fail:
-            CC_SRC = eflags & ~CC_Z;
-            return;
-        }
-    }
-    CC_SRC = eflags | CC_Z;
+    privilege_check(env, selector1, 1);
 }
 
 #if defined(CONFIG_USER_ONLY)
-- 
1.7.2.5




reply via email to

[Prev in Thread] Current Thread [Next in Thread]