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

📄 i386.md

📁 早期freebsd实现
💻 MD
📖 第 1 页 / 共 5 页
字号:
  if (GET_CODE (operands[1]) == CONST_INT      && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0]))      && (! REG_P (operands[0]) || QI_REG_P (operands[0])))    {      if ((INTVAL (operands[1]) & 0xff00) == 0)	{	  /* ??? This might not be necessary. */	  if (INTVAL (operands[1]) & 0xffff0000)	    operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);	  /* We may set the sign bit spuriously.  */	  cc_status.flags |= CC_NOT_NEGATIVE;	  return AS2 (test%B0,%1,%b0);	}      if ((INTVAL (operands[1]) & 0xff) == 0)        {	  operands[1] = GEN_INT ((INTVAL (operands[1]) >> 8) & 0xff);	  if (QI_REG_P (operands[0]))	    return AS2 (test%B0,%1,%h0);	  else	    {	      operands[0] = adj_offsettable_operand (operands[0], 1);	      return AS2 (test%B0,%1,%b0);	    }	}    }  if (CONSTANT_P (operands[1]) || GET_CODE (operands[0]) == MEM)    return AS2 (test%W0,%1,%0);  return AS2 (test%W1,%0,%1);}")(define_insn ""  [(set (cc0)	(and:QI (match_operand:QI 0 "general_operand" "%qm")		(match_operand:QI 1 "general_operand" "qi")))]  ""  "*{  if (CONSTANT_P (operands[1]) || GET_CODE (operands[0]) == MEM)    return AS2 (test%B0,%1,%0);  return AS2 (test%B1,%0,%1);}");; move instructions.;; There is one for each machine mode,;; and each is preceded by a corresponding push-insn pattern;; (since pushes are not general_operands on the 386).(define_insn ""  [(set (match_operand:SI 0 "push_operand" "=<")	(match_operand:SI 1 "general_operand" "g"))]  "! TARGET_486"  "push%L0 %1");; On a 486, it is faster to move MEM to a REG and then push, rather than;; push MEM directly.(define_insn ""  [(set (match_operand:SI 0 "push_operand" "=<")	(match_operand:SI 1 "general_operand" "ri"))]  "TARGET_486"  "push%L0 %1");; General case of fullword move.;; If generating PIC code and operands[1] is a symbolic CONST, emit a;; move to get the address of the symbolic object from the GOT.(define_expand "movsi"  [(set (match_operand:SI 0 "general_operand" "")	(match_operand:SI 1 "general_operand" ""))]  ""  "{  extern int flag_pic;  if (flag_pic && SYMBOLIC_CONST (operands[1]))    emit_pic_move (operands, SImode);}");; On i486, incl reg is faster than movl $1,reg.(define_insn ""  [(set (match_operand:SI 0 "general_operand" "=g,r")	(match_operand:SI 1 "general_operand" "ri,m"))]  ""  "*{  rtx link;  if (operands[1] == const0_rtx && REG_P (operands[0]))    return AS2 (xor%L0,%0,%0);  if (operands[1] == const1_rtx      && (link = find_reg_note (insn, REG_WAS_0, 0))      /* Make sure the insn that stored the 0 is still present.  */      && ! XEXP (link, 0)->volatil      && GET_CODE (XEXP (link, 0)) != NOTE      /* Make sure cross jumping didn't happen here.  */      && no_labels_between_p (XEXP (link, 0), insn))    /* Fastest way to change a 0 to a 1.  */    return AS1 (inc%L0,%0);  return AS2 (mov%L0,%1,%0);}")(define_insn ""  [(set (match_operand:HI 0 "push_operand" "=<")	(match_operand:HI 1 "general_operand" "g"))]  ""  "push%W0 %1");; On i486, an incl and movl are both faster than incw and movw.(define_insn "movhi"  [(set (match_operand:HI 0 "general_operand" "=g,r")	(match_operand:HI 1 "general_operand" "ri,m"))]  ""  "*{  rtx link;  if (REG_P (operands[0]) && operands[1] == const0_rtx)    return AS2 (xor%L0,%k0,%k0);  if (REG_P (operands[0]) && operands[1] == const1_rtx       && (link = find_reg_note (insn, REG_WAS_0, 0))      /* Make sure the insn that stored the 0 is still present.  */      && ! XEXP (link, 0)->volatil      && GET_CODE (XEXP (link, 0)) != NOTE      /* Make sure cross jumping didn't happen here.  */      && no_labels_between_p (XEXP (link, 0), insn))    /* Fastest way to change a 0 to a 1.  */    return AS1 (inc%L0,%k0);  if (REG_P (operands[0]))    {      if (REG_P (operands[1]))	return AS2 (mov%L0,%k1,%k0);      else if (CONSTANT_P (operands[1]))	return AS2 (mov%L0,%1,%k0);    }  return AS2 (mov%W0,%1,%0);}")(define_insn "movstricthi"  [(set (strict_low_part (match_operand:HI 0 "general_operand" "+g,r"))	(match_operand:HI 1 "general_operand" "ri,m"))]  ""  "*{  rtx link;  if (operands[1] == const0_rtx && REG_P (operands[0]))    return AS2 (xor%W0,%0,%0);  if (operands[1] == const1_rtx      && (link = find_reg_note (insn, REG_WAS_0, 0))      /* Make sure the insn that stored the 0 is still present.  */      && ! XEXP (link, 0)->volatil      && GET_CODE (XEXP (link, 0)) != NOTE      /* Make sure cross jumping didn't happen here.  */      && no_labels_between_p (XEXP (link, 0), insn))    /* Fastest way to change a 0 to a 1.  */    return AS1 (inc%W0,%0);  return AS2 (mov%W0,%1,%0);}");; emit_push_insn when it calls move_by_pieces;; requires an insn to "push a byte".;; But actually we use pushw, which has the effect of rounding;; the amount pushed up to a halfword.(define_insn ""  [(set (match_operand:QI 0 "push_operand" "=<")	(match_operand:QI 1 "general_operand" "q"))]  ""  "*{  operands[1] = gen_rtx (REG, HImode, REGNO (operands[1]));  return AS1 (push%W0,%1);}");; On i486, incb reg is faster than movb $1,reg.;; ??? Do a recognizer for zero_extract that looks just like this, but reads;; or writes %ah, %bh, %ch, %dh.(define_insn "movqi"  [(set (match_operand:QI 0 "general_operand" "=q,*r,qm")	(match_operand:QI 1 "general_operand" "*g,q,qn"))]  ""  "*{  rtx link;  if (operands[1] == const0_rtx && REG_P (operands[0]))    return AS2 (xor%B0,%0,%0);  if (operands[1] == const1_rtx      && (link = find_reg_note (insn, REG_WAS_0, 0))      /* Make sure the insn that stored the 0 is still present.  */      && ! XEXP (link, 0)->volatil      && GET_CODE (XEXP (link, 0)) != NOTE      /* Make sure cross jumping didn't happen here.  */      && no_labels_between_p (XEXP (link, 0), insn))    /* Fastest way to change a 0 to a 1.  */    return AS1 (inc%B0,%0);  /* If mov%B0 isn't allowed for one of these regs, use mov%L0.  */  if (NON_QI_REG_P (operands[0]) || NON_QI_REG_P (operands[1]))    return (AS2 (mov%L0,%k1,%k0));  return (AS2 (mov%B0,%1,%0));}");; If it becomes necessary to support movstrictqi into %esi or %edi,;; use the insn sequence:;;;;	shrdl $8,srcreg,dstreg;;	rorl $24,dstreg;;;; If operands[1] is a constant, then an andl/orl sequence would be;; faster.(define_insn "movstrictqi"  [(set (strict_low_part (match_operand:QI 0 "general_operand" "+q,qm"))	(match_operand:QI 1 "general_operand" "*g,qn"))]  ""  "*{  rtx link;  if (operands[1] == const0_rtx && REG_P (operands[0]))    return AS2 (xor%B0,%0,%0);  if (operands[1] == const1_rtx      && (link = find_reg_note (insn, REG_WAS_0, 0))      /* Make sure the insn that stored the 0 is still present.  */      && ! XEXP (link, 0)->volatil      && GET_CODE (XEXP (link, 0)) != NOTE      /* Make sure cross jumping didn't happen here.  */      && no_labels_between_p (XEXP (link, 0), insn))    /* Fastest way to change a 0 to a 1.  */    return AS1 (inc%B0,%0);  /* If mov%B0 isn't allowed for one of these regs, use mov%W0.  */  if (NON_QI_REG_P (operands[0]) || NON_QI_REG_P (operands[1]))    {      abort ();      return (AS2 (mov%L0,%k1,%k0));    }  return AS2 (mov%B0,%1,%0);}")(define_insn ""  [(set (match_operand:SF 0 "push_operand" "=<,<")	(match_operand:SF 1 "general_operand" "gF,f"))]  ""  "*{  if (STACK_REG_P (operands[1]))    {      rtx xops[3];      if (! STACK_TOP_P (operands[1]))        abort ();      xops[0] = AT_SP (SFmode);      xops[1] = GEN_INT (4);      xops[2] = stack_pointer_rtx;      output_asm_insn (AS2 (sub%L2,%1,%2), xops);      if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))        output_asm_insn (AS1 (fstp%S0,%0), xops);      else        output_asm_insn (AS1 (fst%S0,%0), xops);      RET;    }  return AS1 (push%L1,%1);}")(define_insn "movsf"  [(set (match_operand:SF 0 "general_operand" "=f,fm,!*rf,!*rm")	(match_operand:SF 1 "general_operand" "fmG,f,*rfm,*rfF"))]  ""  "*{  int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;  /* First handle a `pop' insn or a `fld %st(0)' */  if (STACK_TOP_P (operands[0]) && STACK_TOP_P (operands[1]))    {      if (stack_top_dies)	return AS1 (fstp,%y0);      else        return AS1 (fld,%y0);    }  /* Handle a transfer between the 387 and a 386 register */  if (STACK_TOP_P (operands[0]) && NON_STACK_REG_P (operands[1]))    {      output_op_from_reg (operands[1], AS1 (fld%z0,%y1));      RET;    }  if (STACK_TOP_P (operands[1]) && NON_STACK_REG_P (operands[0]))    {      output_to_reg (operands[0], stack_top_dies);      RET;    }  /* Handle other kinds of writes from the 387 */  if (STACK_TOP_P (operands[1]))    {      if (stack_top_dies)	return AS1 (fstp%z0,%y0);      else        return AS1 (fst%z0,%y0);    }  /* Handle other kinds of reads to the 387 */  if (STACK_TOP_P (operands[0]) && GET_CODE (operands[1]) == CONST_DOUBLE)    return (char *) output_move_const_single (operands);  if (STACK_TOP_P (operands[0]))    return AS1 (fld%z1,%y1);  /* Handle all SFmode moves not involving the 387 */  return (char *) singlemove_string (operands);}");;should change to handle the memory operands[1] without doing df push..(define_insn ""  [(set (match_operand:DF 0 "push_operand" "=<,<")	(match_operand:DF 1 "general_operand" "gF,f"))]  ""  "*{  if (STACK_REG_P (operands[1]))    {      rtx xops[3];      xops[0] = AT_SP (SFmode);      xops[1] = GEN_INT (8);      xops[2] = stack_pointer_rtx;      output_asm_insn (AS2 (sub%L2,%1,%2), xops);      if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))        output_asm_insn (AS1 (fstp%Q0,%0), xops);      else        output_asm_insn (AS1 (fst%Q0,%0), xops);      RET;    }  else    return (char *) output_move_double (operands);}")(define_insn "swapdf"  [(set (match_operand:DF 0 "register_operand" "f")	(match_operand:DF 1 "register_operand" "f"))   (set (match_dup 1)	(match_dup 0))]  ""  "*{  if (STACK_TOP_P (operands[0]))    return AS1 (fxch,%1);  else    return AS1 (fxch,%0);}")(define_insn "movdf"  [(set (match_operand:DF 0 "general_operand" "=f,fm,!*rf,!*rm")	(match_operand:DF 1 "general_operand" "fmG,f,*rfm,*rfF"))]  ""  "*{  int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;  /* First handle a `pop' insn or a `fld %st(0)' */  if (STACK_TOP_P (operands[0]) && STACK_TOP_P (operands[1]))    {      if (stack_top_dies)	return AS1 (fstp,%y0);      else        return AS1 (fld,%y0);    }  /* Handle a transfer between the 387 and a 386 register */  if (STACK_TOP_P (operands[0]) && NON_STACK_REG_P (operands[1]))    {      output_op_from_reg (operands[1], AS1 (fld%z0,%y1));      RET;    }  if (STACK_TOP_P (operands[1]) && NON_STACK_REG_P (operands[0]))    {      output_to_reg (operands[0], stack_top_dies);      RET;    }  /* Handle other kinds of writes from the 387 */  if (STACK_TOP_P (operands[1]))    {      if (stack_top_dies)	return AS1 (fstp%z0,%y0);      else        return AS1 (fst%z0,%y0);    }  /* Handle other kinds of reads to the 387 */  if (STACK_TOP_P (operands[0]) && GET_CODE (operands[1]) == CONST_DOUBLE)    return (char *) output_move_const_single (operands);  if (STACK_TOP_P (operands[0]))    return AS1 (fld%z1,%y1);  /* Handle all DFmode moves not involving the 387 */  return (char *) output_move_double (operands);}")(define_insn ""  [(set (match_operand:DI 0 "push_operand" "=<")	(match_operand:DI 1 "general_operand" "roiF"))]  ""  "*{  return (char *) output_move_double (operands);}")(define_insn "movdi"  [(set (match_operand:DI 0 "general_operand" "=r,rm")	(match_operand:DI 1 "general_operand" "m,riF"))]  ""  "*{  return (char *) output_move_double (operands);}");;- conversion instructions;;- NONE;;- zero extension instructions;; See comments by `andsi' for when andl is faster than movzx.(define_insn "zero_extendhisi2"  [(set (match_operand:SI 0 "general_operand" "=r")	(zero_extend:SI	 (match_operand:HI 1 "nonimmediate_operand" "rm")))]  ""  "*{  if ((TARGET_486 || REGNO (operands[0]) == 0)      && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1]))    {      rtx xops[2];      xops[0] = operands[0];      xops[1] = GEN_INT (0xffff);      output_asm_insn (AS2 (and%L0,%1,%k0), xops);      RET;    }#ifdef INTEL_SYNTAX  return AS2 (movzx,%1,%0);#else  return AS2 (movz%W0%L0,%1,%0);#endif}")(define_insn "zero_extendqihi2"  [(set (match_operand:HI 0 "general_operand" "=r")

⌨️ 快捷键说明

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