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) ==