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