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