Redesign and clean up the relaxation mechanism.
This commit is contained in:
parent
36bdbeeca5
commit
151337e879
2 changed files with 351 additions and 389 deletions
|
@ -1,3 +1,9 @@
|
|||
2000-09-22 Michael Sokolov <msokolov@ivan.Harhan.ORG>
|
||||
|
||||
* config/tc-m68k.c (md_relax_table, m68k_ip, md_convert_frag_1,
|
||||
md_estimate_size_before_relax): Redesign and clean up the
|
||||
relaxation mechanism.
|
||||
|
||||
2000-09-21 Kazu Hirata <kazu@hxi.com>
|
||||
|
||||
* config/tc-ns32k.c: Fix formatting.
|
||||
|
|
|
@ -133,35 +133,6 @@ static struct label_line *current_label;
|
|||
/* See flames below */
|
||||
static struct obstack robyn;
|
||||
|
||||
#define TAB(x,y) (((x)<<2)+(y))
|
||||
#define TABTYPE(xy) ((xy) >> 2)
|
||||
#define BYTE 0
|
||||
#define SHORT 1
|
||||
#define LONG 2
|
||||
#define SZ_UNDEF 3
|
||||
#undef BRANCH
|
||||
/* Case `g' except when BCC68000 is applicable. */
|
||||
#define ABRANCH 1
|
||||
/* Coprocessor branches. */
|
||||
#define FBRANCH 2
|
||||
/* Mode 7.2 -- program counter indirect with (16-bit) displacement,
|
||||
supported on all cpus. Widens to 32-bit absolute. */
|
||||
#define PCREL 3
|
||||
/* For inserting an extra jmp instruction with long offset on 68000,
|
||||
for expanding conditional branches. (Not bsr or bra.) Since the
|
||||
68000 doesn't support 32-bit displacements for conditional
|
||||
branches, we fake it by reversing the condition and branching
|
||||
around a jmp with an absolute long operand. */
|
||||
#define BCC68000 4
|
||||
/* For the DBcc "instructions". If the displacement requires 32 bits,
|
||||
the branch-around-a-jump game is played here too. */
|
||||
#define DBCC 5
|
||||
/* Not currently used? */
|
||||
#define PCLEA 6
|
||||
/* Mode AINDX (apc-relative) using PC, with variable target, might fit
|
||||
in 16 or 8 bits. */
|
||||
#define PCINDEX 7
|
||||
|
||||
struct m68k_incant
|
||||
{
|
||||
const char *m_operands;
|
||||
|
@ -433,11 +404,60 @@ static const struct m68k_cpu archs[] = {
|
|||
|
||||
static const int n_archs = sizeof (archs) / sizeof (archs[0]);
|
||||
|
||||
/* BCC68000 is for patching in an extra jmp instruction for long offsets
|
||||
on the 68000. The 68000 doesn't support long branches with branchs */
|
||||
/* This is the assembler relaxation table for m68k. m68k is a rich CISC
|
||||
architecture and we have a lot of relaxation modes. */
|
||||
|
||||
/* This table desribes how you change sizes for the various types of variable
|
||||
size expressions. This version only supports two kinds. */
|
||||
/* Macros used in the relaxation code. */
|
||||
#define TAB(x,y) (((x) << 2) + (y))
|
||||
#define TABTYPE(x) ((x) >> 2)
|
||||
|
||||
/* Relaxation states. */
|
||||
#define BYTE 0
|
||||
#define SHORT 1
|
||||
#define LONG 2
|
||||
#define SZ_UNDEF 3
|
||||
|
||||
/* Here are all the relaxation modes we support. First we can relax ordinary
|
||||
branches. On 68020 and higher and on CPU32 all branch instructions take
|
||||
three forms, so on these CPUs all branches always remain as such. When we
|
||||
have to expand to the LONG form on a 68000, though, we substitute an
|
||||
absolute jump instead. This is a direct replacement for unconditional
|
||||
branches and a branch over a jump for conditional branches. However, if the
|
||||
user requires PIC and disables this with --pcrel, we can only relax between
|
||||
BYTE and SHORT forms, punting if that isn't enough. This gives us four
|
||||
different relaxation modes for branches: */
|
||||
|
||||
#define BRANCHBWL 1 /* branch byte, word, or long */
|
||||
#define BRABSJUNC 2 /* absolute jump for LONG, unconditional */
|
||||
#define BRABSJCOND 3 /* absolute jump for LONG, conditional */
|
||||
#define BRANCHBW 4 /* branch byte or word */
|
||||
|
||||
/* We also relax coprocessor branches and DBcc's. All CPUs that support
|
||||
coprocessor branches support them in word and long forms, so we have only
|
||||
one relaxation mode for them. DBcc's are word only on all CPUs. We can
|
||||
relax them to the LONG form with a branch-around sequence. This sequence
|
||||
can use a long branch (if available) or an absolute jump (if acceptable).
|
||||
This gives us two relaxation modes. If long branches are not available and
|
||||
absolute jumps are not acceptable, we don't relax DBcc's. */
|
||||
|
||||
#define FBRANCH 5 /* coprocessor branch */
|
||||
#define DBCCLBR 6 /* DBcc relaxable with a long branch */
|
||||
#define DBCCABSJ 7 /* DBcc relaxable with an absolute jump */
|
||||
|
||||
/* That's all for instruction relaxation. However, we also relax PC-relative
|
||||
operands. Specifically, we have three operand relaxation modes. On the
|
||||
68000 PC-relative operands can only be 16-bit, but on 68020 and higher and
|
||||
on CPU32 they may be 16-bit or 32-bit. For the latter we relax between the
|
||||
two. Also PC+displacement+index operands in their simple form (with a non-
|
||||
suppressed index without memory indirection) are supported on all CPUs, but
|
||||
on the 68000 the displacement can be 8-bit only, whereas on 68020 and higher
|
||||
and on CPU32 we relax it to SHORT and LONG forms as well using the extended
|
||||
form of the PC+displacement+index operand. Finally, some absolute operands
|
||||
can be relaxed down to 16-bit PC-relative. */
|
||||
|
||||
#define PCREL1632 8 /* 16-bit or 32-bit PC-relative */
|
||||
#define PCINDEX 9 /* PC+displacement+index */
|
||||
#define ABSTOPCREL 10 /* absolute relax down to 16-bit PC-relative */
|
||||
|
||||
/* Note that calls to frag_var need to specify the maximum expansion
|
||||
needed; this is currently 10 bytes for DBCC. */
|
||||
|
@ -455,41 +475,55 @@ relax_typeS md_relax_table[] =
|
|||
{1, 1, 0, 0}, /* that the VAX doesn't either */
|
||||
{1, 1, 0, 0},
|
||||
|
||||
{(127), (-128), 0, TAB (ABRANCH, SHORT)},
|
||||
{(32767), (-32768), 2, TAB (ABRANCH, LONG)},
|
||||
{(127), (-128), 0, TAB (BRANCHBWL, SHORT)},
|
||||
{(32767), (-32768), 2, TAB (BRANCHBWL, LONG)},
|
||||
{0, 0, 4, 0},
|
||||
{1, 1, 0, 0},
|
||||
|
||||
{(127), (-128), 0, TAB (BRABSJUNC, SHORT)},
|
||||
{(32767), (-32768), 2, TAB (BRABSJUNC, LONG)},
|
||||
{0, 0, 4, 0},
|
||||
{1, 1, 0, 0},
|
||||
|
||||
{(127), (-128), 0, TAB (BRABSJCOND, SHORT)},
|
||||
{(32767), (-32768), 2, TAB (BRABSJCOND, LONG)},
|
||||
{0, 0, 6, 0},
|
||||
{1, 1, 0, 0},
|
||||
|
||||
{(127), (-128), 0, TAB (BRANCHBW, SHORT)},
|
||||
{0, 0, 2, 0},
|
||||
{1, 1, 0, 0},
|
||||
{1, 1, 0, 0},
|
||||
|
||||
{1, 1, 0, 0}, /* FBRANCH doesn't come BYTE */
|
||||
{(32767), (-32768), 2, TAB (FBRANCH, LONG)},
|
||||
{0, 0, 4, 0},
|
||||
{1, 1, 0, 0},
|
||||
|
||||
{1, 1, 0, 0}, /* PCREL doesn't come BYTE */
|
||||
{(32767), (-32768), 2, TAB (PCREL, LONG)},
|
||||
{0, 0, 4, 0},
|
||||
{1, 1, 0, 0},
|
||||
|
||||
{(127), (-128), 0, TAB (BCC68000, SHORT)},
|
||||
{(32767), (-32768), 2, TAB (BCC68000, LONG)},
|
||||
{0, 0, 6, 0}, /* jmp long space */
|
||||
{1, 1, 0, 0}, /* DBCC doesn't come BYTE */
|
||||
{(32767), (-32768), 2, TAB (DBCCLBR, LONG)},
|
||||
{0, 0, 10, 0},
|
||||
{1, 1, 0, 0},
|
||||
|
||||
{1, 1, 0, 0}, /* DBCC doesn't come BYTE */
|
||||
{(32767), (-32768), 2, TAB (DBCC, LONG)},
|
||||
{0, 0, 10, 0}, /* bra/jmp long space */
|
||||
{(32767), (-32768), 2, TAB (DBCCABSJ, LONG)},
|
||||
{0, 0, 10, 0},
|
||||
{1, 1, 0, 0},
|
||||
|
||||
{1, 1, 0, 0}, /* PCLEA doesn't come BYTE */
|
||||
{32767, -32768, 2, TAB (PCLEA, LONG)},
|
||||
{1, 1, 0, 0}, /* PCREL1632 doesn't come BYTE */
|
||||
{32767, -32768, 2, TAB (PCREL1632, LONG)},
|
||||
{0, 0, 6, 0},
|
||||
{1, 1, 0, 0},
|
||||
|
||||
/* For, e.g., jmp pcrel indexed. */
|
||||
{125, -130, 0, TAB (PCINDEX, SHORT)},
|
||||
{32765, -32770, 2, TAB (PCINDEX, LONG)},
|
||||
{0, 0, 4, 0},
|
||||
{1, 1, 0, 0},
|
||||
|
||||
{1, 1, 0, 0}, /* ABSTOPCREL doesn't come BYTE */
|
||||
{(32767), (-32768), 2, TAB (ABSTOPCREL, LONG)},
|
||||
{0, 0, 4, 0},
|
||||
{1, 1, 0, 0},
|
||||
};
|
||||
|
||||
/* These are the machine dependent pseudo-ops. These are included so
|
||||
|
@ -2064,7 +2098,7 @@ m68k_ip (instring)
|
|||
{
|
||||
add_frag (adds (&opP->disp),
|
||||
offs (&opP->disp),
|
||||
TAB (PCLEA, SZ_UNDEF));
|
||||
TAB (PCREL1632, SZ_UNDEF));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -2372,15 +2406,13 @@ m68k_ip (instring)
|
|||
cannot be relaxed. */
|
||||
&& opP->disp.pic_reloc == pic_none
|
||||
#endif
|
||||
&& S_GET_SEGMENT (adds (&opP->disp)) == now_seg
|
||||
&& relaxable_symbol (adds (&opP->disp))
|
||||
&& !flag_long_jumps
|
||||
&& !strchr ("~%&$?", s[0]))
|
||||
{
|
||||
tmpreg = 0x3A; /* 7.2 */
|
||||
add_frag (adds (&opP->disp),
|
||||
offs (&opP->disp),
|
||||
TAB (PCREL, SZ_UNDEF));
|
||||
TAB (ABSTOPCREL, SZ_UNDEF));
|
||||
break;
|
||||
}
|
||||
/* Fall through into long */
|
||||
|
@ -2512,9 +2544,9 @@ m68k_ip (instring)
|
|||
break;
|
||||
case 'L':
|
||||
long_branch:
|
||||
if (!HAVE_LONG_BRANCH(current_architecture))
|
||||
as_warn (_("Can't use long branches on 68000/68010/5200"));
|
||||
the_ins.opcode[the_ins.numo - 1] |= 0xff;
|
||||
if (! HAVE_LONG_BRANCH (current_architecture))
|
||||
as_warn (_("Can't use long branches on 68000/68010/5200"));
|
||||
the_ins.opcode[0] |= 0xff;
|
||||
add_fix ('l', &opP->disp, 1, 0);
|
||||
addword (0);
|
||||
addword (0);
|
||||
|
@ -2529,37 +2561,66 @@ m68k_ip (instring)
|
|||
if (opP->disp.pic_reloc != pic_none)
|
||||
goto long_branch;
|
||||
#endif
|
||||
|
||||
/* This could either be a symbol, or an absolute
|
||||
address. No matter, the frag hacking will finger it
|
||||
out. Not quite: it can't switch from BRANCH to
|
||||
BCC68000 for the case where opnd is absolute (it
|
||||
needs to use the 68000 hack since no conditional abs
|
||||
jumps). */
|
||||
if (( !HAVE_LONG_BRANCH(current_architecture)
|
||||
|| (0 == adds (&opP->disp)))
|
||||
&& (the_ins.opcode[0] >= 0x6200)
|
||||
&& (the_ins.opcode[0] <= 0x6f00))
|
||||
address. If it's an absolute address, turn it into
|
||||
an absolute jump right here and keep it out of the
|
||||
relaxer. */
|
||||
if (adds (&opP->disp) == 0)
|
||||
{
|
||||
if (the_ins.opcode[0] == 0x6000) /* jbra */
|
||||
the_ins.opcode[0] = 0x4EF1;
|
||||
else if (the_ins.opcode[0] == 0x6100) /* jbsr */
|
||||
the_ins.opcode[0] = 0x4EB1;
|
||||
else /* jCC */
|
||||
{
|
||||
the_ins.opcode[0] ^= 0x0100;
|
||||
the_ins.opcode[0] |= 0x0006;
|
||||
addword (0x4EF1);
|
||||
}
|
||||
add_fix ('l', &opP->disp, 0, 0);
|
||||
addword (0);
|
||||
addword (0);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Now we know it's going into the relaxer. Now figure
|
||||
out which mode. We try in this order of preference:
|
||||
long branch, absolute jump, byte/word branches only. */
|
||||
if (HAVE_LONG_BRANCH (current_architecture))
|
||||
add_frag (adds (&opP->disp), offs (&opP->disp),
|
||||
TAB (BCC68000, SZ_UNDEF));
|
||||
TAB (BRANCHBWL, SZ_UNDEF));
|
||||
else if (! flag_keep_pcrel)
|
||||
{
|
||||
if ((the_ins.opcode[0] == 0x6000)
|
||||
|| (the_ins.opcode[0] == 0x6100))
|
||||
add_frag (adds (&opP->disp), offs (&opP->disp),
|
||||
TAB (BRABSJUNC, SZ_UNDEF));
|
||||
else
|
||||
add_frag (adds (&opP->disp), offs (&opP->disp),
|
||||
TAB (BRABSJCOND, SZ_UNDEF));
|
||||
}
|
||||
else
|
||||
add_frag (adds (&opP->disp), offs (&opP->disp),
|
||||
TAB (ABRANCH, SZ_UNDEF));
|
||||
TAB (BRANCHBW, SZ_UNDEF));
|
||||
break;
|
||||
case 'w':
|
||||
if (isvar (&opP->disp))
|
||||
{
|
||||
#if 1
|
||||
/* check for DBcc instruction */
|
||||
if ((the_ins.opcode[0] & 0xf0f8) == 0x50c8)
|
||||
/* Check for DBcc instructions. We can relax them,
|
||||
but only if we have long branches and/or absolute
|
||||
jumps. */
|
||||
if (((the_ins.opcode[0] & 0xf0f8) == 0x50c8)
|
||||
&& (HAVE_LONG_BRANCH (current_architecture)
|
||||
|| (! flag_keep_pcrel)))
|
||||
{
|
||||
/* size varies if patch */
|
||||
/* needed for long form */
|
||||
add_frag (adds (&opP->disp), offs (&opP->disp),
|
||||
TAB (DBCC, SZ_UNDEF));
|
||||
if (HAVE_LONG_BRANCH (current_architecture))
|
||||
add_frag (adds (&opP->disp), offs (&opP->disp),
|
||||
TAB (DBCCLBR, SZ_UNDEF));
|
||||
else
|
||||
add_frag (adds (&opP->disp), offs (&opP->disp),
|
||||
TAB (DBCCABSJ, SZ_UNDEF));
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
add_fix ('w', &opP->disp, 1, 0);
|
||||
}
|
||||
addword (0);
|
||||
|
@ -2570,23 +2631,16 @@ m68k_ip (instring)
|
|||
addword (0);
|
||||
break;
|
||||
case 'c': /* Var size Coprocesssor branches */
|
||||
if (subs (&opP->disp))
|
||||
if (subs (&opP->disp) || (adds (&opP->disp) == 0))
|
||||
{
|
||||
add_fix ('l', &opP->disp, 1, 0);
|
||||
add_frag ((symbolS *) 0, (offsetT) 0, TAB (FBRANCH, LONG));
|
||||
}
|
||||
else if (adds (&opP->disp))
|
||||
add_frag (adds (&opP->disp), offs (&opP->disp),
|
||||
TAB (FBRANCH, SZ_UNDEF));
|
||||
else
|
||||
{
|
||||
/* add_frag ((symbolS *) 0, offs (&opP->disp),
|
||||
TAB(FBRANCH,SHORT)); */
|
||||
the_ins.opcode[the_ins.numo - 1] |= 0x40;
|
||||
add_fix ('l', &opP->disp, 1, 0);
|
||||
addword (0);
|
||||
addword (0);
|
||||
}
|
||||
else
|
||||
add_frag (adds (&opP->disp), offs (&opP->disp),
|
||||
TAB (FBRANCH, SZ_UNDEF));
|
||||
break;
|
||||
default:
|
||||
abort ();
|
||||
|
@ -4275,7 +4329,6 @@ md_convert_frag_1 (fragP)
|
|||
register fragS *fragP;
|
||||
{
|
||||
long disp;
|
||||
long ext = 0;
|
||||
fixS *fixP;
|
||||
|
||||
/* Address in object code of the displacement. */
|
||||
|
@ -4298,76 +4351,59 @@ md_convert_frag_1 (fragP)
|
|||
|
||||
switch (fragP->fr_subtype)
|
||||
{
|
||||
case TAB (BCC68000, BYTE):
|
||||
case TAB (ABRANCH, BYTE):
|
||||
case TAB (BRANCHBWL, BYTE):
|
||||
case TAB (BRABSJUNC, BYTE):
|
||||
case TAB (BRABSJCOND, BYTE):
|
||||
case TAB (BRANCHBW, BYTE):
|
||||
know (issbyte (disp));
|
||||
if (disp == 0)
|
||||
as_bad (_("short branch with zero offset: use :w"));
|
||||
fragP->fr_opcode[1] = disp;
|
||||
ext = 0;
|
||||
fixP = fix_new (fragP, fragP->fr_fix - 1, 1, fragP->fr_symbol,
|
||||
fragP->fr_offset, 1, BFD_RELOC_8_PCREL);
|
||||
fixP->fx_pcrel_adjust = -1;
|
||||
break;
|
||||
case TAB (DBCC, SHORT):
|
||||
know (issword (disp));
|
||||
ext = 2;
|
||||
break;
|
||||
case TAB (BCC68000, SHORT):
|
||||
case TAB (ABRANCH, SHORT):
|
||||
know (issword (disp));
|
||||
case TAB (BRANCHBWL, SHORT):
|
||||
case TAB (BRABSJUNC, SHORT):
|
||||
case TAB (BRABSJCOND, SHORT):
|
||||
case TAB (BRANCHBW, SHORT):
|
||||
fragP->fr_opcode[1] = 0x00;
|
||||
ext = 2;
|
||||
fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol, fragP->fr_offset,
|
||||
1, BFD_RELOC_16_PCREL);
|
||||
fragP->fr_fix += 2;
|
||||
break;
|
||||
case TAB (ABRANCH, LONG):
|
||||
if (!HAVE_LONG_BRANCH (current_architecture))
|
||||
case TAB (BRANCHBWL, LONG):
|
||||
fragP->fr_opcode[1] = (char) 0xFF;
|
||||
fix_new (fragP, fragP->fr_fix, 4, fragP->fr_symbol, fragP->fr_offset,
|
||||
1, BFD_RELOC_32_PCREL);
|
||||
fragP->fr_fix += 4;
|
||||
break;
|
||||
case TAB (BRABSJUNC, LONG):
|
||||
if (fragP->fr_opcode[0] == 0x61) /* jbsr */
|
||||
{
|
||||
if (flag_keep_pcrel)
|
||||
as_bad (_("long branch not supported"));
|
||||
|
||||
if (fragP->fr_opcode[0] == 0x61)
|
||||
/* BSR */
|
||||
{
|
||||
fragP->fr_opcode[0] = 0x4E;
|
||||
fragP->fr_opcode[1] = (char) 0xB9; /* JBSR with ABSL LONG offset */
|
||||
|
||||
fix_new (fragP,
|
||||
fragP->fr_fix,
|
||||
4,
|
||||
fragP->fr_symbol,
|
||||
fragP->fr_offset,
|
||||
0,
|
||||
NO_RELOC);
|
||||
|
||||
fragP->fr_fix += 4;
|
||||
ext = 0;
|
||||
}
|
||||
/* BRA */
|
||||
else if (fragP->fr_opcode[0] == 0x60)
|
||||
{
|
||||
fragP->fr_opcode[0] = 0x4E;
|
||||
fragP->fr_opcode[1] = (char) 0xF9; /* JMP with ABSL LONG offset */
|
||||
fix_new (fragP, fragP->fr_fix, 4, fragP->fr_symbol,
|
||||
fragP->fr_offset, 0, NO_RELOC);
|
||||
fragP->fr_fix += 4;
|
||||
ext = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* This should never happen, because if it's a conditional
|
||||
branch and we are on a 68000, BCC68000 should have been
|
||||
picked instead of ABRANCH. */
|
||||
abort ();
|
||||
}
|
||||
fragP->fr_opcode[0] = 0x4E;
|
||||
fragP->fr_opcode[1] = (char) 0xB9; /* JSR with ABSL LONG operand */
|
||||
fix_new (fragP, fragP->fr_fix, 4, fragP->fr_symbol, fragP->fr_offset,
|
||||
0, BFD_RELOC_32);
|
||||
fragP->fr_fix += 4;
|
||||
}
|
||||
else if (fragP->fr_opcode[0] == 0x60) /* jbra */
|
||||
{
|
||||
fragP->fr_opcode[0] = 0x4E;
|
||||
fragP->fr_opcode[1] = (char) 0xF9; /* JMP with ABSL LONG operand */
|
||||
fix_new (fragP, fragP->fr_fix, 4, fragP->fr_symbol, fragP->fr_offset,
|
||||
0, BFD_RELOC_32);
|
||||
fragP->fr_fix += 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
fragP->fr_opcode[1] = (char) 0xff;
|
||||
ext = 4;
|
||||
/* This cannot happen, because jbsr and jbra are the only two
|
||||
unconditional branches. */
|
||||
abort ();
|
||||
}
|
||||
break;
|
||||
case TAB (BCC68000, LONG):
|
||||
/* only Bcc 68000 instructions can come here */
|
||||
/* change bcc into b!cc/jmp absl long */
|
||||
if (flag_keep_pcrel)
|
||||
as_bad (_("long branch not supported"));
|
||||
case TAB (BRABSJCOND, LONG):
|
||||
/* Only Bcc 68000 instructions can come here. */
|
||||
/* Change bcc into b!cc/jmp absl long. */
|
||||
|
||||
fragP->fr_opcode[0] ^= 0x01; /* invert bcc */
|
||||
fragP->fr_opcode[1] = 0x6;/* branch offset = 6 */
|
||||
|
@ -4379,125 +4415,120 @@ md_convert_frag_1 (fragP)
|
|||
*buffer_address++ = (char) 0xf9;
|
||||
fragP->fr_fix += 2; /* account for jmp instruction */
|
||||
fix_new (fragP, fragP->fr_fix, 4, fragP->fr_symbol,
|
||||
fragP->fr_offset, 0, NO_RELOC);
|
||||
fragP->fr_offset, 0, BFD_RELOC_32);
|
||||
fragP->fr_fix += 4;
|
||||
ext = 0;
|
||||
break;
|
||||
case TAB (DBCC, LONG):
|
||||
/* only DBcc 68000 instructions can come here */
|
||||
case TAB (FBRANCH, SHORT):
|
||||
know ((fragP->fr_opcode[1] & 0x40) == 0);
|
||||
fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol, fragP->fr_offset,
|
||||
1, BFD_RELOC_16_PCREL);
|
||||
fragP->fr_fix += 2;
|
||||
break;
|
||||
case TAB (FBRANCH, LONG):
|
||||
fragP->fr_opcode[1] |= 0x40; /* Turn on LONG bit */
|
||||
fix_new (fragP, fragP->fr_fix, 4, fragP->fr_symbol, fragP->fr_offset,
|
||||
1, BFD_RELOC_32_PCREL);
|
||||
fragP->fr_fix += 4;
|
||||
break;
|
||||
case TAB (DBCCLBR, SHORT):
|
||||
case TAB (DBCCABSJ, SHORT):
|
||||
fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol, fragP->fr_offset,
|
||||
1, BFD_RELOC_16_PCREL);
|
||||
fragP->fr_fix += 2;
|
||||
break;
|
||||
case TAB (DBCCLBR, LONG):
|
||||
/* only DBcc instructions can come here */
|
||||
/* Change dbcc into dbcc/bral. */
|
||||
if (! HAVE_LONG_BRANCH (current_architecture) && flag_keep_pcrel)
|
||||
as_bad (_("long branch not supported"));
|
||||
|
||||
/* JF: these used to be fr_opcode[2-7], but that's wrong */
|
||||
*buffer_address++ = 0x00; /* branch offset = 4 */
|
||||
*buffer_address++ = 0x04;
|
||||
*buffer_address++ = 0x60; /* put in bra pc+6 */
|
||||
*buffer_address++ = 0x06;
|
||||
if (HAVE_LONG_BRANCH (current_architecture))
|
||||
{
|
||||
*buffer_address++ = 0x60; /* Put in bral (0x60ff). */
|
||||
*buffer_address++ = (char) 0xff;
|
||||
}
|
||||
else
|
||||
{
|
||||
*buffer_address++ = 0x4e; /* Put in jmp long (0x4ef9). */
|
||||
*buffer_address++ = (char) 0xf9;
|
||||
}
|
||||
*buffer_address++ = 0x60; /* Put in bral (0x60ff). */
|
||||
*buffer_address++ = (char) 0xff;
|
||||
|
||||
fragP->fr_fix += 6; /* account for bra/jmp instructions */
|
||||
fix_new (fragP, fragP->fr_fix, 4, fragP->fr_symbol,
|
||||
fragP->fr_offset, HAVE_LONG_BRANCH (current_architecture),
|
||||
NO_RELOC);
|
||||
fix_new (fragP, fragP->fr_fix, 4, fragP->fr_symbol, fragP->fr_offset, 1,
|
||||
BFD_RELOC_32_PCREL);
|
||||
fragP->fr_fix += 4;
|
||||
ext = 0;
|
||||
break;
|
||||
case TAB (FBRANCH, SHORT):
|
||||
know ((fragP->fr_opcode[1] & 0x40) == 0);
|
||||
ext = 2;
|
||||
break;
|
||||
case TAB (FBRANCH, LONG):
|
||||
fragP->fr_opcode[1] |= 0x40; /* Turn on LONG bit */
|
||||
ext = 4;
|
||||
break;
|
||||
case TAB (PCREL, SHORT):
|
||||
ext = 2;
|
||||
break;
|
||||
case TAB (PCREL, LONG):
|
||||
/* The thing to do here is force it to ABSOLUTE LONG, since
|
||||
PCREL is really trying to shorten an ABSOLUTE address anyway */
|
||||
/* JF FOO This code has not been tested */
|
||||
fix_new (fragP, fragP->fr_fix, 4, fragP->fr_symbol, fragP->fr_offset,
|
||||
0, NO_RELOC);
|
||||
if ((fragP->fr_opcode[1] & 0x3F) != 0x3A)
|
||||
as_bad (_("Internal error (long PC-relative operand) for insn 0x%04x at 0x%lx"),
|
||||
(unsigned) fragP->fr_opcode[0],
|
||||
(unsigned long) fragP->fr_address);
|
||||
fragP->fr_opcode[1] &= ~0x3F;
|
||||
fragP->fr_opcode[1] |= 0x39; /* Mode 7.1 */
|
||||
case TAB (DBCCABSJ, LONG):
|
||||
/* only DBcc instructions can come here */
|
||||
/* Change dbcc into dbcc/jmp. */
|
||||
|
||||
/* JF: these used to be fr_opcode[2-7], but that's wrong */
|
||||
*buffer_address++ = 0x00; /* branch offset = 4 */
|
||||
*buffer_address++ = 0x04;
|
||||
*buffer_address++ = 0x60; /* put in bra pc+6 */
|
||||
*buffer_address++ = 0x06;
|
||||
*buffer_address++ = 0x4e; /* Put in jmp long (0x4ef9). */
|
||||
*buffer_address++ = (char) 0xf9;
|
||||
|
||||
fragP->fr_fix += 6; /* account for bra/jmp instructions */
|
||||
fix_new (fragP, fragP->fr_fix, 4, fragP->fr_symbol, fragP->fr_offset, 0,
|
||||
BFD_RELOC_32);
|
||||
fragP->fr_fix += 4;
|
||||
ext = 0;
|
||||
break;
|
||||
case TAB (PCLEA, SHORT):
|
||||
fix_new (fragP, (int) (fragP->fr_fix), 2, fragP->fr_symbol,
|
||||
fragP->fr_offset, 1, NO_RELOC);
|
||||
case TAB (PCREL1632, SHORT):
|
||||
fragP->fr_opcode[1] &= ~0x3F;
|
||||
fragP->fr_opcode[1] |= 0x3A; /* 072 - mode 7.2 */
|
||||
ext = 2;
|
||||
fix_new (fragP, (int) (fragP->fr_fix), 2, fragP->fr_symbol,
|
||||
fragP->fr_offset, 1, BFD_RELOC_16_PCREL);
|
||||
fragP->fr_fix += 2;
|
||||
break;
|
||||
case TAB (PCLEA, LONG):
|
||||
fixP = fix_new (fragP, (int) (fragP->fr_fix) + 2, 4, fragP->fr_symbol,
|
||||
fragP->fr_offset, 1, NO_RELOC);
|
||||
fixP->fx_pcrel_adjust = 2;
|
||||
case TAB (PCREL1632, LONG):
|
||||
/* Already set to mode 7.3; this indicates: PC indirect with
|
||||
suppressed index, 32-bit displacement. */
|
||||
*buffer_address++ = 0x01;
|
||||
*buffer_address++ = 0x70;
|
||||
fragP->fr_fix += 2;
|
||||
ext = 4;
|
||||
fixP = fix_new (fragP, (int) (fragP->fr_fix), 4, fragP->fr_symbol,
|
||||
fragP->fr_offset, 1, BFD_RELOC_32_PCREL);
|
||||
fixP->fx_pcrel_adjust = 2;
|
||||
fragP->fr_fix += 4;
|
||||
break;
|
||||
|
||||
case TAB (PCINDEX, BYTE):
|
||||
disp += 2;
|
||||
if (!issbyte (disp))
|
||||
{
|
||||
as_bad (_("displacement doesn't fit in one byte"));
|
||||
disp = 0;
|
||||
}
|
||||
assert (fragP->fr_fix >= 2);
|
||||
buffer_address[-2] &= ~1;
|
||||
buffer_address[-1] = disp;
|
||||
ext = 0;
|
||||
fixP = fix_new (fragP, fragP->fr_fix - 1, 1, fragP->fr_symbol,
|
||||
fragP->fr_offset, 1, BFD_RELOC_8_PCREL);
|
||||
fixP->fx_pcrel_adjust = 1;
|
||||
break;
|
||||
case TAB (PCINDEX, SHORT):
|
||||
disp += 2;
|
||||
assert (issword (disp));
|
||||
assert (fragP->fr_fix >= 2);
|
||||
buffer_address[-2] |= 0x1;
|
||||
buffer_address[-1] = 0x20;
|
||||
fixP = fix_new (fragP, (int) (fragP->fr_fix), 2, fragP->fr_symbol,
|
||||
fragP->fr_offset, (fragP->fr_opcode[1] & 077) == 073,
|
||||
NO_RELOC);
|
||||
fragP->fr_offset, 1, BFD_RELOC_16_PCREL);
|
||||
fixP->fx_pcrel_adjust = 2;
|
||||
ext = 2;
|
||||
fragP->fr_fix += 2;
|
||||
break;
|
||||
case TAB (PCINDEX, LONG):
|
||||
disp += 2;
|
||||
fixP = fix_new (fragP, (int) (fragP->fr_fix), 4, fragP->fr_symbol,
|
||||
fragP->fr_offset, (fragP->fr_opcode[1] & 077) == 073,
|
||||
NO_RELOC);
|
||||
fixP->fx_pcrel_adjust = 2;
|
||||
assert (fragP->fr_fix >= 2);
|
||||
buffer_address[-2] |= 0x1;
|
||||
buffer_address[-1] = 0x30;
|
||||
ext = 4;
|
||||
fixP = fix_new (fragP, (int) (fragP->fr_fix), 4, fragP->fr_symbol,
|
||||
fragP->fr_offset, 1, BFD_RELOC_32_PCREL);
|
||||
fixP->fx_pcrel_adjust = 2;
|
||||
fragP->fr_fix += 4;
|
||||
break;
|
||||
case TAB (ABSTOPCREL, SHORT):
|
||||
fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol, fragP->fr_offset,
|
||||
1, BFD_RELOC_16_PCREL);
|
||||
fragP->fr_fix += 2;
|
||||
break;
|
||||
case TAB (ABSTOPCREL, LONG):
|
||||
/* The thing to do here is force it to ABSOLUTE LONG, since
|
||||
ABSTOPCREL is really trying to shorten an ABSOLUTE address anyway */
|
||||
if ((fragP->fr_opcode[1] & 0x3F) != 0x3A)
|
||||
abort ();
|
||||
fragP->fr_opcode[1] &= ~0x3F;
|
||||
fragP->fr_opcode[1] |= 0x39; /* Mode 7.1 */
|
||||
fix_new (fragP, fragP->fr_fix, 4, fragP->fr_symbol, fragP->fr_offset,
|
||||
0, BFD_RELOC_32);
|
||||
fragP->fr_fix += 4;
|
||||
break;
|
||||
}
|
||||
|
||||
if (ext)
|
||||
{
|
||||
md_number_to_chars (buffer_address, (long) disp, (int) ext);
|
||||
fragP->fr_fix += ext;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4537,70 +4568,69 @@ md_estimate_size_before_relax (fragP, segment)
|
|||
|
||||
old_fix = fragP->fr_fix;
|
||||
|
||||
/* handle SZ_UNDEF first, it can be changed to BYTE or SHORT */
|
||||
/* Handle SZ_UNDEF first, it can be changed to BYTE or SHORT. */
|
||||
switch (fragP->fr_subtype)
|
||||
{
|
||||
|
||||
case TAB (ABRANCH, SZ_UNDEF):
|
||||
case TAB (BRANCHBWL, SZ_UNDEF):
|
||||
case TAB (BRABSJUNC, SZ_UNDEF):
|
||||
{
|
||||
if ((fragP->fr_symbol != NULL) /* Not absolute */
|
||||
&& S_GET_SEGMENT (fragP->fr_symbol) == segment
|
||||
if (S_GET_SEGMENT (fragP->fr_symbol) == segment
|
||||
&& relaxable_symbol (fragP->fr_symbol))
|
||||
{
|
||||
fragP->fr_subtype = TAB (TABTYPE (fragP->fr_subtype), BYTE);
|
||||
break;
|
||||
}
|
||||
else if ((fragP->fr_symbol != NULL)
|
||||
&& (flag_short_refs || flag_keep_pcrel))
|
||||
{ /* Symbol is undefined and we want short ref */
|
||||
fix_new (fragP, (int) (fragP->fr_fix), 2, fragP->fr_symbol,
|
||||
fragP->fr_offset, 1, NO_RELOC);
|
||||
fragP->fr_fix += 2;
|
||||
frag_wane (fragP);
|
||||
break;
|
||||
}
|
||||
else if ((fragP->fr_symbol == 0) || !HAVE_LONG_BRANCH(current_architecture))
|
||||
else if (flag_short_refs)
|
||||
{
|
||||
/* On 68000, or for absolute value, switch to abs long */
|
||||
/* FIXME, we should check abs val, pick short or long */
|
||||
if (fragP->fr_opcode[0] == 0x61)
|
||||
{
|
||||
fragP->fr_opcode[0] = 0x4E;
|
||||
fragP->fr_opcode[1] = (char) 0xB9; /* JBSR with ABSL LONG offset */
|
||||
fix_new (fragP, fragP->fr_fix, 4,
|
||||
fragP->fr_symbol, fragP->fr_offset, 0, NO_RELOC);
|
||||
fragP->fr_fix += 4;
|
||||
frag_wane (fragP);
|
||||
}
|
||||
else if (fragP->fr_opcode[0] == 0x60)
|
||||
{
|
||||
fragP->fr_opcode[0] = 0x4E;
|
||||
fragP->fr_opcode[1] = (char) 0xF9; /* JMP with ABSL LONG offset */
|
||||
fix_new (fragP, fragP->fr_fix, 4,
|
||||
fragP->fr_symbol, fragP->fr_offset, 0, NO_RELOC);
|
||||
fragP->fr_fix += 4;
|
||||
frag_wane (fragP);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* This should never happen, because if it's a conditional
|
||||
branch and we are on a 68000, BCC68000 should have been
|
||||
picked instead of ABRANCH. */
|
||||
abort ();
|
||||
}
|
||||
/* Symbol is undefined and we want short ref. */
|
||||
fragP->fr_subtype = TAB (TABTYPE (fragP->fr_subtype), SHORT);
|
||||
fragP->fr_var += 2;
|
||||
}
|
||||
else
|
||||
{ /* Symbol is still undefined. Make it simple */
|
||||
fix_new (fragP, (int) (fragP->fr_fix), 4, fragP->fr_symbol,
|
||||
fragP->fr_offset, 1, NO_RELOC);
|
||||
fragP->fr_fix += 4;
|
||||
fragP->fr_opcode[1] = (char) 0xff;
|
||||
frag_wane (fragP);
|
||||
break;
|
||||
{
|
||||
/* Symbol is still undefined. Make it LONG. */
|
||||
fragP->fr_subtype = TAB (TABTYPE (fragP->fr_subtype), LONG);
|
||||
fragP->fr_var += 4;
|
||||
}
|
||||
|
||||
break;
|
||||
} /* case TAB(ABRANCH,SZ_UNDEF) */
|
||||
}
|
||||
|
||||
case TAB (BRABSJCOND, SZ_UNDEF):
|
||||
{
|
||||
if (S_GET_SEGMENT (fragP->fr_symbol) == segment
|
||||
&& relaxable_symbol (fragP->fr_symbol))
|
||||
{
|
||||
fragP->fr_subtype = TAB (TABTYPE (fragP->fr_subtype), BYTE);
|
||||
}
|
||||
else if (flag_short_refs)
|
||||
{
|
||||
/* Symbol is undefined and we want short ref. */
|
||||
fragP->fr_subtype = TAB (TABTYPE (fragP->fr_subtype), SHORT);
|
||||
fragP->fr_var += 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Symbol is still undefined. Make it LONG. */
|
||||
fragP->fr_subtype = TAB (TABTYPE (fragP->fr_subtype), LONG);
|
||||
fragP->fr_var += 6;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case TAB (BRANCHBW, SZ_UNDEF):
|
||||
{
|
||||
if (S_GET_SEGMENT (fragP->fr_symbol) == segment
|
||||
&& relaxable_symbol (fragP->fr_symbol))
|
||||
{
|
||||
fragP->fr_subtype = TAB (TABTYPE (fragP->fr_subtype), BYTE);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Symbol is undefined and we don't have long branches. */
|
||||
fragP->fr_subtype = TAB (TABTYPE (fragP->fr_subtype), SHORT);
|
||||
fragP->fr_var += 2;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case TAB (FBRANCH, SZ_UNDEF):
|
||||
{
|
||||
|
@ -4613,142 +4643,50 @@ md_estimate_size_before_relax (fragP, segment)
|
|||
}
|
||||
else
|
||||
{
|
||||
fix_new (fragP, (int) fragP->fr_fix, 4, fragP->fr_symbol,
|
||||
fragP->fr_offset, 1, NO_RELOC);
|
||||
fragP->fr_fix += 4;
|
||||
fragP->fr_opcode[1] |= 0x40; /* Turn on LONG bit */
|
||||
frag_wane (fragP);
|
||||
}
|
||||
break;
|
||||
} /* TAB(FBRANCH,SZ_UNDEF) */
|
||||
|
||||
case TAB (PCREL, SZ_UNDEF):
|
||||
{
|
||||
if ((S_GET_SEGMENT (fragP->fr_symbol) == segment
|
||||
&& relaxable_symbol (fragP->fr_symbol))
|
||||
|| flag_short_refs)
|
||||
{
|
||||
fragP->fr_subtype = TAB (PCREL, SHORT);
|
||||
fragP->fr_var += 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
fragP->fr_subtype = TAB (PCREL, LONG);
|
||||
fragP->fr_subtype = TAB (FBRANCH, LONG);
|
||||
fragP->fr_var += 4;
|
||||
}
|
||||
break;
|
||||
} /* TAB(PCREL,SZ_UNDEF) */
|
||||
}
|
||||
|
||||
case TAB (BCC68000, SZ_UNDEF):
|
||||
case TAB (DBCCLBR, SZ_UNDEF):
|
||||
case TAB (DBCCABSJ, SZ_UNDEF):
|
||||
{
|
||||
if ((fragP->fr_symbol != NULL)
|
||||
&& 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)
|
||||
|| flag_short_refs)
|
||||
{
|
||||
fragP->fr_subtype = TAB (BCC68000, BYTE);
|
||||
break;
|
||||
}
|
||||
/* only Bcc 68000 instructions can come here */
|
||||
if ((fragP->fr_symbol != NULL) && (flag_short_refs || flag_keep_pcrel))
|
||||
{
|
||||
/* the user wants short refs, so emit one */
|
||||
fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
|
||||
fragP->fr_offset, 1, NO_RELOC);
|
||||
fragP->fr_fix += 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* change bcc into b!cc/jmp absl long */
|
||||
fragP->fr_opcode[0] ^= 0x01; /* invert bcc */
|
||||
fragP->fr_opcode[1] = 0x06; /* branch offset = 6 */
|
||||
/* JF: these were fr_opcode[2,3] */
|
||||
buffer_address[0] = 0x4e; /* put in jmp long (0x4ef9) */
|
||||
buffer_address[1] = (char) 0xf9;
|
||||
fragP->fr_fix += 2; /* account for jmp instruction */
|
||||
fix_new (fragP, fragP->fr_fix, 4, fragP->fr_symbol,
|
||||
fragP->fr_offset, 0, NO_RELOC);
|
||||
fragP->fr_fix += 4;
|
||||
}
|
||||
frag_wane (fragP);
|
||||
break;
|
||||
} /* case TAB(BCC68000,SZ_UNDEF) */
|
||||
|
||||
case TAB (DBCC, SZ_UNDEF):
|
||||
{
|
||||
if (fragP->fr_symbol != NULL
|
||||
&& S_GET_SEGMENT (fragP->fr_symbol) == segment
|
||||
&& relaxable_symbol (fragP->fr_symbol))
|
||||
{
|
||||
fragP->fr_subtype = TAB (DBCC, SHORT);
|
||||
fragP->fr_subtype = TAB (TABTYPE (fragP->fr_subtype), SHORT);
|
||||
fragP->fr_var += 2;
|
||||
break;
|
||||
}
|
||||
/* only DBcc 68000 instructions can come here */
|
||||
|
||||
if (fragP->fr_symbol != NULL
|
||||
&& (flag_short_refs
|
||||
|| (! HAVE_LONG_BRANCH (current_architecture)
|
||||
&& flag_keep_pcrel)))
|
||||
{
|
||||
/* the user wants short refs, so emit one */
|
||||
fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
|
||||
fragP->fr_offset, 1, NO_RELOC);
|
||||
fragP->fr_fix += 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Change dbcc into dbcc/bral. */
|
||||
/* JF: these used to be fr_opcode[2-4], which is wrong. */
|
||||
buffer_address[0] = 0x00; /* branch offset = 4 */
|
||||
buffer_address[1] = 0x04;
|
||||
buffer_address[2] = 0x60; /* put in bra pc + ... */
|
||||
/* JF: these were fr_opcode[5-7] */
|
||||
buffer_address[3] = 0x06; /* Plus 6 */
|
||||
if (HAVE_LONG_BRANCH (current_architecture))
|
||||
{
|
||||
buffer_address[4] = 0x60; /* Put in bral (0x60ff). */
|
||||
buffer_address[5] = (char) 0xff;
|
||||
}
|
||||
else
|
||||
{
|
||||
buffer_address[4] = 0x4e; /* Put in jmp long (0x4ef9). */
|
||||
buffer_address[5] = (char) 0xf9;
|
||||
}
|
||||
fragP->fr_fix += 6; /* account for bra/jmp instruction */
|
||||
fix_new (fragP, fragP->fr_fix, 4, fragP->fr_symbol,
|
||||
fragP->fr_offset, HAVE_LONG_BRANCH (current_architecture),
|
||||
NO_RELOC);
|
||||
fragP->fr_fix += 4;
|
||||
fragP->fr_subtype = TAB (TABTYPE (fragP->fr_subtype), LONG);
|
||||
fragP->fr_var += 10;
|
||||
}
|
||||
|
||||
frag_wane (fragP);
|
||||
break;
|
||||
} /* case TAB(DBCC,SZ_UNDEF) */
|
||||
}
|
||||
|
||||
case TAB (PCLEA, SZ_UNDEF):
|
||||
case TAB (PCREL1632, SZ_UNDEF):
|
||||
{
|
||||
if (((S_GET_SEGMENT (fragP->fr_symbol)) == segment
|
||||
&& relaxable_symbol (fragP->fr_symbol))
|
||||
|| flag_short_refs
|
||||
|| cpu_of_arch (current_architecture) < m68020
|
||||
|| cpu_of_arch (current_architecture) == mcf5200)
|
||||
|| flag_short_refs)
|
||||
{
|
||||
fragP->fr_subtype = TAB (PCLEA, SHORT);
|
||||
fragP->fr_subtype = TAB (PCREL1632, SHORT);
|
||||
fragP->fr_var += 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
fragP->fr_subtype = TAB (PCLEA, LONG);
|
||||
fragP->fr_subtype = TAB (PCREL1632, LONG);
|
||||
fragP->fr_var += 6;
|
||||
}
|
||||
break;
|
||||
} /* TAB(PCLEA,SZ_UNDEF) */
|
||||
|
||||
}
|
||||
|
||||
case TAB (PCINDEX, SZ_UNDEF):
|
||||
if ((S_GET_SEGMENT (fragP->fr_symbol) == segment
|
||||
&& relaxable_symbol (fragP->fr_symbol))
|
||||
|| cpu_of_arch (current_architecture) < m68020
|
||||
|| cpu_of_arch (current_architecture) == mcf5200)
|
||||
&& relaxable_symbol (fragP->fr_symbol)))
|
||||
{
|
||||
fragP->fr_subtype = TAB (PCINDEX, BYTE);
|
||||
}
|
||||
|
@ -4759,15 +4697,33 @@ md_estimate_size_before_relax (fragP, segment)
|
|||
}
|
||||
break;
|
||||
|
||||
case TAB (ABSTOPCREL, SZ_UNDEF):
|
||||
{
|
||||
if ((S_GET_SEGMENT (fragP->fr_symbol) == segment
|
||||
&& relaxable_symbol (fragP->fr_symbol)))
|
||||
{
|
||||
fragP->fr_subtype = TAB (ABSTOPCREL, SHORT);
|
||||
fragP->fr_var += 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
fragP->fr_subtype = TAB (ABSTOPCREL, LONG);
|
||||
fragP->fr_var += 4;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* now that SZ_UNDEF are taken care of, check others */
|
||||
/* Now that SZ_UNDEF are taken care of, check others. */
|
||||
switch (fragP->fr_subtype)
|
||||
{
|
||||
case TAB (BCC68000, BYTE):
|
||||
case TAB (ABRANCH, BYTE):
|
||||
case TAB (BRANCHBWL, BYTE):
|
||||
case TAB (BRABSJUNC, BYTE):
|
||||
case TAB (BRABSJCOND, BYTE):
|
||||
case TAB (BRANCHBW, BYTE):
|
||||
/* We can't do a short jump to the next instruction, so in that
|
||||
case we force word mode. At this point S_GET_VALUE should
|
||||
return the offset of the symbol within its frag. If the
|
||||
|
|
Loading…
Reference in a new issue