From: Aurelien Jarno <aurelien@aurel32.net>
To: Richard Henderson <rth@twiddle.net>
Cc: qemu-devel@nongnu.org
Subject: Re: [Qemu-devel] [PATCH 3/5] tcg-i386: Implement small forward branches.
Date: Sun, 20 Dec 2009 00:11:27 +0100 [thread overview]
Message-ID: <20091219231127.GA355@volta.aurel32.net> (raw)
In-Reply-To: <9f38711e7d93ded68cad15e5cdbeecbf2c9ae521.1261248772.git.rth@twiddle.net>
On Sat, Dec 19, 2009 at 10:44:11AM -0800, Richard Henderson wrote:
> There are places, like brcond2, where we know that the destination
> of a forward branch will be within 127 bytes.
>
> Add the R_386_PC8 relocation type to support this. Add a flag to
> tcg_out_jxx and tcg_out_brcond* to enable it. Set the flag in the
> brcond2 label_next branches; pass along the input flag otherwise.
This looks ok, though I would appreciate someone else to review it in
details.
> Signed-off-by: Richard Henderson <rth@twiddle.net>
> ---
> elf.h | 2 +
> tcg/i386/tcg-target.c | 116 +++++++++++++++++++++++++++++++++----------------
> 2 files changed, 80 insertions(+), 38 deletions(-)
>
> diff --git a/elf.h b/elf.h
> index 11674d7..c84c8ab 100644
> --- a/elf.h
> +++ b/elf.h
> @@ -243,6 +243,8 @@ typedef struct {
> #define R_386_GOTOFF 9
> #define R_386_GOTPC 10
> #define R_386_NUM 11
> +/* Not a dynamic reloc, so not included in R_386_NUM. Used in TCG. */
> +#define R_386_PC8 23
>
> #define R_MIPS_NONE 0
> #define R_MIPS_16 1
> diff --git a/tcg/i386/tcg-target.c b/tcg/i386/tcg-target.c
> index 972b102..4c42caf 100644
> --- a/tcg/i386/tcg-target.c
> +++ b/tcg/i386/tcg-target.c
> @@ -61,6 +61,12 @@ static void patch_reloc(uint8_t *code_ptr, int type,
> case R_386_PC32:
> *(uint32_t *)code_ptr = value - (long)code_ptr;
> break;
> + case R_386_PC8:
> + value -= (long)code_ptr;
> + if (value != (int8_t)value)
> + tcg_abort();
> + *(uint8_t *)code_ptr = value;
> + break;
> default:
> tcg_abort();
> }
> @@ -305,7 +311,8 @@ static void tcg_out_addi(TCGContext *s, int reg, tcg_target_long val)
> tgen_arithi(s, ARITH_ADD, reg, val, 0);
> }
>
> -static void tcg_out_jxx(TCGContext *s, int opc, int label_index)
> +/* Use SMALL != 0 to force a short forward branch. */
> +static void tcg_out_jxx(TCGContext *s, int opc, int label_index, int small)
> {
> int32_t val, val1;
> TCGLabel *l = &s->labels[label_index];
> @@ -314,12 +321,16 @@ static void tcg_out_jxx(TCGContext *s, int opc, int label_index)
> val = l->u.value - (tcg_target_long)s->code_ptr;
> val1 = val - 2;
> if ((int8_t)val1 == val1) {
> - if (opc == -1)
> + if (opc == -1) {
> tcg_out8(s, 0xeb);
> - else
> + } else {
> tcg_out8(s, 0x70 + opc);
> + }
> tcg_out8(s, val1);
> } else {
> + if (small) {
> + tcg_abort();
> + }
> if (opc == -1) {
> tcg_out8(s, 0xe9);
> tcg_out32(s, val - 5);
> @@ -329,6 +340,14 @@ static void tcg_out_jxx(TCGContext *s, int opc, int label_index)
> tcg_out32(s, val - 6);
> }
> }
> + } else if (small) {
> + if (opc == -1) {
> + tcg_out8(s, 0xeb);
> + } else {
> + tcg_out8(s, 0x70 + opc);
> + }
> + tcg_out_reloc(s, s->code_ptr, R_386_PC8, label_index, -1);
> + s->code_ptr += 1;
> } else {
> if (opc == -1) {
> tcg_out8(s, 0xe9);
> @@ -343,7 +362,7 @@ static void tcg_out_jxx(TCGContext *s, int opc, int label_index)
>
> static void tcg_out_brcond(TCGContext *s, int cond,
> TCGArg arg1, TCGArg arg2, int const_arg2,
> - int label_index)
> + int label_index, int small)
> {
> if (const_arg2) {
> if (arg2 == 0) {
> @@ -355,64 +374,84 @@ static void tcg_out_brcond(TCGContext *s, int cond,
> } else {
> tcg_out_modrm(s, 0x01 | (ARITH_CMP << 3), arg2, arg1);
> }
> - tcg_out_jxx(s, tcg_cond_to_jcc[cond], label_index);
> + tcg_out_jxx(s, tcg_cond_to_jcc[cond], label_index, small);
> }
>
> /* XXX: we implement it at the target level to avoid having to
> handle cross basic blocks temporaries */
> -static void tcg_out_brcond2(TCGContext *s,
> - const TCGArg *args, const int *const_args)
> +static void tcg_out_brcond2(TCGContext *s, const TCGArg *args,
> + const int *const_args, int small)
> {
> int label_next;
> label_next = gen_new_label();
> switch(args[4]) {
> case TCG_COND_EQ:
> - tcg_out_brcond(s, TCG_COND_NE, args[0], args[2], const_args[2], label_next);
> - tcg_out_brcond(s, TCG_COND_EQ, args[1], args[3], const_args[3], args[5]);
> + tcg_out_brcond(s, TCG_COND_NE, args[0], args[2], const_args[2],
> + label_next, small);
> + tcg_out_brcond(s, TCG_COND_EQ, args[1], args[3], const_args[3],
> + args[5], small);
> break;
> case TCG_COND_NE:
> - tcg_out_brcond(s, TCG_COND_NE, args[0], args[2], const_args[2], args[5]);
> - tcg_out_brcond(s, TCG_COND_NE, args[1], args[3], const_args[3], args[5]);
> + tcg_out_brcond(s, TCG_COND_NE, args[0], args[2], const_args[2],
> + args[5], small);
> + tcg_out_brcond(s, TCG_COND_NE, args[1], args[3], const_args[3],
> + args[5], small);
> break;
> case TCG_COND_LT:
> - tcg_out_brcond(s, TCG_COND_LT, args[1], args[3], const_args[3], args[5]);
> - tcg_out_jxx(s, JCC_JNE, label_next);
> - tcg_out_brcond(s, TCG_COND_LTU, args[0], args[2], const_args[2], args[5]);
> + tcg_out_brcond(s, TCG_COND_LT, args[1], args[3], const_args[3],
> + args[5], small);
> + tcg_out_jxx(s, JCC_JNE, label_next, 1);
> + tcg_out_brcond(s, TCG_COND_LTU, args[0], args[2], const_args[2],
> + args[5], small);
> break;
> case TCG_COND_LE:
> - tcg_out_brcond(s, TCG_COND_LT, args[1], args[3], const_args[3], args[5]);
> - tcg_out_jxx(s, JCC_JNE, label_next);
> - tcg_out_brcond(s, TCG_COND_LEU, args[0], args[2], const_args[2], args[5]);
> + tcg_out_brcond(s, TCG_COND_LT, args[1], args[3], const_args[3],
> + args[5], small);
> + tcg_out_jxx(s, JCC_JNE, label_next, 1);
> + tcg_out_brcond(s, TCG_COND_LEU, args[0], args[2], const_args[2],
> + args[5], small);
> break;
> case TCG_COND_GT:
> - tcg_out_brcond(s, TCG_COND_GT, args[1], args[3], const_args[3], args[5]);
> - tcg_out_jxx(s, JCC_JNE, label_next);
> - tcg_out_brcond(s, TCG_COND_GTU, args[0], args[2], const_args[2], args[5]);
> + tcg_out_brcond(s, TCG_COND_GT, args[1], args[3], const_args[3],
> + args[5], small);
> + tcg_out_jxx(s, JCC_JNE, label_next, 1);
> + tcg_out_brcond(s, TCG_COND_GTU, args[0], args[2], const_args[2],
> + args[5], small);
> break;
> case TCG_COND_GE:
> - tcg_out_brcond(s, TCG_COND_GT, args[1], args[3], const_args[3], args[5]);
> - tcg_out_jxx(s, JCC_JNE, label_next);
> - tcg_out_brcond(s, TCG_COND_GEU, args[0], args[2], const_args[2], args[5]);
> + tcg_out_brcond(s, TCG_COND_GT, args[1], args[3], const_args[3],
> + args[5], small);
> + tcg_out_jxx(s, JCC_JNE, label_next, 1);
> + tcg_out_brcond(s, TCG_COND_GEU, args[0], args[2], const_args[2],
> + args[5], small);
> break;
> case TCG_COND_LTU:
> - tcg_out_brcond(s, TCG_COND_LTU, args[1], args[3], const_args[3], args[5]);
> - tcg_out_jxx(s, JCC_JNE, label_next);
> - tcg_out_brcond(s, TCG_COND_LTU, args[0], args[2], const_args[2], args[5]);
> + tcg_out_brcond(s, TCG_COND_LTU, args[1], args[3], const_args[3],
> + args[5], small);
> + tcg_out_jxx(s, JCC_JNE, label_next, 1);
> + tcg_out_brcond(s, TCG_COND_LTU, args[0], args[2], const_args[2],
> + args[5], small);
> break;
> case TCG_COND_LEU:
> - tcg_out_brcond(s, TCG_COND_LTU, args[1], args[3], const_args[3], args[5]);
> - tcg_out_jxx(s, JCC_JNE, label_next);
> - tcg_out_brcond(s, TCG_COND_LEU, args[0], args[2], const_args[2], args[5]);
> + tcg_out_brcond(s, TCG_COND_LTU, args[1], args[3], const_args[3],
> + args[5], small);
> + tcg_out_jxx(s, JCC_JNE, label_next, 1);
> + tcg_out_brcond(s, TCG_COND_LEU, args[0], args[2], const_args[2],
> + args[5], small);
> break;
> case TCG_COND_GTU:
> - tcg_out_brcond(s, TCG_COND_GTU, args[1], args[3], const_args[3], args[5]);
> - tcg_out_jxx(s, JCC_JNE, label_next);
> - tcg_out_brcond(s, TCG_COND_GTU, args[0], args[2], const_args[2], args[5]);
> + tcg_out_brcond(s, TCG_COND_GTU, args[1], args[3], const_args[3],
> + args[5], small);
> + tcg_out_jxx(s, JCC_JNE, label_next, 1);
> + tcg_out_brcond(s, TCG_COND_GTU, args[0], args[2], const_args[2],
> + args[5], small);
> break;
> case TCG_COND_GEU:
> - tcg_out_brcond(s, TCG_COND_GTU, args[1], args[3], const_args[3], args[5]);
> - tcg_out_jxx(s, JCC_JNE, label_next);
> - tcg_out_brcond(s, TCG_COND_GEU, args[0], args[2], const_args[2], args[5]);
> + tcg_out_brcond(s, TCG_COND_GTU, args[1], args[3], const_args[3],
> + args[5], small);
> + tcg_out_jxx(s, JCC_JNE, label_next, 1);
> + tcg_out_brcond(s, TCG_COND_GEU, args[0], args[2], const_args[2],
> + args[5], small);
> break;
> default:
> tcg_abort();
> @@ -913,7 +952,7 @@ static inline void tcg_out_op(TCGContext *s, int opc,
> }
> break;
> case INDEX_op_br:
> - tcg_out_jxx(s, JCC_JMP, args[0]);
> + tcg_out_jxx(s, JCC_JMP, args[0], 0);
> break;
> case INDEX_op_movi_i32:
> tcg_out_movi(s, TCG_TYPE_I32, args[0], args[1]);
> @@ -1044,10 +1083,11 @@ static inline void tcg_out_op(TCGContext *s, int opc,
> tcg_out_modrm(s, 0x01 | (ARITH_SBB << 3), args[5], args[1]);
> break;
> case INDEX_op_brcond_i32:
> - tcg_out_brcond(s, args[2], args[0], args[1], const_args[1], args[3]);
> + tcg_out_brcond(s, args[2], args[0], args[1], const_args[1],
> + args[3], 0);
> break;
> case INDEX_op_brcond2_i32:
> - tcg_out_brcond2(s, args, const_args);
> + tcg_out_brcond2(s, args, const_args, 0);
> break;
>
> case INDEX_op_bswap16_i32:
> --
> 1.6.5.2
>
>
>
>
--
Aurelien Jarno GPG: 1024D/F1BCDB73
aurelien@aurel32.net http://www.aurel32.net
next prev parent reply other threads:[~2009-12-19 23:11 UTC|newest]
Thread overview: 34+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-12-19 18:52 [Qemu-devel] [PATCH 0/5] tcg conditional set, round 4 Richard Henderson
2009-12-19 16:50 ` [Qemu-devel] [PATCH 2/5] tcg-x86_64: Implement setcond Richard Henderson
2009-12-19 23:11 ` Aurelien Jarno
2009-12-19 18:01 ` [Qemu-devel] [PATCH 1/5] tcg: Generic support for conditional set Richard Henderson
2009-12-19 23:11 ` Aurelien Jarno
2009-12-19 23:24 ` Richard Henderson
2009-12-19 23:45 ` Aurelien Jarno
2009-12-22 11:27 ` Laurent Desnogues
2009-12-22 16:09 ` Richard Henderson
2009-12-19 18:44 ` [Qemu-devel] [PATCH 3/5] tcg-i386: Implement small forward branches Richard Henderson
2009-12-19 23:11 ` Aurelien Jarno [this message]
2009-12-19 23:32 ` Laurent Desnogues
2009-12-20 1:17 ` Richard Henderson
2009-12-19 18:44 ` [Qemu-devel] [PATCH 4/5] tcg: Add tcg_invert_cond Richard Henderson
2009-12-19 23:11 ` Aurelien Jarno
2009-12-19 18:46 ` [Qemu-devel] [PATCH 5/5] tcg-i386: Implement setcond Richard Henderson
2009-12-19 23:11 ` Aurelien Jarno
2009-12-22 12:20 ` Laurent Desnogues
2009-12-19 23:11 ` [Qemu-devel] [PATCH 0/5] tcg conditional set, round 4 Aurelien Jarno
2009-12-19 23:43 ` malc
2009-12-20 11:03 ` Blue Swirl
2009-12-20 22:57 ` Paul Brook
2009-12-21 2:00 ` Richard Henderson
2009-12-21 9:13 ` Laurent Desnogues
2009-12-21 9:47 ` [Qemu-devel] " Paolo Bonzini
2009-12-21 10:03 ` Laurent Desnogues
2009-12-21 20:28 ` [Qemu-devel] " Richard Henderson
2009-12-21 22:21 ` Laurent Desnogues
2009-12-21 22:50 ` Richard Henderson
2009-12-21 23:08 ` Laurent Desnogues
2009-12-22 0:02 ` Richard Henderson
2009-12-22 14:46 ` Laurent Desnogues
2009-12-22 7:19 ` Aurelien Jarno
2009-12-21 10:08 ` Aurelien Jarno
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=20091219231127.GA355@volta.aurel32.net \
--to=aurelien@aurel32.net \
--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.