Commit 746a9efa by Jeff Law

pa.h (MACHINE_DEPENDENT_REORG): Define.

	* pa.h (MACHINE_DEPENDENT_REORG): Define.
	* pa.md (switch_jump): New pattern for jumps which implement
	a switch table.
	* pa.c (pa_reorg): New function to explode jump tables.
	(pa_adjust_insn_length): Account for jumps in switch tables with
	unfilled delay slots.

From-SVN: r9318
parent 605a99f6
......@@ -2759,6 +2759,12 @@ pa_adjust_insn_length (insn, length)
else
return 0;
}
/* Jumps inside switch tables which have unfilled delay slots
also need adjustment. */
else if (GET_CODE (insn) == JUMP_INSN
&& simplejump_p (insn)
&& GET_MODE (PATTERN (insn)) == DImode)
return 4;
/* Millicode insn with an unfilled delay slot. */
else if (GET_CODE (insn) == INSN
&& GET_CODE (pat) != SEQUENCE
......@@ -4392,3 +4398,77 @@ jump_in_call_delay (insn)
else
return 0;
}
/* We use this hook to perform a PA specific optimization which is difficult
to do in earlier passes.
We want the delay slots of branches within jump tables to be filled.
None of the compiler passes at the moment even has the notion that a
PA jump table doesn't contain addresses, but instead contains actual
instructions!
Because we actually jump into the table, the addresses of each entry
must stay contant in relation to the beginning of the table (which
itself must stay constant relative to the instruction to jump into
it). I don't believe we can guarantee earlier passes of the compiler
will adhere to those rules.
So, late in the compilation process we find all the jump tables, and
expand them into real code -- eg each entry in the jump table vector
will get an appropriate label followed by a jump to the final target.
Reorg and the final jump pass can then optimize these branches and
fill their delay slots. We end up with smaller, more efficient code.
The jump instructions within the table are special; we must be able
to identify them during assembly output (if the jumps don't get filled
we need to emit a nop rather than nullifying the delay slot)). We
identify jumps in switch tables by marking the SET with DImode. */
pa_reorg (insns)
rtx insns;
{
rtx insn;
/* This is fairly cheap, so always run it if optimizing. */
if (optimize > 0)
{
/* Find and explode all ADDR_VEC insns. */
insns = get_insns ();
for (insn = insns; insn; insn = NEXT_INSN (insn))
{
rtx pattern, tmp, location;
unsigned int length, i;
/* Find an ADDR_VEC insn to explode. */
if (GET_CODE (insn) != JUMP_INSN
|| GET_CODE (PATTERN (insn)) != ADDR_VEC)
continue;
pattern = PATTERN (insn);
location = PREV_INSN (insn);
length = XVECLEN (pattern, 0);
for (i = 0; i < length; i++)
{
/* Emit the jump itself. */
tmp = gen_switch_jump (XEXP (XVECEXP (pattern, 0, i), 0));
tmp = emit_jump_insn_after (tmp, location);
JUMP_LABEL (tmp) = XEXP (XVECEXP (pattern, 0, i), 0);
/* Emit a BARRIER after the jump. */
location = NEXT_INSN (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);
}
/* Delete the ADDR_VEC. */
delete_insn (insn);
}
}
......@@ -239,6 +239,9 @@ extern int target_flags;
/* Show we can debug even without a frame pointer. */
#define CAN_DEBUG_WITHOUT_FP
/* Machine dependent reorg pass. */
#define MACHINE_DEPENDENT_REORG(X) pa_reorg(X)
/* Names to predefine in the preprocessor for this target machine. */
#define CPP_PREDEFINES "-Dhppa -Dhp9000s800 -D__hp9000s800 -Dhp9k8 -Dunix -D_HPUX_SOURCE -Dhp9000 -Dhp800 -Dspectrum -DREVARGV -Asystem(unix) -Asystem(bsd) -Acpu(hppa) -Amachine(hppa)"
......
......@@ -3405,6 +3405,13 @@
""
[(set_attr "length" "0")])
(define_insn "switch_jump"
[(set:DI (pc) (label_ref (match_operand 0 "" "")))]
""
"bl %l0,0%#"
[(set_attr "type" "uncond_branch")
(set_attr "length" "4")])
(define_insn "jump"
[(set (pc) (label_ref (match_operand 0 "" "")))]
""
......
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