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