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

📄 gmicro.c

📁 GUN开源阻止下的编译器GCC
💻 C
📖 第 1 页 / 共 2 页
字号:
  /* If one operand is decrementing and one is incrementing     decrement the former register explicitly     and change that operand into ordinary indexing.  */  if (optype0 == PUSHOP && optype1 == POPOP)    {      operands[0] = XEXP (XEXP (operands[0], 0), 0);      output_asm_insn ("sub.w %#8,%0", operands);      operands[0] = gen_rtx (MEM, DImode, operands[0]);      optype0 = OFFSOP;    }  if (optype0 == POPOP && optype1 == PUSHOP)    {      operands[1] = XEXP (XEXP (operands[1], 0), 0);      output_asm_insn ("sub.w %#8,%1", operands);      operands[1] = gen_rtx (MEM, DImode, operands[1]);      optype1 = OFFSOP;    }  /* If an operand is an unoffsettable memory ref, find a register     we can increment temporarily to make it refer to the second word.  */  if (optype0 == MEMOP)    addreg0 = find_addr_reg (operands[0]);  if (optype1 == MEMOP)    addreg1 = find_addr_reg (operands[1]);  /* Ok, we can do one word at a time.     Normally we do the low-numbered word first,     but if either operand is autodecrementing then we     do the high-numbered word first.          In either case, set up in LATEHALF the operands to use     for the high-numbered word and in some cases alter the     operands in OPERANDS to be suitable for the low-numbered word.  */  if (optype0 == REGOP)    latehalf[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);  else if (optype0 == OFFSOP)    latehalf[0] = adj_offsettable_operand (operands[0], 4);  else    latehalf[0] = operands[0];  if (optype1 == REGOP)    latehalf[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1);  else if (optype1 == OFFSOP)    latehalf[1] = adj_offsettable_operand (operands[1], 4);  else if (optype1 == CNSTOP)    {      if (GET_CODE (operands[1]) == CONST_DOUBLE)	split_double (operands[1], &operands[1], &latehalf[1]);      else if (CONSTANT_P (operands[1]))	latehalf[1] = const0_rtx;    }  else    latehalf[1] = operands[1];  /* If insn is effectively movd N(sp),-(sp) then we will do the     high word first.  We should use the adjusted operand 1 (which is N+4(sp))     for the low word as well, to compensate for the first decrement of sp.  */  if (optype0 == PUSHOP      && REGNO (XEXP (XEXP (operands[0], 0), 0)) == STACK_POINTER_REGNUM      && reg_overlap_mentioned_p (stack_pointer_rtx, operands[1]))    operands[1] = latehalf[1];  /* If one or both operands autodecrementing,     do the two words, high-numbered first.  */  /* Likewise,  the first move would clobber the source of the second one,     do them in the other order.  This happens only for registers;     such overlap can't happen in memory unless the user explicitly     sets it up, and that is an undefined circumstance.  */  if (optype0 == PUSHOP || optype1 == PUSHOP      || (optype0 == REGOP && optype1 == REGOP	  && REGNO (operands[0]) == REGNO (latehalf[1])))    {      /* Make any unoffsettable addresses point at high-numbered word.  */      if (addreg0)	output_asm_insn ("add.w %#4,%0", &addreg0);      if (addreg1)	output_asm_insn ("add.w %#4,%0", &addreg1);      /* Do that word.  */      output_asm_insn (singlemove_string (latehalf), latehalf);      /* Undo the adds we just did.  */      if (addreg0)	output_asm_insn ("sub.w %#4,%0", &addreg0);      if (addreg1)	output_asm_insn ("sub.w %#4,%0", &addreg1);      /* Do low-numbered word.  */      return singlemove_string (operands);    }  /* Normal case: do the two words, low-numbered first.  */  output_asm_insn (singlemove_string (operands), operands);  /* Make any unoffsettable addresses point at high-numbered word.  */  if (addreg0)    output_asm_insn ("add.w %#4,%0", &addreg0);  if (addreg1)    output_asm_insn ("add.w %#4,%0", &addreg1);  /* Do that word.  */  output_asm_insn (singlemove_string (latehalf), latehalf);  /* Undo the adds we just did.  */  if (addreg0)    output_asm_insn ("sub.w %#4,%0", &addreg0);  if (addreg1)    output_asm_insn ("sub.w %#4,%0", &addreg1);  return "";}/* Move const_double to floating point register (DF) */char *output_move_const_double (operands)     rtx *operands;{  int code = standard_fpu_constant_p (operands[1]);  if (FPU_REG_P (operands[0]))     {      if (code != 0)	{	  static char buf[40];	  sprintf (buf, "fmvr from%d,%%0.d", code);	  return buf;	}      else 	{	  return "fmov %1,%0.d";	}    }  else if (GREG_P (operands[0]))     {      rtx xoperands[2];      xoperands[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);      xoperands[1] = gen_rtx (CONST_INT, VOIDmode,			      CONST_DOUBLE_HIGH (operands[1]));      output_asm_insn ("mov.w %1,%0", xoperands);      operands[1] = gen_rtx (CONST_INT, VOIDmode,			     CONST_DOUBLE_LOW (operands[1]));      return "mov.w %1,%0";    }  else     {      return output_move_double (operands); /* ?????? */    }}char *output_move_const_single (operands)     rtx *operands;{  int code = standard_fpu_constant_p (operands[1]);  static char buf[40];  if (FPU_REG_P (operands[0]))     {      if (code != 0)	{	  sprintf (buf, "fmvr from%d,%%0.s", code);	  return buf;	}      return "fmov.s %f1,%0";    }  else     return "mov.w %f1,%0";}/* Return nonzero if X, a CONST_DOUBLE, has a value that we can get   from the "fmvr" instruction of the Gmicro FPU.   The value, anded with 0xff, gives the code to use in fmovecr   to get the desired constant.  */  u.i[0] = CONST_DOUBLE_LOW (x);  u.i[1] = CONST_DOUBLE_HIGH (x);  d = u.d;  if (d == 0.0)			/* +0.0 */    return 0x0;  /* Note: there are various other constants available     but it is a nuisance to put in their values here.  */  if (d == 1.0)			/* +1.0 */    return 0x1;  /*   * Stuff that looks different if it's single or double   */  if (GET_MODE (x) == SFmode)    {      if (d == S_PI)	return 0x2;      if (d == (S_PI / 2.0))	return 0x3;      if (d == S_E)	return 0x4;      if (d == S_LOGEof2)	return 0x5;      if (d == S_LOGEof10)	return 0x6;      if (d == S_LOG10of2)	return 0x7;      if (d == S_LOG10ofE)	return 0x8;      if (d == S_LOG2ofE)	return 0x9;    }  else    {      if (d == D_PI)	return 0x2;      if (d == (D_PI / 2.0))	return 0x3;      if (d == D_E)	return 0x4;      if (d == D_LOGEof2)	return 0x5;      if (d == D_LOGEof10)	return 0x6;      if (d == D_LOG10of2)	return 0x7;      if (d == D_LOG10ofE)	return 0x8;      if (d == D_LOG2ofE)	return 0x9;    }  return 0;}#undef S_PI#undef D_PI#undef S_E#undef D_E#undef S_LOGEof2#undef D_LOGEof2#undef S_LOGEof10#undef D_LOGEof10#undef S_LOG10of2#undef D_LOG10of2#undef S_LOG10ofE#undef D_LOG10ofE#undef S_LOG2ofE#undef D_LOG2ofE/* dest should be operand 0 *//* imm should be operand 1 */extern char *sub_imm_word ();char *add_imm_word (imm, dest, immp)     int imm;     rtx dest, *immp;{  int is_reg, short_ok;  if (imm < 0)     {      *immp = gen_rtx (CONST_INT, VOIDmode, -imm);      return sub_imm_word (-imm, dest);    }      if (imm == 0)    return "mov:l.w #0,%0";      short_ok = short_format_ok (dest);  if (short_ok && imm <= 8)    return "add:q %1,%0.w";  if (imm < 128)    return "add:e %1,%0.w";  is_reg = (GET_CODE (dest) == REG);  if (is_reg)    return "add:l %1,%0.w";      if (short_ok)    return "add:i %1,%0.w";      return "add %1,%0.w";}char *sub_imm_word (imm, dest, immp)     int imm;     rtx dest, *immp;{  int is_reg, short_ok;  if (imm < 0 &&  imm != 0x80000000)     {      *immp = gen_rtx (CONST_INT, VOIDmode, -imm);      return add_imm_word (-imm, dest);    }      if (imm == 0)    return "mov:z.w #0,%0";      short_ok = short_format_ok (dest);  if (short_ok && imm <= 8)    return "sub:q %1,%0.w";  if (imm < 128)    return "sub:e %1,%0.w";  is_reg = (GET_CODE (dest) == REG);  if (is_reg)    return "sub:l %1,%0.w";      if (short_ok)    return "sub:i %1,%0.w";      return "sub %1,%0.w";}intshort_format_ok (x)     rtx x;{  rtx x0, x1;  if (GET_CODE (x) == REG)    return 1;  if (GET_CODE (x) == MEM       && GET_CODE (XEXP (x, 0)) == PLUS)     {      x0 = XEXP (XEXP (x, 0), 0);      x1 = XEXP (XEXP (x, 0), 1);      return ((GET_CODE (x0) == REG	       && CONSTANT_P (x1)	       && ((unsigned) (INTVAL (x1) + 0x8000)  < 0x10000))	      ||	      (GET_CODE (x1) == REG	       && CONSTANT_P (x0)	       && ((unsigned) (INTVAL (x0) + 0x8000)  < 0x10000)));    }  return 0;}myoutput_sp_adjust (file, op, fsize)     FILE *file;     char *op;     int fsize;{  if (fsize == 0)    ;  else if (fsize < 8)    fprintf (file, "\t%s:q #%d,sp.w\n", op, fsize);  else if (fsize < 128)    fprintf (file, "\t%s:e #%d,sp.w\n", op, fsize);  else    fprintf (file, "\t%s:l #%d,sp.w\n", op, fsize);}char *mov_imm_word (imm, dest)     int imm;     rtx dest;{  int is_reg, short_ok;  if (imm == 0)    return "mov:z.w #0,%0";      short_ok = short_format_ok (dest);  if (short_ok && imm > 0 && imm <= 8)    return "mov:q %1,%0.w";  if (-128 <= imm && imm < 128)    return "mov:e %1,%0.w";  is_reg = (GET_CODE (dest) == REG);  if (is_reg)    return "mov:l %1,%0.w";      if (short_ok)    return "mov:i %1,%0.w";      return "mov %1,%0.w";}char *cmp_imm_word (imm, dest)     int imm;     rtx dest;{  int is_reg, short_ok;  if (imm == 0)    return "cmp:z.w #0,%0";      short_ok = short_format_ok (dest);  if (short_ok && imm >0 && imm <= 8)    return "cmp:q %1,%0.w";  if (-128 <= imm && imm < 128)    return "cmp:e %1,%0.w";  is_reg = (GET_CODE (dest) == REG);  if (is_reg)    return "cmp:l %1,%0.w";      if (short_ok)    return "cmp:i %1,%0.w";      return "cmp %1,%0.w";}char *push_imm_word (imm)     int imm;{  if (imm == 0)    return "mov:z.w #0,%-";      if (imm > 0 && imm <= 8)    return "mov:q %1,%-.w";  if (-128 <= imm && imm < 128)    return "mov:e %1,%-.w";  return "mov:g %1,%-.w";      /* In some cases, g-format may be better than I format.??     return "mov %1,%0.w";     */}my_signed_comp (insn)     rtx insn;{  rtx my_insn;  my_insn = NEXT_INSN (insn);  if (GET_CODE (my_insn) != JUMP_INSN)     {      fprintf (stderr, "my_signed_comp: Not Jump_insn ");      myabort (GET_CODE (my_insn));    }  my_insn = PATTERN (my_insn);  if (GET_CODE (my_insn) != SET)     {      fprintf (stderr, "my_signed_comp: Not Set ");      myabort (GET_CODE (my_insn));    }  my_insn = SET_SRC (my_insn);  if (GET_CODE (my_insn) != IF_THEN_ELSE)     {      fprintf (stderr, "my_signed_comp: Not if_then_else ");      myabort (GET_CODE (my_insn));    }  switch (GET_CODE (XEXP (my_insn, 0)))    {    case NE:    case EQ:    case GE:    case GT:    case LE:    case LT:      return 1;    case GEU:    case GTU:    case LEU:    case LTU:      return 0;    }  fprintf (stderr, "my_signed_comp: Not cccc ");  myabort (GET_CODE (XEXP (my_insn, 0)));}

⌨️ 快捷键说明

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