i386.md

来自「gcc3.2.1源代码」· Markdown 代码 · 共 2,041 行 · 第 1/5 页

MD
2,041
字号
;; GCC machine description for IA-32 and x86-64.;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002;; Free Software Foundation, Inc.;; Mostly by William Schelter.;; x86_64 support added by Jan Hubicka;;;; 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.;; 9  This is an `fnstsw' operation.;; 10 This is a `sahf' operation.;; 11 This is a `fstcw' operation;; 12 This is behaviour of add when setting carry flag.;; 13 This is a `eh_return' placeholder.;; For SSE/MMX support:;; 30 This is `fix', guaranteed to be truncating.;; 31 This is a `emms' operation.;; 32 This is a `maskmov' operation.;; 33 This is a `movmsk' operation.;; 34 This is a `non-temporal' move.;; 36 This is used to distinguish COMISS from UCOMISS.;; 37 This is a `ldmxcsr' operation.;; 38 This is a forced `movaps' instruction (rather than whatever movti does);; 39 This is a forced `movups' instruction (rather than whatever movti does);; 40 This is a `stmxcsr' operation.;; 41 This is a `shuffle' operation.;; 42 This is a `rcp' operation.;; 43 This is a `rsqsrt' operation.;; 44 This is a `sfence' operation.;; 45 This is a noop to prevent excessive combiner cleverness.;; 46 This is a `femms' operation.;; 49 This is a 'pavgusb' operation.;; 50 This is a `pfrcp' operation.;; 51 This is a `pfrcpit1' operation.;; 52 This is a `pfrcpit2' operation.;; 53 This is a `pfrsqrt' operation.;; 54 This is a `pfrsqrit1' operation.;; Insns whose names begin with "x86_" are emitted by gen_FOO calls;; from i386.c.;; In C guard expressions, put expressions which may be compile-time;; constants first.  This allows for better optimization.  For;; example, write "TARGET_64BIT && reload_completed", not;; "reload_completed && TARGET_64BIT".;; Processor type.  This attribute must exactly match the processor_type;; enumeration in i386.h.(define_attr "cpu" "i386,i486,pentium,pentiumpro,k6,athlon,pentium4"  (const (symbol_ref "ix86_cpu")));; A basic instruction type.  Refinements due to arguments to be;; provided in other attributes.(define_attr "type"  "other,multi,alu1,negnot,alu,icmp,test,imov,imovx,lea,incdec,ishift,imul,idiv,ibr,setcc,push,pop,call,callv,icmov,fmov,fop,fop1,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,str,cld,sse,mmx,fistp"  (const_string "other"));; Main data type used by the insn(define_attr "mode" "unknown,none,QI,HI,SI,DI,unknownfp,SF,DF,XF,TI"  (const_string "unknown"));; Set for i387 operations.(define_attr "i387" ""  (if_then_else (eq_attr "type" "fmov,fop,fop1,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp")    (const_int 1)    (const_int 0)));; The (bounding maximum) length of an instruction immediate.(define_attr "length_immediate" ""  (cond [(eq_attr "type" "incdec,setcc,icmov,ibr,str,cld,lea,other,multi,idiv,sse,mmx")	   (const_int 0)	 (eq_attr "i387" "1")	   (const_int 0)	 (eq_attr "type" "alu1,negnot,alu,icmp,imovx,ishift,imul,push,pop")	   (symbol_ref "ix86_attr_length_immediate_default(insn,1)")	 (eq_attr "type" "imov,test")	   (symbol_ref "ix86_attr_length_immediate_default(insn,0)")	 (eq_attr "type" "call")	   (if_then_else (match_operand 0 "constant_call_address_operand" "")	     (const_int 4)	     (const_int 0))	 (eq_attr "type" "callv")	   (if_then_else (match_operand 1 "constant_call_address_operand" "")	     (const_int 4)	     (const_int 0))	 (eq_attr "type" "ibr")	   (if_then_else (and (ge (minus (match_dup 0) (pc))				  (const_int -128))			      (lt (minus (match_dup 0) (pc))				  (const_int 124)))	     (const_int 1)	     (const_int 4))	 ]	 (symbol_ref "/* Update immediate_length and other attributes! */ abort(),1")));; The (bounding maximum) length of an instruction address.(define_attr "length_address" ""  (cond [(eq_attr "type" "str,cld,other,multi,fxch")	   (const_int 0)	 (and (eq_attr "type" "call")	      (match_operand 1 "constant_call_address_operand" ""))	     (const_int 0)	 (and (eq_attr "type" "callv")	      (match_operand 1 "constant_call_address_operand" ""))	     (const_int 0)	 ]	 (symbol_ref "ix86_attr_length_address_default (insn)")));; Set when length prefix is used.(define_attr "prefix_data16" ""  (if_then_else (eq_attr "mode" "HI")    (const_int 1)    (const_int 0)));; Set when string REP prefix is used.(define_attr "prefix_rep" "" (const_int 0));; Set when 0f opcode prefix is used.(define_attr "prefix_0f" ""  (if_then_else (eq_attr "type" "imovx,setcc,icmov,sse,mmx")    (const_int 1)    (const_int 0)));; Set when modrm byte is used.(define_attr "modrm" ""  (cond [(eq_attr "type" "str,cld")	   (const_int 0)	 (eq_attr "i387" "1")	   (const_int 0)         (and (eq_attr "type" "incdec")	      (ior (match_operand:SI 1 "register_operand" "")		   (match_operand:HI 1 "register_operand" "")))	   (const_int 0)	 (and (eq_attr "type" "push")	      (not (match_operand 1 "memory_operand" "")))	   (const_int 0)	 (and (eq_attr "type" "pop")	      (not (match_operand 0 "memory_operand" "")))	   (const_int 0)	 (and (eq_attr "type" "imov")	      (and (match_operand 0 "register_operand" "")	           (match_operand 1 "immediate_operand" "")))	   (const_int 0)	 ]	 (const_int 1)));; The (bounding maximum) length of an instruction in bytes.;; ??? fistp is in fact fldcw/fistp/fldcw sequence.  Later we may want;; to split it and compute proper length as for other insns.(define_attr "length" ""  (cond [(eq_attr "type" "other,multi,fistp")	   (const_int 16)	 ]	 (plus (plus (attr "modrm")		     (plus (attr "prefix_0f")			   (plus (attr "i387")				 (const_int 1))))	       (plus (attr "prefix_rep")		     (plus (attr "prefix_data16")			   (plus (attr "length_immediate")				 (attr "length_address")))))));; The `memory' attribute is `none' if no memory is referenced, `load' or;; `store' if there is a simple memory reference therein, or `unknown';; if the instruction is complex.(define_attr "memory" "none,load,store,both,unknown"  (cond [(eq_attr "type" "other,multi,str")	   (const_string "unknown")	 (eq_attr "type" "lea,fcmov,fpspc,cld")	   (const_string "none")	 (eq_attr "type" "fistp")	   (const_string "both")	 (eq_attr "type" "push")	   (if_then_else (match_operand 1 "memory_operand" "")	     (const_string "both")	     (const_string "store"))	 (eq_attr "type" "pop,setcc")	   (if_then_else (match_operand 0 "memory_operand" "")	     (const_string "both")	     (const_string "load"))	 (eq_attr "type" "icmp,test")	   (if_then_else (ior (match_operand 0 "memory_operand" "")			      (match_operand 1 "memory_operand" ""))	     (const_string "load")	     (const_string "none"))	 (eq_attr "type" "ibr")	   (if_then_else (match_operand 0 "memory_operand" "")	     (const_string "load")	     (const_string "none"))	 (eq_attr "type" "call")	   (if_then_else (match_operand 0 "constant_call_address_operand" "")	     (const_string "none")	     (const_string "load"))	 (eq_attr "type" "callv")	   (if_then_else (match_operand 1 "constant_call_address_operand" "")	     (const_string "none")	     (const_string "load"))	 (and (eq_attr "type" "alu1,negnot")	      (match_operand 1 "memory_operand" ""))	   (const_string "both")	 (and (match_operand 0 "memory_operand" "")	      (match_operand 1 "memory_operand" ""))	   (const_string "both")	 (match_operand 0 "memory_operand" "")	   (const_string "store")	 (match_operand 1 "memory_operand" "")	   (const_string "load")	 (and (eq_attr "type" "!icmp,test,alu1,negnot,fop1,fsgn,imov,imovx,fmov,fcmp,sse,mmx")	      (match_operand 2 "memory_operand" ""))	   (const_string "load")	 (and (eq_attr "type" "icmov")	      (match_operand 3 "memory_operand" ""))	   (const_string "load")	]	(const_string "none")));; Indicates if an instruction has both an immediate and a displacement.(define_attr "imm_disp" "false,true,unknown"  (cond [(eq_attr "type" "other,multi")	   (const_string "unknown")	 (and (eq_attr "type" "icmp,test,imov")	      (and (match_operand 0 "memory_displacement_operand" "")		   (match_operand 1 "immediate_operand" "")))	   (const_string "true")	 (and (eq_attr "type" "alu,ishift,imul,idiv")	      (and (match_operand 0 "memory_displacement_operand" "")		   (match_operand 2 "immediate_operand" "")))	   (const_string "true")	]	(const_string "false")));; Indicates if an FP operation has an integer source.(define_attr "fp_int_src" "false,true"  (const_string "false"));; Describe a user's asm statement.(define_asm_attributes  [(set_attr "length" "128")   (set_attr "type" "multi")]);; Pentium Scheduling;;;; The Pentium is an in-order core with two integer pipelines.;; True for insns that behave like prefixed insns on the Pentium.(define_attr "pent_prefix" "false,true"  (if_then_else (ior (eq_attr "prefix_0f" "1")  		     (ior (eq_attr "prefix_data16" "1")			  (eq_attr "prefix_rep" "1")))    (const_string "true")    (const_string "false")));; Categorize how an instruction slots.;; The non-MMX Pentium slots an instruction with prefixes on U pipe only,;; while MMX Pentium can slot it on either U or V.  Model non-MMX Pentium;; rules, because it results in noticeably better code on non-MMX Pentium;; and doesn't hurt much on MMX.  (Prefixed instructions are not very;; common, so the scheduler usualy has a non-prefixed insn to pair).(define_attr "pent_pair" "uv,pu,pv,np"  (cond [(eq_attr "imm_disp" "true")	   (const_string "np")	 (ior (eq_attr "type" "alu1,alu,imov,icmp,test,lea,incdec")	      (and (eq_attr "type" "pop,push")		   (eq_attr "memory" "!both")))	   (if_then_else (eq_attr "pent_prefix" "true")	     (const_string "pu")	     (const_string "uv"))	 (eq_attr "type" "ibr")	   (const_string "pv")	 (and (eq_attr "type" "ishift")	      (match_operand 2 "const_int_operand" ""))	   (const_string "pu")	 (and (eq_attr "type" "call")	      (match_operand 0 "constant_call_address_operand" ""))	   (const_string "pv")	 (and (eq_attr "type" "callv")	      (match_operand 1 "constant_call_address_operand" ""))	   (const_string "pv")	]	(const_string "np")));; Rough readiness numbers.  Fine tuning happens in i386.c.;;;; u	describes pipe U;; v	describes pipe V;; uv	describes either pipe U or V for those that can issue to either;; np	describes not paring;; fpu	describes fpu;; fpm	describes fp insns of different types are not pipelined.;;;; ??? fxch isn't handled; not an issue until sched3 after reg-stack is real.(define_function_unit "pent_np" 1 0  (and (eq_attr "cpu" "pentium")       (eq_attr "type" "imul"))  11 11)(define_function_unit "pent_mul" 1 1  (and (eq_attr "cpu" "pentium")       (eq_attr "type" "imul"))  11 11);; Rep movs takes minimally 12 cycles.(define_function_unit "pent_np" 1 0  (and (eq_attr "cpu" "pentium")       (eq_attr "type" "str"))  12 12); ??? IDIV for SI takes 46 cycles, for HI 30, for QI 22(define_function_unit "pent_np" 1 0  (and (eq_attr "cpu" "pentium")       (eq_attr "type" "idiv"))  46 46); Fp reg-reg moves takes 1 cycle. Loads takes 1 cycle for SF/DF mode,; 3 cycles for XFmode.  Stores takes 2 cycles for SF/DF and 3 for XF.; fldz and fld1 takes 2 cycles.  Only reg-reg moves are pairable.; The integer <-> fp conversion is not modeled correctly. Fild behaves; like normal fp operation and fist takes 6 cycles.(define_function_unit "fpu" 1 0  (and (eq_attr "cpu" "pentium")       (and (eq_attr "type" "fmov")	    (and (eq_attr "memory" "load,store")		 (eq_attr "mode" "XF"))))  3 3)(define_function_unit "pent_np" 1 0  (and (eq_attr "cpu" "pentium")       (and (eq_attr "type" "fmov")	    (and (eq_attr "memory" "load,store")		 (eq_attr "mode" "XF"))))  3 3)(define_function_unit "fpu" 1 0  (and (eq_attr "cpu" "pentium")       (and (eq_attr "type" "fmov")            (ior (match_operand 1 "immediate_operand" "")	         (eq_attr "memory" "store"))))  2 2)

⌨️ 快捷键说明

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