📄 iq2000.h
字号:
#define CAN_ELIMINATE(FROM, TO) \ (((FROM) == RETURN_ADDRESS_POINTER_REGNUM && (! leaf_function_p () \ || (TO == GP_REG_FIRST + 31 && leaf_function_p))) \ || ((FROM) != RETURN_ADDRESS_POINTER_REGNUM \ && ((TO) == HARD_FRAME_POINTER_REGNUM \ || ((TO) == STACK_POINTER_REGNUM && ! frame_pointer_needed))))#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \ (OFFSET) = iq2000_initial_elimination_offset ((FROM), (TO))/* Passing Function Arguments on the Stack. *//* #define PUSH_ROUNDING(BYTES) 0 */#define ACCUMULATE_OUTGOING_ARGS 1#define REG_PARM_STACK_SPACE(FNDECL) 0#define OUTGOING_REG_PARM_STACK_SPACE#define RETURN_POPS_ARGS(FUNDECL,FUNTYPE,SIZE) 0/* Function Arguments in Registers. */#define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \ function_arg (& CUM, MODE, TYPE, NAMED)#define MAX_ARGS_IN_REGISTERS 8typedef struct iq2000_args{ int gp_reg_found; /* Whether a gp register was found yet. */ unsigned int arg_number; /* Argument number. */ unsigned int arg_words; /* # total words the arguments take. */ unsigned int fp_arg_words; /* # words for FP args (IQ2000_EABI only). */ int last_arg_fp; /* Nonzero if last arg was FP (EABI only). */ int fp_code; /* Mode of FP arguments. */ unsigned int num_adjusts; /* Number of adjustments made. */ /* Adjustments made to args pass in regs. */ struct rtx_def * adjust[MAX_ARGS_IN_REGISTERS * 2];} CUMULATIVE_ARGS;/* Initialize a variable CUM of type CUMULATIVE_ARGS for a call to a function whose data type is FNTYPE. For a library call, FNTYPE is 0. */#define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, INDIRECT, N_NAMED_ARGS) \ init_cumulative_args (& CUM, FNTYPE, LIBNAME) \#define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED) \ function_arg_advance (& CUM, MODE, TYPE, NAMED)#define FUNCTION_ARG_PADDING(MODE, TYPE) \ (! BYTES_BIG_ENDIAN \ ? upward \ : (((MODE) == BLKmode \ ? ((TYPE) && TREE_CODE (TYPE_SIZE (TYPE)) == INTEGER_CST \ && int_size_in_bytes (TYPE) < (PARM_BOUNDARY / BITS_PER_UNIT))\ : (GET_MODE_BITSIZE (MODE) < PARM_BOUNDARY \ && (GET_MODE_CLASS (MODE) == MODE_INT))) \ ? downward : upward))#define FUNCTION_ARG_BOUNDARY(MODE, TYPE) \ (((TYPE) != 0) \ ? ((TYPE_ALIGN(TYPE) <= PARM_BOUNDARY) \ ? PARM_BOUNDARY \ : TYPE_ALIGN(TYPE)) \ : ((GET_MODE_ALIGNMENT(MODE) <= PARM_BOUNDARY) \ ? PARM_BOUNDARY \ : GET_MODE_ALIGNMENT(MODE)))#define FUNCTION_ARG_REGNO_P(N) \ (((N) >= GP_ARG_FIRST && (N) <= GP_ARG_LAST)) /* How Scalar Function Values are Returned. */#define FUNCTION_VALUE(VALTYPE, FUNC) iq2000_function_value (VALTYPE, FUNC)#define LIBCALL_VALUE(MODE) \ gen_rtx_REG (((GET_MODE_CLASS (MODE) != MODE_INT \ || GET_MODE_SIZE (MODE) >= 4) \ ? (MODE) \ : SImode), \ GP_RETURN)/* On the IQ2000, R2 and R3 are the only register thus used. */#define FUNCTION_VALUE_REGNO_P(N) ((N) == GP_RETURN)/* How Large Values are Returned. */#define DEFAULT_PCC_STRUCT_RETURN 0/* Function Entry and Exit. */#define EXIT_IGNORE_STACK 1/* Generating Code for Profiling. */#define FUNCTION_PROFILER(FILE, LABELNO) \{ \ fprintf (FILE, "\t.set\tnoreorder\n"); \ fprintf (FILE, "\t.set\tnoat\n"); \ fprintf (FILE, "\tmove\t%s,%s\t\t# save current return address\n", \ reg_names[GP_REG_FIRST + 1], reg_names[GP_REG_FIRST + 31]); \ fprintf (FILE, "\tjal\t_mcount\n"); \ fprintf (FILE, \ "\t%s\t%s,%s,%d\t\t# _mcount pops 2 words from stack\n", \ "subu", \ reg_names[STACK_POINTER_REGNUM], \ reg_names[STACK_POINTER_REGNUM], \ Pmode == DImode ? 16 : 8); \ fprintf (FILE, "\t.set\treorder\n"); \ fprintf (FILE, "\t.set\tat\n"); \}/* Implementing the Varargs Macros. */#define EXPAND_BUILTIN_VA_START(valist, nextarg) \ iq2000_va_start (valist, nextarg)/* Trampolines for Nested Functions. *//* A C statement to output, on the stream FILE, assembler code for a block of data that contains the constant parts of a trampoline. This code should not include a label--the label is taken care of automatically. */#define TRAMPOLINE_TEMPLATE(STREAM) \{ \ fprintf (STREAM, "\t.word\t0x03e00821\t\t# move $1,$31\n"); \ fprintf (STREAM, "\t.word\t0x04110001\t\t# bgezal $0,.+8\n"); \ fprintf (STREAM, "\t.word\t0x00000000\t\t# nop\n"); \ if (Pmode == DImode) \ { \ fprintf (STREAM, "\t.word\t0xdfe30014\t\t# ld $3,20($31)\n"); \ fprintf (STREAM, "\t.word\t0xdfe2001c\t\t# ld $2,28($31)\n"); \ } \ else \ { \ fprintf (STREAM, "\t.word\t0x8fe30014\t\t# lw $3,20($31)\n"); \ fprintf (STREAM, "\t.word\t0x8fe20018\t\t# lw $2,24($31)\n"); \ } \ fprintf (STREAM, "\t.word\t0x0060c821\t\t# move $25,$3 (abicalls)\n"); \ fprintf (STREAM, "\t.word\t0x00600008\t\t# jr $3\n"); \ fprintf (STREAM, "\t.word\t0x0020f821\t\t# move $31,$1\n"); \ fprintf (STREAM, "\t.word\t0x00000000\t\t# <function address>\n"); \ fprintf (STREAM, "\t.word\t0x00000000\t\t# <static chain value>\n"); \}#define TRAMPOLINE_SIZE (40)#define TRAMPOLINE_ALIGNMENT 32#define INITIALIZE_TRAMPOLINE(ADDR, FUNC, CHAIN) \{ \ rtx addr = ADDR; \ emit_move_insn (gen_rtx_MEM (SImode, plus_constant (addr, 32)), FUNC); \ emit_move_insn (gen_rtx_MEM (SImode, plus_constant (addr, 36)), CHAIN);\}/* Addressing Modes. */#define CONSTANT_ADDRESS_P(X) \ ( (GET_CODE (X) == LABEL_REF || GET_CODE (X) == SYMBOL_REF \ || GET_CODE (X) == CONST_INT || GET_CODE (X) == HIGH \ || (GET_CODE (X) == CONST)))#define MAX_REGS_PER_ADDRESS 1#ifdef REG_OK_STRICT#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \ { \ if (iq2000_legitimate_address_p (MODE, X, 1)) \ goto ADDR; \ }#else#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \ { \ if (iq2000_legitimate_address_p (MODE, X, 0)) \ goto ADDR; \ }#endif#define REG_OK_FOR_INDEX_P(X) 0/* For the IQ2000, transform: memory(X + <large int>) into: Y = <large int> & ~0x7fff; Z = X + Y memory (Z + (<large int> & 0x7fff));*/#define LEGITIMIZE_ADDRESS(X,OLDX,MODE,WIN) \{ \ rtx xinsn = (X); \ \ if (TARGET_DEBUG_B_MODE) \ { \ GO_PRINTF ("\n========== LEGITIMIZE_ADDRESS\n"); \ GO_DEBUG_RTX (xinsn); \ } \ \ if (iq2000_check_split (X, MODE)) \ { \ X = gen_rtx_LO_SUM (Pmode, \ copy_to_mode_reg (Pmode, \ gen_rtx_HIGH (Pmode, X)), \ X); \ goto WIN; \ } \ \ if (GET_CODE (xinsn) == PLUS) \ { \ rtx xplus0 = XEXP (xinsn, 0); \ rtx xplus1 = XEXP (xinsn, 1); \ enum rtx_code code0 = GET_CODE (xplus0); \ enum rtx_code code1 = GET_CODE (xplus1); \ \ if (code0 != REG && code1 == REG) \ { \ xplus0 = XEXP (xinsn, 1); \ xplus1 = XEXP (xinsn, 0); \ code0 = GET_CODE (xplus0); \ code1 = GET_CODE (xplus1); \ } \ \ if (code0 == REG && REG_MODE_OK_FOR_BASE_P (xplus0, MODE) \ && code1 == CONST_INT && !SMALL_INT (xplus1)) \ { \ rtx int_reg = gen_reg_rtx (Pmode); \ rtx ptr_reg = gen_reg_rtx (Pmode); \ \ emit_move_insn (int_reg, \ GEN_INT (INTVAL (xplus1) & ~ 0x7fff)); \ \ emit_insn (gen_rtx_SET (VOIDmode, \ ptr_reg, \ gen_rtx_PLUS (Pmode, xplus0, int_reg))); \ \ X = plus_constant (ptr_reg, INTVAL (xplus1) & 0x7fff); \ goto WIN; \ } \ } \ \ if (TARGET_DEBUG_B_MODE) \ GO_PRINTF ("LEGITIMIZE_ADDRESS could not fix.\n"); \}#define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR,LABEL) {}#define LEGITIMATE_CONSTANT_P(X) (1)/* Describing Relative Costs of Operations. */#define REGISTER_MOVE_COST(MODE, FROM, TO) 2#define MEMORY_MOVE_COST(MODE,CLASS,TO_P) \ (TO_P ? 2 : 16)#define BRANCH_COST 2#define SLOW_BYTE_ACCESS 1#define NO_FUNCTION_CSE 1#define ADJUST_COST(INSN,LINK,DEP_INSN,COST) \ if (REG_NOTE_KIND (LINK) != 0) \ (COST) = 0; /* Anti or output dependence. *//* Dividing the output into sections. */#define TEXT_SECTION_ASM_OP "\t.text" /* Instructions. */#define DATA_SECTION_ASM_OP "\t.data" /* Large data. *//* The Overall Framework of an Assembler File. */#define ASM_COMMENT_START " #"#define ASM_APP_ON "#APP\n"#define ASM_APP_OFF "#NO_APP\n"/* Output and Generation of Labels. */#undef ASM_GENERATE_INTERNAL_LABEL#define ASM_GENERATE_INTERNAL_LABEL(LABEL,PREFIX,NUM) \ sprintf ((LABEL), "*%s%s%ld", (LOCAL_LABEL_PREFIX), (PREFIX), (long) (NUM))#define GLOBAL_ASM_OP "\t.globl\t"/* Output of Assembler Instructions. */#define REGISTER_NAMES \{ \ "%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", "%rap" \};#define ADDITIONAL_REGISTER_NAMES \{ \ { "%0", 0 + GP_REG_FIRST }, \ { "%1", 1 + GP_REG_FIRST }, \ { "%2", 2 + GP_REG_FIRST }, \ { "%3", 3 + GP_REG_FIRST }, \ { "%4", 4 + GP_REG_FIRST }, \ { "%5", 5 + GP_REG_FIRST }, \ { "%6", 6 + GP_REG_FIRST }, \ { "%7", 7 + GP_REG_FIRST }, \ { "%8", 8 + GP_REG_FIRST }, \ { "%9", 9 + GP_REG_FIRST }, \ { "%10", 10 + GP_REG_FIRST }, \ { "%11", 11 + GP_REG_FIRST }, \ { "%12", 12 + GP_REG_FIRST }, \ { "%13", 13 + GP_REG_FIRST }, \ { "%14", 14 + GP_REG_FIRST }, \ { "%15", 15 + GP_REG_FIRST }, \ { "%16", 16 + GP_REG_FIRST }, \ { "%17", 17 + GP_REG_FIRST }, \ { "%18", 18 + GP_REG_FIRST }, \ { "%19", 19 + GP_REG_FIRST }, \ { "%20", 20 + GP_REG_FIRST }, \ { "%21", 21 + GP_REG_FIRST }, \ { "%22", 22 + GP_REG_FIRST }, \ { "%23", 23 + GP_REG_FIRST }, \ { "%24", 24 + GP_REG_FIRST }, \ { "%25", 25 + GP_REG_FIRST }, \ { "%26", 26 + GP_REG_FIRST }, \ { "%27", 27 + GP_REG_FIRST }, \ { "%28", 28 + GP_REG_FIRST }, \ { "%29", 29 + GP_REG_FIRST }, \ { "%30", 27 + GP_REG_FIRST }, \ { "%31", 31 + GP_REG_FIRST }, \ { "%rap", 32 + GP_REG_FIRST }, \}/* Check if the current insn needs a nop in front of it because of load delays, and also update the delay slot statistics. */#define FINAL_PRESCAN_INSN(INSN, OPVEC, NOPERANDS) \ final_prescan_insn (INSN, OPVEC, NOPERANDS)/* See iq2000.c for the IQ2000 specific codes. */#define PRINT_OPERAND(FILE, X, CODE) print_operand (FILE, X, CODE)#define PRINT_OPERAND_PUNCT_VALID_P(CODE) iq2000_print_operand_punct[CODE]#define PRINT_OPERAND_ADDRESS(FILE, ADDR) print_operand_address (FILE, ADDR)#define DBR_OUTPUT_SEQEND(STREAM) \do \ { \ fputs ("\n", STREAM); \ } \while (0)#define LOCAL_LABEL_PREFIX "$"#define USER_LABEL_PREFIX ""/* Output of dispatch tables. */#define ASM_OUTPUT_ADDR_DIFF_ELT(STREAM, BODY, VALUE, REL) \ do \ { \ fprintf (STREAM, "\t%s\t%sL%d\n", \ Pmode == DImode ? ".dword" : ".word", \ LOCAL_LABEL_PREFIX, VALUE); \ } \ while (0)#define ASM_OUTPUT_ADDR_VEC_ELT(STREAM, VALUE) \ fprintf (STREAM, "\t%s\t%sL%d\n", \ Pmode == DImode ? ".dword" : ".word", \ LOCAL_LABEL_PREFIX, \ VALUE)/* Assembler Commands for Alignment. */#undef ASM_OUTPUT_SKIP#define ASM_OUTPUT_SKIP(STREAM,SIZE) \ fprintf (STREAM, "\t.space\t%u\n", (SIZE))#define ASM_OUTPUT_ALIGN(STREAM,LOG) \ if ((LOG) != 0) \ fprintf (STREAM, "\t.balign %d\n", 1<<(LOG))/* Macros Affecting all Debug Formats. */#define DEBUGGER_AUTO_OFFSET(X) \
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -