@@ -2419,6 +2419,209 @@ OpFoldResult RotateOp::fold(FoldAdaptor adaptor) {
24192419 return IntAttr::get (input.getContext (), input.getType (), resultValue);
24202420}
24212421
2422+ // ===----------------------------------------------------------------------===//
2423+ // InlineAsmOp
2424+ // ===----------------------------------------------------------------------===//
2425+
2426+ void cir::InlineAsmOp::print (OpAsmPrinter &p) {
2427+ p << ' (' << getAsmFlavor () << " , " ;
2428+ p.increaseIndent ();
2429+ p.printNewline ();
2430+
2431+ llvm::SmallVector<std::string, 3 > names{" out" , " in" , " in_out" };
2432+ auto *nameIt = names.begin ();
2433+ auto *attrIt = getOperandAttrs ().begin ();
2434+
2435+ for (mlir::OperandRange ops : getAsmOperands ()) {
2436+ p << *nameIt << " = " ;
2437+
2438+ p << ' [' ;
2439+ llvm::interleaveComma (llvm::make_range (ops.begin (), ops.end ()), p,
2440+ [&](Value value) {
2441+ p.printOperand (value);
2442+ p << " : " << value.getType ();
2443+ if (*attrIt)
2444+ p << " (maybe_memory)" ;
2445+ attrIt++;
2446+ });
2447+ p << " ]," ;
2448+ p.printNewline ();
2449+ ++nameIt;
2450+ }
2451+
2452+ p << " {" ;
2453+ p.printString (getAsmString ());
2454+ p << " " ;
2455+ p.printString (getConstraints ());
2456+ p << " }" ;
2457+ p.decreaseIndent ();
2458+ p << ' )' ;
2459+ if (getSideEffects ())
2460+ p << " side_effects" ;
2461+
2462+ std::array elidedAttrs{
2463+ llvm::StringRef (" asm_flavor" ), llvm::StringRef (" asm_string" ),
2464+ llvm::StringRef (" constraints" ), llvm::StringRef (" operand_attrs" ),
2465+ llvm::StringRef (" operands_segments" ), llvm::StringRef (" side_effects" )};
2466+ p.printOptionalAttrDict (getOperation ()->getAttrs (), elidedAttrs);
2467+
2468+ if (auto v = getRes ())
2469+ p << " -> " << v.getType ();
2470+ }
2471+
2472+ void cir::InlineAsmOp::build (OpBuilder &odsBuilder, OperationState &odsState,
2473+ ArrayRef<ValueRange> asmOperands,
2474+ StringRef asmString, StringRef constraints,
2475+ bool sideEffects, cir::AsmFlavor asmFlavor,
2476+ ArrayRef<Attribute> operandAttrs) {
2477+ // Set up the operands_segments for VariadicOfVariadic
2478+ SmallVector<int32_t > segments;
2479+ for (auto operandRange : asmOperands) {
2480+ segments.push_back (operandRange.size ());
2481+ odsState.addOperands (operandRange);
2482+ }
2483+
2484+ odsState.addAttribute (
2485+ " operands_segments" ,
2486+ DenseI32ArrayAttr::get (odsBuilder.getContext (), segments));
2487+ odsState.addAttribute (" asm_string" , odsBuilder.getStringAttr (asmString));
2488+ odsState.addAttribute (" constraints" , odsBuilder.getStringAttr (constraints));
2489+ odsState.addAttribute (" asm_flavor" ,
2490+ AsmFlavorAttr::get (odsBuilder.getContext (), asmFlavor));
2491+
2492+ if (sideEffects)
2493+ odsState.addAttribute (" side_effects" , odsBuilder.getUnitAttr ());
2494+
2495+ odsState.addAttribute (" operand_attrs" , odsBuilder.getArrayAttr (operandAttrs));
2496+ }
2497+
2498+ ParseResult cir::InlineAsmOp::parse (OpAsmParser &parser,
2499+ OperationState &result) {
2500+ llvm::SmallVector<mlir::Attribute> operandAttrs;
2501+ llvm::SmallVector<int32_t > operandsGroupSizes;
2502+ std::string asmString, constraints;
2503+ Type resType;
2504+ MLIRContext *ctxt = parser.getBuilder ().getContext ();
2505+
2506+ auto error = [&](const Twine &msg) -> LogicalResult {
2507+ return parser.emitError (parser.getCurrentLocation (), msg);
2508+ };
2509+
2510+ auto expected = [&](const std::string &c) {
2511+ return error (" expected '" + c + " '" );
2512+ };
2513+
2514+ if (parser.parseLParen ().failed ())
2515+ return expected (" (" );
2516+
2517+ auto flavor = FieldParser<AsmFlavor, AsmFlavor>::parse (parser);
2518+ if (failed (flavor))
2519+ return error (" Unknown AsmFlavor" );
2520+
2521+ if (parser.parseComma ().failed ())
2522+ return expected (" ," );
2523+
2524+ auto parseValue = [&](Value &v) {
2525+ OpAsmParser::UnresolvedOperand op;
2526+
2527+ if (parser.parseOperand (op) || parser.parseColon ())
2528+ return error (" can't parse operand" );
2529+
2530+ Type typ;
2531+ if (parser.parseType (typ).failed ())
2532+ return error (" can't parse operand type" );
2533+ llvm::SmallVector<mlir::Value> tmp;
2534+ if (parser.resolveOperand (op, typ, tmp))
2535+ return error (" can't resolve operand" );
2536+ v = tmp[0 ];
2537+ return mlir::success ();
2538+ };
2539+
2540+ auto parseOperands = [&](llvm::StringRef name) {
2541+ if (parser.parseKeyword (name).failed ())
2542+ return error (" expected " + name + " operands here" );
2543+ if (parser.parseEqual ().failed ())
2544+ return expected (" =" );
2545+ if (parser.parseLSquare ().failed ())
2546+ return expected (" [" );
2547+
2548+ int size = 0 ;
2549+ if (parser.parseOptionalRSquare ().succeeded ()) {
2550+ operandsGroupSizes.push_back (size);
2551+ if (parser.parseComma ())
2552+ return expected (" ," );
2553+ return mlir::success ();
2554+ }
2555+
2556+ auto parseOperand = [&]() {
2557+ Value val;
2558+ if (parseValue (val).succeeded ()) {
2559+ result.operands .push_back (val);
2560+ size++;
2561+
2562+ if (parser.parseOptionalLParen ().failed ()) {
2563+ operandAttrs.push_back (mlir::Attribute ());
2564+ return mlir::success ();
2565+ }
2566+
2567+ if (parser.parseKeyword (" maybe_memory" ).succeeded ()) {
2568+ operandAttrs.push_back (mlir::UnitAttr::get (ctxt));
2569+ if (parser.parseRParen ())
2570+ return expected (" )" );
2571+ return mlir::success ();
2572+ } else {
2573+ return expected (" maybe_memory" );
2574+ }
2575+ }
2576+ return mlir::failure ();
2577+ };
2578+
2579+ if (parser.parseCommaSeparatedList (parseOperand).failed ())
2580+ return mlir::failure ();
2581+
2582+ if (parser.parseRSquare ().failed () || parser.parseComma ().failed ())
2583+ return expected (" ]" );
2584+ operandsGroupSizes.push_back (size);
2585+ return mlir::success ();
2586+ };
2587+
2588+ if (parseOperands (" out" ).failed () || parseOperands (" in" ).failed () ||
2589+ parseOperands (" in_out" ).failed ())
2590+ return error (" failed to parse operands" );
2591+
2592+ if (parser.parseLBrace ())
2593+ return expected (" {" );
2594+ if (parser.parseString (&asmString))
2595+ return error (" asm string parsing failed" );
2596+ if (parser.parseString (&constraints))
2597+ return error (" constraints string parsing failed" );
2598+ if (parser.parseRBrace ())
2599+ return expected (" }" );
2600+ if (parser.parseRParen ())
2601+ return expected (" )" );
2602+
2603+ if (parser.parseOptionalKeyword (" side_effects" ).succeeded ())
2604+ result.attributes .set (" side_effects" , UnitAttr::get (ctxt));
2605+
2606+ if (parser.parseOptionalArrow ().succeeded () &&
2607+ parser.parseType (resType).failed ())
2608+ return mlir::failure ();
2609+
2610+ if (parser.parseOptionalAttrDict (result.attributes ).failed ())
2611+ return mlir::failure ();
2612+
2613+ result.attributes .set (" asm_flavor" , AsmFlavorAttr::get (ctxt, *flavor));
2614+ result.attributes .set (" asm_string" , StringAttr::get (ctxt, asmString));
2615+ result.attributes .set (" constraints" , StringAttr::get (ctxt, constraints));
2616+ result.attributes .set (" operand_attrs" , ArrayAttr::get (ctxt, operandAttrs));
2617+ result.getOrAddProperties <InlineAsmOp::Properties>().operands_segments =
2618+ parser.getBuilder ().getDenseI32ArrayAttr (operandsGroupSizes);
2619+ if (resType)
2620+ result.addTypes (TypeRange{resType});
2621+
2622+ return mlir::success ();
2623+ }
2624+
24222625// ===----------------------------------------------------------------------===//
24232626// TableGen'd op method definitions
24242627// ===----------------------------------------------------------------------===//
0 commit comments