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

📄 sparc.md

📁 这是完整的gcc源代码
💻 MD
📖 第 1 页 / 共 5 页
字号:
  if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))    {      cc_status.flags |= CC_KNOW_HI_G1;      cc_status.mdep = XEXP (operands[1], 0);      return \"sethi %%hi(%m1),%%g1\;ldub [%%g1+%%lo(%m1)],%0\";    }  return \"ldub %1,%0\";}");;- arithmetic shift instructions(define_insn "ashlsi3"  [(set (match_operand:SI 0 "register_operand" "=r")	(ashift:SI (match_operand:SI 1 "register_operand" "r")		   (match_operand:SI 2 "arith32_operand" "rn")))]  ""  "*{  if (GET_CODE (operands[2]) == CONST_INT      && INTVAL (operands[2]) >= 32)    operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) & 31);  return \"sll %1,%2,%0\";}")(define_insn "ashrsi3"  [(set (match_operand:SI 0 "register_operand" "=r")	(ashiftrt:SI (match_operand:SI 1 "register_operand" "r")		     (match_operand:SI 2 "arith32_operand" "rn")))]  ""  "*{  if (GET_CODE (operands[2]) == CONST_INT      && INTVAL (operands[2]) >= 32)    operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) & 31);  return \"sra %1,%2,%0\";}")(define_insn "lshrsi3"  [(set (match_operand:SI 0 "register_operand" "=r")	(lshiftrt:SI (match_operand:SI 1 "register_operand" "r")		     (match_operand:SI 2 "arith32_operand" "rn")))]  ""  "*{  if (GET_CODE (operands[2]) == CONST_INT      && INTVAL (operands[2]) >= 32)    operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) & 31);  return \"srl %1,%2,%0\";}");; Unconditional and other jump instructions;; Note that for the Sparc, by setting the annul bit on an unconditional;; branch, the following insn is never executed.  This saves us a nop,;; but requires a debugger which can handle annuled branches.(define_insn "jump"  [(set (pc) (label_ref (match_operand 0 "" "")))]  ""  "*{  extern int optimize;  extern int flag_no_peephole;  if (optimize && !flag_no_peephole)    return \"b,a %l0\";  return \"b %l0\;nop\";}");; Peephole optimizers recognize a few simple cases when delay insns are safe.;; Complex ones are up front.  Simple ones after.;; This pattern is just like the following one, but matches when there;; is a jump insn after the "delay" insn.  Without this pattern, we;; de-optimize that case.(define_peephole  [(set (pc) (match_operand 0 "" ""))   (set (match_operand:SI 1 "" "")	(match_operand:SI 2 "" ""))   (set (pc) (label_ref (match_operand 3 "" "")))]  "TARGET_EAGER && operands_satisfy_eager_branch_peephole (operands, 2)"  "*{  rtx xoperands[2];  rtx pat = gen_rtx (SET, VOIDmode, operands[1], operands[2]);  rtx delay_insn = gen_rtx (INSN, VOIDmode, 0, 0, 0, pat, -1, 0, 0);  rtx label, head;  int parity;  if (GET_CODE (XEXP (operands[0], 1)) == PC)    {      parity = 1;      label = XEXP (XEXP (operands[0], 2), 0);    }  else    {      parity = 0;      label = XEXP (XEXP (operands[0], 1), 0);    }  xoperands[0] = XEXP (operands[0], 0);  xoperands[1] = label;  head = next_real_insn_no_labels (label);  /* If at the target of this label we set the condition codes,     and the condition codes are already set for that value,     advance, if we can, to the following insn.  */  if (GET_CODE (PATTERN (head)) == SET      && GET_CODE (SET_DEST (PATTERN (head))) == CC0      && cc_status.value2 == SET_SRC (PATTERN (head)))    {      rtx nhead = next_real_insn_no_labels (head);      if (nhead	  && GET_CODE (nhead) == INSN	  && GET_CODE (PATTERN (nhead)) == SET	  && strict_single_insn_op_p (SET_SRC (PATTERN (nhead)),				      GET_MODE (SET_DEST (PATTERN (nhead))))	  && strict_single_insn_op_p (SET_DEST (PATTERN (nhead)), VOIDmode)	  /* Moves between FP regs and CPU regs are two insns.  */	  && !(GET_CODE (SET_SRC (PATTERN (nhead))) == REG	       && GET_CODE (SET_DEST (PATTERN (nhead))) == REG	       && (FP_REG_P (SET_SRC (PATTERN (nhead)))		   != FP_REG_P (SET_DEST (PATTERN (nhead))))))	{	  head = nhead;	}    }  /* Output the branch instruction first.  */  if (cc_prev_status.flags & CC_IN_FCCR)    {      if (parity)	output_asm_insn (\"fb%F0,a %l1 ! eager\", xoperands);      else	output_asm_insn (\"fb%C0,a %l1 ! eager\", xoperands);    }  else if (cc_prev_status.flags & CC_NO_OVERFLOW)    {      if (parity)	output_asm_insn (\"b%U0,a %l1 ! eager\", xoperands);      else	output_asm_insn (\"b%I0,a %l1 ! eager\", xoperands);    }  else    {      if (parity)	output_asm_insn (\"b%N0,a %l1 ! eager\", xoperands);      else	output_asm_insn (\"b%C0,a %l1 ! eager\", xoperands);    }  /* Now steal the first insn of the target.  */  output_eager_then_insn (head, operands);  XVECEXP (PATTERN (insn), 0, 0) = XVECEXP (PATTERN (insn), 0, 1);  XVECEXP (PATTERN (insn), 0, 1) = XVECEXP (PATTERN (insn), 0, 2);  return output_delayed_branch (\"b %l3 ! eager2\", operands, insn);}");; Here is a peephole which recognizes where delay insns can be made safe:;; (1) following a conditional branch, if the target of the conditional branch;; has only one user (this insn), move the first insn into our delay slot;; and emit an annulled branch.;; (2) following a conditional branch, if we can execute the fall-through;; insn without risking any evil effects, then do that instead of a nop.(define_peephole  [(set (pc) (match_operand 0 "" ""))   (set (match_operand:SI 1 "" "")	(match_operand:SI 2 "" ""))]  "TARGET_EAGER && operands_satisfy_eager_branch_peephole (operands, 1)"  "*{  rtx xoperands[2];  rtx pat = gen_rtx (SET, VOIDmode, operands[1], operands[2]);  rtx delay_insn = gen_rtx (INSN, VOIDmode, 0, 0, 0, pat, -1, 0, 0);  rtx label, head, prev = (rtx)1;  int parity;  if (GET_CODE (XEXP (operands[0], 1)) == PC)    {      parity = 1;      label = XEXP (XEXP (operands[0], 2), 0);    }  else    {      parity = 0;      label = XEXP (XEXP (operands[0], 1), 0);    }  xoperands[0] = XEXP (operands[0], 0);  xoperands[1] = label;  if (LABEL_NUSES (label) == 1)    {      prev = PREV_INSN (label);      while (prev	     && (GET_CODE (prev) == NOTE		 || (GET_CODE (prev) == INSN		     && (GET_CODE (PATTERN (prev)) == CLOBBER			 || GET_CODE (PATTERN (prev)) == USE))))	prev = PREV_INSN (prev);      if (prev == 0	  || GET_CODE (prev) == BARRIER)	{	  prev = 0;	  head = next_real_insn_no_labels (label);	}    }  if (prev == 0      && head != 0      && ! INSN_DELETED_P (head)      && GET_CODE (head) == INSN      && GET_CODE (PATTERN (head)) == SET      && strict_single_insn_op_p (SET_SRC (PATTERN (head)),				  GET_MODE (SET_DEST (PATTERN (head))))      && strict_single_insn_op_p (SET_DEST (PATTERN (head)), VOIDmode)      /* Moves between FP regs and CPU regs are two insns.  */      && !(GET_CODE (SET_SRC (PATTERN (head))) == REG	   && GET_CODE (SET_DEST (PATTERN (head))) == REG	   && (FP_REG_P (SET_SRC (PATTERN (head)))	       != FP_REG_P (SET_DEST (PATTERN (head))))))    {      /* If at the target of this label we set the condition codes,	 and the condition codes are already set for that value,	 advance, if we can, to the following insn.  */      if (GET_CODE (PATTERN (head)) == SET	  && GET_CODE (SET_DEST (PATTERN (head))) == CC0	  && cc_status.value2 == SET_SRC (PATTERN (head)))	{	  rtx nhead = next_real_insn_no_labels (head);	  if (nhead	      && GET_CODE (nhead) == INSN	      && GET_CODE (PATTERN (nhead)) == SET	      && strict_single_insn_op_p (SET_SRC (PATTERN (nhead)),					  GET_MODE (SET_DEST (nhead)))	      && strict_single_insn_op_p (SET_DEST (PATTERN (nhead)), VOIDmode)	      /* Moves between FP regs and CPU regs are two insns.  */	      && !(GET_CODE (SET_SRC (PATTERN (nhead))) == REG		   && GET_CODE (SET_DEST (PATTERN (nhead))) == REG		   && (FP_REG_P (SET_SRC (PATTERN (nhead)))		       != FP_REG_P (SET_DEST (PATTERN (nhead))))))	    head = nhead;	}      /* Output the branch instruction first.  */      if (cc_prev_status.flags & CC_IN_FCCR)	{	  if (parity)	    output_asm_insn (\"fb%F0,a %l1 ! eager\", xoperands);	  else	    output_asm_insn (\"fb%C0,a %l1 ! eager\", xoperands);	}      else if (cc_prev_status.flags & CC_NO_OVERFLOW)	{	  if (parity)	    output_asm_insn (\"b%U0,a %l1 ! eager\", xoperands);	  else	    output_asm_insn (\"b%I0,a %l1 ! eager\", xoperands);	}      else	{	  if (parity)	    output_asm_insn (\"b%N0,a %l1 ! eager\", xoperands);	  else	    output_asm_insn (\"b%C0,a %l1 ! eager\", xoperands);	}      /* Now steal the first insn of the target.  */      output_eager_then_insn (head, operands);    }  else    {      /* Output the branch instruction first.  */      if (cc_prev_status.flags & CC_IN_FCCR)	{	  if (parity)	    output_asm_insn (\"fb%F0 %l1 ! eager\", xoperands);	  else	    output_asm_insn (\"fb%C0 %l1 ! eager\", xoperands);	}      else if (cc_prev_status.flags & CC_NO_OVERFLOW)	{	  if (parity)	    output_asm_insn (\"b%U0,a %l1 ! eager\", xoperands);	  else	    output_asm_insn (\"b%I0,a %l1 ! eager\", xoperands);	}      else	{	  if (parity)	    output_asm_insn (\"b%N0 %l1 ! eager\", xoperands);	  else	    output_asm_insn (\"b%C0 %l1 ! eager\", xoperands);	}    }  return output_delay_insn (delay_insn);}");; Here are two simple peepholes which fill the delay slot of;; an unconditional branch.(define_peephole  [(set (match_operand:SI 0 "register_operand" "=r")	(match_operand:SI 1 "single_insn_src_p" "p"))   (set (pc) (label_ref (match_operand 2 "" "")))]  "single_insn_extra_test (operands[0], operands[1])"  "* return output_delayed_branch (\"b %l2\", operands, insn);")(define_peephole  [(set (match_operand:SI 0 "memory_operand" "=m")	(match_operand:SI 1 "reg_or_0_operand" "rJ"))   (set (pc) (label_ref (match_operand 2 "" "")))]  ""  "* return output_delayed_branch (\"b %l2\", operands, insn);")(define_insn "tablejump"  [(set (pc) (match_operand:SI 0 "register_operand" "r"))   (use (label_ref (match_operand 1 "" "")))]  ""  "jmp %0\;nop")(define_peephole  [(set (match_operand:SI 0 "register_operand" "=r")	(match_operand:SI 1 "single_insn_src_p" "p"))   (parallel [(set (pc) (match_operand:SI 2 "register_operand" "r"))	      (use (label_ref (match_operand 3 "" "")))])]  "REGNO (operands[0]) != REGNO (operands[2])   && single_insn_extra_test (operands[0], operands[1])"  "* return output_delayed_branch (\"jmp %2\", operands, insn);")(define_peephole  [(set (match_operand:SI 0 "memory_operand" "=m")	(match_operand:SI 1 "reg_or_0_operand" "rJ"))   (parallel [(set (pc) (match_operand:SI 2 "register_operand" "r"))	      (use (label_ref (match_operand 3 "" "")))])]  ""  "* return output_delayed_branch (\"jmp %2\", operands, insn);");;- jump to subroutine(define_expand "call"  [(call (match_operand:SI 0 "memory_operand" "m")	 (match_operand 1 "" "i"))]  ;; operand[2] is next_arg_register  ""  "{  rtx fn_rtx, nregs_rtx;  if (TARGET_SUN_ASM && GET_CODE (XEXP (operands[0], 0)) == REG)    {      rtx g1_rtx = gen_rtx (REG, SImode, 1);      emit_move_insn (g1_rtx, XEXP (operands[0], 0));      fn_rtx = gen_rtx (MEM, SImode, g1_rtx);    }  else    fn_rtx = operands[0];  /* Count the number of parameter registers being used by this call.     if that argument is NULL, it means we are using them all, which     means 6 on the sparc.  */#if 0  if (operands[2])    nregs_rtx = gen_rtx (CONST_INT, VOIDmode, REGNO (operands[2]) - 8);  else    nregs_rtx = gen_rtx (CONST_INT, VOIDmode, 6);#else  nregs_rtx = const0_rtx;#endif  emit_call_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (2,			   gen_rtx (CALL, VOIDmode, fn_rtx, nregs_rtx),			   gen_rtx (USE, VOIDmode, gen_rtx (REG, SImode, 31)))));  DONE;}")(define_insn ""  [(call (match_operand:SI 0 "memory_operand" "m")	 (match_operand 1 "" "i"))   (use (reg:SI 31))]  ;;- Don't use operand 1 for most machines.  "CONSTANT_P (XEXP (operands[0], 0))   || GET_CODE (XEXP (operands[0], 0)) == REG"  "*{  /* strip the MEM.  */  operands[0] = XEXP (operands[0], 0);  CC_STATUS_INIT;  if (TARGET_SUN_ASM && GET_CODE (operands[0]) == REG)    return \"jmpl %a0,%%o7\;nop\";  return \"call %a0,%1\;nop\";}")(define_peephole  [(set (match_operand:SI 0 "register_operand" "=r")	(match_operand:SI 1 "single_insn_src_p" "p"))   (parallel [(call (match_operand:SI 2 "memory_operand" "m")		    (match_operand 3 "" "i"))	      (use (reg:SI 31))])]  ;;- Don't use operand 1 for most machines.  "! reg_mentioned_p (operands[0], operands[2])   && single_insn_extra_test (operands[0], operands[1])"  "*{  /* strip the MEM.  */  operands[2] = XEXP (operands[2], 0);  if (TARGET_SUN_ASM && GET_CODE (operands[2]) == REG)    return output_delayed_branch (\"jmpl %a2,%%o7\", operands, insn);  return output_delayed_branch (\"call %a2,%3\", operands, insn);}")(define_peephole  [(set (match_operand:SI 0 "memory_operand" "=m")	(match_operand:SI 1 "reg_or_0_operand" "rJ"))   (parallel [(call (match_operand:SI 2 "memory_operand" "m")		    (match_operand 3 "" "i"))	      (use (reg:SI 31))])]  ;;- Don't use operand 1 for most machines.  ""  "*{  /* strip the MEM.  */  operands[2] = XEXP (operands[2], 0);  if (TARGET_SUN_ASM && GET_CODE (operands[2]) == REG)    return output_delayed_branch (\"jmpl %a2,%%o7\", operands, insn);  return output_delayed_branch (\"call %a2,%3\", operands, insn);}")(define_expand "call_value"  [(set (match_operand 0 "register_operand" "=rf")	(call (match_operand:SI 1 "memory_operand" "m")	      (match_operand 2 "" "i")))]  ;; operand 3 is next_arg_register  ""  "{  rtx fn_rtx, nregs_rtx;  rtvec vec;  if (TARGET_SUN_ASM && GET_CODE (XEXP (operands[1], 0)) == REG)    {      rtx g1_rtx = gen_rtx (REG, SImode, 1);      emit_move_insn (g1_rtx, XEXP (operands[1], 0));      fn_rtx = gen_rtx (MEM, SImode, g1_rtx);    }  else    fn_rtx = operands[1];#if 0  if (operands[3])    nregs_rtx = gen_rtx (CONST_INT, VOIDmode, REGNO (operands[3]) - 8);  else    nregs_rtx = gen_rtx (CONST_INT, VOIDmode, 6);#

⌨️ 快捷键说明

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