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

📄 i386.md

📁 gcc编译工具没有什么特别
💻 MD
📖 第 1 页 / 共 5 页
字号:
; GCC machine description for Intel X86.;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000 Free Software;; Foundation, Inc.;; Mostly by William Schelter.;; 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. */;; The original PO technology requires these to be ordered by speed,;; so that assigner will pick the fastest.;; See file "rtl.def" for documentation on define_insn, match_*, et. al.;; Macro #define NOTICE_UPDATE_CC in file i386.h handles condition code;; updates for most instructions.;; Macro REG_CLASS_FROM_LETTER in file i386.h defines the register;; constraint letters.;; the special asm out single letter directives following a '%' are:;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of;;     operands[1].;; 'L' Print the opcode suffix for a 32-bit integer opcode.;; 'W' Print the opcode suffix for a 16-bit integer opcode.;; 'B' Print the opcode suffix for an 8-bit integer opcode.;; 'Q' Print the opcode suffix for a 64-bit float opcode.;; 'S' Print the opcode suffix for a 32-bit float opcode.;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.;; 'J' Print the appropriate jump operand.;; 'b' Print the QImode name of the register for the indicated operand.;;     %b0 would print %al if operands[0] is reg 0.;; 'w' Likewise, print the HImode name of the register.;; 'k' Likewise, print the SImode name of the register.;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.;; 'y' Print "st(0)" instead of "st" as a register.;; UNSPEC usage:;; 0  This is a `scas' operation.  The mode of the UNSPEC is always SImode.;;    operand 0 is the memory address to scan.;;    operand 1 is a register containing the value to scan for.  The mode;;       of the scas opcode will be the same as the mode of this operand.;;    operand 2 is the known alignment of operand 0.;; 1  This is a `sin' operation.  The mode of the UNSPEC is MODE_FLOAT.;;    operand 0 is the argument for `sin'.;; 2  This is a `cos' operation.  The mode of the UNSPEC is MODE_FLOAT.;;    operand 0 is the argument for `cos'.;; 3  This is part of a `stack probe' operation.  The mode of the UNSPEC is ;;    always SImode.  operand 0 is the size of the stack allocation.;; 4  This is the source of a fake SET of the frame pointer which is used to;;    prevent insns referencing it being scheduled across the initial;;    decrement of the stack pointer.;; 5  This is a `bsf' operation.;; 6  This is the @GOT offset of a PIC address.;; 7  This is the @GOTOFF offset of a PIC address.;; 8  This is a reference to a symbol's @PLT address.;; This shadows the processor_type enumeration, so changes must be made;; to i386.h at the same time.(define_attr "type"  "integer,binary,memory,test,compare,fcompare,idiv,imul,lea,fld,fpop,fpdiv,fpmul"  (const_string "integer"))(define_attr "memory" "none,load,store"  (cond [(eq_attr "type" "idiv,lea")	 (const_string "none")	 (eq_attr "type" "fld")	 (const_string "load")	 (eq_attr "type" "test")	 (if_then_else (match_operand 0 "memory_operand" "")		       (const_string "load")		       (const_string "none"))	 (eq_attr "type" "compare,fcompare")	 (if_then_else (ior (match_operand 0 "memory_operand" "")			    (match_operand 1 "memory_operand" ""))		       (const_string "load")		       (const_string "none"))	 (and (eq_attr "type" "integer,memory,fpop")	      (match_operand 0 "memory_operand" ""))	 (const_string "store")	 (and (eq_attr "type" "integer,memory,fpop")	      (match_operand 1 "memory_operand" ""))	 (const_string "load")	 (and (eq_attr "type" "binary,imul,fpmul,fpdiv")	      (ior (match_operand 1 "memory_operand" "")		   (match_operand 2 "memory_operand" "")))	 (const_string "load")]	(const_string "none")));; Functional units; (define_function_unit NAME MULTIPLICITY SIMULTANEITY;                       TEST READY-DELAY ISSUE-DELAY [CONFLICT-LIST]); pentiumpro has a reservation station with 5 ports; port  0 has integer, float add, integer divide, float divide, float ;        multiply, and shifter units.; port  1 has integer, and jump units.; port  2 has the load address generation unit; ports 3 and 4 have the store address generation units; pentium has two integer pipelines, the main u pipe and the secondary v pipe.; and a float pipeline;; Floating point(define_function_unit "fp" 1 0 (and (eq_attr "type" "fpop,fcompare") (eq_attr "cpu" "i386,i486")) 5 5)(define_function_unit "fp" 1 0 (and (eq_attr "type" "fpop,fcompare") (eq_attr "cpu" "pentium,pentiumpro"))  3 0)(define_function_unit "fp" 1 0 (and (eq_attr "type" "fpmul") (eq_attr "cpu" "pentium"))  7 0)(define_function_unit "fp" 1 0 (and (eq_attr "type" "fpmul") (eq_attr "cpu" "pentiumpro"))  5 0)(define_function_unit "fp" 1 0 (and (eq_attr "type" "idiv") (eq_attr "cpu" "pentiumpro"))  10 10)(define_function_unit "fp" 1 0 (and (eq_attr "type" "imul") (eq_attr "cpu" "pentiumpro"))  6 0)(define_function_unit "fp" 1 0 (eq_attr "type" "fpdiv")  10 10)(define_function_unit "fp" 1 0  (and (eq_attr "type" "fld") (eq_attr "cpu" "!pentiumpro,k6")) 1 0);; K6 FPU is not pipelined.(define_function_unit "fp" 1 0  (and (eq_attr "type" "fpop,fpmul,fcompare") (eq_attr "cpu" "k6")) 2 2);; i386 and i486 have one integer unit, which need not be modeled(define_function_unit "integer" 2 0  (and (eq_attr "type" "integer,binary,test,compare,lea") (eq_attr "cpu" "pentium,pentiumpro")) 1 0)(define_function_unit "integer" 2 0  (and (eq_attr "cpu" "k6")       (and (eq_attr "type" "integer,binary,test,compare")	    (eq_attr "memory" "!load")))  1 0);; Internally, K6 converts REG OP MEM instructions into a load (2 cycles);; and a register operation (1 cycle).(define_function_unit "integer" 2 0  (and (eq_attr "cpu" "k6")       (and (eq_attr "type" "integer,binary,test,compare")	    (eq_attr "memory" "load")))  3 0);; Multiplies use one of the integer units(define_function_unit "integer" 2 0  (and (eq_attr "cpu" "pentium") (eq_attr "type" "imul"))  11 11)(define_function_unit "integer" 2 0  (and (eq_attr "cpu" "k6") (eq_attr "type" "imul"))  2 2)(define_function_unit "integer" 2 0  (and (eq_attr "cpu" "pentium") (eq_attr "type" "idiv"))  25 25)(define_function_unit "integer" 2 0  (and (eq_attr "cpu" "k6") (eq_attr "type" "idiv"))  17 17);; Pentium Pro and K6 have a separate load unit.(define_function_unit "load" 1 0  (and (eq_attr "cpu" "pentiumpro") (eq_attr "memory" "load"))  3 0)(define_function_unit "load" 1 0  (and (eq_attr "cpu" "k6") (eq_attr "memory" "load"))  2 0);; Pentium Pro and K6 have a separate store unit.(define_function_unit "store" 1 0  (and (eq_attr "cpu" "pentiumpro,k6") (eq_attr "memory" "store"))  1 0);; lea executes in the K6 store unit with 1 cycle latency(define_function_unit "store" 1 0  (and (eq_attr "cpu" "k6") (eq_attr "type" "lea"))  1 0);; "movl MEM,REG / testl REG,REG" is faster on a 486 than "cmpl $0,MEM".;; But restricting MEM here would mean that gcc could not remove a redundant;; test in cases like "incl MEM / je TARGET".;;;; We don't want to allow a constant operand for test insns because;; (set (cc0) (const_int foo)) has no mode information.  Such insns will;; be folded while optimizing anyway.;; All test insns have expanders that save the operands away without;; actually generating RTL.  The bCOND or sCOND (emitted immediately;; after the tstM or cmp) will actually emit the tstM or cmpM.;; Processor type -- this attribute must exactly match the processor_type;; enumeration in i386.h.(define_attr "cpu" "i386,i486,pentium,pentiumpro,k6"  (const (symbol_ref "ix86_cpu")))(define_insn "tstsi_1"  [(set (cc0)	(match_operand:SI 0 "nonimmediate_operand" "rm"))]  ""  "*{  if (REG_P (operands[0]))    return AS2 (test%L0,%0,%0);  operands[1] = const0_rtx;  return AS2 (cmp%L0,%1,%0);}"  [(set_attr "type" "test")])(define_expand "tstsi"  [(set (cc0)	(match_operand:SI 0 "nonimmediate_operand" ""))]  ""  "{  i386_compare_gen = gen_tstsi_1;  i386_compare_op0 = operands[0];  i386_compare_op1 = const0_rtx;  DONE;}")(define_insn "tsthi_1"  [(set (cc0)	(match_operand:HI 0 "nonimmediate_operand" "rm"))]  ""  "*{  if (REG_P (operands[0]))    return AS2 (test%W0,%0,%0);  operands[1] = const0_rtx;  return AS2 (cmp%W0,%1,%0);}"  [(set_attr "type" "test")])(define_expand "tsthi"  [(set (cc0)	(match_operand:HI 0 "nonimmediate_operand" ""))]  ""  "{  i386_compare_gen = gen_tsthi_1;  i386_compare_op0 = operands[0];  i386_compare_op1 = const0_rtx;  DONE;}")(define_insn "tstqi_1"  [(set (cc0)	(match_operand:QI 0 "nonimmediate_operand" "qm"))]  ""  "*{  if (REG_P (operands[0]))    return AS2 (test%B0,%0,%0);  operands[1] = const0_rtx;  return AS2 (cmp%B0,%1,%0);}"  [(set_attr "type" "test")])(define_expand "tstqi"  [(set (cc0)	(match_operand:QI 0 "nonimmediate_operand" ""))]  ""  "{  i386_compare_gen = gen_tstqi_1;  i386_compare_op0 = operands[0];  i386_compare_op1 = const0_rtx;  DONE;}")(define_insn "tstsf_cc"  [(set (cc0)	(match_operand:SF 0 "register_operand" "f"))   (clobber (match_scratch:HI 1 "=a"))]  "TARGET_80387 && ! TARGET_IEEE_FP"  "*{  if (! STACK_TOP_P (operands[0]))    abort ();  output_asm_insn (\"ftst\", operands);  if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))    output_asm_insn (AS1 (fstp,%y0), operands);  return output_fp_cc0_set (insn);}"  [(set_attr "type" "test")]);; Don't generate tstsf if generating IEEE code, since the `ftst' opcode;; isn't IEEE compliant.(define_expand "tstsf"  [(parallel [(set (cc0)		   (match_operand:SF 0 "register_operand" ""))	      (clobber (match_scratch:HI 1 ""))])]  "TARGET_80387 && ! TARGET_IEEE_FP"  "{  i386_compare_gen = gen_tstsf_cc;  i386_compare_op0 = operands[0];  i386_compare_op1 = const0_rtx;  DONE;}")(define_insn "tstdf_cc"  [(set (cc0)	(match_operand:DF 0 "register_operand" "f"))   (clobber (match_scratch:HI 1 "=a"))]  "TARGET_80387 && ! TARGET_IEEE_FP"  "*{  if (! STACK_TOP_P (operands[0]))    abort ();  output_asm_insn (\"ftst\", operands);  if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))    output_asm_insn (AS1 (fstp,%y0), operands);  return output_fp_cc0_set (insn);}"  [(set_attr "type" "test")]);; Don't generate tstdf if generating IEEE code, since the `ftst' opcode;; isn't IEEE compliant.(define_expand "tstdf"  [(parallel [(set (cc0)		   (match_operand:DF 0 "register_operand" ""))	      (clobber (match_scratch:HI 1 ""))])]  "TARGET_80387 && ! TARGET_IEEE_FP"  "{  i386_compare_gen = gen_tstdf_cc;  i386_compare_op0 = operands[0];  i386_compare_op1 = const0_rtx;  DONE;}")(define_insn "tstxf_cc"  [(set (cc0)	(match_operand:XF 0 "register_operand" "f"))   (clobber (match_scratch:HI 1 "=a"))]  "TARGET_80387 && ! TARGET_IEEE_FP"  "*{  if (! STACK_TOP_P (operands[0]))    abort ();  output_asm_insn (\"ftst\", operands);  if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))    output_asm_insn (AS1 (fstp,%y0), operands);  return output_fp_cc0_set (insn);}"  [(set_attr "type" "test")]);; Don't generate tstxf if generating IEEE code, since the `ftst' opcode;; isn't IEEE compliant.(define_expand "tstxf"  [(parallel [(set (cc0)		   (match_operand:XF 0 "register_operand" ""))	      (clobber (match_scratch:HI 1 ""))])]  "TARGET_80387 && ! TARGET_IEEE_FP"  "{  i386_compare_gen = gen_tstxf_cc;  i386_compare_op0 = operands[0];  i386_compare_op1 = const0_rtx;  DONE;}");;- compare instructions.  See comments above tstM patterns about;;  expansion of these insns.(define_insn "cmpsi_1"  [(set (cc0)	(compare (match_operand:SI 0 "nonimmediate_operand" "mr,r")		 (match_operand:SI 1 "general_operand" "ri,mr")))]  "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"  "* return AS2 (cmp%L0,%1,%0);"  [(set_attr "type" "compare")])(define_expand "cmpsi"  [(set (cc0)	(compare (match_operand:SI 0 "nonimmediate_operand" "")		 (match_operand:SI 1 "general_operand" "")))]  ""  "{  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)    operands[0] = force_reg (SImode, operands[0]);  i386_compare_gen = gen_cmpsi_1;  i386_compare_op0 = operands[0];

⌨️ 快捷键说明

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