]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/h8300/h8300.c
basic_ios.tcc (basic_ios::init): Set _M_fill to zero.
[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);
1209
1210 fprintf (file, "@");
1211 output_address (addr);
1212
1213 /* If this is an 'R' operand (reference into the 8-bit
1214 area), then specify a symbolic address as "foo:8",
1215 otherwise if operand is still in eight bit section, use
1216 "foo:16". */
1217 if (GET_CODE (addr) == SYMBOL_REF
1218 && SYMBOL_REF_FLAG (addr))
1219 fprintf (file, (code == 'R' ? ":8" : ":16"));
1220 else if (GET_CODE (addr) == SYMBOL_REF
1221 && TINY_DATA_NAME_P (XSTR (addr, 0)))
1222 fprintf (file, ":16");
1223 else if ((code == 'R')
1224 && EIGHTBIT_CONSTANT_ADDRESS_P (addr))
1225 fprintf (file, ":8");
1226 }
07aae5c2
SC
1227 break;
1228
1229 case CONST_INT:
1230 case SYMBOL_REF:
1231 case CONST:
1232 case LABEL_REF:
1233 fprintf (file, "#");
1234 print_operand_address (file, x);
1235 break;
808fbfac
JL
1236 case CONST_DOUBLE:
1237 {
1238 long val;
1239 REAL_VALUE_TYPE rv;
1240 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
1241 REAL_VALUE_TO_TARGET_SINGLE (rv, val);
441d04c6 1242 fprintf (file, "#%ld", val);
808fbfac
JL
1243 break;
1244 }
441d04c6
KG
1245 default:
1246 break;
07aae5c2
SC
1247 }
1248 }
1249}
1250
1251/* Output assembly language output for the address ADDR to FILE. */
1252
1253void
1254print_operand_address (file, addr)
1255 FILE *file;
1256 rtx addr;
1257{
1258 switch (GET_CODE (addr))
1259 {
1260 case REG:
48837e29 1261 fprintf (file, "%s", h8_reg_names[REGNO (addr)]);
07aae5c2
SC
1262 break;
1263
1264 case PRE_DEC:
48837e29 1265 fprintf (file, "-%s", h8_reg_names[REGNO (XEXP (addr, 0))]);
07aae5c2
SC
1266 break;
1267
1268 case POST_INC:
48837e29 1269 fprintf (file, "%s+", h8_reg_names[REGNO (XEXP (addr, 0))]);
07aae5c2
SC
1270 break;
1271
1272 case PLUS:
1273 fprintf (file, "(");
1274 if (GET_CODE (XEXP (addr, 0)) == REG)
1275 {
1276 /* reg,foo */
1277 print_operand_address (file, XEXP (addr, 1));
1278 fprintf (file, ",");
1279 print_operand_address (file, XEXP (addr, 0));
1280 }
1281 else
1282 {
1283 /* foo+k */
1284 print_operand_address (file, XEXP (addr, 0));
1285 fprintf (file, "+");
1286 print_operand_address (file, XEXP (addr, 1));
1287 }
1288 fprintf (file, ")");
1289 break;
1290
1291 case CONST_INT:
48837e29 1292 {
64530b82 1293 /* Since the H8/300 only has 16 bit pointers, negative values are also
48837e29
DE
1294 those >= 32768. This happens for example with pointer minus a
1295 constant. We don't want to turn (char *p - 2) into
1296 (char *p + 65534) because loop unrolling can build upon this
1297 (IE: char *p + 131068). */
1298 int n = INTVAL (addr);
1299 if (TARGET_H8300)
1300 n = (int) (short) n;
1301 if (n < 0)
07e4d94e 1302 /* ??? Why the special case for -ve values? */
48837e29
DE
1303 fprintf (file, "-%d", -n);
1304 else
1305 fprintf (file, "%d", n);
1306 break;
1307 }
07aae5c2
SC
1308
1309 default:
1310 output_addr_const (file, addr);
1311 break;
1312 }
1313}
1314\f
07aae5c2
SC
1315/* Output all insn addresses and their sizes into the assembly language
1316 output file. This is helpful for debugging whether the length attributes
1317 in the md file are correct. This is not meant to be a user selectable
1318 option. */
1319
1320void
1321final_prescan_insn (insn, operand, num_operands)
441d04c6
KG
1322 rtx insn, *operand ATTRIBUTE_UNUSED;
1323 int num_operands ATTRIBUTE_UNUSED;
07aae5c2
SC
1324{
1325 /* This holds the last insn address. */
1326 static int last_insn_address = 0;
1327
1328 int uid = INSN_UID (insn);
1329
48837e29
DE
1330 if (TARGET_RTL_DUMP)
1331 {
1332 fprintf (asm_out_file, "\n****************");
1333 print_rtl (asm_out_file, PATTERN (insn));
1334 fprintf (asm_out_file, "\n");
1335 }
1336
07aae5c2
SC
1337 if (TARGET_ADDRESSES)
1338 {
9d98a694
AO
1339 fprintf (asm_out_file, "; 0x%x %d\n", INSN_ADDRESSES (uid),
1340 INSN_ADDRESSES (uid) - last_insn_address);
1341 last_insn_address = INSN_ADDRESSES (uid);
07aae5c2
SC
1342 }
1343}
1344
48837e29
DE
1345/* Prepare for an SI sized move. */
1346
1347int
1348do_movsi (operands)
1349 rtx operands[];
07aae5c2 1350{
48837e29
DE
1351 rtx src = operands[1];
1352 rtx dst = operands[0];
1353 if (!reload_in_progress && !reload_completed)
1354 {
1355 if (!register_operand (dst, GET_MODE (dst)))
1356 {
1357 rtx tmp = gen_reg_rtx (GET_MODE (dst));
1358 emit_move_insn (tmp, src);
1359 operands[1] = tmp;
1360 }
1361 }
1362 return 0;
1363}
1364
1365/* Function for INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET).
07e4d94e
KH
1366 Define the offset between two registers, one to be eliminated, and
1367 the other its replacement, at the start of a routine. */
07aae5c2 1368
48837e29
DE
1369int
1370initial_offset (from, to)
441d04c6 1371 int from, to;
48837e29
DE
1372{
1373 int offset = 0;
1374
1375 if (from == ARG_POINTER_REGNUM && to == FRAME_POINTER_REGNUM)
1376 offset = UNITS_PER_WORD + frame_pointer_needed * UNITS_PER_WORD;
1aae372e
JL
1377 else if (from == RETURN_ADDRESS_POINTER_REGNUM && to == FRAME_POINTER_REGNUM)
1378 offset = frame_pointer_needed * UNITS_PER_WORD;
48837e29 1379 else
07aae5c2 1380 {
48837e29
DE
1381 int regno;
1382
1383 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
d01d2903 1384 if (WORD_REG_USED (regno))
48837e29
DE
1385 offset += UNITS_PER_WORD;
1386
1387 /* See the comments for get_frame_size. We need to round it up to
1388 STACK_BOUNDARY. */
1389
1390 offset += ((get_frame_size () + STACK_BOUNDARY / BITS_PER_UNIT - 1)
1391 & ~(STACK_BOUNDARY / BITS_PER_UNIT - 1));
1392
1393 if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
1394 offset += UNITS_PER_WORD; /* Skip saved PC */
1395 }
1396 return offset;
1397}
1398
1aae372e
JL
1399rtx
1400h8300_return_addr_rtx (count, frame)
1401 int count;
1402 rtx frame;
1403{
1404 rtx ret;
1405
1406 if (count == 0)
1407 ret = gen_rtx_MEM (Pmode,
1408 gen_rtx_REG (Pmode, RETURN_ADDRESS_POINTER_REGNUM));
1409 else if (flag_omit_frame_pointer)
1410 return (rtx) 0;
1411 else
1412 ret = gen_rtx_MEM (Pmode,
1413 memory_address (Pmode,
1414 plus_constant (frame, UNITS_PER_WORD)));
1415 set_mem_alias_set (ret, get_frame_alias_set ());
1416 return ret;
1417}
1418
48837e29
DE
1419/* Update the condition code from the insn. */
1420
441d04c6 1421void
48837e29
DE
1422notice_update_cc (body, insn)
1423 rtx body;
1424 rtx insn;
1425{
1426 switch (get_attr_cc (insn))
1427 {
1428 case CC_NONE:
269c14e1 1429 /* Insn does not affect CC at all. */
48837e29
DE
1430 break;
1431
1432 case CC_NONE_0HIT:
269c14e1 1433 /* Insn does not change CC, but the 0'th operand has been changed. */
48837e29 1434 if (cc_status.value1 != 0
1ccbefce 1435 && reg_overlap_mentioned_p (recog_data.operand[0], cc_status.value1))
48837e29 1436 cc_status.value1 = 0;
d4d6d0ce
KH
1437 if (cc_status.value2 != 0
1438 && reg_overlap_mentioned_p (recog_data.operand[0], cc_status.value2))
1439 cc_status.value2 = 0;
48837e29
DE
1440 break;
1441
065bbfe6 1442 case CC_SET_ZN:
1ccbefce 1443 /* Insn sets the Z,N flags of CC to recog_data.operand[0].
269c14e1
DE
1444 The V flag is unusable. The C flag may or may not be known but
1445 that's ok because alter_cond will change tests to use EQ/NE. */
48837e29 1446 CC_STATUS_INIT;
269c14e1 1447 cc_status.flags |= CC_OVERFLOW_UNUSABLE | CC_NO_CARRY;
1ccbefce 1448 cc_status.value1 = recog_data.operand[0];
48837e29
DE
1449 break;
1450
065bbfe6 1451 case CC_SET_ZNV:
1ccbefce 1452 /* Insn sets the Z,N,V flags of CC to recog_data.operand[0].
065bbfe6
JL
1453 The C flag may or may not be known but that's ok because
1454 alter_cond will change tests to use EQ/NE. */
1455 CC_STATUS_INIT;
1456 cc_status.flags |= CC_NO_CARRY;
1ccbefce 1457 cc_status.value1 = recog_data.operand[0];
d4d6d0ce
KH
1458 if (GET_CODE (body) == SET && REG_P (SET_SRC (body)))
1459 cc_status.value2 = SET_SRC (body);
065bbfe6
JL
1460 break;
1461
269c14e1
DE
1462 case CC_COMPARE:
1463 /* The insn is a compare instruction. */
48837e29 1464 CC_STATUS_INIT;
269c14e1 1465 cc_status.value1 = SET_SRC (body);
48837e29
DE
1466 break;
1467
48837e29 1468 case CC_CLOBBER:
269c14e1 1469 /* Insn doesn't leave CC in a usable state. */
48837e29
DE
1470 CC_STATUS_INIT;
1471 break;
07aae5c2 1472 }
48837e29
DE
1473}
1474
07e4d94e 1475/* Recognize valid operators for bit instructions. */
48837e29
DE
1476
1477int
1478bit_operator (x, mode)
1479 rtx x;
441d04c6 1480 enum machine_mode mode ATTRIBUTE_UNUSED;
48837e29
DE
1481{
1482 enum rtx_code code = GET_CODE (x);
07aae5c2 1483
48837e29
DE
1484 return (code == XOR
1485 || code == AND
1486 || code == IOR);
07aae5c2 1487}
48837e29 1488\f
366a7b27
KH
1489const char *
1490output_logical_op (mode, code, operands)
1491 enum machine_mode mode;
1492 int code;
1493 rtx *operands;
1494{
1495 /* Pretend that every byte is affected if both operands are registers. */
1496 unsigned HOST_WIDE_INT intval =
1497 (unsigned HOST_WIDE_INT) ((GET_CODE (operands[2]) == CONST_INT)
1498 ? INTVAL (operands[2]) : 0x55555555);
1499 /* The determinant of the algorithm. If we perform an AND, 0
1500 affects a bit. Otherwise, 1 affects a bit. */
1501 unsigned HOST_WIDE_INT det = (code != AND) ? intval : ~intval;
1502 /* The name of an insn. */
1503 const char *opname;
1504 char insn_buf[100];
1505
1506 switch (code)
1507 {
1508 case AND:
1509 opname = "and";
1510 break;
1511 case IOR:
1512 opname = "or";
1513 break;
1514 case XOR:
1515 opname = "xor";
1516 break;
1517 default:
1518 abort ();
1519 }
1520
1521 switch (mode)
1522 {
1523 case HImode:
1524 /* First, see if we can finish with one insn. */
1525 if ((TARGET_H8300H || TARGET_H8300S)
1526 && ((det & 0x00ff) != 0)
1527 && ((det & 0xff00) != 0))
1528 {
1529 sprintf (insn_buf, "%s.w\t%%T2,%%T0", opname);
1530 output_asm_insn (insn_buf, operands);
1531 }
1532 else
1533 {
1534 /* Take care of the lower byte. */
1535 if ((det & 0x00ff) != 0)
1536 {
1537 sprintf (insn_buf, "%s\t%%s2,%%s0", opname);
1538 output_asm_insn (insn_buf, operands);
1539 }
1540 /* Take care of the upper byte. */
1541 if ((det & 0xff00) != 0)
1542 {
1543 sprintf (insn_buf, "%s\t%%t2,%%t0", opname);
1544 output_asm_insn (insn_buf, operands);
1545 }
1546 }
1547 break;
1548 case SImode:
1549 /* First, see if we can finish with one insn.
1550
1551 If code is either AND or XOR, we exclude two special cases,
187462ac 1552 0xffffff00 and 0xffff00ff, because insns like sub.w or not.w
366a7b27
KH
1553 can do a better job. */
1554 if ((TARGET_H8300H || TARGET_H8300S)
1555 && ((det & 0x0000ffff) != 0)
1556 && ((det & 0xffff0000) != 0)
1557 && (code == IOR || det != 0xffffff00)
1558 && (code == IOR || det != 0xffff00ff))
1559 {
1560 sprintf (insn_buf, "%s.l\t%%S2,%%S0", opname);
1561 output_asm_insn (insn_buf, operands);
1562 }
1563 else
1564 {
1565 /* Take care of the lower and upper words individually. For
1566 each word, we try different methods in the order of
1567
1568 1) the special insn (in case of AND or XOR),
1569 2) the word-wise insn, and
1570 3) The byte-wise insn. */
6dfa4005
KH
1571 if ((det & 0x0000ffff) == 0x0000ffff
1572 && (TARGET_H8300 ? (code == AND) : (code != IOR)))
366a7b27 1573 output_asm_insn ((code == AND)
187462ac 1574 ? "sub.w\t%f0,%f0" : "not.w\t%f0",
366a7b27
KH
1575 operands);
1576 else if ((TARGET_H8300H || TARGET_H8300S)
1577 && ((det & 0x000000ff) != 0)
1578 && ((det & 0x0000ff00) != 0))
1579 {
1580 sprintf (insn_buf, "%s.w\t%%f2,%%f0", opname);
1581 output_asm_insn (insn_buf, operands);
1582 }
1583 else
1584 {
1585 if ((det & 0x000000ff) != 0)
1586 {
1587 sprintf (insn_buf, "%s\t%%w2,%%w0", opname);
1588 output_asm_insn (insn_buf, operands);
1589 }
1590 if ((det & 0x0000ff00) != 0)
1591 {
1592 sprintf (insn_buf, "%s\t%%x2,%%x0", opname);
1593 output_asm_insn (insn_buf, operands);
1594 }
1595 }
1596
6dfa4005
KH
1597 if ((det & 0xffff0000) == 0xffff0000
1598 && (TARGET_H8300 ? (code == AND) : (code != IOR)))
366a7b27 1599 output_asm_insn ((code == AND)
187462ac 1600 ? "sub.w\t%e0,%e0" : "not.w\t%e0",
366a7b27
KH
1601 operands);
1602 else if (TARGET_H8300H || TARGET_H8300S)
1603 {
1604 if ((det & 0xffff0000) != 0)
1605 {
1606 sprintf (insn_buf, "%s.w\t%%e2,%%e0", opname);
1607 output_asm_insn (insn_buf, operands);
1608 }
1609 }
1610 else
1611 {
1612 if ((det & 0x00ff0000) != 0)
1613 {
1614 sprintf (insn_buf, "%s\t%%y2,%%y0", opname);
1615 output_asm_insn (insn_buf, operands);
1616 }
1617 if ((det & 0xff000000) != 0)
1618 {
1619 sprintf (insn_buf, "%s\t%%z2,%%z0", opname);
1620 output_asm_insn (insn_buf, operands);
1621 }
1622 }
1623 }
1624 break;
1625 default:
1626 abort ();
1627 }
1628 return "";
1629}
40367e2d
KH
1630
1631unsigned int
1632compute_logical_op_length (mode, code, operands)
1633 enum machine_mode mode;
1634 enum rtx_code code;
1635 rtx *operands;
1636{
1637 /* Pretend that every byte is affected if both operands are registers. */
1638 unsigned HOST_WIDE_INT intval =
1639 (unsigned HOST_WIDE_INT) ((GET_CODE (operands[2]) == CONST_INT)
1640 ? INTVAL (operands[2]) : 0x55555555);
1641 /* The determinant of the algorithm. If we perform an AND, 0
1642 affects a bit. Otherwise, 1 affects a bit. */
1643 unsigned HOST_WIDE_INT det = (code != AND) ? intval : ~intval;
1644 /* Insn length. */
1645 unsigned int length = 0;
1646
1647 switch (mode)
1648 {
1649 case HImode:
1650 /* First, see if we can finish with one insn. */
1651 if ((TARGET_H8300H || TARGET_H8300S)
1652 && ((det & 0x00ff) != 0)
1653 && ((det & 0xff00) != 0))
1654 {
1655 if (REG_P (operands[2]))
1656 length += 2;
1657 else
1658 length += 4;
1659 }
1660 else
1661 {
1662 /* Take care of the lower byte. */
1663 if ((det & 0x00ff) != 0)
1664 length += 2;
1665
1666 /* Take care of the upper byte. */
1667 if ((det & 0xff00) != 0)
1668 length += 2;
1669 }
1670 break;
1671 case SImode:
1672 /* First, see if we can finish with one insn.
1673
1674 If code is either AND or XOR, we exclude two special cases,
1675 0xffffff00 and 0xffff00ff, because insns like sub.w or not.w
1676 can do a better job. */
1677 if ((TARGET_H8300H || TARGET_H8300S)
1678 && ((det & 0x0000ffff) != 0)
1679 && ((det & 0xffff0000) != 0)
1680 && (code == IOR || det != 0xffffff00)
1681 && (code == IOR || det != 0xffff00ff))
1682 {
1683 if (REG_P (operands[2]))
1684 length += 4;
1685 else
1686 length += 6;
1687 }
1688 else
1689 {
1690 /* Take care of the lower and upper words individually. For
1691 each word, we try different methods in the order of
1692
1693 1) the special insn (in case of AND or XOR),
1694 2) the word-wise insn, and
1695 3) The byte-wise insn. */
1696 if ((det & 0x0000ffff) == 0x0000ffff
1697 && (TARGET_H8300 ? (code == AND) : (code != IOR)))
1698 {
1699 length += 2;
1700 }
1701 else if ((TARGET_H8300H || TARGET_H8300S)
1702 && ((det & 0x000000ff) != 0)
1703 && ((det & 0x0000ff00) != 0))
1704 {
1705 length += 4;
1706 }
1707 else
1708 {
1709 if ((det & 0x000000ff) != 0)
1710 length += 2;
1711
1712 if ((det & 0x0000ff00) != 0)
1713 length += 2;
1714 }
1715
1716 if ((det & 0xffff0000) == 0xffff0000
1717 && (TARGET_H8300 ? (code == AND) : (code != IOR)))
1718 {
1719 length += 2;
1720 }
1721 else if (TARGET_H8300H || TARGET_H8300S)
1722 {
1723 if ((det & 0xffff0000) != 0)
1724 length += 4;
1725 }
1726 else
1727 {
1728 if ((det & 0x00ff0000) != 0)
1729 length += 2;
1730
1731 if ((det & 0xff000000) != 0)
1732 length += 2;
1733 }
1734 }
1735 break;
1736 default:
1737 abort ();
1738 }
1739 return length;
1740}
366a7b27 1741\f
48837e29
DE
1742/* Shifts.
1743
005e3e05
KH
1744 We devote a fair bit of code to getting efficient shifts since we
1745 can only shift one bit at a time on the H8/300 and H8/300H and only
1746 one or two bits at a time on the H8/S.
1747
1748 All shift code falls into one of the following ways of
1749 implementation:
1750
1751 o SHIFT_INLINE: Emit straight line code for the shift; this is used
1752 when a straight line shift is about the same size or smaller than
1753 a loop.
1754
1755 o SHIFT_ROT_AND: Rotate the value the opposite direction, then mask
1756 off the bits we don't need. This is used when only a few of the
1757 bits in the original value will survive in the shifted value.
1758
1759 o SHIFT_SPECIAL: Often it's possible to move a byte or a word to
1760 simulate a shift by 8, 16, or 24 bits. Once moved, a few inline
1761 shifts can be added if the shift count is slightly more than 8 or
1762 16. This case also includes other oddballs that are not worth
1763 explaning here.
1764
1765 o SHIFT_LOOP: Emit a loop using one (or two on H8/S) bit shifts.
1766
1767 Here are some thoughts on what the absolutely positively best code
1768 is. "Best" here means some rational trade-off between code size
1769 and speed, where speed is more preferred but not at the expense of
1770 generating 20 insns.
1771
1772 Below, a trailing '*' after the shift count indicates the "best"
1773 mode isn't implemented. We only describe SHIFT_SPECIAL cases to
1774 simplify the table. For other cases, refer to shift_alg_[qhs]i.
51c0c1d7 1775
48837e29 1776 H8/300 QImode shifts
005e3e05 1777 7 - ASHIFTRT: shll, subx (propagate carry bit to all bits)
48837e29
DE
1778
1779 H8/300 HImode shifts
51c0c1d7
JL
1780 7 - shift 2nd half other way into carry.
1781 copy 1st half into 2nd half
1782 rotate 2nd half other way with carry
1783 rotate 1st half other way (no carry)
1784 mask off bits in 1st half (ASHIFT | LSHIFTRT).
1785 sign extend 1st half (ASHIFTRT)
1786 8 - move byte, zero (ASHIFT | LSHIFTRT) or sign extend other (ASHIFTRT)
1787 9-12 - do shift by 8, inline remaining shifts
005e3e05 1788 15 - ASHIFTRT: shll, subx, set other byte
48837e29
DE
1789
1790 H8/300 SImode shifts
51c0c1d7
JL
1791 7* - shift other way once, move bytes into place,
1792 move carry into place (possibly with sign extension)
1793 8 - move bytes into place, zero or sign extend other
51c0c1d7
JL
1794 15* - shift other way once, move word into place, move carry into place
1795 16 - move word, zero or sign extend other
51c0c1d7 1796 24* - move bytes into place, zero or sign extend other
005e3e05 1797 31 - ASHIFTRT: shll top byte, subx, copy to other bytes
51c0c1d7
JL
1798
1799 H8/300H QImode shifts (same as H8/300 QImode shifts)
005e3e05 1800 7 - ASHIFTRT: shll, subx (propagate carry bit to all bits)
51c0c1d7 1801
48837e29 1802 H8/300H HImode shifts
51c0c1d7
JL
1803 7 - shift 2nd half other way into carry.
1804 copy 1st half into 2nd half
1805 rotate entire word other way using carry
1806 mask off remaining bits (ASHIFT | LSHIFTRT)
1807 sign extend remaining bits (ASHIFTRT)
1808 8 - move byte, zero (ASHIFT | LSHIFTRT) or sign extend other (ASHIFTRT)
1809 9-12 - do shift by 8, inline remaining shifts
005e3e05 1810 15 - ASHIFTRT: shll, subx, set other byte
48837e29
DE
1811
1812 H8/300H SImode shifts
1813 (These are complicated by the fact that we don't have byte level access to
1814 the top word.)
1815 A word is: bytes 3,2,1,0 (msb -> lsb), word 1,0 (msw -> lsw)
51c0c1d7
JL
1816 15* - shift other way once, move word into place, move carry into place
1817 (with sign extension for ASHIFTRT)
1818 16 - move word into place, zero or sign extend other
1819 17-20 - do 16bit shift, then inline remaining shifts
51c0c1d7
JL
1820 24* - ASHIFT: move byte 0(msb) to byte 1, zero byte 0,
1821 move word 0 to word 1, zero word 0
1822 LSHIFTRT: move word 1 to word 0, move byte 1 to byte 0,
1823 zero word 1, zero byte 1
1824 ASHIFTRT: move word 1 to word 0, move byte 1 to byte 0,
1825 sign extend byte 0, sign extend word 0
1826 25-27* - either loop, or
1827 do 24 bit shift, inline rest
51c0c1d7
JL
1828 31 - shll, subx byte 0, sign extend byte 0, sign extend word 0
1829
1830 H8/S QImode shifts
005e3e05 1831 7 - ASHIFTRT: shll, subx (propagate carry bit to all bits)
51c0c1d7
JL
1832
1833 H8/S HImode shifts
51c0c1d7
JL
1834 8 - move byte, zero (ASHIFT | LSHIFTRT) or sign extend other (ASHIFTRT)
1835 9-12 - do shift by 8, inline remaining shifts
005e3e05 1836 15 - ASHIFTRT: shll, subx, set other byte
51c0c1d7
JL
1837
1838 H8/S SImode shifts
1839 (These are complicated by the fact that we don't have byte level access to
1840 the top word.)
1841 A word is: bytes 3,2,1,0 (msb -> lsb), word 1,0 (msw -> lsw)
51c0c1d7
JL
1842 15* - shift other way once, move word into place, move carry into place
1843 (with sign extension for ASHIFTRT)
1844 16 - move word into place, zero or sign extend other
1845 17-20 - do 16bit shift, then inline remaining shifts
51c0c1d7
JL
1846 24* - ASHIFT: move byte 0(msb) to byte 1, zero byte 0,
1847 move word 0 to word 1, zero word 0
1848 LSHIFTRT: move word 1 to word 0, move byte 1 to byte 0,
1849 zero word 1, zero byte 1
1850 ASHIFTRT: move word 1 to word 0, move byte 1 to byte 0,
1851 sign extend byte 0, sign extend word 0
1852 25-27* - either loop, or
1853 do 24 bit shift, inline rest
51c0c1d7
JL
1854 31 - shll, subx byte 0, sign extend byte 0, sign extend word 0
1855
1856 Panic!!! */
07aae5c2
SC
1857
1858int
48837e29
DE
1859nshift_operator (x, mode)
1860 rtx x;
441d04c6 1861 enum machine_mode mode ATTRIBUTE_UNUSED;
48837e29
DE
1862{
1863 switch (GET_CODE (x))
1864 {
1865 case ASHIFTRT:
1866 case LSHIFTRT:
1867 case ASHIFT:
1868 return 1;
1869
1870 default:
1871 return 0;
1872 }
1873}
1874
1875/* Called from the .md file to emit code to do shifts.
64530b82
KH
1876 Return a boolean indicating success.
1877 (Currently this is always TRUE). */
48837e29
DE
1878
1879int
1880expand_a_shift (mode, code, operands)
1881 enum machine_mode mode;
07aae5c2
SC
1882 int code;
1883 rtx operands[];
07aae5c2 1884{
07aae5c2
SC
1885 emit_move_insn (operands[0], operands[1]);
1886
07e4d94e
KH
1887 /* Need a loop to get all the bits we want - we generate the
1888 code at emit time, but need to allocate a scratch reg now. */
48837e29 1889
c5c76735
JL
1890 emit_insn (gen_rtx_PARALLEL
1891 (VOIDmode,
48837e29 1892 gen_rtvec (2,
c5c76735
JL
1893 gen_rtx_SET (VOIDmode, operands[0],
1894 gen_rtx (code, mode, operands[0],
1895 operands[2])),
1896 gen_rtx_CLOBBER (VOIDmode,
1897 gen_rtx_SCRATCH (QImode)))));
48837e29
DE
1898
1899 return 1;
1900}
1901
005e3e05 1902/* See above for explanation of this enum. */
48837e29
DE
1903
1904enum shift_alg
1905{
1906 SHIFT_INLINE,
1907 SHIFT_ROT_AND,
1908 SHIFT_SPECIAL,
0c50ee73 1909 SHIFT_LOOP
48837e29
DE
1910};
1911
1912/* Symbols of the various shifts which can be used as indices. */
1913
1914enum shift_type
1a63219b
KH
1915{
1916 SHIFT_ASHIFT, SHIFT_LSHIFTRT, SHIFT_ASHIFTRT
1917};
48837e29
DE
1918
1919/* Symbols of the various modes which can be used as indices. */
1920
1921enum shift_mode
1a63219b
KH
1922{
1923 QIshift, HIshift, SIshift
1924};
48837e29 1925
269c14e1
DE
1926/* For single bit shift insns, record assembler and what bits of the
1927 condition code are valid afterwards (represented as various CC_FOO
1928 bits, 0 means CC isn't left in a usable state). */
48837e29
DE
1929
1930struct shift_insn
1931{
8b60264b
KG
1932 const char *const assembler;
1933 const int cc_valid;
48837e29
DE
1934};
1935
1936/* Assembler instruction shift table.
1937
1938 These tables are used to look up the basic shifts.
07e4d94e 1939 They are indexed by cpu, shift_type, and mode. */
07aae5c2 1940
48837e29
DE
1941static const struct shift_insn shift_one[2][3][3] =
1942{
1943/* H8/300 */
1944 {
1945/* SHIFT_ASHIFT */
1946 {
065bbfe6 1947 { "shll\t%X0", CC_NO_CARRY },
51c0c1d7
JL
1948 { "add.w\t%T0,%T0", CC_OVERFLOW_UNUSABLE | CC_NO_CARRY },
1949 { "add.w\t%f0,%f0\n\taddx\t%y0,%y0\n\taddx\t%z0,%z0", 0 }
48837e29
DE
1950 },
1951/* SHIFT_LSHIFTRT */
1952 {
065bbfe6 1953 { "shlr\t%X0", CC_NO_CARRY },
51c0c1d7
JL
1954 { "shlr\t%t0\n\trotxr\t%s0", 0 },
1955 { "shlr\t%z0\n\trotxr\t%y0\n\trotxr\t%x0\n\trotxr\t%w0", 0 }
48837e29
DE
1956 },
1957/* SHIFT_ASHIFTRT */
1958 {
51c0c1d7
JL
1959 { "shar\t%X0", CC_OVERFLOW_UNUSABLE | CC_NO_CARRY },
1960 { "shar\t%t0\n\trotxr\t%s0", 0 },
1961 { "shar\t%z0\n\trotxr\t%y0\n\trotxr\t%x0\n\trotxr\t%w0", 0 }
48837e29
DE
1962 }
1963 },
1964/* H8/300H */
1965 {
1966/* SHIFT_ASHIFT */
1967 {
065bbfe6
JL
1968 { "shll.b\t%X0", CC_NO_CARRY },
1969 { "shll.w\t%T0", CC_NO_CARRY },
1970 { "shll.l\t%S0", CC_NO_CARRY }
48837e29
DE
1971 },
1972/* SHIFT_LSHIFTRT */
1973 {
065bbfe6
JL
1974 { "shlr.b\t%X0", CC_NO_CARRY },
1975 { "shlr.w\t%T0", CC_NO_CARRY },
1976 { "shlr.l\t%S0", CC_NO_CARRY }
48837e29
DE
1977 },
1978/* SHIFT_ASHIFTRT */
1979 {
51c0c1d7
JL
1980 { "shar.b\t%X0", CC_OVERFLOW_UNUSABLE | CC_NO_CARRY },
1981 { "shar.w\t%T0", CC_OVERFLOW_UNUSABLE | CC_NO_CARRY },
1982 { "shar.l\t%S0", CC_OVERFLOW_UNUSABLE | CC_NO_CARRY }
48837e29
DE
1983 }
1984 }
1985};
07aae5c2 1986
51c0c1d7
JL
1987static const struct shift_insn shift_two[3][3] =
1988{
1989/* SHIFT_ASHIFT */
1990 {
065bbfe6
JL
1991 { "shll.b\t#2,%X0", CC_NO_CARRY },
1992 { "shll.w\t#2,%T0", CC_NO_CARRY },
1993 { "shll.l\t#2,%S0", CC_NO_CARRY }
51c0c1d7
JL
1994 },
1995/* SHIFT_LSHIFTRT */
1996 {
065bbfe6
JL
1997 { "shlr.b\t#2,%X0", CC_NO_CARRY },
1998 { "shlr.w\t#2,%T0", CC_NO_CARRY },
1999 { "shlr.l\t#2,%S0", CC_NO_CARRY }
51c0c1d7
JL
2000 },
2001/* SHIFT_ASHIFTRT */
2002 {
2003 { "shar.b\t#2,%X0", CC_OVERFLOW_UNUSABLE | CC_NO_CARRY },
2004 { "shar.w\t#2,%T0", CC_OVERFLOW_UNUSABLE | CC_NO_CARRY },
2005 { "shar.l\t#2,%S0", CC_OVERFLOW_UNUSABLE | CC_NO_CARRY }
2006 }
2007};
2008
48837e29
DE
2009/* Rotates are organized by which shift they'll be used in implementing.
2010 There's no need to record whether the cc is valid afterwards because
2011 it is the AND insn that will decide this. */
07aae5c2 2012
48837e29
DE
2013static const char *const rotate_one[2][3][3] =
2014{
2015/* H8/300 */
2016 {
2017/* SHIFT_ASHIFT */
2018 {
51c0c1d7
JL
2019 "rotr\t%X0",
2020 "shlr\t%t0\n\trotxr\t%s0\n\tbst\t#7,%t0",
48837e29
DE
2021 0
2022 },
2023/* SHIFT_LSHIFTRT */
2024 {
51c0c1d7
JL
2025 "rotl\t%X0",
2026 "shll\t%s0\n\trotxl\t%t0\n\tbst\t#0,%s0",
48837e29
DE
2027 0
2028 },
2029/* SHIFT_ASHIFTRT */
2030 {
51c0c1d7
JL
2031 "rotl\t%X0",
2032 "shll\t%s0\n\trotxl\t%t0\n\tbst\t#0,%s0",
48837e29 2033 0
07aae5c2 2034 }
48837e29
DE
2035 },
2036/* H8/300H */
2037 {
2038/* SHIFT_ASHIFT */
2039 {
51c0c1d7
JL
2040 "rotr.b\t%X0",
2041 "rotr.w\t%T0",
2042 "rotr.l\t%S0"
48837e29
DE
2043 },
2044/* SHIFT_LSHIFTRT */
07aae5c2 2045 {
51c0c1d7
JL
2046 "rotl.b\t%X0",
2047 "rotl.w\t%T0",
2048 "rotl.l\t%S0"
48837e29
DE
2049 },
2050/* SHIFT_ASHIFTRT */
2051 {
51c0c1d7
JL
2052 "rotl.b\t%X0",
2053 "rotl.w\t%T0",
2054 "rotl.l\t%S0"
48837e29
DE
2055 }
2056 }
2057};
2058
51c0c1d7
JL
2059static const char *const rotate_two[3][3] =
2060{
2061/* SHIFT_ASHIFT */
2062 {
2063 "rotr.b\t#2,%X0",
2064 "rotr.w\t#2,%T0",
2065 "rotr.l\t#2,%S0"
2066 },
2067/* SHIFT_LSHIFTRT */
2068 {
2069 "rotl.b\t#2,%X0",
2070 "rotl.w\t#2,%T0",
2071 "rotl.l\t#2,%S0"
2072 },
2073/* SHIFT_ASHIFTRT */
2074 {
2075 "rotl.b\t#2,%X0",
2076 "rotl.w\t#2,%T0",
2077 "rotl.l\t#2,%S0"
2078 }
2079};
2080
769828ab
KH
2081/* Macros to keep the shift algorithm tables small. */
2082#define INL SHIFT_INLINE
2083#define ROT SHIFT_ROT_AND
2084#define LOP SHIFT_LOOP
2085#define SPC SHIFT_SPECIAL
2086
2087/* The shift algorithms for each machine, mode, shift type, and shift
2088 count are defined below. The three tables below correspond to
2089 QImode, HImode, and SImode, respectively. Each table is organized
2090 by, in the order of indecies, machine, shift type, and shift count. */
2091
2092static const enum shift_alg shift_alg_qi[3][3][8] = {
2093 {
2094 /* TARGET_H8300 */
2095 /* 0 1 2 3 4 5 6 7 */
2096 { INL, INL, INL, INL, INL, ROT, ROT, ROT }, /* SHIFT_ASHIFT */
2097 { INL, INL, INL, INL, INL, ROT, ROT, ROT }, /* SHIFT_LSHIFTRT */
2098 { INL, INL, INL, INL, INL, LOP, LOP, SPC } /* SHIFT_ASHIFTRT */
2099 },
2100 {
2101 /* TARGET_H8300H */
2102 /* 0 1 2 3 4 5 6 7 */
2103 { INL, INL, INL, INL, INL, ROT, ROT, ROT }, /* SHIFT_ASHIFT */
2104 { INL, INL, INL, INL, INL, ROT, ROT, ROT }, /* SHIFT_LSHIFTRT */
2105 { INL, INL, INL, INL, INL, LOP, LOP, SPC } /* SHIFT_ASHIFTRT */
2106 },
2107 {
2108 /* TARGET_H8300S */
2109 /* 0 1 2 3 4 5 6 7 */
e0f19bd0
KH
2110 { INL, INL, INL, INL, INL, INL, ROT, ROT }, /* SHIFT_ASHIFT */
2111 { INL, INL, INL, INL, INL, INL, ROT, ROT }, /* SHIFT_LSHIFTRT */
769828ab
KH
2112 { INL, INL, INL, INL, INL, INL, INL, SPC } /* SHIFT_ASHIFTRT */
2113 }
2114};
2115
2116static const enum shift_alg shift_alg_hi[3][3][16] = {
2117 {
2118 /* TARGET_H8300 */
2119 /* 0 1 2 3 4 5 6 7 */
2120 /* 8 9 10 11 12 13 14 15 */
2121 { INL, INL, INL, INL, INL, LOP, LOP, SPC,
1e41e866 2122 SPC, SPC, SPC, SPC, SPC, LOP, LOP, SPC }, /* SHIFT_ASHIFT */
769828ab 2123 { INL, INL, INL, INL, INL, LOP, LOP, SPC,
1e41e866 2124 SPC, SPC, SPC, SPC, SPC, LOP, LOP, SPC }, /* SHIFT_LSHIFTRT */
769828ab
KH
2125 { INL, INL, INL, INL, INL, LOP, LOP, SPC,
2126 SPC, SPC, SPC, SPC, SPC, LOP, LOP, SPC }, /* SHIFT_ASHIFTRT */
2127 },
2128 {
2129 /* TARGET_H8300H */
2130 /* 0 1 2 3 4 5 6 7 */
2131 /* 8 9 10 11 12 13 14 15 */
2132 { INL, INL, INL, INL, INL, LOP, LOP, SPC,
2133 SPC, SPC, SPC, SPC, SPC, ROT, ROT, ROT }, /* SHIFT_ASHIFT */
2134 { INL, INL, INL, INL, INL, LOP, LOP, SPC,
2135 SPC, SPC, SPC, SPC, SPC, ROT, ROT, ROT }, /* SHIFT_LSHIFTRT */
2136 { INL, INL, INL, INL, INL, LOP, LOP, SPC,
2137 SPC, SPC, SPC, SPC, SPC, LOP, LOP, SPC }, /* SHIFT_ASHIFTRT */
2138 },
2139 {
2140 /* TARGET_H8300S */
2141 /* 0 1 2 3 4 5 6 7 */
2142 /* 8 9 10 11 12 13 14 15 */
2143 { INL, INL, INL, INL, INL, INL, INL, INL,
2144 SPC, SPC, SPC, SPC, SPC, ROT, ROT, ROT }, /* SHIFT_ASHIFT */
2145 { INL, INL, INL, INL, INL, INL, INL, INL,
2146 SPC, SPC, SPC, SPC, SPC, ROT, ROT, ROT }, /* SHIFT_LSHIFTRT */
2147 { INL, INL, INL, INL, INL, INL, INL, INL,
2148 SPC, SPC, SPC, SPC, SPC, LOP, LOP, SPC }, /* SHIFT_ASHIFTRT */
2149 }
2150};
2151
2152static const enum shift_alg shift_alg_si[3][3][32] = {
2153 {
2154 /* TARGET_H8300 */
2155 /* 0 1 2 3 4 5 6 7 */
2156 /* 8 9 10 11 12 13 14 15 */
2157 /* 16 17 18 19 20 21 22 23 */
2158 /* 24 25 26 27 28 29 30 31 */
2159 { INL, INL, INL, LOP, LOP, LOP, LOP, LOP,
2160 SPC, LOP, LOP, LOP, LOP, LOP, LOP, LOP,
1e41e866
KH
2161 SPC, SPC, SPC, SPC, SPC, LOP, LOP, LOP,
2162 SPC, SPC, SPC, SPC, LOP, LOP, LOP, SPC }, /* SHIFT_ASHIFT */
769828ab 2163 { INL, INL, INL, LOP, LOP, LOP, LOP, LOP,
1e41e866
KH
2164 SPC, SPC, LOP, LOP, LOP, LOP, LOP, SPC,
2165 SPC, SPC, SPC, LOP, LOP, LOP, LOP, LOP,
2166 SPC, SPC, SPC, SPC, SPC, LOP, LOP, SPC }, /* SHIFT_LSHIFTRT */
769828ab 2167 { INL, INL, INL, LOP, LOP, LOP, LOP, LOP,
1e41e866
KH
2168 SPC, LOP, LOP, LOP, LOP, LOP, LOP, SPC,
2169 SPC, SPC, LOP, LOP, LOP, LOP, LOP, LOP,
2170 SPC, SPC, SPC, LOP, LOP, LOP, LOP, SPC }, /* SHIFT_ASHIFTRT */
769828ab
KH
2171 },
2172 {
2173 /* TARGET_H8300H */
2174 /* 0 1 2 3 4 5 6 7 */
2175 /* 8 9 10 11 12 13 14 15 */
2176 /* 16 17 18 19 20 21 22 23 */
2177 /* 24 25 26 27 28 29 30 31 */
2178 { INL, INL, INL, INL, INL, LOP, LOP, LOP,
dd69e230 2179 SPC, LOP, LOP, LOP, LOP, LOP, LOP, SPC,
769828ab 2180 SPC, SPC, SPC, SPC, LOP, LOP, LOP, LOP,
dd69e230 2181 SPC, LOP, LOP, LOP, ROT, ROT, ROT, SPC }, /* SHIFT_ASHIFT */
769828ab 2182 { INL, INL, INL, INL, INL, LOP, LOP, LOP,
dd69e230 2183 SPC, LOP, LOP, LOP, LOP, LOP, LOP, SPC,
769828ab 2184 SPC, SPC, SPC, SPC, LOP, LOP, LOP, LOP,
dd69e230 2185 SPC, LOP, LOP, LOP, ROT, ROT, ROT, SPC }, /* SHIFT_LSHIFTRT */
769828ab
KH
2186 { INL, INL, INL, INL, INL, LOP, LOP, LOP,
2187 SPC, LOP, LOP, LOP, LOP, LOP, LOP, LOP,
2188 SPC, SPC, SPC, SPC, LOP, LOP, LOP, LOP,
2189 SPC, LOP, LOP, LOP, LOP, LOP, LOP, SPC }, /* SHIFT_ASHIFTRT */
2190 },
2191 {
2192 /* TARGET_H8300S */
2193 /* 0 1 2 3 4 5 6 7 */
2194 /* 8 9 10 11 12 13 14 15 */
2195 /* 16 17 18 19 20 21 22 23 */
2196 /* 24 25 26 27 28 29 30 31 */
2197 { INL, INL, INL, INL, INL, INL, INL, INL,
dd69e230 2198 INL, INL, INL, LOP, LOP, LOP, LOP, SPC,
e0f19bd0 2199 SPC, SPC, SPC, SPC, SPC, SPC, LOP, LOP,
4a4ae922 2200 SPC, SPC, LOP, LOP, ROT, ROT, ROT, SPC }, /* SHIFT_ASHIFT */
769828ab 2201 { INL, INL, INL, INL, INL, INL, INL, INL,
dd69e230 2202 INL, INL, INL, LOP, LOP, LOP, LOP, SPC,
e0f19bd0 2203 SPC, SPC, SPC, SPC, SPC, SPC, LOP, LOP,
4a4ae922 2204 SPC, SPC, LOP, LOP, ROT, ROT, ROT, SPC }, /* SHIFT_LSHIFTRT */
769828ab
KH
2205 { INL, INL, INL, INL, INL, INL, INL, INL,
2206 INL, INL, INL, LOP, LOP, LOP, LOP, LOP,
e0f19bd0 2207 SPC, SPC, SPC, SPC, SPC, SPC, LOP, LOP,
4a4ae922 2208 SPC, SPC, LOP, LOP, LOP, LOP, LOP, SPC }, /* SHIFT_ASHIFTRT */
769828ab
KH
2209 }
2210};
2211
2212#undef INL
2213#undef ROT
2214#undef LOP
2215#undef SPC
2216
35fb3d1f
KH
2217struct shift_info {
2218 /* Shift algorithm. */
2219 enum shift_alg alg;
2220
2221 /* The number of bits to be shifted by shift1 and shift2. Valid
2222 when ALG is SHIFT_SPECIAL. */
2223 unsigned int remainder;
2224
2225 /* Special insn for a shift. Valid when ALG is SHIFT_SPECIAL. */
2226 const char *special;
2227
2228 /* Insn for a one-bit shift. Valid when ALG is either SHIFT_INLINE
2229 or SHIFT_SPECIAL, and REMAINDER is non-zero. */
2230 const char *shift1;
2231
2232 /* Insn for a two-bit shift. Valid when ALG is either SHIFT_INLINE
2233 or SHIFT_SPECIAL, and REMAINDER is non-zero. */
2234 const char *shift2;
2235
2236 /* Valid CC flags. */
2237 int cc_valid_p;
2238};
2239
cb33eb17 2240static void get_shift_alg PARAMS ((enum shift_type,
769828ab 2241 enum shift_mode, unsigned int,
cb33eb17 2242 struct shift_info *));
441d04c6 2243
c009a745
KH
2244/* Given SHIFT_TYPE, SHIFT_MODE, and shift count COUNT, determine the
2245 best algorithm for doing the shift. The assembler code is stored
2246 in the pointers in INFO. We don't achieve maximum efficiency in
2247 all cases, but the hooks are here to do so.
48837e29
DE
2248
2249 For now we just use lots of switch statements. Since we don't even come
2250 close to supporting all the cases, this is simplest. If this function ever
2251 gets too big, perhaps resort to a more table based lookup. Of course,
2252 at this point you may just wish to do it all in rtl.
2253
2254 WARNING: The constraints on insns shiftbyn_QI/HI/SI assume shifts of
2255 1,2,3,4 will be inlined (1,2 for SI). */
2256
cb33eb17 2257static void
35fb3d1f 2258get_shift_alg (shift_type, shift_mode, count, info)
48837e29 2259 enum shift_type shift_type;
9789584b 2260 enum shift_mode shift_mode;
769828ab 2261 unsigned int count;
35fb3d1f 2262 struct shift_info *info;
48837e29 2263{
769828ab
KH
2264 int cpu;
2265
2266 /* Find the target CPU. */
2267 if (TARGET_H8300)
2268 cpu = 0;
2269 else if (TARGET_H8300H)
2270 cpu = 1;
2271 else
2272 cpu = 2;
2273
96eaf358 2274 /* Find the shift algorithm. */
48837e29
DE
2275 switch (shift_mode)
2276 {
2277 case QIshift:
769828ab 2278 if (GET_MODE_BITSIZE (QImode) <= count)
96eaf358
KH
2279 info->alg = SHIFT_LOOP;
2280 else
2281 info->alg = shift_alg_qi[cpu][shift_type][count];
2282 break;
769828ab 2283
96eaf358
KH
2284 case HIshift:
2285 if (GET_MODE_BITSIZE (HImode) <= count)
2286 info->alg = SHIFT_LOOP;
2287 else
2288 info->alg = shift_alg_hi[cpu][shift_type][count];
2289 break;
2290
2291 case SIshift:
2292 if (GET_MODE_BITSIZE (SImode) <= count)
2293 info->alg = SHIFT_LOOP;
2294 else
2295 info->alg = shift_alg_si[cpu][shift_type][count];
2296 break;
2297
2298 default:
2299 abort ();
2300 }
2301
2302 /* Fill in INFO. Return unless we have SHIFT_SPECIAL. */
2303 switch (info->alg)
2304 {
2305 case SHIFT_INLINE:
2306 info->remainder = count;
2307 /* Fall through. */
2308
2309 case SHIFT_LOOP:
2310 /* It is up to the caller to know that looping clobbers cc. */
2311 info->shift1 = shift_one[cpu_type][shift_type][shift_mode].assembler;
2312 info->shift2 = shift_two[shift_type][shift_mode].assembler;
2313 info->cc_valid_p = shift_one[cpu_type][shift_type][shift_mode].cc_valid;
2314 goto end;
2315
2316 case SHIFT_ROT_AND:
2317 info->shift1 = rotate_one[cpu_type][shift_type][shift_mode];
2318 info->shift2 = rotate_two[shift_type][shift_mode];
2319 info->cc_valid_p = 0;
2320 goto end;
2321
2322 case SHIFT_SPECIAL:
2323 /* REMAINDER is 0 for most cases, so initialize it to 0. */
2324 info->remainder = 0;
2325 info->shift1 = shift_one[cpu_type][shift_type][shift_mode].assembler;
2326 info->shift2 = shift_two[shift_type][shift_mode].assembler;
2327 info->cc_valid_p = 0;
2328 break;
2329 }
51c0c1d7 2330
96eaf358
KH
2331 /* Here we only deal with SHIFT_SPECIAL. */
2332 switch (shift_mode)
2333 {
2334 case QIshift:
769828ab
KH
2335 /* For ASHIFTRT by 7 bits, the sign bit is simply replicated
2336 through the entire value. */
2337 if (shift_type == SHIFT_ASHIFTRT && count == 7)
2338 {
2339 info->special = "shll\t%X0\n\tsubx\t%X0,%X0";
692b7eb3 2340 goto end;
769828ab
KH
2341 }
2342 abort ();
2343
2344 case HIshift:
769828ab 2345 if (count == 7)
51c0c1d7 2346 {
a77b1dbc 2347 switch (shift_type)
51c0c1d7 2348 {
a77b1dbc
KH
2349 case SHIFT_ASHIFT:
2350 if (TARGET_H8300)
2351 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";
2352 else
2353 info->special = "shar.b\t%t0\n\tmov.b\t%s0,%t0\n\trotxr.w\t%T0\n\tand.b\t#0x80,%s0";
692b7eb3 2354 goto end;
a77b1dbc
KH
2355 case SHIFT_LSHIFTRT:
2356 if (TARGET_H8300)
2357 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";
2358 else
2359 info->special = "shal.b\t%s0\n\tmov.b\t%t0,%s0\n\trotxl.w\t%T0\n\tand.b\t#0x01,%t0";
692b7eb3 2360 goto end;
a77b1dbc 2361 case SHIFT_ASHIFTRT:
35fb3d1f 2362 info->special = "shal.b\t%s0\n\tmov.b\t%t0,%s0\n\trotxl.b\t%s0\n\tsubx\t%t0,%t0";
692b7eb3 2363 goto end;
48837e29 2364 }
07aae5c2 2365 }
a7812c0b 2366 else if (8 <= count && count <= 12)
07aae5c2 2367 {
a7812c0b
KH
2368 info->remainder = count - 8;
2369
51c0c1d7 2370 switch (shift_type)
48837e29 2371 {
51c0c1d7 2372 case SHIFT_ASHIFT:
35fb3d1f 2373 info->special = "mov.b\t%s0,%t0\n\tsub.b\t%s0,%s0";
a7812c0b
KH
2374 info->shift1 = "shal.b\t%t0";
2375 info->shift2 = "shal.b\t#2,%t0";
692b7eb3 2376 goto end;
51c0c1d7 2377 case SHIFT_LSHIFTRT:
35fb3d1f 2378 info->special = "mov.b\t%t0,%s0\n\tsub.b\t%t0,%t0";
a7812c0b
KH
2379 info->shift1 = "shlr.b\t%s0";
2380 info->shift2 = "shlr.b\t#2,%s0";
692b7eb3 2381 goto end;
51c0c1d7
JL
2382 case SHIFT_ASHIFTRT:
2383 if (TARGET_H8300)
a7812c0b 2384 info->special = "mov.b\t%t0,%s0\n\tbld\t#7,%s0\n\tsubx\t%t0,%t0";
51c0c1d7 2385 else
35fb3d1f 2386 info->special = "mov.b\t%t0,%s0\n\texts.w\t%T0";
a7812c0b
KH
2387 info->shift1 = "shar.b\t%s0";
2388 info->shift2 = "shar.b\t#2,%s0";
692b7eb3 2389 goto end;
51c0c1d7
JL
2390 }
2391 }
1e41e866 2392 else if (count == 15)
51c0c1d7 2393 {
1e41e866
KH
2394 switch (shift_type)
2395 {
2396 case SHIFT_ASHIFT:
2397 info->special = "bld\t#0,%s0\n\txor\t%s0,%s0\n\txor\t%t0,%t0\n\tbst\t#7,%t0";
2398 goto end;
2399 case SHIFT_LSHIFTRT:
2400 info->special = "bld\t#7,%t0\n\txor\t%s0,%s0\n\txor\t%t0,%t0\n\tbst\t#0,%s0";
2401 goto end;
2402 case SHIFT_ASHIFTRT:
2403 info->special = "shll\t%t0\n\tsubx\t%t0,%t0\n\tmov.b\t%t0,%s0";
2404 goto end;
2405 }
07aae5c2 2406 }
769828ab 2407 abort ();
51c0c1d7 2408
48837e29 2409 case SIshift:
1e41e866 2410 if (TARGET_H8300 && 8 <= count && count <= 9)
48837e29 2411 {
1e41e866
KH
2412 info->remainder = count - 8;
2413
51c0c1d7 2414 switch (shift_type)
48837e29 2415 {
51c0c1d7 2416 case SHIFT_ASHIFT:
35fb3d1f 2417 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 2418 goto end;
51c0c1d7 2419 case SHIFT_LSHIFTRT:
35fb3d1f 2420 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 2421 info->shift1 = "shlr\t%y0\n\trotxr\t%x0\n\trotxr\t%w0";
692b7eb3 2422 goto end;
51c0c1d7 2423 case SHIFT_ASHIFTRT:
35fb3d1f 2424 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 2425 goto end;
48837e29 2426 }
48837e29 2427 }
e6bcfef9
JS
2428 else if (count == 8 && !TARGET_H8300)
2429 {
2430 switch (shift_type)
2431 {
2432 case SHIFT_ASHIFT:
35fb3d1f 2433 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 2434 goto end;
e6bcfef9 2435 case SHIFT_LSHIFTRT:
35fb3d1f 2436 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 2437 goto end;
e6bcfef9 2438 case SHIFT_ASHIFTRT:
35fb3d1f 2439 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 2440 goto end;
e6bcfef9
JS
2441 }
2442 }
1e41e866
KH
2443 else if (count == 15 && TARGET_H8300)
2444 {
2445 switch (shift_type)
2446 {
2447 case SHIFT_ASHIFT:
2448 abort ();
2449 case SHIFT_LSHIFTRT:
2450 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";
2451 goto end;
2452 case SHIFT_ASHIFTRT:
2453 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";
2454 goto end;
2455 }
2456 }
dd69e230
KH
2457 else if (count == 15 && !TARGET_H8300)
2458 {
2459 switch (shift_type)
2460 {
2461 case SHIFT_ASHIFT:
2462 info->special = "shlr.w\t%e0\n\tmov.w\t%f0,%e0\n\txor.w\t%f0,%f0\n\trotxr.l\t%S0";
2463 goto end;
2464 case SHIFT_LSHIFTRT:
18cf8dda 2465 info->special = "shll.w\t%f0\n\tmov.w\t%e0,%f0\n\txor.w\t%e0,%e0\n\trotxl.l\t%S0";
dd69e230 2466 goto end;
aefc5826
KH
2467 case SHIFT_ASHIFTRT:
2468 abort ();
dd69e230
KH
2469 }
2470 }
1e41e866 2471 else if ((TARGET_H8300 && 16 <= count && count <= 20)
a7812c0b 2472 || (TARGET_H8300H && 16 <= count && count <= 19)
e0f19bd0 2473 || (TARGET_H8300S && 16 <= count && count <= 21))
48837e29 2474 {
a7812c0b
KH
2475 info->remainder = count - 16;
2476
48837e29
DE
2477 switch (shift_type)
2478 {
2479 case SHIFT_ASHIFT:
35fb3d1f 2480 info->special = "mov.w\t%f0,%e0\n\tsub.w\t%f0,%f0";
1e41e866
KH
2481 if (TARGET_H8300)
2482 {
2483 info->shift1 = "add.w\t%e0,%e0";
2484 }
2485 else
2486 {
2487 info->shift1 = "shll.l\t%S0";
2488 info->shift2 = "shll.l\t#2,%S0";
2489 }
692b7eb3 2490 goto end;
51c0c1d7 2491 case SHIFT_LSHIFTRT:
35fb3d1f 2492 info->special = "mov.w\t%e0,%f0\n\tsub.w\t%e0,%e0";
1e41e866
KH
2493 if (TARGET_H8300)
2494 {
2495 info->shift1 = "shlr\t%x0\n\trotxr\t%w0";
2496 }
2497 else
2498 {
2499 info->shift1 = "shlr.l\t%S0";
2500 info->shift2 = "shlr.l\t#2,%S0";
2501 }
692b7eb3 2502 goto end;
51c0c1d7
JL
2503 case SHIFT_ASHIFTRT:
2504 if (TARGET_H8300)
1e41e866
KH
2505 {
2506 info->special = "mov.w\t%e0,%f0\n\tshll\t%z0\n\tsubx\t%z0,%z0\n\tmov.b\t%z0,%y0";
2507 info->shift1 = "shar\t%x0\n\trotxr\t%w0";
2508 }
51c0c1d7 2509 else
1e41e866
KH
2510 {
2511 info->special = "mov.w\t%e0,%f0\n\texts.l\t%S0";
2512 info->shift1 = "shar.l\t%S0";
2513 info->shift2 = "shar.l\t#2,%S0";
2514 }
692b7eb3 2515 goto end;
51c0c1d7
JL
2516 }
2517 }
1e41e866 2518 else if (TARGET_H8300 && 24 <= count && count <= 28)
f9477efd
KH
2519 {
2520 info->remainder = count - 24;
1e41e866 2521
f9477efd
KH
2522 switch (shift_type)
2523 {
2524 case SHIFT_ASHIFT:
2525 info->special = "mov.b\t%w0,%z0\n\tsub.b\t%y0,%y0\n\tsub.w\t%f0,%f0";
2526 info->shift1 = "shll.b\t%z0";
2527 goto end;
2528 case SHIFT_LSHIFTRT:
2529 info->special = "mov.b\t%z0,%w0\n\tsub.b\t%x0,%x0\n\tsub.w\t%e0,%e0";
2530 info->shift1 = "shlr.b\t%w0";
2531 goto end;
2532 case SHIFT_ASHIFTRT:
2533 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";
2534 info->shift1 = "shar.b\t%w0";
1e41e866 2535 goto end;
f9477efd
KH
2536 }
2537 }
4a4ae922
KH
2538 else if ((TARGET_H8300H && count == 24)
2539 || (TARGET_H8300S && 24 <= count && count <= 25))
e6bcfef9 2540 {
4a4ae922
KH
2541 info->remainder = count - 24;
2542
e6bcfef9
JS
2543 switch (shift_type)
2544 {
2545 case SHIFT_ASHIFT:
35fb3d1f 2546 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
2547 info->shift1 = "shll.l\t%S0";
2548 info->shift2 = "shll.l\t#2,%S0";
692b7eb3 2549 goto end;
e6bcfef9 2550 case SHIFT_LSHIFTRT:
35fb3d1f 2551 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
2552 info->shift1 = "shlr.l\t%S0";
2553 info->shift2 = "shlr.l\t#2,%S0";
692b7eb3 2554 goto end;
e6bcfef9 2555 case SHIFT_ASHIFTRT:
35fb3d1f 2556 info->special = "mov.w\t%e0,%f0\n\tmov.b\t%t0,%s0\n\texts.w\t%f0\n\texts.l\t%S0";
4a4ae922
KH
2557 info->shift1 = "shar.l\t%S0";
2558 info->shift2 = "shar.l\t#2,%S0";
692b7eb3 2559 goto end;
e6bcfef9
JS
2560 }
2561 }
48837e29
DE
2562 else if (count == 31)
2563 {
dd69e230 2564 if (TARGET_H8300)
48837e29 2565 {
dd69e230
KH
2566 switch (shift_type)
2567 {
2568 case SHIFT_ASHIFT:
2569 info->special = "sub.w\t%e0,%e0\n\tshlr\t%w0\n\tmov.w\t%e0,%f0\n\trotxr\t%z0";
2570 goto end;
2571 case SHIFT_LSHIFTRT:
2572 info->special = "sub.w\t%f0,%f0\n\tshll\t%z0\n\tmov.w\t%f0,%e0\n\trotxl\t%w0";
2573 goto end;
2574 case SHIFT_ASHIFTRT:
2575 info->special = "shll\t%z0\n\tsubx\t%w0,%w0\n\tmov.b\t%w0,%x0\n\tmov.w\t%f0,%e0";
2576 goto end;
2577 }
48837e29
DE
2578 }
2579 else
2580 {
dd69e230 2581 switch (shift_type)
48837e29 2582 {
dd69e230
KH
2583 case SHIFT_ASHIFT:
2584 info->special = "shlr.l\t%S0\n\txor.l\t%S0,%S0\n\trotxr.l\t%S0";
2585 goto end;
2586 case SHIFT_LSHIFTRT:
2587 info->special = "shll.l\t%S0\n\txor.l\t%S0,%S0\n\trotxl.l\t%S0";
2588 goto end;
2589 case SHIFT_ASHIFTRT:
2590 info->special = "shll\t%e0\n\tsubx\t%w0,%w0\n\tmov.b\t%w0,%x0\n\tmov.w\t%f0,%e0";
692b7eb3 2591 goto end;
48837e29 2592 }
48837e29
DE
2593 }
2594 }
769828ab 2595 abort ();
51c0c1d7 2596
48837e29
DE
2597 default:
2598 abort ();
07aae5c2 2599 }
48837e29 2600
cb33eb17
KH
2601 end:
2602 if (!TARGET_H8300S)
2603 info->shift2 = NULL;
07aae5c2
SC
2604}
2605
48837e29
DE
2606/* Emit the assembler code for doing shifts. */
2607
441d04c6 2608const char *
1a275226 2609output_a_shift (operands)
48837e29 2610 rtx *operands;
07aae5c2 2611{
48837e29 2612 static int loopend_lab;
48837e29
DE
2613 rtx shift = operands[3];
2614 enum machine_mode mode = GET_MODE (shift);
2615 enum rtx_code code = GET_CODE (shift);
2616 enum shift_type shift_type;
2617 enum shift_mode shift_mode;
35fb3d1f 2618 struct shift_info info;
48837e29
DE
2619
2620 loopend_lab++;
2621
2622 switch (mode)
2623 {
2624 case QImode:
2625 shift_mode = QIshift;
2626 break;
2627 case HImode:
2628 shift_mode = HIshift;
2629 break;
2630 case SImode:
2631 shift_mode = SIshift;
2632 break;
2633 default:
2634 abort ();
2635 }
07aae5c2 2636
48837e29 2637 switch (code)
07aae5c2 2638 {
48837e29
DE
2639 case ASHIFTRT:
2640 shift_type = SHIFT_ASHIFTRT;
2641 break;
2642 case LSHIFTRT:
2643 shift_type = SHIFT_LSHIFTRT;
2644 break;
2645 case ASHIFT:
2646 shift_type = SHIFT_ASHIFT;
2647 break;
2648 default:
2649 abort ();
2650 }
07aae5c2 2651
48837e29
DE
2652 if (GET_CODE (operands[2]) != CONST_INT)
2653 {
07e4d94e 2654 /* Indexing by reg, so have to loop and test at top. */
48837e29
DE
2655 output_asm_insn ("mov.b %X2,%X4", operands);
2656 fprintf (asm_out_file, "\tble .Lle%d\n", loopend_lab);
2657
2658 /* Get the assembler code to do one shift. */
35fb3d1f 2659 get_shift_alg (shift_type, shift_mode, 1, &info);
b5eaf9ba
KH
2660
2661 fprintf (asm_out_file, ".Llt%d:\n", loopend_lab);
35fb3d1f 2662 output_asm_insn (info.shift1, operands);
b5eaf9ba
KH
2663 output_asm_insn ("add #0xff,%X4", operands);
2664 fprintf (asm_out_file, "\tbne .Llt%d\n", loopend_lab);
2665 fprintf (asm_out_file, ".Lle%d:\n", loopend_lab);
2666
2667 return "";
48837e29
DE
2668 }
2669 else
2670 {
2671 int n = INTVAL (operands[2]);
48837e29
DE
2672
2673 /* If the count is negative, make it 0. */
2674 if (n < 0)
2675 n = 0;
2676 /* If the count is too big, truncate it.
2677 ANSI says shifts of GET_MODE_BITSIZE are undefined - we choose to
2678 do the intuitive thing. */
64530b82 2679 else if ((unsigned int) n > GET_MODE_BITSIZE (mode))
48837e29
DE
2680 n = GET_MODE_BITSIZE (mode);
2681
cb33eb17 2682 get_shift_alg (shift_type, shift_mode, n, &info);
48837e29 2683
cb33eb17 2684 switch (info.alg)
48837e29 2685 {
cb33eb17
KH
2686 case SHIFT_SPECIAL:
2687 output_asm_insn (info.special, operands);
2688 /* Fall through. */
2689
48837e29 2690 case SHIFT_INLINE:
cb33eb17
KH
2691 n = info.remainder;
2692
51c0c1d7 2693 /* Emit two bit shifts first. */
1a275226 2694 if (info.shift2 != NULL)
51c0c1d7 2695 {
1a275226
KH
2696 for (; n > 1; n -= 2)
2697 output_asm_insn (info.shift2, operands);
51c0c1d7
JL
2698 }
2699
2700 /* Now emit one bit shifts for any residual. */
1a275226
KH
2701 for (; n > 0; n--)
2702 output_asm_insn (info.shift1, operands);
51c0c1d7
JL
2703
2704 /* Keep track of CC. */
35fb3d1f 2705 if (info.cc_valid_p)
269c14e1
DE
2706 {
2707 cc_status.value1 = operands[0];
35fb3d1f 2708 cc_status.flags |= info.cc_valid_p;
269c14e1 2709 }
48837e29 2710 return "";
51c0c1d7 2711
48837e29
DE
2712 case SHIFT_ROT_AND:
2713 {
2714 int m = GET_MODE_BITSIZE (mode) - n;
2715 int mask = (shift_type == SHIFT_ASHIFT
1a275226
KH
2716 ? ((1 << m) - 1) << n
2717 : (1 << m) - 1);
48837e29 2718 char insn_buf[200];
b5eaf9ba 2719
48837e29
DE
2720 /* Not all possibilities of rotate are supported. They shouldn't
2721 be generated, but let's watch for 'em. */
35fb3d1f 2722 if (info.shift1 == 0)
48837e29 2723 abort ();
51c0c1d7
JL
2724
2725 /* Emit two bit rotates first. */
1a275226 2726 if (info.shift2 != NULL)
51c0c1d7 2727 {
1a275226
KH
2728 for (; m > 1; m -= 2)
2729 output_asm_insn (info.shift2, operands);
51c0c1d7
JL
2730 }
2731
2732 /* Now single bit rotates for any residual. */
1a275226
KH
2733 for (; m > 0; m--)
2734 output_asm_insn (info.shift1, operands);
51c0c1d7
JL
2735
2736 /* Now mask off the high bits. */
48837e29
DE
2737 if (TARGET_H8300)
2738 {
2739 switch (mode)
2740 {
2741 case QImode:
3e39bdb9 2742 sprintf (insn_buf, "and\t#%d,%%X0", mask);
48837e29 2743 cc_status.value1 = operands[0];
065bbfe6 2744 cc_status.flags |= CC_NO_CARRY;
48837e29
DE
2745 break;
2746 case HImode:
3e39bdb9 2747 sprintf (insn_buf, "and\t#%d,%%s0\n\tand\t#%d,%%t0",
441d04c6 2748 mask & 255, mask >> 8);
48837e29 2749 break;
441d04c6 2750 default:
1a275226 2751 abort ();
48837e29
DE
2752 }
2753 }
2754 else
2755 {
3e39bdb9 2756 sprintf (insn_buf, "and.%c\t#%d,%%%c0",
48837e29
DE
2757 "bwl"[shift_mode], mask,
2758 mode == QImode ? 'X' : mode == HImode ? 'T' : 'S');
2759 cc_status.value1 = operands[0];
065bbfe6 2760 cc_status.flags |= CC_NO_CARRY;
48837e29
DE
2761 }
2762 output_asm_insn (insn_buf, operands);
2763 return "";
2764 }
b5eaf9ba 2765
b5eaf9ba
KH
2766 case SHIFT_LOOP:
2767 /* A loop to shift by a "large" constant value.
2768 If we have shift-by-2 insns, use them. */
35fb3d1f 2769 if (info.shift2 != NULL)
b5eaf9ba
KH
2770 {
2771 fprintf (asm_out_file, "\tmov.b #%d,%sl\n", n / 2,
2772 names_big[REGNO (operands[4])]);
2773 fprintf (asm_out_file, ".Llt%d:\n", loopend_lab);
35fb3d1f 2774 output_asm_insn (info.shift2, operands);
b5eaf9ba
KH
2775 output_asm_insn ("add #0xff,%X4", operands);
2776 fprintf (asm_out_file, "\tbne .Llt%d\n", loopend_lab);
2777 if (n % 2)
35fb3d1f 2778 output_asm_insn (info.shift1, operands);
b5eaf9ba
KH
2779 }
2780 else
2781 {
2782 fprintf (asm_out_file, "\tmov.b #%d,%sl\n", n,
2783 names_big[REGNO (operands[4])]);
2784 fprintf (asm_out_file, ".Llt%d:\n", loopend_lab);
35fb3d1f 2785 output_asm_insn (info.shift1, operands);
b5eaf9ba
KH
2786 output_asm_insn ("add #0xff,%X4", operands);
2787 fprintf (asm_out_file, "\tbne .Llt%d\n", loopend_lab);
2788 }
51c0c1d7 2789 return "";
b5eaf9ba
KH
2790
2791 default:
2792 abort ();
51c0c1d7 2793 }
07aae5c2 2794 }
07aae5c2 2795}
48837e29 2796\f
edd71f0f
KH
2797/* A rotation by a non-constant will cause a loop to be generated, in
2798 which a rotation by one bit is used. A rotation by a constant,
2799 including the one in the loop, will be taken care of by
2800 emit_a_rotate () at the insn emit time. */
2801
2802int
2803expand_a_rotate (code, operands)
a11d9dfc 2804 enum rtx_code code;
edd71f0f
KH
2805 rtx operands[];
2806{
2807 rtx dst = operands[0];
2808 rtx src = operands[1];
2809 rtx rotate_amount = operands[2];
2810 enum machine_mode mode = GET_MODE (dst);
2811 rtx tmp;
2812
2813 /* We rotate in place. */
2814 emit_move_insn (dst, src);
2815
2816 if (GET_CODE (rotate_amount) != CONST_INT)
2817 {
2818 rtx counter = gen_reg_rtx (QImode);
2819 rtx start_label = gen_label_rtx ();
2820 rtx end_label = gen_label_rtx ();
2821
2822 /* If the rotate amount is less than or equal to 0,
2823 we go out of the loop. */
d43e0b7d
RK
2824 emit_cmp_and_jump_insns (rotate_amount, GEN_INT (0), LE, NULL_RTX,
2825 QImode, 0, end_label);
edd71f0f
KH
2826
2827 /* Initialize the loop counter. */
2828 emit_move_insn (counter, rotate_amount);
2829
2830 emit_label (start_label);
2831
2832 /* Rotate by one bit. */
2833 tmp = gen_rtx (code, mode, dst, GEN_INT (1));
2834 emit_insn (gen_rtx_SET (mode, dst, tmp));
2835
2836 /* Decrement the counter by 1. */
2837 tmp = gen_rtx_PLUS (QImode, counter, GEN_INT (-1));
2838 emit_insn (gen_rtx_SET (VOIDmode, counter, tmp));
2839
2840 /* If the loop counter is non-zero, we go back to the beginning
2841 of the loop. */
d43e0b7d
RK
2842 emit_cmp_and_jump_insns (counter, GEN_INT (0), NE, NULL_RTX, QImode, 1,
2843 start_label);
edd71f0f
KH
2844
2845 emit_label (end_label);
2846 }
2847 else
2848 {
2849 /* Rotate by AMOUNT bits. */
2850 tmp = gen_rtx (code, mode, dst, rotate_amount);
2851 emit_insn (gen_rtx_SET (mode, dst, tmp));
2852 }
2853
2854 return 1;
2855}
2856
2857/* Emit rotate insns. */
2858
2859const char *
2860emit_a_rotate (code, operands)
a11d9dfc 2861 enum rtx_code code;
edd71f0f
KH
2862 rtx *operands;
2863{
2864 rtx dst = operands[0];
2865 rtx rotate_amount = operands[2];
2866 enum shift_mode rotate_mode;
2867 enum shift_type rotate_type;
2868 const char *insn_buf;
2869 int bits;
2870 int amount;
2871 enum machine_mode mode = GET_MODE (dst);
2872
2873 if (GET_CODE (rotate_amount) != CONST_INT)
2874 abort ();
2875
2876 switch (mode)
2877 {
2878 case QImode:
2879 rotate_mode = QIshift;
2880 break;
2881 case HImode:
2882 rotate_mode = HIshift;
2883 break;
2884 case SImode:
2885 rotate_mode = SIshift;
2886 break;
2887 default:
2888 abort ();
2889 }
2890
2891 switch (code)
2892 {
2893 case ROTATERT:
2894 rotate_type = SHIFT_ASHIFT;
2895 break;
2896 case ROTATE:
2897 rotate_type = SHIFT_LSHIFTRT;
2898 break;
2899 default:
2900 abort ();
2901 }
2902
2903 amount = INTVAL (rotate_amount);
2904
2905 /* Clean up AMOUNT. */
2906 if (amount < 0)
2907 amount = 0;
2908 if ((unsigned int) amount > GET_MODE_BITSIZE (mode))
2909 amount = GET_MODE_BITSIZE (mode);
2910
2911 /* Determine the faster direction. After this phase, amount will be
2912 at most a half of GET_MODE_BITSIZE (mode). */
aefc5826 2913 if ((unsigned int) amount > GET_MODE_BITSIZE (mode) / 2U)
edd71f0f
KH
2914 {
2915 /* Flip the direction. */
2916 amount = GET_MODE_BITSIZE (mode) - amount;
2917 rotate_type =
2918 (rotate_type == SHIFT_ASHIFT) ? SHIFT_LSHIFTRT : SHIFT_ASHIFT;
2919 }
2920
2921 /* See if a byte swap (in HImode) or a word swap (in SImode) can
2922 boost up the rotation. */
2923 if ((mode == HImode && TARGET_H8300 && amount >= 5)
2924 || (mode == HImode && TARGET_H8300H && amount >= 6)
2925 || (mode == HImode && TARGET_H8300S && amount == 8)
2926 || (mode == SImode && TARGET_H8300H && amount >= 10)
2927 || (mode == SImode && TARGET_H8300S && amount >= 13))
2928 {
2929 switch (mode)
2930 {
2931 case HImode:
2932 /* This code works on any family. */
2933 insn_buf = "xor.b\t%s0,%t0\n\txor.b\t%t0,%s0\n\txor.b\t%s0,%t0";
2934 output_asm_insn (insn_buf, operands);
2935 break;
2936
2937 case SImode:
2938 /* This code works on the H8/300H and H8/S. */
2939 insn_buf = "xor.w\t%e0,%f0\n\txor.w\t%f0,%e0\n\txor.w\t%e0,%f0";
2940 output_asm_insn (insn_buf, operands);
2941 break;
2942
2943 default:
2944 abort ();
2945 }
2946
2947 /* Adjust AMOUNT and flip the direction. */
2948 amount = GET_MODE_BITSIZE (mode) / 2 - amount;
2949 rotate_type =
2950 (rotate_type == SHIFT_ASHIFT) ? SHIFT_LSHIFTRT : SHIFT_ASHIFT;
2951 }
2952
2953 /* Emit rotate insns. */
2954 for (bits = TARGET_H8300S ? 2 : 1; bits > 0; bits /= 2)
2955 {
2956 if (bits == 2)
2957 insn_buf = rotate_two[rotate_type][rotate_mode];
2958 else
2959 insn_buf = rotate_one[cpu_type][rotate_type][rotate_mode];
2c54abce 2960
edd71f0f
KH
2961 for (; amount >= bits; amount -= bits)
2962 output_asm_insn (insn_buf, operands);
2963 }
2964
2965 return "";
2966}
2967\f
48837e29 2968/* Fix the operands of a gen_xxx so that it could become a bit
2c54abce 2969 operating insn. */
07aae5c2
SC
2970
2971int
48837e29
DE
2972fix_bit_operand (operands, what, type)
2973 rtx *operands;
441d04c6 2974 int what;
48837e29 2975 enum rtx_code type;
07aae5c2 2976{
abc95ed3 2977 /* The bit_operand predicate accepts any memory during RTL generation, but
48837e29
DE
2978 only 'U' memory afterwards, so if this is a MEM operand, we must force
2979 it to be valid for 'U' by reloading the address. */
07aae5c2 2980
48837e29 2981 if (GET_CODE (operands[2]) == CONST_INT)
07aae5c2 2982 {
48837e29
DE
2983 if (CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), what))
2984 {
2985 /* Ok to have a memory dest. */
1a63219b
KH
2986 if (GET_CODE (operands[0]) == MEM
2987 && !EXTRA_CONSTRAINT (operands[0], 'U'))
48837e29 2988 {
c5c76735
JL
2989 rtx mem = gen_rtx_MEM (GET_MODE (operands[0]),
2990 copy_to_mode_reg (Pmode,
2991 XEXP (operands[0], 0)));
c6df88cb 2992 MEM_COPY_ATTRIBUTES (mem, operands[0]);
48837e29
DE
2993 operands[0] = mem;
2994 }
2995
1a63219b
KH
2996 if (GET_CODE (operands[1]) == MEM
2997 && !EXTRA_CONSTRAINT (operands[1], 'U'))
48837e29 2998 {
c5c76735
JL
2999 rtx mem = gen_rtx_MEM (GET_MODE (operands[1]),
3000 copy_to_mode_reg (Pmode,
3001 XEXP (operands[1], 0)));
c6df88cb 3002 MEM_COPY_ATTRIBUTES (mem, operands[0]);
48837e29
DE
3003 operands[1] = mem;
3004 }
3005 return 0;
3006 }
3007 }
07aae5c2 3008
48837e29 3009 /* Dest and src op must be register. */
07aae5c2 3010
48837e29
DE
3011 operands[1] = force_reg (QImode, operands[1]);
3012 {
3013 rtx res = gen_reg_rtx (QImode);
c5c76735
JL
3014 emit_insn (gen_rtx_SET (VOIDmode, res,
3015 gen_rtx (type, QImode, operands[1], operands[2])));
3016 emit_insn (gen_rtx_SET (VOIDmode, operands[0], res));
48837e29
DE
3017 }
3018 return 1;
07aae5c2 3019}
f5b65a56 3020
f5b65a56
JL
3021/* Return nonzero if FUNC is an interrupt function as specified
3022 by the "interrupt" attribute. */
3023
3024static int
3025h8300_interrupt_function_p (func)
3026 tree func;
3027{
3028 tree a;
3029
3030 if (TREE_CODE (func) != FUNCTION_DECL)
3031 return 0;
3032
91d231cb 3033 a = lookup_attribute ("interrupt_handler", DECL_ATTRIBUTES (func));
f5b65a56
JL
3034 return a != NULL_TREE;
3035}
3036
fabe72bb
JL
3037/* Return nonzero if FUNC is an OS_Task function as specified
3038 by the "OS_Task" attribute. */
3039
3040static int
3041h8300_os_task_function_p (func)
3042 tree func;
3043{
3044 tree a;
3045
3046 if (TREE_CODE (func) != FUNCTION_DECL)
3047 return 0;
3048
91d231cb 3049 a = lookup_attribute ("OS_Task", DECL_ATTRIBUTES (func));
fabe72bb
JL
3050 return a != NULL_TREE;
3051}
3052
3053/* Return nonzero if FUNC is a monitor function as specified
3054 by the "monitor" attribute. */
3055
3056static int
3057h8300_monitor_function_p (func)
3058 tree func;
3059{
3060 tree a;
3061
3062 if (TREE_CODE (func) != FUNCTION_DECL)
3063 return 0;
3064
91d231cb 3065 a = lookup_attribute ("monitor", DECL_ATTRIBUTES (func));
fabe72bb
JL
3066 return a != NULL_TREE;
3067}
3068
f5b65a56
JL
3069/* Return nonzero if FUNC is a function that should be called
3070 through the function vector. */
3071
3072int
3073h8300_funcvec_function_p (func)
3074 tree func;
3075{
3076 tree a;
3077
3078 if (TREE_CODE (func) != FUNCTION_DECL)
3079 return 0;
3080
91d231cb 3081 a = lookup_attribute ("function_vector", DECL_ATTRIBUTES (func));
f5b65a56
JL
3082 return a != NULL_TREE;
3083}
3084
887a8bd9 3085/* Return nonzero if DECL is a variable that's in the eight bit
15dc331e
JL
3086 data area. */
3087
3088int
fabdc32d 3089h8300_eightbit_data_p (decl)
15dc331e
JL
3090 tree decl;
3091{
3092 tree a;
3093
3094 if (TREE_CODE (decl) != VAR_DECL)
3095 return 0;
3096
91d231cb 3097 a = lookup_attribute ("eightbit_data", DECL_ATTRIBUTES (decl));
15dc331e
JL
3098 return a != NULL_TREE;
3099}
3100
887a8bd9
JL
3101/* Return nonzero if DECL is a variable that's in the tiny
3102 data area. */
3103
3104int
3105h8300_tiny_data_p (decl)
3106 tree decl;
3107{
3108 tree a;
3109
3110 if (TREE_CODE (decl) != VAR_DECL)
3111 return 0;
3112
91d231cb 3113 a = lookup_attribute ("tiny_data", DECL_ATTRIBUTES (decl));
887a8bd9
JL
3114 return a != NULL_TREE;
3115}
3116
91d231cb 3117/* Supported attributes:
f5b65a56 3118
97c5ec1d 3119 interrupt_handler: output a prologue and epilogue suitable for an
f5b65a56
JL
3120 interrupt handler.
3121
97c5ec1d 3122 function_vector: This function should be called through the
887a8bd9
JL
3123 function vector.
3124
3125 eightbit_data: This variable lives in the 8-bit data area and can
3126 be referenced with 8-bit absolute memory addresses.
3127
3128 tiny_data: This variable lives in the tiny data area and can be
3129 referenced with 16-bit absolute memory references. */
f5b65a56 3130
91d231cb 3131const struct attribute_spec h8300_attribute_table[] =
f5b65a56 3132{
91d231cb
JM
3133 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
3134 { "interrupt_handler", 0, 0, true, false, false, h8300_handle_fndecl_attribute },
3135 { "OS_Task", 0, 0, true, false, false, h8300_handle_fndecl_attribute },
3136 { "monitor", 0, 0, true, false, false, h8300_handle_fndecl_attribute },
3137 { "function_vector", 0, 0, true, false, false, h8300_handle_fndecl_attribute },
3138 { "eightbit_data", 0, 0, true, false, false, h8300_handle_eightbit_data_attribute },
3139 { "tiny_data", 0, 0, true, false, false, h8300_handle_tiny_data_attribute },
3140 { NULL, 0, 0, false, false, false, NULL }
3141};
f5b65a56 3142
15dc331e 3143
91d231cb
JM
3144/* Handle an attribute requiring a FUNCTION_DECL; arguments as in
3145 struct attribute_spec.handler. */
3146static tree
3147h8300_handle_fndecl_attribute (node, name, args, flags, no_add_attrs)
3148 tree *node;
3149 tree name;
3150 tree args ATTRIBUTE_UNUSED;
3151 int flags ATTRIBUTE_UNUSED;
3152 bool *no_add_attrs;
3153{
3154 if (TREE_CODE (*node) != FUNCTION_DECL)
3155 {
3156 warning ("`%s' attribute only applies to functions",
3157 IDENTIFIER_POINTER (name));
3158 *no_add_attrs = true;
3159 }
3160
3161 return NULL_TREE;
3162}
3163
3164/* Handle an "eightbit_data" attribute; arguments as in
3165 struct attribute_spec.handler. */
3166static tree
3167h8300_handle_eightbit_data_attribute (node, name, args, flags, no_add_attrs)
3168 tree *node;
3169 tree name;
3170 tree args ATTRIBUTE_UNUSED;
3171 int flags ATTRIBUTE_UNUSED;
3172 bool *no_add_attrs;
3173{
3174 tree decl = *node;
3175
3176 if (TREE_STATIC (decl) || DECL_EXTERNAL (decl))
15dc331e 3177 {
64378c91 3178 DECL_SECTION_NAME (decl) = build_string (7, ".eight");
91d231cb
JM
3179 }
3180 else
3181 {
3182 warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
3183 *no_add_attrs = true;
887a8bd9
JL
3184 }
3185
91d231cb
JM
3186 return NULL_TREE;
3187}
3188
3189/* Handle an "tiny_data" attribute; arguments as in
3190 struct attribute_spec.handler. */
3191static tree
3192h8300_handle_tiny_data_attribute (node, name, args, flags, no_add_attrs)
3193 tree *node;
3194 tree name;
3195 tree args ATTRIBUTE_UNUSED;
3196 int flags ATTRIBUTE_UNUSED;
3197 bool *no_add_attrs;
3198{
3199 tree decl = *node;
3200
3201 if (TREE_STATIC (decl) || DECL_EXTERNAL (decl))
887a8bd9 3202 {
64378c91 3203 DECL_SECTION_NAME (decl) = build_string (6, ".tiny");
91d231cb
JM
3204 }
3205 else
3206 {
3207 warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
3208 *no_add_attrs = true;
15dc331e 3209 }
07e4d94e 3210
91d231cb 3211 return NULL_TREE;
f5b65a56
JL
3212}
3213
441d04c6 3214void
887a8bd9
JL
3215h8300_encode_label (decl)
3216 tree decl;
3217{
441d04c6 3218 const char *str = XSTR (XEXP (DECL_RTL (decl), 0), 0);
887a8bd9 3219 int len = strlen (str);
93cacb72 3220 char *newstr = alloca (len + 2);
887a8bd9 3221
93cacb72
KH
3222 newstr[0] = '&';
3223 strcpy (&newstr[1], str);
887a8bd9 3224
93cacb72
KH
3225 XSTR (XEXP (DECL_RTL (decl), 0), 0) =
3226 ggc_alloc_string (newstr, len + 1);
887a8bd9
JL
3227}
3228
441d04c6 3229const char *
871f73e3 3230output_simode_bld (bild, operands)
bd93f126 3231 int bild;
bd93f126
JL
3232 rtx operands[];
3233{
6be580c7
KH
3234 if (TARGET_H8300)
3235 {
3236 /* Clear the destination register. */
3237 output_asm_insn ("sub.w\t%e0,%e0\n\tsub.w\t%f0,%f0", operands);
3238
3239 /* Now output the bit load or bit inverse load, and store it in
3240 the destination. */
3241 if (bild)
3242 output_asm_insn ("bild\t%Z2,%Y1", operands);
3243 else
3244 output_asm_insn ("bld\t%Z2,%Y1", operands);
bd93f126 3245
6be580c7
KH
3246 output_asm_insn ("bst\t#0,%w0", operands);
3247 }
bd93f126 3248 else
6be580c7
KH
3249 {
3250 /* Output the bit load or bit inverse load. */
3251 if (bild)
3252 output_asm_insn ("bild\t%Z2,%Y1", operands);
3253 else
3254 output_asm_insn ("bld\t%Z2,%Y1", operands);
3255
3256 /* Clear the destination register and perform the bit store. */
3257 output_asm_insn ("xor.l\t%S0,%S0\n\tbst\t#0,%w0", operands);
3258 }
bd93f126
JL
3259
3260 /* All done. */
3261 return "";
3262}
e6219736 3263
9ec36da5 3264/* Given INSN and its current length LENGTH, return the adjustment
e6219736
JL
3265 (in bytes) to correctly compute INSN's length.
3266
3267 We use this to get the lengths of various memory references correct. */
3268
441d04c6 3269int
e6219736
JL
3270h8300_adjust_insn_length (insn, length)
3271 rtx insn;
441d04c6 3272 int length ATTRIBUTE_UNUSED;
e6219736 3273{
5fc4b751 3274 rtx pat = PATTERN (insn);
04b6000c 3275
e32815aa 3276 /* We must filter these out before calling get_attr_adjust_length. */
5fc4b751
KH
3277 if (GET_CODE (pat) == USE
3278 || GET_CODE (pat) == CLOBBER
3279 || GET_CODE (pat) == SEQUENCE
3280 || GET_CODE (pat) == ADDR_VEC
3281 || GET_CODE (pat) == ADDR_DIFF_VEC)
47cf37f9
JL
3282 return 0;
3283
04b6000c
VM
3284 if (get_attr_adjust_length (insn) == ADJUST_LENGTH_NO)
3285 return 0;
3286
e6219736
JL
3287 /* Adjust length for reg->mem and mem->reg copies. */
3288 if (GET_CODE (pat) == SET
3289 && (GET_CODE (SET_SRC (pat)) == MEM
3290 || GET_CODE (SET_DEST (pat)) == MEM))
3291 {
3292 /* This insn might need a length adjustment. */
3293 rtx addr;
3294
3295 if (GET_CODE (SET_SRC (pat)) == MEM)
3296 addr = XEXP (SET_SRC (pat), 0);
3297 else
3298 addr = XEXP (SET_DEST (pat), 0);
3299
3300 /* On the H8/300, only one adjustment is necessary; if the
3301 address mode is register indirect, then this insn is two
3302 bytes shorter than indicated in the machine description. */
3303 if (TARGET_H8300 && GET_CODE (addr) == REG)
3304 return -2;
3305
a1616dd9 3306 /* On the H8/300H and H8/S, register indirect is 6 bytes shorter than
e6219736 3307 indicated in the machine description. */
a1616dd9
JL
3308 if ((TARGET_H8300H || TARGET_H8300S)
3309 && GET_CODE (addr) == REG)
e6219736
JL
3310 return -6;
3311
9bf7ec4e
KH
3312 /* On the H8/300H and H8/S, reg + d, for small displacements is
3313 4 bytes shorter than indicated in the machine description. */
a1616dd9 3314 if ((TARGET_H8300H || TARGET_H8300S)
e6219736
JL
3315 && GET_CODE (addr) == PLUS
3316 && GET_CODE (XEXP (addr, 0)) == REG
3317 && GET_CODE (XEXP (addr, 1)) == CONST_INT
3318 && INTVAL (XEXP (addr, 1)) > -32768
3319 && INTVAL (XEXP (addr, 1)) < 32767)
3320 return -4;
887a8bd9 3321
9bf7ec4e 3322 /* On the H8/300H and H8/S, abs:16 is two bytes shorter than the
887a8bd9 3323 more general abs:24. */
a1616dd9 3324 if ((TARGET_H8300H || TARGET_H8300S)
887a8bd9
JL
3325 && GET_CODE (addr) == SYMBOL_REF
3326 && TINY_DATA_NAME_P (XSTR (addr, 0)))
3327 return -2;
e6219736
JL
3328 }
3329
3330 /* Loading some constants needs adjustment. */
3331 if (GET_CODE (pat) == SET
3332 && GET_CODE (SET_SRC (pat)) == CONST_INT
3333 && GET_MODE (SET_DEST (pat)) == SImode
3334 && INTVAL (SET_SRC (pat)) != 0)
3335 {
64530b82
KH
3336 int val = INTVAL (SET_SRC (pat));
3337
e6219736 3338 if (TARGET_H8300
64530b82
KH
3339 && ((val & 0xffff) == 0
3340 || ((val >> 16) & 0xffff) == 0))
e6219736
JL
3341 return -2;
3342
a1616dd9 3343 if (TARGET_H8300H || TARGET_H8300S)
e6219736 3344 {
e6219736
JL
3345 if (val == (val & 0xff)
3346 || val == (val & 0xff00))
86039100 3347 return 4 - 6;
e6219736 3348
86039100
KH
3349 switch (val & 0xffffffff)
3350 {
3351 case 0xffffffff:
3352 case 0xfffffffe:
3353 case 0xfffffffc:
3354 case 0x0000ffff:
3355 case 0x0000fffe:
3356 case 0xffff0000:
3357 case 0xfffe0000:
3358 case 0x00010000:
3359 case 0x00020000:
3360 return 4 - 6;
3361 }
e6219736
JL
3362 }
3363 }
3364
dd4fd0a0
JL
3365 /* Shifts need various adjustments. */
3366 if (GET_CODE (pat) == PARALLEL
3367 && GET_CODE (XVECEXP (pat, 0, 0)) == SET
3368 && (GET_CODE (SET_SRC (XVECEXP (pat, 0, 0))) == ASHIFTRT
07e4d94e
KH
3369 || GET_CODE (SET_SRC (XVECEXP (pat, 0, 0))) == LSHIFTRT
3370 || GET_CODE (SET_SRC (XVECEXP (pat, 0, 0))) == ASHIFT))
dd4fd0a0
JL
3371 {
3372 rtx src = SET_SRC (XVECEXP (pat, 0, 0));
3373 enum machine_mode mode = GET_MODE (src);
04b6000c 3374 int shift;
dd4fd0a0
JL
3375
3376 if (GET_CODE (XEXP (src, 1)) != CONST_INT)
3377 return 0;
3378
04b6000c
VM
3379 shift = INTVAL (XEXP (src, 1));
3380 /* According to ANSI, negative shift is undefined. It is
3381 considered to be zero in this case (see function
af3c90a6 3382 output_a_shift above). */
04b6000c
VM
3383 if (shift < 0)
3384 shift = 0;
3385
dd4fd0a0
JL
3386 /* QImode shifts by small constants take one insn
3387 per shift. So the adjustment is 20 (md length) -
3388 # shifts * 2. */
04b6000c
VM
3389 if (mode == QImode && shift <= 4)
3390 return -(20 - shift * 2);
dd4fd0a0 3391
9bf7ec4e
KH
3392 /* Similarly for HImode and SImode shifts by small constants on
3393 the H8/300H and H8/S. */
a1616dd9 3394 if ((TARGET_H8300H || TARGET_H8300S)
04b6000c
VM
3395 && (mode == HImode || mode == SImode) && shift <= 4)
3396 return -(20 - shift * 2);
dd4fd0a0
JL
3397
3398 /* HImode shifts by small constants for the H8/300. */
04b6000c
VM
3399 if (mode == HImode && shift <= 4)
3400 return -(20 - (shift * (GET_CODE (src) == ASHIFT ? 2 : 4)));
dd4fd0a0
JL
3401
3402 /* SImode shifts by small constants for the H8/300. */
04b6000c
VM
3403 if (mode == SImode && shift <= 2)
3404 return -(20 - (shift * (GET_CODE (src) == ASHIFT ? 6 : 8)));
dd4fd0a0
JL
3405
3406 /* XXX ??? Could check for more shift/rotate cases here. */
3407 }
07e4d94e 3408
edd71f0f
KH
3409 /* Rotations need various adjustments. */
3410 if (GET_CODE (pat) == SET
3411 && (GET_CODE (SET_SRC (pat)) == ROTATE
3412 || GET_CODE (SET_SRC (pat)) == ROTATERT))
3413 {
3414 rtx src = SET_SRC (pat);
3415 enum machine_mode mode = GET_MODE (src);
3416 int amount;
3417 int states = 0;
3418
3419 if (GET_CODE (XEXP (src, 1)) != CONST_INT)
3420 return 0;
3421
3422 amount = INTVAL (XEXP (src, 1));
3423
3424 /* Clean up AMOUNT. */
3425 if (amount < 0)
3426 amount = 0;
3427 if ((unsigned int) amount > GET_MODE_BITSIZE (mode))
3428 amount = GET_MODE_BITSIZE (mode);
3429
3430 /* Determine the faster direction. After this phase, amount
3431 will be at most a half of GET_MODE_BITSIZE (mode). */
aefc5826 3432 if ((unsigned int) amount > GET_MODE_BITSIZE (mode) / 2U)
edd71f0f
KH
3433 /* Flip the direction. */
3434 amount = GET_MODE_BITSIZE (mode) - amount;
3435
3436 /* See if a byte swap (in HImode) or a word swap (in SImode) can
3437 boost up the rotation. */
3438 if ((mode == HImode && TARGET_H8300 && amount >= 5)
3439 || (mode == HImode && TARGET_H8300H && amount >= 6)
3440 || (mode == HImode && TARGET_H8300S && amount == 8)
3441 || (mode == SImode && TARGET_H8300H && amount >= 10)
3442 || (mode == SImode && TARGET_H8300S && amount >= 13))
3443 {
3444 /* Adjust AMOUNT and flip the direction. */
3445 amount = GET_MODE_BITSIZE (mode) / 2 - amount;
3446 states += 6;
3447 }
3448
3449 /* We use 2-bit rotatations on the H8/S. */
3450 if (TARGET_H8300S)
3451 amount = amount / 2 + amount % 2;
3452
3453 /* The H8/300 uses three insns to rotate one bit, taking 6
3454 states. */
3455 states += amount * ((TARGET_H8300 && mode == HImode) ? 6 : 2);
3456
3457 return -(20 - states);
3458 }
3459
e6219736
JL
3460 return 0;
3461}
7c262518 3462
ede75ee8 3463#ifndef OBJECT_FORMAT_ELF
7c262518 3464static void
715bdd29 3465h8300_asm_named_section (name, flags)
7c262518
RH
3466 const char *name;
3467 unsigned int flags ATTRIBUTE_UNUSED;
7c262518
RH
3468{
3469 /* ??? Perhaps we should be using default_coff_asm_named_section. */
3470 fprintf (asm_out_file, "\t.section %s\n", name);
3471}
ede75ee8 3472#endif /* ! OBJECT_FORMAT_ELF */