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]

[PATCH, ARM] Fix out-of-range immediate assembly errors on 64-bit hosts


Hi,

This patch fixes some immediate-out-of-range errors for VBIC, VORR etc. on 64-bit hosts. On such hosts, the X_add_number field of expressions will be 64 bits wide. INT_MIN and INT_MAX are used to signify that any immediate may be accepted for parse_immediate: unfortunately on a 64-bit host, 0xff000000 for instance is then interpreted as a positive integer outside that range. I've just made passing INT_MIN/INT_MAX disable the check instead, though I'm not very fond of that solution.

Tested with cross to arm-none-eabi from x86_64-unknown-linux-gnu.

OK to apply?

Cheers,

Julian

ChangeLog (gas):

    * config/tc-arm.c (parse_immediate): Handle 64-bit X_add_number
    case.
    (parse_big_immediate): Likewise.
Index: config/tc-arm.c
===================================================================
RCS file: /cvs/src/src/gas/config/tc-arm.c,v
retrieving revision 1.274
diff -c -p -r1.274 tc-arm.c
*** config/tc-arm.c	7 Jun 2006 14:32:28 -0000	1.274
--- config/tc-arm.c	9 Jun 2006 16:41:36 -0000
*************** parse_immediate (char **str, int *val, i
*** 3887,3893 ****
        return FAIL;
      }
  
!   if (exp.X_add_number < min || exp.X_add_number > max)
      {
        inst.error = _("immediate value out of range");
        return FAIL;
--- 3887,3894 ----
        return FAIL;
      }
  
!   if ((min != INT_MIN || max != INT_MAX)
!       && (exp.X_add_number < min || exp.X_add_number > max))
      {
        inst.error = _("immediate value out of range");
        return FAIL;
*************** parse_big_immediate (char **str, int i)
*** 3910,3916 ****
    my_get_expression (&exp, &ptr, GE_OPT_PREFIX_BIG);
  
    if (exp.X_op == O_constant)
!     inst.operands[i].imm = exp.X_add_number;
    else if (exp.X_op == O_big
             && LITTLENUM_NUMBER_OF_BITS * exp.X_add_number > 32
             && LITTLENUM_NUMBER_OF_BITS * exp.X_add_number <= 64)
--- 3911,3928 ----
    my_get_expression (&exp, &ptr, GE_OPT_PREFIX_BIG);
  
    if (exp.X_op == O_constant)
!     {
!       inst.operands[i].imm = exp.X_add_number & 0xffffffff;
!       /* If we're on a 64-bit host, then a 64-bit number can be returned using
! 	 O_constant.  We have to be careful not to break compilation for
! 	 32-bit X_add_number, though.  */
!       if ((exp.X_add_number & ~0xffffffffl) != 0)
! 	{
!           inst.operands[i].reg = ((exp.X_add_number >> 16) >> 16) & 0xffffffff;
! 	  inst.operands[i].regisimm = 1;
! 	}
!     }
! 
    else if (exp.X_op == O_big
             && LITTLENUM_NUMBER_OF_BITS * exp.X_add_number > 32
             && LITTLENUM_NUMBER_OF_BITS * exp.X_add_number <= 64)

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