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

📄 romp.md

📁 linux下的gcc编译器
💻 MD
📖 第 1 页 / 共 5 页
字号:
  if (GET_CODE (operands[1]) != CONST_INT      || (unsigned) (INTVAL (operands[1]) + 0x8000) >= 0x10000)    operands[1] = force_reg (SImode, operands[1]);}")(define_insn ""  [(set (match_operand:SI 0 "register_operand" "=r,r,r")	(minus:SI (match_operand:SI 1 "reg_or_D_operand" "K,0,r")		  (match_operand:SI 2 "register_operand" "r,r,0")))]  ""  "@   sfi %0,%2,%1   s %0,%2   sf %0,%1"  [(set_attr "length" "4,2,2")]);; Multiply either calls a special RT routine or is done in-line, depending;; on the value of a -m flag.;;;; First define the way we call the subroutine.(define_expand "mulsi3_subr"  [(set (reg:SI 2) (match_operand:SI 1 "register_operand" ""))   (set (reg:SI 3) (match_operand:SI 2 "register_operand" ""))   (parallel [(set (reg:SI 2) (mult:SI (reg:SI 2) (reg:SI 3)))	      (clobber (reg:SI 0))	      (clobber (reg:SI 15))])   (set (match_operand:SI 0 "register_operand" "")	(reg:SI 2))]  ""  "")(define_expand "mulsi3"  [(set (match_operand:SI 0 "register_operand" "")	(mult:SI (match_operand:SI 1 "register_operand" "")		 (match_operand:SI 2 "register_operand" "")))]  ""  "{  if (! TARGET_IN_LINE_MUL)    {      emit_insn (gen_mulsi3_subr (operands[0], operands[1], operands[2]));      DONE;    }}");; Define the patterns to match.;; We would like to provide a delay slot for the insns that call internal;; routines, but doing so is risky since reorg will think that the use of;; r2 and r3 is completed in the insn needing the delay slot.  Also, it;; won't know that the cc will be clobbered.  So take the safe approach;; and don't give them delay slots.(define_insn ""  [(set (reg:SI 2)	(mult:SI (reg:SI 2) (reg:SI 3)))   (clobber (reg:SI 0))   (clobber (reg:SI 15))]  "! TARGET_IN_LINE_MUL"  "bali%# r15,lmul$$"  [(set_attr "type" "misc")   (set_attr "in_delay_slot" "no")])(define_insn ""  [(set (match_operand:SI 0 "register_operand" "=&r")	(mult:SI (match_operand:SI 1 "register_operand" "%r")		 (match_operand:SI 2 "register_operand" "r")))]  "TARGET_IN_LINE_MUL"  "*{ return output_in_line_mul (); }"  [(set_attr "length" "38")   (set_attr "type" "multi")]);; Handle divide and modulus.  The same function returns both values,;; so use divmodsi4.  This divides arg 1 by arg 2 with quotient to go;; into arg 0 and remainder in arg 3.;;;; We want to put REG_EQUAL notes for the two outputs.  So we need a;; function to do everything else.(define_expand "divmodsi4_doit"  [(set (reg:SI 2)	(match_operand:SI 0 "register_operand" ""))   (set (reg:SI 3)	(match_operand:SI 1 "register_operand" ""))   (parallel [(set (reg:SI 2) (div:SI (reg:SI 2) (reg:SI 3)))	      (set (reg:SI 3) (mod:SI (reg:SI 2) (reg:SI 3)))	      (clobber (reg:SI 0))	      (clobber (reg:SI 15))])]  ""  "")(define_expand "divmodsi4"  [(parallel [(set (match_operand:SI 0 "register_operand" "")		   (div:SI (match_operand:SI 1 "register_operand" "")			   (match_operand:SI 2 "register_operand" "")))	      (set (match_operand:SI 3 "register_operand" "")		   (mod:SI (match_dup 1) (match_dup 2)))])]  ""  "{  rtx insn;  emit_insn (gen_divmodsi4_doit (operands[1], operands[2]));  insn = emit_move_insn (operands[0], gen_rtx_REG (SImode, 2));  REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL,					gen_rtx_DIV (SImode, operands[1],						     operands[2]),					REG_NOTES (insn));  insn = emit_move_insn (operands[3], gen_rtx_REG (SImode, 3));  REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL,					gen_rtx_MOD (SImode, operands[1],						     operands[2]),					REG_NOTES (insn));  DONE;}")(define_insn ""  [(set (reg:SI 2)	(div:SI (reg:SI 2) (reg:SI 3)))   (set (reg:SI 3)	(mod:SI (reg:SI 2) (reg:SI 3)))   (clobber (reg:SI 0))   (clobber (reg:SI 15))]  ""  "bali%# r15,ldiv$$"  [(set_attr "type" "misc")   (set_attr "in_delay_slot" "no")]);; Similarly for unsigned divide.(define_expand "udivmodsi4_doit"  [(set (reg:SI 2)	(match_operand:SI 0 "register_operand" ""))   (set (reg:SI 3)	(match_operand:SI 1 "register_operand" ""))   (parallel [(set (reg:SI 2) (udiv:SI (reg:SI 2) (reg:SI 3)))	      (set (reg:SI 3) (umod:SI (reg:SI 2) (reg:SI 3)))	      (clobber (reg:SI 0))	      (clobber (reg:SI 15))])]  ""  "")(define_expand "udivmodsi4"  [(parallel [(set (match_operand:SI 0 "register_operand" "")		   (udiv:SI (match_operand:SI 1 "register_operand" "")			    (match_operand:SI 2 "register_operand" "")))	      (set (match_operand:SI 3 "register_operand" "")		   (umod:SI (match_dup 1) (match_dup 2)))])]  ""  "{  rtx insn;  emit_insn (gen_udivmodsi4_doit (operands[1], operands[2]));  insn = emit_move_insn (operands[0], gen_rtx_REG (SImode, 2));  REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL,					gen_rtx_UDIV (SImode, operands[1],						      operands[2]),					REG_NOTES (insn));  insn = emit_move_insn (operands[3], gen_rtx_REG (SImode, 3));  REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL,					gen_rtx_UMOD (SImode, operands[1],						      operands[2]),					REG_NOTES (insn));  DONE;}")(define_insn ""  [(set (reg:SI 2)	(udiv:SI (reg:SI 2) (reg:SI 3)))   (set (reg:SI 3)	(umod:SI (reg:SI 2) (reg:SI 3)))   (clobber (reg:SI 0))   (clobber (reg:SI 15))]  ""  "bali%# r15,uldiv$$"  [(set_attr "type" "misc")   (set_attr "in_delay_slot" "no")]);; Define DImode arithmetic operations.;;;; It is possible to do certain adds and subtracts with constants in a single;; insn, but it doesn't seem worth the trouble.;;;; Don't use DEFINE_SPLIT on these because the dependency on CC can't be;; easily tracked in that case!(define_insn "adddi3"  [(set (match_operand:DI 0 "register_operand" "=r")	(plus:DI (match_operand:DI 1 "register_operand" "%0")		 (match_operand:DI 2 "register_operand" "r")))]  ""  "a %O0,%O2\;ae %0,%2"  [(set_attr "type" "multi")])(define_insn "subdi3"  [(set (match_operand:DI 0 "register_operand" "=r")	(minus:DI (match_operand:DI 1 "register_operand" "0")		  (match_operand:DI 2 "register_operand" "r")))]  ""  "s %O0,%O2\;se %0,%2"  [(set_attr "type" "multi")])(define_insn "negdi2"  [(set (match_operand:DI 0 "register_operand" "=r,&r")	(neg:DI (match_operand:DI 1 "register_operand" "0,r")))]  ""  "twoc %O0,%O1\;onec %0,%1\;aei %0,%0,0"  [(set_attr "type" "multi")   (set_attr "length" "8")]);; Unary arithmetic operations.(define_insn "abssi2"  [(set (match_operand:SI 0 "register_operand" "=r")	(abs:SI (match_operand:SI 1 "register_operand" "r")))]  ""  "abs %0,%1"  [(set_attr "length" "2")])(define_insn "negsi2"  [(set (match_operand:SI 0 "register_operand" "=r")	(neg:SI (match_operand:SI 1 "register_operand" "r")))]  ""  "twoc %0,%1"  [(set_attr "length" "2")])(define_insn "one_cmplsi2"  [(set (match_operand:SI 0 "register_operand" "=r")	(not:SI (match_operand:SI 1 "register_operand" "r")))]  ""  "onec %0,%1"  [(set_attr "length" "2")]);; Logical insns: AND, IOR, and XOR;;;; If the operation is being performed on a 32-bit constant such that;; it cannot be done in one insn, do it in two.  We may lose a bit on;; CSE in pathological cases, but it seems better doing it this way.(define_expand "andsi3"  [(set (match_operand:SI 0 "register_operand" "")	(and:SI (match_operand:SI 1 "register_operand" "")		(match_operand:SI 2 "reg_or_any_cint_operand" "")))]  ""  "{  if (GET_CODE (operands[2]) == CONST_INT)    {      int top = (unsigned) INTVAL (operands[2]) >> 16;      int bottom = INTVAL (operands[2]) & 0xffff;      if (top != 0 && top != 0xffff && bottom != 0 && bottom != 0xffff)	{	  emit_insn (gen_andsi3 (operands[0], operands[1],				 GEN_INT ((top << 16) | 0xffff)));	  operands[1] = operands[0];	  operands[2] = GEN_INT (0xffff0000 | bottom);	}    }}");(define_insn ""  [(set (match_operand:SI 0 "register_operand" "=r,r,r")	(and:SI (match_operand:SI 1 "reg_or_and_operand" "%0,r,0")		(match_operand:SI 2 "reg_or_and_operand" "P,LMO,r")))]  "register_operand (operands[1], SImode)   || register_operand (operands[2], SImode)"  "@   clrb%k2 %0,%b2   ni%z2 %0,%1,%Z2   n %0,%2"  [(set_attr "length" "2,4,2")]);; logical OR (IOR)(define_expand "iorsi3"  [(set (match_operand:SI 0 "register_operand" "")	(ior:SI (match_operand:SI 1 "register_operand" "")		(match_operand:SI 2 "reg_or_any_cint_operand" "")))]  ""  "{  if (GET_CODE (operands[2]) == CONST_INT)    {      int top = (unsigned) INTVAL (operands[2]) >> 16;      int bottom = INTVAL (operands[2]) & 0xffff;      if (top != 0 && bottom != 0)	{	  emit_insn (gen_iorsi3 (operands[0], operands[1],				 GEN_INT (top << 16)));	  operands[1] = operands[0];	  operands[2] = GEN_INT (bottom);	}    }}");(define_insn ""  [(set (match_operand:SI 0 "register_operand" "=r,r,r")	(ior:SI (match_operand:SI 1 "reg_or_cint_operand" "%0,r,0")		(match_operand:SI 2 "reg_or_cint_operand" "N,LM,r")))]  "register_operand (operands[1], SImode)   || register_operand (operands[2], SImode)"  "@   setb%h2 %0,%b2   oi%h2 %0,%1,%H2   o %0,%2"  [(set_attr "length" "2,4,2")]);; exclusive-or (XOR)(define_expand "xorsi3"  [(set (match_operand:SI 0 "register_operand" "")	(xor:SI (match_operand:SI 1 "register_operand" "")		(match_operand:SI 2 "reg_or_any_cint_operand" "")))]  ""  "{  if (GET_CODE (operands[2]) == CONST_INT)    {      int top = (unsigned) INTVAL (operands[2]) >> 16;      int bottom = INTVAL (operands[2]) & 0xffff;      if (top == 0xffff && bottom == 0xffff)	{	  emit_insn (gen_one_cmplsi2 (operands[0], operands[1]));	  DONE;	}      else if (top != 0 && bottom != 0)	{	  emit_insn (gen_xorsi3 (operands[0], operands[1],				 GEN_INT (top << 16)));	  operands[1] = operands[0];	  operands[2] = GEN_INT (bottom);	}    }}");(define_insn ""  [(set (match_operand:SI 0 "register_operand" "=r,r")	(xor:SI (match_operand:SI 1 "reg_or_cint_operand" "%r,0")		(match_operand:SI 2 "reg_or_cint_operand" "LM,r")))]  "register_operand (operands[1], SImode)   || register_operand (operands[2], SImode)"  "@   xi%h2 %0,%1,%H2   x %0,%2"  [(set_attr "length" "4,2")]);; Various shift insns(define_insn "ashrsi3"  [(set (match_operand:SI 0 "register_operand" "=r,r")	(ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")		     (match_operand:SI 2 "reg_or_cint_operand" "r,n")))]  ""  "@   sar %0,%2   sari%s2 %0,%S2"  [(set_attr "length" "2")])(define_insn "lshrsi3"  [(set (match_operand:SI 0 "register_operand" "=r,r")	(lshiftrt:SI (match_operand:SI 1 "register_operand" "0,0")		     (match_operand:SI 2 "reg_or_cint_operand" "r,n")))]  ""  "@   sr %0,%2   sri%s2 %0,%S2"  [(set_attr "length" "2")])(define_insn ""  [(set (match_operand:SI 0 "register_operand" "=r")	(ashift:SI (match_operand:SI 1 "register_operand" "b")		   (const_int 1)))]  ""  "cas %0,%1,%1"  [(set_attr "length" "2")   (set_attr "type" "address")])(define_insn "ashlsi3"  [(set (match_operand:SI 0 "register_operand" "=r,r")	(ashift:SI (match_operand:SI 1 "register_operand" "0,0")		   (match_operand:SI 2 "reg_or_cint_operand" "r,n")))]  ""  "@   sl %0,%2   sli%s2 %0,%S2"  [(set_attr "length" "2")]);; Function call insns:;;;; On the ROMP, &fcn is actually a pointer to the data area, which is passed;; to the function in r0.  &.fcn is the actual starting address of the;; function.  Also, the word at &fcn contains &.fcn.;;;; For both functions that do and don't return values, there are two cases:;; where the function's address is a constant, and where it isn't.;;;; Operand 1 (2 for `call_value') is the number of arguments and is not used.(define_expand "call"  [(use (match_operand:SI 0 "address_operand" ""))   (use (match_operand 1 "" ""))]  ""  "{  rtx reg0 = gen_rtx_REG (SImode, 0);  rtx call_insn;  if (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != CONST_INT)    abort();  operands[0] = XEXP (operands[0], 0);  if (GET_CODE (operands[0]) == SYMBOL_REF)    {      char *real_fcnname	= (char *) alloca (strlen (XSTR (operands[0], 0)) + 2);      /* Copy the data area address to r0.  */      emit_move_insn (reg0, force_reg (SImode, operands[0]));      strcpy (real_fcnname, \".\");      strcat (real_fcnname, XSTR (operands[0], 0));      operands[0] = get_symref (real_fcnname);    }  else    {

⌨️ 快捷键说明

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