diff options
| author | phx <phx@NetBSD.org> | 2008-11-13 18:10:56 +0000 |
|---|---|---|
| committer | phx <phx@NetBSD.org> | 2008-11-13 18:10:56 +0000 |
| commit | 8fea32b8abc0d18dff4cf8dd8d3fb9987d3d412c (patch) | |
| tree | 0491694b1cfff99ab733b80b7b89c97e1fea51f7 /gnu | |
| parent | d5e5a2c9ebe59d9193a55c4412d1a799f7538ac7 (diff) | |
Reverted my last modification, because it included GPLv3 code. Sorry.
Diffstat (limited to 'gnu')
| -rw-r--r-- | gnu/dist/gcc4/gcc/config/m68k/m68k.c | 44 | ||||
| -rw-r--r-- | gnu/dist/gcc4/gcc/config/m68k/m68k.md | 23 |
2 files changed, 63 insertions, 4 deletions
diff --git a/gnu/dist/gcc4/gcc/config/m68k/m68k.c b/gnu/dist/gcc4/gcc/config/m68k/m68k.c index 4652b7b8aef..5d05b1cc795 100644 --- a/gnu/dist/gcc4/gcc/config/m68k/m68k.c +++ b/gnu/dist/gcc4/gcc/config/m68k/m68k.c @@ -1791,6 +1791,25 @@ output_move_himode (rtx *operands) } else if (CONSTANT_P (operands[1])) return "move%.l %1,%0"; + /* Recognize the insn before a tablejump, one that refers + to a table of offsets. Such an insn will need to refer + to a label on the insn. So output one. Use the label-number + of the table of offsets to generate this label. This code, + and similar code below, assumes that there will be at most one + reference to each table. */ + if (GET_CODE (operands[1]) == MEM + && GET_CODE (XEXP (operands[1], 0)) == PLUS + && GET_CODE (XEXP (XEXP (operands[1], 0), 1)) == LABEL_REF + && GET_CODE (XEXP (XEXP (operands[1], 0), 0)) != PLUS) + { + rtx labelref = XEXP (XEXP (operands[1], 0), 1); + if (MOTOROLA) + asm_fprintf (asm_out_file, "\t.set %LLI%d,.+2\n", + CODE_LABEL_NUMBER (XEXP (labelref, 0))); + else + (*targetm.asm_out.internal_label) (asm_out_file, "LI", + CODE_LABEL_NUMBER (XEXP (labelref, 0))); + } return "move%.w %1,%0"; } @@ -2699,6 +2718,27 @@ print_operand (FILE *file, rtx op, int letter) assembler syntax for an instruction operand that is a memory reference whose address is ADDR. ADDR is an RTL expression. + Note that this contains a kludge that knows that the only reason + we have an address (plus (label_ref...) (reg...)) when not generating + PIC code is in the insn before a tablejump, and we know that m68k.md + generates a label LInnn: on such an insn. + + It is possible for PIC to generate a (plus (label_ref...) (reg...)) + and we handle that just like we would a (plus (symbol_ref...) (reg...)). + + Some SGS assemblers have a bug such that "Lnnn-LInnn-2.b(pc,d0.l*2)" + fails to assemble. Luckily "Lnnn(pc,d0.l*2)" produces the results + we want. This difference can be accommodated by using an assembler + 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 behavior. + + They also do not like things like "pea 1.w", so we simple leave off + the .w on small constants. + This routine is responsible for distinguishing between -fpic and -fPIC style relocations in an address. When generating -fpic code the offset is output in word mode (e.g. movel a5@(_foo:w), a0). When generating @@ -2706,10 +2746,10 @@ print_operand (FILE *file, rtx op, int letter) #if MOTOROLA # define ASM_OUTPUT_CASE_FETCH(file, labelno, regname)\ - asm_fprintf (file, "%LL%d(%Rpc,%s.", labelno, regname) + asm_fprintf (file, "%LL%d-%LLI%d.b(%Rpc,%s.", labelno, labelno, regname) #else /* !MOTOROLA */ # define ASM_OUTPUT_CASE_FETCH(file, labelno, regname)\ - asm_fprintf (file, "%Rpc@(%LL%d,%s:", labelno, regname) + asm_fprintf (file, "%Rpc@(%LL%d-%LLI%d-2:b,%s:", labelno, labelno, regname) #endif /* !MOTOROLA */ void diff --git a/gnu/dist/gcc4/gcc/config/m68k/m68k.md b/gnu/dist/gcc4/gcc/config/m68k/m68k.md index ae7349fd14d..b69f53132ba 100644 --- a/gnu/dist/gcc4/gcc/config/m68k/m68k.md +++ b/gnu/dist/gcc4/gcc/config/m68k/m68k.md @@ -6356,11 +6356,30 @@ ;; This should not be used unless the add/sub insns can't be. -(define_insn "*lea" +(define_insn "" [(set (match_operand:SI 0 "nonimmediate_operand" "=a") (match_operand:QI 1 "address_operand" "p"))] "" - "lea %a1,%0") +{ + /* Recognize an insn that refers to a table of offsets. Such an insn will + need to refer to a label on the insn. So output one. Use the + label-number of the table of offsets to generate this label. This code, + and similar code above, assumes that there will be at most one reference + to each table. */ + if (GET_CODE (operands[1]) == PLUS + && GET_CODE (XEXP (operands[1], 1)) == LABEL_REF + && GET_CODE (XEXP (operands[1], 0)) != PLUS) + { + rtx labelref = XEXP (operands[1], 1); + if (MOTOROLA) + asm_fprintf (asm_out_file, "\\t.set %LLI%d,.+2\\n", + CODE_LABEL_NUMBER (XEXP (labelref, 0))); + else + (*targetm.asm_out.internal_label) (asm_out_file, "LI", + CODE_LABEL_NUMBER (XEXP (labelref, 0))); + } + return "lea %a1,%0"; +}) ;; This is the first machine-dependent peephole optimization. ;; It is useful when a floating value is returned from a function call |
