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

📄 mt.md

📁 linux下编程用 编译软件
💻 MD
📖 第 1 页 / 共 3 页
字号:
;; Machine description for MorphoRISC1;; Copyright (C) 2005 Free Software Foundation, Inc.;; Contributed by Red Hat, Inc.;; 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, 51 Franklin Street, Fifth Floor, Boston, MA;; 02110-1301, USA.;; UNSPECs(define_constants  [    (UNSPEC_BLOCKAGE 0)    (UNSPEC_EI 1)    (UNSPEC_DI 2)  ]);; Attributes(define_attr "type" "branch,call,load,store,io,arith,complex,unknown"	 (const_string "unknown") );; If the attribute takes numeric values, no `enum' type will be defined and;; the function to obtain the attribute's value will return `int'.(define_attr "length" "" (const_int 4));; DFA scheduler.(define_automaton "other")(define_cpu_unit "decode_unit" "other")(define_cpu_unit "memory_unit" "other")(define_cpu_unit "branch_unit" "other")(define_insn_reservation "mem_access" 2  (ior (eq_attr "type" "load") (eq_attr "type" "store"))  "decode_unit+memory_unit*2")(define_insn_reservation "io_access" 2  (eq_attr "type" "io")  "decode_unit+memory_unit*2")(define_insn_reservation "branch_access" 2  (ior (eq_attr "type" "branch")       (eq_attr "type" "call"))  "decode_unit+branch_unit*2")(define_insn_reservation "arith_access" 1  (eq_attr "type" "arith")  "decode_unit")(define_bypass 2 "arith_access" "branch_access")(define_bypass 3 "mem_access" "branch_access")(define_bypass 3 "io_access" "branch_access");; Delay Slots;; The mt does not allow branches in the delay slot.;; The mt does not allow back to back memory or io instruction.;; The compiler does not know what the type of instruction is at;; the destination of the branch.  Thus, only type that will be acceptable;; (safe) is the arith type.(define_delay (ior (eq_attr "type" "branch")		   (eq_attr "type" "call"))		 [(eq_attr "type" "arith") (nil) (nil)])(define_insn "decrement_and_branch_until_zero"   [(set (pc)	 (if_then_else	  (ne (match_operand:SI 0 "nonimmediate_operand" "+r,*m")	      (const_int 0))	  (label_ref (match_operand 1 "" ""))	  (pc)))    (set (match_dup 0)	 (plus:SI (match_dup 0)		  (const_int -1)))    (clobber (match_scratch:SI 2 "=X,&r"))    (clobber (match_scratch:SI 3 "=X,&r"))]  "TARGET_MS1_16_003 || TARGET_MS2"  "@   dbnz\t%0, %l1%#   #"  [(set_attr "length" "4,16")   (set_attr "type" "branch,unknown")]);; Split the above to handle the case where operand 0 is in memory;; (a register that couldn't get a hard register).(define_split  [(set (pc)	(if_then_else	  (ne (match_operand:SI 0 "memory_operand" "")	      (const_int 0))	  (label_ref (match_operand 1 "" ""))	  (pc)))    (set (match_dup 0)	 (plus:SI (match_dup 0)		  (const_int -1)))    (clobber (match_scratch:SI 2 ""))    (clobber (match_scratch:SI 3 ""))]  "TARGET_MS1_16_003 || TARGET_MS2"  [(set (match_dup 2) (match_dup 0))   (set (match_dup 3) (plus:SI (match_dup 2) (const_int -1)))   (set (match_dup 0) (match_dup 3))   (set (pc)	(if_then_else	 (ne (match_dup 2)	     (const_int 0))	 (label_ref (match_dup 1))	 (pc)))]  "");; This peephole is defined in the vain hope that it might actually trigger one;; day, although I have yet to find a test case that matches it.  The normal;; problem is that GCC likes to move the loading of the constant value -1 out;; of the loop, so it is not here to be matched.(define_peephole2  [(set (match_operand:SI 0 "register_operand" "")	(plus:SI (match_dup 0) (const_int -1)))   (set (match_operand:SI 1 "register_operand" "")     (const_int -1))   (set (pc) (if_then_else	        (ne (match_dup 0) (match_dup 1))		(label_ref (match_operand 2 "" ""))		(pc)))]  "TARGET_MS1_16_003 || TARGET_MS2"  [(parallel [(set (pc)	           (if_then_else	              (ne (match_dup 0) (const_int 0))	              (label_ref (match_dup 2))	              (pc)))              (set (match_dup 0)	           (plus:SI (match_dup 0) (const_int -1)))	      (clobber (reg:SI 0))	      (clobber (reg:SI 0))])]  "");; Moves(define_expand "loadqi"  [   ;; compute shift   (set (match_operand:SI 2 "register_operand" "")	(and:SI (match_dup 1) (const_int 3)))   (set (match_dup 2)	(xor:SI (match_dup 2) (const_int 3)))   (set (match_dup 2 )	(ashift:SI (match_dup 2) (const_int 3)))   ;; get word that contains byte   (set (match_operand:SI 0 "register_operand" "")	(mem:SI (and:SI (match_operand:SI 1 "register_operand" "")			(const_int -3))))   ;; align byte   (set (match_dup 0)   (ashiftrt:SI (match_dup 0) (match_dup 2)))  ]  ""  "");; storeqi;; operand 0 byte value to store;; operand 1 address;; operand 2 temp, word containing byte;; operand 3 temp, shift count;; operand 4 temp, mask, aligned and masked byte;; operand 5 (unused)(define_expand "storeqi"  [   ;; compute shift   (set (match_operand:SI 3 "register_operand" "")	(and:SI (match_operand:SI 1 "register_operand" "") (const_int 3)))   (set (match_dup 3)	(xor:SI (match_dup 3) (const_int 3)))   (set (match_dup 3)	(ashift:SI (match_dup 3) (const_int 3)))   ;; get word that contains byte   (set (match_operand:SI 2 "register_operand" "")	(mem:SI (and:SI (match_dup 1) (const_int -3))))   ;; generate mask   (set (match_operand:SI 4 "register_operand" "") (const_int 255))   (set (match_dup 4) (ashift:SI (match_dup 4) (match_dup 3)))   (set (match_dup 4) (not:SI (match_dup 4)))   ;; clear appropriate bits   (set (match_dup 2) (and:SI (match_dup 2) (match_dup 4)))   ;; align byte   (set (match_dup 4)	(and:SI (match_operand:SI 0 "register_operand" "") (const_int 255)))   (set (match_dup 4) (ashift:SI (match_dup 4) (match_dup 3)))   ;; combine   (set (match_dup 2) (ior:SI (match_dup 4) (match_dup 2)))   ;; store updated word   (set (mem:SI (and:SI (match_dup 1) (const_int -3))) (match_dup 2))  ]  ""  "")(define_expand "movqi"  [(set (match_operand:QI 0 "general_operand" "")	(match_operand:QI 1 "general_operand" ""))]  ""  "{  if (!reload_in_progress      && !reload_completed      && GET_CODE (operands[0]) == MEM      && GET_CODE (operands[1]) == MEM)    operands[1] = copy_to_mode_reg (QImode, operands[1]);    if ( (! TARGET_BYTE_ACCESS) && GET_CODE (operands[0]) == MEM)    {	rtx scratch1 = gen_reg_rtx (SImode);	rtx scratch2 = gen_reg_rtx (SImode);	rtx scratch3 = gen_reg_rtx (SImode);	rtx data     = operands[1];	rtx address  = XEXP (operands[0], 0);	rtx seq;	if ( GET_CODE (data) != REG )	    data = copy_to_mode_reg (QImode, data);	if ( GET_CODE (address) != REG )	  address = copy_to_mode_reg (SImode, address);	start_sequence ();	emit_insn (gen_storeqi (gen_lowpart (SImode, data), address,				scratch1, scratch2, scratch3));	mt_set_memflags (operands[0]);	seq = get_insns ();	end_sequence ();	emit_insn (seq);	DONE;    }  if ( (! TARGET_BYTE_ACCESS) && GET_CODE (operands[1]) == MEM)    {	rtx scratch1 = gen_reg_rtx (SImode);	rtx data = operands[0];	rtx address = XEXP (operands[1], 0);	rtx seq;	if ( GET_CODE (address) != REG )	  address = copy_to_mode_reg (SImode, address);	start_sequence ();	emit_insn (gen_loadqi (gen_lowpart (SImode, data), address, scratch1));	mt_set_memflags (operands[1]);	seq = get_insns ();	end_sequence ();	emit_insn (seq);	DONE;    }   /* If the load is a pseudo register in a stack slot, some simplification      can be made because the loads are aligned */  if ( (! TARGET_BYTE_ACCESS)         && (reload_in_progress && GET_CODE (operands[1]) == SUBREG	  && GET_CODE (SUBREG_REG (operands[1])) == REG	  && REGNO (SUBREG_REG (operands[1])) >= FIRST_PSEUDO_REGISTER))    {	rtx data = operands[0];	rtx address = XEXP (operands[1], 0);	rtx seq;	start_sequence ();	emit_insn (gen_movsi (gen_lowpart (SImode, data), address));	mt_set_memflags (operands[1]);	seq = get_insns ();	end_sequence ();	emit_insn (seq);	DONE;    }}")(define_insn "*movqi_internal"  [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m,r")	(match_operand:QI 1 "general_operand" "r,m,r,I"))]  "TARGET_BYTE_ACCESS    && (!memory_operand (operands[0], QImode)        || !memory_operand (operands[1], QImode))"  "@   or  %0, %1, %1   ldb %0, %1   stb %1, %0   addi %0, r0, %1"  [(set_attr "length" "4,4,4,4")   (set_attr "type" "arith,load,store,arith")])(define_insn "*movqi_internal_nobyte"  [(set (match_operand:QI 0 "register_operand" "=r,r")	(match_operand:QI 1 "arith_operand" "r,I"))]  "!TARGET_BYTE_ACCESS    && (!memory_operand (operands[0], QImode)        || !memory_operand (operands[1], QImode))"  "@   or   %0, %1, %1   addi %0, r0, %1"  [(set_attr "length" "4,4")   (set_attr "type" "arith,arith")]);; The MorphoRISC does not have 16-bit loads and stores.;; These operations must be synthesized.  Note that the code;; for loadhi and storehi assumes that the least significant bits;; is ignored.;; loadhi;; operand 0 location of result;; operand 1 memory address;; operand 2 temp(define_expand "loadhi"  [   ;; compute shift   (set (match_operand:SI 2 "register_operand" "")	(and:SI (match_dup 1) (const_int 2)))   (set (match_dup 2)	(xor:SI (match_dup 2) (const_int 2)))   (set (match_dup 2 )	(ashift:SI (match_dup 2) (const_int 3)))   ;; get word that contains the 16-bits   (set (match_operand:SI 0 "register_operand" "")	(mem:SI (and:SI (match_operand:SI 1 "register_operand" "")			(const_int -3))))   ;; align 16-bit value   (set (match_dup 0)	(ashiftrt:SI (match_dup 0) (match_dup 2)))  ]  ""  "");; storehi;; operand 0 byte value to store;; operand 1 address;; operand 2 temp, word containing byte;; operand 3 temp, shift count;; operand 4 temp, mask, aligned and masked byte;; operand 5 (unused)(define_expand "storehi"  [   ;; compute shift   (set (match_operand:SI 3 "register_operand" "")	(and:SI (match_operand:SI 1 "register_operand" "") (const_int 2)))   (set (match_dup 3)	(xor:SI (match_dup 3) (const_int 2)))   (set (match_dup 3)	(ashift:SI (match_dup 3) (const_int 3)))   ;; get word that contains the 16-bits   (set (match_operand:SI 2 "register_operand" "")	(mem:SI (and:SI (match_dup 1) (const_int -3))))   ;; generate mask   (set (match_operand:SI 4 "register_operand" "") (const_int 65535))   (set (match_dup 4) (ashift:SI (match_dup 4) (match_dup 3)))   (set (match_dup 4) (not:SI (match_dup 4)))   ;; clear appropriate bits   (set (match_dup 2) (and:SI (match_dup 2) (match_dup 4)))   ;; align 16-bit value   (set (match_dup 4)	(and:SI (match_operand:SI 0 "register_operand" "") (const_int 65535)))   (set (match_dup 4) (ashift:SI (match_dup 4) (match_dup 3)))   ;; combine   (set (match_dup 2) (ior:SI (match_dup 4) (match_dup 2)))   ;; store updated word   (set (mem:SI (and:SI (match_dup 1) (const_int -3))) (match_dup 2))  ]  ""  "")(define_expand "movhi"  [(set (match_operand:HI 0 "general_operand" "")	(match_operand:HI 1 "general_operand" ""))]  ""  "{  if (!reload_in_progress      && !reload_completed      && GET_CODE (operands[0]) == MEM      && GET_CODE (operands[1]) == MEM)    operands[1] = copy_to_mode_reg (HImode, operands[1]);  if ( GET_CODE (operands[0]) == MEM)    {	rtx scratch1 = gen_reg_rtx (SImode);	rtx scratch2 = gen_reg_rtx (SImode);	rtx scratch3 = gen_reg_rtx (SImode);	rtx data     = operands[1];	rtx address  = XEXP (operands[0], 0);	rtx seq;	if (GET_CODE (data) != REG)	  data = copy_to_mode_reg (HImode, data);	if (GET_CODE (address) != REG)	  address = copy_to_mode_reg (SImode, address);	start_sequence ();	emit_insn (gen_storehi (gen_lowpart (SImode, data), address,			        scratch1, scratch2, scratch3));	mt_set_memflags (operands[0]);	seq = get_insns ();	end_sequence ();	emit_insn (seq);	DONE;    }  if ( GET_CODE (operands[1]) == MEM)    {	rtx scratch1 = gen_reg_rtx (SImode);	rtx data     = operands[0];	rtx address  = XEXP (operands[1], 0);	rtx seq;	if (GET_CODE (address) != REG)	    address = copy_to_mode_reg (SImode, address);	start_sequence ();	emit_insn (gen_loadhi (gen_lowpart (SImode, data), address,			       scratch1));	mt_set_memflags (operands[1]);	seq = get_insns ();	end_sequence ();	emit_insn (seq);	DONE;    }   /* If the load is a pseudo register in a stack slot, some simplification      can be made because the loads are aligned */  if ( (reload_in_progress && GET_CODE (operands[1]) == SUBREG	  && GET_CODE (SUBREG_REG (operands[1])) == REG	  && REGNO (SUBREG_REG (operands[1])) >= FIRST_PSEUDO_REGISTER))    {	rtx data = operands[0];	rtx address = XEXP (operands[1], 0);	rtx seq;	start_sequence ();	emit_insn (gen_movsi (gen_lowpart (SImode, data), address));	mt_set_memflags (operands[1]);	seq = get_insns ();	end_sequence ();	emit_insn (seq);	DONE;    }}")(define_insn "*movhi_internal"  [(set (match_operand:HI 0 "register_operand" "=r,r")	(match_operand:HI 1 "arith_operand" "r,I"))]  "!memory_operand (operands[0], HImode) || !memory_operand (operands[1], HImode)"  "@  or    %0, %1, %1  addi  %0, r0, %1"  [(set_attr "length" "4,4")   (set_attr "type" "arith,arith")])(define_expand "movsi"  [(set (match_operand:SI 0 "nonimmediate_operand" "")	(match_operand:SI 1 "general_operand" ""))]  ""  "{  if (!reload_in_progress  && !reload_completed

⌨️ 快捷键说明

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