/* 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.
/* 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. */
/* 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)");
#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. */
/* 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. */
#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
(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) \
/* 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. */
((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. */
/* 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))
|| 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. */
/* 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) \
/* 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 \
"%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)
\
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); \
{ \
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; \
\