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