OSDN Git Service

* config/sh/sh.c (output_far_jump): Don't use braf on SH1. Emit
authoraoliva <aoliva@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 2 Feb 2001 18:20:29 +0000 (18:20 +0000)
committeraoliva <aoliva@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 2 Feb 2001 18:20:29 +0000 (18:20 +0000)
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

gcc/ChangeLog
gcc/config/sh/sh.c
gcc/config/sh/sh.md

index 455cbbc..49c0628 100644 (file)
@@ -1,5 +1,11 @@
 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.
 
index c89db66..4385a0f 100644 (file)
@@ -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 "";
index dbd9759..7f5aefe 100644 (file)
 ;; ??? 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")])