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

📄 a29k.c

📁 gcc编译工具没有什么特别
💻 C
📖 第 1 页 / 共 3 页
字号:
      return;    case 'B':      if (GET_CODE (x) == GE)	fprintf (file, "t");      else	fprintf (file, "f");      return;    case 'J':      /* It so happens that the RTX names for the conditions are the same as	 the 29k's insns except for "ne", which requires "neq".  */      fprintf (file, GET_RTX_NAME (GET_CODE (x)));      if (GET_CODE (x) == NE)	fprintf (file, "q");      return;    case 'e':      if (optimize && flag_delayed_branch	  && a29k_last_prologue_insn == 0 && epilogue_operand (x, VOIDmode)	  && dbr_sequence_length () == 0)	{	  /* We need to output the label number of the last label in the	     function, which is not necessarily X since there might be	     a USE insn in between.  First go forward to the last insn, then	     back up to a label.  */	  while (NEXT_INSN (x) != 0)	    x = NEXT_INSN (x);	  while (GET_CODE (x) != CODE_LABEL)	    x = PREV_INSN (x);	  ASM_GENERATE_INTERNAL_LABEL (buf, "LX", CODE_LABEL_NUMBER (x));	  assemble_name (file, buf);	}      else	output_asm_label (x);      return;    case 'E':      if (dbr_sequence_length ())	;      else if (a29k_last_prologue_insn)	{	  fprintf (file, "\n\t%s", a29k_last_prologue_insn);	  a29k_last_prologue_insn = 0;	}      else if (optimize && flag_delayed_branch	       && epilogue_operand (x, VOIDmode))	{	  fprintf (file, "\n\t%s", a29k_first_epilogue_insn);	  a29k_first_epilogue_insn_used = 1;	}      else	fprintf (file, "\n\tnop");      return;          case 'F':      output_addr_const (file, x);      if (dbr_sequence_length () == 0)	{	  /* If this doesn't have its delay slot filled, see if we need to	     put the last insn of the prolog in it.  If not, see if this is	     a recursive call.  If so, we can put the first insn of its	     prolog in the delay slot.  Otherwise, write a nop.  */	  if (a29k_last_prologue_insn)	    {	      fprintf (file, "\n\t%s", a29k_last_prologue_insn);	      a29k_last_prologue_insn = 0;	    }	  else if (GET_CODE (x) == SYMBOL_REF	      && ! strcmp (XSTR (x, 0), current_function_name))	    fprintf (file, "+4\n\t%s,%d",		     a29k_regstack_size >= 64 ? "const gr121" : "sub gr1,gr1",		     a29k_regstack_size * 4);	  else	    fprintf (file, "\n\tnop");	}      return;    case 'L':      if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == DFmode)	{	  union real_extract u;	  bcopy ((char *) &CONST_DOUBLE_LOW (x), (char *) &u, sizeof u);	  fprintf (file, "$double1(%.20e)", u.d);	}      else if (GET_CODE (x) == REG)	fprintf (file, "%s", reg_names[REGNO (x) + 1]);      else	output_operand_lossage ("invalid %%L value");      return;    case 'O':      if (GET_CODE (x) != REG)	output_operand_lossage ("invalid %%O value");      fprintf (file, "%s", reg_names[REGNO (x) + 2]);      return;    case 'P':      if (GET_CODE (x) != REG)	output_operand_lossage ("invalid %%P value");      fprintf (file, "%s", reg_names[REGNO (x) + 3]);      return;    case 'S':      fprintf (file, "%d", (GET_MODE_SIZE (GET_MODE (x)) / UNITS_PER_WORD)-1);      return;    case 'V':      if (GET_CODE (x) != PARALLEL)	output_operand_lossage ("invalid %%V value");      fprintf (file, "%d", XVECLEN (x, 0) - 2);      return;    case '#':      if (dbr_sequence_length () == 0)	{	  if (a29k_last_prologue_insn)	    {	      fprintf (file, "\n\t%s", a29k_last_prologue_insn);	      a29k_last_prologue_insn = 0;	    }	  else	    fprintf (file, "\n\tnop");	}      return;    case '*':      fprintf (file, "%s", reg_names [R_TPC]);      return;    }  if (GET_CODE (x) == REG)    fprintf (file, "%s", reg_names [REGNO (x)]);  else if (GET_CODE (x) == MEM)    output_address (XEXP (x, 0));  else if (GET_CODE (x) == CONST && GET_CODE (XEXP (x, 0)) == SUBREG	   && GET_CODE (SUBREG_REG (XEXP (x, 0))) == CONST_DOUBLE)    {      union real_extract u;      if (GET_MODE (SUBREG_REG (XEXP (x, 0))) == SFmode)	fprintf (file, "$float");      else	fprintf (file, "$double%d", SUBREG_WORD (XEXP (x, 0)));      bcopy ((char *) &CONST_DOUBLE_LOW (SUBREG_REG (XEXP (x, 0))),	     (char *) &u, sizeof u);      fprintf (file, "(%.20e)", u.d);    }  else if (GET_CODE (x) == CONST_DOUBLE	   && GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT)    {      union real_extract u;      bcopy ((char *) &CONST_DOUBLE_LOW (x), (char *) &u, sizeof u);      fprintf (file, "$%s(%.20e)",	       GET_MODE (x) == SFmode ? "float" : "double0", u.d);    }  else    output_addr_const (file, x);}/* This page contains routines to output function prolog and epilog code. *//* Compute the size of the register stack, and determine if there are any   call instructions.  */static voidcompute_regstack_size (){  int i;  rtx insn;  /* See if we make any calls.  We need to set lr1 if so.  */  a29k_makes_calls = 0;  for (insn = get_insns (); insn; insn = next_insn (insn))    if (GET_CODE (insn) == CALL_INSN	|| (GET_CODE (insn) == INSN	    && GET_CODE (PATTERN (insn)) == SEQUENCE	    && GET_CODE (XVECEXP (PATTERN (insn), 0, 0)) == CALL_INSN))      {	a29k_makes_calls = 1;	break;      }  /* Find the highest local register used.  */  for (i = R_LR (127); i >= R_LR (0); i--)    if (regs_ever_live[i])      break;  a29k_regstack_size = i - (R_LR (0) - 1);  /* If calling routines, ensure we count lr0 & lr1.  */  if (a29k_makes_calls && a29k_regstack_size < 2)    a29k_regstack_size = 2;  /* Count frame pointer and align to 8 byte boundary (even number of     registers).  */  a29k_regstack_size += frame_pointer_needed;  if (a29k_regstack_size & 1) a29k_regstack_size++;}/*  Sets register names for incoming arguments and frame pointer.    This can't be computed until after register allocation.  */voida29k_compute_reg_names (){  int i;  compute_regstack_size ();  /* Set the names and numbers of the frame pointer and incoming argument     registers.  */  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)    a29k_debug_reg_map[i] = i;  reg_names[FRAME_POINTER_REGNUM] = reg_names[R_LR (a29k_regstack_size - 1)];  a29k_debug_reg_map[FRAME_POINTER_REGNUM] = R_LR (a29k_regstack_size - 1);  for (i = 0; i < 16; i++)    {      reg_names[R_AR (i)] = reg_names[R_LR (a29k_regstack_size + i + 2)];      a29k_debug_reg_map[R_AR (i)] = R_LR (a29k_regstack_size + i + 2);    }  /* If using kernel register map, swap numbers for kernel and user     registers.  */  if (TARGET_KERNEL_REGISTERS)    for (i = 0; i < 32; i++)      {	int tem = a29k_debug_reg_map[i];	a29k_debug_reg_map[i] = a29k_debug_reg_map[R_KR (i)];	a29k_debug_reg_map[R_KR (i)] = tem;      }}/* Output function prolog code to file FILE.  Memory stack size is SIZE.  */voidoutput_prolog (file, size)     FILE *file;     int size;{  int i;  int arg_count = 0;  rtx insn;  unsigned int tag_word;  /* See how many incoming arguments we have in registers.  */  for (i = R_AR (0); i < R_AR (16); i++)    if (! fixed_regs[i])      arg_count++;  /* The argument count includes the caller's lr0 and lr1.  */  arg_count += 2;  /* Compute memory stack size.  Add in number of bytes that the we should     push and pretend the caller did and the size of outgoing arguments.     Then round to a doubleword boundary.  */  size += (current_function_pretend_args_size	   + current_function_outgoing_args_size);  size = (size + 7) & ~7;  /* Write header words.  See if one or two word form.  */  tag_word = (frame_pointer_needed ? 0x400000 : 0) + (arg_count << 16);  if (size / 8 > 0xff)    fprintf (file, "\t.word %d, 0x%0x\n", (size / 8) << 2,	     0x800000 + tag_word);  else    fprintf (file, "\t.word 0x%0x\n", tag_word + ((size / 8) << 3));  /* Define the function name.  */  assemble_name (file, a29k_function_name);  fprintf (file, ":\n");  /* Push the register stack by the proper amount.  There are two possible     ways to do this.  */  if (a29k_regstack_size >= 256/4)    fprintf (file, "\tconst %s,%d\n\tsub gr1,gr1,%s\n",	     reg_names[R_TAV], a29k_regstack_size * 4, reg_names[R_TAV]);  else if (a29k_regstack_size)    fprintf (file, "\tsub gr1,gr1,%d\n", a29k_regstack_size * 4);  /* Test that the registers are available.  */  if (a29k_regstack_size)    fprintf (file, "\tasgeu V_%sSPILL,gr1,%s\n",	     TARGET_KERNEL_REGISTERS ? "K" : "", reg_names[R_RAB]);  /* Set up frame pointer, if one is needed.  */  if (frame_pointer_needed)    fprintf (file, "\tsll %s,%s,0\n", reg_names[FRAME_POINTER_REGNUM],	     reg_names[R_MSP]);  /* Make room for any frame space.  There are three ways to do this.  */  if (size >= 256)    {      fprintf (file, "\tconst %s,%d\n", reg_names[R_TAV], size);      if (size >= 65536)	fprintf (file, "\tconsth %s,%d\n", reg_names[R_TAV], size);      if (TARGET_STACK_CHECK)	fprintf (file, "\tcall %s,__msp_check\n", reg_names[R_TPC]);      fprintf (file, "\tsub %s,%s,%s\n",	       reg_names[R_MSP], reg_names[R_MSP], reg_names[R_TAV]);    }  else if (size)    {      if (TARGET_STACK_CHECK)	fprintf (file, "\tcall %s,__msp_check\n", reg_names[R_TPC]);      fprintf (file, "\tsub %s,%s,%d\n",	       reg_names[R_MSP], reg_names[R_MSP], size);    }  /* If this routine will make calls, set lr1.  If we see an insn that     can use a delay slot before a call or jump, save this insn for that     slot (this condition is equivalent to seeing if we have an insn that     needs delay slots before an insn that has a filled delay slot).  */  a29k_last_prologue_insn = 0;  if (a29k_makes_calls)    {      i = (a29k_regstack_size + arg_count) * 4;      if (i >= 256)	fprintf (file, "\tconst %s,%d\n\tadd lr1,gr1,%s\n",		 reg_names[R_TAV], i, reg_names[R_TAV]);      else	{	  if (optimize && flag_delayed_branch)	    for (insn = get_insns (); insn; insn = NEXT_INSN (insn))	      {		if (GET_CODE (insn) == CODE_LABEL		    || (GET_CODE (insn) == INSN			&& GET_CODE (PATTERN (insn)) == SEQUENCE))		  break;		if (GET_CODE (insn) == NOTE		    || (GET_CODE (insn) == INSN			&& (GET_CODE (PATTERN (insn)) == USE			    || GET_CODE (PATTERN (insn)) == CLOBBER)))		  continue;		if (num_delay_slots (insn) > 0)		  {		    a29k_last_prologue_insn = (char *) oballoc (100);		    sprintf (a29k_last_prologue_insn, "add lr1,gr1,%d", i);		    break;		  }	      }	  if (a29k_last_prologue_insn == 0)	    fprintf (file, "\tadd lr1,gr1,%d\n", i);	}    }  /* Compute the first insn of the epilogue.  */  a29k_first_epilogue_insn_used = 0;  if (size == 0 && a29k_regstack_size == 0 && ! frame_pointer_needed)    a29k_first_epilogue_insn = 0;  else    a29k_first_epilogue_insn = (char *) oballoc (100);  if (frame_pointer_needed)    sprintf (a29k_first_epilogue_insn, "sll %s,%s,0",	     reg_names[R_MSP], reg_names[FRAME_POINTER_REGNUM]);  else if (a29k_regstack_size)    {      if (a29k_regstack_size >= 256 / 4)	sprintf (a29k_first_epilogue_insn, "const %s,%d",		 reg_names[R_TAV], a29k_regstack_size * 4);      else	sprintf (a29k_first_epilogue_insn, "add gr1,gr1,%d",		 a29k_regstack_size * 4);    }  else if (size)    {      if (size >= 256)	sprintf (a29k_first_epilogue_insn, "const %s,%d",		 reg_names[R_TAV], size);      else	sprintf (a29k_first_epilogue_insn, "add %s,%s,%d",		 reg_names[R_MSP], reg_names[R_MSP], size);    }}/* Call this after writing what might be the first instruction of the   epilogue.  If that first insn was used in a delay slot, an intermediate   label is written.  */static voidcheck_epilogue_internal_label (file)     FILE *file;{  rtx insn;  if (! a29k_first_epilogue_insn_used)    return;  for (insn = get_last_insn ();       GET_CODE (insn) != CODE_LABEL;       insn = PREV_INSN (insn))    ;  ASM_OUTPUT_INTERNAL_LABEL (file, "LX", CODE_LABEL_NUMBER (insn));  a29k_first_epilogue_insn_used = 0;}/* Output the epilog of the last procedure to file FILE.  SIZE is the memory   stack size.  The register stack size is in the variable   A29K_REGSTACK_SIZE.  */voidoutput_epilog (file, size)     FILE *file;     int size;{  rtx insn;  int locals_unavailable = 0;	/* True until after first insn				   after gr1 update. */  /* If we hit a BARRIER before a real insn or CODE_LABEL, we don't     need to do anything because we are never jumped to.  */  insn = get_last_insn ();  if (GET_CODE (insn) == NOTE)    insn = prev_nonnote_insn (insn);  if (insn && GET_CODE (insn) == BARRIER)    return;  /* If a frame pointer was needed we must restore the memory stack pointer     before adjusting the register stack.  */  if (frame_pointer_needed)    {      fprintf (file, "\tsll %s,%s,0\n",	       reg_names[R_MSP], reg_names[FRAME_POINTER_REGNUM]);      check_epilogue_internal_label (file);    }  /* Restore the register stack.  There are two ways to do this.  */  if (a29k_regstack_size)    {      if (a29k_regstack_size >= 256/4)	{	  fprintf (file, "\tconst %s,%d\n",		   reg_names[R_TAV], a29k_regstack_size * 4);	  check_epilogue_internal_label (file);	  fprintf (file, "\tadd gr1,gr1,%s\n", reg_names[R_TAV]);	}      else	{	  fprintf (file, "\tadd gr1,gr1,%d\n", a29k_regstack_size * 4);	  check_epilogue_internal_label (file);	}      locals_unavailable = 1;    }  /* Restore the memory stack pointer if there is no frame pointer.     Adjust the size to include any pretend arguments and pushed     arguments and round to doubleword boundary.  */  size += (current_function_pretend_args_size	   + current_function_outgoing_args_size);  size = (size + 7) & ~7;  if (size && ! frame_pointer_needed)    {      if (size >= 256)	{	  fprintf (file, "\tconst %s,%d\n", reg_names[R_TAV], size);	  check_epilogue_internal_label (file);	  locals_unavailable = 0;	  if (size >= 65536)	    fprintf (file, "\tconsth %s,%d\n", reg_names[R_TAV], size);	  fprintf (file, "\tadd %s,%s,%s\n",		   reg_names[R_MSP], reg_names[R_MSP], reg_names[R_TAV]);	}      else	{	  fprintf (file, "\tadd %s,%s,%d\n",		   reg_names[R_MSP], reg_names[R_MSP], size);	  check_epilogue_internal_label (file);	  locals_unavailable = 0;	}    }  if (locals_unavailable)    {      /* If we have an insn for this delay slot, write it.  */      if (current_function_epilogue_delay_list)	final_scan_insn (XEXP (current_function_epilogue_delay_list, 0),			 file, 1, -2, 1);      else	fprintf (file, "\tnop\n");    }  fprintf (file, "\tjmpi lr0\n");  if (a29k_regstack_size)    fprintf (file, "\tasleu V_%sFILL,lr1,%s\n",	     TARGET_KERNEL_REGISTERS ? "K" : "", reg_names[R_RFB]);  else if (current_function_epilogue_delay_list)    final_scan_insn (XEXP (current_function_epilogue_delay_list, 0),		     file, 1, -2, 1);  else    fprintf (file, "\tnop\n");}

⌨️ 快捷键说明

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