Re: Setting precision for a PSImode type

2012-04-11 Thread Bernd Schmidt
On 04/11/2012 07:31 PM, Peter Bigot wrote:
 The biggest one is that widening from 20-bit to 32-bit is an extremely
 expensive operation: it was a 16-bit ISA, but some newer MCUs support
 an extension with 20 bits in each register and a set of new
 instructions that must be used to preserve the upper 4 bits.  Getting
 bits 19..16 of a 20-bit register down into the low bits of a 16 bit
 register requires a five-position rotate-through-carry.  The 20-bit
 enhancement to the ISA was really intended only to support a larger
 address space; to simplify validation of the machine description I've
 chosen to allow it to be used for any integer operation, but I have no
 reason to think that'll be common.

Ok. So these are pointer modes, essentially? For the target I'm working
on, I'm using the following patch, see if that helps you any. It seems
to apply to trunk, so I might as well ask for an OK if it bootstraps and
tests ok (but it has little use while these ports remain out-of-tree).


Bernd
* mode-classes.def (MODE_POINTER): New.
* machmode.h (POINTER_MODE_P): New macro.
* genopinit.c (gen_insn): Allow MODE_POINTER for some modifiers.
* expr.c (convert_move): Handle MODE_POINTER like MODE_PARTIAL_INT.
* recog.c (general_operand, immediate_operand): Allow MODE_POINTER.
* stor-layout.c (int_mode_for_mode): Likwise.
* genmodes.c (complete_mode): Likewise.
(POINTER_MODE): New macro.
(make_pointer_mode): New static function.
* emit-rtl.c (immed_double_const): Allow MODE_POINTER.
* simplify-rtx.c (simplify_immed_subreg): Likewise.
* explow.c (trunc_int_for_mode): Likewise.

Index: gcc/machmode.h
===
--- gcc/machmode.h  (revision 365245)
+++ gcc/machmode.h  (working copy)
@@ -76,6 +76,9 @@ extern const unsigned char mode_class[NU
   (GET_MODE_CLASS (MODE) == MODE_INT   \
|| GET_MODE_CLASS (MODE) == MODE_PARTIAL_INT)
 
+/* True if MODE is a pointer mode.  */
+#define POINTER_MODE_P(MODE) (GET_MODE_CLASS (MODE) == MODE_POINTER)
+
 /* Nonzero if MODE is a scalar floating point mode.  */
 #define SCALAR_FLOAT_MODE_P(MODE)  \
   (GET_MODE_CLASS (MODE) == MODE_FLOAT \
Index: gcc/genopinit.c
===
--- gcc/genopinit.c (revision 365109)
+++ gcc/genopinit.c (working copy)
@@ -368,11 +368,13 @@ gen_insn (rtx insn)
 
if (*p == 0
 (! force_int || mode_class[i] == MODE_INT
-   || mode_class[i] == MODE_VECTOR_INT)
+   || mode_class[i] == MODE_VECTOR_INT
+   || mode_class[i] == MODE_POINTER)
 (! force_partial_int
 || mode_class[i] == MODE_INT
 || mode_class[i] == MODE_PARTIAL_INT
-   || mode_class[i] == MODE_VECTOR_INT)
+   || mode_class[i] == MODE_VECTOR_INT
+   || mode_class[i] == MODE_POINTER)
 (! force_float
|| mode_class[i] == MODE_FLOAT
|| mode_class[i] == MODE_DECIMAL_FLOAT
Index: gcc/mode-classes.def
===
--- gcc/mode-classes.def(revision 365109)
+++ gcc/mode-classes.def(working copy)
@@ -23,6 +23,7 @@ along with GCC; see the file COPYING3.
   DEF_MODE_CLASS (MODE_CC),/* condition code in a register */ \
   DEF_MODE_CLASS (MODE_INT),   /* integer */  \
   DEF_MODE_CLASS (MODE_PARTIAL_INT),   /* integer with padding bits */\
+  DEF_MODE_CLASS (MODE_POINTER),   /* pointer */  \
   DEF_MODE_CLASS (MODE_FRACT), /* signed fractional number */ \
   DEF_MODE_CLASS (MODE_UFRACT),/* unsigned fractional number 
*/   \
   DEF_MODE_CLASS (MODE_ACCUM), /* signed accumulator */   \
Index: gcc/expr.c
===
--- gcc/expr.c  (revision 365245)
+++ gcc/expr.c  (working copy)
@@ -481,7 +481,8 @@ convert_move (rtx to, rtx from, int unsi
   /* Handle pointer conversion.  *//* SPEE 900220.  */
   /* Targets are expected to provide conversion insns between PxImode and
  xImode for all MODE_PARTIAL_INT modes they use, but no others.  */
-  if (GET_MODE_CLASS (to_mode) == MODE_PARTIAL_INT)
+  if (GET_MODE_CLASS (to_mode) == MODE_PARTIAL_INT
+  || GET_MODE_CLASS (to_mode) == MODE_POINTER)
 {
   enum machine_mode full_mode
= smallest_mode_for_size (GET_MODE_BITSIZE (to_mode), MODE_INT);
@@ -495,7 +496,8 @@ convert_move (rtx to, rtx from, int unsi
  to, from, UNKNOWN);
   return;
 }
-  if (GET_MODE_CLASS (from_mode) == 

Re: Setting precision for a PSImode type

2012-04-11 Thread Richard Sandiford
Bernd Schmidt ber...@codesourcery.com writes:
 On 04/11/2012 07:31 PM, Peter Bigot wrote:
 The biggest one is that widening from 20-bit to 32-bit is an extremely
 expensive operation: it was a 16-bit ISA, but some newer MCUs support
 an extension with 20 bits in each register and a set of new
 instructions that must be used to preserve the upper 4 bits.  Getting
 bits 19..16 of a 20-bit register down into the low bits of a 16 bit
 register requires a five-position rotate-through-carry.  The 20-bit
 enhancement to the ISA was really intended only to support a larger
 address space; to simplify validation of the machine description I've
 chosen to allow it to be used for any integer operation, but I have no
 reason to think that'll be common.

 Ok. So these are pointer modes, essentially? For the target I'm working
 on, I'm using the following patch, see if that helps you any. It seems
 to apply to trunk, so I might as well ask for an OK if it bootstraps and
 tests ok (but it has little use while these ports remain out-of-tree).

Not that I can approve this anyway, but: what are the properties of
MODE_POINTER vs. MODE_PARTIAL_INT?

It seems odd on the face of it for POINTER_MODE_P (Pmode) to be false
on the majority of targets.  But that's probably just a naming thing.

Richard


Re: Setting precision for a PSImode type

2012-04-11 Thread Bernd Schmidt
On 04/11/2012 09:15 PM, Richard Sandiford wrote:
 Bernd Schmidt ber...@codesourcery.com writes:
 On 04/11/2012 07:31 PM, Peter Bigot wrote:
 The biggest one is that widening from 20-bit to 32-bit is an extremely
 expensive operation: it was a 16-bit ISA, but some newer MCUs support
 an extension with 20 bits in each register and a set of new
 instructions that must be used to preserve the upper 4 bits.  Getting
 bits 19..16 of a 20-bit register down into the low bits of a 16 bit
 register requires a five-position rotate-through-carry.  The 20-bit
 enhancement to the ISA was really intended only to support a larger
 address space; to simplify validation of the machine description I've
 chosen to allow it to be used for any integer operation, but I have no
 reason to think that'll be common.

 Ok. So these are pointer modes, essentially? For the target I'm working
 on, I'm using the following patch, see if that helps you any. It seems
 to apply to trunk, so I might as well ask for an OK if it bootstraps and
 tests ok (but it has little use while these ports remain out-of-tree).
 
 Not that I can approve this anyway, but: what are the properties of
 MODE_POINTER vs. MODE_PARTIAL_INT?

MODE_POINTER is intended to avoid problems where you have modes that
cannot be used as integer modes (because the arithmetic operations
doesn't exist on the machine), and which have odd conversions. It's a
way of keeping them out of the way of int_mode_for_size. I'm also
thinking of overloading the meaning so that MODE_POINTER occupies
exactly one register, even if it is bigger than BITS_PER_WORD (yes, ugh).

 It seems odd on the face of it for POINTER_MODE_P (Pmode) to be false
 on the majority of targets.  But that's probably just a naming thing.

On the majority of targets the distinction is meaningless since pointers
don't behave any differently than integers.


Bernd