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