* config/tc-m68k.c (LONG_BRANCH_VIA_COND): New.

(BRANCHBWPL, FRAG_VAR_SIZE): New.
  (md_relax_table): Add BRANCHBWPL entries.
  (m68k_ip): Choose BRANCHBWPL relaxation if necessary.
  (md_assemble): Use FRAG_VAR_SIZE.
  (md_convert_frag_1): Add BRANCHBWPL cases.
  (md_estimate_size_before_relaz): Likewise.
* gas/m68k/br-isaa.d: Dump relocs too.
* gas/m68k/br-isab.d: Likewise.
* gas/m68k/br-isac.d: Likewise.  Adjust for long branch relaxation.
Index: gas/config/tc-m68k.c
This commit is contained in:
Nick Clifton
2007-09-25 15:31:05 +00:00
parent 4578199859
commit cac2720567
6 changed files with 74 additions and 15 deletions

View File

@ -1,3 +1,13 @@
2007-09-25 Nathan Sidwell <nathan@codesourcery.com>
* config/tc-m68k.c (LONG_BRANCH_VIA_COND): New.
(BRANCHBWPL, FRAG_VAR_SIZE): New.
(md_relax_table): Add BRANCHBWPL entries.
(m68k_ip): Choose BRANCHBWPL relaxation if necessary.
(md_assemble): Use FRAG_VAR_SIZE.
(md_convert_frag_1): Add BRANCHBWPL cases.
(md_estimate_size_before_relaz): Likewise.
2007-09-24 Carlos O'Donell <carlos@codesourcery.com> 2007-09-24 Carlos O'Donell <carlos@codesourcery.com>
* config/tc-mips.c (s_align): Set max_alignment to 28. * config/tc-mips.c (s_align): Set max_alignment to 28.

View File

@ -380,6 +380,7 @@ struct m68k_it
((x) & (m68020|m68030|m68040|m68060|cpu32|fido_a|mcfisa_b|mcfisa_c)) ((x) & (m68020|m68030|m68040|m68060|cpu32|fido_a|mcfisa_b|mcfisa_c))
#define HAVE_LONG_BRANCH(x) \ #define HAVE_LONG_BRANCH(x) \
((x) & (m68020|m68030|m68040|m68060|cpu32|fido_a|mcfisa_b)) ((x) & (m68020|m68030|m68040|m68060|cpu32|fido_a|mcfisa_b))
#define LONG_BRANCH_VIA_COND(x) (HAVE_LONG_COND(x) && !HAVE_LONG_BRANCH(x))
static struct m68k_it the_ins; /* The instruction being assembled. */ static struct m68k_it the_ins; /* The instruction being assembled. */
@ -734,8 +735,14 @@ static void m68k_init_arch (void);
#define PCINDEX 8 /* PC + displacement + index. */ #define PCINDEX 8 /* PC + displacement + index. */
#define ABSTOPCREL 9 /* Absolute relax down to 16-bit PC-relative. */ #define ABSTOPCREL 9 /* Absolute relax down to 16-bit PC-relative. */
/* This relaxation is required for branches where there is no long
branch and we are in pcrel mode. We generate a bne/beq pair. */
#define BRANCHBWPL 10 /* Branch byte, word or pair of longs
*/
/* Note that calls to frag_var need to specify the maximum expansion /* Note that calls to frag_var need to specify the maximum expansion
needed; this is currently 10 bytes for DBCC. */ needed; this is currently 12 bytes for bne/beq pair. */
#define FRAG_VAR_SIZE 12
/* The fields are: /* The fields are:
How far Forward this mode will reach: How far Forward this mode will reach:
@ -795,6 +802,11 @@ relax_typeS md_relax_table[] =
{ 32767, -32768, 2, TAB (ABSTOPCREL, LONG) }, { 32767, -32768, 2, TAB (ABSTOPCREL, LONG) },
{ 0, 0, 4, 0 }, { 0, 0, 4, 0 },
{ 1, 1, 0, 0 }, { 1, 1, 0, 0 },
{ 127, -128, 0, TAB (BRANCHBWPL, SHORT) },
{ 32767, -32768, 2, TAB (BRANCHBWPL, LONG) },
{ 0, 0, 10, 0 },
{ 1, 1, 0, 0 },
}; };
/* These are the machine dependent pseudo-ops. These are included so /* These are the machine dependent pseudo-ops. These are included so
@ -2275,6 +2287,7 @@ m68k_ip (char *instring)
for (s = the_ins.args, opP = &the_ins.operands[0]; *s; s += 2, opP++) for (s = the_ins.args, opP = &the_ins.operands[0]; *s; s += 2, opP++)
{ {
int have_disp = 0; int have_disp = 0;
int use_pl = 0;
/* This switch is a doozy. /* This switch is a doozy.
Watch the first step; its a big one! */ Watch the first step; its a big one! */
@ -2958,6 +2971,7 @@ m68k_ip (char *instring)
case 'b': /* Unconditional branch */ case 'b': /* Unconditional branch */
have_disp = HAVE_LONG_BRANCH (current_architecture); have_disp = HAVE_LONG_BRANCH (current_architecture);
use_pl = LONG_BRANCH_VIA_COND (current_architecture);
goto var_branch; goto var_branch;
case 's': /* Unconditional subroutine */ case 's': /* Unconditional subroutine */
@ -3021,7 +3035,8 @@ m68k_ip (char *instring)
else else
add_frag (adds (&opP->disp), add_frag (adds (&opP->disp),
SEXT (offs (&opP->disp)), SEXT (offs (&opP->disp)),
TAB (BRANCHBW, SZ_UNDEF)); (use_pl ? TAB (BRANCHBWPL, SZ_UNDEF)
: TAB (BRANCHBW, SZ_UNDEF)));
break; break;
case 'w': case 'w':
if (isvar (&opP->disp)) if (isvar (&opP->disp))
@ -3571,10 +3586,9 @@ reverse_8_bits (int in)
return out; return out;
} /* reverse_8_bits() */ } /* reverse_8_bits() */
/* Cause an extra frag to be generated here, inserting up to 10 bytes /* Cause an extra frag to be generated here, inserting up to
(that value is chosen in the frag_var call in md_assemble). TYPE FRAG_VAR_SIZE bytes. TYPE is the subtype of the frag to be
is the subtype of the frag to be generated; its primary type is generated; its primary type is rs_machine_dependent.
rs_machine_dependent.
The TYPE parameter is also used by md_convert_frag_1 and The TYPE parameter is also used by md_convert_frag_1 and
md_estimate_size_before_relax. The appropriate type of fixup will md_estimate_size_before_relax. The appropriate type of fixup will
@ -4247,7 +4261,7 @@ md_assemble (char *str)
for (n = 1; n < the_ins.nfrag; n++) for (n = 1; n < the_ins.nfrag; n++)
wid += 2 * (the_ins.numo - the_ins.fragb[n - 1].fragoff); wid += 2 * (the_ins.numo - the_ins.fragb[n - 1].fragoff);
/* frag_var part. */ /* frag_var part. */
wid += 10; wid += FRAG_VAR_SIZE;
/* Make sure the whole insn fits in one chunk, in particular that /* Make sure the whole insn fits in one chunk, in particular that
the var part is attached, as we access one byte before the the var part is attached, as we access one byte before the
variable frag for byte branches. */ variable frag for byte branches. */
@ -4295,7 +4309,7 @@ md_assemble (char *str)
the_ins.reloc[m].pic_reloc)); the_ins.reloc[m].pic_reloc));
fixP->fx_pcrel_adjust = the_ins.reloc[m].pcrel_fix; fixP->fx_pcrel_adjust = the_ins.reloc[m].pcrel_fix;
} }
(void) frag_var (rs_machine_dependent, 10, 0, (void) frag_var (rs_machine_dependent, FRAG_VAR_SIZE, 0,
(relax_substateT) (the_ins.fragb[n].fragty), (relax_substateT) (the_ins.fragb[n].fragty),
the_ins.fragb[n].fadd, the_ins.fragb[n].foff, to_beg_P); the_ins.fragb[n].fadd, the_ins.fragb[n].foff, to_beg_P);
} }
@ -4867,6 +4881,7 @@ md_convert_frag_1 (fragS *fragP)
case TAB (BRABSJUNC, BYTE): case TAB (BRABSJUNC, BYTE):
case TAB (BRABSJCOND, BYTE): case TAB (BRABSJCOND, BYTE):
case TAB (BRANCHBW, BYTE): case TAB (BRANCHBW, BYTE):
case TAB (BRANCHBWPL, BYTE):
know (issbyte (disp)); know (issbyte (disp));
if (disp == 0) if (disp == 0)
as_bad_where (fragP->fr_file, fragP->fr_line, as_bad_where (fragP->fr_file, fragP->fr_line,
@ -4879,6 +4894,7 @@ md_convert_frag_1 (fragS *fragP)
case TAB (BRABSJUNC, SHORT): case TAB (BRABSJUNC, SHORT):
case TAB (BRABSJCOND, SHORT): case TAB (BRABSJCOND, SHORT):
case TAB (BRANCHBW, SHORT): case TAB (BRANCHBW, SHORT):
case TAB (BRANCHBWPL, SHORT):
fragP->fr_opcode[1] = 0x00; fragP->fr_opcode[1] = 0x00;
fixP = fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol, fixP = fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
fragP->fr_offset, 1, RELAX_RELOC_PC16); fragP->fr_offset, 1, RELAX_RELOC_PC16);
@ -4890,6 +4906,24 @@ md_convert_frag_1 (fragS *fragP)
fragP->fr_offset, 1, RELAX_RELOC_PC32); fragP->fr_offset, 1, RELAX_RELOC_PC32);
fragP->fr_fix += 4; fragP->fr_fix += 4;
break; break;
case TAB (BRANCHBWPL, LONG):
/* Here we are converting an unconditional branch into a pair of
conditional branches, in order to get the range. */
fragP->fr_opcode[0] = 0x66; /* bne */
fragP->fr_opcode[1] = 0xFF;
fixP = fix_new (fragP, fragP->fr_fix, 4, fragP->fr_symbol,
fragP->fr_offset, 1, RELAX_RELOC_PC32);
fixP->fx_file = fragP->fr_file;
fixP->fx_line = fragP->fr_line;
fragP->fr_fix += 4; /* Skip first offset */
buffer_address += 4;
*buffer_address++ = 0x67; /* beq */
*buffer_address++ = 0xff;
fragP->fr_fix += 2; /* Skip second branch opcode */
fixP = fix_new (fragP, fragP->fr_fix, 4, fragP->fr_symbol,
fragP->fr_offset, 1, RELAX_RELOC_PC32);
fragP->fr_fix += 4;
break;
case TAB (BRABSJUNC, LONG): case TAB (BRABSJUNC, LONG):
if (fragP->fr_opcode[0] == 0x61) /* jbsr */ if (fragP->fr_opcode[0] == 0x61) /* jbsr */
{ {
@ -5085,6 +5119,7 @@ md_estimate_size_before_relax (fragS *fragP, segT segment)
switch (fragP->fr_subtype) switch (fragP->fr_subtype)
{ {
case TAB (BRANCHBWL, SZ_UNDEF): case TAB (BRANCHBWL, SZ_UNDEF):
case TAB (BRANCHBWPL, SZ_UNDEF):
case TAB (BRABSJUNC, SZ_UNDEF): case TAB (BRABSJUNC, SZ_UNDEF):
case TAB (BRABSJCOND, SZ_UNDEF): case TAB (BRABSJCOND, SZ_UNDEF):
{ {

View File

@ -1,3 +1,9 @@
2007-09-25 Nathan Sidwell <nathan@codesourcery.com>
* gas/m68k/br-isaa.d: Dump relocs too.
* gas/m68k/br-isab.d: Likewise.
* gas/m68k/br-isac.d: Likewise. Adjust for long branch relaxation.
2007-09-24 Carlos O'Donell <carlos@codesourcery.com> 2007-09-24 Carlos O'Donell <carlos@codesourcery.com>
* gas/mips/align.s, gas/mips/align.d: New test. * gas/mips/align.s, gas/mips/align.d: New test.

View File

@ -1,5 +1,5 @@
#name: br-isaa.d #name: br-isaa.d
#objdump: -d #objdump: -dr
#as: -march=isaa -pcrel #as: -march=isaa -pcrel
.*: file format .* .*: file format .*
@ -10,6 +10,8 @@ Disassembly of section .text:
0: 4e71 nop 0: 4e71 nop
2: 60fc bras 0 <foo> 2: 60fc bras 0 <foo>
4: 6000 0000 braw 6 <foo\+0x6> 4: 6000 0000 braw 6 <foo\+0x6>
6: R_68K_PC16 bar
8: 61f6 bsrs 0 <foo> 8: 61f6 bsrs 0 <foo>
a: 6100 0000 bsrw c <foo\+0xc> a: 6100 0000 bsrw c <foo\+0xc>
c: R_68K_PC16 bar
e: 4e71 nop e: 4e71 nop

View File

@ -1,5 +1,5 @@
#name: br-isab.d #name: br-isab.d
#objdump: -d #objdump: -dr
#as: -march=isab -pcrel #as: -march=isab -pcrel
.*: file format .* .*: file format .*
@ -11,6 +11,8 @@ Disassembly of section .text:
2: 61ff ffff fffc bsrl 0 <foo> 2: 61ff ffff fffc bsrl 0 <foo>
8: 60f6 bras 0 <foo> 8: 60f6 bras 0 <foo>
a: 60ff 0000 0000 bral c <foo\+0xc> a: 60ff 0000 0000 bral c <foo\+0xc>
c: R_68K_PC32 bar
10: 61ee bsrs 0 <foo> 10: 61ee bsrs 0 <foo>
12: 61ff 0000 0000 bsrl 14 <foo\+0x14> 12: 61ff 0000 0000 bsrl 14 <foo\+0x14>
14: R_68K_PC32 bar
18: 4e71 nop 18: 4e71 nop

View File

@ -1,5 +1,5 @@
#name: br-isac.d #name: br-isac.d
#objdump: -d #objdump: -dr
#as: -march=isac -pcrel #as: -march=isac -pcrel
.*: file format .* .*: file format .*
@ -10,7 +10,11 @@ Disassembly of section .text:
0: 4e71 nop 0: 4e71 nop
2: 61ff ffff fffc bsrl 0 <foo> 2: 61ff ffff fffc bsrl 0 <foo>
8: 60f6 bras 0 <foo> 8: 60f6 bras 0 <foo>
a: 6000 0000 braw c <foo\+0xc> a: 66ff 0000 0000 bnel c <foo\+0xc>
e: 61f0 bsrs 0 <foo> c: R_68K_PC32 bar
10: 61ff 0000 0000 bsrl 12 <foo\+0x12> 10: 67ff 0000 0000 beql 12 <foo\+0x12>
16: 4e71 nop 12: R_68K_PC32 bar
16: 61e8 bsrs 0 <foo>
18: 61ff 0000 0000 bsrl 1a <foo\+0x1a>
1a: R_68K_PC32 bar
1e: 4e71 nop