📄 sh.c
字号:
#define TARGET_PASS_BY_REFERENCE sh_pass_by_reference#undef TARGET_CALLEE_COPIES#define TARGET_CALLEE_COPIES sh_callee_copies#undef TARGET_ARG_PARTIAL_BYTES#define TARGET_ARG_PARTIAL_BYTES sh_arg_partial_bytes#undef TARGET_BUILD_BUILTIN_VA_LIST#define TARGET_BUILD_BUILTIN_VA_LIST sh_build_builtin_va_list#undef TARGET_GIMPLIFY_VA_ARG_EXPR#define TARGET_GIMPLIFY_VA_ARG_EXPR sh_gimplify_va_arg_expr#undef TARGET_VECTOR_MODE_SUPPORTED_P#define TARGET_VECTOR_MODE_SUPPORTED_P sh_vector_mode_supported_p#undef TARGET_CHECK_PCH_TARGET_FLAGS#define TARGET_CHECK_PCH_TARGET_FLAGS sh_check_pch_target_flags#undef TARGET_DWARF_CALLING_CONVENTION#define TARGET_DWARF_CALLING_CONVENTION sh_dwarf_calling_convention/* Return regmode weight for insn. */#define INSN_REGMODE_WEIGHT(INSN, MODE) regmode_weight[((MODE) == SImode) ? 0 : 1][INSN_UID (INSN)]/* Return current register pressure for regmode. */#define CURR_REGMODE_PRESSURE(MODE) curr_regmode_pressure[((MODE) == SImode) ? 0 : 1]#ifdef SYMBIAN#undef TARGET_ENCODE_SECTION_INFO#define TARGET_ENCODE_SECTION_INFO sh_symbian_encode_section_info#undef TARGET_STRIP_NAME_ENCODING#define TARGET_STRIP_NAME_ENCODING sh_symbian_strip_name_encoding#undef TARGET_CXX_IMPORT_EXPORT_CLASS#define TARGET_CXX_IMPORT_EXPORT_CLASS symbian_import_export_class#endif /* SYMBIAN */#ifdef TARGET_ADJUST_UNROLL_MAX#undef TARGET_ADJUST_UNROLL_MAX#define TARGET_ADJUST_UNROLL_MAX sh_adjust_unroll_max#endifstruct gcc_target targetm = TARGET_INITIALIZER;/* Implement TARGET_HANDLE_OPTION. */static boolsh_handle_option (size_t code, const char *arg ATTRIBUTE_UNUSED, int value ATTRIBUTE_UNUSED){ switch (code) { case OPT_m1: target_flags = (target_flags & ~MASK_ARCH) | SELECT_SH1; return true; case OPT_m2: target_flags = (target_flags & ~MASK_ARCH) | SELECT_SH2; return true; case OPT_m2a: target_flags = (target_flags & ~MASK_ARCH) | SELECT_SH2A; return true; case OPT_m2a_nofpu: target_flags = (target_flags & ~MASK_ARCH) | SELECT_SH2A_NOFPU; return true; case OPT_m2a_single: target_flags = (target_flags & ~MASK_ARCH) | SELECT_SH2A_SINGLE; return true; case OPT_m2a_single_only: target_flags = (target_flags & ~MASK_ARCH) | SELECT_SH2A_SINGLE_ONLY; return true; case OPT_m2e: target_flags = (target_flags & ~MASK_ARCH) | SELECT_SH2E; return true; case OPT_m3: target_flags = (target_flags & ~MASK_ARCH) | SELECT_SH3; return true; case OPT_m3e: target_flags = (target_flags & ~MASK_ARCH) | SELECT_SH3E; return true; case OPT_m4: target_flags = (target_flags & ~MASK_ARCH) | SELECT_SH4; return true; case OPT_m4_nofpu: target_flags = (target_flags & ~MASK_ARCH) | SELECT_SH4_NOFPU; return true; case OPT_m4_single: target_flags = (target_flags & ~MASK_ARCH) | SELECT_SH4_SINGLE; return true; case OPT_m4_single_only: target_flags = (target_flags & ~MASK_ARCH) | SELECT_SH4_SINGLE_ONLY; return true; case OPT_m4a: target_flags = (target_flags & ~MASK_ARCH) | SELECT_SH4A; return true; case OPT_m4a_nofpu: case OPT_m4al: target_flags = (target_flags & ~MASK_ARCH) | SELECT_SH4A_NOFPU; return true; case OPT_m4a_single: target_flags = (target_flags & ~MASK_ARCH) | SELECT_SH4A_SINGLE; return true; case OPT_m4a_single_only: target_flags = (target_flags & ~MASK_ARCH) | SELECT_SH4A_SINGLE_ONLY; return true; case OPT_m5_32media: target_flags = (target_flags & ~MASK_ARCH) | SELECT_SH5_32MEDIA; return true; case OPT_m5_32media_nofpu: target_flags = (target_flags & ~MASK_ARCH) | SELECT_SH5_32MEDIA_NOFPU; return true; case OPT_m5_64media: target_flags = (target_flags & ~MASK_ARCH) | SELECT_SH5_64MEDIA; return true; case OPT_m5_64media_nofpu: target_flags = (target_flags & ~MASK_ARCH) | SELECT_SH5_64MEDIA_NOFPU; return true; case OPT_m5_compact: target_flags = (target_flags & ~MASK_ARCH) | SELECT_SH5_COMPACT; return true; case OPT_m5_compact_nofpu: target_flags = (target_flags & ~MASK_ARCH) | SELECT_SH5_COMPACT_NOFPU; return true; default: return true; }}/* Print the operand address in x to the stream. */voidprint_operand_address (FILE *stream, rtx x){ switch (GET_CODE (x)) { case REG: case SUBREG: fprintf (stream, "@%s", reg_names[true_regnum (x)]); break; case PLUS: { rtx base = XEXP (x, 0); rtx index = XEXP (x, 1); switch (GET_CODE (index)) { case CONST_INT: fprintf (stream, "@(%d,%s)", (int) INTVAL (index), reg_names[true_regnum (base)]); break; case REG: case SUBREG: { int base_num = true_regnum (base); int index_num = true_regnum (index); fprintf (stream, "@(r0,%s)", reg_names[MAX (base_num, index_num)]); break; } default: gcc_unreachable (); } } break; case PRE_DEC: fprintf (stream, "@-%s", reg_names[true_regnum (XEXP (x, 0))]); break; case POST_INC: fprintf (stream, "@%s+", reg_names[true_regnum (XEXP (x, 0))]); break; default: x = mark_constant_pool_use (x); output_addr_const (stream, x); break; }}/* Print operand x (an rtx) in assembler syntax to file stream according to modifier code. '.' print a .s if insn needs delay slot ',' print LOCAL_LABEL_PREFIX '@' print trap, rte or rts depending upon pragma interruptness '#' output a nop if there is nothing to put in the delay slot ''' print likelihood suffix (/u for unlikely). '>' print branch target if -fverbose-asm 'O' print a constant without the # 'R' print the LSW of a dp value - changes if in little endian 'S' print the MSW of a dp value - changes if in little endian 'T' print the next word of a dp value - same as 'R' in big endian mode. 'M' print an `x' if `m' will print `base,index'. 'N' print 'r63' if the operand is (const_int 0). 'd' print a V2SF reg as dN instead of fpN. 'm' print a pair `base,offset' or `base,index', for LD and ST. 'U' Likewise for {LD,ST}{HI,LO}. 'u' prints the lowest 16 bits of CONST_INT, as an unsigned value. 'o' output an operator. */voidprint_operand (FILE *stream, rtx x, int code){ int regno; enum machine_mode mode; switch (code) { tree trapa_attr; case '.': if (final_sequence && ! INSN_ANNULLED_BRANCH_P (XVECEXP (final_sequence, 0, 0)) && get_attr_length (XVECEXP (final_sequence, 0, 1))) fprintf (stream, ASSEMBLER_DIALECT ? "/s" : ".s"); break; case ',': fprintf (stream, "%s", LOCAL_LABEL_PREFIX); break; case '@': trapa_attr = lookup_attribute ("trap_exit", DECL_ATTRIBUTES (current_function_decl)); if (trapa_attr) fprintf (stream, "trapa #%ld", (long) TREE_INT_CST_LOW (TREE_VALUE (TREE_VALUE (trapa_attr)))); else if (sh_cfun_interrupt_handler_p ()) fprintf (stream, "rte"); else fprintf (stream, "rts"); break; case '#': /* Output a nop if there's nothing in the delay slot. */ if (dbr_sequence_length () == 0) fprintf (stream, "\n\tnop"); break; case '\'': { rtx note = find_reg_note (current_output_insn, REG_BR_PROB, 0); if (note && INTVAL (XEXP (note, 0)) * 2 < REG_BR_PROB_BASE) fputs ("/u", stream); break; } case '>': if (flag_verbose_asm && JUMP_LABEL (current_output_insn)) { fputs ("\t! target: ", stream); output_addr_const (stream, JUMP_LABEL (current_output_insn)); } break; case 'O': x = mark_constant_pool_use (x); output_addr_const (stream, x); break; /* N.B.: %R / %S / %T adjust memory addresses by four. For SHMEDIA, that means they can be used to access the first and second 32 bit part of a 64 bit (or larger) value that might be held in floating point registers or memory. While they can be used to access 64 bit parts of a larger value held in general purpose registers, that won't work with memory - neither for fp registers, since the frxx names are used. */ case 'R': if (REG_P (x) || GET_CODE (x) == SUBREG) { regno = true_regnum (x); regno += FP_REGISTER_P (regno) ? 1 : LSW; fputs (reg_names[regno], (stream)); } else if (MEM_P (x)) { x = adjust_address (x, SImode, 4 * LSW); print_operand_address (stream, XEXP (x, 0)); } else { rtx sub = NULL_RTX; mode = GET_MODE (x); if (mode == VOIDmode) mode = DImode; if (GET_MODE_SIZE (mode) >= 8) sub = simplify_subreg (SImode, x, mode, 4 * LSW); if (sub) print_operand (stream, sub, 0); else output_operand_lossage ("invalid operand to %%R"); } break; case 'S': if (REG_P (x) || GET_CODE (x) == SUBREG) { regno = true_regnum (x); regno += FP_REGISTER_P (regno) ? 0 : MSW; fputs (reg_names[regno], (stream)); } else if (MEM_P (x)) { x = adjust_address (x, SImode, 4 * MSW); print_operand_address (stream, XEXP (x, 0)); } else { rtx sub = NULL_RTX; mode = GET_MODE (x); if (mode == VOIDmode) mode = DImode; if (GET_MODE_SIZE (mode) >= 8) sub = simplify_subreg (SImode, x, mode, 4 * MSW); if (sub) print_operand (stream, sub, 0); else output_operand_lossage ("invalid operand to %%S"); } break; case 'T': /* Next word of a double. */ switch (GET_CODE (x)) { case REG: fputs (reg_names[REGNO (x) + 1], (stream)); break; case MEM: if (GET_CODE (XEXP (x, 0)) != PRE_DEC && GET_CODE (XEXP (x, 0)) != POST_INC) x = adjust_address (x, SImode, 4); print_operand_address (stream, XEXP (x, 0)); break; default: break; } break; case 'o': switch (GET_CODE (x)) { case PLUS: fputs ("add", stream); break; case MINUS: fputs ("sub", stream); break; case MULT: fputs ("mul", stream); break; case DIV: fputs ("div", stream); break; case EQ: fputs ("eq", stream); break; case NE: fputs ("ne", stream); break; case GT: case LT: fputs ("gt", stream); break; case GE: case LE: fputs ("ge", stream); break; case GTU: case LTU: fputs ("gtu", stream); break; case GEU: case LEU: fputs ("geu", stream); break; default: break; } break; case 'M': if (GET_CODE (x) == MEM && GET_CODE (XEXP (x, 0)) == PLUS && (GET_CODE (XEXP (XEXP (x, 0), 1)) == REG || GET_CODE (XEXP (XEXP (x, 0), 1)) == SUBREG)) fputc ('x', stream); break; case 'm': gcc_assert (GET_CODE (x) == MEM); x = XEXP (x, 0); /* Fall through. */ case 'U': switch (GET_CODE (x)) { case REG: case SUBREG: print_operand (stream, x, 0); fputs (", 0", stream); break; case PLUS: print_operand (stream, XEXP (x, 0), 0); fputs (", ", stream); print_operand (stream, XEXP (x, 1), 0); break; default: gcc_unreachable (); } break; case 'd': gcc_assert (GET_CODE (x) == REG && GET_MODE (x) == V2SFmode); fprintf ((stream), "d%s", reg_names[REGNO (x)] + 1); break; case 'N': if (x == CONST0_RTX (GET_MODE (x))) { fprintf ((stream), "r63"); break; } goto default_output; case 'u': if (GET_CODE (x) == CONST_INT) { fprintf ((stream), "%u", (unsigned) INTVAL (x) & (0x10000 - 1)); break; } /* Fall through. */ default_output: default: regno = 0; mode = GET_MODE (x);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -