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