]> gcc.gnu.org Git - gcc.git/blame - gcc/config/h8300/h8300.c
* config/h8300/h8300.c (h8300_init_once): Fix formatting.
[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 {
8682223f 304 /* For this we treat the H8/300H and H8/S 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{
7b3d4613
KH
395 /* On the H8/300H and H8/S, for sizes <= 8 bytes, it is as good or
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{
434 return (size + STACK_BOUNDARY / 8 - 1) & -STACK_BOUNDARY / 8;
435}
436
437/* Compute which registers to push/pop.
438 Return a bit vector of registers. */
439
440static unsigned int
441compute_saved_regs ()
442{
443 unsigned int saved_regs = 0;
444 int regno;
445
446 /* Construct a bit vector of registers to be pushed/popped. */
447 for (regno = 0; regno <= 6; regno++)
448 {
449 if (WORD_REG_USED (regno))
450 saved_regs |= 1 << regno;
451 }
452
453 /* Don't push/pop the frame pointer as it is treated separately. */
454 if (frame_pointer_needed)
455 saved_regs &= ~(1 << FRAME_POINTER_REGNUM);
456
457 return saved_regs;
458}
459
460/* Output assembly language code to push register RN. */
461
462static void
463push (file, rn)
464 FILE *file;
465 int rn;
466{
467 fprintf (file, "\t%s\t%s\n", h8_push_op, h8_reg_names[rn]);
468}
469
470/* Output assembly language code to pop register RN. */
471
472static void
473pop (file, rn)
474 FILE *file;
475 int rn;
476{
477 fprintf (file, "\t%s\t%s\n", h8_pop_op, h8_reg_names[rn]);
478}
07aae5c2 479
f0b6f9a6 480/* This is what the stack looks like after the prolog of
07aae5c2
SC
481 a function with a frame has been set up:
482
48837e29
DE
483 <args>
484 PC
485 FP <- fp
486 <locals>
8bd06267 487 <saved registers> <- sp
07aae5c2
SC
488
489 This is what the stack looks like after the prolog of
490 a function which doesn't have a frame:
491
48837e29
DE
492 <args>
493 PC
494 <locals>
8bd06267 495 <saved registers> <- sp
07aae5c2
SC
496*/
497
8682223f
KH
498/* Output assembly language code for the function prologue. */
499
08c148a8
NB
500static void
501h8300_output_function_prologue (file, size)
07aae5c2 502 FILE *file;
08c148a8 503 HOST_WIDE_INT size;
07aae5c2 504{
8682223f 505 int fsize = round_frame_size (size);
07aae5c2 506 int idx;
8682223f 507 int saved_regs;
cda4bd43 508 int n_regs;
07aae5c2 509
dd07092e
JL
510 /* Note a function with the interrupt attribute and set interrupt_handler
511 accordingly. */
f5b65a56
JL
512 if (h8300_interrupt_function_p (current_function_decl))
513 interrupt_handler = 1;
514
fabe72bb
JL
515 /* If the current function has the OS_Task attribute set, then
516 we have a naked prologue. */
517 if (h8300_os_task_function_p (current_function_decl))
518 {
519 fprintf (file, ";OS_Task prologue\n");
520 os_task = 1;
521 return;
522 }
523
524 if (h8300_monitor_function_p (current_function_decl))
525 {
526 /* My understanding of monitor functions is they act just
527 like interrupt functions, except the prologue must
528 mask interrupts. */
529 fprintf (file, ";monitor prologue\n");
530 interrupt_handler = 1;
531 monitor = 1;
ea3a7ffa
JL
532 if (TARGET_H8300)
533 {
534 fprintf (file, "\tsubs\t#2,sp\n");
8682223f 535 push (file, 0);
ea3a7ffa 536 fprintf (file, "\tstc\tccr,r0l\n");
46d00fef
KH
537 fprintf (file, "\tmov.b\tr0l,@(2,sp)\n");
538 pop (file, 0);
ea3a7ffa 539 fprintf (file, "\torc\t#128,ccr\n");
46d00fef
KH
540 }
541 else if (TARGET_H8300H)
542 {
543 push (file, 0);
544 fprintf (file, "\tstc\tccr,r0l\n");
ea3a7ffa 545 fprintf (file, "\tmov.b\tr0l,@(4,sp)\n");
46d00fef
KH
546 pop (file, 0);
547 fprintf (file, "\torc\t#128,ccr\n");
ea3a7ffa 548 }
46d00fef 549 else if (TARGET_H8300S)
ea3a7ffa 550 {
46d00fef 551 fprintf (file, "\tstc\texr,@-sp\n");
8682223f 552 push (file, 0);
ea3a7ffa 553 fprintf (file, "\tstc\tccr,r0l\n");
46d00fef
KH
554 fprintf (file, "\tmov.b\tr0l,@(6,sp)\n");
555 pop (file, 0);
ea3a7ffa 556 fprintf (file, "\torc\t#128,ccr\n");
ea3a7ffa 557 }
46d00fef
KH
558 else
559 abort ();
fabe72bb
JL
560 }
561
48837e29
DE
562 if (frame_pointer_needed)
563 {
07e4d94e 564 /* Push fp. */
8682223f 565 push (file, FRAME_POINTER_REGNUM);
48837e29
DE
566 fprintf (file, "\t%s\t%s,%s\n", h8_mov_op,
567 h8_reg_names[STACK_POINTER_REGNUM],
568 h8_reg_names[FRAME_POINTER_REGNUM]);
a1616dd9 569 }
48837e29 570
07e4d94e 571 /* Leave room for locals. */
a1616dd9 572 dosize (file, "sub", fsize);
07aae5c2 573
8682223f
KH
574 /* Push the rest of the registers in ascending order. */
575 saved_regs = compute_saved_regs ();
cda4bd43
KH
576 for (idx = 0; idx < FIRST_PSEUDO_REGISTER; idx += n_regs)
577 {
8682223f 578 int regno = idx;
cda4bd43
KH
579
580 n_regs = 1;
8682223f 581 if (saved_regs & (1 << regno))
a1616dd9
JL
582 {
583 if (TARGET_H8300S)
584 {
cda4bd43
KH
585 /* See how many registers we can push at the same time. */
586 if ((regno == 0 || regno == 4)
8682223f 587 && ((saved_regs >> regno) & 0x0f) == 0x0f)
cda4bd43
KH
588 n_regs = 4;
589
590 else if ((regno == 0 || regno == 4)
8682223f 591 && ((saved_regs >> regno) & 0x07) == 0x07)
cda4bd43
KH
592 n_regs = 3;
593
594 else if ((regno == 0 || regno == 2 || regno == 4 || regno == 6)
8682223f 595 && ((saved_regs >> regno) & 0x03) == 0x03)
cda4bd43 596 n_regs = 2;
a1616dd9 597 }
cda4bd43
KH
598
599 if (n_regs == 1)
8682223f 600 push (file, regno);
cda4bd43
KH
601 else
602 fprintf (file, "\tstm.l\t%s-%s,@-sp\n",
603 h8_reg_names[regno],
604 h8_reg_names[regno + (n_regs - 1)]);
07aae5c2
SC
605 }
606 }
607}
608
609/* Output assembly language code for the function epilogue. */
610
08c148a8
NB
611static void
612h8300_output_function_epilogue (file, size)
07aae5c2 613 FILE *file;
08c148a8 614 HOST_WIDE_INT size;
07aae5c2 615{
8682223f 616 int fsize = round_frame_size (size);
07aae5c2
SC
617 int idx;
618 rtx insn = get_last_insn ();
8682223f 619 int saved_regs;
cda4bd43 620 int n_regs;
07aae5c2 621
fabe72bb
JL
622 if (os_task)
623 {
624 /* OS_Task epilogues are nearly naked -- they just have an
625 rts instruction. */
626 fprintf (file, ";OS_task epilogue\n");
627 fprintf (file, "\trts\n");
628 goto out;
629 }
630
07e4d94e 631 /* Monitor epilogues are the same as interrupt function epilogues.
fabe72bb
JL
632 Just make a note that we're in an monitor epilogue. */
633 if (monitor)
07e4d94e 634 fprintf (file, ";monitor epilogue\n");
fabe72bb 635
07aae5c2
SC
636 /* If the last insn was a BARRIER, we don't have to write any code. */
637 if (GET_CODE (insn) == NOTE)
638 insn = prev_nonnote_insn (insn);
639 if (insn && GET_CODE (insn) == BARRIER)
f40a8c03 640 goto out;
07aae5c2 641
8682223f
KH
642 /* Pop the saved registers in descending order. */
643 saved_regs = compute_saved_regs ();
cda4bd43
KH
644 for (idx = 0; idx < FIRST_PSEUDO_REGISTER; idx += n_regs)
645 {
8682223f 646 int regno = (FIRST_PSEUDO_REGISTER - 1) - idx;
cda4bd43
KH
647
648 n_regs = 1;
8682223f 649 if (saved_regs & (1 << regno))
07aae5c2 650 {
a1616dd9
JL
651 if (TARGET_H8300S)
652 {
cda4bd43
KH
653 /* See how many registers we can pop at the same time. */
654 if ((regno == 7 || regno == 3)
8682223f 655 && ((saved_regs >> (regno - 3)) & 0x0f) == 0x0f)
cda4bd43
KH
656 n_regs = 4;
657
658 else if ((regno == 6 || regno == 2)
8682223f 659 && ((saved_regs >> (regno - 2)) & 0x07) == 0x07)
cda4bd43
KH
660 n_regs = 3;
661
662 else if ((regno == 7 || regno == 5 || regno == 3 || regno == 1)
8682223f 663 && ((saved_regs >> (regno - 1)) & 0x03) == 0x03)
cda4bd43 664 n_regs = 2;
a1616dd9 665 }
cda4bd43
KH
666
667 if (n_regs == 1)
8682223f 668 pop (file, regno);
cda4bd43
KH
669 else
670 fprintf (file, "\tldm.l\t@sp+,%s-%s\n",
671 h8_reg_names[regno - (n_regs - 1)],
672 h8_reg_names[regno]);
07aae5c2 673 }
07aae5c2 674 }
48837e29 675
07e4d94e 676 /* Deallocate locals. */
a1616dd9
JL
677 dosize (file, "add", fsize);
678
07e4d94e 679 /* Pop frame pointer if we had one. */
a1616dd9 680 if (frame_pointer_needed)
8682223f 681 pop (file, FRAME_POINTER_REGNUM);
a1616dd9 682
dd07092e
JL
683 if (interrupt_handler)
684 fprintf (file, "\trte\n");
07aae5c2 685 else
dd07092e 686 fprintf (file, "\trts\n");
07aae5c2 687
07e4d94e 688 out:
f5b65a56 689 interrupt_handler = 0;
fabe72bb
JL
690 os_task = 0;
691 monitor = 0;
07aae5c2 692 pragma_saveall = 0;
48837e29
DE
693}
694
695/* Output assembly code for the start of the file. */
696
441d04c6 697void
48837e29
DE
698asm_file_start (file)
699 FILE *file;
700{
701 fprintf (file, ";\tGCC For the Hitachi H8/300\n");
702 fprintf (file, ";\tBy Hitachi America Ltd and Cygnus Support\n");
8bd06267 703
ff970081 704 if (optimize_size)
f8cb5851 705 fprintf (file, "; -Os\n");
ff970081 706 else if (optimize)
48837e29
DE
707 fprintf (file, "; -O%d\n", optimize);
708 if (TARGET_H8300H)
709 fprintf (file, "\n\t.h8300h\n");
a1616dd9
JL
710 else if (TARGET_H8300S)
711 fprintf (file, "\n\t.h8300s\n");
48837e29
DE
712 else
713 fprintf (file, "\n\n");
714 output_file_directive (file, main_input_filename);
715}
716
717/* Output assembly language code for the end of file. */
718
719void
720asm_file_end (file)
721 FILE *file;
722{
723 fprintf (file, "\t.end\n");
07aae5c2
SC
724}
725\f
68560db3 726/* Return true if OP is a valid source operand for an integer move
07aae5c2 727 instruction. */
48837e29 728
07aae5c2
SC
729int
730general_operand_src (op, mode)
731 rtx op;
732 enum machine_mode mode;
733{
48837e29
DE
734 if (GET_CODE (op) == MEM && GET_CODE (XEXP (op, 0)) == POST_INC)
735 return 1;
07aae5c2
SC
736 return general_operand (op, mode);
737}
738
739/* Return true if OP is a valid destination operand for an integer move
5660465a 740 instruction. */
48837e29 741
07aae5c2
SC
742int
743general_operand_dst (op, mode)
744 rtx op;
745 enum machine_mode mode;
746{
48837e29
DE
747 if (GET_CODE (op) == MEM && GET_CODE (XEXP (op, 0)) == PRE_DEC)
748 return 1;
07aae5c2
SC
749 return general_operand (op, mode);
750}
48837e29 751
4d4d89e2
KH
752/* Return true if OP is a constant that contains only one 1 in its
753 binary representation. */
48837e29
DE
754
755int
4d4d89e2 756single_one_operand (operand, mode)
48837e29 757 rtx operand;
441d04c6 758 enum machine_mode mode ATTRIBUTE_UNUSED;
48837e29 759{
4d4d89e2
KH
760 if (GET_CODE (operand) == CONST_INT)
761 {
762 /* We really need to do this masking because 0x80 in QImode is
763 represented as -128 for example. */
764 unsigned HOST_WIDE_INT mask =
765 ((unsigned HOST_WIDE_INT) 1 << GET_MODE_BITSIZE (mode)) - 1;
766 unsigned HOST_WIDE_INT value = INTVAL (operand);
767
768 if (exact_log2 (value & mask) >= 0)
769 return 1;
770 }
771
772 return 0;
773}
774
775/* Return true if OP is a constant that contains only one 0 in its
776 binary representation. */
777
778int
779single_zero_operand (operand, mode)
780 rtx operand;
781 enum machine_mode mode ATTRIBUTE_UNUSED;
782{
783 if (GET_CODE (operand) == CONST_INT)
784 {
785 /* We really need to do this masking because 0x80 in QImode is
786 represented as -128 for example. */
787 unsigned HOST_WIDE_INT mask =
788 ((unsigned HOST_WIDE_INT) 1 << GET_MODE_BITSIZE (mode)) - 1;
789 unsigned HOST_WIDE_INT value = INTVAL (operand);
790
791 if (exact_log2 (~value & mask) >= 0)
792 return 1;
793 }
794
795 return 0;
48837e29
DE
796}
797
48837e29
DE
798/* Return true if OP is a valid call operand. */
799
800int
801call_insn_operand (op, mode)
802 rtx op;
441d04c6 803 enum machine_mode mode ATTRIBUTE_UNUSED;
48837e29
DE
804{
805 if (GET_CODE (op) == MEM)
806 {
807 rtx inside = XEXP (op, 0);
808 if (register_operand (inside, Pmode))
809 return 1;
810 if (CONSTANT_ADDRESS_P (inside))
811 return 1;
812 }
813 return 0;
814}
815
22c9a795 816/* Return 1 if an addition/subtraction of a constant integer can be
997e5af8 817 transformed into two consecutive adds/subs that are faster than the
22c9a795 818 straightforward way. Otherwise, return 0. */
997e5af8 819
3b7d443c 820int
009ac3d3 821two_insn_adds_subs_operand (op, mode)
3b7d443c 822 rtx op;
997e5af8 823 enum machine_mode mode;
3b7d443c
JL
824{
825 if (GET_CODE (op) == CONST_INT)
826 {
009ac3d3 827 HOST_WIDE_INT value = INTVAL (op);
3b7d443c 828
997e5af8
KH
829 /* Force VALUE to be positive so that we do not have to consider
830 the negative case. */
831 if (value < 0)
832 value = -value;
009ac3d3
RH
833 if (TARGET_H8300H || TARGET_H8300S)
834 {
997e5af8
KH
835 /* A constant addition/subtraction takes 2 states in QImode,
836 4 states in HImode, and 6 states in SImode. Thus, the
837 only case we can win is when SImode is used, in which
c59ff527 838 case, two adds/subs are used, taking 4 states. */
997e5af8
KH
839 if (mode == SImode
840 && (value == 2 + 1
841 || value == 4 + 1
842 || value == 4 + 2
843 || value == 4 + 4))
22c9a795 844 return 1;
009ac3d3
RH
845 }
846 else
847 {
ae19f5ef
KH
848 /* We do not profit directly by splitting addition or
849 subtraction of 3 and 4. However, since these are
850 implemented as a sequence of adds or subs, they do not
851 clobber (cc0) unlike a sequence of add.b and add.x. */
852 if (mode == HImode
997e5af8
KH
853 && (value == 2 + 1
854 || value == 2 + 2))
009ac3d3
RH
855 return 1;
856 }
857 }
e6219736 858
e6219736
JL
859 return 0;
860}
861
009ac3d3
RH
862/* Split an add of a small constant into two adds/subs insns. */
863
864void
865split_adds_subs (mode, operands)
866 enum machine_mode mode;
3b7d443c
JL
867 rtx *operands;
868{
009ac3d3
RH
869 HOST_WIDE_INT val = INTVAL (operands[1]);
870 rtx reg = operands[0];
9492393e
KH
871 HOST_WIDE_INT sign = 1;
872 HOST_WIDE_INT amount;
3b7d443c 873
9492393e
KH
874 /* Force VAL to be positive so that we do not have to consider the
875 sign. */
876 if (val < 0)
3b7d443c 877 {
9492393e
KH
878 val = -val;
879 sign = -1;
880 }
3b7d443c 881
9492393e
KH
882 /* Try different amounts in descending order. */
883 for (amount = (TARGET_H8300H || TARGET_H8300S) ? 4 : 2;
884 amount > 0;
885 amount /= 2)
886 {
1a63219b 887 for (; val >= amount; val -= amount)
009ac3d3 888 {
9492393e 889 rtx tmp = gen_rtx_PLUS (mode, reg, GEN_INT (sign * amount));
009ac3d3 890 emit_insn (gen_rtx_SET (VOIDmode, reg, tmp));
009ac3d3 891 }
3b7d443c
JL
892 }
893
9492393e 894 return;
3b7d443c
JL
895}
896
f5b65a56
JL
897/* Return true if OP is a valid call operand, and OP represents
898 an operand for a small call (4 bytes instead of 6 bytes). */
899
900int
901small_call_insn_operand (op, mode)
902 rtx op;
441d04c6 903 enum machine_mode mode ATTRIBUTE_UNUSED;
f5b65a56
JL
904{
905 if (GET_CODE (op) == MEM)
906 {
907 rtx inside = XEXP (op, 0);
908
909 /* Register indirect is a small call. */
910 if (register_operand (inside, Pmode))
911 return 1;
912
913 /* A call through the function vector is a small
914 call too. */
915 if (GET_CODE (inside) == SYMBOL_REF
916 && SYMBOL_REF_FLAG (inside))
917 return 1;
918 }
919 /* Otherwise it's a large call. */
920 return 0;
921}
922
48837e29
DE
923/* Return true if OP is a valid jump operand. */
924
925int
926jump_address_operand (op, mode)
927 rtx op;
928 enum machine_mode mode;
929{
930 if (GET_CODE (op) == REG)
931 return mode == Pmode;
932
933 if (GET_CODE (op) == MEM)
934 {
935 rtx inside = XEXP (op, 0);
936 if (register_operand (inside, Pmode))
937 return 1;
938 if (CONSTANT_ADDRESS_P (inside))
939 return 1;
940 }
941 return 0;
942}
943
944/* Recognize valid operands for bitfield instructions. */
945
946extern int rtx_equal_function_value_matters;
947
948int
949bit_operand (op, mode)
950 rtx op;
951 enum machine_mode mode;
952{
953 /* We can except any general operand, expept that MEM operands must
954 be limited to those that use addresses valid for the 'U' constraint. */
955 if (!general_operand (op, mode))
956 return 0;
957
958 /* Accept any mem during RTL generation. Otherwise, the code that does
959 insv and extzv will think that we can not handle memory. However,
960 to avoid reload problems, we only accept 'U' MEM operands after RTL
961 generation. This means that any named pattern which uses this predicate
962 must force its operands to match 'U' before emitting RTL. */
963
964 if (GET_CODE (op) == REG)
965 return 1;
966 if (GET_CODE (op) == SUBREG)
967 return 1;
968 if (!rtx_equal_function_value_matters)
07e4d94e
KH
969 /* We're building rtl. */
970 return GET_CODE (op) == MEM;
48837e29 971 else
07e4d94e
KH
972 return (GET_CODE (op) == MEM
973 && EXTRA_CONSTRAINT (op, 'U'));
48837e29
DE
974}
975
887a8bd9
JL
976int
977bit_memory_operand (op, mode)
978 rtx op;
441d04c6 979 enum machine_mode mode ATTRIBUTE_UNUSED;
887a8bd9
JL
980{
981 return (GET_CODE (op) == MEM
982 && EXTRA_CONSTRAINT (op, 'U'));
983}
984
07aae5c2 985/* Handle machine specific pragmas for compatibility with existing
48837e29 986 compilers for the H8/300.
07aae5c2
SC
987
988 pragma saveall generates prolog/epilog code which saves and
989 restores all the registers on function entry.
48837e29 990
07aae5c2
SC
991 pragma interrupt saves and restores all registers, and exits with
992 an rte instruction rather than an rts. A pointer to a function
993 with this attribute may be safely used in an interrupt vector. */
48837e29 994
8b97c5f8
ZW
995void
996h8300_pr_interrupt (pfile)
997 cpp_reader *pfile ATTRIBUTE_UNUSED;
07aae5c2 998{
8b97c5f8
ZW
999 interrupt_handler = 1;
1000}
05a81fe5 1001
8b97c5f8
ZW
1002void
1003h8300_pr_saveall (pfile)
1004 cpp_reader *pfile ATTRIBUTE_UNUSED;
1005{
1006 pragma_saveall = 1;
07aae5c2 1007}
8b97c5f8 1008
64bead4c
KH
1009/* If the next function argument with MODE and TYPE is to be passed in
1010 a register, return a reg RTX for the hard register in which to pass
1011 the argument. CUM represents the state after the last argument.
1012 If the argument is to be pushed, NULL_RTX is returned. */
48837e29 1013
07aae5c2
SC
1014rtx
1015function_arg (cum, mode, type, named)
1016 CUMULATIVE_ARGS *cum;
1017 enum machine_mode mode;
1018 tree type;
1019 int named;
1020{
0ea6f6a0
KH
1021 static const char *const hand_list[] = {
1022 "__main",
1023 "__cmpsi2",
1024 "__divhi3",
1025 "__modhi3",
1026 "__udivhi3",
1027 "__umodhi3",
1028 "__divsi3",
1029 "__modsi3",
1030 "__udivsi3",
1031 "__umodsi3",
1032 "__mulhi3",
1033 "__mulsi3",
1034 "__reg_memcpy",
1035 "__reg_memset",
1036 "__ucmpsi2",
1037 0,
1038 };
1039
7192cbf1 1040 rtx result = NULL_RTX;
441d04c6 1041 const char *fname;
48837e29
DE
1042 int regpass = 0;
1043
dd07092e
JL
1044 /* Never pass unnamed arguments in registers. */
1045 if (!named)
7192cbf1 1046 return NULL_RTX;
dd07092e 1047
48837e29
DE
1048 /* Pass 3 regs worth of data in regs when user asked on the command line. */
1049 if (TARGET_QUICKCALL)
1050 regpass = 3;
1051
1052 /* If calling hand written assembler, use 4 regs of args. */
48837e29
DE
1053 if (cum->libcall)
1054 {
441d04c6 1055 const char * const *p;
48837e29
DE
1056
1057 fname = XSTR (cum->libcall, 0);
1058
1059 /* See if this libcall is one of the hand coded ones. */
48837e29
DE
1060 for (p = hand_list; *p && strcmp (*p, fname) != 0; p++)
1061 ;
07aae5c2 1062
48837e29
DE
1063 if (*p)
1064 regpass = 4;
1065 }
1066
1067 if (regpass)
1068 {
1069 int size;
1070
1071 if (mode == BLKmode)
1072 size = int_size_in_bytes (type);
1073 else
1074 size = GET_MODE_SIZE (mode);
1075
15e0e275
KH
1076 if (size + cum->nbytes <= regpass * UNITS_PER_WORD
1077 && cum->nbytes / UNITS_PER_WORD <= 3)
1078 result = gen_rtx_REG (mode, cum->nbytes / UNITS_PER_WORD);
48837e29 1079 }
07aae5c2 1080
48837e29
DE
1081 return result;
1082}
1083\f
1084/* Return the cost of the rtx R with code CODE. */
07aae5c2 1085
48837e29 1086int
037f11ef 1087const_costs (r, c, outer_code)
48837e29
DE
1088 rtx r;
1089 enum rtx_code c;
037f11ef 1090 enum rtx_code outer_code;
48837e29
DE
1091{
1092 switch (c)
07aae5c2 1093 {
48837e29
DE
1094 case CONST_INT:
1095 switch (INTVAL (r))
07aae5c2
SC
1096 {
1097 case 0:
037f11ef 1098 return 0;
48837e29 1099 case 1:
07aae5c2 1100 case 2:
48837e29
DE
1101 case -1:
1102 case -2:
037f11ef 1103 return 0 + (outer_code == SET);
5ae5999c
JL
1104 case 4:
1105 case -4:
a1616dd9 1106 if (TARGET_H8300H || TARGET_H8300S)
037f11ef 1107 return 0 + (outer_code == SET);
5ae5999c
JL
1108 else
1109 return 1;
48837e29
DE
1110 default:
1111 return 1;
07aae5c2 1112 }
48837e29
DE
1113
1114 case CONST:
1115 case LABEL_REF:
1116 case SYMBOL_REF:
1117 return 3;
1118
1119 case CONST_DOUBLE:
1120 return 20;
1121
1122 default:
1123 return 4;
07aae5c2 1124 }
07aae5c2 1125}
48837e29 1126\f
07aae5c2
SC
1127/* Documentation for the machine specific operand escapes:
1128
48837e29
DE
1129 'E' like s but negative.
1130 'F' like t but negative.
1131 'G' constant just the negative
15dc331e
JL
1132 'R' print operand as a byte:8 address if appropriate, else fall back to
1133 'X' handling.
48837e29 1134 'S' print operand as a long word
07aae5c2 1135 'T' print operand as a word
48837e29
DE
1136 'V' find the set bit, and print its number.
1137 'W' find the clear bit, and print its number.
1138 'X' print operand as a byte
07aae5c2 1139 'Y' print either l or h depending on whether last 'Z' operand < 8 or >= 8.
15dc331e 1140 If this operand isn't a register, fall back to 'R' handling.
48837e29
DE
1141 'Z' print int & 7.
1142 'b' print the bit opcode
48837e29
DE
1143 'e' first word of 32 bit value - if reg, then least reg. if mem
1144 then least. if const then most sig word
1145 'f' second word of 32 bit value - if reg, then biggest reg. if mem
1146 then +2. if const then least sig word
07aae5c2
SC
1147 'j' print operand as condition code.
1148 'k' print operand as reverse condition code.
48837e29
DE
1149 's' print as low byte of 16 bit value
1150 't' print as high byte of 16 bit value
1151 'w' print as low byte of 32 bit value
1152 'x' print as 2nd byte of 32 bit value
1153 'y' print as 3rd byte of 32 bit value
1154 'z' print as msb of 32 bit value
1155*/
07aae5c2
SC
1156
1157/* Return assembly language string which identifies a comparison type. */
1158
441d04c6 1159static const char *
07aae5c2
SC
1160cond_string (code)
1161 enum rtx_code code;
1162{
1163 switch (code)
1164 {
1165 case NE:
1166 return "ne";
1167 case EQ:
1168 return "eq";
1169 case GE:
1170 return "ge";
1171 case GT:
1172 return "gt";
1173 case LE:
1174 return "le";
1175 case LT:
1176 return "lt";
1177 case GEU:
1178 return "hs";
1179 case GTU:
1180 return "hi";
1181 case LEU:
1182 return "ls";
1183 case LTU:
1184 return "lo";
1185 default:
1186 abort ();
1187 }
1188}
1189
1190/* Print operand X using operand code CODE to assembly language output file
1191 FILE. */
1192
1193void
1194print_operand (file, x, code)
1195 FILE *file;
1196 rtx x;
1197 int code;
1198{
269c14e1 1199 /* This is used for communication between codes V,W,Z and Y. */
07aae5c2
SC
1200 static int bitint;
1201
1202 switch (code)
1203 {
48837e29
DE
1204 case 'E':
1205 switch (GET_CODE (x))
1206 {
1207 case REG:
1208 fprintf (file, "%sl", names_big[REGNO (x)]);
1209 break;
1210 case CONST_INT:
1211 fprintf (file, "#%d", (-INTVAL (x)) & 0xff);
1212 break;
1213 default:
1214 abort ();
1215 }
1216 break;
1217 case 'F':
1218 switch (GET_CODE (x))
1219 {
1220 case REG:
1221 fprintf (file, "%sh", names_big[REGNO (x)]);
1222 break;
1223 case CONST_INT:
1224 fprintf (file, "#%d", ((-INTVAL (x)) & 0xff00) >> 8);
1225 break;
1226 default:
1227 abort ();
1228 }
1229 break;
07aae5c2
SC
1230 case 'G':
1231 if (GET_CODE (x) != CONST_INT)
1232 abort ();
1233 fprintf (file, "#%d", 0xff & (-INTVAL (x)));
1234 break;
48837e29
DE
1235 case 'S':
1236 if (GET_CODE (x) == REG)
1237 fprintf (file, "%s", names_extended[REGNO (x)]);
07aae5c2 1238 else
48837e29 1239 goto def;
07aae5c2 1240 break;
48837e29
DE
1241 case 'T':
1242 if (GET_CODE (x) == REG)
1243 fprintf (file, "%s", names_big[REGNO (x)]);
07aae5c2 1244 else
48837e29 1245 goto def;
07aae5c2 1246 break;
48837e29 1247 case 'V':
4d4d89e2 1248 bitint = exact_log2 (INTVAL (x) & 0xff);
48837e29 1249 if (bitint == -1)
07aae5c2 1250 abort ();
4d4d89e2 1251 fprintf (file, "#%d", bitint);
07aae5c2 1252 break;
48837e29 1253 case 'W':
07aae5c2
SC
1254 bitint = exact_log2 ((~INTVAL (x)) & 0xff);
1255 if (bitint == -1)
1256 abort ();
4d4d89e2 1257 fprintf (file, "#%d", bitint);
07aae5c2 1258 break;
15dc331e 1259 case 'R':
48837e29
DE
1260 case 'X':
1261 if (GET_CODE (x) == REG)
1262 fprintf (file, "%s", byte_reg (x, 0));
1263 else
1264 goto def;
1265 break;
1266 case 'Y':
07aae5c2
SC
1267 if (bitint == -1)
1268 abort ();
48837e29
DE
1269 if (GET_CODE (x) == REG)
1270 fprintf (file, "%s%c", names_big[REGNO (x)], bitint > 7 ? 'h' : 'l');
1271 else
15dc331e 1272 print_operand (file, x, 'R');
48837e29
DE
1273 bitint = -1;
1274 break;
1275 case 'Z':
1276 bitint = INTVAL (x);
07aae5c2
SC
1277 fprintf (file, "#%d", bitint & 7);
1278 break;
48837e29
DE
1279 case 'b':
1280 switch (GET_CODE (x))
07aae5c2 1281 {
48837e29
DE
1282 case IOR:
1283 fprintf (file, "bor");
1284 break;
1285 case XOR:
1286 fprintf (file, "bxor");
1287 break;
1288 case AND:
1289 fprintf (file, "band");
1290 break;
441d04c6
KG
1291 default:
1292 break;
07aae5c2 1293 }
48837e29 1294 break;
07aae5c2
SC
1295 case 'e':
1296 switch (GET_CODE (x))
1297 {
1298 case REG:
48837e29
DE
1299 if (TARGET_H8300)
1300 fprintf (file, "%s", names_big[REGNO (x)]);
1301 else
1302 fprintf (file, "%s", names_upper_extended[REGNO (x)]);
07aae5c2
SC
1303 break;
1304 case MEM:
07aae5c2
SC
1305 print_operand (file, x, 0);
1306 break;
1307 case CONST_INT:
1308 fprintf (file, "#%d", ((INTVAL (x) >> 16) & 0xffff));
1309 break;
808fbfac
JL
1310 case CONST_DOUBLE:
1311 {
1312 long val;
1313 REAL_VALUE_TYPE rv;
1314 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
1315 REAL_VALUE_TO_TARGET_SINGLE (rv, val);
441d04c6 1316 fprintf (file, "#%ld", ((val >> 16) & 0xffff));
808fbfac
JL
1317 break;
1318 }
07aae5c2
SC
1319 default:
1320 abort ();
1321 break;
1322 }
1323 break;
07aae5c2
SC
1324 case 'f':
1325 switch (GET_CODE (x))
1326 {
1327 case REG:
48837e29
DE
1328 if (TARGET_H8300)
1329 fprintf (file, "%s", names_big[REGNO (x) + 1]);
1330 else
1331 fprintf (file, "%s", names_big[REGNO (x)]);
07aae5c2 1332 break;
07aae5c2 1333 case MEM:
b72f00af 1334 x = adjust_address (x, HImode, 2);
07aae5c2
SC
1335 print_operand (file, x, 0);
1336 break;
07aae5c2
SC
1337 case CONST_INT:
1338 fprintf (file, "#%d", INTVAL (x) & 0xffff);
1339 break;
808fbfac
JL
1340 case CONST_DOUBLE:
1341 {
1342 long val;
1343 REAL_VALUE_TYPE rv;
1344 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
1345 REAL_VALUE_TO_TARGET_SINGLE (rv, val);
441d04c6 1346 fprintf (file, "#%ld", (val & 0xffff));
808fbfac
JL
1347 break;
1348 }
07aae5c2
SC
1349 default:
1350 abort ();
1351 }
1352 break;
07aae5c2 1353 case 'j':
761c70aa 1354 fputs (cond_string (GET_CODE (x)), file);
07aae5c2 1355 break;
07aae5c2 1356 case 'k':
761c70aa 1357 fputs (cond_string (reverse_condition (GET_CODE (x))), file);
07aae5c2 1358 break;
48837e29
DE
1359 case 's':
1360 if (GET_CODE (x) == CONST_INT)
1361 fprintf (file, "#%d", (INTVAL (x)) & 0xff);
1362 else
1363 fprintf (file, "%s", byte_reg (x, 0));
1364 break;
1365 case 't':
1366 if (GET_CODE (x) == CONST_INT)
1367 fprintf (file, "#%d", (INTVAL (x) >> 8) & 0xff);
1368 else
1369 fprintf (file, "%s", byte_reg (x, 1));
1370 break;
1371 case 'u':
1372 if (GET_CODE (x) != CONST_INT)
1373 abort ();
1374 fprintf (file, "%d", INTVAL (x));
1375 break;
1376 case 'w':
1377 if (GET_CODE (x) == CONST_INT)
1378 fprintf (file, "#%d", INTVAL (x) & 0xff);
1379 else
a1616dd9
JL
1380 fprintf (file, "%s",
1381 byte_reg (x, TARGET_H8300 ? 2 : 0));
48837e29
DE
1382 break;
1383 case 'x':
1384 if (GET_CODE (x) == CONST_INT)
1385 fprintf (file, "#%d", (INTVAL (x) >> 8) & 0xff);
1386 else
a1616dd9
JL
1387 fprintf (file, "%s",
1388 byte_reg (x, TARGET_H8300 ? 3 : 1));
48837e29
DE
1389 break;
1390 case 'y':
1391 if (GET_CODE (x) == CONST_INT)
1392 fprintf (file, "#%d", (INTVAL (x) >> 16) & 0xff);
1393 else
1394 fprintf (file, "%s", byte_reg (x, 0));
1395 break;
1396 case 'z':
1397 if (GET_CODE (x) == CONST_INT)
1398 fprintf (file, "#%d", (INTVAL (x) >> 24) & 0xff);
1399 else
1400 fprintf (file, "%s", byte_reg (x, 1));
1401 break;
1402
07aae5c2 1403 default:
48837e29 1404 def:
07aae5c2
SC
1405 switch (GET_CODE (x))
1406 {
1407 case REG:
48837e29
DE
1408 switch (GET_MODE (x))
1409 {
1410 case QImode:
269c14e1 1411#if 0 /* Is it asm ("mov.b %0,r2l", ...) */
48837e29
DE
1412 fprintf (file, "%s", byte_reg (x, 0));
1413#else /* ... or is it asm ("mov.b %0l,r2l", ...) */
1414 fprintf (file, "%s", names_big[REGNO (x)]);
1415#endif
1416 break;
1417 case HImode:
1418 fprintf (file, "%s", names_big[REGNO (x)]);
1419 break;
1420 case SImode:
8977e8a7 1421 case SFmode:
48837e29
DE
1422 fprintf (file, "%s", names_extended[REGNO (x)]);
1423 break;
1424 default:
1425 abort ();
1426 }
07aae5c2
SC
1427 break;
1428
1429 case MEM:
87e4ee91
KH
1430 {
1431 rtx addr = XEXP (x, 0);
bc8db8a1
KH
1432 int eightbit_ok = ((GET_CODE (addr) == SYMBOL_REF
1433 && SYMBOL_REF_FLAG (addr))
1434 || EIGHTBIT_CONSTANT_ADDRESS_P (addr));
1435 int tiny_ok = ((GET_CODE (addr) == SYMBOL_REF
1436 && TINY_DATA_NAME_P (XSTR (addr, 0)))
1437 || TINY_CONSTANT_ADDRESS_P (addr));
87e4ee91
KH
1438
1439 fprintf (file, "@");
1440 output_address (addr);
1441
bc8db8a1
KH
1442 /* We fall back from smaller addressing to larger
1443 addressing in various ways depending on CODE. */
1444 switch (code)
1445 {
1446 case 'R':
1447 /* Used for mov.b and bit operations. */
1448 if (eightbit_ok)
1449 {
1450 fprintf (file, ":8");
1451 break;
1452 }
1453
1454 /* Fall through. We should not get here if we are
1455 processing bit operations on H8/300 or H8/300H
1456 because 'U' constraint does not allow bit
1457 operations on the tiny area on these machines. */
1458
1459 case 'T':
1460 case 'S':
1461 /* Used for mov.w and mov.l. */
1462 if (tiny_ok)
1463 fprintf (file, ":16");
1464 break;
1465 default:
1466 break;
1467 }
87e4ee91 1468 }
07aae5c2
SC
1469 break;
1470
1471 case CONST_INT:
1472 case SYMBOL_REF:
1473 case CONST:
1474 case LABEL_REF:
1475 fprintf (file, "#");
1476 print_operand_address (file, x);
1477 break;
808fbfac
JL
1478 case CONST_DOUBLE:
1479 {
1480 long val;
1481 REAL_VALUE_TYPE rv;
1482 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
1483 REAL_VALUE_TO_TARGET_SINGLE (rv, val);
441d04c6 1484 fprintf (file, "#%ld", val);
808fbfac
JL
1485 break;
1486 }
441d04c6
KG
1487 default:
1488 break;
07aae5c2
SC
1489 }
1490 }
1491}
1492
1493/* Output assembly language output for the address ADDR to FILE. */
1494
1495void
1496print_operand_address (file, addr)
1497 FILE *file;
1498 rtx addr;
1499{
1500 switch (GET_CODE (addr))
1501 {
1502 case REG:
48837e29 1503 fprintf (file, "%s", h8_reg_names[REGNO (addr)]);
07aae5c2
SC
1504 break;
1505
1506 case PRE_DEC:
48837e29 1507 fprintf (file, "-%s", h8_reg_names[REGNO (XEXP (addr, 0))]);
07aae5c2
SC
1508 break;
1509
1510 case POST_INC:
48837e29 1511 fprintf (file, "%s+", h8_reg_names[REGNO (XEXP (addr, 0))]);
07aae5c2
SC
1512 break;
1513
1514 case PLUS:
1515 fprintf (file, "(");
1516 if (GET_CODE (XEXP (addr, 0)) == REG)
1517 {
1518 /* reg,foo */
1519 print_operand_address (file, XEXP (addr, 1));
1520 fprintf (file, ",");
1521 print_operand_address (file, XEXP (addr, 0));
1522 }
1523 else
1524 {
1525 /* foo+k */
1526 print_operand_address (file, XEXP (addr, 0));
1527 fprintf (file, "+");
1528 print_operand_address (file, XEXP (addr, 1));
1529 }
1530 fprintf (file, ")");
1531 break;
1532
1533 case CONST_INT:
48837e29 1534 {
64530b82 1535 /* Since the H8/300 only has 16 bit pointers, negative values are also
48837e29
DE
1536 those >= 32768. This happens for example with pointer minus a
1537 constant. We don't want to turn (char *p - 2) into
1538 (char *p + 65534) because loop unrolling can build upon this
1539 (IE: char *p + 131068). */
1540 int n = INTVAL (addr);
1541 if (TARGET_H8300)
1542 n = (int) (short) n;
1543 if (n < 0)
07e4d94e 1544 /* ??? Why the special case for -ve values? */
48837e29
DE
1545 fprintf (file, "-%d", -n);
1546 else
1547 fprintf (file, "%d", n);
1548 break;
1549 }
07aae5c2
SC
1550
1551 default:
1552 output_addr_const (file, addr);
1553 break;
1554 }
1555}
1556\f
07aae5c2
SC
1557/* Output all insn addresses and their sizes into the assembly language
1558 output file. This is helpful for debugging whether the length attributes
1559 in the md file are correct. This is not meant to be a user selectable
1560 option. */
1561
1562void
1563final_prescan_insn (insn, operand, num_operands)
441d04c6
KG
1564 rtx insn, *operand ATTRIBUTE_UNUSED;
1565 int num_operands ATTRIBUTE_UNUSED;
07aae5c2
SC
1566{
1567 /* This holds the last insn address. */
1568 static int last_insn_address = 0;
1569
1570 int uid = INSN_UID (insn);
1571
48837e29
DE
1572 if (TARGET_RTL_DUMP)
1573 {
1574 fprintf (asm_out_file, "\n****************");
1575 print_rtl (asm_out_file, PATTERN (insn));
1576 fprintf (asm_out_file, "\n");
1577 }
1578
07aae5c2
SC
1579 if (TARGET_ADDRESSES)
1580 {
9d98a694
AO
1581 fprintf (asm_out_file, "; 0x%x %d\n", INSN_ADDRESSES (uid),
1582 INSN_ADDRESSES (uid) - last_insn_address);
1583 last_insn_address = INSN_ADDRESSES (uid);
07aae5c2
SC
1584 }
1585}
1586
48837e29
DE
1587/* Prepare for an SI sized move. */
1588
1589int
1590do_movsi (operands)
1591 rtx operands[];
07aae5c2 1592{
48837e29
DE
1593 rtx src = operands[1];
1594 rtx dst = operands[0];
1595 if (!reload_in_progress && !reload_completed)
1596 {
1597 if (!register_operand (dst, GET_MODE (dst)))
1598 {
1599 rtx tmp = gen_reg_rtx (GET_MODE (dst));
1600 emit_move_insn (tmp, src);
1601 operands[1] = tmp;
1602 }
1603 }
1604 return 0;
1605}
1606
1607/* Function for INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET).
07e4d94e
KH
1608 Define the offset between two registers, one to be eliminated, and
1609 the other its replacement, at the start of a routine. */
07aae5c2 1610
48837e29
DE
1611int
1612initial_offset (from, to)
441d04c6 1613 int from, to;
48837e29
DE
1614{
1615 int offset = 0;
1616
1617 if (from == ARG_POINTER_REGNUM && to == FRAME_POINTER_REGNUM)
1618 offset = UNITS_PER_WORD + frame_pointer_needed * UNITS_PER_WORD;
1aae372e
JL
1619 else if (from == RETURN_ADDRESS_POINTER_REGNUM && to == FRAME_POINTER_REGNUM)
1620 offset = frame_pointer_needed * UNITS_PER_WORD;
48837e29 1621 else
07aae5c2 1622 {
48837e29
DE
1623 int regno;
1624
1625 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
d01d2903 1626 if (WORD_REG_USED (regno))
48837e29
DE
1627 offset += UNITS_PER_WORD;
1628
1629 /* See the comments for get_frame_size. We need to round it up to
1630 STACK_BOUNDARY. */
1631
1632 offset += ((get_frame_size () + STACK_BOUNDARY / BITS_PER_UNIT - 1)
1633 & ~(STACK_BOUNDARY / BITS_PER_UNIT - 1));
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
2039 one or two bits at a time on the H8/S.
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
2058 o SHIFT_LOOP: Emit a loop using one (or two on H8/S) bit shifts.
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
2123 H8/S QImode shifts
005e3e05 2124 7 - ASHIFTRT: shll, subx (propagate carry bit to all bits)
51c0c1d7
JL
2125
2126 H8/S 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
JL
2130
2131 H8/S SImode shifts
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
2369 or SHIFT_SPECIAL, and REMAINDER is non-zero. */
2370 const char *shift1;
2371
2372 /* Insn for a two-bit shift. Valid when ALG is either SHIFT_INLINE
2373 or SHIFT_SPECIAL, and REMAINDER is non-zero. */
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{
769828ab
KH
2404 int cpu;
2405
2406 /* Find the target CPU. */
2407 if (TARGET_H8300)
2408 cpu = 0;
2409 else if (TARGET_H8300H)
2410 cpu = 1;
2411 else
2412 cpu = 2;
2413
96eaf358 2414 /* Find the shift algorithm. */
48837e29
DE
2415 switch (shift_mode)
2416 {
2417 case QIshift:
769828ab 2418 if (GET_MODE_BITSIZE (QImode) <= count)
96eaf358
KH
2419 info->alg = SHIFT_LOOP;
2420 else
2421 info->alg = shift_alg_qi[cpu][shift_type][count];
2422 break;
769828ab 2423
96eaf358
KH
2424 case HIshift:
2425 if (GET_MODE_BITSIZE (HImode) <= count)
2426 info->alg = SHIFT_LOOP;
2427 else
2428 info->alg = shift_alg_hi[cpu][shift_type][count];
2429 break;
2430
2431 case SIshift:
2432 if (GET_MODE_BITSIZE (SImode) <= count)
2433 info->alg = SHIFT_LOOP;
2434 else
2435 info->alg = shift_alg_si[cpu][shift_type][count];
2436 break;
2437
2438 default:
2439 abort ();
2440 }
2441
2442 /* Fill in INFO. Return unless we have SHIFT_SPECIAL. */
2443 switch (info->alg)
2444 {
2445 case SHIFT_INLINE:
2446 info->remainder = count;
2447 /* Fall through. */
2448
2449 case SHIFT_LOOP:
2450 /* It is up to the caller to know that looping clobbers cc. */
2451 info->shift1 = shift_one[cpu_type][shift_type][shift_mode].assembler;
2452 info->shift2 = shift_two[shift_type][shift_mode].assembler;
2453 info->cc_valid_p = shift_one[cpu_type][shift_type][shift_mode].cc_valid;
2454 goto end;
2455
2456 case SHIFT_ROT_AND:
2457 info->shift1 = rotate_one[cpu_type][shift_type][shift_mode];
2458 info->shift2 = rotate_two[shift_type][shift_mode];
2459 info->cc_valid_p = 0;
2460 goto end;
2461
2462 case SHIFT_SPECIAL:
2463 /* REMAINDER is 0 for most cases, so initialize it to 0. */
2464 info->remainder = 0;
2465 info->shift1 = shift_one[cpu_type][shift_type][shift_mode].assembler;
2466 info->shift2 = shift_two[shift_type][shift_mode].assembler;
2467 info->cc_valid_p = 0;
2468 break;
2469 }
51c0c1d7 2470
96eaf358
KH
2471 /* Here we only deal with SHIFT_SPECIAL. */
2472 switch (shift_mode)
2473 {
2474 case QIshift:
769828ab
KH
2475 /* For ASHIFTRT by 7 bits, the sign bit is simply replicated
2476 through the entire value. */
2477 if (shift_type == SHIFT_ASHIFTRT && count == 7)
2478 {
2479 info->special = "shll\t%X0\n\tsubx\t%X0,%X0";
692b7eb3 2480 goto end;
769828ab
KH
2481 }
2482 abort ();
2483
2484 case HIshift:
769828ab 2485 if (count == 7)
51c0c1d7 2486 {
a77b1dbc 2487 switch (shift_type)
51c0c1d7 2488 {
a77b1dbc
KH
2489 case SHIFT_ASHIFT:
2490 if (TARGET_H8300)
2491 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";
2492 else
2493 info->special = "shar.b\t%t0\n\tmov.b\t%s0,%t0\n\trotxr.w\t%T0\n\tand.b\t#0x80,%s0";
692b7eb3 2494 goto end;
a77b1dbc
KH
2495 case SHIFT_LSHIFTRT:
2496 if (TARGET_H8300)
2497 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";
2498 else
2499 info->special = "shal.b\t%s0\n\tmov.b\t%t0,%s0\n\trotxl.w\t%T0\n\tand.b\t#0x01,%t0";
692b7eb3 2500 goto end;
a77b1dbc 2501 case SHIFT_ASHIFTRT:
35fb3d1f 2502 info->special = "shal.b\t%s0\n\tmov.b\t%t0,%s0\n\trotxl.b\t%s0\n\tsubx\t%t0,%t0";
692b7eb3 2503 goto end;
48837e29 2504 }
07aae5c2 2505 }
5e98fba2 2506 else if (8 <= count && count <= 13)
07aae5c2 2507 {
a7812c0b
KH
2508 info->remainder = count - 8;
2509
51c0c1d7 2510 switch (shift_type)
48837e29 2511 {
51c0c1d7 2512 case SHIFT_ASHIFT:
35fb3d1f 2513 info->special = "mov.b\t%s0,%t0\n\tsub.b\t%s0,%s0";
a7812c0b
KH
2514 info->shift1 = "shal.b\t%t0";
2515 info->shift2 = "shal.b\t#2,%t0";
692b7eb3 2516 goto end;
51c0c1d7 2517 case SHIFT_LSHIFTRT:
35fb3d1f 2518 info->special = "mov.b\t%t0,%s0\n\tsub.b\t%t0,%t0";
a7812c0b
KH
2519 info->shift1 = "shlr.b\t%s0";
2520 info->shift2 = "shlr.b\t#2,%s0";
692b7eb3 2521 goto end;
51c0c1d7
JL
2522 case SHIFT_ASHIFTRT:
2523 if (TARGET_H8300)
a7812c0b 2524 info->special = "mov.b\t%t0,%s0\n\tbld\t#7,%s0\n\tsubx\t%t0,%t0";
51c0c1d7 2525 else
35fb3d1f 2526 info->special = "mov.b\t%t0,%s0\n\texts.w\t%T0";
a7812c0b
KH
2527 info->shift1 = "shar.b\t%s0";
2528 info->shift2 = "shar.b\t#2,%s0";
692b7eb3 2529 goto end;
51c0c1d7
JL
2530 }
2531 }
5e98fba2
DD
2532 else if (count == 14)
2533 {
2534 switch (shift_type)
2535 {
2536 case SHIFT_ASHIFT:
2537 if (TARGET_H8300)
2538 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";
2539 goto end;
2540 case SHIFT_LSHIFTRT:
2541 if (TARGET_H8300)
2542 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";
2543 goto end;
2544 case SHIFT_ASHIFTRT:
2545 if (TARGET_H8300)
2546 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";
2547 else if (TARGET_H8300H)
2548 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";
2549 else /* TARGET_H8300S */
2550 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";
2551 goto end;
2552 }
2553 }
1e41e866 2554 else if (count == 15)
51c0c1d7 2555 {
1e41e866
KH
2556 switch (shift_type)
2557 {
2558 case SHIFT_ASHIFT:
2559 info->special = "bld\t#0,%s0\n\txor\t%s0,%s0\n\txor\t%t0,%t0\n\tbst\t#7,%t0";
2560 goto end;
2561 case SHIFT_LSHIFTRT:
2562 info->special = "bld\t#7,%t0\n\txor\t%s0,%s0\n\txor\t%t0,%t0\n\tbst\t#0,%s0";
2563 goto end;
2564 case SHIFT_ASHIFTRT:
2565 info->special = "shll\t%t0\n\tsubx\t%t0,%t0\n\tmov.b\t%t0,%s0";
2566 goto end;
2567 }
07aae5c2 2568 }
769828ab 2569 abort ();
51c0c1d7 2570
48837e29 2571 case SIshift:
1e41e866 2572 if (TARGET_H8300 && 8 <= count && count <= 9)
48837e29 2573 {
1e41e866
KH
2574 info->remainder = count - 8;
2575
51c0c1d7 2576 switch (shift_type)
48837e29 2577 {
51c0c1d7 2578 case SHIFT_ASHIFT:
35fb3d1f 2579 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 2580 goto end;
51c0c1d7 2581 case SHIFT_LSHIFTRT:
35fb3d1f 2582 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 2583 info->shift1 = "shlr\t%y0\n\trotxr\t%x0\n\trotxr\t%w0";
692b7eb3 2584 goto end;
51c0c1d7 2585 case SHIFT_ASHIFTRT:
35fb3d1f 2586 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 2587 goto end;
48837e29 2588 }
48837e29 2589 }
e6bcfef9
JS
2590 else if (count == 8 && !TARGET_H8300)
2591 {
2592 switch (shift_type)
2593 {
2594 case SHIFT_ASHIFT:
35fb3d1f 2595 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 2596 goto end;
e6bcfef9 2597 case SHIFT_LSHIFTRT:
35fb3d1f 2598 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 2599 goto end;
e6bcfef9 2600 case SHIFT_ASHIFTRT:
35fb3d1f 2601 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 2602 goto end;
e6bcfef9
JS
2603 }
2604 }
1e41e866
KH
2605 else if (count == 15 && TARGET_H8300)
2606 {
2607 switch (shift_type)
2608 {
2609 case SHIFT_ASHIFT:
2610 abort ();
2611 case SHIFT_LSHIFTRT:
2612 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";
2613 goto end;
2614 case SHIFT_ASHIFTRT:
2615 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";
2616 goto end;
2617 }
2618 }
dd69e230
KH
2619 else if (count == 15 && !TARGET_H8300)
2620 {
2621 switch (shift_type)
2622 {
2623 case SHIFT_ASHIFT:
2624 info->special = "shlr.w\t%e0\n\tmov.w\t%f0,%e0\n\txor.w\t%f0,%f0\n\trotxr.l\t%S0";
2625 goto end;
2626 case SHIFT_LSHIFTRT:
18cf8dda 2627 info->special = "shll.w\t%f0\n\tmov.w\t%e0,%f0\n\txor.w\t%e0,%e0\n\trotxl.l\t%S0";
dd69e230 2628 goto end;
aefc5826
KH
2629 case SHIFT_ASHIFTRT:
2630 abort ();
dd69e230
KH
2631 }
2632 }
1e41e866 2633 else if ((TARGET_H8300 && 16 <= count && count <= 20)
a7812c0b 2634 || (TARGET_H8300H && 16 <= count && count <= 19)
e0f19bd0 2635 || (TARGET_H8300S && 16 <= count && count <= 21))
48837e29 2636 {
a7812c0b
KH
2637 info->remainder = count - 16;
2638
48837e29
DE
2639 switch (shift_type)
2640 {
2641 case SHIFT_ASHIFT:
35fb3d1f 2642 info->special = "mov.w\t%f0,%e0\n\tsub.w\t%f0,%f0";
1e41e866
KH
2643 if (TARGET_H8300)
2644 {
2645 info->shift1 = "add.w\t%e0,%e0";
2646 }
2647 else
2648 {
2649 info->shift1 = "shll.l\t%S0";
2650 info->shift2 = "shll.l\t#2,%S0";
2651 }
692b7eb3 2652 goto end;
51c0c1d7 2653 case SHIFT_LSHIFTRT:
35fb3d1f 2654 info->special = "mov.w\t%e0,%f0\n\tsub.w\t%e0,%e0";
1e41e866
KH
2655 if (TARGET_H8300)
2656 {
2657 info->shift1 = "shlr\t%x0\n\trotxr\t%w0";
2658 }
2659 else
2660 {
2661 info->shift1 = "shlr.l\t%S0";
2662 info->shift2 = "shlr.l\t#2,%S0";
2663 }
692b7eb3 2664 goto end;
51c0c1d7
JL
2665 case SHIFT_ASHIFTRT:
2666 if (TARGET_H8300)
1e41e866
KH
2667 {
2668 info->special = "mov.w\t%e0,%f0\n\tshll\t%z0\n\tsubx\t%z0,%z0\n\tmov.b\t%z0,%y0";
2669 info->shift1 = "shar\t%x0\n\trotxr\t%w0";
2670 }
51c0c1d7 2671 else
1e41e866
KH
2672 {
2673 info->special = "mov.w\t%e0,%f0\n\texts.l\t%S0";
2674 info->shift1 = "shar.l\t%S0";
2675 info->shift2 = "shar.l\t#2,%S0";
2676 }
692b7eb3 2677 goto end;
51c0c1d7
JL
2678 }
2679 }
1e41e866 2680 else if (TARGET_H8300 && 24 <= count && count <= 28)
f9477efd
KH
2681 {
2682 info->remainder = count - 24;
f0b6f9a6 2683
f9477efd
KH
2684 switch (shift_type)
2685 {
2686 case SHIFT_ASHIFT:
2687 info->special = "mov.b\t%w0,%z0\n\tsub.b\t%y0,%y0\n\tsub.w\t%f0,%f0";
2688 info->shift1 = "shll.b\t%z0";
2689 goto end;
2690 case SHIFT_LSHIFTRT:
2691 info->special = "mov.b\t%z0,%w0\n\tsub.b\t%x0,%x0\n\tsub.w\t%e0,%e0";
2692 info->shift1 = "shlr.b\t%w0";
2693 goto end;
2694 case SHIFT_ASHIFTRT:
2695 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";
2696 info->shift1 = "shar.b\t%w0";
7f473594
KH
2697 goto end;
2698 }
2699 }
4a4ae922
KH
2700 else if ((TARGET_H8300H && count == 24)
2701 || (TARGET_H8300S && 24 <= count && count <= 25))
e6bcfef9 2702 {
4a4ae922
KH
2703 info->remainder = count - 24;
2704
e6bcfef9
JS
2705 switch (shift_type)
2706 {
2707 case SHIFT_ASHIFT:
35fb3d1f 2708 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
2709 info->shift1 = "shll.l\t%S0";
2710 info->shift2 = "shll.l\t#2,%S0";
692b7eb3 2711 goto end;
e6bcfef9 2712 case SHIFT_LSHIFTRT:
35fb3d1f 2713 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
2714 info->shift1 = "shlr.l\t%S0";
2715 info->shift2 = "shlr.l\t#2,%S0";
692b7eb3 2716 goto end;
e6bcfef9 2717 case SHIFT_ASHIFTRT:
35fb3d1f 2718 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
2719 info->shift1 = "shar.l\t%S0";
2720 info->shift2 = "shar.l\t#2,%S0";
692b7eb3 2721 goto end;
e6bcfef9
JS
2722 }
2723 }
48837e29
DE
2724 else if (count == 31)
2725 {
dd69e230 2726 if (TARGET_H8300)
48837e29 2727 {
dd69e230
KH
2728 switch (shift_type)
2729 {
2730 case SHIFT_ASHIFT:
2731 info->special = "sub.w\t%e0,%e0\n\tshlr\t%w0\n\tmov.w\t%e0,%f0\n\trotxr\t%z0";
2732 goto end;
2733 case SHIFT_LSHIFTRT:
2734 info->special = "sub.w\t%f0,%f0\n\tshll\t%z0\n\tmov.w\t%f0,%e0\n\trotxl\t%w0";
2735 goto end;
2736 case SHIFT_ASHIFTRT:
2737 info->special = "shll\t%z0\n\tsubx\t%w0,%w0\n\tmov.b\t%w0,%x0\n\tmov.w\t%f0,%e0";
2738 goto end;
2739 }
48837e29
DE
2740 }
2741 else
2742 {
dd69e230 2743 switch (shift_type)
48837e29 2744 {
dd69e230
KH
2745 case SHIFT_ASHIFT:
2746 info->special = "shlr.l\t%S0\n\txor.l\t%S0,%S0\n\trotxr.l\t%S0";
2747 goto end;
2748 case SHIFT_LSHIFTRT:
2749 info->special = "shll.l\t%S0\n\txor.l\t%S0,%S0\n\trotxl.l\t%S0";
2750 goto end;
2751 case SHIFT_ASHIFTRT:
2752 info->special = "shll\t%e0\n\tsubx\t%w0,%w0\n\tmov.b\t%w0,%x0\n\tmov.w\t%f0,%e0";
692b7eb3 2753 goto end;
48837e29 2754 }
48837e29
DE
2755 }
2756 }
769828ab 2757 abort ();
51c0c1d7 2758
48837e29
DE
2759 default:
2760 abort ();
07aae5c2 2761 }
48837e29 2762
cb33eb17
KH
2763 end:
2764 if (!TARGET_H8300S)
2765 info->shift2 = NULL;
07aae5c2
SC
2766}
2767
be1e06df
KH
2768/* Given COUNT and MODE of a shift, return 1 if a scratch reg may be
2769 needed for some shift with COUNT and MODE. Return 0 otherwise. */
2770
2771int
2772h8300_shift_needs_scratch_p (count, mode)
2773 int count;
2774 enum machine_mode mode;
2775{
2776 int cpu;
2777 int a, lr, ar;
2778
2779 if (GET_MODE_BITSIZE (mode) <= count)
2780 return 1;
2781
2782 /* Find out the target CPU. */
2783 if (TARGET_H8300)
2784 cpu = 0;
2785 else if (TARGET_H8300H)
2786 cpu = 1;
2787 else
2788 cpu = 2;
2789
2790 /* Find the shift algorithm. */
2791 switch (mode)
2792 {
2793 case QImode:
2794 a = shift_alg_qi[cpu][SHIFT_ASHIFT][count];
2795 lr = shift_alg_qi[cpu][SHIFT_LSHIFTRT][count];
2796 ar = shift_alg_qi[cpu][SHIFT_ASHIFTRT][count];
2797 break;
2798
2799 case HImode:
2800 a = shift_alg_hi[cpu][SHIFT_ASHIFT][count];
2801 lr = shift_alg_hi[cpu][SHIFT_LSHIFTRT][count];
2802 ar = shift_alg_hi[cpu][SHIFT_ASHIFTRT][count];
2803 break;
2804
2805 case SImode:
2806 a = shift_alg_si[cpu][SHIFT_ASHIFT][count];
2807 lr = shift_alg_si[cpu][SHIFT_LSHIFTRT][count];
2808 ar = shift_alg_si[cpu][SHIFT_ASHIFTRT][count];
2809 break;
2810
2811 default:
2812 abort ();
2813 }
2814
2815 /* On H8/300H and H8/S, count == 8 uses the scratch register. */
2816 return (a == SHIFT_LOOP || lr == SHIFT_LOOP || ar == SHIFT_LOOP
2817 || (!TARGET_H8300 && mode == SImode && count == 8));
2818}
2819
48837e29
DE
2820/* Emit the assembler code for doing shifts. */
2821
441d04c6 2822const char *
1a275226 2823output_a_shift (operands)
48837e29 2824 rtx *operands;
07aae5c2 2825{
48837e29 2826 static int loopend_lab;
48837e29
DE
2827 rtx shift = operands[3];
2828 enum machine_mode mode = GET_MODE (shift);
2829 enum rtx_code code = GET_CODE (shift);
2830 enum shift_type shift_type;
2831 enum shift_mode shift_mode;
35fb3d1f 2832 struct shift_info info;
48837e29
DE
2833
2834 loopend_lab++;
2835
2836 switch (mode)
2837 {
2838 case QImode:
2839 shift_mode = QIshift;
2840 break;
2841 case HImode:
2842 shift_mode = HIshift;
2843 break;
2844 case SImode:
2845 shift_mode = SIshift;
2846 break;
2847 default:
2848 abort ();
2849 }
07aae5c2 2850
48837e29 2851 switch (code)
07aae5c2 2852 {
48837e29
DE
2853 case ASHIFTRT:
2854 shift_type = SHIFT_ASHIFTRT;
2855 break;
2856 case LSHIFTRT:
2857 shift_type = SHIFT_LSHIFTRT;
2858 break;
2859 case ASHIFT:
2860 shift_type = SHIFT_ASHIFT;
2861 break;
2862 default:
2863 abort ();
2864 }
07aae5c2 2865
48837e29
DE
2866 if (GET_CODE (operands[2]) != CONST_INT)
2867 {
07e4d94e 2868 /* Indexing by reg, so have to loop and test at top. */
48837e29
DE
2869 output_asm_insn ("mov.b %X2,%X4", operands);
2870 fprintf (asm_out_file, "\tble .Lle%d\n", loopend_lab);
2871
2872 /* Get the assembler code to do one shift. */
35fb3d1f 2873 get_shift_alg (shift_type, shift_mode, 1, &info);
b5eaf9ba
KH
2874
2875 fprintf (asm_out_file, ".Llt%d:\n", loopend_lab);
35fb3d1f 2876 output_asm_insn (info.shift1, operands);
b5eaf9ba
KH
2877 output_asm_insn ("add #0xff,%X4", operands);
2878 fprintf (asm_out_file, "\tbne .Llt%d\n", loopend_lab);
2879 fprintf (asm_out_file, ".Lle%d:\n", loopend_lab);
2880
2881 return "";
48837e29
DE
2882 }
2883 else
2884 {
2885 int n = INTVAL (operands[2]);
48837e29
DE
2886
2887 /* If the count is negative, make it 0. */
2888 if (n < 0)
2889 n = 0;
2890 /* If the count is too big, truncate it.
2891 ANSI says shifts of GET_MODE_BITSIZE are undefined - we choose to
2892 do the intuitive thing. */
64530b82 2893 else if ((unsigned int) n > GET_MODE_BITSIZE (mode))
48837e29
DE
2894 n = GET_MODE_BITSIZE (mode);
2895
cb33eb17 2896 get_shift_alg (shift_type, shift_mode, n, &info);
48837e29 2897
cb33eb17 2898 switch (info.alg)
48837e29 2899 {
cb33eb17
KH
2900 case SHIFT_SPECIAL:
2901 output_asm_insn (info.special, operands);
2902 /* Fall through. */
2903
48837e29 2904 case SHIFT_INLINE:
cb33eb17
KH
2905 n = info.remainder;
2906
51c0c1d7 2907 /* Emit two bit shifts first. */
1a275226 2908 if (info.shift2 != NULL)
51c0c1d7 2909 {
1a275226
KH
2910 for (; n > 1; n -= 2)
2911 output_asm_insn (info.shift2, operands);
51c0c1d7
JL
2912 }
2913
2914 /* Now emit one bit shifts for any residual. */
1a275226
KH
2915 for (; n > 0; n--)
2916 output_asm_insn (info.shift1, operands);
51c0c1d7
JL
2917
2918 /* Keep track of CC. */
35fb3d1f 2919 if (info.cc_valid_p)
269c14e1
DE
2920 {
2921 cc_status.value1 = operands[0];
35fb3d1f 2922 cc_status.flags |= info.cc_valid_p;
269c14e1 2923 }
48837e29 2924 return "";
51c0c1d7 2925
48837e29
DE
2926 case SHIFT_ROT_AND:
2927 {
2928 int m = GET_MODE_BITSIZE (mode) - n;
2929 int mask = (shift_type == SHIFT_ASHIFT
1a275226
KH
2930 ? ((1 << m) - 1) << n
2931 : (1 << m) - 1);
48837e29 2932 char insn_buf[200];
b5eaf9ba 2933
48837e29
DE
2934 /* Not all possibilities of rotate are supported. They shouldn't
2935 be generated, but let's watch for 'em. */
35fb3d1f 2936 if (info.shift1 == 0)
48837e29 2937 abort ();
51c0c1d7
JL
2938
2939 /* Emit two bit rotates first. */
1a275226 2940 if (info.shift2 != NULL)
51c0c1d7 2941 {
1a275226
KH
2942 for (; m > 1; m -= 2)
2943 output_asm_insn (info.shift2, operands);
51c0c1d7
JL
2944 }
2945
2946 /* Now single bit rotates for any residual. */
1a275226
KH
2947 for (; m > 0; m--)
2948 output_asm_insn (info.shift1, operands);
51c0c1d7
JL
2949
2950 /* Now mask off the high bits. */
48837e29
DE
2951 if (TARGET_H8300)
2952 {
2953 switch (mode)
2954 {
2955 case QImode:
3e39bdb9 2956 sprintf (insn_buf, "and\t#%d,%%X0", mask);
48837e29 2957 cc_status.value1 = operands[0];
065bbfe6 2958 cc_status.flags |= CC_NO_CARRY;
48837e29
DE
2959 break;
2960 case HImode:
3e39bdb9 2961 sprintf (insn_buf, "and\t#%d,%%s0\n\tand\t#%d,%%t0",
441d04c6 2962 mask & 255, mask >> 8);
48837e29 2963 break;
441d04c6 2964 default:
1a275226 2965 abort ();
48837e29
DE
2966 }
2967 }
2968 else
2969 {
3e39bdb9 2970 sprintf (insn_buf, "and.%c\t#%d,%%%c0",
48837e29
DE
2971 "bwl"[shift_mode], mask,
2972 mode == QImode ? 'X' : mode == HImode ? 'T' : 'S');
2973 cc_status.value1 = operands[0];
065bbfe6 2974 cc_status.flags |= CC_NO_CARRY;
48837e29
DE
2975 }
2976 output_asm_insn (insn_buf, operands);
2977 return "";
2978 }
b5eaf9ba 2979
b5eaf9ba
KH
2980 case SHIFT_LOOP:
2981 /* A loop to shift by a "large" constant value.
2982 If we have shift-by-2 insns, use them. */
35fb3d1f 2983 if (info.shift2 != NULL)
b5eaf9ba
KH
2984 {
2985 fprintf (asm_out_file, "\tmov.b #%d,%sl\n", n / 2,
2986 names_big[REGNO (operands[4])]);
2987 fprintf (asm_out_file, ".Llt%d:\n", loopend_lab);
35fb3d1f 2988 output_asm_insn (info.shift2, operands);
b5eaf9ba
KH
2989 output_asm_insn ("add #0xff,%X4", operands);
2990 fprintf (asm_out_file, "\tbne .Llt%d\n", loopend_lab);
2991 if (n % 2)
35fb3d1f 2992 output_asm_insn (info.shift1, operands);
b5eaf9ba
KH
2993 }
2994 else
2995 {
2996 fprintf (asm_out_file, "\tmov.b #%d,%sl\n", n,
2997 names_big[REGNO (operands[4])]);
2998 fprintf (asm_out_file, ".Llt%d:\n", loopend_lab);
35fb3d1f 2999 output_asm_insn (info.shift1, operands);
b5eaf9ba
KH
3000 output_asm_insn ("add #0xff,%X4", operands);
3001 fprintf (asm_out_file, "\tbne .Llt%d\n", loopend_lab);
3002 }
51c0c1d7 3003 return "";
b5eaf9ba
KH
3004
3005 default:
3006 abort ();
51c0c1d7 3007 }
07aae5c2 3008 }
07aae5c2 3009}
86855e8c
KH
3010
3011static unsigned int
ab2877a3
KG
3012h8300_asm_insn_count (template)
3013 const char *template;
86855e8c
KH
3014{
3015 unsigned int count = 1;
3016
3017 for (; *template; template++)
3018 if (*template == '\n')
3019 count++;
3020
3021 return count;
3022}
3023
3024unsigned int
3025compute_a_shift_length (insn, operands)
3026 rtx insn ATTRIBUTE_UNUSED;
3027 rtx *operands;
3028{
3029 rtx shift = operands[3];
3030 enum machine_mode mode = GET_MODE (shift);
3031 enum rtx_code code = GET_CODE (shift);
3032 enum shift_type shift_type;
3033 enum shift_mode shift_mode;
3034 struct shift_info info;
3035 unsigned int wlength = 0;
3036
3037 switch (mode)
3038 {
3039 case QImode:
3040 shift_mode = QIshift;
3041 break;
3042 case HImode:
3043 shift_mode = HIshift;
3044 break;
3045 case SImode:
3046 shift_mode = SIshift;
3047 break;
3048 default:
3049 abort ();
3050 }
3051
3052 switch (code)
3053 {
3054 case ASHIFTRT:
3055 shift_type = SHIFT_ASHIFTRT;
3056 break;
3057 case LSHIFTRT:
3058 shift_type = SHIFT_LSHIFTRT;
3059 break;
3060 case ASHIFT:
3061 shift_type = SHIFT_ASHIFT;
3062 break;
3063 default:
3064 abort ();
3065 }
3066
3067 if (GET_CODE (operands[2]) != CONST_INT)
3068 {
3069 /* Get the assembler code to do one shift. */
3070 get_shift_alg (shift_type, shift_mode, 1, &info);
3071
3072 return (4 + h8300_asm_insn_count (info.shift1)) * 2;
3073 }
3074 else
3075 {
3076 int n = INTVAL (operands[2]);
3077
3078 /* If the count is negative, make it 0. */
3079 if (n < 0)
3080 n = 0;
3081 /* If the count is too big, truncate it.
3082 ANSI says shifts of GET_MODE_BITSIZE are undefined - we choose to
3083 do the intuitive thing. */
3084 else if ((unsigned int) n > GET_MODE_BITSIZE (mode))
3085 n = GET_MODE_BITSIZE (mode);
3086
3087 get_shift_alg (shift_type, shift_mode, n, &info);
3088
3089 switch (info.alg)
3090 {
3091 case SHIFT_SPECIAL:
3092 wlength += h8300_asm_insn_count (info.special);
3093 /* Fall through. */
3094
3095 case SHIFT_INLINE:
3096 n = info.remainder;
3097
3098 if (info.shift2 != NULL)
3099 {
3100 wlength += h8300_asm_insn_count (info.shift2) * (n / 2);
3101 n = n % 2;
3102 }
3103
3104 wlength += h8300_asm_insn_count (info.shift1) * n;
6b148bd9 3105
86855e8c
KH
3106 return 2 * wlength;
3107
3108 case SHIFT_ROT_AND:
3109 {
3110 int m = GET_MODE_BITSIZE (mode) - n;
3111
3112 /* Not all possibilities of rotate are supported. They shouldn't
3113 be generated, but let's watch for 'em. */
3114 if (info.shift1 == 0)
3115 abort ();
3116
3117 if (info.shift2 != NULL)
3118 {
3119 wlength += h8300_asm_insn_count (info.shift2) * (m / 2);
3120 m = m % 2;
3121 }
3122
3123 wlength += h8300_asm_insn_count (info.shift1) * m;
6b148bd9 3124
86855e8c
KH
3125 /* Now mask off the high bits. */
3126 switch (mode)
3127 {
3128 case QImode:
3129 wlength += 1;
3130 break;
3131 case HImode:
3132 wlength += 2;
3133 break;
3134 case SImode:
3135 if (TARGET_H8300)
3136 abort ();
3137 wlength += 3;
3138 break;
3139 default:
3140 abort ();
3141 }
3142 return 2 * wlength;
3143 }
3144
3145 case SHIFT_LOOP:
3146 /* A loop to shift by a "large" constant value.
3147 If we have shift-by-2 insns, use them. */
3148 if (info.shift2 != NULL)
3149 {
3150 wlength += 3 + h8300_asm_insn_count (info.shift2);
3151 if (n % 2)
3152 wlength += h8300_asm_insn_count (info.shift1);
3153 }
3154 else
3155 {
3156 wlength += 3 + h8300_asm_insn_count (info.shift1);
3157 }
3158 return 2 * wlength;
3159
3160 default:
3161 abort ();
3162 }
3163 }
3164}
48837e29 3165\f
edd71f0f
KH
3166/* A rotation by a non-constant will cause a loop to be generated, in
3167 which a rotation by one bit is used. A rotation by a constant,
3168 including the one in the loop, will be taken care of by
3169 emit_a_rotate () at the insn emit time. */
3170
3171int
3172expand_a_rotate (code, operands)
a11d9dfc 3173 enum rtx_code code;
edd71f0f
KH
3174 rtx operands[];
3175{
3176 rtx dst = operands[0];
3177 rtx src = operands[1];
3178 rtx rotate_amount = operands[2];
3179 enum machine_mode mode = GET_MODE (dst);
3180 rtx tmp;
3181
3182 /* We rotate in place. */
3183 emit_move_insn (dst, src);
3184
3185 if (GET_CODE (rotate_amount) != CONST_INT)
3186 {
3187 rtx counter = gen_reg_rtx (QImode);
3188 rtx start_label = gen_label_rtx ();
3189 rtx end_label = gen_label_rtx ();
3190
3191 /* If the rotate amount is less than or equal to 0,
3192 we go out of the loop. */
d43e0b7d
RK
3193 emit_cmp_and_jump_insns (rotate_amount, GEN_INT (0), LE, NULL_RTX,
3194 QImode, 0, end_label);
edd71f0f
KH
3195
3196 /* Initialize the loop counter. */
3197 emit_move_insn (counter, rotate_amount);
3198
3199 emit_label (start_label);
3200
3201 /* Rotate by one bit. */
3202 tmp = gen_rtx (code, mode, dst, GEN_INT (1));
3203 emit_insn (gen_rtx_SET (mode, dst, tmp));
3204
3205 /* Decrement the counter by 1. */
3206 tmp = gen_rtx_PLUS (QImode, counter, GEN_INT (-1));
3207 emit_insn (gen_rtx_SET (VOIDmode, counter, tmp));
3208
3209 /* If the loop counter is non-zero, we go back to the beginning
3210 of the loop. */
d43e0b7d
RK
3211 emit_cmp_and_jump_insns (counter, GEN_INT (0), NE, NULL_RTX, QImode, 1,
3212 start_label);
edd71f0f
KH
3213
3214 emit_label (end_label);
3215 }
3216 else
3217 {
3218 /* Rotate by AMOUNT bits. */
3219 tmp = gen_rtx (code, mode, dst, rotate_amount);
3220 emit_insn (gen_rtx_SET (mode, dst, tmp));
3221 }
3222
3223 return 1;
3224}
3225
3226/* Emit rotate insns. */
3227
3228const char *
3229emit_a_rotate (code, operands)
a11d9dfc 3230 enum rtx_code code;
edd71f0f
KH
3231 rtx *operands;
3232{
3233 rtx dst = operands[0];
3234 rtx rotate_amount = operands[2];
3235 enum shift_mode rotate_mode;
3236 enum shift_type rotate_type;
3237 const char *insn_buf;
3238 int bits;
3239 int amount;
3240 enum machine_mode mode = GET_MODE (dst);
3241
3242 if (GET_CODE (rotate_amount) != CONST_INT)
3243 abort ();
3244
3245 switch (mode)
3246 {
3247 case QImode:
3248 rotate_mode = QIshift;
3249 break;
3250 case HImode:
3251 rotate_mode = HIshift;
3252 break;
3253 case SImode:
3254 rotate_mode = SIshift;
3255 break;
3256 default:
3257 abort ();
3258 }
3259
3260 switch (code)
3261 {
3262 case ROTATERT:
3263 rotate_type = SHIFT_ASHIFT;
3264 break;
3265 case ROTATE:
3266 rotate_type = SHIFT_LSHIFTRT;
3267 break;
3268 default:
3269 abort ();
3270 }
3271
3272 amount = INTVAL (rotate_amount);
3273
3274 /* Clean up AMOUNT. */
3275 if (amount < 0)
3276 amount = 0;
3277 if ((unsigned int) amount > GET_MODE_BITSIZE (mode))
3278 amount = GET_MODE_BITSIZE (mode);
3279
3280 /* Determine the faster direction. After this phase, amount will be
3281 at most a half of GET_MODE_BITSIZE (mode). */
e0c32c62 3282 if ((unsigned int) amount > GET_MODE_BITSIZE (mode) / (unsigned) 2)
edd71f0f
KH
3283 {
3284 /* Flip the direction. */
3285 amount = GET_MODE_BITSIZE (mode) - amount;
3286 rotate_type =
3287 (rotate_type == SHIFT_ASHIFT) ? SHIFT_LSHIFTRT : SHIFT_ASHIFT;
3288 }
3289
3290 /* See if a byte swap (in HImode) or a word swap (in SImode) can
3291 boost up the rotation. */
3292 if ((mode == HImode && TARGET_H8300 && amount >= 5)
3293 || (mode == HImode && TARGET_H8300H && amount >= 6)
3294 || (mode == HImode && TARGET_H8300S && amount == 8)
3295 || (mode == SImode && TARGET_H8300H && amount >= 10)
3296 || (mode == SImode && TARGET_H8300S && amount >= 13))
3297 {
3298 switch (mode)
3299 {
3300 case HImode:
3301 /* This code works on any family. */
3302 insn_buf = "xor.b\t%s0,%t0\n\txor.b\t%t0,%s0\n\txor.b\t%s0,%t0";
3303 output_asm_insn (insn_buf, operands);
3304 break;
3305
3306 case SImode:
3307 /* This code works on the H8/300H and H8/S. */
3308 insn_buf = "xor.w\t%e0,%f0\n\txor.w\t%f0,%e0\n\txor.w\t%e0,%f0";
3309 output_asm_insn (insn_buf, operands);
3310 break;
3311
3312 default:
3313 abort ();
3314 }
3315
3316 /* Adjust AMOUNT and flip the direction. */
3317 amount = GET_MODE_BITSIZE (mode) / 2 - amount;
3318 rotate_type =
3319 (rotate_type == SHIFT_ASHIFT) ? SHIFT_LSHIFTRT : SHIFT_ASHIFT;
3320 }
3321
3322 /* Emit rotate insns. */
3323 for (bits = TARGET_H8300S ? 2 : 1; bits > 0; bits /= 2)
3324 {
3325 if (bits == 2)
3326 insn_buf = rotate_two[rotate_type][rotate_mode];
3327 else
3328 insn_buf = rotate_one[cpu_type][rotate_type][rotate_mode];
2c54abce 3329
edd71f0f
KH
3330 for (; amount >= bits; amount -= bits)
3331 output_asm_insn (insn_buf, operands);
3332 }
3333
3334 return "";
3335}
3336\f
48837e29 3337/* Fix the operands of a gen_xxx so that it could become a bit
2c54abce 3338 operating insn. */
07aae5c2
SC
3339
3340int
48837e29
DE
3341fix_bit_operand (operands, what, type)
3342 rtx *operands;
441d04c6 3343 int what;
48837e29 3344 enum rtx_code type;
07aae5c2 3345{
abc95ed3 3346 /* The bit_operand predicate accepts any memory during RTL generation, but
48837e29
DE
3347 only 'U' memory afterwards, so if this is a MEM operand, we must force
3348 it to be valid for 'U' by reloading the address. */
07aae5c2 3349
2e760b15
KH
3350 if ((what == 0 && single_zero_operand (operands[2], QImode))
3351 || (what == 1 && single_one_operand (operands[2], QImode)))
07aae5c2 3352 {
2e760b15
KH
3353 /* OK to have a memory dest. */
3354 if (GET_CODE (operands[0]) == MEM
3355 && !EXTRA_CONSTRAINT (operands[0], 'U'))
48837e29 3356 {
2e760b15
KH
3357 rtx mem = gen_rtx_MEM (GET_MODE (operands[0]),
3358 copy_to_mode_reg (Pmode,
3359 XEXP (operands[0], 0)));
3360 MEM_COPY_ATTRIBUTES (mem, operands[0]);
3361 operands[0] = mem;
3362 }
48837e29 3363
2e760b15
KH
3364 if (GET_CODE (operands[1]) == MEM
3365 && !EXTRA_CONSTRAINT (operands[1], 'U'))
3366 {
3367 rtx mem = gen_rtx_MEM (GET_MODE (operands[1]),
3368 copy_to_mode_reg (Pmode,
3369 XEXP (operands[1], 0)));
3370 MEM_COPY_ATTRIBUTES (mem, operands[0]);
3371 operands[1] = mem;
48837e29 3372 }
2e760b15 3373 return 0;
48837e29 3374 }
07aae5c2 3375
48837e29 3376 /* Dest and src op must be register. */
07aae5c2 3377
48837e29
DE
3378 operands[1] = force_reg (QImode, operands[1]);
3379 {
3380 rtx res = gen_reg_rtx (QImode);
c5c76735
JL
3381 emit_insn (gen_rtx_SET (VOIDmode, res,
3382 gen_rtx (type, QImode, operands[1], operands[2])));
3383 emit_insn (gen_rtx_SET (VOIDmode, operands[0], res));
48837e29
DE
3384 }
3385 return 1;
07aae5c2 3386}
f5b65a56 3387
f5b65a56
JL
3388/* Return nonzero if FUNC is an interrupt function as specified
3389 by the "interrupt" attribute. */
3390
3391static int
3392h8300_interrupt_function_p (func)
3393 tree func;
3394{
3395 tree a;
3396
3397 if (TREE_CODE (func) != FUNCTION_DECL)
3398 return 0;
3399
91d231cb 3400 a = lookup_attribute ("interrupt_handler", DECL_ATTRIBUTES (func));
f5b65a56
JL
3401 return a != NULL_TREE;
3402}
3403
fabe72bb
JL
3404/* Return nonzero if FUNC is an OS_Task function as specified
3405 by the "OS_Task" attribute. */
3406
3407static int
3408h8300_os_task_function_p (func)
3409 tree func;
3410{
3411 tree a;
3412
3413 if (TREE_CODE (func) != FUNCTION_DECL)
3414 return 0;
3415
91d231cb 3416 a = lookup_attribute ("OS_Task", DECL_ATTRIBUTES (func));
fabe72bb
JL
3417 return a != NULL_TREE;
3418}
3419
3420/* Return nonzero if FUNC is a monitor function as specified
3421 by the "monitor" attribute. */
3422
3423static int
3424h8300_monitor_function_p (func)
3425 tree func;
3426{
3427 tree a;
3428
3429 if (TREE_CODE (func) != FUNCTION_DECL)
3430 return 0;
3431
91d231cb 3432 a = lookup_attribute ("monitor", DECL_ATTRIBUTES (func));
fabe72bb
JL
3433 return a != NULL_TREE;
3434}
3435
f5b65a56
JL
3436/* Return nonzero if FUNC is a function that should be called
3437 through the function vector. */
3438
3439int
3440h8300_funcvec_function_p (func)
3441 tree func;
3442{
3443 tree a;
3444
3445 if (TREE_CODE (func) != FUNCTION_DECL)
3446 return 0;
3447
91d231cb 3448 a = lookup_attribute ("function_vector", DECL_ATTRIBUTES (func));
f5b65a56
JL
3449 return a != NULL_TREE;
3450}
3451
887a8bd9 3452/* Return nonzero if DECL is a variable that's in the eight bit
15dc331e
JL
3453 data area. */
3454
3455int
fabdc32d 3456h8300_eightbit_data_p (decl)
15dc331e
JL
3457 tree decl;
3458{
3459 tree a;
3460
3461 if (TREE_CODE (decl) != VAR_DECL)
3462 return 0;
3463
91d231cb 3464 a = lookup_attribute ("eightbit_data", DECL_ATTRIBUTES (decl));
15dc331e
JL
3465 return a != NULL_TREE;
3466}
3467
887a8bd9
JL
3468/* Return nonzero if DECL is a variable that's in the tiny
3469 data area. */
3470
3471int
3472h8300_tiny_data_p (decl)
3473 tree decl;
3474{
3475 tree a;
3476
3477 if (TREE_CODE (decl) != VAR_DECL)
3478 return 0;
3479
91d231cb 3480 a = lookup_attribute ("tiny_data", DECL_ATTRIBUTES (decl));
887a8bd9
JL
3481 return a != NULL_TREE;
3482}
3483
2c1d2fcb
DD
3484/* Generate an 'interrupt_handler' attribute for decls. */
3485
3486static void
3487h8300_insert_attributes (node, attributes)
3488 tree node;
3489 tree *attributes;
3490{
3491 if (!interrupt_handler
3492 || TREE_CODE (node) != FUNCTION_DECL)
3493 return;
3494
3495 /* Add an 'interrupt_handler' attribute. */
3496 *attributes = tree_cons (get_identifier ("interrupt_handler"),
3497 NULL, *attributes);
3498}
3499
91d231cb 3500/* Supported attributes:
f5b65a56 3501
97c5ec1d 3502 interrupt_handler: output a prologue and epilogue suitable for an
f5b65a56
JL
3503 interrupt handler.
3504
97c5ec1d 3505 function_vector: This function should be called through the
887a8bd9
JL
3506 function vector.
3507
3508 eightbit_data: This variable lives in the 8-bit data area and can
3509 be referenced with 8-bit absolute memory addresses.
3510
3511 tiny_data: This variable lives in the tiny data area and can be
3512 referenced with 16-bit absolute memory references. */
f5b65a56 3513
91d231cb 3514const struct attribute_spec h8300_attribute_table[] =
f5b65a56 3515{
91d231cb
JM
3516 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
3517 { "interrupt_handler", 0, 0, true, false, false, h8300_handle_fndecl_attribute },
3518 { "OS_Task", 0, 0, true, false, false, h8300_handle_fndecl_attribute },
3519 { "monitor", 0, 0, true, false, false, h8300_handle_fndecl_attribute },
3520 { "function_vector", 0, 0, true, false, false, h8300_handle_fndecl_attribute },
3521 { "eightbit_data", 0, 0, true, false, false, h8300_handle_eightbit_data_attribute },
3522 { "tiny_data", 0, 0, true, false, false, h8300_handle_tiny_data_attribute },
3523 { NULL, 0, 0, false, false, false, NULL }
3524};
f5b65a56 3525
15dc331e 3526
91d231cb
JM
3527/* Handle an attribute requiring a FUNCTION_DECL; arguments as in
3528 struct attribute_spec.handler. */
3529static tree
3530h8300_handle_fndecl_attribute (node, name, args, flags, no_add_attrs)
3531 tree *node;
3532 tree name;
3533 tree args ATTRIBUTE_UNUSED;
3534 int flags ATTRIBUTE_UNUSED;
3535 bool *no_add_attrs;
3536{
3537 if (TREE_CODE (*node) != FUNCTION_DECL)
3538 {
3539 warning ("`%s' attribute only applies to functions",
3540 IDENTIFIER_POINTER (name));
3541 *no_add_attrs = true;
3542 }
3543
3544 return NULL_TREE;
3545}
3546
3547/* Handle an "eightbit_data" attribute; arguments as in
3548 struct attribute_spec.handler. */
3549static tree
3550h8300_handle_eightbit_data_attribute (node, name, args, flags, no_add_attrs)
3551 tree *node;
3552 tree name;
3553 tree args ATTRIBUTE_UNUSED;
3554 int flags ATTRIBUTE_UNUSED;
3555 bool *no_add_attrs;
3556{
3557 tree decl = *node;
3558
3559 if (TREE_STATIC (decl) || DECL_EXTERNAL (decl))
15dc331e 3560 {
64378c91 3561 DECL_SECTION_NAME (decl) = build_string (7, ".eight");
91d231cb
JM
3562 }
3563 else
3564 {
3565 warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
3566 *no_add_attrs = true;
887a8bd9
JL
3567 }
3568
91d231cb
JM
3569 return NULL_TREE;
3570}
3571
3572/* Handle an "tiny_data" attribute; arguments as in
3573 struct attribute_spec.handler. */
3574static tree
3575h8300_handle_tiny_data_attribute (node, name, args, flags, no_add_attrs)
3576 tree *node;
3577 tree name;
3578 tree args ATTRIBUTE_UNUSED;
3579 int flags ATTRIBUTE_UNUSED;
3580 bool *no_add_attrs;
3581{
3582 tree decl = *node;
3583
3584 if (TREE_STATIC (decl) || DECL_EXTERNAL (decl))
887a8bd9 3585 {
64378c91 3586 DECL_SECTION_NAME (decl) = build_string (6, ".tiny");
91d231cb
JM
3587 }
3588 else
3589 {
3590 warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
3591 *no_add_attrs = true;
15dc331e 3592 }
07e4d94e 3593
91d231cb 3594 return NULL_TREE;
f5b65a56
JL
3595}
3596
fb49053f 3597static void
887a8bd9
JL
3598h8300_encode_label (decl)
3599 tree decl;
3600{
441d04c6 3601 const char *str = XSTR (XEXP (DECL_RTL (decl), 0), 0);
887a8bd9 3602 int len = strlen (str);
93cacb72 3603 char *newstr = alloca (len + 2);
887a8bd9 3604
93cacb72
KH
3605 newstr[0] = '&';
3606 strcpy (&newstr[1], str);
887a8bd9 3607
93cacb72
KH
3608 XSTR (XEXP (DECL_RTL (decl), 0), 0) =
3609 ggc_alloc_string (newstr, len + 1);
887a8bd9
JL
3610}
3611
fb49053f
RH
3612/* If we are referencing a function that is supposed to be called
3613 through the function vector, the SYMBOL_REF_FLAG in the rtl
3614 so the call patterns can generate the correct code. */
3615
3616static void
3617h8300_encode_section_info (decl, first)
3618 tree decl;
3619 int first;
3620{
3621 if (TREE_CODE (decl) == FUNCTION_DECL
3622 && h8300_funcvec_function_p (decl))
3623 SYMBOL_REF_FLAG (XEXP (DECL_RTL (decl), 0)) = 1;
3624 else if (TREE_CODE (decl) == VAR_DECL
3625 && (TREE_STATIC (decl) || DECL_EXTERNAL (decl)))
3626 {
3627 if (h8300_eightbit_data_p (decl))
3628 SYMBOL_REF_FLAG (XEXP (DECL_RTL (decl), 0)) = 1;
3629 else if (first && h8300_tiny_data_p (decl))
3630 h8300_encode_label (decl);
3631 }
3632}
3633
772c5265
RH
3634/* Undo the effects of the above. */
3635
3636static const char *
3637h8300_strip_name_encoding (str)
3638 const char *str;
3639{
3640 return str + (*str == '*' || *str == '@' || *str == '&');
3641}
3642
441d04c6 3643const char *
871f73e3 3644output_simode_bld (bild, operands)
bd93f126 3645 int bild;
bd93f126
JL
3646 rtx operands[];
3647{
6be580c7
KH
3648 if (TARGET_H8300)
3649 {
3650 /* Clear the destination register. */
3651 output_asm_insn ("sub.w\t%e0,%e0\n\tsub.w\t%f0,%f0", operands);
3652
3653 /* Now output the bit load or bit inverse load, and store it in
3654 the destination. */
3655 if (bild)
3656 output_asm_insn ("bild\t%Z2,%Y1", operands);
3657 else
3658 output_asm_insn ("bld\t%Z2,%Y1", operands);
bd93f126 3659
6be580c7
KH
3660 output_asm_insn ("bst\t#0,%w0", operands);
3661 }
bd93f126 3662 else
6be580c7
KH
3663 {
3664 /* Output the bit load or bit inverse load. */
3665 if (bild)
3666 output_asm_insn ("bild\t%Z2,%Y1", operands);
3667 else
3668 output_asm_insn ("bld\t%Z2,%Y1", operands);
3669
3670 /* Clear the destination register and perform the bit store. */
3671 output_asm_insn ("xor.l\t%S0,%S0\n\tbst\t#0,%w0", operands);
3672 }
bd93f126
JL
3673
3674 /* All done. */
3675 return "";
3676}
e6219736 3677
9ec36da5 3678/* Given INSN and its current length LENGTH, return the adjustment
e6219736
JL
3679 (in bytes) to correctly compute INSN's length.
3680
3681 We use this to get the lengths of various memory references correct. */
3682
441d04c6 3683int
e6219736
JL
3684h8300_adjust_insn_length (insn, length)
3685 rtx insn;
441d04c6 3686 int length ATTRIBUTE_UNUSED;
e6219736 3687{
5fc4b751 3688 rtx pat = PATTERN (insn);
04b6000c 3689
e32815aa 3690 /* We must filter these out before calling get_attr_adjust_length. */
5fc4b751
KH
3691 if (GET_CODE (pat) == USE
3692 || GET_CODE (pat) == CLOBBER
3693 || GET_CODE (pat) == SEQUENCE
3694 || GET_CODE (pat) == ADDR_VEC
3695 || GET_CODE (pat) == ADDR_DIFF_VEC)
47cf37f9
JL
3696 return 0;
3697
04b6000c
VM
3698 if (get_attr_adjust_length (insn) == ADJUST_LENGTH_NO)
3699 return 0;
3700
e6219736
JL
3701 /* Adjust length for reg->mem and mem->reg copies. */
3702 if (GET_CODE (pat) == SET
3703 && (GET_CODE (SET_SRC (pat)) == MEM
3704 || GET_CODE (SET_DEST (pat)) == MEM))
3705 {
3706 /* This insn might need a length adjustment. */
3707 rtx addr;
3708
3709 if (GET_CODE (SET_SRC (pat)) == MEM)
3710 addr = XEXP (SET_SRC (pat), 0);
3711 else
3712 addr = XEXP (SET_DEST (pat), 0);
3713
fbf0fe41
KH
3714 if (TARGET_H8300)
3715 {
3716 /* On the H8/300, we subtract the difference between the
3717 actual length and the longest one, which is @(d:16,ERs). */
e6219736 3718
fbf0fe41
KH
3719 /* @Rs is 2 bytes shorter than the longest. */
3720 if (GET_CODE (addr) == REG)
3721 return -2;
d56c04ce
DD
3722
3723 /* @aa:8 is 2 bytes shorter than the longest. */
3724 if (GET_MODE (SET_SRC (pat)) == QImode
3725 && ((GET_CODE (addr) == SYMBOL_REF && SYMBOL_REF_FLAG (addr))
3726 || EIGHTBIT_CONSTANT_ADDRESS_P (addr)))
3727 return -2;
fbf0fe41
KH
3728 }
3729 else
3730 {
3731 /* On the H8/300H and H8/S, we subtract the difference
3732 between the actual length and the longest one, which is
3733 @(d:24,ERs). */
3734
3735 /* @ERs is 6 bytes shorter than the longest. */
3736 if (GET_CODE (addr) == REG)
3737 return -6;
3738
3739 /* @(d:16,ERs) is 6 bytes shorter than the longest. */
3740 if (GET_CODE (addr) == PLUS
3741 && GET_CODE (XEXP (addr, 0)) == REG
3742 && GET_CODE (XEXP (addr, 1)) == CONST_INT
3743 && INTVAL (XEXP (addr, 1)) > -32768
3744 && INTVAL (XEXP (addr, 1)) < 32767)
3745 return -4;
3746
054ef905
KH
3747 /* @aa:8 is 6 bytes shorter than the longest. */
3748 if (GET_MODE (SET_SRC (pat)) == QImode
3749 && ((GET_CODE (addr) == SYMBOL_REF && SYMBOL_REF_FLAG (addr))
3750 || EIGHTBIT_CONSTANT_ADDRESS_P (addr)))
3751 return -6;
3752
3753 /* @aa:16 is 4 bytes shorter than the longest. */
3754 if ((GET_CODE (addr) == SYMBOL_REF
3755 && TINY_DATA_NAME_P (XSTR (addr, 0)))
3756 || TINY_CONSTANT_ADDRESS_P (addr))
3757 return -4;
3758
3759 /* @aa:24 is 2 bytes shorter than the longest. */
3760 if (GET_CODE (addr) == CONST_INT)
fbf0fe41
KH
3761 return -2;
3762 }
e6219736
JL
3763 }
3764
3765 /* Loading some constants needs adjustment. */
3766 if (GET_CODE (pat) == SET
3767 && GET_CODE (SET_SRC (pat)) == CONST_INT
3768 && GET_MODE (SET_DEST (pat)) == SImode
3769 && INTVAL (SET_SRC (pat)) != 0)
3770 {
64530b82
KH
3771 int val = INTVAL (SET_SRC (pat));
3772
e6219736 3773 if (TARGET_H8300
64530b82
KH
3774 && ((val & 0xffff) == 0
3775 || ((val >> 16) & 0xffff) == 0))
e6219736
JL
3776 return -2;
3777
a1616dd9 3778 if (TARGET_H8300H || TARGET_H8300S)
e6219736 3779 {
e6219736
JL
3780 if (val == (val & 0xff)
3781 || val == (val & 0xff00))
86039100 3782 return 4 - 6;
e6219736 3783
86039100
KH
3784 switch (val & 0xffffffff)
3785 {
3786 case 0xffffffff:
3787 case 0xfffffffe:
3788 case 0xfffffffc:
3789 case 0x0000ffff:
3790 case 0x0000fffe:
3791 case 0xffff0000:
3792 case 0xfffe0000:
3793 case 0x00010000:
3794 case 0x00020000:
3795 return 4 - 6;
3796 }
e6219736
JL
3797 }
3798 }
3799
edd71f0f
KH
3800 /* Rotations need various adjustments. */
3801 if (GET_CODE (pat) == SET
3802 && (GET_CODE (SET_SRC (pat)) == ROTATE
3803 || GET_CODE (SET_SRC (pat)) == ROTATERT))
3804 {
3805 rtx src = SET_SRC (pat);
3806 enum machine_mode mode = GET_MODE (src);
3807 int amount;
3808 int states = 0;
3809
3810 if (GET_CODE (XEXP (src, 1)) != CONST_INT)
3811 return 0;
3812
3813 amount = INTVAL (XEXP (src, 1));
3814
3815 /* Clean up AMOUNT. */
3816 if (amount < 0)
3817 amount = 0;
3818 if ((unsigned int) amount > GET_MODE_BITSIZE (mode))
3819 amount = GET_MODE_BITSIZE (mode);
3820
3821 /* Determine the faster direction. After this phase, amount
3822 will be at most a half of GET_MODE_BITSIZE (mode). */
e0c32c62 3823 if ((unsigned int) amount > GET_MODE_BITSIZE (mode) / (unsigned) 2)
edd71f0f
KH
3824 /* Flip the direction. */
3825 amount = GET_MODE_BITSIZE (mode) - amount;
3826
3827 /* See if a byte swap (in HImode) or a word swap (in SImode) can
3828 boost up the rotation. */
3829 if ((mode == HImode && TARGET_H8300 && amount >= 5)
3830 || (mode == HImode && TARGET_H8300H && amount >= 6)
3831 || (mode == HImode && TARGET_H8300S && amount == 8)
3832 || (mode == SImode && TARGET_H8300H && amount >= 10)
3833 || (mode == SImode && TARGET_H8300S && amount >= 13))
3834 {
3835 /* Adjust AMOUNT and flip the direction. */
3836 amount = GET_MODE_BITSIZE (mode) / 2 - amount;
3837 states += 6;
3838 }
3839
3840 /* We use 2-bit rotatations on the H8/S. */
3841 if (TARGET_H8300S)
3842 amount = amount / 2 + amount % 2;
3843
3844 /* The H8/300 uses three insns to rotate one bit, taking 6
3845 states. */
3846 states += amount * ((TARGET_H8300 && mode == HImode) ? 6 : 2);
3847
3848 return -(20 - states);
3849 }
3850
e6219736
JL
3851 return 0;
3852}
7c262518 3853
ede75ee8 3854#ifndef OBJECT_FORMAT_ELF
7c262518 3855static void
715bdd29 3856h8300_asm_named_section (name, flags)
7c262518
RH
3857 const char *name;
3858 unsigned int flags ATTRIBUTE_UNUSED;
7c262518
RH
3859{
3860 /* ??? Perhaps we should be using default_coff_asm_named_section. */
3861 fprintf (asm_out_file, "\t.section %s\n", name);
3862}
ede75ee8 3863#endif /* ! OBJECT_FORMAT_ELF */
This page took 1.561194 seconds and 5 git commands to generate.