diff options
-rw-r--r-- | gas/ChangeLog | 10 | ||||
-rw-r--r-- | gas/config/tc-m68k.c | 51 | ||||
-rw-r--r-- | gas/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gas/testsuite/gas/m68k/br-isaa.d | 4 | ||||
-rw-r--r-- | gas/testsuite/gas/m68k/br-isab.d | 4 | ||||
-rw-r--r-- | gas/testsuite/gas/m68k/br-isac.d | 14 |
6 files changed, 74 insertions, 15 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog index fcf45f1..2b561ff 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -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> * config/tc-mips.c (s_align): Set max_alignment to 28. diff --git a/gas/config/tc-m68k.c b/gas/config/tc-m68k.c index 57163ce..569a89e 100644 --- a/gas/config/tc-m68k.c +++ b/gas/config/tc-m68k.c @@ -380,6 +380,7 @@ struct m68k_it ((x) & (m68020|m68030|m68040|m68060|cpu32|fido_a|mcfisa_b|mcfisa_c)) #define HAVE_LONG_BRANCH(x) \ ((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. */ @@ -734,8 +735,14 @@ static void m68k_init_arch (void); #define PCINDEX 8 /* PC + displacement + index. */ #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 - 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: How far Forward this mode will reach: @@ -795,6 +802,11 @@ relax_typeS md_relax_table[] = { 32767, -32768, 2, TAB (ABSTOPCREL, LONG) }, { 0, 0, 4, 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 @@ -2275,6 +2287,7 @@ m68k_ip (char *instring) for (s = the_ins.args, opP = &the_ins.operands[0]; *s; s += 2, opP++) { int have_disp = 0; + int use_pl = 0; /* This switch is a doozy. Watch the first step; its a big one! */ @@ -2958,6 +2971,7 @@ m68k_ip (char *instring) case 'b': /* Unconditional branch */ have_disp = HAVE_LONG_BRANCH (current_architecture); + use_pl = LONG_BRANCH_VIA_COND (current_architecture); goto var_branch; case 's': /* Unconditional subroutine */ @@ -3021,7 +3035,8 @@ m68k_ip (char *instring) else add_frag (adds (&opP->disp), SEXT (offs (&opP->disp)), - TAB (BRANCHBW, SZ_UNDEF)); + (use_pl ? TAB (BRANCHBWPL, SZ_UNDEF) + : TAB (BRANCHBW, SZ_UNDEF))); break; case 'w': if (isvar (&opP->disp)) @@ -3571,10 +3586,9 @@ reverse_8_bits (int in) return out; } /* reverse_8_bits() */ -/* Cause an extra frag to be generated here, inserting up to 10 bytes - (that value is chosen in the frag_var call in md_assemble). TYPE - is the subtype of the frag to be generated; its primary type is - rs_machine_dependent. +/* Cause an extra frag to be generated here, inserting up to + FRAG_VAR_SIZE bytes. TYPE is the subtype of the frag to be + generated; its primary type is rs_machine_dependent. The TYPE parameter is also used by md_convert_frag_1 and 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++) wid += 2 * (the_ins.numo - the_ins.fragb[n - 1].fragoff); /* frag_var part. */ - wid += 10; + wid += FRAG_VAR_SIZE; /* Make sure the whole insn fits in one chunk, in particular that the var part is attached, as we access one byte before the variable frag for byte branches. */ @@ -4295,7 +4309,7 @@ md_assemble (char *str) the_ins.reloc[m].pic_reloc)); 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), 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 (BRABSJCOND, BYTE): case TAB (BRANCHBW, BYTE): + case TAB (BRANCHBWPL, BYTE): know (issbyte (disp)); if (disp == 0) 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 (BRABSJCOND, SHORT): case TAB (BRANCHBW, SHORT): + case TAB (BRANCHBWPL, SHORT): fragP->fr_opcode[1] = 0x00; fixP = fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol, 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_fix += 4; 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): if (fragP->fr_opcode[0] == 0x61) /* jbsr */ { @@ -5085,6 +5119,7 @@ md_estimate_size_before_relax (fragS *fragP, segT segment) switch (fragP->fr_subtype) { case TAB (BRANCHBWL, SZ_UNDEF): + case TAB (BRANCHBWPL, SZ_UNDEF): case TAB (BRABSJUNC, SZ_UNDEF): case TAB (BRABSJCOND, SZ_UNDEF): { diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog index f63e00a..b599228 100644 --- a/gas/testsuite/ChangeLog +++ b/gas/testsuite/ChangeLog @@ -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> * gas/mips/align.s, gas/mips/align.d: New test. diff --git a/gas/testsuite/gas/m68k/br-isaa.d b/gas/testsuite/gas/m68k/br-isaa.d index 0b49dc2..cccb484 100644 --- a/gas/testsuite/gas/m68k/br-isaa.d +++ b/gas/testsuite/gas/m68k/br-isaa.d @@ -1,5 +1,5 @@ #name: br-isaa.d -#objdump: -d +#objdump: -dr #as: -march=isaa -pcrel .*: file format .* @@ -10,6 +10,8 @@ Disassembly of section .text: 0: 4e71 nop 2: 60fc bras 0 <foo> 4: 6000 0000 braw 6 <foo\+0x6> + 6: R_68K_PC16 bar 8: 61f6 bsrs 0 <foo> a: 6100 0000 bsrw c <foo\+0xc> + c: R_68K_PC16 bar e: 4e71 nop diff --git a/gas/testsuite/gas/m68k/br-isab.d b/gas/testsuite/gas/m68k/br-isab.d index 20e093f..bcac0d2 100644 --- a/gas/testsuite/gas/m68k/br-isab.d +++ b/gas/testsuite/gas/m68k/br-isab.d @@ -1,5 +1,5 @@ #name: br-isab.d -#objdump: -d +#objdump: -dr #as: -march=isab -pcrel .*: file format .* @@ -11,6 +11,8 @@ Disassembly of section .text: 2: 61ff ffff fffc bsrl 0 <foo> 8: 60f6 bras 0 <foo> a: 60ff 0000 0000 bral c <foo\+0xc> + c: R_68K_PC32 bar 10: 61ee bsrs 0 <foo> 12: 61ff 0000 0000 bsrl 14 <foo\+0x14> + 14: R_68K_PC32 bar 18: 4e71 nop diff --git a/gas/testsuite/gas/m68k/br-isac.d b/gas/testsuite/gas/m68k/br-isac.d index 126ff46..bc927ed 100644 --- a/gas/testsuite/gas/m68k/br-isac.d +++ b/gas/testsuite/gas/m68k/br-isac.d @@ -1,5 +1,5 @@ #name: br-isac.d -#objdump: -d +#objdump: -dr #as: -march=isac -pcrel .*: file format .* @@ -10,7 +10,11 @@ Disassembly of section .text: 0: 4e71 nop 2: 61ff ffff fffc bsrl 0 <foo> 8: 60f6 bras 0 <foo> - a: 6000 0000 braw c <foo\+0xc> - e: 61f0 bsrs 0 <foo> - 10: 61ff 0000 0000 bsrl 12 <foo\+0x12> - 16: 4e71 nop + a: 66ff 0000 0000 bnel c <foo\+0xc> + c: R_68K_PC32 bar + 10: 67ff 0000 0000 beql 12 <foo\+0x12> + 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 |