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