Thanks for looking at this.

Matthew Fortune <matthew.fort...@imgtec.com> writes:
> Hi Richard/Vladimir,
>
> I believe I finally understand one of the issues with LRA and mips16 but
> I can't see how to solve it. Take the following instruction:
>
> (insn 5 18 6 2 (set (reg:SI 4 $4)
>         (plus:SI (reg/f:SI 78 $frame)
>             (const_int 16 [0x10]))) test.c:6 13 {*addsi3_mips16}
>      (nil))
>
> $frame will be eliminated to either $sp or the hard frame pointer, which
> for mips16 is $17. The problem here is that there is no single
> alternative that accepts either $sp or $17 because the supported
> immediate range is different for $sp(ks) and $17(d). The "ks"
> alternative is disregarded (presumably because there is no way to reload
> into $sp if that ended up being necessary) and instead the "d"
> alternative is chosen.

Ah.  That's probably because "ks" is defined as a normal constraint
rather than a register constraint.  Doing it that way worked best with
reload, because reload did the eliminations first and then matched the
result.  The instruction above would already have been converted into
the $sp or $fp form before matching, so "ks" could simply check for
a (reg STACK_POINTER_REGNUM).

LRA instead keeps the original form around but converts the register
during in_class_p:

  if (regno < FIRST_PSEUDO_REGISTER)
    {
      rtx final_reg = reg;
      rtx *final_loc = &final_reg;

      lra_eliminate_reg_if_possible (final_loc);
      return TEST_HARD_REG_BIT (reg_class_contents[cl], REGNO (*final_loc));
    }

But this only gets called when matching against a register class,
so we'd need a register constraint.  Does the patch below help?

Thanks,
Richard


Index: gcc/config/mips/constraints.md
===================================================================
--- gcc/config/mips/constraints.md      2013-05-25 17:00:02.849405240 +0100
+++ gcc/config/mips/constraints.md      2013-10-29 18:57:24.708435641 +0000
@@ -102,12 +102,9 @@ (define_constraint "kf"
   "@internal"
   (match_operand 0 "force_to_mem_operand"))
 
-;; This is a normal rather than a register constraint because we can
-;; never use the stack pointer as a reload register.
-(define_constraint "ks"
-  "@internal"
-  (and (match_code "reg")
-       (match_test "REGNO (op) == STACK_POINTER_REGNUM")))
+(define_register_constraint "ks"
+  "SP_REG"
+  "@internal")
 
 ;; Integer constraints
 
Index: gcc/config/mips/mips.c
===================================================================
--- gcc/config/mips/mips.c      2013-10-27 18:49:14.034309187 +0000
+++ gcc/config/mips/mips.c      2013-10-29 18:56:48.784108194 +0000
@@ -624,7 +624,7 @@ const enum reg_class mips_regno_to_class
   M16_REGS,    M16_REGS,       LEA_REGS,       LEA_REGS,
   LEA_REGS,    LEA_REGS,       LEA_REGS,       LEA_REGS,
   T_REG,       PIC_FN_ADDR_REG, LEA_REGS,      LEA_REGS,
-  LEA_REGS,    LEA_REGS,       LEA_REGS,       LEA_REGS,
+  LEA_REGS,    SP_REG,         LEA_REGS,       LEA_REGS,
   FP_REGS,     FP_REGS,        FP_REGS,        FP_REGS,
   FP_REGS,     FP_REGS,        FP_REGS,        FP_REGS,
   FP_REGS,     FP_REGS,        FP_REGS,        FP_REGS,
Index: gcc/config/mips/mips.h
===================================================================
--- gcc/config/mips/mips.h      2013-10-20 08:17:38.784934317 +0100
+++ gcc/config/mips/mips.h      2013-10-29 18:56:18.861835434 +0000
@@ -1863,6 +1863,7 @@ enum reg_class
   M16_T_REGS,                  /* mips16 registers plus T register */
   PIC_FN_ADDR_REG,             /* SVR4 PIC function address register */
   V1_REG,                      /* Register $v1 ($3) used for TLS access.  */
+  SP_REG,                      /* Register $sp ($29) */
   LEA_REGS,                    /* Every GPR except $25 */
   GR_REGS,                     /* integer registers */
   FP_REGS,                     /* floating point registers */
@@ -1900,6 +1901,7 @@ #define REG_CLASS_NAMES                                   
                \
   "M16_T_REGS",                                                                
\
   "PIC_FN_ADDR_REG",                                                   \
   "V1_REG",                                                            \
+  "SP_REG",                                                            \
   "LEA_REGS",                                                          \
   "GR_REGS",                                                           \
   "FP_REGS",                                                           \
@@ -1940,6 +1942,7 @@ #define REG_CLASS_CONTENTS
   { 0x010300fc, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },  
/* M16_T_REGS */        \
   { 0x02000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },  
/* PIC_FN_ADDR_REG */   \
   { 0x00000008, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },  
/* V1_REG */            \
+  { 0x20000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },  
/* V1_REG */            \
   { 0xfdffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },  
/* LEA_REGS */          \
   { 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },  
/* GR_REGS */           \
   { 0x00000000, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },  
/* FP_REGS */           \

Reply via email to