2 # Generate mova.md, a file containing patterns that can be implemented
3 # using the h8sx mova instruction.
5 echo ";; -*- buffer-read-only: t -*-"
6 echo ";; Generated automatically from genmova.sh"
8 # Loop over modes for the source operand (the index). Only 8-bit and
9 # 16-bit indices are allowed.
12 # Set $src to the operand syntax for this size of index.
18 # A match_operand for the source.
19 operand
="(match_operand:$s 1 \"h8300_dst_operand\" \"0,rQ\")"
21 # Loop over the destination register's mode. The QI and HI versions use
22 # the same instructions as the SI ones, they just ignore the upper bits
26 # If the destination is larger than the source, include a
27 # zero_extend/plus pattern. We could also match zero extensions
28 # of memory without the plus, but it's not any smaller or faster
29 # than separate insns.
31 SI
:QI | SI
:HI | HI
:QI
)
34 [(set (match_operand:$d 0 "register_operand" "=r,r")
35 (plus:$d (zero_extend:$d $operand)
36 (match_operand:$d 2 "immediate_operand" "i,i")))]
38 "mova/b.l @(%o2,$src),%S0"
39 [(set_attr "length_table" "mova")
40 (set_attr "cc" "none")])
46 # Loop over the shift amount.
53 # Calculate the mask of bits that will be nonzero after the source
54 # has been extended and shifted.
62 # There doesn't seem to be a well-established canonical form for
63 # some of the patterns we need. Emit both shift and multiplication
65 for form
in mult ashift
; do
68 ashift
) amount
=$shift;;
72 # If the source and destination are the same size, we can treat
73 # mova as a sort of multiply-add instruction.
77 [(set (match_operand:$d 0 "register_operand" "=r,r")
78 (plus:$d ($form:$d $operand
80 (match_operand:$d 2 "immediate_operand" "i,i")))]
82 "mova/$opsize.l @(%o2,$src),%S0"
83 [(set_attr "length_table" "mova")
84 (set_attr "cc" "none")])
89 # Handle the cases where the source is smaller than the
90 # destination. Sometimes combine will keep the extension,
91 # sometimes it will use an AND.
92 SI
:QI | SI
:HI | HI
:QI
)
94 # Emit the forms that use zero_extend.
97 [(set (match_operand:$d 0 "register_operand" "=r,r")
98 ($form:$d (zero_extend:$d $operand)
99 (const_int $amount)))]
101 "mova/$opsize.l @(0,$src),%S0"
102 [(set_attr "length_table" "mova_zero")
103 (set_attr "cc" "none")])
106 [(set (match_operand:$d 0 "register_operand" "=r,r")
107 (plus:$d ($form:$d (zero_extend:$d $operand)
109 (match_operand:$d 2 "immediate_operand" "i,i")))]
111 "mova/$opsize.l @(%o2,$src),%S0"
112 [(set_attr "length_table" "mova")
113 (set_attr "cc" "none")])
117 # Now emit the forms that use AND. When the index is a register,
118 # these forms are effectively $d-mode operations: the index will
119 # be a $d-mode REG or SUBREG. When the index is a memory
120 # location, we will have a paradoxical subreg such as:
122 # (and:SI (mult:SI (subreg:SI (mem:QI ...) 0)
126 # Match the two case separately: a $d-mode register_operand
127 # or a $d-mode subreg of an $s-mode memory_operand. Match the
128 # memory form first since register_operand accepts mem subregs
130 memory
="(match_operand:$s 1 \"memory_operand\" \"m\")"
131 memory
="(subreg:$d $memory 0)"
132 register
="(match_operand:$d 1 \"register_operand\" \"0\")"
133 for paradoxical
in "$memory" "$register"; do
136 [(set (match_operand:$d 0 "register_operand" "=r")
137 (and:$d ($form:$d $paradoxical
141 "mova/$opsize.l @(0,$src),%S0"
142 [(set_attr "length_table" "mova_zero")
143 (set_attr "cc" "none")])
146 [(set (match_operand:$d 0 "register_operand" "=r")
147 (plus:$d (and:$d ($form:$d $paradoxical
150 (match_operand:$d 2 "immediate_operand" "i")))]
152 "mova/$opsize.l @(%o2,$src),%S0"
153 [(set_attr "length_table" "mova")
154 (set_attr "cc" "none")])