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

📄 dsp16xx.c

📁 gcc编译工具没有什么特别
💻 C
📖 第 1 页 / 共 4 页
字号:
/* Subroutines for assembler code output on the DSP1610.   Copyright (C) 1994, 1995, 1997, 1998 Free Software Foundation, Inc.   Contributed by Michael Collison (collison@world.std.com).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 <stdio.h>#include "rtl.h"#include "regs.h"#include "hard-reg-set.h"#include "real.h"#include "insn-config.h"#include "conditions.h"#include "insn-flags.h"#include "output.h"#include "insn-attr.h"#include "tree.h"#include "expr.h"#include "flags.h"char *text_seg_name;char *rsect_text;char *data_seg_name;char *rsect_data;char *bss_seg_name;char *rsect_bss;char *const_seg_name;char *rsect_const;char *chip_name;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;struct rtx_def *(*dsp16xx_compare_gen)();static char *fp;static char *sp;static char *rr;static 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;char *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 char *ashift_right_asm[] = {  "%0=%0>>1",  "%0=%0>>4",  "%0=%0>>8",  "%0=%0>>16"};static char *ashift_right_asm_first[] = {  "%0=%1>>1",  "%0=%1>>4",  "%0=%1>>8",  "%0=%1>>16"};static char *ashift_left_asm[] = {  "%0=%0<<1",  "%0=%0<<4",  "%0=%0<<8",  "%0=%0<<16"};static char *ashift_left_asm_first[] = {  "%0=%1<<1",  "%0=%1<<4",  "%0=%1<<8",  "%0=%1<<16"};static char *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 char *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"};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 '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 'C':      return NO_FRAME_Y_ADDR_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:      fatal ("Invalid register class letter %c", c);      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;enum machine_mode mode;{    return (GET_MODE_SIZE(mode));}enum reg_classlimit_reload_class (mode, class)enum machine_mode mode;enum reg_class class;{  switch ((int) class)    {    case NO_REGS:    case A0H_REG:    case A0L_REG:    case A0_REG:    case A1H_REG:      return class;    case ACCUM_HIGH_REGS:      fatal ("ACCUM_HIGH_REGS class in limit_reload_class");    case A1L_REG:    case ACCUM_LOW_REGS:    case A1_REG:      return class;    case ACCUM_REGS:      if (GET_MODE_SIZE(mode) == 1)	return ACCUM_LOW_REGS;      else	return class;    case X_REG:    case X_OR_ACCUM_LOW_REGS:      return class;    case X_OR_ACCUM_REGS:      if (GET_MODE_SIZE(mode) == 1)	return X_OR_ACCUM_LOW_REGS;      else	return class;    case YH_REG:      return class;    case YH_OR_ACCUM_HIGH_REGS:      fatal ("YH_OR_ACCUM_HIGH_REGS found in limit_reload_class");    case X_OR_YH_REGS:      return class;    case YL_REG:      /* Register 'yl' is invalid for QImode, so we should never	 see it. */      fatal ("YL found in limit_reload_class");    case YL_OR_ACCUM_LOW_REGS:    case X_OR_YL_REGS:      return class;    case Y_REG:      if (GET_MODE_SIZE(mode) > 1)	return class;      else	return YH_REG;    case ACCUM_OR_Y_REGS:      if (GET_MODE_SIZE(mode) > 1)	return class;      else	return YL_OR_ACCUM_LOW_REGS;    case PH_REG:    case X_OR_PH_REGS:    case PL_REG:    case PL_OR_ACCUM_LOW_REGS:    case X_OR_PL_REGS:      return class;    case P_REG:      if (GET_MODE_SIZE(mode) > 1)	return class;      else	return PL_REG;    case ACCUM_OR_P_REGS:      if (GET_MODE_SIZE(mode) > 1)	return class;      else	return PL_OR_ACCUM_LOW_REGS;    case YL_OR_P_REGS:    case ACCUM_LOW_OR_YL_OR_P_REGS:      return class;    case Y_OR_P_REGS:      return class;    case ACCUM_Y_OR_P_REGS:      if (GET_MODE_SIZE(mode) > 1)	return class;      else	return ACCUM_LOW_OR_YL_OR_P_REGS;    case NO_FRAME_Y_ADDR_REGS:    case Y_ADDR_REGS:     case ACCUM_LOW_OR_Y_ADDR_REGS:      return class;    case ACCUM_OR_Y_ADDR_REGS:      if (GET_MODE_SIZE(mode) > 1)	return ACCUM_REGS;      else	return ACCUM_LOW_OR_Y_ADDR_REGS;    case X_OR_Y_ADDR_REGS:      return class;    case Y_OR_Y_ADDR_REGS:    case P_OR_Y_ADDR_REGS:    case NON_HIGH_YBASE_ELIGIBLE_REGS:    case J_REG:      return class;    case YBASE_ELIGIBLE_REGS:      if (GET_MODE_SIZE(mode) > 1)	return ACCUM_Y_P_OR_YBASE_REGS;      else	return NON_HIGH_YBASE_ELIGIBLE_REGS;    case J_OR_DAU_16_BIT_REGS:      if (GET_MODE_SIZE(mode) == 1)	return J_REG;      else	return class;    case BMU_REGS:    case NOHIGH_NON_ADDR_REGS:      return class;    case NON_ADDR_REGS:      if (GET_MODE_SIZE(mode) > 1)	return class;      else	return NOHIGH_NON_ADDR_REGS;    case NOHIGH_NON_YBASE_REGS:      return class;    case NON_YBASE_REGS:      if (GET_MODE_SIZE(mode) > 1)	return class;      else	return NOHIGH_NON_YBASE_REGS;    case YBASE_VIRT_REGS:    case ACCUM_LOW_OR_YBASE_REGS:      return class;          case ACCUM_OR_YBASE_REGS:      if (GET_MODE_SIZE(mode) > 1)	return class;      else	return ACCUM_LOW_OR_YBASE_REGS;    case X_OR_YBASE_REGS:      return class;    case Y_OR_YBASE_REGS:    case ACCUM_LOW_YL_PL_OR_YBASE_REGS:    case P_OR_YBASE_REGS:      return class;    case ACCUM_Y_P_OR_YBASE_REGS:      return ACCUM_LOW_YL_PL_OR_YBASE_REGS;    case Y_ADDR_OR_YBASE_REGS:    case YBASE_OR_NOHIGH_YBASE_ELIGIBLE_REGS:      return class;    case YBASE_OR_YBASE_ELIGIBLE_REGS:      if (GET_MODE_SIZE(mode) > 1)	return class;      else	return YBASE_OR_NOHIGH_YBASE_ELIGIBLE_REGS;    case NO_HIGH_ALL_REGS:      return class;    case ALL_REGS:      if (GET_MODE_SIZE(mode) > 1)	return class;      else	return NO_HIGH_ALL_REGS;    default:      return class;    }}intdsp16xx_register_move_cost (from, to)enum reg_class from, to;{#if 0  if (from == NO_REGS || to == NO_REGS || (from == to))    return 2;#endif  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)    {

⌨️ 快捷键说明

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