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