Annotation of gcc/config/tahoe/tahoe.h, revision 1.1.1.4

1.1       root        1: /* Definitions of target machine for GNU compiler.  Tahoe version.
1.1.1.4 ! root        2:    Copyright (C) 1989, 1993, 1994, 1995 Free Software Foundation, Inc.
1.1       root        3: 
                      4: This file is part of GNU CC.
                      5: 
                      6: GNU CC is free software; you can redistribute it and/or modify
                      7: it under the terms of the GNU General Public License as published by
                      8: the Free Software Foundation; either version 2, or (at your option)
                      9: any later version.
                     10: 
                     11: GNU CC is distributed in the hope that it will be useful,
                     12: but WITHOUT ANY WARRANTY; without even the implied warranty of
                     13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                     14: GNU General Public License for more details.
                     15: 
                     16: You should have received a copy of the GNU General Public License
                     17: along with GNU CC; see the file COPYING.  If not, write to
1.1.1.4 ! root       18: the Free Software Foundation, 59 Temple Place - Suite 330,
        !            19: Boston, MA 02111-1307, USA.  */
1.1       root       20: 
                     21: /*
                     22:  * Original port made at the University of Buffalo by Devon Bowen,
                     23:  * Dale Wiles and Kevin Zachmann.
                     24:  *
                     25:  * HCX/UX version by Piet van Oostrum ([email protected])
                     26:  *
1.1.1.3   root       27:  * Performance hacking by Michael Tiemann ([email protected])
1.1       root       28:  */
                     29: 
                     30: /* define this for the HCX/UX version */
                     31: 
                     32: /* #define HCX_UX */
                     33: 
                     34: /*
                     35:  * Run-time Target Specification
                     36:  */
                     37: 
                     38: #ifdef HCX_UX
                     39: /* no predefines, see Makefile and hcx-universe.c */
                     40: /* have cc1 print that this is the hcx version */
                     41: #define TARGET_VERSION printf (" (hcx)");
                     42: #else
                     43: /* we want "tahoe" and "unix" defined for all future compilations */
1.1.1.2   root       44: #define CPP_PREDEFINES "-Dtahoe -Dunix -Asystem(unix) -Acpu(tahoe) -Amachine(tahoe)"
1.1       root       45: /* have cc1 print that this is the tahoe version */
                     46: #define TARGET_VERSION printf (" (tahoe)");
                     47: #endif
                     48: 
                     49: /* this is required in all tm files to hold flags */
                     50: 
                     51: extern int target_flags;
                     52: 
                     53: /* Zero if it is safe to output .dfloat and .float pseudos.  */
                     54: #define TARGET_HEX_FLOAT (target_flags & 1)
                     55: 
                     56: #define TARGET_DEFAULT 1
                     57: 
                     58: #define TARGET_SWITCHES                \
                     59:   { {"hex-float", 1},          \
                     60:     {"no-hex-float", -1},      \
                     61:     { "", TARGET_DEFAULT} }
                     62: 
                     63: 
                     64: /*
                     65:  * Storage Layout
                     66:  */
                     67: 
                     68: /* This symbol was previously not mentioned, so apparently the tahoe
                     69:    is little-endian for bits, or else doesn't care.  */
                     70: #define BITS_BIG_ENDIAN 0
                     71: 
                     72: /* tahoe uses a big endian byte order */
                     73: 
                     74: #define BYTES_BIG_ENDIAN 1
                     75: 
                     76: /* tahoe uses a big endian word order */
                     77: 
                     78: #define WORDS_BIG_ENDIAN 1
                     79: 
                     80: /* standard byte size is usable on tahoe */
                     81: 
                     82: #define BITS_PER_UNIT 8
                     83: 
                     84: /* longs on the tahoe are 4 byte groups */
                     85: 
                     86: #define BITS_PER_WORD 32
                     87: 
                     88: /* from the last two params we get 4 bytes per word */
                     89: 
                     90: #define UNITS_PER_WORD 4
                     91: 
                     92: /* addresses are 32 bits (one word) */
                     93: 
                     94: #define POINTER_SIZE 32
                     95: 
                     96: /* all parameters line up on 32 boundaries */
                     97: 
                     98: #define PARM_BOUNDARY 32
                     99: 
                    100: /* stack should line up on 32 boundaries */
                    101: 
                    102: #define STACK_BOUNDARY 32
                    103: 
                    104: /* line functions up on 32 bits */
                    105: 
                    106: #define FUNCTION_BOUNDARY 32
                    107: 
                    108: /* the biggest alignment the tahoe needs in 32 bits */
                    109: 
                    110: #define BIGGEST_ALIGNMENT 32
                    111: 
                    112: /* we have to align after an 'int : 0' in a structure */
                    113: 
                    114: #define EMPTY_FIELD_BOUNDARY 32
                    115: 
                    116: #ifdef HCX_UX
                    117: /* structures must be made of full words */
                    118: 
                    119: #define STRUCTURE_SIZE_BOUNDARY 32
                    120: #else
                    121: /* structures must be made of full bytes */
                    122: 
                    123: #define STRUCTURE_SIZE_BOUNDARY 8
                    124: #endif
                    125: 
                    126: /* tahoe is picky about data alignment */
                    127: 
                    128: #define STRICT_ALIGNMENT 1
                    129: 
                    130: /* keep things standard with pcc */
                    131: 
                    132: #define PCC_BITFIELD_TYPE_MATTERS 1
                    133: 
                    134: /* this section is borrowed from the vax version since the */
                    135: /* formats are the same in both of the architectures      */
                    136: 
1.1.1.4 ! root      137: #define CHECK_FLOAT_VALUE(MODE, D, OVERFLOW) \
1.1.1.3   root      138:   if (OVERFLOW)                                                                \
                    139:     (D) = 1.7014117331926443e+38;                                      \
                    140:   else if ((MODE) == SFmode)                                           \
                    141:     {                                                                  \
                    142:       if ((D) > 1.7014117331926443e+38)                                        \
                    143:        (OVERFLOW) = 1, (D) = 1.7014117331926443e+38;                   \
                    144:       else if ((D) < -1.7014117331926443e+38)                          \
                    145:        (OVERFLOW) = 1, (D) = -1.7014117331926443e+38;                  \
                    146:       else if (((D) > 0) && ((D) < 2.9387358770557188e-39))            \
                    147:        (OVERFLOW) = 1, (D) = 0.0;                                      \
                    148:       else if (((D) < 0) && ((D) > -2.9387358770557188e-39))           \
                    149:        (OVERFLOW) = 1, (D) = 0.0;                                      \
1.1       root      150:     }
                    151: 
                    152: 
                    153: /*
                    154:  * Register Usage
                    155:  */
                    156: 
                    157: /* define 15 general regs plus one for the floating point reg (FPP) */
                    158: 
                    159: #define FIRST_PSEUDO_REGISTER 17
                    160: 
                    161: /* let the compiler know what the fp, sp and pc are */
                    162: 
                    163: #define FIXED_REGISTERS {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0}
                    164: 
                    165: /* lots of regs aren't guaranteed to return from a call. The FPP reg */
                    166: /* must be included in these since it can't be saved by the reg mask */
                    167: 
                    168: #define CALL_USED_REGISTERS {1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1}
                    169: 
                    170: /* A single fp reg can handle any type of float.
                    171:    CPU regs hold just 32 bits.  */
                    172: 
                    173: #define HARD_REGNO_NREGS(REGNO, MODE) \
                    174:  (REGNO != 16 ? ((GET_MODE_SIZE(MODE)+UNITS_PER_WORD-1) / UNITS_PER_WORD)  \
                    175:   : GET_MODE_NUNITS ((MODE)))
                    176: 
                    177: /* any mode greater than 4 bytes (doubles) can only go in an even regs */
                    178: /* and the FPP can only hold SFmode and DFmode                                */
                    179: 
                    180: #define HARD_REGNO_MODE_OK(REGNO, MODE) \
                    181:  (REGNO != 16                                                  \
                    182:   ? (GET_MODE_UNIT_SIZE (MODE) <= 4 ? 1 : (REGNO % 2 - 1))     \
                    183:   : ((MODE) == SFmode || (MODE) == DFmode                      \
                    184:      || (MODE) == SCmode || (MODE) == DCmode))
                    185: 
                    186: /* if mode1 or mode2, but not both, are doubles then modes cannot be tied */
                    187: 
                    188: #define MODES_TIEABLE_P(MODE1, MODE2) \
                    189:  (((MODE1) == DFmode || (MODE1) == DCmode)     \
                    190:   == ((MODE2) == DFmode || (MODE2) == DCmode))
                    191: 
                    192: /* return nonzero if register variable of mode MODE is not
                    193:    a priori a bad idea.  Used only if defined.  */
                    194: #define MODE_OK_FOR_USERVAR(MODE)      \
                    195:   ((MODE) == SImode)
                    196: 
                    197: /* the program counter is reg 15 */
                    198: 
                    199: #define PC_REGNUM 15
                    200: 
                    201: /* the stack pointer is reg 14 */
                    202: 
                    203: #define STACK_POINTER_REGNUM 14
                    204: 
                    205: /* the frame pointer is reg 13 */
                    206: 
                    207: #define FRAME_POINTER_REGNUM 13
                    208: 
                    209: /* tahoe does require an fp */
                    210: 
                    211: #define FRAME_POINTER_REQUIRED 1
                    212: 
                    213: /* since tahoe doesn't have a argument pointer, make it the fp */
                    214: 
                    215: #define ARG_POINTER_REGNUM 13
                    216: 
                    217: /* this isn't currently used since C doesn't support this feature */
                    218: 
                    219: #define STATIC_CHAIN_REGNUM 0
                    220: 
                    221: /* we'll use reg 1 for structure passing cause the destination */
                    222: /* of the eventual movblk requires it to be there anyway.      */
                    223: 
                    224: #define STRUCT_VALUE_REGNUM 1
                    225: 
                    226: 
                    227: /*
                    228:  * Register Classes
                    229:  */
                    230: 
                    231: /* tahoe has two types of regs. GENERAL_REGS are all the regs up */
                    232: /* to number 15. FPP_REG is the special floating point processor  */
                    233: /* register class (only one reg).                                */
                    234: 
                    235: enum reg_class {NO_REGS,GENERAL_REGS,FPP_REG,ALL_REGS,LIM_REG_CLASSES};
                    236: 
                    237: /* defines the number of reg classes.                              */
                    238: 
                    239: #define N_REG_CLASSES (int) LIM_REG_CLASSES
                    240: 
                    241: /* this defines what the classes are officially named for debugging */
                    242: 
                    243: #define REG_CLASS_NAMES \
                    244:  {"NO_REGS","GENERAL_REGS","FPP_REG","ALL_REGS"}
                    245: 
                    246: /* set general regs to be the first 16 regs and the fpp reg to be 17th */
                    247: 
                    248: #define REG_CLASS_CONTENTS {0,0xffff,0x10000,0x1ffff}
                    249: 
                    250: /* register class for the fpp reg is FPP_REG, all others are GENERAL_REGS */
                    251: 
                    252: #define REGNO_REG_CLASS(REGNO) (REGNO == 16 ? FPP_REG : GENERAL_REGS)
                    253: 
                    254: /* only general registers can be used as a base reg */
                    255: 
                    256: #define BASE_REG_CLASS GENERAL_REGS
                    257: 
                    258: /* only general registers can be used to index */
                    259: 
                    260: #define INDEX_REG_CLASS GENERAL_REGS
                    261: 
                    262: /* 'a' as a constraint in the md file means the FFP_REG class */
                    263: 
                    264: #define REG_CLASS_FROM_LETTER(C) (C == 'a' ? FPP_REG : NO_REGS)
                    265: 
                    266: /* any general reg but the fpp can be a base reg */
                    267: 
                    268: #define REGNO_OK_FOR_BASE_P(regno) \
                    269: ((regno) < FIRST_PSEUDO_REGISTER - 1 || reg_renumber[regno] >= 0)
                    270: 
                    271: /* any general reg except the pc and fpp can be an index reg */
                    272: 
                    273: #define REGNO_OK_FOR_INDEX_P(regno)  \
                    274: ((regno) < FIRST_PSEUDO_REGISTER - 2 || reg_renumber[regno] >= 0)
                    275: 
                    276: /* if your loading a floating point constant, it can't be done */
                    277: /* through a register. Force it to be a memory constant.       */
                    278: 
                    279: #define PREFERRED_RELOAD_CLASS(X,CLASS) \
                    280:        ((GET_CODE (X) == CONST_DOUBLE) ? NO_REGS : CLASS)
                    281: 
                    282: /* for the fpp reg, all modes fit; for any others, you need two for doubles */
                    283: 
                    284: #define CLASS_MAX_NREGS(CLASS, MODE)   \
                    285:  (CLASS != FPP_REG ? ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD) : 1)
                    286: 
                    287: /* we don't define any special constant sizes so all should fail */
                    288: 
                    289: #define CONST_OK_FOR_LETTER_P(VALUE, C)  0
                    290: 
                    291: /* we don't define any special double sizes so all should fail */
                    292: 
                    293: #define CONST_DOUBLE_OK_FOR_LETTER_P(VALUE, C) 0
                    294: 
                    295: 
                    296: /*
                    297:  * Describing Stack Layout
                    298:  */
                    299: 
                    300: /* tahoe stack grows from high to low memory */
                    301: 
                    302: #define STACK_GROWS_DOWNWARD
                    303: 
                    304: /* Define this if longjmp restores from saved registers
                    305:    rather than from what setjmp saved.  */
                    306: #define LONGJMP_RESTORE_FROM_STACK
                    307: 
                    308: /* tahoe call frames grow from high to low memory on the stack */
                    309: 
                    310: #define FRAME_GROWS_DOWNWARD
                    311: 
                    312: /* the tahoe fp points to the *top* of the frame instead of the   */
                    313: /* bottom, so we have to make this offset a constant large enough */
                    314: /* to jump over the biggest frame possible.                      */
                    315: 
                    316: #define STARTING_FRAME_OFFSET -52
                    317: 
                    318: /* tahoe always pushes 4 bytes unless it's a double in which case */
                    319: /* it pushes a full 8 bytes.                                     */
                    320: 
                    321: #define PUSH_ROUNDING(BYTES) (BYTES <= 4 ? 4 : 8)
                    322: 
                    323: /* the first parameter in a function is at the fp + 4 */
                    324: 
                    325: #define FIRST_PARM_OFFSET(FNDECL) 4
                    326: 
                    327: /* the tahoe return function takes care of everything on the stack */
                    328: 
1.1.1.4 ! root      329: #define RETURN_POPS_ARGS(FUNDECL,FUNTYPE,SIZE) (SIZE)
1.1       root      330: 
                    331: /* function values for all types are returned in register 0 */
                    332: 
                    333: #define FUNCTION_VALUE(VALTYPE, FUNC)  \
                    334:   gen_rtx (REG, TYPE_MODE (VALTYPE), 0)
                    335: 
                    336: /* library routines also return things in reg 0 */
                    337: 
                    338: #define LIBCALL_VALUE(MODE)  gen_rtx (REG, MODE, 0)
                    339: 
                    340: /* Tahoe doesn't return structures in a reentrant way */
                    341: 
                    342: #define PCC_STATIC_STRUCT_RETURN
                    343: 
                    344: /* we only return values from a function in reg 0 */
                    345: 
                    346: #define FUNCTION_VALUE_REGNO_P(N) ((N) == 0)
                    347: 
                    348: /* we never pass args through a register */
                    349: 
                    350: #define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) 0
                    351: 
                    352: /* int is fine to hold the argument summary in FUNCTION_ARG */
                    353: 
                    354: #define CUMULATIVE_ARGS int
                    355: 
                    356: /* we just set CUM to 0 before the FUNCTION_ARG call. No matter what */
                    357: /* we make it, FUNCTION_ARG will return 0 anyway                    */
                    358: 
                    359: #define INIT_CUMULATIVE_ARGS(CUM,FNTYPE,LIBNAME)       \
                    360:  ((CUM) = 0)
                    361: 
                    362: /* all modes push their size rounded to the nearest word boundary */
                    363: /* except block which is the size of the block rounded up        */
                    364: 
                    365: #define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED)   \
                    366:  ((CUM) += ((MODE) != BLKmode                  \
                    367:            ? (GET_MODE_SIZE (MODE) + 3) & ~3   \
                    368:            : (int_size_in_bytes (TYPE) + 3) & ~3))
                    369: 
                    370: /* this is always false since we never pass params in regs */
                    371: 
                    372: #define FUNCTION_ARG_REGNO_P(N) 0
                    373: 
                    374: /* this code calculates the register entry mask and sets up    */
                    375: /* the stack pointer for the function. The stack is set down   */
                    376: /* far enough from the fp to jump over any push regs and local */
                    377: /* vars. This is a problem since the tahoe has the fp pointing */
                    378: /* to the top of the frame and the compiler must know the off- */
                    379: /* set off the fp to the local vars.                          */
                    380: 
                    381: #define FUNCTION_PROLOGUE(FILE, SIZE)     \
                    382: { register int regno;                                          \
                    383:   register int mask = 0;                                       \
                    384:   extern char call_used_regs[];                                        \
                    385:   for (regno = 0; regno < FIRST_PSEUDO_REGISTER-1; regno++)    \
                    386:     if (regs_ever_live[regno] && !call_used_regs[regno])       \
                    387:        mask |= 1 << regno;                                     \
                    388:   fprintf (FILE, "\t.word 0x%x\n", mask);                      \
                    389:   if (SIZE != 0) fprintf (FILE, "\tsubl3 $%d,fp,sp\n", (SIZE) - STARTING_FRAME_OFFSET); }
                    390: 
                    391: /* Zero out global variable in case it was used in this function.  */
                    392: #define FUNCTION_EPILOGUE(FILE, SIZE)  \
                    393: { extern rtx tahoe_reg_conversion_loc;                         \
                    394:   tahoe_reg_conversion_loc = 0;                                        \
                    395: }
                    396: 
                    397: #ifdef HCX_UX
                    398: 
                    399: /* to call the profiler, the address of the counter var is placed */
                    400: /* on the stack and then passed into mcount this way                     */
                    401: 
                    402: #define FUNCTION_PROFILER(FILE, LABELNO)  \
                    403:    fprintf (FILE, "\tpushal LP%d\n\tcallf $8,mcount\n", (LABELNO));
                    404: 
                    405: #else
                    406: 
                    407: /* to call the profiler, push the variable value onto the stack */
                    408: /* and call mcount like a regular function.                    */
                    409: 
                    410: #define FUNCTION_PROFILER(FILE, LABELNO)  \
                    411:    fprintf (FILE, "\tpushl $LP%d\n\tcallf $8,mcount\n", (LABELNO));
                    412: 
                    413: #endif
                    414: 
                    415: /* all stack handling at the end of a function is handled by the */
                    416: /* return command.                                              */
                    417: 
                    418: #define EXIT_IGNORE_STACK 1
                    419: 
                    420: /*
                    421:  * Library Subroutine Names
                    422:  */
                    423: 
                    424: /* udiv is a valid C library routine in libc.a, so we call that */
                    425: 
                    426: #define UDIVSI3_LIBCALL "*udiv"
                    427: 
                    428: /* urem is a valid C library routine in libc.a, so we call that */
                    429: /* but not so on hcx/ux */
                    430: 
                    431: #ifdef HCX_UX
                    432: #undef UMODSI3_LIBCALL
                    433: #else
                    434: #define UMODSI3_LIBCALL "*urem"
                    435: #endif
                    436: 
                    437: 
                    438: /*
                    439:  * Addressing Modes
                    440:  */
                    441: 
                    442: /* constant addresses can be treated exactly the same as normal constants */
                    443: 
                    444: #define CONSTANT_ADDRESS_P(X)   \
                    445:   (GET_CODE (X) == LABEL_REF || GET_CODE (X) == SYMBOL_REF             \
                    446:    || GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST               \
                    447:    || GET_CODE (X) == HIGH)
                    448: 
                    449: /* we can have as many as two regs in any given address */
                    450: 
                    451: #define MAX_REGS_PER_ADDRESS 2
                    452: 
                    453: /* The following is all the code for GO_IF_LEGITIMATE_ADDRESS */
                    454: /* most of this taken directly from the vax tm file since the */
                    455: /* tahoe and vax addressing modes are nearly identical.              */
                    456: 
                    457: /* Is x an indirectable address? */
                    458: 
                    459: #define INDIRECTABLE_ADDRESS_P(X)  \
                    460:   (CONSTANT_ADDRESS_P (X)                                              \
                    461:    || (GET_CODE (X) == REG && REG_OK_FOR_BASE_P (X))                   \
                    462:    || (GET_CODE (X) == PLUS                                            \
                    463:        && GET_CODE (XEXP (X, 0)) == REG                                        \
                    464:        && REG_OK_FOR_BASE_P (XEXP (X, 0))                              \
                    465:        && CONSTANT_ADDRESS_P (XEXP (X, 1))))
                    466: 
                    467: /* If x is a non-indexed-address, go to ADDR. */
                    468: 
                    469: #define GO_IF_NONINDEXED_ADDRESS(X, ADDR)  \
                    470: { register rtx xfoob = (X);                                            \
                    471:   if (GET_CODE (xfoob) == REG) goto ADDR;                              \
                    472:   if (INDIRECTABLE_ADDRESS_P (xfoob)) goto ADDR;                       \
                    473:   xfoob = XEXP (X, 0);                                                 \
                    474:   if (GET_CODE (X) == MEM && INDIRECTABLE_ADDRESS_P (xfoob))           \
                    475:     goto ADDR;                                                         \
                    476:   if ((GET_CODE (X) == PRE_DEC || GET_CODE (X) == POST_INC)            \
                    477:       && GET_CODE (xfoob) == REG && REGNO (xfoob) == 14)               \
                    478:     goto ADDR; }
                    479: 
                    480: /* Is PROD an index term in mode MODE. */
                    481: 
                    482: #define INDEX_TERM_P(PROD, MODE)   \
                    483: (GET_MODE_SIZE (MODE) == 1                                             \
                    484:  ? (GET_CODE (PROD) == REG && REG_OK_FOR_BASE_P (PROD))                        \
                    485:  : (GET_CODE (PROD) == MULT                                            \
                    486:     &&                                                                 \
                    487:     (xfoo0 = XEXP (PROD, 0), xfoo1 = XEXP (PROD, 1),                   \
                    488:      ((GET_CODE (xfoo0) == CONST_INT                                   \
                    489:        && INTVAL (xfoo0) == GET_MODE_SIZE (MODE)                       \
                    490:        && GET_CODE (xfoo1) == REG                                      \
                    491:        && REG_OK_FOR_INDEX_P (xfoo1))                                  \
                    492:       ||                                                               \
                    493:       (GET_CODE (xfoo1) == CONST_INT                                   \
                    494:        && INTVAL (xfoo1) == GET_MODE_SIZE (MODE)                       \
                    495:        && GET_CODE (xfoo0) == REG                                      \
                    496:        && REG_OK_FOR_INDEX_P (xfoo0))))))
                    497: 
                    498: /* Is the addition to the index a reg? */
                    499: 
                    500: #define GO_IF_REG_PLUS_INDEX(X, MODE, ADDR)    \
                    501: { register rtx xfooa;                                                  \
                    502:   if (GET_CODE (X) == PLUS)                                            \
                    503:     { if (GET_CODE (XEXP (X, 0)) == REG                                        \
                    504:          && REG_OK_FOR_BASE_P (XEXP (X, 0))                            \
                    505:          && (xfooa = XEXP (X, 1),                                      \
                    506:              INDEX_TERM_P (xfooa, MODE)))                              \
                    507:        goto ADDR;                                                      \
                    508:       if (GET_CODE (XEXP (X, 1)) == REG                                        \
                    509:          && REG_OK_FOR_BASE_P (XEXP (X, 1))                            \
                    510:          && (xfooa = XEXP (X, 0),                                      \
                    511:              INDEX_TERM_P (xfooa, MODE)))                              \
                    512:        goto ADDR; } }
                    513: 
                    514: /* Is the rtx X a valid memory address for operand of mode MODE? */
                    515: /* If it is, go to ADDR */
                    516: 
                    517: #define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR)  \
                    518: { register rtx xfoo, xfoo0, xfoo1;                                     \
                    519:   GO_IF_NONINDEXED_ADDRESS (X, ADDR);                                  \
                    520:   if (GET_CODE (X) == PLUS)                                            \
                    521:     { xfoo = XEXP (X, 0);                                              \
                    522:       if (INDEX_TERM_P (xfoo, MODE))                                   \
                    523:        { GO_IF_NONINDEXED_ADDRESS (XEXP (X, 1), ADDR); }               \
                    524:       xfoo = XEXP (X, 1);                                              \
                    525:       if (INDEX_TERM_P (xfoo, MODE))                                   \
                    526:        { GO_IF_NONINDEXED_ADDRESS (XEXP (X, 0), ADDR); }               \
                    527:       if (CONSTANT_ADDRESS_P (XEXP (X, 0)))                            \
                    528:        { if (GET_CODE (XEXP (X, 1)) == REG                             \
                    529:              && REG_OK_FOR_BASE_P (XEXP (X, 1)))                       \
                    530:            goto ADDR;                                                  \
                    531:          GO_IF_REG_PLUS_INDEX (XEXP (X, 1), MODE, ADDR); }             \
                    532:       if (CONSTANT_ADDRESS_P (XEXP (X, 1)))                            \
                    533:        { if (GET_CODE (XEXP (X, 0)) == REG                             \
                    534:              && REG_OK_FOR_BASE_P (XEXP (X, 0)))                       \
                    535:            goto ADDR;                                                  \
                    536:          GO_IF_REG_PLUS_INDEX (XEXP (X, 0), MODE, ADDR); } } }
                    537: 
                    538: /* Register 16 can never be used for index or base */
                    539: 
                    540: #ifndef REG_OK_STRICT
                    541: #define REG_OK_FOR_INDEX_P(X) (REGNO(X) != 16)
                    542: #define REG_OK_FOR_BASE_P(X) (REGNO(X) != 16)
                    543: #else
                    544: #define REG_OK_FOR_INDEX_P(X) REGNO_OK_FOR_INDEX_P (REGNO (X))
                    545: #define REG_OK_FOR_BASE_P(X) REGNO_OK_FOR_BASE_P (REGNO (X))
                    546: #endif
                    547: 
                    548: /* Addressing is too simple to allow optimizing here */
                    549: 
                    550: #define LEGITIMIZE_ADDRESS(X,OLDX,MODE,WIN)  {}
                    551: 
                    552: /* Post_inc and pre_dec always adds 4 */
                    553: 
                    554: #define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR,LABEL)       \
                    555:  { if (GET_CODE(ADDR) == POST_INC || GET_CODE(ADDR) == PRE_DEC)                \
                    556:        goto LABEL;                                                     \
                    557:    if (GET_CODE (ADDR) == PLUS)                                                \
                    558:      { if (CONSTANT_ADDRESS_P (XEXP (ADDR, 0))                         \
                    559:           && GET_CODE (XEXP (ADDR, 1)) == REG);                        \
                    560:        else if (CONSTANT_ADDRESS_P (XEXP (ADDR, 1))                    \
                    561:                && GET_CODE (XEXP (ADDR, 0)) == REG);                   \
                    562:        else goto LABEL; }}
                    563: 
                    564: /* Double's are not legitimate as immediate operands */
                    565: 
                    566: #define LEGITIMATE_CONSTANT_P(X) \
                    567:   (GET_CODE (X) != CONST_DOUBLE)
                    568: 
                    569: 
                    570: /*
                    571:  * Miscellaneous Parameters
                    572:  */
                    573: 
                    574: /* the elements in the case jump table are all words */
                    575: 
                    576: #define CASE_VECTOR_MODE HImode
                    577: 
                    578: /* each of the table elements in a case are relative to the jump address */
                    579: 
                    580: #define CASE_VECTOR_PC_RELATIVE
                    581: 
                    582: /* tahoe case instructions just fall through to the next instruction */
                    583: /* if not satisfied. It doesn't support a default action            */
                    584: 
                    585: #define CASE_DROPS_THROUGH
                    586: 
                    587: /* the standard answer is given here and work ok */
                    588: 
                    589: #define IMPLICIT_FIX_EXPR FIX_ROUND_EXPR
                    590: 
                    591: /* in a general div case, it's easiest to use TRUNC_DIV_EXPR */
                    592: 
                    593: #define EASY_DIV_EXPR TRUNC_DIV_EXPR
                    594: 
                    595: /* the standard seems to be leaving char's as signed so we left it */
                    596: /* this way even though we think they should be unsigned!         */
                    597: 
                    598: #define DEFAULT_SIGNED_CHAR 1
                    599: 
                    600: /* the most we can move without cutting down speed is 4 bytes */
                    601: 
                    602: #define MOVE_MAX 4
                    603: 
                    604: /* our int is 32 bits */
                    605: 
                    606: #define INT_TYPE_SIZE 32
                    607: 
                    608: /* byte access isn't really slower than anything else */
                    609: 
                    610: #define SLOW_BYTE_ACCESS 0
                    611: 
                    612: /* zero extension is more than one instruction so try to avoid it */
                    613: 
                    614: #define SLOW_ZERO_EXTEND
                    615: 
                    616: /* any bits higher than the low 4 are ignored in the shift count */
                    617: /* so don't bother zero extending or sign extending them         */
                    618: 
1.1.1.2   root      619: #define SHIFT_COUNT_TRUNCATED 1
1.1       root      620: 
                    621: /* we don't need to officially convert from one fixed type to another */
                    622: /* in order to use it as that type. We can just assume it's the same  */
                    623: 
                    624: #define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1
                    625: 
                    626: /* pass chars as ints */
                    627: 
                    628: #define PROMOTE_PROTOTYPES
                    629: 
                    630: /* pointers can be represented by an si mode expression */
                    631: 
                    632: #define Pmode SImode
                    633: 
                    634: /* function addresses are made by specifying a byte address */
                    635: 
                    636: #define FUNCTION_MODE QImode
                    637: 
                    638: /* Define this if addresses of constant functions
                    639:    shouldn't be put through pseudo regs where they can be cse'd.
                    640:    On the tahoe a call with a constant address is much faster than one with a
                    641:    register. */
                    642: 
                    643: #define NO_FUNCTION_CSE
                    644: 
                    645: /* specify the costs of various sorts of constants,
                    646:    and also indicate that multiplication is cheap on this machine.  */
                    647: 
                    648: #define CONST_COSTS(RTX,CODE,OUTER_CODE) \
                    649:   case CONST_INT:                                              \
                    650:     /* Constant zero is super cheap due to clr instruction.  */        \
                    651:     if (RTX == const0_rtx) return 0;                           \
                    652:     if ((unsigned) INTVAL (RTX) < 077) return 1;               \
                    653:     if (INTVAL (RTX) <= 127 && INTVAL (RTX) >= -128) return 2; \
                    654:   case CONST:                                                  \
                    655:   case LABEL_REF:                                              \
                    656:   case SYMBOL_REF:                                             \
                    657:     return 3;                                                  \
                    658:   case CONST_DOUBLE:                                           \
                    659:     return 5;                                                  \
                    660:   case MULT:                                                   \
                    661:     total = 2;
                    662: 
                    663: 
                    664: /*
                    665:  * Condition Code Information
                    666:  */
                    667: 
                    668: /* Nonzero if the results of the previous comparison are
                    669:    in the floating point condition code register.  */
                    670: 
                    671: #define CC_UNCHANGED 04000
                    672: 
                    673: 
                    674: #define NOTICE_UPDATE_CC(EXP, INSN) \
                    675: { if (cc_status.flags & CC_UNCHANGED)                          \
                    676:     /* Happens for cvtld and a few other insns.  */            \
                    677:     cc_status.flags &= ~CC_UNCHANGED;                          \
                    678:   else if (GET_CODE (EXP) == SET)                              \
                    679:     { if (GET_CODE (SET_SRC (EXP)) == CALL)                    \
                    680:        CC_STATUS_INIT;                                         \
                    681:       else if (GET_CODE (SET_DEST (EXP)) != PC)                        \
                    682:        { cc_status.flags = 0;                                  \
                    683:          cc_status.value1 = SET_DEST (EXP);                    \
                    684:          cc_status.value2 = SET_SRC (EXP); } }                 \
                    685:   else if (GET_CODE (EXP) == PARALLEL                          \
                    686:           && GET_CODE (XVECEXP (EXP, 0, 0)) == SET             \
                    687:           && GET_CODE (SET_DEST (XVECEXP (EXP, 0, 0))) != PC)  \
                    688:     { cc_status.flags = 0;                                     \
                    689:       cc_status.value1 = SET_DEST (XVECEXP (EXP, 0, 0));       \
                    690:       cc_status.value2 = SET_SRC (XVECEXP (EXP, 0, 0)); }      \
                    691:   /* PARALLELs whose first element sets the PC are aob, sob insns.     \
                    692:      They do change the cc's.  So drop through and forget the cc's.  */ \
                    693:   else CC_STATUS_INIT;                                         \
                    694:   if (cc_status.value1 && GET_CODE (cc_status.value1) == REG   \
                    695:       && cc_status.value2                                      \
                    696:       && reg_overlap_mentioned_p (cc_status.value1, cc_status.value2)) \
                    697:     cc_status.value2 = 0;                                      \
                    698:   if (cc_status.value1 && GET_CODE (cc_status.value1) == MEM   \
                    699:       && cc_status.value2                                      \
                    700:       && GET_CODE (cc_status.value2) == MEM)                   \
                    701:     cc_status.value2 = 0; }
                    702: /* Actual condition, one line up, should be that value2's address
                    703:    depends on value1, but that is too much of a pain.  */
                    704: 
                    705: 
                    706: /*
                    707:  * Output of Assembler Code
                    708:  */
                    709: 
                    710: /* print which tahoe version compiled this code and print a directive */
                    711: /* to the gnu assembler to say that the following is normal assembly  */
                    712: 
                    713: #ifdef HCX_UX
                    714: #define ASM_FILE_START(FILE)           \
                    715: { fprintf (FILE, "#gcc hcx 1.0\n\n");  \
                    716:   output_file_directive ((FILE), main_input_filename);} while (0)
                    717: #else
                    718: #define ASM_FILE_START(FILE) fprintf (FILE, "#gcc tahoe 1.0\n#NO_APP\n");
                    719: #endif
                    720: 
                    721: /* the instruction that turns on the APP for the gnu assembler */
                    722: 
                    723: #define ASM_APP_ON "#APP\n"
                    724: 
                    725: /* the instruction that turns off the APP for the gnu assembler */
                    726: 
                    727: #define ASM_APP_OFF "#NO_APP\n"
                    728: 
                    729: /* what to output before read-only data.  */
                    730: 
                    731: #define TEXT_SECTION_ASM_OP ".text"
                    732: 
                    733: /* what to output before writable data.  */
                    734: 
                    735: #define DATA_SECTION_ASM_OP ".data"
                    736: 
                    737: /* this is what we call each of the regs. notice that the FPP reg is   */
                    738: /* called "ac". This should never get used due to the way we've set    */
                    739: /* up FPP instructions in the md file. But we call it "ac" here to     */
                    740: /* fill the list.                                                     */
                    741: 
                    742: #define REGISTER_NAMES \
                    743: {"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", \
                    744:  "r9", "r10", "r11", "r12", "fp", "sp", "pc", "ac"}
                    745: 
                    746: #ifdef HCX_UX
                    747: /* allow generation of sdb info in the assembly */
                    748: #define SDB_DEBUGGING_INFO
                    749: #else
                    750: /* allow generation of dbx info in the assembly */
                    751: 
                    752: #define DBX_DEBUGGING_INFO
                    753: 
                    754: /* our dbx doesn't support this */
                    755: 
                    756: #define DBX_NO_XREFS
                    757: 
                    758: /* we don't want symbols broken up */
                    759: 
                    760: #define DBX_CONTIN_LENGTH 0
                    761: 
                    762: /* this'll really never be used, but we'll leave it at this */
                    763: 
                    764: #define DBX_CONTIN_CHAR '?'
                    765: 
                    766: #endif /* HCX_UX */
                    767: 
                    768: /* registers are called the same thing in dbx anything else */
                    769: /* This is necessary even if we generate SDB output */
                    770: 
                    771: #define DBX_REGISTER_NUMBER(REGNO) (REGNO)
                    772: 
                    773: /* labels are the label followed by a colon and a newline */
                    774: /* must be a statement, so surround it in a null loop     */
                    775: 
                    776: #define ASM_OUTPUT_LABEL(FILE,NAME)    \
                    777:   do { assemble_name (FILE, NAME); fputs (":\n", FILE); } while (0)
                    778: 
                    779: /* use the .globl directive to make labels global for the linker */
                    780: 
                    781: #define ASM_GLOBALIZE_LABEL(FILE,NAME) \
                    782:   do { fputs (".globl ", FILE); assemble_name (FILE, NAME); fputs ("\n", FILE);} while (0)
                    783: 
                    784: /* output a label by appending an underscore to it */
                    785: 
                    786: #define ASM_OUTPUT_LABELREF(FILE,NAME) \
                    787:   fprintf (FILE, "_%s", NAME)
                    788: 
                    789: /* use the standard format for printing internal labels */
                    790: 
                    791: #define ASM_OUTPUT_INTERNAL_LABEL(FILE,PREFIX,NUM)     \
                    792:   fprintf (FILE, "%s%d:\n", PREFIX, NUM)
                    793: 
                    794: /* a * is used for label indirection in unix assembly */
                    795: 
                    796: #define ASM_GENERATE_INTERNAL_LABEL(LABEL,PREFIX,NUM)  \
                    797:   sprintf (LABEL, "*%s%d", PREFIX, NUM)
                    798: 
                    799: /* outputting a double is easy cause we only have one kind */
                    800: 
                    801: #ifdef HCX_UX
                    802: #define ASM_OUTPUT_DOUBLE(FILE,VALUE)  \
                    803:   fprintf (FILE, "\t.double 0d%.20e\n", (VALUE))
                    804: #else
                    805: #define ASM_OUTPUT_DOUBLE(FILE,VALUE)  \
                    806: {                                                      \
                    807:   union { int i[2]; double d;} temp;                   \
                    808:   temp.d = (VALUE);                                    \
                    809:   if (TARGET_HEX_FLOAT)                                        \
                    810:     fprintf ((FILE), "\t.long 0x%x,0x%x  # %.20e\n",   \
                    811:             temp.i[0], temp.i[1], temp.d);             \
                    812:   else                                                 \
                    813:     fprintf (FILE, "\t.dfloat 0d%.20e\n", temp.d);     \
                    814: }
                    815: #endif
                    816: 
                    817: /* This is how to output an assembler line defining a `float' constant.  */
                    818: 
                    819: #ifdef HCX_UX
                    820: #define ASM_OUTPUT_FLOAT(FILE,VALUE)  \
                    821:   fprintf (FILE, "\t.float 0f%.20e\n", (VALUE))
                    822: #else
                    823: #define ASM_OUTPUT_FLOAT(FILE,VALUE)  \
                    824: {                                                      \
                    825:   union { int i; float f;} temp;                       \
                    826:   temp.f = (float) (VALUE);                            \
                    827:   if (TARGET_HEX_FLOAT)                                        \
                    828:     fprintf ((FILE), "\t.long 0x%x  # %.20e\n",                \
                    829:             temp.i, temp.f);                           \
                    830:   else                                                 \
                    831:     fprintf (FILE, "\t.float 0f%.20e\n", temp.f);      \
                    832: }
                    833: #endif
                    834: 
                    835: /* This is how to output an assembler line defining an `int' constant.  */
                    836: 
                    837: #define ASM_OUTPUT_INT(FILE,VALUE)  \
                    838: ( fprintf (FILE, "\t.long "),                  \
                    839:   output_addr_const (FILE, (VALUE)),           \
                    840:   fprintf (FILE, "\n"))
                    841: 
                    842: /* Likewise for `char' and `short' constants.  */
                    843: 
                    844: #define ASM_OUTPUT_SHORT(FILE,VALUE)  \
                    845: ( fprintf (FILE, "\t.word "),                  \
                    846:   output_addr_const (FILE, (VALUE)),           \
                    847:   fprintf (FILE, "\n"))
                    848: 
                    849: #define ASM_OUTPUT_CHAR(FILE,VALUE)  \
                    850: ( fprintf (FILE, "\t.byte "),                  \
                    851:   output_addr_const (FILE, (VALUE)),           \
                    852:   fprintf (FILE, "\n"))
                    853: 
                    854: #ifdef HCX_UX
                    855: /* This is how to output an assembler line for an ASCII string.  */
                    856: 
                    857: #define ASM_OUTPUT_ASCII(FILE, p, size)                \
1.1.1.3   root      858: do {   register int i;                                 \
1.1       root      859:          fprintf ((FILE), "\t.ascii \"");              \
                    860:          for (i = 0; i < (size); i++)                  \
                    861:            {                                           \
                    862:              register int c = (p)[i];                  \
                    863:              if (c == '\'' || c == '\\')               \
                    864:                putc ('\\', (FILE));                    \
                    865:              if (c >= ' ' && c < 0177 && c != '\"')    \
                    866:                putc (c, (FILE));                       \
                    867:              else                                      \
                    868:                {                                       \
                    869:                  fprintf ((FILE), "\\%03o", c);        \
                    870:                }                                       \
                    871:            }                                           \
1.1.1.3   root      872:          fprintf ((FILE), "\"\n"); } while (0)
1.1       root      873: #endif
                    874: 
                    875: /* This is how to output an assembler line for a numeric constant byte.  */
                    876: 
                    877: #define ASM_OUTPUT_BYTE(FILE,VALUE)  \
                    878:   fprintf (FILE, "\t.byte 0x%x\n", (VALUE))
                    879: 
                    880: /* this is the insn to push a register onto the stack */
                    881: 
                    882: #define ASM_OUTPUT_REG_PUSH(FILE,REGNO)        \
                    883:   fprintf (FILE, "\tpushl %s\n", reg_names[REGNO])
                    884: 
                    885: /* this is the insn to pop a register from the stack */
                    886: 
                    887: #define ASM_OUTPUT_REG_POP(FILE,REGNO) \
                    888:   fprintf (FILE, "\tmovl (sp)+,%s\n", reg_names[REGNO])
                    889: 
                    890: /* this is required even thought tahoe doesn't support it */
                    891: /* cause the C code expects it to be defined             */
                    892: 
                    893: #define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE)  \
                    894:   fprintf (FILE, "\t.long L%d\n", VALUE)
                    895: 
                    896: /* This is how to output an element of a case-vector that is relative.  */
                    897: 
                    898: #define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, VALUE, REL)  \
                    899:   fprintf (FILE, "\t.word L%d-L%d\n", VALUE, REL)
                    900: 
                    901: /* This is how to output an assembler line
                    902:    that says to advance the location counter
                    903:    to a multiple of 2**LOG bytes.  */
                    904: 
                    905: #ifdef HCX_UX
                    906: #define CASE_ALIGNMENT 2
                    907: #define ASM_OUTPUT_ALIGN(FILE,LOG)  \
                    908:     if ((LOG)!=0) fprintf ((FILE), "\t.align %d\n", 1<<(LOG))
                    909: #else
                    910: #define CASE_ALIGNMENT 1
                    911: #define ASM_OUTPUT_ALIGN(FILE,LOG)  \
                    912:   LOG ? fprintf (FILE, "\t.align %d\n", (LOG)) : 0
                    913: #endif
                    914: 
                    915: /* This is how to skip over some space */
                    916: 
                    917: #define ASM_OUTPUT_SKIP(FILE,SIZE)  \
                    918:   fprintf (FILE, "\t.space %u\n", (SIZE))
                    919: 
                    920: /* This defines common variables across files */
                    921: 
                    922: #ifdef HCX_UX
                    923: #define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED)  \
                    924: ( fputs (".comm ", (FILE)),                    \
                    925:   assemble_name ((FILE), (NAME)),              \
                    926:   fprintf ((FILE), ",%u\n", (SIZE)))
                    927: #else
                    928: #define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED)  \
                    929: ( fputs (".comm ", (FILE)),                    \
                    930:   assemble_name ((FILE), (NAME)),              \
                    931:   fprintf ((FILE), ",%u\n", (ROUNDED)))
                    932: #endif
                    933: 
                    934: /* This says how to output an assembler line
                    935:    to define a local common symbol.  */
                    936: 
                    937: #ifdef HCX_UX
                    938: #define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE, ROUNDED)  \
                    939: ( fputs ("\t.bss ", (FILE)),                   \
                    940:   assemble_name ((FILE), (NAME)),              \
                    941:   fprintf ((FILE), ",%u,4\n", (SIZE),(ROUNDED)))
                    942: #else
                    943: #define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE, ROUNDED)  \
                    944: ( fputs (".lcomm ", (FILE)),                   \
                    945:   assemble_name ((FILE), (NAME)),              \
                    946:   fprintf ((FILE), ",%u\n", (ROUNDED)))
                    947: #endif
                    948: 
                    949: /* code to generate a label */
                    950: 
                    951: #define ASM_FORMAT_PRIVATE_NAME(OUTPUT, NAME, LABELNO) \
                    952: ( (OUTPUT) = (char *) alloca (strlen ((NAME)) + 10),   \
                    953:   sprintf ((OUTPUT), "%s.%d", (NAME), (LABELNO)))
                    954: 
                    955: /* Define the parentheses used to group arithmetic operations
                    956:    in assembler code.  */
                    957: 
                    958: #define ASM_OPEN_PAREN "("
                    959: #define ASM_CLOSE_PAREN ")"
                    960: 
                    961: /* Define results of standard character escape sequences.  */
                    962: 
                    963: #define TARGET_BELL 007
                    964: #define TARGET_BS 010
                    965: #define TARGET_TAB 011
                    966: #define TARGET_NEWLINE 012
                    967: #define TARGET_VT 013
                    968: #define TARGET_FF 014
                    969: #define TARGET_CR 015
                    970: 
                    971: /* Print an instruction operand X on file FILE.
                    972:    CODE is the code from the %-spec that requested printing this operand;
                    973:    if `%z3' was used to print operand 3, then CODE is 'z'.
                    974:    On the Vax, the only code used is `#', indicating that either
                    975:    `d' or `g' should be printed, depending on whether we're using dfloat
                    976:    or gfloat.  */
                    977: /* Print an operand.  Some difference from the vax code,
                    978:    since the tahoe can't support immediate floats and doubles.
                    979: 
                    980:    %@ means print the proper alignment operand for aligning after a casesi.
                    981:    This depends on the assembler syntax.
                    982:    This is 1 for our assembler, since .align is logarithmic.
                    983: 
                    984:    %s means the number given is supposed to be a shift value, but on
                    985:    the tahoe it should be converted to a number that can be used as a
                    986:    multiplicative constant (cause multiplication is a whole lot faster
                    987:    than shifting). So make the number 2^n instead. */
                    988: 
                    989: #define PRINT_OPERAND_PUNCT_VALID_P(CODE)                              \
                    990:   ((CODE) == '@')
                    991: 
                    992: #define PRINT_OPERAND(FILE, X, CODE)  \
                    993: { if (CODE == '@')                                                     \
                    994:     putc ('0' + CASE_ALIGNMENT, FILE);                                 \
                    995:   else if (CODE == 's')                                                        \
                    996:     fprintf (FILE, "$%d", 1 << INTVAL(X));                             \
                    997:   else if (GET_CODE (X) == REG)                                                \
                    998:     fprintf (FILE, "%s", reg_names[REGNO (X)]);                                \
                    999:   else if (GET_CODE (X) == MEM)                                                \
                   1000:     output_address (XEXP (X, 0));                                      \
                   1001:   else { putc ('$', FILE); output_addr_const (FILE, X); }}
                   1002: 
                   1003: /* When the operand is an address, call print_operand_address to */
                   1004: /* do the work from output-tahoe.c.                             */
                   1005: 
                   1006: #define PRINT_OPERAND_ADDRESS(FILE, ADDR)  \
                   1007:  print_operand_address (FILE, ADDR)
                   1008: 
                   1009: /* This is for G++ */
                   1010: 
                   1011: #define CRT0_DUMMIES
                   1012: #define DOT_GLOBAL_START
                   1013: #ifdef HCX_UX
                   1014: #define NO_GNU_LD /* because of COFF format */
                   1015: #define LINK_SPEC "-L/usr/staff/lib"
                   1016: #endif

unix.superglobalmegacorp.com

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