This is the mail archive of the binutils@sourceware.org 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]

Fix error message for badly composed ARM ldrex and strexinstructions


Hi Guys,

  I am applying the attached patch to fix a problem with the ARM port
  of gas assembling badly composed LDREX and STREX instructions -
  under some circumstances it could produce a very confusing error
  message.

Cheers
  Nick

gas/ChangeLog
2005-11-10  Nick Clifton  <nickc@redhat.com>

	* config/tc-arm.c (BAD_ADDR_MODE): Define.
	(arm_reg_parse_multi): Return NULL rather than FAIL.
	(arm_reg_parse): Fix comment, the function returns FAIL rather
	than NULL if it is unable to parse the register name.
	(do_ldrex): Use BAD_ADDR_MODE.
	Change error message for PC-relative addressing.
	(do_strex): Likewise.
	(do_t_ldrex): Use BAD_ADDR_MODE.
	(do_t_strex): Likewise.

gas/testsuite/ChangeLog
2005-11-10  Nick Clifton  <nickc@redhat.com>

	* gas/arm/archv6t2-bad.s: Add tests of badly composed ldrex and
	strex instructions.
	* gas/arm/archv6t2-bad.l: Add expected error messages.
	* gas/arm/r15-bad.l: Adjust error messages for r15 usage in ldrex
	and strex instructions.

Index: gas/config/tc-arm.c
===================================================================
RCS file: /cvs/src/src/gas/config/tc-arm.c,v
retrieving revision 1.232
diff -c -3 -p -r1.232 tc-arm.c
*** gas/config/tc-arm.c	28 Oct 2005 00:50:03 -0000	1.232
--- gas/config/tc-arm.c	9 Nov 2005 18:25:52 -0000
*************** struct asm_opcode
*** 502,507 ****
--- 502,508 ----
  #define BAD_OVERLAP	_("registers may not be the same")
  #define BAD_HIREG	_("lo register required")
  #define BAD_THUMB32	_("instruction not supported in Thumb16 mode")
+ #define BAD_ADDR_MODE   _("instruction does not accept this addressing mode");
  
  static struct hash_control *arm_ops_hsh;
  static struct hash_control *arm_cond_hsh;
*************** arm_reg_parse_multi (char **ccp)
*** 843,849 ****
  
  #ifdef REGISTER_PREFIX
    if (*start != REGISTER_PREFIX)
!     return FAIL;
    start++;
  #endif
  #ifdef OPTIONAL_REGISTER_PREFIX
--- 844,850 ----
  
  #ifdef REGISTER_PREFIX
    if (*start != REGISTER_PREFIX)
!     return NULL;
    start++;
  #endif
  #ifdef OPTIONAL_REGISTER_PREFIX
*************** arm_reg_parse_multi (char **ccp)
*** 869,875 ****
  }
  
  /* As above, but the register must be of type TYPE, and the return
!    value is the register number or NULL.  */
  
  static int
  arm_reg_parse (char **ccp, enum arm_reg_type type)
--- 870,876 ----
  }
  
  /* As above, but the register must be of type TYPE, and the return
!    value is the register number or FAIL.  */
  
  static int
  arm_reg_parse (char **ccp, enum arm_reg_type type)
*************** parse_address (char **str, int i)
*** 3282,3287 ****
--- 3283,3290 ----
  
    if (skip_past_char (&p, '[') == FAIL)
      {
+       char * saved_p;
+ 
        if (skip_past_char (&p, '=') == FAIL)
  	{
  	  /* bare address - translate to PC-relative offset */
*************** parse_address (char **str, int i)
*** 3292,3297 ****
--- 3295,3302 ----
  	}
        /* else a load-constant pseudo op, no special treatment needed here */
  
+       saved_p = p;
+ 
        if (my_get_expression (&inst.reloc.exp, &p, GE_NO_PREFIX))
  	return FAIL;
  
*************** do_ldrex (void)
*** 4825,4834 ****
    constraint (!inst.operands[1].isreg || !inst.operands[1].preind
  	      || inst.operands[1].postind || inst.operands[1].writeback
  	      || inst.operands[1].immisreg || inst.operands[1].shifted
! 	      || inst.operands[1].negative,
! 	      _("instruction does not accept this addressing mode"));
! 
!   constraint (inst.operands[1].reg == REG_PC, BAD_PC);
  
    constraint (inst.reloc.exp.X_op != O_constant
  	      || inst.reloc.exp.X_add_number != 0,
--- 4830,4849 ----
    constraint (!inst.operands[1].isreg || !inst.operands[1].preind
  	      || inst.operands[1].postind || inst.operands[1].writeback
  	      || inst.operands[1].immisreg || inst.operands[1].shifted
! 	      || inst.operands[1].negative
! 	      /* This can arise if the programmer has written
! 		   strex rN, rM, foo
! 		 or if they have mistakenly used a register name as the last
! 		 operand,  eg:
! 		   strex rN, rM, rX
! 		 It is very difficult to distinguish between these two cases
! 		 because "rX" might actually be a label. ie the register
! 		 name has been occluded by a symbol of the same name. So we
! 		 just generate a general 'bad addressing mode' type error
! 		 message and leave it up to the programmer to discover the
! 		 true cause and fix their mistake.  */
! 	      || (inst.operands[1].reg == REG_PC),
! 	      BAD_ADDR_MODE);
  
    constraint (inst.reloc.exp.X_op != O_constant
  	      || inst.reloc.exp.X_add_number != 0,
*************** do_strex (void)
*** 5268,5277 ****
    constraint (!inst.operands[2].isreg || !inst.operands[2].preind
  	      || inst.operands[2].postind || inst.operands[2].writeback
  	      || inst.operands[2].immisreg || inst.operands[2].shifted
! 	      || inst.operands[2].negative,
! 	      _("instruction does not accept this addressing mode"));
! 
!   constraint (inst.operands[2].reg == REG_PC, BAD_PC);
  
    constraint (inst.operands[0].reg == inst.operands[1].reg
  	      || inst.operands[0].reg == inst.operands[2].reg, BAD_OVERLAP);
--- 5283,5292 ----
    constraint (!inst.operands[2].isreg || !inst.operands[2].preind
  	      || inst.operands[2].postind || inst.operands[2].writeback
  	      || inst.operands[2].immisreg || inst.operands[2].shifted
! 	      || inst.operands[2].negative
! 	      /* See comment in do_ldrex().  */
! 	      || (inst.operands[2].reg == REG_PC),
! 	      BAD_ADDR_MODE);
  
    constraint (inst.operands[0].reg == inst.operands[1].reg
  	      || inst.operands[0].reg == inst.operands[2].reg, BAD_OVERLAP);
*************** do_t_ldrex (void)
*** 6703,6709 ****
  	      || inst.operands[1].postind || inst.operands[1].writeback
  	      || inst.operands[1].immisreg || inst.operands[1].shifted
  	      || inst.operands[1].negative,
! 	      _("instruction does not accept this addressing mode"));
  
    inst.instruction |= inst.operands[0].reg << 12;
    inst.instruction |= inst.operands[1].reg << 16;
--- 6718,6724 ----
  	      || inst.operands[1].postind || inst.operands[1].writeback
  	      || inst.operands[1].immisreg || inst.operands[1].shifted
  	      || inst.operands[1].negative,
! 	      BAD_ADDR_MODE);
  
    inst.instruction |= inst.operands[0].reg << 12;
    inst.instruction |= inst.operands[1].reg << 16;
*************** do_t_strex (void)
*** 7578,7584 ****
  	      || inst.operands[2].postind || inst.operands[2].writeback
  	      || inst.operands[2].immisreg || inst.operands[2].shifted
  	      || inst.operands[2].negative,
! 	      _("instruction does not accept this addressing mode"));
  
    inst.instruction |= inst.operands[0].reg << 8;
    inst.instruction |= inst.operands[1].reg << 12;
--- 7593,7599 ----
  	      || inst.operands[2].postind || inst.operands[2].writeback
  	      || inst.operands[2].immisreg || inst.operands[2].shifted
  	      || inst.operands[2].negative,
! 	      BAD_ADDR_MODE);
  
    inst.instruction |= inst.operands[0].reg << 8;
    inst.instruction |= inst.operands[1].reg << 12;
Index: gas/testsuite/gas/arm/archv6t2-bad.l
===================================================================
RCS file: /cvs/src/src/gas/testsuite/gas/arm/archv6t2-bad.l,v
retrieving revision 1.1
diff -c -3 -p -r1.1 archv6t2-bad.l
*** gas/testsuite/gas/arm/archv6t2-bad.l	15 Mar 2005 20:38:00 -0000	1.1
--- gas/testsuite/gas/arm/archv6t2-bad.l	9 Nov 2005 18:25:52 -0000
***************
*** 36,38 ****
--- 36,40 ----
  [^:]*:51: Warning: destination register same as write-back base
  [^:]*:52: Warning: destination register same as write-back base
  [^:]*:53: Warning: source register same as write-back base
+ [^:]*:59: Error: instruction does not accept this addressing mode -- `ldrex r0,r2'
+ [^:]*:60: Error: instruction does not accept this addressing mode -- `strex r1,r0,r2'
Index: gas/testsuite/gas/arm/archv6t2-bad.s
===================================================================
RCS file: /cvs/src/src/gas/testsuite/gas/arm/archv6t2-bad.s,v
retrieving revision 1.1
diff -c -3 -p -r1.1 archv6t2-bad.s
*** gas/testsuite/gas/arm/archv6t2-bad.s	15 Mar 2005 20:38:00 -0000	1.1
--- gas/testsuite/gas/arm/archv6t2-bad.s	9 Nov 2005 18:25:52 -0000
*************** x:
*** 51,53 ****
--- 51,61 ----
  	ldrsbt	r0,[r0]
  	ldrsht	r0,[r0]
  	strht	r0,[r0]
+ 
+ 	@ Bug reported by user.  GAS used to issue an error message
+ 	@ "r15 not allowed here" for these two instructions because
+ 	@ it thought that the "r2" operand was a PC-relative branch
+ 	@ to a label called "r2".
+ 	ldrex	r0, r2
+ 	strex	r1, r0, r2
+ 	
\ No newline at end of file
Index: gas/testsuite/gas/arm/r15-bad.l
===================================================================
RCS file: /cvs/src/src/gas/testsuite/gas/arm/r15-bad.l,v
retrieving revision 1.2
diff -c -3 -p -r1.2 r15-bad.l
*** gas/testsuite/gas/arm/r15-bad.l	18 May 2005 05:40:10 -0000	1.2
--- gas/testsuite/gas/arm/r15-bad.l	9 Nov 2005 18:25:52 -0000
***************
*** 30,36 ****
  [^:]*:33: Error: r15 not allowed here -- `umaal r1,r2,r3,r15'
  [^:]*:34: Error: r15 not allowed here -- `strex r15,r2,[[]r3[]]'
  [^:]*:35: Error: r15 not allowed here -- `strex r1,r15,[[]r3[]]'
! [^:]*:36: Error: r15 not allowed here -- `strex r1,r2,[[]r15[]]'
  [^:]*:37: Error: r15 not allowed here -- `ssat r15,#1,r2'
  [^:]*:38: Error: r15 not allowed here -- `ssat r1,#1,r15'
  [^:]*:39: Error: r15 not allowed here -- `ssat16 r15,#1,r2'
--- 30,36 ----
  [^:]*:33: Error: r15 not allowed here -- `umaal r1,r2,r3,r15'
  [^:]*:34: Error: r15 not allowed here -- `strex r15,r2,[[]r3[]]'
  [^:]*:35: Error: r15 not allowed here -- `strex r1,r15,[[]r3[]]'
! [^:]*:36: Error: instruction does not accept this addressing mode -- `strex r1,r2,[[]r15[]]'
  [^:]*:37: Error: r15 not allowed here -- `ssat r15,#1,r2'
  [^:]*:38: Error: r15 not allowed here -- `ssat r1,#1,r15'
  [^:]*:39: Error: r15 not allowed here -- `ssat16 r15,#1,r2'
***************
*** 58,64 ****
  [^:]*:61: Error: r15 not allowed here -- `pkhtb r1,r15,r3'
  [^:]*:62: Error: r15 not allowed here -- `pkhtb r1,r2,r15'
  [^:]*:63: Error: r15 not allowed here -- `ldrex r15,[[]r2[]]'
! [^:]*:64: Error: r15 not allowed here -- `ldrex r1,[[]r15[]]'
  [^:]*:65: Error: r15 not allowed here -- `swp r15,r2,[[]r3[]]'
  [^:]*:66: Error: r15 not allowed here -- `swp r1,r15,[[]r3[]]'
  [^:]*:67: Error: r15 not allowed here -- `swp r1,r2,[[]r15[]]'
--- 58,64 ----
  [^:]*:61: Error: r15 not allowed here -- `pkhtb r1,r15,r3'
  [^:]*:62: Error: r15 not allowed here -- `pkhtb r1,r2,r15'
  [^:]*:63: Error: r15 not allowed here -- `ldrex r15,[[]r2[]]'
! [^:]*:64: Error: instruction does not accept this addressing mode -- `ldrex r1,[[]r15[]]'
  [^:]*:65: Error: r15 not allowed here -- `swp r15,r2,[[]r3[]]'
  [^:]*:66: Error: r15 not allowed here -- `swp r1,r15,[[]r3[]]'
  [^:]*:67: Error: r15 not allowed here -- `swp r1,r2,[[]r15[]]'

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