xref: /netbsd-src/external/gpl3/gcc/dist/gcc/config/h8300/extensions.md (revision b1e838363e3c6fc78a55519254d99869742dd33c)
1;; ----------------------------------------------------------------------
2;; EXTEND INSTRUCTIONS
3;; ----------------------------------------------------------------------
4
5(define_expand "zero_extendqi<mode>2"
6  [(set (match_operand:HSI 0 "register_operand" "")
7	(zero_extend:HSI (match_operand:QI 1 "general_operand_src" "")))]
8  ""
9  {
10    if (TARGET_H8300SX)
11      operands[1] = force_reg (QImode, operands[1]);
12  })
13
14(define_insn_and_split "*zero_extendqihi2"
15  [(set (match_operand:HI 0 "register_operand" "=r,r")
16	(zero_extend:HI (match_operand:QI 1 "general_operand_src" "0,g>")))]
17  ""
18  "#"
19  "&& reload_completed"
20  [(parallel [(set (match_dup 0) (zero_extend:HI (match_dup 1)))
21	      (clobber (reg:CC CC_REG))])])
22
23(define_insn "*zero_extendqihi2<cczn>"
24  [(set (match_operand:HI 0 "register_operand" "=r,r")
25	(zero_extend:HI (match_operand:QI 1 "general_operand_src" "0,g>")))
26   (clobber (reg:CC CC_REG))]
27  ""
28  "@
29  extu.w	%T0
30  #"
31  [(set_attr "length" "2,10")])
32
33;; Split the zero extension of a general operand (actually a memory
34;; operand) into a load of the operand and the actual zero extension
35;; so that 1) the length will be accurate, and 2) the zero extensions
36;; appearing at the end of basic blocks may be merged.
37
38(define_split
39  [(set (match_operand:HI 0 "register_operand" "")
40	(zero_extend:HI (match_operand:QI 1 "general_operand_src" "")))
41   (clobber (reg:CC CC_REG))]
42  "reload_completed"
43  [(set (match_dup 2) (match_dup 1))
44   (parallel [(set (match_dup 0) (zero_extend:HI (match_dup 2)))
45	      (clobber (reg:CC CC_REG))])]
46  {
47    operands[2] = gen_rtx_REG (QImode, REGNO (operands[0]));
48  })
49
50(define_insn "*zero_extendqisi2"
51  [(set (match_operand:SI 0 "register_operand" "=r,r")
52	(zero_extend:SI (match_operand:QI 1 "general_operand_src" "0,g>")))]
53  "!reload_completed && !TARGET_H8300SX"
54  "#")
55
56;; Two cases for the !H8/SX target.  One where there is an overlap
57;; between the source and destination, one where there is no overlap
58(define_split
59  [(set (match_operand:SI 0 "register_operand" "")
60	(zero_extend:SI (match_operand:QI 1 "general_operand_src" "")))]
61  "!TARGET_H8300SX
62    && reg_overlap_mentioned_p (operands[0], operands[1])
63    && reload_completed"
64  [(parallel [(set (match_dup 2) (match_dup 1))
65	      (clobber (reg:CC CC_REG))])
66   (parallel [(set (match_dup 3) (zero_extend:HI (match_dup 2)))
67	      (clobber (reg:CC CC_REG))])
68   (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 3)))
69	      (clobber (reg:CC CC_REG))])]
70  {
71    operands[2] = gen_lowpart (QImode, operands[0]);
72    operands[3] = gen_lowpart (HImode, operands[0]);
73  })
74
75(define_split
76  [(set (match_operand:SI 0 "register_operand" "")
77	(zero_extend:SI (match_operand:QI 1 "general_operand_src" "")))]
78  "!TARGET_H8300SX
79    && !reg_overlap_mentioned_p (operands[0], operands[1])
80    && reload_completed"
81  [(parallel [(set (match_dup 0) (const_int 0))
82	      (clobber (reg:CC CC_REG))])
83   (parallel [(set (strict_low_part (match_dup 2)) (match_dup 1))
84	      (clobber (reg:CC CC_REG))])]
85  {
86    operands[2] = gen_rtx_REG (QImode, REGNO (operands[0]));
87  })
88
89(define_insn_and_split "*zero_extendqisi2_h8sx"
90  [(set (match_operand:SI 0 "register_operand" "=r")
91	(zero_extend:SI (match_operand:QI 1 "register_operand" "0")))]
92  "TARGET_H8300SX"
93  "#"
94  "&& reload_completed"
95  [(parallel [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
96	      (clobber (reg:CC CC_REG))])])
97
98(define_insn "*zero_extendqisi2_h8sx<cczn>"
99  [(set (match_operand:SI 0 "register_operand" "=r")
100	(zero_extend:SI (match_operand:QI 1 "register_operand" "0")))
101   (clobber (reg:CC CC_REG))]
102  "TARGET_H8300SX"
103  "extu.l\t#2,%0"
104  [(set_attr "length" "2")])
105
106(define_expand "zero_extendhisi2"
107  [(set (match_operand:SI 0 "register_operand" "")
108	(zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
109  ""
110  "")
111
112(define_insn_and_split "*zero_extendhisi2"
113  [(set (match_operand:SI 0 "register_operand" "=r")
114	(zero_extend:SI (match_operand:HI 1 "register_operand" "0")))]
115  ""
116  "#"
117  "&& reload_completed"
118  [(parallel [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
119	      (clobber (reg:CC CC_REG))])])
120
121(define_insn "*zero_extendhisi2<cczn>"
122  [(set (match_operand:SI 0 "register_operand" "=r")
123	(zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
124   (clobber (reg:CC CC_REG))]
125  ""
126  "extu.l	%S0"
127  [(set_attr "length" "2")])
128
129(define_expand "extendqi<mode>2"
130  [(set (match_operand:HSI 0 "register_operand" "")
131	(sign_extend:HSI (match_operand:QI 1 "register_operand" "")))]
132  ""
133  "")
134
135(define_insn_and_split "*extendqihi2"
136  [(set (match_operand:HI 0 "register_operand" "=r")
137	(sign_extend:HI (match_operand:QI 1 "register_operand" "0")))]
138  ""
139  "#"
140  "&& reload_completed"
141  [(parallel [(set (match_dup 0) (sign_extend:HI (match_dup 1)))
142	      (clobber (reg:CC CC_REG))])])
143
144(define_insn "*extendqihi2<cczn>"
145  [(set (match_operand:HI 0 "register_operand" "=r")
146	(sign_extend:HI (match_operand:QI 1 "register_operand" "0")))
147   (clobber (reg:CC CC_REG))]
148  ""
149  "exts.w	%T0"
150  [(set_attr "length" "2")])
151
152;; The following pattern is needed because without the pattern, the
153;; combiner would split (sign_extend:SI (reg:QI)) into two 24-bit
154;; shifts, one ashift and one ashiftrt.
155
156(define_insn_and_split "*extendqisi2"
157  [(set (match_operand:SI 0 "register_operand" "=r")
158	(sign_extend:SI (match_operand:QI 1 "register_operand" "0")))]
159  "!TARGET_H8300SX"
160  "#"
161  "&& reload_completed"
162  [(parallel [(set (match_dup 2) (sign_extend:HI (match_dup 1)))
163	      (clobber (reg:CC CC_REG))])
164   (parallel [(set (match_dup 0) (sign_extend:SI (match_dup 2)))
165	      (clobber (reg:CC CC_REG))])]
166  {
167    operands[2] = gen_rtx_REG (HImode, REGNO (operands[0]));
168  })
169
170(define_insn_and_split "*extendqisi2_h8sx"
171  [(set (match_operand:SI 0 "register_operand" "=r")
172	(sign_extend:SI (match_operand:QI 1 "register_operand" "0")))]
173  "TARGET_H8300SX"
174  "#"
175  "&& reload_completed"
176  [(parallel [(set (match_dup 0) (sign_extend:SI (match_dup 1)))
177	      (clobber (reg:CC CC_REG))])])
178
179(define_insn "*extendqisi2_h8sx<cczn>"
180  [(set (match_operand:SI 0 "register_operand" "=r")
181	(sign_extend:SI (match_operand:QI 1 "register_operand" "0")))
182   (clobber (reg:CC CC_REG))]
183  "TARGET_H8300SX"
184  "exts.l\t#2,%0"
185  [(set_attr "length" "2")])
186
187(define_expand "extendhisi2"
188  [(set (match_operand:SI 0 "register_operand" "")
189	(sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
190  ""
191  "")
192
193(define_insn_and_split "*extendhisi2"
194  [(set (match_operand:SI 0 "register_operand" "=r")
195	(sign_extend:SI (match_operand:HI 1 "register_operand" "0")))]
196  ""
197  "#"
198  "&& reload_completed"
199  [(parallel [(set (match_dup 0) (sign_extend:SI (match_dup 1)))
200	      (clobber (reg:CC CC_REG))])])
201
202(define_insn "*extendhisi2<cczn>"
203  [(set (match_operand:SI 0 "register_operand" "=r")
204	(sign_extend:SI (match_operand:HI 1 "register_operand" "0")))
205   (clobber (reg:CC CC_REG))]
206  ""
207  "exts.l	%S0"
208  [(set_attr "length" "2")])
209