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