Fix more fallout from multi-pass relaxation patch.
This commit is contained in:
parent
dab11f21ed
commit
606ab118ba
@ -1,3 +1,36 @@
|
||||
2001-05-10 Alan Modra <amodra@one.net.au>
|
||||
|
||||
* config/obj-vms.c (obj_crawl_symbol_chain): Don't take address of
|
||||
symbol_next.
|
||||
|
||||
* config/tc-fr30.c (md_estimate_size_before_relax): Return size of
|
||||
current variable part of frag.
|
||||
* config/tc-m32r.c (md_estimate_size_before_relax): Likewise.
|
||||
* config/tc-openrisc.c (md_estimate_size_before_relax): Likewise.
|
||||
* config/tc-m68hc11.c (RELAX_STATE): Define.
|
||||
(RELAX_LENGTH): Define.
|
||||
(md_estimate_size_before_relax): Handle non-relaxable cases
|
||||
separately from relaxable cases for clarity, and return correct
|
||||
size for multi-pass relaxation.
|
||||
* config/tc-tahoe.c (RELAX_LENGTH): Correct.
|
||||
(md_estimate_size_before_relax): As for tc-m68hc11.c.
|
||||
(md_convert_frag): Remove "length_code".
|
||||
* config/tc-vax.c (RELAX_STATE): Define.
|
||||
(RELAX_LENGTH): Define.
|
||||
(md_relax_table): Add missing entry.
|
||||
(md_estimate_size_before_relax): As for tc-m68hc11.c.
|
||||
(md_convert_frag): Remove "length_code".
|
||||
* config/tc-ns32k.c (md_estimate_size_before_relax): Simplify and
|
||||
don't bother setting fr_var. Return correct size for multi-pass
|
||||
relaxation.
|
||||
* config/tc-v850.c (md_estimate_size_before_relax): Rewrite.
|
||||
(md_convert_frag): Don't bother clearing fr_var.
|
||||
(md_pseudo_table): Correct initialization.
|
||||
* config/tc-h8500.c (md_convert_frag): Don't bother clearing fr_var.
|
||||
(md_estimate_size_before_relax): No need to set fr_var.
|
||||
* config/tc-mcore.c (md_convert_frag): Don't bother clearing fr_var.
|
||||
(md_estimate_size_before_relax): No need to set fr_var.
|
||||
|
||||
2001-05-09 Richard Henderson <rth@redhat.com>
|
||||
|
||||
* config/tc-ia64.c (generate_unwind_image): Align the fragment
|
||||
|
@ -552,7 +552,7 @@ obj_crawl_symbol_chain (headers)
|
||||
{
|
||||
symbolP->sy_number = symbol_number++;
|
||||
symbolP->sy_name_offset = 0;
|
||||
symbolPP = &(symbol_next (symbolP));
|
||||
symbolPP = &symbolP->sy_next;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -265,8 +265,6 @@ md_estimate_size_before_relax (fragP, segment)
|
||||
fragS * fragP;
|
||||
segT segment;
|
||||
{
|
||||
int old_fr_fix = fragP->fr_fix;
|
||||
|
||||
/* The only thing we have to handle here are symbols outside of the
|
||||
current segment. They may be undefined or in a different segment in
|
||||
which case linker scripts may place them anywhere.
|
||||
@ -275,6 +273,8 @@ md_estimate_size_before_relax (fragP, segment)
|
||||
|
||||
if (S_GET_SEGMENT (fragP->fr_symbol) != segment)
|
||||
{
|
||||
int old_fr_fix = fragP->fr_fix;
|
||||
|
||||
/* The symbol is undefined in this segment.
|
||||
Change the relaxation subtype to the max allowable and leave
|
||||
all further handling to md_convert_frag. */
|
||||
@ -297,6 +297,7 @@ md_estimate_size_before_relax (fragP, segment)
|
||||
|
||||
/* Mark this fragment as finished. */
|
||||
frag_wane (fragP);
|
||||
return fragP->fr_fix - old_fr_fix;
|
||||
#else
|
||||
{
|
||||
const CGEN_INSN * insn;
|
||||
@ -323,7 +324,8 @@ md_estimate_size_before_relax (fragP, segment)
|
||||
#endif
|
||||
}
|
||||
|
||||
return (fragP->fr_var + fragP->fr_fix - old_fr_fix);
|
||||
/* Return the size of the variable part of the frag. */
|
||||
return md_relax_table[fragP->fr_subtype].rlx_length;
|
||||
}
|
||||
|
||||
/* *fragP has been relaxed to its final size, and now needs to have
|
||||
|
@ -1343,7 +1343,6 @@ md_convert_frag (headers, seg, fragP)
|
||||
R_H8500_PCREL16);
|
||||
|
||||
fragP->fr_fix += disp_size + inst_size;
|
||||
fragP->fr_var = 0;
|
||||
return;
|
||||
break;
|
||||
default:
|
||||
@ -1359,7 +1358,6 @@ md_convert_frag (headers, seg, fragP)
|
||||
|
||||
md_number_to_chars (buffer + inst_size, disp, disp_size);
|
||||
fragP->fr_fix += disp_size + inst_size;
|
||||
fragP->fr_var = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1471,8 +1469,7 @@ md_estimate_size_before_relax (fragP, segment_type)
|
||||
break;
|
||||
}
|
||||
|
||||
fragP->fr_var = md_relax_table[fragP->fr_subtype].rlx_length;
|
||||
return fragP->fr_var;
|
||||
return md_relax_table[fragP->fr_subtype].rlx_length;
|
||||
}
|
||||
|
||||
/* Put number into target byte order. */
|
||||
|
@ -1441,8 +1441,6 @@ md_estimate_size_before_relax (fragP, segment)
|
||||
fragS *fragP;
|
||||
segT segment;
|
||||
{
|
||||
int old_fr_fix = fragP->fr_fix;
|
||||
|
||||
/* The only thing we have to handle here are symbols outside of the
|
||||
current segment. They may be undefined or in a different segment in
|
||||
which case linker scripts may place them anywhere.
|
||||
@ -1451,6 +1449,8 @@ md_estimate_size_before_relax (fragP, segment)
|
||||
|
||||
if (S_GET_SEGMENT (fragP->fr_symbol) != segment)
|
||||
{
|
||||
int old_fr_fix = fragP->fr_fix;
|
||||
|
||||
/* The symbol is undefined in this segment.
|
||||
Change the relaxation subtype to the max allowable and leave
|
||||
all further handling to md_convert_frag. */
|
||||
@ -1474,6 +1474,7 @@ md_estimate_size_before_relax (fragP, segment)
|
||||
|
||||
/* Mark this fragment as finished. */
|
||||
frag_wane (fragP);
|
||||
return fragP->fr_fix - old_fr_fix;
|
||||
#else
|
||||
{
|
||||
const CGEN_INSN *insn;
|
||||
@ -1500,7 +1501,7 @@ md_estimate_size_before_relax (fragP, segment)
|
||||
#endif
|
||||
}
|
||||
|
||||
return (fragP->fr_var + fragP->fr_fix - old_fr_fix);
|
||||
return md_relax_table[fragP->fr_subtype].rlx_length;
|
||||
}
|
||||
|
||||
/* *FRAGP has been relaxed to its final size, and now needs to have
|
||||
|
@ -49,6 +49,8 @@ const char FLT_CHARS[] = "dD";
|
||||
|
||||
/* This macro has no side-effects. */
|
||||
#define ENCODE_RELAX(what,length) (((what) << 2) + (length))
|
||||
#define RELAX_STATE(s) ((s) >> 2)
|
||||
#define RELAX_LENGTH(s) ((s) & 3)
|
||||
|
||||
#define IS_OPCODE(C1,C2) (((C1) & 0x0FF) == ((C2) & 0x0FF))
|
||||
|
||||
@ -2563,145 +2565,153 @@ md_estimate_size_before_relax (fragP, segment)
|
||||
fragS *fragP;
|
||||
asection *segment;
|
||||
{
|
||||
int old_fr_fix;
|
||||
char *buffer_address = fragP->fr_fix + fragP->fr_literal;
|
||||
|
||||
old_fr_fix = fragP->fr_fix;
|
||||
|
||||
switch (fragP->fr_subtype)
|
||||
if (RELAX_LENGTH (fragP->fr_subtype) == STATE_UNDF)
|
||||
{
|
||||
case ENCODE_RELAX (STATE_PC_RELATIVE, STATE_UNDF):
|
||||
|
||||
/* This relax is only for bsr and bra. */
|
||||
assert (IS_OPCODE (fragP->fr_opcode[0], M6811_BSR)
|
||||
|| IS_OPCODE (fragP->fr_opcode[0], M6811_BRA)
|
||||
|| IS_OPCODE (fragP->fr_opcode[0], M6812_BSR));
|
||||
|
||||
/* A relaxable case. */
|
||||
if (S_GET_SEGMENT (fragP->fr_symbol) == segment
|
||||
&& relaxable_symbol (fragP->fr_symbol))
|
||||
if (S_GET_SEGMENT (fragP->fr_symbol) != segment
|
||||
|| !relaxable_symbol (fragP->fr_symbol))
|
||||
{
|
||||
fragP->fr_subtype = ENCODE_RELAX (STATE_PC_RELATIVE, STATE_BYTE);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (flag_fixed_branchs)
|
||||
as_bad_where (fragP->fr_file, fragP->fr_line,
|
||||
_("bra or bsr with undefined symbol."));
|
||||
/* Non-relaxable cases. */
|
||||
int old_fr_fix;
|
||||
char *buffer_address;
|
||||
|
||||
/* The symbol is undefined or in a separate section. Turn bra into a
|
||||
jmp and bsr into a jsr. The insn becomes 3 bytes long (instead of
|
||||
2). A fixup is necessary for the unresolved symbol address. */
|
||||
old_fr_fix = fragP->fr_fix;
|
||||
buffer_address = fragP->fr_fix + fragP->fr_literal;
|
||||
|
||||
fragP->fr_opcode[0] = convert_branch (fragP->fr_opcode[0]);
|
||||
switch (RELAX_STATE (fragP->fr_subtype))
|
||||
{
|
||||
case STATE_PC_RELATIVE:
|
||||
|
||||
fragP->fr_fix++;
|
||||
fix_new (fragP, old_fr_fix - 1, 2, fragP->fr_symbol,
|
||||
fragP->fr_offset, 0, BFD_RELOC_16);
|
||||
/* This relax is only for bsr and bra. */
|
||||
assert (IS_OPCODE (fragP->fr_opcode[0], M6811_BSR)
|
||||
|| IS_OPCODE (fragP->fr_opcode[0], M6811_BRA)
|
||||
|| IS_OPCODE (fragP->fr_opcode[0], M6812_BSR));
|
||||
|
||||
if (flag_fixed_branchs)
|
||||
as_bad_where (fragP->fr_file, fragP->fr_line,
|
||||
_("bra or bsr with undefined symbol."));
|
||||
|
||||
/* The symbol is undefined or in a separate section.
|
||||
Turn bra into a jmp and bsr into a jsr. The insn
|
||||
becomes 3 bytes long (instead of 2). A fixup is
|
||||
necessary for the unresolved symbol address. */
|
||||
fragP->fr_opcode[0] = convert_branch (fragP->fr_opcode[0]);
|
||||
|
||||
fragP->fr_fix++;
|
||||
fix_new (fragP, old_fr_fix - 1, 2, fragP->fr_symbol,
|
||||
fragP->fr_offset, 0, BFD_RELOC_16);
|
||||
break;
|
||||
|
||||
case STATE_CONDITIONAL_BRANCH:
|
||||
assert (current_architecture & cpu6811);
|
||||
|
||||
fragP->fr_opcode[0] ^= 1; /* Reverse sense of branch. */
|
||||
fragP->fr_opcode[1] = 3; /* Skip next jmp insn (3 bytes). */
|
||||
|
||||
/* Don't use fr_opcode[2] because this may be
|
||||
in a different frag. */
|
||||
buffer_address[0] = M6811_JMP;
|
||||
|
||||
fragP->fr_fix++;
|
||||
fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
|
||||
fragP->fr_offset, 0, BFD_RELOC_16);
|
||||
fragP->fr_fix += 2;
|
||||
break;
|
||||
|
||||
case STATE_INDEXED_OFFSET:
|
||||
assert (current_architecture & cpu6812);
|
||||
|
||||
/* Switch the indexed operation to 16-bit mode. */
|
||||
fragP->fr_opcode[0] = fragP->fr_opcode[0] << 3;
|
||||
fragP->fr_opcode[0] |= 0xe2;
|
||||
fragP->fr_fix++;
|
||||
fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
|
||||
fragP->fr_offset, 0, BFD_RELOC_16);
|
||||
fragP->fr_fix++;
|
||||
break;
|
||||
|
||||
case STATE_XBCC_BRANCH:
|
||||
assert (current_architecture & cpu6812);
|
||||
|
||||
fragP->fr_opcode[0] ^= 0x20; /* Reverse sense of branch. */
|
||||
fragP->fr_opcode[1] = 3; /* Skip next jmp insn (3 bytes). */
|
||||
|
||||
/* Don't use fr_opcode[2] because this may be
|
||||
in a different frag. */
|
||||
buffer_address[0] = M6812_JMP;
|
||||
|
||||
fragP->fr_fix++;
|
||||
fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
|
||||
fragP->fr_offset, 0, BFD_RELOC_16);
|
||||
fragP->fr_fix += 2;
|
||||
break;
|
||||
|
||||
case STATE_CONDITIONAL_BRANCH_6812:
|
||||
assert (current_architecture & cpu6812);
|
||||
|
||||
/* Translate into a lbcc branch. */
|
||||
fragP->fr_opcode[1] = fragP->fr_opcode[0];
|
||||
fragP->fr_opcode[0] = M6811_OPCODE_PAGE2;
|
||||
|
||||
fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
|
||||
fragP->fr_offset, 0, BFD_RELOC_16_PCREL);
|
||||
fragP->fr_fix += 2;
|
||||
break;
|
||||
|
||||
default:
|
||||
as_fatal (_("Subtype %d is not recognized."), fragP->fr_subtype);
|
||||
}
|
||||
frag_wane (fragP);
|
||||
|
||||
/* Return the growth in the fixed part of the frag. */
|
||||
return fragP->fr_fix - old_fr_fix;
|
||||
}
|
||||
break;
|
||||
|
||||
case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, STATE_UNDF):
|
||||
assert (current_architecture & cpu6811);
|
||||
|
||||
if (S_GET_SEGMENT (fragP->fr_symbol) == segment
|
||||
&& relaxable_symbol (fragP->fr_symbol))
|
||||
/* Relaxable cases. */
|
||||
switch (RELAX_STATE (fragP->fr_subtype))
|
||||
{
|
||||
case STATE_PC_RELATIVE:
|
||||
/* This relax is only for bsr and bra. */
|
||||
assert (IS_OPCODE (fragP->fr_opcode[0], M6811_BSR)
|
||||
|| IS_OPCODE (fragP->fr_opcode[0], M6811_BRA)
|
||||
|| IS_OPCODE (fragP->fr_opcode[0], M6812_BSR));
|
||||
|
||||
fragP->fr_subtype = ENCODE_RELAX (STATE_PC_RELATIVE, STATE_BYTE);
|
||||
break;
|
||||
|
||||
case STATE_CONDITIONAL_BRANCH:
|
||||
assert (current_architecture & cpu6811);
|
||||
|
||||
fragP->fr_subtype = ENCODE_RELAX (STATE_CONDITIONAL_BRANCH,
|
||||
STATE_BYTE);
|
||||
}
|
||||
else
|
||||
{
|
||||
fragP->fr_opcode[0] ^= 1; /* Reverse sense of branch. */
|
||||
fragP->fr_opcode[1] = 3; /* Skip next jmp insn (3 bytes). */
|
||||
break;
|
||||
|
||||
/* Don't use fr_opcode[2] because this may be
|
||||
in a different frag. */
|
||||
buffer_address[0] = M6811_JMP;
|
||||
case STATE_INDEXED_OFFSET:
|
||||
assert (current_architecture & cpu6812);
|
||||
|
||||
fragP->fr_fix++;
|
||||
fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
|
||||
fragP->fr_offset, 0, BFD_RELOC_16);
|
||||
fragP->fr_fix += 2;
|
||||
frag_wane (fragP);
|
||||
}
|
||||
break;
|
||||
|
||||
case ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_UNDF):
|
||||
assert (current_architecture & cpu6812);
|
||||
|
||||
if (S_GET_SEGMENT (fragP->fr_symbol) == segment
|
||||
&& relaxable_symbol (fragP->fr_symbol))
|
||||
{
|
||||
fragP->fr_subtype = ENCODE_RELAX (STATE_INDEXED_OFFSET,
|
||||
STATE_BITS5);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Switch the indexed operation to 16-bit mode. */
|
||||
fragP->fr_opcode[0] = fragP->fr_opcode[0] << 3;
|
||||
fragP->fr_opcode[0] |= 0xe2;
|
||||
fragP->fr_fix++;
|
||||
fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
|
||||
fragP->fr_offset, 0, BFD_RELOC_16);
|
||||
fragP->fr_fix++;
|
||||
frag_wane (fragP);
|
||||
}
|
||||
break;
|
||||
break;
|
||||
|
||||
case ENCODE_RELAX (STATE_XBCC_BRANCH, STATE_UNDF):
|
||||
assert (current_architecture & cpu6812);
|
||||
case STATE_XBCC_BRANCH:
|
||||
assert (current_architecture & cpu6812);
|
||||
|
||||
if (S_GET_SEGMENT (fragP->fr_symbol) == segment
|
||||
&& relaxable_symbol (fragP->fr_symbol))
|
||||
{
|
||||
fragP->fr_subtype = ENCODE_RELAX (STATE_XBCC_BRANCH, STATE_BYTE);
|
||||
}
|
||||
else
|
||||
{
|
||||
fragP->fr_opcode[0] ^= 0x20; /* Reverse sense of branch. */
|
||||
fragP->fr_opcode[1] = 3; /* Skip next jmp insn (3 bytes). */
|
||||
break;
|
||||
|
||||
/* Don't use fr_opcode[2] because this may be
|
||||
in a different frag. */
|
||||
buffer_address[0] = M6812_JMP;
|
||||
case STATE_CONDITIONAL_BRANCH_6812:
|
||||
assert (current_architecture & cpu6812);
|
||||
|
||||
fragP->fr_fix++;
|
||||
fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
|
||||
fragP->fr_offset, 0, BFD_RELOC_16);
|
||||
fragP->fr_fix += 2;
|
||||
frag_wane (fragP);
|
||||
}
|
||||
break;
|
||||
|
||||
case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812, STATE_UNDF):
|
||||
assert (current_architecture & cpu6812);
|
||||
|
||||
if (S_GET_SEGMENT (fragP->fr_symbol) == segment
|
||||
&& relaxable_symbol (fragP->fr_symbol))
|
||||
{
|
||||
fragP->fr_subtype = ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812,
|
||||
STATE_BYTE);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Translate into a lbcc branch. */
|
||||
fragP->fr_opcode[1] = fragP->fr_opcode[0];
|
||||
fragP->fr_opcode[0] = M6811_OPCODE_PAGE2;
|
||||
|
||||
fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
|
||||
fragP->fr_offset, 0, BFD_RELOC_16_PCREL);
|
||||
fragP->fr_fix += 2;
|
||||
frag_wane (fragP);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
as_fatal (_("Subtype %d is not recognized."), fragP->fr_subtype);
|
||||
}
|
||||
|
||||
return (fragP->fr_fix - old_fr_fix);
|
||||
if (fragP->fr_subtype >= sizeof (md_relax_table) / sizeof (md_relax_table[0]))
|
||||
as_fatal (_("Subtype %d is not recognized."), fragP->fr_subtype);
|
||||
|
||||
/* Return the size of the variable part of the frag. */
|
||||
return md_relax_table[fragP->fr_subtype].rlx_length;
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -1935,7 +1935,6 @@ md_convert_frag (abfd, sec, fragP)
|
||||
}
|
||||
|
||||
fragP->fr_fix += 2;
|
||||
fragP->fr_var = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
@ -2026,8 +2025,6 @@ md_convert_frag (abfd, sec, fragP)
|
||||
else
|
||||
buffer[1] = 4; /* jmpi, ptr, and the 'tail pad' */
|
||||
}
|
||||
|
||||
fragP->fr_var = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
@ -2082,8 +2079,6 @@ md_convert_frag (abfd, sec, fragP)
|
||||
fragP->fr_symbol, fragP->fr_offset, 0, BFD_RELOC_32);
|
||||
fragP->fr_fix += U32_LEN;
|
||||
}
|
||||
|
||||
fragP->fr_var = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
@ -2298,8 +2293,7 @@ md_estimate_size_before_relax (fragP, segment_type)
|
||||
break;
|
||||
}
|
||||
|
||||
fragP->fr_var = md_relax_table[fragP->fr_subtype].rlx_length;
|
||||
return fragP->fr_var;
|
||||
return md_relax_table[fragP->fr_subtype].rlx_length;
|
||||
}
|
||||
|
||||
/* Put number into target byte order. */
|
||||
|
@ -2069,21 +2069,11 @@ md_estimate_size_before_relax (fragP, segment)
|
||||
register fragS *fragP;
|
||||
segT segment;
|
||||
{
|
||||
int old_fix;
|
||||
|
||||
old_fix = fragP->fr_fix;
|
||||
|
||||
switch (fragP->fr_subtype)
|
||||
if (fragP->fr_subtype == IND (BRANCH, UNDEF))
|
||||
{
|
||||
case IND (BRANCH, UNDEF):
|
||||
if (S_GET_SEGMENT (fragP->fr_symbol) == segment)
|
||||
if (S_GET_SEGMENT (fragP->fr_symbol) != segment)
|
||||
{
|
||||
/* The symbol has been assigned a value. */
|
||||
fragP->fr_subtype = IND (BRANCH, BYTE);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* We don't relax symbols defined in an other segment the
|
||||
/* We don't relax symbols defined in another segment. The
|
||||
thing to do is to assume the object will occupy 4 bytes. */
|
||||
fix_new_ns32k (fragP,
|
||||
(int) (fragP->fr_fix),
|
||||
@ -2101,21 +2091,19 @@ md_estimate_size_before_relax (fragP, segment)
|
||||
fragP->fr_opcode[1] = 0xff;
|
||||
#endif
|
||||
frag_wane (fragP);
|
||||
break;
|
||||
return 4;
|
||||
}
|
||||
/* Fall thru */
|
||||
|
||||
case IND (BRANCH, BYTE):
|
||||
case IND (BRANCH, WORD):
|
||||
case IND (BRANCH, DOUBLE):
|
||||
fragP->fr_var = md_relax_table[fragP->fr_subtype].rlx_length;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
/* Relaxable case. Set up the initial guess for the variable
|
||||
part of the frag. */
|
||||
fragP->fr_subtype = IND (BRANCH, BYTE);
|
||||
}
|
||||
|
||||
return fragP->fr_var + fragP->fr_fix - old_fix;
|
||||
if (fragP->fr_subtype >= sizeof (md_relax_table) / sizeof (md_relax_table[0]))
|
||||
abort ();
|
||||
|
||||
/* Return the size of the variable part of the frag. */
|
||||
return md_relax_table[fragP->fr_subtype].rlx_length;
|
||||
}
|
||||
|
||||
int md_short_jump_size = 3;
|
||||
|
@ -277,8 +277,6 @@ md_estimate_size_before_relax (fragP, segment)
|
||||
fragS * fragP;
|
||||
segT segment;
|
||||
{
|
||||
int old_fr_fix = fragP->fr_fix;
|
||||
|
||||
/* The only thing we have to handle here are symbols outside of the
|
||||
current segment. They may be undefined or in a different segment in
|
||||
which case linker scripts may place them anywhere.
|
||||
@ -316,7 +314,7 @@ md_estimate_size_before_relax (fragP, segment)
|
||||
}
|
||||
}
|
||||
|
||||
return (fragP->fr_var + fragP->fr_fix - old_fr_fix);
|
||||
return md_relax_table[fragP->fr_subtype].rlx_length;
|
||||
}
|
||||
|
||||
/* *fragP has been relaxed to its final size, and now needs to have
|
||||
|
@ -245,8 +245,8 @@ pc_rel_disp? That sort of thing.) */
|
||||
#define C(a,b) ENCODE_RELAX(a,b)
|
||||
/* This macro has no side-effects. */
|
||||
#define ENCODE_RELAX(what,length) (((what) << 2) + (length))
|
||||
#define RELAX_STATE(what) ((what) >> 2)
|
||||
#define RELAX_LENGTH(length) ((length) && 3)
|
||||
#define RELAX_STATE(s) ((s) >> 2)
|
||||
#define RELAX_LENGTH(s) ((s) & 3)
|
||||
|
||||
#define STATE_ALWAYS_BRANCH (1)
|
||||
#define STATE_CONDITIONAL_BRANCH (2)
|
||||
@ -604,136 +604,113 @@ md_create_long_jump (ptr, from_addr, to_addr, frag, to_symbol)
|
||||
md_number_to_chars (ptr, offset, 4);
|
||||
}
|
||||
|
||||
/*
|
||||
* md_estimate_size_before_relax()
|
||||
*
|
||||
* Called just before relax().
|
||||
* Any symbol that is now undefined will not become defined, so we assumed
|
||||
* that it will be resolved by the linker.
|
||||
* Return the correct fr_subtype in the frag, for relax()
|
||||
* Return the initial "guess for fr_var" to caller. (How big I think this
|
||||
* will be.)
|
||||
* The guess for fr_var is ACTUALLY the growth beyond fr_fix.
|
||||
* Whatever we do to grow fr_fix or fr_var contributes to our returned value.
|
||||
* Although it may not be explicit in the frag, pretend fr_var starts with a
|
||||
* 0 value.
|
||||
*/
|
||||
/* md_estimate_size_before_relax(), called just before relax().
|
||||
Any symbol that is now undefined will not become defined.
|
||||
Return the correct fr_subtype in the frag and the growth beyond
|
||||
fr_fix. */
|
||||
int
|
||||
md_estimate_size_before_relax (fragP, segment_type)
|
||||
register fragS *fragP;
|
||||
segT segment_type; /* N_DATA or N_TEXT. */
|
||||
{
|
||||
register char *p;
|
||||
register int old_fr_fix;
|
||||
/* int pc_rel; FIXME: remove this */
|
||||
|
||||
old_fr_fix = fragP->fr_fix;
|
||||
switch (fragP->fr_subtype)
|
||||
if (RELAX_LENGTH (fragP->fr_subtype) == STATE_UNDF)
|
||||
{
|
||||
case ENCODE_RELAX (STATE_PC_RELATIVE, STATE_UNDF):
|
||||
if (S_GET_SEGMENT (fragP->fr_symbol) == segment_type)
|
||||
if (S_GET_SEGMENT (fragP->fr_symbol) != segment)
|
||||
{
|
||||
/* The symbol was in the same segment as the opcode, and it's
|
||||
a real pc_rel case so it's a relaxable case. */
|
||||
/* Non-relaxable cases. */
|
||||
char *p;
|
||||
int old_fr_fix;
|
||||
|
||||
old_fr_fix = fragP->fr_fix;
|
||||
p = fragP->fr_literal + old_fr_fix;
|
||||
switch (RELAX_STATE (fragP->fr_subtype))
|
||||
{
|
||||
case STATE_PC_RELATIVE:
|
||||
*p |= TAHOE_PC_OR_LONG;
|
||||
/* We now know how big it will be, one long word. */
|
||||
fragP->fr_fix += 1 + 4;
|
||||
fix_new (fragP, old_fr_fix + 1, fragP->fr_symbol,
|
||||
fragP->fr_offset, FX_PCREL32, NULL);
|
||||
break;
|
||||
|
||||
case STATE_CONDITIONAL_BRANCH:
|
||||
*fragP->fr_opcode ^= 0x10; /* Reverse sense of branch. */
|
||||
*p++ = 6;
|
||||
*p++ = TAHOE_JMP;
|
||||
*p++ = TAHOE_PC_REL_LONG;
|
||||
fragP->fr_fix += 1 + 1 + 1 + 4;
|
||||
fix_new (fragP, old_fr_fix + 3, fragP->fr_symbol,
|
||||
fragP->fr_offset, FX_PCREL32, NULL);
|
||||
break;
|
||||
|
||||
case STATE_BIG_REV_BRANCH:
|
||||
*fragP->fr_opcode ^= 0x10; /* Reverse sense of branch. */
|
||||
*p++ = 0;
|
||||
*p++ = 6;
|
||||
*p++ = TAHOE_JMP;
|
||||
*p++ = TAHOE_PC_REL_LONG;
|
||||
fragP->fr_fix += 2 + 2 + 4;
|
||||
fix_new (fragP, old_fr_fix + 4, fragP->fr_symbol,
|
||||
fragP->fr_offset, FX_PCREL32, NULL);
|
||||
break;
|
||||
|
||||
case STATE_BIG_NON_REV_BRANCH:
|
||||
*p++ = 2;
|
||||
*p++ = 0;
|
||||
*p++ = TAHOE_BRB;
|
||||
*p++ = 6;
|
||||
*p++ = TAHOE_JMP;
|
||||
*p++ = TAHOE_PC_REL_LONG;
|
||||
fragP->fr_fix += 2 + 2 + 2 + 4;
|
||||
fix_new (fragP, old_fr_fix + 6, fragP->fr_symbol,
|
||||
fragP->fr_offset, FX_PCREL32, NULL);
|
||||
break;
|
||||
|
||||
case STATE_ALWAYS_BRANCH:
|
||||
*fragP->fr_opcode = TAHOE_JMP;
|
||||
*p++ = TAHOE_PC_REL_LONG;
|
||||
fragP->fr_fix += 1 + 4;
|
||||
fix_new (fragP, old_fr_fix + 1, fragP->fr_symbol,
|
||||
fragP->fr_offset, FX_PCREL32, NULL);
|
||||
break;
|
||||
|
||||
default:
|
||||
abort ();
|
||||
}
|
||||
frag_wane (fragP);
|
||||
|
||||
/* Return the growth in the fixed part of the frag. */
|
||||
return fragP->fr_fix - old_fr_fix;
|
||||
}
|
||||
|
||||
/* Relaxable cases. Set up the initial guess for the variable
|
||||
part of the frag. */
|
||||
switch (RELAX_STATE (fragP->fr_subtype))
|
||||
{
|
||||
case STATE_PC_RELATIVE:
|
||||
fragP->fr_subtype = ENCODE_RELAX (STATE_PC_RELATIVE, STATE_BYTE);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* This case is still undefined, so asume it's a long word for the
|
||||
linker to fix. */
|
||||
p = fragP->fr_literal + old_fr_fix;
|
||||
*p |= TAHOE_PC_OR_LONG;
|
||||
/* We now know how big it will be, one long word. */
|
||||
fragP->fr_fix += 1 + 4;
|
||||
fix_new (fragP, old_fr_fix + 1, fragP->fr_symbol,
|
||||
fragP->fr_offset, FX_PCREL32, NULL);
|
||||
frag_wane (fragP);
|
||||
}
|
||||
break;
|
||||
|
||||
case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, STATE_UNDF):
|
||||
if (S_GET_SEGMENT (fragP->fr_symbol) == segment_type)
|
||||
{
|
||||
break;
|
||||
case STATE_CONDITIONAL_BRANCH:
|
||||
fragP->fr_subtype = ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, STATE_BYTE);
|
||||
}
|
||||
else
|
||||
{
|
||||
p = fragP->fr_literal + old_fr_fix;
|
||||
*fragP->fr_opcode ^= 0x10; /* Reverse sense of branch. */
|
||||
*p++ = 6;
|
||||
*p++ = TAHOE_JMP;
|
||||
*p++ = TAHOE_PC_REL_LONG;
|
||||
fragP->fr_fix += 1 + 1 + 1 + 4;
|
||||
fix_new (fragP, old_fr_fix + 3, fragP->fr_symbol,
|
||||
fragP->fr_offset, FX_PCREL32, NULL);
|
||||
frag_wane (fragP);
|
||||
}
|
||||
break;
|
||||
|
||||
case ENCODE_RELAX (STATE_BIG_REV_BRANCH, STATE_UNDF):
|
||||
if (S_GET_SEGMENT (fragP->fr_symbol) == segment_type)
|
||||
{
|
||||
fragP->fr_subtype =
|
||||
ENCODE_RELAX (STATE_BIG_REV_BRANCH, STATE_WORD);
|
||||
}
|
||||
else
|
||||
{
|
||||
p = fragP->fr_literal + old_fr_fix;
|
||||
*fragP->fr_opcode ^= 0x10; /* Reverse sense of branch. */
|
||||
*p++ = 0;
|
||||
*p++ = 6;
|
||||
*p++ = TAHOE_JMP;
|
||||
*p++ = TAHOE_PC_REL_LONG;
|
||||
fragP->fr_fix += 2 + 2 + 4;
|
||||
fix_new (fragP, old_fr_fix + 4, fragP->fr_symbol,
|
||||
fragP->fr_offset, FX_PCREL32, NULL);
|
||||
frag_wane (fragP);
|
||||
}
|
||||
break;
|
||||
|
||||
case ENCODE_RELAX (STATE_BIG_NON_REV_BRANCH, STATE_UNDF):
|
||||
if (S_GET_SEGMENT (fragP->fr_symbol) == segment_type)
|
||||
{
|
||||
break;
|
||||
case STATE_BIG_REV_BRANCH:
|
||||
fragP->fr_subtype = ENCODE_RELAX (STATE_BIG_REV_BRANCH, STATE_WORD);
|
||||
break;
|
||||
case STATE_BIG_NON_REV_BRANCH:
|
||||
fragP->fr_subtype = ENCODE_RELAX (STATE_BIG_NON_REV_BRANCH, STATE_WORD);
|
||||
}
|
||||
else
|
||||
{
|
||||
p = fragP->fr_literal + old_fr_fix;
|
||||
*p++ = 2;
|
||||
*p++ = 0;
|
||||
*p++ = TAHOE_BRB;
|
||||
*p++ = 6;
|
||||
*p++ = TAHOE_JMP;
|
||||
*p++ = TAHOE_PC_REL_LONG;
|
||||
fragP->fr_fix += 2 + 2 + 2 + 4;
|
||||
fix_new (fragP, old_fr_fix + 6, fragP->fr_symbol,
|
||||
fragP->fr_offset, FX_PCREL32, NULL);
|
||||
frag_wane (fragP);
|
||||
}
|
||||
break;
|
||||
|
||||
case ENCODE_RELAX (STATE_ALWAYS_BRANCH, STATE_UNDF):
|
||||
if (S_GET_SEGMENT (fragP->fr_symbol) == segment_type)
|
||||
{
|
||||
break;
|
||||
case STATE_ALWAYS_BRANCH:
|
||||
fragP->fr_subtype = ENCODE_RELAX (STATE_ALWAYS_BRANCH, STATE_BYTE);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
p = fragP->fr_literal + old_fr_fix;
|
||||
*fragP->fr_opcode = TAHOE_JMP;
|
||||
*p++ = TAHOE_PC_REL_LONG;
|
||||
fragP->fr_fix += 1 + 4;
|
||||
fix_new (fragP, old_fr_fix + 1, fragP->fr_symbol,
|
||||
fragP->fr_offset, FX_PCREL32, NULL);
|
||||
frag_wane (fragP);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return (fragP->fr_var + fragP->fr_fix - old_fr_fix);
|
||||
} /* md_estimate_size_before_relax() */
|
||||
|
||||
if (fragP->fr_subtype >= sizeof (md_relax_table) / sizeof (md_relax_table[0]))
|
||||
abort ();
|
||||
|
||||
/* Return the size of the variable part of the frag. */
|
||||
return md_relax_table[fragP->fr_subtype].rlx_length;
|
||||
}
|
||||
|
||||
/*
|
||||
* md_convert_frag();
|
||||
@ -754,7 +731,6 @@ md_convert_frag (headers, seg, fragP)
|
||||
{
|
||||
register char *addressP; /* -> _var to change. */
|
||||
register char *opcodeP; /* -> opcode char(s) to change. */
|
||||
register short int length_code; /* 2=long 1=word 0=byte */
|
||||
register short int extension = 0; /* Size of relaxed address.
|
||||
Added to fr_fix: incl. ALL var chars. */
|
||||
register symbolS *symbolP;
|
||||
@ -765,8 +741,6 @@ md_convert_frag (headers, seg, fragP)
|
||||
/* Where, in file space, does addr point? */
|
||||
|
||||
know (fragP->fr_type == rs_machine_dependent);
|
||||
length_code = RELAX_LENGTH (fragP->fr_subtype);
|
||||
know (length_code >= 0 && length_code < 3);
|
||||
where = fragP->fr_fix;
|
||||
addressP = fragP->fr_literal + where;
|
||||
opcodeP = fragP->fr_opcode;
|
||||
|
@ -604,8 +604,8 @@ const pseudo_typeS md_pseudo_table[] = {
|
||||
{"call_table_text", v850_call_table_text, 0},
|
||||
{"v850e", set_machine, bfd_mach_v850e},
|
||||
{"v850ea", set_machine, bfd_mach_v850ea},
|
||||
{"file", dwarf2_directive_file },
|
||||
{"loc", dwarf2_directive_loc },
|
||||
{"file", dwarf2_directive_file, 0},
|
||||
{"loc", dwarf2_directive_loc, 0},
|
||||
{ NULL, NULL, 0}
|
||||
};
|
||||
|
||||
@ -1321,7 +1321,6 @@ md_convert_frag (abfd, sec, fragP)
|
||||
{
|
||||
fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
|
||||
fragP->fr_offset, 1, BFD_RELOC_UNUSED + (int)fragP->fr_opcode);
|
||||
fragP->fr_var = 0;
|
||||
fragP->fr_fix += 2;
|
||||
}
|
||||
/* Out of range conditional branch. Emit a branch around a jump. */
|
||||
@ -1345,7 +1344,6 @@ md_convert_frag (abfd, sec, fragP)
|
||||
fix_new (fragP, fragP->fr_fix + 2, 4, fragP->fr_symbol,
|
||||
fragP->fr_offset, 1, BFD_RELOC_UNUSED +
|
||||
(int) fragP->fr_opcode + 1);
|
||||
fragP->fr_var = 0;
|
||||
fragP->fr_fix += 6;
|
||||
}
|
||||
/* Out of range unconditional branch. Emit a jump. */
|
||||
@ -1355,7 +1353,6 @@ md_convert_frag (abfd, sec, fragP)
|
||||
fix_new (fragP, fragP->fr_fix, 4, fragP->fr_symbol,
|
||||
fragP->fr_offset, 1, BFD_RELOC_UNUSED +
|
||||
(int) fragP->fr_opcode + 1);
|
||||
fragP->fr_var = 0;
|
||||
fragP->fr_fix += 4;
|
||||
}
|
||||
else
|
||||
@ -2315,20 +2312,17 @@ tc_gen_reloc (seg, fixp)
|
||||
return reloc;
|
||||
}
|
||||
|
||||
/* Assume everything will fit in two bytes, then expand as necessary. */
|
||||
/* Return current size of variable part of frag. */
|
||||
|
||||
int
|
||||
md_estimate_size_before_relax (fragp, seg)
|
||||
fragS *fragp;
|
||||
asection *seg ATTRIBUTE_UNUSED;
|
||||
{
|
||||
if (fragp->fr_subtype == 0)
|
||||
fragp->fr_var = 4;
|
||||
else if (fragp->fr_subtype == 2)
|
||||
fragp->fr_var = 2;
|
||||
else
|
||||
if (fragp->fr_subtype >= sizeof (md_relax_table) / sizeof (md_relax_table[0]))
|
||||
abort ();
|
||||
return 2;
|
||||
|
||||
return md_relax_table[fragp->fr_subtype].rlx_length;
|
||||
}
|
||||
|
||||
long
|
||||
|
@ -181,6 +181,8 @@ int flag_no_hash_mixed_case; /* -h NUM */
|
||||
#define C(a,b) ENCODE_RELAX(a,b)
|
||||
/* This macro has no side-effects. */
|
||||
#define ENCODE_RELAX(what,length) (((what) << 2) + (length))
|
||||
#define RELAX_STATE(s) ((s) >> 2)
|
||||
#define RELAX_LENGTH(s) ((s) & 3)
|
||||
|
||||
const relax_typeS md_relax_table[] =
|
||||
{
|
||||
@ -188,25 +190,31 @@ const relax_typeS md_relax_table[] =
|
||||
{1, 1, 0, 0}, /* unused 0,1 */
|
||||
{1, 1, 0, 0}, /* unused 0,2 */
|
||||
{1, 1, 0, 0}, /* unused 0,3 */
|
||||
|
||||
{BF + 1, BB + 1, 2, C (1, 1)},/* B^"foo" 1,0 */
|
||||
{WF + 1, WB + 1, 3, C (1, 2)},/* W^"foo" 1,1 */
|
||||
{0, 0, 5, 0}, /* L^"foo" 1,2 */
|
||||
{1, 1, 0, 0}, /* unused 1,3 */
|
||||
|
||||
{BF, BB, 1, C (2, 1)}, /* b<cond> B^"foo" 2,0 */
|
||||
{WF + 2, WB + 2, 4, C (2, 2)},/* br.+? brw X 2,1 */
|
||||
{0, 0, 7, 0}, /* br.+? jmp X 2,2 */
|
||||
{1, 1, 0, 0}, /* unused 2,3 */
|
||||
|
||||
{BF, BB, 1, C (3, 1)}, /* brb B^foo 3,0 */
|
||||
{WF, WB, 2, C (3, 2)}, /* brw W^foo 3,1 */
|
||||
{0, 0, 5, 0}, /* Jmp L^foo 3,2 */
|
||||
{1, 1, 0, 0}, /* unused 3,3 */
|
||||
|
||||
{1, 1, 0, 0}, /* unused 4,0 */
|
||||
{WF, WB, 2, C (4, 2)}, /* acb_ ^Wfoo 4,1 */
|
||||
{0, 0, 10, 0}, /* acb_,br,jmp L^foo4,2 */
|
||||
{1, 1, 0, 0}, /* unused 4,3 */
|
||||
|
||||
{BF, BB, 1, C (5, 1)}, /* Xob___,,foo 5,0 */
|
||||
{WF + 4, WB + 4, 6, C (5, 2)},/* Xob.+2,brb.+3,brw5,1 */
|
||||
{0, 0, 9, 0}, /* Xob.+2,brb.+6,jmp5,2 */
|
||||
{1, 1, 0, 0}, /* unused 5,3 */
|
||||
};
|
||||
|
||||
#undef C
|
||||
@ -1140,127 +1148,112 @@ md_assemble (instruction_string)
|
||||
} /* for(operandP) */
|
||||
} /* vax_assemble() */
|
||||
|
||||
/*
|
||||
* md_estimate_size_before_relax()
|
||||
*
|
||||
* Called just before relax().
|
||||
* Any symbol that is now undefined will not become defined.
|
||||
* Return the correct fr_subtype in the frag.
|
||||
* Return the initial "guess for fr_var" to caller.
|
||||
* The guess for fr_var is ACTUALLY the growth beyond fr_fix.
|
||||
* Whatever we do to grow fr_fix or fr_var contributes to our returned value.
|
||||
* Although it may not be explicit in the frag, pretend fr_var starts with a
|
||||
* 0 value.
|
||||
*/
|
||||
/* md_estimate_size_before_relax(), called just before relax().
|
||||
Any symbol that is now undefined will not become defined.
|
||||
Return the correct fr_subtype in the frag and the growth beyond
|
||||
fr_fix. */
|
||||
int
|
||||
md_estimate_size_before_relax (fragP, segment)
|
||||
fragS *fragP;
|
||||
segT segment;
|
||||
{
|
||||
char *p;
|
||||
int old_fr_fix;
|
||||
|
||||
old_fr_fix = fragP->fr_fix;
|
||||
switch (fragP->fr_subtype)
|
||||
if (RELAX_LENGTH (fragP->fr_subtype) == STATE_UNDF)
|
||||
{
|
||||
case ENCODE_RELAX (STATE_PC_RELATIVE, STATE_UNDF):
|
||||
if (S_GET_SEGMENT (fragP->fr_symbol) == segment)
|
||||
{ /* A relaxable case. */
|
||||
if (S_GET_SEGMENT (fragP->fr_symbol) != segment)
|
||||
{
|
||||
/* Non-relaxable cases. */
|
||||
char *p;
|
||||
int old_fr_fix;
|
||||
|
||||
old_fr_fix = fragP->fr_fix;
|
||||
p = fragP->fr_literal + old_fr_fix;
|
||||
switch (RELAX_STATE (fragP->fr_subtype))
|
||||
{
|
||||
case STATE_PC_RELATIVE:
|
||||
p[0] |= VAX_PC_RELATIVE_MODE; /* Preserve @ bit. */
|
||||
fragP->fr_fix += 1 + 4;
|
||||
fix_new (fragP, old_fr_fix + 1, 4, fragP->fr_symbol,
|
||||
fragP->fr_offset, 1, NO_RELOC);
|
||||
break;
|
||||
|
||||
case STATE_CONDITIONAL_BRANCH:
|
||||
*fragP->fr_opcode ^= 1; /* Reverse sense of branch. */
|
||||
p[0] = 6;
|
||||
p[1] = VAX_JMP;
|
||||
p[2] = VAX_PC_RELATIVE_MODE; /* ...(PC) */
|
||||
fragP->fr_fix += 1 + 1 + 1 + 4;
|
||||
fix_new (fragP, old_fr_fix + 3, 4, fragP->fr_symbol,
|
||||
fragP->fr_offset, 1, NO_RELOC);
|
||||
break;
|
||||
|
||||
case STATE_COMPLEX_BRANCH:
|
||||
p[0] = 2;
|
||||
p[1] = 0;
|
||||
p[2] = VAX_BRB;
|
||||
p[3] = 6;
|
||||
p[4] = VAX_JMP;
|
||||
p[5] = VAX_PC_RELATIVE_MODE; /* ...(pc) */
|
||||
fragP->fr_fix += 2 + 2 + 1 + 1 + 4;
|
||||
fix_new (fragP, old_fr_fix + 6, 4, fragP->fr_symbol,
|
||||
fragP->fr_offset, 1, NO_RELOC);
|
||||
break;
|
||||
|
||||
case STATE_COMPLEX_HOP:
|
||||
p[0] = 2;
|
||||
p[1] = VAX_BRB;
|
||||
p[2] = 6;
|
||||
p[3] = VAX_JMP;
|
||||
p[4] = VAX_PC_RELATIVE_MODE; /* ...(pc) */
|
||||
fragP->fr_fix += 1 + 2 + 1 + 1 + 4;
|
||||
fix_new (fragP, old_fr_fix + 5, 4, fragP->fr_symbol,
|
||||
fragP->fr_offset, 1, NO_RELOC);
|
||||
break;
|
||||
|
||||
case STATE_ALWAYS_BRANCH:
|
||||
*fragP->fr_opcode += VAX_WIDEN_LONG;
|
||||
p[0] = VAX_PC_RELATIVE_MODE; /* ...(PC) */
|
||||
fragP->fr_fix += 1 + 4;
|
||||
fix_new (fragP, old_fr_fix + 1, 4, fragP->fr_symbol,
|
||||
fragP->fr_offset, 1, NO_RELOC);
|
||||
break;
|
||||
|
||||
default:
|
||||
abort ();
|
||||
}
|
||||
frag_wane (fragP);
|
||||
|
||||
/* Return the growth in the fixed part of the frag. */
|
||||
return fragP->fr_fix - old_fr_fix;
|
||||
}
|
||||
|
||||
/* Relaxable cases. Set up the initial guess for the variable
|
||||
part of the frag. */
|
||||
switch (RELAX_STATE (fragP->fr_subtype))
|
||||
{
|
||||
case STATE_PC_RELATIVE:
|
||||
fragP->fr_subtype = ENCODE_RELAX (STATE_PC_RELATIVE, STATE_BYTE);
|
||||
}
|
||||
else
|
||||
{
|
||||
p = fragP->fr_literal + old_fr_fix;
|
||||
p[0] |= VAX_PC_RELATIVE_MODE; /* Preserve @ bit. */
|
||||
fragP->fr_fix += 1 + 4;
|
||||
fix_new (fragP, old_fr_fix + 1, 4, fragP->fr_symbol,
|
||||
fragP->fr_offset, 1, NO_RELOC);
|
||||
frag_wane (fragP);
|
||||
}
|
||||
break;
|
||||
|
||||
case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, STATE_UNDF):
|
||||
if (S_GET_SEGMENT (fragP->fr_symbol) == segment)
|
||||
{
|
||||
break;
|
||||
case STATE_CONDITIONAL_BRANCH:
|
||||
fragP->fr_subtype = ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, STATE_BYTE);
|
||||
}
|
||||
else
|
||||
{
|
||||
p = fragP->fr_literal + old_fr_fix;
|
||||
*fragP->fr_opcode ^= 1; /* Reverse sense of branch. */
|
||||
p[0] = 6;
|
||||
p[1] = VAX_JMP;
|
||||
p[2] = VAX_PC_RELATIVE_MODE; /* ...(PC) */
|
||||
fragP->fr_fix += 1 + 1 + 1 + 4;
|
||||
fix_new (fragP, old_fr_fix + 3, 4, fragP->fr_symbol,
|
||||
fragP->fr_offset, 1, NO_RELOC);
|
||||
frag_wane (fragP);
|
||||
}
|
||||
break;
|
||||
|
||||
case ENCODE_RELAX (STATE_COMPLEX_BRANCH, STATE_UNDF):
|
||||
if (S_GET_SEGMENT (fragP->fr_symbol) == segment)
|
||||
{
|
||||
break;
|
||||
case STATE_COMPLEX_BRANCH:
|
||||
fragP->fr_subtype = ENCODE_RELAX (STATE_COMPLEX_BRANCH, STATE_WORD);
|
||||
}
|
||||
else
|
||||
{
|
||||
p = fragP->fr_literal + old_fr_fix;
|
||||
p[0] = 2;
|
||||
p[1] = 0;
|
||||
p[2] = VAX_BRB;
|
||||
p[3] = 6;
|
||||
p[4] = VAX_JMP;
|
||||
p[5] = VAX_PC_RELATIVE_MODE; /* ...(pc) */
|
||||
fragP->fr_fix += 2 + 2 + 1 + 1 + 4;
|
||||
fix_new (fragP, old_fr_fix + 6, 4, fragP->fr_symbol,
|
||||
fragP->fr_offset, 1, NO_RELOC);
|
||||
frag_wane (fragP);
|
||||
}
|
||||
break;
|
||||
|
||||
case ENCODE_RELAX (STATE_COMPLEX_HOP, STATE_UNDF):
|
||||
if (S_GET_SEGMENT (fragP->fr_symbol) == segment)
|
||||
{
|
||||
break;
|
||||
case STATE_COMPLEX_HOP:
|
||||
fragP->fr_subtype = ENCODE_RELAX (STATE_COMPLEX_HOP, STATE_BYTE);
|
||||
}
|
||||
else
|
||||
{
|
||||
p = fragP->fr_literal + old_fr_fix;
|
||||
p[0] = 2;
|
||||
p[1] = VAX_BRB;
|
||||
p[2] = 6;
|
||||
p[3] = VAX_JMP;
|
||||
p[4] = VAX_PC_RELATIVE_MODE; /* ...(pc) */
|
||||
fragP->fr_fix += 1 + 2 + 1 + 1 + 4;
|
||||
fix_new (fragP, old_fr_fix + 5, 4, fragP->fr_symbol,
|
||||
fragP->fr_offset, 1, NO_RELOC);
|
||||
frag_wane (fragP);
|
||||
}
|
||||
break;
|
||||
|
||||
case ENCODE_RELAX (STATE_ALWAYS_BRANCH, STATE_UNDF):
|
||||
if (S_GET_SEGMENT (fragP->fr_symbol) == segment)
|
||||
{
|
||||
break;
|
||||
case STATE_ALWAYS_BRANCH:
|
||||
fragP->fr_subtype = ENCODE_RELAX (STATE_ALWAYS_BRANCH, STATE_BYTE);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
p = fragP->fr_literal + old_fr_fix;
|
||||
*fragP->fr_opcode += VAX_WIDEN_LONG;
|
||||
p[0] = VAX_PC_RELATIVE_MODE; /* ...(PC) */
|
||||
fragP->fr_fix += 1 + 4;
|
||||
fix_new (fragP, old_fr_fix + 1, 4, fragP->fr_symbol,
|
||||
fragP->fr_offset, 1, NO_RELOC);
|
||||
frag_wane (fragP);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return (fragP->fr_var + fragP->fr_fix - old_fr_fix);
|
||||
} /* md_estimate_size_before_relax() */
|
||||
|
||||
if (fragP->fr_subtype >= sizeof (md_relax_table) / sizeof (md_relax_table[0]))
|
||||
abort ();
|
||||
|
||||
/* Return the size of the variable part of the frag. */
|
||||
return md_relax_table[fragP->fr_subtype].rlx_length;
|
||||
}
|
||||
|
||||
/*
|
||||
* md_convert_frag();
|
||||
@ -1281,7 +1274,6 @@ md_convert_frag (headers, seg, fragP)
|
||||
{
|
||||
char *addressP; /* -> _var to change. */
|
||||
char *opcodeP; /* -> opcode char(s) to change. */
|
||||
short int length_code; /* 2=long 1=word 0=byte */
|
||||
short int extension = 0; /* Size of relaxed address. */
|
||||
/* Added to fr_fix: incl. ALL var chars. */
|
||||
symbolS *symbolP;
|
||||
@ -1292,8 +1284,6 @@ md_convert_frag (headers, seg, fragP)
|
||||
/* Where, in file space, does addr point? */
|
||||
|
||||
know (fragP->fr_type == rs_machine_dependent);
|
||||
length_code = fragP->fr_subtype & 3; /* depends on ENCODE_RELAX() */
|
||||
know (length_code >= 0 && length_code < 3);
|
||||
where = fragP->fr_fix;
|
||||
addressP = fragP->fr_literal + where;
|
||||
opcodeP = fragP->fr_opcode;
|
||||
|
Loading…
Reference in New Issue
Block a user