📄 ns32k.md
字号:
; 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??;;- Machine description for GNU compiler;;- ns32000 Version;; Copyright (C) 1988 Free Software Foundation, Inc.;; Contributed by Michael Tiemann (tiemann@mcc.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, 675 Mass Ave, Cambridge, MA 02139, USA.;;- 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.(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" "fmF"))] "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\"; }")(define_insn "cmpsi" [(set (cc0) (compare (match_operand:SI 0 "nonimmediate_operand" "rmn") (match_operand:SI 1 "general_operand" "rmn")))] "" "*{ 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 "nonimmediate_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_rtx(CONST_INT, VOIDmode, 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_rtx(CONST_INT, VOIDmode, i); return \"cmpqw %0,%1\"; } } return \"cmpw %0,%1\";}")(define_insn "cmpqi" [(set (cc0) (compare (match_operand:QI 0 "nonimmediate_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_rtx(CONST_INT, VOIDmode, 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_rtx(CONST_INT, VOIDmode, i); return \"cmpqb %0,%1\"; } } return \"cmpb %0,%1\";}")(define_insn "cmpdf" [(set (cc0) (compare (match_operand:DF 0 "general_operand" "fmF") (match_operand:DF 1 "general_operand" "fmF")))] "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")(define_insn "movdf" [(set (match_operand:DF 0 "general_operand" "=&fg<") (match_operand:DF 1 "general_operand" "fFg"))] "" "*{ 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]) < 8) 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 to this? */ operands[1] = gen_rtx (CONST_INT, VOIDmode, 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 17) (match_operand:SI 0 "general_operand" "rmn"))] "" "lprd sp,%0")(define_insn "movsi" [(set (match_operand:SI 0 "general_operand" "=g<,g<,*f,g") (match_operand:SI 1 "general_operand" "g,?xy,g,*f"))] "" "*{ if (FP_REG_P (operands[0])) { if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) < 8) 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[1]) == CONST_INT) { int i = INTVAL (operands[1]); if (i <= 7 && i >= -8) return \"movqd %1,%0\"; if (i < 0x4000 && i >= -0x4000 && ! TARGET_32532)#if defined (GNX_V3) || defined (UTEK_ASM) return \"addr %c1,%0\";#else return \"addr @%c1,%0\";#endif return \"movd %1,%0\"; } else if (GET_CODE (operands[1]) == REG) { if (REGNO (operands[1]) < 16) 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_rtx (CONST_INT, VOIDmode, 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_rtx (CONST_INT, VOIDmode, 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]) < 8) 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\"; } else return \"movw %1,%0\";}")(define_insn "movstricthi" [(set (strict_low_part (match_operand:HI 0 "general_operand" "+r")) (match_operand:HI 1 "general_operand" "g"))] "" "*{ if (GET_CODE (operands[1]) == CONST_INT && INTVAL(operands[1]) <= 7 && INTVAL(operands[1]) >= -8) return \"movqw %1,%0\"; return \"movw %1,%0\";}")(define_insn "movqi" [(set (match_operand:QI 0 "general_operand" "=g<,*f,g") (match_operand:QI 1 "general_operand" "g,g,*f"))] "" "*{ if (GET_CODE (operands[1]) == CONST_INT) { char char_val = (char)INTVAL (operands[1]); if (char_val <= 7 && char_val >= -8) { if (INTVAL (operands[1]) > 7) operands[1] = gen_rtx (CONST_INT, VOIDmode, char_val); return \"movqb %1,%0\"; } return \"movb %1,%0\"; } else if (FP_REG_P (operands[0])) { if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) < 8) return \"movbf %1,tos\;movf tos,%0\"; else return \"movbf %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\"; } else return \"movb %1,%0\";}")(define_insn "movstrictqi" [(set (strict_low_part (match_operand:QI 0 "general_operand" "+r")) (match_operand:QI 1 "general_operand" "g"))] "" "*{ if (GET_CODE (operands[1]) == CONST_INT && INTVAL(operands[1]) < 8 && INTVAL(operands[1]) > -9) return \"movqb %1,%0\"; return \"movb %1,%0\";}");; This is here to accept 4 arguments and pass the first 3 along;; to the movstrsi1 pattern that really does the work.(define_expand "movstrsi" [(set (match_operand:BLK 0 "general_operand" "=g") (match_operand:BLK 1 "general_operand" "g")) (use (match_operand:SI 2 "general_operand" "rmn")) (match_operand 3 "" "")] "" " emit_insn (gen_movstrsi1 (operands[0], operands[1], operands[2])); DONE;");; The definition of this insn does not really explain what it does,;; but it should suffice;; that anything generated as this insn will be recognized as one
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -