Commit 3e056efc by Jeff Law

pa.c (pa_reorg): If TARGET_BIG_SWITCH, then do not explode ADDR_VEC insns.

        * pa.c (pa_reorg): If TARGET_BIG_SWITCH, then do not explode
        ADDR_VEC insns.  Slightly rework code which explodes ADDR_VEC
        insns.
        * pa.h (TARGET_BIG_SWITCH): Define.
        (TARGET_SWITCHES): Add "big-switch" and "no-big-switch".
        (CASE_VECTOR_MODE): Use TI or DI depending on TARGET_BIG_SWITCH.
        (CASE_DROPS_THROUGH): Remove definition.
        (ASM_OUTPUT_ADDR_VEC_ELT): Rewrite to handle TARGET_BIG_SWITCH.
        (ASM_OUTPUT_ADDR_DIFF_ELT): Likewise.
        * pa.md (casesi): Rework to avoid some potential long branch
        problems (also makes generated code faster!).  Handle
        TARGET_BIG_SWITCH.
        (casesi0): Corresponding changes.

From-SVN: r14528
parent b60334e8
...@@ -5807,7 +5807,7 @@ pa_reorg (insns) ...@@ -5807,7 +5807,7 @@ pa_reorg (insns)
pa_combine_instructions (get_insns ()); pa_combine_instructions (get_insns ());
/* This is fairly cheap, so always run it if optimizing. */ /* This is fairly cheap, so always run it if optimizing. */
if (optimize > 0) if (optimize > 0 && !TARGET_BIG_SWITCH)
{ {
/* Find and explode all ADDR_VEC insns. */ /* Find and explode all ADDR_VEC insns. */
insns = get_insns (); insns = get_insns ();
...@@ -5831,28 +5831,33 @@ pa_reorg (insns) ...@@ -5831,28 +5831,33 @@ pa_reorg (insns)
for (i = 0; i < length; i++) for (i = 0; i < length; i++)
{ {
/* Emit a label before each jump to keep jump.c from
removing this code. */
tmp = gen_label_rtx ();
LABEL_NUSES (tmp) = 1;
emit_label_after (tmp, location);
location = NEXT_INSN (location);
/* Emit the jump itself. */ /* Emit the jump itself. */
tmp = gen_switch_jump (XEXP (XVECEXP (pattern, 0, i), 0)); tmp = gen_switch_jump (XEXP (XVECEXP (pattern, 0, i), 0));
tmp = emit_jump_insn_after (tmp, location); tmp = emit_jump_insn_after (tmp, location);
JUMP_LABEL (tmp) = XEXP (XVECEXP (pattern, 0, i), 0); JUMP_LABEL (tmp) = XEXP (XVECEXP (pattern, 0, i), 0);
LABEL_NUSES (JUMP_LABEL (tmp))++; LABEL_NUSES (JUMP_LABEL (tmp))++;
location = NEXT_INSN (location);
/* Emit a BARRIER after the jump. */ /* Emit a BARRIER after the jump. */
location = NEXT_INSN (location);
emit_barrier_after (location); emit_barrier_after (location);
/* Put a CODE_LABEL before each so jump.c does not optimize
the jumps away. */
location = NEXT_INSN (location);
tmp = gen_label_rtx ();
LABEL_NUSES (tmp) = 1;
emit_label_after (tmp, location);
location = NEXT_INSN (location); location = NEXT_INSN (location);
} }
/* If needed, emit marker for the end of the branch table. */ /* If needed, emit marker for the end of the branch table. */
if (TARGET_GAS) if (TARGET_GAS)
emit_insn_before (gen_end_brtab (), location); {
emit_insn_before (gen_end_brtab (), location);
location = NEXT_INSN (location);
emit_barrier_after (location);
}
/* Delete the ADDR_VEC. */ /* Delete the ADDR_VEC. */
delete_insn (insn); delete_insn (insn);
} }
......
...@@ -112,6 +112,10 @@ extern int target_flags; ...@@ -112,6 +112,10 @@ extern int target_flags;
/* Use a faster sequence for indirect calls. */ /* Use a faster sequence for indirect calls. */
#define TARGET_FAST_INDIRECT_CALLS (target_flags & 1024) #define TARGET_FAST_INDIRECT_CALLS (target_flags & 1024)
/* Generate code with big switch statements to avoid out of range branches
occuring within the switch table. */
#define TARGET_BIG_SWITCH (target_flags & 2048)
/* Macro to define tables used to set the flags. /* Macro to define tables used to set the flags.
This is a list in braces of pairs in braces, This is a list in braces of pairs in braces,
each pair being { "NAME", VALUE } each pair being { "NAME", VALUE }
...@@ -143,6 +147,8 @@ extern int target_flags; ...@@ -143,6 +147,8 @@ extern int target_flags;
{"no-long-load-store", -512},\ {"no-long-load-store", -512},\
{"fast-indirect-calls", 1024},\ {"fast-indirect-calls", 1024},\
{"no-fast-indirect-calls", -1024},\ {"no-fast-indirect-calls", -1024},\
{"big-switch", 2048}, \
{"no-big-switch", -2048}, \
{"linker-opt", 0}, \ {"linker-opt", 0}, \
{ "", TARGET_DEFAULT | TARGET_CPU_DEFAULT}} { "", TARGET_DEFAULT | TARGET_CPU_DEFAULT}}
...@@ -1677,14 +1683,8 @@ while (0) ...@@ -1677,14 +1683,8 @@ while (0)
/* Specify the machine mode that this machine uses /* Specify the machine mode that this machine uses
for the index in the tablejump instruction. */ for the index in the tablejump instruction. */
#define CASE_VECTOR_MODE DImode #define CASE_VECTOR_MODE (TARGET_BIG_SWITCH ? TImode : DImode)
/* Define this 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 */
#define CASE_DROPS_THROUGH
/* Specify the tree operation to be used to convert reals to integers. */ /* Specify the tree operation to be used to convert reals to integers. */
#define IMPLICIT_FIX_EXPR FIX_ROUND_EXPR #define IMPLICIT_FIX_EXPR FIX_ROUND_EXPR
...@@ -2205,7 +2205,10 @@ DTORS_SECTION_FUNCTION ...@@ -2205,7 +2205,10 @@ DTORS_SECTION_FUNCTION
impossible. */ impossible. */
#define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \ #define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \
fprintf (FILE, "\tb L$%04d\n\tnop\n", VALUE) if (TARGET_BIG_SWITCH) \
fprintf (FILE, "\tstw %%r1,-16(%%r30)\n\tldil LR'L$%04d,%%r1\n\tbe RR'L$%04d(%%sr4,%%r1)\n\tldw -16(%%r30),%%r1\n", VALUE, VALUE); \
else \
fprintf (FILE, "\tb L$%04d\n\tnop\n", VALUE)
/* Jump tables are executable code and live in the TEXT section on the PA. */ /* Jump tables are executable code and live in the TEXT section on the PA. */
#define JUMP_TABLES_IN_TEXT_SECTION #define JUMP_TABLES_IN_TEXT_SECTION
...@@ -2218,7 +2221,10 @@ DTORS_SECTION_FUNCTION ...@@ -2218,7 +2221,10 @@ DTORS_SECTION_FUNCTION
rather than a table of absolute addresses. */ rather than a table of absolute addresses. */
#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, VALUE, REL) \ #define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, VALUE, REL) \
fprintf (FILE, "\tb L$%04d\n\tnop\n", VALUE) if (TARGET_BIG_SWITCH) \
fprintf (FILE, "\tstw %%r1,-16(%%r30)\n\tldw T'L$%04d(%%r19),%%r1\n\tbv 0(%%r1)\n\tldw -16(%%r30),%%r1\n", VALUE); \
else \
fprintf (FILE, "\tb L$%04d\n\tnop\n", VALUE)
/* This is how to output an assembler line /* This is how to output an assembler line
that says to advance the location counter that says to advance the location counter
......
...@@ -4006,37 +4006,29 @@ ...@@ -4006,37 +4006,29 @@
operands[0] = reg; operands[0] = reg;
} }
if (!INT_11_BITS (operands[2])) if (!INT_5_BITS (operands[2]))
operands[2] = force_reg (SImode, operands[2]); operands[2] = force_reg (SImode, operands[2]);
emit_jump_insn (gen_casesi0 (operands[0], operands[2], emit_insn (gen_cmpsi (operands[0], operands[2]));
operands[3], operands[4])); emit_jump_insn (gen_bgtu (operands[4]));
if (TARGET_BIG_SWITCH)
{
rtx temp = gen_reg_rtx (SImode);
emit_move_insn (temp, gen_rtx (PLUS, SImode, operands[0], operands[0]));
operands[0] = temp;
}
emit_jump_insn (gen_casesi0 (operands[0], operands[3]));
DONE; DONE;
}") }")
(define_insn "casesi0" (define_insn "casesi0"
[(set (pc) [(set (pc) (plus:SI
(if_then_else (leu (match_operand:SI 0 "register_operand" "r") (mem:SI (plus:SI (pc) (match_operand 0 "register_operand" "r")))
(match_operand:SI 1 "arith11_operand" "rI")) (label_ref (match_operand 1 "" ""))))]
(plus:SI (mem:SI (plus:SI (pc) (match_dup 0)))
(label_ref (match_operand 2 "" "")))
(pc)))
(use (label_ref (match_operand 3 "" "")))]
"" ""
"* "blr %0,0\;nop"
{
if (GET_CODE (operands[1]) == CONST_INT)
{
operands[1] = GEN_INT (~INTVAL (operands[1]));
return \"addi,uv %1,%0,0\;blr,n %0,0\;b,n %l3\";
}
else
{
return \"sub,>> %0,%1,0\;blr,n %0,0\;b,n %l3\";
}
}"
[(set_attr "type" "multi") [(set_attr "type" "multi")
(set_attr "length" "12")]) (set_attr "length" "8")])
;; Need nops for the calls because execution is supposed to continue ;; Need nops for the calls because execution is supposed to continue
;; past; we don't want to nullify an instruction that we need. ;; past; we don't want to nullify an instruction that we need.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment