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