at 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. REX registers are disabled for 32bit targets in TARGET_CONDITIONAL_REGISTER_USAGE. */ #define FIXED_REGISTERS \ /*ax,dx,cx,bx,si,di,bp,sp,st,st1,st2,st3,st4,st5,st6,st7*/ \ { 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, \ /*arg,flags,fpsr,frame*/ \ 1, 1, 1, 1, \ /*xmm0,xmm1,xmm2,xmm3,xmm4,xmm5,xmm6,xmm7*/ \ 0, 0, 0, 0, 0, 0, 0, 0, \ /* mm0, mm1, mm2, mm3, mm4, mm5, mm6, mm7*/ \ 0, 0, 0, 0, 0, 0, 0, 0, \ /* r8, r9, r10, r11, r12, r13, r14, r15*/ \ 0, 0, 0, 0, 0, 0, 0, 0, \ /*xmm8,xmm9,xmm10,xmm11,xmm12,xmm13,xmm14,xmm15*/ \ 0, 0, 0, 0, 0, 0, 0, 0, \ /*xmm16,xmm17,xmm18,xmm19,xmm20,xmm21,xmm22,xmm23*/ \ 0, 0, 0, 0, 0, 0, 0, 0, \ /*xmm24,xmm25,xmm26,xmm27,xmm28,xmm29,xmm30,xmm31*/ \ 0, 0, 0, 0, 0, 0, 0, 0, \ /* k0, k1, k2, k3, k4, k5, k6, k7*/ \ 0, 0, 0, 0, 0, 0, 0, 0 } /* 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. Value is set to 1 if the register is call used unconditionally. Bit one is set if the register is call used on TARGET_32BIT ABI. Bit two is set if the register is call used on TARGET_64BIT ABI. Bit three is set if the register is call used on TARGET_64BIT_MS_ABI. Proper values are computed in TARGET_CONDITIONAL_REGISTER_USAGE. */ #define CALL_USED_REGISTERS_MASK(IS_64BIT_MS_ABI) \ ((IS_64BIT_MS_ABI) ? (1 << 3) : TARGET_64BIT ? (1 << 2) : (1 << 1)) #define CALL_USED_REGISTERS \ /*ax,dx,cx,bx,si,di,bp,sp,st,st1,st2,st3,st4,st5,st6,st7*/ \ { 1, 1, 1, 0, 4, 4, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, \ /*arg,flags,fpsr,frame*/ \ 1, 1, 1, 1, \ /*xmm0,xmm1,xmm2,xmm3,xmm4,xmm5,xmm6,xmm7*/ \ 1, 1, 1, 1, 1, 1, 6, 6, \ /* mm0, mm1, mm2, mm3, mm4, mm5, mm6, mm7*/ \ 1, 1, 1, 1, 1, 1, 1, 1, \ /* r8, r9, r10, r11, r12, r13, r14, r15*/ \ 1, 1, 1, 1, 2, 2, 2, 2, \ /*xmm8,xmm9,xmm10,xmm11,xmm12,xmm13,xmm14,xmm15*/ \ 6, 6, 6, 6, 6, 6, 6, 6, \ /*xmm16,xmm17,xmm18,xmm19,xmm20,xmm21,xmm22,xmm23*/ \ 1, 1, 1, 1, 1, 1, 1, 1, \ /*xmm24,xmm25,xmm26,xmm27,xmm28,xmm29,xmm30,xmm31*/ \ 1, 1, 1, 1, 1, 1, 1, 1, \ /* k0, k1, k2, k3, k4, k5, k6, k7*/ \ 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. The ADJUST_REG_ALLOC_ORDER actually overwrite the order, so this is just empty initializer for array. */ #define 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, \ 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 } /* ADJUST_REG_ALLOC_ORDER is a macro which permits reg_alloc_order to be rearranged based on a particular function. When using sse math, we want to allocate SSE before x87 registers and vice versa. */ #define ADJUST_REG_ALLOC_ORDER x86_order_regs_for_local_alloc () #define OVERRIDE_ABI_FORMAT(FNDECL) ix86_call_abi_override (FNDECL) #define HARD_REGNO_NREGS_HAS_PADDING(REGNO, MODE) \ (TARGET_128BIT_LONG_DOUBLE && !TARGET_64BIT \ && GENERAL_REGNO_P (REGNO) \ && ((MODE) == XFmode || (MODE) == XCmode)) #define HARD_REGNO_NREGS_WITH_PADDING(REGNO, MODE) ((MODE) == XFmode ? 4 : 8) #define REGMODE_NATURAL_SIZE(MODE) ix86_regmode_natural_size (MODE) #define VALID_AVX256_REG_MODE(MODE) \ ((MODE) == V32QImode || (MODE) == V16HImode || (MODE) == V8SImode \ || (MODE) == V4DImode || (MODE) == V2TImode || (MODE) == V8SFmode \ || (MODE) == V4DFmode || (MODE) == V16HFmode) #define VALID_AVX256_REG_OR_OI_MODE(MODE) \ (VALID_AVX256_REG_MODE (MODE) || (MODE) == OImode) #define VALID_AVX512F_SCALAR_MODE(MODE) \ ((MODE) == DImode || (MODE) == DFmode || (MODE) == SImode \ || (MODE) == SFmode) #define VALID_AVX512FP16_SCALAR_MODE(MODE) \ ((MODE) == HImode || (MODE) == HFmode) #define VALID_AVX512F_REG_MODE(MODE) \ ((MODE) == V8DImode || (MODE) == V8DFmode || (MODE) == V64QImode \ || (MODE) == V16SImode || (MODE) == V16SFmode || (MODE) == V32HImode \ || (MODE) == V4TImode || (MODE) == V32HFmode) #define VALID_AVX512F_REG_OR_XI_MODE(MODE) \ (VALID_AVX512F_REG_MODE (MODE) || (MODE) == XImode) #define VALID_AVX512VL_128_REG_MODE(MODE) \ ((MODE) == V2DImode || (MODE) == V2DFmode || (MODE) == V16QImode \ || (MODE) == V4SImode || (MODE) == V4SFmode || (MODE) == V8HImode \ || (MODE) == TFmode || (MODE) == V1TImode || (MODE) == V8HFmode \ || (MODE) == TImode) #define VALID_AVX512FP16_REG_MODE(MODE) \ ((MODE) == V8HFmode || (MODE) == V16HFmode || (MODE) == V32HFmode \ || (MODE) == V2HFmode) #define VALID_SSE2_REG_MODE(MODE) \ ((MODE) == V16QImode || (MODE) == V8HImode || (MODE) == V2DFmode \ || (MODE) == V8HFmode || (MODE) == V4HFmode || (MODE) == V2HFmode \ || (MODE) == V4QImode || (MODE) == V2HImode || (MODE) == V1SImode \ || (MODE) == V2DImode || (MODE) == V2QImode || (MODE) == DFmode \ || (MODE) == HFmode) #define VALID_SSE_REG_MODE(MODE) \ ((MODE) == V1TImode || (MODE) == TImode \ || (MODE) == V4SFmode || (MODE) == V4SImode \ || (MODE) == SFmode || (MODE) == TFmode || (MODE) == TDmode) #define VALID_MMX_REG_MODE_3DNOW(MODE) \ ((MODE) == V2SFmode || (MODE) == SFmode) /* To match ia32 psABI, V4HFmode should be added here. */ #define VALID_MMX_REG_MODE(MODE) \ ((MODE) == V1DImode || (MODE) == DImode \ || (MODE) == V2SImode || (MODE) == SImode \ || (MODE) == V4HImode || (MODE) == V8QImode \ || (MODE) == V4HFmode) #define VALID_MASK_REG_MODE(MODE) ((MODE) == HImode || (MODE) == QImode) #define VALID_MASK_AVX512BW_MODE(MODE) ((MODE) == SImode || (MODE) == DImode) #define VALID_FP_MODE_P(MODE) \ ((MODE) == SFmode || (MODE) == DFmode || (MODE) == XFmode \ || (MODE) == SCmode || (MODE) == DCmode || (MODE) == XCmode) #define VALID_INT_MODE_P(MODE) \ ((MODE) == QImode || (MODE) == HImode \ || (MODE) == SImode || (MODE) == DImode \ || (MODE) == CQImode || (MODE) == CHImode \ || (MODE) == CSImode || (MODE) == CDImode \ || (MODE) == SDmode || (MODE) == DDmode \ || (MODE) == HFmode || (MODE) == HCmode \ || (MODE) == V2HImode || (MODE) == V2HFmode \ || (MODE) == V1SImode || (MODE) == V4QImode || (MODE) == V2QImode \ || (TARGET_64BIT \ && ((MODE) == TImode || (MODE) == CTImode \ || (MODE) == TFmode || (MODE) == TCmode \ || (MODE) == V8QImode || (MODE) == V4HImode \ || (MODE) == V2SImode || (MODE) == TDmode))) /* Return true for modes passed in SSE registers. */ #define SSE_REG_MODE_P(MODE) \ ((MODE) == V1TImode || (MODE) == TImode || (MODE) == V16QImode \ || (MODE) == TFmode || (MODE) == V8HImode || (MODE) == V2DFmode \ || (MODE) == V2DImode || (MODE) == V4SFmode || (MODE) == V4SImode \ || (MODE) == V32QImode || (MODE) == V16HImode || (MODE) == V8SImode \ || (MODE) == V4DImode || (MODE) == V8SFmode || (MODE) == V4DFmode \ || (MODE) == V2TImode || (MODE) == V8DImode || (MODE) == V64QImode \ || (MODE) == V16SImode || (MODE) == V32HImode || (MODE) == V8DFmode \ || (MODE) == V16SFmode || (MODE) == V32HFmode || (MODE) == V16HFmode \ || (MODE) == V8HFmode) #define X87_FLOAT_MODE_P(MODE) \ (TARGET_80387 && ((MODE) == SFmode || (MODE) == DFmode || (MODE) == XFmode)) #define SSE_FLOAT_MODE_P(MODE) \ ((TARGET_SSE && (MODE) == SFmode) || (TARGET_SSE2 && (MODE) == DFmode)) #define SSE_FLOAT_MODE_SSEMATH_OR_HF_P(MODE) \ ((SSE_FLOAT_MODE_P (MODE) && TARGET_SSE_MATH) \ || (TARGET_AVX512FP16 && (MODE) == HFmode)) #define FMA4_VEC_FLOAT_MODE_P(MODE) \ (TARGET_FMA4 && ((MODE) == V4SFmode || (MODE) == V2DFmode \ || (MODE) == V8SFmode || (MODE) == V4DFmode)) #define VALID_BCST_MODE_P(MODE) \ ((MODE) == SFmode || (MODE) == DFmode \ || (MODE) == SImode || (MODE) == DImode \ || (MODE) == HFmode) /* It is possible to write patterns to move flags; but until someone does it, */ #define AVOID_CCMODE_COPIES /* Specify the modes required to caller save a given hard regno. We do this on i386 to prevent flags from being saved at all. Kill any attempts to combine saving of modes. */ #define HARD_REGNO_CALLER_SAVE_MODE(REGNO, NREGS, MODE) \ (CC_REGNO_P (REGNO) ? VOIDmode \ : (MODE) == VOIDmode && (NREGS) != 1 ? VOIDmode \ : (MODE) == VOIDmode ? choose_hard_reg_mode ((REGNO), (NREGS), NULL) \ : (MODE) == HImode && !((GENERAL_REGNO_P (REGNO) \ && TARGET_PARTIAL_REG_STALL) \ || MASK_REGNO_P (REGNO)) ? SImode \ : (MODE) == QImode && !(ANY_QI_REGNO_P (REGNO) \ || MASK_REGNO_P (REGNO)) ? SImode \ : (MODE)) /* Specify the registers used for certain standard purposes. The values of these macros are register numbers. */ /* on the 386 the pc register is %eip, and is not usable as a general register. The ordinary mov instructions won't work */ /* #define PC_REGNUM */ /* Base register for access to arguments of the function. */ #define ARG_POINTER_REGNUM ARGP_REG /* Register to use for pushing function arguments. */ #define STACK_POINTER_REGNUM SP_REG /* Base register for access to local variables of the function. */ #define FRAME_POINTER_REGNUM FRAME_REG #define HARD_FRAME_POINTER_REGNUM BP_REG #define FIRST_INT_REG AX_REG #define LAST_INT_REG SP_REG #define FIRST_QI_REG AX_REG #define LAST_QI_REG BX_REG /* First & last stack-like regs */ #define FIRST_STACK_REG ST0_REG #define LAST_STACK_REG ST7_REG #define FIRST_SSE_REG XMM0_REG #define LAST_SSE_REG XMM7_REG #define FIRST_MMX_REG MM0_REG #define LAST_MMX_REG MM7_REG #define FIRST_REX_INT_REG R8_REG #define LAST_REX_INT_REG R15_REG #define FIRST_REX_SSE_REG XMM8_REG #define LAST_REX_SSE_REG XMM15_REG #define FIRST_EXT_REX_SSE_REG XMM16_REG #define LAST_EXT_REX_SSE_REG XMM31_REG #define FIRST_MASK_REG MASK0_REG #define LAST_MASK_REG MASK7_REG /* Override this in other tm.h files to cope with various OS lossage requiring a frame pointer. */ #ifndef SUBTARGET_FRAME_POINTER_REQUIRED #define SUBTARGET_FRAME_POINTER_REQUIRED 0 #endif /* Define the shadow offset for asan. Other OS's can override in the respective tm.h files. */ #ifndef SUBTARGET_SHADOW_OFFSET #define SUBTARGET_SHADOW_OFFSET \ (TARGET_LP64 ? HOST_WIDE_INT_C (0x7fff8000) : HOST_WIDE_INT_1 << 29) #endif /* Make sure we can access arbitrary call frames. */ #define SETUP_FRAME_ADDRESSES() ix86_setup_frame_addresses () /* Register to hold the addressing base for position independent code access to data items. We don't use PIC pointer for 64bit mode. Define the regnum to dummy value to prevent gcc from pessimizing code dealing with EBX. To avoid clobbering a call-saved register unnecessarily, we renumber the pic register when possible. The change is visible after the prologue has been emitted. */ #define REAL_PIC_OFFSET_TABLE_REGNUM (TARGET_64BIT ? R15_REG : BX_REG) #define PIC_OFFSET_TABLE_REGNUM \ (ix86_use_pseudo_pic_reg () \ ? (pic_offset_table_rtx \ ? INVALID_REGNUM \ : REAL_PIC_OFFSET_TABLE_REGNUM) \ : INVALID_REGNUM) #define GOT_SYMBOL_NAME "_GLOBAL_OFFSET_TABLE_" /* This is overridden by . */ #define MS_AGGREGATE_RETURN 0 #define KEEP_AGGREGATE_RETURN_POINTER 0