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