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

📄 gmicro.c

📁 gcc-2.95.3 Linux下最常用的C编译器
💻 C
📖 第 1 页 / 共 2 页
字号:
/* Subroutines for insn-output.c for the Gmicro.   Ported by Masanobu Yuhara, Fujitsu Laboratories LTD.   (yuhara@flab.fujitsu.co.jp)   Copyright (C) 1990, 1991, 1997 Free Software Foundation, Inc.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.Among other things, the copyrightnotice and this notice must be preserved on all copies.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 <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"extern char *rtx_name[];mypr (s, a1, a2, a3, a4, a5)     char *s;     int a1, a2, a3, a4, a5;{  fprintf (stderr, s, a1, a2, a3, a4, a5);}myprcode (i)     int i;{  if (i < 0 || i > 90)    fprintf (stderr, "code = %d\n", i);  else    fprintf (stderr, "code = %s\n", rtx_name[i]);}myabort (i)     int i;{  fprintf (stderr, "myabort");  myprcode (i);}/* This is how to output an ascii string.  *//* See ASM_OUTPUT_ASCII in gmicro.h.  */output_ascii (file, p, size)     FILE *file;     char *p;     int size;{  int i;  int in_quote = 0;  register int c;  fprintf (file, "\t.sdata ");  for (i = 0; i < size; i++)     {      c = p[i];      if (c >= ' ' && c < 0x7f) 	{	  if (!in_quote) 	    {	      putc ('"', file);	      in_quote = 1;	    }	  putc (c, file);	}      else 	{	  if (in_quote) 	    {	      putc ('"', file);	      in_quote = 0;	    }	  fprintf (file, "<%d>", c);	}    }  if (in_quote)    putc ('"', file);  putc ('\n', file);}/* call this when GET_CODE (index) is MULT. */print_scaled_index (file, index)     FILE *file;     register rtx index;{  register rtx ireg;  int scale;  if (GET_CODE (XEXP (index, 0)) == REG)     {      ireg = XEXP (index, 0);      scale = INTVAL (XEXP (index, 1));    }  else     {      ireg = XEXP (index, 1);      scale = INTVAL (XEXP (index, 0));    }  if (scale == 1)    fprintf (file, "%s", reg_names[REGNO (ireg)]);  else    fprintf (file, "%s*%d", reg_names[REGNO (ireg)], scale);}    print_operand_address (file, addr)     FILE *file;     register rtx addr;{  register rtx xtmp0, xtmp1, breg, ixreg;  int scale;  int needcomma = 0;  rtx offset;  fprintf (file, "@"); retry:  switch (GET_CODE (addr))     {    case MEM:      fprintf (file, "@");      addr = XEXP (addr, 0);      goto retry;    case REG:      fprintf (file, "%s", reg_names[REGNO (addr)]);      break;    case MULT:      print_scaled_index (file, addr);      break;    case PRE_DEC:      fprintf (file, "-%s", reg_names[REGNO (XEXP (addr, 0))]);      break;    case POST_INC:      fprintf (file, "%s+", reg_names[REGNO (XEXP (addr, 0))]);      break;    case PLUS:      xtmp0 = XEXP (addr, 0);      xtmp1 = XEXP (addr, 1);      ixreg = 0;	breg = 0;      offset = 0;      if (CONSTANT_ADDRESS_P (xtmp0)) 	{	  offset = xtmp0;	  breg = xtmp1;	}      else if (CONSTANT_ADDRESS_P (xtmp1)) 	{	  offset = xtmp1;	  breg = xtmp0;	}      else 	{	  goto NOT_DISP;	}      if (REG_CODE_BASE_P (breg))	goto PRINT_MEM;      if (GET_CODE (breg) == MULT) 	{	  if (REG_CODE_INDEX_P (XEXP (breg, 0))) 	    {	      ixreg = XEXP (breg, 0);	      scale = INTVAL (XEXP (breg, 1));	      breg = 0;	    }	  else 	    {	      ixreg = XEXP (breg, 1);	      scale = INTVAL (XEXP (breg, 0));	      breg = 0;	    }	  goto PRINT_MEM;	}      /* GET_CODE (breg) must be PLUS here. */      xtmp0 = XEXP (breg, 0);      xtmp1 = XEXP (breg, 1);      if (REG_CODE_BASE_P (xtmp0)) 	{	  breg = xtmp0;	  xtmp0 = xtmp1;	}      else 	{	  breg = xtmp1;	  /* xtmp0 = xtmp0; */	}      if (GET_CODE (xtmp0) == MULT) 	{	  if (REG_CODE_INDEX_P (XEXP (xtmp0, 0))) 	    {	      ixreg = XEXP (xtmp0, 0);	      scale = INTVAL (XEXP (xtmp0, 1));	    }	  else 	    {	      ixreg = XEXP (xtmp0, 1);	      scale = INTVAL (XEXP (xtmp0, 0));	    }	}      else 	{	  ixreg = xtmp0;	  scale = 1;	}      goto PRINT_MEM;    NOT_DISP:      if (REG_CODE_BASE_P (xtmp0)) 	{	  breg = xtmp0;	  xtmp0 = xtmp1;	}      else if (REG_CODE_BASE_P (xtmp1)) 	{	  breg = xtmp1;	  /* xtmp0 = xtmp0; */	}      else	goto NOT_BASE;          if (REG_CODE_INDEX_P (xtmp0)) 	{	  ixreg = xtmp0;	  scale = 1;	  goto PRINT_MEM;	}      else if (CONSTANT_ADDRESS_P (xtmp0)) 	{	  offset = xtmp0;	  goto PRINT_MEM;	}      else if (GET_CODE (xtmp0) == MULT) 	{	  if (REG_CODE_INDEX_P (XEXP (xtmp0, 0))) 	    {	      ixreg = XEXP (xtmp0, 0);	      scale = INTVAL (XEXP (xtmp0, 1));	    }	  else 	    {	      ixreg = XEXP (xtmp0, 1);	      scale = INTVAL (XEXP (xtmp0, 0));	    }	  goto PRINT_MEM;	}      /* GET_CODE (xtmp0) must be PLUS. */      xtmp1 = XEXP (xtmp0, 1);      xtmp0 = XEXP (xtmp0, 0);      if (CONSTANT_ADDRESS_P (xtmp0)) 	{	  offset = xtmp0;	  xtmp0 = xtmp1;	}      else 	{	  offset = xtmp1;	  /* xtmp0 = xtmp0; */	}      if (REG_CODE_INDEX_P (xtmp0)) 	{	  ixreg = xtmp0;	}      else 	{			/* GET_CODE (xtmp0) must be MULT. */	  if (REG_CODE_INDEX_P (XEXP (xtmp0, 0))) 	    {	      ixreg = XEXP (xtmp0, 0);	      scale = INTVAL (XEXP (xtmp0, 1));	    }	  else 	    {	      ixreg = XEXP (xtmp0, 1);	      scale = INTVAL (XEXP (xtmp0, 0));	    }	}      goto PRINT_MEM;    NOT_BASE:      if (GET_CODE (xtmp0) == PLUS) 	{	  ixreg = xtmp1;	  /* xtmp0 = xtmp0; */	}      else 	{	  ixreg = xtmp0;	  xtmp0 = xtmp1;	}      if (REG_CODE_INDEX_P (ixreg)) 	{	  scale = 1;	}      else if (REG_CODE_INDEX_P (XEXP (ixreg, 0))) 	{	  scale = INTVAL (XEXP (ixreg, 1));	  ixreg = XEXP (ixreg, 0);	}      else 	{			/* was else if with no condition. OK ??? */	  scale = INTVAL (XEXP (ixreg, 0));	  ixreg = XEXP (ixreg, 1);	}      if (REG_CODE_BASE_P (XEXP (xtmp0, 0))) 	{	  breg = XEXP (xtmp0, 0);	  offset = XEXP (xtmp0, 1);	}      else 	{	  breg = XEXP (xtmp0, 1);	  offset = XEXP (xtmp0, 0);	}    PRINT_MEM:      if (breg == 0 && ixreg == 0) 	{	  output_address (offset);	  break;	}      else if (ixreg == 0 && offset == 0) 	{	  fprintf (file, "%s", reg_names[REGNO (breg)]);	  break;	}      else 	{	  fprintf (file, "(");	  if (offset != 0) 	    {	      output_addr_const (file, offset);	      needcomma = 1;	    }	  if (breg != 0) 	    {	      if (needcomma)		fprintf (file, ",");	      fprintf (file, "%s", reg_names[REGNO (breg)]);	      needcomma = 1;	    }	  if (ixreg != 0) 	    {	      if (needcomma)		fprintf (file, ",");	      fprintf (file, "%s", reg_names[REGNO (ixreg)]);	      if (scale != 1)		fprintf (file,"*%d", scale);	    }	  fprintf (file, ")");	  break;	}    default:      output_addr_const (file, addr);    }}/* Return a REG that occurs in ADDR with coefficient 1.   ADDR can be effectively incremented by incrementing REG.  */static rtxfind_addr_reg (addr)     rtx addr;{  while (GET_CODE (addr) == PLUS)    {      if (GET_CODE (XEXP (addr, 0)) == REG)	addr = XEXP (addr, 0);      else if (GET_CODE (XEXP (addr, 1)) == REG)	addr = XEXP (addr, 1);      else if (GET_CODE (XEXP (addr, 0)) == PLUS)	addr = XEXP (addr, 0);      else if (GET_CODE (XEXP (addr, 1)) == PLUS)	addr = XEXP (addr, 1);    }  if (GET_CODE (addr) == REG)    return addr;  return 0;}    /* Return the best assembler insn template    for moving operands[1] into operands[0] as a fullword.  */static char *singlemove_string (operands)     rtx *operands;{  if (FPU_REG_P (operands[0]) || FPU_REG_P (operands[1]))     {      if (GREG_P (operands[0]) || GREG_P (operands[1])) 	{	  myabort (101);	/* Not Supported yet !! */	}      else 	{	  return "fmov.s %1,%0";	}    }  return "mov.w %1,%0";}/* Output assembler code to perform a doubleword move insn   with operands OPERANDS.  */char *output_move_double (operands)     rtx *operands;{  enum     { REGOP, OFFSOP, MEMOP, PUSHOP, POPOP, CNSTOP, RNDOP }  optype0, optype1;  rtx latehalf[2];  rtx addreg0 = 0, addreg1 = 0;  /* First classify both operands.  */  if (REG_P (operands[0]))    optype0 = REGOP;  else if (offsettable_memref_p (operands[0]))    optype0 = OFFSOP;  else if (GET_CODE (XEXP (operands[0], 0)) == POST_INC)    optype0 = POPOP;  else if (GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)    optype0 = PUSHOP;  else if (GET_CODE (operands[0]) == MEM)    optype0 = MEMOP;  else    optype0 = RNDOP;  if (REG_P (operands[1]))    optype1 = REGOP;  else if (CONSTANT_P (operands[1]))    optype1 = CNSTOP;  else if (offsettable_memref_p (operands[1]))    optype1 = OFFSOP;  else if (GET_CODE (XEXP (operands[1], 0)) == POST_INC)    optype1 = POPOP;  else if (GET_CODE (XEXP (operands[1], 0)) == PRE_DEC)    optype1 = PUSHOP;  else if (GET_CODE (operands[1]) == MEM)    optype1 = MEMOP;  else    optype1 = RNDOP;  /* Check for the cases that the operand constraints are not     supposed to allow to happen.  Abort if we get one,     because generating code for these cases is painful.  */  if (optype0 == RNDOP || optype1 == RNDOP)    myabort (102);

⌨️ 快捷键说明

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