📄 i370.md
字号:
;;- Machine description for GNU compiler -- System/370 version.;; Copyright (C) 1989, 93, 94, 95, 97, 1999 Free Software Foundation, Inc.;; Contributed by Jan Stein (jan@cd.chalmers.se).;; Modified for MVS C/370 by Dave Pitts (dpitts@nyx.cs.du.edu);; 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.;;- cpp macro #define NOTICE_UPDATE_CC in file tm.h handles condition code;;- updates for most instructions.;;;; 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).;;;; Special formats used for outputting 370 instructions.;;;; %B -- Print a constant byte integer.;; %H -- Print a signed 16-bit constant.;; %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.;;;; 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.;;;;;;- 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\";}");; 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\";}");; 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'\";}");; 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])) { mvs_check_page (0, 4, 4); return \"N %0,=X'000000FF'\"; } mvs_check_page (0, 4, 0); return \"CLI %0,0\";}")(define_insn "tstqi" [(set (cc0) (match_operand:QI 0 "register_operand" "d"))] "" "*{ check_label_emit (); if (unsigned_jump_follows_p (insn)) { mvs_check_page (0, 4, 4); return \"N %0,=X'000000FF'\"; } mvs_check_page (0, 8, 0); return \"SLL %0,24\;SRA %0,24\";}");; 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\";}");; 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\";}");;;;- 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\";}");; cmphi instruction pattern(s).;(define_insn "cmphi" [(set (cc0) (compare (match_operand:HI 0 "register_operand" "d") (match_operand:HI 1 "general_operand" "")))] "" "*{ 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\";}");; cmpqi instruction pattern(s).;(define_insn "" [(set (cc0) (compare (match_operand:QI 0 "r_or_s_operand" "g") (match_operand:QI 1 "r_or_s_operand" "g")))] "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,=FL1'%B1'\"; } 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,=FL1'%B0'\"; } 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\";}")(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 (REG_P (operands[1])) { mvs_check_page (0, 4, 0); return \"CLM %0,1,%1\"; } if (GET_CODE (operands[1]) == CONST_INT) { mvs_check_page (0, 4, 1); return \"CLM %0,1,=FL1'%B1'\"; } 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\";}");; 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\";}");; 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\";}");; cmpstrsi instruction pattern(s).;(define_expand "cmpstrsi" [(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 { rtx reg1 = gen_reg_rtx (DImode); rtx reg2 = gen_reg_rtx (DImode); rtx subreg = gen_rtx (SUBREG, SImode, reg1, 1); emit_insn (gen_rtx (SET, VOIDmode, subreg, operands[3])); emit_insn (gen_rtx (SET, VOIDmode, gen_rtx (SUBREG, SImode, reg2, 1), subreg)); emit_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (5, gen_rtx (SET, VOIDmode, operands[0], gen_rtx (COMPARE, VOIDmode, op1, op2)), gen_rtx (USE, VOIDmode, reg1), gen_rtx (USE, VOIDmode, reg2), gen_rtx (CLOBBER, VOIDmode, reg1), gen_rtx (CLOBBER, VOIDmode, reg2)))); } DONE;}"); Compare a block that is less than 256 bytes in length.(define_insn "" [(set (match_operand:SI 0 "register_operand" "d") (compare (match_operand:BLK 1 "s_operand" "m") (match_operand:BLK 2 "s_operand" "m"))) (use (match_operand:QI 3 "immediate_operand" "I"))] "((unsigned) INTVAL (operands[3]) < 256)" "*{ check_label_emit (); mvs_check_page (0, 22, 0); return \"LA %0,1\;CLC %O1(%c3,%R1),%2\;BH *+12\;BL *+6\;SLR %0,%0\;LNR %0,%0\";}"); Compare a block that is larger than 255 bytes in length.(define_insn "" [(set (match_operand:SI 0 "register_operand" "d") (compare (match_operand:BLK 1 "general_operand" "m") (match_operand:BLK 2 "general_operand" "m"))) (use (match_operand:DI 3 "register_operand" "d")) (use (match_operand:DI 4 "register_operand" "d")) (clobber (match_dup 3)) (clobber (match_dup 4))] "" "*{ check_label_emit (); mvs_check_page (0, 26, 0); return \"LA %3,%1\;LA %4,%2\;LA %0,1\;CLCL %3,%4\;BH *+12\;BL *+6\;SLR %0,%0\;LNR %0,%0\";}");;;;- Move instructions.;;;; movdi instruction pattern(s).;(define_insn "" [(set (match_operand:DI 0 "r_or_s_operand" "=dm") (match_operand:DI 1 "r_or_s_operand" "dim*fF"))] "TARGET_CHAR_INSTRUCTIONS" "*{ check_label_emit (); if (REG_P (operands[0])) { if (FP_REG_P (operands[1])) { mvs_check_page (0, 8, 0); return \"STD %1,140(,13)\;LM %0,%N0,140(13)\"; } if (REG_P (operands[1])) { mvs_check_page (0, 4, 0); return \"LR %0,%1\;LR %N0,%N1\"; } if (operands[1] == const0_rtx) { CC_STATUS_INIT; mvs_check_page (0, 4, 0); return \"SLR %0,%0\;SLR %N0,%N0\"; } if (GET_CODE (operands[1]) == CONST_INT && (unsigned) INTVAL (operands[1]) < 4096) { CC_STATUS_INIT; mvs_check_page (0, 6, 0); return \"SLR %0,%0\;LA %N0,%c1\"; } if (GET_CODE (operands[1]) == CONST_INT) { CC_STATUS_SET (operands[0], operands[1]); mvs_check_page (0, 8, 0); return \"L %0,%1\;SRDA %0,32\"; } mvs_check_page (0, 4, 0); return \"LM %0,%N0,%1\"; } else if (FP_REG_P (operands[1])) { mvs_check_page (0, 4, 0); return \"STD %1,%0\"; } else if (REG_P (operands[1])) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -