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

📄 romp.md

📁 linux下的gcc编译器
💻 MD
📖 第 1 页 / 共 5 页
字号:
;; If the output is a register and the input is memory, we have to be careful;; and see which word needs to be loaded first.  We also cannot to the;; split if the input is a constant because it would result in invalid;; insns.  When the output is a MEM, we must put a CLOBBER on each of the;; resulting insn, when it is not a MEM, we must not.(define_split  [(set (match_operand:DF 0 "memory_operand" "")	(match_operand:DF 1 "register_operand" ""))   (clobber (reg:SI 0))   (clobber (reg:SI 15))]  "GET_CODE (operands[1]) == REG && REGNO (operands[1]) < 15"  [(parallel [(set (match_dup 2) (match_dup 3))	      (clobber (match_dup 6))])   (parallel [(set (match_dup 4) (match_dup 5))	      (clobber (match_dup 7))])]  "{ operands[2] = operand_subword (operands[0], 0, 0, DFmode);  operands[3] = operand_subword (operands[1], 0, 0, DFmode);  operands[4] = operand_subword (operands[0], 1, 0, DFmode);  operands[5] = operand_subword (operands[1], 1, 0, DFmode);  if (operands[2] == 0 || operands[3] == 0      || operands[4] == 0 || operands[5] == 0)    FAIL;  if (reload_completed)    operands[6] = operands[7] = gen_rtx_REG (SImode, 15);  else    {      operands[6] = gen_rtx_SCRATCH (SImode);      operands[7] = gen_rtx_SCRATCH (SImode);    }}")(define_split  [(set (match_operand:DF 0 "nonmemory_operand" "")	(match_operand:DF 1 "general_operand" ""))   (clobber (reg:SI 0))   (clobber (reg:SI 15))]  "! symbolic_memory_operand (operands[1], DFmode)   && GET_CODE (operands[1]) != CONST_DOUBLE   && (GET_CODE (operands[0]) != REG || REGNO (operands[0]) < 15)   && (GET_CODE (operands[1]) != REG || REGNO (operands[1]) < 15)   && (GET_CODE (operands[0]) == REG || GET_CODE (operands[1]) == REG)   && ! (GET_CODE (operands[0]) == REG && GET_CODE (operands[1]) == REG	 && ! reload_completed	 && reg_overlap_mentioned_p (operands[0], operands[1]))"  [(set (match_dup 2) (match_dup 3))   (set (match_dup 4) (match_dup 5))]  "{ if (GET_CODE (operands[0]) != REG      || ! refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,			      operands[1], 0))    {      operands[2] = operand_subword (operands[0], 0, 0, DFmode);      operands[3] = operand_subword (operands[1], 0, 0, DFmode);      operands[4] = operand_subword (operands[0], 1, 0, DFmode);      operands[5] = operand_subword (operands[1], 1, 0, DFmode);    }  else    {      operands[2] = operand_subword (operands[0], 1, 0, DFmode);      operands[3] = operand_subword (operands[1], 1, 0, DFmode);      operands[4] = operand_subword (operands[0], 0, 0, DFmode);      operands[5] = operand_subword (operands[1], 0, 0, DFmode);    }  if (operands[2] == 0 || operands[3] == 0      || operands[4] == 0 || operands[5] == 0)    FAIL;}");; Conversions from one integer mode to another.;; It is possible sometimes to sign- or zero-extend while fetching from memory.;;;; First, sign-extensions:(define_expand "extendhisi2"  [(set (match_operand:SI 0 "register_operand" "")	(sign_extend:SI (match_operand:HI 1 "register_operand" "")))]  ""  "")(define_insn ""  [(set (match_operand:SI 0 "register_operand" "=b")	(sign_extend:SI (match_operand:HI 1 "symbolic_memory_operand" "m")))]  ""  "loadha %0,%1"  [(set_attr "type" "load")])(define_insn ""  [(set (match_operand:SI 0 "register_operand" "=r,r,b")	(sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Q,m")))]  ""  "@   exts %0,%1   lha%M1 %0,%1   loadha %0,%1"  [(set_attr "type" "arith,load,load")   (set_attr "length" "2,*,*")])(define_expand "extendqisi2"  [(set (match_dup 2)	(ashift:SI (match_operand:QI 1 "register_operand" "")		   (const_int 24)))   (set (match_operand:SI 0 "register_operand" "")	(ashiftrt:SI (match_dup 2)		     (const_int 24)))]  ""  "{ operands[1] = gen_lowpart (SImode, operands[1]);  operands[2] = gen_reg_rtx (SImode); }")(define_expand "extendqihi2"  [(set (match_dup 2)	(ashift:SI (match_operand:QI 1 "register_operand" "")		   (const_int 24)))   (set (match_operand:HI 0 "register_operand" "")	(ashiftrt:SI (match_dup 2)		     (const_int 24)))]  ""  "{ operands[0] = gen_lowpart (SImode, operands[0]);  operands[1] = gen_lowpart (SImode, operands[1]);  operands[2] = gen_reg_rtx (SImode); }");; Define peepholes to eliminate an instruction when we are doing a sign;; extension but cannot clobber the input.;;;; In this case we will shift left 24 bits, but need a copy first.  The shift;; can be replaced by a "mc03" instruction, but this can only be done if;; followed by the right shift of 24 or more bits.(define_peephole  [(set (match_operand:SI 0 "register_operand" "")	(subreg:SI (match_operand:QI 1 "register_operand" "") 0))   (set (match_dup 0)	(ashift:SI (match_dup 0)		   (const_int 24)))   (set (match_dup 0)	(ashiftrt:SI (match_dup 0)		     (match_operand:SI 2 "const_int_operand" "")))]  "INTVAL (operands[2]) >= 24"  "mc03 %0,%1\;sari16 %0,%S2" [(set_attr "type" "multi")  (set_attr "length" "4")  (set_attr "cc" "sets")]);; Now zero extensions:(define_expand "zero_extendhisi2"  [(set (match_operand:SI 0 "register_operand" "")	(zero_extend:SI (match_operand:HI 1 "register_operand" "")))]  ""  "")(define_insn ""  [(set (match_operand:SI 0 "register_operand" "=b")	(zero_extend:SI (match_operand:HI 1 "symbolic_memory_operand" "m")))]  ""  "loadh %0,%1"  [(set_attr "type" "load")])(define_insn ""  [(set (match_operand:SI 0 "register_operand" "=r,r,b")	(zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Q,m")))]  ""  "@   nilz %0,%1,65535   lh%N1 %0,%1   loadh %0,%1"  [(set_attr "type" "arith,loadz,load")])(define_expand "zero_extendqisi2"  [(set (match_operand:SI 0 "register_operand" "")	(zero_extend:SI (match_operand:QI 1 "register_operand" "")))]  ""  "")(define_insn ""  [(set (match_operand:SI 0 "register_operand" "=b")	(zero_extend:SI (match_operand:QI 1 "symbolic_memory_operand" "m")))]  ""  "loadc %0,%1"  [(set_attr "type" "load")])(define_insn ""  [(set (match_operand:SI 0 "register_operand" "=r,r,b")	(zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,Q,m")))]  ""  "@   nilz %0,%1,255   lc%M1 %0,%1   loadc %0,%1"  [(set_attr "type" "arith,load,load")])(define_expand "zero_extendqihi2"  [(set (match_operand:HI 0 "register_operand" "")	(zero_extend:HI (match_operand:QI 1 "register_operand" "")))]  ""  "")(define_insn ""  [(set (match_operand:HI 0 "register_operand" "=b")	(zero_extend:HI (match_operand:QI 1 "symbolic_memory_operand" "m")))]  ""  "loadc %0,%1"  [(set_attr "type" "load")])(define_insn ""  [(set (match_operand:HI 0 "register_operand" "=r,r,b")	(zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "r,Q,m")))]  ""  "@   nilz %0,%1,255   lc%M1 %0,%1   loadc %0,%1"  [(set_attr "type" "arith,load,load")]);; Various extract and insertion operations.(define_expand "extzv"  [(set (match_operand:SI 0 "register_operand" "")	(zero_extract:SI (match_operand:SI 1 "register_operand" "")			 (match_operand:SI 2 "const_int_operand" "")			 (match_operand:SI 3 "const_int_operand" "")))]  ""  "{  if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 8)    FAIL;  if (GET_CODE (operands[3]) != CONST_INT)    FAIL;  if (INTVAL (operands[3]) != 0 && INTVAL (operands[3]) != 8      && INTVAL (operands[3]) != 16 && INTVAL (operands[3]) != 24)    FAIL;}")(define_insn ""  [(set (match_operand:SI 0 "register_operand" "=&r")	(zero_extract:SI (match_operand:SI 1 "register_operand" "r")			 (const_int 8)			 (match_operand:SI 2 "const_int_operand" "n")))]  "(INTVAL (operands[2]) & 7) == 0"  "lis %0,0\;mc3%B2 %0,%1"  [(set_attr "type" "multi")   (set_attr "cc" "change0")])(define_split  [(set (match_operand:SI 0 "register_operand" "=&r")	(zero_extract:SI (match_operand:SI 1 "register_operand" "r")			 (const_int 8)			 (match_operand:SI 2 "const_int_operand" "n")))]  "(INTVAL (operands[2]) & 7) == 0"  [(set (match_dup 0) (const_int 0))   (set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 24))	(zero_extract:SI (match_dup 1) (const_int 8) (match_dup 2)))]  "")(define_insn ""  [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")			 (const_int 8)			 (const_int 24))	(zero_extract:SI (match_operand:SI 1 "register_operand" "r")			 (const_int 8)			 (match_operand:SI 2 "const_int_operand" "n")))]  "(INTVAL (operands[2]) & 7) == 0"  "mc3%B2 %0,%1"  [(set_attr "type" "address")   (set_attr "length" "2")])(define_expand "insv"  [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "")			 (match_operand:SI 1 "const_int_operand" "")			 (match_operand:SI 2 "const_int_operand" ""))	(match_operand:SI 3 "register_operand" ""))]  ""  "{  if (GET_CODE (operands[2]) != CONST_INT)    FAIL;  if (GET_CODE (operands[1]) != CONST_INT)    FAIL;  if (INTVAL (operands[1]) == 1)    {      emit_insn (gen_bit_insv (operands[0], operands[1], operands[2],			       operands[3]));      DONE;    }  else if (INTVAL (operands[1]) == 8	   && (INTVAL (operands[2]) % 8 == 0))    ;				/* Accept aligned byte-wide field.  */  else    FAIL;}");; For a single-bit insert, it is better to explicitly generate references;; to the T bit.  We will call the T bit "CC0" because it can be clobbered;; by some CC0 sets (single-bit tests).(define_expand "bit_insv"  [(set (cc0)	(zero_extract:SI (match_operand:SI 3 "register_operand" "")			 (const_int 1)			 (const_int 31)))   (parallel [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "")				    (match_operand:SI 1 "const_int_operand" "")				    (match_operand:SI 2 "const_int_operand" ""))		   (ne (cc0) (const_int 0)))	      (clobber (match_scratch:SI 4 ""))])]  ""  "")	(define_insn ""  [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")			 (const_int 8)			 (match_operand:SI 1 "const_int_operand" "n"))	(match_operand:SI 2 "register_operand" "r"))]  "(INTVAL (operands[1]) & 7) == 0"  "mc%B1%.3 %0,%2"  [(set_attr "type" "address")   (set_attr "length" "2")]);; This pattern cannot have any input reloads since if references CC0.;; So we have to add code to support memory, which is the only other;; thing that a "register_operand" can become.  There is still a problem;; if the address isn't valid and *it* needs a reload, but there is no;; way to solve that problem, so let's hope it never happens.(define_insn ""  [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r,m")			 (const_int 1)			 (match_operand:SI 1 "const_int_operand" "n,m"))	(ne (cc0) (const_int 0)))   (clobber (match_scratch:SI 2 "=X,b"))]  ""  "@   mftbi%t1 %0,%S1   l%M0 %2,%0\;mftb%t1 %2,%S1\;st%M0 %2,%0"  [(set_attr "type" "*,multi")   (set_attr "cc" "none,none")   (set_attr "length" "2,10")]);; Arithmetic instructions.  First, add and subtract.;;;; It may be that the second input is either large or small enough that;; the operation cannot be done in a single insn.  In that case, emit two.(define_expand "addsi3"  [(set (match_operand:SI 0 "register_operand" "")	(plus:SI (match_operand:SI 1 "register_operand" "")		 (match_operand:SI 2 "nonmemory_operand" "")))]  ""  "{  if (GET_CODE (operands[2]) == CONST_INT      && (unsigned) (INTVAL (operands[2]) + 0x8000) >= 0x10000      && (INTVAL (operands[2]) & 0xffff) != 0)    {      int low = INTVAL (operands[2]) & 0xffff;      int high = (unsigned) INTVAL (operands[2]) >> 16;      if (low & 0x8000)	high++, low |= 0xffff0000;      emit_insn (gen_addsi3 (operands[0], operands[1], GEN_INT (high << 16)));      operands[1] = operands[0];      operands[2] = GEN_INT (low);    }}");; Put the insn to add a symbolic constant to a register separately to;; improve register allocation since it has different register requirements.(define_insn ""  [(set (match_operand:SI 0 "register_operand" "=b")	(plus:SI (match_operand:SI 1 "register_operand" "%b")		 (match_operand:SI 2 "romp_symbolic_operand" "s")))]   ""   "get %0,$%2(%1)"   [(set_attr "type" "address")    (set_attr "length" "8")])(define_insn ""  [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,b")	(plus:SI (match_operand:SI 1 "reg_or_add_operand" "%0,0,r,b,0,r,b")		 (match_operand:SI 2 "reg_or_add_operand" "I,J,K,M,r,b,s")))]  "register_operand (operands[1], SImode)   || register_operand (operands[2], SImode)"  "@   ais %0,%2   sis %0,%n2   ail %0,%1,%2   cau %0,%H2(%1)   a %0,%2   cas %0,%1,%2   get %0,$%2(%1)"  [(set_attr "type" "arith,arith,arith,address,arith,address,misc")   (set_attr "length" "2,2,4,4,2,2,8")]);; Now subtract.;;;; 1.	If third operand is constant integer, convert it to add of the negative;;	of that integer.;; 2.	If the second operand is not a valid constant integer, force it into a;;	register.(define_expand "subsi3"  [(set (match_operand:SI 0 "register_operand" "")	(minus:SI (match_operand:SI 1 "reg_or_any_cint_operand" "")		  (match_operand:SI 2 "reg_or_any_cint_operand" "")))]  ""  "{  if (GET_CODE (operands [2]) == CONST_INT)    {      emit_insn (gen_addsi3 (operands[0], operands[1], 			     GEN_INT (- INTVAL (operands[2]))));      DONE;    }  else    operands[2] = force_reg (SImode, operands[2]);

⌨️ 快捷键说明

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