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