diff mbox

target-ppc: Multiple/String Word alignment exception

Message ID 1459357980-29330-1-git-send-email-lvivier@redhat.com
State New
Headers show

Commit Message

Laurent Vivier March 30, 2016, 5:13 p.m. UTC
If the processor is in little-endian mode, an alignment interrupt must
occur for the following instructions: lmw, stmw, lswi, lswx, stswi or stswx.

This is what happens with KVM, so change TCG to do the same.

As the instruction can be emulated by the kernel, enable the change
only in softmmu mode.

Signed-off-by: Laurent Vivier <lvivier@redhat.com>
---
 target-ppc/translate.c | 42 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 42 insertions(+)

Comments

David Gibson March 30, 2016, 11:29 p.m. UTC | #1
On Wed, 30 Mar 2016 19:13:00 +0200
Laurent Vivier <lvivier@redhat.com> wrote:

> If the processor is in little-endian mode, an alignment interrupt must
> occur for the following instructions: lmw, stmw, lswi, lswx, stswi or stswx.
> 
> This is what happens with KVM, so change TCG to do the same.
> 
> As the instruction can be emulated by the kernel, enable the change
> only in softmmu mode.
> 
> Signed-off-by: Laurent Vivier <lvivier@redhat.com>

I guess this makes sense given the existing hardware behaviour, even
though it seems a bit perverse to me to make the emulator strictly less
functional.

Alex, what do you think?

Note that in time I expect we'll want some new flag to control this
behaviour.  Given the push towards LE, I think it's pretty likely that
future CPUs (maybe even POWER9) will allow these operations on LE
without exceptions.

I guess one question here is what does the architecture say about
this?  Does it say these operations will generate alignment exceptions
on LE, or just that they may (implementation dependent)?

> ---
>  target-ppc/translate.c | 42 ++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 42 insertions(+)
> 
> diff --git a/target-ppc/translate.c b/target-ppc/translate.c
> index 6f0e7b4..e33dcf7 100644
> --- a/target-ppc/translate.c
> +++ b/target-ppc/translate.c
> @@ -3181,6 +3181,13 @@ static void gen_lmw(DisasContext *ctx)
>  {
>      TCGv t0;
>      TCGv_i32 t1;
> +#if !defined(CONFIG_USER_ONLY)
> +    if (ctx->le_mode) {
> +        gen_exception_err(ctx, POWERPC_EXCP_ALIGN, POWERPC_EXCP_ALIGN_LE);
> +        return;
> +    }
> +#endif
> +
>      gen_set_access_type(ctx, ACCESS_INT);
>      /* NIP cannot be restored if the memory exception comes from an helper */
>      gen_update_nip(ctx, ctx->nip - 4);
> @@ -3197,6 +3204,13 @@ static void gen_stmw(DisasContext *ctx)
>  {
>      TCGv t0;
>      TCGv_i32 t1;
> +#if !defined(CONFIG_USER_ONLY)
> +    if (ctx->le_mode) {
> +        gen_exception_err(ctx, POWERPC_EXCP_ALIGN, POWERPC_EXCP_ALIGN_LE);
> +        return;
> +    }
> +#endif
> +
>      gen_set_access_type(ctx, ACCESS_INT);
>      /* NIP cannot be restored if the memory exception comes from an helper */
>      gen_update_nip(ctx, ctx->nip - 4);
> @@ -3224,6 +3238,13 @@ static void gen_lswi(DisasContext *ctx)
>      int start = rD(ctx->opcode);
>      int ra = rA(ctx->opcode);
>      int nr;
> +#if !defined(CONFIG_USER_ONLY)
> +    if (ctx->le_mode) {
> +        gen_exception_err(ctx, POWERPC_EXCP_ALIGN, POWERPC_EXCP_ALIGN_LE);
> +        return;
> +    }
> +#endif
> +
>  
>      if (nb == 0)
>          nb = 32;
> @@ -3252,6 +3273,13 @@ static void gen_lswx(DisasContext *ctx)
>  {
>      TCGv t0;
>      TCGv_i32 t1, t2, t3;
> +#if !defined(CONFIG_USER_ONLY)
> +    if (ctx->le_mode) {
> +        gen_exception_err(ctx, POWERPC_EXCP_ALIGN, POWERPC_EXCP_ALIGN_LE);
> +        return;
> +    }
> +#endif
> +
>      gen_set_access_type(ctx, ACCESS_INT);
>      /* NIP cannot be restored if the memory exception comes from an helper */
>      gen_update_nip(ctx, ctx->nip - 4);
> @@ -3273,6 +3301,13 @@ static void gen_stswi(DisasContext *ctx)
>      TCGv t0;
>      TCGv_i32 t1, t2;
>      int nb = NB(ctx->opcode);
> +#if !defined(CONFIG_USER_ONLY)
> +    if (ctx->le_mode) {
> +        gen_exception_err(ctx, POWERPC_EXCP_ALIGN, POWERPC_EXCP_ALIGN_LE);
> +        return;
> +    }
> +#endif
> +
>      gen_set_access_type(ctx, ACCESS_INT);
>      /* NIP cannot be restored if the memory exception comes from an helper */
>      gen_update_nip(ctx, ctx->nip - 4);
> @@ -3293,6 +3328,13 @@ static void gen_stswx(DisasContext *ctx)
>  {
>      TCGv t0;
>      TCGv_i32 t1, t2;
> +#if !defined(CONFIG_USER_ONLY)
> +    if (ctx->le_mode) {
> +        gen_exception_err(ctx, POWERPC_EXCP_ALIGN, POWERPC_EXCP_ALIGN_LE);
> +        return;
> +    }
> +#endif
> +
>      gen_set_access_type(ctx, ACCESS_INT);
>      /* NIP cannot be restored if the memory exception comes from an helper */
>      gen_update_nip(ctx, ctx->nip - 4);
> -- 
> 2.5.5
>
Laurent Vivier March 31, 2016, 12:53 a.m. UTC | #2
On 31/03/2016 01:29, David Gibson wrote:
> On Wed, 30 Mar 2016 19:13:00 +0200
> Laurent Vivier <lvivier@redhat.com> wrote:
> 
>> If the processor is in little-endian mode, an alignment interrupt must
>> occur for the following instructions: lmw, stmw, lswi, lswx, stswi or stswx.
>>
>> This is what happens with KVM, so change TCG to do the same.
>>
>> As the instruction can be emulated by the kernel, enable the change
>> only in softmmu mode.
>>
>> Signed-off-by: Laurent Vivier <lvivier@redhat.com>
> 
> I guess this makes sense given the existing hardware behaviour, even
> though it seems a bit perverse to me to make the emulator strictly less
> functional.
> 
> Alex, what do you think?
> 
> Note that in time I expect we'll want some new flag to control this
> behaviour.  Given the push towards LE, I think it's pretty likely that
> future CPUs (maybe even POWER9) will allow these operations on LE
> without exceptions.
> 
> I guess one question here is what does the architecture say about
> this?  Does it say these operations will generate alignment exceptions
> on LE, or just that they may (implementation dependent)?

"Power ISA Version 2.07

Book III-S

6.5.8 Alignment Interrupt

An Alignment interrupt occurs when no higher priority
exception exists and a data access cannot be per-
formed for any of the following reasons.
...
* The instruction is lmw, stmw, lswi, lswx, stswi, or
stswx, and the operand is in storage that is Write
Through Required or Caching Inhibited, or the
thread is in Little-Endian mode.
..."

And this is very similar in

"The PowerPC Architecture,
A specification for a new family of risc processors

Book III PowerPC Operating Environment Architecture

5.5.6 Alignment Interrupt

An Alignment interrupt occurs when no higher priority
exception exists and the implementation cannot perform a storage access
for one of the reasons listed below.

...
* The instruction is lmw, stmw, lswi, lswx, stswi, or
stswx, and the processor is in Little-Endian mode.
..."

And

"Power ISA version 3.0"

Chapter 3. Fixed-Point Facility
...
lswi
...
This instruction is not supported in Little-Endian mode.
If it is executed in Little-Endian mode, the system alignment
error handler is invoked.
...
Book III

6.5.8 Alignment Interrupt
...
An Alignment interrupt occurs when no higher priority
exception exists and an attempt is made to execute an
instruction in a manner that is required, by the instruction
description, to cause an Alignment interrupt. These
cases are as follows.
„* A Load/Store Multiple instruction that is executed
in Little-Endian mode
...
An Alignment interrupt may occur when no higher priority
exception exists and a data access cannot be performed
for any of the following reasons
..."

Laurent
Alexander Graf March 31, 2016, 6:54 a.m. UTC | #3
On 31.03.16 01:29, David Gibson wrote:
> On Wed, 30 Mar 2016 19:13:00 +0200
> Laurent Vivier <lvivier@redhat.com> wrote:
> 
>> If the processor is in little-endian mode, an alignment interrupt must
>> occur for the following instructions: lmw, stmw, lswi, lswx, stswi or stswx.
>>
>> This is what happens with KVM, so change TCG to do the same.
>>
>> As the instruction can be emulated by the kernel, enable the change
>> only in softmmu mode.
>>
>> Signed-off-by: Laurent Vivier <lvivier@redhat.com>
> 
> I guess this makes sense given the existing hardware behaviour, even
> though it seems a bit perverse to me to make the emulator strictly less
> functional.
> 
> Alex, what do you think?

In general we only implement strict checks if it breaks guests not to
have them. Are you aware of any such case?


Alex
Laurent Vivier March 31, 2016, 7:06 a.m. UTC | #4
On 31/03/2016 08:54, Alexander Graf wrote:
> 
> 
> On 31.03.16 01:29, David Gibson wrote:
>> On Wed, 30 Mar 2016 19:13:00 +0200
>> Laurent Vivier <lvivier@redhat.com> wrote:
>>
>>> If the processor is in little-endian mode, an alignment interrupt must
>>> occur for the following instructions: lmw, stmw, lswi, lswx, stswi or stswx.
>>>
>>> This is what happens with KVM, so change TCG to do the same.
>>>
>>> As the instruction can be emulated by the kernel, enable the change
>>> only in softmmu mode.
>>>
>>> Signed-off-by: Laurent Vivier <lvivier@redhat.com>
>>
>> I guess this makes sense given the existing hardware behaviour, even
>> though it seems a bit perverse to me to make the emulator strictly less
>> functional.
>>
>> Alex, what do you think?
> 
> In general we only implement strict checks if it breaks guests not to
> have them. Are you aware of any such case?

No, it does not break anything. The idea was to have the same behavior
with TCG as with a real CPU (or kvm). But if it is not the rule, we can
drop this patch.

Thanks,
Laurent
Alexander Graf March 31, 2016, 7:15 a.m. UTC | #5
On 31.03.16 09:06, Laurent Vivier wrote:
> 
> 
> On 31/03/2016 08:54, Alexander Graf wrote:
>>
>>
>> On 31.03.16 01:29, David Gibson wrote:
>>> On Wed, 30 Mar 2016 19:13:00 +0200
>>> Laurent Vivier <lvivier@redhat.com> wrote:
>>>
>>>> If the processor is in little-endian mode, an alignment interrupt must
>>>> occur for the following instructions: lmw, stmw, lswi, lswx, stswi or stswx.
>>>>
>>>> This is what happens with KVM, so change TCG to do the same.
>>>>
>>>> As the instruction can be emulated by the kernel, enable the change
>>>> only in softmmu mode.
>>>>
>>>> Signed-off-by: Laurent Vivier <lvivier@redhat.com>
>>>
>>> I guess this makes sense given the existing hardware behaviour, even
>>> though it seems a bit perverse to me to make the emulator strictly less
>>> functional.
>>>
>>> Alex, what do you think?
>>
>> In general we only implement strict checks if it breaks guests not to
>> have them. Are you aware of any such case?
> 
> No, it does not break anything. The idea was to have the same behavior
> with TCG as with a real CPU (or kvm). But if it is not the rule, we can
> drop this patch.

I guess if you really care about same behavior, we'd need to have risu
ported to ppc. However, that's a huge can of worms. Once we start that,
we'd have to verify risu against every single CPU type we support
because they all interpret certain corner cases differently.

That's basically what David was trying to say with POWER9. How do you
know that POWER9 still requires strong alignment checks for indexed LE
instructions? If it doesn't, we'd have to add a case in TCG to not the
the checks again. These multiply very quickly :).


Alex
Laurent Vivier March 31, 2016, 7:39 a.m. UTC | #6
On 31/03/2016 09:15, Alexander Graf wrote:
> 
> 
> On 31.03.16 09:06, Laurent Vivier wrote:
>>
>>
>> On 31/03/2016 08:54, Alexander Graf wrote:
>>>
>>>
>>> On 31.03.16 01:29, David Gibson wrote:
>>>> On Wed, 30 Mar 2016 19:13:00 +0200
>>>> Laurent Vivier <lvivier@redhat.com> wrote:
>>>>
>>>>> If the processor is in little-endian mode, an alignment interrupt must
>>>>> occur for the following instructions: lmw, stmw, lswi, lswx, stswi or stswx.
>>>>>
>>>>> This is what happens with KVM, so change TCG to do the same.
>>>>>
>>>>> As the instruction can be emulated by the kernel, enable the change
>>>>> only in softmmu mode.
>>>>>
>>>>> Signed-off-by: Laurent Vivier <lvivier@redhat.com>
>>>>
>>>> I guess this makes sense given the existing hardware behaviour, even
>>>> though it seems a bit perverse to me to make the emulator strictly less
>>>> functional.
>>>>
>>>> Alex, what do you think?
>>>
>>> In general we only implement strict checks if it breaks guests not to
>>> have them. Are you aware of any such case?
>>
>> No, it does not break anything. The idea was to have the same behavior
>> with TCG as with a real CPU (or kvm). But if it is not the rule, we can
>> drop this patch.
> 
> I guess if you really care about same behavior, we'd need to have risu
> ported to ppc. However, that's a huge can of worms. Once we start that,
> we'd have to verify risu against every single CPU type we support
> because they all interpret certain corner cases differently.

I didn't know risu: it seems to be a wonderful tool!
> 
> That's basically what David was trying to say with POWER9. How do you
> know that POWER9 still requires strong alignment checks for indexed LE
> instructions? If it doesn't, we'd have to add a case in TCG to not the
> the checks again. These multiply very quickly :).

I understand. So just forget this patch :)

Thanks,
Laurent
Thomas Huth March 31, 2016, 8:50 a.m. UTC | #7
On 31.03.2016 09:15, Alexander Graf wrote:
> 
> On 31.03.16 09:06, Laurent Vivier wrote:
>>
>> On 31/03/2016 08:54, Alexander Graf wrote:
>>>
>>> On 31.03.16 01:29, David Gibson wrote:
>>>> On Wed, 30 Mar 2016 19:13:00 +0200
>>>> Laurent Vivier <lvivier@redhat.com> wrote:
>>>>
>>>>> If the processor is in little-endian mode, an alignment interrupt must
>>>>> occur for the following instructions: lmw, stmw, lswi, lswx, stswi or stswx.
>>>>>
>>>>> This is what happens with KVM, so change TCG to do the same.
>>>>>
>>>>> As the instruction can be emulated by the kernel, enable the change
>>>>> only in softmmu mode.
>>>>>
>>>>> Signed-off-by: Laurent Vivier <lvivier@redhat.com>
>>>>
>>>> I guess this makes sense given the existing hardware behaviour, even
>>>> though it seems a bit perverse to me to make the emulator strictly less
>>>> functional.
>>>>
>>>> Alex, what do you think?
>>>
>>> In general we only implement strict checks if it breaks guests not to
>>> have them. Are you aware of any such case?

Well, the new "emulator" test for kvm-unit-tests only works right if
this is done correctly ;-)

> That's basically what David was trying to say with POWER9. How do you
> know that POWER9 still requires strong alignment checks for indexed LE
> instructions? If it doesn't, we'd have to add a case in TCG to not the
> the checks again. These multiply very quickly :).

I'd agree with you in case something is not properly defined in the ISA
or marked as implementation specific. But in this case, this behavior is
properly documented in the PowerISA spec. IMHO, if something is
documented in the ISA, we should follow that behavior in QEMU, too, i.e.
add the alignment checks here. And if POWER9 is different, there must be
a new version of the PowerISA for this one day ... i.e. we have to make
adaptions for that anyway.

 Thomas
Alexander Graf March 31, 2016, 9:03 a.m. UTC | #8
On 03/31/2016 10:50 AM, Thomas Huth wrote:
> On 31.03.2016 09:15, Alexander Graf wrote:
>> On 31.03.16 09:06, Laurent Vivier wrote:
>>> On 31/03/2016 08:54, Alexander Graf wrote:
>>>> On 31.03.16 01:29, David Gibson wrote:
>>>>> On Wed, 30 Mar 2016 19:13:00 +0200
>>>>> Laurent Vivier <lvivier@redhat.com> wrote:
>>>>>
>>>>>> If the processor is in little-endian mode, an alignment interrupt must
>>>>>> occur for the following instructions: lmw, stmw, lswi, lswx, stswi or stswx.
>>>>>>
>>>>>> This is what happens with KVM, so change TCG to do the same.
>>>>>>
>>>>>> As the instruction can be emulated by the kernel, enable the change
>>>>>> only in softmmu mode.
>>>>>>
>>>>>> Signed-off-by: Laurent Vivier <lvivier@redhat.com>
>>>>> I guess this makes sense given the existing hardware behaviour, even
>>>>> though it seems a bit perverse to me to make the emulator strictly less
>>>>> functional.
>>>>>
>>>>> Alex, what do you think?
>>>> In general we only implement strict checks if it breaks guests not to
>>>> have them. Are you aware of any such case?
> Well, the new "emulator" test for kvm-unit-tests only works right if
> this is done correctly ;-)
>
>> That's basically what David was trying to say with POWER9. How do you
>> know that POWER9 still requires strong alignment checks for indexed LE
>> instructions? If it doesn't, we'd have to add a case in TCG to not the
>> the checks again. These multiply very quickly :).
> I'd agree with you in case something is not properly defined in the ISA
> or marked as implementation specific. But in this case, this behavior is
> properly documented in the PowerISA spec. IMHO, if something is
> documented in the ISA, we should follow that behavior in QEMU, too, i.e.

It's not even necessarily about documented or not. It's about 
differences in different PowerISA versions :).

> add the alignment checks here. And if POWER9 is different, there must be
> a new version of the PowerISA for this one day ... i.e. we have to make
> adaptions for that anyway.

Yup, and the less we have to adapt the happier everyone is.

But if it makes the emulator test work, I'm fine with it. Again, safety 
checks should have a real world impact.


Alex
Thomas Huth March 31, 2016, 9:18 a.m. UTC | #9
On 31.03.2016 11:03, Alexander Graf wrote:
> On 03/31/2016 10:50 AM, Thomas Huth wrote:
>> On 31.03.2016 09:15, Alexander Graf wrote:
>>> On 31.03.16 09:06, Laurent Vivier wrote:
>>>> On 31/03/2016 08:54, Alexander Graf wrote:
>>>>> On 31.03.16 01:29, David Gibson wrote:
>>>>>> On Wed, 30 Mar 2016 19:13:00 +0200
>>>>>> Laurent Vivier <lvivier@redhat.com> wrote:
>>>>>>
>>>>>>> If the processor is in little-endian mode, an alignment interrupt
>>>>>>> must
>>>>>>> occur for the following instructions: lmw, stmw, lswi, lswx,
>>>>>>> stswi or stswx.
>>>>>>>
>>>>>>> This is what happens with KVM, so change TCG to do the same.
>>>>>>>
>>>>>>> As the instruction can be emulated by the kernel, enable the change
>>>>>>> only in softmmu mode.
>>>>>>>
>>>>>>> Signed-off-by: Laurent Vivier <lvivier@redhat.com>
>>>>>> I guess this makes sense given the existing hardware behaviour, even
>>>>>> though it seems a bit perverse to me to make the emulator strictly
>>>>>> less
>>>>>> functional.
>>>>>>
>>>>>> Alex, what do you think?
>>>>> In general we only implement strict checks if it breaks guests not to
>>>>> have them. Are you aware of any such case?
>> Well, the new "emulator" test for kvm-unit-tests only works right if
>> this is done correctly ;-)
>>
>>> That's basically what David was trying to say with POWER9. How do you
>>> know that POWER9 still requires strong alignment checks for indexed LE
>>> instructions? If it doesn't, we'd have to add a case in TCG to not the
>>> the checks again. These multiply very quickly :).
>> I'd agree with you in case something is not properly defined in the ISA
>> or marked as implementation specific. But in this case, this behavior is
>> properly documented in the PowerISA spec. IMHO, if something is
>> documented in the ISA, we should follow that behavior in QEMU, too, i.e.
> 
> It's not even necessarily about documented or not. It's about
> differences in different PowerISA versions :).

As Laurent already mentioned it in another mail, it's defined like this
in pretty much all of the ISAs - at least from 2.01 to 2.07 as far as I
can see, too. (I don't have an older version of the PowerISA than 2.01).
I just checked also the "User Manuals" of the PPC 601, the PPC 603, and
the MPC750, and they also specify that these instructions cause an
alignment exception in little endian mode, so I think this really should
occur pretty much with every PPC chip that can run in little endian mode.

 Thomas
diff mbox

Patch

diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index 6f0e7b4..e33dcf7 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -3181,6 +3181,13 @@  static void gen_lmw(DisasContext *ctx)
 {
     TCGv t0;
     TCGv_i32 t1;
+#if !defined(CONFIG_USER_ONLY)
+    if (ctx->le_mode) {
+        gen_exception_err(ctx, POWERPC_EXCP_ALIGN, POWERPC_EXCP_ALIGN_LE);
+        return;
+    }
+#endif
+
     gen_set_access_type(ctx, ACCESS_INT);
     /* NIP cannot be restored if the memory exception comes from an helper */
     gen_update_nip(ctx, ctx->nip - 4);
@@ -3197,6 +3204,13 @@  static void gen_stmw(DisasContext *ctx)
 {
     TCGv t0;
     TCGv_i32 t1;
+#if !defined(CONFIG_USER_ONLY)
+    if (ctx->le_mode) {
+        gen_exception_err(ctx, POWERPC_EXCP_ALIGN, POWERPC_EXCP_ALIGN_LE);
+        return;
+    }
+#endif
+
     gen_set_access_type(ctx, ACCESS_INT);
     /* NIP cannot be restored if the memory exception comes from an helper */
     gen_update_nip(ctx, ctx->nip - 4);
@@ -3224,6 +3238,13 @@  static void gen_lswi(DisasContext *ctx)
     int start = rD(ctx->opcode);
     int ra = rA(ctx->opcode);
     int nr;
+#if !defined(CONFIG_USER_ONLY)
+    if (ctx->le_mode) {
+        gen_exception_err(ctx, POWERPC_EXCP_ALIGN, POWERPC_EXCP_ALIGN_LE);
+        return;
+    }
+#endif
+
 
     if (nb == 0)
         nb = 32;
@@ -3252,6 +3273,13 @@  static void gen_lswx(DisasContext *ctx)
 {
     TCGv t0;
     TCGv_i32 t1, t2, t3;
+#if !defined(CONFIG_USER_ONLY)
+    if (ctx->le_mode) {
+        gen_exception_err(ctx, POWERPC_EXCP_ALIGN, POWERPC_EXCP_ALIGN_LE);
+        return;
+    }
+#endif
+
     gen_set_access_type(ctx, ACCESS_INT);
     /* NIP cannot be restored if the memory exception comes from an helper */
     gen_update_nip(ctx, ctx->nip - 4);
@@ -3273,6 +3301,13 @@  static void gen_stswi(DisasContext *ctx)
     TCGv t0;
     TCGv_i32 t1, t2;
     int nb = NB(ctx->opcode);
+#if !defined(CONFIG_USER_ONLY)
+    if (ctx->le_mode) {
+        gen_exception_err(ctx, POWERPC_EXCP_ALIGN, POWERPC_EXCP_ALIGN_LE);
+        return;
+    }
+#endif
+
     gen_set_access_type(ctx, ACCESS_INT);
     /* NIP cannot be restored if the memory exception comes from an helper */
     gen_update_nip(ctx, ctx->nip - 4);
@@ -3293,6 +3328,13 @@  static void gen_stswx(DisasContext *ctx)
 {
     TCGv t0;
     TCGv_i32 t1, t2;
+#if !defined(CONFIG_USER_ONLY)
+    if (ctx->le_mode) {
+        gen_exception_err(ctx, POWERPC_EXCP_ALIGN, POWERPC_EXCP_ALIGN_LE);
+        return;
+    }
+#endif
+
     gen_set_access_type(ctx, ACCESS_INT);
     /* NIP cannot be restored if the memory exception comes from an helper */
     gen_update_nip(ctx, ctx->nip - 4);