Prepare for multi-pass relaxation.

This commit is contained in:
Alan Modra 2001-03-30 00:06:10 +00:00
parent 23ec5d0312
commit 93c2a809af
10 changed files with 183 additions and 145 deletions

View File

@ -1,3 +1,25 @@
2001-03-30 Alan Modra <alan@linuxcare.com.au>
* config/tc-sh.c (md_estimate_size_before_relax): Add extra
do-nothing cases to switch to avoid abort on a second relaxation
pass, and tidy code a little.
* config/tc-cris.c (md_estimate_size_before_relax): Likewise.
* config/tc-h8500.c (md_estimate_size_before_relax): Likewise.
* config/tc-w65.c (md_estimate_size_before_relax): Likewise.
* config/tc-i386.c (UNCOND_JUMP, COND_JUMP, COND_JUMP86): Decrement.
(md_relax_table): Remove first four unused entries. Increment
rlx_length by one throughout table, and update comments to suit.
(md_estimate_size_before_relax): Return size of current variable
part of frag to reflect reality when relaxing more than once.
* config/tc-mcore.c (COND12, UNCD12): Rename to DISP12 throughout.
(COND32, UNCD32): Rename to DISP32 throughout.
(UNDEF_WORD_DISP): Renumber to 3.
(md_estimate_size_before_relax): Add extra do-nothing cases.
* config/tc-mn10200.c (md_estimate_size_before_relax): Rewrite.
* config/tc-mn10300.c (md_estimate_size_before_relax): Rewrite.
* config/tc-ns32k.c (md_estimate_size_before_relax): Add cases to
handle word and dword branches.
2001-03-29 Hans-Peter Nilsson <hp@axis.com>
* config/tc-cris.h (tc_fix_adjustable): Allow only

View File

@ -445,6 +445,11 @@ md_estimate_size_before_relax (fragP, segment_type)
}
break;
case ENCODE_RELAX (STATE_BASE_PLUS_DISP_PREFIX, STATE_DWORD):
/* When relaxing a section for the second time, we don't need to
do anything. */
break;
default:
BAD_CASE (fragP->fr_subtype);
}

View File

@ -1,5 +1,6 @@
/* tc-h8500.c -- Assemble code for the Hitachi H8/500
Copyright 1993, 1994, 1995, 1998, 2000 Free Software Foundation, Inc.
Copyright 1993, 1994, 1995, 1998, 2000, 2001
Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
@ -1447,6 +1448,7 @@ md_estimate_size_before_relax (fragP, segment_type)
{
default:
abort ();
case C (BRANCH, UNDEF_BYTE_DISP):
case C (SCB_F, UNDEF_BYTE_DISP):
case C (SCB_TST, UNDEF_BYTE_DISP):
@ -1464,8 +1466,18 @@ md_estimate_size_before_relax (fragP, segment_type)
long. */
fragP->fr_subtype = C (what, UNDEF_WORD_DISP);
fragP->fr_var = md_relax_table[C (what, WORD_DISP)].rlx_length;
return md_relax_table[C (what, WORD_DISP)].rlx_length;
}
break;
case C (BRANCH, BYTE_DISP):
case C (BRANCH, UNDEF_WORD_DISP):
case C (SCB_F, BYTE_DISP):
case C (SCB_F, UNDEF_WORD_DISP):
case C (SCB_TST, BYTE_DISP):
case C (SCB_TST, UNDEF_WORD_DISP):
/* When relaxing a section for the second time, we don't need to
do anything. */
break;
}
return fragP->fr_var;
}

View File

@ -284,9 +284,9 @@ static unsigned int no_cond_jump_promotion = 0;
figuring out what sort of jump to choose to reach a given label. */
/* Types. */
#define UNCOND_JUMP 1
#define COND_JUMP 2
#define COND_JUMP86 3
#define UNCOND_JUMP 0
#define COND_JUMP 1
#define COND_JUMP86 2
/* Sizes. */
#define CODE16 1
@ -323,42 +323,38 @@ const relax_typeS md_relax_table[] =
/* The fields are:
1) most positive reach of this state,
2) most negative reach of this state,
3) how many bytes this mode will add to the size of the current frag
3) how many bytes this mode will have in the variable part of the frag
4) which index into the table to try if we can't fit into this one. */
{1, 1, 0, 0},
{1, 1, 0, 0},
{1, 1, 0, 0},
{1, 1, 0, 0},
/* UNCOND_JUMP states. */
{127 + 1, -128 + 1, 0, ENCODE_RELAX_STATE (UNCOND_JUMP, BIG)},
{127 + 1, -128 + 1, 0, ENCODE_RELAX_STATE (UNCOND_JUMP, BIG16)},
/* dword jmp adds 3 bytes to frag:
0 extra opcode bytes, 3 extra displacement bytes. */
{0, 0, 3, 0},
/* word jmp adds 1 byte to frag:
0 extra opcode bytes, 1 extra displacement byte. */
{0, 0, 1, 0},
/* COND_JUMP states. */
{127 + 1, -128 + 1, 0, ENCODE_RELAX_STATE (COND_JUMP, BIG)},
{127 + 1, -128 + 1, 0, ENCODE_RELAX_STATE (COND_JUMP, BIG16)},
/* dword conditionals adds 4 bytes to frag:
1 extra opcode byte, 3 extra displacement bytes. */
{127 + 1, -128 + 1, 1, ENCODE_RELAX_STATE (UNCOND_JUMP, BIG)},
{127 + 1, -128 + 1, 1, ENCODE_RELAX_STATE (UNCOND_JUMP, BIG16)},
/* dword jmp adds 4 bytes to frag:
0 extra opcode bytes, 4 displacement bytes. */
{0, 0, 4, 0},
/* word conditionals add 2 bytes to frag:
1 extra opcode byte, 1 extra displacement byte. */
/* word jmp adds 2 byte2 to frag:
0 extra opcode bytes, 2 displacement bytes. */
{0, 0, 2, 0},
/* COND_JUMP86 states. */
{127 + 1, -128 + 1, 0, ENCODE_RELAX_STATE (COND_JUMP86, BIG)},
{127 + 1, -128 + 1, 0, ENCODE_RELAX_STATE (COND_JUMP86, BIG16)},
/* dword conditionals adds 4 bytes to frag:
1 extra opcode byte, 3 extra displacement bytes. */
{0, 0, 4, 0},
/* COND_JUMP states. */
{127 + 1, -128 + 1, 1, ENCODE_RELAX_STATE (COND_JUMP, BIG)},
{127 + 1, -128 + 1, 1, ENCODE_RELAX_STATE (COND_JUMP, BIG16)},
/* dword conditionals adds 5 bytes to frag:
1 extra opcode byte, 4 displacement bytes. */
{0, 0, 5, 0},
/* word conditionals add 3 bytes to frag:
1 extra opcode byte, 2 extra displacement bytes. */
{0, 0, 3, 0}
1 extra opcode byte, 2 displacement bytes. */
{0, 0, 3, 0},
/* COND_JUMP86 states. */
{127 + 1, -128 + 1, 1, ENCODE_RELAX_STATE (COND_JUMP86, BIG)},
{127 + 1, -128 + 1, 1, ENCODE_RELAX_STATE (COND_JUMP86, BIG16)},
/* dword conditionals adds 5 bytes to frag:
1 extra opcode byte, 4 displacement bytes. */
{0, 0, 5, 0},
/* word conditionals add 4 bytes to frag:
1 displacement byte and a 3 byte long branch insn. */
{0, 0, 4, 0}
};
static const arch_entry cpu_arch[] = {
@ -3971,7 +3967,8 @@ md_estimate_size_before_relax (fragP, segment)
case COND_JUMP86:
if (no_cond_jump_promotion)
return 1;
goto relax_guess;
if (size == 2)
{
/* Negate the condition, and branch past an
@ -3993,7 +3990,8 @@ md_estimate_size_before_relax (fragP, segment)
case COND_JUMP:
if (no_cond_jump_promotion)
return 1;
goto relax_guess;
/* This changes the byte-displacement jump 0x7N
to the (d)word-displacement jump 0x0f,0x8N. */
opcode[1] = opcode[0] + 0x10;
@ -4013,8 +4011,15 @@ md_estimate_size_before_relax (fragP, segment)
frag_wane (fragP);
return fragP->fr_fix - old_fr_fix;
}
/* Guess a short jump. */
return 1;
relax_guess:
/* Guess size depending on current relax state. Initially the relax
state will correspond to a short jump and we return 1, because
the variable part of the frag (the branch offset) is one byte
long. However, we can relax a section more than once and in that
case we must either set fr_subtype back to the unrelaxed state,
or return the value for the appropriate branch. */
return md_relax_table[fragP->fr_subtype].rlx_length;
}
/* Called after relax() is finished.

View File

@ -1,5 +1,5 @@
/* tc-mcore.c -- Assemble code for M*Core
Copyright 1999, 2000 Free Software Foundation, Inc.
Copyright 1999, 2000, 2001 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
@ -92,12 +92,9 @@ const char FLT_CHARS[] = "rRsSfFdDxXpP";
#define UNCD_JUMP 2
#define UNDEF_DISP 0
#define COND12 1
#define COND32 2
#define UNCD12 1
#define UNCD32 2
#define UNDEF_WORD_DISP 4
#define END 5
#define DISP12 1
#define DISP32 2
#define UNDEF_WORD_DISP 3
#define C12_LEN 2
#define C32_LEN 10 /* allow for align */
@ -121,14 +118,13 @@ const relax_typeS md_relax_table[] =
{ 1, 1, 0, 0 }, /* 2: unused */
{ 1, 1, 0, 0 }, /* 3: unused */
{ 1, 1, 0, 0 }, /* 4: unused */
{ 2048, -2046, C12_LEN, C(COND_JUMP, COND32) }, /* 5: C(COND_JUMP, COND12) */
{ 0, 0, C32_LEN, 0 }, /* 6: C(COND_JUMP, COND32) */
{ 2048, -2046, C12_LEN, C(COND_JUMP, DISP32) }, /* 5: C(COND_JUMP, DISP12) */
{ 0, 0, C32_LEN, 0 }, /* 6: C(COND_JUMP, DISP32) */
{ 1, 1, 0, 0 }, /* 7: unused */
{ 1, 1, 0, 0 }, /* 8: unused */
{ 2048, -2046, U12_LEN, C(UNCD_JUMP, UNCD32) }, /* 9: C(UNCD_JUMP, UNCD12) */
{ 0, 0, U32_LEN, 0 }, /*10: C(UNCD_JUMP, UNCD32) */
{ 2048, -2046, U12_LEN, C(UNCD_JUMP, DISP32) }, /* 9: C(UNCD_JUMP, DISP12) */
{ 0, 0, U32_LEN, 0 }, /*10: C(UNCD_JUMP, DISP32) */
{ 1, 1, 0, 0 }, /*11: unused */
{ 0, 0, 0, 0 } /*12: unused */
};
/* Literal pool data structures. */
@ -705,8 +701,8 @@ dump_literals (isforce)
symbol_table_insert (brarsym);
output = frag_var (rs_machine_dependent,
md_relax_table[C (UNCD_JUMP, UNCD32)].rlx_length,
md_relax_table[C (UNCD_JUMP, UNCD12)].rlx_length,
md_relax_table[C (UNCD_JUMP, DISP32)].rlx_length,
md_relax_table[C (UNCD_JUMP, DISP12)].rlx_length,
C (UNCD_JUMP, 0), brarsym, 0, 0);
output[0] = INST_BYTE0 (MCORE_INST_BR); /* br .+xxx */
output[1] = INST_BYTE1 (MCORE_INST_BR);
@ -1558,8 +1554,8 @@ md_assemble (str)
op_end = input_line_pointer;
output = frag_var (rs_machine_dependent,
md_relax_table[C (COND_JUMP, COND32)].rlx_length,
md_relax_table[C (COND_JUMP, COND12)].rlx_length,
md_relax_table[C (COND_JUMP, DISP32)].rlx_length,
md_relax_table[C (COND_JUMP, DISP12)].rlx_length,
C (COND_JUMP, 0), e.X_add_symbol, e.X_add_number, 0);
isize = C32_LEN;
break;
@ -1569,8 +1565,8 @@ md_assemble (str)
op_end = input_line_pointer;
output = frag_var (rs_machine_dependent,
md_relax_table[C (UNCD_JUMP, UNCD32)].rlx_length,
md_relax_table[C (UNCD_JUMP, UNCD12)].rlx_length,
md_relax_table[C (UNCD_JUMP, DISP32)].rlx_length,
md_relax_table[C (UNCD_JUMP, DISP12)].rlx_length,
C (UNCD_JUMP, 0), e.X_add_symbol, e.X_add_number, 0);
isize = U32_LEN;
break;
@ -1904,8 +1900,8 @@ md_convert_frag (abfd, sec, fragP)
switch (fragP->fr_subtype)
{
case C (COND_JUMP, COND12):
case C (UNCD_JUMP, UNCD12):
case C (COND_JUMP, DISP12):
case C (UNCD_JUMP, DISP12):
{
/* Get the address of the end of the instruction. */
int next_inst = fragP->fr_fix + fragP->fr_address + 2;
@ -1939,7 +1935,7 @@ md_convert_frag (abfd, sec, fragP)
}
break;
case C (COND_JUMP, COND32):
case C (COND_JUMP, DISP32):
case C (COND_JUMP, UNDEF_WORD_DISP):
{
/* A conditional branch wont fit into 12 bits so:
@ -2031,7 +2027,7 @@ md_convert_frag (abfd, sec, fragP)
}
break;
case C (UNCD_JUMP, UNCD32):
case C (UNCD_JUMP, DISP32):
case C (UNCD_JUMP, UNDEF_WORD_DISP):
{
/* An unconditional branch will not fit in 12 bits, make code which
@ -2247,29 +2243,28 @@ md_estimate_size_before_relax (fragP, segment_type)
{
switch (fragP->fr_subtype)
{
default:
abort ();
case C (UNCD_JUMP, UNDEF_DISP):
/* Used to be a branch to somewhere which was unknown. */
if (!fragP->fr_symbol)
{
fragP->fr_subtype = C (UNCD_JUMP, UNCD12);
fragP->fr_var = md_relax_table[C (UNCD_JUMP, UNCD12)].rlx_length;
fragP->fr_subtype = C (UNCD_JUMP, DISP12);
fragP->fr_var = md_relax_table[C (UNCD_JUMP, DISP12)].rlx_length;
}
else if (S_GET_SEGMENT (fragP->fr_symbol) == segment_type)
{
fragP->fr_subtype = C (UNCD_JUMP, UNCD12);
fragP->fr_var = md_relax_table[C (UNCD_JUMP, UNCD12)].rlx_length;
fragP->fr_subtype = C (UNCD_JUMP, DISP12);
fragP->fr_var = md_relax_table[C (UNCD_JUMP, DISP12)].rlx_length;
}
else
{
fragP->fr_subtype = C (UNCD_JUMP, UNDEF_WORD_DISP);
fragP->fr_var = md_relax_table[C (UNCD_JUMP, UNCD32)].rlx_length;
return md_relax_table[C (UNCD_JUMP, UNCD32)].rlx_length;
fragP->fr_var = md_relax_table[C (UNCD_JUMP, DISP32)].rlx_length;
}
break;
default:
abort ();
case C (COND_JUMP, UNDEF_DISP):
/* Used to be a branch to somewhere which was unknown. */
if (fragP->fr_symbol
@ -2277,23 +2272,29 @@ md_estimate_size_before_relax (fragP, segment_type)
{
/* Got a symbol and it's defined in this segment, become byte
sized - maybe it will fix up */
fragP->fr_subtype = C (COND_JUMP, COND12);
fragP->fr_var = md_relax_table[C (COND_JUMP, COND12)].rlx_length;
fragP->fr_subtype = C (COND_JUMP, DISP12);
fragP->fr_var = md_relax_table[C (COND_JUMP, DISP12)].rlx_length;
}
else if (fragP->fr_symbol)
{
/* Its got a segment, but its not ours, so it will always be long. */
fragP->fr_subtype = C (COND_JUMP, UNDEF_WORD_DISP);
fragP->fr_var = md_relax_table[C (COND_JUMP, COND32)].rlx_length;
return md_relax_table[C (COND_JUMP, COND32)].rlx_length;
fragP->fr_var = md_relax_table[C (COND_JUMP, DISP32)].rlx_length;
}
else
{
/* We know the abs value. */
fragP->fr_subtype = C (COND_JUMP, COND12);
fragP->fr_var = md_relax_table[C (COND_JUMP, COND12)].rlx_length;
fragP->fr_subtype = C (COND_JUMP, DISP12);
fragP->fr_var = md_relax_table[C (COND_JUMP, DISP12)].rlx_length;
}
break;
case C (UNCD_JUMP, DISP12):
case C (UNCD_JUMP, UNDEF_WORD_DISP):
case C (COND_JUMP, DISP12):
case C (COND_JUMP, UNDEF_WORD_DISP):
/* When relaxing a section for the second time, we don't need to
do anything. */
break;
}

View File

@ -1,5 +1,6 @@
/* tc-mn10200.c -- Assembler code for the Matsushita 10200
Copyright 1996, 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
Copyright 1996, 1997, 1998, 1999, 2000, 2001
Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
@ -1284,29 +1285,19 @@ md_estimate_size_before_relax (fragp, seg)
fragS *fragp;
asection *seg;
{
if (fragp->fr_subtype == 0)
return 2;
if (fragp->fr_subtype == 3)
return 3;
if (fragp->fr_subtype == 6)
{
if (!S_IS_DEFINED (fragp->fr_symbol)
|| seg != S_GET_SEGMENT (fragp->fr_symbol))
{
fragp->fr_subtype = 7;
return 5;
}
return 3;
}
if (fragp->fr_subtype == 8)
{
if (!S_IS_DEFINED (fragp->fr_symbol))
{
fragp->fr_subtype = 10;
return 5;
}
return 2;
}
if (fragp->fr_subtype == 6
&& (!S_IS_DEFINED (fragp->fr_symbol)
|| seg != S_GET_SEGMENT (fragp->fr_symbol)))
fragp->fr_subtype = 7;
else if (fragp->fr_subtype == 8
&& (!S_IS_DEFINED (fragp->fr_symbol)
|| seg != S_GET_SEGMENT (fragp->fr_symbol)))
fragp->fr_subtype = 10;
if (fragp->fr_subtype >= sizeof (md_relax_table) / sizeof (md_relax_table[0]))
abort ();
return md_relax_table[fragp->fr_subtype].rlx_length;
}
long

View File

@ -1843,44 +1843,23 @@ md_estimate_size_before_relax (fragp, seg)
fragS *fragp;
asection *seg;
{
if (fragp->fr_subtype == 0)
return 2;
if (fragp->fr_subtype == 3)
return 3;
if (fragp->fr_subtype == 6)
{
if (!S_IS_DEFINED (fragp->fr_symbol)
|| seg != S_GET_SEGMENT (fragp->fr_symbol))
{
fragp->fr_subtype = 7;
return 7;
}
else
return 5;
}
if (fragp->fr_subtype == 8)
{
if (!S_IS_DEFINED (fragp->fr_symbol)
|| seg != S_GET_SEGMENT (fragp->fr_symbol))
{
fragp->fr_subtype = 9;
return 6;
}
else
return 4;
}
if (fragp->fr_subtype == 10)
{
if (!S_IS_DEFINED (fragp->fr_symbol)
|| seg != S_GET_SEGMENT (fragp->fr_symbol))
{
fragp->fr_subtype = 12;
return 5;
}
else
return 2;
}
abort ();
if (fragp->fr_subtype == 6
&& (!S_IS_DEFINED (fragp->fr_symbol)
|| seg != S_GET_SEGMENT (fragp->fr_symbol)))
fragp->fr_subtype = 7;
else if (fragp->fr_subtype == 8
&& (!S_IS_DEFINED (fragp->fr_symbol)
|| seg != S_GET_SEGMENT (fragp->fr_symbol)))
fragp->fr_subtype = 9;
else if (fragp->fr_subtype == 10
&& (!S_IS_DEFINED (fragp->fr_symbol)
|| seg != S_GET_SEGMENT (fragp->fr_symbol)))
fragp->fr_subtype = 12;
if (fragp->fr_subtype >= sizeof (md_relax_table) / sizeof (md_relax_table[0]))
abort ();
return md_relax_table[fragp->fr_subtype].rlx_length;
}
long

View File

@ -1,5 +1,6 @@
/* ns32k.c -- Assemble on the National Semiconductor 32k series
Copyright 1987, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000
Copyright 1987, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
2001
Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
@ -2102,9 +2103,14 @@ md_estimate_size_before_relax (fragP, segment)
frag_wane (fragP);
break;
}
/* Fall thru */
case IND (BRANCH, BYTE):
fragP->fr_var += 1;
case IND (BRANCH, WORD):
case IND (BRANCH, DOUBLE):
fragP->fr_var = md_relax_table[fragP->fr_subtype].rlx_length;
break;
default:
break;
}

View File

@ -3030,6 +3030,9 @@ md_estimate_size_before_relax (fragP, segment_type)
{
switch (fragP->fr_subtype)
{
default:
abort ();
case C (UNCOND_JUMP, UNDEF_DISP):
/* Used to be a branch to somewhere which was unknown. */
if (!fragP->fr_symbol)
@ -3046,12 +3049,9 @@ md_estimate_size_before_relax (fragP, segment_type)
{
fragP->fr_subtype = C (UNCOND_JUMP, UNDEF_WORD_DISP);
fragP->fr_var = md_relax_table[C (UNCOND_JUMP, UNCOND32)].rlx_length;
return md_relax_table[C (UNCOND_JUMP, UNCOND32)].rlx_length;
}
break;
default:
abort ();
case C (COND_JUMP, UNDEF_DISP):
case C (COND_JUMP_DELAY, UNDEF_DISP):
/* Used to be a branch to somewhere which was unknown. */
@ -3070,7 +3070,6 @@ md_estimate_size_before_relax (fragP, segment_type)
/* Its got a segment, but its not ours, so it will always be long. */
fragP->fr_subtype = C (what, UNDEF_WORD_DISP);
fragP->fr_var = md_relax_table[C (what, COND32)].rlx_length;
return md_relax_table[C (what, COND32)].rlx_length;
}
else
{
@ -3079,7 +3078,16 @@ md_estimate_size_before_relax (fragP, segment_type)
fragP->fr_subtype = C (what, COND8);
fragP->fr_var = md_relax_table[C (what, COND8)].rlx_length;
}
break;
case C (UNCOND_JUMP, UNCOND12):
case C (UNCOND_JUMP, UNDEF_WORD_DISP):
case C (COND_JUMP, COND8):
case C (COND_JUMP, UNDEF_WORD_DISP):
case C (COND_JUMP_DELAY, COND8):
case C (COND_JUMP_DELAY, UNDEF_WORD_DISP):
/* When relaxing a section for the second time, we don't need to
do anything. */
break;
}
return fragP->fr_var;

View File

@ -1,5 +1,5 @@
/* tc-w65.c -- Assemble code for the W65816
Copyright 1995, 1998, 2000 Free Software Foundation, Inc.
Copyright 1995, 1998, 2000, 2001 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
@ -1154,6 +1154,7 @@ md_estimate_size_before_relax (fragP, segment_type)
{
default:
abort ();
case C (COND_BRANCH, UNDEF_BYTE_DISP):
case C (UNCOND_BRANCH, UNDEF_BYTE_DISP):
/* Used to be a branch to somewhere which was unknown. */
@ -1170,8 +1171,16 @@ md_estimate_size_before_relax (fragP, segment_type)
long. */
fragP->fr_subtype = C (what, UNDEF_WORD_DISP);
fragP->fr_var = md_relax_table[C (what, WORD_DISP)].rlx_length;
return md_relax_table[C (what, WORD_DISP)].rlx_length;
}
break;
case C (COND_BRANCH, BYTE_DISP):
case C (COND_BRANCH, WORD_DISP):
case C (UNCOND_BRANCH, BYTE_DISP):
case C (UNCOND_BRANCH, WORD_DISP):
/* When relaxing a section for the second time, we don't need to
do anything. */
break;
}
return fragP->fr_var;
}