|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.