⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sparc.h

📁 gcc库的原代码,对编程有很大帮助.
💻 H
📖 第 1 页 / 共 5 页
字号:
	+ (GET_MODE_CLASS (MODE) == MODE_FLOAT			\	   ? GET_MODE_SIZE (MODE) / 4				\	   : ROUND_ADVANCE ((MODE) == BLKmode			\			    ? GET_MODE_SIZE (Pmode)		\			    : GET_MODE_SIZE (MODE)));		\    sparc_arg_count++;						\  } while (0)#else#define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED)	\  ((CUM) += ((MODE) != BLKmode				\	     ? ROUND_ADVANCE (GET_MODE_SIZE (MODE))	\	     : ROUND_ADVANCE (int_size_in_bytes (TYPE))))#endif/* Return boolean indicating arg of mode MODE will be passed in a reg.   This macro is only used in this file.  */#ifdef SPARCV9#define PASS_IN_REG_P(CUM, MODE, TYPE)				\  (ROUND_REG ((CUM), (MODE)) < NPARM_REGS (MODE)		\   && ((TYPE)==0 || ! TREE_ADDRESSABLE ((tree)(TYPE)))		\   && ((TYPE)==0 || (MODE) != BLKmode))#else#define PASS_IN_REG_P(CUM, MODE, TYPE)				\  ((CUM) < NPARM_REGS (SImode)					\   && ((TYPE)==0 || ! TREE_ADDRESSABLE ((tree)(TYPE)))		\   && ((TYPE)==0 || (MODE) != BLKmode				\       || (TYPE_ALIGN (TYPE) % PARM_BOUNDARY == 0)))#endif/* Determine where to put an argument to a function.   Value is zero to push the argument on the stack,   or a hard register in which to store the argument.   MODE is the argument's machine mode.   TYPE is the data type of the argument (as a tree).    This is null for libcalls where that information may    not be available.   CUM is a variable of type CUMULATIVE_ARGS which gives info about    the preceding args and about the function being called.   NAMED is nonzero if this argument is a named parameter    (otherwise it is an extra parameter matching an ellipsis).  *//* On SPARC the first six args are normally in registers   and the rest are pushed.  Any arg that starts within the first 6 words   is at least partially passed in a register unless its data type forbids.   For v9, the first 6 int args are passed in regs and the first N   float args are passed in regs (where N is such that %f0-15 are filled).   The rest are pushed.  Any arg that starts within the first 6 words   is at least partially passed in a register unless its data type forbids.  */#define FUNCTION_ARG(CUM, MODE, TYPE, NAMED)				\  (PASS_IN_REG_P ((CUM), (MODE), (TYPE))				\   ? gen_rtx (REG, (MODE),						\	      (BASE_PASSING_ARG_REG (MODE) + ROUND_REG ((CUM), (MODE))))\   : 0)/* Define where a function finds its arguments.   This is different from FUNCTION_ARG because of register windows.  */#define FUNCTION_INCOMING_ARG(CUM, MODE, TYPE, NAMED)			\  (PASS_IN_REG_P ((CUM), (MODE), (TYPE))				\   ? gen_rtx (REG, (MODE),						\	      (BASE_INCOMING_ARG_REG (MODE) + ROUND_REG ((CUM), (MODE))))\   : 0)/* For an arg passed partly in registers and partly in memory,   this is the number of registers used.   For args passed entirely in registers or entirely in memory, zero.   Any arg that starts in the first 6 regs but won't entirely fit in them   needs partial registers on the Sparc (!v9).  On v9, there are no arguments   that are passed partially in registers (??? complex values?).  */#ifndef SPARCV9#define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) 		\  (PASS_IN_REG_P ((CUM), (MODE), (TYPE))				\   && ((CUM) + ((MODE) == BLKmode					\		? ROUND_ADVANCE (int_size_in_bytes (TYPE))		\		: ROUND_ADVANCE (GET_MODE_SIZE (MODE))) - NPARM_REGS (SImode) > 0)\   ? (NPARM_REGS (SImode) - (CUM))					\   : 0)#endif/* The SPARC ABI stipulates passing struct arguments (of any size) and   (!v9) quad-precision floats by invisible reference.   For Pascal, also pass arrays by reference.  */#define FUNCTION_ARG_PASS_BY_REFERENCE(CUM, MODE, TYPE, NAMED)		\  ((TYPE && (TREE_CODE (TYPE) == RECORD_TYPE				\	    || TREE_CODE (TYPE) == UNION_TYPE				\    	    || TREE_CODE (TYPE) == ARRAY_TYPE))				\   || (!TARGET_V9 && MODE == TFmode))/* A C expression that indicates when it is the called function's   responsibility to make copies of arguments passed by reference.   If the callee can determine that the argument won't be modified, it can   avoid the copy.  *//* ??? We'd love to be able to use NAMED here.  Unfortunately, it doesn't   include the last named argument so we keep track of the args ourselves.  */#ifdef SPARCV9#define FUNCTION_ARG_CALLEE_COPIES(CUM, MODE, TYPE, NAMED) \  (sparc_arg_count < sparc_n_named_args)#endif/* Initialize data used by insn expanders.  This is called from   init_emit, once for each function, before code is generated.   For v9, clear the temp slot used by float/int DImode conversions.   ??? There is the 16 bytes at [%fp-16], however we'd like to delete this   space at some point.   ??? Use assign_stack_temp?  */extern void sparc64_init_expanders ();extern struct rtx_def *sparc64_fpconv_stack_temp ();#ifdef SPARCV9#define INIT_EXPANDERS sparc64_init_expanders ()#endif/* Define the information needed to generate branch and scc insns.  This is   stored from the compare operation.  Note that we can't use "rtx" here   since it hasn't been defined!  */extern struct rtx_def *sparc_compare_op0, *sparc_compare_op1;/* Define the function that build the compare insn for scc and bcc.  */extern struct rtx_def *gen_compare_reg ();/* This function handles all v9 scc insns */extern int gen_v9_scc ();/* Generate the special assembly code needed to tell the assembler whatever   it might need to know about the return value of a function.   For Sparc assemblers, we need to output a .proc pseudo-op which conveys   information to the assembler relating to peephole optimization (done in   the assembler).  */#define ASM_DECLARE_RESULT(FILE, RESULT) \  fprintf ((FILE), "\t.proc\t0%o\n", sparc_type_code (TREE_TYPE (RESULT)))/* Output the label for a function definition.  */#define ASM_DECLARE_FUNCTION_NAME(FILE, NAME, DECL)			\do {									\  ASM_DECLARE_RESULT (FILE, DECL_RESULT (DECL));			\  ASM_OUTPUT_LABEL (FILE, NAME);					\} while (0)/* This macro generates the assembly code for function entry.   FILE is a stdio stream to output the code to.   SIZE is an int: how many units of temporary storage to allocate.   Refer to the array `regs_ever_live' to determine which registers   to save; `regs_ever_live[I]' is nonzero if register number I   is ever used in the function.  This macro is responsible for   knowing which registers should not be saved even if used.  *//* On SPARC, move-double insns between fpu and cpu need an 8-byte block   of memory.  If any fpu reg is used in the function, we allocate   such a block here, at the bottom of the frame, just in case it's needed.   If this function is a leaf procedure, then we may choose not   to do a "save" insn.  The decision about whether or not   to do this is made in regclass.c.  */extern int leaf_function;#define FUNCTION_PROLOGUE(FILE, SIZE)				\  (TARGET_FRW ? sparc_flat_output_function_prologue (FILE, SIZE) \   : output_function_prologue (FILE, SIZE, leaf_function))/* Output assembler code to FILE to increment profiler label # LABELNO   for profiling a function entry.  */#define FUNCTION_PROFILER(FILE, LABELNO)  			\  do {								\    fputs ("\tsethi %hi(", (FILE));				\    ASM_OUTPUT_INTERNAL_LABELREF (FILE, "LP", LABELNO);		\    fputs ("),%o0\n", (FILE));					\    if (TARGET_MEDANY)						\      fprintf (FILE, "\tadd %%o0,%s,%%o0\n",			\	       MEDANY_BASE_REG);				\    fputs ("\tcall mcount\n\tadd %lo(", (FILE));		\    ASM_OUTPUT_INTERNAL_LABELREF (FILE, "LP", LABELNO);		\    fputs ("),%o0,%o0\n", (FILE));				\  } while (0)/* Output assembler code to FILE to initialize this source file's   basic block profiling info, if that has not already been done.  */#define FUNCTION_BLOCK_PROFILER(FILE, LABELNO)  \  do { \    if (TARGET_MEDANY) \      fprintf (FILE, "\tsethi %%hi(LPBX0),%%o0\n\tor %%0,%%lo(LPBX0),%%o0\n\tld [%s+%%o0],%%o1\n\ttst %%o1\n\tbne LPY%d\n\tadd %%o0,%s,%%o0\n\tcall ___bb_init_func\n\tnop\nLPY%d:\n", \	       MEDANY_BASE_REG, (LABELNO), MEDANY_BASE_REG, (LABELNO)); \    else \      fprintf (FILE, "\tsethi %%hi(LPBX0),%%o0\n\tld [%%lo(LPBX0)+%%o0],%%o1\n\ttst %%o1\n\tbne LPY%d\n\tadd %%o0,%%lo(LPBX0),%%o0\n\tcall ___bb_init_func\n\tnop\nLPY%d:\n", \	       (LABELNO), (LABELNO)); \  } while (0)/* Output assembler code to FILE to increment the entry-count for   the BLOCKNO'th basic block in this source file.  */#define BLOCK_PROFILER(FILE, BLOCKNO) \{ \  int blockn = (BLOCKNO); \  if (TARGET_MEDANY) \    fprintf (FILE, "\tsethi %%hi(LPBX2+%d),%%g1\n\tor %%g1,%%lo(LPBX2+%d),%%g1\n\tld [%%g1+%s],%%g2\n\tadd %%g2,1,%%g2\n\tst %%g2,[%%g1+%s]\n", \	     4 * blockn, 4 * blockn, MEDANY_BASE_REG, MEDANY_BASE_REG); \  else \    fprintf (FILE, "\tsethi %%hi(LPBX2+%d),%%g1\n\tld [%%lo(LPBX2+%d)+%%g1],%%g2\n\\tadd %%g2,1,%%g2\n\tst %%g2,[%%lo(LPBX2+%d)+%%g1]\n", \	     4 * blockn, 4 * blockn, 4 * blockn); \}/* EXIT_IGNORE_STACK should be nonzero if, when returning from a function,   the stack pointer does not matter.  The value is tested only in   functions that have frame pointers.   No definition is equivalent to always zero.  */extern int current_function_calls_alloca;extern int current_function_outgoing_args_size;#define EXIT_IGNORE_STACK	\ (get_frame_size () != 0	\  || current_function_calls_alloca || current_function_outgoing_args_size)/* This macro generates the assembly code for function exit,   on machines that need it.  If FUNCTION_EPILOGUE is not defined   then individual return instructions are generated for each   return statement.  Args are same as for FUNCTION_PROLOGUE.   The function epilogue should not depend on the current stack pointer!   It should use the frame pointer only.  This is mandatory because   of alloca; we also take advantage of it to omit stack adjustments   before returning.  *//* This declaration is needed due to traditional/ANSI   incompatibilities which cannot be #ifdefed away   because they occur inside of macros.  Sigh.  */extern union tree_node *current_function_decl;#define FUNCTION_EPILOGUE(FILE, SIZE)				\  (TARGET_FRW ? sparc_flat_output_function_epilogue (FILE, SIZE) \   : output_function_epilogue (FILE, SIZE, leaf_function))#define DELAY_SLOTS_FOR_EPILOGUE	\  (TARGET_FRW ? sparc_flat_epilogue_delay_slots () : 1)#define ELIGIBLE_FOR_EPILOGUE_DELAY(trial, slots_filled)	\  (TARGET_FRW ? sparc_flat_eligible_for_epilogue_delay (trial, slots_filled) \   : eligible_for_epilogue_delay (trial, slots_filled))/* Output assembler code for a block containing the constant parts   of a trampoline, leaving space for the variable parts.  *//* On 32 bit sparcs, the trampoline contains five instructions:     sethi #TOP_OF_FUNCTION,%g1     or #BOTTOM_OF_FUNCTION,%g1,%g1     sethi #TOP_OF_STATIC,%g2     jmp g1     or #BOTTOM_OF_STATIC,%g2,%g2  On 64 bit sparcs, the trampoline contains 4 insns and two pseudo-immediate  constants (plus some padding):     rd %pc,%g1     ldx[%g1+20],%g5     ldx[%g1+28],%g1     jmp %g1     nop     nop     .xword context     .xword function  */#define TRAMPOLINE_TEMPLATE(FILE) \do {									\  if (TARGET_V9)							\    {									\      fprintf (FILE, "\trd %%pc,%%g1\n");				\      fprintf (FILE, "\tldx [%%g1+24],%%g5\n");				\      fprintf (FILE, "\tldx [%%g1+32],%%g1\n");				\      fprintf (FILE, "\tjmp %%g1\n");					\      fprintf (FILE, "\tnop\n");					\      fprintf (FILE, "\tnop\n");					\      /* -mmedlow shouldn't generate .xwords, so don't use them at all */ \      fprintf (FILE, "\t.word 0,0,0,0\n");				\    }									\  else									\    {									\      ASM_OUTPUT_INT (FILE, gen_rtx (CONST_INT, VOIDmode, 0x00000000));	\      ASM_OUTPUT_INT (FILE, gen_rtx (CONST_INT, VOIDmode, 0x00000000));	\      ASM_OUTPUT_INT (FILE, gen_rtx (CONST_INT, VOIDmode, 0x00000000));	\      ASM_OUTPUT_INT (FILE, gen_rtx (CONST_INT, VOIDmode, 0x81C04000));	\      ASM_OUTPUT_INT (FILE, gen_rtx (CONST_INT, VOIDmode, 0x00000000));	\    }									\} while (0)/* Length in units of the trampoline for entering a nested function.  */#define TRAMPOLINE_SIZE (TARGET_V9 ? 40 : 20)/* Emit RTL insns to initialize the variable parts of a trampoline.   FNADDR is an RTX for the address of the function's pure code.   CXT is an RTX for the static chain value for the function.  */void sparc_initialize_trampoline ();void sparc64_initialize_trampoline ();#define INITIALIZE_TRAMPOLINE(TRAMP, FNADDR, CXT) \  do {								\    if (TARGET_V9)						\      sparc64_initialize_trampoline (TRAMP, FNADDR, CXT);	\    else							\      sparc_initialize_trampoline (TRAMP, FNADDR, CXT);		\  } while (0)/* Generate necessary RTL for __builtin_saveregs().   ARGLIST is the argument list; see expr.c.  */extern struct rtx_def *sparc_builtin_saveregs ();#define EXPAND_BUILTIN_SAVEREGS(ARGLIST) sparc_builtin_saveregs (ARGLIST)/* Generate RTL to flush the register windows so as to make arbitrary frames   available.  */#define SETUP_FRAME_ADDRESSES()		\  emit_insn (gen_flush_register_windows ())/* Given an rtx for the address of a frame,   return an rtx for the address of the word in the frame   that holds the dynamic chain--the previous frame's address.   ??? -mflat support? */#define DYNAMIC_CHAIN_ADDRESS(frame) \  gen_rtx (PLUS, Pmode, frame, gen_rtx (CONST_INT, VOIDmode, 14 * UNITS_PER_WORD))/* The return address isn't on the stack, it is in a register, so we can't   access it from the current frame pointer.  We can access it from the   previous frame pointer though by reading a value from the register window   save area.  */#define RETURN_ADDR_IN_PREVIOUS_FRAME/* This is the offset of the return address to the true next instruction to be   executed for normal void functions. */#define NORMAL_RETURN_ADDR_OFFSET (8)/* The current return address is 

⌨️ 快捷键说明

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