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