On Wed, 30 Mar 2016 19:13:00 +0200 Laurent Vivier <lviv...@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 <lviv...@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 > -- David Gibson <dgib...@redhat.com> Senior Software Engineer, Virtualization, Red Hat
pgpySdH8sPsNG.pgp
Description: OpenPGP digital signature