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

📄 ia64.md

📁 Mac OS X 10.4.9 for x86 Source Code gcc 实现源代码
💻 MD
📖 第 1 页 / 共 5 页
字号:
	 If op0 is a register, then we spill op1, so that we now have a	 MEM operand.  This requires creating an XFmode subreg of a TImode reg	 to force the spill.  */      if (register_operand (operands[0], XFmode))	{	  rtx op1 = gen_rtx_REG (TImode, REGNO (operands[1]));	  op1 = gen_rtx_SUBREG (XFmode, op1, 0);	  operands[1] = spill_xfmode_operand (op1, 0);	}      else if (GET_CODE (operands[0]) == MEM)	{	  rtx in[2];	  in[WORDS_BIG_ENDIAN] = gen_rtx_REG (DImode, REGNO (operands[1]));	  in[!WORDS_BIG_ENDIAN] = gen_rtx_REG (DImode, REGNO (operands[1]) + 1);	  emit_move_insn (adjust_address (operands[0], DImode, 0), in[0]);	  emit_move_insn (adjust_address (operands[0], DImode, 8), in[1]);	  DONE;	}      else	abort ();    }  if (! reload_in_progress && ! reload_completed)    {      operands[1] = spill_xfmode_operand (operands[1], 0);      if (GET_MODE (op0) == TImode && GET_CODE (op0) == REG)	{	  rtx memt, memx, in = operands[1];	  if (CONSTANT_P (in))	    in = validize_mem (force_const_mem (XFmode, in));	  if (GET_CODE (in) == MEM)	    memt = adjust_address (in, TImode, 0);	  else	    {	      memt = assign_stack_temp (TImode, 16, 0);	      memx = adjust_address (memt, XFmode, 0);	      emit_move_insn (memx, in);	    }	  emit_move_insn (op0, memt);	  DONE;	}      if (! ia64_move_ok (operands[0], operands[1]))	operands[1] = force_reg (XFmode, operands[1]);    }});; ??? There's no easy way to mind volatile acquire/release semantics.(define_insn "*movxf_internal"  [(set (match_operand:XF 0 "destination_operand" "=f,f, m")	(match_operand:XF 1 "general_operand"     "fG,m,fG"))]  "ia64_move_ok (operands[0], operands[1])"  "@   mov %0 = %F1   ldfe %0 = %1%P1   stfe %0 = %F1%P0"  [(set_attr "itanium_class" "fmisc,fld,stf")]);; Better code generation via insns that deal with TFmode register pairs;; directly.  Same concerns apply as for TImode.(define_expand "movtf"  [(set (match_operand:TF 0 "general_operand" "")	(match_operand:TF 1 "general_operand" ""))]  ""{  rtx op1 = ia64_expand_move (operands[0], operands[1]);  if (!op1)    DONE;  operands[1] = op1;})(define_insn_and_split "*movtf_internal"  [(set (match_operand:TF 0 "destination_operand"  "=r,r,m")	(match_operand:TF 1 "general_operand"      "ri,m,r"))]  "ia64_move_ok (operands[0], operands[1])"  "#"  "reload_completed"  [(const_int 0)]{  ia64_split_tmode_move (operands);  DONE;}  [(set_attr "itanium_class" "unknown")   (set_attr "predicable" "no")]);; ::::::::::::::::::::;; ::;; :: Conversions;; ::;; ::::::::::::::::::::;; Signed conversions from a smaller integer to a larger integer(define_insn "extendqidi2"  [(set (match_operand:DI 0 "gr_register_operand" "=r")	(sign_extend:DI (match_operand:QI 1 "gr_register_operand" "r")))]  ""  "sxt1 %0 = %1"  [(set_attr "itanium_class" "xtd")])(define_insn "extendhidi2"  [(set (match_operand:DI 0 "gr_register_operand" "=r")	(sign_extend:DI (match_operand:HI 1 "gr_register_operand" "r")))]  ""  "sxt2 %0 = %1"  [(set_attr "itanium_class" "xtd")])(define_insn "extendsidi2"  [(set (match_operand:DI 0 "grfr_register_operand" "=r,?f")	(sign_extend:DI (match_operand:SI 1 "grfr_register_operand" "r,f")))]  ""  "@   sxt4 %0 = %1   fsxt.r %0 = %1, %1"  [(set_attr "itanium_class" "xtd,fmisc")]);; Unsigned conversions from a smaller integer to a larger integer(define_insn "zero_extendqidi2"  [(set (match_operand:DI 0 "gr_register_operand" "=r,r")	(zero_extend:DI (match_operand:QI 1 "gr_nonimmediate_operand" "r,m")))]  ""  "@   zxt1 %0 = %1   ld1%O1 %0 = %1%P1"  [(set_attr "itanium_class" "xtd,ld")])(define_insn "zero_extendhidi2"  [(set (match_operand:DI 0 "gr_register_operand" "=r,r")	(zero_extend:DI (match_operand:HI 1 "gr_nonimmediate_operand" "r,m")))]  ""  "@   zxt2 %0 = %1   ld2%O1 %0 = %1%P1"  [(set_attr "itanium_class" "xtd,ld")])(define_insn "zero_extendsidi2"  [(set (match_operand:DI 0 "grfr_register_operand" "=r,r,?f")	(zero_extend:DI	  (match_operand:SI 1 "grfr_nonimmediate_operand" "r,m,f")))]  ""  "@   addp4 %0 = %1, r0   ld4%O1 %0 = %1%P1   fmix.r %0 = f0, %1"  [(set_attr "itanium_class" "ialu,ld,fmisc")]);; Convert between floating point types of different sizes.;; At first glance, it would appear that emitting fnorm for an extending;; conversion is unnecessary.  However, the stf and getf instructions work;; correctly only if the input is properly rounded for its type.  In;; particular, we get the wrong result for getf.d/stfd if the input is a;; denorm single.  Since we don't know what the next instruction will be, we;; have to emit an fnorm.;; ??? Optimization opportunity here.  Get rid of the insn altogether;; when we can.  Should probably use a scheme like has been proposed;; for ia32 in dealing with operands that match unary operators.  This;; would let combine merge the thing into adjacent insns.  See also how the;; mips port handles SIGN_EXTEND as operands to integer arithmetic insns via;; se_register_operand.(define_insn "extendsfdf2"  [(set (match_operand:DF 0 "fr_register_operand" "=f")	(float_extend:DF (match_operand:SF 1 "fr_register_operand" "f")))]  ""  "fnorm.d %0 = %1"  [(set_attr "itanium_class" "fmac")])(define_insn "extendsfxf2"  [(set (match_operand:XF 0 "fr_register_operand" "=f")	(float_extend:XF (match_operand:SF 1 "fr_register_operand" "f")))]  ""  "fnorm %0 = %1"  [(set_attr "itanium_class" "fmac")])(define_insn "extenddfxf2"  [(set (match_operand:XF 0 "fr_register_operand" "=f")	(float_extend:XF (match_operand:DF 1 "fr_register_operand" "f")))]  ""  "fnorm %0 = %1"  [(set_attr "itanium_class" "fmac")])(define_insn "truncdfsf2"  [(set (match_operand:SF 0 "fr_register_operand" "=f")	(float_truncate:SF (match_operand:DF 1 "fr_register_operand" "f")))]  ""  "fnorm.s %0 = %1"  [(set_attr "itanium_class" "fmac")])(define_insn "truncxfsf2"  [(set (match_operand:SF 0 "fr_register_operand" "=f")	(float_truncate:SF (match_operand:XF 1 "fr_register_operand" "f")))]  ""  "fnorm.s %0 = %1"  [(set_attr "itanium_class" "fmac")])(define_insn "truncxfdf2"  [(set (match_operand:DF 0 "fr_register_operand" "=f")	(float_truncate:DF (match_operand:XF 1 "fr_register_operand" "f")))]  ""  "fnorm.d %0 = %1"  [(set_attr "itanium_class" "fmac")]);; Convert between signed integer types and floating point.(define_insn "floatdixf2"  [(set (match_operand:XF 0 "fr_register_operand" "=f")	(float:XF (match_operand:DI 1 "fr_register_operand" "f")))]  ""  "fcvt.xf %0 = %1"  [(set_attr "itanium_class" "fcvtfx")])(define_insn "fix_truncsfdi2"  [(set (match_operand:DI 0 "fr_register_operand" "=f")	(fix:DI (match_operand:SF 1 "fr_register_operand" "f")))]  ""  "fcvt.fx.trunc %0 = %1"  [(set_attr "itanium_class" "fcvtfx")])(define_insn "fix_truncdfdi2"  [(set (match_operand:DI 0 "fr_register_operand" "=f")	(fix:DI (match_operand:DF 1 "fr_register_operand" "f")))]  ""  "fcvt.fx.trunc %0 = %1"  [(set_attr "itanium_class" "fcvtfx")])(define_insn "fix_truncxfdi2"  [(set (match_operand:DI 0 "fr_register_operand" "=f")	(fix:DI (match_operand:XF 1 "fr_register_operand" "f")))]  ""  "fcvt.fx.trunc %0 = %1"  [(set_attr "itanium_class" "fcvtfx")])(define_insn "fix_truncxfdi2_alts"  [(set (match_operand:DI 0 "fr_register_operand" "=f")	(fix:DI (match_operand:XF 1 "fr_register_operand" "f")))   (use (match_operand:SI 2 "const_int_operand" ""))]  ""  "fcvt.fx.trunc.s%2 %0 = %1"  [(set_attr "itanium_class" "fcvtfx")]);; Convert between unsigned integer types and floating point.(define_insn "floatunsdisf2"  [(set (match_operand:SF 0 "fr_register_operand" "=f")	(unsigned_float:SF (match_operand:DI 1 "fr_register_operand" "f")))]  ""  "fcvt.xuf.s %0 = %1"  [(set_attr "itanium_class" "fcvtfx")])(define_insn "floatunsdidf2"  [(set (match_operand:DF 0 "fr_register_operand" "=f")	(unsigned_float:DF (match_operand:DI 1 "fr_register_operand" "f")))]  ""  "fcvt.xuf.d %0 = %1"  [(set_attr "itanium_class" "fcvtfx")])(define_insn "floatunsdixf2"  [(set (match_operand:XF 0 "fr_register_operand" "=f")	(unsigned_float:XF (match_operand:DI 1 "fr_register_operand" "f")))]  ""  "fcvt.xuf %0 = %1"  [(set_attr "itanium_class" "fcvtfx")])(define_insn "fixuns_truncsfdi2"  [(set (match_operand:DI 0 "fr_register_operand" "=f")	(unsigned_fix:DI (match_operand:SF 1 "fr_register_operand" "f")))]  ""  "fcvt.fxu.trunc %0 = %1"  [(set_attr "itanium_class" "fcvtfx")])(define_insn "fixuns_truncdfdi2"  [(set (match_operand:DI 0 "fr_register_operand" "=f")	(unsigned_fix:DI (match_operand:DF 1 "fr_register_operand" "f")))]  ""  "fcvt.fxu.trunc %0 = %1"  [(set_attr "itanium_class" "fcvtfx")])(define_insn "fixuns_truncxfdi2"  [(set (match_operand:DI 0 "fr_register_operand" "=f")	(unsigned_fix:DI (match_operand:XF 1 "fr_register_operand" "f")))]  ""  "fcvt.fxu.trunc %0 = %1"  [(set_attr "itanium_class" "fcvtfx")])(define_insn "fixuns_truncxfdi2_alts"  [(set (match_operand:DI 0 "fr_register_operand" "=f")	(unsigned_fix:DI (match_operand:XF 1 "fr_register_operand" "f")))   (use (match_operand:SI 2 "const_int_operand" ""))]  ""  "fcvt.fxu.trunc.s%2 %0 = %1"  [(set_attr "itanium_class" "fcvtfx")]);; ::::::::::::::::::::;; ::;; :: Bit field extraction;; ::;; ::::::::::::::::::::(define_insn "extv"  [(set (match_operand:DI 0 "gr_register_operand" "=r")	(sign_extract:DI (match_operand:DI 1 "gr_register_operand" "r")			 (match_operand:DI 2 "const_int_operand" "n")			 (match_operand:DI 3 "const_int_operand" "n")))]  ""  "extr %0 = %1, %3, %2"  [(set_attr "itanium_class" "ishf")])(define_insn "extzv"  [(set (match_operand:DI 0 "gr_register_operand" "=r")	(zero_extract:DI (match_operand:DI 1 "gr_register_operand" "r")			 (match_operand:DI 2 "const_int_operand" "n")			 (match_operand:DI 3 "const_int_operand" "n")))]  ""  "extr.u %0 = %1, %3, %2"  [(set_attr "itanium_class" "ishf")]);; Insert a bit field.;; Can have 3 operands, source1 (inserter), source2 (insertee), dest.;; Source1 can be 0 or -1.;; Source2 can be 0.;; ??? Actual dep instruction is more powerful than what these insv;; patterns support.  Unfortunately, combine is unable to create patterns;; where source2 != dest.(define_expand "insv"  [(set (zero_extract:DI (match_operand:DI 0 "gr_register_operand" "")			 (match_operand:DI 1 "const_int_operand" "")			 (match_operand:DI 2 "const_int_operand" ""))	(match_operand:DI 3 "nonmemory_operand" ""))]  ""{  int width = INTVAL (operands[1]);  int shift = INTVAL (operands[2]);  /* If operand[3] is a constant, and isn't 0 or -1, then load it into a     pseudo.  */  if (! register_operand (operands[3], DImode)      && operands[3] != const0_rtx && operands[3] != constm1_rtx)    operands[3] = force_reg (DImode, operands[3]);  /* If this is a single dep instruction, we have nothing to do.  */  if (! ((register_operand (operands[3], DImode) && width <= 16)	 || operands[3] == const0_rtx || operands[3] == constm1_rtx))    {      /* Check for cases that can be implemented with a mix instruction.  */      if (width == 32 && shift == 0)	{	  /* Directly generating the mix4left instruction confuses	     optimize_bit_field in function.c.  Since this is performing	     a useful optimization, we defer generation of the complicated	     mix4left RTL to the first splitting phase.  */	  rtx tmp = gen_reg_rtx (DImode);	  emit_insn (gen_shift_mix4left (operands[0], operands[3], tmp));	  DONE;	}      else if (width == 32 && shift == 32)	{	  emit_insn (gen_mix4right (operands[0], operands[3]));	  DONE;	}      /* We could handle remaining cases by emitting multiple dep	 instructions.	 If we need more than two dep instructions then we lose.  A 6	 insn sequence mov mask1,mov mask2,shl;;and,and;;or is better than	 mov;;dep,shr;;dep,shr;;dep.  The former can be executed in 3 cycles,	 the latter is 6 cycles on an Itanium (TM) processor, because there is	 only one function unit that can execute dep and shr immed.	 If we only need two dep instruction, then we still lose.	 mov;;dep,shr;;dep is still 4 cycles.  Even if we optimize away	 the unnecessary mov, this is still undesirable because it will be	 hard to optimize, and it creates unnecessary pressure on the I0	 function unit.  */      FAIL;#if 0      /* This code may be useful for other IA-64 processors, so we leave it in	 for now.  */      while (width > 16)	{	  rtx tmp;	  emit_insn (gen_insv (operands[0], GEN_INT (16), GEN_INT (shift),			       operands[3]));	  shift += 16;	  width -= 16;	  tmp = gen_reg_rtx (DImode);	  emit_insn (gen_lshrdi3 (tmp, operands[3], GEN_INT (16)));	  operands[3] = tmp;	}      operands[1] = GEN_INT (width);

⌨️ 快捷键说明

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