@@ -101,7 +101,8 @@ enum EltType {
101
101
Float16,
102
102
Float32,
103
103
Float64,
104
- BFloat16
104
+ BFloat16,
105
+ MFloat8 // Not used by Sema or CodeGen in Clang
105
106
};
106
107
107
108
} // end namespace NeonTypeFlags
@@ -143,14 +144,7 @@ class Type {
143
144
private:
144
145
TypeSpec TS;
145
146
146
- enum TypeKind {
147
- Void,
148
- Float,
149
- SInt,
150
- UInt,
151
- Poly,
152
- BFloat16
153
- };
147
+ enum TypeKind { Void, Float, SInt, UInt, Poly, BFloat16, MFloat8 };
154
148
TypeKind Kind;
155
149
bool Immediate, Constant, Pointer;
156
150
// ScalarForMangling and NoManglingQ are really not suited to live here as
@@ -203,6 +197,7 @@ class Type {
203
197
bool isLong () const { return isInteger () && ElementBitwidth == 64 ; }
204
198
bool isVoid () const { return Kind == Void; }
205
199
bool isBFloat16 () const { return Kind == BFloat16; }
200
+ bool isMFloat8 () const { return Kind == MFloat8; }
206
201
unsigned getNumElements () const { return Bitwidth / ElementBitwidth; }
207
202
unsigned getSizeInBits () const { return Bitwidth; }
208
203
unsigned getElementSizeInBits () const { return ElementBitwidth; }
@@ -657,6 +652,8 @@ std::string Type::str() const {
657
652
S += " float" ;
658
653
else if (isBFloat16 ())
659
654
S += " bfloat" ;
655
+ else if (isMFloat8 ())
656
+ S += " mfloat" ;
660
657
else
661
658
S += " int" ;
662
659
@@ -699,6 +696,9 @@ std::string Type::builtin_str() const {
699
696
else if (isBFloat16 ()) {
700
697
assert (ElementBitwidth == 16 && " BFloat16 can only be 16 bits" );
701
698
S += " y" ;
699
+ } else if (isMFloat8 ()) {
700
+ assert (ElementBitwidth == 8 && " MFloat8 can only be 8 bits" );
701
+ S += " m" ;
702
702
} else
703
703
switch (ElementBitwidth) {
704
704
case 16 : S += " h" ; break ;
@@ -758,6 +758,10 @@ unsigned Type::getNeonEnum() const {
758
758
Base = (unsigned )NeonTypeFlags::BFloat16;
759
759
}
760
760
761
+ if (isMFloat8 ()) {
762
+ Base = (unsigned )NeonTypeFlags::MFloat8;
763
+ }
764
+
761
765
if (Bitwidth == 128 )
762
766
Base |= (unsigned )NeonTypeFlags::QuadFlag;
763
767
if (isInteger () && !isSigned ())
@@ -779,6 +783,8 @@ Type Type::fromTypedefName(StringRef Name) {
779
783
T.Kind = Poly;
780
784
} else if (Name.consume_front (" bfloat" )) {
781
785
T.Kind = BFloat16;
786
+ } else if (Name.consume_front (" mfloat" )) {
787
+ T.Kind = MFloat8;
782
788
} else {
783
789
assert (Name.starts_with (" int" ));
784
790
Name = Name.drop_front (3 );
@@ -879,6 +885,10 @@ void Type::applyTypespec(bool &Quad) {
879
885
Kind = BFloat16;
880
886
ElementBitwidth = 16 ;
881
887
break ;
888
+ case ' m' :
889
+ Kind = MFloat8;
890
+ ElementBitwidth = 8 ;
891
+ break ;
882
892
default :
883
893
llvm_unreachable (" Unhandled type code!" );
884
894
}
@@ -993,6 +1003,9 @@ std::string Intrinsic::getInstTypeCode(Type T, ClassKind CK) const {
993
1003
if (T.isBFloat16 ())
994
1004
return " bf16" ;
995
1005
1006
+ if (T.isMFloat8 ())
1007
+ return " mfp8" ;
1008
+
996
1009
if (T.isPoly ())
997
1010
typeCode = ' p' ;
998
1011
else if (T.isInteger ())
@@ -1030,7 +1043,7 @@ std::string Intrinsic::getBuiltinTypeStr() {
1030
1043
1031
1044
Type RetT = getReturnType ();
1032
1045
if ((LocalCK == ClassI || LocalCK == ClassW) && RetT.isScalar () &&
1033
- !RetT.isFloating () && !RetT.isBFloat16 ())
1046
+ !RetT.isFloating () && !RetT.isBFloat16 () && !RetT. isMFloat8 () )
1034
1047
RetT.makeInteger (RetT.getElementSizeInBits (), false );
1035
1048
1036
1049
// Since the return value must be one type, return a vector type of the
@@ -2270,7 +2283,7 @@ static void emitNeonTypeDefs(const std::string& types, raw_ostream &OS) {
2270
2283
for (auto &TS : TDTypeVec) {
2271
2284
bool IsA64 = false ;
2272
2285
Type T (TS, " ." );
2273
- if (T.isDouble ())
2286
+ if (T.isDouble () || T. isMFloat8 () )
2274
2287
IsA64 = true ;
2275
2288
2276
2289
if (InIfdef && !IsA64) {
@@ -2282,15 +2295,20 @@ static void emitNeonTypeDefs(const std::string& types, raw_ostream &OS) {
2282
2295
InIfdef = true ;
2283
2296
}
2284
2297
2285
- if (T.isPoly ())
2298
+ if (T.isMFloat8 ())
2299
+ OS << " typedef __MFloat8x" ;
2300
+ else if (T.isPoly ())
2286
2301
OS << " typedef __attribute__((neon_polyvector_type(" ;
2287
2302
else
2288
2303
OS << " typedef __attribute__((neon_vector_type(" ;
2289
2304
2290
2305
Type T2 = T;
2291
2306
T2.makeScalar ();
2292
- OS << T.getNumElements () << " ))) " ;
2293
- OS << T2.str ();
2307
+ OS << T.getNumElements ();
2308
+ if (T.isMFloat8 ())
2309
+ OS << " _t " ;
2310
+ else
2311
+ OS << " ))) " << T2.str ();
2294
2312
OS << " " << T.str () << " ;\n " ;
2295
2313
}
2296
2314
if (InIfdef)
@@ -2303,7 +2321,7 @@ static void emitNeonTypeDefs(const std::string& types, raw_ostream &OS) {
2303
2321
for (auto &TS : TDTypeVec) {
2304
2322
bool IsA64 = false ;
2305
2323
Type T (TS, " ." );
2306
- if (T.isDouble ())
2324
+ if (T.isDouble () || T. isMFloat8 () )
2307
2325
IsA64 = true ;
2308
2326
2309
2327
if (InIfdef && !IsA64) {
@@ -2589,8 +2607,6 @@ void NeonEmitter::runVectorTypes(raw_ostream &OS) {
2589
2607
2590
2608
OS << " #if defined(__aarch64__) || defined(__arm64ec__)\n " ;
2591
2609
OS << " typedef __mfp8 mfloat8_t;\n " ;
2592
- OS << " typedef __MFloat8x8_t mfloat8x8_t;\n " ;
2593
- OS << " typedef __MFloat8x16_t mfloat8x16_t;\n " ;
2594
2610
OS << " typedef double float64_t;\n " ;
2595
2611
OS << " #endif\n\n " ;
2596
2612
@@ -2648,7 +2664,7 @@ __arm_set_fpm_lscale2(fpm_t __fpm, uint64_t __scale) {
2648
2664
2649
2665
)" ;
2650
2666
2651
- emitNeonTypeDefs (" cQcsQsiQilQlUcQUcUsQUsUiQUiUlQUlhQhfQfdQd " , OS);
2667
+ emitNeonTypeDefs (" cQcsQsiQilQlUcQUcUsQUsUiQUiUlQUlmQmhQhfQfdQd " , OS);
2652
2668
2653
2669
emitNeonTypeDefs (" bQb" , OS);
2654
2670
OS << " #endif // __ARM_NEON_TYPES_H\n " ;
0 commit comments