@@ -3487,6 +3487,229 @@ MachineInstr *AArch64InstrInfo::emitLdStWithAddr(MachineInstr &MemI,
34873487 " Function must not be called with an addressing mode it can't handle" );
34883488}
34893489
3490+ // / Return true if the opcode is a post-index ld/st instruction, which really
3491+ // / loads from base+0.
3492+ static bool isPostIndexLdStOpcode (unsigned Opcode) {
3493+ switch (Opcode) {
3494+ default :
3495+ return false ;
3496+ case AArch64::LD1Fourv16b_POST:
3497+ case AArch64::LD1Fourv1d_POST:
3498+ case AArch64::LD1Fourv2d_POST:
3499+ case AArch64::LD1Fourv2s_POST:
3500+ case AArch64::LD1Fourv4h_POST:
3501+ case AArch64::LD1Fourv4s_POST:
3502+ case AArch64::LD1Fourv8b_POST:
3503+ case AArch64::LD1Fourv8h_POST:
3504+ case AArch64::LD1Onev16b_POST:
3505+ case AArch64::LD1Onev1d_POST:
3506+ case AArch64::LD1Onev2d_POST:
3507+ case AArch64::LD1Onev2s_POST:
3508+ case AArch64::LD1Onev4h_POST:
3509+ case AArch64::LD1Onev4s_POST:
3510+ case AArch64::LD1Onev8b_POST:
3511+ case AArch64::LD1Onev8h_POST:
3512+ case AArch64::LD1Rv16b_POST:
3513+ case AArch64::LD1Rv1d_POST:
3514+ case AArch64::LD1Rv2d_POST:
3515+ case AArch64::LD1Rv2s_POST:
3516+ case AArch64::LD1Rv4h_POST:
3517+ case AArch64::LD1Rv4s_POST:
3518+ case AArch64::LD1Rv8b_POST:
3519+ case AArch64::LD1Rv8h_POST:
3520+ case AArch64::LD1Threev16b_POST:
3521+ case AArch64::LD1Threev1d_POST:
3522+ case AArch64::LD1Threev2d_POST:
3523+ case AArch64::LD1Threev2s_POST:
3524+ case AArch64::LD1Threev4h_POST:
3525+ case AArch64::LD1Threev4s_POST:
3526+ case AArch64::LD1Threev8b_POST:
3527+ case AArch64::LD1Threev8h_POST:
3528+ case AArch64::LD1Twov16b_POST:
3529+ case AArch64::LD1Twov1d_POST:
3530+ case AArch64::LD1Twov2d_POST:
3531+ case AArch64::LD1Twov2s_POST:
3532+ case AArch64::LD1Twov4h_POST:
3533+ case AArch64::LD1Twov4s_POST:
3534+ case AArch64::LD1Twov8b_POST:
3535+ case AArch64::LD1Twov8h_POST:
3536+ case AArch64::LD1i16_POST:
3537+ case AArch64::LD1i32_POST:
3538+ case AArch64::LD1i64_POST:
3539+ case AArch64::LD1i8_POST:
3540+ case AArch64::LD2Rv16b_POST:
3541+ case AArch64::LD2Rv1d_POST:
3542+ case AArch64::LD2Rv2d_POST:
3543+ case AArch64::LD2Rv2s_POST:
3544+ case AArch64::LD2Rv4h_POST:
3545+ case AArch64::LD2Rv4s_POST:
3546+ case AArch64::LD2Rv8b_POST:
3547+ case AArch64::LD2Rv8h_POST:
3548+ case AArch64::LD2Twov16b_POST:
3549+ case AArch64::LD2Twov2d_POST:
3550+ case AArch64::LD2Twov2s_POST:
3551+ case AArch64::LD2Twov4h_POST:
3552+ case AArch64::LD2Twov4s_POST:
3553+ case AArch64::LD2Twov8b_POST:
3554+ case AArch64::LD2Twov8h_POST:
3555+ case AArch64::LD2i16_POST:
3556+ case AArch64::LD2i32_POST:
3557+ case AArch64::LD2i64_POST:
3558+ case AArch64::LD2i8_POST:
3559+ case AArch64::LD3Rv16b_POST:
3560+ case AArch64::LD3Rv1d_POST:
3561+ case AArch64::LD3Rv2d_POST:
3562+ case AArch64::LD3Rv2s_POST:
3563+ case AArch64::LD3Rv4h_POST:
3564+ case AArch64::LD3Rv4s_POST:
3565+ case AArch64::LD3Rv8b_POST:
3566+ case AArch64::LD3Rv8h_POST:
3567+ case AArch64::LD3Threev16b_POST:
3568+ case AArch64::LD3Threev2d_POST:
3569+ case AArch64::LD3Threev2s_POST:
3570+ case AArch64::LD3Threev4h_POST:
3571+ case AArch64::LD3Threev4s_POST:
3572+ case AArch64::LD3Threev8b_POST:
3573+ case AArch64::LD3Threev8h_POST:
3574+ case AArch64::LD3i16_POST:
3575+ case AArch64::LD3i32_POST:
3576+ case AArch64::LD3i64_POST:
3577+ case AArch64::LD3i8_POST:
3578+ case AArch64::LD4Fourv16b_POST:
3579+ case AArch64::LD4Fourv2d_POST:
3580+ case AArch64::LD4Fourv2s_POST:
3581+ case AArch64::LD4Fourv4h_POST:
3582+ case AArch64::LD4Fourv4s_POST:
3583+ case AArch64::LD4Fourv8b_POST:
3584+ case AArch64::LD4Fourv8h_POST:
3585+ case AArch64::LD4Rv16b_POST:
3586+ case AArch64::LD4Rv1d_POST:
3587+ case AArch64::LD4Rv2d_POST:
3588+ case AArch64::LD4Rv2s_POST:
3589+ case AArch64::LD4Rv4h_POST:
3590+ case AArch64::LD4Rv4s_POST:
3591+ case AArch64::LD4Rv8b_POST:
3592+ case AArch64::LD4Rv8h_POST:
3593+ case AArch64::LD4i16_POST:
3594+ case AArch64::LD4i32_POST:
3595+ case AArch64::LD4i64_POST:
3596+ case AArch64::LD4i8_POST:
3597+ case AArch64::LDAPRWpost:
3598+ case AArch64::LDAPRXpost:
3599+ case AArch64::LDIAPPWpost:
3600+ case AArch64::LDIAPPXpost:
3601+ case AArch64::LDPDpost:
3602+ case AArch64::LDPQpost:
3603+ case AArch64::LDPSWpost:
3604+ case AArch64::LDPSpost:
3605+ case AArch64::LDPWpost:
3606+ case AArch64::LDPXpost:
3607+ case AArch64::LDRBBpost:
3608+ case AArch64::LDRBpost:
3609+ case AArch64::LDRDpost:
3610+ case AArch64::LDRHHpost:
3611+ case AArch64::LDRHpost:
3612+ case AArch64::LDRQpost:
3613+ case AArch64::LDRSBWpost:
3614+ case AArch64::LDRSBXpost:
3615+ case AArch64::LDRSHWpost:
3616+ case AArch64::LDRSHXpost:
3617+ case AArch64::LDRSWpost:
3618+ case AArch64::LDRSpost:
3619+ case AArch64::LDRWpost:
3620+ case AArch64::LDRXpost:
3621+ case AArch64::ST1Fourv16b_POST:
3622+ case AArch64::ST1Fourv1d_POST:
3623+ case AArch64::ST1Fourv2d_POST:
3624+ case AArch64::ST1Fourv2s_POST:
3625+ case AArch64::ST1Fourv4h_POST:
3626+ case AArch64::ST1Fourv4s_POST:
3627+ case AArch64::ST1Fourv8b_POST:
3628+ case AArch64::ST1Fourv8h_POST:
3629+ case AArch64::ST1Onev16b_POST:
3630+ case AArch64::ST1Onev1d_POST:
3631+ case AArch64::ST1Onev2d_POST:
3632+ case AArch64::ST1Onev2s_POST:
3633+ case AArch64::ST1Onev4h_POST:
3634+ case AArch64::ST1Onev4s_POST:
3635+ case AArch64::ST1Onev8b_POST:
3636+ case AArch64::ST1Onev8h_POST:
3637+ case AArch64::ST1Threev16b_POST:
3638+ case AArch64::ST1Threev1d_POST:
3639+ case AArch64::ST1Threev2d_POST:
3640+ case AArch64::ST1Threev2s_POST:
3641+ case AArch64::ST1Threev4h_POST:
3642+ case AArch64::ST1Threev4s_POST:
3643+ case AArch64::ST1Threev8b_POST:
3644+ case AArch64::ST1Threev8h_POST:
3645+ case AArch64::ST1Twov16b_POST:
3646+ case AArch64::ST1Twov1d_POST:
3647+ case AArch64::ST1Twov2d_POST:
3648+ case AArch64::ST1Twov2s_POST:
3649+ case AArch64::ST1Twov4h_POST:
3650+ case AArch64::ST1Twov4s_POST:
3651+ case AArch64::ST1Twov8b_POST:
3652+ case AArch64::ST1Twov8h_POST:
3653+ case AArch64::ST1i16_POST:
3654+ case AArch64::ST1i32_POST:
3655+ case AArch64::ST1i64_POST:
3656+ case AArch64::ST1i8_POST:
3657+ case AArch64::ST2GPostIndex:
3658+ case AArch64::ST2Twov16b_POST:
3659+ case AArch64::ST2Twov2d_POST:
3660+ case AArch64::ST2Twov2s_POST:
3661+ case AArch64::ST2Twov4h_POST:
3662+ case AArch64::ST2Twov4s_POST:
3663+ case AArch64::ST2Twov8b_POST:
3664+ case AArch64::ST2Twov8h_POST:
3665+ case AArch64::ST2i16_POST:
3666+ case AArch64::ST2i32_POST:
3667+ case AArch64::ST2i64_POST:
3668+ case AArch64::ST2i8_POST:
3669+ case AArch64::ST3Threev16b_POST:
3670+ case AArch64::ST3Threev2d_POST:
3671+ case AArch64::ST3Threev2s_POST:
3672+ case AArch64::ST3Threev4h_POST:
3673+ case AArch64::ST3Threev4s_POST:
3674+ case AArch64::ST3Threev8b_POST:
3675+ case AArch64::ST3Threev8h_POST:
3676+ case AArch64::ST3i16_POST:
3677+ case AArch64::ST3i32_POST:
3678+ case AArch64::ST3i64_POST:
3679+ case AArch64::ST3i8_POST:
3680+ case AArch64::ST4Fourv16b_POST:
3681+ case AArch64::ST4Fourv2d_POST:
3682+ case AArch64::ST4Fourv2s_POST:
3683+ case AArch64::ST4Fourv4h_POST:
3684+ case AArch64::ST4Fourv4s_POST:
3685+ case AArch64::ST4Fourv8b_POST:
3686+ case AArch64::ST4Fourv8h_POST:
3687+ case AArch64::ST4i16_POST:
3688+ case AArch64::ST4i32_POST:
3689+ case AArch64::ST4i64_POST:
3690+ case AArch64::ST4i8_POST:
3691+ case AArch64::STGPostIndex:
3692+ case AArch64::STGPpost:
3693+ case AArch64::STPDpost:
3694+ case AArch64::STPQpost:
3695+ case AArch64::STPSpost:
3696+ case AArch64::STPWpost:
3697+ case AArch64::STPXpost:
3698+ case AArch64::STRBBpost:
3699+ case AArch64::STRBpost:
3700+ case AArch64::STRDpost:
3701+ case AArch64::STRHHpost:
3702+ case AArch64::STRHpost:
3703+ case AArch64::STRQpost:
3704+ case AArch64::STRSpost:
3705+ case AArch64::STRWpost:
3706+ case AArch64::STRXpost:
3707+ case AArch64::STZ2GPostIndex:
3708+ case AArch64::STZGPostIndex:
3709+ return true ;
3710+ }
3711+ }
3712+
34903713bool AArch64InstrInfo::getMemOperandWithOffsetWidth (
34913714 const MachineInstr &LdSt, const MachineOperand *&BaseOp, int64_t &Offset,
34923715 bool &OffsetIsScalable, TypeSize &Width,
@@ -3518,8 +3741,11 @@ bool AArch64InstrInfo::getMemOperandWithOffsetWidth(
35183741
35193742 // Compute the offset. Offset is calculated as the immediate operand
35203743 // multiplied by the scaling factor. Unscaled instructions have scaling factor
3521- // set to 1.
3522- if (LdSt.getNumExplicitOperands () == 3 ) {
3744+ // set to 1. Postindex are a special case which have an offset of 0.
3745+ if (isPostIndexLdStOpcode (LdSt.getOpcode ())) {
3746+ BaseOp = &LdSt.getOperand (2 );
3747+ Offset = 0 ;
3748+ } else if (LdSt.getNumExplicitOperands () == 3 ) {
35233749 BaseOp = &LdSt.getOperand (1 );
35243750 Offset = LdSt.getOperand (2 ).getImm () * Scale.getKnownMinValue ();
35253751 } else {
@@ -3529,10 +3755,7 @@ bool AArch64InstrInfo::getMemOperandWithOffsetWidth(
35293755 }
35303756 OffsetIsScalable = Scale.isScalable ();
35313757
3532- if (!BaseOp->isReg () && !BaseOp->isFI ())
3533- return false ;
3534-
3535- return true ;
3758+ return BaseOp->isReg () || BaseOp->isFI ();
35363759}
35373760
35383761MachineOperand &
@@ -3622,8 +3845,8 @@ bool AArch64InstrInfo::getMemOpInfo(unsigned Opcode, TypeSize &Scale,
36223845 break ;
36233846 case AArch64::STRWpost:
36243847 case AArch64::LDRWpost:
3625- Scale = TypeSize::getFixed (4 );
3626- Width = TypeSize::getFixed (32 );
3848+ Scale = TypeSize::getFixed (1 );
3849+ Width = TypeSize::getFixed (4 );
36273850 MinOffset = -256 ;
36283851 MaxOffset = 255 ;
36293852 break ;
@@ -3690,13 +3913,15 @@ bool AArch64InstrInfo::getMemOpInfo(unsigned Opcode, TypeSize &Scale,
36903913 MinOffset = -256 ;
36913914 MaxOffset = 255 ;
36923915 break ;
3693- // LDP / STP
3916+ // LDP / STP (including pre/post inc)
36943917 case AArch64::LDPQi:
36953918 case AArch64::LDNPQi:
36963919 case AArch64::STPQi:
36973920 case AArch64::STNPQi:
3921+ case AArch64::STPQpre:
3922+ case AArch64::LDPQpost:
36983923 Scale = TypeSize::getFixed (16 );
3699- Width = TypeSize::getFixed (32 );
3924+ Width = TypeSize::getFixed (16 * 2 );
37003925 MinOffset = -64 ;
37013926 MaxOffset = 63 ;
37023927 break ;
@@ -3708,8 +3933,12 @@ bool AArch64InstrInfo::getMemOpInfo(unsigned Opcode, TypeSize &Scale,
37083933 case AArch64::STPDi:
37093934 case AArch64::STNPXi:
37103935 case AArch64::STNPDi:
3936+ case AArch64::STPXpre:
3937+ case AArch64::LDPXpost:
3938+ case AArch64::STPDpre:
3939+ case AArch64::LDPDpost:
37113940 Scale = TypeSize::getFixed (8 );
3712- Width = TypeSize::getFixed (16 );
3941+ Width = TypeSize::getFixed (8 * 2 );
37133942 MinOffset = -64 ;
37143943 MaxOffset = 63 ;
37153944 break ;
@@ -3722,27 +3951,10 @@ bool AArch64InstrInfo::getMemOpInfo(unsigned Opcode, TypeSize &Scale,
37223951 case AArch64::STNPWi:
37233952 case AArch64::STNPSi:
37243953 Scale = TypeSize::getFixed (4 );
3725- Width = TypeSize::getFixed (8 );
3954+ Width = TypeSize::getFixed (4 * 2 );
37263955 MinOffset = -64 ;
37273956 MaxOffset = 63 ;
37283957 break ;
3729- // pre/post inc
3730- case AArch64::STPQpre:
3731- case AArch64::LDPQpost:
3732- Scale = TypeSize::getFixed (16 );
3733- Width = TypeSize::getFixed (16 );
3734- MinOffset = -1024 ;
3735- MaxOffset = 1008 ;
3736- break ;
3737- case AArch64::STPXpre:
3738- case AArch64::LDPXpost:
3739- case AArch64::STPDpre:
3740- case AArch64::LDPDpost:
3741- Scale = TypeSize::getFixed (8 );
3742- Width = TypeSize::getFixed (8 );
3743- MinOffset = -512 ;
3744- MaxOffset = 504 ;
3745- break ;
37463958 case AArch64::StoreSwiftAsyncContext:
37473959 // Store is an STRXui, but there might be an ADDXri in the expansion too.
37483960 Scale = TypeSize::getFixed (1 );
0 commit comments