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