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