OSDN Git Service

M68K TLS support.
[pf3gnuchains/gcc-fork.git] / gcc / config / m68k / m68k.md
index 33058fa..037bb37 100644 (file)
    (UNSPEC_GOT 3)
    (UNSPEC_IB 4)
    (UNSPEC_TIE 5)
-   (UNSPEC_GOTOFF 6)
+   (UNSPEC_RELOC16 6)
+   (UNSPEC_RELOC32 7)
   ])
 
 ;; UNSPEC_VOLATILE usage:
 {
   rtx tmp, base, offset;
 
-  if (flag_pic && !TARGET_PCREL && symbolic_operand (operands[1], SImode))
+  /* Recognize the case where operand[1] is a reference to thread-local
+     data and load its address to a register.  */
+  if (!TARGET_PCREL && m68k_tls_reference_p (operands[1], false))
+    {
+      rtx tmp = operands[1];
+      rtx addend = NULL;
+
+      if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS)
+        {
+          addend = XEXP (XEXP (tmp, 0), 1);
+          tmp = XEXP (XEXP (tmp, 0), 0);
+        }
+
+      gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
+      gcc_assert (SYMBOL_REF_TLS_MODEL (tmp) != 0);
+
+      tmp = m68k_legitimize_tls_address (tmp);
+
+      if (addend)
+        {
+         if (!REG_P (tmp))
+           {
+             rtx reg;
+
+             reg = gen_reg_rtx (Pmode);
+             emit_move_insn (reg, tmp);
+             tmp = reg;
+           }
+
+          tmp = gen_rtx_PLUS (SImode, tmp, addend);
+       }
+
+      operands[1] = tmp;
+    }
+  else if (flag_pic && !TARGET_PCREL && symbolic_operand (operands[1], SImode))
     {
       /* The source is an address which requires PIC relocation.
          Call legitimize_pic_address with the source, mode, and a relocation
   "* return output_addsi3 (operands);")
 
 (define_insn_and_split "*addsi3_5200"
-  [(set (match_operand:SI 0 "nonimmediate_operand"         "=mr,mr,a,m,r,  ?a, ?a,?a,?a")
-       (plus:SI (match_operand:SI 1 "general_operand"     "%0, 0, 0,0,0,   a,  a, r, a")
-                (match_operand:SI 2 "general_src_operand" " I, L, J,d,mrKi,Cj, r, a, J")))]
+  [(set (match_operand:SI 0 "nonimmediate_operand"         "=mr,mr,a,  m,r,  ?a, ?a,?a,?a")
+       (plus:SI (match_operand:SI 1 "general_operand"     "%0, 0, 0,  0,0,   a,  a, r, a")
+                (match_operand:SI 2 "general_src_operand" " I, L, JCu,d,mrKi,Cj, r, a, JCu")))]
   "TARGET_COLDFIRE"
 {
   switch (which_alternative)
        (plus:SI (match_dup 0)
                 (match_dup 1)))]
   ""
-  [(set_attr "type" "aluq_l,aluq_l,lea,alu_l,alu_l,*,lea,lea,lea")
-   (set_attr "opy" "2,2,*,2,2,*,*,*,*")
-   (set_attr "opy_type" "*,*,mem5,*,*,*,mem6,mem6,mem5")])
+  [(set_attr "type"     "aluq_l,aluq_l,lea, alu_l,alu_l,*,lea, lea, lea")
+   (set_attr "opy"      "2,     2,     *,   2,    2,    *,*,   *,   *")
+   (set_attr "opy_type" "*,     *,     mem5,*,    *,    *,mem6,mem6,mem5")])
 
 (define_insn ""
   [(set (match_operand:SI 0 "nonimmediate_operand" "=a")