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

📄 rs6000.c

📁 gcc-2.95.3 Linux下最常用的C编译器
💻 C
📖 第 1 页 / 共 5 页
字号:
/* Subroutines used for code generation on IBM RS/6000.   Copyright (C) 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001   Free Software Foundation, Inc.   Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)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.  */#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 "insn-flags.h"#include "insn-attr.h"#include "flags.h"#include "recog.h"#include "expr.h"#include "obstack.h"#include "tree.h"#include "except.h"#include "function.h"#include "output.h"#include "toplev.h"#ifndef TARGET_NO_PROTOTYPE#define TARGET_NO_PROTOTYPE 0#endifextern char *language_string;extern int profile_block_flag;#define min(A,B)	((A) < (B) ? (A) : (B))#define max(A,B)	((A) > (B) ? (A) : (B))/* Target cpu type */enum processor_type rs6000_cpu;struct rs6000_cpu_select rs6000_select[3] ={  /* switch		name,			tune	arch */  { (const char *)0,	"--with-cpu=",		1,	1 },  { (const char *)0,	"-mcpu=",		1,	1 },  { (const char *)0,	"-mtune=",		1,	0 },};/* Set to non-zero by "fix" operation to indicate that itrunc and   uitrunc must be defined.  */int rs6000_trunc_used;/* Set to non-zero once they have been defined.  */static int trunc_defined;/* Set to non-zero once AIX common-mode calls have been defined.  */static int common_mode_defined;/* Save information from a "cmpxx" operation until the branch or scc is   emitted.  */rtx rs6000_compare_op0, rs6000_compare_op1;int rs6000_compare_fp_p;#ifdef USING_SVR4_H/* Label number of label created for -mrelocatable, to call to so we can   get the address of the GOT section */int rs6000_pic_labelno;int rs6000_pic_func_labelno;/* Which abi to adhere to */const char *rs6000_abi_name = RS6000_ABI_NAME;/* Semantics of the small data area */enum rs6000_sdata_type rs6000_sdata = SDATA_DATA;/* Which small data model to use */const char *rs6000_sdata_name = (char *)0;#endif/* Whether a System V.4 varargs area was created.  */int rs6000_sysv_varargs_p;/* ABI enumeration available for subtarget to use.  */enum rs6000_abi rs6000_current_abi;/* Offset & size for fpmem stack locations used for converting between   float and integral types.  */int rs6000_fpmem_offset;int rs6000_fpmem_size;/* Debug flags */const char *rs6000_debug_name;int rs6000_debug_stack;		/* debug stack applications */int rs6000_debug_arg;		/* debug argument handling *//* Flag to say the TOC is initialized */int toc_initialized;/* Default register names.  */char rs6000_reg_names[][8] ={      "0",  "1",  "2",  "3",  "4",  "5",  "6",  "7",      "8",  "9", "10", "11", "12", "13", "14", "15",     "16", "17", "18", "19", "20", "21", "22", "23",     "24", "25", "26", "27", "28", "29", "30", "31",      "0",  "1",  "2",  "3",  "4",  "5",  "6",  "7",      "8",  "9", "10", "11", "12", "13", "14", "15",     "16", "17", "18", "19", "20", "21", "22", "23",     "24", "25", "26", "27", "28", "29", "30", "31",     "mq", "lr", "ctr","ap",      "0",  "1",  "2",  "3",  "4",  "5",  "6",  "7",  "fpmem"};#ifdef TARGET_REGNAMESstatic char alt_reg_names[][8] ={   "%r0",   "%r1",  "%r2",  "%r3",  "%r4",  "%r5",  "%r6",  "%r7",   "%r8",   "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15",  "%r16",  "%r17", "%r18", "%r19", "%r20", "%r21", "%r22", "%r23",  "%r24",  "%r25", "%r26", "%r27", "%r28", "%r29", "%r30", "%r31",   "%f0",   "%f1",  "%f2",  "%f3",  "%f4",  "%f5",  "%f6",  "%f7",   "%f8",   "%f9", "%f10", "%f11", "%f12", "%f13", "%f14", "%f15",  "%f16",  "%f17", "%f18", "%f19", "%f20", "%f21", "%f22", "%f23",  "%f24",  "%f25", "%f26", "%f27", "%f28", "%f29", "%f30", "%f31",    "mq",    "lr",  "ctr",   "ap",  "%cr0",  "%cr1", "%cr2", "%cr3", "%cr4", "%cr5", "%cr6", "%cr7", "fpmem"};#endif#ifndef MASK_STRICT_ALIGN#define MASK_STRICT_ALIGN 0#endif/* Override command line options.  Mostly we process the processor   type and sometimes adjust other TARGET_ options.  */voidrs6000_override_options (default_cpu)     const char *default_cpu;{  size_t i, j;  struct rs6000_cpu_select *ptr;  /* Simplify the entries below by making a mask for any POWER     variant and any PowerPC variant.  */#define POWER_MASKS (MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING)#define POWERPC_MASKS (MASK_POWERPC | MASK_PPC_GPOPT \		       | MASK_PPC_GFXOPT | MASK_POWERPC64)#define POWERPC_OPT_MASKS (MASK_PPC_GPOPT | MASK_PPC_GFXOPT)  static struct ptt    {      const char *name;		/* Canonical processor name.  */      enum processor_type processor; /* Processor type enum value.  */      int target_enable;	/* Target flags to enable.  */      int target_disable;	/* Target flags to disable.  */    } processor_target_table[]      = {{"common", PROCESSOR_COMMON, MASK_NEW_MNEMONICS,	    POWER_MASKS | POWERPC_MASKS},	 {"power", PROCESSOR_POWER,	    MASK_POWER | MASK_MULTIPLE | MASK_STRING,	    MASK_POWER2 | POWERPC_MASKS | MASK_NEW_MNEMONICS},	 {"power2", PROCESSOR_POWER,	    MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING,	    POWERPC_MASKS | MASK_NEW_MNEMONICS},	 {"powerpc", PROCESSOR_POWERPC,	    MASK_POWERPC | MASK_NEW_MNEMONICS,	    POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},	 {"rios", PROCESSOR_RIOS1,	    MASK_POWER | MASK_MULTIPLE | MASK_STRING,	    MASK_POWER2 | POWERPC_MASKS | MASK_NEW_MNEMONICS},	 {"rios1", PROCESSOR_RIOS1,	    MASK_POWER | MASK_MULTIPLE | MASK_STRING,	    MASK_POWER2 | POWERPC_MASKS | MASK_NEW_MNEMONICS},	 {"rsc", PROCESSOR_PPC601,	    MASK_POWER | MASK_MULTIPLE | MASK_STRING,	    MASK_POWER2 | POWERPC_MASKS | MASK_NEW_MNEMONICS},	 {"rsc1", PROCESSOR_PPC601,	    MASK_POWER | MASK_MULTIPLE | MASK_STRING,	    MASK_POWER2 | POWERPC_MASKS | MASK_NEW_MNEMONICS},	 {"rios2", PROCESSOR_RIOS2,	    MASK_POWER | MASK_MULTIPLE | MASK_STRING | MASK_POWER2,	    POWERPC_MASKS | MASK_NEW_MNEMONICS},	 {"401", PROCESSOR_PPC403,	    MASK_POWERPC | MASK_SOFT_FLOAT | MASK_NEW_MNEMONICS,	    POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},	 {"403", PROCESSOR_PPC403,	    MASK_POWERPC | MASK_SOFT_FLOAT | MASK_NEW_MNEMONICS | MASK_STRICT_ALIGN,	    POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},	 {"505", PROCESSOR_MPCCORE,	    MASK_POWERPC | MASK_NEW_MNEMONICS,	    POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},	 {"601", PROCESSOR_PPC601,	    MASK_POWER | MASK_POWERPC | MASK_NEW_MNEMONICS | MASK_MULTIPLE | MASK_STRING,	    MASK_POWER2 | POWERPC_OPT_MASKS | MASK_POWERPC64},	 {"602", PROCESSOR_PPC603,	    MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,	    POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},	 {"603", PROCESSOR_PPC603,	    MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,	    POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},	 {"603e", PROCESSOR_PPC603,	    MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,	    POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},	 {"ec603e", PROCESSOR_PPC603,	    MASK_POWERPC | MASK_SOFT_FLOAT | MASK_NEW_MNEMONICS,	    POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},	 {"604", PROCESSOR_PPC604,	    MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,	    POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},	 {"604e", PROCESSOR_PPC604e,	    MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,	    POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},	 {"620", PROCESSOR_PPC620,	    MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,	    POWER_MASKS | MASK_PPC_GPOPT},	 {"740", PROCESSOR_PPC750, 	    MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS, 	    POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},	 {"750", PROCESSOR_PPC750, 	    MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS, 	    POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},	 {"801", PROCESSOR_MPCCORE,	    MASK_POWERPC | MASK_SOFT_FLOAT | MASK_NEW_MNEMONICS,	    POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},	 {"821", PROCESSOR_MPCCORE,	    MASK_POWERPC | MASK_SOFT_FLOAT | MASK_NEW_MNEMONICS,	    POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},	 {"823", PROCESSOR_MPCCORE,	    MASK_POWERPC | MASK_SOFT_FLOAT | MASK_NEW_MNEMONICS,	    POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},	 {"860", PROCESSOR_MPCCORE,	    MASK_POWERPC | MASK_SOFT_FLOAT | MASK_NEW_MNEMONICS,	    POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64}};  size_t ptt_size = sizeof (processor_target_table) / sizeof (struct ptt);  int multiple = TARGET_MULTIPLE;	/* save current -mmultiple/-mno-multiple status */  int string   = TARGET_STRING;		/* save current -mstring/-mno-string status */  profile_block_flag = 0;  /* Identify the processor type */  rs6000_select[0].string = default_cpu;  rs6000_cpu = PROCESSOR_DEFAULT;  for (i = 0; i < sizeof (rs6000_select) / sizeof (rs6000_select[0]); i++)    {      ptr = &rs6000_select[i];      if (ptr->string != (char *)0 && ptr->string[0] != '\0')	{	  for (j = 0; j < ptt_size; j++)	    if (! strcmp (ptr->string, processor_target_table[j].name))	      {		if (ptr->set_tune_p)		  rs6000_cpu = processor_target_table[j].processor;		if (ptr->set_arch_p)		  {		    target_flags |= processor_target_table[j].target_enable;		    target_flags &= ~processor_target_table[j].target_disable;		  }		break;	      }	  if (i == ptt_size)	    error ("bad value (%s) for %s switch", ptr->string, ptr->name);	}    }  /* If we are optimizing big endian systems for space, use the     store multiple instructions.  */  if (BYTES_BIG_ENDIAN && optimize_size)    target_flags |= MASK_MULTIPLE;  /* If -mmultiple or -mno-multiple was explicitly used, don't     override with the processor default */  if (TARGET_MULTIPLE_SET)    target_flags = (target_flags & ~MASK_MULTIPLE) | multiple;  /* If -mstring or -mno-string was explicitly used, don't     override with the processor default */  if (TARGET_STRING_SET)    target_flags = (target_flags & ~MASK_STRING) | string;  /* Don't allow -mmultiple or -mstring on little endian systems unless the cpu     is a 750, because the hardware doesn't support the instructions used in     little endian mode, and causes an alignment trap.  The 750 does not cause     an alignment trap (except when the target is unaligned).  */  if (! BYTES_BIG_ENDIAN && rs6000_cpu != PROCESSOR_PPC750)    {      if (TARGET_MULTIPLE)	{	  target_flags &= ~MASK_MULTIPLE;	  if (TARGET_MULTIPLE_SET)	    warning ("-mmultiple is not supported on little endian systems");	}      if (TARGET_STRING)	{	  target_flags &= ~MASK_STRING;	  if (TARGET_STRING_SET)	    warning ("-mstring is not supported on little endian systems");	}    }  if (flag_pic && (DEFAULT_ABI == ABI_AIX))    {      warning ("-f%s ignored for AIX (all code is position independent)",	       (flag_pic > 1) ? "PIC" : "pic");      flag_pic = 0;    }  /* Set debug flags */  if (rs6000_debug_name)    {      if (! strcmp (rs6000_debug_name, "all"))	rs6000_debug_stack = rs6000_debug_arg = 1;      else if (! strcmp (rs6000_debug_name, "stack"))	rs6000_debug_stack = 1;      else if (! strcmp (rs6000_debug_name, "arg"))	rs6000_debug_arg = 1;      else	error ("Unknown -mdebug-%s switch", rs6000_debug_name);    }#ifdef TARGET_REGNAMES  /* If the user desires alternate register names, copy in the alternate names     now.  */  if (TARGET_REGNAMES)    bcopy ((char *)alt_reg_names, (char *)rs6000_reg_names,	   sizeof (rs6000_reg_names));#endif#ifdef SUBTARGET_OVERRIDE_OPTIONS  SUBTARGET_OVERRIDE_OPTIONS;#endif}voidoptimization_options (level, size)     int level;     int size ATTRIBUTE_UNUSED;{#ifdef HAVE_decrement_and_branch_on_count  /* When optimizing, enable use of BCT instruction.  */  if (level >= 1)      flag_branch_on_count_reg = 1;#endif}/* Do anything needed at the start of the asm file.  */voidrs6000_file_start (file, default_cpu)     FILE *file;     const char *default_cpu;{  size_t i;  char buffer[80];  const char *start = buffer;  struct rs6000_cpu_select *ptr;  if (flag_verbose_asm)    {      sprintf (buffer, "\n%s rs6000/powerpc options:", ASM_COMMENT_START);      rs6000_select[0].string = default_cpu;      for (i = 0; i < sizeof (rs6000_select) / sizeof (rs6000_select[0]); i++)	{	  ptr = &rs6000_select[i];	  if (ptr->string != (char *)0 && ptr->string[0] != '\0')	    {	      fprintf (file, "%s %s%s", start, ptr->name, ptr->string);	      start = "";	    }	}#ifdef USING_SVR4_H      switch (rs6000_sdata)	{	case SDATA_NONE: fprintf (file, "%s -msdata=none", start); start = ""; break;	case SDATA_DATA: fprintf (file, "%s -msdata=data", start); start = ""; break;	case SDATA_SYSV: fprintf (file, "%s -msdata=sysv", start); start = ""; break;	case SDATA_EABI: fprintf (file, "%s -msdata=eabi", start); start = ""; break;	}      if (rs6000_sdata && g_switch_value)	{	  fprintf (file, "%s -G %d", start, g_switch_value);	  start = "";	}#endif      if (*start == '\0')	fputs ("\n", file);    }}/* Create a CONST_DOUBLE from a string.  */struct rtx_def *rs6000_float_const (string, mode)     const char *string;     enum machine_mode mode;{  REAL_VALUE_TYPE value = REAL_VALUE_ATOF (string, mode);  return immed_real_const_1 (value, mode);}/* Return non-zero if this function is known to have a null epilogue.  */intdirect_return (){  if (reload_completed)    {      rs6000_stack_t *info = rs6000_stack_info ();      if (info->first_gp_reg_save == 32	  && info->first_fp_reg_save == 64	  && !info->lr_save_p	  && !info->cr_save_p	  && !info->push_p)	return 1;    }  return 0;}/* Returns 1 always.  */intany_operand (op, mode)     register rtx op ATTRIBUTE_UNUSED;     enum machine_mode mode ATTRIBUTE_UNUSED;{  return 1;}/* Returns 1 if op is the count register */intcount_register_operand(op, mode)     register rtx op;     enum machine_mode mode ATTRIBUTE_UNUSED;{

⌨️ 快捷键说明

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