2001-02-02 Alexandre Oliva <aoliva@redhat.com>
+ * config/sh/sh.c (output_far_jump): Don't use braf on SH1. Emit
+ label before alignment to be used as the braf base address.
+ * config/sh/sh.md (length): Use longer lengths for SH1 PIC far
+ branches.
+ (casesi_jump_2): Require at least TARGET_SH2.
+
* config/float-sh.h (LDBL_EPSILON, LDBL_MIN, LDBL_MAX): Prevent
truncation to 32-bit doubles on -m3e and -m4-single-only.
rtx op;
{
struct { rtx lab, reg, op; } this;
+ rtx braf_base_lab;
const char *jump;
int far;
int offset = branch_dest (insn) - INSN_ADDRESSES (INSN_UID (insn));
&& offset - get_attr_length (insn) <= 32766)
{
far = 0;
- jump = "mov.w %O0,%1;braf %1";
+ jump = "mov.w %O0,%1; braf %1";
}
else
{
far = 1;
if (flag_pic)
- jump = "mov.l %O0,%1;braf %1";
+ {
+ if (TARGET_SH2)
+ jump = "mov.l %O0,%1; braf %1";
+ else
+ jump = "mov.l r0,@-r15; mova %O0,r0; mov.l @r0,%1; add r0,%1; mov.l @r15+,r0; jmp @%1";
+ }
else
- jump = "mov.l %O0,%1;jmp @%1";
+ jump = "mov.l %O0,%1; jmp @%1";
}
/* If we have a scratch register available, use it. */
if (GET_CODE (PREV_INSN (insn)) == INSN
&& INSN_CODE (PREV_INSN (insn)) == CODE_FOR_indirect_jump_scratch)
{
this.reg = SET_DEST (PATTERN (PREV_INSN (insn)));
+ if (REGNO (this.reg) == R0_REG && flag_pic && ! TARGET_SH2)
+ jump = "mov.l r1,@-r15; mova %O0,r0; mov.l @r0,r1; add r1,r0; mov.l @r15+,r1; jmp @%1";
output_asm_insn (jump, &this.lab);
if (dbr_sequence_length ())
print_slot (final_sequence);
output_asm_insn (jump, &this.lab);
output_asm_insn ("mov.l @r15+,r13", 0);
}
+ if (far && flag_pic && TARGET_SH2)
+ {
+ braf_base_lab = gen_label_rtx ();
+ ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
+ CODE_LABEL_NUMBER (braf_base_lab));
+ }
if (far)
output_asm_insn (".align 2", 0);
ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L", CODE_LABEL_NUMBER (this.lab));
this.op = op;
if (far && flag_pic)
- output_asm_insn (".long %O2-%O0", &this.lab);
+ {
+ if (TARGET_SH2)
+ this.lab = braf_base_lab;
+ output_asm_insn (".long %O2-%O0", &this.lab);
+ }
else
output_asm_insn (far ? ".long %O2" : ".word %O2-%O0", &this.lab);
return "";
;; ??? using pc is not computed transitively.
(ne (match_dup 0) (match_dup 0))
(const_int 14)
+ (ne (symbol_ref ("flag_pic")) (const_int 0))
+ (const_int 24)
] (const_int 16))
(eq_attr "type" "jump")
(cond [(eq_attr "med_branch_p" "yes")
;; ??? using pc is not computed transitively.
(ne (match_dup 0) (match_dup 0))
(const_int 12)
+ (ne (symbol_ref ("flag_pic")) (const_int 0))
+ (const_int 22)
] (const_int 14))
] (const_int 2)))
[(set (pc) (plus:SI (match_operand:SI 0 "register_operand" "r")
(label_ref (match_operand 1 "" ""))))
(use (label_ref (match_operand 2 "" "")))]
- "! INSN_UID (operands[1]) || prev_real_insn (operands[1]) == insn"
+ "TARGET_SH2
+ && (! INSN_UID (operands[1]) || prev_real_insn (operands[1]) == insn)"
"braf %0%#"
[(set_attr "needs_delay_slot" "yes")
(set_attr "type" "jump_ind")])