📄 m68k.c
字号:
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 cc register (used in an `and to cc' insn). '$' 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. '/' for register prefix needed by longlong.h. '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. */voidprint_operand (file, op, letter) FILE *file; /* file to write to */ rtx op; /* operand to print */ int letter; /* %<letter> or 0 */{ int i; if (letter == '.') {#ifdef MOTOROLA asm_fprintf (file, ".");#endif } else if (letter == '#') { asm_fprintf (file, "%0I"); } else if (letter == '-') {#ifdef MOTOROLA asm_fprintf (file, "-(%Rsp)");#else asm_fprintf (file, "%Rsp@-");#endif } else if (letter == '+') {#ifdef MOTOROLA asm_fprintf (file, "(%Rsp)+");#else asm_fprintf (file, "%Rsp@+");#endif } else if (letter == '@') {#ifdef MOTOROLA asm_fprintf (file, "(%Rsp)");#else asm_fprintf (file, "%Rsp@");#endif } else if (letter == '!') { asm_fprintf (file, "%Rfpcr"); } else if (letter == '$') { if (TARGET_68040_ONLY) { fprintf (file, "s"); } } else if (letter == '&') { if (TARGET_68040_ONLY) { fprintf (file, "d"); } } else if (letter == '/') { asm_fprintf (file, "%R"); } else if (GET_CODE (op) == REG) { if (REGNO (op) < 16 && (letter == 'y' || letter == 'x') && GET_MODE (op) == DFmode) { fprintf (file, "%s:%s", reg_names[REGNO (op)], reg_names[REGNO (op)+1]); } else { fprintf (file, "%s", reg_names[REGNO (op)]); } } else if (GET_CODE (op) == MEM) { output_address (XEXP (op, 0)); if (letter == 'd' && ! TARGET_68020 && CONSTANT_ADDRESS_P (XEXP (op, 0)) && !(GET_CODE (XEXP (op, 0)) == CONST_INT && INTVAL (XEXP (op, 0)) < 0x8000 && INTVAL (XEXP (op, 0)) >= -0x8000)) { fprintf (file, ":l"); } }#ifdef SUPPORT_SUN_FPA else if ((letter == 'y' || letter == 'w') && GET_CODE (op) == CONST_DOUBLE && (i = standard_sun_fpa_constant_p (op))) { fprintf (file, "%%%d", i & 0x1ff); }#endif else if (GET_CODE (op) == CONST_DOUBLE && GET_MODE (op) == SFmode) { double d; union { float f; int i; } u1; REAL_VALUE_FROM_CONST_DOUBLE (d, op); u1.f = d; PRINT_OPERAND_PRINT_FLOAT (letter, file); } else if (GET_CODE (op) == CONST_DOUBLE && GET_MODE (op) != DImode) { double d; REAL_VALUE_FROM_CONST_DOUBLE (d, op); ASM_OUTPUT_DOUBLE_OPERAND (file, d); } else { asm_fprintf (file, "%0I"); output_addr_const (file, op); }}/* A C compound statement to output to stdio stream STREAM the assembler syntax for an instruction operand that is a memory reference whose address is ADDR. ADDR is an RTL expression. Note that this contains a kludge that knows that the only reason we have an address (plus (label_ref...) (reg...)) when not generating PIC code is in the insn before a tablejump, and we know that m68k.md generates a label LInnn: on such an insn. It is possible for PIC to generate a (plus (label_ref...) (reg...)) and we handle that just like we would a (plus (symbol_ref...) (reg...)). Some SGS assemblers have a bug such that "Lnnn-LInnn-2.b(pc,d0.l*2)" fails to assemble. Luckily "Lnnn(pc,d0.l*2)" produces the results we want. This difference can be accommodated by using an assembler define such "LDnnn" to be either "Lnnn-LInnn-2.b", "Lnnn", or any other string, as necessary. This is accomplished via the ASM_OUTPUT_CASE_END macro. See m68ksgs.h for an example; for versions without the bug. They also do not like things like "pea 1.w", so we simple leave off the .w on small constants. This routine is responsible for distinguishing between -fpic and -fPIC style relocations in an address. When generating -fpic code the offset is output in word mode (eg movel a5@(_foo:w), a0). When generating -fPIC code the offset is output in long mode (eg movel a5@(_foo:l), a0) */voidprint_operand_address (file, addr) FILE *file; rtx addr;{ register rtx reg1, reg2, breg, ireg; rtx offset; switch (GET_CODE (addr)) { case REG:#ifdef MOTOROLA fprintf (file, "(%s)", reg_names[REGNO (addr)]);#else fprintf (file, "%s@", reg_names[REGNO (addr)]);#endif break; case PRE_DEC:#ifdef MOTOROLA fprintf (file, "-(%s)", reg_names[REGNO (XEXP (addr, 0))]);#else fprintf (file, "%s@-", reg_names[REGNO (XEXP (addr, 0))]);#endif break; case POST_INC:#ifdef MOTOROLA fprintf (file, "(%s)+", reg_names[REGNO (XEXP (addr, 0))]);#else fprintf (file, "%s@+", reg_names[REGNO (XEXP (addr, 0))]);#endif break; case PLUS: reg1 = reg2 = ireg = breg = 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; }#if 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); } }#endif 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 && ! (flag_pic && ireg == pic_offset_table_rtx)) { int scale = 1; if (GET_CODE (ireg) == MULT) { scale = INTVAL (XEXP (ireg, 1)); ireg = XEXP (ireg, 0); } if (GET_CODE (ireg) == SIGN_EXTEND) {#ifdef MOTOROLA#ifdef SGS asm_fprintf (file, "%LLD%d(%Rpc,%s.w", CODE_LABEL_NUMBER (XEXP (addr, 0)), reg_names[REGNO (XEXP (ireg, 0))]);#else asm_fprintf (file, "%LL%d-%LLI%d.b(%Rpc,%s.w", CODE_LABEL_NUMBER (XEXP (addr, 0)), CODE_LABEL_NUMBER (XEXP (addr, 0)), reg_names[REGNO (XEXP (ireg, 0))]);#endif#else asm_fprintf (file, "%Rpc@(%LL%d-%LLI%d-2:b,%s:w", CODE_LABEL_NUMBER (XEXP (addr, 0)), CODE_LABEL_NUMBER (XEXP (addr, 0)), reg_names[REGNO (XEXP (ireg, 0))]);#endif } else {#ifdef MOTOROLA#ifdef SGS asm_fprintf (file, "%LLD%d(%Rpc,%s.l", CODE_LABEL_NUMBER (XEXP (addr, 0)), reg_names[REGNO (ireg)]);#else asm_fprintf (file, "%LL%d-%LLI%d.b(%Rpc,%s.l", CODE_LABEL_NUMBER (XEXP (addr, 0)), CODE_LABEL_NUMBER (XEXP (addr, 0)), reg_names[REGNO (ireg)]);#endif#else asm_fprintf (file, "%Rpc@(%LL%d-%LLI%d-2:b,%s:l", CODE_LABEL_NUMBER (XEXP (addr, 0)), CODE_LABEL_NUMBER (XEXP (addr, 0)), reg_names[REGNO (ireg)]);#endif } if (scale != 1) {#ifdef MOTOROLA fprintf (file, "*%d", scale);#else fprintf (file, ":%d", scale);#endif } putc (')', file); break; } if (breg != 0 && ireg == 0 && GET_CODE (addr) == LABEL_REF && ! (flag_pic && breg == pic_offset_table_rtx)) {#ifdef MOTOROLA#ifdef SGS asm_fprintf (file, "%LLD%d(%Rpc,%s.l", CODE_LABEL_NUMBER (XEXP (addr, 0)), reg_names[REGNO (breg)]);#else asm_fprintf (file, "%LL%d-%LLI%d.b(%Rpc,%s.l", CODE_LABEL_NUMBER (XEXP (addr, 0)), CODE_LABEL_NUMBER (XEXP (addr, 0)), reg_names[REGNO (breg)]);#endif#else asm_fprintf (file, "%Rpc@(%LL%d-%LLI%d-2:b,%s:l", CODE_LABEL_NUMBER (XEXP (addr, 0)), CODE_LABEL_NUMBER (XEXP (addr, 0)), reg_names[REGNO (breg)]);#endif putc (')', file); break; } if (ireg != 0 || breg != 0) { int scale = 1; if (breg == 0) { abort (); } if (! flag_pic && addr && GET_CODE (addr) == LABEL_REF) { abort (); }#ifdef MOTOROLA if (addr != 0) { output_addr_const (file, addr); if ((flag_pic == 1) && (breg == pic_offset_table_rtx)) fprintf (file, ".w"); if ((flag_pic == 2) && (breg == pic_offset_table_rtx)) fprintf (file, ".l"); } fprintf (file, "(%s", reg_names[REGNO (breg)]); if (ireg != 0) { putc (',', file); }#else fprintf (file, "%s@(", reg_names[REGNO (breg)]); if (addr != 0) { output_addr_const (file, addr); if ((flag_pic == 1) && (breg == pic_offset_table_rtx)) fprintf (file, ":w"); if ((flag_pic == 2) && (breg == pic_offset_table_rtx)) fprintf (file, ":l"); } if (addr != 0 && ireg != 0) { putc (',', file); }#endif if (ireg != 0 && GET_CODE (ireg) == MULT) { scale = INTVAL (XEXP (ireg, 1)); ireg = XEXP (ireg, 0); } if (ireg != 0 && GET_CODE (ireg) == SIGN_EXTEND) {#ifdef MOTOROLA fprintf (file, "%s.w", reg_names[REGNO (XEXP (ireg, 0))]);#else fprintf (file, "%s:w", reg_names[REGNO (XEXP (ireg, 0))]);#endif } else if (ireg != 0) {#ifdef MOTOROLA fprintf (file, "%s.l", reg_names[REGNO (ireg)]);#else fprintf (file, "%s:l", reg_names[REGNO (ireg)]);#endif } if (scale != 1) {#ifdef MOTOROLA fprintf (file, "*%d", scale);#else fprintf (file, ":%d", scale);#endif } putc (')', file); break; } else if (reg1 != 0 && GET_CODE (addr) == LABEL_REF && ! (flag_pic && reg1 == pic_offset_table_rtx)) {#ifdef MOTOROLA#ifdef SGS asm_fprintf (file, "%LLD%d(%Rpc,%s.l)", CODE_LABEL_NUMBER (XEXP (addr, 0)), reg_names[REGNO (reg1)]);#else asm_fprintf (file, "%LL%d-%LLI%d.b(%Rpc,%s.l)", CODE_LABEL_NUMBER (XEXP (addr, 0)), CODE_LABEL_NUMBER (XEXP (addr, 0)), reg_names[REGNO (reg1)]);#endif#else asm_fprintf (file, "%Rpc@(%LL%d-%LLI%d-2:b,%s:l)", CODE_LABEL_NUMBER (XEXP (addr, 0)), CODE_LABEL_NUMBER (XEXP (addr, 0)), reg_names[REGNO (reg1)]);#endif break; } /* FALL-THROUGH (is this really what we want? */ default: if (GET_CODE (addr) == CONST_INT && INTVAL (addr) < 0x8000 && INTVAL (addr) >= -0x8000) {#ifdef MOTOROLA#ifdef SGS /* Many SGS assemblers croak on size specifiers for constants. */ fprintf (file, "%d", INTVAL (addr));#else fprintf (file, "%d.w", INTVAL (addr));#endif#else fprintf (file, "%d:w", INTVAL (addr));#endif } else { output_addr_const (file, addr); } break; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -