123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578openBaseopenPpxlibmodulePattern=structopenAst_patternletfailure~locfmt=Stdlib.Format.kasprintf(funs->Error(Location.Error.make~loc~sub:[]s))fmt;;letbad_name~locsexpected=failure~loc"Argument '%s' must be one of [%s]."s(Base.String.concat~sep:","expected);;leteint_range~max=map'(eint__)~f:(funlocfx->(ifx<0||x>=maxthenfailure~loc"Argument '%d' must be in range [0,%d]."x(max-1)elseOkx)|>f);;letetwoints_range~max=letopenResult.Let_syntaxinpstr(pstr_eval(pexp_tuple(eint_range~max^::eint_range~max^::nil))nil^::nil)|>map~f:(funfab->(let%mapaandbina,b)|>f);;letetwoxtwoints_range~max=letopenResult.Let_syntaxinpstr(pstr_eval(pexp_tuple(pexp_tuple(eint_range~max^::eint_range~max^::nil)^::pexp_tuple(eint_range~max^::eint_range~max^::nil)^::nil))nil^::nil)|>map~f:(funfabcd->(let%mapaandbandcanddina,b,c,d)|>f);;letefourints_range~max=letopenResult.Let_syntaxinpstr(pstr_eval(pexp_tuple(eint_range~max^::eint_range~max^::eint_range~max^::eint_range~max^::nil))nil^::nil)|>map~f:(funfabcd->(let%mapaandbandcanddina,b,c,d)|>f);;leteeightints_range~max=letopenResult.Let_syntaxinpstr(pstr_eval(pexp_tuple(eint_range~max^::eint_range~max^::eint_range~max^::eint_range~max^::eint_range~max^::eint_range~max^::eint_range~max^::eint_range~max^::nil))nil^::nil)|>map~f:(funffabcdefgh->(let%mapaandbandcanddandeandfandgandhina,b,c,d,e,f,g,h)|>ff);;moduleBlend=structtypeargs=|Twoofint*int|Fourofint*int*int*int|Eightofint*int*int*int*int*int*int*intletpack=function|Two(a,b)->`Two,alor(blsl1)|Four(a,b,c,d)->`Four,alor(blsl1)lor(clsl2)lor(dlsl3)|Eight(a,b,c,d,e,f,g,h)->(`Eight,alor(blsl1)lor(clsl2)lor(dlsl3)lor(elsl4)lor(flsl5)lor(glsl6)lor(hlsl7));;letetwo~max=etwoints_range~max|>map~f:(funfints->f(Result.mapints~f:(fun(a,b)->Two(a,b))));;letefour~max=efourints_range~max|>map~f:(funfints->f(Result.mapints~f:(fun(a,b,c,d)->Four(a,b,c,d))));;leteeight~max=eeightints_range~max|>map~f:(funfints->f(Result.mapints~f:(fun(a,b,c,d,e,f,g,h)->Eight(a,b,c,d,e,f,g,h))));;letpattern=etwo~max:2|||efour~max:2|||eeight~max:2endmoduleShuffle_or_permute=structtypeargs=|Twoofint*int|TwoxTwoofint*int*int*int|Fourofint*int*int*intletpack=function|Two(a,b)->`Two,alor(blsl1)|TwoxTwo(a,b,c,d)->`TwoxTwo,alor(blsl1)lor(clsl2)lor(dlsl3)|Four(a,b,c,d)->`Four,alor(blsl2)lor(clsl4)lor(dlsl6);;letetwo~max=etwoints_range~max|>map~f:(funfints->f(Result.mapints~f:(fun(a,b)->Two(a,b))));;letetwoxtwo~max=etwoxtwoints_range~max|>map~f:(funfints->f(Result.mapints~f:(fun(a,b,c,d)->TwoxTwo(a,b,c,d))));;letefour~max=efourints_range~max|>map~f:(funfints->f(Result.mapints~f:(fun(a,b,c,d)->Four(a,b,c,d))));;letpattern=etwo~max:2|||etwoxtwo~max:2|||efour~max:4endmoduleString=structopenOcaml_simd.StringmoduleConst=struct(** See the Intel SDM, Volume 2, Chapter 4.1: "IMM8 Control Byte Operation for
PCMPESTRI / PCMPESTRM / PCMPISTRI / PCMPISTRM" *)letubyte_data=0b0000_0000letuword_data=0b0000_0001letsbyte_data=0b0000_0010letsword_data=0b0000_0011letcmp_equal_any=0b0000_0000letcmp_ranges=0b0000_0100letcmp_equal_each=0b0000_1000letcmp_equal_ordered=0b0000_1100letpositive_polarity=0b0000_0000letnegative_polarity=0b0001_0000letmasked_negative_polarity=0b0011_0000letmasked_positive_polarity=0b0010_0000letleast_significant=0b0000_0000letmost_significant=0b0100_0000letbit_mask=0b0000_0000letunit_mask=0b0100_0000endtypeargs=|PlainofSigned.t*Comparison.t*Polarity.t|IndexedofSigned.t*Comparison.t*Polarity.t*Index.t|MaskedofSigned.t*Comparison.t*Polarity.t*Mask.tletsigned~size(signed:Signed.t)=matchsize,signedwith|`Byte,Signed->Const.sbyte_data|`Word,Signed->Const.sword_data|`Byte,Unsigned->Const.ubyte_data|`Word,Unsigned->Const.uword_data;;letcomparison:Comparison.t->int=function|Eq_any->Const.cmp_equal_any|Eq_each->Const.cmp_equal_each|Eq_ordered->Const.cmp_equal_ordered|In_range->Const.cmp_ranges;;letpolarity:Polarity.t->int=function|Pos->Const.positive_polarity|Neg->Const.negative_polarity|Masked_pos->Const.masked_positive_polarity|Masked_neg->Const.masked_negative_polarity;;letindex:Index.t->int=function|Least_sig->Const.least_significant|Most_sig->Const.most_significant;;letmask:Mask.t->int=function|Bit_mask->Const.bit_mask|Vec_mask->Const.unit_mask;;letpack~size=function|Plain(s,c,p)->`Plain,signed~sizeslorcomparisonclorpolarityp|Indexed(s,c,p,i)->`Indexed,signed~sizeslorcomparisonclorpolarityplorindexi|Masked(s,c,p,m)->`Masked,signed~sizeslorcomparisonclorpolarityplormaskm;;letesigned()=letopenOcaml_simd.String.Signedinpexp_construct(lident__)none|>map'~f:(funlocfs->matchswith|"Signed"->f(OkSigned)|"Unsigned"->f(OkUnsigned)|_->f(bad_name~locs["Signed";"Unsigned"]));;letecomparison()=letopenOcaml_simd.String.Comparisoninpexp_construct(lident__)none|>map'~f:(funlocfs->matchswith|"Eq_any"->f(OkEq_any)|"Eq_each"->f(OkEq_each)|"Eq_ordered"->f(OkEq_ordered)|"In_range"->f(OkIn_range)|_->f(bad_name~locs["Eq_any";"Eq_each";"Eq_ordered";"In_range"]));;letepolarity()=letopenOcaml_simd.String.Polarityinpexp_construct(lident__)none|>map'~f:(funlocfs->matchswith|"Pos"->f(OkPos)|"Neg"->f(OkNeg)|"Masked_pos"->f(OkMasked_pos)|"Masked_neg"->f(OkMasked_neg)|_->f(bad_name~locs["Pos";"Neg";"Masked_pos";"Masked_neg"]));;leteindexmask()=letopenOcaml_simd.String.MaskinletopenOcaml_simd.String.Indexinpexp_construct(lident__)none|>map'~f:(funlocfs->matchswith|"Bit_mask"->f(Ok(`MaskBit_mask))|"Vec_mask"->f(Ok(`MaskVec_mask))|"Least_sig"->f(Ok(`IndexLeast_sig))|"Most_sig"->f(Ok(`IndexMost_sig))|_->f(bad_name~locs["Least_sig";"Most_sig";"Bit_mask";"Vec_mask"]));;letesigned_comparison_polarity=letopenResult.Let_syntaxinpstr(pstr_eval(pexp_tuple(esigned()^::ecomparison()^::epolarity()^::nil))nil^::nil)|>map~f:(funfscp->(let%mapsandcandpinPlain(s,c,p))|>f);;letesigned_comparison_polarity_indexmask=letopenResult.Let_syntaxinpstr(pstr_eval(pexp_tuple(esigned()^::ecomparison()^::epolarity()^::eindexmask()^::nil))nil^::nil)|>map~f:(funfscpim->(let%mapsandcandpandiminmatchimwith|`Maskm->Masked(s,c,p,m)|`Indexi->Indexed(s,c,p,i))|>f);;letpattern=esigned_comparison_polarity|||esigned_comparison_polarity_indexmaskendmoduleComparison=structopenOcaml_simd.Float.ComparisonmoduleConst=struct(** See the Intel SDM, Volume 2, Table 3-1: "Comparison Predicate for CMPPD and
CMPPS Instructions" *)letequal=0x0letless=0x1letless_or_equal=0x2letunordered=0x3letnot_equal=0x4letnot_less=0x5letnot_less_or_equal=0x6letordered=0x7endletpack=function|Equal->Const.equal|Less->Const.less|Less_or_equal->Const.less_or_equal|Unordered->Const.unordered|Not_equal->Const.not_equal|Not_less->Const.not_less|Not_less_or_equal->Const.not_less_or_equal|Ordered->Const.ordered;;letecomparison=pstr(pstr_eval(pexp_construct(lident__)none|>map'~f:(funlocfs->matchswith|"Equal"->f(OkEqual)|"Less"->f(OkLess)|"Less_or_equal"->f(OkLess_or_equal)|"Unordered"->f(OkUnordered)|"Not_equal"->f(OkNot_equal)|"Not_less"->f(OkNot_less)|"Not_less_or_equal"->f(OkNot_less_or_equal)|"Ordered"->f(OkOrdered)|_->f(bad_name~locs["Equal";"Less";"Less_or_equal";"Unordered";"Not_equal";"Not_less";"Not_less_or_equal";"Ordered"])))nil^::nil);;letpattern=ecomparisonendmoduleRounding=structopenOcaml_simd.Float.RoundingmoduleConst=struct(** See the Intel SDM, Volume 2, Figure 4-24 / Table 4-18: "Rounding Modes and
Encoding of Rounding Control (RC) Field" *)letnearest=0x8letnegative_infinity=0x9letpositive_infinity=0xAletzero=0xBletcurrent=0xCendletpack=function|Nearest->Const.nearest|Negative_infinity->Const.negative_infinity|Positive_infinity->Const.positive_infinity|Zero->Const.zero|Current->Const.current;;leterounding=letopenOcaml_simd.Float.Roundinginpstr(pstr_eval(pexp_construct(lident__)none|>map'~f:(funlocfs->matchswith|"Nearest"->f(OkNearest)|"Negative_infinity"->f(OkNegative_infinity)|"Positive_infinity"->f(OkPositive_infinity)|"Zero"->f(OkZero)|"Current"->f(OkCurrent)|_->f(bad_name~locs["Nearest";"Negative_infinity";"Positive_infinity";"Zero";"Current"])))nil^::nil);;letpattern=eroundingendendmoduleBlend=structletextension=letopenAst_builder.DefaultinExtension.declare"simd.blend"Extension.Context.expressionPattern.Blend.pattern(fun~loc~path:_blend->Merlin_helpers.hide_expression(matchblendwith|Errorerr->pexp_extension~loc(Location.Error.to_extensionerr)|Okblend->letkind,imm=Pattern.Blend.packblendinletimm=eint~locimmin(matchkindwith|`Two->[%expr(Obj.magic[%eimm]:Ocaml_simd.Blend2.t)]|`Four->[%expr(Obj.magic[%eimm]:Ocaml_simd.Blend4.t)]|`Eight->[%expr(Obj.magic[%eimm]:Ocaml_simd.Blend8.t)])));;endmoduleShuffle=structletextension=letopenAst_builder.DefaultinExtension.declare"simd.shuffle"Extension.Context.expressionPattern.Shuffle_or_permute.pattern(fun~loc~path:_shuffle->Merlin_helpers.hide_expression(matchshufflewith|Errorerr->pexp_extension~loc(Location.Error.to_extensionerr)|Okshuffle->letkind,imm=Pattern.Shuffle_or_permute.packshuffleinletimm=eint~locimmin(matchkindwith|`Two->[%expr(Obj.magic[%eimm]:Ocaml_simd.Shuffle2.t)]|`TwoxTwo->[%expr(Obj.magic[%eimm]:Ocaml_simd.Shuffle2x2.t)]|`Four->[%expr(Obj.magic[%eimm]:Ocaml_simd.Shuffle4.t)])));;endmodulePermute=structletextension=letopenAst_builder.DefaultinExtension.declare"simd.permute"Extension.Context.expressionPattern.Shuffle_or_permute.pattern(fun~loc~path:_permute->Merlin_helpers.hide_expression(matchpermutewith|Errorerr->pexp_extension~loc(Location.Error.to_extensionerr)|Okpermute->letkind,imm=Pattern.Shuffle_or_permute.packpermuteinletimm=eint~locimmin(matchkindwith|`Two->[%expr(Obj.magic[%eimm]:Ocaml_simd.Permute2.t)]|`TwoxTwo->[%expr(Obj.magic[%eimm]:Ocaml_simd.Permute2x2.t)]|`Four->[%expr(Obj.magic[%eimm]:Ocaml_simd.Permute4.t)])));;endmoduleString=structletextension~size~loc~path:_=letopenAst_builder.Defaultinfunction|Errorerr->pexp_extension~loc(Location.Error.to_extensionerr)|Okstr->letkind,imm=Pattern.String.pack~sizestrinletimm=eint~locimmin(matchsize,kindwith|`Byte,`Plain->[%expr(Obj.magic[%eimm]:Ocaml_simd.String.Bytes.t)]|`Byte,`Indexed->[%expr(Obj.magic[%eimm]:Ocaml_simd.String.Bytesi.t)]|`Byte,`Masked->[%expr(Obj.magic[%eimm]:Ocaml_simd.String.Bytesm.t)]|`Word,`Plain->[%expr(Obj.magic[%eimm]:Ocaml_simd.String.Words.t)]|`Word,`Indexed->[%expr(Obj.magic[%eimm]:Ocaml_simd.String.Wordsi.t)]|`Word,`Masked->[%expr(Obj.magic[%eimm]:Ocaml_simd.String.Wordsm.t)])|>Merlin_helpers.hide_expression;;letbyte_extension=Extension.declare"simd.bytes"Extension.Context.expressionPattern.String.pattern(extension~size:`Byte);;letword_extension=Extension.declare"simd.words"Extension.Context.expressionPattern.String.pattern(extension~size:`Word);;endmoduleComparison=structletextension=letopenAst_builder.DefaultinExtension.declare"simd.float_compare"Extension.Context.expressionPattern.Comparison.pattern(fun~loc~path:_comparison->Merlin_helpers.hide_expression(matchcomparisonwith|Errorerr->pexp_extension~loc(Location.Error.to_extensionerr)|Okcomparison->letimm=Pattern.Comparison.packcomparisoninletimm=eint~locimmin[%expr(Obj.magic[%eimm]:Ocaml_simd.Float.Comparison.t)]));;endmoduleRounding=structletextension=letopenAst_builder.DefaultinExtension.declare"simd.float_round"Extension.Context.expressionPattern.Rounding.pattern(fun~loc~path:_rounding->Merlin_helpers.hide_expression(matchroundingwith|Errorerr->pexp_extension~loc(Location.Error.to_extensionerr)|Okrounding->letimm=Pattern.Rounding.packroundinginletimm=eint~locimmin[%expr(Obj.magic[%eimm]:Ocaml_simd.Float.Rounding.t)]));;endlet()=Driver.register_transformation"simd"~extensions:[Comparison.extension;Rounding.extension;Blend.extension;Shuffle.extension;Permute.extension;String.byte_extension;String.word_extension];;