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]

[PATCH]: Fix gas 68HC12 indexed addressing code generation



Hi!

For 68HC12 gas, the insns generated for

	leax	colSelect,x

was wrong when 'colSelect' is an external symbol.
I was trying to relax this symbol to 5-bit, 9-bit and 
then to a 16-bit contant but what was generated is wrong.

I've integrated this patch to fix the relaxation for
this operand. I also added some test case.

	Stephane

2001-01-11  Stephane Carrez  <Stephane.Carrez@worldnet.fr>

	* config/tc-m68hc11.c (md_estimate_size_before_relax): Fix
	STATE_INDEXED_OFFSET when the symbol is undefined (16-bit offset).
	(build_indexed_byte): Don't relax indexed byte, use 16-bit offset
	and fix_new_exp() instead.
	(md_convert_frag): For indexed post byte use the symbol value
	rather than the displacement.
	(md_relax_table): Fix indexed offset relax.

2001-01-11  Stephane Carrez  <Stephane.Carrez@worldnet.fr>

	* gas/m68hc11/opers12.s: Add more tests for index post byte.
	* gas/m68hc11/opers12.d: Likewise.
Index: config/tc-m68hc11.c
===================================================================
RCS file: /cvs/src/src/gas/config/tc-m68hc11.c,v
retrieving revision 1.10
diff -p -r1.10 tc-m68hc11.c
*** tc-m68hc11.c	2001/01/11 19:42:47	1.10
--- tc-m68hc11.c	2001/01/11 20:14:11
*************** relax_typeS md_relax_table[] =
*** 85,91 ****
    /* Relax for indexed offset: 5-bits, 9-bits, 16-bits.  */
    {(15), (-16), 0, ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS9)},
    {(255), (-256), 1, ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS16)},
!   {0, 0, 1, 0},
    {1, 1, 0, 0},
  
    /* Relax for dbeq/ibeq/tbeq r,<L>:
--- 85,91 ----
    /* Relax for indexed offset: 5-bits, 9-bits, 16-bits.  */
    {(15), (-16), 0, ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS9)},
    {(255), (-256), 1, ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS16)},
!   {0, 0, 2, 0},
    {1, 1, 0, 0},
  
    /* Relax for dbeq/ibeq/tbeq r,<L>:
*************** build_indexed_byte (op, format, move_ins
*** 1754,1768 ****
  	      return 3;
  	    }
  	}
!       f = frag_more (1);
!       number_to_chars_bigendian (f, byte, 1);
! #if 0
!       fix_new_exp (frag_now, f - frag_now->fr_literal, 2,
! 		   &op->exp, false, BFD_RELOC_16);
! #endif
!       frag_var (rs_machine_dependent, 2, 2,
! 		ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_UNDF),
! 		op->exp.X_add_symbol, val, f);
        return 3;
      }
  
--- 1754,1779 ----
  	      return 3;
  	    }
  	}
!       if (op->reg1 != REG_PC)
!         {
!           byte = (byte << 3) | 0xe2;
!           f = frag_more (1);
!           number_to_chars_bigendian (f, byte, 1);
! 
!           f = frag_more (2);
!           fix_new_exp (frag_now, f - frag_now->fr_literal, 2,
!                        &op->exp, false, BFD_RELOC_16);
!           number_to_chars_bigendian (f, 0, 2);
!         }
!       else
!         {
!           f = frag_more (1);
!           number_to_chars_bigendian (f, byte, 1);
!           frag_var (rs_machine_dependent, 2, 2,
!                     ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_UNDF),
!                     op->exp.X_add_symbol,
!                     op->exp.X_add_number, f);
!         }
        return 3;
      }
  
*************** md_convert_frag (abfd, sec, fragP)
*** 2425,2430 ****
--- 2436,2442 ----
       fragS *fragP;
  {
    fixS *fixp;
+   long value;
    long disp;
    char *buffer_address = fragP->fr_literal;
  
*************** md_convert_frag (abfd, sec, fragP)
*** 2434,2441 ****
    buffer_address += fragP->fr_fix;
  
    /* The displacement of the address, from current location.  */
!   disp = fragP->fr_symbol ? S_GET_VALUE (fragP->fr_symbol) : 0;
!   disp = (disp + fragP->fr_offset) - object_address;
    disp += symbol_get_frag (fragP->fr_symbol)->fr_address;
  
    switch (fragP->fr_subtype)
--- 2446,2453 ----
    buffer_address += fragP->fr_fix;
  
    /* The displacement of the address, from current location.  */
!   value = fragP->fr_symbol ? S_GET_VALUE (fragP->fr_symbol) : 0;
!   disp = (value + fragP->fr_offset) - object_address;
    disp += symbol_get_frag (fragP->fr_symbol)->fr_address;
  
    switch (fragP->fr_subtype)
*************** md_convert_frag (abfd, sec, fragP)
*** 2485,2508 ****
        break;
  
      case ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS5):
!       fragP->fr_opcode[0] = fragP->fr_opcode[0] << 5;
!       fragP->fr_opcode[0] |= disp & 0x1f;
        break;
  
      case ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS9):
        fragP->fr_opcode[0] = (fragP->fr_opcode[0] << 3);
        fragP->fr_opcode[0] |= 0xE0;
!       fix_new (fragP, fragP->fr_fix + 1, 1,
  	       fragP->fr_symbol, fragP->fr_offset, 0, BFD_RELOC_8);
        fragP->fr_fix += 1;
        break;
  
      case ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS16):
        fragP->fr_opcode[0] = (fragP->fr_opcode[0] << 3);
!       fragP->fr_opcode[0] |= 0xE2;
!       fix_new (fragP, fragP->fr_fix, 2,
! 	       fragP->fr_symbol, fragP->fr_offset, 0, BFD_RELOC_16);
!       fragP->fr_fix += 1;
        break;
  
      case ENCODE_RELAX (STATE_XBCC_BRANCH, STATE_BYTE):
--- 2497,2533 ----
        break;
  
      case ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS5):
!       fragP->fr_opcode[0] = fragP->fr_opcode[0] << 6;
!       if ((fragP->fr_opcode[0] & 0x0ff) == 0x0c0)
!         fragP->fr_opcode[0] |= disp & 0x1f;
!       else
!         fragP->fr_opcode[0] |= value & 0x1f;
        break;
  
      case ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS9):
        fragP->fr_opcode[0] = (fragP->fr_opcode[0] << 3);
        fragP->fr_opcode[0] |= 0xE0;
!       fix_new (fragP, fragP->fr_fix, 1,
  	       fragP->fr_symbol, fragP->fr_offset, 0, BFD_RELOC_8);
        fragP->fr_fix += 1;
        break;
  
      case ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS16):
        fragP->fr_opcode[0] = (fragP->fr_opcode[0] << 3);
!       fragP->fr_opcode[0] |= 0xe2;
!       if ((fragP->fr_opcode[0] & 0x0ff) == 0x0fa)
!         {
!           fixp = fix_new (fragP, fragP->fr_fix, 2,
!                           fragP->fr_symbol, fragP->fr_offset,
!                           1, BFD_RELOC_16_PCREL);
!           fixp->fx_pcrel_adjust = 2;
!         }
!       else
!         {
!           fix_new (fragP, fragP->fr_fix, 2,
!                    fragP->fr_symbol, fragP->fr_offset, 0, BFD_RELOC_16);
!         }
!       fragP->fr_fix += 2;
        break;
  
      case ENCODE_RELAX (STATE_XBCC_BRANCH, STATE_BYTE):
*************** md_estimate_size_before_relax (fragP, se
*** 2621,2633 ****
        else
  	{
  	  /* Switch the indexed operation to 16-bit mode.  */
! 	  if ((fragP->fr_opcode[1] & 0x21) == 0x20)
! 	    fragP->fr_opcode[1] = (fragP->fr_opcode[1] >> 3) | 0xc0 | 0x02;
! 
  	  fragP->fr_fix++;
  	  fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
  		   fragP->fr_offset, 0, BFD_RELOC_16);
! 	  fragP->fr_fix += 2;
  	  frag_wane (fragP);
  	}
        break;
--- 2646,2657 ----
        else
  	{
  	  /* Switch the indexed operation to 16-bit mode.  */
!           fragP->fr_opcode[0] = fragP->fr_opcode[0] << 3;
!           fragP->fr_opcode[0] |= 0xe2;
  	  fragP->fr_fix++;
  	  fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
  		   fragP->fr_offset, 0, BFD_RELOC_16);
! 	  fragP->fr_fix++;
  	  frag_wane (fragP);
  	}
        break;
Index: testsuite/gas/m68hc11/opers12.d
===================================================================
RCS file: /cvs/src/src/gas/testsuite/gas/m68hc11/opers12.d,v
retrieving revision 1.2
diff -p -r1.2 opers12.d
*** opers12.d	2000/11/26 21:18:15	1.2
--- opers12.d	2001/01/11 20:15:58
*************** Disassembly of section .text:
*** 25,31 ****
  0+031 <L1\+0x28> ldaa	\[257,Y\]
  0+035 <L1\+0x2c> ldab	\[32767,SP\]
  0+039 <L1\+0x30> ldd	\[32768,PC\]
! 0+03d <L1\+0x34> ldd	0,PC
  0+040 <L1\+0x37> std	A,X
  0+042 <L1\+0x39> ldx	B,X
  0+044 <L1\+0x3b> stx	D,Y
--- 25,31 ----
  0+031 <L1\+0x28> ldaa	\[257,Y\]
  0+035 <L1\+0x2c> ldab	\[32767,SP\]
  0+039 <L1\+0x30> ldd	\[32768,PC\]
! 0+03d <L1\+0x34> ldd	9,PC
  0+040 <L1\+0x37> std	A,X
  0+042 <L1\+0x39> ldx	B,X
  0+044 <L1\+0x3b> stx	D,Y
*************** Disassembly of section .text:
*** 68,76 ****
  0+0b8 <L1\+0xaf> trap	#128
  0+0ba <L1\+0xb1> trap	#255
  0+0bc <L2> movw	1,X, 2,X
! 0+0c0 <L2\+0x4> movw	0+0ffff <L2\+0xff43>, 0000ffff <L2\+0xff43>
! 0+0c6 <L2\+0xa> movw	0+0ffff <L2\+0xff43>, 1,X
! 0+0cb <L2\+0xf> movw	#0+0ffff <L2\+0xff43>, 1,X
  0+0d0 <L2\+0x14> movw	0+03 <start\+0x3>, 0+08 <start\+0x8>
  0+0d6 <L2\+0x1a> movw	#0+03 <start\+0x3>, 0+03 <start\+0x3>
  0+0dc <L2\+0x20> movw	#0+03 <start\+0x3>, 1,X
--- 68,76 ----
  0+0b8 <L1\+0xaf> trap	#128
  0+0ba <L1\+0xb1> trap	#255
  0+0bc <L2> movw	1,X, 2,X
! 0+0c0 <L2\+0x4> movw	0+0ffff <bb\+0xd7ff>, 0000ffff <bb\+0xd7ff>
! 0+0c6 <L2\+0xa> movw	0+0ffff <bb\+0xd7ff>, 1,X
! 0+0cb <L2\+0xf> movw	#0+0ffff <bb\+0xd7ff>, 1,X
  0+0d0 <L2\+0x14> movw	0+03 <start\+0x3>, 0+08 <start\+0x8>
  0+0d6 <L2\+0x1a> movw	#0+03 <start\+0x3>, 0+03 <start\+0x3>
  0+0dc <L2\+0x20> movw	#0+03 <start\+0x3>, 1,X
*************** Disassembly of section .text:
*** 78,81 ****
  0+0e6 <L2\+0x2a> movw	0+03 <start\+0x3>, 2,X
  0+0eb <L2\+0x2f> movw	0+04 <start\+0x4>, -2,X
  0+0f0 <L2\+0x34> rts
! 
--- 78,90 ----
  0+0e6 <L2\+0x2a> movw	0+03 <start\+0x3>, 2,X
  0+0eb <L2\+0x2f> movw	0+04 <start\+0x4>, -2,X
  0+0f0 <L2\+0x34> rts
! 0+0f1 <post_indexed_pb> leas	0,X
! 0+0f5 <t2> leax	4,Y
! 0+0f7 <t2\+0x2> leax	100,X
! 0+0fb <t2\+0x6> leas	110,SP
! 0+0ff <t2\+0xa> leay	10,X
! 0+103 <t2\+0xe> leas	10240,Y
! 0+107 <t2\+0x12> leas	255,PC
! 0+10b <t2\+0x16> leas	0,PC
! 0+10f <t2\+0x1a> leas	255,PC
! 0+113 <t2\+0x1e> leas	0,PC
Index: testsuite/gas/m68hc11/opers12.s
===================================================================
RCS file: /cvs/src/src/gas/testsuite/gas/m68hc11/opers12.s,v
retrieving revision 1.2
diff -p -r1.2 opers12.s
*** opers12.s	2000/11/26 21:18:15	1.2
--- opers12.s	2001/01/11 20:15:58
***************
*** 6,16 ****
  	globl start
  
  start:
! 	anda	[12,x]
  	ldaa	#10
  	ldx	L1
  L1:	ldy	,x
! 	addd	1,y
  	subd	-1,y
  	eora	15,y
  	eora	-16,y
--- 6,16 ----
  	globl start
  
  start:
! 	anda	[12,x]		; Indexed indirect
  	ldaa	#10
  	ldx	L1
  L1:	ldy	,x
! 	addd	1,y		; Offset from register
  	subd	-1,y
  	eora	15,y
  	eora	-16,y
*************** L1:	ldy	,x
*** 22,54 ****
  	orab	-256,x
  	anda	256,x
  	andb	-257,x
! 	anda	[12,x]
  	ldaa	[257,y]
  	ldab	[32767,sp]
  	ldd	[32768,pc]
  	ldd	L1,pc
! 	std	a,x
  	ldx	b,x
  	stx	d,y
! 	addd	1,+x
  	addd	2,+x
  	addd	8,+x
! 	addd	1,sp+
  	addd	2,sp+
  	addd	8,sp+
! 	subd	1,-y
  	subd	2,-y
  	subd	8,-y
! 	addd	1,y-
  	addd	2,y-
  	addd	8,y-
! 	std	[d,x]
  	std	[d,y]
  	std	[d,sp]
  	std	[d,pc]
  	beq	L1
  	lbeq	start
  	lbcc	L2
  	movb	start, 1,x
  	movw	1,x, start
  	movb	start, 1,+x
--- 22,57 ----
  	orab	-256,x
  	anda	256,x
  	andb	-257,x
! 	anda	[12,x]		; Indexed indirect (16-bit offset)
  	ldaa	[257,y]
  	ldab	[32767,sp]
  	ldd	[32768,pc]
  	ldd	L1,pc
! 	std	a,x		; Two-reg index
  	ldx	b,x
  	stx	d,y
! 	addd	1,+x		; Pre-Auto inc
  	addd	2,+x
  	addd	8,+x
! 	addd	1,sp+		; Post-Auto inc
  	addd	2,sp+
  	addd	8,sp+
! 	subd	1,-y		; Pre-Auto dec
  	subd	2,-y
  	subd	8,-y
! 	addd	1,y-		; Post-Auto dec
  	addd	2,y-
  	addd	8,y-
! 	std	[d,x]		; Indexed indirect with two reg index
  	std	[d,y]
  	std	[d,sp]
  	std	[d,pc]
  	beq	L1
  	lbeq	start
  	lbcc	L2
+ ;;
+ ;; Move insn with various operands
+ ;; 
  	movb	start, 1,x
  	movw	1,x, start
  	movb	start, 1,+x
*************** L2:	
*** 80,82 ****
--- 83,109 ----
  	movw 3,+2,x
  	movw 4,-2,x
  	rts
+ ;;
+ ;; Post-index byte with relocation
+ ;; 
+ post_indexed_pb:
+ t1:
+ 	leas	abort,x
+ t2:
+ 	leax	t2-t1,y
+ 	leax	toto,x
+ 	leas	toto+titi,sp
+ 	leay	titi,x
+ 	leas	bb,y
+ 	leas	min5b,pc
+ 	leas	max5b,pc
+ 	leas	min9b,pc
+ 	leas	max9b,pc
+ 
+ titi = 10
+ toto = 100
+ min5b= -15
+ max5b= 15
+ min9b= -255
+ max9b= 255
+ bb = 10240

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