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