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