📄 i386.h
字号:
block move. Make this large on i386, since the block move is very inefficient with small blocks, and the hard register needs of the block move require much reload work. */#define MOVE_RATIO 5/* Define this if zero-extension is slow (more than one real instruction). *//* #define SLOW_ZERO_EXTEND *//* Nonzero if access to memory by bytes is slow and undesirable. */#define SLOW_BYTE_ACCESS 0/* Define if shifts truncate the shift count which implies one can omit a sign-extension or zero-extension of a shift count. *//* One i386, shifts do truncate the count. But bit opcodes don't. *//* #define SHIFT_COUNT_TRUNCATED *//* Value is 1 if truncating an integer of INPREC bits to OUTPREC bits is done just by pretending it is already truncated. */#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1/* We assume that the store-condition-codes instructions store 0 for false and some other value for true. This is the value stored for true. */#define STORE_FLAG_VALUE 1/* When a prototype says `char' or `short', really pass an `int'. (The 386 can't easily push less than an int.) */#define PROMOTE_PROTOTYPES/* Specify the machine mode that pointers have. After generation of rtl, the compiler makes no further distinction between pointers and any other objects of this machine mode. */#define Pmode SImode/* A function address in a call instruction is a byte address (for indexing purposes) so give the MEM rtx a byte's mode. */#define FUNCTION_MODE QImode/* Define this if addresses of constant functions shouldn't be put through pseudo regs where they can be cse'd. Desirable on the 386 because a CALL with a constant address is not much slower than one with a register address. On a 486, it is faster to call with a constant address than indirect. */#define NO_FUNCTION_CSE/* Provide the costs of a rtl expression. This is in the body of a switch on CODE. */#define RTX_COSTS(X,CODE,OUTER_CODE) \ case MULT: \ return COSTS_N_INSNS (20); \ case DIV: \ case UDIV: \ case MOD: \ case UMOD: \ return COSTS_N_INSNS (20); \ case ASHIFTRT: \ case LSHIFTRT: \ case ASHIFT: \ return (4 + rtx_cost (XEXP (X, 0), OUTER_CODE) \ + rtx_cost (XEXP (X, 1), OUTER_CODE)); \ case PLUS: \ if (GET_CODE (XEXP (X, 0)) == MULT \ && GET_CODE (XEXP (XEXP (X, 0), 1)) == CONST_INT \ && (INTVAL (XEXP (XEXP (X, 0), 1)) == 2 \ || INTVAL (XEXP (XEXP (X, 0), 1)) == 4 \ || INTVAL (XEXP (XEXP (X, 0), 1)) == 8)) \ return (2 + rtx_cost (XEXP (XEXP (X, 0), 0), OUTER_CODE) \ + rtx_cost (XEXP (X, 1), OUTER_CODE)); \ break;/* Compute the cost of computing a constant rtl expression RTX whose rtx-code is CODE. The body of this macro is a portion of a switch statement. If the code is computed here, return it with a return statement. Otherwise, break from the switch. */#define CONST_COSTS(RTX,CODE,OUTER_CODE) \ case CONST_INT: \ case CONST: \ case LABEL_REF: \ case SYMBOL_REF: \ return flag_pic && SYMBOLIC_CONST (RTX) ? 2 : 0; \ case CONST_DOUBLE: \ { \ int code; \ if (GET_MODE (RTX) == VOIDmode) \ return 2; \ code = standard_80387_constant_p (RTX); \ return code == 1 ? 0 : \ code == 2 ? 1 : \ 2; \ }/* Compute the cost of an address. This is meant to approximate the size and/or execution delay of an insn using that address. If the cost is approximated by the RTL complexity, including CONST_COSTS above, as is usually the case for CISC machines, this macro should not be defined. For aggressively RISCy machines, only one insn format is allowed, so this macro should be a constant. The value of this macro only matters for valid addresses. For i386, it is better to use a complex address than let gcc copy the address into a reg and make a new pseudo. But not if the address requires to two regs - that would mean more pseudos with longer lifetimes. */#define ADDRESS_COST(RTX) \ ((CONSTANT_P (RTX) \ || (GET_CODE (RTX) == PLUS && CONSTANT_P (XEXP (RTX, 1)) \ && REG_P (XEXP (RTX, 0)))) ? 0 \ : REG_P (RTX) ? 1 \ : 2)/* Add any extra modes needed to represent the condition code. For the i386, we need separate modes when floating-point equality comparisons are being done. */#define EXTRA_CC_MODES CCFPEQmode/* Define the names for the modes specified above. */#define EXTRA_CC_NAMES "CCFPEQ"/* Given a comparison code (EQ, NE, etc.) and the first operand of a COMPARE, return the mode to be used for the comparison. For floating-point equality comparisons, CCFPEQmode should be used. VOIDmode should be used in all other cases. */#define SELECT_CC_MODE(OP,X,Y) \ (GET_MODE_CLASS (GET_MODE (X)) == MODE_FLOAT \ && ((OP) == EQ || (OP) == NE) ? CCFPEQmode : VOIDmode)/* 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 *(*i386_compare_gen)(), *(*i386_compare_gen_eq)();/* Tell final.c how to eliminate redundant test instructions. *//* Here we define machine-dependent flags and fields in cc_status (see `conditions.h'). *//* Set if the cc value is actually in the 80387, so a floating point conditional branch must be output. */#define CC_IN_80387 04000/* Set if the CC value was stored in a nonstandard way, so that the state of equality is indicated by zero in the carry bit. */#define CC_Z_IN_NOT_C 010000/* Store in cc_status the expressions that the condition codes will describe after execution of an instruction whose pattern is EXP. Do not alter them if the instruction would not alter the cc's. */#define NOTICE_UPDATE_CC(EXP, INSN) \ notice_update_cc((EXP))/* Output a signed jump insn. Use template NORMAL ordinarily, or FLOAT following a floating point comparison. Use NO_OV following an arithmetic insn that set the cc's before a test insn that was deleted. NO_OV may be zero, meaning final should reinsert the test insn because the jump cannot be handled properly without it. */#define OUTPUT_JUMP(NORMAL, FLOAT, NO_OV) \{ \ if (cc_prev_status.flags & CC_IN_80387) \ return FLOAT; \ if (cc_prev_status.flags & CC_NO_OVERFLOW) \ return NO_OV; \ return NORMAL; \}/* Control the assembler format that we output, to the extent this does not vary between assemblers. *//* How to refer to registers in assembler output. This sequence is indexed by compiler's hard-register-number (see above). *//* In order to refer to the first 8 regs as 32 bit regs prefix an "e" For non floating point regs, the following are the HImode names. For float regs, the stack top is sometimes referred to as "%st(0)" instead of just "%st". PRINT_REG handles this with the "y" code. */#define HI_REGISTER_NAMES \{"ax","dx","cx","bx","si","di","bp","sp", \ "st","st(1)","st(2)","st(3)","st(4)","st(5)","st(6)","st(7)","" }#define REGISTER_NAMES HI_REGISTER_NAMES/* Table of additional register names to use in user input. */#define ADDITIONAL_REGISTER_NAMES \{ "eax", 0, "edx", 1, "ecx", 2, "ebx", 3, \ "esi", 4, "edi", 5, "ebp", 6, "esp", 7, \ "al", 0, "dl", 1, "cl", 2, "bl", 3, \ "ah", 0, "dh", 1, "ch", 2, "bh", 3 }/* Note we are omitting these since currently I don't know howto get gcc to use these, since they want the same but differentnumber as al, and ax.*//* note the last four are not really qi_registers, but the md will have to never output movb into one of them only a movw . There is no movb into the last four regs */#define QI_REGISTER_NAMES \{"al", "dl", "cl", "bl", "si", "di", "bp", "sp",}/* These parallel the array above, and can be used to access bits 8:15 of regs 0 through 3. */#define QI_HIGH_REGISTER_NAMES \{"ah", "dh", "ch", "bh", }/* How to renumber registers for dbx and gdb. *//* {0,2,1,3,6,7,4,5,12,13,14,15,16,17} */#define DBX_REGISTER_NUMBER(n) \((n) == 0 ? 0 : \ (n) == 1 ? 2 : \ (n) == 2 ? 1 : \ (n) == 3 ? 3 : \ (n) == 4 ? 6 : \ (n) == 5 ? 7 : \ (n) == 6 ? 4 : \ (n) == 7 ? 5 : \ (n) + 4)/* This is how to output the definition of a user-level label named NAME, such as the label on a static function or variable NAME. */#define ASM_OUTPUT_LABEL(FILE,NAME) \ (assemble_name (FILE, NAME), fputs (":\n", FILE))/* This is how to output an assembler line defining a `double' constant. */#define ASM_OUTPUT_DOUBLE(FILE,VALUE) \do { long l[2]; \ REAL_VALUE_TO_TARGET_DOUBLE (VALUE, l); \ if (sizeof (int) == sizeof (long)) \ fprintf (FILE, "%s 0x%x,0x%x\n", ASM_LONG, l[0], l[1]); \ else \ fprintf (FILE, "%s 0x%lx,0x%lx\n", ASM_LONG, l[0], l[1]); \ } while (0)/* This is how to output a `long double' extended real constant. */#undef ASM_OUTPUT_LONG_DOUBLE#define ASM_OUTPUT_LONG_DOUBLE(FILE,VALUE) \do { long l[3]; \ REAL_VALUE_TO_TARGET_LONG_DOUBLE (VALUE, l); \ if (sizeof (int) == sizeof (long)) \ fprintf (FILE, "%s 0x%x,0x%x,0x%x\n", ASM_LONG, l[0], l[1], l[2]); \ else \ fprintf (FILE, "%s 0x%lx,0x%lx,0x%lx\n", ASM_LONG, l[0], l[1], l[2]); \ } while (0)/* This is how to output an assembler line defining a `float' constant. */#define ASM_OUTPUT_FLOAT(FILE,VALUE) \do { long l; \ REAL_VALUE_TO_TARGET_SINGLE (VALUE, l); \ if (sizeof (int) == sizeof (long)) \ fprintf ((FILE), "%s 0x%x\n", ASM_LONG, l); \ else \ fprintf ((FILE), "%s 0x%lx\n", ASM_LONG, l); \ } while (0)/* Store in OUTPUT a string (made with alloca) containing an assembler-name for a local static variable named NAME. LABELNO is an integer which is different for each call. */#define ASM_FORMAT_PRIVATE_NAME(OUTPUT, NAME, LABELNO) \( (OUTPUT) = (char *) alloca (strlen ((NAME)) + 10), \ sprintf ((OUTPUT), "%s.%d", (NAME), (LABELNO)))/* This is how to output an assembler line defining an `int' constant. */#define ASM_OUTPUT_INT(FILE,VALUE) \( fprintf (FILE, "%s ", ASM_LONG), \ output_addr_const (FILE,(VALUE)), \ putc('\n',FILE))/* Likewise for `char' and `short' constants. *//* is this supposed to do align too?? */#define ASM_OUTPUT_SHORT(FILE,VALUE) \( fprintf (FILE, "%s ", ASM_SHORT), \ output_addr_const (FILE,(VALUE)), \ putc('\n',FILE))/*#define ASM_OUTPUT_SHORT(FILE,VALUE) \( fprintf (FILE, "%s ", ASM_BYTE_OP), \ output_addr_const (FILE,(VALUE)), \ fputs (",", FILE), \ output_addr_const (FILE,(VALUE)), \ fputs (" >> 8\n",FILE))*/#define ASM_OUTPUT_CHAR(FILE,VALUE) \( fprintf (FILE, "%s ", ASM_BYTE_OP), \ output_addr_const (FILE, (VALUE)), \ putc ('\n', FILE))/* This is how to output an assembler line for a numeric constant byte. */#define ASM_OUTPUT_BYTE(FILE,VALUE) \ fprintf ((FILE), "%s 0x%x\n", ASM_BYTE_OP, (VALUE))/* This is how to output an insn to push a register on the stack. It need not be very fast code. */#define ASM_OUTPUT_REG_PUSH(FILE,REGNO) \ fprintf (FILE, "\tpushl e%s\n", reg_names[REGNO])/* This is how to output an insn to pop a register from the stack. It need not be very fast code. */#define ASM_OUTPUT_REG_POP(FILE,REGNO) \ fprintf (FILE, "\tpopl e%s\n", reg_names[REGNO])/* This is how to output an element of a case-vector that is absolute. */#define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \ fpr
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -