emit-rtl.c (gen_lowpart_common): Skip count by HARD_REGNO_NREGS.
authorRichard Henderson <rth@cygnus.com>
Thu, 2 Apr 1998 01:33:22 +0000 (17:33 -0800)
committerRichard Henderson <rth@gcc.gnu.org>
Thu, 2 Apr 1998 01:33:22 +0000 (17:33 -0800)
* emit-rtl.c (gen_lowpart_common): Skip count by HARD_REGNO_NREGS.
(gen_highpart): Likewise.

From-SVN: r18945

gcc/ChangeLog
gcc/emit-rtl.c

index 80459cb1f7b77abbfea2a340eef197cba24d193f..9eea255533b131969aa42b461041b77c2c099153 100644 (file)
@@ -3,6 +3,9 @@ Thu Apr  2 01:01:34 1998  Richard Henderson  <rth@cygnus.com>
        * configure (alpha-*-linuxecoff, alpha-*-linux-gnulibc1):
        Run fixincludes.
 
+       * emit-rtl.c (gen_lowpart_common): Skip count by HARD_REGNO_NREGS.
+       (gen_highpart): Likewise.
+       
 Wed Apr  1 22:26:22 1998  Jeffrey A Law  (law@cygnus.com)
 
        * fold-const.c optimze_bit_field_compare): Initialize rnbitpos,
index 54af3b8bc5b0783650db5c63e20177a916190d1e..fe99e8e6866261f977b423b87f319ba8b5c81ff7 100644 (file)
@@ -652,6 +652,17 @@ gen_lowpart_common (mode, x)
            : gen_rtx_SUBREG (mode, SUBREG_REG (x), SUBREG_WORD (x) + word));
   else if (GET_CODE (x) == REG)
     {
+      /* Let the backend decide how many registers to skip.  This is needed
+         in particular for Sparc64 where fp regs are smaller than a word.  */
+      /* ??? Note that subregs are now ambiguous, in that those against
+        pseudos are sized by the Word Size, while those against hard
+        regs are sized by the underlying register size.  Better would be
+        to always interpret the subreg offset parameter as bytes or bits.  */
+
+      if (WORDS_BIG_ENDIAN && REGNO (x) < FIRST_PSEUDO_REGISTER)
+       word = (HARD_REGNO_NREGS (REGNO (x), GET_MODE (x))
+               - HARD_REGNO_NREGS (REGNO (x), mode));
+
       /* If the register is not valid for MODE, return 0.  If we don't
         do this, there is no way to fix up the resulting REG later.  
         But we do do this if the current REG is not valid for its
@@ -1002,17 +1013,16 @@ gen_highpart (mode, x)
     {
       int word = 0;
 
-      if (! WORDS_BIG_ENDIAN
-         && GET_MODE_SIZE (GET_MODE (x)) > UNITS_PER_WORD)
-       word = ((GET_MODE_SIZE (GET_MODE (x))
-                - MAX (GET_MODE_SIZE (mode), UNITS_PER_WORD))
-               / UNITS_PER_WORD);
-
-      /*
-       * ??? This fails miserably for complex values being passed in registers
-       * where the sizeof the real and imaginary part are not equal to the
-       * sizeof SImode.  FIXME
-       */
+      /* Let the backend decide how many registers to skip.  This is needed
+         in particular for sparc64 where fp regs are smaller than a word.  */
+      /* ??? Note that subregs are now ambiguous, in that those against
+        pseudos are sized by the Word Size, while those against hard
+        regs are sized by the underlying register size.  Better would be
+        to always interpret the subreg offset parameter as bytes or bits.  */
+
+      if (! WORDS_BIG_ENDIAN && REGNO (x) < FIRST_PSEUDO_REGISTER)
+       word = (HARD_REGNO_NREGS (REGNO (x), GET_MODE (x))
+               - HARD_REGNO_NREGS (REGNO (x), mode));
 
       if (REGNO (x) < FIRST_PSEUDO_REGISTER
          /* integrate.c can't handle parts of a return value register.  */