Annotation of gcc/config/tm-tahoe.h, revision 1.1.1.2

1.1       root        1: /* Definitions of target machine for GNU compiler.  Tahoe version.
                      2:    Copyright (C) 1989 Free Software Foundation, Inc.
                      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 1, 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
                     18: the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
                     19: 
                     20: /*
                     21:  * File: tm-tahoe.h
                     22:  *
                     23:  * This port made at the University of Buffalo by Devon Bowen,
                     24:  * Dale Wiles and Kevin Zachmann.
                     25:  *
                     26:  * Mail bugs reports or fixes to:      [email protected]
                     27:  */
                     28: 
                     29: 
                     30: /*
                     31:  * Run-time Target Specification
                     32:  */
                     33: 
                     34: /* we want "tahoe" and "unix" auto-defined for all future compilations */
                     35: 
                     36: #define CPP_PREDEFINES "-Dtahoe -Dunix"
                     37: 
                     38: /* have cc1 print that this is the tahoe version */
                     39: 
                     40: #define TARGET_VERSION printf (" (tahoe)");
                     41: 
                     42: /* this is required in all tm files to hold flags */
                     43: 
                     44: extern int target_flags;
                     45: 
                     46: /* Zero if it is safe to output .dfloat and .float pseudos.  */
                     47: #define TARGET_HEX_FLOAT (target_flags & 1)
                     48: 
                     49: #define TARGET_DEFAULT 1
                     50: 
                     51: #define TARGET_SWITCHES                \
                     52:   { {"hex-float", 1},          \
                     53:     {"no-hex-float", -1},      \
                     54:     { "", TARGET_DEFAULT} }
                     55: 
                     56: 
                     57: /*
                     58:  * Storage Layout
                     59:  */
                     60: 
                     61: /* tahoe uses a big endian byte order */
                     62: 
                     63: #define BYTES_BIG_ENDIAN
                     64: 
                     65: /* tahoe uses a big endian word order */
                     66: 
                     67: #define WORDS_BIG_ENDIAN
                     68: 
                     69: /* standard byte size is usable on tahoe */
                     70: 
                     71: #define BITS_PER_UNIT 8
                     72: 
                     73: /* longs on the tahoe are 4 byte groups */
                     74: 
                     75: #define BITS_PER_WORD 32
                     76: 
                     77: /* from the last two params we get 4 bytes per word */
                     78: 
                     79: #define UNITS_PER_WORD 4
                     80: 
                     81: /* addresses are 32 bits (one word) */
                     82: 
                     83: #define POINTER_SIZE 32
                     84: 
                     85: /* pointers should align every 32 bits */
                     86: 
                     87: #define POINTER_BOUNDARY 32
                     88: 
                     89: /* all parameters line up on 32 boundaries */
                     90: 
                     91: #define PARM_BOUNDARY 32
                     92: 
                     93: /* stack should line up on 32 boundaries */
                     94: 
                     95: #define STACK_BOUNDARY 32
                     96: 
                     97: /* line functions up on 32 bits */
                     98: 
                     99: #define FUNCTION_BOUNDARY 32
                    100: 
                    101: /* the biggest alignment the tahoe needs in 32 bits */
                    102: 
                    103: #define BIGGEST_ALIGNMENT 32
                    104: 
                    105: /* we have to align after an 'int : 0' in a structure */
                    106: 
                    107: #define EMPTY_FIELD_BOUNDARY 32
                    108: 
                    109: /* structures must be made of full bytes */
                    110: 
                    111: #define STRUCTURE_SIZE_BOUNDARY 8
                    112: 
                    113: /* tahoe is picky about data alignment */
                    114: 
                    115: #define STRICT_ALIGNMENT
                    116: 
                    117: /* keep things standard with pcc */
                    118: 
1.1.1.2 ! root      119: #define PCC_BITFIELD_TYPE_MATTERS 1
1.1       root      120: 
                    121: /* this section is borrowed from the vax version since the */
                    122: /* formats are the same in both of the architectures      */
                    123: 
                    124: #define CHECK_FLOAT_VALUE(mode, d) \
                    125:   if ((mode) == SFmode) \
                    126:     { \
                    127:       if ((d) > 1.7014117331926443e+38) \
                    128:        { error ("magnitude of constant too large for `float'"); \
                    129:          (d) = 1.7014117331926443e+38; } \
                    130:       else if ((d) < -1.7014117331926443e+38) \
                    131:        { error ("magnitude of constant too large for `float'"); \
                    132:          (d) = -1.7014117331926443e+38; } \
                    133:       else if (((d) > 0) && ((d) < 2.9387358770557188e-39)) \
                    134:        { warning ("`float' constant truncated to zero"); \
                    135:          (d) = 0.0; } \
                    136:       else if (((d) < 0) && ((d) > -2.9387358770557188e-39)) \
                    137:        { warning ("`float' constant truncated to zero"); \
                    138:          (d) = 0.0; } \
                    139:     }
                    140: 
                    141: 
                    142: /*
                    143:  * Register Usage
                    144:  */
                    145: 
                    146: /* define 15 general regs plus one for the floating point reg (FPP) */
                    147: 
                    148: #define FIRST_PSEUDO_REGISTER 17
                    149: 
                    150: /* let the compiler know what the fp, sp and pc are */
                    151: 
                    152: #define FIXED_REGISTERS {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0}
                    153: 
                    154: /* lots of regs aren't guarenteed to return from a call. The FPP reg */
                    155: /* must be included in these since it can't be saved by the reg mask */
                    156: 
                    157: #define CALL_USED_REGISTERS {1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1}
                    158: 
                    159: /* The FPP can handle any type, but the others may require as many as */
                    160: /* two regs depending on the mode needed                             */
                    161: 
                    162: #define HARD_REGNO_NREGS(REGNO, MODE) \
                    163:  (REGNO != 16 ? ((GET_MODE_SIZE(MODE)+UNITS_PER_WORD-1) / UNITS_PER_WORD) : 1)
                    164: 
                    165: /* any mode greater than 4 bytes (doubles) can only go in an even regs */
                    166: /* and the FPP can only hold SFmode and DFmode                                */
                    167: 
                    168: #define HARD_REGNO_MODE_OK(REGNO, MODE) \
                    169:  (REGNO != 16 ? (GET_MODE_SIZE (MODE) <= 4 ? 1 : (REGNO % 2 - 1)) : \
                    170:        (MODE == SFmode || MODE == DFmode))
                    171: 
                    172: /* if mode1 or mode2, but not both, are doubles then modes cannot be tied */
                    173: 
                    174: #define MODES_TIEABLE_P(MODE1, MODE2) \
                    175:  ((MODE1 == DFmode) == (MODE2 == DFmode))
                    176: 
                    177: /* the program counter is reg 15 */
                    178: 
                    179: #define PC_REGNUM 15
                    180: 
                    181: /* the stack pointer is reg 14 */
                    182: 
                    183: #define STACK_POINTER_REGNUM 14
                    184: 
                    185: /* the frame pointer is reg 13 */
                    186: 
                    187: #define FRAME_POINTER_REGNUM 13
                    188: 
                    189: /* tahoe does require an fp */
                    190: 
                    191: #define FRAME_POINTER_REQUIRED 1
                    192: 
                    193: /* since tahoe doesn't have a argument pointer, make it the fp */
                    194: 
                    195: #define ARG_POINTER_REGNUM 13
                    196: 
                    197: /* this isn't currently used since C doesn't support this feature */
                    198: 
                    199: #define STATIC_CHAIN_REGNUM 0
                    200: 
                    201: /* we'll use reg 1 for structure passing cause the destination */
                    202: /* of the eventual movblk requires it to be there anyway.      */
                    203: 
                    204: #define STRUCT_VALUE_REGNUM 1
                    205: 
                    206: 
                    207: /*
                    208:  * Register Classes
                    209:  */
                    210: 
                    211: /* tahoe has two types of regs. GENERALY_REGS are all the regs up */
                    212: /* to number 15. FPP_REG is the special floating point processor  */
                    213: /* register class (only one reg).                                */
                    214: 
                    215: enum reg_class {NO_REGS,GENERAL_REGS,FPP_REG,ALL_REGS,LIM_REG_CLASSES};
                    216: 
                    217: /* defines the number of reg classes.                              */
                    218: 
                    219: #define N_REG_CLASSES (int) LIM_REG_CLASSES
                    220: 
                    221: /* this defines what the classes are officially named for debugging */
                    222: 
                    223: #define REG_CLASS_NAMES \
                    224:  {"NO_REGS","GENERAL_REGS","FPP_REG","ALL_REGS"}
                    225: 
                    226: /* set general regs to be the first 16 regs and the fpp reg to be 17th */
                    227: 
                    228: #define REG_CLASS_CONTENTS {0,0xffff,0x10000,0x1ffff}
                    229: 
                    230: /* register class for the fpp reg is FPP_REG, all others are GENERAL_REGS */
                    231: 
                    232: #define REGNO_REG_CLASS(REGNO) (REGNO == 16 ? FPP_REG : GENERAL_REGS)
                    233: 
                    234: /* only gereral registers can be used as a base reg */
                    235: 
                    236: #define BASE_REG_CLASS GENERAL_REGS
                    237: 
                    238: /* only gereral registers can be used to index */
                    239: 
                    240: #define INDEX_REG_CLASS GENERAL_REGS
                    241: 
                    242: /* 'a' as a contraint in the md file means the FFP_REG class */
                    243: 
                    244: #define REG_CLASS_FROM_LETTER(C) (C == 'a' ? FPP_REG : NO_REGS)
                    245: 
                    246: /* any general reg but the fpp can be a base reg */
                    247: 
                    248: #define REGNO_OK_FOR_BASE_P(regno) \
                    249: ((regno) < FIRST_PSEUDO_REGISTER - 1 || reg_renumber[regno] >= 0)
                    250: 
                    251: /* any general reg except the pc and fpp can be an index reg */
                    252: 
                    253: #define REGNO_OK_FOR_INDEX_P(regno)  \
                    254: ((regno) < FIRST_PSEUDO_REGISTER - 2 || reg_renumber[regno] >= 0)
                    255: 
                    256: /* if your loading a floating point constant, it can't be done */
                    257: /* through a register. Force it to be a memory constant.       */
                    258: 
                    259: #define PREFERRED_RELOAD_CLASS(X,CLASS) \
                    260:        ((GET_CODE (X) == CONST_DOUBLE) ? NO_REGS : CLASS)
                    261: 
                    262: /* for the fpp reg, all modes fit; for any others, you need two for doubles */
                    263: 
                    264: #define CLASS_MAX_NREGS(CLASS, MODE)   \
                    265:  (CLASS != FPP_REG ? ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD) : 1)
                    266: 
                    267: /* we don't define any special constant sizes so all should fail */
                    268: 
                    269: #define CONST_OK_FOR_LETTER_P(VALUE, C)  0
                    270: 
                    271: /* we don't define any special double sizes so all should fail */
                    272: 
                    273: #define CONST_DOUBLE_OK_FOR_LETTER_P(VALUE, C) 0
                    274: 
                    275: 
                    276: /*
                    277:  * Describing Stack Layout
                    278:  */
                    279: 
                    280: /* tahoe stack grows from high to low memory */
                    281: 
                    282: #define STACK_GROWS_DOWNWARD
                    283: 
                    284: /* Define this if longjmp restores from saved registers
                    285:    rather than from what setjmp saved.  */
                    286: #define LONGJMP_RESTORE_FROM_STACK
                    287: 
                    288: /* tahoe call frames grow from high to low memory on the stack */
                    289: 
                    290: #define FRAME_GROWS_DOWNWARD
                    291: 
                    292: /* the tahoe fp points to the *top* of the frame instead of the   */
                    293: /* bottom, so we have to make this offset a constant large enough */
                    294: /* to jump over the biggest frame possible.                      */
                    295: 
                    296: #define STARTING_FRAME_OFFSET -52
                    297: 
                    298: /* tahoe always pushes 4 bytes unless it's a double in which case */
                    299: /* it pushes a full 8 bytes.                                     */
                    300: 
                    301: #define PUSH_ROUNDING(BYTES) (BYTES <= 4 ? 4 : 8)
                    302: 
                    303: /* the first parameter in a function is at the fp + 4 */
                    304: 
                    305: #define FIRST_PARM_OFFSET(FNDECL) 4
                    306: 
                    307: /* the tahoe return function takes care of everything on the stack */
                    308: 
                    309: #define RETURN_POPS_ARGS(FUNTYPE) 1
                    310: 
                    311: /* function values for all types are returned in register 0 */
                    312: 
                    313: #define FUNCTION_VALUE(VALTYPE, FUNC)  \
                    314:   gen_rtx (REG, TYPE_MODE (VALTYPE), 0)
                    315: 
                    316: /* libarary routines also return things in reg 0 */
                    317: 
                    318: #define LIBCALL_VALUE(MODE)  gen_rtx (REG, MODE, 0)
                    319: 
                    320: /* Tahoe doesn't return structures in a reentrant way */
                    321: 
                    322: #define PCC_STATIC_STRUCT_RETURN
                    323: 
                    324: /* we only return values from a function in reg 0 */
                    325: 
                    326: #define FUNCTION_VALUE_REGNO_P(N) ((N) == 0)
                    327: 
                    328: /* we never pass args through a register */
                    329: 
                    330: #define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) 0
                    331: 
                    332: /* int is fine to hold the argument summary in FUNCTION_ARG */
                    333: 
                    334: #define CUMULATIVE_ARGS int
                    335: 
                    336: /* we just set CUM to 0 before the FUNCTION_ARG call. No matter what */
                    337: /* we make it, FUNCTION_ARG will return 0 anyway                    */
                    338: 
                    339: #define INIT_CUMULATIVE_ARGS(CUM,FNTYPE)       \
                    340:  ((CUM) = 0)
                    341: 
                    342: /* all modes push their size rounded to the nearest word boundary */
                    343: /* except block which is the size of the block rounded up        */
                    344: 
                    345: #define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED)   \
                    346:  ((CUM) += ((MODE) != BLKmode                  \
                    347:            ? (GET_MODE_SIZE (MODE) + 3) & ~3   \
                    348:            : (int_size_in_bytes (TYPE) + 3) & ~3))
                    349: 
                    350: /* this is always false since we never pass params in regs */
                    351: 
                    352: #define FUNCTION_ARG_REGNO_P(N) 0
                    353: 
                    354: /* this code calculates the register entry mask and sets up    */
                    355: /* the stack pointer for the function. The stack is set down   */
                    356: /* far enough from the fp to jump over any push regs and local */
                    357: /* vars. This is a problem since the tahoe has the fp pointing */
                    358: /* to the top of the frame and the compiler must know the off- */
                    359: /* set off the fp to the local vars.                          */
                    360: 
                    361: #define FUNCTION_PROLOGUE(FILE, SIZE)     \
                    362: { register int regno;                                          \
                    363:   register int mask = 0;                                       \
                    364:   extern char call_used_regs[];                                        \
                    365:   for (regno = 0; regno < FIRST_PSEUDO_REGISTER-1; regno++)    \
                    366:     if (regs_ever_live[regno] && !call_used_regs[regno])       \
                    367:        mask |= 1 << regno;                                     \
                    368:   fprintf (FILE, "\t.word 0x%x\n", mask);                      \
                    369:   if (SIZE != 0) fprintf (FILE, "\tsubl3 $%d,fp,sp\n", (SIZE) - STARTING_FRAME_OFFSET); }
                    370: 
                    371: /* to call the profiler, push the variable value onto the stack */
                    372: /* and call mcount like a regular function.                    */
                    373: 
                    374: #define FUNCTION_PROFILER(FILE, LABELNO)  \
                    375:    fprintf (FILE, "\tpushl $LP%d\n\tcallf $8,mcount\n", (LABELNO));
                    376: 
                    377: /* all stack handling at the end of a function is handled by the */
                    378: /* return command.                                              */
                    379: 
                    380: #define EXIT_IGNORE_STACK 1
                    381: 
                    382: /* this never gets executed since the system knows it always gets  */
                    383: /* an fp to work with. It just prints a friendly message since the */
                    384: /* person must be playing with the tm file defs                   */
                    385: 
                    386: #define FIX_FRAME_POINTER_ADDRESS(ADDR,DEPTH) \
                    387:  { abort(); }
                    388: 
                    389: 
                    390: /*
                    391:  * Library Subroutine Names
                    392:  */
                    393: 
                    394: /* udiv is a valid C library routine in libc.a, so we call that */
                    395: 
                    396: #define UDIVSI3_LIBCALL "*udiv"
                    397: 
                    398: /* urem is a valid C library routine in libc.a, so we call that */
                    399: 
                    400: #define UMODSI3_LIBCALL "*urem"
                    401: 
                    402: 
                    403: /*
                    404:  * Addressing Modes
                    405:  */
                    406: 
                    407: /* constant addresses can be treated exactly the same as normal constants */
                    408: 
                    409: #define CONSTANT_ADDRESS_P(X) CONSTANT_P (X)
                    410: 
                    411: /* we can have as many as two regs in any given address */
                    412: 
                    413: #define MAX_REGS_PER_ADDRESS 2
                    414: 
                    415: /* The following is all the code for GO_IF_LEGITIMATE_ADDRESS */
                    416: /* most of this taken directly from the vax tm file since the */
                    417: /* tahoe and vax addressing modes are nearly identicle.              */
                    418: 
                    419: /* Is x an indirectable address? */
                    420: 
                    421: #define INDIRECTABLE_ADDRESS_P(X)  \
                    422:   (CONSTANT_ADDRESS_P (X)                                              \
                    423:    || (GET_CODE (X) == REG && REG_OK_FOR_BASE_P (X))                   \
                    424:    || (GET_CODE (X) == PLUS                                            \
                    425:        && GET_CODE (XEXP (X, 0)) == REG                                        \
                    426:        && REG_OK_FOR_BASE_P (XEXP (X, 0))                              \
                    427:        && CONSTANT_ADDRESS_P (XEXP (X, 1))))
                    428: 
                    429: /* If x is a non-indexed-address, go to ADDR. */
                    430: 
                    431: #define GO_IF_NONINDEXED_ADDRESS(X, ADDR)  \
                    432: { register rtx xfoob = (X);                                            \
                    433:   if (GET_CODE (xfoob) == REG) goto ADDR;                              \
                    434:   if (INDIRECTABLE_ADDRESS_P (xfoob)) goto ADDR;                       \
                    435:   xfoob = XEXP (X, 0);                                                 \
                    436:   if (GET_CODE (X) == MEM && INDIRECTABLE_ADDRESS_P (xfoob))           \
                    437:     goto ADDR;                                                         \
                    438:   if ((GET_CODE (X) == PRE_DEC || GET_CODE (X) == POST_INC)            \
                    439:       && GET_CODE (xfoob) == REG && REGNO (xfoob) == 14)               \
                    440:     goto ADDR; }
                    441: 
                    442: /* Is PROD an index term in mode MODE. */
                    443: 
                    444: #define INDEX_TERM_P(PROD, MODE)   \
                    445: (GET_MODE_SIZE (MODE) == 1                                             \
                    446:  ? (GET_CODE (PROD) == REG && REG_OK_FOR_BASE_P (PROD))                        \
                    447:  : (GET_CODE (PROD) == MULT                                            \
                    448:     &&                                                                 \
                    449:     (xfoo0 = XEXP (PROD, 0), xfoo1 = XEXP (PROD, 1),                   \
                    450:      ((GET_CODE (xfoo0) == CONST_INT                                   \
                    451:        && INTVAL (xfoo0) == GET_MODE_SIZE (MODE)                       \
                    452:        && GET_CODE (xfoo1) == REG                                      \
                    453:        && REG_OK_FOR_INDEX_P (xfoo1))                                  \
                    454:       ||                                                               \
                    455:       (GET_CODE (xfoo1) == CONST_INT                                   \
                    456:        && INTVAL (xfoo1) == GET_MODE_SIZE (MODE)                       \
                    457:        && GET_CODE (xfoo0) == REG                                      \
                    458:        && REG_OK_FOR_INDEX_P (xfoo0))))))
                    459: 
                    460: /* Is the addition to the index a reg? */
                    461: 
                    462: #define GO_IF_REG_PLUS_INDEX(X, MODE, ADDR)    \
                    463: { register rtx xfooa;                                                  \
                    464:   if (GET_CODE (X) == PLUS)                                            \
                    465:     { if (GET_CODE (XEXP (X, 0)) == REG                                        \
                    466:          && REG_OK_FOR_BASE_P (XEXP (X, 0))                            \
                    467:          && (xfooa = XEXP (X, 1),                                      \
                    468:              INDEX_TERM_P (xfooa, MODE)))                              \
                    469:        goto ADDR;                                                      \
                    470:       if (GET_CODE (XEXP (X, 1)) == REG                                        \
                    471:          && REG_OK_FOR_BASE_P (XEXP (X, 1))                            \
                    472:          && (xfooa = XEXP (X, 0),                                      \
                    473:              INDEX_TERM_P (xfooa, MODE)))                              \
                    474:        goto ADDR; } }
                    475: 
                    476: /* Is the rtx X a valid memoy address for operand of mode MODE? */
                    477: /* If it is, go to ADDR */
                    478: 
                    479: #define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR)  \
                    480: { register rtx xfoo, xfoo0, xfoo1;                                     \
                    481:   GO_IF_NONINDEXED_ADDRESS (X, ADDR);                                  \
                    482:   if (GET_CODE (X) == PLUS)                                            \
                    483:     { xfoo = XEXP (X, 0);                                              \
                    484:       if (INDEX_TERM_P (xfoo, MODE))                                   \
                    485:        { GO_IF_NONINDEXED_ADDRESS (XEXP (X, 1), ADDR); }               \
                    486:       xfoo = XEXP (X, 1);                                              \
                    487:       if (INDEX_TERM_P (xfoo, MODE))                                   \
                    488:        { GO_IF_NONINDEXED_ADDRESS (XEXP (X, 0), ADDR); }               \
                    489:       if (CONSTANT_ADDRESS_P (XEXP (X, 0)))                            \
                    490:        { if (GET_CODE (XEXP (X, 1)) == REG                             \
                    491:              && REG_OK_FOR_BASE_P (XEXP (X, 1)))                       \
                    492:            goto ADDR;                                                  \
                    493:          GO_IF_REG_PLUS_INDEX (XEXP (X, 1), MODE, ADDR); }             \
                    494:       if (CONSTANT_ADDRESS_P (XEXP (X, 1)))                            \
                    495:        { if (GET_CODE (XEXP (X, 0)) == REG                             \
                    496:              && REG_OK_FOR_BASE_P (XEXP (X, 0)))                       \
                    497:            goto ADDR;                                                  \
                    498:          GO_IF_REG_PLUS_INDEX (XEXP (X, 0), MODE, ADDR); } } }
                    499: 
                    500: /* Register 16 can never be used for index or base */
                    501: 
                    502: #ifndef REG_OK_STRICT
                    503: #define REG_OK_FOR_INDEX_P(X) (REGNO(X) != 16)
                    504: #define REG_OK_FOR_BASE_P(X) (REGNO(X) != 16)
                    505: #else
                    506: #define REG_OK_FOR_INDEX_P(X) REGNO_OK_FOR_INDEX_P (REGNO (X))
                    507: #define REG_OK_FOR_BASE_P(X) REGNO_OK_FOR_BASE_P (REGNO (X))
                    508: #endif
                    509: 
                    510: /* Addressing is too simple to allow optimizing here */
                    511: 
                    512: #define LEGITIMIZE_ADDRESS(X,OLDX,MODE,WIN)  {}
                    513: 
                    514: /* Post_inc and pre_dec always adds 4 */
                    515: 
                    516: #define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR,LABEL)       \
                    517:  { if (GET_CODE(ADDR) == POST_INC || GET_CODE(ADDR) == PRE_DEC)                \
                    518:        goto LABEL;                                                     \
                    519:    if (GET_CODE (ADDR) == PLUS)                                                \
                    520:      { if (CONSTANT_ADDRESS_P (XEXP (ADDR, 0))                         \
                    521:           && GET_CODE (XEXP (ADDR, 1)) == REG);                        \
                    522:        else if (CONSTANT_ADDRESS_P (XEXP (ADDR, 1))                    \
                    523:                && GET_CODE (XEXP (ADDR, 0)) == REG);                   \
                    524:        else goto LABEL; }}
                    525: 
                    526: /* Double's are not legitimate as immediate operands */
                    527: 
                    528: #define LEGITIMATE_CONSTANT_P(X) \
                    529:   (GET_CODE (X) != CONST_DOUBLE)
                    530: 
                    531: 
                    532: /*
                    533:  * Miscellaneous Parameters
                    534:  */
                    535: 
                    536: /* the elements in the case jump table are all words */
                    537: 
                    538: #define CASE_VECTOR_MODE HImode
                    539: 
                    540: /* each of the table elements in a case are relative to the jump addess */
                    541: 
                    542: #define CASE_VECTOR_PC_RELATIVE
                    543: 
                    544: /* tahoe case instructions just fall through to the next instruction */
                    545: /* if not satisfied. It doesn't support a default action            */
                    546: 
                    547: #define CASE_DROPS_THROUGH
                    548: 
                    549: /* the standard answer is given here and work ok */
                    550: 
                    551: #define IMPLICIT_FIX_EXPR FIX_ROUND_EXPR
                    552: 
                    553: /* in a general div case, it's easiest to use TRUNC_DIV_EXPR */
                    554: 
                    555: #define EASY_DIV_EXPR TRUNC_DIV_EXPR
                    556: 
                    557: /* the standard seems to be leaving char's as signed so we left it */
                    558: /* this way even though we think they should be unsigned!         */
                    559: 
                    560: #define DEFAULT_SIGNED_CHAR 1
                    561: 
                    562: /* the most we can move without cutting down speed is 4 bytes */
                    563: 
                    564: #define MOVE_MAX 4
                    565: 
                    566: /* our int is 32 bits */
                    567: 
                    568: #define INT_TYPE_SIZE 32
                    569: 
                    570: /* byte access isn't really slower than anything else */
                    571: 
                    572: #define SLOW_BYTE_ACCESS 0
                    573: 
                    574: /* zero extension is more than one instruction so try to avoid it */
                    575: 
                    576: #define SLOW_ZERO_EXTEND
                    577: 
                    578: /* any bits higher than the low 4 are ignored in the shift count */
                    579: /* so don't bother zero extending or sign extending them         */
                    580: 
                    581: #define SHIFT_COUNT_TRUNCATED
                    582: 
                    583: /* we don't need to officially convert from one fixed type to another */
                    584: /* in order to use it as that type. We can just assume it's the same  */
                    585: 
                    586: #define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1
                    587: 
                    588: /* pass chars as ints */
                    589: 
                    590: #define PROMOTE_PROTOTYPES
                    591: 
                    592: /* pointers can be represented by an si mode expression */
                    593: 
                    594: #define Pmode SImode
                    595: 
                    596: /* function addresses are made by specifying a byte address */
                    597: 
                    598: #define FUNCTION_MODE QImode
                    599: 
                    600: /* all the costs here were borrowed from the vax version of the */
                    601: /* tm file. They're pretty much the same in the tahoe           */
                    602: 
                    603: #define CONST_COSTS(RTX,CODE) \
                    604:   case CONST_INT:                                              \
                    605:     if (RTX == const0_rtx) return 0;                           \
                    606:     if ((unsigned) INTVAL (RTX) < 077) return 1;               \
                    607:   case CONST:                                                  \
                    608:   case LABEL_REF:                                              \
                    609:   case SYMBOL_REF:                                             \
                    610:     return 3;                                                  \
                    611:   case CONST_DOUBLE:                                           \
                    612:     return 5;
                    613: 
                    614: 
                    615: /*
                    616:  * Condition Code Information
                    617:  */
                    618: 
                    619: /* Condition codes still break in one case that we haven't tracked */
                    620: /* down yet, so we have to leave them like this for now.          */
                    621: 
                    622: #define NOTICE_UPDATE_CC(EXP, INSN) \
                    623: { if (GET_CODE(EXP) == SET && GET_CODE(SET_DEST(EXP)) == CC0) {                \
                    624:        cc_status.flags = 0;                                    \
                    625:        cc_status.value1 = SET_DEST(EXP);                       \
                    626:        cc_status.value2 = SET_SRC(EXP);                        \
                    627:   } else                                                       \
                    628:        CC_STATUS_INIT; }
                    629: 
                    630: 
                    631: /*
                    632:  * Output of Assembler Code
                    633:  */
                    634: 
                    635: /* start the assembly by turning off APP */
                    636: 
                    637: #define ASM_FILE_START(FILE) fprintf (FILE, "#NO_APP\n\n");
                    638: 
                    639: /* the instruction that turns on the APP for the gnu assembler */
                    640: 
                    641: #define ASM_APP_ON "#APP\n"
                    642: 
                    643: /* the instruction that turns off the APP for the gnu assembler */
                    644: 
                    645: #define ASM_APP_OFF "#NO_APP\n"
                    646: 
                    647: /* what to output before read-only data.  */
                    648: 
                    649: #define TEXT_SECTION_ASM_OP ".text"
                    650: 
                    651: /* what to output before writable data.  */
                    652: 
                    653: #define DATA_SECTION_ASM_OP ".data"
                    654: 
                    655: /* this is what we call each of the regs. notice that the FPP reg is   */
                    656: /* called "ac". This should never get used due to the way we've set    */
                    657: /* up FPP instructions in the md file. But we call it "ac" here to     */
                    658: /* fill the list.                                                     */
                    659: 
                    660: #define REGISTER_NAMES \
                    661: {"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", \
                    662:  "r9", "r10", "r11", "r12", "fp", "sp", "pc", "ac"}
                    663: 
                    664: /* registers are called the same thing in dbx anything else */
                    665: 
                    666: #define DBX_REGISTER_NUMBER(REGNO) (REGNO)
                    667: 
                    668: /* allow generation of dbx info in the assembly */
                    669: 
                    670: #define DBX_DEBUGGING_INFO
                    671: 
                    672: /* our dbx doesn't support this */
                    673: 
                    674: #define DBX_NO_XREFS
                    675: 
                    676: /* we don't want symbols broken up */
                    677: 
                    678: #define DBX_CONTIN_LENGTH 0
                    679: 
                    680: /* this'll really never be used, but we'll leave it at this */
                    681: 
                    682: #define DBX_CONTIN_CHAR '?'
                    683: 
                    684: /* labels are the label followed by a colon and a newline */
                    685: /* must be a statement, so surround it in a null loop     */
                    686: 
                    687: #define ASM_OUTPUT_LABEL(FILE,NAME)    \
                    688:   do { assemble_name (FILE, NAME); fputs (":\n", FILE); } while (0)
                    689: 
                    690: /* use the .globl directive to make labels global for the linker */
                    691: 
                    692: #define ASM_GLOBALIZE_LABEL(FILE,NAME) \
                    693:   do { fputs (".globl ", FILE); assemble_name (FILE, NAME); fputs ("\n", FILE);} while (0)
                    694: 
                    695: /* output a label by appending an underscore to it */
                    696: 
                    697: #define ASM_OUTPUT_LABELREF(FILE,NAME) \
                    698:   fprintf (FILE, "_%s", NAME)
                    699: 
                    700: /* use the standard format for printing internal labels */
                    701: 
                    702: #define ASM_OUTPUT_INTERNAL_LABEL(FILE,PREFIX,NUM)     \
                    703:   fprintf (FILE, "%s%d:\n", PREFIX, NUM)
                    704: 
                    705: /* a * is used for label indirection in unix assembly */
                    706: 
                    707: #define ASM_GENERATE_INTERNAL_LABEL(LABEL,PREFIX,NUM)  \
                    708:   sprintf (LABEL, "*%s%d", PREFIX, NUM)
                    709: 
                    710: /* outputing a double is easy cause we only have one kind */
                    711: 
                    712: #define ASM_OUTPUT_DOUBLE(FILE,VALUE)  \
                    713: {                                                      \
                    714:   union { int i[2]; double d;} temp;                   \
                    715:   temp.d = (VALUE);                                    \
                    716:   if (TARGET_HEX_FLOAT)                                        \
                    717:     fprintf ((FILE), "\t.long 0x%x,0x%x  # %.20e\n",   \
                    718:             temp.i[0], temp.i[1], temp.d);             \
                    719:   else                                                 \
                    720:     fprintf (FILE, "\t.dfloat 0d%.20e\n", temp.d);     \
                    721: }
                    722: 
                    723: /* This is how to output an assembler line defining a `float' constant.  */
                    724: 
                    725: #define ASM_OUTPUT_FLOAT(FILE,VALUE)  \
                    726: {                                                      \
                    727:   union { int i; float f;} temp;                       \
                    728:   temp.f = (float) (VALUE);                            \
                    729:   if (TARGET_HEX_FLOAT)                                        \
                    730:     fprintf ((FILE), "\t.long 0x%x  # %.20e\n",                \
                    731:             temp.i, temp.f);                           \
                    732:   else                                                 \
                    733:     fprintf (FILE, "\t.float 0f%.20e\n", temp.f);      \
                    734: }
                    735: 
                    736: /* This is how to output an assembler line defining an `int' constant.  */
                    737: 
                    738: #define ASM_OUTPUT_INT(FILE,VALUE)  \
                    739: ( fprintf (FILE, "\t.long "),                  \
                    740:   output_addr_const (FILE, (VALUE)),           \
                    741:   fprintf (FILE, "\n"))
                    742: 
                    743: /* Likewise for `char' and `short' constants.  */
                    744: 
                    745: #define ASM_OUTPUT_SHORT(FILE,VALUE)  \
                    746: ( fprintf (FILE, "\t.word "),                  \
                    747:   output_addr_const (FILE, (VALUE)),           \
                    748:   fprintf (FILE, "\n"))
                    749: 
                    750: #define ASM_OUTPUT_CHAR(FILE,VALUE)  \
                    751: ( fprintf (FILE, "\t.byte "),                  \
                    752:   output_addr_const (FILE, (VALUE)),           \
                    753:   fprintf (FILE, "\n"))
                    754: 
                    755: /* This is how to output an assembler line for a numeric constant byte.  */
                    756: 
                    757: #define ASM_OUTPUT_BYTE(FILE,VALUE)  \
                    758:   fprintf (FILE, "\t.byte 0x%x\n", (VALUE))
                    759: 
                    760: /* this is the insn to push a register onto the stack */
                    761: 
                    762: #define ASM_OUTPUT_REG_PUSH(FILE,REGNO)        \
                    763:   fprintf (FILE, "\tpushl %s\n", reg_names[REGNO])
                    764: 
                    765: /* this is the insn to pop a register from the stack */
                    766: 
                    767: #define ASM_OUTPUT_REG_POP(FILE,REGNO) \
                    768:   fprintf (FILE, "\tmovl (sp)+,%s\n", reg_names[REGNO])
                    769: 
                    770: /* this is required even thought tahoe doesn't support it */
                    771: /* cause the C code expects it to be defined             */
                    772: 
                    773: #define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE)  \
                    774:   fprintf (FILE, "\t.long L%d\n", VALUE)
                    775: 
                    776: /* This is how to output an element of a case-vector that is relative.  */
                    777: 
                    778: #define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, VALUE, REL)  \
                    779:   fprintf (FILE, "\t.word L%d-L%d\n", VALUE, REL)
                    780: 
                    781: /* This aligns the assembler output */
                    782: 
                    783: #define ASM_OUTPUT_ALIGN(FILE,LOG)  \
                    784:   LOG ? fprintf (FILE, "\t.align %d\n", (LOG)) : 0
                    785: 
                    786: /* This is how to skip over some space */
                    787: 
                    788: #define ASM_OUTPUT_SKIP(FILE,SIZE)  \
1.1.1.2 ! root      789:   fprintf (FILE, "\t.space %u\n", (SIZE))
1.1       root      790: 
                    791: /* This defines common variables across files */
                    792: 
                    793: #define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED)  \
                    794: ( fputs (".comm ", (FILE)),                    \
                    795:   assemble_name ((FILE), (NAME)),              \
1.1.1.2 ! root      796:   fprintf ((FILE), ",%u\n", (ROUNDED)))
1.1       root      797: 
                    798: /* This defines a common varible in the local file */
                    799: 
                    800: #define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE, ROUNDED)  \
                    801: ( fputs (".lcomm ", (FILE)),                   \
                    802:   assemble_name ((FILE), (NAME)),              \
1.1.1.2 ! root      803:   fprintf ((FILE), ",%u\n", (ROUNDED)))
1.1       root      804: 
                    805: /* code to generate a label */
                    806: 
                    807: #define ASM_FORMAT_PRIVATE_NAME(OUTPUT, NAME, LABELNO) \
                    808: ( (OUTPUT) = (char *) alloca (strlen ((NAME)) + 10),   \
                    809:   sprintf ((OUTPUT), "%s.%d", (NAME), (LABELNO)))
                    810: 
                    811: /* parenthesis for expressions in the assembly */
                    812: 
                    813: #define ASM_OPEN_PAREN "("
                    814: #define ASM_CLOSE_PAREN ")"
                    815: 
                    816: /* Define results of standard character escape sequences.  */
                    817: 
                    818: #define TARGET_BELL 007
                    819: #define TARGET_BS 010
                    820: #define TARGET_TAB 011
                    821: #define TARGET_NEWLINE 012
                    822: #define TARGET_VT 013
                    823: #define TARGET_FF 014
                    824: #define TARGET_CR 015
                    825: 
                    826: /* Print an operand.  Some difference from the vax code,
                    827:    since the tahoe can't support immediate floats and doubles.
                    828: 
                    829:    %@ means print the proper alignment operand for aligning after a casesi.
                    830:    This depends on the assembler syntax.
                    831:    This is 1 for our assembler, since .align is logarithmic.  */
                    832: 
                    833: #define PRINT_OPERAND_PUNCT_VALID_P(CODE)                              \
                    834:   ((CODE) == '@')
                    835: 
                    836: #define PRINT_OPERAND(FILE, X, CODE)  \
                    837: { if (CODE == '@')                                                     \
                    838:     putc ('1', FILE);                                                  \
                    839:   else if (GET_CODE (X) == REG)                                                \
                    840:     fprintf (FILE, "%s", reg_names[REGNO (X)]);                                \
                    841:   else if (GET_CODE (X) == MEM)                                                \
                    842:     output_address (XEXP (X, 0));                                      \
                    843:   else { putc ('$', FILE); output_addr_const (FILE, X); }}
                    844: 
                    845: /* When the operand is an address, call print_operand_address to */
                    846: /* do the work from output-tahoe.c.                             */
                    847: 
                    848: #define PRINT_OPERAND_ADDRESS(FILE, ADDR)  \
                    849:  print_operand_address (FILE, ADDR)
                    850: 

unix.superglobalmegacorp.com

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