📄 romp.c
字号:
if (GET_CODE (op) != CONST_INT) return 0; return (INTVAL (op) & 0xffff) == 0xffff || (INTVAL (op) & 0xffff0000) == 0xffff0000;}/* Return 1 if the operand is a register or memory operand. */intreg_or_mem_operand (op, mode) register rtx op; register enum machine_mode mode;{ return register_operand (op, mode) || memory_operand (op, mode);}/* Return 1 if the operand is either a register or a memory operand that is not symbolic. */intreg_or_nonsymb_mem_operand (op, mode) register rtx op; enum machine_mode mode;{ if (register_operand (op, mode)) return 1; if (memory_operand (op, mode) && ! symbolic_memory_operand (op, mode)) return 1; return 0;}/* Return 1 if this operand is valid for the ROMP. This is any operand except certain constant integers. */intromp_operand (op, mode) register rtx op; enum machine_mode mode;{ if (GET_CODE (op) == CONST_INT) return constant_operand (op, mode); return general_operand (op, mode);}/* Return 1 if the operand is (reg:mode 0). */intreg_0_operand (op, mode) rtx op; enum machine_mode mode;{ return ((mode == VOIDmode || mode == GET_MODE (op)) && GET_CODE (op) == REG && REGNO (op) == 0);}/* Return 1 if the operand is (reg:mode 15). */intreg_15_operand (op, mode) rtx op; enum machine_mode mode;{ return ((mode == VOIDmode || mode == GET_MODE (op)) && GET_CODE (op) == REG && REGNO (op) == 15);}/* Return 1 if this is a binary floating-point operation. */intfloat_binary (op, mode) register rtx op; enum machine_mode mode;{ if (mode != VOIDmode && mode != GET_MODE (op)) return 0; if (GET_MODE (op) != SFmode && GET_MODE (op) != DFmode) return 0; switch (GET_CODE (op)) { case PLUS: case MINUS: case MULT: case DIV: return GET_MODE (XEXP (op, 0)) == GET_MODE (op) && GET_MODE (XEXP (op, 1)) == GET_MODE (op); default: return 0; }}/* Return 1 if this is a unary floating-point operation. */intfloat_unary (op, mode) register rtx op; enum machine_mode mode;{ if (mode != VOIDmode && mode != GET_MODE (op)) return 0; if (GET_MODE (op) != SFmode && GET_MODE (op) != DFmode) return 0; return (GET_CODE (op) == NEG || GET_CODE (op) == ABS) && GET_MODE (XEXP (op, 0)) == GET_MODE (op);}/* Return 1 if this is a valid floating-point conversion that can be done as part of an operation by the RT floating-point routines. */intfloat_conversion (op, mode) register rtx op; enum machine_mode mode;{ if (mode != VOIDmode && mode != GET_MODE (op)) return 0; switch (GET_CODE (op)) { case FLOAT_TRUNCATE: return GET_MODE (op) == SFmode && GET_MODE (XEXP (op, 0)) == DFmode; case FLOAT_EXTEND: return GET_MODE (op) == DFmode && GET_MODE (XEXP (op, 0)) == SFmode; case FLOAT: return ((GET_MODE (XEXP (op, 0)) == SImode || GET_CODE (XEXP (op, 0)) == CONST_INT) && (GET_MODE (op) == SFmode || GET_MODE (op) == DFmode)); case FIX: return ((GET_MODE (op) == SImode || GET_CODE (XEXP (op, 0)) == CONST_INT) && (GET_MODE (XEXP (op, 0)) == SFmode || GET_MODE (XEXP (op, 0)) == DFmode)); default: return 0; }}/* Print an operand. Recognize special options, documented below. */voidprint_operand (file, x, code) FILE *file; rtx x; int code;{ int i; switch (code) { case 'B': /* Byte number (const/8) */ if (GET_CODE (x) != CONST_INT) output_operand_lossage ("invalid %%B value"); fprintf (file, "%d", INTVAL (x) / 8); break; case 'L': /* Low order 16 bits of constant. */ if (GET_CODE (x) != CONST_INT) output_operand_lossage ("invalid %%L value"); fprintf (file, "%d", INTVAL (x) & 0xffff); break; case 's': /* Null or "16" depending on whether the constant is greater than 16. */ if (GET_CODE (x) != CONST_INT) output_operand_lossage ("invalid %%s value"); if (INTVAL (x) >= 16) fprintf (file, "16"); break; case 'S': /* For shifts: 's' will have given the half. Just give the amount within 16. */ if (GET_CODE (x) != CONST_INT) output_operand_lossage ("invalid %%S value"); fprintf (file, "%d", INTVAL (x) & 15); break; case 'b': /* The number of a single bit set or cleared, mod 16. Note that the ROMP numbers bits with the high-order bit 31. */ if (GET_CODE (x) != CONST_INT) output_operand_lossage ("invalid %%b value"); if ((i = exact_log2 (INTVAL (x))) >= 0) fprintf (file, "%d", (31 - i) % 16); else if ((i = exact_log2 (~ INTVAL (x))) >= 0) fprintf (file, "%d", (31 - i) % 16); else output_operand_lossage ("invalid %%b value"); break; case 'h': /* "l" or "u" depending on which half of the constant is zero. */ if (GET_CODE (x) != CONST_INT) output_operand_lossage ("invalid %%h value"); if ((INTVAL (x) & 0xffff0000) == 0) fprintf (file, "l"); else if ((INTVAL (x) & 0xffff) == 0) fprintf (file, "u"); else output_operand_lossage ("invalid %%h value"); break; case 'H': /* Upper or lower half, depending on which half is zero. */ if (GET_CODE (x) != CONST_INT) output_operand_lossage ("invalid %%H value"); if ((INTVAL (x) & 0xffff0000) == 0) fprintf (file, "%d", INTVAL (x) & 0xffff); else if ((INTVAL (x) & 0xffff) == 0) fprintf (file, "%d", (INTVAL (x) >> 16) & 0xffff); else output_operand_lossage ("invalid %%H value"); break; case 'z': /* Write two characters: 'lo' if the high order part is all ones 'lz' if the high order part is all zeros 'uo' if the low order part is all ones 'uz' if the low order part is all zeros */ if (GET_CODE (x) != CONST_INT) output_operand_lossage ("invalid %%z value"); if ((INTVAL (x) & 0xffff0000) == 0) fprintf (file, "lz"); else if ((INTVAL (x) & 0xffff0000) == 0xffff0000) fprintf (file, "lo"); else if ((INTVAL (x) & 0xffff) == 0) fprintf (file, "uz"); else if ((INTVAL (x) & 0xffff) == 0xffff) fprintf (file, "uo"); else output_operand_lossage ("invalid %%z value"); break; case 'Z': /* Upper or lower half, depending on which is nonzero or not all ones. Must be consistent with 'z' above. */ if (GET_CODE (x) != CONST_INT) output_operand_lossage ("invalid %%Z value"); if ((INTVAL (x) & 0xffff0000) == 0 || (INTVAL (x) & 0xffff0000) == 0xffff0000) fprintf (file, "%d", INTVAL (x) & 0xffff); else if ((INTVAL (x) & 0xffff) == 0 || (INTVAL (x) & 0xffff) == 0xffff) fprintf (file, "%d", (INTVAL (x) >> 16) & 0xffff); else output_operand_lossage ("invalid %%Z value"); break; case 'k': /* Same as 'z', except the trailing 'o' or 'z' is not written. */ if (GET_CODE (x) != CONST_INT) output_operand_lossage ("invalid %%k value"); if ((INTVAL (x) & 0xffff0000) == 0 || (INTVAL (x) & 0xffff0000) == 0xffff0000) fprintf (file, "l"); else if ((INTVAL (x) & 0xffff) == 0 || (INTVAL (x) & 0xffff) == 0xffff) fprintf (file, "u"); else output_operand_lossage ("invalid %%k value"); break; case 't': /* Similar to 's', except that we write 'h' or 'u'. */ if (GET_CODE (x) != CONST_INT) output_operand_lossage ("invalid %%k value"); if (INTVAL (x) < 16) fprintf (file, "u"); else fprintf (file, "l"); break; case 'M': /* For memory operations, write 's' if the operand is a short memory operand. */ if (short_memory_operand (x, VOIDmode)) fprintf (file, "s"); break; case 'N': /* Like 'M', but check for zero memory offset. */ if (zero_memory_operand (x, VOIDmode)) fprintf (file, "s"); break; case 'O': /* Write low-order part of DImode or DFmode. Supported for MEM and REG only. */ if (GET_CODE (x) == REG) fprintf (file, "%s", reg_names[REGNO (x) + 1]); else if (GET_CODE (x) == MEM) print_operand (file, gen_rtx_MEM (GET_MODE (x), plus_constant (XEXP (x, 0), 4)), 0); else abort (); break; case 'C': /* Offset in constant pool for constant pool address. */ if (! constant_pool_address_operand (x, VOIDmode)) abort (); if (GET_CODE (x) == SYMBOL_REF) fprintf (file, "%d", get_pool_offset (x) + 12); else /* Must be (const (plus (symbol_ref) (const_int))) */ fprintf (file, "%d", (get_pool_offset (XEXP (XEXP (x, 0), 0)) + 12 + INTVAL (XEXP (XEXP (x, 0), 1)))); break; case 'j': /* Branch opcode. Check for condition in test bit for eq/ne. */ switch (GET_CODE (x)) { case EQ: if (cc_status.flags & CC_IN_TB) fprintf (file, "ntb"); else fprintf (file, "eq"); break; case NE: if (cc_status.flags & CC_IN_TB) fprintf (file, "tb"); else fprintf (file, "ne"); break; case GT: case GTU: fprintf (file, "h"); break; case LT: case LTU: fprintf (file, "l"); break; case GE: case GEU: fprintf (file, "he"); break; case LE: case LEU: fprintf (file, "le"); break; default: output_operand_lossage ("invalid %%j value"); } break; case 'J': /* Reversed branch opcode. */ switch (GET_CODE (x)) { case EQ: if (cc_status.flags & CC_IN_TB) fprintf (file, "tb"); else fprintf (file, "ne"); break; case NE: if (cc_status.flags & CC_IN_TB) fprintf (file, "ntb"); else fprintf (file, "eq"); break; case GT: case GTU: fprintf (file, "le"); break; case LT: case LTU: fprintf (file, "he"); break; case GE: case GEU: fprintf (file, "l"); break; case LE: case LEU: fprintf (file, "h"); break; default: output_operand_lossage ("invalid %%j value"); } break; case '.': /* Output nothing. Used as delimiter in, e.g., "mc%B1%.3 " */ break; case '#': /* Output 'x' if this insn has a delay slot, else nothing. */ if (dbr_sequence_length ()) fprintf (file, "x"); break; case 0: if (GET_CODE (x) == REG) fprintf (file, "%s", reg_names[REGNO (x)]); else if (GET_CODE (x) == MEM) { if (GET_CODE (XEXP (x, 0)) == SYMBOL_REF && current_function_operand (x, Pmode)) fprintf (file, "r14"); else output_address (XEXP (x, 0)); } else output_addr_const (file, x); break; default: output_operand_lossage ("invalid %%xn code"); }}/* This page contains routines that are used to determine what the function prologue and epilogue code will do and write them out. *//* Return the first register that is required to be saved. 16 if none. */intfirst_reg_to_save(){ int first_reg; /* Find lowest numbered live register. */ for (first_reg = 6; first_reg <= 15; first_reg++) if (regs_ever_live[first_reg]) break; /* If we think that we do not have to save r14, see if it will be used to be sure. */ if (first_reg > 14 && romp_using_r14 ()) first_reg = 14; return first_reg;}/* Compute the size of the save area in the stack, including the space for the first four incoming arguments. */intromp_sa_size (){ int size; int i; /* We have the 4 words corresponding to the arguments passed in registers, 4 reserved words, space for static chain, general register save area, and floating-point save area. */ size = 4 + 4 + 1 + (16 - first_reg_to_save ()); /* The documentation says we have to leave 18 words in the save area if any floating-point registers at all are saved, not the three words per register you might otherwise expect. */ for (i = 2 + (TARGET_FP_REGS != 0); i <= 7; i++) if (regs_ever_live[i + 17]) { size += 18; break; } return size * 4;}/* Return nonzero if this function makes calls or has fp operations (which are really calls). */intromp_makes_calls (){ rtx insn; for (insn = get_insns (); insn; insn = next_insn (insn)) { if (GET_CODE (insn) == CALL_INSN) return 1; else if (GET_CODE (insn) == INSN) { rtx body = PATTERN (insn);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -