1/* Subroutines used for code generation on IBM RS/6000. 2 Copyright (C) 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 3 2000, 2001, 2002 Free Software Foundation, Inc. 4 Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu) 5 6This file is part of GNU CC. 7 8GNU CC is free software; you can redistribute it and/or modify --- 106 unchanged lines hidden (view full) --- 115int toc_initialized; 116char toc_label_name[10]; 117 118/* Alias set for saves and restores from the rs6000 stack. */ 119static int rs6000_sr_alias_set; 120 121static void rs6000_add_gc_roots PARAMS ((void)); 122static int num_insns_constant_wide PARAMS ((HOST_WIDE_INT)); |
123static void validate_condition_mode 124 PARAMS ((enum rtx_code, enum machine_mode)); 125static rtx rs6000_generate_compare PARAMS ((enum rtx_code)); 126static void rs6000_maybe_dead PARAMS ((rtx)); 127static void rs6000_emit_stack_tie PARAMS ((void)); 128static void rs6000_frame_related PARAMS ((rtx, rtx, HOST_WIDE_INT, rtx, rtx)); 129static void rs6000_emit_allocate_stack PARAMS ((HOST_WIDE_INT, int)); 130static unsigned rs6000_hash_constant PARAMS ((rtx)); --- 4772 unchanged lines hidden (view full) --- 4903 else 4904 abort (); 4905 4906 def_builtin (d->mask, d->name, type, d->code); 4907 } 4908} 4909 4910 |
4911/* Expand a block move operation, and return 1 if successful. Return 0 4912 if we should let the compiler generate normal code. 4913 4914 operands[0] is the destination 4915 operands[1] is the source 4916 operands[2] is the length 4917 operands[3] is the alignment */ 4918 --- 6 unchanged lines hidden (view full) --- 4925 rtx orig_dest = operands[0]; 4926 rtx orig_src = operands[1]; 4927 rtx bytes_rtx = operands[2]; 4928 rtx align_rtx = operands[3]; 4929 int constp = (GET_CODE (bytes_rtx) == CONST_INT); 4930 int align; 4931 int bytes; 4932 int offset; |
4933 int move_bytes; 4934 4935 /* If this is not a fixed size move, just call memcpy */ 4936 if (! constp) 4937 return 0; 4938 4939 /* If this is not a fixed size alignment, abort */ 4940 if (GET_CODE (align_rtx) != CONST_INT) --- 5 unchanged lines hidden (view full) --- 4946 if (bytes <= 0) 4947 return 1; 4948 4949 /* store_one_arg depends on expand_block_move to handle at least the size of 4950 reg_parm_stack_space. */ 4951 if (bytes > (TARGET_POWERPC64 ? 64 : 32)) 4952 return 0; 4953 |
4954 if (TARGET_STRING) /* string instructions are available */ 4955 { |
4956 for (offset = 0; bytes > 0; offset += move_bytes, bytes -= move_bytes) |
4957 { |
4958 union { 4959 rtx (*movstrsi) PARAMS ((rtx, rtx, rtx, rtx)); 4960 rtx (*mov) PARAMS ((rtx, rtx)); 4961 } gen_func; 4962 enum machine_mode mode = BLKmode; 4963 rtx src, dest; 4964 |
4965 if (bytes > 24 /* move up to 32 bytes at a time */ 4966 && ! fixed_regs[5] 4967 && ! fixed_regs[6] 4968 && ! fixed_regs[7] 4969 && ! fixed_regs[8] 4970 && ! fixed_regs[9] 4971 && ! fixed_regs[10] 4972 && ! fixed_regs[11] 4973 && ! fixed_regs[12]) 4974 { 4975 move_bytes = (bytes > 32) ? 32 : bytes; |
4976 gen_func.movstrsi = gen_movstrsi_8reg; |
4977 } 4978 else if (bytes > 16 /* move up to 24 bytes at a time */ 4979 && ! fixed_regs[5] 4980 && ! fixed_regs[6] 4981 && ! fixed_regs[7] 4982 && ! fixed_regs[8] 4983 && ! fixed_regs[9] 4984 && ! fixed_regs[10]) 4985 { 4986 move_bytes = (bytes > 24) ? 24 : bytes; |
4987 gen_func.movstrsi = gen_movstrsi_6reg; |
4988 } 4989 else if (bytes > 8 /* move up to 16 bytes at a time */ 4990 && ! fixed_regs[5] 4991 && ! fixed_regs[6] 4992 && ! fixed_regs[7] 4993 && ! fixed_regs[8]) 4994 { 4995 move_bytes = (bytes > 16) ? 16 : bytes; |
4996 gen_func.movstrsi = gen_movstrsi_4reg; |
4997 } 4998 else if (bytes >= 8 && TARGET_POWERPC64 4999 /* 64-bit loads and stores require word-aligned 5000 displacements. */ 5001 && (align >= 8 || (! STRICT_ALIGNMENT && align >= 4))) 5002 { 5003 move_bytes = 8; |
5004 mode = DImode; 5005 gen_func.mov = gen_movdi; |
5006 } 5007 else if (bytes > 4 && !TARGET_POWERPC64) 5008 { /* move up to 8 bytes at a time */ 5009 move_bytes = (bytes > 8) ? 8 : bytes; |
5010 gen_func.movstrsi = gen_movstrsi_2reg; |
5011 } 5012 else if (bytes >= 4 && (align >= 4 || ! STRICT_ALIGNMENT)) 5013 { /* move 4 bytes */ 5014 move_bytes = 4; |
5015 mode = SImode; 5016 gen_func.mov = gen_movsi; |
5017 } 5018 else if (bytes == 2 && (align >= 2 || ! STRICT_ALIGNMENT)) 5019 { /* move 2 bytes */ 5020 move_bytes = 2; |
5021 mode = HImode; 5022 gen_func.mov = gen_movhi; |
5023 } 5024 else if (bytes == 1) /* move 1 byte */ 5025 { 5026 move_bytes = 1; |
5027 mode = QImode; 5028 gen_func.mov = gen_movqi; |
5029 } 5030 else 5031 { /* move up to 4 bytes at a time */ 5032 move_bytes = (bytes > 4) ? 4 : bytes; |
5033 gen_func.movstrsi = gen_movstrsi_1reg; |
5034 } 5035 |
5036 src = adjust_address (orig_src, mode, offset); 5037 dest = adjust_address (orig_dest, mode, offset); 5038 5039 if (mode == BLKmode) |
5040 { |
5041 /* Move the address into scratch registers. The movstrsi 5042 patterns require zero offset. */ 5043 if (!REG_P (XEXP (src, 0))) |
5044 { |
5045 rtx src_reg = copy_addr_to_reg (XEXP (src, 0)); 5046 src = replace_equiv_address (src, src_reg); |
5047 } |
5048 set_mem_size (src, GEN_INT (move_bytes)); 5049 5050 if (!REG_P (XEXP (dest, 0))) |
5051 { |
5052 rtx dest_reg = copy_addr_to_reg (XEXP (dest, 0)); 5053 dest = replace_equiv_address (dest, dest_reg); |
5054 } |
5055 set_mem_size (dest, GEN_INT (move_bytes)); 5056 5057 emit_insn ((*gen_func.movstrsi) (dest, src, 5058 GEN_INT (move_bytes & 31), 5059 align_rtx)); |
5060 } |
5061 else 5062 { 5063 rtx tmp_reg = gen_reg_rtx (mode); 5064 5065 emit_insn ((*gen_func.mov) (tmp_reg, src)); 5066 emit_insn ((*gen_func.mov) (dest, tmp_reg)); 5067 } |
5068 } 5069 } 5070 5071 else /* string instructions not available */ 5072 { |
5073 rtx stores[MAX_MOVE_REG]; 5074 int num_reg = 0; 5075 int i; 5076 5077 for (offset = 0; bytes > 0; offset += move_bytes, bytes -= move_bytes) |
5078 { |
5079 rtx (*gen_mov_func) PARAMS ((rtx, rtx)); 5080 enum machine_mode mode; 5081 rtx src, dest, tmp_reg; |
5082 5083 /* Generate the appropriate load and store, saving the stores 5084 for later. */ 5085 if (bytes >= 8 && TARGET_POWERPC64 5086 /* 64-bit loads and stores require word-aligned 5087 displacements. */ 5088 && (align >= 8 || (! STRICT_ALIGNMENT && align >= 4))) 5089 { 5090 move_bytes = 8; |
5091 mode = DImode; 5092 gen_mov_func = gen_movdi; |
5093 } 5094 else if (bytes >= 4 && (align >= 4 || ! STRICT_ALIGNMENT)) 5095 { 5096 move_bytes = 4; |
5097 mode = SImode; 5098 gen_mov_func = gen_movsi; |
5099 } 5100 else if (bytes >= 2 && (align >= 2 || ! STRICT_ALIGNMENT)) 5101 { 5102 move_bytes = 2; |
5103 mode = HImode; 5104 gen_mov_func = gen_movhi; |
5105 } 5106 else 5107 { 5108 move_bytes = 1; |
5109 mode = QImode; 5110 gen_mov_func = gen_movqi; |
5111 } 5112 |
5113 src = adjust_address (orig_src, mode, offset); 5114 dest = adjust_address (orig_dest, mode, offset); 5115 tmp_reg = gen_reg_rtx (mode); 5116 5117 emit_insn ((*gen_mov_func) (tmp_reg, src)); 5118 stores[num_reg++] = (*gen_mov_func) (dest, tmp_reg); 5119 |
5120 if (num_reg >= MAX_MOVE_REG) 5121 { 5122 for (i = 0; i < num_reg; i++) 5123 emit_insn (stores[i]); 5124 num_reg = 0; 5125 } 5126 } 5127 --- 2213 unchanged lines hidden (view full) --- 7341 for (first_reg = 13; first_reg <= 31; first_reg++) 7342 if (regs_ever_live[first_reg] 7343 && (! call_used_regs[first_reg] 7344 || (first_reg == RS6000_PIC_OFFSET_TABLE_REGNUM 7345 && ((DEFAULT_ABI == ABI_V4 && flag_pic == 1) 7346 || (DEFAULT_ABI == ABI_DARWIN && flag_pic))))) 7347 break; 7348 |
7349#if TARGET_MACHO |
7350 if (flag_pic && current_function_uses_pic_offset_table && 7351 (first_reg > RS6000_PIC_OFFSET_TABLE_REGNUM)) 7352 return RS6000_PIC_OFFSET_TABLE_REGNUM; 7353#endif 7354 7355 return first_reg; 7356} 7357 --- 626 unchanged lines hidden (view full) --- 7984 7985void 7986rs6000_emit_load_toc_table (fromprolog) 7987 int fromprolog; 7988{ 7989 rtx dest; 7990 dest = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM); 7991 |
7992 if (TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 1) |
7993 { |
7994 rtx temp = (fromprolog 7995 ? gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM) 7996 : gen_reg_rtx (Pmode)); 7997 rs6000_maybe_dead (emit_insn (gen_load_toc_v4_pic_si (temp))); 7998 rs6000_maybe_dead (emit_move_insn (dest, temp)); 7999 } 8000 else if (TARGET_ELF && DEFAULT_ABI != ABI_AIX && flag_pic == 2) 8001 { 8002 char buf[30]; 8003 rtx tempLR = (fromprolog 8004 ? gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM) 8005 : gen_reg_rtx (Pmode)); 8006 rtx temp0 = (fromprolog 8007 ? gen_rtx_REG (Pmode, 0) 8008 : gen_reg_rtx (Pmode)); 8009 rtx symF; 8010 8011 /* possibly create the toc section */ 8012 if (! toc_initialized) |
8013 { |
8014 toc_section (); 8015 function_section (current_function_decl); |
8016 } |
8017 |
8018 if (fromprolog) 8019 { 8020 rtx symL; |
8021 |
8022 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno); 8023 symF = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf)); |
8024 |
8025 ASM_GENERATE_INTERNAL_LABEL (buf, "LCL", rs6000_pic_labelno); 8026 symL = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf)); |
8027 |
8028 rs6000_maybe_dead (emit_insn (gen_load_toc_v4_PIC_1 (tempLR, 8029 symF))); 8030 rs6000_maybe_dead (emit_move_insn (dest, tempLR)); 8031 rs6000_maybe_dead (emit_insn (gen_load_toc_v4_PIC_2 (temp0, dest, 8032 symL, 8033 symF))); 8034 } 8035 else 8036 { 8037 rtx tocsym; 8038 static int reload_toc_labelno = 0; |
8039 |
8040 tocsym = gen_rtx_SYMBOL_REF (Pmode, toc_label_name); |
8041 |
8042 ASM_GENERATE_INTERNAL_LABEL (buf, "LCG", reload_toc_labelno++); 8043 symF = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf)); 8044 8045 rs6000_maybe_dead (emit_insn (gen_load_toc_v4_PIC_1b (tempLR, 8046 symF, 8047 tocsym))); 8048 rs6000_maybe_dead (emit_move_insn (dest, tempLR)); 8049 rs6000_maybe_dead (emit_move_insn (temp0, 8050 gen_rtx_MEM (Pmode, dest))); |
8051 } |
8052 rs6000_maybe_dead (emit_insn (gen_addsi3 (dest, temp0, dest))); |
8053 } |
8054 else if (TARGET_ELF && !TARGET_AIX && flag_pic == 0 && TARGET_MINIMAL_TOC) |
8055 { |
8056 /* This is for AIX code running in non-PIC ELF32. */ 8057 char buf[30]; 8058 rtx realsym; 8059 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1); 8060 realsym = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf)); 8061 8062 rs6000_maybe_dead (emit_insn (gen_elf_high (dest, realsym))); 8063 rs6000_maybe_dead (emit_insn (gen_elf_low (dest, dest, realsym))); 8064 } 8065 else if (DEFAULT_ABI == ABI_AIX) 8066 { |
8067 if (TARGET_32BIT) |
8068 rs6000_maybe_dead (emit_insn (gen_load_toc_aix_si (dest))); |
8069 else |
8070 rs6000_maybe_dead (emit_insn (gen_load_toc_aix_di (dest))); |
8071 } |
8072 else 8073 abort (); |
8074} 8075 8076int 8077get_TOC_alias_set () 8078{ 8079 static int set = -1; 8080 if (set == -1) 8081 set = new_alias_set (); --- 2013 unchanged lines hidden (view full) --- 10095 10096 For a 32-bit target, CONST_INT values are loaded and shifted 10097 entirely within `low' and can be stored in one TOC entry. */ 10098 10099 if (TARGET_64BIT && POINTER_SIZE < GET_MODE_BITSIZE (mode)) 10100 abort ();/* It would be easy to make this work, but it doesn't now. */ 10101 10102 if (POINTER_SIZE > GET_MODE_BITSIZE (mode)) |
10103 { 10104#if HOST_BITS_PER_WIDE_INT == 32 10105 lshift_double (low, high, POINTER_SIZE - GET_MODE_BITSIZE (mode), 10106 POINTER_SIZE, &low, &high, 0); 10107#else 10108 low |= high << 32; 10109 low <<= POINTER_SIZE - GET_MODE_BITSIZE (mode); 10110 high = (HOST_WIDE_INT) low >> 32; 10111 low &= 0xffffffff; 10112#endif 10113 } |
10114 10115 if (TARGET_64BIT) 10116 { 10117 if (TARGET_MINIMAL_TOC) 10118 fputs (DOUBLE_INT_ASM_OP, file); 10119 else 10120 fprintf (file, "\t.tc ID_%lx_%lx[TC],", 10121 (long) high & 0xffffffff, (long) low & 0xffffffff); --- 201 unchanged lines hidden (view full) --- 10323 else 10324 *p = '\0'; 10325} 10326 10327/* Emit profile function. */ 10328 10329void 10330output_profile_hook (labelno) |
10331 int labelno ATTRIBUTE_UNUSED; |
10332{ 10333 if (DEFAULT_ABI == ABI_AIX) 10334 { |
10335#ifdef NO_PROFILE_COUNTERS 10336 emit_library_call (init_one_libfunc (RS6000_MCOUNT), 0, VOIDmode, 0); 10337#else |
10338 char buf[30]; 10339 const char *label_name; 10340 rtx fun; 10341 10342 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno); 10343 STRIP_NAME_ENCODING (label_name, ggc_strdup (buf)); 10344 fun = gen_rtx_SYMBOL_REF (Pmode, label_name); 10345 10346 emit_library_call (init_one_libfunc (RS6000_MCOUNT), 0, VOIDmode, 1, 10347 fun, Pmode); |
10348#endif |
10349 } 10350 else if (DEFAULT_ABI == ABI_DARWIN) 10351 { 10352 const char *mcount_name = RS6000_MCOUNT; 10353 int caller_addr_regno = LINK_REGISTER_REGNUM; 10354 10355 /* Be conservative and always set this, at least for now. */ 10356 current_function_uses_pic_offset_table = 1; --- 17 unchanged lines hidden (view full) --- 10374/* Write function profiler code. */ 10375 10376void 10377output_function_profiler (file, labelno) 10378 FILE *file; 10379 int labelno; 10380{ 10381 char buf[100]; |
10382 int save_lr = 8; |
10383 10384 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno); 10385 switch (DEFAULT_ABI) 10386 { 10387 default: 10388 abort (); 10389 10390 case ABI_V4: |
10391 save_lr = 4; 10392 /* Fall through. */ 10393 |
10394 case ABI_AIX_NODESC: |
10395 if (!TARGET_32BIT) 10396 { 10397 warning ("no profiling of 64-bit code for this ABI"); 10398 return; 10399 } |
10400 fprintf (file, "\tmflr %s\n", reg_names[0]); 10401 if (flag_pic == 1) 10402 { 10403 fputs ("\tbl _GLOBAL_OFFSET_TABLE_@local-4\n", file); |
10404 asm_fprintf (file, "\t{st|stw} %s,%d(%s)\n", 10405 reg_names[0], save_lr, reg_names[1]); |
10406 asm_fprintf (file, "\tmflr %s\n", reg_names[12]); 10407 asm_fprintf (file, "\t{l|lwz} %s,", reg_names[0]); 10408 assemble_name (file, buf); 10409 asm_fprintf (file, "@got(%s)\n", reg_names[12]); 10410 } 10411 else if (flag_pic > 1) 10412 { |
10413 asm_fprintf (file, "\t{st|stw} %s,%d(%s)\n", 10414 reg_names[0], save_lr, reg_names[1]); |
10415 /* Now, we need to get the address of the label. */ 10416 fputs ("\tbl 1f\n\t.long ", file); 10417 assemble_name (file, buf); 10418 fputs ("-.\n1:", file); 10419 asm_fprintf (file, "\tmflr %s\n", reg_names[11]); 10420 asm_fprintf (file, "\t{l|lwz} %s,0(%s)\n", 10421 reg_names[0], reg_names[11]); 10422 asm_fprintf (file, "\t{cax|add} %s,%s,%s\n", 10423 reg_names[0], reg_names[0], reg_names[11]); 10424 } 10425 else 10426 { 10427 asm_fprintf (file, "\t{liu|lis} %s,", reg_names[12]); 10428 assemble_name (file, buf); 10429 fputs ("@ha\n", file); |
10430 asm_fprintf (file, "\t{st|stw} %s,%d(%s)\n", 10431 reg_names[0], save_lr, reg_names[1]); |
10432 asm_fprintf (file, "\t{cal|la} %s,", reg_names[0]); 10433 assemble_name (file, buf); 10434 asm_fprintf (file, "@l(%s)\n", reg_names[12]); 10435 } 10436 |
10437 if (current_function_needs_context && DEFAULT_ABI == ABI_AIX_NODESC) 10438 { 10439 asm_fprintf (file, "\t{st|stw} %s,%d(%s)\n", 10440 reg_names[STATIC_CHAIN_REGNUM], 10441 12, reg_names[1]); 10442 fprintf (file, "\tbl %s\n", RS6000_MCOUNT); 10443 asm_fprintf (file, "\t{l|lwz} %s,%d(%s)\n", 10444 reg_names[STATIC_CHAIN_REGNUM], 10445 12, reg_names[1]); 10446 } 10447 else 10448 /* ABI_V4 saves the static chain reg with ASM_OUTPUT_REG_PUSH. */ 10449 fprintf (file, "\tbl %s\n", RS6000_MCOUNT); |
10450 break; 10451 10452 case ABI_AIX: 10453 case ABI_DARWIN: 10454 /* Don't do anything, done in output_profile_hook (). */ 10455 break; |
10456 } 10457} 10458 10459/* Adjust the cost of a scheduling dependency. Return the new cost of 10460 a dependency LINK or INSN on DEP_INSN. COST is the current cost. */ 10461 10462static int 10463rs6000_adjust_cost (insn, link, dep_insn, cost) --- 962 unchanged lines hidden --- |