📄 ns32k.c
字号:
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);#if ! (defined (PC_RELATIVE) || defined (NO_ABSOLUTE_PREFIX_IF_SYMBOLIC)) if (GET_CODE (tmp) != CONST_INT) { char *out = XSTR (tmp, 0); if (out[0] == '*') { PUT_ABSOLUTE_PREFIX (file); fprintf (file, "%s", &out[1]); } else ASM_OUTPUT_LABELREF (file, out); } else#endif output_address (XEXP (x, 0)); } else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) != DImode) { 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; 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 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;#ifdef INDEX_RATHER_THAN_BASE /* This is a re-implementation of the SEQUENT_ADDRESS_BUG fix. */ if (base && !indexexp && GET_CODE (base) == REG && REG_OK_FOR_INDEX_P (base)) { indexexp = base; base = 0; }#endif /* now, offset, base and indexexp are set */ if (! base) {#if defined (PC_RELATIVE) || defined (NO_ABSOLUTE_PREFIX_IF_SYMBOLIC) if (GET_CODE (offset) == CONST_INT)/* if (! (GET_CODE (offset) == LABEL_REF || GET_CODE (offset) == SYMBOL_REF)) */#endif PUT_ABSOLUTE_PREFIX (file); } 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 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)]);#ifdef BASE_REG_NEEDED else if (TARGET_SB) fprintf (file, "(sb)"); else abort ();#endif fprintf (file, ")"); break; default: abort (); }#ifdef PC_RELATIVE else /* no base */ if (GET_CODE (offset) == LABEL_REF || GET_CODE (offset) == SYMBOL_REF) fprintf (file, "(pc)");#endif#ifdef BASE_REG_NEEDED /* this is defined if the assembler always needs a base register */ else if (TARGET_SB) fprintf (file, "(sb)"); else abort ();#endif /* 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";}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -