|
19 | 19 | #include "llvm/CodeGen/GlobalISel/LegalizerHelper.h"
|
20 | 20 | #include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
|
21 | 21 | #include "llvm/CodeGen/MachineConstantPool.h"
|
| 22 | +#include "llvm/CodeGen/MachineJumpTableInfo.h" |
22 | 23 | #include "llvm/CodeGen/MachineMemOperand.h"
|
23 | 24 | #include "llvm/CodeGen/MachineRegisterInfo.h"
|
24 | 25 | #include "llvm/CodeGen/TargetOpcodes.h"
|
@@ -406,7 +407,7 @@ RISCVLegalizerInfo::RISCVLegalizerInfo(const RISCVSubtarget &ST)
|
406 | 407 |
|
407 | 408 | getActionDefinitionsBuilder(G_BRCOND).legalFor({sXLen}).minScalar(0, sXLen);
|
408 | 409 |
|
409 |
| - getActionDefinitionsBuilder(G_BRJT).legalFor({{p0, sXLen}}); |
| 410 | + getActionDefinitionsBuilder(G_BRJT).customFor({{p0, sXLen}}); |
410 | 411 |
|
411 | 412 | getActionDefinitionsBuilder(G_BRINDIRECT).legalFor({p0});
|
412 | 413 |
|
@@ -687,6 +688,61 @@ bool RISCVLegalizerInfo::legalizeVAStart(MachineInstr &MI,
|
687 | 688 | return true;
|
688 | 689 | }
|
689 | 690 |
|
| 691 | +bool RISCVLegalizerInfo::legalizeBRJT(MachineInstr &MI, |
| 692 | + MachineIRBuilder &MIRBuilder) const { |
| 693 | + MachineRegisterInfo &MRI = *MIRBuilder.getMRI(); |
| 694 | + auto &MF = *MI.getParent()->getParent(); |
| 695 | + const MachineJumpTableInfo *MJTI = MF.getJumpTableInfo(); |
| 696 | + unsigned EntrySize = MJTI->getEntrySize(MF.getDataLayout()); |
| 697 | + |
| 698 | + Register PtrReg = MI.getOperand(0).getReg(); |
| 699 | + LLT PtrTy = MRI.getType(PtrReg); |
| 700 | + Register IndexReg = MI.getOperand(2).getReg(); |
| 701 | + LLT IndexTy = MRI.getType(IndexReg); |
| 702 | + |
| 703 | + if (!isPowerOf2_32(EntrySize)) |
| 704 | + return false; |
| 705 | + |
| 706 | + auto ShiftAmt = MIRBuilder.buildConstant(IndexTy, Log2_32(EntrySize)); |
| 707 | + IndexReg = MIRBuilder.buildShl(IndexTy, IndexReg, ShiftAmt).getReg(0); |
| 708 | + |
| 709 | + auto Addr = MIRBuilder.buildPtrAdd(PtrTy, PtrReg, IndexReg); |
| 710 | + |
| 711 | + MachineMemOperand *MMO = MF.getMachineMemOperand( |
| 712 | + MachinePointerInfo::getJumpTable(MF), MachineMemOperand::MOLoad, |
| 713 | + EntrySize, Align(MJTI->getEntryAlignment(MF.getDataLayout()))); |
| 714 | + |
| 715 | + Register TargetReg; |
| 716 | + switch (MJTI->getEntryKind()) { |
| 717 | + default: |
| 718 | + return false; |
| 719 | + case MachineJumpTableInfo::EK_LabelDifference32: { |
| 720 | + // For PIC, the sequence is: |
| 721 | + // BRIND(load(Jumptable + index) + RelocBase) |
| 722 | + // RelocBase can be JumpTable, GOT or some sort of global base. |
| 723 | + unsigned LoadOpc = |
| 724 | + STI.is64Bit() ? TargetOpcode::G_SEXTLOAD : TargetOpcode::G_LOAD; |
| 725 | + auto Load = MIRBuilder.buildLoadInstr(LoadOpc, IndexTy, Addr, *MMO); |
| 726 | + TargetReg = MIRBuilder.buildPtrAdd(PtrTy, PtrReg, Load).getReg(0); |
| 727 | + break; |
| 728 | + } |
| 729 | + case MachineJumpTableInfo::EK_Custom32: { |
| 730 | + auto Load = MIRBuilder.buildLoadInstr(TargetOpcode::G_SEXTLOAD, IndexTy, |
| 731 | + Addr, *MMO); |
| 732 | + TargetReg = MIRBuilder.buildIntToPtr(PtrTy, Load).getReg(0); |
| 733 | + break; |
| 734 | + } |
| 735 | + case MachineJumpTableInfo::EK_BlockAddress: |
| 736 | + TargetReg = MIRBuilder.buildLoad(PtrTy, Addr, *MMO).getReg(0); |
| 737 | + break; |
| 738 | + } |
| 739 | + |
| 740 | + MIRBuilder.buildBrIndirect(TargetReg); |
| 741 | + |
| 742 | + MI.eraseFromParent(); |
| 743 | + return true; |
| 744 | +} |
| 745 | + |
690 | 746 | bool RISCVLegalizerInfo::shouldBeInConstantPool(const APInt &APImm,
|
691 | 747 | bool ShouldOptForSize) const {
|
692 | 748 | assert(APImm.getBitWidth() == 32 || APImm.getBitWidth() == 64);
|
@@ -1313,6 +1369,8 @@ bool RISCVLegalizerInfo::legalizeCustom(
|
1313 | 1369 | MI.eraseFromParent();
|
1314 | 1370 | return true;
|
1315 | 1371 | }
|
| 1372 | + case TargetOpcode::G_BRJT: |
| 1373 | + return legalizeBRJT(MI, MIRBuilder); |
1316 | 1374 | case TargetOpcode::G_VASTART:
|
1317 | 1375 | return legalizeVAStart(MI, MIRBuilder);
|
1318 | 1376 | case TargetOpcode::G_VSCALE:
|
|
0 commit comments