📄 ns32k.c
字号:
a macro definition in ns32k.h. */voidprint_operand (file, x, code) FILE *file; rtx x; char code;{ if (code == '$') PUT_IMMEDIATE_PREFIX (file); else if (code == '?') PUT_EXTERNAL_PREFIX (file); else if (GET_CODE (x) == REG) fprintf (file, "%s", reg_names[REGNO (x)]); else if (GET_CODE (x) == MEM) { rtx tmp = XEXP (x, 0); output_address (XEXP (x, 0)); } else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) != VOIDmode) { if (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); PUT_IMMEDIATE_PREFIX(file);#ifdef SEQUENT_ASM /* Sequent likes it's floating point constants as integers */ fprintf (file, "0Dx%08x%08x", u.i[1], u.i[0]);#else#ifdef ENCORE_ASM fprintf (file, "0f%.20e", u.d); #else fprintf (file, "0d%.20e", u.d); #endif#endif } else { union { double d; int i[2]; } u; u.i[0] = CONST_DOUBLE_LOW (x); u.i[1] = CONST_DOUBLE_HIGH (x); PUT_IMMEDIATE_PREFIX (file);#ifdef SEQUENT_ASM /* We have no way of winning if we can't get the bits for a sequent floating point number. */#if HOST_FLOAT_FORMAT != TARGET_FLOAT_FORMAT abort ();#endif { union { float f; long l; } uu; uu.f = u.d; fprintf (file, "0Fx%08x", uu.l); }#else fprintf (file, "0f%.20e", u.d); #endif } } else {#ifdef NO_IMMEDIATE_PREFIX_IF_SYMBOLIC if (GET_CODE (x) == CONST_INT)#endif PUT_IMMEDIATE_PREFIX (file); output_addr_const (file, x); }}/* PRINT_OPERAND_ADDRESS is defined to call this function, which is easier to debug than putting all the code in a macro definition in ns32k.h . *//* Completely rewritten to get this to work with Gas for PC532 Mach. This function didn't work and I just wasn't able (nor very willing) to figure out how it worked. 90-11-25 Tatu Yl|nen <ylo@cs.hut.fi> */print_operand_address (file, addr) register FILE *file; register rtx addr;{ static char scales[] = { 'b', 'w', 'd', 0, 'q', }; rtx offset, base, indexexp, tmp; int scale; extern int flag_pic; if (GET_CODE (addr) == PRE_DEC || GET_CODE (addr) == POST_DEC) { fprintf (file, "tos"); return; } offset = NULL; base = NULL; indexexp = NULL; while (addr != NULL) { if (GET_CODE (addr) == PLUS) { if (GET_CODE (XEXP (addr, 0)) == PLUS) { tmp = XEXP (addr, 1); addr = XEXP (addr, 0); } else { tmp = XEXP (addr,0); addr = XEXP (addr,1); } } else { tmp = addr; addr = NULL; } switch (GET_CODE (tmp)) { case PLUS: abort (); case MEM: if (base) { indexexp = base; base = tmp; } else base = tmp; break; case REG: if (REGNO (tmp) < 8) if (base) { indexexp = tmp; } else base = tmp; else if (base) { indexexp = base; base = tmp; } else base = tmp; break; case MULT: indexexp = tmp; break; case SYMBOL_REF: if (flag_pic && ! CONSTANT_POOL_ADDRESS_P (tmp) && ! SYMBOL_REF_FLAG (tmp)) { if (base) { if (indexexp) abort (); indexexp = base; } base = tmp; break; } case CONST: if (flag_pic && GET_CODE (tmp) == CONST) { rtx sym, off, tmp1; tmp1 = XEXP (tmp,0); if (GET_CODE (tmp1) != PLUS) abort (); sym = XEXP (tmp1,0); if (GET_CODE (sym) != SYMBOL_REF) { off = sym; sym = XEXP (tmp1,1); } else off = XEXP (tmp1,1); if (GET_CODE (sym) == SYMBOL_REF) { if (GET_CODE (off) != CONST_INT) abort (); if (CONSTANT_POOL_ADDRESS_P (sym) || SYMBOL_REF_FLAG (sym)) { SYMBOL_REF_FLAG (tmp) = 1; } else { if (base) { if (indexexp) abort (); indexexp = base; } if (offset != 0) abort (); base = sym; offset = off; break; } } } case CONST_INT: case LABEL_REF: if (offset) offset = gen_rtx (PLUS, SImode, tmp, offset); else offset = tmp; break; default: abort (); } } if (! offset) offset = const0_rtx; if (base#ifndef INDEX_RATHER_THAN_BASE && (flag_pic || TARGET_HIMEM) && GET_CODE (base) != SYMBOL_REF && GET_CODE (offset) != CONST_INT#else /* This is a re-implementation of the SEQUENT_ADDRESS_BUG fix. */#endif && !indexexp && GET_CODE (base) == REG && REG_OK_FOR_INDEX_P (base)) { indexexp = base; base = NULL; } /* now, offset, base and indexexp are set */#ifndef BASE_REG_NEEDED if (! base) {#if defined (PC_RELATIVE) || defined (NO_ABSOLUTE_PREFIX_IF_SYMBOLIC) if (GET_CODE (offset) == CONST_INT)#endif PUT_ABSOLUTE_PREFIX (file); }#endif output_addr_const (file, offset); if (base) /* base can be (REG ...) or (MEM ...) */ switch (GET_CODE (base)) { /* now we must output base. Possible alternatives are: (rN) (REG ...) (sp) (REG ...) (fp) (REG ...) (pc) (REG ...) used for SYMBOL_REF and LABEL_REF, output (disp(fp)) (MEM ...) just before possible [rX:y] (disp(sp)) (MEM ...) (disp(sb)) (MEM ...) */ case REG: fprintf (file, "(%s)", reg_names[REGNO (base)]); break; case SYMBOL_REF: if (! flag_pic) abort (); fprintf (file, "("); output_addr_const (file, base); fprintf (file, "(sb))"); break; case MEM: addr = XEXP(base,0); base = NULL; offset = NULL; while (addr != NULL) { if (GET_CODE (addr) == PLUS) { if (GET_CODE (XEXP (addr, 0)) == PLUS) { tmp = XEXP (addr, 1); addr = XEXP (addr, 0); } else { tmp = XEXP (addr, 0); addr = XEXP (addr, 1); } } else { tmp = addr; addr = NULL; } switch (GET_CODE (tmp)) { case REG: base = tmp; break; case CONST: case CONST_INT: case SYMBOL_REF: case LABEL_REF: if (offset) offset = gen_rtx (PLUS, SImode, tmp, offset); else offset = tmp; break; default: abort (); } } if (! offset) offset = const0_rtx; fprintf (file, "("); output_addr_const (file, offset); if (base) fprintf (file, "(%s)", reg_names[REGNO (base)]); else if (TARGET_SB) fprintf (file, "(sb)"); else abort (); fprintf (file, ")"); break; default: abort (); }#ifdef PC_RELATIVE else if (GET_CODE (offset) != CONST_INT) fprintf (file, "(pc)");#ifdef BASE_REG_NEEDED else if (TARGET_SB) fprintf (file, "(sb)"); else abort ();#endif#endif /* PC_RELATIVE */ /* now print index if we have one */ if (indexexp) { if (GET_CODE (indexexp) == MULT) { scale = INTVAL (XEXP (indexexp, 1)) >> 1; indexexp = XEXP (indexexp, 0); } else scale = 0; if (GET_CODE (indexexp) != REG || REGNO (indexexp) >= 8) abort ();#ifdef UTEK_ASM fprintf (file, "[%c`%s]", scales[scale], reg_names[REGNO (indexexp)]);#else fprintf (file, "[%s:%c]", reg_names[REGNO (indexexp)], scales[scale]);#endif }}/* National 32032 shifting is so bad that we can get better performance in many common cases by using other techniques. */char *output_shift_insn (operands) rtx *operands;{ if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0 && INTVAL (operands[2]) <= 3) if (GET_CODE (operands[0]) == REG) { if (GET_CODE (operands[1]) == REG) { if (REGNO (operands[0]) == REGNO (operands[1])) { if (operands[2] == const1_rtx) return "addd %0,%0"; else if (INTVAL (operands[2]) == 2) return "addd %0,%0\n\taddd %0,%0"; } if (operands[2] == const1_rtx) return "movd %1,%0\n\taddd %0,%0"; operands[1] = gen_indexed_expr (const0_rtx, operands[1], operands[2]); return "addr %a1,%0"; } if (operands[2] == const1_rtx) return "movd %1,%0\n\taddd %0,%0"; } else if (GET_CODE (operands[1]) == REG) { operands[1] = gen_indexed_expr (const0_rtx, operands[1], operands[2]); return "addr %a1,%0"; } else if (INTVAL (operands[2]) == 1 && GET_CODE (operands[1]) == MEM && rtx_equal_p (operands [0], operands[1])) { rtx temp = XEXP (operands[1], 0); if (GET_CODE (temp) == REG || (GET_CODE (temp) == PLUS && GET_CODE (XEXP (temp, 0)) == REG && GET_CODE (XEXP (temp, 1)) == CONST_INT)) return "addd %0,%0"; } else return "ashd %2,%0"; return "ashd %2,%0";}char *output_move_dconst (n, s) int n; char *s;{ static char r[32]; if (n > -9 && n < 8) strcpy (r, "movqd "); else if (n > 0 && n < 256) strcpy (r, "movzbd "); else if (n > 0 && n < 65536) strcpy (r, "movzwd "); else if (n < 0 && n > -129) strcpy (r, "movxbd "); else if (n < 0 && n > -32769) strcpy (r, "movxwd "); else strcpy (r, "movd "); strcat (r, s); return r;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -