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

📄 m32r.md

📁 linux下的gcc编译器
💻 MD
📖 第 1 页 / 共 5 页
字号:
;; Machine description of the Mitsubishi M32R cpu for GNU C compiler;; Copyright (C) 1996, 1997, 1998, 1999, 2001, 2003 Free Software Foundation, 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, 59 Temple Place - Suite 330,;; Boston, MA 02111-1307, USA.;; See file "rtl.def" for documentation on define_insn, match_*, et. al.;; unspec usage;; 0 - blockage;; 1 - flush_icache;; 2 - load_sda_base;; 3 - setting carry in addx/subx instructions.;; Insn type.  Used to default other attribute values.(define_attr "type"  "int2,int4,load2,load4,load8,store2,store4,store8,shift2,shift4,mul2,div4,uncond_branch,branch,call,multi,misc"  (const_string "misc"));; Length in bytes.(define_attr "length" ""  (cond [(eq_attr "type" "int2,load2,store2,shift2,mul2")	 (const_int 2)	 (eq_attr "type" "int4,load4,store4,shift4,div4")	 (const_int 4)	 (eq_attr "type" "multi")	 (const_int 8)	 (eq_attr "type" "uncond_branch,branch,call")	 (const_int 4)]	 (const_int 4)));; The length here is the length of a single asm.  Unfortunately it might be;; 2 or 4 so we must allow for 4.  That's ok though.(define_asm_attributes  [(set_attr "length" "4")   (set_attr "type" "multi")]);; Whether an instruction is 16-bit or 32-bit(define_attr "insn_size" "short,long"  (if_then_else (eq_attr "type" "int2,load2,store2,shift2,mul2")		(const_string "short")		(const_string "long")))(define_attr "debug" "no,yes"  (const (symbol_ref "(TARGET_DEBUG != 0)")))(define_attr "opt_size" "no,yes"  (const (symbol_ref "(optimize_size != 0)")))(define_attr "m32r" "no,yes"  (const (symbol_ref "(TARGET_M32R != 0)")))(define_attr "m32rx" "no,yes"  (const (symbol_ref "(TARGET_M32RX != 0)")))(define_attr "m32rx_pipeline" "either,s,o,long,m32r"  (cond [(eq_attr "m32rx" "no")         (const_string "m32r")         (eq_attr "insn_size" "!short")         (const_string "long")]        (cond [(eq_attr "type" "int2")               (const_string "either")               (eq_attr "type" "load2,store2,shift2,uncond_branch,branch,call")               (const_string "o")               (eq_attr "type" "mul2")               (const_string "s")]              (const_string "long"))));; ::::::::::::::::::::;; ::;; :: Function Units;; ::;; ::::::::::::::::::::;; On most RISC machines, there are instructions whose results are not;; available for a specific number of cycles.  Common cases are instructions;; that load data from memory.  On many machines, a pipeline stall will result;; if the data is referenced too soon after the load instruction.;; In addition, many newer microprocessors have multiple function units,;; usually one for integer and one for floating point, and often will incur;; pipeline stalls when a result that is needed is not yet ready.;; The descriptions in this section allow the specification of how much time;; must elapse between the execution of an instruction and the time when its;; result is used.  It also allows specification of when the execution of an;; instruction will delay execution of similar instructions due to function;; unit conflicts.;; For the purposes of the specifications in this section, a machine is divided;; into "function units", each of which execute a specific class of;; instructions in first-in-first-out order.  Function units that accept one;; instruction each cycle and allow a result to be used in the succeeding;; instruction (usually via forwarding) need not be specified.  Classic RISC;; microprocessors will normally have a single function unit, which we can call;; `memory'.  The newer "superscalar" processors will often have function units;; for floating point operations, usually at least a floating point adder and;; multiplier.;; Each usage of a function units by a class of insns is specified with a;; `define_function_unit' expression, which looks like this:;; (define_function_unit NAME MULTIPLICITY SIMULTANEITY TEST READY-DELAY;;   ISSUE-DELAY [CONFLICT-LIST]);; NAME is a string giving the name of the function unit.;; MULTIPLICITY is an integer specifying the number of identical units in the;; processor.  If more than one unit is specified, they will be scheduled;; independently.  Only truly independent units should be counted; a pipelined;; unit should be specified as a single unit.  (The only common example of a;; machine that has multiple function units for a single instruction class that;; are truly independent and not pipelined are the two multiply and two;; increment units of the CDC 6600.);; SIMULTANEITY specifies the maximum number of insns that can be executing in;; each instance of the function unit simultaneously or zero if the unit is;; pipelined and has no limit.;; All `define_function_unit' definitions referring to function unit NAME must;; have the same name and values for MULTIPLICITY and SIMULTANEITY.;; TEST is an attribute test that selects the insns we are describing in this;; definition.  Note that an insn may use more than one function unit and a;; function unit may be specified in more than one `define_function_unit'.;; READY-DELAY is an integer that specifies the number of cycles after which;; the result of the instruction can be used without introducing any stalls.;; ISSUE-DELAY is an integer that specifies the number of cycles after the;; instruction matching the TEST expression begins using this unit until a;; subsequent instruction can begin.  A cost of N indicates an N-1 cycle delay.;; A subsequent instruction may also be delayed if an earlier instruction has a;; longer READY-DELAY value.  This blocking effect is computed using the;; SIMULTANEITY, READY-DELAY, ISSUE-DELAY, and CONFLICT-LIST terms.  For a;; normal non-pipelined function unit, SIMULTANEITY is one, the unit is taken;; to block for the READY-DELAY cycles of the executing insn, and smaller;; values of ISSUE-DELAY are ignored.;; CONFLICT-LIST is an optional list giving detailed conflict costs for this;; unit.  If specified, it is a list of condition test expressions to be;; applied to insns chosen to execute in NAME following the particular insn;; matching TEST that is already executing in NAME.  For each insn in the list,;; ISSUE-DELAY specifies the conflict cost; for insns not in the list, the cost;; is zero.  If not specified, CONFLICT-LIST defaults to all instructions that;; use the function unit.;; Typical uses of this vector are where a floating point function unit can;; pipeline either single- or double-precision operations, but not both, or;; where a memory unit can pipeline loads, but not stores, etc.;; As an example, consider a classic RISC machine where the result of a load;; instruction is not available for two cycles (a single "delay" instruction is;; required) and where only one load instruction can be executed;; simultaneously.  This would be specified as:;; (define_function_unit "memory" 1 1 (eq_attr "type" "load") 2 0);; For the case of a floating point function unit that can pipeline;; either single or double precision, but not both, the following could be;; specified:;;;; (define_function_unit "fp" 1 0;;   (eq_attr "type" "sp_fp") 4 4;;   [(eq_attr "type" "dp_fp")]);;;; (define_function_unit "fp" 1 0;;   (eq_attr "type" "dp_fp") 4 4;;   [(eq_attr "type" "sp_fp")]);; Note: The scheduler attempts to avoid function unit conflicts and uses all;; the specifications in the `define_function_unit' expression.  It has;; recently come to our attention that these specifications may not allow;; modeling of some of the newer "superscalar" processors that have insns using;; multiple pipelined units.  These insns will cause a potential conflict for;; the second unit used during their execution and there is no way of;; representing that conflict.  We welcome any examples of how function unit;; conflicts work in such processors and suggestions for their representation.;; Function units of the M32R;; Units that take one cycle do not need to be specified.;; (define_function_unit {name} {multiplicity} {simulataneity} {test};;                       {ready-delay} {issue-delay} [{conflict-list}]);; Hack to get GCC to better pack the instructions.;; We pretend there is a separate long function unit that conflicts with;; both the left and right 16 bit insn slots.(define_function_unit "short" 2 2  (and (eq_attr "m32r" "yes")       (and (eq_attr "insn_size" "short")	    (eq_attr "type" "!load2")))  1 0  [(eq_attr "insn_size" "long")])(define_function_unit "short" 2 2	;; load delay of 1 clock for mem execution + 1 clock for WB  (and (eq_attr "m32r" "yes")       (eq_attr "type" "load2"))  3 0  [(eq_attr "insn_size" "long")])(define_function_unit "long" 1 1  (and (eq_attr "m32r" "yes")       (and (eq_attr "insn_size" "long")	    (eq_attr "type" "!load4,load8")))  1 0  [(eq_attr "insn_size" "short")])(define_function_unit "long" 1 1	;; load delay of 1 clock for mem execution + 1 clock for WB  (and (eq_attr "m32r" "yes")       (and (eq_attr "insn_size" "long")	    (eq_attr "type" "load4,load8")))  3 0  [(eq_attr "insn_size" "short")])(define_function_unit "left" 1 1  (and (eq_attr "m32rx_pipeline" "o,either")       (eq_attr "type" "!load2"))  1 0  [(eq_attr "insn_size" "long")])(define_function_unit "left" 1 1	;; load delay of 1 clock for mem execution + 1 clock for WB  (and (eq_attr "m32rx_pipeline" "o,either")       (eq_attr "type" "load2"))  3 0  [(eq_attr "insn_size" "long")])(define_function_unit "right" 1 1  (eq_attr "m32rx_pipeline" "s,either")  1 0  [(eq_attr "insn_size" "long")])(define_function_unit "long" 1 1  (and (eq_attr "m32rx" "yes")       (and (eq_attr "insn_size" "long")	    (eq_attr "type" "!load4,load8")))  2 0  [(eq_attr "insn_size" "short")])(define_function_unit "long" 1 1	;; load delay of 1 clock for mem execution + 1 clock for WB  (and (eq_attr "m32rx" "yes")       (and (eq_attr "insn_size" "long")	    (eq_attr "type" "load4,load8")))  3 0  [(eq_attr "insn_size" "short")]);; Expand prologue as RTL(define_expand "prologue"  [(const_int 1)]  ""  "{  m32r_expand_prologue ();  DONE;}");; Move instructions.;;;; For QI and HI moves, the register must contain the full properly;; sign-extended value.  nonzero_bits assumes this [otherwise;; SHORT_IMMEDIATES_SIGN_EXTEND must be used, but the comment for it;; says it's a kludge and the .md files should be fixed instead].(define_expand "movqi"  [(set (match_operand:QI 0 "general_operand" "")	(match_operand:QI 1 "general_operand" ""))]  ""  "{  /* Everything except mem = const or mem = mem can be done easily.     Objects in the small data area are handled too.  */  if (GET_CODE (operands[0]) == MEM)    operands[1] = force_reg (QImode, operands[1]);}")(define_insn "*movqi_insn"  [(set (match_operand:QI 0 "move_dest_operand" "=r,r,r,r,r,T,m")	(match_operand:QI 1 "move_src_operand" "r,I,JQR,T,m,r,r"))]  "register_operand (operands[0], QImode) || register_operand (operands[1], QImode)"  "@   mv %0,%1   ldi %0,%#%1   ldi %0,%#%1   ldub %0,%1   ldub %0,%1   stb %1,%0   stb %1,%0"  [(set_attr "type" "int2,int2,int4,load2,load4,store2,store4")   (set_attr "length" "2,2,4,2,4,2,4")])(define_expand "movhi"  [(set (match_operand:HI 0 "general_operand" "")	(match_operand:HI 1 "general_operand" ""))]  ""  "{  /* Everything except mem = const or mem = mem can be done easily.  */  if (GET_CODE (operands[0]) == MEM)    operands[1] = force_reg (HImode, operands[1]);}")(define_insn "*movhi_insn"  [(set (match_operand:HI 0 "move_dest_operand" "=r,r,r,r,r,r,T,m")	(match_operand:HI 1 "move_src_operand" "r,I,JQR,K,T,m,r,r"))]  "register_operand (operands[0], HImode) || register_operand (operands[1], HImode)"  "@   mv %0,%1   ldi %0,%#%1   ldi %0,%#%1   ld24 %0,%#%1   lduh %0,%1   lduh %0,%1   sth %1,%0   sth %1,%0"  [(set_attr "type" "int2,int2,int4,int4,load2,load4,store2,store4")   (set_attr "length" "2,2,4,4,2,4,2,4")])(define_expand "movsi_push"  [(set (mem:SI (pre_dec:SI (match_operand:SI 0 "register_operand" "")))	(match_operand:SI 1 "register_operand" ""))]  ""  "")(define_expand "movsi_pop"  [(set (match_operand:SI 0 "register_operand" "")	(mem:SI (post_inc:SI (match_operand:SI 1 "register_operand" ""))))]  ""  "")(define_expand "movsi"  [(set (match_operand:SI 0 "general_operand" "")	(match_operand:SI 1 "general_operand" ""))]  ""  "{  /* Everything except mem = const or mem = mem can be done easily.  */  if (GET_CODE (operands[0]) == MEM)    operands[1] = force_reg (SImode, operands[1]);  /* Small Data Area reference?  */  if (small_data_operand (operands[1], SImode))    {      emit_insn (gen_movsi_sda (operands[0], operands[1]));      DONE;    }  /* If medium or large code model, symbols have to be loaded with     seth/add3.  */  if (addr32_operand (operands[1], SImode))    {      emit_insn (gen_movsi_addr32 (operands[0], operands[1]));      DONE;    }}");; ??? Do we need a const_double constraint here for large unsigned values?(define_insn "*movsi_insn"  [(set (match_operand:SI 0 "move_dest_operand" "=r,r,r,r,r,r,r,r,r,T,S,m")	(match_operand:SI 1 "move_src_operand" "r,I,J,MQ,L,n,T,U,m,r,r,r"))]  "register_operand (operands[0], SImode) || register_operand (operands[1], SImode)"  "*{  if (GET_CODE (operands[0]) == REG || GET_CODE (operands[1]) == SUBREG)    {      switch (GET_CODE (operands[1]))	{	  HOST_WIDE_INT value;	  default:	    break;	  case REG:	  case SUBREG:	    return \"mv %0,%1\";	  case MEM:	    if (GET_CODE (XEXP (operands[1], 0)) == POST_INC		&& XEXP (XEXP (operands[1], 0), 0) == stack_pointer_rtx)	      return \"pop %0\";	    return \"ld %0,%1\";	  case CONST_INT:	    value = INTVAL (operands[1]);	    if (INT16_P (value))	      return \"ldi %0,%#%1\\t; %X1\";	    if (UINT24_P (value))	      return \"ld24 %0,%#%1\\t; %X1\";	    if (UPPER16_P (value))	      return \"seth %0,%#%T1\\t; %X1\";	    return \"#\";	  case CONST:	  case SYMBOL_REF:	  case LABEL_REF:	    if (TARGET_ADDR24)	      return \"ld24 %0,%#%1\";	    return \"#\";	}    }  else if (GET_CODE (operands[0]) == MEM	   && (GET_CODE (operands[1]) == REG || GET_CODE (operands[1]) == SUBREG))    {      if (GET_CODE (XEXP (operands[0], 0)) == PRE_DEC	  && XEXP (XEXP (operands[0], 0), 0) == stack_pointer_rtx)	return \"push %1\";      return \"st %1,%0\";    }  abort ();}"  [(set_attr "type" "int2,int2,int4,int4,int4,multi,load2,load2,load4,store2,store2,store4")   (set_attr "length" "2,2,4,4,4,8,2,2,4,2,2,4")]); Try to use a four byte / two byte pair for constants not loadable with; ldi, ld24, seth.(define_split [(set (match_operand:SI 0 "register_operand" "")       (match_operand:SI 1 "two_insn_const_operand" ""))]  ""  [(set (match_dup 0) (match_dup 2))   (set (match_dup 0) (ior:SI (match_dup 0) (match_dup 3)))]  "{  unsigned HOST_WIDE_INT val = INTVAL (operands[1]);  unsigned HOST_WIDE_INT tmp;

⌨️ 快捷键说明

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