|
14 | 14 | #include "RISCVSubtarget.h" |
15 | 15 | #include "llvm/CodeGen/GlobalISel/LegalizerHelper.h" |
16 | 16 | #include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h" |
| 17 | +#include "llvm/CodeGen/MachineJumpTableInfo.h" |
17 | 18 | #include "llvm/CodeGen/MachineRegisterInfo.h" |
18 | 19 | #include "llvm/CodeGen/TargetOpcodes.h" |
19 | 20 | #include "llvm/CodeGen/ValueTypes.h" |
@@ -179,7 +180,7 @@ RISCVLegalizerInfo::RISCVLegalizerInfo(const RISCVSubtarget &ST) |
179 | 180 |
|
180 | 181 | getActionDefinitionsBuilder(G_BRCOND).legalFor({sXLen}).minScalar(0, sXLen); |
181 | 182 |
|
182 | | - getActionDefinitionsBuilder(G_BRJT).legalFor({{p0, sXLen}}); |
| 183 | + getActionDefinitionsBuilder(G_BRJT).customFor({{p0, sXLen}}); |
183 | 184 |
|
184 | 185 | getActionDefinitionsBuilder(G_BRINDIRECT).legalFor({p0}); |
185 | 186 |
|
@@ -317,6 +318,62 @@ bool RISCVLegalizerInfo::legalizeShlAshrLshr( |
317 | 318 | return true; |
318 | 319 | } |
319 | 320 |
|
| 321 | +bool RISCVLegalizerInfo::legalizeBRJT(MachineInstr &MI, |
| 322 | + MachineIRBuilder &MIRBuilder) const { |
| 323 | + MachineRegisterInfo &MRI = *MIRBuilder.getMRI(); |
| 324 | + auto &MF = *MI.getParent()->getParent(); |
| 325 | + const MachineJumpTableInfo *MJTI = MF.getJumpTableInfo(); |
| 326 | + unsigned EntrySize = MJTI->getEntrySize(MF.getDataLayout()); |
| 327 | + |
| 328 | + Register PtrReg = MI.getOperand(0).getReg(); |
| 329 | + LLT PtrTy = MRI.getType(PtrReg); |
| 330 | + Register IndexReg = MI.getOperand(2).getReg(); |
| 331 | + LLT IndexTy = MRI.getType(IndexReg); |
| 332 | + |
| 333 | + MachineInstrBuilder Index; |
| 334 | + if (isPowerOf2_32(EntrySize)) { |
| 335 | + auto ShiftAmt = MIRBuilder.buildConstant(IndexTy, Log2_32(EntrySize)); |
| 336 | + Index = MIRBuilder.buildShl(IndexTy, IndexReg, ShiftAmt); |
| 337 | + } else |
| 338 | + return false; |
| 339 | + |
| 340 | + auto Addr = MIRBuilder.buildPtrAdd(PtrTy, PtrReg, Index); |
| 341 | + |
| 342 | + MachineMemOperand *MMO = MF.getMachineMemOperand( |
| 343 | + MachinePointerInfo::getJumpTable(MF), MachineMemOperand::MOLoad, |
| 344 | + EntrySize, Align(MJTI->getEntryAlignment(MF.getDataLayout()))); |
| 345 | + |
| 346 | + Register TargetReg; |
| 347 | + switch (MJTI->getEntryKind()) { |
| 348 | + default: |
| 349 | + llvm_unreachable("Unexpected jumptable entry kind"); |
| 350 | + case MachineJumpTableInfo::EK_LabelDifference32: { |
| 351 | + // For PIC, the sequence is: |
| 352 | + // BRIND(load(Jumptable + index) + RelocBase) |
| 353 | + // RelocBase can be JumpTable, GOT or some sort of global base. |
| 354 | + auto Load = MIRBuilder.buildLoadInstr( |
| 355 | + TargetOpcode::G_LOAD, LLT::scalar(EntrySize * 8), Addr, *MMO); |
| 356 | + Load = MIRBuilder.buildSExtOrTrunc(IndexTy, Load); |
| 357 | + TargetReg = MIRBuilder.buildPtrAdd(PtrTy, PtrReg, Load).getReg(0); |
| 358 | + break; |
| 359 | + } |
| 360 | + case MachineJumpTableInfo::EK_Custom32: { |
| 361 | + auto Load = MIRBuilder.buildLoadInstr(TargetOpcode::G_SEXTLOAD, IndexTy, |
| 362 | + Addr, *MMO); |
| 363 | + TargetReg = MIRBuilder.buildIntToPtr(PtrTy, Load).getReg(0); |
| 364 | + break; |
| 365 | + } |
| 366 | + case MachineJumpTableInfo::EK_BlockAddress: |
| 367 | + TargetReg = MIRBuilder.buildLoad(PtrTy, Addr, *MMO).getReg(0); |
| 368 | + break; |
| 369 | + } |
| 370 | + |
| 371 | + MIRBuilder.buildBrIndirect(TargetReg); |
| 372 | + |
| 373 | + MI.eraseFromParent(); |
| 374 | + return true; |
| 375 | +} |
| 376 | + |
320 | 377 | bool RISCVLegalizerInfo::legalizeCustom(LegalizerHelper &Helper, |
321 | 378 | MachineInstr &MI) const { |
322 | 379 | MachineIRBuilder &MIRBuilder = Helper.MIRBuilder; |
@@ -357,6 +414,8 @@ bool RISCVLegalizerInfo::legalizeCustom(LegalizerHelper &Helper, |
357 | 414 | MI.eraseFromParent(); |
358 | 415 | return true; |
359 | 416 | } |
| 417 | + case TargetOpcode::G_BRJT: |
| 418 | + return legalizeBRJT(MI, MIRBuilder); |
360 | 419 | } |
361 | 420 |
|
362 | 421 | llvm_unreachable("expected switch to return"); |
|
0 commit comments