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

📄 c4x.c

📁 linux下编程用 编译软件
💻 C
📖 第 1 页 / 共 5 页
字号:
/* Subroutines for assembler code output on the TMS320C[34]x   Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2003,   2004, 2005   Free Software Foundation, Inc.   Contributed by Michael Hayes (m.hayes@elec.canterbury.ac.nz)              and Herman Ten Brugge (Haj.Ten.Brugge@net.HCC.nl).This file is part of GCC.GCC 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.GCC 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 GCC; see the file COPYING.  If not, write tothe Free Software Foundation, 51 Franklin Street, Fifth Floor,Boston, MA 02110-1301, USA.  *//* Some output-actions in c4x.md need these.  */#include "config.h"#include "system.h"#include "coretypes.h"#include "tm.h"#include "rtl.h"#include "tree.h"#include "regs.h"#include "hard-reg-set.h"#include "basic-block.h"#include "real.h"#include "insn-config.h"#include "insn-attr.h"#include "conditions.h"#include "output.h"#include "function.h"#include "expr.h"#include "optabs.h"#include "libfuncs.h"#include "flags.h"#include "recog.h"#include "ggc.h"#include "cpplib.h"#include "toplev.h"#include "tm_p.h"#include "target.h"#include "target-def.h"#include "langhooks.h"rtx smulhi3_libfunc;rtx umulhi3_libfunc;rtx fix_truncqfhi2_libfunc;rtx fixuns_truncqfhi2_libfunc;rtx fix_trunchfhi2_libfunc;rtx fixuns_trunchfhi2_libfunc;rtx floathiqf2_libfunc;rtx floatunshiqf2_libfunc;rtx floathihf2_libfunc;rtx floatunshihf2_libfunc;static int c4x_leaf_function;static const char *const float_reg_names[] = FLOAT_REGISTER_NAMES;/* Array of the smallest class containing reg number REGNO, indexed by   REGNO.  Used by REGNO_REG_CLASS in c4x.h.  We assume that all these   registers are available and set the class to NO_REGS for registers    that the target switches say are unavailable.  */enum reg_class c4x_regclass_map[FIRST_PSEUDO_REGISTER] ={                                /* Reg          Modes           Saved.  */  R0R1_REGS,			/* R0           QI, QF, HF      No.  */  R0R1_REGS,			/* R1           QI, QF, HF      No.  */  R2R3_REGS,			/* R2           QI, QF, HF      No.  */  R2R3_REGS,			/* R3           QI, QF, HF      No.  */  EXT_LOW_REGS,			/* R4           QI, QF, HF      QI.  */  EXT_LOW_REGS,			/* R5           QI, QF, HF      QI.  */  EXT_LOW_REGS,			/* R6           QI, QF, HF      QF.  */  EXT_LOW_REGS,			/* R7           QI, QF, HF      QF.  */  ADDR_REGS,			/* AR0          QI              No.  */  ADDR_REGS,			/* AR1          QI              No.  */  ADDR_REGS,			/* AR2          QI              No.  */  ADDR_REGS,			/* AR3          QI              QI.  */  ADDR_REGS,			/* AR4          QI              QI.  */  ADDR_REGS,			/* AR5          QI              QI.  */  ADDR_REGS,			/* AR6          QI              QI.  */  ADDR_REGS,			/* AR7          QI              QI.  */  DP_REG,			/* DP           QI              No.  */  INDEX_REGS,			/* IR0          QI              No.  */  INDEX_REGS,			/* IR1          QI              No.  */  BK_REG,			/* BK           QI              QI.  */  SP_REG,			/* SP           QI              No.  */  ST_REG,			/* ST           CC              No.  */  NO_REGS,			/* DIE/IE                       No.  */  NO_REGS,			/* IIE/IF                       No.  */  NO_REGS,			/* IIF/IOF                      No.  */  INT_REGS,			/* RS           QI              No.  */  INT_REGS,			/* RE           QI              No.  */  RC_REG,			/* RC           QI              No.  */  EXT_REGS,			/* R8           QI, QF, HF      QI.  */  EXT_REGS,			/* R9           QI, QF, HF      No.  */  EXT_REGS,			/* R10          QI, QF, HF      No.  */  EXT_REGS,			/* R11          QI, QF, HF      No.  */};enum machine_mode c4x_caller_save_map[FIRST_PSEUDO_REGISTER] ={                                /* Reg          Modes           Saved.  */  HFmode,			/* R0           QI, QF, HF      No.  */  HFmode,			/* R1           QI, QF, HF      No.  */  HFmode,			/* R2           QI, QF, HF      No.  */  HFmode,			/* R3           QI, QF, HF      No.  */  QFmode,			/* R4           QI, QF, HF      QI.  */  QFmode,			/* R5           QI, QF, HF      QI.  */  QImode,			/* R6           QI, QF, HF      QF.  */  QImode,			/* R7           QI, QF, HF      QF.  */  QImode,			/* AR0          QI              No.  */  QImode,			/* AR1          QI              No.  */  QImode,			/* AR2          QI              No.  */  QImode,			/* AR3          QI              QI.  */  QImode,			/* AR4          QI              QI.  */  QImode,			/* AR5          QI              QI.  */  QImode,			/* AR6          QI              QI.  */  QImode,			/* AR7          QI              QI.  */  VOIDmode,			/* DP           QI              No.  */  QImode,			/* IR0          QI              No.  */  QImode,			/* IR1          QI              No.  */  QImode,			/* BK           QI              QI.  */  VOIDmode,			/* SP           QI              No.  */  VOIDmode,			/* ST           CC              No.  */  VOIDmode,			/* DIE/IE                       No.  */  VOIDmode,			/* IIE/IF                       No.  */  VOIDmode,			/* IIF/IOF                      No.  */  QImode,			/* RS           QI              No.  */  QImode,			/* RE           QI              No.  */  VOIDmode,			/* RC           QI              No.  */  QFmode,			/* R8           QI, QF, HF      QI.  */  HFmode,			/* R9           QI, QF, HF      No.  */  HFmode,			/* R10          QI, QF, HF      No.  */  HFmode,			/* R11          QI, QF, HF      No.  */};/* Test and compare insns in c4x.md store the information needed to   generate branch and scc insns here.  */rtx c4x_compare_op0;rtx c4x_compare_op1;int c4x_cpu_version = 40;	/* CPU version C30/31/32/33/40/44.  *//* Pragma definitions.  */tree code_tree = NULL_TREE;tree data_tree = NULL_TREE;tree pure_tree = NULL_TREE;tree noreturn_tree = NULL_TREE;tree interrupt_tree = NULL_TREE;tree naked_tree = NULL_TREE;/* Forward declarations */static bool c4x_handle_option (size_t, const char *, int);static int c4x_isr_reg_used_p (unsigned int);static int c4x_leaf_function_p (void);static int c4x_naked_function_p (void);static int c4x_immed_int_constant (rtx);static int c4x_immed_float_constant (rtx);static int c4x_R_indirect (rtx);static void c4x_S_address_parse (rtx , int *, int *, int *, int *);static int c4x_valid_operands (enum rtx_code, rtx *, enum machine_mode, int);static int c4x_arn_reg_operand (rtx, enum machine_mode, unsigned int);static int c4x_arn_mem_operand (rtx, enum machine_mode, unsigned int);static void c4x_file_start (void);static void c4x_file_end (void);static void c4x_check_attribute (const char *, tree, tree, tree *);static int c4x_r11_set_p (rtx);static int c4x_rptb_valid_p (rtx, rtx);static void c4x_reorg (void);static int c4x_label_ref_used_p (rtx, rtx);static tree c4x_handle_fntype_attribute (tree *, tree, tree, int, bool *);const struct attribute_spec c4x_attribute_table[];static void c4x_insert_attributes (tree, tree *);static void c4x_asm_named_section (const char *, unsigned int, tree);static int c4x_adjust_cost (rtx, rtx, rtx, int);static void c4x_globalize_label (FILE *, const char *);static bool c4x_rtx_costs (rtx, int, int, int *);static int c4x_address_cost (rtx);static void c4x_init_libfuncs (void);static void c4x_external_libcall (rtx);static rtx c4x_struct_value_rtx (tree, int);static tree c4x_gimplify_va_arg_expr (tree, tree, tree *, tree *);/* Initialize the GCC target structure.  */#undef TARGET_ASM_BYTE_OP#define TARGET_ASM_BYTE_OP "\t.word\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_FILE_START#define TARGET_ASM_FILE_START c4x_file_start#undef TARGET_ASM_FILE_START_FILE_DIRECTIVE#define TARGET_ASM_FILE_START_FILE_DIRECTIVE true#undef TARGET_ASM_FILE_END#define TARGET_ASM_FILE_END c4x_file_end#undef TARGET_ASM_EXTERNAL_LIBCALL#define TARGET_ASM_EXTERNAL_LIBCALL c4x_external_libcall/* Play safe, not the fastest code.  */#undef TARGET_DEFAULT_TARGET_FLAGS#define TARGET_DEFAULT_TARGET_FLAGS (MASK_ALIASES | MASK_PARALLEL \				     | MASK_PARALLEL_MPY | MASK_RPTB)#undef TARGET_HANDLE_OPTION#define TARGET_HANDLE_OPTION c4x_handle_option#undef TARGET_ATTRIBUTE_TABLE#define TARGET_ATTRIBUTE_TABLE c4x_attribute_table#undef TARGET_INSERT_ATTRIBUTES#define TARGET_INSERT_ATTRIBUTES c4x_insert_attributes#undef TARGET_INIT_BUILTINS#define TARGET_INIT_BUILTINS c4x_init_builtins#undef TARGET_EXPAND_BUILTIN#define TARGET_EXPAND_BUILTIN c4x_expand_builtin#undef TARGET_SCHED_ADJUST_COST#define TARGET_SCHED_ADJUST_COST c4x_adjust_cost#undef TARGET_ASM_GLOBALIZE_LABEL#define TARGET_ASM_GLOBALIZE_LABEL c4x_globalize_label#undef TARGET_RTX_COSTS#define TARGET_RTX_COSTS c4x_rtx_costs#undef TARGET_ADDRESS_COST#define TARGET_ADDRESS_COST c4x_address_cost#undef TARGET_MACHINE_DEPENDENT_REORG#define TARGET_MACHINE_DEPENDENT_REORG c4x_reorg#undef TARGET_INIT_LIBFUNCS#define TARGET_INIT_LIBFUNCS c4x_init_libfuncs#undef TARGET_STRUCT_VALUE_RTX#define TARGET_STRUCT_VALUE_RTX c4x_struct_value_rtx#undef TARGET_GIMPLIFY_VA_ARG_EXPR#define TARGET_GIMPLIFY_VA_ARG_EXPR c4x_gimplify_va_arg_exprstruct gcc_target targetm = TARGET_INITIALIZER;/* Implement TARGET_HANDLE_OPTION.  */static boolc4x_handle_option (size_t code, const char *arg, int value){  switch (code)    {    case OPT_m30: c4x_cpu_version = 30; return true;    case OPT_m31: c4x_cpu_version = 31; return true;    case OPT_m32: c4x_cpu_version = 32; return true;    case OPT_m33: c4x_cpu_version = 33; return true;    case OPT_m40: c4x_cpu_version = 40; return true;    case OPT_m44: c4x_cpu_version = 44; return true;    case OPT_mcpu_:      if (arg[0] == 'c' || arg[0] == 'C')	arg++;      value = atoi (arg);      switch (value)	{	case 30: case 31: case 32: case 33: case 40: case 44:	  c4x_cpu_version = value;	  return true;	}      return false;    default:      return true;    }}/* Override command line options.   Called once after all options have been parsed.   Mostly we process the processor   type and sometimes adjust other TARGET_ options.  */voidc4x_override_options (void){  /* Convert foo / 8.0 into foo * 0.125, etc.  */  set_fast_math_flags (1);  /* We should phase out the following at some stage.     This provides compatibility with the old -mno-aliases option.  */  if (! TARGET_ALIASES && ! flag_argument_noalias)    flag_argument_noalias = 1;  if (!TARGET_C3X)    target_flags |= MASK_MPYI | MASK_DB;  if (optimize < 2)    target_flags &= ~(MASK_RPTB | MASK_PARALLEL);  if (!TARGET_PARALLEL)    target_flags &= ~MASK_PARALLEL_MPY;}/* This is called before c4x_override_options.  */voidc4x_optimization_options (int level ATTRIBUTE_UNUSED,			  int size ATTRIBUTE_UNUSED){  /* Scheduling before register allocation can screw up global     register allocation, especially for functions that use MPY||ADD     instructions.  The benefit we gain we get by scheduling before     register allocation is probably marginal anyhow.  */  flag_schedule_insns = 0;}/* Write an ASCII string.  */#define C4X_ASCII_LIMIT 40voidc4x_output_ascii (FILE *stream, const char *ptr, int len){  char sbuf[C4X_ASCII_LIMIT + 1];  int s, l, special, first = 1, onlys;  if (len)      fprintf (stream, "\t.byte\t");  for (s = l = 0; len > 0; --len, ++ptr)    {      onlys = 0;      /* Escape " and \ with a \".  */      special = *ptr == '\"' || *ptr == '\\';      /* If printable - add to buff.  */      if ((! TARGET_TI || ! special) && *ptr >= 0x20 && *ptr < 0x7f)	{	  if (special)	    sbuf[s++] = '\\';	  sbuf[s++] = *ptr;	  if (s < C4X_ASCII_LIMIT - 1)	    continue;	  onlys = 1;	}      if (s)	{	  if (first)	    first = 0;	  else	    {	      fputc (',', stream);	      l++;	    }	  sbuf[s] = 0;	  fprintf (stream, "\"%s\"", sbuf);	  l += s + 2;	  if (TARGET_TI && l >= 80 && len > 1)	    {	      fprintf (stream, "\n\t.byte\t");	      first = 1;	      l = 0;	    }		  s = 0;	}      if (onlys)	continue;      if (first)	first = 0;      else	{	  fputc (',', stream);	  l++;	}      fprintf (stream, "%d", *ptr);      l += 3;      if (TARGET_TI && l >= 80 && len > 1)	{	  fprintf (stream, "\n\t.byte\t");	  first = 1;	  l = 0;	}    }  if (s)    {      if (! first)	fputc (',', stream);      sbuf[s] = 0;      fprintf (stream, "\"%s\"", sbuf);      s = 0;    }  fputc ('\n', stream);}intc4x_hard_regno_mode_ok (unsigned int regno, enum machine_mode mode){  switch (mode)    {#if Pmode != QImode    case Pmode:			/* Pointer (24/32 bits).  */#endif    case QImode:		/* Integer (32 bits).  */      return IS_INT_REGNO (regno);    case QFmode:		/* Float, Double (32 bits).  */    case HFmode:		/* Long Double (40 bits).  */      return IS_EXT_REGNO (regno);    case CCmode:		/* Condition Codes.  */    case CC_NOOVmode:		/* Condition Codes.  */      return IS_ST_REGNO (regno);    case HImode:		/* Long Long (64 bits).  */      /* We need two registers to store long longs.  Note that 	 it is much easier to constrain the first register	 to start on an even boundary.  */      return IS_INT_REGNO (regno)	&& IS_INT_REGNO (regno + 1)	&& (regno & 1) == 0;    default:      return 0;			/* We don't support these modes.  */    }  return 0;}/* Return nonzero if REGNO1 can be renamed to REGNO2.  */intc4x_hard_regno_rename_ok (unsigned int regno1, unsigned int regno2){  /* We cannot copy call saved registers from mode QI into QF or from     mode QF into QI.  */  if (IS_FLOAT_CALL_SAVED_REGNO (regno1) && IS_INT_CALL_SAVED_REGNO (regno2))    return 0;  if (IS_INT_CALL_SAVED_REGNO (regno1) && IS_FLOAT_CALL_SAVED_REGNO (regno2))    return 0;  /* We cannot copy from an extended (40 bit) register to a standard     (32 bit) register because we only set the condition codes for     extended registers.  */  if (IS_EXT_REGNO (regno1) && ! IS_EXT_REGNO (regno2))    return 0;  if (IS_EXT_REGNO (regno2) && ! IS_EXT_REGNO (regno1))    return 0;  return 1;}/* The TI C3x C compiler register argument runtime model uses 6 registers,   AR2, R2, R3, RC, RS, RE.   The first two floating point arguments (float, double, long double)   that are found scanning from left to right are assigned to R2 and R3.

⌨️ 快捷键说明

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