summaryrefslogtreecommitdiff
path: root/gnu
diff options
context:
space:
mode:
authorMiod Vallat <miod@cvs.openbsd.org>2013-01-30 18:29:20 +0000
committerMiod Vallat <miod@cvs.openbsd.org>2013-01-30 18:29:20 +0000
commita028dd5b9a8c44a608e53998b68ddc8b2a9b1d8f (patch)
treeff73316b3757db46989b9e55644f981784e74e43 /gnu
parent23f673d9adb548e213c94a6a84e811598a603964 (diff)
Revert m88k.md 1.7 and m88k.c 1.27, 1.26 and 1.24 (partially) to restore the
existing behaviour of wrapping big PIC addresses in `unspec's to prevent the cse pass from modifying them. However, instead of building the unspec ourselves in the C code, rely upon explicitely named define_insn() constructs in the .md description. Then, fix the ambiguity this introduces between the locate1 and movsi_high_pic insns by defining symbolic constants as the unspec selector, and using them, instead of 0.
Diffstat (limited to 'gnu')
-rw-r--r--gnu/usr.bin/gcc/gcc/config/m88k/m88k.c25
-rw-r--r--gnu/usr.bin/gcc/gcc/config/m88k/m88k.md35
2 files changed, 43 insertions, 17 deletions
diff --git a/gnu/usr.bin/gcc/gcc/config/m88k/m88k.c b/gnu/usr.bin/gcc/gcc/config/m88k/m88k.c
index 86d664a3a87..4ec5d9e4194 100644
--- a/gnu/usr.bin/gcc/gcc/config/m88k/m88k.c
+++ b/gnu/usr.bin/gcc/gcc/config/m88k/m88k.c
@@ -334,13 +334,12 @@ legitimize_address (pic, orig, reg, scratch)
temp = ((reload_in_progress || reload_completed)
? reg : gen_reg_rtx (Pmode));
- emit_insn (gen_rtx_SET
- (VOIDmode, temp,
- gen_rtx_HIGH (SImode, addr)));
-
- emit_insn (gen_rtx_SET
- (VOIDmode, temp,
- gen_rtx_LO_SUM (SImode, temp, addr)));
+ /* Must put the SYMBOL_REF inside an UNSPEC here so that cse
+ won't get confused into thinking that these two instructions
+ are loading in the true address of the symbol. If in the
+ future a PIC rtx exists, that should be used instead. */
+ emit_insn (gen_movsi_high_pic (temp, addr));
+ emit_insn (gen_movsi_lo_sum_pic (temp, temp, addr));
addr = temp;
}
@@ -2940,6 +2939,11 @@ print_operand (file, x, code)
output_address (x);
else if (xc == MEM)
output_address (XEXP (x, 0));
+ else if (flag_pic && xc == UNSPEC)
+ {
+ output_addr_const (file, XVECEXP (x, 0, 0));
+ fputs ("#got_rel", file);
+ }
else if (xc == CONST_DOUBLE)
output_operand_lossage ("operand is const_double");
else
@@ -2947,7 +2951,7 @@ print_operand (file, x, code)
return;
case 'g': /* append #got_rel as needed */
- if (flag_pic && symbolic_address_p (x))
+ if (flag_pic && (xc == SYMBOL_REF || xc == LABEL_REF))
{
output_addr_const (file, x);
fputs ("#got_rel", file);
@@ -2984,11 +2988,6 @@ print_operand_address (file, addr)
asm_fprintf (file, "%R%s,%Rlo16(",
reg_names[REGNO (XEXP (addr, 0))]);
output_addr_const (file, XEXP (addr, 1));
- if (flag_pic)
- {
- if (symbolic_address_p (XEXP (addr, 1)))
- fputs ("#got_rel", file);
- }
fputc (')', file);
break;
diff --git a/gnu/usr.bin/gcc/gcc/config/m88k/m88k.md b/gnu/usr.bin/gcc/gcc/config/m88k/m88k.md
index 6b971bd9101..40bd2ef192c 100644
--- a/gnu/usr.bin/gcc/gcc/config/m88k/m88k.md
+++ b/gnu/usr.bin/gcc/gcc/config/m88k/m88k.md
@@ -24,6 +24,11 @@
;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
+(define_constants
+ [(UNSPEC_ABDIFF 0)
+ (UNSPEC_GOT_REL 1)
+ ])
+
;; Attribute describing the processor. This attribute must match exactly
;; with the processor_type enumeration in m88k.h.
@@ -1796,8 +1801,8 @@
(define_insn "locate1"
[(set (match_operand:SI 0 "register_operand" "=r")
- (high:SI (unspec:SI [(label_ref (match_operand 1 "" ""))] 0)))]
- ""
+ (high:SI (unspec:SI [(label_ref (match_operand 1 "" ""))] UNSPEC_ABDIFF)))]
+ "flag_pic"
"or.u %0,%#r0,%#hi16(%1#abdiff)")
(define_insn "locate2"
@@ -1805,8 +1810,8 @@
(set (match_operand:SI 0 "register_operand" "=r")
(lo_sum:SI (match_dup 0)
(unspec:SI
- [(label_ref (match_operand 1 "" ""))] 0)))])]
- ""
+ [(label_ref (match_operand 1 "" ""))] UNSPEC_ABDIFF)))])]
+ "flag_pic"
"bsr.n %1\;or %0,%0,%#lo16(%1#abdiff)\\n%1:"
[(set_attr "length" "2")])
@@ -1882,6 +1887,28 @@
""
"or.u %0,%#r0,%#hi16(%g1)")
+;; For PIC, symbol_refs are put inside unspec so that the optimizer won't
+;; confuse them with real addresses.
+
+(define_insn "movsi_lo_sum_pic"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
+ (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] UNSPEC_GOT_REL)))]
+ "flag_pic"
+ "or %0,%1,%#lo16(%g2)"
+ ;; Need to set length for this arith insn because operand2
+ ;; is not an "arith_operand".
+ [(set_attr "length" "1")])
+
+(define_insn "movsi_high_pic"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (high:SI (unspec:SI [(match_operand 1 "" "")] UNSPEC_GOT_REL)))]
+ "flag_pic"
+ "or.u %0,%#r0,%#hi16(%g1)"
+ ;; Need to set length for this arith insn because operand2
+ ;; is not an arith_operand.
+ [(set_attr "length" "1")])
+
;; HImode move instructions
(define_expand "movhi"