summaryrefslogtreecommitdiff
path: root/gcc/config/sh
diff options
context:
space:
mode:
authoraoliva <aoliva@138bc75d-0d04-0410-961f-82ee72b054a4>2001-02-02 18:20:29 +0000
committeraoliva <aoliva@138bc75d-0d04-0410-961f-82ee72b054a4>2001-02-02 18:20:29 +0000
commitd1665c4c230fab5f73b9cef093fd9e936cd10552 (patch)
tree16c1afc47c7bb50194a1926d9777174059b437e7 /gcc/config/sh
parent35d2e451b0babfc001d3c8764a97e6cd48f43983 (diff)
downloadgcc-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.c26
-rw-r--r--gcc/config/sh/sh.md7
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")])