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