From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 21277 invoked by alias); 7 Jun 2014 12:34:20 -0000 Mailing-List: contact binutils-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: binutils-owner@sourceware.org Received: (qmail 21265 invoked by uid 89); 7 Jun 2014 12:34:19 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-0.9 required=5.0 tests=AWL,BAYES_20,FREEMAIL_FROM,RCVD_IN_DNSWL_NONE,SPF_PASS autolearn=ham version=3.3.2 X-HELO: mail-pd0-f171.google.com Received: from mail-pd0-f171.google.com (HELO mail-pd0-f171.google.com) (209.85.192.171) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-SHA encrypted) ESMTPS; Sat, 07 Jun 2014 12:34:17 +0000 Received: by mail-pd0-f171.google.com with SMTP id y13so3529676pdi.30 for ; Sat, 07 Jun 2014 05:34:15 -0700 (PDT) X-Received: by 10.68.134.198 with SMTP id pm6mr11987404pbb.9.1402144455491; Sat, 07 Jun 2014 05:34:15 -0700 (PDT) Received: from bubble.grove.modra.org ([58.160.155.134]) by mx.google.com with ESMTPSA id is5sm48256847pbb.8.2014.06.07.05.34.11 for (version=TLSv1.1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Sat, 07 Jun 2014 05:34:13 -0700 (PDT) Received: by bubble.grove.modra.org (Postfix, from userid 1000) id E39ACEA4AC8; Sat, 7 Jun 2014 22:04:07 +0930 (CST) Date: Sat, 07 Jun 2014 12:34:00 -0000 From: Alan Modra To: Sebastian Huber Cc: binutils@sourceware.org Subject: Re: 32-bit PowerPC sdata linker problem Message-ID: <20140607123407.GN5592@bubble.grove.modra.org> Mail-Followup-To: Sebastian Huber , binutils@sourceware.org References: <53918356.3040102@embedded-brains.de> <20140606105420.GH5592@bubble.grove.modra.org> <5391A4BF.2030308@embedded-brains.de> <5391A6A4.6050708@embedded-brains.de> <20140606121531.GI5592@bubble.grove.modra.org> <5391B8B7.8030908@embedded-brains.de> <20140606130559.GK5592@bubble.grove.modra.org> <5391C0E8.7010409@embedded-brains.de> <20140606134915.GL5592@bubble.grove.modra.org> <5391CCFB.5060206@embedded-brains.de> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <5391CCFB.5060206@embedded-brains.de> User-Agent: Mutt/1.5.21 (2010-09-15) X-IsSubscribed: yes X-SW-Source: 2014-06/txt/msg00069.txt.bz2 On Fri, Jun 06, 2014 at 04:15:23PM +0200, Sebastian Huber wrote: > On 2014-06-06 15:49, Alan Modra wrote: > >On Fri, Jun 06, 2014 at 03:23:52PM +0200, Sebastian Huber wrote: > >>>On 2014-06-06 15:05, Alan Modra wrote: > >>>> >On Fri, Jun 06, 2014 at 02:48:55PM +0200, Sebastian Huber wrote: > >>>>> >> cmplwi cr0, \_REG, ppc_exc_lock_std@sdarel > >>>>> >> > >>>>> >> .endm > >>>>> >> > >>>>> >>I guess, I have to rewrite this a bit. > >>>> > > >>>> >Doesn't using a cmpwi rather than cmplwi work? > >>>> > > >>> > >>>No, the cmplwi uses 0x0000 || UIMM with the cmpwi we have > >>>EXTS(SIMM), but the upper 16-bit must be zero so that the comparison > >>>works in the macro. > >Oh, of course. Perhaps I should make cmpli accept both signed and > >unsigned 16-bit fields. > > I think our usage of this cmplwi with the implicit truncation from > the linker is quite a hack. On the other hand it worked for several > years. Applied. bfd/ * elf32-ppc.c (ppc_elf_relocate_section): Treat field of cmpli insn as a bitfield; Use complain_overflow_bitfield. * elf64-ppc.c (ppc64_elf_relocate_section): Likewise. opcodes/ * ppc-opc.c (UISIGNOPT): Define and use with cmpli. gas/ * config/tc-ppc.c (ppc_insert_operand): Handle PPC_OPERAND_SIGNOPT on unsigned fields. Comment on PPC_OPERAND_SIGNOPT signed fields in 64-bit mode. gold/ * powerpc.cc (relocate): Treat field of cmpli insn as a bitfield. -- Alan Modra Australia Development Lab, IBM diff --git a/bfd/elf32-ppc.c b/bfd/elf32-ppc.c index 1bea6f8..344845d 100644 --- a/bfd/elf32-ppc.c +++ b/bfd/elf32-ppc.c @@ -9147,10 +9147,11 @@ ppc_elf_relocate_section (bfd *output_bfd, unsigned int insn; insn = bfd_get_32 (input_bfd, contents + (rel->r_offset & ~3)); - if ((insn & (0x3f << 26)) == 28u << 26 /* andi */ - || (insn & (0x3f << 26)) == 24u << 26 /* ori */ - || (insn & (0x3f << 26)) == 26u << 26 /* xori */ - || (insn & (0x3f << 26)) == 10u << 26 /* cmpli */) + if ((insn & (0x3f << 26)) == 10u << 26 /* cmpli */) + complain = complain_overflow_bitfield; + else if ((insn & (0x3f << 26)) == 28u << 26 /* andi */ + || (insn & (0x3f << 26)) == 24u << 26 /* ori */ + || (insn & (0x3f << 26)) == 26u << 26 /* xori */) complain = complain_overflow_unsigned; } if (howto->complain_on_overflow != complain) diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c index e7e2e39..b8d7465 100644 --- a/bfd/elf64-ppc.c +++ b/bfd/elf64-ppc.c @@ -14648,14 +14648,15 @@ ppc64_elf_relocate_section (bfd *output_bfd, enum complain_overflow complain = complain_overflow_signed; insn = bfd_get_32 (input_bfd, contents + (rel->r_offset & ~3)); - if (howto->rightshift == 0 - ? ((insn & (0x3f << 26)) == 28u << 26 /* andi */ - || (insn & (0x3f << 26)) == 24u << 26 /* ori */ - || (insn & (0x3f << 26)) == 26u << 26 /* xori */ - || (insn & (0x3f << 26)) == 10u << 26 /* cmpli */) - : ((insn & (0x3f << 26)) == 29u << 26 /* andis */ - || (insn & (0x3f << 26)) == 25u << 26 /* oris */ - || (insn & (0x3f << 26)) == 27u << 26 /* xoris */)) + if ((insn & (0x3f << 26)) == 10u << 26 /* cmpli */) + complain = complain_overflow_bitfield; + else if (howto->rightshift == 0 + ? ((insn & (0x3f << 26)) == 28u << 26 /* andi */ + || (insn & (0x3f << 26)) == 24u << 26 /* ori */ + || (insn & (0x3f << 26)) == 26u << 26 /* xori */) + : ((insn & (0x3f << 26)) == 29u << 26 /* andis */ + || (insn & (0x3f << 26)) == 25u << 26 /* oris */ + || (insn & (0x3f << 26)) == 27u << 26 /* xoris */)) complain = complain_overflow_unsigned; if (howto->complain_on_overflow != complain) { diff --git a/gas/config/tc-ppc.c b/gas/config/tc-ppc.c index 2c8ce6a..ff4ea64 100644 --- a/gas/config/tc-ppc.c +++ b/gas/config/tc-ppc.c @@ -1781,10 +1781,23 @@ ppc_insert_operand (unsigned long insn, right = max & -max; min = 0; - if ((operand->flags & PPC_OPERAND_SIGNED) != 0) + if ((operand->flags & PPC_OPERAND_SIGNOPT) != 0) + { + /* Extend the allowed range for addis to [-65536, 65535]. + Similarly for some VLE high part insns. For 64-bit it + would be good to disable this for signed fields since the + value is sign extended into the high 32 bits of the register. + If the value is, say, an address, then we might care about + the high bits. However, gcc as of 2014-06 uses unsigned + values when loading the high part of 64-bit constants using + lis. + Use the same extended range for cmpli, to allow at least + [-32768, 65535]. */ + min = ~max & -right; + } + else if ((operand->flags & PPC_OPERAND_SIGNED) != 0) { - if ((operand->flags & PPC_OPERAND_SIGNOPT) == 0) - max = (max >> 1) & -right; + max = (max >> 1) & -right; min = ~max & -right; } diff --git a/gold/powerpc.cc b/gold/powerpc.cc index bd3994a..96432ed 100644 --- a/gold/powerpc.cc +++ b/gold/powerpc.cc @@ -7409,14 +7409,15 @@ Target_powerpc::Relocate::relocate( Insn insn = elfcpp::Swap<32, big_endian>::readval(iview); overflow = Reloc::CHECK_SIGNED; - if (overflow == Reloc::CHECK_LOW_INSN - ? ((insn & (0x3f << 26)) == 28u << 26 /* andi */ - || (insn & (0x3f << 26)) == 24u << 26 /* ori */ - || (insn & (0x3f << 26)) == 26u << 26 /* xori */ - || (insn & (0x3f << 26)) == 10u << 26 /* cmpli */) - : ((insn & (0x3f << 26)) == 29u << 26 /* andis */ - || (insn & (0x3f << 26)) == 25u << 26 /* oris */ - || (insn & (0x3f << 26)) == 27u << 26 /* xoris */)) + if ((insn & (0x3f << 26)) == 10u << 26 /* cmpli */) + overflow = Reloc::CHECK_BITFIELD; + else if (overflow == Reloc::CHECK_LOW_INSN + ? ((insn & (0x3f << 26)) == 28u << 26 /* andi */ + || (insn & (0x3f << 26)) == 24u << 26 /* ori */ + || (insn & (0x3f << 26)) == 26u << 26 /* xori */) + : ((insn & (0x3f << 26)) == 29u << 26 /* andis */ + || (insn & (0x3f << 26)) == 25u << 26 /* oris */ + || (insn & (0x3f << 26)) == 27u << 26 /* xoris */)) overflow = Reloc::CHECK_UNSIGNED; } diff --git a/opcodes/ppc-opc.c b/opcodes/ppc-opc.c index 1d27961..a5cfe1a 100644 --- a/opcodes/ppc-opc.c +++ b/opcodes/ppc-opc.c @@ -654,8 +654,11 @@ const struct powerpc_operand powerpc_operands[] = #define UI TO + 1 { 0xffff, 0, NULL, NULL, 0 }, +#define UISIGNOPT UI + 1 + { 0xffff, 0, NULL, NULL, PPC_OPERAND_SIGNOPT }, + /* The IMM field in an SE_IM5 instruction. */ -#define UI5 UI + 1 +#define UI5 UISIGNOPT + 1 { 0x1f, 4, NULL, NULL, 0 }, /* The OIMM field in an SE_OIM5 instruction. */ @@ -3500,10 +3503,10 @@ const struct powerpc_opcode powerpc_opcodes[] = { {"dozi", OP(9), OP_MASK, M601, PPCNONE, {RT, RA, SI}}, -{"cmplwi", OPL(10,0), OPL_MASK, PPCCOM, PPCNONE, {OBF, RA, UI}}, -{"cmpldi", OPL(10,1), OPL_MASK, PPC64, PPCNONE, {OBF, RA, UI}}, -{"cmpli", OP(10), OP_MASK, PPC, PPCNONE, {BF, L, RA, UI}}, -{"cmpli", OP(10), OP_MASK, PWRCOM, PPC, {BF, RA, UI}}, +{"cmplwi", OPL(10,0), OPL_MASK, PPCCOM, PPCNONE, {OBF, RA, UISIGNOPT}}, +{"cmpldi", OPL(10,1), OPL_MASK, PPC64, PPCNONE, {OBF, RA, UISIGNOPT}}, +{"cmpli", OP(10), OP_MASK, PPC, PPCNONE, {BF, L, RA, UISIGNOPT}}, +{"cmpli", OP(10), OP_MASK, PWRCOM, PPC, {BF, RA, UISIGNOPT}}, {"cmpwi", OPL(11,0), OPL_MASK, PPCCOM, PPCNONE, {OBF, RA, SI}}, {"cmpdi", OPL(11,1), OPL_MASK, PPC64, PPCNONE, {OBF, RA, SI}},