s390.h (ASM_OUTPUT_SPECIAL_POOL_ENTRY): Second parameter of ASM_OUTPUT_SKIP must...
[gcc.git] / gcc / config / s390 / s390.h
index 6d8943e760dee94cba6d4b3071bf3f1318bce73e..47998d407c260fdae278e21a6633ebac39760d10 100644 (file)
@@ -1,5 +1,5 @@
 /* Definitions of target machine for GNU compiler, for IBM S/390
-   Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+   Copyright (C) 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
    Contributed by Hartmut Penner (hpenner@de.ibm.com) and
                   Ulrich Weigand (uweigand@de.ibm.com).
 This file is part of GNU CC.
@@ -24,10 +24,32 @@ Boston, MA 02111-1307, USA.  */
 
 /* Override the __fixdfdi etc. routines when building libgcc2.
    ??? This should be done in a cleaner way ...  */
-#ifdef IN_LIBGCC2
+#if defined (IN_LIBGCC2) && !defined (__s390x__)
 #include <s390/fixdfdi.h>
 #endif
 
+/* Which processor to generate code or schedule for. The cpu attribute 
+   defines a list that mirrors this list, so changes to s390.md must be
+   made at the same time.  */
+
+enum processor_type
+{
+  PROCESSOR_9672_G5,           
+  PROCESSOR_9672_G6,           
+  PROCESSOR_2064_Z900,         
+  PROCESSOR_max
+};
+
+extern enum processor_type s390_cpu;
+extern const char *s390_tune_string;
+
+extern enum processor_type s390_arch;
+extern const char *s390_arch_string;
+
+#define TARGET_CPU_DEFAULT_9672 0
+#define TARGET_CPU_DEFAULT_2064 2
+
+#define TARGET_CPU_DEFAULT_NAMES {"g5", "g6", "z900"}
 
 /* Run-time target specification.  */
 
@@ -46,39 +68,57 @@ Boston, MA 02111-1307, USA.  */
 /* Optional target features.  */
 extern int target_flags;
 
-#define TARGET_HARD_FLOAT          (target_flags & 1)
-#define TARGET_SOFT_FLOAT          (!(target_flags & 1))
-#define TARGET_BACKCHAIN           (target_flags & 2)
-#define TARGET_SMALL_EXEC          (target_flags & 4)
-#define TARGET_DEBUG_ARG           (target_flags & 8)
-#define TARGET_64BIT               (target_flags & 16)
-#define TARGET_MVCLE               (target_flags & 32)
+#define MASK_HARD_FLOAT            0x01
+#define MASK_BACKCHAIN             0x02
+#define MASK_SMALL_EXEC            0x04
+#define MASK_DEBUG_ARG             0x08
+#define MASK_64BIT                 0x10
+#define MASK_ZARCH                 0x20
+#define MASK_MVCLE                 0x40
+
+#define TARGET_HARD_FLOAT          (target_flags & MASK_HARD_FLOAT)
+#define TARGET_SOFT_FLOAT          (!(target_flags & MASK_HARD_FLOAT))
+#define TARGET_BACKCHAIN           (target_flags & MASK_BACKCHAIN)
+#define TARGET_SMALL_EXEC          (target_flags & MASK_SMALL_EXEC)
+#define TARGET_DEBUG_ARG           (target_flags & MASK_DEBUG_ARG)
+#define TARGET_64BIT               (target_flags & MASK_64BIT)
+#define TARGET_ZARCH               (target_flags & MASK_ZARCH)
+#define TARGET_MVCLE               (target_flags & MASK_MVCLE)
 
 /* ??? Once this actually works, it could be made a runtime option.  */
 #define TARGET_IBM_FLOAT           0
 #define TARGET_IEEE_FLOAT          1
 
 #ifdef DEFAULT_TARGET_64BIT
-#define TARGET_DEFAULT             0x13
+#define TARGET_DEFAULT             0x33
 #else
 #define TARGET_DEFAULT             0x3
 #endif
 
-#define TARGET_SWITCHES                                               \
-{ { "hard-float",    1, N_("Use hardware fp")},                               \
-  { "soft-float",   -1, N_("Don't use hardware fp")},                 \
-  { "backchain",     2, N_("Set backchain")},                                 \
+#define TARGET_SWITCHES                                                \
+{ { "hard-float",    1, N_("Use hardware fp")},                        \
+  { "soft-float",   -1, N_("Don't use hardware fp")},                  \
+  { "backchain",     2, N_("Set backchain")},                          \
   { "no-backchain", -2, N_("Don't set backchain (faster, but debug harder")}, \
-  { "small-exec",    4, N_("Use bras for execucable < 64k")},           \
-  { "no-small-exec",-4, N_("Don't use bras")},                        \
-  { "debug",         8, N_("Additional debug prints")},                       \
-  { "no-debug",     -8, N_("Don't print additional debug prints")},     \
-  { "64",           16, N_("64 bit mode")},                           \
-  { "31",          -16, N_("31 bit mode")},                             \
-  { "mvcle",        32, N_("mvcle use")},                             \
-  { "no-mvcle",    -32, N_("mvc&ex")},                                  \
+  { "small-exec",    4, N_("Use bras for executable < 64k")},          \
+  { "no-small-exec",-4, N_("Don't use bras")},                         \
+  { "debug",         8, N_("Additional debug prints")},                \
+  { "no-debug",     -8, N_("Don't print additional debug prints")},    \
+  { "64",           16, N_("64 bit ABI")},                             \
+  { "31",          -16, N_("31 bit ABI")},                             \
+  { "zarch",        32, N_("z/Architecture")},                         \
+  { "esa",         -32, N_("ESA/390 architecture")},                   \
+  { "mvcle",        64, N_("mvcle use")},                              \
+  { "no-mvcle",    -64, N_("mvc&ex")},                                 \
   { "", TARGET_DEFAULT, 0 } }
 
+#define TARGET_OPTIONS                                          \
+{ { "tune=",            &s390_tune_string,                      \
+    N_("Schedule code for given CPU"), 0},                      \
+  { "arch=",            &s390_arch_string,                      \
+    N_("Generate code for given CPU"), 0},                      \
+}
+
 /* Target version string.  Overridden by the OS header.  */
 #ifdef DEFAULT_TARGET_64BIT
 #define TARGET_VERSION fprintf (stderr, " (zSeries)");
@@ -94,6 +134,17 @@ extern int target_flags;
 #define CAN_DEBUG_WITHOUT_FP
 
 
+/* In libgcc2, determine target settings as compile-time constants.  */
+#ifdef IN_LIBGCC2
+#undef TARGET_64BIT
+#ifdef __s390x__
+#define TARGET_64BIT 1
+#else
+#define TARGET_64BIT 0
+#endif
+#endif
+
+
 /* Target machine storage layout.  */
 
 /* Everything is big-endian.  */
@@ -103,7 +154,9 @@ extern int target_flags;
 
 /* Width of a word, in units (bytes).  */
 #define UNITS_PER_WORD (TARGET_64BIT ? 8 : 4)
+#ifndef IN_LIBGCC2
 #define MIN_UNITS_PER_WORD 4
+#endif
 #define MAX_BITS_PER_WORD 64
 
 /* Function arguments and return values are promoted to word size.  */
@@ -195,11 +248,13 @@ if (INTEGRAL_MODE_P (MODE) &&                             \
 #define ADDR_REGNO_P(N)                ((N) >= 1 && (N) < 16)
 #define FP_REGNO_P(N)          ((N) >= 16 && (N) < (TARGET_IEEE_FLOAT? 32 : 20))
 #define CC_REGNO_P(N)          ((N) == 33)
+#define FRAME_REGNO_P(N)       ((N) == 32 || (N) == 34)
 
 #define GENERAL_REG_P(X)       (REG_P (X) && GENERAL_REGNO_P (REGNO (X)))
 #define ADDR_REG_P(X)          (REG_P (X) && ADDR_REGNO_P (REGNO (X)))
 #define FP_REG_P(X)            (REG_P (X) && FP_REGNO_P (REGNO (X)))
 #define CC_REG_P(X)            (REG_P (X) && CC_REGNO_P (REGNO (X)))
+#define FRAME_REG_P(X)         (REG_P (X) && FRAME_REGNO_P (REGNO (X)))
 
 #define BASE_REGISTER 13
 #define RETURN_REGNUM 14
@@ -314,6 +369,8 @@ do                                                          \
     (HARD_REGNO_NREGS(REGNO, MODE) == 1 || !((REGNO) & 1)) :        \
    CC_REGNO_P(REGNO)?                                               \
      GET_MODE_CLASS (MODE) == MODE_CC :                             \
+   FRAME_REGNO_P(REGNO)?                                            \
+     (enum machine_mode) (MODE) == Pmode :                          \
    0)
 
 #define MODES_TIEABLE_P(MODE1, MODE2)          \
@@ -330,8 +387,9 @@ do                                                          \
 /* If a 4-byte value is loaded into a FPR, it is placed into the
    *upper* half of the register, not the lower.  Therefore, we
    cannot use SUBREGs to switch between modes in FP registers.  */
-#define CANNOT_CHANGE_MODE_CLASS(FROM, TO)             \
-  (GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO) ? FP_REGS : NO_REGS)
+#define CANNOT_CHANGE_MODE_CLASS(FROM, TO, CLASS)              \
+  (GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO)                  \
+   ? reg_classes_intersect_p (FP_REGS, CLASS) : 0)
 
 /* Register classes.  */
  
@@ -433,7 +491,7 @@ extern const enum reg_class regclass_map[FIRST_PSEUDO_REGISTER];
      ((C) == 'Q' ?  q_constraint (OP) :                        \
       (C) == 'S' ?  larl_operand (OP, GET_MODE (OP)) : 0)
 
-#define EXTRA_MEMORY_CONSTRAINT(C) ((C) == 'Q')
+#define EXTRA_MEMORY_CONSTRAINT(C,STR) ((C) == 'Q')
 
 
 /* Stack layout and calling conventions.  */
@@ -492,7 +550,6 @@ extern int current_function_outgoing_args_size;
 
 /* Describe how we implement __builtin_eh_return.  */
 #define EH_RETURN_DATA_REGNO(N) ((N) < 4 ? (N) + 6 : INVALID_REGNUM)
-#define EH_RETURN_STACKADJ_RTX  gen_rtx_REG (Pmode, 10)
 #define EH_RETURN_HANDLER_RTX \
   gen_rtx_MEM (Pmode, plus_constant (arg_pointer_rtx, \
                                      TARGET_64BIT? -48 : -40))
@@ -749,6 +806,10 @@ CUMULATIVE_ARGS;
  || GET_CODE (X) == LABEL_REF                                           \
  || (GET_CODE (X) == CONST && symbolic_reference_mentioned_p (X)))
 
+#define TLS_SYMBOLIC_CONST(X)  \
+((GET_CODE (X) == SYMBOL_REF && tls_symbolic_operand (X))      \
+ || (GET_CODE (X) == CONST && tls_symbolic_reference_mentioned_p (X)))
+
 
 /* Condition codes.  */
 
@@ -764,77 +825,6 @@ extern struct rtx_def *s390_compare_op0, *s390_compare_op1;
 
 /* Relative costs of operations.  */
 
-/* A part of a C `switch' statement that describes the relative costs
-   of constant RTL expressions.  It must contain `case' labels for
-   expression codes `const_int', `const', `symbol_ref', `label_ref'
-   and `const_double'.  Each case must ultimately reach a `return'
-   statement to return the relative cost of the use of that kind of
-   constant value in an expression.  The cost may depend on the
-   precise value of the constant, which is available for examination
-   in X, and the rtx code of the expression in which it is contained,
-   found in OUTER_CODE.
-
-   CODE is the expression code--redundant, since it can be obtained
-   with `GET_CODE (X)'.  */
-/* Force_const_mem does not work out of reload, because the saveable_obstack
-   is set to reload_obstack, which does not live long enough. 
-   Because of this we cannot use force_const_mem in addsi3.
-   This leads to problems with gen_add2_insn with a constant greater
-   than a short. Because of that we give an addition of greater
-   constants a cost of 3 (reload1.c 10096).  */
-
-#define CONST_COSTS(RTX, CODE, OUTER_CODE)                      \
-  case CONST:                                                   \
-    if ((GET_CODE (XEXP (RTX, 0)) == MINUS) &&                  \
-       (GET_CODE (XEXP (XEXP (RTX, 0), 1)) != CONST_INT))      \
-     return 1000;                                               \
-  case CONST_INT:                                               \
-       if ((OUTER_CODE == PLUS) &&                              \
-          ((INTVAL (RTX) > 32767) ||                           \
-          (INTVAL (RTX) < -32768)))                            \
-         return COSTS_N_INSNS (3);                              \
-  case LABEL_REF:                                               \
-  case SYMBOL_REF:                                              \
-  case CONST_DOUBLE:                                            \
-    return 0;                                                   \
-
-
-/* Like `CONST_COSTS' but applies to nonconstant RTL expressions.
-   This can be used, for example, to indicate how costly a multiply
-   instruction is.  In writing this macro, you can use the construct
-   `COSTS_N_INSNS (N)' to specify a cost equal to N fast
-   instructions.  OUTER_CODE is the code of the expression in which X
-   is contained.  */
-
-#define RTX_COSTS(X, CODE, OUTER_CODE)                                  \
-  case ASHIFT:                                                          \
-  case ASHIFTRT:                                                        \
-  case LSHIFTRT:                                                        \
-  case PLUS:                                                            \
-  case AND:                                                             \
-  case IOR:                                                             \
-  case XOR:                                                             \
-  case MINUS:                                                           \
-  case NEG:                                                             \
-  case NOT:                                                             \
-    return COSTS_N_INSNS (1);                                           \
-  case MULT:                                                            \
-    if (GET_MODE (XEXP (X, 0)) == DImode)                               \
-      return COSTS_N_INSNS (40);                                        \
-    else                                                                \
-      return COSTS_N_INSNS (7);                                         \
-  case DIV:                                                             \
-  case UDIV:                                                            \
-  case MOD:                                                             \
-  case UMOD:                                                            \
-    return COSTS_N_INSNS (33);
-
-
-/* An expression giving the cost of an addressing mode that contains
-   ADDRESS.  If not defined, the cost is computed from the ADDRESS
-   expression and the `CONST_COSTS' values.  */
-#define ADDRESS_COST(RTX) s390_address_cost ((RTX))
-
 /* On s390, copy between fprs and gprs is expensive.  */
 #define REGISTER_MOVE_COST(MODE, CLASS1, CLASS2)                        \
   ((   (   reg_classes_intersect_p ((CLASS1), GENERAL_REGS)            \
@@ -924,15 +914,11 @@ extern int flag_pic;
 
 /* Advance the location counter by SIZE bytes.  */
 #define ASM_OUTPUT_SKIP(FILE, SIZE) \
-  fprintf ((FILE), "\t.set\t.,.+%u\n", (SIZE))
+  fprintf ((FILE), "\t.set\t.,.+"HOST_WIDE_INT_PRINT_UNSIGNED"\n", (SIZE))
 
 /* The LOCAL_LABEL_PREFIX variable is used by dbxelf.h.  */
 #define LOCAL_LABEL_PREFIX "."
 
-/* Either simplify a location expression, or return the original.  */
-#define ASM_SIMPLIFY_DWARF_ADDR(X) \
-  s390_simplify_dwarf_addr (X)
-
 /* How to refer to registers in assembler output.  This sequence is
    indexed by compiler's hard-register-number (see above).  */
 #define REGISTER_NAMES                                                 \
@@ -943,6 +929,13 @@ extern int flag_pic;
   "%ap",  "%cc",  "%fp"                                                        \
 }
 
+/* Emit a dtp-relative reference to a TLS variable.  */
+
+#ifdef HAVE_AS_TLS
+#define ASM_OUTPUT_DWARF_DTPREL(FILE, SIZE, X) \
+  s390_output_dwarf_dtprel (FILE, SIZE, X)
+#endif
+
 /* Print operand X (an rtx) in assembler syntax to file FILE.  */
 #define PRINT_OPERAND(FILE, X, CODE) print_operand (FILE, X, CODE)
 #define PRINT_OPERAND_ADDRESS(FILE, ADDR) print_operand_address (FILE, ADDR)
@@ -1007,10 +1000,9 @@ extern int s390_nr_constants;
                                                                            \
     case MODE_INT:                                                         \
     case MODE_PARTIAL_INT:                                                 \
-      if (flag_pic                                                         \
-         && (GET_CODE (EXP) == CONST                                       \
-             || GET_CODE (EXP) == SYMBOL_REF                               \
-             || GET_CODE (EXP) == LABEL_REF ))                             \
+      if (GET_CODE (EXP) == CONST                                          \
+         || GET_CODE (EXP) == SYMBOL_REF                                   \
+         || GET_CODE (EXP) == LABEL_REF)                                   \
         {                                                                  \
          fputs (integer_asm_op (UNITS_PER_WORD, TRUE), FILE);              \
           s390_output_symbolic_const (FILE, EXP);                          \
@@ -1020,7 +1012,7 @@ extern int s390_nr_constants;
        {                                                                   \
          assemble_integer (EXP, GET_MODE_SIZE (MODE), ALIGN, 1);           \
          if (GET_MODE_SIZE (MODE) == 1)                                    \
-           ASM_OUTPUT_SKIP ((FILE), 1);                                    \
+           ASM_OUTPUT_SKIP ((FILE), (unsigned HOST_WIDE_INT)1);            \
        }                                                                   \
       break;                                                               \
                                                                            \