📄 spur.md
字号:
;;- Machine description for SPUR chip for GNU C compiler;; Copyright (C) 1988 Free Software Foundation, Inc.;; 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 SPUR 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.;; Put cmpsi first among compare insns so it matches two CONST_INT operands.;; This controls RTL generation and register allocation.(define_insn "cmpsi" [(set (cc0) (compare (match_operand:SI 0 "nonmemory_operand" "rK") (match_operand:SI 1 "nonmemory_operand" "rK")))] "" "*{ cc_status.value1 = operands[0], cc_status.value2 = operands[1]; return \"\";}");; Put tstsi first among test insns so it matches a CONST_INT operand.;; 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"))] "" "*{ cc_status.value1 = operands[0], cc_status.value2 = const0_rtx; return \"\";}");; 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)))] "" "* return output_compare (operands, \"eq\", \"eq\", \"ne\", \"ne\"); ")(define_insn "bne" [(set (pc) (if_then_else (ne (cc0) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] "" "* return output_compare (operands, \"ne\", \"ne\", \"eq\", \"eq\"); ")(define_insn "bgt" [(set (pc) (if_then_else (gt (cc0) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] "" "* return output_compare (operands, \"gt\", \"lt\", \"le\", \"ge\"); ")(define_insn "bgtu" [(set (pc) (if_then_else (gtu (cc0) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] "" "* return output_compare (operands, \"ugt\", \"ult\", \"ule\", \"uge\"); ")(define_insn "blt" [(set (pc) (if_then_else (lt (cc0) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] "" "* return output_compare (operands, \"lt\", \"gt\", \"ge\", \"le\"); ")(define_insn "bltu" [(set (pc) (if_then_else (ltu (cc0) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] "" "* return output_compare (operands, \"ult\", \"ugt\", \"uge\", \"ule\"); ")(define_insn "bge" [(set (pc) (if_then_else (ge (cc0) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] "" "* return output_compare (operands, \"ge\", \"le\", \"lt\", \"gt\"); ")(define_insn "bgeu" [(set (pc) (if_then_else (geu (cc0) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] "" "* return output_compare (operands, \"uge\", \"ule\", \"ult\", \"ugt\"); ")(define_insn "ble" [(set (pc) (if_then_else (le (cc0) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] "" "* return output_compare (operands, \"le\", \"ge\", \"gt\", \"lt\"); ")(define_insn "bleu" [(set (pc) (if_then_else (leu (cc0) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] "" "* return output_compare (operands, \"ule\", \"uge\", \"ugt\", \"ult\"); ");; 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 "" ""))))] "" "* return output_compare (operands, \"ne\", \"ne\", \"eq\", \"eq\"); ")(define_insn "" [(set (pc) (if_then_else (ne (cc0) (const_int 0)) (pc) (label_ref (match_operand 0 "" ""))))] "" "* return output_compare (operands, \"eq\", \"eq\", \"ne\", \"ne\"); ")(define_insn "" [(set (pc) (if_then_else (gt (cc0) (const_int 0)) (pc) (label_ref (match_operand 0 "" ""))))] "" "* return output_compare (operands, \"le\", \"ge\", \"gt\", \"lt\"); ")(define_insn "" [(set (pc) (if_then_else (gtu (cc0) (const_int 0)) (pc) (label_ref (match_operand 0 "" ""))))] "" "* return output_compare (operands, \"ule\", \"uge\", \"ugt\", \"ult\"); ")(define_insn "" [(set (pc) (if_then_else (lt (cc0) (const_int 0)) (pc) (label_ref (match_operand 0 "" ""))))] "" "* return output_compare (operands, \"ge\", \"le\", \"lt\", \"gt\"); ")(define_insn "" [(set (pc) (if_then_else (ltu (cc0) (const_int 0)) (pc) (label_ref (match_operand 0 "" ""))))] "" "* return output_compare (operands, \"uge\", \"ule\", \"ult\", \"ugt\"); ")(define_insn "" [(set (pc) (if_then_else (ge (cc0) (const_int 0)) (pc) (label_ref (match_operand 0 "" ""))))] "" "* return output_compare (operands, \"lt\", \"gt\", \"ge\", \"le\"); ")(define_insn "" [(set (pc) (if_then_else (geu (cc0) (const_int 0)) (pc) (label_ref (match_operand 0 "" ""))))] "" "* return output_compare (operands, \"ult\", \"ugt\", \"uge\", \"ule\"); ")(define_insn "" [(set (pc) (if_then_else (le (cc0) (const_int 0)) (pc) (label_ref (match_operand 0 "" ""))))] "" "* return output_compare (operands, \"gt\", \"lt\", \"le\", \"ge\"); ")(define_insn "" [(set (pc) (if_then_else (leu (cc0) (const_int 0)) (pc) (label_ref (match_operand 0 "" ""))))] "" "* return output_compare (operands, \"ugt\", \"ult\", \"ule\", \"uge\"); ");; Move instructions(define_insn "movsi" [(set (match_operand:SI 0 "general_operand" "=r,m") (match_operand:SI 1 "general_operand" "rmi,rJ"))] "" "*{ if (GET_CODE (operands[0]) == MEM) return \"st_32 %r1,%0\"; if (GET_CODE (operands[1]) == MEM) return \"ld_32 %0,%1\;nop\"; if (GET_CODE (operands[1]) == REG) return \"add_nt %0,%1,$0\"; if (GET_CODE (operands[1]) == SYMBOL_REF && operands[1]->unchanging) return \"add_nt %0,r24,$(%1-0b)\"; return \"add_nt %0,r0,%1\";}")(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 "register_operand" "r"))))] "" "ld_32 %0,%1,%2\;nop");; Generate insns for moving single bytes.(define_expand "movqi" [(set (match_operand:QI 0 "general_operand" "") (match_operand:QI 1 "general_operand" ""))] "" "{ if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) operands[1] = copy_to_reg (operands[1]); if (GET_CODE (operands[1]) == MEM) { rtx tem = gen_reg_rtx (SImode); rtx addr = force_reg (SImode, XEXP (operands[1], 0)); rtx subreg; emit_move_insn (tem, gen_rtx (MEM, SImode, addr)); if (GET_CODE (operands[0]) == SUBREG) subreg = gen_rtx (SUBREG, SImode, SUBREG_REG (operands[0]), SUBREG_WORD (operands[0])); else subreg = gen_rtx (SUBREG, SImode, operands[0], 0); emit_insn (gen_rtx (SET, VOIDmode, subreg, gen_rtx (ZERO_EXTRACT, SImode, tem, gen_rtx (CONST_INT, VOIDmode, 8), addr))); } else if (GET_CODE (operands[0]) == MEM) { rtx tem = gen_reg_rtx (SImode); rtx addr = force_reg (SImode, XEXP (operands[0], 0)); rtx subreg; emit_move_insn (tem, gen_rtx (MEM, SImode, addr)); if (! CONSTANT_ADDRESS_P (operands[1])) { if (GET_CODE (operands[1]) == SUBREG) subreg = gen_rtx (SUBREG, SImode, SUBREG_REG (operands[1]), SUBREG_WORD (operands[1])); else subreg = gen_rtx (SUBREG, SImode, operands[1], 0); } emit_insn (gen_rtx (SET, VOIDmode, gen_rtx (ZERO_EXTRACT, SImode, tem, gen_rtx (CONST_INT, VOIDmode, 8), addr), subreg)); emit_move_insn (gen_rtx (MEM, SImode, addr), tem); } else { emit_insn (gen_rtx (SET, VOIDmode, operands[0], operands[1])); } DONE;}");; Recognize insns generated for moving single bytes.(define_insn "" [(set (match_operand:QI 0 "general_operand" "=r,m") (match_operand:QI 1 "general_operand" "rmi,r"))] "" "*{ if (GET_CODE (operands[0]) == MEM) return \"st_32 %1,%0\"; if (GET_CODE (operands[1]) == MEM) return \"ld_32 %0,%1\;nop\"; if (GET_CODE (operands[1]) == REG) return \"add_nt %0,%1,$0\"; return \"add_nt %0,r0,%1\";}")(define_insn "" [(set (match_operand:SI 0 "register_operand" "=r") (zero_extract:SI (match_operand:SI 1 "register_operand" "r") (const_int 8) (match_operand:SI 2 "nonmemory_operand" "rI")))] "" "extract %0,%1,%2")(define_insn "" [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r") (const_int 8) (match_operand:SI 1 "nonmemory_operand" "rI")) (match_operand:SI 2 "nonmemory_operand" "ri"))] "" "wr_insert %1\;insert %0,%0,%2");; Constant propagation can optimize the previous pattern into this pattern.;[Not any more. It could when the position-operand contains a MULT.];(define_insn ""; [(set (zero_extract:QI (match_operand:SI 0 "register_operand" "+r"); (const_int 8)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -