📄 i960.md
字号:
;;- Machine description for Intel 80960 chip for GNU C compiler;; Copyright (C) 1992, 1995, 1998, 2001 Free Software Foundation, Inc.;; Contributed by Steven McGeady, Intel Corp.;; Additional work by Glenn Colon-Bonet, Jonathan Shapiro, Andy Wilson;; Converted to GCC 2.0 by Jim Wilson and Michael Tiemann, Cygnus Support.;; 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 2, 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, 59 Temple Place - Suite 330,;; Boston, MA 02111-1307, USA.;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.;; There are very few (4) 'f' registers, they can't be loaded/stored from/to;; memory, and some instructions explicitly require them, so we get better;; code by discouraging pseudo-registers from being allocated to them.;; However, we do want to allow all patterns which can store to them to;; include them in their constraints, so we always use '*f' in a destination;; constraint except when 'f' is the only alternative.;; Insn attributes which describe the i960.;; Modscan is not used, since the compiler never emits any of these insns.(define_attr "type" "move,arith,alu2,mult,div,modscan,load,store,branch,call,address,compare,fpload,fpstore,fpmove,fpcvt,fpcc,fpadd,fpmul,fpdiv,multi,misc" (const_string "arith"));; Length (in # of insns).(define_attr "length" "" (cond [(eq_attr "type" "load,fpload") (if_then_else (match_operand 1 "symbolic_memory_operand" "") (const_int 2) (const_int 1)) (eq_attr "type" "store,fpstore") (if_then_else (match_operand 0 "symbolic_memory_operand" "") (const_int 2) (const_int 1)) (eq_attr "type" "address") (const_int 2)] (const_int 1)))(define_asm_attributes [(set_attr "length" "1") (set_attr "type" "multi")]);; (define_function_unit {name} {num-units} {n-users} {test};; {ready-delay} {issue-delay} [{conflict-list}]);; The integer ALU(define_function_unit "alu" 2 0 (eq_attr "type" "arith,compare,move,address") 1 0)(define_function_unit "alu" 2 0 (eq_attr "type" "alu2") 2 0)(define_function_unit "alu" 2 0 (eq_attr "type" "mult") 5 0)(define_function_unit "alu" 2 0 (eq_attr "type" "div") 35 0)(define_function_unit "alu" 2 0 (eq_attr "type" "modscan") 3 0);; Memory with load-delay of 1 (i.e., 2 cycle load).(define_function_unit "memory" 1 0 (eq_attr "type" "load,fpload") 2 0);; Floating point operations.(define_function_unit "fp" 1 2 (eq_attr "type" "fpmove") 5 0)(define_function_unit "fp" 1 2 (eq_attr "type" "fpcvt") 35 0)(define_function_unit "fp" 1 2 (eq_attr "type" "fpcc") 10 0)(define_function_unit "fp" 1 2 (eq_attr "type" "fpadd") 10 0)(define_function_unit "fp" 1 2 (eq_attr "type" "fpmul") 20 0)(define_function_unit "fp" 1 2 (eq_attr "type" "fpdiv") 35 0);; Compare instructions.;; This controls RTL generation and register allocation.;; We generate RTL for comparisons and branches by having the cmpxx ;; patterns store away the operands. Then, the scc and bcc patterns;; emit RTL for both the compare and the branch.;;;; We start with the DEFINE_EXPANDs, then DEFINE_INSNs to match;; the patterns. Finally, we have the DEFINE_SPLITs for some of the scc;; insns that actually require more than one machine instruction.;; Put cmpsi first because it is expected to be the most common.(define_expand "cmpsi" [(set (reg:CC 36) (compare:CC (match_operand:SI 0 "nonimmediate_operand" "") (match_operand:SI 1 "general_operand" "")))] "" "{ i960_compare_op0 = operands[0]; i960_compare_op1 = operands[1]; DONE;}")(define_expand "cmpdf" [(set (reg:CC 36) (compare:CC (match_operand:DF 0 "register_operand" "r") (match_operand:DF 1 "nonmemory_operand" "rGH")))] "TARGET_NUMERICS" "{ i960_compare_op0 = operands[0]; i960_compare_op1 = operands[1]; DONE;}")(define_expand "cmpsf" [(set (reg:CC 36) (compare:CC (match_operand:SF 0 "register_operand" "r") (match_operand:SF 1 "nonmemory_operand" "rGH")))] "TARGET_NUMERICS" "{ i960_compare_op0 = operands[0]; i960_compare_op1 = operands[1]; DONE;}");; Now the DEFINE_INSNs for the compare and scc cases. First the compares.(define_insn "" [(set (reg:CC 36) (compare:CC (match_operand:SI 0 "register_operand" "d") (match_operand:SI 1 "arith_operand" "dI")))] "" "cmpi %0,%1" [(set_attr "type" "compare")])(define_insn "" [(set (reg:CC_UNS 36) (compare:CC_UNS (match_operand:SI 0 "register_operand" "d") (match_operand:SI 1 "arith_operand" "dI")))] "" "cmpo %0,%1" [(set_attr "type" "compare")])(define_insn "" [(set (reg:CC 36) (compare:CC (match_operand:DF 0 "register_operand" "r") (match_operand:DF 1 "nonmemory_operand" "rGH")))] "TARGET_NUMERICS" "cmprl %0,%1" [(set_attr "type" "fpcc")])(define_insn "" [(set (reg:CC 36) (compare:CC (match_operand:SF 0 "register_operand" "r") (match_operand:SF 1 "nonmemory_operand" "rGH")))] "TARGET_NUMERICS" "cmpr %0,%1" [(set_attr "type" "fpcc")]);; Instruction definitions for branch-on-bit-set and clear insns.(define_insn "" [(set (pc) (if_then_else (ne (sign_extract:SI (match_operand:SI 0 "register_operand" "d") (const_int 1) (match_operand:SI 1 "arith_operand" "dI")) (const_int 0)) (label_ref (match_operand 2 "" "")) (pc)))] "" "bbs%+ %1,%0,%l2" [(set_attr "type" "branch")])(define_insn "" [(set (pc) (if_then_else (eq (sign_extract:SI (match_operand:SI 0 "register_operand" "d") (const_int 1) (match_operand:SI 1 "arith_operand" "dI")) (const_int 0)) (label_ref (match_operand 2 "" "")) (pc)))] "" "bbc%+ %1,%0,%l2" [(set_attr "type" "branch")])(define_insn "" [(set (pc) (if_then_else (ne (zero_extract:SI (match_operand:SI 0 "register_operand" "d") (const_int 1) (match_operand:SI 1 "arith_operand" "dI")) (const_int 0)) (label_ref (match_operand 2 "" "")) (pc)))] "" "bbs%+ %1,%0,%l2" [(set_attr "type" "branch")])(define_insn "" [(set (pc) (if_then_else (eq (zero_extract:SI (match_operand:SI 0 "register_operand" "d") (const_int 1) (match_operand:SI 1 "arith_operand" "dI")) (const_int 0)) (label_ref (match_operand 2 "" "")) (pc)))] "" "bbc%+ %1,%0,%l2" [(set_attr "type" "branch")]);; ??? These will never match. The LOG_LINKs necessary to make these match;; are not created by flow. These remain as a reminder to make this work;; some day.(define_insn "" [(set (reg:CC 36) (compare (match_operand:SI 0 "arith_operand" "d") (match_operand:SI 1 "arith_operand" "+d"))) (set (match_dup 1) (plus:SI (match_dup 1) (const_int 1)))] "0" "cmpinci %0,%1" [(set_attr "type" "compare")])(define_insn "" [(set (reg:CC_UNS 36) (compare (match_operand:SI 0 "arith_operand" "d") (match_operand:SI 1 "arith_operand" "+d"))) (set (match_dup 1) (plus:SI (match_dup 1) (const_int 1)))] "0" "cmpinco %0,%1" [(set_attr "type" "compare")])(define_insn "" [(set (reg:CC 36) (compare (match_operand:SI 0 "arith_operand" "d") (match_operand:SI 1 "arith_operand" "+d"))) (set (match_dup 1) (minus:SI (match_dup 1) (const_int 1)))] "0" "cmpdeci %0,%1" [(set_attr "type" "compare")])(define_insn "" [(set (reg:CC_UNS 36) (compare (match_operand:SI 0 "arith_operand" "d") (match_operand:SI 1 "arith_operand" "+d"))) (set (match_dup 1) (minus:SI (match_dup 1) (const_int 1)))] "0" "cmpdeco %0,%1" [(set_attr "type" "compare")]);; Templates to store result of condition.;; '1' is stored if condition is true.;; '0' is stored if condition is false.;; These should use predicate "general_operand", since;; gcc seems to be creating mem references which use these;; templates.(define_expand "seq" [(set (match_operand:SI 0 "general_operand" "=d") (eq:SI (match_dup 1) (const_int 0)))] "" "{ operands[1] = gen_compare_reg (EQ, i960_compare_op0, i960_compare_op1);}")(define_expand "sne" [(set (match_operand:SI 0 "general_operand" "=d") (ne:SI (match_dup 1) (const_int 0)))] "" "{ operands[1] = gen_compare_reg (NE, i960_compare_op0, i960_compare_op1);}")(define_expand "sgt" [(set (match_operand:SI 0 "general_operand" "=d") (gt:SI (match_dup 1) (const_int 0)))] "" "{ operands[1] = gen_compare_reg (GT, i960_compare_op0, i960_compare_op1);}")(define_expand "sgtu" [(set (match_operand:SI 0 "general_operand" "=d") (gtu:SI (match_dup 1) (const_int 0)))] "" "{ operands[1] = gen_compare_reg (GTU, i960_compare_op0, i960_compare_op1);}")(define_expand "slt" [(set (match_operand:SI 0 "general_operand" "=d") (lt:SI (match_dup 1) (const_int 0)))] "" "{ operands[1] = gen_compare_reg (LT, i960_compare_op0, i960_compare_op1);}")(define_expand "sltu" [(set (match_operand:SI 0 "general_operand" "=d") (ltu:SI (match_dup 1) (const_int 0)))] "" "{ operands[1] = gen_compare_reg (LTU, i960_compare_op0, i960_compare_op1);}")(define_expand "sge" [(set (match_operand:SI 0 "general_operand" "=d") (ge:SI (match_dup 1) (const_int 0)))] "" "{ operands[1] = gen_compare_reg (GE, i960_compare_op0, i960_compare_op1);}")(define_expand "sgeu" [(set (match_operand:SI 0 "general_operand" "=d") (geu:SI (match_dup 1) (const_int 0)))] "" "{ operands[1] = gen_compare_reg (GEU, i960_compare_op0, i960_compare_op1);}")(define_expand "sle" [(set (match_operand:SI 0 "general_operand" "=d") (le:SI (match_dup 1) (const_int 0)))] "" "{ operands[1] = gen_compare_reg (LE, i960_compare_op0, i960_compare_op1);}")(define_expand "sleu" [(set (match_operand:SI 0 "general_operand" "=d") (leu:SI (match_dup 1) (const_int 0)))] "" "{ operands[1] = gen_compare_reg (LEU, i960_compare_op0, i960_compare_op1);}")(define_insn "" [(set (match_operand:SI 0 "general_operand" "=d") (eq:SI (match_operand:SI 1 "register_operand" "d") (const_int 0)))] "" "shro %1,1,%0" [(set_attr "type" "alu2")])(define_insn "" [(set (match_operand:SI 0 "general_operand" "=d") (match_operator:SI 1 "comparison_operator" [(reg:CC 36) (const_int 0)]))] "" "test%C1 %0" [(set_attr "type" "compare")])(define_insn "" [(set (match_operand:SI 0 "general_operand" "=d") (match_operator:SI 1 "comparison_operator" [(reg:CC_UNS 36) (const_int 0)]))] "" "test%C1 %0" [(set_attr "type" "compare")]);; These control RTL generation for conditional jump insns;; and match them for register allocation.(define_expand "beq" [(set (pc) (if_then_else (eq (match_dup 1) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] "" "{ operands[1] = gen_compare_reg (EQ, i960_compare_op0, i960_compare_op1); }")(define_expand "bne" [(set (pc) (if_then_else (ne (match_dup 1) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] "" "{ operands[1] = gen_compare_reg (NE, i960_compare_op0, i960_compare_op1); }")(define_expand "bgt" [(set (pc) (if_then_else (gt (match_dup 1) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] "" "{ operands[1] = gen_compare_reg (GT, i960_compare_op0, i960_compare_op1); }")(define_expand "bgtu" [(set (pc) (if_then_else (gtu (match_dup 1) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] "" "{ operands[1] = gen_compare_reg (GTU, i960_compare_op0, i960_compare_op1); }")(define_expand "blt" [(set (pc) (if_then_else (lt (match_dup 1) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] "" "{ operands[1] = gen_compare_reg (LT, i960_compare_op0, i960_compare_op1); }")(define_expand "bltu" [(set (pc) (if_then_else (ltu (match_dup 1) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] "" "{ operands[1] = gen_compare_reg (LTU, i960_compare_op0, i960_compare_op1); }")(define_expand "bge" [(set (pc) (if_then_else (ge (match_dup 1) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] "" "{ operands[1] = gen_compare_reg (GE, i960_compare_op0, i960_compare_op1); }")(define_expand "bgeu" [(set (pc) (if_then_else (geu (match_dup 1) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] "" "{ operands[1] = gen_compare_reg (GEU, i960_compare_op0, i960_compare_op1); }")(define_expand "ble" [(set (pc) (if_then_else (le (match_dup 1) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] "" "{ operands[1] = gen_compare_reg (LE, i960_compare_op0, i960_compare_op1); }")(define_expand "bleu" [(set (pc) (if_then_else (leu (match_dup 1) (const_int 0))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -