📄 m68k.h
字号:
: (GET_CODE (X) == CONST_DOUBLE \ && GET_MODE_CLASS (GET_MODE (X)) == MODE_FLOAT) \ ? (TARGET_68881 && (CLASS == FP_REGS || CLASS == DATA_OR_FP_REGS) \ ? FP_REGS : NO_REGS) \ : (TARGET_PCREL \ && (GET_CODE (X) == SYMBOL_REF || GET_CODE (X) == CONST \ || GET_CODE (X) == LABEL_REF)) \ ? ADDR_REGS \ : (CLASS))/* Force QImode output reloads from subregs to be allocated to data regs, since QImode stores from address regs are not supported. We make the assumption that if the class is not ADDR_REGS, then it must be a superset of DATA_REGS. */#define LIMIT_RELOAD_CLASS(MODE, CLASS) \ (((MODE) == QImode && (CLASS) != ADDR_REGS) \ ? DATA_REGS \ : (CLASS))/* On the m68k, this is the size of MODE in words, except in the FP regs, where a single reg is always enough. */#define CLASS_MAX_NREGS(CLASS, MODE) \ ((CLASS) == FP_REGS ? 1 \ : ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD))/* Moves between fp regs and other regs are two insns. */#define REGISTER_MOVE_COST(MODE, CLASS1, CLASS2) \ (((CLASS1) == FP_REGS && (CLASS2) != FP_REGS) \ || ((CLASS2) == FP_REGS && (CLASS1) != FP_REGS) \ ? 4 : 2)/* Stack layout; function entry, exit and calling. */#define STACK_GROWS_DOWNWARD#define FRAME_GROWS_DOWNWARD#define STARTING_FRAME_OFFSET 0/* On the 680x0, sp@- in a byte insn really pushes a word. On the ColdFire, sp@- in a byte insn pushes just a byte. */#define PUSH_ROUNDING(BYTES) (TARGET_COLDFIRE ? BYTES : ((BYTES) + 1) & ~1)#define FIRST_PARM_OFFSET(FNDECL) 8/* On the 68000, the RTS insn cannot pop anything. On the 68010, the RTD insn may be used to pop them if the number of args is fixed, but if the number is variable then the caller must pop them all. RTD can't be used for library calls now because the library is compiled with the Unix compiler. Use of RTD is a selectable option, since it is incompatible with standard Unix calling sequences. If the option is not selected, the caller must always pop the args. */#define RETURN_POPS_ARGS(FUNDECL,FUNTYPE,SIZE) \ ((TARGET_RTD && (!(FUNDECL) || TREE_CODE (FUNDECL) != IDENTIFIER_NODE) \ && (TYPE_ARG_TYPES (FUNTYPE) == 0 \ || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (FUNTYPE))) \ == void_type_node))) \ ? (SIZE) : 0)/* On the m68k the return value is always in D0. */#define FUNCTION_VALUE(VALTYPE, FUNC) \ gen_rtx_REG (TYPE_MODE (VALTYPE), 0)/* On the m68k the return value is always in D0. */#define LIBCALL_VALUE(MODE) gen_rtx_REG (MODE, 0)/* On the m68k, D0 is the only register used. */#define FUNCTION_VALUE_REGNO_P(N) ((N) == 0)/* Define this to be true when FUNCTION_VALUE_REGNO_P is true for more than one register. XXX This macro is m68k specific and used only for m68kemb.h. */#define NEEDS_UNTYPED_CALL 0#define PCC_STATIC_STRUCT_RETURN/* On the m68k, all arguments are usually pushed on the stack. */#define FUNCTION_ARG_REGNO_P(N) 0/* On the m68k, this is a single integer, which is a number of bytes of arguments scanned so far. */#define CUMULATIVE_ARGS int/* On the m68k, the offset starts at 0. */#define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, INDIRECT, N_NAMED_ARGS) \ ((CUM) = 0)#define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED) \ ((CUM) += ((MODE) != BLKmode \ ? (GET_MODE_SIZE (MODE) + 3) & ~3 \ : (int_size_in_bytes (TYPE) + 3) & ~3))/* On the m68k all args are always pushed. */#define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) 0#define FUNCTION_PROFILER(FILE, LABELNO) \ asm_fprintf (FILE, "\tlea %LLP%d,%Ra0\n\tjsr mcount\n", (LABELNO))#define EXIT_IGNORE_STACK 1/* Determine if the epilogue should be output as RTL. You should override this if you define FUNCTION_EXTRA_EPILOGUE. XXX This macro is m68k-specific and only used in m68k.md. */#define USE_RETURN_INSN use_return_insn ()/* Output assembler code for a block containing the constant parts of a trampoline, leaving space for the variable parts. On the m68k, the trampoline looks like this: movl #STATIC,a0 jmp FUNCTION WARNING: Targets that may run on 68040+ cpus must arrange for the instruction cache to be flushed. Previous incarnations of the m68k trampoline code attempted to get around this by either using an out-of-line transfer function or pc-relative data, but the fact remains that the code to jump to the transfer function or the code to load the pc-relative data needs to be flushed just as much as the "variable" portion of the trampoline. Recognizing that a cache flush is going to be required anyway, dispense with such notions and build a smaller trampoline. Since more instructions are required to move a template into place than to create it on the spot, don't use a template. */#define TRAMPOLINE_SIZE 12#define TRAMPOLINE_ALIGNMENT 16/* Targets redefine this to invoke code to either flush the cache, or enable stack execution (or both). */#ifndef FINALIZE_TRAMPOLINE#define FINALIZE_TRAMPOLINE(TRAMP)#endif/* We generate a two-instructions program at address TRAMP : movea.l &CXT,%a0 jmp FNADDR */#define INITIALIZE_TRAMPOLINE(TRAMP, FNADDR, CXT) \{ \ emit_move_insn (gen_rtx_MEM (HImode, TRAMP), GEN_INT(0x207C)); \ emit_move_insn (gen_rtx_MEM (SImode, plus_constant (TRAMP, 2)), CXT); \ emit_move_insn (gen_rtx_MEM (HImode, plus_constant (TRAMP, 6)), \ GEN_INT(0x4EF9)); \ emit_move_insn (gen_rtx_MEM (SImode, plus_constant (TRAMP, 8)), FNADDR); \ FINALIZE_TRAMPOLINE(TRAMP); \}/* This is the library routine that is used to transfer control from the trampoline to the actual nested function. It is defined for backward compatibility, for linking with object code that used the old trampoline definition. A colon is used with no explicit operands to cause the template string to be scanned for %-constructs. The function name __transfer_from_trampoline is not actually used. The function definition just permits use of "asm with operands" (though the operand list is empty). */#define TRANSFER_FROM_TRAMPOLINE \void \__transfer_from_trampoline () \{ \ register char *a0 asm ("%a0"); \ asm (GLOBAL_ASM_OP "___trampoline"); \ asm ("___trampoline:"); \ asm volatile ("move%.l %0,%@" : : "m" (a0[22])); \ asm volatile ("move%.l %1,%0" : "=a" (a0) : "m" (a0[18])); \ asm ("rts":); \}/* There are two registers that can always be eliminated on the m68k. The frame pointer and the arg pointer can be replaced by either the hard frame pointer or to the stack pointer, depending upon the circumstances. The hard frame pointer is not used before reload and so it is not eligible for elimination. */#define ELIMINABLE_REGS \{{ ARG_POINTER_REGNUM, STACK_POINTER_REGNUM }, \ { ARG_POINTER_REGNUM, FRAME_POINTER_REGNUM }, \ { FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM }}#define CAN_ELIMINATE(FROM, TO) \ ((TO) == STACK_POINTER_REGNUM ? ! frame_pointer_needed : 1)#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \ (OFFSET) = m68k_initial_elimination_offset(FROM, TO)/* Addressing modes, and classification of registers for them. */#define HAVE_POST_INCREMENT 1#define HAVE_PRE_DECREMENT 1/* Macros to check register numbers against specific register classes. */#define REGNO_OK_FOR_INDEX_P(REGNO) \((REGNO) < 16 || (unsigned) reg_renumber[REGNO] < 16)#define REGNO_OK_FOR_BASE_P(REGNO) \(((REGNO) ^ 010) < 8 || (unsigned) (reg_renumber[REGNO] ^ 010) < 8)#define REGNO_OK_FOR_DATA_P(REGNO) \((REGNO) < 8 || (unsigned) reg_renumber[REGNO] < 8)#define REGNO_OK_FOR_FP_P(REGNO) \(((REGNO) ^ 020) < 8 || (unsigned) (reg_renumber[REGNO] ^ 020) < 8)/* Now macros that check whether X is a register and also, strictly, whether it is in a specified class. These macros are specific to the m68k, and may be used only in code for printing assembler insns and in conditions for define_optimization. *//* 1 if X is a data register. */#define DATA_REG_P(X) (REG_P (X) && REGNO_OK_FOR_DATA_P (REGNO (X)))/* 1 if X is an fp register. */#define FP_REG_P(X) (REG_P (X) && REGNO_OK_FOR_FP_P (REGNO (X)))/* 1 if X is an address register */#define ADDRESS_REG_P(X) (REG_P (X) && REGNO_OK_FOR_BASE_P (REGNO (X)))#define MAX_REGS_PER_ADDRESS 2#define CONSTANT_ADDRESS_P(X) \ (GET_CODE (X) == LABEL_REF || GET_CODE (X) == SYMBOL_REF \ || GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST \ || GET_CODE (X) == HIGH)/* Nonzero if the constant value X is a legitimate general operand. It is given that X satisfies CONSTANT_P or is a CONST_DOUBLE. */#define LEGITIMATE_CONSTANT_P(X) (GET_MODE (X) != XFmode)#ifndef REG_OK_STRICT#define PCREL_GENERAL_OPERAND_OK 0#else#define PCREL_GENERAL_OPERAND_OK (TARGET_PCREL)#endif#define LEGITIMATE_PIC_OPERAND_P(X) \ (! symbolic_operand (X, VOIDmode) \ || (GET_CODE (X) == SYMBOL_REF && SYMBOL_REF_FLAG (X)) \ || PCREL_GENERAL_OPERAND_OK)#ifndef REG_OK_STRICT/* Nonzero if X is a hard reg that can be used as an index or if it is a pseudo reg. */#define REG_OK_FOR_INDEX_P(X) ((REGNO (X) ^ 020) >= 8)/* Nonzero if X is a hard reg that can be used as a base reg or if it is a pseudo reg. */#define REG_OK_FOR_BASE_P(X) ((REGNO (X) & ~027) != 0)#else/* Nonzero if X is a hard reg that can be used as an index. */#define REG_OK_FOR_INDEX_P(X) REGNO_OK_FOR_INDEX_P (REGNO (X))/* Nonzero if X is a hard reg that can be used as a base reg. */#define REG_OK_FOR_BASE_P(X) REGNO_OK_FOR_BASE_P (REGNO (X))#endif/* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression that is a valid memory address for an instruction. The MODE argument is the machine mode for the MEM expression that wants to use this address. When generating PIC, an address involving a SYMBOL_REF is legitimate if and only if it is the sum of pic_offset_table_rtx and the SYMBOL_REF. We use LEGITIMATE_PIC_OPERAND_P to throw out the illegitimate addresses, and we explicitly check for the sum of pic_offset_table_rtx and a SYMBOL_REF. Likewise for a LABEL_REF when generating PIC. The other macros defined here are used only in GO_IF_LEGITIMATE_ADDRESS. *//* Allow SUBREG everywhere we allow REG. This results in better code. It also makes function inlining work when inline functions are called with arguments that are SUBREGs. */#define LEGITIMATE_BASE_REG_P(X) \ ((GET_CODE (X) == REG && REG_OK_FOR_BASE_P (X)) \ || (GET_CODE (X) == SUBREG \ && GET_CODE (SUBREG_REG (X)) == REG \ && REG_OK_FOR_BASE_P (SUBREG_REG (X))))#define INDIRECTABLE_1_ADDRESS_P(X) \ ((CONSTANT_ADDRESS_P (X) && (!flag_pic || LEGITIMATE_PIC_OPERAND_P (X))) \ || LEGITIMATE_BASE_REG_P (X) \ || ((GET_CODE (X) == PRE_DEC || GET_CODE (X) == POST_INC) \ && LEGITIMATE_BASE_REG_P (XEXP (X, 0))) \ || (GET_CODE (X) == PLUS \ && LEGITIMATE_BASE_REG_P (XEXP (X, 0)) \ && GET_CODE (XEXP (X, 1)) == CONST_INT \ && (TARGET_68020 \ || ((unsigned) INTVAL (XEXP (X, 1)) + 0x8000) < 0x10000)) \ || (GET_CODE (X) == PLUS && XEXP (X, 0) == pic_offset_table_rtx \ && flag_pic && GET_CODE (XEXP (X, 1)) == SYMBOL_REF) \ || (GET_CODE (X) == PLUS && XEXP (X, 0) == pic_offset_table_rtx \ && flag_pic && GET_CODE (XEXP (X, 1)) == LABEL_REF))#define GO_IF_NONINDEXED_ADDRESS(X, ADDR) \{ if (INDIRECTABLE_1_ADDRESS_P (X)) goto ADDR; }/* Only labels on dispatch tables are valid for indexing from. */#define GO_IF_INDEXABLE_BASE(X, ADDR) \{ rtx temp; \ if (GET_CODE (X) == LABEL_REF \ && (temp = next_nonnote_insn (XEXP (X, 0))) != 0 \ && GET_CODE (temp) == JUMP_INSN \ && (GET_CODE (PATTERN (temp)) == ADDR_VEC \ || GET_CODE (PATTERN (temp)) == ADDR_DIFF_VEC)) \ goto ADDR; \ if (LEGITIMATE_BASE_REG_P (X)) goto ADDR; }#define GO_IF_INDEXING(X, ADDR) \{ if (GET_CODE (X) == PLUS && LEGITIMATE_INDEX_P (XEXP (X, 0))) \ { GO_IF_INDEXABLE_BASE (XEXP (X, 1), ADDR); } \ if (GET_CODE (X) == PLUS && LEGITIMATE_INDEX_P (XEXP (X, 1))) \ { GO_IF_INDEXABLE_BASE (XEXP (X, 0), ADDR); } }#define GO_IF_INDEXED_ADDRESS(X, ADDR) \{ GO_IF_INDEXING (X, ADDR); \ if (GET_CODE (X) == PLUS) \
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -