[NDS32] Rewrite PIC/TLS patterns.
authorMonk Chiang <sh.chiang04@gmail.com>
Mon, 15 Apr 2019 07:59:01 +0000 (07:59 +0000)
committerChung-Ju Wu <jasonwucj@gcc.gnu.org>
Mon, 15 Apr 2019 07:59:01 +0000 (07:59 +0000)
gcc/
* config/nds32/nds32-md-auxiliary.c
(nds32_legitimize_pic_address): Use new PIC pattern.
(nds32_legitimize_tls_address): Use new TLS pattern.
(nds32_output_symrel): New.
* config/nds32/nds32-protos.h (nds32_output_symrel): Declare.
(nds32_alloc_relax_group_id): Ditto.
* config/nds32/nds32-relax-opt.c (nds32_alloc_relax_group_id): New.
(nds32_group_insns): Use nds32_alloc_relax_group_id instead of use
relax_group_id.
(nds32_group_tls_insn): Ditto.
(nds32_group_float_insns): Ditto.
* config/nds32/nds32.md (tls_le): New.
(sym_got): Ditto.

Co-Authored-By: Kito Cheng <kito.cheng@gmail.com>
Co-Authored-By: Shiva Chen <shiva0217@gmail.com>
From-SVN: r270361

gcc/ChangeLog
gcc/config/nds32/nds32-md-auxiliary.c
gcc/config/nds32/nds32-protos.h
gcc/config/nds32/nds32-relax-opt.c
gcc/config/nds32/nds32.md

index cfd15892a114fcaee7fa41169a3dae0c47c6930e..a6eadedb57fe331a756c3a0cc71c835377e5d431 100644 (file)
@@ -1,3 +1,21 @@
+2019-04-15  Monk Chiang  <sh.chiang04@gmail.com>
+           Kito Cheng  <kito.cheng@gmail.com>
+           Shiva Chen  <shiva0217@gmail.com>
+
+       * config/nds32/nds32-md-auxiliary.c
+       (nds32_legitimize_pic_address): Use new PIC pattern.
+       (nds32_legitimize_tls_address): Use new TLS pattern.
+       (nds32_output_symrel): New.
+       * config/nds32/nds32-protos.h (nds32_output_symrel): Declare.
+       (nds32_alloc_relax_group_id): Ditto.
+       * config/nds32/nds32-relax-opt.c (nds32_alloc_relax_group_id): New.
+       (nds32_group_insns): Use nds32_alloc_relax_group_id instead of use
+       relax_group_id.
+       (nds32_group_tls_insn): Ditto.
+       (nds32_group_float_insns): Ditto.
+       * config/nds32/nds32.md (tls_le): New.
+       (sym_got): Ditto.
+
 2019-04-15  Chung-Ju Wu  <jasonwucj@gmail.com>
 
        * configure: Add nds32 target for dwarf2 debug_line checking.
index 3c510cf6500c69db50a84bf0227ba60c1bfab8ea..35fcc64511f52d394fda5cabbd6e97153ffa4d14 100644 (file)
@@ -3493,6 +3493,7 @@ nds32_legitimize_pic_address (rtx x)
   rtx addr = x;
   rtx reg = gen_reg_rtx (Pmode);
   rtx pat;
+  int relax_group_id = nds32_alloc_relax_group_id ();
 
   if (GET_CODE (x) == LABEL_REF
       || (GET_CODE (x) == SYMBOL_REF
@@ -3501,16 +3502,14 @@ nds32_legitimize_pic_address (rtx x)
     {
       addr = gen_rtx_UNSPEC (SImode, gen_rtvec (1, x), UNSPEC_GOTOFF);
       addr = gen_rtx_CONST (SImode, addr);
-      emit_insn (gen_sethi (reg, addr));
-      emit_insn (gen_lo_sum (reg, reg, addr));
+      emit_insn (gen_sym_got (reg, addr, GEN_INT (relax_group_id)));
       x = gen_rtx_PLUS (Pmode, reg, pic_offset_table_rtx);
     }
   else if (GET_CODE (x) == SYMBOL_REF)
     {
       addr = gen_rtx_UNSPEC (SImode, gen_rtvec (1, x), UNSPEC_GOT);
       addr = gen_rtx_CONST (SImode, addr);
-      emit_insn (gen_sethi (reg, addr));
-      emit_insn (gen_lo_sum (reg, reg, addr));
+      emit_insn (gen_sym_got (reg, addr, GEN_INT (relax_group_id)));
 
       x = gen_const_mem (SImode, gen_rtx_PLUS (Pmode, pic_offset_table_rtx,
                                               reg));
@@ -3534,8 +3533,7 @@ nds32_legitimize_pic_address (rtx x)
          pat = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, op0), UNSPEC_GOTOFF);
          pat = gen_rtx_PLUS (Pmode, pat, op1);
          pat = gen_rtx_CONST (Pmode, pat);
-         emit_insn (gen_sethi (reg, pat));
-         emit_insn (gen_lo_sum (reg, reg, pat));
+         emit_insn (gen_sym_got (reg, pat, GEN_INT (relax_group_id)));
          x = gen_rtx_PLUS (Pmode, reg, pic_offset_table_rtx);
        }
       else if (GET_CODE (op0) == SYMBOL_REF
@@ -3544,8 +3542,8 @@ nds32_legitimize_pic_address (rtx x)
          /* This is a constant offset from a @GOT symbol reference.  */
          addr = gen_rtx_UNSPEC (SImode, gen_rtvec (1, op0), UNSPEC_GOT);
          addr = gen_rtx_CONST (SImode, addr);
-         emit_insn (gen_sethi (reg, addr));
-         emit_insn (gen_lo_sum (reg, reg, addr));
+         emit_insn (gen_sym_got (reg, addr, GEN_INT (relax_group_id)));
+
          addr = gen_const_mem (SImode, gen_rtx_PLUS (Pmode,
                                                      pic_offset_table_rtx,
                                                      reg));
@@ -3668,6 +3666,7 @@ nds32_legitimize_tls_address (rtx x)
   rtx tmp_reg;
   rtx tp_reg = gen_rtx_REG (Pmode, TP_REGNUM);
   rtx pat, insns, reg0;
+  int relax_group_id = nds32_alloc_relax_group_id ();
 
   if (GET_CODE (x) == SYMBOL_REF)
     switch (SYMBOL_REF_TLS_MODEL (x))
@@ -3685,7 +3684,7 @@ nds32_legitimize_tls_address (rtx x)
        reg0 = gen_rtx_REG (Pmode, 0);
        /* If we can confirm all clobber reigsters, it doesn't have to use call
           instruction.  */
-       insns = emit_call_insn (gen_tls_desc (pat, GEN_INT (0)));
+       insns = emit_call_insn (gen_tls_desc (pat, GEN_INT (relax_group_id)));
        use_reg (&CALL_INSN_FUNCTION_USAGE (insns), pic_offset_table_rtx);
        RTL_CONST_CALL_P (insns) = 1;
        tmp_reg = gen_reg_rtx (SImode);
@@ -3697,7 +3696,7 @@ nds32_legitimize_tls_address (rtx x)
        pat = gen_rtx_UNSPEC (SImode, gen_rtvec (1, x), UNSPEC_TLSIE);
        tmp_reg  = gen_reg_rtx (SImode);
        pat = gen_rtx_CONST (SImode, pat);
-       emit_insn (gen_tls_ie (tmp_reg, pat, GEN_INT (0)));
+       emit_insn (gen_tls_ie (tmp_reg, pat, GEN_INT (relax_group_id)));
        if (flag_pic)
          emit_use (pic_offset_table_rtx);
        x = gen_rtx_PLUS (Pmode, tmp_reg, tp_reg);
@@ -3711,8 +3710,7 @@ nds32_legitimize_tls_address (rtx x)
        tmp_reg  = gen_reg_rtx (SImode);
        pat = gen_rtx_UNSPEC (SImode, gen_rtvec (1, x), UNSPEC_TLSLE);
        pat = gen_rtx_CONST (SImode, pat);
-       emit_insn (gen_sethi (tmp_reg, pat));
-       emit_insn (gen_lo_sum (tmp_reg, tmp_reg, pat));
+       emit_insn (gen_tls_le (tmp_reg, pat, GEN_INT (relax_group_id)));
        x = gen_rtx_PLUS (Pmode, tmp_reg, tp_reg);
        break;
 
@@ -3734,8 +3732,7 @@ nds32_legitimize_tls_address (rtx x)
          pat = gen_rtx_UNSPEC (SImode, gen_rtvec (1, base), UNSPEC_TLSLE);
          pat = gen_rtx_PLUS (SImode, pat, addend);
          pat = gen_rtx_CONST (SImode, pat);
-         emit_insn (gen_sethi (tmp_reg, pat));
-         emit_insn (gen_lo_sum (tmp_reg, tmp_reg, pat));
+         emit_insn (gen_tls_le (tmp_reg, pat, GEN_INT (relax_group_id)));
          x = gen_rtx_PLUS (Pmode, tmp_reg, tp_reg);
        }
     }
@@ -3914,3 +3911,21 @@ nds32_output_tls_ie (rtx *operands)
   output_asm_insn (pattern, operands);
   return "";
 }
+
+const char *
+nds32_output_symrel (rtx *operands)
+{
+  char pattern[1000];
+
+  if (TARGET_RELAX_HINT)
+    snprintf (pattern, sizeof (pattern),
+             ".relax_hint %%2\n\tsethi %%0, hi20(%%1)\n\t"
+             ".relax_hint %%2\n\tori %%0, %%0, lo12(%%1)");
+  else
+    snprintf (pattern, sizeof (pattern),
+             "sethi %%0, hi20(%%1)\n\t"
+             "ori %%0, %%0, lo12(%%1)");
+
+  output_asm_insn (pattern, operands);
+  return "";
+}
index 38aaca9d8e252ada107aad205b3fc4daa3c52303..aaa65d6f038f7384c159483599bbadea7e72e81c 100644 (file)
@@ -256,6 +256,7 @@ extern const char *nds32_output_call (rtx, rtx *, rtx,
                                      const char *, const char *, bool);
 extern const char *nds32_output_tls_desc (rtx *);
 extern const char *nds32_output_tls_ie (rtx *);
+extern const char *nds32_output_symrel (rtx *);
 
 /* Auxiliary functions to output stack push/pop instruction.  */
 
@@ -369,4 +370,6 @@ extern bool nds32_use_load_post_increment(machine_mode);
 extern rtl_opt_pass *make_pass_nds32_relax_opt (gcc::context *);
 extern rtl_opt_pass *make_pass_nds32_fp_as_gp (gcc::context *);
 
+extern int nds32_alloc_relax_group_id ();
+
 /* ------------------------------------------------------------------------ */
index 25be202687dbd31f8e00fec0dbf804318511d90a..5da27530cd61c5c262771d090df54482dad4f540 100644 (file)
@@ -78,6 +78,12 @@ static int relax_group_id = 0;
       lwi37    $rb, [(sym)]
       swi37    $rc, [(sym)] */
 
+int
+nds32_alloc_relax_group_id ()
+{
+  return relax_group_id++;
+}
+
 /* Return true if is load/store with REG addressing mode
    and memory mode is SImode.  */
 static bool
@@ -345,7 +351,7 @@ nds32_group_insns (rtx_insn *sethi)
        return;
     }
 
-  group_id = GEN_INT (relax_group_id);
+  group_id = GEN_INT (nds32_alloc_relax_group_id ());
   /* Insert .relax_* directive for sethi.  */
   emit_insn_before (gen_relax_group (group_id), sethi);
 
@@ -378,8 +384,6 @@ nds32_group_insns (rtx_insn *sethi)
            }
        }
     }
-
-  relax_group_id++;
 }
 
 /* Convert relax group id in rtl.  */
@@ -389,6 +393,7 @@ nds32_group_tls_insn (rtx insn)
 {
   rtx pat = PATTERN (insn);
   rtx unspec_relax_group = XEXP (XVECEXP (pat, 0, 1), 0);
+  int group_id = nds32_alloc_relax_group_id ();
 
   while (GET_CODE (pat) != SET && GET_CODE (pat) == PARALLEL)
     {
@@ -398,10 +403,8 @@ nds32_group_tls_insn (rtx insn)
   if (GET_CODE (unspec_relax_group) == UNSPEC
       && XINT (unspec_relax_group, 1) == UNSPEC_VOLATILE_RELAX_GROUP)
     {
-      XVECEXP (unspec_relax_group, 0, 0) = GEN_INT (relax_group_id);
+      XVECEXP (unspec_relax_group, 0, 0) = GEN_INT (group_id);
     }
-
-  relax_group_id++;
 }
 
 static bool
@@ -472,7 +475,7 @@ nds32_group_float_insns (rtx_insn *insn)
        return;
     }
 
-  group_id = GEN_INT (relax_group_id);
+  group_id = GEN_INT (nds32_alloc_relax_group_id ());
   /* Insert .relax_* directive for insn.  */
   emit_insn_before (gen_relax_group (group_id), insn);
 
@@ -487,8 +490,6 @@ nds32_group_float_insns (rtx_insn *insn)
       /* Insert .relax_* directive.  */
        emit_insn_before (gen_relax_group (group_id), use_insn);
     }
-
-  relax_group_id++;
 }
 
 /* Group the relax candidate instructions for linker.  */
index f9eba0a27d4750d5cf9d45749cad4be505a9d801..1e5f8decadaf73585bd7677ac33ea84a7d897811 100644 (file)
    (set_attr "type" "misc")]
 )
 
+;; There is a unspec operand to record RELAX_GROUP number because each
+;; emitted instruction need a relax_hint above it.
+(define_insn "tls_le"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+       (unspec:SI [(match_operand:SI 1 "nds32_symbolic_operand" "i")] UNSPEC_TLS_IE))
+   (use (unspec [(match_operand:SI 2 "immediate_operand" "i")] UNSPEC_VOLATILE_RELAX_GROUP))]
+  ""
+  {
+    return nds32_output_symrel (operands);
+  }
+  [(set_attr "length" "8")
+   (set_attr "type"   "misc")]
+)
+
 ;; The pattern is for some relaxation groups that have to keep addsi3 in 32-bit mode.
 (define_insn "addsi3_32bit"
   [(set (match_operand:SI 0 "register_operand"             "=r")
    (set_attr "length"  "4")
    (set_attr "feature" "v1")])
 
+;; Patterns for PIC.
+(define_insn "sym_got"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+       (unspec:SI [(match_operand:SI 1 "nds32_symbolic_operand" "i")] UNSPEC_GOT))
+   (use (unspec [(match_operand:SI 2 "immediate_operand" "i")] UNSPEC_VOLATILE_RELAX_GROUP))]
+  ""
+  {
+    return nds32_output_symrel (operands);
+  }
+  [(set_attr "length" "8")
+   (set_attr "type"   "misc")]
+)
+
 ;; ----------------------------------------------------------------------------