c4x.h (TARGET_EXPOSE_LDP, [...]): Define new macros.
authorMichael Hayes <m.hayes@elec.canterbury.ac.nz>
Wed, 9 Jun 1999 03:47:24 +0000 (03:47 +0000)
committerMichael Hayes <m.hayes@gcc.gnu.org>
Wed, 9 Jun 1999 03:47:24 +0000 (03:47 +0000)
* config/c4x/c4x.h (TARGET_EXPOSE_LDP, LEGITIMIZE_RELOAD_ADDRESS):
Define new macros.
* config/c4x/c4x.c (c4x_emit_move_sequence, src_operand): Use
TARGET_EXPOSE_LDP.
(c4x_legitimize_reload_address): New function.
* config/c4x/c4x.md: Update docs.

From-SVN: r27443

gcc/ChangeLog
gcc/config/c4x/c4x.c
gcc/config/c4x/c4x.h
gcc/config/c4x/c4x.md

index 22433ba4357cb7beef7009676bce3af475ab67ea..dc83be10b04f1002328893da25dcb6cf99e49294 100644 (file)
@@ -1,3 +1,12 @@
+Wed Jun  9 22:34:38 1999  Michael Hayes  <m.hayes@elec.canterbury.ac.nz>
+
+       * config/c4x/c4x.h (TARGET_EXPOSE_LDP, LEGITIMIZE_RELOAD_ADDRESS):
+       Define new macros. 
+       * config/c4x/c4x.c (c4x_emit_move_sequence, src_operand): Use
+       TARGET_EXPOSE_LDP.
+       (c4x_legitimize_reload_address): New function.
+       * config/c4x/c4x.md: Update docs.
+
 Wed Jun  9 04:14:48 1999  Jeffrey A Law  (law@cygnus.com)
 
        * fixincludes: Avoid removing '.'.
index 5c5690a4eaf9cfea230f7ee1245aed1a6f5ab7ce..23f8bfa093f57e2afa5d1f025eb59f0e9fd1ef7a 100644 (file)
@@ -1077,7 +1077,8 @@ c4x_emit_move_sequence (operands, mode)
      and emit associated (HIGH (SYMREF)) if large memory model.  
      c4x_legitimize_address could be used to do this,
      perhaps by calling validize_address.  */
-  if (! (reload_in_progress || reload_completed)
+  if (TARGET_EXPOSE_LDP
+      && ! (reload_in_progress || reload_completed)
       && GET_CODE (op1) == MEM
       && symbolic_address_operand (XEXP (op1, 0), Pmode))
     {
@@ -1088,7 +1089,8 @@ c4x_emit_move_sequence (operands, mode)
                            gen_rtx_LO_SUM (Pmode, dp_reg, XEXP (op1, 0)));
     }
 
-  if (! (reload_in_progress || reload_completed)
+  if (TARGET_EXPOSE_LDP
+      && ! (reload_in_progress || reload_completed)
       && GET_CODE (op0) == MEM 
       && symbolic_address_operand (XEXP (op0, 0), Pmode))
     {
@@ -1409,12 +1411,14 @@ c4x_check_legit_addr (mode, addr, strict)
       /* Direct addressing.  */
     case LABEL_REF:
     case SYMBOL_REF:
+      if (! TARGET_EXPOSE_LDP && ! strict && mode != HFmode && mode != HImode)
+       return 1;
       /* These need to be converted to a LO_SUM (...). 
-        c4x_legitimize_address will fix them up.  */
+        LEGITIMIZE_RELOAD_ADDRESS will do this during reload.  */
       return 0;
 
       /* Do not allow direct memory access to absolute addresses.
-         This is more pain than its worth, especially for the
+         This is more pain than it's worth, especially for the
          small memory model where we can't guarantee that
          this address is within the data page---we don't want
          to modify the DP register in the small memory model,
@@ -1515,6 +1519,32 @@ c4x_legitimize_address (orig, mode)
 }
 
 
+rtx
+c4x_legitimize_reload_address (orig, mode, insn)
+     rtx orig ATTRIBUTE_UNUSED;
+     enum machine_mode mode;
+     rtx insn;
+{                                                                      
+  if (mode != HImode 
+      && mode != HFmode
+      && GET_MODE (orig) != HImode
+      && GET_MODE (orig) != HFmode
+      && (GET_CODE (orig) == CONST                                     
+          || GET_CODE (orig) == SYMBOL_REF                             
+          || GET_CODE (orig) == LABEL_REF))
+    {                                                                   
+      rtx dp_reg = gen_rtx_REG (Pmode, DP_REGNO);                      
+      if (! TARGET_SMALL)                                              
+        emit_insn_before (gen_rtx_SET (VOIDmode, dp_reg,               
+                                      gen_rtx_HIGH (Pmode, orig)),     
+                         insn);
+      return gen_rtx_LO_SUM (Pmode, dp_reg, orig);
+    }
+
+  return NULL_RTX;
+}
+
+
 /* Provide the costs of an addressing mode that contains ADDR.
    If ADDR is not a valid address, its cost is irrelevant.  
    This is used in cse and loop optimisation to determine
@@ -3002,20 +3032,24 @@ src_operand (op, mode)
   if (GET_CODE (op) == CONST_DOUBLE)
     return c4x_H_constant (op);
 
-  /* Disallow symbolic addresses.  */
+  /* Disallow symbolic addresses.  Only the predicate
+     symbolic_address_operand will match these.  */
   if (GET_CODE (op) == SYMBOL_REF
       || GET_CODE (op) == LABEL_REF
       || GET_CODE (op) == CONST)
     return 0;
 
-  /* Disallow direct memory access symbolic addresses. 
-     These are usually caught by the movqi expander and
-     converted to a LO_SUM.  */
+  /* If TARGET_EXPOSE_LDP is zero, allow direct memory access to
+     symbolic addresses.  These will be rejected by
+     GO_IF_LEGITIMATE_ADDRESS and fixed up by
+     LEGITIMIZE_RELOAD_ADDRESS.  If TARGET_EXPOSE_LDP is nonzero,
+     disallow direct memory access to symbolic addresses.  These
+     should be converted to a HIGH/LO_SUM pair by the movqi expander.  */
   if (GET_CODE (op) == MEM
       && ((GET_CODE (XEXP (op, 0)) == SYMBOL_REF
           || GET_CODE (XEXP (op, 0)) == LABEL_REF
           || GET_CODE (XEXP (op, 0)) == CONST)))
-    return 0;
+    return ! TARGET_EXPOSE_LDP;
 
   return general_operand (op, mode);
 }
index 1dc8d5c63ed70491965b4e20f62b58eaa3952f77..7ef0738f00841d2e856fb75197e94cd1d45a959d 100644 (file)
@@ -303,7 +303,9 @@ extern int target_flags;
 #define TARGET_C40             (target_flags & C40_FLAG)
 #define TARGET_C44             (target_flags & C44_FLAG)
 
+/* Define some options to control code generation.  */
 #define TARGET_LOAD_ADDRESS    (1 || (! TARGET_C3X && ! TARGET_SMALL))
+#define TARGET_EXPOSE_LDP      0
 
 /* -mrpts            allows the use of the RPTS instruction irregardless.
    -mrpts=max-cycles will use RPTS if the number of cycles is constant
@@ -1664,6 +1666,20 @@ extern struct rtx_def *c4x_legitimize_address ();
   }                                                                    \
 }
 
+extern struct rtx_def *c4x_legitimize_reload_address ();
+#define LEGITIMIZE_RELOAD_ADDRESS(X,MODE,OPNUM,TYPE,IND_LEVELS,WIN)     \
+{                                                                      \
+  rtx new;                                                             \
+  new = c4x_legitimize_reload_address (X, MODE, insn);                 \
+  if (new != NULL_RTX)                                                 \
+  {                                                                    \
+    (X) = new;                                                         \
+   /* We do not have to call push_reload because we do not require      \
+      any more reloads.  */                                            \
+    goto WIN;                                                          \
+  }                                                                    \
+}
+
 
 /* No mode-dependent addresses on the C4x are autoincrements.  */
 
@@ -1684,7 +1700,9 @@ extern struct rtx_def *c4x_legitimize_address ();
    restricted subset of CONST_INT and CONST_DOUBLE.  Disallow
    LABEL_REF and SYMBOL_REF (except on the C40 with the big memory
    model) so that the symbols will be forced into the constant pool.
-   On second thoughts, lets do this with the move expanders.
+   On second thoughts, let's do this with the move expanders since
+   the alias analysis has trouble if we force constant addresses
+   into memory.
 */
 
 #define LEGITIMATE_CONSTANT_P(X)                               \
@@ -2078,7 +2096,7 @@ dtors_section ()                                                  \
     fprintf (FILE, "\n");                                      \
 }
 
-#define ASM_FILE_END(FILE)   fprintf (FILE, "\t.end\n")
+#define ASM_FILE_END(FILE) fprintf (FILE, "\t.end\n")
 
 /* We need to have a data section we can identify so that we can set
    the DP register back to a data pointer in the small memory model.
@@ -2089,7 +2107,7 @@ dtors_section ()                                                  \
     if (! TARGET_TI) fputs ("gcc2_compiled.:\n", FILE);        \
       fputs ("\t.data\ndata_sec:\n", FILE);
 
-#define ASM_COMMENT_START      ";"
+#define ASM_COMMENT_START ";"
 
 #define ASM_APP_ON ""
 #define ASM_APP_OFF ""
@@ -2248,8 +2266,10 @@ asm_fprintf (FILE, "%s%d:\n", PREFIX, NUM)
 
 #define CPP_PREDEFINES ""
 
-/* This says how to output an assembler line
-   to define a local common symbol.  */
+/* Output of Uninitialized Variables  */
+
+/* This says how to output an assembler line to define a local
+   uninitialized variable.  */
 
 #undef ASM_OUTPUT_LOCAL
 #define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE, ROUNDED)  \
@@ -2257,7 +2277,8 @@ asm_fprintf (FILE, "%s%d:\n", PREFIX, NUM)
   assemble_name (FILE, (NAME)),                \
   fprintf (FILE, ",%u\n", (ROUNDED)))
 
-/* Output of Uninitialized Variables  */
+/* This says how to output an assembler line to define a global
+   uninitialized variable.  */
 
 #undef ASM_OUTPUT_COMMON
 #define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED)  \
index a0a4e0b9dd93edb4dd62c0c0efc5ab6b12181aa2..7f1b0f309abd7b75a60a4f5602ec347b87a0866a 100644 (file)
@@ -68,6 +68,8 @@
 ; src_operand           general operand                            [rfHmI]
 ; par_ind_operand       indirect S mode (ARx + 0, 1, IRx)          [S<>]
 ; parallel_operand      par_ind_operand or ext_low_reg_operand
+; symbolic_address_operand
+; call_address_operand
 
 ; ADDI src2, src1, dst  three operand op
 ; ADDI src, dst         two operand op
    operands[3] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[1]) & 0xffff);
 }")
 
-; This pattern is required to handle the case where a register that clobbers
 ; CC has been selected to load a symbolic address.  We force the address
 ; into memory and then generate LDP and LDIU insns.
 ; This is also required for the C30 if we pretend that we can