📄 i370.h
字号:
#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \{ \ if (REG_P (X) && REG_OK_FOR_BASE_P (X)) \ goto ADDR; \ if (GET_CODE (X) == PLUS) \ { \ int regs = 0; \ rtx x0 = XEXP (X, 0); \ rtx x1 = XEXP (X, 1); \ if (GET_CODE (x0) == PLUS) \ { \ COUNT_REGS (XEXP (x0, 0), regs, FAIL); \ COUNT_REGS (XEXP (x0, 1), regs, FAIL); \ COUNT_REGS (x1, regs, FAIL); \ if (regs == 2) \ goto ADDR; \ } \ else if (GET_CODE (x1) == PLUS) \ { \ COUNT_REGS (x0, regs, FAIL); \ COUNT_REGS (XEXP (x1, 0), regs, FAIL); \ COUNT_REGS (XEXP (x1, 1), regs, FAIL); \ if (regs == 2) \ goto ADDR; \ } \ else \ { \ COUNT_REGS (x0, regs, FAIL); \ COUNT_REGS (x1, regs, FAIL); \ if (regs != 0) \ goto ADDR; \ } \ } \ FAIL: ; \}/* The 370 has no mode dependent addresses. */#define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR, LABEL)/* Try machine-dependent ways of modifying an illegitimate address to be legitimate. If we find one, return the new, valid address. This macro is used in only one place: `memory_address' in explow.c. */#define LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN) \{ \ if (GET_CODE (X) == PLUS && CONSTANT_ADDRESS_P (XEXP (X, 1))) \ (X) = gen_rtx (PLUS, SImode, XEXP (X, 0), \ copy_to_mode_reg (SImode, XEXP (X, 1))); \ if (GET_CODE (X) == PLUS && CONSTANT_ADDRESS_P (XEXP (X, 0))) \ (X) = gen_rtx (PLUS, SImode, XEXP (X, 1), \ copy_to_mode_reg (SImode, XEXP (X, 0))); \ if (GET_CODE (X) == PLUS && GET_CODE (XEXP (X, 0)) == MULT) \ (X) = gen_rtx (PLUS, SImode, XEXP (X, 1), \ force_operand (XEXP (X, 0), 0)); \ if (GET_CODE (X) == PLUS && GET_CODE (XEXP (X, 1)) == MULT) \ (X) = gen_rtx (PLUS, SImode, XEXP (X, 0), \ force_operand (XEXP (X, 1), 0)); \ if (memory_address_p (MODE, X)) \ goto WIN; \}/* Specify the machine mode that this machine uses for the index in the tablejump instruction. */#define CASE_VECTOR_MODE SImode/* Define as C expression which evaluates to nonzero if the tablejump instruction expects the table to contain offsets from the address of the table. Do not define this if the table should contain absolute addresses. *//* #define CASE_VECTOR_PC_RELATIVE 1 *//* Specify the tree operation to be used to convert reals to integers. */#define IMPLICIT_FIX_EXPR FIX_ROUND_EXPR/* Define this if fixuns_trunc is the same as fix_trunc. */#define FIXUNS_TRUNC_LIKE_FIX_TRUNC/* We use "unsigned char" as default. */#define DEFAULT_SIGNED_CHAR 0/* This is the kind of divide that is easiest to do in the general case. */#define EASY_DIV_EXPR TRUNC_DIV_EXPR/* Max number of bytes we can move from memory to memory in one reasonably fast instruction. */#define MOVE_MAX 256/* Define this if zero-extension is slow (more than one real instruction). */#define SLOW_ZERO_EXTEND/* Nonzero if access to memory by bytes is slow and undesirable. */#define SLOW_BYTE_ACCESS 1/* Define if shifts truncate the shift count which implies one can omit a sign-extension or zero-extension of a shift count. *//* #define SHIFT_COUNT_TRUNCATED *//* Value is 1 if truncating an integer of INPREC bits to OUTPREC bits is done just by pretending it is already truncated. */#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) (OUTPREC != 16)/* We assume that the store-condition-codes instructions store 0 for false and some other value for true. This is the value stored for true. *//* #define STORE_FLAG_VALUE -1 *//* When a prototype says `char' or `short', really pass an `int'. */#define PROMOTE_PROTOTYPES/* Don't perform CSE on function addresses. */#define NO_FUNCTION_CSE/* Specify the machine mode that pointers have. After generation of rtl, the compiler makes no further distinction between pointers and any other objects of this machine mode. */#define Pmode SImode/* A function address in a call instruction is a byte address (for indexing purposes) so give the MEM rtx a byte's mode. */#define FUNCTION_MODE QImode/* Compute the cost of computing a constant rtl expression RTX whose rtx-code is CODE. The body of this macro is a portion of a switch statement. If the code is computed here, return it with a return statement. Otherwise, break from the switch. */#define CONST_COSTS(RTX, CODE, OUTERCODE) \ case CONST_INT: \ if ((unsigned) INTVAL (RTX) < 0xfff) return 1; \ case CONST: \ case LABEL_REF: \ case SYMBOL_REF: \ return 2; \ case CONST_DOUBLE: \ return 4;/* Tell final.c how to eliminate redundant test instructions. *//* Here we define machine-dependent flags and fields in cc_status (see `conditions.h'). *//* Store in cc_status the expressions that the condition codes will describe after execution of an instruction whose pattern is EXP. Do not alter them if the instruction would not alter the cc's. On the 370, load insns do not alter the cc's. However, in some cases these instructions can make it possibly invalid to use the saved cc's. In those cases we clear out some or all of the saved cc's so they won't be used. */#define NOTICE_UPDATE_CC(EXP, INSN) \{ \ rtx exp = (EXP); \ if (GET_CODE (exp) == PARALLEL) /* Check this */ \ exp = XVECEXP (exp, 0, 0); \ if (GET_CODE (exp) != SET) \ CC_STATUS_INIT; \ else \ { \ if (XEXP (exp, 0) == cc0_rtx) \ { \ cc_status.value1 = XEXP (exp, 0); \ cc_status.value2 = XEXP (exp, 1); \ cc_status.flags = 0; \ } \ else \ { \ if (cc_status.value1 \ && reg_mentioned_p (XEXP (exp, 0), cc_status.value1)) \ cc_status.value1 = 0; \ if (cc_status.value2 \ && reg_mentioned_p (XEXP (exp, 0), cc_status.value2)) \ cc_status.value2 = 0; \ switch (GET_CODE (XEXP (exp, 1))) \ { \ case PLUS: case MINUS: case MULT: /* case UMULT: */ \ case DIV: case UDIV: case NEG: case ASHIFT: \ case ASHIFTRT: case AND: case IOR: case XOR: \ case ABS: case NOT: \ CC_STATUS_SET (XEXP (exp, 0), XEXP (exp, 1)); \ } \ } \ } \}#define CC_STATUS_SET(V1, V2) \{ \ cc_status.flags = 0; \ cc_status.value1 = (V1); \ cc_status.value2 = (V2); \ if (cc_status.value1 \ && reg_mentioned_p (cc_status.value1, cc_status.value2)) \ cc_status.value2 = 0; \}#define OUTPUT_JUMP(NORMAL, FLOAT, NO_OV) \{ if (cc_status.flags & CC_NO_OVERFLOW) return NO_OV; return NORMAL; }/* Control the assembler format that we output. */#define TEXT_SECTION_ASM_OP "* Program text area"#define DATA_SECTION_ASM_OP "* Program data area"#define INIT_SECTION_ASM_OP "* Program initialization area"#define CTOR_LIST_BEGIN /* NO OP */#define CTOR_LIST_END /* NO OP *//* How to refer to registers in assembler output. This sequence is indexed by compiler's hard-register-number (see above). */#define REGISTER_NAMES \{ "0", "1", "2", "3", "4", "5", "6", "7", \ "8", "9", "10", "11", "12", "13", "14", "15", \ "0", "2", "4", "6" \}/* How to renumber registers for dbx and gdb. */#define DBX_REGISTER_NUMBER(REGNO) (REGNO)#define ASM_FILE_START(FILE) fputs ("\tCSECT\n", FILE);#define ASM_FILE_END(FILE) fputs ("\tEND\n", FILE);#define ASM_IDENTIFY_GCC(FILE)#define ASM_COMMENT_START "*"#define ASM_APP_OFF ""#define ASM_APP_ON ""#define ASM_OUTPUT_LABEL(FILE, NAME) \{ assemble_name (FILE, NAME); fputs ("\tEQU\t*\n", FILE); }#define ASM_OUTPUT_EXTERNAL(FILE, DECL, NAME) /* NO OP */#define ASM_GLOBALIZE_LABEL(FILE, NAME) \{ fputs ("\tENTRY\t", FILE); assemble_name (FILE, NAME); fputs ("\n", FILE); }/* MVS externals are limited to 8 characters, upper case only. The '_' is mapped to '@', except for MVS functions, then '#'. */#define MAX_MVS_LABEL_SIZE 8#define ASM_OUTPUT_LABELREF(FILE, NAME) \{ \ char *bp, ch, temp[MAX_MVS_LABEL_SIZE + 1]; \ if (strlen (NAME) > MAX_MVS_LABEL_SIZE) \ { \ strncpy (temp, NAME, MAX_MVS_LABEL_SIZE); \ temp[MAX_MVS_LABEL_SIZE] = '\0'; \ } \ else \ strcpy (temp,NAME); \ if (!strcmp (temp,"main")) \ strcpy (temp,"gccmain"); \ if (mvs_function_check (temp)) \ ch = '#'; \ else \ ch = '@'; \ for (bp = temp; *bp; bp++) \ { \ if (islower (*bp)) *bp = toupper (*bp); \ if (*bp == '_') *bp = ch; \ } \ fprintf (FILE, "%s", temp); \}#define ASM_GENERATE_INTERNAL_LABEL(LABEL, PREFIX, NUM) \ sprintf (LABEL, "*%s%d", PREFIX, NUM)/* Generate internal label. Since we can branch here from off page, we must reload the base register. */#define ASM_OUTPUT_INTERNAL_LABEL(FILE, PREFIX, NUM) \{ \ if (!strcmp (PREFIX,"L")) \ { \ mvs_add_label(NUM); \ mvs_label_emitted = 1; \ } \ fprintf (FILE, "%s%d\tEQU\t*\n", PREFIX, NUM); \}/* Generate case label. */#define ASM_OUTPUT_CASE_LABEL(FILE, PREFIX, NUM, TABLE) \ fprintf (FILE, "%s%d\tEQU\t*\n", PREFIX, NUM)/* This is how to output an element of a case-vector that is absolute. */#define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \ mvs_check_page (FILE, 4, 0); \ fprintf (FILE, "\tDC\tA(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, BODY, VALUE, REL) \ mvs_check_page (FILE, 4, 0); \ fprintf (FILE, "\tDC\tA(L%d-L%d)\n", VALUE, REL)/* This is how to output an insn to push a register on the stack. It need not be very fast code. */#define ASM_OUTPUT_REG_PUSH(FILE, REGNO) \ mvs_check_page (FILE, 8, 4); \ fprintf (FILE, "\tS\t13,=F'4'\n\tST\t%s,%d(13)\n", \ reg_names[REGNO], STACK_POINTER_OFFSET)/* This is how to output an insn to pop a register from the stack. It need not be very fast code. */#define ASM_OUTPUT_REG_POP(FILE, REGNO) \ mvs_check_page (FILE, 8, 0); \ fprintf (FILE, "\tL\t%s,%d(13)\n\tLA\t13,4(13)\n", \ reg_names[REGNO], STACK_POINTER_OFFSET)/* This is how to output an assembler line defining a `double' constant. */#define ASM_OUTPUT_DOUBLE(FILE, VALUE) \ fprintf (FILE, "\tDC\tD'%.18G'\n", (VALUE))/* This is how to output an assembler line defining a `float' constant. */#define ASM_OUTPUT_FLOAT(FILE, VALUE) \ fprintf (FILE, "\tDC\tE'%.9G'\n", (VALUE))/* This outputs an integer, if not a CONST_INT must be address constant. */#define ASM_OUTPUT_INT(FILE, EXP) \{ \ if (GET_CODE (EXP) == CONST_INT) \ { \ fprintf (FILE, "\tDC\tF'"); \ output_addr_const (FILE, EXP); \ fprintf (FILE, "'\n"); \ } \ else \ { \ fprintf (FILE, "\tDC\tA("); \ output_addr_const (FILE, EXP); \ fprintf (FILE, ")\n"); \ } \}/* This outputs a short integer. */#define ASM_OUTPUT_SHORT(FILE, EXP) \{ \ fprintf (FILE, "\tDC\tX'%04X'\n", INTVAL(EXP) & 0xFFFF); \
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -