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