Changeset View
Changeset View
Standalone View
Standalone View
llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp
Show First 20 Lines • Show All 5,930 Lines • ▼ Show 20 Lines | bool ARMBaseInstrInfo::checkAndUpdateStackOffset(MachineInstr *MI, | ||||
// Stack might be involved but addressing mode doesn't handle any offset. | // Stack might be involved but addressing mode doesn't handle any offset. | ||||
// Rq: AddrModeT1_[1|2|4] don't operate on SP | // Rq: AddrModeT1_[1|2|4] don't operate on SP | ||||
if (AddrMode == ARMII::AddrMode1 // Arithmetic instructions | if (AddrMode == ARMII::AddrMode1 // Arithmetic instructions | ||||
|| AddrMode == ARMII::AddrMode4 // Load/Store Multiple | || AddrMode == ARMII::AddrMode4 // Load/Store Multiple | ||||
|| AddrMode == ARMII::AddrMode6 // Neon Load/Store Multiple | || AddrMode == ARMII::AddrMode6 // Neon Load/Store Multiple | ||||
|| AddrMode == ARMII::AddrModeT2_so // SP can't be used as based register | || AddrMode == ARMII::AddrModeT2_so // SP can't be used as based register | ||||
|| AddrMode == ARMII::AddrModeT2_pc // PCrel access | || AddrMode == ARMII::AddrModeT2_pc // PCrel access | ||||
|| AddrMode == ARMII::AddrMode2 // Used by PRE and POST indexed LD/ST | || AddrMode == ARMII::AddrMode2 // Used by PRE and POST indexed LD/ST | ||||
|| AddrMode == ARMII::AddrModeT2_i7 // v8.1-M MVE | |||||
|| AddrMode == ARMII::AddrModeT2_i7s2 // v8.1-M MVE | |||||
|| AddrMode == ARMII::AddrModeT2_i7s4 // v8.1-M sys regs VLDR/VSTR | |||||
|| AddrMode == ARMII::AddrModeNone) | || AddrMode == ARMII::AddrModeNone) | ||||
return false; | return false; | ||||
unsigned NumOps = MI->getDesc().getNumOperands(); | unsigned NumOps = MI->getDesc().getNumOperands(); | ||||
unsigned ImmIdx = NumOps - 3; | unsigned ImmIdx = NumOps - 3; | ||||
const MachineOperand &Offset = MI->getOperand(ImmIdx); | const MachineOperand &Offset = MI->getOperand(ImmIdx); | ||||
assert(Offset.isImm() && "Is not an immediate"); | assert(Offset.isImm() && "Is not an immediate"); | ||||
Show All 26 Lines | case ARMII::AddrMode5FP16: | ||||
OffVal = ARM_AM::getAM5FP16Offset(OffVal); | OffVal = ARM_AM::getAM5FP16Offset(OffVal); | ||||
NumBits = 8; | NumBits = 8; | ||||
Scale = 2; | Scale = 2; | ||||
break; | break; | ||||
case ARMII::AddrModeT2_i8: | case ARMII::AddrModeT2_i8: | ||||
NumBits = 8; | NumBits = 8; | ||||
break; | break; | ||||
case ARMII::AddrModeT2_i8s4: | case ARMII::AddrModeT2_i8s4: | ||||
// FIXME: Values are already scaled in this addressing mode. | |||||
assert((Fixup & 3) == 0 && "Can't encode this offset!"); | |||||
NumBits = 10; | |||||
break; | |||||
efriedma: Maybe assert "Fixup" is a multiple of 4? | |||||
Not Done ReplyInline Actionsok, and I'll change the check line 6005 into an assert yroux: ok, and I'll change the check line 6005 into an assert | |||||
case ARMII::AddrModeT2_ldrex: | case ARMII::AddrModeT2_ldrex: | ||||
NumBits = 8; | NumBits = 8; | ||||
Scale = 4; | Scale = 4; | ||||
break; | break; | ||||
case ARMII::AddrModeT2_i12: | case ARMII::AddrModeT2_i12: | ||||
case ARMII::AddrMode_i12: | case ARMII::AddrMode_i12: | ||||
NumBits = 12; | NumBits = 12; | ||||
break; | break; | ||||
case ARMII::AddrModeT2_i7: | |||||
NumBits = 7; | |||||
break; | |||||
case ARMII::AddrModeT2_i7s2: | |||||
NumBits = 7; | |||||
Scale = 2; | |||||
break; | |||||
case ARMII::AddrModeT2_i7s4: | |||||
NumBits = 7; | |||||
Scale = 4; | |||||
break; | |||||
case ARMII::AddrModeT1_s: // SP-relative LD/ST | case ARMII::AddrModeT1_s: // SP-relative LD/ST | ||||
NumBits = 8; | NumBits = 8; | ||||
Scale = 4; | Scale = 4; | ||||
break; | break; | ||||
default: | default: | ||||
llvm_unreachable("Unsupported addressing mode!"); | llvm_unreachable("Unsupported addressing mode!"); | ||||
Not Done ReplyInline ActionsCan't we instead return false; here and get rid of enumerating all unsupported addressing modes on line 5933? chill: Can't we instead `return false;` here and get rid of enumerating all unsupported addressing… | |||||
Not Done ReplyInline Actionshmm, yes I agree it'll make it easier to read yroux: hmm, yes I agree it'll make it easier to read | |||||
Not Done ReplyInline ActionsThe issue is that getting the offset value line 5948 can only be done if the addressing mode has one, so we can't get rid of the checking line 5933. I already planned to rework this part and extract it since that kind of logic is used in multiple places in the backend, but what about keeping it as it for this bugfix ? yroux: The issue is that getting the offset value line 5948 can only be done if the addressing mode… | |||||
Not Done ReplyInline ActionsAgree, it's a separate concern. chill: Agree, it's a separate concern. | |||||
} | } | ||||
// Make sure the offset is encodable for instructions that scale the | // Make sure the offset is encodable for instructions that scale the | ||||
// immediate. | // immediate. | ||||
if (((OffVal * Scale + Fixup) & (Scale - 1)) != 0) | assert(((OffVal * Scale + Fixup) & (Scale - 1)) == 0 && | ||||
return false; | "Can't encode this offset!"); | ||||
OffVal += Fixup / Scale; | OffVal += Fixup / Scale; | ||||
unsigned Mask = (1 << NumBits) - 1; | unsigned Mask = (1 << NumBits) - 1; | ||||
if (OffVal <= Mask) { | if (OffVal <= Mask) { | ||||
if (Updt) | if (Updt) | ||||
MI->getOperand(ImmIdx).setImm(OffVal); | MI->getOperand(ImmIdx).setImm(OffVal); | ||||
return true; | return true; | ||||
▲ Show 20 Lines • Show All 513 Lines • Show Last 20 Lines |
Maybe assert "Fixup" is a multiple of 4?