📄 sparc.md
字号:
;;- 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 + -