This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: [PATCH/ARM][v2]PR 16722, support VLDR s/d0, =Imm
- From: Jiong Wang <jiong dot wang at arm dot com>
- To: Will Newton <will dot newton at linaro dot org>
- Cc: "binutils at sourceware dot org" <binutils at sourceware dot org>, Richard Earnshaw <Richard dot Earnshaw at arm dot com>, "nickc at redhat dot com" <nickc at redhat dot com>
- Date: Fri, 11 Jul 2014 14:39:10 +0100
- Subject: Re: [PATCH/ARM][v2]PR 16722, support VLDR s/d0, =Imm
- Authentication-results: sourceware.org; auth=none
- References: <53A016C8 dot 2090800 at arm dot com> <CANu=Dmj_WcTJR_qt3DyjwFeKLnF3GtaHLYjhrPtOrLaW268Bgg at mail dot gmail dot com>
On 10/07/14 10:47, Will Newton wrote:
On 17 June 2014 11:22, Jiong Wang <jiong.wang@arm.com> wrote:
* gas/arm/vldconst_be.d: New pattern for big-endian.
* gas/arm/thumb2_vpool_be.d: Likewise.
Sorry for taking so long to test this, but this breaks when building
on a 32bit platform.
unsigned imm1;
unsigned imm2 = 0;
if (nbytes == 8)
{
imm1 = inst.operands[1].imm;
imm2 = (inst.operands[1].regisimm ? inst.operands[1].reg
: inst.reloc.exp.X_unsigned ? 0
: ((int64_t)(imm1)) >> 32);
Hi Will,
On 32bit imm1 is a 32bit type, casting it to 64bit will not give any
useful result.
fixed.
I also get signed/unsigned comparison errors comparing
imm1/imm2 to X_add_number.
fixed.
I also fixed another logic bug on 32bit host.
these glitches should be introduced during my various local respin,
it's my fault haven't re-run the full test against the final patch, sorry.
now, pass build and check-gas on both 64 and 32 bit host.
ok to install?
thanks.
gas/
* config/tc-arm.c (add_to_lit_pool): Use "inst.operands[1].imm" for sign extension.
Casting the type of imm1 and imm2 to offsetT.
Fix one logic error when checking X_op.
--Jiong
diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c
index 2f13238..7fb8b23 100644
--- a/gas/config/tc-arm.c
+++ b/gas/config/tc-arm.c
@@ -3198,7 +3198,7 @@ add_to_lit_pool (unsigned int nbytes)
imm1 = inst.operands[1].imm;
imm2 = (inst.operands[1].regisimm ? inst.operands[1].reg
: inst.reloc.exp.X_unsigned ? 0
- : ((int64_t)(imm1)) >> 32);
+ : ((int64_t) inst.operands[1].imm) >> 32);
if (target_big_endian)
{
imm1 = imm2;
@@ -3237,11 +3237,11 @@ add_to_lit_pool (unsigned int nbytes)
&& !(pool_size & 0x7)
&& ((entry + 1) != pool->next_free_entry)
&& (pool->literals[entry].X_op == O_constant)
- && (pool->literals[entry].X_add_number == imm1)
+ && (pool->literals[entry].X_add_number == (offsetT) imm1)
&& (pool->literals[entry].X_unsigned
== inst.reloc.exp.X_unsigned)
&& (pool->literals[entry + 1].X_op == O_constant)
- && (pool->literals[entry + 1].X_add_number == imm2)
+ && (pool->literals[entry + 1].X_add_number == (offsetT) imm2)
&& (pool->literals[entry + 1].X_unsigned
== inst.reloc.exp.X_unsigned))
break;
@@ -3275,8 +3275,8 @@ add_to_lit_pool (unsigned int nbytes)
We also check to make sure the literal operand is a
constant number. */
- if (!(inst.reloc.exp.X_op == O_constant)
- || (inst.reloc.exp.X_op == O_big))
+ if (!(inst.reloc.exp.X_op == O_constant
+ || inst.reloc.exp.X_op == O_big))
{
inst.error = _("invalid type for literal pool");
return FAIL;