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

📄 bfin.md

📁 Mac OS X 10.4.9 for x86 Source Code gcc 实现源代码
💻 MD
📖 第 1 页 / 共 4 页
字号:
;;- Machine description for Blackfin for GNU compiler;;  Copyright 2005  Free Software Foundation, Inc.;;  Contributed by Analog Devices.;; This file is part of GCC.;; GCC 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.;; GCC 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 GCC; see the file COPYING.  If not, write to;; the Free Software Foundation, 59 Temple Place - Suite 330,;; Boston, MA 02111-1307, USA.; operand punctuation marks:;;     X -- integer value printed as log2;     Y -- integer value printed as log2(~value) - for bitclear;     h -- print half word register, low part;     d -- print half word register, high part;     D -- print operand as dregs pairs;     w -- print operand as accumulator register word (a0w, a1w);     H -- high part of double mode operand;     T -- byte register representation Oct. 02 2001; constant operand classes;;     J   2**N       5bit imm scaled;     Ks7 -64 .. 63  signed 7bit imm;     Ku5 0..31      unsigned 5bit imm;     Ks4 -8 .. 7    signed 4bit imm;     Ks3 -4 .. 3    signed 3bit imm;     Ku3 0 .. 7     unsigned 3bit imm;     Pn  0, 1, 2    constants 0, 1 or 2, corresponding to n;; register operands;     d  (r0..r7);     a  (p0..p5,fp,sp);     e  (a0, a1);     b  (i0..i3);     f  (m0..m3);     B;     c (i0..i3,m0..m3) CIRCREGS;     C (CC)            CCREGS;;; Define constants for hard registers.(define_constants  [(REG_R0 0)   (REG_R1 1)   (REG_R2 2)   (REG_R3 3)   (REG_R4 4)   (REG_R5 5)   (REG_R6 6)   (REG_R7 7)   (REG_P0 8)   (REG_P1 9)   (REG_P2 10)   (REG_P3 11)   (REG_P4 12)   (REG_P5 13)   (REG_P6 14)   (REG_P7 15)   (REG_SP 14)   (REG_FP 15)   (REG_I0 16)   (REG_B0 17)   (REG_L0 18)   (REG_I1 19)   (REG_B1 20)   (REG_L1 21)   (REG_I2 22)   (REG_B2 23)   (REG_L2 24)   (REG_I3 25)   (REG_B3 26)   (REG_L3 27)   (REG_M0 28)   (REG_M1 29)   (REG_M2 30)   (REG_M3 31)   (REG_A0 32)   (REG_A1 33)   (REG_CC 34)   (REG_RETS 35)   (REG_RETI 36)   (REG_RETX 37)   (REG_RETN 38)   (REG_RETE 39)   (REG_ASTAT 40)   (REG_SEQSTAT 41)   (REG_USP 42)   (REG_ARGP 43)]);; Constants used in UNSPECs and UNSPEC_VOLATILEs.(define_constants  [(UNSPEC_CBRANCH_TAKEN 0)   (UNSPEC_CBRANCH_NOPS 1)   (UNSPEC_RETURN 2)   (UNSPEC_MOVE_PIC 3)   (UNSPEC_LIBRARY_OFFSET 4)   (UNSPEC_PUSH_MULTIPLE 5)])(define_constants  [(UNSPEC_VOLATILE_EH_RETURN 0)])(define_attr "type"  "move,mvi,mcld,mcst,dsp32,mult,alu0,shft,brcc,br,call,misc,compare,dummy"  (const_string "misc"));; Scheduling definitions(define_automaton "bfin")(define_cpu_unit "core" "bfin")(define_insn_reservation "alu" 1  (eq_attr "type" "move,mvi,mcst,dsp32,alu0,shft,brcc,br,call,misc,compare")  "core")(define_insn_reservation "imul" 3  (eq_attr "type" "mult")  "core*3")(define_insn_reservation "load" 1  (eq_attr "type" "mcld")  "core");; Make sure genautomata knows about the maximum latency that can be produced;; by the adjust_cost function.(define_insn_reservation "dummy" 5  (eq_attr "type" "mcld")  "core");; Operand and operator predicates(include "predicates.md");;; FRIO branches have been optimized for code density;;; this comes at a slight cost of complexity when;;; a compiler needs to generate branches in the general;;; case.  In order to generate the correct branching;;; mechanisms the compiler needs keep track of instruction;;; lengths.  The follow table describes how to count instructions;;; for the FRIO architecture.;;;;;; unconditional br are 12-bit imm pcrelative branches *2;;; conditional   br are 10-bit imm pcrelative branches *2;;; brcc 10-bit:;;;   1024 10-bit imm *2 is 2048 (-1024..1022);;; br 12-bit  :;;;   4096 12-bit imm *2 is 8192 (-4096..4094);;; NOTE : For brcc we generate instructions such as;;;   if cc jmp; jump.[sl] offset;;;   offset of jump.[sl] is from the jump instruction but;;;     gcc calculates length from the if cc jmp instruction;;;     furthermore gcc takes the end address of the branch instruction;;;     as (pc) for a forward branch;;;     hence our range is (-4094, 4092) instead of (-4096, 4094) for a br;;;;;; The way the (pc) rtx works in these calculations is somewhat odd;;;; for backward branches it's the address of the current instruction,;;; for forward branches it's the previously known address of the following;;; instruction - we have to take this into account by reducing the range;;; for a forward branch.;; Lengths for type "mvi" insns are always defined by the instructions;; themselves.(define_attr "length" ""  (cond [(eq_attr "type" "mcld")         (if_then_else (match_operand 1 "effective_address_32bit_p" "")                       (const_int 4) (const_int 2))	 (eq_attr "type" "mcst")	 (if_then_else (match_operand 0 "effective_address_32bit_p" "")		       (const_int 4) (const_int 2))	 (eq_attr "type" "move") (const_int 2)	 (eq_attr "type" "dsp32") (const_int 4)	 (eq_attr "type" "call")  (const_int 4)         (eq_attr "type" "br")  	 (if_then_else (and	                  (le (minus (match_dup 0) (pc)) (const_int 4092))	                  (ge (minus (match_dup 0) (pc)) (const_int -4096)))        	  (const_int 2)                  (const_int 4))         (eq_attr "type" "brcc")	 (cond [(and	            (le (minus (match_dup 3) (pc)) (const_int 1020))	            (ge (minus (match_dup 3) (pc)) (const_int -1024)))		  (const_int 2)		(and	            (le (minus (match_dup 3) (pc)) (const_int 4092))	            (ge (minus (match_dup 3) (pc)) (const_int -4094)))		  (const_int 4)]	       (const_int 6))        ]	(const_int 2)));; Conditional moves(define_expand "movsicc"  [(set (match_operand:SI 0 "validreg_operand" "")        (if_then_else:SI (match_operand 1 "comparison_operator" "")                         (match_operand:SI 2 "validreg_operand" "")                         (match_operand:SI 3 "validreg_operand" "")))]  ""{  operands[1] = bfin_gen_compare (operands[1], SImode);})(define_insn "*movsicc_insn1"  [(set (match_operand:SI 0 "validreg_operand" "=da,da,da")        (if_then_else:SI	    (eq:BI (match_operand:BI 3 "cc_operand" "C,C,C")		(const_int 0))	    (match_operand:SI 1 "validreg_operand" "da,0,da")	    (match_operand:SI 2 "validreg_operand" "0,da,da")))]  ""  "@    if !cc %0 =%1; /* movsicc-1a */    if cc %0 =%2; /* movsicc-1b */    if !cc %0 =%1; if cc %0=%2; /* movsicc-1 */"  [(set_attr "length" "2,2,4")   (set_attr "type" "move")])(define_insn "*movsicc_insn2"  [(set (match_operand:SI 0 "validreg_operand" "=da,da,da")        (if_then_else:SI	    (ne:BI (match_operand:BI 3 "cc_operand" "C,C,C")		(const_int 0))	    (match_operand:SI 1 "validreg_operand" "0,da,da")	    (match_operand:SI 2 "validreg_operand" "da,0,da")))]  ""  "@   if !cc %0 =%2; /* movsicc-2b */   if cc %0 =%1; /* movsicc-2a */   if cc %0 =%1; if !cc %0=%2; /* movsicc-1 */"  [(set_attr "length" "2,2,4")   (set_attr "type" "move")]);; Insns to load HIGH and LO_SUM(define_insn "movsi_high"  [(set (match_operand:SI 0 "validreg_operand" "=x")	(high:SI (match_operand:SI 1 "immediate_operand" "i")))]  "reload_completed"  "%d0 = %d1;"  [(set_attr "type" "mvi")   (set_attr "length" "4")])(define_insn "movstricthi_high"  [(set (match_operand:SI 0 "validreg_operand" "+x")	(ior:SI (and:SI (match_dup 0) (const_int 65535))		(match_operand:SI 1 "immediate_operand" "i")))]  "reload_completed"  "%d0 = %d1;"  [(set_attr "type" "mvi")   (set_attr "length" "4")])(define_insn "movsi_low"  [(set (match_operand:SI 0 "validreg_operand" "=x")	(lo_sum:SI (match_operand:SI 1 "validreg_operand" "0")		   (match_operand:SI 2 "immediate_operand" "i")))]  "reload_completed"  "%h0 = %h2;"  [(set_attr "type" "mvi")   (set_attr "length" "4")])(define_insn "movsi_high_pic"  [(set (match_operand:SI 0 "validreg_operand" "=x")	(high:SI (unspec:SI [(match_operand:SI 1 "" "")]			    UNSPEC_MOVE_PIC)))]  ""  "%d0 = %1@GOT_LOW;"  [(set_attr "type" "mvi")   (set_attr "length" "4")])(define_insn "movsi_low_pic"  [(set (match_operand:SI 0 "validreg_operand" "=x")	(lo_sum:SI (match_operand:SI 1 "validreg_operand" "0")		   (unspec:SI [(match_operand:SI 2 "" "")]			      UNSPEC_MOVE_PIC)))]  ""  "%h0 = %h2@GOT_HIGH;"  [(set_attr "type" "mvi")   (set_attr "length" "4")]);;; Move instructions(define_insn_and_split "movdi_insn"  [(set (match_operand:DI 0 "nonimmediate_operand" "=x,mx,r")	(match_operand:DI 1 "general_operand" "iFx,r,mx"))]  "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"  "#"  "reload_completed"  [(set (match_dup 2) (match_dup 3))   (set (match_dup 4) (match_dup 5))]{  rtx lo_half[2], hi_half[2];  split_di (operands, 2, lo_half, hi_half);  if (reg_overlap_mentioned_p (lo_half[0], hi_half[1]))    {      operands[2] = hi_half[0];      operands[3] = hi_half[1];      operands[4] = lo_half[0];      operands[5] = lo_half[1];    }  else    {      operands[2] = lo_half[0];      operands[3] = lo_half[1];      operands[4] = hi_half[0];      operands[5] = hi_half[1];    }})(define_insn "movbi"  [(set (match_operand:BI 0 "nonimmediate_operand" "=x,x,d,mr,C,d")        (match_operand:BI 1 "general_operand" "x,xKs3,mr,d,d,C"))]  ""  "@   %0 = %1;   %0 = %1 (X);   %0 = %1;   %0 = %1;   CC = %1;   %0 = CC;"  [(set_attr "type" "move,mvi,mcld,mcst,compare,compare")   (set_attr "length" "2,2,*,*,2,2")])(define_insn "movpdi"  [(set (match_operand:PDI 0 "nonimmediate_operand" "=e,<,e")        (match_operand:PDI 1 "general_operand" " e,e,>"))]  ""  "@   %0 = %1;   %0 = %x1; %0 = %w1;   %w0 = %1; %x0 = %1;"  [(set_attr "type" "move,mcst,mcld")])(define_insn "*pushsi_insn"  [(set (mem:SI (pre_dec:SI (reg:SI REG_SP)))        (match_operand:SI 0 "validreg_operand" "xy"))]  ""  "[--SP] = %0;"  [(set_attr "type" "mcst")   (set_attr "length" "2")])(define_insn "*popsi_insn"  [(set (match_operand:SI 0 "validreg_operand" "=xy")        (mem:SI (post_inc:SI (reg:SI REG_SP))))]  ""  "%0 = [SP++];"  [(set_attr "type" "mcld")   (set_attr "length" "2")]);; The first alternative is used to make reload choose a limited register;; class when faced with a movsi_insn that had its input operand replaced;; with a PLUS.  We generally require fewer secondary reloads this way.(define_insn "*movsi_insn"  [(set (match_operand:SI 0 "nonimmediate_operand" "=da,x*y,da,x,x,x,da,mr")        (match_operand:SI 1 "general_operand" "da,x*y,xKs7,xKsh,xKuh,ix,mr,da"))]  "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"  "@   %0 = %1;   %0 = %1;   %0 = %1 (X);   %0 = %1 (X);   %0 = %1 (Z);   #   %0 = %1;   %0 = %1;"  [(set_attr "type" "move,move,mvi,mvi,mvi,*,mcld,mcst")   (set_attr "length" "2,2,2,4,4,*,*,*")])(define_insn "*movv2hi_insn"  [(set (match_operand:V2HI 0 "nonimmediate_operand" "=da,d,m")        (match_operand:V2HI 1 "general_operand" "d,m,d"))]  "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"  "%0 = %1;"  [(set_attr "type" "move,mcld,mcst")   (set_attr "length" "2,*,*")])(define_insn "*movhi_insn"  [(set (match_operand:HI 0 "nonimmediate_operand" "=x,da,x,d,mr")        (match_operand:HI 1 "general_operand" "x,xKs7,xKsh,mr,d"))]  "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"  "@   %0 = %1;   %0 = %1 (X);   %0 = %1 (X);   %0 = W %1 (X);   W %0 = %1;"  [(set_attr "type" "move,mvi,mvi,mcld,mcst")   (set_attr "length" "2,2,4,*,*")])(define_insn "*movqi_insn"  [(set (match_operand:QI 0 "nonimmediate_operand" "=x,da,x,d,mr")        (match_operand:QI 1 "general_operand" "x,xKs7,xKsh,mr,d"))]  "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"  "@   %0 = %1;   %0 = %1 (X);   %0 = %1 (X);   %0 = B %1 (X);   B %0 = %1;"  [(set_attr "type" "move,mvi,mvi,mcld,mcst")   (set_attr "length" "2,2,4,*,*")])(define_insn "*movsf_insn"  [(set (match_operand:SF 0 "nonimmediate_operand" "=x,x,da,mr")        (match_operand:SF 1 "general_operand" "x,Fx,mr,da"))]  "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"  "@   %0 = %1;   #   %0 = %1;   %0 = %1;"  [(set_attr "type" "move,*,mcld,mcst")])(define_insn_and_split "movdf_insn"  [(set (match_operand:DF 0 "nonimmediate_operand" "=x,mx,r")	(match_operand:DF 1 "general_operand" "iFx,r,mx"))]  "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"  "#"  "reload_completed"  [(set (match_dup 2) (match_dup 3))   (set (match_dup 4) (match_dup 5))]{  rtx lo_half[2], hi_half[2];  split_di (operands, 2, lo_half, hi_half);  if (reg_overlap_mentioned_p (lo_half[0], hi_half[1]))    {      operands[2] = hi_half[0];      operands[3] = hi_half[1];      operands[4] = lo_half[0];      operands[5] = lo_half[1];    }  else    {      operands[2] = lo_half[0];      operands[3] = lo_half[1];      operands[4] = hi_half[0];      operands[5] = hi_half[1];    }});; This is the main "hook" for PIC code.  When generating

⌨️ 快捷键说明

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