1 定义
对于machine_mode,gcc internals是这样解释的:
A machine mode describes a size of data object and the representation used for it. In the C code, machine modes are represented by an enumeration type, enum machine_mode, defined in ‘machmode.def’. Each RTL expression has room for a machine mode and so do certain kinds of tree expressions (declarations and types, to be precise).
而machmode.def中的注释是:
/* This file defines all the MACHINE MODES used by GCC.
A machine mode specifies a size and format of data
at the machine level.
Each RTL expression has a machine mode.
At the syntax tree level, each ..._TYPE and each ..._DECL node
has a machine mode which describes data of that type or the
data of the variable declared. */
从上面的解释可以看出machine_mode指的是一个具体的CPU所能实现的操作数类型和数据长度,如单字节整数,双字节整数,浮点数等等。gcc internals给出了几十种的数据类型,但是通常一个CPU只能实现其中的一部分。比如bf561这个DSP,它实现的操作数类型就只有以下几种(insn-modes.h):
VOIDmode, /* machmode.def:146 */
BLKmode, /* machmode.def:150 */
CCmode, /* machmode.def:178 */
BImode, /* machmode.def:153 */
QImode, /* machmode.def:158 */
HImode, /* machmode.def:159 */
SImode, /* machmode.def:160 */
DImode, /* machmode.def:161 */
TImode, /* machmode.def:162 */
PDImode, /* config/bfin/bfin-modes.def:23 */
SFmode, /* machmode.def:173 */
DFmode, /* machmode.def:174 */
CQImode, /* machmode.def:186 */
CHImode, /* machmode.def:186 */
CSImode, /* machmode.def:186 */
CDImode, /* machmode.def:186 */
CTImode, /* machmode.def:186 */
SCmode, /* machmode.def:187 */
DCmode, /* machmode.def:187 */
V2HImode, /* config/bfin/bfin-modes.def:25 */
V2SImode, /* config/bfin/bfin-modes.def:26 */
V2PDImode, /* config/bfin/bfin-modes.def:27 */
可以看出以上模式的定义来自两个文件,machmode.def和config/bfin/bfin-modes.def。其中machmode.def定义了每个CPU都必须实现的mode,而config目录下的def文件则是不同的CPU实现的mode。
在gcc internals列出的几十种machine_mode中,gcc又将之分为9大类,这就是所谓的MODE_CLASS。在gcc/mode-classes.def中定义。
#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)
2 动态生成
gcc对machine_mode的定义放在insn-modes.h里面,这是一个动态生成的头文件,由genmodes.c生成的可执行文件动态创建(带-h参数执行)。genmodes生成mode的定义,同时还将这些mode按照MODE_CLASS进行了排序。
这里有意思的一点是config/bfin/bfin-modes.def的包含。
genmodes.c中有这样一个函数:
static void
create_modes (void)
{
#include "machmode.def"
}
这个函数就是用来创建mode的链表的。当然在此函数之前事先定义了一些宏,如
#define INT_MODE(N, Y) FRACTIONAL_INT_MODE (N, -1U, Y)
#define FRACTIONAL_INT_MODE(N, B, Y) /
make_int_mode (#N, B, Y, __FILE__, __LINE__)
static void
make_int_mode (const char *name,
unsigned int precision, unsigned int bytesize,
const char *file, unsigned int line)
{
struct mode_data *m = new_mode (MODE_INT, name, file, line);
m->bytesize = bytesize;
m->precision = precision;
}
这样machmode.def中的
INT_MODE (QI, 1);
这样的语句就可以展开为一个函数调用,而在此函数中将新的模式放到链表中去。
而为了要包含config目录下不同的def文件,在machmode.def中有这样的语句:
/* Allow the target to specify additional modes of various kinds. */
#if HAVE_EXTRA_MODES
# include EXTRA_MODES_FILE
#endif
这其中的EXTRA_MODES_FILE是哪来的呢?
经过搜索可以在auto-host.h中发现它的定义:
/* Define to the name of a file containing a list of extra machine modes for
this architecture. */
#ifndef USED_FOR_TARGET
#define EXTRA_MODES_FILE "config/bfin/bfin-modes.def"
#endif
我们知道auto-host.h是由gcc/configure动态生成的,在此文件是搜索,发现了这样的语句:
# Look for a file containing extra machine modes.
if test -n "$extra_modes" && test -f $srcdir/config/$extra_modes; then
extra_modes_file='$(srcdir)'/config/${extra_modes}
cat >>confdefs.h <<_ACEOF
#define EXTRA_MODES_FILE "config/$extra_modes"
_ACEOF
fi
再搜索extra_modes的定义,在config.gcc中可以找到定义:
if test -f ${srcdir}/config/${cpu_type}/${cpu_type}-modes.def
then
extra_modes=${cpu_type}/${cpu_type}-modes.def
fi
原来如此!其实这一切都是取决于configure –target的配置。