comparison gcc/config/iq2000/iq2000.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 /* Subroutines used for code generation on Vitesse IQ2000 processors 1 /* Subroutines used for code generation on Vitesse IQ2000 processors
2 Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 2 Copyright (C) 2003-2017 Free Software Foundation, Inc.
3 Free Software Foundation, Inc.
4 3
5 This file is part of GCC. 4 This file is part of GCC.
6 5
7 GCC is free software; you can redistribute it and/or modify 6 GCC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by 7 it under the terms of the GNU General Public License as published by
19 <http://www.gnu.org/licenses/>. */ 18 <http://www.gnu.org/licenses/>. */
20 19
21 #include "config.h" 20 #include "config.h"
22 #include "system.h" 21 #include "system.h"
23 #include "coretypes.h" 22 #include "coretypes.h"
24 #include "tm.h" 23 #include "backend.h"
24 #include "target.h"
25 #include "rtl.h"
25 #include "tree.h" 26 #include "tree.h"
26 #include "rtl.h" 27 #include "stringpool.h"
28 #include "attribs.h"
29 #include "df.h"
30 #include "memmodel.h"
31 #include "tm_p.h"
32 #include "optabs.h"
27 #include "regs.h" 33 #include "regs.h"
28 #include "hard-reg-set.h" 34 #include "emit-rtl.h"
29 #include "insn-config.h" 35 #include "recog.h"
30 #include "conditions.h" 36 #include "diagnostic-core.h"
37 #include "stor-layout.h"
38 #include "calls.h"
39 #include "varasm.h"
31 #include "output.h" 40 #include "output.h"
32 #include "insn-attr.h" 41 #include "insn-attr.h"
33 #include "flags.h" 42 #include "explow.h"
34 #include "function.h"
35 #include "expr.h" 43 #include "expr.h"
36 #include "optabs.h" 44 #include "langhooks.h"
37 #include "libfuncs.h" 45 #include "builtins.h"
38 #include "recog.h" 46
39 #include "diagnostic-core.h" 47 /* This file should be included last. */
40 #include "reload.h"
41 #include "ggc.h"
42 #include "tm_p.h"
43 #include "debug.h"
44 #include "target.h"
45 #include "target-def.h" 48 #include "target-def.h"
46 #include "langhooks.h"
47 #include "df.h"
48 49
49 /* Enumeration for all of the relational tests, so that we can build 50 /* Enumeration for all of the relational tests, so that we can build
50 arrays indexed by the test type, and not worry about the order 51 arrays indexed by the test type, and not worry about the order
51 of EQ, NE, etc. */ 52 of EQ, NE, etc. */
52 53
109 /* Global variables for machine-dependent things. */ 110 /* Global variables for machine-dependent things. */
110 111
111 /* List of all IQ2000 punctuation characters used by iq2000_print_operand. */ 112 /* List of all IQ2000 punctuation characters used by iq2000_print_operand. */
112 static char iq2000_print_operand_punct[256]; 113 static char iq2000_print_operand_punct[256];
113 114
114 /* The target cpu for optimization and scheduling. */
115 enum processor_type iq2000_tune;
116
117 /* Which instruction set architecture to use. */ 115 /* Which instruction set architecture to use. */
118 int iq2000_isa; 116 int iq2000_isa;
119 117
120 /* Local variables. */ 118 /* Local variables. */
121 119
138 static rtx iq2000_load_reg2; 136 static rtx iq2000_load_reg2;
139 static rtx iq2000_load_reg3; 137 static rtx iq2000_load_reg3;
140 static rtx iq2000_load_reg4; 138 static rtx iq2000_load_reg4;
141 139
142 /* Mode used for saving/restoring general purpose registers. */ 140 /* Mode used for saving/restoring general purpose registers. */
143 static enum machine_mode gpr_mode; 141 static machine_mode gpr_mode;
144 142
145 143
146 /* Initialize the GCC target structure. */ 144 /* Initialize the GCC target structure. */
147 static struct machine_function* iq2000_init_machine_status (void); 145 static struct machine_function* iq2000_init_machine_status (void);
148 static bool iq2000_handle_option (size_t, const char *, int);
149 static void iq2000_option_override (void); 146 static void iq2000_option_override (void);
150 static section *iq2000_select_rtx_section (enum machine_mode, rtx, 147 static section *iq2000_select_rtx_section (machine_mode, rtx,
151 unsigned HOST_WIDE_INT); 148 unsigned HOST_WIDE_INT);
152 static void iq2000_init_builtins (void); 149 static void iq2000_init_builtins (void);
153 static rtx iq2000_expand_builtin (tree, rtx, rtx, enum machine_mode, int); 150 static rtx iq2000_expand_builtin (tree, rtx, rtx, machine_mode, int);
154 static bool iq2000_return_in_memory (const_tree, const_tree); 151 static bool iq2000_return_in_memory (const_tree, const_tree);
155 static void iq2000_setup_incoming_varargs (CUMULATIVE_ARGS *, 152 static void iq2000_setup_incoming_varargs (cumulative_args_t,
156 enum machine_mode, tree, int *, 153 machine_mode, tree, int *,
157 int); 154 int);
158 static bool iq2000_rtx_costs (rtx, int, int, int *, bool); 155 static bool iq2000_rtx_costs (rtx, machine_mode, int, int, int *, bool);
159 static int iq2000_address_cost (rtx, bool); 156 static int iq2000_address_cost (rtx, machine_mode, addr_space_t,
157 bool);
160 static section *iq2000_select_section (tree, int, unsigned HOST_WIDE_INT); 158 static section *iq2000_select_section (tree, int, unsigned HOST_WIDE_INT);
161 static rtx iq2000_legitimize_address (rtx, rtx, enum machine_mode); 159 static rtx iq2000_legitimize_address (rtx, rtx, machine_mode);
162 static bool iq2000_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode, 160 static bool iq2000_pass_by_reference (cumulative_args_t, machine_mode,
163 const_tree, bool); 161 const_tree, bool);
164 static int iq2000_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode, 162 static int iq2000_arg_partial_bytes (cumulative_args_t, machine_mode,
165 tree, bool); 163 tree, bool);
166 static rtx iq2000_function_arg (CUMULATIVE_ARGS *, 164 static rtx iq2000_function_arg (cumulative_args_t,
167 enum machine_mode, const_tree, bool); 165 machine_mode, const_tree, bool);
168 static void iq2000_function_arg_advance (CUMULATIVE_ARGS *, 166 static void iq2000_function_arg_advance (cumulative_args_t,
169 enum machine_mode, const_tree, bool); 167 machine_mode, const_tree, bool);
170 static unsigned int iq2000_function_arg_boundary (enum machine_mode, 168 static pad_direction iq2000_function_arg_padding (machine_mode, const_tree);
169 static unsigned int iq2000_function_arg_boundary (machine_mode,
171 const_tree); 170 const_tree);
172 static void iq2000_va_start (tree, rtx); 171 static void iq2000_va_start (tree, rtx);
173 static bool iq2000_legitimate_address_p (enum machine_mode, rtx, bool); 172 static bool iq2000_legitimate_address_p (machine_mode, rtx, bool);
174 static bool iq2000_can_eliminate (const int, const int); 173 static bool iq2000_can_eliminate (const int, const int);
175 static void iq2000_asm_trampoline_template (FILE *); 174 static void iq2000_asm_trampoline_template (FILE *);
176 static void iq2000_trampoline_init (rtx, tree, rtx); 175 static void iq2000_trampoline_init (rtx, tree, rtx);
177 static rtx iq2000_function_value (const_tree, const_tree, bool); 176 static rtx iq2000_function_value (const_tree, const_tree, bool);
178 static rtx iq2000_libcall_value (enum machine_mode, const_rtx); 177 static rtx iq2000_libcall_value (machine_mode, const_rtx);
179 static void iq2000_print_operand (FILE *, rtx, int); 178 static void iq2000_print_operand (FILE *, rtx, int);
180 static void iq2000_print_operand_address (FILE *, rtx); 179 static void iq2000_print_operand_address (FILE *, machine_mode, rtx);
181 static bool iq2000_print_operand_punct_valid_p (unsigned char code); 180 static bool iq2000_print_operand_punct_valid_p (unsigned char code);
182 181 static bool iq2000_hard_regno_mode_ok (unsigned int, machine_mode);
183 /* Implement TARGET_OPTION_OPTIMIZATION_TABLE. */ 182 static bool iq2000_modes_tieable_p (machine_mode, machine_mode);
184 static const struct default_options iq2000_option_optimization_table[] = 183 static HOST_WIDE_INT iq2000_constant_alignment (const_tree, HOST_WIDE_INT);
185 { 184 static HOST_WIDE_INT iq2000_starting_frame_offset (void);
186 { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 },
187 { OPT_LEVELS_NONE, 0, NULL, 0 }
188 };
189 185
190 #undef TARGET_INIT_BUILTINS 186 #undef TARGET_INIT_BUILTINS
191 #define TARGET_INIT_BUILTINS iq2000_init_builtins 187 #define TARGET_INIT_BUILTINS iq2000_init_builtins
192 #undef TARGET_EXPAND_BUILTIN 188 #undef TARGET_EXPAND_BUILTIN
193 #define TARGET_EXPAND_BUILTIN iq2000_expand_builtin 189 #define TARGET_EXPAND_BUILTIN iq2000_expand_builtin
194 #undef TARGET_ASM_SELECT_RTX_SECTION 190 #undef TARGET_ASM_SELECT_RTX_SECTION
195 #define TARGET_ASM_SELECT_RTX_SECTION iq2000_select_rtx_section 191 #define TARGET_ASM_SELECT_RTX_SECTION iq2000_select_rtx_section
196 #undef TARGET_HANDLE_OPTION
197 #define TARGET_HANDLE_OPTION iq2000_handle_option
198 #undef TARGET_OPTION_OVERRIDE 192 #undef TARGET_OPTION_OVERRIDE
199 #define TARGET_OPTION_OVERRIDE iq2000_option_override 193 #define TARGET_OPTION_OVERRIDE iq2000_option_override
200 #undef TARGET_OPTION_OPTIMIZATION_TABLE
201 #define TARGET_OPTION_OPTIMIZATION_TABLE iq2000_option_optimization_table
202 #undef TARGET_RTX_COSTS 194 #undef TARGET_RTX_COSTS
203 #define TARGET_RTX_COSTS iq2000_rtx_costs 195 #define TARGET_RTX_COSTS iq2000_rtx_costs
204 #undef TARGET_ADDRESS_COST 196 #undef TARGET_ADDRESS_COST
205 #define TARGET_ADDRESS_COST iq2000_address_cost 197 #define TARGET_ADDRESS_COST iq2000_address_cost
206 #undef TARGET_ASM_SELECT_SECTION 198 #undef TARGET_ASM_SELECT_SECTION
240 #define TARGET_ARG_PARTIAL_BYTES iq2000_arg_partial_bytes 232 #define TARGET_ARG_PARTIAL_BYTES iq2000_arg_partial_bytes
241 #undef TARGET_FUNCTION_ARG 233 #undef TARGET_FUNCTION_ARG
242 #define TARGET_FUNCTION_ARG iq2000_function_arg 234 #define TARGET_FUNCTION_ARG iq2000_function_arg
243 #undef TARGET_FUNCTION_ARG_ADVANCE 235 #undef TARGET_FUNCTION_ARG_ADVANCE
244 #define TARGET_FUNCTION_ARG_ADVANCE iq2000_function_arg_advance 236 #define TARGET_FUNCTION_ARG_ADVANCE iq2000_function_arg_advance
237 #undef TARGET_FUNCTION_ARG_PADDING
238 #define TARGET_FUNCTION_ARG_PADDING iq2000_function_arg_padding
245 #undef TARGET_FUNCTION_ARG_BOUNDARY 239 #undef TARGET_FUNCTION_ARG_BOUNDARY
246 #define TARGET_FUNCTION_ARG_BOUNDARY iq2000_function_arg_boundary 240 #define TARGET_FUNCTION_ARG_BOUNDARY iq2000_function_arg_boundary
247 241
248 #undef TARGET_SETUP_INCOMING_VARARGS 242 #undef TARGET_SETUP_INCOMING_VARARGS
249 #define TARGET_SETUP_INCOMING_VARARGS iq2000_setup_incoming_varargs 243 #define TARGET_SETUP_INCOMING_VARARGS iq2000_setup_incoming_varargs
251 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true 245 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
252 246
253 #undef TARGET_EXPAND_BUILTIN_VA_START 247 #undef TARGET_EXPAND_BUILTIN_VA_START
254 #define TARGET_EXPAND_BUILTIN_VA_START iq2000_va_start 248 #define TARGET_EXPAND_BUILTIN_VA_START iq2000_va_start
255 249
250 #undef TARGET_LRA_P
251 #define TARGET_LRA_P hook_bool_void_false
252
256 #undef TARGET_LEGITIMATE_ADDRESS_P 253 #undef TARGET_LEGITIMATE_ADDRESS_P
257 #define TARGET_LEGITIMATE_ADDRESS_P iq2000_legitimate_address_p 254 #define TARGET_LEGITIMATE_ADDRESS_P iq2000_legitimate_address_p
258 255
259 #undef TARGET_CAN_ELIMINATE 256 #undef TARGET_CAN_ELIMINATE
260 #define TARGET_CAN_ELIMINATE iq2000_can_eliminate 257 #define TARGET_CAN_ELIMINATE iq2000_can_eliminate
262 #undef TARGET_ASM_TRAMPOLINE_TEMPLATE 259 #undef TARGET_ASM_TRAMPOLINE_TEMPLATE
263 #define TARGET_ASM_TRAMPOLINE_TEMPLATE iq2000_asm_trampoline_template 260 #define TARGET_ASM_TRAMPOLINE_TEMPLATE iq2000_asm_trampoline_template
264 #undef TARGET_TRAMPOLINE_INIT 261 #undef TARGET_TRAMPOLINE_INIT
265 #define TARGET_TRAMPOLINE_INIT iq2000_trampoline_init 262 #define TARGET_TRAMPOLINE_INIT iq2000_trampoline_init
266 263
264 #undef TARGET_HARD_REGNO_MODE_OK
265 #define TARGET_HARD_REGNO_MODE_OK iq2000_hard_regno_mode_ok
266 #undef TARGET_MODES_TIEABLE_P
267 #define TARGET_MODES_TIEABLE_P iq2000_modes_tieable_p
268
269 #undef TARGET_CONSTANT_ALIGNMENT
270 #define TARGET_CONSTANT_ALIGNMENT iq2000_constant_alignment
271
272 #undef TARGET_STARTING_FRAME_OFFSET
273 #define TARGET_STARTING_FRAME_OFFSET iq2000_starting_frame_offset
274
267 struct gcc_target targetm = TARGET_INITIALIZER; 275 struct gcc_target targetm = TARGET_INITIALIZER;
268 276
269 /* Return nonzero if we split the address into high and low parts. */ 277 /* Return nonzero if we split the address into high and low parts. */
270 278
271 int 279 int
272 iq2000_check_split (rtx address, enum machine_mode mode) 280 iq2000_check_split (rtx address, machine_mode mode)
273 { 281 {
274 /* This is the same check used in simple_memory_operand. 282 /* This is the same check used in simple_memory_operand.
275 We use it here because LO_SUM is not offsettable. */ 283 We use it here because LO_SUM is not offsettable. */
276 if (GET_MODE_SIZE (mode) > (unsigned) UNITS_PER_WORD) 284 if (GET_MODE_SIZE (mode) > (unsigned) UNITS_PER_WORD)
277 return 0; 285 return 0;
287 295
288 /* Return nonzero if REG is valid for MODE. */ 296 /* Return nonzero if REG is valid for MODE. */
289 297
290 int 298 int
291 iq2000_reg_mode_ok_for_base_p (rtx reg, 299 iq2000_reg_mode_ok_for_base_p (rtx reg,
292 enum machine_mode mode ATTRIBUTE_UNUSED, 300 machine_mode mode ATTRIBUTE_UNUSED,
293 int strict) 301 int strict)
294 { 302 {
295 return (strict 303 return (strict
296 ? REGNO_MODE_OK_FOR_BASE_P (REGNO (reg), mode) 304 ? REGNO_MODE_OK_FOR_BASE_P (REGNO (reg), mode)
297 : GP_REG_OR_PSEUDO_NONSTRICT_P (REGNO (reg), mode)); 305 : GP_REG_OR_PSEUDO_NONSTRICT_P (REGNO (reg), mode));
300 /* Return a nonzero value if XINSN is a legitimate address for a 308 /* Return a nonzero value if XINSN is a legitimate address for a
301 memory operand of the indicated MODE. STRICT is nonzero if this 309 memory operand of the indicated MODE. STRICT is nonzero if this
302 function is called during reload. */ 310 function is called during reload. */
303 311
304 bool 312 bool
305 iq2000_legitimate_address_p (enum machine_mode mode, rtx xinsn, bool strict) 313 iq2000_legitimate_address_p (machine_mode mode, rtx xinsn, bool strict)
306 { 314 {
307 if (TARGET_DEBUG_A_MODE) 315 if (TARGET_DEBUG_A_MODE)
308 { 316 {
309 GO_PRINTF2 ("\n========== legitimate_address_p, %sstrict\n", 317 GO_PRINTF2 ("\n========== legitimate_address_p, %sstrict\n",
310 strict ? "" : "not "); 318 strict ? "" : "not ");
361 return 1; 369 return 1;
362 } 370 }
363 } 371 }
364 372
365 if (TARGET_DEBUG_A_MODE) 373 if (TARGET_DEBUG_A_MODE)
366 GO_PRINTF ("Not a enum machine_mode mode, legitimate address\n"); 374 GO_PRINTF ("Not a machine_mode mode, legitimate address\n");
367 375
368 /* The address was not legitimate. */ 376 /* The address was not legitimate. */
369 return 0; 377 return 0;
370 } 378 }
371 379
378 to FINAL_PRESCAN_INSN, and we just set the global variables that 386 to FINAL_PRESCAN_INSN, and we just set the global variables that
379 it needs. */ 387 it needs. */
380 388
381 const char * 389 const char *
382 iq2000_fill_delay_slot (const char *ret, enum delay_type type, rtx operands[], 390 iq2000_fill_delay_slot (const char *ret, enum delay_type type, rtx operands[],
383 rtx cur_insn) 391 rtx_insn *cur_insn)
384 { 392 {
385 rtx set_reg; 393 rtx set_reg;
386 enum machine_mode mode; 394 machine_mode mode;
387 rtx next_insn = cur_insn ? NEXT_INSN (cur_insn) : NULL_RTX; 395 rtx_insn *next_insn = cur_insn ? NEXT_INSN (cur_insn) : NULL;
388 int num_nops; 396 int num_nops;
389 397
390 if (type == DELAY_LOAD || type == DELAY_FCMP) 398 if (type == DELAY_LOAD || type == DELAY_FCMP)
391 num_nops = 1; 399 num_nops = 1;
392 400
394 num_nops = 0; 402 num_nops = 0;
395 403
396 /* Make sure that we don't put nop's after labels. */ 404 /* Make sure that we don't put nop's after labels. */
397 next_insn = NEXT_INSN (cur_insn); 405 next_insn = NEXT_INSN (cur_insn);
398 while (next_insn != 0 406 while (next_insn != 0
399 && (GET_CODE (next_insn) == NOTE 407 && (NOTE_P (next_insn) || LABEL_P (next_insn)))
400 || GET_CODE (next_insn) == CODE_LABEL))
401 next_insn = NEXT_INSN (next_insn); 408 next_insn = NEXT_INSN (next_insn);
402 409
403 dslots_load_total += num_nops; 410 dslots_load_total += num_nops;
404 if (TARGET_DEBUG_C_MODE 411 if (TARGET_DEBUG_C_MODE
405 || type == DELAY_NONE 412 || type == DELAY_NONE
406 || operands == 0 413 || operands == 0
407 || cur_insn == 0 414 || cur_insn == 0
408 || next_insn == 0 415 || next_insn == 0
409 || GET_CODE (next_insn) == CODE_LABEL 416 || LABEL_P (next_insn)
410 || (set_reg = operands[0]) == 0) 417 || (set_reg = operands[0]) == 0)
411 { 418 {
412 dslots_number_nops = 0; 419 dslots_number_nops = 0;
413 iq2000_load_reg = 0; 420 iq2000_load_reg = 0;
414 iq2000_load_reg2 = 0; 421 iq2000_load_reg2 = 0;
562 } 569 }
563 570
564 /* Return the appropriate instructions to move one operand to another. */ 571 /* Return the appropriate instructions to move one operand to another. */
565 572
566 const char * 573 const char *
567 iq2000_move_1word (rtx operands[], rtx insn, int unsignedp) 574 iq2000_move_1word (rtx operands[], rtx_insn *insn, int unsignedp)
568 { 575 {
569 const char *ret = 0; 576 const char *ret = 0;
570 rtx op0 = operands[0]; 577 rtx op0 = operands[0];
571 rtx op1 = operands[1]; 578 rtx op1 = operands[1];
572 enum rtx_code code0 = GET_CODE (op0); 579 enum rtx_code code0 = GET_CODE (op0);
573 enum rtx_code code1 = GET_CODE (op1); 580 enum rtx_code code1 = GET_CODE (op1);
574 enum machine_mode mode = GET_MODE (op0); 581 machine_mode mode = GET_MODE (op0);
575 int subreg_offset0 = 0; 582 int subreg_offset0 = 0;
576 int subreg_offset1 = 0; 583 int subreg_offset1 = 0;
577 enum delay_type delay = DELAY_NONE; 584 enum delay_type delay = DELAY_NONE;
578 585
579 while (code0 == SUBREG) 586 while (code0 == SUBREG)
633 target, so zero/sign extend can use this code as well. */ 640 target, so zero/sign extend can use this code as well. */
634 switch (GET_MODE (op1)) 641 switch (GET_MODE (op1))
635 { 642 {
636 default: 643 default:
637 break; 644 break;
638 case SFmode: 645 case E_SFmode:
639 ret = "lw\t%0,%1"; 646 ret = "lw\t%0,%1";
640 break; 647 break;
641 case SImode: 648 case E_SImode:
642 case CCmode: 649 case E_CCmode:
643 ret = "lw\t%0,%1"; 650 ret = "lw\t%0,%1";
644 break; 651 break;
645 case HImode: 652 case E_HImode:
646 ret = (unsignedp) ? "lhu\t%0,%1" : "lh\t%0,%1"; 653 ret = (unsignedp) ? "lhu\t%0,%1" : "lh\t%0,%1";
647 break; 654 break;
648 case QImode: 655 case E_QImode:
649 ret = (unsignedp) ? "lbu\t%0,%1" : "lb\t%0,%1"; 656 ret = (unsignedp) ? "lbu\t%0,%1" : "lb\t%0,%1";
650 break; 657 break;
651 } 658 }
652 } 659 }
653 } 660 }
743 750
744 if (GP_REG_P (regno1)) 751 if (GP_REG_P (regno1))
745 { 752 {
746 switch (mode) 753 switch (mode)
747 { 754 {
748 case SFmode: ret = "sw\t%1,%0"; break; 755 case E_SFmode: ret = "sw\t%1,%0"; break;
749 case SImode: ret = "sw\t%1,%0"; break; 756 case E_SImode: ret = "sw\t%1,%0"; break;
750 case HImode: ret = "sh\t%1,%0"; break; 757 case E_HImode: ret = "sh\t%1,%0"; break;
751 case QImode: ret = "sb\t%1,%0"; break; 758 case E_QImode: ret = "sb\t%1,%0"; break;
752 default: break; 759 default: break;
753 } 760 }
754 } 761 }
755 } 762 }
756 763
757 else if (code1 == CONST_INT && INTVAL (op1) == 0) 764 else if (code1 == CONST_INT && INTVAL (op1) == 0)
758 { 765 {
759 switch (mode) 766 switch (mode)
760 { 767 {
761 case SFmode: ret = "sw\t%z1,%0"; break; 768 case E_SFmode: ret = "sw\t%z1,%0"; break;
762 case SImode: ret = "sw\t%z1,%0"; break; 769 case E_SImode: ret = "sw\t%z1,%0"; break;
763 case HImode: ret = "sh\t%z1,%0"; break; 770 case E_HImode: ret = "sh\t%z1,%0"; break;
764 case QImode: ret = "sb\t%z1,%0"; break; 771 case E_QImode: ret = "sb\t%z1,%0"; break;
765 default: break; 772 default: break;
766 } 773 }
767 } 774 }
768 775
769 else if (code1 == CONST_DOUBLE && op1 == CONST0_RTX (mode)) 776 else if (code1 == CONST_DOUBLE && op1 == CONST0_RTX (mode))
770 { 777 {
771 switch (mode) 778 switch (mode)
772 { 779 {
773 case SFmode: ret = "sw\t%.,%0"; break; 780 case E_SFmode: ret = "sw\t%.,%0"; break;
774 case SImode: ret = "sw\t%.,%0"; break; 781 case E_SImode: ret = "sw\t%.,%0"; break;
775 case HImode: ret = "sh\t%.,%0"; break; 782 case E_HImode: ret = "sh\t%.,%0"; break;
776 case QImode: ret = "sb\t%.,%0"; break; 783 case E_QImode: ret = "sb\t%.,%0"; break;
777 default: break; 784 default: break;
778 } 785 }
779 } 786 }
780 } 787 }
781 788
792 } 799 }
793 800
794 /* Provide the costs of an addressing mode that contains ADDR. */ 801 /* Provide the costs of an addressing mode that contains ADDR. */
795 802
796 static int 803 static int
797 iq2000_address_cost (rtx addr, bool speed) 804 iq2000_address_cost (rtx addr, machine_mode mode, addr_space_t as,
805 bool speed)
798 { 806 {
799 switch (GET_CODE (addr)) 807 switch (GET_CODE (addr))
800 { 808 {
801 case LO_SUM: 809 case LO_SUM:
802 return 1; 810 return 1;
843 case CONST: 851 case CONST:
844 case SYMBOL_REF: 852 case SYMBOL_REF:
845 case LABEL_REF: 853 case LABEL_REF:
846 case HIGH: 854 case HIGH:
847 case LO_SUM: 855 case LO_SUM:
848 return iq2000_address_cost (plus1, speed) + 1; 856 return iq2000_address_cost (plus1, mode, as, speed) + 1;
849 857
850 default: 858 default:
851 break; 859 break;
852 } 860 }
853 } 861 }
919 { LTU, -32768, 32767, 0, 0, 0, 0, 1 }, /* LTU */ 927 { LTU, -32768, 32767, 0, 0, 0, 0, 1 }, /* LTU */
920 { LTU, -32769, 32766, 1, 1, 0, 1, 1 }, /* LEU */ 928 { LTU, -32769, 32766, 1, 1, 0, 1, 1 }, /* LEU */
921 }; 929 };
922 930
923 enum internal_test test; 931 enum internal_test test;
924 enum machine_mode mode; 932 machine_mode mode;
925 struct cmp_info *p_info; 933 struct cmp_info *p_info;
926 int branch_p; 934 int branch_p;
927 int eqne_p; 935 int eqne_p;
928 int invert; 936 int invert;
929 rtx reg; 937 rtx reg;
1053 /* Emit the common code for doing conditional branches. 1061 /* Emit the common code for doing conditional branches.
1054 operand[0] is the label to jump to. 1062 operand[0] is the label to jump to.
1055 The comparison operands are saved away by cmp{si,di,sf,df}. */ 1063 The comparison operands are saved away by cmp{si,di,sf,df}. */
1056 1064
1057 void 1065 void
1058 gen_conditional_branch (rtx operands[], enum machine_mode mode) 1066 gen_conditional_branch (rtx operands[], machine_mode mode)
1059 { 1067 {
1060 enum rtx_code test_code = GET_CODE (operands[0]); 1068 enum rtx_code test_code = GET_CODE (operands[0]);
1061 rtx cmp0 = operands[1]; 1069 rtx cmp0 = operands[1];
1062 rtx cmp1 = operands[2]; 1070 rtx cmp1 = operands[2];
1063 rtx reg; 1071 rtx reg;
1086 { 1094 {
1087 label2 = label1; 1095 label2 = label1;
1088 label1 = pc_rtx; 1096 label1 = pc_rtx;
1089 } 1097 }
1090 1098
1091 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, 1099 emit_jump_insn (gen_rtx_SET (pc_rtx,
1092 gen_rtx_IF_THEN_ELSE (VOIDmode, 1100 gen_rtx_IF_THEN_ELSE (VOIDmode,
1093 gen_rtx_fmt_ee (test_code, 1101 gen_rtx_fmt_ee (test_code,
1094 mode, 1102 VOIDmode,
1095 cmp0, cmp1), 1103 cmp0, cmp1),
1096 label1, label2))); 1104 label1, label2)));
1097 } 1105 }
1098 1106
1099 /* Initialize CUM for a function FNTYPE. */ 1107 /* Initialize CUM for a function FNTYPE. */
1117 else 1125 else
1118 { 1126 {
1119 tree ret_type = TREE_TYPE (fntype); 1127 tree ret_type = TREE_TYPE (fntype);
1120 1128
1121 fprintf (stderr, ", fntype code = %s, ret code = %s\n", 1129 fprintf (stderr, ", fntype code = %s, ret code = %s\n",
1122 tree_code_name[(int)TREE_CODE (fntype)], 1130 get_tree_code_name (TREE_CODE (fntype)),
1123 tree_code_name[(int)TREE_CODE (ret_type)]); 1131 get_tree_code_name (TREE_CODE (ret_type)));
1124 } 1132 }
1125 } 1133 }
1126 1134
1127 *cum = zero_cum; 1135 *cum = zero_cum;
1128 1136
1142 1150
1143 /* Advance the argument of type TYPE and mode MODE to the next argument 1151 /* Advance the argument of type TYPE and mode MODE to the next argument
1144 position in CUM. */ 1152 position in CUM. */
1145 1153
1146 static void 1154 static void
1147 iq2000_function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode, 1155 iq2000_function_arg_advance (cumulative_args_t cum_v, machine_mode mode,
1148 const_tree type, bool named) 1156 const_tree type, bool named)
1149 { 1157 {
1158 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
1159
1150 if (TARGET_DEBUG_D_MODE) 1160 if (TARGET_DEBUG_D_MODE)
1151 { 1161 {
1152 fprintf (stderr, 1162 fprintf (stderr,
1153 "function_adv({gp reg found = %d, arg # = %2d, words = %2d}, %4s, ", 1163 "function_adv({gp reg found = %d, arg # = %2d, words = %2d}, %4s, ",
1154 cum->gp_reg_found, cum->arg_number, cum->arg_words, 1164 cum->gp_reg_found, cum->arg_number, cum->arg_words,
1155 GET_MODE_NAME (mode)); 1165 GET_MODE_NAME (mode));
1156 fprintf (stderr, "%p", CONST_CAST2 (void *, const_tree, type)); 1166 fprintf (stderr, "%p", (const void *) type);
1157 fprintf (stderr, ", %d )\n\n", named); 1167 fprintf (stderr, ", %d )\n\n", named);
1158 } 1168 }
1159 1169
1160 cum->arg_number++; 1170 cum->arg_number++;
1161 switch (mode) 1171 switch (mode)
1162 { 1172 {
1163 case VOIDmode: 1173 case E_VOIDmode:
1164 break; 1174 break;
1165 1175
1166 default: 1176 default:
1167 gcc_assert (GET_MODE_CLASS (mode) == MODE_COMPLEX_INT 1177 gcc_assert (GET_MODE_CLASS (mode) == MODE_COMPLEX_INT
1168 || GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT); 1178 || GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT);
1170 cum->gp_reg_found = 1; 1180 cum->gp_reg_found = 1;
1171 cum->arg_words += ((GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) 1181 cum->arg_words += ((GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1)
1172 / UNITS_PER_WORD); 1182 / UNITS_PER_WORD);
1173 break; 1183 break;
1174 1184
1175 case BLKmode: 1185 case E_BLKmode:
1176 cum->gp_reg_found = 1; 1186 cum->gp_reg_found = 1;
1177 cum->arg_words += ((int_size_in_bytes (type) + UNITS_PER_WORD - 1) 1187 cum->arg_words += ((int_size_in_bytes (type) + UNITS_PER_WORD - 1)
1178 / UNITS_PER_WORD); 1188 / UNITS_PER_WORD);
1179 break; 1189 break;
1180 1190
1181 case SFmode: 1191 case E_SFmode:
1182 cum->arg_words ++; 1192 cum->arg_words ++;
1183 if (! cum->gp_reg_found && cum->arg_number <= 2) 1193 if (! cum->gp_reg_found && cum->arg_number <= 2)
1184 cum->fp_code += 1 << ((cum->arg_number - 1) * 2); 1194 cum->fp_code += 1 << ((cum->arg_number - 1) * 2);
1185 break; 1195 break;
1186 1196
1187 case DFmode: 1197 case E_DFmode:
1188 cum->arg_words += 2; 1198 cum->arg_words += 2;
1189 if (! cum->gp_reg_found && cum->arg_number <= 2) 1199 if (! cum->gp_reg_found && cum->arg_number <= 2)
1190 cum->fp_code += 2 << ((cum->arg_number - 1) * 2); 1200 cum->fp_code += 2 << ((cum->arg_number - 1) * 2);
1191 break; 1201 break;
1192 1202
1193 case DImode: 1203 case E_DImode:
1194 cum->gp_reg_found = 1; 1204 cum->gp_reg_found = 1;
1195 cum->arg_words += 2; 1205 cum->arg_words += 2;
1196 break; 1206 break;
1197 1207
1198 case TImode: 1208 case E_TImode:
1199 cum->gp_reg_found = 1; 1209 cum->gp_reg_found = 1;
1200 cum->arg_words += 4; 1210 cum->arg_words += 4;
1201 break; 1211 break;
1202 1212
1203 case QImode: 1213 case E_QImode:
1204 case HImode: 1214 case E_HImode:
1205 case SImode: 1215 case E_SImode:
1206 cum->gp_reg_found = 1; 1216 cum->gp_reg_found = 1;
1207 cum->arg_words ++; 1217 cum->arg_words ++;
1208 break; 1218 break;
1209 } 1219 }
1210 } 1220 }
1211 1221
1212 /* Return an RTL expression containing the register for the given mode MODE 1222 /* Return an RTL expression containing the register for the given mode MODE
1213 and type TYPE in CUM, or 0 if the argument is to be passed on the stack. */ 1223 and type TYPE in CUM, or 0 if the argument is to be passed on the stack. */
1214 1224
1215 static rtx 1225 static rtx
1216 iq2000_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, 1226 iq2000_function_arg (cumulative_args_t cum_v, machine_mode mode,
1217 const_tree type, bool named) 1227 const_tree type, bool named)
1218 { 1228 {
1229 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
1219 rtx ret; 1230 rtx ret;
1220 int regbase = -1; 1231 int regbase = -1;
1221 int bias = 0; 1232 int bias = 0;
1222 unsigned int *arg_words = &cum->arg_words; 1233 unsigned int *arg_words = &cum->arg_words;
1223 int struct_p = (type != 0 1234 int struct_p = (type != 0
1237 1248
1238 1249
1239 cum->last_arg_fp = 0; 1250 cum->last_arg_fp = 0;
1240 switch (mode) 1251 switch (mode)
1241 { 1252 {
1242 case SFmode: 1253 case E_SFmode:
1243 regbase = GP_ARG_FIRST; 1254 regbase = GP_ARG_FIRST;
1244 break; 1255 break;
1245 1256
1246 case DFmode: 1257 case E_DFmode:
1247 cum->arg_words += cum->arg_words & 1; 1258 cum->arg_words += cum->arg_words & 1;
1248 1259
1249 regbase = GP_ARG_FIRST; 1260 regbase = GP_ARG_FIRST;
1250 break; 1261 break;
1251 1262
1252 default: 1263 default:
1253 gcc_assert (GET_MODE_CLASS (mode) == MODE_COMPLEX_INT 1264 gcc_assert (GET_MODE_CLASS (mode) == MODE_COMPLEX_INT
1254 || GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT); 1265 || GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT);
1255 1266
1256 /* Drops through. */ 1267 /* FALLTHRU */
1257 case BLKmode: 1268 case E_BLKmode:
1258 if (type != NULL_TREE && TYPE_ALIGN (type) > (unsigned) BITS_PER_WORD) 1269 if (type != NULL_TREE && TYPE_ALIGN (type) > (unsigned) BITS_PER_WORD)
1259 cum->arg_words += (cum->arg_words & 1); 1270 cum->arg_words += (cum->arg_words & 1);
1260 regbase = GP_ARG_FIRST; 1271 regbase = GP_ARG_FIRST;
1261 break; 1272 break;
1262 1273
1263 case VOIDmode: 1274 case E_VOIDmode:
1264 case QImode: 1275 case E_QImode:
1265 case HImode: 1276 case E_HImode:
1266 case SImode: 1277 case E_SImode:
1267 regbase = GP_ARG_FIRST; 1278 regbase = GP_ARG_FIRST;
1268 break; 1279 break;
1269 1280
1270 case DImode: 1281 case E_DImode:
1271 cum->arg_words += (cum->arg_words & 1); 1282 cum->arg_words += (cum->arg_words & 1);
1272 regbase = GP_ARG_FIRST; 1283 regbase = GP_ARG_FIRST;
1273 break; 1284 break;
1274 1285
1275 case TImode: 1286 case E_TImode:
1276 cum->arg_words += (cum->arg_words & 3); 1287 cum->arg_words += (cum->arg_words & 3);
1277 regbase = GP_ARG_FIRST; 1288 regbase = GP_ARG_FIRST;
1278 break; 1289 break;
1279 } 1290 }
1280 1291
1289 { 1300 {
1290 gcc_assert (regbase != -1); 1301 gcc_assert (regbase != -1);
1291 1302
1292 if (! type || TREE_CODE (type) != RECORD_TYPE 1303 if (! type || TREE_CODE (type) != RECORD_TYPE
1293 || ! named || ! TYPE_SIZE_UNIT (type) 1304 || ! named || ! TYPE_SIZE_UNIT (type)
1294 || ! host_integerp (TYPE_SIZE_UNIT (type), 1)) 1305 || ! tree_fits_uhwi_p (TYPE_SIZE_UNIT (type)))
1295 ret = gen_rtx_REG (mode, regbase + *arg_words + bias); 1306 ret = gen_rtx_REG (mode, regbase + *arg_words + bias);
1296 else 1307 else
1297 { 1308 {
1298 tree field; 1309 tree field;
1299 1310
1300 for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field)) 1311 for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
1301 if (TREE_CODE (field) == FIELD_DECL 1312 if (TREE_CODE (field) == FIELD_DECL
1302 && TREE_CODE (TREE_TYPE (field)) == REAL_TYPE 1313 && TREE_CODE (TREE_TYPE (field)) == REAL_TYPE
1303 && TYPE_PRECISION (TREE_TYPE (field)) == BITS_PER_WORD 1314 && TYPE_PRECISION (TREE_TYPE (field)) == BITS_PER_WORD
1304 && host_integerp (bit_position (field), 0) 1315 && tree_fits_shwi_p (bit_position (field))
1305 && int_bit_position (field) % BITS_PER_WORD == 0) 1316 && int_bit_position (field) % BITS_PER_WORD == 0)
1306 break; 1317 break;
1307 1318
1308 /* If the whole struct fits a DFmode register, 1319 /* If the whole struct fits a DFmode register,
1309 we don't need the PARALLEL. */ 1320 we don't need the PARALLEL. */
1317 unsigned int i; 1328 unsigned int i;
1318 1329
1319 /* ??? If this is a packed structure, then the last hunk won't 1330 /* ??? If this is a packed structure, then the last hunk won't
1320 be 64 bits. */ 1331 be 64 bits. */
1321 chunks 1332 chunks
1322 = tree_low_cst (TYPE_SIZE_UNIT (type), 1) / UNITS_PER_WORD; 1333 = tree_to_uhwi (TYPE_SIZE_UNIT (type)) / UNITS_PER_WORD;
1323 if (chunks + *arg_words + bias > (unsigned) MAX_ARGS_IN_REGISTERS) 1334 if (chunks + *arg_words + bias > (unsigned) MAX_ARGS_IN_REGISTERS)
1324 chunks = MAX_ARGS_IN_REGISTERS - *arg_words - bias; 1335 chunks = MAX_ARGS_IN_REGISTERS - *arg_words - bias;
1325 1336
1326 /* Assign_parms checks the mode of ENTRY_PARM, so we must 1337 /* Assign_parms checks the mode of ENTRY_PARM, so we must
1327 use the actual mode here. */ 1338 use the actual mode here. */
1367 insn. If we need any shifts for small structures, return them in 1378 insn. If we need any shifts for small structures, return them in
1368 a PARALLEL. */ 1379 a PARALLEL. */
1369 if (mode == VOIDmode) 1380 if (mode == VOIDmode)
1370 { 1381 {
1371 if (cum->num_adjusts > 0) 1382 if (cum->num_adjusts > 0)
1372 ret = gen_rtx_PARALLEL ((enum machine_mode) cum->fp_code, 1383 ret = gen_rtx_PARALLEL ((machine_mode) cum->fp_code,
1373 gen_rtvec_v (cum->num_adjusts, cum->adjust)); 1384 gen_rtvec_v (cum->num_adjusts, cum->adjust));
1374 } 1385 }
1375 1386
1376 return ret; 1387 return ret;
1377 } 1388 }
1378 1389
1390 /* Implement TARGET_FUNCTION_ARG_PADDING. */
1391
1392 static pad_direction
1393 iq2000_function_arg_padding (machine_mode mode, const_tree type)
1394 {
1395 return (! BYTES_BIG_ENDIAN
1396 ? PAD_UPWARD
1397 : ((mode == BLKmode
1398 ? (type
1399 && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST
1400 && int_size_in_bytes (type) < (PARM_BOUNDARY / BITS_PER_UNIT))
1401 : (GET_MODE_BITSIZE (mode) < PARM_BOUNDARY
1402 && GET_MODE_CLASS (mode) == MODE_INT))
1403 ? PAD_DOWNWARD : PAD_UPWARD));
1404 }
1405
1379 static unsigned int 1406 static unsigned int
1380 iq2000_function_arg_boundary (enum machine_mode mode, const_tree type) 1407 iq2000_function_arg_boundary (machine_mode mode, const_tree type)
1381 { 1408 {
1382 return (type != NULL_TREE 1409 return (type != NULL_TREE
1383 ? (TYPE_ALIGN (type) <= PARM_BOUNDARY 1410 ? (TYPE_ALIGN (type) <= PARM_BOUNDARY
1384 ? PARM_BOUNDARY 1411 ? PARM_BOUNDARY
1385 : TYPE_ALIGN (type)) 1412 : TYPE_ALIGN (type))
1387 ? PARM_BOUNDARY 1414 ? PARM_BOUNDARY
1388 : GET_MODE_ALIGNMENT (mode))); 1415 : GET_MODE_ALIGNMENT (mode)));
1389 } 1416 }
1390 1417
1391 static int 1418 static int
1392 iq2000_arg_partial_bytes (CUMULATIVE_ARGS *cum, enum machine_mode mode, 1419 iq2000_arg_partial_bytes (cumulative_args_t cum_v, machine_mode mode,
1393 tree type ATTRIBUTE_UNUSED, 1420 tree type ATTRIBUTE_UNUSED,
1394 bool named ATTRIBUTE_UNUSED) 1421 bool named ATTRIBUTE_UNUSED)
1395 { 1422 {
1423 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
1424
1396 if (mode == DImode && cum->arg_words == MAX_ARGS_IN_REGISTERS - 1) 1425 if (mode == DImode && cum->arg_words == MAX_ARGS_IN_REGISTERS - 1)
1397 { 1426 {
1398 if (TARGET_DEBUG_D_MODE) 1427 if (TARGET_DEBUG_D_MODE)
1399 fprintf (stderr, "iq2000_arg_partial_bytes=%d\n", UNITS_PER_WORD); 1428 fprintf (stderr, "iq2000_arg_partial_bytes=%d\n", UNITS_PER_WORD);
1400 return UNITS_PER_WORD; 1429 return UNITS_PER_WORD;
1420 else 1449 else
1421 gpr_save_area_size = 0; 1450 gpr_save_area_size = 0;
1422 1451
1423 /* Everything is in the GPR save area, or in the overflow 1452 /* Everything is in the GPR save area, or in the overflow
1424 area which is contiguous with it. */ 1453 area which is contiguous with it. */
1425 nextarg = plus_constant (nextarg, - gpr_save_area_size); 1454 nextarg = plus_constant (Pmode, nextarg, - gpr_save_area_size);
1426 std_expand_builtin_va_start (valist, nextarg); 1455 std_expand_builtin_va_start (valist, nextarg);
1427 } 1456 }
1428 1457
1429 /* Allocate a chunk of memory for per-function machine-dependent data. */ 1458 /* Allocate a chunk of memory for per-function machine-dependent data. */
1430 1459
1431 static struct machine_function * 1460 static struct machine_function *
1432 iq2000_init_machine_status (void) 1461 iq2000_init_machine_status (void)
1433 { 1462 {
1434 return ggc_alloc_cleared_machine_function (); 1463 return ggc_cleared_alloc<machine_function> ();
1435 }
1436
1437 /* Implement TARGET_HANDLE_OPTION. */
1438
1439 static bool
1440 iq2000_handle_option (size_t code, const char *arg, int value ATTRIBUTE_UNUSED)
1441 {
1442 switch (code)
1443 {
1444 case OPT_mcpu_:
1445 if (strcmp (arg, "iq10") == 0)
1446 iq2000_tune = PROCESSOR_IQ10;
1447 else if (strcmp (arg, "iq2000") == 0)
1448 iq2000_tune = PROCESSOR_IQ2000;
1449 else
1450 return false;
1451 return true;
1452
1453 case OPT_march_:
1454 /* This option has no effect at the moment. */
1455 return (strcmp (arg, "default") == 0
1456 || strcmp (arg, "DEFAULT") == 0
1457 || strcmp (arg, "iq2000") == 0);
1458
1459 default:
1460 return true;
1461 }
1462 } 1464 }
1463 1465
1464 /* Detect any conflicts in the switches. */ 1466 /* Detect any conflicts in the switches. */
1465 1467
1466 static void 1468 static void
1538 1540
1539 We use it to check if the current insn needs a nop in front of it because 1541 We use it to check if the current insn needs a nop in front of it because
1540 of load delays, and also to update the delay slot statistics. */ 1542 of load delays, and also to update the delay slot statistics. */
1541 1543
1542 void 1544 void
1543 final_prescan_insn (rtx insn, rtx opvec[] ATTRIBUTE_UNUSED, 1545 final_prescan_insn (rtx_insn *insn, rtx opvec[] ATTRIBUTE_UNUSED,
1544 int noperands ATTRIBUTE_UNUSED) 1546 int noperands ATTRIBUTE_UNUSED)
1545 { 1547 {
1546 if (dslots_number_nops > 0) 1548 if (dslots_number_nops > 0)
1547 { 1549 {
1548 rtx pattern = PATTERN (insn); 1550 rtx pattern = PATTERN (insn);
1567 iq2000_load_reg2 = 0; 1569 iq2000_load_reg2 = 0;
1568 iq2000_load_reg3 = 0; 1570 iq2000_load_reg3 = 0;
1569 iq2000_load_reg4 = 0; 1571 iq2000_load_reg4 = 0;
1570 } 1572 }
1571 1573
1572 if ( (GET_CODE (insn) == JUMP_INSN 1574 if ( (JUMP_P (insn)
1573 || GET_CODE (insn) == CALL_INSN 1575 || CALL_P (insn)
1574 || (GET_CODE (PATTERN (insn)) == RETURN)) 1576 || (GET_CODE (PATTERN (insn)) == RETURN))
1575 && NEXT_INSN (PREV_INSN (insn)) == insn) 1577 && NEXT_INSN (PREV_INSN (insn)) == insn)
1576 { 1578 {
1577 rtx nop_insn = emit_insn_after (gen_nop (), insn); 1579 rtx_insn *tmp = insn;
1578 1580 while (NEXT_INSN (tmp)
1581 && NOTE_P (NEXT_INSN (tmp))
1582 && NOTE_KIND (NEXT_INSN (tmp)) == NOTE_INSN_CALL_ARG_LOCATION)
1583 tmp = NEXT_INSN (tmp);
1584
1585 rtx_insn *nop_insn = emit_insn_after (gen_nop (), tmp);
1579 INSN_ADDRESSES_NEW (nop_insn, -1); 1586 INSN_ADDRESSES_NEW (nop_insn, -1);
1580 } 1587 }
1581 1588
1582 if (TARGET_STATS 1589 if (TARGET_STATS
1583 && (GET_CODE (insn) == JUMP_INSN || GET_CODE (insn) == CALL_INSN)) 1590 && (JUMP_P (insn) || CALL_P (insn)))
1584 dslots_jump_total ++; 1591 dslots_jump_total ++;
1585 } 1592 }
1586 1593
1587 /* Return the bytes needed to compute the frame pointer from the current 1594 /* Return the bytes needed to compute the frame pointer from the current
1588 stack pointer where SIZE is the # of var. bytes allocated. 1595 stack pointer where SIZE is the # of var. bytes allocated.
1804 1811
1805 /* Make INSN frame related and note that it performs the frame-related 1812 /* Make INSN frame related and note that it performs the frame-related
1806 operation DWARF_PATTERN. */ 1813 operation DWARF_PATTERN. */
1807 1814
1808 static void 1815 static void
1809 iq2000_annotate_frame_insn (rtx insn, rtx dwarf_pattern) 1816 iq2000_annotate_frame_insn (rtx_insn *insn, rtx dwarf_pattern)
1810 { 1817 {
1811 RTX_FRAME_RELATED_P (insn) = 1; 1818 RTX_FRAME_RELATED_P (insn) = 1;
1812 REG_NOTES (insn) = alloc_EXPR_LIST (REG_FRAME_RELATED_EXPR, 1819 REG_NOTES (insn) = alloc_EXPR_LIST (REG_FRAME_RELATED_EXPR,
1813 dwarf_pattern, 1820 dwarf_pattern,
1814 REG_NOTES (insn)); 1821 REG_NOTES (insn));
1818 frame related and note that it stores REG at (SP + OFFSET). */ 1825 frame related and note that it stores REG at (SP + OFFSET). */
1819 1826
1820 static void 1827 static void
1821 iq2000_emit_frame_related_store (rtx mem, rtx reg, HOST_WIDE_INT offset) 1828 iq2000_emit_frame_related_store (rtx mem, rtx reg, HOST_WIDE_INT offset)
1822 { 1829 {
1823 rtx dwarf_address = plus_constant (stack_pointer_rtx, offset); 1830 rtx dwarf_address = plus_constant (Pmode, stack_pointer_rtx, offset);
1824 rtx dwarf_mem = gen_rtx_MEM (GET_MODE (reg), dwarf_address); 1831 rtx dwarf_mem = gen_rtx_MEM (GET_MODE (reg), dwarf_address);
1825 1832
1826 iq2000_annotate_frame_insn (emit_move_insn (mem, reg), 1833 iq2000_annotate_frame_insn (emit_move_insn (mem, reg),
1827 gen_rtx_SET (GET_MODE (reg), dwarf_mem, reg)); 1834 gen_rtx_SET (dwarf_mem, reg));
1828 } 1835 }
1829 1836
1830 /* Emit instructions to save/restore registers, as determined by STORE_P. */ 1837 /* Emit instructions to save/restore registers, as determined by STORE_P. */
1831 1838
1832 static void 1839 static void
1919 tree fnargs = DECL_ARGUMENTS (fndecl); 1926 tree fnargs = DECL_ARGUMENTS (fndecl);
1920 rtx next_arg_reg; 1927 rtx next_arg_reg;
1921 int i; 1928 int i;
1922 tree next_arg; 1929 tree next_arg;
1923 tree cur_arg; 1930 tree cur_arg;
1924 CUMULATIVE_ARGS args_so_far; 1931 CUMULATIVE_ARGS args_so_far_v;
1932 cumulative_args_t args_so_far;
1925 int store_args_on_stack = (iq2000_can_use_return_insn ()); 1933 int store_args_on_stack = (iq2000_can_use_return_insn ());
1926 1934
1927 /* If struct value address is treated as the first argument. */ 1935 /* If struct value address is treated as the first argument. */
1928 if (aggregate_value_p (DECL_RESULT (fndecl), fndecl) 1936 if (aggregate_value_p (DECL_RESULT (fndecl), fndecl)
1929 && !cfun->returns_pcc_struct 1937 && !cfun->returns_pcc_struct
1943 otherwise GP_ARG_LAST+1. Note also if the last argument is 1951 otherwise GP_ARG_LAST+1. Note also if the last argument is
1944 the varargs special argument, and treat it as part of the 1952 the varargs special argument, and treat it as part of the
1945 variable arguments. 1953 variable arguments.
1946 1954
1947 This is only needed if store_args_on_stack is true. */ 1955 This is only needed if store_args_on_stack is true. */
1948 INIT_CUMULATIVE_ARGS (args_so_far, fntype, NULL_RTX, 0, 0); 1956 INIT_CUMULATIVE_ARGS (args_so_far_v, fntype, NULL_RTX, 0, 0);
1957 args_so_far = pack_cumulative_args (&args_so_far_v);
1949 regno = GP_ARG_FIRST; 1958 regno = GP_ARG_FIRST;
1950 1959
1951 for (cur_arg = fnargs; cur_arg != 0; cur_arg = next_arg) 1960 for (cur_arg = fnargs; cur_arg != 0; cur_arg = next_arg)
1952 { 1961 {
1953 tree passed_type = DECL_ARG_TYPE (cur_arg); 1962 tree passed_type = DECL_ARG_TYPE (cur_arg);
1954 enum machine_mode passed_mode = TYPE_MODE (passed_type); 1963 machine_mode passed_mode = TYPE_MODE (passed_type);
1955 rtx entry_parm; 1964 rtx entry_parm;
1956 1965
1957 if (TREE_ADDRESSABLE (passed_type)) 1966 if (TREE_ADDRESSABLE (passed_type))
1958 { 1967 {
1959 passed_type = build_pointer_type (passed_type); 1968 passed_type = build_pointer_type (passed_type);
1960 passed_mode = Pmode; 1969 passed_mode = Pmode;
1961 } 1970 }
1962 1971
1963 entry_parm = iq2000_function_arg (&args_so_far, passed_mode, 1972 entry_parm = iq2000_function_arg (args_so_far, passed_mode,
1964 passed_type, true); 1973 passed_type, true);
1965 1974
1966 iq2000_function_arg_advance (&args_so_far, passed_mode, 1975 iq2000_function_arg_advance (args_so_far, passed_mode,
1967 passed_type, true); 1976 passed_type, true);
1968 next_arg = DECL_CHAIN (cur_arg); 1977 next_arg = DECL_CHAIN (cur_arg);
1969 1978
1970 if (entry_parm && store_args_on_stack) 1979 if (entry_parm && store_args_on_stack)
1971 { 1980 {
2004 /* In order to pass small structures by value in registers we need to 2013 /* In order to pass small structures by value in registers we need to
2005 shift the value into the high part of the register. 2014 shift the value into the high part of the register.
2006 iq2000_unction_arg has encoded a PARALLEL rtx, holding a vector of 2015 iq2000_unction_arg has encoded a PARALLEL rtx, holding a vector of
2007 adjustments to be made as the next_arg_reg variable, so we split up 2016 adjustments to be made as the next_arg_reg variable, so we split up
2008 the insns, and emit them separately. */ 2017 the insns, and emit them separately. */
2009 next_arg_reg = iq2000_function_arg (&args_so_far, VOIDmode, 2018 next_arg_reg = iq2000_function_arg (args_so_far, VOIDmode,
2010 void_type_node, true); 2019 void_type_node, true);
2011 if (next_arg_reg != 0 && GET_CODE (next_arg_reg) == PARALLEL) 2020 if (next_arg_reg != 0 && GET_CODE (next_arg_reg) == PARALLEL)
2012 { 2021 {
2013 rtvec adjust = XVEC (next_arg_reg, 0); 2022 rtvec adjust = XVEC (next_arg_reg, 0);
2014 int num = GET_NUM_ELEM (adjust); 2023 int num = GET_NUM_ELEM (adjust);
2050 } 2059 }
2051 2060
2052 if (tsize > 0) 2061 if (tsize > 0)
2053 { 2062 {
2054 rtx tsize_rtx = GEN_INT (tsize); 2063 rtx tsize_rtx = GEN_INT (tsize);
2055 rtx adjustment_rtx, insn, dwarf_pattern; 2064 rtx adjustment_rtx, dwarf_pattern;
2065 rtx_insn *insn;
2056 2066
2057 if (tsize > 32767) 2067 if (tsize > 32767)
2058 { 2068 {
2059 adjustment_rtx = gen_rtx_REG (Pmode, IQ2000_TEMP1_REGNUM); 2069 adjustment_rtx = gen_rtx_REG (Pmode, IQ2000_TEMP1_REGNUM);
2060 emit_move_insn (adjustment_rtx, tsize_rtx); 2070 emit_move_insn (adjustment_rtx, tsize_rtx);
2063 adjustment_rtx = tsize_rtx; 2073 adjustment_rtx = tsize_rtx;
2064 2074
2065 insn = emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx, 2075 insn = emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
2066 adjustment_rtx)); 2076 adjustment_rtx));
2067 2077
2068 dwarf_pattern = gen_rtx_SET (Pmode, stack_pointer_rtx, 2078 dwarf_pattern = gen_rtx_SET (stack_pointer_rtx,
2069 plus_constant (stack_pointer_rtx, -tsize)); 2079 plus_constant (Pmode, stack_pointer_rtx,
2080 -tsize));
2070 2081
2071 iq2000_annotate_frame_insn (insn, dwarf_pattern); 2082 iq2000_annotate_frame_insn (insn, dwarf_pattern);
2072 2083
2073 save_restore_insns (1); 2084 save_restore_insns (1);
2074 2085
2075 if (frame_pointer_needed) 2086 if (frame_pointer_needed)
2076 { 2087 {
2077 rtx insn = 0; 2088 rtx_insn *insn = 0;
2078 2089
2079 insn = emit_insn (gen_movsi (hard_frame_pointer_rtx, 2090 insn = emit_insn (gen_movsi (hard_frame_pointer_rtx,
2080 stack_pointer_rtx)); 2091 stack_pointer_rtx));
2081 2092
2082 if (insn) 2093 if (insn)
2083 RTX_FRAME_RELATED_P (insn) = 1; 2094 RTX_FRAME_RELATED_P (insn) = 1;
2084 } 2095 }
2085 } 2096 }
2097
2098 if (flag_stack_usage_info)
2099 current_function_static_stack_size = cfun->machine->total_size;
2086 2100
2087 emit_insn (gen_blockage ()); 2101 emit_insn (gen_blockage ());
2088 } 2102 }
2089 2103
2090 /* Expand the epilogue into a bunch of separate insns. */ 2104 /* Expand the epilogue into a bunch of separate insns. */
2153 iq2000_expand_eh_return (rtx address) 2167 iq2000_expand_eh_return (rtx address)
2154 { 2168 {
2155 HOST_WIDE_INT gp_offset = cfun->machine->gp_sp_offset; 2169 HOST_WIDE_INT gp_offset = cfun->machine->gp_sp_offset;
2156 rtx scratch; 2170 rtx scratch;
2157 2171
2158 scratch = plus_constant (stack_pointer_rtx, gp_offset); 2172 scratch = plus_constant (Pmode, stack_pointer_rtx, gp_offset);
2159 emit_move_insn (gen_rtx_MEM (GET_MODE (address), scratch), address); 2173 emit_move_insn (gen_rtx_MEM (GET_MODE (address), scratch), address);
2160 } 2174 }
2161 2175
2162 /* Return nonzero if this function is known to have a null epilogue. 2176 /* Return nonzero if this function is known to have a null epilogue.
2163 This allows the optimizer to omit jumps to jumps if no stack 2177 This allows the optimizer to omit jumps to jumps if no stack
2180 2194
2181 /* Choose the section to use for the constant rtx expression X that has 2195 /* Choose the section to use for the constant rtx expression X that has
2182 mode MODE. */ 2196 mode MODE. */
2183 2197
2184 static section * 2198 static section *
2185 iq2000_select_rtx_section (enum machine_mode mode, rtx x ATTRIBUTE_UNUSED, 2199 iq2000_select_rtx_section (machine_mode mode, rtx x ATTRIBUTE_UNUSED,
2186 unsigned HOST_WIDE_INT align) 2200 unsigned HOST_WIDE_INT align)
2187 { 2201 {
2188 /* For embedded applications, always put constants in read-only data, 2202 /* For embedded applications, always put constants in read-only data,
2189 in order to reduce RAM usage. */ 2203 in order to reduce RAM usage. */
2190 return mergeable_constant_section (mode, align, 0); 2204 return mergeable_constant_section (mode, align, 0);
2239 iq2000_function_value (const_tree valtype, 2253 iq2000_function_value (const_tree valtype,
2240 const_tree fn_decl_or_type, 2254 const_tree fn_decl_or_type,
2241 bool outgoing ATTRIBUTE_UNUSED) 2255 bool outgoing ATTRIBUTE_UNUSED)
2242 { 2256 {
2243 int reg = GP_RETURN; 2257 int reg = GP_RETURN;
2244 enum machine_mode mode = TYPE_MODE (valtype); 2258 machine_mode mode = TYPE_MODE (valtype);
2245 int unsignedp = TYPE_UNSIGNED (valtype); 2259 int unsignedp = TYPE_UNSIGNED (valtype);
2246 const_tree func = fn_decl_or_type; 2260 const_tree func = fn_decl_or_type;
2247 2261
2248 if (fn_decl_or_type 2262 if (fn_decl_or_type
2249 && !DECL_P (fn_decl_or_type)) 2263 && !DECL_P (fn_decl_or_type))
2256 } 2270 }
2257 2271
2258 /* Worker function for TARGET_LIBCALL_VALUE. */ 2272 /* Worker function for TARGET_LIBCALL_VALUE. */
2259 2273
2260 static rtx 2274 static rtx
2261 iq2000_libcall_value (enum machine_mode mode, const_rtx fun ATTRIBUTE_UNUSED) 2275 iq2000_libcall_value (machine_mode mode, const_rtx fun ATTRIBUTE_UNUSED)
2262 { 2276 {
2263 return gen_rtx_REG (((GET_MODE_CLASS (mode) != MODE_INT 2277 return gen_rtx_REG (((GET_MODE_CLASS (mode) != MODE_INT
2264 || GET_MODE_SIZE (mode) >= 4) 2278 || GET_MODE_SIZE (mode) >= 4)
2265 ? mode : SImode), 2279 ? mode : SImode),
2266 GP_RETURN); 2280 GP_RETURN);
2278 2292
2279 2293
2280 /* Return true when an argument must be passed by reference. */ 2294 /* Return true when an argument must be passed by reference. */
2281 2295
2282 static bool 2296 static bool
2283 iq2000_pass_by_reference (CUMULATIVE_ARGS *cum, enum machine_mode mode, 2297 iq2000_pass_by_reference (cumulative_args_t cum_v, machine_mode mode,
2284 const_tree type, bool named ATTRIBUTE_UNUSED) 2298 const_tree type, bool named ATTRIBUTE_UNUSED)
2285 { 2299 {
2300 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
2286 int size; 2301 int size;
2287 2302
2288 /* We must pass by reference if we would be both passing in registers 2303 /* We must pass by reference if we would be both passing in registers
2289 and the stack. This is because any subsequent partial arg would be 2304 and the stack. This is because any subsequent partial arg would be
2290 handled incorrectly in this case. */ 2305 handled incorrectly in this case. */
2294 get double copies of any offsets generated for small structs 2309 get double copies of any offsets generated for small structs
2295 passed in registers. */ 2310 passed in registers. */
2296 CUMULATIVE_ARGS temp; 2311 CUMULATIVE_ARGS temp;
2297 2312
2298 temp = *cum; 2313 temp = *cum;
2299 if (iq2000_function_arg (&temp, mode, type, named) != 0) 2314 if (iq2000_function_arg (pack_cumulative_args (&temp), mode, type, named)
2315 != 0)
2300 return 1; 2316 return 1;
2301 } 2317 }
2302 2318
2303 if (type == NULL_TREE || mode == DImode || mode == DFmode) 2319 if (type == NULL_TREE || mode == DImode || mode == DFmode)
2304 return 0; 2320 return 0;
2309 2325
2310 /* Return the length of INSN. LENGTH is the initial length computed by 2326 /* Return the length of INSN. LENGTH is the initial length computed by
2311 attributes in the machine-description file. */ 2327 attributes in the machine-description file. */
2312 2328
2313 int 2329 int
2314 iq2000_adjust_insn_length (rtx insn, int length) 2330 iq2000_adjust_insn_length (rtx_insn *insn, int length)
2315 { 2331 {
2316 /* A unconditional jump has an unfilled delay slot if it is not part 2332 /* A unconditional jump has an unfilled delay slot if it is not part
2317 of a sequence. A conditional jump normally has a delay slot. */ 2333 of a sequence. A conditional jump normally has a delay slot. */
2318 if (simplejump_p (insn) 2334 if (simplejump_p (insn)
2319 || ( (GET_CODE (insn) == JUMP_INSN 2335 || ( (JUMP_P (insn)
2320 || GET_CODE (insn) == CALL_INSN))) 2336 || CALL_P (insn))))
2321 length += 4; 2337 length += 4;
2322 2338
2323 return length; 2339 return length;
2324 } 2340 }
2325 2341
2337 LENGTH is the length (in bytes) of the sequence we are to generate. 2353 LENGTH is the length (in bytes) of the sequence we are to generate.
2338 That tells us whether to generate a simple conditional branch, or a 2354 That tells us whether to generate a simple conditional branch, or a
2339 reversed conditional branch around a `jr' instruction. */ 2355 reversed conditional branch around a `jr' instruction. */
2340 2356
2341 char * 2357 char *
2342 iq2000_output_conditional_branch (rtx insn, rtx * operands, int two_operands_p, 2358 iq2000_output_conditional_branch (rtx_insn *insn, rtx * operands,
2343 int float_p, int inverted_p, int length) 2359 int two_operands_p, int float_p,
2360 int inverted_p, int length)
2344 { 2361 {
2345 static char buffer[200]; 2362 static char buffer[200];
2346 /* The kind of comparison we are doing. */ 2363 /* The kind of comparison we are doing. */
2347 enum rtx_code code = GET_CODE (operands[0]); 2364 enum rtx_code code = GET_CODE (operands[0]);
2348 /* Nonzero if the opcode for the comparison needs a `z' indicating 2365 /* Nonzero if the opcode for the comparison needs a `z' indicating
2497 NULL, NULL_TREE) 2514 NULL, NULL_TREE)
2498 2515
2499 static void 2516 static void
2500 iq2000_init_builtins (void) 2517 iq2000_init_builtins (void)
2501 { 2518 {
2502 tree endlink = void_list_node;
2503 tree void_ftype, void_ftype_int, void_ftype_int_int; 2519 tree void_ftype, void_ftype_int, void_ftype_int_int;
2504 tree void_ftype_int_int_int; 2520 tree void_ftype_int_int_int;
2505 tree int_ftype_int, int_ftype_int_int, int_ftype_int_int_int; 2521 tree int_ftype_int, int_ftype_int_int, int_ftype_int_int_int;
2506 tree int_ftype_int_int_int_int; 2522 tree int_ftype_int_int_int_int;
2507 2523
2508 /* func () */ 2524 /* func () */
2509 void_ftype 2525 void_ftype
2510 = build_function_type (void_type_node, 2526 = build_function_type_list (void_type_node, NULL_TREE);
2511 tree_cons (NULL_TREE, void_type_node, endlink));
2512 2527
2513 /* func (int) */ 2528 /* func (int) */
2514 void_ftype_int 2529 void_ftype_int
2515 = build_function_type (void_type_node, 2530 = build_function_type_list (void_type_node, integer_type_node, NULL_TREE);
2516 tree_cons (NULL_TREE, integer_type_node, endlink));
2517 2531
2518 /* void func (int, int) */ 2532 /* void func (int, int) */
2519 void_ftype_int_int 2533 void_ftype_int_int
2520 = build_function_type (void_type_node, 2534 = build_function_type_list (void_type_node,
2521 tree_cons (NULL_TREE, integer_type_node, 2535 integer_type_node,
2522 tree_cons (NULL_TREE, integer_type_node, 2536 integer_type_node,
2523 endlink))); 2537 NULL_TREE);
2524 2538
2525 /* int func (int) */ 2539 /* int func (int) */
2526 int_ftype_int 2540 int_ftype_int
2527 = build_function_type (integer_type_node, 2541 = build_function_type_list (integer_type_node,
2528 tree_cons (NULL_TREE, integer_type_node, endlink)); 2542 integer_type_node, NULL_TREE);
2529 2543
2530 /* int func (int, int) */ 2544 /* int func (int, int) */
2531 int_ftype_int_int 2545 int_ftype_int_int
2532 = build_function_type (integer_type_node, 2546 = build_function_type_list (integer_type_node,
2533 tree_cons (NULL_TREE, integer_type_node, 2547 integer_type_node,
2534 tree_cons (NULL_TREE, integer_type_node, 2548 integer_type_node,
2535 endlink))); 2549 NULL_TREE);
2536 2550
2537 /* void func (int, int, int) */ 2551 /* void func (int, int, int) */
2538 void_ftype_int_int_int 2552 void_ftype_int_int_int
2539 = build_function_type 2553 = build_function_type_list (void_type_node,
2540 (void_type_node, 2554 integer_type_node,
2541 tree_cons (NULL_TREE, integer_type_node, 2555 integer_type_node,
2542 tree_cons (NULL_TREE, integer_type_node, 2556 integer_type_node,
2543 tree_cons (NULL_TREE, 2557 NULL_TREE);
2544 integer_type_node, 2558
2545 endlink)))); 2559 /* int func (int, int, int) */
2560 int_ftype_int_int_int
2561 = build_function_type_list (integer_type_node,
2562 integer_type_node,
2563 integer_type_node,
2564 integer_type_node,
2565 NULL_TREE);
2546 2566
2547 /* int func (int, int, int, int) */ 2567 /* int func (int, int, int, int) */
2548 int_ftype_int_int_int_int 2568 int_ftype_int_int_int_int
2549 = build_function_type 2569 = build_function_type_list (integer_type_node,
2550 (integer_type_node, 2570 integer_type_node,
2551 tree_cons (NULL_TREE, integer_type_node, 2571 integer_type_node,
2552 tree_cons (NULL_TREE, integer_type_node, 2572 integer_type_node,
2553 tree_cons (NULL_TREE, 2573 integer_type_node,
2554 integer_type_node, 2574 NULL_TREE);
2555 tree_cons (NULL_TREE,
2556 integer_type_node,
2557 endlink)))));
2558
2559 /* int func (int, int, int) */
2560 int_ftype_int_int_int
2561 = build_function_type
2562 (integer_type_node,
2563 tree_cons (NULL_TREE, integer_type_node,
2564 tree_cons (NULL_TREE, integer_type_node,
2565 tree_cons (NULL_TREE,
2566 integer_type_node,
2567 endlink))));
2568
2569 /* int func (int, int, int, int) */
2570 int_ftype_int_int_int_int
2571 = build_function_type
2572 (integer_type_node,
2573 tree_cons (NULL_TREE, integer_type_node,
2574 tree_cons (NULL_TREE, integer_type_node,
2575 tree_cons (NULL_TREE,
2576 integer_type_node,
2577 tree_cons (NULL_TREE,
2578 integer_type_node,
2579 endlink)))));
2580 2575
2581 def_builtin ("__builtin_ado16", int_ftype_int_int, IQ2000_BUILTIN_ADO16); 2576 def_builtin ("__builtin_ado16", int_ftype_int_int, IQ2000_BUILTIN_ADO16);
2582 def_builtin ("__builtin_ram", int_ftype_int_int_int_int, IQ2000_BUILTIN_RAM); 2577 def_builtin ("__builtin_ram", int_ftype_int_int_int_int, IQ2000_BUILTIN_RAM);
2583 def_builtin ("__builtin_chkhdr", void_ftype_int_int, IQ2000_BUILTIN_CHKHDR); 2578 def_builtin ("__builtin_chkhdr", void_ftype_int_int, IQ2000_BUILTIN_CHKHDR);
2584 def_builtin ("__builtin_pkrl", void_ftype_int_int, IQ2000_BUILTIN_PKRL); 2579 def_builtin ("__builtin_pkrl", void_ftype_int_int, IQ2000_BUILTIN_PKRL);
2634 enum rtx_code *code, int argcount) 2629 enum rtx_code *code, int argcount)
2635 { 2630 {
2636 rtx pat; 2631 rtx pat;
2637 tree arg [5]; 2632 tree arg [5];
2638 rtx op [5]; 2633 rtx op [5];
2639 enum machine_mode mode [5]; 2634 machine_mode mode [5];
2640 int i; 2635 int i;
2641 2636
2642 mode[0] = insn_data[icode].operand[0].mode; 2637 mode[0] = insn_data[icode].operand[0].mode;
2643 for (i = 0; i < argcount; i++) 2638 for (i = 0; i < argcount; i++)
2644 { 2639 {
2664 2659
2665 switch (argcount) 2660 switch (argcount)
2666 { 2661 {
2667 case 0: 2662 case 0:
2668 pat = GEN_FCN (icode) (target); 2663 pat = GEN_FCN (icode) (target);
2664 break;
2669 case 1: 2665 case 1:
2670 if (target) 2666 if (target)
2671 pat = GEN_FCN (icode) (target, op[0]); 2667 pat = GEN_FCN (icode) (target, op[0]);
2672 else 2668 else
2673 pat = GEN_FCN (icode) (op[0]); 2669 pat = GEN_FCN (icode) (op[0]);
2706 SUBTARGET may be used as the target for computing one of EXP's operands. 2702 SUBTARGET may be used as the target for computing one of EXP's operands.
2707 IGNORE is nonzero if the value is to be ignored. */ 2703 IGNORE is nonzero if the value is to be ignored. */
2708 2704
2709 static rtx 2705 static rtx
2710 iq2000_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED, 2706 iq2000_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
2711 enum machine_mode mode ATTRIBUTE_UNUSED, 2707 machine_mode mode ATTRIBUTE_UNUSED,
2712 int ignore ATTRIBUTE_UNUSED) 2708 int ignore ATTRIBUTE_UNUSED)
2713 { 2709 {
2714 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0); 2710 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
2715 int fcode = DECL_FUNCTION_CODE (fndecl); 2711 int fcode = DECL_FUNCTION_CODE (fndecl);
2716 enum rtx_code code [5]; 2712 enum rtx_code code [5];
2897 } 2893 }
2898 2894
2899 /* Worker function for TARGET_SETUP_INCOMING_VARARGS. */ 2895 /* Worker function for TARGET_SETUP_INCOMING_VARARGS. */
2900 2896
2901 static void 2897 static void
2902 iq2000_setup_incoming_varargs (CUMULATIVE_ARGS *cum, 2898 iq2000_setup_incoming_varargs (cumulative_args_t cum_v,
2903 enum machine_mode mode ATTRIBUTE_UNUSED, 2899 machine_mode mode ATTRIBUTE_UNUSED,
2904 tree type ATTRIBUTE_UNUSED, int * pretend_size, 2900 tree type ATTRIBUTE_UNUSED, int * pretend_size,
2905 int no_rtl) 2901 int no_rtl)
2906 { 2902 {
2903 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
2907 unsigned int iq2000_off = ! cum->last_arg_fp; 2904 unsigned int iq2000_off = ! cum->last_arg_fp;
2908 unsigned int iq2000_fp_off = cum->last_arg_fp; 2905 unsigned int iq2000_fp_off = cum->last_arg_fp;
2909 2906
2910 if ((cum->arg_words < MAX_ARGS_IN_REGISTERS - iq2000_off)) 2907 if ((cum->arg_words < MAX_ARGS_IN_REGISTERS - iq2000_off))
2911 { 2908 {
2925 if (! (no_rtl)) 2922 if (! (no_rtl))
2926 { 2923 {
2927 if (cum->arg_words < MAX_ARGS_IN_REGISTERS - iq2000_off) 2924 if (cum->arg_words < MAX_ARGS_IN_REGISTERS - iq2000_off)
2928 { 2925 {
2929 rtx ptr, mem; 2926 rtx ptr, mem;
2930 ptr = plus_constant (virtual_incoming_args_rtx, 2927 ptr = plus_constant (Pmode, virtual_incoming_args_rtx,
2931 - (iq2000_save_gp_regs 2928 - (iq2000_save_gp_regs
2932 * UNITS_PER_WORD)); 2929 * UNITS_PER_WORD));
2933 mem = gen_rtx_MEM (BLKmode, ptr); 2930 mem = gen_rtx_MEM (BLKmode, ptr);
2934 move_block_from_reg 2931 move_block_from_reg
2935 (cum->arg_words + GP_ARG_FIRST + iq2000_off, 2932 (cum->arg_words + GP_ARG_FIRST + iq2000_off,
2936 mem, 2933 mem,
2937 iq2000_save_gp_regs); 2934 iq2000_save_gp_regs);
2943 /* A C compound statement to output to stdio stream STREAM the 2940 /* A C compound statement to output to stdio stream STREAM the
2944 assembler syntax for an instruction operand that is a memory 2941 assembler syntax for an instruction operand that is a memory
2945 reference whose address is ADDR. ADDR is an RTL expression. */ 2942 reference whose address is ADDR. ADDR is an RTL expression. */
2946 2943
2947 static void 2944 static void
2948 iq2000_print_operand_address (FILE * file, rtx addr) 2945 iq2000_print_operand_address (FILE * file, machine_mode mode, rtx addr)
2949 { 2946 {
2950 if (!addr) 2947 if (!addr)
2951 error ("PRINT_OPERAND_ADDRESS, null pointer"); 2948 error ("PRINT_OPERAND_ADDRESS, null pointer");
2952 2949
2953 else 2950 else
2968 if (GET_CODE (arg0) != REG) 2965 if (GET_CODE (arg0) != REG)
2969 abort_with_insn (addr, 2966 abort_with_insn (addr,
2970 "PRINT_OPERAND_ADDRESS, LO_SUM with #1 not REG."); 2967 "PRINT_OPERAND_ADDRESS, LO_SUM with #1 not REG.");
2971 2968
2972 fprintf (file, "%%lo("); 2969 fprintf (file, "%%lo(");
2973 iq2000_print_operand_address (file, arg1); 2970 iq2000_print_operand_address (file, mode, arg1);
2974 fprintf (file, ")(%s)", reg_names [REGNO (arg0)]); 2971 fprintf (file, ")(%s)", reg_names [REGNO (arg0)]);
2975 } 2972 }
2976 break; 2973 break;
2977 2974
2978 case PLUS: 2975 case PLUS:
3216 fprintf (file, "%s", reg_names[regnum]); 3213 fprintf (file, "%s", reg_names[regnum]);
3217 } 3214 }
3218 3215
3219 else if (code == MEM) 3216 else if (code == MEM)
3220 { 3217 {
3218 machine_mode mode = GET_MODE (op);
3219
3221 if (letter == 'D') 3220 if (letter == 'D')
3222 output_address (plus_constant (XEXP (op, 0), 4)); 3221 output_address (mode, plus_constant (Pmode, XEXP (op, 0), 4));
3223 else 3222 else
3224 output_address (XEXP (op, 0)); 3223 output_address (mode, XEXP (op, 0));
3225 } 3224 }
3226 3225
3227 else if (code == CONST_DOUBLE 3226 else if (code == CONST_DOUBLE
3228 && GET_MODE_CLASS (GET_MODE (op)) == MODE_FLOAT) 3227 && GET_MODE_CLASS (GET_MODE (op)) == MODE_FLOAT)
3229 { 3228 {
3281 memory (Z + (<large int> & 0x7fff)); 3280 memory (Z + (<large int> & 0x7fff));
3282 */ 3281 */
3283 3282
3284 rtx 3283 rtx
3285 iq2000_legitimize_address (rtx xinsn, rtx old_x ATTRIBUTE_UNUSED, 3284 iq2000_legitimize_address (rtx xinsn, rtx old_x ATTRIBUTE_UNUSED,
3286 enum machine_mode mode) 3285 machine_mode mode)
3287 { 3286 {
3288 if (TARGET_DEBUG_B_MODE) 3287 if (TARGET_DEBUG_B_MODE)
3289 { 3288 {
3290 GO_PRINTF ("\n========== LEGITIMIZE_ADDRESS\n"); 3289 GO_PRINTF ("\n========== LEGITIMIZE_ADDRESS\n");
3291 GO_DEBUG_RTX (xinsn); 3290 GO_DEBUG_RTX (xinsn);
3321 rtx ptr_reg = gen_reg_rtx (Pmode); 3320 rtx ptr_reg = gen_reg_rtx (Pmode);
3322 3321
3323 emit_move_insn (int_reg, 3322 emit_move_insn (int_reg,
3324 GEN_INT (INTVAL (xplus1) & ~ 0x7fff)); 3323 GEN_INT (INTVAL (xplus1) & ~ 0x7fff));
3325 3324
3326 emit_insn (gen_rtx_SET (VOIDmode, 3325 emit_insn (gen_rtx_SET (ptr_reg,
3327 ptr_reg,
3328 gen_rtx_PLUS (Pmode, xplus0, int_reg))); 3326 gen_rtx_PLUS (Pmode, xplus0, int_reg)));
3329 3327
3330 return plus_constant (ptr_reg, INTVAL (xplus1) & 0x7fff); 3328 return plus_constant (Pmode, ptr_reg, INTVAL (xplus1) & 0x7fff);
3331 } 3329 }
3332 } 3330 }
3333 3331
3334 if (TARGET_DEBUG_B_MODE) 3332 if (TARGET_DEBUG_B_MODE)
3335 GO_PRINTF ("LEGITIMIZE_ADDRESS could not fix.\n"); 3333 GO_PRINTF ("LEGITIMIZE_ADDRESS could not fix.\n");
3337 return xinsn; 3335 return xinsn;
3338 } 3336 }
3339 3337
3340 3338
3341 static bool 3339 static bool
3342 iq2000_rtx_costs (rtx x, int code, int outer_code ATTRIBUTE_UNUSED, int * total, 3340 iq2000_rtx_costs (rtx x, machine_mode mode, int outer_code ATTRIBUTE_UNUSED,
3341 int opno ATTRIBUTE_UNUSED, int * total,
3343 bool speed ATTRIBUTE_UNUSED) 3342 bool speed ATTRIBUTE_UNUSED)
3344 { 3343 {
3345 enum machine_mode mode = GET_MODE (x); 3344 int code = GET_CODE (x);
3346 3345
3347 switch (code) 3346 switch (code)
3348 { 3347 {
3349 case MEM: 3348 case MEM:
3350 { 3349 {
3351 int num_words = (GET_MODE_SIZE (mode) > UNITS_PER_WORD) ? 2 : 1; 3350 int num_words = (GET_MODE_SIZE (mode) > UNITS_PER_WORD) ? 2 : 1;
3352 3351
3353 if (simple_memory_operand (x, mode)) 3352 if (simple_memory_operand (x, mode))
3354 return COSTS_N_INSNS (num_words); 3353 return COSTS_N_INSNS (num_words) != 0;
3355 3354
3356 * total = COSTS_N_INSNS (2 * num_words); 3355 * total = COSTS_N_INSNS (2 * num_words);
3357 break; 3356 break;
3358 } 3357 }
3359 3358
3518 mem = adjust_address (m_tramp, Pmode, 3517 mem = adjust_address (m_tramp, Pmode,
3519 TRAMPOLINE_CODE_SIZE + GET_MODE_SIZE (Pmode)); 3518 TRAMPOLINE_CODE_SIZE + GET_MODE_SIZE (Pmode));
3520 emit_move_insn (mem, chain_value); 3519 emit_move_insn (mem, chain_value);
3521 } 3520 }
3522 3521
3522 /* Implement TARGET_HARD_REGNO_MODE_OK. */
3523
3524 static bool
3525 iq2000_hard_regno_mode_ok (unsigned int regno, machine_mode mode)
3526 {
3527 return (REGNO_REG_CLASS (regno) == GR_REGS
3528 ? (regno & 1) == 0 || GET_MODE_SIZE (mode) <= 4
3529 : (regno & 1) == 0 || GET_MODE_SIZE (mode) == 4);
3530 }
3531
3532 /* Implement TARGET_MODES_TIEABLE_P. */
3533
3534 static bool
3535 iq2000_modes_tieable_p (machine_mode mode1, machine_mode mode2)
3536 {
3537 return ((GET_MODE_CLASS (mode1) == MODE_FLOAT
3538 || GET_MODE_CLASS (mode1) == MODE_COMPLEX_FLOAT)
3539 == (GET_MODE_CLASS (mode2) == MODE_FLOAT
3540 || GET_MODE_CLASS (mode2) == MODE_COMPLEX_FLOAT));
3541 }
3542
3543 /* Implement TARGET_CONSTANT_ALIGNMENT. */
3544
3545 static HOST_WIDE_INT
3546 iq2000_constant_alignment (const_tree exp, HOST_WIDE_INT align)
3547 {
3548 if (TREE_CODE (exp) == STRING_CST || TREE_CODE (exp) == CONSTRUCTOR)
3549 return MAX (align, BITS_PER_WORD);
3550 return align;
3551 }
3552
3553 /* Implement TARGET_STARTING_FRAME_OFFSET. */
3554
3555 static HOST_WIDE_INT
3556 iq2000_starting_frame_offset (void)
3557 {
3558 return crtl->outgoing_args_size;
3559 }
3560
3523 #include "gt-iq2000.h" 3561 #include "gt-iq2000.h"