config.gcc: Add m32c-elf support.
* config.gcc: Add m32c-elf support. * doc/contrib.texi: Mention m32c. * doc/extend.texi: Document m32c extensions. * doc/install.texi: Mention m32c. * doc/invoke.texi: Document m32c options. * doc/md.texi: Document m32c constraints. * config/m32c/addsub.md: New file. * config/m32c/bitops.md: New file. * config/m32c/cond.md: New file. * config/m32c/jump.md: New file. * config/m32c/m32c-lib1.S: New file. * config/m32c/m32c-lib2.c: New file. * config/m32c/m32c-modes.def: New file. * config/m32c/m32c-pragma.c: New file. * config/m32c/m32c-protos.h: New file. * config/m32c/m32c.abi: New file. * config/m32c/m32c.c: New file. * config/m32c/m32c.h: New file. * config/m32c/m32c.md: New file. * config/m32c/m32c.opt: New file. * config/m32c/minmax.md: New file. * config/m32c/mov.md: New file. * config/m32c/muldiv.md: New file. * config/m32c/predicates.md: New file. * config/m32c/prologue.md: New file. * config/m32c/shift.md: New file. * config/m32c/t-m32c: New file. From-SVN: r102207
This commit is contained in:
parent
50b69666aa
commit
38b2d07632
@ -1,3 +1,35 @@
|
||||
2005-07-20 DJ Delorie <dj@redhat.com>
|
||||
|
||||
* config.gcc: Add m32c-elf support.
|
||||
|
||||
* doc/contrib.texi: Mention m32c.
|
||||
* doc/extend.texi: Document m32c extensions.
|
||||
* doc/install.texi: Mention m32c.
|
||||
* doc/invoke.texi: Document m32c options.
|
||||
* doc/md.texi: Document m32c constraints.
|
||||
|
||||
* config/m32c/addsub.md: New file.
|
||||
* config/m32c/bitops.md: New file.
|
||||
* config/m32c/cond.md: New file.
|
||||
* config/m32c/jump.md: New file.
|
||||
* config/m32c/m32c-lib1.S: New file.
|
||||
* config/m32c/m32c-lib2.c: New file.
|
||||
* config/m32c/m32c-modes.def: New file.
|
||||
* config/m32c/m32c-pragma.c: New file.
|
||||
* config/m32c/m32c-protos.h: New file.
|
||||
* config/m32c/m32c.abi: New file.
|
||||
* config/m32c/m32c.c: New file.
|
||||
* config/m32c/m32c.h: New file.
|
||||
* config/m32c/m32c.md: New file.
|
||||
* config/m32c/m32c.opt: New file.
|
||||
* config/m32c/minmax.md: New file.
|
||||
* config/m32c/mov.md: New file.
|
||||
* config/m32c/muldiv.md: New file.
|
||||
* config/m32c/predicates.md: New file.
|
||||
* config/m32c/prologue.md: New file.
|
||||
* config/m32c/shift.md: New file.
|
||||
* config/m32c/t-m32c: New file.
|
||||
|
||||
2005-07-20 Kaz Kojima <kkojima@gcc.gnu.org>
|
||||
|
||||
* config/sh/sh.md (UNSPEC_SP_SET, UNSPEC_SP_TEST): New constants.
|
||||
|
@ -231,6 +231,10 @@ tm_p_file=
|
||||
cpu_type=`echo ${target} | sed 's/-.*$//'`
|
||||
cpu_is_64bit=
|
||||
case ${target} in
|
||||
m32c*-*-*)
|
||||
cpu_type=m32c
|
||||
tmake_file=m32c/t-m32c
|
||||
;;
|
||||
alpha*-*-*)
|
||||
cpu_type=alpha
|
||||
need_64bit_hwint=yes
|
||||
@ -2255,6 +2259,12 @@ am33_2.0-*-linux*)
|
||||
extra_parts="crtbegin.o crtend.o crtbeginS.o crtendS.o"
|
||||
use_collect2=no
|
||||
;;
|
||||
m32c-*-elf*)
|
||||
tm_file="dbxelf.h elfos.h svr4.h ${tm_file}"
|
||||
c_target_objs="m32c-pragma.o"
|
||||
cxx_target_objs="m32c-pragma.o"
|
||||
use_fixproto=yes
|
||||
;;
|
||||
*)
|
||||
echo "*** Configuration ${target} not supported" 1>&2
|
||||
exit 1
|
||||
|
178
gcc/config/m32c/addsub.md
Normal file
178
gcc/config/m32c/addsub.md
Normal file
@ -0,0 +1,178 @@
|
||||
;; Machine Descriptions for R8C/M16C/M32C
|
||||
;; Copyright (C) 2005
|
||||
;; Free Software Foundation, Inc.
|
||||
;; Contributed by Red Hat.
|
||||
;;
|
||||
;; This file is part of GCC.
|
||||
;;
|
||||
;; GCC 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.
|
||||
;;
|
||||
;; GCC 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 GCC; see the file COPYING. If not, write to the Free
|
||||
;; Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
;; 02110-1301, USA.
|
||||
|
||||
;; add, sub
|
||||
|
||||
(define_insn "addqi3"
|
||||
[(set (match_operand:QI 0 "mra_or_sp_operand"
|
||||
"=SdRhl,SdRhl,??Rmm,??Rmm, Raa,Raa,SdRhl,??Rmm")
|
||||
(plus:QI (match_operand:QI 1 "mra_operand"
|
||||
"%0,0,0,0, 0,0,0,0")
|
||||
(match_operand:QI 2 "mrai_operand"
|
||||
"iSdRhl,?Rmm,iSdRhl,?Rmm, iSdRhl,?Rmm,Raa,Raa")))]
|
||||
""
|
||||
"add.b\t%2,%0"
|
||||
[(set_attr "flags" "oszc")]
|
||||
)
|
||||
|
||||
(define_insn "addhi3"
|
||||
[(set (match_operand:HI 0 "nonimmediate_operand"
|
||||
"=SdRhi,SdRhi,??Rmm,??Rmm, SdRhi,??Rmm, Rhi, !Rsp")
|
||||
(plus:HI (match_operand:HI 1 "general_operand"
|
||||
"%0,0,0,0, 0,0, Raw, 0")
|
||||
(match_operand:HI 2 "general_operand"
|
||||
"IU2sSdRhi,?Rmm,IU2sSdRhi,?Rmm, IM2,IM2, IS2IU2, i")))]
|
||||
""
|
||||
"@
|
||||
add.w\t%2,%0
|
||||
add.w\t%2,%0
|
||||
add.w\t%2,%0
|
||||
add.w\t%2,%0
|
||||
sub.w\t%m2,%0
|
||||
sub.w\t%m2,%0
|
||||
mova\t%d2[%1],%0
|
||||
add.w\t%2,%0"
|
||||
[(set_attr "flags" "oszc,oszc,oszc,oszc,oszc,oszc,oszc,oszc")]
|
||||
)
|
||||
|
||||
(define_insn "addpsi3"
|
||||
[(set (match_operand:PSI 0 "nonimmediate_operand" "=SdRpi,SdRpi,Rsp*Rmm, Rpi,Rpi,Rhi,&Rhi")
|
||||
(plus:PSI (match_operand:PSI 1 "nonimmediate_operand" "0,0,0, Raa,Rad,!Rcl,Rhi")
|
||||
(match_operand:PSI 2 "general_operand" "iSdRpi,?Rmm,i, i,IS2,i,!Rcl")))]
|
||||
"TARGET_A24"
|
||||
"@
|
||||
add.%&\t%2,%0
|
||||
add.%&\t%2,%0
|
||||
add.%&\t%2,%0
|
||||
mova\t%d2[%1],%0
|
||||
mova\t%D2[%1],%0
|
||||
#
|
||||
#"
|
||||
[(set_attr "flags" "oszc,oszc,oszc,*,*,oszc,oszc")]
|
||||
)
|
||||
|
||||
; This is needed for reloading large frames.
|
||||
(define_split
|
||||
[(set (match_operand:PSI 0 "ra_operand" "")
|
||||
(plus:PSI (match_operand:PSI 1 "cr_operand" "")
|
||||
(match_operand:PSI 2 "immediate_operand" "")))]
|
||||
""
|
||||
[(set (match_dup 0) (match_dup 1))
|
||||
(set (match_dup 0)
|
||||
(plus:PSI (match_dup 0)
|
||||
(match_dup 2)))]
|
||||
""
|
||||
)
|
||||
|
||||
; This is needed for reloading large frames.
|
||||
(define_split
|
||||
[(set (match_operand:PSI 0 "ra_operand" "")
|
||||
(plus:PSI (match_operand:PSI 1 "ra_operand" "")
|
||||
(match_operand:PSI 2 "cr_operand" "")))]
|
||||
""
|
||||
[(set (match_dup 0) (match_dup 2))
|
||||
(set (match_dup 0)
|
||||
(plus:PSI (match_dup 0)
|
||||
(match_dup 1)))]
|
||||
""
|
||||
)
|
||||
|
||||
(define_insn "subqi3"
|
||||
[(set (match_operand:QI 0 "mra_or_sp_operand"
|
||||
"=SdRhl,SdRhl,??Rmm,??Rmm, Raa,Raa,SdRhl,??Rmm, *Rsp")
|
||||
(minus:QI (match_operand:QI 1 "mra_operand"
|
||||
"0,0,0,0, 0,0,0,0, 0")
|
||||
(match_operand:QI 2 "mrai_operand"
|
||||
"iSdRhl,?Rmm,iSdRhl,?Rmm, iSdRhl,?Rmm,Raa,Raa, i")))]
|
||||
""
|
||||
"sub.b\t%2,%0"
|
||||
[(set_attr "flags" "oszc")]
|
||||
)
|
||||
|
||||
(define_insn "subhi3"
|
||||
[(set (match_operand:HI 0 "mra_operand"
|
||||
"=SdRhi,SdRhi,??Rmm,??Rmm, SdRhi,??Rmm")
|
||||
(minus:HI (match_operand:HI 1 "mras_operand"
|
||||
"0,0,0,0, 0,0")
|
||||
(match_operand:HI 2 "mrai_operand"
|
||||
"IU2SdRhi,?Rmm,IU2SdRhi,?Rmm, IM2,IM2")))]
|
||||
""
|
||||
"@
|
||||
sub.w\t%2,%0
|
||||
sub.w\t%2,%0
|
||||
sub.w\t%2,%0
|
||||
sub.w\t%2,%0
|
||||
add.w\t%m2,%0
|
||||
add.w\t%m2,%0"
|
||||
[(set_attr "flags" "oszc,oszc,oszc,oszc,oszc,oszc")]
|
||||
)
|
||||
|
||||
(define_insn "subpsi3"
|
||||
[(set (match_operand:PSI 0 "mra_operand" "=RpiSd,RpiSd,??Rmm,??Rmm")
|
||||
(minus:PSI (match_operand:PSI 1 "mra_operand" "0,0,0,0")
|
||||
(match_operand:PSI 2 "mrai_operand" "iRpiSd,?Rmm,iRpiSd,?Rmm")))]
|
||||
"TARGET_A24"
|
||||
"sub.%&\t%2,%0"
|
||||
[(set_attr "flags" "oszc")]
|
||||
)
|
||||
|
||||
(define_insn "negqi2"
|
||||
[(set (match_operand:QI 0 "mra_operand" "=SdRhl,??Rmm")
|
||||
(neg:QI (match_operand:QI 1 "mra_operand" "0,0")))]
|
||||
""
|
||||
"neg.b\t%0"
|
||||
[(set_attr "flags" "oszc,oszc")]
|
||||
)
|
||||
|
||||
(define_insn "neghi2"
|
||||
[(set (match_operand:HI 0 "mra_operand" "=SdRhi,??Rmm")
|
||||
(neg:HI (match_operand:HI 1 "mra_operand" "0,0")))]
|
||||
""
|
||||
"neg.w\t%0"
|
||||
[(set_attr "flags" "oszc,oszc")]
|
||||
)
|
||||
|
||||
; We can negate an SImode by operating on the subparts. GCC deals
|
||||
; with this itself for larger modes, but not SI.
|
||||
(define_insn "negsi2"
|
||||
[(set (match_operand:SI 0 "mra_operand" "=SdR03,??Rmm")
|
||||
(neg:SI (match_operand:SI 1 "mra_operand" "0,0")))]
|
||||
""
|
||||
"not.w %h0 | not.w %H0 | add.w #1,%h0 | adcf.w %H0"
|
||||
[(set_attr "flags" "oszc,oszc")]
|
||||
)
|
||||
|
||||
(define_insn "absqi2"
|
||||
[(set (match_operand:QI 0 "mra_operand" "=RhlSd,??Rmm")
|
||||
(abs:QI (match_operand:QI 1 "mra_operand" "0,0")))]
|
||||
""
|
||||
"abs.b\t%0"
|
||||
[(set_attr "flags" "oszc")]
|
||||
)
|
||||
|
||||
(define_insn "abshi2"
|
||||
[(set (match_operand:HI 0 "mra_operand" "=RhiSd,??Rmm")
|
||||
(abs:HI (match_operand:HI 1 "mra_operand" "0,0")))]
|
||||
""
|
||||
"abs.w\t%0"
|
||||
[(set_attr "flags" "oszc")]
|
||||
)
|
93
gcc/config/m32c/bitops.md
Normal file
93
gcc/config/m32c/bitops.md
Normal file
@ -0,0 +1,93 @@
|
||||
;; Machine Descriptions for R8C/M16C/M32C
|
||||
;; Copyright (C) 2005
|
||||
;; Free Software Foundation, Inc.
|
||||
;; Contributed by Red Hat.
|
||||
;;
|
||||
;; This file is part of GCC.
|
||||
;;
|
||||
;; GCC 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.
|
||||
;;
|
||||
;; GCC 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 GCC; see the file COPYING. If not, write to the Free
|
||||
;; Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
;; 02110-1301, USA.
|
||||
|
||||
;; Bit-wise operations (and, ior, xor, shift)
|
||||
|
||||
(define_insn "andqi3"
|
||||
[(set (match_operand:QI 0 "mra_operand" "=RhlSd,RhlSd,??Rmm,??Rmm")
|
||||
(and:QI (match_operand:QI 1 "mra_operand" "%0,0,0,0")
|
||||
(match_operand:QI 2 "mrai_operand" "iRhlSd,?Rmm,iRhlSd,?Rmm")))]
|
||||
""
|
||||
"and.b\t%x2,%0"
|
||||
[(set_attr "flags" "sz,sz,sz,sz")]
|
||||
)
|
||||
|
||||
(define_insn "andhi3"
|
||||
[(set (match_operand:HI 0 "mra_operand" "=RhiSd,??Rmm,RhiSd,??Rmm")
|
||||
(and:HI (match_operand:HI 1 "mra_operand" "%0,0,0,0")
|
||||
(match_operand:HI 2 "mrai_operand" "iRhiSd,?Rmm,?Rmm,iRhiSd")))]
|
||||
""
|
||||
"and.w\t%X2,%0"
|
||||
[(set_attr "flags" "sz,sz,sz,sz")]
|
||||
)
|
||||
|
||||
(define_insn "iorqi3"
|
||||
[(set (match_operand:QI 0 "mra_operand" "=RqiSd,??Rmm,RqiSd,??Rmm")
|
||||
(ior:QI (match_operand:QI 1 "mra_operand" "%0,0,0,0")
|
||||
(match_operand:QI 2 "mrai_operand" "iRhlSd,iRhlSd,?Rmm,?Rmm")))]
|
||||
""
|
||||
"or.b\t%x2,%0"
|
||||
[(set_attr "flags" "sz,sz,sz,sz")]
|
||||
)
|
||||
|
||||
(define_insn "iorhi3"
|
||||
[(set (match_operand:HI 0 "mra_operand" "=RhiSd,RhiSd,??Rmm,??Rmm")
|
||||
(ior:HI (match_operand:HI 1 "mra_operand" "%0,0,0,0")
|
||||
(match_operand:HI 2 "mrai_operand" "iRhiSd,?Rmm,iRhiSd,?Rmm")))]
|
||||
""
|
||||
"or.w\t%X2,%0"
|
||||
[(set_attr "flags" "sz,sz,sz,sz")]
|
||||
)
|
||||
|
||||
(define_insn "xorqi3"
|
||||
[(set (match_operand:QI 0 "mra_operand" "=RhlSd,RhlSd,??Rmm,??Rmm")
|
||||
(xor:QI (match_operand:QI 1 "mra_operand" "%0,0,0,0")
|
||||
(match_operand:QI 2 "mrai_operand" "iRhlSd,?Rmm,iRhlSd,?Rmm")))]
|
||||
""
|
||||
"xor.b\t%x2,%0"
|
||||
[(set_attr "flags" "sz,sz,sz,sz")]
|
||||
)
|
||||
|
||||
(define_insn "xorhi3"
|
||||
[(set (match_operand:HI 0 "mra_operand" "=RhiSd,RhiSd,??Rmm,??Rmm")
|
||||
(xor:HI (match_operand:HI 1 "mra_operand" "%0,0,0,0")
|
||||
(match_operand:HI 2 "mrai_operand" "iRhiSd,?Rmm,iRhiSd,?Rmm")))]
|
||||
""
|
||||
"xor.w\t%X2,%0"
|
||||
[(set_attr "flags" "sz,sz,sz,sz")]
|
||||
)
|
||||
|
||||
(define_insn "one_cmplqi2"
|
||||
[(set (match_operand:QI 0 "mra_operand" "=RhlSd,??Rmm")
|
||||
(not:QI (match_operand:QI 1 "mra_operand" "0,0")))]
|
||||
""
|
||||
"not.b\t%0"
|
||||
[(set_attr "flags" "sz,sz")]
|
||||
)
|
||||
|
||||
(define_insn "one_cmplhi2"
|
||||
[(set (match_operand:HI 0 "mra_operand" "=RhiSd,??Rmm")
|
||||
(not:HI (match_operand:HI 1 "mra_operand" "0,0")))]
|
||||
""
|
||||
"not.w\t%0"
|
||||
[(set_attr "flags" "sz,sz")]
|
||||
)
|
72
gcc/config/m32c/cond.md
Normal file
72
gcc/config/m32c/cond.md
Normal file
@ -0,0 +1,72 @@
|
||||
;; Machine Descriptions for R8C/M16C/M32C
|
||||
;; Copyright (C) 2005
|
||||
;; Free Software Foundation, Inc.
|
||||
;; Contributed by Red Hat.
|
||||
;;
|
||||
;; This file is part of GCC.
|
||||
;;
|
||||
;; GCC 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.
|
||||
;;
|
||||
;; GCC 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 GCC; see the file COPYING. If not, write to the Free
|
||||
;; Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
;; 02110-1301, USA.
|
||||
|
||||
; conditionals - cmp, jcc, setcc, etc.
|
||||
|
||||
; Until support for relaxing is supported in gas, we must assume that
|
||||
; short labels won't reach, so we must use long labels.
|
||||
; Unfortunately, there aren't any conditional jumps with long labels,
|
||||
; so instead we invert the conditional and jump around a regular jump.
|
||||
|
||||
; Note that we can, at some point in the future, add code to omit the
|
||||
; "cmp" portion of the insn if the preceeding insn happened to set the
|
||||
; right flags already. For example, a mov followed by a "cmp *,0" is
|
||||
; redundant; the move already set the Z flag.
|
||||
|
||||
(define_insn "cbranchqi4"
|
||||
[(set (pc) (if_then_else
|
||||
(match_operator 0 "m32c_cmp_operator"
|
||||
[(match_operand:QI 1 "mrai_operand" "RqiSd,RqiSd,?Rmm,?Rmm")
|
||||
(match_operand:QI 2 "mrai_operand" "iRqiSd,?Rmm,iRqiSd,?Rmm")])
|
||||
(label_ref (match_operand 3 "" ""))
|
||||
(pc)))]
|
||||
""
|
||||
"cmp.b\t%2,%1\n\tj%C0\t1f\n\tjmp.a\t%l3\n1:"
|
||||
; "cmp.b\t%2,%1\n\tj%c0\t%l3"
|
||||
[(set_attr "flags" "oszc,oszc,oszc,oszc")]
|
||||
)
|
||||
|
||||
(define_insn "cbranchhi4"
|
||||
[(set (pc) (if_then_else
|
||||
(match_operator 0 "m32c_cmp_operator"
|
||||
[(match_operand:HI 1 "mrai_operand" "Rhi,?Sd,Rhi,?Sd,?Rmm,?Rmm")
|
||||
(match_operand:HI 2 "mrai_operand" "iRhiSd,iRhiSd,?Rmm,?Rmm,iRhiSd,?Rmm")])
|
||||
(label_ref (match_operand 3 "" ""))
|
||||
(pc)))]
|
||||
""
|
||||
"cmp.w\t%2,%1\n\tj%C0\t1f\n\tjmp.a\t%l3\n1:"
|
||||
; "cmp.w\t%2,%1\n\tj%c0\t%l3"
|
||||
[(set_attr "flags" "oszc,oszc,oszc,oszc,oszc,oszc")]
|
||||
)
|
||||
|
||||
(define_insn "cbranchpsi4"
|
||||
[(set (pc) (if_then_else
|
||||
(match_operator 0 "m32c_cmp_operator"
|
||||
[(match_operand:PSI 1 "mrai_operand" "RsiSd,RsiSd,?Rmm,?Rmm")
|
||||
(match_operand:PSI 2 "mrai_operand" "iRsiSd,?Rmm,iRsiSd,?Rmm")])
|
||||
(label_ref (match_operand 3 "" ""))
|
||||
(pc)))]
|
||||
"TARGET_A24"
|
||||
"cmp.l\t%2,%1\n\tj%C0\t1f\n\tjmp.a\t%l3\n1:"
|
||||
; "cmp.l\t%2,%1\n\tj%c0\t%l3"
|
||||
[(set_attr "flags" "oszc,oszc,oszc,oszc")]
|
||||
)
|
87
gcc/config/m32c/jump.md
Normal file
87
gcc/config/m32c/jump.md
Normal file
@ -0,0 +1,87 @@
|
||||
;; Machine Descriptions for R8C/M16C/M32C
|
||||
;; Copyright (C) 2005
|
||||
;; Free Software Foundation, Inc.
|
||||
;; Contributed by Red Hat.
|
||||
;;
|
||||
;; This file is part of GCC.
|
||||
;;
|
||||
;; GCC 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.
|
||||
;;
|
||||
;; GCC 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 GCC; see the file COPYING. If not, write to the Free
|
||||
;; Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
;; 02110-1301, USA.
|
||||
|
||||
;; jump, conditionals, calls, etc
|
||||
|
||||
(define_insn "indirect_jump_16"
|
||||
[(set (pc)
|
||||
(match_operand:HI 0 "register_operand" "Rhi"))]
|
||||
"TARGET_A16"
|
||||
; "jmpi.a\t%0"
|
||||
; no 16 bit jmpi in r8c
|
||||
"push.b #0 | push.w\t%0 | rts"
|
||||
)
|
||||
|
||||
(define_insn "indirect_jump_24"
|
||||
[(set (pc)
|
||||
(match_operand:PSI 0 "register_operand" "Rpi"))]
|
||||
"TARGET_A24"
|
||||
"jmpi.a\t%0"
|
||||
)
|
||||
|
||||
(define_expand "indirect_jump"
|
||||
[(match_operand 0 "register_operand" "")]
|
||||
""
|
||||
"if (TARGET_A16)
|
||||
emit_jump_insn (gen_indirect_jump_16(operands[0]));
|
||||
else
|
||||
emit_jump_insn (gen_indirect_jump_24(operands[0]));
|
||||
DONE;"
|
||||
)
|
||||
|
||||
; We can replace this with jmp.s when gas supports relaxing. m32c
|
||||
; opcodes are too complicated to try to compute their sizes here, it's
|
||||
; far easier (and more reliable) to let gas worry about it.
|
||||
(define_insn "jump"
|
||||
[(set (pc)
|
||||
(label_ref (match_operand 0 "" "")))]
|
||||
""
|
||||
"jmp.a\t%l0"
|
||||
)
|
||||
|
||||
; No 16 bit indirect calls on r8c/m16c. */
|
||||
(define_insn "call"
|
||||
[(call (match_operand:QI 0 "memory_operand" "Si,SaSb,?Rmm")
|
||||
(match_operand 1 "" ""))
|
||||
(use (match_operand 2 "immediate_operand" ""))]
|
||||
""
|
||||
"*
|
||||
switch (which_alternative) {
|
||||
case 0: return \"jsr.a\t%0\";
|
||||
case 1: return TARGET_A16 ? \"push.w %a0 | jsr.a\tm32c_jsri16\" : \"jsri.a\t%a0\";
|
||||
case 2: return \"jsri.a\t%a0\";
|
||||
}"
|
||||
)
|
||||
|
||||
(define_insn "call_value"
|
||||
[(set (match_operand 0 "m32c_return_operand" "=RdiRmmRpa,RdiRmmRpa,RdiRmmRpa")
|
||||
(call (match_operand:QI 1 "memory_operand" "Si,SaSb,?Rmm")
|
||||
(match_operand 2 "" "")))
|
||||
(use (match_operand 3 "immediate_operand" ""))]
|
||||
""
|
||||
"*
|
||||
switch (which_alternative) {
|
||||
case 0: return \"jsr.a\t%1\";
|
||||
case 1: return TARGET_A16 ? \"push.w %a1 | jsr.a\tm32c_jsri16\" : \"jsri.a\t%a1\";
|
||||
case 2: return \"jsri.a\t%a1\";
|
||||
}"
|
||||
)
|
227
gcc/config/m32c/m32c-lib1.S
Normal file
227
gcc/config/m32c/m32c-lib1.S
Normal file
@ -0,0 +1,227 @@
|
||||
/* libgcc routines for R8C/M16C/M32C
|
||||
Copyright (C) 2005
|
||||
Free Software Foundation, Inc.
|
||||
Contributed by Red Hat.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC 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.
|
||||
|
||||
In addition to the permissions in the GNU General Public License,
|
||||
the Free Software Foundation gives you unlimited permission to link
|
||||
the compiled version of this file into combinations with other
|
||||
programs, and to distribute those combinations without any
|
||||
restriction coming from the use of this file. (The General Public
|
||||
License restrictions do apply in other respects; for example, they
|
||||
cover modification of the file, and distribution when not linked
|
||||
into a combine executable.)
|
||||
|
||||
GCC 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 GCC; see the file COPYING. If not, write to the Free
|
||||
Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301, USA. */
|
||||
|
||||
#if defined(__r8c_cpu__) || defined(__m16c_cpu__)
|
||||
#define A16
|
||||
#define A(n,w) n
|
||||
#define W w
|
||||
#else
|
||||
#define A24
|
||||
#define A(n,w) w
|
||||
#define W l
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef L__m32c_memregs
|
||||
|
||||
/* Warning: these memory locations are used as a register bank. They
|
||||
*must* end up consecutive in any final executable, so you may *not*
|
||||
use the otherwise obvious ".comm" directive to allocate space for
|
||||
them. */
|
||||
|
||||
.bss
|
||||
.global mem0
|
||||
mem0: .space 1
|
||||
.global mem1
|
||||
mem1: .space 1
|
||||
.global mem2
|
||||
mem2: .space 1
|
||||
.global mem3
|
||||
mem3: .space 1
|
||||
.global mem4
|
||||
mem4: .space 1
|
||||
.global mem5
|
||||
mem5: .space 1
|
||||
.global mem6
|
||||
mem6: .space 1
|
||||
.global mem7
|
||||
mem7: .space 1
|
||||
.global mem8
|
||||
mem8: .space 1
|
||||
.global mem9
|
||||
mem9: .space 1
|
||||
.global mem10
|
||||
mem10: .space 1
|
||||
.global mem11
|
||||
mem11: .space 1
|
||||
.global mem12
|
||||
mem12: .space 1
|
||||
.global mem13
|
||||
mem13: .space 1
|
||||
.global mem14
|
||||
mem14: .space 1
|
||||
.global mem15
|
||||
mem15: .space 1
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef L__m32c_eh_return
|
||||
.text
|
||||
.global __m32c_eh_return
|
||||
__m32c_eh_return:
|
||||
|
||||
/* At this point, r0 has the stack adjustment, r1r3 has the
|
||||
address to return to. The stack looks like this:
|
||||
|
||||
old_ra
|
||||
old_fp
|
||||
<- unwound sp
|
||||
...
|
||||
fb
|
||||
through
|
||||
r0
|
||||
<- sp
|
||||
|
||||
What we need to do is restore all the registers, update the
|
||||
stack, and return to the right place.
|
||||
*/
|
||||
|
||||
stc sp,a0
|
||||
|
||||
add.W A(#16,#24),a0
|
||||
/* a0 points to the current stack, just above the register
|
||||
save areas */
|
||||
|
||||
mov.w a0,a1
|
||||
exts.w r0
|
||||
sub.W A(r0,r0r2),a1
|
||||
sub.W A(#3,#4),a1
|
||||
/* a1 points to the new stack. */
|
||||
|
||||
/* This is for the "rts" below. */
|
||||
mov.w r1,[a1]
|
||||
#ifdef A16
|
||||
mov.w r2,r1
|
||||
mov.b r1l,2[a1]
|
||||
#else
|
||||
mov.w r2,2[a1]
|
||||
#endif
|
||||
|
||||
/* This is for the "popc sp" below. */
|
||||
mov.W a1,[a0]
|
||||
|
||||
popm r0,r1,r2,r3,a0,a1,sb,fb
|
||||
popc sp
|
||||
rts
|
||||
#endif
|
||||
|
||||
/* SImode arguments for SI foo(SI,SI) functions. */
|
||||
#ifdef A16
|
||||
#define SAL 5[fb]
|
||||
#define SAH 7[fb]
|
||||
#define SBL 9[fb]
|
||||
#define SBH 11[fb]
|
||||
#else
|
||||
#define SAL 8[fb]
|
||||
#define SAH 10[fb]
|
||||
#define SBL 12[fb]
|
||||
#define SBH 14[fb]
|
||||
#endif
|
||||
|
||||
#ifdef L__m32c_mulsi3
|
||||
.text
|
||||
.global ___mulsi3
|
||||
___mulsi3:
|
||||
enter #0
|
||||
push.w r2
|
||||
mov.w SAL,mem0
|
||||
mov.w SAH,mem2
|
||||
mulu.w SBL,mem0 /* writes to r2r0 */
|
||||
mov.w SAL,r0
|
||||
mulu.w SBH,r0 /* writes to r2r0 */
|
||||
add.w r0,mem2
|
||||
mov.w SAH,r0
|
||||
mulu.w SBL,r0
|
||||
add.w r0,mem2
|
||||
pop.w r2
|
||||
exitd
|
||||
#endif
|
||||
|
||||
#ifdef L__m32c_cmpsi2
|
||||
.text
|
||||
.global ___cmpsi2
|
||||
___cmpsi2:
|
||||
enter #0
|
||||
cmp.w SBH,SAH
|
||||
jgt cmpsi_gt
|
||||
jlt cmpsi_lt
|
||||
cmp.w SBL,SAL
|
||||
jgt cmpsi_gt
|
||||
jlt cmpsi_lt
|
||||
mov.w #1,r0
|
||||
exitd
|
||||
cmpsi_gt:
|
||||
mov.w #2,r0
|
||||
exitd
|
||||
cmpsi_lt:
|
||||
mov.w #0,r0
|
||||
exitd
|
||||
#endif
|
||||
|
||||
#ifdef L__m32c_ucmpsi2
|
||||
.text
|
||||
.global ___ucmpsi2
|
||||
___ucmpsi2:
|
||||
enter #0
|
||||
cmp.w SBH,SAH
|
||||
jgtu cmpsi_gt
|
||||
jltu cmpsi_lt
|
||||
cmp.w SBL,SAL
|
||||
jgtu cmpsi_gt
|
||||
jltu cmpsi_lt
|
||||
mov.w #1,r0
|
||||
exitd
|
||||
cmpsi_gt:
|
||||
mov.w #2,r0
|
||||
exitd
|
||||
cmpsi_lt:
|
||||
mov.w #0,r0
|
||||
exitd
|
||||
#endif
|
||||
|
||||
#ifdef L__m32c_jsri16
|
||||
.data
|
||||
m32c_jsri_addr:
|
||||
.byte 0, 0, 0
|
||||
m32c_jsri_ret:
|
||||
.byte 0, 0, 0
|
||||
|
||||
.text
|
||||
.global m32c_jsri16
|
||||
m32c_jsri16:
|
||||
pop.w m32c_jsri_ret
|
||||
pop.b m32c_jsri_ret+2
|
||||
pop.w m32c_jsri_addr
|
||||
push.b m32c_jsri_ret+2
|
||||
push.w m32c_jsri_ret
|
||||
jmpi.a m32c_jsri_addr
|
||||
|
||||
#endif
|
139
gcc/config/m32c/m32c-lib2.c
Normal file
139
gcc/config/m32c/m32c-lib2.c
Normal file
@ -0,0 +1,139 @@
|
||||
/* libgcc routines for R8C/M16C/M32C
|
||||
Copyright (C) 2005
|
||||
Free Software Foundation, Inc.
|
||||
Contributed by Red Hat.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC 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.
|
||||
|
||||
In addition to the permissions in the GNU General Public License,
|
||||
the Free Software Foundation gives you unlimited permission to link
|
||||
the compiled version of this file into combinations with other
|
||||
programs, and to distribute those combinations without any
|
||||
restriction coming from the use of this file. (The General Public
|
||||
License restrictions do apply in other respects; for example, they
|
||||
cover modification of the file, and distribution when not linked
|
||||
into a combine executable.)
|
||||
|
||||
GCC 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 GCC; see the file COPYING. If not, write to the Free
|
||||
Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301, USA. */
|
||||
|
||||
typedef int HItype __attribute__ ((mode (HI)));
|
||||
typedef unsigned int UHItype __attribute__ ((mode (HI)));
|
||||
typedef int SItype __attribute__ ((mode (SI)));
|
||||
typedef unsigned int USItype __attribute__ ((mode (SI)));
|
||||
|
||||
typedef int word_type __attribute__ ((mode (__word__)));
|
||||
|
||||
USItype udivmodsi4 (USItype num, USItype den, word_type modwanted);
|
||||
SItype __divsi3 (SItype a, SItype b);
|
||||
SItype __modsi3 (SItype a, SItype b);
|
||||
SItype __udivsi3 (SItype a, SItype b);
|
||||
SItype __umodsi3 (SItype a, SItype b);
|
||||
|
||||
USItype
|
||||
udivmodsi4 (USItype num, USItype den, word_type modwanted)
|
||||
{
|
||||
USItype bit = 1;
|
||||
USItype res = 0;
|
||||
|
||||
while (den < num && bit && !(den & (1L << 31)))
|
||||
{
|
||||
den <<= 1;
|
||||
bit <<= 1;
|
||||
}
|
||||
while (bit)
|
||||
{
|
||||
if (num >= den)
|
||||
{
|
||||
num -= den;
|
||||
res |= bit;
|
||||
}
|
||||
bit >>= 1;
|
||||
den >>= 1;
|
||||
}
|
||||
if (modwanted)
|
||||
return num;
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
|
||||
SItype
|
||||
__divsi3 (SItype a, SItype b)
|
||||
{
|
||||
word_type neg = 0;
|
||||
SItype res;
|
||||
|
||||
if (a < 0)
|
||||
{
|
||||
a = -a;
|
||||
neg = !neg;
|
||||
}
|
||||
|
||||
if (b < 0)
|
||||
{
|
||||
b = -b;
|
||||
neg = !neg;
|
||||
}
|
||||
|
||||
res = udivmodsi4 (a, b, 0);
|
||||
|
||||
if (neg)
|
||||
res = -res;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
|
||||
SItype
|
||||
__modsi3 (SItype a, SItype b)
|
||||
{
|
||||
word_type neg = 0;
|
||||
SItype res;
|
||||
|
||||
if (a < 0)
|
||||
{
|
||||
a = -a;
|
||||
neg = 1;
|
||||
}
|
||||
|
||||
if (b < 0)
|
||||
b = -b;
|
||||
|
||||
res = udivmodsi4 (a, b, 1);
|
||||
|
||||
if (neg)
|
||||
res = -res;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
SItype
|
||||
__udivsi3 (SItype a, SItype b)
|
||||
{
|
||||
return udivmodsi4 (a, b, 0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
SItype
|
||||
__umodsi3 (SItype a, SItype b)
|
||||
{
|
||||
return udivmodsi4 (a, b, 1);
|
||||
}
|
30
gcc/config/m32c/m32c-modes.def
Normal file
30
gcc/config/m32c/m32c-modes.def
Normal file
@ -0,0 +1,30 @@
|
||||
/* Target-Specific Modes for R8C/M16C/M32C
|
||||
Copyright (C) 2005
|
||||
Free Software Foundation, Inc.
|
||||
Contributed by Red Hat.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC 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.
|
||||
|
||||
GCC 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 GCC; see the file COPYING. If not, write to the Free
|
||||
Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301, USA. */
|
||||
|
||||
/* 24-bit pointers, whole */
|
||||
/*INT_MODE (PI, 3);*/
|
||||
|
||||
/* 24-bit pointers, in 32-bit units */
|
||||
PARTIAL_INT_MODE (SI);
|
||||
|
||||
/* 48-bit MULEX result */
|
||||
/* INT_MODE (MI, 6); */
|
97
gcc/config/m32c/m32c-pragma.c
Normal file
97
gcc/config/m32c/m32c-pragma.c
Normal file
@ -0,0 +1,97 @@
|
||||
/* M32C Pragma support
|
||||
Copyright (C) 2004 Free Software Foundation, Inc.
|
||||
Contributed by Red Hat, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC 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.
|
||||
|
||||
GCC 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 GCC; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301, USA. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "config.h"
|
||||
#include "system.h"
|
||||
#include "coretypes.h"
|
||||
#include "tm.h"
|
||||
#include "tree.h"
|
||||
#include "rtl.h"
|
||||
#include "toplev.h"
|
||||
#include "c-pragma.h"
|
||||
#include "cpplib.h"
|
||||
#include "hard-reg-set.h"
|
||||
#include "output.h"
|
||||
#include "m32c-protos.h"
|
||||
#include "function.h"
|
||||
#define MAX_RECOG_OPERANDS 10
|
||||
#include "reload.h"
|
||||
#include "target.h"
|
||||
|
||||
/* Implements the "GCC memregs" pragma. This pragma takes only an
|
||||
integer, and is semantically identical to the -memregs= command
|
||||
line option. The only catch is, the programmer should only use
|
||||
this pragma at the beginning of the file (preferably, in some
|
||||
project-wide header) to avoid ABI changes related to changing the
|
||||
list of available "registers". */
|
||||
static void
|
||||
m32c_pragma_memregs (cpp_reader * reader ATTRIBUTE_UNUSED)
|
||||
{
|
||||
/* on off */
|
||||
tree val;
|
||||
enum cpp_ttype type;
|
||||
HOST_WIDE_INT i;
|
||||
static char new_number[3];
|
||||
|
||||
type = c_lex (&val);
|
||||
if (type == CPP_NUMBER)
|
||||
{
|
||||
if (host_integerp (val, 1))
|
||||
{
|
||||
i = tree_low_cst (val, 1);
|
||||
|
||||
type = c_lex (&val);
|
||||
if (type != CPP_EOF)
|
||||
warning (0, "junk at end of #pragma GCC memregs [0..16]");
|
||||
|
||||
if (0 <= i && i <= 16)
|
||||
{
|
||||
if (!ok_to_change_target_memregs)
|
||||
{
|
||||
warning (0,
|
||||
"#pragma GCC memregs must precede any function decls");
|
||||
return;
|
||||
}
|
||||
new_number[0] = (i / 10) + '0';
|
||||
new_number[1] = (i % 10) + '0';
|
||||
new_number[2] = 0;
|
||||
target_memregs = new_number;
|
||||
m32c_conditional_register_usage ();
|
||||
}
|
||||
else
|
||||
{
|
||||
warning (0, "#pragma GCC memregs takes a number [0..16]");
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
error ("#pragma GCC memregs takes a number [0..16]");
|
||||
}
|
||||
|
||||
/* Implements REGISTER_TARGET_PRAGMAS. */
|
||||
void
|
||||
m32c_register_pragmas (void)
|
||||
{
|
||||
c_register_pragma ("GCC", "memregs", m32c_pragma_memregs);
|
||||
}
|
105
gcc/config/m32c/m32c-protos.h
Normal file
105
gcc/config/m32c/m32c-protos.h
Normal file
@ -0,0 +1,105 @@
|
||||
/* Target Prototypes for R8C/M16C/M32C
|
||||
Copyright (C) 2005
|
||||
Free Software Foundation, Inc.
|
||||
Contributed by Red Hat.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC 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.
|
||||
|
||||
GCC 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 GCC; see the file COPYING. If not, write to the Free
|
||||
Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301, USA. */
|
||||
|
||||
#define MM enum machine_mode
|
||||
#define UINT unsigned int
|
||||
|
||||
int m32c_class_likely_spilled_p (int);
|
||||
void m32c_conditional_register_usage (void);
|
||||
int m32c_const_ok_for_constraint_p (HOST_WIDE_INT, char, const char *);
|
||||
UINT m32c_dwarf_frame_regnum (int);
|
||||
int m32c_eh_return_data_regno (int);
|
||||
void m32c_emit_epilogue (void);
|
||||
void m32c_emit_prologue (void);
|
||||
int m32c_epilogue_uses (int);
|
||||
int m32c_extra_address_constraint (char, const char *);
|
||||
int m32c_extra_memory_constraint (char, const char *);
|
||||
int m32c_function_arg_regno_p (int);
|
||||
void m32c_init_expanders (void);
|
||||
int m32c_initial_elimination_offset (int, int);
|
||||
void m32c_output_reg_pop (FILE *, int);
|
||||
void m32c_output_reg_push (FILE *, int);
|
||||
void m32c_override_options (void);
|
||||
int m32c_print_operand_punct_valid_p (int);
|
||||
int m32c_push_rounding (int);
|
||||
int m32c_reg_class_from_constraint (char, const char *);
|
||||
void m32c_register_pragmas (void);
|
||||
int m32c_regno_ok_for_base_p (int);
|
||||
int m32c_trampoline_alignment (void);
|
||||
int m32c_trampoline_size (void);
|
||||
|
||||
#if defined(RTX_CODE) && defined(TREE_CODE)
|
||||
|
||||
rtx m32c_function_arg (CUMULATIVE_ARGS *, MM, tree, int);
|
||||
rtx m32c_function_value (tree, tree);
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef RTX_CODE
|
||||
|
||||
int m32c_cannot_change_mode_class (MM, MM, int);
|
||||
int m32c_class_max_nregs (int, MM);
|
||||
rtx m32c_eh_return_stackadj_rtx (void);
|
||||
void m32c_emit_eh_epilogue (rtx);
|
||||
int m32c_extra_constraint_p (rtx, char, const char *);
|
||||
int m32c_extra_constraint_p2 (rtx, char, const char *);
|
||||
int m32c_hard_regno_nregs (int, MM);
|
||||
int m32c_hard_regno_ok (int, MM);
|
||||
rtx m32c_incoming_return_addr_rtx (void);
|
||||
void m32c_initialize_trampoline (rtx, rtx, rtx);
|
||||
int m32c_legitimate_address_p (MM, rtx, int);
|
||||
int m32c_legitimate_constant_p (rtx);
|
||||
int m32c_legitimize_address (rtx *, rtx, MM);
|
||||
int m32c_legitimize_reload_address (rtx *, MM, int, int, int);
|
||||
rtx m32c_libcall_value (MM);
|
||||
int m32c_limit_reload_class (MM, int);
|
||||
int m32c_memory_move_cost (MM, int, int);
|
||||
int m32c_mode_dependent_address (rtx);
|
||||
int m32c_modes_tieable_p (MM, MM);
|
||||
bool m32c_mov_ok (rtx *, MM);
|
||||
int m32c_preferred_output_reload_class (rtx, int);
|
||||
int m32c_preferred_reload_class (rtx, int);
|
||||
int m32c_prepare_move (rtx *, MM);
|
||||
int m32c_prepare_shift (rtx *, int, int);
|
||||
void m32c_print_operand (FILE *, rtx, int);
|
||||
void m32c_print_operand_address (FILE *, rtx);
|
||||
int m32c_reg_ok_for_base_p (rtx, int);
|
||||
int m32c_register_move_cost (MM, int, int);
|
||||
MM m32c_regno_reg_class (int);
|
||||
rtx m32c_return_addr_rtx (int);
|
||||
int m32c_secondary_reload_class (int, MM, rtx);
|
||||
int m32c_split_move (rtx *, MM, int);
|
||||
int m32c_split_psi_p (rtx *);
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef TREE_CODE
|
||||
|
||||
void m32c_function_arg_advance (CUMULATIVE_ARGS *, MM, tree, int);
|
||||
tree m32c_gimplify_va_arg_expr (tree, tree, tree *, tree *);
|
||||
void m32c_init_cumulative_args (CUMULATIVE_ARGS *, tree, rtx, tree, int);
|
||||
bool m32c_promote_function_return (tree);
|
||||
|
||||
#endif
|
||||
|
||||
#undef MM
|
||||
#undef UINT
|
133
gcc/config/m32c/m32c.abi
Normal file
133
gcc/config/m32c/m32c.abi
Normal file
@ -0,0 +1,133 @@
|
||||
Target Definitions for R8C/M16C/M32C
|
||||
Copyright (C) 2005
|
||||
Free Software Foundation, Inc.
|
||||
Contributed by Red Hat.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC 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.
|
||||
|
||||
GCC 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 GCC; see the file COPYING. If not, write to the Free
|
||||
Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301, USA.
|
||||
|
||||
|
||||
These are just some random notes I used during development of this
|
||||
port. Please don't consider these to be "official" specifications,
|
||||
just additional information to help make the code easier to
|
||||
understand.
|
||||
|
||||
|
||||
Frame
|
||||
=====
|
||||
|
||||
+--------------------
|
||||
| incoming args
|
||||
+--------------------
|
||||
| return Address
|
||||
osp -> +--------------------
|
||||
| saved fp
|
||||
fp -> +--------------------
|
||||
| local data
|
||||
+--------------------
|
||||
| saved regs
|
||||
+--------------------
|
||||
| outgoing args (opt)
|
||||
sp -> +--------------------
|
||||
|
||||
Argument Passing
|
||||
================
|
||||
|
||||
r8c, m16c
|
||||
---------
|
||||
|
||||
First arg may be passed in r1l or r1 if it (1) fits (QImode or
|
||||
HImode), (2) is named, and (3) is an integer or pointer type (no
|
||||
structs, floats, etc). Otherwise, it's passed on the stack.
|
||||
|
||||
Second arg may be passed in r2, same restrictions (but not QImode),
|
||||
even if the first arg is passed on the stack.
|
||||
|
||||
Third and further args are passed on the stack. No padding is used,
|
||||
stack "alignment" is 8 bits.
|
||||
|
||||
m32cm, m32c
|
||||
-----------
|
||||
First arg may be passed in r0l or r0, same restrictions as above.
|
||||
|
||||
Second and further args are passed on the stack. Padding is used
|
||||
after QImode parameters (i.e. lower-addressed byte is the value,
|
||||
higher-addressed byte is the padding), stack "alignment" is 16 bits.
|
||||
|
||||
|
||||
Return Value
|
||||
============
|
||||
|
||||
r8c, m16c
|
||||
---------
|
||||
|
||||
QImode in r0l
|
||||
HImode in r0
|
||||
near pointer in r0
|
||||
(desired)
|
||||
SImode in r2r0
|
||||
far pointer in r2r0
|
||||
(actual)
|
||||
Anything bigger than 16 bits is returned in memory, at mem0 (mem0
|
||||
through mem15 are provided by libgcc.a)
|
||||
|
||||
Aggregate values (regardless of size) are returned by pushing a
|
||||
pointer to a temporary area on the stack after the args are pushed.
|
||||
The function fills in this area with the value. Note that this
|
||||
pointer on the stack does not affect how register arguments, if any,
|
||||
are configured.
|
||||
|
||||
m32cm, m32c
|
||||
-----------
|
||||
Same.
|
||||
|
||||
|
||||
Registers Preserved Across Calls
|
||||
================================
|
||||
|
||||
r8c, m16c
|
||||
---------
|
||||
sb, fb, sp (i.e. nearly all registers are call clobbered)
|
||||
|
||||
m32cm, m32c
|
||||
-----------
|
||||
r1, r2, r3, a0, a1, sb, fb, sp
|
||||
(except when used for return values)
|
||||
|
||||
|
||||
Interrupt Handlers
|
||||
==================
|
||||
|
||||
The stack frame is slightly different for interrupt handlers, because
|
||||
(1) we don't have a usable parent frame, and (2) we have to use
|
||||
special instructions to return and thus must save/restore everything
|
||||
differently.
|
||||
|
||||
+--------------------
|
||||
| program state
|
||||
osp -> +--------------------
|
||||
| return address
|
||||
+--------------------
|
||||
| saved r0..fp (pushm)
|
||||
fp -> +--------------------
|
||||
| local data
|
||||
+--------------------
|
||||
| saved regs mem0..mem15
|
||||
+--------------------
|
||||
| outgoing args (opt)
|
||||
sp -> +--------------------
|
||||
|
2958
gcc/config/m32c/m32c.c
Normal file
2958
gcc/config/m32c/m32c.c
Normal file
File diff suppressed because it is too large
Load Diff
649
gcc/config/m32c/m32c.h
Normal file
649
gcc/config/m32c/m32c.h
Normal file
@ -0,0 +1,649 @@
|
||||
/* Target Definitions for R8C/M16C/M32C
|
||||
Copyright (C) 2005
|
||||
Free Software Foundation, Inc.
|
||||
Contributed by Red Hat.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC 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.
|
||||
|
||||
GCC 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 GCC; see the file COPYING. If not, write to the Free
|
||||
Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301, USA. */
|
||||
|
||||
#ifndef GCC_M32C_H
|
||||
#define GCC_M32C_H
|
||||
|
||||
/* Controlling the Compilation Driver, `gcc'. */
|
||||
|
||||
#undef STARTFILE_SPEC
|
||||
#define STARTFILE_SPEC "crt0.o%s crtbegin.o%s"
|
||||
|
||||
/* There are four CPU series we support, but they basically break down
|
||||
into two families - the R8C/M16C families, with 16 bit address
|
||||
registers and one set of opcodes, and the M32CM/M32C group, with 24
|
||||
bit address registers and a different set of opcodes. The
|
||||
assembler doesn't care except for which opcode set is needed; the
|
||||
big difference is in the memory maps, which we cover in
|
||||
LIB_SPEC. */
|
||||
|
||||
#undef ASM_SPEC
|
||||
#define ASM_SPEC "\
|
||||
%{mcpu=r8c:--m16c} \
|
||||
%{mcpu=m16c:--m16c} \
|
||||
%{mcpu=m32cm:--m32c} \
|
||||
%{mcpu=m32c:--m32c} "
|
||||
|
||||
/* The default is R8C hardware. We support a simulator, which has its
|
||||
own libgloss and link map, plus one default link map for each chip
|
||||
family. Most of the logic here is making sure we do the right
|
||||
thing when no CPU is specified, which defaults to R8C. */
|
||||
#undef LIB_SPEC
|
||||
#define LIB_SPEC "-( -lc %{msim*:-lsim}%{!msim*:-lnosys} -) \
|
||||
%{msim*:%{!T*: %{mcpu=m32cm:-Tsim24.ld}%{mcpu=m32c:-Tsim24.ld} \
|
||||
%{!mcpu=m32cm:%{!mcpu=m32c:-Tsim16.ld}}}} \
|
||||
%{!T*:%{!msim*: %{mcpu=m16c:-Tm16c.ld} \
|
||||
%{mcpu=m32cm:-Tm32cm.ld} \
|
||||
%{mcpu=m32c:-Tm32c.ld} \
|
||||
%{!mcpu=m16c:%{!mcpu=m32cm:%{!mcpu=m32c:-Tr8c.ld}}}}} \
|
||||
"
|
||||
|
||||
/* Run-time Target Specification */
|
||||
|
||||
/* Nothing unusual here. */
|
||||
#define TARGET_CPU_CPP_BUILTINS() \
|
||||
{ \
|
||||
builtin_assert ("cpu=m32c"); \
|
||||
builtin_assert ("machine=m32c"); \
|
||||
builtin_define ("__m32c__=1"); \
|
||||
if (TARGET_R8C) \
|
||||
builtin_define ("__r8c_cpu__=1"); \
|
||||
if (TARGET_M16C) \
|
||||
builtin_define ("__m16c_cpu__=1"); \
|
||||
if (TARGET_M32CM) \
|
||||
builtin_define ("__m32cm_cpu__=1"); \
|
||||
if (TARGET_M32C) \
|
||||
builtin_define ("__m32c_cpu__=1"); \
|
||||
}
|
||||
|
||||
/* The pragma handlers need to know if we've started processing
|
||||
functions yet, as the memregs pragma should only be given at the
|
||||
beginning of the file. This variable starts off TRUE and later
|
||||
becomes FALSE. */
|
||||
extern int ok_to_change_target_memregs;
|
||||
extern int target_memregs;
|
||||
|
||||
/* TARGET_CPU is a multi-way option set in m32c.opt. While we could
|
||||
use enums or defines for this, this and m32c.opt are the only
|
||||
places that know (or care) what values are being used. */
|
||||
#define TARGET_R8C (target_cpu == 'r')
|
||||
#define TARGET_M16C (target_cpu == '6')
|
||||
#define TARGET_M32CM (target_cpu == 'm')
|
||||
#define TARGET_M32C (target_cpu == '3')
|
||||
|
||||
/* Address register sizes. Warning: these are used all over the place
|
||||
to select between the two CPU families in general. */
|
||||
#define TARGET_A16 (TARGET_R8C || TARGET_M16C)
|
||||
#define TARGET_A24 (TARGET_M32CM || TARGET_M32C)
|
||||
|
||||
#define TARGET_VERSION fprintf (stderr, " (m32c)");
|
||||
|
||||
#define OVERRIDE_OPTIONS m32c_override_options ();
|
||||
|
||||
/* Defining data structures for per-function information */
|
||||
|
||||
typedef struct machine_function GTY (())
|
||||
{
|
||||
/* How much we adjust the stack when returning from an exception
|
||||
handler. */
|
||||
rtx eh_stack_adjust;
|
||||
|
||||
/* TRUE if the current function is an interrupt handler. */
|
||||
int is_interrupt;
|
||||
|
||||
/* TRUE if the current function is a leaf function. Currently, this
|
||||
only affects saving $a0 in interrupt functions. */
|
||||
int is_leaf;
|
||||
|
||||
/* Bitmask that keeps track of which registers are used in an
|
||||
interrupt function, so we know which ones need to be saved and
|
||||
restored. */
|
||||
int intr_pushm;
|
||||
/* Likewise, one element for each memreg that needs to be saved. */
|
||||
char intr_pushmem[16];
|
||||
|
||||
/* TRUE if the current function can use a simple RTS to return, instead
|
||||
of the longer ENTER/EXIT pair. */
|
||||
int use_rts;
|
||||
}
|
||||
machine_function;
|
||||
|
||||
#define INIT_EXPANDERS m32c_init_expanders ()
|
||||
|
||||
/* Storage Layout */
|
||||
|
||||
#define BITS_BIG_ENDIAN 0
|
||||
#define BYTES_BIG_ENDIAN 0
|
||||
#define WORDS_BIG_ENDIAN 0
|
||||
|
||||
/* We can do QI, HI, and SI operations pretty much equally well, but
|
||||
GCC expects us to have a "native" format, so we pick the one that
|
||||
matches "int". Pointers are 16 bits for R8C/M16C (when TARGET_A16
|
||||
is true) and 24 bits for M32CM/M32C (when TARGET_A24 is true), but
|
||||
24 bit pointers are stored in 32 bit words. */
|
||||
#define BITS_PER_UNIT 8
|
||||
#define UNITS_PER_WORD 2
|
||||
#define POINTER_SIZE (TARGET_A16 ? 16 : 32)
|
||||
#define POINTERS_EXTEND_UNSIGNED 1
|
||||
|
||||
/* These match the alignment enforced by the two types of stack operations. */
|
||||
#define PARM_BOUNDARY (TARGET_A16 ? 8 : 16)
|
||||
#define STACK_BOUNDARY (TARGET_A16 ? 8 : 16)
|
||||
|
||||
/* We do this because we care more about space than about speed. For
|
||||
the chips with 16 bit busses, we could set these to 16 if
|
||||
desired. */
|
||||
#define FUNCTION_BOUNDARY 8
|
||||
#define BIGGEST_ALIGNMENT 8
|
||||
|
||||
#define STRICT_ALIGNMENT 0
|
||||
#define SLOW_BYTE_ACCESS 1
|
||||
|
||||
/* Layout of Source Language Data Types */
|
||||
|
||||
#define INT_TYPE_SIZE 16
|
||||
#define SHORT_TYPE_SIZE 16
|
||||
#define LONG_TYPE_SIZE 32
|
||||
#define LONG_LONG_TYPE_SIZE 64
|
||||
|
||||
#define FLOAT_TYPE_SIZE 32
|
||||
#define DOUBLE_TYPE_SIZE 64
|
||||
#define LONG_DOUBLE_TYPE_SIZE 64
|
||||
|
||||
#define DEFAULT_SIGNED_CHAR 1
|
||||
|
||||
/* REGISTER USAGE */
|
||||
|
||||
/* Register Basics */
|
||||
|
||||
/* Register layout:
|
||||
|
||||
[r0h][r0l] $r0 (16 bits, or two 8 bit halves)
|
||||
[--------] $r2 (16 bits)
|
||||
[r1h][r1l] $r1 (16 bits, or two 8 bit halves)
|
||||
[--------] $r3 (16 bits)
|
||||
[---][--------] $a0 (might be 24 bits)
|
||||
[---][--------] $a1 (might be 24 bits)
|
||||
[---][--------] $sb (might be 24 bits)
|
||||
[---][--------] $fb (might be 24 bits)
|
||||
[---][--------] $sp (might be 24 bits)
|
||||
[-------------] $pc (20 or 24 bits)
|
||||
[---] $flg (CPU flags)
|
||||
[---][--------] $argp (virtual)
|
||||
[--------] $mem0 (all 16 bits)
|
||||
. . .
|
||||
[--------] $mem14
|
||||
*/
|
||||
|
||||
#define FIRST_PSEUDO_REGISTER 20
|
||||
|
||||
/* Note that these two tables are modified based on which CPU family
|
||||
you select; see m32c_conditional_register_usage for details. */
|
||||
|
||||
/* r0 r2 r1 r3 - a0 a1 sb fb - sp pc flg argp - mem0..mem14 */
|
||||
#define FIXED_REGISTERS { 0, 0, 0, 0, \
|
||||
0, 0, 1, 0, \
|
||||
1, 1, 0, 1, \
|
||||
0, 0, 0, 0, 0, 0, 0, 0 }
|
||||
#define CALL_USED_REGISTERS { 1, 1, 1, 1, \
|
||||
1, 1, 1, 0, \
|
||||
1, 1, 1, 1, \
|
||||
1, 1, 1, 1, 1, 1, 1, 1 }
|
||||
|
||||
#define CONDITIONAL_REGISTER_USAGE m32c_conditional_register_usage ();
|
||||
|
||||
/* The *_REGNO theme matches m32c.md and most register number
|
||||
arguments; the PC_REGNUM is the odd one out. */
|
||||
#ifndef PC_REGNO
|
||||
#define PC_REGNO 9
|
||||
#endif
|
||||
#define PC_REGNUM PC_REGNO
|
||||
|
||||
/* How Values Fit in Registers */
|
||||
|
||||
#define HARD_REGNO_NREGS(R,M) m32c_hard_regno_nregs (R, M)
|
||||
#define HARD_REGNO_MODE_OK(R,M) m32c_hard_regno_ok (R, M)
|
||||
#define MODES_TIEABLE_P(M1,M2) m32c_modes_tieable_p (M1, M2)
|
||||
#define AVOID_CCMODE_COPIES
|
||||
|
||||
/* Register Classes */
|
||||
|
||||
/* Most registers are special purpose in some form or another, so this
|
||||
table is pretty big. Class names are used for constraints also;
|
||||
for example the HL_REGS class (HL below) is "Rhl" in the md files.
|
||||
See m32c_reg_class_from_constraint for the mapping. There's some
|
||||
duplication so that we can better isolate the reason for using
|
||||
constraints in the md files from the actual registers used; for
|
||||
example we may want to exclude a1a0 from SI_REGS in the future,
|
||||
without precluding their use as HImode registers. */
|
||||
|
||||
/* m7654 - m3210 - argp flg pc sp - fb sb a1 a0 - r3 r1 r2 r0 */
|
||||
/* mmPAR */
|
||||
#define REG_CLASS_CONTENTS \
|
||||
{ { 0x00000000 }, /* NO */\
|
||||
{ 0x00000100 }, /* SP - sp */\
|
||||
{ 0x00000080 }, /* FB - fb */\
|
||||
{ 0x00000040 }, /* SB - sb */\
|
||||
{ 0x000001c0 }, /* CR - sb fb sp */\
|
||||
{ 0x00000001 }, /* R0 - r0 */\
|
||||
{ 0x00000004 }, /* R1 - r1 */\
|
||||
{ 0x00000002 }, /* R2 - r2 */\
|
||||
{ 0x00000008 }, /* R3 - r3 */\
|
||||
{ 0x00000003 }, /* R02 - r0r2 */\
|
||||
{ 0x00000005 }, /* HL - r0 r1 */\
|
||||
{ 0x00000005 }, /* QI - r0 r1 */\
|
||||
{ 0x0000000a }, /* R23 - r2 r3 */\
|
||||
{ 0x0000000f }, /* R03 - r0r2 r1r3 */\
|
||||
{ 0x0000000f }, /* DI - r0r2r1r3 + mems */\
|
||||
{ 0x00000030 }, /* A - a0 a1 */\
|
||||
{ 0x000000f0 }, /* AD - a0 a1 sb fp */\
|
||||
{ 0x000001f0 }, /* PS - a0 a1 sb fp sp */\
|
||||
{ 0x0000003f }, /* SI - r0r2 r1r3 a0a1 */\
|
||||
{ 0x0000003f }, /* HI - r0 r1 r2 r3 a0 a1 */\
|
||||
{ 0x0000003f }, /* RA - r0..r3 a0 a1 */\
|
||||
{ 0x0000007f }, /* GENERAL */\
|
||||
{ 0x00000400 }, /* FLG */\
|
||||
{ 0x000001ff }, /* HC - r0l r1 r2 r3 a0 a1 sb fb sp */\
|
||||
{ 0x000ff000 }, /* MEM */\
|
||||
{ 0x000ff003 }, /* R02_A_MEM */\
|
||||
{ 0x000ff005 }, /* A_HL_MEM */\
|
||||
{ 0x000ff00c }, /* R1_R3_A_MEM */\
|
||||
{ 0x000ff00f }, /* R03_MEM */\
|
||||
{ 0x000ff03f }, /* A_HI_MEM */\
|
||||
{ 0x000ff0ff }, /* A_AD_CR_MEM_SI */\
|
||||
{ 0x000ff1ff }, /* ALL */\
|
||||
}
|
||||
|
||||
enum reg_class
|
||||
{
|
||||
NO_REGS,
|
||||
SP_REGS,
|
||||
FB_REGS,
|
||||
SB_REGS,
|
||||
CR_REGS,
|
||||
R0_REGS,
|
||||
R1_REGS,
|
||||
R2_REGS,
|
||||
R3_REGS,
|
||||
R02_REGS,
|
||||
HL_REGS,
|
||||
QI_REGS,
|
||||
R23_REGS,
|
||||
R03_REGS,
|
||||
DI_REGS,
|
||||
A_REGS,
|
||||
AD_REGS,
|
||||
PS_REGS,
|
||||
SI_REGS,
|
||||
HI_REGS,
|
||||
RA_REGS,
|
||||
GENERAL_REGS,
|
||||
FLG_REGS,
|
||||
HC_REGS,
|
||||
MEM_REGS,
|
||||
R02_A_MEM_REGS,
|
||||
A_HL_MEM_REGS,
|
||||
R1_R3_A_MEM_REGS,
|
||||
R03_MEM_REGS,
|
||||
A_HI_MEM_REGS,
|
||||
A_AD_CR_MEM_SI_REGS,
|
||||
ALL_REGS,
|
||||
LIM_REG_CLASSES
|
||||
};
|
||||
|
||||
#define N_REG_CLASSES LIM_REG_CLASSES
|
||||
|
||||
#define REG_CLASS_NAMES {\
|
||||
"NO_REGS", \
|
||||
"SP_REGS", \
|
||||
"FB_REGS", \
|
||||
"SB_REGS", \
|
||||
"CR_REGS", \
|
||||
"R0_REGS", \
|
||||
"R1_REGS", \
|
||||
"R2_REGS", \
|
||||
"R3_REGS", \
|
||||
"R02_REGS", \
|
||||
"HL_REGS", \
|
||||
"QI_REGS", \
|
||||
"R23_REGS", \
|
||||
"R03_REGS", \
|
||||
"DI_REGS", \
|
||||
"A_REGS", \
|
||||
"AD_REGS", \
|
||||
"PS_REGS", \
|
||||
"SI_REGS", \
|
||||
"HI_REGS", \
|
||||
"RA_REGS", \
|
||||
"GENERAL_REGS", \
|
||||
"FLG_REGS", \
|
||||
"HC_REGS", \
|
||||
"MEM_REGS", \
|
||||
"R02_A_MEM_REGS", \
|
||||
"A_HL_MEM_REGS", \
|
||||
"R1_R3_A_MEM_REGS", \
|
||||
"R03_MEM_REGS", \
|
||||
"A_HI_MEM_REGS", \
|
||||
"A_AD_CR_MEM_SI_REGS", \
|
||||
"ALL_REGS", \
|
||||
}
|
||||
|
||||
#define REGNO_REG_CLASS(R) m32c_regno_reg_class (R)
|
||||
|
||||
/* We support simple displacements off address registers, nothing else. */
|
||||
#define BASE_REG_CLASS A_REGS
|
||||
#define INDEX_REG_CLASS NO_REGS
|
||||
|
||||
/* We primarily use the new "long" constraint names, with the intial
|
||||
letter classifying the constraint type and following letters
|
||||
specifying which. The types are:
|
||||
|
||||
I - integer values
|
||||
R - register classes
|
||||
S - memory references (M was used)
|
||||
A - addresses (currently unused)
|
||||
*/
|
||||
|
||||
#define CONSTRAINT_LEN(CHAR,STR) \
|
||||
((CHAR) == 'I' ? 3 \
|
||||
: (CHAR) == 'R' ? 3 \
|
||||
: (CHAR) == 'S' ? 2 \
|
||||
: (CHAR) == 'A' ? 2 \
|
||||
: DEFAULT_CONSTRAINT_LEN(CHAR,STR))
|
||||
#define REG_CLASS_FROM_CONSTRAINT(CHAR,STR) \
|
||||
m32c_reg_class_from_constraint (CHAR, STR)
|
||||
|
||||
#define REGNO_OK_FOR_BASE_P(NUM) m32c_regno_ok_for_base_p (NUM)
|
||||
#define REGNO_OK_FOR_INDEX_P(NUM) 0
|
||||
|
||||
#define PREFERRED_RELOAD_CLASS(X,CLASS) m32c_preferred_reload_class (X, CLASS)
|
||||
#define PREFERRED_OUTPUT_RELOAD_CLASS(X,CLASS) m32c_preferred_output_reload_class (X, CLASS)
|
||||
#define LIMIT_RELOAD_CLASS(MODE,CLASS) m32c_limit_reload_class (MODE, CLASS)
|
||||
|
||||
#define SECONDARY_RELOAD_CLASS(CLASS,MODE,X) m32c_secondary_reload_class (CLASS, MODE, X)
|
||||
|
||||
#define SMALL_REGISTER_CLASSES 1
|
||||
|
||||
#define CLASS_LIKELY_SPILLED_P(C) m32c_class_likely_spilled_p (C)
|
||||
|
||||
#define CLASS_MAX_NREGS(C,M) m32c_class_max_nregs (C, M)
|
||||
|
||||
#define CANNOT_CHANGE_MODE_CLASS(F,T,C) m32c_cannot_change_mode_class(F,T,C)
|
||||
|
||||
#define CONST_OK_FOR_CONSTRAINT_P(VALUE,C,STR) \
|
||||
m32c_const_ok_for_constraint_p (VALUE, C, STR)
|
||||
#define CONST_DOUBLE_OK_FOR_CONSTRAINT_P(VALUE,C,STR) 0
|
||||
#define EXTRA_CONSTRAINT_STR(VALUE,C,STR) \
|
||||
m32c_extra_constraint_p (VALUE, C, STR)
|
||||
#define EXTRA_MEMORY_CONSTRAINT(C,STR) \
|
||||
m32c_extra_memory_constraint (C, STR)
|
||||
#define EXTRA_ADDRESS_CONSTRAINT(C,STR) \
|
||||
m32c_extra_address_constraint (C, STR)
|
||||
|
||||
/* STACK AND CALLING */
|
||||
|
||||
/* Frame Layout */
|
||||
|
||||
/* Standard push/pop stack, no surprises here. */
|
||||
|
||||
#define STACK_GROWS_DOWNWARD 1
|
||||
#define STACK_PUSH_CODE PRE_DEC
|
||||
#define FRAME_GROWS_DOWNWARD 1
|
||||
|
||||
#define STARTING_FRAME_OFFSET 0
|
||||
#define FIRST_PARM_OFFSET(F) 0
|
||||
|
||||
#define RETURN_ADDR_RTX(COUNT,FA) m32c_return_addr_rtx (COUNT)
|
||||
|
||||
#define INCOMING_RETURN_ADDR_RTX m32c_incoming_return_addr_rtx()
|
||||
#define INCOMING_FRAME_SP_OFFSET 3
|
||||
|
||||
/* Exception Handling Support */
|
||||
|
||||
#define EH_RETURN_DATA_REGNO(N) m32c_eh_return_data_regno (N)
|
||||
#define EH_RETURN_STACKADJ_RTX m32c_eh_return_stackadj_rtx ()
|
||||
|
||||
/* Registers That Address the Stack Frame */
|
||||
|
||||
#ifndef FP_REGNO
|
||||
#define FP_REGNO 7
|
||||
#endif
|
||||
#ifndef SP_REGNO
|
||||
#define SP_REGNO 8
|
||||
#endif
|
||||
#define AP_REGNO 11
|
||||
|
||||
#define STACK_POINTER_REGNUM SP_REGNO
|
||||
#define FRAME_POINTER_REGNUM FP_REGNO
|
||||
#define ARG_POINTER_REGNUM AP_REGNO
|
||||
|
||||
/* The static chain must be pointer-capable. */
|
||||
#define STATIC_CHAIN_REGNUM A0_REGNO
|
||||
|
||||
#define DWARF_FRAME_REGISTERS 20
|
||||
#define DWARF_FRAME_REGNUM(N) m32c_dwarf_frame_regnum (N)
|
||||
#define DBX_REGISTER_NUMBER(N) m32c_dwarf_frame_regnum (N)
|
||||
|
||||
/* Eliminating Frame Pointer and Arg Pointer */
|
||||
|
||||
/* If the frame pointer isn't used, we detect it manually. But the
|
||||
stack pointer doesn't have as flexible addressing as the frame
|
||||
pointer, so we always assume we have it. */
|
||||
#define FRAME_POINTER_REQUIRED 1
|
||||
|
||||
#define ELIMINABLE_REGS \
|
||||
{{AP_REGNO, SP_REGNO}, \
|
||||
{AP_REGNO, FB_REGNO}, \
|
||||
{FB_REGNO, SP_REGNO}}
|
||||
|
||||
#define CAN_ELIMINATE(FROM,TO) 1
|
||||
#define INITIAL_ELIMINATION_OFFSET(FROM,TO,VAR) \
|
||||
(VAR) = m32c_initial_elimination_offset(FROM,TO)
|
||||
|
||||
/* Passing Function Arguments on the Stack */
|
||||
|
||||
#define PUSH_ARGS 1
|
||||
#define PUSH_ROUNDING(N) m32c_push_rounding (N)
|
||||
#define RETURN_POPS_ARGS(D,T,S) 0
|
||||
#define CALL_POPS_ARGS(C) 0
|
||||
|
||||
/* Passing Arguments in Registers */
|
||||
|
||||
#define FUNCTION_ARG(CA,MODE,TYPE,NAMED) \
|
||||
m32c_function_arg (&(CA),MODE,TYPE,NAMED)
|
||||
|
||||
typedef struct m32c_cumulative_args
|
||||
{
|
||||
/* For address of return value buffer (structures are returned by
|
||||
passing the address of a buffer as an invisible first argument.
|
||||
This identifies it). If set, the current parameter will be put
|
||||
on the stack, regardless of type. */
|
||||
int force_mem;
|
||||
/* First parm is 1, parm 0 is hidden pointer for returning
|
||||
aggregates. */
|
||||
int parm_num;
|
||||
} m32c_cumulative_args;
|
||||
|
||||
#define CUMULATIVE_ARGS m32c_cumulative_args
|
||||
#define INIT_CUMULATIVE_ARGS(CA,FNTYPE,LIBNAME,FNDECL,N_NAMED_ARGS) \
|
||||
m32c_init_cumulative_args (&(CA),FNTYPE,LIBNAME,FNDECL,N_NAMED_ARGS)
|
||||
#define FUNCTION_ARG_ADVANCE(CA,MODE,TYPE,NAMED) \
|
||||
m32c_function_arg_advance (&(CA),MODE,TYPE,NAMED)
|
||||
#define FUNCTION_ARG_BOUNDARY(MODE,TYPE) (TARGET_A16 ? 8 : 16)
|
||||
#define FUNCTION_ARG_REGNO_P(r) m32c_function_arg_regno_p (r)
|
||||
|
||||
/* How Scalar Function Values Are Returned */
|
||||
|
||||
#define FUNCTION_VALUE(VT,F) m32c_function_value (VT, F)
|
||||
#define LIBCALL_VALUE(MODE) m32c_libcall_value (MODE)
|
||||
|
||||
#define FUNCTION_VALUE_REGNO_P(r) ((r) == R0_REGNO || (r) == MEM0_REGNO)
|
||||
|
||||
/* How Large Values Are Returned */
|
||||
|
||||
#define DEFAULT_PCC_STRUCT_RETURN 1
|
||||
|
||||
/* Function Entry and Exit */
|
||||
|
||||
#define EXIT_IGNORE_STACK 0
|
||||
#define EPILOGUE_USES(REGNO) m32c_epilogue_uses(REGNO)
|
||||
#define EH_USES(REGNO) 0 /* FIXME */
|
||||
|
||||
/* Generating Code for Profiling */
|
||||
|
||||
#define FUNCTION_PROFILER(FILE,LABELNO)
|
||||
|
||||
/* Implementing the Varargs Macros */
|
||||
|
||||
/* Trampolines for Nested Functions */
|
||||
|
||||
#define TRAMPOLINE_SIZE m32c_trampoline_size ()
|
||||
#define TRAMPOLINE_ALIGMNENT m32c_trampoline_alignment ()
|
||||
#define INITIALIZE_TRAMPOLINE(a,fn,sc) m32c_initialize_trampoline (a, fn, sc)
|
||||
|
||||
/* Addressing Modes */
|
||||
|
||||
#define HAVE_PRE_DECREMENT 1
|
||||
#define HAVE_POST_INCREMENT 1
|
||||
#define CONSTANT_ADDRESS_P(X) CONSTANT_P(X)
|
||||
#define MAX_REGS_PER_ADDRESS 1
|
||||
|
||||
/* This is passed to the macros below, so that they can be implemented
|
||||
in m32c.c. */
|
||||
#ifdef REG_OK_STRICT
|
||||
#define REG_OK_STRICT_V 1
|
||||
#else
|
||||
#define REG_OK_STRICT_V 0
|
||||
#endif
|
||||
|
||||
#define GO_IF_LEGITIMATE_ADDRESS(MODE,X,LABEL) \
|
||||
if (m32c_legitimate_address_p (MODE, X, REG_OK_STRICT_V)) \
|
||||
goto LABEL;
|
||||
|
||||
#define REG_OK_FOR_BASE_P(X) m32c_reg_ok_for_base_p (X, REG_OK_STRICT_V)
|
||||
#define REG_OK_FOR_INDEX_P(X) 0
|
||||
|
||||
/* #define FIND_BASE_TERM(X) when we do unspecs for symrefs */
|
||||
|
||||
#define LEGITIMIZE_ADDRESS(X,OLDX,MODE,WIN) \
|
||||
if (m32c_legitimize_address(&(X),OLDX,MODE)) \
|
||||
goto win;
|
||||
|
||||
#define LEGITIMIZE_RELOAD_ADDRESS(X,MODE,OPNUM,TYPE,IND_LEVELS,WIN) \
|
||||
if (m32c_legitimize_reload_address(&(X),MODE,OPNUM,TYPE,IND_LEVELS)) \
|
||||
goto win;
|
||||
|
||||
#define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR,LABEL) \
|
||||
if (m32c_mode_dependent_address (ADDR)) \
|
||||
goto LABEL;
|
||||
|
||||
#define LEGITIMATE_CONSTANT_P(X) m32c_legitimate_constant_p (X)
|
||||
|
||||
/* Condition Code Status */
|
||||
|
||||
#define REVERSIBLE_CC_MODE(MODE) 1
|
||||
|
||||
/* Describing Relative Costs of Operations */
|
||||
|
||||
#define REGISTER_MOVE_COST(MODE,FROM,TO) \
|
||||
m32c_register_move_cost (MODE, FROM, TO)
|
||||
#define MEMORY_MOVE_COST(MODE,CLASS,IN) \
|
||||
m32c_memory_move_cost (MODE, CLASS, IN)
|
||||
|
||||
/* Dividing the Output into Sections (Texts, Data, ...) */
|
||||
|
||||
#define TEXT_SECTION_ASM_OP ".text"
|
||||
#define DATA_SECTION_ASM_OP ".data"
|
||||
#define BSS_SECTION_ASM_OP ".bss"
|
||||
|
||||
/* The Overall Framework of an Assembler File */
|
||||
|
||||
#define ASM_COMMENT_START ";"
|
||||
#define ASM_APP_ON ""
|
||||
#define ASM_APP_OFF ""
|
||||
|
||||
/* Output and Generation of Labels */
|
||||
|
||||
#define GLOBAL_ASM_OP "\t.global\t"
|
||||
|
||||
/* Output of Assembler Instructions */
|
||||
|
||||
#define REGISTER_NAMES { \
|
||||
"r0", "r2", "r1", "r3", \
|
||||
"a0", "a1", "sb", "fb", "sp", \
|
||||
"pc", "flg", "argp", \
|
||||
"mem0", "mem2", "mem4", "mem6", "mem8", "mem10", "mem12", "mem14", \
|
||||
}
|
||||
|
||||
#define ADDITIONAL_REGISTER_NAMES { \
|
||||
{"r0l", 0}, \
|
||||
{"r1l", 2}, \
|
||||
{"r0r2", 0}, \
|
||||
{"r1r3", 2}, \
|
||||
{"a0a1", 4}, \
|
||||
{"r0r2r1r3", 0} }
|
||||
|
||||
#define PRINT_OPERAND(S,X,C) m32c_print_operand (S, X, C)
|
||||
#define PRINT_OPERAND_PUNCT_VALID_P(C) m32c_print_operand_punct_valid_p (C)
|
||||
#define PRINT_OPERAND_ADDRESS(S,X) m32c_print_operand_address (S, X)
|
||||
|
||||
#undef USER_LABEL_PREFIX
|
||||
#define USER_LABEL_PREFIX "_"
|
||||
|
||||
#define ASM_OUTPUT_REG_PUSH(S,R) m32c_output_reg_push (S, R)
|
||||
#define ASM_OUTPUT_REG_POP(S,R) m32c_output_reg_pop (S, R)
|
||||
|
||||
/* Output of Dispatch Tables */
|
||||
|
||||
#define ASM_OUTPUT_ADDR_VEC_ELT(S,V) \
|
||||
fprintf (S, "\t.word L%d\n", V)
|
||||
|
||||
/* Assembler Commands for Exception Regions */
|
||||
|
||||
#define DWARF_CIE_DATA_ALIGNMENT -1
|
||||
|
||||
/* Assembler Commands for Alignment */
|
||||
|
||||
#define ASM_OUTPUT_ALIGN(STREAM,POWER) \
|
||||
fprintf (STREAM, "\t.p2align\t%d\n", POWER);
|
||||
|
||||
/* Controlling Debugging Information Format */
|
||||
|
||||
#define DWARF2_ADDR_SIZE 4
|
||||
|
||||
/* Miscellaneous Parameters */
|
||||
|
||||
#define HAS_LONG_COND_BRANCH false
|
||||
#define HAS_LONG_UNCOND_BRANCH true
|
||||
#define CASE_VECTOR_MODE SImode
|
||||
#define LOAD_EXTEND_OP(MEM) ZERO_EXTEND
|
||||
|
||||
#define MOVE_MAX 4
|
||||
#define TRULY_NOOP_TRUNCATION(op,ip) 1
|
||||
|
||||
/* 16 or 24 bit pointers */
|
||||
#define Pmode (TARGET_A16 ? HImode : PSImode)
|
||||
#define FUNCTION_MODE QImode
|
||||
|
||||
#define REGISTER_TARGET_PRAGMAS() m32c_register_pragmas()
|
||||
|
||||
#endif
|
57
gcc/config/m32c/m32c.md
Normal file
57
gcc/config/m32c/m32c.md
Normal file
@ -0,0 +1,57 @@
|
||||
;; Machine Descriptions for R8C/M16C/M32C
|
||||
;; Copyright (C) 2005
|
||||
;; Free Software Foundation, Inc.
|
||||
;; Contributed by Red Hat.
|
||||
;;
|
||||
;; This file is part of GCC.
|
||||
;;
|
||||
;; GCC 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.
|
||||
;;
|
||||
;; GCC 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 GCC; see the file COPYING. If not, write to the Free
|
||||
;; Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
;; 02110-1301, USA.
|
||||
|
||||
(define_constants
|
||||
[(R0_REGNO 0)
|
||||
(R2_REGNO 1)
|
||||
(R1_REGNO 2)
|
||||
(R3_REGNO 3)
|
||||
|
||||
(A0_REGNO 4)
|
||||
(A1_REGNO 5)
|
||||
(SB_REGNO 6)
|
||||
(FB_REGNO 7)
|
||||
|
||||
(SP_REGNO 8)
|
||||
(PC_REGNO 9)
|
||||
(FLG_REGNO 10)
|
||||
(MEM0_REGNO 12)
|
||||
(MEM7_REGNO 19)
|
||||
])
|
||||
|
||||
(define_constants
|
||||
[(UNS_PROLOGUE_END 1)
|
||||
(UNS_EPILOGUE_START 2)
|
||||
(UNS_EH_EPILOGUE 3)
|
||||
(UNS_PUSHM 4)
|
||||
(UNS_POPM 5)
|
||||
])
|
||||
|
||||
(define_insn "nop"
|
||||
[(const_int 0)]
|
||||
""
|
||||
"nop")
|
||||
|
||||
;; n = no change, x = clobbered. The first 16 values are chosen such
|
||||
;; that the enum has one bit set for each flag.
|
||||
(define_attr "flags" "x,c,z,zc,s,sc,sz,szc,o,oc,oz,ozc,os,osc,osz,oszc,n" (const_string "n"))
|
||||
(define_asm_attributes [(set_attr "flags" "x")])
|
45
gcc/config/m32c/m32c.opt
Normal file
45
gcc/config/m32c/m32c.opt
Normal file
@ -0,0 +1,45 @@
|
||||
; Target Options for R8C/M16C/M32C
|
||||
; Copyright (C) 2005
|
||||
; Free Software Foundation, Inc.
|
||||
; Contributed by Red Hat.
|
||||
;
|
||||
; This file is part of GCC.
|
||||
;
|
||||
; GCC 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.
|
||||
;
|
||||
; GCC 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 GCC; see the file COPYING. If not, write to the Free
|
||||
; Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
; 02110-1301, USA.
|
||||
|
||||
msim
|
||||
Target
|
||||
-msim Use simulator runtime
|
||||
|
||||
mcpu=r8c
|
||||
Target RejectNegative Var(target_cpu,'r') Init('r')
|
||||
-mcpu=r8c Compile code for R8C variants
|
||||
|
||||
mcpu=m16c
|
||||
Target RejectNegative Var(target_cpu,'6')
|
||||
-mcpu=m16c Compile code for M16C variants
|
||||
|
||||
mcpu=m32cm
|
||||
Target RejectNegative Var(target_cpu,'m')
|
||||
-mcpu=m32cm Compile code for M32CM variants
|
||||
|
||||
mcpu=m32c
|
||||
Target RejectNegative Var(target_cpu,'3')
|
||||
-mcpu=m32c Compile code for M32C variants
|
||||
|
||||
memregs=
|
||||
Target RejectNegative Joined Var(target_memregs_string)
|
||||
-memregs= Number of memreg bytes (default: 16, range: 0..16)
|
55
gcc/config/m32c/minmax.md
Normal file
55
gcc/config/m32c/minmax.md
Normal file
@ -0,0 +1,55 @@
|
||||
;; Machine Descriptions for R8C/M16C/M32C
|
||||
;; Copyright (C) 2005
|
||||
;; Free Software Foundation, Inc.
|
||||
;; Contributed by Red Hat.
|
||||
;;
|
||||
;; This file is part of GCC.
|
||||
;;
|
||||
;; GCC 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.
|
||||
;;
|
||||
;; GCC 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 GCC; see the file COPYING. If not, write to the Free
|
||||
;; Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
;; 02110-1301, USA.
|
||||
|
||||
;; min, max
|
||||
|
||||
(define_insn "sminqi3"
|
||||
[(set (match_operand:QI 0 "mra_operand" "=RhlSd,RhlSd,??Rmm,??Rmm,Raa,Raa")
|
||||
(smin:QI (match_operand:QI 1 "mra_operand" "%0,0,0,0,0,0")
|
||||
(match_operand:QI 2 "mrai_operand" "iRhlSdRaa,?Rmm,iRhlSdRaa,?Rmm,iRhlSd,?Rmm")))]
|
||||
"TARGET_A24"
|
||||
"min.b\t%2,%0"
|
||||
)
|
||||
|
||||
(define_insn "sminhi3"
|
||||
[(set (match_operand:HI 0 "mra_operand" "=RhiSd,RhiSd,??Rmm,??Rmm")
|
||||
(smin:HI (match_operand:HI 1 "mra_operand" "%0,0,0,0")
|
||||
(match_operand:HI 2 "mrai_operand" "iRhiSd,?Rmm,iRhiSd,?Rmm")))]
|
||||
"TARGET_A24"
|
||||
"min.w\t%2,%0"
|
||||
)
|
||||
|
||||
(define_insn "smaxqi3"
|
||||
[(set (match_operand:QI 0 "mra_operand" "=RhlSd,RhlSd,??Rmm,??Rmm,Raa,Raa")
|
||||
(smax:QI (match_operand:QI 1 "mra_operand" "%0,0,0,0,0,0")
|
||||
(match_operand:QI 2 "mrai_operand" "iRhlSdRaa,?Rmm,iRhlSdRaa,?Rmm,iRhlSd,?Rmm")))]
|
||||
"TARGET_A24"
|
||||
"max.b\t%2,%0"
|
||||
)
|
||||
|
||||
(define_insn "smaxhi3"
|
||||
[(set (match_operand:HI 0 "mra_operand" "=RhiSd,RhiSd,??Rmm,??Rmm")
|
||||
(smax:HI (match_operand:HI 1 "mra_operand" "%0,0,0,0")
|
||||
(match_operand:HI 2 "mrai_operand" "iRhiSd,?Rmm,iRhiSd,?Rmm")))]
|
||||
"TARGET_A24"
|
||||
"max.w\t%2,%0"
|
||||
)
|
429
gcc/config/m32c/mov.md
Normal file
429
gcc/config/m32c/mov.md
Normal file
@ -0,0 +1,429 @@
|
||||
;; Machine Descriptions for R8C/M16C/M32C
|
||||
;; Copyright (C) 2005
|
||||
;; Free Software Foundation, Inc.
|
||||
;; Contributed by Red Hat.
|
||||
;;
|
||||
;; This file is part of GCC.
|
||||
;;
|
||||
;; GCC 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.
|
||||
;;
|
||||
;; GCC 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 GCC; see the file COPYING. If not, write to the Free
|
||||
;; Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
;; 02110-1301, USA.
|
||||
|
||||
;; move, push, extend, etc.
|
||||
|
||||
;; Be careful to never create an alternative that has memory as both
|
||||
;; src and dest, as that makes gcc think that mem-mem moves in general
|
||||
;; are supported. While the chip does support this, it only has two
|
||||
;; address registers and sometimes gcc requires more than that. One
|
||||
;; example is code like this: a = *b where both a and b are spilled to
|
||||
;; the stack.
|
||||
|
||||
;; Match push/pop before mov.b for passing char as arg,
|
||||
;; e.g. stdlib/efgcvt.c.
|
||||
(define_insn "movqi_op"
|
||||
[(set (match_operand:QI 0 "mra_qi_operand"
|
||||
"=Rqi*Rmm, <, RqiSd*Rmm, SdSs, Rqi*Rmm, Sd")
|
||||
(match_operand:QI 1 "mrai_qi_operand"
|
||||
"iRqi*Rmm, iRqiSd*Rmm, >, iRqi*Rmm, SdSs, i"))]
|
||||
"m32c_mov_ok (operands, QImode)"
|
||||
"@
|
||||
mov.b\t%1,%0
|
||||
push.b\t%1
|
||||
pop.b\t%0
|
||||
mov.b\t%1,%0
|
||||
mov.b\t%1,%0
|
||||
mov.b\t%1,%0"
|
||||
[(set_attr "flags" "sz,*,*,sz,sz,sz")]
|
||||
)
|
||||
|
||||
(define_expand "movqi"
|
||||
[(set (match_operand:QI 0 "mra_qi_operand" "=RqiSd*Rmm")
|
||||
(match_operand:QI 1 "mrai_qi_operand" "iRqiSd*Rmm"))]
|
||||
""
|
||||
"if (m32c_prepare_move (operands, QImode)) DONE;"
|
||||
)
|
||||
|
||||
|
||||
(define_insn "movhi_op"
|
||||
[(set (match_operand:HI 0 "nonimmediate_operand"
|
||||
"=Rhi*Rmm, Sd, SdSs, *Rcr, RhiSd*Rmm, <, RhiSd*Rmm, <, *Rcr")
|
||||
(match_operand:HI 1 "general_operand"
|
||||
"iRhi*RmmSdSs, i, Rhi*Rmm, RhiSd*Rmm, *Rcr, iRhiSd*Rmm, >, *Rcr, >"))]
|
||||
"m32c_mov_ok (operands, HImode)"
|
||||
"@
|
||||
mov.w\t%1,%0
|
||||
mov.w\t%1,%0
|
||||
mov.w\t%1,%0
|
||||
ldc\t%1,%0
|
||||
stc\t%1,%0
|
||||
push.w\t%1
|
||||
pop.w\t%0
|
||||
pushc\t%1
|
||||
popc\t%0"
|
||||
[(set_attr "flags" "sz,sz,sz,*,*,*,*,*,*")]
|
||||
)
|
||||
|
||||
(define_expand "movhi"
|
||||
[(set (match_operand:HI 0 "nonimmediate_operand" "=RhiSd*Rmm")
|
||||
(match_operand:HI 1 "general_operand" "iRhiSd*Rmm"))]
|
||||
""
|
||||
"if (m32c_prepare_move (operands, HImode)) DONE;"
|
||||
)
|
||||
|
||||
|
||||
(define_insn "movpsi_op"
|
||||
[(set (match_operand:PSI 0 "nonimmediate_operand"
|
||||
"=Raa, SdRmmRpi, Rcl, RpiSd*Rmm, <, <, Rcl, Rsi*Rmm")
|
||||
(match_operand:PSI 1 "general_operand"
|
||||
"sIU3, iSdRmmRpi, iRpiSd*Rmm, Rcl, Rsi*Rmm, Rcl, >, >"))]
|
||||
"TARGET_A24 && m32c_mov_ok (operands, PSImode)"
|
||||
"@
|
||||
mov.l:s\t%1,%0
|
||||
mov.l\t%1,%0
|
||||
ldc\t%1,%0
|
||||
stc\t%1,%0
|
||||
push.l\t%1
|
||||
pushc\t%1
|
||||
popc\t%0
|
||||
#"
|
||||
[(set_attr "flags" "sz,sz,*,*,*,*,*,*")]
|
||||
)
|
||||
|
||||
|
||||
;; The intention here is to combine the add with the move to create an
|
||||
;; indexed move. GCC doesn't always figure this out itself.
|
||||
|
||||
(define_mode_macro QHSI [QI HI SI])
|
||||
(define_mode_macro HPSI [(HI "TARGET_A16") (PSI "TARGET_A24")])
|
||||
|
||||
(define_peephole2
|
||||
[(set (match_operand:HPSI 0 "register_operand" "")
|
||||
(plus:HPSI (match_operand:HPSI 1 "register_operand" "")
|
||||
(match_operand:HPSI 2 "immediate_operand" "")))
|
||||
(set (match_operand:QHSI 3 "nonimmediate_operand" "")
|
||||
(mem:QHSI (match_operand:HPSI 4 "register_operand" "")))]
|
||||
"REGNO (operands[0]) == REGNO (operands[1])
|
||||
&& REGNO (operands[0]) == REGNO (operands[4])
|
||||
&& dead_or_set_p (peep2_next_insn (1), operands[4])
|
||||
&& ! reg_mentioned_p (operands[0], operands[3])"
|
||||
[(set (match_dup 3)
|
||||
(mem:QHSI (plus:HPSI (match_dup 1)
|
||||
(match_dup 2))))]
|
||||
"")
|
||||
|
||||
(define_peephole2
|
||||
[(set (match_operand:HPSI 0 "register_operand" "")
|
||||
(plus:HPSI (match_operand:HPSI 1 "register_operand" "")
|
||||
(match_operand:HPSI 2 "immediate_operand" "")))
|
||||
(set (mem:QHSI (match_operand:HPSI 4 "register_operand" ""))
|
||||
(match_operand:QHSI 3 "general_operand" ""))]
|
||||
"REGNO (operands[0]) == REGNO (operands[1])
|
||||
&& REGNO (operands[0]) == REGNO (operands[4])
|
||||
&& dead_or_set_p (peep2_next_insn (1), operands[4])
|
||||
&& ! reg_mentioned_p (operands[0], operands[3])"
|
||||
[(set (mem:QHSI (plus:HPSI (match_dup 1)
|
||||
(match_dup 2)))
|
||||
(match_dup 3))]
|
||||
"")
|
||||
|
||||
|
||||
; Some PSI moves must be split.
|
||||
(define_split
|
||||
[(set (match_operand:PSI 0 "nonimmediate_operand" "")
|
||||
(match_operand:PSI 1 "general_operand" ""))]
|
||||
"reload_completed && m32c_split_psi_p (operands)"
|
||||
[(set (match_dup 2)
|
||||
(match_dup 3))
|
||||
(set (match_dup 4)
|
||||
(match_dup 5))]
|
||||
"m32c_split_move (operands, PSImode, 3);"
|
||||
)
|
||||
|
||||
(define_expand "movpsi"
|
||||
[(set (match_operand:PSI 0 "mras_operand" "")
|
||||
(match_operand:PSI 1 "mrasi_operand" ""))]
|
||||
""
|
||||
"if (m32c_prepare_move (operands, PSImode)) DONE;"
|
||||
)
|
||||
|
||||
|
||||
|
||||
(define_expand "movsi"
|
||||
[(set (match_operand:SI 0 "mras_operand" "=RsiSd*Rmm")
|
||||
(match_operand:SI 1 "mrasi_operand" "iRsiSd*Rmm"))]
|
||||
""
|
||||
"if (m32c_split_move (operands, SImode, 0)) DONE;"
|
||||
)
|
||||
|
||||
; All SI moves are split if TARGET_A16
|
||||
(define_insn_and_split "movsi_splittable"
|
||||
[(set (match_operand:SI 0 "mras_operand" "=Rsi<*Rmm,RsiSd*Rmm")
|
||||
(match_operand:SI 1 "mrasi_operand" "iRsiSd*Rmm,iRsi>*Rmm"))]
|
||||
"TARGET_A16"
|
||||
"#"
|
||||
"TARGET_A16 && reload_completed"
|
||||
[(pc)]
|
||||
"m32c_split_move (operands, SImode, 1); DONE;"
|
||||
)
|
||||
|
||||
; The movsi pattern doesn't always match because sometimes the modes
|
||||
; don't match.
|
||||
(define_insn "push_a01_l"
|
||||
[(set (mem:SI (pre_dec:PSI (reg:PSI SP_REGNO)))
|
||||
(match_operand 0 "a_operand" ""))]
|
||||
""
|
||||
"push.l\t%0"
|
||||
)
|
||||
|
||||
(define_insn "movsi_24"
|
||||
[(set (match_operand:SI 0 "mras_operand" "=Rsi*Rmm, Sd, RsiSd*Rmm, <")
|
||||
(match_operand:SI 1 "mrasi_operand" "iRsiSd*Rmm, iRsi*Rmm, >, iRsiRaaSd*Rmm"))]
|
||||
"TARGET_A24"
|
||||
"@
|
||||
mov.l\t%1,%0
|
||||
mov.l\t%1,%0
|
||||
#
|
||||
push.l\t%1"
|
||||
)
|
||||
|
||||
(define_expand "movdi"
|
||||
[(set (match_operand:DI 0 "mras_operand" "=RdiSd*Rmm")
|
||||
(match_operand:DI 1 "mrasi_operand" "iRdiSd*Rmm"))]
|
||||
""
|
||||
"if (m32c_split_move (operands, DImode, 0)) DONE;"
|
||||
)
|
||||
|
||||
(define_insn_and_split "movdi_splittable"
|
||||
[(set (match_operand:DI 0 "mras_operand" "=Rdi<*Rmm,RdiSd*Rmm")
|
||||
(match_operand:DI 1 "mrasi_operand" "iRdiSd*Rmm,iRdi>*Rmm"))]
|
||||
""
|
||||
"#"
|
||||
"reload_completed"
|
||||
[(pc)]
|
||||
"m32c_split_move (operands, DImode, 1); DONE;"
|
||||
)
|
||||
|
||||
|
||||
|
||||
|
||||
(define_insn "pushqi"
|
||||
[(set (mem:QI (pre_dec:PSI (reg:PSI SP_REGNO)))
|
||||
(match_operand:QI 0 "mrai_operand" "iRqiSd*Rmm"))]
|
||||
""
|
||||
"push.b\t%0"
|
||||
)
|
||||
|
||||
(define_expand "pushhi"
|
||||
[(set (mem:HI (pre_dec:PSI (reg:PSI SP_REGNO)))
|
||||
(match_operand:HI 0 "" ""))]
|
||||
""
|
||||
"if (TARGET_A16)
|
||||
gen_pushhi_16 (operands[0]);
|
||||
else
|
||||
gen_pushhi_24 (operands[0]);
|
||||
DONE;"
|
||||
)
|
||||
|
||||
(define_insn "pushhi_16"
|
||||
[(set (mem:HI (pre_dec:HI (reg:HI SP_REGNO)))
|
||||
(match_operand:HI 0 "mrai_operand" "iRhiSd*Rmm,Rcr"))]
|
||||
"TARGET_A16"
|
||||
"@
|
||||
push.w\t%0
|
||||
pushc\t%0"
|
||||
)
|
||||
|
||||
(define_insn "pushhi_24"
|
||||
[(set (mem:HI (pre_dec:PSI (reg:PSI SP_REGNO)))
|
||||
(match_operand:HI 0 "mrai_operand" "iRhiSd*Rmm"))]
|
||||
"TARGET_A24"
|
||||
"push.w\t%0"
|
||||
)
|
||||
|
||||
;(define_insn "pushpi"
|
||||
; [(set (mem:PSI (pre_dec:PSI (reg:PSI SP_REGNO)))
|
||||
; (match_operand:PI 0 "mrai_operand" "iRaa,Rcr"))]
|
||||
; "TARGET_A24"
|
||||
; "@
|
||||
; push.l\t%0
|
||||
; pushc\t%0"
|
||||
; )
|
||||
|
||||
(define_insn "pushsi"
|
||||
[(set (mem:SI (pre_dec:PSI (reg:PSI SP_REGNO)))
|
||||
(match_operand:SI 0 "mrai_operand" "iRsiSd*Rmm"))]
|
||||
"TARGET_A24"
|
||||
"push.l\t%0"
|
||||
)
|
||||
|
||||
(define_expand "pophi"
|
||||
[(set (match_operand:HI 0 "mra_operand" "=RhiSd*Rmm,Rcr")
|
||||
(mem:HI (post_inc:HI (reg:HI SP_REGNO))))]
|
||||
""
|
||||
"if (TARGET_A16)
|
||||
gen_pophi_16 (operands[0]);
|
||||
else
|
||||
gen_pophi_24 (operands[0]);
|
||||
DONE;"
|
||||
)
|
||||
|
||||
(define_insn "pophi_16"
|
||||
[(set (match_operand:HI 0 "mra_operand" "=RhiSd*Rmm,Rcr")
|
||||
(mem:HI (post_inc:HI (reg:HI SP_REGNO))))]
|
||||
"TARGET_A16"
|
||||
"@
|
||||
pop.w\t%0
|
||||
popc\t%0"
|
||||
)
|
||||
|
||||
(define_insn "pophi_24"
|
||||
[(set (match_operand:HI 0 "mra_operand" "=RhiSd*Rmm")
|
||||
(mem:HI (post_inc:PSI (reg:PSI SP_REGNO))))]
|
||||
"TARGET_A24"
|
||||
"pop.w\t%0"
|
||||
)
|
||||
|
||||
(define_insn "poppsi"
|
||||
[(set (match_operand:PSI 0 "cr_operand" "=Rcl")
|
||||
(mem:PSI (post_inc:PSI (reg:PSI SP_REGNO))))]
|
||||
"TARGET_A24"
|
||||
"popc\t%0"
|
||||
)
|
||||
|
||||
|
||||
;; Rhl used here as an HI-mode Rxl
|
||||
(define_insn "extendqihi2"
|
||||
[(set (match_operand:HI 0 "mra_operand" "=RhlSd*Rmm")
|
||||
(sign_extend:HI (match_operand:QI 1 "mra_operand" "0")))]
|
||||
""
|
||||
"exts.b\t%1"
|
||||
[(set_attr "flags" "sz")]
|
||||
)
|
||||
|
||||
(define_insn "extendhisi2"
|
||||
[(set (match_operand:SI 0 "r0123_operand" "=R03")
|
||||
(sign_extend:SI (match_operand:HI 1 "r0123_operand" "0")))]
|
||||
""
|
||||
"*
|
||||
if (REGNO(operands[0]) == 0) return \"exts.w\t%1\";
|
||||
else return \"mov.w r1,r3 | sha.w #-8,r3 | sha.w #-7,r3\";"
|
||||
[(set_attr "flags" "sz")]
|
||||
)
|
||||
|
||||
(define_insn "extendpsisi2"
|
||||
[(set (match_operand:SI 0 "mr_operand" "=R03Sd*Rmm")
|
||||
(sign_extend:SI (match_operand:PSI 1 "mr_operand" "0")))]
|
||||
""
|
||||
"; expand psi %1 to si %0"
|
||||
)
|
||||
|
||||
(define_insn "zero_extendpsisi2"
|
||||
[(set (match_operand:SI 0 "mr_operand" "=R03Sd*Rmm")
|
||||
(zero_extend:SI (match_operand:PSI 1 "mr_operand" "0")))]
|
||||
""
|
||||
"; expand psi %1 to si %0"
|
||||
)
|
||||
|
||||
(define_insn "zero_extendhipsi2"
|
||||
[(set (match_operand:PSI 0 "nonimmediate_operand" "=Raa")
|
||||
(truncate:PSI (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "Rhi"))))]
|
||||
""
|
||||
"mov.w\t%1,%0"
|
||||
)
|
||||
|
||||
(define_insn "zero_extendhisi2"
|
||||
[(set (match_operand:SI 0 "nonimmediate_operand" "=RsiSd")
|
||||
(zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0")))]
|
||||
""
|
||||
"mov.w\t#0,%H0"
|
||||
)
|
||||
|
||||
(define_insn "zero_extendqihi2"
|
||||
[(set (match_operand:HI 0 "nonimmediate_operand" "=RsiRaaSd*Rmm")
|
||||
(zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0")))]
|
||||
""
|
||||
"and.w\t#255,%0"
|
||||
)
|
||||
|
||||
(define_insn "truncsipsi2_16"
|
||||
[(set (match_operand:PSI 0 "nonimmediate_operand" "=RsiRadSd*Rmm,Raa,Rcr,RsiSd*Rmm")
|
||||
(truncate:PSI (match_operand:SI 1 "nonimmediate_operand" "0,RsiSd*Rmm,RsiSd*Rmm,Rcr")))]
|
||||
"TARGET_A16"
|
||||
"@
|
||||
; no-op trunc si %1 to psi %0
|
||||
#
|
||||
ldc\t%1,%0
|
||||
stc\t%1,%0"
|
||||
)
|
||||
|
||||
(define_insn "trunchiqi2"
|
||||
[(set (match_operand:QI 0 "mra_qi_operand" "=RqiRmmSd")
|
||||
(truncate:QI (match_operand:HI 1 "mra_qi_operand" "0")))]
|
||||
""
|
||||
"; no-op trunc hi %1 to qi %0"
|
||||
)
|
||||
|
||||
(define_insn "truncsipsi2_24"
|
||||
[(set (match_operand:PSI 0 "nonimmediate_operand" "=RsiSd*Rmm,Raa,!Rcl,RsiSd*Rmm")
|
||||
(truncate:PSI (match_operand:SI 1 "nonimmediate_operand" "0,RsiSd*Rmm,RsiSd*Rmm,!Rcl")))]
|
||||
"TARGET_A24"
|
||||
"@
|
||||
; no-op trunc si %1 to psi %0
|
||||
mov.l\t%1,%0
|
||||
ldc\t%1,%0
|
||||
stc\t%1,%0"
|
||||
)
|
||||
|
||||
(define_expand "truncsipsi2"
|
||||
[(set (match_operand:PSI 0 "nonimmediate_operand" "=RsiRadSd*Rmm,Raa,Rcr,RsiSd*Rmm")
|
||||
(truncate:PSI (match_operand:SI 1 "nonimmediate_operand" "0,RsiSd*Rmm,RsiSd*Rmm,Rcr")))]
|
||||
""
|
||||
""
|
||||
)
|
||||
|
||||
(define_expand "reload_inqi"
|
||||
[(set (match_operand:QI 2 "" "=&Rqi")
|
||||
(match_operand:QI 1 "" ""))
|
||||
(set (match_operand:QI 0 "" "")
|
||||
(match_dup 2))
|
||||
]
|
||||
""
|
||||
"")
|
||||
|
||||
(define_expand "reload_outqi"
|
||||
[(set (match_operand:QI 2 "" "=&Rqi")
|
||||
(match_operand:QI 1 "" ""))
|
||||
(set (match_operand:QI 0 "" "")
|
||||
(match_dup 2))
|
||||
]
|
||||
""
|
||||
"")
|
||||
|
||||
(define_expand "reload_inhi"
|
||||
[(set (match_operand:HI 2 "" "=&Rhi")
|
||||
(match_operand:HI 1 "" ""))
|
||||
(set (match_operand:HI 0 "" "")
|
||||
(match_dup 2))
|
||||
]
|
||||
""
|
||||
"")
|
||||
|
||||
(define_expand "reload_outhi"
|
||||
[(set (match_operand:HI 2 "" "=&Rhi")
|
||||
(match_operand:HI 1 "" ""))
|
||||
(set (match_operand:HI 0 "" "")
|
||||
(match_dup 2))
|
||||
]
|
||||
""
|
||||
"")
|
236
gcc/config/m32c/muldiv.md
Normal file
236
gcc/config/m32c/muldiv.md
Normal file
@ -0,0 +1,236 @@
|
||||
;; Machine Descriptions for R8C/M16C/M32C
|
||||
;; Copyright (C) 2005
|
||||
;; Free Software Foundation, Inc.
|
||||
;; Contributed by Red Hat.
|
||||
;;
|
||||
;; This file is part of GCC.
|
||||
;;
|
||||
;; GCC 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.
|
||||
;;
|
||||
;; GCC 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 GCC; see the file COPYING. If not, write to the Free
|
||||
;; Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
;; 02110-1301, USA.
|
||||
|
||||
;; multiply and divide
|
||||
|
||||
; Here is the pattern for the const_int.
|
||||
(define_insn "mulqihi3_c"
|
||||
[(set (match_operand:HI 0 "mra_operand" "=RhiSd,??Rmm")
|
||||
(mult:HI (sign_extend:HI (match_operand:QI 1 "mra_operand" "%0,0"))
|
||||
(match_operand 2 "immediate_operand" "i,i")))]
|
||||
""
|
||||
"mul.b\t%2,%1"
|
||||
)
|
||||
|
||||
; Here is the pattern for registers and such.
|
||||
(define_insn "mulqihi3_r"
|
||||
[(set (match_operand:HI 0 "mra_operand" "=RhiSd,RhiSd,??Rmm,??Rmm,Raa,Raa")
|
||||
(mult:HI (sign_extend:HI (match_operand:QI 1 "mra_operand" "%0,0,0,0,0,0"))
|
||||
(sign_extend:HI (match_operand:QI 2 "mra_operand" "RqiSd,?Rmm,RqiSd,?Rmm,RhlSd,?Rmm"))))]
|
||||
""
|
||||
"mul.b\t%2,%1"
|
||||
)
|
||||
|
||||
; Don't try to sign_extend a const_int. Same for all other multiplies.
|
||||
(define_expand "mulqihi3"
|
||||
[(set (match_operand:HI 0 "mra_operand" "=RhiSd,RhiSd,??Rmm,??Rmm,Raa,Raa")
|
||||
(mult:HI (sign_extend:HI (match_operand:QI 1 "mra_operand" "%0,0,0,0,0,0"))
|
||||
(match_operand:QI 2 "mra_operand" "RqiSd,?Rmm,RqiSd,?Rmm,RhlSd,?Rmm")))]
|
||||
""
|
||||
"{ if (GET_MODE (operands[2]) != VOIDmode)
|
||||
operands[2] = gen_rtx_SIGN_EXTEND (HImode, operands[2]); }"
|
||||
)
|
||||
|
||||
(define_insn "umulqihi3_c"
|
||||
[(set (match_operand:HI 0 "mra_operand" "=RhiSd,??Rmm")
|
||||
(mult:HI (zero_extend:HI (match_operand:QI 1 "mra_operand" "%0,0"))
|
||||
(match_operand 2 "immediate_operand" "i,i")))]
|
||||
""
|
||||
"mulu.b\t%U2,%1"
|
||||
)
|
||||
|
||||
(define_insn "umulqihi3_r"
|
||||
[(set (match_operand:HI 0 "mra_operand" "=RhiSd,RhiSd,??Rmm,??Rmm,Raa,Raa")
|
||||
(mult:HI (zero_extend:HI (match_operand:QI 1 "mra_operand" "%0,0,0,0,0,0"))
|
||||
(zero_extend:HI (match_operand:QI 2 "mra_operand" "RqiSd,?Rmm,RqiSd,?Rmm,RhlSd,?Rmm"))))]
|
||||
""
|
||||
"mulu.b\t%U2,%1"
|
||||
)
|
||||
|
||||
(define_expand "umulqihi3"
|
||||
[(set (match_operand:HI 0 "mra_operand" "=RhiSd,RhiSd,??Rmm,??Rmm,Raa,Raa")
|
||||
(mult:HI (zero_extend:HI (match_operand:QI 1 "mra_operand" "%0,0,0,0,0,0"))
|
||||
(match_operand:QI 2 "mra_operand" "RqiSd,?Rmm,RqiSd,?Rmm,RhlSd,?Rmm")))]
|
||||
""
|
||||
"{ if (GET_MODE (operands[2]) != VOIDmode)
|
||||
operands[2] = gen_rtx_ZERO_EXTEND (HImode, operands[2]); }"
|
||||
)
|
||||
|
||||
(define_insn "mulhisi3_c"
|
||||
[(set (match_operand:SI 0 "mra_operand" "=RsiSd,??Rmm")
|
||||
(mult:SI (sign_extend:SI (match_operand:HI 1 "mra_operand" "%0,0"))
|
||||
(match_operand 2 "immediate_operand" "i,i")))]
|
||||
""
|
||||
"mul.w\t%2,%1"
|
||||
)
|
||||
|
||||
(define_insn "mulhisi3_r"
|
||||
[(set (match_operand:SI 0 "mra_operand" "=RsiSd,RsiSd,??Rmm,??Rmm")
|
||||
(mult:SI (sign_extend:SI (match_operand:HI 1 "mra_operand" "%0,0,0,0"))
|
||||
(sign_extend:SI (match_operand:HI 2 "mra_operand" "RhiSd,?Rmm,RhiSd,?Rmm"))))]
|
||||
""
|
||||
"mul.w\t%2,%1"
|
||||
)
|
||||
|
||||
(define_expand "mulhisi3"
|
||||
[(set (match_operand:SI 0 "mra_operand" "=RsiSd,RsiSd,??Rmm,??Rmm")
|
||||
(mult:SI (sign_extend:SI (match_operand:HI 1 "mra_operand" "%0,0,0,0"))
|
||||
(match_operand:HI 2 "mra_operand" "RhiSd,?Rmm,RhiSd,?Rmm")))]
|
||||
""
|
||||
"{ if (GET_MODE (operands[2]) != VOIDmode)
|
||||
operands[2] = gen_rtx_SIGN_EXTEND (SImode, operands[2]); }"
|
||||
)
|
||||
|
||||
(define_insn "umulhisi3_c"
|
||||
[(set (match_operand:SI 0 "mra_operand" "=RsiSd,??Rmm")
|
||||
(mult:SI (zero_extend:SI (match_operand:HI 1 "mra_operand" "%0,0"))
|
||||
(match_operand 2 "immediate_operand" "i,i")))]
|
||||
""
|
||||
"mulu.w\t%u2,%1"
|
||||
)
|
||||
|
||||
(define_insn "umulhisi3_r"
|
||||
[(set (match_operand:SI 0 "mra_operand" "=RsiSd,RsiSd,??Rmm,??Rmm")
|
||||
(mult:SI (zero_extend:SI (match_operand:HI 1 "mra_operand" "%0,0,0,0"))
|
||||
(zero_extend:SI (match_operand:HI 2 "mra_operand" "RhiSd,?Rmm,RhiSd,?Rmm"))))]
|
||||
""
|
||||
"mulu.w\t%u2,%1"
|
||||
)
|
||||
|
||||
(define_expand "umulhisi3"
|
||||
[(set (match_operand:SI 0 "mra_operand" "=RsiSd,RsiSd,??Rmm,??Rmm")
|
||||
(mult:SI (zero_extend:SI (match_operand:HI 1 "mra_operand" "%0,0,0,0"))
|
||||
(match_operand:HI 2 "mra_operand" "RhiSd,?Rmm,RhiSd,?Rmm")))]
|
||||
""
|
||||
"{ if (GET_MODE (operands[2]) != VOIDmode)
|
||||
operands[2] = gen_rtx_ZERO_EXTEND (SImode, operands[2]); }"
|
||||
)
|
||||
|
||||
|
||||
; GCC expects to be able to multiply pointer-sized integers too, but
|
||||
; fortunately it only multiplies by powers of two.
|
||||
(define_insn "mulpsi3"
|
||||
[(set (match_operand:PSI 0 "mra_operand" "=RsiSd")
|
||||
(mult:PSI (match_operand:PSI 1 "mra_operand" "%0")
|
||||
(match_operand 2 "const_int_operand" "Ilb")))]
|
||||
"TARGET_A24"
|
||||
"shl.l\t%b2,%0"
|
||||
[(set_attr "flags" "szc")]
|
||||
)
|
||||
|
||||
|
||||
|
||||
(define_expand "divmodqi4"
|
||||
[(set (match_dup 4)
|
||||
(sign_extend:HI (match_operand:QI 1 "register_operand" "0,0")))
|
||||
(parallel [(set (match_operand:QI 0 "register_operand" "=R0w,R0w")
|
||||
(div:QI (match_dup 4)
|
||||
(match_operand:QI 2 "general_operand" "iRqiSd,?Rmm")))
|
||||
(set (match_operand:QI 3 "register_operand" "=&R0h,&R0h")
|
||||
(mod:QI (match_dup 4) (match_dup 2)))
|
||||
])]
|
||||
"0"
|
||||
"operands[4] = gen_reg_rtx (HImode);"
|
||||
)
|
||||
|
||||
(define_insn "divmodqi4_n"
|
||||
[(set (match_operand:QI 0 "register_operand" "=R0l,R0l")
|
||||
(div:QI (match_operand:HI 1 "register_operand" "R0w,R0w")
|
||||
(match_operand:QI 2 "general_operand" "iRqiSd,?Rmm")))
|
||||
(set (match_operand:QI 3 "register_operand" "=R0h,R0h")
|
||||
(mod:QI (match_dup 1) (match_dup 2)))
|
||||
]
|
||||
"0"
|
||||
"div.b\t%2"
|
||||
)
|
||||
|
||||
(define_expand "udivmodqi4"
|
||||
[(set (match_dup 4)
|
||||
(zero_extend:HI (match_operand:QI 1 "register_operand" "0,0")))
|
||||
(parallel [(set (match_operand:QI 0 "register_operand" "=R0l,R0l")
|
||||
(udiv:QI (match_dup 4)
|
||||
(match_operand:QI 2 "general_operand" "iRqiSd,?Rmm")))
|
||||
(set (match_operand:QI 3 "register_operand" "=&R0h,&R0h")
|
||||
(umod:QI (match_dup 4) (match_dup 2)))
|
||||
])]
|
||||
"0"
|
||||
"operands[4] = gen_reg_rtx (HImode);"
|
||||
)
|
||||
|
||||
(define_insn "udivmodqi4_n"
|
||||
[(set (match_operand:QI 0 "register_operand" "=R0l,R0l")
|
||||
(udiv:QI (match_operand:HI 1 "register_operand" "R0w,R0w")
|
||||
(match_operand:QI 2 "general_operand" "iRqiSd,?Rmm")))
|
||||
(set (match_operand:QI 3 "register_operand" "=R0h,R0h")
|
||||
(umod:QI (match_dup 1) (match_dup 2)))
|
||||
]
|
||||
"0"
|
||||
"divu.b\t%2"
|
||||
)
|
||||
|
||||
(define_expand "divmodhi4"
|
||||
[(set (match_dup 4)
|
||||
(sign_extend:SI (match_operand:HI 1 "register_operand" "0,0")))
|
||||
(parallel [(set (match_operand:HI 0 "register_operand" "=R0w,R0w")
|
||||
(div:HI (match_dup 4)
|
||||
(match_operand:HI 2 "general_operand" "iRhiSd,?Rmm")))
|
||||
(set (match_operand:HI 3 "register_operand" "=R2w,R2w")
|
||||
(mod:HI (match_dup 4) (match_dup 2)))
|
||||
])]
|
||||
""
|
||||
"operands[4] = gen_reg_rtx (SImode);"
|
||||
)
|
||||
|
||||
(define_insn "divmodhi4_n"
|
||||
[(set (match_operand:HI 0 "m32c_r0_operand" "=R0w,R0w")
|
||||
(div:HI (match_operand:SI 1 "m32c_r0_operand" "R02,R02")
|
||||
(match_operand:HI 2 "m32c_notr2_operand" "iR1wR3wRaaSd,?Rmm")))
|
||||
(set (match_operand:HI 3 "m32c_r2_operand" "=R2w,R2w")
|
||||
(mod:HI (match_dup 1) (match_dup 2)))
|
||||
]
|
||||
""
|
||||
"div.w\t%2"
|
||||
)
|
||||
|
||||
(define_expand "udivmodhi4"
|
||||
[(set (match_dup 4)
|
||||
(zero_extend:SI (match_operand:HI 1 "register_operand" "0,0")))
|
||||
(parallel [(set (match_operand:HI 0 "register_operand" "=R0w,R0w")
|
||||
(udiv:HI (match_dup 4)
|
||||
(match_operand:HI 2 "general_operand" "iRhiSd,?Rmm")))
|
||||
(set (match_operand:HI 3 "register_operand" "=R2w,R2w")
|
||||
(umod:HI (match_dup 4) (match_dup 2)))
|
||||
])]
|
||||
""
|
||||
"operands[4] = gen_reg_rtx (SImode);"
|
||||
)
|
||||
|
||||
(define_insn "udivmodhi4_n"
|
||||
[(set (match_operand:HI 0 "m32c_r0_operand" "=R0w,R0w")
|
||||
(udiv:HI (match_operand:SI 1 "m32c_r0_operand" "R02,R02")
|
||||
(match_operand:HI 2 "m32c_notr2_operand" "iR1wR3wRaaSd,?Rmm")))
|
||||
(set (match_operand:HI 3 "m32c_r2_operand" "=R2w,R2w")
|
||||
(umod:HI (match_dup 1) (match_dup 2)))
|
||||
]
|
||||
""
|
||||
"divu.w\t%2"
|
||||
)
|
197
gcc/config/m32c/predicates.md
Normal file
197
gcc/config/m32c/predicates.md
Normal file
@ -0,0 +1,197 @@
|
||||
;; Machine Descriptions for R8C/M16C/M32C
|
||||
;; Copyright (C) 2005
|
||||
;; Free Software Foundation, Inc.
|
||||
;; Contributed by Red Hat.
|
||||
;;
|
||||
;; This file is part of GCC.
|
||||
;;
|
||||
;; GCC 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.
|
||||
;;
|
||||
;; GCC 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 GCC; see the file COPYING. If not, write to the Free
|
||||
;; Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
;; 02110-1301, USA.
|
||||
|
||||
;; Predicates
|
||||
|
||||
; TRUE if the operand is a pseudo-register.
|
||||
(define_predicate "m32c_pseudo"
|
||||
(ior (and (match_code "reg")
|
||||
(match_test "REGNO(op) >= FIRST_PSEUDO_REGISTER"))
|
||||
(and (match_code "subreg")
|
||||
(and (match_test "GET_CODE (XEXP (op, 0)) == REG")
|
||||
(match_test "REGNO(XEXP (op,0)) >= FIRST_PSEUDO_REGISTER")))))
|
||||
|
||||
|
||||
; Returning true causes many predicates to NOT match. We allow
|
||||
; subregs for type changing, but not for size changing.
|
||||
(define_predicate "m32c_wide_subreg"
|
||||
(and (match_code "subreg")
|
||||
(not (match_operand 0 "m32c_pseudo")))
|
||||
{
|
||||
unsigned int sizeo = GET_MODE_SIZE (GET_MODE (op));
|
||||
unsigned int sizei = GET_MODE_SIZE (GET_MODE (XEXP (op, 0)));
|
||||
sizeo = (sizeo + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
|
||||
sizei = (sizei + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
|
||||
return sizeo != sizei;
|
||||
})
|
||||
|
||||
; TRUE for r0 through r3, or a pseudo that reload could put in r0
|
||||
; through r3 (likewise for the next couple too)
|
||||
(define_predicate "r0123_operand"
|
||||
(ior (match_operand 0 "m32c_pseudo" "")
|
||||
(and (match_code "reg")
|
||||
(match_test "REGNO(op) <= R3_REGNO"))))
|
||||
|
||||
; TRUE for r0
|
||||
(define_predicate "m32c_r0_operand"
|
||||
(ior (match_operand 0 "m32c_pseudo" "")
|
||||
(and (match_code "reg")
|
||||
(match_test "REGNO(op) == R0_REGNO"))))
|
||||
|
||||
; TRUE for r1
|
||||
(define_predicate "m32c_r1_operand"
|
||||
(ior (match_operand 0 "m32c_pseudo" "")
|
||||
(and (match_code "reg")
|
||||
(match_test "REGNO(op) == R1_REGNO"))))
|
||||
|
||||
; TRUE for r2
|
||||
(define_predicate "m32c_r2_operand"
|
||||
(ior (match_operand 0 "m32c_pseudo" "")
|
||||
(and (match_code "reg")
|
||||
(match_test "REGNO(op) == R2_REGNO"))))
|
||||
|
||||
; TRUE for any general operand except r2.
|
||||
(define_predicate "m32c_notr2_operand"
|
||||
(and (match_operand 0 "general_operand")
|
||||
(ior (not (match_code "reg"))
|
||||
(match_test "REGNO(op) != R2_REGNO"))))
|
||||
|
||||
; TRUE for the stack pointer.
|
||||
(define_predicate "m32c_sp_operand"
|
||||
(ior (match_operand 0 "m32c_pseudo" "")
|
||||
(and (match_code "reg")
|
||||
(match_test "REGNO(op) == SP_REGNO"))))
|
||||
|
||||
; TRUE for control registers.
|
||||
(define_predicate "cr_operand"
|
||||
(match_code "reg")
|
||||
"return (REGNO (op) >= SB_REGNO
|
||||
&& REGNO (op) <= FLG_REGNO);")
|
||||
|
||||
; TRUE for $a0 or $a1.
|
||||
(define_predicate "a_operand"
|
||||
(match_code "reg")
|
||||
"return (REGNO (op) == A0_REGNO
|
||||
|| REGNO (op) == A1_REGNO);")
|
||||
|
||||
; TRUE for r0 through r3, or a0 or a1.
|
||||
(define_predicate "ra_operand"
|
||||
(and (and (match_operand 0 "register_operand" "")
|
||||
(not (match_operand 1 "cr_operand" "")))
|
||||
(not (match_operand 2 "m32c_wide_subreg" ""))))
|
||||
|
||||
; Likewise, plus TRUE for memory references.
|
||||
(define_predicate "mra_operand"
|
||||
(and (and (match_operand 0 "nonimmediate_operand" "")
|
||||
(not (match_operand 1 "cr_operand" "")))
|
||||
(not (match_operand 2 "m32c_wide_subreg" ""))))
|
||||
|
||||
; Likewise, plus TRUE for subregs.
|
||||
(define_predicate "mras_operand"
|
||||
(and (match_operand 0 "nonimmediate_operand" "")
|
||||
(not (match_operand 1 "cr_operand" ""))))
|
||||
|
||||
; TRUE for memory, r0..r3, a0..a1, or immediates.
|
||||
(define_predicate "mrai_operand"
|
||||
(and (and (match_operand 0 "general_operand" "")
|
||||
(not (match_operand 1 "cr_operand" "")))
|
||||
(not (match_operand 2 "m32c_wide_subreg" ""))))
|
||||
|
||||
; Likewise, plus true for subregs.
|
||||
(define_predicate "mrasi_operand"
|
||||
(and (match_operand 0 "general_operand" "")
|
||||
(not (match_operand 1 "cr_operand" ""))))
|
||||
|
||||
; TRUE for r0..r3 or memory.
|
||||
(define_predicate "mr_operand"
|
||||
(and (match_operand 0 "mra_operand" "")
|
||||
(not (match_operand 1 "a_operand" ""))))
|
||||
|
||||
; TRUE for r1h. This complicated since r1h isn't a register GCC
|
||||
; normally knows about.
|
||||
(define_predicate "r1h_operand"
|
||||
(match_code "zero_extract")
|
||||
{
|
||||
rtx reg = XEXP (op, 0);
|
||||
rtx size = XEXP (op, 1);
|
||||
rtx pos = XEXP (op, 2);
|
||||
return (GET_CODE (reg) == REG
|
||||
&& REGNO (reg) == R1_REGNO
|
||||
&& GET_CODE (size) == CONST_INT
|
||||
&& INTVAL (size) == 8
|
||||
&& GET_CODE (pos) == CONST_INT
|
||||
&& INTVAL (pos) == 8);
|
||||
})
|
||||
|
||||
; TRUE if we can shift by this amount. Constant shift counts have a
|
||||
; limited range.
|
||||
(define_predicate "shiftcount_operand"
|
||||
(ior (match_operand 0 "m32c_pseudo" "")
|
||||
(and (match_operand 2 "const_int_operand" "")
|
||||
(match_test "-8 <= INTVAL (op) && INTVAL (op) && INTVAL (op) <= 8"))))
|
||||
|
||||
; TRUE for r0..r3, a0..a1, or sp.
|
||||
(define_predicate "mra_or_sp_operand"
|
||||
(and (ior (match_operand 0 "mra_operand")
|
||||
(match_operand 1 "m32c_sp_operand"))
|
||||
(not (match_operand 2 "m32c_wide_subreg" ""))))
|
||||
|
||||
|
||||
; TRUE for r2 or r3.
|
||||
(define_predicate "m32c_r2r3_operand"
|
||||
(ior (and (match_code "reg")
|
||||
(ior (match_test "REGNO(op) == R2_REGNO")
|
||||
(match_test "REGNO(op) == R3_REGNO")))
|
||||
(and (match_code "subreg")
|
||||
(match_test "GET_CODE (XEXP (op, 0)) == REG && (REGNO (XEXP (op, 0)) == R2_REGNO || REGNO (XEXP (op, 0)) == R3_REGNO)"))))
|
||||
|
||||
; Likewise, plus TRUE for a0..a1.
|
||||
(define_predicate "m32c_r2r3a_operand"
|
||||
(ior (match_operand 0 "m32c_r2r3_operand" "")
|
||||
(match_operand 0 "a_operand" "")))
|
||||
|
||||
; These two are only for movqi - no subreg limit
|
||||
(define_predicate "mra_qi_operand"
|
||||
(and (and (match_operand 0 "nonimmediate_operand" "")
|
||||
(not (match_operand 1 "cr_operand" "")))
|
||||
(not (match_operand 1 "m32c_r2r3a_operand" ""))))
|
||||
|
||||
(define_predicate "mrai_qi_operand"
|
||||
(and (and (match_operand 0 "general_operand" "")
|
||||
(not (match_operand 1 "cr_operand" "")))
|
||||
(not (match_operand 1 "m32c_r2r3a_operand" ""))))
|
||||
|
||||
; TRUE for comparisons we support.
|
||||
(define_predicate "m32c_cmp_operator"
|
||||
(match_code "eq,ne,gt,gtu,lt,ltu,ge,geu,le,leu"))
|
||||
|
||||
; TRUE for mem0
|
||||
(define_predicate "m32c_mem0_operand"
|
||||
(ior (match_operand 0 "m32c_pseudo" "")
|
||||
(and (match_code "reg")
|
||||
(match_test "REGNO(op) == MEM0_REGNO"))))
|
||||
|
||||
; TRUE for things the call patterns can return.
|
||||
(define_predicate "m32c_return_operand"
|
||||
(ior (match_operand 0 "m32c_r0_operand")
|
||||
(ior (match_operand 0 "m32c_mem0_operand")
|
||||
(match_code "parallel"))))
|
139
gcc/config/m32c/prologue.md
Normal file
139
gcc/config/m32c/prologue.md
Normal file
@ -0,0 +1,139 @@
|
||||
;; Machine Descriptions for R8C/M16C/M32C
|
||||
;; Copyright (C) 2005
|
||||
;; Free Software Foundation, Inc.
|
||||
;; Contributed by Red Hat.
|
||||
;;
|
||||
;; This file is part of GCC.
|
||||
;;
|
||||
;; GCC 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.
|
||||
;;
|
||||
;; GCC 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 GCC; see the file COPYING. If not, write to the Free
|
||||
;; Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
;; 02110-1301, USA.
|
||||
|
||||
;; Prologue and epilogue patterns
|
||||
|
||||
(define_expand "prologue"
|
||||
[(const_int 1)]
|
||||
""
|
||||
"m32c_emit_prologue(); DONE;"
|
||||
)
|
||||
|
||||
; For the next two, operands[0] is the amount of stack space we want
|
||||
; to reserve.
|
||||
|
||||
; We assume dwarf2out will process each set in sequence.
|
||||
(define_insn "prologue_enter_16"
|
||||
[(set (mem:HI (pre_dec:HI (reg:HI SP_REGNO)))
|
||||
(reg:HI FB_REGNO))
|
||||
(set (reg:HI FB_REGNO)
|
||||
(reg:HI SP_REGNO))
|
||||
(set (reg:HI SP_REGNO)
|
||||
(minus:HI (reg:HI SP_REGNO)
|
||||
(match_operand 0 "const_int_operand" "i")))
|
||||
]
|
||||
"TARGET_A16"
|
||||
"enter\t%0"
|
||||
)
|
||||
|
||||
(define_insn "prologue_enter_24"
|
||||
[(set (mem:SI (pre_dec:PSI (reg:PSI SP_REGNO)))
|
||||
(reg:SI FB_REGNO))
|
||||
(set (reg:PSI FB_REGNO)
|
||||
(reg:PSI SP_REGNO))
|
||||
(set (reg:PSI SP_REGNO)
|
||||
(minus:PSI (reg:PSI SP_REGNO)
|
||||
(match_operand 0 "const_int_operand" "i")))
|
||||
]
|
||||
"TARGET_A24"
|
||||
"enter\t%0"
|
||||
)
|
||||
|
||||
; Just a comment, for debugging the assembler output.
|
||||
(define_insn "prologue_end"
|
||||
[(unspec_volatile [(const_int 0)] UNS_PROLOGUE_END)]
|
||||
""
|
||||
"; end of prologue"
|
||||
)
|
||||
|
||||
|
||||
|
||||
(define_expand "epilogue"
|
||||
[(const_int 1)]
|
||||
""
|
||||
"m32c_emit_epilogue(); DONE;"
|
||||
)
|
||||
|
||||
(define_expand "eh_return"
|
||||
[(match_operand:PSI 0 "" "")]
|
||||
""
|
||||
"m32c_emit_eh_epilogue(operands[0]); DONE;"
|
||||
)
|
||||
|
||||
(define_insn "eh_epilogue"
|
||||
[(set (pc)
|
||||
(unspec_volatile [(match_operand 0 "m32c_r1_operand" "")
|
||||
(match_operand 1 "m32c_r0_operand" "")
|
||||
] UNS_EH_EPILOGUE))]
|
||||
""
|
||||
"jmp.a\t__m32c_eh_return"
|
||||
)
|
||||
|
||||
(define_insn "epilogue_exitd"
|
||||
[(set (reg:PSI SP_REGNO)
|
||||
(reg:PSI FB_REGNO))
|
||||
(set (reg:PSI FB_REGNO)
|
||||
(mem:PSI (reg:PSI SP_REGNO)))
|
||||
(set (reg:PSI SP_REGNO)
|
||||
(plus:PSI (reg:PSI SP_REGNO)
|
||||
(match_operand 0 "const_int_operand" "i")))
|
||||
(return)
|
||||
]
|
||||
""
|
||||
"exitd"
|
||||
)
|
||||
|
||||
(define_insn "epilogue_reit"
|
||||
[(set (reg:PSI SP_REGNO)
|
||||
(plus:PSI (reg:PSI SP_REGNO)
|
||||
(match_operand 0 "const_int_operand" "i")))
|
||||
(return)
|
||||
]
|
||||
""
|
||||
"reit"
|
||||
)
|
||||
|
||||
(define_insn "epilogue_rts"
|
||||
[(return)
|
||||
]
|
||||
""
|
||||
"rts"
|
||||
)
|
||||
|
||||
(define_insn "epilogue_start"
|
||||
[(unspec_volatile [(const_int 0)] UNS_EPILOGUE_START)]
|
||||
""
|
||||
"; start of epilogue"
|
||||
)
|
||||
|
||||
|
||||
; These are used by the prologue/epilogue code.
|
||||
|
||||
(define_insn "pushm"
|
||||
[(unspec [(match_operand 0 "const_int_operand" "i")] UNS_PUSHM)]
|
||||
""
|
||||
"pushm\t%p0")
|
||||
|
||||
(define_insn "popm"
|
||||
[(unspec [(match_operand 0 "const_int_operand" "i")] UNS_POPM)]
|
||||
""
|
||||
"popm\t%p0")
|
299
gcc/config/m32c/shift.md
Normal file
299
gcc/config/m32c/shift.md
Normal file
@ -0,0 +1,299 @@
|
||||
;; Machine Descriptions for R8C/M16C/M32C
|
||||
;; Copyright (C) 2005
|
||||
;; Free Software Foundation, Inc.
|
||||
;; Contributed by Red Hat.
|
||||
;;
|
||||
;; This file is part of GCC.
|
||||
;;
|
||||
;; GCC 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.
|
||||
;;
|
||||
;; GCC 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 GCC; see the file COPYING. If not, write to the Free
|
||||
;; Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
;; 02110-1301, USA.
|
||||
|
||||
;; bit shifting
|
||||
|
||||
; Shifts are unusual for m32c. We only support shifting in one
|
||||
; "direction" but the shift count is signed. Also, immediate shift
|
||||
; counts have a limited range, and variable shift counts have to be in
|
||||
; $r1h which GCC normally doesn't even know about.
|
||||
|
||||
; Other than compensating for the above, the patterns below are pretty
|
||||
; straightforward.
|
||||
|
||||
(define_insn "ashlqi3_i"
|
||||
[(set (match_operand:QI 0 "mra_operand" "=RqiSd*Rmm,RqiSd*Rmm")
|
||||
(ashift:QI (match_operand:QI 1 "mra_operand" "0,0")
|
||||
(match_operand:QI 2 "mrai_operand" "In4,R1w")))
|
||||
(clobber (match_scratch:HI 3 "=X,R1w"))]
|
||||
""
|
||||
"@
|
||||
sha.b\t%2,%0
|
||||
mov.b\tr1l,r1h\n\tsha.b\tr1h,%0"
|
||||
)
|
||||
|
||||
(define_insn "ashrqi3_i"
|
||||
[(set (match_operand:QI 0 "mra_operand" "=RqiSd*Rmm,RqiSd*Rmm")
|
||||
(ashiftrt:QI (match_operand:QI 1 "mra_operand" "0,0")
|
||||
(neg:QI (match_operand:QI 2 "mrai_operand" "In4,R1w"))))
|
||||
(clobber (match_scratch:HI 3 "=X,R1w"))]
|
||||
""
|
||||
"@
|
||||
sha.b\t%2,%0
|
||||
mov.b\tr1l,r1h\n\tsha.b\tr1h,%0"
|
||||
)
|
||||
|
||||
(define_insn "lshlqi3_i"
|
||||
[(set (match_operand:QI 0 "mra_operand" "=RqiSd*Rmm,RqiSd*Rmm")
|
||||
(lshiftrt:QI (match_operand:QI 1 "mra_operand" "0,0")
|
||||
(neg:QI (match_operand:QI 2 "mrai_operand" "In4,R1w"))))
|
||||
(clobber (match_scratch:HI 3 "=X,R1w"))]
|
||||
""
|
||||
"@
|
||||
shl.b\t%2,%0
|
||||
mov.b\tr1l,r1h\n\tshl.b\tr1h,%0"
|
||||
)
|
||||
|
||||
|
||||
(define_expand "ashlqi3"
|
||||
[(parallel [(set (match_operand:QI 0 "mra_operand" "")
|
||||
(ashift:QI (match_operand:QI 1 "mra_operand" "")
|
||||
(match_operand:QI 2 "general_operand" "")))
|
||||
(clobber (match_scratch:HI 3 ""))])]
|
||||
""
|
||||
"if (m32c_prepare_shift (operands, 1, 4))
|
||||
DONE;"
|
||||
)
|
||||
|
||||
(define_expand "ashrqi3"
|
||||
[(parallel [(set (match_operand:QI 0 "mra_operand" "")
|
||||
(ashiftrt:QI (match_operand:QI 1 "mra_operand" "")
|
||||
(neg:QI (match_operand:QI 2 "general_operand" ""))))
|
||||
(clobber (match_scratch:HI 3 ""))])]
|
||||
""
|
||||
"if (m32c_prepare_shift (operands, -1, 4))
|
||||
DONE;"
|
||||
)
|
||||
|
||||
(define_expand "lshrqi3"
|
||||
[(parallel [(set (match_operand:QI 0 "mra_operand" "")
|
||||
(lshiftrt:QI (match_operand:QI 1 "mra_operand" "")
|
||||
(neg:QI (match_operand:QI 2 "general_operand" ""))))
|
||||
(clobber (match_scratch:HI 3 ""))])]
|
||||
""
|
||||
"if (m32c_prepare_shift (operands, -1, 4))
|
||||
DONE;"
|
||||
)
|
||||
|
||||
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
||||
(define_insn "ashlhi3_i"
|
||||
[(set (match_operand:HI 0 "mra_operand" "=SdRhi*Rmm,SdRhi*Rmm")
|
||||
(ashift:HI (match_operand:HI 1 "mra_operand" "0,0")
|
||||
(match_operand:QI 2 "mrai_operand" "In4,R1w")))
|
||||
(clobber (match_scratch:HI 3 "=X,R1w"))]
|
||||
""
|
||||
"@
|
||||
sha.w\t%2,%0
|
||||
mov.b\tr1l,r1h\n\tsha.w\tr1h,%0"
|
||||
)
|
||||
|
||||
(define_insn "ashrhi3_i"
|
||||
[(set (match_operand:HI 0 "mra_operand" "=SdRhi*Rmm,SdRhi*Rmm")
|
||||
(ashiftrt:HI (match_operand:HI 1 "mra_operand" "0,0")
|
||||
(neg:QI (match_operand:QI 2 "mrai_operand" "In4,R1w"))))
|
||||
(clobber (match_scratch:HI 3 "=X,R1w"))]
|
||||
""
|
||||
"@
|
||||
sha.w\t%2,%0
|
||||
mov.b\tr1l,r1h\n\tsha.w\tr1h,%0"
|
||||
)
|
||||
|
||||
(define_insn "lshlhi3_i"
|
||||
[(set (match_operand:HI 0 "mra_operand" "=RhiSd*Rmm,RhiSd*Rmm")
|
||||
(lshiftrt:HI (match_operand:HI 1 "mra_operand" "0,0")
|
||||
(neg:QI (match_operand:QI 2 "mrai_operand" "In4,R1w"))))
|
||||
(clobber (match_scratch:HI 3 "=X,R1w"))]
|
||||
""
|
||||
"@
|
||||
shl.w\t%2,%0
|
||||
mov.b\tr1l,r1h\n\tshl.w\tr1h,%0"
|
||||
)
|
||||
|
||||
|
||||
(define_expand "ashlhi3"
|
||||
[(parallel [(set (match_operand:HI 0 "mra_operand" "")
|
||||
(ashift:HI (match_operand:HI 1 "mra_operand" "")
|
||||
(match_operand:QI 2 "general_operand" "")))
|
||||
(clobber (match_scratch:HI 3 ""))])]
|
||||
""
|
||||
"if (m32c_prepare_shift (operands, 1, 4))
|
||||
DONE;"
|
||||
)
|
||||
|
||||
(define_expand "ashrhi3"
|
||||
[(parallel [(set (match_operand:HI 0 "mra_operand" "")
|
||||
(ashiftrt:HI (match_operand:HI 1 "mra_operand" "")
|
||||
(neg:QI (match_operand:QI 2 "general_operand" ""))))
|
||||
(clobber (match_scratch:HI 3 ""))])]
|
||||
""
|
||||
"if (m32c_prepare_shift (operands, -1, 4))
|
||||
DONE;"
|
||||
)
|
||||
|
||||
(define_expand "lshrhi3"
|
||||
[(parallel [(set (match_operand:HI 0 "mra_operand" "")
|
||||
(lshiftrt:HI (match_operand:HI 1 "mra_operand" "")
|
||||
(neg:QI (match_operand:QI 2 "general_operand" ""))))
|
||||
(clobber (match_scratch:HI 3 ""))])]
|
||||
""
|
||||
"if (m32c_prepare_shift (operands, -1, 4))
|
||||
DONE;"
|
||||
)
|
||||
|
||||
|
||||
|
||||
|
||||
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
||||
|
||||
(define_insn "ashlpsi3_i"
|
||||
[(set (match_operand:PSI 0 "mra_operand" "=R02RaaSd*Rmm,R02RaaSd*Rmm")
|
||||
(ashift:PSI (match_operand:PSI 1 "mra_operand" "0,0")
|
||||
(match_operand:QI 2 "mrai_operand" "In4,R1w")))
|
||||
(clobber (match_scratch:HI 3 "=X,R1w"))]
|
||||
"TARGET_A24"
|
||||
"@
|
||||
sha.l\t%2,%0
|
||||
mov.b\tr1l,r1h\n\tsha.l\tr1h,%0"
|
||||
)
|
||||
|
||||
(define_insn "ashrpsi3_i"
|
||||
[(set (match_operand:PSI 0 "mra_operand" "=R02RaaSd*Rmm,R02RaaSd*Rmm")
|
||||
(ashiftrt:PSI (match_operand:PSI 1 "mra_operand" "0,0")
|
||||
(neg:QI (match_operand:QI 2 "mrai_operand" "In4,R1w"))))
|
||||
(clobber (match_scratch:HI 3 "=X,R1w"))]
|
||||
"TARGET_A24"
|
||||
"@
|
||||
sha.l\t%2,%0
|
||||
mov.b\tr1l,r1h\n\tsha.l\tr1h,%0"
|
||||
)
|
||||
|
||||
(define_insn "lshlpsi3_i"
|
||||
[(set (match_operand:PSI 0 "mra_operand" "=R02RaaSd,??Rmm")
|
||||
(lshiftrt:PSI (match_operand:PSI 1 "mra_operand" "0,0")
|
||||
(neg:QI (match_operand:QI 2 "shiftcount_operand" "In4,R1w"))))
|
||||
(clobber (match_scratch:HI 3 "=X,R1w"))]
|
||||
"TARGET_A24"
|
||||
"@
|
||||
shl.l\t%2,%0
|
||||
mov.b\tr1l,r1h\n\tshl.l\tr1h,%0"
|
||||
)
|
||||
|
||||
|
||||
(define_expand "ashlpsi3"
|
||||
[(parallel [(set (match_operand:PSI 0 "mra_operand" "")
|
||||
(ashift:PSI (match_operand:PSI 1 "mra_operand" "")
|
||||
(match_operand:QI 2 "mrai_operand" "")))
|
||||
(clobber (match_scratch:HI 3 ""))])]
|
||||
"TARGET_A24"
|
||||
"if (m32c_prepare_shift (operands, 1, 4))
|
||||
DONE;"
|
||||
)
|
||||
|
||||
(define_expand "ashrpsi3"
|
||||
[(parallel [(set (match_operand:PSI 0 "mra_operand" "")
|
||||
(ashiftrt:PSI (match_operand:PSI 1 "mra_operand" "")
|
||||
(neg:QI (match_operand:QI 2 "mrai_operand" ""))))
|
||||
(clobber (match_scratch:HI 3 ""))])]
|
||||
"TARGET_A24"
|
||||
"if (m32c_prepare_shift (operands, -1, 4))
|
||||
DONE;"
|
||||
)
|
||||
|
||||
(define_expand "lshrpsi3"
|
||||
[(parallel [(set (match_operand:PSI 0 "mra_operand" "")
|
||||
(lshiftrt:PSI (match_operand:PSI 1 "mra_operand" "")
|
||||
(neg:QI (match_operand:QI 2 "mrai_operand" ""))))
|
||||
(clobber (match_scratch:HI 3 ""))])]
|
||||
"TARGET_A24"
|
||||
"if (m32c_prepare_shift (operands, -1, 4))
|
||||
DONE;"
|
||||
)
|
||||
|
||||
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
||||
|
||||
|
||||
(define_insn "ashlsi3_i"
|
||||
[(set (match_operand:SI 0 "r0123_operand" "=R03,R03")
|
||||
(ashift:SI (match_operand:SI 1 "r0123_operand" "0,0")
|
||||
(match_operand:QI 2 "mrai_operand" "In4,R1w")))
|
||||
(clobber (match_scratch:HI 3 "=X,R1w"))]
|
||||
""
|
||||
"@
|
||||
sha.l\t%2,%0
|
||||
mov.b\tr1l,r1h\n\tsha.l\tr1h,%0"
|
||||
)
|
||||
|
||||
(define_insn "ashrsi3_i"
|
||||
[(set (match_operand:SI 0 "r0123_operand" "=R03,R03")
|
||||
(ashiftrt:SI (match_operand:SI 1 "r0123_operand" "0,0")
|
||||
(neg:QI (match_operand:QI 2 "mrai_operand" "In4,R1w"))))
|
||||
(clobber (match_scratch:HI 3 "=X,R1w"))]
|
||||
""
|
||||
"@
|
||||
sha.l\t%2,%0
|
||||
mov.b\tr1l,r1h\n\tsha.l\tr1h,%0"
|
||||
)
|
||||
|
||||
(define_insn "lshlsi3_i"
|
||||
[(set (match_operand:SI 0 "r0123_operand" "=R03,R03")
|
||||
(lshiftrt:SI (match_operand:SI 1 "r0123_operand" "0,0")
|
||||
(neg:QI (match_operand:QI 2 "mrai_operand" "In4,R1w"))))
|
||||
(clobber (match_scratch:HI 3 "=X,R1w"))]
|
||||
""
|
||||
"@
|
||||
shl.l\t%2,%0
|
||||
mov.b\tr1l,r1h\n\tshl.l\tr1h,%0"
|
||||
)
|
||||
|
||||
|
||||
(define_expand "ashlsi3"
|
||||
[(parallel [(set (match_operand:SI 0 "r0123_operand" "")
|
||||
(ashift:SI (match_operand:SI 1 "r0123_operand" "")
|
||||
(match_operand:QI 2 "mrai_operand" "")))
|
||||
(clobber (match_scratch:HI 3 ""))])]
|
||||
""
|
||||
"if (m32c_prepare_shift (operands, 1, 4))
|
||||
DONE;"
|
||||
)
|
||||
|
||||
(define_expand "ashrsi3"
|
||||
[(parallel [(set (match_operand:SI 0 "r0123_operand" "")
|
||||
(ashiftrt:SI (match_operand:SI 1 "r0123_operand" "")
|
||||
(neg:QI (match_operand:QI 2 "mrai_operand" ""))))
|
||||
(clobber (match_scratch:HI 3 ""))])]
|
||||
""
|
||||
"if (m32c_prepare_shift (operands, -1, 4))
|
||||
DONE;"
|
||||
)
|
||||
|
||||
(define_expand "lshrsi3"
|
||||
[(parallel [(set (match_operand:SI 0 "r0123_operand" "")
|
||||
(lshiftrt:SI (match_operand:SI 1 "r0123_operand" "")
|
||||
(neg:QI (match_operand:QI 2 "mrai_operand" ""))))
|
||||
(clobber (match_scratch:HI 3 ""))])]
|
||||
""
|
||||
"if (m32c_prepare_shift (operands, -1, 5))
|
||||
DONE;"
|
||||
)
|
70
gcc/config/m32c/t-m32c
Normal file
70
gcc/config/m32c/t-m32c
Normal file
@ -0,0 +1,70 @@
|
||||
# Target Makefile Fragment for R8C/M16C/M32C
|
||||
# Copyright (C) 2005
|
||||
# Free Software Foundation, Inc.
|
||||
# Contributed by Red Hat.
|
||||
#
|
||||
# This file is part of GCC.
|
||||
#
|
||||
# GCC 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.
|
||||
#
|
||||
# GCC 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 GCC; see the file COPYING. If not, write to the Free
|
||||
# Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
# 02110-1301, USA.
|
||||
|
||||
LIB1ASMSRC = m32c/m32c-lib1.S
|
||||
|
||||
LIB1ASMFUNCS = \
|
||||
__m32c_memregs \
|
||||
__m32c_eh_return \
|
||||
__m32c_mulsi3 \
|
||||
__m32c_cmpsi2 \
|
||||
__m32c_ucmpsi2 \
|
||||
__m32c_jsri16
|
||||
|
||||
LIB2FUNCS_EXTRA = $(srcdir)/config/m32c/m32c-lib2.c
|
||||
|
||||
# floating point emulation libraries
|
||||
|
||||
FPBIT = fp-bit.c
|
||||
DPBIT = dp-bit.c
|
||||
|
||||
fp-bit.c: $(srcdir)/config/fp-bit.c
|
||||
echo '#define FLOAT' > fp-bit.c
|
||||
cat $(srcdir)/config/fp-bit.c >> fp-bit.c
|
||||
|
||||
dp-bit.c: $(srcdir)/config/fp-bit.c
|
||||
cat $(srcdir)/config/fp-bit.c > dp-bit.c
|
||||
|
||||
# target-specific files
|
||||
|
||||
md_file = md
|
||||
|
||||
MD_FILES = m32c predicates addsub bitops cond jump minmax mov muldiv prologue shift
|
||||
|
||||
# Doing it this way lets the gen* programs report the right line numbers.
|
||||
|
||||
md : $(MD_FILES:%=$(srcdir)/config/m32c/%.md) $(srcdir)/config/m32c/t-m32c
|
||||
for md in $(MD_FILES); do \
|
||||
echo "(include \"$(srcdir)/config/m32c/$$md.md\")"; \
|
||||
done > md
|
||||
|
||||
m32c-pragma.o: $(srcdir)/config/m32c/m32c-pragma.c $(RTL_H) $(TREE_H) $(CONFIG_H)
|
||||
$(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $<
|
||||
|
||||
# We support four CPU series, but R8C and M16C share one multilib, and
|
||||
# M32C and M32CM share another.
|
||||
|
||||
MULTILIB_OPTIONS = mcpu=m32cm
|
||||
MULTILIB_DIRNAMES = m32cm
|
||||
MULTILIB_MATCHES = mcpu?m32cm=mcpu?m32c mcpu?r8c=mcpu?m16c
|
||||
|
||||
EXTRA_MULTILIB_PARTS = crtbegin.o crtend.o
|
@ -206,8 +206,8 @@ Bud Davis for work on the G77 and gfortran compilers.
|
||||
Mo DeJong for GCJ and libgcj bug fixes.
|
||||
|
||||
@item
|
||||
DJ Delorie for the DJGPP port, build and libiberty maintenance, and
|
||||
various bug fixes.
|
||||
DJ Delorie for the DJGPP port, build and libiberty maintenance,
|
||||
various bug fixes, and the M32C port.
|
||||
|
||||
@item
|
||||
Arnaud Desitter for helping to debug gfortran.
|
||||
|
@ -1887,10 +1887,10 @@ this attribute to work correctly.
|
||||
|
||||
@item interrupt
|
||||
@cindex interrupt handler functions
|
||||
Use this attribute on the ARM, AVR, C4x, M32R/D and Xstormy16 ports to indicate
|
||||
that the specified function is an interrupt handler. The compiler will
|
||||
generate function entry and exit sequences suitable for use in an
|
||||
interrupt handler when this attribute is present.
|
||||
Use this attribute on the ARM, AVR, C4x, M32C, M32R/D and Xstormy16
|
||||
ports to indicate that the specified function is an interrupt handler.
|
||||
The compiler will generate function entry and exit sequences suitable
|
||||
for use in an interrupt handler when this attribute is present.
|
||||
|
||||
Note, interrupt handlers for the Blackfin, m68k, H8/300, H8/300H, H8S, and
|
||||
SH processors can be specified via the @code{interrupt_handler} attribute.
|
||||
@ -8953,6 +8953,7 @@ for further explanation.
|
||||
|
||||
@menu
|
||||
* ARM Pragmas::
|
||||
* M32C Pragmas::
|
||||
* RS/6000 and PowerPC Pragmas::
|
||||
* Darwin Pragmas::
|
||||
* Solaris Pragmas::
|
||||
@ -8984,6 +8985,21 @@ Do not affect the @code{long_call} or @code{short_call} attributes of
|
||||
subsequent functions.
|
||||
@end table
|
||||
|
||||
@node M32C Pragmas
|
||||
@subsection M32C Pragmas
|
||||
|
||||
@table @code
|
||||
@item memregs @var{number}
|
||||
@cindex pragma, memregs
|
||||
Overrides the command line option @code{-memregs=} for the current
|
||||
file. Use with care! This pragma must be before any function in the
|
||||
file, and mixing different memregs values in different objects may
|
||||
make them incompatible. This pragma is useful when a
|
||||
performance-critical function uses a memreg for temporary values,
|
||||
as it may allow you to reduce the number of memregs used.
|
||||
|
||||
@end table
|
||||
|
||||
@node RS/6000 and PowerPC Pragmas
|
||||
@subsection RS/6000 and PowerPC Pragmas
|
||||
|
||||
|
@ -2246,6 +2246,8 @@ GNU Compiler Collection on your machine.
|
||||
@item
|
||||
@uref{#iq2000-x-elf,,iq2000-*-elf}
|
||||
@item
|
||||
@uref{#m32c-x-elf,,m32c-*-elf}
|
||||
@item
|
||||
@uref{#m32r-x-elf,,m32r-*-elf}
|
||||
@item
|
||||
@uref{#m6811-elf,,m6811-elf}
|
||||
@ -3180,6 +3182,13 @@ switch and using the configure option @option{--with-cpu-@var{cpu_type}}.
|
||||
Vitesse IQ2000 processors. These are used in embedded
|
||||
applications. There are no standard Unix configurations.
|
||||
|
||||
@html
|
||||
<hr />
|
||||
@end html
|
||||
@heading @anchor{m32c-x-elf}m32c-*-elf
|
||||
Renesas M32C processor.
|
||||
This configuration is intended for embedded systems.
|
||||
|
||||
@html
|
||||
<hr />
|
||||
@end html
|
||||
|
@ -544,6 +544,9 @@ Objective-C and Objective-C++ Dialects}.
|
||||
-mno-flush-trap -mflush-trap=@var{number} @gol
|
||||
-G @var{num}}
|
||||
|
||||
@emph{M32C Options}
|
||||
@gccoptlist{-mcpu=@var{cpu} -msim -memregs=@var{number}}
|
||||
|
||||
@emph{M680x0 Options}
|
||||
@gccoptlist{-m68000 -m68020 -m68020-40 -m68020-60 -m68030 -m68040 @gol
|
||||
-m68060 -mcpu32 -m5200 -m68881 -mbitfield -mc68000 -mc68020 @gol
|
||||
@ -6957,6 +6960,7 @@ platform.
|
||||
* HPPA Options::
|
||||
* i386 and x86-64 Options::
|
||||
* IA-64 Options::
|
||||
* M32C Options::
|
||||
* M32R/D Options::
|
||||
* M680x0 Options::
|
||||
* M68hc1x Options::
|
||||
@ -9371,6 +9375,39 @@ to 64 bits. These are HP-UX specific flags.
|
||||
|
||||
@end table
|
||||
|
||||
@node M32C Options
|
||||
@subsection M32C Options
|
||||
@cindex M32C options
|
||||
|
||||
@table @gcctabopt
|
||||
@item -mcpu=@var{name}
|
||||
@opindex mcpu=
|
||||
Select the CPU for which code is generated. @var{name} may be one of
|
||||
@samp{r8c} for the R8C/Tiny series, @samp{m16c} for the M16C (up to
|
||||
/60) series, @samp{m32cm} for the M16C/80 series, or @samp{m32c} for
|
||||
the M32C/80 series.
|
||||
|
||||
@item -msim
|
||||
@opindex msim
|
||||
Specifies that the program will be run on the simulator. This causes
|
||||
an alternate runtime library to be linked in which supports, for
|
||||
example, file I/O. You must not use this option when generating
|
||||
programs that will run on real hardware; you must provide your own
|
||||
runtime library for whatever I/O functions are needed.
|
||||
|
||||
@item -memregs=@var{number}
|
||||
@opindex memregs=
|
||||
Specifies the number of memory-based pseudo-registers GCC will use
|
||||
during code generation. These pseudo-registers will be used like real
|
||||
registers, so there is a tradeoff between GCC's ability to fit the
|
||||
code into available registers, and the performance penalty of using
|
||||
memory instead of registers. Note that all modules in a program must
|
||||
be compiled with the same value for this option. Because of that, you
|
||||
must not use this option with the default runtime libraries gcc
|
||||
builds.
|
||||
|
||||
@end table
|
||||
|
||||
@node M32R/D Options
|
||||
@subsection M32R/D Options
|
||||
@cindex M32R/D options
|
||||
|
129
gcc/doc/md.texi
129
gcc/doc/md.texi
@ -2165,6 +2165,135 @@ An integer constant with all bits set except exactly one.
|
||||
Any SYMBOL_REF.
|
||||
@end table
|
||||
|
||||
@item M32C---@file{m32c.c}
|
||||
|
||||
@item Rsp
|
||||
@itemx Rfb
|
||||
@itemx Rsb
|
||||
@samp{$sp}, @samp{$fb}, @samp{$sb}.
|
||||
|
||||
@item Rcr
|
||||
Any control register, when they're 16 bits wide (nothing if control
|
||||
registers are 24 bits wide)
|
||||
|
||||
@item Rcl
|
||||
Any control register, when they're 24 bits wide.
|
||||
|
||||
@item R0w
|
||||
@itemx R1w
|
||||
@itemx R2w
|
||||
@itemx R3w
|
||||
$r0, $r1, $r2, $r3.
|
||||
|
||||
@item R02
|
||||
$r0 or $r2, or $r2r0 for 32 bit values.
|
||||
|
||||
@item R13
|
||||
$r1 or $r3, or $r3r1 for 32 bit values.
|
||||
|
||||
@item Rdi
|
||||
A register that can hold a 64 bit value.
|
||||
|
||||
@item Rhl
|
||||
$r0 or $r1 (registers with addressable high/low bytes)
|
||||
|
||||
@item R23
|
||||
$r2 or $r3
|
||||
|
||||
@item Raa
|
||||
Address registers
|
||||
|
||||
@item Raw
|
||||
Address registers when they're 16 bits wide.
|
||||
|
||||
@item Ral
|
||||
Address registers when they're 24 bits wide.
|
||||
|
||||
@item Rqi
|
||||
Registers that can hold QI values.
|
||||
|
||||
@item Rad
|
||||
Registers that can be used with displacements ($a0, $a1, $sb).
|
||||
|
||||
@item Rsi
|
||||
Registers that can hold 32 bit values.
|
||||
|
||||
@item Rhi
|
||||
Registers that can hold 16 bit values.
|
||||
|
||||
@item Rhc
|
||||
Registers chat can hold 16 bit values, including all control
|
||||
registers.
|
||||
|
||||
@item Rra
|
||||
$r0 through R1, plus $a0 and $a1.
|
||||
|
||||
@item Rfl
|
||||
The flags register.
|
||||
|
||||
@item Rmm
|
||||
The memory-based pseudo-registers $mem0 through $mem15.
|
||||
|
||||
@item Rpi
|
||||
Registers that can hold pointers (16 bit registers for r8c, m16c; 24
|
||||
bit registers for m32cm, m32c).
|
||||
|
||||
@item Rpa
|
||||
Matches multiple registers in a PARALLEL to form a larger register.
|
||||
Used to match function return values.
|
||||
|
||||
@item Is3
|
||||
-8 @dots{} 7
|
||||
|
||||
@item IS1
|
||||
-128 @dots{} 127
|
||||
|
||||
@item IS2
|
||||
-32768 @dots{} 32767
|
||||
|
||||
@item IU2
|
||||
0 @dots{} 65535
|
||||
|
||||
@item In4
|
||||
-8 @dots{} -1 or 1 @dots{} 8
|
||||
|
||||
@item In5
|
||||
-16 @dots{} -1 or 1 @dots{} 16
|
||||
|
||||
@item In4
|
||||
-8 @dots{} -1 or 1 @dots{} 8
|
||||
|
||||
@item IM2
|
||||
-65536 @dots{} -1
|
||||
|
||||
@item Ilb
|
||||
An 8 bit value with exactly one bit set.
|
||||
|
||||
@item Ilw
|
||||
A 16 bit value with exactly one bit set.
|
||||
|
||||
@item Sd
|
||||
The common src/dest memory addressing modes.
|
||||
|
||||
@item Sa
|
||||
Memory addressed using $a0 or $a1.
|
||||
|
||||
@item Si
|
||||
Memory addressed with immediate addresses.
|
||||
|
||||
@item Ss
|
||||
Memory addressed using the stack pointer ($sp).
|
||||
|
||||
@item Sf
|
||||
Memory addressed using the frame base register ($fb).
|
||||
|
||||
@item Ss
|
||||
Memory addressed using the small base register ($sb).
|
||||
|
||||
@item S1
|
||||
$r1h
|
||||
|
||||
|
||||
@item MIPS---@file{mips.h}
|
||||
@table @code
|
||||
@item d
|
||||
|
Loading…
Reference in New Issue
Block a user