--- gcc/config/m68k/m68k.c 2018/04/24 18:14:44 1.1.1.2 +++ gcc/config/m68k/m68k.c 2018/04/24 18:21:09 1.1.1.3 @@ -1,5 +1,5 @@ /* Subroutines for insn-output.c for Motorola 68000 family. - Copyright (C) 1987, 1993 Free Software Foundation, Inc. + Copyright (C) 1987, 1993, 1994 Free Software Foundation, Inc. This file is part of GNU CC. @@ -93,8 +93,20 @@ output_function_prologue (stream, size) if (frame_pointer_needed) { - /* Adding negative number is faster on the 68040. */ - if (fsize < 0x8000 && !TARGET_68040) + if (fsize == 0 && TARGET_68040) + { + /* on the 68040, pea + move is faster than link.w 0 */ +#ifdef MOTOROLA + asm_fprintf (stream, "\tpea (%s)\n\tmove.l %s,%s\n", + reg_names[FRAME_POINTER_REGNUM], reg_names[STACK_POINTER_REGNUM], + reg_names[FRAME_POINTER_REGNUM]); +#else + asm_fprintf (stream, "\tpea %s@\n\tmovel %s,%s\n", + reg_names[FRAME_POINTER_REGNUM], reg_names[STACK_POINTER_REGNUM], + reg_names[FRAME_POINTER_REGNUM]); +#endif + } + else if (fsize < 0x8000) { #ifdef MOTOROLA asm_fprintf (stream, "\tlink.w %s,%0I%d\n", @@ -116,6 +128,7 @@ output_function_prologue (stream, size) } else { + /* Adding negative number is faster on the 68040. */ #ifdef MOTOROLA asm_fprintf (stream, "\tlink.w %s,%0I0\n\tadd.l %0I%d,%Rsp\n", reg_names[FRAME_POINTER_REGNUM], -fsize); @@ -130,6 +143,7 @@ output_function_prologue (stream, size) /* Adding negative number is faster on the 68040. */ if (fsize + 4 < 0x8000) { + /* asm_fprintf() cannot handle %. */ #ifdef MOTOROLA asm_fprintf (stream, "\tadd.w %0I%d,%Rsp\n", - (fsize + 4)); #else @@ -138,6 +152,7 @@ output_function_prologue (stream, size) } else { + /* asm_fprintf() cannot handle %. */ #ifdef MOTOROLA asm_fprintf (stream, "\tadd.l %0I%d,%Rsp\n", - (fsize + 4)); #else @@ -315,9 +330,9 @@ output_function_epilogue (stream, size) && (mask || fmask || fpoffset)) { #ifdef MOTOROLA - asm_fprintf (stream, "\t%Omove.l %0I%d,%Ra0\n", -fsize); + asm_fprintf (stream, "\t%Omove.l %0I%d,%Ra1\n", -fsize); #else - asm_fprintf (stream, "\tmovel %0I%d,%Ra0\n", -fsize); + asm_fprintf (stream, "\tmovel %0I%d,%Ra1\n", -fsize); #endif fsize = 0, big = 1; } @@ -337,12 +352,12 @@ output_function_epilogue (stream, size) if (big) { #ifdef MOTOROLA - asm_fprintf (stream, "\t%Omove.l -%d(%s,%Ra0.l),%s\n", + asm_fprintf (stream, "\t%Omove.l -%d(%s,%Ra1.l),%s\n", offset + fsize, reg_names[FRAME_POINTER_REGNUM], reg_names[i]); #else - asm_fprintf (stream, "\tmovel %s@(-%d,%Ra0:l),%s\n", + asm_fprintf (stream, "\tmovel %s@(-%d,%Ra1:l),%s\n", reg_names[FRAME_POINTER_REGNUM], offset + fsize, reg_names[i]); #endif @@ -378,12 +393,12 @@ output_function_epilogue (stream, size) if (big) { #ifdef MOTOROLA - asm_fprintf (stream, "\tmovm.l -%d(%s,%Ra0.l),%0I0x%x\n", + asm_fprintf (stream, "\tmovm.l -%d(%s,%Ra1.l),%0I0x%x\n", offset + fsize, reg_names[FRAME_POINTER_REGNUM], mask); #else - asm_fprintf (stream, "\tmoveml %s@(-%d,%Ra0:l),%0I0x%x\n", + asm_fprintf (stream, "\tmoveml %s@(-%d,%Ra1:l),%0I0x%x\n", reg_names[FRAME_POINTER_REGNUM], offset + fsize, mask); #endif @@ -415,12 +430,12 @@ output_function_epilogue (stream, size) if (big) { #ifdef MOTOROLA - asm_fprintf (stream, "\tfmovm -%d(%s,%Ra0.l),%0I0x%x\n", + asm_fprintf (stream, "\tfmovm -%d(%s,%Ra1.l),%0I0x%x\n", foffset + fsize, reg_names[FRAME_POINTER_REGNUM], fmask); #else - asm_fprintf (stream, "\tfmovem %s@(-%d,%Ra0:l),%0I0x%x\n", + asm_fprintf (stream, "\tfmovem %s@(-%d,%Ra1:l),%0I0x%x\n", reg_names[FRAME_POINTER_REGNUM], foffset + fsize, fmask); #endif @@ -454,12 +469,12 @@ output_function_epilogue (stream, size) if (big) { #ifdef MOTOROLA - asm_fprintf (stream, "\tfpmovd -%d(%s,%Ra0.l), %s\n", + asm_fprintf (stream, "\tfpmovd -%d(%s,%Ra1.l), %s\n", fpoffset + fsize, reg_names[FRAME_POINTER_REGNUM], reg_names[regno]); #else - asm_fprintf (stream, "\tfpmoved %s@(-%d,%Ra0:l), %s\n", + asm_fprintf (stream, "\tfpmoved %s@(-%d,%Ra1:l), %s\n", reg_names[FRAME_POINTER_REGNUM], fpoffset + fsize, reg_names[regno]); #endif @@ -496,6 +511,7 @@ output_function_epilogue (stream, size) { if (fsize + 4 < 0x8000) { + /* asm_fprintf() cannot handle %. */ #ifdef MOTOROLA asm_fprintf (stream, "\tadd.w %0I%d,%Rsp\n", fsize + 4); #else @@ -504,6 +520,7 @@ output_function_epilogue (stream, size) } else { + /* asm_fprintf() cannot handle %. */ #ifdef MOTOROLA asm_fprintf (stream, "\tadd.l %0I%d,%Rsp\n", fsize + 4); #else @@ -1149,16 +1166,16 @@ compadr: if (addreg0) { if (size == 12) - output_asm_insn ("addql %#8,%0", &addreg0); + output_asm_insn ("addq%.l %#8,%0", &addreg0); else - output_asm_insn ("addql %#4,%0", &addreg0); + output_asm_insn ("addq%.l %#4,%0", &addreg0); } if (addreg1) { if (size == 12) - output_asm_insn ("addql %#8,%0", &addreg1); + output_asm_insn ("addq%.l %#8,%0", &addreg1); else - output_asm_insn ("addql %#4,%0", &addreg1); + output_asm_insn ("addq%.l %#4,%0", &addreg1); } /* Do that word. */ @@ -1166,17 +1183,17 @@ compadr: /* Undo the adds we just did. */ if (addreg0) - output_asm_insn ("subql %#4,%0", &addreg0); + output_asm_insn ("subq%.l %#4,%0", &addreg0); if (addreg1) - output_asm_insn ("subql %#4,%0", &addreg1); + output_asm_insn ("subq%.l %#4,%0", &addreg1); if (size == 12) { output_asm_insn (singlemove_string (middlehalf), middlehalf); if (addreg0) - output_asm_insn ("subql %#4,%0", &addreg0); + output_asm_insn ("subq%.l %#4,%0", &addreg0); if (addreg1) - output_asm_insn ("subql %#4,%0", &addreg1); + output_asm_insn ("subq%.l %#4,%0", &addreg1); } /* Do low-numbered word. */ @@ -1191,18 +1208,18 @@ compadr: if (size == 12) { if (addreg0) - output_asm_insn ("addql %#4,%0", &addreg0); + output_asm_insn ("addq%.l %#4,%0", &addreg0); if (addreg1) - output_asm_insn ("addql %#4,%0", &addreg1); + output_asm_insn ("addq%.l %#4,%0", &addreg1); output_asm_insn (singlemove_string (middlehalf), middlehalf); } /* Make any unoffsettable addresses point at high-numbered word. */ if (addreg0) - output_asm_insn ("addql %#4,%0", &addreg0); + output_asm_insn ("addq%.l %#4,%0", &addreg0); if (addreg1) - output_asm_insn ("addql %#4,%0", &addreg1); + output_asm_insn ("addq%.l %#4,%0", &addreg1); /* Do that word. */ output_asm_insn (singlemove_string (latehalf), latehalf); @@ -1211,16 +1228,16 @@ compadr: if (addreg0) { if (size == 12) - output_asm_insn ("subql %#8,%0", &addreg0); + output_asm_insn ("subq%.l %#8,%0", &addreg0); else - output_asm_insn ("subql %#4,%0", &addreg0); + output_asm_insn ("subq%.l %#4,%0", &addreg0); } if (addreg1) { if (size == 12) - output_asm_insn ("subql %#8,%0", &addreg1); + output_asm_insn ("subq%.l %#8,%0", &addreg1); else - output_asm_insn ("subql %#4,%0", &addreg1); + output_asm_insn ("subq%.l %#4,%0", &addreg1); } return ""; @@ -1344,7 +1361,7 @@ notice_update_cc (exp, insn) { case PLUS: case MINUS: case MULT: case DIV: case UDIV: case MOD: case UMOD: case NEG: - case ASHIFT: case LSHIFT: case ASHIFTRT: case LSHIFTRT: + case ASHIFT: case ASHIFTRT: case LSHIFTRT: case ROTATE: case ROTATERT: if (GET_MODE (cc_status.value2) != VOIDmode) cc_status.flags |= CC_NO_OVERFLOW; @@ -1495,6 +1512,10 @@ standard_68881_constant_p (x) int i; enum machine_mode mode; +#ifdef NO_ASM_FMOVECR + return 0; +#endif + /* fmovecr must be emulated on the 68040, so it shouldn't be used at all. */ if (TARGET_68040) return 0; @@ -1842,6 +1863,7 @@ print_operand (file, op, letter) } else if (GET_CODE (op) == REG) { +#ifdef SUPPORT_SUN_FPA if (REGNO (op) < 16 && (letter == 'y' || letter == 'x') && GET_MODE (op) == DFmode) @@ -1850,6 +1872,7 @@ print_operand (file, op, letter) reg_names[REGNO (op)+1]); } else +#endif { fprintf (file, "%s", reg_names[REGNO (op)]); } @@ -1917,6 +1940,9 @@ print_operand (file, op, letter) define such "LDnnn" to be either "Lnnn-LInnn-2.b", "Lnnn", or any other string, as necessary. This is accomplished via the ASM_OUTPUT_CASE_END macro. See m68k/sgs.h for an example; for versions without the bug. + Some assemblers refuse all the above solutions. The workaround is to + emit "K(pc,d0.l*2)" with K being a small constant known to give the + right behaviour. They also do not like things like "pea 1.w", so we simple leave off the .w on small constants. @@ -1926,6 +1952,21 @@ print_operand (file, op, letter) offset is output in word mode (eg movel a5@(_foo:w), a0). When generating -fPIC code the offset is output in long mode (eg movel a5@(_foo:l), a0) */ +#ifndef ASM_OUTPUT_CASE_FETCH +#ifdef MOTOROLA +#ifdef SGS +#define ASM_OUTPUT_CASE_FETCH(file, labelno, regname)\ + asm_fprintf (file, "%LLD%d(%Rpc,%s.", labelno, regname) +#else +#define ASM_OUTPUT_CASE_FETCH(file, labelno, regname)\ + asm_fprintf (file, "%LL%d-%LLI%d.b(%Rpc,%s.", labelno, labelno, regname) +#endif +#else +#define ASM_OUTPUT_CASE_FETCH(file, labelno, regname)\ + asm_fprintf (file, "%Rpc@(%LL%d-%LLI%d-2:b,%s:", labelno, labelno, regname) +#endif +#endif /* ASM_OUTPUT_CASE_FETCH */ + void print_operand_address (file, addr) FILE *file; @@ -2062,43 +2103,17 @@ print_operand_address (file, addr) } if (GET_CODE (ireg) == SIGN_EXTEND) { -#ifdef MOTOROLA -#ifdef SGS - asm_fprintf (file, "%LLD%d(%Rpc,%s.w", + ASM_OUTPUT_CASE_FETCH (file, CODE_LABEL_NUMBER (XEXP (addr, 0)), reg_names[REGNO (XEXP (ireg, 0))]); -#else - asm_fprintf (file, "%LL%d-%LLI%d.b(%Rpc,%s.w", - CODE_LABEL_NUMBER (XEXP (addr, 0)), - CODE_LABEL_NUMBER (XEXP (addr, 0)), - reg_names[REGNO (XEXP (ireg, 0))]); -#endif -#else - asm_fprintf (file, "%Rpc@(%LL%d-%LLI%d-2:b,%s:w", - CODE_LABEL_NUMBER (XEXP (addr, 0)), - CODE_LABEL_NUMBER (XEXP (addr, 0)), - reg_names[REGNO (XEXP (ireg, 0))]); -#endif + fprintf (file, "w"); } else { -#ifdef MOTOROLA -#ifdef SGS - asm_fprintf (file, "%LLD%d(%Rpc,%s.l", - CODE_LABEL_NUMBER (XEXP (addr, 0)), - reg_names[REGNO (ireg)]); -#else - asm_fprintf (file, "%LL%d-%LLI%d.b(%Rpc,%s.l", - CODE_LABEL_NUMBER (XEXP (addr, 0)), + ASM_OUTPUT_CASE_FETCH (file, CODE_LABEL_NUMBER (XEXP (addr, 0)), reg_names[REGNO (ireg)]); -#endif -#else - asm_fprintf (file, "%Rpc@(%LL%d-%LLI%d-2:b,%s:l", - CODE_LABEL_NUMBER (XEXP (addr, 0)), - CODE_LABEL_NUMBER (XEXP (addr, 0)), - reg_names[REGNO (ireg)]); -#endif + fprintf (file, "l"); } if (scale != 1) { @@ -2114,24 +2129,10 @@ print_operand_address (file, addr) if (breg != 0 && ireg == 0 && GET_CODE (addr) == LABEL_REF && ! (flag_pic && breg == pic_offset_table_rtx)) { -#ifdef MOTOROLA -#ifdef SGS - asm_fprintf (file, "%LLD%d(%Rpc,%s.l", - CODE_LABEL_NUMBER (XEXP (addr, 0)), - reg_names[REGNO (breg)]); -#else - asm_fprintf (file, "%LL%d-%LLI%d.b(%Rpc,%s.l", - CODE_LABEL_NUMBER (XEXP (addr, 0)), - CODE_LABEL_NUMBER (XEXP (addr, 0)), - reg_names[REGNO (breg)]); -#endif -#else - asm_fprintf (file, "%Rpc@(%LL%d-%LLI%d-2:b,%s:l", - CODE_LABEL_NUMBER (XEXP (addr, 0)), + ASM_OUTPUT_CASE_FETCH (file, CODE_LABEL_NUMBER (XEXP (addr, 0)), reg_names[REGNO (breg)]); -#endif - putc (')', file); + fprintf (file, "l)"); break; } if (ireg != 0 || breg != 0) @@ -2207,23 +2208,10 @@ print_operand_address (file, addr) else if (reg1 != 0 && GET_CODE (addr) == LABEL_REF && ! (flag_pic && reg1 == pic_offset_table_rtx)) { -#ifdef MOTOROLA -#ifdef SGS - asm_fprintf (file, "%LLD%d(%Rpc,%s.l)", + ASM_OUTPUT_CASE_FETCH (file, CODE_LABEL_NUMBER (XEXP (addr, 0)), reg_names[REGNO (reg1)]); -#else - asm_fprintf (file, "%LL%d-%LLI%d.b(%Rpc,%s.l)", - CODE_LABEL_NUMBER (XEXP (addr, 0)), - CODE_LABEL_NUMBER (XEXP (addr, 0)), - reg_names[REGNO (reg1)]); -#endif -#else - asm_fprintf (file, "%Rpc@(%LL%d-%LLI%d-2:b,%s:l)", - CODE_LABEL_NUMBER (XEXP (addr, 0)), - CODE_LABEL_NUMBER (XEXP (addr, 0)), - reg_names[REGNO (reg1)]); -#endif + fprintf (file, "l)"); break; } /* FALL-THROUGH (is this really what we want? */