?? out-i386.c
字號:
case 'R': fprintf (file, "%s", RP); return; case 'z': /* this is the size of op from size of operand */ switch (GET_MODE_SIZE (GET_MODE (x))) { case 2: PUT_OP_SIZE ('W', 'w', file); return; case 4: if (GET_MODE (x) == SFmode) { PUT_OP_SIZE ('S', 's', file); return; } else PUT_OP_SIZE ('L', 'l', file); return; case 8: if (!FP_REG_P (x)) PUT_OP_SIZE ('Q', 'l', file); return; case 1: PUT_OP_SIZE ('B', 'b', file); return; } } } if (GET_CODE (x) == REG) { PRINT_REG (x, code, file); } else if (GET_CODE (x) == MEM) { PRINT_PTR (x, file); if (CONSTANT_ADDRESS_P (XEXP (x, 0))) output_addr_const (file, XEXP (x, 0)); else 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; if (code == 'f') fprintf (file, "%.22e", u1.f); else { PRINT_IMMED_PREFIX (file); fprintf (file, "0x%x", u1.i); } } else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == DFmode) { union { double d; int i[2]; } u; u.i[0] = CONST_DOUBLE_LOW (x); u.i[1] = CONST_DOUBLE_HIGH (x); fprintf (file, "%.22e", u.d); } else { if (code != 'c') { if (GET_CODE (x) == CONST_INT) PRINT_IMMED_PREFIX (file); else if (GET_CODE (x) == CONST || GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == LABEL_REF) PRINT_OFFSET_PREFIX (file); } output_addr_const (file, x); }}/* Print a memory operand whose address is ADDR. */voidprint_operand_address (file, addr) FILE *file; register rtx addr;{ register rtx reg1, reg2, breg, ireg; rtx offset; switch (GET_CODE (addr)) { case REG: ADDR_BEG (file); fprintf (file, "%se", RP); fputs (hi_reg_name[REGNO (addr)], file); ADDR_END (file); 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)) == 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) { if (reg1 == 0) reg1 = addr; else reg2 = addr; addr = 0; } if (offset != 0) { if (addr != 0) abort (); addr = offset; } if ((reg1 && 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) { int scale = 1; if (addr != 0) { if (GET_CODE (addr) == LABEL_REF) output_asm_label (addr); else output_addr_const (file, addr); } if (ireg != 0 && GET_CODE (ireg) == MULT) { scale = INTVAL (XEXP (ireg, 1)); ireg = XEXP (ireg, 0); } /* output breg+ireg*scale */ PRINT_B_I_S (breg, ireg, scale, file); break; } case MULT: { int scale; if (GET_CODE (XEXP (addr, 0)) == CONST_INT) { scale = INTVAL (XEXP (addr, 0)); ireg = XEXP (addr, 1); } else { scale = INTVAL (XEXP (addr, 1)); ireg = XEXP (addr, 0); } output_addr_const (file, const0_rtx); PRINT_B_I_S ((rtx) 0, ireg, scale, file); } 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); }}/* Set the cc_status for the results of an insn whose pattern is EXP. On the 80386, we assume that only test and compare insns, as well as SI, HI, & DI mode ADD, SUB, NEG, AND, IOR, XOR, ASHIFT, LSHIFT, ASHIFTRT, and LSHIFTRT instructions set the condition codes usefully. Also, we assume that jumps and moves don't affect the condition codes. All else, clobbers the condition codes, by assumption. We assume that ALL add, minus, etc. instructions effect the condition codes. This MUST be consistent with i386.md. */notice_update_cc (exp) rtx exp;{ if (GET_CODE (exp) == SET) { /* Jumps do not alter the cc's. */ if (SET_DEST (exp) == pc_rtx) return; /* Moving register or memory into a register: it doesn't alter the cc's, but it might invalidate the RTX's which we remember the cc's came from. (Note that moving a constant 0 or 1 MAY set the cc's). */ if (REG_P (SET_DEST (exp)) && (REG_P (SET_SRC (exp)) || GET_CODE (SET_SRC (exp)) == MEM)) { if (cc_status.value1 && reg_overlap_mentioned_p (SET_DEST (exp), cc_status.value1)) cc_status.value1 = 0; if (cc_status.value2 && reg_overlap_mentioned_p (SET_DEST (exp), cc_status.value2)) cc_status.value2 = 0; return; } /* Moving register into memory doesn't alter the cc's. It may invalidate the RTX's which we remember the cc's came from. */ if (GET_CODE (SET_DEST (exp)) == MEM && REG_P (SET_SRC (exp))) { if (cc_status.value1 && GET_CODE (cc_status.value1) == MEM) cc_status.value1 = 0; if (cc_status.value2 && GET_CODE (cc_status.value2) == MEM) cc_status.value2 = 0; return; } /* Function calls clobber the cc's. */ else if (GET_CODE (SET_SRC (exp)) == CALL) { CC_STATUS_INIT; return; } /* Tests and compares set the cc's in predictable ways. */ else if (SET_DEST (exp) == cc0_rtx) { CC_STATUS_INIT; cc_status.value1 = SET_SRC (exp); return; } /* Certain instructions effect the condition codes. */ else if (GET_MODE (SET_SRC (exp)) == SImode || GET_MODE (SET_SRC (exp)) == HImode || GET_MODE (SET_SRC (exp)) == QImode) switch (GET_CODE (SET_SRC (exp))) { case ASHIFTRT: case LSHIFTRT: case ASHIFT: case LSHIFT: /* Shifts on the 386 don't set the condition codes if the shift count is zero. */ if (GET_CODE (XEXP (SET_SRC (exp), 1)) != CONST_INT) { CC_STATUS_INIT; break; } /* We assume that the CONST_INT is non-zero (this rtx would have been deleted if it were zero. */ case PLUS: case MINUS: case NEG: case AND: case IOR: case XOR: cc_status.flags = CC_NO_OVERFLOW; cc_status.value1 = SET_SRC (exp); cc_status.value2 = SET_DEST (exp); break; default: CC_STATUS_INIT; } else { CC_STATUS_INIT; } } else if (GET_CODE (exp) == PARALLEL && GET_CODE (XVECEXP (exp, 0, 0)) == SET) { if (SET_DEST (XVECEXP (exp, 0, 0)) == pc_rtx) return; if (SET_DEST (XVECEXP (exp, 0, 0)) == cc0_rtx) { CC_STATUS_INIT; cc_status.value1 = SET_SRC (XVECEXP (exp, 0, 0)); return; } CC_STATUS_INIT; } else { CC_STATUS_INIT; }}/* Nonzero if the top of the fpu stack dies in this insn. */inttop_dead_p (insn) rtx insn;{ extern int optimize; if (optimize) return (find_regno_note (insn, REG_DEAD, FIRST_FLOAT_REG) || find_regno_note (insn, REG_DEAD, FIRST_FLOAT_REG + 1)); if (GET_CODE (insn) == CALL_INSN) return call_top_dead_p (insn); return fp_top_dead_p1 (insn);}/* Following is used after a call_value insn if obey_regdecls there will not be the REG_DEAD notes to go by (there won't be any cross jumping to worry about either), and we depend on seeing if the FP_TOP is used in the next two insn's. Otherwise we depend on the REG_DEAD notes. */static intcall_top_dead_p (insn) rtx insn;{ int i; for (i = 0; i < 3; i++) { insn = NEXT_INSN (insn); if (insn == 0) return 1; if (GET_CODE (insn) == NOTE || GET_CODE (insn) == CODE_LABEL) continue; if (GET_CODE (insn) == BARRIER) abort (); if (GET_CODE (PATTERN (insn)) == SET && SET_DEST (PATTERN (insn)) != stack_pointer_rtx) return (!(mentions_fp_top (SET_SRC (PATTERN (insn))))); if (GET_CODE (PATTERN (insn)) == CALL) return 1; if (GET_CODE (PATTERN (insn)) == USE) return (! FP_REG_P (XEXP (PATTERN (insn), 0))); } return 1;}/* Return 1 if current val of fpu top-of-stack appears unused in rest of this basic block and also through a jump insn. This is called from top_dead_p and from fp_call_internal. */static intfp_top_dead_p1 (insn) rtx insn;{ extern int optimize; int past_jump = 0; for (insn = NEXT_INSN (insn); insn; insn = NEXT_INSN (insn)) { switch (GET_CODE (insn)) { case CALL_INSN: /* Function calls clobber this value, so it's dead. */ return 1; case JUMP_INSN: /* Follow one jump in case of cross-jumping, which could insert such a jump into one basic block. */ if (! optimize) /* Can't use JUMP_LABEL, but there's no cross-jumping either. */ return 1; if (JUMP_LABEL (insn) == 0) return 1; /* Don't scan past a jump and another jump. */ if (past_jump) return 1; past_jump = 1; insn = JUMP_LABEL (insn); case CODE_LABEL: if (! optimize) return 1; break; case INSN: if (GET_CODE (PATTERN (insn)) == SET) { if ((mentions_fp_top (SET_SRC (PATTERN (insn))))) return 0; else if (mentions_fp_top (SET_DEST (PATTERN (insn)))) return 1; } else if (mentions_fp_top (PATTERN (insn))) return 0; break; } } return 1;}/* Return 1 if X involves an FPU register. */static intmentions_fp_top (x) rtx x;{ register RTX_CODE code; code = GET_CODE (x); switch (code) { case LABEL_REF: case SYMBOL_REF: case CONST_INT: case CONST: case CC0: case PC: case CLOBBER: case MEM: return 0; case REG: return FP_REGNO_P (REGNO (x)); } /* Recursively scan the operands of this expression. */ { register char *fmt = GET_RTX_FORMAT (code); register int i; for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) { if (fmt[i] == 'e') { if (mentions_fp_top (XEXP (x, i))) return 1; } if (fmt[i] == 'E') { register int j; for (j = 0; j < XVECLEN (x, i); j++) if (mentions_fp_top (XVECEXP (x, i, j))) return 1; } } } return 0;}/* Some asm-dependent functions. */#ifdef MASM#include "masm386.c"#endif
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -