summaryrefslogtreecommitdiff
path: root/gnu/egcs/gcc/config/i370
diff options
context:
space:
mode:
authorMarc Espie <espie@cvs.openbsd.org>1999-05-26 13:38:57 +0000
committerMarc Espie <espie@cvs.openbsd.org>1999-05-26 13:38:57 +0000
commit0126e157b87f137fc08dc7f46f6c291b9d06ac5d (patch)
treef8555e3e504eb82b4cd3cba5cec20ae4ce8124ff /gnu/egcs/gcc/config/i370
parentff8e9a4356e55ed142306c3a375fa280800abc86 (diff)
egcs projects compiler system
Exact copy of the snapshot, except for the removal of texinfo/ gcc/ch/ libchill/
Diffstat (limited to 'gnu/egcs/gcc/config/i370')
-rw-r--r--gnu/egcs/gcc/config/i370/i370.c584
-rw-r--r--gnu/egcs/gcc/config/i370/i370.h1440
-rw-r--r--gnu/egcs/gcc/config/i370/i370.md4210
-rw-r--r--gnu/egcs/gcc/config/i370/t-i3704
-rw-r--r--gnu/egcs/gcc/config/i370/xm-i370.h53
5 files changed, 6291 insertions, 0 deletions
diff --git a/gnu/egcs/gcc/config/i370/i370.c b/gnu/egcs/gcc/config/i370/i370.c
new file mode 100644
index 00000000000..55189825540
--- /dev/null
+++ b/gnu/egcs/gcc/config/i370/i370.c
@@ -0,0 +1,584 @@
+/* Subroutines for insn-output.c for System/370.
+ Copyright (C) 1989, 1993, 1995, 1997 Free Software Foundation, Inc.
+ Contributed by Jan Stein (jan@cd.chalmers.se).
+ Modified for MVS C/370 by Dave Pitts (dpitts@nyx.cs.du.edu)
+
+This file is part of GNU CC.
+
+GNU CC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU CC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include "rtl.h"
+#include "regs.h"
+#include "hard-reg-set.h"
+#include "real.h"
+#include "insn-config.h"
+#include "conditions.h"
+#include "insn-flags.h"
+#include "output.h"
+#include "insn-attr.h"
+#include "flags.h"
+#include "recog.h"
+#ifdef sun
+#include <sys/types.h>
+#include <ctype.h>
+#endif
+#include <time.h>
+
+
+/* Label node, this structure is used to keep track of labels on the
+ current page. */
+typedef struct label_node
+ {
+ struct label_node *label_next;
+ int label_id;
+ int label_page;
+ }
+label_node_t;
+
+/* Is 1 when a label has been generated and the base register must be
+ reloaded. */
+int mvs_label_emitted = 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. */
+int 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;
+
+/* 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 char *mvs_function_table[MVS_FUNCTION_TABLE_LENGTH] =
+{
+ "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"
+};
+
+/* ASCII to EBCDIC conversion table. */
+#if defined(TARGET_EBCDIC) && !defined(HOST_EBCDIC)
+static unsigned char ascebc[256] =
+{
+ /*00 NL SH SX EX ET NQ AK BL */
+ 0x00, 0x01, 0x02, 0x03, 0x37, 0x2D, 0x2E, 0x2F,
+ /*08 BS HT LF VT FF CR SO SI */
+ 0x16, 0x05, 0x15, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
+ /*10 DL D1 D2 D3 D4 NK SN EB */
+ 0x10, 0x11, 0x12, 0x13, 0x3C, 0x3D, 0x32, 0x26,
+ /*18 CN EM SB EC FS GS RS US */
+ 0x18, 0x19, 0x3F, 0x27, 0x1C, 0x1D, 0x1E, 0x1F,
+ /*20 SP ! " # $ % & ' */
+ 0x40, 0x5A, 0x7F, 0x7B, 0x5B, 0x6C, 0x50, 0x7D,
+ /*28 ( ) * + , - . / */
+ 0x4D, 0x5D, 0x5C, 0x4E, 0x6B, 0x60, 0x4B, 0x61,
+ /*30 0 1 2 3 4 5 6 7 */
+ 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,
+ /*38 8 9 : ; < = > ? */
+ 0xF8, 0xF9, 0x7A, 0x5E, 0x4C, 0x7E, 0x6E, 0x6F,
+ /*40 @ A B C D E F G */
+ 0x7C, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
+ /*48 H I J K L M N O */
+ 0xC8, 0xC9, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6,
+ /*50 P Q R S T U V W */
+ 0xD7, 0xD8, 0xD9, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6,
+ /*58 X Y Z [ \ ] ^ _ */
+ 0xE7, 0xE8, 0xE9, 0xAD, 0xE0, 0xBD, 0x5F, 0x6D,
+ /*60 ` a b c d e f g */
+ 0x79, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
+ /*68 h i j k l m n o */
+ 0x88, 0x89, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96,
+ /*70 p q r s t u v w */
+ 0x97, 0x98, 0x99, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6,
+ /*78 x y z { | } ~ DL */
+ 0xA7, 0xA8, 0xA9, 0xC0, 0x4F, 0xD0, 0xA1, 0x07,
+ 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+ 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+ 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+ 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+ 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+ 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+ 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+ 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+ 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+ 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+ 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+ 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+ 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+ 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+ 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+ 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xFF
+};
+#endif
+
+/* EBCDIC to ASCII conversion table. */
+#if defined(HOST_EBCDIC) && !defined(TARGET_EBCDIC)
+unsigned char ebcasc[256] =
+{
+ /*00 NU SH SX EX PF HT LC DL */
+ 0x00, 0x01, 0x02, 0x03, 0x00, 0x09, 0x00, 0x7F,
+ /*08 SM VT FF CR SO SI */
+ 0x00, 0x00, 0x00, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
+ /*10 DE D1 D2 TM RS NL BS IL */
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x0A, 0x08, 0x00,
+ /*18 CN EM CC C1 FS GS RS US */
+ 0x18, 0x19, 0x00, 0x00, 0x1C, 0x1D, 0x1E, 0x1F,
+ /*20 DS SS FS BP LF EB EC */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x17, 0x1B,
+ /*28 SM C2 EQ AK BL */
+ 0x00, 0x00, 0x00, 0x00, 0x05, 0x06, 0x07, 0x00,
+ /*30 SY PN RS UC ET */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
+ /*38 C3 D4 NK SU */
+ 0x00, 0x00, 0x00, 0x00, 0x14, 0x15, 0x00, 0x1A,
+ /*40 SP */
+ 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*48 . < ( + | */
+ 0x00, 0x00, 0x00, 0x2E, 0x3C, 0x28, 0x2B, 0x7C,
+ /*50 & */
+ 0x26, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*58 ! $ * ) ; ^ */
+ 0x00, 0x00, 0x21, 0x24, 0x2A, 0x29, 0x3B, 0x5E,
+ /*60 - / */
+ 0x2D, 0x2F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*68 , % _ > ? */
+ 0x00, 0x00, 0x00, 0x2C, 0x25, 0x5F, 0x3E, 0x3F,
+ /*70 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*78 ` : # @ ' = " */
+ 0x00, 0x60, 0x3A, 0x23, 0x40, 0x27, 0x3D, 0x22,
+ /*80 a b c d e f g */
+ 0x00, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
+ /*88 h i { */
+ 0x68, 0x69, 0x00, 0x7B, 0x00, 0x00, 0x00, 0x00,
+ /*90 j k l m n o p */
+ 0x00, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70,
+ /*98 q r } */
+ 0x71, 0x72, 0x00, 0x7D, 0x00, 0x00, 0x00, 0x00,
+ /*A0 ~ s t u v w x */
+ 0x00, 0x7E, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
+ /*A8 y z [ */
+ 0x79, 0x7A, 0x00, 0x00, 0x00, 0x5B, 0x00, 0x00,
+ /*B0 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*B8 ] */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x5D, 0x00, 0x00,
+ /*C0 { A B C D E F G */
+ 0x7B, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
+ /*C8 H I */
+ 0x48, 0x49, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*D0 } J K L M N O P */
+ 0x7D, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50,
+ /*D8 Q R */
+ 0x51, 0x52, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*E0 \ S T U V W X */
+ 0x5C, 0x00, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
+ /*E8 Y Z */
+ 0x59, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*F0 0 1 2 3 4 5 6 7 */
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+ /*F8 8 9 */
+ 0x38, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF
+};
+#endif
+
+/* Map characters from one character set to another.
+ C is the character to be translated. */
+
+char
+mvs_map_char (c)
+ char c;
+{
+#if defined(TARGET_EBCDIC) && !defined(HOST_EBCDIC)
+ return ascebc[c];
+#else
+#if defined(HOST_EBCDIC) && !defined(TARGET_EBCDIC)
+ return ebcasc[c];
+#else
+ return c;
+#endif
+#endif
+}
+
+/* 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. */
+
+int
+check_label_emit (void)
+{
+ if (mvs_label_emitted)
+ {
+ mvs_label_emitted = 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. */
+
+int
+mvs_add_label (id)
+ int id;
+{
+ label_node_t *lp;
+
+ if (free_anchor)
+ {
+ lp = free_anchor;
+ free_anchor = lp->label_next;
+ }
+ else
+ {
+ lp = (label_node_t *) malloc (sizeof (label_node_t));
+ if (lp == 0)
+ {
+ fatal ("virtual memory exhausted\n");
+ abort ();
+ }
+ }
+ lp->label_id = id;
+ lp->label_page = mvs_page_num;
+ lp->label_next = label_anchor;
+ label_anchor = lp;
+}
+
+/* Check to see if the label is in the list. If 1 is returned then a load
+ and branch on register must be generated.
+ 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)
+ return 1;
+ }
+ return 0;
+}
+
+/* The label list for the current page freed by linking the list onto the free
+ label element chain. */
+
+int
+mvs_free_label (void)
+{
+ if (label_anchor)
+ {
+ if (free_anchor)
+ label_anchor->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. */
+
+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++;
+ fprintf (assembler_source, "\tBALR\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_free_label ();
+ mvs_page_code = code;
+ mvs_page_lit = lit;
+ return 1;
+ }
+ mvs_page_code += code;
+ mvs_page_lit += lit;
+ return 0;
+}
+
+/* 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)
+ 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;
+}
+
+
+/* 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;
+}
+
+
+/* Return 1 if the next instruction is an unsigned jump instruction.
+ INSN is the current instruction. */
+
+unsigned_jump_follows_p (insn)
+ register rtx insn;
+{
+ insn = NEXT_INSN (insn);
+ if (GET_CODE (insn) != JUMP_INSN)
+ return 0;
+
+ insn = XEXP (insn, 3);
+ if (GET_CODE (insn) != SET)
+ return 0;
+
+ if (GET_CODE (XEXP (insn, 0)) != PC)
+ return 0;
+
+ insn = XEXP (insn, 1);
+ if (GET_CODE (insn) != IF_THEN_ELSE)
+ return 0;
+
+ insn = XEXP (insn, 0);
+ return GET_CODE (insn) != GE && GET_CODE (insn) != GT
+ && GET_CODE (insn) != LE && GET_CODE (insn) != LT;
+}
+
+void
+i370_function_prolog (f, l)
+ FILE *f;
+ int l;
+{
+#if MACROPROLOGUE == 1
+ fprintf (f, "\tEDCPRLG USRDSAL=%d,BASEREG=%d\n",
+ STACK_POINTER_OFFSET + l - 120 +
+ current_function_outgoing_args_size, BASE_REGISTER);
+ 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);
+ mvs_page_code = 6;
+ mvs_page_lit = 4;
+ mvs_check_page (f, 0, 0);
+ function_base_page = mvs_page_num;
+#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;
+ int i;
+ 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, "$DSD%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\t$DSD%03d\n", function_label_index);
+ fprintf (f, "\tDS\tCL(120+8)\n");
+ fprintf (f, "\tORG\n");
+ fprintf (f, "\tDS\t0D\n");
+ fprintf (f, "$DSL%03d\tEQU\t*-$DSD%03d-8\n", function_label_index,
+ function_label_index);
+ fprintf (f, "\tDS\t0H\n");
+ assemble_name (f, mvs_function_name);
+ fprintf (f, "\tEQU\t*\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($DSL%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, "PG%d\tEQU\t*\n", mvs_page_num );
+ fprintf (f, "\tUSING\t*,%d\n", BASE_REGISTER);
+ fprintf (f, "\tLR\t11,1\n");
+ fprintf (f, "\tL\t%d,=A(PGT%d)\n", PAGE_REGISTER, mvs_page_num);
+ mvs_page_code = 4;
+ mvs_page_lit = 4;
+ mvs_check_page (f, 0, 0);
+ function_base_page = mvs_page_num;
+ function_first = 1;
+ function_label_index += 2;
+#endif /* MACROPROLOGUE */
+}
diff --git a/gnu/egcs/gcc/config/i370/i370.h b/gnu/egcs/gcc/config/i370/i370.h
new file mode 100644
index 00000000000..3c54acfd56e
--- /dev/null
+++ b/gnu/egcs/gcc/config/i370/i370.h
@@ -0,0 +1,1440 @@
+/* Definitions of target machine for GNU compiler. System/370 version.
+ Copyright (C) 1989, 1993, 1995, 1996, 1997 Free Software Foundation, Inc.
+ Contributed by Jan Stein (jan@cd.chalmers.se).
+ Modified for C/370 MVS by Dave Pitts (dpitts@nyx.cs.du.edu)
+
+This file is part of GNU CC.
+
+GNU CC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU CC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#define TARGET_VERSION printf (" (370/MVS)");
+
+/* Options for the preprocessor for this target machine. */
+
+#define CPP_SPEC "-trigraphs"
+
+/* Names to predefine in the preprocessor for this target machine. */
+
+#define CPP_PREDEFINES "-DGCC -Dgcc -DMVS -Dmvs -Asystem(mvs) -Acpu(i370) -Amachine(i370)"
+
+/* 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;
+
+/* True if a label has been emitted. */
+
+extern int mvs_label_emitted;
+
+/* The name of the current function. */
+
+extern char *mvs_function_name;
+
+/* The length of the function name malloc'd area. */
+
+extern int mvs_function_name_length;
+
+/* The amount of space used for outgoing arguments. */
+
+extern int current_function_outgoing_args_size;
+
+/* 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, "Generate char instructions"}, \
+ { "no-char-instructions", -1, "Do not generate char instructions"}, \
+ { "", TARGET_DEFAULT, NULL} }
+
+/* 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
+
+/* Number of bits in an addressable storage unit. */
+
+#define BITS_PER_UNIT 8
+
+/* Width in bits of a "word", which is the contents of a machine register. */
+
+#define BITS_PER_WORD 32
+
+/* Width of a word, in units (bytes). */
+
+#define UNITS_PER_WORD 4
+
+/* Width in bits of a pointer. See also the macro `Pmode' defined below. */
+
+#define POINTER_SIZE 32
+
+/* 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
+
+/* Define character mapping for cross-compiling. */
+
+#define TARGET_EBCDIC 1
+
+#ifdef HOST_EBCDIC
+#define MAP_CHARACTER(c) ((char)(c))
+#else
+#define MAP_CHARACTER(c) ((char)mvs_map_char (c))
+#endif
+
+/* Define maximum length of page minus page escape overhead. */
+
+#define MAX_MVS_PAGE_LENGTH 4080
+
+/* Define if special allocation order desired. */
+
+#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
+
+/* 1 for registers that have pervasive standard uses and are not available
+ for the register allocator. On the 370 under C/370, R13 is stack (DSA)
+ pointer, R12 is the TCA pointer, R3 is the base register, R4 is the page
+ origin table pointer and R11 is the arg pointer. */
+
+#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. */
+
+#define HARD_REGNO_NREGS(REGNO, MODE) \
+ ((REGNO) > 15 ? 1 : (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 or DF. */
+
+#define HARD_REGNO_MODE_OK(REGNO, MODE) \
+ ((REGNO) < 16 ? ((REGNO) & 1) == 0 || (MODE) != DImode \
+ : (MODE) == SFmode || (MODE) == DFmode)
+
+/* 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))
+
+/* Mark external references. */
+
+#define ENCODE_SECTION_INFO(decl) \
+ if (DECL_EXTERNAL (decl) && TREE_PUBLIC (decl)) \
+ SYMBOL_REF_FLAG (XEXP (DECL_RTL (decl), 0)) = 1;
+
+/* 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
+
+/* Register in which static-chain is passed to a function. */
+
+#define STATIC_CHAIN_REGNUM 10
+
+/* Register in which address to store a structure value is passed to
+ a function. */
+
+#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
+
+/* 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. */
+
+#define PREFERRED_RELOAD_CLASS(X, CLASS) \
+ (GET_CODE(X) == CONST_DOUBLE ? FP_REGS : \
+ GET_CODE(X) == CONST_INT ? 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. */
+
+#define CLASS_MAX_NREGS(CLASS, MODE) \
+ ((CLASS) == FP_REGS ? 1 : \
+ (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. */
+
+/* #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. */
+
+/* #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
+
+/* 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
+
+/* Define 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 15. */
+
+#define RET_REG(MODE) ((MODE) == DFmode || (MODE) == SFmode ? 16 : 15)
+
+/* On the 370 the return value is in R15 or R16. */
+
+#define FUNCTION_VALUE(VALTYPE, FUNC) \
+ gen_rtx(REG, TYPE_MODE (VALTYPE), RET_REG(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)
+
+/* This macro generates the assembly code for function entry.
+ All of the C/370 environment is preserved. */
+#define FUNCTION_PROLOGUE(FILE, LSIZE) i370_function_prolog ((FILE), (LSIZE));
+
+#define ASM_DECLARE_FUNCTION_NAME(FILE, NAME, DECL) \
+{ \
+ if (strlen (NAME) * 2 > 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; \
+ mvs_function_name = (char *) malloc (mvs_function_name_length); \
+ if (mvs_function_name == 0) \
+ { \
+ fatal ("virtual memory exceeded"); \
+ abort (); \
+ } \
+ } \
+ if (!strcmp (NAME, "main")) \
+ strcpy (mvs_function_name, "gccmain"); \
+ else \
+ strcpy (mvs_function_name, NAME); \
+}
+
+/* This macro generates the assembly code for function exit, on machines
+ that need it. If FUNCTION_EPILOGUE is not defined then individual
+ return instructions are generated for each return statement. Args are
+ same as for 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. */
+
+#if MACROEPILOGUE == 1
+#define FUNCTION_EPILOGUE(FILE, LSIZE) \
+{ \
+ int i; \
+ check_label_emit(); \
+ mvs_check_page (FILE,14,0); \
+ fprintf (FILE, "\tEDCEPIL\n"); \
+ mvs_page_num++; \
+ fprintf (FILE, "\tDS\t0F\n" ); \
+ fprintf (FILE, "\tLTORG\n"); \
+ fprintf (FILE, "\tDS\t0F\n"); \
+ fprintf (FILE, "PGT%d\tEQU\t*\n", function_base_page); \
+ mvs_free_label(); \
+ for ( i = function_base_page; i < mvs_page_num; i++ ) \
+ fprintf (FILE, "\tDC\tA(PG%d)\n", i); \
+}
+#else /* MACROEPILOGUE != 1 */
+#define FUNCTION_EPILOGUE(FILE, LSIZE) \
+{ \
+ int i; \
+ check_label_emit(); \
+ mvs_check_page (FILE,14,0); \
+ 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("); \
+ mvs_page_num++; \
+ assemble_name (FILE, mvs_function_name); \
+ fprintf (FILE, ")\n" ); \
+ fprintf (FILE, "\tDS\t0F\n" ); \
+ fprintf (FILE, "\tLTORG\n"); \
+ fprintf (FILE, "\tDS\t0F\n"); \
+ fprintf (FILE, "PGT%d\tEQU\t*\n", function_base_page); \
+ mvs_free_label(); \
+ for ( i = function_base_page; i < mvs_page_num; i++ ) \
+ fprintf (FILE, "\tDC\tA(PG%d)\n", i); \
+}
+#endif /* MACROEPILOGUE */
+
+
+/* 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 */
+
+#define TRAMPOLINE_TEMPLATE(FILE) \
+{ \
+ ASM_OUTPUT_SHORT (FILE, GEN_INT (0x05E0)); \
+ ASM_OUTPUT_SHORT (FILE, GEN_INT (0x5800 | STATIC_CHAIN_REGNUM << 4)); \
+ ASM_OUTPUT_SHORT (FILE, GEN_INT (0xE00A)); \
+ ASM_OUTPUT_SHORT (FILE, GEN_INT (0x58F0)); \
+ ASM_OUTPUT_SHORT (FILE, GEN_INT (0xE00E)); \
+ ASM_OUTPUT_SHORT (FILE, GEN_INT (0x07FF)); \
+ ASM_OUTPUT_SHORT (FILE, const0_rtx); \
+ ASM_OUTPUT_SHORT (FILE, const0_rtx); \
+ ASM_OUTPUT_SHORT (FILE, const0_rtx); \
+ ASM_OUTPUT_SHORT (FILE, 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); \
+}
+
+/* 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")
+
+/* 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. */
+
+/* #define HAVE_POST_INCREMENT 0 */
+/* #define HAVE_POST_DECREMENT 0 */
+
+/* #define HAVE_PRE_DECREMENT 0 */
+/* #define HAVE_PRE_INCREMENT 0 */
+
+/* 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_FLAG (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) && REG_OK_FOR_BASE_P (X)) \
+ REGS += 1; \
+ 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)
+
+/* 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. */
+
+#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 as C expression which evaluates to nonzero if the tablejump
+ instruction expects the table to contain offsets from the address of the
+ table.
+ Do not define this if the table should contain absolute addresses. */
+/* #define CASE_VECTOR_PC_RELATIVE 1 */
+
+/* Specify the tree operation to be used to convert reals to integers. */
+
+#define IMPLICIT_FIX_EXPR FIX_ROUND_EXPR
+
+/* 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
+
+/* This is the kind of divide that is easiest to do in the general case. */
+
+#define EASY_DIV_EXPR TRUNC_DIV_EXPR
+
+/* Max number of bytes we can move from memory to memory in one reasonably
+ fast instruction. */
+
+#define MOVE_MAX 256
+
+/* Define this if zero-extension is slow (more than one real instruction). */
+
+#define SLOW_ZERO_EXTEND
+
+/* 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)
+
+/* We assume that the store-condition-codes instructions store 0 for false
+ and some other value for true. This is the value stored for true. */
+
+/* #define STORE_FLAG_VALUE -1 */
+
+/* When a prototype says `char' or `short', really pass an `int'. */
+
+#define PROMOTE_PROTOTYPES
+
+/* 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
+
+/* Compute the cost of computing a constant rtl expression RTX whose
+ rtx-code is CODE. The body of this macro is a portion of a switch
+ statement. If the code is computed here, return it with a return
+ statement. Otherwise, break from the switch. */
+
+#define CONST_COSTS(RTX, CODE, OUTERCODE) \
+ case CONST_INT: \
+ if ((unsigned) INTVAL (RTX) < 0xfff) return 1; \
+ case CONST: \
+ case LABEL_REF: \
+ case SYMBOL_REF: \
+ return 2; \
+ case CONST_DOUBLE: \
+ return 4;
+
+/* 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. */
+
+#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 MULT: /* case UMULT: */ \
+ case DIV: case UDIV: case NEG: case ASHIFT: \
+ case ASHIFTRT: case AND: case IOR: case XOR: \
+ case ABS: case NOT: \
+ CC_STATUS_SET (XEXP (exp, 0), XEXP (exp, 1)); \
+ } \
+ } \
+ } \
+}
+
+
+#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 TEXT_SECTION_ASM_OP "* Program text area"
+#define DATA_SECTION_ASM_OP "* Program data area"
+#define INIT_SECTION_ASM_OP "* Program initialization area"
+#define CTOR_LIST_BEGIN /* NO OP */
+#define CTOR_LIST_END /* NO OP */
+
+/* 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" \
+}
+
+/* How to renumber registers for dbx and gdb. */
+
+#define DBX_REGISTER_NUMBER(REGNO) (REGNO)
+
+#define ASM_FILE_START(FILE) fputs ("\tCSECT\n", FILE);
+#define ASM_FILE_END(FILE) fputs ("\tEND\n", FILE);
+#define ASM_IDENTIFY_GCC(FILE)
+#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) /* NO OP */
+
+#define ASM_GLOBALIZE_LABEL(FILE, NAME) \
+{ fputs ("\tENTRY\t", FILE); assemble_name (FILE, NAME); fputs ("\n", FILE); }
+
+/* MVS externals are limited to 8 characters, upper case only.
+ The '_' is mapped to '@', except for MVS functions, then '#'. */
+
+#define MAX_MVS_LABEL_SIZE 8
+
+#define ASM_OUTPUT_LABELREF(FILE, NAME) \
+{ \
+ char *bp, ch, temp[MAX_MVS_LABEL_SIZE + 1]; \
+ if (strlen (NAME) > MAX_MVS_LABEL_SIZE) \
+ { \
+ strncpy (temp, NAME, MAX_MVS_LABEL_SIZE); \
+ temp[MAX_MVS_LABEL_SIZE] = '\0'; \
+ } \
+ else \
+ strcpy (temp,NAME); \
+ if (!strcmp (temp,"main")) \
+ strcpy (temp,"gccmain"); \
+ if (mvs_function_check (temp)) \
+ ch = '#'; \
+ else \
+ ch = '@'; \
+ for (bp = temp; *bp; bp++) \
+ { \
+ if (islower (*bp)) *bp = toupper (*bp); \
+ if (*bp == '_') *bp = ch; \
+ } \
+ fprintf (FILE, "%s", temp); \
+}
+
+#define ASM_GENERATE_INTERNAL_LABEL(LABEL, PREFIX, NUM) \
+ sprintf (LABEL, "*%s%d", PREFIX, NUM)
+
+/* Generate internal label. Since we can branch here from off page, we
+ must reload the base register. */
+
+#define ASM_OUTPUT_INTERNAL_LABEL(FILE, PREFIX, NUM) \
+{ \
+ if (!strcmp (PREFIX,"L")) \
+ { \
+ mvs_add_label(NUM); \
+ mvs_label_emitted = 1; \
+ } \
+ fprintf (FILE, "%s%d\tEQU\t*\n", PREFIX, NUM); \
+}
+
+/* Generate case label. */
+
+#define ASM_OUTPUT_CASE_LABEL(FILE, PREFIX, NUM, TABLE) \
+ fprintf (FILE, "%s%d\tEQU\t*\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, "\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) \
+ mvs_check_page (FILE, 4, 0); \
+ 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. */
+
+#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 is how to output an assembler line defining a `double' constant. */
+
+#define ASM_OUTPUT_DOUBLE(FILE, VALUE) \
+ fprintf (FILE, "\tDC\tD'%.18G'\n", (VALUE))
+
+/* This is how to output an assembler line defining a `float' constant. */
+
+#define ASM_OUTPUT_FLOAT(FILE, VALUE) \
+ fprintf (FILE, "\tDC\tE'%.9G'\n", (VALUE))
+
+/* This outputs an integer, if not a CONST_INT must be address constant. */
+
+#define ASM_OUTPUT_INT(FILE, EXP) \
+{ \
+ if (GET_CODE (EXP) == CONST_INT) \
+ { \
+ fprintf (FILE, "\tDC\tF'"); \
+ output_addr_const (FILE, EXP); \
+ fprintf (FILE, "'\n"); \
+ } \
+ else \
+ { \
+ fprintf (FILE, "\tDC\tA("); \
+ output_addr_const (FILE, EXP); \
+ fprintf (FILE, ")\n"); \
+ } \
+}
+
+/* This outputs a short integer. */
+
+#define ASM_OUTPUT_SHORT(FILE, EXP) \
+{ \
+ fprintf (FILE, "\tDC\tX'%04X'\n", INTVAL(EXP) & 0xFFFF); \
+}
+
+/* This outputs a byte sized integer. */
+
+#define ASM_OUTPUT_CHAR(FILE, EXP) \
+ fprintf (FILE, "\tDC\tX'%02X'\n", INTVAL (EXP) )
+
+#define ASM_OUTPUT_BYTE(FILE, VALUE) \
+ fprintf (FILE, "\tDC\tX'%02X'\n", VALUE)
+
+/* 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) \
+{ \
+ int i, j; \
+ int c; \
+ for (j = 0, i = 0; i < LEN; j++, i++) \
+ { \
+ c = PTR[i]; \
+ if (iscntrl (c) || c == '&') \
+ { \
+ if (j % MVS_ASCII_TEXT_LENGTH != 0 ) \
+ fprintf (FILE, "'\n"); \
+ j = -1; \
+ if (c == '&') c = MAP_CHARACTER (c); \
+ 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) \
+{ \
+ int s, 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) \
+{ \
+ 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); \
+}
+
+/* Store in OUTPUT a string (made with alloca) containing an
+ assembler-name for a local static variable named NAME.
+ LABELNO is an integer which is different for each call. */
+
+#define ASM_FORMAT_PRIVATE_NAME(OUTPUT, NAME, LABELNO) \
+{ \
+ (OUTPUT) = (char *) alloca (strlen ((NAME)) + 10); \
+ sprintf ((OUTPUT), "%s%d", (NAME), (LABELNO)); \
+}
+
+/* Define the parentheses used to group arithmetic operations
+ in assembler code. */
+
+#define ASM_OPEN_PAREN "("
+#define ASM_CLOSE_PAREN ")"
+
+/* Define results of standard character escape sequences. */
+
+#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
+
+/* Print operand X (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 X is null. */
+
+#define PRINT_OPERAND(FILE, X, CODE) \
+{ \
+ switch (GET_CODE (X)) \
+ { \
+ static char curreg[4]; \
+ case REG: \
+ if (CODE == 'N') \
+ strcpy (curreg, reg_names[REGNO (X) + 1]); \
+ else \
+ strcpy (curreg, reg_names[REGNO (X)]); \
+ fprintf (FILE, "%s", curreg); \
+ break; \
+ case MEM: \
+ { \
+ rtx addr = XEXP (X, 0); \
+ if (CODE == 'O') \
+ { \
+ if (GET_CODE (addr) == PLUS) \
+ fprintf (FILE, "%d", 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 (X, 0)); \
+ } \
+ break; \
+ case SYMBOL_REF: \
+ case LABEL_REF: \
+ mvs_page_lit += 4; \
+ if (SYMBOL_REF_FLAG (X)) fprintf (FILE, "=V("); \
+ else fprintf (FILE, "=A("); \
+ output_addr_const (FILE, X); \
+ fprintf (FILE, ")"); \
+ break; \
+ case CONST_INT: \
+ if (CODE == 'B') \
+ fprintf (FILE, "%d", INTVAL (X) & 0xff); \
+ else if (CODE == 'X') \
+ fprintf (FILE, "%02X", INTVAL (X) & 0xff); \
+ else if (CODE == 'h') \
+ fprintf (FILE, "%d", (INTVAL (X) << 16) >> 16); \
+ else if (CODE == 'H') \
+ { \
+ mvs_page_lit += 2; \
+ fprintf (FILE, "=H'%d'", (INTVAL (X) << 16) >> 16); \
+ } \
+ else \
+ { \
+ mvs_page_lit += 4; \
+ fprintf (FILE, "=F'%d'", INTVAL (X)); \
+ } \
+ break; \
+ case CONST_DOUBLE: \
+ if (GET_MODE (X) == DImode) \
+ { \
+ if (CODE == 'M') \
+ { \
+ mvs_page_lit += 4; \
+ fprintf (FILE, "=XL4'%08X'", CONST_DOUBLE_LOW (X)); \
+ } \
+ else if (CODE == 'L') \
+ { \
+ mvs_page_lit += 4; \
+ fprintf (FILE, "=XL4'%08X'", CONST_DOUBLE_HIGH (X)); \
+ } \
+ else \
+ { \
+ mvs_page_lit += 8; \
+ fprintf (FILE, "=XL8'%08X%08X'", CONST_DOUBLE_LOW (X), \
+ CONST_DOUBLE_HIGH (X)); \
+ } \
+ } \
+ else \
+ { \
+ union { double d; int i[2]; } u; \
+ u.i[0] = CONST_DOUBLE_LOW (X); \
+ u.i[1] = CONST_DOUBLE_HIGH (X); \
+ if (GET_MODE (X) == SFmode) \
+ { \
+ mvs_page_lit += 4; \
+ fprintf (FILE, "=E'%.9G'", u.d); \
+ } \
+ else \
+ { \
+ mvs_page_lit += 8; \
+ fprintf (FILE, "=D'%.18G'", u.d); \
+ } \
+ } \
+ break; \
+ case CONST: \
+ if (GET_CODE (XEXP (X, 0)) == PLUS \
+ && GET_CODE (XEXP (XEXP (X, 0), 0)) == SYMBOL_REF) \
+ { \
+ mvs_page_lit += 4; \
+ if (SYMBOL_REF_FLAG (XEXP (XEXP (X, 0), 0))) \
+ { \
+ fprintf (FILE, "=V("); \
+ ASM_OUTPUT_LABELREF (FILE, \
+ XSTR (XEXP (XEXP (X, 0), 0), 0)); \
+ fprintf (FILE, ")\n\tA\t%s,=F'%d'", curreg, \
+ INTVAL (XEXP (XEXP (X, 0), 1))); \
+ } \
+ else \
+ { \
+ fprintf (FILE, "=A("); \
+ output_addr_const (FILE, X); \
+ fprintf (FILE, ")"); \
+ } \
+ } \
+ else \
+ { \
+ mvs_page_lit += 4; \
+ fprintf (FILE, "=F'"); \
+ output_addr_const (FILE, X); \
+ 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_FLAG (ADDR)) fprintf (FILE, "=V("); \
+ else fprintf (FILE, "=A("); \
+ output_addr_const (FILE, ADDR); \
+ fprintf (FILE, ")"); \
+ break; \
+ } \
+}
diff --git a/gnu/egcs/gcc/config/i370/i370.md b/gnu/egcs/gcc/config/i370/i370.md
new file mode 100644
index 00000000000..16e2c95dc76
--- /dev/null
+++ b/gnu/egcs/gcc/config/i370/i370.md
@@ -0,0 +1,4210 @@
+;;- Machine description for GNU compiler -- System/370 version.
+;; Copyright (C) 1989, 93, 94, 95, 97, 1999 Free Software Foundation, Inc.
+;; Contributed by Jan Stein (jan@cd.chalmers.se).
+;; Modified for MVS C/370 by Dave Pitts (dpitts@nyx.cs.du.edu)
+
+;; This file is part of GNU CC.
+
+;; GNU CC is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+
+;; GNU CC is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU CC; see the file COPYING. If not, write to
+;; the Free Software Foundation, 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;;- cpp macro #define NOTICE_UPDATE_CC in file tm.h handles condition code
+;;- updates for most instructions.
+
+;;
+;; 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).
+;;
+;; Special formats used for outputting 370 instructions.
+;;
+;; %B -- Print a constant byte integer.
+;; %H -- Print a signed 16-bit constant.
+;; %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.
+;;
+;; 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.
+;;
+
+;;
+;;- 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\";
+}")
+
+;
+; 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\";
+}")
+
+;
+; 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'\";
+}")
+
+;
+; 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]))
+ {
+ mvs_check_page (0, 4, 4);
+ return \"N %0,=X'000000FF'\";
+ }
+ mvs_check_page (0, 4, 0);
+ return \"CLI %0,0\";
+}")
+
+(define_insn "tstqi"
+ [(set (cc0)
+ (match_operand:QI 0 "register_operand" "d"))]
+ ""
+ "*
+{
+ check_label_emit ();
+ if (unsigned_jump_follows_p (insn))
+ {
+ mvs_check_page (0, 4, 4);
+ return \"N %0,=X'000000FF'\";
+ }
+ mvs_check_page (0, 8, 0);
+ return \"SLL %0,24\;SRA %0,24\";
+}")
+
+;
+; 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\";
+}")
+
+;
+; 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\";
+}")
+
+;;
+;;- 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\";
+}")
+
+;
+; cmphi instruction pattern(s).
+;
+
+(define_insn "cmphi"
+ [(set (cc0)
+ (compare (match_operand:HI 0 "register_operand" "d")
+ (match_operand:HI 1 "general_operand" "")))]
+ ""
+ "*
+{
+ 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\";
+}")
+
+;
+; cmpqi instruction pattern(s).
+;
+
+(define_insn ""
+ [(set (cc0)
+ (compare (match_operand:QI 0 "r_or_s_operand" "g")
+ (match_operand:QI 1 "r_or_s_operand" "g")))]
+ "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,=FL1'%B1'\";
+ }
+ 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,=FL1'%B0'\";
+ }
+ 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\";
+}")
+
+(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 (REG_P (operands[1]))
+ {
+ mvs_check_page (0, 4, 0);
+ return \"CLM %0,1,%1\";
+ }
+ if (GET_CODE (operands[1]) == CONST_INT)
+ {
+ mvs_check_page (0, 4, 1);
+ return \"CLM %0,1,=FL1'%B1'\";
+ }
+ 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\";
+}")
+
+;
+; 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\";
+}")
+
+;
+; 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\";
+}")
+
+;
+; cmpstrsi instruction pattern(s).
+;
+
+(define_expand "cmpstrsi"
+ [(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
+ {
+ rtx reg1 = gen_reg_rtx (DImode);
+ rtx reg2 = gen_reg_rtx (DImode);
+ rtx subreg = gen_rtx (SUBREG, SImode, reg1, 1);
+
+ emit_insn (gen_rtx (SET, VOIDmode, subreg, operands[3]));
+ emit_insn (gen_rtx (SET, VOIDmode, gen_rtx (SUBREG, SImode, reg2, 1),
+ subreg));
+ emit_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (5,
+ gen_rtx (SET, VOIDmode, operands[0],
+ gen_rtx (COMPARE, VOIDmode, op1, op2)),
+ gen_rtx (USE, VOIDmode, reg1),
+ gen_rtx (USE, VOIDmode, reg2),
+ gen_rtx (CLOBBER, VOIDmode, reg1),
+ gen_rtx (CLOBBER, VOIDmode, 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\";
+}")
+
+; Compare a block that is larger than 255 bytes in length.
+
+(define_insn ""
+ [(set (match_operand:SI 0 "register_operand" "d")
+ (compare (match_operand:BLK 1 "general_operand" "m")
+ (match_operand:BLK 2 "general_operand" "m")))
+ (use (match_operand:DI 3 "register_operand" "d"))
+ (use (match_operand:DI 4 "register_operand" "d"))
+ (clobber (match_dup 3))
+ (clobber (match_dup 4))]
+ ""
+ "*
+{
+ check_label_emit ();
+ mvs_check_page (0, 26, 0);
+ return \"LA %3,%1\;LA %4,%2\;LA %0,1\;CLCL %3,%4\;BH *+12\;BL *+6\;SLR %0,%0\;LNR %0,%0\";
+}")
+
+;;
+;;- 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"))]
+ "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\";
+ }
+ 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),%1\";
+}")
+
+(define_insn "movdi"
+ [(set (match_operand:DI 0 "general_operand" "=dm")
+ (match_operand:DI 1 "general_operand" "dim*fF"))]
+ ""
+ "*
+{
+ 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\";
+ }
+ 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\";
+}")
+
+;
+; movsi instruction pattern(s).
+;
+
+(define_insn ""
+ [(set (match_operand:SI 0 "r_or_s_operand" "=dm,dm")
+ (match_operand:SI 1 "r_or_s_operand" "dim,*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\";
+ }
+ 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\";
+}")
+
+(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\";
+ }
+ 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\";
+}")
+
+;(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_FLAG (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_FLAG (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\";
+ }
+ 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\";
+}")
+
+(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\";
+ }
+ 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\";
+}")
+
+;
+; 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)
+ {
+ mvs_check_page (0, 4, 0);
+ return \"LA %0,%c1\";
+ }
+ 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\";
+}")
+
+(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)
+ {
+ mvs_check_page (0, 4, 0);
+ return \"LA %0,%c1\";
+ }
+ 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\";
+}")
+
+;
+; movestrictqi instruction pattern(s).
+;
+
+(define_insn "movestrictqi"
+ [(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\";
+}")
+
+;
+; 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\";
+}")
+
+(define_insn "movestricthi"
+ [(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\";
+}")
+
+;
+; 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"))]
+ "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)\";
+ }
+ 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\";
+}")
+
+(define_insn "movdf"
+ [(set (match_operand:DF 0 "general_operand" "=f,fm,m,*d")
+ (match_operand:DF 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 \"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)\";
+ }
+ 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\";
+}")
+
+;
+; 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"))]
+ "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)\";
+ }
+ 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\";
+}")
+
+(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\";
+}")
+
+;
+; movstrsi instruction pattern(s).
+;
+
+(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 = change_address (operands[0], VOIDmode,
+ 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 = change_address (operands[1], VOIDmode,
+ 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
+ {
+ rtx reg1 = gen_reg_rtx (DImode);
+ rtx reg2 = gen_reg_rtx (DImode);
+ rtx subreg = gen_rtx (SUBREG, SImode, reg1, 1);
+
+ emit_insn (gen_rtx (SET, VOIDmode, subreg, operands[2]));
+ emit_insn (gen_rtx (SET, VOIDmode, gen_rtx (SUBREG, SImode, reg2, 1),
+ subreg));
+ emit_insn (gen_rtx (PARALLEL, VOIDmode,
+ gen_rtvec (5,
+ gen_rtx (SET, VOIDmode, op0, op1),
+ gen_rtx (USE, VOIDmode, reg1),
+ gen_rtx (USE, VOIDmode, reg2),
+ gen_rtx (CLOBBER, VOIDmode, reg1),
+ gen_rtx (CLOBBER, VOIDmode, 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\";
+}")
+
+; Move a block that is larger than 255 bytes in length.
+
+(define_insn ""
+ [(set (match_operand:BLK 0 "general_operand" "=m")
+ (match_operand:BLK 1 "general_operand" "m"))
+ (use (match_operand:DI 2 "register_operand" "d"))
+ (use (match_operand:DI 3 "register_operand" "d"))
+ (clobber (match_dup 2))
+ (clobber (match_dup 3))]
+ ""
+ "*
+{
+ check_label_emit ();
+ mvs_check_page (0, 10, 0);
+ return \"LA %2,%0\;LA %3,%1\;MVCL %2,%3\";
+}")
+
+;;
+;;- Conversion instructions.
+;;
+
+;
+; extendsidi2 instruction pattern(s).
+;
+
+(define_expand "extendsidi2"
+ [(set (match_operand:DI 0 "general_operand" "")
+ (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_INT (32))));
+ }
+ else
+ {
+ if (INTVAL (operands[1]) < 0)
+ {
+ emit_insn (gen_rtx (SET, VOIDmode,
+ operand_subword (operands[0], 0, 1, DImode),
+ GEN_INT (-1)));
+ }
+ else
+ {
+ emit_insn (gen_rtx (SET, VOIDmode,
+ operand_subword (operands[0], 0, 1, DImode),
+ GEN_INT (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, 2, 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\";
+ }
+ 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 \"SLL %1,16\;SRA %1,16\;ST %1,%0\";
+}")
+
+;
+; 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]))
+ {
+ 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\";
+}")
+
+;
+; 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]))
+ {
+ 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\";
+}")
+
+;
+; zero_extendsidi2 instruction pattern(s).
+;
+
+(define_expand "zero_extendsidi2"
+ [(set (match_operand:DI 0 "general_operand" "")
+ (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_INT (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 ();
+ CC_STATUS_SET (operands[0], operands[1]);
+ mvs_check_page (0, 4, 4);
+ return \"N %1,=X'0000FFFF'\";
+}")
+
+;
+; 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]))
+ {
+ CC_STATUS_SET (operands[0], operands[1]);
+ mvs_check_page (0, 4, 4);
+ return \"N %0,=X'000000FF'\";
+ }
+ if (GET_CODE (operands[1]) == CONST_INT)
+ {
+ mvs_check_page (0, 4, 0);
+ return \"LA %0,%c1\";
+ }
+ CC_STATUS_INIT;
+ mvs_check_page (0, 8, 0);
+ return \"SLR %0,%0\;IC %0,%1\";
+}")
+
+;
+; 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]))
+ {
+ CC_STATUS_SET (operands[0], operands[1]);
+ mvs_check_page (0, 4, 4);
+ return \"N %0,=X'000000FF'\";
+ }
+ if (GET_CODE (operands[1]) == CONST_INT)
+ {
+ mvs_check_page (0, 4, 0);
+ return \"LA %0,%c1\";
+ }
+ CC_STATUS_INIT;
+ mvs_check_page (0, 8, 0);
+ return \"SLR %0,%0\;IC %0,%1\";
+}")
+
+;
+; 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\";
+}")
+
+;
+; 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)\";
+}")
+
+;
+; floatsidf2 instruction pattern(s).
+;
+; 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;
+ mvs_check_page (0, 16, 8);
+ return \"ST %1,508(,12)\;XI 508(12),128\;LD %0,504(,12)\;SD %0,=XL8'4E00000080000000'\";
+}")
+
+;
+; 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\";
+}")
+
+;
+; 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\";
+}")
+
+;;
+;;- 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_INT (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 "" "")))]
+ ""
+ "*
+{
+ 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\";
+}")
+
+;
+; 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;
+ mvs_check_page (0, 4, 0);
+ return \"LA %0,%c2(,%1)\";
+}")
+
+; 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)
+ {
+ mvs_check_page (0, 4, 0);
+ return \"LA %0,%c2(,%1)\";
+ }
+ if (REGNO (operands[1]) == REGNO (operands[0]))
+ {
+ mvs_check_page (0, 4, 0);
+ return \"A %0,%2\";
+ }
+ mvs_check_page (0, 6, 0);
+ return \"L %0,%2\;AR %0,%1\";
+}")
+
+(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;
+ mvs_check_page (0, 2, 0);
+ return \"BCTR %0,0\";
+ }
+ }
+ mvs_check_page (0, 4, 0);
+ return \"A %0,%2\";
+}")
+
+;
+; 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;
+ 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\";
+}")
+
+;
+; 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;
+ mvs_check_page (0, 4, 0);
+ if (REG_P (operands[2]))
+ return \"LA %0,0(%1,%2)\";
+ return \"LA %0,%B2(,%1)\";
+}")
+
+;
+; 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\";
+}")
+
+;
+; 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\";
+}")
+
+;;
+;;- 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_INT (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 "" "")))]
+ ""
+ "*
+{
+ 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\";
+}")
+
+;
+; 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;
+ mvs_check_page (0, 2, 0);
+ return \"BCTR %0,0\";
+ }
+ mvs_check_page (0, 4, 0);
+ return \"S %0,%2\";
+}")
+
+;
+; 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;
+ 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\";
+}")
+
+;
+; 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 ();
+ CC_STATUS_INIT;
+ mvs_check_page (0, 2, 0);
+ return \"SR %0,%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\";
+}")
+
+;
+; 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\";
+}")
+
+;;
+;;- 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);
+
+ emit_insn (gen_rtx (SET, VOIDmode,
+ gen_rtx (SUBREG, SImode, r, 1), operands[1]));
+ emit_insn (gen_rtx (SET, VOIDmode, r,
+ gen_rtx (MULT, SImode, r, operands[2])));
+ emit_insn (gen_rtx (SET, VOIDmode, operands[0],
+ gen_rtx (SUBREG, SImode, r, 1)));
+ }
+ DONE;
+}")
+
+(define_insn ""
+ [(set (match_operand:SI 0 "register_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\";
+}")
+
+(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" "g")))]
+ ""
+ "*
+{
+ 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\";
+}")
+
+;
+; 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\";
+}")
+
+;
+; 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\";
+}")
+
+;;
+;;- 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, SImode, r, operands[2])));
+ emit_insn (gen_rtx (SET, VOIDmode, operands[0],
+ gen_rtx (SUBREG, SImode, r, 1)));
+ 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, 1);
+
+
+ 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, SImode, 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_jump_insn (gen_beq (label1));
+ emit_insn (gen_rtx (SET, VOIDmode, dr,
+ gen_rtx (LSHIFTRT, DImode, dr,
+ GEN_INT (32))));
+ emit_insn (gen_rtx (SET, VOIDmode, dr,
+ gen_rtx (DIV, SImode, 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" "")))]
+ ""
+ "*
+{
+ 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\";
+}")
+
+;
+; 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\";
+}")
+
+;
+; 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\";
+}")
+
+;;
+;;- 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, SImode, 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);
+ rtx dr_1 = gen_rtx (SUBREG, SImode, dr, 1);
+
+ 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_INT (32))));
+ emit_insn (gen_rtx (SET, VOIDmode, dr,
+ gen_rtx (MOD, SImode, 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_INT (32))));
+ emit_insn (gen_rtx (SET, VOIDmode, dr, gen_rtx (MOD, SImode, 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" "")))]
+ ""
+ "*
+{
+ 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\";
+}")
+
+;;
+;;- 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 ();
+ 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\";
+ }
+ CC_STATUS_INIT;
+ mvs_check_page (0, 6, 0);
+ return \"NC %O0(4,%R0),%2\";
+}")
+
+(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 ();
+ 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\";
+}")
+
+;
+; 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 ();
+ 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\";
+ }
+ CC_STATUS_INIT;
+ 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\";
+}")
+
+(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 ();
+ 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\";
+}")
+
+;
+; 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;
+ 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\";
+}")
+
+(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;
+ 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\";
+}")
+
+;;
+;;- 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,mi")))]
+ "TARGET_CHAR_INSTRUCTIONS"
+ "*
+{
+ check_label_emit ();
+ 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\";
+ }
+ CC_STATUS_INIT;
+ mvs_check_page (0, 6, 0);
+ return \"OC %O0(4,%R0),%2\";
+}")
+
+(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 ();
+ 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\";
+}")
+
+;
+; 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 ();
+ 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\";
+ }
+ CC_STATUS_INIT;
+ if (GET_CODE (operands[2]) == CONST_INT)
+ {
+ mvs_check_page (0, 6, 0);
+ return \"OC %O0(2,%R0),%H2\";
+ }
+ mvs_check_page (0, 6, 0);
+ return \"OC %O0(2,%R0),%2\";
+}")
+
+(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 ();
+ 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\";
+}")
+
+;
+; 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;
+ 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\";
+ }
+ CC_STATUS_INIT;
+ 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\";
+}")
+
+(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;
+ 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\";
+}")
+
+;;
+;;- 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 ();
+ 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\";
+ }
+ CC_STATUS_INIT;
+ mvs_check_page (0, 6, 0);
+ return \"XC %O0(4,%R0),%2\";
+}")
+
+(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 ();
+ 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\";
+}")
+
+;
+; 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 ();
+ 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\";
+ }
+ CC_STATUS_INIT;
+ 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\";
+}")
+
+(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 ();
+ 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\";
+}")
+
+;
+; 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;
+ 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\";
+}")
+
+(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;
+ 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\";
+}")
+
+;;
+;;- 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\";
+}")
+
+;
+; 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\";
+}")
+
+;
+; 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\";
+}")
+
+;
+; 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\";
+}")
+
+;;
+;;- 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\";
+}")
+
+;
+; 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\";
+}")
+
+;
+; 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\";
+}")
+
+;
+; 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\";
+}")
+
+;;
+;;- 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 ();
+ 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'\";
+}")
+
+(define_insn "one_cmplsi2"
+ [(set (match_operand:SI 0 "general_operand" "=d")
+ (not:SI (match_operand:SI 1 "general_operand" "0")))]
+ ""
+ "*
+{
+ check_label_emit ();
+ mvs_check_page (0, 4, 4);
+ return \"X %0,=F'-1'\";
+}")
+
+;
+; 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 ();
+ 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(2,%R0),=X'FFFF'\";
+}")
+
+(define_insn "one_cmplhi2"
+ [(set (match_operand:HI 0 "general_operand" "=d")
+ (not:HI (match_operand:HI 1 "general_operand" "0")))]
+ ""
+ "*
+{
+ check_label_emit ();
+ mvs_check_page (0, 4, 4);
+ return \"X %0,=F'-1'\";
+}")
+
+;
+; 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;
+ 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\";
+}")
+
+(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;
+ mvs_check_page (0, 4, 4);
+ return \"X %0,=F'-1'\";
+}")
+
+;;
+;;- 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 ();
+ CC_STATUS_INIT;
+ mvs_check_page (0, 4, 0);
+ if (REG_P (operands[2]))
+ return \"SLDA %0,0(%2)\";
+ return \"SLDA %0,%c2\";
+}")
+
+;
+; 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 ();
+ mvs_check_page (0, 4, 0);
+ if (REG_P (operands[2]))
+ return \"SRDA %0,0(%2)\";
+ return \"SRDA %0,%c2\";
+}")
+
+;
+; 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 ();
+ CC_STATUS_INIT;
+ mvs_check_page (0, 4, 0);
+ if (REG_P (operands[2]))
+ return \"SLL %0,0(%2)\";
+ return \"SLL %0,%c2\";
+}")
+
+;
+; 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 ();
+ mvs_check_page (0, 4, 0);
+ if (REG_P (operands[2]))
+ return \"SRA %0,0(%2)\";
+ return \"SRA %0,%c2\";
+}")
+
+;
+; 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\";
+}")
+
+;
+; 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, 4, 0);
+ if (REG_P (operands[2]))
+ return \"SLL %0,16\;SRA %0,16(%2)\";
+ return \"SLL %0,16\;SRA %0,16+%c2\";
+}")
+
+;
+; 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 ();
+ CC_STATUS_INIT;
+ mvs_check_page (0, 4, 0);
+ if (REG_P (operands[2]))
+ return \"SLL %0,0(%2)\";
+ return \"SLL %0,%c2\";
+}")
+
+;
+; 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\";
+}")
+
+;;
+;;- 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\";
+}")
+
+
+;
+; 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\";
+}")
+
+;
+; 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;
+ if (REG_P (operands[2]))
+ {
+ mvs_check_page (0, 8, 4);
+ return \"N %0,=X'0000FFFF'\;SRL %0,0(%2)\";
+ }
+ mvs_check_page (0, 8, 4);
+ return \"N %0,=X'0000FFFF'\;SRL %0,%c2\";
+}")
+
+;
+; 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;
+ mvs_check_page (0, 8, 4);
+ if (REG_P (operands[2]))
+ return \"N %0,=X'000000FF'\;SRL %0,0(%2)\";
+ return \"N %0,=X'000000FF'\;SRL %0,%c2\";
+}")
+
+;;
+;;- 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)))]
+ ""
+ "*
+{
+ check_label_emit ();
+ if (!mvs_check_label (CODE_LABEL_NUMBER (operands[0])))
+ {
+ mvs_check_page (0, 6, 4);
+ return \"L 14,=A(%l0)\;BER 14\";
+ }
+ if (mvs_check_page (0, 4, 0))
+ {
+ mvs_check_page (0, 2, 4);
+ return \"L 14,=A(%l0)\;BER 14\";
+ }
+ return \"BE %l0\";
+}")
+
+;
+; bne instruction pattern(s).
+;
+
+(define_insn "bne"
+ [(set (pc)
+ (if_then_else (ne (cc0)
+ (const_int 0))
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ "*
+{
+ check_label_emit ();
+ if (!mvs_check_label (CODE_LABEL_NUMBER (operands[0])))
+ {
+ mvs_check_page (0, 6, 4);
+ return \"L 14,=A(%l0)\;BNER 14\";
+ }
+ if (mvs_check_page (0, 4, 0))
+ {
+ mvs_check_page (0, 2, 4);
+ return \"L 14,=A(%l0)\;BNER 14\";
+ }
+ return \"BNE %l0\";
+}")
+
+;
+; bgt instruction pattern(s).
+;
+
+(define_insn "bgt"
+ [(set (pc)
+ (if_then_else (gt (cc0)
+ (const_int 0))
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ "*
+{
+ check_label_emit ();
+ if (!mvs_check_label (CODE_LABEL_NUMBER (operands[0])))
+ {
+ mvs_check_page (0, 6, 4);
+ return \"L 14,=A(%l0)\;BHR 14\";
+ }
+ if (mvs_check_page (0, 4, 0))
+ {
+ mvs_check_page (0, 2, 4);
+ return \"L 14,=A(%l0)\;BHR 14\";
+ }
+ return \"BH %l0\";
+}")
+
+;
+; bgtu instruction pattern(s).
+;
+
+(define_insn "bgtu"
+ [(set (pc)
+ (if_then_else (gtu (cc0)
+ (const_int 0))
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ "*
+{
+ check_label_emit ();
+ if (!mvs_check_label (CODE_LABEL_NUMBER (operands[0])))
+ {
+ mvs_check_page (0, 6, 4);
+ return \"L 14,=A(%l0)\;BHR 14\";
+ }
+ if (mvs_check_page (0, 4, 0))
+ {
+ mvs_check_page (0, 2, 4);
+ return \"L 14,=A(%l0)\;BHR 14\";
+ }
+ return \"BH %l0\";
+}")
+
+;
+; blt instruction pattern(s).
+;
+
+(define_insn "blt"
+ [(set (pc)
+ (if_then_else (lt (cc0)
+ (const_int 0))
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ "*
+{
+ check_label_emit ();
+ if (!mvs_check_label (CODE_LABEL_NUMBER (operands[0])))
+ {
+ mvs_check_page (0, 6, 4);
+ return \"L 14,=A(%l0)\;BLR 14\";
+ }
+ if (mvs_check_page (0, 4, 0))
+ {
+ mvs_check_page (0, 2, 4);
+ return \"L 14,=A(%l0)\;BLR 14\";
+ }
+ return \"BL %l0\";
+}")
+
+;
+; bltu instruction pattern(s).
+;
+
+(define_insn "bltu"
+ [(set (pc)
+ (if_then_else (ltu (cc0)
+ (const_int 0))
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ "*
+{
+ check_label_emit ();
+ if (!mvs_check_label (CODE_LABEL_NUMBER (operands[0])))
+ {
+ mvs_check_page (0, 6, 4);
+ return \"L 14,=A(%l0)\;BLR 14\";
+ }
+ if (mvs_check_page (0, 4, 0))
+ {
+ mvs_check_page (0, 2, 4);
+ return \"L 14,=A(%l0)\;BLR 14\";
+ }
+ return \"BL %l0\";
+}")
+
+;
+; bge instruction pattern(s).
+;
+
+(define_insn "bge"
+ [(set (pc)
+ (if_then_else (ge (cc0)
+ (const_int 0))
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ "*
+{
+ check_label_emit ();
+ if (!mvs_check_label (CODE_LABEL_NUMBER (operands[0])))
+ {
+ mvs_check_page (0, 6, 4);
+ return \"L 14,=A(%l0)\;BNLR 14\";
+ }
+ if (mvs_check_page (0, 4, 0))
+ {
+ mvs_check_page (0, 2, 4);
+ return \"L 14,=A(%l0)\;BNLR 14\";
+ }
+ return \"BNL %l0\";
+}")
+
+;
+; bgeu instruction pattern(s).
+;
+
+(define_insn "bgeu"
+ [(set (pc)
+ (if_then_else (geu (cc0)
+ (const_int 0))
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ "*
+{
+ check_label_emit ();
+ if (!mvs_check_label (CODE_LABEL_NUMBER (operands[0])))
+ {
+ mvs_check_page (0, 6, 4);
+ return \"L 14,=A(%l0)\;BNLR 14\";
+ }
+ if (mvs_check_page (0, 4, 0))
+ {
+ mvs_check_page (0, 2, 4);
+ return \"L 14,=A(%l0)\;BNLR 14\";
+ }
+ return \"BNL %l0\";
+}")
+
+;
+; ble instruction pattern(s).
+;
+
+(define_insn "ble"
+ [(set (pc)
+ (if_then_else (le (cc0)
+ (const_int 0))
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ "*
+{
+ check_label_emit ();
+ if (!mvs_check_label (CODE_LABEL_NUMBER (operands[0])))
+ {
+ mvs_check_page (0, 6, 4);
+ return \"L 14,=A(%l0)\;BNHR 14\";
+ }
+ if (mvs_check_page (0, 4, 0))
+ {
+ mvs_check_page (0, 2, 4);
+ return \"L 14,=A(%l0)\;BNHR 14\";
+ }
+ return \"BNH %l0\";
+}")
+
+;
+; bleu instruction pattern(s).
+;
+
+(define_insn "bleu"
+ [(set (pc)
+ (if_then_else (leu (cc0)
+ (const_int 0))
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ "*
+{
+ check_label_emit ();
+ if (!mvs_check_label (CODE_LABEL_NUMBER (operands[0])))
+ {
+ mvs_check_page (0, 6, 4);
+ return \"L 14,=A(%l0)\;BNHR 14\";
+ }
+ if (mvs_check_page (0, 4, 0))
+ {
+ mvs_check_page (0, 2, 4);
+ return \"L 14,=A(%l0)\;BNHR 14\";
+ }
+ return \"BNH %l0\";
+}")
+
+;;
+;;- Negated conditional jump instructions.
+;;
+
+(define_insn ""
+ [(set (pc)
+ (if_then_else (eq (cc0)
+ (const_int 0))
+ (pc)
+ (label_ref (match_operand 0 "" ""))))]
+ ""
+ "*
+{
+ check_label_emit ();
+ if (!mvs_check_label (CODE_LABEL_NUMBER (operands[0])))
+ {
+ mvs_check_page (0, 6, 4);
+ return \"L 14,=A(%l0)\;BNER 14\";
+ }
+ if (mvs_check_page (0, 4, 0))
+ {
+ mvs_check_page (0, 2, 4);
+ return \"L 14,=A(%l0)\;BNER 14\";
+ }
+ return \"BNE %l0\";
+}")
+
+(define_insn ""
+ [(set (pc)
+ (if_then_else (ne (cc0)
+ (const_int 0))
+ (pc)
+ (label_ref (match_operand 0 "" ""))))]
+ ""
+ "*
+{
+ check_label_emit ();
+ if (!mvs_check_label (CODE_LABEL_NUMBER (operands[0])))
+ {
+ mvs_check_page (0, 6, 4);
+ return \"L 14,=A(%l0)\;BER 14\";
+ }
+ if (mvs_check_page (0, 4, 0))
+ {
+ mvs_check_page (0, 2, 4);
+ return \"L 14,=A(%l0)\;BER 14\";
+ }
+ return \"BE %l0\";
+}")
+
+(define_insn ""
+ [(set (pc)
+ (if_then_else (gt (cc0)
+ (const_int 0))
+ (pc)
+ (label_ref (match_operand 0 "" ""))))]
+ ""
+ "*
+{
+ check_label_emit ();
+ if (!mvs_check_label (CODE_LABEL_NUMBER (operands[0])))
+ {
+ mvs_check_page (0, 6, 4);
+ return \"L 14,=A(%l0)\;BNHR 14\";
+ }
+ if (mvs_check_page (0, 4, 0))
+ {
+ mvs_check_page (0, 2, 4);
+ return \"L 14,=A(%l0)\;BNHR 14\";
+ }
+ return \"BNH %l0\";
+}")
+
+(define_insn ""
+ [(set (pc)
+ (if_then_else (gtu (cc0)
+ (const_int 0))
+ (pc)
+ (label_ref (match_operand 0 "" ""))))]
+ ""
+ "*
+{
+ check_label_emit ();
+ if (!mvs_check_label (CODE_LABEL_NUMBER (operands[0])))
+ {
+ mvs_check_page (0, 6, 4);
+ return \"L 14,=A(%l0)\;BNHR 14\";
+ }
+ if (mvs_check_page (0, 4, 0))
+ {
+ mvs_check_page (0, 2, 4);
+ return \"L 14,=A(%l0)\;BNHR 14\";
+ }
+ return \"BNH %l0\";
+}")
+
+(define_insn ""
+ [(set (pc)
+ (if_then_else (lt (cc0)
+ (const_int 0))
+ (pc)
+ (label_ref (match_operand 0 "" ""))))]
+ ""
+ "*
+{
+ check_label_emit ();
+ if (!mvs_check_label (CODE_LABEL_NUMBER (operands[0])))
+ {
+ mvs_check_page (0, 6, 4);
+ return \"L 14,=A(%l0)\;BNLR 14\";
+ }
+ if (mvs_check_page (0, 4, 0))
+ {
+ mvs_check_page (0, 2, 4);
+ return \"L 14,=A(%l0)\;BNLR 14\";
+ }
+ return \"BNL %l0\";
+}")
+
+(define_insn ""
+ [(set (pc)
+ (if_then_else (ltu (cc0)
+ (const_int 0))
+ (pc)
+ (label_ref (match_operand 0 "" ""))))]
+ ""
+ "*
+{
+ check_label_emit ();
+ if (!mvs_check_label (CODE_LABEL_NUMBER (operands[0])))
+ {
+ mvs_check_page (0, 6, 4);
+ return \"L 14,=A(%l0)\;BNLR 14\";
+ }
+ if (mvs_check_page (0, 4, 0))
+ {
+ mvs_check_page (0, 2, 4);
+ return \"L 14,=A(%l0)\;BNLR 14\";
+ }
+ return \"BNL %l0\";
+}")
+
+(define_insn ""
+ [(set (pc)
+ (if_then_else (ge (cc0)
+ (const_int 0))
+ (pc)
+ (label_ref (match_operand 0 "" ""))))]
+ ""
+ "*
+{
+ check_label_emit ();
+ if (!mvs_check_label (CODE_LABEL_NUMBER (operands[0])))
+ {
+ mvs_check_page (0, 6, 4);
+ return \"L 14,=A(%l0)\;BLR 14\";
+ }
+ if (mvs_check_page (0, 4, 0))
+ {
+ mvs_check_page (0, 2, 4);
+ return \"L 14,=A(%l0)\;BLR 14\";
+ }
+ return \"BL %l0\";
+}")
+
+(define_insn ""
+ [(set (pc)
+ (if_then_else (geu (cc0)
+ (const_int 0))
+ (pc)
+ (label_ref (match_operand 0 "" ""))))]
+ ""
+ "*
+{
+ check_label_emit ();
+ if (!mvs_check_label (CODE_LABEL_NUMBER (operands[0])))
+ {
+ mvs_check_page (0, 6, 4);
+ return \"L 14,=A(%l0)\;BLR 14\";
+ }
+ if (mvs_check_page (0, 4, 0))
+ {
+ mvs_check_page (0, 2, 4);
+ return \"L 14,=A(%l0)\;BLR 14\";
+ }
+ return \"BL %l0\";
+}")
+
+(define_insn ""
+ [(set (pc)
+ (if_then_else (le (cc0)
+ (const_int 0))
+ (pc)
+ (label_ref (match_operand 0 "" ""))))]
+ ""
+ "*
+{
+ check_label_emit ();
+ if (!mvs_check_label (CODE_LABEL_NUMBER (operands[0])))
+ {
+ mvs_check_page (0, 6, 4);
+ return \"L 14,=A(%l0)\;BHR 14\";
+ }
+ if (mvs_check_page (0, 4, 0))
+ {
+ mvs_check_page (0, 2, 4);
+ return \"L 14,=A(%l0)\;BHR 14\";
+ }
+ return \"BH %l0\";
+}")
+
+(define_insn ""
+ [(set (pc)
+ (if_then_else (leu (cc0)
+ (const_int 0))
+ (pc)
+ (label_ref (match_operand 0 "" ""))))]
+ ""
+ "*
+{
+ check_label_emit ();
+ if (!mvs_check_label (CODE_LABEL_NUMBER (operands[0])))
+ {
+ mvs_check_page (0, 6, 4);
+ return \"L 14,=A(%l0)\;BHR 14\";
+ }
+ if (mvs_check_page (0, 4, 0))
+ {
+ mvs_check_page (0, 2, 4);
+ return \"L 14,=A(%l0)\;BHR 14\";
+ }
+ return \"BH %l0\";
+}")
+
+;;
+;;- Subtract one and jump if not zero.
+;;
+
+(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)))]
+ ""
+ "*
+{
+ check_label_emit ();
+ if (!mvs_check_label (CODE_LABEL_NUMBER (operands[1])))
+ {
+ mvs_check_page (0, 6, 4);
+ return \"L 14,=A(%l1)\;BCTR %0,14\";
+ }
+ if (mvs_check_page (0, 4, 0))
+ {
+ mvs_check_page (0, 2, 4);
+ return \"L 14,=A(%l1)\;BCTR %0,14\";
+ }
+ return \"BCT %0,%l1\";
+}")
+
+(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)))]
+ ""
+ "*
+{
+ check_label_emit ();
+ if (!mvs_check_label (CODE_LABEL_NUMBER (operands[1])))
+ {
+ mvs_check_page (0, 6, 4);
+ return \"L 14,=A(%l1)\;BCTR %0,14\";
+ }
+ if (mvs_check_page (0, 4, 0))
+ {
+ mvs_check_page (0, 2, 4);
+ return \"L 14,=A(%l1)\;BCTR %0,14\";
+ }
+ return \"BCT %0,%l1\";
+}")
+
+;;
+;;- Unconditional jump instructions.
+;;
+
+;
+; jump instruction pattern(s).
+;
+
+(define_insn "jump"
+ [(set (pc)
+ (label_ref (match_operand 0 "" "")))]
+ ""
+ "*
+{
+ check_label_emit ();
+ if (!mvs_check_label (CODE_LABEL_NUMBER (operands[0])))
+ {
+ mvs_check_page (0, 6, 4);
+ return \"L 14,=A(%l0)\;BR 14\";
+ }
+ if (mvs_check_page (0, 4, 0))
+ {
+ mvs_check_page (0, 2, 4);
+ return \"L 14,=A(%l0)\;BR 14\";
+ }
+ return \"B %l0\";
+}")
+
+;
+; indirect-jump instruction pattern(s).
+;
+
+(define_insn "indirect_jump"
+ [(set (pc) (match_operand:SI 0 "general_operand" "r"))]
+ "(GET_CODE (operands[0]) != MEM )"
+ "*
+{
+ check_label_emit ();
+ mvs_check_page (0, 2, 0);
+ return \"BR %0\";
+}")
+
+;
+; tablejump instruction pattern(s).
+;
+
+(define_insn "tablejump"
+ [(set (pc)
+ (match_operand:SI 0 "general_operand" "am"))
+ (use (label_ref (match_operand 1 "" "")))]
+ ""
+ "*
+{
+ 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\";
+}")
+
+;;
+;;- 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.
+;;
+
+;
+; call instruction pattern(s).
+;
+
+(define_insn "call"
+ [(call (match_operand:QI 0 "memory_operand" "m")
+ (match_operand:SI 1 "immediate_operand" "i"))]
+ ""
+ "*
+{
+ static char temp[128];
+ int i = STACK_POINTER_OFFSET;
+
+ check_label_emit ();
+ 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;
+}")
+
+;
+; 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")))]
+ ""
+ "*
+{
+ static char temp[128];
+ int i = STACK_POINTER_OFFSET;
+
+ check_label_emit ();
+ 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;
+}")
+
+(define_insn ""
+ [(call (mem:QI (match_operand:SI 0 "" "i"))
+ (match_operand:SI 1 "general_operand" "g"))]
+ "GET_CODE (operands[0]) == SYMBOL_REF"
+ "*
+{
+ static char temp[128];
+ int i = STACK_POINTER_OFFSET;
+
+ check_label_emit ();
+ 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;
+}")
+
+(define_insn ""
+ [(set (match_operand 0 "" "rf")
+ (call (mem:QI (match_operand:SI 1 "" "i"))
+ (match_operand:SI 2 "general_operand" "g")))]
+ "GET_CODE (operands[1]) == SYMBOL_REF"
+ "*
+{
+ static char temp[128];
+ int i = STACK_POINTER_OFFSET;
+
+ check_label_emit ();
+ 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;
+}")
+
+
+;;
+;;- 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\";
+}")
+
diff --git a/gnu/egcs/gcc/config/i370/t-i370 b/gnu/egcs/gcc/config/i370/t-i370
new file mode 100644
index 00000000000..d20ab385dcc
--- /dev/null
+++ b/gnu/egcs/gcc/config/i370/t-i370
@@ -0,0 +1,4 @@
+# There is no libgcc for mvs
+LIBGCC =
+INSTALL_LIBGCC =
+LIBGCC1_TEST =
diff --git a/gnu/egcs/gcc/config/i370/xm-i370.h b/gnu/egcs/gcc/config/i370/xm-i370.h
new file mode 100644
index 00000000000..ac753633070
--- /dev/null
+++ b/gnu/egcs/gcc/config/i370/xm-i370.h
@@ -0,0 +1,53 @@
+/* Configuration for GNU C-compiler for System/370.
+ Copyright (C) 1989, 1993, 1997 Free Software Foundation, Inc.
+ Contributed by Jan Stein (jan@cd.chalmers.se).
+ Modified for MVS C/370 by Dave Pitts (dpitts@nyx.cs.du.edu)
+
+This file is part of GNU CC.
+
+GNU CC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU CC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+/* #defines that need visibility everywhere. */
+
+#define FALSE 0
+#define TRUE 1
+
+/* This describes the machine the compiler is hosted on. */
+
+#define HOST_BITS_PER_CHAR 8
+#define HOST_BITS_PER_SHORT 16
+#define HOST_BITS_PER_INT 32
+#define HOST_BITS_PER_LONG 32
+#define HOST_FLOAT_FORMAT IBM_FLOAT_FORMAT
+#define HOST_EBCDIC 1
+
+#define USG
+#ifndef MVS
+#define MVS
+#endif
+
+/* Target machine dependencies. tm.h is a symbolic link to the actual
+ target specific file. */
+
+#include "tm.h"
+
+/* Arguments to use with `exit'. */
+
+#define SUCCESS_EXIT_CODE 0
+#define FATAL_EXIT_CODE 12
+
+#define NO_DBX_FORMAT
+