diff options
author | Miod Vallat <miod@cvs.openbsd.org> | 2013-01-30 18:29:20 +0000 |
---|---|---|
committer | Miod Vallat <miod@cvs.openbsd.org> | 2013-01-30 18:29:20 +0000 |
commit | a028dd5b9a8c44a608e53998b68ddc8b2a9b1d8f (patch) | |
tree | ff73316b3757db46989b9e55644f981784e74e43 /gnu | |
parent | 23f673d9adb548e213c94a6a84e811598a603964 (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.c | 25 | ||||
-rw-r--r-- | gnu/usr.bin/gcc/gcc/config/m88k/m88k.md | 35 |
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" |