📄 rs6000.c
字号:
MASK_POWER | MASK_MULTIPLE | MASK_STRING, MASK_POWER2 | POWERPC_MASKS | MASK_NEW_MNEMONICS}, {"rios2", PROCESSOR_RIOS2, MASK_POWER | MASK_MULTIPLE | MASK_STRING | MASK_POWER2, POWERPC_MASKS | MASK_NEW_MNEMONICS}, {"rs64a", PROCESSOR_RS64A, MASK_POWERPC | MASK_NEW_MNEMONICS, POWER_MASKS | POWERPC_OPT_MASKS}, {"401", PROCESSOR_PPC403, MASK_POWERPC | MASK_SOFT_FLOAT | MASK_NEW_MNEMONICS, POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64}, {"403", PROCESSOR_PPC403, MASK_POWERPC | MASK_SOFT_FLOAT | MASK_NEW_MNEMONICS | MASK_STRICT_ALIGN, POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64}, {"405", PROCESSOR_PPC405, MASK_POWERPC | MASK_SOFT_FLOAT | MASK_NEW_MNEMONICS, POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64}, {"505", PROCESSOR_MPCCORE, MASK_POWERPC | MASK_NEW_MNEMONICS, POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64}, {"601", PROCESSOR_PPC601, MASK_POWER | MASK_POWERPC | MASK_NEW_MNEMONICS | MASK_MULTIPLE | MASK_STRING, MASK_POWER2 | POWERPC_OPT_MASKS | MASK_POWERPC64}, {"602", PROCESSOR_PPC603, MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS, POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64}, {"603", PROCESSOR_PPC603, MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS, POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64}, {"603e", PROCESSOR_PPC603, MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS, POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64}, {"ec603e", PROCESSOR_PPC603, MASK_POWERPC | MASK_SOFT_FLOAT | MASK_NEW_MNEMONICS, POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64}, {"604", PROCESSOR_PPC604, MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS, POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64}, {"604e", PROCESSOR_PPC604e, MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS, POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64}, {"620", PROCESSOR_PPC620, MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS, POWER_MASKS | MASK_PPC_GPOPT}, {"630", PROCESSOR_PPC630, MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS, POWER_MASKS | MASK_PPC_GPOPT}, {"740", PROCESSOR_PPC750, MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS, POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64}, {"750", PROCESSOR_PPC750, MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS, POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64}, {"7400", PROCESSOR_PPC7400, MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS, POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64}, {"7450", PROCESSOR_PPC7450, MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS, POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64}, {"8540", PROCESSOR_PPC8540, MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS, POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64}, {"801", PROCESSOR_MPCCORE, MASK_POWERPC | MASK_SOFT_FLOAT | MASK_NEW_MNEMONICS, POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64}, {"821", PROCESSOR_MPCCORE, MASK_POWERPC | MASK_SOFT_FLOAT | MASK_NEW_MNEMONICS, POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64}, {"823", PROCESSOR_MPCCORE, MASK_POWERPC | MASK_SOFT_FLOAT | MASK_NEW_MNEMONICS, POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64}, {"860", PROCESSOR_MPCCORE, MASK_POWERPC | MASK_SOFT_FLOAT | MASK_NEW_MNEMONICS, POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64}}; const size_t ptt_size = ARRAY_SIZE (processor_target_table); /* Save current -mmultiple/-mno-multiple status. */ int multiple = TARGET_MULTIPLE; /* Save current -mstring/-mno-string status. */ int string = TARGET_STRING; /* Identify the processor type. */ rs6000_select[0].string = default_cpu; rs6000_cpu = TARGET_POWERPC64 ? PROCESSOR_DEFAULT64 : PROCESSOR_DEFAULT; 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 |= processor_target_table[j].target_enable; target_flags &= ~processor_target_table[j].target_disable; } break; } if (j == ptt_size) error ("bad value (%s) for %s switch", ptr->string, ptr->name); } } if (rs6000_cpu == PROCESSOR_PPC8540) rs6000_isel = 1; /* If we are optimizing big endian systems for space, use the load/store multiple and string instructions. */ if (BYTES_BIG_ENDIAN && optimize_size) target_flags |= MASK_MULTIPLE | MASK_STRING; /* If -mmultiple or -mno-multiple was explicitly used, don't override with the processor default */ if (TARGET_MULTIPLE_SET) target_flags = (target_flags & ~MASK_MULTIPLE) | multiple; /* If -mstring or -mno-string was explicitly used, don't override with the processor default. */ if (TARGET_STRING_SET) target_flags = (target_flags & ~MASK_STRING) | string; /* 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_MULTIPLE_SET) warning ("-mmultiple is not supported on little endian systems"); } if (TARGET_STRING) { target_flags &= ~MASK_STRING; if (TARGET_STRING_SET) warning ("-mstring is not supported on little endian systems"); } } if (flag_pic != 0 && DEFAULT_ABI == ABI_AIX) { rs6000_flag_pic = flag_pic; flag_pic = 0; } /* For Darwin, always silently make -fpic and -fPIC identical. */ if (flag_pic == 1 && DEFAULT_ABI == ABI_DARWIN) flag_pic = 2; /* Set debug flags */ if (rs6000_debug_name) { if (! strcmp (rs6000_debug_name, "all")) rs6000_debug_stack = rs6000_debug_arg = 1; else if (! strcmp (rs6000_debug_name, "stack")) rs6000_debug_stack = 1; else if (! strcmp (rs6000_debug_name, "arg")) rs6000_debug_arg = 1; else error ("unknown -mdebug-%s switch", rs6000_debug_name); } if (rs6000_traceback_name) { if (! strncmp (rs6000_traceback_name, "full", 4)) rs6000_traceback = traceback_full; else if (! strncmp (rs6000_traceback_name, "part", 4)) rs6000_traceback = traceback_part; else if (! strncmp (rs6000_traceback_name, "no", 2)) rs6000_traceback = traceback_none; else error ("unknown -mtraceback arg `%s'; expecting `full', `partial' or `none'", rs6000_traceback_name); } /* Set size of long double */ rs6000_long_double_type_size = 64; if (rs6000_long_double_size_string) { char *tail; int size = strtol (rs6000_long_double_size_string, &tail, 10); if (*tail != '\0' || (size != 64 && size != 128)) error ("Unknown switch -mlong-double-%s", rs6000_long_double_size_string); else rs6000_long_double_type_size = size; } /* Handle -mabi= options. */ rs6000_parse_abi_options (); /* Handle -mvrsave= option. */ rs6000_parse_vrsave_option (); /* Handle -misel= option. */ rs6000_parse_isel_option ();#ifdef SUBTARGET_OVERRIDE_OPTIONS SUBTARGET_OVERRIDE_OPTIONS;#endif#ifdef SUBSUBTARGET_OVERRIDE_OPTIONS SUBSUBTARGET_OVERRIDE_OPTIONS;#endif /* Handle -m(no-)longcall option. This is a bit of a cheap hack, using TARGET_OPTIONS to handle a toggle switch, but we're out of bits in target_flags so TARGET_SWITCHES cannot be used. Assumption here is that rs6000_longcall_switch points into the text of the complete option, rather than being a copy, so we can scan back for the presence or absence of the no- modifier. */ if (rs6000_longcall_switch) { const char *base = rs6000_longcall_switch; while (base[-1] != 'm') base--; if (*rs6000_longcall_switch != '\0') error ("invalid option `%s'", base); rs6000_default_long_calls = (base[0] != 'n'); }#ifdef TARGET_REGNAMES /* If the user desires alternate register names, copy in the alternate names now. */ if (TARGET_REGNAMES) memcpy (rs6000_reg_names, alt_reg_names, sizeof (rs6000_reg_names));#endif /* Set TARGET_AIX_STRUCT_RET last, after the ABI is determined. If -maix-struct-return or -msvr4-struct-return was explicitly used, don't override with the ABI default. */ if (!(target_flags & MASK_AIX_STRUCT_RET_SET)) { if (DEFAULT_ABI == ABI_V4 && !DRAFT_V4_STRUCT_RET) target_flags = (target_flags & ~MASK_AIX_STRUCT_RET); else target_flags |= MASK_AIX_STRUCT_RET; } if (TARGET_LONG_DOUBLE_128 && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN)) real_format_for_mode[TFmode - QFmode] = &ibm_extended_format; /* Register global variables with the garbage collector. */ rs6000_add_gc_roots (); /* Allocate an alias set for register saves & restores from stack. */ rs6000_sr_alias_set = new_alias_set (); if (TARGET_TOC) ASM_GENERATE_INTERNAL_LABEL (toc_label_name, "LCTOC", 1); /* We can only guarantee the availability of DI pseudo-ops when assembling for 64-bit targets. */ if (!TARGET_64BIT) { targetm.asm_out.aligned_op.di = NULL; targetm.asm_out.unaligned_op.di = NULL; } /* Arrange to save and restore machine status around nested functions. */ init_machine_status = rs6000_init_machine_status;}/* Handle -misel= option. */static voidrs6000_parse_isel_option (){ if (rs6000_isel_string == 0) return; else if (! strcmp (rs6000_isel_string, "yes")) rs6000_isel = 1; else if (! strcmp (rs6000_isel_string, "no")) rs6000_isel = 0; else error ("unknown -misel= option specified: '%s'", rs6000_isel_string);}/* Handle -mvrsave= options. */static voidrs6000_parse_vrsave_option (){ /* Generate VRSAVE instructions by default. */ if (rs6000_altivec_vrsave_string == 0 || ! strcmp (rs6000_altivec_vrsave_string, "yes")) rs6000_altivec_vrsave = 1; else if (! strcmp (rs6000_altivec_vrsave_string, "no")) rs6000_altivec_vrsave = 0; else error ("unknown -mvrsave= option specified: '%s'", rs6000_altivec_vrsave_string);}/* Handle -mabi= options. */static voidrs6000_parse_abi_options (){ if (rs6000_abi_string == 0) return; else if (! strcmp (rs6000_abi_string, "altivec")) rs6000_altivec_abi = 1; else if (! strcmp (rs6000_abi_string, "no-altivec")) rs6000_altivec_abi = 0; else if (! strcmp (rs6000_abi_string, "spe")) rs6000_spe_abi = 1; else if (! strcmp (rs6000_abi_string, "no-spe")) rs6000_spe_abi = 0; else error ("unknown ABI specified: '%s'", rs6000_abi_string);}voidoptimization_options (level, size) int level ATTRIBUTE_UNUSED; int size ATTRIBUTE_UNUSED;{}/* Do anything needed at the start of the asm file. */voidrs6000_file_start (file, default_cpu) FILE *file; const char *default_cpu;{ size_t i; char buffer[80]; const char *start = buffer; struct rs6000_cpu_select *ptr; if (flag_verbose_asm) { sprintf (buffer, "\n%s rs6000/powerpc options:", ASM_COMMENT_START); rs6000_select[0].string = default_cpu; for (i = 0; i < ARRAY_SIZE (rs6000_select); i++) { ptr = &rs6000_select[i]; if (ptr->string != (char *)0 && ptr->string[0] != '\0') { fprintf (file, "%s %s%s", start, ptr->name, ptr->string); start = ""; } }#ifdef USING_ELFOS_H switch (rs6000_sdata) { case SDATA_NONE: fprintf (file, "%s -msdata=none", start); start = ""; break; case SDATA_DATA: fprintf (file, "%s -msdata=data", start); start = ""; break; case SDATA_SYSV: fprintf (file, "%s -msdata=sysv", start); start = ""; break; case SDATA_EABI: fprintf (file, "%s -msdata=eabi", start); start = ""; break; } if (rs6000_sdata && g_switch_value) { fprintf (file, "%s -G %d", start, g_switch_value); start = ""; }#endif if (*start == '\0') putc ('\n', file); }}/* Return nonzero if this function is known to have a null epilogue. */intdirect_return (){ if (reload_completed) { rs6000_stack_t *info = rs6000_stack_info (); if (info->first_gp_reg_save == 32 && info->first_fp_reg_save == 64 && info->first_altivec_reg_save == LAST_ALTIVEC_REGNO + 1 && ! info->lr_save_p && ! info->cr_save_p && info->vrsave_mask == 0 && ! info->push_p) return 1; } return 0;}/* Returns 1 always. */intany_operand (op, mode) rtx op ATTRIBUTE_UNUSED; enum machine_mode mode ATTRIBUTE_UNUSED;{ return 1;}/* Returns 1 if op is the count register. */intcount_register_operand (op, mode) rtx op; enum machine_mode mode ATTRIBUTE_UNUSED;{ if (GET_CODE (op) != REG) return 0; if (REGNO (op) == COUNT_REGISTER_REGNUM) return 1; if (REGNO (op) > FIRST_PSEUDO_REGISTER) return 1; return 0;}/* Returns 1 if op is an altivec register. */intaltivec_register_operand (op, mode) rtx op; enum machine_mode mode ATTRIBUTE_UNUSED;{ return (register_operand (op, mode) && (GET_CODE (op) != REG || REGNO (op) > FIRST_PSEUDO_REGISTER || ALTIVEC_REGNO_P (REGNO (op))));}intxer_operand (op, mode) rtx op; enum machine_mode mode ATTRIBUTE_UNUSED;{ if (GET_CODE (op) != REG) return 0; if (XER_REGNO_P (REGNO (op))) return 1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -