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