📄 rs6000.c
字号:
/* MPC604EUM 3.5.2 Weak Consistency between Multiple Processors The PowerPC architecture requires only weak consistency among processors--that is, memory accesses between processors need not be sequentially consistent and memory accesses among processors can occur in any order. The ability to order memory accesses weakly provides opportunities for more efficient use of the system bus. Unless a dependency exists, the 604e allows read operations to precede store operations. */#undef TARGET_RELAXED_ORDERING#define TARGET_RELAXED_ORDERING truestruct gcc_target targetm = TARGET_INITIALIZER;/* Value is 1 if hard register REGNO can hold a value of machine-mode MODE. */static intrs6000_hard_regno_mode_ok (int regno, enum machine_mode mode){ /* The GPRs can hold any mode, but values bigger than one register cannot go past R31. */ if (INT_REGNO_P (regno)) return INT_REGNO_P (regno + HARD_REGNO_NREGS (regno, mode) - 1); /* The float registers can only hold floating modes and DImode. */ if (FP_REGNO_P (regno)) return (GET_MODE_CLASS (mode) == MODE_FLOAT && FP_REGNO_P (regno + HARD_REGNO_NREGS (regno, mode) - 1)) || (GET_MODE_CLASS (mode) == MODE_INT && GET_MODE_SIZE (mode) == UNITS_PER_FP_WORD); /* The CR register can only hold CC modes. */ if (CR_REGNO_P (regno)) return GET_MODE_CLASS (mode) == MODE_CC; if (XER_REGNO_P (regno)) return mode == PSImode; /* AltiVec only in AldyVec registers. */ if (ALTIVEC_REGNO_P (regno)) return ALTIVEC_VECTOR_MODE (mode); /* ...but GPRs can hold SIMD data on the SPE in one register. */ if (SPE_SIMD_REGNO_P (regno) && TARGET_SPE && SPE_VECTOR_MODE (mode)) return 1; /* We cannot put TImode anywhere except general register and it must be able to fit within the register set. */ return GET_MODE_SIZE (mode) <= UNITS_PER_WORD;}/* Initialize rs6000_hard_regno_mode_ok_p table. */static voidrs6000_init_hard_regno_mode_ok (void){ int r, m; for (r = 0; r < FIRST_PSEUDO_REGISTER; ++r) for (m = 0; m < NUM_MACHINE_MODES; ++m) if (rs6000_hard_regno_mode_ok (r, m)) rs6000_hard_regno_mode_ok_p[m][r] = true;}/* If not otherwise specified by a target, make 'long double' equivalent to 'double'. */#ifndef RS6000_DEFAULT_LONG_DOUBLE_SIZE#define RS6000_DEFAULT_LONG_DOUBLE_SIZE 64#endif/* Override command line options. Mostly we process the processor type and sometimes adjust other TARGET_ options. */voidrs6000_override_options (const char *default_cpu){ size_t i, j; struct rs6000_cpu_select *ptr; int set_masks; /* APPLE LOCAL -fast */ enum processor_type mcpu_cpu = PROCESSOR_POWER4; /* Simplifications for entries below. */ enum { POWERPC_BASE_MASK = MASK_POWERPC | MASK_NEW_MNEMONICS, POWERPC_7400_MASK = POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_ALTIVEC }; /* This table occasionally claims that a processor does not support a particular feature even though it does, but the feature is slower than the alternative. Thus, it shouldn't be relied on as a complete description of the processor's support. Please keep this list in order, and don't forget to update the documentation in invoke.texi when adding a new processor or flag. */ static struct ptt { const char *const name; /* Canonical processor name. */ const enum processor_type processor; /* Processor type enum value. */ const int target_enable; /* Target flags to enable. */ } const processor_target_table[] = {{"401", PROCESSOR_PPC403, POWERPC_BASE_MASK | MASK_SOFT_FLOAT}, {"403", PROCESSOR_PPC403, POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_STRICT_ALIGN}, {"405", PROCESSOR_PPC405, POWERPC_BASE_MASK | MASK_SOFT_FLOAT}, {"405fp", PROCESSOR_PPC405, POWERPC_BASE_MASK}, {"440", PROCESSOR_PPC440, POWERPC_BASE_MASK | MASK_SOFT_FLOAT}, {"440fp", PROCESSOR_PPC440, POWERPC_BASE_MASK}, {"505", PROCESSOR_MPCCORE, POWERPC_BASE_MASK}, {"601", PROCESSOR_PPC601, MASK_POWER | POWERPC_BASE_MASK | MASK_MULTIPLE | MASK_STRING}, {"602", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT}, {"603", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT}, {"603e", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT}, {"604", PROCESSOR_PPC604, POWERPC_BASE_MASK | MASK_PPC_GFXOPT}, {"604e", PROCESSOR_PPC604e, POWERPC_BASE_MASK | MASK_PPC_GFXOPT}, {"620", PROCESSOR_PPC620, POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64}, {"630", PROCESSOR_PPC630, POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64}, {"740", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT}, {"7400", PROCESSOR_PPC7400, POWERPC_7400_MASK}, {"7450", PROCESSOR_PPC7450, POWERPC_7400_MASK}, {"750", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT}, {"801", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT}, {"821", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT}, {"823", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT}, {"8540", PROCESSOR_PPC8540, POWERPC_BASE_MASK | MASK_PPC_GFXOPT}, /* 8548 has a dummy entry for now. */ {"8548", PROCESSOR_PPC8540, POWERPC_BASE_MASK | MASK_PPC_GFXOPT}, {"860", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT}, {"970", PROCESSOR_POWER4, POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64}, {"common", PROCESSOR_COMMON, MASK_NEW_MNEMONICS}, {"ec603e", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_SOFT_FLOAT}, {"G3", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT}, {"G4", PROCESSOR_PPC7450, POWERPC_7400_MASK}, {"G5", PROCESSOR_POWER4, POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64}, {"power", PROCESSOR_POWER, MASK_POWER | MASK_MULTIPLE | MASK_STRING}, {"power2", PROCESSOR_POWER, MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING}, {"power3", PROCESSOR_PPC630, POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64}, {"power4", PROCESSOR_POWER4, POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_MFCRF | MASK_POWERPC64}, {"power5", PROCESSOR_POWER5, POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_MFCRF | MASK_POWERPC64}, {"powerpc", PROCESSOR_POWERPC, POWERPC_BASE_MASK}, {"powerpc64", PROCESSOR_POWERPC64, POWERPC_BASE_MASK | MASK_POWERPC64}, {"rios", PROCESSOR_RIOS1, MASK_POWER | MASK_MULTIPLE | MASK_STRING}, {"rios1", PROCESSOR_RIOS1, MASK_POWER | MASK_MULTIPLE | MASK_STRING}, {"rios2", PROCESSOR_RIOS2, MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING}, {"rsc", PROCESSOR_PPC601, MASK_POWER | MASK_MULTIPLE | MASK_STRING}, {"rsc1", PROCESSOR_PPC601, MASK_POWER | MASK_MULTIPLE | MASK_STRING}, {"rs64a", PROCESSOR_RS64A, POWERPC_BASE_MASK | MASK_POWERPC64}, }; const size_t ptt_size = ARRAY_SIZE (processor_target_table); /* APPLE LOCAL begin -mmultiple/-mstring fixme */ /* Save current -mmultiple/-mno-multiple status. */ int multiple = TARGET_MULTIPLE; /* Save current -mstring/-mno-string status. */ int string = TARGET_STRING; /* APPLE LOCAL end -mmultiple/-mstring fixme */ /* Some OSs don't support saving the high part of 64-bit registers on context switch. Other OSs don't support saving Altivec registers. On those OSs, we don't touch the MASK_POWERPC64 or MASK_ALTIVEC settings; if the user wants either, the user must explicitly specify them and we won't interfere with the user's specification. */ enum { POWER_MASKS = MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING, POWERPC_MASKS = (POWERPC_BASE_MASK | MASK_PPC_GPOPT | MASK_PPC_GFXOPT | MASK_POWERPC64 | MASK_ALTIVEC | MASK_MFCRF) }; rs6000_init_hard_regno_mode_ok (); set_masks = POWER_MASKS | POWERPC_MASKS | MASK_SOFT_FLOAT;#ifdef OS_MISSING_POWERPC64 if (OS_MISSING_POWERPC64) set_masks &= ~MASK_POWERPC64;#endif#ifdef OS_MISSING_ALTIVEC if (OS_MISSING_ALTIVEC) set_masks &= ~MASK_ALTIVEC;#endif /* Don't override by the processor default if given explicitly. */ set_masks &= ~target_flags_explicit; /* Identify the processor type. */ rs6000_select[0].string = default_cpu; rs6000_cpu = TARGET_POWERPC64 ? PROCESSOR_DEFAULT64 : PROCESSOR_DEFAULT; /* APPLE LOCAL begin -fast */ if (flag_fast || flag_fastf || flag_fastcp) { if (rs6000_select[1].string == (char *)0 && rs6000_select[2].string == (char *)0) { /* -mcpu and -mtune unspecified. Assume both are G5 */ set_target_switch ("tune=G5"); set_target_switch ("cpu=G5"); } } /* APPLE LOCAL end -fast */ for (i = 0; i < ARRAY_SIZE (rs6000_select); i++) { ptr = &rs6000_select[i]; if (ptr->string != (char *)0 && ptr->string[0] != '\0') { for (j = 0; j < ptt_size; j++) if (! strcmp (ptr->string, processor_target_table[j].name)) { if (ptr->set_tune_p) rs6000_cpu = processor_target_table[j].processor; if (ptr->set_arch_p) { target_flags &= ~set_masks; target_flags |= (processor_target_table[j].target_enable & set_masks); /* APPLE LOCAL begin -fast */ mcpu_cpu = processor_target_table[j].processor; /* APPLE LOCAL end -fast */ } break; } if (j == ptt_size) error ("bad value (%s) for %s switch", ptr->string, ptr->name); } } /* APPLE LOCAL begin AltiVec */ /* If '-maltivec' has been specified or if anything else turns on AltiVec, enable AltiVec optimizations, even if previously turned off via '-faltivec'. */ if (TARGET_ALTIVEC) flag_disable_opts_for_faltivec = 0; /* Handle -m(no-)pim-altivec. */ if (rs6000_altivec_pim_switch) { const char *base = rs6000_altivec_pim_switch - strlen ("pim-altivec");; while (base[-1] != 'm') base--; if (*rs6000_altivec_pim_switch != '\0') error ("invalid option `%s'", base); rs6000_altivec_pim = (base[0] != 'n'); /* If '-faltivec' or '-mpim-altivec' has been specified and we have not already selected AltiVec codegen, disable certain unsafe AltiVec optimizations so that the resulting binary can run on a G3. These may be re-enabled by subsequently specifying '-maltivec' or '-mcpu=xxx', where xxx supports AltiVec instructions. */ if (rs6000_altivec_pim) { if (! TARGET_ALTIVEC) { flag_disable_opts_for_faltivec = 1; /* APPLE LOCAL radar 4161346 */ target_flags |= (MASK_ALTIVEC | MASK_PIM_ALTIVEC); } } else target_flags &= ~MASK_ALTIVEC; } /* APPLE LOCAL end AltiVec */ /* APPLE LOCAL begin -fast */ if (flag_fast || flag_fastf || flag_fastcp) { flag_gcse_sm = 1; rs6000_sched_insert_nops = sched_finish_regroup_exact; flag_unroll_loops = 1; flag_tree_loop_linear = 1; flag_strict_aliasing = 1; flag_schedule_interblock = 1; flag_gcse_las = 1; align_jumps_max_skip = 15; align_loops_max_skip = 15; align_functions = 16; align_loops = 16; align_jumps = 16; set_fast_math_flags (1); flag_reorder_blocks = 1; if (flag_branch_probabilities && !flag_exceptions) flag_reorder_blocks_and_partition = 1; if (!flag_pic) set_target_switch ("dynamic-no-pic"); if (mcpu_cpu == PROCESSOR_POWER4) { set_target_switch ("powerpc-gpopt"); set_target_switch ("powerpc64"); } if (flag_fast || flag_fastcp) /* This doesn't work with NAG Fortran output. The gcc 3.5 C++ libraries have been adjusted so that it now works with them. */ set_target_switch ("align-natural"); if (flag_fastf) /* This applies Fortran argument semantics; for NAG Fortran output only. */ flag_argument_noalias = 2; /* IMI flags */ disable_typechecking_for_spec_flag = 1; flag_unit_at_a_time = 1; } /* APPLE LOCAL end -fast */ /* APPLE LOCAL rs6000_init_hard_regno_mode_ok must come AFTER setting of -fast flags */ rs6000_init_hard_regno_mode_ok (); if (TARGET_E500) rs6000_isel = 1; /* APPLE LOCAL begin Disable string insns with -Os on Darwin (radar 3509006) */ /* If we are optimizing big endian systems for space, use the load/store multiple instructions. */ if (BYTES_BIG_ENDIAN && optimize_size) target_flags |= ~target_flags_explicit & MASK_MULTIPLE; /* If we are optimizing big endian systems for space, use the string instructions. But do not do this for Darwin, as the kernel can't properly support some hardware that doesn't have these instructions. It's not clear that the compiler is the right place to fix this, but that's how it is for now. See *extensive* discussion in Radar 3509006. */ if (BYTES_BIG_ENDIAN && optimize_size && DEFAULT_ABI != ABI_DARWIN) target_flags |= MASK_STRING; /* APPLE LOCAL end Disable string insns with -Os on Darwin (radar 3509006) */ /* APPLE LOCAL begin -mmultiple/-mstring fixme */ /* If -mmultiple or -mno-multiple was explicitly used, don't override with the processor default */ if ((target_flags_explicit & MASK_MULTIPLE) != 0) target_flags = (target_flags & ~MASK_MULTIPLE) | multiple; /* If -mstring or -mno-string was explicitly used, don't override with the processor default. */ if ((target_flags_explicit & MASK_STRING) != 0) target_flags = (target_flags & ~MASK_STRING) | string; /* APPLE LOCAL end -mmultiple/-mstring fixme */ /* Don't allow -mmultiple or -mstring on little endian systems unless the cpu is a 750, because the hardware doesn't support the instructions used in little endian mode, and causes an alignment trap. The 750 does not cause an alignment trap (except when the target is unaligned). */ if (!BYTES_BIG_ENDIAN && rs6000_cpu != PROCESSOR_PPC750) { if (TARGET_MULTIPLE) { target_flags &= ~MASK_MULTIPLE; if ((target_flags_explicit & MASK_MULTIPLE) != 0)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -