public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* Re: PATCH to gas: --pcrel option for m68k
@ 2000-07-31 18:42 Michael Sokolov
  0 siblings, 0 replies; 4+ messages in thread
From: Michael Sokolov @ 2000-07-31 18:42 UTC (permalink / raw)
  To: binutils

Nick Clifton <nickc@cygnus.com> wrote:

> Approved and applied.

Thanks!

In gas/ChangeLog:

:         * doc/c-m68k.texi: Document new command line option.

Thanks for documenting the new option, I should have done this myself in the
original patch. In fact, what I really should have done in the original patch,
and what I've just done now, is to rewrite the whole section about branch
relaxation to match what the current gas relaxer actually does, both with and
without --pcrel on all processors. The old description is nowhere near the
reality. The patch is below. It also describes the --pcrel option more
accurately.

--
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)

P.S. I believe "PC-relative" is correctly written like this, with a hyphen, but
I'm not a native speaker.

2000-07-31  Michael Sokolov  <msokolov@ivan.Harhan.ORG>

	* doc/c-m68k.texi (@cindex @samp{--pcrel}): Rewrite option description.
	(@node M68K-Branch): Rewrite to match the reality.

Index: c-m68k.texi
===================================================================
RCS file: /cvs/src/src/gas/doc/c-m68k.texi,v
retrieving revision 1.2
diff -c -r1.2 c-m68k.texi
*** c-m68k.texi	2000/07/31 22:08:14	1.2
--- c-m68k.texi	2000/08/01 01:23:06
***************
*** 85,95 ****
  @samp{--disp-size-default-32} option to restore the default behaviour.
  
  @cindex @samp{--pcrel}
! Always generate PC relative branches.  Actually what this option really
! does is to prevent PC relative branches from being turned into absolute
! jumps.  If this cannot be done (because the specific architecture does
! not have a suitable PC relative branch instruction), the assembler will
! generate an error message.
  
  @cindex @samp{-m68000} and related options
  @cindex architecture options, M680x0
--- 85,99 ----
  @samp{--disp-size-default-32} option to restore the default behaviour.
  
  @cindex @samp{--pcrel}
! Always keep branches PC-relative.  In the M680x0 architecture all branches
! are defined as PC-relative.  However, on some processors they are limited
! to word displacements maximum.  When @code{@value{AS}} needs a long branch
! that is not available, it normally emits an absolute jump instead.  This
! option disables this substitution.  When this option is given and no long
! branches are available, only word branches will be emitted.  An error
! message will be generated if a word branch cannot reach its target.  This
! option has no effect on 68020 and other processors that have long branches.
! @pxref{M68K-Branch,,Branch Improvement}.
  
  @cindex @samp{-m68000} and related options
  @cindex architecture options, M680x0
***************
*** 410,437 ****
  
  @smallexample
            Displacement
!           +-------------------------------------------------
!           |                68020   68000/10
! Pseudo-Op |BYTE    WORD    LONG    LONG      non-PC relative
!           +-------------------------------------------------
!      jbsr |bsrs    bsr     bsrl    jsr       jsr
!       jra |bras    bra     bral    jmp       jmp
! *     jXX |bXXs    bXX     bXXl    bNXs;jmpl bNXs;jmp
! *    dbXX |dbXX    dbXX        dbXX; bra; jmpl
! *    fjXX |fbXXw   fbXXw   fbXXl             fbNXw;jmp
  
  XX: condition
  NX: negative of condition XX
  
  @end smallexample
  @center @code{*}---see full description below
  
  @table @code
  @item jbsr
  @itemx jra
  These are the simplest jump pseudo-operations; they always map to one
  particular machine instruction, depending on the displacement to the
! branch target.
  
  @item j@var{XX}
  Here, @samp{j@var{XX}} stands for an entire family of pseudo-operations,
--- 414,452 ----
  
  @smallexample
            Displacement
!           +------------------------------------------------------------
!           |                68020           68000/10, not PC-relative OK
! Pseudo-Op |BYTE    WORD    LONG            ABSOLUTE LONG JUMP    **
!           +------------------------------------------------------------
!      jbsr |bsrs    bsrw    bsrl            jsr
!       jra |bras    braw    bral            jmp
! *     jXX |bXXs    bXXw    bXXl            bNXs;jmp
! *    dbXX | N/A    dbXXw   dbXX;bras;bral  dbXX;bras;jmp
!      fjXX | N/A    fbXXw   fbXXl            N/A
  
  XX: condition
  NX: negative of condition XX
  
  @end smallexample
  @center @code{*}---see full description below
+ @center @code{**}---this expansion mode is disallowed by @samp{--pcrel}
  
  @table @code
  @item jbsr
  @itemx jra
  These are the simplest jump pseudo-operations; they always map to one
  particular machine instruction, depending on the displacement to the
! branch target.  This instruction will be a byte or word branch is that
! is sufficient.  Otherwise, a long branch will be emitted if available.
! If no long branches are available and the @samp{--pcrel} option is not
! given, an absolute long jump will be emitted instead.  If no long
! branches are available, the @samp{--pcrel} option is given, and a word
! branch cannot reach the target, an error message is generated.
! 
! In addition to standard branch operands, @code{@value{AS}} allows these
! pseudo-operations to have all operands that are allowed for jsr and jmp,
! substituting these instructions if the operand given is not valid for a
! branch instruction.
  
  @item j@var{XX}
  Here, @samp{j@var{XX}} stands for an entire family of pseudo-operations,
***************
*** 442,451 ****
   jvs   jpl   jmi   jge   jlt   jgt   jle
  @end smallexample
  
! For the cases of non-PC relative displacements and long displacements on
! the 68000 or 68010, @code{@value{AS}} issues a longer code fragment in terms of
! @var{NX}, the opposite condition to @var{XX}.  For example, for the
! non-PC relative case:
  @smallexample
      j@var{XX} foo
  @end smallexample
--- 457,467 ----
   jvs   jpl   jmi   jge   jlt   jgt   jle
  @end smallexample
  
! Usually, each of these pseudo-operations expands to a single branch
! instruction.  However, if a word branch is not sufficient, no long branches
! are available, and the @samp{--pcrel} option is not given, @code{@value{AS}}
! issues a longer code fragment in terms of @var{NX}, the opposite condition
! to @var{XX}.  For example, under these conditions:
  @smallexample
      j@var{XX} foo
  @end smallexample
***************
*** 464,478 ****
   dbf    dbra   dbt
  @end smallexample
  
! Other than for word and byte displacements, when the source reads
  @samp{db@var{XX} foo}, @code{@value{AS}} emits
  @smallexample
       db@var{XX} oo1
!      bra oo2
!  oo1:jmpl foo
   oo2:
  @end smallexample
  
  @item fj@var{XX}
  This family includes
  @smallexample
--- 480,506 ----
   dbf    dbra   dbt
  @end smallexample
  
! Motorola @samp{db@var{XX}} instructions allow word displacements only.  When
! a word displacement is sufficient, each of these pseudo-operations expands
! to the corresponding Motorola instruction.  When a word displacement is not
! sufficient and long branches are available, when the source reads
  @samp{db@var{XX} foo}, @code{@value{AS}} emits
  @smallexample
       db@var{XX} oo1
!      bras oo2
!  oo1:bral foo
   oo2:
  @end smallexample
  
+ If, however, long branches are not available and the @samp{--pcrel} option is
+ not given, @code{@value{AS}} emits
+ @smallexample
+      db@var{XX} oo1
+      bras oo2
+  oo1:jmp foo
+  oo2:
+ @end smallexample
+ 
  @item fj@var{XX}
  This family includes
  @smallexample
***************
*** 483,495 ****
   fjugt  fjule  fjult  fjun
  @end smallexample
  
! For branch targets that are not PC relative, @code{@value{AS}} emits
! @smallexample
!      fb@var{NX} oof
!      jmp foo
!  oof:
! @end smallexample
! when it encounters @samp{fj@var{XX} foo}.
  
  @end table
  
--- 511,519 ----
   fjugt  fjule  fjult  fjun
  @end smallexample
  
! Each of these pseudo-operations always expands to a single Motorola
! coprocessor branch instruction, word or long.  All Motorola coprocessor
! branch instructions allow both word and long displacements.
  
  @end table
  

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: PATCH to gas: --pcrel option for m68k
@ 2000-08-01 10:01 Nick Clifton
  0 siblings, 0 replies; 4+ messages in thread
From: Nick Clifton @ 2000-08-01 10:01 UTC (permalink / raw)
  To: msokolov; +Cc: binutils

Hi Michael,

: 2000-07-31  Michael Sokolov  <msokolov@ivan.Harhan.ORG>
: 
: 	* doc/c-m68k.texi (@cindex @samp{--pcrel}): Rewrite option description.
: 	(@node M68K-Branch): Rewrite to match the reality.

Approved and applied.

: P.S. I believe "PC-relative" is correctly written like this, with a
: hyphen, but I'm not a native speaker.

Actually many native speakers (including myself) are not clear on this
point, but I checked with our doc department and they agree that he
hyphen is the right way to go.

Cheers
	Nick

PS.
  Whilst checking this patch I noticed that the m68k options were not
  being set out as a table, which is how the other machine specific
  sections handle this.  So I added the code to this and checked that
  in as well.


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: PATCH to gas: --pcrel option for m68k
@ 2000-07-31 15:13 Nick Clifton
  0 siblings, 0 replies; 4+ messages in thread
From: Nick Clifton @ 2000-07-31 15:13 UTC (permalink / raw)
  To: binutils

Hi Michael,

: 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.

Approved and applied.

Cheers
	Nick

^ permalink raw reply	[flat|nested] 4+ messages in thread

* PATCH to gas: --pcrel option for m68k
@ 2000-07-23 10:45 Michael Sokolov
  0 siblings, 0 replies; 4+ messages in thread
From: Michael Sokolov @ 2000-07-23 10:45 UTC (permalink / raw)
  To: binutils

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"));

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2000-08-01 10:01 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2000-07-31 18:42 PATCH to gas: --pcrel option for m68k Michael Sokolov
  -- strict thread matches above, loose matches on Subject: below --
2000-08-01 10:01 Nick Clifton
2000-07-31 15:13 Nick Clifton
2000-07-23 10:45 Michael Sokolov

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).