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