Annotation of GNUtools/cc/config/i370/mvs.h, revision 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.