Mercurial > hg > CbC > CbC_gcc
comparison gcc/config/picochip/picochip.c @ 67:f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
author | nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Tue, 22 Mar 2011 17:18:12 +0900 |
parents | b7f97abdc517 |
children |
comparison
equal
deleted
inserted
replaced
65:65488c3d617d | 67:f6334be47118 |
---|---|
1 /* Subroutines used for code generation on picoChip processors. | 1 /* Subroutines used for code generation on picoChip processors. |
2 Copyright (C) 2001,2008, 2009 Free Software Foundation, Inc. | 2 Copyright (C) 2001, 2008, 2009, 2010 Free Software Foundation, Inc. |
3 Contributed by picoChip Designs Ltd. (http://www.picochip.com) | 3 Contributed by Picochip Ltd. (http://www.picochip.com) |
4 Maintained by Daniel Towner (daniel.towner@picochip.com) and | 4 Maintained by Daniel Towner (daniel.towner@picochip.com) and |
5 Hariharan Sandanagobalane (hariharan@picochip.com) | 5 Hariharan Sandanagobalane (hariharan@picochip.com) |
6 | 6 |
7 This file is part of GCC. | 7 This file is part of GCC. |
8 | 8 |
39 #include "except.h" | 39 #include "except.h" |
40 #include "function.h" | 40 #include "function.h" |
41 #include "output.h" | 41 #include "output.h" |
42 #include "basic-block.h" | 42 #include "basic-block.h" |
43 #include "integrate.h" | 43 #include "integrate.h" |
44 #include "toplev.h" | 44 #include "diagnostic-core.h" |
45 #include "ggc.h" | 45 #include "ggc.h" |
46 #include "hashtab.h" | 46 #include "hashtab.h" |
47 #include "tm_p.h" | 47 #include "tm_p.h" |
48 #include "target.h" | 48 #include "target.h" |
49 #include "target-def.h" | 49 #include "target-def.h" |
78 void picochip_reorg (void); | 78 void picochip_reorg (void); |
79 | 79 |
80 int picochip_arg_partial_bytes (CUMULATIVE_ARGS * p_cum, | 80 int picochip_arg_partial_bytes (CUMULATIVE_ARGS * p_cum, |
81 enum machine_mode mode, | 81 enum machine_mode mode, |
82 tree type, bool named); | 82 tree type, bool named); |
83 rtx picochip_function_arg (CUMULATIVE_ARGS * p_cum, | |
84 enum machine_mode mode, | |
85 const_tree type, bool named); | |
86 rtx picochip_incoming_function_arg (CUMULATIVE_ARGS * p_cum, | |
87 enum machine_mode mode, | |
88 const_tree type, bool named); | |
89 void picochip_arg_advance (CUMULATIVE_ARGS * p_cum, enum machine_mode mode, | |
90 const_tree type, bool named); | |
91 unsigned int picochip_function_arg_boundary (enum machine_mode mode, | |
92 const_tree type); | |
83 | 93 |
84 int picochip_sched_lookahead (void); | 94 int picochip_sched_lookahead (void); |
85 int picochip_sched_issue_rate (void); | 95 int picochip_sched_issue_rate (void); |
86 int picochip_sched_adjust_cost (rtx insn, rtx link, | 96 int picochip_sched_adjust_cost (rtx insn, rtx link, |
87 rtx dep_insn, int cost); | 97 rtx dep_insn, int cost); |
101 int opnum, int type, int ind_levels); | 111 int opnum, int type, int ind_levels); |
102 | 112 |
103 rtx picochip_struct_value_rtx(tree fntype ATTRIBUTE_UNUSED, int incoming ATTRIBUTE_UNUSED); | 113 rtx picochip_struct_value_rtx(tree fntype ATTRIBUTE_UNUSED, int incoming ATTRIBUTE_UNUSED); |
104 rtx picochip_function_value (const_tree valtype, const_tree func ATTRIBUTE_UNUSED, | 114 rtx picochip_function_value (const_tree valtype, const_tree func ATTRIBUTE_UNUSED, |
105 bool outgoing ATTRIBUTE_UNUSED); | 115 bool outgoing ATTRIBUTE_UNUSED); |
106 enum reg_class | 116 static reg_class_t |
107 picochip_secondary_reload (bool in_p, | 117 picochip_secondary_reload (bool in_p, |
108 rtx x ATTRIBUTE_UNUSED, | 118 rtx x ATTRIBUTE_UNUSED, |
109 enum reg_class cla ATTRIBUTE_UNUSED, | 119 reg_class_t cla ATTRIBUTE_UNUSED, |
110 enum machine_mode mode, | 120 enum machine_mode mode, |
111 secondary_reload_info *sri); | 121 secondary_reload_info *sri); |
112 void | 122 void |
113 picochip_asm_named_section (const char *name, | 123 picochip_asm_named_section (const char *name, |
114 unsigned int flags ATTRIBUTE_UNUSED, | 124 unsigned int flags ATTRIBUTE_UNUSED, |
115 tree decl ATTRIBUTE_UNUSED); | 125 tree decl ATTRIBUTE_UNUSED); |
116 | 126 |
117 static rtx picochip_static_chain (const_tree, bool); | 127 static rtx picochip_static_chain (const_tree, bool); |
128 | |
129 static void picochip_option_override (void); | |
118 | 130 |
119 /* Lookup table mapping a register number to the earliest containing | 131 /* Lookup table mapping a register number to the earliest containing |
120 class. Used by REGNO_REG_CLASS. */ | 132 class. Used by REGNO_REG_CLASS. */ |
121 const enum reg_class picochip_regno_reg_class[FIRST_PSEUDO_REGISTER] = | 133 const enum reg_class picochip_regno_reg_class[FIRST_PSEUDO_REGISTER] = |
122 { | 134 { |
185 static struct recog_data picochip_saved_recog_data; | 197 static struct recog_data picochip_saved_recog_data; |
186 | 198 |
187 /* Determine which ALU to use for the instruction in | 199 /* Determine which ALU to use for the instruction in |
188 picochip_current_prescan_insn. */ | 200 picochip_current_prescan_insn. */ |
189 static char picochip_get_vliw_alu_id (void); | 201 static char picochip_get_vliw_alu_id (void); |
202 | |
203 /* Implement TARGET_OPTION_OPTIMIZATION_TABLE. */ | |
204 static const struct default_options picochip_option_optimization_table[] = | |
205 { | |
206 { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 }, | |
207 { OPT_LEVELS_NONE, 0, NULL, 0 } | |
208 }; | |
190 | 209 |
191 /* Initialize the GCC target structure. */ | 210 /* Initialize the GCC target structure. */ |
192 | 211 |
193 #undef TARGET_ASM_FUNCTION_PROLOGUE | 212 #undef TARGET_ASM_FUNCTION_PROLOGUE |
194 #define TARGET_ASM_FUNCTION_PROLOGUE picochip_function_prologue | 213 #define TARGET_ASM_FUNCTION_PROLOGUE picochip_function_prologue |
257 #define TARGET_MACHINE_DEPENDENT_REORG picochip_reorg | 276 #define TARGET_MACHINE_DEPENDENT_REORG picochip_reorg |
258 | 277 |
259 #undef TARGET_ARG_PARTIAL_BYTES | 278 #undef TARGET_ARG_PARTIAL_BYTES |
260 #define TARGET_ARG_PARTIAL_BYTES picochip_arg_partial_bytes | 279 #define TARGET_ARG_PARTIAL_BYTES picochip_arg_partial_bytes |
261 | 280 |
281 #undef TARGET_FUNCTION_ARG | |
282 #define TARGET_FUNCTION_ARG picochip_function_arg | |
283 | |
284 #undef TARGET_FUNCTION_INCOMING_ARG | |
285 #define TARGET_FUNCTION_INCOMING_ARG picochip_incoming_function_arg | |
286 | |
287 #undef TARGET_FUNCTION_ARG_ADVANCE | |
288 #define TARGET_FUNCTION_ARG_ADVANCE picochip_arg_advance | |
289 | |
290 #undef TARGET_FUNCTION_ARG_BOUNDARY | |
291 #define TARGET_FUNCTION_ARG_BOUNDARY picochip_function_arg_boundary | |
292 | |
262 #undef TARGET_PROMOTE_FUNCTION_MODE | 293 #undef TARGET_PROMOTE_FUNCTION_MODE |
263 #define TARGET_PROMOTE_FUNCTION_MODE default_promote_function_mode_always_promote | 294 #define TARGET_PROMOTE_FUNCTION_MODE default_promote_function_mode_always_promote |
264 #undef TARGET_PROMOTE_PROTOTYPES | 295 #undef TARGET_PROMOTE_PROTOTYPES |
265 #define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_true | 296 #define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_true |
266 | 297 |
298 #define TARGET_RETURN_IN_MEMORY picochip_return_in_memory | 329 #define TARGET_RETURN_IN_MEMORY picochip_return_in_memory |
299 | 330 |
300 #undef TARGET_STATIC_CHAIN | 331 #undef TARGET_STATIC_CHAIN |
301 #define TARGET_STATIC_CHAIN picochip_static_chain | 332 #define TARGET_STATIC_CHAIN picochip_static_chain |
302 | 333 |
334 #undef TARGET_OPTION_OVERRIDE | |
335 #define TARGET_OPTION_OVERRIDE picochip_option_override | |
336 | |
337 #undef TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE | |
338 #define TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE picochip_option_override | |
339 | |
340 #undef TARGET_OPTION_OPTIMIZATION_TABLE | |
341 #define TARGET_OPTION_OPTIMIZATION_TABLE picochip_option_optimization_table | |
342 | |
343 #undef TARGET_EXCEPT_UNWIND_INFO | |
344 #define TARGET_EXCEPT_UNWIND_INFO sjlj_except_unwind_info | |
345 | |
303 struct gcc_target targetm = TARGET_INITIALIZER; | 346 struct gcc_target targetm = TARGET_INITIALIZER; |
304 | 347 |
305 | 348 |
306 /* Only return a value in memory if it is greater than 4 bytes. | 349 /* Only return a value in memory if it is greater than 4 bytes. |
307 int_size_in_bytes returns -1 for variable size objects, which go in | 350 int_size_in_bytes returns -1 for variable size objects, which go in |
311 picochip_return_in_memory(const_tree type, const_tree fntype ATTRIBUTE_UNUSED) | 354 picochip_return_in_memory(const_tree type, const_tree fntype ATTRIBUTE_UNUSED) |
312 { | 355 { |
313 return ((unsigned HOST_WIDE_INT) int_size_in_bytes (type) > 4); | 356 return ((unsigned HOST_WIDE_INT) int_size_in_bytes (type) > 4); |
314 } | 357 } |
315 | 358 |
316 /* Allow certain command options to be overriden. */ | 359 /* Allow some options to be overriden. In particular, the 2nd |
317 void | 360 scheduling pass option is switched off, and a machine dependent |
318 picochip_override_options (void) | 361 reorganisation ensures that it is run later on, after the second |
362 jump optimisation. */ | |
363 | |
364 static void | |
365 picochip_option_override (void) | |
319 { | 366 { |
320 /* If we are optimizing for stack, dont let inliner to inline functions | 367 /* If we are optimizing for stack, dont let inliner to inline functions |
321 that could potentially increase stack size.*/ | 368 that could potentially increase stack size.*/ |
322 if (flag_conserve_stack) | 369 if (flag_conserve_stack) |
323 { | 370 { |
324 PARAM_VALUE (PARAM_LARGE_STACK_FRAME) = 0; | 371 maybe_set_param_value (PARAM_LARGE_STACK_FRAME, 0, |
325 PARAM_VALUE (PARAM_STACK_FRAME_GROWTH) = 0; | 372 global_options.x_param_values, |
326 } | 373 global_options_set.x_param_values); |
374 maybe_set_param_value (PARAM_STACK_FRAME_GROWTH, 0, | |
375 global_options.x_param_values, | |
376 global_options_set.x_param_values); | |
377 } | |
327 | 378 |
328 /* Turn off the elimination of unused types. The elaborator | 379 /* Turn off the elimination of unused types. The elaborator |
329 generates various interesting types to represent constants, | 380 generates various interesting types to represent constants, |
330 generics, and so on, and it is useful to retain this information | 381 generics, and so on, and it is useful to retain this information |
331 in the debug output. The increased size of the debug information | 382 in the debug output. The increased size of the debug information |
356 VLIW scheduling is disabled when scheduling for size. */ | 407 VLIW scheduling is disabled when scheduling for size. */ |
357 picochip_flag_schedule_insns2 = flag_schedule_insns_after_reload; | 408 picochip_flag_schedule_insns2 = flag_schedule_insns_after_reload; |
358 flag_schedule_insns_after_reload = 0; | 409 flag_schedule_insns_after_reload = 0; |
359 if (picochip_flag_schedule_insns2) | 410 if (picochip_flag_schedule_insns2) |
360 { | 411 { |
361 | |
362 if (optimize_size) | 412 if (optimize_size) |
363 picochip_schedule_type = DFA_TYPE_SPACE; | 413 picochip_schedule_type = DFA_TYPE_SPACE; |
364 else | 414 else |
365 { | 415 { |
366 picochip_schedule_type = DFA_TYPE_SPEED; | 416 picochip_schedule_type = DFA_TYPE_SPEED; |
367 flag_delayed_branch = 0; | 417 flag_delayed_branch = 0; |
368 } | 418 } |
369 | |
370 } | 419 } |
371 else | 420 else |
372 picochip_schedule_type = DFA_TYPE_NONE; | 421 picochip_schedule_type = DFA_TYPE_NONE; |
373 | 422 |
374 /* Ensure that the debug level is always at least -g2. The flow | 423 /* Ensure that the debug level is always at least -g2. The flow |
384 /* Options of the form -mae=mac, and so on will be substituted by | 433 /* Options of the form -mae=mac, and so on will be substituted by |
385 the compiler driver for the appropriate byte access and multiply | 434 the compiler driver for the appropriate byte access and multiply |
386 unit ISA options. Any unrecognised AE types will end up being | 435 unit ISA options. Any unrecognised AE types will end up being |
387 passed to the compiler, which should reject them as invalid. */ | 436 passed to the compiler, which should reject them as invalid. */ |
388 if (picochip_ae_type_string != NULL) | 437 if (picochip_ae_type_string != NULL) |
389 error ("invalid AE type specified (%s)\n", picochip_ae_type_string); | 438 error ("invalid AE type specified (%s)", picochip_ae_type_string); |
390 | 439 |
391 /* Override any specific capabilities of the instruction set. These | 440 /* Override any specific capabilities of the instruction set. These |
392 take precedence over any capabilities inferred from the AE type, | 441 take precedence over any capabilities inferred from the AE type, |
393 regardless of where the options appear on the command line. */ | 442 regardless of where the options appear on the command line. */ |
394 if (picochip_mul_type_string == NULL) | 443 if (picochip_mul_type_string == NULL) |
407 else if (strcmp (picochip_mul_type_string, "mac") == 0) | 456 else if (strcmp (picochip_mul_type_string, "mac") == 0) |
408 picochip_has_mac_unit = true; | 457 picochip_has_mac_unit = true; |
409 else if (strcmp (picochip_mul_type_string, "none") == 0) | 458 else if (strcmp (picochip_mul_type_string, "none") == 0) |
410 { /* Do nothing. Unit types already set to false. */ } | 459 { /* Do nothing. Unit types already set to false. */ } |
411 else | 460 else |
412 error ("Invalid mul type specified (%s) - expected mac, mul or none", | 461 error ("invalid mul type specified (%s) - expected mac, mul or none", |
413 picochip_mul_type_string); | 462 picochip_mul_type_string); |
414 } | 463 } |
415 | 464 |
416 } | 465 } |
417 | 466 |
446 | 495 |
447 /* 64-bit addition and subtraction*/ | 496 /* 64-bit addition and subtraction*/ |
448 set_optab_libfunc (add_optab, DImode, "_adddi3"); | 497 set_optab_libfunc (add_optab, DImode, "_adddi3"); |
449 set_optab_libfunc (sub_optab, DImode, "_subdi3"); | 498 set_optab_libfunc (sub_optab, DImode, "_subdi3"); |
450 } | 499 } |
500 | |
501 /* Memcpy function */ | |
502 int | |
503 picochip_expand_movmemhi (rtx *operands) | |
504 { | |
505 rtx src_addr_reg, dst_addr_reg, count_reg, src_mem, dst_mem, tmp_reg; | |
506 rtx start_label; | |
507 int align, size; | |
508 src_addr_reg = gen_reg_rtx(HImode); | |
509 dst_addr_reg = gen_reg_rtx(HImode); | |
510 count_reg = gen_reg_rtx(HImode); | |
511 emit_insn (gen_movhi (count_reg, operands[2])); | |
512 emit_insn (gen_movqi (src_addr_reg, XEXP(operands[1], 0))); | |
513 emit_insn (gen_movqi (dst_addr_reg, XEXP(operands[0], 0))); | |
514 gcc_assert (GET_CODE(count_reg) == REG); | |
515 start_label = gen_label_rtx (); | |
516 emit_label (start_label); | |
517 | |
518 /* We can specialise the code for different alignments */ | |
519 align = INTVAL(operands[3]); | |
520 size = INTVAL(operands[2]); | |
521 gcc_assert(align >= 0 && size >= 0); | |
522 if (size != 0) | |
523 { | |
524 if (size % 4 == 0 && align % 4 == 0) | |
525 { | |
526 src_mem = gen_rtx_MEM(SImode, src_addr_reg); | |
527 dst_mem = gen_rtx_MEM(SImode, dst_addr_reg); | |
528 tmp_reg = gen_reg_rtx(SImode); | |
529 emit_insn (gen_movsi (tmp_reg, src_mem)); | |
530 emit_insn (gen_movsi (dst_mem, tmp_reg)); | |
531 emit_insn (gen_addhi3 (dst_addr_reg, dst_addr_reg, GEN_INT(4))); | |
532 emit_insn (gen_addhi3 (src_addr_reg, src_addr_reg, GEN_INT(4))); | |
533 emit_insn (gen_addhi3 (count_reg, count_reg, GEN_INT(-4))); | |
534 /* The sub instruction above generates cc, but we cannot just emit the branch.*/ | |
535 emit_cmp_and_jump_insns (count_reg, const0_rtx, GT, 0, HImode, 0, start_label); | |
536 } | |
537 else if (size % 2 == 0 && align % 2 == 0) | |
538 { | |
539 src_mem = gen_rtx_MEM(HImode, src_addr_reg); | |
540 dst_mem = gen_rtx_MEM(HImode, dst_addr_reg); | |
541 tmp_reg = gen_reg_rtx(HImode); | |
542 emit_insn (gen_movhi (tmp_reg, src_mem)); | |
543 emit_insn (gen_movhi (dst_mem, tmp_reg)); | |
544 emit_insn (gen_addhi3 (dst_addr_reg, dst_addr_reg, const2_rtx)); | |
545 emit_insn (gen_addhi3 (src_addr_reg, src_addr_reg, const2_rtx)); | |
546 emit_insn (gen_addhi3 (count_reg, count_reg, GEN_INT(-2))); | |
547 /* The sub instruction above generates cc, but we cannot just emit the branch.*/ | |
548 emit_cmp_and_jump_insns (count_reg, const0_rtx, GT, 0, HImode, 0, start_label); | |
549 } | |
550 else | |
551 { | |
552 src_mem = gen_rtx_MEM(QImode, src_addr_reg); | |
553 dst_mem = gen_rtx_MEM(QImode, dst_addr_reg); | |
554 tmp_reg = gen_reg_rtx(QImode); | |
555 emit_insn (gen_movqi (tmp_reg, src_mem)); | |
556 emit_insn (gen_movqi (dst_mem, tmp_reg)); | |
557 emit_insn (gen_addhi3 (dst_addr_reg, dst_addr_reg, const1_rtx)); | |
558 emit_insn (gen_addhi3 (src_addr_reg, src_addr_reg, const1_rtx)); | |
559 emit_insn (gen_addhi3 (count_reg, count_reg, GEN_INT(-1))); | |
560 /* The sub instruction above generates cc, but we cannot just emit the branch.*/ | |
561 emit_cmp_and_jump_insns (count_reg, const0_rtx, GT, 0, HImode, 0, start_label); | |
562 } | |
563 } | |
564 return 1; | |
565 } | |
566 | |
451 | 567 |
452 /* Return the register class for letter C. */ | 568 /* Return the register class for letter C. */ |
453 enum reg_class | 569 enum reg_class |
454 picochip_reg_class_from_letter (unsigned c) | 570 picochip_reg_class_from_letter (unsigned c) |
455 { | 571 { |
520 /* Stack utility functions. */ | 636 /* Stack utility functions. */ |
521 rtx | 637 rtx |
522 picochip_return_addr_rtx(int count, rtx frameaddr ATTRIBUTE_UNUSED) | 638 picochip_return_addr_rtx(int count, rtx frameaddr ATTRIBUTE_UNUSED) |
523 { | 639 { |
524 if (count==0) | 640 if (count==0) |
525 return gen_rtx_REG (Pmode, LINK_REGNUM); | 641 return gen_rtx_REG (Pmode, LINK_REGNUM); |
526 else | 642 else |
527 return NULL_RTX; | 643 return NULL_RTX; |
528 } | 644 } |
529 | 645 |
530 | 646 |
531 /* Emit a set of parallel register expressions used to store | 647 /* Emit a set of parallel register expressions used to store |
532 blockmode values to pass to functions. */ | 648 blockmode values to pass to functions. */ |
571 | 687 |
572 /* Make the instruction frame related. Also add an expression note, | 688 /* Make the instruction frame related. Also add an expression note, |
573 so that the correct Dwarf information is generated (see documention | 689 so that the correct Dwarf information is generated (see documention |
574 for RTX_FRAME_RELATED_P for more details). */ | 690 for RTX_FRAME_RELATED_P for more details). */ |
575 RTX_FRAME_RELATED_P (insn) = 1; | 691 RTX_FRAME_RELATED_P (insn) = 1; |
576 REG_NOTES (insn) = | 692 add_reg_note (insn, REG_FRAME_RELATED_EXPR, |
577 gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR, | 693 gen_rtx_SET (VOIDmode, stack_pointer_reg, |
578 gen_rtx_SET (VOIDmode, stack_pointer_reg, | 694 gen_rtx_PLUS (Pmode, stack_pointer_reg, |
579 gen_rtx_PLUS (Pmode, stack_pointer_reg, | 695 GEN_INT (-adjustment)))); |
580 GEN_INT (-adjustment))), | |
581 REG_NOTES (insn)); | |
582 | 696 |
583 } | 697 } |
584 | 698 |
585 /* Emit an instruction to save a register of the given mode. The | 699 /* Emit an instruction to save a register of the given mode. The |
586 offset at which to save the register is given relative to the stack | 700 offset at which to save the register is given relative to the stack |
629 GEN_INT (offset + | 743 GEN_INT (offset + |
630 2))), | 744 2))), |
631 gen_rtx_REG (HImode, REGNO (reg) + 1)); | 745 gen_rtx_REG (HImode, REGNO (reg) + 1)); |
632 RTX_FRAME_RELATED_P (RTVEC_ELT (p, 1)) = 1; | 746 RTX_FRAME_RELATED_P (RTVEC_ELT (p, 1)) = 1; |
633 | 747 |
634 REG_NOTES (insn) = | 748 add_reg_note (insn, REG_FRAME_RELATED_EXPR, |
635 gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR, | 749 gen_rtx_PARALLEL (VOIDmode, p)); |
636 gen_rtx_PARALLEL (VOIDmode, p), | |
637 REG_NOTES (insn)); | |
638 | 750 |
639 } | 751 } |
640 break; | 752 break; |
641 | 753 |
642 default: | 754 default: |
643 internal_error | 755 internal_error |
644 ("unexpected mode %s encountered in picochip_emit_save_register\n", | 756 ("unexpected mode %s encountered in picochip_emit_save_register", |
645 GET_MODE_NAME (GET_MODE (reg))); | 757 GET_MODE_NAME (GET_MODE (reg))); |
646 } | 758 } |
647 | 759 |
648 } | 760 } |
649 | 761 |
651 offset from which to restore the register is given relative to the | 763 offset from which to restore the register is given relative to the |
652 stack pointer. */ | 764 stack pointer. */ |
653 static void | 765 static void |
654 picochip_emit_restore_register (rtx reg, int offset) | 766 picochip_emit_restore_register (rtx reg, int offset) |
655 { | 767 { |
656 rtx stack_pointer, address, mem, insn; | 768 rtx stack_pointer, address, mem; |
657 | 769 |
658 stack_pointer = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM); | 770 stack_pointer = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM); |
659 | 771 |
660 address = gen_rtx_PLUS (Pmode, stack_pointer, GEN_INT (offset)); | 772 address = gen_rtx_PLUS (Pmode, stack_pointer, GEN_INT (offset)); |
661 | 773 |
662 mem = gen_rtx_MEM (GET_MODE (reg), address); | 774 mem = gen_rtx_MEM (GET_MODE (reg), address); |
663 | 775 |
664 insn = emit_move_insn (reg, mem); | 776 emit_move_insn (reg, mem); |
665 | 777 |
666 } | 778 } |
667 | 779 |
668 /* Check that the given byte offset is aligned to the given number of | 780 /* Check that the given byte offset is aligned to the given number of |
669 bits. */ | 781 bits. */ |
710 * | 822 * |
711 ****************************************************************************/ | 823 ****************************************************************************/ |
712 | 824 |
713 /* Compute the size of an argument in units. */ | 825 /* Compute the size of an argument in units. */ |
714 static int | 826 static int |
715 picochip_compute_arg_size (tree type, enum machine_mode mode) | 827 picochip_compute_arg_size (const_tree type, enum machine_mode mode) |
716 { | 828 { |
717 int type_size_in_units = 0; | 829 int type_size_in_units = 0; |
718 | 830 |
719 if (type) | 831 if (type) |
720 type_size_in_units = tree_low_cst (TYPE_SIZE_UNIT (type), 1); | 832 type_size_in_units = tree_low_cst (TYPE_SIZE_UNIT (type), 1); |
725 | 837 |
726 } | 838 } |
727 | 839 |
728 /* Determine where the next outgoing arg should be placed. */ | 840 /* Determine where the next outgoing arg should be placed. */ |
729 rtx | 841 rtx |
730 picochip_function_arg (CUMULATIVE_ARGS cum, int mode, tree type, | 842 picochip_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, |
731 int named ATTRIBUTE_UNUSED) | 843 const_tree type, bool named ATTRIBUTE_UNUSED) |
732 { | 844 { |
733 int reg = 0; | 845 int reg = 0; |
734 int type_align_in_units = 0; | 846 int type_align_in_units = 0; |
735 int type_size_in_units; | 847 int type_size_in_units; |
736 int new_offset = 0; | 848 int new_offset = 0; |
741 if (mode == VOIDmode) | 853 if (mode == VOIDmode) |
742 return 0; | 854 return 0; |
743 | 855 |
744 /* Compute the alignment and size of the parameter. */ | 856 /* Compute the alignment and size of the parameter. */ |
745 type_align_in_units = | 857 type_align_in_units = |
746 picochip_get_function_arg_boundary (mode) / BITS_PER_UNIT; | 858 picochip_function_arg_boundary (mode, type) / BITS_PER_UNIT; |
747 type_size_in_units = picochip_compute_arg_size (type, mode); | 859 type_size_in_units = picochip_compute_arg_size (type, mode); |
748 | 860 |
749 /* Compute the correct offset (i.e., ensure that the offset meets | 861 /* Compute the correct offset (i.e., ensure that the offset meets |
750 the alignment requirements). */ | 862 the alignment requirements). */ |
751 offset_overflow = cum % type_align_in_units; | 863 offset_overflow = *cum % type_align_in_units; |
752 if (offset_overflow == 0) | 864 if (offset_overflow == 0) |
753 new_offset = cum; | 865 new_offset = *cum; |
754 else | 866 else |
755 new_offset = (cum - offset_overflow) + type_align_in_units; | 867 new_offset = (*cum - offset_overflow) + type_align_in_units; |
756 | 868 |
757 if (TARGET_DEBUG) | 869 if (TARGET_DEBUG) |
758 { | 870 { |
759 printf ("Function arg:\n"); | 871 printf ("Function arg:\n"); |
760 printf (" Type valid: %s\n", (type ? "yes" : "no")); | 872 printf (" Type valid: %s\n", (type ? "yes" : "no")); |
761 printf (" Cumulative Value: %d\n", cum); | 873 printf (" Cumulative Value: %d\n", *cum); |
762 printf (" Mode: %s\n", GET_MODE_NAME (mode)); | 874 printf (" Mode: %s\n", GET_MODE_NAME (mode)); |
763 printf (" Type size: %i units\n", type_size_in_units); | 875 printf (" Type size: %i units\n", type_size_in_units); |
764 printf (" Alignment: %i units\n", type_align_in_units); | 876 printf (" Alignment: %i units\n", type_align_in_units); |
765 printf (" New offset: %i\n", new_offset); | 877 printf (" New offset: %i\n", new_offset); |
766 printf ("\n"); | 878 printf ("\n"); |
790 case DDmode: | 902 case DDmode: |
791 case CHImode: | 903 case CHImode: |
792 case CSImode: | 904 case CSImode: |
793 case SCmode: | 905 case SCmode: |
794 case CQImode: | 906 case CQImode: |
795 return gen_rtx_REG ((enum machine_mode) mode, reg); | 907 return gen_rtx_REG (mode, reg); |
796 | 908 |
797 case BLKmode: | 909 case BLKmode: |
798 { | 910 { |
799 /* Empty blockmode values can be passed as arguments (e.g., | 911 /* Empty blockmode values can be passed as arguments (e.g., |
800 * empty structs). These require no registers | 912 * empty structs). These require no registers |
806 return picochip_emit_register_parallel (type_size_in_units, new_offset); | 918 return picochip_emit_register_parallel (type_size_in_units, new_offset); |
807 } | 919 } |
808 | 920 |
809 default: | 921 default: |
810 warning | 922 warning |
811 (0, "Defaulting to stack for %s register creation\n", | 923 (0, "defaulting to stack for %s register creation", |
812 GET_MODE_NAME (mode)); | 924 GET_MODE_NAME (mode)); |
813 break; | 925 break; |
814 } | 926 } |
815 | 927 |
816 return 0; | 928 return 0; |
823 varadic function. In this case, the incoming arguments all appear | 935 varadic function. In this case, the incoming arguments all appear |
824 to be passed on the stack (actually, some of the arguments are | 936 to be passed on the stack (actually, some of the arguments are |
825 passed in registers, which are then pushed onto the stack by the | 937 passed in registers, which are then pushed onto the stack by the |
826 function prologue). */ | 938 function prologue). */ |
827 rtx | 939 rtx |
828 picochip_incoming_function_arg (CUMULATIVE_ARGS cum, int mode, | 940 picochip_incoming_function_arg (CUMULATIVE_ARGS *cum, |
829 tree type, int named) | 941 enum machine_mode mode, |
942 const_tree type, bool named) | |
830 { | 943 { |
831 | 944 |
832 if (cfun->stdarg) | 945 if (cfun->stdarg) |
833 return 0; | 946 return 0; |
834 else | 947 else |
836 | 949 |
837 } | 950 } |
838 | 951 |
839 /* Gives the alignment boundary, in bits, of an argument with the | 952 /* Gives the alignment boundary, in bits, of an argument with the |
840 specified mode. */ | 953 specified mode. */ |
841 int | 954 unsigned int |
842 picochip_get_function_arg_boundary (enum machine_mode mode) | 955 picochip_function_arg_boundary (enum machine_mode mode, |
956 const_tree type ATTRIBUTE_UNUSED) | |
843 { | 957 { |
844 int align; | 958 int align; |
845 | 959 |
846 if (mode == BLKmode) | 960 if (mode == BLKmode) |
847 align = STACK_BOUNDARY; | 961 align = STACK_BOUNDARY; |
872 if (mode == VOIDmode) | 986 if (mode == VOIDmode) |
873 return 0; | 987 return 0; |
874 | 988 |
875 /* Compute the alignment and size of the parameter. */ | 989 /* Compute the alignment and size of the parameter. */ |
876 type_align_in_units = | 990 type_align_in_units = |
877 picochip_get_function_arg_boundary (mode) / BITS_PER_UNIT; | 991 picochip_function_arg_boundary (mode, type) / BITS_PER_UNIT; |
878 type_size_in_units = picochip_compute_arg_size (type, mode); | 992 type_size_in_units = picochip_compute_arg_size (type, mode); |
879 | 993 |
880 /* Compute the correct offset (i.e., ensure that the offset meets | 994 /* Compute the correct offset (i.e., ensure that the offset meets |
881 the alignment requirements). */ | 995 the alignment requirements). */ |
882 offset_overflow = cum % type_align_in_units; | 996 offset_overflow = cum % type_align_in_units; |
909 | 1023 |
910 return 0; | 1024 return 0; |
911 | 1025 |
912 } | 1026 } |
913 | 1027 |
914 /* Advance the cumulative args counter, returning the new counter. */ | 1028 /* Advance the cumulative args counter CUM. */ |
915 CUMULATIVE_ARGS | 1029 void |
916 picochip_arg_advance (const CUMULATIVE_ARGS cum, int mode, | 1030 picochip_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode, |
917 tree type, int named ATTRIBUTE_UNUSED) | 1031 const_tree type, bool named ATTRIBUTE_UNUSED) |
918 { | 1032 { |
919 int type_align_in_units = 0; | 1033 int type_align_in_units = 0; |
920 int type_size_in_units; | 1034 int type_size_in_units; |
921 int new_offset = 0; | 1035 int new_offset = 0; |
922 int offset_overflow = 0; | 1036 int offset_overflow = 0; |
923 | 1037 |
924 /* VOIDmode is passed when computing the second argument to a `call' | 1038 /* VOIDmode is passed when computing the second argument to a `call' |
925 pattern. This can be ignored. */ | 1039 pattern. This can be ignored. */ |
926 if (mode == VOIDmode) | 1040 if (mode == VOIDmode) |
927 return 0; | 1041 return; |
928 | 1042 |
929 /* Compute the alignment and size of the parameter. */ | 1043 /* Compute the alignment and size of the parameter. */ |
930 type_align_in_units = | 1044 type_align_in_units = |
931 picochip_get_function_arg_boundary (mode) / BITS_PER_UNIT; | 1045 picochip_function_arg_boundary (mode, type) / BITS_PER_UNIT; |
932 type_size_in_units = picochip_compute_arg_size (type, mode); | 1046 type_size_in_units = picochip_compute_arg_size (type, mode); |
933 | 1047 |
934 /* Compute the correct offset (i.e., ensure that the offset meets | 1048 /* Compute the correct offset (i.e., ensure that the offset meets |
935 the alignment requirements). */ | 1049 the alignment requirements). */ |
936 offset_overflow = cum % type_align_in_units; | 1050 offset_overflow = *cum % type_align_in_units; |
937 if (offset_overflow == 0) | 1051 if (offset_overflow == 0) |
938 new_offset = cum; | 1052 new_offset = *cum; |
939 else | 1053 else |
940 new_offset = (cum - offset_overflow) + type_align_in_units; | 1054 new_offset = (*cum - offset_overflow) + type_align_in_units; |
941 | 1055 |
942 /* Advance past the last argument. */ | 1056 /* Advance past the last argument. */ |
943 new_offset += type_size_in_units; | 1057 new_offset += type_size_in_units; |
944 | 1058 |
945 return new_offset; | 1059 *cum = new_offset; |
946 | |
947 } | 1060 } |
948 | 1061 |
949 /* Determine whether a register needs saving/restoring. It does if it | 1062 /* Determine whether a register needs saving/restoring. It does if it |
950 is live in a function, and isn't a call-used register. */ | 1063 is live in a function, and isn't a call-used register. */ |
951 static int | 1064 static int |
1147 return ((GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD); | 1260 return ((GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD); |
1148 | 1261 |
1149 } | 1262 } |
1150 | 1263 |
1151 int | 1264 int |
1152 picochip_class_max_nregs (int class, int mode) | 1265 picochip_class_max_nregs (int reg_class, int mode) |
1153 { | 1266 { |
1154 int size = ((GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD); | 1267 int size = ((GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD); |
1155 | 1268 |
1156 if (class == ACC_REGS) | 1269 if (reg_class == ACC_REGS) |
1157 return 1; | 1270 return 1; |
1158 | 1271 |
1159 if (GET_MODE_CLASS (mode) == MODE_CC) | 1272 if (GET_MODE_CLASS (mode) == MODE_CC) |
1160 return 1; | 1273 return 1; |
1161 else | 1274 else |
1336 */ | 1449 */ |
1337 rtx | 1450 rtx |
1338 picochip_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED, | 1451 picochip_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED, |
1339 enum machine_mode mode) | 1452 enum machine_mode mode) |
1340 { | 1453 { |
1454 unsigned mask_val; | |
1455 | |
1341 if (!optimize) | 1456 if (!optimize) |
1342 return x; | 1457 return x; |
1343 | 1458 |
1344 unsigned mask_val; | 1459 /* Depending on mode, the offsets allowed are either 16/32/64.*/ |
1345 // Depending on mode, the offsets allowed are either 16/32/64. | |
1346 switch (mode) | 1460 switch (mode) |
1347 { | 1461 { |
1348 case QImode: | 1462 case QImode: |
1349 mask_val = 0xFFF0; | 1463 mask_val = 0xFFF0; |
1350 break; | 1464 break; |
1360 | 1474 |
1361 if (GET_CODE (x) == PLUS | 1475 if (GET_CODE (x) == PLUS |
1362 && GET_CODE (XEXP (x, 0)) == REG | 1476 && GET_CODE (XEXP (x, 0)) == REG |
1363 && GET_CODE (XEXP (x, 1)) == CONST_INT) | 1477 && GET_CODE (XEXP (x, 1)) == CONST_INT) |
1364 { | 1478 { |
1365 int offset = INTVAL (XEXP (x, 1)); | 1479 int high_val, low_val, offset; |
1366 // Ignore cases with negative offsets. | 1480 offset = INTVAL (XEXP (x, 1)); |
1481 /* Ignore cases with negative offsets. */ | |
1367 if (offset < 0) | 1482 if (offset < 0) |
1368 return x; | 1483 return x; |
1369 int high_val = offset & mask_val; | 1484 high_val = offset & mask_val; |
1370 int low_val = offset - high_val; | 1485 low_val = offset - high_val; |
1371 if (high_val != 0) | 1486 if (high_val != 0) |
1372 { | 1487 { |
1373 rtx temp_reg = force_reg (Pmode, gen_rtx_PLUS (Pmode, XEXP (x, 0), GEN_INT(high_val))); | 1488 rtx temp_reg = force_reg (Pmode, gen_rtx_PLUS (Pmode, XEXP (x, 0), GEN_INT(high_val))); |
1374 x = gen_rtx_PLUS (Pmode, temp_reg, GEN_INT(low_val)); | 1489 x = gen_rtx_PLUS (Pmode, temp_reg, GEN_INT(low_val)); |
1375 return x; | 1490 return x; |
1395 picochip_legitimize_reload_address (rtx *x, | 1510 picochip_legitimize_reload_address (rtx *x, |
1396 enum machine_mode mode, | 1511 enum machine_mode mode, |
1397 int opnum, int type, | 1512 int opnum, int type, |
1398 int ind_levels ATTRIBUTE_UNUSED) | 1513 int ind_levels ATTRIBUTE_UNUSED) |
1399 { | 1514 { |
1515 unsigned mask_val; | |
1516 | |
1400 if (picochip_symbol_offset(*x)) | 1517 if (picochip_symbol_offset(*x)) |
1401 { | 1518 { |
1402 *x = gen_rtx_CONST(mode, *x); | 1519 *x = gen_rtx_CONST(mode, *x); |
1403 return 0; | 1520 return 0; |
1404 } | 1521 } |
1416 BASE_REG_CLASS, GET_MODE (*x), VOIDmode, 0, 0, | 1533 BASE_REG_CLASS, GET_MODE (*x), VOIDmode, 0, 0, |
1417 opnum, (enum reload_type)type); | 1534 opnum, (enum reload_type)type); |
1418 return 1; | 1535 return 1; |
1419 } | 1536 } |
1420 | 1537 |
1421 unsigned mask_val; | 1538 /* Depending on mode, the offsets allowed are either 16/32/64. */ |
1422 // Depending on mode, the offsets allowed are either 16/32/64. | |
1423 switch (mode) | 1539 switch (mode) |
1424 { | 1540 { |
1425 case QImode: | 1541 case QImode: |
1426 mask_val = 0xFFF0; | 1542 mask_val = 0xFFF0; |
1427 break; | 1543 break; |
1437 | 1553 |
1438 if (GET_CODE (*x) == PLUS | 1554 if (GET_CODE (*x) == PLUS |
1439 && GET_CODE (XEXP (*x, 0)) == REG | 1555 && GET_CODE (XEXP (*x, 0)) == REG |
1440 && GET_CODE (XEXP (*x, 1)) == CONST_INT) | 1556 && GET_CODE (XEXP (*x, 1)) == CONST_INT) |
1441 { | 1557 { |
1442 int offset = INTVAL (XEXP (*x, 1)); | 1558 int high_val, low_val, offset; |
1443 // Ignore cases with negative offsets. | 1559 offset = INTVAL (XEXP (*x, 1)); |
1560 /* Ignore cases with negative offsets. */ | |
1444 if (offset < 0) | 1561 if (offset < 0) |
1445 return 0; | 1562 return 0; |
1446 int high_val = offset & mask_val; | 1563 high_val = offset & mask_val; |
1447 int low_val = offset - high_val; | 1564 low_val = offset - high_val; |
1448 if (high_val != 0) | 1565 if (high_val != 0) |
1449 { | 1566 { |
1450 rtx temp_reg = gen_rtx_PLUS (Pmode, XEXP (*x, 0), GEN_INT(high_val)); | 1567 rtx temp_reg = gen_rtx_PLUS (Pmode, XEXP (*x, 0), GEN_INT(high_val)); |
1451 *x = gen_rtx_PLUS (Pmode, temp_reg, GEN_INT(low_val)); | 1568 *x = gen_rtx_PLUS (Pmode, temp_reg, GEN_INT(low_val)); |
1452 push_reload (XEXP (*x, 0), NULL_RTX, &XEXP (*x, 0), NULL, | 1569 push_reload (XEXP (*x, 0), NULL_RTX, &XEXP (*x, 0), NULL, |
1485 if (picochip_schedule_type == DFA_TYPE_SPEED && | 1602 if (picochip_schedule_type == DFA_TYPE_SPEED && |
1486 is_cfi_label && picochip_vliw_continuation) | 1603 is_cfi_label && picochip_vliw_continuation) |
1487 { | 1604 { |
1488 if (picochip_current_vliw_state.num_cfi_labels_deferred == 2) | 1605 if (picochip_current_vliw_state.num_cfi_labels_deferred == 2) |
1489 { | 1606 { |
1490 internal_error ("LCFI labels have already been deferred."); | 1607 internal_error ("LCFI labels have already been deferred"); |
1491 } | 1608 } |
1492 strcpy (picochip_current_vliw_state.cfi_label_name[ | 1609 strcpy (picochip_current_vliw_state.cfi_label_name[ |
1493 picochip_current_vliw_state.num_cfi_labels_deferred], name); | 1610 picochip_current_vliw_state.num_cfi_labels_deferred], name); |
1494 picochip_current_vliw_state.num_cfi_labels_deferred++; | 1611 picochip_current_vliw_state.num_cfi_labels_deferred++; |
1495 } | 1612 } |
1548 never been a need to handle more than one lm label at a time. */ | 1665 never been a need to handle more than one lm label at a time. */ |
1549 if (picochip_schedule_type == DFA_TYPE_SPEED && | 1666 if (picochip_schedule_type == DFA_TYPE_SPEED && |
1550 (strcmp (prefix, "LM")) == 0 && picochip_vliw_continuation) | 1667 (strcmp (prefix, "LM")) == 0 && picochip_vliw_continuation) |
1551 { | 1668 { |
1552 if (strlen (picochip_current_vliw_state.lm_label_name) != 0) | 1669 if (strlen (picochip_current_vliw_state.lm_label_name) != 0) |
1553 internal_error ("LM label has already been deferred."); | 1670 internal_error ("LM label has already been deferred"); |
1554 | 1671 |
1555 sprintf (picochip_current_vliw_state.lm_label_name, | 1672 sprintf (picochip_current_vliw_state.lm_label_name, |
1556 "picoMark_%s%ld", prefix, num); | 1673 "picoMark_%s%ld", prefix, num); |
1674 } | |
1675 else if (picochip_schedule_type == DFA_TYPE_SPEED && | |
1676 (strcmp (prefix, "LCFI")) == 0 && picochip_vliw_continuation) | |
1677 { | |
1678 if (picochip_current_vliw_state.num_cfi_labels_deferred == 2) | |
1679 { | |
1680 internal_error ("LCFI labels have already been deferred."); | |
1681 } | |
1682 sprintf(picochip_current_vliw_state.cfi_label_name[ | |
1683 picochip_current_vliw_state.num_cfi_labels_deferred], | |
1684 "picoMark_%s%ld", prefix, num); | |
1685 picochip_current_vliw_state.num_cfi_labels_deferred++; | |
1557 } | 1686 } |
1558 else | 1687 else |
1559 { | 1688 { |
1560 /* Marker label. */ | 1689 /* Marker label. */ |
1561 fprintf (stream, "_picoMark_%s%ld=\n", prefix, num); | 1690 fprintf (stream, "_picoMark_%s%ld=\n", prefix, num); |
1634 | 1763 |
1635 fprintf (file, ".ascii "); | 1764 fprintf (file, ".ascii "); |
1636 | 1765 |
1637 for (i = 0; i < length; ++i) | 1766 for (i = 0; i < length; ++i) |
1638 { | 1767 { |
1639 fprintf (file, "16#%hhx# ", (char) (str[i])); | 1768 fprintf (file, "16#%x# ", (char) (str[i])); |
1640 } | 1769 } |
1641 | 1770 |
1642 fprintf (file, " ; "); | 1771 fprintf (file, " ; "); |
1643 | 1772 |
1644 for (i = 0; i < length; ++i) | 1773 for (i = 0; i < length; ++i) |
1685 else | 1814 else |
1686 fprintf (asm_out_file, "// Has multiply: No\n"); | 1815 fprintf (asm_out_file, "// Has multiply: No\n"); |
1687 | 1816 |
1688 /* Variable tracking should be run after all optimizations which change order | 1817 /* Variable tracking should be run after all optimizations which change order |
1689 of insns. It also needs a valid CFG. This can't be done in | 1818 of insns. It also needs a valid CFG. This can't be done in |
1690 picochip_override_options, because flag_var_tracking is finalized after | 1819 picochip_option_override, because flag_var_tracking is finalized after |
1691 that. */ | 1820 that. */ |
1692 picochip_flag_var_tracking = flag_var_tracking; | 1821 picochip_flag_var_tracking = flag_var_tracking; |
1693 flag_var_tracking = 0; | 1822 flag_var_tracking = 0; |
1694 } | 1823 } |
1695 | 1824 |
1828 /* If the instruction uses multiple lines (i.e., a new line | 1957 /* If the instruction uses multiple lines (i.e., a new line |
1829 character appears in the opcode), then ensure that no attempt is | 1958 character appears in the opcode), then ensure that no attempt is |
1830 made to pack it into a VLIW. */ | 1959 made to pack it into a VLIW. */ |
1831 if (strchr (ptr, '\n') != NULL && picochip_vliw_continuation) | 1960 if (strchr (ptr, '\n') != NULL && picochip_vliw_continuation) |
1832 internal_error | 1961 internal_error |
1833 ("picochip_asm_output_opcode - Found multiple lines in VLIW packet %s\n", | 1962 ("picochip_asm_output_opcode - Found multiple lines in VLIW packet %s", |
1834 ptr); | 1963 ptr); |
1835 | 1964 |
1836 | 1965 |
1837 /* If a delay slot is pending, output the directive to the assembler | 1966 /* If a delay slot is pending, output the directive to the assembler |
1838 before the instruction. */ | 1967 before the instruction. */ |
1931 while ((c = *ptr) >= '0' && c <= '9') | 2060 while ((c = *ptr) >= '0' && c <= '9') |
1932 ptr++; | 2061 ptr++; |
1933 } | 2062 } |
1934 else if (c == '%') | 2063 else if (c == '%') |
1935 internal_error | 2064 internal_error |
1936 ("picochip_asm_output_opcode - can't output unknown operator %c\n", | 2065 ("picochip_asm_output_opcode - can%'t output unknown operator %c", |
1937 *ptr); | 2066 *ptr); |
1938 else | 2067 else |
1939 fputc (c, f); | 2068 fputc (c, f); |
1940 } | 2069 } |
1941 | 2070 |
2169 picochip_is_short_branch (rtx insn) | 2298 picochip_is_short_branch (rtx insn) |
2170 { | 2299 { |
2171 int isRealShortBranch = (get_attr_length(insn) == SHORT_BRANCH_LENGTH); | 2300 int isRealShortBranch = (get_attr_length(insn) == SHORT_BRANCH_LENGTH); |
2172 | 2301 |
2173 return (isRealShortBranch || | 2302 return (isRealShortBranch || |
2174 (!isRealShortBranch && | 2303 picochip_current_vliw_state.num_insns_in_packet > 1); |
2175 picochip_current_vliw_state.num_insns_in_packet > 1)); | |
2176 } | 2304 } |
2177 | 2305 |
2178 /* Output a compare-and-branch instruction (matching the cbranch | 2306 /* Output a compare-and-branch instruction (matching the cbranch |
2179 pattern). */ | 2307 pattern). */ |
2180 const char * | 2308 const char * |
2183 | 2311 |
2184 if (HImode != GET_MODE (operands[1]) || | 2312 if (HImode != GET_MODE (operands[1]) || |
2185 (HImode != GET_MODE (operands[2]) && | 2313 (HImode != GET_MODE (operands[2]) && |
2186 GET_CODE (operands[2]) != CONST_INT)) | 2314 GET_CODE (operands[2]) != CONST_INT)) |
2187 { | 2315 { |
2188 internal_error ("%s: At least one operand can't be handled", | 2316 internal_error ("%s: at least one operand can%'t be handled", |
2189 __FUNCTION__); | 2317 __FUNCTION__); |
2190 } | 2318 } |
2191 | 2319 |
2192 /* Use the type of comparison to output the appropriate condition | 2320 /* Use the type of comparison to output the appropriate condition |
2193 test. */ | 2321 test. */ |
2237 split is disabled. The function is kept around so we can use | 2365 split is disabled. The function is kept around so we can use |
2238 it when we understand how to do cbranch split safely. */ | 2366 it when we understand how to do cbranch split safely. */ |
2239 const char * | 2367 const char * |
2240 picochip_output_compare (rtx operands[]) | 2368 picochip_output_compare (rtx operands[]) |
2241 { | 2369 { |
2370 int code; | |
2242 | 2371 |
2243 if (HImode != GET_MODE (operands[1]) || | 2372 if (HImode != GET_MODE (operands[1]) || |
2244 (HImode != GET_MODE (operands[2]) && | 2373 (HImode != GET_MODE (operands[2]) && |
2245 GET_CODE (operands[2]) != CONST_INT)) | 2374 GET_CODE (operands[2]) != CONST_INT)) |
2246 { | 2375 { |
2247 internal_error ("%s: At least one operand can't be handled", | 2376 internal_error ("%s: at least one operand can%'t be handled", |
2248 __FUNCTION__); | 2377 __FUNCTION__); |
2249 } | 2378 } |
2250 | 2379 |
2380 code = GET_CODE (operands[0]); | |
2251 /* Use the type of comparison to output the appropriate condition | 2381 /* Use the type of comparison to output the appropriate condition |
2252 test. */ | 2382 test. */ |
2253 int code = GET_CODE (operands[0]); | |
2254 switch (code) | 2383 switch (code) |
2255 { | 2384 { |
2256 case NE: | 2385 case NE: |
2257 return ("SUB.%# %1,%2,r15\t// CC := (%0)"); | 2386 return ("SUB.%# %1,%2,r15\t// CC := (%0)"); |
2258 | 2387 |
2323 case GT: | 2452 case GT: |
2324 return ("BLT %l0 %>"); | 2453 return ("BLT %l0 %>"); |
2325 case GTU: | 2454 case GTU: |
2326 return ("BLO %l0 %>"); | 2455 return ("BLO %l0 %>"); |
2327 default: | 2456 default: |
2328 internal_error ("Unknown short branch in %s (type %d)\n", | 2457 internal_error ("unknown short branch in %s (type %d)", |
2329 __FUNCTION__, (int) INTVAL (operands[1])); | 2458 __FUNCTION__, (int) INTVAL (operands[1])); |
2330 return "UNKNOWN_BRANCH"; | 2459 return "UNKNOWN_BRANCH"; |
2331 } | 2460 } |
2332 } | 2461 } |
2333 else | 2462 else |
2360 return ("JMPLT %l0 %>"); | 2489 return ("JMPLT %l0 %>"); |
2361 case GTU: | 2490 case GTU: |
2362 return ("JMPLO %l0 %>"); | 2491 return ("JMPLO %l0 %>"); |
2363 | 2492 |
2364 default: | 2493 default: |
2365 internal_error ("Unknown long branch in %s (type %d)\n", | 2494 internal_error ("unknown long branch in %s (type %d)", |
2366 __FUNCTION__, (int) INTVAL (operands[1])); | 2495 __FUNCTION__, (int) INTVAL (operands[1])); |
2367 return "UNKNOWN_BRANCH"; | 2496 return "UNKNOWN_BRANCH"; |
2368 } | 2497 } |
2369 | 2498 |
2370 } | 2499 } |
3062 three-instruction bundle. */ | 3191 three-instruction bundle. */ |
3063 static void | 3192 static void |
3064 reorder_var_tracking_notes (void) | 3193 reorder_var_tracking_notes (void) |
3065 { | 3194 { |
3066 basic_block bb; | 3195 basic_block bb; |
3196 | |
3067 FOR_EACH_BB (bb) | 3197 FOR_EACH_BB (bb) |
3068 { | 3198 { |
3069 rtx insn, next; | 3199 rtx insn, next, last_insn = NULL_RTX; |
3070 rtx queue = NULL_RTX; | 3200 rtx queue = NULL_RTX; |
3071 | 3201 |
3072 for (insn = BB_HEAD (bb); insn != BB_END (bb); insn = next) | 3202 /* Iterate through the bb and find the last non-debug insn */ |
3073 { | 3203 for (insn = BB_HEAD (bb); insn != NEXT_INSN(BB_END (bb)); insn = NEXT_INSN(insn)) |
3074 next = NEXT_INSN (insn); | 3204 { |
3075 | 3205 if (NONDEBUG_INSN_P(insn)) |
3076 if (NONDEBUG_INSN_P (insn)) | 3206 last_insn = insn; |
3077 { | 3207 } |
3078 /* Emit queued up notes before the first instruction of a bundle. */ | 3208 |
3079 if (GET_MODE (insn) == TImode) | 3209 /* In all normal cases, queue up notes and emit them just before a TImode |
3080 { | 3210 instruction. For the last instruction, emit the queued notes just after |
3081 while (queue) | 3211 the last instruction. */ |
3082 { | 3212 for (insn = BB_HEAD (bb); insn != NEXT_INSN(BB_END (bb)); insn = next) |
3083 rtx next_queue = PREV_INSN (queue); | 3213 { |
3084 NEXT_INSN (PREV_INSN(insn)) = queue; | 3214 next = NEXT_INSN (insn); |
3085 PREV_INSN (queue) = PREV_INSN(insn); | 3215 |
3086 PREV_INSN (insn) = queue; | 3216 if (insn == last_insn) |
3087 NEXT_INSN (queue) = insn; | 3217 { |
3088 queue = next_queue; | 3218 while (queue) |
3089 } | 3219 { |
3090 } | 3220 rtx next_queue = PREV_INSN (queue); |
3091 } | 3221 PREV_INSN (NEXT_INSN(insn)) = queue; |
3092 else if (NOTE_P (insn) && NOTE_KIND (insn) == NOTE_INSN_VAR_LOCATION) | 3222 NEXT_INSN(queue) = NEXT_INSN(insn); |
3093 { | 3223 PREV_INSN(queue) = insn; |
3094 rtx prev = PREV_INSN (insn); | 3224 NEXT_INSN(insn) = queue; |
3095 PREV_INSN (next) = prev; | 3225 queue = next_queue; |
3096 NEXT_INSN (prev) = next; | 3226 } |
3227 /* There is no more to do for this bb. break*/ | |
3228 break; | |
3229 } | |
3230 else if (NONDEBUG_INSN_P (insn)) | |
3231 { | |
3232 /* Emit queued up notes before the first instruction of a bundle. */ | |
3233 if (GET_MODE (insn) == TImode) | |
3234 { | |
3235 while (queue) | |
3236 { | |
3237 rtx next_queue = PREV_INSN (queue); | |
3238 NEXT_INSN (PREV_INSN(insn)) = queue; | |
3239 PREV_INSN (queue) = PREV_INSN(insn); | |
3240 PREV_INSN (insn) = queue; | |
3241 NEXT_INSN (queue) = insn; | |
3242 queue = next_queue; | |
3243 } | |
3244 } | |
3245 } | |
3246 else if (NOTE_P (insn) && NOTE_KIND (insn) == NOTE_INSN_VAR_LOCATION) | |
3247 { | |
3248 rtx prev = PREV_INSN (insn); | |
3249 PREV_INSN (next) = prev; | |
3250 NEXT_INSN (prev) = next; | |
3097 PREV_INSN (insn) = queue; | 3251 PREV_INSN (insn) = queue; |
3098 queue = insn; | 3252 queue = insn; |
3099 } | 3253 } |
3100 } | 3254 } |
3255 /* Make sure we are not dropping debug instructions.*/ | |
3256 gcc_assert (queue == NULL_RTX); | |
3101 } | 3257 } |
3102 } | 3258 } |
3103 | 3259 |
3104 /* Perform machine dependent operations on the rtl chain INSNS. */ | 3260 /* Perform machine dependent operations on the rtl chain INSNS. */ |
3105 void | 3261 void |
3186 rtx last_insn_in_packet = NULL; | 3342 rtx last_insn_in_packet = NULL; |
3187 | 3343 |
3188 for (insn = get_insns (); insn; insn = next_insn (insn)) | 3344 for (insn = get_insns (); insn; insn = next_insn (insn)) |
3189 { | 3345 { |
3190 /* The prologue end must be moved to the end of the VLIW packet. */ | 3346 /* The prologue end must be moved to the end of the VLIW packet. */ |
3191 if (NOTE_KIND (insn) == NOTE_INSN_PROLOGUE_END) | 3347 if (NOTE_P (insn) && NOTE_KIND (insn) == NOTE_INSN_PROLOGUE_END) |
3192 { | 3348 { |
3193 prologue_end_note = insn; | 3349 prologue_end_note = insn; |
3194 break; | 3350 break; |
3195 } | 3351 } |
3196 } | 3352 } |
3204 last_insn_in_packet = insn; | 3360 last_insn_in_packet = insn; |
3205 } | 3361 } |
3206 | 3362 |
3207 if (last_insn_in_packet != NULL) | 3363 if (last_insn_in_packet != NULL) |
3208 { | 3364 { |
3209 rtx tmp_note = emit_note_after (NOTE_KIND(prologue_end_note), last_insn_in_packet); | 3365 rtx tmp_note |
3366 = emit_note_after ((enum insn_note) NOTE_KIND (prologue_end_note), | |
3367 last_insn_in_packet); | |
3210 memcpy(&NOTE_DATA (tmp_note), &NOTE_DATA(prologue_end_note), sizeof(NOTE_DATA(prologue_end_note))); | 3368 memcpy(&NOTE_DATA (tmp_note), &NOTE_DATA(prologue_end_note), sizeof(NOTE_DATA(prologue_end_note))); |
3211 delete_insn (prologue_end_note); | 3369 delete_insn (prologue_end_note); |
3212 } | 3370 } |
3213 } | 3371 } |
3214 if (picochip_flag_var_tracking) | 3372 if (picochip_flag_var_tracking) |
3276 case 1: | 3434 case 1: |
3277 picochip_current_vliw_state.num_alu_insns_so_far++; | 3435 picochip_current_vliw_state.num_alu_insns_so_far++; |
3278 return '1'; | 3436 return '1'; |
3279 | 3437 |
3280 default: | 3438 default: |
3281 internal_error ("Too many ALU instructions emitted (%d)\n", | 3439 internal_error ("too many ALU instructions emitted (%d)", |
3282 picochip_current_vliw_state.num_alu_insns_so_far); | 3440 picochip_current_vliw_state.num_alu_insns_so_far); |
3283 return 'X'; | 3441 return 'X'; |
3284 } | 3442 } |
3285 } | 3443 } |
3286 | 3444 |
3577 rtx | 3735 rtx |
3578 gen_SImode_mem(rtx opnd1,rtx opnd2) | 3736 gen_SImode_mem(rtx opnd1,rtx opnd2) |
3579 { | 3737 { |
3580 int offset1=0,offset2=0; | 3738 int offset1=0,offset2=0; |
3581 rtx reg; | 3739 rtx reg; |
3740 rtx address; | |
3582 if (GET_CODE(XEXP(opnd1,0)) == PLUS && GET_CODE(XEXP(XEXP(opnd1,0),1)) == CONST_INT) | 3741 if (GET_CODE(XEXP(opnd1,0)) == PLUS && GET_CODE(XEXP(XEXP(opnd1,0),1)) == CONST_INT) |
3583 { | 3742 { |
3584 offset1 = INTVAL(XEXP(XEXP(opnd1,0),1)); | 3743 offset1 = INTVAL(XEXP(XEXP(opnd1,0),1)); |
3585 reg = XEXP(XEXP(opnd1,0),0); | 3744 reg = XEXP(XEXP(opnd1,0),0); |
3586 } | 3745 } |
3590 } | 3749 } |
3591 if (GET_CODE(XEXP(opnd2,0)) == PLUS && GET_CODE(XEXP(XEXP(opnd2,0),1)) == CONST_INT) | 3750 if (GET_CODE(XEXP(opnd2,0)) == PLUS && GET_CODE(XEXP(XEXP(opnd2,0),1)) == CONST_INT) |
3592 { | 3751 { |
3593 offset2 = INTVAL(XEXP(XEXP(opnd2,0),1)); | 3752 offset2 = INTVAL(XEXP(XEXP(opnd2,0),1)); |
3594 } | 3753 } |
3595 rtx address = gen_rtx_PLUS (HImode, reg, GEN_INT(minimum(offset1,offset2))); | 3754 address = gen_rtx_PLUS (HImode, reg, GEN_INT(minimum(offset1,offset2))); |
3596 return gen_rtx_MEM(SImode,address); | 3755 return gen_rtx_MEM(SImode,address); |
3597 } | 3756 } |
3598 | 3757 |
3599 bool | 3758 bool |
3600 picochip_rtx_costs (rtx x, int code, int outer_code ATTRIBUTE_UNUSED, int* total, bool speed) | 3759 picochip_rtx_costs (rtx x, int code, int outer_code ATTRIBUTE_UNUSED, int* total, bool speed) |
3778 rtx op0, pat; | 3937 rtx op0, pat; |
3779 enum machine_mode tmode, mode0; | 3938 enum machine_mode tmode, mode0; |
3780 | 3939 |
3781 /* Grab the incoming argument and emit its RTL. */ | 3940 /* Grab the incoming argument and emit its RTL. */ |
3782 arg0 = CALL_EXPR_ARG (call, 0); | 3941 arg0 = CALL_EXPR_ARG (call, 0); |
3783 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0); | 3942 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, EXPAND_NORMAL); |
3784 | 3943 |
3785 /* Determine the modes of the instruction operands. */ | 3944 /* Determine the modes of the instruction operands. */ |
3786 tmode = insn_data[icode].operand[0].mode; | 3945 tmode = insn_data[icode].operand[0].mode; |
3787 mode0 = insn_data[icode].operand[1].mode; | 3946 mode0 = insn_data[icode].operand[1].mode; |
3788 | 3947 |
3819 /* Grab the function's arguments. */ | 3978 /* Grab the function's arguments. */ |
3820 arg0 = CALL_EXPR_ARG (call, 0); | 3979 arg0 = CALL_EXPR_ARG (call, 0); |
3821 arg1 = CALL_EXPR_ARG (call, 1); | 3980 arg1 = CALL_EXPR_ARG (call, 1); |
3822 | 3981 |
3823 /* Emit rtl sequences for the function arguments. */ | 3982 /* Emit rtl sequences for the function arguments. */ |
3824 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0); | 3983 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, EXPAND_NORMAL); |
3825 op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0); | 3984 op1 = expand_expr (arg1, NULL_RTX, VOIDmode, EXPAND_NORMAL); |
3826 | 3985 |
3827 /* Get the mode's of each of the instruction operands. */ | 3986 /* Get the mode's of each of the instruction operands. */ |
3828 tmode = insn_data[icode].operand[0].mode; | 3987 tmode = insn_data[icode].operand[0].mode; |
3829 mode0 = insn_data[icode].operand[1].mode; | 3988 mode0 = insn_data[icode].operand[1].mode; |
3830 mode1 = insn_data[icode].operand[2].mode; | 3989 mode1 = insn_data[icode].operand[2].mode; |
3863 /* Grab the function's arguments. */ | 4022 /* Grab the function's arguments. */ |
3864 arg0 = CALL_EXPR_ARG (call, 0); | 4023 arg0 = CALL_EXPR_ARG (call, 0); |
3865 arg1 = CALL_EXPR_ARG (call, 1); | 4024 arg1 = CALL_EXPR_ARG (call, 1); |
3866 | 4025 |
3867 /* Emit rtl sequences for the function arguments. */ | 4026 /* Emit rtl sequences for the function arguments. */ |
3868 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0); | 4027 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, EXPAND_NORMAL); |
3869 op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0); | 4028 op1 = expand_expr (arg1, NULL_RTX, VOIDmode, EXPAND_NORMAL); |
3870 | 4029 |
3871 /* Get the mode's of each of the instruction operands. */ | 4030 /* Get the mode's of each of the instruction operands. */ |
3872 mode0 = insn_data[icode].operand[0].mode; | 4031 mode0 = insn_data[icode].operand[0].mode; |
3873 mode1 = insn_data[icode].operand[1].mode; | 4032 mode1 = insn_data[icode].operand[1].mode; |
3874 | 4033 |
3900 arg0 = CALL_EXPR_ARG (call, 0); | 4059 arg0 = CALL_EXPR_ARG (call, 0); |
3901 arg1 = CALL_EXPR_ARG (call, 1); | 4060 arg1 = CALL_EXPR_ARG (call, 1); |
3902 arg2 = CALL_EXPR_ARG (call, 2) ; | 4061 arg2 = CALL_EXPR_ARG (call, 2) ; |
3903 | 4062 |
3904 /* Emit rtl sequences for the function arguments. */ | 4063 /* Emit rtl sequences for the function arguments. */ |
3905 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0); | 4064 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, EXPAND_NORMAL); |
3906 op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0); | 4065 op1 = expand_expr (arg1, NULL_RTX, VOIDmode, EXPAND_NORMAL); |
3907 op2 = expand_expr (arg2, NULL_RTX, VOIDmode, 0); | 4066 op2 = expand_expr (arg2, NULL_RTX, VOIDmode, EXPAND_NORMAL); |
3908 | 4067 |
3909 /* The second and third operands must be constant. Nothing else will | 4068 /* The second and third operands must be constant. Nothing else will |
3910 do. */ | 4069 do. */ |
3911 if (CONST_INT != GET_CODE (op1)) | 4070 if (CONST_INT != GET_CODE (op1)) |
3912 internal_error ("%s: Second source operand is not a constant", | 4071 internal_error ("%s: Second source operand is not a constant", |
3945 arg1 = CALL_EXPR_ARG (call, 1); | 4104 arg1 = CALL_EXPR_ARG (call, 1); |
3946 arg2 = CALL_EXPR_ARG (call, 2); | 4105 arg2 = CALL_EXPR_ARG (call, 2); |
3947 arg3 = CALL_EXPR_ARG (call, 3); | 4106 arg3 = CALL_EXPR_ARG (call, 3); |
3948 | 4107 |
3949 /* Emit rtl sequences for the function arguments. */ | 4108 /* Emit rtl sequences for the function arguments. */ |
3950 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0); | 4109 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, EXPAND_NORMAL); |
3951 op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0); | 4110 op1 = expand_expr (arg1, NULL_RTX, VOIDmode, EXPAND_NORMAL); |
3952 op2 = expand_expr (arg2, NULL_RTX, VOIDmode, 0); | 4111 op2 = expand_expr (arg2, NULL_RTX, VOIDmode, EXPAND_NORMAL); |
3953 op3 = expand_expr (arg3, NULL_RTX, VOIDmode, 0); | 4112 op3 = expand_expr (arg3, NULL_RTX, VOIDmode, EXPAND_NORMAL); |
3954 | 4113 |
3955 /* The first operand must be an SImode register. */ | 4114 /* The first operand must be an SImode register. */ |
3956 if (GET_MODE (op0) != SImode || REG != GET_CODE (op0)) | 4115 if (GET_MODE (op0) != SImode || REG != GET_CODE (op0)) |
3957 op0 = copy_to_mode_reg (SImode, op0); | 4116 op0 = copy_to_mode_reg (SImode, op0); |
3958 | 4117 |
3988 arg0 = CALL_EXPR_ARG (call, 0); | 4147 arg0 = CALL_EXPR_ARG (call, 0); |
3989 arg1 = CALL_EXPR_ARG (call, 1); | 4148 arg1 = CALL_EXPR_ARG (call, 1); |
3990 arg2 = CALL_EXPR_ARG (call, 2); | 4149 arg2 = CALL_EXPR_ARG (call, 2); |
3991 | 4150 |
3992 /* Emit rtl sequences for the function arguments. */ | 4151 /* Emit rtl sequences for the function arguments. */ |
3993 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0); | 4152 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, EXPAND_NORMAL); |
3994 op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0); | 4153 op1 = expand_expr (arg1, NULL_RTX, VOIDmode, EXPAND_NORMAL); |
3995 op2 = expand_expr (arg2, NULL_RTX, VOIDmode, 0); | 4154 op2 = expand_expr (arg2, NULL_RTX, VOIDmode, EXPAND_NORMAL); |
3996 | 4155 |
3997 /* The first operand must be a HImode register, or a constant. If it | 4156 /* The first operand must be a HImode register, or a constant. If it |
3998 isn't, force it into a HImode register. */ | 4157 isn't, force it into a HImode register. */ |
3999 if (GET_MODE (op0) != HImode || REG != GET_CODE (op0)) | 4158 if (GET_MODE (op0) != HImode || REG != GET_CODE (op0)) |
4000 op0 = copy_to_mode_reg (HImode, op0); | 4159 op0 = copy_to_mode_reg (HImode, op0); |
4030 turn means that assertions work as expected. */ | 4189 turn means that assertions work as expected. */ |
4031 static rtx | 4190 static rtx |
4032 picochip_generate_halt (void) | 4191 picochip_generate_halt (void) |
4033 { | 4192 { |
4034 static int currentId = 0; | 4193 static int currentId = 0; |
4194 rtx insns; | |
4035 rtx id = GEN_INT (currentId); | 4195 rtx id = GEN_INT (currentId); |
4036 currentId += 1; | 4196 currentId += 1; |
4037 | 4197 |
4038 start_sequence(); | 4198 start_sequence(); |
4039 emit_insn (gen_halt (id)); | 4199 emit_insn (gen_halt (id)); |
4040 | 4200 |
4041 /* A barrier is inserted to prevent the compiler from thinking that | 4201 /* A barrier is inserted to prevent the compiler from thinking that |
4042 it has to continue execution after the HALT.*/ | 4202 it has to continue execution after the HALT.*/ |
4043 emit_barrier (); | 4203 emit_barrier (); |
4044 | 4204 |
4045 rtx insns = get_insns(); | 4205 insns = get_insns(); |
4046 end_sequence(); | 4206 end_sequence(); |
4047 emit_insn (insns); | 4207 emit_insn (insns); |
4048 | 4208 |
4049 return const0_rtx; | 4209 return const0_rtx; |
4050 } | 4210 } |
4053 descriptions of different types of functions (e.g., void fn(int), | 4213 descriptions of different types of functions (e.g., void fn(int), |
4054 int fn(void)), and then use these to define the builtins. */ | 4214 int fn(void)), and then use these to define the builtins. */ |
4055 void | 4215 void |
4056 picochip_init_builtins (void) | 4216 picochip_init_builtins (void) |
4057 { | 4217 { |
4218 tree noreturn; | |
4058 tree endlink = void_list_node; | 4219 tree endlink = void_list_node; |
4059 tree int_endlink = tree_cons (NULL_TREE, integer_type_node, endlink); | 4220 tree int_endlink = tree_cons (NULL_TREE, integer_type_node, endlink); |
4060 tree unsigned_endlink = tree_cons (NULL_TREE, unsigned_type_node, endlink); | 4221 tree unsigned_endlink = tree_cons (NULL_TREE, unsigned_type_node, endlink); |
4061 tree long_endlink = tree_cons (NULL_TREE, long_integer_type_node, endlink); | 4222 tree long_endlink = tree_cons (NULL_TREE, long_integer_type_node, endlink); |
4062 tree int_int_endlink = | 4223 tree int_int_endlink = |
4063 tree_cons (NULL_TREE, integer_type_node, int_endlink); | 4224 tree_cons (NULL_TREE, integer_type_node, int_endlink); |
4064 tree int_int_int_endlink = | 4225 tree int_int_int_endlink = |
4065 tree_cons (NULL_TREE, integer_type_node, int_int_endlink); | 4226 tree_cons (NULL_TREE, integer_type_node, int_int_endlink); |
4066 tree int_long_endlink = | 4227 tree int_long_endlink = |
4067 tree_cons (NULL_TREE, integer_type_node, long_endlink); | 4228 tree_cons (NULL_TREE, integer_type_node, long_endlink); |
4068 tree pchar_type_node = build_pointer_type (char_type_node); | |
4069 tree long_int_int_int_endlink = | 4229 tree long_int_int_int_endlink = |
4070 tree_cons (NULL_TREE, long_integer_type_node, int_int_int_endlink); | 4230 tree_cons (NULL_TREE, long_integer_type_node, int_int_int_endlink); |
4071 | 4231 |
4072 tree int_ftype_void, int_ftype_int, int_ftype_int_int, void_ftype_pchar; | 4232 tree int_ftype_int, int_ftype_int_int; |
4073 tree long_ftype_int, long_ftype_int_int, long_ftype_int_int_int; | 4233 tree long_ftype_int, long_ftype_int_int_int; |
4074 tree void_ftype_int_long, int_ftype_int_int_int, | 4234 tree void_ftype_int_long, int_ftype_int_int_int, |
4075 void_ftype_long_int_int_int; | 4235 void_ftype_long_int_int_int; |
4076 tree void_ftype_void, void_ftype_int, unsigned_ftype_unsigned; | 4236 tree void_ftype_void, unsigned_ftype_unsigned; |
4077 | 4237 |
4078 /* void func (void) */ | 4238 /* void func (void) */ |
4079 void_ftype_void = build_function_type (void_type_node, endlink); | 4239 void_ftype_void = build_function_type (void_type_node, endlink); |
4080 | |
4081 /* void func (void *) */ | |
4082 void_ftype_pchar | |
4083 = build_function_type (void_type_node, | |
4084 tree_cons (NULL_TREE, pchar_type_node, endlink)); | |
4085 | |
4086 /* int func (void) */ | |
4087 int_ftype_void = build_function_type (integer_type_node, endlink); | |
4088 | |
4089 /* void func (int) */ | |
4090 void_ftype_int = build_function_type (void_type_node, int_endlink); | |
4091 | 4240 |
4092 /* int func (int) */ | 4241 /* int func (int) */ |
4093 int_ftype_int = build_function_type (integer_type_node, int_endlink); | 4242 int_ftype_int = build_function_type (integer_type_node, int_endlink); |
4094 | 4243 |
4095 /* unsigned int func (unsigned int) */ | 4244 /* unsigned int func (unsigned int) */ |
4099 int_ftype_int_int | 4248 int_ftype_int_int |
4100 = build_function_type (integer_type_node, int_int_endlink); | 4249 = build_function_type (integer_type_node, int_int_endlink); |
4101 | 4250 |
4102 /* long func(int) */ | 4251 /* long func(int) */ |
4103 long_ftype_int = build_function_type (long_integer_type_node, int_endlink); | 4252 long_ftype_int = build_function_type (long_integer_type_node, int_endlink); |
4104 | |
4105 /* long func(int, int) */ | |
4106 long_ftype_int_int | |
4107 = build_function_type (long_integer_type_node, int_int_endlink); | |
4108 | 4253 |
4109 /* long func(int, int, int) */ | 4254 /* long func(int, int, int) */ |
4110 long_ftype_int_int_int | 4255 long_ftype_int_int_int |
4111 = build_function_type (long_integer_type_node, int_int_int_endlink); | 4256 = build_function_type (long_integer_type_node, int_int_int_endlink); |
4112 | 4257 |
4194 NULL, NULL_TREE); | 4339 NULL, NULL_TREE); |
4195 | 4340 |
4196 /* Halt instruction. Note that the builtin function is marked as | 4341 /* Halt instruction. Note that the builtin function is marked as |
4197 having the attribute `noreturn' so that the compiler realises | 4342 having the attribute `noreturn' so that the compiler realises |
4198 that the halt stops the program dead. */ | 4343 that the halt stops the program dead. */ |
4199 tree noreturn = tree_cons (get_identifier ("noreturn"), NULL, NULL); | 4344 noreturn = tree_cons (get_identifier ("noreturn"), NULL, NULL); |
4200 add_builtin_function ("__builtin_halt", void_ftype_void, | 4345 add_builtin_function ("__builtin_halt", void_ftype_void, |
4201 PICOCHIP_BUILTIN_HALT, BUILT_IN_MD, NULL, | 4346 PICOCHIP_BUILTIN_HALT, BUILT_IN_MD, NULL, |
4202 noreturn); | 4347 noreturn); |
4203 add_builtin_function ("picoHalt", void_ftype_void, | 4348 add_builtin_function ("picoHalt", void_ftype_void, |
4204 PICOCHIP_BUILTIN_HALT, BUILT_IN_MD, NULL, | 4349 PICOCHIP_BUILTIN_HALT, BUILT_IN_MD, NULL, |
4361 scratch register is supplied which is definitely different to the | 4506 scratch register is supplied which is definitely different to the |
4362 output register, request a register pair. This effectively gives a | 4507 output register, request a register pair. This effectively gives a |
4363 choice of two registers to choose from, so that we a guaranteed to | 4508 choice of two registers to choose from, so that we a guaranteed to |
4364 get at least one register which is different to the output | 4509 get at least one register which is different to the output |
4365 register. This trick is taken from the alpha implementation. */ | 4510 register. This trick is taken from the alpha implementation. */ |
4366 enum reg_class | 4511 static reg_class_t |
4367 picochip_secondary_reload (bool in_p, | 4512 picochip_secondary_reload (bool in_p, |
4368 rtx x ATTRIBUTE_UNUSED, | 4513 rtx x ATTRIBUTE_UNUSED, |
4369 enum reg_class cla ATTRIBUTE_UNUSED, | 4514 reg_class_t cla ATTRIBUTE_UNUSED, |
4370 enum machine_mode mode, | 4515 enum machine_mode mode, |
4371 secondary_reload_info *sri) | 4516 secondary_reload_info *sri) |
4372 { | 4517 { |
4373 if (mode == QImode && !TARGET_HAS_BYTE_ACCESS) | 4518 if (mode == QImode && !TARGET_HAS_BYTE_ACCESS) |
4374 { | 4519 { |
4375 if (in_p == 0) | 4520 if (in_p == 0) |
4376 sri->icode = CODE_FOR_reload_outqi; | 4521 sri->icode = CODE_FOR_reload_outqi; |