📄 mot3300.h
字号:
For `%' followed by punctuation, CODE is the punctuation and X is null. On the 68000, we use several CODE characters: '.' for dot needed in Motorola-style opcode names. '-' for an operand pushing on the stack: sp@-, -(sp) or -(%sp) depending on the style of syntax. '+' for an operand pushing on the stack: sp@+, (sp)+ or (%sp)+ depending on the style of syntax. '@' for a reference to the top word on the stack: sp@, (sp) or (%sp) depending on the style of syntax. '#' for an immediate operand prefix (# in MIT and Motorola syntax but & in SGS syntax). '!' for the fpcr register (used in some float-to-fixed conversions). '$' for the letter `s' in an op code, but only on the 68040. '&' for the letter `d' in an op code, but only on the 68040. 'b' for byte insn (no effect, on the Sun; this is for the ISI). 'd' to force memory addressing to be absolute, not relative. 'f' for float insn (print a CONST_DOUBLE as a float rather than in hex) 'w' for FPA insn (print a CONST_DOUBLE as a SunFPA constant rather than directly). Second part of 'y' below. 'x' for float insn (print a CONST_DOUBLE as a float rather than in hex), or print pair of registers as rx:ry. 'y' for a FPA insn (print pair of registers as rx:ry). This also outputs CONST_DOUBLE's as SunFPA constant RAM registers if possible, so it should not be used except for the SunFPA. */#undef PRINT_OPERAND#define PRINT_OPERAND(FILE, X, CODE) \{ if (CODE == '.') fprintf (FILE, "."); \ else if (CODE == '#') fprintf (FILE, "&"); \ else if (CODE == '-') fprintf (FILE, "-(%%sp)"); \ else if (CODE == '+') fprintf (FILE, "(%%sp)+"); \ else if (CODE == '@') fprintf (FILE, "(%%sp)"); \ else if (CODE == '!') fprintf (FILE, "%%fpcr"); \ else if (CODE == '$') { if (TARGET_68040_ONLY) fprintf (FILE, "s"); } \ else if (CODE == '&') { if (TARGET_68040_ONLY) fprintf (FILE, "d"); } \ 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) \ { union { double d; int i[2]; } u; \ union { float f; int i; } u1; \ u.i[0] = CONST_DOUBLE_LOW (X); u.i[1] = CONST_DOUBLE_HIGH (X); \ u1.f = u.d; \ /* Use hex representation even if CODE is f. as needs it. */ \ if (CODE == 'f') \ fprintf (FILE, "&0x%x", u1.i); \ else \ fprintf (FILE, "&0x%x", u1.i); } \ else if (GET_CODE (X) == CONST_DOUBLE && GET_MODE (X) == DFmode) \ { union { double d; int i[2]; } u; \ PRINT_OPERAND_EXTRACT_FLOAT (X); \ fprintf (FILE, "&0x%08x%08x", u.i[0], u.i[1]); } \ else { putc ('&', FILE); output_addr_const (FILE, X); }}#undef PRINT_OPERAND_ADDRESS#define PRINT_OPERAND_ADDRESS(FILE, ADDR) \{ register rtx reg1, reg2, breg, ireg; \ register rtx addr = ADDR; \ rtx offset; \ switch (GET_CODE (addr)) \ { \ case REG: \ fprintf (FILE, "(%s)", reg_names[REGNO (addr)]); \ break; \ case PRE_DEC: \ fprintf (FILE, "-(%s)", reg_names[REGNO (XEXP (addr, 0))]); \ break; \ case POST_INC: \ fprintf (FILE, "(%s)+", reg_names[REGNO (XEXP (addr, 0))]); \ break; \ case PLUS: \ reg1 = 0; reg2 = 0; \ ireg = 0; breg = 0; \ offset = 0; \ if (CONSTANT_ADDRESS_P (XEXP (addr, 0))) \ { \ offset = XEXP (addr, 0); \ addr = XEXP (addr, 1); \ } \ else if (CONSTANT_ADDRESS_P (XEXP (addr, 1))) \ { \ offset = XEXP (addr, 1); \ addr = XEXP (addr, 0); \ } \ if (GET_CODE (addr) != PLUS) ; \ else if (GET_CODE (XEXP (addr, 0)) == SIGN_EXTEND) \ { \ reg1 = XEXP (addr, 0); \ addr = XEXP (addr, 1); \ } \ else if (GET_CODE (XEXP (addr, 1)) == SIGN_EXTEND) \ { \ reg1 = XEXP (addr, 1); \ addr = XEXP (addr, 0); \ } \ else if (GET_CODE (XEXP (addr, 0)) == MULT) \ { \ reg1 = XEXP (addr, 0); \ addr = XEXP (addr, 1); \ } \ else if (GET_CODE (XEXP (addr, 1)) == MULT) \ { \ reg1 = XEXP (addr, 1); \ addr = XEXP (addr, 0); \ } \ else if (GET_CODE (XEXP (addr, 0)) == REG) \ { \ reg1 = XEXP (addr, 0); \ addr = XEXP (addr, 1); \ } \ else if (GET_CODE (XEXP (addr, 1)) == REG) \ { \ reg1 = XEXP (addr, 1); \ addr = XEXP (addr, 0); \ } \ if (GET_CODE (addr) == REG || GET_CODE (addr) == MULT \ || GET_CODE (addr) == SIGN_EXTEND) \ { if (reg1 == 0) reg1 = addr; else reg2 = addr; addr = 0; } \/* for OLD_INDEXING \ else if (GET_CODE (addr) == PLUS) \ { \ if (GET_CODE (XEXP (addr, 0)) == REG) \ { \ reg2 = XEXP (addr, 0); \ addr = XEXP (addr, 1); \ } \ else if (GET_CODE (XEXP (addr, 1)) == REG) \ { \ reg2 = XEXP (addr, 1); \ addr = XEXP (addr, 0); \ } \ } \ */ \ if (offset != 0) { if (addr != 0) abort (); addr = offset; } \ if ((reg1 && (GET_CODE (reg1) == SIGN_EXTEND \ || GET_CODE (reg1) == MULT)) \ || (reg2 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg2)))) \ { breg = reg2; ireg = reg1; } \ else if (reg1 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg1))) \ { breg = reg1; ireg = reg2; } \ if (ireg != 0 && breg == 0 && GET_CODE (addr) == LABEL_REF) \ { int scale = 1; \ if (GET_CODE (ireg) == MULT) \ { scale = INTVAL (XEXP (ireg, 1)); \ ireg = XEXP (ireg, 0); } \ if (GET_CODE (ireg) == SIGN_EXTEND) \ fprintf (FILE, "12(%%pc,%s.w", \ reg_names[REGNO (XEXP (ireg, 0))]); \ else \ fprintf (FILE, "12(%%pc,%s.l", \ reg_names[REGNO (ireg)]); \ if (scale != 1) fprintf (FILE, "*%d", scale); \ fprintf (FILE, ")"); \ break; } \ if (breg != 0 && ireg == 0 && GET_CODE (addr) == LABEL_REF) \ { fprintf (FILE, "12(%%pc,%s.l", \ reg_names[REGNO (breg)]); \ putc (')', FILE); \ break; } \ if (ireg != 0 || breg != 0) \ { int scale = 1; \ if (breg == 0) \ abort (); \ if (addr != 0) \ output_addr_const (FILE, addr); \ fprintf (FILE, "(%s", reg_names[REGNO (breg)]); \ if (ireg != 0) \ putc (',', FILE); \ if (ireg != 0 && GET_CODE (ireg) == MULT) \ { scale = INTVAL (XEXP (ireg, 1)); \ ireg = XEXP (ireg, 0); } \ if (ireg != 0 && GET_CODE (ireg) == SIGN_EXTEND) \ fprintf (FILE, "%s.w", reg_names[REGNO (XEXP (ireg, 0))]); \ else if (ireg != 0) \ fprintf (FILE, "%s.l", reg_names[REGNO (ireg)]); \ if (scale != 1) fprintf (FILE, "*%d", scale); \ putc (')', FILE); \ break; \ } \ else if (reg1 != 0 && GET_CODE (addr) == LABEL_REF) \ { fprintf (FILE, "12(%%pc,%s.w)", \ reg_names[REGNO (reg1)]); \ break; } \ default: \ if (GET_CODE (addr) == CONST_INT \ && INTVAL (addr) < 0x8000 \ && INTVAL (addr) >= -0x8000) \ fprintf (FILE, "%d", INTVAL (addr)); \ else \ output_addr_const (FILE, addr); \ }}/* 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'. */#undef ASM_GENERATE_INTERNAL_LABEL#define ASM_GENERATE_INTERNAL_LABEL(LABEL, PREFIX, NUM) \ sprintf ((LABEL), "%s%%%d", (PREFIX), (NUM))/* This is how to output an internal numbered label where PREFIX is the class of label and NUM is the number within the class. */#undef ASM_OUTPUT_INTERNAL_LABEL#define ASM_OUTPUT_INTERNAL_LABEL(FILE,PREFIX,NUM) \ fprintf (FILE, "%s%%%d:\n", PREFIX, NUM)/* This is how to output a reference to a user-level label named NAME. `assemble_name' uses this. */#undef ASM_OUTPUT_LABELREF#define ASM_OUTPUT_LABELREF(FILE,NAME) \ fprintf (FILE, "%s", NAME)/* This is how to output an element of a case-vector that is absolute. (The 68000 does not use such vectors, but we must define this macro anyway.) */#undef ASM_OUTPUT_ADDR_VEC_ELT#define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \ fprintf (FILE, "\tlong L%%%d\n", (VALUE))/* This is how to output an element of a case-vector that is relative. */#undef ASM_OUTPUT_ADDR_DIFF_ELT#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, VALUE, REL) \ fprintf (FILE, "\tshort L%%%d-L%%%d\n", (VALUE), (REL))#define ASM_OUTPUT_CASE_LABEL(FILE,PREFIX,NUM,TABLE) \ fprintf (FILE, "\tswbeg &%d\n%s%%%d:\n", \ XVECLEN (PATTERN (TABLE), 1), (PREFIX), (NUM)) #if 0/* At end of a switch table, define LD%n iff the symbol LI%n was defined. */#define ASM_OUTPUT_CASE_END(FILE,NUM,TABLE) \{ if (switch_table_difference_label_flag) \ asm_fprintf (FILE, "\t%s %LLD%d,%LL%d-%LLI%d-2.b\n",\ SET_ASM_OP, (NUM), (NUM), (NUM)) \ switch_table_difference_label_flag = 0; }#endif/* We have to define this to avoid errors. */int switch_table_difference_label_flag;/* Translate some opcodes to fit the sysV68 assembler syntax. *//* The opcodes fdmov and fsmov are guesses. */#define SWITCH_JUMP_MATCH "jmp 6(%%pc,"#undef ASM_OUTPUT_OPCODE#define ASM_OUTPUT_OPCODE(FILE, PTR) \{ if ((PTR)[0] == 'j' && (PTR)[1] == 'b') \ { ++(PTR); \ while (*(PTR) != ' ') \ { putc (*(PTR), (FILE)); ++(PTR); } \ fprintf ((FILE), ".w"); } \ else if ((PTR)[0] == 's') \ { \ if (!strncmp ((PTR), "swap", 4)) \ { fprintf ((FILE), "swap.w"); (PTR) += 4; } \ } \ else if ((PTR)[0] == 'f') \ { \ if (!strncmp ((PTR), "fmove", 5)) \ { fprintf ((FILE), "fmov"); (PTR) += 5; } \ else if (!strncmp ((PTR), "f%$move", 7)) \ { if (TARGET_68040_ONLY) \ { fprintf ((FILE), "fsmov"); (PTR) += 7; } \ else \ { fprintf ((FILE), "fmov"); (PTR) += 7; } } \ else if (!strncmp ((PTR), "f%&move", 7)) \ { if (TARGET_68040_ONLY) \ { fprintf ((FILE), "fdmov"); (PTR) += 7; } \ else \ { fprintf ((FILE), "fmov"); (PTR) += 7; } } \ else if (!strncmp ((PTR), "ftst", 4)) \ { fprintf ((FILE), "ftest"); (PTR) += 4; } \ else if (!strncmp ((PTR), "fbne", 4)) \ { fprintf ((FILE), "fbneq"); (PTR) += 4; } \ else if (!strncmp ((PTR), "fsne", 4)) \ { fprintf ((FILE), "fsneq"); (PTR) += 4; } \ } \/* MOVE, MOVEA, MOVEQ, MOVEC ==> MOV */ \ else if ((PTR)[0] == 'm' && (PTR)[1] == 'o' \ && (PTR)[2] == 'v' && (PTR)[3] == 'e') \ { fprintf ((FILE), "mov"); (PTR) += 4; \ if ((PTR)[0] == 'q' || (PTR)[0] == 'a' \ || (PTR)[0] == 'c') (PTR)++; } \/* SUB, SUBQ, SUBA, SUBI ==> SUB */ \ else if ((PTR)[0] == 's' && (PTR)[1] == 'u' \ && (PTR)[2] == 'b') \ { fprintf ((FILE), "sub"); (PTR) += 3; \ if ((PTR)[0] == 'q' || (PTR)[0] == 'i' \ || (PTR)[0] == 'a') (PTR)++; } \/* CMP, CMPA, CMPI, CMPM ==> CMP */ \ else if ((PTR)[0] == 'c' && (PTR)[1] == 'm' \ && (PTR)[2] == 'p') \ { fprintf ((FILE), "cmp"); (PTR) += 3; \ if ((PTR)[0] == 'a' || (PTR)[0] == 'i' \ || (PTR)[0] == 'm') (PTR)++; } \/* JMP to switch label */ \ else if (!strncmp((PTR), (SWITCH_JUMP_MATCH), sizeof(SWITCH_JUMP_MATCH) - 1)) \ { while (*(PTR)++ != '('); \ fprintf ((FILE), "jmp 8("); } \}/* This says how to output an assembler line to define a global common symbol. */#undef ASM_OUTPUT_COMMON#define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED) \( fputs ("\tcomm ", (FILE)), \ assemble_name ((FILE), (NAME)), \ fprintf ((FILE), ",%u\n", (ROUNDED)))/* This says how to output an assembler line to define a local common symbol. */#undef ASM_OUTPUT_LOCAL#define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE, ROUNDED) \( fputs ("\tlcomm ", (FILE)), \ assemble_name ((FILE), (NAME)), \ fprintf ((FILE), ",%u\n", (ROUNDED)))/* Override usual definitions of SDB output macros. These definitions differ only in the absence of the period at the beginning of the name of the directive and in the use of `~' as the symbol for the current location. */#define PUT_SDB_SCL(a) fprintf(asm_out_file, "\tscl\t%d;", (a))#define PUT_SDB_INT_VAL(a) fprintf (asm_out_file, "\tval\t%d;", (a))#define PUT_SDB_VAL(a) \( fputs ("\tval\t", asm_out_file), \ output_addr_const (asm_out_file, (a)), \ fputc (';', asm_out_file))#define PUT_SDB_DEF(a) \do { fprintf (asm_out_file, "\tdef\t"); \ ASM_OUTPUT_LABELREF (asm_out_file, a); \ fprintf (asm_out_file, ";"); } while (0)#define PUT_SDB_PLAIN_DEF(a) fprintf(asm_out_file,"\tdef\t~%s;",a)#define PUT_SDB_ENDEF fputs("\tendef\n", asm_out_file)#define PUT_SDB_TYPE(a) fprintf(asm_out_file, "\ttype\t0%o;", a)#define PUT_SDB_SIZE(a) fprintf(asm_out_file, "\tsize\t%d;", a)#define PUT_SDB_START_DIM fprintf(asm_out_file, "\tdim\t")#define PUT_SDB_NEXT_DIM(a) fprintf(asm_out_file, "%d,", a)#define PUT_SDB_LAST_DIM(a) fprintf(asm_out_file, "%d;", a)#define PUT_SDB_TAG(a) \do { fprintf (asm_out_file, "\ttag\t"); \ ASM_OUTPUT_LABELREF (asm_out_file, a); \ fprintf (asm_out_file, ";"); } while (0)#define PUT_SDB_BLOCK_START(LINE) \ fprintf (asm_out_file, \ "\tdef\t~bb;\tval\t~;\tscl\t100;\tline\t%d;\tendef\n", \ (LINE))#define PUT_SDB_BLOCK_END(LINE) \ fprintf (asm_out_file, \ "\tdef\t~eb;\tval\t~;\tscl\t100;\tline\t%d;\tendef\n", \ (LINE))#define PUT_SDB_FUNCTION_START(LINE) \ fprintf (asm_out_file, \ "\tdef\t~bf;\tval\t~;\tscl\t101;\tline\t%d;\tendef\n", \ (LINE))#define PUT_SDB_FUNCTION_END(LINE) \ fprintf (asm_out_file, \ "\tdef\t~ef;\tval\t~;\tscl\t101;\tline\t%d;\tendef\n", \ (LINE))#define PUT_SDB_EPILOGUE_END(NAME) \ fprintf (asm_out_file, \ "\tdef\t%s;\tval\t~;\tscl\t-1;\tendef\n", \ (NAME))#define SDB_GENERATE_FAKE(BUFFER, NUMBER) \ sprintf ((BUFFER), "~%dfake", (NUMBER));/* Define subroutines to call to handle multiply, divide, and remainder. Use the subroutines that the 3b1's library provides. The `*' prevents an underscore from being prepended by the compiler. */#define DIVSI3_LIBCALL "*ldiv"#define UDIVSI3_LIBCALL "*uldiv"#define MODSI3_LIBCALL "*lrem"#define UMODSI3_LIBCALL "*ulrem"#define MULSI3_LIBCALL "*lmul"#define UMULSI3_LIBCALL "*ulmul"
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -