larger than a byte offset.  */
 static bool no_cond_jump_promotion = false;
 
+/* This will be set from an expression parser hook if there's any
+   applicable operator involved in an expression.  */
+static enum {
+  expr_operator_none,
+  expr_operator_present,
+  expr_large_value,
+} expr_mode;
+
 /* Encode SSE instructions with VEX prefix.  */
 static unsigned int sse2avx;
 
     }
   else if ((flag_code == CODE_16BIT) ^ (i.prefix[DATA_PREFIX] != 0))
     guess_suffix = WORD_MNEM_SUFFIX;
+  else if (flag_code != CODE_64BIT || !(i.prefix[REX_PREFIX] & REX_W))
+    guess_suffix = LONG_MNEM_SUFFIX;
 
   for (op = i.operands; --op >= 0;)
     if (operand_type_check (i.types[op], imm))
 
   intel_syntax = -intel_syntax;
   exp->X_md = 0;
+  expr_mode = expr_operator_none;
 
 #if ((defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)) \
       && !defined (LEX_AT)) \
     i386_intel_simplify (exp);
 
   /* If not 64bit, massage value, to account for wraparound when !BFD64.  */
-  if (size == 4 && exp->X_op == O_constant && !object_64bit)
+  if (size <= 4 && expr_mode == expr_operator_present
+      && exp->X_op == O_constant && !object_64bit)
     exp->X_add_number = extend_to_32bit_address (exp->X_add_number);
 
   return got_reloc;
   if (gotfree_input_line)
     input_line_pointer = gotfree_input_line;
 
+  expr_mode = expr_operator_none;
   exp_seg = expression (exp);
 
   /* For .insn immediates there may be a size specifier.  */
 
       /* If not 64bit, sign/zero extend val, to account for wraparound
         when !BFD64.  */
-      if (flag_code != CODE_64BIT && !object_64bit)
+      if (expr_mode == expr_operator_present
+         && flag_code != CODE_64BIT && !object_64bit)
        exp->X_add_number = extend_to_32bit_address (exp->X_add_number);
     }
 #if (defined (OBJ_AOUT) || defined (OBJ_MAYBE_AOUT))
   if (gotfree_input_line)
     input_line_pointer = gotfree_input_line;
 
+  expr_mode = expr_operator_none;
   exp_seg = expression (exp);
 
   SKIP_WHITESPACE ();
 
         If not 64bit, sign/zero extend val, to account for wraparound
         when !BFD64.  */
-      if (flag_code != CODE_64BIT && !object_64bit)
+      if (expr_mode == expr_operator_present
+         && flag_code != CODE_64BIT && !object_64bit)
        exp->X_add_number = extend_to_32bit_address (exp->X_add_number);
     }
 
     }
 }
 
+#ifdef BFD64
+/* To maintain consistency with !BFD64 builds of gas record, whether any
+   (binary) operator was involved in an expression.  As expressions are
+   evaluated in only 32 bits when !BFD64, we use this to decide whether to
+   truncate results.  */
+bool i386_record_operator (operatorT op,
+                          const expressionS *left,
+                          const expressionS *right)
+{
+  if (op == O_absent)
+    return false;
+
+  if (!left)
+    {
+      /* Since the expression parser applies unary operators fine to bignum
+        operands, we don't need to be concerned of respective operands not
+        fitting in 32 bits.  */
+      if (right->X_op == O_constant && right->X_unsigned
+         && !fits_in_unsigned_long (right->X_add_number))
+       return false;
+    }
+  /* This isn't entirely right: The pattern can also result when constant
+     expressions are folded (e.g. 0xffffffff + 1).  */
+  else if ((left->X_op == O_constant && left->X_unsigned
+           && !fits_in_unsigned_long (left->X_add_number))
+          || (right->X_op == O_constant && right->X_unsigned
+              && !fits_in_unsigned_long (right->X_add_number)))
+    expr_mode = expr_large_value;
+
+  if (expr_mode != expr_large_value)
+    expr_mode = expr_operator_present;
+
+  return false;
+}
+#endif
 \f
 #if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
 const char *md_shortopts = "kVQ:sqnO::";
 
--- /dev/null
+       .text
+const:
+       add     $0x101, %cl
+       add     $0x10001, %cx
+       add     $0x100000001, %ecx
+       add     0x100000001, %ecx
+
+       add     $0x100, %cl
+       add     $0x10000, %cx
+       add     $0x100000000, %ecx
+       add     0x100000000, %ecx
+
+       add     $-0x101, %cl
+       add     $-0x10001, %cx
+       add     $-0x100000001, %ecx
+       add     -0x100000001, %ecx
+
+       add     $-0x100, %cl
+       add     $-0x10000, %cx
+       add     $-0x100000000, %ecx
+
+       add     $0xffffffffffffff00, %cl
+       add     $0xffffffffffff0000, %cx
+       add     $0xffffffff00000000, %ecx
+       add     0xffffffff00000000, %ecx
+
+       # The next two might as well not have a disagnostic issued, but if
+       # there is one (as is the case now), then it should be independent
+       # of BFD64.
+       and     $~0xff, %cl
+       and     $~0xffff, %cx
+       and     $~0xffffffff, %ecx
+       and     ~0xffffffff, %ecx
+
+       and     $0xff+2, %cl
+       and     $0xffff+2, %cx
+       and     $0xffffffff+2, %ecx
+       and     0xffffffff+2, %ecx
+
+       and     $0xff*2, %cl
+       and     $0xffff*2, %cx
+       and     $0xffffffff*2, %ecx
+       and     0xffffffff*2, %ecx
+
+       .data
+       .byte 0x101
+       .byte -0x100
+       .byte 0xffffffffffffff00
+#      .byte ~0xffffffffffffff00
+       .byte ~0xff
+       .byte 0xff+2
+       .byte 0xff*2
+
+       .p2align 4
+       .word 0x10001
+       .word -0x10000
+       .word 0xffffffffffff0000
+#      .word ~0xffffffffffff0000
+       .word ~0xffff
+       .word 0xffff+2
+       .word 0xffff*2
+
+       .p2align 4
+       .long 0x100000001
+       .long -0x100000000
+       .long 0xffffffff00000000
+#      .long ~0xffffffff00000000
+       .long ~0xffffffff
+#      .long 0xffffffff+2
+#      .long 0xffffffff*2
+
+       .p2align 4
+       .quad 0x100000001
+       .quad -0x100000000
+       .quad 0xffffffff00000000
+#      .quad ~0xffffffff00000000
+       .quad ~0xffffffff
+#      .quad 0xffffffff+2
+#      .quad 0xffffffff*2
 
 #objdump: -dw
 #name: i386 displacements / immediates (32-bit)
+#warning_output: disp-imm-32.e
 
 .*: +file format .*
 
 [      ]*[a-f0-9]+:    8b 40 ff                mov    -0x1\(%eax\),%eax
 [      ]*[a-f0-9]+:    62 f1 7c 48 28 40 ff    vmovaps -0x40\(%eax\),%zmm0
 [      ]*[a-f0-9]+:    83 c1 ff                add    \$0xffffffff,%ecx
-[      ]*[a-f0-9]+:    8b 40 01                mov    0x1\(%eax\),%eax
-[      ]*[a-f0-9]+:    62 f1 7c 48 28 40 01    vmovaps 0x40\(%eax\),%zmm0
-[      ]*[a-f0-9]+:    83 c1 01                add    \$0x1,%ecx
+[      ]*[a-f0-9]+:    8b (40 01 +|80 01 00 00 00)     mov    0x1\(%eax\),%eax
+[      ]*[a-f0-9]+:    62 f1 7c 48 28 (40 01|80 40 00 00 00)   vmovaps 0x40\(%eax\),%zmm0
+[      ]*[a-f0-9]+:    (83 c1 01 +|81 c1 01 00 00 00)          add    \$0x1,%ecx
 #pass