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

📄 sparc.md

📁 这是完整的gcc源代码
💻 MD
📖 第 1 页 / 共 5 页
字号:
;;- Machine description for SPARC chip for GNU C compiler;;   Copyright (C) 1988, 1989 Free Software Foundation, Inc.;;   Contributed by Michael Tiemann (tiemann@mcc.com);; This file is part of GNU CC.;; GNU CC is free software; you can redistribute it and/or modify;; it under the terms of the GNU General Public License as published by;; the Free Software Foundation; either version 1, or (at your option);; any later version.;; GNU CC is distributed in the hope that it will be useful,;; but WITHOUT ANY WARRANTY; without even the implied warranty of;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the;; GNU General Public License for more details.;; You should have received a copy of the GNU General Public License;; along with GNU CC; see the file COPYING.  If not, write to;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.;;- cpp macro #define NOTICE_UPDATE_CC in file tm.h handles condition code;;- updates for most instructions.;;- Operand classes for the register allocator:;; Compare instructions.;; This controls RTL generation and register allocation.;; Put cmpsi first among compare insns so it matches two CONST_INT operands.(define_insn "cmpsi"  [(set (cc0)	(compare (match_operand:SI 0 "arith_operand" "r,rI")		 (match_operand:SI 1 "arith_operand" "I,r")))]  ""  "*{  if (! REG_P (operands[0]))    {      cc_status.flags |= CC_REVERSED;      return \"cmp %1,%0\";    }  return \"cmp %0,%1\";}")(define_expand "cmpdf"  [(set (cc0)	(compare (match_operand:DF 0 "nonmemory_operand" "f,fG")		 (match_operand:DF 1 "nonmemory_operand" "G,f")))]  ""  "emit_insn (gen_rtx (USE, VOIDmode, gen_rtx (REG, DFmode, 32)));")(define_insn ""  [(set (cc0)	(compare (match_operand:DF 0 "nonmemory_operand" "f,fG")		 (match_operand:DF 1 "nonmemory_operand" "G,f")))]  "GET_CODE (operands[0]) != CONST_INT && GET_CODE (operands[1]) != CONST_INT"  "*{  if (GET_CODE (operands[0]) == CONST_DOUBLE      || GET_CODE (operands[1]) == CONST_DOUBLE)    make_f0_contain_0 (2);  cc_status.flags |= CC_IN_FCCR;  if (GET_CODE (operands[0]) == CONST_DOUBLE)    return \"fcmped %%f0,%1\;nop\";  if (GET_CODE (operands[1]) == CONST_DOUBLE)    return \"fcmped %0,%%f0\;nop\";  return \"fcmped %0,%1\;nop\";}")(define_expand "cmpsf"  [(set (cc0)	(compare (match_operand:SF 0 "nonmemory_operand" "f,fG")		 (match_operand:SF 1 "nonmemory_operand" "G,f")))]  ""  "emit_insn (gen_rtx (USE, VOIDmode, gen_rtx (REG, SFmode, 32)));")(define_insn ""  [(set (cc0)	(compare (match_operand:SF 0 "nonmemory_operand" "f,fG")		 (match_operand:SF 1 "nonmemory_operand" "G,f")))]  "GET_CODE (operands[0]) != CONST_INT && GET_CODE (operands[1]) != CONST_INT"  "*{  if (GET_CODE (operands[0]) == CONST_DOUBLE      || GET_CODE (operands[1]) == CONST_DOUBLE)    make_f0_contain_0 (1);  cc_status.flags |= CC_IN_FCCR;  if (GET_CODE (operands[0]) == CONST_DOUBLE)    return \"fcmpes %%f0,%1\;nop\";  if (GET_CODE (operands[1]) == CONST_DOUBLE)    return \"fcmpes %0,%%f0\;nop\";  return \"fcmpes %0,%1\;nop\";}");; Put tstsi first among test insns so it matches a CONST_INT operand.(define_insn "tstsi"  [(set (cc0)	(match_operand:SI 0 "register_operand" "r"))]  ""  "tst %0");; Need this to take a general operand because cse can make;; a CONST which won't be in a register.(define_insn ""  [(set (cc0)	(match_operand:SI 0 "immediate_operand" "i"))]  ""  "set %0,%%g1\;tst %%g1");; Optimize the case of following a reg-reg move with a test;; of reg just moved.(define_peephole  [(set (match_operand:SI 0 "register_operand" "=r")	(match_operand:SI 1 "register_operand" "r"))   (set (cc0) (match_operand:SI 2 "register_operand" "r"))]  "operands[2] == operands[0]   || operands[2] == operands[1]"  "orcc %1,%%g0,%0 ! 2-insn combine");; Optimize 5(6) insn sequence to 3(4) insns.;; These patterns could also optimize more complicated sets;; before conditional branches.;; Turned off because (1) this case is rarely encounted;; (2) to be correct, more conditions must be checked;; (3) the conditions must be checked with rtx_equal_p, not ==;; (4) when branch scheduling is added to the compiler,;;     this optimization will be performed by the branch scheduler;; Bottom line: it is not worth the trouble of fixing or;; maintaining it.;(define_peephole;  [(set (match_operand:SI 0 "register_operand" "=r");	(match_operand:SI 1 "general_operand" "g"));   (set (match_operand:SI 2 "register_operand" "=r");	(match_operand:SI 3 "reg_or_0_operand" "rJ"));   (set (cc0) (match_operand:SI 4 "register_operand" "r"));   (set (pc) (match_operand 5 "" ""))];  "GET_CODE (operands[5]) == IF_THEN_ELSE;   && operands[0] != operands[3];   && ! reg_mentioned_p (operands[2], operands[1]);   && (operands[4] == operands[0];       || operands[4] == operands[2];       || operands[4] == operands[3])";  "*;{;  rtx xoperands[2];;  int parity;;  xoperands[0] = XEXP (operands[5], 0);;  if (GET_CODE (XEXP (operands[5], 1)) == PC);    {;      parity = 1;;      xoperands[1] = XEXP (XEXP (operands[5], 2), 0);;    };  else;    {;      parity = 0;;      xoperands[1] = XEXP (XEXP (operands[5], 1), 0);;    };;  if (operands[4] == operands[0]);    {;      /* Although the constraints for operands[1] permit a general;	 operand (and hence possibly a const_int), we know that;	 in this branch it cannot be a CONST_INT, since that would give;	 us a fixed condition, and those should have been optimized away.  */;      if (REG_P (operands[1]));	output_asm_insn (\"orcc %1,%%g0,%0 ! 3-insn reorder\", operands);;      else if (GET_CODE (operands[1]) != MEM);	abort ();;      else;	{;	  if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)));	    output_asm_insn (\"sethi %%hi(%m1),%%g1\;ld [%%g1+%%lo(%m1)],%0\;tst %0 ! 4-insn reorder\", operands);;	  else;	    output_asm_insn (\"ld %1,%0\;tst %0 ! 3.5-insn reorder\", operands);;	};      XVECEXP (PATTERN (insn), 0, 0) = XVECEXP (PATTERN (insn), 0, 2);;      XVECEXP (PATTERN (insn), 0, 1) = XVECEXP (PATTERN (insn), 0, 3);;    };  else;    {;      output_asm_insn (\"orcc %3,%%g0,%2 ! 3-insn reorder\", operands);;    };  if (parity);    return output_delayed_branch (\"b%N0 %l1\", xoperands, insn);;  else;    return output_delayed_branch (\"b%C0 %l1\", xoperands, insn);;}");; By default, operations don't set the condition codes.;; These patterns allow cc's to be set, while doing some work(define_insn ""  [(set (cc0)	(zero_extend:SI (subreg:QI (match_operand:SI 0 "register_operand" "r") 0)))]  ""  "andcc %0,0xff,%%g0")(define_insn ""  [(set (cc0)	(plus:SI (match_operand:SI 0 "register_operand" "r%")		 (match_operand:SI 1 "arith_operand" "rI")))]  "ignore_overflow_conditional_p (NEXT_INSN (insn))"  "*{  cc_status.flags |= CC_NO_OVERFLOW;  return \"addcc %0,%1,%%g0\";}")(define_insn ""  [(set (cc0)	(plus:SI (match_operand:SI 0 "register_operand" "r%")		 (match_operand:SI 1 "arith_operand" "rI")))   (set (match_operand:SI 2 "register_operand" "=r")	(plus:SI (match_dup 0) (match_dup 1)))]  "ignore_overflow_conditional_p (NEXT_INSN (insn))"  "*{  cc_status.flags |= CC_NO_OVERFLOW;  return \"addcc %0,%1,%2\";}")(define_insn ""  [(set (cc0)	(minus:SI (match_operand:SI 0 "register_operand" "r")		  (match_operand:SI 1 "arith_operand" "rI")))]  "ignore_overflow_conditional_p (NEXT_INSN (insn))"  "*{  cc_status.flags |= CC_NO_OVERFLOW;  return \"subcc %0,%1,%%g0\";}")(define_insn ""  [(set (cc0)	(minus:SI (match_operand:SI 0 "register_operand" "r")		  (match_operand:SI 1 "arith_operand" "rI")))   (set (match_operand:SI 2 "register_operand" "=r")	(minus:SI (match_dup 0) (match_dup 1)))]  "ignore_overflow_conditional_p (NEXT_INSN (insn))"  "*{  cc_status.flags |= CC_NO_OVERFLOW;  return \"subcc %0,%1,%2\";}")(define_insn ""  [(set (cc0)	(and:SI (match_operand:SI 0 "register_operand" "r%")		(match_operand:SI 1 "arith_operand" "rI")))]  ""  "andcc %0,%1,%%g0")(define_insn ""  [(set (cc0)	(and:SI (match_operand:SI 0 "register_operand" "r%")		(match_operand:SI 1 "arith_operand" "rI")))   (set (match_operand:SI 2 "register_operand" "=r")	(and:SI (match_dup 0) (match_dup 1)))]  ""  "andcc %0,%1,%2")(define_insn ""  [(set (cc0)	(and:SI (match_operand:SI 0 "register_operand" "r")		(not:SI (match_operand:SI 1 "arith_operand" "rI"))))]  ""  "andncc %0,%1,%%g0")(define_insn ""  [(set (cc0)	(and:SI (match_operand:SI 0 "register_operand" "r")		(not:SI (match_operand:SI 1 "arith_operand" "rI"))))   (set (match_operand:SI 2 "register_operand" "=r")	(and:SI (match_dup 0) (not:SI (match_dup 1))))]  ""  "andncc %0,%1,%2")(define_insn ""  [(set (cc0)	(ior:SI (match_operand:SI 0 "register_operand" "r%")		(match_operand:SI 1 "arith_operand" "rI")))]  ""  "orcc %0,%1,%%g0")(define_insn ""  [(set (cc0)	(ior:SI (match_operand:SI 0 "register_operand" "r%")		(match_operand:SI 1 "arith_operand" "rI")))   (set (match_operand:SI 2 "register_operand" "=r")	(ior:SI (match_dup 0) (match_dup 1)))]  ""  "orcc %0,%1,%2")(define_insn ""  [(set (cc0)	(ior:SI (match_operand:SI 0 "register_operand" "r")		(not:SI (match_operand:SI 1 "arith_operand" "rI"))))]  ""  "orncc %0,%1,%%g0")(define_insn ""  [(set (cc0)	(ior:SI (match_operand:SI 0 "register_operand" "r")		(not:SI (match_operand:SI 1 "arith_operand" "rI"))))   (set (match_operand:SI 2 "register_operand" "=r")	(ior:SI (match_dup 0) (not:SI (match_dup 1))))]  ""  "orncc %0,%1,%2")(define_insn ""  [(set (cc0)	(xor:SI (match_operand:SI 0 "register_operand" "r%")		(match_operand:SI 1 "arith_operand" "rI")))]  ""  "xorcc %0,%1,%%g0")(define_insn ""  [(set (cc0)	(xor:SI (match_operand:SI 0 "register_operand" "r%")		(match_operand:SI 1 "arith_operand" "rI")))   (set (match_operand:SI 2 "register_operand" "=r")	(xor:SI (match_dup 0) (match_dup 1)))]  ""  "xorcc %0,%1,%2")(define_insn ""  [(set (cc0)	(xor:SI (match_operand:SI 0 "register_operand" "r")		(not:SI (match_operand:SI 1 "arith_operand" "rI"))))]  ""  "xnorcc %0,%1,%%g0")(define_insn ""  [(set (cc0)	(xor:SI (match_operand:SI 0 "register_operand" "r")		(not:SI (match_operand:SI 1 "arith_operand" "rI"))))   (set (match_operand:SI 2 "register_operand" "=r")	(xor:SI (match_dup 0) (not:SI (match_dup 1))))]  ""  "xnorcc %0,%1,%2")(define_expand "tstdf"  [(set (cc0)	(match_operand:DF 0 "register_operand" "f"))]  ""  "emit_insn (gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, DFmode, 32)));")(define_insn ""  [(set (cc0)	(match_operand:DF 0 "register_operand" "f"))]  ""  "*{  make_f0_contain_0 (2);  cc_status.flags |= CC_IN_FCCR;  return \"fcmped %0,%%f0\;nop\";}")(define_expand "tstsf"  [(set (cc0)	(match_operand:SF 0 "register_operand" "f"))]  ""  "emit_insn (gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SFmode, 32)));")(define_insn ""  [(set (cc0)	(match_operand:SF 0 "register_operand" "f"))]  ""  "*{  make_f0_contain_0 (1);  cc_status.flags |= CC_IN_FCCR;  return \"fcmpes %0,%%f0\;nop\";}");; There are no logical links for the condition codes.  This;; would not normally be a problem, but on the SPARC (and possibly;; other RISC machines), when argument passing, the insn which sets;; the condition code and the insn which uses the set condition code;; may not be performed adjacently (due to optimizations performed;; in combine.c).  To make up for this, we emit insn patterns which;; cannot possibly be rearranged on us.(define_expand "seq"  [(set (match_operand:SI 0 "general_operand" "=r")	(eq (cc0) (const_int 0)))]  ""  "gen_scc_insn (EQ, VOIDmode, operands); DONE;")(define_expand "sne"  [(set (match_operand:SI 0 "general_operand" "=r")	(ne (cc0) (const_int 0)))]  ""  "gen_scc_insn (NE, VOIDmode, operands); DONE;")(define_insn ""  [(set (match_operand:SI 0 "general_operand" "=r,r")	(match_operator 1 "eq_or_neq"			[(compare (match_operand:SI 2 "general_operand" "r,rI")				  (match_operand:SI 3 "general_operand" "I,r"))			 (const_int 0)]))]  ""  "*{  CC_STATUS_INIT;  cc_status.value1 = operands[0];  if (! REG_P (operands[2]))    {      output_asm_insn (\"cmp %3,%2\", operands);      cc_status.flags |= CC_REVERSED;    }  else    output_asm_insn (\"cmp %2,%3\", operands);  return output_scc_insn (GET_CODE (operands[1]), operands[0]);}")(define_insn ""  [(set (match_operand:SI 0 "general_operand" "=r")	(match_operator 1 "eq_or_neq"			[(match_operand:SI 2 "general_operand" "r")			 (const_int 0)]))]  ""  "*{  CC_STATUS_INIT;  cc_status.value1 = operands[0];  output_asm_insn (\"tst %2\", operands);  return output_scc_insn (GET_CODE (operands[1]), operands[0]);}")(define_insn ""  [(set (match_operand:SI 0 "general_operand" "=r,r")	(match_operator 1 "eq_or_neq"			[(compare (match_operand:DF 2 "general_operand" "f,fG")				  (match_operand:DF 3 "general_operand" "G,f"))			 (const_int 0)]))]  ""  "*{  CC_STATUS_INIT;  cc_status.value1 = operands[0];  cc_status.flags |= CC_IN_FCCR;

⌨️ 快捷键说明

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