@@ -9839,6 +9839,10 @@ arc_spill_class (reg_class_t /* orig_class */, enum machine_mode)
98399839 return GENERAL_REGS ;
98409840}
98419841
9842+ /* Return true if OP is an acceptable memory operand for ARCompact
9843+ 16-bit load instructions of MODE. SCALED indicates if address can
9844+ be scaled. CODE_DENSITY indicates ARCv2 code density operations are
9845+ available. */
98429846bool
98439847compact_memory_operand_p (rtx op , enum machine_mode mode , bool code_density , bool scaled )
98449848{
@@ -9847,16 +9851,17 @@ compact_memory_operand_p (rtx op, enum machine_mode mode, bool code_density, boo
98479851
98489852 /* .di instructions have no 16-bit form. */
98499853 if (MEM_VOLATILE_P (op ) && !TARGET_VOLATILE_CACHE_SET )
9850- return 0 ;
9854+ return false ;
98519855
98529856 if (mode == VOIDmode )
98539857 mode = GET_MODE (op );
98549858
98559859 size = GET_MODE_SIZE (mode );
98569860
9857- /* dword operations really put out 2 instructions, so eliminate them. */
9861+ /* dword operations really put out 2 instructions, so eliminate
9862+ them. */
98589863 if (size > UNITS_PER_WORD )
9859- return 0 ;
9864+ return false ;
98609865
98619866 /* Decode the address now. */
98629867 addr = XEXP (op , 0 );
@@ -9866,53 +9871,81 @@ compact_memory_operand_p (rtx op, enum machine_mode mode, bool code_density, boo
98669871 return (REGNO (addr ) >= FIRST_PSEUDO_REGISTER
98679872 || COMPACT_GP_REG_P (REGNO (addr ))
98689873 || (SP_REG_P (REGNO (addr )) && (size != 2 )));
9869- /* Reverting for the moment since ldw_s does not have sp as a valid
9870- parameter. */
9874+ /* Reverting for the moment since ld/st{w,h}_s does not have sp
9875+ as a valid parameter. */
98719876 case PLUS :
98729877 plus0 = XEXP (addr , 0 );
98739878 plus1 = XEXP (addr , 1 );
98749879
9875- if (( GET_CODE (plus0 ) == REG )
9880+ if (REG_P (plus0 ) && REG_P ( plus1 )
98769881 && ((REGNO (plus0 ) >= FIRST_PSEUDO_REGISTER )
98779882 || COMPACT_GP_REG_P (REGNO (plus0 )))
9878- && ((GET_CODE (plus1 ) == REG )
9879- && ((REGNO (plus1 ) >= FIRST_PSEUDO_REGISTER )
9880- || COMPACT_GP_REG_P (REGNO (plus1 )))))
9883+ && ((REGNO (plus1 ) >= FIRST_PSEUDO_REGISTER )
9884+ || COMPACT_GP_REG_P (REGNO (plus1 ))))
98819885 {
98829886 return !code_density ;
98839887 }
98849888
9885- if ((GET_CODE (plus0 ) == REG )
9886- && ((REGNO (plus0 ) >= FIRST_PSEUDO_REGISTER )
9887- || (COMPACT_GP_REG_P (REGNO (plus0 )) && !code_density )
9888- || (REGNO (plus0 ) <= 31 && code_density ))
9889- && (GET_CODE (plus1 ) == CONST_INT ))
9889+ if (REG_P (plus0 ) && CONST_INT_P (plus1 ))
98909890 {
9891+ bool valid = false;
9892+
98919893 off = INTVAL (plus1 );
98929894
9893- /* Negative offset is not supported in 16-bit load/store insns. */
9895+ /* Negative offset is not supported in 16-bit load/store
9896+ insns. */
98949897 if (off < 0 )
9895- return 0 ;
9898+ return false;
9899+
9900+ if (REGNO (plus0 ) >= FIRST_PSEUDO_REGISTER )
9901+ valid = true;
98969902
9897- /* Only u5 immediates allowed in code density instructions. */
98989903 if (code_density )
9899- return ((size == 4 ) && (off < 32 ) && (off % 4 == 0 ));
9904+ {
9905+ switch (size )
9906+ {
9907+ case 1 :
9908+ return false;
9909+ case 2 :
9910+ /* This is an ldh_s.x instruction, check the u6
9911+ immediate. */
9912+ if (COMPACT_GP_REG_P (REGNO (plus0 )))
9913+ valid = true;
9914+ break ;
9915+ case 4 :
9916+ /* u5 immediates allowed in 32bit access code
9917+ density instructions. */
9918+ if (REGNO (plus0 ) <= 31 )
9919+ valid = true;
9920+ break ;
9921+ default :
9922+ return false;
9923+ }
9924+ }
9925+ else
9926+ if (COMPACT_GP_REG_P (REGNO (plus0 )))
9927+ valid = true;
99009928
9901- switch ( size )
9929+ if ( valid )
99029930 {
9903- case 1 :
9904- return (off < 32 );
9905- case 2 :
9906- return ((off < 64 ) && (off % 2 == 0 ));
9907- case 4 :
9908- return ((off < 128 ) && (off % 4 == 0 ));
9931+
9932+ switch (size )
9933+ {
9934+ case 1 :
9935+ return (off < 32 );
9936+ case 2 :
9937+ return ((off < 64 ) && (off % 2 == 0 ));
9938+ case 4 :
9939+ return ((off < 128 ) && (off % 4 == 0 ));
9940+ default :
9941+ return false;
9942+ }
99099943 }
99109944 }
99119945
9912- if (( GET_CODE (plus0 ) == REG )
9946+ if (REG_P (plus0 ) && CONST_INT_P ( plus1 )
99139947 && ((REGNO (plus0 ) >= FIRST_PSEUDO_REGISTER )
99149948 || SP_REG_P (REGNO (plus0 )))
9915- && (GET_CODE (plus1 ) == CONST_INT )
99169949 && !code_density )
99179950 {
99189951 off = INTVAL (plus1 );
@@ -9932,7 +9965,7 @@ compact_memory_operand_p (rtx op, enum machine_mode mode, bool code_density, boo
99329965 /* TODO: 'gp' and 'pcl' are to supported as base address operand
99339966 for 16-bit load instructions. */
99349967 }
9935- return 0 ;
9968+ return false ;
99369969}
99379970
99389971bool
0 commit comments