📄 mcore.md
字号:
;; Machine description the Motorola MCore;; Copyright (C) 1993, 1999, 2000 Free Software Foundation, Inc.;; Contributed by Motorola.;; 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.;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.;; -------------------------------------------------------------------------;; Attributes;; -------------------------------------------------------------------------; Target CPU.(define_attr "type" "brcond,branch,jmp,load,store,move,alu,shift" (const_string "alu"));; If a branch destination is within -2048..2047 bytes away from the;; instruction it can be 2 bytes long. All other conditional branches;; are 10 bytes long, and all other unconditional branches are 8 bytes.;;;; the assembler handles the long-branch span case for us if we use;; the "jb*" mnemonics for jumps/branches. This pushes the span;; calculations and the literal table placement into the assembler,;; where their interactions can be managed in a single place.; All MCORE instructions are two bytes long.(define_attr "length" "" (const_int 2));; (define_function_unit {name} {num-units} {n-users} {test};; {ready-delay} {issue-delay} [{conflict-list}]) (define_function_unit "memory" 1 1 (eq_attr "type" "load") 2 0);; -------------------------------------------------------------------------;; Test and bit test;; -------------------------------------------------------------------------(define_insn "" [(set (reg:SI 17) (sign_extract:SI (match_operand:SI 0 "mcore_arith_reg_operand" "r") (const_int 1) (match_operand:SI 1 "mcore_literal_K_operand" "K")))] "" "btsti %0,%1" [(set_attr "type" "shift")])(define_insn "" [(set (reg:SI 17) (zero_extract:SI (match_operand:SI 0 "mcore_arith_reg_operand" "r") (const_int 1) (match_operand:SI 1 "mcore_literal_K_operand" "K")))] "" "btsti %0,%1" [(set_attr "type" "shift")]);;; This is created by combine.(define_insn "" [(set (reg:CC 17) (ne:CC (zero_extract:SI (match_operand:SI 0 "mcore_arith_reg_operand" "r") (const_int 1) (match_operand:SI 1 "mcore_literal_K_operand" "K")) (const_int 0)))] "" "btsti %0,%1" [(set_attr "type" "shift")]);; Created by combine from conditional patterns below (see sextb/btsti rx,31)(define_insn "" [(set (reg:CC 17) (ne:CC (lshiftrt:SI (match_operand:SI 0 "mcore_arith_reg_operand" "r") (const_int 7)) (const_int 0)))] "GET_CODE(operands[0]) == SUBREG && GET_MODE(SUBREG_REG(operands[0])) == QImode" "btsti %0,7" [(set_attr "type" "shift")])(define_insn "" [(set (reg:CC 17) (ne:CC (lshiftrt:SI (match_operand:SI 0 "mcore_arith_reg_operand" "r") (const_int 15)) (const_int 0)))] "GET_CODE(operands[0]) == SUBREG && GET_MODE(SUBREG_REG(operands[0])) == HImode" "btsti %0,15" [(set_attr "type" "shift")])(define_split [(set (pc) (if_then_else (ne (eq:CC (zero_extract:SI (match_operand:SI 0 "mcore_arith_reg_operand" "") (const_int 1) (match_operand:SI 1 "mcore_literal_K_operand" "")) (const_int 0)) (const_int 0)) (label_ref (match_operand 2 "" "")) (pc)))] "" [(set (reg:CC 17) (zero_extract:SI (match_dup 0) (const_int 1) (match_dup 1))) (set (pc) (if_then_else (eq (reg:CC 17) (const_int 0)) (label_ref (match_dup 2)) (pc)))] "")(define_split [(set (pc) (if_then_else (eq (ne:CC (zero_extract:SI (match_operand:SI 0 "mcore_arith_reg_operand" "") (const_int 1) (match_operand:SI 1 "mcore_literal_K_operand" "")) (const_int 0)) (const_int 0)) (label_ref (match_operand 2 "" "")) (pc)))] "" [(set (reg:CC 17) (zero_extract:SI (match_dup 0) (const_int 1) (match_dup 1))) (set (pc) (if_then_else (eq (reg:CC 17) (const_int 0)) (label_ref (match_dup 2)) (pc)))] "");; XXX - disabled by nickc because it fails on libiberty/fnmatch.c;;;; ; Experimental - relax immediates for and, andn, or, and tst to allow;; ; any immediate value (or an immediate at all -- or, andn, & tst). ;; ; This is done to allow bit field masks to fold together in combine.;; ; The reload phase will force the immediate into a register at the;; ; very end. This helps in some cases, but hurts in others: we'd;; ; really like to cse these immediates. However, there is a phase;; ; ordering problem here. cse picks up individual masks and cse's;; ; those, but not folded masks (cse happens before combine). It's;; ; not clear what the best solution is because we really want cse;; ; before combine (leaving the bit field masks alone). To pick up;; ; relaxed immediates use -mrelax-immediates. It might take some;; ; experimenting to see which does better (i.e. regular imms vs.;; ; arbitrary imms) for a particular code. BRC;; ;; (define_insn "";; [(set (reg:CC 17);; (ne:CC (and:SI (match_operand:SI 0 "mcore_arith_reg_operand" "r");; (match_operand:SI 1 "mcore_arith_any_imm_operand" "rI"));; (const_int 0)))];; "TARGET_RELAX_IMM";; "tst %0,%1");; ;; (define_insn "";; [(set (reg:CC 17);; (ne:CC (and:SI (match_operand:SI 0 "mcore_arith_reg_operand" "r");; (match_operand:SI 1 "mcore_arith_M_operand" "r"));; (const_int 0)))];; "!TARGET_RELAX_IMM";; "tst %0,%1")(define_insn "" [(set (reg:CC 17) (ne:CC (and:SI (match_operand:SI 0 "mcore_arith_reg_operand" "r") (match_operand:SI 1 "mcore_arith_M_operand" "r")) (const_int 0)))] "" "tst %0,%1")(define_split [(parallel[ (set (reg:CC 17) (ne:CC (ne:SI (leu:CC (match_operand:SI 0 "mcore_arith_reg_operand" "r") (match_operand:SI 1 "mcore_arith_reg_operand" "r")) (const_int 0)) (const_int 0))) (clobber (match_operand:CC 2 "mcore_arith_reg_operand" "=r"))])] "" [(set (reg:CC 17) (ne:SI (match_dup 0) (const_int 0))) (set (reg:CC 17) (leu:CC (match_dup 0) (match_dup 1)))]);; -------------------------------------------------------------------------;; SImode signed integer comparisons;; -------------------------------------------------------------------------(define_insn "decne_t" [(set (reg:CC 17) (ne:CC (plus:SI (match_operand:SI 0 "mcore_arith_reg_operand" "+r") (const_int -1)) (const_int 0))) (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))] "" "decne %0");; The combiner seems to prefer the following to the former.;;(define_insn "" [(set (reg:CC 17) (ne:CC (match_operand:SI 0 "mcore_arith_reg_operand" "+r") (const_int 1))) (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))] "" "decne %0")(define_insn "cmpnesi_t" [(set (reg:CC 17) (ne:CC (match_operand:SI 0 "mcore_arith_reg_operand" "r") (match_operand:SI 1 "mcore_arith_reg_operand" "r")))] "" "cmpne %0,%1")(define_insn "cmpneisi_t" [(set (reg:CC 17) (ne:CC (match_operand:SI 0 "mcore_arith_reg_operand" "r") (match_operand:SI 1 "mcore_arith_K_operand" "K")))] "" "cmpnei %0,%1")(define_insn "cmpgtsi_t" [(set (reg:CC 17) (gt:CC (match_operand:SI 0 "mcore_arith_reg_operand" "r") (match_operand:SI 1 "mcore_arith_reg_operand" "r")))] "" "cmplt %1,%0")(define_insn "" [(set (reg:CC 17) (gt:CC (plus:SI (match_operand:SI 0 "mcore_arith_reg_operand" "+r") (const_int -1)) (const_int 0))) (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))] "" "decgt %0")(define_insn "cmpltsi_t" [(set (reg:CC 17) (lt:CC (match_operand:SI 0 "mcore_arith_reg_operand" "r") (match_operand:SI 1 "mcore_arith_reg_operand" "r")))] "" "cmplt %0,%1"); cmplti is 1-32(define_insn "cmpltisi_t" [(set (reg:CC 17) (lt:CC (match_operand:SI 0 "mcore_arith_reg_operand" "r") (match_operand:SI 1 "mcore_arith_J_operand" "J")))] "" "cmplti %0,%1"); covers cmplti x,0(define_insn "" [(set (reg:CC 17) (lt:CC (match_operand:SI 0 "mcore_arith_reg_operand" "r") (const_int 0)))] "" "btsti %0,31")(define_insn "" [(set (reg:CC 17) (lt:CC (plus:SI (match_operand:SI 0 "mcore_arith_reg_operand" "+r") (const_int -1)) (const_int 0))) (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))] "" "declt %0");; -------------------------------------------------------------------------;; SImode unsigned integer comparisons;; -------------------------------------------------------------------------(define_insn "cmpgeusi_t" [(set (reg:CC 17) (geu:CC (match_operand:SI 0 "mcore_arith_reg_operand" "r") (match_operand:SI 1 "mcore_arith_reg_operand" "r")))] "" "cmphs %0,%1")(define_insn "cmpgeusi_0" [(set (reg:CC 17) (geu:CC (match_operand:SI 0 "mcore_arith_reg_operand" "r") (const_int 0)))] "" "cmpnei %0, 0")(define_insn "cmpleusi_t" [(set (reg:CC 17) (leu:CC (match_operand:SI 0 "mcore_arith_reg_operand" "r") (match_operand:SI 1 "mcore_arith_reg_operand" "r")))] "" "cmphs %1,%0");; We save the compare operands in the cmpxx patterns and use them when;; we generate the branch.;; We accept constants here, in case we can modify them to ones which;; are more efficient to load. E.g. change 'x <= 62' to 'x < 63'.(define_expand "cmpsi" [(set (reg:CC 17) (compare:CC (match_operand:SI 0 "mcore_compare_operand" "") (match_operand:SI 1 "nonmemory_operand" "")))] "" "{ arch_compare_op0 = operands[0]; arch_compare_op1 = operands[1]; DONE;}");; -------------------------------------------------------------------------;; Logical operations;; -------------------------------------------------------------------------;; Logical AND clearing a single bit. andsi3 knows that we have this;; pattern and allows the constant literal pass through.;;;; RBE 2/97: don't need this pattern any longer...;; RBE: I don't think we need both "S" and exact_log2() clauses.;;(define_insn "";; [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r");; (and:SI (match_operand:SI 1 "mcore_arith_reg_operand" "%0");; (match_operand:SI 2 "const_int_operand" "S")))];; "mcore_arith_S_operand (operands[2])";; "bclri %0,%Q2");;(define_insn "andnsi3" [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r") (and:SI (not:SI (match_operand:SI 1 "mcore_arith_reg_operand" "r")) (match_operand:SI 2 "mcore_arith_reg_operand" "0")))] "" "andn %0,%1")(define_expand "andsi3" [(set (match_operand:SI 0 "mcore_arith_reg_operand" "") (and:SI (match_operand:SI 1 "mcore_arith_reg_operand" "") (match_operand:SI 2 "nonmemory_operand" "")))] "" "{ if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0 && ! mcore_arith_S_operand (operands[2])) { int not_value = ~ INTVAL (operands[2]); if ( CONST_OK_FOR_I (not_value) || CONST_OK_FOR_M (not_value) || CONST_OK_FOR_N (not_value)) { operands[2] = copy_to_mode_reg (SImode, GEN_INT (not_value)); emit_insn (gen_andnsi3 (operands[0], operands[2], operands[1])); DONE; } } if (! mcore_arith_K_S_operand (operands[2], SImode)) operands[2] = copy_to_mode_reg (SImode, operands[2]);}")(define_insn "" [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r,r,r,r") (and:SI (match_operand:SI 1 "mcore_arith_reg_operand" "0,0,r,0") (match_operand:SI 2 "mcore_arith_any_imm_operand" "r,K,0,S")))] "TARGET_RELAX_IMM" "*{ switch (which_alternative) { case 0: return \"and %0,%2\"; case 1: return \"andi %0,%2\"; case 2: return \"and %0,%1\"; /* case -1: return \"bclri %0,%Q2\"; will not happen */ case 3: return mcore_output_bclri (operands[0], INTVAL (operands[2])); default: abort (); }}");; This was the old "S" which was "!(2^n)" */;; case -1: return \"bclri %0,%Q2\"; will not happen */(define_insn "" [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r,r,r,r") (and:SI (match_operand:SI 1 "mcore_arith_reg_operand" "0,0,r,0") (match_operand:SI 2 "mcore_arith_K_S_operand" "r,K,0,S")))] "!TARGET_RELAX_IMM" "*{ switch (which_alternative) { case 0: return \"and %0,%2\"; case 1: return \"andi %0,%2\"; case 2: return \"and %0,%1\"; case 3: return mcore_output_bclri (operands[0], INTVAL (operands[2])); default: abort (); }}");(define_insn "iorsi3"; [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r"); (ior:SI (match_operand:SI 1 "mcore_arith_reg_operand" "%0"); (match_operand:SI 2 "mcore_arith_reg_operand" "r")))]; ""; "or %0,%2"); need an expand to resolve ambiguity betw. the two iors below.(define_expand "iorsi3" [(set (match_operand:SI 0 "mcore_arith_reg_operand" "") (ior:SI (match_operand:SI 1 "mcore_arith_reg_operand" "") (match_operand:SI 2 "nonmemory_operand" "")))] "" "{ if (! mcore_arith_M_operand (operands[2], SImode)) operands[2] = copy_to_mode_reg (SImode, operands[2]);}")(define_insn "" [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r,r,r") (ior:SI (match_operand:SI 1 "mcore_arith_reg_operand" "%0,0,0") (match_operand:SI 2 "mcore_arith_any_imm_operand" "r,M,T")))] "TARGET_RELAX_IMM"
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -