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