On Thu, Dec 17, 2009 at 6:55 PM, Richard Henderson <r...@twiddle.net> 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, and add a flag to tcg_out_jxx to > generate it. Set the flag in the small forward branches in brcond2. > > Signed-off-by: Richard Henderson <r...@twiddle.net> > --- > elf.h | 2 ++ > tcg/i386/tcg-target.c | 36 +++++++++++++++++++++++++----------- > 2 files changed, 27 insertions(+), 11 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..cc3d28f 100644 > --- a/tcg/i386/tcg-target.c > +++ b/tcg/i386/tcg-target.c > @@ -61,6 +61,9 @@ 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: > + *(uint8_t *)code_ptr = value - (long)code_ptr; > + break; > default: > tcg_abort(); > } > @@ -305,7 +308,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]; > @@ -320,6 +324,7 @@ static void tcg_out_jxx(TCGContext *s, int opc, int > label_index) > tcg_out8(s, 0x70 + opc); > tcg_out8(s, val1); > } else { > + assert (!small);
To be consistent with the rest I'd use: if (small) tcg_abort(); > if (opc == -1) { > tcg_out8(s, 0xe9); > tcg_out32(s, val - 5); > @@ -329,6 +334,15 @@ 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, 0x0f); I don't think this prefix should be output. Laurent > + 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); > @@ -355,7 +369,7 @@ 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, 0); > } > > /* XXX: we implement it at the target level to avoid having to > @@ -376,42 +390,42 @@ static void tcg_out_brcond2(TCGContext *s, > 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_jxx(s, JCC_JNE, label_next, 1); > tcg_out_brcond(s, TCG_COND_LTU, args[0], args[2], const_args[2], > args[5]); > 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_jxx(s, JCC_JNE, label_next, 1); > tcg_out_brcond(s, TCG_COND_LEU, args[0], args[2], const_args[2], > args[5]); > 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_jxx(s, JCC_JNE, label_next, 1); > tcg_out_brcond(s, TCG_COND_GTU, args[0], args[2], const_args[2], > args[5]); > 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_jxx(s, JCC_JNE, label_next, 1); > tcg_out_brcond(s, TCG_COND_GEU, args[0], args[2], const_args[2], > args[5]); > 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_jxx(s, JCC_JNE, label_next, 1); > tcg_out_brcond(s, TCG_COND_LTU, args[0], args[2], const_args[2], > args[5]); > 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_jxx(s, JCC_JNE, label_next, 1); > tcg_out_brcond(s, TCG_COND_LEU, args[0], args[2], const_args[2], > args[5]); > 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_jxx(s, JCC_JNE, label_next, 1); > tcg_out_brcond(s, TCG_COND_GTU, args[0], args[2], const_args[2], > args[5]); > 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_jxx(s, JCC_JNE, label_next, 1); > tcg_out_brcond(s, TCG_COND_GEU, args[0], args[2], const_args[2], > args[5]); > break; > default: > @@ -913,7 +927,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]); > -- > 1.6.5.2 > >