|
|
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: ! 119: #define PCC_BITFIELD_TYPE_MATTERS ! 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) \ ! 789: fprintf (FILE, "\t.space %d\n", (SIZE)) ! 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)), \ ! 796: fprintf ((FILE), ",%d\n", (ROUNDED))) ! 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)), \ ! 803: fprintf ((FILE), ",%d\n", (ROUNDED))) ! 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:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.