--- gcc/config/i860.c 2018/04/24 17:51:36 1.1 +++ gcc/config/i860.c 2018/04/24 17:59:43 1.1.1.3 @@ -669,12 +669,14 @@ singlemove_string (operands) } if (GET_CODE (operands[1]) == CONST_INT) { + if (operands[1] == const0_rtx) + return "mov %?r0,%0"; if((INTVAL (operands[1]) & 0xffff0000) == 0) return "or %L1,%?r0,%0"; + if((INTVAL (operands[1]) & 0xffff8000) == 0xffff8000) + return "adds %1,%?r0,%0"; if((INTVAL (operands[1]) & 0x0000ffff) == 0) return "orh %H1,%?r0,%0"; - if (operands[1] == const0_rtx) - return "mov %?r0,%0"; } return "mov %1,%0"; } @@ -1196,7 +1198,7 @@ output_size_for_block_move (size, reg, a #if 1 cc_status.flags &= ~ CC_KNOW_HI_R31; - output_asm_insn ("mov %1,%0", xoperands); + output_asm_insn (singlemove_string (xoperands), xoperands); #else if (GET_CODE (size) == REG) output_asm_insn ("sub %2,%1,%0", xoperands); @@ -1347,8 +1349,8 @@ output_block_move (operands) output_asm_insn ("adds %4,%?r0,%5", xoperands); /* Predecrement the loop counter. This happens again also in the `bla' - instruction which precceds the loop, but we need to have it done - two times before we enter the loop because of the bizzare semantics + instruction which precedes the loop, but we need to have it done + two times before we enter the loop because of the bizarre semantics of the bla instruction. */ output_asm_insn ("adds %5,%2,%2", xoperands); @@ -1522,7 +1524,7 @@ output_delayed_branch (template, operand output_asm_insn (template, operands); /* Now recognize the insn which we put in its delay slot. - We must do this after outputing the branch insn, + We must do this after outputting the branch insn, since operands may just be a pointer to `recog_operand'. */ INSN_CODE (delay_insn) = insn_code_number = recog (pat, delay_insn); if (insn_code_number == -1) @@ -1557,7 +1559,7 @@ output_delay_insn (delay_insn) int i; /* Now recognize the insn which we put in its delay slot. - We must do this after outputing the branch insn, + We must do this after outputting the branch insn, since operands may just be a pointer to `recog_operand'. */ insn_code_number = recog_memoized (delay_insn); if (insn_code_number == -1) @@ -1567,7 +1569,7 @@ output_delay_insn (delay_insn) INSN_CODE (delay_insn) = insn_code_number; insn_extract (delay_insn); - /* It is possible that this insn has not been properly scaned by final + /* It is possible that this insn has not been properly scanned by final yet. If this insn's operands don't appear in the peephole's actual operands, then they won't be fixed up by final, so we make sure they get fixed up here. -- This is a kludge. */ @@ -1614,21 +1616,17 @@ unsigned long sfmode_constant_to_ulong (x) rtx x; { - union { double d; unsigned long i[2]; } u; + REAL_VALUE_TYPE d; union { float f; unsigned long i; } u2; if (GET_CODE (x) != CONST_DOUBLE || GET_MODE (x) != SFmode) abort (); -#ifndef HOST_WORDS_BIG_ENDIAN - u.i[0] = CONST_DOUBLE_LOW (x); - u.i[1] = CONST_DOUBLE_HIGH (x); -#else - u.i[0] = CONST_DOUBLE_HIGH (x); - u.i[1] = CONST_DOUBLE_LOW (x); +#if TARGET_FLOAT_FORMAT != HOST_FLOAT_FORMAT + error IEEE emulation needed #endif - - u2.f = u.d; + REAL_VALUE_FROM_CONST_DOUBLE (d, x); + u2.f = d; return u2.i; } @@ -1667,7 +1665,7 @@ sfmode_constant_to_ulong (x) offsets from the frame pointer). Previous versions of GCC also saved the "preserved" registers in the - "nagative" part of the frame, but they saved them using positive + "negative" part of the frame, but they saved them using positive offsets from the (adjusted) stack pointer (after it had been adjusted to allocate space for the new frame). That's just plain wrong because if the current function calls alloca(), the stack pointer @@ -1706,7 +1704,7 @@ sfmode_constant_to_ulong (x) There are two somewhat different ways that you can generate prologues here... i.e. pedantically ABI-compliant, and the "other" way. The - "other" way is more consistant with what is currently generated by the + "other" way is more consistent with what is currently generated by the "native" svr4 C compiler for the i860. That's important if you want to use the current (as of 8/91) incarnation of svr4 SDB for the i860. The SVR4 SDB for the i860 insists on having function prologues be @@ -2041,15 +2039,49 @@ function_prologue (asm_file, local_bytes instruction, so what the hell. */ +/* This corresponds to a version 4 TDESC structure. Lower numbered + versions successively omit the last word of the structure. We + don't try to handle version 5 here. */ + +typedef struct TDESC_flags { + int version:4; + int reg_packing:1; + int callable_block:1; + int reserved:4; + int fregs:6; /* fp regs 2-7 */ + int iregs:16; /* regs 0-15 */ +} TDESC_flags; + +typedef struct TDESC { + TDESC_flags flags; + int integer_reg_offset; /* same as must_preserve_bytes */ + int floating_point_reg_offset; + unsigned int positive_frame_size; /* same as frame_upper_bytes */ + unsigned int negative_frame_size; /* same as frame_lower_bytes */ +} TDESC; + void function_epilogue (asm_file, local_bytes) register FILE *asm_file; register unsigned local_bytes; { register unsigned frame_upper_bytes; + register unsigned frame_lower_bytes; register unsigned preserved_reg_bytes = 0; register unsigned i; register unsigned restored_so_far = 0; + register unsigned int_restored; + register unsigned mask; + unsigned intflags=0; + register TDESC_flags *flags = (TDESC_flags *) &intflags; + + flags->version = 4; + flags->reg_packing = 1; + flags->iregs = 8; /* old fp always gets saved */ + + /* Round-up the frame_lower_bytes so that it's a multiple of 16. */ + + frame_lower_bytes = (local_bytes + STACK_ALIGNMENT - 1) & -STACK_ALIGNMENT; /* Count the number of registers that were preserved in the prologue. Ignore r0. It is never preserved. */ @@ -2073,17 +2105,31 @@ function_epilogue (asm_file, local_bytes /* Restore all of the "preserved" registers that need restoring. */ - for (i = 1; i < 32; i++) - if (regs_ever_live[i] && ! call_used_regs[i]) + mask = 2; + + for (i = 1; i < 32; i++, mask<<=1) + if (regs_ever_live[i] && ! call_used_regs[i]) { fprintf (asm_file, "\tld.l %d(%sfp),%s%s\n", must_preserve_bytes + (4 * restored_so_far++), i860_reg_prefix, i860_reg_prefix, reg_names[i]); + if (i > 3 && i < 16) + flags->iregs |= mask; + } - for (i = 32; i < 64; i++) - if (regs_ever_live[i] && ! call_used_regs[i]) + int_restored = restored_so_far; + mask = 1; + + for (i = 32; i < 64; i++) { + if (regs_ever_live[i] && ! call_used_regs[i]) { fprintf (asm_file, "\tfld.l %d(%sfp),%s%s\n", must_preserve_bytes + (4 * restored_so_far++), i860_reg_prefix, i860_reg_prefix, reg_names[i]); + if (i > 33 & i < 40) + flags->fregs |= mask; + } + if (i > 33 && i < 40) + mask<<=1; + } /* Get the value we plan to use to restore the stack pointer into r31. */ @@ -2092,9 +2138,11 @@ function_epilogue (asm_file, local_bytes /* Restore the return address and the old frame pointer. */ - if (must_preserve_r1) + if (must_preserve_r1) { fprintf (asm_file, "\tld.l 4(%sfp),%sr1\n", i860_reg_prefix, i860_reg_prefix); + flags->iregs |= 2; + } fprintf (asm_file, "\tld.l 0(%sfp),%sfp\n", i860_reg_prefix, i860_reg_prefix); @@ -2103,4 +2151,37 @@ function_epilogue (asm_file, local_bytes fprintf (asm_file, "\tbri %sr1\n\tmov %sr31,%ssp\n", i860_reg_prefix, i860_reg_prefix, i860_reg_prefix); + +#ifdef OUTPUT_TDESC /* Output an ABI-compliant TDESC entry */ + if (! frame_lower_bytes) { + flags->version--; + if (! frame_upper_bytes) { + flags->version--; + if (restored_so_far == int_restored) /* No FP saves */ + flags->version--; + } + } + assemble_name(asm_file,current_function_original_name); + fputs(".TDESC:\n", asm_file); + fprintf(asm_file, "%s 0x%0x\n", ASM_LONG, intflags); + fprintf(asm_file, "%s %d\n", ASM_LONG, + int_restored ? must_preserve_bytes : 0); + if (flags->version > 1) { + fprintf(asm_file, "%s %d\n", ASM_LONG, + (restored_so_far == int_restored) ? 0 : must_preserve_bytes + + (4 * int_restored)); + if (flags->version > 2) { + fprintf(asm_file, "%s %d\n", ASM_LONG, frame_upper_bytes); + if (flags->version > 3) + fprintf(asm_file, "%s %d\n", ASM_LONG, frame_lower_bytes); + } + } + tdesc_section(); + fprintf(asm_file, "%s ", ASM_LONG); + assemble_name(asm_file, current_function_original_name); + fprintf(asm_file, "\n%s ", ASM_LONG); + assemble_name(asm_file, current_function_original_name); + fputs(".TDESC\n", asm_file); + text_section(); +#endif }