@@ -2049,6 +2049,7 @@ void ConvertCIRToLLVMPass::runOnOperation() {
20492049 CIRToLLVMGetGlobalOpLowering,
20502050 CIRToLLVMGetMemberOpLowering,
20512051 CIRToLLVMSelectOpLowering,
2052+ CIRToLLVMSetBitfieldOpLowering,
20522053 CIRToLLVMShiftOpLowering,
20532054 CIRToLLVMStackRestoreOpLowering,
20542055 CIRToLLVMStackSaveOpLowering,
@@ -2384,6 +2385,82 @@ mlir::LogicalResult CIRToLLVMComplexImagOpLowering::matchAndRewrite(
23842385 return mlir::success ();
23852386}
23862387
2388+ mlir::LogicalResult CIRToLLVMSetBitfieldOpLowering::matchAndRewrite (
2389+ cir::SetBitfieldOp op, OpAdaptor adaptor,
2390+ mlir::ConversionPatternRewriter &rewriter) const {
2391+ mlir::OpBuilder::InsertionGuard guard (rewriter);
2392+ rewriter.setInsertionPoint (op);
2393+
2394+ cir::BitfieldInfoAttr info = op.getBitfieldInfo ();
2395+ uint64_t size = info.getSize ();
2396+ uint64_t offset = info.getOffset ();
2397+ mlir::Type storageType = info.getStorageType ();
2398+ mlir::MLIRContext *context = storageType.getContext ();
2399+
2400+ unsigned storageSize = 0 ;
2401+
2402+ mlir::IntegerType intType =
2403+ TypeSwitch<mlir::Type, mlir::IntegerType>(storageType)
2404+ .Case <cir::ArrayType>([&](cir::ArrayType atTy) {
2405+ storageSize = atTy.getSize () * 8 ;
2406+ return mlir::IntegerType::get (context, storageSize);
2407+ })
2408+ .Case <cir::IntType>([&](cir::IntType intTy) {
2409+ storageSize = intTy.getWidth ();
2410+ return mlir::IntegerType::get (context, storageSize);
2411+ })
2412+ .Default ([](mlir::Type) -> mlir::IntegerType {
2413+ llvm_unreachable (
2414+ " Either ArrayType or IntType expected for bitfields storage" );
2415+ });
2416+
2417+ mlir::Value srcVal = createIntCast (rewriter, adaptor.getSrc (), intType);
2418+ unsigned srcWidth = storageSize;
2419+ mlir::Value resultVal = srcVal;
2420+
2421+ if (storageSize != size) {
2422+ assert (storageSize > size && " Invalid bitfield size." );
2423+
2424+ mlir::Value val = rewriter.create <mlir::LLVM::LoadOp>(
2425+ op.getLoc (), intType, adaptor.getAddr (), /* alignment */ 0 ,
2426+ op.getIsVolatile ());
2427+
2428+ srcVal =
2429+ createAnd (rewriter, srcVal, llvm::APInt::getLowBitsSet (srcWidth, size));
2430+ resultVal = srcVal;
2431+ srcVal = createShL (rewriter, srcVal, offset);
2432+
2433+ // Mask out the original value.
2434+ val = createAnd (rewriter, val,
2435+ ~llvm::APInt::getBitsSet (srcWidth, offset, offset + size));
2436+
2437+ // Or together the unchanged values and the source value.
2438+ srcVal = rewriter.create <mlir::LLVM::OrOp>(op.getLoc (), val, srcVal);
2439+ }
2440+
2441+ rewriter.create <mlir::LLVM::StoreOp>(op.getLoc (), srcVal, adaptor.getAddr (),
2442+ /* alignment */ 0 , op.getIsVolatile ());
2443+
2444+ mlir::Type resultTy = getTypeConverter ()->convertType (op.getType ());
2445+
2446+ if (info.getIsSigned ()) {
2447+ assert (size <= storageSize);
2448+ unsigned highBits = storageSize - size;
2449+
2450+ if (highBits) {
2451+ resultVal = createShL (rewriter, resultVal, highBits);
2452+ resultVal = createAShR (rewriter, resultVal, highBits);
2453+ }
2454+ }
2455+
2456+ resultVal = createIntCast (rewriter, resultVal,
2457+ mlir::cast<mlir::IntegerType>(resultTy),
2458+ info.getIsSigned ());
2459+
2460+ rewriter.replaceOp (op, resultVal);
2461+ return mlir::success ();
2462+ }
2463+
23872464mlir::LogicalResult CIRToLLVMGetBitfieldOpLowering::matchAndRewrite (
23882465 cir::GetBitfieldOp op, OpAdaptor adaptor,
23892466 mlir::ConversionPatternRewriter &rewriter) const {
0 commit comments