📄 romp.c
字号:
return register_operand (op, mode);}/* Return 1 if the operand is either a register or an item that can be used as the operand of an SI add insn. */intreg_or_add_operand (op, mode) register rtx op; enum machine_mode mode;{ return reg_or_D_operand (op, mode) || romp_symbolic_operand (op, mode) || (GET_CODE (op) == CONST_INT && (INTVAL (op) & 0xffff) == 0);}/* Return 1 if the operand is either a register or an item that can be used as the operand of a ROMP logical AND insn. */intreg_or_and_operand (op, mode) register rtx op; enum machine_mode mode;{ if (reg_or_cint_operand (op, mode)) return 1; 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; char 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 non-zero 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));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -