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