This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[PATCH 16/20] MIPS/GAS: Correct types used for DEXT/DINS macros
- From: "Maciej W. Rozycki" <macro at codesourcery dot com>
- To: Richard Sandiford <rdsandiford at googlemail dot com>
- Cc: Catherine Moore <clm at codesourcery dot com>, binutils at sourceware dot org
- Date: Thu, 2 Dec 2010 19:22:28 +0000 (GMT)
- Subject: [PATCH 16/20] MIPS/GAS: Correct types used for DEXT/DINS macros
Hi,
Here's a change to correct types used for the bitfield position and
offset immediates with the DEXT and DINS macros. There are two issues:
- the "unsigned long" type may be narrower than offsetT/addressT (e.g. on
ILP32 hosts); truncation will mask overflow errors for some inputs,
- the "unsigned long" type may be wider than int (e.g. on LP64 hosts)
expected for the format specifiers used here and macro_build() is a
variadic function so implicit type conversion does not happen; this may
cause problems with some ABIs.
There's no C way to say "unsigned offsetT" (.X_add_number is typed
offsetT), but addressT is equivalent.
2010-12-02 Maciej W. Rozycki <macro@codesourcery.com>
gas/
* config/tc-mips.c (macro)[M_DEXT, M_DINS]: Correct types used
for pos and size.
OK to apply?
Maciej
binutils-gas-mips-dextins.diff
Index: binutils-fsf-trunk-quilt/gas/config/tc-mips.c
===================================================================
--- binutils-fsf-trunk-quilt.orig/gas/config/tc-mips.c 2010-12-01 21:05:51.000000000 +0000
+++ binutils-fsf-trunk-quilt/gas/config/tc-mips.c 2010-12-01 21:05:58.000000000 +0000
@@ -5268,8 +5268,9 @@ macro (struct mips_cl_insn *ip)
case M_DEXT:
{
- unsigned long pos;
- unsigned long size;
+ /* Use unsigned arithmetic. */
+ addressT pos;
+ addressT size;
if (imm_expr.X_op != O_constant || imm2_expr.X_op != O_constant)
{
@@ -5278,19 +5279,19 @@ macro (struct mips_cl_insn *ip)
}
else
{
- pos = (unsigned long) imm_expr.X_add_number;
- size = (unsigned long) imm2_expr.X_add_number;
+ pos = imm_expr.X_add_number;
+ size = imm2_expr.X_add_number;
}
if (pos > 63)
{
- as_bad (_("Improper position (%lu)"), pos);
+ as_bad (_("Improper position (%lu)"), (unsigned long) pos);
pos = 1;
}
if (size == 0 || size > 64 || (pos + size - 1) > 63)
{
as_bad (_("Improper extract size (%lu, position %lu)"),
- size, pos);
+ (unsigned long) size, (unsigned long) pos);
size = 1;
}
@@ -5309,14 +5310,16 @@ macro (struct mips_cl_insn *ip)
s = "dextm";
fmt = "t,r,+A,+G";
}
- macro_build ((expressionS *) NULL, s, fmt, treg, sreg, pos, size - 1);
+ macro_build ((expressionS *) NULL, s, fmt, treg, sreg, (int) pos,
+ (int) (size - 1));
}
break;
case M_DINS:
{
- unsigned long pos;
- unsigned long size;
+ /* Use unsigned arithmetic. */
+ addressT pos;
+ addressT size;
if (imm_expr.X_op != O_constant || imm2_expr.X_op != O_constant)
{
@@ -5325,19 +5328,19 @@ macro (struct mips_cl_insn *ip)
}
else
{
- pos = (unsigned long) imm_expr.X_add_number;
- size = (unsigned long) imm2_expr.X_add_number;
+ pos = imm_expr.X_add_number;
+ size = imm2_expr.X_add_number;
}
if (pos > 63)
{
- as_bad (_("Improper position (%lu)"), pos);
+ as_bad (_("Improper position (%lu)"), (unsigned long) pos);
pos = 1;
}
if (size == 0 || size > 64 || (pos + size - 1) > 63)
{
as_bad (_("Improper insert size (%lu, position %lu)"),
- size, pos);
+ (unsigned long) size, (unsigned long) pos);
size = 1;
}