From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 7655 invoked by alias); 20 Dec 2007 16:37:53 -0000 Received: (qmail 7646 invoked by uid 22791); 20 Dec 2007 16:37:52 -0000 X-Spam-Check-By: sourceware.org Received: from dmz.mips-uk.com (HELO dmz.mips-uk.com) (194.74.144.194) by sourceware.org (qpsmtpd/0.31) with ESMTP; Thu, 20 Dec 2007 16:37:42 +0000 Received: from internal-mx1 ([192.168.192.240] helo=ukservices1.mips.com) by dmz.mips-uk.com with esmtp (Exim 3.35 #1 (Debian)) id 1J5OOu-0003vO-00; Thu, 20 Dec 2007 16:37:36 +0000 Received: from perivale.mips.com ([192.168.192.200]) by ukservices1.mips.com with esmtp (Exim 3.36 #1 (Debian)) id 1J5OOp-0007zj-00; Thu, 20 Dec 2007 16:37:31 +0000 Received: from macro (helo=localhost) by perivale.mips.com with local-esmtp (Exim 4.63) (envelope-from ) id 1J5OOp-0002H1-Og; Thu, 20 Dec 2007 16:37:31 +0000 Date: Thu, 20 Dec 2007 16:41:00 -0000 From: "Maciej W. Rozycki" To: Daniel Jacobowitz cc: gdb-patches@sourceware.org, David Ung , "Maciej W. Rozycki" Subject: Re: mips-tdep.c: Sign-extend pointers for n32 In-Reply-To: <20071219161552.GA1280@caradoc.them.org> Message-ID: References: <20071216184625.GA22905@caradoc.them.org> <20071219152826.GA30488@caradoc.them.org> <20071219161552.GA1280@caradoc.them.org> MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII X-MIPS-Technologies-UK-MailScanner: Found to be clean X-MIPS-Technologies-UK-MailScanner-From: macro@mips.com Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2007-12/txt/msg00341.txt.bz2 On Wed, 19 Dec 2007, Daniel Jacobowitz wrote: > I happen to know otherwise. I once wasted several days tracking down > a bug in the Linux kernel's IP checksumming implementation which > resulted in incorrectly extended values in registers; there are MIPS > parts which really do behave unpredictably when you use 32-bit > arithmetic operations on them (specifically the Broadcom SB1). I recall the issue and the problem was broken inline assembly, which used 64-bit operations to produce results associated with 32-bit integer types and register constraints. This is a different issue and is doomed to fail indeed. > And I believe a compiler would be justified in using such instructions > on a signed char argument. Yes, of course -- it is actually meant to and thus will never produce results outside the sign-extended 32-bit range (remember that before extending, bits 31:16 or 31:8 as appropriate are zeroes, so after a zero-extension the values still fall within the signed 32-bit range). And most ALU operations do not care about the signedness, but there are two exceptions that came to my mind after I sent you the previous letter, specifically signed "div/mult", and GCC indeed uses signed/unsigned load operations for 16/8-bit types as appropriate, so even though chasing the relevant document that would state it explicitly seems a non-trivial task, I think sign-extension of such small signed integers is implied. Also n32 builds on compatibility with o32 and the most definite o32 document which is: "SYSTEM V APPLICATION BINARY INTERFACE, MIPS RISC Processor Supplement, 3rd Edition" says: "All integer-valued arguments are passed as 32-bit words, with signed or unsigned bytes and halfwords expanded (promoted) as necessary." Thus I have taken your suggestion into account and modified the change further as follows and regression tested it as previously, successfully. Well, I guess it actually means we do not really have a terribly good coverage here -- I suppose a set of test cases that would check that promotion is performed correctly with manual calls would be useful. 2007-12-19 David Ung Maciej W. Rozycki * mips-tdep.c (mips_n32n64_push_dummy_call): Sign-extend integers and 32-bit pointers as required by the ABI. OK to apply? Maciej 12741-0.diff Index: binutils-quilt/src/gdb/mips-tdep.c =================================================================== --- binutils-quilt.orig/src/gdb/mips-tdep.c 2007-12-19 15:15:45.000000000 +0000 +++ binutils-quilt/src/gdb/mips-tdep.c 2007-12-20 16:13:31.000000000 +0000 @@ -3184,8 +3184,21 @@ purpose register. */ if (argreg <= MIPS_LAST_ARG_REGNUM) { - LONGEST regval = - extract_unsigned_integer (val, partial_len); + LONGEST regval; + + /* Sign extend pointers, 32-bit integers and signed + 16-bit and 8-bit integers; everything else is taken + as is. */ + + if ((partial_len == 4 + && (typecode == TYPE_CODE_PTR + || typecode == TYPE_CODE_INT)) + || (partial_len < 4 + && typecode == TYPE_CODE_INT + && !TYPE_UNSIGNED (arg_type))) + regval = extract_signed_integer (val, partial_len); + else + regval = extract_unsigned_integer (val, partial_len); /* A non-floating-point argument being passed in a general register. If a struct or union, and if