From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 20117 invoked by alias); 15 Oct 2009 14:41:16 -0000 Received: (qmail 20108 invoked by uid 22791); 15 Oct 2009 14:41:15 -0000 X-SWARE-Spam-Status: No, hits=-2.0 required=5.0 tests=BAYES_00,SARE_MSGID_LONG40,SPF_PASS X-Spam-Check-By: sourceware.org Received: from gv-out-0910.google.com (HELO gv-out-0910.google.com) (216.239.58.190) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Thu, 15 Oct 2009 14:41:08 +0000 Received: by gv-out-0910.google.com with SMTP id p33so133792gvf.10 for ; Thu, 15 Oct 2009 07:41:06 -0700 (PDT) MIME-Version: 1.0 Received: by 10.103.127.7 with SMTP id e7mr51477mun.117.1255617666287; Thu, 15 Oct 2009 07:41:06 -0700 (PDT) Date: Thu, 15 Oct 2009 15:33:00 -0000 Message-ID: Subject: Storing 16bit values in upper part of 32bit registers From: Markus L To: gcc@gcc.gnu.org Content-Type: text/plain; charset=ISO-8859-1 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-10/txt/msg00337.txt.bz2 Hi, I am working with an architecture where the 32bit registers (rN) are divided into high (rNh) and low (rNl) 16bit sub registers that can in principle be individually accessed by the instructions in the IS. However the IS is designed so that it is beneficial to to store 16bit values in the high part of the registers (rNh) and also the calling conventions that we want follow require 16bit values to be passed and returned in rNh. What would be the "proper way" make the compiler use the upper parts of these registers for the 16bit operands? Currently this is done by having the registers in two register classes ('full' and 'high_only') and printing the 'h' in the output template when the constraint matches the 'high_only' class. This however causes problems when converting between 16 and 32bit operands. One annoying example is returning scalar values. E.g. assume that a 32bit variable (long) is assigned to a 16bit variable (int) like in int foo(void) { long sum; ... return (int)sum; } then we want the low part of sum to be moved to the high part of the return register r0h. However TARGET_FUNCTION_VALUE only seem to allow me to return the RTX for register r0 but not the subreg for r0h so the compiler will not emit the necessary RTL to move the value from the low part of sum to r0h before the return. This (and probably many other issues that I am about to discover) makes me think that maybe this is not the ideal way to do this. I have searched the available ports but have not been able to find any which seem to use its registers in a similar way. Any advice or pointers to code to look into would be much appreciated. Thanks in advance. /Markus