summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>2014-04-17 12:49:49 +0000
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>2014-04-17 12:49:49 +0000
commite2ec52cad85e7fdd83aa32fbff941d42eeebbd8a (patch)
tree4c749de5dc4a776f1ab9f29f46405e370f12efcc
parent65b0537f9e9741318f7c8e738b6dd3b8f82f58b5 (diff)
downloadgcc-e2ec52cad85e7fdd83aa32fbff941d42eeebbd8a.tar.gz
* genmodes.c (struct mode_data): Add need_bytesize_adj field.
(blank_mode): Initialize it. (emit_mode_size_inline, emit_mode_nunits_inline, emit_mode_inner_inline): New functions. (emit_insn_modes_h): Call them and surround their output with #if GCC_VERSION >= 4001 ... #endif. * machmode.h (GET_MODE_SIZE, GET_MODE_NUNITS, GET_MODE_INNER): For GCC_VERSION >= 4001 use mode_*_inline routines instead of mode_* arrays if the argument is __builtin_constant_p. * lower-subreg.c (dump_choices): Make sure GET_MODE_SIZE argument is enum machine_mode. fortran/ * trans-types.c (gfc_init_kinds): Make sure GET_MODE_BITSIZE argument is enum machine_mode. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@209484 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog14
-rw-r--r--gcc/fortran/ChangeLog5
-rw-r--r--gcc/fortran/trans-types.c2
-rw-r--r--gcc/genmodes.c109
-rw-r--r--gcc/lower-subreg.c2
-rw-r--r--gcc/machmode.h18
6 files changed, 147 insertions, 3 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index ea9bb14a40b..ead28c2bf92 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,17 @@
+2014-04-17 Jakub Jelinek <jakub@redhat.com>
+
+ * genmodes.c (struct mode_data): Add need_bytesize_adj field.
+ (blank_mode): Initialize it.
+ (emit_mode_size_inline, emit_mode_nunits_inline,
+ emit_mode_inner_inline): New functions.
+ (emit_insn_modes_h): Call them and surround their output with
+ #if GCC_VERSION >= 4001 ... #endif.
+ * machmode.h (GET_MODE_SIZE, GET_MODE_NUNITS, GET_MODE_INNER):
+ For GCC_VERSION >= 4001 use mode_*_inline routines instead of
+ mode_* arrays if the argument is __builtin_constant_p.
+ * lower-subreg.c (dump_choices): Make sure GET_MODE_SIZE argument
+ is enum machine_mode.
+
2014-04-17 Trevor Saunders <tsaunders@mozilla.com>
* passes.c (opt_pass::execute): Adjust.
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index 29ea5f7871c..d2b666040d0 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -1,3 +1,8 @@
+2014-04-17 Jakub Jelinek <jakub@redhat.com>
+
+ * trans-types.c (gfc_init_kinds): Make sure GET_MODE_BITSIZE
+ argument is enum machine_mode.
+
2014-04-13 Paul Thomas <pault@gcc.gnu.org>
PR fortran/58085
diff --git a/gcc/fortran/trans-types.c b/gcc/fortran/trans-types.c
index 59637f2d3cb..243feb7aedb 100644
--- a/gcc/fortran/trans-types.c
+++ b/gcc/fortran/trans-types.c
@@ -373,7 +373,7 @@ gfc_init_kinds (void)
/* The middle end doesn't support constants larger than 2*HWI.
Perhaps the target hook shouldn't have accepted these either,
but just to be safe... */
- bitsize = GET_MODE_BITSIZE (mode);
+ bitsize = GET_MODE_BITSIZE ((enum machine_mode) mode);
if (bitsize > 2*HOST_BITS_PER_WIDE_INT)
continue;
diff --git a/gcc/genmodes.c b/gcc/genmodes.c
index 8cc3cdeeeb3..99078788c52 100644
--- a/gcc/genmodes.c
+++ b/gcc/genmodes.c
@@ -72,6 +72,8 @@ struct mode_data
unsigned int counter; /* Rank ordering of modes */
unsigned int ibit; /* the number of integral bits */
unsigned int fbit; /* the number of fractional bits */
+ bool need_bytesize_adj; /* true if this mode need dynamic size
+ adjustment */
};
static struct mode_data *modes[MAX_MODE_CLASS];
@@ -82,7 +84,7 @@ static const struct mode_data blank_mode = {
0, "<unknown>", MAX_MODE_CLASS,
-1U, -1U, -1U, -1U,
0, 0, 0, 0, 0,
- "<unknown>", 0, 0, 0, 0
+ "<unknown>", 0, 0, 0, 0, false
};
static htab_t modes_by_name;
@@ -904,6 +906,105 @@ emit_max_int (void)
printf ("#define MAX_BITSIZE_MODE_ANY_MODE (%d*BITS_PER_UNIT)\n", mmax);
}
+/* Emit mode_size_inline routine into insn-modes.h header. */
+static void
+emit_mode_size_inline (void)
+{
+ int c;
+ struct mode_adjust *a;
+ struct mode_data *m;
+
+ /* Size adjustments must be propagated to all containing modes. */
+ for (a = adj_bytesize; a; a = a->next)
+ {
+ a->mode->need_bytesize_adj = true;
+ for (m = a->mode->contained; m; m = m->next_cont)
+ m->need_bytesize_adj = true;
+ }
+
+ printf ("\
+#ifdef __cplusplus\n\
+inline __attribute__((__always_inline__))\n\
+#else\n\
+extern __inline__ __attribute__((__always_inline__, __gnu_inline__))\n\
+#endif\n\
+unsigned char\n\
+mode_size_inline (enum machine_mode mode)\n\
+{\n\
+ extern %sunsigned char mode_size[NUM_MACHINE_MODES];\n\
+ switch (mode)\n\
+ {\n", adj_bytesize ? "" : "const ");
+
+ for_all_modes (c, m)
+ if (!m->need_bytesize_adj)
+ printf (" case %smode: return %u;\n", m->name, m->bytesize);
+
+ puts ("\
+ default: return mode_size[mode];\n\
+ }\n\
+}\n");
+}
+
+/* Emit mode_nunits_inline routine into insn-modes.h header. */
+static void
+emit_mode_nunits_inline (void)
+{
+ int c;
+ struct mode_data *m;
+
+ puts ("\
+#ifdef __cplusplus\n\
+inline __attribute__((__always_inline__))\n\
+#else\n\
+extern __inline__ __attribute__((__always_inline__, __gnu_inline__))\n\
+#endif\n\
+unsigned char\n\
+mode_nunits_inline (enum machine_mode mode)\n\
+{\n\
+ extern const unsigned char mode_nunits[NUM_MACHINE_MODES];\n\
+ switch (mode)\n\
+ {");
+
+ for_all_modes (c, m)
+ printf (" case %smode: return %u;\n", m->name, m->ncomponents);
+
+ puts ("\
+ default: return mode_nunits[mode];\n\
+ }\n\
+}\n");
+}
+
+/* Emit mode_inner_inline routine into insn-modes.h header. */
+static void
+emit_mode_inner_inline (void)
+{
+ int c;
+ struct mode_data *m;
+
+ puts ("\
+#ifdef __cplusplus\n\
+inline __attribute__((__always_inline__))\n\
+#else\n\
+extern __inline__ __attribute__((__always_inline__, __gnu_inline__))\n\
+#endif\n\
+unsigned char\n\
+mode_inner_inline (enum machine_mode mode)\n\
+{\n\
+ extern const unsigned char mode_inner[NUM_MACHINE_MODES];\n\
+ switch (mode)\n\
+ {");
+
+ for_all_modes (c, m)
+ printf (" case %smode: return %smode;\n", m->name,
+ c != MODE_PARTIAL_INT && m->component
+ ? m->component->name : void_mode->name);
+
+ puts ("\
+ default: return mode_inner[mode];\n\
+ }\n\
+}\n");
+}
+
static void
emit_insn_modes_h (void)
{
@@ -969,6 +1070,12 @@ enum machine_mode\n{");
printf ("#define CONST_MODE_IBIT%s\n", adj_ibit ? "" : " const");
printf ("#define CONST_MODE_FBIT%s\n", adj_fbit ? "" : " const");
emit_max_int ();
+ puts ("\n#if GCC_VERSION >= 4001\n");
+ emit_mode_size_inline ();
+ emit_mode_nunits_inline ();
+ emit_mode_inner_inline ();
+ puts ("#endif /* GCC_VERSION >= 4001 */");
+
puts ("\
\n\
#endif /* insn-modes.h */");
diff --git a/gcc/lower-subreg.c b/gcc/lower-subreg.c
index bdad2a6aa9c..ae935f76459 100644
--- a/gcc/lower-subreg.c
+++ b/gcc/lower-subreg.c
@@ -1371,7 +1371,7 @@ dump_choices (bool speed_p, const char *description)
fprintf (dump_file, "Choices when optimizing for %s:\n", description);
for (i = 0; i < MAX_MACHINE_MODE; i++)
- if (GET_MODE_SIZE (i) > UNITS_PER_WORD)
+ if (GET_MODE_SIZE ((enum machine_mode) i) > UNITS_PER_WORD)
fprintf (dump_file, " %s mode %s for copy lowering.\n",
choices[speed_p].move_modes_to_split[i]
? "Splitting"
diff --git a/gcc/machmode.h b/gcc/machmode.h
index bc5d901d245..222e6263e0b 100644
--- a/gcc/machmode.h
+++ b/gcc/machmode.h
@@ -177,7 +177,13 @@ extern const unsigned char mode_class[NUM_MACHINE_MODES];
/* Get the size in bytes and bits of an object of mode MODE. */
extern CONST_MODE_SIZE unsigned char mode_size[NUM_MACHINE_MODES];
+#if GCC_VERSION >= 4001
+#define GET_MODE_SIZE(MODE) \
+ ((unsigned short) (__builtin_constant_p (MODE) \
+ ? mode_size_inline (MODE) : mode_size[MODE]))
+#else
#define GET_MODE_SIZE(MODE) ((unsigned short) mode_size[MODE])
+#endif
#define GET_MODE_BITSIZE(MODE) \
((unsigned short) (GET_MODE_SIZE (MODE) * BITS_PER_UNIT))
@@ -203,7 +209,13 @@ extern const unsigned HOST_WIDE_INT mode_mask_array[NUM_MACHINE_MODES];
/* Return the mode of the inner elements in a vector. */
extern const unsigned char mode_inner[NUM_MACHINE_MODES];
+#if GCC_VERSION >= 4001
+#define GET_MODE_INNER(MODE) \
+ ((enum machine_mode) (__builtin_constant_p (MODE) \
+ ? mode_inner_inline (MODE) : mode_inner[MODE]))
+#else
#define GET_MODE_INNER(MODE) ((enum machine_mode) mode_inner[MODE])
+#endif
/* Get the size in bytes or bites of the basic parts of an
object of mode MODE. */
@@ -224,7 +236,13 @@ extern const unsigned char mode_inner[NUM_MACHINE_MODES];
/* Get the number of units in the object. */
extern const unsigned char mode_nunits[NUM_MACHINE_MODES];
+#if GCC_VERSION >= 4001
+#define GET_MODE_NUNITS(MODE) \
+ ((unsigned char) (__builtin_constant_p (MODE) \
+ ? mode_nunits_inline (MODE) : mode_nunits[MODE]))
+#else
#define GET_MODE_NUNITS(MODE) mode_nunits[MODE]
+#endif
/* Get the next wider natural mode (eg, QI -> HI -> SI -> DI -> TI). */