📄 i386.h
字号:
/* Definitions of target machine for GNU compiler for Intel X86 (386, 486, Pentium). Copyright (C) 1988, 1992, 1994, 1995 Free Software Foundation, Inc.This file is part of GNU CC.GNU CC is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation; either version 2, or (at your option)any later version.GNU CC is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with GNU CC; see the file COPYING. If not, write tothe Free Software Foundation, 59 Temple Place - Suite 330,Boston, MA 02111-1307, USA. *//* The purpose of this file is to define the characteristics of the i386, independent of assembler syntax or operating system. Three other files build on this one to describe a specific assembler syntax: bsd386.h, att386.h, and sun386.h. The actual tm.h file for a particular system should include this file, and then the file for the appropriate assembler syntax. Many macros that specify assembler syntax are omitted entirely from this file because they really belong in the files for particular assemblers. These include AS1, AS2, AS3, RP, IP, LPREFIX, L_SIZE, PUT_OP_SIZE, USE_STAR, ADDR_BEG, ADDR_END, PRINT_IREG, PRINT_SCALE, PRINT_B_I_S, and many that start with ASM_ or end in ASM_OP. *//* Names to predefine in the preprocessor for this target machine. */#define I386 1/* Stubs for half-pic support if not OSF/1 reference platform. */#ifndef HALF_PIC_P#define HALF_PIC_P() 0#define HALF_PIC_NUMBER_PTRS 0#define HALF_PIC_NUMBER_REFS 0#define HALF_PIC_ENCODE(DECL)#define HALF_PIC_DECLARE(NAME)#define HALF_PIC_INIT() error ("half-pic init called on systems that don't support it.")#define HALF_PIC_ADDRESS_P(X) 0#define HALF_PIC_PTR(X) X#define HALF_PIC_FINISH(STREAM)#endif/* Run-time compilation parameters selecting different hardware subsets. */extern int target_flags;/* Macros used in the machine description to test the flags. *//* configure can arrange to make this 2, to force a 486. */#ifndef TARGET_CPU_DEFAULT#define TARGET_CPU_DEFAULT 0#endif/* Masks for the -m switches */#define MASK_80387 000000000001 /* Hardware floating point */#define MASK_486 000000000002 /* 80486 specific */#define MASK_NOTUSED1 000000000004 /* bit not currently used */#define MASK_RTD 000000000010 /* Use ret that pops args */#define MASK_ALIGN_DOUBLE 000000000020 /* align doubles to 2 word boundary */#define MASK_SVR3_SHLIB 000000000040 /* Uninit locals into bss */#define MASK_IEEE_FP 000000000100 /* IEEE fp comparisons */#define MASK_FLOAT_RETURNS 000000000200 /* Return float in st(0) */#define MASK_NO_FANCY_MATH_387 000000000400 /* Disable sin, cos, sqrt */ /* Temporary codegen switches */#define MASK_DEBUG_ADDR 000001000000 /* Debug GO_IF_LEGITIMATE_ADDRESS */#define MASK_NO_WIDE_MULTIPLY 000002000000 /* Disable 32x32->64 multiplies */#define MASK_NO_MOVE 000004000000 /* Don't generate mem->mem */#define MASK_DEBUG_ARG 000010000000 /* Debug function_arg */ /* Use the floating point instructions */#define TARGET_80387 (target_flags & MASK_80387)/* Compile using ret insn that pops args. This will not work unless you use prototypes at least for all functions that can take varying numbers of args. */ #define TARGET_RTD (target_flags & MASK_RTD)/* Align doubles to a two word boundary. This breaks compatibility with the published ABI's for structures containing doubles, but produces faster code on the pentium. */#define TARGET_ALIGN_DOUBLE (target_flags & MASK_ALIGN_DOUBLE)/* Put uninitialized locals into bss, not data. Meaningful only on svr3. */#define TARGET_SVR3_SHLIB (target_flags & MASK_SVR3_SHLIB)/* Use IEEE floating point comparisons. These handle correctly the cases where the result of a comparison is unordered. Normally SIGFPE is generated in such cases, in which case this isn't needed. */#define TARGET_IEEE_FP (target_flags & MASK_IEEE_FP)/* Functions that return a floating point value may return that value in the 387 FPU or in 386 integer registers. If set, this flag causes the 387 to be used, which is compatible with most calling conventions. */#define TARGET_FLOAT_RETURNS_IN_80387 (target_flags & MASK_FLOAT_RETURNS)/* Disable generation of FP sin, cos and sqrt operations for 387. This is because FreeBSD lacks these in the math-emulator-code */#define TARGET_NO_FANCY_MATH_387 (target_flags & MASK_NO_FANCY_MATH_387)/* Temporary switches for tuning code generation *//* Disable 32x32->64 bit multiplies that are used for long long multiplies and division by constants, but sometimes cause reload problems. */#define TARGET_NO_WIDE_MULTIPLY (target_flags & MASK_NO_WIDE_MULTIPLY)#define TARGET_WIDE_MULTIPLY (!TARGET_NO_WIDE_MULTIPLY)/* Debug GO_IF_LEGITIMATE_ADDRESS */#define TARGET_DEBUG_ADDR (target_flags & MASK_DEBUG_ADDR)/* Debug FUNCTION_ARG macros */#define TARGET_DEBUG_ARG (target_flags & MASK_DEBUG_ARG)/* Hack macros for tuning code generation */#define TARGET_MOVE ((target_flags & MASK_NO_MOVE) == 0) /* Don't generate memory->memory *//* Specific hardware switches */#define TARGET_486 (target_flags & MASK_486) /* 80486DX, 80486SX, 80486DX[24] */#define TARGET_386 (!TARGET_486) /* 80386 */#define TARGET_SWITCHES \{ { "80387", MASK_80387 }, \ { "no-80387", -MASK_80387 }, \ { "hard-float", MASK_80387 }, \ { "soft-float", -MASK_80387 }, \ { "no-soft-float", MASK_80387 }, \ { "386", -MASK_486 }, \ { "no-386", MASK_486 }, \ { "486", MASK_486 }, \ { "no-486", -MASK_486 }, \ { "rtd", MASK_RTD }, \ { "no-rtd", -MASK_RTD }, \ { "align-double", MASK_ALIGN_DOUBLE }, \ { "no-align-double", -MASK_ALIGN_DOUBLE }, \ { "svr3-shlib", MASK_SVR3_SHLIB }, \ { "no-svr3-shlib", -MASK_SVR3_SHLIB }, \ { "ieee-fp", MASK_IEEE_FP }, \ { "no-ieee-fp", -MASK_IEEE_FP }, \ { "fp-ret-in-387", MASK_FLOAT_RETURNS }, \ { "no-fp-ret-in-387", -MASK_FLOAT_RETURNS }, \ { "no-fancy-math-387", MASK_NO_FANCY_MATH_387 }, \ { "fancy-math-387", -MASK_NO_FANCY_MATH_387 }, \ { "no-wide-multiply", MASK_NO_WIDE_MULTIPLY }, \ { "wide-multiply", -MASK_NO_WIDE_MULTIPLY }, \ { "debug-addr", MASK_DEBUG_ADDR }, \ { "no-debug-addr", -MASK_DEBUG_ADDR }, \ { "move", -MASK_NO_MOVE }, \ { "no-move", MASK_NO_MOVE }, \ { "debug-arg", MASK_DEBUG_ARG }, \ { "no-debug-arg", -MASK_DEBUG_ARG }, \ SUBTARGET_SWITCHES \ { "", TARGET_DEFAULT | TARGET_CPU_DEFAULT}}/* This macro is similar to `TARGET_SWITCHES' but defines names of command options that have values. Its definition is an initializer with a subgrouping for each command option. Each subgrouping contains a string constant, that defines the fixed part of the option name, and the address of a variable. The variable, type `char *', is set to the variable part of the given option if the fixed part matches. The actual option name is made by appending `-m' to the specified name. */#define TARGET_OPTIONS \{ { "reg-alloc=", &i386_reg_alloc_order }, \ { "regparm=", &i386_regparm_string }, \ { "align-loops=", &i386_align_loops_string }, \ { "align-jumps=", &i386_align_jumps_string }, \ { "align-functions=", &i386_align_funcs_string }, \ SUBTARGET_OPTIONS \}/* Sometimes certain combinations of command options do not make sense on a particular target machine. You can define a macro `OVERRIDE_OPTIONS' to take account of this. This macro, if defined, is executed once just after all the command options have been parsed. Don't use this macro to turn on various extra optimizations for `-O'. That is what `OPTIMIZATION_OPTIONS' is for. */#define OVERRIDE_OPTIONS override_options ()/* These are meant to be redefined in the host dependent files */#define SUBTARGET_SWITCHES#define SUBTARGET_OPTIONS/* target machine storage layout *//* Define for XFmode extended real floating point support. This will automatically cause REAL_ARITHMETIC to be defined. */#define LONG_DOUBLE_TYPE_SIZE 96/* Define if you don't want extended real, but do want to use the software floating point emulator for REAL_ARITHMETIC and decimal <-> binary conversion. *//* #define REAL_ARITHMETIC *//* Define this if most significant byte of a word is the lowest numbered. *//* That is true on the 80386. */#define BITS_BIG_ENDIAN 0/* Define this if most significant byte of a word is the lowest numbered. *//* That is not true on the 80386. */#define BYTES_BIG_ENDIAN 0/* Define this if most significant word of a multiword number is the lowest numbered. *//* Not true for 80386 */#define WORDS_BIG_ENDIAN 0/* number of bits in an addressable storage unit */#define BITS_PER_UNIT 8/* Width in bits of a "word", which is the contents of a machine register. Note that this is not necessarily the width of data type `int'; if using 16-bit ints on a 80386, this would still be 32. But on a machine with 16-bit registers, this would be 16. */#define BITS_PER_WORD 32/* Width of a word, in units (bytes). */#define UNITS_PER_WORD 4/* Width in bits of a pointer. See also the macro `Pmode' defined below. */#define POINTER_SIZE 32/* Allocation boundary (in *bits*) for storing arguments in argument list. */#define PARM_BOUNDARY 32/* Boundary (in *bits*) on which stack pointer should be aligned. */#define STACK_BOUNDARY 32/* Allocation boundary (in *bits*) for the code of a function. For i486, we get better performance by aligning to a cache line (i.e. 16 byte) boundary. */#define FUNCTION_BOUNDARY (1 << (i386_align_funcs + 3))/* Alignment of field after `int : 0' in a structure. */#define EMPTY_FIELD_BOUNDARY 32/* Minimum size in bits of the largest boundary to which any and all fundamental data types supported by the hardware might need to be aligned. No data type wants to be aligned rounder than this. The i386 supports 64-bit floating point quantities, but these can be aligned on any 32-bit boundary. The published ABIs say that doubles should be aligned on word boundaries, but the Pentium gets better performance with them aligned on 64 bit boundaries. */#define BIGGEST_ALIGNMENT (TARGET_ALIGN_DOUBLE ? 64 : 32)/* Set this non-zero if move instructions will actually fail to work when given unaligned data. */#define STRICT_ALIGNMENT 0/* If bit field type is int, don't let it cross an int, and give entire struct the alignment of an int. *//* Required on the 386 since it doesn't have bitfield insns. */#define PCC_BITFIELD_TYPE_MATTERS 1/* Maximum power of 2 that code can be aligned to. */#define MAX_CODE_ALIGN 6 /* 64 byte alignment *//* Align loop starts for optimal branching. */#define ASM_OUTPUT_LOOP_ALIGN(FILE) ASM_OUTPUT_ALIGN (FILE, i386_align_loops)/* This is how to align an instruction for optimal branching. On i486 we'll get better performance by aligning on a cache line (i.e. 16 byte) boundary. */#define ASM_OUTPUT_ALIGN_CODE(FILE) ASM_OUTPUT_ALIGN ((FILE), i386_align_jumps)/* Standard register usage. *//* This processor has special stack-like registers. See reg-stack.c for details. */#define STACK_REGS/* Number of actual hardware registers. The hardware registers are assigned numbers for the compiler from 0 to just below FIRST_PSEUDO_REGISTER. All registers that the compiler knows about must be given numbers, even those that are not normally considered general registers. In the 80386 we give the 8 general purpose registers the numbers 0-7. We number the floating point registers 8-15. Note that registers 0-7 can be accessed as a short or int, while only 0-3 may be used with byte `mov' instructions. Reg 16 does not correspond to any hardware register, but instead appears in the RTL as an argument pointer prior to reload, and is eliminated during reloading in favor of either the stack or frame pointer. */#define FIRST_PSEUDO_REGISTER 17/* 1 for registers that have pervasive standard uses and are not available for the register allocator. On the 80386, the stack pointer is such, as is the arg pointer. */#define FIXED_REGISTERS \/*ax,dx,cx,bx,si,di,bp,sp,st,st1,st2,st3,st4,st5,st6,st7,arg*/ \{ 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1 }/* 1 for registers not available across function calls. These must include the FIXED_REGISTERS and also any registers that can be used without being saved. The latter must include the registers where values are returned and the register where structure-value addresses are passed. Aside from that, you can include as many other registers as you like. */#define CALL_USED_REGISTERS \/*ax,dx,cx,bx,si,di,bp,sp,st,st1,st2,st3,st4,st5,st6,st7,arg*/ \{ 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }/* Order in which to allocate registers. Each register must be listed once, even those in FIXED_REGISTERS. List frame pointer late and fixed registers last. Note that, in general, we prefer registers listed in CALL_USED_REGISTERS, keeping the others available for storage of persistent values. Three different versions of REG_ALLOC_ORDER have been tried: If the order is edx, ecx, eax, ... it produces a slightly faster compiler, but slower code on simple functions returning values in eax. If the order is eax, ecx, edx, ... it causes reload to abort when compiling
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -