Jim Stichnoth | f7c9a14 | 2014-04-29 10:52:43 -0700 | [diff] [blame] | 1 | //===- subzero/src/IceTypes.h - Primitive ICE types -------------*- C++ -*-===// |
| 2 | // |
| 3 | // The Subzero Code Generator |
| 4 | // |
| 5 | // This file is distributed under the University of Illinois Open Source |
| 6 | // License. See LICENSE.TXT for details. |
| 7 | // |
| 8 | //===----------------------------------------------------------------------===// |
Andrew Scull | 9612d32 | 2015-07-06 14:53:25 -0700 | [diff] [blame] | 9 | /// |
| 10 | /// \file |
Jim Stichnoth | 92a6e5b | 2015-12-02 16:52:44 -0800 | [diff] [blame] | 11 | /// \brief Declares a few properties of the primitive types allowed in Subzero. |
| 12 | /// Every Subzero source file is expected to include IceTypes.h. |
Andrew Scull | 9612d32 | 2015-07-06 14:53:25 -0700 | [diff] [blame] | 13 | /// |
Jim Stichnoth | f7c9a14 | 2014-04-29 10:52:43 -0700 | [diff] [blame] | 14 | //===----------------------------------------------------------------------===// |
| 15 | |
| 16 | #ifndef SUBZERO_SRC_ICETYPES_H |
| 17 | #define SUBZERO_SRC_ICETYPES_H |
| 18 | |
John Porto | 67f8de9 | 2015-06-25 10:14:17 -0700 | [diff] [blame] | 19 | #include "IceDefs.h" |
Jim Stichnoth | f7c9a14 | 2014-04-29 10:52:43 -0700 | [diff] [blame] | 20 | #include "IceTypes.def" |
| 21 | |
| 22 | namespace Ice { |
| 23 | |
| 24 | enum Type { |
Jim Stichnoth | 2544d4d | 2016-01-22 13:07:46 -0800 | [diff] [blame] | 25 | #define X(tag, sizeLog2, align, elts, elty, str, rcstr) IceType_##tag, |
Jim Stichnoth | f7c9a14 | 2014-04-29 10:52:43 -0700 | [diff] [blame] | 26 | ICETYPE_TABLE |
| 27 | #undef X |
Jim Stichnoth | 4376d29 | 2014-05-23 13:39:02 -0700 | [diff] [blame] | 28 | IceType_NUM |
Jim Stichnoth | f7c9a14 | 2014-04-29 10:52:43 -0700 | [diff] [blame] | 29 | }; |
| 30 | |
Jim Stichnoth | 2544d4d | 2016-01-22 13:07:46 -0800 | [diff] [blame] | 31 | /// RegClass indicates the physical register class that a Variable may be |
| 32 | /// register-allocated from. By default, a variable's register class is |
| 33 | /// directly associated with its type. However, the target lowering may define |
| 34 | /// additional target-specific register classes by extending the set of enum |
| 35 | /// values. |
| 36 | enum RegClass : uint8_t { |
| 37 | // Define RC_void, RC_i1, RC_i8, etc. |
| 38 | #define X(tag, sizeLog2, align, elts, elty, str, rcstr) \ |
| 39 | RC_##tag = IceType_##tag, |
| 40 | ICETYPE_TABLE |
| 41 | #undef X |
| 42 | RC_Target, |
| 43 | // Leave plenty of space for target-specific values. |
| 44 | RC_Max = std::numeric_limits<uint8_t>::max() |
| 45 | }; |
| 46 | static_assert(RC_Target == static_cast<RegClass>(IceType_NUM), |
| 47 | "Expected RC_Target and IceType_NUM to be the same"); |
| 48 | |
Jim Stichnoth | 5bc2b1d | 2014-05-22 13:38:48 -0700 | [diff] [blame] | 49 | enum TargetArch { |
Jan Voung | 08c3bcd | 2014-12-01 17:55:16 -0800 | [diff] [blame] | 50 | #define X(tag, str, is_elf64, e_machine, e_flags) tag, |
Karl Schimpf | b262c5e | 2014-10-27 14:41:57 -0700 | [diff] [blame] | 51 | TARGETARCH_TABLE |
| 52 | #undef X |
Jim Stichnoth | 336f6c4 | 2014-10-30 15:01:31 -0700 | [diff] [blame] | 53 | TargetArch_NUM |
Jim Stichnoth | 5bc2b1d | 2014-05-22 13:38:48 -0700 | [diff] [blame] | 54 | }; |
| 55 | |
Karl Schimpf | b262c5e | 2014-10-27 14:41:57 -0700 | [diff] [blame] | 56 | const char *targetArchString(TargetArch Arch); |
| 57 | |
| 58 | inline Ostream &operator<<(Ostream &Stream, TargetArch Arch) { |
| 59 | return Stream << targetArchString(Arch); |
| 60 | } |
| 61 | |
Andrew Scull | 57e1268 | 2015-09-16 11:30:19 -0700 | [diff] [blame] | 62 | /// The list of all target instruction sets. Individual targets will map this to |
| 63 | /// include only what is valid for the target. |
Jan Voung | 1f47ad0 | 2015-03-20 15:01:26 -0700 | [diff] [blame] | 64 | enum TargetInstructionSet { |
Jan Voung | d062f73 | 2015-06-15 17:17:31 -0700 | [diff] [blame] | 65 | // Represents baseline that can be assumed for a target (usually "Begin"). |
| 66 | BaseInstructionSet, |
Jan Voung | 1f47ad0 | 2015-03-20 15:01:26 -0700 | [diff] [blame] | 67 | X86InstructionSet_Begin, |
Jan Voung | 1f47ad0 | 2015-03-20 15:01:26 -0700 | [diff] [blame] | 68 | X86InstructionSet_SSE2 = X86InstructionSet_Begin, |
| 69 | X86InstructionSet_SSE4_1, |
| 70 | X86InstructionSet_End, |
Jan Voung | d062f73 | 2015-06-15 17:17:31 -0700 | [diff] [blame] | 71 | ARM32InstructionSet_Begin, |
| 72 | ARM32InstructionSet_Neon = ARM32InstructionSet_Begin, |
| 73 | ARM32InstructionSet_HWDivArm, |
| 74 | ARM32InstructionSet_End, |
Jan Voung | 1f47ad0 | 2015-03-20 15:01:26 -0700 | [diff] [blame] | 75 | }; |
| 76 | |
Jim Stichnoth | dd842db | 2015-01-27 12:53:53 -0800 | [diff] [blame] | 77 | enum OptLevel { Opt_m1, Opt_0, Opt_1, Opt_2 }; |
Jim Stichnoth | 5bc2b1d | 2014-05-22 13:38:48 -0700 | [diff] [blame] | 78 | |
Jim Stichnoth | f7c9a14 | 2014-04-29 10:52:43 -0700 | [diff] [blame] | 79 | size_t typeWidthInBytes(Type Ty); |
Andrew Scull | 87f80c1 | 2015-07-20 10:19:16 -0700 | [diff] [blame] | 80 | int8_t typeWidthInBytesLog2(Type Ty); |
Jim Stichnoth | f7c9a14 | 2014-04-29 10:52:43 -0700 | [diff] [blame] | 81 | size_t typeAlignInBytes(Type Ty); |
Matt Wala | 928f129 | 2014-07-07 16:50:46 -0700 | [diff] [blame] | 82 | size_t typeNumElements(Type Ty); |
| 83 | Type typeElementType(Type Ty); |
Jim Stichnoth | 78282f6 | 2014-07-27 23:14:00 -0700 | [diff] [blame] | 84 | const char *typeString(Type Ty); |
Jim Stichnoth | 467ffe5 | 2016-03-29 15:01:06 -0700 | [diff] [blame] | 85 | inline std::string typeStdString(Type Ty) { return typeString(Ty); } |
Jim Stichnoth | 2544d4d | 2016-01-22 13:07:46 -0800 | [diff] [blame] | 86 | const char *regClassString(RegClass C); |
Matt Wala | 928f129 | 2014-07-07 16:50:46 -0700 | [diff] [blame] | 87 | |
Nicolas Capens | 32f9cce | 2016-10-19 01:24:27 -0400 | [diff] [blame] | 88 | Type getPointerType(); |
Karl Schimpf | 4019f08 | 2014-12-15 13:45:00 -0800 | [diff] [blame] | 89 | |
Karl Schimpf | d6064a1 | 2014-08-27 15:34:58 -0700 | [diff] [blame] | 90 | bool isVectorType(Type Ty); |
| 91 | |
Nicolas Capens | e965530 | 2017-02-13 10:21:20 -0500 | [diff] [blame] | 92 | bool isBooleanType(Type Ty); // scalar or vector |
Karl Schimpf | d6064a1 | 2014-08-27 15:34:58 -0700 | [diff] [blame] | 93 | bool isIntegerType(Type Ty); // scalar or vector |
| 94 | bool isScalarIntegerType(Type Ty); |
| 95 | bool isVectorIntegerType(Type Ty); |
| 96 | bool isIntegerArithmeticType(Type Ty); |
| 97 | |
| 98 | bool isFloatingType(Type Ty); // scalar or vector |
| 99 | bool isScalarFloatingType(Type Ty); |
| 100 | bool isVectorFloatingType(Type Ty); |
Jim Stichnoth | f7c9a14 | 2014-04-29 10:52:43 -0700 | [diff] [blame] | 101 | |
Karl Schimpf | 41689df | 2014-09-10 14:36:07 -0700 | [diff] [blame] | 102 | /// Returns true if the given type can be used in a load instruction. |
| 103 | bool isLoadStoreType(Type Ty); |
| 104 | |
Karl Schimpf | ff94f59 | 2015-09-18 10:37:44 -0700 | [diff] [blame] | 105 | /// Returns true if the given type can be used as a parameter type in a call. |
| 106 | bool isCallParameterType(Type Ty); |
| 107 | |
| 108 | /// Returns true if the given type can be used as the return type of a call. |
| 109 | inline bool isCallReturnType(Type Ty) { |
| 110 | return Ty == IceType_void || isCallParameterType(Ty); |
| 111 | } |
| 112 | |
Karl Schimpf | 83f9f0c | 2014-09-05 08:30:55 -0700 | [diff] [blame] | 113 | /// Returns type generated by applying the compare instructions (icmp and fcmp) |
| 114 | /// to arguments of the given type. Returns IceType_void if compare is not |
| 115 | /// allowed. |
| 116 | Type getCompareResultType(Type Ty); |
| 117 | |
Karl Schimpf | d1a971a | 2014-09-17 15:38:17 -0700 | [diff] [blame] | 118 | /// Returns the number of bits in a scalar integer type. |
| 119 | SizeT getScalarIntBitWidth(Type Ty); |
| 120 | |
Andrew Scull | 9612d32 | 2015-07-06 14:53:25 -0700 | [diff] [blame] | 121 | /// Check if a type is byte sized (slight optimization over typeWidthInBytes). |
Jan Voung | 3a56918 | 2014-09-29 10:16:01 -0700 | [diff] [blame] | 122 | inline bool isByteSizedType(Type Ty) { |
| 123 | bool result = Ty == IceType_i8 || Ty == IceType_i1; |
| 124 | assert(result == (1 == typeWidthInBytes(Ty))); |
| 125 | return result; |
| 126 | } |
| 127 | |
Andrew Scull | 57e1268 | 2015-09-16 11:30:19 -0700 | [diff] [blame] | 128 | /// Check if Ty is byte sized and specifically i8. Assert that it's not byte |
| 129 | /// sized due to being an i1. |
Jan Voung | 3a56918 | 2014-09-29 10:16:01 -0700 | [diff] [blame] | 130 | inline bool isByteSizedArithType(Type Ty) { |
| 131 | assert(Ty != IceType_i1); |
| 132 | return Ty == IceType_i8; |
| 133 | } |
| 134 | |
Andrew Scull | 9612d32 | 2015-07-06 14:53:25 -0700 | [diff] [blame] | 135 | /// Return true if Ty is i32. This asserts that Ty is either i32 or i64. |
Jan Voung | 3a56918 | 2014-09-29 10:16:01 -0700 | [diff] [blame] | 136 | inline bool isInt32Asserting32Or64(Type Ty) { |
| 137 | bool result = Ty == IceType_i32; |
| 138 | assert(result || Ty == IceType_i64); |
| 139 | return result; |
| 140 | } |
| 141 | |
Andrew Scull | 9612d32 | 2015-07-06 14:53:25 -0700 | [diff] [blame] | 142 | /// Return true if Ty is f32. This asserts that Ty is either f32 or f64. |
Jan Voung | 3a56918 | 2014-09-29 10:16:01 -0700 | [diff] [blame] | 143 | inline bool isFloat32Asserting32Or64(Type Ty) { |
| 144 | bool result = Ty == IceType_f32; |
| 145 | assert(result || Ty == IceType_f64); |
| 146 | return result; |
| 147 | } |
| 148 | |
Jim Stichnoth | 78282f6 | 2014-07-27 23:14:00 -0700 | [diff] [blame] | 149 | template <typename StreamType> |
| 150 | inline StreamType &operator<<(StreamType &Str, const Type &Ty) { |
| 151 | Str << typeString(Ty); |
| 152 | return Str; |
| 153 | } |
Jim Stichnoth | f7c9a14 | 2014-04-29 10:52:43 -0700 | [diff] [blame] | 154 | |
Karl Schimpf | 645aa1a | 2014-10-08 09:05:53 -0700 | [diff] [blame] | 155 | /// Models a type signature for a function. |
Karl Schimpf | 645aa1a | 2014-10-08 09:05:53 -0700 | [diff] [blame] | 156 | class FuncSigType { |
Karl Schimpf | 645aa1a | 2014-10-08 09:05:53 -0700 | [diff] [blame] | 157 | FuncSigType &operator=(const FuncSigType &Ty) = delete; |
Jim Stichnoth | dd842db | 2015-01-27 12:53:53 -0800 | [diff] [blame] | 158 | |
Karl Schimpf | 645aa1a | 2014-10-08 09:05:53 -0700 | [diff] [blame] | 159 | public: |
Andrew Scull | 8072bae | 2015-09-14 16:01:26 -0700 | [diff] [blame] | 160 | using ArgListType = std::vector<Type>; |
Karl Schimpf | 645aa1a | 2014-10-08 09:05:53 -0700 | [diff] [blame] | 161 | |
Andrew Scull | 57e1268 | 2015-09-16 11:30:19 -0700 | [diff] [blame] | 162 | /// Creates a function signature type with the given return type. Parameter |
| 163 | /// types should be added using calls to appendArgType. |
Jim Stichnoth | eafb56c | 2015-06-22 10:35:22 -0700 | [diff] [blame] | 164 | FuncSigType() = default; |
Jim Stichnoth | 7e57136 | 2015-01-09 11:43:26 -0800 | [diff] [blame] | 165 | FuncSigType(const FuncSigType &Ty) = default; |
Karl Schimpf | 645aa1a | 2014-10-08 09:05:53 -0700 | [diff] [blame] | 166 | |
| 167 | void appendArgType(Type ArgType) { ArgList.push_back(ArgType); } |
| 168 | |
| 169 | Type getReturnType() const { return ReturnType; } |
| 170 | void setReturnType(Type NewType) { ReturnType = NewType; } |
| 171 | SizeT getNumArgs() const { return ArgList.size(); } |
| 172 | Type getArgType(SizeT Index) const { |
| 173 | assert(Index < ArgList.size()); |
| 174 | return ArgList[Index]; |
| 175 | } |
| 176 | const ArgListType &getArgList() const { return ArgList; } |
| 177 | void dump(Ostream &Stream) const; |
| 178 | |
| 179 | private: |
Andrew Scull | 9612d32 | 2015-07-06 14:53:25 -0700 | [diff] [blame] | 180 | /// The return type. |
Jim Stichnoth | eafb56c | 2015-06-22 10:35:22 -0700 | [diff] [blame] | 181 | Type ReturnType = IceType_void; |
Andrew Scull | 9612d32 | 2015-07-06 14:53:25 -0700 | [diff] [blame] | 182 | /// The list of parameters. |
Karl Schimpf | 645aa1a | 2014-10-08 09:05:53 -0700 | [diff] [blame] | 183 | ArgListType ArgList; |
| 184 | }; |
| 185 | |
| 186 | inline Ostream &operator<<(Ostream &Stream, const FuncSigType &Sig) { |
| 187 | Sig.dump(Stream); |
| 188 | return Stream; |
| 189 | } |
| 190 | |
Jim Stichnoth | f7c9a14 | 2014-04-29 10:52:43 -0700 | [diff] [blame] | 191 | } // end of namespace Ice |
| 192 | |
| 193 | #endif // SUBZERO_SRC_ICETYPES_H |