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

📄 ip2k.md

📁 gcc-you can use this code to learn something about gcc, and inquire further into linux,
💻 MD
📖 第 1 页 / 共 5 页
字号:
;; -*- Mode: Scheme -*-;; GCC machine description for Ubicom IP2022 Communications Controller.;; Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc.;; Contributed by Red Hat, Inc and Ubicom, 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 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.  */;; Default all instruction lengths to two bytes (one 16-bit instruction).;;(define_attr "length" "" (const_int 2));; Define if we can "skip" an insn or not(define_attr "skip" "no,yes" (const_string "no"));; Define an insn clobbers WREG or not(define_attr "clobberw" "no,yes" (const_string "yes"));; Performance Issues:;;;; With the IP2k only having one really useful pointer register we have to;; make most of our instruction patterns only match one offsettable address;; before addressing becomes strict whereas afterwards of course we can use;; any register details that have become fixed.  As we've already committed;; any reloads at this point of course we're a little late so we have to use;; a number of peephole2 optimizations to remerge viable patterns.  We can;; do a bit more tidying up in the machine-dependent reorg pass to try and;; make things better still.  None of this is ideal, but it's *much* better;; than nothing.;; Constraints:;;;; I - -255..-1 - all other literal values have to be loaded;; J - 0..7 - valid bit number in a register;; K - 0..127 - valid offset for addressing mode;; L - 1..127 - positive count suitable for shift.;; M - -1 as a literal value;; N - +1 as a literal value;; O - zero;; P - 0..255;;;; a - DP or IP registers (general address);; f - IP register;; j - IPL register;; k - IPH register;; b - DP register;; y - DPH register;; z - DPL register;; q - SP register;; c - DP or SP registers (offsettable address);; d - non-pointer registers (not SP, DP, IP);; u - non-SP registers (everything except SP);;;; R - Indirect thru IP - Avoid this except for QI mode, since we;;     can't access extra bytes.;; S - Short (stack/dp address). Pointer with 0..127 displacement;;     Note that 0(SP) has undefined contents due to post-decrement push;; T - data-section immediate value.  A CONST_INT or SYMBOL_REF into .data;; Special assembly-language format effectors:;;;; ABCD -;;     Reference up to 4 big-endian registers - %A0 is Rn+0, while %D0 is Rn+3;; STUVWXYZ -;;     Reference up to 8 big-endian registers - %S0 is Rn+0, while %Z0 is Rn+7;;;; H - High part of 16 bit address or literal %hi8data(v) or %hi8insn(v);; L - Low part of 16 bit address or literal  %lo8data(v) or %lo8insn(v);; b - print a literal value with no punctuation (typically bit selector);; e - print 1 << v ('exponent');; n - print negative number;; x - print 16 bit hex number;; < - interior stack push; adjust any stack-relative operands accordingly;; > - interior stack pop; clear adjustment.;;;; Basic operations to move data in and out of fr's.  Also extended to;; cover the loading of w with immediates;;(define_insn "*movqi_w_gen"  [(set (reg:QI 10)        (match_operand:QI 0 "general_operand" "rSi"))]  "(ip2k_reorg_split_qimode)"  "mov\\tw,%0"  [(set_attr "skip" "yes")])(define_insn "*movqi_fr_w"  [(set (match_operand:QI 0 "nonimmediate_operand" "=rS")        (reg:QI 10))]  "(ip2k_reorg_split_qimode)"  "mov\\t%0,w"  [(set_attr "skip" "yes")   (set_attr "clobberw" "no")]);; Handle the cases where we get back to back redundant mov patterns issued.  ;; This of course sounds somewhat absurd but is actually reasonably common;; because we aren't able to match certain patterns before registers are;; chosen.  This is particularly true of memory to memory operations where;; we can't provide patterns that will guarantee to match every time because;; this would require reloads in the middle of instructions.  If we;; discover a case that doesn't need a reload of course then this combiner;; operation will tidy up for us.;;;; Warning!  Whilst it would be nice to match operand 0 as a general operand;; we mustn't do so because this doesn't work with the REG_DEAD check.;;(define_peephole2  [(set (match_operand 0 "ip2k_nonsp_reg_operand" "")	(match_operand 1 "ip2k_gen_operand" ""))   (set (match_operand 2 "ip2k_split_dest_operand" "")        (match_dup 0))]  "(peep2_reg_dead_p (2, operands[0])    && ! (REG_P (operands[2]) && REGNO (operands[2]) == REG_SP)    && (REG_P (operands[2])        || ip2k_xexp_not_uses_reg_p (operands[2], REGNO (operands[0]),                                     GET_MODE_SIZE (GET_MODE (operands[0])))))"  [(set (match_dup 2)	(match_dup 1))]  "")(define_peephole2  [(set (match_operand 0 "ip2k_nonsp_reg_operand" "")	(match_operand 1 "immediate_operand" ""))   (set (match_operand 2 "ip2k_gen_operand" "")        (match_dup 0))]  "(peep2_reg_dead_p (2, operands[0])    && ! (REG_P (operands[2]) && REGNO (operands[2]) == REG_SP)    && ip2k_xexp_not_uses_reg_p (operands[2], REGNO (operands[0]),                                 GET_MODE_SIZE (GET_MODE (operands[0]))))"  [(set (match_dup 2)	(match_dup 1))]  "");;;; Move 8-bit integers.;;(define_expand "movqi"  [(set (match_operand:QI 0 "" "")	(match_operand:QI 1 "" ""))]  ""  "")(define_insn "*pushqi"  [(set (match_operand:QI 0 "push_operand"   "=<")	(match_operand:QI 1 "general_operand" "g"))]  ""  "push\\t%1"  [(set_attr "skip" "yes")   (set_attr "clobberw" "no")]);; IP isn't offsettable but we can fake this behavior here and win if we would;; otherwise use DP and require a reload from IP.  This instruction is only;; matched by peephole2 operations.;;(define_insn "*movqi_to_ip_plus_offs"  [(set (mem:QI (plus:HI (reg:HI 4)			 (match_operand 0 "const_int_operand" "P,P")))	(match_operand:QI 1 "general_operand"                 "O,g"))]  "reload_completed && (INTVAL (operands[0]) < 0x100)"  "*{    if (INTVAL (operands[0]) == 1)      OUT_AS1 (inc, ipl);    else      {        OUT_AS2 (mov, w, %0);        OUT_AS2 (add, ipl, w);      }    switch (which_alternative)      {      case 0:        OUT_AS1 (clr, (IP));	break;      case 1:        OUT_AS1 (push, %1%<);        OUT_AS1 (pop, (IP)%>);	break;      }    if (!find_regno_note (insn, REG_DEAD, REG_IP))      {        if (INTVAL (operands[0]) == 1)          OUT_AS1 (dec, ipl);        else          OUT_AS2 (sub, ipl, w);      }    return \"\";  }");; IP isn't offsettable but we can fake this behavior here and win if we would;; otherwise use DP and require a reload from IP.  This instruction is only;; matched by peephole2 operations.;;(define_insn "*movqi_from_ip_plus_offs"  [(set (match_operand:QI 0 "nonimmediate_operand"           "=g")        (mem:QI (plus:HI (reg:HI 4)			 (match_operand 1 "const_int_operand" "P"))))]  "reload_completed && (INTVAL (operands[1]) < 0x100)"  "*{    if (INTVAL (operands[1]) == 1)      OUT_AS1 (inc, ipl);    else      {        OUT_AS2 (mov, w, %1);        OUT_AS2 (add, ipl, w);      }    OUT_AS1 (push, (IP)%<);    OUT_AS1 (pop, %0%>);    if (!find_regno_note (insn, REG_DEAD, REG_IP)        && ip2k_xexp_not_uses_reg_p (operands[0], REG_IP, 2))      {        if (INTVAL (operands[1]) == 1)          OUT_AS1 (dec, ipl);        else          OUT_AS2 (sub, ipl, w);      }    return \"\";  }")(define_insn_and_split "*movqi"  [(set (match_operand:QI 0 "nonimmediate_operand" "=roR,roR,r,  rS,roR")	(match_operand:QI 1 "general_operand"       "  O, ri,o,rioR,rSi"))]  ""  "@   clr\\t%0   #   #   #   #"  "(ip2k_reorg_split_qimode    && (GET_CODE (operands[1]) != CONST_INT        || INTVAL (operands[1]) != 0))"  [(set (reg:QI 10) (match_dup 1))   (set (match_dup 0) (reg:QI 10))]  ""  [(set_attr "skip" "yes,no,no,no,no")   (set_attr "clobberw" "no,yes,yes,yes,yes")])(define_peephole2  [(set (reg:HI 12)  	(reg:HI 4))   (set (match_operand:QI 0 "nonimmediate_operand" "")   	(mem:QI (plus:HI (reg:HI 12)		         (match_operand 1 "const_int_operand" ""))))]  "((ip2k_reorg_in_progress || ip2k_reorg_completed)    && peep2_regno_dead_p (2, REG_DP)    && ip2k_xexp_not_uses_reg_p (operands[0], REG_DP, 2)    && (INTVAL (operands[1]) < 0x100))"  [(set (match_dup 0)	(mem:QI (plus:HI (reg:HI 4)			 (match_dup 1))))]  "")(define_peephole2  [(set (reg:HI 12)  	(reg:HI 4))   (set (mem:QI (plus:HI (reg:HI 12)		         (match_operand 0 "const_int_operand" "")))	(match_operand:QI 1 "general_operand" ""))]  "((ip2k_reorg_in_progress || ip2k_reorg_completed)    && peep2_regno_dead_p (2, REG_DP)    && ip2k_xexp_not_uses_reg_p (operands[0], REG_DP, 2)    && (INTVAL (operands[0]) < 0x100))"  [(set (mem:QI (plus:HI (reg:HI 4)			 (match_dup 0)))	(match_dup 1))]  "")(define_peephole2  [(set (match_operand:QI 0 "register_operand" "")   	(mem:QI (plus:HI (reg:HI 4)			 (match_operand 1 "const_int_operand" ""))))   (set (match_operand:QI 2 "nonimmediate_operand" "")        (match_dup 0))]  "((ip2k_reorg_in_progress || ip2k_reorg_completed)    && peep2_reg_dead_p (2, operands[0]))"  [(set (match_dup 2)	(mem:QI (plus:HI (reg:HI 4)			 (match_dup 1))))]  "");; We sometimes want to copy a value twice, usually when we copy a value into;; both a structure slot and into a temporary register.  We can win here;; because gcc doesn't know about ways of reusing w while we're copying.;;(define_insn_and_split "*movqi_twice"  [(set (match_operand:QI 0 "nonimmediate_operand" "=g")        (match_operand:QI 1 "general_operand"       "g"))   (set (match_operand:QI 2 "nonimmediate_operand" "=g")        (match_dup 1))]  "ip2k_reorg_merge_qimode"  "mov\\tw,%1\;mov\\t%0,w\;mov\\t%2,w"  "(ip2k_reorg_split_qimode)"  [(set (reg:QI 10) (match_dup 1))   (set (match_dup 0) (reg:QI 10))   (set (match_dup 2) (reg:QI 10))]  "");; Don't try to match until we've removed redundant reloads.  Often this;; simplification will remove the need to do two moves!;;(define_peephole2  [(set (match_operand:QI 0 "nonimmediate_operand" "")        (match_operand:QI 1 "general_operand" ""))   (set (match_operand:QI 2 "nonimmediate_operand" "")        (match_dup 0))]  "(ip2k_reorg_merge_qimode    && (GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 0))"  [(parallel [(set (match_dup 0)  		   (match_dup 1))	      (set (match_dup 2)	      	   (match_dup 1))])]  "");; Don't try to match until we've removed redundant reloads.  Often this;; simplification will remove the need to do two moves!;;(define_peephole2  [(set (match_operand:QI 0 "nonimmediate_operand" "")        (match_operand:QI 1 "general_operand" ""))   (set (match_operand:QI 2 "nonimmediate_operand" "")        (match_dup 1))]  "(ip2k_reorg_merge_qimode    && (GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 0))"  [(parallel [(set (match_dup 0)  		   (match_dup 1))	      (set (match_dup 2)	      	   (match_dup 1))])]  "");;;; Move 16-bit integers.;;(define_expand "movhi"  [(set (match_operand:HI 0 "" "")	(match_operand:HI 1 "" ""))]  ""  "")(define_insn "*pushhi_ip"  [(set (match_operand:HI 0 "push_operand"      "=<")	(mem:HI (reg:HI 4)))]  "reload_completed"  "inc\\tipl\;push\\t(IP)\;dec\\tipl\;push\\t(IP)"  [(set_attr "clobberw" "no")])(define_insn "*movhi_to_ip"  [(set (mem:HI (reg:HI 4))  	(match_operand:HI 0 "general_operand" "O,roi"))]  "reload_completed"  "*{    switch (which_alternative)      {      case 0:        OUT_AS1 (clr, (IP));	OUT_AS1 (inc, ipl);	OUT_AS1 (clr, (IP));        if (!find_regno_note (insn, REG_DEAD, REG_IP))	  OUT_AS1 (dec, ipl);	return \"\";      case 1:        OUT_AS2 (mov, w, %H0);	OUT_AS2 (mov, (IP), w);	OUT_AS2 (mov, w, %L0);	OUT_AS1 (inc, ipl);	OUT_AS2 (mov, (IP), w);        if (!find_regno_note (insn, REG_DEAD, REG_IP))	  OUT_AS1 (dec, ipl);	return \"\";      default:        abort ();      }  }")(define_insn "*movhi_from_ip"  [(set (match_operand:HI 0 "nonimmediate_operand" "=f,bqdo")        (mem:HI (reg:HI 4)))]  "reload_completed"  "*{    switch (which_alternative)      {      case 0:        OUT_AS1 (push, (IP));	OUT_AS1 (inc, ipl);	OUT_AS2 (mov, w, (IP));

⌨️ 快捷键说明

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