📄 cris.h
字号:
/* ASRQ, BTSTQ, LSRQ, LSLQ. */ \ (C) == 'K' ? (VALUE) >= 0 && (VALUE) <= 31 : \ /* A 16-bit signed number. */ \ (C) == 'L' ? (VALUE) >= -32768 && (VALUE) <= 32767 : \ /* The constant 0 for CLEAR. */ \ (C) == 'M' ? (VALUE) == 0 : \ /* A negative ADDQ or SUBQ. */ \ (C) == 'N' ? (VALUE) >= -63 && (VALUE) < 0 : \ /* Quickened ints, QI and HI. */ \ (C) == 'O' ? (VALUE) >= 0 && (VALUE) <= 65535 \ && ((VALUE) >= (65535-31) \ || ((VALUE) >= (255-31) \ && (VALUE) <= 255 )) : \ /* A 16-bit number signed *or* unsigned. */ \ (C) == 'P' ? (VALUE) >= -32768 && (VALUE) <= 65535 : \ 0)/* It is really simple to make up a 0.0; it is the same as int-0 in IEEE754. */#define CONST_DOUBLE_OK_FOR_LETTER_P(VALUE, C) \ ((C) == 'G' && ((VALUE) == CONST0_RTX (DFmode) \ || (VALUE) == CONST0_RTX (SFmode)))/* We need this on cris to distinguish delay-slottable addressing modes. */#define EXTRA_CONSTRAINT(X, C) \ ( \ /* Slottable address mode? */ \ (C) == 'Q' ? EXTRA_CONSTRAINT_Q (X) : \ /* Operand to BDAP or BIAP? */ \ (C) == 'R' ? EXTRA_CONSTRAINT_R (X) : \ /* A local PIC symbol? */ \ (C) == 'S' ? EXTRA_CONSTRAINT_S (X) : \ /* A three-address addressing-mode? */ \ (C) == 'T' ? EXTRA_CONSTRAINT_T (X) : \ /* A global PIC symbol? */ \ (C) == 'U' ? EXTRA_CONSTRAINT_U (X) : \ 0)#define EXTRA_CONSTRAINT_Q(X) \ ( \ /* Slottable addressing modes: \ A register? FIXME: Unnecessary. */ \ (BASE_P (X) && REGNO (X) != CRIS_PC_REGNUM) \ /* Indirect register: [reg]? */ \ || (GET_CODE (X) == MEM && BASE_P (XEXP (X, 0)) \ && REGNO (XEXP (X, 0)) != CRIS_PC_REGNUM) \ )#define EXTRA_CONSTRAINT_R(X) \ ( \ /* An operand to BDAP or BIAP: \ A BIAP; r.S? */ \ BIAP_INDEX_P (X) \ /* A [reg] or (int) [reg], maybe with post-increment. */ \ || BDAP_INDEX_P (X) \ || CONSTANT_INDEX_P (X) \ )#define EXTRA_CONSTRAINT_T(X) \ ( \ /* Memory three-address operand. All are indirect-memory: */ \ GET_CODE (X) == MEM \ && ((GET_CODE (XEXP (X, 0)) == MEM \ /* Double indirect: [[reg]] or [[reg+]]? */ \ && (BASE_OR_AUTOINCR_P (XEXP (XEXP (X, 0), 0)))) \ /* Just an explicit indirect reference: [const]? */ \ || CONSTANT_P (XEXP (X, 0)) \ /* Something that is indexed; [...+...]? */ \ || (GET_CODE (XEXP (X, 0)) == PLUS \ /* A BDAP constant: [reg+(8|16|32)bit offset]? */ \ && ((BASE_P (XEXP (XEXP (X, 0), 0)) \ && CONSTANT_INDEX_P (XEXP (XEXP (X, 0), 1))) \ /* Swap arguments to the above. FIXME: gcc-2.9x? */ \ || (BASE_P (XEXP (XEXP (X, 0), 1)) \ && CONSTANT_INDEX_P (XEXP (XEXP (X, 0), 0))) \ /* A BDAP register: [reg+[reg(+)].S]? */ \ || (BASE_P (XEXP (XEXP (X, 0), 0)) \ && BDAP_INDEX_P(XEXP(XEXP(X, 0), 1))) \ /* Same, but with swapped arguments. */ \ || (BASE_P (XEXP (XEXP (X, 0), 1)) \ && BDAP_INDEX_P (XEXP (XEXP (X, 0), 0))) \ /* A BIAP: [reg+reg.S]. */ \ || (BASE_P (XEXP (XEXP (X, 0), 0)) \ && BIAP_INDEX_P (XEXP (XEXP (X, 0), 1))) \ /* Same, but with swapped arguments. */ \ || (BASE_P (XEXP (XEXP (X, 0), 1)) \ && BIAP_INDEX_P (XEXP (XEXP (X, 0), 0)))))) \ )#define EXTRA_CONSTRAINT_S(X) \ (flag_pic && CONSTANT_P (X) && cris_gotless_symbol (X))#define EXTRA_CONSTRAINT_U(X) \ (flag_pic && CONSTANT_P (X) && cris_got_symbol (X))/* Node: Frame Layout */#define STACK_GROWS_DOWNWARD#define FRAME_GROWS_DOWNWARD/* It seems to be indicated in the code (at least 2.1) that this is better a constant, and best 0. */#define STARTING_FRAME_OFFSET 0#define FIRST_PARM_OFFSET(FNDECL) 0#define RETURN_ADDR_RTX(COUNT, FRAMEADDR) \ cris_return_addr_rtx (COUNT, FRAMEADDR)#define INCOMING_RETURN_ADDR_RTX gen_rtx (REG, Pmode, CRIS_SRP_REGNUM)/* FIXME: Any __builtin_eh_return callers must not return anything and there must not be collisions with incoming parameters. Luckily the number of __builtin_eh_return callers is limited. For now return parameter registers in reverse order and hope for the best. */#define EH_RETURN_DATA_REGNO(N) \ (IN_RANGE ((N), 0, 3) ? (CRIS_FIRST_ARG_REG + 3 - (N)) : INVALID_REGNUM)/* Store the stack adjustment in the structure-return-address register. */#define CRIS_STACKADJ_REG STRUCT_VALUE_REGNUM#define EH_RETURN_STACKADJ_RTX gen_rtx_REG (SImode, CRIS_STACKADJ_REG)#define EH_RETURN_HANDLER_RTX \ cris_return_addr_rtx (0, NULL)#define INIT_EXPANDERS cris_init_expanders ()/* FIXME: Move this to right node (it's not documented properly yet). */#define DWARF_FRAME_RETURN_COLUMN DWARF_FRAME_REGNUM (CRIS_SRP_REGNUM)/* FIXME: Move this to right node (it's not documented properly yet). FIXME: Check what alignment we can assume regarding TARGET_STACK_ALIGN and TARGET_ALIGN_BY_32. */#define DWARF_CIE_DATA_ALIGNMENT -1/* If we would ever need an exact mapping between canonical register number and dwarf frame register, we would either need to include all registers in the gcc decription (with some marked fixed of course), or an inverse mapping from dwarf register to gcc register. There is one need in dwarf2out.c:expand_builtin_init_dwarf_reg_sizes. Right now, I don't see that we need exact correspondence between DWARF *frame* registers and DBX_REGISTER_NUMBER, so map them onto GCC registers. */#define DWARF_FRAME_REGNUM(REG) (REG)/* Node: Stack Checking *//* (no definitions) FIXME: Check. *//* Node: Frame Registers */#define STACK_POINTER_REGNUM 14/* Register used for frame pointer. This is also the last of the saved registers, when a frame pointer is not used. */#define FRAME_POINTER_REGNUM 8/* Faked register, is always eliminated. We need it to eliminate allocating stack slots for the return address and the frame pointer. */#define ARG_POINTER_REGNUM 17#define STATIC_CHAIN_REGNUM 7/* Node: Elimination *//* Really only needed if the stack frame has variable length (alloca or variable sized local arguments (GNU C extension). */#define FRAME_POINTER_REQUIRED 0#define ELIMINABLE_REGS \ {{ARG_POINTER_REGNUM, STACK_POINTER_REGNUM}, \ {ARG_POINTER_REGNUM, FRAME_POINTER_REGNUM}, \ {FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM}}/* We need not worry about when the frame-pointer is required for other reasons. */#define CAN_ELIMINATE(FROM, TO) 1#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \ (OFFSET) = cris_initial_elimination_offset (FROM, TO)/* Node: Stack Arguments *//* Since many parameters take up one register each in any case, PROMOTE_PROTOTYPES would seem like a good idea, but measurements indicate that a combination using PROMOTE_MODE is better. */#define ACCUMULATE_OUTGOING_ARGS 1#define RETURN_POPS_ARGS(FUNDECL, FUNTYPE, STACKSIZE) 0/* Node: Register Arguments *//* The void_type_node is sent as a "closing" call. We have to stop it since it's invalid to FUNCTION_ARG_PASS_BY_REFERENCE (or was invalid at some time). */#define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \ ((CUM).regs < CRIS_MAX_ARGS_IN_REGS \ && (TYPE) != void_type_node \ && ! FUNCTION_ARG_PASS_BY_REFERENCE (CUM, MODE, TYPE, NAMED) \ ? gen_rtx (REG, MODE, (CRIS_FIRST_ARG_REG) + (CUM).regs) \ : NULL_RTX)/* The differences between this and the previous, is that this one checks that an argument is named, since incoming stdarg/varargs arguments are pushed onto the stack, and we don't have to check against the "closing" void_type_node TYPE parameter. */#define FUNCTION_INCOMING_ARG(CUM, MODE, TYPE, NAMED) \ (((NAMED) && (CUM).regs < CRIS_MAX_ARGS_IN_REGS \ && ! FUNCTION_ARG_PASS_BY_REFERENCE (CUM, MODE, TYPE, NAMED)) \ ? gen_rtx (REG, MODE, CRIS_FIRST_ARG_REG + (CUM).regs) \ : NULL_RTX)#define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) \ (((CUM).regs == (CRIS_MAX_ARGS_IN_REGS - 1) \ && !MUST_PASS_IN_STACK (MODE, TYPE) \ && CRIS_FUNCTION_ARG_SIZE (MODE, TYPE) > 4 \ && CRIS_FUNCTION_ARG_SIZE (MODE, TYPE) <= 8) \ ? 1 : 0)/* Structs may be passed by value, but they must not be more than 8 bytes long. If you tweak this, don't forget to adjust cris_expand_builtin_va_arg. */#define FUNCTION_ARG_PASS_BY_REFERENCE(CUM, MODE, TYPE, NAMED) \ (MUST_PASS_IN_STACK (MODE, TYPE) \ || CRIS_FUNCTION_ARG_SIZE (MODE, TYPE) > 8) \/* Contrary to what you'd believe, defining FUNCTION_ARG_CALLEE_COPIES seems like a (small total) loss, at least for gcc-2.7.2 compiling and running gcc-2.1 (small win in size, small loss running -- 100.1%), and similarly for size for products (.1 .. .3% bloat, sometimes win). Due to the empirical likeliness of making slower code, it is not defined. *//* This no longer *needs* to be a structure; but keeping it as such should not hurt (and hacking the ABI is simpler). */#define CUMULATIVE_ARGS struct cum_argsstruct cum_args {int regs;};/* The regs member is an integer, the number of arguments got into registers so far. */#define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, INDIRECT) \ ((CUM).regs = 0)#define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED) \ ((CUM).regs \ = (FUNCTION_ARG_PASS_BY_REFERENCE(CUM, MODE, TYPE, NAMED) \ ? (CRIS_MAX_ARGS_IN_REGS) + 1 \ : ((CUM).regs \ + (3 + (CRIS_FUNCTION_ARG_SIZE (MODE, TYPE))) / 4)))#define FUNCTION_ARG_REGNO_P(REGNO) \ ((REGNO) >= CRIS_FIRST_ARG_REG \ && (REGNO) < CRIS_FIRST_ARG_REG + (CRIS_MAX_ARGS_IN_REGS))/* Node: Scalar Return *//* Let's assume all functions return in r[CRIS_FIRST_ARG_REG] for the time being. */#define FUNCTION_VALUE(VALTYPE, FUNC) \ gen_rtx (REG, TYPE_MODE (VALTYPE), CRIS_FIRST_ARG_REG)#define LIBCALL_VALUE(MODE) gen_rtx (REG, MODE, CRIS_FIRST_ARG_REG)#define FUNCTION_VALUE_REGNO_P(N) ((N) == CRIS_FIRST_ARG_REG)/* Node: Aggregate Return */#if 0/* FIXME: Let's try this some time, so we return structures in registers. We would cast the result of int_size_in_bytes to unsigned, so we will get a huge number for "structures" of variable size (-1). */#define RETURN_IN_MEMORY(TYPE) \ ((unsigned) int_size_in_bytes (TYPE) > CRIS_MAX_ARGS_IN_REGS * UNITS_PER_WORD)#endif#define STRUCT_VALUE_REGNUM ((CRIS_FIRST_ARG_REG) - 1)/* Node: Caller Saves *//* (no definitions) *//* Node: Function entry *//* See cris.c for TARGET_ASM_FUNCTION_PROLOGUE and TARGET_ASM_FUNCTION_EPILOGUE. *//* If the epilogue uses the "ret" insn, we need to fill the delay slot. */#define DELAY_SLOTS_FOR_EPILOGUE cris_delay_slots_for_epilogue ()#define ELIGIBLE_FOR_EPILOGUE_DELAY(INSN, N) \ cris_eligible_for_epilogue_delay (INSN)/* Node: Profiling */#define FUNCTION_PROFILER(FILE, LABELNO) \ error ("no FUNCTION_PROFILER for CRIS")/* FIXME: Some of the undefined macros might be mandatory. If so, fix documentation. *//* Node: Varargs *//* We save the register number of the first anonymous argument in first_vararg_reg, and take care of this in the function prologue. This behavior is used by at least one more port (the ARM?), but may be unsafe when compiling nested functions. (With varargs? Hairy.) Note that nested-functions is a GNU C extension. FIXME: We can actually put the size in PRETEND and deduce the number of registers from it in the prologue and epilogue. */#define SETUP_INCOMING_VARARGS(ARGSSF, MODE, TYPE, PRETEND, SECOND) \ do \ { \ if ((ARGSSF).regs < (CRIS_MAX_ARGS_IN_REGS)) \ (PRETEND) = ((CRIS_MAX_ARGS_IN_REGS) - (ARGSSF).regs) * 4; \ if (TARGET_PDEBUG) \ { \ fprintf (asm_out_file, \ "\n; VA:: ANSI: %d args before, anon @ #%d, %dtime\n", \ (ARGSSF).regs, PRETEND, SECOND); \ } \ } \ while (0)/* FIXME: This and other EXPAND_BUILTIN_VA_... target macros are not documented, although used by several targets. */#define EXPAND_BUILTIN_VA_ARG(VALIST, TYPE) \ cris_expand_builtin_va_arg (VALIST, TYPE)/* Node: Trampolines *//* This looks too complicated, and it is. I assigned r7 to be the static chain register, but it is call-saved, so we have to save it, and come back to restore it after the call, so we have to save srp... Anyway, trampolines are rare enough that we can cope with this somewhat lack of elegance. (Do not be tempted to "straighten up" whitespace in the asms; the assembler #NO_APP state mandates strict spacing). */#define TRAMPOLINE_TEMPLATE(FILE) \ do \ { \ fprintf (FILE, "\tmove.d $%s,[$pc+20]\n", \ reg_names[STATIC_CHAIN_REGNUM]); \ fprintf (FILE, "\tmove $srp,[$pc+22]\n"); \ fprintf (FILE, "\tmove.d 0,$%s\n", \ reg_names[STATIC_CHAIN_REGNUM]); \ fprintf (FILE, "\tjsr 0\n"); \ fprintf (FILE, "\tmove.d 0,$%s\n", \ reg_names[STATIC_CHAIN_REGNUM]); \ fprintf (FILE, "\tjump 0\n"); \ } \ while (0)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -