From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 12070 invoked by alias); 12 Aug 2006 17:20:02 -0000 Received: (qmail 12044 invoked by uid 22791); 12 Aug 2006 17:20:01 -0000 X-Spam-Check-By: sourceware.org Received: from mx1.redhat.com (HELO mx1.redhat.com) (66.187.233.31) by sourceware.org (qpsmtpd/0.31) with ESMTP; Sat, 12 Aug 2006 18:19:58 +0100 Received: from int-mx1.corp.redhat.com (int-mx1.corp.redhat.com [172.16.52.254]) by mx1.redhat.com (8.12.11.20060308/8.12.11) with ESMTP id k7CHJuN0027767 for ; Sat, 12 Aug 2006 13:19:56 -0400 Received: from devserv.devel.redhat.com (devserv.devel.redhat.com [172.16.58.1]) by int-mx1.corp.redhat.com (8.12.11.20060308/8.12.11) with ESMTP id k7CHJprF009121 for ; Sat, 12 Aug 2006 13:19:51 -0400 Received: from devserv.devel.redhat.com (localhost.localdomain [127.0.0.1]) by devserv.devel.redhat.com (8.12.11.20060308/8.12.11) with ESMTP id k7CHJoD5025088 for ; Sat, 12 Aug 2006 13:19:50 -0400 Received: (from aviro@localhost) by devserv.devel.redhat.com (8.12.11.20060308/8.12.11/Submit) id k7CHJoQr025086 for cgen@sourceware.org; Sat, 12 Aug 2006 13:19:50 -0400 Date: Sat, 12 Aug 2006 17:20:00 -0000 From: Alexander Viro To: cgen@sourceware.org Subject: [RFC] cgen_parse_signed_integer() and 64bit bugs Message-ID: <20060812171950.GA25038@devserv.devel.redhat.com> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.4.1i Mailing-List: contact cgen-help@sourceware.org; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: cgen-owner@sourceware.org X-SW-Source: 2006-q3/txt/msg00026.txt.bz2 [apologies if it ends up double-posted] Consider the following example (on FRV): setlos #0xffffffff,gr4 FRV is a 32bit target and instruction above takes a 16bit immediate that gets sign-expanded. So when we run native gas(1) or cross-build on e.g. i386 we will get no complaints: 1 0000 88FCFFFF setlos #0xffffffff,gr4 Everything is fine - 16bit all-ones gets sign-expanded to 32bit all-ones. Perhaps writing it as setlos #-1,gr4 would be cleaner, perhaps it would not, but in any case gas takes either form without any complaints and produces expected results. Unfortunately, as soon as you move to 64bit host, you'll get breakage. Note that this is not a theoretical example - it's pulled straight from arch/frv/lib/tlb-flush.S in Linux kernel. Similar examples for other architectures exist in a lot of places waiting for cross-toolchain to be moved to another host. Mechanism of this particular breakage is pretty simple: return cgen_parse_signed_integer (cd, strp, opindex, valuep); in the very end of parse_uslo16() in cpu/frv.opc is sensitive to word size of _host_. That's documented behaviour, so in this case the obvious answer would be "so truncate the value and sign-expand it after the call". As the matter of fact, _any_ 32bit target using that puppy should be doing that. Each case where such fixup is not done means a portability bug. And such bugs exist: * frv.opc never does fixups. Each instance is a bug. * m32r.opc never does fixups. Buggy. * m32c.opc never does fixups. Buggy. * mt.opc has something that might be a fixup, but it's (a) broken and (b) #if 0'd. Buggy. * iq2000.opc does manual fixups. Correct. That's 4 out of 5. Unfortunately, the situation is even messier. We can do manual fixups, all right. But every time we describe something as h-sint we get a call inserted into *-asm.c. And for those we can't deal with that way. Potential solutions: * deal with those suckers manually in frv-asm.c, etc. Unacceptable, since fixes will be lost the next time somebody reruns cgen. * add cgen_parse_signed_32bit() that would do fixups and h-s32 in addition to h-sint. Teach cgen to produce cgen_parse_signed_32bit() for those. Possible, but requires messing with cgen guts. * change the rules and make cgen_parse_signed_integer() to do fixups. Unfortunately, that means changes of behaviour for sh64-*.cpu. All uses of h-sint in there are for 32 or fewer bits, so we are not breaking any valid code, but currently we *do* fail for 0xffffffff as argument and after that change we won't. Plus there might be out-of-tree users in similar situations. Suggestions?