📄 sparc.c
字号:
#undef TARGET_RTX_COSTS#define TARGET_RTX_COSTS sparc_rtx_costs#undef TARGET_ADDRESS_COST#define TARGET_ADDRESS_COST hook_int_rtx_0/* This is only needed for TARGET_ARCH64, but since PROMOTE_FUNCTION_MODE is a no-op for TARGET_ARCH32 this is ok. Otherwise we'd need to add a runtime test for this value. */#undef TARGET_PROMOTE_FUNCTION_ARGS#define TARGET_PROMOTE_FUNCTION_ARGS hook_bool_tree_true/* This is only needed for TARGET_ARCH64, but since PROMOTE_FUNCTION_MODE is a no-op for TARGET_ARCH32 this is ok. Otherwise we'd need to add a runtime test for this value. */#undef TARGET_PROMOTE_FUNCTION_RETURN#define TARGET_PROMOTE_FUNCTION_RETURN hook_bool_tree_true#undef TARGET_PROMOTE_PROTOTYPES#define TARGET_PROMOTE_PROTOTYPES sparc_promote_prototypes#undef TARGET_STRUCT_VALUE_RTX#define TARGET_STRUCT_VALUE_RTX sparc_struct_value_rtx#undef TARGET_RETURN_IN_MEMORY#define TARGET_RETURN_IN_MEMORY sparc_return_in_memory#undef TARGET_MUST_PASS_IN_STACK#define TARGET_MUST_PASS_IN_STACK must_pass_in_stack_var_size#undef TARGET_PASS_BY_REFERENCE#define TARGET_PASS_BY_REFERENCE sparc_pass_by_reference#undef TARGET_ARG_PARTIAL_BYTES#define TARGET_ARG_PARTIAL_BYTES sparc_arg_partial_bytes#undef TARGET_EXPAND_BUILTIN_SAVEREGS#define TARGET_EXPAND_BUILTIN_SAVEREGS sparc_builtin_saveregs#undef TARGET_STRICT_ARGUMENT_NAMING#define TARGET_STRICT_ARGUMENT_NAMING sparc_strict_argument_naming#undef TARGET_GIMPLIFY_VA_ARG_EXPR#define TARGET_GIMPLIFY_VA_ARG_EXPR sparc_gimplify_va_arg#undef TARGET_VECTOR_MODE_SUPPORTED_P#define TARGET_VECTOR_MODE_SUPPORTED_P sparc_vector_mode_supported_p#undef TARGET_DWARF_HANDLE_FRAME_UNSPEC#define TARGET_DWARF_HANDLE_FRAME_UNSPEC sparc_dwarf_handle_frame_unspec#ifdef SUBTARGET_INSERT_ATTRIBUTES#undef TARGET_INSERT_ATTRIBUTES#define TARGET_INSERT_ATTRIBUTES SUBTARGET_INSERT_ATTRIBUTES#endif#ifdef SUBTARGET_ATTRIBUTE_TABLE#undef TARGET_ATTRIBUTE_TABLE#define TARGET_ATTRIBUTE_TABLE sparc_attribute_table#endif#undef TARGET_RELAXED_ORDERING#define TARGET_RELAXED_ORDERING SPARC_RELAXED_ORDERING#undef TARGET_ASM_FILE_END#define TARGET_ASM_FILE_END sparc_file_endstruct gcc_target targetm = TARGET_INITIALIZER;/* Validate and override various options, and do some machine dependent initialization. */voidsparc_override_options (void){ static struct code_model { const char *const name; const int value; } const cmodels[] = { { "32", CM_32 }, { "medlow", CM_MEDLOW }, { "medmid", CM_MEDMID }, { "medany", CM_MEDANY }, { "embmedany", CM_EMBMEDANY }, { 0, 0 } }; const struct code_model *cmodel; /* Map TARGET_CPU_DEFAULT to value for -m{arch,tune}=. */ static struct cpu_default { const int cpu; const char *const name; } const cpu_default[] = { /* There must be one entry here for each TARGET_CPU value. */ { TARGET_CPU_sparc, "cypress" }, { TARGET_CPU_sparclet, "tsc701" }, { TARGET_CPU_sparclite, "f930" }, { TARGET_CPU_v8, "v8" }, { TARGET_CPU_hypersparc, "hypersparc" }, { TARGET_CPU_sparclite86x, "sparclite86x" }, { TARGET_CPU_supersparc, "supersparc" }, { TARGET_CPU_v9, "v9" }, { TARGET_CPU_ultrasparc, "ultrasparc" }, { TARGET_CPU_ultrasparc3, "ultrasparc3" }, { 0, 0 } }; const struct cpu_default *def; /* Table of values for -m{cpu,tune}=. */ static struct cpu_table { const char *const name; const enum processor_type processor; const int disable; const int enable; } const cpu_table[] = { { "v7", PROCESSOR_V7, MASK_ISA, 0 }, { "cypress", PROCESSOR_CYPRESS, MASK_ISA, 0 }, { "v8", PROCESSOR_V8, MASK_ISA, MASK_V8 }, /* TI TMS390Z55 supersparc */ { "supersparc", PROCESSOR_SUPERSPARC, MASK_ISA, MASK_V8 }, { "sparclite", PROCESSOR_SPARCLITE, MASK_ISA, MASK_SPARCLITE }, /* The Fujitsu MB86930 is the original sparclite chip, with no fpu. The Fujitsu MB86934 is the recent sparclite chip, with an fpu. */ { "f930", PROCESSOR_F930, MASK_ISA|MASK_FPU, MASK_SPARCLITE }, { "f934", PROCESSOR_F934, MASK_ISA, MASK_SPARCLITE|MASK_FPU }, { "hypersparc", PROCESSOR_HYPERSPARC, MASK_ISA, MASK_V8|MASK_FPU }, { "sparclite86x", PROCESSOR_SPARCLITE86X, MASK_ISA|MASK_FPU, MASK_SPARCLITE }, { "sparclet", PROCESSOR_SPARCLET, MASK_ISA, MASK_SPARCLET }, /* TEMIC sparclet */ { "tsc701", PROCESSOR_TSC701, MASK_ISA, MASK_SPARCLET }, { "v9", PROCESSOR_V9, MASK_ISA, MASK_V9 }, /* TI ultrasparc I, II, IIi */ { "ultrasparc", PROCESSOR_ULTRASPARC, MASK_ISA, MASK_V9 /* Although insns using %y are deprecated, it is a clear win on current ultrasparcs. */ |MASK_DEPRECATED_V8_INSNS}, /* TI ultrasparc III */ /* ??? Check if %y issue still holds true in ultra3. */ { "ultrasparc3", PROCESSOR_ULTRASPARC3, MASK_ISA, MASK_V9|MASK_DEPRECATED_V8_INSNS}, { 0, 0, 0, 0 } }; const struct cpu_table *cpu; const struct sparc_cpu_select *sel; int fpu; #ifndef SPARC_BI_ARCH /* Check for unsupported architecture size. */ if (! TARGET_64BIT != DEFAULT_ARCH32_P) error ("%s is not supported by this configuration", DEFAULT_ARCH32_P ? "-m64" : "-m32");#endif /* We force all 64bit archs to use 128 bit long double */ if (TARGET_64BIT && ! TARGET_LONG_DOUBLE_128) { error ("-mlong-double-64 not allowed with -m64"); target_flags |= MASK_LONG_DOUBLE_128; } /* Code model selection. */ sparc_cmodel = SPARC_DEFAULT_CMODEL; #ifdef SPARC_BI_ARCH if (TARGET_ARCH32) sparc_cmodel = CM_32;#endif if (sparc_cmodel_string != NULL) { if (TARGET_ARCH64) { for (cmodel = &cmodels[0]; cmodel->name; cmodel++) if (strcmp (sparc_cmodel_string, cmodel->name) == 0) break; if (cmodel->name == NULL) error ("bad value (%s) for -mcmodel= switch", sparc_cmodel_string); else sparc_cmodel = cmodel->value; } else error ("-mcmodel= is not supported on 32 bit systems"); } fpu = TARGET_FPU; /* save current -mfpu status */ /* Set the default CPU. */ for (def = &cpu_default[0]; def->name; ++def) if (def->cpu == TARGET_CPU_DEFAULT) break; if (! def->name) abort (); sparc_select[0].string = def->name; for (sel = &sparc_select[0]; sel->name; ++sel) { if (sel->string) { for (cpu = &cpu_table[0]; cpu->name; ++cpu) if (! strcmp (sel->string, cpu->name)) { if (sel->set_tune_p) sparc_cpu = cpu->processor; if (sel->set_arch_p) { target_flags &= ~cpu->disable; target_flags |= cpu->enable; } break; } if (! cpu->name) error ("bad value (%s) for %s switch", sel->string, sel->name); } } /* If -mfpu or -mno-fpu was explicitly used, don't override with the processor default. Clear MASK_FPU_SET to avoid confusing the reverse mapping from switch values to names. */ if (TARGET_FPU_SET) { target_flags = (target_flags & ~MASK_FPU) | fpu; target_flags &= ~MASK_FPU_SET; } /* Don't allow -mvis if FPU is disabled. */ if (! TARGET_FPU) target_flags &= ~MASK_VIS; /* -mvis assumes UltraSPARC+, so we are sure v9 instructions are available. -m64 also implies v9. */ if (TARGET_VIS || TARGET_ARCH64) { target_flags |= MASK_V9; 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 (); /* Acquire a unique set number for our register saves and restores. */ sparc_sr_alias_set = new_alias_set (); /* Set up function hooks. */ init_machine_status = sparc_init_machine_status; switch (sparc_cpu) { case PROCESSOR_V7: case PROCESSOR_CYPRESS: sparc_costs = &cypress_costs; break; case PROCESSOR_V8: case PROCESSOR_SPARCLITE: case PROCESSOR_SUPERSPARC: sparc_costs = &supersparc_costs; break; case PROCESSOR_F930: case PROCESSOR_F934: case PROCESSOR_HYPERSPARC: case PROCESSOR_SPARCLITE86X: sparc_costs = &hypersparc_costs; break; case PROCESSOR_SPARCLET: case PROCESSOR_TSC701: sparc_costs = &sparclet_costs; break; case PROCESSOR_V9: case PROCESSOR_ULTRASPARC: sparc_costs = &ultrasparc_costs; break; case PROCESSOR_ULTRASPARC3: sparc_costs = &ultrasparc3_costs; break; };}#ifdef SUBTARGET_ATTRIBUTE_TABLE/* Table of valid machine attributes. */const struct attribute_spec sparc_attribute_table[] ={ /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */ SUBTARGET_ATTRIBUTE_TABLE, { NULL, 0, 0, false, false, false, NULL }};#endif/* 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){ enum mode_class mclass = GET_MODE_CLASS (GET_MODE (op)); if (mclass != MODE_FLOAT && mclass != MODE_VECTOR_INT) 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; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -