📄 m88k.md
字号:
;;- Machine description for the Motorola 88000 for GNU C compiler;; Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000;; Free Software Foundation, Inc.;; Contributed by Michael Tiemann (tiemann@mcc.com);; Currently maintained by (gcc@dg-rtp.dg.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, 59 Temple Place - Suite 330,;; Boston, MA 02111-1307, USA.;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.;; Attribute describing the processor. This attribute must match exactly;; with the processor_type enumeration in m88k.h.; Target CPU.(define_attr "cpu" "m88100,m88110,m88000" (const (symbol_ref "m88k_cpu"))); Type of each instruction. Default is arithmetic.; I'd like to write the list as this, but genattrtab won't accept it.;; "branch,jump,call, ; flow-control instructions; load,store,loadd,loada, ; data unit instructions; spadd,dpadd,spcmp,dpcmp,spdiv,dpdiv,idiv, ; FPU add instructions; spmul,dpmul,imul, ; FPU multiply instructions; arith,bit,mov ; integer unit instructions; marith,weird" ; multi-word instructions; Classification of each insn. Some insns of TYPE_BRANCH are multi-word.(define_attr "type" "branch,jump,call,load,store,loadd,loada,spadd,dpadd,spcmp,dpcmp,spdiv,dpdiv,idiv,spmul,dpmul,imul,arith,bit,mov,marith,weird" (const_string "arith"))(define_attr "fpu" "yes,no" (if_then_else (eq_attr "type" "spmul,dpmul,imul,spadd,dpadd,spcmp,dpcmp,spdiv,dpdiv,idiv") (const_string "yes") (const_string "no"))); Length in # of instructions of each insn. The values are not exact, but; are safe.(define_attr "length" "" (cond [(eq_attr "type" "marith,weird,branch") (const_int 2)] (const_int 1))); Describe a user's asm statement.(define_asm_attributes [(set_attr "type" "weird")]); Define the delay slot requirements for branches and calls.; The m88100 annuls instructions if a conditional branch is taken.; For insns of TYPE_BRANCH that are multi-word instructions, the; delay slot applies to the first instruction.; @@ For the moment, reorg.c requires that the delay slot of a branch not; be a call or branch.(define_delay (eq_attr "type" "branch,jump") [(and (and (eq_attr "type" "!branch,jump,call,marith,weird") ; required. (eq_attr "type" "!load,loadd")) ; issue as-soon-as-possible. (eq_attr "fpu" "no")) ; issue as-soon-as-possible. (eq_attr "type" "!call,branch,jump") (nil)]) ; @@ was (const_int 1); output_call supports an unconditional branch in the delay slot of; a call. (@@ Support for this case is expected in reorg.c soon.)(define_delay (eq_attr "type" "call") [(eq_attr "type" "!branch,call,marith,weird") ; required. (nil) (nil)]); An abstract block diagram of the function units for the m88100.;; *; |; +---v----+; | decode |; +-vv-v-v-+ fpu; ,----------'| | `----------------------.; | | | | ,-----.; load | store | | arith | | |; | | | +-v-v-+ | dp source; | | | | fp1 |---'; store | | | div +-v-v-+; ,------. | | | ,-----. ,-----------' `-----------.; | | | | | | | | |; | +--v---v--+ ,---' | | +-v-v---+ +---v---+; | | stage 2 | | | `---| add 2 | | mul 2 |; | +---------+ | +--v--+ +-------+ imul +-------+; | | stage 1 | | | alu | | add 3 | ,--------| mul 3 |; | +---------+ | +--v--+ +-------+ | +-------+; | | stage 0 | | | | add 4 | | | mul 4 |; | +--v---v--+ | | +---v---+ | +-------+; | | | | | | | | mul 5 |; | * | | | | | +---v---+; | | | | | +----v----+ |; | load | | | fp add `------>| fp last |<------' fp mul; | | | | +---v-v--^+; | | | | | | |; | | | | | `--' dp dest; | | +--v-----v--+ |; | `--->| writeback |<--------------------'; | +--v-----v--+; | | |; `------------------' *;; The decode unit need not be specified.; Consideration of writeback contention is critical to superb scheduling.;; (define_function_unit NAME MULTIPLICITY SIMULTANEITY; TEST READY-DELAY ISSUE-DELAY [CONFLICT-LIST]); Describing the '100 alu is currently not useful.;(define_function_unit "alu" 1 0 (eq_attr "type"; "!store,marith,weird") 1 0);(define_function_unit "alu" 1 0 (eq_attr "type" "marith,weird") 2 0)(define_function_unit "alu" 1 0 (and (eq_attr "type" "loada,arith,mov") (eq_attr "cpu" "!m88100")) 2 0)(define_function_unit "alu" 1 0 (and (eq_attr "type" "marith,weird") (eq_attr "cpu" "!m88100")) 4 0)(define_function_unit "bit" 1 0 (and (eq_attr "type" "bit") (eq_attr "cpu" "!m88100")) 2 2)(define_function_unit "mem100" 1 0 (and (eq_attr "type" "store,loada") (eq_attr "cpu" "m88100")) 1 0)(define_function_unit "mem100" 1 0 (and (eq_attr "type" "load") (eq_attr "cpu" "m88100")) 3 0)(define_function_unit "mem100" 1 0 (and (eq_attr "type" "loadd") (eq_attr "cpu" "m88100")) 3 2)(define_function_unit "mem110" 1 0 (and (eq_attr "type" "load,loadd") (eq_attr "cpu" "!m88100")) 3 2)(define_function_unit "mem110" 1 0 (and (eq_attr "type" "store") (eq_attr "cpu" "!m88100")) 1 2); The times are adjusted to include fp1 and fplast, but then are further; adjusted based on the actual generated code. The notation to the right; is the total latency. A range denotes a group of instructions and/or; conditions (the extra clock of fplast time with some sequences).(define_function_unit "fpmul100" 1 0 (and (eq_attr "type" "spmul") (eq_attr "cpu" "m88100")) 4 0) ; 6-8(define_function_unit "fpmul100" 1 0 (and (eq_attr "type" "dpmul") (eq_attr "cpu" "m88100")) 7 0) ; 9-10(define_function_unit "fpmul100" 1 0 (and (eq_attr "type" "imul") (eq_attr "cpu" "m88100")) 3 0) ; 4(define_function_unit "fpmul110" 1 0 (and (eq_attr "type" "imul,spmul,dpmul") (eq_attr "cpu" "!m88100")) 5 2) ; 3(define_function_unit "fpadd100" 1 5 (and (eq_attr "type" "spadd,spcmp") (eq_attr "cpu" "m88100")) 3 0) ; 5-6(define_function_unit "fpadd100" 1 5 (and (eq_attr "type" "dpadd,dpcmp") (eq_attr "cpu" "m88100")) 4 0) ; 6-7(define_function_unit "fpadd110" 1 0 (and (eq_attr "type" "spadd,dpadd") (eq_attr "cpu" "!m88100")) 5 2) ; 3(define_function_unit "fpadd110" 1 0 (and (eq_attr "type" "spcmp,dpcmp") (eq_attr "cpu" "!m88100")) 2 2) ; 1(define_function_unit "fpadd100" 1 5 (and (eq_attr "type" "spdiv") (eq_attr "cpu" "m88100")) 30 0) ; 30-31(define_function_unit "fpadd100" 1 5 (and (eq_attr "type" "dpdiv") (eq_attr "cpu" "m88100")) 60 0) ; 60-61(define_function_unit "fpadd100" 1 5 (and (eq_attr "type" "idiv") (eq_attr "cpu" "m88100")) 38 0) ; 38(define_function_unit "div" 1 1 (and (eq_attr "type" "spdiv") (eq_attr "cpu" "!m88100")) 25 2) ; 13(define_function_unit "div" 1 1 (and (eq_attr "type" "dpdiv") (eq_attr "cpu" "!m88100")) 45 2) ; 23(define_function_unit "div" 1 1 (and (eq_attr "type" "idiv") (eq_attr "cpu" "!m88100")) 35 2) ; 18;; Superoptimizer sequences;; geu+: { r = ((unsigned_word) v0 >= (unsigned_word) v1) + v2; };; subu.co r5,r2,r3;; addu.cio r6,r4,r0(define_split [(set (match_operand:SI 0 "register_operand" "=r") (minus:SI (match_operand:SI 1 "register_operand" "r") (geu:SI (match_operand:SI 2 "register_operand" "r") (match_operand:SI 3 "register_operand" "r"))))] "" [(set (reg:CC 0) (unspec:CC [(match_dup 2) (match_dup 3)] 1)) (set (match_dup 0) (plus:SI (match_dup 1) (unspec:SI [(const_int 0) (reg:CC 0)] 0)))] "");; leu+: { r = ((unsigned_word) v0 <= (unsigned_word) v1) + v2; };; subu.co r5,r3,r2;; addu.cio r6,r4,r0(define_split [(set (match_operand:SI 0 "register_operand" "=r") (minus:SI (match_operand:SI 1 "register_operand" "r") (leu:SI (match_operand:SI 3 "register_operand" "r") (match_operand:SI 2 "register_operand" "r"))))] "" [(set (reg:CC 0) (unspec:CC [(match_dup 2) (match_dup 3)] 1)) (set (match_dup 0) (plus:SI (match_dup 1) (unspec:SI [(const_int 0) (reg:CC 0)] 0)))] "");; eq0+: { r = (v0 == 0) + v1; };; subu.co r4,r0,r2;; addu.cio r5,r3,r0(define_split [(set (match_operand:SI 0 "register_operand" "=r") (minus:SI (match_operand:SI 1 "register_operand" "r") (eq:SI (match_operand:SI 2 "register_operand" "r") (const_int 0))))] "" [(set (reg:CC 0) (unspec:CC [(const_int 0) (match_dup 2)] 1)) (set (match_dup 0) (plus:SI (match_dup 1) (unspec:SI [(const_int 0) (reg:CC 0)] 0)))] "");; ltu-: { r = v2 - ((unsigned_word) v0 < (unsigned_word) v1); };; subu.co r5,r2,r3;; subu.cio r6,r4,r0(define_split [(set (match_operand:SI 0 "register_operand" "=r") (plus:SI (ltu:SI (match_operand:SI 2 "register_operand" "r") (match_operand:SI 3 "register_operand" "r")) (match_operand:SI 1 "register_operand" "r")))] "" [(set (reg:CC 0) (unspec:CC [(match_dup 2) (match_dup 3)] 1)) (set (match_dup 0) (minus:SI (match_dup 1) (unspec:SI [(const_int 0) (reg:CC 0)] 1)))] "");; gtu-: { r = v2 - ((unsigned_word) v0 > (unsigned_word) v1); };; subu.co r5,r3,r2;; subu.cio r6,r4,r0(define_split [(set (match_operand:SI 0 "register_operand" "=r") (plus:SI (gtu:SI (match_operand:SI 3 "register_operand" "r") (match_operand:SI 2 "register_operand" "r")) (match_operand:SI 1 "register_operand" "r")))] "" [(set (reg:CC 0) (unspec:CC [(match_dup 2) (match_dup 3)] 1)) (set (match_dup 0) (minus:SI (match_dup 1) (unspec:SI [(const_int 0) (reg:CC 0)] 1)))] "");; ne0-: { r = v1 - (v0 != 0); };; subu.co r4,r0,r2;; subu.cio r5,r3,r0(define_split [(set (match_operand:SI 0 "register_operand" "=r") (plus:SI (ne:SI (match_operand:SI 2 "register_operand" "r") (const_int 0)) (match_operand:SI 1 "register_operand" "r")))] "" [(set (reg:CC 0) (unspec:CC [(const_int 0) (match_dup 2)] 1)) (set (match_dup 0) (minus:SI (match_dup 1) (unspec:SI [(const_int 0) (reg:CC 0)] 1)))] "");; ges0-: { r = v1 - ((signed_word) v0 >= 0); };; addu.co r4,r2,r2;; subu.cio r5,r3,r0(define_split [(set (match_operand:SI 0 "register_operand" "=r") (minus:SI (match_operand:SI 1 "register_operand" "r") (xor:SI (lshiftrt:SI (match_operand:SI 2 "register_operand" "r") (const_int 31)) (const_int 1))))] "" [(set (reg:CC 0) (unspec:CC [(match_dup 2) (match_dup 2)] 0)) (set (match_dup 0) (minus:SI (match_dup 1) (unspec:SI [(const_int 0) (reg:CC 0)] 1)))] "");; This rich set of complex patterns are mostly due to Torbjorn Granlund;; (tege@sics.se). They've changed since then, so don't complain to him;; if they don't work right.;; Regarding shifts, gen_lshlsi3 generates ASHIFT. The gen functions;; produce the necessary insns to support TARGET_*_LARGE_SHIFT, so nothing;; special needs to be done here.;; Optimize possible cases of the set instruction.(define_insn "" [(set (match_operand:SI 0 "register_operand" "=r") (ashift:SI (const_int -1) (match_operand:SI 1 "register_operand" "r")))] "" "set %0,%#r0,%1" [(set_attr "type" "bit")])(define_insn "" [(set (match_operand:SI 0 "register_operand" "=r") (ior:SI (ashift:SI (const_int -1) (match_operand:SI 1 "register_operand" "r")) (match_operand:SI 2 "register_operand" "r")))] "" "set %0,%2,%1" [(set_attr "type" "bit")])(define_insn "" [(set (match_operand:SI 0 "register_operand" "=r") (ior:SI (match_operand:SI 1 "register_operand" "r") (ashift:SI (const_int -1) (match_operand:SI 2 "register_operand" "r"))))] "" "set %0,%1,%2" [(set_attr "type" "bit")]);; Optimize possible cases of the mak instruction.(define_insn "" [(set (match_operand:SI 0 "register_operand" "=r") (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "r") (match_operand:SI 2 "int5_operand" "")) (match_operand:SI 3 "immediate_operand" "n")))] "mak_mask_p (INTVAL (operands[3]) >> INTVAL (operands[2]))" "*{ operands[4] = GEN_INT (exact_log2 (1 + (INTVAL (operands[3]) >> INTVAL(operands[2])))); return \"mak %0,%1,%4<%2>\";}" [(set_attr "type" "bit")]);; Optimize possible cases of output_and.(define_insn "" [(set (match_operand:SI 0 "register_operand" "=r") (ashift:SI (zero_extract:SI (match_operand:SI 1 "register_operand" "r") (match_operand:SI 2 "int5_operand" "") (match_operand:SI 3 "int5_operand" "")) (match_operand:SI 4 "int5_operand" "")))] "INTVAL (operands[2]) + INTVAL (operands[3]) + INTVAL (operands[4]) == 32" "*{ operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1) << INTVAL (operands[4])); return output_and (operands);}" [(set_attr "type" "marith")]) ; arith,bit,marith. length is 1 or 2.;; Improve logical operations on compare words;;;; We define all logical operations on CCmode values to preserve the pairwise;; relationship of the compare bits. This allows a future branch prediction;; pass the degree of freedom needed to change and/bb0-le into or/bb1-gt.;; THIS IS CURRENTLY FALSE! ;;;; Opportunities arise when conditional expressions using && and || are made;; unconditional. When these are used to branch, the sequence is;; cmp/cmp/extu/extu/{and,or}/bcnd-{eq0,ne0}. When these are used to create;; a value, the sequence is cmp/cmp/extu/extu/{and,or} for 1 or 0 or;; cmp/cmp/ext/ext/{and,or} for -1 or 0.;;;; When the extracted conditions are the same, the define_split patterns;; below change extu/extu/{and,or} into {and,or}/extu. If the reversed;; conditions match, one compare word can be complemented, resulting in;; {and.c,or.c}/extu. These changes are done for ext/ext/{and,or} as well.;; If the conditions don't line up, one can be rotated. To keep the pairwise;; relationship, it may be necessary to both rotate and complement. Rotating;; makes branching cheaper, but doesn't help (or hurt) creating a value, so;; we don't do this for ext/ext/{and,or}.;;;; These changes result in the sequence extu/bcnd-{eq0,ne0} which is combined;; into an alternate form of bb0 and bb1.(define_split [(set (match_operand:SI 0 "register_operand" "=r") (ior:SI (neg:SI (match_operator 1 "even_relop" [(match_operand 2 "partial_ccmode_register_operand" "%r") (const_int 0)])) (neg:SI (match_operator 3 "relop" [(match_operand 4 "partial_ccmode_register_operand" "r") (const_int 0)])))) (clobber (match_operand:SI 5 "register_operand" "=r"))] "" [(set (match_dup 5) (ior:CCEVEN (match_dup 4) (match_dup 2))) (set (match_dup 0) (neg:SI (match_op_dup 1 [(match_dup 5) (const_int 0)])))]
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -