This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
PATCH to gas: --pcrel option for m68k
- To: binutils at sources dot redhat dot com
- Subject: PATCH to gas: --pcrel option for m68k
- From: msokolov at ivan dot Harhan dot ORG (Michael Sokolov)
- Date: Sun, 23 Jul 00 12:43:15 CDT
Hi there,
Back in April, after a thorough discussion with then-maintainer Ian, I posted a
patch adding a --pcrel option to m68k gas (for use in parallel with -mpcrel in
current gcc) that keeps all branches always PC-relative, never turning them
into absolute jumps. That patch fell through the cracks. I didn't bug anyone
because I didn't have a copyright assignment, but now I do. Below is this patch
brought up-to-date with the current CVS. Can Nick or another maintainer please
review it? TIA.
--
Michael Sokolov Harhan Engineering Laboratory
Public Service Agent International Free Computing Task Force
International Engineering and Science Task Force
615 N GOOD LATIMER EXPY STE #4
DALLAS TX 75204-5852 USA
Phone: +1-214-824-7693 (Harhan Eng Lab office)
E-mail: msokolov@ivan.Harhan.ORG (ARPA TCP/SMTP) (UUCP coming soon)
2000-07-23 Michael Sokolov <msokolov@ivan.Harhan.ORG>
* config/tc-m68k.c (flag_keep_pcrel, OPTION_PCREL): Add --pcrel option.
(md_convert_frag_1, md_estimate_size_before_relax): When making DBcc
long emit a long branch if available instead of an absolute jump, never
emit absolute jumps for anything with --pcrel.
Index: tc-m68k.c
===================================================================
RCS file: /cvs/src/src/gas/config/tc-m68k.c,v
retrieving revision 1.8
diff -c -r1.8 tc-m68k.c
*** tc-m68k.c 2000/07/07 16:58:24 1.8
--- tc-m68k.c 2000/07/23 17:30:07
***************
*** 74,79 ****
--- 74,80 ----
static int flag_short_refs; /* -l option */
static int flag_long_jumps; /* -S option */
+ static int flag_keep_pcrel; /* --pcrel option */
#ifdef REGISTER_PREFIX_OPTIONAL
int flag_reg_prefix_optional = REGISTER_PREFIX_OPTIONAL;
***************
*** 4319,4324 ****
--- 4320,4327 ----
case TAB (ABRANCH, LONG):
if (!HAVE_LONG_BRANCH(current_architecture))
{
+ if (flag_keep_pcrel)
+ as_bad (_("long branch not supported"));
if (fragP->fr_opcode[0] == 0x61)
/* BSR */
{
***************
*** 4363,4368 ****
--- 4366,4373 ----
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"));
fragP->fr_opcode[0] ^= 0x01; /* invert bcc */
fragP->fr_opcode[1] = 0x6;/* branch offset = 6 */
***************
*** 4379,4396 ****
break;
case TAB (DBCC, LONG):
/* only DBcc 68000 instructions can come here */
! /* change dbcc into dbcc/jmp absl long */
/* 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, NO_RELOC);
fragP->fr_fix += 4;
ext = 0;
break;
--- 4384,4412 ----
break;
case TAB (DBCC, LONG):
/* only DBcc 68000 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;
! }
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);
fragP->fr_fix += 4;
ext = 0;
break;
***************
*** 4532,4538 ****
fragP->fr_subtype = TAB (TABTYPE (fragP->fr_subtype), BYTE);
break;
}
! else if ((fragP->fr_symbol != NULL) && flag_short_refs)
{ /* 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);
--- 4548,4555 ----
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);
***************
*** 4630,4636 ****
break;
}
/* only Bcc 68000 instructions can come here */
! if ((fragP->fr_symbol != NULL) && flag_short_refs)
{
/* the user wants short refs, so emit one */
fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
--- 4647,4653 ----
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,
***************
*** 4666,4672 ****
}
/* only DBcc 68000 instructions can come here */
! if (fragP->fr_symbol != NULL && flag_short_refs)
{
/* the user wants short refs, so emit one */
fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
--- 4683,4690 ----
}
/* 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,
***************
*** 4675,4692 ****
}
else
{
! /* change dbcc into dbcc/jmp absl long */
/* 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 */
! 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, 0, NO_RELOC);
fragP->fr_fix += 4;
}
--- 4693,4719 ----
}
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;
}
***************
*** 6745,6750 ****
--- 6772,6778 ----
*
* -pic Indicates PIC.
* -k Indicates PIC. (Sun 3 only.)
+ * --pcrel Never turn PC-relative branches into absolute jumps.
*
* --bitwise-or
* Permit `|' to be used in expressions.
***************
*** 6773,6778 ****
--- 6801,6808 ----
{"disp-size-default-16", no_argument, NULL, OPTION_DISP_SIZE_DEFAULT_16},
#define OPTION_DISP_SIZE_DEFAULT_32 (OPTION_MD_BASE + 6)
{"disp-size-default-32", no_argument, NULL, OPTION_DISP_SIZE_DEFAULT_32},
+ #define OPTION_PCREL (OPTION_MD_BASE + 7)
+ {"pcrel", no_argument, NULL, OPTION_PCREL},
{NULL, no_argument, NULL, 0}
};
size_t md_longopts_size = sizeof(md_longopts);
***************
*** 6794,6799 ****
--- 6824,6834 ----
flag_long_jumps = 1;
break;
+ case OPTION_PCREL: /* --pcrel means never turn PC-relative
+ branches into absolute jumps. */
+ flag_keep_pcrel = 1;
+ break;
+
case 'A':
if (*arg == 'm')
arg++;
***************
*** 6950,6955 ****
--- 6985,6991 ----
[default yes for 68020 and up]\n\
-pic, -k generate position independent code\n\
-S turn jbsr into jsr\n\
+ --pcrel never turn PC-relative branches into absolute jumps\n\
--register-prefix-optional\n\
recognize register names without prefix character\n\
--bitwise-or do not treat `|' as a comment character\n"));