Index: calls.c =================================================================== RCS file: /cvsroot/linux-vax/toolchain/src/gcc/calls.c,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -r1.1.1.1 -r1.2 --- calls.c 17 Feb 2003 00:10:14 -0000 1.1.1.1 +++ calls.c 17 Feb 2003 03:02:02 -0000 1.2 @@ -405,7 +405,15 @@ #ifndef ACCUMULATE_OUTGOING_ARGS #if defined (HAVE_call_pop) && defined (HAVE_call_value_pop) - if (HAVE_call_pop && HAVE_call_value_pop && n_popped > 0) +/* If the target has "call" or "call_value" insns, then prefer them + if no arguments are actually popped. If the target does not have + "call" or "call_value" insns, then we must use the popping versions + even if the call has no arguments to pop. */ + if (HAVE_call_pop && HAVE_call_value_pop +#if defined (HAVE_call) && defined (HAVE_call_value) + && (n_popped > 0 || ! HAVE_call || ! HAVE_call_value) +#endif + ) { rtx n_pop = GEN_INT (n_popped); rtx pat; Index: cccp.c =================================================================== RCS file: /cvsroot/linux-vax/toolchain/src/gcc/cccp.c,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -r1.1.1.1 -r1.2 --- cccp.c 17 Feb 2003 00:10:24 -0000 1.1.1.1 +++ cccp.c 17 Feb 2003 02:10:29 -0000 1.2 @@ -2496,7 +2496,7 @@ int output_marks; { /* Character being scanned in main loop. */ - register U_CHAR c; + register U_CHAR c = 0; /* Length of pending accumulated identifier. */ register int ident_length = 0; Index: collect2.c =================================================================== RCS file: /cvsroot/linux-vax/toolchain/src/gcc/collect2.c,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -r1.1.1.1 -r1.2 --- collect2.c 17 Feb 2003 00:10:28 -0000 1.1.1.1 +++ collect2.c 17 Feb 2003 02:11:09 -0000 1.2 @@ -53,7 +53,6 @@ #define obstack_chunk_alloc xmalloc #define obstack_chunk_free free -extern char *make_temp_file PROTO ((char *)); /* On certain systems, we have code that works by scanning the object file directly. But this code uses system-specific header files and library Index: configure =================================================================== RCS file: /cvsroot/linux-vax/toolchain/src/gcc/configure,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -r1.1.1.1 -r1.2 --- configure 17 Feb 2003 00:10:44 -0000 1.1.1.1 +++ configure 17 Feb 2003 01:47:03 -0000 1.2 @@ -5556,6 +5556,28 @@ fi use_collect2=no ;; + vax-*-linux-gnuaout*) # vax running Linux + # with a.out format + xmake_file=x-linux + tm_file="${tm_file} vax/linux-aout.h" + tmake_file="t-linux-aout vax/t-linux-aout" + fixincludes=Makefile.in # The headers are ok already. + float_format=vax + gnu_ld=yes + ;; + vax-*-linux*) # vax running linux ELF binary format + # glibc2. no libc5 binaries needed + xmake_file=x-linux + tm_file="${tm_file} vax/linux.h" + tmake_file="t-linux vax/t-linux" + extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o" + fixincludes=Makefile.in #On Linux, the headers are ok already. + float_format=vax + gnu_ld=yes + if [ x$enable_threads = xyes ]; then + thread_file='posix' + fi + ;; vax-*-bsd*) # vaxen running BSD use_collect2=yes float_format=vax Index: configure.in =================================================================== RCS file: /cvsroot/linux-vax/toolchain/src/gcc/configure.in,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -r1.1.1.1 -r1.2 --- configure.in 17 Feb 2003 00:10:46 -0000 1.1.1.1 +++ configure.in 17 Feb 2003 01:47:03 -0000 1.2 @@ -3253,6 +3253,28 @@ fi use_collect2=no ;; + vax-*-linux-gnuaout*) # vax running Linux + # with a.out format + xmake_file=x-linux + tm_file="${tm_file} vax/linux-aout.h" + tmake_file="t-linux-aout vax/t-linux-aout" + fixincludes=Makefile.in # The headers are ok already. + float_format=vax + gnu_ld=yes + ;; + vax-*-linux*) # vax running linux ELF binary format + # glibc2. no libc5 binaries needed + xmake_file=x-linux + tm_file="${tm_file} vax/linux.h" + tmake_file="t-linux vax/t-linux" + extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o" + fixincludes=Makefile.in #On Linux, the headers are ok already. + float_format=vax + gnu_ld=yes + if [ x$enable_threads = xyes ]; then + thread_file='posix' + fi + ;; vax-*-bsd*) # vaxen running BSD use_collect2=yes float_format=vax Index: flow.c =================================================================== RCS file: /cvsroot/linux-vax/toolchain/src/gcc/flow.c,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -r1.1.1.1 -r1.2 --- flow.c 17 Feb 2003 00:12:13 -0000 1.1.1.1 +++ flow.c 17 Feb 2003 02:56:10 -0000 1.2 @@ -2021,8 +2021,14 @@ } /* Selectively unlink the sequence. */ - if (q != PREV_INSN (c->head)) + if (q != PREV_INSN (c->head)) { + /* check that we will no orphan b->end + * i.e. NEXT_INSN(b->head) == b->end */ + if (b->end==NEXT_INSN(q)) { + b->end=q; + } delete_insn_chain (NEXT_INSN (q), PREV_INSN (c->head)); + } e->flags |= EDGE_FALLTHRU; } Index: gcc.c =================================================================== RCS file: /cvsroot/linux-vax/toolchain/src/gcc/gcc.c,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -r1.1.1.1 -r1.2 --- gcc.c 17 Feb 2003 00:12:39 -0000 1.1.1.1 +++ gcc.c 17 Feb 2003 02:12:14 -0000 1.2 @@ -1288,8 +1288,6 @@ #ifdef MKTEMP_EACH_FILE -extern char *make_temp_file PROTO((const char *)); - /* This is the list of suffixes and codes (%g/%u/%U) and the associated temp file. */ Index: jump.c =================================================================== RCS file: /cvsroot/linux-vax/toolchain/src/gcc/jump.c,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -r1.1.1.1 -r1.2 --- jump.c 17 Feb 2003 00:13:32 -0000 1.1.1.1 +++ jump.c 17 Feb 2003 01:54:04 -0000 1.2 @@ -3912,8 +3912,9 @@ { rtx part = XVECEXP (PATTERN (our_prev), 0, i); + /* Don't do it if asm volatile instruction - D.A. Linux/VAX */ if (GET_CODE (part) == SET - && SET_DEST (part) != XEXP (note, 0)) + && (SET_DEST (part) != XEXP (note, 0) || (GET_CODE(SET_SRC(part)) == ASM_OPERANDS && MEM_VOLATILE_P(SET_SRC(part))))) break; } Index: config/vax/linux.h =================================================================== RCS file: config/vax/linux.h diff -N config/vax/linux.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ config/vax/linux.h 17 Feb 2003 01:38:22 -0000 1.1 @@ -0,0 +1,134 @@ +/* Definitions for VAX running Linux-based GNU systems with ELF format. + Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999 Free Software Foundation, Inc. + Contributed by Andy Phillips. + Based heavily on i386 version by Eric Youngdale, + with modifications by H.J. Lu. + +This file is part of GNU CC. + +GNU CC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU CC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +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. */ + + +/* temporary*/ +#define inhibit_libc + +#define LINUX_DEFAULT_ELF +/* FIXME: check this with the gas sources */ +#define LPREFIX ".L" + +/* Keeps gcc quiet. This is defined in terms of the vaxc structure + * alignment flag. Only really applicable to VMS. For this target we + * will be getting a definition from svr4.h */ + +#ifdef PCC_BITFIELD_TYPE_MATTERS +#undef PCC_BITFIELD_TYPE_MATTERS +#endif + +#include /* some common stuff */ + /* This includes svr4, which undefines DBX_REGISTER_NUMBER */ +#include /* pic stuff */ + +#undef TARGET_VERSION +#define TARGET_VERSION fprintf (stderr, " (VAX Linux/ELF)"); + +#undef CPP_PREDEFINES +#define CPP_PREDEFINES "-D__ELF__ -Dunix -Dvax -D__vax__ -Dlinux -Asystem(posix) -Acpu(vax) -Amachine(vax)" + +#undef CPP_SPEC +#define CPP_SPEC "%(cpp_cpu) %{fPIC:-D__PIC__ -D__pic__} %{fpic:-D__PIC__ -D__pic__} %{posix:-D_POSIX_SOURCE} %{pthread:-D_REENTRANT}" + +#undef CC1_SPEC +#define CC1_SPEC "%(cc1_cpu) %{profile:-p} %{!fno-pic: \ + %{!mno-pic: %{!fpic: %{!fPIC:-fPIC}}} \ + %{!mindirect: %{!mno-indirect:-mno-indirect}}} \ + %{mno-pic: -fno-pic -mindirect} \ + %{fno-pic: \ + %{!mindirect: %{!mno-indirect:-mindirect}}}" + +#define CC1PLUS_SPEC CC1_SPEC + +/* Provide a LINK_SPEC appropriate for Linux. Here we provide support + for the special GCC options -static and -shared, which allow us to + link things in one of these three modes by applying the appropriate + combinations of options at link-time. We like to support here for + as many of the other GNU linker options as possible. But I don't + have the time to search for those flags. I am sure how to add + support for -soname shared_object_name. H.J. + + I took out %{v:%{!V:-V}}. It is too much :-(. They can use + -Wl,-V. + + When the -shared link option is used a final link is not being + done. */ + +/* If ELF is the default format, we should not use /lib/elf. */ +/* we do not support libc5 */ + +#undef LINK_SPEC +#define LINK_SPEC "-m elf32vax %{shared:-shared} \ + %{!shared: \ + %{!ibcs: \ + %{!static: \ + %{rdynamic:-export-dynamic} \ + %{!dynamic-linker:-dynamic-linker /lib/ld-linux.so.2}} \ + %{static:-static}}}" + + +/* Make gcc agree with */ + +#undef SIZE_TYPE +#define SIZE_TYPE "unsigned int" + +#undef PTRDIFF_TYPE +#define PTRDIFF_TYPE "int" + +#undef WCHAR_TYPE +#define WCHAR_TYPE "int" + +#undef WCHAR_UNSIGNED +#define WCHAR_UNSIGNED 0 + +#undef WCHAR_TYPE_SIZE +#define WCHAR_TYPE_SIZE 32 + +/* Until they use ELF or something that handles dwarf2 unwinds + and initialization stuff better. */ +/* #undef DWARF2_UNWIND_INFO */ + +#undef ASM_COMMENT_START +#define ASM_COMMENT_START "#" + +/* Indicate that jump tables (case instr) go in the text section. */ +#define JUMP_TABLES_IN_TEXT_SECTION (1) + +/* svr4.h defines ASM_OUTPUT_CASE_LABEL as calling the + ASM_OUTPUT_BEFORE_CASE_LABEL and ASM_OUTPUT_INTERNAL_LABEL + macros in turn. This causes a .align 2 to be inserted between the + CASEx instruction and the jump table. This is Not Good. + Undefining ASM_OUTPUT_CASE_LABEL altogether, causes the compiler + to fallback to ASM_OUPUT_INTERNAL_LABEL which is what we want. */ + +#undef ASM_OUTPUT_CASE_LABEL + +/* How to renumber registers for dbx and gdb. + Vax needs no change in the numeration. */ +/* This is repeated here, because it gets undefined in */ + +#define DBX_REGISTER_NUMBER(REGNO) (REGNO) + +/* we dont have these in our libc */ +#undef UDIVSI3_LIBCALL +#undef UMODSI3_LIBCALL Index: config/vax/pic.h =================================================================== RCS file: config/vax/pic.h diff -N config/vax/pic.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ config/vax/pic.h 17 Feb 2003 01:38:22 -0000 1.1 @@ -0,0 +1,135 @@ +/* pic support routines Contributed by Andy Phillips, + atp at mssl.ucl.ac.uk March 1999 + + i386 implementation used as template + +This file is part of GNU CC. + +GNU CC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU CC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +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. */ + +#undef REGISTER_PREFIX +#define REGISTER_PREFIX "%" + +#undef TARGET_GAS +#define TARGET_GAS (1) + +#undef TARGET_DEFAULT +#define TARGET_DEFAULT 0 + +#define TARGET_MEM_FUNCTIONS + +/* Function CSE screws up PLT .vs. GOT usage. + * */ +#define NO_FUNCTION_CSE + +/* This makes use of a hook in varasm.c to mark all external functions + * for us. We use this to make sure that external functions are correctly + * referenced from the PLT. */ + +#define NO_EXTERNAL_INDIRECT_ADDRESS + +/* Output assembler code to FILE to increment profiler label # LABELNO + for profiling a function entry. */ +/* overrides default definition in vax.h */ + +#undef FUNCTION_PROFILER +#define FUNCTION_PROFILER(FILE, LABELNO) \ + asm_fprintf (FILE, "\tmovab .LP%d,%Rr0\n\tjsb __mcount\n", (LABELNO)) + +/* There are three profiling modes for basic blocks available. + The modes are selected at compile time by using the options + -a or -ax of the gnu compiler. + The variable `profile_block_flag' will be set according to the + selected option. + + profile_block_flag == 0, no option used: + + No profiling done. + + profile_block_flag == 1, -a option used. + + Count frequency of execution of every basic block. + + profile_block_flag == 2, -ax option used. + + Generate code to allow several different profiling modes at run time. + Available modes are: + Produce a trace of all basic blocks. + Count frequency of jump instructions executed. + In every mode it is possible to start profiling upon entering + certain functions and to disable profiling of some other functions. + + The result of basic-block profiling will be written to a file `bb.out'. + If the -ax option is used parameters for the profiling will be read + from file `bb.in'. + +*/ +/* we dont support profile_block_flag == 2, PIC makes this more complex */ + +/* The following macro shall output assembler code to FILE + to indicate a return from function during basic-block profiling. + + we do not support the case of profile_block_flag == 2 + The macro will not be used. +*/ + +#define FUNCTION_BLOCK_PROFILER_EXIT(FILE) {} + +#define TARGET_DEBUG_ADDR 0 +/* Define this macro if references to a symbol must be treated + differently depending on something about the variable or + function named by the symbol (such as what section it is in). + + On i386, if using PIC, mark a SYMBOL_REF for a non-global symbol + so that we may access it directly in the GOT. */ + +#define ENCODE_SECTION_INFO(DECL) \ +do \ + { \ + if (flag_pic) \ + { \ + rtx rtl = (TREE_CODE_CLASS (TREE_CODE (DECL)) != 'd' \ + ? TREE_CST_RTL (DECL) : DECL_RTL (DECL)); \ + \ + if (TARGET_DEBUG_ADDR \ + && TREE_CODE_CLASS (TREE_CODE (DECL)) == 'd') \ + { \ + fprintf (stderr, "Encode %s, public = %d\n", \ + IDENTIFIER_POINTER (DECL_NAME (DECL)), \ + TREE_PUBLIC (DECL)); \ + } \ + \ + if (GET_CODE (rtl) == MEM) \ + { \ + SYMBOL_REF_FLAG (XEXP (rtl, 0)) \ + = (TREE_CODE_CLASS (TREE_CODE (DECL)) != 'd' \ + || ! TREE_PUBLIC (DECL)); \ + }\ + } \ + } \ +while (0) + +/* Put relocations in the constant pool in the writable data section. */ +#undef SELECT_RTX_SECTION +#define SELECT_RTX_SECTION(MODE,RTX) \ +{ \ + if (flag_pic && vax_symbolic_operand ((RTX), (MODE))) \ + data_section (); \ + else \ + readonly_data_section (); \ +} + + Index: config/vax/vax.c =================================================================== RCS file: /cvsroot/linux-vax/toolchain/src/gcc/config/vax/vax.c,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -r1.1.1.1 -r1.2 --- config/vax/vax.c 17 Feb 2003 00:25:53 -0000 1.1.1.1 +++ config/vax/vax.c 17 Feb 2003 01:38:22 -0000 1.2 @@ -25,6 +25,7 @@ #include "hard-reg-set.h" #include "real.h" #include "insn-config.h" +#include "insn-codes.h" #include "conditions.h" #include "insn-flags.h" #include "output.h" @@ -32,6 +33,9 @@ #ifdef VMS_TARGET #include "tree.h" #endif +#include "reload.h" +#include "recog.h" +/*#include "tm_p.h"*/ /* This is like nonimmediate_operand with a restriction on the type of MEM. */ @@ -43,8 +47,9 @@ int i; /* Split operands. */ - low[0] = low[1] = low[2] = 0; - for (i = 0; i < 3; i++) + for (i = 0; i < n; i++) + low[i] = 0; + for (i = 0; i < n; i++) { if (low[i]) /* it's already been figured out */; @@ -67,12 +72,29 @@ } } +void print_operand_address (file, addr) FILE *file; register rtx addr; { - register rtx reg1, reg2, breg, ireg; + register rtx reg1, breg, ireg; rtx offset; + rtx orig_addr = addr; + +#if 0 + if (GET_CODE (addr) == PLUS && GET_CODE (XEXP (addr, 1)) == CONST) + debug_rtx (addr); +#endif +#ifdef NO_EXTERNAL_INDIRECT_ADDRESS + if (flag_pic && GET_CODE (addr) == CONST && + GET_CODE (XEXP (addr, 0)) == PLUS && + GET_CODE (XEXP (XEXP (addr, 0), 0)) == SYMBOL_REF && + !SYMBOL_REF_FLAG (XEXP (XEXP (addr, 0), 0)) && + GET_CODE (XEXP (XEXP (addr, 0), 1)) == CONST_INT) + { + fatal_insn ("Non-PIC operand escaped:\n", addr); + } +#endif retry: switch (GET_CODE (addr)) @@ -83,15 +105,20 @@ goto retry; case REG: - fprintf (file, "(%s)", reg_names[REGNO (addr)]); + if (REGNO (addr) >= 16) + { + debug_rtx (orig_addr); + abort (); + } + fprintf (file, "(%s%s)", REGISTER_PREFIX, reg_names[REGNO (addr)]); break; case PRE_DEC: - fprintf (file, "-(%s)", reg_names[REGNO (XEXP (addr, 0))]); + fprintf (file, "-(%s%s)", REGISTER_PREFIX, reg_names[REGNO (XEXP (addr, 0))]); break; case POST_INC: - fprintf (file, "(%s)+", reg_names[REGNO (XEXP (addr, 0))]); + fprintf (file, "(%s%s)+", REGISTER_PREFIX, reg_names[REGNO (XEXP (addr, 0))]); break; case PLUS: @@ -139,7 +166,10 @@ addr = XEXP (addr, 1); } else - abort (); + { + debug_rtx (orig_addr); + abort (); + } if (GET_CODE (addr) == REG) { @@ -162,7 +192,10 @@ else if (GET_CODE (XEXP (addr, 0)) == CONST_INT) offset = plus_constant (offset, INTVAL (XEXP (addr, 0))); else - abort (); + { + debug_rtx (orig_addr); + abort (); + } } offset = XEXP (addr, 0); } @@ -176,11 +209,17 @@ else if (GET_CODE (XEXP (addr, 0)) == MULT) { if (ireg) - abort (); + { + debug_rtx (orig_addr); + abort (); + } ireg = XEXP (addr, 0); } else - abort (); + { + debug_rtx (orig_addr); + abort (); + } if (CONSTANT_ADDRESS_P (XEXP (addr, 1)) || GET_CODE (XEXP (addr, 1)) == MEM) @@ -192,7 +231,10 @@ else if (GET_CODE (XEXP (addr, 1)) == CONST_INT) offset = plus_constant (offset, INTVAL (XEXP (addr, 1))); else - abort (); + { + debug_rtx (orig_addr); + abort (); + } } offset = XEXP (addr, 1); } @@ -206,22 +248,49 @@ else if (GET_CODE (XEXP (addr, 1)) == MULT) { if (ireg) - abort (); + { + debug_rtx (orig_addr); + abort (); + } ireg = XEXP (addr, 1); } + else if (GET_CODE (addr) == SYMBOL_REF) + { + output_addr_const (file, addr); + if (offset != 0) + { + fputc ('+', file); + output_address (offset); + offset = 0; + } + } else - abort (); + { + debug_rtx (orig_addr); + abort (); + } } else - abort (); + { + debug_rtx (orig_addr); + abort (); + } /* If REG1 is non-zero, figure out if it is a base or index register. */ if (reg1) { - if (breg != 0 || (offset && GET_CODE (offset) == MEM)) + if (breg != 0 + || GET_CODE (addr) == SYMBOL_REF + || (offset + && (GET_CODE (offset) == MEM + || GET_CODE (offset) == SYMBOL_REF + || GET_CODE (offset) == CONST))) { if (ireg) - abort (); + { + debug_rtx (orig_addr); + abort (); + } ireg = reg1; } else @@ -232,15 +301,25 @@ output_address (offset); if (breg != 0) - fprintf (file, "(%s)", reg_names[REGNO (breg)]); + { + if (REGNO (breg) >= 16) + { + debug_rtx (orig_addr); + abort (); + } + fprintf (file, "(%s%s)", REGISTER_PREFIX, reg_names[REGNO (breg)]); + } if (ireg != 0) { if (GET_CODE (ireg) == MULT) ireg = XEXP (ireg, 0); if (GET_CODE (ireg) != REG) - abort (); - fprintf (file, "[%s]", reg_names[REGNO (ireg)]); + { + debug_rtx (orig_addr); + abort (); + } + fprintf (file, "[%s%s]", REGISTER_PREFIX, reg_names[REGNO (ireg)]); } break; @@ -249,7 +328,7 @@ } } -char * +const char * rev_cond_name (op) rtx op; { @@ -286,8 +365,10 @@ register rtx c; { register enum machine_mode mode; +#if HOST_FLOAT_FORMAT == VAX_FLOAT_FORMAT int i; union {double d; int i[2];} val; +#endif if (GET_CODE (c) != CONST_DOUBLE) return 0; @@ -365,6 +446,9 @@ indir = 2; /* 3 on VAX 2 */ addr = XEXP (addr, 0); goto restart; + default: + /* shut up gcc complaining about other enum values */ + break; } /* Up to 3 things can be added in an address. They are stored in @@ -400,9 +484,9 @@ { register enum rtx_code code = GET_CODE (x); enum machine_mode mode = GET_MODE (x); - register int c; + register int c=0; int i = 0; /* may be modified in switch */ - char *fmt = GET_RTX_FORMAT (code); /* may be modified in switch */ + const char *fmt = GET_RTX_FORMAT (code); /* may be modified in switch */ switch (code) { @@ -427,6 +511,13 @@ case QImode: c = 10; /* 3-4 on VAX 9000, 20-28 on VAX 2 */ break; + case VOIDmode: + c=9; + break; + default: + /* complex, partial int modes ?? shouldnt need these*/ + c=20; + break; } break; case UDIV: @@ -582,7 +673,7 @@ /* Check a `double' value for validity for a particular machine mode. */ -static char *float_strings[] = +static const char *const float_strings[] = { "1.70141173319264430e+38", /* 2^127 (2^24 - 1) / 2^24 */ "-1.70141173319264430e+38", @@ -651,6 +742,338 @@ return 0; } +/* Nonzero if X is a hard reg that can be used as an index. */ +#define XREG_OK_FOR_INDEX_P(X, STRICT) (!(STRICT) || REGNO_OK_FOR_INDEX_P (REGNO (X))) +/* Nonzero if X is a hard reg that can be used as a base reg. */ +#define XREG_OK_FOR_BASE_P(X, STRICT) (!(STRICT) || REGNO_OK_FOR_BASE_P (REGNO (X))) + +#ifdef NO_EXTERNAL_INDIRECT_ADDRESS + +/* Re-definition of CONSTANT_ADDRESS_P, which is true only when there + are no SYMBOL_REFs for external symbols present and allow valid + addressing modes. */ + +#define INDIRECTABLE_CONSTANT_ADDRESS_P(X, INDEXED, INDIRECT) \ + (GET_CODE (X) == LABEL_REF \ + || (!INDEXED && GET_CODE (X) == SYMBOL_REF \ + && (!INDIRECT || SYMBOL_REF_FLAG (X))) \ + || (!INDEXED && GET_CODE (X) == CONST \ + && GET_CODE (XEXP ((X), 0)) == PLUS \ + && GET_CODE (XEXP (XEXP ((X), 0), 0)) == SYMBOL_REF \ + && ((!INDIRECT && !flag_pic) \ + || SYMBOL_REF_FLAG (XEXP (XEXP ((X), 0), 0)))) \ + || GET_CODE (X) == CONST_INT) + +/* Non-zero if X is an address which can be indirected. External symbols + could be in a sharable image library, so we disallow those. */ + +#define INDIRECTABLE_ADDRESS_P(X, STRICT, INDEXED, INDIRECT) \ + (INDIRECTABLE_CONSTANT_ADDRESS_P (X, INDEXED, INDIRECT) \ + || (GET_CODE (X) == REG && XREG_OK_FOR_BASE_P (X, STRICT)) \ + || (GET_CODE (X) == PLUS \ + && GET_CODE (XEXP (X, 0)) == REG \ + && XREG_OK_FOR_BASE_P (XEXP (X, 0), STRICT) \ + && GET_CODE (XEXP (X, 1)) != SYMBOL_REF \ + && !(GET_CODE (XEXP (X, 1)) == CONST \ + && GET_CODE (XEXP (XEXP (X, 1), 0)) == PLUS \ + && GET_CODE (XEXP (XEXP (XEXP (X, 1), 0), 0)) == SYMBOL_REF) \ + && INDIRECTABLE_CONSTANT_ADDRESS_P (XEXP (X, 1), INDEXED, INDIRECT))) + +#else /* not NO_EXTERNAL_INDIRECT_ADDRESS */ + +#define INDIRECTABLE_CONSTANT_ADDRESS_P(X, INDEXED, INDIRECT) \ + CONSTANT_ADDRESS_P (X) + +/* Non-zero if X is an address which can be indirected. */ +#define INDIRECTABLE_ADDRESS_P(X, STRICT, INDEXED, INDIRECT) \ + (INDIRECTABLE_CONSTANT_ADDRESS_P (X, INDEXED, INDIRECT) \ + || (GET_CODE (X) == REG && XREG_OK_FOR_BASE_P (X, STRICT)) \ + || (GET_CODE (X) == PLUS \ + && GET_CODE (XEXP (X, 0)) == REG \ + && XREG_OK_FOR_BASE_P (XEXP (X, 0), STRICT) \ + && CONSTANT_ADDRESS_P (XEXP (X, 1)))) + +#endif /* not NO_EXTERNAL_INDIRECT_ADDRESS */ + +/* Go to ADDR if X is a valid address not using indexing. + (This much is the easy part.) */ +#define GO_IF_NONINDEXED_ADDRESS(X, ADDR, STRICT, INDEXED) \ +{ register rtx xfoob = (X); \ + if (GET_CODE (X) == REG) \ + { \ + extern rtx *reg_equiv_mem; \ + if (! reload_in_progress) \ + goto ADDR; \ + if (!STRICT) \ + { \ + if ((xfoob = reg_equiv_mem[REGNO (xfoob)]) == 0) \ + goto ADDR; \ + } \ + if (INDIRECTABLE_ADDRESS_P (xfoob, STRICT, INDEXED, 0)) \ + goto ADDR; \ + } \ + if (INDIRECTABLE_CONSTANT_ADDRESS_P (X, INDEXED, 0)) goto ADDR; \ + if (INDIRECTABLE_ADDRESS_P (X, STRICT, INDEXED, 0)) goto ADDR; \ + xfoob = XEXP (X, 0); \ + if (GET_CODE (X) == MEM \ + && INDIRECTABLE_ADDRESS_P (xfoob, STRICT, INDEXED, !TARGET_INDIRECT)) \ + goto ADDR; \ + if ((GET_CODE (X) == PRE_DEC || GET_CODE (X) == POST_INC) \ + && GET_CODE (xfoob) == REG \ + && XREG_OK_FOR_BASE_P (xfoob, STRICT)) \ + goto ADDR; } + +/* 1 if PROD is either a reg times size of mode MODE + or just a reg, if MODE is just one byte. + This macro's expansion uses the temporary variables xfoo0 and xfoo1 + that must be declared in the surrounding context. */ +#define INDEX_TERM_P(PROD, MODE, STRICT) \ +(GET_MODE_SIZE (MODE) == 1 \ + ? (GET_CODE (PROD) == REG && XREG_OK_FOR_BASE_P (PROD, STRICT)) \ + : (GET_CODE (PROD) == MULT \ + && \ + (xfoo0 = XEXP (PROD, 0), xfoo1 = XEXP (PROD, 1), \ + ((GET_CODE (xfoo0) == CONST_INT \ + && GET_CODE (xfoo1) == REG \ + && INTVAL (xfoo0) == (int)GET_MODE_SIZE (MODE) \ + && XREG_OK_FOR_INDEX_P (xfoo1, STRICT)) \ + || \ + (GET_CODE (xfoo1) == CONST_INT \ + && GET_CODE (xfoo0) == REG \ + && INTVAL (xfoo1) == (int)GET_MODE_SIZE (MODE) \ + && XREG_OK_FOR_INDEX_P (xfoo0, STRICT)))))) + +/* Go to ADDR if X is the sum of a register + and a valid index term for mode MODE. */ +#define GO_IF_REG_PLUS_INDEX(X, MODE, ADDR, STRICT) \ +{ register rtx xfooa; \ + if (GET_CODE (X) == PLUS) \ + { if (GET_CODE (XEXP (X, 0)) == REG \ + && XREG_OK_FOR_BASE_P (XEXP (X, 0), STRICT) \ + && (xfooa = XEXP (X, 1), \ + INDEX_TERM_P (xfooa, MODE, STRICT))) \ + goto ADDR; \ + if (GET_CODE (XEXP (X, 1)) == REG \ + && XREG_OK_FOR_BASE_P (XEXP (X, 1), STRICT) \ + && (xfooa = XEXP (X, 0), \ + INDEX_TERM_P (xfooa, MODE, STRICT))) \ + goto ADDR; } } + +int +legitimate_pic_operand_p(x, strict) + register rtx x; + int strict ATTRIBUTE_UNUSED; +{ + if (GET_CODE (x) != SYMBOL_REF + && !(GET_CODE (x) == CONST + && GET_CODE (XEXP (x, 0)) == PLUS + && GET_CODE (XEXP (XEXP (x, 0), 0)) == SYMBOL_REF)) + { + return 1; + } + return 0; +} + +int +legitimate_address_p(mode, xbar, strict) + enum machine_mode mode; + register rtx xbar; + int strict; +{ + register rtx xfoo, xfoo0, xfoo1; + int from = __LINE__; + GO_IF_NONINDEXED_ADDRESS (xbar, win, strict, 0); + if (GET_CODE (xbar) == PLUS) + { + /* Handle
[index] represented with index-sum outermost */ + xfoo = XEXP (xbar, 0); + if (INDEX_TERM_P (xfoo, mode, strict)) + { + from = __LINE__; + GO_IF_NONINDEXED_ADDRESS (XEXP (xbar, 1), win, strict, 0); + } + xfoo = XEXP (xbar, 1); + if (INDEX_TERM_P (xfoo, mode, strict)) + { + from = __LINE__; + GO_IF_NONINDEXED_ADDRESS (XEXP (xbar, 0), win, strict, 0); + } + /* Handle offset(reg)[index] with offset added outermost */ + if (INDIRECTABLE_CONSTANT_ADDRESS_P (XEXP (xbar, 0), 1, 0)) + { + from = __LINE__; + if (GET_CODE (XEXP (xbar, 1)) == REG + && XREG_OK_FOR_BASE_P (XEXP (xbar, 1), strict)) + goto win; + from = __LINE__; + GO_IF_REG_PLUS_INDEX (XEXP (xbar, 1), mode, win, strict); + } + if (INDIRECTABLE_CONSTANT_ADDRESS_P (XEXP (xbar, 1), 1, 0)) + { + from = __LINE__; + if (GET_CODE (XEXP (xbar, 0)) == REG + && XREG_OK_FOR_BASE_P (XEXP (xbar, 0), strict)) + goto win; + from = __LINE__; + GO_IF_REG_PLUS_INDEX (XEXP (xbar, 0), mode, win, strict); + } + } + return 0; + + win: +#if 0 + if (strict) + { + fprintf(stderr, "line=%d\n", from); + debug_rtx (xbar); + } +#endif + if (flag_pic && GET_CODE (xbar) == SYMBOL_REF +#ifdef NO_EXTERNAL_INDIRECT_ADDRESS + && !SYMBOL_REF_FLAG (xbar) +#endif + && mode == DImode) + return 0; + return 1; +} + +int +vax_symbolic_operand (op, mode) + register rtx op; + enum machine_mode mode ATTRIBUTE_UNUSED; +{ + if (!general_operand(op, mode)) + return 0; + if (GET_CODE (op) == SYMBOL_REF + || GET_CODE (op) == LABEL_REF + || (GET_CODE (op) == CONST + && GET_CODE (XEXP (op, 0)) == PLUS + && GET_CODE (XEXP (XEXP (op, 0), 0)) == SYMBOL_REF +#ifdef NO_EXTERNAL_INDIRECT_ADDRESS + && (SYMBOL_REF_FLAG (XEXP (XEXP (op, 0), 0)) || !flag_pic) +#endif + && GET_CODE (XEXP (XEXP (op, 0), 1)) == CONST_INT) + || (GET_CODE (op) == PLUS + && GET_CODE (XEXP (op, 1)) == SYMBOL_REF +#ifdef NO_EXTERNAL_INDIRECT_ADDRESS + && (SYMBOL_REF_FLAG (XEXP (op, 1)) || !flag_pic) +#endif + && GET_CODE (XEXP (op, 0)) == CONST_INT) + || (GET_CODE (op) == PLUS + && GET_CODE (XEXP (op, 0)) == SYMBOL_REF +#ifdef NO_EXTERNAL_INDIRECT_ADDRESS + && (SYMBOL_REF_FLAG (XEXP (op, 0)) || !flag_pic) +#endif + && GET_CODE (XEXP (op, 1)) == CONST_INT)) + { + return 1; + } + return 0; +} + +int +vax_nonsymbolic_operand (op, mode) + register rtx op; + enum machine_mode mode ATTRIBUTE_UNUSED; +{ + if (!general_operand(op, mode)) + return 0; + if (GET_CODE (op) == SYMBOL_REF + || GET_CODE (op) == LABEL_REF + || (GET_CODE (op) == CONST + && GET_CODE (XEXP (op, 0)) == PLUS + && GET_CODE (XEXP (XEXP (op, 0), 0)) == SYMBOL_REF) + || (GET_CODE (op) == MEM + && GET_CODE (XEXP (op, 0)) == CONST + && GET_CODE (XEXP (XEXP (op, 0), 0)) == PLUS + && GET_CODE (XEXP (XEXP (XEXP (op, 0), 0), 0)) == SYMBOL_REF) + || (GET_CODE (op) == PLUS + && GET_CODE (XEXP (op, 0)) == SYMBOL_REF + && GET_CODE (XEXP (op, 1)) == CONST_INT)) + return 0; +#if 0 + if (GET_CODE (op) == PLUS) + debug_rtx (op); +#endif + if (vax_symbolic_operand (op, mode)) + return 0; +#if 0 + if (GET_CODE (op) != CONST_INT && GET_CODE (op) != REG && + GET_CODE (op) != MEM) + debug_rtx (op); +#endif + return 1; +} + +int +vax_lvalue_operand(op, mode) + register rtx op; + enum machine_mode mode; +{ + if (!general_operand(op, mode)) + return 0; + return GET_CODE (op) == REG + || GET_CODE (op) == SUBREG + || GET_CODE (op) == MEM + || GET_CODE (op) == CONCAT + || GET_CODE (op) == PARALLEL + || GET_CODE (op) == STRICT_LOW_PART; +} + +int +vax_general_operand(op, mode) + register rtx op; + enum machine_mode mode; +{ + if (!general_operand(op, mode)) + return 0; + if (!flag_pic) + return 1; + if ((GET_CODE (op) == CONST + && GET_CODE (XEXP (op, 0)) == PLUS + && GET_CODE (XEXP (XEXP (op, 0), 0)) == SYMBOL_REF +#ifdef NO_EXTERNAL_INDIRECT_ADDRESS + && !SYMBOL_REF_FLAG (XEXP (XEXP (op, 0), 0)) +#endif + ) || (GET_CODE (op) == MEM + && GET_CODE (XEXP (op, 0)) == CONST + && GET_CODE (XEXP (XEXP (op, 0), 0)) == PLUS + && GET_CODE (XEXP (XEXP (XEXP (op, 0), 0), 0)) == SYMBOL_REF +#ifdef NO_EXTERNAL_INDIRECT_ADDRESS + && !SYMBOL_REF_FLAG (XEXP (XEXP (op, 0), 0)) +#endif + ) || (GET_CODE (op) == PLUS + && GET_CODE (XEXP (op, 0)) == SYMBOL_REF + && GET_CODE (XEXP (op, 1)) == CONST_INT +#ifdef NO_EXTERNAL_INDIRECT_ADDRESS + && !SYMBOL_REF_FLAG (XEXP (op, 0)) +#endif + )) + return 0; +#if 0 + debug_rtx (op); +#endif + return 1; +} + +int +vax_reg_used_p(operand, reg) + rtx operand; + int reg; +{ + if (GET_CODE (operand) == REG && REGNO (operand) == reg) + return 1; + if (GET_CODE (operand) == MEM || + GET_CODE (operand) == PRE_DEC || + GET_CODE (operand) == POST_DEC) + return vax_reg_used_p (XEXP(operand, 0), reg); + if (GET_CODE (operand) == PLUS || + GET_CODE (operand) == MULT) + return vax_reg_used_p (XEXP(operand, 0), reg) || + vax_reg_used_p (XEXP(operand, 1), reg); + return 0; +} + #ifdef VMS_TARGET /* Additional support code for VMS target. */ @@ -661,7 +1084,7 @@ static struct extern_list { struct extern_list *next; /* next external */ - char *name; /* name of the external */ + const char *name; /* name of the external */ int size; /* external's actual size */ int in_const; /* section type flag */ } *extern_head = 0, *pending_head = 0; @@ -672,7 +1095,7 @@ void vms_check_external (decl, name, pending) tree decl; - char *name; + const char *name; int pending; { register struct extern_list *p, *p0; Index: config/vax/vax.h =================================================================== RCS file: /cvsroot/linux-vax/toolchain/src/gcc/config/vax/vax.h,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -r1.1.1.1 -r1.2 --- config/vax/vax.h 17 Feb 2003 00:25:54 -0000 1.1.1.1 +++ config/vax/vax.h 17 Feb 2003 01:38:22 -0000 1.2 @@ -25,7 +25,7 @@ /* If using g-format floating point, alter math.h. */ -#define CPP_SPEC "%{mg:-DGFLOAT}" +#define CPP_SPEC "%{mg:%{!ansi:-DGFLOAT} -D__GFLOAT}" /* Choose proper libraries depending on float format. Note that there are no profiling libraries for g-format. @@ -51,41 +51,53 @@ /* Macros used in the machine description to test the flags. */ /* Nonzero if compiling code that Unix assembler can assemble. */ -#define TARGET_UNIX_ASM (target_flags & 1) +#define MASK_UNIX_ASM 1 +#define TARGET_UNIX_ASM (target_flags & MASK_UNIX_ASM) /* Nonzero if compiling with VAX-11 "C" style structure alignment */ -#define TARGET_VAXC_ALIGNMENT (target_flags & 2) +#define MASK_VAXC_ALIGNMENT 2 +#define TARGET_VAXC_ALIGNMENT (target_flags & MASK_VAXC_ALIGNMENT) /* Nonzero if compiling with `G'-format floating point */ -#define TARGET_G_FLOAT (target_flags & 4) +#define MASK_G_FLOAT 4 +#define TARGET_G_FLOAT (target_flags & MASK_G_FLOAT) + +/* Nonzero if compiling for PIC code */ +#define MASK_INDIRECT 8 +#define TARGET_INDIRECT (target_flags & MASK_INDIRECT) /* Macro to define tables used to set the flags. This is a list in braces of pairs in braces, - each pair being { "NAME", VALUE } + each pair being { "NAME", VALUE, "description" } where VALUE is the bits to set or minus the bits to clear. An empty string NAME is used to identify the default VALUE. */ #define TARGET_SWITCHES \ - { {"unix", 1}, \ - {"gnu", -1}, \ - {"vaxc-alignment", 2}, \ - {"g", 4}, \ - {"g-float", 4}, \ - {"d", -4}, \ - {"d-float", -4}, \ - { "", TARGET_DEFAULT}} + { {"unix", MASK_UNIX_ASM, "Do not output long jump instructions that old versions of as cant handle"}, \ + {"gnu", -MASK_UNIX_ASM, "Do output long jump instructions, as we are using gas"}, \ + {"vaxc-alignment", MASK_VAXC_ALIGNMENT, "keep same alignment as VAX C"}, \ + {"g", MASK_G_FLOAT, "output code for g floating point code not d float"}, \ + {"g-float", MASK_G_FLOAT, "output code for g floating point code not d float"}, \ + {"d", -MASK_G_FLOAT, "output code for d floating point code not g float"}, \ + {"d-float", -MASK_G_FLOAT, "output code for d floating point code not g float"}, \ + {"indirect", MASK_INDIRECT, "Allow indirect memory references in PIC code"}, \ + {"no-indirect", -MASK_INDIRECT, "Disallow indirect memory references in PIC code"}, \ + { "", TARGET_DEFAULT, ""}} /* Default target_flags if no switches specified. */ #ifndef TARGET_DEFAULT -#define TARGET_DEFAULT 1 +#define TARGET_DEFAULT MASK_UNIX_ASM #endif /* Target machine storage layout */ /* Define for software floating point emulation of VAX format when cross compiling from a non-VAX host. */ -/* #define REAL_ARITHMETIC */ + +#ifdef CROSS_COMPILE +#define REAL_ARITHMETIC +#endif /* Define this if most significant bit is lowest numbered in instructions that operate on numbered bit-fields. @@ -169,6 +181,8 @@ The latter must include the registers where values are returned and the register where structure-value addresses are passed. Aside from that, you can include as many other registers as you like. */ +/* test - comply with vax proc calling standard, */ +/* #define CALL_USED_REGISTERS {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1} */ #define CALL_USED_REGISTERS {1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1} /* Return number of consecutive hard regs needed starting at reg REGNO @@ -256,9 +270,11 @@ /* Define which registers fit in which classes. This is an initializer for a vector of HARD_REG_SET - of length N_REG_CLASSES. */ + of length N_REG_CLASSES. In this case hard_reg_set is an int, as + we can represent a bit mask of all hard registers within the host + integer type*/ -#define REG_CLASS_CONTENTS {0, 0xffff} +#define REG_CLASS_CONTENTS { {0}, {0xffff}} /* The same information, inverted: Return the class number of the smallest class containing @@ -276,16 +292,28 @@ #define REG_CLASS_FROM_LETTER(C) NO_REGS -/* The letters I, J, K, L and M in a register constraint string +/* The letters I, J, K, L, M, N, and O in a register constraint string can be used to stand for particular ranges of immediate operands. This macro defines what the ranges are. C is the letter, and VALUE is a constant value. Return 1 if VALUE is in the range specified by C. - `I' is the constant zero. */ - -#define CONST_OK_FOR_LETTER_P(VALUE, C) \ - ((C) == 'I' ? (VALUE) == 0 \ + `I' is the constant zero. + `J' is a value between 0 .. 63 (inclusive) S^# + `K' is a value between -128 and 127 (inclusive) B^ + 'L' is a value between -32768 and 32767 (include) W^ + `M' is a value between 0 and 255 (inclusive) B^ + 'N' is a value between 0 and 65535 (inclusive) W^ + `O' is a value between -63 and -1 (inclusive) */ + +#define CONST_OK_FOR_LETTER_P(VALUE, C) \ + ( (C) == 'I' ? (VALUE) == 0 \ + : (C) == 'J' ? 0 <= (VALUE) && (VALUE) < 64 \ + : (C) == 'O' ? -63 <= (VALUE) && (VALUE) < 0 \ + : (C) == 'K' ? -128 <= (VALUE) && (VALUE) < 128 \ + : (C) == 'M' ? 0 <= (VALUE) && (VALUE) < 256 \ + : (C) == 'L' ? -32768 <= (VALUE) && (VALUE) < 32768 \ + : (C) == 'N' ? 0 <= (VALUE) && (VALUE) < 65536 \ : 0) /* Similar, but for floating constants, and defining letters G and H. @@ -347,8 +375,7 @@ /* Given an rtx for the address of a frame, 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_INT (12)) +#define DYNAMIC_CHAIN_ADDRESS(FRAME) plus_constant ((FRAME), 12) /* If we generate an insn to push BYTES bytes, this says how many the stack pointer really advances by. @@ -466,8 +493,12 @@ mask |= 1 << regno; \ fprintf (FILE, "\t.word 0x%x\n", mask); \ MAYBE_VMS_FUNCTION_PROLOGUE(FILE) \ - if ((size) >= 64) fprintf (FILE, "\tmovab %d(sp),sp\n", -size);\ - else if (size) fprintf (FILE, "\tsubl2 $%d,sp\n", (size)); } + if ((size) >= 64) \ + fprintf (FILE, "\tmovab %d(%ssp),%ssp\n", -size, \ + REGISTER_PREFIX, REGISTER_PREFIX); \ + else if (size) \ + fprintf (FILE, "\tsubl2 $%d,%ssp\n", \ + (size), REGISTER_PREFIX); } /* vms.h redefines this. */ #define MAYBE_VMS_FUNCTION_PROLOGUE(FILE) @@ -495,8 +526,9 @@ */ #define BLOCK_PROFILER(FILE, BLOCKNO) \ - fprintf (FILE, "\tmovpsl -(sp)\n\tmovw (sp),2(sp)\n\taddl2 $2,sp\n\taddl2 $1,LPBX2+%d\n\tbicpsw $255\n\tbispsw (sp)+\n", \ - 4 * BLOCKNO) + fprintf (FILE, "\tmovpsl -(%ssp)\n\tmovw (%ssp),2(%ssp)\n\taddl2 $2,%ssp\n\taddl2 $1,LPBX2+%d\n\tbicpsw $255\n\tbispsw (%ssp)+\n", \ + 4 * BLOCKNO, REGISTER_PREFIX, REGISTER_PREFIX, REGISTER_PREFIX, \ + REGISTER_PREFIX, REGISTER_PREFIX) /* EXIT_IGNORE_STACK should be nonzero if, when returning from a function, the stack pointer does not matter. The value is tested only in @@ -548,12 +580,15 @@ FNADDR is an RTX for the address of the function's pure code. CXT is an RTX for the static chain value for the function. */ +/* This is separated out so register prefixes can be added by a target + if it requires them */ +#define VAX_ISTREAM_SYNC "movpsl -(sp)\n\tpushal 1(pc)\n\trei" + /* We copy the register-mask from the function's pure code to the start of the trampoline. */ #define INITIALIZE_TRAMPOLINE(TRAMP, FNADDR, CXT) \ { \ - emit_insn (gen_rtx (ASM_INPUT, VOIDmode, \ - "movpsl -(sp)\n\tpushal 1(pc)\n\trei")); \ + emit_insn (gen_rtx (ASM_INPUT, VOIDmode, VAX_ISTREAM_SYNC)); \ emit_move_insn (gen_rtx (MEM, HImode, TRAMP), \ gen_rtx (MEM, HImode, FNADDR)); \ emit_move_insn (gen_rtx (MEM, SImode, plus_constant (TRAMP, 4)), CXT);\ @@ -607,7 +642,7 @@ #define CONSTANT_ADDRESS_P(X) \ (GET_CODE (X) == LABEL_REF || GET_CODE (X) == SYMBOL_REF \ || GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST \ - || GET_CODE (X) == HIGH) + || GET_CODE (X) == CONSTANT_P_RTX || GET_CODE (X) == HIGH) /* Nonzero if the constant value X is a legitimate general operand. It is given that X satisfies CONSTANT_P or is a CONST_DOUBLE. */ @@ -635,6 +670,9 @@ /* Nonzero if X is a hard reg that can be used as a base reg or if it is a pseudo reg. */ #define REG_OK_FOR_BASE_P(X) 1 +#define LEGITIMATE_PIC_OPERAND_P(X) legitimate_pic_operand_p (X, 0) +#define GO_IF_LEGITIMATE_ADDRESS(ZMODE, XOP, LABEL) \ + do { if (legitimate_address_p(ZMODE, XOP, 0)) goto LABEL; } while (0) #else @@ -642,9 +680,13 @@ #define REG_OK_FOR_INDEX_P(X) REGNO_OK_FOR_INDEX_P (REGNO (X)) /* Nonzero if X is a hard reg that can be used as a base reg. */ #define REG_OK_FOR_BASE_P(X) REGNO_OK_FOR_BASE_P (REGNO (X)) +#define LEGITIMATE_PIC_OPERAND_P(X) legitimate_pic_operand_p (X, 1) +#define GO_IF_LEGITIMATE_ADDRESS(ZMODE, XOP, LABEL) \ + do { if (legitimate_address_p(ZMODE, XOP, 1)) goto LABEL; } while (0) #endif +#if 0 /* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression that is a valid memory address for an instruction. The MODE argument is the machine mode for the MEM expression @@ -667,7 +709,8 @@ /* Re-definition of CONSTANT_ADDRESS_P, which is true only when there are no SYMBOL_REFs for external symbols present. */ -#define INDIRECTABLE_CONSTANT_ADDRESS_P(X) \ +/* ** */ +#define INDIRECTABLE_CONSTANT_ADDRESS_P(X) \ (GET_CODE (X) == LABEL_REF \ || (GET_CODE (X) == SYMBOL_REF && !SYMBOL_REF_FLAG (X)) \ || (GET_CODE (X) == CONST && INDIRECTABLE_CONSTANT_P(X)) \ @@ -677,7 +720,7 @@ /* Non-zero if X is an address which can be indirected. External symbols could be in a sharable image library, so we disallow those. */ -#define INDIRECTABLE_ADDRESS_P(X) \ +#define INDIRECTABLE_ADDRESS_P(X) \ (INDIRECTABLE_CONSTANT_ADDRESS_P (X) \ || (GET_CODE (X) == REG && REG_OK_FOR_BASE_P (X)) \ || (GET_CODE (X) == PLUS \ @@ -725,21 +768,25 @@ or just a reg, if MODE is just one byte. This macro's expansion uses the temporary variables xfoo0 and xfoo1 that must be declared in the surrounding context. */ -#define INDEX_TERM_P(PROD, MODE) \ +#define INDEX_TERM_P(PROD, MODE) \ (GET_MODE_SIZE (MODE) == 1 \ ? (GET_CODE (PROD) == REG && REG_OK_FOR_BASE_P (PROD)) \ - : (GET_CODE (PROD) == MULT \ + : ( (GET_CODE (PROD) == MULT) \ && \ - (xfoo0 = XEXP (PROD, 0), xfoo1 = XEXP (PROD, 1), \ - ((GET_CODE (xfoo0) == CONST_INT \ - && INTVAL (xfoo0) == GET_MODE_SIZE (MODE) \ - && GET_CODE (xfoo1) == REG \ - && REG_OK_FOR_INDEX_P (xfoo1)) \ - || \ - (GET_CODE (xfoo1) == CONST_INT \ - && INTVAL (xfoo1) == GET_MODE_SIZE (MODE) \ - && GET_CODE (xfoo0) == REG \ - && REG_OK_FOR_INDEX_P (xfoo0)))))) + ( xfoo0 = XEXP (PROD, 0), \ + xfoo1 = XEXP (PROD, 1), \ + xfoo2 = ( \ + (GET_CODE (xfoo0) == CONST_INT) \ + && (INTVAL (xfoo0) == GET_MODE_SIZE (MODE)) \ + && (GET_CODE (xfoo1) == REG) \ + && (REG_OK_FOR_INDEX_P (xfoo1)) ), \ + xfoo3 = ( \ + (GET_CODE (xfoo1) == CONST_INT) \ + && (INTVAL (xfoo1) == GET_MODE_SIZE (MODE)) \ + && (GET_CODE (xfoo0) == REG) \ + && (REG_OK_FOR_INDEX_P (xfoo0)) ), \ + (xfoo2 || xfoo3 ) ))) + /* Go to ADDR if X is the sum of a register and a valid index term for mode MODE. */ @@ -759,6 +806,7 @@ #define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \ { register rtx xfoo, xfoo0, xfoo1; \ +int xfoo2, xfoo3; \ GO_IF_NONINDEXED_ADDRESS (X, ADDR); \ if (GET_CODE (X) == PLUS) \ { /* Handle
[index] represented with index-sum outermost */\ @@ -779,6 +827,7 @@ && REG_OK_FOR_BASE_P (XEXP (X, 0))) \ goto ADDR; \ GO_IF_REG_PLUS_INDEX (XEXP (X, 0), MODE, ADDR); } } } +#endif /* Try machine-dependent ways of modifying an illegitimate address to be legitimate. If we find one, return the new, valid address. @@ -808,8 +857,10 @@ goto LABEL; \ if (GET_CODE (ADDR) == PLUS) \ { if (CONSTANT_ADDRESS_P (XEXP (ADDR, 0)) \ + && (!flag_pic || GET_CODE (XEXP (ADDR, 0)) != SYMBOL_REF) \ && GET_CODE (XEXP (ADDR, 1)) == REG); \ else if (CONSTANT_ADDRESS_P (XEXP (ADDR, 1)) \ + && (!flag_pic || GET_CODE (XEXP (ADDR, 1)) != SYMBOL_REF) \ && GET_CODE (XEXP (ADDR, 0)) == REG); \ else goto LABEL; }} @@ -961,6 +1012,36 @@ #define MIN_G_FLOAT .556268464626800e-308 */ +/* Optionally define this if you have added predicates to + `MACHINE.c'. This macro is called within an initializer of an + array of structures. The first field in the structure is the + name of a predicate and the second field is an array of rtl + codes. For each predicate, list all rtl codes that can be in + expressions matched by the predicate. The list should have a + trailing comma. Here is an example of two entries in the list + for a typical RISC machine: + + #define PREDICATE_CODES \ + {"gen_reg_rtx_operand", {SUBREG, REG}}, \ + {"reg_or_short_cint_operand", {SUBREG, REG, CONST_INT}}, + + Defining this macro does not affect the generated code (however, + incorrect definitions that omit an rtl code that may be matched + by the predicate can cause the compiler to malfunction). + Instead, it allows the table built by `genrecog' to be more + compact and efficient, thus speeding up the compiler. The most + important predicates to include in the list specified by this + macro are thoses used in the most insn patterns. */ + +#define PREDICATE_CODES \ + {"vax_symbolic_operand", { SYMBOL_REF, LABEL_REF, CONST, PLUS }},\ + {"vax_lvalue_operand", { REG, SUBREG, MEM, CONCAT, PARALLEL, \ + STRICT_LOW_PART }}, \ + {"vax_nonsymbolic_operand", { CONST_INT, CONST_DOUBLE, SUBREG, REG, \ + MEM }}, \ + {"vax_general_operand", { CONST_INT, CONST_DOUBLE, SUBREG, REG, \ + MEM, SYMBOL_REF, LABEL_REF, CONST, PLUS }}, + /* Tell final.c how to eliminate redundant test instructions. */ /* Here we define machine-dependent flags and fields in cc_status @@ -975,9 +1056,15 @@ { if (GET_CODE (EXP) == SET) \ { if (GET_CODE (SET_SRC (EXP)) == CALL) \ CC_STATUS_INIT; \ + else if (GET_CODE (SET_SRC (EXP)) == COMPARE \ + || GET_CODE (SET_SRC (EXP)) == PLUS \ + || GET_CODE (SET_SRC (EXP)) == MINUS) \ + { cc_status.flags = 0; \ + cc_status.value1 = SET_DEST (EXP); \ + cc_status.value2 = SET_SRC (EXP); } \ else if (GET_CODE (SET_DEST (EXP)) != ZERO_EXTRACT \ && GET_CODE (SET_DEST (EXP)) != PC) \ - { cc_status.flags = 0; \ + { cc_status.flags = CC_NO_OVERFLOW; \ cc_status.value1 = SET_DEST (EXP); \ cc_status.value2 = SET_SRC (EXP); } } \ else if (GET_CODE (EXP) == PARALLEL \ @@ -986,7 +1073,7 @@ if (GET_CODE (SET_SRC (XVECEXP (EXP, 0, 0))) == CALL) \ CC_STATUS_INIT; \ else if (GET_CODE (SET_DEST (XVECEXP (EXP, 0, 0))) != PC) \ - { cc_status.flags = 0; \ + { cc_status.flags = CC_NO_OVERFLOW; \ cc_status.value1 = SET_DEST (XVECEXP (EXP, 0, 0)); \ cc_status.value2 = SET_SRC (XVECEXP (EXP, 0, 0)); } \ else \ @@ -1028,20 +1115,25 @@ /* Output before read-only data. */ -#define TEXT_SECTION_ASM_OP ".text" +#define TEXT_SECTION_ASM_OP "\t.text" /* Output before writable data. */ -#define DATA_SECTION_ASM_OP ".data" +#define DATA_SECTION_ASM_OP "\t.data" /* How to refer to registers in assembler output. - This sequence is indexed by compiler's hard-register-number (see above). */ + This sequence is indexed by compiler's hard-register-number (see above). + The register names will be prefixed by REGISTER_PREFIX, if any. */ + +#define REGISTER_PREFIX "" #define REGISTER_NAMES \ {"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", \ "r9", "r10", "r11", "ap", "fp", "sp", "pc"} -/* This is BSD, so it wants DBX format. */ +/* dbx format rather than dwarf */ +#undef PREFERRED_DEBUGGING_TYPE +#define PREFERRED_DEBUGGING_TYPE DBX_DEBUG #define DBX_DEBUGGING_INFO @@ -1064,8 +1156,10 @@ #define DBX_NO_XREFS -/* Output the .stabs for a C `static' variable in the data section. */ -#define DBX_STATIC_STAB_DATA_SECTION +/* Output the .stabs for a C `static' variable in the data section. + * Dont do this for elf. But may need this for a.out. Can this be + * conditional on the target type? */ +/*#define DBX_STATIC_STAB_DATA_SECTION*/ /* Vax specific: which type character is used for type double? */ @@ -1146,25 +1240,45 @@ It need not be very fast code. */ #define ASM_OUTPUT_REG_PUSH(FILE,REGNO) \ - fprintf (FILE, "\tpushl %s\n", reg_names[REGNO]) + fprintf (FILE, "\tpushl %s%s\n", REGISTER_PREFIX, reg_names[REGNO]) /* This is how to output an insn to pop a register from the stack. It need not be very fast code. */ #define ASM_OUTPUT_REG_POP(FILE,REGNO) \ - fprintf (FILE, "\tmovl (sp)+,%s\n", reg_names[REGNO]) + fprintf (FILE, "\tmovl (%ssp)+,%s%s\n", REGISTER_PREFIX, REGISTER_PREFIX, \ + reg_names[REGNO]) /* This is how to output an element of a case-vector that is absolute. (The Vax does not use such vectors, but we must define this macro anyway.) */ -#define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \ - fprintf (FILE, "\t.long L%d\n", VALUE) +#define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \ + do \ + { \ + char label[256]; \ + ASM_GENERATE_INTERNAL_LABEL (label, "L", (VALUE)); \ + fprintf (FILE, "\t.long "); \ + assemble_name (FILE, label); \ + fprintf (FILE, "\n"); \ + } \ + while (0) /* This is how to output an element of a case-vector that is relative. */ -#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) \ - fprintf (FILE, "\t.word L%d-L%d\n", VALUE, REL) +#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) \ + do \ + { \ + char label[256]; \ + ASM_GENERATE_INTERNAL_LABEL (label, "L", (VALUE)); \ + fprintf (FILE, "\t.word "); \ + assemble_name (FILE, label); \ + ASM_GENERATE_INTERNAL_LABEL (label, "L", (REL)); \ + fprintf (FILE, "-"); \ + assemble_name (FILE, label); \ + fprintf (FILE, "\n"); \ + } \ + while (0) /* This is how to output an assembler line that says to advance the location counter @@ -1223,7 +1337,7 @@ #define ASM_OUTPUT_MI_THUNK(FILE, THUNK_FNDECL, DELTA, FUNCTION) \ do { \ fprintf (FILE, "\t.word 0x0ffc\n"); \ - fprintf (FILE, "\taddl2 $%d,4(ap)\n", DELTA); \ + fprintf (FILE, "\taddl2 $%d,4(%sap)\n", DELTA, REGISTER_PREFIX); \ fprintf (FILE, "\tjmp "); \ assemble_name (FILE, XSTR (XEXP (DECL_RTL (FUNCTION), 0), 0)); \ fprintf (FILE, "+2\n"); \ @@ -1271,7 +1385,7 @@ ((CODE) == '#') #define PRINT_OPERAND(FILE, X, CODE) \ -{ extern char *rev_cond_name (); \ +{ extern const char *rev_cond_name (); \ if (CODE == '#') fputc (ASM_DOUBLE_CHAR, FILE); \ else if (CODE == 'C') \ fputs (rev_cond_name (X), FILE); \ @@ -1295,7 +1409,7 @@ else if (CODE == 'M' && GET_CODE (X) == CONST_INT) \ fprintf (FILE, "$%d", ~((1 << INTVAL (x)) - 1)); \ else if (GET_CODE (X) == REG) \ - fprintf (FILE, "%s", reg_names[REGNO (X)]); \ + fprintf (FILE, "%s%s", REGISTER_PREFIX, reg_names[REGNO (X)]); \ else if (GET_CODE (X) == MEM) \ output_address (XEXP (X, 0)); \ else if (GET_CODE (X) == CONST_DOUBLE && GET_MODE (X) == SFmode) \ @@ -1315,3 +1429,5 @@ #define PRINT_OPERAND_ADDRESS(FILE, ADDR) \ print_operand_address (FILE, ADDR) + +#define CHECK_FLOAT_VALUE_PROTO int check_float_value(enum machine_mode, REAL_VALUE_TYPE *, int) Index: config/vax/vax.md =================================================================== RCS file: /cvsroot/linux-vax/toolchain/src/gcc/config/vax/vax.md,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -r1.1.1.1 -r1.2 --- config/vax/vax.md 17 Feb 2003 00:25:55 -0000 1.1.1.1 +++ config/vax/vax.md 17 Feb 2003 01:38:22 -0000 1.2 @@ -135,20 +135,50 @@ ;; patterns need to be recognized. ;; -- Ken Raeburn (Raeburn@Watch.COM) 24 August 1991. +;; The original insns didn't allow for auto-increment or auto-decrement +;; addressing modes. The constraint was simply "=ro". This forced +;; GCC to reload the output operand when the result was being pushed +;; on the stack as part of an argument list. However, the reloading +;; code clobbered cc0, thus giving incorrect results. Compiling this +;; fragment with optimisation would generate incorrect code: +;; +;; extern unsigned int f(unsigned int); +;; unsigned int g(unsigned int x) { return f(x/0x80000001; } +;; +;; The reason for prohibiting auto-inc/dec is the two references to +;; %0 in the asm code. This would, obviously, end up incrementing +;; or decrementing twice if auto-inc/dec was allowed through. +;; +;; I've added the second alternative that will only match for +;; these auto-inc/dec cases and that guarantees only one +;; evaluation of %0. +;; -- Kenn Humborg (kenn@linux.ie) 17 August 2000 + (define_insn "sltu" - [(set (match_operand:SI 0 "general_operand" "=ro") + [(set (match_operand:SI 0 "general_operand" "=ro,<>") (ltu (cc0) (const_int 0)))] "" - "clrl %0\;adwc $0,%0") + "@ + clrl %0\;adwc $0,%0 + blssu .LB%=1f\;clrl %0\;brb .LB%=2f\;.LB%=1f: movl $1, %0\;.LB%=2f:") (define_insn "sgeu" - [(set (match_operand:SI 0 "general_operand" "=ro") + [(set (match_operand:SI 0 "general_operand" "=ro,<>") (geu (cc0) (const_int 0)))] "" - "movl $1,%0\;sbwc $0,%0") + "@ + movl $1,%0\;sbwc $0,%0 + bgequ .LB%=1f\;clrl %0\;brb .LB%=2f\;.LB%=1f: movl $1, %0\;.LB%=2f:") + +(define_insn "sleu" + [(set (match_operand:SI 0 "general_operand" "=g") + (leu (cc0) (const_int 0)))] + "" + "blequ .LB%=1f\;clrl %0\;brb .LB%=2f\;.LB%=1f: movl $1, %0\;.LB%=2f:") + (define_insn "movdf" - [(set (match_operand:DF 0 "general_operand" "=g,g") + [(set (match_operand:DF 0 "nonimmediate_operand" "=g,g") (match_operand:DF 1 "general_operand" "G,gF"))] "" "@ @@ -156,7 +186,7 @@ mov%# %1,%0") (define_insn "movsf" - [(set (match_operand:SF 0 "general_operand" "=g,g") + [(set (match_operand:SF 0 "nonimmediate_operand" "=g,g") (match_operand:SF 1 "general_operand" "G,gF"))] "" "@ @@ -171,7 +201,7 @@ ;; "movh %1,%0") (define_insn "movdi" - [(set (match_operand:DI 0 "general_operand" "=g,g") + [(set (match_operand:DI 0 "nonimmediate_operand" "=g,g") (match_operand:DI 1 "general_operand" "I,g"))] "" "@ @@ -195,8 +225,32 @@ ;; Loads of constants between 64 and 128 used to be done with ;; "addl3 $63,#,dst" but this is slower than movzbl and takes as much space. -(define_insn "movsi" - [(set (match_operand:SI 0 "general_operand" "=g") +(define_expand "movsi" + [(set (match_operand:SI 0 "nonimmediate_operand" "") + (match_operand:SI 1 "general_operand" ""))] + "" + " +{ + if (GET_CODE (operands[1]) == CONST && + GET_CODE (XEXP (operands[1], 0)) == PLUS && + GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == SYMBOL_REF && +#ifdef NO_EXTERNAL_INDIRECT_ADDRESS + (!flag_pic || !SYMBOL_REF_FLAG (XEXP (XEXP (operands[1], 0), 0))) && +#endif + GET_CODE (XEXP (XEXP (operands[1], 0), 1)) == CONST_INT) + { + rtx symbol_ref = XEXP (XEXP (operands[1], 0), 0); + rtx const_int = XEXP (XEXP (operands[1], 0), 1); + rtx temp = gen_reg_rtx (Pmode); + emit_move_insn (temp, symbol_ref); + emit_move_insn (operands[0], + plus_constant_for_output (temp, INTVAL (const_int))); + DONE; + } +}") + +(define_insn "movgensi" + [(set (match_operand:SI 0 "nonimmediate_operand" "=g") (match_operand:SI 1 "general_operand" "g"))] "" "* @@ -212,15 +266,21 @@ /* Make sure the reg hasn't been clobbered. */ && ! reg_set_between_p (operands[0], XEXP (link, 0), insn)) return \"incl %0\"; - if (GET_CODE (operands[1]) == SYMBOL_REF || GET_CODE (operands[1]) == CONST) + if (GET_CODE (operands[1]) == SYMBOL_REF + || GET_CODE (operands[1]) == LABEL_REF + || GET_CODE (operands[1]) == CONST) { if (push_operand (operands[0], SImode)) return \"pushab %a1\"; return \"movab %a1,%0\"; } if (operands[1] == const0_rtx) - return \"clrl %0\"; - if (GET_CODE (operands[1]) == CONST_INT + { + if (push_operand (operands[0], SImode)) + return \"pushl %1\"; + return \"clrl %0\"; + } + if ( ((GET_CODE (operands[1]) == CONST_INT) || (GET_CODE (operands[1]) == CONSTANT_P_RTX)) && (unsigned) INTVAL (operands[1]) >= 64) { int i = INTVAL (operands[1]); @@ -241,7 +301,7 @@ }") (define_insn "movhi" - [(set (match_operand:HI 0 "general_operand" "=g") + [(set (match_operand:HI 0 "nonimmediate_operand" "=g") (match_operand:HI 1 "general_operand" "g"))] "" "* @@ -258,7 +318,8 @@ && ! reg_set_between_p (operands[0], XEXP (link, 0), insn)) return \"incw %0\"; - if (GET_CODE (operands[1]) == CONST_INT) + if ( ((GET_CODE (operands[1]) == CONST_INT) + || (GET_CODE (operands[1]) == CONSTANT_P_RTX))) { int i = INTVAL (operands[1]); if (i == 0) @@ -274,12 +335,13 @@ }") (define_insn "movstricthi" - [(set (strict_low_part (match_operand:HI 0 "register_operand" "=g")) + [(set (strict_low_part (match_operand:HI 0 "register_operand" "+g")) (match_operand:HI 1 "general_operand" "g"))] "" "* { - if (GET_CODE (operands[1]) == CONST_INT) + if ( ((GET_CODE (operands[1]) == CONST_INT) + || (GET_CODE (operands[1]) == CONSTANT_P_RTX))) { int i = INTVAL (operands[1]); if (i == 0) @@ -295,7 +357,7 @@ }") (define_insn "movqi" - [(set (match_operand:QI 0 "general_operand" "=g") + [(set (match_operand:QI 0 "nonimmediate_operand" "=g") (match_operand:QI 1 "general_operand" "g"))] "" "* @@ -312,7 +374,8 @@ && ! reg_set_between_p (operands[0], XEXP (link, 0), insn)) return \"incb %0\"; - if (GET_CODE (operands[1]) == CONST_INT) + if ( ((GET_CODE (operands[1]) == CONST_INT) + || (GET_CODE (operands[1]) == CONSTANT_P_RTX))) { int i = INTVAL (operands[1]); if (i == 0) @@ -324,12 +387,13 @@ }") (define_insn "movstrictqi" - [(set (strict_low_part (match_operand:QI 0 "register_operand" "=g")) + [(set (strict_low_part (match_operand:QI 0 "register_operand" "+g")) (match_operand:QI 1 "general_operand" "g"))] "" "* { - if (GET_CODE (operands[1]) == CONST_INT) + if ((GET_CODE (operands[1]) == CONST_INT) + || (GET_CODE (operands[1]) == CONSTANT_P_RTX)) { int i = INTVAL (operands[1]); if (i == 0) @@ -358,8 +422,8 @@ ;; that anything generated as this insn will be recognized as one ;; and that it won't successfully combine with anything. (define_insn "movstrhi1" - [(set (match_operand:BLK 0 "general_operand" "=g") - (match_operand:BLK 1 "general_operand" "g")) + [(set (match_operand:BLK 0 "memory_operand" "=m") + (match_operand:BLK 1 "memory_operand" "m")) (use (match_operand:HI 2 "general_operand" "g")) (clobber (reg:SI 0)) (clobber (reg:SI 1)) @@ -373,67 +437,67 @@ ;; Extension and truncation insns. (define_insn "truncsiqi2" - [(set (match_operand:QI 0 "general_operand" "=g") + [(set (match_operand:QI 0 "nonimmediate_operand" "=g") (truncate:QI (match_operand:SI 1 "nonimmediate_operand" "g")))] "" "cvtlb %1,%0") (define_insn "truncsihi2" - [(set (match_operand:HI 0 "general_operand" "=g") + [(set (match_operand:HI 0 "nonimmediate_operand" "=g") (truncate:HI (match_operand:SI 1 "nonimmediate_operand" "g")))] "" "cvtlw %1,%0") (define_insn "trunchiqi2" - [(set (match_operand:QI 0 "general_operand" "=g") + [(set (match_operand:QI 0 "nonimmediate_operand" "=g") (truncate:QI (match_operand:HI 1 "nonimmediate_operand" "g")))] "" "cvtwb %1,%0") (define_insn "extendhisi2" - [(set (match_operand:SI 0 "general_operand" "=g") + [(set (match_operand:SI 0 "nonimmediate_operand" "=g") (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "g")))] "" "cvtwl %1,%0") (define_insn "extendqihi2" - [(set (match_operand:HI 0 "general_operand" "=g") + [(set (match_operand:HI 0 "nonimmediate_operand" "=g") (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "g")))] "" "cvtbw %1,%0") (define_insn "extendqisi2" - [(set (match_operand:SI 0 "general_operand" "=g") + [(set (match_operand:SI 0 "nonimmediate_operand" "=g") (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "g")))] "" "cvtbl %1,%0") (define_insn "extendsfdf2" - [(set (match_operand:DF 0 "general_operand" "=g") + [(set (match_operand:DF 0 "nonimmediate_operand" "=g") (float_extend:DF (match_operand:SF 1 "general_operand" "gF")))] "" "cvtf%# %1,%0") (define_insn "truncdfsf2" - [(set (match_operand:SF 0 "general_operand" "=g") + [(set (match_operand:SF 0 "nonimmediate_operand" "=g") (float_truncate:SF (match_operand:DF 1 "general_operand" "gF")))] "" "cvt%#f %1,%0") (define_insn "zero_extendhisi2" - [(set (match_operand:SI 0 "general_operand" "=g") + [(set (match_operand:SI 0 "nonimmediate_operand" "=g") (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "g")))] "" "movzwl %1,%0") (define_insn "zero_extendqihi2" - [(set (match_operand:HI 0 "general_operand" "=g") + [(set (match_operand:HI 0 "nonimmediate_operand" "=g") (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "g")))] "" "movzbw %1,%0") (define_insn "zero_extendqisi2" - [(set (match_operand:SI 0 "general_operand" "=g") + [(set (match_operand:SI 0 "nonimmediate_operand" "=g") (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "g")))] "" "movzbl %1,%0") @@ -441,37 +505,37 @@ ;; Fix-to-float conversion insns. (define_insn "floatsisf2" - [(set (match_operand:SF 0 "general_operand" "=g") + [(set (match_operand:SF 0 "nonimmediate_operand" "=g") (float:SF (match_operand:SI 1 "nonimmediate_operand" "g")))] "" "cvtlf %1,%0") (define_insn "floatsidf2" - [(set (match_operand:DF 0 "general_operand" "=g") + [(set (match_operand:DF 0 "nonimmediate_operand" "=g") (float:DF (match_operand:SI 1 "nonimmediate_operand" "g")))] "" "cvtl%# %1,%0") (define_insn "floathisf2" - [(set (match_operand:SF 0 "general_operand" "=g") + [(set (match_operand:SF 0 "nonimmediate_operand" "=g") (float:SF (match_operand:HI 1 "nonimmediate_operand" "g")))] "" "cvtwf %1,%0") (define_insn "floathidf2" - [(set (match_operand:DF 0 "general_operand" "=g") + [(set (match_operand:DF 0 "nonimmediate_operand" "=g") (float:DF (match_operand:HI 1 "nonimmediate_operand" "g")))] "" "cvtw%# %1,%0") (define_insn "floatqisf2" - [(set (match_operand:SF 0 "general_operand" "=g") + [(set (match_operand:SF 0 "nonimmediate_operand" "=g") (float:SF (match_operand:QI 1 "nonimmediate_operand" "g")))] "" "cvtbf %1,%0") (define_insn "floatqidf2" - [(set (match_operand:DF 0 "general_operand" "=g") + [(set (match_operand:DF 0 "nonimmediate_operand" "=g") (float:DF (match_operand:QI 1 "nonimmediate_operand" "g")))] "" "cvtb%# %1,%0") @@ -479,37 +543,37 @@ ;; Float-to-fix conversion insns. (define_insn "fix_truncsfqi2" - [(set (match_operand:QI 0 "general_operand" "=g") + [(set (match_operand:QI 0 "nonimmediate_operand" "=g") (fix:QI (fix:SF (match_operand:SF 1 "general_operand" "gF"))))] "" "cvtfb %1,%0") (define_insn "fix_truncsfhi2" - [(set (match_operand:HI 0 "general_operand" "=g") + [(set (match_operand:HI 0 "nonimmediate_operand" "=g") (fix:HI (fix:SF (match_operand:SF 1 "general_operand" "gF"))))] "" "cvtfw %1,%0") (define_insn "fix_truncsfsi2" - [(set (match_operand:SI 0 "general_operand" "=g") + [(set (match_operand:SI 0 "nonimmediate_operand" "=g") (fix:SI (fix:SF (match_operand:SF 1 "general_operand" "gF"))))] "" "cvtfl %1,%0") (define_insn "fix_truncdfqi2" - [(set (match_operand:QI 0 "general_operand" "=g") + [(set (match_operand:QI 0 "nonimmediate_operand" "=g") (fix:QI (fix:DF (match_operand:DF 1 "general_operand" "gF"))))] "" "cvt%#b %1,%0") (define_insn "fix_truncdfhi2" - [(set (match_operand:HI 0 "general_operand" "=g") + [(set (match_operand:HI 0 "nonimmediate_operand" "=g") (fix:HI (fix:DF (match_operand:DF 1 "general_operand" "gF"))))] "" "cvt%#w %1,%0") (define_insn "fix_truncdfsi2" - [(set (match_operand:SI 0 "general_operand" "=g") + [(set (match_operand:SI 0 "nonimmediate_operand" "=g") (fix:SI (fix:DF (match_operand:DF 1 "general_operand" "gF"))))] "" "cvt%#l %1,%0") @@ -517,7 +581,7 @@ ;;- All kinds of add instructions. (define_insn "adddf3" - [(set (match_operand:DF 0 "general_operand" "=g,g,g") + [(set (match_operand:DF 0 "nonimmediate_operand" "=g,g,g") (plus:DF (match_operand:DF 1 "general_operand" "0,gF,gF") (match_operand:DF 2 "general_operand" "gF,0,gF")))] "" @@ -527,7 +591,7 @@ add%#3 %1,%2,%0") (define_insn "addsf3" - [(set (match_operand:SF 0 "general_operand" "=g,g,g") + [(set (match_operand:SF 0 "nonimmediate_operand" "=g,g,g") (plus:SF (match_operand:SF 1 "general_operand" "0,gF,gF") (match_operand:SF 2 "general_operand" "gF,0,gF")))] "" @@ -550,7 +614,7 @@ (define_insn "addsi3" - [(set (match_operand:SI 0 "general_operand" "=g") + [(set (match_operand:SI 0 "nonimmediate_operand" "=g") (plus:SI (match_operand:SI 1 "general_operand" "g") (match_operand:SI 2 "general_operand" "g")))] "" @@ -602,7 +666,7 @@ }") (define_insn "addhi3" - [(set (match_operand:HI 0 "general_operand" "=g") + [(set (match_operand:HI 0 "nonimmediate_operand" "=g") (plus:HI (match_operand:HI 1 "general_operand" "g") (match_operand:HI 2 "general_operand" "g")))] "" @@ -628,7 +692,7 @@ }") (define_insn "addqi3" - [(set (match_operand:QI 0 "general_operand" "=g") + [(set (match_operand:QI 0 "nonimmediate_operand" "=g") (plus:QI (match_operand:QI 1 "general_operand" "g") (match_operand:QI 2 "general_operand" "g")))] "" @@ -655,14 +719,14 @@ ;; The add-with-carry (adwc) instruction only accepts two operands. (define_insn "adddi3" - [(set (match_operand:DI 0 "general_operand" "=ro>,ro>") + [(set (match_operand:DI 0 "nonimmediate_operand" "=ro>,ro>") (plus:DI (match_operand:DI 1 "general_operand" "%0,ro>") (match_operand:DI 2 "general_operand" "Fro,F")))] "" "* { rtx low[3]; - char *pattern; + const char *pattern; int carry = 1; split_quadword_operands (operands, low, 3); @@ -700,7 +764,7 @@ ;;- All kinds of subtract instructions. (define_insn "subdf3" - [(set (match_operand:DF 0 "general_operand" "=g,g") + [(set (match_operand:DF 0 "nonimmediate_operand" "=g,g") (minus:DF (match_operand:DF 1 "general_operand" "0,gF") (match_operand:DF 2 "general_operand" "gF,gF")))] "" @@ -709,7 +773,7 @@ sub%#3 %2,%1,%0") (define_insn "subsf3" - [(set (match_operand:SF 0 "general_operand" "=g,g") + [(set (match_operand:SF 0 "nonimmediate_operand" "=g,g") (minus:SF (match_operand:SF 1 "general_operand" "0,gF") (match_operand:SF 2 "general_operand" "gF,gF")))] "" @@ -718,7 +782,7 @@ subf3 %2,%1,%0") (define_insn "subsi3" - [(set (match_operand:SI 0 "general_operand" "=g,g") + [(set (match_operand:SI 0 "nonimmediate_operand" "=g,g") (minus:SI (match_operand:SI 1 "general_operand" "0,g") (match_operand:SI 2 "general_operand" "g,g")))] "" @@ -727,7 +791,7 @@ subl3 %2,%1,%0") (define_insn "subhi3" - [(set (match_operand:HI 0 "general_operand" "=g,g") + [(set (match_operand:HI 0 "nonimmediate_operand" "=g,g") (minus:HI (match_operand:HI 1 "general_operand" "0,g") (match_operand:HI 2 "general_operand" "g,g")))] "" @@ -736,7 +800,7 @@ subw3 %2,%1,%0") (define_insn "subqi3" - [(set (match_operand:QI 0 "general_operand" "=g,g") + [(set (match_operand:QI 0 "nonimmediate_operand" "=g,g") (minus:QI (match_operand:QI 1 "general_operand" "0,g") (match_operand:QI 2 "general_operand" "g,g")))] "" @@ -746,14 +810,14 @@ ;; The subtract-with-carry (sbwc) instruction only takes two operands. (define_insn "subdi3" - [(set (match_operand:DI 0 "general_operand" "=or>,or>") + [(set (match_operand:DI 0 "nonimmediate_operand" "=or>,or>") (minus:DI (match_operand:DI 1 "general_operand" "0,or>") (match_operand:DI 2 "general_operand" "For,F")))] "" "* { rtx low[3]; - char *pattern; + const char *pattern; int carry = 1; split_quadword_operands (operands, low, 3); @@ -791,7 +855,7 @@ ;;- Multiply instructions. (define_insn "muldf3" - [(set (match_operand:DF 0 "general_operand" "=g,g,g") + [(set (match_operand:DF 0 "nonimmediate_operand" "=g,g,g") (mult:DF (match_operand:DF 1 "general_operand" "0,gF,gF") (match_operand:DF 2 "general_operand" "gF,0,gF")))] "" @@ -801,7 +865,7 @@ mul%#3 %1,%2,%0") (define_insn "mulsf3" - [(set (match_operand:SF 0 "general_operand" "=g,g,g") + [(set (match_operand:SF 0 "nonimmediate_operand" "=g,g,g") (mult:SF (match_operand:SF 1 "general_operand" "0,gF,gF") (match_operand:SF 2 "general_operand" "gF,0,gF")))] "" @@ -811,7 +875,7 @@ mulf3 %1,%2,%0") (define_insn "mulsi3" - [(set (match_operand:SI 0 "general_operand" "=g,g,g") + [(set (match_operand:SI 0 "nonimmediate_operand" "=g,g,g") (mult:SI (match_operand:SI 1 "general_operand" "0,g,g") (match_operand:SI 2 "general_operand" "g,0,g")))] "" @@ -821,7 +885,7 @@ mull3 %1,%2,%0") (define_insn "mulhi3" - [(set (match_operand:HI 0 "general_operand" "=g,g,") + [(set (match_operand:HI 0 "nonimmediate_operand" "=g,g,") (mult:HI (match_operand:HI 1 "general_operand" "0,g,g") (match_operand:HI 2 "general_operand" "g,0,g")))] "" @@ -831,7 +895,7 @@ mulw3 %1,%2,%0") (define_insn "mulqi3" - [(set (match_operand:QI 0 "general_operand" "=g,g,g") + [(set (match_operand:QI 0 "nonimmediate_operand" "=g,g,g") (mult:QI (match_operand:QI 1 "general_operand" "0,g,g") (match_operand:QI 2 "general_operand" "g,0,g")))] "" @@ -841,7 +905,7 @@ mulb3 %1,%2,%0") (define_insn "mulsidi3" - [(set (match_operand:DI 0 "general_operand" "=g") + [(set (match_operand:DI 0 "nonimmediate_operand" "=g") (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "g")) (sign_extend:DI @@ -850,7 +914,7 @@ "emul %1,%2,$0,%0") (define_insn "" - [(set (match_operand:DI 0 "general_operand" "=g") + [(set (match_operand:DI 0 "nonimmediate_operand" "=g") (plus:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "g")) @@ -862,7 +926,7 @@ ;; 'F' constraint means type CONST_DOUBLE (define_insn "" - [(set (match_operand:DI 0 "general_operand" "=g") + [(set (match_operand:DI 0 "nonimmediate_operand" "=g") (plus:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "g")) @@ -881,7 +945,7 @@ ;;- Divide instructions. (define_insn "divdf3" - [(set (match_operand:DF 0 "general_operand" "=g,g") + [(set (match_operand:DF 0 "nonimmediate_operand" "=g,g") (div:DF (match_operand:DF 1 "general_operand" "0,gF") (match_operand:DF 2 "general_operand" "gF,gF")))] "" @@ -890,7 +954,7 @@ div%#3 %2,%1,%0") (define_insn "divsf3" - [(set (match_operand:SF 0 "general_operand" "=g,g") + [(set (match_operand:SF 0 "nonimmediate_operand" "=g,g") (div:SF (match_operand:SF 1 "general_operand" "0,gF") (match_operand:SF 2 "general_operand" "gF,gF")))] "" @@ -899,7 +963,7 @@ divf3 %2,%1,%0") (define_insn "divsi3" - [(set (match_operand:SI 0 "general_operand" "=g,g") + [(set (match_operand:SI 0 "nonimmediate_operand" "=g,g") (div:SI (match_operand:SI 1 "general_operand" "0,g") (match_operand:SI 2 "general_operand" "g,g")))] "" @@ -908,7 +972,7 @@ divl3 %2,%1,%0") (define_insn "divhi3" - [(set (match_operand:HI 0 "general_operand" "=g,g") + [(set (match_operand:HI 0 "nonimmediate_operand" "=g,g") (div:HI (match_operand:HI 1 "general_operand" "0,g") (match_operand:HI 2 "general_operand" "g,g")))] "" @@ -917,7 +981,7 @@ divw3 %2,%1,%0") (define_insn "divqi3" - [(set (match_operand:QI 0 "general_operand" "=g,g") + [(set (match_operand:QI 0 "nonimmediate_operand" "=g,g") (div:QI (match_operand:QI 1 "general_operand" "0,g") (match_operand:QI 2 "general_operand" "g,g")))] "" @@ -936,10 +1000,302 @@ ; (match_operand:SI 2 "general_operand" "g")))] ; "" ; "ediv %2,%1,%0,%3") + +(define_insn "ediv_helper" + [(set (match_operand:SI 2 "general_operand" "=g") + (div:SI (match_operand:SI 0 "general_operand" "g") + (match_operand:DI 1 "general_operand" "g"))) + (set (match_operand:SI 3 "general_operand" "=g") + (mod:SI (match_dup 0) + (match_dup 1)))] + "" + "ediv %0,%1,%2,%3") + + +(define_expand "udivsi3" + [(set (match_operand:SI 0 "general_operand" "=g") + (udiv:SI (match_operand:SI 1 "general_operand" "g") + (match_operand:SI 2 "general_operand" "g")))] + "" + " +{ + rtx remainder = gen_reg_rtx(SImode); + rtx dividend_di = gen_reg_rtx(DImode); + rtx dividend = gen_rtx(SUBREG, SImode, dividend_di, 0); + rtx dividend_hi = gen_rtx(SUBREG, SImode, dividend_di, 1); + + rtx label_easy = gen_label_rtx(); + rtx label_ediv = gen_label_rtx(); + rtx label_end = gen_label_rtx(); + + /* we have to deal with the case where one of the operands is + a constant, because otherwise invalid RTXs will be generated. + Both operands can never be constant, because constant + folding will already have eliminated then. */ + + if (GET_CODE (operands[2]) == CONST_INT) { + + /* Divisor is constant */ + + if (INTVAL (operands[2]) > 0) { + + /* Divisor <= 0x7fffffff. If dividend is also <= 0x7fffffff, + then signed division is OK, otherwise need to do extended + (64-bit) division */ + + emit_insn(gen_tstsi(operands[1])); + emit_jump_insn(gen_blt(label_ediv)); + + emit_insn(gen_divsi3(operands[0], operands[1], operands[2])); + emit_jump_insn(gen_jump(label_end)); + + } else { + + /* divisor is >= 0x80000000, so quotient can only be 1 or 0 + depending on which is bigger, dividend or divisor, + respectively */ + + emit_insn(gen_cmpsi(operands[1], operands[2])); + emit_insn(gen_sgeu(operands[0])); + + } + } else if (GET_CODE (operands[1]) == CONST_INT) { + + /* Dividend is constant, divisor is variable */ + if (INTVAL (operands[1]) > 0) { + + /* Dividend <= 0x7fffffff. If divisor is also <= 0x7fffffff, + then signed division is OK, otherwise quotient must be 0 */ + + emit_move_insn(operands[0], const0_rtx); + emit_insn(gen_tstsi(operands[2])); + emit_jump_insn(gen_blt(label_end)); + + emit_insn(gen_divsi3(operands[0], operands[1], operands[2])); + + } else { + + /* Is divisor <= 0x7fffffff ? (i.e. high bit clear, so looks positive) */ + emit_insn(gen_tstsi(operands[2])); + emit_jump_insn(gen_bge(label_ediv)); + + /* divisor is >= 0x80000000, so quotient can only be 1 or 0 + depending on which is bigger, dividend or divisor, + respectively */ + emit_insn(gen_cmpsi(operands[2], operands[1])); + emit_insn(gen_sleu(operands[0])); + } + } else { + + /* Is divisor >= 0x80000000 ? (i.e. high bit set, so looks negative) */ + emit_insn(gen_tstsi(operands[2])); + emit_jump_insn(gen_blt(label_easy)); + + emit_insn(gen_tstsi(operands[1])); + emit_jump_insn(gen_blt(label_ediv)); + + /* Both <= 0x7fffffff - signed division OK */ + emit_insn(gen_divsi3(operands[0], operands[1], operands[2])); + emit_jump_insn(gen_jump(label_end)); + + emit_label(label_easy); + + /* divisor is >= 0x80000000, so quotient can only be 1 or 0 + depending on which is bigger, dividend or divisor, + respectively */ + + emit_insn(gen_cmpsi(operands[1], operands[2])); + emit_insn(gen_sgeu(operands[0])); + + } + + emit_jump_insn(gen_jump(label_end)); + + emit_label(label_ediv); + /* Dividend is >= 0x80000000 and divisor <= 0x7fffffff, + so we'll use the EDIV instruction instead (EDIV divides + a quadword by a longword, or a DImode by an SImode in + RTL-speak, and produces both quotient and remainder) */ + + emit_move_insn(dividend, operands[1]); + emit_move_insn(dividend_hi, const0_rtx); + + emit_insn(gen_ediv_helper(operands[2], dividend_di, operands[0], remainder)); + + emit_label(label_end); + + DONE; +} +") + +(define_expand "umodsi3" + [(set (match_operand:SI 0 "general_operand" "=g") + (umod:SI (match_operand:SI 1 "general_operand" "g") + (match_operand:SI 2 "general_operand" "g")))] + "" + " +{ + rtx quotient = gen_reg_rtx(SImode); + rtx dividend_di = gen_reg_rtx(DImode); + rtx dividend = gen_rtx(SUBREG, SImode, dividend_di, 0); + rtx dividend_hi = gen_rtx(SUBREG, SImode, dividend_di, 1); + + rtx label_signed_mod = gen_label_rtx(); + rtx label_compare = gen_label_rtx(); + rtx label_ediv = gen_label_rtx(); + rtx label_end = gen_label_rtx(); + + int emit_signed_mod_code = 0; + int emit_compare_code = 0; + int emit_ediv_code = 0; + + /* we have to deal with the case where one of the operands is + a constant, because otherwise invalid RTXs will be generated. + Both operands can never be constant, because constant + folding will already have eliminated then. */ + + if (GET_CODE (operands[2]) == CONST_INT) { + + /* Divisor is constant */ + + if (INTVAL (operands[2]) > 0) { + + /* Divisor <= 0x7fffffff. If dividend is also <= 0x7fffffff, + then signed division is OK, otherwise need to do extended + (64-bit) division */ + + emit_insn(gen_tstsi(operands[1])); + emit_jump_insn(gen_bge(label_signed_mod)); + emit_jump_insn(gen_jump(label_ediv)); + + emit_signed_mod_code = 1; + emit_ediv_code = 1; + + } else { + + /* divisor is >= 0x80000000, calculate by comparison */ + emit_jump_insn(gen_jump(label_compare)); + + emit_compare_code = 1; + } + + } else if (GET_CODE (operands[1]) == CONST_INT) { + + /* I don't know why, but GCC never seems to end up here */ + + /* Dividend is constant, divisor is variable */ + if (INTVAL (operands[1]) > 0) { + + /* Dividend <= 0x7fffffff. If divisor is also <= 0x7fffffff, + then signed modulus is OK, otherwise do 64-bit division */ + + emit_insn(gen_tstsi(operands[2])); + emit_jump_insn(gen_bge(label_signed_mod)); + emit_jump_insn(gen_jump(label_ediv)); + + emit_signed_mod_code = 1; + emit_ediv_code = 1; + + } else { + + /* Dividend >= 0x80000000. If divisor is also >= 0x80000000, + then do mod-by-comparison, otherwise do 64-bit division */ + + emit_insn(gen_tstsi(operands[2])); + emit_jump_insn(gen_blt(label_compare)); + emit_jump_insn(gen_jump(label_ediv)); + + emit_compare_code = 1; + emit_ediv_code = 1; + } + } else { + + /* Is divisor >= 0x80000000 ? (i.e. high bit set, so looks negative) */ + emit_insn(gen_tstsi(operands[2])); + emit_jump_insn(gen_blt(label_compare)); + + /* Is dividend >= 0x80000000 ? (i.e. high bit set, so looks negative) */ + emit_insn(gen_tstsi(operands[1])); + emit_jump_insn(gen_blt(label_ediv)); + + /* Both <= 0x7fffffff - signed modulus OK */ + emit_jump_insn(gen_jump(label_signed_mod)); + + emit_ediv_code = 1; + emit_compare_code = 1; + emit_signed_mod_code = 1; + } + + if (emit_signed_mod_code) { + emit_label(label_signed_mod); + + /* Both <= 0x7fffffff - signed modulus OK */ + emit_insn(gen_divsi3(quotient, operands[1], operands[2])); + emit_insn(gen_mulsi3(quotient, quotient, operands[2])); + emit_insn(gen_subsi3(operands[0], operands[1], quotient)); + emit_jump_insn(gen_jump(label_end)); + + /* Emit code to use extended division instruction */ + } + + if (emit_ediv_code) { + emit_label(label_ediv); + + /* Dividend is >= 0x80000000 and divisor <= 0x7fffffff, + so we'll use the EDIV instruction instead (EDIV divides + a quadword by a longword, or a DImode by an SImode in + RTL-speak, and produces both quotient and remainder) */ + + emit_move_insn(dividend, operands[1]); + emit_move_insn(dividend_hi, const0_rtx); + + emit_insn(gen_ediv_helper(operands[2], dividend_di, quotient, operands[0])); + emit_jump_insn(gen_jump(label_end)); + } + + if (emit_compare_code) { + /* Emit code to to mod-by-comparison. */ + emit_label(label_compare); + emit_insn(gen_umodsi3_compare(operands[0], operands[1], operands[2])); + } + + emit_label(label_end); + + DONE; +} +") + +;; This is used by the umodsi3 define_expand above. It will never +;; be matched by GCC because it is more specific than the umodsi3 +;; definition, and GCC matches insns in the order they occur in +;; this file. This is essential, because the code generated here +;; is only valid for the case where the divisor is >= 0x80000000, +;; so dividend/divisor can only be 0 or 1 depending on which +;; is bigger, dividend or divisor. This means that the remainder +;; can be calculated without a division +;; +;; If divisor is bigger, then quotient is 0, so remainder is +;; +;; dividend - (divisor * quotient) +;; = dividend - (divisor * 0) +;; = dividend +;; +;; If dividend is bigger, then quotient is 1, so remainder is +;; +;; dividend - (divisor * quotient) +;; = dividend - (divisor * 1) +;; = dividend - divisor +(define_insn "umodsi3_compare" + [(set (match_operand:SI 0 "general_operand" "=ro") + (umod:SI (match_operand:SI 1 "general_operand" "ro") + (match_operand:SI 2 "general_operand" "g")))] + "" + "subl3 %2, %1, %0\;bcc .LB%=\;movl %1, %0\;.LB%=:") + ;; Bit-and on the vax is done with a clear-bits insn. (define_expand "andsi3" - [(set (match_operand:SI 0 "general_operand" "=g") + [(set (match_operand:SI 0 "nonimmediate_operand" "=g") (and:SI (not:SI (match_operand:SI 1 "general_operand" "g")) (match_operand:SI 2 "general_operand" "g")))] "" @@ -962,7 +1318,7 @@ }") (define_expand "andhi3" - [(set (match_operand:HI 0 "general_operand" "=g") + [(set (match_operand:HI 0 "nonimmediate_operand" "=g") (and:HI (not:HI (match_operand:HI 1 "general_operand" "g")) (match_operand:HI 2 "general_operand" "g")))] "" @@ -984,7 +1340,7 @@ }") (define_expand "andqi3" - [(set (match_operand:QI 0 "general_operand" "=g") + [(set (match_operand:QI 0 "nonimmediate_operand" "=g") (and:QI (not:QI (match_operand:QI 1 "general_operand" "g")) (match_operand:QI 2 "general_operand" "g")))] "" @@ -1006,7 +1362,7 @@ }") (define_insn "" - [(set (match_operand:SI 0 "general_operand" "=g,g") + [(set (match_operand:SI 0 "nonimmediate_operand" "=g,g") (and:SI (not:SI (match_operand:SI 1 "general_operand" "g,g")) (match_operand:SI 2 "general_operand" "0,g")))] "" @@ -1015,7 +1371,7 @@ bicl3 %1,%2,%0") (define_insn "" - [(set (match_operand:HI 0 "general_operand" "=g,g") + [(set (match_operand:HI 0 "nonimmediate_operand" "=g,g") (and:HI (not:HI (match_operand:HI 1 "general_operand" "g,g")) (match_operand:HI 2 "general_operand" "0,g")))] "" @@ -1024,7 +1380,7 @@ bicw3 %1,%2,%0") (define_insn "" - [(set (match_operand:QI 0 "general_operand" "=g,g") + [(set (match_operand:QI 0 "nonimmediate_operand" "=g,g") (and:QI (not:QI (match_operand:QI 1 "general_operand" "g,g")) (match_operand:QI 2 "general_operand" "0,g")))] "" @@ -1038,7 +1394,7 @@ ;; opportunities in combine.c. (define_insn "" - [(set (match_operand:SI 0 "general_operand" "=g,g") + [(set (match_operand:SI 0 "nonimmediate_operand" "=g,g") (and:SI (match_operand:SI 1 "general_operand" "0,g") (match_operand:SI 2 "const_int_operand" "n,n")))] "" @@ -1047,7 +1403,7 @@ bicl3 %N2,%1,%0") (define_insn "" - [(set (match_operand:HI 0 "general_operand" "=g,g") + [(set (match_operand:HI 0 "nonimmediate_operand" "=g,g") (and:HI (match_operand:HI 1 "general_operand" "0,g") (match_operand:HI 2 "const_int_operand" "n,n")))] "" @@ -1056,7 +1412,7 @@ bicw3 %H2,%1,%0") (define_insn "" - [(set (match_operand:QI 0 "general_operand" "=g,g") + [(set (match_operand:QI 0 "nonimmediate_operand" "=g,g") (and:QI (match_operand:QI 1 "general_operand" "0,g") (match_operand:QI 2 "const_int_operand" "n,n")))] "" @@ -1067,7 +1423,7 @@ ;;- Bit set instructions. (define_insn "iorsi3" - [(set (match_operand:SI 0 "general_operand" "=g,g,g") + [(set (match_operand:SI 0 "nonimmediate_operand" "=g,g,g") (ior:SI (match_operand:SI 1 "general_operand" "0,g,g") (match_operand:SI 2 "general_operand" "g,0,g")))] "" @@ -1077,7 +1433,7 @@ bisl3 %2,%1,%0") (define_insn "iorhi3" - [(set (match_operand:HI 0 "general_operand" "=g,g,g") + [(set (match_operand:HI 0 "nonimmediate_operand" "=g,g,g") (ior:HI (match_operand:HI 1 "general_operand" "0,g,g") (match_operand:HI 2 "general_operand" "g,0,g")))] "" @@ -1087,7 +1443,7 @@ bisw3 %2,%1,%0") (define_insn "iorqi3" - [(set (match_operand:QI 0 "general_operand" "=g,g,g") + [(set (match_operand:QI 0 "nonimmediate_operand" "=g,g,g") (ior:QI (match_operand:QI 1 "general_operand" "0,g,g") (match_operand:QI 2 "general_operand" "g,0,g")))] "" @@ -1099,7 +1455,7 @@ ;;- xor instructions. (define_insn "xorsi3" - [(set (match_operand:SI 0 "general_operand" "=g,g,g") + [(set (match_operand:SI 0 "nonimmediate_operand" "=g,g,g") (xor:SI (match_operand:SI 1 "general_operand" "0,g,g") (match_operand:SI 2 "general_operand" "g,0,g")))] "" @@ -1109,7 +1465,7 @@ xorl3 %2,%1,%0") (define_insn "xorhi3" - [(set (match_operand:HI 0 "general_operand" "=g,g,g") + [(set (match_operand:HI 0 "nonimmediate_operand" "=g,g,g") (xor:HI (match_operand:HI 1 "general_operand" "0,g,g") (match_operand:HI 2 "general_operand" "g,0,g")))] "" @@ -1119,7 +1475,7 @@ xorw3 %2,%1,%0") (define_insn "xorqi3" - [(set (match_operand:QI 0 "general_operand" "=g,g,g") + [(set (match_operand:QI 0 "nonimmediate_operand" "=g,g,g") (xor:QI (match_operand:QI 1 "general_operand" "0,g,g") (match_operand:QI 2 "general_operand" "g,0,g")))] "" @@ -1129,49 +1485,49 @@ xorb3 %2,%1,%0") (define_insn "negdf2" - [(set (match_operand:DF 0 "general_operand" "=g") + [(set (match_operand:DF 0 "nonimmediate_operand" "=g") (neg:DF (match_operand:DF 1 "general_operand" "gF")))] "" "mneg%# %1,%0") (define_insn "negsf2" - [(set (match_operand:SF 0 "general_operand" "=g") + [(set (match_operand:SF 0 "nonimmediate_operand" "=g") (neg:SF (match_operand:SF 1 "general_operand" "gF")))] "" "mnegf %1,%0") (define_insn "negsi2" - [(set (match_operand:SI 0 "general_operand" "=g") + [(set (match_operand:SI 0 "nonimmediate_operand" "=g") (neg:SI (match_operand:SI 1 "general_operand" "g")))] "" "mnegl %1,%0") (define_insn "neghi2" - [(set (match_operand:HI 0 "general_operand" "=g") + [(set (match_operand:HI 0 "nonimmediate_operand" "=g") (neg:HI (match_operand:HI 1 "general_operand" "g")))] "" "mnegw %1,%0") (define_insn "negqi2" - [(set (match_operand:QI 0 "general_operand" "=g") + [(set (match_operand:QI 0 "nonimmediate_operand" "=g") (neg:QI (match_operand:QI 1 "general_operand" "g")))] "" "mnegb %1,%0") (define_insn "one_cmplsi2" - [(set (match_operand:SI 0 "general_operand" "=g") + [(set (match_operand:SI 0 "nonimmediate_operand" "=g") (not:SI (match_operand:SI 1 "general_operand" "g")))] "" "mcoml %1,%0") (define_insn "one_cmplhi2" - [(set (match_operand:HI 0 "general_operand" "=g") + [(set (match_operand:HI 0 "nonimmediate_operand" "=g") (not:HI (match_operand:HI 1 "general_operand" "g")))] "" "mcomw %1,%0") (define_insn "one_cmplqi2" - [(set (match_operand:QI 0 "general_operand" "=g") + [(set (match_operand:QI 0 "nonimmediate_operand" "=g") (not:QI (match_operand:QI 1 "general_operand" "g")))] "" "mcomb %1,%0") @@ -1182,7 +1538,7 @@ ;; prevents converting shifts to ZERO_EXTRACTs with negative positions, ;; which isn't valid. (define_expand "ashrsi3" - [(set (match_operand:SI 0 "general_operand" "=g") + [(set (match_operand:SI 0 "nonimmediate_operand" "=g") (ashiftrt:SI (match_operand:SI 1 "general_operand" "g") (match_operand:QI 2 "general_operand" "g")))] "" @@ -1193,21 +1549,21 @@ }") (define_insn "" - [(set (match_operand:SI 0 "general_operand" "=g") + [(set (match_operand:SI 0 "nonimmediate_operand" "=g") (ashiftrt:SI (match_operand:SI 1 "general_operand" "g") (match_operand:QI 2 "const_int_operand" "n")))] "" "ashl $%n2,%1,%0") (define_insn "" - [(set (match_operand:SI 0 "general_operand" "=g") + [(set (match_operand:SI 0 "nonimmediate_operand" "=g") (ashiftrt:SI (match_operand:SI 1 "general_operand" "g") (neg:QI (match_operand:QI 2 "general_operand" "g"))))] "" "ashl %2,%1,%0") (define_insn "ashlsi3" - [(set (match_operand:SI 0 "general_operand" "=g") + [(set (match_operand:SI 0 "nonimmediate_operand" "=g") (ashift:SI (match_operand:SI 1 "general_operand" "g") (match_operand:QI 2 "general_operand" "g")))] "" @@ -1231,7 +1587,7 @@ ;; Arithmetic right shift on the vax works by negating the shift count. (define_expand "ashrdi3" - [(set (match_operand:DI 0 "general_operand" "=g") + [(set (match_operand:DI 0 "nonimmediate_operand" "=g") (ashiftrt:DI (match_operand:DI 1 "general_operand" "g") (match_operand:QI 2 "general_operand" "g")))] "" @@ -1241,14 +1597,14 @@ }") (define_insn "ashldi3" - [(set (match_operand:DI 0 "general_operand" "=g") + [(set (match_operand:DI 0 "nonimmediate_operand" "=g") (ashift:DI (match_operand:DI 1 "general_operand" "g") (match_operand:QI 2 "general_operand" "g")))] "" "ashq %2,%1,%0") (define_insn "" - [(set (match_operand:DI 0 "general_operand" "=g") + [(set (match_operand:DI 0 "nonimmediate_operand" "=g") (ashiftrt:DI (match_operand:DI 1 "general_operand" "g") (neg:QI (match_operand:QI 2 "general_operand" "g"))))] "" @@ -1263,7 +1619,7 @@ [(set (match_dup 3) (minus:QI (const_int 32) (match_dup 4))) - (set (match_operand:SI 0 "general_operand" "=g") + (set (match_operand:SI 0 "nonimmediate_operand" "=g") (zero_extract:SI (match_operand:SI 1 "register_operand" "r") (match_dup 3) (match_operand:SI 2 "register_operand" "g")))] @@ -1276,7 +1632,7 @@ ;; Rotate right on the vax works by negating the shift count. (define_expand "rotrsi3" - [(set (match_operand:SI 0 "general_operand" "=g") + [(set (match_operand:SI 0 "nonimmediate_operand" "=g") (rotatert:SI (match_operand:SI 1 "general_operand" "g") (match_operand:QI 2 "general_operand" "g")))] "" @@ -1287,21 +1643,21 @@ }") (define_insn "rotlsi3" - [(set (match_operand:SI 0 "general_operand" "=g") + [(set (match_operand:SI 0 "nonimmediate_operand" "=g") (rotate:SI (match_operand:SI 1 "general_operand" "g") (match_operand:QI 2 "general_operand" "g")))] "" "rotl %2,%1,%0") (define_insn "" - [(set (match_operand:SI 0 "general_operand" "=g") + [(set (match_operand:SI 0 "nonimmediate_operand" "=g") (rotatert:SI (match_operand:SI 1 "general_operand" "g") (match_operand:QI 2 "const_int_operand" "n")))] "" "rotl %R2,%1,%0") (define_insn "" - [(set (match_operand:SI 0 "general_operand" "=g") + [(set (match_operand:SI 0 "nonimmediate_operand" "=g") (rotatert:SI (match_operand:SI 1 "general_operand" "g") (neg:QI (match_operand:QI 2 "general_operand" "g"))))] "" @@ -1309,7 +1665,7 @@ ;This insn is probably slower than a multiply and an add. ;(define_insn "" -; [(set (match_operand:SI 0 "general_operand" "=g") +; [(set (match_operand:SI 0 "nonimmediate_operand" "=g") ; (mult:SI (plus:SI (match_operand:SI 1 "general_operand" "g") ; (match_operand:SI 2 "general_operand" "g")) ; (match_operand:SI 3 "general_operand" "g")))] @@ -1348,7 +1704,7 @@ }") (define_insn "" - [(set (match_operand:SI 0 "general_operand" "=&g") + [(set (match_operand:SI 0 "nonimmediate_operand" "=&g") (zero_extract:SI (match_operand:SI 1 "register_operand" "ro") (match_operand:QI 2 "const_int_operand" "n") (match_operand:SI 3 "const_int_operand" "n")))] @@ -1373,7 +1729,7 @@ }") (define_insn "" - [(set (match_operand:SI 0 "general_operand" "=g") + [(set (match_operand:SI 0 "nonimmediate_operand" "=g") (sign_extract:SI (match_operand:SI 1 "register_operand" "ro") (match_operand:QI 2 "const_int_operand" "n") (match_operand:SI 3 "const_int_operand" "n")))] @@ -1425,7 +1781,7 @@ ;; anyway, we can't allow immediate values for the primary source operand. (define_insn "" - [(set (match_operand:SI 0 "general_operand" "=g") + [(set (match_operand:SI 0 "nonimmediate_operand" "=g") (sign_extract:SI (match_operand:SI 1 "register_operand" "ro") (match_operand:QI 2 "general_operand" "g") (match_operand:SI 3 "general_operand" "g")))] @@ -1442,7 +1798,7 @@ }") (define_insn "" - [(set (match_operand:SI 0 "general_operand" "=g") + [(set (match_operand:SI 0 "nonimmediate_operand" "=g") (zero_extract:SI (match_operand:SI 1 "register_operand" "ro") (match_operand:QI 2 "general_operand" "g") (match_operand:SI 3 "general_operand" "g")))] @@ -1488,7 +1844,7 @@ "cmpzv %2,%1,%0,%3") (define_insn "extv" - [(set (match_operand:SI 0 "general_operand" "=g") + [(set (match_operand:SI 0 "nonimmediate_operand" "=g") (sign_extract:SI (match_operand:QI 1 "memory_operand" "m") (match_operand:QI 2 "general_operand" "g") (match_operand:SI 3 "general_operand" "g")))] @@ -1517,7 +1873,7 @@ "") (define_insn "" - [(set (match_operand:SI 0 "general_operand" "=g") + [(set (match_operand:SI 0 "nonimmediate_operand" "=g") (zero_extract:SI (match_operand:QI 1 "memory_operand" "m") (match_operand:QI 2 "general_operand" "g") (match_operand:SI 3 "general_operand" "g")))] @@ -1602,7 +1958,9 @@ (label_ref (match_operand 0 "" "")) (pc)))] "" - "jgtru %l0") + "* + OUTPUT_JUMP(\"jgtru %l0\", 0, \"jneq %l0\"); + ") (define_insn "blt" [(set (pc) @@ -1620,7 +1978,9 @@ (label_ref (match_operand 0 "" "")) (pc)))] "" - "jlssu %l0") + "* + OUTPUT_JUMP(\"jlssu %l0\", 0, 0); + ") (define_insn "bge" [(set (pc) @@ -1638,7 +1998,9 @@ (label_ref (match_operand 0 "" "")) (pc)))] "" - "jgequ %l0") + "* + OUTPUT_JUMP(\"jgequ %l0\", 0, 0); + ") (define_insn "ble" [(set (pc) @@ -1656,10 +2018,12 @@ (label_ref (match_operand 0 "" "")) (pc)))] "" - "jlequ %l0") + "* + OUTPUT_JUMP(\"jlequ %l0\", NULL, \"jeql %l0\"); + ") ;; Recognize reversed jumps. -(define_insn "" +(define_insn "*rbr" [(set (pc) (if_then_else (match_operator 0 "comparison_operator" [(cc0) @@ -1667,7 +2031,19 @@ (pc) (label_ref (match_operand 1 "" ""))))] "" - "j%C0 %l1") ; %C0 negates condition + "* + if ((cc_status.flags & CC_NO_OVERFLOW) != 0) + { + if (GET_CODE (operands[0]) == LTU + || GET_CODE (operands[0]) == GEU) + fatal (\"Cannot reverse branch\"); + if (GET_CODE (operands[0]) == GTU) + return \"jeql %l0\"; + if (GET_CODE (operands[0]) == LEU) + return \"jneq %l0\"; + } + return \"j%C0 %l1\"; /* %C0 negates condition */ + ") ;; Recognize jbs, jlbs, jbc and jlbc instructions. Note that the operand ;; of jlbs and jlbc insns are SImode in the hardware. However, if it is @@ -1739,7 +2115,7 @@ (define_insn "" [(set (pc) (if_then_else - (gt (plus:SI (match_operand:SI 0 "general_operand" "+g") + (gt (plus:SI (match_operand:SI 0 "nonimmediate_operand" "+g") (const_int -1)) (const_int 0)) (label_ref (match_operand 1 "" "")) @@ -1753,7 +2129,7 @@ (define_insn "" [(set (pc) (if_then_else - (ge (plus:SI (match_operand:SI 0 "general_operand" "+g") + (ge (plus:SI (match_operand:SI 0 "nonimmediate_operand" "+g") (const_int -1)) (const_int 0)) (label_ref (match_operand 1 "" "")) @@ -1768,7 +2144,7 @@ (define_insn "" [(set (pc) (if_then_else - (lt (plus:SI (match_operand:SI 0 "general_operand" "+g") + (lt (plus:SI (match_operand:SI 0 "nonimmediate_operand" "+g") (const_int 1)) (match_operand:SI 1 "general_operand" "g")) (label_ref (match_operand 2 "" "")) @@ -1782,7 +2158,7 @@ (define_insn "" [(set (pc) (if_then_else - (lt (match_operand:SI 0 "general_operand" "+g") + (lt (match_operand:SI 0 "nonimmediate_operand" "+g") (match_operand:SI 1 "general_operand" "g")) (label_ref (match_operand 2 "" "")) (pc))) @@ -1795,7 +2171,7 @@ (define_insn "" [(set (pc) (if_then_else - (le (plus:SI (match_operand:SI 0 "general_operand" "+g") + (le (plus:SI (match_operand:SI 0 "nonimmediate_operand" "+g") (const_int 1)) (match_operand:SI 1 "general_operand" "g")) (label_ref (match_operand 2 "" "")) @@ -1809,7 +2185,7 @@ (define_insn "" [(set (pc) (if_then_else - (le (match_operand:SI 0 "general_operand" "+g") + (le (match_operand:SI 0 "nonimmediate_operand" "+g") (match_operand:SI 1 "general_operand" "g")) (label_ref (match_operand 2 "" "")) (pc))) @@ -1825,7 +2201,7 @@ (define_insn "" [(set (pc) (if_then_else - (ne (match_operand:SI 0 "general_operand" "g") + (ne (match_operand:SI 0 "nonimmediate_operand" "g") (const_int 0)) (label_ref (match_operand 1 "" "")) (pc))) @@ -1840,63 +2216,66 @@ ;; 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" +(define_expand "call_pop" + [(parallel [(call (match_operand:QI 0 "memory_operand" "") + (match_operand:SI 1 "const_int_operand" "")) + (set (reg:SI 14) + (plus:SI (reg:SI 14) + (match_operand:SI 3 "immediate_operand" "")))])] + "" + " +{ + if (INTVAL (operands[1]) > 255 * 4) + abort (); + operands[1] = GEN_INT ((INTVAL (operands[1]) + 3)/ 4); +}") + +(define_insn "*call_pop" [(call (match_operand:QI 0 "memory_operand" "m") (match_operand:SI 1 "const_int_operand" "n")) (set (reg:SI 14) (plus:SI (reg:SI 14) - (match_operand:SI 3 "immediate_operand" "i")))] + (match_operand:SI 2 "immediate_operand" "i")))] "" - "* - 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_INT ((INTVAL (operands[1]) + 3)/ 4); - return \"calls %1,%0\"; -") + "calls %1,%0") -(define_insn "call_value_pop" - [(set (match_operand 0 "" "=g") +(define_expand "call_value_pop" + [(parallel [(set (match_operand 0 "" "") + (call (match_operand:QI 1 "memory_operand" "") + (match_operand:SI 2 "const_int_operand" ""))) + (set (reg:SI 14) + (plus:SI (reg:SI 14) + (match_operand:SI 4 "immediate_operand" "")))])] + "" + " +{ + if (INTVAL (operands[2]) > 255 * 4) + abort (); + operands[2] = GEN_INT ((INTVAL (operands[2]) + 3)/ 4); +}") + +(define_insn "*call_value_pop" + [(set (match_operand 0 "" "") (call (match_operand:QI 1 "memory_operand" "m") (match_operand:SI 2 "const_int_operand" "n"))) (set (reg:SI 14) (plus:SI (reg:SI 14) - (match_operand:SI 4 "immediate_operand" "i")))] + (match_operand:SI 3 "immediate_operand" "i")))] "" - "* - 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_INT ((INTVAL (operands[2]) + 3)/ 4); - return \"calls %2,%1\"; -") + "calls %2,%1") -;; Define another set of these for the case of functions with no -;; operands. In that case, combine may simplify the adjustment of sp. -(define_insn "" +;; Define another set of these for the case of functions with no operands. +;; These will allow the optimizers to do a slightly better job. +(define_insn "call" [(call (match_operand:QI 0 "memory_operand" "m") - (match_operand:SI 1 "const_int_operand" "n")) - (set (reg:SI 14) (reg:SI 14))] + (const_int 0))] "" - "* - 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_INT ((INTVAL (operands[1]) + 3)/ 4); - return \"calls %1,%0\"; -") + "calls $0,%0") -(define_insn "" - [(set (match_operand 0 "" "=g") +(define_insn "call_value" + [(set (match_operand 0 "" "") (call (match_operand:QI 1 "memory_operand" "m") - (match_operand:SI 2 "const_int_operand" "n"))) - (set (reg:SI 14) (reg:SI 14))] + (const_int 0)))] "" - "* - 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_INT ((INTVAL (operands[2]) + 3)/ 4); - return \"calls %2,%1\"; -") + "calls $0,%1") ;; Call subroutine returning any type. @@ -2003,7 +2382,7 @@ (mult:SI (minus:SI (match_dup 0) (const_int 0)) (const_int 2))))) - (label_ref:SI (match_operand 3 "" ""))) + (label_ref:SI (match_operand 2 "" ""))) (pc)))] "" "casel %0,$0,%1") @@ -2017,7 +2396,7 @@ ;; because < matches any autodecrement, not just a push. (define_insn "" - [(set (match_operand:SI 0 "general_operand" "=g") + [(set (match_operand:SI 0 "nonimmediate_operand" "=g") (match_operand:QI 1 "address_operand" "p"))] "" "* @@ -2029,7 +2408,7 @@ }") (define_insn "" - [(set (match_operand:SI 0 "general_operand" "=g") + [(set (match_operand:SI 0 "nonimmediate_operand" "=g") (match_operand:HI 1 "address_operand" "p"))] "" "* @@ -2041,7 +2420,7 @@ }") (define_insn "" - [(set (match_operand:SI 0 "general_operand" "=g") + [(set (match_operand:SI 0 "nonimmediate_operand" "=g") (match_operand:SI 1 "address_operand" "p"))] "" "* @@ -2053,7 +2432,7 @@ }") (define_insn "" - [(set (match_operand:SI 0 "general_operand" "=g") + [(set (match_operand:SI 0 "nonimmediate_operand" "=g") (match_operand:DI 1 "address_operand" "p"))] "" "* @@ -2065,7 +2444,7 @@ }") (define_insn "" - [(set (match_operand:SI 0 "general_operand" "=g") + [(set (match_operand:SI 0 "nonimmediate_operand" "=g") (match_operand:SF 1 "address_operand" "p"))] "" "* @@ -2077,7 +2456,7 @@ }") (define_insn "" - [(set (match_operand:SI 0 "general_operand" "=g") + [(set (match_operand:SI 0 "nonimmediate_operand" "=g") (match_operand:DF 1 "address_operand" "p"))] "" "* @@ -2102,7 +2481,7 @@ ;; above sequences to before attempting to recognize the new insn. (define_insn "" - [(set (match_operand:SI 0 "general_operand" "=ro") + [(set (match_operand:SI 0 "nonimmediate_operand" "=ro") (and:SI (ashiftrt:SI (match_operand:SI 1 "general_operand" "g") (match_operand:QI 2 "const_int_operand" "n")) (match_operand:SI 3 "const_int_operand" "n")))] @@ -2124,7 +2503,7 @@ ;; optimized away. (define_insn "" - [(set (match_operand:SI 0 "general_operand" "=ro") + [(set (match_operand:SI 0 "nonimmediate_operand" "=ro") (and:SI (ashift:SI (match_operand:SI 1 "general_operand" "g") (match_operand:QI 2 "const_int_operand" "n")) (match_operand:SI 3 "const_int_operand" "n")))]