Enhancement for avx-vnni patch
[binutils-gdb.git] / gas / expr.c
index 23a6a003b9c82ac9a3ed42682c0e2bf845564be3..6f74de786d2297cb88ea6a84ff4c375a09c14639 100644 (file)
@@ -224,8 +224,8 @@ static valueT
 generic_bignum_to_int32 (void)
 {
   valueT number =
-          ((generic_bignum[1] & LITTLENUM_MASK) << LITTLENUM_NUMBER_OF_BITS)
-          | (generic_bignum[0] & LITTLENUM_MASK);
+    ((((valueT) generic_bignum[1] & LITTLENUM_MASK) << LITTLENUM_NUMBER_OF_BITS)
+     | ((valueT) generic_bignum[0] & LITTLENUM_MASK));
   number &= 0xffffffff;
   return number;
 }
@@ -1722,7 +1722,7 @@ add_to_result (expressionS *resultP, offsetT amount, int rhs_highbit)
   valueT ures = resultP->X_add_number;
   valueT uamount = amount;
 
-  resultP->X_add_number += amount;
+  resultP->X_add_number += uamount;
 
   resultP->X_extrabit ^= rhs_highbit;
 
@@ -1738,7 +1738,7 @@ subtract_from_result (expressionS *resultP, offsetT amount, int rhs_highbit)
   valueT ures = resultP->X_add_number;
   valueT uamount = amount;
 
-  resultP->X_add_number -= amount;
+  resultP->X_add_number -= uamount;
 
   resultP->X_extrabit ^= rhs_highbit;
 
@@ -1933,12 +1933,21 @@ expr (int rankarg,              /* Larger # is higher rank.  */
            case O_multiply:            resultP->X_add_number *= v; break;
            case O_divide:              resultP->X_add_number /= v; break;
            case O_modulus:             resultP->X_add_number %= v; break;
-           case O_left_shift:          resultP->X_add_number <<= v; break;
+           case O_left_shift:
+             /* We always use unsigned shifts.  According to the ISO
+                C standard, left shift of a signed type having a
+                negative value is undefined behaviour, and right
+                shift of a signed type having negative value is
+                implementation defined.  Left shift of a signed type
+                when the result overflows is also undefined
+                behaviour.  So don't trigger ubsan warnings or rely
+                on characteristics of the compiler.  */
+             resultP->X_add_number
+               = (valueT) resultP->X_add_number << (valueT) v;
+             break;
            case O_right_shift:
-             /* We always use unsigned shifts, to avoid relying on
-                characteristics of the compiler used to compile gas.  */
-             resultP->X_add_number =
-               (offsetT) ((valueT) resultP->X_add_number >> (valueT) v);
+             resultP->X_add_number
+               = (valueT) resultP->X_add_number >> (valueT) v;
              break;
            case O_bit_inclusive_or:    resultP->X_add_number |= v; break;
            case O_bit_or_not:          resultP->X_add_number |= ~v; break;