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