+2021-06-07 Jan Beulich <jbeulich@suse.com>
+
+ * config/tc-i386.c (extend_to_32bit_address): New.
+ (x86_cons, i386_finalize_immediate, md_apply_fix): Use it.
+ (signed_cons): Use object_64bit.
+ * testsuite/gas/i386/wrap32.s, testsuite/gas/i386/wrap32-data.d,
+ testsuite/gas/i386/wrap32-text.d: New.
+ * testsuite/gas/i386/i386.exp: Run new tests.
+
2021-06-03 Alan Modra <amodra@gmail.com>
PR 1202
#endif
} /* fits_in_unsigned_long() */
+static INLINE valueT extend_to_32bit_address (addressT num)
+{
+#ifdef BFD64
+ if (fits_in_unsigned_long(num))
+ return (num ^ ((addressT) 1 << 31)) - ((addressT) 1 << 31);
+
+ if (!fits_in_signed_long (num))
+ return num & 0xffffffff;
+#endif
+
+ return num;
+}
+
static INLINE int
fits_in_disp8 (offsetT num)
{
if (intel_syntax)
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)
+ exp->X_add_number = extend_to_32bit_address (exp->X_add_number);
+
return got_reloc;
}
static void
signed_cons (int size)
{
- if (flag_code == CODE_64BIT)
+ if (object_64bit)
cons_sign = 1;
cons (size);
cons_sign = -1;
{
/* Size it properly later. */
i.types[this_operand].bitfield.imm64 = 1;
- /* If not 64bit, sign extend val. */
- if (flag_code != CODE_64BIT
- && (exp->X_add_number & ~(((addressT) 2 << 31) - 1)) == 0)
- exp->X_add_number
- = (exp->X_add_number ^ ((addressT) 1 << 31)) - ((addressT) 1 << 31);
+
+ /* If not 64bit, sign/zero extend val, to account for wraparound
+ when !BFD64. */
+ if (flag_code != CODE_64BIT)
+ exp->X_add_number = extend_to_32bit_address (exp->X_add_number);
}
#if (defined (OBJ_AOUT) || defined (OBJ_MAYBE_AOUT))
else if (OUTPUT_FLAVOR == bfd_target_aout_flavour
break;
}
#endif /* defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF) */
+
+ /* If not 64bit, massage value, to account for wraparound when !BFD64. */
+ if (!object_64bit)
+ value = extend_to_32bit_address (value);
+
*valP = value;
#endif /* !defined (TE_Mach) */
run_dump_test "addr32"
run_dump_test "code16"
run_list_test "oversized16" "-al"
+ run_dump_test "wrap32-text"
+ run_dump_test "wrap32-data"
run_dump_test "sse4_1"
run_dump_test "sse4_1-intel"
run_dump_test "sse4_2"
--- /dev/null
+#name: i386 32-bit wrapping calculations (data/ELF)
+#source: wrap32.s
+#objdump: -rsj .data
+
+.*: +file format .*
+
+RELOCATION RECORDS FOR \[\.data\]:
+
+OFFSET +TYPE +VALUE *
+0*10 (R_386_32|dir32) *sym
+0*14 (R_386_32|dir32) *sym
+0*18 (R_386_32|dir32) *sym
+0*1c (R_386_32|dir32) *sym
+0*30 (R_386_32|dir32) *sym
+0*34 (R_386_32|dir32) *sym
+0*38 (R_386_32|dir32) *sym
+0*3c (R_386_32|dir32) *sym
+
+Contents of section .data:
+ 0+00 f4 ?00 ?00 ?00 f4 ?00 ?00 ?00 90 ?00 ?00 ?00 90 ?00 ?00 ?00 .*
+ 0+10 00 ?ff ?ff ?ff 00 ?ff ?ff ?ff f4 ?00 ?00 ?00 f4 ?00 ?00 ?00 .*
+ 0+20 f4 ?02 ?00 ?70 f4 ?00 ?00 ?80 90 ?02 ?00 ?70 90 ?00 ?00 ?80 .*
+ 0+30 00 ?01 ?00 ?70 00 ?ff ?ff ?7f f4 ?02 ?00 ?70 f4 ?00 ?00 ?80 .*
--- /dev/null
+#name: i386 32-bit wrapping calculations (text)
+#source: wrap32.s
+#objdump: -dwr
+
+.*: +file format .*
+
+Disassembly of section .text:
+
+0+ <wrap>:
+[ ]*[0-9a-f]+:[ ]+b8 f4 00 00 00 mov \$0xf4,%eax
+[ ]*[0-9a-f]+:[ ]+ba f4 00 00 00 mov \$0xf4,%edx
+[ ]*[0-9a-f]+:[ ]+b8 90 00 00 00 mov \$0x90,%eax
+[ ]*[0-9a-f]+:[ ]+ba 90 00 00 00 mov \$0x90,%edx
+[ ]*[0-9a-f]+:[ ]+b8 00 ff ff ff mov \$0xffffff00,%eax[ ]+[0-9a-f]+: (R_386_32|dir32)[ ]+sym
+[ ]*[0-9a-f]+:[ ]+ba 00 ff ff ff mov \$0xffffff00,%edx[ ]+[0-9a-f]+: (R_386_32|dir32)[ ]+sym
+[ ]*[0-9a-f]+:[ ]+b8 f4 00 00 00 mov \$0xf4,%eax[ ]+[0-9a-f]+: (R_386_32|dir32)[ ]+sym
+[ ]*[0-9a-f]+:[ ]+ba f4 00 00 00 mov \$0xf4,%edx[ ]+[0-9a-f]+: (R_386_32|dir32)[ ]+sym
+[ ]*[0-9a-f]+:[ ]+c7 00 f4 00 00 00 movl \$0xf4,\(%eax\)
+[ ]*[0-9a-f]+:[ ]+c7 02 f4 00 00 00 movl \$0xf4,\(%edx\)
+[ ]*[0-9a-f]+:[ ]+c7 00 90 00 00 00 movl \$0x90,\(%eax\)
+[ ]*[0-9a-f]+:[ ]+c7 02 90 00 00 00 movl \$0x90,\(%edx\)
+[ ]*[0-9a-f]+:[ ]+c7 00 00 ff ff ff movl \$0xffffff00,\(%eax\)[ ]+[0-9a-f]+: (R_386_32|dir32)[ ]+sym
+[ ]*[0-9a-f]+:[ ]+c7 02 00 ff ff ff movl \$0xffffff00,\(%edx\)[ ]+[0-9a-f]+: (R_386_32|dir32)[ ]+sym
+[ ]*[0-9a-f]+:[ ]+c7 00 f4 00 00 00 movl \$0xf4,\(%eax\)[ ]+[0-9a-f]+: (R_386_32|dir32)[ ]+sym
+[ ]*[0-9a-f]+:[ ]+c7 02 f4 00 00 00 movl \$0xf4,\(%edx\)[ ]+[0-9a-f]+: (R_386_32|dir32)[ ]+sym
+[ ]*[0-9a-f]+:[ ]+81 c1 f4 00 00 00 add \$0xf4,%ecx
+[ ]*[0-9a-f]+:[ ]+81 c2 f4 00 00 00 add \$0xf4,%edx
+[ ]*[0-9a-f]+:[ ]+81 c1 90 00 00 00 add \$0x90,%ecx
+[ ]*[0-9a-f]+:[ ]+81 c2 90 00 00 00 add \$0x90,%edx
+[ ]*[0-9a-f]+:[ ]+81 c1 00 ff ff ff add \$0xffffff00,%ecx[ ]+[0-9a-f]+: (R_386_32|dir32)[ ]+sym
+[ ]*[0-9a-f]+:[ ]+81 c2 00 ff ff ff add \$0xffffff00,%edx[ ]+[0-9a-f]+: (R_386_32|dir32)[ ]+sym
+[ ]*[0-9a-f]+:[ ]+81 c1 f4 00 00 00 add \$0xf4,%ecx[ ]+[0-9a-f]+: (R_386_32|dir32)[ ]+sym
+[ ]*[0-9a-f]+:[ ]+81 c2 f4 00 00 00 add \$0xf4,%edx[ ]+[0-9a-f]+: (R_386_32|dir32)[ ]+sym
+[ ]*[0-9a-f]+:[ ]+81 00 f4 00 00 00 addl \$0xf4,\(%eax\)
+[ ]*[0-9a-f]+:[ ]+81 02 f4 00 00 00 addl \$0xf4,\(%edx\)
+[ ]*[0-9a-f]+:[ ]+81 00 90 00 00 00 addl \$0x90,\(%eax\)
+[ ]*[0-9a-f]+:[ ]+81 02 90 00 00 00 addl \$0x90,\(%edx\)
+[ ]*[0-9a-f]+:[ ]+81 00 00 ff ff ff addl \$0xffffff00,\(%eax\)[ ]+[0-9a-f]+: (R_386_32|dir32)[ ]+sym
+[ ]*[0-9a-f]+:[ ]+81 02 00 ff ff ff addl \$0xffffff00,\(%edx\)[ ]+[0-9a-f]+: (R_386_32|dir32)[ ]+sym
+[ ]*[0-9a-f]+:[ ]+81 00 f4 00 00 00 addl \$0xf4,\(%eax\)[ ]+[0-9a-f]+: (R_386_32|dir32)[ ]+sym
+[ ]*[0-9a-f]+:[ ]+81 02 f4 00 00 00 addl \$0xf4,\(%edx\)[ ]+[0-9a-f]+: (R_386_32|dir32)[ ]+sym
+[ ]*[0-9a-f]+:[ ]+c3 ret *
+#pass
--- /dev/null
+ .text
+wrap:
+ mov $500 - 0x100, %eax
+ mov $500 + 0xffffff00, %edx
+ mov $val - 0x100, %eax
+ mov $val + 0xffffff00, %edx
+ mov $sym - 0x100, %eax
+ mov $sym + 0xffffff00, %edx
+ mov $sym + 500 - 0x100, %eax
+ mov $sym + 500 + 0xffffff00, %edx
+
+ movl $500 - 0x100, (%eax)
+ movl $500 + 0xffffff00, (%edx)
+ movl $val - 0x100, (%eax)
+ movl $val + 0xffffff00, (%edx)
+ movl $sym - 0x100, (%eax)
+ movl $sym + 0xffffff00, (%edx)
+ movl $sym + 500 - 0x100, (%eax)
+ movl $sym + 500 + 0xffffff00, (%edx)
+
+ add $500 - 0x100, %ecx
+ add $500 + 0xffffff00, %edx
+ add $val - 0x100, %ecx
+ add $val + 0xffffff00, %edx
+ add $sym - 0x100, %ecx
+ add $sym + 0xffffff00, %edx
+ add $sym + 500 - 0x100, %ecx
+ add $sym + 500 + 0xffffff00, %edx
+
+ addl $500 - 0x100, (%eax)
+ addl $500 + 0xffffff00, (%edx)
+ addl $val - 0x100, (%eax)
+ addl $val + 0xffffff00, (%edx)
+ addl $sym - 0x100, (%eax)
+ addl $sym + 0xffffff00, (%edx)
+ addl $sym + 500 - 0x100, (%eax)
+ addl $sym + 500 + 0xffffff00, (%edx)
+
+ ret
+
+ .data
+ .long 500 - 0x100
+ .long 500 + 0xffffff00
+ .long val - 0x100
+ .long val + 0xffffff00
+ .long sym - 0x100
+ .long sym + 0xffffff00
+ .long sym + 500 - 0x100
+ .long sym + 500 + 0xffffff00
+
+ .slong 500 - 0x8fffff00
+ .slong 500 + 0x7fffff00
+ .slong val - 0x8fffff00
+ .slong val + 0x7fffff00
+ .slong sym - 0x8fffff00
+ .slong sym + 0x7fffff00
+ .slong sym + 500 - 0x8fffff00
+ .slong sym + 500 + 0x7fffff00
+
+ .equ val, 400