📄 ns32k.md
字号:
;;- Machine description for GNU compiler, ns32000 Version;; Copyright (C) 1988, 1994, 1996, 1999 Free Software Foundation, Inc.;; Contributed by Michael Tiemann (tiemann@cygnus.com);; 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.; BUGS:;; Insert no-op between an insn with memory read-write operands;; following by a scale-indexing operation.;; The Sequent assembler does not allow addresses to be used;; except in insns which explicitly compute an effective address.;; I.e., one cannot say "cmpd _p,@_x";; Implement unsigned multiplication??;;- Instruction patterns. When multiple patterns apply,;;- the first one in the file is chosen.;;-;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.;;-;;- cpp macro #define NOTICE_UPDATE_CC in file tm.h handles condition code;;- updates for most instructions.;; We don't want to allow a constant operand for test insns because;; (set (cc0) (const_int foo)) has no mode information. Such insns will;; be folded while optimizing anyway.;;;; In order for pic mode to work we cannot generate, for example;;;; addd _x+5,r1;;;; instead we must force gcc to generate something like;;;; addr 5(_x(sb)),r0;; addd r0,r1;;;; This was done through operand constraints (using "rmn" in place of "g"),;; but with the proper definition of LEGITIMATE_PIC_OPERAND (ns32k.h);; this is unnecessary.;;(define_insn "tstsi" [(set (cc0) (match_operand:SI 0 "nonimmediate_operand" "rm"))] "" "*{ cc_status.flags |= CC_REVERSED; operands[1] = const0_rtx; return \"cmpqd %1,%0\"; }")(define_insn "tsthi" [(set (cc0) (match_operand:HI 0 "nonimmediate_operand" "g"))] "" "*{ cc_status.flags |= CC_REVERSED; operands[1] = const0_rtx; return \"cmpqw %1,%0\"; }")(define_insn "tstqi" [(set (cc0) (match_operand:QI 0 "nonimmediate_operand" "g"))] "" "*{ cc_status.flags |= CC_REVERSED; operands[1] = const0_rtx; return \"cmpqb %1,%0\"; }")(define_insn "tstdf" [(set (cc0) (match_operand:DF 0 "general_operand" "lmF"))] "TARGET_32081" "*{ cc_status.flags |= CC_REVERSED; operands[1] = CONST0_RTX (DFmode); return \"cmpl %1,%0\"; }")(define_insn "tstsf" [(set (cc0) (match_operand:SF 0 "general_operand" "fmF"))] "TARGET_32081" "*{ cc_status.flags |= CC_REVERSED; operands[1] = CONST0_RTX (SFmode); return \"cmpf %1,%0\"; }");; See note 1(define_insn "cmpsi" [(set (cc0) (compare (match_operand:SI 0 "general_operand" "g") (match_operand:SI 1 "general_operand" "g")))] "" "*{ if (GET_CODE (operands[1]) == CONST_INT) { int i = INTVAL (operands[1]); if (i <= 7 && i >= -8) { cc_status.flags |= CC_REVERSED; return \"cmpqd %1,%0\"; } } cc_status.flags &= ~CC_REVERSED; if (GET_CODE (operands[0]) == CONST_INT) { int i = INTVAL (operands[0]); if (i <= 7 && i >= -8) return \"cmpqd %0,%1\"; } return \"cmpd %0,%1\";}")(define_insn "cmphi" [(set (cc0) (compare (match_operand:HI 0 "general_operand" "g") (match_operand:HI 1 "general_operand" "g")))] "" "*{ if (GET_CODE (operands[1]) == CONST_INT) { short i = INTVAL (operands[1]); if (i <= 7 && i >= -8) { cc_status.flags |= CC_REVERSED; if (INTVAL (operands[1]) > 7) operands[1] = GEN_INT (i); return \"cmpqw %1,%0\"; } } cc_status.flags &= ~CC_REVERSED; if (GET_CODE (operands[0]) == CONST_INT) { short i = INTVAL (operands[0]); if (i <= 7 && i >= -8) { if (INTVAL (operands[0]) > 7) operands[0] = GEN_INT (i); return \"cmpqw %0,%1\"; } } return \"cmpw %0,%1\";}")(define_insn "cmpqi" [(set (cc0) (compare (match_operand:QI 0 "general_operand" "g") (match_operand:QI 1 "general_operand" "g")))] "" "*{ if (GET_CODE (operands[1]) == CONST_INT) { char i = INTVAL (operands[1]); if (i <= 7 && i >= -8) { cc_status.flags |= CC_REVERSED; if (INTVAL (operands[1]) > 7) operands[1] = GEN_INT (i); return \"cmpqb %1,%0\"; } } cc_status.flags &= ~CC_REVERSED; if (GET_CODE (operands[0]) == CONST_INT) { char i = INTVAL (operands[0]); if (i <= 7 && i >= -8) { if (INTVAL (operands[0]) > 7) operands[0] = GEN_INT (i); return \"cmpqb %0,%1\"; } } return \"cmpb %0,%1\";}")(define_insn "cmpdf" [(set (cc0) (compare (match_operand:DF 0 "general_operand" "lmF") (match_operand:DF 1 "general_operand" "lmF")))] "TARGET_32081" "cmpl %0,%1")(define_insn "cmpsf" [(set (cc0) (compare (match_operand:SF 0 "general_operand" "fmF") (match_operand:SF 1 "general_operand" "fmF")))] "TARGET_32081" "cmpf %0,%1");; movdf and movsf copy between general and floating registers using;; the stack. In principle, we could get better code not allowing;; that case in the constraints and defining SECONDARY_MEMORY_NEEDED;; in practice, though the stack slots used are not available for;; optimization.(define_insn "movdf" [(set (match_operand:DF 0 "general_operand" "=lg<") (match_operand:DF 1 "general_operand" "lFg"))] "" "*{ if (FP_REG_P (operands[0])) { if (FP_REG_P (operands[1]) || GET_CODE (operands[1]) == CONST_DOUBLE) return \"movl %1,%0\"; if (REG_P (operands[1])) { rtx xoperands[2]; xoperands[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1); output_asm_insn (\"movd %1,tos\", xoperands); output_asm_insn (\"movd %1,tos\", operands); return \"movl tos,%0\"; } return \"movl %1,%0\"; } else if (FP_REG_P (operands[1])) { if (REG_P (operands[0])) { output_asm_insn (\"movl %1,tos\;movd tos,%0\", operands); operands[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1); return \"movd tos,%0\"; } else return \"movl %1,%0\"; } return output_move_double (operands);}")(define_insn "movsf" [(set (match_operand:SF 0 "general_operand" "=fg<") (match_operand:SF 1 "general_operand" "fFg"))] "" "*{ if (FP_REG_P (operands[0])) { if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) < F0_REGNUM) return \"movd %1,tos\;movf tos,%0\"; else return \"movf %1,%0\"; } else if (FP_REG_P (operands[1])) { if (REG_P (operands[0])) return \"movf %1,tos\;movd tos,%0\"; return \"movf %1,%0\"; }#if 0 /* Someone suggested this for the Sequent. Is it needed? */ else if (GET_CODE (operands[1]) == CONST_DOUBLE) return \"movf %1,%0\";#endif/* There was a #if 0 around this, but that was erroneous for many machines -- rms. */#ifndef MOVD_FLOAT_OK /* GAS understands floating constants in ordinary movd instructions but other assemblers might object. */ else if (GET_CODE (operands[1]) == CONST_DOUBLE) { union {int i[2]; float f; double d;} convrt; convrt.i[0] = CONST_DOUBLE_LOW (operands[1]); convrt.i[1] = CONST_DOUBLE_HIGH (operands[1]); convrt.f = convrt.d; /* Is there a better machine-independent way to do this? */ operands[1] = GEN_INT (convrt.i[0]); return \"movd %1,%0\"; }#endif else return \"movd %1,%0\";}")(define_insn "" [(set (match_operand:TI 0 "memory_operand" "=m") (match_operand:TI 1 "memory_operand" "m"))] "" "movmd %1,%0,4")(define_insn "movdi" [(set (match_operand:DI 0 "general_operand" "=g<,*f,g") (match_operand:DI 1 "general_operand" "gF,g,*f"))] "" "*{ if (FP_REG_P (operands[0])) { if (FP_REG_P (operands[1]) || GET_CODE (operands[1]) == CONST_DOUBLE) return \"movl %1,%0\"; if (REG_P (operands[1])) { rtx xoperands[2]; xoperands[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1); output_asm_insn (\"movd %1,tos\", xoperands); output_asm_insn (\"movd %1,tos\", operands); return \"movl tos,%0\"; } return \"movl %1,%0\"; } else if (FP_REG_P (operands[1])) { if (REG_P (operands[0])) { output_asm_insn (\"movl %1,tos\;movd tos,%0\", operands); operands[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1); return \"movd tos,%0\"; } else return \"movl %1,%0\"; } return output_move_double (operands);}");; This special case must precede movsi.(define_insn "" [(set (reg:SI 25) (match_operand:SI 0 "general_operand" "g"))] "" "lprd sp,%0")(define_insn "movsi" [(set (match_operand:SI 0 "general_operand" "=g<,g<,*f,g,x") (match_operand:SI 1 "general_operand" "g,?xy,g,*f,rmn"))] "" "*{ extern int flag_pic; \ if (FP_REG_P (operands[0])) { if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) < F0_REGNUM) return \"movd %1,tos\;movf tos,%0\"; else return \"movf %1,%0\"; } else if (FP_REG_P (operands[1])) { if (REG_P (operands[0])) return \"movf %1,tos\;movd tos,%0\"; return \"movf %1,%0\"; } if (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == FRAME_POINTER_REGNUM) return \"lprd fp,%1\"; if (GET_CODE (operands[1]) == CONST_DOUBLE) operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1])); if (GET_CODE (operands[1]) == CONST_INT) { int i = INTVAL (operands[1]); if (! TARGET_32532) { if (i <= 7 && i >= -8) return \"movqd %1,%0\"; if (NS32K_DISPLACEMENT_P (i))#if defined (GNX_V3) || defined (UTEK_ASM) return \"addr %c1,%0\";#else return \"addr @%c1,%0\";#endif return \"movd %1,%0\"; } else return output_move_dconst(i, \"%1,%0\"); } else if (GET_CODE (operands[1]) == CONST && ! flag_pic) { /* Must contain symbols so we don`t know how big it is. In * that case addr might lead to overflow. For PIC symbolic * address loads always have to be done with addr. */ return \"movd %1,%0\"; } else if (GET_CODE (operands[1]) == REG) { if (REGNO (operands[1]) < F0_REGNUM) return \"movd %1,%0\"; else if (REGNO (operands[1]) == FRAME_POINTER_REGNUM) { if (GET_CODE(operands[0]) == REG) return \"sprd fp,%0\"; else return \"addr 0(fp),%0\" ; } else if (REGNO (operands[1]) == STACK_POINTER_REGNUM) { if (GET_CODE(operands[0]) == REG) return \"sprd sp,%0\"; else return \"addr 0(sp),%0\" ; } else abort (); } else if (GET_CODE (operands[1]) == MEM) return \"movd %1,%0\"; /* Check if this effective address can be calculated faster by pulling it apart. */ if (REG_P (operands[0]) && GET_CODE (operands[1]) == MULT && GET_CODE (XEXP (operands[1], 1)) == CONST_INT && (INTVAL (XEXP (operands[1], 1)) == 2 || INTVAL (XEXP (operands[1], 1)) == 4)) { rtx xoperands[3]; xoperands[0] = operands[0]; xoperands[1] = XEXP (operands[1], 0); xoperands[2] = GEN_INT (INTVAL (XEXP (operands[1], 1)) >> 1); return output_shift_insn (xoperands); } return \"addr %a1,%0\";}")(define_insn "movhi" [(set (match_operand:HI 0 "general_operand" "=g<,*f,g") (match_operand:HI 1 "general_operand" "g,g,*f"))] "" "*{ if (GET_CODE (operands[1]) == CONST_INT) { short i = INTVAL (operands[1]); if (i <= 7 && i >= -8) { if (INTVAL (operands[1]) > 7) operands[1] = GEN_INT (i); return \"movqw %1,%0\"; } return \"movw %1,%0\"; } else if (FP_REG_P (operands[0])) { if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) < F0_REGNUM) return \"movwf %1,tos\;movf tos,%0\"; else return \"movwf %1,%0\"; } else if (FP_REG_P (operands[1])) { if (REG_P (operands[0])) return \"movf %1,tos\;movd tos,%0\"; return \"movf %1,%0\"; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -