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