ARM TCG conversion 3/16.
authorpbrook <pbrook@c046a42c-6fe2-441c-8c8c-71466251a162>
Mon, 31 Mar 2008 03:45:35 +0000 (03:45 +0000)
committerpbrook <pbrook@c046a42c-6fe2-441c-8c8c-71466251a162>
Mon, 31 Mar 2008 03:45:35 +0000 (03:45 +0000)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4140 c046a42c-6fe2-441c-8c8c-71466251a162

target-arm/op.c
target-arm/translate.c

index bf535c8..b8b45e9 100644 (file)
@@ -317,55 +317,6 @@ void OPPROTO op_clrex(void)
     cpu_unlock();
 }
 
-/* shifts */
-
-/* T1 based, set C flag */
-void OPPROTO op_shll_T1_im_cc(void)
-{
-    env->CF = (T1 >> (32 - PARAM1)) & 1;
-    T1 = T1 << PARAM1;
-}
-
-void OPPROTO op_shrl_T1_im_cc(void)
-{
-    env->CF = (T1 >> (PARAM1 - 1)) & 1;
-    T1 = (uint32_t)T1 >> PARAM1;
-}
-
-void OPPROTO op_shrl_T1_0_cc(void)
-{
-    env->CF = (T1 >> 31) & 1;
-    T1 = 0;
-}
-
-void OPPROTO op_sarl_T1_im_cc(void)
-{
-    env->CF = (T1 >> (PARAM1 - 1)) & 1;
-    T1 = (int32_t)T1 >> PARAM1;
-}
-
-void OPPROTO op_sarl_T1_0_cc(void)
-{
-    env->CF = (T1 >> 31) & 1;
-    T1 = (int32_t)T1 >> 31;
-}
-
-void OPPROTO op_rorl_T1_im_cc(void)
-{
-    int shift;
-    shift = PARAM1;
-    env->CF = (T1 >> (shift - 1)) & 1;
-    T1 = ((uint32_t)T1 >> shift) | (T1 << (32 - shift));
-}
-
-void OPPROTO op_rrxl_T1_cc(void)
-{
-    uint32_t c;
-    c = T1 & 1;
-    T1 = ((uint32_t)T1 >> 1) | ((uint32_t)env->CF << 31);
-    env->CF = c;
-}
-
 /* T1 based, use T0 as shift count */
 
 void OPPROTO op_shll_T1_T0(void)
@@ -573,83 +524,6 @@ void OPPROTO op_subl_T0_T1_usaturate(void)
   FORCE_RET();
 }
 
-/* Thumb shift by immediate */
-void OPPROTO op_shll_T0_im_thumb_cc(void)
-{
-    int shift;
-    shift = PARAM1;
-    if (shift != 0) {
-       env->CF = (T0 >> (32 - shift)) & 1;
-       T0 = T0 << shift;
-    }
-    env->NZF = T0;
-    FORCE_RET();
-}
-
-void OPPROTO op_shll_T0_im_thumb(void)
-{
-    T0 = T0 << PARAM1;
-    FORCE_RET();
-}
-
-void OPPROTO op_shrl_T0_im_thumb_cc(void)
-{
-    int shift;
-
-    shift = PARAM1;
-    if (shift == 0) {
-       env->CF = ((uint32_t)T0) >> 31;
-       T0 = 0;
-    } else {
-       env->CF = (T0 >> (shift - 1)) & 1;
-       T0 = T0 >> shift;
-    }
-    env->NZF = T0;
-    FORCE_RET();
-}
-
-void OPPROTO op_shrl_T0_im_thumb(void)
-{
-    int shift;
-
-    shift = PARAM1;
-    if (shift == 0) {
-       T0 = 0;
-    } else {
-       T0 = T0 >> shift;
-    }
-    FORCE_RET();
-}
-
-void OPPROTO op_sarl_T0_im_thumb_cc(void)
-{
-    int shift;
-
-    shift = PARAM1;
-    if (shift == 0) {
-       T0 = ((int32_t)T0) >> 31;
-       env->CF = T0 & 1;
-    } else {
-       env->CF = (T0 >> (shift - 1)) & 1;
-       T0 = ((int32_t)T0) >> shift;
-    }
-    env->NZF = T0;
-    FORCE_RET();
-}
-
-void OPPROTO op_sarl_T0_im_thumb(void)
-{
-    int shift;
-
-    shift = PARAM1;
-    if (shift == 0) {
-       env->CF = T0 & 1;
-    } else {
-       T0 = ((int32_t)T0) >> shift;
-    }
-    FORCE_RET();
-}
-
 /* exceptions */
 
 void OPPROTO op_swi(void)
index 8669e94..bb6d513 100644 (file)
@@ -228,12 +228,14 @@ static void gen_add16(TCGv t0, TCGv t1)
     dead_tmp(t1);
 }
 
+#define gen_set_CF(var) tcg_gen_st_i32(var, cpu_env, offsetof(CPUState, CF))
+
 /* Set CF to the top bit of var.  */
 static void gen_set_CF_bit31(TCGv var)
 {
     TCGv tmp = new_tmp();
     tcg_gen_shri_i32(tmp, var, 31);
-    tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUState, CF));
+    gen_set_CF(var);
     dead_tmp(tmp);
 }
 
@@ -282,31 +284,67 @@ static void tcg_gen_rori_i32(TCGv t0, TCGv t1, int i)
     dead_tmp(tmp);
 }
 
-/* Shift by immediate.  Includes special handling for shift == 0.  */
-static inline void gen_arm_shift_im(TCGv var, int shiftop, int shift)
+static void shifter_out_im(TCGv var, int shift)
 {
-    if (shift != 0) {
-        switch (shiftop) {
-        case 0: tcg_gen_shli_i32(var, var, shift); break;
-        case 1: tcg_gen_shri_i32(var, var, shift); break;
-        case 2: tcg_gen_sari_i32(var, var, shift); break;
-        case 3: tcg_gen_rori_i32(var, var, shift); break;
-        }
+    TCGv tmp = new_tmp();
+    if (shift == 0) {
+        tcg_gen_andi_i32(tmp, var, 1);
     } else {
-        TCGv tmp;
+        tcg_gen_shri_i32(tmp, var, shift);
+        if (shift != 31);
+            tcg_gen_andi_i32(tmp, tmp, 1);
+    }
+    gen_set_CF(tmp);
+    dead_tmp(tmp);
+}
 
-        switch (shiftop) {
-        case 0: break;
-        case 1: tcg_gen_movi_i32(var, 0); break;
-        case 2: tcg_gen_sari_i32(var, var, 31); break;
-        case 3: /* rrx */
-            tcg_gen_shri_i32(var, var, 1);
-            tmp = new_tmp();
+/* Shift by immediate.  Includes special handling for shift == 0.  */
+static inline void gen_arm_shift_im(TCGv var, int shiftop, int shift, int flags)
+{
+    switch (shiftop) {
+    case 0: /* LSL */
+        if (shift != 0) {
+            if (flags)
+                shifter_out_im(var, 32 - shift);
+            tcg_gen_shli_i32(var, var, shift);
+        }
+        break;
+    case 1: /* LSR */
+        if (shift == 0) {
+            if (flags) {
+                tcg_gen_shri_i32(var, var, 31);
+                gen_set_CF(var);
+            }
+            tcg_gen_movi_i32(var, 0);
+        } else {
+            if (flags)
+                shifter_out_im(var, shift - 1);
+            tcg_gen_shri_i32(var, var, shift);
+        }
+        break;
+    case 2: /* ASR */
+        if (shift == 0)
+            shift = 32;
+        if (flags)
+            shifter_out_im(var, shift - 1);
+        if (shift == 32)
+          shift = 31;
+        tcg_gen_sari_i32(var, var, shift);
+        break;
+    case 3: /* ROR/RRX */
+        if (shift != 0) {
+            if (flags)
+                shifter_out_im(var, shift - 1);
+            tcg_gen_rori_i32(var, var, shift); break;
+        } else {
+            TCGv tmp = new_tmp();
             tcg_gen_ld_i32(tmp, cpu_env, offsetof(CPUState, CF));
+            if (flags)
+                shifter_out_im(var, 0);
+            tcg_gen_shri_i32(var, var, 1);
             tcg_gen_shli_i32(tmp, tmp, 31);
             tcg_gen_or_i32(var, var, tmp);
             dead_tmp(tmp);
-            break;
         }
     }
 };
@@ -392,20 +430,6 @@ const uint8_t table_logic_cc[16] = {
     1, /* mvn */
 };
 
-static GenOpFunc1 *gen_shift_T1_im_cc[4] = {
-    gen_op_shll_T1_im_cc,
-    gen_op_shrl_T1_im_cc,
-    gen_op_sarl_T1_im_cc,
-    gen_op_rorl_T1_im_cc,
-};
-
-static GenOpFunc *gen_shift_T1_0_cc[4] = {
-    NULL,
-    gen_op_shrl_T1_0_cc,
-    gen_op_sarl_T1_0_cc,
-    gen_op_rrxl_T1_cc,
-};
-
 static GenOpFunc *gen_shift_T1_T0[4] = {
     gen_op_shll_T1_T0,
     gen_op_shrl_T1_T0,
@@ -420,18 +444,6 @@ static GenOpFunc *gen_shift_T1_T0_cc[4] = {
     gen_op_rorl_T1_T0_cc,
 };
 
-static GenOpFunc1 *gen_shift_T0_im_thumb_cc[3] = {
-    gen_op_shll_T0_im_thumb_cc,
-    gen_op_shrl_T0_im_thumb_cc,
-    gen_op_sarl_T0_im_thumb_cc,
-};
-
-static GenOpFunc1 *gen_shift_T0_im_thumb[3] = {
-    gen_op_shll_T0_im_thumb,
-    gen_op_shrl_T0_im_thumb,
-    gen_op_sarl_T0_im_thumb,
-};
-
 /* Set PC and thumb state from T0.  Clobbers T0.  */
 static inline void gen_bx(DisasContext *s)
 {
@@ -530,7 +542,7 @@ static inline void gen_add_data_offset(DisasContext *s, unsigned int insn)
         shift = (insn >> 7) & 0x1f;
         shiftop = (insn >> 5) & 3;
         offset = load_reg(s, rm);
-        gen_arm_shift_im(offset, shiftop, shift);
+        gen_arm_shift_im(offset, shiftop, shift, 0);
         if (!(insn & (1 << 23)))
             tcg_gen_sub_i32(cpu_T[1], cpu_T[1], offset);
         else
@@ -5126,15 +5138,7 @@ static void disas_arm_insn(CPUState * env, DisasContext *s)
             shiftop = (insn >> 5) & 3;
             if (!(insn & (1 << 4))) {
                 shift = (insn >> 7) & 0x1f;
-                if (logic_cc) {
-                    if (shift != 0) {
-                        gen_shift_T1_im_cc[shiftop](shift);
-                    } else if (shiftop != 0) {
-                        gen_shift_T1_0_cc[shiftop]();
-                    }
-                } else {
-                    gen_arm_shift_im(cpu_T[1], shiftop, shift);
-                }
+                gen_arm_shift_im(cpu_T[1], shiftop, shift, logic_cc);
             } else {
                 rs = (insn >> 8) & 0xf;
                 gen_movl_T0_reg(s, rs);
@@ -6243,15 +6247,7 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1)
         shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
         conds = (insn & (1 << 20)) != 0;
         logic_cc = (conds && thumb2_logic_op(op));
-        if (logic_cc) {
-            if (shift != 0) {
-                gen_shift_T1_im_cc[shiftop](shift);
-            } else if (shiftop != 0) {
-                gen_shift_T1_0_cc[shiftop]();
-            }
-        } else {
-            gen_arm_shift_im(cpu_T[1], shiftop, shift);
-        }
+        gen_arm_shift_im(cpu_T[1], shiftop, shift, logic_cc);
         if (gen_thumb2_data_op(s, op, conds, 0))
             goto illegal_op;
         if (rd != 15)
@@ -6960,12 +6956,11 @@ static void disas_thumb_insn(CPUState *env, DisasContext *s)
             /* shift immediate */
             rm = (insn >> 3) & 7;
             shift = (insn >> 6) & 0x1f;
-            gen_movl_T0_reg(s, rm);
-            if (s->condexec_mask)
-                gen_shift_T0_im_thumb[op](shift);
-            else
-                gen_shift_T0_im_thumb_cc[op](shift);
-            gen_movl_reg_T0(s, rd);
+            tmp = load_reg(s, rm);
+            gen_arm_shift_im(tmp, op, shift, s->condexec_mask == 0);
+            if (!s->condexec_mask)
+                gen_logic_CC(tmp);
+            store_reg(s, rd, tmp);
         }
         break;
     case 2: case 3: