Richard Sandiford <rdsandif...@googlemail.com> writes:
> Matthew Fortune <matthew.fort...@imgtec.com> writes:
>> Hi Catherine/Richard,
>>
>> I think there may be some impact on register move costs by introducing
>> this class.
>
> Yeah, I was worried about that too.  I'm going to do some code comparison
> tests for SE and MIPS16 to see what happens.

OK, I compared the .s testsuite output for -O, -O2, -O3, -Os,
"-O -mips16 -mabi=32" and "-Os -mips16 -mabi=32" on mips64-linux-gnu.
I also tried CSiBE with -O2 and "-Os -mips16 -mabi=32".  The code was
identical in all cases so I think we should be OK.

I went ahead and applied the adjusted version of the patch to trunk
as below (because I wanted to add a testcase too).

Adding a new register class is definitely a bit invasive for this stage
of 4.9.  OTOH microMIPS is a new feature and it would be good to have
it working in 4.9.0.  Since the testing suggests that the patch really
doesn't affect non-microMIPS code, I'd like it to go in 4.9 now.
Richard, Jakub, would that be OK?

Thanks,
Richard


gcc/
2014-04-12  Catherine Moore  <c...@codesourcery.com>

        * config/mips/constraints.md: Add new register constraint "kb".
        * config/mips/mips.md (*mov<mode>_internal): Use constraint "kb".
        (*movhi_internal): Likewise.
        (*movqi_internal): Likewise.
        * config/mips/mips.h (M16_STORE_REGS): New register class.
        (REG_CLASS_NAMES): Add M16_STORE_REGS.
        (REG_CLASS_CONTENTS): Likewise.
        * config/mips/mips.c (mips_regno_to_class): Add M16_STORE_REGS.

gcc/testsuite/
        * gcc.target/mips/umips-store16-1.c: New test.

Index: gcc/config/mips/constraints.md
===================================================================
--- gcc/config/mips/constraints.md      2014-04-12 10:36:09.105788710 +0100
+++ gcc/config/mips/constraints.md      2014-04-12 10:38:48.895224932 +0100
@@ -92,6 +92,9 @@ (define_register_constraint "D" "COP3_RE
 ;; but the DSP version allows any accumulator target.
 (define_register_constraint "ka" "ISA_HAS_DSP_MULT ? ACC_REGS : MD_REGS")
 
+(define_register_constraint "kb" "M16_STORE_REGS"
+  "@internal")
+
 (define_constraint "kf"
   "@internal"
   (match_operand 0 "force_to_mem_operand"))
Index: gcc/config/mips/mips.md
===================================================================
--- gcc/config/mips/mips.md     2014-04-12 10:36:09.105788710 +0100
+++ gcc/config/mips/mips.md     2014-04-12 10:38:48.925225200 +0100
@@ -4437,7 +4437,7 @@ (define_expand "mov<mode>"
 
 (define_insn "*mov<mode>_internal"
   [(set (match_operand:IMOVE32 0 "nonimmediate_operand" 
"=d,!u,!u,d,e,!u,!ks,d,ZS,ZT,m,*f,*f,*d,*m,*d,*z,*a,*d,*B*C*D,*B*C*D,*d,*m")
-       (match_operand:IMOVE32 1 "move_operand" 
"d,J,Udb7,Yd,Yf,ZT,ZS,m,!ks,!u,dJ,*d*J,*m,*f,*f,*z,*d,*J*d,*a,*d,*m,*B*C*D,*B*C*D"))]
+       (match_operand:IMOVE32 1 "move_operand" 
"d,J,Udb7,Yd,Yf,ZT,ZS,m,!ks,!kb,dJ,*d*J,*m,*f,*f,*z,*d,*J*d,*a,*d,*m,*B*C*D,*B*C*D"))]
   "!TARGET_MIPS16
    && (register_operand (operands[0], <MODE>mode)
        || reg_or_0_operand (operands[1], <MODE>mode))"
@@ -4578,7 +4578,7 @@ (define_expand "movhi"
 
 (define_insn "*movhi_internal"
   [(set (match_operand:HI 0 "nonimmediate_operand" "=d,!u,d,!u,d,ZU,m,*a,*d")
-       (match_operand:HI 1 "move_operand"         "d,J,I,ZU,m,!u,dJ,*d*J,*a"))]
+       (match_operand:HI 1 "move_operand"         
"d,J,I,ZU,m,!kb,dJ,*d*J,*a"))]
   "!TARGET_MIPS16
    && (register_operand (operands[0], HImode)
        || reg_or_0_operand (operands[1], HImode))"
@@ -4654,7 +4654,7 @@ (define_expand "movqi"
 
 (define_insn "*movqi_internal"
   [(set (match_operand:QI 0 "nonimmediate_operand" "=d,!u,d,!u,d,ZV,m,*a,*d")
-       (match_operand:QI 1 "move_operand"         "d,J,I,ZW,m,!u,dJ,*d*J,*a"))]
+       (match_operand:QI 1 "move_operand"         
"d,J,I,ZW,m,!kb,dJ,*d*J,*a"))]
   "!TARGET_MIPS16
    && (register_operand (operands[0], QImode)
        || reg_or_0_operand (operands[1], QImode))"
Index: gcc/config/mips/mips.h
===================================================================
--- gcc/config/mips/mips.h      2014-04-12 10:36:09.105788710 +0100
+++ gcc/config/mips/mips.h      2014-04-12 10:38:48.924225191 +0100
@@ -1870,6 +1870,7 @@ #define PIC_OFFSET_TABLE_REGNUM \
 enum reg_class
 {
   NO_REGS,                     /* no registers in set */
+  M16_STORE_REGS,              /* microMIPS store registers  */
   M16_REGS,                    /* mips16 directly accessible registers */
   T_REG,                       /* mips16 T register ($24) */
   M16_T_REGS,                  /* mips16 registers plus T register */
@@ -1907,6 +1908,7 @@ #define GENERAL_REGS GR_REGS
 #define REG_CLASS_NAMES                                                        
\
 {                                                                      \
   "NO_REGS",                                                           \
+  "M16_STORE_REGS",                                                    \
   "M16_REGS",                                                          \
   "T_REG",                                                             \
   "M16_T_REGS",                                                                
\
@@ -1947,6 +1949,7 @@ #define REG_CLASS_NAMES                                   
                \
 #define REG_CLASS_CONTENTS                                                     
                        \
 {                                                                              
                        \
   { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },  
/* NO_REGS */           \
+  { 0x000200fc, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },  
/* M16_STORE_REGS */    \
   { 0x000300fc, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },  
/* M16_REGS */          \
   { 0x01000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },  
/* T_REG */             \
   { 0x010300fc, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },  
/* M16_T_REGS */        \
Index: gcc/config/mips/mips.c
===================================================================
--- gcc/config/mips/mips.c      2014-04-12 10:36:09.105788710 +0100
+++ gcc/config/mips/mips.c      2014-04-12 10:38:48.923225182 +0100
@@ -648,14 +648,15 @@ struct target_globals *mips16_globals;
 
 /* Index R is the smallest register class that contains register R.  */
 const enum reg_class mips_regno_to_class[FIRST_PSEUDO_REGISTER] = {
-  LEA_REGS,    LEA_REGS,       M16_REGS,       V1_REG,
-  M16_REGS,    M16_REGS,       M16_REGS,       M16_REGS,
-  LEA_REGS,    LEA_REGS,       LEA_REGS,       LEA_REGS,
-  LEA_REGS,    LEA_REGS,       LEA_REGS,       LEA_REGS,
-  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,        LEA_REGS,        M16_STORE_REGS,  V1_REG,
+  M16_STORE_REGS,  M16_STORE_REGS,  M16_STORE_REGS,  M16_STORE_REGS,
+  LEA_REGS,        LEA_REGS,        LEA_REGS,        LEA_REGS,
+  LEA_REGS,        LEA_REGS,        LEA_REGS,        LEA_REGS,
+  M16_REGS,        M16_STORE_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,
+
   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/testsuite/gcc.target/mips/umips-store16-1.c
===================================================================
--- /dev/null   2014-04-11 11:50:02.034263237 +0100
+++ gcc/testsuite/gcc.target/mips/umips-store16-1.c     2014-04-12 
10:38:48.926225209 +0100
@@ -0,0 +1,30 @@
+/* { dg-options "(-mmicromips)" } */
+/* { dg-do assemble } */
+
+register unsigned int global asm ("$16");
+
+extern void exit (int) __attribute__((noreturn));
+
+MICROMIPS void
+test_sb (unsigned char *ptr, void (*f) (void))
+{
+  ptr[0] = global;
+  f ();
+  exit (0);
+}
+
+MICROMIPS void
+test_sh (unsigned short *ptr, void (*f) (void))
+{
+  ptr[0] = global;
+  f ();
+  exit (0);
+}
+
+MICROMIPS void
+test_sw (unsigned int *ptr, void (*f) (void))
+{
+  ptr[0] = global;
+  f ();
+  exit (0);
+}

Reply via email to