This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [sh PATCH] PR/27717, sh backend lies to reload about index registers



Whether sh really needs that is beyond my understanding. The more I read the patch, the more I hope it doesn't. For example, another way to achieve the same would be to emit the memory access as an UNSPEC.

As in this patch. I am curious whether anybody thinks it's too much of a hack (compared to INDEX_REG_CLASS_FOR_MODE).


It fixes PR27117, and produces correct code by inspection and comparison with sh.md's example:

        movi    (((datalabel ___div_table) >> 16) & 65535), r3
        shori   ((datalabel ___div_table) & 65535), r3
	...
        shari   r1, 58, r6
        ldx.ub  r3, r6, r7		;; divsi_inv_qitable
        shari   r1, 32, r5
        shlli   r6, 1, r6
        muls.l  r5, r7, r7
        ldx.w   r3, r6, r6		;; divsi_inv_hitable
	...

I haven't run a simulator test on it, though.

Paolo
2006-08-19  Paolo Bonzini  <bonzini@gnu.org>

	PR target/27117
	* config/sh/sh.md (divsi_inv_qitable, divsi_inv_hitable): New patterns.
	(divsi_inv_m1): Use them.
	(UNSPEC_DIV_INV_TABLE): New constant.

Index: sh.md
===================================================================
--- sh.md	(revision 116179)
+++ sh.md	(working copy)
@@ -148,6 +148,7 @@
   (UNSPEC_DIV_INV_M2	32)
   (UNSPEC_DIV_INV_M3	33)
   (UNSPEC_DIV_INV20	34)
+  (UNSPEC_DIV_INV_TABLE	37)
   (UNSPEC_ASHIFTRT	35)
   (UNSPEC_THUNK		36)
   (UNSPEC_SP_SET	40)
@@ -2244,6 +2245,30 @@
   DONE;
 }")
 
+;; operands: scratch, tab_base, tab_ix
+(define_insn "divsi_inv_qitable"
+  [(set (match_operand:DI 0 "register_operand" "=r")
+	(zero_extend:DI (unspec:QI [(match_operand:DI 1 "register_operand" "r")
+				    (match_operand:DI 2 "register_operand" "r")]
+			 UNSPEC_DIV_INV_TABLE)))]
+  "TARGET_SHMEDIA"
+  "@
+	ldx.ub	%1, %2, %0"
+  [(set_attr "type" "load_media")
+   (set_attr "highpart" "user")])
+
+;; operands: scratch, tab_base, tab_ix
+(define_insn "divsi_inv_hitable"
+  [(set (match_operand:DI 0 "register_operand" "=r")
+	(sign_extend:DI (unspec:HI [(match_operand:DI 1 "register_operand" "r")
+				    (match_operand:DI 2 "register_operand" "r")]
+			 UNSPEC_DIV_INV_TABLE)))]
+  "TARGET_SHMEDIA"
+  "@
+	ldx.w	%1, %2, %0"
+  [(set_attr "type" "load_media")
+   (set_attr "highpart" "user")])
+
 ;; operands: inv0, tab_base, tab_ix, norm32
 ;; scratch equiv in sdivsi3_2: r19, r21
 (define_expand "divsi_inv_m0"
@@ -2278,12 +2303,10 @@ norm32: r25
   rtx scratch1 = operands[5];
   rtx mem;
 
-  mem = gen_const_mem (QImode, gen_rtx_PLUS (DImode, tab_base, tab_ix));
-  emit_insn (gen_zero_extendqidi2 (scratch0, mem));
+  emit_insn (gen_divsi_inv_qitable (scratch0, tab_base, tab_ix));
   emit_insn (gen_ashldi3_media (scratch1, tab_ix, GEN_INT (1)));
   emit_insn (gen_mulsidi3_media (scratch0, norm32, scratch0_si));
-  mem = gen_const_mem (HImode, gen_rtx_PLUS (DImode, tab_base, scratch1));
-  emit_insn (gen_extendhidi2 (scratch1, mem));
+  emit_insn (gen_divsi_inv_hitable (scratch1, tab_base, scratch1));
   emit_insn (gen_ashrdi3_media (scratch0, scratch0, GEN_INT (24)));
   emit_insn (gen_subdisi3_media (inv0, scratch1, scratch0));
   DONE;

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]