From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 9927 invoked by alias); 12 Aug 2009 22:01:41 -0000 Received: (qmail 9742 invoked by uid 22791); 12 Aug 2009 22:01:40 -0000 X-SWARE-Spam-Status: No, hits=-2.8 required=5.0 tests=AWL,BAYES_00 X-Spam-Check-By: sourceware.org Received: from mpls-qmqp-01.inet.qwest.net (HELO mpls-qmqp-01.inet.qwest.net) (63.231.195.112) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Wed, 12 Aug 2009 22:01:31 +0000 Received: from flag.mcgary.org (unknown [65.101.31.122]) by mpls-qmqp-01.inet.qwest.net (Postfix) with ESMTP id 0E4011A9912 for ; Wed, 12 Aug 2009 22:01:28 +0000 (UTC) Message-ID: <4A833BB8.2090209@mcgary.org> Date: Wed, 12 Aug 2009 22:26:00 -0000 From: Greg McGary User-Agent: Thunderbird 2.0.0.21 (X11/20090320) MIME-Version: 1.0 To: gcc@gcc.gnu.org Subject: How to deal with 48-bit pointers and 32-bit integers Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Mailing-List: contact gcc-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-owner@gcc.gnu.org X-SW-Source: 2009-08/txt/msg00206.txt.bz2 I'm doing a port for an unusual new machine which is 32-bit RISCy in every way, except that it has 48-bit pointers. Pointers have a high-order 16-bit segID and low-order 32-bit seg offset. Most ALU instructions only work on 32 bits, zeroing the upper 16-bit seg ID in the result. A few ALU ops intended for pointers preserve the segID. Loads/stores to pointers with segID=0 cause an exception. The idea is to catch bugs where scalars are erroneously used as pointers. For sake of efficiency, GCC can assume that segIDs of pointers are identical for pointer arithmetic: there won't be any data objects that span segments, and pointer comparisons will always be intra-segment. I chose to define Pmode as PDImode, and write PDI patterns for pointer moves & arithmetic. POINTER_SIZE is 64 bits, UNITS_PER_WORD is 4. FUNCTION_ARG_ADVANCE arranges for both SImode and PDImode values to occupy a single register. I have the port mostly working (passes 90% of execution tests), but find myself painted into a corner in some cases. What currently vexes me is when GCC wants to promote a PDImode register (say r1) to DImode, then needs to truncate down to SImode for some kind of ALU op, say pointer subtraction. The desired quantity is the low-order 32 bits of r1, but GCC thinks the promotion to DImode implies a pair of 32-bit regs (r1, r2) and since this is a big-endian machine, it wants to deliver the low-order bits as the subreg r2. I now wonder if I can salvage my overall approach, or if I need to do things an entirely different way. I fear I might be in uncharted territory since after cursory review, I don't see any existing ports where pointers need special handling and are larger than the native int size. Comments? Advice? Greg