This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Patch to implement subreg_lsb for VRP


subreg_lsb is a generic support routine used by VRP to determine
the bit offset where a subreg begins (counting from the least
significant bit of the reg).  It may be useful elsewhere.

This patch (combined with VRP) passes make bootstrap and make check
on Dec Alpha 4.0f, Solaris 7 SPARC, and Solaris 7 x86.

ChangeLog:

Wed Nov 28 00:43:31 EST 2001  John Wehle  (john@feith.com)

	* rtl.h (subreg_lsb): Declare.
	* rtlanal.c (subreg_lsb): Implement.

Enjoy!

-- John Wehle
------------------8<------------------------8<------------------------
*** gcc/rtl.h.ORIGINAL	Wed Nov 14 21:42:17 2001
--- gcc/rtl.h	Wed Nov 28 00:37:36 2001
*************** extern const char * const note_insn_name
*** 817,822 ****
--- 817,823 ----
  #define SUBREG_BYTE(RTX) XCUINT(RTX, 1, SUBREG)
  
  /* in rtlanal.c */
+ extern unsigned int subreg_lsb		PARAMS ((rtx));
  extern unsigned int subreg_regno_offset 	PARAMS ((unsigned int, 
  							 enum machine_mode, 
  							 unsigned int, 
*** gcc/rtlanal.c.ORIGINAL	Mon Nov 12 14:19:37 2001
--- gcc/rtlanal.c	Wed Nov 28 00:36:32 2001
*************** loc_mentioned_in_p (loc, in)
*** 2734,2739 ****
--- 2734,2782 ----
    return 0;
  }
  
+ /* Given a subreg X, return the bit offset where the subreg begins
+    (counting from the least significant bit of the reg).  */
+ 
+ unsigned int
+ subreg_lsb (x)
+      rtx x;
+ {
+   enum machine_mode inner_mode = GET_MODE (SUBREG_REG (x));
+   enum machine_mode mode = GET_MODE (x);
+   unsigned int bitpos;
+   unsigned int byte;
+   unsigned int word;
+ 
+   /* A paradoxical subreg begins at bit position 0.  */
+   if (GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (inner_mode))
+     return 0;
+ 
+   if (WORDS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
+     /* If the subreg crosses a word boundary ensure that
+        it also begins and ends on a word boundary.  */
+     if ((SUBREG_BYTE (x) % UNITS_PER_WORD
+ 	 + GET_MODE_SIZE (mode)) > UNITS_PER_WORD
+ 	&& (SUBREG_BYTE (x) % UNITS_PER_WORD
+ 	    || GET_MODE_SIZE (mode) % UNITS_PER_WORD))
+ 	abort ();
+ 
+   if (WORDS_BIG_ENDIAN)
+     word = (GET_MODE_SIZE (inner_mode)
+ 	    - (SUBREG_BYTE (x) + GET_MODE_SIZE (mode))) / UNITS_PER_WORD;
+   else
+     word = SUBREG_BYTE (x) / UNITS_PER_WORD;
+   bitpos = word * BITS_PER_WORD;
+ 
+   if (BYTES_BIG_ENDIAN)
+     byte = (GET_MODE_SIZE (inner_mode)
+ 	    - (SUBREG_BYTE (x) + GET_MODE_SIZE (mode))) % UNITS_PER_WORD;
+   else
+     byte = SUBREG_BYTE (x) % UNITS_PER_WORD;
+   bitpos += byte * BITS_PER_UNIT;
+ 
+   return bitpos;
+ }
+ 
  /* This function returns the regno offset of a subreg expression.
     xregno - A regno of an inner hard subreg_reg (or what will become one).
     xmode  - The mode of xregno.
-------------------------------------------------------------------------
|   Feith Systems  |   Voice: 1-215-646-8000  |  Email: john@feith.com  |
|    John Wehle    |     Fax: 1-215-540-5495  |                         |
-------------------------------------------------------------------------


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]