📄 m88k.md
字号:
;;- Machine description for the Motorola 88000 for GNU C compiler;; 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 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.;;- 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.;;- Operand classes for the register allocator:;; Compare instructions.;; This pattern is used for generating an "insn";; which does just a compare and sets a (fictitious) condition code.;; The actual the m88000 insns are compare-and-conditional-jump.;; The define_peephole's below recognize the combinations of;; compares and jumps, and output each pair as a single assembler insn.;; This controls RTL generation and register allocation.(define_insn "cmpsi" [(set (cc0) (compare (match_operand:SI 0 "arith_operand" "rI") (match_operand:SI 1 "arith_operand" "rI")))] "" "*{ if (GET_CODE (operands[0]) == CONST_INT) { cc_status.flags |= CC_REVERSED; return \"cmp r25,%1,%0\"; } return \"cmp r25,%0,%1\";}")(define_insn "cmpdf" [(set (cc0) (compare (match_operand:DF 0 "nonmemory_operand" "rG") (match_operand:DF 1 "nonmemory_operand" "rG")))] "" "*{ if (GET_CODE (operands[0]) == CONST_DOUBLE) { cc_status.flags |= CC_REVERSED | CC_IN_FCCR; return \"fcmp.sdd r25,%1,%0\"; } cc_status.flags |= CC_IN_FCCR; return \"fcmp.sdd r25,%0,%1\";}")(define_insn "cmpsf" [(set (cc0) (compare (match_operand:SF 0 "nonmemory_operand" "rG") (match_operand:SF 1 "nonmemory_operand" "rG")))] "" "*{ if (GET_CODE (operands[0]) == CONST_DOUBLE) { cc_status.flags |= CC_REVERSED | CC_IN_FCCR; return \"fcmp.sss r25,%1,%0\"; } cc_status.flags |= CC_IN_FCCR; return \"fcmp.sss r25,%0,%1\";}");; We have to have this because cse can optimize the previous pattern;; into this one.(define_insn "tstsi" [(set (cc0) (match_operand:SI 0 "register_operand" "r"))] "" "cmp r25,%0,0")(define_insn "tstdf" [(set (cc0) (match_operand:DF 0 "register_operand" "r"))] "" "*{ cc_status.flags |= CC_IN_FCCR; return \"fcmp.sds r25,%0,r0\";}")(define_insn "tstsf" [(set (cc0) (match_operand:SF 0 "register_operand" "r"))] "" "*{ cc_status.flags |= CC_IN_FCCR; return \"fcmp.sss r25,%0,r0\";}");; These control RTL generation for conditional jump insns;; and match them for register allocation.(define_insn "beq" [(set (pc) (if_then_else (eq (cc0) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] "" "bb1 eq,r25,%l0")(define_peephole [(set (cc0) (match_operand:SI 0 "register_operand" "r")) (set (pc) (if_then_else (eq (cc0) (const_int 0)) (label_ref (match_operand 1 "" "")) (pc)))] "" "*{ CC_STATUS_INIT; return \"bcnd eq0,%0,%l1\";}")(define_insn "bne" [(set (pc) (if_then_else (ne (cc0) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] "" "bb1 ne,r25,%l0")(define_peephole [(set (cc0) (match_operand:SI 0 "register_operand" "r")) (set (pc) (if_then_else (ne (cc0) (const_int 0)) (label_ref (match_operand 1 "" "")) (pc)))] "" "*{ CC_STATUS_INIT; return \"bcnd ne0,%0,%l1\";}")(define_insn "bgt" [(set (pc) (if_then_else (gt (cc0) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] "" "bb1 gt,r25,%l0")(define_insn "bgtu" [(set (pc) (if_then_else (gtu (cc0) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] "" "bb1 hi,r25,%l0")(define_insn "blt" [(set (pc) (if_then_else (lt (cc0) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] "" "bb1 lt,r25,%l0")(define_insn "bltu" [(set (pc) (if_then_else (ltu (cc0) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] "" "bb1 lo,r25,%l0")(define_insn "bge" [(set (pc) (if_then_else (ge (cc0) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] "" "bb1 ge,r25,%l0")(define_insn "bgeu" [(set (pc) (if_then_else (geu (cc0) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] "" "bb1 hs,r25,%l0")(define_insn "ble" [(set (pc) (if_then_else (le (cc0) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] "" "bb1 le,r25,%l0")(define_insn "bleu" [(set (pc) (if_then_else (leu (cc0) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] "" "bb1 ls,r25,%l0");; These match inverted jump insns for register allocation.(define_insn "" [(set (pc) (if_then_else (eq (cc0) (const_int 0)) (pc) (label_ref (match_operand 0 "" ""))))] "" "bb0 eq,r25,%l0")(define_peephole [(set (cc0) (match_operand:SI 0 "register_operand" "r")) (set (pc) (if_then_else (eq (cc0) (const_int 0)) (pc) (label_ref (match_operand 1 "" ""))))] "" "*{ CC_STATUS_INIT; return \"bcnd ne0,%0,%l1\";}")(define_insn "" [(set (pc) (if_then_else (ne (cc0) (const_int 0)) (pc) (label_ref (match_operand 0 "" ""))))] "" "bb0 ne,r25,%l0")(define_peephole [(set (cc0) (match_operand:SI 0 "register_operand" "r")) (set (pc) (if_then_else (ne (cc0) (const_int 0)) (pc) (label_ref (match_operand 1 "" ""))))] "" "*{ CC_STATUS_INIT; return \"bcnd eq0,%0,%l1\";}")(define_insn "" [(set (pc) (if_then_else (gt (cc0) (const_int 0)) (pc) (label_ref (match_operand 0 "" ""))))] "" "bb0 gt,r25,%l0")(define_insn "" [(set (pc) (if_then_else (gtu (cc0) (const_int 0)) (pc) (label_ref (match_operand 0 "" ""))))] "" "bb0 hi,r25,%l0")(define_insn "" [(set (pc) (if_then_else (lt (cc0) (const_int 0)) (pc) (label_ref (match_operand 0 "" ""))))] "" "bb0 lt,r25,%l0")(define_insn "" [(set (pc) (if_then_else (ltu (cc0) (const_int 0)) (pc) (label_ref (match_operand 0 "" ""))))] "" "bb0 lo,r25,%l0")(define_insn "" [(set (pc) (if_then_else (ge (cc0) (const_int 0)) (pc) (label_ref (match_operand 0 "" ""))))] "" "bb0 ge,r25,%l0")(define_insn "" [(set (pc) (if_then_else (geu (cc0) (const_int 0)) (pc) (label_ref (match_operand 0 "" ""))))] "" "bb0 hs,r25,%l0")(define_insn "" [(set (pc) (if_then_else (le (cc0) (const_int 0)) (pc) (label_ref (match_operand 0 "" ""))))] "" "bb0 le,r25,%l0")(define_insn "" [(set (pc) (if_then_else (leu (cc0) (const_int 0)) (pc) (label_ref (match_operand 0 "" ""))))] "" "bb0 ls,r25,%l0");; Move instructions(define_insn "swapsi" [(set (match_operand:SI 0 "general_operand" "g") (match_operand:SI 1 "general_operand" "g")) (set (match_dup 1) (match_dup 0))] "" "*{ if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) { CC_STATUS_INIT; return \"ld r25,%0\;xmem r25,%1\;st r25,%0\"; } if (! REG_P (operands[1])) return \"xmem %0,%1\"; if (REG_P (operands[0])) { if (REGNO (operands[0]) == REGNO (operands[1])) return \"\"; return \"xor %0,%0,%1\;xor %1,%1,%0\;xor %0,%0,%1\"; } return \"xmem %1,%0\";}")(define_peephole [(set (match_operand:SI 0 "register_operand" "=r") (match_operand:SI 1 "memory_operand" "m")) (set (match_operand:SI 2 "register_operand" "=r") (match_operand:SI 3 "memory_operand" "m")) (set (match_dup 1) (match_dup 2)) (set (match_dup 3) (match_dup 0))] "" "*{ CC_STATUS_INIT; return \"ld r25,%1\;xmem r25,%3\;st r25,%1\";}")(define_insn "swapqi" [(set (match_operand:QI 0 "general_operand" "g") (match_operand:QI 1 "general_operand" "g")) (set (match_dup 1) (match_dup 0))] "" "*{ if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) { CC_STATUS_INIT; return \"ld.bu r25,%0\;xmem.bu r25,%1\;st.bu r25,%0\"; } if (! REG_P (operands[1])) return \"xmem.bu %0,%1\"; if (REG_P (operands[0])) { if (REGNO (operands[0]) == REGNO (operands[1])) return \"\"; return \"xor %0,%0,%1\;xor %1,%1,%0\;xor %0,%0,%1\"; } return \"xmem.bu %1,%0\";}")(define_peephole [(set (match_operand:QI 0 "register_operand" "=r") (match_operand:QI 1 "memory_operand" "m")) (set (match_operand:QI 2 "register_operand" "=r") (match_operand:QI 3 "memory_operand" "m")) (set (match_dup 1) (match_dup 2)) (set (match_dup 3) (match_dup 0))] "" "*{ CC_STATUS_INIT; return \"ld.bu r25,%1\;xmem.bu r25,%3\;st.bu r25,%1\";}")(define_insn "" [(set (match_operand:SI 0 "general_operand" "g") (const_int 0))] "" "*{ if (REG_P (operands[0])) return \"or %0,r0,0\"; return \"st r0,%0\";}")(define_insn "movsi" [(set (match_operand:SI 0 "general_operand" "=g,r") (match_operand:SI 1 "general_operand" "r,mi"))] "" "*{ if (REG_P (operands[0])) { if (GET_CODE (operands[1]) == MEM) return \"ld %0,%1\"; if (GET_CODE (operands[1]) == CONST_INT) return output_store_const_int (SImode, operands); if (GET_CODE (operands[1]) == LABEL_REF || GET_CODE (operands[1]) == SYMBOL_REF) return \"lda %0,r0,%1\"; return \"or %0,r0,%1\"; } return \"st %1,%0\";}");; Simulate pre inc. Post inc/dec is automatically optimized;; by sheer luck. ?? In which phase should this really be done??(define_insn "" [(set (match_operand:SI 0 "register_operand" "r") (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r") (match_operand:SI 2 "arith_operand" "rI")))) (set (match_dup 1) (plus:SI (match_dup 1) (match_dup 2)))] "" "ld %0,%1,%2\\t;; pipelined!\;addu %1,%1,%2\\t;; /")(define_insn "" [(set (mem:SI (plus:SI (match_operand:SI 0 "register_operand" "r") (match_operand:SI 1 "arith_operand" "rI"))) (match_operand:SI 2 "register_operand" "r")) (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))] "" "st %2,%0,%1\\t;; pipelined!\;addu %0,%0,%1\\t;; /")(define_insn "" [(set (match_operand:HI 0 "general_operand" "g") (const_int 0))] "" "*{ if (REG_P (operands[0])) return \"or %0,r0,0\"; return \"st.h r0,%0\";}")(define_insn "movhi" [(set (match_operand:HI 0 "general_operand" "=g,r") (match_operand:HI 1 "general_operand" "r,mn"))] "" "*{ if (REG_P (operands[0])) { if (GET_CODE (operands[1]) == MEM) return \"ld.h %0,%1\"; if (GET_CODE (operands[1]) == CONST_INT) return output_store_const_int (HImode, operands); return \"or %0,r0,%1\"; } return \"st.h %1,%0\";}")(define_insn "" [(set (match_operand:SI 0 "register_operand" "r") (sign_extend:SI (mem:HI (plus:SI (match_operand:SI 1 "register_operand" "r") (match_operand:SI 2 "arith_operand" "rI"))))) (set (match_dup 1) (plus:SI (match_dup 1) (match_dup 2)))] "" "ld.h %0,%1,%2\\t;; pipelined!\;addu %1,%1,%2\\t;; /")(define_insn "" [(set (match_operand:SI 0 "register_operand" "r") (zero_extend:SI (mem:HI (plus:SI (match_operand:SI 1 "register_operand" "r") (match_operand:SI 2 "arith_operand" "rI"))))) (set (match_dup 1) (plus:SI (match_dup 1) (match_dup 2)))] "" "ld.hu %0,%1,%2\\t;; pipelined!\;addu %1,%1,%2\\t;; /")(define_insn "" [(set (mem:HI (plus:SI (match_operand:SI 0 "register_operand" "r") (match_operand:SI 1 "arith_operand" "rI"))) (match_operand:SI 2 "register_operand" "r")) (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))] "" "st.h %2,%0,%1\\t;; pipelined!\;addu %0,%0,%1\\t;; /")(define_insn "" [(set (match_operand:QI 0 "general_operand" "g") (const_int 0))] "" "*{ if (REG_P (operands[0])) return \"or %0,r0,0\"; return \"st.b r0,%0\";}")(define_insn "movqi" [(set (match_operand:QI 0 "general_operand" "=g,r") (match_operand:QI 1 "general_operand" "r,mn"))] "" "*{ if (REG_P (operands[0])) { if (GET_CODE (operands[1]) == MEM) return \"ld.b %0,%1\"; if (GET_CODE (operands[1]) == CONST_INT) return output_store_const_int (QImode, operands); return \"or %0,r0,%1\"; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -