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

📄 i370.md

📁 linux下的gcc编译器
💻 MD
📖 第 1 页 / 共 5 页
字号:
;;- Machine description for GNU compiler -- System/370 version.;;  Copyright (C) 1989, 1993, 1994, 1995, 1997, 1998, 1999, 2000, 2002;;  Free Software Foundation, Inc.;;  Contributed by Jan Stein (jan@cd.chalmers.se).;;  Modified for OS/390 LanguageEnvironment C by Dave Pitts (dpitts@cozx.com);;  Lots of Bug Fixes & Enhancements by Linas Vepstas (linas@linas.org);; 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.;; =======================================================================;; Condition codes for some of the instructions (in particular, for ;; add, sub, shift, abs, etc. are handled with the cpp macro NOTICE_UPDATE_CC ;;;; Special constraints for 370 machine description:;;;;    a -- Any address register from 1 to 15.;;    d -- Any register from 0 to 15.;;    I -- An 8-bit constant (0..255).;;    J -- A 12-bit constant (0..4095).;;    K -- A 16-bit constant (-32768..32767).;;    R -- a valid S operand in an RS, SI or SS instruction, or register;;    S -- a valid S operand in an RS, SI or SS instruction;;;; Note this well: ;; When defining an instruction, e.g. the movsi pattern:;; ;;    (define_insn "";;        [(set (match_operand:SI 0 "r_or_s_operand" "=dm,d,dm");;            (match_operand:SI 1 "r_or_s_operand" "diR,dim,*fF"))];;;; The "r_or_s_operand" predicate is used to recognize the instruction;;; however, it is not further used to enforce a constraint at later stages.;; Thus, for example, although "r_or_s_operand" bars operands of the form;; base+index+displacement, such operands can none-the-less show up during;; post-instruction-recog processing: thus, for example, garbage like;; MVC     152(4,r13),0(r5,r13) might be generated if both op0 and op1 are ;; mem operands.   To avoid this, use the S constraint.;; ;;;; Special formats used for outputting 370 instructions.;;;;   %B -- Print a constant byte integer.;;   %H -- Print a signed 16-bit constant.;;   %K -- Print a signed 16-bit constant signed-extended to 32-bits.;;   %L -- Print least significant word of a CONST_DOUBLE.;;   %M -- Print most significant word of a CONST_DOUBLE.;;   %N -- Print next register (second word of a DImode reg).;;   %O -- Print the offset of a memory reference (PLUS (REG) (CONST_INT)).;;   %R -- Print the register of a memory reference (PLUS (REG) (CONST_INT)).;;   %X -- Print a constant byte integer in hex.;;   %W -- Print a signed 32-bit int sign-extended to 64-bits.;;;; We have a special constraint for pattern matching.;;;;   s_operand -- Matches a valid S operand in a RS, SI or SS type instruction.;;;;   r_or_s_operand -- Matches a register or a valid S operand in a RS, SI;;		       or SS type instruction or a register;;;; For MVS C/370 we use the following stack locations for:;;;;   136 - internal function result buffer;;   140 - numeric conversion buffer;;   144 - pointer to internal function result buffer;;   148 - start of automatic variables and function arguments;;;; To support programs larger than a page, 4096 bytes, PAGE_REGISTER points;; to a page origin table, all internal labels are generated to reload the;; BASE_REGISTER knowing what page it is on and all branch instructions go;; directly to the target if it is known that the target is on the current;; page (essentially backward references).  All forward references and off;; page references are handled by loading the address of target into a;; register and branching indirectly.;;;; Some *di patterns have been commented out per advice from RMS, as gcc;; will generate the right things to do.;;;; See the note in i370.h about register 14, clobbering it, and optimization.;; Basically, using clobber in egcs-1.1.1 will ruin ability to optimize around;; branches, so don't do it.;;;; We use the "length" attirbute to store the max possible code size of an;; insn.  We use this length to estimate the length of forward branches, to;; determine if they're on page or off.(define_attr "length" "" (const_int 0));;;;- Test instructions.;;;; tstdi instruction pattern(s).;(define_insn "tstdi"  [(set (cc0)	(match_operand:DI 0 "register_operand" "d"))]  ""  "*{  check_label_emit ();  mvs_check_page (0, 4, 0);  return \"SRDA	%0,0\";}"   [(set_attr "length" "4")]);; tstsi instruction pattern(s).;(define_insn "tstsi"  [(set (cc0)	(match_operand:SI 0 "register_operand" "d"))]  ""  "*{  check_label_emit ();  mvs_check_page (0, 2, 0);  return \"LTR	%0,%0\";}"   [(set_attr "length" "2")]);; tsthi instruction pattern(s).;(define_insn "tsthi"  [(set (cc0)	(match_operand:HI 0 "register_operand" "d"))]  ""  "*{  check_label_emit ();  mvs_check_page (0, 4, 2);  return \"CH	%0,=H'0'\";}"   [(set_attr "length" "4")]);; tstqi instruction pattern(s).;(define_insn ""  [(set (cc0)	(match_operand:QI 0 "r_or_s_operand" "dm"))]  "unsigned_jump_follows_p (insn)"  "*{  check_label_emit ();  if (REG_P (operands[0]))    {      /* an unsigned compare to zero is always zero/not-zero...  */      mvs_check_page (0, 4, 4);      return \"N	%0,=XL4'000000FF'\";    }  mvs_check_page (0, 4, 0);  return \"CLI	%0,0\";}"   [(set_attr "length" "4")])(define_insn "tstqi"  [(set (cc0)     (match_operand:QI 0 "register_operand" "d"))]  ""  "*{  check_label_emit ();  if (unsigned_jump_follows_p (insn))    {      /* an unsigned compare to zero is always zero/not-zero...  */      mvs_check_page (0, 4, 4);      return \"N	%0,=XL4'000000FF'\";    }  mvs_check_page (0, 8, 0);  return \"SLL	%0,24\;SRA	%0,24\";}"   [(set_attr "length" "8")]);; tstdf instruction pattern(s).;(define_insn "tstdf"  [(set (cc0)	(match_operand:DF 0 "general_operand" "f"))]  ""  "*{  check_label_emit ();  mvs_check_page (0, 2, 0);  return \"LTDR	%0,%0\";}"   [(set_attr "length" "2")]);; tstsf instruction pattern(s).;(define_insn "tstsf"  [(set (cc0)	(match_operand:SF 0 "general_operand" "f"))]  ""  "*{  check_label_emit ();  mvs_check_page (0, 2, 0);  return \"LTER	%0,%0\";}"   [(set_attr "length" "2")]);;;;- Compare instructions.;;;; cmpdi instruction pattern(s).;;(define_insn "cmpdi";  [(set (cc0);	(compare (match_operand:DI 0 "register_operand" "d");		 (match_operand:DI 1 "general_operand" "")))];  "";  "*;{;  check_label_emit ();;  if (REG_P (operands[1]));    {;      mvs_check_page (0, 8, 0);;      if (unsigned_jump_follows_p (insn));        return \"CLR	%0,%1\;BNE	*+6\;CLR	%N0,%N1\";;      return \"CR	%0,%1\;BNE	*+6\;CLR	%N0,%N1\";;    };  mvs_check_page (0, 12, 0);;  if (unsigned_jump_follows_p (insn));    return \"CL	%0,%M1\;BNE	*+8\;CL	%N0,%L1\";;  return \"C	%0,%M1\;BNE	*+8\;CL	%N0,%L1\";;}");; cmpsi instruction pattern(s).;(define_insn "cmpsi"  [(set (cc0)	(compare (match_operand:SI 0 "register_operand" "d")		 (match_operand:SI 1 "general_operand" "md")))]  ""  "*{  check_label_emit ();  if (REG_P (operands[1]))    {      mvs_check_page (0, 2, 0);      if (unsigned_jump_follows_p (insn))	return \"CLR	%0,%1\";      return \"CR	%0,%1\";    }  if (GET_CODE (operands[1]) == CONST_INT)    {      mvs_check_page (0, 4, 4);      if (unsigned_jump_follows_p (insn))	 return \"CL	%0,=F'%c1'\";      return \"C	%0,=F'%c1'\";    }  mvs_check_page (0, 4, 0);  if (unsigned_jump_follows_p (insn))    return \"CL	%0,%1\";  return \"C	%0,%1\";}"   [(set_attr "length" "4")]);; cmphi instruction pattern(s).;; deprecate constraint d because it takes multiple instructions; and a memeory access ...(define_insn "cmphi"  [(set (cc0)	(compare (match_operand:HI 0 "register_operand" "d")		 (match_operand:HI 1 "general_operand" "???dim")))]  ""  "*{  check_label_emit ();  if (REG_P (operands[1]))    {      mvs_check_page (0, 8, 0);      if (unsigned_jump_follows_p (insn))	return \"STH	%1,140(,13)\;CLM	%0,3,140(13)\";      return \"STH	%1,140(,13)\;CH	%0,140(,13)\";    }  if (GET_CODE (operands[1]) == CONST_INT)    {      mvs_check_page (0, 4, 0);      return \"CH	%0,%H1\";    }  mvs_check_page (0, 4, 0);  return \"CH	%0,%1\";}"   [(set_attr "length" "8")]);; cmpqi instruction pattern(s).;(define_insn ""  [(set (cc0)	(compare (match_operand:QI 0 "r_or_s_operand" "dS")		 (match_operand:QI 1 "r_or_s_operand" "diS")))]  "unsigned_jump_follows_p (insn)"  "*{  check_label_emit ();  if (REG_P (operands[0]))    {      if (REG_P (operands[1]))	{	  mvs_check_page (0, 8, 0);          return \"STC	%1,140(,13)\;CLM	%0,1,140(13)\";        }      if (GET_CODE (operands[1]) == CONST_INT)	{	  mvs_check_page (0, 4, 1);          return \"CLM	%0,1,=XL1'%X1'\";        }      mvs_check_page (0, 4, 0);      return \"CLM	%0,1,%1\";    }  else if (GET_CODE (operands[0]) == CONST_INT)    {      cc_status.flags |= CC_REVERSED;      if (REG_P (operands[1]))	{	  mvs_check_page (0, 4, 1);          return \"CLM	%1,1,=XL1'%X0'\";        }      mvs_check_page (0, 4, 0);      return \"CLI	%1,%B0\";    }  if (GET_CODE (operands[1]) == CONST_INT)    {      mvs_check_page (0, 4, 0);      return \"CLI	%0,%B1\";    }  if (GET_CODE (operands[1]) == MEM)    {      mvs_check_page (0, 6, 0);      return \"CLC	%O0(1,%R0),%1\";    }  cc_status.flags |= CC_REVERSED;  mvs_check_page (0, 4, 0);  return \"CLM	%1,1,%0\";}"   [(set_attr "length" "8")])(define_insn "cmpqi"  [(set (cc0)	(compare (match_operand:QI 0 "register_operand" "d")		 (match_operand:QI 1 "general_operand" "di")))]  ""  "*{  check_label_emit ();  if (unsigned_jump_follows_p (insn))    {      if (GET_CODE (operands[1]) == CONST_INT)	{	  mvs_check_page (0, 4, 1);          return \"CLM	%0,1,=XL1'%X1'\";        }      if (!(REG_P (operands[1])))	{	  mvs_check_page (0, 4, 0);          return \"CLM	%0,1,%1\";        }      mvs_check_page (0, 8, 0);      return \"STC	%1,140(,13)\;CLM	%0,1,140(13)\";    }  if (REG_P (operands[1]))    {      mvs_check_page (0, 18, 0);      return \"SLL	%0,24\;SRA	%0,24\;SLL	%1,24\;SRA	%1,24\;CR	%0,%1\";    }  mvs_check_page (0, 12, 0);  return \"SLL	%0,24\;SRA	%0,24\;C	%0,%1\";}"   [(set_attr "length" "18")]);; cmpdf instruction pattern(s).;(define_insn "cmpdf"  [(set (cc0)	(compare (match_operand:DF 0 "general_operand" "f,mF")		 (match_operand:DF 1 "general_operand" "fmF,f")))]  ""  "*{  check_label_emit ();  if (FP_REG_P (operands[0]))    {      if (FP_REG_P (operands[1]))	{	  mvs_check_page (0, 2, 0);	  return \"CDR	%0,%1\";	}      mvs_check_page (0, 4, 0);      return \"CD	%0,%1\";    }  cc_status.flags |= CC_REVERSED;  mvs_check_page (0, 4, 0);  return \"CD	%1,%0\";}"   [(set_attr "length" "4")]);; cmpsf instruction pattern(s).;(define_insn "cmpsf"  [(set (cc0)	(compare (match_operand:SF 0 "general_operand" "f,mF")		 (match_operand:SF 1 "general_operand" "fmF,f")))]  ""  "*{check_label_emit ();  if (FP_REG_P (operands[0]))    {      if (FP_REG_P (operands[1]))	{	  mvs_check_page (0, 2, 0);	  return \"CER	%0,%1\";	}      mvs_check_page (0, 4, 0);      return \"CE	%0,%1\";    }  cc_status.flags |= CC_REVERSED;  mvs_check_page (0, 4, 0);  return \"CE	%1,%0\";}"   [(set_attr "length" "4")]);; cmpmemsi instruction pattern(s).;(define_expand "cmpmemsi"  [(set (match_operand:SI 0 "general_operand" "")	  (compare (match_operand:BLK 1 "general_operand" "")		   (match_operand:BLK 2 "general_operand" "")))     (use (match_operand:SI 3 "general_operand" ""))     (use (match_operand:SI 4 "" ""))]   ""   "{  rtx op1, op2;  op1 = XEXP (operands[1], 0);  if (GET_CODE (op1) == REG      || (GET_CODE (op1) == PLUS && GET_CODE (XEXP (op1, 0)) == REG	  && GET_CODE (XEXP (op1, 1)) == CONST_INT	  && (unsigned) INTVAL (XEXP (op1, 1)) < 4096))    {      op1 = operands[1];    }  else    {      op1 = gen_rtx_MEM (BLKmode, copy_to_mode_reg (SImode, op1));    }  op2 = XEXP (operands[2], 0);  if (GET_CODE (op2) == REG      || (GET_CODE (op2) == PLUS && GET_CODE (XEXP (op2, 0)) == REG	  && GET_CODE (XEXP (op2, 1)) == CONST_INT	  && (unsigned) INTVAL (XEXP (op2, 1)) < 4096))    {      op2 = operands[2];    }  else    {      op2 = gen_rtx_MEM (BLKmode, copy_to_mode_reg (SImode, op2));    }        if (GET_CODE (operands[3]) == CONST_INT && INTVAL (operands[3]) < 256)    {      emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,		gen_rtx_SET (VOIDmode, operands[0], 			gen_rtx_COMPARE (VOIDmode, op1, op2)),		gen_rtx_USE (VOIDmode, operands[3]))));    }  else    {        /* implementation suggested by  Richard Henderson <rth@cygnus.com> */        rtx reg1 = gen_reg_rtx (DImode);        rtx reg2 = gen_reg_rtx (DImode);        rtx result = operands[0];        rtx mem1 = operands[1];        rtx mem2 = operands[2];        rtx len = operands[3];        if (!CONSTANT_P (len))          len = force_reg (SImode, len);        /* Load up the address+length pairs.  */        emit_insn (gen_rtx_CLOBBER (VOIDmode, reg1));        emit_move_insn (gen_rtx_SUBREG (SImode, reg1, 0),                        force_operand (XEXP (mem1, 0), NULL_RTX));        emit_move_insn (gen_rtx_SUBREG (SImode, reg1, GET_MODE_SIZE (SImode)), len);        emit_insn (gen_rtx_CLOBBER (VOIDmode, reg2));        emit_move_insn (gen_rtx_SUBREG (SImode, reg2, 0),                        force_operand (XEXP (mem2, 0), NULL_RTX));

⌨️ 快捷键说明

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