📄 alliant.md
字号:
;;- Machine description for GNU C compiler for Alliant FX systems;; Copyright (C) 1989 Free Software Foundation, Inc.;; Adapted from m68k.md by Paul Petersen (petersen@uicsrd.csrd.uiuc.edu);; and Joe Weening (weening@gang-of-four.stanford.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 1, 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 definitions;;- @@The original PO technology requires these to be ordered by speed,;;- @@ so that assigner will pick the fastest.;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.;;- When naming insn's (operand 0 of define_insn) be careful about using;;- names from other targets machine descriptions.;;- cpp macro #define NOTICE_UPDATE_CC in file tm.h handles condition code;;- updates for most instructions.;;- Operand classes for the register allocator:;;- 'a' one of the address registers can be used.;;- 'd' one of the data registers can be used.;;- 'f' one of the CE floating point registers can be used;;- 'r' either a data or an address register can be used.;;- Immediate integer operand constraints:;;- 'I' 1 .. 8;;- 'J' -32768 .. 32767;;- 'K' -128 .. 127;;- 'L' -8 .. -1;;- Some remnants of constraint codes for the m68k ('x','y','G','H');;- may remain in the insn definitions.;;- Some of these insn's are composites of several Alliant op codes.;;- The assembler (or final @@??) insures that the appropriate one is;;- selected.;; Put tstsi first among test insns so it matches a CONST_INT operand.(define_insn "tstsi" [(set (cc0) (match_operand:SI 0 "general_operand" "rm"))] "" "*{ if (TARGET_68020 || ! ADDRESS_REG_P (operands[0])) return \"tst%.l %0\"; /* If you think that the 68020 does not support tstl a0, reread page B-167 of the 68020 manual more carefully. */ /* On an address reg, cmpw may replace cmpl. */ return \"cmp%.w %#0,%0\";}")(define_insn "tsthi" [(set (cc0) (match_operand:HI 0 "general_operand" "rm"))] "" "*{ if (TARGET_68020 || ! ADDRESS_REG_P (operands[0])) return \"tst%.w %0\"; return \"cmp%.w %#0,%0\";}")(define_insn "tstqi" [(set (cc0) (match_operand:QI 0 "general_operand" "dm"))] "" "tst%.b %0")(define_insn "tstsf" [(set (cc0) (match_operand:SF 0 "nonimmediate_operand" "fm"))] "TARGET_CE" "*{ cc_status.flags = CC_IN_FP; return \"ftest%.s %0\";}")(define_insn "tstdf" [(set (cc0) (match_operand:DF 0 "nonimmediate_operand" "fm"))] "TARGET_CE" "*{ cc_status.flags = CC_IN_FP; return \"ftest%.d %0\";}");; compare instructions.;; Put cmpsi first among compare insns so it matches two CONST_INT operands.;; A composite of the cmp, cmpa, & cmpi m68000 op codes.(define_insn "cmpsi" [(set (cc0) (compare (match_operand:SI 0 "general_operand" "rKs,mr,>") (match_operand:SI 1 "general_operand" "mr,Ksr,>")))] "" "*{ if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) return \"cmpm%.l %1,%0\"; if (REG_P (operands[1]) || (!REG_P (operands[0]) && GET_CODE (operands[0]) != MEM)) { cc_status.flags |= CC_REVERSED; return \"cmp%.l %d0,%d1\"; } return \"cmp%.l %d1,%d0\";}")(define_insn "cmphi" [(set (cc0) (compare (match_operand:HI 0 "general_operand" "rnm,d,n,m") (match_operand:HI 1 "general_operand" "d,rnm,m,n")))] "" "*{ if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) return \"cmpm%.w %1,%0\"; if ((REG_P (operands[1]) && !ADDRESS_REG_P (operands[1])) || (!REG_P (operands[0]) && GET_CODE (operands[0]) != MEM)) { cc_status.flags |= CC_REVERSED; return \"cmp%.w %d0,%d1\"; } return \"cmp%.w %d1,%d0\";}")(define_insn "cmpqi" [(set (cc0) (compare (match_operand:QI 0 "general_operand" "dn,md,>") (match_operand:QI 1 "general_operand" "dm,nd,>")))] "" "*{ if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) return \"cmpm%.b %1,%0\"; if (REG_P (operands[1]) || (!REG_P (operands[0]) && GET_CODE (operands[0]) != MEM)) { cc_status.flags |= CC_REVERSED; return \"cmp%.b %d0,%d1\"; } return \"cmp%.b %d1,%d0\";}")(define_insn "cmpdf" [(set (cc0) (compare (match_operand:DF 0 "nonimmediate_operand" "f,m") (match_operand:DF 1 "nonimmediate_operand" "fm,f")))] "TARGET_CE" "*{ cc_status.flags = CC_IN_FP; if (FP_REG_P (operands[0])) return \"fcmp%.d %1,%0\"; cc_status.flags |= CC_REVERSED; return \"fcmp%.d %0,%1\";}")(define_insn "cmpsf" [(set (cc0) (compare (match_operand:SF 0 "nonimmediate_operand" "f,m") (match_operand:SF 1 "nonimmediate_operand" "fm,f")))] "TARGET_CE" "*{ cc_status.flags = CC_IN_FP; if (FP_REG_P (operands[0])) return \"fcmp%.s %1,%0\"; cc_status.flags |= CC_REVERSED; return \"fcmp%.s %0,%1\";}");; Recognizers for btst instructions.(define_insn "" [(set (cc0) (zero_extract (match_operand:QI 0 "nonimmediate_operand" "do") (const_int 1) (minus:SI (const_int 7) (match_operand:SI 1 "general_operand" "di"))))] "" "* { return output_btst (operands, operands[1], operands[0], insn, 7); }")(define_insn "" [(set (cc0) (zero_extract (match_operand:SI 0 "nonimmediate_operand" "d") (const_int 1) (minus:SI (const_int 31) (match_operand:SI 1 "general_operand" "di"))))] "" "* { return output_btst (operands, operands[1], operands[0], insn, 31); }");; The following two patterns are like the previous two;; except that they use the fact that bit-number operands;; are automatically masked to 3 or 5 bits.(define_insn "" [(set (cc0) (zero_extract (match_operand:QI 0 "nonimmediate_operand" "do") (const_int 1) (minus:SI (const_int 7) (and:SI (match_operand:SI 1 "general_operand" "d") (const_int 7)))))] "" "* { return output_btst (operands, operands[1], operands[0], insn, 7); }")(define_insn "" [(set (cc0) (zero_extract (match_operand:SI 0 "nonimmediate_operand" "d") (const_int 1) (minus:SI (const_int 31) (and:SI (match_operand:SI 1 "general_operand" "d") (const_int 31)))))] "" "* { return output_btst (operands, operands[1], operands[0], insn, 31); }");; Nonoffsettable mem refs are ok in this one pattern;; since we don't try to adjust them.(define_insn "" [(set (cc0) (zero_extract (match_operand:QI 0 "nonimmediate_operand" "md") (const_int 1) (match_operand:SI 1 "general_operand" "i")))] "GET_CODE (operands[1]) == CONST_INT && (unsigned) INTVAL (operands[1]) < 8" "*{ operands[1] = gen_rtx (CONST_INT, VOIDmode, 7 - INTVAL (operands[1])); return output_btst (operands, operands[1], operands[0], insn, 7);}")(define_insn "" ;; The constraint "o,d" here means that a nonoffsettable memref ;; will match the first alternative, and its address will be reloaded. ;; Copying the memory contents into a reg would be incorrect if the ;; bit position is over 7. [(set (cc0) (zero_extract (match_operand:HI 0 "nonimmediate_operand" "o,d") (const_int 1) (match_operand:SI 1 "general_operand" "i,i")))] "GET_CODE (operands[1]) == CONST_INT" "*{ if (GET_CODE (operands[0]) == MEM) { operands[0] = adj_offsettable_operand (operands[0], INTVAL (operands[1]) / 8); operands[1] = gen_rtx (CONST_INT, VOIDmode, 7 - INTVAL (operands[1]) % 8); return output_btst (operands, operands[1], operands[0], insn, 7); } operands[1] = gen_rtx (CONST_INT, VOIDmode, 15 - INTVAL (operands[1])); return output_btst (operands, operands[1], operands[0], insn, 15);}")(define_insn "" [(set (cc0) (zero_extract (match_operand:SI 0 "nonimmediate_operand" "do") (const_int 1) (match_operand:SI 1 "general_operand" "i")))] "GET_CODE (operands[1]) == CONST_INT" "*{ if (GET_CODE (operands[0]) == MEM) { operands[0] = adj_offsettable_operand (operands[0], INTVAL (operands[1]) / 8); operands[1] = gen_rtx (CONST_INT, VOIDmode, 7 - INTVAL (operands[1]) % 8); return output_btst (operands, operands[1], operands[0], insn, 7); } operands[1] = gen_rtx (CONST_INT, VOIDmode, 31 - INTVAL (operands[1])); return output_btst (operands, operands[1], operands[0], insn, 31);}")(define_insn "" [(set (cc0) (subreg:SI (lshiftrt:QI (match_operand:QI 0 "nonimmediate_operand" "dm") (const_int 7)) 0))] "" "*{ cc_status.flags = CC_Z_IN_NOT_N | CC_NOT_NEGATIVE; return \"tst%.b %0\";}")(define_insn "" [(set (cc0) (and:SI (sign_extend:SI (sign_extend:HI (match_operand:QI 0 "nonimmediate_operand" "dm"))) (match_operand:SI 1 "general_operand" "i")))] "(GET_CODE (operands[1]) == CONST_INT && (unsigned) INTVAL (operands[1]) < 0x100 && exact_log2 (INTVAL (operands[1])) >= 0)" "*{ register int log = exact_log2 (INTVAL (operands[1])); operands[1] = gen_rtx (CONST_INT, VOIDmode, log); return output_btst (operands, operands[1], operands[0], insn, 7);}");; move instructions;; A special case in which it is not desirable;; to reload the constant into a data register.(define_insn "" [(set (match_operand:SI 0 "push_operand" "=m") (match_operand:SI 1 "general_operand" "J"))] "GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) >= -0x8000 && INTVAL (operands[1]) < 0x8000" "*{ if (operands[1] == const0_rtx) return \"clr%.l %0\"; return \"pea %a1\";}");This is never used.;(define_insn "swapsi"; [(set (match_operand:SI 0 "general_operand" "r"); (match_operand:SI 1 "general_operand" "r")); (set (match_dup 1) (match_dup 0))]; ""; "exg %1,%0");; Special case of fullword move when source is zero.;; The reason this is special is to avoid loading a zero;; into a data reg with moveq in order to store it elsewhere. (define_insn "" [(set (match_operand:SI 0 "general_operand" "=g") (const_int 0))] "" "*{ if (ADDRESS_REG_P (operands[0])) return \"sub%.l %0,%0\"; return \"clr%.l %0\";}");; General case of fullword move. The register constraints;; force integer constants in range for a moveq to be reloaded;; if they are headed for memory.(define_insn "movsi" ;; Notes: make sure no alternative allows g vs g. ;; We don't allow f-regs since fixed point cannot go in them. ;; We do allow y and x regs since fixed point is allowed in them. [(set (match_operand:SI 0 "general_operand" "=g,da,y,!*x*r*m") (match_operand:SI 1 "general_operand" "daymKs,i,g,*x*r*m"))] "" "*{ if (GET_CODE (operands[1]) == CONST_INT) { if (operands[1] == const0_rtx && (DATA_REG_P (operands[0]) || GET_CODE (operands[0]) == MEM)) return \"clr%.l %0\"; else if (DATA_REG_P (operands[0]) && INTVAL (operands[1]) < 128 && INTVAL (operands[1]) >= -128) return \"moveq %1,%0\"; else if (ADDRESS_REG_P (operands[0]) && INTVAL (operands[1]) < 0x8000 && INTVAL (operands[1]) >= -0x8000) return \"mov%.w %1,%0\"; else if (push_operand (operands[0], SImode) && INTVAL (operands[1]) < 0x8000 && INTVAL (operands[1]) >= -0x8000) return \"pea %a1\"; } else if ((GET_CODE (operands[1]) == SYMBOL_REF || GET_CODE (operands[1]) == CONST) && push_operand (operands[0], SImode)) return \"pea %a1\"; else if ((GET_CODE (operands[1]) == SYMBOL_REF || GET_CODE (operands[1]) == CONST) && ADDRESS_REG_P (operands[0])) return \"lea %a1,%0\"; return \"mov%.l %1,%0\";}")(define_insn "movhi" [(set (match_operand:HI 0 "general_operand" "=g") (match_operand:HI 1 "general_operand" "g"))] "" "*{ if (GET_CODE (operands[1]) == CONST_INT) { if (operands[1] == const0_rtx && (DATA_REG_P (operands[0]) || GET_CODE (operands[0]) == MEM)) return \"clr%.w %0\"; else if (DATA_REG_P (operands[0]) && INTVAL (operands[1]) < 128 && INTVAL (operands[1]) >= -128) { return \"moveq %1,%0\"; } else if (INTVAL (operands[1]) < 0x8000 && INTVAL (operands[1]) >= -0x8000) return \"mov%.w %1,%0\"; } else if (CONSTANT_P (operands[1])) return \"mov%.l %1,%0\"; /* Recognize the insn before a tablejump, one that refers to a table of offsets. Such an insn will need to refer to a label on the insn. So output one. Use the label-number of the table of offsets to generate this label. */ if (GET_CODE (operands[1]) == MEM && GET_CODE (XEXP (operands[1], 0)) == PLUS && (GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == LABEL_REF || GET_CODE (XEXP (XEXP (operands[1], 0), 1)) == LABEL_REF) && GET_CODE (XEXP (XEXP (operands[1], 0), 0)) != PLUS && GET_CODE (XEXP (XEXP (operands[1], 0), 1)) != PLUS) { rtx labelref; if (GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == LABEL_REF) labelref = XEXP (XEXP (operands[1], 0), 0); else labelref = XEXP (XEXP (operands[1], 0), 1); ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"LI\", CODE_LABEL_NUMBER (XEXP (labelref, 0))); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -