📄 mmix.h
字号:
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, 1 \ }#define CONDITIONAL_REGISTER_USAGE mmix_conditional_register_usage ()/* No INCOMING_REGNO or OUTGOING_REGNO, since those macros are not usable for MMIX: it doesn't have a fixed register window size. FIXME: Perhaps we should say something about $0..$15 may sometimes be the incoming $16..$31. Those macros need better documentation; it looks like they're just bogus and that FUNCTION_INCOMING_ARG_REGNO_P and FUNCTION_OUTGOING_VALUE should be used where they're used. For the moment, do nothing; things seem to work anyway. *//* Defining LOCAL_REGNO is necessary in presence of prologue/epilogue, else GCC will be confused that those registers aren't saved and restored. */#define LOCAL_REGNO(REGNO) mmix_local_regno (REGNO)/* Node: Allocation Order *//* We should allocate registers from 0 to 31 by increasing number, because I think that's what people expect. Beyond that, just use call-clobbered global registers first, then call-clobbered special registers. Last, the fixed registers. */#define MMIX_MMIXWARE_ABI_REG_ALLOC_ORDER \ { 0, 1, 2, 3, 4, 5, 6, 7, \ 8, 9, 10, 11, 12, 13, 14, 15, \ 16, 17, 18, 19, 20, 21, 22, 23, \ 24, 25, 26, 27, 28, 29, 30, 31, \ \ 252, 251, 250, 249, 248, 247, \ \ 253, \ \ 258, 260, 259, \ \ 32, 33, 34, 35, 36, 37, 38, 39, \ 40, 41, 42, 43, 44, 45, 46, 47, \ 48, 49, 50, 51, 52, 53, 54, 55, \ 56, 57, 58, 59, 60, 61, 62, 63, \ 64, 65, 66, 67, 68, 69, 70, 71, \ 72, 73, 74, 75, 76, 77, 78, 79, \ 80, 81, 82, 83, 84, 85, 86, 87, \ 88, 89, 90, 91, 92, 93, 94, 95, \ 96, 97, 98, 99, 100, 101, 102, 103, \ 104, 105, 106, 107, 108, 109, 110, 111, \ 112, 113, 114, 115, 116, 117, 118, 119, \ 120, 121, 122, 123, 124, 125, 126, 127, \ 128, 129, 130, 131, 132, 133, 134, 135, \ 136, 137, 138, 139, 140, 141, 142, 143, \ 144, 145, 146, 147, 148, 149, 150, 151, \ 152, 153, 154, 155, 156, 157, 158, 159, \ 160, 161, 162, 163, 164, 165, 166, 167, \ 168, 169, 170, 171, 172, 173, 174, 175, \ 176, 177, 178, 179, 180, 181, 182, 183, \ 184, 185, 186, 187, 188, 189, 190, 191, \ 192, 193, 194, 195, 196, 197, 198, 199, \ 200, 201, 202, 203, 204, 205, 206, 207, \ 208, 209, 210, 211, 212, 213, 214, 215, \ 216, 217, 218, 219, 220, 221, 222, 223, \ 224, 225, 226, 227, 228, 229, 230, 231, \ 232, 233, 234, 235, 236, 237, 238, 239, \ 240, 241, 242, 243, 244, 245, 246, \ \ 254, 255, 256, 257, 261, 262 \ }/* As a convenience, we put this nearby, for ease of comparison. First, call-clobbered registers in reverse order of assignment as parameters (also the top ones; not because they're parameters, but for continuity). Second, saved registers that go on the register-stack. Third, special registers rH, rR and rJ. They should not normally be allocated, but since they're call-clobbered, it is cheaper to use one of them than using a call-saved register for a call-clobbered use, assuming it is referenced a very limited number of times. Other global and fixed registers come next; they are never allocated. */#define MMIX_GNU_ABI_REG_ALLOC_ORDER \ { 252, 251, 250, 249, 248, 247, 246, \ 245, 244, 243, 242, 241, 240, 239, 238, \ 237, 236, 235, 234, 233, 232, 231, \ \ 0, 1, 2, 3, 4, 5, 6, 7, \ 8, 9, 10, 11, 12, 13, 14, 15, \ 16, 17, 18, 19, 20, 21, 22, 23, \ 24, 25, 26, 27, 28, 29, 30, 31, \ \ 253, \ \ 258, 260, 259, \ \ 32, 33, 34, 35, 36, 37, 38, 39, \ 40, 41, 42, 43, 44, 45, 46, 47, \ 48, 49, 50, 51, 52, 53, 54, 55, \ 56, 57, 58, 59, 60, 61, 62, 63, \ 64, 65, 66, 67, 68, 69, 70, 71, \ 72, 73, 74, 75, 76, 77, 78, 79, \ 80, 81, 82, 83, 84, 85, 86, 87, \ 88, 89, 90, 91, 92, 93, 94, 95, \ 96, 97, 98, 99, 100, 101, 102, 103, \ 104, 105, 106, 107, 108, 109, 110, 111, \ 112, 113, 114, 115, 116, 117, 118, 119, \ 120, 121, 122, 123, 124, 125, 126, 127, \ 128, 129, 130, 131, 132, 133, 134, 135, \ 136, 137, 138, 139, 140, 141, 142, 143, \ 144, 145, 146, 147, 148, 149, 150, 151, \ 152, 153, 154, 155, 156, 157, 158, 159, \ 160, 161, 162, 163, 164, 165, 166, 167, \ 168, 169, 170, 171, 172, 173, 174, 175, \ 176, 177, 178, 179, 180, 181, 182, 183, \ 184, 185, 186, 187, 188, 189, 190, 191, \ 192, 193, 194, 195, 196, 197, 198, 199, \ 200, 201, 202, 203, 204, 205, 206, 207, \ 208, 209, 210, 211, 212, 213, 214, 215, \ 216, 217, 218, 219, 220, 221, 222, 223, \ 224, 225, 226, 227, 228, 229, 230, \ \ 254, 255, 256, 257, 261, 262 \ }/* The default one. */#define REG_ALLOC_ORDER MMIX_MMIXWARE_ABI_REG_ALLOC_ORDER/* Node: Values in Registers */#define HARD_REGNO_NREGS(REGNO, MODE) \ ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) \ / UNITS_PER_WORD)#define HARD_REGNO_MODE_OK(REGNO, MODE) 1/* Note that no register can really be accessed in single-float mode, so we *can* say 1 here. FIXME: Will TRT happen for single-float, or do we have to punt to libgcc1.asm? */#define MODES_TIEABLE_P(MODE1, MODE2) 1/* Node: Leaf Functions *//* (empty) *//* Node: Register Classes */enum reg_class { NO_REGS, GENERAL_REGS, REMAINDER_REG, HIMULT_REG, SYSTEM_REGS, ALL_REGS, LIM_REG_CLASSES };#define N_REG_CLASSES (int) LIM_REG_CLASSES#define REG_CLASS_NAMES \ {"NO_REGS", "GENERAL_REGS", "REMAINDER_REG", "HIMULT_REG", \ "SYSTEM_REGS", "ALL_REGS"}/* Note that the contents of each item is always 32 bits. */#define REG_CLASS_CONTENTS \ {{0, 0, 0, 0, 0, 0, 0, 0, 0}, \ {~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, 0x20}, \ {0, 0, 0, 0, 0, 0, 0, 0, 0x10}, \ {0, 0, 0, 0, 0, 0, 0, 0, 4}, \ {0, 0, 0, 0, 0, 0, 0, 0, 0x7f}, \ {~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, 0x7f}}#define REGNO_REG_CLASS(REGNO) \ ((REGNO) <= MMIX_LAST_GENERAL_REGISTER \ || (REGNO) == MMIX_ARG_POINTER_REGNUM \ ? GENERAL_REGS \ : (REGNO) == MMIX_REMAINDER_REGNUM ? REMAINDER_REG \ : (REGNO) == MMIX_HIMULT_REGNUM ? HIMULT_REG : SYSTEM_REGS)#define BASE_REG_CLASS GENERAL_REGS#define INDEX_REG_CLASS GENERAL_REGS#define REG_CLASS_FROM_LETTER(CHAR) \ ((CHAR) == 'x' ? SYSTEM_REGS \ : (CHAR) == 'y' ? REMAINDER_REG \ : (CHAR) == 'z' ? HIMULT_REG : NO_REGS)#define REGNO_OK_FOR_BASE_P(REGNO) \ ((REGNO) <= MMIX_LAST_GENERAL_REGISTER \ || (REGNO) == MMIX_ARG_POINTER_REGNUM \ || (reg_renumber[REGNO] > 0 \ && reg_renumber[REGNO] <= MMIX_LAST_GENERAL_REGISTER))#define REGNO_OK_FOR_INDEX_P(REGNO) REGNO_OK_FOR_BASE_P (REGNO)#define PREFERRED_RELOAD_CLASS(X, CLASS) \ mmix_preferred_reload_class (X, CLASS)#define PREFERRED_OUTPUT_RELOAD_CLASS(X, CLASS) \ mmix_preferred_output_reload_class (X, CLASS)#define SECONDARY_INPUT_RELOAD_CLASS(CLASS, MODE, X) \ mmix_secondary_reload_class (CLASS, MODE, X, 1)#define SECONDARY_OUTPUT_RELOAD_CLASS(CLASS, MODE, X) \ mmix_secondary_reload_class (CLASS, MODE, X, 0)#define CLASS_MAX_NREGS(CLASS, MODE) HARD_REGNO_NREGS (CLASS, MODE)#define CONST_OK_FOR_LETTER_P(VALUE, C) \ mmix_const_ok_for_letter_p (VALUE, C)#define EXTRA_CONSTRAINT(VALUE, C) \ mmix_extra_constraint (VALUE, C, MMIX_REG_OK_STRICT)/* Do we need anything serious here? Yes, any FLOT constant. */#define CONST_DOUBLE_OK_FOR_LETTER_P(VALUE, C) \ mmix_const_double_ok_for_letter_p (VALUE, C)/* Node: Frame Layout */#define STACK_GROWS_DOWNWARD#define FRAME_GROWS_DOWNWARD#define STARTING_FRAME_OFFSET \ mmix_starting_frame_offset ()#define FIRST_PARM_OFFSET(FUNDECL) 0#define DYNAMIC_CHAIN_ADDRESS(FRAMEADDR) \ mmix_dynamic_chain_address (FRAMEADDR)/* FIXME: It seems RETURN_ADDR_OFFSET is undocumented. */#define SETUP_FRAME_ADDRESSES() \ mmix_setup_frame_addresses ()#define RETURN_ADDR_RTX(COUNT, FRAME) \ mmix_return_addr_rtx (COUNT, FRAME)/* It's in rJ before we store it somewhere. */#define INCOMING_RETURN_ADDR_RTX \ gen_rtx_REG (Pmode, MMIX_INCOMING_RETURN_ADDRESS_REGNUM)/* FIXME: This does not seem properly documented or cross-indexed. Nowhere except in the code does it say it *has* to be in the range 0..255, or else it will be truncated. That goes for the default too. */#define DWARF_FRAME_RETURN_COLUMN \ DWARF_FRAME_REGNUM (MMIX_INCOMING_RETURN_ADDRESS_REGNUM)/* No return address is stored there. */#define INCOMING_FRAME_SP_OFFSET 0/* Node: Stack Checking *//* (empty) *//* Node: Exception Handling */#define EH_RETURN_DATA_REGNO(N) \ mmix_eh_return_data_regno (N)#define EH_RETURN_STACKADJ_RTX \ mmix_eh_return_stackadj_rtx ()#define EH_RETURN_HANDLER_RTX \ mmix_eh_return_handler_rtx ()#define ASM_PREFERRED_EH_DATA_FORMAT(CODE, GLOBAL) \ mmix_asm_preferred_eh_data_format (CODE, GLOBAL)/* Node: Frame Registers */#define STACK_POINTER_REGNUM MMIX_STACK_POINTER_REGNUM/* Perhaps we can use HARD_FRAME_POINTER_REGNUM and decide later on what register we want to use. */#define FRAME_POINTER_REGNUM MMIX_FRAME_POINTER_REGNUM#define ARG_POINTER_REGNUM MMIX_ARG_POINTER_REGNUM#define STATIC_CHAIN_REGNUM MMIX_STATIC_CHAIN_REGNUM/* Node: Elimination *//* FIXME: Is this requirement built-in? Anyway, we should try to get rid of it; we can deduce the value. */#define FRAME_POINTER_REQUIRED (nonlocal_goto_stack_level != NULL_RTX)/* The frame-pointer is stored in a location that either counts to the offset of incoming parameters, or that counts to the offset of the frame, so we can't use a single offset. We therefore eliminate those two separately. */#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; GCC takes care of those cases. */#define CAN_ELIMINATE(FROM, TO) 1#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \ (OFFSET) = mmix_initial_elimination_offset (FROM, TO)/* Node: Stack Arguments */#define ACCUMULATE_OUTGOING_ARGS 1#define RETURN_POPS_ARGS(FUNDECL, FUNTYPE, STACKSIZE) 0/* Node: Register Arguments */#define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \ mmix_function_arg (&(CUM), MODE, TYPE, NAMED, 0)#define FUNCTION_INCOMING_ARG(CUM, MODE, TYPE, NAMED) \ mmix_function_arg (&(CUM), MODE, TYPE, NAMED, 1)#define FUNCTION_ARG_PASS_BY_REFERENCE(CUM, MODE, TYPE, NAMED) \ mmix_function_arg_pass_by_reference (&(CUM), MODE, TYPE, NAMED)/* This *sounds* good, but does not seem to be implemented correctly to be a win; at least it wasn't in 2.7.2. FIXME: Check and perhaps replace with a big comment. The definition needs to match or be a subset of FUNCTION_ARG_PASS_BY_REFERENCE, since not all callers check that before usage. Watch lots of C++ test-cases fail if set to 1, for example g++.dg/init/byval1.C. */#define FUNCTION_ARG_CALLEE_COPIES(CUM, MODE, TYPE, NAMED) \ mmix_function_arg_pass_by_reference (&(CUM), MODE, TYPE, NAMED)typedef struct { int regs; int lib; } CUMULATIVE_ARGS;#define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, INDIRECT) \ ((CUM).regs = 0, (CUM).lib = ((LIBNAME) != 0))#define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED) \ ((CUM).regs \ = ((MUST_PASS_IN_STACK (MODE, TYPE)) \ || (MMIX_FUNCTION_ARG_SIZE (MODE, TYPE) > 8 \ && !TARGET_LIBFUNC && !(CUM).lib)) \ ? (MMIX_MAX_ARGS_IN_REGS) + 1 \ : (CUM).regs + (7 + (MMIX_FUNCTION_ARG_SIZE (MODE, TYPE))) / 8)#define FUNCTION_ARG_REGNO_P(REGNO) \ mmix_function_arg_regno_p (REGNO, 0)#define FUNCTION_INCOMING_ARG_REGNO_P(REGNO) \ mmix_function_arg_regno_p (REGNO, 1)/* Node: Register Arguments */#define FUNCTION_VALUE(VALTYPE, FUNC) \ gen_rtx_REG (TYPE_MODE (VALTYPE), MMIX_RETURN_VALUE_REGNUM)/* This needs to take care of the register hole for complex return values. */#define FUNCTION_OUTGOING_VALUE(VALTYPE, FUNC) \ mmix_function_outgoing_value (VALTYPE, FUNC)#define LIBCALL_VALUE(MODE) \ gen_rtx_REG (MODE, MMIX_RETURN_VALUE_REGNUM)#define FUNCTION_VALUE_REGNO_P(REGNO) \ mmix_function_value_regno_p (REGNO)/* Node: Aggregate Return */#define STRUCT_VALUE_REGNUM MMIX_STRUCT_VALUE_REGNUM/* Node: Caller Saves *//* (empty) *//* Node: Function Entry *//* See mmix.c for TARGET_ASM_FUNCTION_PROLOGUE and TARGET_ASM_FUNCTION_EPILOGUE. *//* We need to say that the epilogue uses the return address, so the initial-value machinery restores it. FIXME: Some targets conditionalize on "reload_completed &&". Investigate difference.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -