@@ -5425,3 +5425,69 @@ bool AArch64TargetLowering::isZExtFree(SDValue Val, EVT VT2) const {
5425
5425
return (VT1.isSimple () && VT1.isInteger () && VT2.isSimple () &&
5426
5426
VT2.isInteger () && VT1.getSizeInBits () <= 32 );
5427
5427
}
5428
+
5429
+ // isLegalAddressingMode - Return true if the addressing mode represented
5430
+ // / by AM is legal for this target, for a load/store of the specified type.
5431
+ bool AArch64TargetLowering::isLegalAddressingMode (const AddrMode &AM,
5432
+ Type *Ty) const {
5433
+ // AArch64 has five basic addressing modes:
5434
+ // reg
5435
+ // reg + 9-bit signed offset
5436
+ // reg + SIZE_IN_BYTES * 12-bit unsigned offset
5437
+ // reg1 + reg2
5438
+ // reg + SIZE_IN_BYTES * reg
5439
+
5440
+ // No global is ever allowed as a base.
5441
+ if (AM.BaseGV )
5442
+ return false ;
5443
+
5444
+ // No reg+reg+imm addressing.
5445
+ if (AM.HasBaseReg && AM.BaseOffs && AM.Scale )
5446
+ return false ;
5447
+
5448
+ // check reg + imm case:
5449
+ // i.e., reg + 0, reg + imm9, reg + SIZE_IN_BYTES * uimm12
5450
+ uint64_t NumBytes = 0 ;
5451
+ if (Ty->isSized ()) {
5452
+ uint64_t NumBits = getDataLayout ()->getTypeSizeInBits (Ty);
5453
+ NumBytes = NumBits / 8 ;
5454
+ if (!isPowerOf2_64 (NumBits))
5455
+ NumBytes = 0 ;
5456
+ }
5457
+
5458
+ if (!AM.Scale ) {
5459
+ int64_t Offset = AM.BaseOffs ;
5460
+
5461
+ // 9-bit signed offset
5462
+ if (Offset >= -(1LL << 9 ) && Offset <= (1LL << 9 ) - 1 )
5463
+ return true ;
5464
+
5465
+ // 12-bit unsigned offset
5466
+ unsigned shift = Log2_64 (NumBytes);
5467
+ if (NumBytes && Offset > 0 && (Offset / NumBytes) <= (1LL << 12 ) - 1 &&
5468
+ // Must be a multiple of NumBytes (NumBytes is a power of 2)
5469
+ (Offset >> shift) << shift == Offset)
5470
+ return true ;
5471
+ return false ;
5472
+ }
5473
+ if (!AM.Scale || AM.Scale == 1 ||
5474
+ (AM.Scale > 0 && (uint64_t )AM.Scale == NumBytes))
5475
+ return true ;
5476
+ return false ;
5477
+ }
5478
+
5479
+ int AArch64TargetLowering::getScalingFactorCost (const AddrMode &AM,
5480
+ Type *Ty) const {
5481
+ // Scaling factors are not free at all.
5482
+ // Operands | Rt Latency
5483
+ // -------------------------------------------
5484
+ // Rt, [Xn, Xm] | 4
5485
+ // -------------------------------------------
5486
+ // Rt, [Xn, Xm, lsl #imm] | Rn: 4 Rm: 5
5487
+ // Rt, [Xn, Wm, <extend> #imm] |
5488
+ if (isLegalAddressingMode (AM, Ty))
5489
+ // Scale represents reg2 * scale, thus account for 1 if
5490
+ // it is not equal to 0 or 1.
5491
+ return AM.Scale != 0 && AM.Scale != 1 ;
5492
+ return -1 ;
5493
+ }
0 commit comments