]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/h8300/h8300.c
Daily bump.
[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}
1630\f
48837e29
DE
1631/* Shifts.
1632
005e3e05
KH
1633 We devote a fair bit of code to getting efficient shifts since we
1634 can only shift one bit at a time on the H8/300 and H8/300H and only
1635 one or two bits at a time on the H8/S.
1636
1637 All shift code falls into one of the following ways of
1638 implementation:
1639
1640 o SHIFT_INLINE: Emit straight line code for the shift; this is used
1641 when a straight line shift is about the same size or smaller than
1642 a loop.
1643
1644 o SHIFT_ROT_AND: Rotate the value the opposite direction, then mask
1645 off the bits we don't need. This is used when only a few of the
1646 bits in the original value will survive in the shifted value.
1647
1648 o SHIFT_SPECIAL: Often it's possible to move a byte or a word to
1649 simulate a shift by 8, 16, or 24 bits. Once moved, a few inline
1650 shifts can be added if the shift count is slightly more than 8 or
1651 16. This case also includes other oddballs that are not worth
1652 explaning here.
1653
1654 o SHIFT_LOOP: Emit a loop using one (or two on H8/S) bit shifts.
1655
1656 Here are some thoughts on what the absolutely positively best code
1657 is. "Best" here means some rational trade-off between code size
1658 and speed, where speed is more preferred but not at the expense of
1659 generating 20 insns.
1660
1661 Below, a trailing '*' after the shift count indicates the "best"
1662 mode isn't implemented. We only describe SHIFT_SPECIAL cases to
1663 simplify the table. For other cases, refer to shift_alg_[qhs]i.
51c0c1d7 1664
48837e29 1665 H8/300 QImode shifts
005e3e05 1666 7 - ASHIFTRT: shll, subx (propagate carry bit to all bits)
48837e29
DE
1667
1668 H8/300 HImode shifts
51c0c1d7
JL
1669 7 - shift 2nd half other way into carry.
1670 copy 1st half into 2nd half
1671 rotate 2nd half other way with carry
1672 rotate 1st half other way (no carry)
1673 mask off bits in 1st half (ASHIFT | LSHIFTRT).
1674 sign extend 1st half (ASHIFTRT)
1675 8 - move byte, zero (ASHIFT | LSHIFTRT) or sign extend other (ASHIFTRT)
1676 9-12 - do shift by 8, inline remaining shifts
005e3e05 1677 15 - ASHIFTRT: shll, subx, set other byte
48837e29
DE
1678
1679 H8/300 SImode shifts
51c0c1d7
JL
1680 7* - shift other way once, move bytes into place,
1681 move carry into place (possibly with sign extension)
1682 8 - move bytes into place, zero or sign extend other
51c0c1d7
JL
1683 15* - shift other way once, move word into place, move carry into place
1684 16 - move word, zero or sign extend other
51c0c1d7 1685 24* - move bytes into place, zero or sign extend other
005e3e05 1686 31 - ASHIFTRT: shll top byte, subx, copy to other bytes
51c0c1d7
JL
1687
1688 H8/300H QImode shifts (same as H8/300 QImode shifts)
005e3e05 1689 7 - ASHIFTRT: shll, subx (propagate carry bit to all bits)
51c0c1d7 1690
48837e29 1691 H8/300H HImode shifts
51c0c1d7
JL
1692 7 - shift 2nd half other way into carry.
1693 copy 1st half into 2nd half
1694 rotate entire word other way using carry
1695 mask off remaining bits (ASHIFT | LSHIFTRT)
1696 sign extend remaining bits (ASHIFTRT)
1697 8 - move byte, zero (ASHIFT | LSHIFTRT) or sign extend other (ASHIFTRT)
1698 9-12 - do shift by 8, inline remaining shifts
005e3e05 1699 15 - ASHIFTRT: shll, subx, set other byte
48837e29
DE
1700
1701 H8/300H SImode shifts
1702 (These are complicated by the fact that we don't have byte level access to
1703 the top word.)
1704 A word is: bytes 3,2,1,0 (msb -> lsb), word 1,0 (msw -> lsw)
51c0c1d7
JL
1705 15* - shift other way once, move word into place, move carry into place
1706 (with sign extension for ASHIFTRT)
1707 16 - move word into place, zero or sign extend other
1708 17-20 - do 16bit shift, then inline remaining shifts
51c0c1d7
JL
1709 24* - ASHIFT: move byte 0(msb) to byte 1, zero byte 0,
1710 move word 0 to word 1, zero word 0
1711 LSHIFTRT: move word 1 to word 0, move byte 1 to byte 0,
1712 zero word 1, zero byte 1
1713 ASHIFTRT: move word 1 to word 0, move byte 1 to byte 0,
1714 sign extend byte 0, sign extend word 0
1715 25-27* - either loop, or
1716 do 24 bit shift, inline rest
51c0c1d7
JL
1717 31 - shll, subx byte 0, sign extend byte 0, sign extend word 0
1718
1719 H8/S QImode shifts
005e3e05 1720 7 - ASHIFTRT: shll, subx (propagate carry bit to all bits)
51c0c1d7
JL
1721
1722 H8/S HImode shifts
51c0c1d7
JL
1723 8 - move byte, zero (ASHIFT | LSHIFTRT) or sign extend other (ASHIFTRT)
1724 9-12 - do shift by 8, inline remaining shifts
005e3e05 1725 15 - ASHIFTRT: shll, subx, set other byte
51c0c1d7
JL
1726
1727 H8/S SImode shifts
1728 (These are complicated by the fact that we don't have byte level access to
1729 the top word.)
1730 A word is: bytes 3,2,1,0 (msb -> lsb), word 1,0 (msw -> lsw)
51c0c1d7
JL
1731 15* - shift other way once, move word into place, move carry into place
1732 (with sign extension for ASHIFTRT)
1733 16 - move word into place, zero or sign extend other
1734 17-20 - do 16bit shift, then inline remaining shifts
51c0c1d7
JL
1735 24* - ASHIFT: move byte 0(msb) to byte 1, zero byte 0,
1736 move word 0 to word 1, zero word 0
1737 LSHIFTRT: move word 1 to word 0, move byte 1 to byte 0,
1738 zero word 1, zero byte 1
1739 ASHIFTRT: move word 1 to word 0, move byte 1 to byte 0,
1740 sign extend byte 0, sign extend word 0
1741 25-27* - either loop, or
1742 do 24 bit shift, inline rest
51c0c1d7
JL
1743 31 - shll, subx byte 0, sign extend byte 0, sign extend word 0
1744
1745 Panic!!! */
07aae5c2
SC
1746
1747int
48837e29
DE
1748nshift_operator (x, mode)
1749 rtx x;
441d04c6 1750 enum machine_mode mode ATTRIBUTE_UNUSED;
48837e29
DE
1751{
1752 switch (GET_CODE (x))
1753 {
1754 case ASHIFTRT:
1755 case LSHIFTRT:
1756 case ASHIFT:
1757 return 1;
1758
1759 default:
1760 return 0;
1761 }
1762}
1763
1764/* Called from the .md file to emit code to do shifts.
64530b82
KH
1765 Return a boolean indicating success.
1766 (Currently this is always TRUE). */
48837e29
DE
1767
1768int
1769expand_a_shift (mode, code, operands)
1770 enum machine_mode mode;
07aae5c2
SC
1771 int code;
1772 rtx operands[];
07aae5c2 1773{
07aae5c2
SC
1774 emit_move_insn (operands[0], operands[1]);
1775
07e4d94e
KH
1776 /* Need a loop to get all the bits we want - we generate the
1777 code at emit time, but need to allocate a scratch reg now. */
48837e29 1778
c5c76735
JL
1779 emit_insn (gen_rtx_PARALLEL
1780 (VOIDmode,
48837e29 1781 gen_rtvec (2,
c5c76735
JL
1782 gen_rtx_SET (VOIDmode, operands[0],
1783 gen_rtx (code, mode, operands[0],
1784 operands[2])),
1785 gen_rtx_CLOBBER (VOIDmode,
1786 gen_rtx_SCRATCH (QImode)))));
48837e29
DE
1787
1788 return 1;
1789}
1790
005e3e05 1791/* See above for explanation of this enum. */
48837e29
DE
1792
1793enum shift_alg
1794{
1795 SHIFT_INLINE,
1796 SHIFT_ROT_AND,
1797 SHIFT_SPECIAL,
0c50ee73 1798 SHIFT_LOOP
48837e29
DE
1799};
1800
1801/* Symbols of the various shifts which can be used as indices. */
1802
1803enum shift_type
1a63219b
KH
1804{
1805 SHIFT_ASHIFT, SHIFT_LSHIFTRT, SHIFT_ASHIFTRT
1806};
48837e29
DE
1807
1808/* Symbols of the various modes which can be used as indices. */
1809
1810enum shift_mode
1a63219b
KH
1811{
1812 QIshift, HIshift, SIshift
1813};
48837e29 1814
269c14e1
DE
1815/* For single bit shift insns, record assembler and what bits of the
1816 condition code are valid afterwards (represented as various CC_FOO
1817 bits, 0 means CC isn't left in a usable state). */
48837e29
DE
1818
1819struct shift_insn
1820{
8b60264b
KG
1821 const char *const assembler;
1822 const int cc_valid;
48837e29
DE
1823};
1824
1825/* Assembler instruction shift table.
1826
1827 These tables are used to look up the basic shifts.
07e4d94e 1828 They are indexed by cpu, shift_type, and mode. */
07aae5c2 1829
48837e29
DE
1830static const struct shift_insn shift_one[2][3][3] =
1831{
1832/* H8/300 */
1833 {
1834/* SHIFT_ASHIFT */
1835 {
065bbfe6 1836 { "shll\t%X0", CC_NO_CARRY },
51c0c1d7
JL
1837 { "add.w\t%T0,%T0", CC_OVERFLOW_UNUSABLE | CC_NO_CARRY },
1838 { "add.w\t%f0,%f0\n\taddx\t%y0,%y0\n\taddx\t%z0,%z0", 0 }
48837e29
DE
1839 },
1840/* SHIFT_LSHIFTRT */
1841 {
065bbfe6 1842 { "shlr\t%X0", CC_NO_CARRY },
51c0c1d7
JL
1843 { "shlr\t%t0\n\trotxr\t%s0", 0 },
1844 { "shlr\t%z0\n\trotxr\t%y0\n\trotxr\t%x0\n\trotxr\t%w0", 0 }
48837e29
DE
1845 },
1846/* SHIFT_ASHIFTRT */
1847 {
51c0c1d7
JL
1848 { "shar\t%X0", CC_OVERFLOW_UNUSABLE | CC_NO_CARRY },
1849 { "shar\t%t0\n\trotxr\t%s0", 0 },
1850 { "shar\t%z0\n\trotxr\t%y0\n\trotxr\t%x0\n\trotxr\t%w0", 0 }
48837e29
DE
1851 }
1852 },
1853/* H8/300H */
1854 {
1855/* SHIFT_ASHIFT */
1856 {
065bbfe6
JL
1857 { "shll.b\t%X0", CC_NO_CARRY },
1858 { "shll.w\t%T0", CC_NO_CARRY },
1859 { "shll.l\t%S0", CC_NO_CARRY }
48837e29
DE
1860 },
1861/* SHIFT_LSHIFTRT */
1862 {
065bbfe6
JL
1863 { "shlr.b\t%X0", CC_NO_CARRY },
1864 { "shlr.w\t%T0", CC_NO_CARRY },
1865 { "shlr.l\t%S0", CC_NO_CARRY }
48837e29
DE
1866 },
1867/* SHIFT_ASHIFTRT */
1868 {
51c0c1d7
JL
1869 { "shar.b\t%X0", CC_OVERFLOW_UNUSABLE | CC_NO_CARRY },
1870 { "shar.w\t%T0", CC_OVERFLOW_UNUSABLE | CC_NO_CARRY },
1871 { "shar.l\t%S0", CC_OVERFLOW_UNUSABLE | CC_NO_CARRY }
48837e29
DE
1872 }
1873 }
1874};
07aae5c2 1875
51c0c1d7
JL
1876static const struct shift_insn shift_two[3][3] =
1877{
1878/* SHIFT_ASHIFT */
1879 {
065bbfe6
JL
1880 { "shll.b\t#2,%X0", CC_NO_CARRY },
1881 { "shll.w\t#2,%T0", CC_NO_CARRY },
1882 { "shll.l\t#2,%S0", CC_NO_CARRY }
51c0c1d7
JL
1883 },
1884/* SHIFT_LSHIFTRT */
1885 {
065bbfe6
JL
1886 { "shlr.b\t#2,%X0", CC_NO_CARRY },
1887 { "shlr.w\t#2,%T0", CC_NO_CARRY },
1888 { "shlr.l\t#2,%S0", CC_NO_CARRY }
51c0c1d7
JL
1889 },
1890/* SHIFT_ASHIFTRT */
1891 {
1892 { "shar.b\t#2,%X0", CC_OVERFLOW_UNUSABLE | CC_NO_CARRY },
1893 { "shar.w\t#2,%T0", CC_OVERFLOW_UNUSABLE | CC_NO_CARRY },
1894 { "shar.l\t#2,%S0", CC_OVERFLOW_UNUSABLE | CC_NO_CARRY }
1895 }
1896};
1897
48837e29
DE
1898/* Rotates are organized by which shift they'll be used in implementing.
1899 There's no need to record whether the cc is valid afterwards because
1900 it is the AND insn that will decide this. */
07aae5c2 1901
48837e29
DE
1902static const char *const rotate_one[2][3][3] =
1903{
1904/* H8/300 */
1905 {
1906/* SHIFT_ASHIFT */
1907 {
51c0c1d7
JL
1908 "rotr\t%X0",
1909 "shlr\t%t0\n\trotxr\t%s0\n\tbst\t#7,%t0",
48837e29
DE
1910 0
1911 },
1912/* SHIFT_LSHIFTRT */
1913 {
51c0c1d7
JL
1914 "rotl\t%X0",
1915 "shll\t%s0\n\trotxl\t%t0\n\tbst\t#0,%s0",
48837e29
DE
1916 0
1917 },
1918/* SHIFT_ASHIFTRT */
1919 {
51c0c1d7
JL
1920 "rotl\t%X0",
1921 "shll\t%s0\n\trotxl\t%t0\n\tbst\t#0,%s0",
48837e29 1922 0
07aae5c2 1923 }
48837e29
DE
1924 },
1925/* H8/300H */
1926 {
1927/* SHIFT_ASHIFT */
1928 {
51c0c1d7
JL
1929 "rotr.b\t%X0",
1930 "rotr.w\t%T0",
1931 "rotr.l\t%S0"
48837e29
DE
1932 },
1933/* SHIFT_LSHIFTRT */
07aae5c2 1934 {
51c0c1d7
JL
1935 "rotl.b\t%X0",
1936 "rotl.w\t%T0",
1937 "rotl.l\t%S0"
48837e29
DE
1938 },
1939/* SHIFT_ASHIFTRT */
1940 {
51c0c1d7
JL
1941 "rotl.b\t%X0",
1942 "rotl.w\t%T0",
1943 "rotl.l\t%S0"
48837e29
DE
1944 }
1945 }
1946};
1947
51c0c1d7
JL
1948static const char *const rotate_two[3][3] =
1949{
1950/* SHIFT_ASHIFT */
1951 {
1952 "rotr.b\t#2,%X0",
1953 "rotr.w\t#2,%T0",
1954 "rotr.l\t#2,%S0"
1955 },
1956/* SHIFT_LSHIFTRT */
1957 {
1958 "rotl.b\t#2,%X0",
1959 "rotl.w\t#2,%T0",
1960 "rotl.l\t#2,%S0"
1961 },
1962/* SHIFT_ASHIFTRT */
1963 {
1964 "rotl.b\t#2,%X0",
1965 "rotl.w\t#2,%T0",
1966 "rotl.l\t#2,%S0"
1967 }
1968};
1969
769828ab
KH
1970/* Macros to keep the shift algorithm tables small. */
1971#define INL SHIFT_INLINE
1972#define ROT SHIFT_ROT_AND
1973#define LOP SHIFT_LOOP
1974#define SPC SHIFT_SPECIAL
1975
1976/* The shift algorithms for each machine, mode, shift type, and shift
1977 count are defined below. The three tables below correspond to
1978 QImode, HImode, and SImode, respectively. Each table is organized
1979 by, in the order of indecies, machine, shift type, and shift count. */
1980
1981static const enum shift_alg shift_alg_qi[3][3][8] = {
1982 {
1983 /* TARGET_H8300 */
1984 /* 0 1 2 3 4 5 6 7 */
1985 { INL, INL, INL, INL, INL, ROT, ROT, ROT }, /* SHIFT_ASHIFT */
1986 { INL, INL, INL, INL, INL, ROT, ROT, ROT }, /* SHIFT_LSHIFTRT */
1987 { INL, INL, INL, INL, INL, LOP, LOP, SPC } /* SHIFT_ASHIFTRT */
1988 },
1989 {
1990 /* TARGET_H8300H */
1991 /* 0 1 2 3 4 5 6 7 */
1992 { INL, INL, INL, INL, INL, ROT, ROT, ROT }, /* SHIFT_ASHIFT */
1993 { INL, INL, INL, INL, INL, ROT, ROT, ROT }, /* SHIFT_LSHIFTRT */
1994 { INL, INL, INL, INL, INL, LOP, LOP, SPC } /* SHIFT_ASHIFTRT */
1995 },
1996 {
1997 /* TARGET_H8300S */
1998 /* 0 1 2 3 4 5 6 7 */
e0f19bd0
KH
1999 { INL, INL, INL, INL, INL, INL, ROT, ROT }, /* SHIFT_ASHIFT */
2000 { INL, INL, INL, INL, INL, INL, ROT, ROT }, /* SHIFT_LSHIFTRT */
769828ab
KH
2001 { INL, INL, INL, INL, INL, INL, INL, SPC } /* SHIFT_ASHIFTRT */
2002 }
2003};
2004
2005static const enum shift_alg shift_alg_hi[3][3][16] = {
2006 {
2007 /* TARGET_H8300 */
2008 /* 0 1 2 3 4 5 6 7 */
2009 /* 8 9 10 11 12 13 14 15 */
2010 { INL, INL, INL, INL, INL, LOP, LOP, SPC,
1e41e866 2011 SPC, SPC, SPC, SPC, SPC, LOP, LOP, SPC }, /* SHIFT_ASHIFT */
769828ab 2012 { INL, INL, INL, INL, INL, LOP, LOP, SPC,
1e41e866 2013 SPC, SPC, SPC, SPC, SPC, LOP, LOP, SPC }, /* SHIFT_LSHIFTRT */
769828ab
KH
2014 { INL, INL, INL, INL, INL, LOP, LOP, SPC,
2015 SPC, SPC, SPC, SPC, SPC, LOP, LOP, SPC }, /* SHIFT_ASHIFTRT */
2016 },
2017 {
2018 /* TARGET_H8300H */
2019 /* 0 1 2 3 4 5 6 7 */
2020 /* 8 9 10 11 12 13 14 15 */
2021 { INL, INL, INL, INL, INL, LOP, LOP, SPC,
2022 SPC, SPC, SPC, SPC, SPC, ROT, ROT, ROT }, /* SHIFT_ASHIFT */
2023 { INL, INL, INL, INL, INL, LOP, LOP, SPC,
2024 SPC, SPC, SPC, SPC, SPC, ROT, ROT, ROT }, /* SHIFT_LSHIFTRT */
2025 { INL, INL, INL, INL, INL, LOP, LOP, SPC,
2026 SPC, SPC, SPC, SPC, SPC, LOP, LOP, SPC }, /* SHIFT_ASHIFTRT */
2027 },
2028 {
2029 /* TARGET_H8300S */
2030 /* 0 1 2 3 4 5 6 7 */
2031 /* 8 9 10 11 12 13 14 15 */
2032 { INL, INL, INL, INL, INL, INL, INL, INL,
2033 SPC, SPC, SPC, SPC, SPC, ROT, ROT, ROT }, /* SHIFT_ASHIFT */
2034 { INL, INL, INL, INL, INL, INL, INL, INL,
2035 SPC, SPC, SPC, SPC, SPC, ROT, ROT, ROT }, /* SHIFT_LSHIFTRT */
2036 { INL, INL, INL, INL, INL, INL, INL, INL,
2037 SPC, SPC, SPC, SPC, SPC, LOP, LOP, SPC }, /* SHIFT_ASHIFTRT */
2038 }
2039};
2040
2041static const enum shift_alg shift_alg_si[3][3][32] = {
2042 {
2043 /* TARGET_H8300 */
2044 /* 0 1 2 3 4 5 6 7 */
2045 /* 8 9 10 11 12 13 14 15 */
2046 /* 16 17 18 19 20 21 22 23 */
2047 /* 24 25 26 27 28 29 30 31 */
2048 { INL, INL, INL, LOP, LOP, LOP, LOP, LOP,
2049 SPC, LOP, LOP, LOP, LOP, LOP, LOP, LOP,
1e41e866
KH
2050 SPC, SPC, SPC, SPC, SPC, LOP, LOP, LOP,
2051 SPC, SPC, SPC, SPC, LOP, LOP, LOP, SPC }, /* SHIFT_ASHIFT */
769828ab 2052 { INL, INL, INL, LOP, LOP, LOP, LOP, LOP,
1e41e866
KH
2053 SPC, SPC, LOP, LOP, LOP, LOP, LOP, SPC,
2054 SPC, SPC, SPC, LOP, LOP, LOP, LOP, LOP,
2055 SPC, SPC, SPC, SPC, SPC, LOP, LOP, SPC }, /* SHIFT_LSHIFTRT */
769828ab 2056 { INL, INL, INL, LOP, LOP, LOP, LOP, LOP,
1e41e866
KH
2057 SPC, LOP, LOP, LOP, LOP, LOP, LOP, SPC,
2058 SPC, SPC, LOP, LOP, LOP, LOP, LOP, LOP,
2059 SPC, SPC, SPC, LOP, LOP, LOP, LOP, SPC }, /* SHIFT_ASHIFTRT */
769828ab
KH
2060 },
2061 {
2062 /* TARGET_H8300H */
2063 /* 0 1 2 3 4 5 6 7 */
2064 /* 8 9 10 11 12 13 14 15 */
2065 /* 16 17 18 19 20 21 22 23 */
2066 /* 24 25 26 27 28 29 30 31 */
2067 { INL, INL, INL, INL, INL, LOP, LOP, LOP,
dd69e230 2068 SPC, LOP, LOP, LOP, LOP, LOP, LOP, SPC,
769828ab 2069 SPC, SPC, SPC, SPC, LOP, LOP, LOP, LOP,
dd69e230 2070 SPC, LOP, LOP, LOP, ROT, ROT, ROT, SPC }, /* SHIFT_ASHIFT */
769828ab 2071 { INL, INL, INL, INL, INL, LOP, LOP, LOP,
dd69e230 2072 SPC, LOP, LOP, LOP, LOP, LOP, LOP, SPC,
769828ab 2073 SPC, SPC, SPC, SPC, LOP, LOP, LOP, LOP,
dd69e230 2074 SPC, LOP, LOP, LOP, ROT, ROT, ROT, SPC }, /* SHIFT_LSHIFTRT */
769828ab
KH
2075 { INL, INL, INL, INL, INL, LOP, LOP, LOP,
2076 SPC, LOP, LOP, LOP, LOP, LOP, LOP, LOP,
2077 SPC, SPC, SPC, SPC, LOP, LOP, LOP, LOP,
2078 SPC, LOP, LOP, LOP, LOP, LOP, LOP, SPC }, /* SHIFT_ASHIFTRT */
2079 },
2080 {
2081 /* TARGET_H8300S */
2082 /* 0 1 2 3 4 5 6 7 */
2083 /* 8 9 10 11 12 13 14 15 */
2084 /* 16 17 18 19 20 21 22 23 */
2085 /* 24 25 26 27 28 29 30 31 */
2086 { INL, INL, INL, INL, INL, INL, INL, INL,
dd69e230 2087 INL, INL, INL, LOP, LOP, LOP, LOP, SPC,
e0f19bd0 2088 SPC, SPC, SPC, SPC, SPC, SPC, LOP, LOP,
4a4ae922 2089 SPC, SPC, LOP, LOP, ROT, ROT, ROT, SPC }, /* SHIFT_ASHIFT */
769828ab 2090 { INL, INL, INL, INL, INL, INL, INL, INL,
dd69e230 2091 INL, INL, INL, LOP, LOP, LOP, LOP, SPC,
e0f19bd0 2092 SPC, SPC, SPC, SPC, SPC, SPC, LOP, LOP,
4a4ae922 2093 SPC, SPC, LOP, LOP, ROT, ROT, ROT, SPC }, /* SHIFT_LSHIFTRT */
769828ab
KH
2094 { INL, INL, INL, INL, INL, INL, INL, INL,
2095 INL, INL, INL, LOP, LOP, LOP, LOP, LOP,
e0f19bd0 2096 SPC, SPC, SPC, SPC, SPC, SPC, LOP, LOP,
4a4ae922 2097 SPC, SPC, LOP, LOP, LOP, LOP, LOP, SPC }, /* SHIFT_ASHIFTRT */
769828ab
KH
2098 }
2099};
2100
2101#undef INL
2102#undef ROT
2103#undef LOP
2104#undef SPC
2105
35fb3d1f
KH
2106struct shift_info {
2107 /* Shift algorithm. */
2108 enum shift_alg alg;
2109
2110 /* The number of bits to be shifted by shift1 and shift2. Valid
2111 when ALG is SHIFT_SPECIAL. */
2112 unsigned int remainder;
2113
2114 /* Special insn for a shift. Valid when ALG is SHIFT_SPECIAL. */
2115 const char *special;
2116
2117 /* Insn for a one-bit shift. Valid when ALG is either SHIFT_INLINE
2118 or SHIFT_SPECIAL, and REMAINDER is non-zero. */
2119 const char *shift1;
2120
2121 /* Insn for a two-bit shift. Valid when ALG is either SHIFT_INLINE
2122 or SHIFT_SPECIAL, and REMAINDER is non-zero. */
2123 const char *shift2;
2124
2125 /* Valid CC flags. */
2126 int cc_valid_p;
2127};
2128
cb33eb17 2129static void get_shift_alg PARAMS ((enum shift_type,
769828ab 2130 enum shift_mode, unsigned int,
cb33eb17 2131 struct shift_info *));
441d04c6 2132
c009a745
KH
2133/* Given SHIFT_TYPE, SHIFT_MODE, and shift count COUNT, determine the
2134 best algorithm for doing the shift. The assembler code is stored
2135 in the pointers in INFO. We don't achieve maximum efficiency in
2136 all cases, but the hooks are here to do so.
48837e29
DE
2137
2138 For now we just use lots of switch statements. Since we don't even come
2139 close to supporting all the cases, this is simplest. If this function ever
2140 gets too big, perhaps resort to a more table based lookup. Of course,
2141 at this point you may just wish to do it all in rtl.
2142
2143 WARNING: The constraints on insns shiftbyn_QI/HI/SI assume shifts of
2144 1,2,3,4 will be inlined (1,2 for SI). */
2145
cb33eb17 2146static void
35fb3d1f 2147get_shift_alg (shift_type, shift_mode, count, info)
48837e29 2148 enum shift_type shift_type;
9789584b 2149 enum shift_mode shift_mode;
769828ab 2150 unsigned int count;
35fb3d1f 2151 struct shift_info *info;
48837e29 2152{
769828ab
KH
2153 int cpu;
2154
2155 /* Find the target CPU. */
2156 if (TARGET_H8300)
2157 cpu = 0;
2158 else if (TARGET_H8300H)
2159 cpu = 1;
2160 else
2161 cpu = 2;
2162
96eaf358 2163 /* Find the shift algorithm. */
48837e29
DE
2164 switch (shift_mode)
2165 {
2166 case QIshift:
769828ab 2167 if (GET_MODE_BITSIZE (QImode) <= count)
96eaf358
KH
2168 info->alg = SHIFT_LOOP;
2169 else
2170 info->alg = shift_alg_qi[cpu][shift_type][count];
2171 break;
769828ab 2172
96eaf358
KH
2173 case HIshift:
2174 if (GET_MODE_BITSIZE (HImode) <= count)
2175 info->alg = SHIFT_LOOP;
2176 else
2177 info->alg = shift_alg_hi[cpu][shift_type][count];
2178 break;
2179
2180 case SIshift:
2181 if (GET_MODE_BITSIZE (SImode) <= count)
2182 info->alg = SHIFT_LOOP;
2183 else
2184 info->alg = shift_alg_si[cpu][shift_type][count];
2185 break;
2186
2187 default:
2188 abort ();
2189 }
2190
2191 /* Fill in INFO. Return unless we have SHIFT_SPECIAL. */
2192 switch (info->alg)
2193 {
2194 case SHIFT_INLINE:
2195 info->remainder = count;
2196 /* Fall through. */
2197
2198 case SHIFT_LOOP:
2199 /* It is up to the caller to know that looping clobbers cc. */
2200 info->shift1 = shift_one[cpu_type][shift_type][shift_mode].assembler;
2201 info->shift2 = shift_two[shift_type][shift_mode].assembler;
2202 info->cc_valid_p = shift_one[cpu_type][shift_type][shift_mode].cc_valid;
2203 goto end;
2204
2205 case SHIFT_ROT_AND:
2206 info->shift1 = rotate_one[cpu_type][shift_type][shift_mode];
2207 info->shift2 = rotate_two[shift_type][shift_mode];
2208 info->cc_valid_p = 0;
2209 goto end;
2210
2211 case SHIFT_SPECIAL:
2212 /* REMAINDER is 0 for most cases, so initialize it to 0. */
2213 info->remainder = 0;
2214 info->shift1 = shift_one[cpu_type][shift_type][shift_mode].assembler;
2215 info->shift2 = shift_two[shift_type][shift_mode].assembler;
2216 info->cc_valid_p = 0;
2217 break;
2218 }
51c0c1d7 2219
96eaf358
KH
2220 /* Here we only deal with SHIFT_SPECIAL. */
2221 switch (shift_mode)
2222 {
2223 case QIshift:
769828ab
KH
2224 /* For ASHIFTRT by 7 bits, the sign bit is simply replicated
2225 through the entire value. */
2226 if (shift_type == SHIFT_ASHIFTRT && count == 7)
2227 {
2228 info->special = "shll\t%X0\n\tsubx\t%X0,%X0";
692b7eb3 2229 goto end;
769828ab
KH
2230 }
2231 abort ();
2232
2233 case HIshift:
769828ab 2234 if (count == 7)
51c0c1d7 2235 {
a77b1dbc 2236 switch (shift_type)
51c0c1d7 2237 {
a77b1dbc
KH
2238 case SHIFT_ASHIFT:
2239 if (TARGET_H8300)
2240 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";
2241 else
2242 info->special = "shar.b\t%t0\n\tmov.b\t%s0,%t0\n\trotxr.w\t%T0\n\tand.b\t#0x80,%s0";
692b7eb3 2243 goto end;
a77b1dbc
KH
2244 case SHIFT_LSHIFTRT:
2245 if (TARGET_H8300)
2246 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";
2247 else
2248 info->special = "shal.b\t%s0\n\tmov.b\t%t0,%s0\n\trotxl.w\t%T0\n\tand.b\t#0x01,%t0";
692b7eb3 2249 goto end;
a77b1dbc 2250 case SHIFT_ASHIFTRT:
35fb3d1f 2251 info->special = "shal.b\t%s0\n\tmov.b\t%t0,%s0\n\trotxl.b\t%s0\n\tsubx\t%t0,%t0";
692b7eb3 2252 goto end;
48837e29 2253 }
07aae5c2 2254 }
a7812c0b 2255 else if (8 <= count && count <= 12)
07aae5c2 2256 {
a7812c0b
KH
2257 info->remainder = count - 8;
2258
51c0c1d7 2259 switch (shift_type)
48837e29 2260 {
51c0c1d7 2261 case SHIFT_ASHIFT:
35fb3d1f 2262 info->special = "mov.b\t%s0,%t0\n\tsub.b\t%s0,%s0";
a7812c0b
KH
2263 info->shift1 = "shal.b\t%t0";
2264 info->shift2 = "shal.b\t#2,%t0";
692b7eb3 2265 goto end;
51c0c1d7 2266 case SHIFT_LSHIFTRT:
35fb3d1f 2267 info->special = "mov.b\t%t0,%s0\n\tsub.b\t%t0,%t0";
a7812c0b
KH
2268 info->shift1 = "shlr.b\t%s0";
2269 info->shift2 = "shlr.b\t#2,%s0";
692b7eb3 2270 goto end;
51c0c1d7
JL
2271 case SHIFT_ASHIFTRT:
2272 if (TARGET_H8300)
a7812c0b 2273 info->special = "mov.b\t%t0,%s0\n\tbld\t#7,%s0\n\tsubx\t%t0,%t0";
51c0c1d7 2274 else
35fb3d1f 2275 info->special = "mov.b\t%t0,%s0\n\texts.w\t%T0";
a7812c0b
KH
2276 info->shift1 = "shar.b\t%s0";
2277 info->shift2 = "shar.b\t#2,%s0";
692b7eb3 2278 goto end;
51c0c1d7
JL
2279 }
2280 }
1e41e866 2281 else if (count == 15)
51c0c1d7 2282 {
1e41e866
KH
2283 switch (shift_type)
2284 {
2285 case SHIFT_ASHIFT:
2286 info->special = "bld\t#0,%s0\n\txor\t%s0,%s0\n\txor\t%t0,%t0\n\tbst\t#7,%t0";
2287 goto end;
2288 case SHIFT_LSHIFTRT:
2289 info->special = "bld\t#7,%t0\n\txor\t%s0,%s0\n\txor\t%t0,%t0\n\tbst\t#0,%s0";
2290 goto end;
2291 case SHIFT_ASHIFTRT:
2292 info->special = "shll\t%t0\n\tsubx\t%t0,%t0\n\tmov.b\t%t0,%s0";
2293 goto end;
2294 }
07aae5c2 2295 }
769828ab 2296 abort ();
51c0c1d7 2297
48837e29 2298 case SIshift:
1e41e866 2299 if (TARGET_H8300 && 8 <= count && count <= 9)
48837e29 2300 {
1e41e866
KH
2301 info->remainder = count - 8;
2302
51c0c1d7 2303 switch (shift_type)
48837e29 2304 {
51c0c1d7 2305 case SHIFT_ASHIFT:
35fb3d1f 2306 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 2307 goto end;
51c0c1d7 2308 case SHIFT_LSHIFTRT:
35fb3d1f 2309 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 2310 info->shift1 = "shlr\t%y0\n\trotxr\t%x0\n\trotxr\t%w0";
692b7eb3 2311 goto end;
51c0c1d7 2312 case SHIFT_ASHIFTRT:
35fb3d1f 2313 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 2314 goto end;
48837e29 2315 }
48837e29 2316 }
e6bcfef9
JS
2317 else if (count == 8 && !TARGET_H8300)
2318 {
2319 switch (shift_type)
2320 {
2321 case SHIFT_ASHIFT:
35fb3d1f 2322 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 2323 goto end;
e6bcfef9 2324 case SHIFT_LSHIFTRT:
35fb3d1f 2325 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 2326 goto end;
e6bcfef9 2327 case SHIFT_ASHIFTRT:
35fb3d1f 2328 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 2329 goto end;
e6bcfef9
JS
2330 }
2331 }
1e41e866
KH
2332 else if (count == 15 && TARGET_H8300)
2333 {
2334 switch (shift_type)
2335 {
2336 case SHIFT_ASHIFT:
2337 abort ();
2338 case SHIFT_LSHIFTRT:
2339 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";
2340 goto end;
2341 case SHIFT_ASHIFTRT:
2342 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";
2343 goto end;
2344 }
2345 }
dd69e230
KH
2346 else if (count == 15 && !TARGET_H8300)
2347 {
2348 switch (shift_type)
2349 {
2350 case SHIFT_ASHIFT:
2351 info->special = "shlr.w\t%e0\n\tmov.w\t%f0,%e0\n\txor.w\t%f0,%f0\n\trotxr.l\t%S0";
2352 goto end;
2353 case SHIFT_LSHIFTRT:
18cf8dda 2354 info->special = "shll.w\t%f0\n\tmov.w\t%e0,%f0\n\txor.w\t%e0,%e0\n\trotxl.l\t%S0";
dd69e230 2355 goto end;
aefc5826
KH
2356 case SHIFT_ASHIFTRT:
2357 abort ();
dd69e230
KH
2358 }
2359 }
1e41e866 2360 else if ((TARGET_H8300 && 16 <= count && count <= 20)
a7812c0b 2361 || (TARGET_H8300H && 16 <= count && count <= 19)
e0f19bd0 2362 || (TARGET_H8300S && 16 <= count && count <= 21))
48837e29 2363 {
a7812c0b
KH
2364 info->remainder = count - 16;
2365
48837e29
DE
2366 switch (shift_type)
2367 {
2368 case SHIFT_ASHIFT:
35fb3d1f 2369 info->special = "mov.w\t%f0,%e0\n\tsub.w\t%f0,%f0";
1e41e866
KH
2370 if (TARGET_H8300)
2371 {
2372 info->shift1 = "add.w\t%e0,%e0";
2373 }
2374 else
2375 {
2376 info->shift1 = "shll.l\t%S0";
2377 info->shift2 = "shll.l\t#2,%S0";
2378 }
692b7eb3 2379 goto end;
51c0c1d7 2380 case SHIFT_LSHIFTRT:
35fb3d1f 2381 info->special = "mov.w\t%e0,%f0\n\tsub.w\t%e0,%e0";
1e41e866
KH
2382 if (TARGET_H8300)
2383 {
2384 info->shift1 = "shlr\t%x0\n\trotxr\t%w0";
2385 }
2386 else
2387 {
2388 info->shift1 = "shlr.l\t%S0";
2389 info->shift2 = "shlr.l\t#2,%S0";
2390 }
692b7eb3 2391 goto end;
51c0c1d7
JL
2392 case SHIFT_ASHIFTRT:
2393 if (TARGET_H8300)
1e41e866
KH
2394 {
2395 info->special = "mov.w\t%e0,%f0\n\tshll\t%z0\n\tsubx\t%z0,%z0\n\tmov.b\t%z0,%y0";
2396 info->shift1 = "shar\t%x0\n\trotxr\t%w0";
2397 }
51c0c1d7 2398 else
1e41e866
KH
2399 {
2400 info->special = "mov.w\t%e0,%f0\n\texts.l\t%S0";
2401 info->shift1 = "shar.l\t%S0";
2402 info->shift2 = "shar.l\t#2,%S0";
2403 }
692b7eb3 2404 goto end;
51c0c1d7
JL
2405 }
2406 }
1e41e866 2407 else if (TARGET_H8300 && 24 <= count && count <= 28)
f9477efd
KH
2408 {
2409 info->remainder = count - 24;
1e41e866 2410
f9477efd
KH
2411 switch (shift_type)
2412 {
2413 case SHIFT_ASHIFT:
2414 info->special = "mov.b\t%w0,%z0\n\tsub.b\t%y0,%y0\n\tsub.w\t%f0,%f0";
2415 info->shift1 = "shll.b\t%z0";
2416 goto end;
2417 case SHIFT_LSHIFTRT:
2418 info->special = "mov.b\t%z0,%w0\n\tsub.b\t%x0,%x0\n\tsub.w\t%e0,%e0";
2419 info->shift1 = "shlr.b\t%w0";
2420 goto end;
2421 case SHIFT_ASHIFTRT:
2422 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";
2423 info->shift1 = "shar.b\t%w0";
1e41e866 2424 goto end;
f9477efd
KH
2425 }
2426 }
4a4ae922
KH
2427 else if ((TARGET_H8300H && count == 24)
2428 || (TARGET_H8300S && 24 <= count && count <= 25))
e6bcfef9 2429 {
4a4ae922
KH
2430 info->remainder = count - 24;
2431
e6bcfef9
JS
2432 switch (shift_type)
2433 {
2434 case SHIFT_ASHIFT:
35fb3d1f 2435 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
2436 info->shift1 = "shll.l\t%S0";
2437 info->shift2 = "shll.l\t#2,%S0";
692b7eb3 2438 goto end;
e6bcfef9 2439 case SHIFT_LSHIFTRT:
35fb3d1f 2440 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
2441 info->shift1 = "shlr.l\t%S0";
2442 info->shift2 = "shlr.l\t#2,%S0";
692b7eb3 2443 goto end;
e6bcfef9 2444 case SHIFT_ASHIFTRT:
35fb3d1f 2445 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
2446 info->shift1 = "shar.l\t%S0";
2447 info->shift2 = "shar.l\t#2,%S0";
692b7eb3 2448 goto end;
e6bcfef9
JS
2449 }
2450 }
48837e29
DE
2451 else if (count == 31)
2452 {
dd69e230 2453 if (TARGET_H8300)
48837e29 2454 {
dd69e230
KH
2455 switch (shift_type)
2456 {
2457 case SHIFT_ASHIFT:
2458 info->special = "sub.w\t%e0,%e0\n\tshlr\t%w0\n\tmov.w\t%e0,%f0\n\trotxr\t%z0";
2459 goto end;
2460 case SHIFT_LSHIFTRT:
2461 info->special = "sub.w\t%f0,%f0\n\tshll\t%z0\n\tmov.w\t%f0,%e0\n\trotxl\t%w0";
2462 goto end;
2463 case SHIFT_ASHIFTRT:
2464 info->special = "shll\t%z0\n\tsubx\t%w0,%w0\n\tmov.b\t%w0,%x0\n\tmov.w\t%f0,%e0";
2465 goto end;
2466 }
48837e29
DE
2467 }
2468 else
2469 {
dd69e230 2470 switch (shift_type)
48837e29 2471 {
dd69e230
KH
2472 case SHIFT_ASHIFT:
2473 info->special = "shlr.l\t%S0\n\txor.l\t%S0,%S0\n\trotxr.l\t%S0";
2474 goto end;
2475 case SHIFT_LSHIFTRT:
2476 info->special = "shll.l\t%S0\n\txor.l\t%S0,%S0\n\trotxl.l\t%S0";
2477 goto end;
2478 case SHIFT_ASHIFTRT:
2479 info->special = "shll\t%e0\n\tsubx\t%w0,%w0\n\tmov.b\t%w0,%x0\n\tmov.w\t%f0,%e0";
692b7eb3 2480 goto end;
48837e29 2481 }
48837e29
DE
2482 }
2483 }
769828ab 2484 abort ();
51c0c1d7 2485
48837e29
DE
2486 default:
2487 abort ();
07aae5c2 2488 }
48837e29 2489
cb33eb17
KH
2490 end:
2491 if (!TARGET_H8300S)
2492 info->shift2 = NULL;
07aae5c2
SC
2493}
2494
48837e29
DE
2495/* Emit the assembler code for doing shifts. */
2496
441d04c6 2497const char *
1a275226 2498output_a_shift (operands)
48837e29 2499 rtx *operands;
07aae5c2 2500{
48837e29 2501 static int loopend_lab;
48837e29
DE
2502 rtx shift = operands[3];
2503 enum machine_mode mode = GET_MODE (shift);
2504 enum rtx_code code = GET_CODE (shift);
2505 enum shift_type shift_type;
2506 enum shift_mode shift_mode;
35fb3d1f 2507 struct shift_info info;
48837e29
DE
2508
2509 loopend_lab++;
2510
2511 switch (mode)
2512 {
2513 case QImode:
2514 shift_mode = QIshift;
2515 break;
2516 case HImode:
2517 shift_mode = HIshift;
2518 break;
2519 case SImode:
2520 shift_mode = SIshift;
2521 break;
2522 default:
2523 abort ();
2524 }
07aae5c2 2525
48837e29 2526 switch (code)
07aae5c2 2527 {
48837e29
DE
2528 case ASHIFTRT:
2529 shift_type = SHIFT_ASHIFTRT;
2530 break;
2531 case LSHIFTRT:
2532 shift_type = SHIFT_LSHIFTRT;
2533 break;
2534 case ASHIFT:
2535 shift_type = SHIFT_ASHIFT;
2536 break;
2537 default:
2538 abort ();
2539 }
07aae5c2 2540
48837e29
DE
2541 if (GET_CODE (operands[2]) != CONST_INT)
2542 {
07e4d94e 2543 /* Indexing by reg, so have to loop and test at top. */
48837e29
DE
2544 output_asm_insn ("mov.b %X2,%X4", operands);
2545 fprintf (asm_out_file, "\tble .Lle%d\n", loopend_lab);
2546
2547 /* Get the assembler code to do one shift. */
35fb3d1f 2548 get_shift_alg (shift_type, shift_mode, 1, &info);
b5eaf9ba
KH
2549
2550 fprintf (asm_out_file, ".Llt%d:\n", loopend_lab);
35fb3d1f 2551 output_asm_insn (info.shift1, operands);
b5eaf9ba
KH
2552 output_asm_insn ("add #0xff,%X4", operands);
2553 fprintf (asm_out_file, "\tbne .Llt%d\n", loopend_lab);
2554 fprintf (asm_out_file, ".Lle%d:\n", loopend_lab);
2555
2556 return "";
48837e29
DE
2557 }
2558 else
2559 {
2560 int n = INTVAL (operands[2]);
48837e29
DE
2561
2562 /* If the count is negative, make it 0. */
2563 if (n < 0)
2564 n = 0;
2565 /* If the count is too big, truncate it.
2566 ANSI says shifts of GET_MODE_BITSIZE are undefined - we choose to
2567 do the intuitive thing. */
64530b82 2568 else if ((unsigned int) n > GET_MODE_BITSIZE (mode))
48837e29
DE
2569 n = GET_MODE_BITSIZE (mode);
2570
cb33eb17 2571 get_shift_alg (shift_type, shift_mode, n, &info);
48837e29 2572
cb33eb17 2573 switch (info.alg)
48837e29 2574 {
cb33eb17
KH
2575 case SHIFT_SPECIAL:
2576 output_asm_insn (info.special, operands);
2577 /* Fall through. */
2578
48837e29 2579 case SHIFT_INLINE:
cb33eb17
KH
2580 n = info.remainder;
2581
51c0c1d7 2582 /* Emit two bit shifts first. */
1a275226 2583 if (info.shift2 != NULL)
51c0c1d7 2584 {
1a275226
KH
2585 for (; n > 1; n -= 2)
2586 output_asm_insn (info.shift2, operands);
51c0c1d7
JL
2587 }
2588
2589 /* Now emit one bit shifts for any residual. */
1a275226
KH
2590 for (; n > 0; n--)
2591 output_asm_insn (info.shift1, operands);
51c0c1d7
JL
2592
2593 /* Keep track of CC. */
35fb3d1f 2594 if (info.cc_valid_p)
269c14e1
DE
2595 {
2596 cc_status.value1 = operands[0];
35fb3d1f 2597 cc_status.flags |= info.cc_valid_p;
269c14e1 2598 }
48837e29 2599 return "";
51c0c1d7 2600
48837e29
DE
2601 case SHIFT_ROT_AND:
2602 {
2603 int m = GET_MODE_BITSIZE (mode) - n;
2604 int mask = (shift_type == SHIFT_ASHIFT
1a275226
KH
2605 ? ((1 << m) - 1) << n
2606 : (1 << m) - 1);
48837e29 2607 char insn_buf[200];
b5eaf9ba 2608
48837e29
DE
2609 /* Not all possibilities of rotate are supported. They shouldn't
2610 be generated, but let's watch for 'em. */
35fb3d1f 2611 if (info.shift1 == 0)
48837e29 2612 abort ();
51c0c1d7
JL
2613
2614 /* Emit two bit rotates first. */
1a275226 2615 if (info.shift2 != NULL)
51c0c1d7 2616 {
1a275226
KH
2617 for (; m > 1; m -= 2)
2618 output_asm_insn (info.shift2, operands);
51c0c1d7
JL
2619 }
2620
2621 /* Now single bit rotates for any residual. */
1a275226
KH
2622 for (; m > 0; m--)
2623 output_asm_insn (info.shift1, operands);
51c0c1d7
JL
2624
2625 /* Now mask off the high bits. */
48837e29
DE
2626 if (TARGET_H8300)
2627 {
2628 switch (mode)
2629 {
2630 case QImode:
3e39bdb9 2631 sprintf (insn_buf, "and\t#%d,%%X0", mask);
48837e29 2632 cc_status.value1 = operands[0];
065bbfe6 2633 cc_status.flags |= CC_NO_CARRY;
48837e29
DE
2634 break;
2635 case HImode:
3e39bdb9 2636 sprintf (insn_buf, "and\t#%d,%%s0\n\tand\t#%d,%%t0",
441d04c6 2637 mask & 255, mask >> 8);
48837e29 2638 break;
441d04c6 2639 default:
1a275226 2640 abort ();
48837e29
DE
2641 }
2642 }
2643 else
2644 {
3e39bdb9 2645 sprintf (insn_buf, "and.%c\t#%d,%%%c0",
48837e29
DE
2646 "bwl"[shift_mode], mask,
2647 mode == QImode ? 'X' : mode == HImode ? 'T' : 'S');
2648 cc_status.value1 = operands[0];
065bbfe6 2649 cc_status.flags |= CC_NO_CARRY;
48837e29
DE
2650 }
2651 output_asm_insn (insn_buf, operands);
2652 return "";
2653 }
b5eaf9ba 2654
b5eaf9ba
KH
2655 case SHIFT_LOOP:
2656 /* A loop to shift by a "large" constant value.
2657 If we have shift-by-2 insns, use them. */
35fb3d1f 2658 if (info.shift2 != NULL)
b5eaf9ba
KH
2659 {
2660 fprintf (asm_out_file, "\tmov.b #%d,%sl\n", n / 2,
2661 names_big[REGNO (operands[4])]);
2662 fprintf (asm_out_file, ".Llt%d:\n", loopend_lab);
35fb3d1f 2663 output_asm_insn (info.shift2, operands);
b5eaf9ba
KH
2664 output_asm_insn ("add #0xff,%X4", operands);
2665 fprintf (asm_out_file, "\tbne .Llt%d\n", loopend_lab);
2666 if (n % 2)
35fb3d1f 2667 output_asm_insn (info.shift1, operands);
b5eaf9ba
KH
2668 }
2669 else
2670 {
2671 fprintf (asm_out_file, "\tmov.b #%d,%sl\n", n,
2672 names_big[REGNO (operands[4])]);
2673 fprintf (asm_out_file, ".Llt%d:\n", loopend_lab);
35fb3d1f 2674 output_asm_insn (info.shift1, operands);
b5eaf9ba
KH
2675 output_asm_insn ("add #0xff,%X4", operands);
2676 fprintf (asm_out_file, "\tbne .Llt%d\n", loopend_lab);
2677 }
51c0c1d7 2678 return "";
b5eaf9ba
KH
2679
2680 default:
2681 abort ();
51c0c1d7 2682 }
07aae5c2 2683 }
07aae5c2 2684}
48837e29 2685\f
edd71f0f
KH
2686/* A rotation by a non-constant will cause a loop to be generated, in
2687 which a rotation by one bit is used. A rotation by a constant,
2688 including the one in the loop, will be taken care of by
2689 emit_a_rotate () at the insn emit time. */
2690
2691int
2692expand_a_rotate (code, operands)
a11d9dfc 2693 enum rtx_code code;
edd71f0f
KH
2694 rtx operands[];
2695{
2696 rtx dst = operands[0];
2697 rtx src = operands[1];
2698 rtx rotate_amount = operands[2];
2699 enum machine_mode mode = GET_MODE (dst);
2700 rtx tmp;
2701
2702 /* We rotate in place. */
2703 emit_move_insn (dst, src);
2704
2705 if (GET_CODE (rotate_amount) != CONST_INT)
2706 {
2707 rtx counter = gen_reg_rtx (QImode);
2708 rtx start_label = gen_label_rtx ();
2709 rtx end_label = gen_label_rtx ();
2710
2711 /* If the rotate amount is less than or equal to 0,
2712 we go out of the loop. */
d43e0b7d
RK
2713 emit_cmp_and_jump_insns (rotate_amount, GEN_INT (0), LE, NULL_RTX,
2714 QImode, 0, end_label);
edd71f0f
KH
2715
2716 /* Initialize the loop counter. */
2717 emit_move_insn (counter, rotate_amount);
2718
2719 emit_label (start_label);
2720
2721 /* Rotate by one bit. */
2722 tmp = gen_rtx (code, mode, dst, GEN_INT (1));
2723 emit_insn (gen_rtx_SET (mode, dst, tmp));
2724
2725 /* Decrement the counter by 1. */
2726 tmp = gen_rtx_PLUS (QImode, counter, GEN_INT (-1));
2727 emit_insn (gen_rtx_SET (VOIDmode, counter, tmp));
2728
2729 /* If the loop counter is non-zero, we go back to the beginning
2730 of the loop. */
d43e0b7d
RK
2731 emit_cmp_and_jump_insns (counter, GEN_INT (0), NE, NULL_RTX, QImode, 1,
2732 start_label);
edd71f0f
KH
2733
2734 emit_label (end_label);
2735 }
2736 else
2737 {
2738 /* Rotate by AMOUNT bits. */
2739 tmp = gen_rtx (code, mode, dst, rotate_amount);
2740 emit_insn (gen_rtx_SET (mode, dst, tmp));
2741 }
2742
2743 return 1;
2744}
2745
2746/* Emit rotate insns. */
2747
2748const char *
2749emit_a_rotate (code, operands)
a11d9dfc 2750 enum rtx_code code;
edd71f0f
KH
2751 rtx *operands;
2752{
2753 rtx dst = operands[0];
2754 rtx rotate_amount = operands[2];
2755 enum shift_mode rotate_mode;
2756 enum shift_type rotate_type;
2757 const char *insn_buf;
2758 int bits;
2759 int amount;
2760 enum machine_mode mode = GET_MODE (dst);
2761
2762 if (GET_CODE (rotate_amount) != CONST_INT)
2763 abort ();
2764
2765 switch (mode)
2766 {
2767 case QImode:
2768 rotate_mode = QIshift;
2769 break;
2770 case HImode:
2771 rotate_mode = HIshift;
2772 break;
2773 case SImode:
2774 rotate_mode = SIshift;
2775 break;
2776 default:
2777 abort ();
2778 }
2779
2780 switch (code)
2781 {
2782 case ROTATERT:
2783 rotate_type = SHIFT_ASHIFT;
2784 break;
2785 case ROTATE:
2786 rotate_type = SHIFT_LSHIFTRT;
2787 break;
2788 default:
2789 abort ();
2790 }
2791
2792 amount = INTVAL (rotate_amount);
2793
2794 /* Clean up AMOUNT. */
2795 if (amount < 0)
2796 amount = 0;
2797 if ((unsigned int) amount > GET_MODE_BITSIZE (mode))
2798 amount = GET_MODE_BITSIZE (mode);
2799
2800 /* Determine the faster direction. After this phase, amount will be
2801 at most a half of GET_MODE_BITSIZE (mode). */
aefc5826 2802 if ((unsigned int) amount > GET_MODE_BITSIZE (mode) / 2U)
edd71f0f
KH
2803 {
2804 /* Flip the direction. */
2805 amount = GET_MODE_BITSIZE (mode) - amount;
2806 rotate_type =
2807 (rotate_type == SHIFT_ASHIFT) ? SHIFT_LSHIFTRT : SHIFT_ASHIFT;
2808 }
2809
2810 /* See if a byte swap (in HImode) or a word swap (in SImode) can
2811 boost up the rotation. */
2812 if ((mode == HImode && TARGET_H8300 && amount >= 5)
2813 || (mode == HImode && TARGET_H8300H && amount >= 6)
2814 || (mode == HImode && TARGET_H8300S && amount == 8)
2815 || (mode == SImode && TARGET_H8300H && amount >= 10)
2816 || (mode == SImode && TARGET_H8300S && amount >= 13))
2817 {
2818 switch (mode)
2819 {
2820 case HImode:
2821 /* This code works on any family. */
2822 insn_buf = "xor.b\t%s0,%t0\n\txor.b\t%t0,%s0\n\txor.b\t%s0,%t0";
2823 output_asm_insn (insn_buf, operands);
2824 break;
2825
2826 case SImode:
2827 /* This code works on the H8/300H and H8/S. */
2828 insn_buf = "xor.w\t%e0,%f0\n\txor.w\t%f0,%e0\n\txor.w\t%e0,%f0";
2829 output_asm_insn (insn_buf, operands);
2830 break;
2831
2832 default:
2833 abort ();
2834 }
2835
2836 /* Adjust AMOUNT and flip the direction. */
2837 amount = GET_MODE_BITSIZE (mode) / 2 - amount;
2838 rotate_type =
2839 (rotate_type == SHIFT_ASHIFT) ? SHIFT_LSHIFTRT : SHIFT_ASHIFT;
2840 }
2841
2842 /* Emit rotate insns. */
2843 for (bits = TARGET_H8300S ? 2 : 1; bits > 0; bits /= 2)
2844 {
2845 if (bits == 2)
2846 insn_buf = rotate_two[rotate_type][rotate_mode];
2847 else
2848 insn_buf = rotate_one[cpu_type][rotate_type][rotate_mode];
2c54abce 2849
edd71f0f
KH
2850 for (; amount >= bits; amount -= bits)
2851 output_asm_insn (insn_buf, operands);
2852 }
2853
2854 return "";
2855}
2856\f
48837e29 2857/* Fix the operands of a gen_xxx so that it could become a bit
2c54abce 2858 operating insn. */
07aae5c2
SC
2859
2860int
48837e29
DE
2861fix_bit_operand (operands, what, type)
2862 rtx *operands;
441d04c6 2863 int what;
48837e29 2864 enum rtx_code type;
07aae5c2 2865{
abc95ed3 2866 /* The bit_operand predicate accepts any memory during RTL generation, but
48837e29
DE
2867 only 'U' memory afterwards, so if this is a MEM operand, we must force
2868 it to be valid for 'U' by reloading the address. */
07aae5c2 2869
48837e29 2870 if (GET_CODE (operands[2]) == CONST_INT)
07aae5c2 2871 {
48837e29
DE
2872 if (CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), what))
2873 {
2874 /* Ok to have a memory dest. */
1a63219b
KH
2875 if (GET_CODE (operands[0]) == MEM
2876 && !EXTRA_CONSTRAINT (operands[0], 'U'))
48837e29 2877 {
c5c76735
JL
2878 rtx mem = gen_rtx_MEM (GET_MODE (operands[0]),
2879 copy_to_mode_reg (Pmode,
2880 XEXP (operands[0], 0)));
c6df88cb 2881 MEM_COPY_ATTRIBUTES (mem, operands[0]);
48837e29
DE
2882 operands[0] = mem;
2883 }
2884
1a63219b
KH
2885 if (GET_CODE (operands[1]) == MEM
2886 && !EXTRA_CONSTRAINT (operands[1], 'U'))
48837e29 2887 {
c5c76735
JL
2888 rtx mem = gen_rtx_MEM (GET_MODE (operands[1]),
2889 copy_to_mode_reg (Pmode,
2890 XEXP (operands[1], 0)));
c6df88cb 2891 MEM_COPY_ATTRIBUTES (mem, operands[0]);
48837e29
DE
2892 operands[1] = mem;
2893 }
2894 return 0;
2895 }
2896 }
07aae5c2 2897
48837e29 2898 /* Dest and src op must be register. */
07aae5c2 2899
48837e29
DE
2900 operands[1] = force_reg (QImode, operands[1]);
2901 {
2902 rtx res = gen_reg_rtx (QImode);
c5c76735
JL
2903 emit_insn (gen_rtx_SET (VOIDmode, res,
2904 gen_rtx (type, QImode, operands[1], operands[2])));
2905 emit_insn (gen_rtx_SET (VOIDmode, operands[0], res));
48837e29
DE
2906 }
2907 return 1;
07aae5c2 2908}
f5b65a56 2909
f5b65a56
JL
2910/* Return nonzero if FUNC is an interrupt function as specified
2911 by the "interrupt" attribute. */
2912
2913static int
2914h8300_interrupt_function_p (func)
2915 tree func;
2916{
2917 tree a;
2918
2919 if (TREE_CODE (func) != FUNCTION_DECL)
2920 return 0;
2921
91d231cb 2922 a = lookup_attribute ("interrupt_handler", DECL_ATTRIBUTES (func));
f5b65a56
JL
2923 return a != NULL_TREE;
2924}
2925
fabe72bb
JL
2926/* Return nonzero if FUNC is an OS_Task function as specified
2927 by the "OS_Task" attribute. */
2928
2929static int
2930h8300_os_task_function_p (func)
2931 tree func;
2932{
2933 tree a;
2934
2935 if (TREE_CODE (func) != FUNCTION_DECL)
2936 return 0;
2937
91d231cb 2938 a = lookup_attribute ("OS_Task", DECL_ATTRIBUTES (func));
fabe72bb
JL
2939 return a != NULL_TREE;
2940}
2941
2942/* Return nonzero if FUNC is a monitor function as specified
2943 by the "monitor" attribute. */
2944
2945static int
2946h8300_monitor_function_p (func)
2947 tree func;
2948{
2949 tree a;
2950
2951 if (TREE_CODE (func) != FUNCTION_DECL)
2952 return 0;
2953
91d231cb 2954 a = lookup_attribute ("monitor", DECL_ATTRIBUTES (func));
fabe72bb
JL
2955 return a != NULL_TREE;
2956}
2957
f5b65a56
JL
2958/* Return nonzero if FUNC is a function that should be called
2959 through the function vector. */
2960
2961int
2962h8300_funcvec_function_p (func)
2963 tree func;
2964{
2965 tree a;
2966
2967 if (TREE_CODE (func) != FUNCTION_DECL)
2968 return 0;
2969
91d231cb 2970 a = lookup_attribute ("function_vector", DECL_ATTRIBUTES (func));
f5b65a56
JL
2971 return a != NULL_TREE;
2972}
2973
887a8bd9 2974/* Return nonzero if DECL is a variable that's in the eight bit
15dc331e
JL
2975 data area. */
2976
2977int
fabdc32d 2978h8300_eightbit_data_p (decl)
15dc331e
JL
2979 tree decl;
2980{
2981 tree a;
2982
2983 if (TREE_CODE (decl) != VAR_DECL)
2984 return 0;
2985
91d231cb 2986 a = lookup_attribute ("eightbit_data", DECL_ATTRIBUTES (decl));
15dc331e
JL
2987 return a != NULL_TREE;
2988}
2989
887a8bd9
JL
2990/* Return nonzero if DECL is a variable that's in the tiny
2991 data area. */
2992
2993int
2994h8300_tiny_data_p (decl)
2995 tree decl;
2996{
2997 tree a;
2998
2999 if (TREE_CODE (decl) != VAR_DECL)
3000 return 0;
3001
91d231cb 3002 a = lookup_attribute ("tiny_data", DECL_ATTRIBUTES (decl));
887a8bd9
JL
3003 return a != NULL_TREE;
3004}
3005
91d231cb 3006/* Supported attributes:
f5b65a56 3007
97c5ec1d 3008 interrupt_handler: output a prologue and epilogue suitable for an
f5b65a56
JL
3009 interrupt handler.
3010
97c5ec1d 3011 function_vector: This function should be called through the
887a8bd9
JL
3012 function vector.
3013
3014 eightbit_data: This variable lives in the 8-bit data area and can
3015 be referenced with 8-bit absolute memory addresses.
3016
3017 tiny_data: This variable lives in the tiny data area and can be
3018 referenced with 16-bit absolute memory references. */
f5b65a56 3019
91d231cb 3020const struct attribute_spec h8300_attribute_table[] =
f5b65a56 3021{
91d231cb
JM
3022 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
3023 { "interrupt_handler", 0, 0, true, false, false, h8300_handle_fndecl_attribute },
3024 { "OS_Task", 0, 0, true, false, false, h8300_handle_fndecl_attribute },
3025 { "monitor", 0, 0, true, false, false, h8300_handle_fndecl_attribute },
3026 { "function_vector", 0, 0, true, false, false, h8300_handle_fndecl_attribute },
3027 { "eightbit_data", 0, 0, true, false, false, h8300_handle_eightbit_data_attribute },
3028 { "tiny_data", 0, 0, true, false, false, h8300_handle_tiny_data_attribute },
3029 { NULL, 0, 0, false, false, false, NULL }
3030};
f5b65a56 3031
15dc331e 3032
91d231cb
JM
3033/* Handle an attribute requiring a FUNCTION_DECL; arguments as in
3034 struct attribute_spec.handler. */
3035static tree
3036h8300_handle_fndecl_attribute (node, name, args, flags, no_add_attrs)
3037 tree *node;
3038 tree name;
3039 tree args ATTRIBUTE_UNUSED;
3040 int flags ATTRIBUTE_UNUSED;
3041 bool *no_add_attrs;
3042{
3043 if (TREE_CODE (*node) != FUNCTION_DECL)
3044 {
3045 warning ("`%s' attribute only applies to functions",
3046 IDENTIFIER_POINTER (name));
3047 *no_add_attrs = true;
3048 }
3049
3050 return NULL_TREE;
3051}
3052
3053/* Handle an "eightbit_data" attribute; arguments as in
3054 struct attribute_spec.handler. */
3055static tree
3056h8300_handle_eightbit_data_attribute (node, name, args, flags, no_add_attrs)
3057 tree *node;
3058 tree name;
3059 tree args ATTRIBUTE_UNUSED;
3060 int flags ATTRIBUTE_UNUSED;
3061 bool *no_add_attrs;
3062{
3063 tree decl = *node;
3064
3065 if (TREE_STATIC (decl) || DECL_EXTERNAL (decl))
15dc331e 3066 {
64378c91 3067 DECL_SECTION_NAME (decl) = build_string (7, ".eight");
91d231cb
JM
3068 }
3069 else
3070 {
3071 warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
3072 *no_add_attrs = true;
887a8bd9
JL
3073 }
3074
91d231cb
JM
3075 return NULL_TREE;
3076}
3077
3078/* Handle an "tiny_data" attribute; arguments as in
3079 struct attribute_spec.handler. */
3080static tree
3081h8300_handle_tiny_data_attribute (node, name, args, flags, no_add_attrs)
3082 tree *node;
3083 tree name;
3084 tree args ATTRIBUTE_UNUSED;
3085 int flags ATTRIBUTE_UNUSED;
3086 bool *no_add_attrs;
3087{
3088 tree decl = *node;
3089
3090 if (TREE_STATIC (decl) || DECL_EXTERNAL (decl))
887a8bd9 3091 {
64378c91 3092 DECL_SECTION_NAME (decl) = build_string (6, ".tiny");
91d231cb
JM
3093 }
3094 else
3095 {
3096 warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
3097 *no_add_attrs = true;
15dc331e 3098 }
07e4d94e 3099
91d231cb 3100 return NULL_TREE;
f5b65a56
JL
3101}
3102
441d04c6 3103void
887a8bd9
JL
3104h8300_encode_label (decl)
3105 tree decl;
3106{
441d04c6 3107 const char *str = XSTR (XEXP (DECL_RTL (decl), 0), 0);
887a8bd9 3108 int len = strlen (str);
93cacb72 3109 char *newstr = alloca (len + 2);
887a8bd9 3110
93cacb72
KH
3111 newstr[0] = '&';
3112 strcpy (&newstr[1], str);
887a8bd9 3113
93cacb72
KH
3114 XSTR (XEXP (DECL_RTL (decl), 0), 0) =
3115 ggc_alloc_string (newstr, len + 1);
887a8bd9
JL
3116}
3117
441d04c6 3118const char *
871f73e3 3119output_simode_bld (bild, operands)
bd93f126 3120 int bild;
bd93f126
JL
3121 rtx operands[];
3122{
6be580c7
KH
3123 if (TARGET_H8300)
3124 {
3125 /* Clear the destination register. */
3126 output_asm_insn ("sub.w\t%e0,%e0\n\tsub.w\t%f0,%f0", operands);
3127
3128 /* Now output the bit load or bit inverse load, and store it in
3129 the destination. */
3130 if (bild)
3131 output_asm_insn ("bild\t%Z2,%Y1", operands);
3132 else
3133 output_asm_insn ("bld\t%Z2,%Y1", operands);
bd93f126 3134
6be580c7
KH
3135 output_asm_insn ("bst\t#0,%w0", operands);
3136 }
bd93f126 3137 else
6be580c7
KH
3138 {
3139 /* Output the bit load or bit inverse load. */
3140 if (bild)
3141 output_asm_insn ("bild\t%Z2,%Y1", operands);
3142 else
3143 output_asm_insn ("bld\t%Z2,%Y1", operands);
3144
3145 /* Clear the destination register and perform the bit store. */
3146 output_asm_insn ("xor.l\t%S0,%S0\n\tbst\t#0,%w0", operands);
3147 }
bd93f126
JL
3148
3149 /* All done. */
3150 return "";
3151}
e6219736 3152
9ec36da5 3153/* Given INSN and its current length LENGTH, return the adjustment
e6219736
JL
3154 (in bytes) to correctly compute INSN's length.
3155
3156 We use this to get the lengths of various memory references correct. */
3157
441d04c6 3158int
e6219736
JL
3159h8300_adjust_insn_length (insn, length)
3160 rtx insn;
441d04c6 3161 int length ATTRIBUTE_UNUSED;
e6219736 3162{
5fc4b751 3163 rtx pat = PATTERN (insn);
04b6000c 3164
e32815aa 3165 /* We must filter these out before calling get_attr_adjust_length. */
5fc4b751
KH
3166 if (GET_CODE (pat) == USE
3167 || GET_CODE (pat) == CLOBBER
3168 || GET_CODE (pat) == SEQUENCE
3169 || GET_CODE (pat) == ADDR_VEC
3170 || GET_CODE (pat) == ADDR_DIFF_VEC)
47cf37f9
JL
3171 return 0;
3172
04b6000c
VM
3173 if (get_attr_adjust_length (insn) == ADJUST_LENGTH_NO)
3174 return 0;
3175
e6219736
JL
3176 /* Adjust length for reg->mem and mem->reg copies. */
3177 if (GET_CODE (pat) == SET
3178 && (GET_CODE (SET_SRC (pat)) == MEM
3179 || GET_CODE (SET_DEST (pat)) == MEM))
3180 {
3181 /* This insn might need a length adjustment. */
3182 rtx addr;
3183
3184 if (GET_CODE (SET_SRC (pat)) == MEM)
3185 addr = XEXP (SET_SRC (pat), 0);
3186 else
3187 addr = XEXP (SET_DEST (pat), 0);
3188
3189 /* On the H8/300, only one adjustment is necessary; if the
3190 address mode is register indirect, then this insn is two
3191 bytes shorter than indicated in the machine description. */
3192 if (TARGET_H8300 && GET_CODE (addr) == REG)
3193 return -2;
3194
a1616dd9 3195 /* On the H8/300H and H8/S, register indirect is 6 bytes shorter than
e6219736 3196 indicated in the machine description. */
a1616dd9
JL
3197 if ((TARGET_H8300H || TARGET_H8300S)
3198 && GET_CODE (addr) == REG)
e6219736
JL
3199 return -6;
3200
9bf7ec4e
KH
3201 /* On the H8/300H and H8/S, reg + d, for small displacements is
3202 4 bytes shorter than indicated in the machine description. */
a1616dd9 3203 if ((TARGET_H8300H || TARGET_H8300S)
e6219736
JL
3204 && GET_CODE (addr) == PLUS
3205 && GET_CODE (XEXP (addr, 0)) == REG
3206 && GET_CODE (XEXP (addr, 1)) == CONST_INT
3207 && INTVAL (XEXP (addr, 1)) > -32768
3208 && INTVAL (XEXP (addr, 1)) < 32767)
3209 return -4;
887a8bd9 3210
9bf7ec4e 3211 /* On the H8/300H and H8/S, abs:16 is two bytes shorter than the
887a8bd9 3212 more general abs:24. */
a1616dd9 3213 if ((TARGET_H8300H || TARGET_H8300S)
887a8bd9
JL
3214 && GET_CODE (addr) == SYMBOL_REF
3215 && TINY_DATA_NAME_P (XSTR (addr, 0)))
3216 return -2;
e6219736
JL
3217 }
3218
3219 /* Loading some constants needs adjustment. */
3220 if (GET_CODE (pat) == SET
3221 && GET_CODE (SET_SRC (pat)) == CONST_INT
3222 && GET_MODE (SET_DEST (pat)) == SImode
3223 && INTVAL (SET_SRC (pat)) != 0)
3224 {
64530b82
KH
3225 int val = INTVAL (SET_SRC (pat));
3226
e6219736 3227 if (TARGET_H8300
64530b82
KH
3228 && ((val & 0xffff) == 0
3229 || ((val >> 16) & 0xffff) == 0))
e6219736
JL
3230 return -2;
3231
a1616dd9 3232 if (TARGET_H8300H || TARGET_H8300S)
e6219736 3233 {
e6219736
JL
3234 if (val == (val & 0xff)
3235 || val == (val & 0xff00))
86039100 3236 return 4 - 6;
e6219736 3237
86039100
KH
3238 switch (val & 0xffffffff)
3239 {
3240 case 0xffffffff:
3241 case 0xfffffffe:
3242 case 0xfffffffc:
3243 case 0x0000ffff:
3244 case 0x0000fffe:
3245 case 0xffff0000:
3246 case 0xfffe0000:
3247 case 0x00010000:
3248 case 0x00020000:
3249 return 4 - 6;
3250 }
e6219736
JL
3251 }
3252 }
3253
dd4fd0a0
JL
3254 /* Shifts need various adjustments. */
3255 if (GET_CODE (pat) == PARALLEL
3256 && GET_CODE (XVECEXP (pat, 0, 0)) == SET
3257 && (GET_CODE (SET_SRC (XVECEXP (pat, 0, 0))) == ASHIFTRT
07e4d94e
KH
3258 || GET_CODE (SET_SRC (XVECEXP (pat, 0, 0))) == LSHIFTRT
3259 || GET_CODE (SET_SRC (XVECEXP (pat, 0, 0))) == ASHIFT))
dd4fd0a0
JL
3260 {
3261 rtx src = SET_SRC (XVECEXP (pat, 0, 0));
3262 enum machine_mode mode = GET_MODE (src);
04b6000c 3263 int shift;
dd4fd0a0
JL
3264
3265 if (GET_CODE (XEXP (src, 1)) != CONST_INT)
3266 return 0;
3267
04b6000c
VM
3268 shift = INTVAL (XEXP (src, 1));
3269 /* According to ANSI, negative shift is undefined. It is
3270 considered to be zero in this case (see function
af3c90a6 3271 output_a_shift above). */
04b6000c
VM
3272 if (shift < 0)
3273 shift = 0;
3274
dd4fd0a0
JL
3275 /* QImode shifts by small constants take one insn
3276 per shift. So the adjustment is 20 (md length) -
3277 # shifts * 2. */
04b6000c
VM
3278 if (mode == QImode && shift <= 4)
3279 return -(20 - shift * 2);
dd4fd0a0 3280
9bf7ec4e
KH
3281 /* Similarly for HImode and SImode shifts by small constants on
3282 the H8/300H and H8/S. */
a1616dd9 3283 if ((TARGET_H8300H || TARGET_H8300S)
04b6000c
VM
3284 && (mode == HImode || mode == SImode) && shift <= 4)
3285 return -(20 - shift * 2);
dd4fd0a0
JL
3286
3287 /* HImode shifts by small constants for the H8/300. */
04b6000c
VM
3288 if (mode == HImode && shift <= 4)
3289 return -(20 - (shift * (GET_CODE (src) == ASHIFT ? 2 : 4)));
dd4fd0a0
JL
3290
3291 /* SImode shifts by small constants for the H8/300. */
04b6000c
VM
3292 if (mode == SImode && shift <= 2)
3293 return -(20 - (shift * (GET_CODE (src) == ASHIFT ? 6 : 8)));
dd4fd0a0
JL
3294
3295 /* XXX ??? Could check for more shift/rotate cases here. */
3296 }
07e4d94e 3297
edd71f0f
KH
3298 /* Rotations need various adjustments. */
3299 if (GET_CODE (pat) == SET
3300 && (GET_CODE (SET_SRC (pat)) == ROTATE
3301 || GET_CODE (SET_SRC (pat)) == ROTATERT))
3302 {
3303 rtx src = SET_SRC (pat);
3304 enum machine_mode mode = GET_MODE (src);
3305 int amount;
3306 int states = 0;
3307
3308 if (GET_CODE (XEXP (src, 1)) != CONST_INT)
3309 return 0;
3310
3311 amount = INTVAL (XEXP (src, 1));
3312
3313 /* Clean up AMOUNT. */
3314 if (amount < 0)
3315 amount = 0;
3316 if ((unsigned int) amount > GET_MODE_BITSIZE (mode))
3317 amount = GET_MODE_BITSIZE (mode);
3318
3319 /* Determine the faster direction. After this phase, amount
3320 will be at most a half of GET_MODE_BITSIZE (mode). */
aefc5826 3321 if ((unsigned int) amount > GET_MODE_BITSIZE (mode) / 2U)
edd71f0f
KH
3322 /* Flip the direction. */
3323 amount = GET_MODE_BITSIZE (mode) - amount;
3324
3325 /* See if a byte swap (in HImode) or a word swap (in SImode) can
3326 boost up the rotation. */
3327 if ((mode == HImode && TARGET_H8300 && amount >= 5)
3328 || (mode == HImode && TARGET_H8300H && amount >= 6)
3329 || (mode == HImode && TARGET_H8300S && amount == 8)
3330 || (mode == SImode && TARGET_H8300H && amount >= 10)
3331 || (mode == SImode && TARGET_H8300S && amount >= 13))
3332 {
3333 /* Adjust AMOUNT and flip the direction. */
3334 amount = GET_MODE_BITSIZE (mode) / 2 - amount;
3335 states += 6;
3336 }
3337
3338 /* We use 2-bit rotatations on the H8/S. */
3339 if (TARGET_H8300S)
3340 amount = amount / 2 + amount % 2;
3341
3342 /* The H8/300 uses three insns to rotate one bit, taking 6
3343 states. */
3344 states += amount * ((TARGET_H8300 && mode == HImode) ? 6 : 2);
3345
3346 return -(20 - states);
3347 }
3348
e6219736
JL
3349 return 0;
3350}
7c262518 3351
ede75ee8 3352#ifndef OBJECT_FORMAT_ELF
7c262518 3353static void
715bdd29 3354h8300_asm_named_section (name, flags)
7c262518
RH
3355 const char *name;
3356 unsigned int flags ATTRIBUTE_UNUSED;
7c262518
RH
3357{
3358 /* ??? Perhaps we should be using default_coff_asm_named_section. */
3359 fprintf (asm_out_file, "\t.section %s\n", name);
3360}
ede75ee8 3361#endif /* ! OBJECT_FORMAT_ELF */