This is the mail archive of the crossgcc@cygnus.com mailing list for the crossgcc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: Hitachi SH1 egcs1.1 generating braf instuction.


> Dave Madsen wrote:
> 
> >  It is not a Super 8 but a SuperH1 (SH1) SH7034 and it does not have
> > a branch far (braf) instruction.  That was added in the SH2
> > instruction set.
>
> Ok, I looked in the source for egcs-1.1 and in the directory
> egcs-1.1b/gcc/config/sh in sh.c there's the following:
> 
>     556     {
>     557       far = 0;
>     558       jump = "mov.w     %O0,%1;braf     %1";
>     559     }
> 
> Yup, looks like there may be a problem with egcs for SH1
> possibly generating a braf under certain conditions.
> 
> The bad news is I don't know how to fix it myself.  Probably
> ouput_far jump needs to do something like the code in lib1funcs.asm
> but I don't know which registers are valid at that point.

 My conclusions were quite the same... Ok, here is my suggestion
(the 'lib1funcs.asm' fuzzied me first too...)

------------ clip ---------------------------------------------
*** sh.c.orig	Fri May 15 06:26:52 1998
--- sh.c	Sat Dec  5 19:26:32 1998
***************
*** 552,567 ****
  
    this.lab = gen_label_rtx ();
  
!   if (offset >= -32764 && offset - get_attr_length (insn) <= 32766)
      {
!       far = 0;
!       jump = "mov.w	%O0,%1;braf	%1";
      }
    else
      {
!       far = 1;
!       jump = "mov.l	%O0,%1;jmp	@%1";
      }
    /* If we have a scratch register available, use it.  */
    if (GET_CODE (PREV_INSN (insn)) == INSN
        && INSN_CODE (PREV_INSN (insn)) == CODE_FOR_indirect_jump_scratch)
--- 552,576 ----
  
    this.lab = gen_label_rtx ();
  
!   if (TARGET_SH1)
      {
!       far = 1;
!       jump = "mov.l	%O0,%1;jmp	@%1";
      }
    else
      {
!     if (offset >= -32764 && offset - get_attr_length (insn) <= 32766)
!       {
!         far = 0;
!         jump = "mov.w	%O0,%1;braf	%1";
!       }
!     else
!       {
!         far = 1;
!         jump = "mov.l	%O0,%1;jmp	@%1";
!       }
      }
+ 
    /* If we have a scratch register available, use it.  */
    if (GET_CODE (PREV_INSN (insn)) == INSN
        && INSN_CODE (PREV_INSN (insn)) == CODE_FOR_indirect_jump_scratch)

> I believe the maintainer for this part of egcs is
> Jeffrey A Law law@cygnus.com, he might know for sure if it's
> really a compiler bug and what to do about it.

 Perhaps Jeff will find a better solution...

 I looked how newlib suffered from this bug. The 'vfprintf.o' was one of
those having the 'braf' instruction for SH1. The diffs between the assembly
output from 'vfprintf.c' before and after the previous patch was 
like as follows:

-------------- clip --------------------------------
314c314
< 	mov.w	L519,r7;braf	r7
---
> 	mov.l	L519,r7;jmp	@r7
315a316
> 	.align	2
317c318
< 	.word L329-L519
---
> 	.long	L329
357c358
< 	mov.w	L520,r7;braf	r7
---
> 	mov.l	L520,r7;jmp	@r7
358a360
> 	.align	2
360c362
< 	.word L329-L520
---
> 	.long	L329
474c476
< 	mov.w	L521,r0;braf	r0
---
> 	mov.l	L521,r0;jmp	@r0
475a478
> 	.align	2
477c480
< 	.word L39-L521
---
> 	.long	L39
490c493
< 	mov.w	L522,r5;braf	r5
---
> 	mov.l	L522,r5;jmp	@r5
491a495
> 	.align	2
493c497
< 	.word L512-L522
---
> 	.long	L512
3111c3115
< 	mov.w	L523,r0;braf	r0
---
> 	mov.l	L523,r0;jmp	@r0
3112a3117
> 	.align	2
3114c3119
< 	.word L28-L523
---
> 	.long	L28
-------------- clip --------------------------------

 I compiled some SH1 programs and ran them under the
simulator, and they seemed to work still after the fix...
Ok, all SH-experts, please comment this...

Cheers, Kai
_______________________________________________
New CrossGCC FAQ: http://www.objsw.com/CrossGCC
_______________________________________________
To remove yourself from the crossgcc list, send
mail to crossgcc-request@cygnus.com with the
text 'unsubscribe' (without the quotes) in the
body of the message.