--- gcc/config/arm/arm.c 2018/04/24 18:22:26 1.1.1.3 +++ gcc/config/arm/arm.c 2018/04/24 18:30:08 1.1.1.4 @@ -1,5 +1,5 @@ /* Output routines for GCC for ARM/RISCiX. - Copyright (C) 1991, 1993, 1994 Free Software Foundation, Inc. + Copyright (C) 1991, 1993, 1994, 1995 Free Software Foundation, Inc. Contributed by Pieter `Tiggr' Schoenmakers (rcpieter@win.tue.nl) and Martin Simmons (@harleqn.co.uk). More major hacks by Richard Earnshaw (rwe11@cl.cam.ac.uk) @@ -18,7 +18,8 @@ GNU General Public License for more deta You should have received a copy of the GNU General Public License along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ +the Free Software Foundation, 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ #include #include @@ -59,7 +60,7 @@ int arm_compare_fp; /* What type of cpu are we compiling for? */ enum processor_type arm_cpu; -/* Waht type of floating point are we compiling for? */ +/* What type of floating point are we compiling for? */ enum floating_point_type arm_fpu; /* In case of a PRE_INC, POST_INC, PRE_DEC, POST_DEC memory reference, we @@ -1143,6 +1144,32 @@ di_operand (op, mode) } } +/* Return TRUE for a valid operand of a DFmode operation when -msoft-float. + Either: REG, CONST_DOUBLE or MEM(DImode_address). + Note that this disallows MEM(REG+REG), but allows + MEM(PRE/POST_INC/DEC(REG)). */ + +int +soft_df_operand (op, mode) + rtx op; + enum machine_mode mode; +{ + if (s_register_operand (op, mode)) + return TRUE; + + switch (GET_CODE (op)) + { + case CONST_DOUBLE: + return TRUE; + + case MEM: + return memory_address_p (DFmode, XEXP (op, 0)); + + default: + return FALSE; + } +} + /* Return TRUE for valid index operands. */ int @@ -1576,7 +1603,6 @@ arm_gen_movstrqi (operands) { HOST_WIDE_INT in_words_to_go, out_words_to_go, last_bytes; int i, r; - rtx const_sxteen = gen_rtx (CONST_INT, SImode, 16); rtx src, dst; rtx st_src, st_dst, end_src, end_dst, fin_src, fin_dst; rtx part_bytes_reg = NULL; @@ -1856,14 +1882,14 @@ print_multi_reg (stream, instr, mask, ha int not_first = FALSE; fputc ('\t', stream); - fprintf (stream, instr, ARM_REG_PREFIX); + fprintf (stream, instr, REGISTER_PREFIX); fputs (", {", stream); for (i = 0; i < 16; i++) if (mask & (1 << i)) { if (not_first) fprintf (stream, ", "); - fprintf (stream, "%s%s", ARM_REG_PREFIX, reg_names[i]); + fprintf (stream, "%s%s", REGISTER_PREFIX, reg_names[i]); not_first = TRUE; } @@ -2399,7 +2425,7 @@ shift_op (op, amountp) multiplication by a power of 2 with the recognizer for a shift. >=32 is not a valid shift for "asl", so we must try and output a shift that produces the correct arithmetical result. - Using lsr #32 is idendical except for the fact that the carry bit + Using lsr #32 is identical except for the fact that the carry bit is not set correctly if we set the flags; but we never use the carry bit from such an operation, so we can ignore that. */ if (code == ROTATERT) @@ -2719,6 +2745,12 @@ output_return_instruction (operand, real return ""; } +/* Return nonzero if optimizing and the current function is volatile. + Such functions never return, and many memory cycles can be saved + by not storing register values that will never be needed again. + This optimization was added to speed up context switching in a + kernel application. */ + int arm_volatile_func () { @@ -2763,15 +2795,15 @@ output_func_prologue (f, frame_size) return_used_this_function = 0; lr_save_eliminated = 0; - fprintf (f, "\t%c args = %d, pretend = %d, frame = %d\n", - ARM_COMMENT_CHAR, current_function_args_size, + fprintf (f, "\t%s args = %d, pretend = %d, frame = %d\n", + ASM_COMMENT_START, current_function_args_size, current_function_pretend_args_size, frame_size); - fprintf (f, "\t%c frame_needed = %d, current_function_anonymous_args = %d\n", - ARM_COMMENT_CHAR, frame_pointer_needed, + fprintf (f, "\t%s frame_needed = %d, current_function_anonymous_args = %d\n", + ASM_COMMENT_START, frame_pointer_needed, current_function_anonymous_args); if (volatile_func) - fprintf (f, "\t%c Volatile function.\n", ARM_COMMENT_CHAR); + fprintf (f, "\t%s Volatile function.\n", ASM_COMMENT_START); if (current_function_anonymous_args && current_function_pretend_args_size) store_arg_regs = 1; @@ -2804,8 +2836,8 @@ output_func_prologue (f, frame_size) } if (lr_save_eliminated) - fprintf (f,"\t%c I don't think this function clobbers lr\n", - ARM_COMMENT_CHAR); + fprintf (f,"\t%s I don't think this function clobbers lr\n", + ASM_COMMENT_START); } @@ -2851,8 +2883,8 @@ output_func_epilogue (f, frame_size) for (reg = 23; reg > 15; reg--) if (regs_ever_live[reg] && ! call_used_regs[reg]) { - fprintf (f, "\tldfe\t%s%s, [%sfp, #-%d]\n", ARM_REG_PREFIX, - reg_names[reg], ARM_REG_PREFIX, floats_offset); + fprintf (f, "\tldfe\t%s%s, [%sfp, #-%d]\n", REGISTER_PREFIX, + reg_names[reg], REGISTER_PREFIX, floats_offset); floats_offset += 12; code_size += 4; } @@ -2875,8 +2907,8 @@ output_func_epilogue (f, frame_size) for (reg = 16; reg < 24; reg++) if (regs_ever_live[reg] && ! call_used_regs[reg]) { - fprintf (f, "\tldfe\t%s%s, [%ssp], #12\n", ARM_REG_PREFIX, - reg_names[reg], ARM_REG_PREFIX); + fprintf (f, "\tldfe\t%s%s, [%ssp], #12\n", REGISTER_PREFIX, + reg_names[reg], REGISTER_PREFIX); code_size += 4; } if (current_function_pretend_args_size == 0 && regs_ever_live[14]) @@ -2902,7 +2934,7 @@ output_func_epilogue (f, frame_size) } fprintf (f, TARGET_6 ? "\tmov\t%spc, %slr\n" : "\tmovs\t%spc, %slr\n", - ARM_REG_PREFIX, ARM_REG_PREFIX, f); + REGISTER_PREFIX, REGISTER_PREFIX, f); code_size += 4; } } @@ -3006,7 +3038,7 @@ arm_expand_prologue () if (live_regs_mask) { /* If we have to push any regs, then we must push lr as well, or - we won't get a propper return. */ + we won't get a proper return. */ live_regs_mask |= 0x4000; emit_multi_reg_push (live_regs_mask); } @@ -3043,13 +3075,13 @@ arm_expand_prologue () /* If CODE is 'd', then the X is a condition operand and the instruction should only be executed if the condition is true. - if CODE is 'D', then the X is a condition operand and the instruciton + if CODE is 'D', then the X is a condition operand and the instruction should only be executed if the condition is false: however, if the mode of the comparison is CCFPEmode, then always execute the instruction -- we do this because in these circumstances !GE does not necessarily imply LT; in these cases the instruction pattern will take care to make sure that an instruction containing %d will follow, thereby undoing the effects of - doing this instrucion unconditionally. + doing this instruction unconditionally. If CODE is 'N' then X is a floating point operand that must be negated before output. If CODE is 'B' then output a bitwise inverted value of X (a const int). @@ -3064,11 +3096,11 @@ arm_print_operand (stream, x, code) switch (code) { case '@': - fputc (ARM_COMMENT_CHAR, stream); + fputs (ASM_COMMENT_START, stream); return; case '|': - fputs (ARM_REG_PREFIX, stream); + fputs (REGISTER_PREFIX, stream); return; case '?': @@ -3134,12 +3166,12 @@ arm_print_operand (stream, x, code) case 'R': if (REGNO (x) > 15) abort (); - fputs (ARM_REG_PREFIX, stream); + fputs (REGISTER_PREFIX, stream); fputs (reg_names[REGNO (x) + 1], stream); return; case 'm': - fputs (ARM_REG_PREFIX, stream); + fputs (REGISTER_PREFIX, stream); if (GET_CODE (XEXP (x, 0)) == REG) fputs (reg_names[REGNO (XEXP (x, 0))], stream); else @@ -3147,8 +3179,8 @@ arm_print_operand (stream, x, code) return; case 'M': - fprintf (stream, "{%s%s-%s%s}", ARM_REG_PREFIX, reg_names[REGNO (x)], - ARM_REG_PREFIX, reg_names[REGNO (x) - 1 + fprintf (stream, "{%s%s-%s%s}", REGISTER_PREFIX, reg_names[REGNO (x)], + REGISTER_PREFIX, reg_names[REGNO (x) - 1 + ((GET_MODE_SIZE (GET_MODE (x)) + GET_MODE_SIZE (SImode) - 1) / GET_MODE_SIZE (SImode))]); @@ -3177,7 +3209,7 @@ arm_print_operand (stream, x, code) if (GET_CODE (x) == REG) { - fputs (ARM_REG_PREFIX, stream); + fputs (REGISTER_PREFIX, stream); fputs (reg_names[REGNO (x)], stream); } else if (GET_CODE (x) == MEM) @@ -3237,7 +3269,7 @@ arm_asm_output_label (stream, name) else { real_name = xmalloc (2 + strlen (name)); - strcpy (real_name, "_"); + strcpy (real_name, USER_LABEL_PREFIX); strcat (real_name, name); } for (s = real_name; *s; s++) @@ -3288,7 +3320,7 @@ output_load_symbol (insn, operands) abort (); /* When generating the instructions, we never mask out the bits that we - think will be always zero, then if a mistake has occured somewhere, the + think will be always zero, then if a mistake has occurred somewhere, the assembler will spot it and generate an error. */ /* If the symbol is word aligned then we might be able to reduce the @@ -3340,7 +3372,7 @@ output_lcomm_directive (stream, name, si char *name; int size, rounded; { - fprintf (stream, "\n\t.bss\t%c .lcomm\n", ARM_COMMENT_CHAR); + fprintf (stream, "\n\t.bss\t%s .lcomm\n", ASM_COMMENT_START); assemble_name (stream, name); fprintf (stream, ":\t.space\t%d\n", rounded); if (in_text_section ()) @@ -3490,7 +3522,7 @@ final_prescan_insn (insn, opvec, noperan if (GET_CODE (insn) != JUMP_INSN) return; - /* This jump might be paralled with a clobber of the condition codes + /* This jump might be paralleled with a clobber of the condition codes the jump should always come first */ if (GET_CODE (body) == PARALLEL && XVECLEN (body, 0) > 0) body = XVECEXP (body, 0, 0); @@ -3708,7 +3740,7 @@ final_prescan_insn (insn, opvec, noperan } /* restore recog_operand (getting the attributes of other insns can destroy this array, but final.c assumes that it remains intact - accross this call; since the insn has been recognized already we + across this call; since the insn has been recognized already we call recog direct). */ recog (PATTERN (insn), insn, NULL_PTR); }