You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+Boston, MA 02110-1301, USA. */
#include "config.h"
#include "system.h"
static void copy_reg_pointer (rtx, rtx);
static void fix_range (const char *);
+static bool pa_handle_option (size_t, const char *, int);
static int hppa_address_cost (rtx);
static bool hppa_rtx_costs (rtx, int, int, int *);
static inline rtx force_mode (enum machine_mode, rtx);
rtx hppa_compare_op0, hppa_compare_op1;
enum cmp_type hppa_branch_type;
-/* Which architecture we are generating code for. */
-enum architecture_type pa_arch;
-
-/* String to hold which architecture we are generating code for. */
-const char *pa_arch_string;
-
-/* String used with the -mfixed-range= option. */
-const char *pa_fixed_range_string;
-
/* Which cpu we are scheduling for. */
-enum processor_type pa_cpu;
-
-/* String to hold which cpu we are scheduling for. */
-const char *pa_cpu_string;
-
-/* String used with the -munix= option. */
-const char *pa_unix_string;
+enum processor_type pa_cpu = TARGET_SCHED_DEFAULT;
/* The UNIX standard to use for predefines and linking. */
-int flag_pa_unix;
+int flag_pa_unix = TARGET_HPUX_11_11 ? 1998 : TARGET_HPUX_10_10 ? 1995 : 1993;
/* Counts for the number of callee-saved general and floating point
registers which were saved by the current function's prologue. */
#define TARGET_ASM_DESTRUCTOR pa_asm_out_destructor
#endif
+#undef TARGET_DEFAULT_TARGET_FLAGS
+#define TARGET_DEFAULT_TARGET_FLAGS (TARGET_DEFAULT | TARGET_CPU_DEFAULT)
+#undef TARGET_HANDLE_OPTION
+#define TARGET_HANDLE_OPTION pa_handle_option
+
#undef TARGET_INIT_BUILTINS
#define TARGET_INIT_BUILTINS pa_init_builtins
#undef TARGET_SCALAR_MODE_SUPPORTED_P
#define TARGET_SCALAR_MODE_SUPPORTED_P pa_scalar_mode_supported_p
+#undef TARGET_CANNOT_FORCE_CONST_MEM
+#define TARGET_CANNOT_FORCE_CONST_MEM pa_tls_referenced_p
+
struct gcc_target targetm = TARGET_INITIALIZER;
\f
/* Parse the -mfixed-range= option string. */
REG2 are either register names or register numbers. The effect
of this option is to mark the registers in the range from REG1 to
REG2 as ``fixed'' so they won't be used by the compiler. This is
- used, e.g., to ensure that kernel mode code doesn't use f32-f127. */
+ used, e.g., to ensure that kernel mode code doesn't use fr4-fr31. */
i = strlen (const_str);
str = (char *) alloca (i + 1);
dash = strchr (str, '-');
if (!dash)
{
- warning ("value of -mfixed-range must have form REG1-REG2");
+ warning (0, "value of -mfixed-range must have form REG1-REG2");
return;
}
*dash = '\0';
first = decode_reg_name (str);
if (first < 0)
{
- warning ("unknown register name: %s", str);
+ warning (0, "unknown register name: %s", str);
return;
}
last = decode_reg_name (dash + 1);
if (last < 0)
{
- warning ("unknown register name: %s", dash + 1);
+ warning (0, "unknown register name: %s", dash + 1);
return;
}
if (first > last)
{
- warning ("%s-%s is an empty range", str, dash + 1);
+ warning (0, "%s-%s is an empty range", str, dash + 1);
return;
}
target_flags |= MASK_DISABLE_FPREGS;
}
-void
-override_options (void)
-{
- if (pa_cpu_string == NULL)
- pa_cpu_string = TARGET_SCHED_DEFAULT;
-
- if (! strcmp (pa_cpu_string, "8000"))
- {
- pa_cpu_string = "8000";
- pa_cpu = PROCESSOR_8000;
- }
- else if (! strcmp (pa_cpu_string, "7100"))
- {
- pa_cpu_string = "7100";
- pa_cpu = PROCESSOR_7100;
- }
- else if (! strcmp (pa_cpu_string, "700"))
- {
- pa_cpu_string = "700";
- pa_cpu = PROCESSOR_700;
- }
- else if (! strcmp (pa_cpu_string, "7100LC"))
- {
- pa_cpu_string = "7100LC";
- pa_cpu = PROCESSOR_7100LC;
- }
- else if (! strcmp (pa_cpu_string, "7200"))
- {
- pa_cpu_string = "7200";
- pa_cpu = PROCESSOR_7200;
- }
- else if (! strcmp (pa_cpu_string, "7300"))
- {
- pa_cpu_string = "7300";
- pa_cpu = PROCESSOR_7300;
- }
- else
- {
- warning ("unknown -mschedule= option (%s).\nValid options are 700, 7100, 7100LC, 7200, 7300, and 8000\n", pa_cpu_string);
- }
+/* Implement TARGET_HANDLE_OPTION. */
- /* Set the instruction architecture. */
- if (pa_arch_string && ! strcmp (pa_arch_string, "1.0"))
+static bool
+pa_handle_option (size_t code, const char *arg, int value ATTRIBUTE_UNUSED)
+{
+ switch (code)
{
- pa_arch_string = "1.0";
- pa_arch = ARCHITECTURE_10;
+ case OPT_mnosnake:
+ case OPT_mpa_risc_1_0:
+ case OPT_march_1_0:
target_flags &= ~(MASK_PA_11 | MASK_PA_20);
- }
- else if (pa_arch_string && ! strcmp (pa_arch_string, "1.1"))
- {
- pa_arch_string = "1.1";
- pa_arch = ARCHITECTURE_11;
+ return true;
+
+ case OPT_msnake:
+ case OPT_mpa_risc_1_1:
+ case OPT_march_1_1:
target_flags &= ~MASK_PA_20;
target_flags |= MASK_PA_11;
- }
- else if (pa_arch_string && ! strcmp (pa_arch_string, "2.0"))
- {
- pa_arch_string = "2.0";
- pa_arch = ARCHITECTURE_20;
- target_flags |= MASK_PA_11 | MASK_PA_20;
- }
- else if (pa_arch_string)
- {
- warning ("unknown -march= option (%s).\nValid options are 1.0, 1.1, and 2.0\n", pa_arch_string);
- }
+ return true;
- if (TARGET_HPUX)
- {
- /* Set the default UNIX standard for HP-UX. This affects the
- predefines and startfiles used for the target. */
- if (pa_unix_string == NULL)
- pa_unix_string
- = TARGET_HPUX_11_11 ? "98" : (TARGET_HPUX_10_10 ? "95" : "93");
+ case OPT_mpa_risc_2_0:
+ case OPT_march_2_0:
+ target_flags |= MASK_PA_11 | MASK_PA_20;
+ return true;
- if (!strcmp (pa_unix_string, "93"))
- flag_pa_unix = 1993;
- else if (!strcmp (pa_unix_string, "95"))
- flag_pa_unix = 1995;
- else if (TARGET_HPUX_11_11)
- {
- if (!strcmp (pa_unix_string, "98"))
- flag_pa_unix = 1998;
- else
- warning ("unknown -munix= option (%s).\n"
- "Valid options are 93, 95 and 98.\n",
- pa_unix_string);
- }
- else if (TARGET_HPUX_10_10)
- warning ("unknown -munix= option (%s)."
- "\nValid options are 93 and 95.\n",
- pa_unix_string);
+ case OPT_mschedule_:
+ if (strcmp (arg, "8000") == 0)
+ pa_cpu = PROCESSOR_8000;
+ else if (strcmp (arg, "7100") == 0)
+ pa_cpu = PROCESSOR_7100;
+ else if (strcmp (arg, "700") == 0)
+ pa_cpu = PROCESSOR_700;
+ else if (strcmp (arg, "7100LC") == 0)
+ pa_cpu = PROCESSOR_7100LC;
+ else if (strcmp (arg, "7200") == 0)
+ pa_cpu = PROCESSOR_7200;
+ else if (strcmp (arg, "7300") == 0)
+ pa_cpu = PROCESSOR_7300;
else
- warning ("unknown -munix= option (%s).\nValid option is 93.\n",
- pa_unix_string);
- }
+ return false;
+ return true;
+
+ case OPT_mfixed_range_:
+ fix_range (arg);
+ return true;
- if (pa_fixed_range_string)
- fix_range (pa_fixed_range_string);
+#if TARGET_HPUX
+ case OPT_munix_93:
+ flag_pa_unix = 1993;
+ return true;
+#endif
+#if TARGET_HPUX_10_10
+ case OPT_munix_95:
+ flag_pa_unix = 1995;
+ return true;
+#endif
+
+#if TARGET_HPUX_11_11
+ case OPT_munix_98:
+ flag_pa_unix = 1998;
+ return true;
+#endif
+
+ default:
+ return true;
+ }
+}
+
+void
+override_options (void)
+{
/* Unconditional branches in the delay slot are not compatible with dwarf2
call frame information. There is no benefit in using this optimization
on PA8000 and later processors. */
if (flag_pic && TARGET_PORTABLE_RUNTIME)
{
- warning ("PIC code generation is not supported in the portable runtime model\n");
+ warning (0, "PIC code generation is not supported in the portable runtime model");
}
if (flag_pic && TARGET_FAST_INDIRECT_CALLS)
{
- warning ("PIC code generation is not compatible with fast indirect calls\n");
+ warning (0, "PIC code generation is not compatible with fast indirect calls");
}
if (! TARGET_GAS && write_symbols != NO_DEBUG)
{
- warning ("-g is only supported when using GAS on this processor,");
- warning ("-g option disabled");
+ warning (0, "-g is only supported when using GAS on this processor,");
+ warning (0, "-g option disabled");
write_symbols = NO_DEBUG;
}
{
rtx pic_ref = orig;
+ gcc_assert (!PA_SYMBOL_REF_TLS_P (orig));
+
/* Labels need special handling. */
if (pic_label_operand (orig, mode))
{
{
rtx insn, tmp_reg;
- if (reg == 0)
- abort ();
+ gcc_assert (reg);
/* Before reload, allocate a temporary register for the intermediate
result. This allows the sequence to be deleted when the final
&& XEXP (XEXP (orig, 0), 0) == pic_offset_table_rtx)
return orig;
- if (reg == 0)
- abort ();
-
- if (GET_CODE (XEXP (orig, 0)) == PLUS)
- {
- base = legitimize_pic_address (XEXP (XEXP (orig, 0), 0), Pmode, reg);
- orig = legitimize_pic_address (XEXP (XEXP (orig, 0), 1), Pmode,
- base == reg ? 0 : reg);
- }
- else
- abort ();
+ gcc_assert (reg);
+ gcc_assert (GET_CODE (XEXP (orig, 0)) == PLUS);
+
+ base = legitimize_pic_address (XEXP (XEXP (orig, 0), 0), Pmode, reg);
+ orig = legitimize_pic_address (XEXP (XEXP (orig, 0), 1), Pmode,
+ base == reg ? 0 : reg);
if (GET_CODE (orig) == CONST_INT)
{
return pic_ref;
}
+static GTY(()) rtx gen_tls_tga;
+
+static rtx
+gen_tls_get_addr (void)
+{
+ if (!gen_tls_tga)
+ gen_tls_tga = init_one_libfunc ("__tls_get_addr");
+ return gen_tls_tga;
+}
+
+static rtx
+hppa_tls_call (rtx arg)
+{
+ rtx ret;
+
+ ret = gen_reg_rtx (Pmode);
+ emit_library_call_value (gen_tls_get_addr (), ret,
+ LCT_CONST, Pmode, 1, arg, Pmode);
+
+ return ret;
+}
+
+static rtx
+legitimize_tls_address (rtx addr)
+{
+ rtx ret, insn, tmp, t1, t2, tp;
+ enum tls_model model = SYMBOL_REF_TLS_MODEL (addr);
+
+ switch (model)
+ {
+ case TLS_MODEL_GLOBAL_DYNAMIC:
+ tmp = gen_reg_rtx (Pmode);
+ emit_insn (gen_tgd_load (tmp, addr));
+ ret = hppa_tls_call (tmp);
+ break;
+
+ case TLS_MODEL_LOCAL_DYNAMIC:
+ ret = gen_reg_rtx (Pmode);
+ tmp = gen_reg_rtx (Pmode);
+ start_sequence ();
+ emit_insn (gen_tld_load (tmp, addr));
+ t1 = hppa_tls_call (tmp);
+ insn = get_insns ();
+ end_sequence ();
+ t2 = gen_reg_rtx (Pmode);
+ emit_libcall_block (insn, t2, t1,
+ gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
+ UNSPEC_TLSLDBASE));
+ emit_insn (gen_tld_offset_load (ret, addr, t2));
+ break;
+
+ case TLS_MODEL_INITIAL_EXEC:
+ tp = gen_reg_rtx (Pmode);
+ tmp = gen_reg_rtx (Pmode);
+ ret = gen_reg_rtx (Pmode);
+ emit_insn (gen_tp_load (tp));
+ emit_insn (gen_tie_load (tmp, addr));
+ emit_move_insn (ret, gen_rtx_PLUS (Pmode, tp, tmp));
+ break;
+
+ case TLS_MODEL_LOCAL_EXEC:
+ tp = gen_reg_rtx (Pmode);
+ ret = gen_reg_rtx (Pmode);
+ emit_insn (gen_tp_load (tp));
+ emit_insn (gen_tle_load (ret, addr, tp));
+ break;
+
+ default:
+ gcc_unreachable ();
+ }
+
+ return ret;
+}
+
/* Try machine-dependent ways of modifying an illegitimate address
to be legitimate. If we find one, return the new, valid address.
This macro is used in only one place: `memory_address' in explow.c.
&& !REG_POINTER (XEXP (x, 1)))
return gen_rtx_PLUS (Pmode, XEXP (x, 1), XEXP (x, 0));
- if (flag_pic)
+ if (PA_SYMBOL_REF_TLS_P (x))
+ return legitimize_tls_address (x);
+ else if (flag_pic)
return legitimize_pic_address (x, mode, gen_reg_rtx (Pmode));
/* Strip off CONST. */
if (mode == GET_MODE (orig))
return orig;
- if (REGNO (orig) >= FIRST_PSEUDO_REGISTER)
- abort ();
+ gcc_assert (REGNO (orig) < FIRST_PSEUDO_REGISTER);
return gen_rtx_REG (mode, REGNO (orig));
}
+/* Return 1 if *X is a thread-local symbol. */
+
+static int
+pa_tls_symbol_ref_1 (rtx *x, void *data ATTRIBUTE_UNUSED)
+{
+ return PA_SYMBOL_REF_TLS_P (*x);
+}
+
+/* Return 1 if X contains a thread-local symbol. */
+
+bool
+pa_tls_referenced_p (rtx x)
+{
+ if (!TARGET_HAVE_TLS)
+ return false;
+
+ return for_each_rtx (&x, &pa_tls_symbol_ref_1, 0);
+}
+
/* Emit insns to move operands[1] into operands[0].
Return 1 if we have written out everything that needs to be done to
if (GET_CODE (operand0) == MEM && IS_INDEX_ADDR_P (XEXP (operand0, 0)))
{
/* This is only safe up to the beginning of life analysis. */
- if (no_new_pseudos)
- abort ();
+ gcc_assert (!no_new_pseudos);
tem = copy_to_mode_reg (Pmode, XEXP (operand0, 0));
operand0 = replace_equiv_address (operand0, tem);
{
/* Save away the constant part of the expression. */
const_part = XEXP (XEXP (operand1, 0), 1);
- if (GET_CODE (const_part) != CONST_INT)
- abort ();
+ gcc_assert (GET_CODE (const_part) == CONST_INT);
/* Force the function label into memory. */
temp = force_const_mem (mode, XEXP (XEXP (operand1, 0), 0));
}
return 1;
}
+ else if (pa_tls_referenced_p (operand1))
+ {
+ rtx tmp = operand1;
+ rtx addend = NULL;
+
+ if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS)
+ {
+ addend = XEXP (XEXP (tmp, 0), 1);
+ tmp = XEXP (XEXP (tmp, 0), 0);
+ }
+
+ gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
+ tmp = legitimize_tls_address (tmp);
+ if (addend)
+ {
+ tmp = gen_rtx_PLUS (mode, tmp, addend);
+ tmp = force_operand (tmp, operands[0]);
+ }
+ operands[1] = tmp;
+ }
else if (GET_CODE (operand1) != CONST_INT
|| !cint_ok_for_move (INTVAL (operand1)))
{
long i;
REAL_VALUE_TYPE d;
- if (GET_MODE (operands[1]) != SFmode)
- abort ();
+ gcc_assert (GET_MODE (operands[1]) == SFmode);
/* Translate the CONST_DOUBLE to a CONST_INT with the same target
bit pattern. */
optype1 = RNDOP;
/* Check for the cases that the operand constraints are not
- supposed to allow to happen. Abort if we get one,
- because generating code for these cases is painful. */
-
- if (optype0 != REGOP && optype1 != REGOP)
- abort ();
+ supposed to allow to happen. */
+ gcc_assert (optype0 == REGOP || optype1 == REGOP);
/* Handle auto decrementing and incrementing loads and stores
specifically, since the structure of the function doesn't work
rtx high_reg = gen_rtx_SUBREG (SImode, operands[1], 0);
operands[0] = XEXP (addr, 0);
- if (GET_CODE (operands[1]) != REG || GET_CODE (operands[0]) != REG)
- abort ();
+ gcc_assert (GET_CODE (operands[1]) == REG
+ && GET_CODE (operands[0]) == REG);
- if (!reg_overlap_mentioned_p (high_reg, addr))
- {
- /* No overlap between high target register and address
- register. (We do this in a non-obvious way to
- save a register file writeback) */
- if (GET_CODE (addr) == POST_INC)
- return "{stws|stw},ma %1,8(%0)\n\tstw %R1,-4(%0)";
- return "{stws|stw},ma %1,-8(%0)\n\tstw %R1,12(%0)";
- }
- else
- abort ();
+ gcc_assert (!reg_overlap_mentioned_p (high_reg, addr));
+
+ /* No overlap between high target register and address
+ register. (We do this in a non-obvious way to
+ save a register file writeback) */
+ if (GET_CODE (addr) == POST_INC)
+ return "{stws|stw},ma %1,8(%0)\n\tstw %R1,-4(%0)";
+ return "{stws|stw},ma %1,-8(%0)\n\tstw %R1,12(%0)";
}
else if (GET_CODE (addr) == PRE_INC || GET_CODE (addr) == PRE_DEC)
{
rtx high_reg = gen_rtx_SUBREG (SImode, operands[1], 0);
operands[0] = XEXP (addr, 0);
- if (GET_CODE (operands[1]) != REG || GET_CODE (operands[0]) != REG)
- abort ();
-
- if (!reg_overlap_mentioned_p (high_reg, addr))
- {
- /* No overlap between high target register and address
- register. (We do this in a non-obvious way to
- save a register file writeback) */
- if (GET_CODE (addr) == PRE_INC)
- return "{stws|stw},mb %1,8(%0)\n\tstw %R1,4(%0)";
- return "{stws|stw},mb %1,-8(%0)\n\tstw %R1,4(%0)";
- }
- else
- abort ();
+ gcc_assert (GET_CODE (operands[1]) == REG
+ && GET_CODE (operands[0]) == REG);
+
+ gcc_assert (!reg_overlap_mentioned_p (high_reg, addr));
+ /* No overlap between high target register and address
+ register. (We do this in a non-obvious way to save a
+ register file writeback) */
+ if (GET_CODE (addr) == PRE_INC)
+ return "{stws|stw},mb %1,8(%0)\n\tstw %R1,4(%0)";
+ return "{stws|stw},mb %1,-8(%0)\n\tstw %R1,4(%0)";
}
}
if (optype1 == MEMOP)
rtx high_reg = gen_rtx_SUBREG (SImode, operands[0], 0);
operands[1] = XEXP (addr, 0);
- if (GET_CODE (operands[0]) != REG || GET_CODE (operands[1]) != REG)
- abort ();
+ gcc_assert (GET_CODE (operands[0]) == REG
+ && GET_CODE (operands[1]) == REG);
if (!reg_overlap_mentioned_p (high_reg, addr))
{
rtx high_reg = gen_rtx_SUBREG (SImode, operands[0], 0);
operands[1] = XEXP (addr, 0);
- if (GET_CODE (operands[0]) != REG || GET_CODE (operands[1]) != REG)
- abort ();
+ gcc_assert (GET_CODE (operands[0]) == REG
+ && GET_CODE (operands[1]) == REG);
if (!reg_overlap_mentioned_p (high_reg, addr))
{
{
output_asm_insn ("fstd%F0 %1,%0", operands);
}
- else if (operands[1] == CONST0_RTX (GET_MODE (operands[0])))
+ else
{
- if (GET_CODE (operands[0]) == REG)
- {
- rtx xoperands[2];
- xoperands[1] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
- xoperands[0] = operands[0];
- output_asm_insn ("copy %%r0,%0\n\tcopy %%r0,%1", xoperands);
- }
+ rtx xoperands[2];
+
+ gcc_assert (operands[1] == CONST0_RTX (GET_MODE (operands[0])));
+
/* This is a pain. You have to be prepared to deal with an
arbitrary address here including pre/post increment/decrement.
so avoid this in the MD. */
- else
- abort ();
+ gcc_assert (GET_CODE (operands[0]) == REG);
+
+ xoperands[1] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
+ xoperands[0] = operands[0];
+ output_asm_insn ("copy %%r0,%0\n\tcopy %%r0,%1", xoperands);
}
- else abort ();
return "";
}
\f
else if (CONSTANT_P (XEXP (addr, 1)))
addr = XEXP (addr, 0);
else
- abort ();
+ gcc_unreachable ();
}
- if (GET_CODE (addr) == REG)
- return addr;
- abort ();
+ gcc_assert (GET_CODE (addr) == REG);
+ return addr;
}
/* Emit code to perform a block move.
return "";
default:
- abort ();
+ gcc_unreachable ();
}
}
return "";
default:
- abort ();
+ gcc_unreachable ();
}
}
if ((mask & (1 << ms0)) == 0)
break;
- if (ms0 != 32)
- abort ();
+ gcc_assert (ms0 == 32);
if (ls1 == 32)
{
len = ls0;
- if (len == 0)
- abort ();
+ gcc_assert (len);
operands[2] = GEN_INT (len);
return "{extru|extrw,u} %1,31,%2,%0";
if ((mask & ((unsigned HOST_WIDE_INT) 1 << ms0)) == 0)
break;
- if (ms0 != HOST_BITS_PER_WIDE_INT)
- abort ();
+ gcc_assert (ms0 == HOST_BITS_PER_WIDE_INT);
if (ls1 == HOST_BITS_PER_WIDE_INT)
{
len = ls0;
- if (len == 0)
- abort ();
+ gcc_assert (len);
operands[2] = GEN_INT (len);
return "extrd,u %1,63,%2,%0";
if ((mask & (1 << bs1)) == 0)
break;
- if (bs1 != 32 && ((unsigned HOST_WIDE_INT) 1 << bs1) <= mask)
- abort ();
+ gcc_assert (bs1 == 32 || ((unsigned HOST_WIDE_INT) 1 << bs1) > mask);
p = 31 - bs0;
len = bs1 - bs0;
if ((mask & ((unsigned HOST_WIDE_INT) 1 << bs1)) == 0)
break;
- if (bs1 != HOST_BITS_PER_WIDE_INT
- && ((unsigned HOST_WIDE_INT) 1 << bs1) <= mask)
- abort ();
+ gcc_assert (bs1 == HOST_BITS_PER_WIDE_INT
+ || ((unsigned HOST_WIDE_INT) 1 << bs1) > mask);
p = 63 - bs0;
len = bs1 - bs0;
{
rtx insn, basereg, srcreg, delta;
- if (!VAL_14_BITS_P (mod))
- abort ();
+ gcc_assert (VAL_14_BITS_P (mod));
basereg = gen_rtx_REG (Pmode, base);
srcreg = gen_rtx_REG (word_mode, reg);
attr_type = get_attr_type (insn);
- if (REG_NOTE_KIND (link) == REG_DEP_ANTI)
+ switch (REG_NOTE_KIND (link))
{
+ case REG_DEP_ANTI:
/* Anti dependency; DEP_INSN reads a register that INSN writes some
cycles later. */
/* For other anti dependencies, the cost is 0. */
return 0;
- }
- else if (REG_NOTE_KIND (link) == REG_DEP_OUTPUT)
- {
+
+ case REG_DEP_OUTPUT:
/* Output dependency; DEP_INSN writes a register that INSN writes some
cycles later. */
if (attr_type == TYPE_FPLOAD)
/* For other output dependencies, the cost is 0. */
return 0;
+
+ default:
+ gcc_unreachable ();
}
- else
- abort ();
}
/* Adjust scheduling priorities. We use this to try and keep addil
case PROCESSOR_8000: return 4;
default:
- abort ();
+ gcc_unreachable ();
}
}
case LTU:
fputs ("<<", file); break;
default:
- abort ();
+ gcc_unreachable ();
}
return;
case 'N': /* Condition, (N)egated */
case LTU:
fputs (">>=", file); break;
default:
- abort ();
+ gcc_unreachable ();
}
return;
/* For floating point comparisons. Note that the output
case ORDERED:
fputs ("?", file); break;
default:
- abort ();
+ gcc_unreachable ();
}
return;
case 'S': /* Condition, operands are (S)wapped. */
case LTU:
fputs (">>", file); break;
default:
- abort ();
+ gcc_unreachable ();
}
return;
case 'B': /* Condition, (B)oth swapped and negate. */
case LTU:
fputs ("<<=", file); break;
default:
- abort ();
+ gcc_unreachable ();
}
return;
case 'k':
- if (GET_CODE (x) == CONST_INT)
- {
- fprintf (file, HOST_WIDE_INT_PRINT_DEC, ~INTVAL (x));
- return;
- }
- abort ();
+ gcc_assert (GET_CODE (x) == CONST_INT);
+ fprintf (file, HOST_WIDE_INT_PRINT_DEC, ~INTVAL (x));
+ return;
case 'Q':
- if (GET_CODE (x) == CONST_INT)
- {
- fprintf (file, HOST_WIDE_INT_PRINT_DEC, 64 - (INTVAL (x) & 63));
- return;
- }
- abort ();
+ gcc_assert (GET_CODE (x) == CONST_INT);
+ fprintf (file, HOST_WIDE_INT_PRINT_DEC, 64 - (INTVAL (x) & 63));
+ return;
case 'L':
- if (GET_CODE (x) == CONST_INT)
- {
- fprintf (file, HOST_WIDE_INT_PRINT_DEC, 32 - (INTVAL (x) & 31));
- return;
- }
- abort ();
+ gcc_assert (GET_CODE (x) == CONST_INT);
+ fprintf (file, HOST_WIDE_INT_PRINT_DEC, 32 - (INTVAL (x) & 31));
+ return;
case 'O':
- if (GET_CODE (x) == CONST_INT && exact_log2 (INTVAL (x)) >= 0)
- {
- fprintf (file, "%d", exact_log2 (INTVAL (x)));
- return;
- }
- abort ();
+ gcc_assert (GET_CODE (x) == CONST_INT && exact_log2 (INTVAL (x)) >= 0);
+ fprintf (file, "%d", exact_log2 (INTVAL (x)));
+ return;
case 'p':
- if (GET_CODE (x) == CONST_INT)
- {
- fprintf (file, HOST_WIDE_INT_PRINT_DEC, 63 - (INTVAL (x) & 63));
- return;
- }
- abort ();
+ gcc_assert (GET_CODE (x) == CONST_INT);
+ fprintf (file, HOST_WIDE_INT_PRINT_DEC, 63 - (INTVAL (x) & 63));
+ return;
case 'P':
- if (GET_CODE (x) == CONST_INT)
- {
- fprintf (file, HOST_WIDE_INT_PRINT_DEC, 31 - (INTVAL (x) & 31));
- return;
- }
- abort ();
+ gcc_assert (GET_CODE (x) == CONST_INT);
+ fprintf (file, HOST_WIDE_INT_PRINT_DEC, 31 - (INTVAL (x) & 31));
+ return;
case 'I':
if (GET_CODE (x) == CONST_INT)
fputs ("i", file);
addresses. */
break;
default:
- abort ();
+ gcc_unreachable ();
}
if (GET_CODE (x) == REG)
{
int offset = 0; /* assembler wants -$global$ at end */
rtx base = NULL_RTX;
- if (GET_CODE (XEXP (XEXP (x, 0), 0)) == SYMBOL_REF)
+ switch (GET_CODE (XEXP (XEXP (x, 0), 0)))
{
+ case SYMBOL_REF:
base = XEXP (XEXP (x, 0), 0);
output_addr_const (file, base);
+ break;
+ case CONST_INT:
+ offset = INTVAL (XEXP (XEXP (x, 0), 0));
+ break;
+ default:
+ gcc_unreachable ();
}
- else if (GET_CODE (XEXP (XEXP (x, 0), 0)) == CONST_INT)
- offset = INTVAL (XEXP (XEXP (x, 0), 0));
- else abort ();
- if (GET_CODE (XEXP (XEXP (x, 0), 1)) == SYMBOL_REF)
+ switch (GET_CODE (XEXP (XEXP (x, 0), 1)))
{
+ case SYMBOL_REF:
base = XEXP (XEXP (x, 0), 1);
output_addr_const (file, base);
+ break;
+ case CONST_INT:
+ offset = INTVAL (XEXP (XEXP (x, 0), 1));
+ break;
+ default:
+ gcc_unreachable ();
}
- else if (GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT)
- offset = INTVAL (XEXP (XEXP (x, 0), 1));
- else abort ();
/* How bogus. The compiler is apparently responsible for
rounding the constant if it uses an LR field selector.
if (round_constant)
offset = ((offset + 0x1000) & ~0x1fff);
- if (GET_CODE (XEXP (x, 0)) == PLUS)
+ switch (GET_CODE (XEXP (x, 0)))
{
+ case PLUS:
if (offset < 0)
{
offset = -offset;
}
else
sep = "+";
- }
- else if (GET_CODE (XEXP (x, 0)) == MINUS
- && (GET_CODE (XEXP (XEXP (x, 0), 0)) == SYMBOL_REF))
- sep = "-";
- else abort ();
+ break;
+
+ case MINUS:
+ gcc_assert (GET_CODE (XEXP (XEXP (x, 0), 0)) == SYMBOL_REF);
+ sep = "-";
+ break;
+ default:
+ gcc_unreachable ();
+ }
+
if (!read_only_operand (base, VOIDmode) && !flag_pic)
fputs ("-$global$", file);
if (offset)
return;
}
- if (GET_CODE (call_insn) != CALL_INSN)
- abort ();
- for (link = CALL_INSN_FUNCTION_USAGE (call_insn); link; link = XEXP (link, 1))
+ gcc_assert (GET_CODE (call_insn) == CALL_INSN);
+ for (link = CALL_INSN_FUNCTION_USAGE (call_insn);
+ link; link = XEXP (link, 1))
{
rtx use = XEXP (link, 0);
return output_lbranch (operands[0], insn);
default:
- abort ();
+ gcc_unreachable ();
}
return buf;
}
if (dbr_sequence_length () != 0)
{
/* We can't handle a jump in the delay slot. */
- if (GET_CODE (NEXT_INSN (insn)) == JUMP_INSN)
- abort ();
+ gcc_assert (GET_CODE (NEXT_INSN (insn)) != JUMP_INSN);
final_scan_insn (NEXT_INSN (insn), asm_out_file,
- optimize, 0, 0, NULL);
+ optimize, 0, NULL);
/* Now delete the delay insn. */
PUT_CODE (NEXT_INSN (insn), NOTE);
break;
default:
- abort ();
+ gcc_unreachable ();
}
return buf;
}
break;
default:
- abort ();
+ gcc_unreachable ();
}
return buf;
}
if (! nullify && length == 4 && dbr_sequence_length () == 0)
nullify = forward_branch_p (insn);
- /* Handle short versions first. */
- if (length == 4 && nullify)
- return "addib,%C2,n %1,%0,%3";
- else if (length == 4 && ! nullify)
- return "addib,%C2 %1,%0,%3";
- else if (length == 8)
+ switch (length)
{
+ case 4:
+ if (nullify)
+ return "addib,%C2,n %1,%0,%3";
+ else
+ return "addib,%C2 %1,%0,%3";
+
+ case 8:
/* Handle weird backwards branch with a fulled delay slot
which is nullified. */
if (dbr_sequence_length () != 0
return "addi,%N2 %1,%0,%0\n\tb,n %3";
else
return "addi,%N2 %1,%0,%0\n\tb %3";
+
+ default:
+ gcc_unreachable ();
}
- else
- abort ();
+
}
/* Deal with gross reload from FP register case. */
else if (which_alternative == 1)
if (! nullify && length == 4 && dbr_sequence_length () == 0)
nullify = forward_branch_p (insn);
- /* Handle short versions first. */
- if (length == 4 && nullify)
- return "movb,%C2,n %1,%0,%3";
- else if (length == 4 && ! nullify)
- return "movb,%C2 %1,%0,%3";
- else if (length == 8)
+ switch (length)
{
+ case 4:
+ if (nullify)
+ return "movb,%C2,n %1,%0,%3";
+ else
+ return "movb,%C2 %1,%0,%3";
+
+ case 8:
/* Handle weird backwards branch with a filled delay slot
which is nullified. */
if (dbr_sequence_length () != 0
return "or,%N2 %1,%%r0,%0\n\tb,n %3";
else
return "or,%N2 %1,%%r0,%0\n\tb %3";
+
+ default:
+ gcc_unreachable ();
}
- else
- abort ();
}
/* Deal with gross reload from FP register case. */
else if (which_alternative == 1)
&& !sibcall)
{
final_scan_insn (NEXT_INSN (insn), asm_out_file,
- optimize, 0, 0, NULL);
+ optimize, 0, NULL);
/* Now delete the delay insn. */
PUT_CODE (NEXT_INSN (insn), NOTE);
/* A non-jump insn in the delay slot. By definition we can
emit this insn before the call (and in fact before argument
relocating. */
- final_scan_insn (NEXT_INSN (insn), asm_out_file, optimize, 0, 0,
+ final_scan_insn (NEXT_INSN (insn), asm_out_file, optimize, 0,
NULL);
/* Now delete the delay insn. */
return "";
/* A sibcall should never have a branch in the delay slot. */
- if (sibcall)
- abort ();
+ gcc_assert (!sibcall);
/* This call has an unconditional jump in its delay slot. */
xoperands[0] = XEXP (PATTERN (NEXT_INSN (insn)), 1);
static void
pa_encode_section_info (tree decl, rtx rtl, int first)
{
+ default_encode_section_info (decl, rtl, first);
+
if (first && TEXT_SPACE_P (decl))
{
SYMBOL_REF_FLAG (XEXP (rtl, 0)) = 1;
max_common_align = TARGET_64BIT ? 128 : (size >= 4096 ? 256 : 64);
if (align > max_common_align)
{
- warning ("alignment (%u) for %s exceeds maximum alignment "
+ warning (0, "alignment (%u) for %s exceeds maximum alignment "
"for global common data. Using %u",
align / BITS_PER_UNIT, name, max_common_align / BITS_PER_UNIT);
align = max_common_align;
{
enum machine_mode valmode;
- /* Aggregates with a size less than or equal to 128 bits are returned
- in GR 28(-29). They are left justified. The pad bits are undefined.
- Larger aggregates are returned in memory. */
- if (TARGET_64BIT && AGGREGATE_TYPE_P (valtype))
+ if (AGGREGATE_TYPE_P (valtype))
{
- rtx loc[2];
- int i, offset = 0;
- int ub = int_size_in_bytes (valtype) <= UNITS_PER_WORD ? 1 : 2;
+ if (TARGET_64BIT)
+ {
+ /* Aggregates with a size less than or equal to 128 bits are
+ returned in GR 28(-29). They are left justified. The pad
+ bits are undefined. Larger aggregates are returned in
+ memory. */
+ rtx loc[2];
+ int i, offset = 0;
+ int ub = int_size_in_bytes (valtype) <= UNITS_PER_WORD ? 1 : 2;
- for (i = 0; i < ub; i++)
+ for (i = 0; i < ub; i++)
+ {
+ loc[i] = gen_rtx_EXPR_LIST (VOIDmode,
+ gen_rtx_REG (DImode, 28 + i),
+ GEN_INT (offset));
+ offset += 8;
+ }
+
+ return gen_rtx_PARALLEL (BLKmode, gen_rtvec_v (ub, loc));
+ }
+ else if (int_size_in_bytes (valtype) > UNITS_PER_WORD)
{
- loc[i] = gen_rtx_EXPR_LIST (VOIDmode,
- gen_rtx_REG (DImode, 28 + i),
- GEN_INT (offset));
- offset += 8;
+ /* Aggregates 5 to 8 bytes in size are returned in general
+ registers r28-r29 in the same manner as other non
+ floating-point objects. The data is right-justified and
+ zero-extended to 64 bits. This is opposite to the normal
+ justification used on big endian targets and requires
+ special treatment. */
+ rtx loc = gen_rtx_EXPR_LIST (VOIDmode,
+ gen_rtx_REG (DImode, 28), const0_rtx);
+ return gen_rtx_PARALLEL (BLKmode, gen_rtvec (1, loc));
}
-
- return gen_rtx_PARALLEL (BLKmode, gen_rtvec_v (ub, loc));
}
if ((INTEGRAL_TYPE_P (valtype)
valmode = TYPE_MODE (valtype);
if (TREE_CODE (valtype) == REAL_TYPE
+ && !AGGREGATE_TYPE_P (valtype)
&& TYPE_MODE (valtype) != TFmode
&& !TARGET_SOFT_FLOAT)
return gen_rtx_REG (valmode, 32);
to 64 bits. This is opposite to the normal justification
used on big endian targets and requires special treatment.
We now define BLOCK_REG_PADDING to pad these objects. */
- if (mode == BLKmode)
+ if (mode == BLKmode || (type && AGGREGATE_TYPE_P (type)))
{
rtx loc = gen_rtx_EXPR_LIST (VOIDmode,
gen_rtx_REG (DImode, gpr_reg_base),
const0_rtx);
- return gen_rtx_PARALLEL (mode, gen_rtvec (1, loc));
+ return gen_rtx_PARALLEL (BLKmode, gen_rtvec (1, loc));
}
}
else
&& cum->indirect)
/* If the parameter is not a floating point parameter, then
it belongs in GPRs. */
- || !FLOAT_MODE_P (mode))
+ || !FLOAT_MODE_P (mode)
+ /* Structure with single SFmode field belongs in GPR. */
+ || (type && AGGREGATE_TYPE_P (type)))
retval = gen_rtx_REG (mode, gpr_reg_base);
else
retval = gen_rtx_REG (mode, fpr_reg_base);
at the end of the file if and only if SYMBOL_REF_REFERENCED_P is true.
This avoids putting out names that are never really used. */
-struct extern_symbol GTY(())
+typedef struct extern_symbol GTY(())
{
tree decl;
const char *name;
-};
-typedef struct extern_symbol *extern_symbol;
+} extern_symbol;
/* Define gc'd vector type for extern_symbol. */
-DEF_VEC_GC_P(extern_symbol);
+DEF_VEC_O(extern_symbol);
+DEF_VEC_ALLOC_O(extern_symbol,gc);
/* Vector of extern_symbol pointers. */
-static GTY(()) VEC(extern_symbol) *extern_symbols;
+static GTY(()) VEC(extern_symbol,gc) *extern_symbols;
#ifdef ASM_OUTPUT_EXTERNAL_REAL
/* Mark DECL (name NAME) as an external reference (assembler output
void
pa_hpux_asm_output_external (FILE *file, tree decl, const char *name)
{
- extern_symbol p = ggc_alloc (sizeof (struct extern_symbol));
+ extern_symbol * p = VEC_safe_push (extern_symbol, gc, extern_symbols, NULL);
gcc_assert (file == asm_out_file);
p->decl = decl;
p->name = name;
- VEC_safe_push (extern_symbol, extern_symbols, p);
}
/* Output text required at the end of an assembler file.
pa_hpux_file_end (void)
{
unsigned int i;
- extern_symbol p;
+ extern_symbol *p;
output_deferred_plabels ();
ASM_OUTPUT_EXTERNAL_REAL (asm_out_file, decl, p->name);
}
- extern_symbols = NULL;
+ VEC_free (extern_symbol, gc, extern_symbols);
}
#endif