diff --git a/clang/utils/TableGen/NeonEmitter.cpp b/clang/utils/TableGen/NeonEmitter.cpp --- a/clang/utils/TableGen/NeonEmitter.cpp +++ b/clang/utils/TableGen/NeonEmitter.cpp @@ -140,7 +140,15 @@ private: TypeSpec TS; - bool Float, Signed, Immediate, Void, Poly, Constant, Pointer; + enum TypeKind { + Void, + Float, + SInt, + UInt, + Poly, + }; + TypeKind Kind; + bool Immediate, Constant, Pointer; // ScalarForMangling and NoManglingQ are really not suited to live here as // they are not related to the type. But they live in the TypeSpec (not the // prototype), so this is really the only place to store them. @@ -149,15 +157,14 @@ public: Type() - : Float(false), Signed(false), Immediate(false), Void(true), Poly(false), - Constant(false), Pointer(false), ScalarForMangling(false), - NoManglingQ(false), Bitwidth(0), ElementBitwidth(0), NumVectors(0) {} + : Kind(Void), Immediate(false), Constant(false), + Pointer(false), ScalarForMangling(false), NoManglingQ(false), + Bitwidth(0), ElementBitwidth(0), NumVectors(0) {} Type(TypeSpec TS, char CharMod) - : TS(std::move(TS)), Float(false), Signed(false), Immediate(false), - Void(false), Poly(false), Constant(false), Pointer(false), - ScalarForMangling(false), NoManglingQ(false), Bitwidth(0), - ElementBitwidth(0), NumVectors(0) { + : TS(std::move(TS)), Kind(Void), Immediate(false), + Constant(false), Pointer(false), ScalarForMangling(false), + NoManglingQ(false), Bitwidth(0), ElementBitwidth(0), NumVectors(0) { applyModifier(CharMod); } @@ -174,21 +181,21 @@ bool noManglingQ() const { return NoManglingQ; } bool isPointer() const { return Pointer; } - bool isFloating() const { return Float; } - bool isInteger() const { return !Float && !Poly; } - bool isSigned() const { return Signed; } + bool isFloating() const { return Kind == Float; } + bool isInteger() const { return Kind == SInt || Kind == UInt; } + bool isPoly() const { return Kind == Poly; } + bool isSigned() const { return Kind == SInt; } bool isImmediate() const { return Immediate; } bool isScalar() const { return NumVectors == 0; } bool isVector() const { return NumVectors > 0; } - bool isFloat() const { return Float && ElementBitwidth == 32; } - bool isDouble() const { return Float && ElementBitwidth == 64; } - bool isHalf() const { return Float && ElementBitwidth == 16; } - bool isPoly() const { return Poly; } + bool isFloat() const { return isFloating() && ElementBitwidth == 32; } + bool isDouble() const { return isFloating() && ElementBitwidth == 64; } + bool isHalf() const { return isFloating() && ElementBitwidth == 16; } bool isChar() const { return ElementBitwidth == 8; } - bool isShort() const { return !Float && ElementBitwidth == 16; } - bool isInt() const { return !Float && ElementBitwidth == 32; } - bool isLong() const { return !Float && ElementBitwidth == 64; } - bool isVoid() const { return Void; } + bool isShort() const { return isInteger() && ElementBitwidth == 16; } + bool isInt() const { return isInteger() && ElementBitwidth == 32; } + bool isLong() const { return isInteger() && ElementBitwidth == 64; } + bool isVoid() const { return Kind == Void; } unsigned getNumElements() const { return Bitwidth / ElementBitwidth; } unsigned getSizeInBits() const { return Bitwidth; } unsigned getElementSizeInBits() const { return ElementBitwidth; } @@ -197,21 +204,24 @@ // // Mutator functions // - void makeUnsigned() { Signed = false; } - void makeSigned() { Signed = true; } + void makeUnsigned() { + assert(isInteger() && "not a potentially signed type"); + Kind = UInt; + } + void makeSigned() { + assert(isInteger() && "not a potentially signed type"); + Kind = SInt; + } void makeInteger(unsigned ElemWidth, bool Sign) { - Float = false; - Poly = false; - Signed = Sign; + assert(!isVoid() && "converting void to int probably not useful"); + Kind = Sign ? SInt : UInt; Immediate = false; ElementBitwidth = ElemWidth; } void makeImmediate(unsigned ElemWidth) { - Float = false; - Poly = false; - Signed = true; + Kind = SInt; Immediate = true; ElementBitwidth = ElemWidth; } @@ -257,7 +267,7 @@ /// seen. This is needed by applyModifier as some modifiers /// only take effect if the type size was changed by "Q" or "H". void applyTypespec(bool &Quad); - /// Applies a prototype modifier to the type. + /// Applies a prototype modifiers to the type. void applyModifier(char Mod); }; @@ -582,16 +592,16 @@ //===----------------------------------------------------------------------===// std::string Type::str() const { - if (Void) + if (isVoid()) return "void"; std::string S; - if (!Signed && isInteger()) + if (isInteger() && !isSigned()) S += "u"; - if (Poly) + if (isPoly()) S += "poly"; - else if (Float) + else if (isFloating()) S += "float"; else S += "int"; @@ -639,7 +649,7 @@ if (isChar() && !Pointer) // Make chars explicitly signed. S = "S" + S; - else if (isInteger() && !Pointer && !Signed) + else if (!isPointer() && isInteger() && !isSigned()) S = "U" + S; // Constant indices are "int", but have the "constant expression" modifier. @@ -673,20 +683,20 @@ } unsigned Base = (unsigned)NeonTypeFlags::Int8 + Addend; - if (Poly) { + if (isPoly()) { // Adjustment needed because Poly32 doesn't exist. if (Addend >= 2) --Addend; Base = (unsigned)NeonTypeFlags::Poly8 + Addend; } - if (Float) { + if (isFloating()) { assert(Addend != 0 && "Float8 doesn't exist!"); Base = (unsigned)NeonTypeFlags::Float16 + (Addend - 1); } if (Bitwidth == 128) Base |= (unsigned)NeonTypeFlags::QuadFlag; - if (isInteger() && !Signed) + if (isInteger() && !isSigned()) Base |= (unsigned)NeonTypeFlags::UnsignedFlag; return Base; @@ -694,22 +704,18 @@ Type Type::fromTypedefName(StringRef Name) { Type T; - T.Void = false; - T.Float = false; - T.Poly = false; + T.Kind = SInt; if (Name.front() == 'u') { - T.Signed = false; + T.Kind = UInt; Name = Name.drop_front(); - } else { - T.Signed = true; } if (Name.startswith("float")) { - T.Float = true; + T.Kind = Float; Name = Name.drop_front(5); } else if (Name.startswith("poly")) { - T.Poly = true; + T.Kind = Poly; Name = Name.drop_front(4); } else { assert(Name.startswith("int")); @@ -760,10 +766,8 @@ void Type::applyTypespec(bool &Quad) { std::string S = TS; ScalarForMangling = false; - Void = false; - Poly = Float = false; + Kind = SInt; ElementBitwidth = ~0U; - Signed = true; NumVectors = 1; for (char I : S) { @@ -779,28 +783,28 @@ Quad = true; break; case 'P': - Poly = true; + Kind = Poly; break; case 'U': - Signed = false; + Kind = UInt; break; case 'c': ElementBitwidth = 8; break; case 'h': - Float = true; + Kind = Float; LLVM_FALLTHROUGH; case 's': ElementBitwidth = 16; break; case 'f': - Float = true; + Kind = Float; LLVM_FALLTHROUGH; case 'i': ElementBitwidth = 32; break; case 'd': - Float = true; + Kind = Float; LLVM_FALLTHROUGH; case 'l': ElementBitwidth = 64; @@ -808,7 +812,7 @@ case 'k': ElementBitwidth = 128; // Poly doesn't have a 128x1 type. - if (Poly) + if (isPoly()) NumVectors = 0; break; default: @@ -826,97 +830,84 @@ switch (Mod) { case 'v': - Void = true; + Kind = Void; break; case 't': - if (Poly) { - Poly = false; - Signed = false; - } + if (isPoly()) + Kind = UInt; break; case 'b': - Signed = false; - Float = false; - Poly = false; + Kind = UInt; NumVectors = 0; Bitwidth = ElementBitwidth; break; case '$': - Signed = true; - Float = false; - Poly = false; + Kind = SInt; NumVectors = 0; Bitwidth = ElementBitwidth; break; case 'u': - Signed = false; - Poly = false; - Float = false; + Kind = UInt; break; case 'x': - Signed = true; - assert(!Poly && "'u' can't be used with poly types!"); - Float = false; + assert(!isPoly() && "'u' can't be used with poly types!"); + Kind = SInt; break; case 'o': Bitwidth = ElementBitwidth = 64; NumVectors = 0; - Float = true; + Kind = Float; break; case 'y': Bitwidth = ElementBitwidth = 32; NumVectors = 0; - Float = true; + Kind = Float; break; case 'Y': Bitwidth = ElementBitwidth = 16; NumVectors = 0; - Float = true; + Kind = Float; break; case 'I': Bitwidth = ElementBitwidth = 32; NumVectors = 0; - Float = false; - Signed = true; + Kind = SInt; break; case 'L': Bitwidth = ElementBitwidth = 64; NumVectors = 0; - Float = false; - Signed = true; + Kind = SInt; break; case 'U': Bitwidth = ElementBitwidth = 32; NumVectors = 0; - Float = false; - Signed = false; + Kind = UInt; break; case 'O': Bitwidth = ElementBitwidth = 64; NumVectors = 0; - Float = false; - Signed = false; + Kind = UInt; break; case 'f': - Float = true; + Kind = Float; ElementBitwidth = 32; break; case 'F': - Float = true; + Kind = Float; ElementBitwidth = 64; break; case 'H': - Float = true; + Kind = Float; ElementBitwidth = 16; break; case '0': - Float = true; + Kind = Float; if (AppliedQuad) Bitwidth /= 2; ElementBitwidth = 16; break; case '1': - Float = true; + Kind = Float; if (!AppliedQuad) Bitwidth *= 2; ElementBitwidth = 16; @@ -937,19 +928,15 @@ ElementBitwidth *= 2; break; case 'i': - Float = false; - Poly = false; + Kind = SInt; ElementBitwidth = Bitwidth = 32; NumVectors = 0; - Signed = true; Immediate = true; break; case 'l': - Float = false; - Poly = false; + Kind = UInt; ElementBitwidth = Bitwidth = 64; NumVectors = 0; - Signed = false; Immediate = true; break; case 'z': @@ -987,7 +974,7 @@ break; case 'e': ElementBitwidth /= 2; - Signed = false; + Kind = UInt; break; case 'm': ElementBitwidth /= 2; @@ -1089,7 +1076,7 @@ Type RetT = getReturnType(); if ((LocalCK == ClassI || LocalCK == ClassW) && RetT.isScalar() && - !RetT.isFloating()) + !RetT.isFloating() && !RetT.isVoid()) RetT.makeInteger(RetT.getElementSizeInBits(), false); // Since the return value must be one type, return a vector type of the @@ -1101,11 +1088,12 @@ } else { if (RetT.isPoly()) RetT.makeInteger(RetT.getElementSizeInBits(), false); - if (!RetT.isScalar() && !RetT.isSigned()) + if (!RetT.isScalar() && RetT.isInteger() && !RetT.isSigned()) RetT.makeSigned(); bool ForcedVectorFloatingType = isFloatingPointProtoModifier(Proto[0]); - if (LocalCK == ClassB && !RetT.isScalar() && !ForcedVectorFloatingType) + if (LocalCK == ClassB && !RetT.isVoid() && !RetT.isScalar() && + !ForcedVectorFloatingType) // Cast to vector of 8-bit elements. RetT.makeInteger(8, true); @@ -1124,7 +1112,7 @@ if (T.isHalf() && T.isVector() && !T.isScalarForMangling()) T.makeInteger(8, true); - if (LocalCK == ClassI) + if (LocalCK == ClassI && T.isInteger()) T.makeSigned(); if (hasImmediate() && getImmediateIdx() == I) @@ -2406,7 +2394,7 @@ for (auto &TS : TDTypeVec) { bool IsA64 = false; Type T(TS, 'd'); - if (T.isDouble() || (T.isPoly() && T.isLong())) + if (T.isDouble() || (T.isPoly() && T.getElementSizeInBits() == 64)) IsA64 = true; if (InIfdef && !IsA64) { @@ -2439,7 +2427,7 @@ for (auto &TS : TDTypeVec) { bool IsA64 = false; Type T(TS, 'd'); - if (T.isDouble() || (T.isPoly() && T.isLong())) + if (T.isDouble() || (T.isPoly() && T.getElementSizeInBits() == 64)) IsA64 = true; if (InIfdef && !IsA64) {