comparison gcc/config/moxie/moxie.c @ 111:04ced10e8804

gcc 7
author kono
date Fri, 27 Oct 2017 22:46:09 +0900
parents f6334be47118
children 84e7813d76e9
comparison
equal deleted inserted replaced
68:561a7518be6b 111:04ced10e8804
1 /* Target Code for moxie 1 /* Target Code for moxie
2 Copyright (C) 2008, 2009, 2010 Free Software Foundation 2 Copyright (C) 2008-2017 Free Software Foundation, Inc.
3 Contributed by Anthony Green. 3 Contributed by Anthony Green.
4 4
5 This file is part of GCC. 5 This file is part of GCC.
6 6
7 GCC is free software; you can redistribute it and/or modify it 7 GCC is free software; you can redistribute it and/or modify it
19 <http://www.gnu.org/licenses/>. */ 19 <http://www.gnu.org/licenses/>. */
20 20
21 #include "config.h" 21 #include "config.h"
22 #include "system.h" 22 #include "system.h"
23 #include "coretypes.h" 23 #include "coretypes.h"
24 #include "tm.h" 24 #include "backend.h"
25 #include "target.h"
25 #include "rtl.h" 26 #include "rtl.h"
27 #include "tree.h"
28 #include "stringpool.h"
29 #include "attribs.h"
30 #include "df.h"
26 #include "regs.h" 31 #include "regs.h"
27 #include "hard-reg-set.h" 32 #include "memmodel.h"
28 #include "insn-config.h" 33 #include "emit-rtl.h"
29 #include "conditions.h" 34 #include "diagnostic-core.h"
30 #include "insn-flags.h"
31 #include "output.h" 35 #include "output.h"
32 #include "insn-attr.h" 36 #include "stor-layout.h"
33 #include "flags.h" 37 #include "varasm.h"
34 #include "recog.h" 38 #include "calls.h"
35 #include "reload.h"
36 #include "diagnostic-core.h"
37 #include "obstack.h"
38 #include "tree.h"
39 #include "expr.h" 39 #include "expr.h"
40 #include "optabs.h" 40 #include "builtins.h"
41 #include "except.h" 41
42 #include "function.h" 42 /* This file should be included last. */
43 #include "ggc.h"
44 #include "target.h"
45 #include "target-def.h" 43 #include "target-def.h"
46 #include "tm_p.h"
47 #include "langhooks.h"
48 #include "df.h"
49 44
50 #define LOSE_AND_RETURN(msgid, x) \ 45 #define LOSE_AND_RETURN(msgid, x) \
51 do \ 46 do \
52 { \ 47 { \
53 moxie_operand_lossage (msgid, x); \ 48 moxie_operand_lossage (msgid, x); \
81 /* Define how to find the value returned by a library function. 76 /* Define how to find the value returned by a library function.
82 77
83 We always return values in register $r0 for moxie. */ 78 We always return values in register $r0 for moxie. */
84 79
85 static rtx 80 static rtx
86 moxie_libcall_value (enum machine_mode mode, 81 moxie_libcall_value (machine_mode mode,
87 const_rtx fun ATTRIBUTE_UNUSED) 82 const_rtx fun ATTRIBUTE_UNUSED)
88 { 83 {
89 return gen_rtx_REG (mode, MOXIE_R0); 84 return gen_rtx_REG (mode, MOXIE_R0);
90 } 85 }
91 86
111 output_operand_lossage ("%s", msgid); 106 output_operand_lossage ("%s", msgid);
112 } 107 }
113 108
114 /* The PRINT_OPERAND_ADDRESS worker. */ 109 /* The PRINT_OPERAND_ADDRESS worker. */
115 110
116 void 111 static void
117 moxie_print_operand_address (FILE *file, rtx x) 112 moxie_print_operand_address (FILE *file, machine_mode, rtx x)
118 { 113 {
119 switch (GET_CODE (x)) 114 switch (GET_CODE (x))
120 { 115 {
121 case REG: 116 case REG:
122 fprintf (file, "(%s)", reg_names[REGNO (x)]); 117 fprintf (file, "(%s)", reg_names[REGNO (x)]);
158 } 153 }
159 } 154 }
160 155
161 /* The PRINT_OPERAND worker. */ 156 /* The PRINT_OPERAND worker. */
162 157
163 void 158 static void
164 moxie_print_operand (FILE *file, rtx x, int code) 159 moxie_print_operand (FILE *file, rtx x, int code)
165 { 160 {
166 rtx operand = x; 161 rtx operand = x;
167 162
168 /* New code entries should just be added to the switch below. If 163 /* New code entries should just be added to the switch below. If
189 internal_error ("internal error: bad register: %d", REGNO (operand)); 184 internal_error ("internal error: bad register: %d", REGNO (operand));
190 fprintf (file, "%s", reg_names[REGNO (operand)]); 185 fprintf (file, "%s", reg_names[REGNO (operand)]);
191 return; 186 return;
192 187
193 case MEM: 188 case MEM:
194 output_address (XEXP (operand, 0)); 189 output_address (GET_MODE (XEXP (operand, 0)), XEXP (operand, 0));
195 return; 190 return;
196 191
197 default: 192 default:
198 /* No need to handle all strange variants, let output_addr_const 193 /* No need to handle all strange variants, let output_addr_const
199 do it for us. */ 194 do it for us. */
224 /* Zero initialization is OK for all current fields. */ 219 /* Zero initialization is OK for all current fields. */
225 220
226 static struct machine_function * 221 static struct machine_function *
227 moxie_init_machine_status (void) 222 moxie_init_machine_status (void)
228 { 223 {
229 return ggc_alloc_cleared_machine_function (); 224 return ggc_cleared_alloc<machine_function> ();
230 } 225 }
231 226
232 227
233 /* The TARGET_OPTION_OVERRIDE worker. 228 /* The TARGET_OPTION_OVERRIDE worker. */
234 All this curently does is set init_machine_status. */
235 static void 229 static void
236 moxie_option_override (void) 230 moxie_option_override (void)
237 { 231 {
238 /* Set the per-function-data initializer. */ 232 /* Set the per-function-data initializer. */
239 init_machine_status = moxie_init_machine_status; 233 init_machine_status = moxie_init_machine_status;
234
235 #ifdef TARGET_MOXIEBOX
236 target_flags |= MASK_HAS_MULX;
237 #endif
240 } 238 }
241 239
242 /* Compute the size of the local area and the size to be adjusted by the 240 /* Compute the size of the local area and the size to be adjusted by the
243 * prologue and epilogue. */ 241 * prologue and epilogue. */
244 242
279 int regno; 277 int regno;
280 rtx insn; 278 rtx insn;
281 279
282 moxie_compute_frame (); 280 moxie_compute_frame ();
283 281
282 if (flag_stack_usage_info)
283 current_function_static_stack_size = cfun->machine->size_for_adjusting_sp;
284
284 /* Save callee-saved registers. */ 285 /* Save callee-saved registers. */
285 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) 286 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
286 { 287 {
287 if (!fixed_regs[regno] && df_regs_ever_live_p (regno) && !call_used_regs[regno]) 288 if (!fixed_regs[regno] && df_regs_ever_live_p (regno) && !call_used_regs[regno])
288 { 289 {
291 } 292 }
292 } 293 }
293 294
294 if (cfun->machine->size_for_adjusting_sp > 0) 295 if (cfun->machine->size_for_adjusting_sp > 0)
295 { 296 {
296 int i = cfun->machine->size_for_adjusting_sp; 297 int i = cfun->machine->size_for_adjusting_sp;
297 while (i > 255) 298 while ((i >= 255) && (i <= 510))
298 { 299 {
299 insn = emit_insn (gen_subsi3 (stack_pointer_rtx, 300 insn = emit_insn (gen_subsi3 (stack_pointer_rtx,
300 stack_pointer_rtx, 301 stack_pointer_rtx,
301 GEN_INT (255))); 302 GEN_INT (255)));
302 RTX_FRAME_RELATED_P (insn) = 1; 303 RTX_FRAME_RELATED_P (insn) = 1;
303 i -= 255; 304 i -= 255;
304 } 305 }
305 if (i > 0) 306 if (i <= 255)
306 { 307 {
307 insn = emit_insn (gen_subsi3 (stack_pointer_rtx, 308 insn = emit_insn (gen_subsi3 (stack_pointer_rtx,
308 stack_pointer_rtx, 309 stack_pointer_rtx,
309 GEN_INT (i))); 310 GEN_INT (i)));
310 RTX_FRAME_RELATED_P (insn) = 1; 311 RTX_FRAME_RELATED_P (insn) = 1;
311 } 312 }
313 else
314 {
315 rtx reg = gen_rtx_REG (SImode, MOXIE_R12);
316 insn = emit_move_insn (reg, GEN_INT (i));
317 RTX_FRAME_RELATED_P (insn) = 1;
318 insn = emit_insn (gen_subsi3 (stack_pointer_rtx,
319 stack_pointer_rtx,
320 reg));
321 RTX_FRAME_RELATED_P (insn) = 1;
322 }
312 } 323 }
313 } 324 }
314 325
315 void 326 void
316 moxie_expand_epilogue (void) 327 moxie_expand_epilogue (void)
318 int regno; 329 int regno;
319 rtx reg; 330 rtx reg;
320 331
321 if (cfun->machine->callee_saved_reg_size != 0) 332 if (cfun->machine->callee_saved_reg_size != 0)
322 { 333 {
323 reg = gen_rtx_REG (Pmode, MOXIE_R5); 334 reg = gen_rtx_REG (Pmode, MOXIE_R12);
324 if (cfun->machine->callee_saved_reg_size <= 255) 335 if (cfun->machine->callee_saved_reg_size <= 255)
325 { 336 {
326 emit_move_insn (reg, hard_frame_pointer_rtx); 337 emit_move_insn (reg, hard_frame_pointer_rtx);
327 emit_insn (gen_subsi3 338 emit_insn (gen_subsi3
328 (reg, reg, 339 (reg, reg,
368 } 379 }
369 380
370 /* Worker function for TARGET_SETUP_INCOMING_VARARGS. */ 381 /* Worker function for TARGET_SETUP_INCOMING_VARARGS. */
371 382
372 static void 383 static void
373 moxie_setup_incoming_varargs (CUMULATIVE_ARGS *cum, 384 moxie_setup_incoming_varargs (cumulative_args_t cum_v,
374 enum machine_mode mode ATTRIBUTE_UNUSED, 385 machine_mode mode ATTRIBUTE_UNUSED,
375 tree type ATTRIBUTE_UNUSED, 386 tree type ATTRIBUTE_UNUSED,
376 int *pretend_size, int no_rtl) 387 int *pretend_size, int no_rtl)
377 { 388 {
389 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
378 int regno; 390 int regno;
379 int regs = 8 - *cum; 391 int regs = 8 - *cum;
380 392
381 *pretend_size = regs < 0 ? 0 : GET_MODE_SIZE (SImode) * regs; 393 *pretend_size = regs < 0 ? 0 : GET_MODE_SIZE (SImode) * regs;
382 394
407 419
408 /* Return the next register to be used to hold a function argument or 420 /* Return the next register to be used to hold a function argument or
409 NULL_RTX if there's no more space. */ 421 NULL_RTX if there's no more space. */
410 422
411 static rtx 423 static rtx
412 moxie_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, 424 moxie_function_arg (cumulative_args_t cum_v, machine_mode mode,
413 const_tree type ATTRIBUTE_UNUSED, 425 const_tree type ATTRIBUTE_UNUSED,
414 bool named ATTRIBUTE_UNUSED) 426 bool named ATTRIBUTE_UNUSED)
415 { 427 {
428 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
429
416 if (*cum < 8) 430 if (*cum < 8)
417 return gen_rtx_REG (mode, *cum); 431 return gen_rtx_REG (mode, *cum);
418 else 432 else
419 return NULL_RTX; 433 return NULL_RTX;
420 } 434 }
422 #define MOXIE_FUNCTION_ARG_SIZE(MODE, TYPE) \ 436 #define MOXIE_FUNCTION_ARG_SIZE(MODE, TYPE) \
423 ((MODE) != BLKmode ? GET_MODE_SIZE (MODE) \ 437 ((MODE) != BLKmode ? GET_MODE_SIZE (MODE) \
424 : (unsigned) int_size_in_bytes (TYPE)) 438 : (unsigned) int_size_in_bytes (TYPE))
425 439
426 static void 440 static void
427 moxie_function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode, 441 moxie_function_arg_advance (cumulative_args_t cum_v, machine_mode mode,
428 const_tree type, bool named ATTRIBUTE_UNUSED) 442 const_tree type, bool named ATTRIBUTE_UNUSED)
429 { 443 {
444 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
445
430 *cum = (*cum < MOXIE_R6 446 *cum = (*cum < MOXIE_R6
431 ? *cum + ((3 + MOXIE_FUNCTION_ARG_SIZE (mode, type)) / 4) 447 ? *cum + ((3 + MOXIE_FUNCTION_ARG_SIZE (mode, type)) / 4)
432 : *cum); 448 : *cum);
433 } 449 }
434 450
435 /* Return non-zero if the function argument described by TYPE is to be 451 /* Return non-zero if the function argument described by TYPE is to be
436 passed by reference. */ 452 passed by reference. */
437 453
438 static bool 454 static bool
439 moxie_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED, 455 moxie_pass_by_reference (cumulative_args_t cum ATTRIBUTE_UNUSED,
440 enum machine_mode mode, const_tree type, 456 machine_mode mode, const_tree type,
441 bool named ATTRIBUTE_UNUSED) 457 bool named ATTRIBUTE_UNUSED)
442 { 458 {
443 unsigned HOST_WIDE_INT size; 459 unsigned HOST_WIDE_INT size;
444 460
445 if (type) 461 if (type)
457 /* Some function arguments will only partially fit in the registers 473 /* Some function arguments will only partially fit in the registers
458 that hold arguments. Given a new arg, return the number of bytes 474 that hold arguments. Given a new arg, return the number of bytes
459 that fit in argument passing registers. */ 475 that fit in argument passing registers. */
460 476
461 static int 477 static int
462 moxie_arg_partial_bytes (CUMULATIVE_ARGS *cum, 478 moxie_arg_partial_bytes (cumulative_args_t cum_v,
463 enum machine_mode mode, 479 machine_mode mode,
464 tree type, bool named) 480 tree type, bool named)
465 { 481 {
482 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
466 int bytes_left, size; 483 int bytes_left, size;
467 484
468 if (*cum >= 8) 485 if (*cum >= 8)
469 return 0; 486 return 0;
470 487
471 if (moxie_pass_by_reference (cum, mode, type, named)) 488 if (moxie_pass_by_reference (cum_v, mode, type, named))
472 size = 4; 489 size = 4;
473 else if (type) 490 else if (type)
474 { 491 {
475 if (AGGREGATE_TYPE_P (type)) 492 if (AGGREGATE_TYPE_P (type))
476 return 0; 493 return 0;
488 } 505 }
489 506
490 /* Worker function for TARGET_STATIC_CHAIN. */ 507 /* Worker function for TARGET_STATIC_CHAIN. */
491 508
492 static rtx 509 static rtx
493 moxie_static_chain (const_tree fndecl, bool incoming_p) 510 moxie_static_chain (const_tree ARG_UNUSED (fndecl_or_type), bool incoming_p)
494 { 511 {
495 rtx addr, mem; 512 rtx addr, mem;
496 513
497 if (!DECL_STATIC_CHAIN (fndecl))
498 return NULL;
499
500 if (incoming_p) 514 if (incoming_p)
501 addr = plus_constant (arg_pointer_rtx, 2 * UNITS_PER_WORD); 515 addr = plus_constant (Pmode, arg_pointer_rtx, 2 * UNITS_PER_WORD);
502 else 516 else
503 addr = plus_constant (stack_pointer_rtx, -UNITS_PER_WORD); 517 addr = plus_constant (Pmode, stack_pointer_rtx, -UNITS_PER_WORD);
504 518
505 mem = gen_rtx_MEM (Pmode, addr); 519 mem = gen_rtx_MEM (Pmode, addr);
506 MEM_NOTRAP_P (mem) = 1; 520 MEM_NOTRAP_P (mem) = 1;
507 521
508 return mem; 522 return mem;
515 { 529 {
516 fprintf (f, "\tpush $sp, $r0\n"); 530 fprintf (f, "\tpush $sp, $r0\n");
517 fprintf (f, "\tldi.l $r0, 0x0\n"); 531 fprintf (f, "\tldi.l $r0, 0x0\n");
518 fprintf (f, "\tsto.l 0x8($fp), $r0\n"); 532 fprintf (f, "\tsto.l 0x8($fp), $r0\n");
519 fprintf (f, "\tpop $sp, $r0\n"); 533 fprintf (f, "\tpop $sp, $r0\n");
520 fprintf (f, "\tnop\n");
521 fprintf (f, "\tjmpa 0x0\n"); 534 fprintf (f, "\tjmpa 0x0\n");
522 } 535 }
523 536
524 /* Worker function for TARGET_TRAMPOLINE_INIT. */ 537 /* Worker function for TARGET_TRAMPOLINE_INIT. */
525 538
531 emit_block_move (m_tramp, assemble_trampoline_template (), 544 emit_block_move (m_tramp, assemble_trampoline_template (),
532 GEN_INT (TRAMPOLINE_SIZE), BLOCK_OP_NORMAL); 545 GEN_INT (TRAMPOLINE_SIZE), BLOCK_OP_NORMAL);
533 546
534 mem = adjust_address (m_tramp, SImode, 4); 547 mem = adjust_address (m_tramp, SImode, 4);
535 emit_move_insn (mem, chain_value); 548 emit_move_insn (mem, chain_value);
536 mem = adjust_address (m_tramp, SImode, 20); 549 mem = adjust_address (m_tramp, SImode, 16);
537 emit_move_insn (mem, fnaddr); 550 emit_move_insn (mem, fnaddr);
551 }
552
553 /* Return true for memory offset addresses between -32768 and 32767. */
554 bool
555 moxie_offset_address_p (rtx x)
556 {
557 x = XEXP (x, 0);
558
559 if (GET_CODE (x) == PLUS)
560 {
561 x = XEXP (x, 1);
562 if (GET_CODE (x) == CONST_INT)
563 {
564 unsigned int v = INTVAL (x) & 0xFFFF8000;
565 return (v == 0xFFFF8000 || v == 0x00000000);
566 }
567 }
568 return 0;
569 }
570
571 /* Helper function for `moxie_legitimate_address_p'. */
572
573 static bool
574 moxie_reg_ok_for_base_p (const_rtx reg, bool strict_p)
575 {
576 int regno = REGNO (reg);
577
578 if (strict_p)
579 return HARD_REGNO_OK_FOR_BASE_P (regno)
580 || HARD_REGNO_OK_FOR_BASE_P (reg_renumber[regno]);
581 else
582 return !HARD_REGISTER_NUM_P (regno)
583 || HARD_REGNO_OK_FOR_BASE_P (regno);
584 }
585
586 /* Worker function for TARGET_LEGITIMATE_ADDRESS_P. */
587
588 static bool
589 moxie_legitimate_address_p (machine_mode mode ATTRIBUTE_UNUSED,
590 rtx x, bool strict_p,
591 addr_space_t as)
592 {
593 gcc_assert (ADDR_SPACE_GENERIC_P (as));
594
595 if (GET_CODE(x) == PLUS
596 && REG_P (XEXP (x, 0))
597 && moxie_reg_ok_for_base_p (XEXP (x, 0), strict_p)
598 && CONST_INT_P (XEXP (x, 1))
599 && IN_RANGE (INTVAL (XEXP (x, 1)), -32768, 32767))
600 return true;
601 if (REG_P (x) && moxie_reg_ok_for_base_p (x, strict_p))
602 return true;
603 if (GET_CODE (x) == SYMBOL_REF
604 || GET_CODE (x) == LABEL_REF
605 || GET_CODE (x) == CONST)
606 return true;
607 return false;
538 } 608 }
539 609
540 /* The Global `targetm' Variable. */ 610 /* The Global `targetm' Variable. */
541 611
542 /* Initialize the GCC target structure. */ 612 /* Initialize the GCC target structure. */
555 #undef TARGET_FUNCTION_ARG 625 #undef TARGET_FUNCTION_ARG
556 #define TARGET_FUNCTION_ARG moxie_function_arg 626 #define TARGET_FUNCTION_ARG moxie_function_arg
557 #undef TARGET_FUNCTION_ARG_ADVANCE 627 #undef TARGET_FUNCTION_ARG_ADVANCE
558 #define TARGET_FUNCTION_ARG_ADVANCE moxie_function_arg_advance 628 #define TARGET_FUNCTION_ARG_ADVANCE moxie_function_arg_advance
559 629
630 #undef TARGET_LRA_P
631 #define TARGET_LRA_P hook_bool_void_false
632
633 #undef TARGET_ADDR_SPACE_LEGITIMATE_ADDRESS_P
634 #define TARGET_ADDR_SPACE_LEGITIMATE_ADDRESS_P moxie_legitimate_address_p
560 635
561 #undef TARGET_SETUP_INCOMING_VARARGS 636 #undef TARGET_SETUP_INCOMING_VARARGS
562 #define TARGET_SETUP_INCOMING_VARARGS moxie_setup_incoming_varargs 637 #define TARGET_SETUP_INCOMING_VARARGS moxie_setup_incoming_varargs
563 638
564 #undef TARGET_FIXED_CONDITION_CODE_REGS 639 #undef TARGET_FIXED_CONDITION_CODE_REGS
565 #define TARGET_FIXED_CONDITION_CODE_REGS moxie_fixed_condition_code_regs 640 #define TARGET_FIXED_CONDITION_CODE_REGS moxie_fixed_condition_code_regs
566 641
567 /* Define this to return an RTX representing the place where a 642 /* Define this to return an RTX representing the place where a
568 function returns or receives a value of data type RET_TYPE, a tree 643 function returns or receives a value of data type RET_TYPE, a tree
569 node node representing a data type. */ 644 node representing a data type. */
570 #undef TARGET_FUNCTION_VALUE 645 #undef TARGET_FUNCTION_VALUE
571 #define TARGET_FUNCTION_VALUE moxie_function_value 646 #define TARGET_FUNCTION_VALUE moxie_function_value
572 #undef TARGET_LIBCALL_VALUE 647 #undef TARGET_LIBCALL_VALUE
573 #define TARGET_LIBCALL_VALUE moxie_libcall_value 648 #define TARGET_LIBCALL_VALUE moxie_libcall_value
574 #undef TARGET_FUNCTION_VALUE_REGNO_P 649 #undef TARGET_FUNCTION_VALUE_REGNO_P
585 #define TARGET_TRAMPOLINE_INIT moxie_trampoline_init 660 #define TARGET_TRAMPOLINE_INIT moxie_trampoline_init
586 661
587 #undef TARGET_OPTION_OVERRIDE 662 #undef TARGET_OPTION_OVERRIDE
588 #define TARGET_OPTION_OVERRIDE moxie_option_override 663 #define TARGET_OPTION_OVERRIDE moxie_option_override
589 664
665 #undef TARGET_PRINT_OPERAND
666 #define TARGET_PRINT_OPERAND moxie_print_operand
667 #undef TARGET_PRINT_OPERAND_ADDRESS
668 #define TARGET_PRINT_OPERAND_ADDRESS moxie_print_operand_address
669
670 #undef TARGET_CONSTANT_ALIGNMENT
671 #define TARGET_CONSTANT_ALIGNMENT constant_alignment_word_strings
672
590 struct gcc_target targetm = TARGET_INITIALIZER; 673 struct gcc_target targetm = TARGET_INITIALIZER;
591 674
592 #include "gt-moxie.h" 675 #include "gt-moxie.h"