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

📄 1750a.c

📁 gcc3.2.1源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* Subroutines for insn-output.c for MIL-STD-1750.   Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999,   2000 Free Software Foundation, Inc.   Contributed by O.M.Kellogg, DASA (kellogg@space.otn.dasa.de)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.  */#define __datalbl#include "config.h"#include "system.h"#include "rtl.h"#include "tree.h"#include "function.h"#include "expr.h"#define HAVE_cc0#include "conditions.h"#include "real.h"#include "regs.h"#include "output.h"#include "flags.h"#include "tm_p.h"#include "target.h"#include "target-def.h"struct datalabel_array datalbl[DATALBL_ARRSIZ];int datalbl_ndx = -1;struct jumplabel_array jmplbl[JMPLBL_ARRSIZ];int jmplbl_ndx = -1;int label_pending = 0, program_counter = 0;enum section current_section = Normal;const char *const sectname[4] ={"Init", "Normal", "Konst", "Static"};static int which_bit PARAMS ((int));static bool assemble_integer_1750a PARAMS ((rtx, unsigned int, int));static void output_function_prologue PARAMS ((FILE *, HOST_WIDE_INT));static void output_function_epilogue PARAMS ((FILE *, HOST_WIDE_INT));/* Initialize the GCC target structure.  */#undef TARGET_ASM_BYTE_OP#define TARGET_ASM_BYTE_OP "\tdata\t"#undef TARGET_ASM_ALIGNED_HI_OP#define TARGET_ASM_ALIGNED_HI_OP "\tdatal\t"#undef TARGET_ASM_ALIGNED_SI_OP#define TARGET_ASM_ALIGNED_SI_OP NULL#undef TARGET_ASM_INTEGER#define TARGET_ASM_INTEGER assemble_integer_1750a#undef TARGET_ASM_FUNCTION_PROLOGUE#define TARGET_ASM_FUNCTION_PROLOGUE output_function_prologue#undef TARGET_ASM_FUNCTION_EPILOGUE#define TARGET_ASM_FUNCTION_EPILOGUE output_function_epiloguestruct gcc_target targetm = TARGET_INITIALIZER;/* Generate the assembly code for function entry.  FILE is a stdio   stream to output the code to.  SIZE is an int: how many units of   temporary storage to allocate.   Refer to the array `regs_ever_live' to determine which registers to   save; `regs_ever_live[I]' is nonzero if register number I is ever   used in the function.  This function is responsible for knowing   which registers should not be saved even if used.  */static voidoutput_function_prologue (file, size)     FILE *file;     HOST_WIDE_INT size;{  if (flag_verbose_asm)    {      int regno, regs_used = 0;      fprintf (file, "\t; registers used: ");      for (regno = 0; regno < 14; regno++)	if (regs_ever_live[regno])	  {	    fprintf (file, " %s", reg_names[regno]);	    regs_used++;	  }      if (regs_used == 0)	fprintf (file, "(none)");    }  if (size > 0)    {      fprintf (file, "\n\t%s\tr15,%d",	       (size <= 16 ? "sisp" : "sim"), size);      if (flag_verbose_asm)	fprintf (file, "  ; reserve local-variable space");    }  if (frame_pointer_needed)    {      fprintf(file, "\n\tpshm\tr14,r14");      if (flag_verbose_asm)	fprintf (file, "  ; push old frame");      fprintf (file, "\n\tlr\tr14,r15");      if (flag_verbose_asm)	fprintf (file, "  ; set new frame");    }  fprintf (file, "\n");  program_counter = 0;  jmplbl_ndx = -1;}/* This function generates the assembly code for function exit.   Args are as for output_function_prologue ().   The function epilogue should not depend on the current stack   pointer!  It should use the frame pointer only.  This is mandatory   because of alloca; we also take advantage of it to omit stack   adjustments before returning.  */static voidoutput_function_epilogue (file, size)     FILE *file;     HOST_WIDE_INT size;{  if (frame_pointer_needed)    {      fprintf (file, "\tlr\tr15,r14");      if (flag_verbose_asm)        fprintf (file, "  ; set stack ptr to frame ptr");      fprintf (file, "\n\tpopm\tr14,r14");      if (flag_verbose_asm)        fprintf (file, "  ; restore previous frame ptr");      fprintf (file, "\n");    }  if (size > 0)    {      fprintf (file, "\t%s\tr15,%d",	       (size <= 16 ? "aisp" : "aim"), size);      if (flag_verbose_asm)	fprintf (file, "  ; free up local-var space");      fprintf (file, "\n");    }  fprintf (file, "\turs\tr15\n\n");}voidnotice_update_cc (exp)     rtx exp;{  if (GET_CODE (exp) == SET)    {      enum rtx_code src_code = GET_CODE (SET_SRC (exp));      /* Jumps do not alter the cc's.  */      if (SET_DEST (exp) == pc_rtx)	return;      /* Moving a register or constant into memory doesn't alter the cc's.  */      if (GET_CODE (SET_DEST (exp)) == MEM	  && (src_code == REG || src_code == CONST_INT))	return;      /* Function calls clobber the cc's.  */      if (src_code == CALL)	{	  CC_STATUS_INIT;	  return;	}      /* Emulated longword bit-ops leave cc's incorrect */      if (GET_MODE (SET_DEST (exp)) == HImode ?	       src_code == AND || src_code == IOR ||	       src_code == XOR || src_code == NOT : 0)	{	  CC_STATUS_INIT;	  return;	}      /* Tests and compares set the cc's in predictable ways.  */      if (SET_DEST (exp) == cc0_rtx)	{	  CC_STATUS_INIT;	  cc_status.value1 = SET_SRC (exp);	  return;	}      /* Anything else will set cc_status.  */      cc_status.flags = CC_NO_OVERFLOW;      cc_status.value1 = SET_SRC (exp);      cc_status.value2 = SET_DEST (exp);      return;    }  else if (GET_CODE (exp) == PARALLEL	   && GET_CODE (XVECEXP (exp, 0, 0)) == SET)    {      if (SET_DEST (XVECEXP (exp, 0, 0)) == pc_rtx)	return;      if (SET_DEST (XVECEXP (exp, 0, 0)) == cc0_rtx)	{	  CC_STATUS_INIT;	  cc_status.value1 = SET_SRC (XVECEXP (exp, 0, 0));	  return;	}      CC_STATUS_INIT;    }  else    {      CC_STATUS_INIT;    }}rtxfunction_arg (cum, mode, type, named)     int cum;     enum machine_mode mode;     tree type;     int named ATTRIBUTE_UNUSED;{  int size;  if (MUST_PASS_IN_STACK (mode, type))    return (rtx) 0;  if (mode == BLKmode)    size = int_size_in_bytes (type);  else    size = GET_MODE_SIZE (mode);  if (cum + size < 12)    return gen_rtx_REG (mode, cum);  else    return (rtx) 0;}doubleget_double (x)     rtx x;{  union    {      double d;      long i[2];    }  du;  du.i[0] = CONST_DOUBLE_LOW (x);  du.i[1] = CONST_DOUBLE_HIGH (x);  return du.d;}char *float_label (code, value)     int code;     double value;{  static char label[32];  char *p;  label[0] = code;  p = label + 1;  sprintf (p, "%f", value);  while (*p)    {      *p = (*p == '+') ? 'p' :	(*p == '-') ? 'm' : *p;      p++;    }  return xstrdup (label);}const char *movcnt_regno_adjust (op)     rtx *op;{  static char outstr[80];  int op0r = REGNO (op[0]), op1r = REGNO (op[1]), op2r = REGNO (op[2]);#define dstreg op0r#define srcreg op1r#define cntreg op2r#define cntreg_1750 (op0r + 1)  if (cntreg == cntreg_1750)    sprintf (outstr, "mov r%d,r%d", op0r, op1r);  else if (dstreg + 1 == srcreg && cntreg > srcreg)    sprintf (outstr, "xwr r%d,r%d\n\tmov r%d,r%d", op2r, op1r, op0r, op2r);  else if (dstreg == cntreg + 1)    sprintf (outstr, "xwr r%d,r%d\n\tmov r%d,r%d", op0r, op2r, op2r, op1r);  else if (dstreg == srcreg + 1)    sprintf (outstr, "xwr r%d,r%d\n\txwr r%d,r%d\n\tmov r%d,r%d",	     op0r, op1r, op0r, op2r, op1r, op2r);  else if (cntreg + 1 == srcreg)    sprintf (outstr, "xwr r%d,r%d\n\txwr r%d,r%d\n\tmov r%d,r%d",	     op2r, op1r, op0r, op2r, op2r, op0r);  else if (cntreg == srcreg + 1)    sprintf (outstr, "xwr r%d,r%d\n\tmov r%d,r%d", op0r, op1r, op1r, op0r);  else    sprintf (outstr, "xwr r%d,r%d\n\tmov r%d,r%d\n\txwr r%d,r%d",	     op2r, cntreg_1750, op0r, op1r, op2r, cntreg_1750);  return outstr;}const char *mod_regno_adjust (instr, op)     const char *instr;     rtx *op;{  static char outstr[40];  const char *const r = (!strncmp (instr, "dvr", 3) ? "r" : "");  int modregno_gcc = REGNO (op[3]), modregno_1750 = REGNO (op[0]) + 1;  if (modregno_gcc == modregno_1750      || (reg_renumber != NULL	  && reg_renumber[modregno_gcc] >= 0	  && reg_renumber[modregno_gcc] == reg_renumber[modregno_1750]))    sprintf (outstr, "%s r%%0,%s%%2", instr, r);  else    sprintf (outstr, "lr r%d,r%d\n\t%s r%%0,%s%%2\n\txwr r%d,r%d",	     modregno_gcc, modregno_1750, instr, r, modregno_1750,	     modregno_gcc);  return outstr;}/* Check if op is a valid memory operand for 1750A Load/Store instructions   (memory indirection permitted.)  */intmemop_valid (op)     rtx op;{  static int recurred = 0;  int valid_operand;  if (GET_MODE (op) != Pmode && GET_MODE (op) != VOIDmode      && GET_MODE (op) != QImode)    return 0;  switch (GET_CODE (op))    {    case MEM:      if (!recurred && GET_CODE (XEXP (op, 0)) == REG)	return 1;    case MINUS:    case MULT:    case DIV:      return 0;    case PLUS:      recurred = 1;      valid_operand = memop_valid (XEXP (op, 0));      if (valid_operand)	valid_operand = memop_valid (XEXP (op, 1));       recurred = 0;       return valid_operand;    case REG:      if (REGNO (op) > 0)	return 1;      return 0;    case CONST:    case CONST_INT:    case SYMBOL_REF:    case SUBREG:      return 1;    default:      printf ("memop_valid: code=%d\n", (int) GET_CODE (op));      return 1;    }}/* predicate for the MOV instruction: */intmov_memory_operand (op, mode)     rtx op;     enum machine_mode mode ATTRIBUTE_UNUSED;{  return (GET_CODE (op) == MEM && GET_CODE (XEXP (op, 0)) == REG);}/* predicate for the STC instruction: */intsmall_nonneg_const (op, mode)     rtx op;     enum machine_mode mode ATTRIBUTE_UNUSED;{  if (GET_CODE (op) == CONST_INT && INTVAL (op) >= 0 && INTVAL (op) <= 15)    return 1;  return 0;}/* predicate for constant zero: */intzero_operand (op, mode)     rtx op;     enum machine_mode mode;{  return op == CONST0_RTX (mode);}/* predicate for 1750 `B' addressing mode (Base Register with Offset)   memory operand */intb_mode_operand (op)     rtx op;{  if (GET_CODE (op) == MEM)    {      rtx inner = XEXP (op, 0);      if (GET_CODE (inner) == REG && REG_OK_FOR_INDEX_P (inner))	return 1;      if (GET_CODE (inner) == PLUS)	{	  rtx plus_op0 = XEXP (inner, 0);	  if (GET_CODE (plus_op0) == REG && REG_OK_FOR_INDEX_P (plus_op0))	    {	      rtx plus_op1 = XEXP (inner, 1);	      if (GET_CODE (plus_op1) == CONST_INT		  && INTVAL (plus_op1) >= 0		  && INTVAL (plus_op1) <= 255)		return 1;	    }	}    }  return 0;}/* Decide whether to output a conditional jump as a "Jump Conditional"   or as a "Branch Conditional": */intfind_jmplbl (labelnum)     int labelnum;{  int i, found = 0;  for (i = 0; i <= jmplbl_ndx; i++)    if (labelnum == jmplbl[i].num)      {	found = 1;	break;      }  if (found)    return i;  return -1;}const char *branch_or_jump (condition, targetlabel_number)     const char *condition;     int targetlabel_number;{  static char buf[30];  int index;  if ((index = find_jmplbl (targetlabel_number)) >= 0)    if (program_counter - jmplbl[index].pc < 128)      {	sprintf (buf, "b%s %%l0", condition);	return buf;      }  sprintf (buf, "jc %s,%%l0", condition);  return buf;}intunsigned_comparison_operator (insn)     rtx insn;{  switch (GET_CODE (insn))    {    case GEU:    case GTU:    case LEU:    case LTU:      return 1;    default:      return 0;    }}intnext_cc_user_is_unsigned (insn)     rtx insn;{  if ( !(insn = next_cc0_user (insn)))    abort ();  else if (GET_CODE (insn) == JUMP_INSN	   && GET_CODE (PATTERN (insn)) == SET	   && GET_CODE (SET_SRC (PATTERN (insn))) == IF_THEN_ELSE)    return unsigned_comparison_operator (XEXP (SET_SRC (PATTERN (insn)), 0));  else if (GET_CODE (insn) == INSN	   && GET_CODE (PATTERN (insn)) == SET)    return unsigned_comparison_operator (SET_SRC (PATTERN (insn)));  else    abort ();}

⌨️ 快捷键说明

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