⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 m68hc11.c

📁 Mac OS X 10.4.9 for x86 Source Code gcc 实现源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
}/* Returns true if X is a PRE/POST increment decrement   (same as auto_inc_p() in rtlanal.c but do not take into   account the stack).  */static intm68hc11_auto_inc_p (rtx x){  return GET_CODE (x) == PRE_DEC    || GET_CODE (x) == POST_INC    || GET_CODE (x) == POST_DEC || GET_CODE (x) == PRE_INC;}/* Predicates for machine description.  */intmemory_reload_operand (rtx operand, enum machine_mode mode ATTRIBUTE_UNUSED){  return GET_CODE (operand) == MEM    && GET_CODE (XEXP (operand, 0)) == PLUS    && ((GET_CODE (XEXP (XEXP (operand, 0), 0)) == REG	 && GET_CODE (XEXP (XEXP (operand, 0), 1)) == CONST_INT)	|| (GET_CODE (XEXP (XEXP (operand, 0), 1)) == REG	    && GET_CODE (XEXP (XEXP (operand, 0), 0)) == CONST_INT));}inttst_operand (rtx operand, enum machine_mode mode){  if (GET_CODE (operand) == MEM && reload_completed == 0)    {      rtx addr = XEXP (operand, 0);      if (m68hc11_auto_inc_p (addr))	return 0;    }  return nonimmediate_operand (operand, mode);}intcmp_operand (rtx operand, enum machine_mode mode){  if (GET_CODE (operand) == MEM)    {      rtx addr = XEXP (operand, 0);      if (m68hc11_auto_inc_p (addr))	return 0;    }  return general_operand (operand, mode);}intnon_push_operand (rtx operand, enum machine_mode mode){  if (general_operand (operand, mode) == 0)    return 0;  if (push_operand (operand, mode) == 1)    return 0;  return 1;}intsplitable_operand (rtx operand, enum machine_mode mode){  if (general_operand (operand, mode) == 0)    return 0;  if (push_operand (operand, mode) == 1)    return 0;  /* Reject a (MEM (MEM X)) because the patterns that use non_push_operand     need to split such addresses to access the low and high part but it     is not possible to express a valid address for the low part.  */  if (mode != QImode && GET_CODE (operand) == MEM      && GET_CODE (XEXP (operand, 0)) == MEM)    return 0;  return 1;}intreg_or_some_mem_operand (rtx operand, enum machine_mode mode){  if (GET_CODE (operand) == MEM)    {      rtx op = XEXP (operand, 0);      int addr_mode;      if (symbolic_memory_operand (op, mode))	return 1;      if (IS_STACK_PUSH (operand))	return 1;      if (GET_CODE (operand) == REG && reload_in_progress          && REGNO (operand) >= FIRST_PSEUDO_REGISTER          && reg_equiv_memory_loc[REGNO (operand)])         {            operand = reg_equiv_memory_loc[REGNO (operand)];            operand = eliminate_regs (operand, 0, NULL_RTX);         }      if (GET_CODE (operand) != MEM)         return 0;      operand = XEXP (operand, 0);      addr_mode = m68hc11_addr_mode | (reload_completed ? ADDR_STRICT : 0);      addr_mode &= ~ADDR_INDIRECT;      return register_indirect_p (operand, mode, addr_mode);    }  return register_operand (operand, mode);}intm68hc11_symbolic_p (rtx operand, enum machine_mode mode){  if (GET_CODE (operand) == MEM)    {      rtx op = XEXP (operand, 0);      if (symbolic_memory_operand (op, mode))	return 1;    }  return 0;}intm68hc11_indirect_p (rtx operand, enum machine_mode mode){  if (GET_CODE (operand) == MEM && GET_MODE (operand) == mode)    {      rtx op = XEXP (operand, 0);      int addr_mode;      if (m68hc11_page0_symbol_p (op))        return 1;      if (symbolic_memory_operand (op, mode))	return TARGET_M6812;      if (reload_in_progress)        return 1;      operand = XEXP (operand, 0);      addr_mode = m68hc11_addr_mode | (reload_completed ? ADDR_STRICT : 0);      return register_indirect_p (operand, mode, addr_mode);    }  return 0;}intstack_register_operand (rtx operand, enum machine_mode mode ATTRIBUTE_UNUSED){  return SP_REG_P (operand);}intd_register_operand (rtx operand, enum machine_mode mode){  if (GET_MODE (operand) != mode && mode != VOIDmode)    return 0;  if (GET_CODE (operand) == SUBREG)    operand = XEXP (operand, 0);  return GET_CODE (operand) == REG    && (REGNO (operand) >= FIRST_PSEUDO_REGISTER	|| REGNO (operand) == HARD_D_REGNUM        || (mode == QImode && REGNO (operand) == HARD_B_REGNUM));}inthard_addr_reg_operand (rtx operand, enum machine_mode mode){  if (GET_MODE (operand) != mode && mode != VOIDmode)    return 0;  if (GET_CODE (operand) == SUBREG)    operand = XEXP (operand, 0);  return GET_CODE (operand) == REG    && (REGNO (operand) == HARD_X_REGNUM	|| REGNO (operand) == HARD_Y_REGNUM	|| REGNO (operand) == HARD_Z_REGNUM);}inthard_reg_operand (rtx operand, enum machine_mode mode){  if (GET_MODE (operand) != mode && mode != VOIDmode)    return 0;  if (GET_CODE (operand) == SUBREG)    operand = XEXP (operand, 0);  return GET_CODE (operand) == REG    && (REGNO (operand) >= FIRST_PSEUDO_REGISTER	|| H_REGNO_P (REGNO (operand)));}intmemory_indexed_operand (rtx operand, enum machine_mode mode ATTRIBUTE_UNUSED){  if (GET_CODE (operand) != MEM)    return 0;  operand = XEXP (operand, 0);  if (GET_CODE (operand) == PLUS)    {      if (GET_CODE (XEXP (operand, 0)) == REG)	operand = XEXP (operand, 0);      else if (GET_CODE (XEXP (operand, 1)) == REG)	operand = XEXP (operand, 1);    }  return GET_CODE (operand) == REG    && (REGNO (operand) >= FIRST_PSEUDO_REGISTER	|| A_REGNO_P (REGNO (operand)));}intpush_pop_operand_p (rtx operand){  if (GET_CODE (operand) != MEM)    {      return 0;    }  operand = XEXP (operand, 0);  return PUSH_POP_ADDRESS_P (operand);}/* Returns 1 if OP is either a symbol reference or a sum of a symbol   reference and a constant.  */intsymbolic_memory_operand (rtx op, enum machine_mode mode){  switch (GET_CODE (op))    {    case SYMBOL_REF:    case LABEL_REF:      return 1;    case CONST:      op = XEXP (op, 0);      return ((GET_CODE (XEXP (op, 0)) == SYMBOL_REF	       || GET_CODE (XEXP (op, 0)) == LABEL_REF)	      && GET_CODE (XEXP (op, 1)) == CONST_INT);      /* ??? This clause seems to be irrelevant.  */    case CONST_DOUBLE:      return GET_MODE (op) == mode;    case PLUS:      return symbolic_memory_operand (XEXP (op, 0), mode)	&& symbolic_memory_operand (XEXP (op, 1), mode);    default:      return 0;    }}intm68hc11_eq_compare_operator (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED){  return GET_CODE (op) == EQ || GET_CODE (op) == NE;}intm68hc11_logical_operator (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED){  return GET_CODE (op) == AND || GET_CODE (op) == IOR || GET_CODE (op) == XOR;}intm68hc11_arith_operator (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED){  return GET_CODE (op) == AND || GET_CODE (op) == IOR || GET_CODE (op) == XOR    || GET_CODE (op) == PLUS || GET_CODE (op) == MINUS    || GET_CODE (op) == ASHIFT || GET_CODE (op) == ASHIFTRT    || GET_CODE (op) == LSHIFTRT || GET_CODE (op) == ROTATE    || GET_CODE (op) == ROTATERT;}intm68hc11_non_shift_operator (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED){  return GET_CODE (op) == AND || GET_CODE (op) == IOR || GET_CODE (op) == XOR    || GET_CODE (op) == PLUS || GET_CODE (op) == MINUS;}/* Return true if op is a shift operator.  */intm68hc11_shift_operator (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED){  return GET_CODE (op) == ROTATE || GET_CODE (op) == ROTATERT    || GET_CODE (op) == LSHIFTRT || GET_CODE (op) == ASHIFT    || GET_CODE (op) == ASHIFTRT;}intm68hc11_unary_operator (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED){  return GET_CODE (op) == NEG || GET_CODE (op) == NOT    || GET_CODE (op) == SIGN_EXTEND || GET_CODE (op) == ZERO_EXTEND;}/* Emit the code to build the trampoline used to call a nested function.      68HC11               68HC12   ldy #&CXT            movw #&CXT,*_.d1   sty *_.d1            jmp FNADDR   jmp FNADDR*/voidm68hc11_initialize_trampoline (rtx tramp, rtx fnaddr, rtx cxt){  const char *static_chain_reg = reg_names[STATIC_CHAIN_REGNUM];  /* Skip the '*'.  */  if (*static_chain_reg == '*')    static_chain_reg++;  if (TARGET_M6811)    {      emit_move_insn (gen_rtx_MEM (HImode, tramp), GEN_INT (0x18ce));      emit_move_insn (gen_rtx_MEM (HImode, plus_constant (tramp, 2)), cxt);      emit_move_insn (gen_rtx_MEM (HImode, plus_constant (tramp, 4)),                      GEN_INT (0x18df));      emit_move_insn (gen_rtx_MEM (QImode, plus_constant (tramp, 6)),                      gen_rtx_CONST (QImode,                                     gen_rtx_SYMBOL_REF (Pmode,                                                         static_chain_reg)));      emit_move_insn (gen_rtx_MEM (QImode, plus_constant (tramp, 7)),                      GEN_INT (0x7e));      emit_move_insn (gen_rtx_MEM (HImode, plus_constant (tramp, 8)), fnaddr);    }  else    {      emit_move_insn (gen_rtx_MEM (HImode, tramp), GEN_INT (0x1803));      emit_move_insn (gen_rtx_MEM (HImode, plus_constant (tramp, 2)), cxt);      emit_move_insn (gen_rtx_MEM (HImode, plus_constant (tramp, 4)),                      gen_rtx_CONST (HImode,                                     gen_rtx_SYMBOL_REF (Pmode,                                                         static_chain_reg)));      emit_move_insn (gen_rtx_MEM (QImode, plus_constant (tramp, 6)),                      GEN_INT (0x06));      emit_move_insn (gen_rtx_MEM (HImode, plus_constant (tramp, 7)), fnaddr);    }}/* Declaration of types.  *//* Handle an "tiny_data" attribute; arguments as in   struct attribute_spec.handler.  */static treem68hc11_handle_page0_attribute (tree *node, tree name,                                tree args ATTRIBUTE_UNUSED,                                int flags ATTRIBUTE_UNUSED, bool *no_add_attrs){  tree decl = *node;  if (TREE_STATIC (decl) || DECL_EXTERNAL (decl))    {      DECL_SECTION_NAME (decl) = build_string (6, ".page0");    }  else    {      warning ("%qs attribute ignored", IDENTIFIER_POINTER (name));      *no_add_attrs = true;    }  return NULL_TREE;}const struct attribute_spec m68hc11_attribute_table[] ={  /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */  { "interrupt", 0, 0, false, true,  true,  m68hc11_handle_fntype_attribute },  { "trap",      0, 0, false, true,  true,  m68hc11_handle_fntype_attribute },  { "far",       0, 0, false, true,  true,  m68hc11_handle_fntype_attribute },  { "near",      0, 0, false, true,  true,  m68hc11_handle_fntype_attribute },  { "page0",     0, 0, false, false, false, m68hc11_handle_page0_attribute },  { NULL,        0, 0, false, false, false, NULL }};/* Keep track of the symbol which has a `trap' attribute and which uses   the `swi' calling convention.  Since there is only one trap, we only   record one such symbol.  If there are several, a warning is reported.  */static rtx trap_handler_symbol = 0;/* Handle an attribute requiring a FUNCTION_TYPE, FIELD_DECL or TYPE_DECL;   arguments as in struct attribute_spec.handler.  */static treem68hc11_handle_fntype_attribute (tree *node, tree name,                                 tree args ATTRIBUTE_UNUSED,                                 int flags ATTRIBUTE_UNUSED,                                 bool *no_add_attrs){  if (TREE_CODE (*node) != FUNCTION_TYPE      && TREE_CODE (*node) != METHOD_TYPE      && TREE_CODE (*node) != FIELD_DECL      && TREE_CODE (*node) != TYPE_DECL)    {      warning ("%qs attribute only applies to functions",	       IDENTIFIER_POINTER (name));      *no_add_attrs = true;    }  return NULL_TREE;}/* Undo the effects of the above.  */static const char *m68hc11_strip_name_encoding (const char *str){  return str + (*str == '*' || *str == '@' || *str == '&');}static voidm68hc11_encode_label (tree decl){  const char *str = XSTR (XEXP (DECL_RTL (decl), 0), 0);  int len = strlen (str);  char *newstr = alloca (len + 2);  newstr[0] = '@';  strcpy (&newstr[1], str);  XSTR (XEXP (DECL_RTL (decl), 0), 0) = ggc_alloc_string (newstr, len + 1);}/* Return 1 if this is a symbol in page0  */intm68hc11_page0_symbol_p (rtx x){  switch (GET_CODE (x))    {    case SYMBOL_REF:      return XSTR (x, 0) != 0 && XSTR (x, 0)[0] == '@';    case CONST:      return m68hc11_page0_symbol_p (XEXP (x, 0));    case PLUS:      if (!m68hc11_page0_symbol_p (XEXP (x, 0)))        return 0;      return GET_CODE (XEXP (x, 1)) == CONST_INT        && INTVAL (XEXP (x, 1)) < 256        && INTVAL (XEXP (x, 1)) >= 0;    default:      return 0;    }}/* We want to recognize trap handlers so that we handle calls to traps   in a special manner (by issuing the trap).  This information is stored   in SYMBOL_REF_FLAG.  */static voidm68hc11_encode_section_info (tree decl, rtx rtl, int first ATTRIBUTE_UNUSED){  tree func_attr;  int trap_handler;  int is_far = 0;    if (TREE_CODE (decl) == VAR_DECL)    {      if (lookup_attribute ("page0", DECL_ATTRIBUTES (decl)) != 0)        m68hc11_encode_label (decl);      return;    }  if (TREE_CODE (decl) != FUNCTION_DECL)    return;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -