diff options
Diffstat (limited to 'gcc/config/rs6000/rs6000.c')
-rw-r--r-- | gcc/config/rs6000/rs6000.c | 105 |
1 files changed, 83 insertions, 22 deletions
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 4ebea38388b..9b9fefda2af 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -171,7 +171,7 @@ int rs6000_long_double_type_size; /* IEEE quad extended precision long double. */ int rs6000_ieeequad; -/* Whether -mabi=altivec has appeared. */ +/* Nonzero to use AltiVec ABI. */ int rs6000_altivec_abi; /* Nonzero if we want SPE ABI extensions. */ @@ -262,12 +262,14 @@ int rs6000_alignment_flags; struct { bool aix_struct_ret; /* True if -maix-struct-ret was used. */ bool alignment; /* True if -malign- was used. */ - bool abi; /* True if -mabi=spe/nospe was used. */ + bool spe_abi; /* True if -mabi=spe/no-spe was used. */ + bool altivec_abi; /* True if -mabi=altivec/no-altivec used. */ bool spe; /* True if -mspe= was used. */ bool float_gprs; /* True if -mfloat-gprs= was used. */ bool isel; /* True if -misel was used. */ bool long_double; /* True if -mlong-double- was used. */ bool ieee; /* True if -mabi=ieee/ibmlongdouble used. */ + bool vrsave; /* True if -mvrsave was used. */ } rs6000_explicit_options; struct builtin_description @@ -667,6 +669,25 @@ struct processor_costs ppc8540_cost = { 1, /* prefetch streams /*/ }; +/* Instruction costs on E300C2 and E300C3 cores. */ +static const +struct processor_costs ppce300c2c3_cost = { + COSTS_N_INSNS (4), /* mulsi */ + COSTS_N_INSNS (4), /* mulsi_const */ + COSTS_N_INSNS (4), /* mulsi_const9 */ + COSTS_N_INSNS (4), /* muldi */ + COSTS_N_INSNS (19), /* divsi */ + COSTS_N_INSNS (19), /* divdi */ + COSTS_N_INSNS (3), /* fp */ + COSTS_N_INSNS (4), /* dmul */ + COSTS_N_INSNS (18), /* sdiv */ + COSTS_N_INSNS (33), /* ddiv */ + 32, + 32, /* l1 cache */ + 256, /* l2 cache */ + 1, /* prefetch streams /*/ +}; + /* Instruction costs on POWER4 and POWER5 processors. */ static const struct processor_costs power4_cost = { @@ -1418,6 +1439,8 @@ rs6000_override_options (const char *default_cpu) {"8540", PROCESSOR_PPC8540, POWERPC_BASE_MASK | MASK_STRICT_ALIGN}, /* 8548 has a dummy entry for now. */ {"8548", PROCESSOR_PPC8540, POWERPC_BASE_MASK | MASK_STRICT_ALIGN}, + {"e300c2", PROCESSOR_PPCE300C2, POWERPC_BASE_MASK | MASK_SOFT_FLOAT}, + {"e300c3", PROCESSOR_PPCE300C3, POWERPC_BASE_MASK}, {"860", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT}, {"970", PROCESSOR_POWER4, POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64}, @@ -1524,6 +1547,14 @@ rs6000_override_options (const char *default_cpu) if (TARGET_E500) rs6000_isel = 1; + if (rs6000_cpu == PROCESSOR_PPCE300C2 || rs6000_cpu == PROCESSOR_PPCE300C3) + { + if (TARGET_ALTIVEC) + error ("AltiVec not supported in this target"); + if (TARGET_SPE) + error ("Spe not supported in this target"); + } + /* If we are optimizing big endian systems for space, use the load/store multiple and string instructions. */ if (BYTES_BIG_ENDIAN && optimize_size) @@ -1590,11 +1621,18 @@ rs6000_override_options (const char *default_cpu) if (TARGET_XCOFF && TARGET_ALTIVEC) rs6000_altivec_abi = 1; - /* Set Altivec ABI as default for PowerPC64 Linux. */ - if (TARGET_ELF && TARGET_64BIT) + /* The AltiVec ABI is the default for PowerPC-64 GNU/Linux. For + PowerPC-32 GNU/Linux, -maltivec implies the AltiVec ABI. It can + be explicitly overridden in either case. */ + if (TARGET_ELF) { - rs6000_altivec_abi = 1; - TARGET_ALTIVEC_VRSAVE = 1; + if (!rs6000_explicit_options.altivec_abi + && (TARGET_64BIT || TARGET_ALTIVEC)) + rs6000_altivec_abi = 1; + + /* Enable VRSAVE for AltiVec ABI, unless explicitly overridden. */ + if (!rs6000_explicit_options.vrsave) + TARGET_ALTIVEC_VRSAVE = rs6000_altivec_abi; } /* Set the Darwin64 ABI as default for 64-bit Darwin. */ @@ -1638,7 +1676,7 @@ rs6000_override_options (const char *default_cpu) /* For the powerpc-eabispe configuration, we set all these by default, so let's unset them if we manually set another CPU that is not the E500. */ - if (!rs6000_explicit_options.abi) + if (!rs6000_explicit_options.spe_abi) rs6000_spe_abi = 0; if (!rs6000_explicit_options.spe) rs6000_spe = 0; @@ -1836,6 +1874,11 @@ rs6000_override_options (const char *default_cpu) rs6000_cost = &ppc8540_cost; break; + case PROCESSOR_PPCE300C2: + case PROCESSOR_PPCE300C3: + rs6000_cost = &ppce300c2c3_cost; + break; + case PROCESSOR_POWER4: case PROCESSOR_POWER5: rs6000_cost = &power4_cost; @@ -2131,6 +2174,7 @@ rs6000_handle_option (size_t code, const char *arg, int value) break; case OPT_mvrsave_: + rs6000_explicit_options.vrsave = true; rs6000_parse_yes_no_option ("vrsave", arg, &(TARGET_ALTIVEC_VRSAVE)); break; @@ -2188,19 +2232,20 @@ rs6000_handle_option (size_t code, const char *arg, int value) case OPT_mabi_: if (!strcmp (arg, "altivec")) { - rs6000_explicit_options.abi = true; + rs6000_explicit_options.altivec_abi = true; rs6000_altivec_abi = 1; + + /* Enabling the AltiVec ABI turns off the SPE ABI. */ rs6000_spe_abi = 0; } else if (! strcmp (arg, "no-altivec")) { - /* ??? Don't set rs6000_explicit_options.abi here, to allow - the default for rs6000_spe_abi to be chosen later. */ + rs6000_explicit_options.altivec_abi = true; rs6000_altivec_abi = 0; } else if (! strcmp (arg, "spe")) { - rs6000_explicit_options.abi = true; + rs6000_explicit_options.spe_abi = true; rs6000_spe_abi = 1; rs6000_altivec_abi = 0; if (!TARGET_SPE_ABI) @@ -2208,7 +2253,7 @@ rs6000_handle_option (size_t code, const char *arg, int value) } else if (! strcmp (arg, "no-spe")) { - rs6000_explicit_options.abi = true; + rs6000_explicit_options.spe_abi = true; rs6000_spe_abi = 0; } @@ -3619,19 +3664,29 @@ rs6000_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED, /* We accept [reg + reg] and [reg + OFFSET]. */ if (GET_CODE (x) == PLUS) - { - rtx op1 = XEXP (x, 0); - rtx op2 = XEXP (x, 1); + { + rtx op1 = XEXP (x, 0); + rtx op2 = XEXP (x, 1); + rtx y; - op1 = force_reg (Pmode, op1); + op1 = force_reg (Pmode, op1); - if (GET_CODE (op2) != REG - && (GET_CODE (op2) != CONST_INT - || !SPE_CONST_OFFSET_OK (INTVAL (op2)))) - op2 = force_reg (Pmode, op2); + if (GET_CODE (op2) != REG + && (GET_CODE (op2) != CONST_INT + || !SPE_CONST_OFFSET_OK (INTVAL (op2)) + || (GET_MODE_SIZE (mode) > 8 + && !SPE_CONST_OFFSET_OK (INTVAL (op2) + 8)))) + op2 = force_reg (Pmode, op2); - return gen_rtx_PLUS (Pmode, op1, op2); - } + /* We can't always do [reg + reg] for these, because [reg + + reg + offset] is not a legitimate addressing mode. */ + y = gen_rtx_PLUS (Pmode, op1, op2); + + if (GET_MODE_SIZE (mode) > 8 && REG_P (op2)) + return force_reg (Pmode, y); + else + return y; + } return force_reg (Pmode, x); } @@ -9166,6 +9221,10 @@ rs6000_init_builtins (void) if (built_in_decls [BUILT_IN_CLOG]) set_user_assembler_name (built_in_decls [BUILT_IN_CLOG], "__clog"); #endif + +#ifdef SUBTARGET_INIT_BUILTINS + SUBTARGET_INIT_BUILTINS; +#endif } /* Search through a set of builtins and enable the mask bits. @@ -18502,6 +18561,8 @@ rs6000_issue_rate (void) case CPU_PPC7400: case CPU_PPC8540: case CPU_CELL: + case CPU_PPCE300C2: + case CPU_PPCE300C3: return 2; case CPU_RIOS2: case CPU_PPC604: |