📄 stormy16.md
字号:
;; XSTORMY16 Machine description template;; Copyright (C) 1997, 1998, 1999, 2001, 2002 Free Software Foundation, Inc.;; Contributed by Red Hat, 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 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;; ::;; ::::::::::::::::::::; Categorize branches for the conditional in the length attribute.(define_attr "branch_class" "notdirectbranch,br12,bcc12,bcc8p2,bcc8p4" (const_string "notdirectbranch")); The length of an instruction, used for branch shortening.(define_attr "length" "" (cond [(eq_attr "branch_class" "br12") (if_then_else (and (ge (minus (match_dup 0) (pc)) (const_int -2046)) (lt (minus (match_dup 0) (pc)) (const_int 2048))) (const_int 2) (const_int 4)) (eq_attr "branch_class" "bcc12") (if_then_else (and (ge (minus (match_dup 0) (pc)) (const_int -2044)) (lt (minus (match_dup 0) (pc)) (const_int 2048))) (const_int 4) (const_int 8)) (eq_attr "branch_class" "bcc8p2") (if_then_else (and (ge (minus (match_dup 0) (pc)) (const_int -124)) (lt (minus (match_dup 0) (pc)) (const_int 128))) (const_int 4) (const_int 8)) (eq_attr "branch_class" "bcc8p4") (if_then_else (and (ge (minus (match_dup 0) (pc)) (const_int -122)) (lt (minus (match_dup 0) (pc)) (const_int 128))) (const_int 6) (const_int 10))] (const_int 2))); The operand which determines the setting of Rpsw.; The numbers indicate the operand number,; 'clobber' indicates it is changed in some unspecified way; 'nop' means it is not changed.(define_attr "psw_operand" "clobber,nop,0,1,2,3,4" (const_string "0"))(define_asm_attributes [(set_attr "length" "4") (set_attr "psw_operand" "clobber")]);; ::::::::::::::::::::;; ::;; :: Moves;; ::;; ::::::::::::::::::::;; push/pop qi and hi are here as separate insns rather than part of;; the movqi/hi patterns because we need to ensure that reload isn't;; passed anything it can't cope with. Without these patterns, we;; might end up with;; (set (mem (post_inc (sp))) mem (post_inc (reg)));; If, in this example, reg needs reloading, reload will read reg from;; the stack , adjust sp, and store reg back at what is now the wrong;; offset. By using separate patterns for push and pop we ensure that;; insns like this one are never generated.(define_insn "pushqi" [(set (mem:QI (post_inc (reg:HI 15))) (match_operand:QI 0 "register_operand" "r"))] "" "push %0" [(set_attr "psw_operand" "nop") (set_attr "length" "2")])(define_insn "popqi" [(set (match_operand:QI 0 "register_operand" "=r") (mem:QI (pre_dec (reg:HI 15))))] "" "pop %0" [(set_attr "psw_operand" "nop") (set_attr "length" "2")])(define_expand "movqi" [(set (match_operand:QI 0 "nonimmediate_nonstack_operand" "") (match_operand:QI 1 "general_operand" ""))] "" "{ xstormy16_expand_move (QImode, operands[0], operands[1]); DONE; }")(define_insn "*movqi_internal" [(set (match_operand:QI 0 "nonimmediate_nonstack_operand" "=r,m,e,e,T,r,S") (match_operand:QI 1 "general_operand" "r,e,m,i,i,i,i"))] "" "@ mov %0,%1 mov.b %0,%1 mov.b %0,%1 mov %0,%1 mov Rx,%1 mov %0,%1 mov.b %0,%1" [(set_attr_alternative "length" [(const_int 2) (if_then_else (match_operand:QI 0 "short_memory_operand" "") (const_int 2) (const_int 4)) (if_then_else (match_operand:QI 1 "short_memory_operand" "") (const_int 2) (const_int 4)) (const_int 2) (const_int 2) (const_int 4) (const_int 4)]) (set_attr "psw_operand" "0,0,0,0,nop,0,nop")])(define_insn "pushhi" [(set (mem:HI (post_inc (reg:HI 15))) (match_operand:HI 0 "register_operand" "r"))] "" "push %0" [(set_attr "psw_operand" "nop") (set_attr "length" "2")])(define_insn "pophi" [(set (match_operand:HI 0 "register_operand" "=r") (mem:HI (pre_dec (reg:HI 15))))] "" "pop %0" [(set_attr "psw_operand" "nop") (set_attr "length" "2")])(define_expand "movhi" [(set (match_operand:HI 0 "nonimmediate_nonstack_operand" "") (match_operand:HI 1 "general_operand" ""))] "" "{ xstormy16_expand_move (HImode, operands[0], operands[1]); DONE; }")(define_insn "*movhi_internal" [(set (match_operand:HI 0 "nonimmediate_nonstack_operand" "=r,m,e,e,T,r,S") (match_operand:HI 1 "general_operand" "r,e,m,L,L,i,i"))] "" "@ mov %0,%1 mov.w %0,%1 mov.w %0,%1 mov.w %0,%1 mov.w Rx,%1 mov.w %0,%1 mov.w %0,%1" [(set_attr_alternative "length" [(const_int 2) (if_then_else (match_operand:QI 0 "short_memory_operand" "") (const_int 2) (const_int 4)) (if_then_else (match_operand:QI 1 "short_memory_operand" "") (const_int 2) (const_int 4)) (const_int 2) (const_int 2) (const_int 4) (const_int 4)]) (set_attr "psw_operand" "0,0,0,0,nop,0,nop")])(define_expand "movsi" [(set (match_operand:SI 0 "nonimmediate_operand" "") (match_operand:SI 1 "general_operand" ""))] "" "{ xstormy16_expand_move (SImode, operands[0], operands[1]); DONE; }")(define_insn_and_split "*movsi_internal" [(set (match_operand:SI 0 "nonimmediate_operand" "=r,Q,r,m,e,&e,e,r,S") (match_operand:SI 1 "general_operand" "r,r,R,e,o, V,L,i,i"))] "" "#" "reload_completed" [(pc)] "{ xstormy16_split_move (SImode, operands[0], operands[1]); DONE; }" [(set_attr_alternative "length" [(const_int 4) (const_int 4) (const_int 4) (if_then_else (match_operand:QI 0 "short_memory_operand" "") (const_int 6) (const_int 8)) (if_then_else (match_operand:QI 1 "short_memory_operand" "") (const_int 6) (const_int 8)) (if_then_else (match_operand:QI 1 "short_memory_operand" "") (const_int 6) (const_int 8)) (const_int 4) (const_int 8) (const_int 8)])]);; ::::::::::::::::::::;; ::;; :: Conversions;; ::;; ::::::::::::::::::::(define_insn "extendqihi2" [(set (match_operand:HI 0 "register_operand" "=r") (sign_extend:HI (match_operand:QI 1 "register_operand" "0")))] "" "cbw %0")(define_insn "zero_extendqihi2" [(set (match_operand:HI 0 "register_operand" "=e,r") (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "m,0")))] "" "@ mov.b %0, %1 shl %0,#8\n\tshr %0,#8" [(set_attr "psw_operand" "nop,0") (set_attr_alternative "length" [(const_int 2) (const_int 4)])]);; ::::::::::::::::::::;; ::;; :: Bit field extraction;; ::;; ::::::::::::::::::::;; Extract an unsigned bit field;(define_insn "extzv"; [(set (match_operand:SI 0 "register_operand" "=r"); (zero_extract:SI (match_operand:SI 1 "register_operand" "r"); (match_operand:SI 2 "const_int_operand" "n"); (match_operand:SI 3 "const_int_operand" "n")))]; ""; "extzv %0,%1,%2,%3"; [(set_attr "length" "4")]);; Insert a bit field;(define_insn "insv"; [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r"); (match_operand:SI 1 "const_int_operand" "n"); (match_operand:SI 2 "const_int_operand" "n")); (match_operand:SI 3 "nonmemory_operand" "ri"))]; ""; "insv %0,%1,%2,%3"; [(set_attr "length" "4")]);; ::::::::::::::::::::;; ::;; :: 16 bit Integer arithmetic;; ::;; ::::::::::::::::::::;; Addition; Operand 3 is marked earlyclobber because that helps reload; to generate better code---this pattern will never need the; carry register as an input, and some output reloads or input; reloads might need to use it. In fact, without the '&' reload; will fail in some cases.(define_insn "addhi3" [(set (match_operand:HI 0 "register_operand" "=r,r,T,T,r,r,r") (plus:HI (match_operand:HI 1 "register_operand" "%0,0,0,0,0,0,0") (match_operand:HI 2 "nonmemory_operand" "O,P,L,M,Ir,N,i"))) (clobber (match_scratch:BI 3 "=X,X,&y,&y,&y,&y,&y"))] "" "@ inc %0,%o2 dec %0,%O2 add Rx,%2 sub Rx,#%n2 add %0,%2 sub %0,#%n2 add %0,%2" [(set_attr "length" "2,2,2,2,2,2,4")]); Reload can generate addition operations. The SECONDARY_RELOAD_CLASS; macro causes it to allocate the carry register; this pattern; shows it how to place the register in RTL to make the addition work.(define_expand "reload_inhi" [(parallel [(set (match_operand:HI 0 "register_operand" "=r") (match_operand:HI 1 "xstormy16_carry_plus_operand" "")) (clobber (match_operand:BI 2 "" "=&y"))])] "" "if (! rtx_equal_p (operands[0], XEXP (operands[1], 0))) { emit_insn (gen_rtx_SET (VOIDmode, operands[0], XEXP (operands[1], 0))); operands[1] = gen_rtx_PLUS (GET_MODE (operands[1]), operands[0], XEXP (operands[1], 1)); } ")(define_insn "addchi4" [(set (match_operand:HI 0 "register_operand" "=T,r,r") (plus:HI (match_operand:HI 1 "register_operand" "%0,0,0") (match_operand:HI 2 "nonmemory_operand" "L,Ir,i"))) (set (match_operand:BI 3 "register_operand" "=y,y,y") (truncate:BI (lshiftrt:SI (plus:SI (zero_extend:SI (match_dup 1)) (zero_extend:SI (match_dup 2))) (const_int 16))))] "" "@ add Rx,%2 add %0,%2 add %0,%2" [(set_attr "length" "2,2,4")])(define_insn "addchi5" [(set (match_operand:HI 0 "register_operand" "=T,r,r") (plus:HI (plus:HI (match_operand:HI 1 "register_operand" "%0,0,0") (zero_extend:HI (match_operand:BI 3 "register_operand" "y,y,y"))) (match_operand:HI 2 "nonmemory_operand" "L,Ir,i"))) (set (match_operand:BI 4 "register_operand" "=y,y,y") (truncate:BI (lshiftrt:SI (plus:SI (plus:SI (zero_extend:SI (match_dup 1)) (zero_extend:SI (match_dup 3))) (zero_extend:SI (match_dup 2))) (const_int 16))))] "" "@ adc Rx,%2 adc %0,%2 adc %0,%2" [(set_attr "length" "2,2,4")]);; Subtraction; Operand 3 is marked earlyclobber because that helps reload; to generate better code---this pattern will never need the; carry register as an input, and some output reloads or input; reloads might need to use it. In fact, without the '&' reload; will fail in some cases.(define_insn "subhi3" [(set (match_operand:HI 0 "register_operand" "=r,r,T,T,r,r,r")
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -