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