📄 tahoe.h
字号:
&& (xfooa = XEXP (X, 0), \ INDEX_TERM_P (xfooa, MODE))) \ goto ADDR; } }/* Is the rtx X a valid memory address for operand of mode MODE? *//* If it is, go to ADDR */#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \{ register rtx xfoo, xfoo0, xfoo1; \ GO_IF_NONINDEXED_ADDRESS (X, ADDR); \ if (GET_CODE (X) == PLUS) \ { xfoo = XEXP (X, 0); \ if (INDEX_TERM_P (xfoo, MODE)) \ { GO_IF_NONINDEXED_ADDRESS (XEXP (X, 1), ADDR); } \ xfoo = XEXP (X, 1); \ if (INDEX_TERM_P (xfoo, MODE)) \ { GO_IF_NONINDEXED_ADDRESS (XEXP (X, 0), ADDR); } \ if (CONSTANT_ADDRESS_P (XEXP (X, 0))) \ { if (GET_CODE (XEXP (X, 1)) == REG \ && REG_OK_FOR_BASE_P (XEXP (X, 1))) \ goto ADDR; \ GO_IF_REG_PLUS_INDEX (XEXP (X, 1), MODE, ADDR); } \ if (CONSTANT_ADDRESS_P (XEXP (X, 1))) \ { if (GET_CODE (XEXP (X, 0)) == REG \ && REG_OK_FOR_BASE_P (XEXP (X, 0))) \ goto ADDR; \ GO_IF_REG_PLUS_INDEX (XEXP (X, 0), MODE, ADDR); } } }/* Register 16 can never be used for index or base */#ifndef REG_OK_STRICT#define REG_OK_FOR_INDEX_P(X) (REGNO(X) != 16)#define REG_OK_FOR_BASE_P(X) (REGNO(X) != 16)#else#define REG_OK_FOR_INDEX_P(X) REGNO_OK_FOR_INDEX_P (REGNO (X))#define REG_OK_FOR_BASE_P(X) REGNO_OK_FOR_BASE_P (REGNO (X))#endif/* Addressing is too simple to allow optimizing here */#define LEGITIMIZE_ADDRESS(X,OLDX,MODE,WIN) {}/* Post_inc and pre_dec always adds 4 */#define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR,LABEL) \ { if (GET_CODE(ADDR) == POST_INC || GET_CODE(ADDR) == PRE_DEC) \ goto LABEL; \ if (GET_CODE (ADDR) == PLUS) \ { if (CONSTANT_ADDRESS_P (XEXP (ADDR, 0)) \ && GET_CODE (XEXP (ADDR, 1)) == REG); \ else if (CONSTANT_ADDRESS_P (XEXP (ADDR, 1)) \ && GET_CODE (XEXP (ADDR, 0)) == REG); \ else goto LABEL; }}/* Double's are not legitimate as immediate operands */#define LEGITIMATE_CONSTANT_P(X) \ (GET_CODE (X) != CONST_DOUBLE)/* * Miscellaneous Parameters *//* the elements in the case jump table are all words */#define CASE_VECTOR_MODE HImode/* each of the table elements in a case are relative to the jump address */#define CASE_VECTOR_PC_RELATIVE/* tahoe case instructions just fall through to the next instruction *//* if not satisfied. It doesn't support a default action */#define CASE_DROPS_THROUGH/* the standard answer is given here and work ok */#define IMPLICIT_FIX_EXPR FIX_ROUND_EXPR/* in a general div case, it's easiest to use TRUNC_DIV_EXPR */#define EASY_DIV_EXPR TRUNC_DIV_EXPR/* the standard seems to be leaving char's as signed so we left it *//* this way even though we think they should be unsigned! */#define DEFAULT_SIGNED_CHAR 1/* the most we can move without cutting down speed is 4 bytes */#define MOVE_MAX 4/* our int is 32 bits */#define INT_TYPE_SIZE 32/* byte access isn't really slower than anything else */#define SLOW_BYTE_ACCESS 0/* zero extension is more than one instruction so try to avoid it */#define SLOW_ZERO_EXTEND/* any bits higher than the low 4 are ignored in the shift count *//* so don't bother zero extending or sign extending them */#define SHIFT_COUNT_TRUNCATED 1/* we don't need to officially convert from one fixed type to another *//* in order to use it as that type. We can just assume it's the same */#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1/* pass chars as ints */#define PROMOTE_PROTOTYPES/* pointers can be represented by an si mode expression */#define Pmode SImode/* function addresses are made by specifying a byte address */#define FUNCTION_MODE QImode/* Define this if addresses of constant functions shouldn't be put through pseudo regs where they can be cse'd. On the tahoe a call with a constant address is much faster than one with a register. */#define NO_FUNCTION_CSE/* specify the costs of various sorts of constants, and also indicate that multiplication is cheap on this machine. */#define CONST_COSTS(RTX,CODE,OUTER_CODE) \ case CONST_INT: \ /* Constant zero is super cheap due to clr instruction. */ \ if (RTX == const0_rtx) return 0; \ if ((unsigned) INTVAL (RTX) < 077) return 1; \ if (INTVAL (RTX) <= 127 && INTVAL (RTX) >= -128) return 2; \ case CONST: \ case LABEL_REF: \ case SYMBOL_REF: \ return 3; \ case CONST_DOUBLE: \ return 5; \ case MULT: \ total = 2;/* * Condition Code Information *//* Nonzero if the results of the previous comparison are in the floating point condition code register. */#define CC_UNCHANGED 04000#define NOTICE_UPDATE_CC(EXP, INSN) \{ if (cc_status.flags & CC_UNCHANGED) \ /* Happens for cvtld and a few other insns. */ \ cc_status.flags &= ~CC_UNCHANGED; \ else if (GET_CODE (EXP) == SET) \ { if (GET_CODE (SET_SRC (EXP)) == CALL) \ CC_STATUS_INIT; \ else if (GET_CODE (SET_DEST (EXP)) != PC) \ { cc_status.flags = 0; \ cc_status.value1 = SET_DEST (EXP); \ cc_status.value2 = SET_SRC (EXP); } } \ else if (GET_CODE (EXP) == PARALLEL \ && GET_CODE (XVECEXP (EXP, 0, 0)) == SET \ && GET_CODE (SET_DEST (XVECEXP (EXP, 0, 0))) != PC) \ { cc_status.flags = 0; \ cc_status.value1 = SET_DEST (XVECEXP (EXP, 0, 0)); \ cc_status.value2 = SET_SRC (XVECEXP (EXP, 0, 0)); } \ /* PARALLELs whose first element sets the PC are aob, sob insns. \ They do change the cc's. So drop through and forget the cc's. */ \ else CC_STATUS_INIT; \ if (cc_status.value1 && GET_CODE (cc_status.value1) == REG \ && cc_status.value2 \ && reg_overlap_mentioned_p (cc_status.value1, cc_status.value2)) \ cc_status.value2 = 0; \ if (cc_status.value1 && GET_CODE (cc_status.value1) == MEM \ && cc_status.value2 \ && GET_CODE (cc_status.value2) == MEM) \ cc_status.value2 = 0; }/* Actual condition, one line up, should be that value2's address depends on value1, but that is too much of a pain. *//* * Output of Assembler Code *//* print which tahoe version compiled this code and print a directive *//* to the gnu assembler to say that the following is normal assembly */#ifdef HCX_UX#define ASM_FILE_START(FILE) \{ fprintf (FILE, "#gcc hcx 1.0\n\n"); \ output_file_directive ((FILE), main_input_filename);} while (0)#else#define ASM_FILE_START(FILE) fprintf (FILE, "#gcc tahoe 1.0\n#NO_APP\n");#endif/* the instruction that turns on the APP for the gnu assembler */#define ASM_APP_ON "#APP\n"/* the instruction that turns off the APP for the gnu assembler */#define ASM_APP_OFF "#NO_APP\n"/* what to output before read-only data. */#define TEXT_SECTION_ASM_OP ".text"/* what to output before writable data. */#define DATA_SECTION_ASM_OP ".data"/* this is what we call each of the regs. notice that the FPP reg is *//* called "ac". This should never get used due to the way we've set *//* up FPP instructions in the md file. But we call it "ac" here to *//* fill the list. */#define REGISTER_NAMES \{"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", \ "r9", "r10", "r11", "r12", "fp", "sp", "pc", "ac"}#ifdef HCX_UX/* allow generation of sdb info in the assembly */#define SDB_DEBUGGING_INFO#else/* allow generation of dbx info in the assembly */#define DBX_DEBUGGING_INFO/* our dbx doesn't support this */#define DBX_NO_XREFS/* we don't want symbols broken up */#define DBX_CONTIN_LENGTH 0/* this'll really never be used, but we'll leave it at this */#define DBX_CONTIN_CHAR '?'#endif /* HCX_UX *//* registers are called the same thing in dbx anything else *//* This is necessary even if we generate SDB output */#define DBX_REGISTER_NUMBER(REGNO) (REGNO)/* labels are the label followed by a colon and a newline *//* must be a statement, so surround it in a null loop */#define ASM_OUTPUT_LABEL(FILE,NAME) \ do { assemble_name (FILE, NAME); fputs (":\n", FILE); } while (0)/* use the .globl directive to make labels global for the linker */#define ASM_GLOBALIZE_LABEL(FILE,NAME) \ do { fputs (".globl ", FILE); assemble_name (FILE, NAME); fputs ("\n", FILE);} while (0)/* output a label by appending an underscore to it */#define ASM_OUTPUT_LABELREF(FILE,NAME) \ fprintf (FILE, "_%s", NAME)/* use the standard format for printing internal labels */#define ASM_OUTPUT_INTERNAL_LABEL(FILE,PREFIX,NUM) \ fprintf (FILE, "%s%d:\n", PREFIX, NUM)/* a * is used for label indirection in unix assembly */#define ASM_GENERATE_INTERNAL_LABEL(LABEL,PREFIX,NUM) \ sprintf (LABEL, "*%s%d", PREFIX, NUM)/* outputting a double is easy cause we only have one kind */#ifdef HCX_UX#define ASM_OUTPUT_DOUBLE(FILE,VALUE) \ fprintf (FILE, "\t.double 0d%.20e\n", (VALUE))#else#define ASM_OUTPUT_DOUBLE(FILE,VALUE) \{ \ union { int i[2]; double d;} temp; \ temp.d = (VALUE); \ if (TARGET_HEX_FLOAT) \ fprintf ((FILE), "\t.long 0x%x,0x%x # %.20e\n", \ temp.i[0], temp.i[1], temp.d); \ else \ fprintf (FILE, "\t.dfloat 0d%.20e\n", temp.d); \}#endif/* This is how to output an assembler line defining a `float' constant. */#ifdef HCX_UX#define ASM_OUTPUT_FLOAT(FILE,VALUE) \ fprintf (FILE, "\t.float 0f%.20e\n", (VALUE))#else#define ASM_OUTPUT_FLOAT(FILE,VALUE) \{ \ union { int i; float f;} temp; \ temp.f = (float) (VALUE); \ if (TARGET_HEX_FLOAT) \ fprintf ((FILE), "\t.long 0x%x # %.20e\n", \ temp.i, temp.f); \ else \ fprintf (FILE, "\t.float 0f%.20e\n", temp.f); \}#endif/* This is how to output an assembler line defining an `int' constant. */#define ASM_OUTPUT_INT(FILE,VALUE) \( fprintf (FILE, "\t.long "), \ output_addr_const (FILE, (VALUE)), \ fprintf (FILE, "\n"))/* Likewise for `char' and `short' constants. */#define ASM_OUTPUT_SHORT(FILE,VALUE) \( fprintf (FILE, "\t.word "), \ output_addr_const (FILE, (VALUE)), \ fprintf (FILE, "\n"))#define ASM_OUTPUT_CHAR(FILE,VALUE) \( fprintf (FILE, "\t.byte "), \ output_addr_const (FILE, (VALUE)), \ fprintf (FILE, "\n"))#ifdef HCX_UX/* This is how to output an assembler line for an ASCII string. */#define ASM_OUTPUT_ASCII(FILE, p, size) \do { register int i; \ fprintf ((FILE), "\t.ascii \""); \ for (i = 0; i < (size); i++) \ { \ register int c = (p)[i]; \ if (c == '\'' || c == '\\') \ putc ('\\', (FILE)); \ if (c >= ' ' && c < 0177 && c != '\"') \ putc (c, (FILE)); \ else \ { \ fprintf ((FILE), "\\%03o", c); \ } \ } \ fprintf ((FILE), "\"\n"); } while (0)#endif/* This is how to output an assembler line for a numeric constant byte. */#define ASM_OUTPUT_BYTE(FILE,VALUE) \ fprintf (FILE, "\t.byte 0x%x\n", (VALUE))/* this is the insn to push a register onto the stack */#define ASM_OUTPUT_REG_PUSH(FILE,REGNO) \ fprintf (FILE, "\tpushl %s\n", reg_names[REGNO])/* this is the insn to pop a register from the stack */#define ASM_OUTPUT_REG_POP(FILE,REGNO) \ fprintf (FILE, "\tmovl (sp)+,%s\n", reg_names[REGNO])/* this is required even thought tahoe doesn't support it *//* cause the C code expects it to be defined */#define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \ fprintf (FILE, "\t.long L%d\n", VALUE)/* This is how to output an element of a case-vector that is relative. */#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, VALUE, REL) \ fprintf (FILE, "\t.word L%d-L%d\n", VALUE, REL)/* This is how to output an assembler line that says to advance the location counter to a multiple of 2**LOG bytes. */#ifdef HCX_UX#define CASE_ALIGNMENT 2#define ASM_OUTPUT_ALIGN(FILE,LOG) \ if ((LOG)!=0) fprintf ((FILE), "\t.align %d\n", 1<<(LOG))#else#define CASE_ALIGNMENT 1#define ASM_OUTPUT_ALIGN(FILE,LOG) \ LOG ? fprintf (FILE, "\t.align %d\n", (LOG)) : 0#endif/* This is how to skip over some space */#define ASM_OUTPUT_SKIP(FILE,SIZE) \ fprintf (FILE, "\t.space %u\n", (SIZE))/* This defines common variables across files */#ifdef HCX_UX#define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED) \( fputs (".comm ", (FILE)), \ assemble_name ((FILE), (NAME)), \ fprintf ((FILE), ",%u\n", (SIZE)))#else#define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED) \( fputs (".comm ", (FILE)), \ assemble_name ((FILE), (NAME)), \ fprintf ((FILE), ",%u\n", (ROUNDED)))#endif/* This says how to output an assembler line to define a local common symbol. */#ifdef HCX_UX#define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE, ROUNDED) \( fputs ("\t.bss ", (FILE)), \ assemble_name ((FILE), (NAME)), \ fprintf ((FILE), ",%u,4\n", (SIZE),(ROUNDED)))#else#define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE, ROUNDED) \( fputs (".lcomm ", (FILE)), \ assemble_name ((FILE), (NAME)), \ fprintf ((FILE), ",%u\n", (ROUNDED)))#endif/* code to generate a label */#define ASM_FORMAT_PRIVATE_NAME(OUTPUT, NAME, LABELNO) \( (OUTPUT) = (char *) alloca (strlen ((NAME)) + 10), \ sprintf ((OUTPUT), "%s.%d", (NAME), (LABELNO)))/* Define the parentheses used to group arithmetic operations in assembler code. */#define ASM_OPEN_PAREN "("#define ASM_CLOSE_PAREN ")"/* Define results of standard character escape sequences. */#define TARGET_BELL 007#define TARGET_BS 010#define TARGET_TAB 011#define TARGET_NEWLINE 012#define TARGET_VT 013#define TARGET_FF 014#define TARGET_CR 015/* Print an instruction operand X on file FILE. CODE is the code from the %-spec that requested printing this operand; if `%z3' was used to print operand 3, then CODE is 'z'. On the Vax, the only code used is `#', indicating that either `d' or `g' should be printed, depending on whether we're using dfloat or gfloat. *//* Print an operand. Some difference from the vax code, since the tahoe can't support immediate floats and doubles. %@ means print the proper alignment operand for aligning after a casesi. This depends on the assembler syntax. This is 1 for our assembler, since .align is logarithmic. %s means the number given is supposed to be a shift value, but on the tahoe it should be converted to a number that can be used as a multiplicative constant (cause multiplication is a whole lot faster than shifting). So make the number 2^n instead. */#define PRINT_OPERAND_PUNCT_VALID_P(CODE) \ ((CODE) == '@')#define PRINT_OPERAND(FILE, X, CODE) \{ if (CODE == '@') \ putc ('0' + CASE_ALIGNMENT, FILE); \ else if (CODE == 's') \ fprintf (FILE, "$%d", 1 << INTVAL(X)); \ else if (GET_CODE (X) == REG) \ fprintf (FILE, "%s", reg_names[REGNO (X)]); \ else if (GET_CODE (X) == MEM) \ output_address (XEXP (X, 0)); \ else { putc ('$', FILE); output_addr_const (FILE, X); }}/* When the operand is an address, call print_operand_address to *//* do the work from output-tahoe.c. */#define PRINT_OPERAND_ADDRESS(FILE, ADDR) \ print_operand_address (FILE, ADDR)/* This is for G++ */#define CRT0_DUMMIES#define DOT_GLOBAL_START#ifdef HCX_UX#define NO_GNU_LD /* because of COFF format */#define LINK_SPEC "-L/usr/staff/lib"#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -