summaryrefslogtreecommitdiff
path: root/gnu
diff options
context:
space:
mode:
authorphx <phx@NetBSD.org>2008-11-13 18:10:56 +0000
committerphx <phx@NetBSD.org>2008-11-13 18:10:56 +0000
commit8fea32b8abc0d18dff4cf8dd8d3fb9987d3d412c (patch)
tree0491694b1cfff99ab733b80b7b89c97e1fea51f7 /gnu
parentd5e5a2c9ebe59d9193a55c4412d1a799f7538ac7 (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.c44
-rw-r--r--gnu/dist/gcc4/gcc/config/m68k/m68k.md23
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