Re: RFA: MN10300: Add TLS support

2011-05-19 Thread Richard Henderson
 +  fmt = GET_RTX_FORMAT (GET_CODE (x));
 +  for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i = 0; i--)
 +{
 +  if (fmt[i] == 'E')
 + {
 +   int j;
 +
 +   for (j = XVECLEN (x, i) - 1; j = 0; j--)
 + if (! is_legitimate_tls_operand (XVECEXP (x, i, j)))
 +   return false;
 + }
 +  else if (fmt[i] == 'e'  ! is_legitimate_tls_operand (XEXP (x, i)))
 + return false;

Do you really want to find such an unspec buried in arbitrary rtl?
That seems in conflict with the term legitimate.  But supposing
that you really do, this code should use for_each_rtx.

 @@ -1908,6 +2007,9 @@
const char *fmt;
int i;
  
 +  if (is_legitimate_tls_operand (x))

Please remember to use -p in generating the diff, for function context.

 +(define_predicate tls_symbolic_operand
 +  (match_code symbol_ref)
 +{
 +  return SYMBOL_REF_TLS_MODEL (op);
 +})

I'm pretty sure you also want to test for (const (plus (symbol) (int)).

 +(define_predicate nontls_general_operand
 +  (match_code 
 const_int,const_double,const,symbol_ref,label_ref,subreg,reg,mem)
 +{
 +  if (tls_symbolic_operand (op, mode))
 +return false;
 +  return general_operand (op, mode);
 +})

Simpler as

(define_predicate nontls_general_operand
  (and (match_operand general_operand 0)
   (not (match_operand tls_symbolic_operand 0)))

 +#define PRINT_OPERAND_PUNCT_VALID_P(CODE)  ((CODE) == '')

This is now a target hook.

 +mn10300_tls_get_addr (void)
 +{
 +  return gen_rtx_REG (Pmode, TLS_REG);
 +}

Most seriously, I don't see TLS_REG become fixed.  And some note
that this is an ABI change.


r~



RFA: MN10300: Add TLS support

2011-05-17 Thread Nick Clifton
Hi Richard, Hi Jeff, Hi Alex,

  Here is another MN10300 patch.  This ones adds support for TLS.  I
  must confess that I did not actually write this code - DJ did - but I
  have been asked to submit it upstream, so here goes:

  OK to apply ?

Cheers
  Nick

gcc/ChangeLog
2011-05-17  DJ Delorie  d...@redhat.com
Nick Clifton  ni...@redhat.com

* config/mn10300/mn10300.c (mn10300_unspec_int_label_counter):
New variable.
(mn10300_option_override): Disable TLS for the MN10300.
(tls_symbolic_operand_kind): New function.
(get_some_local_dynamic_name_1): New function.
(get_some_local_dynamic_name): New function.
(mn10300_print_operand): Handle %.
(mn10300_legitimize_address): Legitimize TLS addresses.
(is_legitimate_tls_operand): New function.
(mn10300_legitimate_pic_operand_p): TLS operands are
legitimate.
(mn10300_legitimate_address_p): TLS symbols do not make
legitimate addresses.
Allow TLS operands under some circumstances.
(mn10300_legitimate_constant_p): Handle TLS UNSPECs.
(mn10300_init_machine_status): New function.
(mn10300_init_expanders): New function.
(pic_nonpic_got_ptr): New function.
(mn10300_tls_get_addr): New function.
(mn10300_legitimize_tls_address): New function.
(mn10300_constant_address_p): New function.
(TARGET_HAVE_TLS): Define.
* config/mn10300/predicates.md (tls_symbolic_operand): New.
(nontls_general_operand): New.
* config/mn10300/mn10300.h (enum reg_class): Add D0_REGS,
A0_REGS.
(REG_CLASS_NAMES): Likewise.
(REG_CLASS_CONTENTS): Likewise.
(struct machine_function): New structure.
(INIT_EXPANDERS): Define.
(mn10300_unspec_int_label_counter): New variable.
(PRINT_OPERAND_PUNCT_VALID_P): Define.
(CONSTANT_ADDRESS_P): Define.
* config/mn10300/constraints (B): New constraint.
(C): New constraint.
* config/mn10300/mn10300-protos.h: Alpha sort.
(mn10300_init_expanders): Prototype.
(mn10300_tls_get_addr): Prototype.
(mn10300_legitimize_tls_address): Prototype.
(mn10300_constant_address_p): Prototype.
* config/mn10300/mn10300.md (TLS_REG): New constant.
(UNSPEC_INT_LABEL): New constant.
(UNSPEC_TLSGD): New constant.
(UNSPEC_TLSLDM): New constant.
(UNSPEC_DTPOFF): New constant.
(UNSPEC_GOTNTPOFF): New constant.
(UNSPEC_INDNTPOFF): New constant.
(UNSPEC_TPOFF): New constant.
(UNSPEC_TLS_GD): New constant.
(UNSPEC_TLS_LD_BASE): New constant.
(movsi): Add TLS code.
(tls_global_dynamic_i): New pattern.
(tls_global_dynamic): New pattern.
(tls_local_dynamic_base_i): New pattern.
(tls_local_dynamic_base): New pattern.
(tls_initial_exec): New pattern.
(tls_initial_exec_1): New pattern.
(tls_initial_exec_2): New pattern.
(am33_set_got): New pattern.
(int_label): New pattern.
(am33_loadPC_anyreg): New pattern.
(add_GOT_to_any_reg): New pattern.

Index: gcc/config/mn10300/mn10300.c
===
--- gcc/config/mn10300/mn10300.c	(revision 173815)
+++ gcc/config/mn10300/mn10300.c	(working copy)
@@ -46,7 +46,12 @@
 #include df.h
 #include opts.h
 #include cfgloop.h
+#include ggc.h
 
+/* This is used by GOTaddr2picreg to uniquely identify
+   UNSPEC_INT_LABELs.  */
+int mn10300_unspec_int_label_counter;
+
 /* This is used in the am33_2.0-linux-gnu port, in which global symbol
names are not prefixed by underscores, to tell whether to prefix a
label with a plus sign or not, so that the assembler can tell
@@ -124,6 +129,9 @@
 target_flags = ~MASK_MULT_BUG;
   else
 {
+  /* We can't do TLS if we don't have the TLS register.  */
+  targetm.have_tls = false;
+
   /* Disable scheduling for the MN10300 as we do
 	 not have timing information available for it.  */
   flag_schedule_insns = 0;
@@ -162,6 +170,51 @@
 fprintf (asm_out_file, \t.am33\n);
 }
 
+/* Returns non-zero if OP has the KIND tls model.  */
+
+static inline bool
+tls_symbolic_operand_kind (rtx op, enum tls_model kind)
+{
+  if (GET_CODE (op) != SYMBOL_REF)
+return false;
+  return SYMBOL_REF_TLS_MODEL (op) == kind;
+}
+
+/* Locate some local-dynamic symbol still in use by this function
+   so that we can print its name in some tls_local_dynamic_base
+   pattern.  This is used by % in print_operand().  */
+
+static int
+get_some_local_dynamic_name_1 (rtx *px, void *data ATTRIBUTE_UNUSED)
+{
+  rtx x = *px;
+
+  if (GET_CODE (x) == SYMBOL_REF
+   tls_symbolic_operand_kind (x, TLS_MODEL_LOCAL_DYNAMIC))
+{
+  cfun-machine-some_ld_name = XSTR (x, 0);
+  return 1;
+}
+
+  return 0;
+}
+
+static const char *
+get_some_local_dynamic_name (void)
+{