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

📄 i386.md

📁 早期freebsd实现
💻 MD
📖 第 1 页 / 共 5 页
字号:
		(match_operand:SI 2 "general_operand" "0")))]  "GET_CODE (operands[2]) == CONST_INT   && (unsigned int) INTVAL (operands[2]) < (1 << GET_MODE_BITSIZE (QImode))"  "and%L0 %1,%0")*/;;- Bit set (inclusive or) instructions;; ??? What if we only change one byte of an offsettable memory reference?(define_insn "iorsi3"  [(set (match_operand:SI 0 "general_operand" "=rm,r")	(ior:SI (match_operand:SI 1 "general_operand" "%0,0")		(match_operand:SI 2 "general_operand" "ri,rm")))]  ""  "*{  if (GET_CODE (operands[2]) == CONST_INT      && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0])))    {      if ((! REG_P (operands[0]) || QI_REG_P (operands[0]))	  && (INTVAL (operands[2]) & ~0xff) == 0)	{	  CC_STATUS_INIT;	  if (INTVAL (operands[2]) == 0xff)	    return AS2 (mov%B0,%2,%b0);	  return AS2 (or%B0,%2,%b0);	}      if (QI_REG_P (operands[0]) && (INTVAL (operands[2]) & ~0xff00) == 0)	{	  CC_STATUS_INIT;	  operands[2] = GEN_INT (INTVAL (operands[2]) >> 8);	  if (INTVAL (operands[2]) == 0xff)	    return AS2 (mov%B0,%2,%h0);	  return AS2 (or%B0,%2,%h0);	}    }  return AS2 (or%L0,%2,%0);}")(define_insn "iorhi3"  [(set (match_operand:HI 0 "general_operand" "=rm,r")	(ior:HI (match_operand:HI 1 "general_operand" "%0,0")		(match_operand:HI 2 "general_operand" "ri,rm")))]  ""  "*{  if (GET_CODE (operands[2]) == CONST_INT      && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0])))    {      /* Can we ignore the upper byte? */      if ((! REG_P (operands[0]) || QI_REG_P (operands[0]))	  && (INTVAL (operands[2]) & 0xff00) == 0)	{	  CC_STATUS_INIT;	  if (INTVAL (operands[2]) & 0xffff0000)	    operands[2] = GEN_INT (INTVAL (operands[2]) & 0xffff);	  if (INTVAL (operands[2]) == 0xff)	    return AS2 (mov%B0,%2,%b0);	  return AS2 (or%B0,%2,%b0);	}      /* Can we ignore the lower byte? */      /* ??? what about offsettable memory references? */      if (QI_REG_P (operands[0])	  && (INTVAL (operands[2]) & 0xff) == 0)	{	  CC_STATUS_INIT;	  operands[2] = GEN_INT ((INTVAL (operands[2]) >> 8) & 0xff);	  if (INTVAL (operands[2]) == 0xff)	    return AS2 (mov%B0,%2,%h0);	  return AS2 (or%B0,%2,%h0);	}    }  return AS2 (or%W0,%2,%0);}")(define_insn "iorqi3"  [(set (match_operand:QI 0 "general_operand" "=qm,q")	(ior:QI (match_operand:QI 1 "general_operand" "%0,0")		(match_operand:QI 2 "general_operand" "qn,qmn")))]  ""  "* return AS2 (or%B0,%2,%0);");;- xor instructions;; ??? What if we only change one byte of an offsettable memory reference?(define_insn "xorsi3"  [(set (match_operand:SI 0 "general_operand" "=rm,r")	(xor:SI (match_operand:SI 1 "general_operand" "%0,0")		(match_operand:SI 2 "general_operand" "ri,rm")))]  ""  "*{  if (GET_CODE (operands[2]) == CONST_INT      && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0])))    {      if ((! REG_P (operands[0]) || QI_REG_P (operands[0]))	  && (INTVAL (operands[2]) & ~0xff) == 0)	{	  CC_STATUS_INIT;	  if (INTVAL (operands[2]) == 0xff)	    return AS1 (not%B0,%b0);	  return AS2 (xor%B0,%2,%b0);	}      if (QI_REG_P (operands[0]) && (INTVAL (operands[2]) & ~0xff00) == 0)	{	  CC_STATUS_INIT;	  operands[2] = GEN_INT (INTVAL (operands[2]) >> 8);	  if (INTVAL (operands[2]) == 0xff)	    return AS1 (not%B0,%h0);	  return AS2 (xor%B0,%2,%h0);	}    }  return AS2 (xor%L0,%2,%0);}")(define_insn "xorhi3"  [(set (match_operand:HI 0 "general_operand" "=rm,r")	(xor:HI (match_operand:HI 1 "general_operand" "%0,0")		(match_operand:HI 2 "general_operand" "ri,rm")))]  ""  "*{  if (GET_CODE (operands[2]) == CONST_INT      && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0])))    {      /* Can we ignore the upper byte? */      if ((! REG_P (operands[0]) || QI_REG_P (operands[0]))	  && (INTVAL (operands[2]) & 0xff00) == 0)	{	  CC_STATUS_INIT;	  if (INTVAL (operands[2]) & 0xffff0000)	    operands[2] = GEN_INT (INTVAL (operands[2]) & 0xffff);	  if (INTVAL (operands[2]) == 0xff)	    return AS1 (not%B0,%b0);	  return AS2 (xor%B0,%2,%b0);	}      /* Can we ignore the lower byte? */      /* ??? what about offsettable memory references? */      if (QI_REG_P (operands[0])	  && (INTVAL (operands[2]) & 0xff) == 0)	{	  CC_STATUS_INIT;	  operands[2] = GEN_INT ((INTVAL (operands[2]) >> 8) & 0xff);	  if (INTVAL (operands[2]) == 0xff)	    return AS1 (not%B0,%h0);	  return AS2 (xor%B0,%2,%h0);	}    }  return AS2 (xor%W0,%2,%0);}")(define_insn "xorqi3"  [(set (match_operand:QI 0 "general_operand" "=qm,q")	(xor:QI (match_operand:QI 1 "general_operand" "%0,0")		(match_operand:QI 2 "general_operand" "qn,qm")))]  ""  "* return AS2 (xor%B0,%2,%0);");;- negation instructions(define_insn "negdi2"  [(set (match_operand:DI 0 "general_operand" "=&ro")	(neg:DI (match_operand:DI 1 "general_operand" "0")))]  ""  "*{  rtx xops[2], low[1], high[1];  CC_STATUS_INIT;  split_di (operands, 1, low, high);  xops[0] = const0_rtx;  xops[1] = high[0];  output_asm_insn (AS1 (neg%L0,%0), low);  output_asm_insn (AS2 (adc%L1,%0,%1), xops);  output_asm_insn (AS1 (neg%L0,%0), high);  RET;}")(define_insn "negsi2"  [(set (match_operand:SI 0 "general_operand" "=rm")	(neg:SI (match_operand:SI 1 "general_operand" "0")))]  ""  "neg%L0 %0")(define_insn "neghi2"  [(set (match_operand:HI 0 "general_operand" "=rm")	(neg:HI (match_operand:HI 1 "general_operand" "0")))]  ""  "neg%W0 %0")(define_insn "negqi2"  [(set (match_operand:QI 0 "general_operand" "=qm")	(neg:QI (match_operand:QI 1 "general_operand" "0")))]  ""  "neg%B0 %0")(define_insn "negsf2"  [(set (match_operand:SF 0 "register_operand" "=f")	(neg:SF (match_operand:SF 1 "general_operand" "0")))]  "TARGET_80387"  "fchs")(define_insn "negdf2"  [(set (match_operand:DF 0 "register_operand" "=f")	(neg:DF (match_operand:DF 1 "general_operand" "0")))]  "TARGET_80387"  "fchs")(define_insn ""  [(set (match_operand:DF 0 "register_operand" "=f")	(neg:DF (float_extend:DF (match_operand:SF 1 "general_operand" "0"))))]  "TARGET_80387"  "fchs");; Absolute value instructions(define_insn "abssf2"  [(set (match_operand:SF 0 "register_operand" "=f")	(abs:SF (match_operand:SF 1 "general_operand" "0")))]  "TARGET_80387"  "fabs")(define_insn "absdf2"  [(set (match_operand:DF 0 "register_operand" "=f")	(abs:DF (match_operand:DF 1 "general_operand" "0")))]  "TARGET_80387"  "fabs")(define_insn ""  [(set (match_operand:DF 0 "register_operand" "=f")	(abs:DF (float_extend:DF (match_operand:SF 1 "general_operand" "0"))))]  "TARGET_80387"  "fabs")(define_insn "sqrtsf2"  [(set (match_operand:SF 0 "register_operand" "=f")	(sqrt:SF (match_operand:SF 1 "general_operand" "0")))]  "TARGET_80387 && (TARGET_IEEE_FP || flag_fast_math)"  "fsqrt")(define_insn "sqrtdf2"  [(set (match_operand:DF 0 "register_operand" "=f")	(sqrt:DF (match_operand:DF 1 "general_operand" "0")))]  "TARGET_80387 && (TARGET_IEEE_FP || flag_fast_math)"  "fsqrt")(define_insn ""  [(set (match_operand:DF 0 "register_operand" "=f")	(sqrt:DF (float_extend:DF		  (match_operand:SF 1 "general_operand" "0"))))]  "TARGET_80387 && (TARGET_IEEE_FP || flag_fast_math)"  "fsqrt")(define_insn "sindf2"  [(set (match_operand:DF 0 "register_operand" "=f")	(unspec:DF [(match_operand:DF 1 "register_operand" "0")] 1))]  "TARGET_80387 && (TARGET_IEEE_FP || flag_fast_math)"  "fsin")(define_insn "sinsf2"  [(set (match_operand:SF 0 "register_operand" "=f")	(unspec:SF [(match_operand:SF 1 "register_operand" "0")] 1))]  "TARGET_80387 && (TARGET_IEEE_FP || flag_fast_math)"  "fsin")(define_insn ""  [(set (match_operand:DF 0 "register_operand" "=f")	(unspec:DF [(float_extend:DF		     (match_operand:SF 1 "register_operand" "0"))] 1))]  "TARGET_80387 && (TARGET_IEEE_FP || flag_fast_math)"  "fsin")(define_insn "cosdf2"  [(set (match_operand:DF 0 "register_operand" "=f")	(unspec:DF [(match_operand:DF 1 "register_operand" "0")] 2))]  "TARGET_80387 && (TARGET_IEEE_FP || flag_fast_math)"  "fcos")(define_insn "cossf2"  [(set (match_operand:SF 0 "register_operand" "=f")	(unspec:SF [(match_operand:SF 1 "register_operand" "0")] 2))]  "TARGET_80387 && (TARGET_IEEE_FP || flag_fast_math)"  "fcos")(define_insn ""  [(set (match_operand:DF 0 "register_operand" "=f")	(unspec:DF [(float_extend:DF		     (match_operand:SF 1 "register_operand" "0"))] 2))]  "TARGET_80387 && (TARGET_IEEE_FP || flag_fast_math)"  "fcos");;- one complement instructions(define_insn "one_cmplsi2"  [(set (match_operand:SI 0 "general_operand" "=rm")	(not:SI (match_operand:SI 1 "general_operand" "0")))]  ""  "not%L0 %0")(define_insn "one_cmplhi2"  [(set (match_operand:HI 0 "general_operand" "=rm")	(not:HI (match_operand:HI 1 "general_operand" "0")))]  ""  "not%W0 %0")(define_insn "one_cmplqi2"  [(set (match_operand:QI 0 "general_operand" "=qm")	(not:QI (match_operand:QI 1 "general_operand" "0")))]  ""  "not%B0 %0");;- arithmetic shift instructions;; DImode shifts are implemented using the i386 "shift double" opcode,;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count;; is variable, then the count is in %cl and the "imm" operand is dropped;; from the assembler input.;; This instruction shifts the target reg/mem as usual, but instead of;; shifting in zeros, bits are shifted in from reg operand.  If the insn;; is a left shift double, bits are taken from the high order bits of;; reg, else if the insn is a shift right double, bits are taken from the;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".;; Since sh[lr]d does not change the `reg' operand, that is done;; separately, making all shifts emit pairs of shift double and normal;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to;; support a 63 bit shift, each shift where the count is in a reg expands;; to three pairs.  If the overall shift is by N bits, then the first two;; pairs shift by N / 2 and the last pair by N & 1.;; If the shift count is a constant, we need never emit more than one;; shift pair, instead using moves and sign extension for counts greater;; than 31.(define_expand "ashldi3"  [(set (match_operand:DI 0 "register_operand" "")	(ashift:DI (match_operand:DI 1 "register_operand" "")		   (match_operand:QI 2 "nonmemory_operand" "")))]  ""  "{  if (GET_CODE (operands[2]) != CONST_INT      || ! CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J'))    {      operands[2] = copy_to_mode_reg (QImode, operands[2]);      emit_insn (gen_ashldi3_non_const_int (operands[0], operands[1],					    operands[2]));    }  else    emit_insn (gen_ashldi3_const_int (operands[0], operands[1], operands[2]));  DONE;}")(define_insn "ashldi3_const_int"  [(set (match_operand:DI 0 "register_operand" "=&r")	(ashift:DI (match_operand:DI 1 "register_operand" "0")		   (match_operand:QI 2 "const_int_operand" "J")))]  ""  "*{  rtx xops[4], low[1], high[1];  CC_STATUS_INIT;  split_di (operands, 1, low, high);  xops[0] = operands[2];  xops[1] = const1_rtx;  xops[2] = low[0];  xops[3] = high[0];  if (INTVAL (xops[0]) > 31)    {      output_asm_insn (AS2 (mov%L3,%2,%3), xops);	/* Fast shift by 32 */      output_asm_insn (AS2 (xor%L2,%2,%2), xops);      if (INTVAL (xops[0]) > 32)        {	  xops[0] = GEN_INT (INTVAL (xops[0]) - 32);	  output_asm_insn (AS2 (sal%L3,%0,%3), xops); /* Remaining shift */	}    }  else    {      output_asm_insn (AS3 (shld%L3,%0,%2,%3), xops);      output_asm_insn (AS2 (sal%L2,%0,%2), xops);    }  RET;}")(define_insn "ashldi3_non_const_int"  [(set (match_operand:DI 0 "register_operand" "=&r")	(ashift:DI (match_operand:DI 1 "register_operand" "0")		   (match_operand:QI 2 "register_operand" "c")))   (clobber (match_dup 2))]  ""  "*{  rtx xops[4], low[1], high[1];  CC_STATUS_INIT;  split_di (operands, 1, low, high);  xops[0] = operands[2];  xops[1] = const1_rtx;  xops[2] = low[0];  xops[3] = high[0];  output_asm_insn (AS2 (ror%B0,%1,%0), xops);	/* shift count / 2 */  output_asm_insn (AS3_SHIFT_DOUBLE (shld%L3,%0,%2,%3), xops);  output_asm_insn (AS2 (sal%L2,%0,%2), xops);  output_asm_insn (AS3_SHIFT_DOUBLE (shld%L3,%0,%2,%3), xops);  output_asm_insn (AS2 (sal%L2,%0,%2), xops);  xops[1] = GEN_INT (7);			/* shift count & 1 */  output_asm_insn (AS2 (shr%B0,%1,%0), xops);  output_asm_insn (AS3_SHIFT_DOUBLE (shld%L3,%0,%2,%3), xops);  output_asm_insn (AS2 (sal%L2,%0,%2), xops);  RET;}");; On i386 and i486, "addl reg,reg" is faster than "sall $1,reg";; On i486, movl/sall appears slightly faster than leal, but the leal;; is smaller - use leal for now unless the shift count is 1.(define_insn "ashlsi3"  [(set (match_operand:SI 0 "general_operand" "=r,rm")	(ashift:SI (match_operand:SI 1 "general_operand" "r,0")		   (match_operand:SI 2 "nonmemory_operand" "M,cI")))]  ""  "*{  if (REG_P (operands[0]) && REGNO (operands[0]) != REGNO (operands[1]))    {      if (TARGET_486 && INTVAL (operands[2]) == 1)	{	  output_asm_insn (AS2 (mov%L0,%1,%0), operands);	  return AS2 (add%L0,%1,%0);	}      else        {          CC_STATUS_INIT;	  if (operands[1] == stack_pointer_rtx)	    {	      output_asm_insn (AS2 (mov%L0,%1,%0), operands);	      operands[1] = operands[0];	    }          operands[1] = gen_rtx (MULT, SImode, operands[1],				 GEN_INT (1 << INTVAL (operands[2])))

⌨️ 快捷键说明

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