2 # Generate mova.md, a file containing patterns that can be implemented
3 # using the h8sx mova instruction.
5 # Copyright (C) 2004-2024 Free Software Foundation, Inc.
7 # This file is part of GCC.
9 # GCC is free software; you can redistribute it and/or modify
10 # it under the terms of the GNU General Public License as published by
11 # the Free Software Foundation; either version 3, or (at your option)
14 # GCC is distributed in the hope that it will be useful,
15 # but WITHOUT ANY WARRANTY; without even the implied warranty of
16 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 # GNU General Public License for more details.
19 # You should have received a copy of the GNU General Public License
20 # along with GCC; see the file COPYING3. If not see
21 # <http://www.gnu.org/licenses/>.
23 echo ";; -*- buffer-read-only: t -*-"
24 echo ";; Generated automatically from genmova.sh"
25 echo ";; Copyright (C) 2004-2024 Free Software Foundation, Inc."
27 echo ";; This file is part of GCC."
29 echo ";; GCC is free software; you can redistribute it and/or modify"
30 echo ";; it under the terms of the GNU General Public License as published by"
31 echo ";; the Free Software Foundation; either version 3, or (at your option)"
32 echo ";; any later version."
34 echo ";; GCC is distributed in the hope that it will be useful,"
35 echo ";; but WITHOUT ANY WARRANTY; without even the implied warranty of"
36 echo ";; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the"
37 echo ";; GNU General Public License for more details."
39 echo ";; You should have received a copy of the GNU General Public License"
40 echo ";; along with GCC; see the file COPYING3. If not see"
41 echo ";; <http://www.gnu.org/licenses/>."
43 # Loop over modes for the source operand (the index). Only 8-bit and
44 # 16-bit indices are allowed.
47 # Set $src to the operand syntax for this size of index.
53 # A match_operand for the source.
54 operand
="(match_operand:$s 1 \"h8300_dst_operand\" \"0,rQ\")"
56 # Loop over the destination register's mode. The QI and HI versions use
57 # the same instructions as the SI ones, they just ignore the upper bits
61 # If the destination is larger than the source, include a
62 # zero_extend/plus pattern. We could also match zero extensions
63 # of memory without the plus, but it's not any smaller or faster
64 # than separate insns.
66 SI
:QI | SI
:HI | HI
:QI
)
69 [(set (match_operand:$d 0 "register_operand" "=r,r")
70 (plus:$d (zero_extend:$d $operand)
71 (match_operand:$d 2 "immediate_operand" "i,i")))]
73 "mova/b.l @(%o2%C2,$src),%S0"
74 [(set_attr "length_table" "mova")])
80 # Loop over the shift amount.
87 # Calculate the mask of bits that will be nonzero after the source
88 # has been extended and shifted.
96 # There doesn't seem to be a well-established canonical form for
97 # some of the patterns we need. Emit both shift and multiplication
99 for form
in mult ashift
; do
102 ashift
) amount
=$shift;;
106 # If the source and destination are the same size, we can treat
107 # mova as a sort of multiply-add instruction.
111 [(set (match_operand:$d 0 "register_operand" "=r,r")
112 (plus:$d ($form:$d $operand
114 (match_operand:$d 2 "immediate_operand" "i,i")))]
116 "mova/$opsize.l @(%o2%C2,$src),%S0"
117 [(set_attr "length_table" "mova")])
122 # Handle the cases where the source is smaller than the
123 # destination. Sometimes combine will keep the extension,
124 # sometimes it will use an AND.
125 SI
:QI | SI
:HI | HI
:QI
)
127 # Emit the forms that use zero_extend.
130 [(set (match_operand:$d 0 "register_operand" "=r,r")
131 ($form:$d (zero_extend:$d $operand)
132 (const_int $amount)))]
134 "mova/$opsize.l @(0,$src),%S0"
135 [(set_attr "length_table" "mova_zero")])
138 [(set (match_operand:$d 0 "register_operand" "=r,r")
139 (plus:$d ($form:$d (zero_extend:$d $operand)
141 (match_operand:$d 2 "immediate_operand" "i,i")))]
143 "mova/$opsize.l @(%o2%C2,$src),%S0"
144 [(set_attr "length_table" "mova")])
148 # Now emit the forms that use AND. When the index is a register,
149 # these forms are effectively $d-mode operations: the index will
150 # be a $d-mode REG or SUBREG. When the index is a memory
151 # location, we will have a paradoxical subreg such as:
153 # (and:SI (mult:SI (subreg:SI (mem:QI ...) 0)
157 # Match the two case separately: a $d-mode register_operand
158 # or a $d-mode subreg of an $s-mode memory_operand. Match the
159 # memory form first since register_operand accepts mem subregs
161 memory
="(match_operand:$s 1 \"memory_operand\" \"m\")"
162 memory
="(subreg:$d $memory 0)"
163 register
="(match_operand:$d 1 \"register_operand\" \"0\")"
164 for paradoxical
in "$memory" "$register"; do
167 [(set (match_operand:$d 0 "register_operand" "=r")
168 (and:$d ($form:$d $paradoxical
172 "mova/$opsize.l @(0,$src),%S0"
173 [(set_attr "length_table" "mova_zero")])
176 [(set (match_operand:$d 0 "register_operand" "=r")
177 (plus:$d (and:$d ($form:$d $paradoxical
180 (match_operand:$d 2 "immediate_operand" "i")))]
182 "mova/$opsize.l @(%o2%C2,$src),%S0"
183 [(set_attr "length_table" "mova")])