From: Aurelien Jarno <aurelien@aurel32.net>
To: Jia Liu <proljc@gmail.com>
Cc: Peter Maydell <peter.maydell@linaro.org>,
"Jovanovic, Petar" <petarj@mips.com>,
"qemu-devel@nongnu.org" <qemu-devel@nongnu.org>,
Richard Henderson <rth@twiddle.net>
Subject: Re: [Qemu-devel] [PATCH v12 09/14] target-mips: Add ASE DSP bit/manipulation instructions
Date: Wed, 31 Oct 2012 20:20:49 +0100 [thread overview]
Message-ID: <20121031192049.GA7669@ohm.aurel32.net> (raw)
In-Reply-To: <CAJBMM-t7Bhr1VBF0a96_bF9Ue3bZ7+runDJ7xTmNWgdti6vRJA@mail.gmail.com>
On Wed, Oct 31, 2012 at 09:29:30PM +0800, Jia Liu wrote:
> Hi Richard Peter Jovanovic and Aurelien,
>
> On Wed, Oct 31, 2012 at 1:26 PM, Richard Henderson <rth@twiddle.net> wrote:
> > On 2012-10-31 01:44, Peter Maydell wrote:
> >> On 30 October 2012 15:34, Jia Liu <proljc@gmail.com> wrote:
> >>> On Mon, Oct 29, 2012 at 9:40 PM, Jovanovic, Petar <petarj@mips.com> wrote:
> >>>>> imm = (int16_t)(imm << 6) >> 6;
> >>>>
> >>>> result of a bitwise shift of a signed type and a negative vlaue is
> >>>> implementation-defined, so you can not rely on that.
> >>>>
> >>>
> >>> I think it will take a 10bits signed value sign extend into 16bits
> >>> signed value, and I've tested it with negative values, it working
> >>> well.
> >>
> >> You cannot rely on the behaviour of a specific compiler implementation
> >> as evidence that a piece of code is correct. C has a standard which
> >> defines what is and is not valid.
> >
> > Indeed. The only portable way is
> >
> > val = ((val & (sign | (sign - 1))) ^ sign) - sign
> >
> > with all unsigned types, and "sign" set to the sign bit.
> >
>
> Thank you very much for the code.
>
> Is this time OK?
As said by Peter, I don't think the code should be modified, the
previous code was fine.
> static void gen_mipsdsp_bitinsn(CPUMIPSState *env, DisasContext *ctx,
> uint32_t op1, uint32_t op2,
> int ret, int val)
> {
> const char *opn = "mipsdsp Bit/ Manipulation";
> TCGv t0;
> TCGv val_t;
>
> if (ret == 0) {
> /* Treat as NOP. */
> MIPS_DEBUG("NOP");
> return;
> }
>
> t0 = tcg_temp_new();
> val_t = tcg_temp_new();
> gen_load_gpr(val_t, val);
>
> #define SIGN_EXTEND10_16(val, sign) \
> val = (((val & (sign | (sign - 1))) ^ sign) - sign)
>
> switch (op1) {
> case OPC_ABSQ_S_PH_DSP:
> switch (op2) {
> case OPC_BITREV:
> check_dsp(ctx);
> gen_helper_bitrev(cpu_gpr[ret], val_t);
> break;
> case OPC_REPL_QB:
> check_dsp(ctx);
> {
> uint32_t imm;
> target_long result;
>
> imm = (ctx->opcode >> 16) & 0xFF;
> result = imm << 24 | imm << 16 | imm << 8 | imm;
> result = (int32_t)result;
> tcg_gen_movi_tl(cpu_gpr[ret], result);
> }
> break;
> case OPC_REPLV_QB:
> check_dsp(ctx);
> tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
> tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
> tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
> tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
> tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
> tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
> break;
> case OPC_REPL_PH:
> check_dsp(ctx);
> {
> uint16_t imm;
> imm = (ctx->opcode >> 16) & 0x03FF;
> SIGN_EXTEND10_16(imm, 0x200);
> tcg_gen_movi_tl(cpu_gpr[ret],
> (target_long)(int32_t)
> ((uint32_t)imm << 16 | imm));
> }
> break;
> case OPC_REPLV_PH:
> check_dsp(ctx);
> tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
> tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
> tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
> tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
> break;
> }
> break;
> #ifdef TARGET_MIPS64
> case OPC_ABSQ_S_QH_DSP:
> switch (op2) {
> case OPC_REPL_OB:
> check_dsp(ctx);
> {
> target_ulong imm;
>
> imm = (ctx->opcode >> 16) & 0xFF;
> imm = (imm << 8) | imm;
> imm = (imm << 16) | imm;
> imm = (imm << 32) | imm;
> tcg_gen_movi_tl(cpu_gpr[ret], imm);
> break;
> }
> case OPC_REPL_PW:
> check_dsp(ctx);
> {
> target_long imm;
>
> imm = (ctx->opcode >> 16) & 0x03FF;
> SIGN_EXTEND10_16(imm, 0x200);
> tcg_gen_movi_tl(cpu_gpr[ret],
> (imm << 32) | (imm & 0xFFFFFFFF));
> break;
> }
> case OPC_REPL_QH:
> check_dsp(ctx);
> {
> target_ulong imm;
>
> imm = (ctx->opcode >> 16) & 0x03FF;
> SIGN_EXTEND10_16(imm, 0x200);
>
> imm = imm & 0xFFFF;
> imm = (imm << 48) | (imm << 32) | (imm << 16) | imm;
> tcg_gen_movi_tl(cpu_gpr[ret], imm);
> break;
> }
> case OPC_REPLV_OB:
> check_dsp(ctx);
> tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
> tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
> tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
> tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
> tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
> tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
> tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
> break;
> case OPC_REPLV_PW:
> check_dsp(ctx);
> tcg_gen_ext32u_i64(cpu_gpr[ret], val_t);
> tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
> tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
> break;
> case OPC_REPLV_QH:
> check_dsp(ctx);
> tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
> tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
> tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
> tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
> tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
> break;
> }
> break;
> #endif
> }
>
> #undef SIGN_EXTEND10_16
> tcg_temp_free(t0);
> tcg_temp_free(val_t);
>
> (void)opn; /* avoid a compiler warning */
> MIPS_DEBUG("%s", opn);
> }
>
>
> >>
> >> Having said that, right shift of negative signed integers is one of
> >> those bits of implementation defined behaviour which we allow ourselves
> >> to rely on in QEMU because all the platforms we care about behave
> >> that way. (That integers are 2s complement representation is another.)
> >
> > Also very true. I don't like seeing the code in question though.
> > We've several implementations of sign-extend-to-N-bits functions
> > throughout qemu; we ought to unify them.
> >
> >
> > r~
>
> Regards,
> Jia.
>
>
--
Aurelien Jarno GPG: 1024D/F1BCDB73
aurelien@aurel32.net http://www.aurel32.net
next prev parent reply other threads:[~2012-10-31 19:21 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-10-27 22:58 [Qemu-devel] [PATCH v12 09/14] target-mips: Add ASE DSP bit/manipulation instructions Jovanovic, Petar
2012-10-29 12:36 ` Jia Liu
2012-10-29 13:40 ` Jovanovic, Petar
2012-10-30 14:34 ` Jia Liu
2012-10-30 14:44 ` Peter Maydell
2012-10-31 5:26 ` Richard Henderson
2012-10-31 13:29 ` Jia Liu
2012-10-31 19:20 ` Aurelien Jarno [this message]
2012-11-01 0:34 ` Jia Liu
2012-11-06 3:50 ` Jovanovic, Petar
2012-11-06 7:40 ` Aurelien Jarno
2012-10-30 14:51 ` Peter Maydell
-- strict thread matches above, loose matches on Subject: below --
2012-10-24 14:17 [Qemu-devel] [PATCH v12 00/14] QEMU MIPS ASE DSP support Jia Liu
2012-10-24 14:17 ` [Qemu-devel] [PATCH v12 09/14] target-mips: Add ASE DSP bit/manipulation instructions Jia Liu
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20121031192049.GA7669@ohm.aurel32.net \
--to=aurelien@aurel32.net \
--cc=petarj@mips.com \
--cc=peter.maydell@linaro.org \
--cc=proljc@gmail.com \
--cc=qemu-devel@nongnu.org \
--cc=rth@twiddle.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.