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