ubsan: aarch64: left shift of negative value
[deliverable/binutils-gdb.git] / opcodes / aarch64-dis.c
index 6b53a2c3228aea3117e0f45450dc9f192eedd6de..abed2d824c5b22075d77a78038dba389844742cc 100644 (file)
@@ -178,18 +178,15 @@ extract_all_fields (const aarch64_operand *self, aarch64_insn code)
 }
 
 /* Sign-extend bit I of VALUE.  */
-static inline int32_t
+static inline uint64_t
 sign_extend (aarch64_insn value, unsigned i)
 {
-  uint32_t ret = value;
+  uint64_t ret, sign;
 
   assert (i < 32);
-  if ((value >> i) & 0x1)
-    {
-      uint32_t val = (uint32_t)(-1) << i;
-      ret = ret | val;
-    }
-  return (int32_t) ret;
+  ret = value;
+  sign = (uint64_t) 1 << i;
+  return ((ret & (sign + sign - 1)) ^ sign) - sign;
 }
 
 /* N.B. the following inline helpfer functions create a dependency on the
@@ -348,6 +345,7 @@ aarch64_ext_reglane (const aarch64_operand *self, aarch64_opnd_info *info,
       switch (info->qualifier)
        {
        case AARCH64_OPND_QLF_S_4B:
+       case AARCH64_OPND_QLF_S_2H:
          /* L:H */
          info->reglane.index = extract_fields (code, 0, 2, FLD_H, FLD_L);
          info->reglane.regno &= 0x1f;
@@ -657,7 +655,7 @@ aarch64_ext_imm (const aarch64_operand *self, aarch64_opnd_info *info,
                 const aarch64_inst *inst ATTRIBUTE_UNUSED,
                 aarch64_operand_error *errors ATTRIBUTE_UNUSED)
 {
-  int64_t imm;
+  uint64_t imm;
 
   imm = extract_all_fields (self, code);
 
@@ -2822,14 +2820,11 @@ aarch64_decode_variant_using_iclass (aarch64_inst *inst)
       variant = i - 1;
       break;
 
-    case sve_size_013:
-      i = extract_field (FLD_size, inst->value, 0);
-      if (i == 2)
-       return FALSE;
-      if (i == 3)
-       variant = 2;
-      else
-       variant = i;
+    case sve_size_13:
+      /* Ignore low bit of this field since that is set in the opcode for
+        instructions of this iclass.  */
+      i = (extract_field (FLD_size, inst->value, 0) & 2);
+      variant = (i >> 1);
       break;
 
     case sve_shift_tsz_bhsd:
@@ -2845,6 +2840,8 @@ aarch64_decode_variant_using_iclass (aarch64_inst *inst)
 
     case sve_size_tsz_bhs:
       i = extract_fields (inst->value, 0, 2, FLD_SVE_sz, FLD_SVE_tszl_19);
+      if (i == 0)
+       return FALSE;
       while (i != 1)
        {
          if (i & 1)
This page took 0.024154 seconds and 4 git commands to generate.