[AArch64] Add support for :tlsdesc: and TLSDESC_ADR_PREL21
[deliverable/binutils-gdb.git] / gas / config / tc-crx.c
index b347d8b828a16d582aed192daea37b8af38e7b0a..a2314b713b38a93755f780b13f55219963a39719 100644 (file)
@@ -1,6 +1,5 @@
 /* tc-crx.c -- Assembler code for the CRX CPU core.
-   Copyright 2004, 2005, 2006, 2007, 2008, 2009, 2010
-   Free Software Foundation, Inc.
+   Copyright (C) 2004-2015 Free Software Foundation, Inc.
 
    Contributed by Tomer Levi, NSC, Israel.
    Originally written for GAS 2.12 by Tomer Levi, NSC, Israel.
@@ -24,6 +23,7 @@
    MA 02110-1301, USA.  */
 
 #include "as.h"
+#include "bfd_stdint.h"
 #include "safe-ctype.h"
 #include "dwarf2dbg.h"
 #include "opcode/crx.h"
@@ -1173,9 +1173,7 @@ getreg_image (reg r)
 static long
 getconstant (long x, int nbits)
 {
-  /* The following expression avoids overflow if
-     'nbits' is the number of bits in 'bfd_vma'.  */
-  return (x & ((((1 << (nbits - 1)) - 1) << 1) | 1));
+  return x & ((((1U << (nbits - 1)) - 1) << 1) | 1);
 }
 
 /* Print a constant value to 'output_opcode':
@@ -1326,17 +1324,11 @@ get_number_of_operands (void)
 static op_err
 check_range (long *num, int bits, int unsigned flags, int update)
 {
-  long min, max;
+  uint32_t max;
   int retval = OP_LEGAL;
   int bin;
-  long upper_64kb = 0xFFFF0000;
-  long value = *num;
-
-  /* For hosts witah longs bigger than 32-bits make sure that the top 
-     bits of a 32-bit negative value read in by the parser are set,
-     so that the correct comparisons are made.  */
-  if (value & 0x80000000)
-    value |= (-1L << 31);
+  uint32_t upper_64kb = 0xffff0000;
+  uint32_t value = *num;
 
   /* Verify operand value is even.  */
   if (flags & OP_EVEN)
@@ -1360,7 +1352,12 @@ check_range (long *num, int bits, int unsigned flags, int update)
 
   if (flags & OP_SHIFT)
     {
+      /* All OP_SHIFT args are also OP_SIGNED, so we want to keep the
+        sign.  However, right shift of a signed type with a negative
+        value is implementation defined.  See ISO C 6.5.7.  So we use
+        an unsigned type and sign extend afterwards.  */
       value >>= 1;
+      value = (value ^ 0x40000000) - 0x40000000;
       if (update)
        *num = value;
     }
@@ -1382,13 +1379,14 @@ check_range (long *num, int bits, int unsigned flags, int update)
     {
       int is_dispu4 = 0;
 
-      int mul = (instruction->flags & DISPUB4) ? 1 
-               : (instruction->flags & DISPUW4) ? 2
-               : (instruction->flags & DISPUD4) ? 4 : 0;
+      uint32_t mul = (instruction->flags & DISPUB4 ? 1 
+                     : instruction->flags & DISPUW4 ? 2
+                     : instruction->flags & DISPUD4 ? 4
+                     : 0);
       
       for (bin = 0; bin < cst4_maps; bin++)
        {
-         if (value == (mul * bin))
+         if (value == mul * bin)
            {
              is_dispu4 = 1;
              if (update)
@@ -1405,7 +1403,7 @@ check_range (long *num, int bits, int unsigned flags, int update)
 
       for (bin = 0; bin < cst4_maps; bin++)
        {
-         if (value == cst4_map[bin])
+         if (value == (uint32_t) cst4_map[bin])
            {
              is_cst4 = 1;
              if (update)
@@ -1418,17 +1416,19 @@ check_range (long *num, int bits, int unsigned flags, int update)
     }
   else if (flags & OP_SIGNED)
     {
-      max = (1 << (bits - 1)) - 1;
-      min = - (1 << (bits - 1));
-      if ((value > max) || (value < min))
+      max = 1;
+      max = max << (bits - 1);
+      value += max;
+      max = ((max - 1) << 1) | 1;
+      if (value > max)
        retval = OP_OUT_OF_RANGE;
     }
   else if (flags & OP_UNSIGNED)
     {
-      max = ((((1 << (bits - 1)) - 1) << 1) | 1);
-      min = 0;
-      if (((unsigned long) value > (unsigned long) max) 
-           || ((unsigned long) value < (unsigned long) min))
+      max = 1;
+      max = max << (bits - 1);
+      max = ((max - 1) << 1) | 1;
+      if (value > max)
        retval = OP_OUT_OF_RANGE;
     }
   return retval;
This page took 0.032134 seconds and 4 git commands to generate.