📄 vax.h
字号:
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) 1/* When a prototype says `char' or `short', really pass an `int'. (On the VAX, this is required for system-library compatibility.) */#define PROMOTE_PROTOTYPES 1/* 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/* This machine doesn't use IEEE floats. */#define TARGET_FLOAT_FORMAT VAX_FLOAT_FORMAT/* 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. *//* On a VAX, constants from 0..63 are cheap because they can use the 1 byte literal constant format. compare to -1 should be made cheap so that decrement-and-branch insns can be formed more easily (if the value -1 is copied to a register some decrement-and-branch patterns will not match). */#define CONST_COSTS(RTX,CODE,OUTER_CODE) \ case CONST_INT: \ if (INTVAL (RTX) == 0) return 0; \ if ((OUTER_CODE) == AND) \ return ((unsigned) ~INTVAL (RTX) <= 077) ? 1 : 2; \ if ((unsigned) INTVAL (RTX) <= 077) return 1; \ if ((OUTER_CODE) == COMPARE && INTVAL (RTX) == -1) \ return 1; \ if ((OUTER_CODE) == PLUS && (unsigned) -INTVAL (RTX) <= 077)\ return 1; \ case CONST: \ case LABEL_REF: \ case SYMBOL_REF: \ return 3; \ case CONST_DOUBLE: \ if (GET_MODE_CLASS (GET_MODE (RTX)) == MODE_FLOAT) \ return vax_float_literal (RTX) ? 5 : 8; \ else \ return (((CONST_DOUBLE_HIGH (RTX) == 0 \ && (unsigned) CONST_DOUBLE_LOW (RTX) < 64) \ || ((OUTER_CODE) == PLUS \ && CONST_DOUBLE_HIGH (RTX) == -1 \ && (unsigned)-CONST_DOUBLE_LOW (RTX) < 64)) \ ? 2 : 5);#define RTX_COSTS(RTX,CODE,OUTER_CODE) case FIX: case FLOAT: \ case MULT: case DIV: case UDIV: case MOD: case UMOD: \ case ASHIFT: case LSHIFTRT: case ASHIFTRT: \ case ROTATE: case ROTATERT: case PLUS: case MINUS: case IOR: \ case XOR: case AND: case NEG: case NOT: case ZERO_EXTRACT: \ case SIGN_EXTRACT: case MEM: return vax_rtx_cost(RTX)#define ADDRESS_COST(RTX) (1 + (GET_CODE (RTX) == REG ? 0 : vax_address_cost(RTX)))/* Specify the cost of a branch insn; roughly the number of extra insns that should be added to avoid a branch. Branches are extremely cheap on the VAX while the shift insns often used to replace branches can be expensive. */#define BRANCH_COST 0/* * We can use the BSD C library routines for the libgcc calls that are * still generated, since that's what they boil down to anyways. */#define UDIVSI3_LIBCALL "*udiv"#define UMODSI3_LIBCALL "*urem"/* Tell final.c how to eliminate redundant test instructions. *//* Here we define machine-dependent flags and fields in cc_status (see `conditions.h'). No extra ones are needed for the VAX. *//* 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. */#define NOTICE_UPDATE_CC(EXP, INSN) \{ if (GET_CODE (EXP) == SET) \ { if (GET_CODE (SET_SRC (EXP)) == CALL) \ CC_STATUS_INIT; \ else if (GET_CODE (SET_DEST (EXP)) != ZERO_EXTRACT \ && GET_CODE (SET_DEST (EXP)) != PC) \ { \ cc_status.flags = 0; \ /* The integer operations below don't set carry or \ set it in an incompatible way. That's ok though \ as the Z bit is all we need when doing unsigned \ comparisons on the result of these insns (since \ they're always with 0). Set CC_NO_OVERFLOW to \ generate the correct unsigned branches. */ \ switch (GET_CODE (SET_SRC (EXP))) \ { \ case NEG: \ if (GET_MODE_CLASS (GET_MODE (EXP)) == MODE_FLOAT)\ break; \ case AND: \ case IOR: \ case XOR: \ case NOT: \ case MEM: \ case REG: \ cc_status.flags = CC_NO_OVERFLOW; \ break; \ default: \ break; \ } \ 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) \ { \ if (GET_CODE (SET_SRC (XVECEXP (EXP, 0, 0))) == CALL) \ CC_STATUS_INIT; \ else if (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)); } \ else \ /* PARALLELs whose first element sets the PC are aob, \ sob insns. They do change the cc's. */ \ CC_STATUS_INIT; } \ 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. */#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. *//* Output at beginning of assembler file. *//* When debugging, we want to output an extra dummy label so that gas can distinguish between D_float and G_float prior to processing the .stabs directive identifying type double. */#define ASM_FILE_START(FILE) \ do { \ fputs (ASM_APP_OFF, FILE); \ if (write_symbols == DBX_DEBUG) \ fprintf (FILE, "___vax_%c_doubles:\n", ASM_DOUBLE_CHAR); \ } while (0)/* Output to assembler file text saying following lines may contain character constants, extra white space, comments, etc. */#define ASM_APP_ON "#APP\n"/* Output to assembler file text saying following lines no longer contain unusual constructs. */#define ASM_APP_OFF "#NO_APP\n"/* Output before read-only data. */#define TEXT_SECTION_ASM_OP "\t.text"/* Output before writable data. */#define DATA_SECTION_ASM_OP "\t.data"/* How to refer to registers in assembler output. This sequence is indexed by compiler's hard-register-number (see above). The register names will be prefixed by REGISTER_PREFIX, if any. */#define REGISTER_PREFIX ""#define REGISTER_NAMES \{"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", \ "r9", "r10", "r11", "ap", "fp", "sp", "pc"}/* This is BSD, so it wants DBX format. */#define DBX_DEBUGGING_INFO 1/* Do not break .stabs pseudos into continuations. */#define DBX_CONTIN_LENGTH 0/* This is the char to use for continuation (in case we need to turn continuation back on). */#define DBX_CONTIN_CHAR '?'/* Don't use the `xsfoo;' construct in DBX output; this system doesn't support it. */#define DBX_NO_XREFS/* Output the .stabs for a C `static' variable in the data section. */#define DBX_STATIC_STAB_DATA_SECTION/* VAX specific: which type character is used for type double? */#define ASM_DOUBLE_CHAR (TARGET_G_FLOAT ? 'g' : 'd')/* This is how to output a command to make the user-level label named NAME defined for reference from other files. *//* Globalizing directive for a label. */#define GLOBAL_ASM_OP ".globl "/* The prefix to add to user-visible assembler symbols. */#define USER_LABEL_PREFIX "_"/* This is how to output an internal numbered label where PREFIX is the class of label and NUM is the number within the class. */#define ASM_OUTPUT_INTERNAL_LABEL(FILE,PREFIX,NUM) \ fprintf (FILE, "%s%d:\n", PREFIX, NUM)/* This is how to store into the string LABEL the symbol_ref name of an internal numbered label where PREFIX is the class of label and NUM is the number within the class. This is suitable for output with `assemble_name'. */#define ASM_GENERATE_INTERNAL_LABEL(LABEL,PREFIX,NUM) \ sprintf (LABEL, "*%s%d", PREFIX, NUM)/* 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) \ fprintf (FILE, "\tpushl %s\n", reg_names[REGNO])/* 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) \ fprintf (FILE, "\tmovl (%s)+,%s\n", reg_names[STACK_POINTER_REGNUM], \ reg_names[REGNO])/* This is how to output an element of a case-vector that is absolute. (The VAX does not use such vectors, but we must define this macro anyway.) */#define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \ do \ { \ char label[256]; \ ASM_GENERATE_INTERNAL_LABEL (label, "L", (VALUE));\ fprintf (FILE, "\t.long "); \ assemble_name (FILE, label); \ fprintf (FILE, "\n"); \ } \ while (0)/* This is how to output an element of a case-vector that is relative. */#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) \ do \ { \ char label[256]; \ ASM_GENERATE_INTERNAL_LABEL (label, "L", (VALUE)); \ fprintf (FILE, "\t.word "); \ assemble_name (FILE, label); \ ASM_GENERATE_INTERNAL_LABEL (label, "L", (REL)); \ fprintf (FILE, "-"); \ assemble_name (FILE, label); \ fprintf (FILE, "\n"); \ } \ while (0)/* This is how to output an assembler line that says to advance the location counter to a multiple of 2**LOG bytes. */#define ASM_OUTPUT_ALIGN(FILE,LOG) \ fprintf (FILE, "\t.align %d\n", (LOG))/* This is how to output an assembler line that says to advance the location counter by SIZE bytes. */#define ASM_OUTPUT_SKIP(FILE,SIZE) \ fprintf (FILE, "\t.space %u\n", (SIZE))/* This says how to output an assembler line to define a global common symbol. */#define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED) \( fputs (".comm ", (FILE)), \ assemble_name ((FILE), (NAME)), \ fprintf ((FILE), ",%u\n", (ROUNDED)))/* This says how to output an assembler line to define a local common symbol. */#define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE, ROUNDED) \( fputs (".lcomm ", (FILE)), \ assemble_name ((FILE), (NAME)), \ fprintf ((FILE), ",%u\n", (ROUNDED)))/* Store in OUTPUT a string (made with alloca) containing an assembler-name for a local static variable named NAME. LABELNO is an integer which is different for each call. */#define ASM_FORMAT_PRIVATE_NAME(OUTPUT, NAME, LABELNO) \( (OUTPUT) = (char *) alloca (strlen ((NAME)) + 10), \ sprintf ((OUTPUT), "%s.%d", (NAME), (LABELNO)))/* 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'.VAX operand formatting codes: letter print C reverse branch condition D 64-bit immediate operand B the low 8 bits of the complement of a constant operand H the low 16 bits of the complement of a constant operand M a mask for the N highest bits of a word N the complement of a constant integer operand P constant operand plus 1 R 32 - constant operand b the low 8 bits of a negated constant operand h the low 16 bits of a negated constant operand # 'd' or 'g' depending on whether dfloat or gfloat is used | register prefix *//* The purpose of D is to get around a quirk or bug in VAX assembler whereby -1 in a 64-bit immediate operand means 0x00000000ffffffff, which is not a 64-bit minus one. */#define PRINT_OPERAND_PUNCT_VALID_P(CODE) \ ((CODE) == '#' || (CODE) == '|')#define PRINT_OPERAND(FILE, X, CODE) \{ if (CODE == '#') fputc (ASM_DOUBLE_CHAR, FILE); \ else if (CODE == '|') \ fputs (REGISTER_PREFIX, FILE); \ else if (CODE == 'C') \ fputs (rev_cond_name (X), FILE); \ else if (CODE == 'D' && GET_CODE (X) == CONST_INT && INTVAL (X) < 0) \ fprintf (FILE, "$0xffffffff%08x", INTVAL (X)); \ else if (CODE == 'P' && GET_CODE (X) == CONST_INT) \ fprintf (FILE, "$%d", INTVAL (X) + 1); \ else if (CODE == 'N' && GET_CODE (X) == CONST_INT) \ fprintf (FILE, "$%d", ~ INTVAL (X)); \ /* rotl instruction cannot deal with negative arguments. */ \ else if (CODE == 'R' && GET_CODE (X) == CONST_INT) \ fprintf (FILE, "$%d", 32 - INTVAL (X)); \ else if (CODE == 'H' && GET_CODE (X) == CONST_INT) \ fprintf (FILE, "$%d", 0xffff & ~ INTVAL (X)); \ else if (CODE == 'h' && GET_CODE (X) == CONST_INT) \ fprintf (FILE, "$%d", (short) - INTVAL (x)); \ else if (CODE == 'B' && GET_CODE (X) == CONST_INT) \ fprintf (FILE, "$%d", 0xff & ~ INTVAL (X)); \ else if (CODE == 'b' && GET_CODE (X) == CONST_INT) \ fprintf (FILE, "$%d", 0xff & - INTVAL (X)); \ else if (CODE == 'M' && GET_CODE (X) == CONST_INT) \ fprintf (FILE, "$%d", ~((1 << INTVAL (x)) - 1)); \ 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 if (GET_CODE (X) == CONST_DOUBLE && GET_MODE (X) == SFmode) \ { char dstr[30]; \ real_to_decimal (dstr, CONST_DOUBLE_REAL_VALUE (X), \ sizeof (dstr), 0, 1); \ fprintf (FILE, "$0f%s", dstr); } \ else if (GET_CODE (X) == CONST_DOUBLE && GET_MODE (X) == DFmode) \ { char dstr[30]; \ real_to_decimal (dstr, CONST_DOUBLE_REAL_VALUE (X), \ sizeof (dstr), 0, 1); \ fprintf (FILE, "$0%c%s", ASM_DOUBLE_CHAR, dstr); } \ else { putc ('$', FILE); output_addr_const (FILE, X); }}/* Print a memory operand whose address is X, on file FILE. This uses a function in output-vax.c. */#define PRINT_OPERAND_ADDRESS(FILE, ADDR) \ print_operand_address (FILE, ADDR)/* This is a blatent lie. However, it's good enough, since we don't actually have any code whatsoever for which this isn't overridden by the proper FDE definition. */#define INCOMING_RETURN_ADDR_RTX gen_rtx_REG (Pmode, PC_REGNUM)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -