📄 ns32k.c
字号:
if (rtd) { if (TYPE_ARG_TYPES (funtype) == NULL_TREE || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (funtype))) == void_type_node)) return size; } return 0;}/* PRINT_OPERAND is defined to call this function, which is easier to debug than putting all the code in a macro definition in ns32k.h. *//* XXX time 12% of cpu time is in fprintf for non optimizing */voidprint_operand (FILE *file, rtx x, int code){ if (code == '$') PUT_IMMEDIATE_PREFIX (file); else if (code == '?') PUT_EXTERNAL_PREFIX (file); else if (GET_CODE (x) == REG) fprintf (file, "%s", ns32k_out_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) != VOIDmode) { REAL_VALUE_TYPE r; REAL_VALUE_FROM_CONST_DOUBLE (r, x); PUT_IMMEDIATE_PREFIX (file); if (GET_MODE (x) == DFmode) { #ifdef SEQUENT_ASM /* Sequent likes its floating point constants as integers */ long l[2]; REAL_VALUE_TO_TARGET_DOUBLE (r, l); fprintf (file, "0Dx%08x%08x", l[!WORDS_BIG_ENDIAN], l[WORDS_BIG_ENDIAN]);#else char s[30]; real_to_decimal (s, &r, sizeof (s), 0, 1);#ifdef ENCORE_ASM fprintf (file, "0f%s", s);#else fprintf (file, "0d%s", s);#endif#endif } else {#ifdef SEQUENT_ASM long l; REAL_VALUE_TO_TARGET_SINGLE (r, l); fprintf (file, "0Fx%08lx", l);#else char s[30]; real_to_decimal (s, &r, sizeof (s), 0, 1); fprintf (file, "0f%s", s);#endif } } else { if (flag_pic && GET_CODE (x) == CONST && symbolic_reference_mentioned_p (x)) { fprintf (stderr, "illegal constant for pic-mode: \n"); print_rtl (stderr, x); fprintf (stderr, "\nGET_CODE (x) == %d, CONST == %d, symbolic_reference_mentioned_p (x) == %d\n", GET_CODE (x), CONST, symbolic_reference_mentioned_p (x)); abort (); } else if (flag_pic && (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == LABEL_REF)) { output_addr_const (file, x); fprintf (file, "(sb)"); } 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> */voidprint_operand_address (register FILE *file, register rtx addr){ static const 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) < F0_REGNUM) 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 && ! SYMBOL_REF_LOCAL_P (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 (! SYMBOL_REF_LOCAL_P (sym)) { 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)", ns32k_out_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)", ns32k_out_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) >= F0_REGNUM) abort ();#ifdef UTEK_ASM fprintf (file, "[%c`%s]", scales[scale], ns32k_out_reg_names[REGNO (indexexp)]);#else fprintf (file, "[%s:%c]", ns32k_out_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. */const char *output_shift_insn (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";}const char *output_move_dconst (int n, const 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;}static rtxns32k_struct_value_rtx (tree fntype ATTRIBUTE_UNUSED, int incoming ATTRIBUTE_UNUSED){ return gen_rtx_REG (Pmode, NS32K_STRUCT_VALUE_REGNUM);}/* Worker function for NOTICE_UPDATE_CC. */voidns32k_notice_update_cc (rtx exp, rtx insn ATTRIBUTE_UNUSED){ if (GET_CODE (exp) == SET) { if (GET_CODE (SET_DEST (exp)) == CC0) { cc_status.flags = 0; cc_status.value1 = SET_DEST (exp); cc_status.value2 = SET_SRC (exp); } else if (GET_CODE (SET_SRC (exp)) == CALL) { CC_STATUS_INIT; } else if (GET_CODE (SET_DEST (exp)) == REG) { 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; } else if (GET_CODE (SET_DEST (exp)) == MEM) { CC_STATUS_INIT; } } else if (GET_CODE (exp) == PARALLEL && GET_CODE (XVECEXP (exp, 0, 0)) == SET) { if (GET_CODE (SET_DEST (XVECEXP (exp, 0, 0))) == CC0) { cc_status.flags = 0; cc_status.value1 = SET_DEST (XVECEXP (exp, 0, 0)); cc_status.value2 = SET_SRC (XVECEXP (exp, 0, 0)); } else if (GET_CODE (SET_DEST (XVECEXP (exp, 0, 0))) == REG) { if (cc_status.value1 && reg_overlap_mentioned_p (SET_DEST (XVECEXP (exp, 0, 0)), cc_status.value1)) cc_status.value1 = 0; if (cc_status.value2 && reg_overlap_mentioned_p (SET_DEST (XVECEXP (exp, 0, 0)), cc_status.value2)) cc_status.value2 = 0; } else if (GET_CODE (SET_DEST (XVECEXP (exp, 0, 0))) == MEM) { CC_STATUS_INIT; } } else if (GET_CODE (exp) == CALL) { /* all bets are off */ CC_STATUS_INIT; } else { /* nothing happens? CC_STATUS_INIT; */ } if (cc_status.value1 && GET_CODE (cc_status.value1) == REG && cc_status.value2 && reg_overlap_mentioned_p (cc_status.value1, cc_status.value2)) abort ();}/* Implement TARGET_ARG_PARTIAL_BYTES. */static intns32k_arg_partial_bytes (CUMULATIVE_ARGS *pcum, enum machine_mode mode, tree type, bool named ATTRIBUTE_UNUSED){ int cum = *pcum; if (TARGET_REGPARM && cum < 8) { HOST_WIDE_INT size; if (mode == BLKmode) size = int_size_in_bytes (type); else size = GET_MODE_SIZE (mode); if (8 < cum + size) return 8 - cum; } return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -