This is the mail archive of the binutils@sources.redhat.com mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Committed, CRIS: Fix branch-to-constant bug.


The recent relaxation change in tc-cris.c caused an
inconsistency-check call as_fatal in cris_relax_frag.  Before
the recent change, the test-case did not emit errors, but
instead emitted incorrect code for the 8- and 16-bit cases, as
if the "bmi const" instead said "bmi .text+expr".  That is, the
generic relaxation machinery can't handle pure constants, and
treats it as section offsets.  It should be spared from such
constants.  Perhaps the "if (symbolP)" in write.c:relax_frag
should instead be "know (symbolP != NULL)".

gas/testsuite:
	* gas/cris/rd-bcnst.d, gas/cris/rd-bcnst.d: New test.

gas:
	* config/tc-cris.c (cris_relax_frag): Fix typo in comment.
	(md_assemble): Don't pass on branches to constants as relaxable.
	Tweak comment.

Index: gas/cris/rd-bcnst.d
===================================================================
RCS file: gas/cris/rd-bcnst.d
diff -N gas/cris/rd-bcnst.d
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- gas/cris/rd-bcnst.d	26 Nov 2002 08:08:35 -0000
***************
*** 0 ****
--- 1,22 ----
+ #objdump: -dr
+ 
+ # Catches an error in the relaxation machinery and checks that there's no
+ # confusion between section offset and absolute address.
+ 
+ .*:     file format .*-cris
+ 
+ Disassembly of section \.text:
+ 
+ 0+ <\.text>:
+ [ 	]+0:[ 	]+08e0[ 	]+ba 0xa
+ [ 	]+2:[ 	]+0f05[ 	]+nop 
+ [ 	]+4:[ 	]+3f0d 00db ba00[ 	]+jump 0xbadb00
+ [ 	]+a:[ 	]+f970[ 	]+bmi 0x4
+ [ 	]+c:[ 	]+08e0[ 	]+ba 0x16
+ [ 	]+e:[ 	]+0f05[ 	]+nop 
+ [ 	]+10:[ 	]+3f0d 000b 0000[ 	]+jump 0xb00
+ [ 	]+16:[ 	]+f970[ 	]+bmi 0x10
+ [ 	]+18:[ 	]+08e0[ 	]+ba 0x22
+ [ 	]+1a:[ 	]+0f05[ 	]+nop 
+ [ 	]+1c:[ 	]+3f0d 4200 0000[ 	]+jump 0x42
+ [ 	]+22:[ 	]+f970[ 	]+bmi 0x1c
Index: gas/cris/rd-bcnst.s
===================================================================
RCS file: gas/cris/rd-bcnst.s
diff -N gas/cris/rd-bcnst.s
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- gas/cris/rd-bcnst.s	26 Nov 2002 08:08:35 -0000
***************
*** 0 ****
--- 1,3 ----
+  bmi 0xbadb00
+  bmi 0xb00
+  bmi 0x42
Index: tc-cris.c
===================================================================
RCS file: /cvs/src/src/gas/config/tc-cris.c,v
retrieving revision 1.23
diff -p -c -r1.23 tc-cris.c
*** tc-cris.c	22 Oct 2002 23:45:40 -0000	1.23
--- tc-cris.c	26 Nov 2002 08:00:44 -0000
*************** cris_relax_frag (seg, fragP, stretch)
*** 360,366 ****
    const relax_typeS *table = TC_GENERIC_RELAX_TABLE;
  
    /* We only have to cope with frags as prepared by
!      md_estimate_size_before_relax.  The dword cases may geet here
       because of the different reasons that they aren't relaxable.  */
    switch (fragP->fr_subtype)
      {
--- 360,366 ----
    const relax_typeS *table = TC_GENERIC_RELAX_TABLE;
  
    /* We only have to cope with frags as prepared by
!      md_estimate_size_before_relax.  The dword cases may get here
       because of the different reasons that they aren't relaxable.  */
    switch (fragP->fr_subtype)
      {
*************** md_assemble (str)
*** 924,931 ****
  	    is_undefined = 1;
  	}
  
!       if (output_instruction.expr.X_op == O_constant
! 	  || to_seg == now_seg || is_undefined)
  	{
  	  /* Handle complex expressions.  */
  	  valueT addvalue
--- 924,930 ----
  	    is_undefined = 1;
  	}
  
!       if (to_seg == now_seg || is_undefined)
  	{
  	  /* Handle complex expressions.  */
  	  valueT addvalue
*************** md_assemble (str)
*** 949,956 ****
  	{
  	  /* We have: to_seg != now_seg && to_seg != undefined_section.
  	     This means it is a branch to a known symbol in another
! 	     section.  Code in data?  Weird but valid.	Emit a 32-bit
! 	     branch.  */
  	  char *cond_jump = frag_more (10);
  
  	  gen_cond_branch_32 (opcodep, cond_jump, frag_now,
--- 948,954 ----
  	{
  	  /* We have: to_seg != now_seg && to_seg != undefined_section.
  	     This means it is a branch to a known symbol in another
! 	     section, perhaps an absolute address.  Emit a 32-bit branch.  */
  	  char *cond_jump = frag_more (10);
  
  	  gen_cond_branch_32 (opcodep, cond_jump, frag_now,

brgds, H-P


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