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