diff options
author | aoliva <aoliva@138bc75d-0d04-0410-961f-82ee72b054a4> | 2001-02-02 18:20:29 +0000 |
---|---|---|
committer | aoliva <aoliva@138bc75d-0d04-0410-961f-82ee72b054a4> | 2001-02-02 18:20:29 +0000 |
commit | d1665c4c230fab5f73b9cef093fd9e936cd10552 (patch) | |
tree | 16c1afc47c7bb50194a1926d9777174059b437e7 /gcc/config/sh | |
parent | 35d2e451b0babfc001d3c8764a97e6cd48f43983 (diff) | |
download | gcc-d1665c4c230fab5f73b9cef093fd9e936cd10552.tar.gz |
* 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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@39410 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/config/sh')
-rw-r--r-- | gcc/config/sh/sh.c | 26 | ||||
-rw-r--r-- | gcc/config/sh/sh.md | 7 |
2 files changed, 28 insertions, 5 deletions
diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c index c89db668b90..4385a0fa6e0 100644 --- a/gcc/config/sh/sh.c +++ b/gcc/config/sh/sh.c @@ -715,6 +715,7 @@ output_far_jump (insn, op) 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)); @@ -726,21 +727,28 @@ output_far_jump (insn, op) && 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); @@ -758,12 +766,22 @@ output_far_jump (insn, op) 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 ""; diff --git a/gcc/config/sh/sh.md b/gcc/config/sh/sh.md index dbd9759c36f..7f5aefe5188 100644 --- a/gcc/config/sh/sh.md +++ b/gcc/config/sh/sh.md @@ -290,6 +290,8 @@ ;; ??? 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") @@ -306,6 +308,8 @@ ;; ??? 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))) @@ -3674,7 +3678,8 @@ [(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")]) |