mirror of
https://github.com/RPCS3/llvm.git
synced 2026-06-30 21:08:10 -04:00
[GlobalISel] Add a G_JUMP_TABLE opcode.
This opcode generates a pointer to the address of the jump table specified by the source operand, which is a jump table index. It will be used in conjunction with an upcoming G_BRJT opcode to support jump table codegen with GlobalISel. Differential Revision: https://reviews.llvm.org/D63111 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@363096 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -1359,6 +1359,14 @@ public:
|
||||
return buildInstr(TargetOpcode::G_UMAX, {Dst}, {Src0, Src1});
|
||||
}
|
||||
|
||||
/// Build and insert \p Res = G_JUMP_TABLE \p JTI
|
||||
///
|
||||
/// G_JUMP_TABLE sets \p Res to the address of the jump table specified by
|
||||
/// the jump table index \p JTI.
|
||||
///
|
||||
/// \return a MachineInstrBuilder for the newly created instruction.
|
||||
MachineInstrBuilder buildJumpTable(const LLT PtrTy, unsigned JTI);
|
||||
|
||||
virtual MachineInstrBuilder buildInstr(unsigned Opc, ArrayRef<DstOp> DstOps,
|
||||
ArrayRef<SrcOp> SrcOps,
|
||||
Optional<unsigned> Flags = None);
|
||||
|
||||
@@ -566,12 +566,15 @@ HANDLE_TARGET_OPCODE(G_ADDRSPACE_CAST)
|
||||
/// Generic block address
|
||||
HANDLE_TARGET_OPCODE(G_BLOCK_ADDR)
|
||||
|
||||
/// Generic jump table address
|
||||
HANDLE_TARGET_OPCODE(G_JUMP_TABLE)
|
||||
|
||||
// TODO: Add more generic opcodes as we move along.
|
||||
|
||||
/// Marker for the end of the generic opcode.
|
||||
/// This is used to check if an opcode is in the range of the
|
||||
/// generic opcodes.
|
||||
HANDLE_TARGET_OPCODE_MARKER(PRE_ISEL_GENERIC_OPCODE_END, G_BLOCK_ADDR)
|
||||
HANDLE_TARGET_OPCODE_MARKER(PRE_ISEL_GENERIC_OPCODE_END, G_JUMP_TABLE)
|
||||
|
||||
/// BUILTIN_OP_END - This must be the last enum value in this list.
|
||||
/// The target-specific post-isel opcode values start here.
|
||||
|
||||
@@ -169,6 +169,12 @@ def G_BLOCK_ADDR : GenericInstruction {
|
||||
let hasSideEffects = 0;
|
||||
}
|
||||
|
||||
def G_JUMP_TABLE : GenericInstruction {
|
||||
let OutOperandList = (outs type0:$dst);
|
||||
let InOperandList = (ins unknown:$jti);
|
||||
let hasSideEffects = 0;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Binary ops.
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
@@ -179,6 +179,12 @@ MachineInstrBuilder MachineIRBuilder::buildGlobalValue(unsigned Res,
|
||||
.addGlobalAddress(GV);
|
||||
}
|
||||
|
||||
MachineInstrBuilder MachineIRBuilder::buildJumpTable(const LLT PtrTy,
|
||||
unsigned JTI) {
|
||||
return buildInstr(TargetOpcode::G_JUMP_TABLE, {PtrTy}, {})
|
||||
.addJumpTableIndex(JTI);
|
||||
}
|
||||
|
||||
void MachineIRBuilder::validateBinaryOp(const LLT &Res, const LLT &Op0,
|
||||
const LLT &Op1) {
|
||||
assert((Res.isScalar() || Res.isVector()) && "invalid operand type");
|
||||
|
||||
@@ -1312,6 +1312,14 @@ void MachineVerifier::verifyPreISelGenericInstruction(const MachineInstr *MI) {
|
||||
|
||||
break;
|
||||
}
|
||||
case TargetOpcode::G_JUMP_TABLE: {
|
||||
if (!MI->getOperand(1).isJTI())
|
||||
report("G_JUMP_TABLE source operand must be a jump table index", MI);
|
||||
LLT DstTy = MRI->getType(MI->getOperand(0).getReg());
|
||||
if (!DstTy.isPointer())
|
||||
report("G_JUMP_TABLE dest operand must have a pointer type", MI);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
# RUN: not llc -march=aarch64 -o /dev/null -run-pass=none -verify-machineinstrs %s 2>&1 | FileCheck %s
|
||||
# REQUIRES: global-isel, aarch64-registered-target
|
||||
|
||||
---
|
||||
name: test_jump_table
|
||||
legalized: true
|
||||
tracksRegLiveness: true
|
||||
jumpTable:
|
||||
kind: block-address
|
||||
entries:
|
||||
- id: 0
|
||||
blocks: [ '%bb.0' ]
|
||||
liveins:
|
||||
body: |
|
||||
bb.0:
|
||||
|
||||
; CHECK: Bad machine code: Too few operands
|
||||
%0:_(s32) = G_JUMP_TABLE
|
||||
|
||||
; CHECK: G_JUMP_TABLE source operand must be a jump table index
|
||||
%2:_(s32) = G_JUMP_TABLE %0
|
||||
|
||||
; CHECK: G_JUMP_TABLE dest operand must have a pointer type
|
||||
%3:_(s32) = G_JUMP_TABLE %jump-table.0
|
||||
|
||||
...
|
||||
Reference in New Issue
Block a user