Annotation of GNUtools/cc/config/i370/mvs.h, revision 1.1.1.1

1.1       root        1: /* Definitions of target machine for GNU compiler.  System/370 version.
                      2:    Copyright (C) 1989, 1993 Free Software Foundation, Inc.
                      3:    Contributed by Jan Stein ([email protected]).
                      4:    Modified for C/370 MVS by Dave Pitts ([email protected])
                      5: 
                      6: This file is part of GNU CC.
                      7: 
                      8: GNU CC is free software; you can redistribute it and/or modify
                      9: it under the terms of the GNU General Public License as published by
                     10: the Free Software Foundation; either version 2, or (at your option)
                     11: any later version.
                     12: 
                     13: GNU CC is distributed in the hope that it will be useful,
                     14: but WITHOUT ANY WARRANTY; without even the implied warranty of
                     15: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                     16: GNU General Public License for more details.
                     17: 
                     18: You should have received a copy of the GNU General Public License
                     19: along with GNU CC; see the file COPYING.  If not, write to
                     20: the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
                     21: 
                     22: #ifdef sun
                     23: #include <sys/types.h>
                     24: #include <ctype.h>
                     25: #endif
                     26: #include <time.h>
                     27: 
                     28: #define TARGET_VERSION printf (" (370/MVS)");
                     29: 
                     30: /* Names to predefine in the preprocessor for this target machine.  */
                     31: 
                     32: #define CPP_PREDEFINES "-DGCC -Dgcc -DMVS -Dmvs -Asystem(mvs) -Acpu(i370) -Amachine(i370)"
                     33: 
                     34: /* Run-time compilation parameters selecting different hardware subsets.  */
                     35: 
                     36: extern int target_flags;
                     37: 
                     38: /* The sizes of the code and literals on the current page.  */
                     39: 
                     40: extern int mvs_page_code, mvs_page_lit;
                     41: 
                     42: /* The current page number and the base page number for the function.  */
                     43: 
                     44: extern int mvs_page_num, function_base_page;
                     45: 
                     46: /* True if a label has been emitted.  */
                     47: 
                     48: extern int mvs_label_emited;
                     49: 
                     50: /* The name of the current function.  */
                     51: 
                     52: extern char *mvs_function_name;
                     53: 
                     54: /* The length of the function name malloc'd area.  */
                     55: 
                     56: extern int mvs_function_name_length;
                     57: 
                     58: /* The amount of space used for outgoing arguments.  */
                     59: 
                     60: extern int current_function_outgoing_args_size;
                     61: 
                     62: /* Compile using char instructins (mvc, nc, oc, xc).  On 4341 use this since
                     63:    these are more than twice as fast as load-op-store.
                     64:    On 3090 don't use this since load-op-store is much faster.  */
                     65: 
                     66: #define TARGET_CHAR_INSTRUCTIONS (target_flags & 1)
                     67: 
                     68: /* Default target switches */
                     69: 
                     70: #define TARGET_DEFAULT 1
                     71: 
                     72: /* Macro to define tables used to set the flags.  This is a list in braces
                     73:    of pairs in braces, each pair being { "NAME", VALUE }
                     74:    where VALUE is the bits to set or minus the bits to clear.
                     75:    An empty string NAME is used to identify the default VALUE.  */
                     76: 
                     77: #define TARGET_SWITCHES                                                        \
                     78: { { "char-instructions", 1},                                           \
                     79:   { "no-char-instructions", -1},                                       \
                     80:   { "", TARGET_DEFAULT} }
                     81: 
                     82: /* Target machine storage layout */
                     83: 
                     84: /* Define this if most significant bit is lowest numbered in instructions
                     85:    that operate on numbered bit-fields.  */
                     86: 
                     87: #define BITS_BIG_ENDIAN 1
                     88: 
                     89: /* Define this if most significant byte of a word is the lowest numbered.  */
                     90: 
                     91: #define BYTES_BIG_ENDIAN 1
                     92: 
                     93: /* Define this if MS word of a multiword is the lowest numbered.  */
                     94: 
                     95: #define WORDS_BIG_ENDIAN 1
                     96: 
                     97: /* Number of bits in an addressible storage unit.  */
                     98: 
                     99: #define BITS_PER_UNIT 8
                    100: 
                    101: /* Width in bits of a "word", which is the contents of a machine register.  */
                    102: 
                    103: #define BITS_PER_WORD 32
                    104: 
                    105: /* Width of a word, in units (bytes).  */
                    106: 
                    107: #define UNITS_PER_WORD 4
                    108: 
                    109: /* Width in bits of a pointer.  See also the macro `Pmode' defined below.  */
                    110: 
                    111: #define POINTER_SIZE 32
                    112: 
                    113: /* Allocation boundary (in *bits*) for storing pointers in memory.  */
                    114: 
                    115: #define POINTER_BOUNDARY 32
                    116: 
                    117: /* Allocation boundary (in *bits*) for storing arguments in argument list.  */
                    118: 
                    119: #define PARM_BOUNDARY 32
                    120: 
                    121: /* Boundary (in *bits*) on which stack pointer should be aligned.  */
                    122: 
                    123: #define STACK_BOUNDARY 32
                    124: 
                    125: /* Allocation boundary (in *bits*) for the code of a function.  */
                    126: 
                    127: #define FUNCTION_BOUNDARY 32
                    128: 
                    129: /* There is no point aligning anything to a rounder boundary than this.  */
                    130: 
                    131: #define BIGGEST_ALIGNMENT 64
                    132: 
                    133: /* Alignment of field after `int : 0' in a structure.  */
                    134: 
                    135: #define EMPTY_FIELD_BOUNDARY 32
                    136: 
                    137: /* Define this if move instructions will actually fail to work when given
                    138:    unaligned data.  */
                    139: 
                    140: #define STRICT_ALIGNMENT 0
                    141: 
                    142: /* Define target floating point format.  */
                    143: 
                    144: #define TARGET_FLOAT_FORMAT IBM_FLOAT_FORMAT
                    145: 
                    146: /* Define character mapping for cross-compiling.  */
                    147: 
                    148: #define TARGET_EBCDIC 1
                    149: 
                    150: #ifdef HOST_EBCDIC
                    151: #define MAP_CHARACTER(c) ((char)(c))
                    152: #else
                    153: #define MAP_CHARACTER(c) ((char)mvs_map_char (c))
                    154: #endif
                    155: 
                    156: /* Define maximum length of page minus page escape overhead.  */
                    157: 
                    158: #define MAX_MVS_PAGE_LENGTH 4080
                    159: 
                    160: /* Define if special allocation order desired.  */
                    161: 
                    162: #define REG_ALLOC_ORDER                                                        \
                    163: { 0, 1, 2, 3, 14, 15, 12, 10, 9, 8, 7, 6, 5, 4, 16, 17, 18, 19, 11, 13 }
                    164: 
                    165: /* Standard register usage.  */
                    166: 
                    167: /* Number of actual hardware registers.  The hardware registers are
                    168:    assigned numbers for the compiler from 0 to just below
                    169:    FIRST_PSEUDO_REGISTER.
                    170:    All registers that the compiler knows about must be given numbers,
                    171:    even those that are not normally considered general registers.
                    172:    For the 370, we give the data registers numbers 0-15,
                    173:    and the floating point registers numbers 16-19.  */
                    174: 
                    175: #define FIRST_PSEUDO_REGISTER 20
                    176: 
                    177: /* Define base and page registers.  */
                    178: 
                    179: #define BASE_REGISTER 3
                    180: #define PAGE_REGISTER 4
                    181: 
                    182: /* 1 for registers that have pervasive standard uses and are not available
                    183:    for the register allocator.  On the 370 under C/370, R13 is stack (DSA)
                    184:    pointer, R12 is the TCA pointer, R3 is the base register, R4 is the page
                    185:    origin table pointer and R11 is the arg pointer.  */
                    186: 
                    187: #define FIXED_REGISTERS                                                \
                    188: { 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0 }
                    189: /*0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19*/
                    190: 
                    191: /* 1 for registers not available across function calls.  These must include
                    192:    the FIXED_REGISTERS and also any registers that can be used without being
                    193:    saved.
                    194:    The latter must include the registers where values are returned
                    195:    and the register where structure-value addresses are passed.
                    196:    NOTE: all floating registers are undefined across calls.  */
                    197: 
                    198: #define CALL_USED_REGISTERS                                            \
                    199: { 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1 }
                    200: /*0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19*/
                    201: 
                    202: /* Return number of consecutive hard regs needed starting at reg REGNO
                    203:    to hold something of mode MODE.
                    204:    This is ordinarily the length in words of a value of mode MODE
                    205:    but can be less for certain modes in special long registers.  */
                    206: 
                    207: #define HARD_REGNO_NREGS(REGNO, MODE)                                  \
                    208:   ((REGNO) > 15 ? 1 : (GET_MODE_SIZE(MODE)+UNITS_PER_WORD-1) / UNITS_PER_WORD)
                    209: 
                    210: /* Value is 1 if hard register REGNO can hold a value of machine-mode MODE.
                    211:    On the 370, the cpu registers can hold QI, HI, SI, SF and DF.  The
                    212:    even registers can hold DI.  The floating point registers can hold
                    213:    either SF or DF.  */
                    214: 
                    215: #define HARD_REGNO_MODE_OK(REGNO, MODE)                                        \
                    216:   ((REGNO) < 16 ? ((REGNO) & 1) == 0 || (MODE) != DImode               \
                    217:                : (MODE) == SFmode || (MODE) == DFmode)
                    218: 
                    219: /* Value is 1 if it is a good idea to tie two pseudo registers when one has
                    220:    mode MODE1 and one has mode MODE2.
                    221:    If HARD_REGNO_MODE_OK could produce different values for MODE1 and MODE2,
                    222:    for any hard reg, then this must be 0 for correct output.  */
                    223: 
                    224: #define MODES_TIEABLE_P(MODE1, MODE2)                                  \
                    225:   (((MODE1) == SFmode || (MODE1) == DFmode)                            \
                    226:    == ((MODE2) == SFmode || (MODE2) == DFmode))
                    227: 
                    228: /* Mark external references.  */
                    229: 
                    230: #define ENCODE_SECTION_INFO(decl)                                      \
                    231:   if (DECL_EXTERNAL (decl) && TREE_PUBLIC (decl))                      \
                    232:     SYMBOL_REF_FLAG (XEXP (DECL_RTL (decl), 0)) = 1;
                    233: 
                    234: /* Specify the registers used for certain standard purposes.
                    235:    The values of these macros are register numbers.  */
                    236: 
                    237: /* 370 PC isn't overloaded on a register.  */
                    238: 
                    239: /* #define PC_REGNUM */
                    240: 
                    241: /* Register to use for pushing function arguments.  */
                    242: 
                    243: #define STACK_POINTER_REGNUM 13
                    244: 
                    245: /* Base register for access to local variables of the function.  */
                    246: 
                    247: #define FRAME_POINTER_REGNUM 13
                    248: 
                    249: /* Value should be nonzero if functions must have frame pointers.
                    250:    Zero means the frame pointer need not be set up (and parms may be
                    251:    accessed via the stack pointer) in functions that seem suitable.
                    252:    This is computed in `reload', in reload1.c.  */
                    253: 
                    254: #define FRAME_POINTER_REQUIRED 1
                    255: 
                    256: /* Base register for access to arguments of the function.  */
                    257: 
                    258: #define ARG_POINTER_REGNUM 11
                    259: 
                    260: /* Register in which static-chain is passed to a function.  */
                    261: 
                    262: #define STATIC_CHAIN_REGNUM 10
                    263: 
                    264: /* Register in which address to store a structure value is passed to
                    265:    a function.  */
                    266: 
                    267: #define STRUCT_VALUE_REGNUM 1
                    268: 
                    269: /* Define the classes of registers for register constraints in the
                    270:    machine description.  Also define ranges of constants.
                    271: 
                    272:    One of the classes must always be named ALL_REGS and include all hard regs.
                    273:    If there is more than one class, another class must be named NO_REGS
                    274:    and contain no registers.
                    275: 
                    276:    The name GENERAL_REGS must be the name of a class (or an alias for
                    277:    another name such as ALL_REGS).  This is the class of registers
                    278:    that is allowed by "g" or "r" in a register constraint.
                    279:    Also, registers outside this class are allocated only when
                    280:    instructions express preferences for them.
                    281: 
                    282:    The classes must be numbered in nondecreasing order; that is,
                    283:    a larger-numbered class must never be contained completely
                    284:    in a smaller-numbered class.
                    285: 
                    286:    For any two classes, it is very desirable that there be another
                    287:    class that represents their union.  */
                    288: 
                    289: enum reg_class
                    290:   {
                    291:     NO_REGS, ADDR_REGS, DATA_REGS,
                    292:     FP_REGS, ALL_REGS, LIM_REG_CLASSES
                    293:   };
                    294: 
                    295: #define GENERAL_REGS DATA_REGS
                    296: #define N_REG_CLASSES (int) LIM_REG_CLASSES
                    297: 
                    298: /* Give names of register classes as strings for dump file.  */
                    299: 
                    300: #define REG_CLASS_NAMES                                                \
                    301: { "NO_REGS", "ADDR_REGS", "DATA_REGS", "FP_REGS", "ALL_REGS" }
                    302: 
                    303: /* Define which registers fit in which classes.  This is an initializer for
                    304:    a vector of HARD_REG_SET of length N_REG_CLASSES.  */
                    305: 
                    306: #define REG_CLASS_CONTENTS {0, 0x0fffe, 0x0ffff, 0xf0000, 0xfffff}
                    307: 
                    308: /* The same information, inverted:
                    309:    Return the class number of the smallest class containing
                    310:    reg number REGNO.  This could be a conditional expression
                    311:    or could index an array.  */
                    312: 
                    313: #define REGNO_REG_CLASS(REGNO)                                                 \
                    314:   ((REGNO) >= 16 ? FP_REGS : (REGNO) != 0 ? ADDR_REGS : DATA_REGS)
                    315: 
                    316: /* The class value for index registers, and the one for base regs.  */
                    317: 
                    318: #define INDEX_REG_CLASS ADDR_REGS
                    319: #define BASE_REG_CLASS ADDR_REGS
                    320: 
                    321: /* Get reg_class from a letter such as appears in the machine description.  */
                    322: 
                    323: #define REG_CLASS_FROM_LETTER(C)                                       \
                    324:   ((C) == 'a' ? ADDR_REGS :                                            \
                    325:   ((C) == 'd' ? DATA_REGS :                                            \
                    326:   ((C) == 'f' ? FP_REGS   : NO_REGS)))
                    327: 
                    328: /* The letters I, J, K, L and M in a register constraint string can be used
                    329:    to stand for particular ranges of immediate operands.
                    330:    This macro defines what the ranges are.
                    331:    C is the letter, and VALUE is a constant value.
                    332:    Return 1 if VALUE is in the range specified by C.  */
                    333: 
                    334: #define CONST_OK_FOR_LETTER_P(VALUE, C)                                        \
                    335:   ((C) == 'I' ? (unsigned) (VALUE) < 256 :                             \
                    336:    (C) == 'J' ? (unsigned) (VALUE) < 4096 :                            \
                    337:    (C) == 'K' ? (VALUE) >= -32768 && (VALUE) < 32768 : 0)
                    338: 
                    339: /* Similar, but for floating constants, and defining letters G and H.
                    340:    Here VALUE is the CONST_DOUBLE rtx itself.  */
                    341: 
                    342: #define CONST_DOUBLE_OK_FOR_LETTER_P(VALUE, C)  1
                    343: 
                    344: /* Given an rtx X being reloaded into a reg required to be in class CLASS,
                    345:    return the class of reg to actually use.  In general this is just CLASS;
                    346:    but on some machines in some cases it is preferable to use a more
                    347:    restrictive class.  */
                    348: 
                    349: #define PREFERRED_RELOAD_CLASS(X, CLASS)                               \
                    350:     (GET_CODE(X) == CONST_DOUBLE ? FP_REGS :                           \
                    351:      GET_CODE(X) == CONST_INT ? DATA_REGS :                            \
                    352:      GET_CODE(X) == LABEL_REF ||                                       \
                    353:      GET_CODE(X) == SYMBOL_REF ||                                      \
                    354:      GET_CODE(X) == CONST ? ADDR_REGS : (CLASS))
                    355: 
                    356: /* Return the maximum number of consecutive registers needed to represent
                    357:    mode MODE in a register of class CLASS.  */
                    358: 
                    359: #define CLASS_MAX_NREGS(CLASS, MODE)                                   \
                    360:   ((CLASS) == FP_REGS ? 1 :                                            \
                    361:    (GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
                    362: 
                    363: /* Stack layout; function entry, exit and calling.  */
                    364: 
                    365: /* Define this if pushing a word on the stack makes the stack pointer a
                    366:    smaller address.  */
                    367: 
                    368: /* #define STACK_GROWS_DOWNWARD */
                    369: 
                    370: /* Define this if the nominal address of the stack frame is at the
                    371:    high-address end of the local variables; that is, each additional local
                    372:    variable allocated goes at a more negative offset in the frame.  */
                    373: 
                    374: /* #define FRAME_GROWS_DOWNWARD */
                    375: 
                    376: /* Offset within stack frame to start allocating local variables at.
                    377:    If FRAME_GROWS_DOWNWARD, this is the offset to the END of the
                    378:    first local allocated.  Otherwise, it is the offset to the BEGINNING
                    379:    of the first local allocated.  */
                    380: 
                    381: #define STARTING_FRAME_OFFSET                                                  \
                    382:      (STACK_POINTER_OFFSET + current_function_outgoing_args_size)
                    383: 
                    384: #define INITIAL_FRAME_POINTER_OFFSET(DEPTH) (DEPTH) = STARTING_FRAME_OFFSET
                    385: 
                    386: /* If we generate an insn to push BYTES bytes, this says how many the stack
                    387:    pointer really advances by.  On the 370, we have no push instruction.  */
                    388: 
                    389: /* #define PUSH_ROUNDING(BYTES) */
                    390: 
                    391: /* Accumulate the outgoing argument count so we can request the right
                    392:    DSA size and determine stack offset.  */
                    393: 
                    394: #define ACCUMULATE_OUTGOING_ARGS
                    395: 
                    396: /* Define offset from stack pointer, to location where a parm can be
                    397:    pushed.  */
                    398: 
                    399: #define STACK_POINTER_OFFSET 148
                    400: 
                    401: /* Offset of first parameter from the argument pointer register value.  */
                    402: 
                    403: #define FIRST_PARM_OFFSET(FNDECL) 0
                    404: 
                    405: /* 1 if N is a possible register number for function argument passing.
                    406:    On the 370, no registers are used in this way.  */
                    407: 
                    408: #define FUNCTION_ARG_REGNO_P(N) 0
                    409: 
                    410: /* Define a data type for recording info about an argument list during
                    411:    the scan of that argument list.  This data type should hold all
                    412:    necessary information about the function itself and about the args
                    413:    processed so far, enough to enable macros such as FUNCTION_ARG to
                    414:    determine where the next arg should go.  */
                    415: 
                    416: #define CUMULATIVE_ARGS int
                    417: 
                    418: /* Initialize a variable CUM of type CUMULATIVE_ARGS for a call to
                    419:    a function whose data type is FNTYPE.
                    420:    For a library call, FNTYPE is 0.  */
                    421: 
                    422: #define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME)  ((CUM) = 0)
                    423: 
                    424: /* Update the data in CUM to advance over an argument of mode MODE and
                    425:    data type TYPE.  (TYPE is null for libcalls where that information
                    426:    may not be available.) */
                    427: 
                    428: #define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED)                   \
                    429:  ((CUM) += ((MODE) == DFmode || (MODE) == SFmode                       \
                    430:            ? 256                                                       \
                    431:            : (MODE) != BLKmode                                         \
                    432:            ? (GET_MODE_SIZE (MODE) + 3) / 4                            \
                    433:            : (int_size_in_bytes (TYPE) + 3) / 4))
                    434: 
                    435: /* Define where to put the arguments to a function.  Value is zero to push
                    436:    the argument on the stack, or a hard register in which to store the
                    437:    argument.  */
                    438: 
                    439: #define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) 0
                    440: 
                    441: /* For an arg passed partly in registers and partly in memory, this is the
                    442:    number of registers used.  For args passed entirely in registers or
                    443:    entirely in memory, zero.  */
                    444: 
                    445: #define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) 0
                    446: 
                    447: /* Define if returning from a function call automatically pops the
                    448:    arguments described by the number-of-args field in the call.  */
                    449: 
                    450: #define RETURN_POPS_ARGS(FUNTYPE, STACKSIZE) 0
                    451: 
                    452: /* Define how to find the value returned by a function.  VALTYPE is the
                    453:    data type of the value (as a tree).
                    454:    If the precise function being called is known, FUNC is its FUNCTION_DECL;
                    455:    otherwise, FUNC is 15.  */
                    456: 
                    457: #define RET_REG(MODE)  ((MODE) == DFmode || (MODE) == SFmode ? 16 : 15)
                    458: 
                    459: /* On the 370 the return value is in R15 or R16.  */
                    460: 
                    461: #define FUNCTION_VALUE(VALTYPE, FUNC)                                          \
                    462:   gen_rtx(REG, TYPE_MODE (VALTYPE), RET_REG(TYPE_MODE(VALTYPE)))
                    463: 
                    464: /* Define how to find the value returned by a library function assuming
                    465:    the value has mode MODE.  */
                    466: 
                    467: #define LIBCALL_VALUE(MODE)  gen_rtx(REG, MODE, RET_REG(MODE))
                    468: 
                    469: /* 1 if N is a possible register number for a function value.
                    470:    On the 370 under C/370, R15 and R16 are thus used.  */
                    471: 
                    472: #define FUNCTION_VALUE_REGNO_P(N) ((N) == 15 || (N) == 16)
                    473: 
                    474: /* This macro definition sets up a default value for `main' to return.  */
                    475: 
                    476: #define DEFAULT_MAIN_RETURN  c_expand_return (integer_zero_node)
                    477: 
                    478: /* This macro generates the assembly code for function entry.
                    479:    All of the C/370 environment is preserved.  */
                    480: 
                    481: #define FUNCTION_PROLOGUE(FILE, LSIZE)                                 \
                    482: {                                                                      \
                    483:   static int function_label_index = 1;                                 \
                    484:   static int function_first = 0;                                       \
                    485:   static int function_year, function_month, function_day;              \
                    486:   static int function_hour, function_minute, function_second;          \
                    487:   int i;                                                               \
                    488:   if (!function_first)                                                 \
                    489:     {                                                                  \
                    490:       struct tm *function_time;                                                \
                    491:       time_t lcltime;                                                  \
                    492:       time (&lcltime);                                                 \
                    493:       function_time = localtime (&lcltime);                            \
                    494:       function_year = function_time->tm_year + 1900;                   \
                    495:       function_month = function_time->tm_mon + 1;                      \
                    496:       function_day = function_time->tm_mday;                           \
                    497:       function_hour = function_time->tm_hour;                          \
                    498:       function_minute = function_time->tm_min;                         \
                    499:       function_second = function_time->tm_sec;                         \
                    500:     }                                                                  \
                    501:   fprintf (FILE, "\tUSING\t*,15\n");                                   \
                    502:   fprintf (FILE, "\tB\tFPL%03d\n", function_label_index);              \
                    503:   fprintf (FILE, "\tDC\tAL1(FPL%03d+4-*)\n", function_label_index + 1);        \
                    504:   fprintf (FILE, "\tDC\tX'CE',X'A0',X'10'\n");                         \
                    505:   fprintf (FILE, "\tDC\tA($PPA2)\n");                                  \
                    506:   fprintf (FILE, "\tDC\tF'%d'\n", 0);                                  \
                    507:   fprintf (FILE, "\tDC\tF'%d'\n", STACK_POINTER_OFFSET + LSIZE         \
                    508:                        + current_function_outgoing_args_size);         \
                    509:   fprintf (FILE, "FPL%03d\tEQU\t*\n", function_label_index + 1);       \
                    510:   fprintf (FILE, "\tDC\tAL2(%d),C'%s'\n", strlen (mvs_function_name),  \
                    511:        mvs_function_name);                                             \
                    512:   fprintf (FILE, "\tDS\t0F\n");                                                \
                    513:   if (!function_first)                                                 \
                    514:     {                                                                  \
                    515:       fprintf (FILE, "$PPA2\tEQU\t*\n");                               \
                    516:       fprintf (FILE, "\tDC\tX'03',X'00',X'33',X'00'\n");               \
                    517:       fprintf (FILE, "\tDC\tV(CEESTART),A(0)\n");                      \
                    518:       fprintf (FILE, "\tDC\tA($TIMES)\n");                             \
                    519:       fprintf (FILE, "\tDS\t0F\n");                                    \
                    520:       fprintf (FILE, "$TIMES\tEQU\t*\n");                              \
                    521:       fprintf (FILE, "\tDC\tCL4'%d',CL4'%02d%02d',CL6'%02d%02d00'\n",  \
                    522:                      function_year, function_month, function_day,      \
                    523:                      function_hour, function_minute, function_second); \
                    524:       fprintf (FILE, "\tDC\tCL2'01',CL4'0100'\n");                     \
                    525:     }                                                                  \
                    526:   fprintf (FILE, "\tDS\t0H\n");                                                \
                    527:   fprintf (FILE, "FPL%03d\tEQU\t*\n", function_label_index);           \
                    528:   fprintf (FILE, "\tSTM\t14,12,12(13)\n");                             \
                    529:   fprintf (FILE, "\tL\t2,76(,13)\n");                                  \
                    530:   fprintf (FILE, "\tL\t0,16(,15)\n");                                  \
                    531:   fprintf (FILE, "\tALR\t0,2\n");                                      \
                    532:   fprintf (FILE, "\tCL\t0,12(,12)\n");                                 \
                    533:   fprintf (FILE, "\tBNH\t*+10\n");                                     \
                    534:   fprintf (FILE, "\tL\t15,116(,12)\n");                                        \
                    535:   fprintf (FILE, "\tBALR\t14,15\n");                                   \
                    536:   fprintf (FILE, "\tL\t15,72(,13)\n");                                 \
                    537:   fprintf (FILE, "\tSTM\t15,0,72(2)\n");                               \
                    538:   fprintf (FILE, "\tMVI\t0(2),X'10'\n");                               \
                    539:   fprintf (FILE, "\tST\t13,4(,2)\n ");                                 \
                    540:   fprintf (FILE, "\tLR\t13,2\n");                                      \
                    541:   fprintf (FILE, "\tLR\t11,1\n");                                      \
                    542:   fprintf (FILE, "\tDROP\t15\n");                                      \
                    543:   fprintf (FILE, "\tBALR\t%d,0\n", BASE_REGISTER);                     \
                    544:   fprintf (FILE, "PG%d\tEQU\t*\n", mvs_page_num );                     \
                    545:   fprintf (FILE, "\tUSING\t*,%d\n", BASE_REGISTER);                    \
                    546:   fprintf (FILE, "\tL\t%d,=A(PGT%d)\n", PAGE_REGISTER, mvs_page_num);  \
                    547:   mvs_page_code = 4;                                                   \
                    548:   mvs_page_lit = 4;                                                    \
                    549:   mvs_check_page (FILE, 0, 0);                                         \
                    550:   function_base_page = mvs_page_num;                                   \
                    551:   function_first = 1;                                                  \
                    552:   function_label_index += 2;                                           \
                    553: }
                    554: 
                    555: #define ASM_DECLARE_FUNCTION_NAME(FILE, NAME, DECL)                    \
                    556: {                                                                      \
                    557:   if (strlen (NAME) * 2 > mvs_function_name_length)                    \
                    558:     {                                                                  \
                    559:       if (mvs_function_name)                                           \
                    560:        free (mvs_function_name);                                       \
                    561:       mvs_function_name = 0;                                           \
                    562:     }                                                                  \
                    563:   if (!mvs_function_name)                                              \
                    564:     {                                                                  \
                    565:       mvs_function_name_length = strlen (NAME) * 2;                    \
                    566:       mvs_function_name = (char *) malloc (mvs_function_name_length);  \
                    567:       if (mvs_function_name == 0)                                      \
                    568:        {                                                               \
                    569:          fatal ("virtual memory exceeded");                            \
                    570:          abort ();                                                     \
                    571:        }                                                               \
                    572:     }                                                                  \
                    573:   if (!strcmp (NAME, "main"))                                          \
                    574:     strcpy (mvs_function_name, "gccmain");                             \
                    575:   else                                                                 \
                    576:     strcpy (mvs_function_name, NAME);                                  \
                    577:   fprintf (FILE, "\tDS\t0H\n");                                                \
                    578:   assemble_name (FILE, mvs_function_name);                             \
                    579:   fputs ("\tCSECT\n", FILE);                                           \
                    580: }
                    581: 
                    582: /* This macro generates the assembly code for function exit, on machines
                    583:    that need it.  If FUNCTION_EPILOGUE is not defined then individual
                    584:    return instructions are generated for each return statement.  Args are
                    585:    same as for FUNCTION_PROLOGUE.
                    586: 
                    587:    The function epilogue should not depend on the current stack pointer!
                    588:    It should use the frame pointer only.  This is mandatory because
                    589:    of alloca; we also take advantage of it to omit stack adjustments
                    590:    before returning.  */
                    591: 
                    592: #define FUNCTION_EPILOGUE(FILE, LSIZE)                                 \
                    593: {                                                                      \
                    594:   int i;                                                               \
                    595:   check_label_emit();                                                  \
                    596:   mvs_check_page (FILE,14,0);                                          \
                    597:   fprintf (FILE, "\tL\t13,4(,13)\n");                                  \
                    598:   fprintf (FILE, "\tL\t14,12(,13)\n");                                 \
                    599:   fprintf (FILE, "\tLM\t2,12,28(13)\n");                               \
                    600:   fprintf (FILE, "\tBALR\t1,14\n");                                    \
                    601:   fprintf (FILE, "\tDC\tA(");                                          \
                    602:   mvs_page_num++;                                                      \
                    603:   assemble_name (FILE, mvs_function_name);                             \
                    604:   fprintf (FILE, ")\n" );                                              \
                    605:   fprintf (FILE, "\tDS\t0F\n" );                                       \
                    606:   fprintf (FILE, "\tLTORG\n");                                         \
                    607:   fprintf (FILE, "\tDS\t0F\n");                                                \
                    608:   fprintf (FILE, "PGT%d\tEQU\t*\n", function_base_page);               \
                    609:   mvs_free_label();                                                    \
                    610:   for ( i = function_base_page; i < mvs_page_num; i++ )                        \
                    611:     fprintf (FILE, "\tDC\tA(PG%d)\n", i);                              \
                    612: }
                    613: 
                    614: /* Output assembler code for a block containing the constant parts of a
                    615:    trampoline, leaving space for the variable parts.
                    616: 
                    617:    On the 370, the trampoline contains these instructions:
                    618: 
                    619:         BALR  14,0
                    620:         USING *,14
                    621:         L     STATIC_CHAIN_REGISTER,X
                    622:         L     15,Y
                    623:         BR    15
                    624:    X    DS    0F
                    625:    Y    DS    0F  */
                    626: 
                    627: #define TRAMPOLINE_TEMPLATE(FILE)                                      \
                    628: {                                                                      \
                    629:   ASM_OUTPUT_SHORT (FILE, gen_rtx (CONST_INT, VOIDmode, 0x05E0));      \
                    630:   ASM_OUTPUT_SHORT (FILE, gen_rtx (CONST_INT, VOIDmode, 0x5800 |       \
                    631:                           STATIC_CHAIN_REGNUM << 4));                  \
                    632:   ASM_OUTPUT_SHORT (FILE, gen_rtx (CONST_INT, VOIDmode, 0xE00A));      \
                    633:   ASM_OUTPUT_SHORT (FILE, gen_rtx (CONST_INT, VOIDmode, 0x58F0));      \
                    634:   ASM_OUTPUT_SHORT (FILE, gen_rtx (CONST_INT, VOIDmode, 0xE00E));      \
                    635:   ASM_OUTPUT_SHORT (FILE, gen_rtx (CONST_INT, VOIDmode, 0x07FF));      \
                    636:   ASM_OUTPUT_SHORT (FILE, const0_rtx);                                 \
                    637:   ASM_OUTPUT_SHORT (FILE, const0_rtx);                                 \
                    638:   ASM_OUTPUT_SHORT (FILE, const0_rtx);                                 \
                    639:   ASM_OUTPUT_SHORT (FILE, const0_rtx);                                 \
                    640: }
                    641: 
                    642: /* Length in units of the trampoline for entering a nested function.  */
                    643: 
                    644: #define TRAMPOLINE_SIZE 20
                    645: 
                    646: /* Emit RTL insns to initialize the variable parts of a trampoline.  */
                    647: 
                    648: #define INITIALIZE_TRAMPOLINE(TRAMP, FNADDR, CXT)                      \
                    649: {                                                                      \
                    650:   emit_move_insn (gen_rtx (MEM, SImode, plus_constant (TRAMP, 12)), CXT); \
                    651:   emit_move_insn (gen_rtx (MEM, SImode, plus_constant (TRAMP, 16)), FNADDR); \
                    652: }
                    653: 
                    654: /* Output assembler code to FILE to increment profiler label # LABELNO
                    655:    for profiling a function entry.  */
                    656: 
                    657: #define FUNCTION_PROFILER(FILE, LABELNO)                               \
                    658:   fprintf (FILE, "Error: No profiling availble.\n")
                    659: 
                    660: /* Define EXIT_IGNORE_STACK if, when returning from a function, the stack
                    661:    pointer does not matter (provided there is a frame pointer).  */
                    662: 
                    663: #define EXIT_IGNORE_STACK      1
                    664: 
                    665: /* Addressing modes, and classification of registers for them.  */
                    666: 
                    667: /* #define HAVE_POST_INCREMENT */
                    668: /* #define HAVE_POST_DECREMENT */
                    669: 
                    670: /* #define HAVE_PRE_DECREMENT */
                    671: /* #define HAVE_PRE_INCREMENT */
                    672: 
                    673: /* These assume that REGNO is a hard or pseudo reg number.  They give
                    674:    nonzero only if REGNO is a hard reg of the suitable class or a pseudo
                    675:    reg currently allocated to a suitable hard reg.
                    676:    These definitions are NOT overridden anywhere.  */
                    677: 
                    678: #define REGNO_OK_FOR_INDEX_P(REGNO)                                    \
                    679:   (((REGNO) > 0 && (REGNO) < 16)                                       \
                    680:     || (reg_renumber[REGNO] > 0 && reg_renumber[REGNO] < 16))
                    681: 
                    682: #define REGNO_OK_FOR_BASE_P(REGNO) REGNO_OK_FOR_INDEX_P(REGNO)
                    683: 
                    684: #define REGNO_OK_FOR_DATA_P(REGNO)                                     \
                    685:   ((REGNO) < 16 || (unsigned) reg_renumber[REGNO] < 16)
                    686: 
                    687: #define REGNO_OK_FOR_FP_P(REGNO)                                       \
                    688:   ((unsigned) ((REGNO) - 16) < 4 || (unsigned) (reg_renumber[REGNO] - 16) < 4)
                    689: 
                    690: /* Now macros that check whether X is a register and also,
                    691:    strictly, whether it is in a specified class.  */
                    692: 
                    693: /* 1 if X is a data register.  */
                    694: 
                    695: #define DATA_REG_P(X) (REG_P (X) && REGNO_OK_FOR_DATA_P (REGNO (X)))
                    696: 
                    697: /* 1 if X is an fp register.  */
                    698: 
                    699: #define FP_REG_P(X) (REG_P (X) && REGNO_OK_FOR_FP_P (REGNO (X)))
                    700: 
                    701: /* 1 if X is an address register.  */
                    702: 
                    703: #define ADDRESS_REG_P(X) (REG_P (X) && REGNO_OK_FOR_BASE_P (REGNO (X)))
                    704: 
                    705: /* Maximum number of registers that can appear in a valid memory address.  */
                    706: 
                    707: #define MAX_REGS_PER_ADDRESS 2
                    708: 
                    709: /* Recognize any constant value that is a valid address.  */
                    710: 
                    711: #define CONSTANT_ADDRESS_P(X)                                          \
                    712:   (GET_CODE (X) == LABEL_REF || GET_CODE (X) == SYMBOL_REF             \
                    713:   || GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST_DOUBLE         \
                    714:   || (GET_CODE (X) == CONST                                            \
                    715:          && GET_CODE (XEXP (XEXP (X, 0), 0)) == LABEL_REF)             \
                    716:   || (GET_CODE (X) == CONST                                            \
                    717:          && GET_CODE (XEXP (XEXP (X, 0), 0)) == SYMBOL_REF             \
                    718:          && !SYMBOL_REF_FLAG (XEXP (XEXP (X, 0), 0))))
                    719: 
                    720: /* Nonzero if the constant value X is a legitimate general operand.
                    721:    It is given that X satisfies CONSTANT_P or is a CONST_DOUBLE.  */
                    722: 
                    723: #define LEGITIMATE_CONSTANT_P(X) 1
                    724: 
                    725: /* The macros REG_OK_FOR..._P assume that the arg is a REG rtx and check
                    726:    its validity for a certain class.  We have two alternate definitions
                    727:    for each of them.  The usual definition accepts all pseudo regs; the
                    728:    other rejects them all.  The symbol REG_OK_STRICT causes the latter
                    729:    definition to be used.
                    730: 
                    731:    Most source files want to accept pseudo regs in the hope that they will
                    732:    get allocated to the class that the insn wants them to be in.
                    733:    Some source files that are used after register allocation
                    734:    need to be strict.  */
                    735: 
                    736: #ifndef REG_OK_STRICT
                    737: 
                    738: /* Nonzero if X is a hard reg that can be used as an index or if it is
                    739:   a pseudo reg.  */
                    740: 
                    741: #define REG_OK_FOR_INDEX_P(X)                                          \
                    742:   ((REGNO(X) > 0 && REGNO(X) < 16) || REGNO(X) >= 20)
                    743: 
                    744: /* Nonzero if X is a hard reg that can be used as a base reg or if it is
                    745:    a pseudo reg.  */
                    746: 
                    747: #define REG_OK_FOR_BASE_P(X)   REG_OK_FOR_INDEX_P(X)
                    748: 
                    749: #else /* REG_OK_STRICT */
                    750: 
                    751: /* Nonzero if X is a hard reg that can be used as an index.  */
                    752: 
                    753: #define REG_OK_FOR_INDEX_P(X) REGNO_OK_FOR_INDEX_P(REGNO(X))
                    754: 
                    755: /* Nonzero if X is a hard reg that can be used as a base reg.  */
                    756: 
                    757: #define REG_OK_FOR_BASE_P(X) REGNO_OK_FOR_BASE_P(REGNO(X))
                    758: 
                    759: #endif /* REG_OK_STRICT */
                    760: 
                    761: /* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression that is a
                    762:    valid memory address for an instruction.
                    763:    The MODE argument is the machine mode for the MEM expression
                    764:    that wants to use this address.
                    765: 
                    766:    The other macros defined here are used only in GO_IF_LEGITIMATE_ADDRESS,
                    767:    except for CONSTANT_ADDRESS_P which is actually machine-independent.  */
                    768: 
                    769: #define COUNT_REGS(X, REGS, FAIL)                                      \
                    770:  if (REG_P (X) && REG_OK_FOR_BASE_P (X))                               \
                    771:    REGS += 1;                                                          \
                    772:  else if (GET_CODE (X) != CONST_INT || (unsigned) INTVAL (X) >= 4096)  \
                    773:    goto FAIL;
                    774: 
                    775: #define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR)                                \
                    776: {                                                                      \
                    777:   if (REG_P (X) && REG_OK_FOR_BASE_P (X))                              \
                    778:     goto ADDR;                                                         \
                    779:   if (GET_CODE (X) == PLUS)                                            \
                    780:     {                                                                  \
                    781:       int regs = 0;                                                    \
                    782:       rtx x0 = XEXP (X, 0);                                            \
                    783:       rtx x1 = XEXP (X, 1);                                            \
                    784:       if (GET_CODE (x0) == PLUS)                                       \
                    785:        {                                                               \
                    786:          COUNT_REGS (XEXP (x0, 0), regs, FAIL);                        \
                    787:          COUNT_REGS (XEXP (x0, 1), regs, FAIL);                        \
                    788:          COUNT_REGS (x1, regs, FAIL);                                  \
                    789:          if (regs == 2)                                                \
                    790:            goto ADDR;                                                  \
                    791:        }                                                               \
                    792:       else if (GET_CODE (x1) == PLUS)                                  \
                    793:        {                                                               \
                    794:          COUNT_REGS (x0, regs, FAIL);                                  \
                    795:          COUNT_REGS (XEXP (x1, 0), regs, FAIL);                        \
                    796:          COUNT_REGS (XEXP (x1, 1), regs, FAIL);                        \
                    797:          if (regs == 2)                                                \
                    798:            goto ADDR;                                                  \
                    799:        }                                                               \
                    800:       else                                                             \
                    801:        {                                                               \
                    802:          COUNT_REGS (x0, regs, FAIL);                                  \
                    803:          COUNT_REGS (x1, regs, FAIL);                                  \
                    804:          if (regs != 0)                                                \
                    805:            goto ADDR;                                                  \
                    806:        }                                                               \
                    807:     }                                                                  \
                    808:   FAIL: ;                                                              \
                    809: }
                    810: 
                    811: /* The 370 has no mode dependent addresses.  */
                    812: 
                    813: #define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR, LABEL)
                    814: 
                    815: /* Try machine-dependent ways of modifying an illegitimate address
                    816:    to be legitimate.  If we find one, return the new, valid address.
                    817:    This macro is used in only one place: `memory_address' in explow.c.  */
                    818: 
                    819: #define LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN)                         \
                    820: {                                                                      \
                    821:   if (GET_CODE (X) == PLUS && CONSTANT_ADDRESS_P (XEXP (X, 1)))                \
                    822:     (X) = gen_rtx (PLUS, SImode, XEXP (X, 0),                          \
                    823:                   copy_to_mode_reg (SImode, XEXP (X, 1)));             \
                    824:   if (GET_CODE (X) == PLUS && CONSTANT_ADDRESS_P (XEXP (X, 0)))                \
                    825:     (X) = gen_rtx (PLUS, SImode, XEXP (X, 1),                          \
                    826:                   copy_to_mode_reg (SImode, XEXP (X, 0)));             \
                    827:   if (GET_CODE (X) == PLUS && GET_CODE (XEXP (X, 0)) == MULT)          \
                    828:     (X) = gen_rtx (PLUS, SImode, XEXP (X, 1),                          \
                    829:                   force_operand (XEXP (X, 0), 0));                     \
                    830:   if (GET_CODE (X) == PLUS && GET_CODE (XEXP (X, 1)) == MULT)          \
                    831:     (X) = gen_rtx (PLUS, SImode, XEXP (X, 0),                          \
                    832:                   force_operand (XEXP (X, 1), 0));                     \
                    833:   if (memory_address_p (MODE, X))                                      \
                    834:     goto WIN;                                                          \
                    835: }
                    836: 
                    837: /* Specify the machine mode that this machine uses for the index in the
                    838:    tablejump instruction.  */
                    839: 
                    840: #define CASE_VECTOR_MODE SImode
                    841: 
                    842: /* Define this if the tablejump instruction expects the table to contain
                    843:    offsets from the address of the table.
                    844:    Do not define this if the table should contain absolute addresses.  */
                    845: 
                    846: /* #define CASE_VECTOR_PC_RELATIVE */
                    847: 
                    848: /* Specify the tree operation to be used to convert reals to integers.  */
                    849: 
                    850: #define IMPLICIT_FIX_EXPR FIX_ROUND_EXPR
                    851: 
                    852: /* Define this if fixuns_trunc is the same as fix_trunc.  */
                    853: 
                    854: #define FIXUNS_TRUNC_LIKE_FIX_TRUNC
                    855: 
                    856: /* We use "unsigned char" as default.  */
                    857: 
                    858: #define DEFAULT_SIGNED_CHAR 0
                    859: 
                    860: /* This is the kind of divide that is easiest to do in the general case.  */
                    861: 
                    862: #define EASY_DIV_EXPR TRUNC_DIV_EXPR
                    863: 
                    864: /* Max number of bytes we can move from memory to memory in one reasonably
                    865:    fast instruction.  */
                    866: 
                    867: #define MOVE_MAX 256
                    868: 
                    869: /* Define this if zero-extension is slow (more than one real instruction).  */
                    870: 
                    871: #define SLOW_ZERO_EXTEND
                    872: 
                    873: /* Nonzero if access to memory by bytes is slow and undesirable.  */
                    874: 
                    875: #define SLOW_BYTE_ACCESS 1
                    876: 
                    877: /* Define if shifts truncate the shift count which implies one can omit
                    878:    a sign-extension or zero-extension of a shift count.  */
                    879: 
                    880: /* #define SHIFT_COUNT_TRUNCATED */
                    881: 
                    882: /* Value is 1 if truncating an integer of INPREC bits to OUTPREC bits
                    883:    is done just by pretending it is already truncated.  */
                    884: 
                    885: #define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) (OUTPREC != 16)
                    886: 
                    887: /* We assume that the store-condition-codes instructions store 0 for false
                    888:    and some other value for true.  This is the value stored for true.  */
                    889: 
                    890: /* #define STORE_FLAG_VALUE -1 */
                    891: 
                    892: /* When a prototype says `char' or `short', really pass an `int'.  */
                    893: 
                    894: #define PROMOTE_PROTOTYPES
                    895: 
                    896: /* Don't perform CSE on function addresses.  */
                    897: 
                    898: #define NO_FUNCTION_CSE
                    899: 
                    900: /* Specify the machine mode that pointers have.
                    901:    After generation of rtl, the compiler makes no further distinction
                    902:    between pointers and any other objects of this machine mode.  */
                    903: 
                    904: #define Pmode SImode
                    905: 
                    906: /* A function address in a call instruction is a byte address (for
                    907:    indexing purposes) so give the MEM rtx a byte's mode.  */
                    908: 
                    909: #define FUNCTION_MODE QImode
                    910: 
                    911: /* Compute the cost of computing a constant rtl expression RTX whose
                    912:    rtx-code is CODE.  The body of this macro is a portion of a switch
                    913:    statement.  If the code is computed here, return it with a return
                    914:    statement.  Otherwise, break from the switch.  */
                    915: 
                    916: #define CONST_COSTS(RTX, CODE, OUTERCODE)                              \
                    917:   case CONST_INT:                                                      \
                    918:     if ((unsigned) INTVAL (RTX) < 0xfff) return 1;                     \
                    919:   case CONST:                                                          \
                    920:   case LABEL_REF:                                                      \
                    921:   case SYMBOL_REF:                                                     \
                    922:     return 2;                                                          \
                    923:   case CONST_DOUBLE:                                                   \
                    924:     return 4;
                    925: 
                    926: /* Tell final.c how to eliminate redundant test instructions.  */
                    927: 
                    928: /* Here we define machine-dependent flags and fields in cc_status
                    929:    (see `conditions.h').  */
                    930: 
                    931: /* Store in cc_status the expressions that the condition codes will
                    932:    describe after execution of an instruction whose pattern is EXP.
                    933:    Do not alter them if the instruction would not alter the cc's.
                    934: 
                    935:    On the 370, load insns do not alter the cc's.  However, in some
                    936:    cases these instructions can make it possibly invalid to use the
                    937:    saved cc's.  In those cases we clear out some or all of the saved
                    938:    cc's so they won't be used.  */
                    939: 
                    940: #define NOTICE_UPDATE_CC(EXP, INSN)                                    \
                    941: {                                                                      \
                    942:   rtx exp = (EXP);                                                     \
                    943:   if (GET_CODE (exp) == PARALLEL) /* Check this */                     \
                    944:     exp = XVECEXP (exp, 0, 0);                                         \
                    945:   if (GET_CODE (exp) != SET)                                           \
                    946:     CC_STATUS_INIT;                                                    \
                    947:   else                                                                 \
                    948:     {                                                                  \
                    949:       if (XEXP (exp, 0) == cc0_rtx)                                    \
                    950:        {                                                               \
                    951:          cc_status.value1 = XEXP (exp, 0);                             \
                    952:          cc_status.value2 = XEXP (exp, 1);                             \
                    953:          cc_status.flags = 0;                                          \
                    954:        }                                                               \
                    955:       else                                                             \
                    956:        {                                                               \
                    957:          if (cc_status.value1                                          \
                    958:              && reg_mentioned_p (XEXP (exp, 0), cc_status.value1))     \
                    959:            cc_status.value1 = 0;                                       \
                    960:          if (cc_status.value2                                          \
                    961:              && reg_mentioned_p (XEXP (exp, 0), cc_status.value2))     \
                    962:            cc_status.value2 = 0;                                       \
                    963:          switch (GET_CODE (XEXP (exp, 1)))                             \
                    964:            {                                                           \
                    965:              case PLUS:     case MINUS: case MULT:   /* case UMULT: */ \
                    966:              case DIV:      case UDIV:  case NEG:    case ASHIFT:      \
                    967:              case ASHIFTRT: case AND:   case IOR:    case XOR:         \
                    968:              case ABS:      case NOT:                                  \
                    969:                CC_STATUS_SET (XEXP (exp, 0), XEXP (exp, 1));           \
                    970:            }                                                           \
                    971:        }                                                               \
                    972:     }                                                                  \
                    973: }
                    974: 
                    975: 
                    976: #define CC_STATUS_SET(V1, V2)                                          \
                    977: {                                                                      \
                    978:   cc_status.flags = 0;                                                 \
                    979:   cc_status.value1 = (V1);                                             \
                    980:   cc_status.value2 = (V2);                                             \
                    981:   if (cc_status.value1                                                 \
                    982:       && reg_mentioned_p (cc_status.value1, cc_status.value2))         \
                    983:     cc_status.value2 = 0;                                              \
                    984: }
                    985: 
                    986: #define OUTPUT_JUMP(NORMAL, FLOAT, NO_OV)                              \
                    987: { if (cc_status.flags & CC_NO_OVERFLOW)        return NO_OV; return NORMAL; }
                    988: 
                    989: /* Control the assembler format that we output.  */
                    990: 
                    991: #define TEXT_SECTION_ASM_OP "* Program text area"
                    992: #define DATA_SECTION_ASM_OP "* Program data area"
                    993: #define INIT_SECTION_ASM_OP "* Program initialization area"
                    994: #define CTOR_LIST_BEGIN                /* NO OP */
                    995: #define CTOR_LIST_END          /* NO OP */
                    996: 
                    997: /* How to refer to registers in assembler output.  This sequence is
                    998:    indexed by compiler's hard-register-number (see above).  */
                    999: 
                   1000: #define REGISTER_NAMES                                                 \
                   1001: { "0",  "1",  "2",  "3",  "4",  "5",  "6",  "7",                       \
                   1002:   "8",  "9", "10", "11", "12", "13", "14", "15",                       \
                   1003:   "0",  "2",  "4",  "6"                                                        \
                   1004: }
                   1005: 
                   1006: /* How to renumber registers for dbx and gdb.  */
                   1007: 
                   1008: #define DBX_REGISTER_NUMBER(REGNO) (REGNO)
                   1009: 
                   1010: #define ASM_FILE_START(FILE) fputs ("\tCSECT\n", FILE);
                   1011: #define ASM_FILE_END(FILE) fputs ("\tEND\n", FILE);
                   1012: #define ASM_IDENTIFY_GCC(FILE)
                   1013: #define ASM_COMMENT_START "*"
                   1014: #define ASM_APP_OFF ""
                   1015: #define ASM_APP_ON ""
                   1016: 
                   1017: #define ASM_OUTPUT_LABEL(FILE, NAME)                                   \
                   1018: { assemble_name (FILE, NAME); fputs ("\tEQU\t*\n", FILE); }
                   1019: 
                   1020: #define ASM_OUTPUT_EXTERNAL(FILE, DECL, NAME)  /* NO OP */
                   1021: 
                   1022: #define ASM_GLOBALIZE_LABEL(FILE, NAME)                                        \
                   1023: { fputs ("\tENTRY\t", FILE); assemble_name (FILE, NAME); fputs ("\n", FILE); }
                   1024: 
                   1025: /* MVS externals are limited to 8 characters, upper case only.
                   1026:    The '_' is mapped to '@', except for MVS functions, then '#'.  */
                   1027: 
                   1028: #define MAX_MVS_LABEL_SIZE 8
                   1029: 
                   1030: #define ASM_OUTPUT_LABELREF(FILE, NAME)                                        \
                   1031: {                                                                      \
                   1032:   char *bp, ch, temp[MAX_MVS_LABEL_SIZE + 1];                          \
                   1033:   if (strlen (NAME) > MAX_MVS_LABEL_SIZE)                              \
                   1034:     {                                                                  \
                   1035:       strncpy (temp, NAME, MAX_MVS_LABEL_SIZE);                                \
                   1036:       temp[MAX_MVS_LABEL_SIZE] = '\0';                                 \
                   1037:     }                                                                  \
                   1038:   else                                                                 \
                   1039:     strcpy (temp,NAME);                                                        \
                   1040:   if (!strcmp (temp,"main"))                                           \
                   1041:     strcpy (temp,"gccmain");                                           \
                   1042:   if (mvs_function_check (temp))                                       \
                   1043:     ch = '#';                                                          \
                   1044:   else                                                                 \
                   1045:     ch = '@';                                                          \
                   1046:   for (bp = temp; *bp; bp++)                                           \
                   1047:     {                                                                  \
                   1048:       if (islower (*bp)) *bp = toupper (*bp);                          \
                   1049:       if (*bp == '_') *bp = ch;                                                \
                   1050:     }                                                                  \
                   1051:   fprintf (FILE, "%s", temp);                                          \
                   1052: }
                   1053: 
                   1054: #define ASM_GENERATE_INTERNAL_LABEL(LABEL, PREFIX, NUM)                        \
                   1055:   sprintf (LABEL, "*%s%d", PREFIX, NUM)
                   1056: 
                   1057: /* Generate internal label.  Since we can branch here from off page, we
                   1058:    must reload the base register.  */
                   1059: 
                   1060: #define ASM_OUTPUT_INTERNAL_LABEL(FILE, PREFIX, NUM)                   \
                   1061: {                                                                      \
                   1062:   if (!strcmp (PREFIX,"L"))                                            \
                   1063:     {                                                                  \
                   1064:       mvs_add_label(NUM);                                              \
                   1065:       mvs_label_emited = 1;                                            \
                   1066:     }                                                                  \
                   1067:   fprintf (FILE, "%s%d\tEQU\t*\n", PREFIX, NUM);                       \
                   1068: }
                   1069: 
                   1070: /* Generate case label.  */
                   1071: 
                   1072: #define ASM_OUTPUT_CASE_LABEL(FILE, PREFIX, NUM, TABLE)                        \
                   1073:    fprintf (FILE, "%s%d\tEQU\t*\n", PREFIX, NUM)
                   1074: 
                   1075: /* This is how to output an element of a case-vector that is absolute.  */
                   1076: 
                   1077: #define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE)                           \
                   1078:   mvs_check_page (FILE, 4, 0);                                         \
                   1079:   fprintf (FILE, "\tDC\tA(L%d)\n", VALUE)
                   1080: 
                   1081: /* This is how to output an element of a case-vector that is relative.  */
                   1082: 
                   1083: #define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, VALUE, REL)                     \
                   1084:   mvs_check_page (FILE, 4, 0);                                         \
                   1085:   fprintf (FILE, "\tDC\tA(L%d-L%d)\n", VALUE, REL)
                   1086: 
                   1087: /* This is how to output an insn to push a register on the stack.
                   1088:    It need not be very fast code.  */
                   1089: 
                   1090: #define ASM_OUTPUT_REG_PUSH(FILE, REGNO)                               \
                   1091:   mvs_check_page (FILE, 8, 4);                                         \
                   1092:   fprintf (FILE, "\tS\t13,=F'4'\n\tST\t%s,%d(13)\n",                   \
                   1093:      reg_names[REGNO], STACK_POINTER_OFFSET)
                   1094: 
                   1095: /* This is how to output an insn to pop a register from the stack.
                   1096:    It need not be very fast code.  */
                   1097: 
                   1098: #define ASM_OUTPUT_REG_POP(FILE, REGNO)                                        \
                   1099:   mvs_check_page (FILE, 8, 0);                                         \
                   1100:   fprintf (FILE, "\tL\t%s,%d(13)\n\tLA\t13,4(13)\n",                   \
                   1101:      reg_names[REGNO], STACK_POINTER_OFFSET)
                   1102: 
                   1103: /* This is how to output an assembler line defining a `double' constant.  */
                   1104: 
                   1105: #define ASM_OUTPUT_DOUBLE(FILE, VALUE)                                 \
                   1106:   fprintf (FILE, "\tDC\tD'%.18G'\n", (VALUE))
                   1107: 
                   1108: /* This is how to output an assembler line defining a `float' constant.  */
                   1109: 
                   1110: #define ASM_OUTPUT_FLOAT(FILE, VALUE)                                  \
                   1111:   fprintf (FILE, "\tDC\tE'%.9G'\n", (VALUE))
                   1112: 
                   1113: /* This outputs an integer, if not a CONST_INT must be address constant.  */
                   1114: 
                   1115: #define ASM_OUTPUT_INT(FILE, EXP)                                      \
                   1116: {                                                                      \
                   1117:   if (GET_CODE (EXP) == CONST_INT)                                     \
                   1118:     {                                                                  \
                   1119:       fprintf (FILE, "\tDC\tF'");                                      \
                   1120:       output_addr_const (FILE, EXP);                                   \
                   1121:       fprintf (FILE, "'\n");                                           \
                   1122:     }                                                                  \
                   1123:   else                                                                 \
                   1124:     {                                                                  \
                   1125:       fprintf (FILE, "\tDC\tA(");                                      \
                   1126:       output_addr_const (FILE, EXP);                                   \
                   1127:       fprintf (FILE, ")\n");                                           \
                   1128:     }                                                                  \
                   1129: }
                   1130: 
                   1131: /* This outputs a short integer.  */
                   1132: 
                   1133: #define ASM_OUTPUT_SHORT(FILE, EXP)                                    \
                   1134: {                                                                      \
                   1135:   fprintf (FILE, "\tDC\tH'");                                          \
                   1136:   output_addr_const (FILE, EXP);                                       \
                   1137:   fprintf (FILE, "'\n");                                               \
                   1138: }
                   1139: 
                   1140: /* This outputs a byte sized integer.  */
                   1141: 
                   1142: #define ASM_OUTPUT_CHAR(FILE, EXP)                                     \
                   1143:   fprintf (FILE, "\tDC\tX'%02X'\n", INTVAL (EXP) )
                   1144: 
                   1145: #define ASM_OUTPUT_BYTE(FILE, VALUE)                                   \
                   1146:   fprintf (FILE, "\tDC\tX'%02X'\n", VALUE)
                   1147: 
                   1148: /* This outputs a text string.  The string are chopped up to fit into
                   1149:    an 80 byte record.  Also, control and special characters, interpreted
                   1150:    by the IBM assembler, are output numerically.  */
                   1151: 
                   1152: #define MVS_ASCII_TEXT_LENGTH 48
                   1153: 
                   1154: #define ASM_OUTPUT_ASCII(FILE, PTR, LEN)                               \
                   1155: {                                                                      \
                   1156:   int i, j;                                                            \
                   1157:   int c;                                                               \
                   1158:   for (j = 0, i = 0; i < LEN; j++, i++)                                        \
                   1159:     {                                                                  \
                   1160:       c = PTR[i];                                                      \
                   1161:       if (iscntrl (c) || c == '&')                                     \
                   1162:        {                                                               \
                   1163:          if (j % MVS_ASCII_TEXT_LENGTH != 0 )                          \
                   1164:            fprintf (FILE, "'\n");                                      \
                   1165:          j = -1;                                                       \
                   1166:          if (c == '&') c = MAP_CHARACTER (c);                          \
                   1167:          fprintf (FILE, "\tDC\tX'%X'\n", c );                          \
                   1168:        }                                                               \
                   1169:       else                                                             \
                   1170:        {                                                               \
                   1171:          if (j % MVS_ASCII_TEXT_LENGTH == 0)                           \
                   1172:             fprintf (FILE, "\tDC\tC'%c", c);                           \
                   1173:          else                                                          \
                   1174:            {                                                           \
                   1175:              if ( c == '\'' )                                          \
                   1176:                fprintf (FILE, "%c%c", c, c);                           \
                   1177:              else                                                      \
                   1178:                fprintf (FILE, "%c", c);                                \
                   1179:              if (j % MVS_ASCII_TEXT_LENGTH                             \
                   1180:                  == MVS_ASCII_TEXT_LENGTH - 1)                         \
                   1181:                fprintf (FILE, "'\n" );                                 \
                   1182:            }                                                           \
                   1183:        }                                                               \
                   1184:     }                                                                  \
                   1185:   if (j % MVS_ASCII_TEXT_LENGTH != 0)                                  \
                   1186:     fprintf (FILE, "'\n");                                             \
                   1187: }
                   1188: 
                   1189: /* This is how to output an assembler line that says to advance the
                   1190:    location counter to a multiple of 2**LOG bytes.  */
                   1191: 
                   1192: #define ASM_OUTPUT_ALIGN(FILE, LOG)                                    \
                   1193:   if (LOG)                                                             \
                   1194:     {                                                                  \
                   1195:       if ((LOG) == 1)                                                  \
                   1196:         fprintf (FILE, "\tDS\t0H\n" );                                 \
                   1197:       else                                                             \
                   1198:         fprintf (FILE, "\tDS\t0F\n" );                                 \
                   1199:     }                                                                  \
                   1200: 
                   1201: /* The maximum length of memory that the IBM assembler will allow in one
                   1202:    DS operation.  */
                   1203: 
                   1204: #define MAX_CHUNK 32767
                   1205: 
                   1206: /* A C statement to output to the stdio stream FILE an assembler
                   1207:    instruction to advance the location counter by SIZE bytes. Those
                   1208:    bytes should be zero when loaded.  */
                   1209: 
                   1210: #define ASM_OUTPUT_SKIP(FILE, SIZE)                                    \
                   1211: {                                                                      \
                   1212:   int s, k;                                                            \
                   1213:   for (s = (SIZE); s > 0; s -= MAX_CHUNK)                              \
                   1214:     {                                                                  \
                   1215:       if (s > MAX_CHUNK)                                               \
                   1216:        k = MAX_CHUNK;                                                  \
                   1217:       else                                                             \
                   1218:        k = s;                                                          \
                   1219:       fprintf (FILE, "\tDS\tXL%d\n", k);                               \
                   1220:     }                                                                  \
                   1221: }
                   1222: 
                   1223: /* A C statement (sans semicolon) to output to the stdio stream
                   1224:    FILE the assembler definition of a common-label named NAME whose
                   1225:    size is SIZE bytes.  The variable ROUNDED is the size rounded up
                   1226:    to whatever alignment the caller wants.  */
                   1227: 
                   1228: #define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED)                   \
                   1229: {                                                                      \
                   1230:   fputs ("\tENTRY\t", FILE);                                           \
                   1231:   assemble_name (FILE, NAME);                                          \
                   1232:   fputs ("\n", FILE);                                                  \
                   1233:   fprintf (FILE, "\tDS\t0F\n");                                                \
                   1234:   ASM_OUTPUT_LABEL (FILE,NAME);                                                \
                   1235:   ASM_OUTPUT_SKIP (FILE,SIZE);                                         \
                   1236: }
                   1237: 
                   1238: /* A C statement (sans semicolon) to output to the stdio stream
                   1239:    FILE the assembler definition of a local-common-label named NAME
                   1240:    whose size is SIZE bytes.  The variable ROUNDED is the size
                   1241:    rounded up to whatever alignment the caller wants.  */
                   1242: 
                   1243: #define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE, ROUNDED)                    \
                   1244: {                                                                      \
                   1245:   fprintf (FILE, "\tDS\t0F\n");                                                \
                   1246:   ASM_OUTPUT_LABEL (FILE,NAME);                                                \
                   1247:   ASM_OUTPUT_SKIP (FILE,SIZE);                                         \
                   1248: }
                   1249: 
                   1250: /* Store in OUTPUT a string (made with alloca) containing an
                   1251:    assembler-name for a local static variable named NAME.
                   1252:    LABELNO is an integer which is different for each call.  */
                   1253: 
                   1254: #define ASM_FORMAT_PRIVATE_NAME(OUTPUT, NAME, LABELNO)                 \
                   1255: {                                                                      \
                   1256:   (OUTPUT) = (char *) alloca (strlen ((NAME)) + 10);                   \
                   1257:   sprintf ((OUTPUT), "%s%d", (NAME), (LABELNO));                       \
                   1258: }
                   1259: 
                   1260: /* Define the parentheses used to group arithmetic operations
                   1261:    in assembler code.  */
                   1262: 
                   1263: #define ASM_OPEN_PAREN "("
                   1264: #define ASM_CLOSE_PAREN ")"
                   1265: 
                   1266: /* Define results of standard character escape sequences.  */
                   1267: 
                   1268: #define TARGET_BELL    47
                   1269: #define TARGET_BS      22
                   1270: #define TARGET_TAB     5
                   1271: #define TARGET_NEWLINE 21
                   1272: #define TARGET_VT      11
                   1273: #define TARGET_FF      12
                   1274: #define TARGET_CR      13
                   1275: 
                   1276: /* Print operand X (an rtx) in assembler syntax to file FILE.
                   1277:    CODE is a letter or dot (`z' in `%z0') or 0 if no letter was specified.
                   1278:    For `%' followed by punctuation, CODE is the punctuation and X is null.  */
                   1279: 
                   1280: #define PRINT_OPERAND(FILE, X, CODE)                                   \
                   1281: {                                                                      \
                   1282:   switch (GET_CODE (X))                                                        \
                   1283:     {                                                                  \
                   1284:       static char curreg[4];                                           \
                   1285:       case REG:                                                                \
                   1286:        if (CODE == 'N')                                                \
                   1287:            strcpy (curreg, reg_names[REGNO (X) + 1]);                  \
                   1288:        else                                                            \
                   1289:            strcpy (curreg, reg_names[REGNO (X)]);                      \
                   1290:        fprintf (FILE, "%s", curreg);                                   \
                   1291:        break;                                                          \
                   1292:       case MEM:                                                                \
                   1293:        {                                                               \
                   1294:          rtx addr = XEXP (X, 0);                                       \
                   1295:          if (CODE == 'O')                                              \
                   1296:            {                                                           \
                   1297:              if (GET_CODE (addr) == PLUS)                              \
                   1298:                fprintf (FILE, "%d", INTVAL (XEXP (addr, 1)));          \
                   1299:              else                                                      \
                   1300:                fprintf (FILE, "0");                                    \
                   1301:            }                                                           \
                   1302:          else if (CODE == 'R')                                         \
                   1303:            {                                                           \
                   1304:              if (GET_CODE (addr) == PLUS)                              \
                   1305:                fprintf (FILE, "%s", reg_names[REGNO (XEXP (addr, 0))]);\
                   1306:              else                                                      \
                   1307:                fprintf (FILE, "%s", reg_names[REGNO (addr)]);          \
                   1308:            }                                                           \
                   1309:          else                                                          \
                   1310:            output_address (XEXP (X, 0));                               \
                   1311:        }                                                               \
                   1312:        break;                                                          \
                   1313:       case SYMBOL_REF:                                                 \
                   1314:       case LABEL_REF:                                                  \
                   1315:        mvs_page_lit += 4;                                              \
                   1316:        if (SYMBOL_REF_FLAG (X)) fprintf (FILE, "=V(");                 \
                   1317:        else                     fprintf (FILE, "=A(");                 \
                   1318:        output_addr_const (FILE, X);                                    \
                   1319:        fprintf (FILE, ")");                                            \
                   1320:        break;                                                          \
                   1321:       case CONST_INT:                                                  \
                   1322:        if (CODE == 'B')                                                \
                   1323:          fprintf (FILE, "%d", INTVAL (X) & 0xff);                      \
                   1324:        else if (CODE == 'X')                                           \
                   1325:          fprintf (FILE, "%02X", INTVAL (X) & 0xff);                    \
                   1326:        else if (CODE == 'h')                                           \
                   1327:          fprintf (FILE, "%d", (INTVAL (X) << 16) >> 16);               \
                   1328:        else if (CODE == 'H')                                           \
                   1329:          {                                                             \
                   1330:            mvs_page_lit += 4;                                          \
                   1331:            fprintf (FILE, "=F'%d'", (INTVAL (X) << 16) >> 16);         \
                   1332:          }                                                             \
                   1333:        else                                                            \
                   1334:          {                                                             \
                   1335:            mvs_page_lit += 4;                                          \
                   1336:            fprintf (FILE, "=F'%d'", INTVAL (X));                       \
                   1337:          }                                                             \
                   1338:        break;                                                          \
                   1339:       case CONST_DOUBLE:                                               \
                   1340:        if (GET_MODE (X) == DImode)                                     \
                   1341:          {                                                             \
                   1342:            if (CODE == 'M')                                            \
                   1343:              {                                                         \
                   1344:                mvs_page_lit += 4;                                      \
                   1345:                fprintf (FILE, "=XL4'%08X'", CONST_DOUBLE_LOW (X));     \
                   1346:              }                                                         \
                   1347:            else if (CODE == 'L')                                       \
                   1348:              {                                                         \
                   1349:                mvs_page_lit += 4;                                      \
                   1350:                fprintf (FILE, "=XL4'%08X'", CONST_DOUBLE_HIGH (X));    \
                   1351:              }                                                         \
                   1352:            else                                                        \
                   1353:              {                                                         \
                   1354:                mvs_page_lit += 8;                                      \
                   1355:                fprintf (FILE, "=XL8'%08X%08X'", CONST_DOUBLE_LOW (X),  \
                   1356:                        CONST_DOUBLE_HIGH (X));                         \
                   1357:              }                                                         \
                   1358:          }                                                             \
                   1359:        else                                                            \
                   1360:          {                                                             \
                   1361:            union { double d; int i[2]; } u;                            \
                   1362:            u.i[0] = CONST_DOUBLE_LOW (X);                              \
                   1363:            u.i[1] = CONST_DOUBLE_HIGH (X);                             \
                   1364:            if (GET_MODE (X) == SFmode)                                 \
                   1365:              {                                                         \
                   1366:                mvs_page_lit += 4;                                      \
                   1367:                fprintf (FILE, "=E'%.9G'", u.d);                        \
                   1368:              }                                                         \
                   1369:            else                                                        \
                   1370:              {                                                         \
                   1371:                mvs_page_lit += 8;                                      \
                   1372:                fprintf (FILE, "=D'%.18G'", u.d);                       \
                   1373:              }                                                         \
                   1374:          }                                                             \
                   1375:        break;                                                          \
                   1376:       case CONST:                                                      \
                   1377:        if (GET_CODE (XEXP (X, 0)) == PLUS                              \
                   1378:           && GET_CODE (XEXP (XEXP (X, 0), 0)) == SYMBOL_REF)           \
                   1379:          {                                                             \
                   1380:            mvs_page_lit += 4;                                          \
                   1381:            if (SYMBOL_REF_FLAG (XEXP (XEXP (X, 0), 0)))                \
                   1382:              {                                                         \
                   1383:                fprintf (FILE, "=V(");                                  \
                   1384:                ASM_OUTPUT_LABELREF (FILE,                              \
                   1385:                                  XSTR (XEXP (XEXP (X, 0), 0), 0));     \
                   1386:                fprintf (FILE, ")\n\tA\t%s,=F'%d'", curreg,             \
                   1387:                                  INTVAL (XEXP (XEXP (X, 0), 1)));      \
                   1388:              }                                                         \
                   1389:            else                                                        \
                   1390:              {                                                         \
                   1391:                fprintf (FILE, "=A(");                                  \
                   1392:                output_addr_const (FILE, X);                            \
                   1393:                fprintf (FILE, ")");                                    \
                   1394:              }                                                         \
                   1395:          }                                                             \
                   1396:        else                                                            \
                   1397:          {                                                             \
                   1398:            mvs_page_lit += 4;                                          \
                   1399:            fprintf (FILE, "=F'");                                      \
                   1400:            output_addr_const (FILE, X);                                \
                   1401:            fprintf (FILE, "'");                                        \
                   1402:          }                                                             \
                   1403:        break;                                                          \
                   1404:       default:                                                         \
                   1405:        abort();                                                        \
                   1406:     }                                                                  \
                   1407: }
                   1408: 
                   1409: #define PRINT_OPERAND_ADDRESS(FILE, ADDR)                              \
                   1410: {                                                                      \
                   1411:   rtx breg, xreg, offset, plus;                                                \
                   1412:                                                                        \
                   1413:   switch (GET_CODE (ADDR))                                             \
                   1414:     {                                                                  \
                   1415:       case REG:                                                                \
                   1416:        fprintf (FILE, "0(%s)", reg_names[REGNO (ADDR)]);               \
                   1417:        break;                                                          \
                   1418:       case PLUS:                                                       \
                   1419:        breg = 0;                                                       \
                   1420:        xreg = 0;                                                       \
                   1421:        offset = 0;                                                     \
                   1422:        if (GET_CODE (XEXP (ADDR, 0)) == PLUS)                          \
                   1423:          {                                                             \
                   1424:            if (GET_CODE (XEXP (ADDR, 1)) == REG)                       \
                   1425:              breg = XEXP (ADDR, 1);                                    \
                   1426:            else                                                        \
                   1427:              offset = XEXP (ADDR, 1);                                  \
                   1428:            plus = XEXP (ADDR, 0);                                      \
                   1429:          }                                                             \
                   1430:        else                                                            \
                   1431:          {                                                             \
                   1432:            if (GET_CODE (XEXP (ADDR, 0)) == REG)                       \
                   1433:              breg = XEXP (ADDR, 0);                                    \
                   1434:            else                                                        \
                   1435:              offset = XEXP (ADDR, 0);                                  \
                   1436:            plus = XEXP (ADDR, 1);                                      \
                   1437:          }                                                             \
                   1438:        if (GET_CODE (plus) == PLUS)                                    \
                   1439:          {                                                             \
                   1440:            if (GET_CODE (XEXP (plus, 0)) == REG)                       \
                   1441:              {                                                         \
                   1442:                if (breg)                                               \
                   1443:                  xreg = XEXP (plus, 0);                                \
                   1444:                else                                                    \
                   1445:                  breg = XEXP (plus, 0);                                \
                   1446:              }                                                         \
                   1447:            else                                                        \
                   1448:              {                                                         \
                   1449:                offset = XEXP (plus, 0);                                \
                   1450:              }                                                         \
                   1451:            if (GET_CODE (XEXP (plus, 1)) == REG)                       \
                   1452:              {                                                         \
                   1453:                if (breg)                                               \
                   1454:                  xreg = XEXP (plus, 1);                                \
                   1455:                else                                                    \
                   1456:                  breg = XEXP (plus, 1);                                \
                   1457:              }                                                         \
                   1458:            else                                                        \
                   1459:              {                                                         \
                   1460:                offset = XEXP (plus, 1);                                \
                   1461:              }                                                         \
                   1462:          }                                                             \
                   1463:        else if (GET_CODE (plus) == REG)                                \
                   1464:          {                                                             \
                   1465:            if (breg)                                                   \
                   1466:              xreg = plus;                                              \
                   1467:            else                                                        \
                   1468:              breg = plus;                                              \
                   1469:          }                                                             \
                   1470:        else                                                            \
                   1471:          {                                                             \
                   1472:            offset = plus;                                              \
                   1473:          }                                                             \
                   1474:        if (offset)                                                     \
                   1475:          {                                                             \
                   1476:            if (GET_CODE (offset) == LABEL_REF)                         \
                   1477:              fprintf (FILE, "L%d",                                     \
                   1478:                        CODE_LABEL_NUMBER (XEXP (offset, 0)));          \
                   1479:            else                                                        \
                   1480:              output_addr_const (FILE, offset);                         \
                   1481:          }                                                             \
                   1482:        else                                                            \
                   1483:          fprintf (FILE, "0");                                          \
                   1484:        if (xreg)                                                       \
                   1485:            fprintf (FILE, "(%s,%s)",                                   \
                   1486:                    reg_names[REGNO (xreg)], reg_names[REGNO (breg)]);  \
                   1487:        else                                                            \
                   1488:          fprintf (FILE, "(%s)", reg_names[REGNO (breg)]);              \
                   1489:        break;                                                          \
                   1490:       default:                                                         \
                   1491:        mvs_page_lit += 4;                                              \
                   1492:        if (SYMBOL_REF_FLAG (ADDR)) fprintf (FILE, "=V(");              \
                   1493:        else                        fprintf (FILE, "=A(");              \
                   1494:        output_addr_const (FILE, ADDR);                                 \
                   1495:        fprintf (FILE, ")");                                            \
                   1496:        break;                                                          \
                   1497:     }                                                                  \
                   1498: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.