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