@@ -2254,6 +2254,87 @@ def CIR_StackRestoreOp : CIR_Op<"stackrestore"> {
22542254 let assemblyFormat = "$ptr attr-dict `:` qualified(type($ptr))";
22552255}
22562256
2257+ //===----------------------------------------------------------------------===//
2258+ // InlineAsmOp
2259+ //===----------------------------------------------------------------------===//
2260+
2261+ def CIR_AsmFlavor : CIR_I32EnumAttr<"AsmFlavor", "ATT or Intel",
2262+ [I32EnumAttrCase<"x86_att", 0>,
2263+ I32EnumAttrCase<"x86_intel", 1>]>;
2264+
2265+ def CIR_InlineAsmOp : CIR_Op<"asm", [RecursiveMemoryEffects]> {
2266+ let description = [{
2267+ The `cir.asm` operation represents C/C++ asm inline.
2268+
2269+ CIR constraints strings follow the same rules that are established for
2270+ the C level assembler constraints with several differences caused by
2271+ clang::AsmStmt processing.
2272+
2273+ Thus, numbers that appears in the constraint string may also refer to:
2274+ - the output variable index referenced by the input operands.
2275+ - the index of early-clobber operand
2276+
2277+ Operand attributes are a storage, where each element corresponds to the
2278+ operand with the same index. The first index relates to the operation
2279+ result (if any).
2280+ The operands themselves are stored as VariadicOfVariadic in the following
2281+ order: output, input and then in/out operands. When several output operands
2282+ are present, the result type may be represented as an anonymous record type.
2283+
2284+ Example:
2285+ ```C++
2286+ __asm__("foo" : : : );
2287+ __asm__("bar $42 %[val]" : [val] "=r" (x), "+&r"(x));
2288+ __asm__("baz $42 %[val]" : [val] "=r" (x), "+&r"(x) : "[val]"(y));
2289+ ```
2290+
2291+ ```mlir
2292+ !rec_22anon2E022 = !cir.record<struct "anon.0" {!cir.int<s, 32>, !cir.int<s, 32>}>
2293+ !rec_22anon2E122 = !cir.record<struct "anon.1" {!cir.int<s, 32>, !cir.int<s, 32>}>
2294+ ...
2295+ %0 = cir.alloca !s32i, !cir.ptr<!s32i>, ["x", init]
2296+ %1 = cir.alloca !s32i, !cir.ptr<!s32i>, ["y", init]
2297+ ...
2298+ %2 = cir.load %0 : !cir.ptr<!s32i>, !s32i
2299+ %3 = cir.load %1 : !cir.ptr<!s32i>, !s32i
2300+
2301+ cir.asm(x86_att,
2302+ out = [],
2303+ in = [],
2304+ in_out = [],
2305+ {"foo" "~{dirflag},~{fpsr},~{flags}"}) side_effects
2306+
2307+ cir.asm(x86_att,
2308+ out = [],
2309+ in = [],
2310+ in_out = [%2 : !s32i],
2311+ {"bar $$42 $0" "=r,=&r,1,~{dirflag},~{fpsr},~{flags}"}) -> !rec_22anon2E022
2312+
2313+ cir.asm(x86_att,
2314+ out = [],
2315+ in = [%3 : !s32i],
2316+ in_out = [%2 : !s32i],
2317+ {"baz $$42 $0" "=r,=&r,0,1,~{dirflag},~{fpsr},~{flags}"}) -> !rec_22anon2E122
2318+ ```
2319+ }];
2320+
2321+ let results = (outs Optional<CIR_AnyType>:$res);
2322+
2323+ let arguments =
2324+ (ins VariadicOfVariadic<AnyType, "operands_segments">:$asm_operands,
2325+ StrAttr:$asm_string, StrAttr:$constraints, UnitAttr:$side_effects,
2326+ CIR_AsmFlavor:$asm_flavor, ArrayAttr:$operand_attrs,
2327+ DenseI32ArrayAttr:$operands_segments);
2328+
2329+ let builders = [OpBuilder<(ins
2330+ "llvm::ArrayRef<mlir::ValueRange>":$asmOperands,
2331+ "llvm::StringRef":$asmString, "llvm::StringRef":$constraints,
2332+ "bool":$sideEffects, "AsmFlavor":$asmFlavor,
2333+ "llvm::ArrayRef<mlir::Attribute>":$operandAttrs)>];
2334+
2335+ let hasCustomAssemblyFormat = 1;
2336+ }
2337+
22572338//===----------------------------------------------------------------------===//
22582339// UnreachableOp
22592340//===----------------------------------------------------------------------===//
0 commit comments