#undef TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA
#define TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA rs6000_output_addr_const_extra
+#undef TARGET_ASM_GENERATE_PIC_ADDR_DIFF_VEC
+#define TARGET_ASM_GENERATE_PIC_ADDR_DIFF_VEC rs6000_gen_pic_addr_diff_vec
+
#undef TARGET_LEGITIMIZE_ADDRESS
#define TARGET_LEGITIMIZE_ADDRESS rs6000_legitimize_address
emit_insn( gen_xxspltidp_v2df_inst (dst, GEN_INT (value)));
}
+/* Implement TARGET_ASM_GENERATE_PIC_ADDR_DIFF_VEC. */
+
+static bool
+rs6000_gen_pic_addr_diff_vec (void)
+{
+ return rs6000_relative_jumptables;
+}
+
+void
+rs6000_output_addr_vec_elt (FILE *file, int value)
+{
+ const char *directive = TARGET_64BIT ? DOUBLE_INT_ASM_OP : "\t.long\t";
+ char buf[100];
+
+ fprintf (file, "%s", directive);
+ ASM_GENERATE_INTERNAL_LABEL (buf, "L", value);
+ assemble_name (file, buf);
+ fprintf (file, "\n");
+}
+
struct gcc_target targetm = TARGET_INITIALIZER;
#include "gt-rs6000.h"
/* #define LEGITIMATE_PIC_OPERAND_P (X) */
\f
-/* Specify the machine mode that this machine uses
- for the index in the tablejump instruction. */
-#define CASE_VECTOR_MODE SImode
-
/* Define as C expression which evaluates to nonzero if the tablejump
instruction expects the table to contain offsets from the address of the
table.
Do not define this if the table should contain absolute addresses. */
-#define CASE_VECTOR_PC_RELATIVE 1
+#define CASE_VECTOR_PC_RELATIVE rs6000_relative_jumptables
+
+/* Specify the machine mode that this machine uses
+ for the index in the tablejump instruction. */
+#define CASE_VECTOR_MODE (rs6000_relative_jumptables ? SImode : Pmode)
/* Define this as 1 if `char' should by default be signed; else as 0. */
#define DEFAULT_SIGNED_CHAR 0
putc ('\n', FILE); \
} while (0)
+/* This is how to output an element of a case-vector
+ that is non-relative. */
+#define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \
+ rs6000_output_addr_vec_elt ((FILE), (VALUE))
+
/* This is how to output an assembler line
that says to advance the location counter
to a multiple of 2**LOG bytes. */
""
{
if (rs6000_speculate_indirect_jumps)
- emit_jump_insn (gen_tablejump_normal (Pmode, operands[0], operands[1]));
+ {
+ if (rs6000_relative_jumptables)
+ emit_jump_insn (gen_tablejump_normal (Pmode, operands[0], operands[1]));
+ else
+ emit_jump_insn (gen_tablejump_absolute (Pmode, operands[0],
+ operands[1]));
+ }
else
{
rtx ccreg = gen_reg_rtx (CCmode);
rtx jump;
- if (TARGET_32BIT)
- jump = gen_tablejumpsi_nospec (operands[0], operands[1], ccreg);
+ if (rs6000_relative_jumptables)
+ jump = gen_tablejump_nospec (Pmode, operands[0], operands[1], ccreg);
else
- jump = gen_tablejumpdi_nospec (operands[0], operands[1], ccreg);
+ jump = gen_tablejump_absolute_nospec (Pmode, operands[0], operands[1],
+ ccreg);
emit_jump_insn (jump);
}
DONE;
(define_expand "@tablejump<mode>_normal"
[(use (match_operand:SI 0))
(use (match_operand:P 1))]
- "rs6000_speculate_indirect_jumps"
+ "rs6000_speculate_indirect_jumps && rs6000_relative_jumptables"
{
rtx off = force_reg (SImode, operands[0]);
if (<MODE>mode != SImode)
DONE;
})
+(define_expand "@tablejump<mode>_absolute"
+ [(use (match_operand:P 0))
+ (use (match_operand:P 1))]
+ "rs6000_speculate_indirect_jumps && !rs6000_relative_jumptables"
+{
+ rtx addr = gen_reg_rtx (Pmode);
+ emit_move_insn (addr, operands[0]);
+
+ emit_jump_insn (gen_tablejump_insn_normal (Pmode, addr, operands[1]));
+ DONE;
+})
+
(define_expand "@tablejump<mode>_nospec"
[(use (match_operand:SI 0))
(use (match_operand:P 1))
(use (match_operand:CC 2))]
- "!rs6000_speculate_indirect_jumps"
+ "!rs6000_speculate_indirect_jumps && rs6000_relative_jumptables"
{
rtx off = force_reg (SImode, operands[0]);
if (<MODE>mode != SImode)
DONE;
})
+(define_expand "@tablejump<mode>_absolute_nospec"
+ [(use (match_operand:P 0))
+ (use (match_operand:P 1))
+ (use (match_operand:CC 2))]
+ "!rs6000_speculate_indirect_jumps && !rs6000_relative_jumptables"
+{
+ rtx addr = gen_reg_rtx (Pmode);
+ emit_move_insn (addr, operands[0]);
+
+ emit_jump_insn (gen_tablejump_insn_nospec (Pmode, addr, operands[1],
+ operands[2]));
+ DONE;
+})
+
(define_insn "@tablejump<mode>_insn_normal"
[(set (pc)
(match_operand:P 0 "register_operand" "c,*l"))