diff mbox series

[v2,02/23] target/i386: Return bool from disas_insn

Message ID 20220906100932.343523-3-richard.henderson@linaro.org
State Superseded
Headers show
Series target/i386: pc-relative translation blocks | expand

Commit Message

Richard Henderson Sept. 6, 2022, 10:09 a.m. UTC
Instead of returning the new pc, which is present in
DisasContext, return true if an insn was translated.
This is false when we detect a page crossing and must
undo the insn under translation.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/i386/tcg/translate.c | 42 +++++++++++++++++++------------------
 1 file changed, 22 insertions(+), 20 deletions(-)

Comments

Philippe Mathieu-Daudé Sept. 6, 2022, 2:42 p.m. UTC | #1
On 6/9/22 12:09, Richard Henderson wrote:
> Instead of returning the new pc, which is present in
> DisasContext, return true if an insn was translated.
> This is false when we detect a page crossing and must
> undo the insn under translation.
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>   target/i386/tcg/translate.c | 42 +++++++++++++++++++------------------
>   1 file changed, 22 insertions(+), 20 deletions(-)
> 
> diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
> index 1e24bb2985..46300ffd91 100644
> --- a/target/i386/tcg/translate.c
> +++ b/target/i386/tcg/translate.c
> @@ -4665,7 +4665,7 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b)
>   
>   /* convert one instruction. s->base.is_jmp is set if the translation must
>      be stopped. Return the next pc value */
> -static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
> +static bool disas_insn(DisasContext *s, CPUState *cpu)
>   {
>       CPUX86State *env = cpu->env_ptr;
>       int b, prefixes;
> @@ -4695,12 +4695,13 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
>           return s->pc;

Shouldn't we return 'true' here?

>       case 2:
>           /* Restore state that may affect the next instruction. */
> +        s->pc = s->base.pc_next;
>           s->cc_op_dirty = orig_cc_op_dirty;
>           s->cc_op = orig_cc_op;
>           s->base.num_insns--;
>           tcg_remove_ops_after(s->prev_insn_end);
>           s->base.is_jmp = DISAS_TOO_MANY;
> -        return s->base.pc_next;
> +        return false;
>       default:
>           g_assert_not_reached();
>       }
> @@ -8609,13 +8610,13 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
>       default:
>           goto unknown_op;
>       }
> -    return s->pc;
> +    return true;
>    illegal_op:
>       gen_illegal_opcode(s);
> -    return s->pc;
> +    return true;
>    unknown_op:
>       gen_unknown_opcode(env, s);
> -    return s->pc;
> +    return true;
>   }
Richard Henderson Sept. 8, 2022, 12:14 p.m. UTC | #2
On 9/6/22 15:42, Philippe Mathieu-Daudé wrote:
> On 6/9/22 12:09, Richard Henderson wrote:
>> Instead of returning the new pc, which is present in
>> DisasContext, return true if an insn was translated.
>> This is false when we detect a page crossing and must
>> undo the insn under translation.
>>
>> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
>> ---
>>   target/i386/tcg/translate.c | 42 +++++++++++++++++++------------------
>>   1 file changed, 22 insertions(+), 20 deletions(-)
>>
>> diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
>> index 1e24bb2985..46300ffd91 100644
>> --- a/target/i386/tcg/translate.c
>> +++ b/target/i386/tcg/translate.c
>> @@ -4665,7 +4665,7 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b)
>>   /* convert one instruction. s->base.is_jmp is set if the translation must
>>      be stopped. Return the next pc value */
>> -static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
>> +static bool disas_insn(DisasContext *s, CPUState *cpu)
>>   {
>>       CPUX86State *env = cpu->env_ptr;
>>       int b, prefixes;
>> @@ -4695,12 +4695,13 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
>>           return s->pc;
> 
> Shouldn't we return 'true' here?

Whoops, yes.


r~
Philippe Mathieu-Daudé Sept. 21, 2022, 5:51 p.m. UTC | #3
On 8/9/22 14:14, Richard Henderson wrote:
> On 9/6/22 15:42, Philippe Mathieu-Daudé wrote:
>> On 6/9/22 12:09, Richard Henderson wrote:
>>> Instead of returning the new pc, which is present in
>>> DisasContext, return true if an insn was translated.
>>> This is false when we detect a page crossing and must
>>> undo the insn under translation.
>>>
>>> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
>>> ---
>>>   target/i386/tcg/translate.c | 42 +++++++++++++++++++------------------
>>>   1 file changed, 22 insertions(+), 20 deletions(-)
>>>
>>> diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
>>> index 1e24bb2985..46300ffd91 100644
>>> --- a/target/i386/tcg/translate.c
>>> +++ b/target/i386/tcg/translate.c
>>> @@ -4665,7 +4665,7 @@ static void gen_sse(CPUX86State *env, 
>>> DisasContext *s, int b)
>>>   /* convert one instruction. s->base.is_jmp is set if the 
>>> translation must
>>>      be stopped. Return the next pc value */
>>> -static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
>>> +static bool disas_insn(DisasContext *s, CPUState *cpu)
>>>   {
>>>       CPUX86State *env = cpu->env_ptr;
>>>       int b, prefixes;
>>> @@ -4695,12 +4695,13 @@ static target_ulong disas_insn(DisasContext 
>>> *s, CPUState *cpu)
>>>           return s->pc;
>>
>> Shouldn't we return 'true' here?
> 
> Whoops, yes.

Returning 'true':

Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
diff mbox series

Patch

diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
index 1e24bb2985..46300ffd91 100644
--- a/target/i386/tcg/translate.c
+++ b/target/i386/tcg/translate.c
@@ -4665,7 +4665,7 @@  static void gen_sse(CPUX86State *env, DisasContext *s, int b)
 
 /* convert one instruction. s->base.is_jmp is set if the translation must
    be stopped. Return the next pc value */
-static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
+static bool disas_insn(DisasContext *s, CPUState *cpu)
 {
     CPUX86State *env = cpu->env_ptr;
     int b, prefixes;
@@ -4695,12 +4695,13 @@  static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         return s->pc;
     case 2:
         /* Restore state that may affect the next instruction. */
+        s->pc = s->base.pc_next;
         s->cc_op_dirty = orig_cc_op_dirty;
         s->cc_op = orig_cc_op;
         s->base.num_insns--;
         tcg_remove_ops_after(s->prev_insn_end);
         s->base.is_jmp = DISAS_TOO_MANY;
-        return s->base.pc_next;
+        return false;
     default:
         g_assert_not_reached();
     }
@@ -8609,13 +8610,13 @@  static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
     default:
         goto unknown_op;
     }
-    return s->pc;
+    return true;
  illegal_op:
     gen_illegal_opcode(s);
-    return s->pc;
+    return true;
  unknown_op:
     gen_unknown_opcode(env, s);
-    return s->pc;
+    return true;
 }
 
 void tcg_x86_init(void)
@@ -8780,7 +8781,6 @@  static void i386_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
 static void i386_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
 {
     DisasContext *dc = container_of(dcbase, DisasContext, base);
-    target_ulong pc_next;
 
 #ifdef TARGET_VSYSCALL_PAGE
     /*
@@ -8793,21 +8793,23 @@  static void i386_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
     }
 #endif
 
-    pc_next = disas_insn(dc, cpu);
-    dc->base.pc_next = pc_next;
+    if (disas_insn(dc, cpu)) {
+        target_ulong pc_next = dc->pc;
+        dc->base.pc_next = pc_next;
 
-    if (dc->base.is_jmp == DISAS_NEXT) {
-        if (dc->flags & (HF_TF_MASK | HF_INHIBIT_IRQ_MASK)) {
-            /*
-             * If single step mode, we generate only one instruction and
-             * generate an exception.
-             * If irq were inhibited with HF_INHIBIT_IRQ_MASK, we clear
-             * the flag and abort the translation to give the irqs a
-             * chance to happen.
-             */
-            dc->base.is_jmp = DISAS_TOO_MANY;
-        } else if (!is_same_page(&dc->base, pc_next)) {
-            dc->base.is_jmp = DISAS_TOO_MANY;
+        if (dc->base.is_jmp == DISAS_NEXT) {
+            if (dc->flags & (HF_TF_MASK | HF_INHIBIT_IRQ_MASK)) {
+                /*
+                 * If single step mode, we generate only one instruction and
+                 * generate an exception.
+                 * If irq were inhibited with HF_INHIBIT_IRQ_MASK, we clear
+                 * the flag and abort the translation to give the irqs a
+                 * chance to happen.
+                 */
+                dc->base.is_jmp = DISAS_TOO_MANY;
+            } else if (!is_same_page(&dc->base, pc_next)) {
+                dc->base.is_jmp = DISAS_TOO_MANY;
+            }
         }
     }
 }