genmodes.c, [...]: New files.

* genmodes.c, mode-classes.def: New files.
	* machmode.def: Rewritten to genmodes.c interface.
	* Makefile.in (extra_modes_file): New substitution variable.
	(MACHMODE_H): No longer includes machmode.def or
	@extra_modes_file@; instead, mode-classes.def and insn-modes.h.
	(BUILD_RTL): Add $(BUILD_PREFIX)insn-modes.o.
	(OBJS-common): Add insn-modes.o.
	(STAGESTUFF): Add insn-modes.c, insn-modes.h, s-modes, and
	genmodes$(build_exeext).
	(insn-modes.o, insn-modes.c, insn-modes.h, s-modes, genmodes.o,
	genmodes$(build_exeext), $(BUILD_PREFIX_1)insn-modes.o): New targets.
	(s-genrtl): Don't depend on $(RTL_BASE_H).
	(gengenrtl.o): Don't depend on coretypes.h, $(GTM_H), real.h,
	or $(RTL_BASE_H); just rtl.def.
	* gengenrtl.c: Don't include coretypes.h, tm.h, rtl.h, or
	real.h.  Give fake definition of CONST_DOUBLE_FORMAT and
	substitute definition of NUM_RTX_CODE.  Add casts to avoid
	warnings.
	* machmode.h: Include insn-modes.h, not machmode.def.  Include
	mode-classes.def to define enum mode_class.  Tweak definitions
	of GET_MODE_CLASS, GET_MODE_SIZE, GET_MODE_BITSIZE, GET_MODE_MASK,
	GET_MODE_INNER, GET_MODE_WIDER_MODE, GET_CLASS_NARROWEST_MODE.
	(inner_mode_array): Renamed mode_inner.
	(mode_base_align): New.
	* rtl.c (mode_name, mode_class, mode_bitsize, mode_size,
	mode_unit_size, mode_wider_mode, mode_mask_array,
	inner_mode_array, class_narrowest_mode): Delete definitions.
	* stor-layout.c (get_mode_alignment): Use mode_base_align.
	* real.h: Use MIN_MODE_FLOAT and MAX_MODE_FLOAT, not QFmode
	and TFmode, in real_format_for_mode and REAL_MODE_FORMAT.

	* config/ip2k/ip2k.h, config/iq2000/iq2000.h:
	No need to define BITS_PER_UNIT.

From-SVN: r72313
This commit is contained in:
Zack Weinberg 2003-10-10 20:33:07 +00:00
parent 51e73d5737
commit 0974c7d70d
11 changed files with 1147 additions and 295 deletions

View File

@ -362,6 +362,7 @@ target_cpu_default=@target_cpu_default@
GCC_THREAD_FILE=@thread_file@
OBJC_BOEHM_GC=@objc_boehm_gc@
GTHREAD_FLAGS=@gthread_flags@
extra_modes_file=@extra_modes_file@
host_hook_obj=@out_host_hook_obj@
# Be prepared for gcc2 merges.
gcc_version=@gcc_version@
@ -632,7 +633,7 @@ TARGET_H = target.h
HOOKS_H = hooks.h
LANGHOOKS_DEF_H = langhooks-def.h $(HOOKS_H)
TARGET_DEF_H = target-def.h $(HOOKS_H)
MACHMODE_H = machmode.h machmode.def @extra_modes_file@
MACHMODE_H = machmode.h mode-classes.def insn-modes.h
RTL_BASE_H = rtl.h rtl.def $(MACHMODE_H)
RTL_H = $(RTL_BASE_H) genrtl.h input.h
PARAMS_H = params.h params.def
@ -714,7 +715,7 @@ LDEXP_LIB = @LDEXP_LIB@
BUILD_LIBS = $(BUILD_LIBIBERTY)
BUILD_RTL = $(BUILD_PREFIX)rtl.o read-rtl.o $(BUILD_PREFIX)bitmap.o \
$(BUILD_PREFIX)ggc-none.o
$(BUILD_PREFIX)ggc-none.o $(BUILD_PREFIX)insn-modes.o
BUILD_SUPPORT = gensupport.o insn-conditions.o
BUILD_EARLY_SUPPORT = gensupport.o dummy-conditions.o
@ -834,7 +835,7 @@ OBJS-common = \
dwarf2asm.o dwarf2out.o dwarfout.o emit-rtl.o except.o explow.o \
expmed.o expr.o final.o flow.o fold-const.o function.o gcse.o \
genrtl.o ggc-common.o global.o graph.o gtype-desc.o \
haifa-sched.o hooks.o ifcvt.o insn-attrtab.o insn-emit.o \
haifa-sched.o hooks.o ifcvt.o insn-attrtab.o insn-emit.o insn-modes.o \
insn-extract.o insn-opinit.o insn-output.o insn-peep.o insn-recog.o \
integrate.o intl.o jump.o langhooks.o lcm.o lists.o local-alloc.o \
loop.o optabs.o options.o opts.o params.o postreload.o predict.o \
@ -862,8 +863,8 @@ BACKEND = main.o libbackend.a
STAGESTUFF = *$(objext) insn-flags.h insn-config.h insn-codes.h \
insn-output.c insn-recog.c insn-emit.c insn-extract.c insn-peep.c \
insn-attr.h insn-attrtab.c insn-opinit.c insn-constants.h tm-preds.h \
tree-check.h insn-conditions.c \
s-flags s-config s-codes s-mlib s-genrtl s-gtype gtyp-gen.h \
tree-check.h insn-conditions.c insn-modes.c insn-modes.h \
s-flags s-config s-codes s-mlib s-genrtl s-modes s-gtype gtyp-gen.h \
s-output s-recog s-emit s-extract s-peep s-check s-conditions \
s-attr s-attrtab s-opinit s-preds s-constants s-crt0 \
genemit$(build_exeext) genoutput$(build_exeext) genrecog$(build_exeext) \
@ -871,7 +872,7 @@ STAGESTUFF = *$(objext) insn-flags.h insn-config.h insn-codes.h \
genconfig$(build_exeext) genpeep$(build_exeext) genattrtab$(build_exeext) \
genattr$(build_exeext) genopinit$(build_exeext) gengenrtl$(build_exeext) \
gencheck$(build_exeext) genpreds$(build_exeext) genconstants$(build_exeext) \
gengtype$(build_exeext) genconditions$(build_exeext) \
gengtype$(build_exeext) genconditions$(build_exeext) genmodes$(build_exeext) \
genrtl.c genrtl.h gt-*.h gtype-*.h gtype-desc.c \
xgcc$(exeext) cpp$(exeext) cc1$(exeext) $(EXTRA_PASSES) \
$(EXTRA_PARTS) $(EXTRA_PROGRAMS) gcc-cross$(exeext) \
@ -2000,13 +2001,24 @@ genrtl.o : genrtl.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
genrtl.c genrtl.h : s-genrtl
@true # force gnu make to recheck modification times.
s-genrtl: gengenrtl$(build_exeext) $(srcdir)/move-if-change $(RTL_BASE_H)
s-genrtl: gengenrtl$(build_exeext) $(srcdir)/move-if-change
$(RUN_GEN) ./gengenrtl$(build_exeext) -h > tmp-genrtl.h
$(SHELL) $(srcdir)/move-if-change tmp-genrtl.h genrtl.h
$(RUN_GEN) ./gengenrtl$(build_exeext) > tmp-genrtl.c
$(SHELL) $(srcdir)/move-if-change tmp-genrtl.c genrtl.c
$(STAMP) s-genrtl
insn-modes.o : insn-modes.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(GTM_H) \
$(MACHMODE_H)
insn-modes.c insn-modes.h : s-modes ; @true
s-modes: genmodes$(build_exeext) $(srcdir)/move-if-change
$(RUN_GEN) ./genmodes$(build_exeext) -h > tmp-modes.h
$(SHELL) $(srcdir)/move-if-change tmp-modes.h insn-modes.h
$(RUN_GEN) ./genmodes$(build_exeext) > tmp-modes.c
$(SHELL) $(srcdir)/move-if-change tmp-modes.c insn-modes.c
$(STAMP) s-modes
tm-preds.h: s-preds; @true
s-preds: genpreds$(build_exeext) $(srcdir)/move-if-change
@ -2176,8 +2188,14 @@ gengenrtl$(build_exeext) : gengenrtl.o $(BUILD_LIBDEPS)
$(CC_FOR_BUILD) $(BUILD_CFLAGS) $(BUILD_LDFLAGS) -o $@ \
gengenrtl.o $(BUILD_LIBS)
gengenrtl.o : gengenrtl.c $(RTL_BASE_H) $(BCONFIG_H) $(SYSTEM_H) coretypes.h \
$(GTM_H) real.h
gengenrtl.o : gengenrtl.c $(BCONFIG_H) $(SYSTEM_H) rtl.def
genmodes$(build_exeext) : genmodes.o $(BUILD_ERRORS) $(BUILD_LIBDEPS)
$(CC_FOR_BUILD) $(BUILD_CFLAGS) $(BUILD_LDFLAGS) -o $@ \
genmodes.o $(BUILD_ERRORS) $(BUILD_LIBS)
genmodes.o : genmodes.c $(BCONFIG_H) $(SYSTEM_H) errors.h machmode.def \
$(extra_modes_file)
genpreds$(build_exeext) : genpreds.o $(BUILD_LIBDEPS)
$(CC_FOR_BUILD) $(BUILD_CFLAGS) $(BUILD_LDFLAGS) -o $@ \
@ -2270,6 +2288,12 @@ $(BUILD_PREFIX_1)ggc-none.o: ggc-none.c $(BCONFIG_H) coretypes.h $(GTM_H) $(SYST
sed -e 's/config[.]h/bconfig.h/' $(srcdir)/ggc-none.c > $(BUILD_PREFIX)ggc-none.c
$(CC_FOR_BUILD) -c $(BUILD_CFLAGS) $(BUILD_CPPFLAGS) $(INCLUDES) $(BUILD_PREFIX)ggc-none.c $(OUTPUT_OPTION)
$(BUILD_PREFIX_1)insn-modes.o: insn-modes.c $(BCONFIG_H) $(SYSTEM_H) \
coretypes.h $(GTM_H) $(MACHMODE_H)
rm -f $(BUILD_PREFIX)insn-modes.c
sed -e 's/config[.]h/bconfig.h/' $(srcdir)/insn-modes.c > $(BUILD_PREFIX)insn-modes.c
$(CC_FOR_BUILD) -c $(BUILD_CFLAGS) $(BUILD_CPPFLAGS) $(INCLUDES) $(BUILD_PREFIX)insn-modes.c $(OUTPUT_OPTION)
#
# Remake internationalization support.
intl.o: intl.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) intl.h Makefile

View File

@ -63,7 +63,6 @@ extern int target_flags;
#define BITS_BIG_ENDIAN 0
#define BYTES_BIG_ENDIAN 1
#define WORDS_BIG_ENDIAN 1
#define BITS_PER_UNIT 8
#define BITS_PER_WORD 8
#define UNITS_PER_WORD (BITS_PER_WORD / BITS_PER_UNIT)

View File

@ -142,8 +142,6 @@ extern int target_flags;
#define LIBGCC2_WORDS_BIG_ENDIAN 1
#define BITS_PER_UNIT 8
#define BITS_PER_WORD 32
#define MAX_BITS_PER_WORD 64

View File

@ -22,26 +22,24 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "bconfig.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#define NO_GENRTL_H
#include "rtl.h"
#undef abort
#include "real.h"
struct rtx_definition
{
const char *const enumname, *const name, *const format;
};
/* rtl.def needs CONST_DOUBLE_FORMAT, but we don't care what
CONST_DOUBLE_FORMAT is because we're not going to be generating
anything for CONST_DOUBLE anyway. */
#define CONST_DOUBLE_FORMAT ""
#define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) { #ENUM, NAME, FORMAT },
static const struct rtx_definition defs[] =
{
#include "rtl.def" /* rtl expressions are documented here */
};
#define NUM_RTX_CODE ARRAY_SIZE(defs)
static const char *formats[NUM_RTX_CODE];
@ -169,7 +167,7 @@ find_formats (void)
{
int i;
for (i = 0; i < NUM_RTX_CODE; i++)
for (i = 0; i < (int)NUM_RTX_CODE; i++)
{
const char **f;
@ -309,7 +307,7 @@ genheader (void)
putchar ('\n');
for (i = 0; i < NUM_RTX_CODE; i++)
for (i = 0; i < (int) NUM_RTX_CODE; i++)
if (! special_format (defs[i].format))
genmacro (i);

908
gcc/genmodes.c Normal file
View File

@ -0,0 +1,908 @@
/* Generate the machine mode enumeration and associated tables.
Copyright (C) 2003
Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 2, or (at your option) any later
version.
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING. If not, write to the Free
Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA. */
#include "bconfig.h"
#include "system.h"
#include "errors.h"
/* enum mode_class is normally defined by machmode.h but we can't
include that header here. */
#include "mode-classes.def"
#define DEF_MODE_CLASS(M) M
enum mode_class { MODE_CLASSES, MAX_MODE_CLASS };
#undef DEF_MODE_CLASS
/* Text names of mode classes, for output. */
#define DEF_MODE_CLASS(M) #M
static const char *const mode_class_names[MAX_MODE_CLASS] =
{
MODE_CLASSES
};
#undef DEF_MODE_CLASS
#undef MODE_CLASSES
#ifdef EXTRA_MODES_FILE
# define HAVE_EXTRA_MODES 1
#else
# define HAVE_EXTRA_MODES 0
# define EXTRA_MODES_FILE ""
#endif
/* Data structure for building up what we know about a mode.
They're clustered by mode class. */
struct mode_data
{
struct mode_data *next; /* next this class - arbitrary order */
const char *name; /* printable mode name -- SI, not SImode */
enum mode_class class; /* this mode class */
unsigned int bitsize; /* size in bits, equiv to TYPE_PRECISION */
unsigned int bytesize; /* storage size in addressable units */
unsigned int ncomponents; /* number of subunits */
unsigned int alignment; /* mode alignment */
struct mode_data *component; /* mode of components */
struct mode_data *wider; /* next wider mode */
const char *file; /* file and line of definition, */
unsigned int line; /* for error reporting */
};
static struct mode_data *known_modes[MAX_MODE_CLASS];
static unsigned int n_modes[MAX_MODE_CLASS];
static struct mode_data *void_mode;
static const struct mode_data blank_mode = {
0, "<unknown>", MAX_MODE_CLASS,
-1, -1, -1, -1,
0, 0,
"<unknown>", 0
};
/* Mode class operations. */
static enum mode_class
complex_class (enum mode_class class)
{
switch (class)
{
case MODE_INT: return MODE_COMPLEX_INT;
case MODE_FLOAT: return MODE_COMPLEX_FLOAT;
default:
error ("no complex class for class %s", mode_class_names[class]);
return MODE_RANDOM;
}
}
static enum mode_class
vector_class (enum mode_class class)
{
switch (class)
{
case MODE_INT: return MODE_VECTOR_INT;
case MODE_FLOAT: return MODE_VECTOR_FLOAT;
default:
error ("no vector class for class %s", mode_class_names[class]);
return MODE_RANDOM;
}
}
static struct mode_data *
find_mode (enum mode_class class, const char *name)
{
struct mode_data *m;
for (m = known_modes[class]; m; m = m->next)
if (!strcmp (name, m->name))
return m;
return 0;
}
static struct mode_data *
new_mode (enum mode_class class, const char *name,
const char *file, unsigned int line)
{
struct mode_data *m;
m = find_mode (class, name);
if (m)
{
error ("%s:%d: duplicate definition of mode \"%s\"",
trim_filename (file), line, name);
error ("%s:%d: previous definition here", m->file, m->line);
return m;
}
m = xmalloc (sizeof (struct mode_data));
memcpy (m, &blank_mode, sizeof (struct mode_data));
m->class = class;
m->name = name;
if (file)
m->file = trim_filename (file);
m->line = line;
m->next = known_modes[class];
known_modes[class] = m;
n_modes[class]++;
return m;
}
#define for_all_modes(C, M) \
for (C = 0; C < MAX_MODE_CLASS; C++) \
for (M = known_modes[C]; M; M = M->next)
/* Diagnose failure to meet expectations in a partially filled out
mode structure. */
enum requirement { SET, UNSET, OPTIONAL };
#define validate_field_(mname, fname, req, val, unset, file, line) do { \
switch (req) \
{ \
case SET: \
if (val == unset) \
error ("%s:%d: (%s) field %s must be set", \
file, line, mname, fname); \
break; \
case UNSET: \
if (val != unset) \
error ("%s:%d: (%s) field %s must not be set", \
file, line, mname, fname); \
case OPTIONAL: \
break; \
} \
} while (0)
#define validate_field(M, F) \
validate_field_(M->name, #F, r_##F, M->F, blank_mode.F, M->file, M->line)
static void
validate_mode (struct mode_data *m,
enum requirement r_bitsize,
enum requirement r_bytesize,
enum requirement r_component,
enum requirement r_ncomponents)
{
validate_field (m, bitsize);
validate_field (m, bytesize);
validate_field (m, component);
validate_field (m, ncomponents);
}
#undef validate_field
#undef validate_field_
/* Given a partially-filled-out mode structure, figure out what we can
and fill the rest of it in; die if it isn't enough. */
static void
complete_mode (struct mode_data *m)
{
unsigned int alignment;
if (!m->name)
{
error ("%s:%d: mode with no name", m->file, m->line);
return;
}
if (m->class == MAX_MODE_CLASS)
{
error ("%s:%d: %smode has no mode class", m->file, m->line, m->name);
return;
}
switch (m->class)
{
case MODE_RANDOM:
/* Nothing more need be said. */
if (!strcmp (m->name, "VOID"))
void_mode = m;
validate_mode (m, UNSET, UNSET, UNSET, UNSET);
m->bitsize = 0;
m->bytesize = 0;
m->ncomponents = 0;
m->component = 0;
break;
case MODE_CC:
/* Again, nothing more need be said. For historical reasons,
the size of a CC mode is four units. */
validate_mode (m, UNSET, UNSET, UNSET, UNSET);
m->bytesize = 4;
m->ncomponents = 0;
m->component = 0;
break;
case MODE_INT:
case MODE_FLOAT:
/* A scalar mode must have a byte size, may have a bit size,
and must not have components. */
validate_mode (m, OPTIONAL, SET, UNSET, UNSET);
m->ncomponents = 0;
m->component = 0;
break;
case MODE_PARTIAL_INT:
/* A partial integer mode uses ->component to say what the
corresponding full-size integer mode is, and may also
specify a bit size. */
validate_mode (m, OPTIONAL, UNSET, SET, UNSET);
m->bytesize = m->component->bytesize;
m->ncomponents = 0;
m->component = 0; /* ??? preserve this */
break;
case MODE_COMPLEX_INT:
case MODE_COMPLEX_FLOAT:
/* Complex modes should have a component indicated, but no more. */
validate_mode (m, UNSET, UNSET, SET, UNSET);
m->ncomponents = 2;
if (m->component->bitsize != (unsigned int)-1)
m->bitsize = 2 * m->component->bitsize;
m->bytesize = 2 * m->component->bytesize;
break;
case MODE_VECTOR_INT:
case MODE_VECTOR_FLOAT:
/* Vector modes should have a component and a number of components. */
validate_mode (m, UNSET, UNSET, SET, SET);
if (m->component->bitsize != (unsigned int)-1)
m->bitsize = m->ncomponents * m->component->bitsize;
m->bytesize = m->ncomponents * m->component->bytesize;
break;
default:
abort ();
}
/* If not already specified, the mode alignment defaults to the largest
power of two that divides the size of the object. Complex types are
not more aligned than their contents. */
if (m->class == MODE_COMPLEX_INT || m->class == MODE_COMPLEX_FLOAT)
alignment = m->component->bytesize;
else
alignment = m->bytesize;
m->alignment = alignment & (~alignment + 1);
}
static void
complete_all_modes (void)
{
struct mode_data *m;
enum mode_class c;
for_all_modes (c, m)
complete_mode (m);
}
/* For each mode in class CLASS, construct a corresponding complex mode. */
#define COMPLEX_MODES(C) make_complex_modes(MODE_##C, __FILE__, __LINE__)
static void
make_complex_modes (enum mode_class class,
const char *file, unsigned int line)
{
struct mode_data *m;
struct mode_data *c;
char buf[8];
enum mode_class cclass = complex_class (class);
if (cclass == MODE_RANDOM)
return;
for (m = known_modes[class]; m; m = m->next)
{
/* Skip BImode. FIXME: BImode probably shouldn't be MODE_INT. */
if (m->bitsize == 1)
continue;
if (strlen (m->name) >= sizeof buf)
{
error ("%s:%d:mode name \"%s\" is too long",
m->file, m->line, m->name);
continue;
}
/* Float complex modes are named SCmode, etc.
Int complex modes are named CSImode, etc.
This inconsistency should be eliminated. */
if (class == MODE_FLOAT)
{
char *p;
strncpy (buf, m->name, sizeof buf);
p = strchr (buf, 'F');
if (p == 0)
{
error ("%s:%d: float mode \"%s\" has no 'F'",
m->file, m->line, m->name);
continue;
}
*p = 'C';
}
else
snprintf (buf, sizeof buf, "C%s", m->name);
c = new_mode (cclass, xstrdup (buf), file, line);
c->component = m;
}
}
/* For all modes in class CLASS, construct vector modes of width
WIDTH, having as many components as necessary. */
#define VECTOR_MODES(C, W) make_vector_modes(MODE_##C, W, __FILE__, __LINE__)
static void
make_vector_modes (enum mode_class class, unsigned int width,
const char *file, unsigned int line)
{
struct mode_data *m;
struct mode_data *v;
char buf[8];
unsigned int ncomponents;
enum mode_class vclass = vector_class (class);
if (vclass == MODE_RANDOM)
return;
for (m = known_modes[class]; m; m = m->next)
{
/* Do not construct vector modes with only one element, or
vector modes where the element size doesn't divide the full
size evenly. */
ncomponents = width / m->bytesize;
if (ncomponents < 2)
continue;
if (width % m->bytesize)
continue;
/* Skip QFmode and BImode. FIXME: this special case should
not be necessary. */
if (class == MODE_FLOAT && m->bytesize == 1)
continue;
if (class == MODE_INT && m->bitsize == 1)
continue;
if ((size_t)snprintf (buf, sizeof buf, "V%u%s", ncomponents, m->name)
>= sizeof buf)
{
error ("%s:%d: mode name \"%s\" is too long",
m->file, m->line, m->name);
continue;
}
v = new_mode (vclass, xstrdup (buf), file, line);
v->component = m;
v->ncomponents = ncomponents;
}
}
/* Input. */
#define _SPECIAL_MODE(C, N) make_special_mode(MODE_##C, #N, __FILE__, __LINE__)
#define RANDOM_MODE(N) _SPECIAL_MODE (RANDOM, N)
#define CC_MODE(N) _SPECIAL_MODE (CC, N)
static void
make_special_mode (enum mode_class class, const char *name,
const char *file, unsigned int line)
{
new_mode (class, name, file, line);
}
#define _SCALAR_MODE(C, N, B, Y) \
make_scalar_mode (MODE_##C, #N, B, Y, __FILE__, __LINE__)
#define INT_MODE(N, Y) _SCALAR_MODE (INT, N, -1, Y)
#define FRACTIONAL_INT_MODE(N, B, Y) _SCALAR_MODE (INT, N, B, Y)
#define FLOAT_MODE(N, Y) _SCALAR_MODE (FLOAT, N, -1, Y)
#define FRACTIONAL_FLOAT_MODE(N, B, Y) _SCALAR_MODE (FLOAT, N, B, Y)
static void
make_scalar_mode (enum mode_class class, const char *name,
unsigned int bitsize, unsigned int bytesize,
const char *file, unsigned int line)
{
struct mode_data *m = new_mode (class, name, file, line);
m->bytesize = bytesize;
m->bitsize = bitsize;
}
/* Partial integer modes are specified by relation to a full integer mode.
For now, we do not attempt to narrow down their bit sizes. */
#define PARTIAL_INT_MODE(M) \
make_partial_integer_mode (#M, "P" #M, -1, __FILE__, __LINE__)
static void ATTRIBUTE_UNUSED
make_partial_integer_mode (const char *base, const char *name,
unsigned int bitsize,
const char *file, unsigned int line)
{
struct mode_data *m;
struct mode_data *component = find_mode (MODE_INT, base);
if (!component)
{
error ("%s:%d: no mode \"%s\" in class INT", file, line, name);
return;
}
m = new_mode (MODE_PARTIAL_INT, name, file, line);
m->bitsize = bitsize;
m->component = component;
}
/* A single vector mode can be specified by naming its component
mode and the number of components. */
#define VECTOR_MODE(C, M, N) \
make_vector_mode (MODE_##C, #M, N, __FILE__, __LINE__);
static void ATTRIBUTE_UNUSED
make_vector_mode (enum mode_class bclass,
const char *base,
unsigned int ncomponents,
const char *file, unsigned int line)
{
struct mode_data *v;
enum mode_class vclass = vector_class (bclass);
struct mode_data *component = find_mode (bclass, base);
char namebuf[8];
if (vclass == MODE_RANDOM)
return;
if (component == 0)
{
error ("%s:%d: no mode \"%s\" in class %s",
file, line, base, mode_class_names[bclass] + 5);
return;
}
if ((size_t)snprintf (namebuf, sizeof namebuf, "V%u%s",
ncomponents, base) >= sizeof namebuf)
{
error ("%s:%d: mode name \"%s\" is too long",
base, file, line);
return;
}
v = new_mode (vclass, xstrdup (namebuf), file, line);
v->ncomponents = ncomponents;
v->component = component;
}
static void
create_modes (void)
{
#include "machmode.def"
}
/* Processing. */
/* Sort a list of modes into the order needed for the WIDER field:
major sort by bitsize, minor sort by component bitsize.
For instance:
QI < HI < SI < DI < TI
V4QI < V2HI < V8QI < V4HI < V2SI.
If the bitsize is not set, sort by the bytesize. A mode with
bitsize set gets sorted before a mode without bitsize set, if
they have the same bytesize; this is the right thing because
the bitsize must always be smaller than the bytesize * BITS_PER_UNIT.
We don't have to do anything special to get this done -- an unset
bitsize shows up as (unsigned int)-1, i.e. UINT_MAX. */
static int
cmp_modes (const void *a, const void *b)
{
struct mode_data *m = *(struct mode_data **)a;
struct mode_data *n = *(struct mode_data **)b;
if (m->bytesize > n->bytesize)
return 1;
else if (m->bytesize < n->bytesize)
return -1;
if (m->bitsize > n->bitsize)
return 1;
else if (m->bitsize < n->bitsize)
return -1;
if (!m->component && !n->component)
return 0;
if (m->component->bytesize > n->component->bytesize)
return 1;
else if (m->component->bytesize < n->component->bytesize)
return -1;
if (m->component->bitsize > n->component->bitsize)
return 1;
else if (m->component->bitsize < n->component->bitsize)
return -1;
return 0;
}
static void
calc_wider_mode (void)
{
enum mode_class c;
struct mode_data *m;
struct mode_data **sortbuf;
unsigned int max_n_modes = 0;
unsigned int i, j;
for (c = 0; c < MAX_MODE_CLASS; c++)
max_n_modes = MAX (max_n_modes, n_modes[c]);
sortbuf = alloca (max_n_modes * sizeof (struct mode_data *));
for (c = 0; c < MAX_MODE_CLASS; c++)
{
/* "wider" is not meaningful for MODE_RANDOM and MODE_CC.
However, we want these in textual order, and we have
precisely the reverse. */
if (c == MODE_RANDOM || c == MODE_CC)
{
struct mode_data *prev, *next;
for (prev = 0, m = known_modes[c]; m; m = next)
{
m->wider = void_mode;
/* this is nreverse */
next = m->next;
m->next = prev;
prev = m;
}
known_modes[c] = prev;
}
else
{
if (!known_modes[c])
continue;
for (i = 0, m = known_modes[c]; m; i++, m = m->next)
sortbuf[i] = m;
qsort (sortbuf, i, sizeof (struct mode_data *), cmp_modes);
sortbuf[i] = 0;
for (j = 0; j < i; j++)
sortbuf[j]->next = sortbuf[j]->wider = sortbuf[j + 1];
known_modes[c] = sortbuf[0];
}
}
}
/* Output routines. */
#define tagged_printf(FMT, ARG, TAG) do { \
int count_; \
printf (" " FMT ",%n", ARG, &count_); \
printf ("%*s/* %s */\n", 27 - count_, "", TAG); \
} while (0)
#define print_decl(TYPE, NAME, ASIZE) \
printf ("\nconst %s %s[%s] =\n{\n", TYPE, NAME, ASIZE);
#define print_closer() puts ("};")
static void
emit_insn_modes_h (void)
{
enum mode_class c;
struct mode_data *m, *first, *last;
printf ("/* Generated automatically from machmode.def%s%s\n",
HAVE_EXTRA_MODES ? " and " : "",
EXTRA_MODES_FILE);
puts ("\
by genmodes. */\n\
\n\
#ifndef GCC_INSN_MODES_H\n\
#define GCC_INSN_MODES_H\n\
\n\
enum machine_mode\n{");
for (c = 0; c < MAX_MODE_CLASS; c++)
for (m = known_modes[c]; m; m = m->next)
{
int count_;
printf (" %smode,%n", m->name, &count_);
printf ("%*s/* %s:%d */\n", 27 - count_, "",
trim_filename (m->file), m->line);
}
puts (" MAX_MACHINE_MODE,\n");
for (c = 0; c < MAX_MODE_CLASS; c++)
{
first = known_modes[c];
last = 0;
for (m = first; m; last = m, m = m->next)
;
/* Don't use BImode for MIN_MODE_INT, since otherwise the middle
end will try to use it for bitfields in structures and the
like, which we do not want. Only the target md file should
generate BImode widgets. */
if (first && first->bitsize == 1)
first = first->next;
if (first && last)
printf (" MIN_%s = %smode,\n MAX_%s = %smode,\n\n",
mode_class_names[c], first->name,
mode_class_names[c], last->name);
else
printf (" MIN_%s = %smode,\n MAX_%s = %smode,\n\n",
mode_class_names[c], void_mode->name,
mode_class_names[c], void_mode->name);
}
puts ("\
NUM_MACHINE_MODES = MAX_MACHINE_MODE\n\
};\n\
\n\
#endif /* insn-modes.h */");
}
static void
emit_insn_modes_c_header (void)
{
printf ("/* Generated automatically from machmode.def%s%s\n",
HAVE_EXTRA_MODES ? " and " : "",
EXTRA_MODES_FILE);
puts ("\
by genmodes. */\n\
\n\
#define GENERATOR_FILE /* This inhibits insn-flags.h and\n\
insn-constants.h, which don't exist yet. */\n\
#include \"config.h\"\n\
#include \"system.h\"\n\
#include \"coretypes.h\"\n\
#include \"tm.h\"\n\
#include \"machmode.h\"");
}
static void
emit_mode_name (void)
{
enum mode_class c;
struct mode_data *m;
print_decl ("char *const", "mode_name", "NUM_MACHINE_MODES");
for_all_modes (c, m)
printf (" \"%s\",\n", m->name);
print_closer ();
}
static void
emit_mode_class (void)
{
enum mode_class c;
struct mode_data *m;
print_decl ("unsigned char", "mode_class", "NUM_MACHINE_MODES");
for_all_modes (c, m)
tagged_printf ("%s", mode_class_names[m->class], m->name);
print_closer ();
}
static void
emit_mode_bitsize (void)
{
enum mode_class c;
struct mode_data *m;
print_decl ("unsigned short", "mode_bitsize", "NUM_MACHINE_MODES");
for_all_modes (c, m)
if (m->bitsize != (unsigned int)-1)
tagged_printf ("%u", m->bitsize, m->name);
else
tagged_printf ("%u*BITS_PER_UNIT", m->bytesize, m->name);
print_closer ();
}
static void
emit_mode_size (void)
{
enum mode_class c;
struct mode_data *m;
print_decl ("unsigned char", "mode_size", "NUM_MACHINE_MODES");
for_all_modes (c, m)
tagged_printf ("%u", m->bytesize, m->name);
print_closer ();
}
static void
emit_mode_unit_size (void)
{
enum mode_class c;
struct mode_data *m;
print_decl ("unsigned char", "mode_unit_size", "NUM_MACHINE_MODES");
for_all_modes (c, m)
tagged_printf ("%u",
m->component
? m->component->bytesize : m->bytesize,
m->name);
print_closer ();
}
static void
emit_mode_wider (void)
{
enum mode_class c;
struct mode_data *m;
print_decl ("unsigned char", "mode_wider", "NUM_MACHINE_MODES");
for_all_modes (c, m)
tagged_printf ("%smode",
m->wider ? m->wider->name : void_mode->name,
m->name);
print_closer ();
}
static void
emit_mode_mask (void)
{
enum mode_class c;
struct mode_data *m;
print_decl ("unsigned HOST_WIDE_INT", "mode_mask_array",
"NUM_MACHINE_MODES");
puts ("\
#define MASK(m) \\\n\
((m) >= HOST_BITS_PER_WIDE_INT) \\\n\
? ~(unsigned HOST_WIDE_INT) 0 \\\n\
: ((unsigned HOST_WIDE_INT) 1 << (m)) - 1\n");
for_all_modes (c, m)
if (m->bitsize != (unsigned int)-1)
tagged_printf ("MASK (%u)", m->bitsize, m->name);
else
tagged_printf ("MASK (%u*BITS_PER_UNIT)", m->bytesize, m->name);
puts ("#undef MASK");
print_closer ();
}
static void
emit_mode_inner (void)
{
enum mode_class c;
struct mode_data *m;
print_decl ("unsigned char", "mode_inner", "NUM_MACHINE_MODES");
for_all_modes (c, m)
tagged_printf ("%smode",
m->component ? m->component->name : void_mode->name,
m->name);
print_closer ();
}
static void
emit_mode_base_align (void)
{
enum mode_class c;
struct mode_data *m;
print_decl ("unsigned char", "mode_base_align", "NUM_MACHINE_MODES");
for_all_modes (c, m)
tagged_printf ("%u", m->alignment, m->name);
print_closer ();
}
static void
emit_class_narrowest_mode (void)
{
enum mode_class c;
print_decl ("unsigned char", "class_narrowest_mode", "MAX_MODE_CLASS");
for (c = 0; c < MAX_MODE_CLASS; c++)
/* Bleah, all this to get the comment right for MIN_MODE_INT. */
tagged_printf ("MIN_%s", mode_class_names[c],
known_modes[c]
? (known_modes[c]->bitsize != 1
? known_modes[c]->name
: (known_modes[c]->next
? known_modes[c]->next->name
: void_mode->name))
: void_mode->name);
print_closer ();
}
static void
emit_insn_modes_c (void)
{
emit_insn_modes_c_header ();
emit_mode_name ();
emit_mode_class ();
emit_mode_bitsize ();
emit_mode_size ();
emit_mode_unit_size ();
emit_mode_wider ();
emit_mode_mask ();
emit_mode_inner ();
emit_mode_base_align ();
emit_class_narrowest_mode ();
}
/* Master control. */
int
main(int argc, char **argv)
{
bool gen_header;
progname = argv[0];
if (argc == 1)
gen_header = false;
else if (argc == 2 && !strcmp (argv[1], "-h"))
gen_header = true;
else
{
error ("usage: %s [-h] > file", progname);
return FATAL_EXIT_CODE;
}
create_modes ();
complete_all_modes ();
if (have_error)
return FATAL_EXIT_CODE;
calc_wider_mode ();
if (gen_header)
emit_insn_modes_h ();
else
emit_insn_modes_c ();
if (fflush (stdout) || fclose (stdout))
return FATAL_EXIT_CODE;
return SUCCESS_EXIT_CODE;
}

View File

@ -1,6 +1,7 @@
/* This file contains the definitions and documentation for the
machine modes used in the GNU compiler.
Copyright (C) 1987, 1992, 1994, 1997, 1998, 2000 Free Software Foundation, Inc.
Copyright (C) 1987, 1992, 1994, 1997, 1998, 2000, 2003
Free Software Foundation, Inc.
This file is part of GCC.
@ -31,145 +32,165 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
has a machine mode which describes data of that type or the
data of the variable declared. */
/* The first argument is the internal name of the machine mode
used in the C source.
By convention these are in UPPER_CASE, except for the word "mode".
/* This file is included by the genmodes program. Its text is the
body of a function. Do not rely on this, it will change in the
future.
The second argument is the name of the machine mode in the
external ASCII format used for reading and printing RTL and trees.
By convention these names in UPPER_CASE.
The following statements can be used in this file -- all have
the form of a C macro call. In their arguments:
Third argument states the kind of representation:
MODE_INT - integer
MODE_FLOAT - floating
MODE_PARTIAL_INT - PQImode, PHImode, PSImode and PDImode
MODE_CC - modes used for representing the condition code in a register
MODE_COMPLEX_INT, MODE_COMPLEX_FLOAT - complex number
MODE_VECTOR_INT, MODE_VECTOR_FLOAT - vector
MODE_RANDOM - anything else
A CLASS argument must be one of the constants defined in
mode-classes.def, less the leading MODE_ prefix; some statements
that take CLASS arguments have restructions on which classes are
acceptable. For instance, INT.
Fourth argument is the relative size of the object, in bits,
so we can have modes smaller than 1 byte.
A MODE argument must be the printable name of a machine mode,
without quotation marks or trailing "mode". For instance, SI.
Fifth argument is the relative size of the object, in bytes.
It is zero when the size is meaningless or not determined.
A byte's size is determined by BITS_PER_UNIT in tm.h.
A BITSIZE, BYTESIZE, or COUNT argument must be a positive integer
constant.
Sixth arg is the relative size of subunits of the object.
It is same as the fifth argument except for complexes and vectors,
since they are really made of many equal size subunits.
Order matters in this file in so far as statements which refer to
other modes must appear after the modes they refer to. However,
statements which do not refer to other modes may appear in any
order.
Seventh arg is next wider natural mode of the same class. 0 if
there is none. Vector modes use this field to point to the next
vector size, so we can iterate through the different vectors modes.
The ordering is by increasing byte size, with QI coming before HI,
HI before SI, etc.
RANDOM_MODE (MODE);
declares MODE to be of class RANDOM.
Eigth arg is the mode of the internal elements in a vector or
complex, and VOIDmode if not applicable.
*/
CC_MODE (MODE);
declares MODE to be of class CC.
INT_MODE (MODE, BYTESIZE);
declares MODE to be of class INT and BYTESIZE bytes wide.
All of the bits of its representation are significant.
FRACTIONAL_INT_MODE (MODE, BITSIZE, BYTESIZE);
declares MODE to be of class INT, BYTESIZE bytes wide in
storage, but with only BITSIZE significant bits.
FLOAT_MODE (MODE, BYTESIZE);
declares MODE to be of class FLOAT and BYTESIZE bytes wide.
All of the bits of its representation are significant.
FRACTIONAL_FLOAT_MODE (MODE, BITSIZE, BYTESIZE);
declares MODE to be of class FLOAT, BYTESIZE bytes wide in
storage, but with only BITSIZE significant bits.
PARTIAL_INT_MODE (MODE);
declares a mode of class PARTIAL_INT with the same size as
MODE (which must be an INT mode). The name of the new mode
is made by prefixing a P to the name MODE. This statement
may grow a BITSIZE argument in the future.
VECTOR_MODE (CLASS, MODE, COUNT);
Declare a vector mode whose component mode is MODE (of class
CLASS) with COUNT components. CLASS must be INT or FLOAT.
The name of the vector mode takes the form VnX where n is
COUNT in decimal and X is MODE.
VECTOR_MODES (CLASS, WIDTH);
For all modes presently declared in class CLASS, construct
corresponding vector modes having width WIDTH. Modes whose
byte sizes do not evenly divide WIDTH are ignored, as are
modes that would produce vector modes with only one component,
and modes smaller than one byte (if CLASS is INT) or smaller
than two bytes (if CLASS is FLOAT). CLASS must be INT or
FLOAT. The names follow the same rule as VECTOR_MODE uses.
COMPLEX_MODES (CLASS);
For all modes presently declared in class CLASS, construct
corresponding complex modes. Modes smaller than one byte
are ignored. For FLOAT modes, the names are derived by
replacing the 'F' in the mode name with a 'C'. (It is an
error if there is no 'F'. For INT modes, the names are
derived by prefixing a C to the name.
BITS_PER_UNIT (COUNT);
Sets the number of bits in a machine byte (least addressable
unit). If this statement does not appear, the default is 8.
Note: If a mode is ever made which is more than 255 bytes wide,
machmode.h and genmodes.c will have to be changed to allocate
more space for the mode_size and mode_alignment arrays. */
/* VOIDmode is used when no mode needs to be specified,
as for example on CONST_INT RTL expressions. */
DEF_MACHMODE (VOIDmode, "VOID", MODE_RANDOM, 0, 0, 0, VOIDmode, VOIDmode)
RANDOM_MODE (VOID);
DEF_MACHMODE (BImode, "BI", MODE_INT, 1, 1, 1, QImode, VOIDmode)
DEF_MACHMODE (QImode, "QI", MODE_INT, BITS_PER_UNIT, 1, 1, HImode, VOIDmode)
DEF_MACHMODE (HImode, "HI", MODE_INT, BITS_PER_UNIT*2, 2, 2, SImode, VOIDmode)
DEF_MACHMODE (SImode, "SI", MODE_INT, BITS_PER_UNIT*4, 4, 4, DImode, VOIDmode)
DEF_MACHMODE (DImode, "DI", MODE_INT, BITS_PER_UNIT*8, 8, 8, TImode, VOIDmode)
DEF_MACHMODE (TImode, "TI", MODE_INT, BITS_PER_UNIT*16, 16, 16, OImode, VOIDmode)
DEF_MACHMODE (OImode, "OI", MODE_INT, BITS_PER_UNIT*32, 32, 32, VOIDmode, VOIDmode)
/* BLKmode is used for structures, arrays, etc.
that fit no more specific mode. */
RANDOM_MODE (BLK);
/* Single bit mode used for booleans. */
FRACTIONAL_INT_MODE (BI, 1, 1);
/* Basic integer modes. */
INT_MODE (QI, 1);
INT_MODE (HI, 2);
INT_MODE (SI, 4);
INT_MODE (DI, 8);
INT_MODE (TI, 16);
INT_MODE (OI, 32);
/* Pointers on some machines use these types to distinguish them from
ints. Useful if a pointer is 4 bytes but has some bits that are
not significant, so it is really not quite as wide as an integer. */
DEF_MACHMODE (PQImode, "PQI", MODE_PARTIAL_INT, BITS_PER_UNIT, 1, 1, PHImode, VOIDmode)
DEF_MACHMODE (PHImode, "PHI", MODE_PARTIAL_INT, BITS_PER_UNIT*2, 2, 2, PSImode, VOIDmode)
DEF_MACHMODE (PSImode, "PSI", MODE_PARTIAL_INT, BITS_PER_UNIT*4, 4, 4, PDImode, VOIDmode)
DEF_MACHMODE (PDImode, "PDI", MODE_PARTIAL_INT, BITS_PER_UNIT*8, 8, 8, VOIDmode, VOIDmode)
PARTIAL_INT_MODE (QI);
PARTIAL_INT_MODE (HI);
PARTIAL_INT_MODE (SI);
PARTIAL_INT_MODE (DI);
DEF_MACHMODE (QFmode, "QF", MODE_FLOAT, BITS_PER_UNIT, 1, 1, HFmode, VOIDmode)
DEF_MACHMODE (HFmode, "HF", MODE_FLOAT, BITS_PER_UNIT*2, 2, 2, TQFmode, VOIDmode)
DEF_MACHMODE (TQFmode, "TQF", MODE_FLOAT, BITS_PER_UNIT*3, 3, 3, SFmode, VOIDmode) /* MIL-STD-1750A */
DEF_MACHMODE (SFmode, "SF", MODE_FLOAT, BITS_PER_UNIT*4, 4, 4, DFmode, VOIDmode)
DEF_MACHMODE (DFmode, "DF", MODE_FLOAT, BITS_PER_UNIT*8, 8, 8, XFmode, VOIDmode)
DEF_MACHMODE (XFmode, "XF", MODE_FLOAT, BITS_PER_UNIT*12, 12, 12, TFmode, VOIDmode) /* IEEE extended */
DEF_MACHMODE (TFmode, "TF", MODE_FLOAT, BITS_PER_UNIT*16, 16, 16, VOIDmode, VOIDmode)
/* Basic floating point modes. */
FLOAT_MODE (QF, 1); /* C4x single precision */
FLOAT_MODE (HF, 2); /* C4x double precision */
FLOAT_MODE (TQF, 3); /* MIL-STD-1750a */
FLOAT_MODE (SF, 4);
FLOAT_MODE (DF, 8);
FLOAT_MODE (XF, 12); /* IEEE extended (80-bit) */
FLOAT_MODE (TF, 16);
/* Complex modes. */
DEF_MACHMODE (QCmode, "QC", MODE_COMPLEX_FLOAT, BITS_PER_UNIT*2, 2, 1, HCmode, QFmode)
DEF_MACHMODE (HCmode, "HC", MODE_COMPLEX_FLOAT, BITS_PER_UNIT*4, 4, 2, SCmode, HFmode)
DEF_MACHMODE (SCmode, "SC", MODE_COMPLEX_FLOAT, BITS_PER_UNIT*8, 8, 4, DCmode, SFmode)
DEF_MACHMODE (DCmode, "DC", MODE_COMPLEX_FLOAT, BITS_PER_UNIT*16, 16, 8, XCmode, DFmode)
DEF_MACHMODE (XCmode, "XC", MODE_COMPLEX_FLOAT, BITS_PER_UNIT*24, 24, 12, TCmode, XFmode)
DEF_MACHMODE (TCmode, "TC", MODE_COMPLEX_FLOAT, BITS_PER_UNIT*32, 32, 16, VOIDmode, TFmode)
/* Basic CC modes. */
CC_MODE (CC);
DEF_MACHMODE (CQImode, "CQI", MODE_COMPLEX_INT, BITS_PER_UNIT*2, 2, 1, CHImode, QImode)
DEF_MACHMODE (CHImode, "CHI", MODE_COMPLEX_INT, BITS_PER_UNIT*4, 4, 2, CSImode, HImode)
DEF_MACHMODE (CSImode, "CSI", MODE_COMPLEX_INT, BITS_PER_UNIT*8, 8, 4, CDImode, SImode)
DEF_MACHMODE (CDImode, "CDI", MODE_COMPLEX_INT, BITS_PER_UNIT*16, 16, 8, CTImode, DImode)
DEF_MACHMODE (CTImode, "CTI", MODE_COMPLEX_INT, BITS_PER_UNIT*32, 32, 16, COImode, TImode)
DEF_MACHMODE (COImode, "COI", MODE_COMPLEX_INT, BITS_PER_UNIT*64, 64, 32, VOIDmode, OImode)
/* Vector modes. */
/* The wider mode field for vectors follows in order of increasing bit
size with QI coming before HI, HI before SI, and SI before DI
within same bit sizes. */
DEF_MACHMODE (V1DImode, "V1DI", MODE_VECTOR_INT, BITS_PER_UNIT*8, 8, 8, V2QImode, DImode)
DEF_MACHMODE (V2QImode, "V2QI", MODE_VECTOR_INT, BITS_PER_UNIT*2, 2, 1, V4QImode, QImode)
DEF_MACHMODE (V2HImode, "V2HI", MODE_VECTOR_INT, BITS_PER_UNIT*4, 4, 2, V8QImode, HImode)
DEF_MACHMODE (V2SImode, "V2SI", MODE_VECTOR_INT, BITS_PER_UNIT*8, 8, 4, V16QImode, SImode)
DEF_MACHMODE (V2DImode, "V2DI", MODE_VECTOR_INT, BITS_PER_UNIT*16, 16, 8, V8SImode, DImode)
DEF_MACHMODE (V4QImode, "V4QI", MODE_VECTOR_INT, BITS_PER_UNIT*4, 4, 1, V2HImode, QImode)
DEF_MACHMODE (V4HImode, "V4HI", MODE_VECTOR_INT, BITS_PER_UNIT*8, 8, 2, V2SImode, HImode)
DEF_MACHMODE (V4SImode, "V4SI", MODE_VECTOR_INT, BITS_PER_UNIT*16, 16, 4, V2DImode, SImode)
DEF_MACHMODE (V4DImode, "V4DI", MODE_VECTOR_INT, BITS_PER_UNIT*32, 32, 8, V8DImode, DImode)
DEF_MACHMODE (V8QImode, "V8QI", MODE_VECTOR_INT, BITS_PER_UNIT*8, 8, 1, V4HImode, QImode)
DEF_MACHMODE (V8HImode, "V8HI", MODE_VECTOR_INT, BITS_PER_UNIT*16, 16, 2, V4SImode, HImode)
DEF_MACHMODE (V8SImode, "V8SI", MODE_VECTOR_INT, BITS_PER_UNIT*32, 32, 4, V4DImode, SImode)
DEF_MACHMODE (V8DImode, "V8DI", MODE_VECTOR_INT, BITS_PER_UNIT*64, 64, 8, VOIDmode, DImode)
DEF_MACHMODE (V16QImode, "V16QI", MODE_VECTOR_INT, BITS_PER_UNIT*16, 16, 1, V8HImode, QImode)
DEF_MACHMODE (V2HFmode, "V2HF", MODE_VECTOR_FLOAT, BITS_PER_UNIT*4, 4, 2, V4HFmode, HFmode)
DEF_MACHMODE (V2SFmode, "V2SF", MODE_VECTOR_FLOAT, BITS_PER_UNIT*8, 8, 4, V4SFmode, SFmode)
DEF_MACHMODE (V2DFmode, "V2DF", MODE_VECTOR_FLOAT, BITS_PER_UNIT*16, 16, 8, V8SFmode, DFmode)
DEF_MACHMODE (V4HFmode, "V4HF", MODE_VECTOR_FLOAT, BITS_PER_UNIT*8, 8, 2, V2SFmode, HFmode)
DEF_MACHMODE (V4SFmode, "V4SF", MODE_VECTOR_FLOAT, BITS_PER_UNIT*16, 16, 4, V2DFmode, SFmode)
DEF_MACHMODE (V4DFmode, "V4DF", MODE_VECTOR_FLOAT, BITS_PER_UNIT*32, 32, 8, V8DFmode, DFmode)
DEF_MACHMODE (V8HFmode, "V8HF", MODE_VECTOR_FLOAT, BITS_PER_UNIT*16, 16, 2, V4SFmode, HFmode)
DEF_MACHMODE (V8SFmode, "V8SF", MODE_VECTOR_FLOAT, BITS_PER_UNIT*32, 32, 4, V4DFmode, SFmode)
DEF_MACHMODE (V8DFmode, "V8DF", MODE_VECTOR_FLOAT, BITS_PER_UNIT*64, 64, 8, VOIDmode, DFmode)
DEF_MACHMODE (V16SFmode, "V16SF", MODE_VECTOR_FLOAT, 512, 64, 4, VOIDmode, SFmode)
/* BLKmode is used for structures, arrays, etc.
that fit no more specific mode. */
DEF_MACHMODE (BLKmode, "BLK", MODE_RANDOM, 0, 0, 0, VOIDmode, VOIDmode)
/* The modes for representing the condition codes come last. CCmode
is always defined. Additional modes for the condition code can be
specified in the EXTRA_CC_MODES header. All MODE_CC modes are the
same width as SImode and have VOIDmode as their next wider mode. */
/* We do not use CC() for CCmode to avoid a warning about use of
function-like macros with no arguments. */
DEF_MACHMODE (CCmode, "CC", MODE_CC, BITS_PER_UNIT*4, 4, 4, VOIDmode, VOIDmode)
#ifdef EXTRA_MODES_FILE
#define CC(N) \
DEF_MACHMODE (N##mode, #N, \
MODE_CC, BITS_PER_UNIT*4, 4, 4, VOIDmode, VOIDmode)
#include EXTRA_MODES_FILE
#undef CC
/* Allow the target to specify additional modes of various kinds. */
#if HAVE_EXTRA_MODES
# define CC(X) CC_MODE(X); /* backward compatibility, temporary */
# include EXTRA_MODES_FILE
# undef CC
#endif
/* Complex modes. */
COMPLEX_MODES (INT);
COMPLEX_MODES (FLOAT);
/* Vector modes. */
VECTOR_MODES (INT, 2); /* V2QI */
VECTOR_MODES (INT, 4); /* V4QI V2HI */
VECTOR_MODES (INT, 8); /* V8QI V4HI V2SI */
VECTOR_MODES (INT, 16); /* V16QI V8HI V4SI V2DI */
/* VECTOR_MODES (INT, 32); V8SI V4DI */
/* VECTOR_MODES (INT, 64); V8DI */
VECTOR_MODE (INT, SI, 8)
VECTOR_MODE (INT, DI, 4);
VECTOR_MODE (INT, DI, 8);
VECTOR_MODE (INT, DI, 1); /* PPC uses this. Why not plain DI? */
VECTOR_MODES (FLOAT, 4); /* V2HF */
VECTOR_MODES (FLOAT, 8); /* V4HF V2SF */
VECTOR_MODES (FLOAT, 16); /* V8HF V4SF V2DF */
/* VECTOR_MODES (FLOAT, 32); V8SF V4DF */
/* VECTOR_MODES (FLOAT, 64); V16SF V8DF */
VECTOR_MODE (FLOAT, SF, 8);
VECTOR_MODE (FLOAT, SF, 16);
VECTOR_MODE (FLOAT, DF, 4);
VECTOR_MODE (FLOAT, DF, 8);
/* The symbol Pmode stands for one of the above machine modes (usually SImode).
The tm file specifies which one. It is not a distinct mode. */
The tm.h file specifies which one. It is not a distinct mode. */
/*
Local variables:

View File

@ -23,34 +23,26 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#define HAVE_MACHINE_MODES
/* Make an enum class that gives all the machine modes. */
#define DEF_MACHMODE(SYM, NAME, TYPE, BITSIZE, SIZE, UNIT, WIDER, INNER) SYM,
enum machine_mode {
#include "machmode.def"
MAX_MACHINE_MODE };
#undef DEF_MACHMODE
#ifndef NUM_MACHINE_MODES
#define NUM_MACHINE_MODES (int) MAX_MACHINE_MODE
#endif
#include "insn-modes.h"
/* Get the name of mode MODE as a string. */
extern const char * const mode_name[NUM_MACHINE_MODES];
#define GET_MODE_NAME(MODE) (mode_name[(int) (MODE)])
#define GET_MODE_NAME(MODE) mode_name[MODE]
enum mode_class { MODE_RANDOM, MODE_INT, MODE_FLOAT, MODE_PARTIAL_INT, MODE_CC,
MODE_COMPLEX_INT, MODE_COMPLEX_FLOAT,
MODE_VECTOR_INT, MODE_VECTOR_FLOAT,
MAX_MODE_CLASS};
/* Mode classes. */
#include "mode-classes.def"
#define DEF_MODE_CLASS(M) M
enum mode_class { MODE_CLASSES, MAX_MODE_CLASS };
#undef DEF_MODE_CLASS
#undef MODE_CLASSES
/* Get the general kind of object that mode MODE represents
(integer, floating, complex, etc.) */
extern const enum mode_class mode_class[NUM_MACHINE_MODES];
#define GET_MODE_CLASS(MODE) (mode_class[(int) (MODE)])
extern const unsigned char mode_class[NUM_MACHINE_MODES];
#define GET_MODE_CLASS(MODE) mode_class[MODE]
/* Nonzero if MODE is an integral mode. */
#define INTEGRAL_MODE_P(MODE) \
@ -87,12 +79,12 @@ extern const enum mode_class mode_class[NUM_MACHINE_MODES];
/* Get the size in bytes of an object of mode MODE. */
extern const unsigned char mode_size[NUM_MACHINE_MODES];
#define GET_MODE_SIZE(MODE) (mode_size[(int) (MODE)])
#define GET_MODE_SIZE(MODE) mode_size[MODE]
/* Get the size in bytes of the basic parts of an object of mode MODE. */
extern const unsigned char mode_unit_size[NUM_MACHINE_MODES];
#define GET_MODE_UNIT_SIZE(MODE) (mode_unit_size[(int) (MODE)])
#define GET_MODE_UNIT_SIZE(MODE) mode_unit_size[MODE]
/* Get the number of units in the object. */
@ -103,7 +95,7 @@ extern const unsigned char mode_unit_size[NUM_MACHINE_MODES];
/* Get the size in bits of an object of mode MODE. */
extern const unsigned short mode_bitsize[NUM_MACHINE_MODES];
#define GET_MODE_BITSIZE(MODE) (mode_bitsize[(int) (MODE)])
#define GET_MODE_BITSIZE(MODE) mode_bitsize[MODE]
#endif /* not HAVE_MACHINE_MODES */
@ -114,13 +106,13 @@ extern const unsigned short mode_bitsize[NUM_MACHINE_MODES];
extern const unsigned HOST_WIDE_INT mode_mask_array[NUM_MACHINE_MODES];
#define GET_MODE_MASK(MODE) mode_mask_array[(int) (MODE)]
#define GET_MODE_MASK(MODE) mode_mask_array[MODE]
extern const enum machine_mode inner_mode_array[NUM_MACHINE_MODES];
extern const unsigned char mode_inner[NUM_MACHINE_MODES];
/* Return the mode of the inner elements in a vector. */
#define GET_MODE_INNER(MODE) inner_mode_array[(int) (MODE)]
#define GET_MODE_INNER(MODE) mode_inner[MODE]
#endif /* defined (HOST_WIDE_INT) && ! defined GET_MODE_MASK */
@ -129,8 +121,8 @@ extern const enum machine_mode inner_mode_array[NUM_MACHINE_MODES];
/* Get the next wider natural mode (eg, QI -> HI -> SI -> DI -> TI). */
extern const unsigned char mode_wider_mode[NUM_MACHINE_MODES];
#define GET_MODE_WIDER_MODE(MODE) ((enum machine_mode)mode_wider_mode[(int) (MODE)])
extern const unsigned char mode_wider[NUM_MACHINE_MODES];
#define GET_MODE_WIDER_MODE(MODE) mode_wider[MODE]
/* Return the mode for data of a given size SIZE and mode class CLASS.
If LIMIT is nonzero, then don't use modes bigger than MAX_FIXED_MODE_SIZE.
@ -156,14 +148,16 @@ extern enum machine_mode get_best_mode (int, int, unsigned int,
/* Determine alignment, 1<=result<=BIGGEST_ALIGNMENT. */
extern const unsigned char mode_base_align[NUM_MACHINE_MODES];
extern unsigned get_mode_alignment (enum machine_mode);
#define GET_MODE_ALIGNMENT(MODE) get_mode_alignment (MODE)
/* For each class, get the narrowest mode in that class. */
extern const enum machine_mode class_narrowest_mode[(int) MAX_MODE_CLASS];
#define GET_CLASS_NARROWEST_MODE(CLASS) class_narrowest_mode[(int) (CLASS)]
extern const unsigned char class_narrowest_mode[MAX_MODE_CLASS];
#define GET_CLASS_NARROWEST_MODE(CLASS) class_narrowest_mode[CLASS]
/* Define the integer modes whose sizes are BITS_PER_UNIT and BITS_PER_WORD
and the mode whose class is Pmode and whose size is POINTER_SIZE. */

31
gcc/mode-classes.def Normal file
View File

@ -0,0 +1,31 @@
/* Machine mode class definitions for GCC.
Copyright (C) 2003
Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 2, or (at your option) any later
version.
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING. If not, write to the Free
Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA. */
#define MODE_CLASSES \
DEF_MODE_CLASS (MODE_RANDOM), /* other */ \
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_FLOAT), /* floating point */ \
DEF_MODE_CLASS (MODE_COMPLEX_INT), /* complex numbers */ \
DEF_MODE_CLASS (MODE_COMPLEX_FLOAT), \
DEF_MODE_CLASS (MODE_VECTOR_INT), /* SIMD vectors */ \
DEF_MODE_CLASS (MODE_VECTOR_FLOAT)

View File

@ -143,9 +143,10 @@ struct real_format
/* The target format used for each floating floating point mode.
Indexed by MODE - QFmode. */
extern const struct real_format *real_format_for_mode[TFmode - QFmode + 1];
extern const struct real_format *
real_format_for_mode[MAX_MODE_FLOAT - MIN_MODE_FLOAT + 1];
#define REAL_MODE_FORMAT(MODE) (real_format_for_mode[(MODE) - QFmode])
#define REAL_MODE_FORMAT(MODE) (real_format_for_mode[(MODE) - MIN_MODE_FLOAT])
/* Declare functions in real.c. */

109
gcc/rtl.c
View File

@ -50,115 +50,6 @@ const char * const rtx_name[NUM_RTX_CODE] = {
#undef DEF_RTL_EXPR
/* Indexed by machine mode, gives the name of that machine mode.
This name does not include the letters "mode". */
#define DEF_MACHMODE(SYM, NAME, CLASS, BITSIZE, SIZE, UNIT, WIDER, INNER) NAME,
const char * const mode_name[NUM_MACHINE_MODES] = {
#include "machmode.def"
};
#undef DEF_MACHMODE
/* Indexed by machine mode, gives the class mode for GET_MODE_CLASS. */
#define DEF_MACHMODE(SYM, NAME, CLASS, BITSIZE, SIZE, UNIT, WIDER, INNER) CLASS,
const enum mode_class mode_class[NUM_MACHINE_MODES] = {
#include "machmode.def"
};
#undef DEF_MACHMODE
/* Indexed by machine mode, gives the length of the mode, in bits.
GET_MODE_BITSIZE uses this. */
#define DEF_MACHMODE(SYM, NAME, CLASS, BITSIZE, SIZE, UNIT, WIDER, INNER) BITSIZE,
const unsigned short mode_bitsize[NUM_MACHINE_MODES] = {
#include "machmode.def"
};
#undef DEF_MACHMODE
/* Indexed by machine mode, gives the length of the mode, in bytes.
GET_MODE_SIZE uses this. */
#define DEF_MACHMODE(SYM, NAME, CLASS, BITSIZE, SIZE, UNIT, WIDER, INNER) SIZE,
const unsigned char mode_size[NUM_MACHINE_MODES] = {
#include "machmode.def"
};
#undef DEF_MACHMODE
/* Indexed by machine mode, gives the length of the mode's subunit.
GET_MODE_UNIT_SIZE uses this. */
#define DEF_MACHMODE(SYM, NAME, CLASS, BITSIZE, SIZE, UNIT, WIDER, INNER) UNIT,
const unsigned char mode_unit_size[NUM_MACHINE_MODES] = {
#include "machmode.def" /* machine modes are documented here */
};
#undef DEF_MACHMODE
/* Indexed by machine mode, gives next wider natural mode
(QI -> HI -> SI -> DI, etc.) Widening multiply instructions
use this. */
#define DEF_MACHMODE(SYM, NAME, CLASS, BITSIZE, SIZE, UNIT, WIDER, INNER) \
(unsigned char) WIDER,
const unsigned char mode_wider_mode[NUM_MACHINE_MODES] = {
#include "machmode.def" /* machine modes are documented here */
};
#undef DEF_MACHMODE
#define DEF_MACHMODE(SYM, NAME, CLASS, BITSIZE, SIZE, UNIT, WIDER, INNER) \
((BITSIZE) >= HOST_BITS_PER_WIDE_INT) ? ~(unsigned HOST_WIDE_INT) 0 : ((unsigned HOST_WIDE_INT) 1 << (BITSIZE)) - 1,
/* Indexed by machine mode, gives mask of significant bits in mode. */
const unsigned HOST_WIDE_INT mode_mask_array[NUM_MACHINE_MODES] = {
#include "machmode.def"
};
#undef DEF_MACHMODE
#define DEF_MACHMODE(SYM, NAME, CLASS, BITSIZE, SIZE, UNIT, WIDER, INNER) INNER,
/* Indexed by machine mode, gives the mode of the inner elements in a
vector type. */
const enum machine_mode inner_mode_array[NUM_MACHINE_MODES] = {
#include "machmode.def"
};
/* Indexed by mode class, gives the narrowest mode for each class.
The Q modes are always of width 1 (2 for complex) - it is impossible
for any mode to be narrower.
Note that we use QImode instead of BImode for MODE_INT, since
otherwise the middle end will try to use it for bitfields in
structures and the like, which we do not want. Only the target
md file should generate BImode widgets. */
const enum machine_mode class_narrowest_mode[(int) MAX_MODE_CLASS] = {
/* MODE_RANDOM */ VOIDmode,
/* MODE_INT */ QImode,
/* MODE_FLOAT */ QFmode,
/* MODE_PARTIAL_INT */ PQImode,
/* MODE_CC */ CCmode,
/* MODE_COMPLEX_INT */ CQImode,
/* MODE_COMPLEX_FLOAT */ QCmode,
/* MODE_VECTOR_INT */ V1DImode,
/* MODE_VECTOR_FLOAT */ V2SFmode
};
/* Indexed by rtx code, gives a sequence of operand-types for
rtx's of that code. The sequence is a C string in which
each character describes one operand. */

View File

@ -298,20 +298,7 @@ int_mode_for_mode (enum machine_mode mode)
unsigned int
get_mode_alignment (enum machine_mode mode)
{
unsigned int alignment;
if (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT
|| GET_MODE_CLASS (mode) == MODE_COMPLEX_INT)
alignment = GET_MODE_UNIT_SIZE (mode);
else
alignment = GET_MODE_SIZE (mode);
/* Extract the LSB of the size. */
alignment = alignment & -alignment;
alignment *= BITS_PER_UNIT;
alignment = MIN (BIGGEST_ALIGNMENT, MAX (1, alignment));
return alignment;
return MIN (BIGGEST_ALIGNMENT, MAX (1, mode_base_align[mode]*BITS_PER_UNIT));
}
/* Return the value of VALUE, rounded up to a multiple of DIVISOR.