📄 sparc.c
字号:
target_flags &= ~(MASK_V8 | MASK_SPARCLET | MASK_SPARCLITE); } /* Use the deprecated v8 insns for sparc64 in 32 bit mode. */ if (TARGET_V9 && TARGET_ARCH32) target_flags |= MASK_DEPRECATED_V8_INSNS; /* V8PLUS requires V9, makes no sense in 64 bit mode. */ if (! TARGET_V9 || TARGET_ARCH64) target_flags &= ~MASK_V8PLUS; /* Don't use stack biasing in 32 bit mode. */ if (TARGET_ARCH32) target_flags &= ~MASK_STACK_BIAS; /* Supply a default value for align_functions. */ if (align_functions == 0 && (sparc_cpu == PROCESSOR_ULTRASPARC || sparc_cpu == PROCESSOR_ULTRASPARC3)) align_functions = 32; /* Validate PCC_STRUCT_RETURN. */ if (flag_pcc_struct_return == DEFAULT_PCC_STRUCT_RETURN) flag_pcc_struct_return = (TARGET_ARCH64 ? 0 : 1); /* Only use .uaxword when compiling for a 64-bit target. */ if (!TARGET_ARCH64) targetm.asm_out.unaligned_op.di = NULL; /* Do various machine dependent initializations. */ sparc_init_modes (); /* Set up function hooks. */ init_machine_status = sparc_init_machine_status;}/* Miscellaneous utilities. *//* Nonzero if CODE, a comparison, is suitable for use in v9 conditional move or branch on register contents instructions. */intv9_regcmp_p (enum rtx_code code){ return (code == EQ || code == NE || code == GE || code == LT || code == LE || code == GT);}/* Operand constraints. *//* Return nonzero only if OP is a register of mode MODE, or const0_rtx. */intreg_or_0_operand (rtx op, enum machine_mode mode){ if (register_operand (op, mode)) return 1; if (op == const0_rtx) return 1; if (GET_MODE (op) == VOIDmode && GET_CODE (op) == CONST_DOUBLE && CONST_DOUBLE_HIGH (op) == 0 && CONST_DOUBLE_LOW (op) == 0) return 1; if (fp_zero_operand (op, mode)) return 1; return 0;}/* Return nonzero only if OP is const1_rtx. */intconst1_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED){ return op == const1_rtx;}/* Nonzero if OP is a floating point value with value 0.0. */intfp_zero_operand (rtx op, enum machine_mode mode){ if (GET_MODE_CLASS (GET_MODE (op)) != MODE_FLOAT) return 0; return op == CONST0_RTX (mode);}/* Nonzero if OP is a register operand in floating point register. */intfp_register_operand (rtx op, enum machine_mode mode){ if (! register_operand (op, mode)) return 0; if (GET_CODE (op) == SUBREG) op = SUBREG_REG (op); return GET_CODE (op) == REG && SPARC_FP_REG_P (REGNO (op));}/* Nonzero if OP is a floating point constant which can be loaded into an integer register using a single sethi instruction. */intfp_sethi_p (rtx op){ if (GET_CODE (op) == CONST_DOUBLE) { REAL_VALUE_TYPE r; long i; REAL_VALUE_FROM_CONST_DOUBLE (r, op); if (REAL_VALUES_EQUAL (r, dconst0) && ! REAL_VALUE_MINUS_ZERO (r)) return 0; REAL_VALUE_TO_TARGET_SINGLE (r, i); if (SPARC_SETHI_P (i)) return 1; } return 0;}/* Nonzero if OP is a floating point constant which can be loaded into an integer register using a single mov instruction. */intfp_mov_p (rtx op){ if (GET_CODE (op) == CONST_DOUBLE) { REAL_VALUE_TYPE r; long i; REAL_VALUE_FROM_CONST_DOUBLE (r, op); if (REAL_VALUES_EQUAL (r, dconst0) && ! REAL_VALUE_MINUS_ZERO (r)) return 0; REAL_VALUE_TO_TARGET_SINGLE (r, i); if (SPARC_SIMM13_P (i)) return 1; } return 0;}/* Nonzero if OP is a floating point constant which can be loaded into an integer register using a high/losum instruction sequence. */intfp_high_losum_p (rtx op){ /* The constraints calling this should only be in SFmode move insns, so any constant which cannot be moved using a single insn will do. */ if (GET_CODE (op) == CONST_DOUBLE) { REAL_VALUE_TYPE r; long i; REAL_VALUE_FROM_CONST_DOUBLE (r, op); if (REAL_VALUES_EQUAL (r, dconst0) && ! REAL_VALUE_MINUS_ZERO (r)) return 0; REAL_VALUE_TO_TARGET_SINGLE (r, i); if (! SPARC_SETHI_P (i) && ! SPARC_SIMM13_P (i)) return 1; } return 0;}/* Nonzero if OP is an integer register. */intintreg_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED){ return (register_operand (op, SImode) || (TARGET_ARCH64 && register_operand (op, DImode)));}/* Nonzero if OP is a floating point condition code register. */intfcc_reg_operand (rtx op, enum machine_mode mode){ /* This can happen when recog is called from combine. Op may be a MEM. Fail instead of calling abort in this case. */ if (GET_CODE (op) != REG) return 0; if (mode != VOIDmode && mode != GET_MODE (op)) return 0; if (mode == VOIDmode && (GET_MODE (op) != CCFPmode && GET_MODE (op) != CCFPEmode)) return 0;#if 0 /* ??? ==> 1 when %fcc0-3 are pseudos first. See gen_compare_reg(). */ if (reg_renumber == 0) return REGNO (op) >= FIRST_PSEUDO_REGISTER; return REGNO_OK_FOR_CCFP_P (REGNO (op));#else return (unsigned) REGNO (op) - SPARC_FIRST_V9_FCC_REG < 4;#endif}/* Nonzero if OP is a floating point condition code fcc0 register. */intfcc0_reg_operand (rtx op, enum machine_mode mode){ /* This can happen when recog is called from combine. Op may be a MEM. Fail instead of calling abort in this case. */ if (GET_CODE (op) != REG) return 0; if (mode != VOIDmode && mode != GET_MODE (op)) return 0; if (mode == VOIDmode && (GET_MODE (op) != CCFPmode && GET_MODE (op) != CCFPEmode)) return 0; return REGNO (op) == SPARC_FCC_REG;}/* Nonzero if OP is an integer or floating point condition code register. */inticc_or_fcc_reg_operand (rtx op, enum machine_mode mode){ if (GET_CODE (op) == REG && REGNO (op) == SPARC_ICC_REG) { if (mode != VOIDmode && mode != GET_MODE (op)) return 0; if (mode == VOIDmode && GET_MODE (op) != CCmode && GET_MODE (op) != CCXmode) return 0; return 1; } return fcc_reg_operand (op, mode);}/* Nonzero if OP can appear as the dest of a RESTORE insn. */intrestore_operand (rtx op, enum machine_mode mode){ return (GET_CODE (op) == REG && GET_MODE (op) == mode && (REGNO (op) < 8 || (REGNO (op) >= 24 && REGNO (op) < 32)));}/* Call insn on SPARC can take a PC-relative constant address, or any regular memory address. */intcall_operand (rtx op, enum machine_mode mode){ if (GET_CODE (op) != MEM) abort (); op = XEXP (op, 0); return (symbolic_operand (op, mode) || memory_address_p (Pmode, op));}intcall_operand_address (rtx op, enum machine_mode mode){ return (symbolic_operand (op, mode) || memory_address_p (Pmode, op));}/* If OP is a SYMBOL_REF of a thread-local symbol, return its TLS mode, otherwise return 0. */inttls_symbolic_operand (rtx op){ if (GET_CODE (op) != SYMBOL_REF) return 0; return SYMBOL_REF_TLS_MODEL (op);}inttgd_symbolic_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED){ return tls_symbolic_operand (op) == TLS_MODEL_GLOBAL_DYNAMIC;}inttld_symbolic_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED){ return tls_symbolic_operand (op) == TLS_MODEL_LOCAL_DYNAMIC;}inttie_symbolic_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED){ return tls_symbolic_operand (op) == TLS_MODEL_INITIAL_EXEC;}inttle_symbolic_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED){ return tls_symbolic_operand (op) == TLS_MODEL_LOCAL_EXEC;}/* Returns 1 if OP is either a symbol reference or a sum of a symbol reference and a constant. */intsymbolic_operand (register rtx op, enum machine_mode mode){ enum machine_mode omode = GET_MODE (op); if (omode != mode && omode != VOIDmode && mode != VOIDmode) return 0; switch (GET_CODE (op)) { case SYMBOL_REF: return !SYMBOL_REF_TLS_MODEL (op); case LABEL_REF: return 1; case CONST: op = XEXP (op, 0); return (((GET_CODE (XEXP (op, 0)) == SYMBOL_REF && !SYMBOL_REF_TLS_MODEL (XEXP (op, 0))) || GET_CODE (XEXP (op, 0)) == LABEL_REF) && GET_CODE (XEXP (op, 1)) == CONST_INT); default: return 0; }}/* Return truth value of statement that OP is a symbolic memory operand of mode MODE. */intsymbolic_memory_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED){ if (GET_CODE (op) == SUBREG) op = SUBREG_REG (op); if (GET_CODE (op) != MEM) return 0; op = XEXP (op, 0); return ((GET_CODE (op) == SYMBOL_REF && !SYMBOL_REF_TLS_MODEL (op)) || GET_CODE (op) == CONST || GET_CODE (op) == HIGH || GET_CODE (op) == LABEL_REF);}/* Return truth value of statement that OP is a LABEL_REF of mode MODE. */intlabel_ref_operand (rtx op, enum machine_mode mode){ if (GET_CODE (op) != LABEL_REF) return 0; if (GET_MODE (op) != mode) return 0; return 1;}/* Return 1 if the operand is an argument used in generating pic references in either the medium/low or medium/anywhere code models of sparc64. */intsp64_medium_pic_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED){ /* Check for (const (minus (symbol_ref:GOT) (const (minus (label) (pc))))). */ if (GET_CODE (op) != CONST) return 0; op = XEXP (op, 0); if (GET_CODE (op) != MINUS) return 0; if (GET_CODE (XEXP (op, 0)) != SYMBOL_REF) return 0; /* ??? Ensure symbol is GOT. */ if (GET_CODE (XEXP (op, 1)) != CONST) return 0; if (GET_CODE (XEXP (XEXP (op, 1), 0)) != MINUS) return 0; return 1;}/* Return 1 if the operand is a data segment reference. This includes the readonly data segment, or in other words anything but the text segment. This is needed in the medium/anywhere code model on v9. These values are accessed with EMBMEDANY_BASE_REG. */intdata_segment_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED){ switch (GET_CODE (op)) { case SYMBOL_REF : return ! SYMBOL_REF_FUNCTION_P (op); case PLUS : /* Assume canonical format of symbol + constant. Fall through. */ case CONST : return data_segment_operand (XEXP (op, 0), VOIDmode); default : return 0; }}/* Return 1 if the operand is a text segment reference. This is needed in the medium/anywhere code model on v9. */inttext_segment_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED){ switch (GET_CODE (op)) { case LABEL_REF : return 1; case SYMBOL_REF : return SYMBOL_REF_FUNCTION_P (op); case PLUS : /* Assume canonical format of symbol + constant. Fall through. */ case CONST : return text_segment_operand (XEXP (op, 0), VOIDmode); default : return 0; }}/* Return 1 if the operand is either a register or a memory operand that is not symbolic. */intreg_or_nonsymb_mem_operand (register rtx op, enum machine_mode mode){ if (register_operand (op, mode)) return 1; if (memory_operand (op, mode) && ! symbolic_memory_operand (op, mode)) return 1; return 0;}intsplittable_symbolic_memory_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED){ if (GET_CODE (op) != MEM) return 0; if (! symbolic_operand (XEXP (op, 0), Pmode))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -