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