Skip to content

Commit d4c3fc9

Browse files
committed
Separate MCExpr kernel descriptor from kernel_descriptor_t, add more hsa symbolic expression tests, apply feedback
1 parent e21b9bd commit d4c3fc9

14 files changed

+780
-153
lines changed

llvm/include/llvm/Support/AMDHSAKernelDescriptor.h

Lines changed: 45 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,6 @@
5252
#endif // AMDHSA_BITS_SET
5353

5454
namespace llvm {
55-
56-
class MCContext;
57-
class MCExpr;
58-
5955
namespace amdhsa {
6056

6157
// Floating point rounding modes. Must match hardware definition.
@@ -242,40 +238,18 @@ enum : int32_t {
242238

243239
// Kernel descriptor. Must be kept backwards compatible.
244240
struct kernel_descriptor_t {
245-
const MCExpr *group_segment_fixed_size;
246-
const MCExpr *private_segment_fixed_size;
247-
const MCExpr *kernarg_size;
241+
uint32_t group_segment_fixed_size;
242+
uint32_t private_segment_fixed_size;
243+
uint32_t kernarg_size;
248244
uint8_t reserved0[4];
249245
int64_t kernel_code_entry_byte_offset;
250246
uint8_t reserved1[20];
251-
const MCExpr *compute_pgm_rsrc3; // GFX10+ and GFX90A+
252-
const MCExpr *compute_pgm_rsrc1;
253-
const MCExpr *compute_pgm_rsrc2;
254-
const MCExpr *kernel_code_properties;
255-
const MCExpr *kernarg_preload;
247+
uint32_t compute_pgm_rsrc3; // GFX10+ and GFX90A+
248+
uint32_t compute_pgm_rsrc1;
249+
uint32_t compute_pgm_rsrc2;
250+
uint16_t kernel_code_properties;
251+
uint16_t kernarg_preload;
256252
uint8_t reserved3[4];
257-
258-
static void bits_set(const MCExpr *&Dst, const MCExpr *Value, uint32_t Shift,
259-
uint32_t Mask, MCContext &Ctx);
260-
static const MCExpr *bits_get(const MCExpr *Src, uint32_t Shift,
261-
uint32_t Mask, MCContext &Ctx);
262-
};
263-
264-
// Sizes for kernel_descriptor_t properties, should add up to 64.
265-
enum : uint32_t {
266-
SIZEOF_GROUP_SEGMENT_FIXED_SIZE = 4,
267-
SIZEOF_PRIVATE_SEGMENT_FIXED_SIZE = 4,
268-
SIZEOF_KERNARG_SIZE = 4,
269-
SIZEOF_RESERVED0 = 4,
270-
SIZEOF_KERNEL_CODE_ENTRY_BYTE_OFFSET = 8,
271-
SIZEOF_RESERVED1 = 20,
272-
SIZEOF_COMPUTE_PGM_RSRC3 = 4,
273-
SIZEOF_COMPUTE_PGM_RSRC1 = 4,
274-
SIZEOF_COMPUTE_PGM_RSRC2 = 4,
275-
SIZEOF_KERNEL_CODE_PROPERTIES = 2,
276-
SIZEOF_KERNARG_PRELOAD = 2,
277-
SIZEOF_RESERVED3 = 4,
278-
SIZEOF_KERNEL_DESCRIPTOR = 64
279253
};
280254

281255
enum : uint32_t {
@@ -293,6 +267,43 @@ enum : uint32_t {
293267
RESERVED3_OFFSET = 60
294268
};
295269

270+
static_assert(
271+
sizeof(kernel_descriptor_t) == 64,
272+
"invalid size for kernel_descriptor_t");
273+
static_assert(offsetof(kernel_descriptor_t, group_segment_fixed_size) ==
274+
GROUP_SEGMENT_FIXED_SIZE_OFFSET,
275+
"invalid offset for group_segment_fixed_size");
276+
static_assert(offsetof(kernel_descriptor_t, private_segment_fixed_size) ==
277+
PRIVATE_SEGMENT_FIXED_SIZE_OFFSET,
278+
"invalid offset for private_segment_fixed_size");
279+
static_assert(offsetof(kernel_descriptor_t, kernarg_size) ==
280+
KERNARG_SIZE_OFFSET,
281+
"invalid offset for kernarg_size");
282+
static_assert(offsetof(kernel_descriptor_t, reserved0) == RESERVED0_OFFSET,
283+
"invalid offset for reserved0");
284+
static_assert(offsetof(kernel_descriptor_t, kernel_code_entry_byte_offset) ==
285+
KERNEL_CODE_ENTRY_BYTE_OFFSET_OFFSET,
286+
"invalid offset for kernel_code_entry_byte_offset");
287+
static_assert(offsetof(kernel_descriptor_t, reserved1) == RESERVED1_OFFSET,
288+
"invalid offset for reserved1");
289+
static_assert(offsetof(kernel_descriptor_t, compute_pgm_rsrc3) ==
290+
COMPUTE_PGM_RSRC3_OFFSET,
291+
"invalid offset for compute_pgm_rsrc3");
292+
static_assert(offsetof(kernel_descriptor_t, compute_pgm_rsrc1) ==
293+
COMPUTE_PGM_RSRC1_OFFSET,
294+
"invalid offset for compute_pgm_rsrc1");
295+
static_assert(offsetof(kernel_descriptor_t, compute_pgm_rsrc2) ==
296+
COMPUTE_PGM_RSRC2_OFFSET,
297+
"invalid offset for compute_pgm_rsrc2");
298+
static_assert(offsetof(kernel_descriptor_t, kernel_code_properties) ==
299+
KERNEL_CODE_PROPERTIES_OFFSET,
300+
"invalid offset for kernel_code_properties");
301+
static_assert(offsetof(kernel_descriptor_t, kernarg_preload) ==
302+
KERNARG_PRELOAD_OFFSET,
303+
"invalid offset for kernarg_preload");
304+
static_assert(offsetof(kernel_descriptor_t, reserved3) == RESERVED3_OFFSET,
305+
"invalid offset for reserved3");
306+
296307
} // end namespace amdhsa
297308
} // end namespace llvm
298309

llvm/lib/Target/AMDGPU/AMDGPUAsmPrinter.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "AMDKernelCodeT.h"
2323
#include "GCNSubtarget.h"
2424
#include "MCTargetDesc/AMDGPUInstPrinter.h"
25+
#include "MCTargetDesc/AMDGPUMCKernelDescriptor.h"
2526
#include "MCTargetDesc/AMDGPUTargetStreamer.h"
2627
#include "R600AsmPrinter.h"
2728
#include "SIMachineFunctionInfo.h"
@@ -428,15 +429,14 @@ uint16_t AMDGPUAsmPrinter::getAmdhsaKernelCodeProperties(
428429
return KernelCodeProperties;
429430
}
430431

431-
amdhsa::kernel_descriptor_t AMDGPUAsmPrinter::getAmdhsaKernelDescriptor(
432-
const MachineFunction &MF,
433-
const SIProgramInfo &PI) const {
432+
MCKernelDescriptor
433+
AMDGPUAsmPrinter::getAmdhsaKernelDescriptor(const MachineFunction &MF,
434+
const SIProgramInfo &PI) const {
434435
const GCNSubtarget &STM = MF.getSubtarget<GCNSubtarget>();
435436
const Function &F = MF.getFunction();
436437
const SIMachineFunctionInfo *Info = MF.getInfo<SIMachineFunctionInfo>();
437438

438-
amdhsa::kernel_descriptor_t KernelDescriptor;
439-
memset(&KernelDescriptor, 0x0, sizeof(KernelDescriptor));
439+
MCKernelDescriptor KernelDescriptor;
440440

441441
assert(isUInt<32>(PI.ScratchSize));
442442
assert(isUInt<32>(PI.getComputePGMRSrc1(STM)));

llvm/lib/Target/AMDGPU/AMDGPUAsmPrinter.h

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,15 +28,12 @@ class MCCodeEmitter;
2828
class MCOperand;
2929

3030
namespace AMDGPU {
31+
struct MCKernelDescriptor;
3132
namespace HSAMD {
3233
class MetadataStreamer;
3334
}
3435
} // namespace AMDGPU
3536

36-
namespace amdhsa {
37-
struct kernel_descriptor_t;
38-
}
39-
4037
class AMDGPUAsmPrinter final : public AsmPrinter {
4138
private:
4239
unsigned CodeObjectVersion;
@@ -75,9 +72,9 @@ class AMDGPUAsmPrinter final : public AsmPrinter {
7572
uint16_t getAmdhsaKernelCodeProperties(
7673
const MachineFunction &MF) const;
7774

78-
amdhsa::kernel_descriptor_t getAmdhsaKernelDescriptor(
79-
const MachineFunction &MF,
80-
const SIProgramInfo &PI) const;
75+
AMDGPU::MCKernelDescriptor
76+
getAmdhsaKernelDescriptor(const MachineFunction &MF,
77+
const SIProgramInfo &PI) const;
8178

8279
void initTargetStreamer(Module &M);
8380

llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp

Lines changed: 29 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
#include "AMDKernelCodeT.h"
1010
#include "MCTargetDesc/AMDGPUMCExpr.h"
11+
#include "MCTargetDesc/AMDGPUMCKernelDescriptor.h"
1112
#include "MCTargetDesc/AMDGPUMCTargetDesc.h"
1213
#include "MCTargetDesc/AMDGPUTargetStreamer.h"
1314
#include "SIDefines.h"
@@ -5417,7 +5418,7 @@ bool AMDGPUAsmParser::ParseDirectiveAMDHSAKernel() {
54175418
if (getParser().parseIdentifier(KernelName))
54185419
return true;
54195420

5420-
kernel_descriptor_t KD =
5421+
AMDGPU::MCKernelDescriptor KD =
54215422
getDefaultAmdhsaKernelDescriptor(&getSTI(), getContext());
54225423

54235424
StringSet<> Seen;
@@ -5476,11 +5477,13 @@ bool AMDGPUAsmParser::ParseDirectiveAMDHSAKernel() {
54765477
#define PARSE_BITS_ENTRY(FIELD, ENTRY, VALUE, RANGE) \
54775478
if (!isUInt<ENTRY##_WIDTH>(Val)) \
54785479
return OutOfRangeError(RANGE); \
5479-
kernel_descriptor_t::bits_set(FIELD, VALUE, ENTRY##_SHIFT, ENTRY, \
5480-
getContext());
5480+
AMDGPU::MCKernelDescriptor::bits_set(FIELD, VALUE, ENTRY##_SHIFT, ENTRY, \
5481+
getContext());
54815482

5482-
#define EXPR_SHOULD_RESOLVE() \
5483-
if (!EvaluatableExpr) \
5483+
// Some fields use the parsed value immediately which requires the expression to
5484+
// be solvable.
5485+
#define EXPR_RESOLVE_OR_ERROR(RESOLVED) \
5486+
if (!(RESOLVED)) \
54845487
return Error(IDRange.Start, "directive should have resolvable expression", \
54855488
IDRange);
54865489

@@ -5497,10 +5500,10 @@ bool AMDGPUAsmParser::ParseDirectiveAMDHSAKernel() {
54975500
return OutOfRangeError(ValRange);
54985501
KD.kernarg_size = ExprVal;
54995502
} else if (ID == ".amdhsa_user_sgpr_count") {
5500-
EXPR_SHOULD_RESOLVE();
5503+
EXPR_RESOLVE_OR_ERROR(EvaluatableExpr);
55015504
ExplicitUserSGPRCount = Val;
55025505
} else if (ID == ".amdhsa_user_sgpr_private_segment_buffer") {
5503-
EXPR_SHOULD_RESOLVE();
5506+
EXPR_RESOLVE_OR_ERROR(EvaluatableExpr);
55045507
if (hasArchitectedFlatScratch())
55055508
return Error(IDRange.Start,
55065509
"directive is not supported with architected flat scratch",
@@ -5511,7 +5514,7 @@ bool AMDGPUAsmParser::ParseDirectiveAMDHSAKernel() {
55115514
if (Val)
55125515
ImpliedUserSGPRCount += 4;
55135516
} else if (ID == ".amdhsa_user_sgpr_kernarg_preload_length") {
5514-
EXPR_SHOULD_RESOLVE();
5517+
EXPR_RESOLVE_OR_ERROR(EvaluatableExpr);
55155518
if (!hasKernargPreload())
55165519
return Error(IDRange.Start, "directive requires gfx90a+", IDRange);
55175520

@@ -5524,7 +5527,7 @@ bool AMDGPUAsmParser::ParseDirectiveAMDHSAKernel() {
55245527
PreloadLength = Val;
55255528
}
55265529
} else if (ID == ".amdhsa_user_sgpr_kernarg_preload_offset") {
5527-
EXPR_SHOULD_RESOLVE();
5530+
EXPR_RESOLVE_OR_ERROR(EvaluatableExpr);
55285531
if (!hasKernargPreload())
55295532
return Error(IDRange.Start, "directive requires gfx90a+", IDRange);
55305533

@@ -5535,28 +5538,28 @@ bool AMDGPUAsmParser::ParseDirectiveAMDHSAKernel() {
55355538
if (Val)
55365539
PreloadOffset = Val;
55375540
} else if (ID == ".amdhsa_user_sgpr_dispatch_ptr") {
5538-
EXPR_SHOULD_RESOLVE();
5541+
EXPR_RESOLVE_OR_ERROR(EvaluatableExpr);
55395542
PARSE_BITS_ENTRY(KD.kernel_code_properties,
55405543
KERNEL_CODE_PROPERTY_ENABLE_SGPR_DISPATCH_PTR, ExprVal,
55415544
ValRange);
55425545
if (Val)
55435546
ImpliedUserSGPRCount += 2;
55445547
} else if (ID == ".amdhsa_user_sgpr_queue_ptr") {
5545-
EXPR_SHOULD_RESOLVE();
5548+
EXPR_RESOLVE_OR_ERROR(EvaluatableExpr);
55465549
PARSE_BITS_ENTRY(KD.kernel_code_properties,
55475550
KERNEL_CODE_PROPERTY_ENABLE_SGPR_QUEUE_PTR, ExprVal,
55485551
ValRange);
55495552
if (Val)
55505553
ImpliedUserSGPRCount += 2;
55515554
} else if (ID == ".amdhsa_user_sgpr_kernarg_segment_ptr") {
5552-
EXPR_SHOULD_RESOLVE();
5555+
EXPR_RESOLVE_OR_ERROR(EvaluatableExpr);
55535556
PARSE_BITS_ENTRY(KD.kernel_code_properties,
55545557
KERNEL_CODE_PROPERTY_ENABLE_SGPR_KERNARG_SEGMENT_PTR,
55555558
ExprVal, ValRange);
55565559
if (Val)
55575560
ImpliedUserSGPRCount += 2;
55585561
} else if (ID == ".amdhsa_user_sgpr_dispatch_id") {
5559-
EXPR_SHOULD_RESOLVE();
5562+
EXPR_RESOLVE_OR_ERROR(EvaluatableExpr);
55605563
PARSE_BITS_ENTRY(KD.kernel_code_properties,
55615564
KERNEL_CODE_PROPERTY_ENABLE_SGPR_DISPATCH_ID, ExprVal,
55625565
ValRange);
@@ -5567,21 +5570,21 @@ bool AMDGPUAsmParser::ParseDirectiveAMDHSAKernel() {
55675570
return Error(IDRange.Start,
55685571
"directive is not supported with architected flat scratch",
55695572
IDRange);
5570-
EXPR_SHOULD_RESOLVE();
5573+
EXPR_RESOLVE_OR_ERROR(EvaluatableExpr);
55715574
PARSE_BITS_ENTRY(KD.kernel_code_properties,
55725575
KERNEL_CODE_PROPERTY_ENABLE_SGPR_FLAT_SCRATCH_INIT,
55735576
ExprVal, ValRange);
55745577
if (Val)
55755578
ImpliedUserSGPRCount += 2;
55765579
} else if (ID == ".amdhsa_user_sgpr_private_segment_size") {
5577-
EXPR_SHOULD_RESOLVE();
5580+
EXPR_RESOLVE_OR_ERROR(EvaluatableExpr);
55785581
PARSE_BITS_ENTRY(KD.kernel_code_properties,
55795582
KERNEL_CODE_PROPERTY_ENABLE_SGPR_PRIVATE_SEGMENT_SIZE,
55805583
ExprVal, ValRange);
55815584
if (Val)
55825585
ImpliedUserSGPRCount += 1;
55835586
} else if (ID == ".amdhsa_wavefront_size32") {
5584-
EXPR_SHOULD_RESOLVE();
5587+
EXPR_RESOLVE_OR_ERROR(EvaluatableExpr);
55855588
if (IVersion.Major < 10)
55865589
return Error(IDRange.Start, "directive requires gfx10+", IDRange);
55875590
EnableWavefrontSize32 = Val;
@@ -5630,25 +5633,25 @@ bool AMDGPUAsmParser::ParseDirectiveAMDHSAKernel() {
56305633
COMPUTE_PGM_RSRC2_ENABLE_VGPR_WORKITEM_ID, ExprVal,
56315634
ValRange);
56325635
} else if (ID == ".amdhsa_next_free_vgpr") {
5633-
EXPR_SHOULD_RESOLVE();
5636+
EXPR_RESOLVE_OR_ERROR(EvaluatableExpr);
56345637
VGPRRange = ValRange;
56355638
NextFreeVGPR = Val;
56365639
} else if (ID == ".amdhsa_next_free_sgpr") {
5637-
EXPR_SHOULD_RESOLVE();
5640+
EXPR_RESOLVE_OR_ERROR(EvaluatableExpr);
56385641
SGPRRange = ValRange;
56395642
NextFreeSGPR = Val;
56405643
} else if (ID == ".amdhsa_accum_offset") {
56415644
if (!isGFX90A())
56425645
return Error(IDRange.Start, "directive requires gfx90a+", IDRange);
5643-
EXPR_SHOULD_RESOLVE();
5646+
EXPR_RESOLVE_OR_ERROR(EvaluatableExpr);
56445647
AccumOffset = Val;
56455648
} else if (ID == ".amdhsa_reserve_vcc") {
5646-
EXPR_SHOULD_RESOLVE();
5649+
EXPR_RESOLVE_OR_ERROR(EvaluatableExpr);
56475650
if (!isUInt<1>(Val))
56485651
return OutOfRangeError(ValRange);
56495652
ReserveVCC = Val;
56505653
} else if (ID == ".amdhsa_reserve_flat_scratch") {
5651-
EXPR_SHOULD_RESOLVE();
5654+
EXPR_RESOLVE_OR_ERROR(EvaluatableExpr);
56525655
if (IVersion.Major < 7)
56535656
return Error(IDRange.Start, "directive requires gfx7+", IDRange);
56545657
if (hasArchitectedFlatScratch())
@@ -5724,7 +5727,7 @@ bool AMDGPUAsmParser::ParseDirectiveAMDHSAKernel() {
57245727
COMPUTE_PGM_RSRC1_GFX10_PLUS_FWD_PROGRESS, ExprVal,
57255728
ValRange);
57265729
} else if (ID == ".amdhsa_shared_vgpr_count") {
5727-
EXPR_SHOULD_RESOLVE();
5730+
EXPR_RESOLVE_OR_ERROR(EvaluatableExpr);
57285731
if (IVersion.Major < 10 || IVersion.Major >= 12)
57295732
return Error(IDRange.Start, "directive requires gfx10 or gfx11",
57305733
IDRange);
@@ -5793,15 +5796,15 @@ bool AMDGPUAsmParser::ParseDirectiveAMDHSAKernel() {
57935796
if (!isUInt<COMPUTE_PGM_RSRC1_GRANULATED_WORKITEM_VGPR_COUNT_WIDTH>(
57945797
VGPRBlocks))
57955798
return OutOfRangeError(VGPRRange);
5796-
kernel_descriptor_t::bits_set(
5799+
AMDGPU::MCKernelDescriptor::bits_set(
57975800
KD.compute_pgm_rsrc1, MCConstantExpr::create(VGPRBlocks, getContext()),
57985801
COMPUTE_PGM_RSRC1_GRANULATED_WORKITEM_VGPR_COUNT_SHIFT,
57995802
COMPUTE_PGM_RSRC1_GRANULATED_WORKITEM_VGPR_COUNT, getContext());
58005803

58015804
if (!isUInt<COMPUTE_PGM_RSRC1_GRANULATED_WAVEFRONT_SGPR_COUNT_WIDTH>(
58025805
SGPRBlocks))
58035806
return OutOfRangeError(SGPRRange);
5804-
kernel_descriptor_t::bits_set(
5807+
AMDGPU::MCKernelDescriptor::bits_set(
58055808
KD.compute_pgm_rsrc1, MCConstantExpr::create(SGPRBlocks, getContext()),
58065809
COMPUTE_PGM_RSRC1_GRANULATED_WAVEFRONT_SGPR_COUNT_SHIFT,
58075810
COMPUTE_PGM_RSRC1_GRANULATED_WAVEFRONT_SGPR_COUNT, getContext());
@@ -5815,7 +5818,7 @@ bool AMDGPUAsmParser::ParseDirectiveAMDHSAKernel() {
58155818

58165819
if (!isUInt<COMPUTE_PGM_RSRC2_USER_SGPR_COUNT_WIDTH>(UserSGPRCount))
58175820
return TokError("too many user SGPRs enabled");
5818-
kernel_descriptor_t::bits_set(
5821+
AMDGPU::MCKernelDescriptor::bits_set(
58195822
KD.compute_pgm_rsrc2, MCConstantExpr::create(UserSGPRCount, getContext()),
58205823
COMPUTE_PGM_RSRC2_USER_SGPR_COUNT_SHIFT,
58215824
COMPUTE_PGM_RSRC2_USER_SGPR_COUNT, getContext());
@@ -5837,7 +5840,7 @@ bool AMDGPUAsmParser::ParseDirectiveAMDHSAKernel() {
58375840
"increments of 4");
58385841
if (AccumOffset > alignTo(std::max((uint64_t)1, NextFreeVGPR), 4))
58395842
return TokError("accum_offset exceeds total VGPR allocation");
5840-
kernel_descriptor_t::bits_set(
5843+
MCKernelDescriptor::bits_set(
58415844
KD.compute_pgm_rsrc3,
58425845
MCConstantExpr::create(AccumOffset / 4 - 1, getContext()),
58435846
COMPUTE_PGM_RSRC3_GFX90A_ACCUM_OFFSET_SHIFT,

llvm/lib/Target/AMDGPU/MCTargetDesc/AMDHSAKernelDescriptor.cpp renamed to llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCKernelDescriptor.cpp

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,25 +6,30 @@
66
//
77
//===----------------------------------------------------------------------===//
88

9-
#include "llvm/Support/AMDHSAKernelDescriptor.h"
9+
#include "AMDGPUMCKernelDescriptor.h"
1010
#include "llvm/MC/MCContext.h"
1111
#include "llvm/MC/MCExpr.h"
1212

1313
using namespace llvm;
14-
using namespace llvm::amdhsa;
14+
using namespace llvm::AMDGPU;
1515

16-
void kernel_descriptor_t::bits_set(const MCExpr *&Dst, const MCExpr *Value,
17-
uint32_t Shift, uint32_t Mask,
18-
MCContext &Ctx) {
16+
// MCExpr for:
17+
// Dst = Dst & ~Mask
18+
// Dst = Dst | (Value << Shift)
19+
void MCKernelDescriptor::bits_set(const MCExpr *&Dst, const MCExpr *Value,
20+
uint32_t Shift, uint32_t Mask,
21+
MCContext &Ctx) {
1922
auto Sft = MCConstantExpr::create(Shift, Ctx);
2023
auto Msk = MCConstantExpr::create(Mask, Ctx);
2124
Dst = MCBinaryExpr::createAnd(Dst, MCUnaryExpr::createNot(Msk, Ctx), Ctx);
2225
Dst = MCBinaryExpr::createOr(Dst, MCBinaryExpr::createShl(Value, Sft, Ctx),
2326
Ctx);
2427
}
2528

26-
const MCExpr *kernel_descriptor_t::bits_get(const MCExpr *Src, uint32_t Shift,
27-
uint32_t Mask, MCContext &Ctx) {
29+
// MCExpr for:
30+
// return (Src & Mask) >> Shift
31+
const MCExpr *MCKernelDescriptor::bits_get(const MCExpr *Src, uint32_t Shift,
32+
uint32_t Mask, MCContext &Ctx) {
2833
auto Sft = MCConstantExpr::create(Shift, Ctx);
2934
auto Msk = MCConstantExpr::create(Mask, Ctx);
3035
return MCBinaryExpr::createLShr(MCBinaryExpr::createAnd(Src, Msk, Ctx), Sft,

0 commit comments

Comments
 (0)