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