]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/h8300/h8300.c
* genattrtab.c (count_sub_rtxs): Removed.
[thirdparty/gcc.git] / gcc / config / h8300 / h8300.c
CommitLineData
07aae5c2 1/* Subroutines for insn-output.c for Hitachi H8/300.
aefc5826 2 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
0f18b2b0 3 2001, 2002, 2003 Free Software Foundation, Inc.
48837e29
DE
4 Contributed by Steve Chamberlain (sac@cygnus.com),
5 Jim Wilson (wilson@cygnus.com), and Doug Evans (dje@cygnus.com).
07aae5c2 6
8aa063fb 7This file is part of GCC.
07aae5c2 8
8aa063fb 9GCC is free software; you can redistribute it and/or modify
07aae5c2
SC
10it under the terms of the GNU General Public License as published by
11the Free Software Foundation; either version 2, or (at your option)
12any later version.
13
8aa063fb 14GCC is distributed in the hope that it will be useful,
07aae5c2
SC
15but WITHOUT ANY WARRANTY; without even the implied warranty of
16MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17GNU General Public License for more details.
18
19You should have received a copy of the GNU General Public License
8aa063fb 20along with GCC; see the file COPYING. If not, write to
97aadbb9
RK
21the Free Software Foundation, 59 Temple Place - Suite 330,
22Boston, MA 02111-1307, USA. */
07aae5c2 23
07aae5c2 24#include "config.h"
c5c76735 25#include "system.h"
4977bab6
ZW
26#include "coretypes.h"
27#include "tm.h"
07aae5c2 28#include "rtl.h"
bf6bb899 29#include "tree.h"
07aae5c2
SC
30#include "regs.h"
31#include "hard-reg-set.h"
32#include "real.h"
33#include "insn-config.h"
34#include "conditions.h"
07aae5c2
SC
35#include "output.h"
36#include "insn-attr.h"
37#include "flags.h"
38#include "recog.h"
39#include "expr.h"
bf6bb899 40#include "function.h"
c15c90bb 41#include "optabs.h"
441d04c6 42#include "toplev.h"
8b97c5f8 43#include "c-pragma.h"
441d04c6 44#include "tm_p.h"
f2a9645f 45#include "ggc.h"
672a6f42
NB
46#include "target.h"
47#include "target-def.h"
07aae5c2
SC
48
49/* Forward declarations. */
cb713a8d
KH
50static const char *byte_reg (rtx, int);
51static int h8300_interrupt_function_p (tree);
3cfa3702 52static int h8300_saveall_function_p (tree);
cb713a8d
KH
53static int h8300_monitor_function_p (tree);
54static int h8300_os_task_function_p (tree);
55static void dosize (int, unsigned int);
56static int round_frame_size (int);
57static unsigned int compute_saved_regs (void);
58static void push (int);
59static void pop (int);
60static const char *cond_string (enum rtx_code);
61static unsigned int h8300_asm_insn_count (const char *);
cb713a8d
KH
62static tree h8300_handle_fndecl_attribute (tree *, tree, tree, int, bool *);
63static tree h8300_handle_eightbit_data_attribute (tree *, tree, tree, int, bool *);
64static tree h8300_handle_tiny_data_attribute (tree *, tree, tree, int, bool *);
ede75ee8 65#ifndef OBJECT_FORMAT_ELF
cb713a8d 66static void h8300_asm_named_section (const char *, unsigned int);
ede75ee8 67#endif
cb713a8d
KH
68static int h8300_and_costs (rtx);
69static int h8300_shift_costs (rtx);
f5b65a56 70
48837e29
DE
71/* CPU_TYPE, says what cpu we're compiling for. */
72int cpu_type;
73
e392d367
KH
74/* True if a #pragma interrupt has been seen for the current function. */
75static int pragma_interrupt;
07aae5c2
SC
76
77/* True if a #pragma saveall has been seen for the current function. */
0869f126 78static int pragma_saveall;
07aae5c2 79
441d04c6 80static const char *const names_big[] =
07e4d94e 81{ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7" };
48837e29 82
441d04c6 83static const char *const names_extended[] =
07e4d94e 84{ "er0", "er1", "er2", "er3", "er4", "er5", "er6", "er7" };
48837e29 85
441d04c6 86static const char *const names_upper_extended[] =
07e4d94e 87{ "e0", "e1", "e2", "e3", "e4", "e5", "e6", "e7" };
48837e29
DE
88
89/* Points to one of the above. */
90/* ??? The above could be put in an array indexed by CPU_TYPE. */
441d04c6 91const char * const *h8_reg_names;
48837e29
DE
92
93/* Various operations needed by the following, indexed by CPU_TYPE. */
48837e29 94
441d04c6 95const char *h8_push_op, *h8_pop_op, *h8_mov_op;
dc66a1c4
RH
96
97/* Machine-specific symbol_ref flags. */
98#define SYMBOL_FLAG_FUNCVEC_FUNCTION (SYMBOL_FLAG_MACH_DEP << 0)
99#define SYMBOL_FLAG_EIGHTBIT_DATA (SYMBOL_FLAG_MACH_DEP << 1)
100#define SYMBOL_FLAG_TINY_DATA (SYMBOL_FLAG_MACH_DEP << 2)
672a6f42 101\f
c4dfc70c
DD
102/* See below where shifts are handled for explanation of this enum. */
103
104enum shift_alg
105{
106 SHIFT_INLINE,
107 SHIFT_ROT_AND,
108 SHIFT_SPECIAL,
109 SHIFT_LOOP
110};
111
112/* Symbols of the various shifts which can be used as indices. */
113
114enum shift_type
115{
116 SHIFT_ASHIFT, SHIFT_LSHIFTRT, SHIFT_ASHIFTRT
117};
118
119/* Macros to keep the shift algorithm tables small. */
120#define INL SHIFT_INLINE
121#define ROT SHIFT_ROT_AND
122#define LOP SHIFT_LOOP
123#define SPC SHIFT_SPECIAL
124
125/* The shift algorithms for each machine, mode, shift type, and shift
126 count are defined below. The three tables below correspond to
127 QImode, HImode, and SImode, respectively. Each table is organized
f411c849 128 by, in the order of indices, machine, shift type, and shift count. */
c4dfc70c
DD
129
130static enum shift_alg shift_alg_qi[3][3][8] = {
131 {
132 /* TARGET_H8300 */
133 /* 0 1 2 3 4 5 6 7 */
134 { INL, INL, INL, INL, INL, ROT, ROT, ROT }, /* SHIFT_ASHIFT */
135 { INL, INL, INL, INL, INL, ROT, ROT, ROT }, /* SHIFT_LSHIFTRT */
136 { INL, INL, INL, INL, INL, LOP, LOP, SPC } /* SHIFT_ASHIFTRT */
137 },
138 {
139 /* TARGET_H8300H */
140 /* 0 1 2 3 4 5 6 7 */
141 { INL, INL, INL, INL, INL, ROT, ROT, ROT }, /* SHIFT_ASHIFT */
142 { INL, INL, INL, INL, INL, ROT, ROT, ROT }, /* SHIFT_LSHIFTRT */
143 { INL, INL, INL, INL, INL, LOP, LOP, SPC } /* SHIFT_ASHIFTRT */
144 },
145 {
146 /* TARGET_H8300S */
147 /* 0 1 2 3 4 5 6 7 */
148 { INL, INL, INL, INL, INL, INL, ROT, ROT }, /* SHIFT_ASHIFT */
149 { INL, INL, INL, INL, INL, INL, ROT, ROT }, /* SHIFT_LSHIFTRT */
150 { INL, INL, INL, INL, INL, INL, INL, SPC } /* SHIFT_ASHIFTRT */
151 }
152};
153
154static enum shift_alg shift_alg_hi[3][3][16] = {
155 {
156 /* TARGET_H8300 */
157 /* 0 1 2 3 4 5 6 7 */
158 /* 8 9 10 11 12 13 14 15 */
159 { INL, INL, INL, INL, INL, INL, INL, SPC,
160 SPC, SPC, SPC, SPC, SPC, SPC, SPC, SPC }, /* SHIFT_ASHIFT */
161 { INL, INL, INL, INL, INL, LOP, LOP, SPC,
162 SPC, SPC, SPC, SPC, SPC, SPC, SPC, SPC }, /* SHIFT_LSHIFTRT */
163 { INL, INL, INL, INL, INL, LOP, LOP, SPC,
164 SPC, SPC, SPC, SPC, SPC, SPC, SPC, SPC }, /* SHIFT_ASHIFTRT */
165 },
166 {
167 /* TARGET_H8300H */
168 /* 0 1 2 3 4 5 6 7 */
169 /* 8 9 10 11 12 13 14 15 */
170 { INL, INL, INL, INL, INL, INL, INL, SPC,
171 SPC, SPC, SPC, SPC, SPC, ROT, ROT, ROT }, /* SHIFT_ASHIFT */
172 { INL, INL, INL, INL, INL, INL, INL, SPC,
173 SPC, SPC, SPC, SPC, SPC, ROT, ROT, ROT }, /* SHIFT_LSHIFTRT */
174 { INL, INL, INL, INL, INL, INL, INL, SPC,
175 SPC, SPC, SPC, SPC, SPC, SPC, SPC, SPC }, /* SHIFT_ASHIFTRT */
176 },
177 {
178 /* TARGET_H8300S */
179 /* 0 1 2 3 4 5 6 7 */
180 /* 8 9 10 11 12 13 14 15 */
181 { INL, INL, INL, INL, INL, INL, INL, INL,
182 SPC, SPC, SPC, SPC, SPC, ROT, ROT, ROT }, /* SHIFT_ASHIFT */
183 { INL, INL, INL, INL, INL, INL, INL, INL,
184 SPC, SPC, SPC, SPC, SPC, ROT, ROT, ROT }, /* SHIFT_LSHIFTRT */
185 { INL, INL, INL, INL, INL, INL, INL, INL,
186 SPC, SPC, SPC, SPC, SPC, SPC, SPC, SPC }, /* SHIFT_ASHIFTRT */
187 }
188};
189
190static enum shift_alg shift_alg_si[3][3][32] = {
191 {
192 /* TARGET_H8300 */
193 /* 0 1 2 3 4 5 6 7 */
194 /* 8 9 10 11 12 13 14 15 */
195 /* 16 17 18 19 20 21 22 23 */
196 /* 24 25 26 27 28 29 30 31 */
197 { INL, INL, INL, LOP, LOP, LOP, LOP, LOP,
198 SPC, LOP, LOP, LOP, LOP, LOP, LOP, LOP,
199 SPC, SPC, SPC, SPC, SPC, LOP, LOP, LOP,
200 SPC, SPC, SPC, SPC, LOP, LOP, LOP, SPC }, /* SHIFT_ASHIFT */
201 { INL, INL, INL, LOP, LOP, LOP, LOP, LOP,
202 SPC, SPC, LOP, LOP, LOP, LOP, LOP, SPC,
203 SPC, SPC, SPC, LOP, LOP, LOP, LOP, LOP,
204 SPC, SPC, SPC, SPC, SPC, LOP, LOP, SPC }, /* SHIFT_LSHIFTRT */
205 { INL, INL, INL, LOP, LOP, LOP, LOP, LOP,
206 SPC, LOP, LOP, LOP, LOP, LOP, LOP, SPC,
207 SPC, SPC, LOP, LOP, LOP, LOP, LOP, LOP,
208 SPC, SPC, SPC, LOP, LOP, LOP, LOP, SPC }, /* SHIFT_ASHIFTRT */
209 },
210 {
211 /* TARGET_H8300H */
212 /* 0 1 2 3 4 5 6 7 */
213 /* 8 9 10 11 12 13 14 15 */
214 /* 16 17 18 19 20 21 22 23 */
215 /* 24 25 26 27 28 29 30 31 */
216 { INL, INL, INL, INL, INL, LOP, LOP, LOP,
217 SPC, LOP, LOP, LOP, LOP, LOP, LOP, SPC,
218 SPC, SPC, SPC, SPC, LOP, LOP, LOP, LOP,
1e5bdc40 219 SPC, LOP, LOP, LOP, SPC, SPC, SPC, SPC }, /* SHIFT_ASHIFT */
c4dfc70c
DD
220 { INL, INL, INL, INL, INL, LOP, LOP, LOP,
221 SPC, LOP, LOP, LOP, LOP, LOP, LOP, SPC,
222 SPC, SPC, SPC, SPC, LOP, LOP, LOP, LOP,
1e5bdc40 223 SPC, LOP, LOP, LOP, SPC, SPC, SPC, SPC }, /* SHIFT_LSHIFTRT */
c4dfc70c
DD
224 { INL, INL, INL, INL, INL, LOP, LOP, LOP,
225 SPC, LOP, LOP, LOP, LOP, LOP, LOP, LOP,
226 SPC, SPC, SPC, SPC, LOP, LOP, LOP, LOP,
227 SPC, LOP, LOP, LOP, LOP, LOP, LOP, SPC }, /* SHIFT_ASHIFTRT */
228 },
229 {
230 /* TARGET_H8300S */
231 /* 0 1 2 3 4 5 6 7 */
232 /* 8 9 10 11 12 13 14 15 */
233 /* 16 17 18 19 20 21 22 23 */
234 /* 24 25 26 27 28 29 30 31 */
235 { INL, INL, INL, INL, INL, INL, INL, INL,
236 INL, INL, INL, LOP, LOP, LOP, LOP, SPC,
237 SPC, SPC, SPC, SPC, SPC, SPC, LOP, LOP,
1e5bdc40 238 SPC, SPC, LOP, LOP, SPC, SPC, SPC, SPC }, /* SHIFT_ASHIFT */
c4dfc70c
DD
239 { INL, INL, INL, INL, INL, INL, INL, INL,
240 INL, INL, INL, LOP, LOP, LOP, LOP, SPC,
241 SPC, SPC, SPC, SPC, SPC, SPC, LOP, LOP,
1e5bdc40 242 SPC, SPC, LOP, LOP, SPC, SPC, SPC, SPC }, /* SHIFT_LSHIFTRT */
c4dfc70c
DD
243 { INL, INL, INL, INL, INL, INL, INL, INL,
244 INL, INL, INL, LOP, LOP, LOP, LOP, LOP,
245 SPC, SPC, SPC, SPC, SPC, SPC, LOP, LOP,
246 SPC, SPC, LOP, LOP, LOP, LOP, LOP, SPC }, /* SHIFT_ASHIFTRT */
247 }
248};
249
250#undef INL
251#undef ROT
252#undef LOP
253#undef SPC
254
255enum h8_cpu
256{
257 H8_300,
258 H8_300H,
259 H8_S
260};
261
48837e29
DE
262/* Initialize various cpu specific globals at start up. */
263
264void
cb713a8d 265h8300_init_once (void)
48837e29 266{
cbf1b2da
KH
267 static const char *const h8_push_ops[2] = { "push" , "push.l" };
268 static const char *const h8_pop_ops[2] = { "pop" , "pop.l" };
269 static const char *const h8_mov_ops[2] = { "mov.w", "mov.l" };
270
48837e29
DE
271 if (TARGET_H8300)
272 {
273 cpu_type = (int) CPU_H8300;
274 h8_reg_names = names_big;
275 }
276 else
277 {
3db11b5c 278 /* For this we treat the H8/300H and H8S the same. */
48837e29
DE
279 cpu_type = (int) CPU_H8300H;
280 h8_reg_names = names_extended;
281 }
282 h8_push_op = h8_push_ops[cpu_type];
283 h8_pop_op = h8_pop_ops[cpu_type];
284 h8_mov_op = h8_mov_ops[cpu_type];
17f0f8fa
KH
285
286 if (!TARGET_H8300S && TARGET_MAC)
400500c4 287 {
c725bd79 288 error ("-ms2600 is used without -ms");
ec5b0c68 289 target_flags |= MASK_H8300S;
400500c4 290 }
920e86b8 291
39ba95b5
VK
292 if (TARGET_H8300 && TARGET_NORMAL_MODE)
293 {
92d4b8a0 294 error ("-mn is used without -mh or -ms");
39ba95b5
VK
295 target_flags ^= MASK_NORMAL_MODE;
296 }
c4dfc70c 297
8bd06267 298 /* Some of the shifts are optimized for speed by default.
c4dfc70c 299 See http://gcc.gnu.org/ml/gcc-patches/2002-07/msg01858.html
8bd06267 300 If optimizing for size, change shift_alg for those shift to
c4dfc70c 301 SHIFT_LOOP. */
b6894857 302 if (optimize_size)
c4dfc70c 303 {
b6894857
KH
304 /* H8/300 */
305 shift_alg_hi[H8_300][SHIFT_ASHIFT][5] = SHIFT_LOOP;
306 shift_alg_hi[H8_300][SHIFT_ASHIFT][6] = SHIFT_LOOP;
307 shift_alg_hi[H8_300][SHIFT_ASHIFT][13] = SHIFT_LOOP;
308 shift_alg_hi[H8_300][SHIFT_ASHIFT][14] = SHIFT_LOOP;
c4dfc70c 309
b6894857
KH
310 shift_alg_hi[H8_300][SHIFT_LSHIFTRT][13] = SHIFT_LOOP;
311 shift_alg_hi[H8_300][SHIFT_LSHIFTRT][14] = SHIFT_LOOP;
c4dfc70c 312
b6894857
KH
313 shift_alg_hi[H8_300][SHIFT_ASHIFTRT][13] = SHIFT_LOOP;
314 shift_alg_hi[H8_300][SHIFT_ASHIFTRT][14] = SHIFT_LOOP;
c4dfc70c 315
b6894857
KH
316 /* H8/300H */
317 shift_alg_hi[H8_300H][SHIFT_ASHIFT][5] = SHIFT_LOOP;
318 shift_alg_hi[H8_300H][SHIFT_ASHIFT][6] = SHIFT_LOOP;
c4dfc70c 319
b6894857
KH
320 shift_alg_hi[H8_300H][SHIFT_LSHIFTRT][5] = SHIFT_LOOP;
321 shift_alg_hi[H8_300H][SHIFT_LSHIFTRT][6] = SHIFT_LOOP;
c4dfc70c 322
b6894857
KH
323 shift_alg_hi[H8_300H][SHIFT_ASHIFTRT][5] = SHIFT_LOOP;
324 shift_alg_hi[H8_300H][SHIFT_ASHIFTRT][6] = SHIFT_LOOP;
325 shift_alg_hi[H8_300H][SHIFT_ASHIFTRT][13] = SHIFT_LOOP;
326 shift_alg_hi[H8_300H][SHIFT_ASHIFTRT][14] = SHIFT_LOOP;
c4dfc70c
DD
327
328 /* H8S */
b6894857 329 shift_alg_hi[H8_S][SHIFT_ASHIFTRT][14] = SHIFT_LOOP;
c4dfc70c 330 }
48837e29 331}
07aae5c2 332
9c188705 333static const char *
cb713a8d 334byte_reg (rtx x, int b)
07aae5c2 335{
9cbcd983
KH
336 static const char *const names_small[] = {
337 "r0l", "r0h", "r1l", "r1h", "r2l", "r2h", "r3l", "r3h",
338 "r4l", "r4h", "r5l", "r5h", "r6l", "r6h", "r7l", "r7h"
339 };
07aae5c2
SC
340
341 return names_small[REGNO (x) * 2 + b];
342}
343
344/* REGNO must be saved/restored across calls if this macro is true. */
48837e29 345
9cbcd983 346#define WORD_REG_USED(regno) \
d60004ee 347 (regno < SP_REG \
9cbcd983
KH
348 /* No need to save registers if this function will not return. */ \
349 && ! TREE_THIS_VOLATILE (current_function_decl) \
3cfa3702 350 && (h8300_saveall_function_p (current_function_decl) \
9cbcd983
KH
351 /* Save any call saved register that was used. */ \
352 || (regs_ever_live[regno] && !call_used_regs[regno]) \
353 /* Save the frame pointer if it was used. */ \
354 || (regno == FRAME_POINTER_REGNUM && regs_ever_live[regno]) \
355 /* Save any register used in an interrupt handler. */ \
e392d367
KH
356 || (h8300_current_function_interrupt_function_p () \
357 && regs_ever_live[regno]) \
9cbcd983
KH
358 /* Save call clobbered registers in non-leaf interrupt \
359 handlers. */ \
e392d367 360 || (h8300_current_function_interrupt_function_p () \
9cbcd983 361 && call_used_regs[regno] \
fc80ea73 362 && !current_function_is_leaf)))
07aae5c2
SC
363
364/* Output assembly language to FILE for the operation OP with operand size
48837e29 365 SIZE to adjust the stack pointer. */
48837e29 366
07aae5c2 367static void
dd4c3763 368dosize (int sign, unsigned int size)
07aae5c2 369{
68ee6df6
KH
370 /* H8/300 cannot add/subtract a large constant with a single
371 instruction. If a temporary register is available, load the
372 constant to it and then do the addition. */
373 if (TARGET_H8300
374 && size > 4
375 && !h8300_current_function_interrupt_function_p ()
376 && !(current_function_needs_context && sign < 0))
f8f26adc 377 {
68ee6df6
KH
378 rtx new_sp;
379 rtx r3 = gen_rtx_REG (Pmode, 3);
380 emit_insn (gen_rtx_SET (Pmode, r3, GEN_INT (sign * size)));
381 new_sp = gen_rtx_PLUS (Pmode, stack_pointer_rtx, r3);
382 emit_insn (gen_rtx_SET (Pmode, stack_pointer_rtx, new_sp));
7b3d4613
KH
383 }
384 else
385 {
68ee6df6
KH
386 /* The stack adjustment made here is further optimized by the
387 splitter. In case of H8/300, the splitter always splits the
388 addition emitted here to make the adjustment
389 interrupt-safe. */
390 rtx new_sp = plus_constant (stack_pointer_rtx, sign * size);
391 emit_insn (gen_rtx_SET (Pmode, stack_pointer_rtx, new_sp));
07aae5c2
SC
392 }
393}
394
8682223f
KH
395/* Round up frame size SIZE. */
396
397static int
cb713a8d 398round_frame_size (int size)
8682223f 399{
489eda65
KH
400 return ((size + STACK_BOUNDARY / BITS_PER_UNIT - 1)
401 & -STACK_BOUNDARY / BITS_PER_UNIT);
8682223f
KH
402}
403
404/* Compute which registers to push/pop.
405 Return a bit vector of registers. */
406
407static unsigned int
cb713a8d 408compute_saved_regs (void)
8682223f
KH
409{
410 unsigned int saved_regs = 0;
411 int regno;
412
413 /* Construct a bit vector of registers to be pushed/popped. */
b9b575e6 414 for (regno = 0; regno <= FRAME_POINTER_REGNUM; regno++)
8682223f
KH
415 {
416 if (WORD_REG_USED (regno))
417 saved_regs |= 1 << regno;
418 }
419
420 /* Don't push/pop the frame pointer as it is treated separately. */
421 if (frame_pointer_needed)
422 saved_regs &= ~(1 << FRAME_POINTER_REGNUM);
423
424 return saved_regs;
425}
426
68ee6df6 427/* Emit an insn to push register RN. */
8682223f
KH
428
429static void
cb713a8d 430push (int rn)
8682223f 431{
68ee6df6
KH
432 rtx reg = gen_rtx_REG (word_mode, rn);
433 rtx x;
434
513f31eb 435 if (TARGET_H8300)
68ee6df6 436 x = gen_push_h8300 (reg);
513f31eb 437 else
68ee6df6
KH
438 x = gen_push_h8300hs (reg);
439 x = emit_insn (x);
440 REG_NOTES (x) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, 0);
8682223f
KH
441}
442
68ee6df6 443/* Emit an insn to pop register RN. */
8682223f
KH
444
445static void
cb713a8d 446pop (int rn)
8682223f 447{
68ee6df6
KH
448 rtx reg = gen_rtx_REG (word_mode, rn);
449 rtx x;
450
513f31eb 451 if (TARGET_H8300)
68ee6df6 452 x = gen_pop_h8300 (reg);
513f31eb 453 else
68ee6df6
KH
454 x = gen_pop_h8300hs (reg);
455 x = emit_insn (x);
456 REG_NOTES (x) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, 0);
8682223f 457}
07aae5c2 458
f0b6f9a6 459/* This is what the stack looks like after the prolog of
07aae5c2
SC
460 a function with a frame has been set up:
461
48837e29
DE
462 <args>
463 PC
464 FP <- fp
465 <locals>
8bd06267 466 <saved registers> <- sp
07aae5c2
SC
467
468 This is what the stack looks like after the prolog of
469 a function which doesn't have a frame:
470
48837e29
DE
471 <args>
472 PC
473 <locals>
8bd06267 474 <saved registers> <- sp
07aae5c2
SC
475*/
476
68ee6df6 477/* Generate RTL code for the function prologue. */
8682223f 478
68ee6df6 479void
cb713a8d 480h8300_expand_prologue (void)
07aae5c2 481{
e651d484 482 int regno;
8682223f 483 int saved_regs;
cda4bd43 484 int n_regs;
07aae5c2 485
fabe72bb
JL
486 /* If the current function has the OS_Task attribute set, then
487 we have a naked prologue. */
488 if (h8300_os_task_function_p (current_function_decl))
68ee6df6 489 return;
fabe72bb
JL
490
491 if (h8300_monitor_function_p (current_function_decl))
68ee6df6
KH
492 /* My understanding of monitor functions is they act just like
493 interrupt functions, except the prologue must mask
494 interrupts. */
495 emit_insn (gen_monitor_prologue ());
fabe72bb 496
48837e29
DE
497 if (frame_pointer_needed)
498 {
07e4d94e 499 /* Push fp. */
68ee6df6
KH
500 push (FRAME_POINTER_REGNUM);
501 emit_insn (gen_rtx_SET (Pmode, frame_pointer_rtx, stack_pointer_rtx));
a1616dd9 502 }
48837e29 503
07e4d94e 504 /* Leave room for locals. */
4705d102 505 dosize (-1, round_frame_size (get_frame_size ()));
07aae5c2 506
8682223f
KH
507 /* Push the rest of the registers in ascending order. */
508 saved_regs = compute_saved_regs ();
e651d484 509 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno += n_regs)
cda4bd43 510 {
cda4bd43 511 n_regs = 1;
8682223f 512 if (saved_regs & (1 << regno))
a1616dd9
JL
513 {
514 if (TARGET_H8300S)
515 {
cda4bd43
KH
516 /* See how many registers we can push at the same time. */
517 if ((regno == 0 || regno == 4)
8682223f 518 && ((saved_regs >> regno) & 0x0f) == 0x0f)
cda4bd43
KH
519 n_regs = 4;
520
521 else if ((regno == 0 || regno == 4)
8682223f 522 && ((saved_regs >> regno) & 0x07) == 0x07)
cda4bd43
KH
523 n_regs = 3;
524
525 else if ((regno == 0 || regno == 2 || regno == 4 || regno == 6)
8682223f 526 && ((saved_regs >> regno) & 0x03) == 0x03)
cda4bd43 527 n_regs = 2;
a1616dd9 528 }
cda4bd43 529
e8a68017
KH
530 switch (n_regs)
531 {
532 case 1:
68ee6df6 533 push (regno);
e8a68017
KH
534 break;
535 case 2:
68ee6df6
KH
536 emit_insn (gen_stm_h8300s_2 (gen_rtx_REG (SImode, regno),
537 gen_rtx_REG (SImode, regno + 1)));
e8a68017
KH
538 break;
539 case 3:
68ee6df6
KH
540 emit_insn (gen_stm_h8300s_3 (gen_rtx_REG (SImode, regno),
541 gen_rtx_REG (SImode, regno + 1),
542 gen_rtx_REG (SImode, regno + 2)));
e8a68017
KH
543 break;
544 case 4:
68ee6df6
KH
545 emit_insn (gen_stm_h8300s_4 (gen_rtx_REG (SImode, regno),
546 gen_rtx_REG (SImode, regno + 1),
547 gen_rtx_REG (SImode, regno + 2),
548 gen_rtx_REG (SImode, regno + 3)));
e8a68017
KH
549 break;
550 default:
551 abort ();
552 }
07aae5c2
SC
553 }
554 }
555}
556
68ee6df6 557int
cb713a8d 558h8300_can_use_return_insn_p (void)
68ee6df6
KH
559{
560 return (reload_completed
561 && !frame_pointer_needed
562 && get_frame_size () == 0
563 && compute_saved_regs () == 0);
564}
07aae5c2 565
68ee6df6
KH
566/* Generate RTL code for the function epilogue. */
567
568void
cb713a8d 569h8300_expand_epilogue (void)
07aae5c2 570{
e651d484 571 int regno;
8682223f 572 int saved_regs;
cda4bd43 573 int n_regs;
07aae5c2 574
e392d367 575 if (h8300_os_task_function_p (current_function_decl))
68ee6df6
KH
576 /* OS_Task epilogues are nearly naked -- they just have an
577 rts instruction. */
578 return;
07aae5c2 579
8682223f
KH
580 /* Pop the saved registers in descending order. */
581 saved_regs = compute_saved_regs ();
e651d484 582 for (regno = FIRST_PSEUDO_REGISTER - 1; regno >= 0; regno -= n_regs)
cda4bd43 583 {
cda4bd43 584 n_regs = 1;
8682223f 585 if (saved_regs & (1 << regno))
07aae5c2 586 {
a1616dd9
JL
587 if (TARGET_H8300S)
588 {
cda4bd43
KH
589 /* See how many registers we can pop at the same time. */
590 if ((regno == 7 || regno == 3)
8682223f 591 && ((saved_regs >> (regno - 3)) & 0x0f) == 0x0f)
cda4bd43
KH
592 n_regs = 4;
593
594 else if ((regno == 6 || regno == 2)
8682223f 595 && ((saved_regs >> (regno - 2)) & 0x07) == 0x07)
cda4bd43
KH
596 n_regs = 3;
597
598 else if ((regno == 7 || regno == 5 || regno == 3 || regno == 1)
8682223f 599 && ((saved_regs >> (regno - 1)) & 0x03) == 0x03)
cda4bd43 600 n_regs = 2;
a1616dd9 601 }
cda4bd43 602
e8a68017
KH
603 switch (n_regs)
604 {
605 case 1:
68ee6df6 606 pop (regno);
e8a68017
KH
607 break;
608 case 2:
68ee6df6
KH
609 emit_insn (gen_ldm_h8300s_2 (gen_rtx_REG (SImode, regno - 1),
610 gen_rtx_REG (SImode, regno)));
e8a68017
KH
611 break;
612 case 3:
68ee6df6
KH
613 emit_insn (gen_ldm_h8300s_3 (gen_rtx_REG (SImode, regno - 2),
614 gen_rtx_REG (SImode, regno - 1),
615 gen_rtx_REG (SImode, regno)));
e8a68017
KH
616 break;
617 case 4:
68ee6df6
KH
618 emit_insn (gen_ldm_h8300s_4 (gen_rtx_REG (SImode, regno - 3),
619 gen_rtx_REG (SImode, regno - 2),
620 gen_rtx_REG (SImode, regno - 1),
621 gen_rtx_REG (SImode, regno)));
e8a68017
KH
622 break;
623 default:
624 abort ();
625 }
07aae5c2 626 }
07aae5c2 627 }
48837e29 628
07e4d94e 629 /* Deallocate locals. */
4705d102 630 dosize (1, round_frame_size (get_frame_size ()));
a1616dd9 631
07e4d94e 632 /* Pop frame pointer if we had one. */
a1616dd9 633 if (frame_pointer_needed)
68ee6df6
KH
634 pop (FRAME_POINTER_REGNUM);
635}
a1616dd9 636
e392d367
KH
637/* Return nonzero if the current function is an interrupt
638 function. */
639
640int
cb713a8d 641h8300_current_function_interrupt_function_p (void)
e392d367
KH
642{
643 return (h8300_interrupt_function_p (current_function_decl)
644 || h8300_monitor_function_p (current_function_decl));
645}
646
48837e29
DE
647/* Output assembly code for the start of the file. */
648
1bc7c5b6
ZW
649static void
650h8300_file_start (void)
48837e29 651{
1bc7c5b6 652 default_file_start ();
8bd06267 653
48837e29 654 if (TARGET_H8300H)
1bc7c5b6 655 fputs (TARGET_NORMAL_MODE ? "\t.h8300hn\n" : "\t.h8300h\n", asm_out_file);
a1616dd9 656 else if (TARGET_H8300S)
1bc7c5b6 657 fputs (TARGET_NORMAL_MODE ? "\t.h8300sn\n" : "\t.h8300s\n", asm_out_file);
48837e29
DE
658}
659
660/* Output assembly language code for the end of file. */
661
a5fe455b 662static void
cb713a8d 663h8300_file_end (void)
48837e29 664{
a5fe455b 665 fputs ("\t.end\n", asm_out_file);
07aae5c2
SC
666}
667\f
68560db3 668/* Return true if OP is a valid source operand for an integer move
07aae5c2 669 instruction. */
48837e29 670
07aae5c2 671int
cb713a8d 672general_operand_src (rtx op, enum machine_mode mode)
07aae5c2 673{
ff6e1a2f
KH
674 if (GET_MODE (op) == mode
675 && GET_CODE (op) == MEM
676 && GET_CODE (XEXP (op, 0)) == POST_INC)
48837e29 677 return 1;
07aae5c2
SC
678 return general_operand (op, mode);
679}
680
681/* Return true if OP is a valid destination operand for an integer move
5660465a 682 instruction. */
48837e29 683
07aae5c2 684int
cb713a8d 685general_operand_dst (rtx op, enum machine_mode mode)
07aae5c2 686{
ff6e1a2f
KH
687 if (GET_MODE (op) == mode
688 && GET_CODE (op) == MEM
689 && GET_CODE (XEXP (op, 0)) == PRE_DEC)
48837e29 690 return 1;
07aae5c2
SC
691 return general_operand (op, mode);
692}
48837e29 693
4d4d89e2
KH
694/* Return true if OP is a constant that contains only one 1 in its
695 binary representation. */
48837e29
DE
696
697int
cb713a8d 698single_one_operand (rtx operand, enum machine_mode mode ATTRIBUTE_UNUSED)
48837e29 699{
4d4d89e2
KH
700 if (GET_CODE (operand) == CONST_INT)
701 {
702 /* We really need to do this masking because 0x80 in QImode is
703 represented as -128 for example. */
ef378bbe 704 if (exact_log2 (INTVAL (operand) & GET_MODE_MASK (mode)) >= 0)
4d4d89e2
KH
705 return 1;
706 }
707
708 return 0;
709}
710
711/* Return true if OP is a constant that contains only one 0 in its
712 binary representation. */
713
714int
cb713a8d 715single_zero_operand (rtx operand, enum machine_mode mode ATTRIBUTE_UNUSED)
4d4d89e2
KH
716{
717 if (GET_CODE (operand) == CONST_INT)
718 {
719 /* We really need to do this masking because 0x80 in QImode is
720 represented as -128 for example. */
ef378bbe 721 if (exact_log2 (~INTVAL (operand) & GET_MODE_MASK (mode)) >= 0)
4d4d89e2
KH
722 return 1;
723 }
724
725 return 0;
48837e29
DE
726}
727
48837e29
DE
728/* Return true if OP is a valid call operand. */
729
730int
cb713a8d 731call_insn_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
48837e29
DE
732{
733 if (GET_CODE (op) == MEM)
734 {
735 rtx inside = XEXP (op, 0);
736 if (register_operand (inside, Pmode))
737 return 1;
738 if (CONSTANT_ADDRESS_P (inside))
739 return 1;
740 }
741 return 0;
742}
743
22c9a795 744/* Return 1 if an addition/subtraction of a constant integer can be
997e5af8 745 transformed into two consecutive adds/subs that are faster than the
22c9a795 746 straightforward way. Otherwise, return 0. */
997e5af8 747
3b7d443c 748int
cb713a8d 749two_insn_adds_subs_operand (rtx op, enum machine_mode mode)
3b7d443c
JL
750{
751 if (GET_CODE (op) == CONST_INT)
752 {
009ac3d3 753 HOST_WIDE_INT value = INTVAL (op);
3b7d443c 754
997e5af8
KH
755 /* Force VALUE to be positive so that we do not have to consider
756 the negative case. */
757 if (value < 0)
758 value = -value;
009ac3d3
RH
759 if (TARGET_H8300H || TARGET_H8300S)
760 {
997e5af8
KH
761 /* A constant addition/subtraction takes 2 states in QImode,
762 4 states in HImode, and 6 states in SImode. Thus, the
763 only case we can win is when SImode is used, in which
c59ff527 764 case, two adds/subs are used, taking 4 states. */
997e5af8
KH
765 if (mode == SImode
766 && (value == 2 + 1
767 || value == 4 + 1
768 || value == 4 + 2
769 || value == 4 + 4))
22c9a795 770 return 1;
009ac3d3
RH
771 }
772 else
773 {
ae19f5ef
KH
774 /* We do not profit directly by splitting addition or
775 subtraction of 3 and 4. However, since these are
776 implemented as a sequence of adds or subs, they do not
777 clobber (cc0) unlike a sequence of add.b and add.x. */
778 if (mode == HImode
997e5af8
KH
779 && (value == 2 + 1
780 || value == 2 + 2))
009ac3d3
RH
781 return 1;
782 }
783 }
e6219736 784
e6219736
JL
785 return 0;
786}
787
3cee1a78
KH
788/* Split an add of a small constant into two adds/subs insns.
789
790 If USE_INCDEC_P is nonzero, we generate the last insn using inc/dec
791 instead of adds/subs. */
009ac3d3
RH
792
793void
cb713a8d 794split_adds_subs (enum machine_mode mode, rtx *operands)
3b7d443c 795{
009ac3d3
RH
796 HOST_WIDE_INT val = INTVAL (operands[1]);
797 rtx reg = operands[0];
9492393e
KH
798 HOST_WIDE_INT sign = 1;
799 HOST_WIDE_INT amount;
590734b6 800 rtx (*gen_add) (rtx, rtx, rtx);
3b7d443c 801
9492393e
KH
802 /* Force VAL to be positive so that we do not have to consider the
803 sign. */
804 if (val < 0)
3b7d443c 805 {
9492393e
KH
806 val = -val;
807 sign = -1;
808 }
3b7d443c 809
3cee1a78
KH
810 switch (mode)
811 {
812 case HImode:
590734b6 813 gen_add = gen_addhi3;
3cee1a78
KH
814 break;
815
816 case SImode:
590734b6 817 gen_add = gen_addsi3;
3cee1a78
KH
818 break;
819
820 default:
821 abort ();
822 }
823
9492393e
KH
824 /* Try different amounts in descending order. */
825 for (amount = (TARGET_H8300H || TARGET_H8300S) ? 4 : 2;
826 amount > 0;
827 amount /= 2)
828 {
1a63219b 829 for (; val >= amount; val -= amount)
590734b6 830 emit_insn (gen_add (reg, reg, GEN_INT (sign * amount)));
3b7d443c
JL
831 }
832
9492393e 833 return;
3b7d443c
JL
834}
835
f5b65a56
JL
836/* Return true if OP is a valid call operand, and OP represents
837 an operand for a small call (4 bytes instead of 6 bytes). */
838
839int
cb713a8d 840small_call_insn_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
f5b65a56
JL
841{
842 if (GET_CODE (op) == MEM)
843 {
844 rtx inside = XEXP (op, 0);
845
846 /* Register indirect is a small call. */
847 if (register_operand (inside, Pmode))
848 return 1;
849
dc66a1c4 850 /* A call through the function vector is a small call too. */
f5b65a56 851 if (GET_CODE (inside) == SYMBOL_REF
dc66a1c4 852 && (SYMBOL_REF_FLAGS (inside) & SYMBOL_FLAG_FUNCVEC_FUNCTION))
f5b65a56
JL
853 return 1;
854 }
855 /* Otherwise it's a large call. */
856 return 0;
857}
858
48837e29
DE
859/* Return true if OP is a valid jump operand. */
860
861int
cb713a8d 862jump_address_operand (rtx op, enum machine_mode mode)
48837e29
DE
863{
864 if (GET_CODE (op) == REG)
865 return mode == Pmode;
866
867 if (GET_CODE (op) == MEM)
868 {
869 rtx inside = XEXP (op, 0);
870 if (register_operand (inside, Pmode))
871 return 1;
872 if (CONSTANT_ADDRESS_P (inside))
873 return 1;
874 }
875 return 0;
876}
877
43a88a8c 878/* Recognize valid operands for bit-field instructions. */
48837e29
DE
879
880extern int rtx_equal_function_value_matters;
881
882int
cb713a8d 883bit_operand (rtx op, enum machine_mode mode)
48837e29 884{
f411c849 885 /* We can accept any general operand, except that MEM operands must
48837e29
DE
886 be limited to those that use addresses valid for the 'U' constraint. */
887 if (!general_operand (op, mode))
888 return 0;
889
890 /* Accept any mem during RTL generation. Otherwise, the code that does
891 insv and extzv will think that we can not handle memory. However,
892 to avoid reload problems, we only accept 'U' MEM operands after RTL
893 generation. This means that any named pattern which uses this predicate
894 must force its operands to match 'U' before emitting RTL. */
895
896 if (GET_CODE (op) == REG)
897 return 1;
898 if (GET_CODE (op) == SUBREG)
899 return 1;
6620997b
KH
900 return (GET_CODE (op) == MEM
901 && EXTRA_CONSTRAINT (op, 'U'));
48837e29
DE
902}
903
887a8bd9 904int
cb713a8d 905bit_memory_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
887a8bd9
JL
906{
907 return (GET_CODE (op) == MEM
908 && EXTRA_CONSTRAINT (op, 'U'));
909}
910
07aae5c2 911/* Handle machine specific pragmas for compatibility with existing
48837e29 912 compilers for the H8/300.
07aae5c2 913
f411c849 914 pragma saveall generates prologue/epilogue code which saves and
07aae5c2 915 restores all the registers on function entry.
48837e29 916
07aae5c2
SC
917 pragma interrupt saves and restores all registers, and exits with
918 an rte instruction rather than an rts. A pointer to a function
919 with this attribute may be safely used in an interrupt vector. */
48837e29 920
8b97c5f8 921void
cb713a8d 922h8300_pr_interrupt (struct cpp_reader *pfile ATTRIBUTE_UNUSED)
07aae5c2 923{
e392d367 924 pragma_interrupt = 1;
8b97c5f8 925}
05a81fe5 926
8b97c5f8 927void
cb713a8d 928h8300_pr_saveall (struct cpp_reader *pfile ATTRIBUTE_UNUSED)
8b97c5f8
ZW
929{
930 pragma_saveall = 1;
07aae5c2 931}
8b97c5f8 932
64bead4c
KH
933/* If the next function argument with MODE and TYPE is to be passed in
934 a register, return a reg RTX for the hard register in which to pass
935 the argument. CUM represents the state after the last argument.
936 If the argument is to be pushed, NULL_RTX is returned. */
48837e29 937
07aae5c2 938rtx
cb713a8d
KH
939function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
940 tree type, int named)
07aae5c2 941{
0ea6f6a0
KH
942 static const char *const hand_list[] = {
943 "__main",
944 "__cmpsi2",
945 "__divhi3",
946 "__modhi3",
947 "__udivhi3",
948 "__umodhi3",
949 "__divsi3",
950 "__modsi3",
951 "__udivsi3",
952 "__umodsi3",
953 "__mulhi3",
954 "__mulsi3",
955 "__reg_memcpy",
956 "__reg_memset",
957 "__ucmpsi2",
958 0,
959 };
960
7192cbf1 961 rtx result = NULL_RTX;
441d04c6 962 const char *fname;
48837e29
DE
963 int regpass = 0;
964
dd07092e
JL
965 /* Never pass unnamed arguments in registers. */
966 if (!named)
7192cbf1 967 return NULL_RTX;
dd07092e 968
48837e29
DE
969 /* Pass 3 regs worth of data in regs when user asked on the command line. */
970 if (TARGET_QUICKCALL)
971 regpass = 3;
972
973 /* If calling hand written assembler, use 4 regs of args. */
48837e29
DE
974 if (cum->libcall)
975 {
441d04c6 976 const char * const *p;
48837e29
DE
977
978 fname = XSTR (cum->libcall, 0);
979
980 /* See if this libcall is one of the hand coded ones. */
48837e29
DE
981 for (p = hand_list; *p && strcmp (*p, fname) != 0; p++)
982 ;
07aae5c2 983
48837e29
DE
984 if (*p)
985 regpass = 4;
986 }
987
988 if (regpass)
989 {
990 int size;
991
992 if (mode == BLKmode)
993 size = int_size_in_bytes (type);
994 else
995 size = GET_MODE_SIZE (mode);
996
15e0e275
KH
997 if (size + cum->nbytes <= regpass * UNITS_PER_WORD
998 && cum->nbytes / UNITS_PER_WORD <= 3)
999 result = gen_rtx_REG (mode, cum->nbytes / UNITS_PER_WORD);
48837e29 1000 }
07aae5c2 1001
48837e29
DE
1002 return result;
1003}
1004\f
3c50106f 1005static int
cb713a8d 1006h8300_and_costs (rtx x)
73cc75e9
KH
1007{
1008 rtx operands[4];
1009
1010 if (GET_MODE (x) == QImode)
1011 return 1;
1012
1013 if (GET_MODE (x) != HImode
1014 && GET_MODE (x) != SImode)
1015 return 100;
1016
1017 operands[0] = NULL;
1018 operands[1] = NULL;
1019 operands[2] = XEXP (x, 1);
1020 operands[3] = x;
4f4ebda3 1021 return compute_logical_op_length (GET_MODE (x), operands) / 2;
73cc75e9
KH
1022}
1023
3c50106f 1024static int
cb713a8d 1025h8300_shift_costs (rtx x)
ae557002
KH
1026{
1027 rtx operands[4];
1028
1029 if (GET_MODE (x) != QImode
1030 && GET_MODE (x) != HImode
1031 && GET_MODE (x) != SImode)
1032 return 100;
1033
1034 operands[0] = NULL;
1035 operands[1] = NULL;
1036 operands[2] = XEXP (x, 1);
1037 operands[3] = x;
4f4ebda3 1038 return compute_a_shift_length (NULL, operands) / 2;
ae557002 1039}
3c50106f
RH
1040
1041static bool
cb713a8d 1042h8300_rtx_costs (rtx x, int code, int outer_code, int *total)
3c50106f
RH
1043{
1044 switch (code)
1045 {
08dca707
KH
1046 case CONST_INT:
1047 {
1048 HOST_WIDE_INT n = INTVAL (x);
1049
1050 if (-4 <= n || n <= 4)
1051 {
1052 switch ((int) n)
1053 {
1054 case 0:
1055 *total = 0;
1056 return true;
1057 case 1:
1058 case 2:
1059 case -1:
1060 case -2:
1061 *total = 0 + (outer_code == SET);
1062 return true;
1063 case 4:
1064 case -4:
1065 if (TARGET_H8300H || TARGET_H8300S)
1066 *total = 0 + (outer_code == SET);
1067 else
1068 *total = 1;
1069 return true;
1070 }
1071 }
1072 *total = 1;
1073 return true;
1074 }
1075
1076 case CONST:
1077 case LABEL_REF:
1078 case SYMBOL_REF:
1079 *total = 3;
1080 return true;
1081
1082 case CONST_DOUBLE:
1083 *total = 20;
1084 return true;
1085
3c50106f
RH
1086 case AND:
1087 *total = COSTS_N_INSNS (h8300_and_costs (x));
1088 return true;
1089
1090 /* We say that MOD and DIV are so expensive because otherwise we'll
1091 generate some really horrible code for division of a power of two. */
1092 case MOD:
1093 case DIV:
1094 *total = 60;
1095 return true;
1096
1097 case MULT:
1098 *total = 20;
1099 return true;
1100
1101 case ASHIFT:
1102 case ASHIFTRT:
1103 case LSHIFTRT:
1104 *total = COSTS_N_INSNS (h8300_shift_costs (x));
1105 return true;
1106
1107 case ROTATE:
1108 case ROTATERT:
1109 if (GET_MODE (x) == HImode)
1110 *total = 2;
1111 else
1112 *total = 8;
1113 return true;
1114
1115 default:
08dca707 1116 *total = 4;
3c50106f
RH
1117 return true;
1118 }
1119}
48837e29 1120\f
07aae5c2
SC
1121/* Documentation for the machine specific operand escapes:
1122
48837e29
DE
1123 'E' like s but negative.
1124 'F' like t but negative.
1125 'G' constant just the negative
15dc331e
JL
1126 'R' print operand as a byte:8 address if appropriate, else fall back to
1127 'X' handling.
48837e29 1128 'S' print operand as a long word
07aae5c2 1129 'T' print operand as a word
48837e29
DE
1130 'V' find the set bit, and print its number.
1131 'W' find the clear bit, and print its number.
1132 'X' print operand as a byte
07aae5c2 1133 'Y' print either l or h depending on whether last 'Z' operand < 8 or >= 8.
15dc331e 1134 If this operand isn't a register, fall back to 'R' handling.
48837e29 1135 'Z' print int & 7.
b059c02a 1136 'c' print the opcode corresponding to rtl
48837e29
DE
1137 'e' first word of 32 bit value - if reg, then least reg. if mem
1138 then least. if const then most sig word
1139 'f' second word of 32 bit value - if reg, then biggest reg. if mem
1140 then +2. if const then least sig word
07aae5c2
SC
1141 'j' print operand as condition code.
1142 'k' print operand as reverse condition code.
48837e29
DE
1143 's' print as low byte of 16 bit value
1144 't' print as high byte of 16 bit value
1145 'w' print as low byte of 32 bit value
1146 'x' print as 2nd byte of 32 bit value
1147 'y' print as 3rd byte of 32 bit value
1148 'z' print as msb of 32 bit value
1149*/
07aae5c2
SC
1150
1151/* Return assembly language string which identifies a comparison type. */
1152
441d04c6 1153static const char *
cb713a8d 1154cond_string (enum rtx_code code)
07aae5c2
SC
1155{
1156 switch (code)
1157 {
1158 case NE:
1159 return "ne";
1160 case EQ:
1161 return "eq";
1162 case GE:
1163 return "ge";
1164 case GT:
1165 return "gt";
1166 case LE:
1167 return "le";
1168 case LT:
1169 return "lt";
1170 case GEU:
1171 return "hs";
1172 case GTU:
1173 return "hi";
1174 case LEU:
1175 return "ls";
1176 case LTU:
1177 return "lo";
1178 default:
1179 abort ();
1180 }
1181}
1182
1183/* Print operand X using operand code CODE to assembly language output file
1184 FILE. */
1185
1186void
cb713a8d 1187print_operand (FILE *file, rtx x, int code)
07aae5c2 1188{
269c14e1 1189 /* This is used for communication between codes V,W,Z and Y. */
07aae5c2
SC
1190 static int bitint;
1191
1192 switch (code)
1193 {
48837e29
DE
1194 case 'E':
1195 switch (GET_CODE (x))
1196 {
1197 case REG:
1198 fprintf (file, "%sl", names_big[REGNO (x)]);
1199 break;
1200 case CONST_INT:
b47900aa 1201 fprintf (file, "#%ld", (-INTVAL (x)) & 0xff);
48837e29
DE
1202 break;
1203 default:
1204 abort ();
1205 }
1206 break;
1207 case 'F':
1208 switch (GET_CODE (x))
1209 {
1210 case REG:
1211 fprintf (file, "%sh", names_big[REGNO (x)]);
1212 break;
1213 case CONST_INT:
b47900aa 1214 fprintf (file, "#%ld", ((-INTVAL (x)) & 0xff00) >> 8);
48837e29
DE
1215 break;
1216 default:
1217 abort ();
1218 }
1219 break;
07aae5c2
SC
1220 case 'G':
1221 if (GET_CODE (x) != CONST_INT)
1222 abort ();
b47900aa 1223 fprintf (file, "#%ld", 0xff & (-INTVAL (x)));
07aae5c2 1224 break;
48837e29
DE
1225 case 'S':
1226 if (GET_CODE (x) == REG)
1227 fprintf (file, "%s", names_extended[REGNO (x)]);
07aae5c2 1228 else
48837e29 1229 goto def;
07aae5c2 1230 break;
48837e29
DE
1231 case 'T':
1232 if (GET_CODE (x) == REG)
1233 fprintf (file, "%s", names_big[REGNO (x)]);
07aae5c2 1234 else
48837e29 1235 goto def;
07aae5c2 1236 break;
48837e29 1237 case 'V':
4d4d89e2 1238 bitint = exact_log2 (INTVAL (x) & 0xff);
48837e29 1239 if (bitint == -1)
07aae5c2 1240 abort ();
4d4d89e2 1241 fprintf (file, "#%d", bitint);
07aae5c2 1242 break;
48837e29 1243 case 'W':
07aae5c2
SC
1244 bitint = exact_log2 ((~INTVAL (x)) & 0xff);
1245 if (bitint == -1)
1246 abort ();
4d4d89e2 1247 fprintf (file, "#%d", bitint);
07aae5c2 1248 break;
15dc331e 1249 case 'R':
48837e29
DE
1250 case 'X':
1251 if (GET_CODE (x) == REG)
1252 fprintf (file, "%s", byte_reg (x, 0));
1253 else
1254 goto def;
1255 break;
1256 case 'Y':
07aae5c2
SC
1257 if (bitint == -1)
1258 abort ();
48837e29
DE
1259 if (GET_CODE (x) == REG)
1260 fprintf (file, "%s%c", names_big[REGNO (x)], bitint > 7 ? 'h' : 'l');
1261 else
15dc331e 1262 print_operand (file, x, 'R');
48837e29
DE
1263 bitint = -1;
1264 break;
1265 case 'Z':
1266 bitint = INTVAL (x);
07aae5c2
SC
1267 fprintf (file, "#%d", bitint & 7);
1268 break;
b059c02a
KH
1269 case 'c':
1270 switch (GET_CODE (x))
1271 {
1272 case IOR:
1273 fprintf (file, "or");
1274 break;
1275 case XOR:
1276 fprintf (file, "xor");
1277 break;
5abfd1af
KH
1278 case AND:
1279 fprintf (file, "and");
1280 break;
b059c02a
KH
1281 default:
1282 break;
1283 }
1284 break;
07aae5c2
SC
1285 case 'e':
1286 switch (GET_CODE (x))
1287 {
1288 case REG:
48837e29
DE
1289 if (TARGET_H8300)
1290 fprintf (file, "%s", names_big[REGNO (x)]);
1291 else
1292 fprintf (file, "%s", names_upper_extended[REGNO (x)]);
07aae5c2
SC
1293 break;
1294 case MEM:
07aae5c2
SC
1295 print_operand (file, x, 0);
1296 break;
1297 case CONST_INT:
b47900aa 1298 fprintf (file, "#%ld", ((INTVAL (x) >> 16) & 0xffff));
07aae5c2 1299 break;
808fbfac
JL
1300 case CONST_DOUBLE:
1301 {
1302 long val;
1303 REAL_VALUE_TYPE rv;
1304 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
1305 REAL_VALUE_TO_TARGET_SINGLE (rv, val);
441d04c6 1306 fprintf (file, "#%ld", ((val >> 16) & 0xffff));
808fbfac
JL
1307 break;
1308 }
07aae5c2
SC
1309 default:
1310 abort ();
1311 break;
1312 }
1313 break;
07aae5c2
SC
1314 case 'f':
1315 switch (GET_CODE (x))
1316 {
1317 case REG:
48837e29
DE
1318 if (TARGET_H8300)
1319 fprintf (file, "%s", names_big[REGNO (x) + 1]);
1320 else
1321 fprintf (file, "%s", names_big[REGNO (x)]);
07aae5c2 1322 break;
07aae5c2 1323 case MEM:
b72f00af 1324 x = adjust_address (x, HImode, 2);
07aae5c2
SC
1325 print_operand (file, x, 0);
1326 break;
07aae5c2 1327 case CONST_INT:
b47900aa 1328 fprintf (file, "#%ld", INTVAL (x) & 0xffff);
07aae5c2 1329 break;
808fbfac
JL
1330 case CONST_DOUBLE:
1331 {
1332 long val;
1333 REAL_VALUE_TYPE rv;
1334 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
1335 REAL_VALUE_TO_TARGET_SINGLE (rv, val);
441d04c6 1336 fprintf (file, "#%ld", (val & 0xffff));
808fbfac
JL
1337 break;
1338 }
07aae5c2
SC
1339 default:
1340 abort ();
1341 }
1342 break;
07aae5c2 1343 case 'j':
761c70aa 1344 fputs (cond_string (GET_CODE (x)), file);
07aae5c2 1345 break;
07aae5c2 1346 case 'k':
761c70aa 1347 fputs (cond_string (reverse_condition (GET_CODE (x))), file);
07aae5c2 1348 break;
48837e29
DE
1349 case 's':
1350 if (GET_CODE (x) == CONST_INT)
b47900aa 1351 fprintf (file, "#%ld", (INTVAL (x)) & 0xff);
48837e29
DE
1352 else
1353 fprintf (file, "%s", byte_reg (x, 0));
1354 break;
1355 case 't':
1356 if (GET_CODE (x) == CONST_INT)
b47900aa 1357 fprintf (file, "#%ld", (INTVAL (x) >> 8) & 0xff);
48837e29
DE
1358 else
1359 fprintf (file, "%s", byte_reg (x, 1));
1360 break;
48837e29
DE
1361 case 'w':
1362 if (GET_CODE (x) == CONST_INT)
b47900aa 1363 fprintf (file, "#%ld", INTVAL (x) & 0xff);
48837e29 1364 else
a1616dd9
JL
1365 fprintf (file, "%s",
1366 byte_reg (x, TARGET_H8300 ? 2 : 0));
48837e29
DE
1367 break;
1368 case 'x':
1369 if (GET_CODE (x) == CONST_INT)
b47900aa 1370 fprintf (file, "#%ld", (INTVAL (x) >> 8) & 0xff);
48837e29 1371 else
a1616dd9
JL
1372 fprintf (file, "%s",
1373 byte_reg (x, TARGET_H8300 ? 3 : 1));
48837e29
DE
1374 break;
1375 case 'y':
1376 if (GET_CODE (x) == CONST_INT)
b47900aa 1377 fprintf (file, "#%ld", (INTVAL (x) >> 16) & 0xff);
48837e29
DE
1378 else
1379 fprintf (file, "%s", byte_reg (x, 0));
1380 break;
1381 case 'z':
1382 if (GET_CODE (x) == CONST_INT)
b47900aa 1383 fprintf (file, "#%ld", (INTVAL (x) >> 24) & 0xff);
48837e29
DE
1384 else
1385 fprintf (file, "%s", byte_reg (x, 1));
1386 break;
1387
07aae5c2 1388 default:
48837e29 1389 def:
07aae5c2
SC
1390 switch (GET_CODE (x))
1391 {
1392 case REG:
48837e29
DE
1393 switch (GET_MODE (x))
1394 {
1395 case QImode:
269c14e1 1396#if 0 /* Is it asm ("mov.b %0,r2l", ...) */
48837e29
DE
1397 fprintf (file, "%s", byte_reg (x, 0));
1398#else /* ... or is it asm ("mov.b %0l,r2l", ...) */
1399 fprintf (file, "%s", names_big[REGNO (x)]);
1400#endif
1401 break;
1402 case HImode:
1403 fprintf (file, "%s", names_big[REGNO (x)]);
1404 break;
1405 case SImode:
8977e8a7 1406 case SFmode:
48837e29
DE
1407 fprintf (file, "%s", names_extended[REGNO (x)]);
1408 break;
1409 default:
1410 abort ();
1411 }
07aae5c2
SC
1412 break;
1413
1414 case MEM:
87e4ee91
KH
1415 {
1416 rtx addr = XEXP (x, 0);
1417
1418 fprintf (file, "@");
1419 output_address (addr);
1420
bc8db8a1
KH
1421 /* We fall back from smaller addressing to larger
1422 addressing in various ways depending on CODE. */
1423 switch (code)
1424 {
1425 case 'R':
1426 /* Used for mov.b and bit operations. */
7c143ed2 1427 if (h8300_eightbit_constant_address_p (addr))
bc8db8a1
KH
1428 {
1429 fprintf (file, ":8");
1430 break;
1431 }
1432
1433 /* Fall through. We should not get here if we are
1434 processing bit operations on H8/300 or H8/300H
1435 because 'U' constraint does not allow bit
1436 operations on the tiny area on these machines. */
1437
1438 case 'T':
1439 case 'S':
1440 /* Used for mov.w and mov.l. */
56b8e164 1441 if (h8300_tiny_constant_address_p (addr))
bc8db8a1
KH
1442 fprintf (file, ":16");
1443 break;
1444 default:
1445 break;
1446 }
87e4ee91 1447 }
07aae5c2
SC
1448 break;
1449
1450 case CONST_INT:
1451 case SYMBOL_REF:
1452 case CONST:
1453 case LABEL_REF:
1454 fprintf (file, "#");
1455 print_operand_address (file, x);
1456 break;
808fbfac
JL
1457 case CONST_DOUBLE:
1458 {
1459 long val;
1460 REAL_VALUE_TYPE rv;
1461 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
1462 REAL_VALUE_TO_TARGET_SINGLE (rv, val);
441d04c6 1463 fprintf (file, "#%ld", val);
808fbfac
JL
1464 break;
1465 }
441d04c6
KG
1466 default:
1467 break;
07aae5c2
SC
1468 }
1469 }
1470}
1471
1472/* Output assembly language output for the address ADDR to FILE. */
1473
1474void
cb713a8d 1475print_operand_address (FILE *file, rtx addr)
07aae5c2
SC
1476{
1477 switch (GET_CODE (addr))
1478 {
1479 case REG:
48837e29 1480 fprintf (file, "%s", h8_reg_names[REGNO (addr)]);
07aae5c2
SC
1481 break;
1482
1483 case PRE_DEC:
48837e29 1484 fprintf (file, "-%s", h8_reg_names[REGNO (XEXP (addr, 0))]);
07aae5c2
SC
1485 break;
1486
1487 case POST_INC:
48837e29 1488 fprintf (file, "%s+", h8_reg_names[REGNO (XEXP (addr, 0))]);
07aae5c2
SC
1489 break;
1490
1491 case PLUS:
1492 fprintf (file, "(");
1493 if (GET_CODE (XEXP (addr, 0)) == REG)
1494 {
1495 /* reg,foo */
1496 print_operand_address (file, XEXP (addr, 1));
1497 fprintf (file, ",");
1498 print_operand_address (file, XEXP (addr, 0));
1499 }
1500 else
1501 {
1502 /* foo+k */
1503 print_operand_address (file, XEXP (addr, 0));
1504 fprintf (file, "+");
1505 print_operand_address (file, XEXP (addr, 1));
1506 }
1507 fprintf (file, ")");
1508 break;
1509
1510 case CONST_INT:
48837e29 1511 {
64530b82 1512 /* Since the H8/300 only has 16 bit pointers, negative values are also
48837e29
DE
1513 those >= 32768. This happens for example with pointer minus a
1514 constant. We don't want to turn (char *p - 2) into
1515 (char *p + 65534) because loop unrolling can build upon this
1516 (IE: char *p + 131068). */
1517 int n = INTVAL (addr);
1518 if (TARGET_H8300)
1519 n = (int) (short) n;
7a770d8b 1520 fprintf (file, "%d", n);
48837e29
DE
1521 break;
1522 }
07aae5c2
SC
1523
1524 default:
1525 output_addr_const (file, addr);
1526 break;
1527 }
1528}
1529\f
07aae5c2
SC
1530/* Output all insn addresses and their sizes into the assembly language
1531 output file. This is helpful for debugging whether the length attributes
1532 in the md file are correct. This is not meant to be a user selectable
1533 option. */
1534
1535void
cb713a8d
KH
1536final_prescan_insn (rtx insn, rtx *operand ATTRIBUTE_UNUSED,
1537 int num_operands ATTRIBUTE_UNUSED)
07aae5c2
SC
1538{
1539 /* This holds the last insn address. */
1540 static int last_insn_address = 0;
1541
7798db98 1542 const int uid = INSN_UID (insn);
07aae5c2
SC
1543
1544 if (TARGET_ADDRESSES)
1545 {
9d98a694
AO
1546 fprintf (asm_out_file, "; 0x%x %d\n", INSN_ADDRESSES (uid),
1547 INSN_ADDRESSES (uid) - last_insn_address);
1548 last_insn_address = INSN_ADDRESSES (uid);
07aae5c2
SC
1549 }
1550}
1551
48837e29
DE
1552/* Prepare for an SI sized move. */
1553
1554int
cb713a8d 1555do_movsi (rtx operands[])
07aae5c2 1556{
48837e29
DE
1557 rtx src = operands[1];
1558 rtx dst = operands[0];
1559 if (!reload_in_progress && !reload_completed)
1560 {
1561 if (!register_operand (dst, GET_MODE (dst)))
1562 {
1563 rtx tmp = gen_reg_rtx (GET_MODE (dst));
1564 emit_move_insn (tmp, src);
1565 operands[1] = tmp;
1566 }
1567 }
1568 return 0;
1569}
1570
1571/* Function for INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET).
07e4d94e
KH
1572 Define the offset between two registers, one to be eliminated, and
1573 the other its replacement, at the start of a routine. */
07aae5c2 1574
48837e29 1575int
cb713a8d 1576h8300_initial_elimination_offset (int from, int to)
48837e29
DE
1577{
1578 int offset = 0;
d18ad191
KH
1579 /* The number of bytes that the return address takes on the stack. */
1580 int pc_size = POINTER_SIZE / BITS_PER_UNIT;
48837e29
DE
1581
1582 if (from == ARG_POINTER_REGNUM && to == FRAME_POINTER_REGNUM)
d18ad191 1583 offset = pc_size + frame_pointer_needed * UNITS_PER_WORD;
1aae372e
JL
1584 else if (from == RETURN_ADDRESS_POINTER_REGNUM && to == FRAME_POINTER_REGNUM)
1585 offset = frame_pointer_needed * UNITS_PER_WORD;
48837e29 1586 else
07aae5c2 1587 {
48837e29
DE
1588 int regno;
1589
1590 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
d01d2903 1591 if (WORD_REG_USED (regno))
48837e29
DE
1592 offset += UNITS_PER_WORD;
1593
1594 /* See the comments for get_frame_size. We need to round it up to
1595 STACK_BOUNDARY. */
1596
1a86c850 1597 offset += round_frame_size (get_frame_size ());
48837e29
DE
1598
1599 if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
d18ad191
KH
1600 /* Skip saved PC. */
1601 offset += pc_size;
48837e29 1602 }
39ba95b5 1603
48837e29
DE
1604 return offset;
1605}
1606
1aae372e 1607rtx
cb713a8d 1608h8300_return_addr_rtx (int count, rtx frame)
1aae372e
JL
1609{
1610 rtx ret;
1611
1612 if (count == 0)
1613 ret = gen_rtx_MEM (Pmode,
1614 gen_rtx_REG (Pmode, RETURN_ADDRESS_POINTER_REGNUM));
1615 else if (flag_omit_frame_pointer)
1616 return (rtx) 0;
1617 else
1618 ret = gen_rtx_MEM (Pmode,
1619 memory_address (Pmode,
1620 plus_constant (frame, UNITS_PER_WORD)));
1621 set_mem_alias_set (ret, get_frame_alias_set ());
1622 return ret;
1623}
1624
48837e29
DE
1625/* Update the condition code from the insn. */
1626
441d04c6 1627void
cb713a8d 1628notice_update_cc (rtx body, rtx insn)
48837e29 1629{
d99c740f
KH
1630 rtx set;
1631
48837e29
DE
1632 switch (get_attr_cc (insn))
1633 {
1634 case CC_NONE:
269c14e1 1635 /* Insn does not affect CC at all. */
48837e29
DE
1636 break;
1637
1638 case CC_NONE_0HIT:
269c14e1 1639 /* Insn does not change CC, but the 0'th operand has been changed. */
48837e29 1640 if (cc_status.value1 != 0
1ccbefce 1641 && reg_overlap_mentioned_p (recog_data.operand[0], cc_status.value1))
48837e29 1642 cc_status.value1 = 0;
d4d6d0ce
KH
1643 if (cc_status.value2 != 0
1644 && reg_overlap_mentioned_p (recog_data.operand[0], cc_status.value2))
1645 cc_status.value2 = 0;
48837e29
DE
1646 break;
1647
065bbfe6 1648 case CC_SET_ZN:
1ccbefce 1649 /* Insn sets the Z,N flags of CC to recog_data.operand[0].
269c14e1
DE
1650 The V flag is unusable. The C flag may or may not be known but
1651 that's ok because alter_cond will change tests to use EQ/NE. */
48837e29 1652 CC_STATUS_INIT;
269c14e1 1653 cc_status.flags |= CC_OVERFLOW_UNUSABLE | CC_NO_CARRY;
d99c740f
KH
1654 set = single_set (insn);
1655 cc_status.value1 = SET_SRC (set);
1656 if (SET_DEST (set) != cc0_rtx)
1657 cc_status.value2 = SET_DEST (set);
48837e29
DE
1658 break;
1659
065bbfe6 1660 case CC_SET_ZNV:
1ccbefce 1661 /* Insn sets the Z,N,V flags of CC to recog_data.operand[0].
065bbfe6
JL
1662 The C flag may or may not be known but that's ok because
1663 alter_cond will change tests to use EQ/NE. */
1664 CC_STATUS_INIT;
1665 cc_status.flags |= CC_NO_CARRY;
d99c740f
KH
1666 set = single_set (insn);
1667 cc_status.value1 = SET_SRC (set);
1668 if (SET_DEST (set) != cc0_rtx)
c8fcf20c
KH
1669 {
1670 /* If the destination is STRICT_LOW_PART, strip off
1671 STRICT_LOW_PART. */
1672 if (GET_CODE (SET_DEST (set)) == STRICT_LOW_PART)
1673 cc_status.value2 = XEXP (SET_DEST (set), 0);
1674 else
1675 cc_status.value2 = SET_DEST (set);
1676 }
065bbfe6
JL
1677 break;
1678
269c14e1
DE
1679 case CC_COMPARE:
1680 /* The insn is a compare instruction. */
48837e29 1681 CC_STATUS_INIT;
269c14e1 1682 cc_status.value1 = SET_SRC (body);
48837e29
DE
1683 break;
1684
48837e29 1685 case CC_CLOBBER:
269c14e1 1686 /* Insn doesn't leave CC in a usable state. */
48837e29
DE
1687 CC_STATUS_INIT;
1688 break;
07aae5c2 1689 }
48837e29
DE
1690}
1691
8ccf5d5f
KH
1692/* Return nonzero if X is a stack pointer. */
1693
1694int
cb713a8d 1695stack_pointer_operand (rtx x, enum machine_mode mode ATTRIBUTE_UNUSED)
8ccf5d5f
KH
1696{
1697 return x == stack_pointer_rtx;
1698}
1699
8ccf5d5f
KH
1700/* Return nonzero if X is a constant whose absolute value is greater
1701 than 2. */
1702
1703int
cb713a8d 1704const_int_gt_2_operand (rtx x, enum machine_mode mode ATTRIBUTE_UNUSED)
8ccf5d5f
KH
1705{
1706 return (GET_CODE (x) == CONST_INT
1707 && abs (INTVAL (x)) > 2);
1708}
1709
1710/* Return nonzero if X is a constant whose absolute value is no
1711 smaller than 8. */
1712
1713int
cb713a8d 1714const_int_ge_8_operand (rtx x, enum machine_mode mode ATTRIBUTE_UNUSED)
8ccf5d5f
KH
1715{
1716 return (GET_CODE (x) == CONST_INT
1717 && abs (INTVAL (x)) >= 8);
1718}
1719
2873836b
KH
1720/* Return nonzero if X is a constant expressible in QImode. */
1721
1722int
cb713a8d 1723const_int_qi_operand (rtx x, enum machine_mode mode ATTRIBUTE_UNUSED)
2873836b
KH
1724{
1725 return (GET_CODE (x) == CONST_INT
1726 && (INTVAL (x) & 0xff) == INTVAL (x));
1727}
1728
1729/* Return nonzero if X is a constant expressible in HImode. */
1730
1731int
cb713a8d 1732const_int_hi_operand (rtx x, enum machine_mode mode ATTRIBUTE_UNUSED)
2873836b
KH
1733{
1734 return (GET_CODE (x) == CONST_INT
1735 && (INTVAL (x) & 0xffff) == INTVAL (x));
1736}
1737
f9d2de4d
KH
1738/* Return nonzero if X is a constant suitable for inc/dec. */
1739
1740int
cb713a8d 1741incdec_operand (rtx x, enum machine_mode mode ATTRIBUTE_UNUSED)
f9d2de4d
KH
1742{
1743 return (GET_CODE (x) == CONST_INT
1744 && (CONST_OK_FOR_M (INTVAL (x))
1745 || CONST_OK_FOR_O (INTVAL (x))));
1746}
1747
1748/* Return nonzero if X is either EQ or NE. */
1749
1750int
cb713a8d 1751eqne_operator (rtx x, enum machine_mode mode ATTRIBUTE_UNUSED)
f9d2de4d
KH
1752{
1753 enum rtx_code code = GET_CODE (x);
1754
1755 return (code == EQ || code == NE);
1756}
1757
9a2dd2dd
KH
1758/* Return nonzero if X is GT, LE, GTU, or LEU. */
1759
1760int
cb713a8d 1761gtle_operator (rtx x, enum machine_mode mode ATTRIBUTE_UNUSED)
9a2dd2dd
KH
1762{
1763 enum rtx_code code = GET_CODE (x);
1764
1765 return (code == GT || code == LE || code == GTU || code == LEU);
1766}
1767
717d8b71
KH
1768/* Return nonzero if X is either GTU or LEU. */
1769
1770int
cb713a8d 1771gtuleu_operator (rtx x, enum machine_mode mode ATTRIBUTE_UNUSED)
717d8b71
KH
1772{
1773 enum rtx_code code = GET_CODE (x);
1774
1775 return (code == GTU || code == LEU);
1776}
1777
b059c02a
KH
1778/* Return nonzero if X is either IOR or XOR. */
1779
1780int
cb713a8d 1781iorxor_operator (rtx x, enum machine_mode mode ATTRIBUTE_UNUSED)
b059c02a
KH
1782{
1783 enum rtx_code code = GET_CODE (x);
1784
1785 return (code == IOR || code == XOR);
1786}
1787
07e4d94e 1788/* Recognize valid operators for bit instructions. */
48837e29
DE
1789
1790int
cb713a8d 1791bit_operator (rtx x, enum machine_mode mode ATTRIBUTE_UNUSED)
48837e29
DE
1792{
1793 enum rtx_code code = GET_CODE (x);
07aae5c2 1794
48837e29
DE
1795 return (code == XOR
1796 || code == AND
1797 || code == IOR);
07aae5c2 1798}
48837e29 1799\f
7948a9ea
KH
1800/* Return the length of mov instruction. */
1801
1802unsigned int
1803compute_mov_length (rtx *operands)
1804{
1805 /* If the mov instruction involves a memory operand, we compute the
1806 length, assuming the largest addressing mode is used, and then
1807 adjust later in the function. Otherwise, we compute and return
1808 the exact length in one step. */
1809 enum machine_mode mode = GET_MODE (operands[0]);
1810 rtx dest = operands[0];
1811 rtx src = operands[1];
1812 rtx addr;
1813
1814 if (GET_CODE (src) == MEM)
1815 addr = XEXP (src, 0);
1816 else if (GET_CODE (dest) == MEM)
1817 addr = XEXP (dest, 0);
1818 else
1819 addr = NULL_RTX;
1820
1821 if (TARGET_H8300)
1822 {
1823 unsigned int base_length;
1824
1825 switch (mode)
1826 {
1827 case QImode:
1828 if (addr == NULL_RTX)
1829 return 2;
1830
1831 /* The eightbit addressing is available only in QImode, so
1832 go ahead and take care of it. */
1833 if (h8300_eightbit_constant_address_p (addr))
1834 return 2;
1835
1836 base_length = 4;
1837 break;
1838
1839 case HImode:
1840 if (addr == NULL_RTX)
1841 {
1842 if (REG_P (src))
1843 return 2;
1844
1845 if (src == const0_rtx)
1846 return 2;
1847
1848 return 4;
1849 }
1850
1851 base_length = 4;
1852 break;
1853
1854 case SImode:
1855 if (addr == NULL_RTX)
1856 {
1857 if (REG_P (src))
1858 return 4;
1859
1860 if (GET_CODE (src) == CONST_INT)
1861 {
1862 if (src == const0_rtx)
1863 return 4;
1864
1865 if ((INTVAL (src) & 0xffff) == 0)
1866 return 6;
1867
1868 if ((INTVAL (src) & 0xffff) == 0)
1869 return 6;
f5139cc5
KH
1870
1871 if ((INTVAL (src) & 0xffff)
1872 == ((INTVAL (src) >> 16) & 0xffff))
1873 return 6;
7948a9ea
KH
1874 }
1875 return 8;
1876 }
1877
1878 base_length = 8;
1879 break;
1880
1881 case SFmode:
1882 if (addr == NULL_RTX)
1883 {
1884 if (REG_P (src))
1885 return 4;
1886
2c4a71b3
KH
1887 if (CONST_DOUBLE_OK_FOR_LETTER_P (src, 'G'))
1888 return 4;
1889
81983b04 1890 return 8;
7948a9ea
KH
1891 }
1892
1893 base_length = 8;
1894 break;
1895
1896 default:
1897 abort ();
1898 }
1899
1900 /* Adjust the length based on the addressing mode used.
1901 Specifically, we subtract the difference between the actual
1902 length and the longest one, which is @(d:16,Rs). For SImode
1903 and SFmode, we double the adjustment because two mov.w are
1904 used to do the job. */
1905
1906 /* @Rs+ and @-Rd are 2 bytes shorter than the longest. */
1907 if (GET_CODE (addr) == PRE_DEC
1908 || GET_CODE (addr) == POST_INC)
1909 {
1910 if (mode == QImode || mode == HImode)
1911 return base_length - 2;
1912 else
1913 /* In SImode and SFmode, we use two mov.w instructions, so
2a43945f 1914 double the adjustment. */
7948a9ea
KH
1915 return base_length - 4;
1916 }
1917
1918 /* @Rs and @Rd are 2 bytes shorter than the longest. Note that
1919 in SImode and SFmode, the second mov.w involves an address
1920 with displacement, namely @(2,Rs) or @(2,Rd), so we subtract
1921 only 2 bytes. */
1922 if (GET_CODE (addr) == REG)
1923 return base_length - 2;
1924
1925 return base_length;
1926 }
1927 else
1928 {
1929 unsigned int base_length;
1930
1931 switch (mode)
1932 {
1933 case QImode:
1934 if (addr == NULL_RTX)
1935 return 2;
1936
1937 /* The eightbit addressing is available only in QImode, so
1938 go ahead and take care of it. */
1939 if (h8300_eightbit_constant_address_p (addr))
1940 return 2;
1941
1942 base_length = 8;
1943 break;
1944
1945 case HImode:
1946 if (addr == NULL_RTX)
1947 {
1948 if (REG_P (src))
1949 return 2;
1950
1951 if (src == const0_rtx)
1952 return 2;
1953
1954 return 4;
1955 }
1956
1957 base_length = 8;
1958 break;
1959
1960 case SImode:
1961 if (addr == NULL_RTX)
1962 {
1963 if (REG_P (src))
1964 {
1965 if (REGNO (src) == MAC_REG || REGNO (dest) == MAC_REG)
1966 return 4;
1967 else
1968 return 2;
1969 }
1970
1971 if (GET_CODE (src) == CONST_INT)
1972 {
1973 int val = INTVAL (src);
1974
1975 if (val == 0)
1976 return 2;
1977
1978 if (val == (val & 0x00ff) || val == (val & 0xff00))
1979 return 4;
1980
1981 switch (val & 0xffffffff)
1982 {
1983 case 0xffffffff:
1984 case 0xfffffffe:
1985 case 0xfffffffc:
1986 case 0x0000ffff:
1987 case 0x0000fffe:
1988 case 0xffff0000:
1989 case 0xfffe0000:
1990 case 0x00010000:
1991 case 0x00020000:
1992 return 4;
1993 }
1994 }
1995 return 6;
1996 }
1997
1998 base_length = 10;
1999 break;
2000
2001 case SFmode:
2002 if (addr == NULL_RTX)
2003 {
2004 if (REG_P (src))
2005 return 2;
2006
fad37371 2007 if (CONST_DOUBLE_OK_FOR_LETTER_P (src, 'G'))
7948a9ea 2008 return 2;
2c4a71b3 2009
7948a9ea
KH
2010 return 6;
2011 }
2012
2013 base_length = 10;
2014 break;
2015
2016 default:
2017 abort ();
2018 }
2019
2020 /* Adjust the length based on the addressing mode used.
2021 Specifically, we subtract the difference between the actual
2022 length and the longest one, which is @(d:24,ERs). */
2023
2024 /* @ERs+ and @-ERd are 6 bytes shorter than the longest. */
2025 if (GET_CODE (addr) == PRE_DEC
2026 || GET_CODE (addr) == POST_INC)
2027 return base_length - 6;
2028
2029 /* @ERs and @ERd are 6 bytes shorter than the longest. */
2030 if (GET_CODE (addr) == REG)
2031 return base_length - 6;
2032
2033 /* @(d:16,ERs) and @(d:16,ERd) are 4 bytes shorter than the
2034 longest. */
2035 if (GET_CODE (addr) == PLUS
2036 && GET_CODE (XEXP (addr, 0)) == REG
2037 && GET_CODE (XEXP (addr, 1)) == CONST_INT
2038 && INTVAL (XEXP (addr, 1)) > -32768
2039 && INTVAL (XEXP (addr, 1)) < 32767)
2040 return base_length - 4;
2041
2042 /* @aa:16 is 4 bytes shorter than the longest. */
2043 if (h8300_tiny_constant_address_p (addr))
2044 return base_length - 4;
2045
2046 /* @aa:24 is 2 bytes shorter than the longest. */
2047 if (CONSTANT_P (addr))
2048 return base_length - 2;
2049
2050 return base_length;
2051 }
2052}
2053\f
366a7b27 2054const char *
cb713a8d 2055output_plussi (rtx *operands)
7d6ac401
KH
2056{
2057 enum machine_mode mode = GET_MODE (operands[0]);
2058
2059 if (mode != SImode)
2060 abort ();
2061
2062 if (TARGET_H8300)
2063 {
cfedf91b
KH
2064 if (GET_CODE (operands[2]) == REG)
2065 return "add.w\t%f2,%f0\n\taddx\t%y2,%y0\n\taddx\t%z2,%z0";
2066
2067 if (GET_CODE (operands[2]) == CONST_INT)
2068 {
2069 HOST_WIDE_INT n = INTVAL (operands[2]);
2070
2071 if ((n & 0xffffff) == 0)
2072 return "add\t%z2,%z0";
2073 if ((n & 0xffff) == 0)
2074 return "add\t%y2,%y0\n\taddx\t%z2,%z0";
2075 if ((n & 0xff) == 0)
2076 return "add\t%x2,%x0\n\taddx\t%y2,%y0\n\taddx\t%z2,%z0";
2077 }
2078
2079 return "add\t%w2,%w0\n\taddx\t%x2,%x0\n\taddx\t%y2,%y0\n\taddx\t%z2,%z0";
7d6ac401
KH
2080 }
2081 else
2082 {
2083 if (GET_CODE (operands[2]) == REG)
2084 return "add.l\t%S2,%S0";
2085
2086 if (GET_CODE (operands[2]) == CONST_INT)
2087 {
2088 HOST_WIDE_INT intval = INTVAL (operands[2]);
2089
2090 /* See if we can finish with 2 bytes. */
2091
9ac7ebba 2092 switch ((unsigned int) intval & 0xffffffff)
7d6ac401
KH
2093 {
2094 case 0x00000001:
2095 case 0x00000002:
2096 case 0x00000004:
2097 return "adds\t%2,%S0";
2098
2099 case 0xffffffff:
2100 case 0xfffffffe:
2101 case 0xfffffffc:
2102 return "subs\t%G2,%S0";
2103
2104 case 0x00010000:
2105 case 0x00020000:
2106 operands[2] = GEN_INT (intval >> 16);
2107 return "inc.w\t%2,%e0";
2108
2109 case 0xffff0000:
2110 case 0xfffe0000:
2111 operands[2] = GEN_INT (intval >> 16);
2112 return "dec.w\t%G2,%e0";
2113 }
2114
2115 /* See if we can finish with 4 bytes. */
2116 if ((intval & 0xffff) == 0)
2117 {
2118 operands[2] = GEN_INT (intval >> 16);
2119 return "add.w\t%2,%e0";
2120 }
2121 }
2122
2123 return "add.l\t%S2,%S0";
2124 }
2125}
2126
2127unsigned int
cb713a8d 2128compute_plussi_length (rtx *operands)
7d6ac401
KH
2129{
2130 enum machine_mode mode = GET_MODE (operands[0]);
2131
2132 if (mode != SImode)
2133 abort ();
2134
2135 if (TARGET_H8300)
2136 {
cfedf91b
KH
2137 if (GET_CODE (operands[2]) == REG)
2138 return 6;
2139
2140 if (GET_CODE (operands[2]) == CONST_INT)
2141 {
2142 HOST_WIDE_INT n = INTVAL (operands[2]);
2143
2144 if ((n & 0xffffff) == 0)
2145 return 2;
2146 if ((n & 0xffff) == 0)
2147 return 4;
2148 if ((n & 0xff) == 0)
2149 return 6;
2150 }
2151
2152 return 8;
7d6ac401
KH
2153 }
2154 else
2155 {
2156 if (GET_CODE (operands[2]) == REG)
2157 return 2;
2158
2159 if (GET_CODE (operands[2]) == CONST_INT)
2160 {
2161 HOST_WIDE_INT intval = INTVAL (operands[2]);
2162
2163 /* See if we can finish with 2 bytes. */
2164
9ac7ebba 2165 switch ((unsigned int) intval & 0xffffffff)
7d6ac401
KH
2166 {
2167 case 0x00000001:
2168 case 0x00000002:
2169 case 0x00000004:
2170 return 2;
2171
2172 case 0xffffffff:
2173 case 0xfffffffe:
2174 case 0xfffffffc:
2175 return 2;
2176
2177 case 0x00010000:
2178 case 0x00020000:
2179 return 2;
2180
2181 case 0xffff0000:
2182 case 0xfffe0000:
2183 return 2;
2184 }
2185
2186 /* See if we can finish with 4 bytes. */
2187 if ((intval & 0xffff) == 0)
2188 return 4;
2189 }
2190
2191 return 6;
2192 }
2193}
2194
87a902e4 2195int
cb713a8d 2196compute_plussi_cc (rtx *operands)
7d6ac401
KH
2197{
2198 enum machine_mode mode = GET_MODE (operands[0]);
2199
2200 if (mode != SImode)
2201 abort ();
2202
2203 if (TARGET_H8300)
2204 {
cfedf91b 2205 return CC_CLOBBER;
7d6ac401
KH
2206 }
2207 else
2208 {
2209 if (GET_CODE (operands[2]) == REG)
2210 return CC_SET_ZN;
2211
2212 if (GET_CODE (operands[2]) == CONST_INT)
2213 {
2214 HOST_WIDE_INT intval = INTVAL (operands[2]);
2215
2216 /* See if we can finish with 2 bytes. */
2217
9ac7ebba 2218 switch ((unsigned int) intval & 0xffffffff)
7d6ac401
KH
2219 {
2220 case 0x00000001:
2221 case 0x00000002:
2222 case 0x00000004:
2223 return CC_NONE_0HIT;
2224
2225 case 0xffffffff:
2226 case 0xfffffffe:
2227 case 0xfffffffc:
2228 return CC_NONE_0HIT;
2229
2230 case 0x00010000:
2231 case 0x00020000:
2232 return CC_CLOBBER;
2233
2234 case 0xffff0000:
2235 case 0xfffe0000:
2236 return CC_CLOBBER;
2237 }
2238
2239 /* See if we can finish with 4 bytes. */
2240 if ((intval & 0xffff) == 0)
2241 return CC_CLOBBER;
2242 }
2243
2244 return CC_SET_ZN;
2245 }
2246}
2247\f
2248const char *
cb713a8d 2249output_logical_op (enum machine_mode mode, rtx *operands)
366a7b27 2250{
b42cff6b
KH
2251 /* Figure out the logical op that we need to perform. */
2252 enum rtx_code code = GET_CODE (operands[3]);
366a7b27 2253 /* Pretend that every byte is affected if both operands are registers. */
7798db98 2254 const unsigned HOST_WIDE_INT intval =
366a7b27
KH
2255 (unsigned HOST_WIDE_INT) ((GET_CODE (operands[2]) == CONST_INT)
2256 ? INTVAL (operands[2]) : 0x55555555);
2257 /* The determinant of the algorithm. If we perform an AND, 0
2258 affects a bit. Otherwise, 1 affects a bit. */
7798db98 2259 const unsigned HOST_WIDE_INT det = (code != AND) ? intval : ~intval;
f9ac2f95
KH
2260 /* Break up DET into pieces. */
2261 const unsigned HOST_WIDE_INT b0 = (det >> 0) & 0xff;
2262 const unsigned HOST_WIDE_INT b1 = (det >> 8) & 0xff;
c5e7ce43
KH
2263 const unsigned HOST_WIDE_INT b2 = (det >> 16) & 0xff;
2264 const unsigned HOST_WIDE_INT b3 = (det >> 24) & 0xff;
f9ac2f95
KH
2265 const unsigned HOST_WIDE_INT w0 = (det >> 0) & 0xffff;
2266 const unsigned HOST_WIDE_INT w1 = (det >> 16) & 0xffff;
2267 int lower_half_easy_p = 0;
2268 int upper_half_easy_p = 0;
366a7b27
KH
2269 /* The name of an insn. */
2270 const char *opname;
2271 char insn_buf[100];
2272
2273 switch (code)
2274 {
2275 case AND:
2276 opname = "and";
2277 break;
2278 case IOR:
2279 opname = "or";
2280 break;
2281 case XOR:
2282 opname = "xor";
2283 break;
2284 default:
2285 abort ();
2286 }
2287
2288 switch (mode)
2289 {
2290 case HImode:
2291 /* First, see if we can finish with one insn. */
2292 if ((TARGET_H8300H || TARGET_H8300S)
c5e7ce43
KH
2293 && b0 != 0
2294 && b1 != 0)
366a7b27
KH
2295 {
2296 sprintf (insn_buf, "%s.w\t%%T2,%%T0", opname);
2297 output_asm_insn (insn_buf, operands);
2298 }
2299 else
2300 {
2301 /* Take care of the lower byte. */
c5e7ce43 2302 if (b0 != 0)
366a7b27
KH
2303 {
2304 sprintf (insn_buf, "%s\t%%s2,%%s0", opname);
2305 output_asm_insn (insn_buf, operands);
2306 }
2307 /* Take care of the upper byte. */
c5e7ce43 2308 if (b1 != 0)
366a7b27
KH
2309 {
2310 sprintf (insn_buf, "%s\t%%t2,%%t0", opname);
2311 output_asm_insn (insn_buf, operands);
2312 }
2313 }
2314 break;
2315 case SImode:
f9ac2f95
KH
2316 if (TARGET_H8300H || TARGET_H8300S)
2317 {
2318 /* Determine if the lower half can be taken care of in no more
2319 than two bytes. */
2320 lower_half_easy_p = (b0 == 0
2321 || b1 == 0
2322 || (code != IOR && w0 == 0xffff));
2323
2324 /* Determine if the upper half can be taken care of in no more
2325 than two bytes. */
2326 upper_half_easy_p = ((code != IOR && w1 == 0xffff)
2327 || (code == AND && w1 == 0xff00));
2328 }
366a7b27 2329
f9ac2f95
KH
2330 /* Check if doing everything with one insn is no worse than
2331 using multiple insns. */
366a7b27 2332 if ((TARGET_H8300H || TARGET_H8300S)
f9ac2f95 2333 && w0 != 0 && w1 != 0
472f2723
KH
2334 && !(lower_half_easy_p && upper_half_easy_p)
2335 && !(code == IOR && w1 == 0xffff
2336 && (w0 & 0x8000) != 0 && lower_half_easy_p))
366a7b27
KH
2337 {
2338 sprintf (insn_buf, "%s.l\t%%S2,%%S0", opname);
2339 output_asm_insn (insn_buf, operands);
2340 }
2341 else
2342 {
2343 /* Take care of the lower and upper words individually. For
2344 each word, we try different methods in the order of
2345
2346 1) the special insn (in case of AND or XOR),
2347 2) the word-wise insn, and
2348 3) The byte-wise insn. */
c5e7ce43 2349 if (w0 == 0xffff
6dfa4005 2350 && (TARGET_H8300 ? (code == AND) : (code != IOR)))
366a7b27 2351 output_asm_insn ((code == AND)
187462ac 2352 ? "sub.w\t%f0,%f0" : "not.w\t%f0",
366a7b27
KH
2353 operands);
2354 else if ((TARGET_H8300H || TARGET_H8300S)
c5e7ce43
KH
2355 && (b0 != 0)
2356 && (b1 != 0))
366a7b27
KH
2357 {
2358 sprintf (insn_buf, "%s.w\t%%f2,%%f0", opname);
2359 output_asm_insn (insn_buf, operands);
2360 }
2361 else
2362 {
c5e7ce43 2363 if (b0 != 0)
366a7b27
KH
2364 {
2365 sprintf (insn_buf, "%s\t%%w2,%%w0", opname);
2366 output_asm_insn (insn_buf, operands);
2367 }
c5e7ce43 2368 if (b1 != 0)
366a7b27
KH
2369 {
2370 sprintf (insn_buf, "%s\t%%x2,%%x0", opname);
2371 output_asm_insn (insn_buf, operands);
2372 }
2373 }
2374
c5e7ce43 2375 if ((w1 == 0xffff)
6dfa4005 2376 && (TARGET_H8300 ? (code == AND) : (code != IOR)))
366a7b27 2377 output_asm_insn ((code == AND)
187462ac 2378 ? "sub.w\t%e0,%e0" : "not.w\t%e0",
366a7b27 2379 operands);
472f2723
KH
2380 else if ((TARGET_H8300H || TARGET_H8300S)
2381 && code == IOR
2382 && w1 == 0xffff
2383 && (w0 & 0x8000) != 0)
2384 {
2385 output_asm_insn ("exts.l\t%S0", operands);
2386 }
a6e8d113
KH
2387 else if ((TARGET_H8300H || TARGET_H8300S)
2388 && code == AND
c5e7ce43 2389 && w1 == 0xff00)
a6e8d113 2390 {
dc5f17ec 2391 output_asm_insn ("extu.w\t%e0", operands);
a6e8d113 2392 }
366a7b27
KH
2393 else if (TARGET_H8300H || TARGET_H8300S)
2394 {
c5e7ce43 2395 if (w1 != 0)
366a7b27
KH
2396 {
2397 sprintf (insn_buf, "%s.w\t%%e2,%%e0", opname);
2398 output_asm_insn (insn_buf, operands);
2399 }
2400 }
2401 else
2402 {
c5e7ce43 2403 if (b2 != 0)
366a7b27
KH
2404 {
2405 sprintf (insn_buf, "%s\t%%y2,%%y0", opname);
2406 output_asm_insn (insn_buf, operands);
2407 }
c5e7ce43 2408 if (b3 != 0)
366a7b27
KH
2409 {
2410 sprintf (insn_buf, "%s\t%%z2,%%z0", opname);
2411 output_asm_insn (insn_buf, operands);
2412 }
2413 }
2414 }
2415 break;
2416 default:
2417 abort ();
2418 }
2419 return "";
2420}
40367e2d
KH
2421
2422unsigned int
cb713a8d 2423compute_logical_op_length (enum machine_mode mode, rtx *operands)
40367e2d 2424{
b42cff6b
KH
2425 /* Figure out the logical op that we need to perform. */
2426 enum rtx_code code = GET_CODE (operands[3]);
40367e2d 2427 /* Pretend that every byte is affected if both operands are registers. */
7798db98 2428 const unsigned HOST_WIDE_INT intval =
40367e2d
KH
2429 (unsigned HOST_WIDE_INT) ((GET_CODE (operands[2]) == CONST_INT)
2430 ? INTVAL (operands[2]) : 0x55555555);
2431 /* The determinant of the algorithm. If we perform an AND, 0
2432 affects a bit. Otherwise, 1 affects a bit. */
7798db98 2433 const unsigned HOST_WIDE_INT det = (code != AND) ? intval : ~intval;
f9ac2f95
KH
2434 /* Break up DET into pieces. */
2435 const unsigned HOST_WIDE_INT b0 = (det >> 0) & 0xff;
2436 const unsigned HOST_WIDE_INT b1 = (det >> 8) & 0xff;
c5e7ce43
KH
2437 const unsigned HOST_WIDE_INT b2 = (det >> 16) & 0xff;
2438 const unsigned HOST_WIDE_INT b3 = (det >> 24) & 0xff;
f9ac2f95
KH
2439 const unsigned HOST_WIDE_INT w0 = (det >> 0) & 0xffff;
2440 const unsigned HOST_WIDE_INT w1 = (det >> 16) & 0xffff;
2441 int lower_half_easy_p = 0;
2442 int upper_half_easy_p = 0;
40367e2d
KH
2443 /* Insn length. */
2444 unsigned int length = 0;
2445
2446 switch (mode)
2447 {
2448 case HImode:
2449 /* First, see if we can finish with one insn. */
2450 if ((TARGET_H8300H || TARGET_H8300S)
c5e7ce43
KH
2451 && b0 != 0
2452 && b1 != 0)
40367e2d
KH
2453 {
2454 if (REG_P (operands[2]))
2455 length += 2;
2456 else
2457 length += 4;
2458 }
2459 else
2460 {
2461 /* Take care of the lower byte. */
c5e7ce43 2462 if (b0 != 0)
40367e2d
KH
2463 length += 2;
2464
2465 /* Take care of the upper byte. */
c5e7ce43 2466 if (b1 != 0)
40367e2d
KH
2467 length += 2;
2468 }
2469 break;
2470 case SImode:
f9ac2f95
KH
2471 if (TARGET_H8300H || TARGET_H8300S)
2472 {
2473 /* Determine if the lower half can be taken care of in no more
2474 than two bytes. */
2475 lower_half_easy_p = (b0 == 0
2476 || b1 == 0
2477 || (code != IOR && w0 == 0xffff));
2478
2479 /* Determine if the upper half can be taken care of in no more
2480 than two bytes. */
2481 upper_half_easy_p = ((code != IOR && w1 == 0xffff)
2482 || (code == AND && w1 == 0xff00));
2483 }
40367e2d 2484
f9ac2f95
KH
2485 /* Check if doing everything with one insn is no worse than
2486 using multiple insns. */
40367e2d 2487 if ((TARGET_H8300H || TARGET_H8300S)
f9ac2f95 2488 && w0 != 0 && w1 != 0
472f2723
KH
2489 && !(lower_half_easy_p && upper_half_easy_p)
2490 && !(code == IOR && w1 == 0xffff
2491 && (w0 & 0x8000) != 0 && lower_half_easy_p))
40367e2d
KH
2492 {
2493 if (REG_P (operands[2]))
2494 length += 4;
2495 else
2496 length += 6;
2497 }
2498 else
2499 {
2500 /* Take care of the lower and upper words individually. For
2501 each word, we try different methods in the order of
2502
2503 1) the special insn (in case of AND or XOR),
2504 2) the word-wise insn, and
2505 3) The byte-wise insn. */
c5e7ce43 2506 if (w0 == 0xffff
40367e2d
KH
2507 && (TARGET_H8300 ? (code == AND) : (code != IOR)))
2508 {
2509 length += 2;
2510 }
2511 else if ((TARGET_H8300H || TARGET_H8300S)
c5e7ce43
KH
2512 && (b0 != 0)
2513 && (b1 != 0))
40367e2d
KH
2514 {
2515 length += 4;
2516 }
2517 else
2518 {
c5e7ce43 2519 if (b0 != 0)
40367e2d
KH
2520 length += 2;
2521
c5e7ce43 2522 if (b1 != 0)
40367e2d
KH
2523 length += 2;
2524 }
2525
c5e7ce43 2526 if (w1 == 0xffff
40367e2d
KH
2527 && (TARGET_H8300 ? (code == AND) : (code != IOR)))
2528 {
2529 length += 2;
2530 }
472f2723
KH
2531 else if ((TARGET_H8300H || TARGET_H8300S)
2532 && code == IOR
2533 && w1 == 0xffff
2534 && (w0 & 0x8000) != 0)
2535 {
2536 length += 2;
2537 }
a6e8d113
KH
2538 else if ((TARGET_H8300H || TARGET_H8300S)
2539 && code == AND
c5e7ce43 2540 && w1 == 0xff00)
a6e8d113
KH
2541 {
2542 length += 2;
2543 }
40367e2d
KH
2544 else if (TARGET_H8300H || TARGET_H8300S)
2545 {
c5e7ce43 2546 if (w1 != 0)
40367e2d
KH
2547 length += 4;
2548 }
2549 else
2550 {
c5e7ce43 2551 if (b2 != 0)
40367e2d
KH
2552 length += 2;
2553
c5e7ce43 2554 if (b3 != 0)
40367e2d
KH
2555 length += 2;
2556 }
2557 }
2558 break;
2559 default:
2560 abort ();
2561 }
2562 return length;
2563}
b42cff6b
KH
2564
2565int
cb713a8d 2566compute_logical_op_cc (enum machine_mode mode, rtx *operands)
b42cff6b
KH
2567{
2568 /* Figure out the logical op that we need to perform. */
2569 enum rtx_code code = GET_CODE (operands[3]);
2570 /* Pretend that every byte is affected if both operands are registers. */
7798db98 2571 const unsigned HOST_WIDE_INT intval =
b42cff6b
KH
2572 (unsigned HOST_WIDE_INT) ((GET_CODE (operands[2]) == CONST_INT)
2573 ? INTVAL (operands[2]) : 0x55555555);
2574 /* The determinant of the algorithm. If we perform an AND, 0
2575 affects a bit. Otherwise, 1 affects a bit. */
7798db98 2576 const unsigned HOST_WIDE_INT det = (code != AND) ? intval : ~intval;
f9ac2f95
KH
2577 /* Break up DET into pieces. */
2578 const unsigned HOST_WIDE_INT b0 = (det >> 0) & 0xff;
2579 const unsigned HOST_WIDE_INT b1 = (det >> 8) & 0xff;
2580 const unsigned HOST_WIDE_INT w0 = (det >> 0) & 0xffff;
2581 const unsigned HOST_WIDE_INT w1 = (det >> 16) & 0xffff;
2582 int lower_half_easy_p = 0;
2583 int upper_half_easy_p = 0;
b42cff6b
KH
2584 /* Condition code. */
2585 enum attr_cc cc = CC_CLOBBER;
2586
2587 switch (mode)
2588 {
2589 case HImode:
2590 /* First, see if we can finish with one insn. */
2591 if ((TARGET_H8300H || TARGET_H8300S)
c5e7ce43
KH
2592 && b0 != 0
2593 && b1 != 0)
b42cff6b
KH
2594 {
2595 cc = CC_SET_ZNV;
2596 }
2597 break;
2598 case SImode:
f9ac2f95
KH
2599 if (TARGET_H8300H || TARGET_H8300S)
2600 {
2601 /* Determine if the lower half can be taken care of in no more
2602 than two bytes. */
2603 lower_half_easy_p = (b0 == 0
2604 || b1 == 0
2605 || (code != IOR && w0 == 0xffff));
2606
2607 /* Determine if the upper half can be taken care of in no more
2608 than two bytes. */
2609 upper_half_easy_p = ((code != IOR && w1 == 0xffff)
2610 || (code == AND && w1 == 0xff00));
2611 }
b42cff6b 2612
f9ac2f95
KH
2613 /* Check if doing everything with one insn is no worse than
2614 using multiple insns. */
b42cff6b 2615 if ((TARGET_H8300H || TARGET_H8300S)
f9ac2f95 2616 && w0 != 0 && w1 != 0
472f2723
KH
2617 && !(lower_half_easy_p && upper_half_easy_p)
2618 && !(code == IOR && w1 == 0xffff
2619 && (w0 & 0x8000) != 0 && lower_half_easy_p))
b42cff6b
KH
2620 {
2621 cc = CC_SET_ZNV;
2622 }
472f2723
KH
2623 else
2624 {
2625 if ((TARGET_H8300H || TARGET_H8300S)
2626 && code == IOR
2627 && w1 == 0xffff
2628 && (w0 & 0x8000) != 0)
2629 {
2630 cc = CC_SET_ZNV;
2631 }
2632 }
b42cff6b
KH
2633 break;
2634 default:
2635 abort ();
2636 }
2637 return cc;
2638}
366a7b27 2639\f
48837e29
DE
2640/* Shifts.
2641
005e3e05
KH
2642 We devote a fair bit of code to getting efficient shifts since we
2643 can only shift one bit at a time on the H8/300 and H8/300H and only
3db11b5c 2644 one or two bits at a time on the H8S.
005e3e05
KH
2645
2646 All shift code falls into one of the following ways of
2647 implementation:
2648
2649 o SHIFT_INLINE: Emit straight line code for the shift; this is used
2650 when a straight line shift is about the same size or smaller than
2651 a loop.
2652
2653 o SHIFT_ROT_AND: Rotate the value the opposite direction, then mask
2654 off the bits we don't need. This is used when only a few of the
2655 bits in the original value will survive in the shifted value.
2656
2657 o SHIFT_SPECIAL: Often it's possible to move a byte or a word to
2658 simulate a shift by 8, 16, or 24 bits. Once moved, a few inline
2659 shifts can be added if the shift count is slightly more than 8 or
2660 16. This case also includes other oddballs that are not worth
f411c849 2661 explaining here.
005e3e05 2662
3db11b5c 2663 o SHIFT_LOOP: Emit a loop using one (or two on H8S) bit shifts.
005e3e05 2664
5ec0b66e
KH
2665 For each shift count, we try to use code that has no trade-off
2666 between code size and speed whenever possible.
2667
2668 If the trade-off is unavoidable, we try to be reasonable.
2669 Specifically, the fastest version is one instruction longer than
2670 the shortest version, we take the fastest version. We also provide
2671 the use a way to switch back to the shortest version with -Os.
2672
2673 For the details of the shift algorithms for various shift counts,
2674 refer to shift_alg_[qhs]i. */
07aae5c2
SC
2675
2676int
cb713a8d 2677nshift_operator (rtx x, enum machine_mode mode ATTRIBUTE_UNUSED)
48837e29
DE
2678{
2679 switch (GET_CODE (x))
2680 {
2681 case ASHIFTRT:
2682 case LSHIFTRT:
2683 case ASHIFT:
2684 return 1;
2685
2686 default:
2687 return 0;
2688 }
2689}
2690
317d21e9 2691/* Emit code to do shifts. */
48837e29 2692
317d21e9 2693void
cb713a8d 2694expand_a_shift (enum machine_mode mode, int code, rtx operands[])
07aae5c2 2695{
07aae5c2
SC
2696 emit_move_insn (operands[0], operands[1]);
2697
07e4d94e
KH
2698 /* Need a loop to get all the bits we want - we generate the
2699 code at emit time, but need to allocate a scratch reg now. */
48837e29 2700
c5c76735
JL
2701 emit_insn (gen_rtx_PARALLEL
2702 (VOIDmode,
48837e29 2703 gen_rtvec (2,
c5c76735
JL
2704 gen_rtx_SET (VOIDmode, operands[0],
2705 gen_rtx (code, mode, operands[0],
2706 operands[2])),
2707 gen_rtx_CLOBBER (VOIDmode,
2708 gen_rtx_SCRATCH (QImode)))));
48837e29
DE
2709}
2710
48837e29
DE
2711/* Symbols of the various modes which can be used as indices. */
2712
2713enum shift_mode
1a63219b
KH
2714{
2715 QIshift, HIshift, SIshift
2716};
48837e29 2717
269c14e1
DE
2718/* For single bit shift insns, record assembler and what bits of the
2719 condition code are valid afterwards (represented as various CC_FOO
2720 bits, 0 means CC isn't left in a usable state). */
48837e29
DE
2721
2722struct shift_insn
2723{
8b60264b
KG
2724 const char *const assembler;
2725 const int cc_valid;
48837e29
DE
2726};
2727
2728/* Assembler instruction shift table.
2729
2730 These tables are used to look up the basic shifts.
07e4d94e 2731 They are indexed by cpu, shift_type, and mode. */
07aae5c2 2732
48837e29
DE
2733static const struct shift_insn shift_one[2][3][3] =
2734{
2735/* H8/300 */
2736 {
2737/* SHIFT_ASHIFT */
2738 {
45ca2106
KH
2739 { "shll\t%X0", CC_SET_ZNV },
2740 { "add.w\t%T0,%T0", CC_SET_ZN },
2741 { "add.w\t%f0,%f0\n\taddx\t%y0,%y0\n\taddx\t%z0,%z0", CC_CLOBBER }
48837e29
DE
2742 },
2743/* SHIFT_LSHIFTRT */
2744 {
45ca2106
KH
2745 { "shlr\t%X0", CC_SET_ZNV },
2746 { "shlr\t%t0\n\trotxr\t%s0", CC_CLOBBER },
2747 { "shlr\t%z0\n\trotxr\t%y0\n\trotxr\t%x0\n\trotxr\t%w0", CC_CLOBBER }
48837e29
DE
2748 },
2749/* SHIFT_ASHIFTRT */
2750 {
45ca2106
KH
2751 { "shar\t%X0", CC_SET_ZNV },
2752 { "shar\t%t0\n\trotxr\t%s0", CC_CLOBBER },
2753 { "shar\t%z0\n\trotxr\t%y0\n\trotxr\t%x0\n\trotxr\t%w0", CC_CLOBBER }
48837e29
DE
2754 }
2755 },
2756/* H8/300H */
2757 {
2758/* SHIFT_ASHIFT */
2759 {
45ca2106
KH
2760 { "shll.b\t%X0", CC_SET_ZNV },
2761 { "shll.w\t%T0", CC_SET_ZNV },
2762 { "shll.l\t%S0", CC_SET_ZNV }
48837e29
DE
2763 },
2764/* SHIFT_LSHIFTRT */
2765 {
45ca2106
KH
2766 { "shlr.b\t%X0", CC_SET_ZNV },
2767 { "shlr.w\t%T0", CC_SET_ZNV },
2768 { "shlr.l\t%S0", CC_SET_ZNV }
48837e29
DE
2769 },
2770/* SHIFT_ASHIFTRT */
2771 {
45ca2106
KH
2772 { "shar.b\t%X0", CC_SET_ZNV },
2773 { "shar.w\t%T0", CC_SET_ZNV },
2774 { "shar.l\t%S0", CC_SET_ZNV }
48837e29
DE
2775 }
2776 }
2777};
07aae5c2 2778
51c0c1d7
JL
2779static const struct shift_insn shift_two[3][3] =
2780{
2781/* SHIFT_ASHIFT */
2782 {
45ca2106
KH
2783 { "shll.b\t#2,%X0", CC_SET_ZNV },
2784 { "shll.w\t#2,%T0", CC_SET_ZNV },
2785 { "shll.l\t#2,%S0", CC_SET_ZNV }
51c0c1d7
JL
2786 },
2787/* SHIFT_LSHIFTRT */
2788 {
45ca2106
KH
2789 { "shlr.b\t#2,%X0", CC_SET_ZNV },
2790 { "shlr.w\t#2,%T0", CC_SET_ZNV },
2791 { "shlr.l\t#2,%S0", CC_SET_ZNV }
51c0c1d7
JL
2792 },
2793/* SHIFT_ASHIFTRT */
2794 {
45ca2106
KH
2795 { "shar.b\t#2,%X0", CC_SET_ZNV },
2796 { "shar.w\t#2,%T0", CC_SET_ZNV },
2797 { "shar.l\t#2,%S0", CC_SET_ZNV }
51c0c1d7
JL
2798 }
2799};
2800
48837e29
DE
2801/* Rotates are organized by which shift they'll be used in implementing.
2802 There's no need to record whether the cc is valid afterwards because
2803 it is the AND insn that will decide this. */
07aae5c2 2804
48837e29
DE
2805static const char *const rotate_one[2][3][3] =
2806{
2807/* H8/300 */
2808 {
2809/* SHIFT_ASHIFT */
2810 {
51c0c1d7
JL
2811 "rotr\t%X0",
2812 "shlr\t%t0\n\trotxr\t%s0\n\tbst\t#7,%t0",
48837e29
DE
2813 0
2814 },
2815/* SHIFT_LSHIFTRT */
2816 {
51c0c1d7
JL
2817 "rotl\t%X0",
2818 "shll\t%s0\n\trotxl\t%t0\n\tbst\t#0,%s0",
48837e29
DE
2819 0
2820 },
2821/* SHIFT_ASHIFTRT */
2822 {
51c0c1d7
JL
2823 "rotl\t%X0",
2824 "shll\t%s0\n\trotxl\t%t0\n\tbst\t#0,%s0",
48837e29 2825 0
07aae5c2 2826 }
48837e29
DE
2827 },
2828/* H8/300H */
2829 {
2830/* SHIFT_ASHIFT */
2831 {
51c0c1d7
JL
2832 "rotr.b\t%X0",
2833 "rotr.w\t%T0",
2834 "rotr.l\t%S0"
48837e29
DE
2835 },
2836/* SHIFT_LSHIFTRT */
07aae5c2 2837 {
51c0c1d7
JL
2838 "rotl.b\t%X0",
2839 "rotl.w\t%T0",
2840 "rotl.l\t%S0"
48837e29
DE
2841 },
2842/* SHIFT_ASHIFTRT */
2843 {
51c0c1d7
JL
2844 "rotl.b\t%X0",
2845 "rotl.w\t%T0",
2846 "rotl.l\t%S0"
48837e29
DE
2847 }
2848 }
2849};
2850
51c0c1d7
JL
2851static const char *const rotate_two[3][3] =
2852{
2853/* SHIFT_ASHIFT */
2854 {
2855 "rotr.b\t#2,%X0",
2856 "rotr.w\t#2,%T0",
2857 "rotr.l\t#2,%S0"
2858 },
2859/* SHIFT_LSHIFTRT */
2860 {
2861 "rotl.b\t#2,%X0",
2862 "rotl.w\t#2,%T0",
2863 "rotl.l\t#2,%S0"
2864 },
2865/* SHIFT_ASHIFTRT */
2866 {
2867 "rotl.b\t#2,%X0",
2868 "rotl.w\t#2,%T0",
2869 "rotl.l\t#2,%S0"
2870 }
2871};
2872
35fb3d1f
KH
2873struct shift_info {
2874 /* Shift algorithm. */
2875 enum shift_alg alg;
2876
2877 /* The number of bits to be shifted by shift1 and shift2. Valid
2878 when ALG is SHIFT_SPECIAL. */
2879 unsigned int remainder;
2880
2881 /* Special insn for a shift. Valid when ALG is SHIFT_SPECIAL. */
2882 const char *special;
2883
2884 /* Insn for a one-bit shift. Valid when ALG is either SHIFT_INLINE
9cd10576 2885 or SHIFT_SPECIAL, and REMAINDER is nonzero. */
35fb3d1f
KH
2886 const char *shift1;
2887
2888 /* Insn for a two-bit shift. Valid when ALG is either SHIFT_INLINE
9cd10576 2889 or SHIFT_SPECIAL, and REMAINDER is nonzero. */
35fb3d1f
KH
2890 const char *shift2;
2891
45ca2106
KH
2892 /* CC status for SHIFT_INLINE. */
2893 int cc_inline;
2894
2895 /* CC status for SHIFT_SPECIAL. */
2896 int cc_special;
35fb3d1f
KH
2897};
2898
cb713a8d
KH
2899static void get_shift_alg (enum shift_type,
2900 enum shift_mode, unsigned int,
2901 struct shift_info *);
441d04c6 2902
c009a745
KH
2903/* Given SHIFT_TYPE, SHIFT_MODE, and shift count COUNT, determine the
2904 best algorithm for doing the shift. The assembler code is stored
5ec0b66e
KH
2905 in the pointers in INFO. We achieve the maximum efficiency in most
2906 cases when !TARGET_H8300. In case of TARGET_H8300, shifts in
2907 SImode in particular have a lot of room to optimize.
2908
2909 We first determine the strategy of the shift algorithm by a table
2910 lookup. If that tells us to use a hand crafted assembly code, we
2911 go into the big switch statement to find what that is. Otherwise,
2912 we resort to a generic way, such as inlining. In either case, the
2913 result is returned through INFO. */
48837e29 2914
cb33eb17 2915static void
cb713a8d
KH
2916get_shift_alg (enum shift_type shift_type, enum shift_mode shift_mode,
2917 unsigned int count, struct shift_info *info)
48837e29 2918{
b9b575e6 2919 enum h8_cpu cpu;
769828ab
KH
2920
2921 /* Find the target CPU. */
2922 if (TARGET_H8300)
b9b575e6 2923 cpu = H8_300;
769828ab 2924 else if (TARGET_H8300H)
b9b575e6 2925 cpu = H8_300H;
769828ab 2926 else
b9b575e6 2927 cpu = H8_S;
769828ab 2928
96eaf358 2929 /* Find the shift algorithm. */
b9b575e6 2930 info->alg = SHIFT_LOOP;
48837e29
DE
2931 switch (shift_mode)
2932 {
2933 case QIshift:
b9b575e6 2934 if (count < GET_MODE_BITSIZE (QImode))
96eaf358
KH
2935 info->alg = shift_alg_qi[cpu][shift_type][count];
2936 break;
769828ab 2937
96eaf358 2938 case HIshift:
b9b575e6 2939 if (count < GET_MODE_BITSIZE (HImode))
96eaf358
KH
2940 info->alg = shift_alg_hi[cpu][shift_type][count];
2941 break;
2942
2943 case SIshift:
b9b575e6 2944 if (count < GET_MODE_BITSIZE (SImode))
96eaf358
KH
2945 info->alg = shift_alg_si[cpu][shift_type][count];
2946 break;
2947
2948 default:
2949 abort ();
2950 }
2951
2952 /* Fill in INFO. Return unless we have SHIFT_SPECIAL. */
2953 switch (info->alg)
2954 {
2955 case SHIFT_INLINE:
2956 info->remainder = count;
2957 /* Fall through. */
2958
2959 case SHIFT_LOOP:
2960 /* It is up to the caller to know that looping clobbers cc. */
2961 info->shift1 = shift_one[cpu_type][shift_type][shift_mode].assembler;
2962 info->shift2 = shift_two[shift_type][shift_mode].assembler;
45ca2106 2963 info->cc_inline = shift_one[cpu_type][shift_type][shift_mode].cc_valid;
96eaf358
KH
2964 goto end;
2965
2966 case SHIFT_ROT_AND:
2967 info->shift1 = rotate_one[cpu_type][shift_type][shift_mode];
2968 info->shift2 = rotate_two[shift_type][shift_mode];
45ca2106 2969 info->cc_inline = CC_CLOBBER;
96eaf358
KH
2970 goto end;
2971
2972 case SHIFT_SPECIAL:
2973 /* REMAINDER is 0 for most cases, so initialize it to 0. */
2974 info->remainder = 0;
2975 info->shift1 = shift_one[cpu_type][shift_type][shift_mode].assembler;
2976 info->shift2 = shift_two[shift_type][shift_mode].assembler;
45ca2106
KH
2977 info->cc_inline = shift_one[cpu_type][shift_type][shift_mode].cc_valid;
2978 info->cc_special = CC_CLOBBER;
96eaf358
KH
2979 break;
2980 }
51c0c1d7 2981
96eaf358
KH
2982 /* Here we only deal with SHIFT_SPECIAL. */
2983 switch (shift_mode)
2984 {
2985 case QIshift:
769828ab
KH
2986 /* For ASHIFTRT by 7 bits, the sign bit is simply replicated
2987 through the entire value. */
2988 if (shift_type == SHIFT_ASHIFTRT && count == 7)
2989 {
2990 info->special = "shll\t%X0\n\tsubx\t%X0,%X0";
692b7eb3 2991 goto end;
769828ab
KH
2992 }
2993 abort ();
2994
2995 case HIshift:
769828ab 2996 if (count == 7)
51c0c1d7 2997 {
a77b1dbc 2998 switch (shift_type)
51c0c1d7 2999 {
a77b1dbc
KH
3000 case SHIFT_ASHIFT:
3001 if (TARGET_H8300)
3002 info->special = "shar.b\t%t0\n\tmov.b\t%s0,%t0\n\trotxr.b\t%t0\n\trotr.b\t%s0\n\tand.b\t#0x80,%s0";
3003 else
3004 info->special = "shar.b\t%t0\n\tmov.b\t%s0,%t0\n\trotxr.w\t%T0\n\tand.b\t#0x80,%s0";
692b7eb3 3005 goto end;
a77b1dbc
KH
3006 case SHIFT_LSHIFTRT:
3007 if (TARGET_H8300)
3008 info->special = "shal.b\t%s0\n\tmov.b\t%t0,%s0\n\trotxl.b\t%s0\n\trotl.b\t%t0\n\tand.b\t#0x01,%t0";
3009 else
3010 info->special = "shal.b\t%s0\n\tmov.b\t%t0,%s0\n\trotxl.w\t%T0\n\tand.b\t#0x01,%t0";
692b7eb3 3011 goto end;
a77b1dbc 3012 case SHIFT_ASHIFTRT:
35fb3d1f 3013 info->special = "shal.b\t%s0\n\tmov.b\t%t0,%s0\n\trotxl.b\t%s0\n\tsubx\t%t0,%t0";
692b7eb3 3014 goto end;
48837e29 3015 }
07aae5c2 3016 }
b30686ec 3017 else if ((8 <= count && count <= 13)
a38b3eea 3018 || (TARGET_H8300S && count == 14))
07aae5c2 3019 {
a7812c0b
KH
3020 info->remainder = count - 8;
3021
51c0c1d7 3022 switch (shift_type)
48837e29 3023 {
51c0c1d7 3024 case SHIFT_ASHIFT:
35fb3d1f 3025 info->special = "mov.b\t%s0,%t0\n\tsub.b\t%s0,%s0";
692b7eb3 3026 goto end;
51c0c1d7 3027 case SHIFT_LSHIFTRT:
a7612343
KH
3028 if (TARGET_H8300)
3029 {
3030 info->special = "mov.b\t%t0,%s0\n\tsub.b\t%t0,%t0";
3031 info->shift1 = "shlr.b\t%s0";
45ca2106 3032 info->cc_inline = CC_SET_ZNV;
a7612343
KH
3033 }
3034 else
3035 {
3036 info->special = "mov.b\t%t0,%s0\n\textu.w\t%T0";
45ca2106 3037 info->cc_special = CC_SET_ZNV;
a7612343 3038 }
692b7eb3 3039 goto end;
51c0c1d7
JL
3040 case SHIFT_ASHIFTRT:
3041 if (TARGET_H8300)
a7612343
KH
3042 {
3043 info->special = "mov.b\t%t0,%s0\n\tbld\t#7,%s0\n\tsubx\t%t0,%t0";
3044 info->shift1 = "shar.b\t%s0";
a7612343 3045 }
51c0c1d7 3046 else
a7612343
KH
3047 {
3048 info->special = "mov.b\t%t0,%s0\n\texts.w\t%T0";
45ca2106 3049 info->cc_special = CC_SET_ZNV;
a7612343 3050 }
692b7eb3 3051 goto end;
51c0c1d7
JL
3052 }
3053 }
5e98fba2
DD
3054 else if (count == 14)
3055 {
3056 switch (shift_type)
3057 {
3058 case SHIFT_ASHIFT:
3059 if (TARGET_H8300)
3060 info->special = "mov.b\t%s0,%t0\n\trotr.b\t%t0\n\trotr.b\t%t0\n\tand.b\t#0xC0,%t0\n\tsub.b\t%s0,%s0";
3061 goto end;
3062 case SHIFT_LSHIFTRT:
3063 if (TARGET_H8300)
3064 info->special = "mov.b\t%t0,%s0\n\trotl.b\t%s0\n\trotl.b\t%s0\n\tand.b\t#3,%s0\n\tsub.b\t%t0,%t0";
3065 goto end;
3066 case SHIFT_ASHIFTRT:
3067 if (TARGET_H8300)
3068 info->special = "mov.b\t%t0,%s0\n\tshll.b\t%s0\n\tsubx.b\t%t0,%t0\n\tshll.b\t%s0\n\tmov.b\t%t0,%s0\n\tbst.b\t#0,%s0";
3069 else if (TARGET_H8300H)
45ca2106
KH
3070 {
3071 info->special = "shll.b\t%t0\n\tsubx.b\t%s0,%s0\n\tshll.b\t%t0\n\trotxl.b\t%s0\n\texts.w\t%T0";
3072 info->cc_special = CC_SET_ZNV;
3073 }
5e98fba2 3074 else /* TARGET_H8300S */
b30686ec 3075 abort ();
5e98fba2
DD
3076 goto end;
3077 }
3078 }
1e41e866 3079 else if (count == 15)
51c0c1d7 3080 {
1e41e866
KH
3081 switch (shift_type)
3082 {
3083 case SHIFT_ASHIFT:
3084 info->special = "bld\t#0,%s0\n\txor\t%s0,%s0\n\txor\t%t0,%t0\n\tbst\t#7,%t0";
3085 goto end;
3086 case SHIFT_LSHIFTRT:
3087 info->special = "bld\t#7,%t0\n\txor\t%s0,%s0\n\txor\t%t0,%t0\n\tbst\t#0,%s0";
3088 goto end;
3089 case SHIFT_ASHIFTRT:
3090 info->special = "shll\t%t0\n\tsubx\t%t0,%t0\n\tmov.b\t%t0,%s0";
3091 goto end;
3092 }
07aae5c2 3093 }
769828ab 3094 abort ();
51c0c1d7 3095
48837e29 3096 case SIshift:
1e41e866 3097 if (TARGET_H8300 && 8 <= count && count <= 9)
48837e29 3098 {
1e41e866
KH
3099 info->remainder = count - 8;
3100
51c0c1d7 3101 switch (shift_type)
48837e29 3102 {
51c0c1d7 3103 case SHIFT_ASHIFT:
35fb3d1f 3104 info->special = "mov.b\t%y0,%z0\n\tmov.b\t%x0,%y0\n\tmov.b\t%w0,%x0\n\tsub.b\t%w0,%w0";
692b7eb3 3105 goto end;
51c0c1d7 3106 case SHIFT_LSHIFTRT:
35fb3d1f 3107 info->special = "mov.b\t%x0,%w0\n\tmov.b\t%y0,%x0\n\tmov.b\t%z0,%y0\n\tsub.b\t%z0,%z0";
1e41e866 3108 info->shift1 = "shlr\t%y0\n\trotxr\t%x0\n\trotxr\t%w0";
692b7eb3 3109 goto end;
51c0c1d7 3110 case SHIFT_ASHIFTRT:
35fb3d1f 3111 info->special = "mov.b\t%x0,%w0\n\tmov.b\t%y0,%x0\n\tmov.b\t%z0,%y0\n\tshll\t%z0\n\tsubx\t%z0,%z0";
692b7eb3 3112 goto end;
48837e29 3113 }
48837e29 3114 }
e6bcfef9
JS
3115 else if (count == 8 && !TARGET_H8300)
3116 {
3117 switch (shift_type)
3118 {
3119 case SHIFT_ASHIFT:
35fb3d1f 3120 info->special = "mov.w\t%e0,%f4\n\tmov.b\t%s4,%t4\n\tmov.b\t%t0,%s4\n\tmov.b\t%s0,%t0\n\tsub.b\t%s0,%s0\n\tmov.w\t%f4,%e0";
692b7eb3 3121 goto end;
e6bcfef9 3122 case SHIFT_LSHIFTRT:
35fb3d1f 3123 info->special = "mov.w\t%e0,%f4\n\tmov.b\t%t0,%s0\n\tmov.b\t%s4,%t0\n\tmov.b\t%t4,%s4\n\textu.w\t%f4\n\tmov.w\t%f4,%e0";
692b7eb3 3124 goto end;
e6bcfef9 3125 case SHIFT_ASHIFTRT:
35fb3d1f 3126 info->special = "mov.w\t%e0,%f4\n\tmov.b\t%t0,%s0\n\tmov.b\t%s4,%t0\n\tmov.b\t%t4,%s4\n\texts.w\t%f4\n\tmov.w\t%f4,%e0";
692b7eb3 3127 goto end;
e6bcfef9
JS
3128 }
3129 }
1e41e866
KH
3130 else if (count == 15 && TARGET_H8300)
3131 {
3132 switch (shift_type)
3133 {
3134 case SHIFT_ASHIFT:
3135 abort ();
3136 case SHIFT_LSHIFTRT:
a35abc3c 3137 info->special = "bld\t#7,%z0\n\tmov.w\t%e0,%f0\n\txor\t%y0,%y0\n\txor\t%z0,%z0\n\trotxl\t%w0\n\trotxl\t%x0\n\trotxl\t%y0";
1e41e866
KH
3138 goto end;
3139 case SHIFT_ASHIFTRT:
a35abc3c 3140 info->special = "bld\t#7,%z0\n\tmov.w\t%e0,%f0\n\trotxl\t%w0\n\trotxl\t%x0\n\tsubx\t%y0,%y0\n\tsubx\t%z0,%z0";
1e41e866
KH
3141 goto end;
3142 }
3143 }
dd69e230
KH
3144 else if (count == 15 && !TARGET_H8300)
3145 {
3146 switch (shift_type)
3147 {
3148 case SHIFT_ASHIFT:
3149 info->special = "shlr.w\t%e0\n\tmov.w\t%f0,%e0\n\txor.w\t%f0,%f0\n\trotxr.l\t%S0";
45ca2106 3150 info->cc_special = CC_SET_ZNV;
dd69e230
KH
3151 goto end;
3152 case SHIFT_LSHIFTRT:
18cf8dda 3153 info->special = "shll.w\t%f0\n\tmov.w\t%e0,%f0\n\txor.w\t%e0,%e0\n\trotxl.l\t%S0";
45ca2106 3154 info->cc_special = CC_SET_ZNV;
dd69e230 3155 goto end;
aefc5826
KH
3156 case SHIFT_ASHIFTRT:
3157 abort ();
dd69e230
KH
3158 }
3159 }
1e41e866 3160 else if ((TARGET_H8300 && 16 <= count && count <= 20)
a7812c0b 3161 || (TARGET_H8300H && 16 <= count && count <= 19)
e0f19bd0 3162 || (TARGET_H8300S && 16 <= count && count <= 21))
48837e29 3163 {
a7812c0b
KH
3164 info->remainder = count - 16;
3165
48837e29
DE
3166 switch (shift_type)
3167 {
3168 case SHIFT_ASHIFT:
35fb3d1f 3169 info->special = "mov.w\t%f0,%e0\n\tsub.w\t%f0,%f0";
1e41e866 3170 if (TARGET_H8300)
b30686ec 3171 info->shift1 = "add.w\t%e0,%e0";
692b7eb3 3172 goto end;
51c0c1d7 3173 case SHIFT_LSHIFTRT:
1e41e866
KH
3174 if (TARGET_H8300)
3175 {
a7612343
KH
3176 info->special = "mov.w\t%e0,%f0\n\tsub.w\t%e0,%e0";
3177 info->shift1 = "shlr\t%x0\n\trotxr\t%w0";
1e41e866
KH
3178 }
3179 else
3180 {
a7612343 3181 info->special = "mov.w\t%e0,%f0\n\textu.l\t%S0";
45ca2106 3182 info->cc_special = CC_SET_ZNV;
1e41e866 3183 }
692b7eb3 3184 goto end;
51c0c1d7
JL
3185 case SHIFT_ASHIFTRT:
3186 if (TARGET_H8300)
1e41e866
KH
3187 {
3188 info->special = "mov.w\t%e0,%f0\n\tshll\t%z0\n\tsubx\t%z0,%z0\n\tmov.b\t%z0,%y0";
3189 info->shift1 = "shar\t%x0\n\trotxr\t%w0";
3190 }
51c0c1d7 3191 else
1e41e866
KH
3192 {
3193 info->special = "mov.w\t%e0,%f0\n\texts.l\t%S0";
45ca2106 3194 info->cc_special = CC_SET_ZNV;
1e41e866 3195 }
692b7eb3 3196 goto end;
51c0c1d7
JL
3197 }
3198 }
1e41e866 3199 else if (TARGET_H8300 && 24 <= count && count <= 28)
f9477efd
KH
3200 {
3201 info->remainder = count - 24;
f0b6f9a6 3202
f9477efd
KH
3203 switch (shift_type)
3204 {
3205 case SHIFT_ASHIFT:
3206 info->special = "mov.b\t%w0,%z0\n\tsub.b\t%y0,%y0\n\tsub.w\t%f0,%f0";
3207 info->shift1 = "shll.b\t%z0";
45ca2106 3208 info->cc_inline = CC_SET_ZNV;
f9477efd
KH
3209 goto end;
3210 case SHIFT_LSHIFTRT:
3211 info->special = "mov.b\t%z0,%w0\n\tsub.b\t%x0,%x0\n\tsub.w\t%e0,%e0";
3212 info->shift1 = "shlr.b\t%w0";
45ca2106 3213 info->cc_inline = CC_SET_ZNV;
f9477efd
KH
3214 goto end;
3215 case SHIFT_ASHIFTRT:
3216 info->special = "mov.b\t%z0,%w0\n\tbld\t#7,%w0\n\tsubx\t%x0,%x0\n\tsubx\t%x0,%x0\n\tsubx\t%x0,%x0";
3217 info->shift1 = "shar.b\t%w0";
45ca2106 3218 info->cc_inline = CC_SET_ZNV;
7f473594
KH
3219 goto end;
3220 }
3221 }
4a4ae922
KH
3222 else if ((TARGET_H8300H && count == 24)
3223 || (TARGET_H8300S && 24 <= count && count <= 25))
e6bcfef9 3224 {
4a4ae922
KH
3225 info->remainder = count - 24;
3226
e6bcfef9
JS
3227 switch (shift_type)
3228 {
3229 case SHIFT_ASHIFT:
35fb3d1f 3230 info->special = "mov.b\t%s0,%t0\n\tsub.b\t%s0,%s0\n\tmov.w\t%f0,%e0\n\tsub.w\t%f0,%f0";
692b7eb3 3231 goto end;
e6bcfef9 3232 case SHIFT_LSHIFTRT:
35fb3d1f 3233 info->special = "mov.w\t%e0,%f0\n\tmov.b\t%t0,%s0\n\textu.w\t%f0\n\textu.l\t%S0";
45ca2106 3234 info->cc_special = CC_SET_ZNV;
692b7eb3 3235 goto end;
e6bcfef9 3236 case SHIFT_ASHIFTRT:
35fb3d1f 3237 info->special = "mov.w\t%e0,%f0\n\tmov.b\t%t0,%s0\n\texts.w\t%f0\n\texts.l\t%S0";
45ca2106 3238 info->cc_special = CC_SET_ZNV;
692b7eb3 3239 goto end;
e6bcfef9
JS
3240 }
3241 }
1e5bdc40
KH
3242 else if (!TARGET_H8300 && count == 28)
3243 {
3244 switch (shift_type)
3245 {
3246 case SHIFT_ASHIFT:
3247 if (TARGET_H8300H)
3248 info->special = "sub.w\t%e0,%e0\n\trotr.l\t%S0\n\trotr.l\t%S0\n\trotr.l\t%S0\n\trotr.l\t%S0\n\tsub.w\t%f0,%f0";
3249 else
3250 info->special = "sub.w\t%e0,%e0\n\trotr.l\t#2,%S0\n\trotr.l\t#2,%S0\n\tsub.w\t%f0,%f0";
1e5bdc40
KH
3251 goto end;
3252 case SHIFT_LSHIFTRT:
3253 if (TARGET_H8300H)
45ca2106
KH
3254 {
3255 info->special = "sub.w\t%f0,%f0\n\trotl.l\t%S0\n\trotl.l\t%S0\n\trotl.l\t%S0\n\trotl.l\t%S0\n\textu.l\t%S0";
3256 info->cc_special = CC_SET_ZNV;
3257 }
1e5bdc40 3258 else
a7612343 3259 info->special = "sub.w\t%f0,%f0\n\trotl.l\t#2,%S0\n\trotl.l\t#2,%S0\n\textu.l\t%S0";
1e5bdc40
KH
3260 goto end;
3261 case SHIFT_ASHIFTRT:
3262 abort ();
3263 }
3264 }
3265 else if (!TARGET_H8300 && count == 29)
3266 {
3267 switch (shift_type)
3268 {
3269 case SHIFT_ASHIFT:
3270 if (TARGET_H8300H)
3271 info->special = "sub.w\t%e0,%e0\n\trotr.l\t%S0\n\trotr.l\t%S0\n\trotr.l\t%S0\n\tsub.w\t%f0,%f0";
3272 else
3273 info->special = "sub.w\t%e0,%e0\n\trotr.l\t#2,%S0\n\trotr.l\t%S0\n\tsub.w\t%f0,%f0";
1e5bdc40
KH
3274 goto end;
3275 case SHIFT_LSHIFTRT:
3276 if (TARGET_H8300H)
45ca2106
KH
3277 {
3278 info->special = "sub.w\t%f0,%f0\n\trotl.l\t%S0\n\trotl.l\t%S0\n\trotl.l\t%S0\n\textu.l\t%S0";
3279 info->cc_special = CC_SET_ZNV;
3280 }
1e5bdc40 3281 else
45ca2106
KH
3282 {
3283 info->special = "sub.w\t%f0,%f0\n\trotl.l\t#2,%S0\n\trotl.l\t%S0\n\textu.l\t%S0";
3284 info->cc_special = CC_SET_ZNV;
3285 }
1e5bdc40
KH
3286 goto end;
3287 case SHIFT_ASHIFTRT:
3288 abort ();
3289 }
3290 }
3291 else if (!TARGET_H8300 && count == 30)
3292 {
3293 switch (shift_type)
3294 {
3295 case SHIFT_ASHIFT:
3296 if (TARGET_H8300H)
3297 info->special = "sub.w\t%e0,%e0\n\trotr.l\t%S0\n\trotr.l\t%S0\n\tsub.w\t%f0,%f0";
3298 else
3299 info->special = "sub.w\t%e0,%e0\n\trotr.l\t#2,%S0\n\tsub.w\t%f0,%f0";
1e5bdc40
KH
3300 goto end;
3301 case SHIFT_LSHIFTRT:
3302 if (TARGET_H8300H)
a7612343 3303 info->special = "sub.w\t%f0,%f0\n\trotl.l\t%S0\n\trotl.l\t%S0\n\textu.l\t%S0";
1e5bdc40 3304 else
a7612343 3305 info->special = "sub.w\t%f0,%f0\n\trotl.l\t#2,%S0\n\textu.l\t%S0";
1e5bdc40
KH
3306 goto end;
3307 case SHIFT_ASHIFTRT:
3308 abort ();
3309 }
3310 }
48837e29
DE
3311 else if (count == 31)
3312 {
dd69e230 3313 if (TARGET_H8300)
48837e29 3314 {
dd69e230
KH
3315 switch (shift_type)
3316 {
3317 case SHIFT_ASHIFT:
3318 info->special = "sub.w\t%e0,%e0\n\tshlr\t%w0\n\tmov.w\t%e0,%f0\n\trotxr\t%z0";
3319 goto end;
3320 case SHIFT_LSHIFTRT:
3321 info->special = "sub.w\t%f0,%f0\n\tshll\t%z0\n\tmov.w\t%f0,%e0\n\trotxl\t%w0";
3322 goto end;
3323 case SHIFT_ASHIFTRT:
3324 info->special = "shll\t%z0\n\tsubx\t%w0,%w0\n\tmov.b\t%w0,%x0\n\tmov.w\t%f0,%e0";
3325 goto end;
3326 }
48837e29
DE
3327 }
3328 else
3329 {
dd69e230 3330 switch (shift_type)
48837e29 3331 {
dd69e230
KH
3332 case SHIFT_ASHIFT:
3333 info->special = "shlr.l\t%S0\n\txor.l\t%S0,%S0\n\trotxr.l\t%S0";
45ca2106 3334 info->cc_special = CC_SET_ZNV;
dd69e230
KH
3335 goto end;
3336 case SHIFT_LSHIFTRT:
3337 info->special = "shll.l\t%S0\n\txor.l\t%S0,%S0\n\trotxl.l\t%S0";
45ca2106 3338 info->cc_special = CC_SET_ZNV;
dd69e230
KH
3339 goto end;
3340 case SHIFT_ASHIFTRT:
a7612343 3341 info->special = "shll\t%e0\n\tsubx\t%w0,%w0\n\texts.w\t%T0\n\texts.l\t%S0";
45ca2106 3342 info->cc_special = CC_SET_ZNV;
692b7eb3 3343 goto end;
48837e29 3344 }
48837e29
DE
3345 }
3346 }
769828ab 3347 abort ();
51c0c1d7 3348
48837e29
DE
3349 default:
3350 abort ();
07aae5c2 3351 }
48837e29 3352
cb33eb17
KH
3353 end:
3354 if (!TARGET_H8300S)
3355 info->shift2 = NULL;
07aae5c2
SC
3356}
3357
be1e06df
KH
3358/* Given COUNT and MODE of a shift, return 1 if a scratch reg may be
3359 needed for some shift with COUNT and MODE. Return 0 otherwise. */
3360
3361int
cb713a8d 3362h8300_shift_needs_scratch_p (int count, enum machine_mode mode)
be1e06df 3363{
b9b575e6 3364 enum h8_cpu cpu;
be1e06df
KH
3365 int a, lr, ar;
3366
3367 if (GET_MODE_BITSIZE (mode) <= count)
3368 return 1;
3369
3370 /* Find out the target CPU. */
3371 if (TARGET_H8300)
b9b575e6 3372 cpu = H8_300;
be1e06df 3373 else if (TARGET_H8300H)
b9b575e6 3374 cpu = H8_300H;
be1e06df 3375 else
b9b575e6 3376 cpu = H8_S;
be1e06df
KH
3377
3378 /* Find the shift algorithm. */
3379 switch (mode)
3380 {
3381 case QImode:
3382 a = shift_alg_qi[cpu][SHIFT_ASHIFT][count];
3383 lr = shift_alg_qi[cpu][SHIFT_LSHIFTRT][count];
3384 ar = shift_alg_qi[cpu][SHIFT_ASHIFTRT][count];
3385 break;
3386
3387 case HImode:
3388 a = shift_alg_hi[cpu][SHIFT_ASHIFT][count];
3389 lr = shift_alg_hi[cpu][SHIFT_LSHIFTRT][count];
3390 ar = shift_alg_hi[cpu][SHIFT_ASHIFTRT][count];
3391 break;
3392
3393 case SImode:
3394 a = shift_alg_si[cpu][SHIFT_ASHIFT][count];
3395 lr = shift_alg_si[cpu][SHIFT_LSHIFTRT][count];
3396 ar = shift_alg_si[cpu][SHIFT_ASHIFTRT][count];
3397 break;
3398
3399 default:
3400 abort ();
3401 }
3402
aa2fb4dd 3403 /* On H8/300H, count == 8 uses a scratch register. */
be1e06df 3404 return (a == SHIFT_LOOP || lr == SHIFT_LOOP || ar == SHIFT_LOOP
75a3503b 3405 || (TARGET_H8300H && mode == SImode && count == 8));
be1e06df
KH
3406}
3407
48837e29
DE
3408/* Emit the assembler code for doing shifts. */
3409
441d04c6 3410const char *
cb713a8d 3411output_a_shift (rtx *operands)
07aae5c2 3412{
48837e29 3413 static int loopend_lab;
48837e29
DE
3414 rtx shift = operands[3];
3415 enum machine_mode mode = GET_MODE (shift);
3416 enum rtx_code code = GET_CODE (shift);
3417 enum shift_type shift_type;
3418 enum shift_mode shift_mode;
35fb3d1f 3419 struct shift_info info;
48837e29
DE
3420
3421 loopend_lab++;
3422
3423 switch (mode)
3424 {
3425 case QImode:
3426 shift_mode = QIshift;
3427 break;
3428 case HImode:
3429 shift_mode = HIshift;
3430 break;
3431 case SImode:
3432 shift_mode = SIshift;
3433 break;
3434 default:
3435 abort ();
3436 }
07aae5c2 3437
48837e29 3438 switch (code)
07aae5c2 3439 {
48837e29
DE
3440 case ASHIFTRT:
3441 shift_type = SHIFT_ASHIFTRT;
3442 break;
3443 case LSHIFTRT:
3444 shift_type = SHIFT_LSHIFTRT;
3445 break;
3446 case ASHIFT:
3447 shift_type = SHIFT_ASHIFT;
3448 break;
3449 default:
3450 abort ();
3451 }
07aae5c2 3452
48837e29
DE
3453 if (GET_CODE (operands[2]) != CONST_INT)
3454 {
cd9b5ca8
KH
3455 /* This case must be taken care of by one of the two splitters
3456 that convert a variable shift into a loop. */
3457 abort ();
48837e29
DE
3458 }
3459 else
3460 {
3461 int n = INTVAL (operands[2]);
48837e29
DE
3462
3463 /* If the count is negative, make it 0. */
3464 if (n < 0)
3465 n = 0;
3466 /* If the count is too big, truncate it.
3467 ANSI says shifts of GET_MODE_BITSIZE are undefined - we choose to
3468 do the intuitive thing. */
64530b82 3469 else if ((unsigned int) n > GET_MODE_BITSIZE (mode))
48837e29
DE
3470 n = GET_MODE_BITSIZE (mode);
3471
cb33eb17 3472 get_shift_alg (shift_type, shift_mode, n, &info);
48837e29 3473
cb33eb17 3474 switch (info.alg)
48837e29 3475 {
cb33eb17
KH
3476 case SHIFT_SPECIAL:
3477 output_asm_insn (info.special, operands);
3478 /* Fall through. */
3479
48837e29 3480 case SHIFT_INLINE:
cb33eb17
KH
3481 n = info.remainder;
3482
51c0c1d7 3483 /* Emit two bit shifts first. */
1a275226 3484 if (info.shift2 != NULL)
51c0c1d7 3485 {
1a275226
KH
3486 for (; n > 1; n -= 2)
3487 output_asm_insn (info.shift2, operands);
51c0c1d7
JL
3488 }
3489
3490 /* Now emit one bit shifts for any residual. */
1a275226
KH
3491 for (; n > 0; n--)
3492 output_asm_insn (info.shift1, operands);
48837e29 3493 return "";
51c0c1d7 3494
48837e29
DE
3495 case SHIFT_ROT_AND:
3496 {
3497 int m = GET_MODE_BITSIZE (mode) - n;
7798db98
KH
3498 const int mask = (shift_type == SHIFT_ASHIFT
3499 ? ((1 << m) - 1) << n
3500 : (1 << m) - 1);
48837e29 3501 char insn_buf[200];
b5eaf9ba 3502
48837e29
DE
3503 /* Not all possibilities of rotate are supported. They shouldn't
3504 be generated, but let's watch for 'em. */
35fb3d1f 3505 if (info.shift1 == 0)
48837e29 3506 abort ();
51c0c1d7
JL
3507
3508 /* Emit two bit rotates first. */
1a275226 3509 if (info.shift2 != NULL)
51c0c1d7 3510 {
1a275226
KH
3511 for (; m > 1; m -= 2)
3512 output_asm_insn (info.shift2, operands);
51c0c1d7
JL
3513 }
3514
3515 /* Now single bit rotates for any residual. */
1a275226
KH
3516 for (; m > 0; m--)
3517 output_asm_insn (info.shift1, operands);
51c0c1d7
JL
3518
3519 /* Now mask off the high bits. */
ade53a50
KH
3520 if (mode == QImode)
3521 sprintf (insn_buf, "and\t#%d,%%X0", mask);
3522 else if (mode == HImode && (TARGET_H8300H || TARGET_H8300S))
3523 sprintf (insn_buf, "and.w\t#%d,%%T0", mask);
3524 else
3525 abort ();
3526
48837e29
DE
3527 output_asm_insn (insn_buf, operands);
3528 return "";
3529 }
b5eaf9ba 3530
b5eaf9ba
KH
3531 case SHIFT_LOOP:
3532 /* A loop to shift by a "large" constant value.
3533 If we have shift-by-2 insns, use them. */
35fb3d1f 3534 if (info.shift2 != NULL)
b5eaf9ba
KH
3535 {
3536 fprintf (asm_out_file, "\tmov.b #%d,%sl\n", n / 2,
3537 names_big[REGNO (operands[4])]);
3538 fprintf (asm_out_file, ".Llt%d:\n", loopend_lab);
35fb3d1f 3539 output_asm_insn (info.shift2, operands);
b5eaf9ba
KH
3540 output_asm_insn ("add #0xff,%X4", operands);
3541 fprintf (asm_out_file, "\tbne .Llt%d\n", loopend_lab);
3542 if (n % 2)
35fb3d1f 3543 output_asm_insn (info.shift1, operands);
b5eaf9ba
KH
3544 }
3545 else
3546 {
3547 fprintf (asm_out_file, "\tmov.b #%d,%sl\n", n,
3548 names_big[REGNO (operands[4])]);
3549 fprintf (asm_out_file, ".Llt%d:\n", loopend_lab);
35fb3d1f 3550 output_asm_insn (info.shift1, operands);
b5eaf9ba
KH
3551 output_asm_insn ("add #0xff,%X4", operands);
3552 fprintf (asm_out_file, "\tbne .Llt%d\n", loopend_lab);
3553 }
51c0c1d7 3554 return "";
b5eaf9ba
KH
3555
3556 default:
3557 abort ();
51c0c1d7 3558 }
07aae5c2 3559 }
07aae5c2 3560}
86855e8c
KH
3561
3562static unsigned int
cb713a8d 3563h8300_asm_insn_count (const char *template)
86855e8c
KH
3564{
3565 unsigned int count = 1;
3566
3567 for (; *template; template++)
3568 if (*template == '\n')
3569 count++;
3570
3571 return count;
3572}
3573
3574unsigned int
cb713a8d 3575compute_a_shift_length (rtx insn ATTRIBUTE_UNUSED, rtx *operands)
86855e8c
KH
3576{
3577 rtx shift = operands[3];
3578 enum machine_mode mode = GET_MODE (shift);
3579 enum rtx_code code = GET_CODE (shift);
3580 enum shift_type shift_type;
3581 enum shift_mode shift_mode;
3582 struct shift_info info;
3583 unsigned int wlength = 0;
3584
3585 switch (mode)
3586 {
3587 case QImode:
3588 shift_mode = QIshift;
3589 break;
3590 case HImode:
3591 shift_mode = HIshift;
3592 break;
3593 case SImode:
3594 shift_mode = SIshift;
3595 break;
3596 default:
3597 abort ();
3598 }
3599
3600 switch (code)
3601 {
3602 case ASHIFTRT:
3603 shift_type = SHIFT_ASHIFTRT;
3604 break;
3605 case LSHIFTRT:
3606 shift_type = SHIFT_LSHIFTRT;
3607 break;
3608 case ASHIFT:
3609 shift_type = SHIFT_ASHIFT;
3610 break;
3611 default:
3612 abort ();
3613 }
3614
3615 if (GET_CODE (operands[2]) != CONST_INT)
3616 {
3617 /* Get the assembler code to do one shift. */
3618 get_shift_alg (shift_type, shift_mode, 1, &info);
3619
3620 return (4 + h8300_asm_insn_count (info.shift1)) * 2;
3621 }
3622 else
3623 {
3624 int n = INTVAL (operands[2]);
3625
3626 /* If the count is negative, make it 0. */
3627 if (n < 0)
3628 n = 0;
3629 /* If the count is too big, truncate it.
3630 ANSI says shifts of GET_MODE_BITSIZE are undefined - we choose to
3631 do the intuitive thing. */
3632 else if ((unsigned int) n > GET_MODE_BITSIZE (mode))
3633 n = GET_MODE_BITSIZE (mode);
3634
3635 get_shift_alg (shift_type, shift_mode, n, &info);
3636
3637 switch (info.alg)
3638 {
3639 case SHIFT_SPECIAL:
3640 wlength += h8300_asm_insn_count (info.special);
41c3eb5d
KH
3641
3642 /* Every assembly instruction used in SHIFT_SPECIAL case
3643 takes 2 bytes except xor.l, which takes 4 bytes, so if we
3644 see xor.l, we just pretend that xor.l counts as two insns
3645 so that the insn length will be computed correctly. */
3646 if (strstr (info.special, "xor.l") != NULL)
3647 wlength++;
3648
86855e8c
KH
3649 /* Fall through. */
3650
3651 case SHIFT_INLINE:
3652 n = info.remainder;
3653
3654 if (info.shift2 != NULL)
3655 {
3656 wlength += h8300_asm_insn_count (info.shift2) * (n / 2);
3657 n = n % 2;
3658 }
3659
3660 wlength += h8300_asm_insn_count (info.shift1) * n;
6b148bd9 3661
86855e8c
KH
3662 return 2 * wlength;
3663
3664 case SHIFT_ROT_AND:
3665 {
3666 int m = GET_MODE_BITSIZE (mode) - n;
3667
3668 /* Not all possibilities of rotate are supported. They shouldn't
3669 be generated, but let's watch for 'em. */
3670 if (info.shift1 == 0)
3671 abort ();
3672
3673 if (info.shift2 != NULL)
3674 {
3675 wlength += h8300_asm_insn_count (info.shift2) * (m / 2);
3676 m = m % 2;
3677 }
3678
3679 wlength += h8300_asm_insn_count (info.shift1) * m;
6b148bd9 3680
86855e8c
KH
3681 /* Now mask off the high bits. */
3682 switch (mode)
3683 {
3684 case QImode:
3685 wlength += 1;
3686 break;
3687 case HImode:
3688 wlength += 2;
3689 break;
3690 case SImode:
3691 if (TARGET_H8300)
3692 abort ();
3693 wlength += 3;
3694 break;
3695 default:
3696 abort ();
3697 }
3698 return 2 * wlength;
3699 }
3700
3701 case SHIFT_LOOP:
3702 /* A loop to shift by a "large" constant value.
3703 If we have shift-by-2 insns, use them. */
3704 if (info.shift2 != NULL)
3705 {
3706 wlength += 3 + h8300_asm_insn_count (info.shift2);
3707 if (n % 2)
3708 wlength += h8300_asm_insn_count (info.shift1);
3709 }
3710 else
3711 {
3712 wlength += 3 + h8300_asm_insn_count (info.shift1);
3713 }
3714 return 2 * wlength;
3715
3716 default:
3717 abort ();
3718 }
3719 }
3720}
45ca2106
KH
3721
3722int
cb713a8d 3723compute_a_shift_cc (rtx insn ATTRIBUTE_UNUSED, rtx *operands)
45ca2106
KH
3724{
3725 rtx shift = operands[3];
3726 enum machine_mode mode = GET_MODE (shift);
3727 enum rtx_code code = GET_CODE (shift);
3728 enum shift_type shift_type;
3729 enum shift_mode shift_mode;
3730 struct shift_info info;
3731
3732 switch (mode)
3733 {
3734 case QImode:
3735 shift_mode = QIshift;
3736 break;
3737 case HImode:
3738 shift_mode = HIshift;
3739 break;
3740 case SImode:
3741 shift_mode = SIshift;
3742 break;
3743 default:
3744 abort ();
3745 }
3746
3747 switch (code)
3748 {
3749 case ASHIFTRT:
3750 shift_type = SHIFT_ASHIFTRT;
3751 break;
3752 case LSHIFTRT:
3753 shift_type = SHIFT_LSHIFTRT;
3754 break;
3755 case ASHIFT:
3756 shift_type = SHIFT_ASHIFT;
3757 break;
3758 default:
3759 abort ();
3760 }
3761
3762 if (GET_CODE (operands[2]) != CONST_INT)
3763 {
3764 /* This case must be taken care of by one of the two splitters
3765 that convert a variable shift into a loop. */
3766 abort ();
3767 }
3768 else
3769 {
3770 int n = INTVAL (operands[2]);
3771
3772 /* If the count is negative, make it 0. */
3773 if (n < 0)
3774 n = 0;
3775 /* If the count is too big, truncate it.
3776 ANSI says shifts of GET_MODE_BITSIZE are undefined - we choose to
3777 do the intuitive thing. */
3778 else if ((unsigned int) n > GET_MODE_BITSIZE (mode))
3779 n = GET_MODE_BITSIZE (mode);
3780
3781 get_shift_alg (shift_type, shift_mode, n, &info);
3782
3783 switch (info.alg)
3784 {
3785 case SHIFT_SPECIAL:
3786 if (info.remainder == 0)
3787 return info.cc_special;
3788
3789 /* Fall through. */
3790
3791 case SHIFT_INLINE:
3792 return info.cc_inline;
3793
3794 case SHIFT_ROT_AND:
3795 /* This case always ends with an and instruction. */
3796 return CC_SET_ZNV;
3797
3798 case SHIFT_LOOP:
3799 /* A loop to shift by a "large" constant value.
3800 If we have shift-by-2 insns, use them. */
3801 if (info.shift2 != NULL)
3802 {
3803 if (n % 2)
3804 return info.cc_inline;
3805 }
3806 return CC_CLOBBER;
3807
3808 default:
3809 abort ();
3810 }
3811 }
3812}
48837e29 3813\f
edd71f0f
KH
3814/* A rotation by a non-constant will cause a loop to be generated, in
3815 which a rotation by one bit is used. A rotation by a constant,
3816 including the one in the loop, will be taken care of by
caf7f21a 3817 output_a_rotate () at the insn emit time. */
edd71f0f
KH
3818
3819int
cb713a8d 3820expand_a_rotate (enum rtx_code code, rtx operands[])
edd71f0f
KH
3821{
3822 rtx dst = operands[0];
3823 rtx src = operands[1];
3824 rtx rotate_amount = operands[2];
3825 enum machine_mode mode = GET_MODE (dst);
3826 rtx tmp;
3827
3828 /* We rotate in place. */
3829 emit_move_insn (dst, src);
3830
3831 if (GET_CODE (rotate_amount) != CONST_INT)
3832 {
3833 rtx counter = gen_reg_rtx (QImode);
3834 rtx start_label = gen_label_rtx ();
3835 rtx end_label = gen_label_rtx ();
3836
3837 /* If the rotate amount is less than or equal to 0,
3838 we go out of the loop. */
d43e0b7d
RK
3839 emit_cmp_and_jump_insns (rotate_amount, GEN_INT (0), LE, NULL_RTX,
3840 QImode, 0, end_label);
edd71f0f
KH
3841
3842 /* Initialize the loop counter. */
3843 emit_move_insn (counter, rotate_amount);
3844
3845 emit_label (start_label);
3846
3847 /* Rotate by one bit. */
3848 tmp = gen_rtx (code, mode, dst, GEN_INT (1));
3849 emit_insn (gen_rtx_SET (mode, dst, tmp));
3850
3851 /* Decrement the counter by 1. */
3852 tmp = gen_rtx_PLUS (QImode, counter, GEN_INT (-1));
3853 emit_insn (gen_rtx_SET (VOIDmode, counter, tmp));
3854
9cd10576 3855 /* If the loop counter is nonzero, we go back to the beginning
edd71f0f 3856 of the loop. */
d43e0b7d
RK
3857 emit_cmp_and_jump_insns (counter, GEN_INT (0), NE, NULL_RTX, QImode, 1,
3858 start_label);
edd71f0f
KH
3859
3860 emit_label (end_label);
3861 }
3862 else
3863 {
3864 /* Rotate by AMOUNT bits. */
3865 tmp = gen_rtx (code, mode, dst, rotate_amount);
3866 emit_insn (gen_rtx_SET (mode, dst, tmp));
3867 }
3868
3869 return 1;
3870}
3871
caf7f21a 3872/* Output rotate insns. */
edd71f0f
KH
3873
3874const char *
caf7f21a 3875output_a_rotate (enum rtx_code code, rtx *operands)
edd71f0f
KH
3876{
3877 rtx dst = operands[0];
3878 rtx rotate_amount = operands[2];
3879 enum shift_mode rotate_mode;
3880 enum shift_type rotate_type;
3881 const char *insn_buf;
3882 int bits;
3883 int amount;
3884 enum machine_mode mode = GET_MODE (dst);
3885
3886 if (GET_CODE (rotate_amount) != CONST_INT)
3887 abort ();
3888
3889 switch (mode)
3890 {
3891 case QImode:
3892 rotate_mode = QIshift;
3893 break;
3894 case HImode:
3895 rotate_mode = HIshift;
3896 break;
3897 case SImode:
3898 rotate_mode = SIshift;
3899 break;
3900 default:
3901 abort ();
3902 }
3903
3904 switch (code)
3905 {
3906 case ROTATERT:
3907 rotate_type = SHIFT_ASHIFT;
3908 break;
3909 case ROTATE:
3910 rotate_type = SHIFT_LSHIFTRT;
3911 break;
3912 default:
3913 abort ();
3914 }
3915
3916 amount = INTVAL (rotate_amount);
3917
3918 /* Clean up AMOUNT. */
3919 if (amount < 0)
3920 amount = 0;
3921 if ((unsigned int) amount > GET_MODE_BITSIZE (mode))
3922 amount = GET_MODE_BITSIZE (mode);
3923
3924 /* Determine the faster direction. After this phase, amount will be
3925 at most a half of GET_MODE_BITSIZE (mode). */
e0c32c62 3926 if ((unsigned int) amount > GET_MODE_BITSIZE (mode) / (unsigned) 2)
edd71f0f
KH
3927 {
3928 /* Flip the direction. */
3929 amount = GET_MODE_BITSIZE (mode) - amount;
3930 rotate_type =
3931 (rotate_type == SHIFT_ASHIFT) ? SHIFT_LSHIFTRT : SHIFT_ASHIFT;
3932 }
3933
3934 /* See if a byte swap (in HImode) or a word swap (in SImode) can
3935 boost up the rotation. */
3936 if ((mode == HImode && TARGET_H8300 && amount >= 5)
3937 || (mode == HImode && TARGET_H8300H && amount >= 6)
3938 || (mode == HImode && TARGET_H8300S && amount == 8)
3939 || (mode == SImode && TARGET_H8300H && amount >= 10)
3940 || (mode == SImode && TARGET_H8300S && amount >= 13))
3941 {
3942 switch (mode)
3943 {
3944 case HImode:
3945 /* This code works on any family. */
3946 insn_buf = "xor.b\t%s0,%t0\n\txor.b\t%t0,%s0\n\txor.b\t%s0,%t0";
3947 output_asm_insn (insn_buf, operands);
3948 break;
3949
3950 case SImode:
3db11b5c 3951 /* This code works on the H8/300H and H8S. */
edd71f0f
KH
3952 insn_buf = "xor.w\t%e0,%f0\n\txor.w\t%f0,%e0\n\txor.w\t%e0,%f0";
3953 output_asm_insn (insn_buf, operands);
3954 break;
3955
3956 default:
3957 abort ();
3958 }
3959
3960 /* Adjust AMOUNT and flip the direction. */
3961 amount = GET_MODE_BITSIZE (mode) / 2 - amount;
3962 rotate_type =
3963 (rotate_type == SHIFT_ASHIFT) ? SHIFT_LSHIFTRT : SHIFT_ASHIFT;
3964 }
3965
3966 /* Emit rotate insns. */
3967 for (bits = TARGET_H8300S ? 2 : 1; bits > 0; bits /= 2)
3968 {
3969 if (bits == 2)
3970 insn_buf = rotate_two[rotate_type][rotate_mode];
3971 else
3972 insn_buf = rotate_one[cpu_type][rotate_type][rotate_mode];
2c54abce 3973
edd71f0f
KH
3974 for (; amount >= bits; amount -= bits)
3975 output_asm_insn (insn_buf, operands);
3976 }
3977
3978 return "";
3979}
caf7f21a
KH
3980
3981unsigned int
3982compute_a_rotate_length (rtx *operands)
3983{
3984 rtx src = operands[1];
343fd2c7 3985 rtx amount_rtx = operands[2];
caf7f21a
KH
3986 enum machine_mode mode = GET_MODE (src);
3987 int amount;
3988 unsigned int length = 0;
3989
343fd2c7
KH
3990 if (GET_CODE (amount_rtx) != CONST_INT)
3991 abort ();
caf7f21a 3992
343fd2c7 3993 amount = INTVAL (amount_rtx);
caf7f21a
KH
3994
3995 /* Clean up AMOUNT. */
3996 if (amount < 0)
3997 amount = 0;
3998 if ((unsigned int) amount > GET_MODE_BITSIZE (mode))
3999 amount = GET_MODE_BITSIZE (mode);
4000
4001 /* Determine the faster direction. After this phase, amount
4002 will be at most a half of GET_MODE_BITSIZE (mode). */
4003 if ((unsigned int) amount > GET_MODE_BITSIZE (mode) / (unsigned) 2)
4004 /* Flip the direction. */
4005 amount = GET_MODE_BITSIZE (mode) - amount;
4006
4007 /* See if a byte swap (in HImode) or a word swap (in SImode) can
4008 boost up the rotation. */
4009 if ((mode == HImode && TARGET_H8300 && amount >= 5)
4010 || (mode == HImode && TARGET_H8300H && amount >= 6)
4011 || (mode == HImode && TARGET_H8300S && amount == 8)
4012 || (mode == SImode && TARGET_H8300H && amount >= 10)
4013 || (mode == SImode && TARGET_H8300S && amount >= 13))
4014 {
4015 /* Adjust AMOUNT and flip the direction. */
4016 amount = GET_MODE_BITSIZE (mode) / 2 - amount;
4017 length += 6;
4018 }
4019
4020 /* We use 2-bit rotations on the H8S. */
4021 if (TARGET_H8300S)
4022 amount = amount / 2 + amount % 2;
4023
4024 /* The H8/300 uses three insns to rotate one bit, taking 6
4025 length. */
4026 length += amount * ((TARGET_H8300 && mode == HImode) ? 6 : 2);
4027
4028 return length;
4029}
edd71f0f 4030\f
48837e29 4031/* Fix the operands of a gen_xxx so that it could become a bit
2c54abce 4032 operating insn. */
07aae5c2
SC
4033
4034int
cb713a8d 4035fix_bit_operand (rtx *operands, int what, enum rtx_code type)
07aae5c2 4036{
abc95ed3 4037 /* The bit_operand predicate accepts any memory during RTL generation, but
48837e29
DE
4038 only 'U' memory afterwards, so if this is a MEM operand, we must force
4039 it to be valid for 'U' by reloading the address. */
07aae5c2 4040
2e760b15
KH
4041 if ((what == 0 && single_zero_operand (operands[2], QImode))
4042 || (what == 1 && single_one_operand (operands[2], QImode)))
07aae5c2 4043 {
2e760b15
KH
4044 /* OK to have a memory dest. */
4045 if (GET_CODE (operands[0]) == MEM
4046 && !EXTRA_CONSTRAINT (operands[0], 'U'))
48837e29 4047 {
2e760b15
KH
4048 rtx mem = gen_rtx_MEM (GET_MODE (operands[0]),
4049 copy_to_mode_reg (Pmode,
4050 XEXP (operands[0], 0)));
4051 MEM_COPY_ATTRIBUTES (mem, operands[0]);
4052 operands[0] = mem;
4053 }
48837e29 4054
2e760b15
KH
4055 if (GET_CODE (operands[1]) == MEM
4056 && !EXTRA_CONSTRAINT (operands[1], 'U'))
4057 {
4058 rtx mem = gen_rtx_MEM (GET_MODE (operands[1]),
4059 copy_to_mode_reg (Pmode,
4060 XEXP (operands[1], 0)));
4061 MEM_COPY_ATTRIBUTES (mem, operands[0]);
4062 operands[1] = mem;
48837e29 4063 }
2e760b15 4064 return 0;
48837e29 4065 }
07aae5c2 4066
48837e29 4067 /* Dest and src op must be register. */
07aae5c2 4068
48837e29
DE
4069 operands[1] = force_reg (QImode, operands[1]);
4070 {
4071 rtx res = gen_reg_rtx (QImode);
c5c76735
JL
4072 emit_insn (gen_rtx_SET (VOIDmode, res,
4073 gen_rtx (type, QImode, operands[1], operands[2])));
4074 emit_insn (gen_rtx_SET (VOIDmode, operands[0], res));
48837e29
DE
4075 }
4076 return 1;
07aae5c2 4077}
f5b65a56 4078
f5b65a56
JL
4079/* Return nonzero if FUNC is an interrupt function as specified
4080 by the "interrupt" attribute. */
4081
4082static int
cb713a8d 4083h8300_interrupt_function_p (tree func)
f5b65a56
JL
4084{
4085 tree a;
4086
4087 if (TREE_CODE (func) != FUNCTION_DECL)
4088 return 0;
4089
91d231cb 4090 a = lookup_attribute ("interrupt_handler", DECL_ATTRIBUTES (func));
f5b65a56
JL
4091 return a != NULL_TREE;
4092}
4093
3cfa3702
KH
4094/* Return nonzero if FUNC is a saveall function as specified by the
4095 "saveall" attribute. */
4096
4097static int
4098h8300_saveall_function_p (tree func)
4099{
4100 tree a;
4101
4102 if (TREE_CODE (func) != FUNCTION_DECL)
4103 return 0;
4104
4105 a = lookup_attribute ("saveall", DECL_ATTRIBUTES (func));
4106 return a != NULL_TREE;
4107}
4108
fabe72bb
JL
4109/* Return nonzero if FUNC is an OS_Task function as specified
4110 by the "OS_Task" attribute. */
4111
4112static int
cb713a8d 4113h8300_os_task_function_p (tree func)
fabe72bb
JL
4114{
4115 tree a;
4116
4117 if (TREE_CODE (func) != FUNCTION_DECL)
4118 return 0;
4119
91d231cb 4120 a = lookup_attribute ("OS_Task", DECL_ATTRIBUTES (func));
fabe72bb
JL
4121 return a != NULL_TREE;
4122}
4123
4124/* Return nonzero if FUNC is a monitor function as specified
4125 by the "monitor" attribute. */
4126
4127static int
cb713a8d 4128h8300_monitor_function_p (tree func)
fabe72bb
JL
4129{
4130 tree a;
4131
4132 if (TREE_CODE (func) != FUNCTION_DECL)
4133 return 0;
4134
91d231cb 4135 a = lookup_attribute ("monitor", DECL_ATTRIBUTES (func));
fabe72bb
JL
4136 return a != NULL_TREE;
4137}
4138
f5b65a56
JL
4139/* Return nonzero if FUNC is a function that should be called
4140 through the function vector. */
4141
4142int
cb713a8d 4143h8300_funcvec_function_p (tree func)
f5b65a56
JL
4144{
4145 tree a;
4146
4147 if (TREE_CODE (func) != FUNCTION_DECL)
4148 return 0;
4149
91d231cb 4150 a = lookup_attribute ("function_vector", DECL_ATTRIBUTES (func));
f5b65a56
JL
4151 return a != NULL_TREE;
4152}
4153
887a8bd9 4154/* Return nonzero if DECL is a variable that's in the eight bit
15dc331e
JL
4155 data area. */
4156
4157int
cb713a8d 4158h8300_eightbit_data_p (tree decl)
15dc331e
JL
4159{
4160 tree a;
4161
4162 if (TREE_CODE (decl) != VAR_DECL)
4163 return 0;
4164
91d231cb 4165 a = lookup_attribute ("eightbit_data", DECL_ATTRIBUTES (decl));
15dc331e
JL
4166 return a != NULL_TREE;
4167}
4168
887a8bd9
JL
4169/* Return nonzero if DECL is a variable that's in the tiny
4170 data area. */
4171
4172int
cb713a8d 4173h8300_tiny_data_p (tree decl)
887a8bd9
JL
4174{
4175 tree a;
4176
4177 if (TREE_CODE (decl) != VAR_DECL)
4178 return 0;
4179
91d231cb 4180 a = lookup_attribute ("tiny_data", DECL_ATTRIBUTES (decl));
887a8bd9
JL
4181 return a != NULL_TREE;
4182}
4183
3cfa3702
KH
4184/* Generate an 'interrupt_handler' attribute for decls. We convert
4185 all the pragmas to corresponding attributes. */
2c1d2fcb
DD
4186
4187static void
cb713a8d 4188h8300_insert_attributes (tree node, tree *attributes)
2c1d2fcb 4189{
3cfa3702
KH
4190 if (TREE_CODE (node) == FUNCTION_DECL)
4191 {
4192 if (pragma_interrupt)
4193 {
4194 pragma_interrupt = 0;
2c1d2fcb 4195
3cfa3702
KH
4196 /* Add an 'interrupt_handler' attribute. */
4197 *attributes = tree_cons (get_identifier ("interrupt_handler"),
4198 NULL, *attributes);
4199 }
e392d367 4200
3cfa3702
KH
4201 if (pragma_saveall)
4202 {
4203 pragma_saveall = 0;
4204
4205 /* Add an 'saveall' attribute. */
4206 *attributes = tree_cons (get_identifier ("saveall"),
4207 NULL, *attributes);
4208 }
4209 }
2c1d2fcb
DD
4210}
4211
91d231cb 4212/* Supported attributes:
f5b65a56 4213
97c5ec1d 4214 interrupt_handler: output a prologue and epilogue suitable for an
f5b65a56
JL
4215 interrupt handler.
4216
3cfa3702
KH
4217 saveall: output a prologue and epilogue that saves and restores
4218 all registers except the stack pointer.
4219
97c5ec1d 4220 function_vector: This function should be called through the
887a8bd9
JL
4221 function vector.
4222
4223 eightbit_data: This variable lives in the 8-bit data area and can
4224 be referenced with 8-bit absolute memory addresses.
4225
4226 tiny_data: This variable lives in the tiny data area and can be
4227 referenced with 16-bit absolute memory references. */
f5b65a56 4228
91d231cb 4229const struct attribute_spec h8300_attribute_table[] =
f5b65a56 4230{
91d231cb
JM
4231 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
4232 { "interrupt_handler", 0, 0, true, false, false, h8300_handle_fndecl_attribute },
3cfa3702 4233 { "saveall", 0, 0, true, false, false, h8300_handle_fndecl_attribute },
91d231cb
JM
4234 { "OS_Task", 0, 0, true, false, false, h8300_handle_fndecl_attribute },
4235 { "monitor", 0, 0, true, false, false, h8300_handle_fndecl_attribute },
4236 { "function_vector", 0, 0, true, false, false, h8300_handle_fndecl_attribute },
4237 { "eightbit_data", 0, 0, true, false, false, h8300_handle_eightbit_data_attribute },
4238 { "tiny_data", 0, 0, true, false, false, h8300_handle_tiny_data_attribute },
4239 { NULL, 0, 0, false, false, false, NULL }
4240};
f5b65a56 4241
15dc331e 4242
91d231cb
JM
4243/* Handle an attribute requiring a FUNCTION_DECL; arguments as in
4244 struct attribute_spec.handler. */
4245static tree
cb713a8d
KH
4246h8300_handle_fndecl_attribute (tree *node, tree name,
4247 tree args ATTRIBUTE_UNUSED,
4248 int flags ATTRIBUTE_UNUSED,
4249 bool *no_add_attrs)
91d231cb
JM
4250{
4251 if (TREE_CODE (*node) != FUNCTION_DECL)
4252 {
4253 warning ("`%s' attribute only applies to functions",
4254 IDENTIFIER_POINTER (name));
4255 *no_add_attrs = true;
4256 }
4257
4258 return NULL_TREE;
4259}
4260
4261/* Handle an "eightbit_data" attribute; arguments as in
4262 struct attribute_spec.handler. */
4263static tree
cb713a8d
KH
4264h8300_handle_eightbit_data_attribute (tree *node, tree name,
4265 tree args ATTRIBUTE_UNUSED,
4266 int flags ATTRIBUTE_UNUSED,
4267 bool *no_add_attrs)
91d231cb
JM
4268{
4269 tree decl = *node;
4270
4271 if (TREE_STATIC (decl) || DECL_EXTERNAL (decl))
15dc331e 4272 {
64378c91 4273 DECL_SECTION_NAME (decl) = build_string (7, ".eight");
91d231cb
JM
4274 }
4275 else
4276 {
4277 warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
4278 *no_add_attrs = true;
887a8bd9
JL
4279 }
4280
91d231cb
JM
4281 return NULL_TREE;
4282}
4283
4284/* Handle an "tiny_data" attribute; arguments as in
4285 struct attribute_spec.handler. */
4286static tree
cb713a8d
KH
4287h8300_handle_tiny_data_attribute (tree *node, tree name,
4288 tree args ATTRIBUTE_UNUSED,
4289 int flags ATTRIBUTE_UNUSED,
4290 bool *no_add_attrs)
91d231cb
JM
4291{
4292 tree decl = *node;
4293
4294 if (TREE_STATIC (decl) || DECL_EXTERNAL (decl))
887a8bd9 4295 {
64378c91 4296 DECL_SECTION_NAME (decl) = build_string (6, ".tiny");
91d231cb
JM
4297 }
4298 else
4299 {
4300 warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
4301 *no_add_attrs = true;
15dc331e 4302 }
07e4d94e 4303
91d231cb 4304 return NULL_TREE;
f5b65a56
JL
4305}
4306
dc66a1c4 4307/* Mark function vectors, and various small data objects. */
fb49053f
RH
4308
4309static void
cb713a8d 4310h8300_encode_section_info (tree decl, rtx rtl, int first)
fb49053f 4311{
dc66a1c4
RH
4312 int extra_flags = 0;
4313
c6a2438a 4314 default_encode_section_info (decl, rtl, first);
dc66a1c4 4315
fb49053f
RH
4316 if (TREE_CODE (decl) == FUNCTION_DECL
4317 && h8300_funcvec_function_p (decl))
dc66a1c4 4318 extra_flags = SYMBOL_FLAG_FUNCVEC_FUNCTION;
fb49053f
RH
4319 else if (TREE_CODE (decl) == VAR_DECL
4320 && (TREE_STATIC (decl) || DECL_EXTERNAL (decl)))
4321 {
4322 if (h8300_eightbit_data_p (decl))
dc66a1c4 4323 extra_flags = SYMBOL_FLAG_EIGHTBIT_DATA;
fb49053f 4324 else if (first && h8300_tiny_data_p (decl))
dc66a1c4 4325 extra_flags = SYMBOL_FLAG_TINY_DATA;
fb49053f 4326 }
772c5265 4327
dc66a1c4 4328 if (extra_flags)
c6a2438a 4329 SYMBOL_REF_FLAGS (XEXP (rtl, 0)) |= extra_flags;
772c5265
RH
4330}
4331
441d04c6 4332const char *
cb713a8d 4333output_simode_bld (int bild, rtx operands[])
bd93f126 4334{
6be580c7
KH
4335 if (TARGET_H8300)
4336 {
4337 /* Clear the destination register. */
4338 output_asm_insn ("sub.w\t%e0,%e0\n\tsub.w\t%f0,%f0", operands);
4339
4340 /* Now output the bit load or bit inverse load, and store it in
4341 the destination. */
4342 if (bild)
4343 output_asm_insn ("bild\t%Z2,%Y1", operands);
4344 else
4345 output_asm_insn ("bld\t%Z2,%Y1", operands);
bd93f126 4346
6be580c7
KH
4347 output_asm_insn ("bst\t#0,%w0", operands);
4348 }
bd93f126 4349 else
6be580c7 4350 {
0eb933a0
KH
4351 /* Determine if we can clear the destination first. */
4352 int clear_first = (REG_P (operands[0]) && REG_P (operands[1])
4353 && REGNO (operands[0]) != REGNO (operands[1]));
4354
4355 if (clear_first)
4356 output_asm_insn ("sub.l\t%S0,%S0", operands);
4357
6be580c7
KH
4358 /* Output the bit load or bit inverse load. */
4359 if (bild)
4360 output_asm_insn ("bild\t%Z2,%Y1", operands);
4361 else
4362 output_asm_insn ("bld\t%Z2,%Y1", operands);
4363
0eb933a0
KH
4364 if (!clear_first)
4365 output_asm_insn ("xor.l\t%S0,%S0", operands);
4366
4367 /* Perform the bit store. */
802a9907 4368 output_asm_insn ("rotxl.l\t%S0", operands);
6be580c7 4369 }
bd93f126
JL
4370
4371 /* All done. */
4372 return "";
4373}
e6219736 4374
ede75ee8 4375#ifndef OBJECT_FORMAT_ELF
7c262518 4376static void
cb713a8d 4377h8300_asm_named_section (const char *name, unsigned int flags ATTRIBUTE_UNUSED)
7c262518
RH
4378{
4379 /* ??? Perhaps we should be using default_coff_asm_named_section. */
4380 fprintf (asm_out_file, "\t.section %s\n", name);
4381}
ede75ee8 4382#endif /* ! OBJECT_FORMAT_ELF */
803d56f5 4383
7c143ed2
KH
4384/* Nonzero if X is a constant address suitable as an 8-bit absolute,
4385 which is a special case of the 'R' operand. */
4386
803d56f5 4387int
cb713a8d 4388h8300_eightbit_constant_address_p (rtx x)
803d56f5 4389{
3f7211f1 4390 /* The ranges of the 8-bit area. */
d2d199a3
KH
4391 const unsigned HOST_WIDE_INT n1 = trunc_int_for_mode (0xff00, HImode);
4392 const unsigned HOST_WIDE_INT n2 = trunc_int_for_mode (0xffff, HImode);
803d56f5
KH
4393 const unsigned HOST_WIDE_INT h1 = trunc_int_for_mode (0x00ffff00, SImode);
4394 const unsigned HOST_WIDE_INT h2 = trunc_int_for_mode (0x00ffffff, SImode);
4395 const unsigned HOST_WIDE_INT s1 = trunc_int_for_mode (0xffffff00, SImode);
4396 const unsigned HOST_WIDE_INT s2 = trunc_int_for_mode (0xffffffff, SImode);
4397
4398 unsigned HOST_WIDE_INT addr;
4399
9675a91e 4400 /* We accept symbols declared with eightbit_data. */
dc66a1c4
RH
4401 if (GET_CODE (x) == SYMBOL_REF)
4402 return (SYMBOL_REF_FLAGS (x) & SYMBOL_FLAG_EIGHTBIT_DATA) != 0;
9675a91e 4403
803d56f5
KH
4404 if (GET_CODE (x) != CONST_INT)
4405 return 0;
4406
4407 addr = INTVAL (x);
4408
4409 return (0
39ba95b5 4410 || ((TARGET_H8300 || TARGET_NORMAL_MODE) && IN_RANGE (addr, n1, n2))
803d56f5
KH
4411 || (TARGET_H8300H && IN_RANGE (addr, h1, h2))
4412 || (TARGET_H8300S && IN_RANGE (addr, s1, s2)));
4413}
4414
7c143ed2
KH
4415/* Nonzero if X is a constant address suitable as an 16-bit absolute
4416 on H8/300H and H8S. */
4417
803d56f5 4418int
cb713a8d 4419h8300_tiny_constant_address_p (rtx x)
803d56f5 4420{
3f7211f1 4421 /* The ranges of the 16-bit area. */
803d56f5
KH
4422 const unsigned HOST_WIDE_INT h1 = trunc_int_for_mode (0x00000000, SImode);
4423 const unsigned HOST_WIDE_INT h2 = trunc_int_for_mode (0x00007fff, SImode);
4424 const unsigned HOST_WIDE_INT h3 = trunc_int_for_mode (0x00ff8000, SImode);
4425 const unsigned HOST_WIDE_INT h4 = trunc_int_for_mode (0x00ffffff, SImode);
4426 const unsigned HOST_WIDE_INT s1 = trunc_int_for_mode (0x00000000, SImode);
4427 const unsigned HOST_WIDE_INT s2 = trunc_int_for_mode (0x00007fff, SImode);
4428 const unsigned HOST_WIDE_INT s3 = trunc_int_for_mode (0xffff8000, SImode);
4429 const unsigned HOST_WIDE_INT s4 = trunc_int_for_mode (0xffffffff, SImode);
4430
4431 unsigned HOST_WIDE_INT addr;
4432
56b8e164 4433 /* We accept symbols declared with tiny_data. */
dc66a1c4
RH
4434 if (GET_CODE (x) == SYMBOL_REF)
4435 return (SYMBOL_REF_FLAGS (x) & SYMBOL_FLAG_TINY_DATA) != 0;
56b8e164 4436
803d56f5
KH
4437 if (GET_CODE (x) != CONST_INT)
4438 return 0;
4439
4440 addr = INTVAL (x);
4441
4442 return (0
6d7d3112
DD
4443 || TARGET_NORMAL_MODE
4444 || (TARGET_H8300H
94aec8dd 4445 && (IN_RANGE (addr, h1, h2) || IN_RANGE (addr, h3, h4)))
6d7d3112 4446 || (TARGET_H8300S
94aec8dd 4447 && (IN_RANGE (addr, s1, s2) || IN_RANGE (addr, s3, s4))));
803d56f5 4448}
9b98dc74
KH
4449
4450int
cb713a8d 4451byte_accesses_mergeable_p (rtx addr1, rtx addr2)
9b98dc74
KH
4452{
4453 HOST_WIDE_INT offset1, offset2;
4454 rtx reg1, reg2;
4455
4456 if (REG_P (addr1))
4457 {
4458 reg1 = addr1;
4459 offset1 = 0;
4460 }
4461 else if (GET_CODE (addr1) == PLUS
4462 && REG_P (XEXP (addr1, 0))
4463 && GET_CODE (XEXP (addr1, 1)) == CONST_INT)
4464 {
4465 reg1 = XEXP (addr1, 0);
4466 offset1 = INTVAL (XEXP (addr1, 1));
4467 }
4468 else
4469 return 0;
4470
4471 if (REG_P (addr2))
4472 {
4473 reg2 = addr2;
4474 offset2 = 0;
4475 }
4476 else if (GET_CODE (addr2) == PLUS
4477 && REG_P (XEXP (addr2, 0))
4478 && GET_CODE (XEXP (addr2, 1)) == CONST_INT)
4479 {
4480 reg2 = XEXP (addr2, 0);
4481 offset2 = INTVAL (XEXP (addr2, 1));
4482 }
4483 else
4484 return 0;
4485
4486 if (((reg1 == stack_pointer_rtx && reg2 == stack_pointer_rtx)
4487 || (reg1 == frame_pointer_rtx && reg2 == frame_pointer_rtx))
4488 && offset1 % 2 == 0
4489 && offset1 + 1 == offset2)
4490 return 1;
4491
4492 return 0;
4493}
02529902
KH
4494
4495/* Return nonzero if we have the same comparison insn as I3 two insns
19cff4db 4496 before I3. I3 is assumed to be a comparison insn. */
02529902
KH
4497
4498int
4499same_cmp_preceding_p (rtx i3)
4500{
4501 rtx i1, i2;
4502
4503 /* Make sure we have a sequence of three insns. */
4504 i2 = prev_nonnote_insn (i3);
4505 if (i2 == NULL_RTX)
4506 return 0;
4507 i1 = prev_nonnote_insn (i2);
4508 if (i1 == NULL_RTX)
4509 return 0;
4510
4511 return (INSN_P (i1) && rtx_equal_p (PATTERN (i1), PATTERN (i3))
4512 && any_condjump_p (i2) && onlyjump_p (i2));
4513}
c87ec0ba 4514
c06d5c85
KH
4515/* Return nonzero if we have the same comparison insn as I1 two insns
4516 after I1. I1 is assumed to be a comparison insn. */
4517
4518int
4519same_cmp_following_p (rtx i1)
4520{
4521 rtx i2, i3;
4522
4523 /* Make sure we have a sequence of three insns. */
4524 i2 = next_nonnote_insn (i1);
4525 if (i2 == NULL_RTX)
4526 return 0;
4527 i3 = next_nonnote_insn (i2);
4528 if (i3 == NULL_RTX)
4529 return 0;
4530
4531 return (INSN_P (i3) && rtx_equal_p (PATTERN (i1), PATTERN (i3))
4532 && any_condjump_p (i2) && onlyjump_p (i2));
4533}
4534
c87ec0ba
NY
4535/* Return nonzero if register OLD_REG can be renamed to register NEW_REG. */
4536
4537int
4538h8300_hard_regno_rename_ok (unsigned int old_reg ATTRIBUTE_UNUSED,
4539 unsigned int new_reg)
4540{
4541 /* Interrupt functions can only use registers that have already been
4542 saved by the prologue, even if they would normally be
4543 call-clobbered. */
4544
4545 if (h8300_current_function_interrupt_function_p ()
4546 && !regs_ever_live[new_reg])
4547 return 0;
4548
4549 return 1;
4550}
6e014ef3 4551\f
c15c90bb
ZW
4552/* Perform target dependent optabs initialization. */
4553static void
4554h8300_init_libfuncs (void)
4555{
4556 set_optab_libfunc (smul_optab, HImode, "__mulhi3");
4557 set_optab_libfunc (sdiv_optab, HImode, "__divhi3");
4558 set_optab_libfunc (udiv_optab, HImode, "__udivhi3");
4559 set_optab_libfunc (smod_optab, HImode, "__modhi3");
4560 set_optab_libfunc (umod_optab, HImode, "__umodhi3");
4561}
4562\f
6e014ef3
KH
4563/* Initialize the GCC target structure. */
4564#undef TARGET_ATTRIBUTE_TABLE
4565#define TARGET_ATTRIBUTE_TABLE h8300_attribute_table
4566
4567#undef TARGET_ASM_ALIGNED_HI_OP
4568#define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
4569
1bc7c5b6
ZW
4570#undef TARGET_ASM_FILE_START
4571#define TARGET_ASM_FILE_START h8300_file_start
4572#undef TARGET_ASM_FILE_START_FILE_DIRECTIVE
4573#define TARGET_ASM_FILE_START_FILE_DIRECTIVE true
4574
6e014ef3
KH
4575#undef TARGET_ASM_FILE_END
4576#define TARGET_ASM_FILE_END h8300_file_end
4577
4578#undef TARGET_ENCODE_SECTION_INFO
4579#define TARGET_ENCODE_SECTION_INFO h8300_encode_section_info
4580
4581#undef TARGET_INSERT_ATTRIBUTES
4582#define TARGET_INSERT_ATTRIBUTES h8300_insert_attributes
4583
4584#undef TARGET_RTX_COSTS
4585#define TARGET_RTX_COSTS h8300_rtx_costs
4586
c15c90bb
ZW
4587#undef TARGET_INIT_LIBFUNCS
4588#define TARGET_INIT_LIBFUNCS h8300_init_libfuncs
4589
6e014ef3 4590struct gcc_target targetm = TARGET_INITIALIZER;