mmix.h

来自「gcc3.2.1源代码」· C头文件 代码 · 共 1,230 行 · 第 1/3 页

H
1,230
字号
/* Definitions of target machine for GNU compiler, for MMIX.   Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc.   Contributed by Hans-Peter Nilsson (hp@bitrange.com)This file is part of GNU CC.GNU CC is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation; either version 2, or (at your option)any later version.GNU CC is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with GNU CC; see the file COPYING.  If not, write tothe Free Software Foundation, 59 Temple Place - Suite 330,Boston, MA 02111-1307, USA.  */#ifndef GCC_MMIX_H#define GCC_MMIX_H/* First, some local helper macros.  Note that the "default" value of   FIXED_REGISTERS, CALL_USED_REGISTERS, REG_ALLOC_ORDER and   REG_CLASS_CONTENTS depend on these values.  */#define MMIX_RESERVED_GNU_ARG_0_REGNUM 231#define MMIX_FIRST_ARG_REGNUM \  (TARGET_ABI_GNU ? MMIX_RESERVED_GNU_ARG_0_REGNUM : 16)#define MMIX_FIRST_INCOMING_ARG_REGNUM \  (TARGET_ABI_GNU ? MMIX_RESERVED_GNU_ARG_0_REGNUM : 0)#define MMIX_MAX_ARGS_IN_REGS 16/* FIXME: This one isn't fully implemented yet.  Return values larger than   one register are passed by reference in MMIX_STRUCT_VALUE_REGNUM by the   caller, except for return values of type "complex".  */#define MMIX_MAX_REGS_FOR_VALUE 16#define MMIX_RETURN_VALUE_REGNUM \  (TARGET_ABI_GNU ? MMIX_RESERVED_GNU_ARG_0_REGNUM : 15)#define MMIX_OUTGOING_RETURN_VALUE_REGNUM \  (TARGET_ABI_GNU ? MMIX_RESERVED_GNU_ARG_0_REGNUM : 0)#define MMIX_STRUCT_VALUE_REGNUM 251#define MMIX_STATIC_CHAIN_REGNUM 252#define MMIX_FRAME_POINTER_REGNUM 253#define MMIX_STACK_POINTER_REGNUM 254#define MMIX_LAST_GENERAL_REGISTER 255#define MMIX_INCOMING_RETURN_ADDRESS_REGNUM MMIX_rJ_REGNUM#define MMIX_HIMULT_REGNUM 258#define MMIX_REMAINDER_REGNUM 260#define MMIX_ARG_POINTER_REGNUM 261#define MMIX_LAST_REGISTER_FILE_REGNUM 31/* Four registers; "ideally, these registers should be call-clobbered", so   just grab a bunch of the common clobbered registers.  FIXME: Last   registers of return-value should be used, with an error if there's a   return-value (that collides in size).  */#define MMIX_EH_RETURN_DATA_REGNO_START (MMIX_STRUCT_VALUE_REGNUM - 4)/* Try to keep the definitions from running away on their own.  */#if (MMIX_EH_RETURN_DATA_REGNO_START \     != MMIX_RESERVED_GNU_ARG_0_REGNUM + MMIX_MAX_ARGS_IN_REGS) #error MMIX register definition inconsistency#endif#if (MMIX_MAX_REGS_FOR_VALUE + MMIX_MAX_ARGS_IN_REGS > 32) #error MMIX parameters and return values bad, more than 32 registers#endif/* This chosen as "a call-clobbered hard register that is otherwise   untouched by the epilogue".  */#define MMIX_EH_RETURN_STACKADJ_REGNUM MMIX_STATIC_CHAIN_REGNUM#ifdef REG_OK_STRICT# define MMIX_REG_OK_STRICT 1#else# define MMIX_REG_OK_STRICT 0#endif#define MMIX_FUNCTION_ARG_SIZE(MODE, TYPE) \ ((MODE) != BLKmode ? GET_MODE_SIZE (MODE) : int_size_in_bytes (TYPE))/* Declarations for helper variables that are not tied to a particular   target macro.  */extern struct rtx_def *mmix_compare_op0;extern struct rtx_def *mmix_compare_op1;/* Per-function machine data.  This is normally an opaque type just   defined and used in the tm.c file, but we need to see the definition in   mmix.md too.  */struct machine_function {   int has_landing_pad; };/* For these target macros, there is no generic documentation here.  You   should read `Using and Porting GCC' for that.  Only comments specific   to the MMIX target are here.   There are however references to the specific texinfo node (comments   with "Node:"), so there should be little or nothing amiss.  Probably   the opposite, since we don't have to care about old littering and   soon outdated generic comments.  *//* Node: Driver *//* When both ABI:s work, this is how we tell them apart in code.  The   GNU abi is implied the default.  Also implied in TARGET_DEFAULT.  */#define CPP_SPEC \ "%{mabi=gnu:-D__MMIX_ABI_GNU__\    %{mabi=mmixware:\      %eoptions -mabi=mmixware and -mabi=gnu are mutually exclusive}}\  %{!mabi=gnu:-D__MMIX_ABI_MMIXWARE__}"/* User symbols are in the same name-space as built-in symbols, but we   don't need the built-in symbols, so remove those and instead apply   stricter operand checking.  Don't warn when expanding insns.  */#define ASM_SPEC "-no-predefined-syms -x"/* Pass on -mset-program-start=N and -mset-data-start=M to the linker.   Provide default program start 0x100 unless -mno-set-program-start.   Don't do this if linking relocatably, with -r.  For a final link,   produce mmo, unless ELF is requested or when linking relocatably.  */#define LINK_SPEC \ "%{mset-program-start=*:--defsym __.MMIX.start..text=%*}\  %{mset-data-start=*:--defsym __.MMIX.start..data=%*}\  %{!mset-program-start=*:\    %{!mno-set-program-start:\     %{!r:--defsym __.MMIX.start..text=0x100}}}\  %{!melf:%{!r:-m mmo}}%{melf|r:-m elf64mmix}"/* Put unused option values here.  */extern const char *mmix_cc1_ignored_option;#define TARGET_OPTIONS					\   {{"set-program-start=", &mmix_cc1_ignored_option,	\  N_("Set start-address of the program") },		\    {"set-data-start=", &mmix_cc1_ignored_option,	\  N_("Set start-address of data")}}/* FIXME: There's no provision for profiling here.  */#define STARTFILE_SPEC  \  "crti%O%s crtbegin%O%s"#define ENDFILE_SPEC "crtend%O%s crtn%O%s"/* Node: Run-time Target *//* Define __LONG_MAX__, since we're advised not to change glimits.h.  */#define CPP_PREDEFINES "-D__mmix__ -D__MMIX__ -D__LONG_MAX__=9223372036854775807L"extern int target_flags;#define TARGET_MASK_LIBFUNCS 1#define TARGET_MASK_ABI_GNU 2#define TARGET_MASK_FCMP_EPSILON 4#define TARGET_MASK_ZERO_EXTEND 8#define TARGET_MASK_KNUTH_DIVISION 16#define TARGET_MASK_TOPLEVEL_SYMBOLS 32#define TARGET_MASK_BRANCH_PREDICT 64/* We use the term "base address" since that's what Knuth uses.  The base   address goes in a global register.  When addressing, it's more like   "base address plus offset", with the offset being 0..255 from the base,   which itself can be a symbol plus an offset.  The effect is like having   a constant pool in global registers, code offseting from those   registers (automatically causing a request for a suitable constant base   address register) without having to know the specific register or the   specific offset.  */#define TARGET_MASK_BASE_ADDRESSES 128/* FIXME: Get rid of this one.  */#define TARGET_LIBFUNC (target_flags & TARGET_MASK_LIBFUNCS)#define TARGET_ABI_GNU (target_flags & TARGET_MASK_ABI_GNU)#define TARGET_FCMP_EPSILON (target_flags & TARGET_MASK_FCMP_EPSILON)#define TARGET_ZERO_EXTEND (target_flags & TARGET_MASK_ZERO_EXTEND)#define TARGET_KNUTH_DIVISION (target_flags & TARGET_MASK_KNUTH_DIVISION)#define TARGET_TOPLEVEL_SYMBOLS (target_flags & TARGET_MASK_TOPLEVEL_SYMBOLS)#define TARGET_BRANCH_PREDICT (target_flags & TARGET_MASK_BRANCH_PREDICT)#define TARGET_BASE_ADDRESSES (target_flags & TARGET_MASK_BASE_ADDRESSES)#define TARGET_DEFAULT \ (TARGET_MASK_BRANCH_PREDICT | TARGET_MASK_BASE_ADDRESSES)/* FIXME: Provide a way to *load* the epsilon register.  */#define TARGET_SWITCHES							\ {{"libfuncs",		TARGET_MASK_LIBFUNCS,				\   N_("For intrinsics library: pass all parameters in registers")},	\  {"no-libfuncs",	-TARGET_MASK_LIBFUNCS, ""},			\  {"abi=mmixware",	-TARGET_MASK_ABI_GNU,				\   N_("Use register stack for parameters and return value")},		\  {"abi=gnu",		TARGET_MASK_ABI_GNU,				\   N_("Use call-clobbered registers for parameters and return value")},	\  {"epsilon",		TARGET_MASK_FCMP_EPSILON,			\   N_("Use epsilon-respecting floating point compare instructions")},	\  {"no-epsilon",	-TARGET_MASK_FCMP_EPSILON, ""},			\  {"zero-extend",	TARGET_MASK_ZERO_EXTEND,			\   N_("Use zero-extending memory loads, not sign-extending ones")},	\  {"no-zero-extend",	-TARGET_MASK_ZERO_EXTEND,  ""},			\  {"knuthdiv",		TARGET_MASK_KNUTH_DIVISION,			\   N_("Generate divide results with reminder having the same sign as the\ divisor (not the dividend)")},						\  {"no-knuthdiv",	-TARGET_MASK_KNUTH_DIVISION, ""},		\  {"toplevel-symbols",	TARGET_MASK_TOPLEVEL_SYMBOLS,			\   N_("Prepend global symbols with \":\" (for use with PREFIX)")},	\  {"no-toplevel-symbols", -TARGET_MASK_TOPLEVEL_SYMBOLS,		\   N_("Do not provide a default start-address 0x100 of the program")},	\  {"elf", 0,								\   N_("Link to emit program in ELF format (rather than mmo)")},		\  {"branch-predict",	TARGET_MASK_BRANCH_PREDICT,			\   N_("Use P-mnemonics for branches statically predicted as taken")},	\  {"no-branch-predict",	-TARGET_MASK_BRANCH_PREDICT,			\   N_("Don't use P-mnemonics for branches")},				\  {"base-addresses",	TARGET_MASK_BASE_ADDRESSES,			\   N_("Use addresses that allocate global registers")},			\  {"no-base-addresses",	-TARGET_MASK_BASE_ADDRESSES,			\   N_("Do not use addresses that allocate global registers")},		\  {"",			TARGET_DEFAULT, ""}}/* Unfortunately, this must not reference anything in "mmix.c".  */#define TARGET_VERSION \  fprintf (stderr, " (MMIX)")#define OVERRIDE_OPTIONS mmix_override_options ()#define OPTIMIZATION_OPTIONS(LEVEL, SIZE)	\  do						\    {						\      if (LEVEL >= 1)				\	flag_regmove = TRUE;			\      						\      if (SIZE || LEVEL > 1)			\	{					\	  flag_omit_frame_pointer = TRUE;	\	  flag_strength_reduce = FALSE;		\	}					\    }						\  while (0)/* This one will have to wait a little bit; right now we can't debug   neither with or without a frame-pointer.  *//* #define CAN_DEBUG_WITHOUT_FP *//* Node: Per-Function Data */#define INIT_EXPANDERS mmix_init_expanders ()/* Node: Storage Layout *//* I see no bitfield instructions.  Anyway, the common order is from low   to high, as the power of two, hence little-endian.  */#define BITS_BIG_ENDIAN 0#define BYTES_BIG_ENDIAN 1#define WORDS_BIG_ENDIAN 1#define FLOAT_WORDS_BIG_ENDIAN 1#define BITS_PER_UNIT 8#define BITS_PER_WORD 64#define UNITS_PER_WORD 8#define POINTER_SIZE 64/* FIXME: This macro is correlated to MAX_FIXED_MODE_SIZE in that   e.g. this macro must not be 8 (default, UNITS_PER_WORD) when   MAX_FIXED_MODE_SIZE is 64 (default, DImode), or really: this must be   set manually if MAX_FIXED_MODE_SIZE is not at least twice the register   size.  By setting it to 4, we don't have to worry about TImode things   yet.  Revisit, perhaps get TImode going or get some solution that does   not mandate TImode or lie in other ways.  */#define MIN_UNITS_PER_WORD 4/* FIXME: Promotion of modes currently generates slow code, extending   before every operation.  */#define PROMOTE_MODE(MODE, UNSIGNEDP, TYPE)	\ do {						\  if (GET_MODE_CLASS (MODE) == MODE_INT		\      && GET_MODE_SIZE (MODE) < 8)		\   {						\     (MODE) = DImode;				\     /* Do the following some time later,	\	scrutinizing differences.  */		\     if (0) (UNSIGNEDP) = 0;			\   }						\ } while (0)#define PROMOTE_FUNCTION_ARGS#if 0/* Apparently not doing TRT if int < register-size.  FIXME: Perhaps   FUNCTION_VALUE and LIBCALL_VALUE needs tweaking as some ports say.  */#define PROMOTE_FUNCTION_RETURN#endif/* I'm a little bit undecided about this one.  It might be beneficial to   promote all operations.  */#define PROMOTE_FOR_CALL_ONLY/* We need to align everything to 64 bits that can affect the alignment   of other types.  Since address N is interpreted in MMIX as (N modulo   access_size), we must align.  */#define PARM_BOUNDARY 64#define STACK_BOUNDARY 64#define FUNCTION_BOUNDARY 32#define BIGGEST_ALIGNMENT 64/* This one is only used in the ADA front end.  */#define MINIMUM_ATOMIC_ALIGNMENT 8/* Copied from elfos.h.  */#define MAX_OFILE_ALIGNMENT (32768 * 8)#define DATA_ALIGNMENT(TYPE, BASIC_ALIGN) \ mmix_data_alignment (TYPE, BASIC_ALIGN)#define CONSTANT_ALIGNMENT(CONSTANT, BASIC_ALIGN) \ mmix_constant_alignment (CONSTANT, BASIC_ALIGN)#define LOCAL_ALIGNMENT(TYPE, BASIC_ALIGN) \ mmix_local_alignment (TYPE, BASIC_ALIGN)/* Following other ports, this seems to most commonly be the word-size,   so let's do that here too.  */#define EMPTY_FIELD_BOUNDARY 64/* We chose to have this low solely for similarity with the alpha.  It has   nothing to do with passing the tests dg/c99-scope-2 and   execute/align-1.c.  Nothing.  Though the tests seem wrong.  Padding of   the structure is automatically added to get alignment when needed if we   set this to just byte-boundary.  */#define STRUCTURE_SIZE_BOUNDARY 8/* The lower bits are ignored.  */#define STRICT_ALIGNMENT 1/* Node: Type Layout *//* It might seem more natural to have 64-bit ints on a 64-bit machine,   but then an occasional MMIX programmer needs to know how to put a lot   of __attribute__ stuff to get to the 8, 16 and 32-bit modes rather   than the "intuitive" char, short and int types.  */#define INT_TYPE_SIZE 32#define SHORT_TYPE_SIZE 16#define LONG_LONG_TYPE_SIZE 64#define FLOAT_TYPE_SIZE 32#define DOUBLE_TYPE_SIZE 64#define LONG_DOUBLE_TYPE_SIZE 64#define DEFAULT_SIGNED_CHAR 1/* Node: Register Basics *//* We tell GCC about all 256 general registers, and we also include   rD, rE, rH, rJ and rR (in that order) so we can describe what insns   clobber them.  We use a faked register for the argument pointer.  It is   always eliminated towards the frame-pointer or the stack-pointer, never   output in assembly.  Any fixed register would do for this, like $255,   but future debugging is easier when using a separate register.  It   counts as a global register for pseudorandom reasons.  */#define FIRST_PSEUDO_REGISTER 262/* We treat general registers with no assigned purpose as fixed.  The   stack pointer, $254, is also fixed.  Register $255 is referred to as a   temporary register in the MMIX papers, and used as such in mmixal, so   it should not be used as a stack pointer.  We set it to fixed, and use   it "manually" at times of despair.  */#define FIXED_REGISTERS \ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \   1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, \   1, 1, 0, 0, 0, 1 \ }/* General registers are fixed and therefore "historically" marked   call-used.  (FIXME: This has changed).  Registers $15..$31 are   call-clobbered; we'll put arguments in $16 and up, and we need $15 for   the MMIX register-stack "hole".  */#define CALL_USED_REGISTERS \ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, \   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, \   1, 1, 1, 1, 1, 1 \ }

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?