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:
parent
d6567b3adf
commit
852dff6156
3 changed files with 91 additions and 22 deletions
|
@ -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.
|
||||
|
|
|
@ -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 "";
|
||||
}
|
||||
|
||||
|
|
|
@ -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")
|
||||
|
|
Loading…
Add table
Reference in a new issue