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

📄 h8300.md

📁 Mac OS X 10.4.9 for x86 Source Code gcc 实现源代码
💻 MD
📖 第 1 页 / 共 5 页
字号:
;; GCC machine description for Renesas H8/300;; Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,;; 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.;;   Contributed by Steve Chamberlain (sac@cygnus.com),;;   Jim Wilson (wilson@cygnus.com), and Doug Evans (dje@cygnus.com).;; 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.;; We compute exact length on each instruction for most of the time.;; In some case, most notably bit operations that may involve memory;; operands, the lengths in this file are "worst case".;; On the H8/300H and H8S, adds/subs operate on the 32bit "er";; registers.  Right now GCC doesn't expose the "e" half to the;; compiler, so using add/subs for addhi and subhi is safe.  Long;; term, we want to expose the "e" half to the compiler (gives us 8;; more 16bit registers).  At that point addhi and subhi can't use;; adds/subs.;; There's currently no way to have an insv/extzv expander for the H8/300H;; because word_mode is different for the H8/300 and H8/300H.;; Shifts/rotates by small constants should be handled by special;; patterns so we get the length and cc status correct.;; Bitfield operations no longer accept memory operands.  We need;; to add variants which operate on memory back to the MD.;; ??? Implement remaining bit ops available on the h8300;; ----------------------------------------------------------------------;; CONSTANTS;; ----------------------------------------------------------------------(define_constants  [(UNSPEC_INCDEC	0)   (UNSPEC_MONITOR	1)])(define_constants  [(UNSPEC_MOVMD	100)   (UNSPEC_STPCPY	101)])(define_constants  [(R0_REG	 0)   (SC_REG	 3)   (COUNTER_REG  4)   (SOURCE_REG   5)   (DESTINATION_REG 6)   (HFP_REG	 6)   (SP_REG	 7)   (MAC_REG	 8)   (AP_REG	 9)   (RAP_REG	10)   (FP_REG	11)]);; ----------------------------------------------------------------------;; ATTRIBUTES;; ----------------------------------------------------------------------(define_attr "cpu" "h8300,h8300h"  (const (symbol_ref "cpu_type")))(define_attr "type" "branch,arith,bitbranch,call"  (const_string "arith"))(define_attr "length_table" "none,addb,addw,addl,logicb,movb,movw,movl,mova_zero,mova,unary,mov_imm4,short_immediate,bitfield,bitbranch"  (const_string "none"));; The size of instructions in bytes.(define_attr "length" ""  (cond [(eq_attr "type" "branch")	 ;; In a forward delayed branch, (pc) represents the end of the	 ;; delay sequence, not the end of the branch itself.	 (if_then_else (and (ge (minus (match_dup 0) (pc))				(const_int -126))			    (le (plus (minus (match_dup 0) (pc))				      (symbol_ref "DELAY_SLOT_LENGTH (insn)"))				(const_int 126)))		       (const_int 2)		       (if_then_else (and (eq_attr "cpu" "h8300h")					  (and (ge (minus (pc) (match_dup 0))						   (const_int -32000))					       (le (minus (pc) (match_dup 0))						   (const_int 32000))))				     (const_int 4)				     (const_int 6)))	 (eq_attr "type" "bitbranch")	 (if_then_else	  (and (ge (minus (match_dup 0) (pc))		   (const_int -126))	       (le (minus (match_dup 0) (pc))		   (const_int 126)))	  (plus	   (symbol_ref "h8300_insn_length_from_table (insn, operands)")	   (const_int 2))	  (if_then_else	   (and (eq_attr "cpu" "h8300h")		(and (ge (minus (pc) (match_dup 0))			 (const_int -32000))		     (le (minus (pc) (match_dup 0))			 (const_int 32000))))	   (plus	    (symbol_ref "h8300_insn_length_from_table (insn, operands)")	    (const_int 4))	   (plus	    (symbol_ref "h8300_insn_length_from_table (insn, operands)")	    (const_int 6))))	 (eq_attr "length_table" "!none")	 (symbol_ref "h8300_insn_length_from_table (insn, operands)")]	(const_int 200)));; Condition code settings.;;;; none - insn does not affect cc;; none_0hit - insn does not affect cc but it does modify operand 0;;	This attribute is used to keep track of when operand 0 changes.;;	See the description of NOTICE_UPDATE_CC for more info.;; set_znv - insn sets z,n,v to usable values (like a tst insn); c is unknown.;; set_zn  - insn sets z,n to usable values; v,c are unknown.;; compare - compare instruction;; clobber - value of cc is unknown(define_attr "cc" "none,none_0hit,set_znv,set_zn,compare,clobber"  (const_string "clobber"));; Type of delay slot.  NONE means the instruction has no delay slot.;; JUMP means it is an unconditional jump that (if short enough);; could be implemented using bra/s.(define_attr "delay_slot" "none,jump"  (const_string "none"));; "yes" if the instruction can be put into a delay slot.  It's not;; entirely clear that jsr is not valid in delay slots, but it;; definitely doesn't have the effect of causing the called function;; to return to the target of the delayed branch.(define_attr "can_delay" "no,yes"  (cond [(eq_attr "type" "branch,bitbranch,call")	   (const_string "no")	 (ne (symbol_ref "get_attr_length (insn)") (const_int 2))	   (const_string "no")]	(const_string "yes")));; Only allow jumps to have a delay slot if we think they might;; be short enough.  This is just an optimization: we don't know;; for certain whether they will be or not.(define_delay (and (eq_attr "delay_slot" "jump")		   (eq (symbol_ref "get_attr_length (insn)") (const_int 2)))  [(eq_attr "can_delay" "yes")   (nil)   (nil)]);; Provide the maximum length of an assembly instruction in an asm;; statement.  The maximum length of 14 bytes is achieved on H8SX.(define_asm_attributes  [(set (attr "length")	(cond [(ne (symbol_ref "TARGET_H8300")  (const_int 0)) (const_int 4)	       (ne (symbol_ref "TARGET_H8300H") (const_int 0)) (const_int 10)	       (ne (symbol_ref "TARGET_H8300S") (const_int 0)) (const_int 10)]	      (const_int 14)))]);; ----------------------------------------------------------------------;; MOVE INSTRUCTIONS;; ----------------------------------------------------------------------;; movqi(define_insn "*movqi_h8300"  [(set (match_operand:QI 0 "general_operand_dst" "=r,r ,<,r,r,m")	(match_operand:QI 1 "general_operand_src" " I,r>,r,n,m,r"))]  "TARGET_H8300   && (register_operand (operands[0], QImode)       || register_operand (operands[1], QImode))"  "@   sub.b	%X0,%X0   mov.b	%R1,%X0   mov.b	%X1,%R0   mov.b	%R1,%X0   mov.b	%R1,%X0   mov.b	%X1,%R0"  [(set_attr "length" "2,2,2,2,4,4")   (set_attr "cc" "set_zn,set_znv,set_znv,set_znv,set_znv,set_znv")])(define_insn "*movqi_h8300hs"  [(set (match_operand:QI 0 "general_operand_dst" "=r,r ,<,r,r,m")	(match_operand:QI 1 "general_operand_src" " I,r>,r,n,m,r"))]  "(TARGET_H8300H || TARGET_H8300S) && !TARGET_H8300SX   && (register_operand (operands[0], QImode)       || register_operand (operands[1], QImode))"  "@   sub.b	%X0,%X0   mov.b	%R1,%X0   mov.b	%X1,%R0   mov.b	%R1,%X0   mov.b	%R1,%X0   mov.b	%X1,%R0"  [(set (attr "length")	(symbol_ref "compute_mov_length (operands)"))   (set_attr "cc" "set_zn,set_znv,set_znv,clobber,set_znv,set_znv")])(define_insn "*movqi_h8sx"  [(set (match_operand:QI 0 "general_operand_dst" "=Z,rQ")	(match_operand:QI 1 "general_operand_src" "P4>X,rQi"))]  "TARGET_H8300SX"  "@    mov.b	%X1,%X0    mov.b	%X1,%X0"  [(set_attr "length_table" "mov_imm4,movb")   (set_attr "cc" "set_znv")])(define_expand "movqi"  [(set (match_operand:QI 0 "general_operand_dst" "")	(match_operand:QI 1 "general_operand_src" ""))]  ""  "{  /* One of the ops has to be in a register.  */  if (!TARGET_H8300SX      && !register_operand (operand0, QImode)      && !register_operand (operand1, QImode))    {      operands[1] = copy_to_mode_reg (QImode, operand1);    }}")(define_insn "movstrictqi"  [(set (strict_low_part (match_operand:QI 0 "general_operand_dst" "+r,r"))			 (match_operand:QI 1 "general_operand_src" "I,rmi>"))]  ""  "@   sub.b	%X0,%X0   mov.b	%X1,%X0"  [(set_attr "length" "2,*")   (set_attr "length_table" "*,movb")   (set_attr "cc" "set_zn,set_znv")]);; movhi(define_insn "*movhi_h8300"  [(set (match_operand:HI 0 "general_operand_dst" "=r,r,<,r,r,m")	(match_operand:HI 1 "general_operand_src" "I,r>,r,i,m,r"))]  "TARGET_H8300   && (register_operand (operands[0], HImode)       || register_operand (operands[1], HImode))   && !(GET_CODE (operands[0]) == MEM	&& GET_CODE (XEXP (operands[0], 0)) == PRE_DEC	&& GET_CODE (XEXP (XEXP (operands[0], 0), 0)) == REG	&& GET_CODE (operands[1]) == REG	&& REGNO (XEXP (XEXP (operands[0], 0), 0)) == REGNO (operands[1]))"  "@   sub.w	%T0,%T0   mov.w	%T1,%T0   mov.w	%T1,%T0   mov.w	%T1,%T0   mov.w	%T1,%T0   mov.w	%T1,%T0"  [(set (attr "length")	(symbol_ref "compute_mov_length (operands)"))   (set_attr "cc" "set_zn,set_znv,set_znv,set_znv,set_znv,set_znv")])(define_insn "*movhi_h8300hs"  [(set (match_operand:HI 0 "general_operand_dst" "=r,r,<,r,r,m")	(match_operand:HI 1 "general_operand_src" "I,r>,r,i,m,r"))]  "(TARGET_H8300H || TARGET_H8300S) && !TARGET_H8300SX   && (register_operand (operands[0], HImode)       || register_operand (operands[1], HImode))"  "@   sub.w	%T0,%T0   mov.w	%T1,%T0   mov.w	%T1,%T0   mov.w	%T1,%T0   mov.w	%T1,%T0   mov.w	%T1,%T0"  [(set (attr "length")	(symbol_ref "compute_mov_length (operands)"))   (set_attr "cc" "set_zn,set_znv,set_znv,set_znv,set_znv,set_znv")])(define_insn "*movhi_h8sx"  [(set (match_operand:HI 0 "general_operand_dst" "=r,r,Z,Q,rQ")	(match_operand:HI 1 "general_operand_src" "I,P3>X,P4>X,IP8>X,rQi"))]  "TARGET_H8300SX"  "@   sub.w	%T0,%T0   mov.w	%T1,%T0   mov.w	%T1,%T0   mov.w	%T1,%T0   mov.w	%T1,%T0"  [(set_attr "length_table" "*,*,mov_imm4,short_immediate,movw")   (set_attr "length" "2,2,*,*,*")   (set_attr "cc" "set_zn,set_znv,set_znv,set_znv,set_znv")])(define_expand "movhi"  [(set (match_operand:HI 0 "general_operand_dst" "")	(match_operand:HI 1 "general_operand_src" ""))]  ""  "{  /* One of the ops has to be in a register.  */  if (!register_operand (operand1, HImode)      && !register_operand (operand0, HImode))    {      operands[1] = copy_to_mode_reg (HImode, operand1);    }}")(define_insn "movstricthi"  [(set (strict_low_part (match_operand:HI 0 "general_operand_dst" "+r,r,r"))			 (match_operand:HI 1 "general_operand_src" "I,P3>X,rmi"))]  ""  "@   sub.w	%T0,%T0   mov.w	%T1,%T0   mov.w	%T1,%T0"  [(set_attr "length" "2,2,*")   (set_attr "length_table" "*,*,movw")   (set_attr "cc" "set_zn,set_znv,set_znv")]);; movsi(define_expand "movsi"  [(set (match_operand:SI 0 "general_operand_dst" "")	(match_operand:SI 1 "general_operand_src" ""))]  ""  "{  if (TARGET_H8300)    {      if (h8300_expand_movsi (operands))	DONE;    }  else if (!TARGET_H8300SX)    {      /* One of the ops has to be in a register.  */      if (!register_operand (operand1, SImode)	  && !register_operand (operand0, SImode))	{	  operands[1] = copy_to_mode_reg (SImode, operand1);	}    }}")(define_insn "*movsi_h8300"  [(set (match_operand:SI 0 "general_operand_dst" "=r,r,r,o,<,r")	(match_operand:SI 1 "general_operand_src" "I,r,io,r,r,>"))]  "TARGET_H8300   && (register_operand (operands[0], SImode)       || register_operand (operands[1], SImode))"  "*{  unsigned int rn = -1;  switch (which_alternative)    {    case 0:      return \"sub.w	%e0,%e0\;sub.w	%f0,%f0\";    case 1:      if (REGNO (operands[0]) < REGNO (operands[1]))	return \"mov.w	%e1,%e0\;mov.w	%f1,%f0\";      else	return \"mov.w	%f1,%f0\;mov.w	%e1,%e0\";    case 2:      /* Make sure we don't trample the register we index with.  */      if (GET_CODE (operands[1]) == MEM)	{	  rtx inside = XEXP (operands[1], 0);	  if (REG_P (inside))	    {	      rn = REGNO (inside);	    }	  else if (GET_CODE (inside) == PLUS)	    {	      rtx lhs = XEXP (inside, 0);	      rtx rhs = XEXP (inside, 1);	      if (REG_P (lhs)) rn = REGNO (lhs);	      if (REG_P (rhs)) rn = REGNO (rhs);	    }	}      if (rn == REGNO (operands[0]))	{	  /* Move the second word first.  */	  return \"mov.w	%f1,%f0\;mov.w	%e1,%e0\";	}      else	{	  if (GET_CODE (operands[1]) == CONST_INT)	    {	      /* If either half is zero, use sub.w to clear that		 half.  */	      if ((INTVAL (operands[1]) & 0xffff) == 0)		return \"mov.w	%e1,%e0\;sub.w	%f0,%f0\";	      if (((INTVAL (operands[1]) >> 16) & 0xffff) == 0)		return \"sub.w	%e0,%e0\;mov.w	%f1,%f0\";	      /* If the upper half and the lower half are the same,		 copy one half to the other.  */	      if ((INTVAL (operands[1]) & 0xffff)		  == ((INTVAL (operands[1]) >> 16) & 0xffff))		return \"mov.w\\t%e1,%e0\;mov.w\\t%e0,%f0\";	    }	  return \"mov.w	%e1,%e0\;mov.w	%f1,%f0\";

⌨️ 快捷键说明

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