diff options
author | Kazu Hirata <kazu@cs.umass.edu> | 2004-02-04 05:13:43 +0000 |
---|---|---|
committer | Kazu Hirata <kazu@gcc.gnu.org> | 2004-02-04 05:13:43 +0000 |
commit | a4a4b1d36476aaa60ebd05db0dfd16145dc72338 (patch) | |
tree | ce646f5c227e247e4200d85892382a8f5bb625d6 /gcc/config/i370 | |
parent | c3bf16ff7dec47581f450b1a486cfdf9d566927e (diff) | |
download | gcc-a4a4b1d36476aaa60ebd05db0dfd16145dc72338.zip gcc-a4a4b1d36476aaa60ebd05db0dfd16145dc72338.tar.gz gcc-a4a4b1d36476aaa60ebd05db0dfd16145dc72338.tar.bz2 |
config.gcc: Remove obsolete ports and configurations.
gcc/
* config.gcc: Remove obsolete ports and configurations.
* config/linux-aout.h, config/netware.h,
config/t-linux-gnulibc1, config/d30v/abi,
config/d30v/d30v-protos.h, config/d30v/d30v.c,
config/d30v/d30v.h, config/d30v/d30v.md,
config/d30v/libgcc1.asm, config/d30v/t-d30v,
config/dsp16xx/dsp16xx-modes.def,
config/dsp16xx/dsp16xx-protos.h, config/dsp16xx/dsp16xx.c,
config/dsp16xx/dsp16xx.h, config/dsp16xx/dsp16xx.md,
config/i370/README, config/i370/i370-c.c,
config/i370/i370-protos.h, config/i370/i370.c,
config/i370/i370.h, config/i370/i370.md, config/i370/linux.h,
config/i370/mvs.h, config/i370/oe.h, config/i370/t-i370,
config/i386/freebsd-aout.h, config/i386/linux-aout.h,
config/i386/moss.h, config/i386/netware.h,
config/i386/svr3.ifile, config/i386/svr3dbx.h,
config/i386/svr3gas.h, config/i386/svr3z.ifile,
config/i386/t-udk, config/i386/udk.h, config/i386/vsta.h,
config/i960/i960-c.c, config/i960/i960-coff.h,
config/i960/i960-modes.def, config/i960/i960-protos.h,
config/i960/i960.c, config/i960/i960.h, config/i960/i960.md,
config/i960/rtems.h, config/i960/t-960bare,
config/m68k/hp310.h, config/m68k/hp320.h,
config/m68k/hp320base.h, config/m68k/m68kv4.h,
config/m68k/netbsd.h, config/m68k/sgs.h, config/m68k/t-hp320:
Remove.
* doc/extend.texi, doc/install.texi, doc/invoke.texi,
doc/md.texi: Remove mentions of obsolete ports.
testsuite/
* gcc.dg/20020312-2.c, gcc.dg/builtin-inf-1.c,
gcc.dg/sibcall-3.c, gcc.dg/sibcall-4.c, gcc.dg/cpp/assert4.c:
Remove mentions of obsolete ports.
From-SVN: r77216
Diffstat (limited to 'gcc/config/i370')
-rw-r--r-- | gcc/config/i370/README | 125 | ||||
-rw-r--r-- | gcc/config/i370/i370-c.c | 64 | ||||
-rw-r--r-- | gcc/config/i370/i370-protos.h | 55 | ||||
-rw-r--r-- | gcc/config/i370/i370.c | 1514 | ||||
-rw-r--r-- | gcc/config/i370/i370.h | 1862 | ||||
-rw-r--r-- | gcc/config/i370/i370.md | 4739 | ||||
-rw-r--r-- | gcc/config/i370/linux.h | 113 | ||||
-rw-r--r-- | gcc/config/i370/mvs.h | 49 | ||||
-rw-r--r-- | gcc/config/i370/oe.h | 53 | ||||
-rw-r--r-- | gcc/config/i370/t-i370 | 3 |
10 files changed, 0 insertions, 8577 deletions
diff --git a/gcc/config/i370/README b/gcc/config/i370/README deleted file mode 100644 index 56c6342..0000000 --- a/gcc/config/i370/README +++ /dev/null @@ -1,125 +0,0 @@ - -This directory contains code for building a compiler for the -32-bit ESA/390 architecture. It supports three different styles -of assembly: - --- MVS for use with the HLASM assembler --- Open Edition (USS Unix System Services) --- ELF/Linux for use with the binutils/gas GNU assembler. - - -Cross-compiling Hints ---------------------- -When building a cross-compiler on AIX, set the environment variable CC -and be sure to set the -ma and -qcpluscmt flags; i.e. - - export CC="cc -ma -qcpluscmt" - -do this *before* running configure, e.g. - - configure --target=i370-ibm-linux --prefix=/where/to/install/usr - -The Objective-C and FORTRAN front ends don't build. To avoid looking at -errors, do only - - make LANGUAGES=c - - -OpenEdition Hints ------------------ -The shell script "install" is handy for users of OpenEdition. - - -The ELF ABI ------------ -This compiler, in conjunction with the gas/binutils assembler, defines -a defacto ELF-based ABI for the ESA/390 architecture. Be warned: this -ABI has several major faults. It should be fixed. As it is fixed, -it is subject to change without warning. You should not commit to major -software systems without further exploring and fixing these problems. -Here are some of the problems: - --- No support for shared libraries or dynamically loadable objects. - This is because the compiler currently places address literals in - the text section. Although the GAS assembler supports a syntax for - USING that will place address literals in the data section, this forces - the use of two base registers, one for branches and one for the literal - pool. Work is needed to redesign the function prologue, epilogue and the - base register reloads to minimize the currently excessive use of reserved - registers. - - I beleive the best solution would be to add a toc or plt, and extending - the meaning of the USING directive to encompass this. This would - allow the continued use of the human-readable and familiar practice - of using =A() and =F'' to denote address literals, as opposed to more - difficult jump-table notation. - --- the stackframe is almost twice as big as it needs to be. - --- currently, r15 is used to return 32-bit values. Because this is the - last register, it prevents 64-bit ints and small structures from being - returned in registers, forcing return in memory. It would be more - efficient to use r14 to return 32-bit values, and r14+r15 to return - 64-bit values. - --- all arguments are currently passed in memory. It would be more efficient - to pass arguments in registers. - - - - -ChangeLog ---------- -Oct98-Dec98 -- add ELF back end; work on getting ABI more or less functional. -98.12.05 -- fix numerous MVC bugs -99.02.06 -- multiply insn sometimes not generated when needed. - -- extendsidi bugs, bad literal values printed - -- remove broken adddi subdi patterns -99.02.15 -- add clrstrsi pattern - -- fix -O2 divide bug -99.03.04 -- base & index reg usage bugs -99.03.15 -- fixes for returning long longs and structs (struct value return) -99.03.29 -- fix handling & alignment of shorts -99.03.31 -- clobbered register 14 is not always clobbered -99.04.02 -- operand constraints for cmphi -99.04.07 -- function pointer fixes for call, call_value patterns, - function pointers derefed once too often. -99.04.14 -- add pattern to print double-wide int - -- check intval<4096 for misc operands - -- add clrstrsi pattern - -- movstrsi fixes -99.04.16 -- use r2 to pass args into r11 in subroutine call. - -- fixes to movsi; some operand combinations impossible; - rework constraints - -- start work on forward jump optimization - -- char alignment bug -99.04.25 -- add untyped_call pattern so that builtin_apply works -99.04.27 -- fixes to compare logical under mask -99.04.28 -- reg 2 is clobbered by calls -99.04.30 -- fix rare mulsi bug -99.04.30 -- add constraints so that all RS, SI, SS forms insns have valid - addressing modes -99.04.30 -- major condition code fixes. The old code was just way off - w.r.t. which insns set condition code, and the codes that - were set. The extent of this damage was unbeleivable. -99.05.01 -- restructuring of operand constraints on many patterns, - many lead to invalid instructions being genned. -99.05.02 -- float pt fixes - -- fix movdi issue bugs -99.05.03 -- fix divide insn; was dividing incorrectly -99.05.05 -- fix sign extension problems on andhi - -- deprecate some constraints -99.05.06 -- add set_attr insn lengths; fix misc litpool sizes - -- add notes about how unsigned jumps work (i.e. - arithmetic vs. logical vs. signed vs unsigned). -99.05.11 -- use insn length to predict forward branch target; - use relative branchining where possible, - remove un-needed base register reload. -99.05.15 -- fix movstrsi, clrstrsi, cmpstrsi patterns as per conversation - w/ Richard Henderson - - - - - - diff --git a/gcc/config/i370/i370-c.c b/gcc/config/i370/i370-c.c deleted file mode 100644 index fe39191..0000000 --- a/gcc/config/i370/i370-c.c +++ /dev/null @@ -1,64 +0,0 @@ -/* Subroutines for the C front end for System/370. - Copyright (C) 1989, 1993, 1995, 1997, 1998, 1999, 2000 - Free Software Foundation, Inc. - Contributed by Jan Stein (jan@cd.chalmers.se). - Modified for OS/390 LanguageEnvironment C by Dave Pitts (dpitts@cozx.com) - Hacked for Linux-ELF/390 by Linas Vepstas (linas@linas.org) - -This file is part of GCC. - -GCC 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. - -GCC 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 GCC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -#include "config.h" -#include "system.h" -#include "coretypes.h" -#include "tm.h" -#include "tree.h" -#include "toplev.h" -#include "cpplib.h" -#include "c-pragma.h" -#include "tm_p.h" - -#ifdef TARGET_HLASM - -/* #pragma map (name, alias) - - In this implementation both name and alias are required to be - identifiers. The older code seemed to be more permissive. Can - anyone clarify? */ - -void -i370_pr_map (pfile) - cpp_reader *pfile ATTRIBUTE_UNUSED; -{ - tree name, alias, x; - - if (c_lex (&x) == CPP_OPEN_PAREN - && c_lex (&name) == CPP_NAME - && c_lex (&x) == CPP_COMMA - && c_lex (&alias) == CPP_NAME - && c_lex (&x) == CPP_CLOSE_PAREN) - { - if (c_lex (&x) != CPP_EOF) - warning ("junk at end of #pragma map"); - - mvs_add_alias (IDENTIFIER_POINTER (name), IDENTIFIER_POINTER (alias), 1); - return; - } - - warning ("malformed #pragma map, ignored"); -} - -#endif diff --git a/gcc/config/i370/i370-protos.h b/gcc/config/i370/i370-protos.h deleted file mode 100644 index 666db0b..0000000 --- a/gcc/config/i370/i370-protos.h +++ /dev/null @@ -1,55 +0,0 @@ -/* Definitions of target machine for GNU compiler. System/370 version. - Copyright (C) 2000 Free Software Foundation, Inc. - Contributed by Jan Stein (jan@cd.chalmers.se). - Modified for OS/390 LanguageEnvironment C by Dave Pitts (dpitts@cozx.com) - Hacked for Linux-ELF/390 by Linas Vepstas (linas@linas.org) - -This file is part of GCC. - -GCC 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. - -GCC 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 GCC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -#ifndef GCC_I370_PROTOS_H -#define GCC_I370_PROTOS_H - -extern void override_options (void); - -#ifdef RTX_CODE -extern int i370_branch_dest (rtx); -extern int i370_branch_length (rtx); -extern int i370_short_branch (rtx); -extern int s_operand (rtx, enum machine_mode); -extern int r_or_s_operand (rtx, enum machine_mode); -extern int unsigned_jump_follows_p (rtx); -#endif /* RTX_CODE */ - -#ifdef TREE_CODE -extern int handle_pragma (int (*)(void), void (*)(int), const char *); -#endif /* TREE_CODE */ - -extern void mvs_add_label (int); -extern int mvs_check_label (int); -extern int mvs_check_page (FILE *, int, int); -extern int mvs_function_check (const char *); -extern void mvs_add_alias (const char *, const char *, int); -extern int mvs_need_alias (const char *); -extern int mvs_get_alias (const char *, char *); -extern int mvs_check_alias (const char *, char *); -extern void check_label_emit (void); -extern void mvs_free_label_list (void); - -extern void i370_pr_map (struct cpp_reader *); - -#endif /* ! GCC_I370_PROTOS_H */ diff --git a/gcc/config/i370/i370.c b/gcc/config/i370/i370.c deleted file mode 100644 index 2cfe4fe..0000000 --- a/gcc/config/i370/i370.c +++ /dev/null @@ -1,1514 +0,0 @@ -/* Subroutines for insn-output.c for System/370. - Copyright (C) 1989, 1993, 1995, 1997, 1998, 1999, 2000, 2002 - Free Software Foundation, Inc. - Contributed by Jan Stein (jan@cd.chalmers.se). - Modified for OS/390 LanguageEnvironment C by Dave Pitts (dpitts@cozx.com) - Hacked for Linux-ELF/390 by Linas Vepstas (linas@linas.org) - -This file is part of GCC. - -GCC 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. - -GCC 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 GCC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -#include "config.h" -#include "system.h" -#include "coretypes.h" -#include "tm.h" -#include "rtl.h" -#include "tree.h" -#include "regs.h" -#include "hard-reg-set.h" -#include "real.h" -#include "insn-config.h" -#include "conditions.h" -#include "output.h" -#include "insn-attr.h" -#include "function.h" -#include "expr.h" -#include "flags.h" -#include "recog.h" -#include "toplev.h" -#include "cpplib.h" -#include "tm_p.h" -#include "target.h" -#include "target-def.h" - -extern FILE *asm_out_file; - -/* Label node. This structure is used to keep track of labels - on the various pages in the current routine. - The label_id is the numeric ID of the label, - The label_page is the page on which it actually appears, - The first_ref_page is the page on which the true first ref appears. - The label_addr is an estimate of its location in the current routine, - The label_first & last_ref are estimates of where the earliest and - latest references to this label occur. */ - -typedef struct label_node - { - struct label_node *label_next; - int label_id; - int label_page; - int first_ref_page; - - int label_addr; - int label_first_ref; - int label_last_ref; - } -label_node_t; - -/* Is 1 when a label has been generated and the base register must be reloaded. */ -int mvs_need_base_reload = 0; - -/* Current function starting base page. */ -int function_base_page; - -/* Length of the current page code. */ -int mvs_page_code; - -/* Length of the current page literals. */ -int mvs_page_lit; - -/* Current function name. */ -char *mvs_function_name = 0; - -/* Current function name length. */ -size_t mvs_function_name_length = 0; - -/* Page number for multi-page functions. */ -int mvs_page_num = 0; - -/* Label node list anchor. */ -static label_node_t *label_anchor = 0; - -/* Label node free list anchor. */ -static label_node_t *free_anchor = 0; - -/* Assembler source file descriptor. */ -static FILE *assembler_source = 0; - -static label_node_t * mvs_get_label (int); -static void i370_label_scan (void); -#ifdef TARGET_HLASM -static bool i370_hlasm_assemble_integer (rtx, unsigned int, int); -static void i370_globalize_label (FILE *, const char *); -#endif -static void i370_output_function_prologue (FILE *, HOST_WIDE_INT); -static void i370_output_function_epilogue (FILE *, HOST_WIDE_INT); -static void i370_file_start (void); -static void i370_file_end (void); - -#ifdef LONGEXTERNAL -static int mvs_hash_alias (const char *); -#endif -static void i370_internal_label (FILE *, const char *, unsigned long); -static bool i370_rtx_costs (rtx, int, int, int *); - -/* ===================================================== */ -/* defines and functions specific to the HLASM assembler */ -#ifdef TARGET_HLASM - -#define MVS_HASH_PRIME 999983 -#if HOST_CHARSET == HOST_CHARSET_EBCDIC -#define MVS_SET_SIZE 256 -#else -#define MVS_SET_SIZE 128 -#endif - -#ifndef MAX_MVS_LABEL_SIZE -#define MAX_MVS_LABEL_SIZE 8 -#endif - -#define MAX_LONG_LABEL_SIZE 255 - -/* Alias node, this structure is used to keep track of aliases to external - variables. The IBM assembler allows an alias to an external name - that is longer that 8 characters; but only once per assembly. - Also, this structure stores the #pragma map info. */ -typedef struct alias_node - { - struct alias_node *alias_next; - int alias_emitted; - char alias_name [MAX_MVS_LABEL_SIZE + 1]; - char real_name [MAX_LONG_LABEL_SIZE + 1]; - } -alias_node_t; - -/* Alias node list anchor. */ -static alias_node_t *alias_anchor = 0; - -/* Define the length of the internal MVS function table. */ -#define MVS_FUNCTION_TABLE_LENGTH 32 - -/* C/370 internal function table. These functions use non-standard linkage - and must handled in a special manner. */ -static const char *const mvs_function_table[MVS_FUNCTION_TABLE_LENGTH] = -{ -#if HOST_CHARSET == HOST_CHARSET_EBCDIC /* Changed for EBCDIC collating sequence */ - "ceil", "edc_acos", "edc_asin", "edc_atan", "edc_ata2", "edc_cos", - "edc_cosh", "edc_erf", "edc_erfc", "edc_exp", "edc_gamm", "edc_lg10", - "edc_log", "edc_sin", "edc_sinh", "edc_sqrt", "edc_tan", "edc_tanh", - "fabs", "floor", "fmod", "frexp", "hypot", "jn", - "j0", "j1", "ldexp", "modf", "pow", "yn", - "y0", "y1" -#else - "ceil", "edc_acos", "edc_asin", "edc_ata2", "edc_atan", "edc_cos", - "edc_cosh", "edc_erf", "edc_erfc", "edc_exp", "edc_gamm", "edc_lg10", - "edc_log", "edc_sin", "edc_sinh", "edc_sqrt", "edc_tan", "edc_tanh", - "fabs", "floor", "fmod", "frexp", "hypot", "j0", - "j1", "jn", "ldexp", "modf", "pow", "y0", - "y1", "yn" -#endif -}; - -#endif /* TARGET_HLASM */ -/* ===================================================== */ - - -/* Initialize the GCC target structure. */ -#ifdef TARGET_HLASM -#undef TARGET_ASM_BYTE_OP -#define TARGET_ASM_BYTE_OP NULL -#undef TARGET_ASM_ALIGNED_HI_OP -#define TARGET_ASM_ALIGNED_HI_OP NULL -#undef TARGET_ASM_ALIGNED_SI_OP -#define TARGET_ASM_ALIGNED_SI_OP NULL -#undef TARGET_ASM_INTEGER -#define TARGET_ASM_INTEGER i370_hlasm_assemble_integer -#undef TARGET_ASM_GLOBALIZE_LABEL -#define TARGET_ASM_GLOBALIZE_LABEL i370_globalize_label -#endif - -#undef TARGET_ASM_FUNCTION_PROLOGUE -#define TARGET_ASM_FUNCTION_PROLOGUE i370_output_function_prologue -#undef TARGET_ASM_FUNCTION_EPILOGUE -#define TARGET_ASM_FUNCTION_EPILOGUE i370_output_function_epilogue -#undef TARGET_ASM_FILE_START -#define TARGET_ASM_FILE_START i370_file_start -#undef TARGET_ASM_FILE_END -#define TARGET_ASM_FILE_END i370_file_end -#undef TARGET_ASM_INTERNAL_LABEL -#define TARGET_ASM_INTERNAL_LABEL i370_internal_label -#undef TARGET_RTX_COSTS -#define TARGET_RTX_COSTS i370_rtx_costs - -struct gcc_target targetm = TARGET_INITIALIZER; - -/* Set global variables as needed for the options enabled. */ - -void -override_options () -{ - /* We're 370 floating point, not IEEE floating point. */ - memset (real_format_for_mode, 0, sizeof real_format_for_mode); - REAL_MODE_FORMAT (SFmode) = &i370_single_format; - REAL_MODE_FORMAT (DFmode) = &i370_double_format; -} - -/* ===================================================== */ -/* The following three routines are used to determine whther - forward branch is on this page, or is a far jump. We use - the "length" attr on an insn [(set_atter "length" "4")] - to store the largest possible code length that insn - could have. This gives us a hint of the address of a - branch destination, and from that, we can work out - the length of the jump, and whether its on page or not. - */ - -/* Return the destination address of a branch. */ - -int -i370_branch_dest (branch) - rtx branch; -{ - rtx dest = SET_SRC (PATTERN (branch)); - int dest_uid; - int dest_addr; - - /* first, compute the estimated address of the branch target */ - if (GET_CODE (dest) == IF_THEN_ELSE) - dest = XEXP (dest, 1); - dest = XEXP (dest, 0); - dest_uid = INSN_UID (dest); - dest_addr = INSN_ADDRESSES (dest_uid); - - /* next, record the address of this insn as the true addr of first ref */ - { - label_node_t *lp; - rtx label = JUMP_LABEL (branch); - int labelno = CODE_LABEL_NUMBER (label); - - if (!label || CODE_LABEL != GET_CODE (label)) abort (); - - lp = mvs_get_label (labelno); - if (-1 == lp -> first_ref_page) lp->first_ref_page = mvs_page_num; - } - return dest_addr; -} - -int -i370_branch_length (insn) - rtx insn; -{ - int here, there; - here = INSN_ADDRESSES (INSN_UID (insn)); - there = i370_branch_dest (insn); - return (there - here); -} - - -int -i370_short_branch (insn) - rtx insn; -{ - int base_offset; - - base_offset = i370_branch_length(insn); - if (0 > base_offset) - { - base_offset += mvs_page_code; - } - else - { - /* avoid bumping into lit pool; use 2x to estimate max possible lits */ - base_offset *= 2; - base_offset += mvs_page_code + mvs_page_lit; - } - - /* make a conservative estimate of room left on page */ - if ((4060 >base_offset) && ( 0 < base_offset)) return 1; - return 0; -} - -/* The i370_label_scan() routine is supposed to loop over - all labels and label references in a compilation unit, - and determine whether all label refs appear on the same - code page as the label. If they do, then we can avoid - a reload of the base register for that label. - - Note that the instruction addresses used here are only - approximate, and make the sizes of the jumps appear - farther apart then they will actually be. This makes - this code far more conservative than it needs to be. - */ - -#define I370_RECORD_LABEL_REF(label,addr) { \ - label_node_t *lp; \ - int labelno = CODE_LABEL_NUMBER (label); \ - lp = mvs_get_label (labelno); \ - if (addr < lp -> label_first_ref) lp->label_first_ref = addr; \ - if (addr > lp -> label_last_ref) lp->label_last_ref = addr; \ -} - -static void -i370_label_scan () -{ - rtx insn; - label_node_t *lp; - int tablejump_offset = 0; - - for (insn = get_insns(); insn; insn = NEXT_INSN(insn)) - { - int here = INSN_ADDRESSES (INSN_UID (insn)); - enum rtx_code code = GET_CODE(insn); - - /* ??? adjust for tables embedded in the .text section that - * the compiler didn't take into account */ - here += tablejump_offset; - INSN_ADDRESSES (INSN_UID (insn)) = here; - - /* check to see if this insn is a label ... */ - if (CODE_LABEL == code) - { - int labelno = CODE_LABEL_NUMBER (insn); - - lp = mvs_get_label (labelno); - lp -> label_addr = here; -#if 0 - /* Supposedly, labels are supposed to have circular - lists of label-refs that reference them, - setup in flow.c, but this does not appear to be the case. */ - rtx labelref = LABEL_REFS (insn); - rtx ref = labelref; - do - { - rtx linsn = CONTAINING_INSN(ref); - ref = LABEL_NEXTREF(ref); - } while (ref && (ref != labelref)); -#endif - } - else - if (JUMP_INSN == code) - { - rtx label = JUMP_LABEL (insn); - - /* If there is no label for this jump, then this - had better be a ADDR_VEC or an ADDR_DIFF_VEC - and there had better be a vector of labels. */ - if (!label) - { - int j; - rtx body = PATTERN (insn); - if (ADDR_VEC == GET_CODE(body)) - { - for (j=0; j < XVECLEN (body, 0); j++) - { - rtx lref = XVECEXP (body, 0, j); - if (LABEL_REF != GET_CODE (lref)) abort (); - label = XEXP (lref,0); - if (CODE_LABEL != GET_CODE (label)) abort (); - tablejump_offset += 4; - here += 4; - I370_RECORD_LABEL_REF(label,here); - } - /* finished with the vector go do next insn */ - continue; - } - else - if (ADDR_DIFF_VEC == GET_CODE(body)) - { -/* XXX hack alert. - Right now, we leave this as a no-op, but strictly speaking, - this is incorrect. It is possible that a table-jump - driven off of a relative address could take us off-page, - to a place where we need to reload the base reg. So really, - we need to examing both labels, and compare thier values - to the current basereg value. - - More generally, this brings up a troubling issue overall: - what happens if a tablejump is split across two pages? I do - not beleive that this case is handled correctly at all, and - can only lead to horrible results if this were to occur. - - However, the current situation is not any worse than it was - last week, and so we punt for now. */ - - debug_rtx (insn); - for (j=0; j < XVECLEN (body, 0); j++) - { - } - /* finished with the vector go do next insn */ - continue; - } - else - { -/* XXX hack alert. - Compiling the exception handling (L_eh) in libgcc2.a will trip - up right here, with something that looks like - (set (pc) (mem:SI (plus:SI (reg/v:SI 1 r1) (const_int 4)))) - {indirect_jump} - I'm not sure of what leads up to this, but it looks like - the makings of a long jump which will surely get us into trouble - because the base & page registers don't get reloaded. For now - I'm not sure of what to do ... again we punt ... we are not worse - off than yesterday. */ - - /* print_rtl_single (stdout, insn); */ - debug_rtx (insn); - /* abort(); */ - continue; - } - } - else - { - /* At this point, this jump_insn had better be a plain-old - ordinary one, grap the label id and go */ - if (CODE_LABEL != GET_CODE (label)) abort (); - I370_RECORD_LABEL_REF(label,here); - } - } - - /* Sometimes, we take addresses of labels and use them - as instruction operands ... these show up as REG_NOTES */ - else - if (INSN == code) - { - if ('i' == GET_RTX_CLASS (code)) - { - rtx note; - for (note = REG_NOTES (insn); note; note = XEXP(note,1)) - { - if (REG_LABEL == REG_NOTE_KIND(note)) - { - rtx label = XEXP (note,0); - if (!label || CODE_LABEL != GET_CODE (label)) abort (); - - I370_RECORD_LABEL_REF(label,here); - } - } - } - } - } -} - -/* ===================================================== */ - -/* Emit reload of base register if indicated. This is to eliminate multiple - reloads when several labels are generated pointing to the same place - in the code. - - The page table is written at the end of the function. - The entries in the page table look like - .LPGT0: // PGT0 EQU * - .long .LPG0 // DC A(PG0) - .long .LPG1 // DC A(PG1) - while the prologue generates - L r4,=A(.LPGT0) - - Note that this paging scheme breaks down if a single subroutine - has more than about 10MB of code in it ... as long as humans write - code, this shouldn't be a problem ... - */ - -void -check_label_emit () -{ - if (mvs_need_base_reload) - { - mvs_need_base_reload = 0; - - mvs_page_code += 4; - fprintf (assembler_source, "\tL\t%d,%d(,%d)\n", - BASE_REGISTER, (mvs_page_num - function_base_page) * 4, - PAGE_REGISTER); - } -} - -/* Add the label to the current page label list. If a free element is available - it will be used for the new label. Otherwise, a label element will be - allocated from memory. - ID is the label number of the label being added to the list. */ - -static label_node_t * -mvs_get_label (id) - int id; -{ - label_node_t *lp; - - /* first, lets see if we already go one, if so, use that. */ - for (lp = label_anchor; lp; lp = lp->label_next) - { - if (lp->label_id == id) return lp; - } - - /* not found, get a new one */ - if (free_anchor) - { - lp = free_anchor; - free_anchor = lp->label_next; - } - else - { - lp = (label_node_t *) xmalloc (sizeof (label_node_t)); - } - - /* initialize for new label */ - lp->label_id = id; - lp->label_page = -1; - lp->label_next = label_anchor; - lp->label_first_ref = 2000123123; - lp->label_last_ref = -1; - lp->label_addr = -1; - lp->first_ref_page = -1; - label_anchor = lp; - - return lp; -} - -void -mvs_add_label (id) - int id; -{ - label_node_t *lp; - int fwd_distance; - - lp = mvs_get_label (id); - lp->label_page = mvs_page_num; - - /* OK, we just saw the label. Determine if this label - * needs a reload of the base register */ - if ((-1 != lp->first_ref_page) && - (lp->first_ref_page != mvs_page_num)) - { - /* Yep; the first label_ref was on a different page. */ - mvs_need_base_reload ++; - return; - } - - /* Hmm. Try to see if the estimated address of the last - label_ref is on the current page. If it is, then we - don't need a base reg reload. Note that this estimate - is very conservatively handled; we'll tend to have - a good bit more reloads than actually needed. Someday, - we should tighten the estimates (which are driven by - the (set_att "length") insn attibute. - - Currently, we estimate that number of page literals - same as number of insns, which is a vast overestimate, - esp that the estimate of each insn size is its max size. */ - - /* if latest ref comes before label, we are clear */ - if (lp->label_last_ref < lp->label_addr) return; - - fwd_distance = lp->label_last_ref - lp->label_addr; - - if (mvs_page_code + 2 * fwd_distance + mvs_page_lit < 4060) return; - - mvs_need_base_reload ++; -} - -/* Check to see if the label is in the list and in the current - page. If not found, we have to make worst case assumption - that label will be on a different page, and thus will have to - generate a load and branch on register. This is rather - ugly for forward-jumps, but what can we do? For backward - jumps on the same page we can branch directly to address. - ID is the label number of the label being checked. */ - -int -mvs_check_label (id) - int id; -{ - label_node_t *lp; - - for (lp = label_anchor; lp; lp = lp->label_next) - { - if (lp->label_id == id) - { - if (lp->label_page == mvs_page_num) - { - return 1; - } - else - { - return 0; - } - } - } - return 0; -} - -/* Get the page on which the label sits. This will be used to - determine is a register reload is really needed. */ - -#if 0 -int -mvs_get_label_page(int id) -{ - label_node_t *lp; - - for (lp = label_anchor; lp; lp = lp->label_next) - { - if (lp->label_id == id) - return lp->label_page; - } - return -1; -} -#endif - -/* The label list for the current page freed by linking the list onto the free - label element chain. */ - -void -mvs_free_label_list () -{ - - if (label_anchor) - { - label_node_t *last_lp = label_anchor; - while (last_lp->label_next) last_lp = last_lp->label_next; - last_lp->label_next = free_anchor; - free_anchor = label_anchor; - } - label_anchor = 0; -} - -/* ====================================================================== */ -/* If the page size limit is reached a new code page is started, and the base - register is set to it. This page break point is counted conservatively, - most literals that have the same value are collapsed by the assembler. - True is returned when a new page is started. - FILE is the assembler output file descriptor. - CODE is the length, in bytes, of the instruction to be emitted. - LIT is the length of the literal to be emitted. */ - -#ifdef TARGET_HLASM -int -mvs_check_page (file, code, lit) - FILE *file; - int code, lit; -{ - if (file) - assembler_source = file; - - if (mvs_page_code + code + mvs_page_lit + lit > MAX_MVS_PAGE_LENGTH) - { - fprintf (assembler_source, "\tB\tPGE%d\n", mvs_page_num); - fprintf (assembler_source, "\tDS\t0F\n"); - fprintf (assembler_source, "\tLTORG\n"); - fprintf (assembler_source, "\tDS\t0F\n"); - fprintf (assembler_source, "PGE%d\tEQU\t*\n", mvs_page_num); - fprintf (assembler_source, "\tDROP\t%d\n", BASE_REGISTER); - mvs_page_num++; - /* Safe to use BASR not BALR, since we are - * not switching addressing mode here ... */ - fprintf (assembler_source, "\tBASR\t%d,0\n", BASE_REGISTER); - fprintf (assembler_source, "PG%d\tEQU\t*\n", mvs_page_num); - fprintf (assembler_source, "\tUSING\t*,%d\n", BASE_REGISTER); - mvs_page_code = code; - mvs_page_lit = lit; - return 1; - } - mvs_page_code += code; - mvs_page_lit += lit; - return 0; -} -#endif /* TARGET_HLASM */ - - -#ifdef TARGET_ELF_ABI -int -mvs_check_page (file, code, lit) - FILE *file; - int code, lit; -{ - if (file) - assembler_source = file; - - if (mvs_page_code + code + mvs_page_lit + lit > MAX_MVS_PAGE_LENGTH) - { - /* hop past the literal pool */ - fprintf (assembler_source, "\tB\t.LPGE%d\n", mvs_page_num); - - /* dump the literal pool. The .baligns are optional, since - * ltorg will align to the size of the largest literal - * (which is possibly 8 bytes) */ - fprintf (assembler_source, "\t.balign\t4\n"); - fprintf (assembler_source, "\t.LTORG\n"); - fprintf (assembler_source, "\t.balign\t4\n"); - - /* we continue execution here ... */ - fprintf (assembler_source, ".LPGE%d:\n", mvs_page_num); - fprintf (assembler_source, "\t.DROP\t%d\n", BASE_REGISTER); - mvs_page_num++; - - /* BASR puts the contents of the PSW into r3 - * that is, r3 will be loaded with the address of "." */ - fprintf (assembler_source, "\tBASR\tr%d,0\n", BASE_REGISTER); - fprintf (assembler_source, ".LPG%d:\n", mvs_page_num); - fprintf (assembler_source, "\t.USING\t.,r%d\n", BASE_REGISTER); - mvs_page_code = code; - mvs_page_lit = lit; - return 1; - } - mvs_page_code += code; - mvs_page_lit += lit; - return 0; -} -#endif /* TARGET_ELF_ABI */ - -/* ===================================================== */ -/* defines and functions specific to the HLASM assembler */ -#ifdef TARGET_HLASM - -/* Check for C/370 runtime function, they don't use standard calling - conventions. True is returned if the function is in the table. - NAME is the name of the current function. */ - -int -mvs_function_check (name) - const char *name; -{ - int lower, middle, upper; - int i; - - lower = 0; - upper = MVS_FUNCTION_TABLE_LENGTH - 1; - while (lower <= upper) - { - middle = (lower + upper) / 2; - i = strcmp (name, mvs_function_table[middle]); - if (i == 0) - return 1; - if (i < 0) - upper = middle - 1; - else - lower = middle + 1; - } - return 0; -} - -/* Generate a hash for a given key. */ - -#ifdef LONGEXTERNAL -static int -mvs_hash_alias (key) - const char *key; -{ - int h; - int i; - int l = strlen (key); - - h = key[0]; - for (i = 1; i < l; i++) - h = ((h * MVS_SET_SIZE) + key[i]) % MVS_HASH_PRIME; - return (h); -} -#endif - -/* Add the alias to the current alias list. */ - -void -mvs_add_alias (realname, aliasname, emitted) - const char *realname; - const char *aliasname; - int emitted; -{ - alias_node_t *ap; - - ap = (alias_node_t *) xmalloc (sizeof (alias_node_t)); - if (strlen (realname) > MAX_LONG_LABEL_SIZE) - { - warning ("real name is too long - alias ignored"); - return; - } - if (strlen (aliasname) > MAX_MVS_LABEL_SIZE) - { - warning ("alias name is too long - alias ignored"); - return; - } - - strcpy (ap->real_name, realname); - strcpy (ap->alias_name, aliasname); - ap->alias_emitted = emitted; - ap->alias_next = alias_anchor; - alias_anchor = ap; -} - -/* Check to see if the name needs aliasing. ie. the name is either: - 1. Longer than 8 characters - 2. Contains an underscore - 3. Is mixed case */ - -int -mvs_need_alias (realname) - const char *realname; -{ - int i, j = strlen (realname); - - if (mvs_function_check (realname)) - return 0; -#if 0 - if (!strcmp (realname, "gccmain")) - return 0; - if (!strcmp (realname, "main")) - return 0; -#endif - if (j > MAX_MVS_LABEL_SIZE) - return 1; - if (strchr (realname, '_') != 0) - return 1; - if (ISUPPER (realname[0])) - { - for (i = 1; i < j; i++) - { - if (ISLOWER (realname[i])) - return 1; - } - } - else - { - for (i = 1; i < j; i++) - { - if (ISUPPER (realname[i])) - return 1; - } - } - - return 0; -} - -/* Get the alias from the list. - If 1 is returned then it's in the alias list, 0 if it was not */ - -int -mvs_get_alias (realname, aliasname) - const char *realname; - char *aliasname; -{ -#ifdef LONGEXTERNAL - alias_node_t *ap; - - for (ap = alias_anchor; ap; ap = ap->alias_next) - { - if (!strcmp (ap->real_name, realname)) - { - strcpy (aliasname, ap->alias_name); - return 1; - } - } - if (mvs_need_alias (realname)) - { - char c1, c2; - - c1 = realname[0]; - c2 = realname[1]; - if (ISLOWER (c1)) c1 = TOUPPER (c1); - else if (c1 == '_') c1 = 'A'; - if (ISLOWER (c2)) c2 = TOUPPER (c2); - else if (c2 == '_' || c2 == '\0') c2 = '#'; - - sprintf (aliasname, "%c%c%06d", c1, c2, mvs_hash_alias (realname)); - mvs_add_alias (realname, aliasname, 0); - return 1; - } -#else - if (strlen (realname) > MAX_MVS_LABEL_SIZE) - { - strncpy (aliasname, realname, MAX_MVS_LABEL_SIZE); - aliasname[MAX_MVS_LABEL_SIZE] = '\0'; - return 1; - } -#endif - return 0; -} - -/* Check to see if the alias is in the list. - If 1 is returned then it's in the alias list, 2 it was emitted */ - -int -mvs_check_alias (realname, aliasname) - const char *realname; - char *aliasname; -{ -#ifdef LONGEXTERNAL - alias_node_t *ap; - - for (ap = alias_anchor; ap; ap = ap->alias_next) - { - if (!strcmp (ap->real_name, realname)) - { - int rc = (ap->alias_emitted == 1) ? 1 : 2; - strcpy (aliasname, ap->alias_name); - ap->alias_emitted = 1; - return rc; - } - } - if (mvs_need_alias (realname)) - { - char c1, c2; - - c1 = realname[0]; - c2 = realname[1]; - if (ISLOWER (c1)) c1 = TOUPPER (c1); - else if (c1 == '_') c1 = 'A'; - if (ISLOWER (c2)) c2 = TOUPPER (c2); - else if (c2 == '_' || c2 == '\0') c2 = '#'; - - sprintf (aliasname, "%c%c%06d", c1, c2, mvs_hash_alias (realname)); - mvs_add_alias (realname, aliasname, 0); - alias_anchor->alias_emitted = 1; - return 2; - } -#else - if (strlen (realname) > MAX_MVS_LABEL_SIZE) - { - strncpy (aliasname, realname, MAX_MVS_LABEL_SIZE); - aliasname[MAX_MVS_LABEL_SIZE] = '\0'; - return 1; - } -#endif - return 0; -} - -/* defines and functions specific to the HLASM assembler */ -#endif /* TARGET_HLASM */ -/* ===================================================== */ -/* ===================================================== */ -/* defines and functions specific to the gas assembler */ -#ifdef TARGET_ELF_ABI - -/* Check for C/370 runtime function, they don't use standard calling - conventions. True is returned if the function is in the table. - NAME is the name of the current function. */ -/* no special calling conventions (yet ??) */ - -int -mvs_function_check (name) - const char *name ATTRIBUTE_UNUSED; -{ - return 0; -} - -#endif /* TARGET_ELF_ABI */ -/* ===================================================== */ - - -/* Return 1 if OP is a valid S operand for an RS, SI or SS type instruction. - OP is the current operation. - MODE is the current operation mode. */ - -int -s_operand (op, mode) - register rtx op; - enum machine_mode mode; -{ - extern int volatile_ok; - register enum rtx_code code = GET_CODE (op); - - if (CONSTANT_ADDRESS_P (op)) - return 1; - if (mode == VOIDmode || GET_MODE (op) != mode) - return 0; - if (code == MEM) - { - register rtx x = XEXP (op, 0); - - if (!volatile_ok && op->volatil) - return 0; - if (REG_P (x) && REG_OK_FOR_BASE_P (x)) - return 1; - if (GET_CODE (x) == PLUS - && REG_P (XEXP (x, 0)) && REG_OK_FOR_BASE_P (XEXP (x, 0)) - && GET_CODE (XEXP (x, 1)) == CONST_INT - && (unsigned) INTVAL (XEXP (x, 1)) < 4096) - return 1; - } - return 0; -} - - -/* Return 1 if OP is a valid R or S operand for an RS, SI or SS type - instruction. - OP is the current operation. - MODE is the current operation mode. */ - -int -r_or_s_operand (op, mode) - register rtx op; - enum machine_mode mode; -{ - extern int volatile_ok; - register enum rtx_code code = GET_CODE (op); - - if (CONSTANT_ADDRESS_P (op)) - return 1; - if (mode == VOIDmode || GET_MODE (op) != mode) - return 0; - if (code == REG) - return 1; - else if (code == MEM) - { - register rtx x = XEXP (op, 0); - - if (!volatile_ok && op->volatil) - return 0; - if (REG_P (x) && REG_OK_FOR_BASE_P (x)) - return 1; - if (GET_CODE (x) == PLUS - && REG_P (XEXP (x, 0)) && REG_OK_FOR_BASE_P (XEXP (x, 0)) - && GET_CODE (XEXP (x, 1)) == CONST_INT - && (unsigned) INTVAL (XEXP (x, 1)) < 4096) - return 1; - } - return 0; -} - - -/* Some remarks about unsigned_jump_follows_p(): - gcc is built around the assumption that branches are signed - or unsigned, whereas the 370 doesn't care; its the compares that - are signed or unsigned. Thus, we need to somehow know if we - need to do a signed or an unsigned compare, and we do this by - looking ahead in the instruction sequence until we find a jump. - We then note whether this jump is signed or unsigned, and do the - compare appropriately. Note that we have to scan ahead indefinitley, - as the gcc optimizer may insert any number of instructions between - the compare and the jump. - - Note that using conditional branch expanders seems to be be a more - elegant/correct way of doing this. See, for instance, the Alpha - cmpdi and bgt patterns. Note also that for the i370, various - arithmetic insn's set the condition code as well. - - The unsigned_jump_follows_p() routine returns a 1 if the next jump - is unsigned. INSN is the current instruction. */ - -int -unsigned_jump_follows_p (insn) - register rtx insn; -{ - rtx orig_insn = insn; - while (1) - { - register rtx tmp_insn; - enum rtx_code coda; - - insn = NEXT_INSN (insn); - if (!insn) fatal_insn ("internal error--no jump follows compare:", orig_insn); - - if (GET_CODE (insn) != JUMP_INSN) continue; - - tmp_insn = XEXP (insn, 3); - if (GET_CODE (tmp_insn) != SET) continue; - - if (GET_CODE (XEXP (tmp_insn, 0)) != PC) continue; - - tmp_insn = XEXP (tmp_insn, 1); - if (GET_CODE (tmp_insn) != IF_THEN_ELSE) continue; - - /* if we got to here, this instruction is a jump. Is it signed? */ - tmp_insn = XEXP (tmp_insn, 0); - coda = GET_CODE (tmp_insn); - - return coda != GE && coda != GT && coda != LE && coda != LT; - } -} - -#ifdef TARGET_HLASM - -/* Target hook for assembling integer objects. This version handles all - objects when TARGET_HLASM is defined. */ - -static bool -i370_hlasm_assemble_integer (x, size, aligned_p) - rtx x; - unsigned int size; - int aligned_p; -{ - const char *int_format = NULL; - - if (aligned_p) - switch (size) - { - case 1: - int_format = "\tDC\tX'%02X'\n"; - break; - - case 2: - int_format = "\tDC\tX'%04X'\n"; - break; - - case 4: - if (GET_CODE (x) == CONST_INT) - { - fputs ("\tDC\tF'", asm_out_file); - output_addr_const (asm_out_file, x); - fputs ("'\n", asm_out_file); - } - else - { - fputs ("\tDC\tA(", asm_out_file); - output_addr_const (asm_out_file, x); - fputs (")\n", asm_out_file); - } - return true; - } - - if (int_format && GET_CODE (x) == CONST_INT) - { - fprintf (asm_out_file, int_format, INTVAL (x)); - return true; - } - return default_assemble_integer (x, size, aligned_p); -} - -/* Generate the assembly code for function entry. FILE is a stdio - stream to output the code to. SIZE is an int: how many units of - temporary storage to allocate. - - Refer to the array `regs_ever_live' to determine which registers to - save; `regs_ever_live[I]' is nonzero if register number I is ever - used in the function. This function is responsible for knowing - which registers should not be saved even if used. */ - -static void -i370_output_function_prologue (f, l) - FILE *f; - HOST_WIDE_INT l; -{ -#if MACROPROLOGUE == 1 - fprintf (f, "* Function %s prologue\n", mvs_function_name); - fprintf (f, "\tEDCPRLG USRDSAL=%d,BASEREG=%d\n", - STACK_POINTER_OFFSET + l - 120 + - current_function_outgoing_args_size, BASE_REGISTER); -#else /* MACROPROLOGUE != 1 */ - static int function_label_index = 1; - static int function_first = 0; - static int function_year, function_month, function_day; - static int function_hour, function_minute, function_second; -#if defined(LE370) - if (!function_first) - { - struct tm *function_time; - time_t lcltime; - time (&lcltime); - function_time = localtime (&lcltime); - function_year = function_time->tm_year + 1900; - function_month = function_time->tm_mon + 1; - function_day = function_time->tm_mday; - function_hour = function_time->tm_hour; - function_minute = function_time->tm_min; - function_second = function_time->tm_sec; - } - fprintf (f, "* Function %s prologue\n", mvs_function_name); - fprintf (f, "FDSE%03d\tDSECT\n", function_label_index); - fprintf (f, "\tDS\tD\n"); - fprintf (f, "\tDS\tCL(" HOST_WIDE_INT_PRINT_DEC ")\n", - STACK_POINTER_OFFSET + l - + current_function_outgoing_args_size); - fprintf (f, "\tORG\tFDSE%03d\n", function_label_index); - fprintf (f, "\tDS\tCL(120+8)\n"); - fprintf (f, "\tORG\n"); - fprintf (f, "\tDS\t0D\n"); - fprintf (f, "FDSL%03d\tEQU\t*-FDSE%03d-8\n", function_label_index, - function_label_index); - fprintf (f, "\tDS\t0H\n"); - assemble_name (f, mvs_function_name); - fprintf (f, "\tCSECT\n"); - fprintf (f, "\tUSING\t*,15\n"); - fprintf (f, "\tB\tFENT%03d\n", function_label_index); - fprintf (f, "\tDC\tAL1(FNAM%03d+4-*)\n", function_label_index); - fprintf (f, "\tDC\tX'CE',X'A0',AL1(16)\n"); - fprintf (f, "\tDC\tAL4(FPPA%03d)\n", function_label_index); - fprintf (f, "\tDC\tAL4(0)\n"); - fprintf (f, "\tDC\tAL4(FDSL%03d)\n", function_label_index); - fprintf (f, "FNAM%03d\tEQU\t*\n", function_label_index); - fprintf (f, "\tDC\tAL2(%d),C'%s'\n", strlen (mvs_function_name), - mvs_function_name); - fprintf (f, "FPPA%03d\tDS\t0F\n", function_label_index); - fprintf (f, "\tDC\tX'03',X'00',X'33',X'00'\n"); - fprintf (f, "\tDC\tV(CEESTART)\n"); - fprintf (f, "\tDC\tAL4(0)\n"); - fprintf (f, "\tDC\tAL4(FTIM%03d)\n", function_label_index); - fprintf (f, "FTIM%03d\tDS\t0F\n", function_label_index); - fprintf (f, "\tDC\tCL4'%d',CL4'%02d%02d',CL6'%02d%02d00'\n", - function_year, function_month, function_day, - function_hour, function_minute); - fprintf (f, "\tDC\tCL2'01',CL4'0100'\n"); - fprintf (f, "FENT%03d\tDS\t0H\n", function_label_index); - fprintf (f, "\tSTM\t14,12,12(13)\n"); - fprintf (f, "\tL\t2,76(,13)\n"); - fprintf (f, "\tL\t0,16(,15)\n"); - fprintf (f, "\tALR\t0,2\n"); - fprintf (f, "\tCL\t0,12(,12)\n"); - fprintf (f, "\tBNH\t*+10\n"); - fprintf (f, "\tL\t15,116(,12)\n"); - fprintf (f, "\tBALR\t14,15\n"); - fprintf (f, "\tL\t15,72(,13)\n"); - fprintf (f, "\tSTM\t15,0,72(2)\n"); - fprintf (f, "\tMVI\t0(2),X'10'\n"); - fprintf (f, "\tST\t2,8(,13)\n "); - fprintf (f, "\tST\t13,4(,2)\n "); - fprintf (f, "\tLR\t13,2\n"); - fprintf (f, "\tDROP\t15\n"); - fprintf (f, "\tBALR\t%d,0\n", BASE_REGISTER); - fprintf (f, "\tUSING\t*,%d\n", BASE_REGISTER); - function_first = 1; - function_label_index ++; -#else /* !LE370 */ - if (!function_first) - { - struct tm *function_time; - time_t lcltime; - time (&lcltime); - function_time = localtime (&lcltime); - function_year = function_time->tm_year + 1900; - function_month = function_time->tm_mon + 1; - function_day = function_time->tm_mday; - function_hour = function_time->tm_hour; - function_minute = function_time->tm_min; - function_second = function_time->tm_sec; - fprintf (f, "PPA2\tDS\t0F\n"); - fprintf (f, "\tDC\tX'03',X'00',X'33',X'00'\n"); - fprintf (f, "\tDC\tV(CEESTART),A(0)\n"); - fprintf (f, "\tDC\tA(CEETIMES)\n"); - fprintf (f, "CEETIMES\tDS\t0F\n"); - fprintf (f, "\tDC\tCL4'%d',CL4'%02d%02d',CL6'%02d%02d00'\n", - function_year, function_month, function_day, - function_hour, function_minute, function_second); - fprintf (f, "\tDC\tCL2'01',CL4'0100'\n"); - } - fprintf (f, "* Function %s prologue\n", mvs_function_name); - fprintf (f, "FDSD%03d\tDSECT\n", function_label_index); - fprintf (f, "\tDS\tD\n"); - fprintf (f, "\tDS\tCL(%d)\n", STACK_POINTER_OFFSET + l - + current_function_outgoing_args_size); - fprintf (f, "\tORG\tFDSD%03d\n", function_label_index); - fprintf (f, "\tDS\tCL(120+8)\n"); - fprintf (f, "\tORG\n"); - fprintf (f, "\tDS\t0D\n"); - fprintf (f, "FDSL%03d\tEQU\t*-FDSD%03d-8\n", function_label_index, - function_label_index); - fprintf (f, "\tDS\t0H\n"); - assemble_name (f, mvs_function_name); - fprintf (f, "\tCSECT\n"); - fprintf (f, "\tUSING\t*,15\n"); - fprintf (f, "\tB\tFPL%03d\n", function_label_index); - fprintf (f, "\tDC\tAL1(FPL%03d+4-*)\n", function_label_index + 1); - fprintf (f, "\tDC\tX'CE',X'A0',AL1(16)\n"); - fprintf (f, "\tDC\tAL4(PPA2)\n"); - fprintf (f, "\tDC\tAL4(0)\n"); - fprintf (f, "\tDC\tAL4(FDSL%03d)\n", function_label_index); - fprintf (f, "FPL%03d\tEQU\t*\n", function_label_index + 1); - fprintf (f, "\tDC\tAL2(%d),C'%s'\n", strlen (mvs_function_name), - mvs_function_name); - fprintf (f, "FPL%03d\tDS\t0H\n", function_label_index); - fprintf (f, "\tSTM\t14,12,12(13)\n"); - fprintf (f, "\tL\t2,76(,13)\n"); - fprintf (f, "\tL\t0,16(,15)\n"); - fprintf (f, "\tALR\t0,2\n"); - fprintf (f, "\tCL\t0,12(,12)\n"); - fprintf (f, "\tBNH\t*+10\n"); - fprintf (f, "\tL\t15,116(,12)\n"); - fprintf (f, "\tBALR\t14,15\n"); - fprintf (f, "\tL\t15,72(,13)\n"); - fprintf (f, "\tSTM\t15,0,72(2)\n"); - fprintf (f, "\tMVI\t0(2),X'10'\n"); - fprintf (f, "\tST\t2,8(,13)\n "); - fprintf (f, "\tST\t13,4(,2)\n "); - fprintf (f, "\tLR\t13,2\n"); - fprintf (f, "\tDROP\t15\n"); - fprintf (f, "\tBALR\t%d,0\n", BASE_REGISTER); - fprintf (f, "\tUSING\t*,%d\n", BASE_REGISTER); - function_first = 1; - function_label_index += 2; -#endif /* !LE370 */ -#endif /* MACROPROLOGUE */ - fprintf (f, "PG%d\tEQU\t*\n", mvs_page_num ); - fprintf (f, "\tLR\t11,1\n"); - fprintf (f, "\tL\t%d,=A(PGT%d)\n", PAGE_REGISTER, mvs_page_num); - fprintf (f, "* Function %s code\n", mvs_function_name); - - mvs_free_label_list (); - mvs_page_code = 6; - mvs_page_lit = 4; - mvs_check_page (f, 0, 0); - function_base_page = mvs_page_num; - - /* find all labels in this routine */ - i370_label_scan (); -} - -static void -i370_globalize_label (stream, name) - FILE *stream; - const char *name; -{ - char temp[MAX_MVS_LABEL_SIZE + 1]; - if (mvs_check_alias (name, temp) == 2) - fprintf (stream, "%s\tALIAS\tC'%s'\n", temp, name); - fputs ("\tENTRY\t", stream); - assemble_name (stream, name); - putc ('\n', stream); -} -#endif /* TARGET_HLASM */ - - -#ifdef TARGET_ELF_ABI -/* - The 370_function_prolog() routine generates the current ELF ABI ES/390 prolog. - It implements a stack that grows downward. - It performs the following steps: - -- saves the callers non-volatile registers on the callers stack. - -- subtracts stackframe size from the stack pointer. - -- stores backpointer to old caller stack. - - XXX hack alert -- if the global var int leaf_function is nonzero, - then this is a leaf, and it might be possible to optimize the prologue - into doing even less, e.g. not grabbing a new stackframe or maybe just a - partial stack frame. - - XXX hack alert -- the current stack frame is bloated into twice the - needed size by unused entries. These entries make it marginally - compatible with MVS/OE/USS C environment, but really they're not used - and could probably chopped out. Modifications to i370.md would be needed - also, to quite using addresses 136, 140, etc. - */ - -static void -i370_output_function_prologue (f, frame_size) - FILE *f; - HOST_WIDE_INT frame_size; -{ - static int function_label_index = 1; - static int function_first = 0; - int stackframe_size, aligned_size; - - fprintf (f, "# Function prologue\n"); - /* define the stack, put it into its own data segment - FDSE == Function Stack Entry - FDSL == Function Stack Length */ - stackframe_size = - STACK_POINTER_OFFSET + current_function_outgoing_args_size + frame_size; - aligned_size = (stackframe_size + 7) >> 3; - aligned_size <<= 3; - - fprintf (f, "# arg_size=0x%x frame_size=" HOST_WIDE_INT_PRINT_HEX - " aligned size=0x%x\n", - current_function_outgoing_args_size, frame_size, aligned_size); - - fprintf (f, "\t.using\t.,r15\n"); - - /* Branch to exectuable part of prologue. */ - fprintf (f, "\tB\t.LFENT%03d\n", function_label_index); - - /* write the length of the stackframe */ - fprintf (f, "\t.long\t%d\n", aligned_size); - - /* FENT == function prologue entry */ - fprintf (f, "\t.balign 2\n.LFENT%03d:\n", - function_label_index); - - /* store multiple registers 14,15,0,...12 at 12 bytes from sp */ - fprintf (f, "\tSTM\tr14,r12,12(sp)\n"); - - /* r3 == saved callee stack pointer */ - fprintf (f, "\tLR\tr3,sp\n"); - - /* 4(r15) == stackframe size */ - fprintf (f, "\tSL\tsp,4(,r15)\n"); - - /* r11 points to arg list in callers stackframe; was passed in r2 */ - fprintf (f, "\tLR\tr11,r2\n"); - - /* store callee stack pointer at 8(sp) */ - /* fprintf (f, "\tST\tsp,8(,r3)\n "); wasted cycles, no one uses this ... */ - - /* backchain -- store caller sp at 4(callee_sp) */ - fprintf (f, "\tST\tr3,4(,sp)\n "); - - fprintf (f, "\t.drop\tr15\n"); - /* Place contents of the PSW into r3 - that is, place the address of "." into r3 */ - fprintf (f, "\tBASR\tr%d,0\n", BASE_REGISTER); - fprintf (f, "\t.using\t.,r%d\n", BASE_REGISTER); - function_first = 1; - function_label_index ++; - - fprintf (f, ".LPG%d:\n", mvs_page_num ); - fprintf (f, "\tL\tr%d,=A(.LPGT%d)\n", PAGE_REGISTER, mvs_page_num); - fprintf (f, "# Function code\n"); - - mvs_free_label_list (); - mvs_page_code = 6; - mvs_page_lit = 4; - mvs_check_page (f, 0, 0); - function_base_page = mvs_page_num; - - /* find all labels in this routine */ - i370_label_scan (); -} -#endif /* TARGET_ELF_ABI */ - -/* This function generates the assembly code for function exit. - Args are as for output_function_prologue (). - - The function epilogue should not depend on the current stack - pointer! It should use the frame pointer only. This is mandatory - because of alloca; we also take advantage of it to omit stack - adjustments before returning. */ - -static void -i370_output_function_epilogue (file, l) - FILE *file; - HOST_WIDE_INT l ATTRIBUTE_UNUSED; -{ - int i; - - check_label_emit (); - mvs_check_page (file, 14, 0); - fprintf (file, "* Function %s epilogue\n", mvs_function_name); - mvs_page_num++; - -#if MACROEPILOGUE == 1 - fprintf (file, "\tEDCEPIL\n"); -#else /* MACROEPILOGUE != 1 */ - fprintf (file, "\tL\t13,4(,13)\n"); - fprintf (file, "\tL\t14,12(,13)\n"); - fprintf (file, "\tLM\t2,12,28(13)\n"); - fprintf (file, "\tBALR\t1,14\n"); - fprintf (file, "\tDC\tA("); - assemble_name (file, mvs_function_name); - fprintf (file, ")\n" ); -#endif /* MACROEPILOGUE */ - - fprintf (file, "* Function %s literal pool\n", mvs_function_name); - fprintf (file, "\tDS\t0F\n" ); - fprintf (file, "\tLTORG\n"); - fprintf (file, "* Function %s page table\n", mvs_function_name); - fprintf (file, "\tDS\t0F\n"); - fprintf (file, "PGT%d\tEQU\t*\n", function_base_page); - - mvs_free_label_list(); - for (i = function_base_page; i < mvs_page_num; i++) - fprintf (file, "\tDC\tA(PG%d)\n", i); -} - -static void -i370_file_start () -{ - fputs ("\tRMODE\tANY\n\tCSECT\n", asm_out_file); -} - -static void -i370_file_end () -{ - fputs ("\tEND\n", asm_out_file); -} - -static void -i370_internal_label (stream, prefix, labelno) - FILE *stream; - const char *prefix; - unsigned long labelno; -{ - if (!strcmp (prefix, "L")) - mvs_add_label(labelno); - - default_internal_label (stream, prefix, labelno); -} - -static bool -i370_rtx_costs (x, code, outer_code, total) - rtx x; - int code; - int outer_code ATTRIBUTE_UNUSED; - int *total; -{ - switch (code) - { - case CONST_INT: - if ((unsigned HOST_WIDE_INT) INTVAL (x) < 0xfff) - { - *total = 1; - return true; - } - /* FALLTHRU */ - - case CONST: - case LABEL_REF: - case SYMBOL_REF: - *total = 2; - return true; - - case CONST_DOUBLE: - *total = 4; - return true; - - default: - return false; - } -} diff --git a/gcc/config/i370/i370.h b/gcc/config/i370/i370.h deleted file mode 100644 index 8109dde..0000000 --- a/gcc/config/i370/i370.h +++ /dev/null @@ -1,1862 +0,0 @@ -/* Definitions of target machine for GNU compiler. System/370 version. - Copyright (C) 1989, 1993, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, - 2003 Free Software Foundation, Inc. - Contributed by Jan Stein (jan@cd.chalmers.se). - Modified for OS/390 LanguageEnvironment C by Dave Pitts (dpitts@cozx.com) - Hacked for Linux-ELF/390 by Linas Vepstas (linas@linas.org) - -This file is part of GCC. - -GCC 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. - -GCC 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 GCC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -#ifndef GCC_I370_H -#define GCC_I370_H - -/* Target CPU builtins. */ -#define TARGET_CPU_CPP_BUILTINS() \ - do \ - { \ - builtin_define_std ("GCC"); \ - builtin_define_std ("gcc"); \ - builtin_assert ("machine=i370"); \ - builtin_assert ("cpu=i370"); \ - } \ - while (0) - -/* Run-time compilation parameters selecting different hardware subsets. */ - -extern int target_flags; - -/* The sizes of the code and literals on the current page. */ - -extern int mvs_page_code, mvs_page_lit; - -/* The current page number and the base page number for the function. */ - -extern int mvs_page_num, function_base_page; - -/* The name of the current function. */ - -extern char *mvs_function_name; - -/* The length of the function name malloc'd area. */ - -extern size_t mvs_function_name_length; - -/* Compile using char instructions (mvc, nc, oc, xc). On 4341 use this since - these are more than twice as fast as load-op-store. - On 3090 don't use this since load-op-store is much faster. */ - -#define TARGET_CHAR_INSTRUCTIONS (target_flags & 1) - -/* Default target switches */ - -#define TARGET_DEFAULT 1 - -/* Macro to define tables used to set the flags. This is a list in braces - of pairs in braces, each pair being { "NAME", VALUE } - 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 \ -{ { "char-instructions", 1, N_("Generate char instructions")}, \ - { "no-char-instructions", -1, N_("Do not generate char instructions")}, \ - { "", TARGET_DEFAULT, 0} } - -#define OVERRIDE_OPTIONS override_options () - -/* To use IBM supplied macro function prologue and epilogue, define the - following to 1. Should only be needed if IBM changes the definition - of their prologue and epilogue. */ - -#define MACROPROLOGUE 0 -#define MACROEPILOGUE 0 - -/* Target machine storage layout */ - -/* Define this if most significant bit is lowest numbered in instructions - that operate on numbered bit-fields. */ - -#define BITS_BIG_ENDIAN 1 - -/* Define this if most significant byte of a word is the lowest numbered. */ - -#define BYTES_BIG_ENDIAN 1 - -/* Define this if MS word of a multiword is the lowest numbered. */ - -#define WORDS_BIG_ENDIAN 1 - -/* Width of a word, in units (bytes). */ - -#define UNITS_PER_WORD 4 - -/* Allocation boundary (in *bits*) for storing pointers in memory. */ - -#define POINTER_BOUNDARY 32 - -/* Allocation boundary (in *bits*) for storing arguments in argument list. */ - -#define PARM_BOUNDARY 32 - -/* Boundary (in *bits*) on which stack pointer should be aligned. */ - -#define STACK_BOUNDARY 32 - -/* Allocation boundary (in *bits*) for the code of a function. */ - -#define FUNCTION_BOUNDARY 32 - -/* There is no point aligning anything to a rounder boundary than this. */ - -#define BIGGEST_ALIGNMENT 64 - -/* Alignment of field after `int : 0' in a structure. */ - -#define EMPTY_FIELD_BOUNDARY 32 - -/* Define this if move instructions will actually fail to work when given - unaligned data. */ - -#define STRICT_ALIGNMENT 0 - -/* Define target floating point format. */ - -#define TARGET_FLOAT_FORMAT IBM_FLOAT_FORMAT - -#ifdef TARGET_HLASM -/* HLASM requires #pragma map. */ -#define REGISTER_TARGET_PRAGMAS() c_register_pragma (0, "map", i370_pr_map) -#endif /* TARGET_HLASM */ - -/* Define maximum length of page minus page escape overhead. */ - -#define MAX_MVS_PAGE_LENGTH 4080 - -/* Define special register allocation order desired. - Don't fiddle with this. I did, and I got all sorts of register - spill errors when compiling even relatively simple programs... - I have no clue why ... - E.g. this one is bad: - { 0, 1, 2, 9, 8, 7, 6, 5, 10, 15, 14, 12, 3, 4, 16, 17, 18, 19, 11, 13 } - */ - -#define REG_ALLOC_ORDER \ -{ 0, 1, 2, 3, 14, 15, 12, 10, 9, 8, 7, 6, 5, 4, 16, 17, 18, 19, 11, 13 } - -/* Standard register usage. */ - -/* Number of actual hardware registers. The hardware registers are - assigned numbers for the compiler from 0 to just below - FIRST_PSEUDO_REGISTER. - All registers that the compiler knows about must be given numbers, - even those that are not normally considered general registers. - For the 370, we give the data registers numbers 0-15, - and the floating point registers numbers 16-19. */ - -#define FIRST_PSEUDO_REGISTER 20 - -/* Define base and page registers. */ - -#define BASE_REGISTER 3 -#define PAGE_REGISTER 4 - -#ifdef TARGET_HLASM -/* 1 for registers that have pervasive standard uses and are not available - for the register allocator. These are registers that must have fixed, - valid values stored in them for the entire length of the subroutine call, - and must not in any way be moved around, jiggered with, etc. That is, - they must never be clobbered, and, if clobbered, the register allocator - will never restore them back. - - We use five registers in this special way: - -- R3 which is used as the base register - -- R4 the page origin table pointer used to load R3, - -- R11 the arg pointer. - -- R12 the TCA pointer - -- R13 the stack (DSA) pointer - - A fifth register is also exceptional: R14 is used in many branch - instructions to hold the target of the branch. Technically, this - does not qualify R14 as a register with a long-term meaning; it should - be enough, theoretically, to note that these instructions clobber - R14, and let the compiler deal with that. In practice, however, - the "clobber" directive acts as a barrier to optimization, and the - optimizer appears to be unable to perform optimizations around branches. - Thus, a much better strategy appears to give R14 a pervasive use; - this eliminates it from the register pool witout hurting optimization. - - There are other registers which have special meanings, but its OK - for them to get clobbered, since other allocator config below will - make sure that they always have the right value. These are for - example: - -- R1 the returned structure pointer. - -- R10 the static chain reg. - -- R15 holds the value a subroutine returns. - - Notice that it is *almost* safe to mark R11 as available to the allocator. - By marking it as a call_used_register, in most cases, the compiler - can handle it being clobbered. However, there are a few rare - circumstances where the register allocator will allocate r11 and - also try to use it as the arg pointer ... thus it must be marked fixed. - I think this is a bug, but I can't track it down... - */ - -#define FIXED_REGISTERS \ -{ 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0 } -/*0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19*/ - -/* 1 for registers not available across function calls. These must include - the FIXED_REGISTERS and also any registers that can be used without being - saved. - The latter must include the registers where values are returned - and the register where structure-value addresses are passed. - NOTE: all floating registers are undefined across calls. -*/ - -#define CALL_USED_REGISTERS \ -{ 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1 } -/*0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19*/ - -/* Return number of consecutive hard regs needed starting at reg REGNO - to hold something of mode MODE. - This is ordinarily the length in words of a value of mode MODE - but can be less for certain modes in special long registers. - Note that DCmode (complex double) needs two regs. -*/ -#endif /* TARGET_HLASM */ - -/* ================= */ -#ifdef TARGET_ELF_ABI -/* The Linux/ELF ABI uses the same register layout as the - * the MVS/OE version, with the following exceptions: - * -- r12 (rtca) is not used. - */ - -#define FIXED_REGISTERS \ -{ 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0 } -/*0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19*/ - -#define CALL_USED_REGISTERS \ -{ 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1 } -/*0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19*/ - -#endif /* TARGET_ELF_ABI */ -/* ================= */ - - -#define HARD_REGNO_NREGS(REGNO, MODE) \ - ((REGNO) > 15 ? \ - ((GET_MODE_SIZE (MODE) + 2*UNITS_PER_WORD - 1) / (2*UNITS_PER_WORD)) : \ - (GET_MODE_SIZE(MODE)+UNITS_PER_WORD-1) / UNITS_PER_WORD) - -/* Value is 1 if hard register REGNO can hold a value of machine-mode MODE. - On the 370, the cpu registers can hold QI, HI, SI, SF and DF. The - even registers can hold DI. The floating point registers can hold - either SF, DF, SC or DC. */ - -#define HARD_REGNO_MODE_OK(REGNO, MODE) \ - ((REGNO) < 16 ? (((REGNO) & 1) == 0 || \ - (((MODE) != DImode) && ((MODE) != DFmode))) \ - : ((MODE) == SFmode || (MODE) == DFmode) || \ - (MODE) == SCmode || (MODE) == DCmode) - -/* Value is 1 if it is a good idea to tie two pseudo registers when one has - mode MODE1 and one has mode MODE2. - If HARD_REGNO_MODE_OK could produce different values for MODE1 and MODE2, - for any hard reg, then this must be 0 for correct output. */ - -#define MODES_TIEABLE_P(MODE1, MODE2) \ - (((MODE1) == SFmode || (MODE1) == DFmode) \ - == ((MODE2) == SFmode || (MODE2) == DFmode)) - -/* Specify the registers used for certain standard purposes. - The values of these macros are register numbers. */ - -/* 370 PC isn't overloaded on a register. */ - -/* #define PC_REGNUM */ - -/* Register to use for pushing function arguments. */ - -#define STACK_POINTER_REGNUM 13 - -/* Base register for access to local variables of the function. */ - -#define FRAME_POINTER_REGNUM 13 - -/* Value should be nonzero if functions must have frame pointers. - Zero means the frame pointer need not be set up (and parms may be - accessed via the stack pointer) in functions that seem suitable. - This is computed in `reload', in reload1.c. */ - -#define FRAME_POINTER_REQUIRED 1 - -/* Base register for access to arguments of the function. */ - -#define ARG_POINTER_REGNUM 11 - -/* R10 is register in which static-chain is passed to a function. - Static-chaining is done when a nested function references as a global - a stack variable of its parent: e.g. - int parent_func (int arg) { - int x; // x is in parents stack - void child_func (void) { x++: } // child references x as global var - ... - } - */ - -#define STATIC_CHAIN_REGNUM 10 - -/* R1 is register in which address to store a structure value is passed to - a function. This is used only when returning 64-bit long-long in a 32-bit arch - and when calling functions that return structs by value. e.g. - typedef struct A_s { int a,b,c; } A_t; - A_t fun_returns_value (void) { - A_t a; a.a=1; a.b=2 a.c=3; - return a; - } - In the above, the storage for the return value is in the callers stack, and - the R1 points at that mem location. - */ - -#define STRUCT_VALUE_REGNUM 1 - -/* Define the classes of registers for register constraints in the - machine description. Also define ranges of constants. - - One of the classes must always be named ALL_REGS and include all hard regs. - If there is more than one class, another class must be named NO_REGS - and contain no registers. - - The name GENERAL_REGS must be the name of a class (or an alias for - another name such as ALL_REGS). This is the class of registers - that is allowed by "g" or "r" in a register constraint. - Also, registers outside this class are allocated only when - instructions express preferences for them. - - The classes must be numbered in nondecreasing order; that is, - a larger-numbered class must never be contained completely - in a smaller-numbered class. - - For any two classes, it is very desirable that there be another - class that represents their union. */ - -enum reg_class - { - NO_REGS, ADDR_REGS, DATA_REGS, - FP_REGS, ALL_REGS, LIM_REG_CLASSES - }; - -#define GENERAL_REGS DATA_REGS -#define N_REG_CLASSES (int) LIM_REG_CLASSES - -/* Give names of register classes as strings for dump file. */ - -#define REG_CLASS_NAMES \ -{ "NO_REGS", "ADDR_REGS", "DATA_REGS", "FP_REGS", "ALL_REGS" } - -/* Define which registers fit in which classes. This is an initializer for - a vector of HARD_REG_SET of length N_REG_CLASSES. */ - -#define REG_CLASS_CONTENTS {{0}, {0x0fffe}, {0x0ffff}, {0xf0000}, {0xfffff}} - -/* The same information, inverted: - Return the class number of the smallest class containing - reg number REGNO. This could be a conditional expression - or could index an array. */ - -#define REGNO_REG_CLASS(REGNO) \ - ((REGNO) >= 16 ? FP_REGS : (REGNO) != 0 ? ADDR_REGS : DATA_REGS) - -/* The class value for index registers, and the one for base regs. */ - -#define INDEX_REG_CLASS ADDR_REGS -#define BASE_REG_CLASS ADDR_REGS - -/* Get reg_class from a letter such as appears in the machine description. */ - -#define REG_CLASS_FROM_LETTER(C) \ - ((C) == 'a' ? ADDR_REGS : \ - ((C) == 'd' ? DATA_REGS : \ - ((C) == 'f' ? FP_REGS : NO_REGS))) - -/* The letters I, J, K, L and M 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. */ - -#define CONST_OK_FOR_LETTER_P(VALUE, C) \ - ((C) == 'I' ? (unsigned) (VALUE) < 256 : \ - (C) == 'J' ? (unsigned) (VALUE) < 4096 : \ - (C) == 'K' ? (VALUE) >= -32768 && (VALUE) < 32768 : 0) - -/* Similar, but for floating constants, and defining letters G and H. - Here VALUE is the CONST_DOUBLE rtx itself. */ - -#define CONST_DOUBLE_OK_FOR_LETTER_P(VALUE, C) 1 - -/* see recog.c for details */ -#define EXTRA_CONSTRAINT(OP,C) \ - ((C) == 'R' ? r_or_s_operand (OP, GET_MODE(OP)) : \ - (C) == 'S' ? s_operand (OP, GET_MODE(OP)) : 0) \ - -/* Given an rtx X being reloaded into a reg required to be in class CLASS, - return the class of reg to actually use. In general this is just CLASS; - but on some machines in some cases it is preferable to use a more - restrictive class. - - XXX We reload CONST_INT's into ADDR not DATA regs because on certain - rare occasions when lots of egisters are spilled, reload() will try - to put a const int into r0 and then use r0 as an index register. -*/ - -#define PREFERRED_RELOAD_CLASS(X, CLASS) \ - (GET_CODE(X) == CONST_DOUBLE ? FP_REGS : \ - GET_CODE(X) == CONST_INT ? (reload_in_progress ? ADDR_REGS : DATA_REGS) : \ - GET_CODE(X) == LABEL_REF || \ - GET_CODE(X) == SYMBOL_REF || \ - GET_CODE(X) == CONST ? ADDR_REGS : (CLASS)) - -/* Return the maximum number of consecutive registers needed to represent - mode MODE in a register of class CLASS. - Note that DCmode (complex double) needs two regs. -*/ - -#define CLASS_MAX_NREGS(CLASS, MODE) \ - ((CLASS) == FP_REGS ? \ - ((GET_MODE_SIZE (MODE) + 2*UNITS_PER_WORD - 1) / (2*UNITS_PER_WORD)) : \ - (GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD) - -/* Stack layout; function entry, exit and calling. */ - -/* Define this if pushing a word on the stack makes the stack pointer a - smaller address. */ -/* ------------------------------------------------------------------- */ - -/* ================= */ -#ifdef TARGET_HLASM -/* #define STACK_GROWS_DOWNWARD */ - -/* Define this if the nominal address of the stack frame is at the - high-address end of the local variables; that is, each additional local - variable allocated goes at a more negative offset in the frame. */ - -/* #define FRAME_GROWS_DOWNWARD */ - -/* Offset within stack frame to start allocating local variables at. - If FRAME_GROWS_DOWNWARD, this is the offset to the END of the - first local allocated. Otherwise, it is the offset to the BEGINNING - of the first local allocated. */ - -#define STARTING_FRAME_OFFSET \ - (STACK_POINTER_OFFSET + current_function_outgoing_args_size) - -#define INITIAL_FRAME_POINTER_OFFSET(DEPTH) (DEPTH) = STARTING_FRAME_OFFSET - -/* If we generate an insn to push BYTES bytes, this says how many the stack - pointer really advances by. On the 370, we have no push instruction. */ - -#endif /* TARGET_HLASM */ - -/* ================= */ -#ifdef TARGET_ELF_ABI - -/* With ELF/Linux, stack is placed at large virtual addrs and grows down. - But we want the compiler to generate posistive displacements from the - stack pointer, and so we make the frame lie above the stack. */ - -#define STACK_GROWS_DOWNWARD -/* #define FRAME_GROWS_DOWNWARD */ - -/* Offset within stack frame to start allocating local variables at. - This is the offset to the BEGINNING of the first local allocated. */ - -#define STARTING_FRAME_OFFSET \ - (STACK_POINTER_OFFSET + current_function_outgoing_args_size) - -#define INITIAL_FRAME_POINTER_OFFSET(DEPTH) (DEPTH) = STARTING_FRAME_OFFSET - -#endif /* TARGET_ELF_ABI */ -/* ================= */ - -/* #define PUSH_ROUNDING(BYTES) */ - -/* Accumulate the outgoing argument count so we can request the right - DSA size and determine stack offset. */ - -#define ACCUMULATE_OUTGOING_ARGS 1 - -/* Define offset from stack pointer, to location where a parm can be - pushed. */ - -#define STACK_POINTER_OFFSET 148 - -/* Offset of first parameter from the argument pointer register value. */ - -#define FIRST_PARM_OFFSET(FNDECL) 0 - -/* 1 if N is a possible register number for function argument passing. - On the 370, no registers are used in this way. */ - -#define FUNCTION_ARG_REGNO_P(N) 0 - -/* Define a data type for recording info about an argument list during - the scan of that argument list. This data type should hold all - necessary information about the function itself and about the args - processed so far, enough to enable macros such as FUNCTION_ARG to - determine where the next arg should go. */ - -#define CUMULATIVE_ARGS int - -/* Initialize a variable CUM of type CUMULATIVE_ARGS for a call to - a function whose data type is FNTYPE. - For a library call, FNTYPE is 0. */ - -#define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, INDIRECT) ((CUM) = 0) - -/* Update the data in CUM to advance over an argument of mode MODE and - data type TYPE. (TYPE is null for libcalls where that information - may not be available.) */ - -#define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED) \ - ((CUM) += ((MODE) == DFmode || (MODE) == SFmode \ - ? 256 \ - : (MODE) != BLKmode \ - ? (GET_MODE_SIZE (MODE) + 3) / 4 \ - : (int_size_in_bytes (TYPE) + 3) / 4)) - -/* Define where to put the arguments to a function. Value is zero to push - the argument on the stack, or a hard register in which to store the - argument. */ - -#define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) 0 - -/* For an arg passed partly in registers and partly in memory, this is the - number of registers used. For args passed entirely in registers or - entirely in memory, zero. */ - -#define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) 0 - -/* Define if returning from a function call automatically pops the - arguments described by the number-of-args field in the call. */ - -#define RETURN_POPS_ARGS(FUNDECL,FUNTYPE,SIZE) 0 - -/* The FUNCTION_VALUE macro defines how to find the value returned by a - function. VALTYPE is the data type of the value (as a tree). - If the precise function being called is known, FUNC is its FUNCTION_DECL; - otherwise, FUNC is NULL. - - On the 370 the return value is in R15 or R16. However, - DImode (64-bit ints) scalars need to get returned on the stack, - with r15 pointing to the location. To accomplish this, we define - the RETURN_IN_MEMORY macro to be true for both blockmode (structures) - and the DImode scalars. - */ - -#define RET_REG(MODE) \ - (((MODE) == DCmode || (MODE) == SCmode \ - || (MODE) == DFmode || (MODE) == SFmode) ? 16 : 15) - -#define FUNCTION_VALUE(VALTYPE, FUNC) \ - gen_rtx_REG (TYPE_MODE (VALTYPE), RET_REG (TYPE_MODE (VALTYPE))) - -#define RETURN_IN_MEMORY(VALTYPE) \ - ((DImode == TYPE_MODE (VALTYPE)) || (BLKmode == TYPE_MODE (VALTYPE))) - -/* Define how to find the value returned by a library function assuming - the value has mode MODE. */ - -#define LIBCALL_VALUE(MODE) gen_rtx_REG (MODE, RET_REG (MODE)) - -/* 1 if N is a possible register number for a function value. - On the 370 under C/370, R15 and R16 are thus used. */ - -#define FUNCTION_VALUE_REGNO_P(N) ((N) == 15 || (N) == 16) - -/* This macro definition sets up a default value for `main' to return. */ - -#define DEFAULT_MAIN_RETURN c_expand_return (integer_zero_node) - - -/* Output assembler code for a block containing the constant parts of a - trampoline, leaving space for the variable parts. - - On the 370, the trampoline contains these instructions: - - BALR 14,0 - USING *,14 - L STATIC_CHAIN_REGISTER,X - L 15,Y - BR 15 - X DS 0F - Y DS 0F */ -/* - I am confused as to why this emitting raw binary, instead of instructions ... - see for example, rs6000/rs000.c for an example of a different way to - do this ... especially since BASR should probably be substituted for BALR. - */ - -#define TRAMPOLINE_TEMPLATE(FILE) \ -{ \ - assemble_aligned_integer (2, GEN_INT (0x05E0)); \ - assemble_aligned_integer (2, GEN_INT (0x5800 | STATIC_CHAIN_REGNUM << 4)); \ - assemble_aligned_integer (2, GEN_INT (0xE00A)); \ - assemble_aligned_integer (2, GEN_INT (0x58F0)); \ - assemble_aligned_integer (2, GEN_INT (0xE00E)); \ - assemble_aligned_integer (2, GEN_INT (0x07FF)); \ - assemble_aligned_integer (2, const0_rtx); \ - assemble_aligned_integer (2, const0_rtx); \ - assemble_aligned_integer (2, const0_rtx); \ - assemble_aligned_integer (2, const0_rtx); \ -} - -/* Length in units of the trampoline for entering a nested function. */ - -#define TRAMPOLINE_SIZE 20 - -/* Emit RTL insns to initialize the variable parts of a trampoline. */ - -#define INITIALIZE_TRAMPOLINE(TRAMP, FNADDR, CXT) \ -{ \ - emit_move_insn (gen_rtx_MEM (SImode, plus_constant (TRAMP, 12)), CXT); \ - emit_move_insn (gen_rtx_MEM (SImode, plus_constant (TRAMP, 16)), FNADDR); \ -} - -/* Define EXIT_IGNORE_STACK if, when returning from a function, the stack - pointer does not matter (provided there is a frame pointer). */ - -#define EXIT_IGNORE_STACK 1 - -/* Addressing modes, and classification of registers for them. */ - -/* These assume that REGNO is a hard or pseudo reg number. They give - nonzero only if REGNO is a hard reg of the suitable class or a pseudo - reg currently allocated to a suitable hard reg. - These definitions are NOT overridden anywhere. */ - -#define REGNO_OK_FOR_INDEX_P(REGNO) \ - (((REGNO) > 0 && (REGNO) < 16) \ - || (reg_renumber[REGNO] > 0 && reg_renumber[REGNO] < 16)) - -#define REGNO_OK_FOR_BASE_P(REGNO) REGNO_OK_FOR_INDEX_P(REGNO) - -#define REGNO_OK_FOR_DATA_P(REGNO) \ - ((REGNO) < 16 || (unsigned) reg_renumber[REGNO] < 16) - -#define REGNO_OK_FOR_FP_P(REGNO) \ - ((unsigned) ((REGNO) - 16) < 4 || (unsigned) (reg_renumber[REGNO] - 16) < 4) - -/* Now macros that check whether X is a register and also, - strictly, whether it is in a specified class. */ - -/* 1 if X is a data register. */ - -#define DATA_REG_P(X) (REG_P (X) && REGNO_OK_FOR_DATA_P (REGNO (X))) - -/* 1 if X is an fp register. */ - -#define FP_REG_P(X) (REG_P (X) && REGNO_OK_FOR_FP_P (REGNO (X))) - -/* 1 if X is an address register. */ - -#define ADDRESS_REG_P(X) (REG_P (X) && REGNO_OK_FOR_BASE_P (REGNO (X))) - -/* Maximum number of registers that can appear in a valid memory address. */ - -#define MAX_REGS_PER_ADDRESS 2 - -/* Recognize any constant value that is a valid address. */ - -#define CONSTANT_ADDRESS_P(X) \ - (GET_CODE (X) == LABEL_REF || GET_CODE (X) == SYMBOL_REF \ - || GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST_DOUBLE \ - || (GET_CODE (X) == CONST \ - && GET_CODE (XEXP (XEXP (X, 0), 0)) == LABEL_REF) \ - || (GET_CODE (X) == CONST \ - && GET_CODE (XEXP (XEXP (X, 0), 0)) == SYMBOL_REF \ - && !SYMBOL_REF_EXTERNAL_P (XEXP (XEXP (X, 0), 0)))) - -/* Nonzero if the constant value X is a legitimate general operand. - It is given that X satisfies CONSTANT_P or is a CONST_DOUBLE. */ - -#define LEGITIMATE_CONSTANT_P(X) 1 - -/* The macros REG_OK_FOR..._P assume that the arg is a REG rtx and check - its validity for a certain class. We have two alternate definitions - for each of them. The usual definition accepts all pseudo regs; the - other rejects them all. The symbol REG_OK_STRICT causes the latter - definition to be used. - - Most source files want to accept pseudo regs in the hope that they will - get allocated to the class that the insn wants them to be in. - Some source files that are used after register allocation - need to be strict. */ - -#ifndef REG_OK_STRICT - -/* Nonzero if X is a hard reg that can be used as an index or if it is - a pseudo reg. */ - -#define REG_OK_FOR_INDEX_P(X) \ - ((REGNO(X) > 0 && REGNO(X) < 16) || REGNO(X) >= 20) - -/* 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) REG_OK_FOR_INDEX_P(X) - -#else /* REG_OK_STRICT */ - -/* Nonzero if X is a hard reg that can be used as an index. */ - -#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)) - -#endif /* REG_OK_STRICT */ - -/* 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 - that wants to use this address. - - The other macros defined here are used only in GO_IF_LEGITIMATE_ADDRESS, - except for CONSTANT_ADDRESS_P which is actually machine-independent. -*/ - -#define COUNT_REGS(X, REGS, FAIL) \ - if (REG_P (X)) { \ - if (REG_OK_FOR_BASE_P (X)) REGS += 1; \ - else goto FAIL; \ - } \ - else if (GET_CODE (X) != CONST_INT || (unsigned) INTVAL (X) >= 4096) \ - goto FAIL; - -#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \ -{ \ - if (REG_P (X) && REG_OK_FOR_BASE_P (X)) \ - goto ADDR; \ - if (GET_CODE (X) == PLUS) \ - { \ - int regs = 0; \ - rtx x0 = XEXP (X, 0); \ - rtx x1 = XEXP (X, 1); \ - if (GET_CODE (x0) == PLUS) \ - { \ - COUNT_REGS (XEXP (x0, 0), regs, FAIL); \ - COUNT_REGS (XEXP (x0, 1), regs, FAIL); \ - COUNT_REGS (x1, regs, FAIL); \ - if (regs == 2) \ - goto ADDR; \ - } \ - else if (GET_CODE (x1) == PLUS) \ - { \ - COUNT_REGS (x0, regs, FAIL); \ - COUNT_REGS (XEXP (x1, 0), regs, FAIL); \ - COUNT_REGS (XEXP (x1, 1), regs, FAIL); \ - if (regs == 2) \ - goto ADDR; \ - } \ - else \ - { \ - COUNT_REGS (x0, regs, FAIL); \ - COUNT_REGS (x1, regs, FAIL); \ - if (regs != 0) \ - goto ADDR; \ - } \ - } \ - FAIL: ; \ -} - -/* The 370 has no mode dependent addresses. */ - -#define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR, LABEL) - -/* Macro: LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN) - Try machine-dependent ways of modifying an illegitimate address - to be legitimate. If we find one, return the new, valid address. - This macro is used in only one place: `memory_address' in explow.c. - - Several comments: - (1) It's not obvious that this macro results in better code - than its omission does. For historical reasons we leave it in. - - (2) This macro may be (???) implicated in the accidental promotion - or RS operand to RX operands, which bombs out any RS, SI, SS - instruction that was expecting a simple address. Note that - this occurs fairly rarely ... - - (3) There is a bug somewhere that causes either r4 to be spilled, - or causes r0 to be used as a base register. Changeing the macro - below will make the bug move around, but will not make it go away - ... Note that this is a rare bug ... - - */ - -#define LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN) \ -{ \ - if (GET_CODE (X) == PLUS && CONSTANT_ADDRESS_P (XEXP (X, 1))) \ - (X) = gen_rtx_PLUS (SImode, XEXP (X, 0), \ - copy_to_mode_reg (SImode, XEXP (X, 1))); \ - if (GET_CODE (X) == PLUS && CONSTANT_ADDRESS_P (XEXP (X, 0))) \ - (X) = gen_rtx_PLUS (SImode, XEXP (X, 1), \ - copy_to_mode_reg (SImode, XEXP (X, 0))); \ - if (GET_CODE (X) == PLUS && GET_CODE (XEXP (X, 0)) == MULT) \ - (X) = gen_rtx_PLUS (SImode, XEXP (X, 1), \ - force_operand (XEXP (X, 0), 0)); \ - if (GET_CODE (X) == PLUS && GET_CODE (XEXP (X, 1)) == MULT) \ - (X) = gen_rtx_PLUS (SImode, XEXP (X, 0), \ - force_operand (XEXP (X, 1), 0)); \ - if (memory_address_p (MODE, X)) \ - goto WIN; \ -} - -/* Specify the machine mode that this machine uses for the index in the - tablejump instruction. */ - -#define CASE_VECTOR_MODE SImode - -/* Define this if the tablejump instruction expects the table to contain - offsets from the address of the table. - Do not define this if the table should contain absolute addresses. */ - -/* #define CASE_VECTOR_PC_RELATIVE */ - -/* Define this if fixuns_trunc is the same as fix_trunc. */ - -#define FIXUNS_TRUNC_LIKE_FIX_TRUNC - -/* We use "unsigned char" as default. */ - -#define DEFAULT_SIGNED_CHAR 0 - -/* Max number of bytes we can move from memory to memory in one reasonably - fast instruction. */ - -#define MOVE_MAX 256 - -/* Nonzero if access to memory by bytes is slow and undesirable. */ - -#define SLOW_BYTE_ACCESS 1 - -/* Define if shifts truncate the shift count which implies one can omit - a sign-extension or zero-extension of a shift count. */ - -/* #define SHIFT_COUNT_TRUNCATED */ - -/* Value is 1 if truncating an integer of INPREC bits to OUTPREC bits - is done just by pretending it is already truncated. */ - -#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) (OUTPREC != 16) - -/* ??? Investigate defining STORE_FLAG_VALUE to (-1). */ - -/* When a prototype says `char' or `short', really pass an `int'. */ - -#define PROMOTE_PROTOTYPES 1 - -/* Don't perform CSE on function addresses. */ - -#define NO_FUNCTION_CSE - -/* Specify the machine mode that pointers have. - After generation of rtl, the compiler makes no further distinction - between pointers and any other objects of this machine mode. */ - -#define Pmode SImode - -/* A function address in a call instruction is a byte address (for - indexing purposes) so give the MEM rtx a byte's mode. */ - -#define FUNCTION_MODE QImode - -/* A C statement (sans semicolon) to update the integer variable COST - based on the relationship between INSN that is dependent on - DEP_INSN through the dependence LINK. The default is to make no - adjustment to COST. This can be used for example to specify to - the scheduler that an output- or anti-dependence does not incur - the same cost as a data-dependence. - - We will want to use this to indicate that there is a cost associated - with the loading, followed by use of base registers ... -#define ADJUST_COST (INSN, LINK, DEP_INSN, COST) - */ - -/* Tell final.c how to eliminate redundant test instructions. */ - -/* Here we define machine-dependent flags and fields in cc_status - (see `conditions.h'). */ - -/* Store in cc_status the expressions that the condition codes will - describe after execution of an instruction whose pattern is EXP. - Do not alter them if the instruction would not alter the cc's. - - On the 370, load insns do not alter the cc's. However, in some - cases these instructions can make it possibly invalid to use the - saved cc's. In those cases we clear out some or all of the saved - cc's so they won't be used. - - Note that only some arith instructions set the CC. These include - add, subtract, complement, various shifts. Note that multiply - and divide do *not* set set the CC. Therefore, in the code below, - don't set the status for MUL, DIV, etc. - - Note that the bitwise ops set the condition code, but not in a - way that we can make use of it. So we treat these as clobbering, - rather than setting the CC. These are clobbered in the individual - instruction patterns that use them. Use CC_STATUS_INIT to clobber. -*/ - -#define NOTICE_UPDATE_CC(EXP, INSN) \ -{ \ - rtx exp = (EXP); \ - if (GET_CODE (exp) == PARALLEL) /* Check this */ \ - exp = XVECEXP (exp, 0, 0); \ - if (GET_CODE (exp) != SET) \ - CC_STATUS_INIT; \ - else \ - { \ - if (XEXP (exp, 0) == cc0_rtx) \ - { \ - cc_status.value1 = XEXP (exp, 0); \ - cc_status.value2 = XEXP (exp, 1); \ - cc_status.flags = 0; \ - } \ - else \ - { \ - if (cc_status.value1 \ - && reg_mentioned_p (XEXP (exp, 0), cc_status.value1)) \ - cc_status.value1 = 0; \ - if (cc_status.value2 \ - && reg_mentioned_p (XEXP (exp, 0), cc_status.value2)) \ - cc_status.value2 = 0; \ - switch (GET_CODE (XEXP (exp, 1))) \ - { \ - case PLUS: case MINUS: case NEG: \ - case NOT: case ABS: \ - CC_STATUS_SET (XEXP (exp, 0), XEXP (exp, 1)); \ - \ - /* mult and div don't set any cc codes !! */ \ - case MULT: /* case UMULT: */ case DIV: case UDIV: \ - /* and, or and xor set the cc's the wrong way !! */ \ - case AND: case IOR: case XOR: \ - /* some shifts set the CC some don't. */ \ - case ASHIFT: case ASHIFTRT: \ - do {} while (0); \ - default: \ - break; \ - } \ - } \ - } \ -} - - -#define CC_STATUS_SET(V1, V2) \ -{ \ - cc_status.flags = 0; \ - cc_status.value1 = (V1); \ - cc_status.value2 = (V2); \ - if (cc_status.value1 \ - && reg_mentioned_p (cc_status.value1, cc_status.value2)) \ - cc_status.value2 = 0; \ -} - -#define OUTPUT_JUMP(NORMAL, FLOAT, NO_OV) \ -{ if (cc_status.flags & CC_NO_OVERFLOW) return NO_OV; return NORMAL; } - -/* ------------------------------------------ */ -/* Control the assembler format that we output. */ - -/* Define standard character escape sequences for non-ASCII targets - only. */ - -#ifdef TARGET_EBCDIC -#define TARGET_ESC 39 -#define TARGET_BELL 47 -#define TARGET_BS 22 -#define TARGET_TAB 5 -#define TARGET_NEWLINE 21 -#define TARGET_VT 11 -#define TARGET_FF 12 -#define TARGET_CR 13 -#endif - -/* ======================================================== */ - -#ifdef TARGET_HLASM -#define TEXT_SECTION_ASM_OP "* Program text area" -#define DATA_SECTION_ASM_OP "* Program data area" -#define INIT_SECTION_ASM_OP "* Program initialization area" -#define SHARED_SECTION_ASM_OP "* Program shared data" -#define CTOR_LIST_BEGIN /* NO OP */ -#define CTOR_LIST_END /* NO OP */ -#define MAX_MVS_LABEL_SIZE 8 - -/* How to refer to registers in assembler output. This sequence is - indexed by compiler's hard-register-number (see above). */ - -#define REGISTER_NAMES \ -{ "0", "1", "2", "3", "4", "5", "6", "7", \ - "8", "9", "10", "11", "12", "13", "14", "15", \ - "0", "2", "4", "6" \ -} - -#define ASM_COMMENT_START "*" -#define ASM_APP_OFF "" -#define ASM_APP_ON "" - -#define ASM_OUTPUT_LABEL(FILE, NAME) \ -{ assemble_name (FILE, NAME); fputs ("\tEQU\t*\n", FILE); } - -#define ASM_OUTPUT_EXTERNAL(FILE, DECL, NAME) \ -{ \ - char temp[MAX_MVS_LABEL_SIZE + 1]; \ - if (mvs_check_alias (NAME, temp) == 2) \ - { \ - fprintf (FILE, "%s\tALIAS\tC'%s'\n", temp, NAME); \ - } \ -} - -/* MVS externals are limited to 8 characters, upper case only. - The '_' is mapped to '@', except for MVS functions, then '#'. */ - - -#define ASM_OUTPUT_LABELREF(FILE, NAME) \ -{ \ - char *bp, ch, temp[MAX_MVS_LABEL_SIZE + 1]; \ - if (!mvs_get_alias (NAME, temp)) \ - strcpy (temp, NAME); \ - if (!strcmp (temp,"main")) \ - strcpy (temp,"gccmain"); \ - if (mvs_function_check (temp)) \ - ch = '#'; \ - else \ - ch = '@'; \ - for (bp = temp; *bp; bp++) \ - *bp = (*bp == '_' ? ch : TOUPPER (*bp)); \ - fprintf (FILE, "%s", temp); \ -} - -#define ASM_GENERATE_INTERNAL_LABEL(LABEL, PREFIX, NUM) \ - sprintf (LABEL, "*%s%lu", PREFIX, (unsigned long)(NUM)) - -/* Generate case label. For HLASM we can change to the data CSECT - and put the vectors out of the code body. The assembler just - concatenates CSECTs with the same name. */ - -#define ASM_OUTPUT_CASE_LABEL(FILE, PREFIX, NUM, TABLE) \ - fprintf (FILE, "\tDS\t0F\n"); \ - fprintf (FILE,"\tCSECT\n"); \ - fprintf (FILE, "%s%d\tEQU\t*\n", PREFIX, NUM) - -/* Put the CSECT back to the code body */ - -#define ASM_OUTPUT_CASE_END(FILE, NUM, TABLE) \ - assemble_name (FILE, mvs_function_name); \ - fputs ("\tCSECT\n", FILE); - -/* This is how to output an element of a case-vector that is absolute. */ - -#define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \ - fprintf (FILE, "\tDC\tA(L%d)\n", VALUE) - -/* 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, "\tDC\tA(L%d-L%d)\n", VALUE, REL) - -/* This is how to output an insn to push a register on the stack. - It need not be very fast code. - Right now, PUSH & POP are used only when profiling is enabled, - and then, only to push the static chain reg and the function struct - value reg, and only if those are used. Since profiling is not - supported anyway, punt on this. */ - -#define ASM_OUTPUT_REG_PUSH(FILE, REGNO) \ - mvs_check_page (FILE, 8, 4); \ - fprintf (FILE, "\tS\t13,=F'4'\n\tST\t%s,%d(13)\n", \ - reg_names[REGNO], STACK_POINTER_OFFSET) - -/* 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) \ - mvs_check_page (FILE, 8, 0); \ - fprintf (FILE, "\tL\t%s,%d(13)\n\tLA\t13,4(13)\n", \ - reg_names[REGNO], STACK_POINTER_OFFSET) - -/* This outputs a text string. The string are chopped up to fit into - an 80 byte record. Also, control and special characters, interpreted - by the IBM assembler, are output numerically. */ - -#define MVS_ASCII_TEXT_LENGTH 48 - -#define ASM_OUTPUT_ASCII(FILE, PTR, LEN) \ -{ \ - size_t i, limit = (LEN); \ - int j; \ - for (j = 0, i = 0; i < limit; j++, i++) \ - { \ - int c = (PTR)[i]; \ - if (ISCNTRL (c) || c == '&') \ - { \ - if (j % MVS_ASCII_TEXT_LENGTH != 0 ) \ - fprintf (FILE, "'\n"); \ - j = -1; \ - fprintf (FILE, "\tDC\tX'%X'\n", c ); \ - } \ - else \ - { \ - if (j % MVS_ASCII_TEXT_LENGTH == 0) \ - fprintf (FILE, "\tDC\tC'"); \ - if ( c == '\'' ) \ - fprintf (FILE, "%c%c", c, c); \ - else \ - fprintf (FILE, "%c", c); \ - if (j % MVS_ASCII_TEXT_LENGTH == MVS_ASCII_TEXT_LENGTH - 1) \ - fprintf (FILE, "'\n" ); \ - } \ - } \ - if (j % MVS_ASCII_TEXT_LENGTH != 0) \ - fprintf (FILE, "'\n"); \ -} - -/* This is how to output an assembler line that says to advance the - location counter to a multiple of 2**LOG bytes. */ - -#define ASM_OUTPUT_ALIGN(FILE, LOG) \ - if (LOG) \ - { \ - if ((LOG) == 1) \ - fprintf (FILE, "\tDS\t0H\n" ); \ - else \ - fprintf (FILE, "\tDS\t0F\n" ); \ - } \ - -/* The maximum length of memory that the IBM assembler will allow in one - DS operation. */ - -#define MAX_CHUNK 32767 - -/* A C statement to output to the stdio stream FILE an assembler - instruction to advance the location counter by SIZE bytes. Those - bytes should be zero when loaded. */ - -#define ASM_OUTPUT_SKIP(FILE, SIZE) \ -{ \ - unsigned HOST_WIDE_INT s; \ - int k; \ - for (s = (SIZE); s > 0; s -= MAX_CHUNK) \ - { \ - if (s > MAX_CHUNK) \ - k = MAX_CHUNK; \ - else \ - k = s; \ - fprintf (FILE, "\tDS\tXL%d\n", k); \ - } \ -} - -/* A C statement (sans semicolon) to output to the stdio stream - FILE the assembler definition of a common-label named NAME whose - size is SIZE bytes. The variable ROUNDED is the size rounded up - to whatever alignment the caller wants. */ - -#define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED) \ -{ \ - char temp[MAX_MVS_LABEL_SIZE + 1]; \ - if (mvs_check_alias(NAME, temp) == 2) \ - { \ - fprintf (FILE, "%s\tALIAS\tC'%s'\n", temp, NAME); \ - } \ - fputs ("\tENTRY\t", FILE); \ - assemble_name (FILE, NAME); \ - fputs ("\n", FILE); \ - fprintf (FILE, "\tDS\t0F\n"); \ - ASM_OUTPUT_LABEL (FILE,NAME); \ - ASM_OUTPUT_SKIP (FILE,SIZE); \ -} - -/* A C statement (sans semicolon) to output to the stdio stream - FILE the assembler definition of a local-common-label named NAME - whose size is SIZE bytes. The variable ROUNDED is the size - rounded up to whatever alignment the caller wants. */ - -#define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE, ROUNDED) \ -{ \ - fprintf (FILE, "\tDS\t0F\n"); \ - ASM_OUTPUT_LABEL (FILE,NAME); \ - ASM_OUTPUT_SKIP (FILE,SIZE); \ -} - -#define ASM_PN_FORMAT "%s%lu" - -/* Print operand XV (an rtx) in assembler syntax to file FILE. - CODE is a letter or dot (`z' in `%z0') or 0 if no letter was specified. - For `%' followed by punctuation, CODE is the punctuation and XV is null. */ - -#define PRINT_OPERAND(FILE, XV, CODE) \ -{ \ - switch (GET_CODE (XV)) \ - { \ - static char curreg[4]; \ - case REG: \ - if (CODE == 'N') \ - strcpy (curreg, reg_names[REGNO (XV) + 1]); \ - else \ - strcpy (curreg, reg_names[REGNO (XV)]); \ - fprintf (FILE, "%s", curreg); \ - break; \ - case MEM: \ - { \ - rtx addr = XEXP (XV, 0); \ - if (CODE == 'O') \ - { \ - if (GET_CODE (addr) == PLUS) \ - fprintf (FILE, HOST_WIDE_INT_PRINT_DEC, INTVAL (XEXP (addr, 1))); \ - else \ - fprintf (FILE, "0"); \ - } \ - else if (CODE == 'R') \ - { \ - if (GET_CODE (addr) == PLUS) \ - fprintf (FILE, "%s", reg_names[REGNO (XEXP (addr, 0))]);\ - else \ - fprintf (FILE, "%s", reg_names[REGNO (addr)]); \ - } \ - else \ - output_address (XEXP (XV, 0)); \ - } \ - break; \ - case SYMBOL_REF: \ - case LABEL_REF: \ - mvs_page_lit += 4; \ - if (SYMBOL_REF_EXTERNAL_P (XV)) fprintf (FILE, "=V("); \ - else fprintf (FILE, "=A("); \ - output_addr_const (FILE, XV); \ - fprintf (FILE, ")"); \ - break; \ - case CONST_INT: \ - if (CODE == 'B') \ - fprintf (FILE, "%d", (int) (INTVAL (XV) & 0xff)); \ - else if (CODE == 'X') \ - fprintf (FILE, "%02X", (int) (INTVAL (XV) & 0xff)); \ - else if (CODE == 'h') \ - fprintf (FILE, HOST_WIDE_INT_PRINT_DEC, (INTVAL (XV) << 16) >> 16); \ - else if (CODE == 'H') \ - { \ - mvs_page_lit += 2; \ - fprintf (FILE, "=H'" HOST_WIDE_INT_PRINT_DEC "'", (INTVAL (XV) << 16) >> 16); \ - } \ - else if (CODE == 'K') \ - { \ - /* auto sign-extension of signed 16-bit to signed 32-bit */ \ - mvs_page_lit += 4; \ - fprintf (FILE, "=F'" HOST_WIDE_INT_PRINT_DEC "'", (INTVAL (XV) << 16) >> 16); \ - } \ - else if (CODE == 'W') \ - { \ - /* hand-built sign-extension of signed 32-bit to 64-bit */ \ - mvs_page_lit += 8; \ - if (0 <= INTVAL (XV)) { \ - fprintf (FILE, "=XL8'00000000"); \ - } else { \ - fprintf (FILE, "=XL8'FFFFFFFF"); \ - } \ - fprintf (FILE, "%08X'", INTVAL (XV)); \ - } \ - else \ - { \ - mvs_page_lit += 4; \ - fprintf (FILE, "=F'" HOST_WIDE_INT_PRINT_DEC "'", INTVAL (XV)); \ - } \ - break; \ - case CONST_DOUBLE: \ - if (GET_MODE (XV) == DImode) \ - { \ - if (CODE == 'M') \ - { \ - mvs_page_lit += 4; \ - fprintf (FILE, "=XL4'%08X'", CONST_DOUBLE_LOW (XV)); \ - } \ - else if (CODE == 'L') \ - { \ - mvs_page_lit += 4; \ - fprintf (FILE, "=XL4'%08X'", CONST_DOUBLE_HIGH (XV)); \ - } \ - else \ - { \ - mvs_page_lit += 8; \ - fprintf (FILE, "=XL8'%08X%08X'", CONST_DOUBLE_LOW (XV), \ - CONST_DOUBLE_HIGH (XV)); \ - } \ - } \ - else \ - { \ - char buf[50]; \ - if (GET_MODE (XV) == SFmode) \ - { \ - mvs_page_lit += 4; \ - real_to_decimal (buf, CONST_DOUBLE_REAL_VALUE (XV), \ - sizeof (buf), 0, 1); \ - fprintf (FILE, "=E'%s'", buf); \ - } \ - else if (GET_MODE (XV) == DFmode) \ - { \ - mvs_page_lit += 8; \ - real_to_decimal (buf, CONST_DOUBLE_REAL_VALUE (XV), \ - sizeof (buf), 0, 1); \ - fprintf (FILE, "=D'%s'", buf); \ - } \ - else /* VOIDmode */ \ - { \ - mvs_page_lit += 8; \ - fprintf (FILE, "=XL8'%08X%08X'", \ - CONST_DOUBLE_HIGH (XV), CONST_DOUBLE_LOW (XV)); \ - } \ - } \ - break; \ - case CONST: \ - if (GET_CODE (XEXP (XV, 0)) == PLUS \ - && GET_CODE (XEXP (XEXP (XV, 0), 0)) == SYMBOL_REF) \ - { \ - mvs_page_lit += 4; \ - if (SYMBOL_REF_EXTERNAL_P (XEXP (XEXP (XV, 0), 0))) \ - { \ - fprintf (FILE, "=V("); \ - ASM_OUTPUT_LABELREF (FILE, \ - XSTR (XEXP (XEXP (XV, 0), 0), 0)); \ - fprintf (FILE, ")\n\tA\t%s,=F'" HOST_WIDE_INT_PRINT_DEC "'", \ - curreg, INTVAL (XEXP (XEXP (XV, 0), 1))); \ - } \ - else \ - { \ - fprintf (FILE, "=A("); \ - output_addr_const (FILE, XV); \ - fprintf (FILE, ")"); \ - } \ - } \ - else \ - { \ - mvs_page_lit += 4; \ - fprintf (FILE, "=F'"); \ - output_addr_const (FILE, XV); \ - fprintf (FILE, "'"); \ - } \ - break; \ - default: \ - abort(); \ - } \ -} - -#define PRINT_OPERAND_ADDRESS(FILE, ADDR) \ -{ \ - rtx breg, xreg, offset, plus; \ - \ - switch (GET_CODE (ADDR)) \ - { \ - case REG: \ - fprintf (FILE, "0(%s)", reg_names[REGNO (ADDR)]); \ - break; \ - case PLUS: \ - breg = 0; \ - xreg = 0; \ - offset = 0; \ - if (GET_CODE (XEXP (ADDR, 0)) == PLUS) \ - { \ - if (GET_CODE (XEXP (ADDR, 1)) == REG) \ - breg = XEXP (ADDR, 1); \ - else \ - offset = XEXP (ADDR, 1); \ - plus = XEXP (ADDR, 0); \ - } \ - else \ - { \ - if (GET_CODE (XEXP (ADDR, 0)) == REG) \ - breg = XEXP (ADDR, 0); \ - else \ - offset = XEXP (ADDR, 0); \ - plus = XEXP (ADDR, 1); \ - } \ - if (GET_CODE (plus) == PLUS) \ - { \ - if (GET_CODE (XEXP (plus, 0)) == REG) \ - { \ - if (breg) \ - xreg = XEXP (plus, 0); \ - else \ - breg = XEXP (plus, 0); \ - } \ - else \ - { \ - offset = XEXP (plus, 0); \ - } \ - if (GET_CODE (XEXP (plus, 1)) == REG) \ - { \ - if (breg) \ - xreg = XEXP (plus, 1); \ - else \ - breg = XEXP (plus, 1); \ - } \ - else \ - { \ - offset = XEXP (plus, 1); \ - } \ - } \ - else if (GET_CODE (plus) == REG) \ - { \ - if (breg) \ - xreg = plus; \ - else \ - breg = plus; \ - } \ - else \ - { \ - offset = plus; \ - } \ - if (offset) \ - { \ - if (GET_CODE (offset) == LABEL_REF) \ - fprintf (FILE, "L%d", \ - CODE_LABEL_NUMBER (XEXP (offset, 0))); \ - else \ - output_addr_const (FILE, offset); \ - } \ - else \ - fprintf (FILE, "0"); \ - if (xreg) \ - fprintf (FILE, "(%s,%s)", \ - reg_names[REGNO (xreg)], reg_names[REGNO (breg)]); \ - else \ - fprintf (FILE, "(%s)", reg_names[REGNO (breg)]); \ - break; \ - default: \ - mvs_page_lit += 4; \ - if (SYMBOL_REF_EXTERNAL_P (ADDR)) fprintf (FILE, "=V("); \ - else fprintf (FILE, "=A("); \ - output_addr_const (FILE, ADDR); \ - fprintf (FILE, ")"); \ - break; \ - } \ -} - -#define ASM_DECLARE_FUNCTION_NAME(FILE, NAME, DECL) \ -{ \ - if (strlen (NAME) + 1 > mvs_function_name_length) \ - { \ - if (mvs_function_name) \ - free (mvs_function_name); \ - mvs_function_name = 0; \ - } \ - if (!mvs_function_name) \ - { \ - mvs_function_name_length = strlen (NAME) * 2 + 1; \ - mvs_function_name = (char *) xmalloc (mvs_function_name_length); \ - } \ - if (!strcmp (NAME, "main")) \ - strcpy (mvs_function_name, "gccmain"); \ - else \ - strcpy (mvs_function_name, NAME); \ - fprintf (FILE, "\tDS\t0F\n"); \ - assemble_name (FILE, mvs_function_name); \ - fputs ("\tRMODE\tANY\n", FILE); \ - assemble_name (FILE, mvs_function_name); \ - fputs ("\tCSECT\n", FILE); \ -} - -/* Output assembler code to FILE to increment profiler label # LABELNO - for profiling a function entry. */ - -#define FUNCTION_PROFILER(FILE, LABELNO) \ - fprintf (FILE, "Error: No profiling available.\n") - -#endif /* TARGET_HLASM */ - -/* ======================================================== */ - -#ifdef TARGET_ELF_ABI - -/* How to refer to registers in assembler output. This sequence is - indexed by compiler's hard-register-number (see above). */ - -#define REGISTER_NAMES \ -{ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", \ - "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", \ - "f0", "f2", "f4", "f6" \ -} - -/* Print operand XV (an rtx) in assembler syntax to file FILE. - CODE is a letter or dot (`z' in `%z0') or 0 if no letter was specified. - For `%' followed by punctuation, CODE is the punctuation and XV is null. */ - -#define PRINT_OPERAND(FILE, XV, CODE) \ -{ \ - switch (GET_CODE (XV)) \ - { \ - static char curreg[4]; \ - case REG: \ - if (CODE == 'N') \ - strcpy (curreg, reg_names[REGNO (XV) + 1]); \ - else \ - strcpy (curreg, reg_names[REGNO (XV)]); \ - fprintf (FILE, "%s", curreg); \ - break; \ - case MEM: \ - { \ - rtx addr = XEXP (XV, 0); \ - if (CODE == 'O') \ - { \ - if (GET_CODE (addr) == PLUS) \ - fprintf (FILE, HOST_WIDE_INT_PRINT_DEC, INTVAL (XEXP (addr, 1))); \ - else \ - fprintf (FILE, "0"); \ - } \ - else if (CODE == 'R') \ - { \ - if (GET_CODE (addr) == PLUS) \ - fprintf (FILE, "%s", reg_names[REGNO (XEXP (addr, 0))]);\ - else \ - fprintf (FILE, "%s", reg_names[REGNO (addr)]); \ - } \ - else \ - output_address (XEXP (XV, 0)); \ - } \ - break; \ - case SYMBOL_REF: \ - case LABEL_REF: \ - mvs_page_lit += 4; \ - if (SYMBOL_REF_EXTERNAL_P (XV)) fprintf (FILE, "=V("); \ - else fprintf (FILE, "=A("); \ - output_addr_const (FILE, XV); \ - fprintf (FILE, ")"); \ - break; \ - case CONST_INT: \ - if (CODE == 'B') \ - fprintf (FILE, "%d", (int) (INTVAL (XV) & 0xff)); \ - else if (CODE == 'X') \ - fprintf (FILE, "%02X", (int) (INTVAL (XV) & 0xff)); \ - else if (CODE == 'h') \ - fprintf (FILE, HOST_WIDE_INT_PRINT_DEC, (INTVAL (XV) << 16) >> 16); \ - else if (CODE == 'H') \ - { \ - mvs_page_lit += 2; \ - fprintf (FILE, "=H'" HOST_WIDE_INT_PRINT_DEC "'", \ - (INTVAL (XV) << 16) >> 16); \ - } \ - else if (CODE == 'K') \ - { \ - /* auto sign-extension of signed 16-bit to signed 32-bit */ \ - mvs_page_lit += 4; \ - fprintf (FILE, "=F'" HOST_WIDE_INT_PRINT_DEC "'", \ - (INTVAL (XV) << 16) >> 16); \ - } \ - else if (CODE == 'W') \ - { \ - /* hand-built sign-extension of signed 32-bit to 64-bit */ \ - mvs_page_lit += 8; \ - if (0 <= INTVAL (XV)) { \ - fprintf (FILE, "=XL8'00000000"); \ - } else { \ - fprintf (FILE, "=XL8'FFFFFFFF"); \ - } \ - fprintf (FILE, "%08X'", INTVAL (XV)); \ - } \ - else \ - { \ - mvs_page_lit += 4; \ - fprintf (FILE, "=F'" HOST_WIDE_INT_PRINT_DEC "'", INTVAL (XV)); \ - } \ - break; \ - case CONST_DOUBLE: \ - if (GET_MODE (XV) == DImode) \ - { \ - if (CODE == 'M') \ - { \ - mvs_page_lit += 4; \ - fprintf (FILE, "=XL4'%08X'", CONST_DOUBLE_LOW (XV)); \ - } \ - else if (CODE == 'L') \ - { \ - mvs_page_lit += 4; \ - fprintf (FILE, "=XL4'%08X'", CONST_DOUBLE_HIGH (XV)); \ - } \ - else \ - { \ - mvs_page_lit += 8; \ - fprintf (FILE, "=yyyyXL8'%08X%08X'", \ - CONST_DOUBLE_HIGH (XV), CONST_DOUBLE_LOW (XV)); \ - } \ - } \ - else \ - { \ - char buf[50]; \ - if (GET_MODE (XV) == SFmode) \ - { \ - mvs_page_lit += 4; \ - real_to_decimal (buf, CONST_DOUBLE_REAL_VALUE (XV), \ - sizeof (buf), 0, 1); \ - fprintf (FILE, "=E'%s'", buf); \ - } \ - else if (GET_MODE (XV) == DFmode) \ - { \ - mvs_page_lit += 8; \ - real_to_decimal (buf, CONST_DOUBLE_REAL_VALUE (XV), \ - sizeof (buf), 0, 1); \ - fprintf (FILE, "=D'%s'", buf); \ - } \ - else /* VOIDmode */ \ - { \ - mvs_page_lit += 8; \ - fprintf (FILE, "=XL8'%08X%08X'", \ - CONST_DOUBLE_HIGH (XV), CONST_DOUBLE_LOW (XV)); \ - } \ - } \ - break; \ - case CONST: \ - if (GET_CODE (XEXP (XV, 0)) == PLUS \ - && GET_CODE (XEXP (XEXP (XV, 0), 0)) == SYMBOL_REF) \ - { \ - mvs_page_lit += 4; \ - if (SYMBOL_REF_EXTERNAL_P (XEXP (XEXP (XV, 0), 0))) \ - { \ - fprintf (FILE, "=V("); \ - ASM_OUTPUT_LABELREF (FILE, \ - XSTR (XEXP (XEXP (XV, 0), 0), 0)); \ - fprintf (FILE, ")\n\tA\t%s,=F'" HOST_WIDE_INT_PRINT_DEC "'", \ - curreg, INTVAL (XEXP (XEXP (XV, 0), 1))); \ - } \ - else \ - { \ - fprintf (FILE, "=A("); \ - output_addr_const (FILE, XV); \ - fprintf (FILE, ")"); \ - } \ - } \ - else \ - { \ - mvs_page_lit += 4; \ - fprintf (FILE, "=bogus_bad_F'"); \ - output_addr_const (FILE, XV); \ - fprintf (FILE, "'"); \ -/* XXX hack alert this gets gen'd in -fPIC code in relation to a tablejump */ \ -/* but its somehow fundamentally broken, I can't make any sense out of it */ \ -debug_rtx (XV); \ -abort(); \ - } \ - break; \ - default: \ - abort(); \ - } \ -} - -#define PRINT_OPERAND_ADDRESS(FILE, ADDR) \ -{ \ - rtx breg, xreg, offset, plus; \ - \ - switch (GET_CODE (ADDR)) \ - { \ - case REG: \ - fprintf (FILE, "0(%s)", reg_names[REGNO (ADDR)]); \ - break; \ - case PLUS: \ - breg = 0; \ - xreg = 0; \ - offset = 0; \ - if (GET_CODE (XEXP (ADDR, 0)) == PLUS) \ - { \ - if (GET_CODE (XEXP (ADDR, 1)) == REG) \ - breg = XEXP (ADDR, 1); \ - else \ - offset = XEXP (ADDR, 1); \ - plus = XEXP (ADDR, 0); \ - } \ - else \ - { \ - if (GET_CODE (XEXP (ADDR, 0)) == REG) \ - breg = XEXP (ADDR, 0); \ - else \ - offset = XEXP (ADDR, 0); \ - plus = XEXP (ADDR, 1); \ - } \ - if (GET_CODE (plus) == PLUS) \ - { \ - if (GET_CODE (XEXP (plus, 0)) == REG) \ - { \ - if (breg) \ - xreg = XEXP (plus, 0); \ - else \ - breg = XEXP (plus, 0); \ - } \ - else \ - { \ - offset = XEXP (plus, 0); \ - } \ - if (GET_CODE (XEXP (plus, 1)) == REG) \ - { \ - if (breg) \ - xreg = XEXP (plus, 1); \ - else \ - breg = XEXP (plus, 1); \ - } \ - else \ - { \ - offset = XEXP (plus, 1); \ - } \ - } \ - else if (GET_CODE (plus) == REG) \ - { \ - if (breg) \ - xreg = plus; \ - else \ - breg = plus; \ - } \ - else \ - { \ - offset = plus; \ - } \ - if (offset) \ - { \ - if (GET_CODE (offset) == LABEL_REF) \ - fprintf (FILE, "L%d", \ - CODE_LABEL_NUMBER (XEXP (offset, 0))); \ - else \ - output_addr_const (FILE, offset); \ - } \ - else \ - fprintf (FILE, "0"); \ - if (xreg) \ - fprintf (FILE, "(%s,%s)", \ - reg_names[REGNO (xreg)], reg_names[REGNO (breg)]); \ - else \ - fprintf (FILE, "(%s)", reg_names[REGNO (breg)]); \ - break; \ - default: \ - mvs_page_lit += 4; \ - if (SYMBOL_REF_EXTERNAL_P (ADDR)) fprintf (FILE, "=V("); \ - else fprintf (FILE, "=A("); \ - output_addr_const (FILE, ADDR); \ - fprintf (FILE, ")"); \ - break; \ - } \ -} - -/* Output assembler code to FILE to increment profiler label # LABELNO - for profiling a function entry. */ -/* Make it a no-op for now, so we can at least compile glibc */ -#define FUNCTION_PROFILER(FILE, LABELNO) { \ - mvs_check_page (FILE, 24, 4); \ - fprintf (FILE, "\tSTM\tr1,r2,%d(sp)\n", STACK_POINTER_OFFSET-8); \ - fprintf (FILE, "\tLA\tr1,1(0,0)\n"); \ - fprintf (FILE, "\tL\tr2,=A(.LP%d)\n", LABELNO); \ - fprintf (FILE, "\tA\tr1,0(r2)\n"); \ - fprintf (FILE, "\tST\tr1,0(r2)\n"); \ - fprintf (FILE, "\tLM\tr1,r2,%d(sp)\n", STACK_POINTER_OFFSET-8); \ -} - -/* Don't bother to output .extern pseudo-ops. They are not needed by - ELF assemblers. */ - -#undef ASM_OUTPUT_EXTERNAL - -#define ASM_DOUBLE "\t.double" - -/* #define ASM_OUTPUT_LABELREF(FILE, NAME) */ /* use gas -- defaults.h */ - -/* let config/svr4.h define this ... - * #define ASM_OUTPUT_CASE_LABEL(FILE, PREFIX, NUM, TABLE) - * fprintf (FILE, "%s%d:\n", PREFIX, NUM) - */ - -/* This is how to output an element of a case-vector that is absolute. */ -#define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \ - mvs_check_page (FILE, 4, 0); \ - fprintf (FILE, "\t.long\t.L%d\n", VALUE) - -/* This is how to output an element of a case-vector that is relative. */ -#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) \ - mvs_check_page (FILE, 4, 0); \ - fprintf (FILE, "\t.long\t.L%d-.L%d\n", VALUE, REL) - -/* Right now, PUSH & POP are used only when profiling is enabled, - and then, only to push the static chain reg and the function struct - value reg, and only if those are used by the function being profiled. - We don't need this for profiling, so punt. */ -#define ASM_OUTPUT_REG_PUSH(FILE, REGNO) -#define ASM_OUTPUT_REG_POP(FILE, REGNO) - - -/* Indicate that jump tables go in the text section. This is - necessary when compiling PIC code. */ -#define JUMP_TABLES_IN_TEXT_SECTION 1 - -/* Define macro used to output shift-double opcodes when the shift - count is in %cl. Some assemblers require %cl as an argument; - some don't. - - GAS requires the %cl argument, so override i386/unix.h. */ - -#undef SHIFT_DOUBLE_OMITS_COUNT -#define SHIFT_DOUBLE_OMITS_COUNT 0 - -/* Implicit library calls should use memcpy, not bcopy, etc. */ -#define TARGET_MEM_FUNCTIONS - -/* Output before read-only data. */ -#define TEXT_SECTION_ASM_OP "\t.text" - -/* Output before writable (initialized) data. */ -#define DATA_SECTION_ASM_OP "\t.data" - -/* Output before writable (uninitialized) data. */ -#define BSS_SECTION_ASM_OP "\t.bss" - -/* In the past there was confusion as to what the argument to .align was - in GAS. For the last several years the rule has been this: for a.out - file formats that argument is LOG, and for all other file formats the - argument is 1<<LOG. - - However, GAS now has .p2align and .balign pseudo-ops so to remove any - doubt or guess work, and since this file is used for both a.out and other - file formats, we use one of them. */ - -#define ASM_OUTPUT_ALIGN(FILE,LOG) \ - if ((LOG)!=0) fprintf ((FILE), "\t.balign %d\n", 1<<(LOG)) - -/* Globalizing directive for a label. */ -#define GLOBAL_ASM_OP ".globl " - -/* This says how to output an assembler line - to define a global common symbol. */ - -#define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED) \ -( fputs (".comm ", (FILE)), \ - assemble_name ((FILE), (NAME)), \ - fprintf ((FILE), ","HOST_WIDE_INT_PRINT_UNSIGNED"\n", (ROUNDED))) - -/* This says how to output an assembler line - to define a local common symbol. */ - -#define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE, ROUNDED) \ -( fputs (".lcomm ", (FILE)), \ - assemble_name ((FILE), (NAME)), \ - fprintf ((FILE), ","HOST_WIDE_INT_PRINT_UNSIGNED"\n", (ROUNDED))) - -#endif /* TARGET_ELF_ABI */ -#endif /* ! GCC_I370_H */ diff --git a/gcc/config/i370/i370.md b/gcc/config/i370/i370.md deleted file mode 100644 index 342b6e8..0000000 --- a/gcc/config/i370/i370.md +++ /dev/null @@ -1,4739 +0,0 @@ -;;- Machine description for GNU compiler -- System/370 version. -;; Copyright (C) 1989, 1993, 1994, 1995, 1997, 1998, 1999, 2000, 2002 -;; Free Software Foundation, Inc. -;; Contributed by Jan Stein (jan@cd.chalmers.se). -;; Modified for OS/390 LanguageEnvironment C by Dave Pitts (dpitts@cozx.com) -;; Lots of Bug Fixes & Enhancements by Linas Vepstas (linas@linas.org) - -;; This file is part of GCC. - -;; GCC 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. - -;; GCC 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 GCC; see the file COPYING. If not, write to -;; the Free Software Foundation, 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. - -;; ======================================================================= -;; Condition codes for some of the instructions (in particular, for -;; add, sub, shift, abs, etc. are handled with the cpp macro NOTICE_UPDATE_CC -;; -;; Special constraints for 370 machine description: -;; -;; a -- Any address register from 1 to 15. -;; d -- Any register from 0 to 15. -;; I -- An 8-bit constant (0..255). -;; J -- A 12-bit constant (0..4095). -;; K -- A 16-bit constant (-32768..32767). -;; R -- a valid S operand in an RS, SI or SS instruction, or register -;; S -- a valid S operand in an RS, SI or SS instruction -;; -;; Note this well: -;; When defining an instruction, e.g. the movsi pattern: -;; -;; (define_insn "" -;; [(set (match_operand:SI 0 "r_or_s_operand" "=dm,d,dm") -;; (match_operand:SI 1 "r_or_s_operand" "diR,dim,*fF"))] -;; -;; The "r_or_s_operand" predicate is used to recognize the instruction; -;; however, it is not further used to enforce a constraint at later stages. -;; Thus, for example, although "r_or_s_operand" bars operands of the form -;; base+index+displacement, such operands can none-the-less show up during -;; post-instruction-recog processing: thus, for example, garbage like -;; MVC 152(4,r13),0(r5,r13) might be generated if both op0 and op1 are -;; mem operands. To avoid this, use the S constraint. -;; -;; -;; Special formats used for outputting 370 instructions. -;; -;; %B -- Print a constant byte integer. -;; %H -- Print a signed 16-bit constant. -;; %K -- Print a signed 16-bit constant signed-extended to 32-bits. -;; %L -- Print least significant word of a CONST_DOUBLE. -;; %M -- Print most significant word of a CONST_DOUBLE. -;; %N -- Print next register (second word of a DImode reg). -;; %O -- Print the offset of a memory reference (PLUS (REG) (CONST_INT)). -;; %R -- Print the register of a memory reference (PLUS (REG) (CONST_INT)). -;; %X -- Print a constant byte integer in hex. -;; %W -- Print a signed 32-bit int sign-extended to 64-bits. -;; -;; We have a special constraint for pattern matching. -;; -;; s_operand -- Matches a valid S operand in a RS, SI or SS type instruction. -;; -;; r_or_s_operand -- Matches a register or a valid S operand in a RS, SI -;; or SS type instruction or a register -;; -;; For MVS C/370 we use the following stack locations for: -;; -;; 136 - internal function result buffer -;; 140 - numeric conversion buffer -;; 144 - pointer to internal function result buffer -;; 148 - start of automatic variables and function arguments -;; -;; To support programs larger than a page, 4096 bytes, PAGE_REGISTER points -;; to a page origin table, all internal labels are generated to reload the -;; BASE_REGISTER knowing what page it is on and all branch instructions go -;; directly to the target if it is known that the target is on the current -;; page (essentially backward references). All forward references and off -;; page references are handled by loading the address of target into a -;; register and branching indirectly. -;; -;; Some *di patterns have been commented out per advice from RMS, as gcc -;; will generate the right things to do. -;; -;; See the note in i370.h about register 14, clobbering it, and optimization. -;; Basically, using clobber in egcs-1.1.1 will ruin ability to optimize around -;; branches, so don't do it. -;; -;; We use the "length" attirbute to store the max possible code size of an -;; insn. We use this length to estimate the length of forward branches, to -;; determine if they're on page or off. - -(define_attr "length" "" (const_int 0)) - -;; -;;- Test instructions. -;; - -; -; tstdi instruction pattern(s). -; - -(define_insn "tstdi" - [(set (cc0) - (match_operand:DI 0 "register_operand" "d"))] - "" - "* -{ - check_label_emit (); - mvs_check_page (0, 4, 0); - return \"SRDA %0,0\"; -}" - [(set_attr "length" "4")] -) - -; -; tstsi instruction pattern(s). -; - -(define_insn "tstsi" - [(set (cc0) - (match_operand:SI 0 "register_operand" "d"))] - "" - "* -{ - check_label_emit (); - mvs_check_page (0, 2, 0); - return \"LTR %0,%0\"; -}" - [(set_attr "length" "2")] -) - -; -; tsthi instruction pattern(s). -; - -(define_insn "tsthi" - [(set (cc0) - (match_operand:HI 0 "register_operand" "d"))] - "" - "* -{ - check_label_emit (); - mvs_check_page (0, 4, 2); - return \"CH %0,=H'0'\"; -}" - [(set_attr "length" "4")] -) - -; -; tstqi instruction pattern(s). -; - -(define_insn "" - [(set (cc0) - (match_operand:QI 0 "r_or_s_operand" "dm"))] - "unsigned_jump_follows_p (insn)" - "* -{ - check_label_emit (); - if (REG_P (operands[0])) - { - /* an unsigned compare to zero is always zero/not-zero... */ - mvs_check_page (0, 4, 4); - return \"N %0,=XL4'000000FF'\"; - } - mvs_check_page (0, 4, 0); - return \"CLI %0,0\"; -}" - [(set_attr "length" "4")] -) - -(define_insn "tstqi" - [(set (cc0) - (match_operand:QI 0 "register_operand" "d"))] - "" - "* -{ - check_label_emit (); - if (unsigned_jump_follows_p (insn)) - { - /* an unsigned compare to zero is always zero/not-zero... */ - mvs_check_page (0, 4, 4); - return \"N %0,=XL4'000000FF'\"; - } - mvs_check_page (0, 8, 0); - return \"SLL %0,24\;SRA %0,24\"; -}" - [(set_attr "length" "8")] -) - -; -; tstdf instruction pattern(s). -; - -(define_insn "tstdf" - [(set (cc0) - (match_operand:DF 0 "general_operand" "f"))] - "" - "* -{ - check_label_emit (); - mvs_check_page (0, 2, 0); - return \"LTDR %0,%0\"; -}" - [(set_attr "length" "2")] -) - -; -; tstsf instruction pattern(s). -; - -(define_insn "tstsf" - [(set (cc0) - (match_operand:SF 0 "general_operand" "f"))] - "" - "* -{ - check_label_emit (); - mvs_check_page (0, 2, 0); - return \"LTER %0,%0\"; -}" - [(set_attr "length" "2")] -) - -;; -;;- Compare instructions. -;; - -; -; cmpdi instruction pattern(s). -; - -;(define_insn "cmpdi" -; [(set (cc0) -; (compare (match_operand:DI 0 "register_operand" "d") -; (match_operand:DI 1 "general_operand" "")))] -; "" -; "* -;{ -; check_label_emit (); -; if (REG_P (operands[1])) -; { -; mvs_check_page (0, 8, 0); -; if (unsigned_jump_follows_p (insn)) -; return \"CLR %0,%1\;BNE *+6\;CLR %N0,%N1\"; -; return \"CR %0,%1\;BNE *+6\;CLR %N0,%N1\"; -; } -; mvs_check_page (0, 12, 0); -; if (unsigned_jump_follows_p (insn)) -; return \"CL %0,%M1\;BNE *+8\;CL %N0,%L1\"; -; return \"C %0,%M1\;BNE *+8\;CL %N0,%L1\"; -;}") - -; -; cmpsi instruction pattern(s). -; - -(define_insn "cmpsi" - [(set (cc0) - (compare (match_operand:SI 0 "register_operand" "d") - (match_operand:SI 1 "general_operand" "md")))] - "" - "* -{ - check_label_emit (); - if (REG_P (operands[1])) - { - mvs_check_page (0, 2, 0); - if (unsigned_jump_follows_p (insn)) - return \"CLR %0,%1\"; - return \"CR %0,%1\"; - } - if (GET_CODE (operands[1]) == CONST_INT) - { - mvs_check_page (0, 4, 4); - if (unsigned_jump_follows_p (insn)) - return \"CL %0,=F'%c1'\"; - return \"C %0,=F'%c1'\"; - } - mvs_check_page (0, 4, 0); - if (unsigned_jump_follows_p (insn)) - return \"CL %0,%1\"; - return \"C %0,%1\"; -}" - [(set_attr "length" "4")] -) - -; -; cmphi instruction pattern(s). -; - -; deprecate constraint d because it takes multiple instructions -; and a memeory access ... -(define_insn "cmphi" - [(set (cc0) - (compare (match_operand:HI 0 "register_operand" "d") - (match_operand:HI 1 "general_operand" "???dim")))] - "" - "* -{ - check_label_emit (); - if (REG_P (operands[1])) - { - mvs_check_page (0, 8, 0); - if (unsigned_jump_follows_p (insn)) - return \"STH %1,140(,13)\;CLM %0,3,140(13)\"; - return \"STH %1,140(,13)\;CH %0,140(,13)\"; - } - if (GET_CODE (operands[1]) == CONST_INT) - { - mvs_check_page (0, 4, 0); - return \"CH %0,%H1\"; - } - mvs_check_page (0, 4, 0); - return \"CH %0,%1\"; -}" - [(set_attr "length" "8")] -) - -; -; cmpqi instruction pattern(s). -; - -(define_insn "" - [(set (cc0) - (compare (match_operand:QI 0 "r_or_s_operand" "dS") - (match_operand:QI 1 "r_or_s_operand" "diS")))] - "unsigned_jump_follows_p (insn)" - "* -{ - check_label_emit (); - if (REG_P (operands[0])) - { - if (REG_P (operands[1])) - { - mvs_check_page (0, 8, 0); - return \"STC %1,140(,13)\;CLM %0,1,140(13)\"; - } - if (GET_CODE (operands[1]) == CONST_INT) - { - mvs_check_page (0, 4, 1); - return \"CLM %0,1,=XL1'%X1'\"; - } - mvs_check_page (0, 4, 0); - return \"CLM %0,1,%1\"; - } - else if (GET_CODE (operands[0]) == CONST_INT) - { - cc_status.flags |= CC_REVERSED; - if (REG_P (operands[1])) - { - mvs_check_page (0, 4, 1); - return \"CLM %1,1,=XL1'%X0'\"; - } - mvs_check_page (0, 4, 0); - return \"CLI %1,%B0\"; - } - if (GET_CODE (operands[1]) == CONST_INT) - { - mvs_check_page (0, 4, 0); - return \"CLI %0,%B1\"; - } - if (GET_CODE (operands[1]) == MEM) - { - mvs_check_page (0, 6, 0); - return \"CLC %O0(1,%R0),%1\"; - } - cc_status.flags |= CC_REVERSED; - mvs_check_page (0, 4, 0); - return \"CLM %1,1,%0\"; -}" - [(set_attr "length" "8")] -) - -(define_insn "cmpqi" - [(set (cc0) - (compare (match_operand:QI 0 "register_operand" "d") - (match_operand:QI 1 "general_operand" "di")))] - "" - "* -{ - check_label_emit (); - if (unsigned_jump_follows_p (insn)) - { - if (GET_CODE (operands[1]) == CONST_INT) - { - mvs_check_page (0, 4, 1); - return \"CLM %0,1,=XL1'%X1'\"; - } - if (!(REG_P (operands[1]))) - { - mvs_check_page (0, 4, 0); - return \"CLM %0,1,%1\"; - } - mvs_check_page (0, 8, 0); - return \"STC %1,140(,13)\;CLM %0,1,140(13)\"; - } - if (REG_P (operands[1])) - { - mvs_check_page (0, 18, 0); - return \"SLL %0,24\;SRA %0,24\;SLL %1,24\;SRA %1,24\;CR %0,%1\"; - } - mvs_check_page (0, 12, 0); - return \"SLL %0,24\;SRA %0,24\;C %0,%1\"; -}" - [(set_attr "length" "18")] -) - -; -; cmpdf instruction pattern(s). -; - -(define_insn "cmpdf" - [(set (cc0) - (compare (match_operand:DF 0 "general_operand" "f,mF") - (match_operand:DF 1 "general_operand" "fmF,f")))] - "" - "* -{ - check_label_emit (); - if (FP_REG_P (operands[0])) - { - if (FP_REG_P (operands[1])) - { - mvs_check_page (0, 2, 0); - return \"CDR %0,%1\"; - } - mvs_check_page (0, 4, 0); - return \"CD %0,%1\"; - } - cc_status.flags |= CC_REVERSED; - mvs_check_page (0, 4, 0); - return \"CD %1,%0\"; -}" - [(set_attr "length" "4")] -) - -; -; cmpsf instruction pattern(s). -; - -(define_insn "cmpsf" - [(set (cc0) - (compare (match_operand:SF 0 "general_operand" "f,mF") - (match_operand:SF 1 "general_operand" "fmF,f")))] - "" - "* -{ -check_label_emit (); - if (FP_REG_P (operands[0])) - { - if (FP_REG_P (operands[1])) - { - mvs_check_page (0, 2, 0); - return \"CER %0,%1\"; - } - mvs_check_page (0, 4, 0); - return \"CE %0,%1\"; - } - cc_status.flags |= CC_REVERSED; - mvs_check_page (0, 4, 0); - return \"CE %1,%0\"; -}" - [(set_attr "length" "4")] -) - -; -; cmpmemsi instruction pattern(s). -; - -(define_expand "cmpmemsi" - [(set (match_operand:SI 0 "general_operand" "") - (compare (match_operand:BLK 1 "general_operand" "") - (match_operand:BLK 2 "general_operand" ""))) - (use (match_operand:SI 3 "general_operand" "")) - (use (match_operand:SI 4 "" ""))] - "" - " -{ - rtx op1, op2; - - op1 = XEXP (operands[1], 0); - if (GET_CODE (op1) == REG - || (GET_CODE (op1) == PLUS && GET_CODE (XEXP (op1, 0)) == REG - && GET_CODE (XEXP (op1, 1)) == CONST_INT - && (unsigned) INTVAL (XEXP (op1, 1)) < 4096)) - { - op1 = operands[1]; - } - else - { - op1 = gen_rtx_MEM (BLKmode, copy_to_mode_reg (SImode, op1)); - } - - op2 = XEXP (operands[2], 0); - if (GET_CODE (op2) == REG - || (GET_CODE (op2) == PLUS && GET_CODE (XEXP (op2, 0)) == REG - && GET_CODE (XEXP (op2, 1)) == CONST_INT - && (unsigned) INTVAL (XEXP (op2, 1)) < 4096)) - { - op2 = operands[2]; - } - else - { - op2 = gen_rtx_MEM (BLKmode, copy_to_mode_reg (SImode, op2)); - } - - if (GET_CODE (operands[3]) == CONST_INT && INTVAL (operands[3]) < 256) - { - emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, - gen_rtx_SET (VOIDmode, operands[0], - gen_rtx_COMPARE (VOIDmode, op1, op2)), - gen_rtx_USE (VOIDmode, operands[3])))); - } - else - { - /* implementation suggested by Richard Henderson <rth@cygnus.com> */ - rtx reg1 = gen_reg_rtx (DImode); - rtx reg2 = gen_reg_rtx (DImode); - rtx result = operands[0]; - rtx mem1 = operands[1]; - rtx mem2 = operands[2]; - rtx len = operands[3]; - if (!CONSTANT_P (len)) - len = force_reg (SImode, len); - - /* Load up the address+length pairs. */ - emit_insn (gen_rtx_CLOBBER (VOIDmode, reg1)); - emit_move_insn (gen_rtx_SUBREG (SImode, reg1, 0), - force_operand (XEXP (mem1, 0), NULL_RTX)); - emit_move_insn (gen_rtx_SUBREG (SImode, reg1, GET_MODE_SIZE (SImode)), len); - - emit_insn (gen_rtx_CLOBBER (VOIDmode, reg2)); - emit_move_insn (gen_rtx_SUBREG (SImode, reg2, 0), - force_operand (XEXP (mem2, 0), NULL_RTX)); - emit_move_insn (gen_rtx_SUBREG (SImode, reg2, GET_MODE_SIZE (SImode)), len); - - /* Compare! */ - emit_insn (gen_cmpmemsi_1 (result, reg1, reg2)); - } - DONE; -}") - -; Compare a block that is less than 256 bytes in length. - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=d") - (compare (match_operand:BLK 1 "s_operand" "m") - (match_operand:BLK 2 "s_operand" "m"))) - (use (match_operand:QI 3 "immediate_operand" "I"))] - "((unsigned) INTVAL (operands[3]) < 256)" - "* -{ - check_label_emit (); - mvs_check_page (0, 22, 0); - return \"LA %0,%1\;CLC %O1(%c3,%R1),%2\;BH *+12\;BL *+6\;SLR %0,%0\;LNR %0,%0\"; -}" - [(set_attr "length" "22")] -) - -; Compare a block that is larger than 255 bytes in length. - -(define_insn "cmpmemsi_1" - [(set (match_operand:SI 0 "register_operand" "+d") - (compare - (mem:BLK (subreg:SI (match_operand:DI 1 "register_operand" "+d") 0)) - (mem:BLK (subreg:SI (match_operand:DI 2 "register_operand" "+d") 0)))) - (use (match_dup 1)) - (use (match_dup 2)) - (clobber (match_dup 1)) - (clobber (match_dup 2))] - "" - "* -{ - check_label_emit (); - mvs_check_page (0, 18, 0); - return \"LA %0,1(0,0)\;CLCL %1,%2\;BH *+12\;BL *+6\;SLR %0,%0\;LNR %0,%0\"; -}" - [(set_attr "length" "18")] -) - -;; -;;- Move instructions. -;; - -; -; movdi instruction pattern(s). -; - -(define_insn "" -;; [(set (match_operand:DI 0 "r_or_s_operand" "=dm") -;; (match_operand:DI 1 "r_or_s_operand" "dim*fF"))] - [(set (match_operand:DI 0 "r_or_s_operand" "=dS,m") - (match_operand:DI 1 "r_or_s_operand" "diS*fF,d*fF"))] - - "TARGET_CHAR_INSTRUCTIONS" - "* -{ - check_label_emit (); - if (REG_P (operands[0])) - { - if (FP_REG_P (operands[1])) - { - mvs_check_page (0, 8, 0); - return \"STD %1,140(,13)\;LM %0,%N0,140(13)\"; - } - if (REG_P (operands[1])) - { - mvs_check_page (0, 4, 0); - return \"LR %0,%1\;LR %N0,%N1\"; - } - if (operands[1] == const0_rtx) - { - CC_STATUS_INIT; - mvs_check_page (0, 4, 0); - return \"SLR %0,%0\;SLR %N0,%N0\"; - } - if (GET_CODE (operands[1]) == CONST_INT - && (unsigned) INTVAL (operands[1]) < 4096) - { - CC_STATUS_INIT; - mvs_check_page (0, 6, 0); - return \"SLR %0,%0\;LA %N0,%c1(0,0)\"; - } - if (GET_CODE (operands[1]) == CONST_INT) - { - CC_STATUS_SET (operands[0], operands[1]); - mvs_check_page (0, 8, 0); - return \"L %0,%1\;SRDA %0,32\"; - } - mvs_check_page (0, 4, 0); - return \"LM %0,%N0,%1\"; - } - else if (FP_REG_P (operands[1])) - { - mvs_check_page (0, 4, 0); - return \"STD %1,%0\"; - } - else if (REG_P (operands[1])) - { - mvs_check_page (0, 4, 0); - return \"STM %1,%N1,%0\"; - } - mvs_check_page (0, 6, 0); - return \"MVC %O0(8,%R0),%W1\"; -}" - [(set_attr "length" "8")] -) - -(define_insn "movdi" -;; [(set (match_operand:DI 0 "general_operand" "=d,dm") -;; (match_operand:DI 1 "general_operand" "dimF,*fd"))] - [(set (match_operand:DI 0 "general_operand" "=d,dm") - (match_operand:DI 1 "r_or_s_operand" "diSF,*fd"))] - "" - "* -{ - check_label_emit (); - if (REG_P (operands[0])) - { - if (FP_REG_P (operands[1])) - { - mvs_check_page (0, 8, 0); - return \"STD %1,140(,13)\;LM %0,%N0,140(13)\"; - } - if (REG_P (operands[1])) - { - mvs_check_page (0, 4, 0); - return \"LR %0,%1\;LR %N0,%N1\"; - } - if (operands[1] == const0_rtx) - { - CC_STATUS_INIT; - mvs_check_page (0, 4, 0); - return \"SLR %0,%0\;SLR %N0,%N0\"; - } - if (GET_CODE (operands[1]) == CONST_INT - && (unsigned) INTVAL (operands[1]) < 4096) - { - CC_STATUS_INIT; - mvs_check_page (0, 6, 0); - return \"SLR %0,%0\;LA %N0,%c1(0,0)\"; - } - if (GET_CODE (operands[1]) == CONST_INT) - { - CC_STATUS_SET (operands[0], operands[1]); - mvs_check_page (0, 8, 0); - return \"L %0,%1\;SRDA %0,32\"; - } - mvs_check_page (0, 4, 0); - return \"LM %0,%N0,%1\"; - } - else if (FP_REG_P (operands[1])) - { - mvs_check_page (0, 4, 0); - return \"STD %1,%0\"; - } - mvs_check_page (0, 4, 0); - return \"STM %1,%N1,%0\"; -}" - [(set_attr "length" "8")] -) - -;; we have got to provide a movdi alternative that will go from -;; register to memory & back in its full glory. However, we try to -;; discourage its use by listing this alternative last. -;; The problem is that the instructions above only provide -;; S-form style (base + displacement) mem access, while the -;; below provvides the full (base+index+displacement) RX-form. -;; These are rarely needed, but when needed they're needed. - -(define_insn "" - [(set (match_operand:DI 0 "general_operand" "=d,???m") - (match_operand:DI 1 "general_operand" "???m,d"))] - - "" - "* -{ - check_label_emit (); - if (REG_P (operands[0])) - { - mvs_check_page (0, 8, 0); - return \"LM %0,%N0,%1\"; - } - else if (REG_P (operands[1])) - { - mvs_check_page (0, 8, 0); - return \"STM %1,%N1,%0\"; - } - mvs_check_page (0, 6, 0); - return \"MVC %O0(8,%R0),%1\"; -}" - [(set_attr "length" "8")] -) - -; -; movsi instruction pattern(s). -; - -(define_insn "" -;; [(set (match_operand:SI 0 "r_or_s_operand" "=dm,d,dm") -;; (match_operand:SI 1 "r_or_s_operand" "diR,dim,*fF"))] - [(set (match_operand:SI 0 "r_or_s_operand" "=d,dS,dm") - (match_operand:SI 1 "general_operand" "dim,diS,di*fF"))] - - "TARGET_CHAR_INSTRUCTIONS" - "* -{ - check_label_emit (); - if (REG_P (operands[0])) - { - if (FP_REG_P (operands[1])) - { - mvs_check_page (0, 8, 0); - return \"STE %1,140(,13)\;L %0,140(,13)\"; - } - if (REG_P (operands[1])) - { - mvs_check_page (0, 2, 0); - return \"LR %0,%1\"; - } - if (operands[1] == const0_rtx) - { - CC_STATUS_INIT; - mvs_check_page (0, 2, 0); - return \"SLR %0,%0\"; - } - if (GET_CODE (operands[1]) == CONST_INT - && (unsigned) INTVAL (operands[1]) < 4096) - { - mvs_check_page (0, 4, 0); - return \"LA %0,%c1(0,0)\"; - } - mvs_check_page (0, 4, 0); - return \"L %0,%1\"; - } - else if (FP_REG_P (operands[1])) - { - mvs_check_page (0, 4, 0); - return \"STE %1,%0\"; - } - else if (REG_P (operands[1])) - { - mvs_check_page (0, 4, 0); - return \"ST %1,%0\"; - } - mvs_check_page (0, 6, 0); - return \"MVC %O0(4,%R0),%1\"; -}" - [(set_attr "length" "8")] -) - -(define_insn "movsi" - [(set (match_operand:SI 0 "general_operand" "=d,dm") - (match_operand:SI 1 "general_operand" "dimF,*fd"))] - "" - "* -{ - check_label_emit (); - if (REG_P (operands[0])) - { - if (FP_REG_P (operands[1])) - { - mvs_check_page (0, 8, 0); - return \"STE %1,140(,13)\;L %0,140(,13)\"; - } - if (REG_P (operands[1])) - { - mvs_check_page (0, 2, 0); - return \"LR %0,%1\"; - } - if (operands[1] == const0_rtx) - { - CC_STATUS_INIT; - mvs_check_page (0, 2, 0); - return \"SLR %0,%0\"; - } - if (GET_CODE (operands[1]) == CONST_INT - && (unsigned) INTVAL (operands[1]) < 4096) - { - mvs_check_page (0, 4, 0); - return \"LA %0,%c1(0,0)\"; - } - mvs_check_page (0, 4, 0); - return \"L %0,%1\"; - } - else if (FP_REG_P (operands[1])) - { - mvs_check_page (0, 4, 0); - return \"STE %1,%0\"; - } - mvs_check_page (0, 4, 0); - return \"ST %1,%0\"; -}" - [(set_attr "length" "8")] -) - -;(define_expand "movsi" -; [(set (match_operand:SI 0 "general_operand" "=d,dm") -; (match_operand:SI 1 "general_operand" "dimF,*fd"))] -; "" -; " -;{ -; rtx op0, op1; -; -; op0 = operands[0]; -; if (GET_CODE (op0) == CONST -; && GET_CODE (XEXP (XEXP (op0, 0), 0)) == SYMBOL_REF -; && SYMBOL_REF_EXTERNAL_P (XEXP (XEXP (op0, 0), 0))) -; { -; op0 = gen_rtx_MEM (SImode, copy_to_mode_reg (SImode, XEXP (op0, 0))); -; } -; -; op1 = operands[1]; -; if (GET_CODE (op1) == CONST -; && GET_CODE (XEXP (XEXP (op1, 0), 0)) == SYMBOL_REF -; && SYMBOL_REF_EXTERNAL_P (XEXP (XEXP (op1, 0), 0))) -; { -; op1 = gen_rtx_MEM (SImode, copy_to_mode_reg (SImode, XEXP (op1, 0))); -; } -; -; emit_insn (gen_rtx_SET (VOIDmode, op0, op1)); -; DONE; -;}") - -; -; movhi instruction pattern(s). -; - -(define_insn "" - [(set (match_operand:HI 0 "r_or_s_operand" "=g") - (match_operand:HI 1 "r_or_s_operand" "g"))] - "TARGET_CHAR_INSTRUCTIONS" - "* -{ - check_label_emit (); - if (REG_P (operands[0])) - { - if (REG_P (operands[1])) - { - mvs_check_page (0, 2, 0); - return \"LR %0,%1\"; - } - if (operands[1] == const0_rtx) - { - CC_STATUS_INIT; - mvs_check_page (0, 2, 0); - return \"SLR %0,%0\"; - } - if (GET_CODE (operands[1]) == CONST_INT - && (unsigned) INTVAL (operands[1]) < 4096) - { - mvs_check_page (0, 4, 0); - return \"LA %0,%c1(0,0)\"; - } - if (GET_CODE (operands[1]) == CONST_INT) - { - mvs_check_page (0, 4, 0); - return \"LH %0,%H1\"; - } - mvs_check_page (0, 4, 0); - return \"LH %0,%1\"; - } - else if (REG_P (operands[1])) - { - mvs_check_page (0, 4, 0); - return \"STH %1,%0\"; - } - if (GET_CODE (operands[1]) == CONST_INT) - { - mvs_check_page (0, 6, 0); - return \"MVC %O0(2,%R0),%H1\"; - } - mvs_check_page (0, 6, 0); - return \"MVC %O0(2,%R0),%1\"; -}" - [(set_attr "length" "6")] -) - -(define_insn "movhi" - [(set (match_operand:HI 0 "general_operand" "=d,m") - (match_operand:HI 1 "general_operand" "g,d"))] - "" - "* -{ - check_label_emit (); - if (REG_P (operands[0])) - { - if (REG_P (operands[1])) - { - mvs_check_page (0, 2, 0); - return \"LR %0,%1\"; - } - if (operands[1] == const0_rtx) - { - CC_STATUS_INIT; - mvs_check_page (0, 2, 0); - return \"SLR %0,%0\"; - } - if (GET_CODE (operands[1]) == CONST_INT - && (unsigned) INTVAL (operands[1]) < 4096) - { - mvs_check_page (0, 4, 0); - return \"LA %0,%c1(0,0)\"; - } - if (GET_CODE (operands[1]) == CONST_INT) - { - mvs_check_page (0, 4, 0); - return \"LH %0,%H1\"; - } - mvs_check_page (0, 4, 0); - return \"LH %0,%1\"; - } - mvs_check_page (0, 4, 0); - return \"STH %1,%0\"; -}" - [(set_attr "length" "4")] -) - -; -; movqi instruction pattern(s). -; - -(define_insn "" - [(set (match_operand:QI 0 "r_or_s_operand" "=g") - (match_operand:QI 1 "r_or_s_operand" "g"))] - "TARGET_CHAR_INSTRUCTIONS" - "* -{ - check_label_emit (); - if (REG_P (operands[0])) - { - if (REG_P (operands[1])) - { - mvs_check_page (0, 2, 0); - return \"LR %0,%1\"; - } - if (operands[1] == const0_rtx) - { - CC_STATUS_INIT; - mvs_check_page (0, 2, 0); - return \"SLR %0,%0\"; - } - if (GET_CODE (operands[1]) == CONST_INT) - { - if ((INTVAL (operands[1]) >= 0) - && (unsigned) INTVAL (operands[1]) < 4096) - { - mvs_check_page (0, 4, 0); - return \"LA %0,%c1(0,0)\"; - } - mvs_check_page (0, 4, 0); - return \"L %0,=F'%c1'\"; - } - mvs_check_page (0, 4, 0); - return \"IC %0,%1\"; - } - else if (REG_P (operands[1])) - { - mvs_check_page (0, 4, 0); - return \"STC %1,%0\"; - } - else if (GET_CODE (operands[1]) == CONST_INT) - { - mvs_check_page (0, 4, 0); - return \"MVI %0,%B1\"; - } - mvs_check_page (0, 6, 0); - return \"MVC %O0(1,%R0),%1\"; -}" - [(set_attr "length" "6")] -) - -(define_insn "movqi" - [(set (match_operand:QI 0 "general_operand" "=d,m") - (match_operand:QI 1 "general_operand" "g,d"))] - "" - "* -{ - check_label_emit (); - if (REG_P (operands[0])) - { - if (REG_P (operands[1])) - { - mvs_check_page (0, 2, 0); - return \"LR %0,%1\"; - } - if (operands[1] == const0_rtx) - { - CC_STATUS_INIT; - mvs_check_page (0, 2, 0); - return \"SLR %0,%0\"; - } - if (GET_CODE (operands[1]) == CONST_INT) - { - if ((INTVAL (operands[1]) >= 0) - && (unsigned) INTVAL (operands[1]) < 4096) - { - mvs_check_page (0, 4, 0); - return \"LA %0,%c1(0,0)\"; - } - mvs_check_page (0, 4, 0); - return \"L %0,=F'%c1'\"; - } - mvs_check_page (0, 4, 0); - return \"IC %0,%1\"; - } - mvs_check_page (0, 4, 0); - return \"STC %1,%0\"; -}" - [(set_attr "length" "4")] -) - -; -; movstrictqi instruction pattern(s). -; - -(define_insn "movstrictqi" - [(set (strict_low_part (match_operand:QI 0 "general_operand" "+d")) - (match_operand:QI 1 "general_operand" "g"))] - "" - "* -{ - check_label_emit (); - if (REG_P (operands[1])) - { - mvs_check_page (0, 8, 0); - return \"STC %1,140(,13)\;IC %0,140(,13)\"; - } - mvs_check_page (0, 4, 0); - return \"IC %0,%1\"; -}" - [(set_attr "length" "8")] -) - -; -; movstricthi instruction pattern(s). -; - -(define_insn "" - [(set (strict_low_part (match_operand:HI 0 "register_operand" "+d")) - (match_operand:HI 1 "r_or_s_operand" "g"))] - "" - "* -{ - check_label_emit (); - if (REG_P (operands[1])) - { - mvs_check_page (0, 8, 0); - return \"STH %1,140(,13)\;ICM %0,3,140(13)\"; - } - else if (GET_CODE (operands[1]) == CONST_INT) - { - mvs_check_page (0, 4, 0); - return \"ICM %0,3,%H1\"; - } - mvs_check_page (0, 4, 0); - return \"ICM %0,3,%1\"; -}" - [(set_attr "length" "8")] -) - -(define_insn "movstricthi" - [(set (strict_low_part (match_operand:HI 0 "general_operand" "+dm")) - (match_operand:HI 1 "general_operand" "d"))] - "" - "* -{ - check_label_emit (); - if (REG_P (operands[0])) - { - mvs_check_page (0, 8, 0); - return \"STH %1,140(,13)\;ICM %0,3,140(13)\"; - } - mvs_check_page (0, 4, 0); - return \"STH %1,%0\"; -}" - [(set_attr "length" "8")] -) - -; -; movdf instruction pattern(s). -; - -(define_insn "" -;; [(set (match_operand:DF 0 "r_or_s_operand" "=fm,fm,*dm") -;; (match_operand:DF 1 "r_or_s_operand" "fmF,*dm,fmF"))] - [(set (match_operand:DF 0 "general_operand" "=f,m,fS,*dS,???d") - (match_operand:DF 1 "general_operand" "fmF,fF,*dS,fSF,???d"))] - - "TARGET_CHAR_INSTRUCTIONS" - "* -{ - check_label_emit (); - if (FP_REG_P (operands[0])) - { - if (FP_REG_P (operands[1])) - { - mvs_check_page (0, 2, 0); - return \"LDR %0,%1\"; - } - if (REG_P (operands[1])) - { - mvs_check_page (0, 8, 0); - return \"STM %1,%N1,140(13)\;LD %0,140(,13)\"; - } - if (operands[1] == const0_rtx) - { - CC_STATUS_SET (operands[0], operands[1]); - mvs_check_page (0, 2, 0); - return \"SDR %0,%0\"; - } - mvs_check_page (0, 4, 0); - return \"LD %0,%1\"; - } - if (REG_P (operands[0])) - { - if (FP_REG_P (operands[1])) - { - mvs_check_page (0, 12, 0); - return \"STD %1,140(,13)\;LM %0,%N0,140(13)\"; - } - if (REG_P (operands[1])) - { - mvs_check_page (0, 4, 0); - return \"LR %0,%1\;LR %N0,%N1\"; - } - mvs_check_page (0, 4, 0); - return \"LM %0,%N0,%1\"; - } - else if (FP_REG_P (operands[1])) - { - mvs_check_page (0, 4, 0); - return \"STD %1,%0\"; - } - else if (REG_P (operands[1])) - { - mvs_check_page (0, 4, 0); - return \"STM %1,%N1,%0\"; - } - mvs_check_page (0, 6, 0); - return \"MVC %O0(8,%R0),%1\"; -}" - [(set_attr "length" "12")] -) - -(define_insn "movdf" -;; [(set (match_operand:DF 0 "general_operand" "=f,fm,m,*d") -;; (match_operand:DF 1 "general_operand" "fmF,*d,f,fmF"))] - [(set (match_operand:DF 0 "general_operand" "=f,m,fS,*d,???d") - (match_operand:DF 1 "general_operand" "fmF,f,*d,SfF,???d"))] - - "" - "* -{ - check_label_emit (); - if (FP_REG_P (operands[0])) - { - if (FP_REG_P (operands[1])) - { - mvs_check_page (0, 2, 0); - return \"LDR %0,%1\"; - } - if (REG_P (operands[1])) - { - mvs_check_page (0, 8, 0); - return \"STM %1,%N1,140(13)\;LD %0,140(,13)\"; - } - if (operands[1] == const0_rtx) - { - CC_STATUS_SET (operands[0], operands[1]); - mvs_check_page (0, 2, 0); - return \"SDR %0,%0\"; - } - mvs_check_page (0, 4, 0); - return \"LD %0,%1\"; - } - else if (REG_P (operands[0])) - { - if (FP_REG_P (operands[1])) - { - mvs_check_page (0, 12, 0); - return \"STD %1,140(,13)\;LM %0,%N0,140(13)\"; - } - if (REG_P (operands[1])) - { - mvs_check_page (0, 4, 0); - return \"LR %0,%1\;LR %N0,%N1\"; - } - mvs_check_page (0, 4, 0); - return \"LM %0,%N0,%1\"; - } - else if (FP_REG_P (operands[1])) - { - mvs_check_page (0, 4, 0); - return \"STD %1,%0\"; - } - mvs_check_page (0, 4, 0); - return \"STM %1,%N1,%0\"; -}" - [(set_attr "length" "12")] -) - -; -; movsf instruction pattern(s). -; - -(define_insn "" -;; [(set (match_operand:SF 0 "r_or_s_operand" "=fm,fm,*dm") -;; (match_operand:SF 1 "r_or_s_operand" "fmF,*dm,fmF"))] -;; [(set (match_operand:SF 0 "general_operand" "=f,m,fm,*d,S") -;; (match_operand:SF 1 "general_operand" "fmF,fF,*d,fmF,S"))] - [(set (match_operand:SF 0 "general_operand" "=f*d,fm,S,???d") - (match_operand:SF 1 "general_operand" "fmF,fF*d,S,???d"))] - - "TARGET_CHAR_INSTRUCTIONS" - "* -{ - check_label_emit (); - if (FP_REG_P (operands[0])) - { - if (FP_REG_P (operands[1])) - { - mvs_check_page (0, 2, 0); - return \"LER %0,%1\"; - } - if (REG_P (operands[1])) - { - mvs_check_page (0, 8, 0); - return \"ST %1,140(,13)\;LE %0,140(,13)\"; - } - if (operands[1] == const0_rtx) - { - CC_STATUS_SET (operands[0], operands[1]); - mvs_check_page (0, 2, 0); - return \"SER %0,%0\"; - } - mvs_check_page (0, 4, 0); - return \"LE %0,%1\"; - } - else if (REG_P (operands[0])) - { - if (FP_REG_P (operands[1])) - { - mvs_check_page (0, 8, 0); - return \"STE %1,140(,13)\;L %0,140(,13)\"; - } - if (REG_P (operands[1])) - { - mvs_check_page (0, 2, 0); - return \"LR %0,%1\"; - } - mvs_check_page (0, 4, 0); - return \"L %0,%1\"; - } - else if (FP_REG_P (operands[1])) - { - mvs_check_page (0, 4, 0); - return \"STE %1,%0\"; - } - else if (REG_P (operands[1])) - { - mvs_check_page (0, 4, 0); - return \"ST %1,%0\"; - } - mvs_check_page (0, 6, 0); - return \"MVC %O0(4,%R0),%1\"; -}" - [(set_attr "length" "8")] -) - -(define_insn "movsf" - [(set (match_operand:SF 0 "general_operand" "=f,fm,m,*d") - (match_operand:SF 1 "general_operand" "fmF,*d,f,fmF"))] - "" - "* -{ - check_label_emit (); - if (FP_REG_P (operands[0])) - { - if (FP_REG_P (operands[1])) - { - mvs_check_page (0, 2, 0); - return \"LER %0,%1\"; - } - if (REG_P (operands[1])) - { - mvs_check_page (0, 8, 0); - return \"ST %1,140(,13)\;LE %0,140(,13)\"; - } - if (operands[1] == const0_rtx) - { - CC_STATUS_SET (operands[0], operands[1]); - mvs_check_page (0, 2, 0); - return \"SER %0,%0\"; - } - mvs_check_page (0, 4, 0); - return \"LE %0,%1\"; - } - else if (REG_P (operands[0])) - { - if (FP_REG_P (operands[1])) - { - mvs_check_page (0, 8, 0); - return \"STE %1,140(,13)\;L %0,140(,13)\"; - } - mvs_check_page (0, 4, 0); - return \"L %0,%1\"; - } - else if (FP_REG_P (operands[1])) - { - mvs_check_page (0, 4, 0); - return \"STE %1,%0\"; - } - mvs_check_page (0, 4, 0); - return \"ST %1,%0\"; -}" - [(set_attr "length" "8")] -) - -; -; clrstrsi instruction pattern(s). -; memset a block of bytes to zero. -; block must be less than 16M (24 bits) in length -; -(define_expand "clrstrsi" - [(set (match_operand:BLK 0 "general_operand" "g") - (const_int 0)) - (use (match_operand:SI 1 "general_operand" "")) - (match_operand 2 "" "")] - "" - " -{ - { - /* implementation suggested by Richard Henderson <rth@cygnus.com> */ - rtx reg1 = gen_reg_rtx (DImode); - rtx reg2 = gen_reg_rtx (DImode); - rtx mem1 = operands[0]; - rtx zippo = gen_rtx_CONST_INT (SImode, 0); - rtx len = operands[1]; - if (!CONSTANT_P (len)) - len = force_reg (SImode, len); - - /* Load up the address+length pairs. */ - emit_insn (gen_rtx_CLOBBER (VOIDmode, reg1)); - emit_move_insn (gen_rtx_SUBREG (SImode, reg1, 0), - force_operand (XEXP (mem1, 0), NULL_RTX)); - emit_move_insn (gen_rtx_SUBREG (SImode, reg1, GET_MODE_SIZE (SImode)), len); - - emit_insn (gen_rtx_CLOBBER (VOIDmode, reg2)); - emit_move_insn (gen_rtx_SUBREG (SImode, reg2, 0), zippo); - emit_move_insn (gen_rtx_SUBREG (SImode, reg2, GET_MODE_SIZE (SImode)), zippo); - - /* Copy! */ - emit_insn (gen_movstrsi_1 (reg1, reg2)); - } - DONE; -}") - -; -; movstrsi instruction pattern(s). -; block must be less than 16M (24 bits) in length - -(define_expand "movstrsi" - [(set (match_operand:BLK 0 "general_operand" "") - (match_operand:BLK 1 "general_operand" "")) - (use (match_operand:SI 2 "general_operand" "")) - (match_operand 3 "" "")] - "" - " -{ - rtx op0, op1; - - op0 = XEXP (operands[0], 0); - if (GET_CODE (op0) == REG - || (GET_CODE (op0) == PLUS && GET_CODE (XEXP (op0, 0)) == REG - && GET_CODE (XEXP (op0, 1)) == CONST_INT - && (unsigned) INTVAL (XEXP (op0, 1)) < 4096)) - op0 = operands[0]; - else - op0 = replace_equiv_address (operands[0], copy_to_mode_reg (SImode, op0)); - - op1 = XEXP (operands[1], 0); - if (GET_CODE (op1) == REG - || (GET_CODE (op1) == PLUS && GET_CODE (XEXP (op1, 0)) == REG - && GET_CODE (XEXP (op1, 1)) == CONST_INT - && (unsigned) INTVAL (XEXP (op1, 1)) < 4096)) - op1 = operands[1]; - else - op1 = replace_equiv_address (operands[1], copy_to_mode_reg (SImode, op1)); - - if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 256) - emit_insn (gen_rtx_PARALLEL (VOIDmode, - gen_rtvec (2, - gen_rtx_SET (VOIDmode, op0, op1), - gen_rtx_USE (VOIDmode, operands[2])))); - - else - { - /* implementation provided by Richard Henderson <rth@cygnus.com> */ - rtx reg1 = gen_reg_rtx (DImode); - rtx reg2 = gen_reg_rtx (DImode); - rtx mem1 = operands[0]; - rtx mem2 = operands[1]; - rtx len = operands[2]; - if (!CONSTANT_P (len)) - len = force_reg (SImode, len); - - /* Load up the address+length pairs. */ - emit_insn (gen_rtx_CLOBBER (VOIDmode, reg1)); - emit_move_insn (gen_rtx_SUBREG (SImode, reg1, 0), - force_operand (XEXP (mem1, 0), NULL_RTX)); - emit_move_insn (gen_rtx_SUBREG (SImode, reg1, GET_MODE_SIZE (SImode)), len); - - emit_insn (gen_rtx_CLOBBER (VOIDmode, reg2)); - emit_move_insn (gen_rtx_SUBREG (SImode, reg2, 0), - force_operand (XEXP (mem2, 0), NULL_RTX)); - emit_move_insn (gen_rtx_SUBREG (SImode, reg2, GET_MODE_SIZE (SImode)), len); - - /* Copy! */ - emit_insn (gen_movstrsi_1 (reg1, reg2)); - } - DONE; -}") - -; Move a block that is less than 256 bytes in length. - -(define_insn "" - [(set (match_operand:BLK 0 "s_operand" "=m") - (match_operand:BLK 1 "s_operand" "m")) - (use (match_operand 2 "immediate_operand" "I"))] - "((unsigned) INTVAL (operands[2]) < 256)" - "* -{ - check_label_emit (); - mvs_check_page (0, 6, 0); - return \"MVC %O0(%c2,%R0),%1\"; -}" - [(set_attr "length" "6")] -) - -; Move a block that is larger than 255 bytes in length. - -(define_insn "movstrsi_1" - [(set (mem:BLK (subreg:SI (match_operand:DI 0 "register_operand" "+d") 0)) - (mem:BLK (subreg:SI (match_operand:DI 1 "register_operand" "+d") 0))) - (use (match_dup 0)) - (use (match_dup 1)) - (clobber (match_dup 0)) - (clobber (match_dup 1))] - "" - "* -{ - check_label_emit (); - mvs_check_page (0, 2, 0); - return \"MVCL %0,%1\"; -}" - [(set_attr "length" "2")] -) - -;; -;;- Conversion instructions. -;; - -; -; extendsidi2 instruction pattern(s). -; - -(define_expand "extendsidi2" - [(set (match_operand:DI 0 "register_operand" "=d") - (sign_extend:DI (match_operand:SI 1 "general_operand" "")))] - "" - " -{ - if (GET_CODE (operands[1]) != CONST_INT) - { - emit_insn (gen_rtx_SET (VOIDmode, - operand_subword (operands[0], 0, 1, DImode), operands[1])); - emit_insn (gen_rtx_SET (VOIDmode, operands[0], - gen_rtx_ASHIFTRT (DImode, operands[0], - gen_rtx_CONST_INT (SImode, 32)))); - } - else - { - if (INTVAL (operands[1]) < 0) - { - emit_insn (gen_rtx_SET (VOIDmode, - operand_subword (operands[0], 0, 1, DImode), - gen_rtx_CONST_INT (SImode, -1))); - } - else - { - emit_insn (gen_rtx_SET (VOIDmode, - operand_subword (operands[0], 0, 1, DImode), - gen_rtx_CONST_INT (SImode, 0))); - } - emit_insn (gen_rtx_SET (VOIDmode, gen_lowpart (SImode, operands[0]), - operands[1])); - } - DONE; -}") - -; -; extendhisi2 instruction pattern(s). -; - -(define_insn "extendhisi2" - [(set (match_operand:SI 0 "general_operand" "=d,m") - (sign_extend:SI (match_operand:HI 1 "general_operand" "g,d")))] - "" - "* -{ - check_label_emit (); - if (REG_P (operands[0])) - { - if (REG_P (operands[1])) - { - if (REGNO (operands[0]) != REGNO (operands[1])) - { - mvs_check_page (0, 10, 0); - return \"LR %0,%1\;SLL %0,16\;SRA %0,16\"; - } - else - return \"\"; /* Should be empty. 16-bits regs are always 32-bits. */ - } - if (operands[1] == const0_rtx) - { - CC_STATUS_INIT; - mvs_check_page (0, 2, 0); - return \"SLR %0,%0\"; - } - if (GET_CODE (operands[1]) == CONST_INT - && (unsigned) INTVAL (operands[1]) < 4096) - { - mvs_check_page (0, 4, 0); - return \"LA %0,%c1(0,0)\"; - } - if (GET_CODE (operands[1]) == CONST_INT) - { - mvs_check_page (0, 4, 0); - return \"LH %0,%H1\"; - } - mvs_check_page (0, 4, 0); - return \"LH %0,%1\"; - } - mvs_check_page (0, 12, 0); - return \"SLL %1,16\;SRA %1,16\;ST %1,%0\"; -}" - [(set_attr "length" "12")] -) - -; -; extendqisi2 instruction pattern(s). -; - -(define_insn "extendqisi2" - [(set (match_operand:SI 0 "general_operand" "=d") - (sign_extend:SI (match_operand:QI 1 "general_operand" "0mi")))] - "" - "* -{ - check_label_emit (); - CC_STATUS_SET (operands[0], operands[1]); - if (REG_P (operands[1])) - { - mvs_check_page (0, 8, 0); - return \"SLL %0,24\;SRA %0,24\"; - } - if (s_operand (operands[1], GET_MODE (operands[1]))) - { - mvs_check_page (0, 8, 0); - return \"ICM %0,8,%1\;SRA %0,24\"; - } - mvs_check_page (0, 12, 0); - return \"IC %0,%1\;SLL %0,24\;SRA %0,24\"; -}" - [(set_attr "length" "12")] -) - -; -; extendqihi2 instruction pattern(s). -; - -(define_insn "extendqihi2" - [(set (match_operand:HI 0 "general_operand" "=d") - (sign_extend:HI (match_operand:QI 1 "general_operand" "0m")))] - "" - "* -{ - check_label_emit (); - CC_STATUS_SET (operands[0], operands[1]); - if (REG_P (operands[1])) - { - mvs_check_page (0, 8, 0); - return \"SLL %0,24\;SRA %0,24\"; - } - if (s_operand (operands[1], GET_MODE (operands[1]))) - { - mvs_check_page (0, 8, 0); - return \"ICM %0,8,%1\;SRA %0,24\"; - } - mvs_check_page (0, 12, 0); - return \"IC %0,%1\;SLL %0,24\;SRA %0,24\"; -}" - [(set_attr "length" "12")] -) - -; -; zero_extendsidi2 instruction pattern(s). -; - -(define_expand "zero_extendsidi2" - [(set (match_operand:DI 0 "register_operand" "=d") - (zero_extend:DI (match_operand:SI 1 "general_operand" "")))] - "" - " -{ - emit_insn (gen_rtx_SET (VOIDmode, - operand_subword (operands[0], 0, 1, DImode), operands[1])); - emit_insn (gen_rtx_SET (VOIDmode, operands[0], - gen_rtx_LSHIFTRT (DImode, operands[0], - gen_rtx_CONST_INT (SImode, 32)))); - DONE; -}") - -; -; zero_extendhisi2 instruction pattern(s). -; - -(define_insn "zero_extendhisi2" - [(set (match_operand:SI 0 "general_operand" "=d") - (zero_extend:SI (match_operand:HI 1 "general_operand" "0")))] - "" - "* -{ - check_label_emit (); - /* AND only sets zero/not-zero bits not the arithmetic bits ... */ - CC_STATUS_INIT; - mvs_check_page (0, 4, 4); - return \"N %1,=XL4'0000FFFF'\"; -}" - [(set_attr "length" "4")] -) - -; -; zero_extendqisi2 instruction pattern(s). -; - -(define_insn "zero_extendqisi2" - [(set (match_operand:SI 0 "general_operand" "=d,&d") - (zero_extend:SI (match_operand:QI 1 "general_operand" "0i,m")))] - "" - "* -{ - check_label_emit (); - if (REG_P (operands[1])) - { - /* AND only sets zero/not-zero bits not the arithmetic bits ... */ - CC_STATUS_INIT; - mvs_check_page (0, 4, 4); - return \"N %0,=XL4'000000FF'\"; - } - if (GET_CODE (operands[1]) == CONST_INT) - { - mvs_check_page (0, 4, 0); - return \"LA %0,%c1(0,0)\"; - } - CC_STATUS_INIT; - mvs_check_page (0, 8, 0); - return \"SLR %0,%0\;IC %0,%1\"; -}" - [(set_attr "length" "8")] -) - -; -; zero_extendqihi2 instruction pattern(s). -; - -(define_insn "zero_extendqihi2" - [(set (match_operand:HI 0 "general_operand" "=d,&d") - (zero_extend:HI (match_operand:QI 1 "general_operand" "0i,m")))] - "" - "* -{ - check_label_emit (); - if (REG_P (operands[1])) - { - /* AND only sets zero/not-zero bits not the arithmetic bits ... */ - CC_STATUS_INIT; - mvs_check_page (0, 4, 4); - return \"N %0,=XL4'000000FF'\"; - } - if (GET_CODE (operands[1]) == CONST_INT) - { - mvs_check_page (0, 4, 0); - return \"LA %0,%c1(0,0)\"; - } - CC_STATUS_INIT; - mvs_check_page (0, 8, 0); - return \"SLR %0,%0\;IC %0,%1\"; -}" - [(set_attr "length" "8")] -) - -; -; truncsihi2 instruction pattern(s). -; - -(define_insn "truncsihi2" - [(set (match_operand:HI 0 "general_operand" "=d,m") - (truncate:HI (match_operand:SI 1 "general_operand" "0,d")))] - "" - "* -{ - check_label_emit (); - if (REG_P (operands[0])) - { - CC_STATUS_SET (operands[0], operands[1]); - mvs_check_page (0, 8, 0); - return \"SLL %0,16\;SRA %0,16\"; - } - mvs_check_page (0, 4, 0); - return \"STH %1,%0\"; -}" - [(set_attr "length" "8")] -) - -; -; fix_truncdfsi2 instruction pattern(s). -; - -(define_insn "fix_truncdfsi2" - [(set (match_operand:SI 0 "general_operand" "=d") - (fix:SI (truncate:DF (match_operand:DF 1 "general_operand" "+f")))) - (clobber (reg:DF 16))] - "" - "* -{ - check_label_emit (); - CC_STATUS_INIT; - if (REGNO (operands[1]) == 16) - { - mvs_check_page (0, 12, 8); - return \"AD 0,=XL8'4F08000000000000'\;STD 0,140(,13)\;L %0,144(,13)\"; - } - mvs_check_page (0, 14, 8); - return \"LDR 0,%1\;AD 0,=XL8'4F08000000000000'\;STD 0,140(,13)\;L %0,144(,13)\"; -}" - [(set_attr "length" "14")] -) - -; -; floatsidf2 instruction pattern(s). -; -; LE/370 mode uses the float field of the TCA. -; - -(define_insn "floatsidf2" - [(set (match_operand:DF 0 "general_operand" "=f") - (float:DF (match_operand:SI 1 "general_operand" "d")))] - "" - "* -{ - check_label_emit (); - CC_STATUS_INIT; -#ifdef TARGET_ELF_ABI - mvs_check_page (0, 22, 12); - return \"MVC 140(4,13),=XL4'4E000000'\;ST %1,144(,13)\;XI 144(13),128\;LD %0,140(,13)\;SD %0,=XL8'4E00000080000000'\"; -#else - mvs_check_page (0, 16, 8); - return \"ST %1,508(,12)\;XI 508(12),128\;LD %0,504(,12)\;SD %0,=XL8'4E00000080000000'\"; -#endif -}" - [(set_attr "length" "22")] -) - -; -; truncdfsf2 instruction pattern(s). -; - -(define_insn "truncdfsf2" - [(set (match_operand:SF 0 "general_operand" "=f") - (float_truncate:SF (match_operand:DF 1 "general_operand" "f")))] - "" - "* -{ - check_label_emit (); - mvs_check_page (0, 2, 0); - return \"LRER %0,%1\"; -}" - [(set_attr "length" "2")] -) - -; -; extendsfdf2 instruction pattern(s). -; - -(define_insn "extendsfdf2" - [(set (match_operand:DF 0 "general_operand" "=f") - (float_extend:DF (match_operand:SF 1 "general_operand" "fmF")))] - "" - "* -{ - check_label_emit (); - CC_STATUS_SET (0, const0_rtx); - if (FP_REG_P (operands[1])) - { - if (REGNO (operands[0]) == REGNO (operands[1])) - { - mvs_check_page (0, 10, 0); - return \"STE %1,140(,13)\;SDR %0,%0\;LE %0,140(,13)\"; - } - mvs_check_page (0, 4, 0); - return \"SDR %0,%0\;LER %0,%1\"; - } - mvs_check_page (0, 6, 0); - return \"SDR %0,%0\;LE %0,%1\"; -}" - [(set_attr "length" "10")] -) - -;; -;;- Add instructions. -;; - -; -; adddi3 instruction pattern(s). -; -; -;(define_expand "adddi3" -; [(set (match_operand:DI 0 "general_operand" "") -; (plus:DI (match_operand:DI 1 "general_operand" "") -; (match_operand:DI 2 "general_operand" "")))] -; "" -; " -;{ -; rtx label = gen_label_rtx (); -; rtx op0_high = operand_subword (operands[0], 0, 1, DImode); -; rtx op0_low = gen_lowpart (SImode, operands[0]); -; -; emit_insn (gen_rtx_SET (VOIDmode, op0_high, -; gen_rtx_PLUS (SImode, -; operand_subword (operands[1], 0, 1, DImode), -; operand_subword (operands[2], 0, 1, DImode)))); -; emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, -; gen_rtx_SET (VOIDmode, op0_low, -; gen_rtx_PLUS (SImode, gen_lowpart (SImode, operands[1]), -; gen_lowpart (SImode, operands[2]))), -; gen_rtx_USE (VOIDmode, gen_rtx_LABEL_REF (VOIDmode, label))))); -; emit_insn (gen_rtx_SET (VOIDmode, op0_high, -; gen_rtx_PLUS (SImode, op0_high, -; gen_rtx_CONST_INT (SImode, 1)))); -; emit_label (label); -; DONE; -;}") - -(define_insn "" - [(set (match_operand:SI 0 "general_operand" "=d") - (plus:SI (match_operand:SI 1 "general_operand" "%0") - (match_operand:SI 2 "general_operand" "g"))) - (use (label_ref (match_operand 3 "" ""))) -; (clobber (reg:SI 14)) - ] - "" - "* -{ - int onpage; - - check_label_emit (); - onpage = mvs_check_label (CODE_LABEL_NUMBER (operands[3])); - if (REG_P (operands[2])) - { - if (!onpage) - { - mvs_check_page (0, 8, 4); - return \"ALR %0,%2\;L 14,=A(%l3)\;BCR 12,14\"; - } - if (mvs_check_page (0, 6, 0)) - { - mvs_check_page (0, 2, 4); - return \"ALR %0,%2\;L 14,=A(%l3)\;BCR 12,14\"; - } - return \"ALR %0,%2\;BC 12,%l3\"; - } - if (!onpage) - { - mvs_check_page (0, 10, 4); - return \"AL %0,%2\;L 14,=A(%l3)\;BCR 12,14\"; - } - if (mvs_check_page (0, 8 ,0)) - { - mvs_check_page (0, 2, 4); - return \"AL %0,%2\;L 14,=A(%l3)\;BCR 12,14\"; - } - return \"AL %0,%2\;BC 12,%l3\"; -}" - [(set_attr "length" "10")] -) - -; -; addsi3 instruction pattern(s). -; -; The following insn is used when it is known that operand one is an address, -; frame, stack or argument pointer, and operand two is a constant that is -; small enough to fit in the displacement field. -; Notice that we can't allow the frame pointer to used as a normal register -; because of this insn. -; - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=d") - (plus:SI (match_operand:SI 1 "general_operand" "%a") - (match_operand:SI 2 "immediate_operand" "J")))] - "((REGNO (operands[1]) == FRAME_POINTER_REGNUM || REGNO (operands[1]) == ARG_POINTER_REGNUM || REGNO (operands[1]) == STACK_POINTER_REGNUM) && (unsigned) INTVAL (operands[2]) < 4096)" - "* -{ - check_label_emit (); - CC_STATUS_INIT; /* add assumes CC but LA doesn't set CC */ - mvs_check_page (0, 4, 0); - return \"LA %0,%c2(,%1)\"; -}" - [(set_attr "length" "4")] -) - -; This insn handles additions that are relative to the frame pointer. - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=d") - (plus:SI (match_operand:SI 1 "register_operand" "%a") - (match_operand:SI 2 "immediate_operand" "i")))] - "REGNO (operands[1]) == FRAME_POINTER_REGNUM" - "* -{ - check_label_emit (); - if ((unsigned) INTVAL (operands[2]) < 4096) - { - CC_STATUS_INIT; /* add assumes CC but LA doesn't set CC */ - mvs_check_page (0, 4, 0); - return \"LA %0,%c2(,%1)\"; - } - if (REGNO (operands[1]) == REGNO (operands[0])) - { - CC_STATUS_INIT; - mvs_check_page (0, 4, 0); - return \"A %0,%2\"; - } - mvs_check_page (0, 6, 0); - return \"L %0,%2\;AR %0,%1\"; -}" - [(set_attr "length" "6")] -) - -;; -;; The CC status bits for the arithmetic instructions are handled -;; in the NOTICE_UPDATE_CC macro (yeah???) and so they do not need -;; to be set below. They only need to be invalidated if *not* set -;; (e.g. by BCTR) ... yeah I think that's right ... -;; - -(define_insn "addsi3" - [(set (match_operand:SI 0 "general_operand" "=d") - (plus:SI (match_operand:SI 1 "general_operand" "%0") - (match_operand:SI 2 "general_operand" "g")))] - "" - "* -{ - check_label_emit (); - if (REG_P (operands[2])) - { - mvs_check_page (0, 2, 0); - return \"AR %0,%2\"; - } - if (GET_CODE (operands[2]) == CONST_INT) - { - if (INTVAL (operands[2]) == -1) - { - CC_STATUS_INIT; /* add assumes CC but BCTR doesn't set CC */ - mvs_check_page (0, 2, 0); - return \"BCTR %0,0\"; - } - } - mvs_check_page (0, 4, 0); - return \"A %0,%2\"; -}" - [(set_attr "length" "4")] -) - -; -; addhi3 instruction pattern(s). -; - -(define_insn "addhi3" - [(set (match_operand:HI 0 "general_operand" "=d") - (plus:HI (match_operand:HI 1 "general_operand" "%0") - (match_operand:HI 2 "general_operand" "dmi")))] - "" - "* -{ - check_label_emit (); - if (REG_P (operands[2])) - { - mvs_check_page (0, 8, 0); - return \"STH %2,140(,13)\;AH %0,140(,13)\"; - } - if (GET_CODE (operands[2]) == CONST_INT) - { - if (INTVAL (operands[2]) == -1) - { - CC_STATUS_INIT; /* add assumes CC but BCTR doesn't set CC */ - mvs_check_page (0, 2, 0); - return \"BCTR %0,0\"; - } - mvs_check_page (0, 4, 0); - return \"AH %0,%H2\"; - } - mvs_check_page (0, 4, 0); - return \"AH %0,%2\"; -}" - [(set_attr "length" "8")] -) - -; -; addqi3 instruction pattern(s). -; - -(define_insn "addqi3" - [(set (match_operand:QI 0 "general_operand" "=d") - (plus:QI (match_operand:QI 1 "general_operand" "%a") - (match_operand:QI 2 "general_operand" "ai")))] - "" - "* -{ - check_label_emit (); - CC_STATUS_INIT; /* add assumes CC but LA doesn't set CC */ - mvs_check_page (0, 4, 0); - if (REG_P (operands[2])) - return \"LA %0,0(%1,%2)\"; - return \"LA %0,%B2(,%1)\"; -}" - [(set_attr "length" "4")] -) - -; -; adddf3 instruction pattern(s). -; - -(define_insn "adddf3" - [(set (match_operand:DF 0 "general_operand" "=f") - (plus:DF (match_operand:DF 1 "general_operand" "%0") - (match_operand:DF 2 "general_operand" "fmF")))] - "" - "* -{ - check_label_emit (); - if (FP_REG_P (operands[2])) - { - mvs_check_page (0, 2, 0); - return \"ADR %0,%2\"; - } - mvs_check_page (0, 4, 0); - return \"AD %0,%2\"; -}" - [(set_attr "length" "4")] -) - -; -; addsf3 instruction pattern(s). -; - -(define_insn "addsf3" - [(set (match_operand:SF 0 "general_operand" "=f") - (plus:SF (match_operand:SF 1 "general_operand" "%0") - (match_operand:SF 2 "general_operand" "fmF")))] - "" - "* -{ - check_label_emit (); - if (FP_REG_P (operands[2])) - { - mvs_check_page (0, 2, 0); - return \"AER %0,%2\"; - } - mvs_check_page (0, 4, 0); - return \"AE %0,%2\"; -}" - [(set_attr "length" "4")] -) - -;; -;;- Subtract instructions. -;; - -; -; subdi3 instruction pattern(s). -; -; -;(define_expand "subdi3" -; [(set (match_operand:DI 0 "general_operand" "") -; (minus:DI (match_operand:DI 1 "general_operand" "") -; (match_operand:DI 2 "general_operand" "")))] -; "" -; " -;{ -; rtx label = gen_label_rtx (); -; rtx op0_high = operand_subword (operands[0], 0, 1, DImode); -; rtx op0_low = gen_lowpart (SImode, operands[0]); -; -; emit_insn (gen_rtx_SET (VOIDmode, op0_high, -; gen_rtx_MINUS (SImode, -; operand_subword (operands[1], 0, 1, DImode), -; operand_subword (operands[2], 0, 1, DImode)))); -; emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, -; gen_rtx_SET (VOIDmode, op0_low, -; gen_rtx_MINUS (SImode, -; gen_lowpart (SImode, operands[1]), -; gen_lowpart (SImode, operands[2]))), -; gen_rtx_USE (VOIDmode, -; gen_rtx_LABEL_REF (VOIDmode, label))))); -; emit_insn (gen_rtx_SET (VOIDmode, op0_high, -; gen_rtx_MINUS (SImode, op0_high, -; gen_rtx_CONST_INT (SImode, 1)))); -; emit_label (label); -; DONE; -;}") - -(define_insn "" - [(set (match_operand:SI 0 "general_operand" "=d") - (minus:SI (match_operand:SI 1 "general_operand" "0") - (match_operand:SI 2 "general_operand" "g"))) - (use (label_ref (match_operand 3 "" ""))) -; (clobber (reg:SI 14)) - ] - "" - "* -{ - int onpage; - - check_label_emit (); - CC_STATUS_INIT; - onpage = mvs_check_label (CODE_LABEL_NUMBER (operands[3])); - if (REG_P (operands[2])) - { - if (!onpage) - { - mvs_check_page (0, 8, 4); - return \"SLR %0,%2\;L 14,=A(%l3)\;BCR 12,14\"; - } - if (mvs_check_page (0, 6, 0)) - { - mvs_check_page (0, 2, 4); - return \"SLR %0,%2\;L 14,=A(%l3)\;BCR 12,14\"; - } - return \"SLR %0,%2\;BC 12,%l3\"; - } - if (!onpage) - { - mvs_check_page (0, 10, 4); - return \"SL %0,%2\;L 14,=A(%l3)\;BCR 12,14\"; - } - if (mvs_check_page (0, 8, 0)) - { - mvs_check_page (0, 2, 4); - return \"SL %0,%2\;L 14,=A(%l3)\;BCR 12,14\"; - } - return \"SL %0,%2\;BC 12,%l3\"; -}" - [(set_attr "length" "10")] -) - -; -; subsi3 instruction pattern(s). -; - -(define_insn "subsi3" - [(set (match_operand:SI 0 "general_operand" "=d") - (minus:SI (match_operand:SI 1 "general_operand" "0") - (match_operand:SI 2 "general_operand" "g")))] - "" - "* -{ - check_label_emit (); - if (REG_P (operands[2])) - { - mvs_check_page (0, 2, 0); - return \"SR %0,%2\"; - } - if (operands[2] == const1_rtx) - { - CC_STATUS_INIT; /* subtract assumes CC but BCTR doesn't set CC */ - mvs_check_page (0, 2, 0); - return \"BCTR %0,0\"; - } - mvs_check_page (0, 4, 0); - return \"S %0,%2\"; -}" - [(set_attr "length" "4")] -) - -; -; subhi3 instruction pattern(s). -; - -(define_insn "subhi3" - [(set (match_operand:HI 0 "general_operand" "=d") - (minus:HI (match_operand:HI 1 "general_operand" "0") - (match_operand:HI 2 "general_operand" "g")))] - "" - "* -{ - check_label_emit (); - if (REG_P (operands[2])) - { - mvs_check_page (0, 8, 0); - return \"STH %2,140(,13)\;SH %0,140(,13)\"; - } - if (operands[2] == const1_rtx) - { - CC_STATUS_INIT; /* subtract assumes CC but BCTR doesn't set CC */ - mvs_check_page (0, 2, 0); - return \"BCTR %0,0\"; - } - if (GET_CODE (operands[2]) == CONST_INT) - { - mvs_check_page (0, 4, 0); - return \"SH %0,%H2\"; - } - mvs_check_page (0, 4, 0); - return \"SH %0,%2\"; -}" - [(set_attr "length" "8")] -) - -; -; subqi3 instruction pattern(s). -; - -(define_expand "subqi3" - [(set (match_operand:QI 0 "general_operand" "=d") - (minus:QI (match_operand:QI 1 "general_operand" "0") - (match_operand:QI 2 "general_operand" "di")))] - "" - " -{ - if (REG_P (operands[2])) - { - emit_insn (gen_rtx_SET (VOIDmode, operands[0], - gen_rtx_MINUS (QImode, operands[1], operands[2]))); - } - else - { - emit_insn (gen_rtx_SET (VOIDmode, operands[0], - gen_rtx_PLUS (QImode, operands[1], - negate_rtx (QImode, operands[2])))); - } - DONE; -}") - -(define_insn "" - [(set (match_operand:QI 0 "register_operand" "=d") - (minus:QI (match_operand:QI 1 "register_operand" "0") - (match_operand:QI 2 "register_operand" "d")))] - "" - "* -{ - check_label_emit (); - mvs_check_page (0, 2, 0); - return \"SR %0,%2\"; -}" - [(set_attr "length" "2")] -) - -; -; subdf3 instruction pattern(s). -; - -(define_insn "subdf3" - [(set (match_operand:DF 0 "general_operand" "=f") - (minus:DF (match_operand:DF 1 "general_operand" "0") - (match_operand:DF 2 "general_operand" "fmF")))] - "" - "* -{ - check_label_emit (); - if (FP_REG_P (operands[2])) - { - mvs_check_page (0, 2, 0); - return \"SDR %0,%2\"; - } - mvs_check_page (0, 4, 0); - return \"SD %0,%2\"; -}" - [(set_attr "length" "4")] -) - -; -; subsf3 instruction pattern(s). -; - -(define_insn "subsf3" - [(set (match_operand:SF 0 "general_operand" "=f") - (minus:SF (match_operand:SF 1 "general_operand" "0") - (match_operand:SF 2 "general_operand" "fmF")))] - "" - "* -{ - check_label_emit (); - if (FP_REG_P (operands[2])) - { - mvs_check_page (0, 2, 0); - return \"SER %0,%2\"; - } - mvs_check_page (0, 4, 0); - return \"SE %0,%2\"; -}" - [(set_attr "length" "4")] -) - -;; -;;- Multiply instructions. -;; - -; -; mulsi3 instruction pattern(s). -; - -(define_expand "mulsi3" - [(set (match_operand:SI 0 "general_operand" "") - (mult:SI (match_operand:SI 1 "general_operand" "") - (match_operand:SI 2 "general_operand" "")))] - "" - " -{ - if (GET_CODE (operands[1]) == CONST_INT - && CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'K')) - { - emit_insn (gen_rtx_SET (VOIDmode, operands[0], - gen_rtx_MULT (SImode, operands[2], operands[1]))); - } - else if (GET_CODE (operands[2]) == CONST_INT - && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')) - { - emit_insn (gen_rtx_SET (VOIDmode, operands[0], - gen_rtx_MULT (SImode, operands[1], operands[2]))); - } - else - { - rtx r = gen_reg_rtx (DImode); - - /* XXX trouble. Below we generate some rtx's that model what - * is really supposed to happen with multiply on the 370/390 - * hardware, and that is all well & good. However, during optimization - * it can happen that the two operands are exchanged (after all, - * multiplication is commutitive), in which case the doubleword - * ends up in memory and everything is hosed. The gen_reg_rtx - * should have kept it in a reg ... We hack around this - * below, in the M/MR isntruction pattern, and constrain it to - * \"di\" instead of \"g\". But this still ends up with lots & lots of - * movement between registers & memory and is an awful waste. - * Dunno how to untwist it elegantly; but it seems to work for now. - */ - emit_insn (gen_rtx_SET (VOIDmode, - gen_rtx_SUBREG (SImode, r, GET_MODE_SIZE (SImode)), - operands[1])); - emit_insn (gen_rtx_SET (VOIDmode, r, - gen_rtx_MULT (DImode, r, operands[2]))); - emit_insn (gen_rtx_SET (VOIDmode, operands[0], - gen_rtx_SUBREG (SImode, r, GET_MODE_SIZE (SImode)))); - } - DONE; -}") - -(define_insn "" - [(set (match_operand:SI 0 "general_operand" "=d") - (mult:SI (match_operand:SI 1 "general_operand" "%0") - (match_operand:SI 2 "immediate_operand" "K")))] - "" - "* -{ - check_label_emit (); - mvs_check_page (0, 4, 0); - return \"MH %0,%H2\"; -}" - [(set_attr "length" "4")] -) - -(define_insn "" - [(set (match_operand:DI 0 "register_operand" "=d") - (mult:DI (match_operand:DI 1 "general_operand" "%0") - (match_operand:SI 2 "general_operand" "di")))] - "" - "* -{ - check_label_emit (); - if (REG_P (operands[2])) - { - mvs_check_page (0, 2, 0); - return \"MR %0,%2\"; - } - mvs_check_page (0, 4, 0); - return \"M %0,%2\"; -}" - [(set_attr "length" "4")] -) - -; -; muldf3 instruction pattern(s). -; - -(define_insn "muldf3" - [(set (match_operand:DF 0 "general_operand" "=f") - (mult:DF (match_operand:DF 1 "general_operand" "%0") - (match_operand:DF 2 "general_operand" "fmF")))] - "" - "* -{ - check_label_emit (); - if (FP_REG_P (operands[2])) - { - mvs_check_page (0, 2, 0); - return \"MDR %0,%2\"; - } - mvs_check_page (0, 4, 0); - return \"MD %0,%2\"; -}" - [(set_attr "length" "4")] -) - -; -; mulsf3 instruction pattern(s). -; - -(define_insn "mulsf3" - [(set (match_operand:SF 0 "general_operand" "=f") - (mult:SF (match_operand:SF 1 "general_operand" "%0") - (match_operand:SF 2 "general_operand" "fmF")))] - "" - "* -{ - check_label_emit (); - if (FP_REG_P (operands[2])) - { - mvs_check_page (0, 2, 0); - return \"MER %0,%2\"; - } - mvs_check_page (0, 4, 0); - return \"ME %0,%2\"; -}" - [(set_attr "length" "4")] -) - -;; -;;- Divide instructions. -;; - -; -; divsi3 instruction pattern(s). -; - -(define_expand "divsi3" - [(set (match_operand:SI 0 "general_operand" "") - (div:SI (match_operand:SI 1 "general_operand" "") - (match_operand:SI 2 "general_operand" "")))] - "" - " -{ - rtx r = gen_reg_rtx (DImode); - - emit_insn (gen_extendsidi2 (r, operands[1])); - emit_insn (gen_rtx_SET (VOIDmode, r, - gen_rtx_DIV (DImode, r, operands[2]))); - emit_insn (gen_rtx_SET (VOIDmode, operands[0], - gen_rtx_SUBREG (SImode, r, GET_MODE_SIZE (SImode)))); - DONE; -}") - - -; -; udivsi3 instruction pattern(s). -; - -(define_expand "udivsi3" - [(set (match_operand:SI 0 "general_operand" "") - (udiv:SI (match_operand:SI 1 "general_operand" "") - (match_operand:SI 2 "general_operand" "")))] - "" - " -{ - rtx dr = gen_reg_rtx (DImode); - rtx dr_0 = gen_rtx_SUBREG (SImode, dr, 0); - rtx dr_1 = gen_rtx_SUBREG (SImode, dr, GET_MODE_SIZE (SImode)); - - - if (GET_CODE (operands[2]) == CONST_INT) - { - if (INTVAL (operands[2]) > 0) - { - emit_insn (gen_zero_extendsidi2 (dr, operands[1])); - emit_insn (gen_rtx_SET (VOIDmode, dr, - gen_rtx_DIV (DImode, dr, operands[2]))); - } - else - { - rtx label1 = gen_label_rtx (); - - emit_insn (gen_rtx_SET (VOIDmode, dr_0, operands[1])); - emit_insn (gen_rtx_SET (VOIDmode, dr_1, const0_rtx)); - emit_insn (gen_cmpsi (dr_0, operands[2])); - emit_jump_insn (gen_bltu (label1)); - emit_insn (gen_rtx_SET (VOIDmode, dr_1, const1_rtx)); - emit_label (label1); - } - } - else - { - rtx label1 = gen_label_rtx (); - rtx label2 = gen_label_rtx (); - rtx label3 = gen_label_rtx (); - rtx sr = gen_reg_rtx (SImode); - - emit_insn (gen_rtx_SET (VOIDmode, dr_0, operands[1])); - emit_insn (gen_rtx_SET (VOIDmode, sr, operands[2])); - emit_insn (gen_rtx_SET (VOIDmode, dr_1, const0_rtx)); - emit_insn (gen_cmpsi (sr, dr_0)); - emit_jump_insn (gen_bgtu (label3)); - emit_insn (gen_cmpsi (sr, const1_rtx)); - emit_jump_insn (gen_blt (label2)); - emit_insn (gen_cmpsi (sr, const1_rtx)); - emit_jump_insn (gen_beq (label1)); - emit_insn (gen_rtx_SET (VOIDmode, dr, - gen_rtx_LSHIFTRT (DImode, dr, - gen_rtx_CONST_INT (SImode, 32)))); - emit_insn (gen_rtx_SET (VOIDmode, dr, - gen_rtx_DIV (DImode, dr, sr))); - emit_jump_insn (gen_jump (label3)); - emit_label (label1); - emit_insn (gen_rtx_SET (VOIDmode, dr_1, dr_0)); - emit_jump_insn (gen_jump (label3)); - emit_label (label2); - emit_insn (gen_rtx_SET (VOIDmode, dr_1, const1_rtx)); - emit_label (label3); - } - emit_insn (gen_rtx_SET (VOIDmode, operands[0], dr_1)); - - DONE; -}") - -; This is used by divsi3 & udivsi3. - -(define_insn "" - [(set (match_operand:DI 0 "register_operand" "=d") - (div:DI (match_operand:DI 1 "register_operand" "0") - (match_operand:SI 2 "general_operand" "dm")))] - "" - "* -{ - check_label_emit (); - if (REG_P (operands[2])) - { - mvs_check_page (0, 2, 0); - return \"DR %0,%2\"; - } - mvs_check_page (0, 4, 0); - return \"D %0,%2\"; -}" - [(set_attr "length" "4")] -) - -; -; divdf3 instruction pattern(s). -; - -(define_insn "divdf3" - [(set (match_operand:DF 0 "general_operand" "=f") - (div:DF (match_operand:DF 1 "general_operand" "0") - (match_operand:DF 2 "general_operand" "fmF")))] - "" - "* -{ - check_label_emit (); - if (FP_REG_P (operands[2])) - { - mvs_check_page (0, 2, 0); - return \"DDR %0,%2\"; - } - mvs_check_page (0, 4, 0); - return \"DD %0,%2\"; -}" - [(set_attr "length" "4")] -) - -; -; divsf3 instruction pattern(s). -; - -(define_insn "divsf3" - [(set (match_operand:SF 0 "general_operand" "=f") - (div:SF (match_operand:SF 1 "general_operand" "0") - (match_operand:SF 2 "general_operand" "fmF")))] - "" - "* -{ - check_label_emit (); - if (FP_REG_P (operands[2])) - { - mvs_check_page (0, 2, 0); - return \"DER %0,%2\"; - } - mvs_check_page (0, 4, 0); - return \"DE %0,%2\"; -}" - [(set_attr "length" "4")] -) - -;; -;;- Modulo instructions. -;; - -; -; modsi3 instruction pattern(s). -; - -(define_expand "modsi3" - [(set (match_operand:SI 0 "general_operand" "") - (mod:SI (match_operand:SI 1 "general_operand" "") - (match_operand:SI 2 "general_operand" "")))] - "" - " -{ - rtx r = gen_reg_rtx (DImode); - - emit_insn (gen_extendsidi2 (r, operands[1])); - emit_insn (gen_rtx_SET (VOIDmode, r, - gen_rtx_MOD (DImode, r, operands[2]))); - emit_insn (gen_rtx_SET (VOIDmode, operands[0], - gen_rtx_SUBREG (SImode, r, 0))); - DONE; -}") - -; -; umodsi3 instruction pattern(s). -; - -(define_expand "umodsi3" - [(set (match_operand:SI 0 "general_operand" "") - (umod:SI (match_operand:SI 1 "general_operand" "") - (match_operand:SI 2 "general_operand" "")))] - "" - " -{ - rtx dr = gen_reg_rtx (DImode); - rtx dr_0 = gen_rtx_SUBREG (SImode, dr, 0); - - emit_insn (gen_rtx_SET (VOIDmode, dr_0, operands[1])); - - if (GET_CODE (operands[2]) == CONST_INT) - { - if (INTVAL (operands[2]) > 0) - { - emit_insn (gen_rtx_SET (VOIDmode, dr, - gen_rtx_LSHIFTRT (DImode, dr, - gen_rtx_CONST_INT (SImode, 32)))); - emit_insn (gen_rtx_SET (VOIDmode, dr, - gen_rtx_MOD (DImode, dr, operands[2]))); - } - else - { - rtx label1 = gen_label_rtx (); - rtx sr = gen_reg_rtx (SImode); - - emit_insn (gen_rtx_SET (VOIDmode, sr, operands[2])); - emit_insn (gen_cmpsi (dr_0, sr)); - emit_jump_insn (gen_bltu (label1)); - emit_insn (gen_rtx_SET (VOIDmode, sr, gen_rtx_ABS (SImode, sr))); - emit_insn (gen_rtx_SET (VOIDmode, dr_0, - gen_rtx_PLUS (SImode, dr_0, sr))); - emit_label (label1); - } - } - else - { - rtx label1 = gen_label_rtx (); - rtx label2 = gen_label_rtx (); - rtx label3 = gen_label_rtx (); - rtx sr = gen_reg_rtx (SImode); - - emit_insn (gen_rtx_SET (VOIDmode, dr_0, operands[1])); - emit_insn (gen_rtx_SET (VOIDmode, sr, operands[2])); - emit_insn (gen_cmpsi (sr, dr_0)); - emit_jump_insn (gen_bgtu (label3)); - emit_insn (gen_cmpsi (sr, const1_rtx)); - emit_jump_insn (gen_blt (label2)); - emit_jump_insn (gen_beq (label1)); - emit_insn (gen_rtx_SET (VOIDmode, dr, - gen_rtx_LSHIFTRT (DImode, dr, - gen_rtx_CONST_INT (SImode, 32)))); - emit_insn (gen_rtx_SET (VOIDmode, dr, gen_rtx_MOD (DImode, dr, sr))); - emit_jump_insn (gen_jump (label3)); - emit_label (label1); - emit_insn (gen_rtx_SET (VOIDmode, dr_0, const0_rtx)); - emit_jump_insn (gen_jump (label3)); - emit_label (label2); - emit_insn (gen_rtx_SET (VOIDmode, dr_0, - gen_rtx_MINUS (SImode, dr_0, sr))); - emit_label (label3); - - } - emit_insn (gen_rtx_SET (VOIDmode, operands[0], dr_0)); - - DONE; -}") - -; This is used by modsi3 & umodsi3. - -(define_insn "" - [(set (match_operand:DI 0 "register_operand" "=d") - (mod:DI (match_operand:DI 1 "register_operand" "0") - (match_operand:SI 2 "general_operand" "dm")))] - "" - "* -{ - check_label_emit (); - if (REG_P (operands[2])) - { - mvs_check_page (0, 2, 0); - return \"DR %0,%2\"; - } - mvs_check_page (0, 4, 0); - return \"D %0,%2\"; -}" - [(set_attr "length" "4")] -) - -;; -;;- And instructions. -;; - -; -; anddi3 instruction pattern(s). -; - -;(define_expand "anddi3" -; [(set (match_operand:DI 0 "general_operand" "") -; (and:DI (match_operand:DI 1 "general_operand" "") -; (match_operand:DI 2 "general_operand" "")))] -; "" -; " -;{ -; rtx gen_andsi3(); -; -; emit_insn (gen_andsi3 (operand_subword (operands[0], 0, 1, DImode), -; operand_subword (operands[1], 0, 1, DImode), -; operand_subword (operands[2], 0, 1, DImode))); -; emit_insn (gen_andsi3 (gen_lowpart (SImode, operands[0]), -; gen_lowpart (SImode, operands[1]), -; gen_lowpart (SImode, operands[2]))); -; DONE; -;}") - -; -; andsi3 instruction pattern(s). -; - -(define_insn "" - [(set (match_operand:SI 0 "r_or_s_operand" "=d,m") - (and:SI (match_operand:SI 1 "r_or_s_operand" "%0,0") - (match_operand:SI 2 "r_or_s_operand" "g,mi")))] - "TARGET_CHAR_INSTRUCTIONS" - "* -{ - check_label_emit (); - CC_STATUS_INIT; /* and sets CC but not how we want it */ - if (REG_P (operands[2])) - { - mvs_check_page (0, 2, 0); - return \"NR %0,%2\"; - } - if (REG_P (operands[0])) - { - mvs_check_page (0, 4, 0); - return \"N %0,%2\"; - } - mvs_check_page (0, 6, 0); - return \"NC %O0(4,%R0),%2\"; -}" - [(set_attr "length" "6")] -) - -(define_insn "andsi3" - [(set (match_operand:SI 0 "general_operand" "=d") - (and:SI (match_operand:SI 1 "general_operand" "%0") - (match_operand:SI 2 "general_operand" "g")))] - "" - "* -{ - check_label_emit (); - CC_STATUS_INIT; /* and sets CC but not how we want it */ - if (REG_P (operands[2])) - { - mvs_check_page (0, 2, 0); - return \"NR %0,%2\"; - } - mvs_check_page (0, 4, 0); - return \"N %0,%2\"; -}" - [(set_attr "length" "4")] -) - -; -; andhi3 instruction pattern(s). -; - -(define_insn "" - [(set (match_operand:HI 0 "r_or_s_operand" "=d,m") - (and:HI (match_operand:HI 1 "r_or_s_operand" "%0,0") - (match_operand:HI 2 "r_or_s_operand" "di,mi")))] - "TARGET_CHAR_INSTRUCTIONS" - "* -{ - check_label_emit (); - CC_STATUS_INIT; /* and sets CC but not how we want it */ - if (REG_P (operands[2])) - { - mvs_check_page (0, 2, 0); - return \"NR %0,%2\"; - } - if (REG_P (operands[0])) - { - /* %K2 == sign extend operand to 32 bits so that CH works */ - mvs_check_page (0, 4, 0); - if (GET_CODE (operands[2]) == CONST_INT) - return \"N %0,%K2\"; - return \"N %0,%2\"; - } - if (GET_CODE (operands[2]) == CONST_INT) - { - mvs_check_page (0, 6, 0); - return \"NC %O0(2,%R0),%H2\"; - } - mvs_check_page (0, 6, 0); - return \"NC %O0(2,%R0),%2\"; -}" - [(set_attr "length" "6")] -) - -(define_insn "andhi3" - [(set (match_operand:HI 0 "general_operand" "=d") - (and:HI (match_operand:HI 1 "general_operand" "%0") - (match_operand:HI 2 "general_operand" "di")))] - "" - "* -{ - check_label_emit (); - CC_STATUS_INIT; /* and sets CC but not how we want it */ - if (GET_CODE (operands[2]) == CONST_INT) - { - /* %K2 == sign extend operand to 32 bits so that CH works */ - mvs_check_page (0, 4, 0); - return \"N %0,%K2\"; - } - mvs_check_page (0, 2, 0); - return \"NR %0,%2\"; -}" - [(set_attr "length" "4")] -) - -; -; andqi3 instruction pattern(s). -; - -(define_insn "" - [(set (match_operand:QI 0 "r_or_s_operand" "=d,m") - (and:QI (match_operand:QI 1 "r_or_s_operand" "%0,0") - (match_operand:QI 2 "r_or_s_operand" "di,mi")))] - "TARGET_CHAR_INSTRUCTIONS" - "* -{ - check_label_emit (); - CC_STATUS_INIT; /* and sets CC but not how we want it */ - if (REG_P (operands[2])) - { - mvs_check_page (0, 2, 0); - return \"NR %0,%2\"; - } - if (REG_P (operands[0])) - { - mvs_check_page (0, 4, 0); - return \"N %0,%2\"; - } - if (GET_CODE (operands[2]) == CONST_INT) - { - mvs_check_page (0, 4, 0); - return \"NI %0,%B2\"; - } - mvs_check_page (0, 6, 0); - return \"NC %O0(1,%R0),%2\"; -}" - [(set_attr "length" "6")] -) - -(define_insn "andqi3" - [(set (match_operand:QI 0 "general_operand" "=d") - (and:QI (match_operand:QI 1 "general_operand" "%0") - (match_operand:QI 2 "general_operand" "di")))] - "" - "* -{ - check_label_emit (); - CC_STATUS_INIT; /* and sets CC but not how we want it */ - if (GET_CODE (operands[2]) == CONST_INT) - { - mvs_check_page (0, 4, 0); - return \"N %0,%2\"; - } - mvs_check_page (0, 2, 0); - return \"NR %0,%2\"; -}" - [(set_attr "length" "4")] -) - -;; -;;- Bit set (inclusive or) instructions. -;; - -; -; iordi3 instruction pattern(s). -; - -;(define_expand "iordi3" -; [(set (match_operand:DI 0 "general_operand" "") -; (ior:DI (match_operand:DI 1 "general_operand" "") -; (match_operand:DI 2 "general_operand" "")))] -; "" -; " -;{ -; rtx gen_iorsi3(); -; -; emit_insn (gen_iorsi3 (operand_subword (operands[0], 0, 1, DImode), -; operand_subword (operands[1], 0, 1, DImode), -; operand_subword (operands[2], 0, 1, DImode))); -; emit_insn (gen_iorsi3 (gen_lowpart (SImode, operands[0]), -; gen_lowpart (SImode, operands[1]), -; gen_lowpart (SImode, operands[2]))); -; DONE; -;}") - -; -; iorsi3 instruction pattern(s). -; - -(define_insn "" - [(set (match_operand:SI 0 "r_or_s_operand" "=d,m") - (ior:SI (match_operand:SI 1 "r_or_s_operand" "%0,0") - (match_operand:SI 2 "r_or_s_operand" "g,Si")))] - "TARGET_CHAR_INSTRUCTIONS" - "* -{ - check_label_emit (); - CC_STATUS_INIT; /* OR sets CC but not how we want it */ - if (REG_P (operands[2])) - { - mvs_check_page (0, 2, 0); - return \"OR %0,%2\"; - } - if (REG_P (operands[0])) - { - mvs_check_page (0, 4, 0); - return \"O %0,%2\"; - } - mvs_check_page (0, 6, 0); - return \"OC %O0(4,%R0),%2\"; -}" - [(set_attr "length" "6")] -) - -(define_insn "iorsi3" - [(set (match_operand:SI 0 "general_operand" "=d") - (ior:SI (match_operand:SI 1 "general_operand" "%0") - (match_operand:SI 2 "general_operand" "g")))] - "" - "* -{ - check_label_emit (); - CC_STATUS_INIT; /* OR sets CC but not how we want it */ - if (REG_P (operands[2])) - { - mvs_check_page (0, 2, 0); - return \"OR %0,%2\"; - } - mvs_check_page (0, 4, 0); - return \"O %0,%2\"; -}" - [(set_attr "length" "4")] -) - -; -; iorhi3 instruction pattern(s). -; - -(define_insn "" - [(set (match_operand:HI 0 "r_or_s_operand" "=d,m") - (ior:HI (match_operand:HI 1 "r_or_s_operand" "%0,0") - (match_operand:HI 2 "r_or_s_operand" "di,mi")))] - "TARGET_CHAR_INSTRUCTIONS" - "* -{ - check_label_emit (); - CC_STATUS_INIT; /* OR sets CC but not how we want it */ - if (REG_P (operands[2])) - { - mvs_check_page (0, 2, 0); - return \"OR %0,%2\"; - } - if (REG_P (operands[0])) - { - mvs_check_page (0, 4, 0); - return \"O %0,%2\"; - } - if (GET_CODE (operands[2]) == CONST_INT) - { - mvs_check_page (0, 6, 2); - return \"OC %O0(2,%R0),%H2\"; - } - mvs_check_page (0, 6, 0); - return \"OC %O0(2,%R0),%2\"; -}" - [(set_attr "length" "6")] -) - -(define_insn "iorhi3" - [(set (match_operand:HI 0 "general_operand" "=d") - (ior:HI (match_operand:HI 1 "general_operand" "%0") - (match_operand:HI 2 "general_operand" "di")))] - "" - "* -{ - check_label_emit (); - CC_STATUS_INIT; /* OR sets CC but not how we want it */ - if (GET_CODE (operands[2]) == CONST_INT) - { - mvs_check_page (0, 4, 0); - return \"O %0,%2\"; - } - mvs_check_page (0, 2, 0); - return \"OR %0,%2\"; -}" - [(set_attr "length" "4")] -) - -; -; iorqi3 instruction pattern(s). -; - -(define_insn "" - [(set (match_operand:QI 0 "r_or_s_operand" "=d,m") - (ior:QI (match_operand:QI 1 "r_or_s_operand" "%0,0") - (match_operand:QI 2 "r_or_s_operand" "di,mi")))] - "TARGET_CHAR_INSTRUCTIONS" - "* -{ - check_label_emit (); - CC_STATUS_INIT; /* OR sets CC but not how we want it */ - if (REG_P (operands[2])) - { - mvs_check_page (0, 2, 0); - return \"OR %0,%2\"; - } - if (REG_P (operands[0])) - { - mvs_check_page (0, 4, 0); - return \"O %0,%2\"; - } - if (GET_CODE (operands[2]) == CONST_INT) - { - mvs_check_page (0, 4, 0); - return \"OI %0,%B2\"; - } - mvs_check_page (0, 6, 0); - return \"OC %O0(1,%R0),%2\"; -}" - [(set_attr "length" "6")] -) - -(define_insn "iorqi3" - [(set (match_operand:QI 0 "general_operand" "=d") - (ior:QI (match_operand:QI 1 "general_operand" "%0") - (match_operand:QI 2 "general_operand" "di")))] - "" - "* -{ - check_label_emit (); - CC_STATUS_INIT; /* OR sets CC but not how we want it */ - if (GET_CODE (operands[2]) == CONST_INT) - { - mvs_check_page (0, 4, 0); - return \"O %0,%2\"; - } - mvs_check_page (0, 2, 0); - return \"OR %0,%2\"; -}" - [(set_attr "length" "4")] -) - -;; -;;- Xor instructions. -;; - -; -; xordi3 instruction pattern(s). -; - -;(define_expand "xordi3" -; [(set (match_operand:DI 0 "general_operand" "") -; (xor:DI (match_operand:DI 1 "general_operand" "") -; (match_operand:DI 2 "general_operand" "")))] -; "" -; " -;{ -; rtx gen_xorsi3(); -; -; emit_insn (gen_xorsi3 (operand_subword (operands[0], 0, 1, DImode), -; operand_subword (operands[1], 0, 1, DImode), -; operand_subword (operands[2], 0, 1, DImode))); -; emit_insn (gen_xorsi3 (gen_lowpart (SImode, operands[0]), -; gen_lowpart (SImode, operands[1]), -; gen_lowpart (SImode, operands[2]))); -; DONE; -;}") - -; -; xorsi3 instruction pattern(s). -; - -(define_insn "" - [(set (match_operand:SI 0 "r_or_s_operand" "=d,m") - (xor:SI (match_operand:SI 1 "r_or_s_operand" "%0,0") - (match_operand:SI 2 "r_or_s_operand" "g,mi")))] - "TARGET_CHAR_INSTRUCTIONS" - "* -{ - check_label_emit (); - CC_STATUS_INIT; /* XOR sets CC but not how we want it */ - if (REG_P (operands[2])) - { - mvs_check_page (0, 2, 0); - return \"XR %0,%2\"; - } - if (REG_P (operands[0])) - { - mvs_check_page (0, 4, 0); - return \"X %0,%2\"; - } - mvs_check_page (0, 6, 0); - return \"XC %O0(4,%R0),%2\"; -}" - [(set_attr "length" "6")] -) - -(define_insn "xorsi3" - [(set (match_operand:SI 0 "general_operand" "=d") - (xor:SI (match_operand:SI 1 "general_operand" "%0") - (match_operand:SI 2 "general_operand" "g")))] - "" - "* -{ - check_label_emit (); - CC_STATUS_INIT; /* XOR sets CC but not how we want it */ - if (REG_P (operands[2])) - { - mvs_check_page (0, 2, 0); - return \"XR %0,%2\"; - } - mvs_check_page (0, 4, 0); - return \"X %0,%2\"; -}" - [(set_attr "length" "4")] -) - -; -; xorhi3 instruction pattern(s). -; - -(define_insn "" - [(set (match_operand:HI 0 "r_or_s_operand" "=d,m") - (xor:HI (match_operand:HI 1 "r_or_s_operand" "%0,0") - (match_operand:HI 2 "r_or_s_operand" "di,mi")))] - "TARGET_CHAR_INSTRUCTIONS" - "* -{ - check_label_emit (); - CC_STATUS_INIT; /* XOR sets CC but not how we want it */ - if (REG_P (operands[2])) - { - mvs_check_page (0, 2, 0); - return \"XR %0,%2\"; - } - if (REG_P (operands[0])) - { - mvs_check_page (0, 4, 0); - return \"X %0,%H2\"; - } - if (GET_CODE (operands[2]) == CONST_INT) - { - mvs_check_page (0, 6, 0); - return \"XC %O0(2,%R0),%H2\"; - } - mvs_check_page (0, 6, 0); - return \"XC %O0(2,%R0),%2\"; -}" - [(set_attr "length" "6")] -) - -(define_insn "xorhi3" - [(set (match_operand:HI 0 "general_operand" "=d") - (xor:HI (match_operand:HI 1 "general_operand" "%0") - (match_operand:HI 2 "general_operand" "di")))] - "" - "* -{ - check_label_emit (); - CC_STATUS_INIT; /* XOR sets CC but not how we want it */ - if (GET_CODE (operands[2]) == CONST_INT) - { - mvs_check_page (0, 4, 0); - return \"X %0,%H2\"; - } - mvs_check_page (0, 2, 0); - return \"XR %0,%2\"; -}" - [(set_attr "length" "4")] -) - -; -; xorqi3 instruction pattern(s). -; - -(define_insn "" - [(set (match_operand:QI 0 "r_or_s_operand" "=d,m") - (xor:QI (match_operand:QI 1 "r_or_s_operand" "%0,0") - (match_operand:QI 2 "r_or_s_operand" "di,mi")))] - "TARGET_CHAR_INSTRUCTIONS" - "* -{ - check_label_emit (); - CC_STATUS_INIT; /* XOR sets CC but not how we want it */ - if (REG_P (operands[2])) - { - mvs_check_page (0, 2, 0); - return \"XR %0,%2\"; - } - if (REG_P (operands[0])) - { - mvs_check_page (0, 4, 0); - return \"X %0,%2\"; - } - if (GET_CODE (operands[2]) == CONST_INT) - { - mvs_check_page (0, 4, 0); - return \"XI %0,%B2\"; - } - mvs_check_page (0, 6, 0); - return \"XC %O0(1,%R0),%2\"; -}" - [(set_attr "length" "6")] -) - -(define_insn "xorqi3" - [(set (match_operand:QI 0 "general_operand" "=d") - (xor:QI (match_operand:QI 1 "general_operand" "%0") - (match_operand:QI 2 "general_operand" "di")))] - "" - "* -{ - check_label_emit (); - CC_STATUS_INIT; /* XOR sets CC but not how we want it */ - if (GET_CODE (operands[2]) == CONST_INT) - { - mvs_check_page (0, 4, 0); - return \"X %0,%2\"; - } - mvs_check_page (0, 2, 0); - return \"XR %0,%2\"; -}" - [(set_attr "length" "4")] -) - -;; -;;- Negate instructions. -;; - -; -; negsi2 instruction pattern(s). -; - -(define_insn "negsi2" - [(set (match_operand:SI 0 "general_operand" "=d") - (neg:SI (match_operand:SI 1 "general_operand" "d")))] - "" - "* -{ - check_label_emit (); - mvs_check_page (0, 2, 0); - return \"LCR %0,%1\"; -}" - [(set_attr "length" "2")] -) - -; -; neghi2 instruction pattern(s). -; - -(define_insn "neghi2" - [(set (match_operand:HI 0 "general_operand" "=d") - (neg:HI (match_operand:HI 1 "general_operand" "d")))] - "" - "* -{ - check_label_emit (); - mvs_check_page (0, 10, 0); - return \"SLL %1,16\;SRA %1,16\;LCR %0,%1\"; -}" - [(set_attr "length" "10")] -) - -; -; negdf2 instruction pattern(s). -; - -(define_insn "negdf2" - [(set (match_operand:DF 0 "general_operand" "=f") - (neg:DF (match_operand:DF 1 "general_operand" "f")))] - "" - "* -{ - check_label_emit (); - mvs_check_page (0, 2, 0); - return \"LCDR %0,%1\"; -}" - [(set_attr "length" "2")] -) - -; -; negsf2 instruction pattern(s). -; - -(define_insn "negsf2" - [(set (match_operand:SF 0 "general_operand" "=f") - (neg:SF (match_operand:SF 1 "general_operand" "f")))] - "" - "* -{ - check_label_emit (); - mvs_check_page (0, 2, 0); - return \"LCER %0,%1\"; -}" - [(set_attr "length" "2")] -) - -;; -;;- Absolute value instructions. -;; - -; -; abssi2 instruction pattern(s). -; - -(define_insn "abssi2" - [(set (match_operand:SI 0 "general_operand" "=d") - (abs:SI (match_operand:SI 1 "general_operand" "d")))] - "" - "* -{ - check_label_emit (); - mvs_check_page (0, 2, 0); - return \"LPR %0,%1\"; -}" - [(set_attr "length" "2")] -) - -; -; abshi2 instruction pattern(s). -; - -(define_insn "abshi2" - [(set (match_operand:HI 0 "general_operand" "=d") - (abs:HI (match_operand:HI 1 "general_operand" "d")))] - "" - "* -{ - check_label_emit (); - mvs_check_page (0, 10, 0); - return \"SLL %1,16\;SRA %1,16\;LPR %0,%1\"; -}" - [(set_attr "length" "10")] -) - -; -; absdf2 instruction pattern(s). -; - -(define_insn "absdf2" - [(set (match_operand:DF 0 "general_operand" "=f") - (abs:DF (match_operand:DF 1 "general_operand" "f")))] - "" - "* -{ - check_label_emit (); - mvs_check_page (0, 2, 0); - return \"LPDR %0,%1\"; -}" - [(set_attr "length" "2")] -) - -; -; abssf2 instruction pattern(s). -; - -(define_insn "abssf2" - [(set (match_operand:SF 0 "general_operand" "=f") - (abs:SF (match_operand:SF 1 "general_operand" "f")))] - "" - "* -{ - check_label_emit (); - mvs_check_page (0, 2, 0); - return \"LPER %0,%1\"; -}" - [(set_attr "length" "2")] -) - -;; -;;- One complement instructions. -;; - -; -; one_cmpldi2 instruction pattern(s). -; - -;(define_expand "one_cmpldi2" -; [(set (match_operand:DI 0 "general_operand" "") -; (not:DI (match_operand:DI 1 "general_operand" "")))] -; "" -; " -;{ -; rtx gen_one_cmplsi2(); -; -; emit_insn (gen_one_cmplsi2 (operand_subword (operands[0], 0, 1, DImode), -; operand_subword (operands[1], 0, 1, DImode))); -; emit_insn (gen_one_cmplsi2 (gen_lowpart (SImode, operands[0]), -; gen_lowpart (SImode, operands[1]))); -; DONE; -;}") - -; -; one_cmplsi2 instruction pattern(s). -; - -(define_insn "" - [(set (match_operand:SI 0 "r_or_s_operand" "=dm") - (not:SI (match_operand:SI 1 "r_or_s_operand" "0")))] - "TARGET_CHAR_INSTRUCTIONS" - "* -{ - check_label_emit (); - CC_STATUS_INIT; /* XOR sets CC but not how we want it */ - if (REG_P (operands[0])) - { - mvs_check_page (0, 4, 4); - return \"X %0,=F'-1'\"; - } - CC_STATUS_INIT; - mvs_check_page (0, 6, 4); - return \"XC %O0(4,%R0),=F'-1'\"; -}" - [(set_attr "length" "6")] -) - -(define_insn "one_cmplsi2" - [(set (match_operand:SI 0 "general_operand" "=d") - (not:SI (match_operand:SI 1 "general_operand" "0")))] - "" - "* -{ - check_label_emit (); - CC_STATUS_INIT; /* XOR sets CC but not how we want it */ - mvs_check_page (0, 4, 4); - return \"X %0,=F'-1'\"; -}" - [(set_attr "length" "4")] -) - -; -; one_cmplhi2 instruction pattern(s). -; - -(define_insn "" - [(set (match_operand:HI 0 "r_or_s_operand" "=dm") - (not:HI (match_operand:HI 1 "r_or_s_operand" "0")))] - "TARGET_CHAR_INSTRUCTIONS" - "* -{ - check_label_emit (); - CC_STATUS_INIT; /* XOR sets CC but not how we want it */ - if (REG_P (operands[0])) - { - mvs_check_page (0, 4, 4); - return \"X %0,=F'-1'\"; - } - mvs_check_page (0, 6, 4); - return \"XC %O0(2,%R0),=XL4'FFFF'\"; -}" - [(set_attr "length" "6")] -) - -(define_insn "one_cmplhi2" - [(set (match_operand:HI 0 "general_operand" "=d") - (not:HI (match_operand:HI 1 "general_operand" "0")))] - "" - "* -{ - check_label_emit (); - CC_STATUS_INIT; /* XOR sets CC but not how we want it */ - mvs_check_page (0, 4, 4); - return \"X %0,=F'-1'\"; -}" - [(set_attr "length" "4")] -) - -; -; one_cmplqi2 instruction pattern(s). -; - -(define_insn "" - [(set (match_operand:QI 0 "r_or_s_operand" "=dm") - (not:QI (match_operand:QI 1 "r_or_s_operand" "0")))] - "TARGET_CHAR_INSTRUCTIONS" - "* -{ - check_label_emit (); - CC_STATUS_INIT; /* XOR sets CC but not how we want it */ - if (REG_P (operands[0])) - { - mvs_check_page (0, 4, 4); - return \"X %0,=F'-1'\"; - } - mvs_check_page (0, 4, 0); - return \"XI %0,255\"; -}" - [(set_attr "length" "4")] -) - -(define_insn "one_cmplqi2" - [(set (match_operand:QI 0 "general_operand" "=d") - (not:QI (match_operand:QI 1 "general_operand" "0")))] - "" - "* -{ - check_label_emit (); - CC_STATUS_INIT; /* XOR sets CC but not how we want it */ - mvs_check_page (0, 4, 4); - return \"X %0,=F'-1'\"; -}" - [(set_attr "length" "4")] -) - -;; -;;- Arithmetic shift instructions. -;; - -; -; ashldi3 instruction pattern(s). -; - -(define_insn "ashldi3" - [(set (match_operand:DI 0 "general_operand" "=d") - (ashift:DI (match_operand:DI 1 "general_operand" "0") - (match_operand:SI 2 "general_operand" "Ja")))] - "" - "* -{ - check_label_emit (); - /* this status set seems not have the desired effect, - * proably because the 64-bit long-long test is emulated ?! */ - CC_STATUS_SET (operands[0], operands[1]); - mvs_check_page (0, 4, 0); - if (REG_P (operands[2])) - return \"SLDA %0,0(%2)\"; - return \"SLDA %0,%c2\"; -}" - [(set_attr "length" "4")] -) - -; -; ashrdi3 instruction pattern(s). -; - -(define_insn "ashrdi3" - [(set (match_operand:DI 0 "register_operand" "=d") - (ashiftrt:DI (match_operand:DI 1 "general_operand" "0") - (match_operand:SI 2 "general_operand" "Ja")))] - "" - "* -{ - check_label_emit (); - /* this status set seems not have the desired effect, - * proably because the 64-bit long-long test is emulated ?! */ - CC_STATUS_SET (operands[0], operands[1]); - mvs_check_page (0, 4, 0); - if (REG_P (operands[2])) - return \"SRDA %0,0(%2)\"; - return \"SRDA %0,%c2\"; -}" - [(set_attr "length" "4")] -) - -; -; ashlsi3 instruction pattern(s). -; - -(define_insn "ashlsi3" - [(set (match_operand:SI 0 "general_operand" "=d") - (ashift:SI (match_operand:SI 1 "general_operand" "0") - (match_operand:SI 2 "general_operand" "Ja")))] - "" - "* -{ - check_label_emit (); - mvs_check_page (0, 4, 0); - if (REG_P (operands[2])) - return \"SLL %0,0(%2)\"; - return \"SLL %0,%c2\"; -}" - [(set_attr "length" "4")] -) - -; -; ashrsi3 instruction pattern(s). -; - -(define_insn "ashrsi3" - [(set (match_operand:SI 0 "general_operand" "=d") - (ashiftrt:SI (match_operand:SI 1 "general_operand" "0") - (match_operand:SI 2 "general_operand" "Ja")))] - "" - "* -{ - check_label_emit (); - CC_STATUS_SET (operands[0], operands[1]); - mvs_check_page (0, 4, 0); - if (REG_P (operands[2])) - return \"SRA %0,0(%2)\"; - return \"SRA %0,%c2\"; -}" - [(set_attr "length" "4")] -) - -; -; ashlhi3 instruction pattern(s). -; - -(define_insn "ashlhi3" - [(set (match_operand:HI 0 "general_operand" "=d") - (ashift:HI (match_operand:HI 1 "general_operand" "0") - (match_operand:SI 2 "general_operand" "Ja")))] - "" - "* -{ - check_label_emit (); - mvs_check_page (0, 8, 0); - if (REG_P (operands[2])) - return \"SLL %0,16(%2)\;SRA %0,16\"; - return \"SLL %0,16+%c2\;SRA %0,16\"; -}" - [(set_attr "length" "8")] -) - -; -; ashrhi3 instruction pattern(s). -; - -(define_insn "ashrhi3" - [(set (match_operand:HI 0 "general_operand" "=d") - (ashiftrt:HI (match_operand:HI 1 "general_operand" "0") - (match_operand:SI 2 "general_operand" "Ja")))] - "" - "* -{ - check_label_emit (); - mvs_check_page (0, 8, 0); - if (REG_P (operands[2])) - return \"SLL %0,16\;SRA %0,16(%2)\"; - return \"SLL %0,16\;SRA %0,16+%c2\"; -}" - [(set_attr "length" "8")] -) - -; -; ashlqi3 instruction pattern(s). -; - -(define_insn "ashlqi3" - [(set (match_operand:QI 0 "general_operand" "=d") - (ashift:QI (match_operand:QI 1 "general_operand" "0") - (match_operand:SI 2 "general_operand" "Ja")))] - "" - "* -{ - check_label_emit (); - mvs_check_page (0, 4, 0); - if (REG_P (operands[2])) - return \"SLL %0,0(%2)\"; - return \"SLL %0,%c2\"; -}" - [(set_attr "length" "4")] -) - -; -; ashrqi3 instruction pattern(s). -; - -(define_insn "ashrqi3" - [(set (match_operand:QI 0 "general_operand" "=d") - (ashiftrt:QI (match_operand:QI 1 "general_operand" "0") - (match_operand:SI 2 "general_operand" "Ja")))] - "" - "* -{ - check_label_emit (); - mvs_check_page (0, 8, 0); - if (REG_P (operands[2])) - return \"SLL %0,24\;SRA %0,24(%2)\"; - return \"SLL %0,24\;SRA %0,24+%c2\"; -}" - [(set_attr "length" "8")] -) - -;; -;;- Logical shift instructions. -;; - -; -; lshrdi3 instruction pattern(s). -; - -(define_insn "lshrdi3" - [(set (match_operand:DI 0 "general_operand" "=d") - (lshiftrt:DI (match_operand:DI 1 "general_operand" "0") - (match_operand:SI 2 "general_operand" "Ja")))] - "" - "* -{ - check_label_emit (); - mvs_check_page (0, 4, 0); - if (REG_P (operands[2])) - return \"SRDL %0,0(%2)\"; - return \"SRDL %0,%c2\"; -}" - [(set_attr "length" "4")] -) - - -; -; lshrsi3 instruction pattern(s). -; - -(define_insn "lshrsi3" - [(set (match_operand:SI 0 "general_operand" "=d") - (lshiftrt:SI (match_operand:SI 1 "general_operand" "0") - (match_operand:SI 2 "general_operand" "Ja")))] - "" - "* -{ - check_label_emit (); - mvs_check_page (0, 4, 0); - if (REG_P (operands[2])) - return \"SRL %0,0(%2)\"; - return \"SRL %0,%c2\"; -}" - [(set_attr "length" "4")] -) - -; -; lshrhi3 instruction pattern(s). -; - -(define_insn "lshrhi3" - [(set (match_operand:HI 0 "general_operand" "=d") - (lshiftrt:HI (match_operand:HI 1 "general_operand" "0") - (match_operand:SI 2 "general_operand" "Ja")))] - "" - "* -{ - check_label_emit (); - CC_STATUS_INIT; /* AND sets the CC but not how we want it */ - if (REG_P (operands[2])) - { - mvs_check_page (0, 8, 4); - return \"N %0,=XL4'0000FFFF'\;SRL %0,0(%2)\"; - } - mvs_check_page (0, 8, 4); - return \"N %0,=XL4'0000FFFF'\;SRL %0,%c2\"; -}" - [(set_attr "length" "8")] -) - -; -; lshrqi3 instruction pattern(s). -; - -(define_insn "lshrqi3" - [(set (match_operand:QI 0 "general_operand" "=d") - (lshiftrt:QI (match_operand:QI 1 "general_operand" "0") - (match_operand:SI 2 "general_operand" "Ja")))] - "" - "* -{ - check_label_emit (); - CC_STATUS_INIT; /* AND sets the CC but not how we want it */ - mvs_check_page (0, 8, 4); - if (REG_P (operands[2])) - return \"N %0,=XL4'000000FF'\;SRL %0,0(%2)\"; - return \"N %0,=XL4'000000FF'\;SRL %0,%c2\"; -}" - [(set_attr "length" "8")] -) - -;; ======================================================================= -;;- Conditional jump instructions. -;; ======================================================================= - -; -; beq instruction pattern(s). -; - -(define_insn "beq" - [(set (pc) - (if_then_else (eq (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc))) -; (clobber (reg:SI 14)) - ] - "" - "* -{ - check_label_emit (); - mvs_check_page (0, 4, 0); - if (i370_short_branch(insn) || mvs_check_label (CODE_LABEL_NUMBER (operands[0]))) - { - return \"BE %l0\"; - } - mvs_check_page (0, 2, 4); - return \"L 14,=A(%l0)\;BER 14\"; -}" - [(set_attr "length" "6")] -) - -; -; bne instruction pattern(s). -; - -(define_insn "bne" - [(set (pc) - (if_then_else (ne (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc))) -; (clobber (reg:SI 14)) - ] - "" - "* -{ - check_label_emit (); - mvs_check_page (0, 4, 0); - if (i370_short_branch(insn) || mvs_check_label (CODE_LABEL_NUMBER (operands[0]))) - { - return \"BNE %l0\"; - } - mvs_check_page (0, 2, 4); - return \"L 14,=A(%l0)\;BNER 14\"; -}" - [(set_attr "length" "6")] -) - -; -; bgt instruction pattern(s). -; - -(define_insn "bgt" - [(set (pc) - (if_then_else (gt (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc))) -; (clobber (reg:SI 14)) - ] - "" - "* -{ - check_label_emit (); - mvs_check_page (0, 4, 0); - if (i370_short_branch(insn) || mvs_check_label (CODE_LABEL_NUMBER (operands[0]))) - { - return \"BH %l0\"; - } - mvs_check_page (0, 2, 4); - return \"L 14,=A(%l0)\;BHR 14\"; -}" - [(set_attr "length" "6")] -) - -; -; bgtu instruction pattern(s). -; - -(define_insn "bgtu" - [(set (pc) - (if_then_else (gtu (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc))) -; (clobber (reg:SI 14)) - ] - "" - "* -{ - check_label_emit (); - mvs_check_page (0, 4, 0); - if (i370_short_branch(insn) || mvs_check_label (CODE_LABEL_NUMBER (operands[0]))) - { - return \"BH %l0\"; - } - mvs_check_page (0, 2, 4); - return \"L 14,=A(%l0)\;BHR 14\"; -}" - [(set_attr "length" "6")] -) - -; -; blt instruction pattern(s). -; - -(define_insn "blt" - [(set (pc) - (if_then_else (lt (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc))) -; (clobber (reg:SI 14)) - ] - "" - "* -{ - check_label_emit (); - mvs_check_page (0, 4, 0); - if (i370_short_branch(insn) || mvs_check_label (CODE_LABEL_NUMBER (operands[0]))) - { - return \"BL %l0\"; - } - mvs_check_page (0, 2, 4); - return \"L 14,=A(%l0)\;BLR 14\"; -}" - [(set_attr "length" "6")] -) - -; -; bltu instruction pattern(s). -; - -(define_insn "bltu" - [(set (pc) - (if_then_else (ltu (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc))) -; (clobber (reg:SI 14)) - ] - "" - "* -{ - check_label_emit (); - mvs_check_page (0, 4, 0); - if (i370_short_branch(insn) || mvs_check_label (CODE_LABEL_NUMBER (operands[0]))) - { - return \"BL %l0\"; - } - mvs_check_page (0, 2, 4); - return \"L 14,=A(%l0)\;BLR 14\"; -}" - [(set_attr "length" "6")] -) - -; -; bge instruction pattern(s). -; - -(define_insn "bge" - [(set (pc) - (if_then_else (ge (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc))) -; (clobber (reg:SI 14)) - ] - "" - "* -{ - check_label_emit (); - mvs_check_page (0, 4, 0); - if (i370_short_branch(insn) || mvs_check_label (CODE_LABEL_NUMBER (operands[0]))) - { - return \"BNL %l0\"; - } - mvs_check_page (0, 2, 4); - return \"L 14,=A(%l0)\;BNLR 14\"; -}" - [(set_attr "length" "6")] -) - -; -; bgeu instruction pattern(s). -; - -(define_insn "bgeu" - [(set (pc) - (if_then_else (geu (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc))) -; (clobber (reg:SI 14)) - ] - "" - "* -{ - check_label_emit (); - mvs_check_page (0, 4, 0); - if (i370_short_branch(insn) || mvs_check_label (CODE_LABEL_NUMBER (operands[0]))) - { - return \"BNL %l0\"; - } - mvs_check_page (0, 2, 4); - return \"L 14,=A(%l0)\;BNLR 14\"; -}" - [(set_attr "length" "6")] -) - -; -; ble instruction pattern(s). -; - -(define_insn "ble" - [(set (pc) - (if_then_else (le (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc))) -; (clobber (reg:SI 14)) - ] - "" - "* -{ - check_label_emit (); - mvs_check_page (0, 4, 0); - if (i370_short_branch(insn) || mvs_check_label (CODE_LABEL_NUMBER (operands[0]))) - { - return \"BNH %l0\"; - } - mvs_check_page (0, 2, 4); - return \"L 14,=A(%l0)\;BNHR 14\"; -}" - [(set_attr "length" "6")] -) - -; -; bleu instruction pattern(s). -; - -(define_insn "bleu" - [(set (pc) - (if_then_else (leu (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc))) -; (clobber (reg:SI 14)) - ] - "" - "* -{ - check_label_emit (); - mvs_check_page (0, 4, 0); - if (i370_short_branch(insn) || mvs_check_label (CODE_LABEL_NUMBER (operands[0]))) - { - return \"BNH %l0\"; - } - mvs_check_page (0, 2, 4); - return \"L 14,=A(%l0)\;BNHR 14\"; -}" - [(set_attr "length" "6")] -) - -;; -;;- Negated conditional jump instructions. -;; - -(define_insn "" - [(set (pc) - (if_then_else (eq (cc0) - (const_int 0)) - (pc) - (label_ref (match_operand 0 "" "")))) -; (clobber (reg:SI 14)) - ] - "" - "* -{ - check_label_emit (); - mvs_check_page (0, 4, 0); - if (i370_short_branch(insn) || mvs_check_label (CODE_LABEL_NUMBER (operands[0]))) - { - return \"BNE %l0\"; - } - mvs_check_page (0, 2, 4); - return \"L 14,=A(%l0)\;BNER 14\"; -}" - [(set_attr "length" "6")] -) - -(define_insn "" - [(set (pc) - (if_then_else (ne (cc0) - (const_int 0)) - (pc) - (label_ref (match_operand 0 "" "")))) -; (clobber (reg:SI 14)) - ] - "" - "* -{ - check_label_emit (); - mvs_check_page (0, 4, 0); - if (i370_short_branch(insn) || mvs_check_label (CODE_LABEL_NUMBER (operands[0]))) - { - return \"BE %l0\"; - } - mvs_check_page (0, 2, 4); - return \"L 14,=A(%l0)\;BER 14\"; -}" - [(set_attr "length" "6")] -) - -(define_insn "" - [(set (pc) - (if_then_else (gt (cc0) - (const_int 0)) - (pc) - (label_ref (match_operand 0 "" "")))) -; (clobber (reg:SI 14)) - ] - "" - "* -{ - check_label_emit (); - mvs_check_page (0, 4, 0); - if (i370_short_branch(insn) || mvs_check_label (CODE_LABEL_NUMBER (operands[0]))) - { - return \"BNH %l0\"; - } - mvs_check_page (0, 2, 4); - return \"L 14,=A(%l0)\;BNHR 14\"; -}" - [(set_attr "length" "6")] -) - -(define_insn "" - [(set (pc) - (if_then_else (gtu (cc0) - (const_int 0)) - (pc) - (label_ref (match_operand 0 "" "")))) -; (clobber (reg:SI 14)) - ] - "" - "* -{ - check_label_emit (); - mvs_check_page (0, 4, 0); - if (i370_short_branch(insn) || mvs_check_label (CODE_LABEL_NUMBER (operands[0]))) - { - return \"BNH %l0\"; - } - mvs_check_page (0, 2, 4); - return \"L 14,=A(%l0)\;BNHR 14\"; -}" - [(set_attr "length" "6")] -) - -(define_insn "" - [(set (pc) - (if_then_else (lt (cc0) - (const_int 0)) - (pc) - (label_ref (match_operand 0 "" "")))) -; (clobber (reg:SI 14)) - ] - "" - "* -{ - check_label_emit (); - mvs_check_page (0, 4, 0); - if (i370_short_branch(insn) || mvs_check_label (CODE_LABEL_NUMBER (operands[0]))) - { - return \"BNL %l0\"; - } - mvs_check_page (0, 2, 4); - return \"L 14,=A(%l0)\;BNLR 14\"; -}" - [(set_attr "length" "6")] -) - -(define_insn "" - [(set (pc) - (if_then_else (ltu (cc0) - (const_int 0)) - (pc) - (label_ref (match_operand 0 "" "")))) -; (clobber (reg:SI 14)) - ] - "" - "* -{ - check_label_emit (); - mvs_check_page (0, 4, 0); - if (i370_short_branch(insn) || mvs_check_label (CODE_LABEL_NUMBER (operands[0]))) - { - return \"BNL %l0\"; - } - mvs_check_page (0, 2, 4); - return \"L 14,=A(%l0)\;BNLR 14\"; -}" - [(set_attr "length" "6")] -) - -(define_insn "" - [(set (pc) - (if_then_else (ge (cc0) - (const_int 0)) - (pc) - (label_ref (match_operand 0 "" "")))) -; (clobber (reg:SI 14)) - ] - "" - "* -{ - check_label_emit (); - mvs_check_page (0, 4, 0); - if (i370_short_branch(insn) || mvs_check_label (CODE_LABEL_NUMBER (operands[0]))) - { - return \"BL %l0\"; - } - mvs_check_page (0, 2, 4); - return \"L 14,=A(%l0)\;BLR 14\"; -}" - [(set_attr "length" "6")] -) - -(define_insn "" - [(set (pc) - (if_then_else (geu (cc0) - (const_int 0)) - (pc) - (label_ref (match_operand 0 "" "")))) -; (clobber (reg:SI 14)) - ] - "" - "* -{ - check_label_emit (); - mvs_check_page (0, 4, 0); - if (i370_short_branch(insn) || mvs_check_label (CODE_LABEL_NUMBER (operands[0]))) - { - return \"BL %l0\"; - } - mvs_check_page (0, 2, 4); - return \"L 14,=A(%l0)\;BLR 14\"; -}" - [(set_attr "length" "6")] -) - -(define_insn "" - [(set (pc) - (if_then_else (le (cc0) - (const_int 0)) - (pc) - (label_ref (match_operand 0 "" "")))) -; (clobber (reg:SI 14)) - ] - "" - "* -{ - check_label_emit (); - mvs_check_page (0, 4, 0); - if (i370_short_branch(insn) || mvs_check_label (CODE_LABEL_NUMBER (operands[0]))) - { - return \"BH %l0\"; - } - mvs_check_page (0, 2, 4); - return \"L 14,=A(%l0)\;BHR 14\"; -}" - [(set_attr "length" "6")] -) - -(define_insn "" - [(set (pc) - (if_then_else (leu (cc0) - (const_int 0)) - (pc) - (label_ref (match_operand 0 "" "")))) -; (clobber (reg:SI 14)) - ] - "" - "* -{ - check_label_emit (); - mvs_check_page (0, 4, 0); - if (i370_short_branch(insn) || mvs_check_label (CODE_LABEL_NUMBER (operands[0]))) - { - return \"BH %l0\"; - } - mvs_check_page (0, 2, 4); - return \"L 14,=A(%l0)\;BHR 14\"; -}" - [(set_attr "length" "6")] -) - -;; ============================================================== -;;- Subtract one and jump if not zero. -;; These insns seem to not be getting matched ... -;; XXX should fix this, as it would improve for loops - -(define_insn "" - [(set (pc) - (if_then_else - (ne (plus:SI (match_operand:SI 0 "register_operand" "+d") - (const_int -1)) - (const_int 0)) - (label_ref (match_operand 1 "" "")) - (pc))) - (set (match_dup 0) - (plus:SI (match_dup 0) - (const_int -1))) -; (clobber (reg:SI 14)) - ] - "" - "* -{ - check_label_emit (); - mvs_check_page (0, 4, 0); - if (mvs_check_label (CODE_LABEL_NUMBER (operands[1]))) - { - return \"BCT %0,%l1\"; - } - mvs_check_page (0, 2, 4); - return \"L 14,=A(%l1)\;BCTR %0,14\"; -}" - [(set_attr "length" "6")] -) - -(define_insn "" - [(set (pc) - (if_then_else - (eq (plus:SI (match_operand:SI 0 "register_operand" "+d") - (const_int -1)) - (const_int 0)) - (pc) - (label_ref (match_operand 1 "" "")))) - (set (match_dup 0) - (plus:SI (match_dup 0) - (const_int -1))) -; (clobber (reg:SI 14)) - ] - "" - "* -{ - check_label_emit (); - mvs_check_page (0, 4, 0); - if (mvs_check_label (CODE_LABEL_NUMBER (operands[1]))) - { - return \"BCT %0,%l1\"; - } - mvs_check_page (0, 2, 4); - return \"L 14,=A(%l1)\;BCTR %0,14\"; -}" - [(set_attr "length" "6")] -) - -;; ============================================================= -;;- Unconditional jump instructions. -;; - -; -; jump instruction pattern(s). -; - -(define_insn "jump" - [(set (pc) - (label_ref (match_operand 0 "" ""))) -; (clobber (reg:SI 14)) - ] - "" - "* -{ - check_label_emit (); - mvs_check_page (0, 4, 0); - if (i370_short_branch(insn) || mvs_check_label (CODE_LABEL_NUMBER (operands[0]))) - { - return \"B %l0\"; - } - mvs_check_page (0, 2, 4); - return \"L 14,=A(%l0)\;BR 14\"; -}" - [(set_attr "length" "6")] -) - -; -; indirect-jump instruction pattern(s). -; hack alert -- should check that displacement is < 4096 - -(define_insn "indirect_jump" - [(set (pc) (match_operand:SI 0 "general_operand" "rm"))] - "" - "* -{ - check_label_emit (); - if (REG_P (operands[0])) - { - mvs_check_page (0, 2, 0); - return \"BR %0\"; - } - mvs_check_page (0, 4, 0); - return \"B %0\"; -}" - [(set_attr "length" "4")] -) - -; -; tablejump instruction pattern(s). -; - -(define_insn "tablejump" - [(set (pc) - (match_operand:SI 0 "general_operand" "am")) - (use (label_ref (match_operand 1 "" ""))) -; (clobber (reg:SI 14)) - ] - "" - "* -{ - check_label_emit (); - if (REG_P (operands[0])) - { - mvs_check_page (0, 6, 0); - return \"BR %0\;DS 0F\"; - } - mvs_check_page (0, 10, 0); - return \"L 14,%0\;BR 14\;DS 0F\"; -}" - [(set_attr "length" "10")] -) - -;; -;;- Jump to subroutine. -;; -;; For the C/370 environment the internal functions, ie. sqrt, are called with -;; a non-standard form. So, we must fix it here. There's no BM like IBM. -;; -;; The ELF ABI is different from the C/370 ABI because we have a simpler, -;; more powerful way of dealing with structure-value returns. Basically, -;; we use R1 to point at structure returns (64-bit and larger returns) -;; and R11 to point at the args. Note that this handles double-precision -;; (64-bit) values just fine, in a less-kludged manner than the C/370 ABI. -;; Since R1 is used, we use R2 to pass the argument pointer to the routine. - -; -; call instruction pattern(s). -; -; We define four call instruction patterns below. The first two patterns, -; although general, end up matching (only?) calls through function pointers. -; The last two, which require a symbol-ref to match, get used for all -; ordinary subroutine calls. - -(define_insn "call" - [(call (match_operand:QI 0 "memory_operand" "m") - (match_operand:SI 1 "immediate_operand" "i")) - (clobber (reg:SI 2)) - ] - "" - "* -{ - static char temp[128]; - int i = STACK_POINTER_OFFSET; - CC_STATUS_INIT; - - check_label_emit (); -#ifdef TARGET_ELF_ABI - mvs_check_page (0, 10, 4); - sprintf ( temp, \"LA r2,%d(,sp)\;LA 15,%%0\;BASR 14,15\", i ); - return temp; -#else - if (mvs_function_check (XSTR (operands[0], 0))) - { - mvs_check_page (0, 22, 4); - sprintf ( temp, \"LA 1,136(,13)\;ST 1,%d(,13)\;LA 1,%d(,13)\;LA 15,%%0\;BALR 14,15\;LD 0,136(,13)\", - i - 4, i - 4 ); - } - else - { - mvs_check_page (0, 10, 4); - sprintf ( temp, \"LA 1,%d(,13)\;LA 15,%%0\;BALR 14,15\", i ); - } - return temp; -#endif -}" - [(set_attr "length" "22")] -) - -; -; call_value instruction pattern(s). -; - -(define_insn "call_value" - [(set (match_operand 0 "" "=rf") - (call (match_operand:QI 1 "memory_operand" "m") - (match_operand:SI 2 "general_operand" "i"))) - (clobber (reg:SI 2)) - ] - "" - "* -{ - static char temp[128]; - int i = STACK_POINTER_OFFSET; - CC_STATUS_INIT; - - check_label_emit (); -#ifdef TARGET_ELF_ABI - mvs_check_page (0, 10, 4); - sprintf ( temp, \"LA r2,%d(,sp)\;LA 15,%%1\;BASR 14,15\", i ); - return temp; -#else - if (mvs_function_check (XSTR (operands[1], 0))) - { - mvs_check_page (0, 22, 4); - sprintf ( temp, \"LA 1,136(,13)\;ST 1,%d(,13)\;LA 1,%d(,13)\;LA 15,%%1\;BALR 14,15\;LD 0,136(,13)\", - i - 4, i - 4 ); - } - else - { - mvs_check_page (0, 10, 4); - sprintf ( temp, \"LA 1,%d(,13)\;LA 15,%%1\;BALR 14,15\", i ); - } - return temp; -#endif -}" - [(set_attr "length" "22")] -) - -(define_insn "" - [(call (mem:QI (match_operand:SI 0 "" "i")) - (match_operand:SI 1 "general_operand" "g")) - (clobber (reg:SI 2)) - ] - "GET_CODE (operands[0]) == SYMBOL_REF" - "* -{ - static char temp[128]; - int i = STACK_POINTER_OFFSET; - CC_STATUS_INIT; - - check_label_emit (); -#ifdef TARGET_ELF_ABI - mvs_check_page (0, 10, 4); - sprintf ( temp, \"LA r2,%d(,sp)\;L 15,%%0\;BASR 14,15\", i ); - return temp; -#else - if (mvs_function_check (XSTR (operands[0], 0))) - { - mvs_check_page (0, 22, 4); - sprintf ( temp, \"LA 1,136(,13)\;ST 1,%d(,13)\;LA 1,%d(,13)\;L 15,%%0\;BALR 14,15\;LD 0,136(,13)\", - i - 4, i - 4 ); - } - else - { - mvs_check_page (0, 10, 4); - sprintf ( temp, \"LA 1,%d(,13)\;L 15,%%0\;BALR 14,15\", i ); - } - return temp; -#endif -}" - [(set_attr "length" "22")] -) - -(define_insn "" - [(set (match_operand 0 "" "=rf") - (call (mem:QI (match_operand:SI 1 "" "i")) - (match_operand:SI 2 "general_operand" "g"))) - (clobber (reg:SI 2)) - ] - "GET_CODE (operands[1]) == SYMBOL_REF" - "* -{ - static char temp[128]; - int i = STACK_POINTER_OFFSET; - CC_STATUS_INIT; - - check_label_emit (); -#ifdef TARGET_ELF_ABI - mvs_check_page (0, 10, 4); - sprintf ( temp, \"LA r2,%d(,sp)\;L 15,%%1\;BASR 14,15\", i ); - return temp; -#else - if (mvs_function_check (XSTR (operands[1], 0))) - { - mvs_check_page (0, 22, 4); - sprintf ( temp, \"LA 1,136(,13)\;ST 1,%d(,13)\;LA 1,%d(,13)\;L 15,%%1\;BALR 14,15\;LD 0,136(,13)\", - i - 4, i - 4 ); - } - else - { - mvs_check_page (0, 10, 4); - sprintf ( temp, \"LA 1,%d(,13)\;L 15,%%1\;BALR 14,15\", i ); - } - return temp; -#endif -}" - [(set_attr "length" "22")] -) - -;; -;; Call subroutine returning any type. -;; This instruction pattern appears to be used only by the -;; expand_builtin_apply definition for __builtin_apply. It is needed -;; since call_value might return an int in r15 or a float in fpr0 (r16) -;; and the builtin code calls abort since the reg is ambiguous. Well, -;; the below is probably broken anyway, we just want to go for now. -;; -(define_expand "untyped_call" -[(parallel [(call (match_operand 0 "" "") - (const_int 0)) - (match_operand 1 "" "") - (match_operand 2 "" "")])] - "" - " -{ - int i; - - emit_call_insn (GEN_CALL (operands[0], const0_rtx, const0_rtx, const0_rtx)); - - for (i = 0; i < XVECLEN (operands[2], 0); i++) - { - rtx set = XVECEXP (operands[2], 0, i); - emit_move_insn (SET_DEST (set), SET_SRC (set)); - } - - /* The optimizer does not know that the call sets the function value - registers we stored in the result block. We avoid problems by - claiming that all hard registers are used and clobbered at this - point. */ - /* emit_insn (gen_blockage ()); */ - - DONE; -}") - - -;; -;;- Miscellaneous instructions. -;; - -; -; nop instruction pattern(s). -; - -(define_insn "nop" - [(const_int 0)] - "" - "* -{ - check_label_emit (); - mvs_check_page (0, 2, 0); - return \"LR 0,0\"; -}" - [(set_attr "length" "2")] -) diff --git a/gcc/config/i370/linux.h b/gcc/config/i370/linux.h deleted file mode 100644 index f402fbd..0000000 --- a/gcc/config/i370/linux.h +++ /dev/null @@ -1,113 +0,0 @@ -/* Definitions of target machine for GNU compiler. System/370 version. - Copyright (C) 1989, 1993, 1995, 1996, 1997, 2003 - Free Software Foundation, Inc. - Contributed by Jan Stein (jan@cd.chalmers.se). - Modified for Linux/390 by Linas Vepstas (linas@linas.org) - -This file is part of GCC. - -GCC 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. - -GCC 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 GCC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - - -#define TARGET_VERSION fprintf (stderr, " (i370 GNU/Linux with ELF)"); - -/* Specify that we're generating code for a Linux port to 370 */ - -#define TARGET_ELF_ABI - -/* Target OS preprocessor built-ins. */ -#define TARGET_OS_CPP_BUILTINS() LINUX_TARGET_OS_CPP_BUILTINS() - -/* Options for this target machine. */ - -#define LIBGCC_SPEC "libgcc.a%s" - -#ifdef SOME_FUTURE_DAY - -#define CPP_SPEC "%{posix: -D_POSIX_SOURCE} %(cpp_sysv) %(cpp_endian_big) \ -%{mcall-linux: %(cpp_os_linux) } \ -%{!mcall-linux: %(cpp_os_default) }" - -#define LIB_SPEC "\ -%{mcall-linux: %(lib_linux) } \ -%{!mcall-linux:%(lib_default) }" - -#define STARTFILE_SPEC "\ -%{mcall-linux: %(startfile_linux) } \ -%{!mcall-linux: %(startfile_default) }" - -#define ENDFILE_SPEC "\ -%{mcall-linux: %(endfile_linux) } \ -%{!mcall-linux: %(endfile_default) }" - -/* GNU/Linux support. */ -#ifndef LIB_LINUX_SPEC -#define LIB_LINUX_SPEC "%{mnewlib: --start-group -llinux -lc --end-group } %{!mnewlib: -lc }" -#endif - -#ifndef STARTFILE_LINUX_SPEC -#define STARTFILE_LINUX_SPEC "\ -%{!shared: %{pg:gcrt1.o%s} %{!pg:%{p:gcrt1.o%s} %{!p:crt1.o%s}}} \ -%{mnewlib: ecrti.o%s} \ -%{!mnewlib: crti.o%s %{!shared:crtbegin.o%s} %{shared:crtbeginS.o%s}}" -#endif - -#ifndef ENDFILE_LINUX_SPEC -#define ENDFILE_LINUX_SPEC "\ -%{mnewlib: ecrtn.o%s} \ -%{!mnewlib: %{!shared:crtend.o%s} %{shared:crtendS.o%s} crtn.o%s}" -#endif - -#ifndef LINK_START_LINUX_SPEC -#define LINK_START_LINUX_SPEC "-Ttext 0x10000" -#endif - -#ifndef LINK_OS_LINUX_SPEC -#define LINK_OS_LINUX_SPEC "" -#endif - -#ifndef CPP_OS_LINUX_SPEC -#define CPP_OS_LINUX_SPEC "-D__unix__ -D__gnu_linux__ -D__linux__ \ -%{!ansi: -Dunix -Dlinux } \ --Asystem=unix -Asystem=linux" -#endif - -#ifndef CPP_OS_LINUX_SPEC -#define CPP_OS_LINUX_SPEC "" -#endif - - -/* Define any extra SPECS that the compiler needs to generate. */ -#undef SUBTARGET_EXTRA_SPECS -#define SUBTARGET_EXTRA_SPECS \ - { "lib_linux", LIB_LINUX_SPEC }, \ - { "lib_default", LIB_DEFAULT_SPEC }, \ - { "startfile_linux", STARTFILE_LINUX_SPEC }, \ - { "startfile_default", STARTFILE_DEFAULT_SPEC }, \ - { "endfile_linux", ENDFILE_LINUX_SPEC }, \ - { "endfile_default", ENDFILE_DEFAULT_SPEC }, \ - { "link_shlib", LINK_SHLIB_SPEC }, \ - { "link_target", LINK_TARGET_SPEC }, \ - { "link_start", LINK_START_SPEC }, \ - { "link_start_linux", LINK_START_LINUX_SPEC }, \ - { "link_os", LINK_OS_SPEC }, \ - { "link_os_linux", LINK_OS_LINUX_SPEC }, \ - { "link_os_default", LINK_OS_DEFAULT_SPEC }, \ - { "cpp_endian_big", CPP_ENDIAN_BIG_SPEC }, \ - { "cpp_os_linux", CPP_OS_LINUX_SPEC }, \ - { "cpp_os_default", CPP_OS_DEFAULT_SPEC }, - -#endif /* SOME_FUTURE_DAY */ diff --git a/gcc/config/i370/mvs.h b/gcc/config/i370/mvs.h deleted file mode 100644 index dfb4cba..0000000 --- a/gcc/config/i370/mvs.h +++ /dev/null @@ -1,49 +0,0 @@ -/* Definitions of target machine for GNU compiler. System/370 version. - Copyright (C) 1989, 1993, 1995, 1996, 1997, 2003 - Free Software Foundation, Inc. - Contributed by Jan Stein (jan@cd.chalmers.se). - Modified for OS/390 LanguageEnvironment C by Dave Pitts (dpitts@cozx.com) - -This file is part of GCC. - -GCC 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. - -GCC 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 GCC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -#define TARGET_VERSION printf (" (370/MVS)"); - -/* Specify that we're generating code for the Language Environment */ - -#define LE370 1 -#define TARGET_EBCDIC 1 -#define TARGET_HLASM 1 - -/* Options for the preprocessor for this target machine. */ - -#define CPP_SPEC "-trigraphs" - -/* Target OS preprocessor built-ins. */ -#define TARGET_OS_CPP_BUILTINS() \ - do { \ - builtin_define_std ("MVS"); \ - builtin_define_std ("mvs"); \ - MAYBE_LE370_MACROS(); \ - builtin_assert ("system=mvs"); \ - } while (0) - -#if defined(LE370) -# define MAYBE_LE370_MACROS() do {builtin_define_std ("LE370");} while (0) -#else -# define MAYBE_LE370_MACROS() -#endif diff --git a/gcc/config/i370/oe.h b/gcc/config/i370/oe.h deleted file mode 100644 index 088c043..0000000 --- a/gcc/config/i370/oe.h +++ /dev/null @@ -1,53 +0,0 @@ -/* Definitions of target machine for GNU compiler. System/370 version. - Copyright (C) 1989, 1993, 1995, 1996, 1997, 2003 - Free Software Foundation, Inc. - Contributed by Jan Stein (jan@cd.chalmers.se). - Modified for OS/390 OpenEdition by Dave Pitts (dpitts@cozx.com) - -This file is part of GCC. - -GCC 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. - -GCC 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 GCC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -#define TARGET_VERSION printf (" (370/OpenEdition)"); - -/* Specify that we're generating code for the Language Environment */ - -#define LE370 1 -#define LONGEXTERNAL 1 -#define TARGET_EBCDIC 1 -#define TARGET_HLASM 1 - -/* Options for the preprocessor for this target machine. */ - -#define CPP_SPEC "-trigraphs" - -/* Options for this target machine. */ - -#define LIB_SPEC "" -#define LIBGCC_SPEC "" -#define STARTFILE_SPEC "/usr/local/lib/gccmain.o" - -/* Target OS preprocessor built-ins. */ -#define TARGET_OS_CPP_BUILTINS() \ - do { \ - builtin_define_std ("unix"); \ - builtin_define_std ("UNIX"); \ - builtin_define_std ("openedition"); \ - builtin_define ("__i370__"); \ - builtin_assert ("system=openedition"); \ - builtin_assert ("system=unix"); \ - } while (0) - diff --git a/gcc/config/i370/t-i370 b/gcc/config/i370/t-i370 deleted file mode 100644 index fccd163..0000000 --- a/gcc/config/i370/t-i370 +++ /dev/null @@ -1,3 +0,0 @@ -i370-c.o: $(srcdir)/config/i370/i370-c.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ - $(TM_H) $(TREE_H) toplev.h $(CPPLIB_H) c-pragma.h $(TM_P_H) - $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $(srcdir)/config/i370/i370-c.c |