1//===- PPCTargetParser.def - PPC target parsing defines ---------*- C++ -*-===// 2// 3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4// See https://llvm.org/LICENSE.txt for license information. 5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6// 7//===----------------------------------------------------------------------===// 8// 9// This file provides defines to build up the PPC target parser's logic. 10// 11//===----------------------------------------------------------------------===// 12 13// NOTE: NO INCLUDE GUARD DESIRED! 14 15#ifdef PPC_TGT_PARSER_UNDEF_MACROS 16#undef PPC_LNX_FEATURE 17#undef PPC_LNX_CPU 18#undef PPC_FAWORD_HWCAP 19#undef PPC_FAWORD_HWCAP2 20#undef PPC_FAWORD_CPUID 21#undef PPC_HWCAP_OFFSET_LE32 22#undef PPC_HWCAP_OFFSET_LE64 23#undef PPC_HWCAP_OFFSET_BE32 24#undef PPC_HWCAP_OFFSET_BE64 25#undef PPC_HWCAP2_OFFSET_LE32 26#undef PPC_HWCAP2_OFFSET_LE64 27#undef PPC_HWCAP2_OFFSET_BE32 28#undef PPC_HWCAP2_OFFSET_BE64 29#undef PPC_CPUID_OFFSET_LE32 30#undef PPC_CPUID_OFFSET_LE64 31#undef PPC_CPUID_OFFSET_BE32 32#undef PPC_CPUID_OFFSET_BE64 33#else 34#ifndef PPC_LNX_FEATURE 35#define PPC_LNX_FEATURE(NAME, DESC, ENUMNAME, ENUMVAL, HWCAPN) 36#endif 37#ifndef PPC_LNX_CPU 38#define PPC_LNX_CPU(NAME, NUM) 39#endif 40#ifndef PPC_FAWORD_HWCAP 41#define PPC_FAWORD_HWCAP 1 42#endif 43#ifndef PPC_FAWORD_HWCAP2 44#define PPC_FAWORD_HWCAP2 2 45#endif 46#ifndef PPC_FAWORD_CPUID 47#define PPC_FAWORD_CPUID 3 48#endif 49 50// PPC_LNX_FEATURE(Name, Description, EnumName, BitMask, PPC_FAWORD_WORD) 51PPC_LNX_FEATURE("4xxmac","4xx CPU has a Multiply Accumulator",PPCF_4XXMAC,0x02000000,PPC_FAWORD_HWCAP) 52PPC_LNX_FEATURE("altivec","CPU has a SIMD/Vector Unit",PPCF_ALTIVEC,0x10000000,PPC_FAWORD_HWCAP) 53PPC_LNX_FEATURE("arch_2_05","CPU supports ISA 205 (eg, POWER6)",PPCF_ARCH205,0x00001000,PPC_FAWORD_HWCAP) 54PPC_LNX_FEATURE("arch_2_06","CPU supports ISA 206 (eg, POWER7)",PPCF_ARCH206,0x00000100,PPC_FAWORD_HWCAP) 55PPC_LNX_FEATURE("arch_2_07","CPU supports ISA 207 (eg, POWER8)",PPCF_ARCH207,0x80000000,PPC_FAWORD_HWCAP2) 56PPC_LNX_FEATURE("arch_3_00","CPU supports ISA 30 (eg, POWER9)",PPCF_ARCH30,0x00800000,PPC_FAWORD_HWCAP2) 57PPC_LNX_FEATURE("arch_3_1","CPU supports ISA 31 (eg, POWER10)",PPCF_ARCH31,0x00040000,PPC_FAWORD_HWCAP2) 58PPC_LNX_FEATURE("archpmu","CPU supports the set of compatible performance monitoring events",PPCF_ARCHPMU,0x00000040,PPC_FAWORD_HWCAP) 59PPC_LNX_FEATURE("booke","CPU supports the Embedded ISA category",PPCF_BOOKE,0x00008000,PPC_FAWORD_HWCAP) 60PPC_LNX_FEATURE("cellbe","CPU has a CELL broadband engine",PPCF_CELLBE,0x00010000,PPC_FAWORD_HWCAP) 61PPC_LNX_FEATURE("darn","CPU supports the darn (deliver a random number) instruction",PPCF_DARN,0x00200000,PPC_FAWORD_HWCAP2) 62PPC_LNX_FEATURE("dfp","CPU has a decimal floating point unit",PPCF_DFP,0x00000400,PPC_FAWORD_HWCAP) 63PPC_LNX_FEATURE("dscr","CPU supports the data stream control register",PPCF_DSCR,0x20000000,PPC_FAWORD_HWCAP2) 64PPC_LNX_FEATURE("ebb","CPU supports event base branching",PPCF_EBB,0x10000000,PPC_FAWORD_HWCAP2) 65PPC_LNX_FEATURE("efpdouble","CPU has a SPE double precision floating point unit",PPCF_EFPDOUBLE,0x00200000,PPC_FAWORD_HWCAP) 66PPC_LNX_FEATURE("efpsingle","CPU has a SPE single precision floating point unit",PPCF_EFPSINGLE,0x00400000,PPC_FAWORD_HWCAP) 67PPC_LNX_FEATURE("fpu","CPU has a floating point unit",PPCF_FPU,0x08000000,PPC_FAWORD_HWCAP) 68PPC_LNX_FEATURE("htm","CPU has hardware transaction memory instructions",PPCF_HTM,0x40000000,PPC_FAWORD_HWCAP2) 69PPC_LNX_FEATURE("htm-nosc","Kernel aborts hardware transactions when a syscall is made",PPCF_HTM_NOSC,0x01000000,PPC_FAWORD_HWCAP2) 70PPC_LNX_FEATURE("htm-no-suspend","CPU supports hardware transaction memory but does not support the tsuspend instruction.",PPCF_HTM_NO_SUSPEND,0x00080000,PPC_FAWORD_HWCAP2) 71PPC_LNX_FEATURE("ic_snoop","CPU supports icache snooping capabilities",PPCF_IC_SNOOP,0x00002000,PPC_FAWORD_HWCAP) 72PPC_LNX_FEATURE("ieee128","CPU supports 128-bit IEEE binary floating point instructions",PPCF_IEEE128,0x00400000,PPC_FAWORD_HWCAP2) 73PPC_LNX_FEATURE("isel","CPU supports the integer select instruction",PPCF_ISEL,0x08000000,PPC_FAWORD_HWCAP2) 74PPC_LNX_FEATURE("mma","CPU supports the matrix-multiply assist instructions",PPCF_MMA,0x00020000,PPC_FAWORD_HWCAP2) 75PPC_LNX_FEATURE("mmu","CPU has a memory management unit",PPCF_MMU,0x04000000,PPC_FAWORD_HWCAP) 76PPC_LNX_FEATURE("notb","CPU does not have a timebase (eg, 601 and 403gx)",PPCF_NOTB,0x00100000,PPC_FAWORD_HWCAP) 77PPC_LNX_FEATURE("pa6t","CPU supports the PA Semi 6T CORE ISA",PPCF_PA6T,0x00000800,PPC_FAWORD_HWCAP) 78PPC_LNX_FEATURE("power4","CPU supports ISA 200 (eg, POWER4)",PPCF_POWER4,0x00080000,PPC_FAWORD_HWCAP) 79PPC_LNX_FEATURE("power5","CPU supports ISA 202 (eg, POWER5)",PPCF_POWER5,0x00040000,PPC_FAWORD_HWCAP) 80PPC_LNX_FEATURE("power5+","CPU supports ISA 203 (eg, POWER5+)",PPCF_POWER5P,0x00020000,PPC_FAWORD_HWCAP) 81PPC_LNX_FEATURE("power6x","CPU supports ISA 205 (eg, POWER6) extended opcodes mffgpr and mftgpr.",PPCF_POWER6X,0x00000200,PPC_FAWORD_HWCAP) 82PPC_LNX_FEATURE("ppc32","CPU supports 32-bit mode execution",PPCF_PPC32,0x80000000,PPC_FAWORD_HWCAP) 83PPC_LNX_FEATURE("ppc601","CPU supports the old POWER ISA (eg, 601)",PPCF_PPC601,0x20000000,PPC_FAWORD_HWCAP) 84PPC_LNX_FEATURE("ppc64","CPU supports 64-bit mode execution",PPCF_PPC64,0x40000000,PPC_FAWORD_HWCAP) 85PPC_LNX_FEATURE("ppcle","CPU supports a little-endian mode that uses address swizzling",PPCF_PPCLE,0x00000001,PPC_FAWORD_HWCAP) 86PPC_LNX_FEATURE("scv","Kernel supports system call vectored",PPCF_SCV,0x00100000,PPC_FAWORD_HWCAP2) 87PPC_LNX_FEATURE("smt","CPU support simultaneous multi-threading",PPCF_SMT,0x00004000,PPC_FAWORD_HWCAP) 88PPC_LNX_FEATURE("spe","CPU has a signal processing extension unit",PPCF_SPE,0x00800000,PPC_FAWORD_HWCAP) 89PPC_LNX_FEATURE("tar","CPU supports the target address register",PPCF_TAR,0x04000000,PPC_FAWORD_HWCAP2) 90PPC_LNX_FEATURE("true_le","CPU supports true little-endian mode",PPCF_TRUE_LE,0x00000002,PPC_FAWORD_HWCAP) 91PPC_LNX_FEATURE("ucache","CPU has unified I/D cache",PPCF_UCACHE,0x01000000,PPC_FAWORD_HWCAP) 92PPC_LNX_FEATURE("vcrypto","CPU supports the vector cryptography instructions",PPCF_VCRYPTO,0x02000000,PPC_FAWORD_HWCAP2) 93PPC_LNX_FEATURE("vsx","CPU supports the vector-scalar extension",PPCF_VSX,0x00000080,PPC_FAWORD_HWCAP) 94 95// PPC_LNX_CPU(Name, NumericID) 96PPC_LNX_CPU("power4",32) 97PPC_LNX_CPU("ppc970",33) 98PPC_LNX_CPU("power5",34) 99PPC_LNX_CPU("power5+",35) 100PPC_LNX_CPU("power6",36) 101PPC_LNX_CPU("ppc-cell-be",37) 102PPC_LNX_CPU("power6x",38) 103PPC_LNX_CPU("power7",39) 104PPC_LNX_CPU("ppca2",40) 105PPC_LNX_CPU("ppc405",41) 106PPC_LNX_CPU("ppc440",42) 107PPC_LNX_CPU("ppc464",43) 108PPC_LNX_CPU("ppc476",44) 109PPC_LNX_CPU("power8",45) 110PPC_LNX_CPU("power9",46) 111PPC_LNX_CPU("power10",47) 112#ifdef PPC_LNX_DEFINE_OFFSETS 113# define PPC_HWCAP_OFFSET_LE32 -0x703C 114# define PPC_HWCAP_OFFSET_LE64 -0x7064 115# define PPC_HWCAP_OFFSET_BE32 -0x7040 116# define PPC_HWCAP_OFFSET_BE64 -0x7068 117# define PPC_HWCAP2_OFFSET_LE32 -0x7040 118# define PPC_HWCAP2_OFFSET_LE64 -0x7068 119# define PPC_HWCAP2_OFFSET_BE32 -0x703C 120# define PPC_HWCAP2_OFFSET_BE64 -0x7064 121# define PPC_CPUID_OFFSET_LE32 -0x7034 122# define PPC_CPUID_OFFSET_LE64 -0x705C 123# define PPC_CPUID_OFFSET_BE32 -0x7034 124# define PPC_CPUID_OFFSET_BE64 -0x705C 125#endif 126#undef PPC_LNX_DEFINE_OFFSETS 127#undef PPC_LNX_FEATURE 128#undef PPC_LNX_CPU 129 130// Definition of the following values are found in the AIX header 131// file: </usr/include/sys/systemcfg.h>. 132#ifndef AIX_POWERPC_USE_SYS_CONF 133 #define AIX_POWERPC_USE_SYS_CONF 134 #define AIX_SYSCON_IMPL_IDX 1 135 #define AIX_SYSCON_CACHE_IDX 5 136 #define AIX_SYSCON_SMT_IDX 44 137 #define AIX_SYSCON_VMX_IDX 46 138 #define AIX_SYSCON_DFP_IDX 53 139 140 #define SYS_CALL_TM_VER 59 141 #define SYS_CALL_MMA_VER 62 142 143 #define AIX_PPC7_VALUE 0x00008000 144 #define AIX_PPC8_VALUE 0x00010000 145 #define AIX_PPC9_VALUE 0x00020000 146 #define AIX_PPC10_VALUE 0x00040000 147 148 // Supported SUPPORT_METHOD values. 149 #define AIX_BUILTIN_PPC_TRUE 1 150 #define AIX_BUILTIN_PPC_FALSE 0 151 #define USE_SYS_CONF 2 152 #define SYS_CALL 3 153#endif 154 155// The value of SUPPORT_METHOD can be: 156// AIX_BUILTIN_PPC_TRUE : feature supported 157// AIX_BUILTIN_PPC_FALSE : feature not supported 158// USE_SYS_CONF : return value depends on comparing VALUE with the specified 159// data member of _system_configuration at INDEX, where the 160// data member is masked by Mask. 161// SYS_CALL : return value depends on comparing a VALUE with the return value 162// of calling `getsystemcfg` with the parameter INDEX, which is 163// then masked by Mask. 164 165#ifndef PPC_AIX_CPU 166 #define PPC_AIX_CPU(NAME, SUPPORT_METHOD, INDEX, COMPARE_OP, VALUE) 167#endif 168 169// __builtin_cpu_is() and __builtin_cpu_supports() are supported only on Power7 and up. 170PPC_AIX_CPU("power4",AIX_BUILTIN_PPC_FALSE,0,CmpInst::Predicate(),0) 171PPC_AIX_CPU("ppc970",AIX_BUILTIN_PPC_FALSE,0,CmpInst::Predicate(),0) 172PPC_AIX_CPU("power5",AIX_BUILTIN_PPC_FALSE,0,CmpInst::Predicate(),0) 173PPC_AIX_CPU("power5+",AIX_BUILTIN_PPC_FALSE,0,CmpInst::Predicate(),0) 174PPC_AIX_CPU("power6",AIX_BUILTIN_PPC_FALSE,0,CmpInst::Predicate(),0) 175PPC_AIX_CPU("ppc-cell-be",AIX_BUILTIN_PPC_FALSE,0,CmpInst::Predicate(),0) 176PPC_AIX_CPU("power6x",AIX_BUILTIN_PPC_FALSE,0,CmpInst::Predicate(),0) 177PPC_AIX_CPU("ppca2",AIX_BUILTIN_PPC_FALSE,0,CmpInst::Predicate(),0) 178PPC_AIX_CPU("ppc405",AIX_BUILTIN_PPC_FALSE,0,CmpInst::Predicate(),0) 179PPC_AIX_CPU("ppc440",AIX_BUILTIN_PPC_FALSE,0,CmpInst::Predicate(),0) 180PPC_AIX_CPU("ppc464",AIX_BUILTIN_PPC_FALSE,0,CmpInst::Predicate(),0) 181PPC_AIX_CPU("ppc476",AIX_BUILTIN_PPC_FALSE,0,CmpInst::Predicate(),0) 182PPC_AIX_CPU("power7",USE_SYS_CONF,AIX_SYSCON_IMPL_IDX,ICmpInst::ICMP_EQ,AIX_PPC7_VALUE) 183PPC_AIX_CPU("power8",USE_SYS_CONF,AIX_SYSCON_IMPL_IDX,ICmpInst::ICMP_EQ,AIX_PPC8_VALUE) 184PPC_AIX_CPU("power9",USE_SYS_CONF,AIX_SYSCON_IMPL_IDX,ICmpInst::ICMP_EQ,AIX_PPC9_VALUE) 185PPC_AIX_CPU("power10",USE_SYS_CONF,AIX_SYSCON_IMPL_IDX,ICmpInst::ICMP_EQ,AIX_PPC10_VALUE) 186#undef PPC_AIX_CPU 187 188#ifndef PPC_AIX_FEATURE 189#define PPC_AIX_FEATURE(NAME,DESC,SUPPORT_METHOD,INDEX,MASK,COMPARE_OP,VALUE) 190#endif 191 192PPC_AIX_FEATURE("4xxmac","4xx CPU has a Multiply Accumulator",AIX_BUILTIN_PPC_FALSE,0,0,CmpInst::Predicate(),0) 193PPC_AIX_FEATURE("altivec","CPU has a SIMD/Vector Unit",USE_SYS_CONF,AIX_SYSCON_VMX_IDX,0,ICmpInst::ICMP_UGT,0) 194PPC_AIX_FEATURE("arch_2_05","CPU supports ISA 205 (eg, POWER6)",AIX_BUILTIN_PPC_TRUE,0,0,CmpInst::Predicate(),0) 195PPC_AIX_FEATURE("arch_2_06","CPU supports ISA 206 (eg, POWER7)",USE_SYS_CONF,AIX_SYSCON_IMPL_IDX,0,ICmpInst::ICMP_UGE,AIX_PPC7_VALUE) 196PPC_AIX_FEATURE("arch_2_07","CPU supports ISA 207 (eg, POWER8)",USE_SYS_CONF,AIX_SYSCON_IMPL_IDX,0,ICmpInst::ICMP_UGE,AIX_PPC8_VALUE) 197PPC_AIX_FEATURE("arch_3_00","CPU supports ISA 30 (eg, POWER9)", USE_SYS_CONF,AIX_SYSCON_IMPL_IDX,0,ICmpInst::ICMP_UGE,AIX_PPC9_VALUE) 198PPC_AIX_FEATURE("arch_3_1","CPU supports ISA 31 (eg, POWER10)", USE_SYS_CONF,AIX_SYSCON_IMPL_IDX,0,ICmpInst::ICMP_UGE,AIX_PPC10_VALUE) 199PPC_AIX_FEATURE("booke","CPU supports the Embedded ISA category",AIX_BUILTIN_PPC_FALSE,0,0,CmpInst::Predicate(),0) 200PPC_AIX_FEATURE("cellbe","CPU has a CELL broadband engine",AIX_BUILTIN_PPC_FALSE,0,0,CmpInst::Predicate(),0) 201PPC_AIX_FEATURE("darn","CPU supports the darn (deliver a random number) instruction",USE_SYS_CONF,AIX_SYSCON_IMPL_IDX,0,ICmpInst::ICMP_UGE,AIX_PPC9_VALUE) 202PPC_AIX_FEATURE("dfp","CPU has a decimal floating point unit",USE_SYS_CONF,AIX_SYSCON_DFP_IDX,0,ICmpInst::ICMP_NE,0) 203PPC_AIX_FEATURE("dscr","CPU supports the data stream control register",USE_SYS_CONF,AIX_SYSCON_IMPL_IDX,0,ICmpInst::ICMP_UGE,AIX_PPC8_VALUE) 204PPC_AIX_FEATURE("ebb","CPU supports event base branching",USE_SYS_CONF,AIX_SYSCON_IMPL_IDX,0,ICmpInst::ICMP_UGE,AIX_PPC8_VALUE) 205PPC_AIX_FEATURE("efpsingle","CPU has a SPE single precision floating point unit",AIX_BUILTIN_PPC_FALSE,0,0,CmpInst::Predicate(),0) 206PPC_AIX_FEATURE("efpdouble","CPU has a SPE double precision floating point unit",AIX_BUILTIN_PPC_FALSE,0,0,CmpInst::Predicate(),0) 207PPC_AIX_FEATURE("fpu","CPU has a floating point unit",AIX_BUILTIN_PPC_TRUE,0,0,CmpInst::Predicate(),0) 208PPC_AIX_FEATURE("htm","CPU has hardware transaction memory instructions",SYS_CALL,SYS_CALL_TM_VER,0,ICmpInst::ICMP_UGT,0) 209PPC_AIX_FEATURE("isel","CPU supports the integer select instruction",AIX_BUILTIN_PPC_TRUE,0,0,CmpInst::Predicate(),0) 210PPC_AIX_FEATURE("mma","CPU supports the matrix-multiply assist instructions",SYS_CALL,SYS_CALL_MMA_VER,0,ICmpInst::ICMP_UGT,0) 211PPC_AIX_FEATURE("mmu","CPU has a memory management unit",AIX_BUILTIN_PPC_TRUE,0,0,CmpInst::Predicate(),0) 212PPC_AIX_FEATURE("pa6t","CPU supports the PA Semi 6T CORE ISA",AIX_BUILTIN_PPC_FALSE,0,0,CmpInst::Predicate(),0) 213PPC_AIX_FEATURE("power4","CPU supports ISA 200 (eg, POWER4)",AIX_BUILTIN_PPC_TRUE,0,0,CmpInst::Predicate(),0) 214PPC_AIX_FEATURE("power5","CPU supports ISA 202 (eg, POWER5)",AIX_BUILTIN_PPC_TRUE,0,0,CmpInst::Predicate(),0) 215PPC_AIX_FEATURE("power5+","CPU supports ISA 203 (eg, POWER5+)",AIX_BUILTIN_PPC_TRUE,0,0,CmpInst::Predicate(),0) 216PPC_AIX_FEATURE("power6x","CPU supports ISA 205 (eg, POWER6)",AIX_BUILTIN_PPC_FALSE,0,0,CmpInst::Predicate(),0) 217PPC_AIX_FEATURE("ppc32","CPU supports 32-bit mode execution",AIX_BUILTIN_PPC_TRUE,0,0,CmpInst::Predicate(),0) 218PPC_AIX_FEATURE("ppc601","CPU supports the old POWER ISA (eg, 601)",AIX_BUILTIN_PPC_FALSE,0,0,CmpInst::Predicate(),0) 219PPC_AIX_FEATURE("ppc64","CPU supports 64-bit mode execution",AIX_BUILTIN_PPC_TRUE,0,0,CmpInst::Predicate(),0) 220PPC_AIX_FEATURE("ppcle","CPU supports a little-endian mode that uses address swizzling",AIX_BUILTIN_PPC_FALSE,0,0,CmpInst::Predicate(),0) 221PPC_AIX_FEATURE("smt","CPU supports simultaneous multi-threading",USE_SYS_CONF,AIX_SYSCON_SMT_IDX,0x3,ICmpInst::ICMP_EQ,0x3) 222PPC_AIX_FEATURE("spe","CPU has a signal processing extension unit",AIX_BUILTIN_PPC_FALSE,0,0,CmpInst::Predicate(),0) 223PPC_AIX_FEATURE("tar","CPU supports the target address register",USE_SYS_CONF,AIX_SYSCON_IMPL_IDX,0,ICmpInst::ICMP_UGE,AIX_PPC8_VALUE) 224PPC_AIX_FEATURE("true_le","CPU supports true little-endian mode",AIX_BUILTIN_PPC_TRUE,0,0,CmpInst::Predicate(),0) 225PPC_AIX_FEATURE("ucache","CPU has unified I/D cache",USE_SYS_CONF,AIX_SYSCON_CACHE_IDX,0x00000002,ICmpInst::ICMP_EQ,0x00000002) 226PPC_AIX_FEATURE("vsx","CPU supports the vector-scalar extension",USE_SYS_CONF,AIX_SYSCON_VMX_IDX,0,ICmpInst::ICMP_UGT,1) 227#undef PPC_AIX_FEATURE 228 229// PPC_SYSTEMCONFIG_TYPE defines the IR data structure of kernel variable 230// `_system_configuration`, that is found in the AIX OS header file: </usr/include/sys/systemcfg.h>. 231#ifndef PPC_SYSTEMCONFIG_TYPE 232#define PPC_SYSTEMCONFIG_TYPE \ 233Int32Ty, Int32Ty, Int32Ty, Int32Ty, Int32Ty, Int32Ty, \ 234Int32Ty, Int32Ty, Int32Ty, Int32Ty, Int32Ty, Int32Ty, \ 235Int32Ty, Int32Ty, Int32Ty, Int32Ty, Int32Ty, Int32Ty, \ 236Int32Ty, Int32Ty, Int32Ty, Int32Ty, Int32Ty, Int32Ty, \ 237Int32Ty, Int32Ty, Int32Ty, Int32Ty, Int32Ty, Int32Ty, \ 238Int32Ty, Int32Ty, Int64Ty, Int32Ty, Int32Ty, Int32Ty, \ 239Int32Ty, Int64Ty, Int64Ty, Int64Ty, Int64Ty, Int32Ty, \ 240Int32Ty, Int32Ty, Int32Ty, Int32Ty, Int32Ty, Int64Ty, \ 241Int32Ty, Int8Ty, Int8Ty, Int8Ty, Int8Ty, Int32Ty, \ 242Int32Ty, Int16Ty, Int16Ty, llvm::ArrayType::get(Int32Ty,3), Int32Ty 243#endif 244 245#endif // !PPC_TGT_PARSER_UNDEF_MACROS 246