@@ -24,25 +24,85 @@ def LLZK_FeltConstAttr
2424 A felt attribute represents a finite field element.
2525 }];
2626
27- let parameters = (ins APIntParameter<"The felt constant value">:$value);
27+ let parameters = (ins APIntParameter<"The felt constant value">:$value,
28+ OptionalParameter<"::mlir::StringAttr">:$fieldName);
2829
29- let returnType = "::llvm::APInt";
30- let convertFromStorage = "$_self.getValue()";
31-
32- let assemblyFormat = [{ $value }];
30+ let assemblyFormat = [{ $value ( ` ` `<` $fieldName^ `>` )? }];
3331
3432 let builders =
35- [AttrBuilder<(ins "unsigned":$numBits, "::llvm::StringRef":$str), [{
36- return $_get(context, ::llvm::APInt(numBits, str, 10));
37- }]>,
33+ [AttrBuilder<(ins "unsigned":$numBits, "::llvm::StringRef":$str,
34+ "::llvm::StringRef":$fieldName),
35+ [{
36+ return $_get(context, ::llvm::APInt(numBits, str, 10), ::mlir::StringAttr::get(context, fieldName));
37+ }]>,
38+ AttrBuilder<(ins "unsigned":$numBits,
39+ "::llvm::ArrayRef<uint64_t>":$parts,
40+ "::llvm::StringRef":$fieldName),
41+ [{
42+ return $_get(context, ::llvm::APInt(numBits, parts), ::mlir::StringAttr::get(context, fieldName));
43+ }]>,
44+ AttrBuilder<(ins "unsigned":$numBits, "::llvm::StringRef":$str), [{
45+ return $_get(context, ::llvm::APInt(numBits, str, 10), ::mlir::StringAttr());
46+ }]>,
3847 AttrBuilder<
3948 (ins "unsigned":$numBits, "::llvm::ArrayRef<uint64_t>":$parts), [{
40- return $_get(context, ::llvm::APInt(numBits, parts));
41- }]>];
49+ return $_get(context, ::llvm::APInt(numBits, parts), ::mlir::StringAttr());
50+ }]>,
51+ AttrBuilder<(ins "::llvm::APInt":$value, "::llvm::StringRef":$fieldName),
52+ [{
53+ return $_get(context, value, ::mlir::StringAttr::get(context, fieldName));
54+ }]>,
55+ AttrBuilder<(ins "::llvm::APInt":$value), [{
56+ return $_get(context, value, ::mlir::StringAttr());
57+ }]>];
4258
4359 let extraClassDeclaration = [{
4460 ::mlir::Type getType() const;
61+
62+ operator ::llvm::APInt() const;
63+ }];
64+
65+ let genVerifyDecl = 1;
66+ }
67+
68+ def LLZK_FieldSpecAttr : AttrDef<FeltDialect, "FieldSpec"> {
69+ let mnemonic = "field";
70+ let summary = "prime field specification";
71+ let description = [{
72+ A specification of a prime field for use by felt types.
73+
74+ These specifications are provided in the `llzk.fields` attribute on the root
75+ module as either a single element or a flat array, for example:
76+
77+ module attributes {llzk.lang, llzk.fields = field<foo, 7> { ... }
78+ module attributes {llzk.lang, llzk.fields = [field<>]} { ... }
79+
80+ Specifications should not be provided for built-in fields, which include:
81+ - babybear
82+ - bn128/bn254
83+ - goldilocks
84+ - koalabear
85+ - mersenne31
4586 }];
87+
88+ let parameters = (ins "::mlir::StringAttr":$fieldName,
89+ APIntParameter<"The prime modulus">:$prime);
90+
91+ // Format is [{ `<` $fieldName `,` $prime `>` }], but with custom parsing
92+ // to enable caching of the Field object definition.
93+ let hasCustomAssemblyFormat = 1;
94+
95+ let builders =
96+ [AttrBuilder<(ins "::llvm::StringRef":$fieldName, "unsigned":$numBits,
97+ "::llvm::StringRef":$primeStr),
98+ [{
99+ return $_get(context, ::mlir::StringAttr::get(context, fieldName), ::llvm::APInt(numBits, primeStr, 10));
100+ }]>,
101+ AttrBuilder<(ins "::llvm::StringRef":$fieldName, "unsigned":$numBits,
102+ "::llvm::ArrayRef<uint64_t>":$parts),
103+ [{
104+ return $_get(context, ::mlir::StringAttr::get(context, fieldName), ::llvm::APInt(numBits, parts));
105+ }]>];
46106}
47107
48108#endif // LLZK_FELT_ATTRS
0 commit comments