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

📄 dsp16xx.c

📁 gcc-you can use this code to learn something about gcc, and inquire further into linux,
💻 C
📖 第 1 页 / 共 4 页
字号:
/* Subroutines for assembler code output on the DSP1610.   Copyright (C) 1994, 1995, 1997, 1998, 2001 Free Software Foundation, Inc.   Contributed by Michael Collison (collison@isisinc.net).This file is part of GNU CC.GNU CC is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation; either version 2, or (at your option)any later version.GNU CC is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with GNU CC; see the file COPYING.  If not, write tothe Free Software Foundation, 59 Temple Place - Suite 330,Boston, MA 02111-1307, USA.  *//* Some output-actions in dsp1600.md need these.  */#include "config.h"#include "system.h"#include "rtl.h"#include "regs.h"#include "hard-reg-set.h"#include "real.h"#include "insn-config.h"#include "conditions.h"#include "output.h"#include "insn-attr.h"#include "tree.h"#include "expr.h"#include "function.h"#include "flags.h"#include "ggc.h"#include "toplev.h"#include "recog.h"#include "tm_p.h"#include "target.h"#include "target-def.h"const char *text_seg_name;const char *rsect_text;const char *data_seg_name;const char *rsect_data;const char *bss_seg_name;const char *rsect_bss;const char *const_seg_name;const char *rsect_const;const char *chip_name;const char *save_chip_name;/* Save the operands of a compare. The 16xx has not lt or gt, so   in these cases we swap the operands and reverse the condition.  */rtx dsp16xx_compare_op0;rtx dsp16xx_compare_op1;rtx (*dsp16xx_compare_gen) PARAMS (());static const char *fp;static const char *sp;static const char *rr;static const char *a1h;struct dsp16xx_frame_info current_frame_info;struct dsp16xx_frame_info zero_frame_info;rtx dsp16xx_addhf3_libcall = (rtx) 0;rtx dsp16xx_subhf3_libcall = (rtx) 0;rtx dsp16xx_mulhf3_libcall = (rtx) 0;rtx dsp16xx_divhf3_libcall = (rtx) 0;rtx dsp16xx_cmphf3_libcall = (rtx) 0;rtx dsp16xx_fixhfhi2_libcall = (rtx) 0;rtx dsp16xx_floathihf2_libcall = (rtx) 0;rtx dsp16xx_neghf2_libcall = (rtx) 0;rtx dsp16xx_mulhi3_libcall = (rtx) 0;rtx dsp16xx_udivqi3_libcall = (rtx) 0;rtx dsp16xx_udivhi3_libcall = (rtx) 0;rtx dsp16xx_divqi3_libcall = (rtx) 0;rtx dsp16xx_divhi3_libcall = (rtx) 0;rtx dsp16xx_modqi3_libcall = (rtx) 0;rtx dsp16xx_modhi3_libcall = (rtx) 0;rtx dsp16xx_umodqi3_libcall = (rtx) 0;rtx dsp16xx_umodhi3_libcall = (rtx) 0;rtx dsp16xx_ashrhi3_libcall = (rtx) 0;rtx dsp16xx_ashlhi3_libcall = (rtx) 0;rtx dsp16xx_ucmphi2_libcall = (rtx) 0;rtx dsp16xx_lshrhi3_libcall = (rtx) 0;static const char *const himode_reg_name[] = HIMODE_REGISTER_NAMES;#define SHIFT_INDEX_1   0#define SHIFT_INDEX_4   1#define SHIFT_INDEX_8   2#define SHIFT_INDEX_16  3static const char *const ashift_right_asm[] = {  "%0=%0>>1",  "%0=%0>>4",  "%0=%0>>8",  "%0=%0>>16"};static const char *const ashift_right_asm_first[] = {  "%0=%1>>1",  "%0=%1>>4",  "%0=%1>>8",  "%0=%1>>16"};static const char *const ashift_left_asm[] = {  "%0=%0<<1",  "%0=%0<<4",  "%0=%0<<8",  "%0=%0<<16"};static const char *const ashift_left_asm_first[] = {  "%0=%1<<1",  "%0=%1<<4",  "%0=%1<<8",  "%0=%1<<16"};static const char *const lshift_right_asm[] = {  "%0=%0>>1\n\t%0=%b0&0x7fff",  "%0=%0>>4\n\t%0=%b0&0x0fff",  "%0=%0>>8\n\t%0=%b0&0x00ff",  "%0=%0>>16\n\t%0=%b0&0x0000"};static const char *const lshift_right_asm_first[] = {  "%0=%1>>1\n\t%0=%b0&0x7fff",  "%0=%1>>4\n\t%0=%b0&0x0fff",  "%0=%1>>8\n\t%0=%b0&0x00ff",  "%0=%1>>16\n\t%0=%b0&0x0000"};static int reg_save_size PARAMS ((void));static void dsp16xx_output_function_prologue PARAMS ((FILE *, HOST_WIDE_INT));static void dsp16xx_output_function_epilogue PARAMS ((FILE *, HOST_WIDE_INT));/* Initialize the GCC target structure.  */#undef TARGET_ASM_BYTE_OP#define TARGET_ASM_BYTE_OP "\tint\t"#undef TARGET_ASM_ALIGNED_HI_OP#define TARGET_ASM_ALIGNED_HI_OP NULL#undef TARGET_ASM_ALIGNED_SI_OP#define TARGET_ASM_ALIGNED_SI_OP NULL#undef TARGET_ASM_FUNCTION_PROLOGUE#define TARGET_ASM_FUNCTION_PROLOGUE dsp16xx_output_function_prologue#undef TARGET_ASM_FUNCTION_EPILOGUE#define TARGET_ASM_FUNCTION_EPILOGUE dsp16xx_output_function_epiloguestruct gcc_target targetm = TARGET_INITIALIZER;int hard_regno_mode_ok (regno, mode)     int regno;     enum machine_mode mode;{  switch ((int) mode)    {    case VOIDmode:      return 1;            /* We can't use the c0-c2 for QImode, since they are only	 8 bits in length.  */    case QImode:      if (regno != REG_C0 && regno != REG_C1 && regno != REG_C2)	return 1;      else	return 0;            /* We only allow a0, a1, y, and p to be allocated for 32-bit modes.         Additionally we allow the virtual ybase registers to be used for 32-bit	 modes.  */          case HFmode:    case SFmode:    case DFmode:    case XFmode:    case HImode:    case SImode:    case DImode:      if (regno == REG_A0 || regno == REG_A1 || regno == REG_Y || regno == REG_PROD	  || (IS_YBASE_REGISTER_WINDOW(regno) && ((regno & 1) == 0)))	return 1;      else	return 0;          default:      return 0;    }}enum reg_classdsp16xx_reg_class_from_letter (c)     int c;{  switch (c)    {    case 'A':      return ACCUM_REGS;    case 'l':      return A0_REG;    case 'C':      return A1_REG;          case 'h':      return ACCUM_HIGH_REGS;          case 'j':      return A0H_REG;          case 'k':      return A0L_REG;          case 'q':      return A1H_REG;          case 'u':      return A1L_REG;          case 'x':      return X_REG;    case 'y':      return YH_REG;    case 'z':      return YL_REG;    case 't':      return P_REG;    case 'Z':      return Y_OR_P_REGS;    case 'd':      return ACCUM_Y_OR_P_REGS;    case 'a':      return Y_ADDR_REGS;    case 'B':      return (TARGET_BMU ? BMU_REGS : NO_REGS);    case 'Y':      return YBASE_VIRT_REGS;    case 'v':      return PH_REG;    case 'w':      return PL_REG;    case 'W':      return J_REG;    case 'e':      return YBASE_ELIGIBLE_REGS;    case 'b':      return ACCUM_LOW_REGS;    case 'c':      return NON_YBASE_REGS;    case 'f':      return Y_REG;    case 'D':      return SLOW_MEM_LOAD_REGS;    default:      return NO_REGS;    }}/* Return the class number of the smallest class containing   reg number REGNO.  */int regno_reg_class(regno)     int regno;{  switch (regno)    {    case REG_A0L:      return (int) A0L_REG;    case REG_A1L:      return (int) A1L_REG;          case REG_A0:      return (int) A0H_REG;    case REG_A1:      return (int) A1H_REG;          case REG_X:      return (int) X_REG;          case REG_Y:      return (int) YH_REG;    case REG_YL:      return (int) YL_REG;          case REG_PROD:      return (int) PH_REG;    case REG_PRODL:      return (int) PL_REG;          case REG_R0: case REG_R1: case REG_R2: case REG_R3:      return (int) Y_ADDR_REGS;          case REG_J:      return (int) J_REG;    case REG_K:      return (int) GENERAL_REGS;          case REG_YBASE:      return (int) GENERAL_REGS;          case REG_PT:      return (int) GENERAL_REGS;          case REG_AR0: case REG_AR1: case REG_AR2: case REG_AR3:      return (int) BMU_REGS;          case REG_C0: case REG_C1: case REG_C2:      return (int) GENERAL_REGS;          case REG_PR:      return (int) GENERAL_REGS;          case REG_RB:      return (int) GENERAL_REGS;          case REG_YBASE0: case REG_YBASE1: case REG_YBASE2: case REG_YBASE3:    case REG_YBASE4: case REG_YBASE5: case REG_YBASE6: case REG_YBASE7:    case REG_YBASE8: case REG_YBASE9: case REG_YBASE10: case REG_YBASE11:    case REG_YBASE12: case REG_YBASE13: case REG_YBASE14: case REG_YBASE15:    case REG_YBASE16: case REG_YBASE17: case REG_YBASE18: case REG_YBASE19:    case REG_YBASE20: case REG_YBASE21: case REG_YBASE22: case REG_YBASE23:    case REG_YBASE24: case REG_YBASE25: case REG_YBASE26: case REG_YBASE27:    case REG_YBASE28: case REG_YBASE29: case REG_YBASE30: case REG_YBASE31:      return (int) YBASE_VIRT_REGS;          default:      return (int) NO_REGS;    }}/* A C expression for the maximum number of consecutive registers of class CLASS   needed to hold a value of mode MODE.  */intclass_max_nregs(class, mode)     enum reg_class class ATTRIBUTE_UNUSED;     enum machine_mode mode;{    return (GET_MODE_SIZE(mode));}enum reg_classlimit_reload_class (mode, class)     enum machine_mode mode ATTRIBUTE_UNUSED;     enum reg_class class;{  return class;}intdsp16xx_register_move_cost (from, to)     enum reg_class from, to;{  if (from == A0H_REG || from == A0L_REG || from == A0_REG ||      from == A1H_REG || from == ACCUM_HIGH_REGS || from == A1L_REG ||      from == ACCUM_LOW_REGS || from == A1_REG || from == ACCUM_REGS)    {      if (to == Y_REG || to == P_REG)	return 4;      else	return 2;    }  if (to == A0H_REG || to == A0L_REG || to == A0_REG ||      to == A1H_REG || to == ACCUM_HIGH_REGS || to == A1L_REG ||      to == ACCUM_LOW_REGS || to == A1_REG || to == ACCUM_REGS)    {      return 2;    }  if (from == YBASE_VIRT_REGS)    {      if (to == YBASE_VIRT_REGS)	return 16;      if (to == X_REG || to == YH_REG || to == YL_REG ||	  to == Y_REG || to == PL_REG || to == PH_REG ||	  to == P_REG || to == Y_ADDR_REGS || to == YBASE_ELIGIBLE_REGS ||	  to == Y_OR_P_REGS)	{	  return 8;	}      else	return 10;    }  if (to == YBASE_VIRT_REGS)    {      if (from == X_REG || from == YH_REG || from == YL_REG ||	  from == Y_REG || from == PL_REG || from == PH_REG ||	  from == P_REG || from == Y_ADDR_REGS || from == YBASE_ELIGIBLE_REGS ||	  from == Y_OR_P_REGS)	{	  return 8;	}      else	return 10;    }  return 8;}/* Given an rtx X being reloaded into a reg required to be   in class CLASS, return the class of reg to actually use.   In general this is just CLASS; but on some machines   in some cases it is preferable to use a more restrictive class.   Also, we must ensure that a PLUS is reloaded either   into an accumulator or an address register.  */enum reg_classpreferred_reload_class (x, class)     rtx x;     enum reg_class class;{  /* The ybase registers cannot have constants copied directly     to them.  */  if (CONSTANT_P (x))    {      switch ((int) class)	{	case YBASE_VIRT_REGS:	  return (!reload_in_progress ? NO_REGS : class);	case ACCUM_LOW_OR_YBASE_REGS:	  return ACCUM_LOW_REGS;	case ACCUM_OR_YBASE_REGS:	  return ACCUM_REGS;	case X_OR_YBASE_REGS:	  return X_REG;	case Y_OR_YBASE_REGS:	  return Y_REG;	case ACCUM_LOW_YL_PL_OR_YBASE_REGS:	  return YL_OR_PL_OR_ACCUM_LOW_REGS;	case P_OR_YBASE_REGS:	  return P_REG;	case ACCUM_Y_P_OR_YBASE_REGS:	  return ACCUM_Y_OR_P_REGS;	case Y_ADDR_OR_YBASE_REGS:	  return Y_ADDR_REGS;	case YBASE_OR_NOHIGH_YBASE_ELIGIBLE_REGS:	  return NON_HIGH_YBASE_ELIGIBLE_REGS;;	  	case YBASE_OR_YBASE_ELIGIBLE_REGS:	  return YBASE_ELIGIBLE_REGS;	case NO_HIGH_ALL_REGS:	  return NOHIGH_NON_YBASE_REGS;	case ALL_REGS:	  return NON_YBASE_REGS;	default:	  return class;	}    }  /* If x is not an accumulator or a ybase register, restrict the class of registers     we can copy the register into.  */  if (REG_P (x) && !IS_ACCUM_REG (REGNO (x)) && !IS_YBASE_REGISTER_WINDOW (REGNO (x)))    {      switch ((int) class)	{	case NO_REGS:	case A0H_REG: case A0L_REG: case A0_REG: case A1H_REG:	case ACCUM_HIGH_REGS: case A1L_REG: case ACCUM_LOW_REGS: 	case A1_REG: case ACCUM_REGS:	  return class;	case X_REG: 	  return (!reload_in_progress ? NO_REGS : class);	case X_OR_ACCUM_LOW_REGS: 	  return ACCUM_LOW_REGS;	case X_OR_ACCUM_REGS:	  return ACCUM_REGS;	case YH_REG:	  return (!reload_in_progress ? NO_REGS : class);	case YH_OR_ACCUM_HIGH_REGS:	  return ACCUM_HIGH_REGS;	case X_OR_YH_REGS: 	case YL_REG:	  return (!reload_in_progress ? NO_REGS : class);	case YL_OR_ACCUM_LOW_REGS: 	  return ACCUM_LOW_REGS;	case X_OR_YL_REGS:	case X_OR_Y_REGS: case Y_REG:	  return (!reload_in_progress ? NO_REGS : class);	case ACCUM_OR_Y_REGS: 	  return ACCUM_REGS;	case PH_REG:	case X_OR_PH_REGS: case PL_REG: 	  return (!reload_in_progress ? NO_REGS : class);	case PL_OR_ACCUM_LOW_REGS: 	  return ACCUM_LOW_REGS;	case X_OR_PL_REGS:	  return (!reload_in_progress ? NO_REGS : class);	case YL_OR_PL_OR_ACCUM_LOW_REGS:  	  return ACCUM_LOW_REGS;	case P_REG:	  return (!reload_in_progress ? NO_REGS : class);	case ACCUM_OR_P_REGS: 	  return ACCUM_REGS;	case YL_OR_P_REGS:	  return (!reload_in_progress ? NO_REGS : class);	case ACCUM_LOW_OR_YL_OR_P_REGS:  	  return ACCUM_LOW_REGS;	case Y_OR_P_REGS:	  return (!reload_in_progress ? NO_REGS : class);	case ACCUM_Y_OR_P_REGS: 	  return ACCUM_REGS;	case NO_FRAME_Y_ADDR_REGS:	case Y_ADDR_REGS:	  return (!reload_in_progress ? NO_REGS : class);	case ACCUM_LOW_OR_Y_ADDR_REGS: 	  return ACCUM_LOW_REGS;	case ACCUM_OR_Y_ADDR_REGS: 	  return ACCUM_REGS;	case X_OR_Y_ADDR_REGS:	case Y_OR_Y_ADDR_REGS: 	case P_OR_Y_ADDR_REGS:	  return (!reload_in_progress ? NO_REGS : class);	case NON_HIGH_YBASE_ELIGIBLE_REGS:  	  return ACCUM_LOW_REGS;	case YBASE_ELIGIBLE_REGS:	  return ACCUM_REGS;	case J_REG:	case J_OR_DAU_16_BIT_REGS:	case BMU_REGS: 	  return (!reload_in_progress ? NO_REGS : class);	case YBASE_VIRT_REGS:	  if (IS_YBASE_ELIGIBLE_REG (REGNO (x)))	    return class;	  else	    return (!reload_in_progress ? NO_REGS : class);	case ACCUM_LOW_OR_YBASE_REGS:	  if (IS_YBASE_ELIGIBLE_REG (REGNO (x)))	    return class;	  else	    return ACCUM_LOW_REGS;	case ACCUM_OR_YBASE_REGS:	  if (IS_YBASE_ELIGIBLE_REG (REGNO (x)))	    return class;	  else	    return ACCUM_REGS;	case X_OR_YBASE_REGS:	case Y_OR_YBASE_REGS:	  if (IS_YBASE_ELIGIBLE_REG (REGNO (x)))	    return YBASE_VIRT_REGS;	  else	    return (!reload_in_progress ? NO_REGS : class);	case ACCUM_LOW_YL_PL_OR_YBASE_REGS:	  if (IS_YBASE_ELIGIBLE_REG (REGNO (x)))	    return ACCUM_LOW_OR_YBASE_REGS;	  else	    return ACCUM_LOW_REGS;	case P_OR_YBASE_REGS:	  if (IS_YBASE_ELIGIBLE_REG (REGNO (x)))	    return YBASE_VIRT_REGS;	  else	    return (!reload_in_progress ? NO_REGS : class);	case ACCUM_Y_P_OR_YBASE_REGS:	  if (IS_YBASE_ELIGIBLE_REG (REGNO (x)))	    return ACCUM_OR_YBASE_REGS;	  else	    return ACCUM_REGS;

⌨️ 快捷键说明

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