?? i860.md
字號:
;;- Machine description for Intel 860 chip for GNU C compiler;; Copyright (C) 1989 Free Software Foundation, Inc.;; 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:/* Bit-test instructions. */(define_insn "" [(set (cc0) (eq (and:SI (match_operand:SI 0 "register_operand" "r") (match_operand:SI 1 "logic_operand" "rL")) (const_int 0)))] "" "*{ cc_status.flags |= CC_ONLY_EQ; return \"and %1,%0,r0\";}")(define_insn "" [(set (cc0) (ne (and:SI (match_operand:SI 0 "register_operand" "r") (match_operand:SI 1 "logic_operand" "rL")) (const_int 0)))] "" "*{ cc_status.flags |= CC_NEGATED; cc_status.flags |= CC_ONLY_EQ; return \"and %1,%0,r0\";}")(define_insn "" [(set (cc0) (eq (and:SI (match_operand:SI 0 "register_operand" "r") (match_operand:SI 1 "immediate_operand" "i")) (const_int 0)))] "GET_CODE (operands[1]) == CONST_INT && (INTVAL (operands[1]) & 0xffff) == 0" "*{ cc_status.flags |= CC_ONLY_EQ; return \"andh h%%%1,%0,r0\";}")(define_insn "" [(set (cc0) (ne (and:SI (match_operand:SI 0 "register_operand" "r") (match_operand:SI 1 "immediate_operand" "i")) (const_int 0)))] "GET_CODE (operands[1]) == CONST_INT && (INTVAL (operands[1]) & 0xffff) == 0" "*{ cc_status.flags |= CC_NEGATED; cc_status.flags |= CC_ONLY_EQ; return \"andh h%%%1,%0,r0\";}")(define_insn "" [(set (cc0) (eq (ashiftrt:SI (sign_extend:SI (ashift:QI (match_operand:QI 0 "register_operand" "r") (match_operand:QI 1 "logic_int" "n"))) (match_operand:SI 2 "logic_int" "n")) (const_int 0)))] "" "*{ int width = 8 - INTVAL (operands[2]); int pos = 8 - width - INTVAL (operands[1]); operands[2] = gen_rtx (CONST_INT, VOIDmode, ~((-1) << width) << pos); return \"and %2,%0,r0\";}");; Compare instructions.;; This controls RTL generation and register allocation.;; Put cmpsi first among compare insns so it matches two CONST_INT operands.(define_insn "cmpeqsi" [(set (cc0) (eq (match_operand:SI 0 "logic_operand" "r,rL") (match_operand:SI 1 "logic_operand" "L,r")))] "" "*{ cc_status.flags &= ~ CC_CONDITION_MASK; cc_status.flags |= CC_ONLY_EQ; if (REG_P (operands[0])) return \"xor %1,%0,r0\"; return \"xor %0,%1,r0\";}")(define_insn "cmpltsi" [(set (cc0) (lt (match_operand:SI 0 "arith_operand" "r,rI") (match_operand:SI 1 "arith_operand" "I,r")))] "" "*{ cc_status.flags &= ~ CC_CONDITION_MASK; cc_status.flags |= CC_ONLY_LT; if (REG_P (operands[1])) return \"subs %0,%1,r0\"; cc_status.flags |= CC_REVERSED; operands[1] = gen_rtx (CONST_INT, VOIDmode, - INTVAL (operands[1])); return \"adds %1,%0,r0\";}")(define_insn "cmpgtsi" [(set (cc0) (gt (match_operand:SI 0 "arith_operand" "r,rI") (match_operand:SI 1 "arith_operand" "I,r")))] "" "*{ cc_status.flags &= ~ CC_CONDITION_MASK; cc_status.flags |= CC_ONLY_LT; if (REG_P (operands[0])) return \"subs %1,%0,r0\"; cc_status.flags |= CC_REVERSED; operands[0] = gen_rtx (CONST_INT, VOIDmode, - INTVAL (operands[0])); return \"adds %0,%1,r0\";}")(define_insn "cmpgeusi" [(set (cc0) (geu (match_operand:SI 0 "arith_operand" "r,rI") (match_operand:SI 1 "arith_operand" "I,r")))] "" "*{ cc_status.flags &= ~ CC_CONDITION_MASK; cc_status.flags |= CC_ONLY_LEU; if (REG_P (operands[1])) return \"subu %0,%1,r0\"; cc_status.flags |= CC_REVERSED; operands[1] = gen_rtx (CONST_INT, VOIDmode, - INTVAL (operands[1])); return \"addu %1,%0,r0\";}")(define_insn "cmpleusi" [(set (cc0) (leu (match_operand:SI 0 "arith_operand" "r,rI") (match_operand:SI 1 "arith_operand" "I,r")))] "" "*{ cc_status.flags &= ~ CC_CONDITION_MASK; cc_status.flags |= CC_ONLY_LEU; if (REG_P (operands[0])) return \"subu %1,%0,r0\"; cc_status.flags |= CC_REVERSED; operands[0] = gen_rtx (CONST_INT, VOIDmode, - INTVAL (operands[0])); return \"addu %0,%1,r0\";}")(define_insn "cmpeqsf" [(set (cc0) (eq (match_operand:SF 0 "reg_or_0_operand" "fG") (match_operand:SF 1 "reg_or_0_operand" "fG")))] "" "*{ cc_status.flags &= ~ CC_CONDITION_MASK; cc_status.flags |= CC_ONLY_EQ; return \"pfeq.ss %r1,%r0,f0\";}")(define_insn "cmpltsf" [(set (cc0) (lt (match_operand:SF 0 "reg_or_0_operand" "fG") (match_operand:SF 1 "reg_or_0_operand" "fG")))] "" "*{ cc_status.flags &= ~ CC_CONDITION_MASK; cc_status.flags |= CC_ONLY_LT;}")(define_insn "cmpgtsf" [(set (cc0) (gt (match_operand:SF 0 "reg_or_0_operand" "fG") (match_operand:SF 1 "reg_or_0_operand" "fG")))] "" "*{ cc_status.flags &= ~ CC_CONDITION_MASK; cc_status.flags |= CC_ONLY_LT; return \"pfgt.ss %r0,%r1,f0\";}")(define_insn "cmplesf" [(set (cc0) (le (match_operand:SF 0 "reg_or_0_operand" "fG") (match_operand:SF 1 "reg_or_0_operand" "fG")))] "" "*{ cc_status.flags &= ~ CC_CONDITION_MASK; cc_status.flags |= CC_ONLY_LE; cc_status.flags |= CC_NEGATED; /* added by markb */ return \"pfle.ss %r0,%r1,f0\";}")(define_insn "cmpgesf" [(set (cc0) (ge (match_operand:SF 0 "reg_or_0_operand" "fG") (match_operand:SF 1 "reg_or_0_operand" "fG")))] "" "*{ cc_status.flags &= ~ CC_CONDITION_MASK; cc_status.flags |= CC_ONLY_LE; cc_status.flags |= CC_NEGATED; /* added by markb */ return \"pfle.ss %r1,%r0,f0\";}")(define_insn "cmpeqdf" [(set (cc0) (eq (match_operand:DF 0 "reg_or_0_operand" "fG") (match_operand:DF 1 "reg_or_0_operand" "fG")))] "" "*{ cc_status.flags &= ~ CC_CONDITION_MASK; cc_status.flags |= CC_ONLY_EQ; return \"pfeq.dd %r1,%r0,f0\";}")(define_insn "cmpltdf" [(set (cc0) (lt (match_operand:DF 0 "reg_or_0_operand" "fG") (match_operand:DF 1 "reg_or_0_operand" "fG")))] "" "*{ cc_status.flags &= ~ CC_CONDITION_MASK; cc_status.flags |= CC_ONLY_LT; return \"pfgt.dd %r1,%r0,f0\";}")(define_insn "cmpgtdf" [(set (cc0) (gt (match_operand:DF 0 "reg_or_0_operand" "fG") (match_operand:DF 1 "reg_or_0_operand" "fG")))] "" "*{ cc_status.flags &= ~ CC_CONDITION_MASK; cc_status.flags |= CC_ONLY_LT; return \"pfgt.dd %r0,%r1,f0\";}")(define_insn "cmpledf" [(set (cc0) (le (match_operand:DF 0 "reg_or_0_operand" "fG") (match_operand:DF 1 "reg_or_0_operand" "fG")))] "" "*{ cc_status.flags &= ~ CC_CONDITION_MASK; cc_status.flags |= CC_ONLY_LE; cc_status.flags |= CC_NEGATED; /* added by markb */ return \"pfle.dd %r0,%r1,f0\";}")(define_insn "cmpgedf" [(set (cc0) (ge (match_operand:DF 0 "reg_or_0_operand" "fG") (match_operand:DF 1 "reg_or_0_operand" "fG")))] "" "*{ cc_status.flags &= ~ CC_CONDITION_MASK; cc_status.flags |= CC_ONLY_LE; cc_status.flags |= CC_NEGATED; /* added by markb */ return \"pfle.dd %r1,%r0,f0\";}")(define_insn "" [(set (cc0) (eq (zero_extend:SI (match_operand:HI 0 "load_operand" "m")) (match_operand:SI 1 "small_int" "I")))] "INTVAL (operands[1]) >= 0" "ld.s %0,r31\;xor %1,r31,r0")(define_insn "" [(set (cc0) (eq (match_operand:SI 0 "small_int" "I") (zero_extend:SI (match_operand:HI 1 "load_operand" "m"))))] "INTVAL (operands[0]) >= 0" "ld.s %1,r31\;xor %0,r31,r0");; Define the real conditional branch instructions.(define_insn "cbranch" [(set (pc) (if_then_else (cc0) (label_ref (match_operand 0 "" "")) (pc)))] "" "*{ if (cc_prev_status.flags & CC_NEGATED) return \"bnc %l0\"; else return \"bc %l0\";}")(define_insn "inverse_cbranch" [(set (pc) (if_then_else (cc0) (pc) (label_ref (match_operand 0 "" ""))))] "" "*{ if (cc_prev_status.flags & CC_NEGATED) return \"bc %l0\"; else return \"bnc %l0\";}");; Other conditional branches, made by combining.(define_insn "" [(set (pc) (if_then_else (eq (match_operand:SI 0 "bte_operand" "%rK") (match_operand:SI 1 "bte_operand" "rJ")) (label_ref (match_operand 2 "" "")) (pc)))] "GET_CODE (operands[0]) == REG || GET_CODE (operands[1]) == REG" "bte %0,%r1,%2")(define_insn "" [(set (pc) (if_then_else (eq (match_operand:SI 0 "bte_operand" "%rK") (match_operand:SI 1 "bte_operand" "rJ")) (pc) (label_ref (match_operand 2 "" ""))))] "GET_CODE (operands[0]) == REG || GET_CODE (operands[1]) == REG" "btne %0,%r1,%2");; Optimize fetching an unsigned half word and comparing against constant.;; No need to zero-extend.(define_insn "" [(set (pc) (if_then_else (eq (zero_extend:SI (match_operand:HI 0 "load_operand" "m")) (match_operand:SI 1 "immediate_operand" "K")) (label_ref (match_operand 2 "" "")) (pc)))] "GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0x10 && INTVAL (operands[1]) >= 0" "ld.s %0,r31\;bte %1,r31,%2")(define_insn "" [(set (pc) (if_then_else (eq (match_operand:SI 0 "immediate_operand" "K") (zero_extend:SI (match_operand:HI 1 "load_operand" "m"))) (label_ref (match_operand 2 "" "")) (pc)))] "GET_CODE (operands[0]) == CONST_INT && INTVAL (operands[0]) < 0x10 && INTVAL (operands[0]) >= 0" "ld.s %1,r31\;bte %0,r31,%2")(define_insn "" [(set (pc) (if_then_else (eq (zero_extend:SI (match_operand:HI 0 "load_operand" "m")) (match_operand:SI 1 "immediate_operand" "K")) (pc) (label_ref (match_operand 2 "" ""))))] "GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0x10 && INTVAL (operands[1]) >= 0" "ld.s %0,r31\;btne %1,r31,%2")(define_insn "" [(set (pc) (if_then_else (eq (match_operand:SI 0 "immediate_operand" "K") (zero_extend:SI (match_operand:HI 1 "load_operand" "m"))) (pc) (label_ref (match_operand 2 "" ""))))] "GET_CODE (operands[0]) == CONST_INT && INTVAL (operands[0]) < 0x10 && INTVAL (operands[0]) >= 0" "ld.s %1,r31\;btne %0,r31,%2")(define_insn "" [(set (pc) (if_then_else (eq (zero_extend:SI (match_operand:QI 0 "load_operand" "m")) (match_operand:SI 1 "immediate_operand" "K")) (label_ref (match_operand 2 "" "")) (pc)))] "GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0x10 && INTVAL (operands[1]) >= 0" "ld.b %0,r31\;bte %1,r31,%2")(define_insn "" [(set (pc) (if_then_else (eq (match_operand:SI 0 "immediate_operand" "K") (zero_extend:SI (match_operand:QI 1 "load_operand" "m"))) (label_ref (match_operand 2 "" "")) (pc)))] "GET_CODE (operands[0]) == CONST_INT && INTVAL (operands[0]) < 0x10 && INTVAL (operands[0]) >= 0" "ld.b %1,r31\;bte %0,r31,%2")(define_insn "" [(set (pc) (if_then_else (eq (zero_extend:SI (match_operand:QI 0 "load_operand" "m")) (match_operand:SI 1 "immediate_operand" "K")) (pc) (label_ref (match_operand 2 "" ""))))] "GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0x10 && INTVAL (operands[1]) >= 0" "ld.b %0,r31\;btne %1,r31,%2")(define_insn "" [(set (pc) (if_then_else (eq (match_operand:SI 0 "immediate_operand" "K") (zero_extend:SI (match_operand:QI 1 "load_operand" "m"))) (pc) (label_ref (match_operand 2 "" ""))))] "GET_CODE (operands[0]) == CONST_INT && INTVAL (operands[0]) < 0x10 && INTVAL (operands[0]) >= 0" "ld.b %1,r31\;btne %0,r31,%2");; Generation of conditionals.;; The first step is the emission of a standard-looking compare insn.;; Then a standard-named conditional branch pattern is run.;; That branch pattern looks back at the compare insn and deletes it.;; It then emits a machine-specific compare insn and a branch-if-true;; or a branch-if-false.;; These patterns have `abort' because they are supposed to be deleted;; in that fashion.(define_insn "cmpsi" [(set (cc0) (compare (match_operand:SI 0 "compare_operand" "") (match_operand:SI 1 "compare_operand" "")))] "" "* abort ();")(define_insn "cmpsf" [(set (cc0) (compare (match_operand:SF 0 "register_operand" "") (match_operand:SF 1 "register_operand" "")))] "" "* abort ();")(define_insn "cmpdf" [(set (cc0) (compare (match_operand:DF 0 "register_operand" "") (match_operand:DF 1 "register_operand" "")))] "" "* abort ();");; These are the standard-named conditional branch patterns.;; Detailed comments are found in the first one only.(define_expand "beq" [(set (pc) (if_then_else (eq (cc0) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] "" "{ rtx label = operands[0]; enum insn_code code; rtx prev; /* Get out of the sequence just started for us. */ end_sequence (); prev = get_last_insn (); /* Examine the preceding compare insn, and get rid of it. */ code = recog_memoized (prev); insn_extract (prev); NEXT_INSN (PREV_INSN (prev)) = 0; set_last_insn (PREV_INSN (prev)); /* Now once again start a sequence for our new instructions. */ start_sequence (); /* Emit a single-condition compare insn according to the type of operands and the condition to be tested. */ if (code == CODE_FOR_cmpsi) emit_insn (gen_cmpeqsi (recog_operand[0], recog_operand[1])); else if (code == CODE_FOR_cmpsf) emit_insn (gen_cmpeqsf (recog_operand[0], recog_operand[1])); else if (code == CODE_FOR_cmpdf) emit_insn (gen_cmpeqdf (recog_operand[0], recog_operand[1])); else abort (); /* Emit branch-if-true. */ emit_jump_insn (gen_cbranch (label)); DONE;}")(define_expand "bne" [(set (pc) (if_then_else (ne (cc0) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] "" "{ rtx label = operands[0]; enum insn_code code; rtx prev; end_sequence (); prev = get_last_insn (); code = recog_memoized (prev); insn_extract (prev); NEXT_INSN (PREV_INSN (prev)) = 0; set_last_insn (PREV_INSN (prev)); start_sequence ();
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -