From 6fe7eeb157f147d9ce8a7fb849583d3a75697e56 Mon Sep 17 00:00:00 2001 From: tv Date: Sun, 16 Aug 1998 17:45:46 +0000 Subject: [PATCH] Import egcs-1.1 gcc, 19980816 snapshot --- gnu/dist/gcc/config/sparc/sparc.h | 705 ++++---- gnu/dist/gcc/config/sparc/sparc.md | 2069 +++++++++++++++-------- gnu/dist/gcc/config/sparc/sun4o3.h | 21 +- gnu/dist/gcc/config/sparc/sunos4.h | 19 + gnu/dist/gcc/config/sparc/sysv4.h | 20 +- gnu/dist/gcc/config/sparc/t-sparcbare | 2 +- gnu/dist/gcc/config/sparc/xm-linux.h | 4 +- gnu/dist/gcc/config/sparc/xm-pbd.h | 3 - gnu/dist/gcc/config/sparc/xm-sol2.h | 2 - gnu/dist/gcc/config/sparc/xm-sparc.h | 4 +- gnu/dist/gcc/config/sparc/xm-sysv4.h | 7 +- gnu/dist/gcc/config/spur/spur.c | 21 +- gnu/dist/gcc/config/spur/spur.h | 11 +- gnu/dist/gcc/config/spur/spur.md | 23 +- gnu/dist/gcc/config/tahoe/tahoe.c | 7 +- gnu/dist/gcc/config/tahoe/tahoe.h | 10 +- gnu/dist/gcc/config/tahoe/tahoe.md | 22 +- gnu/dist/gcc/config/v850/lib1funcs.asm | 17 +- gnu/dist/gcc/config/v850/t-v850 | 2 + gnu/dist/gcc/config/v850/v850.c | 42 +- gnu/dist/gcc/config/v850/v850.h | 41 +- gnu/dist/gcc/config/v850/v850.md | 12 +- gnu/dist/gcc/config/vax/ultrix.h | 3 + gnu/dist/gcc/config/vax/vax.c | 18 +- gnu/dist/gcc/config/vax/vax.h | 25 +- gnu/dist/gcc/config/vax/vax.md | 42 +- gnu/dist/gcc/config/vax/vms.h | 18 +- gnu/dist/gcc/config/vax/xm-vaxv.h | 4 - gnu/dist/gcc/config/vax/xm-vms.h | 31 +- gnu/dist/gcc/config/we32k/we32k.c | 16 +- gnu/dist/gcc/config/we32k/we32k.h | 17 +- gnu/dist/gcc/config/we32k/we32k.md | 52 +- gnu/dist/gcc/config/winnt/config-nt.sed | 7 +- gnu/dist/gcc/config/winnt/win-nt.h | 6 +- gnu/dist/gcc/config/winnt/xm-winnt.h | 8 +- gnu/dist/gcc/ginclude/ppc-asm.h | 2 +- gnu/dist/gcc/ginclude/stdarg.h | 2 +- gnu/dist/gcc/ginclude/stdbool.h | 20 + gnu/dist/gcc/ginclude/stddef.h | 19 +- gnu/dist/gcc/ginclude/va-i960.h | 2 +- gnu/dist/gcc/ginclude/va-mips.h | 15 +- gnu/dist/gcc/ginclude/va-v850.h | 3 - gnu/dist/gcc/ginclude/varargs.h | 2 +- 43 files changed, 2090 insertions(+), 1286 deletions(-) create mode 100644 gnu/dist/gcc/ginclude/stdbool.h diff --git a/gnu/dist/gcc/config/sparc/sparc.h b/gnu/dist/gcc/config/sparc/sparc.h index 9d8f1a1a3b60..1f21659178a4 100644 --- a/gnu/dist/gcc/config/sparc/sparc.h +++ b/gnu/dist/gcc/config/sparc/sparc.h @@ -1,5 +1,5 @@ /* Definitions of target machine for GNU compiler, for Sun SPARC. - Copyright (C) 1987, 88, 89, 92, 94-6, 1997 Free Software Foundation, Inc. + Copyright (C) 1987, 88, 89, 92, 94-97, 1998 Free Software Foundation, Inc. Contributed by Michael Tiemann (tiemann@cygnus.com). 64 bit SPARC V9 support by Michael Tiemann, Jim Wilson, and Doug Evans, at Cygnus Support. @@ -139,7 +139,7 @@ Unrecognized value in TARGET_CPU_DEFAULT. ??? It would be nice to not include any subtarget specific values here, however there's no way to portably provide subtarget values to CPP_PREFINES. Also, -D values in CPP_SUBTARGET_SPEC don't get turned into - into foo, __foo and __foo__. */ + foo, __foo and __foo__. */ #define CPP_PREDEFINES "-Dsparc -Dsun -Dunix -Asystem(unix) -Asystem(bsd)" @@ -158,7 +158,6 @@ Unrecognized value in TARGET_CPU_DEFAULT. %{mcpu=f930:-D__sparclite__} %{mcpu=f934:-D__sparclite__} \ %{mcpu=v8:-D__sparc_v8__} \ %{mcpu=supersparc:-D__supersparc__ -D__sparc_v8__} \ -%{mcpu=v8plus:-D__sparc_v9__} \ %{mcpu=v9:-D__sparc_v9__} \ %{mcpu=ultrasparc:-D__sparc_v9__} \ %{!mcpu*:%{!mcypress:%{!msparclite:%{!mf930:%{!mf934:%{!mv8:%{!msupersparc:%(cpp_cpu_default)}}}}}}} \ @@ -209,9 +208,9 @@ Unrecognized value in TARGET_CPU_DEFAULT. %{mf930:-Asparclite} %{mf934:-Asparclite} \ %{mcpu=sparclite:-Asparclite} \ %{mcpu=f930:-Asparclite} %{mcpu=f934:-Asparclite} \ -%{mcpu=v8plus:-Av8plus} \ +%{mv8plus:-Av8plus} \ %{mcpu=v9:-Av9} \ -%{mcpu=ultrasparc:-Av9a} \ +%{mcpu=ultrasparc:%{!mv8plus:-Av9a}} \ %{!mcpu*:%{!mcypress:%{!msparclite:%{!mf930:%{!mf934:%{!mv8:%{!msupersparc:%(asm_cpu_default)}}}}}}} \ " @@ -277,8 +276,8 @@ Unrecognized value in TARGET_CPU_DEFAULT. #define NO_BUILTIN_PTRDIFF_TYPE #define NO_BUILTIN_SIZE_TYPE #endif -#define PTRDIFF_TYPE (TARGET_ARCH64 ? "long long int" : "int") -#define SIZE_TYPE (TARGET_ARCH64 ? "long long unsigned int" : "unsigned int") +#define PTRDIFF_TYPE (TARGET_ARCH64 ? "long int" : "int") +#define SIZE_TYPE (TARGET_ARCH64 ? "long unsigned int" : "unsigned int") /* ??? This should be 32 bits for v9 but what can we do? */ #define WCHAR_TYPE "short unsigned int" @@ -440,8 +439,8 @@ extern int target_flags; /* Non-zero means the cpu has broken `save' and `restore' insns, only the trivial versions work (save %g0,%g0,%g0; restore %g0,%g0,%g0). We assume the environment will properly handle or otherwise avoid - trouble associated with an interrupt occuring after the `save' or trap - occuring during it. */ + trouble associated with an interrupt occurring after the `save' or trap + occurring during it. */ #define MASK_BROKEN_SAVERESTORE 0x200000 #define TARGET_BROKEN_SAVERESTORE (target_flags & MASK_BROKEN_SAVERESTORE) @@ -449,6 +448,31 @@ extern int target_flags; #define MASK_FPU_SET 0x400000 #define TARGET_FPU_SET (target_flags & MASK_FPU_SET) +/* Use the UltraSPARC Visual Instruction Set extensions. */ +#define MASK_VIS 0x1000000 +#define TARGET_VIS (target_flags & MASK_VIS) + +/* Compile for Solaris V8+. 32 bit Solaris preserves the high bits of + the current out and global registers. Linux saves the high bits on + context switches but not signals. */ +#define MASK_V8PLUS 0x2000000 +#define TARGET_V8PLUS (target_flags & MASK_V8PLUS) + +/* TARGET_HARD_MUL: Use hardware multiply instructions but not %y. + TARGET_HARD_MUL32: Use hardware multiply instructions with rd %y + to get high 32 bits. False in V8+ or V9 because multiply stores + a 64 bit result in a register. */ + +#define TARGET_HARD_MUL32 \ + ((TARGET_V8 || TARGET_SPARCLITE \ + || TARGET_SPARCLET || TARGET_DEPRECATED_V8_INSNS) \ + && ! TARGET_V8PLUS) + +#define TARGET_HARD_MUL \ + (TARGET_V8 || TARGET_SPARCLITE || TARGET_SPARCLET \ + || TARGET_DEPRECATED_V8_INSNS || TARGET_V8PLUS) + + /* Macro to define tables used to set the flags. This is a list in braces of pairs in braces, each pair being { "NAME", VALUE } @@ -474,6 +498,9 @@ extern int target_flags; {"no-app-regs", -MASK_APP_REGS}, \ {"hard-quad-float", MASK_HARD_QUAD}, \ {"soft-quad-float", -MASK_HARD_QUAD}, \ + {"v8plus", MASK_V8PLUS}, \ + {"no-v8plus", -MASK_V8PLUS}, \ + {"vis", MASK_VIS}, \ /* ??? These are deprecated, coerced to -mcpu=. Delete in 2.9. */ \ {"cypress", 0}, \ {"sparclite", 0}, \ @@ -512,7 +539,6 @@ enum processor_type { PROCESSOR_F934, PROCESSOR_SPARCLET, PROCESSOR_TSC701, - PROCESSOR_V8PLUS, PROCESSOR_V9, PROCESSOR_ULTRASPARC }; @@ -807,7 +833,7 @@ if (TARGET_ARCH64 \ /* Argument passing regs. */ #define SPARC_OUTGOING_INT_ARG_FIRST 8 -#define SPARC_INCOMING_INT_ARG_FIRST 24 +#define SPARC_INCOMING_INT_ARG_FIRST (TARGET_FLAT ? 8 : 24) #define SPARC_FP_ARG_FIRST 32 /* 1 for registers that have pervasive standard uses @@ -954,6 +980,12 @@ while (0) : (GET_MODE_SIZE (MODE) + 3) / 4) \ : ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)) +/* A subreg in 64 bit mode will have the wrong offset for a floating point + register. The least significant part is at offset 1, compared to 0 for + integer registers. */ +#define ALTER_HARD_SUBREG(TMODE, WORD, FMODE, REGNO) \ + (TARGET_ARCH64 && (REGNO) >= 32 && (REGNO) < 96 && (TMODE) == SImode ? 1 : ((REGNO) + (WORD))) + /* Value is 1 if hard register REGNO can hold a value of machine-mode MODE. See sparc.c for how we initialize this. */ extern int *hard_regno_mode_classes; @@ -1046,18 +1078,24 @@ extern int sparc_mode_class[]; #define INITIALIZE_PIC initialize_pic () #define FINALIZE_PIC finalize_pic () +/* Pick a default value we can notice from override_options: + !v9: Default is on. + v9: Default is off. */ + +#define DEFAULT_PCC_STRUCT_RETURN -1 + /* Sparc ABI says that quad-precision floats and all structures are returned in memory. For v9: unions <= 32 bytes in size are returned in int regs, - structures up to 32 bytes are returned in int and fp regs. - FIXME: wip */ + structures up to 32 bytes are returned in int and fp regs. */ #define RETURN_IN_MEMORY(TYPE) \ (TARGET_ARCH32 \ ? (TYPE_MODE (TYPE) == BLKmode \ || TYPE_MODE (TYPE) == TFmode \ || TYPE_MODE (TYPE) == TCmode) \ - : TYPE_MODE (TYPE) == BLKmode) + : (TYPE_MODE (TYPE) == BLKmode \ + && int_size_in_bytes (TYPE) > 32)) /* Functions which return large structures get the address to place the wanted value at offset 64 from the frame. @@ -1070,15 +1108,15 @@ extern int sparc_mode_class[]; #define STRUCT_VALUE \ (TARGET_ARCH64 \ ? 0 \ - : gen_rtx (MEM, Pmode, \ - gen_rtx (PLUS, Pmode, stack_pointer_rtx, \ - gen_rtx (CONST_INT, VOIDmode, STRUCT_VALUE_OFFSET)))) + : gen_rtx_MEM (Pmode, \ + gen_rtx_PLUS (Pmode, stack_pointer_rtx, \ + GEN_INT (STRUCT_VALUE_OFFSET)))) #define STRUCT_VALUE_INCOMING \ (TARGET_ARCH64 \ ? 0 \ - : gen_rtx (MEM, Pmode, \ - gen_rtx (PLUS, Pmode, frame_pointer_rtx, \ - gen_rtx (CONST_INT, VOIDmode, STRUCT_VALUE_OFFSET)))) + : gen_rtx_MEM (Pmode, \ + gen_rtx_PLUS (Pmode, frame_pointer_rtx, \ + GEN_INT (STRUCT_VALUE_OFFSET)))) /* Define the classes of registers for register constraints in the machine description. Also define ranges of constants. @@ -1131,11 +1169,11 @@ extern int sparc_mode_class[]; It is important that SPARC_ICC_REG have class NO_REGS. Otherwise combine may try to use it to hold an SImode value. See register_operand. - ??? Should %fcc[0123] be handled similarily? + ??? Should %fcc[0123] be handled similarly? */ -enum reg_class { NO_REGS, FPCC_REGS, GENERAL_REGS, FP_REGS, EXTRA_FP_REGS, - GENERAL_OR_FP_REGS, GENERAL_OR_EXTRA_FP_REGS, +enum reg_class { NO_REGS, FPCC_REGS, I64_REGS, GENERAL_REGS, FP_REGS, + EXTRA_FP_REGS, GENERAL_OR_FP_REGS, GENERAL_OR_EXTRA_FP_REGS, ALL_REGS, LIM_REG_CLASSES }; #define N_REG_CLASSES (int) LIM_REG_CLASSES @@ -1143,15 +1181,16 @@ enum reg_class { NO_REGS, FPCC_REGS, GENERAL_REGS, FP_REGS, EXTRA_FP_REGS, /* Give names of register classes as strings for dump file. */ #define REG_CLASS_NAMES \ - { "NO_REGS", "FPCC_REGS", "GENERAL_REGS", "FP_REGS", "EXTRA_FP_REGS", \ - "GENERAL_OR_FP_REGS", "GENERAL_OR_EXTRA_FP_REGS", "ALL_REGS" } + { "NO_REGS", "FPCC_REGS", "I64_REGS", "GENERAL_REGS", "FP_REGS", \ + "EXTRA_FP_REGS", "GENERAL_OR_FP_REGS", "GENERAL_OR_EXTRA_FP_REGS", \ + "ALL_REGS" } /* Define which registers fit in which classes. This is an initializer for a vector of HARD_REG_SET of length N_REG_CLASSES. */ #define REG_CLASS_CONTENTS \ - {{0, 0, 0, 0}, {0, 0, 0, 0xf}, \ + {{0, 0, 0, 0}, {0, 0, 0, 0xf}, {0xffff, 0, 0, 0}, \ {-1, 0, 0, 0}, {0, -1, 0, 0}, {0, -1, -1, 0}, \ {-1, -1, 0, 0}, {-1, -1, -1, 0}, {-1, -1, -1, 0x1f}} @@ -1242,17 +1281,23 @@ extern char leaf_reg_remap[]; /* Get reg_class from a letter such as appears in the machine description. In the not-v9 case, coerce v9's 'e' class to 'f', so we can use 'e' in the - .md file for v8 and v9. */ + .md file for v8 and v9. + 'd' and 'b' are used for single and double precision VIS operations, + if TARGET_VIS. + 'h' is used for V8+ 64 bit global and out registers. */ -#define REG_CLASS_FROM_LETTER(C) \ -(TARGET_V9 \ - ? ((C) == 'f' ? FP_REGS \ - : (C) == 'e' ? EXTRA_FP_REGS \ - : (C) == 'c' ? FPCC_REGS \ - : NO_REGS) \ - : ((C) == 'f' ? FP_REGS \ - : (C) == 'e' ? FP_REGS \ - : (C) == 'c' ? FPCC_REGS \ +#define REG_CLASS_FROM_LETTER(C) \ +(TARGET_V9 \ + ? ((C) == 'f' ? FP_REGS \ + : (C) == 'e' ? EXTRA_FP_REGS \ + : (C) == 'c' ? FPCC_REGS \ + : ((C) == 'd' && TARGET_VIS) ? FP_REGS\ + : ((C) == 'b' && TARGET_VIS) ? EXTRA_FP_REGS\ + : ((C) == 'h' && TARGET_V8PLUS) ? I64_REGS\ + : NO_REGS) \ + : ((C) == 'f' ? FP_REGS \ + : (C) == 'e' ? FP_REGS \ + : (C) == 'c' ? FPCC_REGS \ : NO_REGS)) /* The letters I, J, K, L and M in a register constraint string @@ -1273,6 +1318,8 @@ extern char leaf_reg_remap[]; /* 10 and 11 bit immediates are only used for a few specific insns. SMALL_INT is used throughout the port so we continue to use it. */ #define SMALL_INT(X) (SPARC_SIMM13_P (INTVAL (X))) +/* 13 bit immediate, considering only the low 32 bits */ +#define SMALL_INT32(X) (SPARC_SIMM13_P ((int)INTVAL (X) & 0xffffffff)) #define SPARC_SETHI_P(X) \ (((unsigned HOST_WIDE_INT) (X) & ~(unsigned HOST_WIDE_INT) 0xfffffc00) == 0) @@ -1340,10 +1387,10 @@ extern char leaf_reg_remap[]; #define SECONDARY_MEMORY_NEEDED_RTX(MODE) \ (get_frame_size () == 0 \ ? assign_stack_local (MODE, GET_MODE_SIZE (MODE), 0) \ - : gen_rtx (MEM, MODE, gen_rtx (PLUS, Pmode, frame_pointer_rtx, \ + : gen_rtx_MEM (MODE, gen_rtx_PLUS (Pmode, frame_pointer_rtx, \ GEN_INT (STARTING_FRAME_OFFSET)))) -/* Get_secondary_mem widens it's argument to BITS_PER_WORD which loses on v9 +/* Get_secondary_mem widens its argument to BITS_PER_WORD which loses on v9 because the movsi and movsf patterns don't handle r/f moves. For v8 we copy the default definition. */ #define SECONDARY_MEMORY_NEEDED_MODE(MODE) \ @@ -1408,9 +1455,14 @@ extern char leaf_reg_remap[]; : (STRUCT_VALUE_OFFSET + UNITS_PER_WORD)) /* When a parameter is passed in a register, stack space is still - allocated for it. */ -/* This only takes into account the int regs. - fp regs are handled elsewhere. */ + allocated for it. + !v9: All 6 possible integer registers have backing store allocated. + v9: Only space for the arguments passed is allocated. */ +/* ??? Ideally, we'd use zero here (as the minimum), but zero has special + meaning to the backend. Further, we need to be able to detect if a + varargs/unprototyped function is called, as they may want to spill more + registers than we've provided space. Ugly, ugly. So for now we retain + all 6 slots even for v9. */ #define REG_PARM_STACK_SPACE(DECL) (6 * UNITS_PER_WORD) /* Keep the stack pointer constant throughout the function. @@ -1431,24 +1483,28 @@ extern char leaf_reg_remap[]; /* Some subroutine macros specific to this machine. When !TARGET_FPU, put float return values in the general registers, since we don't have any fp registers. */ -#define BASE_RETURN_VALUE_REG(MODE) \ - (TARGET_ARCH64 \ - ? (TARGET_FPU && GET_MODE_CLASS (MODE) == MODE_FLOAT ? 32 : 8) \ +#define BASE_RETURN_VALUE_REG(MODE) \ + (TARGET_ARCH64 \ + ? (TARGET_FPU && FLOAT_MODE_P (MODE) ? 32 : 8) \ : (((MODE) == SFmode || (MODE) == DFmode) && TARGET_FPU ? 32 : 8)) -#define BASE_OUTGOING_VALUE_REG(MODE) \ - (TARGET_ARCH64 \ - ? (TARGET_FPU && GET_MODE_CLASS (MODE) == MODE_FLOAT ? 32 \ - : TARGET_FLAT ? 8 : 24) \ + +#define BASE_OUTGOING_VALUE_REG(MODE) \ + (TARGET_ARCH64 \ + ? (TARGET_FPU && FLOAT_MODE_P (MODE) ? 32 \ + : TARGET_FLAT ? 8 : 24) \ : (((MODE) == SFmode || (MODE) == DFmode) && TARGET_FPU ? 32 \ : (TARGET_FLAT ? 8 : 24))) -#define BASE_PASSING_ARG_REG(MODE) \ - (TARGET_ARCH64 \ - ? (TARGET_FPU && GET_MODE_CLASS (MODE) == MODE_FLOAT ? 32 : 8) \ + +#define BASE_PASSING_ARG_REG(MODE) \ + (TARGET_ARCH64 \ + ? (TARGET_FPU && FLOAT_MODE_P (MODE) ? 32 : 8) \ : 8) -#define BASE_INCOMING_ARG_REG(MODE) \ - (TARGET_ARCH64 \ - ? (TARGET_FPU && GET_MODE_CLASS (MODE) == MODE_FLOAT ? 32 \ - : TARGET_FLAT ? 8 : 24) \ + +/* ??? FIXME -- seems wrong for v9 structure passing... */ +#define BASE_INCOMING_ARG_REG(MODE) \ + (TARGET_ARCH64 \ + ? (TARGET_FPU && FLOAT_MODE_P (MODE) ? 32 \ + : TARGET_FLAT ? 8 : 24) \ : (TARGET_FLAT ? 8 : 24)) /* Define this macro if the target machine has "register windows". This @@ -1474,19 +1530,20 @@ extern char leaf_reg_remap[]; /* On SPARC the value is found in the first "output" register. */ -#define FUNCTION_VALUE(VALTYPE, FUNC) \ - gen_rtx (REG, TYPE_MODE (VALTYPE), BASE_RETURN_VALUE_REG (TYPE_MODE (VALTYPE))) +extern struct rtx_def *function_value (); +#define FUNCTION_VALUE(VALTYPE, FUNC) \ + function_value ((VALTYPE), TYPE_MODE (VALTYPE), 1) /* But the called function leaves it in the first "input" register. */ -#define FUNCTION_OUTGOING_VALUE(VALTYPE, FUNC) \ - gen_rtx (REG, TYPE_MODE (VALTYPE), BASE_OUTGOING_VALUE_REG (TYPE_MODE (VALTYPE))) +#define FUNCTION_OUTGOING_VALUE(VALTYPE, FUNC) \ + function_value ((VALTYPE), TYPE_MODE (VALTYPE), 0) /* Define how to find the value returned by a library function assuming the value has mode MODE. */ -#define LIBCALL_VALUE(MODE) \ - gen_rtx (REG, MODE, BASE_RETURN_VALUE_REG (MODE)) +#define LIBCALL_VALUE(MODE) \ + function_value (NULL_TREE, (MODE), 1) /* 1 if N is a possible register number for a function value as seen by the caller. @@ -1589,7 +1646,7 @@ function_arg_pass_by_reference (& (CUM), (MODE), (TYPE), (NAMED)) to pad out an argument with extra space. The value should be of type `enum direction': either `upward' to pad above the argument, `downward' to pad below, or `none' to inhibit padding. */ -extern enum direction function_arg_padding (); + #define FUNCTION_ARG_PADDING(MODE, TYPE) \ function_arg_padding ((MODE), (TYPE)) @@ -1604,17 +1661,6 @@ function_arg_padding ((MODE), (TYPE)) || ((TYPE) && TYPE_ALIGN (TYPE) == 128))) \ ? 128 : PARM_BOUNDARY) -/* Initialize data used by insn expanders. This is called from - init_emit, once for each function, before code is generated. - For v9, clear the temp slot used by float/int DImode conversions. - ??? There is the 16 bytes at [%fp-16], however we'd like to delete this - space at some point. - ??? Use assign_stack_temp? */ - -extern void sparc_init_expanders (); -extern struct rtx_def *sparc64_fpconv_stack_temp (); -#define INIT_EXPANDERS sparc_init_expanders () - /* Define the information needed to generate branch and scc insns. This is stored from the compare operation. Note that we can't use "rtx" here since it hasn't been defined! */ @@ -1637,7 +1683,7 @@ extern int gen_v9_scc (); the assembler). */ #define ASM_DECLARE_RESULT(FILE, RESULT) \ - fprintf ((FILE), "\t.proc\t0%o\n", sparc_type_code (TREE_TYPE (RESULT))) + fprintf ((FILE), "\t.proc\t0%lo\n", sparc_type_code (TREE_TYPE (RESULT))) /* Output the label for a function definition. */ @@ -1665,8 +1711,8 @@ do { \ extern int leaf_function; #define FUNCTION_PROLOGUE(FILE, SIZE) \ - (TARGET_FLAT ? sparc_flat_output_function_prologue (FILE, SIZE) \ - : output_function_prologue (FILE, SIZE, leaf_function)) + (TARGET_FLAT ? sparc_flat_output_function_prologue (FILE, (int)SIZE) \ + : output_function_prologue (FILE, (int)SIZE, leaf_function)) /* Output assembler code to FILE to increment profiler label # LABELNO for profiling a function entry. @@ -1925,19 +1971,24 @@ while(0) so we read only the condition codes by using branch instructions and hope that this is enough. */ -#define MACHINE_STATE_SAVE(ID) \ - asm (" mov %g0,%l0");\ - asm (" be,a LFLGNZ" ID);\ - asm (" or %l0,4,%l0");\ - asm ("LFLGNZ" ID ": bcs,a LFLGNC" ID);\ - asm (" or %l0,1,%l0");\ - asm ("LFLGNC" ID ": bvs,a LFLGNV" ID);\ - asm (" or %l0,2,%l0");\ - asm ("LFLGNV" ID ": bneg,a LFLGNN" ID);\ - asm (" or %l0,8,%l0");\ - asm ("LFLGNN" ID ": sethi %hi(LFLAGS" ID "),%l1");\ - asm (" st %l0,[%l1+%lo(LFLAGS" ID ")]"); \ - asm (" st %g2,[%l1+%lo(LSAVRET" ID ")]"); +#define MACHINE_STATE_SAVE(ID) \ + int ms_flags, ms_saveret; \ + asm volatile( \ + "mov %%g0,%0\n\ + be,a LFLGNZ"ID"\n\ + or %0,4,%0\n\ +LFLGNZ"ID":\n\ + bcs,a LFLGNC"ID"\n\ + or %0,1,%0\n\ +LFLGNC"ID":\n\ + bvs,a LFLGNV"ID"\n\ + or %0,2,%0\n\ +LFLGNV"ID":\n\ + bneg,a LFLGNN"ID"\n\ + or %0,8,%0\n\ +LFLGNN"ID":\n\ + mov %%g2,%1" \ + : "=r"(ms_flags), "=r"(ms_saveret)); /* On sparc MACHINE_STATE_RESTORE restores the psw register from memory. The psw register can be written in supervisor mode only, @@ -1947,74 +1998,65 @@ while(0) be generated in this way. If this happens an unimplemented instruction will be executed to abort the program. */ -#define MACHINE_STATE_RESTORE(ID) \ - asm (" sethi %hi(LFLGTAB" ID "),%l1");\ - asm (" ld [%l1+%lo(LFLGTAB" ID "-(LFLGTAB" ID "-LFLAGS" ID "))],%l0");\ - asm (" ld [%l1+%lo(LFLGTAB" ID "-(LFLGTAB" ID "-LSAVRET" ID "))],%g2");\ - asm (" sll %l0,2,%l0");\ - asm (" add %l0,%l1,%l0");\ - asm (" ld [%l0+%lo(LFLGTAB" ID ")],%l1");\ - asm (" jmp %l1");\ - asm (" nop");\ - asm (".data");\ - asm (" .align 4");\ - asm ("LFLAGS" ID ":");\ - asm (" .word 0");\ - asm ("LSAVRET" ID ":");\ - asm (" .word 0");\ - asm ("LFLGTAB" ID ": ");\ - asm (" .word LSFLG0" ID);\ - asm (" .word LSFLGC" ID);\ - asm (" .word LSFLGV" ID);\ - asm (" .word LSFLGVC" ID);\ - asm (" .word LSFLGZ" ID);\ - asm (" .word LSFLGZC" ID);\ - asm (" .word LSFLGZV" ID);\ - asm (" .word LSFLGZVC" ID);\ - asm (" .word LSFLGN" ID);\ - asm (" .word LSFLGNC" ID);\ - asm (" .word LSFLGNV" ID);\ - asm (" .word LSFLGNVC" ID);\ - asm (" .word LSFLGNZ" ID);\ - asm (" .word LSFLGNZC" ID);\ - asm (" .word LSFLGNZV" ID);\ - asm (" .word LSFLGNZVC" ID);\ - asm (".text");\ - asm ("LSFLGVC" ID ": mov -1,%l0");\ - asm (" addcc 2,%l0,%g0");\ - asm (" sethi %hi(0x80000000),%l0");\ - asm (" mov %l0,%l1");\ - asm (" ba LFLGRET" ID);\ - asm (" addxcc %l0,%l1,%l0");\ - asm ("LSFLGC" ID ": mov -1,%l0");\ - asm (" ba LFLGRET" ID);\ - asm (" addcc 2,%l0,%g0");\ - asm ("LSFLGZC" ID ": mov -1,%l0");\ - asm (" ba LFLGRET" ID);\ - asm (" addcc 1,%l0,%l0");\ - asm ("LSFLGZVC" ID ": sethi %hi(0x80000000),%l0");\ - asm (" mov %l0,%l1");\ - asm (" ba LFLGRET" ID);\ - asm (" addcc %l0,%l1,%l0");\ - asm ("LSFLGZ" ID ": ba LFLGRET" ID);\ - asm (" subcc %g0,%g0,%g0");\ - asm ("LSFLGNC" ID ": add %g0,1,%l0");\ - asm (" ba LFLGRET" ID);\ - asm (" subcc %g0,%l0,%g0");\ - asm ("LSFLG0" ID ": ba LFLGRET" ID);\ - asm (" orcc 1,%g0,%g0");\ - asm ("LSFLGN" ID ": ba LFLGRET" ID);\ - asm (" orcc -1,%g0,%g0");\ - asm ("LSFLGV" ID ":");\ - asm ("LSFLGZV" ID ":");\ - asm ("LSFLGNV" ID ":");\ - asm ("LSFLGNVC" ID ":");\ - asm ("LSFLGNZ" ID ":");\ - asm ("LSFLGNZC" ID ":");\ - asm ("LSFLGNZV" ID ":");\ - asm ("LSFLGNZVC" ID ":");\ - asm (" unimp");\ - asm ("LFLGRET" ID ":"); +#define MACHINE_STATE_RESTORE(ID) \ +{ extern char flgtab[] __asm__("LFLGTAB"ID); \ + int scratch; \ + asm volatile ( \ + "jmpl %2+%1,%%g0\n\ + ! Do part of VC in the delay slot here, as it needs 3 insns.\n\ + addcc 2,%3,%%g0\n\ +LFLGTAB" ID ":\n\ + ! 0\n\ + ba LFLGRET"ID"\n\ + orcc 1,%%g0,%%g0\n\ + ! C\n\ + ba LFLGRET"ID"\n\ + addcc 2,%3,%%g0\n\ + ! V\n\ + unimp\n\ + nop\n\ + ! VC\n\ + ba LFLGRET"ID"\n\ + addxcc %4,%4,%0\n\ + ! Z\n\ + ba LFLGRET"ID"\n\ + subcc %%g0,%%g0,%%g0\n\ + ! ZC\n\ + ba LFLGRET"ID"\n\ + addcc 1,%3,%0\n\ + ! ZVC\n\ + ba LFLGRET"ID"\n\ + addcc %4,%4,%0\n\ + ! N\n\ + ba LFLGRET"ID"\n\ + orcc %%g0,-1,%%g0\n\ + ! NC\n\ + ba LFLGRET"ID"\n\ + addcc %%g0,%3,%%g0\n\ + ! NV\n\ + unimp\n\ + nop\n\ + ! NVC\n\ + unimp\n\ + nop\n\ + ! NZ\n\ + unimp\n\ + nop\n\ + ! NZC\n\ + unimp\n\ + nop\n\ + ! NZV\n\ + unimp\n\ + nop\n\ + ! NZVC\n\ + unimp\n\ + nop\n\ +LFLGRET"ID":\n\ + mov %5,%%g2" \ + : "=r"(scratch) \ + : "r"(ms_flags*8), "r"(flgtab), "r"(-1), \ + "r"(0x80000000), "r"(ms_saveret) \ + : "cc", "%g2"); } /* EXIT_IGNORE_STACK should be nonzero if, when returning from a function, the stack pointer does not matter. The value is tested only in @@ -2044,8 +2086,8 @@ extern int current_function_outgoing_args_size; extern union tree_node *current_function_decl; #define FUNCTION_EPILOGUE(FILE, SIZE) \ - (TARGET_FLAT ? sparc_flat_output_function_epilogue (FILE, SIZE) \ - : output_function_epilogue (FILE, SIZE, leaf_function)) + (TARGET_FLAT ? sparc_flat_output_function_epilogue (FILE, (int)SIZE) \ + : output_function_epilogue (FILE, (int)SIZE, leaf_function)) #define DELAY_SLOTS_FOR_EPILOGUE \ (TARGET_FLAT ? sparc_flat_epilogue_delay_slots () : 1) @@ -2057,54 +2099,11 @@ extern union tree_node *current_function_decl; #define EPILOGUE_USES(REGNO) \ (!TARGET_FLAT && REGNO == 31) -/* Output assembler code for a block containing the constant parts - of a trampoline, leaving space for the variable parts. */ - -/* On 32 bit sparcs, the trampoline contains five instructions: - sethi #TOP_OF_FUNCTION,%g1 - or #BOTTOM_OF_FUNCTION,%g1,%g1 - sethi #TOP_OF_STATIC,%g2 - jmp g1 - or #BOTTOM_OF_STATIC,%g2,%g2 - - On 64 bit sparcs, the trampoline contains 4 insns and two pseudo-immediate - constants (plus some padding): - rd %pc,%g1 - ldx[%g1+20],%g5 - ldx[%g1+28],%g1 - jmp %g1 - nop - nop - .xword context - .xword function */ -/* ??? Stack is execute-protected in v9. */ - -#define TRAMPOLINE_TEMPLATE(FILE) \ -do { \ - if (TARGET_ARCH64) \ - { \ - fprintf (FILE, "\trd %%pc,%%g1\n"); \ - fprintf (FILE, "\tldx [%%g1+24],%%g5\n"); \ - fprintf (FILE, "\tldx [%%g1+32],%%g1\n"); \ - fprintf (FILE, "\tjmp %%g1\n"); \ - fprintf (FILE, "\tnop\n"); \ - fprintf (FILE, "\tnop\n"); \ - /* -mmedlow shouldn't generate .xwords, so don't use them at all */ \ - fprintf (FILE, "\t.word 0,0,0,0\n"); \ - } \ - else \ - { \ - ASM_OUTPUT_INT (FILE, gen_rtx (CONST_INT, VOIDmode, 0x00000000)); \ - ASM_OUTPUT_INT (FILE, gen_rtx (CONST_INT, VOIDmode, 0x00000000)); \ - ASM_OUTPUT_INT (FILE, gen_rtx (CONST_INT, VOIDmode, 0x00000000)); \ - ASM_OUTPUT_INT (FILE, gen_rtx (CONST_INT, VOIDmode, 0x81C04000)); \ - ASM_OUTPUT_INT (FILE, gen_rtx (CONST_INT, VOIDmode, 0x00000000)); \ - } \ -} while (0) - /* Length in units of the trampoline for entering a nested function. */ -#define TRAMPOLINE_SIZE (TARGET_ARCH64 ? 40 : 20) +#define TRAMPOLINE_SIZE (TARGET_ARCH64 ? 32 : 16) + +#define TRAMPOLINE_ALIGNMENT 128 /* 16 bytes */ /* Emit RTL insns to initialize the variable parts of a trampoline. FNADDR is an RTX for the address of the function's pure code. @@ -2113,12 +2112,10 @@ do { \ void sparc_initialize_trampoline (); void sparc64_initialize_trampoline (); #define INITIALIZE_TRAMPOLINE(TRAMP, FNADDR, CXT) \ - do { \ if (TARGET_ARCH64) \ sparc64_initialize_trampoline (TRAMP, FNADDR, CXT); \ else \ - sparc_initialize_trampoline (TRAMP, FNADDR, CXT); \ - } while (0) + sparc_initialize_trampoline (TRAMP, FNADDR, CXT) /* Generate necessary RTL for __builtin_saveregs(). ARGLIST is the argument list; see expr.c. */ @@ -2136,9 +2133,8 @@ extern struct rtx_def *sparc_builtin_saveregs (); is defined, then all arguments are treated as named. Otherwise, all named arguments except the last are treated as named. For the v9 we want NAMED to mean what it says it means. */ -/* ??? This needn't be set for v8, but I don't want to make this runtime - selectable if I don't have to. */ -#define STRICT_ARGUMENT_NAMING + +#define STRICT_ARGUMENT_NAMING TARGET_V9 /* Generate RTL to flush the register windows so as to make arbitrary frames available. */ @@ -2150,7 +2146,7 @@ extern struct rtx_def *sparc_builtin_saveregs (); that holds the dynamic chain--the previous frame's address. ??? -mflat support? */ #define DYNAMIC_CHAIN_ADDRESS(frame) \ - gen_rtx (PLUS, Pmode, frame, gen_rtx (CONST_INT, VOIDmode, 14 * UNITS_PER_WORD)) + gen_rtx_PLUS (Pmode, frame, GEN_INT (14 * UNITS_PER_WORD)) /* The return address isn't on the stack, it is in a register, so we can't access it from the current frame pointer. We can access it from the @@ -2169,8 +2165,8 @@ extern struct rtx_def *sparc_builtin_saveregs (); returns, and +12 for structure returns. */ #define RETURN_ADDR_RTX(count, frame) \ ((count == -1) \ - ? gen_rtx (REG, Pmode, 31) \ - : gen_rtx (MEM, Pmode, \ + ? gen_rtx_REG (Pmode, 31) \ + : gen_rtx_MEM (Pmode, \ memory_address (Pmode, plus_constant (frame, 15 * UNITS_PER_WORD)))) /* Before the prologue, the return address is %o7 + 8. OK, sometimes it's @@ -2178,7 +2174,7 @@ extern struct rtx_def *sparc_builtin_saveregs (); Actually, just using %o7 is close enough for unwinding, but %o7+8 is something you can return to. */ #define INCOMING_RETURN_ADDR_RTX \ - gen_rtx (PLUS, word_mode, gen_rtx (REG, word_mode, 15), GEN_INT (8)) + gen_rtx_PLUS (word_mode, gen_rtx_REG (word_mode, 15), GEN_INT (8)) /* The offset from the incoming value of %sp to the top of the stack frame for the current function. On sparc64, we have to account for the stack @@ -2204,16 +2200,16 @@ extern struct rtx_def *sparc_builtin_saveregs (); has been allocated, which happens in local-alloc.c. */ #define REGNO_OK_FOR_INDEX_P(REGNO) \ -((REGNO) < 32 || (unsigned) reg_renumber[REGNO] < 32) +((REGNO) < 32 || (unsigned) reg_renumber[REGNO] < (unsigned)32) #define REGNO_OK_FOR_BASE_P(REGNO) \ -((REGNO) < 32 || (unsigned) reg_renumber[REGNO] < 32) +((REGNO) < 32 || (unsigned) reg_renumber[REGNO] < (unsigned)32) #define REGNO_OK_FOR_FP_P(REGNO) \ - (((unsigned) (REGNO) - 32 < (TARGET_V9 ? 64 : 32)) \ - || ((unsigned) reg_renumber[REGNO] - 32 < (TARGET_V9 ? 64 : 32))) + (((unsigned) (REGNO) - 32 < (TARGET_V9 ? (unsigned)64 : (unsigned)32)) \ + || ((unsigned) reg_renumber[REGNO] - 32 < (TARGET_V9 ? (unsigned)64 : (unsigned)32))) #define REGNO_OK_FOR_CCFP_P(REGNO) \ (TARGET_V9 \ - && (((unsigned) (REGNO) - 96 < 4) \ - || ((unsigned) reg_renumber[REGNO] - 96 < 4))) + && (((unsigned) (REGNO) - 96 < (unsigned)4) \ + || ((unsigned) reg_renumber[REGNO] - 96 < (unsigned)4))) /* Now macros that check whether X is a register and also, strictly, whether it is in a specified class. @@ -2225,6 +2221,9 @@ extern struct rtx_def *sparc_builtin_saveregs (); /* 1 if X is an fp register. */ #define FP_REG_P(X) (REG_P (X) && REGNO_OK_FOR_FP_P (REGNO (X))) + +/* Is X, a REG, an in or global register? i.e. is regno 0..7 or 24..31 */ +#define IN_OR_GLOBAL_P(X) (REGNO (X) < 8 || (REGNO (X) >= 24 && REGNO (X) <= 31)) /* Maximum number of registers that can appear in a valid memory address. */ @@ -2414,30 +2413,30 @@ extern struct rtx_def *legitimize_pic_address (); #define LEGITIMIZE_ADDRESS(X,OLDX,MODE,WIN) \ { rtx sparc_x = (X); \ if (GET_CODE (X) == PLUS && GET_CODE (XEXP (X, 0)) == MULT) \ - (X) = gen_rtx (PLUS, Pmode, XEXP (X, 1), \ + (X) = gen_rtx_PLUS (Pmode, XEXP (X, 1), \ force_operand (XEXP (X, 0), NULL_RTX)); \ if (GET_CODE (X) == PLUS && GET_CODE (XEXP (X, 1)) == MULT) \ - (X) = gen_rtx (PLUS, Pmode, XEXP (X, 0), \ + (X) = gen_rtx_PLUS (Pmode, XEXP (X, 0), \ force_operand (XEXP (X, 1), NULL_RTX)); \ if (GET_CODE (X) == PLUS && GET_CODE (XEXP (X, 0)) == PLUS) \ - (X) = gen_rtx (PLUS, Pmode, force_operand (XEXP (X, 0), NULL_RTX),\ + (X) = gen_rtx_PLUS (Pmode, force_operand (XEXP (X, 0), NULL_RTX),\ XEXP (X, 1)); \ if (GET_CODE (X) == PLUS && GET_CODE (XEXP (X, 1)) == PLUS) \ - (X) = gen_rtx (PLUS, Pmode, XEXP (X, 0), \ + (X) = gen_rtx_PLUS (Pmode, XEXP (X, 0), \ force_operand (XEXP (X, 1), NULL_RTX)); \ if (sparc_x != (X) && memory_address_p (MODE, X)) \ goto WIN; \ if (flag_pic) (X) = legitimize_pic_address (X, MODE, 0); \ else if (GET_CODE (X) == PLUS && CONSTANT_ADDRESS_P (XEXP (X, 1))) \ - (X) = gen_rtx (PLUS, Pmode, XEXP (X, 0), \ + (X) = gen_rtx_PLUS (Pmode, XEXP (X, 0), \ copy_to_mode_reg (Pmode, XEXP (X, 1))); \ else if (GET_CODE (X) == PLUS && CONSTANT_ADDRESS_P (XEXP (X, 0))) \ - (X) = gen_rtx (PLUS, Pmode, XEXP (X, 1), \ + (X) = gen_rtx_PLUS (Pmode, XEXP (X, 1), \ copy_to_mode_reg (Pmode, XEXP (X, 0))); \ else if (GET_CODE (X) == SYMBOL_REF || GET_CODE (X) == CONST \ || GET_CODE (X) == LABEL_REF) \ - (X) = gen_rtx (LO_SUM, Pmode, \ - copy_to_mode_reg (Pmode, gen_rtx (HIGH, Pmode, X)), X); \ + (X) = gen_rtx_LO_SUM (Pmode, \ + copy_to_mode_reg (Pmode, gen_rtx_HIGH (Pmode, X)), X); \ if (memory_address_p (MODE, X)) \ goto WIN; } @@ -2461,10 +2460,11 @@ extern struct rtx_def *legitimize_pic_address (); for the index in the tablejump instruction. */ #define CASE_VECTOR_MODE Pmode -/* Define this if the tablejump instruction expects the table - to contain offsets from the address of the table. - Do not define this if the table should contain absolute addresses. */ -/* #define CASE_VECTOR_PC_RELATIVE */ +/* Define as C expression which evaluates to nonzero if the tablejump + instruction expects the table to contain offsets from the address of the + table. + Do not define this if the table should contain absolute addresses. */ +/* #define CASE_VECTOR_PC_RELATIVE 1 */ /* Specify the tree operation to be used to convert reals to integers. */ #define IMPLICIT_FIX_EXPR FIX_ROUND_EXPR @@ -2486,7 +2486,7 @@ extern struct rtx_def *legitimize_pic_address (); /* This is how to refer to the variable errno. */ #define GEN_ERRNO_RTX \ - gen_rtx (MEM, SImode, gen_rtx (SYMBOL_REF, Pmode, "errno")) + gen_rtx_MEM (SImode, gen_rtx_SYMBOL_REF (Pmode, "errno")) #endif /* 0 */ /* Define if operations between registers always perform the operation @@ -2559,7 +2559,7 @@ extern struct rtx_def *legitimize_pic_address (); : ((GET_CODE (X) == PLUS || GET_CODE (X) == MINUS \ || GET_CODE (X) == NEG || GET_CODE (X) == ASHIFT) \ ? (TARGET_ARCH64 && GET_MODE (X) == DImode ? CCX_NOOVmode : CC_NOOVmode) \ - : (TARGET_ARCH64 && GET_MODE (X) == DImode ? CCXmode : CCmode))) + : ((TARGET_ARCH64 || TARGET_V8PLUS) && GET_MODE (X) == DImode ? CCXmode : CCmode))) /* Return non-zero if SELECT_CC_MODE will never return MODE for a floating point inequality comparison. */ @@ -2619,32 +2619,32 @@ extern struct rtx_def *legitimize_pic_address (); #define INIT_TARGET_OPTABS \ do { \ add_optab->handlers[(int) TFmode].libfunc \ - = gen_rtx (SYMBOL_REF, Pmode, ADDTF3_LIBCALL); \ + = gen_rtx_SYMBOL_REF (Pmode, ADDTF3_LIBCALL); \ sub_optab->handlers[(int) TFmode].libfunc \ - = gen_rtx (SYMBOL_REF, Pmode, SUBTF3_LIBCALL); \ + = gen_rtx_SYMBOL_REF (Pmode, SUBTF3_LIBCALL); \ neg_optab->handlers[(int) TFmode].libfunc \ - = gen_rtx (SYMBOL_REF, Pmode, NEGTF2_LIBCALL); \ + = gen_rtx_SYMBOL_REF (Pmode, NEGTF2_LIBCALL); \ smul_optab->handlers[(int) TFmode].libfunc \ - = gen_rtx (SYMBOL_REF, Pmode, MULTF3_LIBCALL); \ + = gen_rtx_SYMBOL_REF (Pmode, MULTF3_LIBCALL); \ flodiv_optab->handlers[(int) TFmode].libfunc \ - = gen_rtx (SYMBOL_REF, Pmode, DIVTF3_LIBCALL); \ - eqtf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, EQTF2_LIBCALL); \ - netf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, NETF2_LIBCALL); \ - gttf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, GTTF2_LIBCALL); \ - getf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, GETF2_LIBCALL); \ - lttf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, LTTF2_LIBCALL); \ - letf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, LETF2_LIBCALL); \ - trunctfsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, TRUNCTFSF2_LIBCALL); \ - trunctfdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, TRUNCTFDF2_LIBCALL); \ - extendsftf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, EXTENDSFTF2_LIBCALL); \ - extenddftf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, EXTENDDFTF2_LIBCALL); \ - floatsitf_libfunc = gen_rtx (SYMBOL_REF, Pmode, FLOATSITF2_LIBCALL); \ - fixtfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, FIX_TRUNCTFSI2_LIBCALL); \ + = gen_rtx_SYMBOL_REF (Pmode, DIVTF3_LIBCALL); \ + eqtf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, EQTF2_LIBCALL); \ + netf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, NETF2_LIBCALL); \ + gttf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, GTTF2_LIBCALL); \ + getf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, GETF2_LIBCALL); \ + lttf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, LTTF2_LIBCALL); \ + letf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, LETF2_LIBCALL); \ + trunctfsf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, TRUNCTFSF2_LIBCALL); \ + trunctfdf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, TRUNCTFDF2_LIBCALL); \ + extendsftf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, EXTENDSFTF2_LIBCALL); \ + extenddftf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, EXTENDDFTF2_LIBCALL); \ + floatsitf_libfunc = gen_rtx_SYMBOL_REF (Pmode, FLOATSITF2_LIBCALL); \ + fixtfsi_libfunc = gen_rtx_SYMBOL_REF (Pmode, FIX_TRUNCTFSI2_LIBCALL); \ fixunstfsi_libfunc \ - = gen_rtx (SYMBOL_REF, Pmode, FIXUNS_TRUNCTFSI2_LIBCALL); \ + = gen_rtx_SYMBOL_REF (Pmode, FIXUNS_TRUNCTFSI2_LIBCALL); \ if (TARGET_FPU) \ sqrt_optab->handlers[(int) TFmode].libfunc \ - = gen_rtx (SYMBOL_REF, Pmode, "_Q_sqrt"); \ + = gen_rtx_SYMBOL_REF (Pmode, "_Q_sqrt"); \ INIT_SUBTARGET_OPTABS; \ } while (0) @@ -2682,11 +2682,13 @@ extern struct rtx_def *legitimize_pic_address (); #define ADDRESS_COST(RTX) 1 /* Compute extra cost of moving data between one register class - and another. - ??? v9: We ignore FPCC_REGS on the assumption they'll never be seen. */ -#define REGISTER_MOVE_COST(CLASS1, CLASS2) \ - (((FP_REG_CLASS_P (CLASS1) && (CLASS2) == GENERAL_REGS) \ - || ((CLASS1) == GENERAL_REGS && FP_REG_CLASS_P (CLASS2))) ? 6 : 2) + and another. */ +#define GENERAL_OR_I64(C) ((C) == GENERAL_REGS || (C) == I64_REGS) +#define REGISTER_MOVE_COST(CLASS1, CLASS2) \ + (((FP_REG_CLASS_P (CLASS1) && GENERAL_OR_I64 (CLASS2)) \ + || (GENERAL_OR_I64 (CLASS1) && FP_REG_CLASS_P (CLASS2)) \ + || (CLASS1) == FPCC_REGS || (CLASS2) == FPCC_REGS) \ + ? (sparc_cpu == PROCESSOR_ULTRASPARC ? 12 : 6) : 2) /* Provide the costs of a rtl expression. This is in the body of a switch on CODE. The purpose for the cost of MULT is to encourage @@ -2697,8 +2699,7 @@ extern struct rtx_def *legitimize_pic_address (); #define RTX_COSTS(X,CODE,OUTER_CODE) \ case MULT: \ - return (TARGET_V8 || TARGET_SPARCLITE) \ - ? COSTS_N_INSNS (5) : COSTS_N_INSNS (25); \ + return TARGET_HARD_MUL ? COSTS_N_INSNS (5) : COSTS_N_INSNS (25); \ case DIV: \ case UDIV: \ case MOD: \ @@ -2710,16 +2711,21 @@ extern struct rtx_def *legitimize_pic_address (); case FIX: \ return 19; +#define ISSUE_RATE sparc_issue_rate() + /* Adjust the cost of dependencies. */ -#define ADJUST_COST(INSN,LINK,DEP,COST) \ - if (sparc_cpu == PROCESSOR_SUPERSPARC) \ - (COST) = supersparc_adjust_cost (INSN, LINK, DEP, COST) +#define ADJUST_COST(INSN,LINK,DEP,COST) \ + if (sparc_cpu == PROCESSOR_SUPERSPARC) \ + (COST) = supersparc_adjust_cost (INSN, LINK, DEP, COST); \ + else if (sparc_cpu == PROCESSOR_ULTRASPARC) \ + (COST) = ultrasparc_adjust_cost (INSN, LINK, DEP, COST); \ + else /* Conditional branches with empty delay slots have a length of two. */ -#define ADJUST_INSN_LENGTH(INSN, LENGTH) \ +#define ADJUST_INSN_LENGTH(INSN, LENGTH) \ if (GET_CODE (INSN) == CALL_INSN \ || (GET_CODE (INSN) == JUMP_INSN && ! simplejump_p (insn))) \ - LENGTH += 1; + LENGTH += 1; else /* Control the assembler format that we output. */ @@ -2837,7 +2843,7 @@ extern struct rtx_def *legitimize_pic_address (); This is suitable for output with `assemble_name'. */ #define ASM_GENERATE_INTERNAL_LABEL(LABEL,PREFIX,NUM) \ - sprintf (LABEL, "*%s%d", PREFIX, NUM) + sprintf ((LABEL), "*%s%ld", (PREFIX), (long)(NUM)) /* This is how to output an assembler line defining a `float' constant. We always have to use a .long pseudo-op to do this because the native @@ -2933,7 +2939,7 @@ do { \ /* This is how to output an element of a case-vector that is relative. (SPARC uses such vectors only when generating PIC.) */ -#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, VALUE, REL) \ +#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) \ do { \ char label[30]; \ ASM_GENERATE_INTERNAL_LABEL (label, "L", VALUE); \ @@ -2955,11 +2961,9 @@ do { \ if ((LOG) != 0) \ fprintf (FILE, "\t.align %d\n", (1<<(LOG))) -#define ASM_OUTPUT_ALIGN_CODE(FILE) \ - ASM_OUTPUT_ALIGN (FILE, sparc_align_jumps) +#define LABEL_ALIGN_AFTER_BARRIER(LABEL) (sparc_align_jumps) -#define ASM_OUTPUT_LOOP_ALIGN(FILE) \ - ASM_OUTPUT_ALIGN (FILE, sparc_align_loops) +#define LOOP_ALIGN(LABEL) (sparc_align_loops) #define ASM_OUTPUT_SKIP(FILE,SIZE) \ fprintf (FILE, "\t.skip %u\n", (SIZE)) @@ -3016,37 +3020,37 @@ do { \ int big_delta = (DELTA) >= 4096 || (DELTA) < -4096; \ if (big_delta) \ fprintf (FILE, "\tset %d,%%g1\n\tadd %%o0,%%g1,%%o0\n", (DELTA)); \ - if (flag_pic) \ + /* Don't use the jmp solution unless we know the target is local to \ + the application or shared object. \ + XXX: Wimp out and don't actually check anything except if this is \ + an embedded target where we assume there are no shared libs. */ \ + if (!TARGET_CM_EMBMEDANY || flag_pic) \ { \ if (! big_delta) \ fprintf (FILE, "\tadd %%o0,%d,%%o0\n", DELTA); \ - fprintf (FILE, "\tsave %%sp,-112,%%sp\n"); \ + fprintf (FILE, "\tmov %%o7,%%g1\n"); \ fprintf (FILE, "\tcall "); \ - assemble_name \ - (FILE, IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (FUNCTION))); \ + assemble_name (FILE, XSTR (XEXP (DECL_RTL (FUNCTION), 0), 0)); \ fprintf (FILE, ",0\n"); \ } \ else if (TARGET_CM_EMBMEDANY) \ { \ fprintf (FILE, "\tsetx "); \ - assemble_name \ - (FILE, IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (FUNCTION))); \ + assemble_name (FILE, XSTR (XEXP (DECL_RTL (FUNCTION), 0), 0)); \ fprintf (FILE, ",%%g5,%%g1\n\tjmp %%g1\n"); \ } \ else \ { \ fprintf (FILE, "\tsethi %%hi("); \ - assemble_name \ - (FILE, IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (FUNCTION))); \ + assemble_name (FILE, XSTR (XEXP (DECL_RTL (FUNCTION), 0), 0)); \ fprintf (FILE, "),%%g1\n\tjmp %%g1+%%lo("); \ - assemble_name \ - (FILE, IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (FUNCTION))); \ + assemble_name (FILE, XSTR (XEXP (DECL_RTL (FUNCTION), 0), 0)); \ fprintf (FILE, ")\n"); \ } \ - if (big_delta) \ + if (!TARGET_CM_EMBMEDANY || flag_pic) \ + fprintf (FILE, "\tmov %%g1,%%o7\n"); \ + else if (big_delta) \ fprintf (FILE, "\tnop\n"); \ - else if (flag_pic) \ - fprintf (FILE, "\trestore\n"); \ else \ fprintf (FILE, "\tadd %%o0,%d,%%o0\n", DELTA); \ } while (0) @@ -3137,6 +3141,49 @@ do { \ } \ } +/* Define the codes that are matched by predicates in sparc.c. */ + +#define PREDICATE_CODES \ +{"reg_or_0_operand", {SUBREG, REG, CONST_INT, CONST_DOUBLE}}, \ +{"fp_zero_operand", {CONST_DOUBLE}}, \ +{"intreg_operand", {SUBREG, REG}}, \ +{"fcc_reg_operand", {REG}}, \ +{"icc_or_fcc_reg_operand", {REG}}, \ +{"restore_operand", {REG}}, \ +{"call_operand", {MEM}}, \ +{"call_operand_address", {SYMBOL_REF, LABEL_REF, CONST, CONST_DOUBLE, ADDRESSOF, \ + SUBREG, REG, PLUS, LO_SUM, CONST_INT}}, \ +{"symbolic_operand", {SYMBOL_REF, LABEL_REF, CONST, CONST_DOUBLE}}, \ +{"symbolic_memory_operand", {SUBREG, MEM}}, \ +{"label_ref_operand", {LABEL_REF}}, \ +{"sp64_medium_pic_operand", {CONST}}, \ +{"data_segment_operand", {SYMBOL_REF, PLUS, CONST}}, \ +{"text_segment_operand", {LABEL_REF, SYMBOL_REF, PLUS, CONST}}, \ +{"reg_or_nonsymb_mem_operand", {SUBREG, REG, MEM}}, \ +{"sparc_operand", {SUBREG, REG, CONSTANT_P_RTX, CONST_INT, MEM}}, \ +{"move_operand", {SUBREG, REG, CONSTANT_P_RTX, CONST_INT, CONST_DOUBLE, MEM}}, \ +{"splittable_symbolic_memory_operand", {MEM}}, \ +{"splittable_immediate_memory_operand", {MEM}}, \ +{"eq_or_neq", {EQ, NE}}, \ +{"normal_comp_operator", {GE, GT, LE, LT, GTU, LEU}}, \ +{"noov_compare_op", {NE, EQ, GE, GT, LE, LT, GEU, GTU, LEU, LTU}}, \ +{"v9_regcmp_op", {EQ, NE, GE, LT, LE, GT}}, \ +{"v8plus_regcmp_op", {EQ, NE}}, \ +{"extend_op", {SIGN_EXTEND, ZERO_EXTEND}}, \ +{"cc_arithop", {AND, IOR, XOR}}, \ +{"cc_arithopn", {AND, IOR}}, \ +{"arith_operand", {SUBREG, REG, CONSTANT_P_RTX, CONST_INT}}, \ +{"arith11_operand", {SUBREG, REG, CONSTANT_P_RTX, CONST_INT}}, \ +{"arith10_operand", {SUBREG, REG, CONSTANT_P_RTX, CONST_INT}}, \ +{"arith_double_operand", {SUBREG, REG, CONSTANT_P_RTX, CONST_INT, CONST_DOUBLE}}, \ +{"arith11_double_operand", {SUBREG, REG, CONSTANT_P_RTX, CONST_INT, CONST_DOUBLE}}, \ +{"arith10_double_operand", {SUBREG, REG, CONSTANT_P_RTX, CONST_INT, CONST_DOUBLE}}, \ +{"small_int", {CONST_INT, CONSTANT_P_RTX}}, \ +{"uns_small_int", {CONST_INT, CONSTANT_P_RTX}}, \ +{"uns_arith_operand", {SUBREG, REG, CONST_INT, CONSTANT_P_RTX}}, \ +{"clobbered_register", {REG}}, + + /* The number of Pmode words for the setjmp buffer. */ #define JMP_BUF_SIZE 12 @@ -3144,17 +3191,91 @@ do { \ /* Declare functions defined in sparc.c and used in templates. */ -extern char *singlemove_string (); extern char *doublemove_string (); -extern char *output_move_double (); -extern char *output_move_quad (); +extern char *output_block_move (); +extern char *output_cbranch (); extern char *output_fp_move_double (); extern char *output_fp_move_quad (); -extern char *output_block_move (); -extern char *output_scc_insn (); -extern char *output_cbranch (); -extern char *output_v9branch (); +extern char *output_move_double (); +extern char *output_move_quad (); extern char *output_return (); +extern char *output_scc_insn (); +extern char *output_v9branch (); +extern char *singlemove_string (); + +extern void emit_v9_brxx_insn (); +extern void finalize_pic (); +extern void order_regs_for_local_alloc (); +extern void output_double_int (); +extern void output_function_epilogue (); +extern void output_function_prologue (); +extern void print_operand (); +extern void sparc_flat_output_function_epilogue (); +extern void sparc_flat_output_function_prologue (); + +extern int addrs_ok_for_ldd_peep (); +extern int arith10_double_operand (); +extern int arith10_operand (); +extern int arith11_double_operand (); +extern int arith11_operand (); +extern int arith_double_operand (); +extern int arith_operand (); +extern int call_operand_address (); +extern int cc_arithop (); +extern int cc_arithopn (); +extern int check_pic (); +extern int compute_frame_size (); +extern int data_segment_operand (); +extern int eligible_for_epilogue_delay (); +extern int eligible_for_return_delay (); +extern int emit_move_sequence (); +extern int extend_op (); +extern int fcc_reg_operand (); +extern int fp_zero_operand (); +extern int icc_or_fcc_reg_operand (); +extern int label_ref_operand (); +extern int mem_aligned_8 (); +extern int move_operand (); +extern int noov_compare_op (); +extern int pic_address_needs_scratch (); +extern int reg_or_0_operand (); +extern int reg_or_nonsymb_mem_operand (); +extern int reg_unused_after (); +extern int register_ok_for_ldd (); +extern int registers_ok_for_ldd_peep (); +extern int restore_operand (); +extern int short_branch (); +extern int small_int (); +extern int sp64_medium_pic_operand (); +extern int sparc_flat_eligible_for_epilogue_delay (); +extern int sparc_flat_epilogue_delay_slots (); +extern int sparc_issue_rate (); +extern int sparc_operand (); +extern int splittable_immediate_memory_operand (); +extern int splittable_symbolic_memory_operand (); +extern int supersparc_adjust_cost (); +extern int symbolic_memory_operand (); +extern int symbolic_operand (); +extern int text_segment_operand (); +extern int ultrasparc_adjust_cost (); +extern int uns_small_int (); +extern int v8plus_regcmp_op (); +extern int v8plus_regcmp_p (); +extern int v9_regcmp_op (); +extern int v9_regcmp_p (); + +extern unsigned long sparc_flat_compute_frame_size (); +extern unsigned long sparc_type_code (); + +extern char *sparc_v8plus_shift (); + +#ifdef __STDC__ +/* Function used for V8+ code generation. Returns 1 if the high + 32 bits of REG are 0 before INSN. */ +extern int sparc_check_64 (struct rtx_def *, struct rtx_def *); +extern int sparc_return_peephole_ok (struct rtx_def *, struct rtx_def *); +extern int compute_frame_size (int, int); +#endif /* Defined in flags.h, but insn-emit.c does not include flags.h. */ diff --git a/gnu/dist/gcc/config/sparc/sparc.md b/gnu/dist/gcc/config/sparc/sparc.md index de1f090bcdb5..47d2d3de7ad3 100644 --- a/gnu/dist/gcc/config/sparc/sparc.md +++ b/gnu/dist/gcc/config/sparc/sparc.md @@ -34,7 +34,7 @@ ;; Attribute for cpu type. ;; These must match the values for enum processor_type in sparc.h. -(define_attr "cpu" "v7,cypress,v8,supersparc,sparclite,f930,f934,sparclet,tsc701,v8plus,v9,ultrasparc" +(define_attr "cpu" "v7,cypress,v8,supersparc,sparclite,f930,f934,sparclet,tsc701,v9,ultrasparc" (const (symbol_ref "sparc_cpu_attr"))) ;; Attribute for the instruction set. @@ -67,7 +67,7 @@ ;; type "call_no_delay_slot" is a call followed by an unimp instruction. (define_attr "type" - "move,unary,binary,compare,load,store,ialu,shift,uncond_branch,branch,call,call_no_delay_slot,address,imul,fpload,fpstore,fp,fpcmp,fpmul,fpdivs,fpdivd,fpsqrt,cmove,multi,misc" + "move,unary,binary,compare,load,sload,store,ialu,shift,uncond_branch,branch,call,call_no_delay_slot,return,address,imul,fpload,fpstore,fp,fpmove,fpcmove,fpcmp,fpmul,fpdivs,fpdivd,fpsqrt,cmove,multi,misc" (const_string "binary")) ;; Set true if insn uses call-clobbered intermediate register. @@ -79,7 +79,7 @@ ;; Length (in # of insns). (define_attr "length" "" - (cond [(eq_attr "type" "load,fpload") + (cond [(eq_attr "type" "load,sload,fpload") (if_then_else (match_operand 1 "symbolic_memory_operand" "") (const_int 2) (const_int 1)) @@ -110,7 +110,7 @@ ;; Attributes for instruction and branch scheduling (define_attr "in_call_delay" "false,true" - (cond [(eq_attr "type" "uncond_branch,branch,call,call_no_delay_slot,multi") + (cond [(eq_attr "type" "uncond_branch,branch,call,call_no_delay_slot,return,multi") (const_string "false") (eq_attr "type" "load,fpload,store,fpstore") (if_then_else (eq_attr "length" "1") @@ -127,6 +127,22 @@ (define_delay (eq_attr "type" "call") [(eq_attr "in_call_delay" "true") (nil) (nil)]) +(define_attr "leaf_function" "false,true" + (const (symbol_ref "leaf_function"))) + + +(define_attr "in_return_delay" "false,true" + (if_then_else (and (and (and (eq_attr "type" "move,load,sload,store,binary,ialu") + (eq_attr "length" "1")) + (eq_attr "leaf_function" "false")) + (match_insn "eligible_for_return_delay")) + (const_string "true") + (const_string "false"))) + +(define_delay (and (eq_attr "type" "return") + (eq_attr "isa" "v9")) + [(eq_attr "in_return_delay" "true") (nil) (nil)]) + ;; ??? Should implement the notion of predelay slots for floating point ;; branches. This would allow us to remove the nop always inserted before ;; a floating point branch. @@ -182,8 +198,11 @@ ;; ---- cypress CY7C602 scheduling: ;; Memory with load-delay of 1 (i.e., 2 cycle load). + (define_function_unit "memory" 1 0 - (and (eq_attr "type" "load,fpload") (eq_attr "cpu" "cypress")) 2 2) + (and (eq_attr "cpu" "cypress") + (eq_attr "type" "load,sload,fpload")) + 2 2) ;; SPARC has two floating-point units: the FP ALU, ;; and the FP MUL/DIV/SQRT unit. @@ -205,34 +224,57 @@ ;; More insns cause the chip to stall. (define_function_unit "fp_alu" 1 0 - (and (eq_attr "type" "fp") (eq_attr "cpu" "cypress")) 5 5) + (and (eq_attr "cpu" "cypress") + (eq_attr "type" "fp,fpmove")) + 5 5) + (define_function_unit "fp_mds" 1 0 - (and (eq_attr "type" "fpmul") (eq_attr "cpu" "cypress")) 7 7) + (and (eq_attr "cpu" "cypress") + (eq_attr "type" "fpmul")) + 7 7) + (define_function_unit "fp_mds" 1 0 - (and (eq_attr "type" "fpdivs,fpdivd") (eq_attr "cpu" "cypress")) 37 37) + (and (eq_attr "cpu" "cypress") + (eq_attr "type" "fpdivs,fpdivd")) + 37 37) + (define_function_unit "fp_mds" 1 0 - (and (eq_attr "type" "fpsqrt") (eq_attr "cpu" "cypress")) 63 63) + (and (eq_attr "cpu" "cypress") + (eq_attr "type" "fpsqrt")) + 63 63) ;; ----- The TMS390Z55 scheduling -;; The Supersparc can issue 1 - 3 insns per cycle; here we assume -;; three insns/cycle, and hence multiply all costs by three. -;; Combinations up to two integer, one ld/st, one fp. +;; The Supersparc can issue 1 - 3 insns per cycle: up to two integer, +;; one ld/st, one fp. ;; Memory delivers its result in one cycle to IU, zero cycles to FP + (define_function_unit "memory" 1 0 - (and (eq_attr "type" "load") (eq_attr "cpu" "supersparc")) 3 3) + (and (eq_attr "cpu" "supersparc") + (eq_attr "type" "load,sload")) + 1 1) + (define_function_unit "memory" 1 0 - (and (eq_attr "type" "fpload") (eq_attr "cpu" "supersparc")) 1 3) -;; at least one in three instructions can be a mem opt. + (and (eq_attr "cpu" "supersparc") + (eq_attr "type" "fpload")) + 0 1) + (define_function_unit "memory" 1 0 - (and (eq_attr "type" "store,fpstore") (eq_attr "cpu" "supersparc")) 1 3) -;; at least one in three instructions can be a shift op. + (and (eq_attr "cpu" "supersparc") + (eq_attr "type" "store,fpstore")) + 1 1) + (define_function_unit "shift" 1 0 - (and (eq_attr "type" "shift") (eq_attr "cpu" "supersparc")) 1 3) + (and (eq_attr "cpu" "supersparc") + (eq_attr "type" "shift")) + 1 1) ;; There are only two write ports to the integer register file ;; A store also uses a write port + (define_function_unit "iwport" 2 0 - (and (eq_attr "type" "load,store,shift,ialu") (eq_attr "cpu" "supersparc")) 1 3) + (and (eq_attr "cpu" "supersparc") + (eq_attr "type" "load,sload,store,shift,ialu")) + 1 1) ;; Timings; throughput/latency ;; FADD 1/3 add/sub, format conv, compar, abs, neg @@ -244,71 +286,160 @@ ;; IMUL 4/4 (define_function_unit "fp_alu" 1 0 - (and (eq_attr "type" "fp,fpcmp") (eq_attr "cpu" "supersparc")) 9 3) + (and (eq_attr "cpu" "supersparc") + (eq_attr "type" "fp,fpmove,fpcmp")) + 3 1) + (define_function_unit "fp_mds" 1 0 - (and (eq_attr "type" "fpmul") (eq_attr "cpu" "supersparc")) 9 3) + (and (eq_attr "cpu" "supersparc") + (eq_attr "type" "fpmul")) + 3 1) + (define_function_unit "fp_mds" 1 0 - (and (eq_attr "type" "fpdivs") (eq_attr "cpu" "supersparc")) 18 12) + (and (eq_attr "cpu" "supersparc") + (eq_attr "type" "fpdivs")) + 6 4) + (define_function_unit "fp_mds" 1 0 - (and (eq_attr "type" "fpdivd") (eq_attr "cpu" "supersparc")) 27 21) + (and (eq_attr "cpu" "supersparc") + (eq_attr "type" "fpdivd")) + 9 7) + (define_function_unit "fp_mds" 1 0 - (and (eq_attr "type" "fpsqrt") (eq_attr "cpu" "supersparc")) 36 30) + (and (eq_attr "cpu" "supersparc") + (eq_attr "type" "fpsqrt")) + 12 10) + (define_function_unit "fp_mds" 1 0 - (and (eq_attr "type" "imul") (eq_attr "cpu" "supersparc")) 12 12) + (and (eq_attr "cpu" "supersparc") + (eq_attr "type" "imul")) + 4 4) ;; ----- sparclet tsc701 scheduling ;; The tsc701 issues 1 insn per cycle. ;; Results may be written back out of order. ;; Loads take 2 extra cycles to complete and 4 can be buffered at a time. + (define_function_unit "tsc701_load" 4 1 - (and (eq_attr "type" "load") (eq_attr "cpu" "tsc701")) 3 1) + (and (eq_attr "cpu" "tsc701") + (eq_attr "type" "load,sload")) + 3 1) + ;; Stores take 2(?) extra cycles to complete. ;; It is desirable to not have any memory operation in the following 2 cycles. ;; (??? or 2 memory ops in the case of std). + (define_function_unit "tsc701_store" 1 0 - (and (eq_attr "type" "store") (eq_attr "cpu" "tsc701")) 3 3 - [(eq_attr "type" "load,store")]) + (and (eq_attr "cpu" "tsc701") + (eq_attr "type" "store")) + 3 3 + [(eq_attr "type" "load,sload,store")]) + ;; The multiply unit has a latency of 5. (define_function_unit "tsc701_mul" 1 0 - (and (eq_attr "type" "imul") (eq_attr "cpu" "tsc701")) 5 5) + (and (eq_attr "cpu" "tsc701") + (eq_attr "type" "imul")) + 5 5) ;; ----- The UltraSPARC-1 scheduling -;; The Ultrasparc can issue 1 - 4 insns per cycle; here we assume -;; four insns/cycle, and hence multiply all costs by four. +;; UltraSPARC has two integer units. Shift instructions can only execute +;; on IE0. Condition code setting instructions, call, and jmpl (including +;; the ret and retl pseudo-instructions) can only execute on IE1. +;; Branch on register uses IE1, but branch on condition code does not. +;; Conditional moves take 2 cycles. No other instruction can issue in the +;; same cycle as a conditional move. +;; Multiply and divide take many cycles during which no other instructions +;; can issue. +;; Memory delivers its result in two cycles (except for signed loads, +;; which take one cycle more). One memory instruction can be issued per +;; cycle. -;; Memory delivers its result in three cycles to IU, three cycles to FP (define_function_unit "memory" 1 0 - (and (eq_attr "type" "load,fpload") (eq_attr "cpu" "ultrasparc")) 12 4) + (and (eq_attr "cpu" "ultrasparc") + (eq_attr "type" "load,fpload")) + 2 1) + (define_function_unit "memory" 1 0 - (and (eq_attr "type" "store,fpstore") (eq_attr "cpu" "ultrasparc")) 4 4) + (and (eq_attr "cpu" "ultrasparc") + (eq_attr "type" "sload")) + 3 1) + +(define_function_unit "memory" 1 0 + (and (eq_attr "cpu" "ultrasparc") + (eq_attr "type" "store,fpstore")) + 1 1) + (define_function_unit "ieu" 1 0 - (and (eq_attr "type" "ialu") (eq_attr "cpu" "ultrasparc")) 1 2) -(define_function_unit "ieu" 1 0 - (and (eq_attr "type" "shift") (eq_attr "cpu" "ultrasparc")) 1 4) -(define_function_unit "ieu" 1 0 - (and (eq_attr "type" "cmove") (eq_attr "cpu" "ultrasparc")) 8 4) + (and (eq_attr "cpu" "ultrasparc") + (eq_attr "type" "ialu,binary,shift,compare,cmove,call")) + 1 1) + +(define_function_unit "ieu_shift" 1 0 + (and (eq_attr "cpu" "ultrasparc") + (eq_attr "type" "shift")) + 1 1) + +(define_function_unit "ieu_shift" 1 0 + (and (eq_attr "cpu" "ultrasparc") + (eq_attr "type" "cmove")) + 2 1) ;; Timings; throughput/latency -;; ?? FADD 1/3 add/sub, format conv, compar, abs, neg -;; ?? FMUL 1/3 -;; ?? FDIVs 1/12 -;; ?? FDIVd 1/22 -;; ?? FSQRTs 1/12 -;; ?? FSQRTd 1/22 +;; FMOV 1/1 fmov, fabs, fneg +;; FMOVcc 1/2 +;; FADD 1/4 add/sub, format conv, compar +;; FMUL 1/4 +;; FDIVs 12/12 +;; FDIVd 22/22 +;; FSQRTs 12/12 +;; FSQRTd 22/22 +;; FCMP takes 1 cycle to branch, 2 cycles to conditional move. -(define_function_unit "fp" 1 0 - (and (eq_attr "type" "fp") (eq_attr "cpu" "ultrasparc")) 12 2) -(define_function_unit "fp" 1 0 - (and (eq_attr "type" "fpcmp") (eq_attr "cpu" "ultrasparc")) 8 2) -(define_function_unit "fp" 1 0 - (and (eq_attr "type" "fpmul") (eq_attr "cpu" "ultrasparc")) 12 2) -(define_function_unit "fp" 1 0 - (and (eq_attr "type" "fpdivs") (eq_attr "cpu" "ultrasparc")) 48 2) -(define_function_unit "fp" 1 0 - (and (eq_attr "type" "fpdivd") (eq_attr "cpu" "ultrasparc")) 88 2) -(define_function_unit "fp" 1 0 - (and (eq_attr "type" "fpsqrt") (eq_attr "cpu" "ultrasparc")) 48 2) +(define_function_unit "fadd" 1 0 + (and (eq_attr "cpu" "ultrasparc") + (eq_attr "type" "fpmove")) + 1 1) + +(define_function_unit "fadd" 1 0 + (and (eq_attr "cpu" "ultrasparc") + (eq_attr "type" "fpcmove")) + 2 1) + +(define_function_unit "fadd" 1 0 + (and (eq_attr "cpu" "ultrasparc") + (eq_attr "type" "fp")) + 4 1) + +(define_function_unit "fadd" 1 0 + (and (eq_attr "cpu" "ultrasparc") + (eq_attr "type" "fpcmp")) + 2 1) + +(define_function_unit "fmul" 1 0 + (and (eq_attr "cpu" "ultrasparc") + (eq_attr "type" "fpmul")) + 4 1) + +(define_function_unit "fadd" 1 0 + (and (eq_attr "cpu" "ultrasparc") + (eq_attr "type" "fpcmove")) + 2 1) + +(define_function_unit "fadd" 1 0 + (and (eq_attr "cpu" "ultrasparc") + (eq_attr "type" "fpdivs")) + 12 12) + +(define_function_unit "fadd" 1 0 + (and (eq_attr "cpu" "ultrasparc") + (eq_attr "type" "fpdivd")) + 22 22) + +(define_function_unit "fadd" 1 0 + (and (eq_attr "cpu" "ultrasparc") + (eq_attr "type" "fpsqrt")) + 12 12) ;; Compare instructions. ;; This controls RTL generation and register allocation. @@ -344,7 +475,7 @@ [(set (reg:CCX 100) (compare:CCX (match_operand:DI 0 "register_operand" "") (match_operand:DI 1 "arith_double_operand" "")))] - "TARGET_ARCH64" + "TARGET_ARCH64 || TARGET_V8PLUS" " { sparc_compare_op0 = operands[0]; @@ -409,6 +540,39 @@ "cmp %0,%1" [(set_attr "type" "compare")]) +(define_insn "cmpdi_v8plus" + [(set (reg:CCX 100) + (compare:CCX (match_operand:DI 0 "register_operand" "r,r,r") + (match_operand:DI 1 "arith_double_operand" "J,I,r"))) + (clobber (match_scratch:SI 2 "=&h,&h,&h")) + (clobber (match_scratch:SI 3 "=X,X,&h"))] + "TARGET_V8PLUS" + "* +{ + /* The srl can be omitted if the value in the %L0 or %L1 is already + zero extended. */ + + output_asm_insn (\"sllx %H0,32,%2\", operands); + + if (sparc_check_64 (operands[0], insn) <= 0) + output_asm_insn (\"srl %L0,0,%L0\", operands); + + switch (which_alternative) + { + case 0: + return \"orcc %L0,%2,%%g0\"; + case 1: + return \"or %L0,%2,%2\;cmp %2,%1\"; + case 2: + if (sparc_check_64 (operands[1], insn) <= 0) + output_asm_insn (\"srl %L1,0,%L1\", operands); + return \"sllx %H1,32,%3\;or %L0,%2,%2\;or %L1,%3,%3\;cmp %2,%3\"; + default: + abort(); + } +}" + [(set_attr "length" "3,4,7")]) + (define_insn "*cmpsf_fpe" [(set (match_operand:CCFPE 0 "fcc_reg_operand" "=c") (compare:CCFPE (match_operand:SF 1 "register_operand" "f") @@ -896,7 +1060,7 @@ (const_int 0)))] "TARGET_ARCH64" "mov 0,%0\;movrnz %1,1,%0" - [(set_attr "type" "unary") + [(set_attr "type" "cmove") (set_attr "length" "2")]) (define_insn "*neg_snedi_zero" @@ -905,7 +1069,7 @@ (const_int 0))))] "TARGET_ARCH64" "mov 0,%0\;movrnz %1,-1,%0" - [(set_attr "type" "unary") + [(set_attr "type" "cmove") (set_attr "length" "2")]) (define_insn "*snedi_zero_trunc" @@ -914,7 +1078,7 @@ (const_int 0)))] "TARGET_ARCH64" "mov 0,%0\;movrnz %1,1,%0" - [(set_attr "type" "unary") + [(set_attr "type" "cmove") (set_attr "length" "2")]) (define_insn "*seqsi_zero" @@ -953,7 +1117,7 @@ (const_int 0)))] "TARGET_ARCH64" "mov 0,%0\;movrz %1,1,%0" - [(set_attr "type" "unary") + [(set_attr "type" "cmove") (set_attr "length" "2")]) (define_insn "*neg_seqdi_zero" @@ -962,7 +1126,7 @@ (const_int 0))))] "TARGET_ARCH64" "mov 0,%0\;movrz %1,-1,%0" - [(set_attr "type" "unary") + [(set_attr "type" "cmove") (set_attr "length" "2")]) (define_insn "*seqdi_zero_trunc" @@ -971,7 +1135,7 @@ (const_int 0)))] "TARGET_ARCH64" "mov 0,%0\;movrz %1,1,%0" - [(set_attr "type" "unary") + [(set_attr "type" "cmove") (set_attr "length" "2")]) ;; We can also do (x + (i == 0)) and related, so put them in. @@ -1144,6 +1308,22 @@ [(set_attr "type" "multi") (set_attr "length" "3")]) +(define_split + [(set (match_operand:SI 0 "register_operand" "=r") + (match_operator:SI 2 "noov_compare_op" + [(match_operand 1 "icc_or_fcc_reg_operand" "") + (const_int 0)]))] + ;; 32 bit LTU/GEU are better implemented using addx/subx + "TARGET_V9 && REGNO (operands[1]) == SPARC_ICC_REG + && (GET_MODE (operands[1]) == CCXmode + || (GET_CODE (operands[2]) != LTU && GET_CODE (operands[2]) != GEU))" + [(set (match_dup 0) (const_int 0)) + (set (match_dup 0) + (if_then_else:SI (match_op_dup:SI 2 [(match_dup 1) (const_int 0)]) + (const_int 1) + (match_dup 0)))] + "") + (define_insn "*scc_di" [(set (match_operand:DI 0 "register_operand" "=r") (match_operator:DI 2 "noov_compare_op" @@ -1357,7 +1537,7 @@ { return output_cbranch (operands[0], 1, 0, final_sequence && INSN_ANNULLED_BRANCH_P (insn), - ! final_sequence); + ! final_sequence, insn); }" [(set_attr "type" "branch")]) @@ -1372,7 +1552,7 @@ { return output_cbranch (operands[0], 1, 1, final_sequence && INSN_ANNULLED_BRANCH_P (insn), - ! final_sequence); + ! final_sequence, insn); }" [(set_attr "type" "branch")]) @@ -1388,7 +1568,7 @@ { return output_cbranch (operands[1], 2, 0, final_sequence && INSN_ANNULLED_BRANCH_P (insn), - ! final_sequence); + ! final_sequence, insn); }" [(set_attr "type" "branch")]) @@ -1404,7 +1584,7 @@ { return output_cbranch (operands[1], 2, 1, final_sequence && INSN_ANNULLED_BRANCH_P (insn), - ! final_sequence); + ! final_sequence, insn); }" [(set_attr "type" "branch")]) @@ -1420,7 +1600,7 @@ { return output_cbranch (operands[1], 2, 0, final_sequence && INSN_ANNULLED_BRANCH_P (insn), - ! final_sequence); + ! final_sequence, insn); }" [(set_attr "type" "branch")]) @@ -1436,7 +1616,7 @@ { return output_cbranch (operands[1], 2, 1, final_sequence && INSN_ANNULLED_BRANCH_P (insn), - ! final_sequence); + ! final_sequence, insn); }" [(set_attr "type" "branch")]) @@ -1519,30 +1699,31 @@ (define_insn "pic_lo_sum_di" [(set (match_operand:DI 0 "register_operand" "=r") - (lo_sum:SI (match_operand:DI 1 "register_operand" "r") - (unspec:SI [(match_operand:DI 2 "immediate_operand" "in")] 0)))] + (lo_sum:SI (match_operand:DI 1 "register_operand" "r") + (unspec:SI [(match_operand:DI 2 "immediate_operand" "in")] 0)))] "TARGET_ARCH64 && flag_pic" "add %1,%%lo(%a2),%0" [(set_attr "length" "1")]) (define_insn "pic_sethi_di" [(set (match_operand:DI 0 "register_operand" "=r") - (high:SI (unspec:SI [(match_operand 1 "" "")] 0)))] + (high:SI (unspec:SI [(match_operand 1 "" "")] 0)))] "TARGET_ARCH64 && flag_pic && check_pic (1)" "sethi %%hi(%a1),%0" [(set_attr "type" "move") (set_attr "length" "1")]) -(define_insn "get_pc_via_call" - [(set (pc) (label_ref (match_operand 0 "" ""))) - (set (reg:SI 15) (label_ref (match_operand 1 "" "")))] - "" - "call %l0%#" - [(set_attr "type" "uncond_branch")]) +(define_insn "get_pc" + [(clobber (reg:SI 15)) + (set (match_operand 0 "register_operand" "=r") + (unspec [(match_operand 1 "" "") (match_operand 2 "" "")] 2))] + "flag_pic && REGNO (operands[0]) == 23" + "sethi %%hi(%a1-4),%0\;call %a2\;add %0,%%lo(%a1+4),%0" + [(set_attr "length" "3")]) (define_insn "get_pc_via_rdpc" - [(set (match_operand:DI 0 "register_operand" "=r") (pc))] - "TARGET_PTR64" + [(set (match_operand 0 "register_operand" "=r") (pc))] + "TARGET_V9" "rd %%pc,%0" [(set_attr "type" "move")]) @@ -1972,12 +2153,15 @@ ;; in an fp register, or an fp number is an integer register. (define_insn "*movsi_insn" - [(set (match_operand:SI 0 "reg_or_nonsymb_mem_operand" "=r,f,r,r,f,Q,Q") - (match_operand:SI 1 "move_operand" "rI,!f,K,Q,!Q,rJ,!f"))] + [(set (match_operand:SI 0 "reg_or_nonsymb_mem_operand" "=r,f,r,r,f,Q,Q,d") + (match_operand:SI 1 "move_operand" "rI,!f,K,Q,!Q,rJ,!f,J"))] "! TARGET_LIVE_G0 && (register_operand (operands[0], SImode) || register_operand (operands[1], SImode) - || operands[1] == const0_rtx)" + || operands[1] == const0_rtx) + && (GET_CODE (operands[0]) != REG || ! CONSTANT_P (operands[1]) + || REGNO (operands[0]) < 32 + || REGNO (operands[0]) >= FIRST_PSEUDO_REGISTER)" "@ mov %1,%0 fmovs %1,%0 @@ -1985,8 +2169,9 @@ ld %1,%0 ld %1,%0 st %r1,%0 - st %1,%0" - [(set_attr "type" "move,fp,move,load,fpload,store,fpstore") + st %1,%0 + fzeros %0" + [(set_attr "type" "move,fpmove,move,load,fpload,store,fpstore,fpmove") (set_attr "length" "1")]) (define_insn "*movsi_insn_liveg0" @@ -2005,7 +2190,7 @@ ld %1,%0 st %1,%0 st %1,%0" - [(set_attr "type" "move,move,move,fp,move,load,fpload,store,fpstore") + [(set_attr "type" "move,move,move,fpmove,move,load,fpload,store,fpstore") (set_attr "length" "1,1,2,1,1,1,1,1,1")]) (define_insn "*store_si" @@ -2028,10 +2213,68 @@ DONE; }") -(define_insn "*movdi_sp32_insn" +;; 32 bit V9 movdi is like regular 32 bit except: a 64 bit zero can be stored +;; to aligned memory with a single instruction, the ldd/std instructions +;; are not used, and constants can not be moved to floating point registers. + +(define_insn "*movdi_sp32_v9" + [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "=r,T,Q,r,r,?e,?e,?Q,?b") + (match_operand:DI 1 "general_operand" "r,J,r,Q,i,e,Q,e,J"))] + "TARGET_V9 && ! TARGET_ARCH64 + && (register_operand (operands[0], DImode) + || register_operand (operands[1], DImode) + || operands[1] == const0_rtx) + && (GET_CODE (operands[0]) != REG || ! CONSTANT_P (operands[1]) + || REGNO (operands[0]) < 32 + || REGNO (operands[0]) >= FIRST_PSEUDO_REGISTER)" + "* +{ + if (which_alternative == 1) + return \"stx %%g0,%0\"; + if (which_alternative == 8) + return \"fzero %0\"; + if (FP_REG_P (operands[0]) || FP_REG_P (operands[1])) + return output_fp_move_double (operands); + return output_move_double (operands); +}" + [(set_attr "type" "move,store,store,load,multi,fp,fpload,fpstore,fpmove") + (set_attr "length" "2,1,3,3,3,2,3,3,1")]) + +;; SPARC V9 deprecates std. Split it here. +(define_split + [(set (match_operand:DI 0 "memory_operand" "=m") + (match_operand:DI 1 "register_operand" "r"))] + "TARGET_V9 && ! TARGET_ARCH64 && reload_completed + && REGNO (operands[1]) < 32 && ! MEM_VOLATILE_P (operands[0]) + && offsettable_memref_p (operands[0])" + [(set (match_dup 2) (match_dup 3)) + (set (match_dup 4) (match_dup 5))] + "operands[3] = gen_highpart (SImode, operands[1]); + operands[5] = gen_lowpart (SImode, operands[1]); + operands[4] = adj_offsettable_operand (operands[0], 4); + PUT_MODE (operands[4], SImode); + operands[2] = copy_rtx (operands[0]); + PUT_MODE (operands[2], SImode);") + +;; Split register to register moves. +(define_split + [(set (match_operand:DI 0 "register_operand" "=r") + (match_operand:DI 1 "arith_double_operand" "rIN"))] + "! TARGET_ARCH64 + && REGNO (operands[0]) < 32 + && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < 32 + && ! reg_overlap_mentioned_p (operands[0], operands[1])" + [(set (match_dup 2) (match_dup 4)) + (set (match_dup 3) (match_dup 5))] + "operands[2] = gen_highpart (SImode, operands[0]); + operands[3] = gen_lowpart (SImode, operands[0]); + operands[4] = gen_highpart (SImode, operands[1]); + operands[5] = gen_lowpart (SImode, operands[1]);") + +(define_insn "*movdi_sp32" [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "=r,T,U,Q,r,r,?f,?f,?Q") (match_operand:DI 1 "general_operand" "r,U,T,r,Q,i,f,Q,f"))] - "! TARGET_ARCH64 + "! TARGET_V9 && (register_operand (operands[0], DImode) || register_operand (operands[1], DImode) || operands[1] == const0_rtx)" @@ -2053,8 +2296,8 @@ ;;; This needs the original value of operands[1], not the inverted value. (define_insn "*movdi_sp64_insn" - [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,Q,?f,?f,?Q") - (match_operand:DI 1 "move_operand" "rI,K,Q,rJ,f,Q,f"))] + [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,Q,?e,?e,?Q") + (match_operand:DI 1 "move_operand" "rI,K,Q,rJ,e,Q,e"))] "TARGET_ARCH64 && (register_operand (operands[0], DImode) || register_operand (operands[1], DImode) @@ -2087,11 +2330,13 @@ case 3: return \"stx %r1,%0\"; case 4: - return \"mov %1,%0\"; + return \"fmovd %1,%0\"; case 5: return \"ldd %1,%0\"; case 6: return \"std %1,%0\"; + default: + abort (); } }" [(set_attr "type" "move,move,load,store,fp,fpload,fpstore") @@ -2100,78 +2345,36 @@ ;; ??? There's no symbolic (set (mem:DI ...) ...). ;; Experimentation with v9 suggested one isn't needed. -;; Block move insns. - -;; ??? We get better code without it. See output_block_move in sparc.c. - -;; The definition of this insn does not really explain what it does, -;; but it should suffice -;; that anything generated as this insn will be recognized as one -;; and that it will not successfully combine with anything. -;(define_expand "movstrsi" -; [(parallel [(set (mem:BLK (match_operand:BLK 0 "general_operand" "")) -; (mem:BLK (match_operand:BLK 1 "general_operand" ""))) -; (use (match_operand:SI 2 "nonmemory_operand" "")) -; (use (match_operand:SI 3 "immediate_operand" "")) -; (clobber (match_dup 0)) -; (clobber (match_dup 1)) -; (clobber (match_scratch:SI 4 "")) -; (clobber (reg:SI 100)) -; (clobber (reg:SI 1))])] -; "" -; " -;{ -; /* If the size isn't known, don't emit inline code. output_block_move -; would output code that's much slower than the library function. -; Also don't output code for large blocks. */ -; if (GET_CODE (operands[2]) != CONST_INT -; || GET_CODE (operands[3]) != CONST_INT -; || INTVAL (operands[2]) / INTVAL (operands[3]) > 16) -; FAIL; -; -; operands[0] = copy_to_mode_reg (Pmode, XEXP (operands[0], 0)); -; operands[1] = copy_to_mode_reg (Pmode, XEXP (operands[1], 0)); -; operands[2] = force_not_mem (operands[2]); -;}") - -;(define_insn "*block_move_insn" -; [(set (mem:BLK (match_operand:SI 0 "register_operand" "+r")) -; (mem:BLK (match_operand:SI 1 "register_operand" "+r"))) -; (use (match_operand:SI 2 "nonmemory_operand" "rn")) -; (use (match_operand:SI 3 "immediate_operand" "i")) -; (clobber (match_dup 0)) -; (clobber (match_dup 1)) -; (clobber (match_scratch:SI 4 "=&r")) -; (clobber (reg:SI 100)) -; (clobber (reg:SI 1))] -; "" -; "* return output_block_move (operands);" -; [(set_attr "type" "multi") -; (set_attr "length" "6")]) - ;; Floating point move insns ;; This pattern forces (set (reg:SF ...) (const_double ...)) ;; to be reloaded by putting the constant into memory. ;; It must come before the more general movsf pattern. (define_insn "*movsf_const_insn" - [(set (match_operand:SF 0 "general_operand" "=?r,f,m") - (match_operand:SF 1 "" "?F,m,G"))] - "TARGET_FPU && GET_CODE (operands[1]) == CONST_DOUBLE" + [(set (match_operand:SF 0 "general_operand" "=f,d,m,?r") + (match_operand:SF 1 "" "m,G,G,?F"))] + "TARGET_FPU + && GET_CODE (operands[1]) == CONST_DOUBLE + && (GET_CODE (operands[0]) == REG + || fp_zero_operand (operands[1]))" "* { switch (which_alternative) { case 0: - return singlemove_string (operands); - case 1: return \"ld %1,%0\"; + case 1: + return \"fzeros %0\"; case 2: return \"st %%g0,%0\"; + case 3: + return singlemove_string (operands); + default: + abort (); } }" - [(set_attr "type" "load,fpload,store") - (set_attr "length" "2,1,1")]) + [(set_attr "type" "fpload,fpmove,store,load") + (set_attr "length" "1,1,1,2")]) (define_expand "movsf" [(set (match_operand:SF 0 "general_operand" "") @@ -2184,19 +2387,19 @@ }") (define_insn "*movsf_insn" - [(set (match_operand:SF 0 "reg_or_nonsymb_mem_operand" "=f,r,f,r,Q,Q") - (match_operand:SF 1 "reg_or_nonsymb_mem_operand" "f,r,Q,Q,f,r"))] + [(set (match_operand:SF 0 "reg_or_nonsymb_mem_operand" "=f,f,Q,r,r,Q") + (match_operand:SF 1 "reg_or_nonsymb_mem_operand" "f,Q,f,r,Q,r"))] "TARGET_FPU && (register_operand (operands[0], SFmode) || register_operand (operands[1], SFmode))" "@ fmovs %1,%0 - mov %1,%0 - ld %1,%0 ld %1,%0 st %1,%0 + mov %1,%0 + ld %1,%0 st %1,%0" - [(set_attr "type" "fp,move,fpload,load,fpstore,store")]) + [(set_attr "type" "fpmove,fpload,fpstore,move,load,store")]) ;; Exactly the same as above, except that all `f' cases are deleted. ;; This is necessary to prevent reload from ever trying to use a `f' reg @@ -2229,9 +2432,12 @@ ;; It must come before the more general movdf pattern. (define_insn "*movdf_const_insn" - [(set (match_operand:DF 0 "general_operand" "=?r,e,o") - (match_operand:DF 1 "" "?F,m,G"))] - "TARGET_FPU && GET_CODE (operands[1]) == CONST_DOUBLE" + [(set (match_operand:DF 0 "general_operand" "=?r,e,o,d") + (match_operand:DF 1 "" "?F,m,G,G"))] + "TARGET_FPU + && GET_CODE (operands[1]) == CONST_DOUBLE + && (GET_CODE (operands[0]) == REG + || fp_zero_operand (operands[1]))" "* { switch (which_alternative) @@ -2241,7 +2447,7 @@ case 1: return output_fp_move_double (operands); case 2: - if (TARGET_ARCH64) + if (TARGET_ARCH64 || (TARGET_V9 && mem_aligned_8 (operands[0]))) { return \"stx %%g0,%0\"; } @@ -2250,10 +2456,14 @@ operands[1] = adj_offsettable_operand (operands[0], 4); return \"st %%g0,%0\;st %%g0,%1\"; } + case 3: + return \"fzero %0\"; + default: + abort (); } }" - [(set_attr "type" "load,fpload,store") - (set_attr "length" "3,3,3")]) + [(set_attr "type" "load,fpload,store,fpmove") + (set_attr "length" "3,3,3,1")]) (define_expand "movdf" [(set (match_operand:DF 0 "general_operand" "") @@ -2266,8 +2476,8 @@ }") (define_insn "*movdf_insn" - [(set (match_operand:DF 0 "reg_or_nonsymb_mem_operand" "=T,U,e,r,Q,Q,e,r") - (match_operand:DF 1 "reg_or_nonsymb_mem_operand" "U,T,e,r,e,r,Q,Q"))] + [(set (match_operand:DF 0 "reg_or_nonsymb_mem_operand" "=e,Q,e,T,U,r,Q,r") + (match_operand:DF 1 "reg_or_nonsymb_mem_operand" "e,e,Q,U,T,r,r,Q"))] "TARGET_FPU && (register_operand (operands[0], DFmode) || register_operand (operands[1], DFmode))" @@ -2286,7 +2496,7 @@ (define_insn "*movdf_no_e_insn" [(set (match_operand:DF 0 "reg_or_nonsymb_mem_operand" "=T,U,r,Q,&r") - (match_operand:DF 1 "reg_or_nonsymb_mem_operand" "U,T,r,r,Q"))] + (match_operand:DF 1 "reg_or_nonsymb_mem_operand" "U,T,r,r,Q"))] "! TARGET_FPU && (register_operand (operands[0], DFmode) || register_operand (operands[1], DFmode))" @@ -2349,7 +2559,10 @@ (define_insn "*movtf_const_insn" [(set (match_operand:TF 0 "general_operand" "=?r,e,o") (match_operand:TF 1 "" "?F,m,G"))] - "TARGET_FPU && GET_CODE (operands[1]) == CONST_DOUBLE" + "TARGET_FPU + && GET_CODE (operands[1]) == CONST_DOUBLE + && (GET_CODE (operands[0]) == REG + || fp_zero_operand (operands[1]))" "* { switch (which_alternative) @@ -2359,7 +2572,7 @@ case 1: return output_fp_move_quad (operands); case 2: - if (TARGET_ARCH64) + if (TARGET_ARCH64 || (TARGET_V9 && mem_aligned_8 (operands[0]))) { operands[1] = adj_offsettable_operand (operands[0], 8); return \"stx %%g0,%0\;stx %%g0,%1\"; @@ -2372,6 +2585,8 @@ operands[3] = adj_offsettable_operand (operands[0], 12); return \"st %%g0,%0\;st %%g0,%1\;st %%g0,%2\;st %%g0,%3\"; } + default: + abort (); } }" [(set_attr "type" "load,fpload,store") @@ -2388,8 +2603,8 @@ }") (define_insn "*movtf_insn" - [(set (match_operand:TF 0 "reg_or_nonsymb_mem_operand" "=e,r,Q,Q,e,&r") - (match_operand:TF 1 "reg_or_nonsymb_mem_operand" "e,r,e,r,Q,Q"))] + [(set (match_operand:TF 0 "reg_or_nonsymb_mem_operand" "=e,Q,e,r,Q,r") + (match_operand:TF 1 "reg_or_nonsymb_mem_operand" "e,e,Q,r,r,Q"))] "TARGET_FPU && (register_operand (operands[0], TFmode) || register_operand (operands[1], TFmode))" @@ -2468,14 +2683,14 @@ && GET_MODE (sparc_compare_op0) == DImode && v9_regcmp_p (code)) { - operands[1] = gen_rtx (code, DImode, + operands[1] = gen_rtx_fmt_ee (code, DImode, sparc_compare_op0, sparc_compare_op1); } else { rtx cc_reg = gen_compare_reg (code, sparc_compare_op0, sparc_compare_op1); - operands[1] = gen_rtx (code, GET_MODE (cc_reg), cc_reg, const0_rtx); + operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx); } }") @@ -2498,14 +2713,14 @@ && GET_MODE (sparc_compare_op0) == DImode && v9_regcmp_p (code)) { - operands[1] = gen_rtx (code, DImode, + operands[1] = gen_rtx_fmt_ee (code, DImode, sparc_compare_op0, sparc_compare_op1); } else { rtx cc_reg = gen_compare_reg (code, sparc_compare_op0, sparc_compare_op1); - operands[1] = gen_rtx (code, GET_MODE (cc_reg), cc_reg, const0_rtx); + operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx); } }") @@ -2518,24 +2733,22 @@ " { enum rtx_code code = GET_CODE (operands[1]); - - if (GET_MODE (sparc_compare_op0) == DImode - && ! TARGET_ARCH64) - FAIL; + enum machine_mode op0_mode = GET_MODE (sparc_compare_op0); if (sparc_compare_op1 == const0_rtx && GET_CODE (sparc_compare_op0) == REG - && GET_MODE (sparc_compare_op0) == DImode - && v9_regcmp_p (code)) + && ((TARGET_ARCH64 && op0_mode == DImode && v9_regcmp_p (code)) + || (op0_mode == SImode && v8plus_regcmp_p (code)))) { - operands[1] = gen_rtx (code, DImode, + operands[1] = gen_rtx_fmt_ee (code, op0_mode, sparc_compare_op0, sparc_compare_op1); } else { rtx cc_reg = gen_compare_reg (code, sparc_compare_op0, sparc_compare_op1); - operands[1] = gen_rtx (code, GET_MODE (cc_reg), cc_reg, const0_rtx); + operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), + cc_reg, const0_rtx); } }") @@ -2554,14 +2767,15 @@ && GET_MODE (sparc_compare_op0) == DImode && v9_regcmp_p (code)) { - operands[1] = gen_rtx (code, DImode, + operands[1] = gen_rtx_fmt_ee (code, DImode, sparc_compare_op0, sparc_compare_op1); } else { rtx cc_reg = gen_compare_reg (code, sparc_compare_op0, sparc_compare_op1); - operands[1] = gen_rtx (code, GET_MODE (cc_reg), cc_reg, const0_rtx); + operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), + cc_reg, const0_rtx); } }") @@ -2584,14 +2798,14 @@ && GET_MODE (sparc_compare_op0) == DImode && v9_regcmp_p (code)) { - operands[1] = gen_rtx (code, DImode, + operands[1] = gen_rtx_fmt_ee (code, DImode, sparc_compare_op0, sparc_compare_op1); } else { rtx cc_reg = gen_compare_reg (code, sparc_compare_op0, sparc_compare_op1); - operands[1] = gen_rtx (code, GET_MODE (cc_reg), cc_reg, const0_rtx); + operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx); } }") @@ -2614,14 +2828,14 @@ && GET_MODE (sparc_compare_op0) == DImode && v9_regcmp_p (code)) { - operands[1] = gen_rtx (code, DImode, + operands[1] = gen_rtx_fmt_ee (code, DImode, sparc_compare_op0, sparc_compare_op1); } else { rtx cc_reg = gen_compare_reg (code, sparc_compare_op0, sparc_compare_op1); - operands[1] = gen_rtx (code, GET_MODE (cc_reg), cc_reg, const0_rtx); + operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx); } }") @@ -2644,14 +2858,14 @@ && GET_MODE (sparc_compare_op0) == DImode && v9_regcmp_p (code)) { - operands[1] = gen_rtx (code, DImode, + operands[1] = gen_rtx_fmt_ee (code, DImode, sparc_compare_op0, sparc_compare_op1); } else { rtx cc_reg = gen_compare_reg (code, sparc_compare_op0, sparc_compare_op1); - operands[1] = gen_rtx (code, GET_MODE (cc_reg), cc_reg, const0_rtx); + operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx); } }") @@ -2721,7 +2935,7 @@ "@ fmovs%C1 %x2,%3,%0 fmovs%c1 %x2,%4,%0" - [(set_attr "type" "cmove")]) + [(set_attr "type" "fpcmove")]) (define_insn "*movdf_cc_sp64" [(set (match_operand:DF 0 "register_operand" "=e,e") @@ -2734,7 +2948,7 @@ "@ fmovd%C1 %x2,%3,%0 fmovd%c1 %x2,%4,%0" - [(set_attr "type" "cmove")]) + [(set_attr "type" "fpcmove")]) (define_insn "*movtf_cc_sp64" [(set (match_operand:TF 0 "register_operand" "=e,e") @@ -2747,7 +2961,7 @@ "@ fmovq%C1 %x2,%3,%0 fmovq%c1 %x2,%4,%0" - [(set_attr "type" "cmove")]) + [(set_attr "type" "fpcmove")]) (define_insn "*movqi_cc_reg_sp64" [(set (match_operand:QI 0 "register_operand" "=r,r") @@ -2788,6 +3002,57 @@ movr%d1 %2,%r4,%0" [(set_attr "type" "cmove")]) +;; On UltraSPARC this is slightly worse than cmp/mov %icc if the register +;; needs to be zero extended but better on average. +(define_insn "*movsi_cc_reg_v8plus" + [(set (match_operand:SI 0 "register_operand" "=r,r") + (if_then_else:SI (match_operator 1 "v8plus_regcmp_op" + [(match_operand:SI 2 "register_operand" "r,r") + (const_int 0)]) + (match_operand:SI 3 "arith10_operand" "rM,0") + (match_operand:SI 4 "arith10_operand" "0,rM")))] + "TARGET_V9" + "* +{ + if (! sparc_check_64 (operands[2], insn)) + output_asm_insn (\"srl %2,0,%2\", operands); + if (which_alternative == 0) + return \"movr%D1 %2,%r3,%0\"; + return \"movr%d1 %2,%r4,%0\"; +}" + [(set_attr "type" "cmove") + (set_attr "length" "2")]) + +;; To work well this needs to know the current insn, but that is not an +;; argument to gen_split_*. + +(define_split + [(set (match_operand:SI 0 "register_operand" "=r,r") + (if_then_else:SI (match_operator 1 "v8plus_regcmp_op" + [(match_operand:SI 2 "register_operand" "r,r") + (const_int 0)]) + (match_operand:SI 3 "arith10_operand" "rM,0") + (match_operand:SI 4 "arith10_operand" "0,rM")))] + "reload_completed" + [(set (match_dup 0) + (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 4)] 9))] + "if (! sparc_check_64 (operands[2], NULL_RTX)) + emit_insn (gen_v8plus_clear_high (operands[2], operands[2]));") + +;; A conditional move with the condition argument known to be zero extended +(define_insn "" + [(set (match_operand:SI 0 "register_operand" "=r,r") + (unspec:SI [(match_operator 1 "v8plus_regcmp_op" + [(match_operand:SI 2 "register_operand" "r,r") + (const_int 0)]) + (match_operand:SI 3 "arith10_operand" "rM,0") + (match_operand:SI 4 "arith10_operand" "0,rM")] 9))] + "TARGET_V9" + "@ + movr%D1 %2,%r3,%0 + movr%d1 %2,%r4,%0" + [(set_attr "type" "cmove")]) + ;; ??? The constraints of operands 3,4 need work. (define_insn "*movdi_cc_reg_sp64" [(set (match_operand:DI 0 "register_operand" "=r,r") @@ -2813,7 +3078,7 @@ "@ fmovrs%D1 %2,%3,%0 fmovrs%d1 %2,%4,%0" - [(set_attr "type" "cmove")]) + [(set_attr "type" "fpcmove")]) (define_insn "*movdf_cc_reg_sp64" [(set (match_operand:DF 0 "register_operand" "=e,e") @@ -2826,7 +3091,7 @@ "@ fmovrd%D1 %2,%3,%0 fmovrd%d1 %2,%4,%0" - [(set_attr "type" "cmove")]) + [(set_attr "type" "fpcmove")]) (define_insn "*movtf_cc_reg_sp64" [(set (match_operand:TF 0 "register_operand" "=e,e") @@ -2839,7 +3104,7 @@ "@ fmovrq%D1 %2,%3,%0 fmovrq%d1 %2,%4,%0" - [(set_attr "type" "cmove")]) + [(set_attr "type" "fpcmove")]) ;;- zero extension instructions @@ -2863,7 +3128,7 @@ operand1 = XEXP (operand1, 0); } - emit_insn (gen_ashlsi3 (temp, gen_rtx (SUBREG, SImode, operand1, + emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subword), shift_16)); emit_insn (gen_lshrsi3 (operand0, temp, shift_16)); @@ -2941,8 +3206,8 @@ operand1 = XEXP (operand1, 0); } - emit_insn (gen_ashldi3 (temp, gen_rtx (SUBREG, DImode, operand1, - op1_subword), + emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, + op1_subword), shift_48)); emit_insn (gen_lshrdi3 (operand0, temp, shift_48)); DONE; @@ -2955,6 +3220,7 @@ "lduh %1,%0" [(set_attr "type" "load")]) + ;; ??? Write truncdisi pattern using sra? (define_expand "zero_extendsidi2" @@ -2973,6 +3239,20 @@ [(set_attr "type" "unary,load") (set_attr "length" "1")]) +;; Zero extend a 32 bit value in a 64 bit register. +(define_insn "v8plus_clear_high" + [(set (match_operand:SI 0 "reg_or_nonsymb_mem_operand" "=r,Q") + (unspec:SI [(match_operand:SI 1 "register_operand" "r,r")] 10))] + "TARGET_V9" + "* +if (which_alternative == 1) + return \"st %1,%0\"; +if (sparc_check_64 (operands[1], insn) > 0) + return final_sequence ? \"nop\" : \"\"; +return \"srl %1,0,%0\"; +" + [(set_attr "type" "shift,store")]) + ;; Simplify comparisons of extended values. (define_insn "*cmp_zero_extendqisi2" @@ -3035,8 +3315,8 @@ operand1 = XEXP (operand1, 0); } - emit_insn (gen_ashlsi3 (temp, gen_rtx (SUBREG, SImode, operand1, - op1_subword), + emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, + op1_subword), shift_16)); emit_insn (gen_ashrsi3 (operand0, temp, shift_16)); DONE; @@ -3047,7 +3327,7 @@ (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))] "" "ldsh %1,%0" - [(set_attr "type" "load")]) + [(set_attr "type" "sload")]) (define_expand "extendqihi2" [(set (match_operand:HI 0 "register_operand" "") @@ -3070,11 +3350,11 @@ op0_subword = SUBREG_WORD (operand0); operand0 = XEXP (operand0, 0); } - emit_insn (gen_ashlsi3 (temp, gen_rtx (SUBREG, SImode, operand1, - op1_subword), + emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, + op1_subword), shift_24)); if (GET_MODE (operand0) != SImode) - operand0 = gen_rtx (SUBREG, SImode, operand0, op0_subword); + operand0 = gen_rtx_SUBREG (SImode, operand0, op0_subword); emit_insn (gen_ashrsi3 (operand0, temp, shift_24)); DONE; }") @@ -3084,7 +3364,7 @@ (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))] "" "ldsb %1,%0" - [(set_attr "type" "load")]) + [(set_attr "type" "sload")]) (define_expand "extendqisi2" [(set (match_operand:SI 0 "register_operand" "") @@ -3102,8 +3382,8 @@ operand1 = XEXP (operand1, 0); } - emit_insn (gen_ashlsi3 (temp, gen_rtx (SUBREG, SImode, operand1, - op1_subword), + emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, + op1_subword), shift_24)); emit_insn (gen_ashrsi3 (operand0, temp, shift_24)); DONE; @@ -3114,7 +3394,7 @@ (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))] "" "ldsb %1,%0" - [(set_attr "type" "load")]) + [(set_attr "type" "sload")]) (define_expand "extendqidi2" [(set (match_operand:DI 0 "register_operand" "") @@ -3132,8 +3412,8 @@ operand1 = XEXP (operand1, 0); } - emit_insn (gen_ashldi3 (temp, gen_rtx (SUBREG, DImode, operand1, - op1_subword), + emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, + op1_subword), shift_56)); emit_insn (gen_ashrdi3 (operand0, temp, shift_56)); DONE; @@ -3144,7 +3424,7 @@ (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))] "TARGET_ARCH64" "ldsb %1,%0" - [(set_attr "type" "load")]) + [(set_attr "type" "sload")]) (define_expand "extendhidi2" [(set (match_operand:DI 0 "register_operand" "") @@ -3162,8 +3442,8 @@ operand1 = XEXP (operand1, 0); } - emit_insn (gen_ashldi3 (temp, gen_rtx (SUBREG, DImode, operand1, - op1_subword), + emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, + op1_subword), shift_48)); emit_insn (gen_ashrdi3 (operand0, temp, shift_48)); DONE; @@ -3189,7 +3469,7 @@ "@ sra %1,0,%0 ldsw %1,%0" - [(set_attr "type" "unary,load") + [(set_attr "type" "unary,sload") (set_attr "length" "1")]) ;; Special pattern for optimizing bit-field compares. This is needed @@ -3305,115 +3585,25 @@ [(set_attr "type" "fp")]) ;; Now the same for 64 bit sources. -;; ??? We cannot put DImode values in fp regs (see below near fix_truncdfsi2). -(define_expand "floatdisf2" - [(parallel [(set (match_operand:SF 0 "register_operand" "") - (float:SF (match_operand:DI 1 "general_operand" ""))) - (clobber (match_dup 2)) - (clobber (match_dup 3))])] - "TARGET_ARCH64 && TARGET_FPU" - " -{ - operands[2] = gen_reg_rtx (DFmode); - operands[3] = sparc64_fpconv_stack_temp (); -}") - -(define_expand "floatdidf2" - [(parallel [(set (match_operand:DF 0 "register_operand" "") - (float:DF (match_operand:DI 1 "general_operand" ""))) - (clobber (match_dup 2)) - (clobber (match_dup 3))])] - "TARGET_ARCH64 && TARGET_FPU" - " -{ - operands[2] = gen_reg_rtx (DFmode); - operands[3] = sparc64_fpconv_stack_temp (); -}") - -(define_expand "floatditf2" - [(parallel [(set (match_operand:TF 0 "register_operand" "") - (float:TF (match_operand:DI 1 "general_operand" ""))) - (clobber (match_dup 2)) - (clobber (match_dup 3))])] - "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD" - " -{ - operands[2] = gen_reg_rtx (DFmode); - operands[3] = sparc64_fpconv_stack_temp (); -}") - -(define_insn "*floatdisf2_insn" - [(parallel [(set (match_operand:SF 0 "register_operand" "=f") - (float:SF (match_operand:DI 1 "general_operand" "rm"))) - (clobber (match_operand:DF 2 "register_operand" "=&e")) - (clobber (match_operand:DI 3 "memory_operand" "m"))])] - "TARGET_ARCH64 && TARGET_FPU" - "* -{ - if (GET_CODE (operands[1]) == MEM) - output_asm_insn (\"ldd %1,%2\", operands); - else - output_asm_insn (\"stx %1,%3\;ldd %3,%2\", operands); - return \"fxtos %2,%0\"; -}" - [(set_attr "type" "fp") - (set_attr "length" "3")]) - -(define_insn "*floatdidf2_insn" - [(parallel [(set (match_operand:DF 0 "register_operand" "=e") - (float:DF (match_operand:DI 1 "general_operand" "rm"))) - (clobber (match_operand:DF 2 "register_operand" "=&e")) - (clobber (match_operand:DI 3 "memory_operand" "m"))])] - "TARGET_ARCH64 && TARGET_FPU" - "* -{ - if (GET_CODE (operands[1]) == MEM) - output_asm_insn (\"ldd %1,%2\", operands); - else - output_asm_insn (\"stx %1,%3\;ldd %3,%2\", operands); - return \"fxtod %2,%0\"; -}" - [(set_attr "type" "fp") - (set_attr "length" "3")]) - -(define_insn "*floatditf2_insn" - [(parallel [(set (match_operand:TF 0 "register_operand" "=e") - (float:TF (match_operand:DI 1 "general_operand" "rm"))) - (clobber (match_operand:DF 2 "register_operand" "=&e")) - (clobber (match_operand:DI 3 "memory_operand" "m"))])] - "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD" - "* -{ - if (GET_CODE (operands[1]) == MEM) - output_asm_insn (\"ldd %1,%2\", operands); - else - output_asm_insn (\"stx %1,%3\;ldd %3,%2\", operands); - return \"fxtoq %2,%0\"; -}" - [(set_attr "type" "fp") - (set_attr "length" "3")]) - -;; ??? Ideally, these are what we would like to use. - -(define_insn "floatdisf2_sp64" +(define_insn "floatdisf2" [(set (match_operand:SF 0 "register_operand" "=f") (float:SF (match_operand:DI 1 "register_operand" "e")))] - "0 && TARGET_ARCH64 && TARGET_FPU" + "TARGET_V9 && TARGET_FPU" "fxtos %1,%0" [(set_attr "type" "fp")]) -(define_insn "floatdidf2_sp64" +(define_insn "floatdidf2" [(set (match_operand:DF 0 "register_operand" "=e") (float:DF (match_operand:DI 1 "register_operand" "e")))] - "0 && TARGET_ARCH64 && TARGET_FPU" + "TARGET_V9 && TARGET_FPU" "fxtod %1,%0" [(set_attr "type" "fp")]) -(define_insn "floatditf2_sp64" +(define_insn "floatditf2" [(set (match_operand:TF 0 "register_operand" "=e") (float:TF (match_operand:DI 1 "register_operand" "e")))] - "0 && TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD" + "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD" "fxtoq %1,%0" [(set_attr "type" "fp")]) @@ -3441,121 +3631,26 @@ "fqtoi %1,%0" [(set_attr "type" "fp")]) -;; Now the same, for 64-bit targets -;; ??? We try to work around an interesting problem. -;; If gcc tries to do a subreg on the result it will get the wrong answer: -;; "(subreg:SI (reg:DI M int-reg) 0)" is the same as -;; "(subreg:SI (reg:DI N float-reg) 1)", but gcc does not know how to change -;; the "0" to a "1". One could enhance alter_subreg but it is not clear how to -;; do this cleanly. +;; Now the same, for V9 targets -(define_expand "fix_truncsfdi2" - [(parallel [(set (match_operand:DI 0 "general_operand" "") - (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "")))) - (clobber (match_dup 2)) - (clobber (match_dup 3))])] - "TARGET_ARCH64 && TARGET_FPU" - " -{ - operands[2] = gen_reg_rtx (DFmode); - operands[3] = sparc64_fpconv_stack_temp (); -}") - -(define_expand "fix_truncdfdi2" - [(parallel [(set (match_operand:DI 0 "general_operand" "") - (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "")))) - (clobber (match_dup 2)) - (clobber (match_dup 3))])] - "TARGET_ARCH64 && TARGET_FPU" - " -{ - operands[2] = gen_reg_rtx (DFmode); - operands[3] = sparc64_fpconv_stack_temp (); -}") - -(define_expand "fix_trunctfdi2" - [(parallel [(set (match_operand:DI 0 "general_operand" "") - (fix:DI (fix:TF (match_operand:TF 1 "register_operand" "")))) - (clobber (match_dup 2)) - (clobber (match_dup 3))])] - "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD" - " -{ - operands[2] = gen_reg_rtx (DFmode); - operands[3] = sparc64_fpconv_stack_temp (); -}") - -(define_insn "*fix_truncsfdi2_insn" - [(parallel [(set (match_operand:DI 0 "general_operand" "=rm") - (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f")))) - (clobber (match_operand:DF 2 "register_operand" "=&e")) - (clobber (match_operand:DI 3 "memory_operand" "m"))])] - "TARGET_ARCH64 && TARGET_FPU" - "* -{ - output_asm_insn (\"fstox %1,%2\", operands); - if (GET_CODE (operands[0]) == MEM) - return \"std %2,%0\"; - else - return \"std %2,%3\;ldx %3,%0\"; -}" - [(set_attr "type" "fp") - (set_attr "length" "3")]) - -(define_insn "*fix_truncdfdi2_insn" - [(parallel [(set (match_operand:DI 0 "general_operand" "=rm") - (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e")))) - (clobber (match_operand:DF 2 "register_operand" "=&e")) - (clobber (match_operand:DI 3 "memory_operand" "m"))])] - "TARGET_ARCH64 && TARGET_FPU" - "* -{ - output_asm_insn (\"fdtox %1,%2\", operands); - if (GET_CODE (operands[0]) == MEM) - return \"std %2,%0\"; - else - return \"std %2,%3\;ldx %3,%0\"; -}" - [(set_attr "type" "fp") - (set_attr "length" "3")]) - -(define_insn "*fix_trunctfdi2_insn" - [(parallel [(set (match_operand:DI 0 "general_operand" "=rm") - (fix:DI (fix:TF (match_operand:TF 1 "register_operand" "e")))) - (clobber (match_operand:DF 2 "register_operand" "=&e")) - (clobber (match_operand:DI 3 "memory_operand" "m"))])] - "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD" - "* -{ - output_asm_insn (\"fqtox %1,%2\", operands); - if (GET_CODE (operands[0]) == MEM) - return \"std %2,%0\"; - else - return \"std %2,%3\;ldx %3,%0\"; -}" - [(set_attr "type" "fp") - (set_attr "length" "3")]) - -;; ??? Ideally, these are what we would like to use. - -(define_insn "fix_truncsfdi2_sp64" +(define_insn "fix_truncsfdi2" [(set (match_operand:DI 0 "register_operand" "=e") (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))] - "0 && TARGET_ARCH64 && TARGET_FPU" + "TARGET_V9 && TARGET_FPU" "fstox %1,%0" [(set_attr "type" "fp")]) -(define_insn "fix_truncdfdi2_sp64" +(define_insn "fix_truncdfdi2" [(set (match_operand:DI 0 "register_operand" "=e") (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))] - "0 && TARGET_ARCH64 && TARGET_FPU" + "TARGET_V9 && TARGET_FPU" "fdtox %1,%0" [(set_attr "type" "fp")]) -(define_insn "fix_trunctfdi2_sp64" +(define_insn "fix_trunctfdi2" [(set (match_operand:DI 0 "register_operand" "=e") (fix:DI (fix:TF (match_operand:TF 1 "register_operand" "e"))))] - "0 && TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD" + "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD" "fqtox %1,%0" [(set_attr "type" "fp")]) @@ -3570,12 +3665,12 @@ { if (! TARGET_ARCH64) { - emit_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (2, - gen_rtx (SET, VOIDmode, operands[0], - gen_rtx (PLUS, DImode, operands[1], - operands[2])), - gen_rtx (CLOBBER, VOIDmode, - gen_rtx (REG, SImode, SPARC_ICC_REG))))); + emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, + gen_rtx_SET (VOIDmode, operands[0], + gen_rtx_PLUS (DImode, operands[1], + operands[2])), + gen_rtx_CLOBBER (VOIDmode, + gen_rtx_REG (CCmode, SPARC_ICC_REG))))); DONE; } }") @@ -3584,7 +3679,7 @@ [(set (match_operand:DI 0 "register_operand" "=r") (plus:DI (match_operand:DI 1 "arith_double_operand" "%r") (match_operand:DI 2 "arith_double_operand" "rHI"))) - (clobber (reg:SI 100))] + (clobber (reg:CC 100))] "! TARGET_ARCH64" "* { @@ -3610,6 +3705,105 @@ }" [(set_attr "length" "2")]) + +;; Split DImode arithmetic + +(define_split + [(set (match_operand:DI 0 "register_operand" "=r") + (plus:DI (match_operand:DI 1 "arith_double_operand" "%r") + (match_operand:DI 2 "arith_double_operand" "rHI"))) + (clobber (reg:CC 100))] + "! TARGET_ARCH64 && reload_completed" + [(parallel [(set (reg:CC_NOOV 100) + (compare:CC_NOOV (plus:SI (match_dup 4) + (match_dup 5)) + (const_int 0))) + (set (match_dup 3) + (plus:SI (match_dup 4) (match_dup 5)))]) + (set (match_dup 6) + (plus:SI (plus:SI (match_dup 7) + (match_dup 8)) + (ltu:SI (reg:CC_NOOV 100) (const_int 0))))] + " +{ + operands[3] = gen_lowpart (SImode, operands[0]); + operands[4] = gen_lowpart (SImode, operands[1]); + operands[5] = gen_lowpart (SImode, operands[2]); + operands[6] = gen_highpart (SImode, operands[0]); + operands[7] = gen_highpart (SImode, operands[1]); + if (GET_CODE (operands[2]) == CONST_INT) + { + if (INTVAL (operands[2]) < 0) + operands[8] = constm1_rtx; + else + operands[8] = const0_rtx; + } + else + operands[8] = gen_highpart (SImode, operands[2]); +}") + +(define_split + [(set (match_operand:DI 0 "register_operand" "=r") + (minus:DI (match_operand:DI 1 "arith_double_operand" "r") + (match_operand:DI 2 "arith_double_operand" "rHI"))) + (clobber (reg:CC 100))] + "! TARGET_ARCH64 && reload_completed" + [(parallel [(set (reg:CC_NOOV 100) + (compare:CC_NOOV (minus:SI (match_dup 4) + (match_dup 5)) + (const_int 0))) + (set (match_dup 3) + (minus:SI (match_dup 4) (match_dup 5)))]) + (set (match_dup 6) + (minus:SI (minus:SI (match_dup 7) + (match_dup 8)) + (ltu:SI (reg:CC_NOOV 100) (const_int 0))))] + " +{ + operands[3] = gen_lowpart (SImode, operands[0]); + operands[4] = gen_lowpart (SImode, operands[1]); + operands[5] = gen_lowpart (SImode, operands[2]); + operands[6] = gen_highpart (SImode, operands[0]); + operands[7] = gen_highpart (SImode, operands[1]); + if (GET_CODE (operands[2]) == CONST_INT) + { + if (INTVAL (operands[2]) < 0) + operands[8] = constm1_rtx; + else + operands[8] = const0_rtx; + } + else + operands[8] = gen_highpart (SImode, operands[2]); +}") + +;; LTU here means "carry set" +(define_insn "*addx" + [(set (match_operand:SI 0 "register_operand" "=r") + (plus:SI (plus:SI (match_operand:SI 1 "arith_operand" "%r") + (match_operand:SI 2 "arith_operand" "rI")) + (ltu:SI (reg:CC_NOOV 100) (const_int 0))))] + "" + "addx %1,%2,%0" + [(set_attr "type" "unary")]) + +(define_insn "*subx" + [(set (match_operand:SI 0 "register_operand" "=r") + (minus:SI (minus:SI (match_operand:SI 1 "register_operand" "r") + (match_operand:SI 2 "arith_operand" "rI")) + (ltu:SI (reg:CC_NOOV 100) (const_int 0))))] + "" + "subx %1,%2,%0" + [(set_attr "type" "unary")]) + +(define_insn "" + [(set (match_operand:DI 0 "register_operand" "=r") + (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r")) + (match_operand:DI 2 "register_operand" "r"))) + (clobber (reg:CC 100))] + "! TARGET_ARCH64" + "addcc %L2,%1,%L0\;addx %H2,0,%H0" + [(set_attr "type" "multi")]) + (define_insn "*adddi3_sp64" [(set (match_operand:DI 0 "register_operand" "=r") (plus:DI (match_operand:DI 1 "arith_double_operand" "%r") @@ -3618,12 +3812,14 @@ "add %1,%2,%0") (define_insn "addsi3" - [(set (match_operand:SI 0 "register_operand" "=r") - (plus:SI (match_operand:SI 1 "arith_operand" "%r") - (match_operand:SI 2 "arith_operand" "rI")))] + [(set (match_operand:SI 0 "register_operand" "=r,d") + (plus:SI (match_operand:SI 1 "arith_operand" "%r,d") + (match_operand:SI 2 "arith_operand" "rI,d")))] "" - "add %1,%2,%0" - [(set_attr "type" "ialu")]) + "@ + add %1,%2,%0 + fpadd32s %1,%2,%0" + [(set_attr "type" "ialu,fp")]) (define_insn "*cmp_cc_plus" [(set (reg:CC_NOOV 100) @@ -3672,12 +3868,12 @@ { if (! TARGET_ARCH64) { - emit_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (2, - gen_rtx (SET, VOIDmode, operands[0], - gen_rtx (MINUS, DImode, operands[1], - operands[2])), - gen_rtx (CLOBBER, VOIDmode, - gen_rtx (REG, SImode, SPARC_ICC_REG))))); + emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, + gen_rtx_SET (VOIDmode, operands[0], + gen_rtx_MINUS (DImode, operands[1], + operands[2])), + gen_rtx_CLOBBER (VOIDmode, + gen_rtx_REG (CCmode, SPARC_ICC_REG))))); DONE; } }") @@ -3686,7 +3882,7 @@ [(set (match_operand:DI 0 "register_operand" "=r") (minus:DI (match_operand:DI 1 "register_operand" "r") (match_operand:DI 2 "arith_double_operand" "rHI"))) - (clobber (reg:SI 100))] + (clobber (reg:CC 100))] "! TARGET_ARCH64" "* { @@ -3712,6 +3908,15 @@ }" [(set_attr "length" "2")]) +(define_insn "" + [(set (match_operand:DI 0 "register_operand" "=r") + (minus:DI (match_operand:DI 1 "register_operand" "r") + (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))) + (clobber (reg:CC 100))] + "! TARGET_ARCH64" + "subcc %L1,%2,%L0\;addx %H1,0,%H0" + [(set_attr "type" "multi")]) + (define_insn "*subdi3_sp64" [(set (match_operand:DI 0 "register_operand" "=r") (minus:DI (match_operand:DI 1 "register_operand" "r") @@ -3720,12 +3925,14 @@ "sub %1,%2,%0") (define_insn "subsi3" - [(set (match_operand:SI 0 "register_operand" "=r") - (minus:SI (match_operand:SI 1 "register_operand" "r") - (match_operand:SI 2 "arith_operand" "rI")))] + [(set (match_operand:SI 0 "register_operand" "=r,d") + (minus:SI (match_operand:SI 1 "register_operand" "r,d") + (match_operand:SI 2 "arith_operand" "rI,d")))] "" - "sub %1,%2,%0" - [(set_attr "type" "ialu")]) + "@ + sub %1,%2,%0 + fpsub32s %1,%2,%0" + [(set_attr "type" "ialu,fp")]) (define_insn "*cmp_minus_cc" [(set (reg:CC_NOOV 100) @@ -3775,17 +3982,54 @@ [(set (match_operand:SI 0 "register_operand" "=r") (mult:SI (match_operand:SI 1 "arith_operand" "%r") (match_operand:SI 2 "arith_operand" "rI")))] - "TARGET_V8 || TARGET_SPARCLITE || TARGET_SPARCLET || TARGET_DEPRECATED_V8_INSNS" + "TARGET_HARD_MUL" "smul %1,%2,%0" [(set_attr "type" "imul")]) -(define_insn "muldi3" +(define_expand "muldi3" + [(set (match_operand:DI 0 "register_operand" "=r") + (mult:DI (match_operand:DI 1 "arith_double_operand" "%r") + (match_operand:DI 2 "arith_double_operand" "rHI")))] + "TARGET_ARCH64 || TARGET_V8PLUS" + " +{ + if (TARGET_V8PLUS) + { + emit_insn (gen_muldi3_v8plus (operands[0], operands[1], operands[2])); + DONE; + } +}") + +(define_insn "*muldi3_sp64" [(set (match_operand:DI 0 "register_operand" "=r") (mult:DI (match_operand:DI 1 "arith_double_operand" "%r") (match_operand:DI 2 "arith_double_operand" "rHI")))] "TARGET_ARCH64" "mulx %1,%2,%0") +;; V8plus wide multiply. +(define_insn "muldi3_v8plus" + [(set (match_operand:DI 0 "register_operand" "=r,h") + (mult:DI (match_operand:DI 1 "arith_double_operand" "%r,0") + (match_operand:DI 2 "arith_double_operand" "rHI,rHI"))) + (clobber (match_scratch:SI 3 "=&h,X")) + (clobber (match_scratch:SI 4 "=&h,X"))] + "TARGET_V8PLUS" + "* +{ + if (sparc_check_64 (operands[1], insn) <= 0) + output_asm_insn (\"srl %L1,0,%L1\", operands); + if (which_alternative == 1) + output_asm_insn (\"sllx %H1,32,%H1\", operands); + if (sparc_check_64 (operands[2], insn) <= 0) + output_asm_insn (\"srl %L2,0,%L2\", operands); + if (which_alternative == 1) + return \"or %L1,%H1,%H1\;sllx %H2,32,%L1\;or %L2,%L1,%L1\;mulx %H1,%L1,%L0\;srlx %L0,32,%H0\"; + else + return \"sllx %H1,32,%3\;sllx %H2,32,%4\;or %L1,%3,%3\;or %L2,%4,%4\;mulx %3,%4,%3\;srlx %3,32,%H0\;mov %3,%L0\"; +}" + [(set_attr "length" "9,8")]) + ;; It is not known whether this will match. (define_insn "*cmp_mul_set" @@ -3803,21 +4047,56 @@ [(set (match_operand:DI 0 "register_operand" "") (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "")) (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))] - "TARGET_V8 || TARGET_SPARCLITE || TARGET_SPARCLET || TARGET_DEPRECATED_V8_INSNS" + "TARGET_HARD_MUL" " { if (CONSTANT_P (operands[2])) { + if (TARGET_V8PLUS) + { + emit_insn (gen_const_mulsidi3_v8plus (operands[0], operands[1], + operands[2])); + DONE; + } emit_insn (gen_const_mulsidi3 (operands[0], operands[1], operands[2])); DONE; } + if (TARGET_V8PLUS) + { + emit_insn (gen_mulsidi3_v8plus (operands[0], operands[1], operands[2])); + DONE; + } }") +;; V9 puts the 64 bit product in a 64 bit register. Only out or global +;; registers can hold 64 bit values in the V8plus environment. +(define_insn "mulsidi3_v8plus" + [(set (match_operand:DI 0 "register_operand" "=h,r") + (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r")) + (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))) + (clobber (match_scratch:SI 3 "=X,&h"))] + "TARGET_V8PLUS" + "@ + smul %1,%2,%L0\;srlx %L0,32,%H0 + smul %1,%2,%3\;srlx %3,32,%H0\;mov %3,%L0" + [(set_attr "length" "2,3")]) + +(define_insn "const_mulsidi3_v8plus" + [(set (match_operand:DI 0 "register_operand" "=h,r") + (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r")) + (match_operand:SI 2 "small_int" "I,I"))) + (clobber (match_scratch:SI 3 "=X,&h"))] + "TARGET_V8PLUS" + "@ + smul %1,%2,%L0\;srlx %L0,32,%H0 + smul %1,%2,%3\;srlx %3,32,%H0\;mov %3,%L0" + [(set_attr "length" "2,3")]) + (define_insn "*mulsidi3_sp32" [(set (match_operand:DI 0 "register_operand" "=r") (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r")) (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))] - "TARGET_V8 || TARGET_SPARCLITE || TARGET_SPARCLET || TARGET_DEPRECATED_V8_INSNS" + "TARGET_HARD_MUL32" "* { return TARGET_SPARCLET ? \"smuld %1,%2,%L0\" : \"smul %1,%2,%L0\;rd %%y,%H0\"; @@ -3832,7 +4111,7 @@ [(set (match_operand:DI 0 "register_operand" "=r") (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r")) (match_operand:SI 2 "small_int" "I")))] - "TARGET_V8 || TARGET_SPARCLITE || TARGET_SPARCLET || TARGET_DEPRECATED_V8_INSNS" + "TARGET_HARD_MUL" "* { return TARGET_SPARCLET ? \"smuld %1,%2,%L0\" : \"smul %1,%2,%L0\;rd %%y,%H0\"; @@ -3847,23 +4126,79 @@ (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "")) (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))) (const_int 32))))] - "TARGET_V8 || TARGET_SPARCLITE || TARGET_SPARCLET || TARGET_DEPRECATED_V8_INSNS" + "TARGET_HARD_MUL" " { if (CONSTANT_P (operands[2])) { + if (TARGET_V8PLUS) + { + emit_insn (gen_const_smulsi3_highpart_v8plus (operands[0], + operands[1], + operands[2], + GEN_INT (32))); + DONE; + } emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2])); DONE; } + if (TARGET_V8PLUS) + { + emit_insn (gen_smulsi3_highpart_v8plus (operands[0], operands[1], + operands[2], GEN_INT (32))); + DONE; + } }") -(define_insn "*smulsidi3_highpart_sp32" +(define_insn "smulsi3_highpart_v8plus" + [(set (match_operand:SI 0 "register_operand" "=h,r") + (truncate:SI + (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r")) + (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))) + (match_operand:SI 3 "const_int_operand" "i,i")))) + (clobber (match_scratch:SI 4 "=X,&h"))] + "TARGET_V8PLUS" + "@ + smul %1,%2,%0\;srlx %0,%3,%0 + smul %1,%2,%4\;srlx %4,%3,%0" + [(set_attr "length" "2")]) + +;; The combiner changes TRUNCATE in the previous pattern to SUBREG. +(define_insn "" + [(set (match_operand:SI 0 "register_operand" "=h,r") + (subreg:SI + (lshiftrt:DI + (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r")) + (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))) + (match_operand:SI 3 "const_int_operand" "i,i")) + 1)) + (clobber (match_scratch:SI 4 "=X,&h"))] + "TARGET_V8PLUS" + "@ + smul %1,%2,%0\;srlx %0,%3,%0 + smul %1,%2,%4\;srlx %4,%3,%0" + [(set_attr "length" "2")]) + +(define_insn "const_smulsi3_highpart_v8plus" + [(set (match_operand:SI 0 "register_operand" "=h,r") + (truncate:SI + (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r")) + (match_operand 2 "small_int" "i,i")) + (match_operand:SI 3 "const_int_operand" "i,i")))) + (clobber (match_scratch:SI 4 "=X,&h"))] + "TARGET_V8PLUS" + "@ + smul %1,%2,%0\;srlx %0,%3,%0 + smul %1,%2,%4\;srlx %4,%3,%0" + [(set_attr "length" "2")]) + +(define_insn "*smulsi3_highpart_sp32" [(set (match_operand:SI 0 "register_operand" "=r") (truncate:SI (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r")) (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))) (const_int 32))))] - "TARGET_V8 || TARGET_SPARCLITE || TARGET_SPARCLET || TARGET_DEPRECATED_V8_INSNS" + "TARGET_HARD_MUL32" "smul %1,%2,%%g0\;rd %%y,%0" [(set_attr "length" "2")]) @@ -3873,7 +4208,7 @@ (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r")) (match_operand:SI 2 "register_operand" "r")) (const_int 32))))] - "TARGET_V8 || TARGET_SPARCLITE || TARGET_SPARCLET || TARGET_DEPRECATED_V8_INSNS" + "TARGET_HARD_MUL32" "smul %1,%2,%%g0\;rd %%y,%0" [(set_attr "length" "2")]) @@ -3881,21 +4216,43 @@ [(set (match_operand:DI 0 "register_operand" "") (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "")) (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))] - "TARGET_V8 || TARGET_SPARCLITE || TARGET_SPARCLET || TARGET_DEPRECATED_V8_INSNS" + "TARGET_HARD_MUL" " { if (CONSTANT_P (operands[2])) { + if (TARGET_V8PLUS) + { + emit_insn (gen_const_umulsidi3_v8plus (operands[0], operands[1], + operands[2])); + DONE; + } emit_insn (gen_const_umulsidi3 (operands[0], operands[1], operands[2])); DONE; } + if (TARGET_V8PLUS) + { + emit_insn (gen_umulsidi3_v8plus (operands[0], operands[1], operands[2])); + DONE; + } }") +(define_insn "umulsidi3_v8plus" + [(set (match_operand:DI 0 "register_operand" "=h,r") + (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r")) + (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r")))) + (clobber (match_scratch:SI 3 "=X,&h"))] + "TARGET_V8PLUS" + "@ + umul %1,%2,%L0\;srlx %L0,32,%H0 + umul %1,%2,%3\;srlx %3,32,%H0\;mov %3,%L0" + [(set_attr "length" "2,3")]) + (define_insn "*umulsidi3_sp32" [(set (match_operand:DI 0 "register_operand" "=r") (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r")) (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))] - "TARGET_V8 || TARGET_SPARCLITE || TARGET_SPARCLET || TARGET_DEPRECATED_V8_INSNS" + "TARGET_HARD_MUL32" "* { return TARGET_SPARCLET ? \"umuld %1,%2,%L0\" : \"umul %1,%2,%L0\;rd %%y,%H0\"; @@ -3910,7 +4267,7 @@ [(set (match_operand:DI 0 "register_operand" "=r") (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r")) (match_operand:SI 2 "uns_small_int" "")))] - "TARGET_V8 || TARGET_SPARCLITE || TARGET_SPARCLET || TARGET_DEPRECATED_V8_INSNS" + "TARGET_HARD_MUL32" "* { return TARGET_SPARCLET ? \"umuld %1,%2,%L0\" : \"umul %1,%2,%L0\;rd %%y,%H0\"; @@ -3919,29 +4276,80 @@ (if_then_else (eq_attr "isa" "sparclet") (const_int 1) (const_int 2)))]) +(define_insn "const_umulsidi3_v8plus" + [(set (match_operand:DI 0 "register_operand" "=h,r") + (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r")) + (match_operand:SI 2 "uns_small_int" ""))) + (clobber (match_scratch:SI 3 "=X,h"))] + "TARGET_V8PLUS" + "@ + umul %1,%2,%L0\;srlx %L0,32,%H0 + umul %1,%2,%3\;srlx %3,32,%H0\;mov %3,%L0" + [(set_attr "length" "2,3")]) + (define_expand "umulsi3_highpart" [(set (match_operand:SI 0 "register_operand" "") (truncate:SI (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "")) (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))) (const_int 32))))] - "TARGET_V8 || TARGET_SPARCLITE || TARGET_SPARCLET || TARGET_DEPRECATED_V8_INSNS" + "TARGET_HARD_MUL" " { if (CONSTANT_P (operands[2])) { + if (TARGET_V8PLUS) + { + emit_insn (gen_const_umulsi3_highpart_v8plus (operands[0], + operands[1], + operands[2], + GEN_INT (32))); + DONE; + } emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2])); DONE; } + if (TARGET_V8PLUS) + { + emit_insn (gen_umulsi3_highpart_v8plus (operands[0], operands[1], + operands[2], GEN_INT (32))); + DONE; + } }") -(define_insn "*umulsidi3_highpart_sp32" +(define_insn "umulsi3_highpart_v8plus" + [(set (match_operand:SI 0 "register_operand" "=h,r") + (truncate:SI + (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r")) + (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r"))) + (match_operand:SI 3 "const_int_operand" "i,i")))) + (clobber (match_scratch:SI 4 "=X,h"))] + "TARGET_V8PLUS" + "@ + umul %1,%2,%0\;srlx %0,%3,%0 + umul %1,%2,%4\;srlx %4,%3,%0" + [(set_attr "length" "2")]) + +(define_insn "const_umulsi3_highpart_v8plus" + [(set (match_operand:SI 0 "register_operand" "=h,r") + (truncate:SI + (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r")) + (match_operand:SI 2 "uns_small_int" "")) + (match_operand:SI 3 "const_int_operand" "i,i")))) + (clobber (match_scratch:SI 4 "=X,h"))] + "TARGET_V8PLUS" + "@ + umul %1,%2,%0\;srlx %0,%3,%0 + umul %1,%2,%4\;srlx %4,%3,%0" + [(set_attr "length" "2")]) + +(define_insn "*umulsi3_highpart_sp32" [(set (match_operand:SI 0 "register_operand" "=r") (truncate:SI (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r")) (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))) (const_int 32))))] - "TARGET_V8 || TARGET_SPARCLITE || TARGET_SPARCLET || TARGET_DEPRECATED_V8_INSNS" + "TARGET_HARD_MUL32" "umul %1,%2,%%g0\;rd %%y,%0" [(set_attr "length" "2")]) @@ -3951,7 +4359,7 @@ (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r")) (match_operand:SI 2 "uns_small_int" "")) (const_int 32))))] - "TARGET_V8 || TARGET_SPARCLITE || TARGET_SPARCLET || TARGET_DEPRECATED_V8_INSNS" + "TARGET_HARD_MUL32" "umul %1,%2,%%g0\;rd %%y,%0" [(set_attr "length" "2")]) @@ -3959,21 +4367,27 @@ ;; a y register write and a use of it for correct results. (define_insn "divsi3" - [(set (match_operand:SI 0 "register_operand" "=r") - (div:SI (match_operand:SI 1 "register_operand" "r") - (match_operand:SI 2 "arith_operand" "rI"))) - (clobber (match_scratch:SI 3 "=&r"))] + [(set (match_operand:SI 0 "register_operand" "=r,r") + (div:SI (match_operand:SI 1 "register_operand" "r,r") + (match_operand:SI 2 "move_operand" "rI,m"))) + (clobber (match_scratch:SI 3 "=&r,&r"))] "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS" "* { + if (which_alternative == 0) if (TARGET_V9) return \"sra %1,31,%3\;wr %%g0,%3,%%y\;sdiv %1,%2,%0\"; else return \"sra %1,31,%3\;wr %%g0,%3,%%y\;nop\;nop\;nop\;sdiv %1,%2,%0\"; + else + if (TARGET_V9) + return \"sra %1,31,%3\;wr %%g0,%3,%%y\;ld %2,%3\;sdiv %1,%3,%0\"; + else + return \"sra %1,31,%3\;wr %%g0,%3,%%y\;ld %2,%3\;nop\;nop\;sdiv %1,%3,%0\"; }" [(set (attr "length") (if_then_else (eq_attr "isa" "v9") - (const_int 3) (const_int 6)))]) + (const_int 4) (const_int 7)))]) (define_insn "divdi3" [(set (match_operand:DI 0 "register_operand" "=r") @@ -4005,19 +4419,28 @@ (const_int 3) (const_int 6)))]) (define_insn "udivsi3" - [(set (match_operand:SI 0 "register_operand" "=r") - (udiv:SI (match_operand:SI 1 "register_operand" "r") - (match_operand:SI 2 "arith_operand" "rI")))] + [(set (match_operand:SI 0 "register_operand" "=r,&r,&r") + (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "r,r,m") + (match_operand:SI 2 "move_operand" "rI,m,r")))] "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS" "* { + output_asm_insn (\"wr %%g0,%%g0,%%y\", operands); + switch (which_alternative) + { + default: if (TARGET_V9) - return \"wr %%g0,%%g0,%%y\;udiv %1,%2,%0\"; - else - return \"wr %%g0,%%g0,%%y\;nop\;nop\;nop\;udiv %1,%2,%0\"; + return \"udiv %1,%2,%0\"; + return \"nop\;nop\;nop\;udiv %1,%2,%0\"; + case 1: + return \"ld %2,%0\;nop\;nop\;udiv %1,%0,%0\"; + case 2: + return \"ld %1,%0\;nop\;nop\;udiv %0,%2,%0\"; + } }" [(set (attr "length") - (if_then_else (eq_attr "isa" "v9") + (if_then_else (and (eq_attr "isa" "v9") + (eq_attr "alternative" "0")) (const_int 2) (const_int 5)))]) (define_insn "udivdi3" @@ -4093,14 +4516,17 @@ "") (define_insn "*anddi3_sp32" - [(set (match_operand:DI 0 "register_operand" "=r") - (and:DI (match_operand:DI 1 "arith_double_operand" "%r") - (match_operand:DI 2 "arith_double_operand" "rHI")))] + [(set (match_operand:DI 0 "register_operand" "=r,b") + (and:DI (match_operand:DI 1 "arith_double_operand" "%r,b") + (match_operand:DI 2 "arith_double_operand" "rHI,b")))] "! TARGET_ARCH64" "* { rtx op2 = operands[2]; + if (which_alternative == 1) + return \"fand %1,%2,%0\"; + if (GET_CODE (op2) == CONST_INT || GET_CODE (op2) == CONST_DOUBLE) { @@ -4116,7 +4542,7 @@ } return \"and %1,%2,%0\;and %R1,%R2,%R0\"; }" - [(set_attr "length" "2")]) + [(set_attr "length" "2,1")]) (define_insn "*anddi3_sp64" [(set (match_operand:DI 0 "register_operand" "=r") @@ -4126,12 +4552,14 @@ "and %1,%2,%0") (define_insn "andsi3" - [(set (match_operand:SI 0 "register_operand" "=r") - (and:SI (match_operand:SI 1 "arith_operand" "%r") - (match_operand:SI 2 "arith_operand" "rI")))] + [(set (match_operand:SI 0 "register_operand" "=r,d") + (and:SI (match_operand:SI 1 "arith_operand" "%r,d") + (match_operand:SI 2 "arith_operand" "rI,d")))] "" - "and %1,%2,%0" - [(set_attr "type" "ialu")]) + "@ + and %1,%2,%0 + fands %1,%2,%0" + [(set_attr "type" "ialu,fp")]) (define_split [(set (match_operand:SI 0 "register_operand" "") @@ -4139,22 +4567,52 @@ (match_operand:SI 2 "" ""))) (clobber (match_operand:SI 3 "register_operand" ""))] "GET_CODE (operands[2]) == CONST_INT - && !SMALL_INT (operands[2]) + && !SMALL_INT32 (operands[2]) && (INTVAL (operands[2]) & 0x3ff) == 0x3ff" [(set (match_dup 3) (match_dup 4)) (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))] " { - operands[4] = GEN_INT (~INTVAL (operands[2])); + operands[4] = GEN_INT (~INTVAL (operands[2]) & 0xffffffff); +}") + +;; Split DImode logical operations requiring two instructions. +(define_split + [(set (match_operand:DI 0 "register_operand" "") + (match_operator:DI 1 "cc_arithop" ; AND, IOR, XOR + [(match_operand:DI 2 "register_operand" "") + (match_operand:DI 3 "arith_double_operand" "")]))] + "! TARGET_ARCH64 && reload_completed + && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < 32" + [(set (match_dup 4) (match_op_dup:SI 1 [(match_dup 6) (match_dup 8)])) + (set (match_dup 5) (match_op_dup:SI 1 [(match_dup 7) (match_dup 9)]))] + " +{ + operands[4] = gen_highpart (SImode, operands[0]); + operands[5] = gen_lowpart (SImode, operands[0]); + operands[6] = gen_highpart (SImode, operands[2]); + operands[7] = gen_lowpart (SImode, operands[2]); + if (GET_CODE (operands[3]) == CONST_INT) + { + if (INTVAL (operands[3]) < 0) + operands[8] = constm1_rtx; + else + operands[8] = const0_rtx; + } + else + operands[8] = gen_highpart (SImode, operands[3]); + operands[9] = gen_lowpart (SImode, operands[3]); }") (define_insn "*and_not_di_sp32" - [(set (match_operand:DI 0 "register_operand" "=r") - (and:DI (not:DI (match_operand:DI 1 "register_operand" "r")) - (match_operand:DI 2 "register_operand" "r")))] + [(set (match_operand:DI 0 "register_operand" "=r,b") + (and:DI (not:DI (match_operand:DI 1 "register_operand" "r,b")) + (match_operand:DI 2 "register_operand" "r,b")))] "! TARGET_ARCH64" - "andn %2,%1,%0\;andn %R2,%R1,%R0" - [(set_attr "length" "2")]) + "@ + andn %2,%1,%0\;andn %R2,%R1,%R0 + fandnot1 %1,%2,%0" + [(set_attr "length" "2,1")]) (define_insn "*and_not_di_sp64" [(set (match_operand:DI 0 "register_operand" "=r") @@ -4164,12 +4622,14 @@ "andn %2,%1,%0") (define_insn "*and_not_si" - [(set (match_operand:SI 0 "register_operand" "=r") - (and:SI (not:SI (match_operand:SI 1 "register_operand" "r")) - (match_operand:SI 2 "register_operand" "r")))] + [(set (match_operand:SI 0 "register_operand" "=r,d") + (and:SI (not:SI (match_operand:SI 1 "register_operand" "r,d")) + (match_operand:SI 2 "register_operand" "r,d")))] "" - "andn %2,%1,%0" - [(set_attr "type" "ialu")]) + "@ + andn %2,%1,%0 + fandnot1s %1,%2,%0" + [(set_attr "type" "ialu,fp")]) (define_expand "iordi3" [(set (match_operand:DI 0 "register_operand" "") @@ -4179,14 +4639,17 @@ "") (define_insn "*iordi3_sp32" - [(set (match_operand:DI 0 "register_operand" "=r") - (ior:DI (match_operand:DI 1 "arith_double_operand" "%r") - (match_operand:DI 2 "arith_double_operand" "rHI")))] + [(set (match_operand:DI 0 "register_operand" "=r,b") + (ior:DI (match_operand:DI 1 "arith_double_operand" "%r,b") + (match_operand:DI 2 "arith_double_operand" "rHI,b")))] "! TARGET_ARCH64" "* { rtx op2 = operands[2]; + if (which_alternative == 1) + return \"for %1,%2,%0\"; + if (GET_CODE (op2) == CONST_INT || GET_CODE (op2) == CONST_DOUBLE) { @@ -4202,7 +4665,7 @@ } return \"or %1,%2,%0\;or %R1,%R2,%R0\"; }" - [(set_attr "length" "2")]) + [(set_attr "length" "2,1")]) (define_insn "*iordi3_sp64" [(set (match_operand:DI 0 "register_operand" "=r") @@ -4212,12 +4675,14 @@ "or %1,%2,%0") (define_insn "iorsi3" - [(set (match_operand:SI 0 "register_operand" "=r") - (ior:SI (match_operand:SI 1 "arith_operand" "%r") - (match_operand:SI 2 "arith_operand" "rI")))] + [(set (match_operand:SI 0 "register_operand" "=r,d") + (ior:SI (match_operand:SI 1 "arith_operand" "%r,d") + (match_operand:SI 2 "arith_operand" "rI,d")))] "" - "or %1,%2,%0" - [(set_attr "type" "ialu")]) + "@ + or %1,%2,%0 + fors %1,%2,%0" + [(set_attr "type" "ialu,fp")]) (define_split [(set (match_operand:SI 0 "register_operand" "") @@ -4225,22 +4690,24 @@ (match_operand:SI 2 "" ""))) (clobber (match_operand:SI 3 "register_operand" ""))] "GET_CODE (operands[2]) == CONST_INT - && !SMALL_INT (operands[2]) + && !SMALL_INT32 (operands[2]) && (INTVAL (operands[2]) & 0x3ff) == 0x3ff" [(set (match_dup 3) (match_dup 4)) (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))] " { - operands[4] = GEN_INT (~INTVAL (operands[2])); + operands[4] = GEN_INT (~INTVAL (operands[2]) & 0xffffffff); }") (define_insn "*or_not_di_sp32" - [(set (match_operand:DI 0 "register_operand" "=r") - (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r")) - (match_operand:DI 2 "register_operand" "r")))] + [(set (match_operand:DI 0 "register_operand" "=r,b") + (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r,b")) + (match_operand:DI 2 "register_operand" "r,b")))] "! TARGET_ARCH64" - "orn %2,%1,%0\;orn %R2,%R1,%R0" - [(set_attr "length" "2")]) + "@ + orn %2,%1,%0\;orn %R2,%R1,%R0 + fornot1 %1,%2,%0" + [(set_attr "length" "2,1")]) (define_insn "*or_not_di_sp64" [(set (match_operand:DI 0 "register_operand" "=r") @@ -4250,12 +4717,14 @@ "orn %2,%1,%0") (define_insn "*or_not_si" - [(set (match_operand:SI 0 "register_operand" "=r") - (ior:SI (not:SI (match_operand:SI 1 "register_operand" "r")) - (match_operand:SI 2 "register_operand" "r")))] + [(set (match_operand:SI 0 "register_operand" "=r,d") + (ior:SI (not:SI (match_operand:SI 1 "register_operand" "r,d")) + (match_operand:SI 2 "register_operand" "r,d")))] "" - "orn %2,%1,%0" - [(set_attr "type" "ialu")]) + "@ + orn %2,%1,%0 + fornot1s %1,%2,%0" + [(set_attr "type" "ialu,fp")]) (define_expand "xordi3" [(set (match_operand:DI 0 "register_operand" "") @@ -4264,15 +4733,18 @@ "" "") -(define_insn "*xorsi3_sp32" - [(set (match_operand:DI 0 "register_operand" "=r") - (xor:DI (match_operand:DI 1 "arith_double_operand" "%r") - (match_operand:DI 2 "arith_double_operand" "rHI")))] +(define_insn "*xordi3_sp32" + [(set (match_operand:DI 0 "register_operand" "=r,b") + (xor:DI (match_operand:DI 1 "arith_double_operand" "%r,b") + (match_operand:DI 2 "arith_double_operand" "rHI,b")))] "! TARGET_ARCH64" "* { rtx op2 = operands[2]; + if (which_alternative == 1) + return \"fxor %1,%2,%0\"; + if (GET_CODE (op2) == CONST_INT || GET_CODE (op2) == CONST_DOUBLE) { @@ -4288,7 +4760,8 @@ } return \"xor %1,%2,%0\;xor %R1,%R2,%R0\"; }" - [(set_attr "length" "2")]) + [(set_attr "length" "2,1") + (set_attr "type" "ialu,fp")]) (define_insn "*xordi3_sp64" [(set (match_operand:DI 0 "register_operand" "=r") @@ -4298,12 +4771,14 @@ "xor %r1,%2,%0") (define_insn "xorsi3" - [(set (match_operand:SI 0 "register_operand" "=r") - (xor:SI (match_operand:SI 1 "arith_operand" "%rJ") - (match_operand:SI 2 "arith_operand" "rI")))] + [(set (match_operand:SI 0 "register_operand" "=r,d") + (xor:SI (match_operand:SI 1 "arith_operand" "%rJ,d") + (match_operand:SI 2 "arith_operand" "rI,d")))] "" - "xor %r1,%2,%0" - [(set_attr "type" "ialu")]) + "@ + xor %r1,%2,%0 + fxors %1,%2,%0" + [(set_attr "type" "ialu,fp")]) (define_split [(set (match_operand:SI 0 "register_operand" "") @@ -4311,13 +4786,13 @@ (match_operand:SI 2 "" ""))) (clobber (match_operand:SI 3 "register_operand" ""))] "GET_CODE (operands[2]) == CONST_INT - && !SMALL_INT (operands[2]) + && !SMALL_INT32 (operands[2]) && (INTVAL (operands[2]) & 0x3ff) == 0x3ff" [(set (match_dup 3) (match_dup 4)) (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))] " { - operands[4] = GEN_INT (~INTVAL (operands[2])); + operands[4] = GEN_INT (~INTVAL (operands[2]) & 0xffffffff); }") (define_split @@ -4326,40 +4801,46 @@ (match_operand:SI 2 "" "")))) (clobber (match_operand:SI 3 "register_operand" ""))] "GET_CODE (operands[2]) == CONST_INT - && !SMALL_INT (operands[2]) + && !SMALL_INT32 (operands[2]) && (INTVAL (operands[2]) & 0x3ff) == 0x3ff" [(set (match_dup 3) (match_dup 4)) (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))] " { - operands[4] = GEN_INT (~INTVAL (operands[2])); + operands[4] = GEN_INT (~INTVAL (operands[2]) & 0xffffffff); }") ;; xnor patterns. Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b). ;; Combine now canonicalizes to the rightmost expression. (define_insn "*xor_not_di_sp32" - [(set (match_operand:DI 0 "register_operand" "=r") - (not:DI (xor:DI (match_operand:DI 1 "register_operand" "r") - (match_operand:DI 2 "register_operand" "r"))))] + [(set (match_operand:DI 0 "register_operand" "=r,b") + (not:DI (xor:DI (match_operand:DI 1 "register_operand" "r,b") + (match_operand:DI 2 "register_operand" "r,b"))))] "! TARGET_ARCH64" - "xnor %1,%2,%0\;xnor %R1,%R2,%R0" - [(set_attr "length" "2")]) + "@ + xnor %1,%2,%0\;xnor %R1,%R2,%R0 + fxnor %1,%2,%0" + [(set_attr "length" "2,1") + (set_attr "type" "ialu,fp")]) (define_insn "*xor_not_di_sp64" [(set (match_operand:DI 0 "register_operand" "=r") (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "rJ") (match_operand:DI 2 "arith_double_operand" "rHI"))))] "TARGET_ARCH64" - "xnor %r1,%2,%0") - -(define_insn "*xor_not_si" - [(set (match_operand:SI 0 "register_operand" "=r") - (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "rJ") - (match_operand:SI 2 "arith_operand" "rI"))))] - "" "xnor %r1,%2,%0" [(set_attr "type" "ialu")]) +(define_insn "*xor_not_si" + [(set (match_operand:SI 0 "register_operand" "=r,d") + (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "rJ,d") + (match_operand:SI 2 "arith_operand" "rI,d"))))] + "" + "@ + xnor %r1,%2,%0 + fxnors %1,%2,%0" + [(set_attr "type" "ialu,fp")]) + ;; These correspond to the above in the case where we also (or only) ;; want to set the condition code. @@ -4508,11 +4989,11 @@ { if (! TARGET_ARCH64) { - emit_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (2, - gen_rtx (SET, VOIDmode, operand0, - gen_rtx (NEG, DImode, operand1)), - gen_rtx (CLOBBER, VOIDmode, - gen_rtx (REG, SImode, SPARC_ICC_REG))))); + emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, + gen_rtx_SET (VOIDmode, operand0, + gen_rtx_NEG (DImode, operand1)), + gen_rtx_CLOBBER (VOIDmode, + gen_rtx_REG (CCmode, SPARC_ICC_REG))))); DONE; } }") @@ -4520,7 +5001,7 @@ (define_insn "*negdi2_sp32" [(set (match_operand:DI 0 "register_operand" "=r") (neg:DI (match_operand:DI 1 "register_operand" "r"))) - (clobber (reg:SI 100))] + (clobber (reg:CC 100))] "! TARGET_ARCH64" "* { @@ -4599,12 +5080,14 @@ "") (define_insn "*one_cmpldi2_sp32" - [(set (match_operand:DI 0 "register_operand" "=r") - (not:DI (match_operand:DI 1 "register_operand" "r")))] + [(set (match_operand:DI 0 "register_operand" "=r,b") + (not:DI (match_operand:DI 1 "register_operand" "r,b")))] "! TARGET_ARCH64" - "xnor %1,0,%0\;xnor %R1,0,%R0" - [(set_attr "type" "unary") - (set_attr "length" "2")]) + "@ + xnor %1,0,%0\;xnor %R1,0,%R0 + fnot1 %1,%0" + [(set_attr "type" "unary,fp") + (set_attr "length" "2,1")]) (define_insn "*one_cmpldi2_sp64" [(set (match_operand:DI 0 "register_operand" "=r") @@ -4614,21 +5097,24 @@ [(set_attr "type" "unary")]) (define_insn "one_cmplsi2" - [(set (match_operand:SI 0 "register_operand" "=r,r") - (not:SI (match_operand:SI 1 "arith_operand" "r,I")))] + [(set (match_operand:SI 0 "register_operand" "=r,r,d") + (not:SI (match_operand:SI 1 "arith_operand" "r,I,d")))] "" "* { if (which_alternative == 0) return \"xnor %1,0,%0\"; + if (which_alternative == 2) + return \"fnot1s %1,%0\"; if (TARGET_LIVE_G0) output_asm_insn (\"and %%g0,0,%%g0\", operands); return \"xnor %%g0,%1,%0\"; }" - [(set_attr "type" "unary") + [(set_attr "type" "unary,unary,fp") (set_attr_alternative "length" [(const_int 1) - (if_then_else (eq_attr "live_g0" "yes") (const_int 2) (const_int 1))])]) + (if_then_else (eq_attr "live_g0" "yes") (const_int 2) (const_int 1)) + (const_int 1)])]) (define_insn "*cmp_cc_not" [(set (reg:CC 100) @@ -4795,7 +5281,7 @@ return TARGET_V9 ? \"fnegd %1,%0\;fmovd %S1,%S0\" : \"fnegs %1,%0\;fmovs %R1,%R0\;fmovs %S1,%S0\;fmovs %T1,%T0\"; }" - [(set_attr "type" "fp") + [(set_attr "type" "fpmove") (set_attr_alternative "length" [(const_int 1) (if_then_else (eq_attr "isa" "v9") (const_int 2) (const_int 4))])]) @@ -4813,7 +5299,7 @@ else return \"fnegs %1,%0\;fmovs %R1,%R0\"; }" - [(set_attr "type" "fp") + [(set_attr "type" "fpmove") (set_attr_alternative "length" [(const_int 1) (if_then_else (eq_attr "isa" "v9") (const_int 1) (const_int 2))])]) @@ -4823,7 +5309,7 @@ (neg:SF (match_operand:SF 1 "register_operand" "f")))] "TARGET_FPU" "fnegs %1,%0" - [(set_attr "type" "fp")]) + [(set_attr "type" "fpmove")]) (define_insn "abstf2" [(set (match_operand:TF 0 "register_operand" "=e,e") @@ -4839,7 +5325,7 @@ return TARGET_V9 ? \"fabsd %1,%0\;fmovd %S1,%S0\" : \"fabss %1,%0\;fmovs %R1,%R0\;fmovs %S1,%S0\;fmovs %T1,%T0\"; }" - [(set_attr "type" "fp") + [(set_attr "type" "fpmove") (set_attr_alternative "length" [(const_int 1) (if_then_else (eq_attr "isa" "v9") (const_int 2) (const_int 4))])]) @@ -4857,7 +5343,7 @@ else return \"fabss %1,%0\;fmovs %R1,%R0\"; }" - [(set_attr "type" "fp") + [(set_attr "type" "fpmove") (set_attr_alternative "length" [(const_int 1) (if_then_else (eq_attr "isa" "v9") (const_int 1) (const_int 2))])]) @@ -4867,7 +5353,7 @@ (abs:SF (match_operand:SF 1 "register_operand" "f")))] "TARGET_FPU" "fabss %1,%0" - [(set_attr "type" "fp")]) + [(set_attr "type" "fpmove")]) (define_insn "sqrttf2" [(set (match_operand:TF 0 "register_operand" "=e") @@ -4907,7 +5393,23 @@ }" [(set_attr "type" "shift")]) -(define_insn "ashldi3" +(define_expand "ashldi3" + [(set (match_operand:DI 0 "register_operand" "=r") + (ashift:DI (match_operand:DI 1 "register_operand" "r") + (match_operand:SI 2 "arith_operand" "rI")))] + "TARGET_ARCH64 || TARGET_V8PLUS" + " +{ + if (! TARGET_ARCH64) + { + if (GET_CODE (operands[2]) == CONST_INT) + FAIL; + emit_insn (gen_ashldi3_v8plus (operands[0], operands[1], operands[2])); + DONE; + } +}") + +(define_insn "" [(set (match_operand:DI 0 "register_operand" "=r") (ashift:DI (match_operand:DI 1 "register_operand" "r") (match_operand:SI 2 "arith_operand" "rI")))] @@ -4921,6 +5423,30 @@ return \"sllx %1,%2,%0\"; }") +(define_insn "ashldi3_v8plus" + [(set (match_operand:DI 0 "register_operand" "=&h,&h,r") + (ashift:DI (match_operand:DI 1 "arith_operand" "rI,0,rI") + (match_operand:SI 2 "arith_operand" "rI,rI,rI"))) + (clobber (match_scratch:SI 3 "=X,X,&h"))] + "TARGET_V8PLUS" + "*return sparc_v8plus_shift (operands, insn, \"sllx\");" + [(set_attr "length" "5,5,6")]) + +;; Optimize (1LL< #include #endif - -#include diff --git a/gnu/dist/gcc/config/sparc/xm-pbd.h b/gnu/dist/gcc/config/sparc/xm-pbd.h index dad9fdc6b349..1c3f47590c79 100644 --- a/gnu/dist/gcc/config/sparc/xm-pbd.h +++ b/gnu/dist/gcc/config/sparc/xm-pbd.h @@ -3,9 +3,6 @@ #include "sparc/xm-sparc.h" #define USG -#define bcopy(a,b,c) memcpy (b,a,c) -#define bzero(a,b) memset (a,0,b) -#define bcmp(a,b,c) memcmp (a,b,c) #ifndef __GNUC__ #define USE_C_ALLOCA diff --git a/gnu/dist/gcc/config/sparc/xm-sol2.h b/gnu/dist/gcc/config/sparc/xm-sol2.h index a799f12b9464..5613b086b572 100644 --- a/gnu/dist/gcc/config/sparc/xm-sol2.h +++ b/gnu/dist/gcc/config/sparc/xm-sol2.h @@ -1,5 +1,3 @@ -#include "sparc/xm-sysv4.h" - /* If not compiled with GNU C, include the system's header. */ #ifndef __GNUC__ #include diff --git a/gnu/dist/gcc/config/sparc/xm-sparc.h b/gnu/dist/gcc/config/sparc/xm-sparc.h index afc44ae889d8..e553a0df0b25 100644 --- a/gnu/dist/gcc/config/sparc/xm-sparc.h +++ b/gnu/dist/gcc/config/sparc/xm-sparc.h @@ -1,5 +1,5 @@ /* Configuration for GNU C-compiler for Sun Sparc. - Copyright (C) 1988, 1993, 1995 Free Software Foundation, Inc. + Copyright (C) 1988, 1993, 1995, 1997 Free Software Foundation, Inc. Contributed by Michael Tiemann (tiemann@cygnus.com). This file is part of GNU CC. @@ -43,8 +43,6 @@ Boston, MA 02111-1307, USA. */ #define SUCCESS_EXIT_CODE 0 #define FATAL_EXIT_CODE 33 -#define HAVE_POPEN - /* If compiled with Sun CC, the use of alloca requires this #include. */ #ifndef __GNUC__ #include "alloca.h" diff --git a/gnu/dist/gcc/config/sparc/xm-sysv4.h b/gnu/dist/gcc/config/sparc/xm-sysv4.h index e72c49922fdd..6e663d12cfa1 100644 --- a/gnu/dist/gcc/config/sparc/xm-sysv4.h +++ b/gnu/dist/gcc/config/sparc/xm-sysv4.h @@ -1,7 +1,6 @@ /* Configuration for GNU C-compiler for Sun Sparc running System V.4. - Copyright (C) 1992, 1993 Free Software Foundation, Inc. - - Written by Ron Guilmette (rfg@netcom.com). + Copyright (C) 1992, 1993, 1998 Free Software Foundation, Inc. + Contributed by Ron Guilmette (rfg@netcom.com). This file is part of GNU CC. @@ -44,8 +43,6 @@ Boston, MA 02111-1307, USA. */ #define SUCCESS_EXIT_CODE 0 #define FATAL_EXIT_CODE 33 -#include "xm-svr4.h" - #ifndef __GNUC__ #define ONLY_INT_FIELDS #endif diff --git a/gnu/dist/gcc/config/spur/spur.c b/gnu/dist/gcc/config/spur/spur.c index 5837cbbfe3af..83e37b8aeef5 100644 --- a/gnu/dist/gcc/config/spur/spur.c +++ b/gnu/dist/gcc/config/spur/spur.c @@ -1,6 +1,6 @@ /* Subroutines for insn-output.c for SPUR. Adapted from routines for the Motorola 68000 family. - Copyright (C) 1988, 1991 Free Software Foundation, Inc. + Copyright (C) 1988, 1991, 1997 Free Software Foundation, Inc. This file is part of GNU CC. @@ -20,6 +20,7 @@ the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "config.h" +#include #include "rtl.h" #include "regs.h" #include "hard-reg-set.h" @@ -152,10 +153,8 @@ output_move_double (operands) { if (GET_CODE (operands[1]) == CONST_DOUBLE) { - latehalf[1] = gen_rtx (CONST_INT, VOIDmode, - CONST_DOUBLE_HIGH (operands[1])); - operands[1] = gen_rtx (CONST_INT, VOIDmode, - CONST_DOUBLE_LOW (operands[1])); + latehalf[1] = GEN_INT (CONST_DOUBLE_HIGH (operands[1])); + operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1])); } else if (CONSTANT_P (operands[1])) latehalf[1] = const0_rtx; @@ -225,10 +224,10 @@ output_fp_move_double (operands) rtx xoperands[2]; int offset = - get_frame_size () - 8; xoperands[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1); - xoperands[0] = gen_rtx (CONST_INT, VOIDmode, offset + 4); + xoperands[0] = GEN_INT (offset + 4); output_asm_insn ("st_32 %1,r25,%0", xoperands); xoperands[1] = operands[1]; - xoperands[0] = gen_rtx (CONST_INT, VOIDmode, offset); + xoperands[0] = GEN_INT (offset); output_asm_insn ("st_32 %1,r25,%0", xoperands); xoperands[1] = operands[0]; output_asm_insn ("ld_dbl %1,r25,%0\n\tnop", xoperands); @@ -242,13 +241,13 @@ output_fp_move_double (operands) { rtx xoperands[2]; int offset = - get_frame_size () - 8; - xoperands[0] = gen_rtx (CONST_INT, VOIDmode, offset); + xoperands[0] = GEN_INT (offset); xoperands[1] = operands[1]; output_asm_insn ("st_dbl %1,r25,%0", xoperands); xoperands[1] = operands[0]; output_asm_insn ("ld_32 %1,r25,%0\n\tnop", xoperands); xoperands[1] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1); - xoperands[0] = gen_rtx (CONST_INT, VOIDmode, offset + 4); + xoperands[0] = GEN_INT (offset + 4); output_asm_insn ("ld_32 %1,r25,%0\n\tnop", xoperands); return ""; } @@ -297,7 +296,7 @@ output_add_large_offset (target, reg, offset) (unsigned) (high + 0x2000) >= 0x4000; high >>= 1, n += 1) ; - operands[2] = gen_rtx (CONST_INT, VOIDmode, high); + operands[2] = GEN_INT (high); output_asm_insn ("add_nt r2,r0,%2", operands); i = n; while (i >= 3) @@ -309,7 +308,7 @@ output_add_large_offset (target, reg, offset) output_asm_insn ("add_nt %0,r2,%1", operands); if (offset - (high << n) != 0) { - operands[2] = gen_rtx (CONST_INT, VOIDmode, offset - (high << n)); + operands[2] = GEN_INT (offset - (high << n)); output_asm_insn ("add_nt %0,%0,%2", operands); } return ""; diff --git a/gnu/dist/gcc/config/spur/spur.h b/gnu/dist/gcc/config/spur/spur.h index 51e1add1b27a..c75caf6f5f12 100644 --- a/gnu/dist/gcc/config/spur/spur.h +++ b/gnu/dist/gcc/config/spur/spur.h @@ -738,10 +738,11 @@ extern int current_function_pretend_args_size; for the index in the tablejump instruction. */ #define CASE_VECTOR_MODE SImode -/* Define this if the tablejump instruction expects the table - to contain offsets from the address of the table. - Do not define this if the table should contain absolute addresses. */ -/* #define CASE_VECTOR_PC_RELATIVE */ +/* Define as C expression which evaluates to nonzero if the tablejump + instruction expects the table to contain offsets from the address of the + table. + Do not define this if the table should contain absolute addresses. */ +/* #define CASE_VECTOR_PC_RELATIVE 1 */ /* Specify the tree operation to be used to convert reals to integers. */ #define IMPLICIT_FIX_EXPR FIX_ROUND_EXPR @@ -946,7 +947,7 @@ extern int current_function_pretend_args_size; (SPUR does not use such vectors, but we must define this macro anyway.) */ -#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, VALUE, REL) \ +#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) \ fprintf (FILE, "\t.word L%d-L%d\n", VALUE, REL) /* This is how to output an assembler line diff --git a/gnu/dist/gcc/config/spur/spur.md b/gnu/dist/gcc/config/spur/spur.md index f95e8e04695f..7ad4af5b3421 100644 --- a/gnu/dist/gcc/config/spur/spur.md +++ b/gnu/dist/gcc/config/spur/spur.md @@ -297,7 +297,7 @@ emit_insn (gen_rtx (SET, VOIDmode, subreg, gen_rtx (ZERO_EXTRACT, SImode, tem, - gen_rtx (CONST_INT, VOIDmode, 8), + GEN_INT (8), addr))); } else if (GET_CODE (operands[0]) == MEM) @@ -318,7 +318,7 @@ emit_insn (gen_rtx (SET, VOIDmode, gen_rtx (ZERO_EXTRACT, SImode, tem, - gen_rtx (CONST_INT, VOIDmode, 8), + GEN_INT (8), addr), subreg)); emit_move_insn (gen_rtx (MEM, SImode, addr), tem); @@ -376,7 +376,7 @@ ; && (unsigned) INTVAL (operands[1]) < 32" ; "* ;{ -; operands[1] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[1]) / 8); +; operands[1] = GEN_INT (INTVAL (operands[1]) / 8); ; return \"wr_insert 0,0,%1\;insert %0,%0,%2\"; ;}") @@ -467,9 +467,8 @@ (set (mem:SI (match_dup 0)) (match_dup 2))] "" - " operands[5] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[1]) & 255); - operands[6] = gen_rtx (CONST_INT, VOIDmode, - (INTVAL (operands[1]) >> 8) & 255); + " operands[5] = GEN_INT (INTVAL (operands[1]) & 255); + operands[6] = GEN_INT ((INTVAL (operands[1]) >> 8) & 255); ") ;; Main entry for generating insns to move halfwords. @@ -563,7 +562,7 @@ ; && (unsigned) INTVAL (operands[1]) < 32" ; "* ;{ -; operands[1] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[1]) / 8); +; operands[1] = GEN_INT (INTVAL (operands[1]) / 8); ; return \"wr_insert 0,0,%1\;insert %0,%0,%2\"; ;}") @@ -631,7 +630,7 @@ rtx xoperands[2]; int offset = - get_frame_size () - 8; xoperands[1] = operands[1]; - xoperands[0] = gen_rtx (CONST_INT, VOIDmode, offset); + xoperands[0] = GEN_INT (offset); output_asm_insn (\"st_32 %1,r25,%0\", xoperands); xoperands[1] = operands[0]; output_asm_insn (\"ld_sgl %1,r25,%0\;nop\", xoperands); @@ -645,7 +644,7 @@ { rtx xoperands[2]; int offset = - get_frame_size () - 8; - xoperands[0] = gen_rtx (CONST_INT, VOIDmode, offset); + xoperands[0] = GEN_INT (offset); xoperands[1] = operands[1]; output_asm_insn (\"st_sgl %1,r25,%0\", xoperands); xoperands[1] = operands[0]; @@ -705,7 +704,7 @@ else operands[1] = gen_rtx (SUBREG, SImode, operands[1], 0); - operands[2] = force_reg (SImode, gen_rtx (CONST_INT, VOIDmode, 65535)); + operands[2] = force_reg (SImode, GEN_INT (65535)); }") (define_insn "zero_extendqihi2" @@ -744,8 +743,8 @@ operands[2] = gen_reg_rtx (SImode); operands[3] = gen_reg_rtx (SImode); - operands[4] = force_reg (SImode, gen_rtx (CONST_INT, VOIDmode, 65535)); - operands[5] = force_reg (SImode, gen_rtx (CONST_INT, VOIDmode, -32768)); + operands[4] = force_reg (SImode, GEN_INT (65535)); + operands[5] = force_reg (SImode, GEN_INT (-32768)); }") (define_expand "extendqihi2" diff --git a/gnu/dist/gcc/config/tahoe/tahoe.c b/gnu/dist/gcc/config/tahoe/tahoe.c index 6fec44418f48..9dd189bde2f7 100644 --- a/gnu/dist/gcc/config/tahoe/tahoe.c +++ b/gnu/dist/gcc/config/tahoe/tahoe.c @@ -1,5 +1,5 @@ /* Subroutines for insn-output.c for Tahoe. - Copyright (C) 1989, 1991 Free Software Foundation, Inc. + Copyright (C) 1989, 1991, 1997 Free Software Foundation, Inc. This file is part of GNU CC. @@ -20,6 +20,7 @@ Boston, MA 02111-1307, USA. */ #include "config.h" +#include #include "rtl.h" #include "regs.h" #include "hard-reg-set.h" @@ -51,7 +52,7 @@ Boston, MA 02111-1307, USA. */ rtx tahoe_reg_conversion_loc; int -extendable_operand (op, mode) +extensible_operand (op, mode) rtx op; enum machine_mode mode; { @@ -67,8 +68,6 @@ extendable_operand (op, mode) /* since the modes are basically the same. I had to add a special case, */ /* though, for symbol references with offsets. */ -#include - print_operand_address (file, addr) FILE *file; register rtx addr; diff --git a/gnu/dist/gcc/config/tahoe/tahoe.h b/gnu/dist/gcc/config/tahoe/tahoe.h index b4076ce53b3b..29ac01392e72 100644 --- a/gnu/dist/gcc/config/tahoe/tahoe.h +++ b/gnu/dist/gcc/config/tahoe/tahoe.h @@ -575,9 +575,11 @@ enum reg_class {NO_REGS,GENERAL_REGS,FPP_REG,ALL_REGS,LIM_REG_CLASSES}; #define CASE_VECTOR_MODE HImode -/* each of the table elements in a case are relative to the jump address */ - -#define CASE_VECTOR_PC_RELATIVE +/* Define as C expression which evaluates to nonzero if the tablejump + instruction expects the table to contain offsets from the address of the + table. + Do not define this if the table should contain absolute addresses. */ +#define CASE_VECTOR_PC_RELATIVE 1 /* tahoe case instructions just fall through to the next instruction */ /* if not satisfied. It doesn't support a default action */ @@ -894,7 +896,7 @@ do { register int i; \ /* This is how to output an element of a case-vector that is relative. */ -#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, VALUE, REL) \ +#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) \ fprintf (FILE, "\t.word L%d-L%d\n", VALUE, REL) /* This is how to output an assembler line diff --git a/gnu/dist/gcc/config/tahoe/tahoe.md b/gnu/dist/gcc/config/tahoe/tahoe.md index 101d69f68227..021c1b010326 100644 --- a/gnu/dist/gcc/config/tahoe/tahoe.md +++ b/gnu/dist/gcc/config/tahoe/tahoe.md @@ -1,5 +1,5 @@ ;; Machine description for GNU compiler, Tahoe version -;; Copyright (C) 1989, 1994, 1996 Free Software Foundation, Inc. +;; Copyright (C) 1989, 1994, 1996, 1997 Free Software Foundation, Inc. ;; This file is part of GNU CC. @@ -1015,7 +1015,7 @@ "* { if (INTVAL (operands[1]) > 32767) - operands[1] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[1]) + 0xffff0000); + operands[1] = GEN_INT (INTVAL (operands[1]) + 0xffff0000); return \"cmpw %0,%1\"; }") @@ -1062,7 +1062,7 @@ "* { if (INTVAL (operands[1]) > 127) - operands[1] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[1]) + 0xffffff00); + operands[1] = GEN_INT (INTVAL (operands[1]) + 0xffffff00); return \"cmpb %0,%1\"; }") @@ -1143,7 +1143,7 @@ (define_insn "tsthi" [(set (cc0) - (match_operand:HI 0 "extendable_operand" "m,!r"))] + (match_operand:HI 0 "extensible_operand" "m,!r"))] "GET_MODE (operands[0]) != VOIDmode" "* { @@ -1179,7 +1179,7 @@ (define_insn "tstqi" [(set (cc0) - (match_operand:QI 0 "extendable_operand" "m,!r"))] + (match_operand:QI 0 "extensible_operand" "m,!r"))] "GET_MODE (operands[0]) != VOIDmode" "* { @@ -1591,7 +1591,7 @@ "" "* { - operands[1] = gen_rtx (CONST_INT, VOIDmode, (INTVAL (operands[1]) + 4)); + operands[1] = GEN_INT ((INTVAL (operands[1]) + 4)); if (GET_CODE(operands[0]) == MEM && CONSTANT_ADDRESS_P (XEXP(operands[0], 0)) && INTVAL (operands[1]) < 64) @@ -1609,7 +1609,7 @@ "" "* { - operands[2] = gen_rtx (CONST_INT, VOIDmode, (INTVAL (operands[2]) + 4)); + operands[2] = GEN_INT ((INTVAL (operands[2]) + 4)); if (GET_CODE(operands[1]) == MEM && CONSTANT_ADDRESS_P (XEXP(operands[1], 0)) && INTVAL (operands[2]) < 64) @@ -2057,7 +2057,7 @@ ; "* ;{ ; operands[1] -; = gen_rtx (CONST_INT, VOIDmode, exact_log2 (INTVAL (operands[1]))); +; = GEN_INT (exact_log2 (INTVAL (operands[1]))); ; return \"bbs %1,%0,%l2\"; ;}") ; @@ -2074,7 +2074,7 @@ ; "* ;{ ; operands[1] -; = gen_rtx (CONST_INT, VOIDmode, exact_log2 (INTVAL (operands[1]))); +; = GEN_INT (exact_log2 (INTVAL (operands[1]))); ; return \"bbc %1,%0,%l2\"; ;}") ; @@ -2091,7 +2091,7 @@ ; "* ;{ ; operands[1] -; = gen_rtx (CONST_INT, VOIDmode, exact_log2 (INTVAL (operands[1]))); +; = GEN_INT (exact_log2 (INTVAL (operands[1]))); ; return \"bbc %1,%0,%l2\"; ;}") ; @@ -2108,6 +2108,6 @@ ; "* ;{ ; operands[1] -; = gen_rtx (CONST_INT, VOIDmode, exact_log2 (INTVAL (operands[1]))); +; = GEN_INT (exact_log2 (INTVAL (operands[1]))); ; return \"bbs %1,%0,%l2\"; ;}") diff --git a/gnu/dist/gcc/config/v850/lib1funcs.asm b/gnu/dist/gcc/config/v850/lib1funcs.asm index 82ad0894d666..2787e97519a0 100644 --- a/gnu/dist/gcc/config/v850/lib1funcs.asm +++ b/gnu/dist/gcc/config/v850/lib1funcs.asm @@ -89,10 +89,11 @@ ___mulsi3: ble .L5 jmp [r31] /* return */ - .size __mulsi3,.-__mulsi3 + .size ___mulsi3,.-___mulsi3 #endif #ifdef L_udivsi3 + .text .global ___udivsi3 ___udivsi3: mov 1,r12 @@ -126,7 +127,7 @@ ___udivsi3: bne .L9 .L8: jmp [r31] - .size __udivsi3,.-__udivsi3 + .size ___udivsi3,.-___udivsi3 #endif #ifdef L_divsi3 @@ -157,7 +158,7 @@ ___divsi3: ld.w 4[sp],r31 add 8,sp jmp [r31] - .size __divsi3,.-__divsi3 + .size ___divsi3,.-___divsi3 #endif #ifdef L_umodsi3 @@ -178,7 +179,7 @@ ___umodsi3: ld.w 8[sp],r31 add 12,sp jmp [r31] - .size __umodsi3,.-__umodsi3 + .size ___umodsi3,.-___umodsi3 #endif /* L_umodsi3 */ #ifdef L_modsi3 @@ -199,7 +200,7 @@ ___modsi3: ld.w 8[sp],r31 add 12,sp jmp [r31] - .size __modsi3,.-__modsi3 + .size ___modsi3,.-___modsi3 #endif /* L_modsi3 */ #ifdef L_save_2 @@ -1172,7 +1173,7 @@ __save_interrupt: .size __save_interrupt,.-__save_interrupt /* Restore saved registers, deallocate stack and return from the interrupt */ - /* Called via: jr __return_interupt */ + /* Called via: jr __return_interrupt */ .align 2 .globl __return_interrupt .type __return_interrupt,@function @@ -1180,8 +1181,8 @@ __return_interrupt: ld.w 0[sp],ep ld.w 4[sp],gp ld.w 8[sp],r1 - ld.w 12[sp],r10 - add 16,sp + ld.w 12[sp],r10 + addi 16,sp,sp reti .size __return_interrupt,.-__return_interrupt #endif /* L_save_interrupt */ diff --git a/gnu/dist/gcc/config/v850/t-v850 b/gnu/dist/gcc/config/v850/t-v850 index d1d9b16f1b67..12af46b50374 100644 --- a/gnu/dist/gcc/config/v850/t-v850 +++ b/gnu/dist/gcc/config/v850/t-v850 @@ -50,3 +50,5 @@ fp-bit.c: $(srcdir)/config/fp-bit.c echo '#define FLOAT_BIT_ORDER_MISMATCH' >>fp-bit.c echo '#endif' >> fp-bit.c cat $(srcdir)/config/fp-bit.c >> fp-bit.c + +TCFLAGS = -Wa,-mwarn-signed-overflow -Wa,-mwarn-unsigned-overflow diff --git a/gnu/dist/gcc/config/v850/v850.c b/gnu/dist/gcc/config/v850/v850.c index 79ae10f9fbef..0962c779145a 100644 --- a/gnu/dist/gcc/config/v850/v850.c +++ b/gnu/dist/gcc/config/v850/v850.c @@ -399,16 +399,16 @@ print_operand (file, x, code) else if (TDA_NAME_P (name)) fprintf (file, "tdaoff"); else - abort(); + abort (); } else - abort(); + abort (); break; case 'P': if (special_symbolref_operand (x, VOIDmode)) output_addr_const (file, x); else - abort(); + abort (); break; case 'Q': if (special_symbolref_operand (x, VOIDmode)) @@ -429,10 +429,10 @@ print_operand (file, x, code) else if (TDA_NAME_P (name)) fprintf (file, "ep"); else - abort(); + abort (); } else - abort(); + abort (); break; case 'R': /* 2nd word of a double. */ switch (GET_CODE (x)) @@ -448,7 +448,7 @@ print_operand (file, x, code) break; case 'S': { - /* if it's a referance to a TDA variable, use sst/sld vs. st/ld */ + /* if it's a reference to a TDA variable, use sst/sld vs. st/ld */ if (GET_CODE (x) == MEM && ep_memory_operand (x, GET_MODE (x), FALSE)) fputs ("s", file); @@ -584,7 +584,7 @@ print_operand_address (file, addr) reg_name = "ep"; } else - abort(); + abort (); fprintf (file, "%s(", off_name); output_addr_const (file, addr); @@ -616,7 +616,7 @@ print_operand_address (file, addr) reg_name = "ep"; } else - abort(); + abort (); fprintf (file, "%s(", off_name); output_addr_const (file, addr); @@ -2082,11 +2082,11 @@ construct_restore_jr (op) last = 29; } - /* Paranoia */ - for (i = (first == 2 ? 20 : first + 1); i < 29; i++) - if ((mask & (1 << i)) == 0) - abort (); - + /* Note, it is possible to have gaps in the register mask. + We ignore this here, and generate a JR anyway. We will + be popping more registers thatn is strictly necessary, but + it does save code space. */ + if (first == last) sprintf (buff, "jr __return_%s", reg_names [first]); else @@ -2157,8 +2157,8 @@ pattern_is_ok_for_prologue (op, mode) return 0; /* If the register is being pushed somewhere other than the stack - space just aquired by the first operand then abandon this quest. - Note: the test is <= becuase both values are negative. */ + space just acquired by the first operand then abandon this quest. + Note: the test is <= because both values are negative. */ if (INTVAL (XEXP (plus, 1)) <= INTVAL (XEXP (SET_SRC (XVECEXP (op, 0, 0)), 1))) { @@ -2254,7 +2254,7 @@ construct_save_jarl (op) if (mask & (1 << 31)) { if (stack_bytes != -16) - abort(); + abort (); last = 31; } @@ -2268,11 +2268,11 @@ construct_save_jarl (op) last = 29; } - /* Paranoia */ - for (i = (first == 2 ? 20 : first + 1); i < 29; i++) - if ((mask & (1 << i)) == 0) - abort (); - + /* Note, it is possible to have gaps in the register mask. + We ignore this here, and generate a JARL anyway. We will + be pushing more registers thatn is strictly necessary, but + it does save code space. */ + if (first == last) sprintf (buff, "jarl __save_%s, r10", reg_names [first]); else diff --git a/gnu/dist/gcc/config/v850/v850.h b/gnu/dist/gcc/config/v850/v850.h index 063cf698e696..2ccbe98925b6 100644 --- a/gnu/dist/gcc/config/v850/v850.h +++ b/gnu/dist/gcc/config/v850/v850.h @@ -1,6 +1,5 @@ -/* Definitions of target machine for GNU compiler. - NEC V850 series - Copyright (C) 1996, 1997 Free Software Foundation, Inc. +/* Definitions of target machine for GNU compiler. NEC V850 series + Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc. Contributed by Jeff Law (law@cygnus.com). This file is part of GNU CC. @@ -79,11 +78,11 @@ extern int target_flags; * Doubles are normally 4 byte aligned, except in argument lists where they are 8 byte aligned. Is the alignment in the argument list based on the first parameter, - first stack parameter, etc etc. + first stack parameter, etc., etc. * Passing/returning of large structures probably isn't the same as GHS. We don't have enough documentation on their conventions - to be compatable. + to be compatible. * Tests of SETUP_INCOMING_VARARGS need to be made runtime checks since it depends on TARGET_GHS. */ @@ -209,6 +208,8 @@ extern struct small_memory_info small_memory[(int)SMALL_MEMORY_max]; LEVEL is the optimization level specified; 2 if `-O2' is specified, 1 if `-O' is specified, and 0 if neither is specified. + SIZE is non-zero if `-Os' is specified, 0 otherwise. + You should not use this macro to change options that are not machine-specific. These should uniformly selected by the same optimization level on all supported machines. Use this macro to @@ -217,7 +218,7 @@ extern struct small_memory_info small_memory[(int)SMALL_MEMORY_max]; *Do not examine `write_symbols' in this macro!* The debugging options are not supposed to alter the generated code. */ -#define OPTIMIZATION_OPTIONS(LEVEL) \ +#define OPTIMIZATION_OPTIONS(LEVEL,SIZE) \ { \ if (LEVEL) \ target_flags |= (MASK_EP | MASK_PROLOG_FUNCTION); \ @@ -348,7 +349,7 @@ extern struct small_memory_info small_memory[(int)SMALL_MEMORY_max]; On the 850, we make the return registers first, then all of the volatile registers, then the saved registers in reverse order to better save the - registers with an out of line function , and finnally the fixed + registers with an out of line function, and finally the fixed registers. */ #define REG_ALLOC_ORDER \ @@ -1007,7 +1008,7 @@ do { \ switch on CODE. There aren't DImode MOD, DIV or MULT operations, so call them - very expensive. Everything else is pretty much a costant cost. */ + very expensive. Everything else is pretty much a constant cost. */ #define RTX_COSTS(RTX,CODE,OUTER_CODE) \ case MOD: \ @@ -1197,11 +1198,10 @@ do { char dstr[30]; \ #define ASM_CLOSE_PAREN ")" /* This says how to output the assembler to define a global - uninitialized but not common symbol. - Try to use asm_output_bss to implement this macro. */ + uninitialized but not common symbol. */ -#define ASM_OUTPUT_BSS(FILE, DECL, NAME, SIZE, ROUNDED) \ - asm_output_bss ((FILE), (DECL), (NAME), (SIZE), (ROUNDED)) +#define ASM_OUTPUT_ALIGNED_BSS(FILE, DECL, NAME, SIZE, ALIGN) \ + asm_output_aligned_bss ((FILE), (DECL), (NAME), (SIZE), (ALIGN)) /* This is how to output the definition of a user-level label named NAME, such as the label on a static function or variable NAME. */ @@ -1287,7 +1287,7 @@ do { char dstr[30]; \ /* This is how to output an element of a case-vector that is relative. */ -#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, VALUE, REL) \ +#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) \ fprintf (FILE, "\t%s .L%d-.L%d\n", \ (TARGET_BIG_SWITCH ? ".long" : ".short"), \ VALUE, REL) @@ -1296,7 +1296,7 @@ do { char dstr[30]; \ if ((LOG) != 0) \ fprintf (FILE, "\t.align %d\n", (LOG)) -/* We don't have to worry about dbx compatability for the v850. */ +/* We don't have to worry about dbx compatibility for the v850. */ #define DEFAULT_GDB_EXTENSIONS 1 /* Use stabs debugging info by default. */ @@ -1318,14 +1318,15 @@ do { char dstr[30]; \ jumps to the default label instead. */ /* #define CASE_DROPS_THROUGH */ -/* We must use a PC relative entry for small tables. It would be more - efficient to use an absolute entry for big tables, but this is not - a runtime choice yet. */ -#define CASE_VECTOR_PC_RELATIVE +/* Define as C expression which evaluates to nonzero if the tablejump + instruction expects the table to contain offsets from the address of the + table. + Do not define this if the table should contain absolute addresses. */ +#define CASE_VECTOR_PC_RELATIVE 1 /* The switch instruction requires that the jump table immediately follow it. */ -#define JUMP_TABLES_IN_TEXT_SECTION +#define JUMP_TABLES_IN_TEXT_SECTION 1 /* svr4.h defines this assuming that 4 byte alignment is required. */ #undef ASM_OUTPUT_BEFORE_CASE_LABEL @@ -1386,7 +1387,7 @@ v850_valid_machine_decl_attribute (DECL, ATTRIBUTES, IDENTIFIER, ARGS) /* Tell compiler we want to support GHS pragmas */ #define HANDLE_GHS_PRAGMA -/* The assembler op to to start the file. */ +/* The assembler op to start the file. */ #define FILE_ASM_OP "\t.file\n" diff --git a/gnu/dist/gcc/config/v850/v850.md b/gnu/dist/gcc/config/v850/v850.md index c2095f2c294e..0ba10ca0cc02 100644 --- a/gnu/dist/gcc/config/v850/v850.md +++ b/gnu/dist/gcc/config/v850/v850.md @@ -46,7 +46,7 @@ ;; none_0hit - insn does not affect cc but it does modify operand 0 ;; This attribute is used to keep track of when operand 0 changes. ;; See the description of NOTICE_UPDATE_CC for more info. -;; set_znv - sets z,n,v to useable values; c is unknown. +;; set_znv - sets z,n,v to usable values; c is unknown. ;; set_zn - sets z,n to usable values; v,c is unknown. ;; compare - compare instruction ;; clobber - value of cc is unknown @@ -935,7 +935,7 @@ /* Shift index for the table array access. */ emit_insn (gen_ashlsi3 (reg, reg, GEN_INT (TARGET_BIG_SWITCH ? 2 : 1))); - /* Load the table address into a psuedo. */ + /* Load the table address into a pseudo. */ emit_insn (gen_movsi (tableaddress, gen_rtx (LABEL_REF, VOIDmode, operands[3]))); /* Add the table address to the index. */ @@ -1201,8 +1201,8 @@ ;; an interrupt function makes a call. ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and ;; all of memory. This blocks insns from being moved across this point. -;; This is needed because the rest of the compiler is not reading to handle -;; insns this compilcated +;; This is needed because the rest of the compiler is not ready to handle +;; insns this complicated. (define_insn "save_all_interrupt" [(unspec_volatile [(const_int 0)] 0)] @@ -1249,8 +1249,8 @@ ;; Restore all registers saved when an interrupt function makes a call. ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and ;; all of memory. This blocks insns from being moved across this point. -;; This is needed because the rest of the compiler is not reading to handle -;; insns this compilcated +;; This is needed because the rest of the compiler is not ready to handle +;; insns this complicated. (define_insn "restore_all_interrupt" [(unspec_volatile [(const_int 0)] 1)] diff --git a/gnu/dist/gcc/config/vax/ultrix.h b/gnu/dist/gcc/config/vax/ultrix.h index 7181e5b00193..3a14419c1027 100644 --- a/gnu/dist/gcc/config/vax/ultrix.h +++ b/gnu/dist/gcc/config/vax/ultrix.h @@ -7,3 +7,6 @@ #define PTRDIFF_TYPE "int" #define WCHAR_TYPE "unsigned int" #define WCHAR_TYPE_SIZE 32 + +/* True for Ultrix 4.3 and later and possibly earlier. */ +#define HAVE_ATEXIT diff --git a/gnu/dist/gcc/config/vax/vax.c b/gnu/dist/gcc/config/vax/vax.c index 35448cb5fa5d..bac442a467dc 100644 --- a/gnu/dist/gcc/config/vax/vax.c +++ b/gnu/dist/gcc/config/vax/vax.c @@ -1,5 +1,5 @@ /* Subroutines for insn-output.c for Vax. - Copyright (C) 1987, 1994, 1995, 1997 Free Software Foundation, Inc. + Copyright (C) 1987, 1994, 1995, 1997, 1998 Free Software Foundation, Inc. This file is part of GNU CC. @@ -18,8 +18,8 @@ along with GNU CC; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include #include "config.h" +#include #include "rtl.h" #include "regs.h" #include "hard-reg-set.h" @@ -614,34 +614,36 @@ check_float_value (mode, d, overflow) if (overflow) { - bcopy (&float_values[0], d, sizeof (REAL_VALUE_TYPE)); + bcopy ((char *) &float_values[0], (char *) d, sizeof (REAL_VALUE_TYPE)); return 1; } if ((mode) == SFmode) { REAL_VALUE_TYPE r; - bcopy (d, &r, sizeof (REAL_VALUE_TYPE)); + bcopy ((char *) d, (char *) &r, sizeof (REAL_VALUE_TYPE)); if (REAL_VALUES_LESS (float_values[0], r)) { - bcopy (&float_values[0], d, sizeof (REAL_VALUE_TYPE)); + bcopy ((char *) &float_values[0], (char *) d, + sizeof (REAL_VALUE_TYPE)); return 1; } else if (REAL_VALUES_LESS (r, float_values[1])) { - bcopy (&float_values[1], d, sizeof (REAL_VALUE_TYPE)); + bcopy ((char *) &float_values[1], (char*) d, + sizeof (REAL_VALUE_TYPE)); return 1; } else if (REAL_VALUES_LESS (dconst0, r) && REAL_VALUES_LESS (r, float_values[2])) { - bcopy (&dconst0, d, sizeof (REAL_VALUE_TYPE)); + bcopy ((char *) &dconst0, (char *) d, sizeof (REAL_VALUE_TYPE)); return 1; } else if (REAL_VALUES_LESS (r, dconst0) && REAL_VALUES_LESS (float_values[3], r)) { - bcopy (&dconst0, d, sizeof (REAL_VALUE_TYPE)); + bcopy ((char *) &dconst0, (char *) d, sizeof (REAL_VALUE_TYPE)); return 1; } } diff --git a/gnu/dist/gcc/config/vax/vax.h b/gnu/dist/gcc/config/vax/vax.h index 1d4d67ddb382..3b4c54999cce 100644 --- a/gnu/dist/gcc/config/vax/vax.h +++ b/gnu/dist/gcc/config/vax/vax.h @@ -144,6 +144,10 @@ extern int target_flags; /* Let's keep the stack somewhat aligned. */ #define STACK_BOUNDARY 32 + +/* The table of an ADDR_DIFF_VEC must be contiguous with the case + opcode, it is part of the case instruction. */ +#define ADDR_VEC_ALIGN(ADDR_VEC) 0 /* Standard register usage. */ @@ -344,7 +348,7 @@ enum reg_class { NO_REGS, ALL_REGS, LIM_REG_CLASSES }; return an rtx for the address of the word in the frame that holds the dynamic chain--the previous frame's address. */ #define DYNAMIC_CHAIN_ADDRESS(frame) \ -gen_rtx (PLUS, Pmode, frame, gen_rtx (CONST_INT, VOIDmode, 12)) +gen_rtx (PLUS, Pmode, frame, GEN_INT (12)) /* If we generate an insn to push BYTES bytes, this says how many the stack pointer really advances by. @@ -446,7 +450,7 @@ gen_rtx (PLUS, Pmode, frame, gen_rtx (CONST_INT, VOIDmode, 12)) /* This macro generates the assembly code for function entry. FILE is a stdio stream to output the code to. SIZE is an int: how many units of temporary storage to allocate, - adjusted by STARTING_FRAME_OFFSET to accomodate vms.h. + adjusted by STARTING_FRAME_OFFSET to accommodate vms.h. Refer to the array `regs_ever_live' to determine which registers to save; `regs_ever_live[I]' is nonzero if register number I is ever used in the function. This macro is responsible for @@ -529,10 +533,10 @@ gen_rtx (PLUS, Pmode, frame, gen_rtx (CONST_INT, VOIDmode, 12)) #define TRAMPOLINE_TEMPLATE(FILE) \ { \ ASM_OUTPUT_SHORT (FILE, const0_rtx); \ - ASM_OUTPUT_SHORT (FILE, gen_rtx (CONST_INT, VOIDmode, 0x8fd0)); \ + ASM_OUTPUT_SHORT (FILE, GEN_INT (0x8fd0)); \ ASM_OUTPUT_INT (FILE, const0_rtx); \ ASM_OUTPUT_BYTE (FILE, 0x50+STATIC_CHAIN_REGNUM); \ - ASM_OUTPUT_SHORT (FILE, gen_rtx (CONST_INT, VOIDmode, 0x9f17)); \ + ASM_OUTPUT_SHORT (FILE, GEN_INT (0x9f17)); \ ASM_OUTPUT_INT (FILE, const0_rtx); \ } @@ -813,10 +817,11 @@ gen_rtx (PLUS, Pmode, frame, gen_rtx (CONST_INT, VOIDmode, 12)) for the index in the tablejump instruction. */ #define CASE_VECTOR_MODE HImode -/* Define this if the case instruction expects the table - to contain offsets from the address of the table. - Do not define this if the table should contain absolute addresses. */ -#define CASE_VECTOR_PC_RELATIVE +/* Define as C expression which evaluates to nonzero if the tablejump + instruction expects the table to contain offsets from the address of the + table. + Do not define this if the table should contain absolute addresses. */ +#define CASE_VECTOR_PC_RELATIVE 1 /* Define this if the case instruction drops through after the table when the index is out of range. Don't define it if the case insn @@ -1158,7 +1163,7 @@ do { char dstr[30]; \ /* This is how to output an element of a case-vector that is relative. */ -#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, VALUE, REL) \ +#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) \ fprintf (FILE, "\t.word L%d-L%d\n", VALUE, REL) /* This is how to output an assembler line @@ -1220,7 +1225,7 @@ do { \ fprintf (FILE, "\t.word 0x0ffc\n"); \ fprintf (FILE, "\taddl2 $%d,4(ap)\n", DELTA); \ fprintf (FILE, "\tjmp "); \ - assemble_name (FILE, IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (FUNCTION))); \ + assemble_name (FILE, XSTR (XEXP (DECL_RTL (FUNCTION), 0), 0)); \ fprintf (FILE, "+2\n"); \ } while (0) diff --git a/gnu/dist/gcc/config/vax/vax.md b/gnu/dist/gcc/config/vax/vax.md index c3a2ae395880..4ca4668929d0 100644 --- a/gnu/dist/gcc/config/vax/vax.md +++ b/gnu/dist/gcc/config/vax/vax.md @@ -1,5 +1,5 @@ ;;- Machine description for GNU compiler, Vax Version -;; Copyright (C) 1987, 88, 91, 94, 95, 1996 Free Software Foundation, Inc. +;; Copyright (C) 1987, 88, 91, 94-96, 1998 Free Software Foundation, Inc. ;; This file is part of GNU CC. @@ -874,7 +874,7 @@ "* { if (CONST_DOUBLE_HIGH (operands[3])) - operands[3] = gen_rtx (CONST_INT, VOIDmode, CONST_DOUBLE_LOW (operands[3])); + operands[3] = GEN_INT (CONST_DOUBLE_LOW (operands[3])); return \"emul %1,%2,%3,%0\"; }") @@ -956,7 +956,7 @@ } if (GET_CODE (op1) == CONST_INT) - operands[1] = gen_rtx (CONST_INT, VOIDmode, ~INTVAL (op1)); + operands[1] = GEN_INT (~INTVAL (op1)); else operands[1] = expand_unop (SImode, one_cmpl_optab, op1, 0, 1); }") @@ -978,7 +978,7 @@ } if (GET_CODE (op1) == CONST_INT) - operands[1] = gen_rtx (CONST_INT, VOIDmode, 65535 & ~INTVAL (op1)); + operands[1] = GEN_INT (65535 & ~INTVAL (op1)); else operands[1] = expand_unop (HImode, one_cmpl_optab, op1, 0, 1); }") @@ -1000,7 +1000,7 @@ } if (GET_CODE (op1) == CONST_INT) - operands[1] = gen_rtx (CONST_INT, VOIDmode, 255 & ~INTVAL (op1)); + operands[1] = GEN_INT (255 & ~INTVAL (op1)); else operands[1] = expand_unop (QImode, one_cmpl_optab, op1, 0, 1); }") @@ -1837,32 +1837,35 @@ ;; Note that operand 1 is total size of args, in bytes, ;; and what the call insn wants is the number of words. +;; It is used in the call instruction as a byte, but in the addl2 as +;; a word. Since the only time we actually use it in the call instruction +;; is when it is a constant, SImode (for addl2) is the proper mode. (define_insn "call_pop" [(call (match_operand:QI 0 "memory_operand" "m") - (match_operand:QI 1 "general_operand" "g")) + (match_operand:SI 1 "const_int_operand" "n")) (set (reg:SI 14) (plus:SI (reg:SI 14) (match_operand:SI 3 "immediate_operand" "i")))] "" "* - if (GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) > 255 * 4) + if (INTVAL (operands[1]) > 255 * 4) /* Vax `calls' really uses only one byte of #args, so pop explicitly. */ return \"calls $0,%0\;addl2 %1,sp\"; - operands[1] = gen_rtx (CONST_INT, VOIDmode, (INTVAL (operands[1]) + 3)/ 4); + operands[1] = GEN_INT ((INTVAL (operands[1]) + 3)/ 4); return \"calls %1,%0\"; ") (define_insn "call_value_pop" [(set (match_operand 0 "" "=g") (call (match_operand:QI 1 "memory_operand" "m") - (match_operand:QI 2 "general_operand" "g"))) + (match_operand:SI 2 "const_int_operand" "n"))) (set (reg:SI 14) (plus:SI (reg:SI 14) (match_operand:SI 4 "immediate_operand" "i")))] "" "* - if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) > 255 * 4) + if (INTVAL (operands[2]) > 255 * 4) /* Vax `calls' really uses only one byte of #args, so pop explicitly. */ return \"calls $0,%1\;addl2 %2,sp\"; - operands[2] = gen_rtx (CONST_INT, VOIDmode, (INTVAL (operands[2]) + 3)/ 4); + operands[2] = GEN_INT ((INTVAL (operands[2]) + 3)/ 4); return \"calls %2,%1\"; ") @@ -1870,28 +1873,28 @@ ;; operands. In that case, combine may simplify the adjustment of sp. (define_insn "" [(call (match_operand:QI 0 "memory_operand" "m") - (match_operand:QI 1 "general_operand" "g")) + (match_operand:SI 1 "const_int_operand" "n")) (set (reg:SI 14) (reg:SI 14))] "" "* - if (GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) > 255 * 4) + if (INTVAL (operands[1]) > 255 * 4) /* Vax `calls' really uses only one byte of #args, so pop explicitly. */ return \"calls $0,%0\;addl2 %1,sp\"; - operands[1] = gen_rtx (CONST_INT, VOIDmode, (INTVAL (operands[1]) + 3)/ 4); + operands[1] = GEN_INT ((INTVAL (operands[1]) + 3)/ 4); return \"calls %1,%0\"; ") (define_insn "" [(set (match_operand 0 "" "=g") (call (match_operand:QI 1 "memory_operand" "m") - (match_operand:QI 2 "general_operand" "g"))) + (match_operand:SI 2 "const_int_operand" "n"))) (set (reg:SI 14) (reg:SI 14))] "" "* - if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) > 255 * 4) + if (INTVAL (operands[2]) > 255 * 4) /* Vax `calls' really uses only one byte of #args, so pop explicitly. */ return \"calls $0,%1\;addl2 %2,sp\"; - operands[2] = gen_rtx (CONST_INT, VOIDmode, (INTVAL (operands[2]) + 3)/ 4); + operands[2] = GEN_INT ((INTVAL (operands[2]) + 3)/ 4); return \"calls %2,%1\"; ") @@ -2110,7 +2113,7 @@ unsigned long mask2 = (1 << (32 - INTVAL (operands[2]))) - 1; if ((mask1 & mask2) != mask1) - operands[3] = gen_rtx (CONST_INT, VOIDmode, mask1 & mask2); + operands[3] = GEN_INT (mask1 & mask2); return \"rotl %R2,%1,%0\;bicl2 %N3,%0\"; }") @@ -2128,7 +2131,6 @@ "" "* { - operands[3] = gen_rtx (CONST_INT, VOIDmode, - INTVAL (operands[3]) & ~((1 << INTVAL (operands[2])) - 1)); + operands[3] = GEN_INT (INTVAL (operands[3]) & ~((1 << INTVAL (operands[2])) - 1)); return \"rotl %2,%1,%0\;bicl2 %N3,%0\"; }") diff --git a/gnu/dist/gcc/config/vax/vms.h b/gnu/dist/gcc/config/vax/vms.h index d8580b5c1a13..35c1665f05a3 100644 --- a/gnu/dist/gcc/config/vax/vms.h +++ b/gnu/dist/gcc/config/vax/vms.h @@ -264,7 +264,7 @@ const_section () \ else \ data_section (); \ } \ - if (*tree_code_type[(int) TREE_CODE (T)] == 'c') \ + if (TREE_CODE_CLASS (TREE_CODE (T)) == 'c') \ { \ if ((TREE_CODE (T) == STRING_CST && flag_writable_strings)) \ data_section (); \ @@ -304,9 +304,9 @@ const_section () \ /* The following definitions are used in libgcc2.c with the __main function. The _SHR symbol is used when the sharable image library - for libg++ is used - this is picked up automatically by the linker - and this symbol points to the start of the __CTOR_LIST__ from libg++. - If libg++ is not being used, then __CTOR_LIST_SHR__ occurs just after + for the C++ library is used - this is picked up automatically by the linker + and this symbol points to the start of __CTOR_LIST__ from the C++ library. + If the C++ library is not used, then __CTOR_LIST_SHR__ occurs just after __CTOR_LIST__, and essentially points to the same list as __CTOR_LIST. */ #ifdef L__main @@ -357,3 +357,13 @@ do { \ } while (0) #endif /* L__main */ + +/* Specify the list of include file directories. */ +#define INCLUDE_DEFAULTS \ +{ \ + { "GNU_GXX_INCLUDE:", "G++", 1, 1 }, \ + { "GNU_CC_INCLUDE:", "GCC", 0, 0 }, /* GNU includes */ \ + { "SYS$SYSROOT:[SYSLIB.]", 0, 0, 0 }, /* VAX-11 "C" includes */ \ + { ".", 0, 0, 1 }, /* Make normal VMS filespecs work. */ \ + { 0, 0, 0, 0 } \ +} diff --git a/gnu/dist/gcc/config/vax/xm-vaxv.h b/gnu/dist/gcc/config/vax/xm-vaxv.h index 18a1d73ac985..aef16f043214 100644 --- a/gnu/dist/gcc/config/vax/xm-vaxv.h +++ b/gnu/dist/gcc/config/vax/xm-vaxv.h @@ -1,7 +1,3 @@ /* Config file for Vax running system V. */ #define USG - -#define bcopy(a,b,c) memcpy (b,a,c) -#define bzero(a,b) memset (a,0,b) -#define bcmp(a,b,c) memcmp (a,b,c) diff --git a/gnu/dist/gcc/config/vax/xm-vms.h b/gnu/dist/gcc/config/vax/xm-vms.h index 430905b0483e..5d01aeb23ee4 100644 --- a/gnu/dist/gcc/config/vax/xm-vms.h +++ b/gnu/dist/gcc/config/vax/xm-vms.h @@ -22,6 +22,14 @@ Boston, MA 02111-1307, USA. */ #define FALSE 0 #define TRUE 1 +/* Other configurations get these via autoconfig. */ +#define STDC_HEADERS 1 +#define HAVE_STDLIB_H 1 +#define HAVE_STRING_H 1 +#ifdef __DECC +#define HAVE_UNISTD_H 1 +#endif + #if defined(VAXC) || defined(__DECC) /* if compiling with VAXC, need to fix problem with which defines a macro called FILE_TYPE that breaks "tree.h". @@ -69,16 +77,6 @@ Boston, MA 02111-1307, USA. */ /* and define a local equivalent (sort of) for unlink */ #define unlink remove -/* Specify the list of include file directories. */ -#define INCLUDE_DEFAULTS \ -{ \ - { "GNU_GXX_INCLUDE:", 1, 1 }, \ - { "GNU_CC_INCLUDE:", 0, 0 }, /* GNU includes */ \ - { "SYS$SYSROOT:[SYSLIB.]", 0, 0 }, /* VAX-11 "C" includes */ \ - { ".", 0, 1 }, /* Make normal VMS filespecs work. */ \ - { 0, 0, 0 } \ -} - /* Used by the preprocessor to limit size of disk I/O chunks. 64K - 1 is the maximum supported by VAXCRTL. Amounts in excess of 35 blocks will bypass the VMS V6.x VIOC [Virtual I/O Cache], @@ -136,22 +134,16 @@ Boston, MA 02111-1307, USA. */ #define HAVE_VPRINTF #if defined(VAXC) || defined(__DECC) + /* Customizations/kludges for building with DEC's VAX C compiler rather than GCC. */ + #define NO_SYS_PARAMS_H /* don't have */ -#define NO_STAB_H /* don't have */ #define USE_C_ALLOCA /* using alloca.c */ #define QSORT_WORKAROUND /* do not use VAXCRTL's qsort */ /* use ANSI/SYSV style byte manipulation routines instead of BSD ones */ -#define bcopy(s,d,n) memcpy((d),(s),(n)) -#define bzero(d,n) memset((d),0,(n)) -#define bcmp(l,r,n) memcmp((l),(r),(n)) -#define index strchr -#define rindex strrchr - /* rename all too-long external symbol names to avoid warnings */ -#define bc_check_for_full_enumeration_handling bc_check_for_full_enum_handling #define check_for_full_enumeration_handling check_for_full_enum_handling #define current_function_contains_functions curfunc_contains_functions #define current_function_epilogue_delay_list curfunc_epilogue_delay_list @@ -165,11 +157,14 @@ Boston, MA 02111-1307, USA. */ #define current_function_uses_const_pool curfunc_uses_const_pool #define current_function_uses_pic_offset_table curfunc_uses_pic_offset_table #define dbxout_resume_previous_source_file dbxout_resume_previous_src_file +#define expand_builtin_extract_return_addr expand_builtin_extract_ret_addr +#define expand_builtin_set_return_addr_reg expand_builtin_set_ret_addr_reg #define expand_start_loop_continue_elsewhere expnd_start_loop_cont_elsewhere #define flag_schedule_insns_after_reload flag_sched_insns_after_reload #define get_dynamic_handler_chain_libfunc get_dynamic_hndlr_chain_libfunc #define lookup_name_current_level_global lookup_name_current_level_gbl #define maybe_building_objc_message_expr maybe_building_objc_msg_expr +#define mesg_implicit_function_declaration mesg_implicit_func_declaration #define output_deferred_addressed_constants output_deferred_addr_constants #define protect_cleanup_actions_with_terminate protect_cleanup_act_w_terminate #define reg_overlap_mentioned_for_reload_p reg_overlap_mtnd_for_reload_p diff --git a/gnu/dist/gcc/config/we32k/we32k.c b/gnu/dist/gcc/config/we32k/we32k.c index 3dceb07e8c98..0c02686d703a 100644 --- a/gnu/dist/gcc/config/we32k/we32k.c +++ b/gnu/dist/gcc/config/we32k/we32k.c @@ -1,6 +1,6 @@ /* Subroutines for insn-output.c for AT&T we32000 Family. Contributed by John Wehle (john@feith1.uucp) - Copyright (C) 1991-1992 Free Software Foundation, Inc. + Copyright (C) 1991, 1992, 1997 Free Software Foundation, Inc. This file is part of GNU CC. @@ -20,8 +20,8 @@ the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include #include "config.h" +#include #include "rtl.h" #include "real.h" @@ -85,10 +85,8 @@ output_move_double (operands) } else if (GET_CODE (operands[1]) == CONST_DOUBLE) { - lsw_operands[1] = gen_rtx (CONST_INT, SImode, - CONST_DOUBLE_HIGH (operands[1])); - operands[1] = gen_rtx (CONST_INT, SImode, - CONST_DOUBLE_LOW (operands[1])); + lsw_operands[1] = GEN_INT (CONST_DOUBLE_HIGH (operands[1])); + operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1])); } else if (GET_CODE (operands[1]) == CONST_INT) { @@ -122,10 +120,8 @@ output_push_double (operands) lsw_operands[0] = adj_offsettable_operand (operands[0], 4); else if (GET_CODE (operands[0]) == CONST_DOUBLE) { - lsw_operands[0] = gen_rtx (CONST_INT, SImode, - CONST_DOUBLE_HIGH (operands[0])); - operands[0] = gen_rtx (CONST_INT, SImode, - CONST_DOUBLE_LOW (operands[0])); + lsw_operands[0] = GEN_INT (CONST_DOUBLE_HIGH (operands[0])); + operands[0] = GEN_INT (CONST_DOUBLE_LOW (operands[0])); } else if (GET_CODE (operands[0]) == CONST_INT) { diff --git a/gnu/dist/gcc/config/we32k/we32k.h b/gnu/dist/gcc/config/we32k/we32k.h index 460fc3d28201..07f00107d59f 100644 --- a/gnu/dist/gcc/config/we32k/we32k.h +++ b/gnu/dist/gcc/config/we32k/we32k.h @@ -480,11 +480,11 @@ enum reg_class { NO_REGS, GENERAL_REGS, #define TRAMPOLINE_TEMPLATE(FILE) \ { \ - ASM_OUTPUT_SHORT (FILE, gen_rtx (CONST_INT, VOIDmode, 0x844f)); \ + ASM_OUTPUT_SHORT (FILE, GEN_INT (0x844f)); \ ASM_OUTPUT_SHORT (FILE, const0_rtx); \ ASM_OUTPUT_SHORT (FILE, const0_rtx); \ - ASM_OUTPUT_CHAR (FILE, gen_rtx (CONST_INT, VOIDmode, 0x48)); \ - ASM_OUTPUT_SHORT (FILE, gen_rtx (CONST_INT, VOIDmode, 0x247f)); \ + ASM_OUTPUT_CHAR (FILE, GEN_INT (0x48)); \ + ASM_OUTPUT_SHORT (FILE, GEN_INT (0x247f)); \ ASM_OUTPUT_SHORT (FILE, const0_rtx); \ ASM_OUTPUT_SHORT (FILE, const0_rtx); \ } @@ -625,10 +625,11 @@ enum reg_class { NO_REGS, GENERAL_REGS, for the index in the tablejump instruction. */ #define CASE_VECTOR_MODE SImode -/* Define this if the tablejump instruction expects the table - to contain offsets from the address of the table. - Do not define this if the table should contain absolute addresses. */ -/* #define CASE_VECTOR_PC_RELATIVE */ +/* Define as C expression which evaluates to nonzero if the tablejump + instruction expects the table to contain offsets from the address of the + table. + Do not define this if the table should contain absolute addresses. */ +/* #define CASE_VECTOR_PC_RELATIVE 1 */ /* Specify the tree operation to be used to convert reals to integers. */ #define IMPLICIT_FIX_EXPR FIX_ROUND_EXPR @@ -888,7 +889,7 @@ do { \ /* This is how to output an element of a case-vector that is relative. */ -#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, VALUE, REL) \ +#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) \ fprintf (FILE, "\t.word .L%d-.L%d\n", VALUE, REL) /* This is how to output an assembler line diff --git a/gnu/dist/gcc/config/we32k/we32k.md b/gnu/dist/gcc/config/we32k/we32k.md index 216b1ff04e29..9d85a1026db9 100644 --- a/gnu/dist/gcc/config/we32k/we32k.md +++ b/gnu/dist/gcc/config/we32k/we32k.md @@ -140,10 +140,8 @@ else if (GET_CODE (operands[2]) == CONST_DOUBLE) { - lsw_operands[2] = gen_rtx(CONST_INT, SImode, - CONST_DOUBLE_HIGH(operands[2])); - operands[2] = gen_rtx(CONST_INT, SImode, - CONST_DOUBLE_LOW(operands[2])); + lsw_operands[2] = GEN_INT (CONST_DOUBLE_HIGH(operands[2])); + operands[2] = GEN_INT (CONST_DOUBLE_LOW(operands[2])); } else if (GET_CODE (operands[2]) == CONST_INT) @@ -192,10 +190,8 @@ else if (GET_CODE (operands[1]) == CONST_DOUBLE) { - lsw_operands[1] = gen_rtx(CONST_INT, SImode, - CONST_DOUBLE_HIGH(operands[1])); - operands[1] = gen_rtx(CONST_INT, SImode, - CONST_DOUBLE_LOW(operands[1])); + lsw_operands[1] = GEN_INT (CONST_DOUBLE_HIGH(operands[1])); + operands[1] = GEN_INT (CONST_DOUBLE_LOW(operands[1])); } else if (GET_CODE (operands[1]) == CONST_INT) @@ -214,10 +210,8 @@ else if (GET_CODE (operands[2]) == CONST_DOUBLE) { - lsw_operands[2] = gen_rtx(CONST_INT, SImode, - CONST_DOUBLE_HIGH(operands[2])); - operands[2] = gen_rtx(CONST_INT, SImode, - CONST_DOUBLE_LOW(operands[2])); + lsw_operands[2] = GEN_INT (CONST_DOUBLE_HIGH(operands[2])); + operands[2] = GEN_INT (CONST_DOUBLE_LOW(operands[2])); } else if (GET_CODE (operands[2]) == CONST_INT) @@ -310,10 +304,8 @@ else if (GET_CODE (operands[2]) == CONST_DOUBLE) { - lsw_operands[2] = gen_rtx(CONST_INT, SImode, - CONST_DOUBLE_HIGH(operands[2])); - operands[2] = gen_rtx(CONST_INT, SImode, - CONST_DOUBLE_LOW(operands[2])); + lsw_operands[2] = GEN_INT (CONST_DOUBLE_HIGH(operands[2])); + operands[2] = GEN_INT (CONST_DOUBLE_LOW(operands[2])); } else if (GET_CODE (operands[2]) == CONST_INT) @@ -362,10 +354,8 @@ else if (GET_CODE (operands[1]) == CONST_DOUBLE) { - lsw_operands[1] = gen_rtx(CONST_INT, SImode, - CONST_DOUBLE_HIGH(operands[1])); - operands[1] = gen_rtx(CONST_INT, SImode, - CONST_DOUBLE_LOW(operands[1])); + lsw_operands[1] = GEN_INT (CONST_DOUBLE_HIGH(operands[1])); + operands[1] = GEN_INT (CONST_DOUBLE_LOW(operands[1])); } else if (GET_CODE (operands[1]) == CONST_INT) @@ -384,10 +374,8 @@ else if (GET_CODE (operands[2]) == CONST_DOUBLE) { - lsw_operands[2] = gen_rtx(CONST_INT, SImode, - CONST_DOUBLE_HIGH(operands[2])); - operands[2] = gen_rtx(CONST_INT, SImode, - CONST_DOUBLE_LOW(operands[2])); + lsw_operands[2] = GEN_INT (CONST_DOUBLE_HIGH(operands[2])); + operands[2] = GEN_INT (CONST_DOUBLE_LOW(operands[2])); } else if (GET_CODE (operands[2]) == CONST_INT) @@ -770,7 +758,7 @@ if (GET_CODE (operands[1]) == CONST_INT && ((unsigned long)INTVAL (operands[1]) & 0x8000L)) - operands[1] = gen_rtx(CONST_INT, SImode, INTVAL(operands[1]) | 0xffff0000L); + operands[1] = GEN_INT (INTVAL(operands[1]) | 0xffff0000L); output_asm_insn(\"CMPH %1, %0\",operands); @@ -786,7 +774,7 @@ if (GET_CODE (operands[1]) == CONST_INT && ((unsigned long)INTVAL (operands[1]) & 0x80L)) - operands[1] = gen_rtx(CONST_INT, SImode, INTVAL(operands[1]) | 0xffffff00L); + operands[1] = GEN_INT (INTVAL(operands[1]) | 0xffffff00L); output_asm_insn(\"CMPB {sbyte}%1, {sbyte}%0\",operands); @@ -910,7 +898,7 @@ "* { - operands[2] = gen_rtx(CONST_INT, SImode, INTVAL(operands[2]) - 1); + operands[2] = GEN_INT (INTVAL(operands[2]) - 1); output_asm_insn(\"EXTFW %2, %3, %1, %0\",operands); return \"\"; @@ -925,7 +913,7 @@ "* { - operands[2] = gen_rtx(CONST_INT, SImode, INTVAL(operands[2]) - 1); + operands[2] = GEN_INT (INTVAL(operands[2]) - 1); output_asm_insn(\"EXTFH %2, %3, {uhalf}%1, {uword}%0\",operands); return \"\"; @@ -940,7 +928,7 @@ "* { - operands[2] = gen_rtx(CONST_INT, SImode, INTVAL(operands[2]) - 1); + operands[2] = GEN_INT (INTVAL(operands[2]) - 1); output_asm_insn(\"EXTFB %2, %3, {ubyte}%1, {uword}%0\",operands); return \"\"; @@ -955,7 +943,7 @@ "* { - operands[1] = gen_rtx(CONST_INT, SImode, INTVAL(operands[1]) - 1); + operands[1] = GEN_INT (INTVAL(operands[1]) - 1); output_asm_insn(\"INSFW %1, %2, %3, %0\",operands); return \"\"; @@ -970,7 +958,7 @@ "* { - operands[1] = gen_rtx(CONST_INT, SImode, INTVAL(operands[1]) - 1); + operands[1] = GEN_INT (INTVAL(operands[1]) - 1); output_asm_insn(\"INSFH %1, %2, {uword}%3, {uhalf}%0\",operands); return \"\"; @@ -985,7 +973,7 @@ "* { - operands[1] = gen_rtx(CONST_INT, SImode, INTVAL(operands[1]) - 1); + operands[1] = GEN_INT (INTVAL(operands[1]) - 1); output_asm_insn(\"INSFB %1, %2, {uword}%3, {ubyte}%0\",operands); return \"\"; diff --git a/gnu/dist/gcc/config/winnt/config-nt.sed b/gnu/dist/gcc/config/winnt/config-nt.sed index ee0088ad8183..9beceabf2ec8 100644 --- a/gnu/dist/gcc/config/winnt/config-nt.sed +++ b/gnu/dist/gcc/config/winnt/config-nt.sed @@ -13,7 +13,7 @@ s/$(srcdir)\/c-gperf/c-gperf/g /^lang_specs_files=/ d /^lang_options_files=/ d /^version=/ c\ -version=2.7.2 +version=2.8.1 s/CC = cc/CC = cl/ s/^SHELL =.*/SHELL =/ s/CFLAGS = -g/CFLAGS =/ @@ -38,7 +38,7 @@ GCC_FOR_TARGET = xgcc ENQUIRE_LDFLAGS = s/; *@true// /> *stamp-objlist/ c\ - echo.exe $(OBJS) $(BC_OBJS) | sed -e "s, \([a-z]\), ../\1,g" >stamp-objlist + echo.exe $(OBJS) | sed -e "s, \([a-z]\), ../\1,g" >stamp-objlist /^OBJS.*stamp-objlist/ s?`cat ../stamp-objlist`?@../stamp-objlist? s/^\(SUBDIR_OBSTACK *=\).*$/\1 ..\/obstack.o/ s/^\(SUBDIR_USE_ALLOCA *=\).*$/\1/ @@ -90,9 +90,6 @@ USE_HOST_ALLOCA=alloca.obj s/^ALLOCA =/ALLOCA = alloca.obj/ s/^ALLOCA_FINISH = true/ALLOCA_FINISH =/ s/ \.\// / -s/^bi-\([a-z]*\) *:/bi-\1.exe :/ -s/ bi-\([a-z]*\)$/ bi-\1.exe/ -s/ bi-\([a-z]*\) / bi-\1.exe /g s/^gen\([a-z]*\) *:/gen\1.exe :/ s/ gen\([a-z]*\)$/ gen\1.exe/ s/ gen\([a-z]*\) / gen\1.exe /g diff --git a/gnu/dist/gcc/config/winnt/win-nt.h b/gnu/dist/gcc/config/winnt/win-nt.h index 4b93f8c118d9..14f3f87bcdbe 100644 --- a/gnu/dist/gcc/config/winnt/win-nt.h +++ b/gnu/dist/gcc/config/winnt/win-nt.h @@ -1,6 +1,6 @@ /* Operating system specific defines to be used when targeting GCC for Windows NT 3.x. - Copyright (C) 1994, 1995 Free Software Foundation, Inc. + Copyright (C) 1994, 1995, 1997 Free Software Foundation, Inc. Contributed by Douglas B. Rupp (drupp@cs.washington.edu). This file is part of GNU CC. @@ -29,7 +29,7 @@ Boston, MA 02111-1307, USA. */ #define LINK_SPEC "-stack 5000000,5000000 -noinhibit-exec %{g}" #undef CPP_SPEC -#define CPP_SPEC "-lang-c-c++-comments" +#define CPP_SPEC "" #undef STANDARD_EXEC_PREFIX #define STANDARD_EXEC_PREFIX "" @@ -51,7 +51,7 @@ Boston, MA 02111-1307, USA. */ #undef INCLUDE_DEFAULTS #define INCLUDE_DEFAULTS \ { \ - { 0, 0, 0 } \ + { 0, 0, 0, 0 } \ } #undef STDC_VALUE diff --git a/gnu/dist/gcc/config/winnt/xm-winnt.h b/gnu/dist/gcc/config/winnt/xm-winnt.h index be62d020138d..f56073cb8de8 100644 --- a/gnu/dist/gcc/config/winnt/xm-winnt.h +++ b/gnu/dist/gcc/config/winnt/xm-winnt.h @@ -1,5 +1,5 @@ /* Configuration for GNU compiler for processor running Windows NT 3.x. - Copyright (C) 1993, 1995 Free Software Foundation, Inc. + Copyright (C) 1993, 1995, 1997 Free Software Foundation, Inc. Contributed by Douglas B. Rupp (drupp@cs.washington.edu) This file is part of GNU CC. @@ -42,11 +42,6 @@ Boston, MA 02111-1307, USA. */ #endif #define NO_SYS_SIGLIST 1 -#define bcmp(a,b,c) memcmp (a,b,c) -#define bcopy(a,b,c) memcpy (b,a,c) -#define bzero(a,b) memset (a,0,b) -#define index strchr -#define rindex strrchr #define kill(a,b) raise(b) #define OBJECT_SUFFIX ".obj" @@ -66,4 +61,3 @@ Boston, MA 02111-1307, USA. */ #define S_IRWXU S_IRUSR | S_IWUSR | S_IXUSR #define S_ISREG(m) (((m)&S_IFMT) == S_IFREG) #define S_ISDIR(m) (((m)&S_IFMT) == S_IFDIR) - diff --git a/gnu/dist/gcc/ginclude/ppc-asm.h b/gnu/dist/gcc/ginclude/ppc-asm.h index 9e830dcc6ebf..4512d94352a3 100644 --- a/gnu/dist/gcc/ginclude/ppc-asm.h +++ b/gnu/dist/gcc/ginclude/ppc-asm.h @@ -1,5 +1,5 @@ /* PowerPC asm definitions for GNU C. */ -/* Under winnt, 1) gas suppports the following as names and 2) in particular +/* Under winnt, 1) gas supports the following as names and 2) in particular defining "toc" breaks the FUNC_START macro as ".toc" becomes ".2" */ #if !defined(__WINNT__) diff --git a/gnu/dist/gcc/ginclude/stdarg.h b/gnu/dist/gcc/ginclude/stdarg.h index 431439c152f7..24f3383198d4 100644 --- a/gnu/dist/gcc/ginclude/stdarg.h +++ b/gnu/dist/gcc/ginclude/stdarg.h @@ -96,7 +96,7 @@ void va_end (__gnuc_va_list); /* Defined in libgcc.a */ /* We cast to void * and then to TYPE * because this avoids a warning about increasing the alignment requirement. */ -#if defined (__arm__) || defined (__i386__) || defined (__i860__) || defined (__ns32000__) || defined (__vax__) +#if (defined (__arm__) && ! defined (__ARMEB__)) || defined (__i386__) || defined (__i860__) || defined (__ns32000__) || defined (__vax__) /* This is for little-endian machines; small args are padded upward. */ #define va_arg(AP, TYPE) \ (AP = (__gnuc_va_list) ((char *) (AP) + __va_rounded_size (TYPE)), \ diff --git a/gnu/dist/gcc/ginclude/stdbool.h b/gnu/dist/gcc/ginclude/stdbool.h new file mode 100644 index 000000000000..0baf9ce42bdc --- /dev/null +++ b/gnu/dist/gcc/ginclude/stdbool.h @@ -0,0 +1,20 @@ +/* stdbool.h for GNU. */ +#ifndef __STDBOOL_H__ +#define __STDBOOL_H__ 1 + +/* The type `bool' must promote to `int' or `unsigned int'. The constants + `true' and `false' must have the value 0 and 1 respectively. */ +typedef enum + { + false = 0, + true = 1 + } bool; + +/* The names `true' and `false' must also be made available as macros. */ +#define false false +#define true true + +/* Signal that all the definitions are present. */ +#define __bool_true_false_are_defined 1 + +#endif /* stdbool.h */ diff --git a/gnu/dist/gcc/ginclude/stddef.h b/gnu/dist/gcc/ginclude/stddef.h index 23d8455c649c..615052e85d4e 100644 --- a/gnu/dist/gcc/ginclude/stddef.h +++ b/gnu/dist/gcc/ginclude/stddef.h @@ -135,6 +135,7 @@ typedef __PTRDIFF_TYPE__ ptrdiff_t; /* Define this type if we are doing the whole job, or if we want this type in particular. */ #if defined (_STDDEF_H) || defined (__need_size_t) +#ifndef __size_t__ /* BeOS */ #ifndef _SIZE_T /* in case has defined it. */ #ifndef _SYS_SIZE_T_H #ifndef _T_SIZE_ @@ -148,6 +149,7 @@ typedef __PTRDIFF_TYPE__ ptrdiff_t; #ifndef _GCC_SIZE_T #ifndef _SIZET_ #ifndef __size_t +#define __size_t__ /* BeOS */ #define _SIZE_T #define _SYS_SIZE_T_H #define _T_SIZE_ @@ -166,6 +168,9 @@ typedef __PTRDIFF_TYPE__ ptrdiff_t; #endif #if !(defined (__GNUG__) && defined (size_t)) typedef __SIZE_TYPE__ size_t; +#ifdef __BEOS__ +typedef long ssize_t; +#endif /* __BEOS__ */ #endif /* !(defined (__GNUG__) && defined (size_t)) */ #endif /* __size_t */ #endif /* _SIZET_ */ @@ -180,6 +185,7 @@ typedef __SIZE_TYPE__ size_t; #endif /* _T_SIZE_ */ #endif /* _SYS_SIZE_T_H */ #endif /* _SIZE_T */ +#endif /* __size_t__ */ #undef __need_size_t #endif /* _STDDEF_H or __need_size_t. */ @@ -192,6 +198,7 @@ typedef __SIZE_TYPE__ size_t; /* Define this type if we are doing the whole job, or if we want this type in particular. */ #if defined (_STDDEF_H) || defined (__need_wchar_t) +#ifndef __wchar_t__ /* BeOS */ #ifndef _WCHAR_T #ifndef _T_WCHAR_ #ifndef _T_WCHAR @@ -204,6 +211,7 @@ typedef __SIZE_TYPE__ size_t; #ifndef ___int_wchar_t_h #ifndef __INT_WCHAR_T_H #ifndef _GCC_WCHAR_T +#define __wchar_t__ /* BeOS */ #define _WCHAR_T #define _T_WCHAR_ #define _T_WCHAR @@ -237,8 +245,12 @@ typedef _BSD_RUNE_T_ rune_t; #endif #ifndef __WCHAR_TYPE__ +#ifdef __BEOS__ +#define __WCHAR_TYPE__ unsigned char +#else #define __WCHAR_TYPE__ int #endif +#endif #ifndef __cplusplus typedef __WCHAR_TYPE__ wchar_t; #endif @@ -254,6 +266,7 @@ typedef __WCHAR_TYPE__ wchar_t; #endif #endif #endif +#endif /* __wchar_t__ */ #undef __need_wchar_t #endif /* _STDDEF_H or __need_wchar_t. */ @@ -271,7 +284,9 @@ typedef __WINT_TYPE__ wint_t; /* In 4.3bsd-net2, leave these undefined to indicate that size_t, etc. are already defined. */ -#ifdef _ANSI_H_ +/* BSD/OS 3.1 requires the MACHINE_ANSI_H check here. FreeBSD 2.x apparently + does not, even though there is a check for MACHINE_ANSI_H above. */ +#if defined(_ANSI_H_) || (defined(__bsdi__) && defined(_MACHINE_ANSI_H_)) /* The references to _GCC_PTRDIFF_T_, _GCC_SIZE_T_, and _GCC_WCHAR_T_ are probably typos and should be removed before 2.8 is released. */ #ifdef _GCC_PTRDIFF_T_ @@ -299,7 +314,7 @@ typedef __WINT_TYPE__ wint_t; #undef _WCHAR_T_ #undef _BSD_WCHAR_T_ #endif -#endif /* _ANSI_H_ */ +#endif /* _ANSI_H_ || ( __bsdi__ && _MACHINE_ANSI_H_ ) */ #endif /* __sys_stdtypes_h */ diff --git a/gnu/dist/gcc/ginclude/va-i960.h b/gnu/dist/gcc/ginclude/va-i960.h index ba0d08ba8936..5588d4112917 100644 --- a/gnu/dist/gcc/ginclude/va-i960.h +++ b/gnu/dist/gcc/ginclude/va-i960.h @@ -70,7 +70,7 @@ __extension__ \ #ifndef va_end void va_end (__gnuc_va_list); /* Defined in libgcc.a */ #endif -#define va_end(AP) ((void *)0) +#define va_end(AP) ((void) 0) /* Copy __gnuc_va_list into another variable of this type. */ #define __va_copy(dest, src) (dest) = (src) diff --git a/gnu/dist/gcc/ginclude/va-mips.h b/gnu/dist/gcc/ginclude/va-mips.h index a622199388e6..96db5b466cc3 100644 --- a/gnu/dist/gcc/ginclude/va-mips.h +++ b/gnu/dist/gcc/ginclude/va-mips.h @@ -200,7 +200,7 @@ void va_end (__gnuc_va_list); /* Defined in libgcc.a */ #define __va_next_addr(__AP, __type) \ (((__builtin_classify_type (* (__type *) 0) < __record_type_class \ && __alignof__ (__type) > 4) \ - ? __AP = (char *) (((int) __AP + 8 - 1) & -8) \ + ? __AP = (char *) (((__PTRDIFF_TYPE__) __AP + 8 - 1) & -8) \ : (char *) 0), \ (__builtin_classify_type (* (__type *) 0) >= __record_type_class \ ? (__AP += __va_reg_size) - __va_reg_size \ @@ -240,8 +240,9 @@ void va_end (__gnuc_va_list); /* Defined in libgcc.a */ #ifdef __mips64 #ifdef __MIPSEB__ #define va_arg(__AP, __type) \ - ((__type *) (void *) (__AP = (char *) ((((__PTRDIFF_TYPE__)__AP + 8 - 1) & -8) \ - + __va_rounded_size (__type))))[-1] + ((__type *) (void *) (__AP = (char *) \ + ((((__PTRDIFF_TYPE__)__AP + 8 - 1) & -8) \ + + __va_rounded_size (__type))))[-1] #else #define va_arg(__AP, __type) \ ((__AP = (char *) ((((__PTRDIFF_TYPE__)__AP + 8 - 1) & -8) \ @@ -255,16 +256,16 @@ void va_end (__gnuc_va_list); /* Defined in libgcc.a */ /* For big-endian machines. */ #define va_arg(__AP, __type) \ ((__AP = (char *) ((__alignof__ (__type) > 4 \ - ? ((int)__AP + 8 - 1) & -8 \ - : ((int)__AP + 4 - 1) & -4) \ + ? ((__PTRDIFF_TYPE__)__AP + 8 - 1) & -8 \ + : ((__PTRDIFF_TYPE__)__AP + 4 - 1) & -4) \ + __va_rounded_size (__type))), \ *(__type *) (void *) (__AP - __va_rounded_size (__type))) #else /* For little-endian machines. */ #define va_arg(__AP, __type) \ ((__type *) (void *) (__AP = (char *) ((__alignof__(__type) > 4 \ - ? ((int)__AP + 8 - 1) & -8 \ - : ((int)__AP + 4 - 1) & -4) \ + ? ((__PTRDIFF_TYPE__)__AP + 8 - 1) & -8 \ + : ((__PTRDIFF_TYPE__)__AP + 4 - 1) & -4) \ + __va_rounded_size(__type))))[-1] #endif #endif diff --git a/gnu/dist/gcc/ginclude/va-v850.h b/gnu/dist/gcc/ginclude/va-v850.h index 3fd812ab228e..96da6d5a3dea 100644 --- a/gnu/dist/gcc/ginclude/va-v850.h +++ b/gnu/dist/gcc/ginclude/va-v850.h @@ -1,5 +1,3 @@ -/* CYGNUS LOCAL v850/law (entire file ) */ - /* Define __gnuc_va_list. */ #ifndef __GNUC_VA_LIST @@ -34,4 +32,3 @@ void va_end (__gnuc_va_list); : (AP = (__gnuc_va_list) ((char *) (AP) + __va_rounded_size (TYPE)), \ *((TYPE *) (void *) ((char *) (AP) - __va_rounded_size (TYPE))))) #endif -/* END CYGNUS LOCAL */ diff --git a/gnu/dist/gcc/ginclude/varargs.h b/gnu/dist/gcc/ginclude/varargs.h index cfb5f2308c7d..410d06aac69b 100644 --- a/gnu/dist/gcc/ginclude/varargs.h +++ b/gnu/dist/gcc/ginclude/varargs.h @@ -115,7 +115,7 @@ typedef void *__gnuc_va_list; (((sizeof (TYPE) + sizeof (int) - 1) / sizeof (int)) * sizeof (int)) #endif -#if defined (__arm__) || defined (__i386__) || defined (__i860__) || defined (__ns32000__) || defined (__vax__) +#if (defined (__arm__) && ! defined (__ARMEB__)) || defined (__i386__) || defined (__i860__) || defined (__ns32000__) || defined (__vax__) /* This is for little-endian machines; small args are padded upward. */ #define va_arg(AP, TYPE) \ (AP = (__gnuc_va_list) ((char *) (AP) + __va_rounded_size (TYPE)), \