mips.c (mips_output_conditional_branch): Support PIC-safe out-of-range branch and branch-likely.

* config/mips/mips.c (mips_output_conditional_branch): Support
PIC-safe out-of-range branch and branch-likely.
* config/mips/mips.md (attr length): PIC-safe out-of-range
branches are longer.
("jump"): Support PIC-safe out-of-range-for-branch jumps.  Remove
unused code to support indirect jumps.

From-SVN: r60058
This commit is contained in:
Alexandre Oliva 2002-12-12 05:13:04 +00:00 committed by Alexandre Oliva
parent d6567b3adf
commit 852dff6156
3 changed files with 91 additions and 22 deletions

View File

@ -1,3 +1,12 @@
2002-12-12 Alexandre Oliva <aoliva@redhat.com>
* config/mips/mips.c (mips_output_conditional_branch): Support
PIC-safe out-of-range branch and branch-likely.
* config/mips/mips.md (attr length): PIC-safe out-of-range
branches are longer.
("jump"): Support PIC-safe out-of-range-for-branch jumps. Remove
unused code to support indirect jumps.
2002-12-11 John David Anglin <dave@hiauly1.hia.nrc.ca>
* pa.h (BIGGEST_ALIGNMENT): Change 32-bit value to 64 bits.

View File

@ -10177,6 +10177,8 @@ mips_output_conditional_branch (insn,
case 12:
case 16:
case 24:
case 28:
{
/* Generate a reversed conditional branch around ` j'
instruction:
@ -10184,18 +10186,41 @@ mips_output_conditional_branch (insn,
.set noreorder
.set nomacro
bc l
nop
delay_slot or #nop
j target
#nop
l:
.set macro
.set reorder
l:
If the original branch was a likely branch, the delay slot
must be executed only if the branch is taken, so generate:
.set noreorder
.set nomacro
bc l
#nop
j target
delay slot or #nop
l:
.set macro
.set reorder
When generating non-embedded PIC, instead of:
j target
we emit:
.set noat
la $at, target
jr $at
.set at
*/
rtx orig_target;
rtx target = gen_label_rtx ();
output_asm_insn ("%(%<", 0);
orig_target = operands[1];
operands[1] = target;
/* Generate the reversed comparison. This takes four
@ -10210,13 +10235,8 @@ mips_output_conditional_branch (insn,
op1,
op2);
output_asm_insn (buffer, operands);
operands[1] = orig_target;
output_asm_insn ("nop\n\tj\t%1", operands);
if (length == 16)
output_asm_insn ("nop", 0);
else
if (length != 16 && length != 28 && ! mips_branch_likely)
{
/* Output delay slot instruction. */
rtx insn = final_sequence;
@ -10224,9 +10244,33 @@ mips_output_conditional_branch (insn,
optimize, 0, 1);
INSN_DELETED_P (XVECEXP (insn, 0, 1)) = 1;
}
output_asm_insn ("%>%)", 0);
else
output_asm_insn ("%#", 0);
if (length <= 16)
output_asm_insn ("j\t%0", &orig_target);
else
{
if (Pmode == DImode)
output_asm_insn ("%[dla\t%@,%0\n\tjr\t%@%]", &orig_target);
else
output_asm_insn ("%[la\t%@,%0\n\tjr\t%@%]", &orig_target);
}
if (length != 16 && length != 28 && mips_branch_likely)
{
/* Output delay slot instruction. */
rtx insn = final_sequence;
final_scan_insn (XVECEXP (insn, 0, 1), asm_out_file,
optimize, 0, 1);
INSN_DELETED_P (XVECEXP (insn, 0, 1)) = 1;
}
else
output_asm_insn ("%#", 0);
ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
CODE_LABEL_NUMBER (target));
return "";
}

View File

@ -105,9 +105,12 @@
(cond [(eq_attr "type" "branch")
(cond [(lt (abs (minus (match_dup 1) (plus (pc) (const_int 4))))
(const_int 131072))
(const_int 4)]
(const_int 12))]
(const_int 4)))
(const_int 4)
(ne (symbol_ref "flag_pic && ! TARGET_EMBEDDED_PIC")
(const_int 0))
(const_int 24)
] (const_int 12))
] (const_int 4)))
;; Attribute describing the processor. This attribute must match exactly
;; with the processor_type enumeration in mips.h.
@ -9592,18 +9595,31 @@ move\\t%0,%z4\\n\\
"!TARGET_MIPS16"
"*
{
if (GET_CODE (operands[0]) == REG)
return \"%*j\\t%0\";
/* ??? I don't know why this is necessary. This works around an
assembler problem that appears when a label is defined, then referenced
in a switch table, then used in a `j' instruction. */
else if (mips_abi != ABI_32 && mips_abi != ABI_O64)
return \"%*b\\t%l0\";
if (flag_pic && ! TARGET_EMBEDDED_PIC)
{
if (get_attr_length (insn) <= 8)
return \"%*b\\t%l0\";
else if (Pmode == DImode)
return \"%[dla\\t%@,%l0\;%*jr\\t%@%]\";
else
return \"%[la\\t%@,%l0\;%*jr\\t%@%]\";
}
else
return \"%*j\\t%l0\";
}"
[(set_attr "type" "jump")
(set_attr "mode" "none")])
(set_attr "mode" "none")
(set (attr "length")
;; we can't use `j' when emitting non-embedded PIC, so we emit
;; branch, if it's in range, or load the address of the branch
;; target into $at in a PIC-compatible way and then jump to it.
(if_then_else
(ior (eq (symbol_ref "flag_pic && ! TARGET_EMBEDDED_PIC")
(const_int 0))
(lt (abs (minus (match_dup 0)
(plus (pc) (const_int 4))))
(const_int 131072)))
(const_int 4) (const_int 16)))])
;; We need a different insn for the mips16, because a mips16 branch
;; does not have a delay slot.
@ -9611,7 +9627,7 @@ move\\t%0,%z4\\n\\
(define_insn ""
[(set (pc)
(label_ref (match_operand 0 "" "")))]
"TARGET_MIPS16 && GET_CODE (operands[0]) != REG"
"TARGET_MIPS16"
"b\\t%l0"
[(set_attr "type" "branch")
(set_attr "mode" "none")